<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE module [
  <!ELEMENT module (dtdversion,name,version,description*,help*,about*,requires*,file+)>
  <!ELEMENT dtdversion (#PCDATA)>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT version (#PCDATA)>
  <!ELEMENT mincmsversion (#PCDATA)>
  <!ELEMENT description (#PCDATA)>
  <!ELEMENT help (#PCDATA)>
  <!ELEMENT about (#PCDATA)>
  <!ELEMENT requires (requiredname,requiredversion)>
  <!ELEMENT requiredname (#PCDATA)>
  <!ELEMENT requiredversion (#PCDATA)>
  <!ELEMENT file (filename,isdir,data)>
  <!ELEMENT filename (#PCDATA)>
  <!ELEMENT isdir (#PCDATA)>
  <!ELEMENT data (#PCDATA)>
]>
<module>
	<dtdversion>1.3</dtdversion>
	<name>touchInlineEdit</name>
	<version>1.2</version>
  <mincmsversion>1.6.8</mincmsversion>
	<help><![CDATA[PGgzPlVzYWdlPC9oMz4KPHVsPgoJPGxpPkxvYWQgbW9kdWxlIC0ge2Ntc19tb2R1bGUgbW9kdWxlPSJ0b3VjaElubGluZUVkaXQifTwvbGk+Cgk8bGk+TWFyayBlZGl0YWJsZSBjb250ZW50cyAtIHtjb250ZW50IGlzZWRpdGFibGU9J3RydWUnfTwvbGk+CjwvdWw+CjxoMz5BYm91dDwvaDM+Cjx1bD4KCTxsaT5Db3B5cmlnaHQgYnkgPGEgaHJlZj0iaHR0cDovL3d3dy50b3VjaGRlc2lnbi5kZS8iPnRvdWNoRGVzaWduPC9hPjwvbGk+Cgk8bGk+QXV0b3IgQ2hyaXN0b3BoIEdydWJlcjwvbGk+Cgk8bGk+U3VwcG9ydCB2aWEgPGEgaHJlZj0iaHR0cDovL3d3dy5ob21lcGFnZS1jb21tdW5pdHkuZGUvaW5kZXgucGhwP3RvcGljPTE2ODAuMCI+SFBDPC9hPjwvbGk+Cgk8bGk+TGljZW5zZSBHUEwgMi4wPC9saT4KPC91bD48aDM+UGFyYW1ldGVyPC9oMz48dWw+PGxpPjxlbT4ob3B0aW9uYWwpPC9lbT4gbGFuZz0iZW5fVVMiIC0gRGllc2VyIFBhcmFtZXRlciBsZWd0IGRpZSBTcHJhY2hlIGZlc3QsIGRpZSB2b20gTW9kdWwgZiZ1dW1sO3IgZGllIEF1c2dhYmUgYXVmIGRlciBXZWJzZWl0ZSB2ZXJ3ZW5kZXQgd2lyZC4gRGllcyB3aXJkIGplZG9jaCBuaWNodCB2b24gYWxsZW4gTW9kdWxlbiB1bnRlcnN0JnV1bWw7dHp0IGJ6dy4gYmVuJm91bWw7dGlndC48L2xpPjwvdWw+]]></help>
	<about><![CDATA[PGJyIC8+QXV0b3I6IENocmlzdG9waCBHcnViZXIgPHRvdWNoRGVzaWduLmRlPiAmbHQ7Yy5ncnViZXJAdG91Y2hkZXNpZ24uZGUmZ3Q7PGJyIC8+PGJyIC8+VmVyc2lvbiA6IDEuMjxiciAvPg==]]></about>
	<file>
	  <filename>/</filename>
	  <isdir>1</isdir>
	</file>
	<file>
	  <filename>/action.default.php</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[PD9waHAKLyoqCiAqICRJZDogYWN0aW9uLmRlZmF1bHQucGhwIDggMjAxMC0wOC0yOCAwMzo1NjowOVogdG91Y2hkZXNpZ24gJAogKgogKiB0b3VjaElubGluZUVkaXQgTW9kdWxlCiAqCiAqIENvcHlyaWdodCAoYykgMjAxMCB0b3VjaERlc2lnbiwgPHd3dy50b3VjaGRlc2lnbi5kZT4KICoKICogQGNhdGVnb3J5IE1vZHVsZQogKiBAYXV0aG9yIENocmlzdG9waCBHcnViZXIgPHd3dy50b3VjaGRlc2lnbi5kZT4KICogQHZlcnNpb24gMS4yCiAqIEBjb3B5cmlnaHQgQ2hyaXN0b3BoIEdydWJlciB0b3VjaERlc2lnbi5kZSAwNC4wOC4yMDEwCiAqIEBsaW5rIGh0dHA6Ly93d3cudG91Y2hkZXNpZ24uZGUvCiAqIEBsaW5rIGh0dHA6Ly93d3cuaG9tZXBhZ2UtY29tbXVuaXR5LmRlL2luZGV4LnBocD90b3BpYz0xNjgwLjAKICogQGxpbmsgaHR0cDovL2Rldi5jbXNtYWRlc2ltcGxlLm9yZy9wcm9qZWN0cy90b3VjaElubGluZUVkaXQKICogQGxpY2Vuc2UgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2xpY2Vuc2VzLmh0bWwjR1BMIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIChHUEwgMi4wKQogKiBAdG9kbyBhZGQgY29udGVudF9ibG9jayBoYW5kbGluZwogKiAKICogLS0KICoKICogVXNhZ2U6IAogKgogKiB7Y21zX21vZHVsZSBtb2R1bGU9InRvdWNoSW5saW5lRWRpdCJ9CiAqCiAqIHtjb250ZW50IGlzZWRpdGFibGU9J3RydWUnfQogKgogKiAtLQogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3IFVTQQogKiBPciByZWFkIGl0IG9ubGluZTogaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2xpY2Vuc2VzLmh0bWwjR1BMCiAqCiAqLwoKZ2xvYmFsICRnQ21zOwoKaWYoaXNzZXQoJGdDbXMtPm1vZHVsZXNbJ3RvdWNoSW5saW5lRWRpdCddKSAKCSYmIGlzX29iamVjdCgkZ0Ntcy0+bW9kdWxlc1sndG91Y2hJbmxpbmVFZGl0J11bJ29iamVjdCddKSl7CgoJJHRvdWNoSW5saW5lRWRpdCA9ICRnQ21zLT5tb2R1bGVzWyd0b3VjaElubGluZUVkaXQnXVsnb2JqZWN0J107Cgkkc21hcnR5ID0gJiRnQ21zLT5zbWFydHk7CgkkY29uZmlnID0gJiRnQ21zLT5jb25maWc7CgoJLy9EZWJ1ZwoJLy8kc21hcnR5LT5mb3JjZV9jb21waWxlID0gdHJ1ZTsKCglpZihjaGVja19sb2dpbih0cnVlKSAmJiAkdGhpcy0+Q2hlY2tQZXJtaXNzaW9uKCdVc2UgdG91Y2hJbmxpbmVFZGl0JykpewoJCWlmKCR0b3VjaElubGluZUVkaXQtPmlzQUpBWFJlcXVlc3QoKSl7CgkJCWRpZSgkdG91Y2hJbmxpbmVFZGl0LT51cGRhdGVDb250ZW50KCkpOwkJCgkJfQoKCQkkc21hcnR5LT5hc3NpZ24oJ2hhc0lubGluZUVkaXRSaWdodHMnLDEpOwoJCSRzbWFydHktPmFzc2lnbigndGllRmVFZGl0QnV0dG9uJywkdG91Y2hJbmxpbmVFZGl0LT5HZXRQcmVmZXJlbmNlKCJ0b3VjaElubGluZUVkaXQuZmVFZGl0QnV0dG9uIikpOwoJCSRzbWFydHktPmFzc2lnbigndGllRmVGdWxsUGFuZWwnLCR0b3VjaElubGluZUVkaXQtPkdldFByZWZlcmVuY2UoInRvdWNoSW5saW5lRWRpdC5mZUZ1bGxQYW5lbCIpKTsKCQkkc21hcnR5LT5hc3NpZ24oJ3RpZUZlVXBkYXRlQWxlcnQnLCR0b3VjaElubGluZUVkaXQtPkdldFByZWZlcmVuY2UoInRvdWNoSW5saW5lRWRpdC5mZVVwZGF0ZUFsZXJ0IikpOwoJfQp9Cgo/Pg==]]></data>
	</file>
	<file>
	  <filename>/action.defaultadmin.php</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[PD9waHAKLyoqCiAqICRJZDogYWN0aW9uLmRlZmF1bHRhZG1pbi5waHAgOCAyMDEwLTA4LTI4IDAzOjU2OjA5WiB0b3VjaGRlc2lnbiAkCiAqCiAqIHRvdWNoSW5saW5lRWRpdCBNb2R1bGUKICoKICogQ29weXJpZ2h0IChjKSAyMDEwIHRvdWNoRGVzaWduLCA8d3d3LnRvdWNoZGVzaWduLmRlPgogKgogKiBAY2F0ZWdvcnkgTW9kdWxlCiAqIEBhdXRob3IgQ2hyaXN0b3BoIEdydWJlciA8d3d3LnRvdWNoZGVzaWduLmRlPgogKiBAdmVyc2lvbiAxLjIKICogQGNvcHlyaWdodCBDaHJpc3RvcGggR3J1YmVyIHRvdWNoRGVzaWduLmRlIDA0LjA4LjIwMTAKICogQGxpbmsgaHR0cDovL3d3dy50b3VjaGRlc2lnbi5kZS8KICogQGxpbmsgaHR0cDovL3d3dy5ob21lcGFnZS1jb21tdW5pdHkuZGUvaW5kZXgucGhwP3RvcGljPTE2ODAuMAogKiBAbGluayBodHRwOi8vZGV2LmNtc21hZGVzaW1wbGUub3JnL3Byb2plY3RzL3RvdWNoSW5saW5lRWRpdAogKiBAbGljZW5zZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvbGljZW5zZXMuaHRtbCNHUEwgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgKEdQTCAyLjApCiAqIEB0b2RvIGFkZCBjb250ZW50X2Jsb2NrIGhhbmRsaW5nCiAqIAogKiAtLQogKgogKiBVc2FnZTogCiAqCiAqIHtjbXNfbW9kdWxlIG1vZHVsZT0idG91Y2hJbmxpbmVFZGl0In0KICoKICoge2NvbnRlbnQgaXNlZGl0YWJsZT0ndHJ1ZSd9CiAqCiAqIC0tCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcgVVNBCiAqIE9yIHJlYWQgaXQgb25saW5lOiBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvbGljZW5zZXMuaHRtbCNHUEwKICoKICovCgppZiAoIWlzc2V0KCRnQ21zKSl7CglleGl0Owp9CgppZiAoISR0aGlzLT5DaGVja1Blcm1pc3Npb24oJ1VzZSB0b3VjaElubGluZUVkaXQnKSkgewoJZWNobyAkdGhpcy0+bGFuZygibm9wZXJtaXNzaW9uIik7CglyZXR1cm47Cn0KCmVjaG8gJHRoaXMtPlN0YXJ0VGFiSGVhZGVycygpOwoKZWNobyAkdGhpcy0+U2V0VGFiSGVhZGVyKCJzZXR0aW5ncyIsJHRoaXMtPkxhbmcoInNldHRpbmdzIikpOwoKZWNobyAkdGhpcy0+RW5kVGFiSGVhZGVycygpOwplY2hvICR0aGlzLT5TdGFydFRhYkNvbnRlbnQoKTsKCmVjaG8gJHRoaXMtPlN0YXJ0VGFiKCJzZXR0aW5ncyIpOwoKJHluID0gYXJyYXkoCgkkdGhpcy0+TGFuZygieWVzIikgPT4gJ1knLAoJJHRoaXMtPkxhbmcoIm5vIikgPT4gJ04nCik7CgokYm9vbCA9IGFycmF5KAoJJHRoaXMtPkxhbmcoInllcyIpID0+ICd0cnVlJywKCSR0aGlzLT5MYW5nKCJubyIpID0+ICdmYWxzZScKKTsKCi8vIEZvcm0gc3RhcnQKJHRoaXMtPnNtYXJ0eS0+YXNzaWduKCdmb3Jtc3RhcnQnLCR0aGlzLT5DcmVhdGVGb3JtU3RhcnQoJGlkLCJzYXZlc2V0dGluZ3MiLCRyZXR1cm5pZCkpOwoKLy8gRW5hYmxlIGRpc2FibGUgaW5saW5lRWRpdCBidXR0b24gaW4gRkUKJHRoaXMtPnNtYXJ0eS0+YXNzaWduKCdmZUVkaXRCdXR0b25fbGFiZWwnLCR0aGlzLT5MYW5nKCJmZUVkaXRCdXR0b25fbGFiZWwiKSk7CiR0aGlzLT5zbWFydHktPmFzc2lnbignZmVFZGl0QnV0dG9uX2hlbHAnLCR0aGlzLT5MYW5nKCJmZUVkaXRCdXR0b25faGVscCIpKTsKJHRoaXMtPnNtYXJ0eS0+YXNzaWduKCdmZUVkaXRCdXR0b25faW5wdXQnLCR0aGlzLT5DcmVhdGVJbnB1dFJhZGlvR3JvdXAoJGlkLCJmZUVkaXRCdXR0b24iLCR5biwkdGhpcy0+R2V0UHJlZmVyZW5jZSgidG91Y2hJbmxpbmVFZGl0LmZlRWRpdEJ1dHRvbiIsIlkiKSwiIiwiXG4iKSk7CgovLyBFbmFibGUgZnVsbCBwYW5lbCBpbiBGRQokdGhpcy0+c21hcnR5LT5hc3NpZ24oJ2ZlRnVsbFBhbmVsX2xhYmVsJywkdGhpcy0+TGFuZygiZmVGdWxsUGFuZWxfbGFiZWwiKSk7CiR0aGlzLT5zbWFydHktPmFzc2lnbignZmVGdWxsUGFuZWxfaGVscCcsJHRoaXMtPkxhbmcoImZlRnVsbFBhbmVsX2hlbHAiKSk7CiR0aGlzLT5zbWFydHktPmFzc2lnbignZmVGdWxsUGFuZWxfaW5wdXQnLCR0aGlzLT5DcmVhdGVJbnB1dFJhZGlvR3JvdXAoJGlkLCJmZUZ1bGxQYW5lbCIsJGJvb2wsJHRoaXMtPkdldFByZWZlcmVuY2UoInRvdWNoSW5saW5lRWRpdC5mZUZ1bGxQYW5lbCIsInRydWUiKSwiIiwiXG4iKSk7CgovLyBFbmFibGUgYWxlcnQgYW4gY29udGVudCB1cGRhdGUKJHRoaXMtPnNtYXJ0eS0+YXNzaWduKCdmZVVwZGF0ZUFsZXJ0X2xhYmVsJywkdGhpcy0+TGFuZygiZmVVcGRhdGVBbGVydF9sYWJlbCIpKTsKJHRoaXMtPnNtYXJ0eS0+YXNzaWduKCdmZVVwZGF0ZUFsZXJ0X2hlbHAnLCR0aGlzLT5MYW5nKCJmZVVwZGF0ZUFsZXJ0X2hlbHAiKSk7CiR0aGlzLT5zbWFydHktPmFzc2lnbignZmVVcGRhdGVBbGVydF9pbnB1dCcsJHRoaXMtPkNyZWF0ZUlucHV0UmFkaW9Hcm91cCgkaWQsImZlVXBkYXRlQWxlcnQiLCRib29sLCR0aGlzLT5HZXRQcmVmZXJlbmNlKCJ0b3VjaElubGluZUVkaXQuZmVVcGRhdGVBbGVydCIsInRydWUiKSwiIiwiXG4iKSk7CgovLyBTdWJtaXQgLyBjYW5jZWwKJHRoaXMtPnNtYXJ0eS0+YXNzaWduKCdzdWJtaXQnLCR0aGlzLT5DcmVhdGVJbnB1dFN1Ym1pdCgkaWQsInN1Ym1pdCIsJHRoaXMtPkxhbmcoInNhdmUiKSkpOwokdGhpcy0+c21hcnR5LT5hc3NpZ24oJ2NhbmNlbCcsJHRoaXMtPkNyZWF0ZUlucHV0U3VibWl0KCRpZCwiY2FuY2VsIiwkdGhpcy0+TGFuZygiY2FuY2VsIikpKTsKCi8vIEZvcm0gZW5kCiR0aGlzLT5zbWFydHktPmFzc2lnbignZm9ybWVuZCcsJHRoaXMtPkNyZWF0ZUZvcm1FbmQoKSk7CgplY2hvICR0aGlzLT5Qcm9jZXNzVGVtcGxhdGUoImFkbWluc2V0dGluZ3MudHBsIik7CgplY2hvICR0aGlzLT5FbmRUYWIoKTsKCj8+Cg==]]></data>
	</file>
	<file>
	  <filename>/action.savesettings.php</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[PD9waHAKLyoqCiAqICRJZDogYWN0aW9uLnNhdmVzZXR0aW5ncy5waHAgOCAyMDEwLTA4LTI4IDAzOjU2OjA5WiB0b3VjaGRlc2lnbiAkCiAqCiAqIHRvdWNoSW5saW5lRWRpdCBNb2R1bGUKICoKICogQ29weXJpZ2h0IChjKSAyMDEwIHRvdWNoRGVzaWduLCA8d3d3LnRvdWNoZGVzaWduLmRlPgogKgogKiBAY2F0ZWdvcnkgTW9kdWxlCiAqIEBhdXRob3IgQ2hyaXN0b3BoIEdydWJlciA8d3d3LnRvdWNoZGVzaWduLmRlPgogKiBAdmVyc2lvbiAxLjIKICogQGNvcHlyaWdodCBDaHJpc3RvcGggR3J1YmVyIHRvdWNoRGVzaWduLmRlIDA0LjA4LjIwMTAKICogQGxpbmsgaHR0cDovL3d3dy50b3VjaGRlc2lnbi5kZS8KICogQGxpbmsgaHR0cDovL3d3dy5ob21lcGFnZS1jb21tdW5pdHkuZGUvaW5kZXgucGhwP3RvcGljPTE2ODAuMAogKiBAbGluayBodHRwOi8vZGV2LmNtc21hZGVzaW1wbGUub3JnL3Byb2plY3RzL3RvdWNoSW5saW5lRWRpdAogKiBAbGljZW5zZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvbGljZW5zZXMuaHRtbCNHUEwgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgKEdQTCAyLjApCiAqIEB0b2RvIGFkZCBjb250ZW50X2Jsb2NrIGhhbmRsaW5nCiAqIAogKiAtLQogKgogKiBVc2FnZTogCiAqCiAqIHtjbXNfbW9kdWxlIG1vZHVsZT0idG91Y2hJbmxpbmVFZGl0In0KICoKICoge2NvbnRlbnQgaXNlZGl0YWJsZT0ndHJ1ZSd9CiAqCiAqIC0tCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcgVVNBCiAqIE9yIHJlYWQgaXQgb25saW5lOiBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvbGljZW5zZXMuaHRtbCNHUEwKICoKICovCgppZiAoISR0aGlzLT5DaGVja1Blcm1pc3Npb24oJ01vZGlmeSBTaXRlIFNldHRpbmdzJykpIHsKCWVjaG8gJHRoaXMtPmxhbmcoIm5vcGVybWlzc2lvbiIpOwoJcmV0dXJuOwp9CgppZihpc3NldCgkcGFyYW1zWyJmZUVkaXRCdXR0b24iXSkgJiYgIWVtcHR5KCRwYXJhbXNbImZlRWRpdEJ1dHRvbiJdKSkgewoJJHRoaXMtPlNldFByZWZlcmVuY2UoInRvdWNoSW5saW5lRWRpdC5mZUVkaXRCdXR0b24iLCRwYXJhbXNbImZlRWRpdEJ1dHRvbiJdKTsKfQppZihpc3NldCgkcGFyYW1zWyJmZUZ1bGxQYW5lbCJdKSAmJiAhZW1wdHkoJHBhcmFtc1siZmVGdWxsUGFuZWwiXSkpIHsKCSR0aGlzLT5TZXRQcmVmZXJlbmNlKCJ0b3VjaElubGluZUVkaXQuZmVGdWxsUGFuZWwiLCRwYXJhbXNbImZlRnVsbFBhbmVsIl0pOwp9CmlmKGlzc2V0KCRwYXJhbXNbImZlVXBkYXRlQWxlcnQiXSkgJiYgIWVtcHR5KCRwYXJhbXNbImZlVXBkYXRlQWxlcnQiXSkpIHsKCSR0aGlzLT5TZXRQcmVmZXJlbmNlKCJ0b3VjaElubGluZUVkaXQuZmVVcGRhdGVBbGVydCIsJHBhcmFtc1siZmVVcGRhdGVBbGVydCJdKTsKfQoKJHRoaXMtPlJlZGlyZWN0KCRpZCwgJ2RlZmF1bHRhZG1pbicsICcnLCBhcnJheSgibW9kdWxlX21lc3NhZ2UiID0+ICR0aGlzLT5MYW5nKCJzZXR0aW5nc3NhdmVkIiksInRhYiIgPT4gInNldHRpbmdzIikpOwoKPz4=]]></data>
	</file>
	<file>
	  <filename>/img/</filename>
	  <isdir>1</isdir>
	</file>
	<file>
	  <filename>/img/nicEditorIcons.gif</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[R0lGODlhwgESAPcAAAAAABERESIiIjMzMzNmIndVIkR3IkRERFVVVWZmZnd3d90iIu4zM7tEEbtVIqp3M91mAO53EcxmM7t3RIhmd+5ERO5EVe5VVf9VVf9mZv9md+53d/93d1WIIlWIRGaIVXe7RGaIZruIM7uZM/+qM//MM4iIRKqIVYi7RIiqVZm7VbuqVZmZd4i7ZsyZVd2ZVe6ZVcyqRMyZZt2ZZt2qZsyqd92qd8y7d+67ZpnMZt3MVe7MZu7dZv/dZu7MdzNmqjNmuzN3u0R3u5l3iP93iGaZmUSZqlWIu2aIqlWIzFWI3VWZ3WaIzGaZzHeZzGaI3WaZ3XeZ3VWq3Waq3Xeq3VWq7maq7neq7ma7/4iIiJmZmZmqiLuqmYiqqqqqqru7u/+IiN2qiMy7iN27iMy7md27me6qiO6qme67mf+7u5nMiLvMmbvdu93MiO7MiN3Mqu7Mqv/Mu+7du8zuu//uqoiZ3YiqzJmqzIiq3Zm73aq73Yiq7oi77pm77qq77rvM3YjM7pnd/6rM7rvM7rvd7szMzMzM3czd3d3d3f/MzO7dzO7d3f/d3f//zO7u3f/u3czd7szd/93d/93u7t3u/+7u7v/u7u7u/+7//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJoALAAAAADCARIAAAj+ADUJHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDNq3MixI8Q/VJokESlypJ1MDB2hqVEDjSOPMGPKnLkwEyA+gG7yoZRRDx4mQoAIHSpUCJNBNJNaNKTnjtOnUO8YUvoQJUGfQIkSNYqUIpVLYMOCnRTS6kFHY2yMgQNnjAwZcqjKnevwkh+lhARBgrRTI569mTJhCotpMKVBTQTRXZxQTyWxkC9VusPYEiODjNIkIvgXUuDBYAtfOpyYYpNLkVLvhUQoE6GQlm60KQhHBho5PUqUkAMHjYwydBUIV5AgAQIEBw4MEMB4pp+7SQEJwknF7MUjkKgUZhI20+jDg4T+NG9IyA+hiIWyKPAyUAuCLwXvXHLaRY19NUWK3JmcMVMfSplcoYkkV/SBkCUccHDZQIxkkAEYC2qCnXaYcAeWd5SAJ95ESaCWmmqtRUKJHWLQMcJAKoWBAwkklJBbGGGwNcFLBBWihXBfaJGAFpUgNFxxxR2H3AEY/RikkMkt9AWQCvgoHJDGHZdkQUYeOaRB0BVS5XEGbYkkkQYJQggfkABCRXZWTKEmFQRVGeWVAwmR3WAWCvbdmUAcVIkXX3zhRRYJaSFoFpWo12REl/DBB3QD+THIXV94idCNBFVyKEHy5VGfGjl02oV+/GU0yB6S/HfFHgdyQAQRCgrUoAb+RGSQhlVyandJnYZRgidFSWQi4oesTXKJI23QEcMNA7UlBwkr4lACDiqAgAIcLBm0JKCauJeARsRFmdxyAgQQgEcKvNfcc4zCRIl0kKxLxWtSWGFFFAZOBER2YHEnWoaURCFInl3Cp4kXCCSkZQLs/dljRHzYhSpB5Z0XkY5UGpRpfZ3m0EIO+YVa6RdZaJEFIoWK/MXCB42ayR4CIpRJgmBwkAEjr8pcgVn3fnXrJftm6C/AEnXILyUg/lHsDjdY5YgMZ1zwArMwhgFCDiCEgcYE1iaALcFgHrTkm8kdwB5G9WrypJULIcJlQt2C/e0AXQL5JUf1nv2mQXzk1Uf+H9lRMoUUS0yBh3UDua0c3APlzC/P31ECSRR6AD1QIQgPdOlBaiPgxeUSsawRxW1afImmnLZgegtFdEFDDS7EJVAmglaCSI5aIDK7oNZVArLIgJacxckGZaKBqjI7aLN1imfIOL+PR85r4xlGAskhR59gyUBooLHBBhesxVYYK6Cwgg1oPGAQwb0jhy1GUionQLhdG9THHjx9efhC7q2/2N6XPEQJH/Wy3wAQ9zpBCIIKBtwbFfowhSUQYgl4qEjOmEDBJliQghSE3A8Mggjj1E4ThVgI11AWqEEVSjia6AMVJKGRLGyLIC/E1Oi60KnTpSAFbpDDI+TggoFEChH+WTjAjohzgCxsTmCagF3tbpct29GOcEnMAKwSxIEL3KwgE6zgBTGoQQ7aznaFCKFBhMYvEVGPDjsYARIIUgM4hOECG6jNBGQAByPYcQblOx8CEJYAISbESmEb4HIusoc+8IEKPJFIH5F4EEC+bZAFceThIEmQRDnkfwBkE0P+xzeBUAIPVFjCEiAhiCVEIZKGG+D7CJIzKrjSlVGIpSzzsEGDZEFKCRBjQiqRHP0h5GAJIxQk9nCJdhFkEH3oCkRuGUmLVSIPeSiCDVPgAznkUA40aE8WCpGJA3yhEH46QCbSowUfKiA9QgwhEY2oAEYOJBMX4AAGMMCBK2IxO6/+hKUsY0lLL34REbokCBkzBIkv3ACNIzhEEghCx97ECGsTQIMdjfCCPBaEYIfKwgAQQEKKoOuje9sbH/bwsIHsAZGasBKcEIKIKTXHkpr4QvsOxxyC6KplKnWpJnACQE1kpw9PkEIES/kECeIzn/vkZy1jOpwnHUAAAIgqAHwpkPUMMISJWhTmjrM5gVABCmAtSB8EgSqZDommCGEmQQoWn9Hl4Q4miKsJfNAIHviABjTon0A2h86w9VJLY8vWNhUQGJQEBhHnDNlBGBHPedYzQok76iuTGoV+FiQTXwwjFDUx0ENwgQsjiEEMvnCJhWJPBjXwngweYBsWGIEFY6j+gfkuioBDVeJ95TwI1yb5vsA2ahDABa4BBeGHkGpyIC3TxCPfV9NJHYBzBpmpIJk7roJIV5UI2QMoI9Ky5a5SIYKQwhSG4IAGOIACm/VuuFg5iHxSgbJRwMNSB4IyLygnfpUyoiY0OoBCNMwPJaXtAToapj0oZmLenBxV93PDFJjABS6gKw/s6gIaCaSDWvCCF26kAC1s4QMf8MAWBsLXICappUUELGYukIEEaUADGKgAZDUBhPYilbLyPcg4NYuQJEwiQ3+wwxcU8YUTcMEzQSiISmowgZb0xgYveEEYxjCBN5zPjwJ5H1UlUtyQjhSU7t0IAgbgzvEoBRJLUML+ECRghjiYgc0UqXF1CkvnwDQhxwXxE0EEQEAqaS1zyQmh5/TUy5jwkqMgPAAinMmGRrOhBhKmcBcu28EE4KgQIWjBGubQgg6MWBMY1jClOizqBCyaIIxtsRUrYIEMWIABkJVznet85/kSZJybFUiHquBKO9ghCUiogrAzkeSzRHQGUa5oGJp8EC0cgK1aeN+pCxJIVb5PXNW1SLXBFS5xGYySCdn2tcUFAIOIe9zZ9qorIXLubqfbIFGAIJthEIEIwMABBDk3tsuduEFEIROnC3gLMFHr8w0AZQLYskJUyMKDWLW/hi5XbQM6kP04mgw1qCuFF0EZhnhgDWsAeAv+CPC6SuPIbGdDhHVSXcWbZYIBFchABWDd738L/HQEx7NEgjAJLCDh5z+nQiACgQViJ+QtaCCfbx4AHGsRBwHqqe20zfwQHR0nhs1BKU0g0QclKEEQDYhDYSPQgDi3NxOOTjsbCO4EWw/s2RmmFESGWcxE0le//KU4QfxAhXRxxDFgwTgZdEBhR3hMIQYIeWDWQHJ4/xsKyjRIIlgcY6u8nNUM2IxAZK12R7Pd7Q7hORZGT/rSGx0hjngAjFY7I414gdvuzu1FaErdd2vb2u6Wqrlx3+2E6Gpg4CJ3VHcPe28rxOtef4ID6F1vCJTdILUPgO5rLvKbV6jtHvlqWP39PLL26d2rhwR+7od/kNpPnyBMcYoIHuECEbT/KVNhiAFMJ/LGEyQKUJBEHSABBb8TJBEWYE+vswCZx142d3MDxwTYxyGXMAkO6IBiERimhRBl8ABNZmFUl4FJ4UplQxVv1nwNYAYUIQQGNGt05gROsCEaiCV9lxQF4AZuIAIisAgRsQUdoGmd9mkDUQdQAAmaAAWXIAn/lhCJAEWZoHlxUoImGBgoqIIR8QdNEARSOIVUmAR/sIJYmIV0YQbl5QAiSBF4EAVBIRQ/UIZmaIZHoIWMUQAF4AI0gIEPsQUEQAAGoINJEYZjCARnuIdpqIZ++IeAGIiCOIiEiBABAQA7]]></data>
	</file>
	<file>
	  <filename>/js/</filename>
	  <isdir>1</isdir>
	</file>
	<file>
	  <filename>/js/jquery.js</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[LyohCiAqIGpRdWVyeSBKYXZhU2NyaXB0IExpYnJhcnkgdjEuMy4yCiAqIGh0dHA6Ly9qcXVlcnkuY29tLwogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDkgSm9obiBSZXNpZwogKiBEdWFsIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgYW5kIEdQTCBsaWNlbnNlcy4KICogaHR0cDovL2RvY3MuanF1ZXJ5LmNvbS9MaWNlbnNlCiAqCiAqIERhdGU6IDIwMDktMDItMTkgMTc6MzQ6MjEgLTA1MDAgKFRodSwgMTkgRmViIDIwMDkpCiAqIFJldmlzaW9uOiA2MjQ2CiAqLwooZnVuY3Rpb24oKXsKCnZhciAKCS8vIFdpbGwgc3BlZWQgdXAgcmVmZXJlbmNlcyB0byB3aW5kb3csIGFuZCBhbGxvd3MgbXVuZ2luZyBpdHMgbmFtZS4KCXdpbmRvdyA9IHRoaXMsCgkvLyBXaWxsIHNwZWVkIHVwIHJlZmVyZW5jZXMgdG8gdW5kZWZpbmVkLCBhbmQgYWxsb3dzIG11bmdpbmcgaXRzIG5hbWUuCgl1bmRlZmluZWQsCgkvLyBNYXAgb3ZlciBqUXVlcnkgaW4gY2FzZSBvZiBvdmVyd3JpdGUKCV9qUXVlcnkgPSB3aW5kb3cualF1ZXJ5LAoJLy8gTWFwIG92ZXIgdGhlICQgaW4gY2FzZSBvZiBvdmVyd3JpdGUKCV8kID0gd2luZG93LiQsCgoJalF1ZXJ5ID0gd2luZG93LmpRdWVyeSA9IHdpbmRvdy4kID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0ICkgewoJCS8vIFRoZSBqUXVlcnkgb2JqZWN0IGlzIGFjdHVhbGx5IGp1c3QgdGhlIGluaXQgY29uc3RydWN0b3IgJ2VuaGFuY2VkJwoJCXJldHVybiBuZXcgalF1ZXJ5LmZuLmluaXQoIHNlbGVjdG9yLCBjb250ZXh0ICk7Cgl9LAoKCS8vIEEgc2ltcGxlIHdheSB0byBjaGVjayBmb3IgSFRNTCBzdHJpbmdzIG9yIElEIHN0cmluZ3MKCS8vIChib3RoIG9mIHdoaWNoIHdlIG9wdGltaXplIGZvcikKCXF1aWNrRXhwciA9IC9eW148XSooPCgufFxzKSs+KVtePl0qJHxeIyhbXHctXSspJC8sCgkvLyBJcyBpdCBhIHNpbXBsZSBzZWxlY3RvcgoJaXNTaW1wbGUgPSAvXi5bXjojXFtcLixdKiQvOwoKalF1ZXJ5LmZuID0galF1ZXJ5LnByb3RvdHlwZSA9IHsKCWluaXQ6IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHsKCQkvLyBNYWtlIHN1cmUgdGhhdCBhIHNlbGVjdGlvbiB3YXMgcHJvdmlkZWQKCQlzZWxlY3RvciA9IHNlbGVjdG9yIHx8IGRvY3VtZW50OwoKCQkvLyBIYW5kbGUgJChET01FbGVtZW50KQoJCWlmICggc2VsZWN0b3Iubm9kZVR5cGUgKSB7CgkJCXRoaXNbMF0gPSBzZWxlY3RvcjsKCQkJdGhpcy5sZW5ndGggPSAxOwoJCQl0aGlzLmNvbnRleHQgPSBzZWxlY3RvcjsKCQkJcmV0dXJuIHRoaXM7CgkJfQoJCS8vIEhhbmRsZSBIVE1MIHN0cmluZ3MKCQlpZiAoIHR5cGVvZiBzZWxlY3RvciA9PT0gInN0cmluZyIgKSB7CgkJCS8vIEFyZSB3ZSBkZWFsaW5nIHdpdGggSFRNTCBzdHJpbmcgb3IgYW4gSUQ/CgkJCXZhciBtYXRjaCA9IHF1aWNrRXhwci5leGVjKCBzZWxlY3RvciApOwoKCQkJLy8gVmVyaWZ5IGEgbWF0Y2gsIGFuZCB0aGF0IG5vIGNvbnRleHQgd2FzIHNwZWNpZmllZCBmb3IgI2lkCgkJCWlmICggbWF0Y2ggJiYgKG1hdGNoWzFdIHx8ICFjb250ZXh0KSApIHsKCgkJCQkvLyBIQU5ETEU6ICQoaHRtbCkgLT4gJChhcnJheSkKCQkJCWlmICggbWF0Y2hbMV0gKQoJCQkJCXNlbGVjdG9yID0galF1ZXJ5LmNsZWFuKCBbIG1hdGNoWzFdIF0sIGNvbnRleHQgKTsKCgkJCQkvLyBIQU5ETEU6ICQoIiNpZCIpCgkJCQllbHNlIHsKCQkJCQl2YXIgZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBtYXRjaFszXSApOwoKCQkJCQkvLyBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgSUUgYW5kIE9wZXJhIHJldHVybiBpdGVtcwoJCQkJCS8vIGJ5IG5hbWUgaW5zdGVhZCBvZiBJRAoJCQkJCWlmICggZWxlbSAmJiBlbGVtLmlkICE9IG1hdGNoWzNdICkKCQkJCQkJcmV0dXJuIGpRdWVyeSgpLmZpbmQoIHNlbGVjdG9yICk7CgoJCQkJCS8vIE90aGVyd2lzZSwgd2UgaW5qZWN0IHRoZSBlbGVtZW50IGRpcmVjdGx5IGludG8gdGhlIGpRdWVyeSBvYmplY3QKCQkJCQl2YXIgcmV0ID0galF1ZXJ5KCBlbGVtIHx8IFtdICk7CgkJCQkJcmV0LmNvbnRleHQgPSBkb2N1bWVudDsKCQkJCQlyZXQuc2VsZWN0b3IgPSBzZWxlY3RvcjsKCQkJCQlyZXR1cm4gcmV0OwoJCQkJfQoKCQkJLy8gSEFORExFOiAkKGV4cHIsIFtjb250ZXh0XSkKCQkJLy8gKHdoaWNoIGlzIGp1c3QgZXF1aXZhbGVudCB0bzogJChjb250ZW50KS5maW5kKGV4cHIpCgkJCX0gZWxzZQoJCQkJcmV0dXJuIGpRdWVyeSggY29udGV4dCApLmZpbmQoIHNlbGVjdG9yICk7CgoJCS8vIEhBTkRMRTogJChmdW5jdGlvbikKCQkvLyBTaG9ydGN1dCBmb3IgZG9jdW1lbnQgcmVhZHkKCQl9IGVsc2UgaWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggc2VsZWN0b3IgKSApCgkJCXJldHVybiBqUXVlcnkoIGRvY3VtZW50ICkucmVhZHkoIHNlbGVjdG9yICk7CgoJCS8vIE1ha2Ugc3VyZSB0aGF0IG9sZCBzZWxlY3RvciBzdGF0ZSBpcyBwYXNzZWQgYWxvbmcKCQlpZiAoIHNlbGVjdG9yLnNlbGVjdG9yICYmIHNlbGVjdG9yLmNvbnRleHQgKSB7CgkJCXRoaXMuc2VsZWN0b3IgPSBzZWxlY3Rvci5zZWxlY3RvcjsKCQkJdGhpcy5jb250ZXh0ID0gc2VsZWN0b3IuY29udGV4dDsKCQl9CgoJCXJldHVybiB0aGlzLnNldEFycmF5KGpRdWVyeS5pc0FycmF5KCBzZWxlY3RvciApID8KCQkJc2VsZWN0b3IgOgoJCQlqUXVlcnkubWFrZUFycmF5KHNlbGVjdG9yKSk7Cgl9LAoKCS8vIFN0YXJ0IHdpdGggYW4gZW1wdHkgc2VsZWN0b3IKCXNlbGVjdG9yOiAiIiwKCgkvLyBUaGUgY3VycmVudCB2ZXJzaW9uIG9mIGpRdWVyeSBiZWluZyB1c2VkCglqcXVlcnk6ICIxLjMuMiIsCgoJLy8gVGhlIG51bWJlciBvZiBlbGVtZW50cyBjb250YWluZWQgaW4gdGhlIG1hdGNoZWQgZWxlbWVudCBzZXQKCXNpemU6IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLmxlbmd0aDsKCX0sCgoJLy8gR2V0IHRoZSBOdGggZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBlbGVtZW50IHNldCBPUgoJLy8gR2V0IHRoZSB3aG9sZSBtYXRjaGVkIGVsZW1lbnQgc2V0IGFzIGEgY2xlYW4gYXJyYXkKCWdldDogZnVuY3Rpb24oIG51bSApIHsKCQlyZXR1cm4gbnVtID09PSB1bmRlZmluZWQgPwoKCQkJLy8gUmV0dXJuIGEgJ2NsZWFuJyBhcnJheQoJCQlBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCggdGhpcyApIDoKCgkJCS8vIFJldHVybiBqdXN0IHRoZSBvYmplY3QKCQkJdGhpc1sgbnVtIF07Cgl9LAoKCS8vIFRha2UgYW4gYXJyYXkgb2YgZWxlbWVudHMgYW5kIHB1c2ggaXQgb250byB0aGUgc3RhY2sKCS8vIChyZXR1cm5pbmcgdGhlIG5ldyBtYXRjaGVkIGVsZW1lbnQgc2V0KQoJcHVzaFN0YWNrOiBmdW5jdGlvbiggZWxlbXMsIG5hbWUsIHNlbGVjdG9yICkgewoJCS8vIEJ1aWxkIGEgbmV3IGpRdWVyeSBtYXRjaGVkIGVsZW1lbnQgc2V0CgkJdmFyIHJldCA9IGpRdWVyeSggZWxlbXMgKTsKCgkJLy8gQWRkIHRoZSBvbGQgb2JqZWN0IG9udG8gdGhlIHN0YWNrIChhcyBhIHJlZmVyZW5jZSkKCQlyZXQucHJldk9iamVjdCA9IHRoaXM7CgoJCXJldC5jb250ZXh0ID0gdGhpcy5jb250ZXh0OwoKCQlpZiAoIG5hbWUgPT09ICJmaW5kIiApCgkJCXJldC5zZWxlY3RvciA9IHRoaXMuc2VsZWN0b3IgKyAodGhpcy5zZWxlY3RvciA/ICIgIiA6ICIiKSArIHNlbGVjdG9yOwoJCWVsc2UgaWYgKCBuYW1lICkKCQkJcmV0LnNlbGVjdG9yID0gdGhpcy5zZWxlY3RvciArICIuIiArIG5hbWUgKyAiKCIgKyBzZWxlY3RvciArICIpIjsKCgkJLy8gUmV0dXJuIHRoZSBuZXdseS1mb3JtZWQgZWxlbWVudCBzZXQKCQlyZXR1cm4gcmV0OwoJfSwKCgkvLyBGb3JjZSB0aGUgY3VycmVudCBtYXRjaGVkIHNldCBvZiBlbGVtZW50cyB0byBiZWNvbWUKCS8vIHRoZSBzcGVjaWZpZWQgYXJyYXkgb2YgZWxlbWVudHMgKGRlc3Ryb3lpbmcgdGhlIHN0YWNrIGluIHRoZSBwcm9jZXNzKQoJLy8gWW91IHNob3VsZCB1c2UgcHVzaFN0YWNrKCkgaW4gb3JkZXIgdG8gZG8gdGhpcywgYnV0IG1haW50YWluIHRoZSBzdGFjawoJc2V0QXJyYXk6IGZ1bmN0aW9uKCBlbGVtcyApIHsKCQkvLyBSZXNldHRpbmcgdGhlIGxlbmd0aCB0byAwLCB0aGVuIHVzaW5nIHRoZSBuYXRpdmUgQXJyYXkgcHVzaAoJCS8vIGlzIGEgc3VwZXItZmFzdCB3YXkgdG8gcG9wdWxhdGUgYW4gb2JqZWN0IHdpdGggYXJyYXktbGlrZSBwcm9wZXJ0aWVzCgkJdGhpcy5sZW5ndGggPSAwOwoJCUFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KCB0aGlzLCBlbGVtcyApOwoKCQlyZXR1cm4gdGhpczsKCX0sCgoJLy8gRXhlY3V0ZSBhIGNhbGxiYWNrIGZvciBldmVyeSBlbGVtZW50IGluIHRoZSBtYXRjaGVkIHNldC4KCS8vIChZb3UgY2FuIHNlZWQgdGhlIGFyZ3VtZW50cyB3aXRoIGFuIGFycmF5IG9mIGFyZ3MsIGJ1dCB0aGlzIGlzCgkvLyBvbmx5IHVzZWQgaW50ZXJuYWxseS4pCgllYWNoOiBmdW5jdGlvbiggY2FsbGJhY2ssIGFyZ3MgKSB7CgkJcmV0dXJuIGpRdWVyeS5lYWNoKCB0aGlzLCBjYWxsYmFjaywgYXJncyApOwoJfSwKCgkvLyBEZXRlcm1pbmUgdGhlIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgd2l0aGluCgkvLyB0aGUgbWF0Y2hlZCBzZXQgb2YgZWxlbWVudHMKCWluZGV4OiBmdW5jdGlvbiggZWxlbSApIHsKCQkvLyBMb2NhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBkZXNpcmVkIGVsZW1lbnQKCQlyZXR1cm4galF1ZXJ5LmluQXJyYXkoCgkJCS8vIElmIGl0IHJlY2VpdmVzIGEgalF1ZXJ5IG9iamVjdCwgdGhlIGZpcnN0IGVsZW1lbnQgaXMgdXNlZAoJCQllbGVtICYmIGVsZW0uanF1ZXJ5ID8gZWxlbVswXSA6IGVsZW0KCQksIHRoaXMgKTsKCX0sCgoJYXR0cjogZnVuY3Rpb24oIG5hbWUsIHZhbHVlLCB0eXBlICkgewoJCXZhciBvcHRpb25zID0gbmFtZTsKCgkJLy8gTG9vayBmb3IgdGhlIGNhc2Ugd2hlcmUgd2UncmUgYWNjZXNzaW5nIGEgc3R5bGUgdmFsdWUKCQlpZiAoIHR5cGVvZiBuYW1lID09PSAic3RyaW5nIiApCgkJCWlmICggdmFsdWUgPT09IHVuZGVmaW5lZCApCgkJCQlyZXR1cm4gdGhpc1swXSAmJiBqUXVlcnlbIHR5cGUgfHwgImF0dHIiIF0oIHRoaXNbMF0sIG5hbWUgKTsKCgkJCWVsc2UgewoJCQkJb3B0aW9ucyA9IHt9OwoJCQkJb3B0aW9uc1sgbmFtZSBdID0gdmFsdWU7CgkJCX0KCgkJLy8gQ2hlY2sgdG8gc2VlIGlmIHdlJ3JlIHNldHRpbmcgc3R5bGUgdmFsdWVzCgkJcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihpKXsKCQkJLy8gU2V0IGFsbCB0aGUgc3R5bGVzCgkJCWZvciAoIG5hbWUgaW4gb3B0aW9ucyApCgkJCQlqUXVlcnkuYXR0cigKCQkJCQl0eXBlID8KCQkJCQkJdGhpcy5zdHlsZSA6CgkJCQkJCXRoaXMsCgkJCQkJbmFtZSwgalF1ZXJ5LnByb3AoIHRoaXMsIG9wdGlvbnNbIG5hbWUgXSwgdHlwZSwgaSwgbmFtZSApCgkJCQkpOwoJCX0pOwoJfSwKCgljc3M6IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkgewoJCS8vIGlnbm9yZSBuZWdhdGl2ZSB3aWR0aCBhbmQgaGVpZ2h0IHZhbHVlcwoJCWlmICggKGtleSA9PSAnd2lkdGgnIHx8IGtleSA9PSAnaGVpZ2h0JykgJiYgcGFyc2VGbG9hdCh2YWx1ZSkgPCAwICkKCQkJdmFsdWUgPSB1bmRlZmluZWQ7CgkJcmV0dXJuIHRoaXMuYXR0cigga2V5LCB2YWx1ZSwgImN1ckNTUyIgKTsKCX0sCgoJdGV4dDogZnVuY3Rpb24oIHRleHQgKSB7CgkJaWYgKCB0eXBlb2YgdGV4dCAhPT0gIm9iamVjdCIgJiYgdGV4dCAhPSBudWxsICkKCQkJcmV0dXJuIHRoaXMuZW1wdHkoKS5hcHBlbmQoICh0aGlzWzBdICYmIHRoaXNbMF0ub3duZXJEb2N1bWVudCB8fCBkb2N1bWVudCkuY3JlYXRlVGV4dE5vZGUoIHRleHQgKSApOwoKCQl2YXIgcmV0ID0gIiI7CgoJCWpRdWVyeS5lYWNoKCB0ZXh0IHx8IHRoaXMsIGZ1bmN0aW9uKCl7CgkJCWpRdWVyeS5lYWNoKCB0aGlzLmNoaWxkTm9kZXMsIGZ1bmN0aW9uKCl7CgkJCQlpZiAoIHRoaXMubm9kZVR5cGUgIT0gOCApCgkJCQkJcmV0ICs9IHRoaXMubm9kZVR5cGUgIT0gMSA/CgkJCQkJCXRoaXMubm9kZVZhbHVlIDoKCQkJCQkJalF1ZXJ5LmZuLnRleHQoIFsgdGhpcyBdICk7CgkJCX0pOwoJCX0pOwoKCQlyZXR1cm4gcmV0OwoJfSwKCgl3cmFwQWxsOiBmdW5jdGlvbiggaHRtbCApIHsKCQlpZiAoIHRoaXNbMF0gKSB7CgkJCS8vIFRoZSBlbGVtZW50cyB0byB3cmFwIHRoZSB0YXJnZXQgYXJvdW5kCgkJCXZhciB3cmFwID0galF1ZXJ5KCBodG1sLCB0aGlzWzBdLm93bmVyRG9jdW1lbnQgKS5jbG9uZSgpOwoKCQkJaWYgKCB0aGlzWzBdLnBhcmVudE5vZGUgKQoJCQkJd3JhcC5pbnNlcnRCZWZvcmUoIHRoaXNbMF0gKTsKCgkJCXdyYXAubWFwKGZ1bmN0aW9uKCl7CgkJCQl2YXIgZWxlbSA9IHRoaXM7CgoJCQkJd2hpbGUgKCBlbGVtLmZpcnN0Q2hpbGQgKQoJCQkJCWVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7CgoJCQkJcmV0dXJuIGVsZW07CgkJCX0pLmFwcGVuZCh0aGlzKTsKCQl9CgoJCXJldHVybiB0aGlzOwoJfSwKCgl3cmFwSW5uZXI6IGZ1bmN0aW9uKCBodG1sICkgewoJCXJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXsKCQkJalF1ZXJ5KCB0aGlzICkuY29udGVudHMoKS53cmFwQWxsKCBodG1sICk7CgkJfSk7Cgl9LAoKCXdyYXA6IGZ1bmN0aW9uKCBodG1sICkgewoJCXJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXsKCQkJalF1ZXJ5KCB0aGlzICkud3JhcEFsbCggaHRtbCApOwoJCX0pOwoJfSwKCglhcHBlbmQ6IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLmRvbU1hbmlwKGFyZ3VtZW50cywgdHJ1ZSwgZnVuY3Rpb24oZWxlbSl7CgkJCWlmICh0aGlzLm5vZGVUeXBlID09IDEpCgkJCQl0aGlzLmFwcGVuZENoaWxkKCBlbGVtICk7CgkJfSk7Cgl9LAoKCXByZXBlbmQ6IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLmRvbU1hbmlwKGFyZ3VtZW50cywgdHJ1ZSwgZnVuY3Rpb24oZWxlbSl7CgkJCWlmICh0aGlzLm5vZGVUeXBlID09IDEpCgkJCQl0aGlzLmluc2VydEJlZm9yZSggZWxlbSwgdGhpcy5maXJzdENoaWxkICk7CgkJfSk7Cgl9LAoKCWJlZm9yZTogZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRoaXMuZG9tTWFuaXAoYXJndW1lbnRzLCBmYWxzZSwgZnVuY3Rpb24oZWxlbSl7CgkJCXRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoIGVsZW0sIHRoaXMgKTsKCQl9KTsKCX0sCgoJYWZ0ZXI6IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLmRvbU1hbmlwKGFyZ3VtZW50cywgZmFsc2UsIGZ1bmN0aW9uKGVsZW0pewoJCQl0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzLm5leHRTaWJsaW5nICk7CgkJfSk7Cgl9LAoKCWVuZDogZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRoaXMucHJldk9iamVjdCB8fCBqUXVlcnkoIFtdICk7Cgl9LAoKCS8vIEZvciBpbnRlcm5hbCB1c2Ugb25seS4KCS8vIEJlaGF2ZXMgbGlrZSBhbiBBcnJheSdzIG1ldGhvZCwgbm90IGxpa2UgYSBqUXVlcnkgbWV0aG9kLgoJcHVzaDogW10ucHVzaCwKCXNvcnQ6IFtdLnNvcnQsCglzcGxpY2U6IFtdLnNwbGljZSwKCglmaW5kOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7CgkJaWYgKCB0aGlzLmxlbmd0aCA9PT0gMSApIHsKCQkJdmFyIHJldCA9IHRoaXMucHVzaFN0YWNrKCBbXSwgImZpbmQiLCBzZWxlY3RvciApOwoJCQlyZXQubGVuZ3RoID0gMDsKCQkJalF1ZXJ5LmZpbmQoIHNlbGVjdG9yLCB0aGlzWzBdLCByZXQgKTsKCQkJcmV0dXJuIHJldDsKCQl9IGVsc2UgewoJCQlyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeS51bmlxdWUoalF1ZXJ5Lm1hcCh0aGlzLCBmdW5jdGlvbihlbGVtKXsKCQkJCXJldHVybiBqUXVlcnkuZmluZCggc2VsZWN0b3IsIGVsZW0gKTsKCQkJfSkpLCAiZmluZCIsIHNlbGVjdG9yICk7CgkJfQoJfSwKCgljbG9uZTogZnVuY3Rpb24oIGV2ZW50cyApIHsKCQkvLyBEbyB0aGUgY2xvbmUKCQl2YXIgcmV0ID0gdGhpcy5tYXAoZnVuY3Rpb24oKXsKCQkJaWYgKCAhalF1ZXJ5LnN1cHBvcnQubm9DbG9uZUV2ZW50ICYmICFqUXVlcnkuaXNYTUxEb2ModGhpcykgKSB7CgkJCQkvLyBJRSBjb3BpZXMgZXZlbnRzIGJvdW5kIHZpYSBhdHRhY2hFdmVudCB3aGVuCgkJCQkvLyB1c2luZyBjbG9uZU5vZGUuIENhbGxpbmcgZGV0YWNoRXZlbnQgb24gdGhlCgkJCQkvLyBjbG9uZSB3aWxsIGFsc28gcmVtb3ZlIHRoZSBldmVudHMgZnJvbSB0aGUgb3JpZ25hbAoJCQkJLy8gSW4gb3JkZXIgdG8gZ2V0IGFyb3VuZCB0aGlzLCB3ZSB1c2UgaW5uZXJIVE1MLgoJCQkJLy8gVW5mb3J0dW5hdGVseSwgdGhpcyBtZWFucyBzb21lIG1vZGlmaWNhdGlvbnMgdG8KCQkJCS8vIGF0dHJpYnV0ZXMgaW4gSUUgdGhhdCBhcmUgYWN0dWFsbHkgb25seSBzdG9yZWQKCQkJCS8vIGFzIHByb3BlcnRpZXMgd2lsbCBub3QgYmUgY29waWVkIChzdWNoIGFzIHRoZQoJCQkJLy8gdGhlIG5hbWUgYXR0cmlidXRlIG9uIGFuIGlucHV0KS4KCQkJCXZhciBodG1sID0gdGhpcy5vdXRlckhUTUw7CgkJCQlpZiAoICFodG1sICkgewoJCQkJCXZhciBkaXYgPSB0aGlzLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CgkJCQkJZGl2LmFwcGVuZENoaWxkKCB0aGlzLmNsb25lTm9kZSh0cnVlKSApOwoJCQkJCWh0bWwgPSBkaXYuaW5uZXJIVE1MOwoJCQkJfQoKCQkJCXJldHVybiBqUXVlcnkuY2xlYW4oW2h0bWwucmVwbGFjZSgvIGpRdWVyeVxkKz0iKD86XGQrfG51bGwpIi9nLCAiIikucmVwbGFjZSgvXlxzKi8sICIiKV0pWzBdOwoJCQl9IGVsc2UKCQkJCXJldHVybiB0aGlzLmNsb25lTm9kZSh0cnVlKTsKCQl9KTsKCgkJLy8gQ29weSB0aGUgZXZlbnRzIGZyb20gdGhlIG9yaWdpbmFsIHRvIHRoZSBjbG9uZQoJCWlmICggZXZlbnRzID09PSB0cnVlICkgewoJCQl2YXIgb3JpZyA9IHRoaXMuZmluZCgiKiIpLmFuZFNlbGYoKSwgaSA9IDA7CgoJCQlyZXQuZmluZCgiKiIpLmFuZFNlbGYoKS5lYWNoKGZ1bmN0aW9uKCl7CgkJCQlpZiAoIHRoaXMubm9kZU5hbWUgIT09IG9yaWdbaV0ubm9kZU5hbWUgKQoJCQkJCXJldHVybjsKCgkJCQl2YXIgZXZlbnRzID0galF1ZXJ5LmRhdGEoIG9yaWdbaV0sICJldmVudHMiICk7CgoJCQkJZm9yICggdmFyIHR5cGUgaW4gZXZlbnRzICkgewoJCQkJCWZvciAoIHZhciBoYW5kbGVyIGluIGV2ZW50c1sgdHlwZSBdICkgewoJCQkJCQlqUXVlcnkuZXZlbnQuYWRkKCB0aGlzLCB0eXBlLCBldmVudHNbIHR5cGUgXVsgaGFuZGxlciBdLCBldmVudHNbIHR5cGUgXVsgaGFuZGxlciBdLmRhdGEgKTsKCQkJCQl9CgkJCQl9CgoJCQkJaSsrOwoJCQl9KTsKCQl9CgoJCS8vIFJldHVybiB0aGUgY2xvbmVkIHNldAoJCXJldHVybiByZXQ7Cgl9LAoKCWZpbHRlcjogZnVuY3Rpb24oIHNlbGVjdG9yICkgewoJCXJldHVybiB0aGlzLnB1c2hTdGFjaygKCQkJalF1ZXJ5LmlzRnVuY3Rpb24oIHNlbGVjdG9yICkgJiYKCQkJalF1ZXJ5LmdyZXAodGhpcywgZnVuY3Rpb24oZWxlbSwgaSl7CgkJCQlyZXR1cm4gc2VsZWN0b3IuY2FsbCggZWxlbSwgaSApOwoJCQl9KSB8fAoKCQkJalF1ZXJ5Lm11bHRpRmlsdGVyKCBzZWxlY3RvciwgalF1ZXJ5LmdyZXAodGhpcywgZnVuY3Rpb24oZWxlbSl7CgkJCQlyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gMTsKCQkJfSkgKSwgImZpbHRlciIsIHNlbGVjdG9yICk7Cgl9LAoKCWNsb3Nlc3Q6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHsKCQl2YXIgcG9zID0galF1ZXJ5LmV4cHIubWF0Y2guUE9TLnRlc3QoIHNlbGVjdG9yICkgPyBqUXVlcnkoc2VsZWN0b3IpIDogbnVsbCwKCQkJY2xvc2VyID0gMDsKCgkJcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKCl7CgkJCXZhciBjdXIgPSB0aGlzOwoJCQl3aGlsZSAoIGN1ciAmJiBjdXIub3duZXJEb2N1bWVudCApIHsKCQkJCWlmICggcG9zID8gcG9zLmluZGV4KGN1cikgPiAtMSA6IGpRdWVyeShjdXIpLmlzKHNlbGVjdG9yKSApIHsKCQkJCQlqUXVlcnkuZGF0YShjdXIsICJjbG9zZXN0IiwgY2xvc2VyKTsKCQkJCQlyZXR1cm4gY3VyOwoJCQkJfQoJCQkJY3VyID0gY3VyLnBhcmVudE5vZGU7CgkJCQljbG9zZXIrKzsKCQkJfQoJCX0pOwoJfSwKCglub3Q6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHsKCQlpZiAoIHR5cGVvZiBzZWxlY3RvciA9PT0gInN0cmluZyIgKQoJCQkvLyB0ZXN0IHNwZWNpYWwgY2FzZSB3aGVyZSBqdXN0IG9uZSBzZWxlY3RvciBpcyBwYXNzZWQgaW4KCQkJaWYgKCBpc1NpbXBsZS50ZXN0KCBzZWxlY3RvciApICkKCQkJCXJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5Lm11bHRpRmlsdGVyKCBzZWxlY3RvciwgdGhpcywgdHJ1ZSApLCAibm90Iiwgc2VsZWN0b3IgKTsKCQkJZWxzZQoJCQkJc2VsZWN0b3IgPSBqUXVlcnkubXVsdGlGaWx0ZXIoIHNlbGVjdG9yLCB0aGlzICk7CgoJCXZhciBpc0FycmF5TGlrZSA9IHNlbGVjdG9yLmxlbmd0aCAmJiBzZWxlY3RvcltzZWxlY3Rvci5sZW5ndGggLSAxXSAhPT0gdW5kZWZpbmVkICYmICFzZWxlY3Rvci5ub2RlVHlwZTsKCQlyZXR1cm4gdGhpcy5maWx0ZXIoZnVuY3Rpb24oKSB7CgkJCXJldHVybiBpc0FycmF5TGlrZSA/IGpRdWVyeS5pbkFycmF5KCB0aGlzLCBzZWxlY3RvciApIDwgMCA6IHRoaXMgIT0gc2VsZWN0b3I7CgkJfSk7Cgl9LAoKCWFkZDogZnVuY3Rpb24oIHNlbGVjdG9yICkgewoJCXJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5LnVuaXF1ZSggalF1ZXJ5Lm1lcmdlKAoJCQl0aGlzLmdldCgpLAoJCQl0eXBlb2Ygc2VsZWN0b3IgPT09ICJzdHJpbmciID8KCQkJCWpRdWVyeSggc2VsZWN0b3IgKSA6CgkJCQlqUXVlcnkubWFrZUFycmF5KCBzZWxlY3RvciApCgkJKSkpOwoJfSwKCglpczogZnVuY3Rpb24oIHNlbGVjdG9yICkgewoJCXJldHVybiAhIXNlbGVjdG9yICYmIGpRdWVyeS5tdWx0aUZpbHRlciggc2VsZWN0b3IsIHRoaXMgKS5sZW5ndGggPiAwOwoJfSwKCgloYXNDbGFzczogZnVuY3Rpb24oIHNlbGVjdG9yICkgewoJCXJldHVybiAhIXNlbGVjdG9yICYmIHRoaXMuaXMoICIuIiArIHNlbGVjdG9yICk7Cgl9LAoKCXZhbDogZnVuY3Rpb24oIHZhbHVlICkgewoJCWlmICggdmFsdWUgPT09IHVuZGVmaW5lZCApIHsJCQkKCQkJdmFyIGVsZW0gPSB0aGlzWzBdOwoKCQkJaWYgKCBlbGVtICkgewoJCQkJaWYoIGpRdWVyeS5ub2RlTmFtZSggZWxlbSwgJ29wdGlvbicgKSApCgkJCQkJcmV0dXJuIChlbGVtLmF0dHJpYnV0ZXMudmFsdWUgfHwge30pLnNwZWNpZmllZCA/IGVsZW0udmFsdWUgOiBlbGVtLnRleHQ7CgkJCQkKCQkJCS8vIFdlIG5lZWQgdG8gaGFuZGxlIHNlbGVjdCBib3hlcyBzcGVjaWFsCgkJCQlpZiAoIGpRdWVyeS5ub2RlTmFtZSggZWxlbSwgInNlbGVjdCIgKSApIHsKCQkJCQl2YXIgaW5kZXggPSBlbGVtLnNlbGVjdGVkSW5kZXgsCgkJCQkJCXZhbHVlcyA9IFtdLAoJCQkJCQlvcHRpb25zID0gZWxlbS5vcHRpb25zLAoJCQkJCQlvbmUgPSBlbGVtLnR5cGUgPT0gInNlbGVjdC1vbmUiOwoKCQkJCQkvLyBOb3RoaW5nIHdhcyBzZWxlY3RlZAoJCQkJCWlmICggaW5kZXggPCAwICkKCQkJCQkJcmV0dXJuIG51bGw7CgoJCQkJCS8vIExvb3AgdGhyb3VnaCBhbGwgdGhlIHNlbGVjdGVkIG9wdGlvbnMKCQkJCQlmb3IgKCB2YXIgaSA9IG9uZSA/IGluZGV4IDogMCwgbWF4ID0gb25lID8gaW5kZXggKyAxIDogb3B0aW9ucy5sZW5ndGg7IGkgPCBtYXg7IGkrKyApIHsKCQkJCQkJdmFyIG9wdGlvbiA9IG9wdGlvbnNbIGkgXTsKCgkJCQkJCWlmICggb3B0aW9uLnNlbGVjdGVkICkgewoJCQkJCQkJLy8gR2V0IHRoZSBzcGVjaWZjIHZhbHVlIGZvciB0aGUgb3B0aW9uCgkJCQkJCQl2YWx1ZSA9IGpRdWVyeShvcHRpb24pLnZhbCgpOwoKCQkJCQkJCS8vIFdlIGRvbid0IG5lZWQgYW4gYXJyYXkgZm9yIG9uZSBzZWxlY3RzCgkJCQkJCQlpZiAoIG9uZSApCgkJCQkJCQkJcmV0dXJuIHZhbHVlOwoKCQkJCQkJCS8vIE11bHRpLVNlbGVjdHMgcmV0dXJuIGFuIGFycmF5CgkJCQkJCQl2YWx1ZXMucHVzaCggdmFsdWUgKTsKCQkJCQkJfQoJCQkJCX0KCgkJCQkJcmV0dXJuIHZhbHVlczsJCQkJCgkJCQl9CgoJCQkJLy8gRXZlcnl0aGluZyBlbHNlLCB3ZSBqdXN0IGdyYWIgdGhlIHZhbHVlCgkJCQlyZXR1cm4gKGVsZW0udmFsdWUgfHwgIiIpLnJlcGxhY2UoL1xyL2csICIiKTsKCgkJCX0KCgkJCXJldHVybiB1bmRlZmluZWQ7CgkJfQoKCQlpZiAoIHR5cGVvZiB2YWx1ZSA9PT0gIm51bWJlciIgKQoJCQl2YWx1ZSArPSAnJzsKCgkJcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpewoJCQlpZiAoIHRoaXMubm9kZVR5cGUgIT0gMSApCgkJCQlyZXR1cm47CgoJCQlpZiAoIGpRdWVyeS5pc0FycmF5KHZhbHVlKSAmJiAvcmFkaW98Y2hlY2tib3gvLnRlc3QoIHRoaXMudHlwZSApICkKCQkJCXRoaXMuY2hlY2tlZCA9IChqUXVlcnkuaW5BcnJheSh0aGlzLnZhbHVlLCB2YWx1ZSkgPj0gMCB8fAoJCQkJCWpRdWVyeS5pbkFycmF5KHRoaXMubmFtZSwgdmFsdWUpID49IDApOwoKCQkJZWxzZSBpZiAoIGpRdWVyeS5ub2RlTmFtZSggdGhpcywgInNlbGVjdCIgKSApIHsKCQkJCXZhciB2YWx1ZXMgPSBqUXVlcnkubWFrZUFycmF5KHZhbHVlKTsKCgkJCQlqUXVlcnkoICJvcHRpb24iLCB0aGlzICkuZWFjaChmdW5jdGlvbigpewoJCQkJCXRoaXMuc2VsZWN0ZWQgPSAoalF1ZXJ5LmluQXJyYXkoIHRoaXMudmFsdWUsIHZhbHVlcyApID49IDAgfHwKCQkJCQkJalF1ZXJ5LmluQXJyYXkoIHRoaXMudGV4dCwgdmFsdWVzICkgPj0gMCk7CgkJCQl9KTsKCgkJCQlpZiAoICF2YWx1ZXMubGVuZ3RoICkKCQkJCQl0aGlzLnNlbGVjdGVkSW5kZXggPSAtMTsKCgkJCX0gZWxzZQoJCQkJdGhpcy52YWx1ZSA9IHZhbHVlOwoJCX0pOwoJfSwKCglodG1sOiBmdW5jdGlvbiggdmFsdWUgKSB7CgkJcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgPwoJCQkodGhpc1swXSA/CgkJCQl0aGlzWzBdLmlubmVySFRNTC5yZXBsYWNlKC8galF1ZXJ5XGQrPSIoPzpcZCt8bnVsbCkiL2csICIiKSA6CgkJCQludWxsKSA6CgkJCXRoaXMuZW1wdHkoKS5hcHBlbmQoIHZhbHVlICk7Cgl9LAoKCXJlcGxhY2VXaXRoOiBmdW5jdGlvbiggdmFsdWUgKSB7CgkJcmV0dXJuIHRoaXMuYWZ0ZXIoIHZhbHVlICkucmVtb3ZlKCk7Cgl9LAoKCWVxOiBmdW5jdGlvbiggaSApIHsKCQlyZXR1cm4gdGhpcy5zbGljZSggaSwgK2kgKyAxICk7Cgl9LAoKCXNsaWNlOiBmdW5jdGlvbigpIHsKCQlyZXR1cm4gdGhpcy5wdXNoU3RhY2soIEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBseSggdGhpcywgYXJndW1lbnRzICksCgkJCSJzbGljZSIsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykuam9pbigiLCIpICk7Cgl9LAoKCW1hcDogZnVuY3Rpb24oIGNhbGxiYWNrICkgewoJCXJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5Lm1hcCh0aGlzLCBmdW5jdGlvbihlbGVtLCBpKXsKCQkJcmV0dXJuIGNhbGxiYWNrLmNhbGwoIGVsZW0sIGksIGVsZW0gKTsKCQl9KSk7Cgl9LAoKCWFuZFNlbGY6IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLmFkZCggdGhpcy5wcmV2T2JqZWN0ICk7Cgl9LAoKCWRvbU1hbmlwOiBmdW5jdGlvbiggYXJncywgdGFibGUsIGNhbGxiYWNrICkgewoJCWlmICggdGhpc1swXSApIHsKCQkJdmFyIGZyYWdtZW50ID0gKHRoaXNbMF0ub3duZXJEb2N1bWVudCB8fCB0aGlzWzBdKS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksCgkJCQlzY3JpcHRzID0galF1ZXJ5LmNsZWFuKCBhcmdzLCAodGhpc1swXS5vd25lckRvY3VtZW50IHx8IHRoaXNbMF0pLCBmcmFnbWVudCApLAoJCQkJZmlyc3QgPSBmcmFnbWVudC5maXJzdENoaWxkOwoKCQkJaWYgKCBmaXJzdCApCgkJCQlmb3IgKCB2YXIgaSA9IDAsIGwgPSB0aGlzLmxlbmd0aDsgaSA8IGw7IGkrKyApCgkJCQkJY2FsbGJhY2suY2FsbCggcm9vdCh0aGlzW2ldLCBmaXJzdCksIHRoaXMubGVuZ3RoID4gMSB8fCBpID4gMCA/CgkJCQkJCQlmcmFnbWVudC5jbG9uZU5vZGUodHJ1ZSkgOiBmcmFnbWVudCApOwoJCQoJCQlpZiAoIHNjcmlwdHMgKQoJCQkJalF1ZXJ5LmVhY2goIHNjcmlwdHMsIGV2YWxTY3JpcHQgKTsKCQl9CgoJCXJldHVybiB0aGlzOwoJCQoJCWZ1bmN0aW9uIHJvb3QoIGVsZW0sIGN1ciApIHsKCQkJcmV0dXJuIHRhYmxlICYmIGpRdWVyeS5ub2RlTmFtZShlbGVtLCAidGFibGUiKSAmJiBqUXVlcnkubm9kZU5hbWUoY3VyLCAidHIiKSA/CgkJCQkoZWxlbS5nZXRFbGVtZW50c0J5VGFnTmFtZSgidGJvZHkiKVswXSB8fAoJCQkJZWxlbS5hcHBlbmRDaGlsZChlbGVtLm93bmVyRG9jdW1lbnQuY3JlYXRlRWxlbWVudCgidGJvZHkiKSkpIDoKCQkJCWVsZW07CgkJfQoJfQp9OwoKLy8gR2l2ZSB0aGUgaW5pdCBmdW5jdGlvbiB0aGUgalF1ZXJ5IHByb3RvdHlwZSBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvbgpqUXVlcnkuZm4uaW5pdC5wcm90b3R5cGUgPSBqUXVlcnkuZm47CgpmdW5jdGlvbiBldmFsU2NyaXB0KCBpLCBlbGVtICkgewoJaWYgKCBlbGVtLnNyYyApCgkJalF1ZXJ5LmFqYXgoewoJCQl1cmw6IGVsZW0uc3JjLAoJCQlhc3luYzogZmFsc2UsCgkJCWRhdGFUeXBlOiAic2NyaXB0IgoJCX0pOwoKCWVsc2UKCQlqUXVlcnkuZ2xvYmFsRXZhbCggZWxlbS50ZXh0IHx8IGVsZW0udGV4dENvbnRlbnQgfHwgZWxlbS5pbm5lckhUTUwgfHwgIiIgKTsKCglpZiAoIGVsZW0ucGFyZW50Tm9kZSApCgkJZWxlbS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBlbGVtICk7Cn0KCmZ1bmN0aW9uIG5vdygpewoJcmV0dXJuICtuZXcgRGF0ZTsKfQoKalF1ZXJ5LmV4dGVuZCA9IGpRdWVyeS5mbi5leHRlbmQgPSBmdW5jdGlvbigpIHsKCS8vIGNvcHkgcmVmZXJlbmNlIHRvIHRhcmdldCBvYmplY3QKCXZhciB0YXJnZXQgPSBhcmd1bWVudHNbMF0gfHwge30sIGkgPSAxLCBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLCBkZWVwID0gZmFsc2UsIG9wdGlvbnM7CgoJLy8gSGFuZGxlIGEgZGVlcCBjb3B5IHNpdHVhdGlvbgoJaWYgKCB0eXBlb2YgdGFyZ2V0ID09PSAiYm9vbGVhbiIgKSB7CgkJZGVlcCA9IHRhcmdldDsKCQl0YXJnZXQgPSBhcmd1bWVudHNbMV0gfHwge307CgkJLy8gc2tpcCB0aGUgYm9vbGVhbiBhbmQgdGhlIHRhcmdldAoJCWkgPSAyOwoJfQoKCS8vIEhhbmRsZSBjYXNlIHdoZW4gdGFyZ2V0IGlzIGEgc3RyaW5nIG9yIHNvbWV0aGluZyAocG9zc2libGUgaW4gZGVlcCBjb3B5KQoJaWYgKCB0eXBlb2YgdGFyZ2V0ICE9PSAib2JqZWN0IiAmJiAhalF1ZXJ5LmlzRnVuY3Rpb24odGFyZ2V0KSApCgkJdGFyZ2V0ID0ge307CgoJLy8gZXh0ZW5kIGpRdWVyeSBpdHNlbGYgaWYgb25seSBvbmUgYXJndW1lbnQgaXMgcGFzc2VkCglpZiAoIGxlbmd0aCA9PSBpICkgewoJCXRhcmdldCA9IHRoaXM7CgkJLS1pOwoJfQoKCWZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkKCQkvLyBPbmx5IGRlYWwgd2l0aCBub24tbnVsbC91bmRlZmluZWQgdmFsdWVzCgkJaWYgKCAob3B0aW9ucyA9IGFyZ3VtZW50c1sgaSBdKSAhPSBudWxsICkKCQkJLy8gRXh0ZW5kIHRoZSBiYXNlIG9iamVjdAoJCQlmb3IgKCB2YXIgbmFtZSBpbiBvcHRpb25zICkgewoJCQkJdmFyIHNyYyA9IHRhcmdldFsgbmFtZSBdLCBjb3B5ID0gb3B0aW9uc1sgbmFtZSBdOwoKCQkJCS8vIFByZXZlbnQgbmV2ZXItZW5kaW5nIGxvb3AKCQkJCWlmICggdGFyZ2V0ID09PSBjb3B5ICkKCQkJCQljb250aW51ZTsKCgkJCQkvLyBSZWN1cnNlIGlmIHdlJ3JlIG1lcmdpbmcgb2JqZWN0IHZhbHVlcwoJCQkJaWYgKCBkZWVwICYmIGNvcHkgJiYgdHlwZW9mIGNvcHkgPT09ICJvYmplY3QiICYmICFjb3B5Lm5vZGVUeXBlICkKCQkJCQl0YXJnZXRbIG5hbWUgXSA9IGpRdWVyeS5leHRlbmQoIGRlZXAsIAoJCQkJCQkvLyBOZXZlciBtb3ZlIG9yaWdpbmFsIG9iamVjdHMsIGNsb25lIHRoZW0KCQkJCQkJc3JjIHx8ICggY29weS5sZW5ndGggIT0gbnVsbCA/IFsgXSA6IHsgfSApCgkJCQkJLCBjb3B5ICk7CgoJCQkJLy8gRG9uJ3QgYnJpbmcgaW4gdW5kZWZpbmVkIHZhbHVlcwoJCQkJZWxzZSBpZiAoIGNvcHkgIT09IHVuZGVmaW5lZCApCgkJCQkJdGFyZ2V0WyBuYW1lIF0gPSBjb3B5OwoKCQkJfQoKCS8vIFJldHVybiB0aGUgbW9kaWZpZWQgb2JqZWN0CglyZXR1cm4gdGFyZ2V0Owp9OwoKLy8gZXhjbHVkZSB0aGUgZm9sbG93aW5nIGNzcyBwcm9wZXJ0aWVzIHRvIGFkZCBweAp2YXIJZXhjbHVkZSA9IC96LT9pbmRleHxmb250LT93ZWlnaHR8b3BhY2l0eXx6b29tfGxpbmUtP2hlaWdodC9pLAoJLy8gY2FjaGUgZGVmYXVsdFZpZXcKCWRlZmF1bHRWaWV3ID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcgfHwge30sCgl0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7CgpqUXVlcnkuZXh0ZW5kKHsKCW5vQ29uZmxpY3Q6IGZ1bmN0aW9uKCBkZWVwICkgewoJCXdpbmRvdy4kID0gXyQ7CgoJCWlmICggZGVlcCApCgkJCXdpbmRvdy5qUXVlcnkgPSBfalF1ZXJ5OwoKCQlyZXR1cm4galF1ZXJ5OwoJfSwKCgkvLyBTZWUgdGVzdC91bml0L2NvcmUuanMgZm9yIGRldGFpbHMgY29uY2VybmluZyBpc0Z1bmN0aW9uLgoJLy8gU2luY2UgdmVyc2lvbiAxLjMsIERPTSBtZXRob2RzIGFuZCBmdW5jdGlvbnMgbGlrZSBhbGVydAoJLy8gYXJlbid0IHN1cHBvcnRlZC4gVGhleSByZXR1cm4gZmFsc2Ugb24gSUUgKCMyOTY4KS4KCWlzRnVuY3Rpb246IGZ1bmN0aW9uKCBvYmogKSB7CgkJcmV0dXJuIHRvU3RyaW5nLmNhbGwob2JqKSA9PT0gIltvYmplY3QgRnVuY3Rpb25dIjsKCX0sCgoJaXNBcnJheTogZnVuY3Rpb24oIG9iaiApIHsKCQlyZXR1cm4gdG9TdHJpbmcuY2FsbChvYmopID09PSAiW29iamVjdCBBcnJheV0iOwoJfSwKCgkvLyBjaGVjayBpZiBhbiBlbGVtZW50IGlzIGluIGEgKG9yIGlzIGFuKSBYTUwgZG9jdW1lbnQKCWlzWE1MRG9jOiBmdW5jdGlvbiggZWxlbSApIHsKCQlyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gOSAmJiBlbGVtLmRvY3VtZW50RWxlbWVudC5ub2RlTmFtZSAhPT0gIkhUTUwiIHx8CgkJCSEhZWxlbS5vd25lckRvY3VtZW50ICYmIGpRdWVyeS5pc1hNTERvYyggZWxlbS5vd25lckRvY3VtZW50ICk7Cgl9LAoKCS8vIEV2YWx1bGF0ZXMgYSBzY3JpcHQgaW4gYSBnbG9iYWwgY29udGV4dAoJZ2xvYmFsRXZhbDogZnVuY3Rpb24oIGRhdGEgKSB7CgkJaWYgKCBkYXRhICYmIC9cUy8udGVzdChkYXRhKSApIHsKCQkJLy8gSW5zcGlyZWQgYnkgY29kZSBieSBBbmRyZWEgR2lhbW1hcmNoaQoJCQkvLyBodHRwOi8vd2VicmVmbGVjdGlvbi5ibG9nc3BvdC5jb20vMjAwNy8wOC9nbG9iYWwtc2NvcGUtZXZhbHVhdGlvbi1hbmQtZG9tLmh0bWwKCQkJdmFyIGhlYWQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiaGVhZCIpWzBdIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwKCQkJCXNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNjcmlwdCIpOwoKCQkJc2NyaXB0LnR5cGUgPSAidGV4dC9qYXZhc2NyaXB0IjsKCQkJaWYgKCBqUXVlcnkuc3VwcG9ydC5zY3JpcHRFdmFsICkKCQkJCXNjcmlwdC5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoIGRhdGEgKSApOwoJCQllbHNlCgkJCQlzY3JpcHQudGV4dCA9IGRhdGE7CgoJCQkvLyBVc2UgaW5zZXJ0QmVmb3JlIGluc3RlYWQgb2YgYXBwZW5kQ2hpbGQgIHRvIGNpcmN1bXZlbnQgYW4gSUU2IGJ1Zy4KCQkJLy8gVGhpcyBhcmlzZXMgd2hlbiBhIGJhc2Ugbm9kZSBpcyB1c2VkICgjMjcwOSkuCgkJCWhlYWQuaW5zZXJ0QmVmb3JlKCBzY3JpcHQsIGhlYWQuZmlyc3RDaGlsZCApOwoJCQloZWFkLnJlbW92ZUNoaWxkKCBzY3JpcHQgKTsKCQl9Cgl9LAoKCW5vZGVOYW1lOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHsKCQlyZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT0gbmFtZS50b1VwcGVyQ2FzZSgpOwoJfSwKCgkvLyBhcmdzIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5CgllYWNoOiBmdW5jdGlvbiggb2JqZWN0LCBjYWxsYmFjaywgYXJncyApIHsKCQl2YXIgbmFtZSwgaSA9IDAsIGxlbmd0aCA9IG9iamVjdC5sZW5ndGg7CgoJCWlmICggYXJncyApIHsKCQkJaWYgKCBsZW5ndGggPT09IHVuZGVmaW5lZCApIHsKCQkJCWZvciAoIG5hbWUgaW4gb2JqZWN0ICkKCQkJCQlpZiAoIGNhbGxiYWNrLmFwcGx5KCBvYmplY3RbIG5hbWUgXSwgYXJncyApID09PSBmYWxzZSApCgkJCQkJCWJyZWFrOwoJCQl9IGVsc2UKCQkJCWZvciAoIDsgaSA8IGxlbmd0aDsgKQoJCQkJCWlmICggY2FsbGJhY2suYXBwbHkoIG9iamVjdFsgaSsrIF0sIGFyZ3MgKSA9PT0gZmFsc2UgKQoJCQkJCQlicmVhazsKCgkJLy8gQSBzcGVjaWFsLCBmYXN0LCBjYXNlIGZvciB0aGUgbW9zdCBjb21tb24gdXNlIG9mIGVhY2gKCQl9IGVsc2UgewoJCQlpZiAoIGxlbmd0aCA9PT0gdW5kZWZpbmVkICkgewoJCQkJZm9yICggbmFtZSBpbiBvYmplY3QgKQoJCQkJCWlmICggY2FsbGJhY2suY2FsbCggb2JqZWN0WyBuYW1lIF0sIG5hbWUsIG9iamVjdFsgbmFtZSBdICkgPT09IGZhbHNlICkKCQkJCQkJYnJlYWs7CgkJCX0gZWxzZQoJCQkJZm9yICggdmFyIHZhbHVlID0gb2JqZWN0WzBdOwoJCQkJCWkgPCBsZW5ndGggJiYgY2FsbGJhY2suY2FsbCggdmFsdWUsIGksIHZhbHVlICkgIT09IGZhbHNlOyB2YWx1ZSA9IG9iamVjdFsrK2ldICl7fQoJCX0KCgkJcmV0dXJuIG9iamVjdDsKCX0sCgoJcHJvcDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlLCB0eXBlLCBpLCBuYW1lICkgewoJCS8vIEhhbmRsZSBleGVjdXRhYmxlIGZ1bmN0aW9ucwoJCWlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKQoJCQl2YWx1ZSA9IHZhbHVlLmNhbGwoIGVsZW0sIGkgKTsKCgkJLy8gSGFuZGxlIHBhc3NpbmcgaW4gYSBudW1iZXIgdG8gYSBDU1MgcHJvcGVydHkKCQlyZXR1cm4gdHlwZW9mIHZhbHVlID09PSAibnVtYmVyIiAmJiB0eXBlID09ICJjdXJDU1MiICYmICFleGNsdWRlLnRlc3QoIG5hbWUgKSA/CgkJCXZhbHVlICsgInB4IiA6CgkJCXZhbHVlOwoJfSwKCgljbGFzc05hbWU6IHsKCQkvLyBpbnRlcm5hbCBvbmx5LCB1c2UgYWRkQ2xhc3MoImNsYXNzIikKCQlhZGQ6IGZ1bmN0aW9uKCBlbGVtLCBjbGFzc05hbWVzICkgewoJCQlqUXVlcnkuZWFjaCgoY2xhc3NOYW1lcyB8fCAiIikuc3BsaXQoL1xzKy8pLCBmdW5jdGlvbihpLCBjbGFzc05hbWUpewoJCQkJaWYgKCBlbGVtLm5vZGVUeXBlID09IDEgJiYgIWpRdWVyeS5jbGFzc05hbWUuaGFzKCBlbGVtLmNsYXNzTmFtZSwgY2xhc3NOYW1lICkgKQoJCQkJCWVsZW0uY2xhc3NOYW1lICs9IChlbGVtLmNsYXNzTmFtZSA/ICIgIiA6ICIiKSArIGNsYXNzTmFtZTsKCQkJfSk7CgkJfSwKCgkJLy8gaW50ZXJuYWwgb25seSwgdXNlIHJlbW92ZUNsYXNzKCJjbGFzcyIpCgkJcmVtb3ZlOiBmdW5jdGlvbiggZWxlbSwgY2xhc3NOYW1lcyApIHsKCQkJaWYgKGVsZW0ubm9kZVR5cGUgPT0gMSkKCQkJCWVsZW0uY2xhc3NOYW1lID0gY2xhc3NOYW1lcyAhPT0gdW5kZWZpbmVkID8KCQkJCQlqUXVlcnkuZ3JlcChlbGVtLmNsYXNzTmFtZS5zcGxpdCgvXHMrLyksIGZ1bmN0aW9uKGNsYXNzTmFtZSl7CgkJCQkJCXJldHVybiAhalF1ZXJ5LmNsYXNzTmFtZS5oYXMoIGNsYXNzTmFtZXMsIGNsYXNzTmFtZSApOwoJCQkJCX0pLmpvaW4oIiAiKSA6CgkJCQkJIiI7CgkJfSwKCgkJLy8gaW50ZXJuYWwgb25seSwgdXNlIGhhc0NsYXNzKCJjbGFzcyIpCgkJaGFzOiBmdW5jdGlvbiggZWxlbSwgY2xhc3NOYW1lICkgewoJCQlyZXR1cm4gZWxlbSAmJiBqUXVlcnkuaW5BcnJheSggY2xhc3NOYW1lLCAoZWxlbS5jbGFzc05hbWUgfHwgZWxlbSkudG9TdHJpbmcoKS5zcGxpdCgvXHMrLykgKSA+IC0xOwoJCX0KCX0sCgoJLy8gQSBtZXRob2QgZm9yIHF1aWNrbHkgc3dhcHBpbmcgaW4vb3V0IENTUyBwcm9wZXJ0aWVzIHRvIGdldCBjb3JyZWN0IGNhbGN1bGF0aW9ucwoJc3dhcDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGNhbGxiYWNrICkgewoJCXZhciBvbGQgPSB7fTsKCQkvLyBSZW1lbWJlciB0aGUgb2xkIHZhbHVlcywgYW5kIGluc2VydCB0aGUgbmV3IG9uZXMKCQlmb3IgKCB2YXIgbmFtZSBpbiBvcHRpb25zICkgewoJCQlvbGRbIG5hbWUgXSA9IGVsZW0uc3R5bGVbIG5hbWUgXTsKCQkJZWxlbS5zdHlsZVsgbmFtZSBdID0gb3B0aW9uc1sgbmFtZSBdOwoJCX0KCgkJY2FsbGJhY2suY2FsbCggZWxlbSApOwoKCQkvLyBSZXZlcnQgdGhlIG9sZCB2YWx1ZXMKCQlmb3IgKCB2YXIgbmFtZSBpbiBvcHRpb25zICkKCQkJZWxlbS5zdHlsZVsgbmFtZSBdID0gb2xkWyBuYW1lIF07Cgl9LAoKCWNzczogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGZvcmNlLCBleHRyYSApIHsKCQlpZiAoIG5hbWUgPT0gIndpZHRoIiB8fCBuYW1lID09ICJoZWlnaHQiICkgewoJCQl2YXIgdmFsLCBwcm9wcyA9IHsgcG9zaXRpb246ICJhYnNvbHV0ZSIsIHZpc2liaWxpdHk6ICJoaWRkZW4iLCBkaXNwbGF5OiJibG9jayIgfSwgd2hpY2ggPSBuYW1lID09ICJ3aWR0aCIgPyBbICJMZWZ0IiwgIlJpZ2h0IiBdIDogWyAiVG9wIiwgIkJvdHRvbSIgXTsKCgkJCWZ1bmN0aW9uIGdldFdIKCkgewoJCQkJdmFsID0gbmFtZSA9PSAid2lkdGgiID8gZWxlbS5vZmZzZXRXaWR0aCA6IGVsZW0ub2Zmc2V0SGVpZ2h0OwoKCQkJCWlmICggZXh0cmEgPT09ICJib3JkZXIiICkKCQkJCQlyZXR1cm47CgoJCQkJalF1ZXJ5LmVhY2goIHdoaWNoLCBmdW5jdGlvbigpIHsKCQkJCQlpZiAoICFleHRyYSApCgkJCQkJCXZhbCAtPSBwYXJzZUZsb2F0KGpRdWVyeS5jdXJDU1MoIGVsZW0sICJwYWRkaW5nIiArIHRoaXMsIHRydWUpKSB8fCAwOwoJCQkJCWlmICggZXh0cmEgPT09ICJtYXJnaW4iICkKCQkJCQkJdmFsICs9IHBhcnNlRmxvYXQoalF1ZXJ5LmN1ckNTUyggZWxlbSwgIm1hcmdpbiIgKyB0aGlzLCB0cnVlKSkgfHwgMDsKCQkJCQllbHNlCgkJCQkJCXZhbCAtPSBwYXJzZUZsb2F0KGpRdWVyeS5jdXJDU1MoIGVsZW0sICJib3JkZXIiICsgdGhpcyArICJXaWR0aCIsIHRydWUpKSB8fCAwOwoJCQkJfSk7CgkJCX0KCgkJCWlmICggZWxlbS5vZmZzZXRXaWR0aCAhPT0gMCApCgkJCQlnZXRXSCgpOwoJCQllbHNlCgkJCQlqUXVlcnkuc3dhcCggZWxlbSwgcHJvcHMsIGdldFdIICk7CgoJCQlyZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5yb3VuZCh2YWwpKTsKCQl9CgoJCXJldHVybiBqUXVlcnkuY3VyQ1NTKCBlbGVtLCBuYW1lLCBmb3JjZSApOwoJfSwKCgljdXJDU1M6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBmb3JjZSApIHsKCQl2YXIgcmV0LCBzdHlsZSA9IGVsZW0uc3R5bGU7CgoJCS8vIFdlIG5lZWQgdG8gaGFuZGxlIG9wYWNpdHkgc3BlY2lhbCBpbiBJRQoJCWlmICggbmFtZSA9PSAib3BhY2l0eSIgJiYgIWpRdWVyeS5zdXBwb3J0Lm9wYWNpdHkgKSB7CgkJCXJldCA9IGpRdWVyeS5hdHRyKCBzdHlsZSwgIm9wYWNpdHkiICk7CgoJCQlyZXR1cm4gcmV0ID09ICIiID8KCQkJCSIxIiA6CgkJCQlyZXQ7CgkJfQoKCQkvLyBNYWtlIHN1cmUgd2UncmUgdXNpbmcgdGhlIHJpZ2h0IG5hbWUgZm9yIGdldHRpbmcgdGhlIGZsb2F0IHZhbHVlCgkJaWYgKCBuYW1lLm1hdGNoKCAvZmxvYXQvaSApICkKCQkJbmFtZSA9IHN0eWxlRmxvYXQ7CgoJCWlmICggIWZvcmNlICYmIHN0eWxlICYmIHN0eWxlWyBuYW1lIF0gKQoJCQlyZXQgPSBzdHlsZVsgbmFtZSBdOwoKCQllbHNlIGlmICggZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZSApIHsKCgkJCS8vIE9ubHkgImZsb2F0IiBpcyBuZWVkZWQgaGVyZQoJCQlpZiAoIG5hbWUubWF0Y2goIC9mbG9hdC9pICkgKQoJCQkJbmFtZSA9ICJmbG9hdCI7CgoJCQluYW1lID0gbmFtZS5yZXBsYWNlKCAvKFtBLVpdKS9nLCAiLSQxIiApLnRvTG93ZXJDYXNlKCk7CgoJCQl2YXIgY29tcHV0ZWRTdHlsZSA9IGRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGUoIGVsZW0sIG51bGwgKTsKCgkJCWlmICggY29tcHV0ZWRTdHlsZSApCgkJCQlyZXQgPSBjb21wdXRlZFN0eWxlLmdldFByb3BlcnR5VmFsdWUoIG5hbWUgKTsKCgkJCS8vIFdlIHNob3VsZCBhbHdheXMgZ2V0IGEgbnVtYmVyIGJhY2sgZnJvbSBvcGFjaXR5CgkJCWlmICggbmFtZSA9PSAib3BhY2l0eSIgJiYgcmV0ID09ICIiICkKCQkJCXJldCA9ICIxIjsKCgkJfSBlbHNlIGlmICggZWxlbS5jdXJyZW50U3R5bGUgKSB7CgkJCXZhciBjYW1lbENhc2UgPSBuYW1lLnJlcGxhY2UoL1wtKFx3KS9nLCBmdW5jdGlvbihhbGwsIGxldHRlcil7CgkJCQlyZXR1cm4gbGV0dGVyLnRvVXBwZXJDYXNlKCk7CgkJCX0pOwoKCQkJcmV0ID0gZWxlbS5jdXJyZW50U3R5bGVbIG5hbWUgXSB8fCBlbGVtLmN1cnJlbnRTdHlsZVsgY2FtZWxDYXNlIF07CgoJCQkvLyBGcm9tIHRoZSBhd2Vzb21lIGhhY2sgYnkgRGVhbiBFZHdhcmRzCgkJCS8vIGh0dHA6Ly9lcmlrLmVhZS5uZXQvYXJjaGl2ZXMvMjAwNy8wNy8yNy8xOC41NC4xNS8jY29tbWVudC0xMDIyOTEKCgkJCS8vIElmIHdlJ3JlIG5vdCBkZWFsaW5nIHdpdGggYSByZWd1bGFyIHBpeGVsIG51bWJlcgoJCQkvLyBidXQgYSBudW1iZXIgdGhhdCBoYXMgYSB3ZWlyZCBlbmRpbmcsIHdlIG5lZWQgdG8gY29udmVydCBpdCB0byBwaXhlbHMKCQkJaWYgKCAhL15cZCsocHgpPyQvaS50ZXN0KCByZXQgKSAmJiAvXlxkLy50ZXN0KCByZXQgKSApIHsKCQkJCS8vIFJlbWVtYmVyIHRoZSBvcmlnaW5hbCB2YWx1ZXMKCQkJCXZhciBsZWZ0ID0gc3R5bGUubGVmdCwgcnNMZWZ0ID0gZWxlbS5ydW50aW1lU3R5bGUubGVmdDsKCgkJCQkvLyBQdXQgaW4gdGhlIG5ldyB2YWx1ZXMgdG8gZ2V0IGEgY29tcHV0ZWQgdmFsdWUgb3V0CgkJCQllbGVtLnJ1bnRpbWVTdHlsZS5sZWZ0ID0gZWxlbS5jdXJyZW50U3R5bGUubGVmdDsKCQkJCXN0eWxlLmxlZnQgPSByZXQgfHwgMDsKCQkJCXJldCA9IHN0eWxlLnBpeGVsTGVmdCArICJweCI7CgoJCQkJLy8gUmV2ZXJ0IHRoZSBjaGFuZ2VkIHZhbHVlcwoJCQkJc3R5bGUubGVmdCA9IGxlZnQ7CgkJCQllbGVtLnJ1bnRpbWVTdHlsZS5sZWZ0ID0gcnNMZWZ0OwoJCQl9CgkJfQoKCQlyZXR1cm4gcmV0OwoJfSwKCgljbGVhbjogZnVuY3Rpb24oIGVsZW1zLCBjb250ZXh0LCBmcmFnbWVudCApIHsKCQljb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDsKCgkJLy8gIWNvbnRleHQuY3JlYXRlRWxlbWVudCBmYWlscyBpbiBJRSB3aXRoIGFuIGVycm9yIGJ1dCByZXR1cm5zIHR5cGVvZiAnb2JqZWN0JwoJCWlmICggdHlwZW9mIGNvbnRleHQuY3JlYXRlRWxlbWVudCA9PT0gInVuZGVmaW5lZCIgKQoJCQljb250ZXh0ID0gY29udGV4dC5vd25lckRvY3VtZW50IHx8IGNvbnRleHRbMF0gJiYgY29udGV4dFswXS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50OwoKCQkvLyBJZiBhIHNpbmdsZSBzdHJpbmcgaXMgcGFzc2VkIGluIGFuZCBpdCdzIGEgc2luZ2xlIHRhZwoJCS8vIGp1c3QgZG8gYSBjcmVhdGVFbGVtZW50IGFuZCBza2lwIHRoZSByZXN0CgkJaWYgKCAhZnJhZ21lbnQgJiYgZWxlbXMubGVuZ3RoID09PSAxICYmIHR5cGVvZiBlbGVtc1swXSA9PT0gInN0cmluZyIgKSB7CgkJCXZhciBtYXRjaCA9IC9ePChcdyspXHMqXC8/PiQvLmV4ZWMoZWxlbXNbMF0pOwoJCQlpZiAoIG1hdGNoICkKCQkJCXJldHVybiBbIGNvbnRleHQuY3JlYXRlRWxlbWVudCggbWF0Y2hbMV0gKSBdOwoJCX0KCgkJdmFyIHJldCA9IFtdLCBzY3JpcHRzID0gW10sIGRpdiA9IGNvbnRleHQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CgoJCWpRdWVyeS5lYWNoKGVsZW1zLCBmdW5jdGlvbihpLCBlbGVtKXsKCQkJaWYgKCB0eXBlb2YgZWxlbSA9PT0gIm51bWJlciIgKQoJCQkJZWxlbSArPSAnJzsKCgkJCWlmICggIWVsZW0gKQoJCQkJcmV0dXJuOwoKCQkJLy8gQ29udmVydCBodG1sIHN0cmluZyBpbnRvIERPTSBub2RlcwoJCQlpZiAoIHR5cGVvZiBlbGVtID09PSAic3RyaW5nIiApIHsKCQkJCS8vIEZpeCAiWEhUTUwiLXN0eWxlIHRhZ3MgaW4gYWxsIGJyb3dzZXJzCgkJCQllbGVtID0gZWxlbS5yZXBsYWNlKC8oPChcdyspW14+XSo/KVwvPi9nLCBmdW5jdGlvbihhbGwsIGZyb250LCB0YWcpewoJCQkJCXJldHVybiB0YWcubWF0Y2goL14oYWJicnxicnxjb2x8aW1nfGlucHV0fGxpbmt8bWV0YXxwYXJhbXxocnxhcmVhfGVtYmVkKSQvaSkgPwoJCQkJCQlhbGwgOgoJCQkJCQlmcm9udCArICI+PC8iICsgdGFnICsgIj4iOwoJCQkJfSk7CgoJCQkJLy8gVHJpbSB3aGl0ZXNwYWNlLCBvdGhlcndpc2UgaW5kZXhPZiB3b24ndCB3b3JrIGFzIGV4cGVjdGVkCgkJCQl2YXIgdGFncyA9IGVsZW0ucmVwbGFjZSgvXlxzKy8sICIiKS5zdWJzdHJpbmcoMCwgMTApLnRvTG93ZXJDYXNlKCk7CgoJCQkJdmFyIHdyYXAgPQoJCQkJCS8vIG9wdGlvbiBvciBvcHRncm91cAoJCQkJCSF0YWdzLmluZGV4T2YoIjxvcHQiKSAmJgoJCQkJCVsgMSwgIjxzZWxlY3QgbXVsdGlwbGU9J211bHRpcGxlJz4iLCAiPC9zZWxlY3Q+IiBdIHx8CgoJCQkJCSF0YWdzLmluZGV4T2YoIjxsZWciKSAmJgoJCQkJCVsgMSwgIjxmaWVsZHNldD4iLCAiPC9maWVsZHNldD4iIF0gfHwKCgkJCQkJdGFncy5tYXRjaCgvXjwodGhlYWR8dGJvZHl8dGZvb3R8Y29sZ3xjYXApLykgJiYKCQkJCQlbIDEsICI8dGFibGU+IiwgIjwvdGFibGU+IiBdIHx8CgoJCQkJCSF0YWdzLmluZGV4T2YoIjx0ciIpICYmCgkJCQkJWyAyLCAiPHRhYmxlPjx0Ym9keT4iLCAiPC90Ym9keT48L3RhYmxlPiIgXSB8fAoKCQkJCSAJLy8gPHRoZWFkPiBtYXRjaGVkIGFib3ZlCgkJCQkJKCF0YWdzLmluZGV4T2YoIjx0ZCIpIHx8ICF0YWdzLmluZGV4T2YoIjx0aCIpKSAmJgoJCQkJCVsgMywgIjx0YWJsZT48dGJvZHk+PHRyPiIsICI8L3RyPjwvdGJvZHk+PC90YWJsZT4iIF0gfHwKCgkJCQkJIXRhZ3MuaW5kZXhPZigiPGNvbCIpICYmCgkJCQkJWyAyLCAiPHRhYmxlPjx0Ym9keT48L3Rib2R5Pjxjb2xncm91cD4iLCAiPC9jb2xncm91cD48L3RhYmxlPiIgXSB8fAoKCQkJCQkvLyBJRSBjYW4ndCBzZXJpYWxpemUgPGxpbms+IGFuZCA8c2NyaXB0PiB0YWdzIG5vcm1hbGx5CgkJCQkJIWpRdWVyeS5zdXBwb3J0Lmh0bWxTZXJpYWxpemUgJiYKCQkJCQlbIDEsICJkaXY8ZGl2PiIsICI8L2Rpdj4iIF0gfHwKCgkJCQkJWyAwLCAiIiwgIiIgXTsKCgkJCQkvLyBHbyB0byBodG1sIGFuZCBiYWNrLCB0aGVuIHBlZWwgb2ZmIGV4dHJhIHdyYXBwZXJzCgkJCQlkaXYuaW5uZXJIVE1MID0gd3JhcFsxXSArIGVsZW0gKyB3cmFwWzJdOwoKCQkJCS8vIE1vdmUgdG8gdGhlIHJpZ2h0IGRlcHRoCgkJCQl3aGlsZSAoIHdyYXBbMF0tLSApCgkJCQkJZGl2ID0gZGl2Lmxhc3RDaGlsZDsKCgkJCQkvLyBSZW1vdmUgSUUncyBhdXRvaW5zZXJ0ZWQgPHRib2R5PiBmcm9tIHRhYmxlIGZyYWdtZW50cwoJCQkJaWYgKCAhalF1ZXJ5LnN1cHBvcnQudGJvZHkgKSB7CgoJCQkJCS8vIFN0cmluZyB3YXMgYSA8dGFibGU+LCAqbWF5KiBoYXZlIHNwdXJpb3VzIDx0Ym9keT4KCQkJCQl2YXIgaGFzQm9keSA9IC88dGJvZHkvaS50ZXN0KGVsZW0pLAoJCQkJCQl0Ym9keSA9ICF0YWdzLmluZGV4T2YoIjx0YWJsZSIpICYmICFoYXNCb2R5ID8KCQkJCQkJCWRpdi5maXJzdENoaWxkICYmIGRpdi5maXJzdENoaWxkLmNoaWxkTm9kZXMgOgoKCQkJCQkJLy8gU3RyaW5nIHdhcyBhIGJhcmUgPHRoZWFkPiBvciA8dGZvb3Q+CgkJCQkJCXdyYXBbMV0gPT0gIjx0YWJsZT4iICYmICFoYXNCb2R5ID8KCQkJCQkJCWRpdi5jaGlsZE5vZGVzIDoKCQkJCQkJCVtdOwoKCQkJCQlmb3IgKCB2YXIgaiA9IHRib2R5Lmxlbmd0aCAtIDE7IGogPj0gMCA7IC0taiApCgkJCQkJCWlmICggalF1ZXJ5Lm5vZGVOYW1lKCB0Ym9keVsgaiBdLCAidGJvZHkiICkgJiYgIXRib2R5WyBqIF0uY2hpbGROb2Rlcy5sZW5ndGggKQoJCQkJCQkJdGJvZHlbIGogXS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCB0Ym9keVsgaiBdICk7CgoJCQkJCX0KCgkJCQkvLyBJRSBjb21wbGV0ZWx5IGtpbGxzIGxlYWRpbmcgd2hpdGVzcGFjZSB3aGVuIGlubmVySFRNTCBpcyB1c2VkCgkJCQlpZiAoICFqUXVlcnkuc3VwcG9ydC5sZWFkaW5nV2hpdGVzcGFjZSAmJiAvXlxzLy50ZXN0KCBlbGVtICkgKQoJCQkJCWRpdi5pbnNlcnRCZWZvcmUoIGNvbnRleHQuY3JlYXRlVGV4dE5vZGUoIGVsZW0ubWF0Y2goL15ccyovKVswXSApLCBkaXYuZmlyc3RDaGlsZCApOwoJCQkJCgkJCQllbGVtID0galF1ZXJ5Lm1ha2VBcnJheSggZGl2LmNoaWxkTm9kZXMgKTsKCQkJfQoKCQkJaWYgKCBlbGVtLm5vZGVUeXBlICkKCQkJCXJldC5wdXNoKCBlbGVtICk7CgkJCWVsc2UKCQkJCXJldCA9IGpRdWVyeS5tZXJnZSggcmV0LCBlbGVtICk7CgoJCX0pOwoKCQlpZiAoIGZyYWdtZW50ICkgewoJCQlmb3IgKCB2YXIgaSA9IDA7IHJldFtpXTsgaSsrICkgewoJCQkJaWYgKCBqUXVlcnkubm9kZU5hbWUoIHJldFtpXSwgInNjcmlwdCIgKSAmJiAoIXJldFtpXS50eXBlIHx8IHJldFtpXS50eXBlLnRvTG93ZXJDYXNlKCkgPT09ICJ0ZXh0L2phdmFzY3JpcHQiKSApIHsKCQkJCQlzY3JpcHRzLnB1c2goIHJldFtpXS5wYXJlbnROb2RlID8gcmV0W2ldLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHJldFtpXSApIDogcmV0W2ldICk7CgkJCQl9IGVsc2UgewoJCQkJCWlmICggcmV0W2ldLm5vZGVUeXBlID09PSAxICkKCQkJCQkJcmV0LnNwbGljZS5hcHBseSggcmV0LCBbaSArIDEsIDBdLmNvbmNhdChqUXVlcnkubWFrZUFycmF5KHJldFtpXS5nZXRFbGVtZW50c0J5VGFnTmFtZSgic2NyaXB0IikpKSApOwoJCQkJCWZyYWdtZW50LmFwcGVuZENoaWxkKCByZXRbaV0gKTsKCQkJCX0KCQkJfQoJCQkKCQkJcmV0dXJuIHNjcmlwdHM7CgkJfQoKCQlyZXR1cm4gcmV0OwoJfSwKCglhdHRyOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7CgkJLy8gZG9uJ3Qgc2V0IGF0dHJpYnV0ZXMgb24gdGV4dCBhbmQgY29tbWVudCBub2RlcwoJCWlmICghZWxlbSB8fCBlbGVtLm5vZGVUeXBlID09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PSA4KQoJCQlyZXR1cm4gdW5kZWZpbmVkOwoKCQl2YXIgbm90eG1sID0gIWpRdWVyeS5pc1hNTERvYyggZWxlbSApLAoJCQkvLyBXaGV0aGVyIHdlIGFyZSBzZXR0aW5nIChvciBnZXR0aW5nKQoJCQlzZXQgPSB2YWx1ZSAhPT0gdW5kZWZpbmVkOwoKCQkvLyBUcnkgdG8gbm9ybWFsaXplL2ZpeCB0aGUgbmFtZQoJCW5hbWUgPSBub3R4bWwgJiYgalF1ZXJ5LnByb3BzWyBuYW1lIF0gfHwgbmFtZTsKCgkJLy8gT25seSBkbyBhbGwgdGhlIGZvbGxvd2luZyBpZiB0aGlzIGlzIGEgbm9kZSAoZmFzdGVyIGZvciBzdHlsZSkKCQkvLyBJRSBlbGVtLmdldEF0dHJpYnV0ZSBwYXNzZXMgZXZlbiBmb3Igc3R5bGUKCQlpZiAoIGVsZW0udGFnTmFtZSApIHsKCgkJCS8vIFRoZXNlIGF0dHJpYnV0ZXMgcmVxdWlyZSBzcGVjaWFsIHRyZWF0bWVudAoJCQl2YXIgc3BlY2lhbCA9IC9ocmVmfHNyY3xzdHlsZS8udGVzdCggbmFtZSApOwoKCQkJLy8gU2FmYXJpIG1pcy1yZXBvcnRzIHRoZSBkZWZhdWx0IHNlbGVjdGVkIHByb3BlcnR5IG9mIGEgaGlkZGVuIG9wdGlvbgoJCQkvLyBBY2Nlc3NpbmcgdGhlIHBhcmVudCdzIHNlbGVjdGVkSW5kZXggcHJvcGVydHkgZml4ZXMgaXQKCQkJaWYgKCBuYW1lID09ICJzZWxlY3RlZCIgJiYgZWxlbS5wYXJlbnROb2RlICkKCQkJCWVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4OwoKCQkJLy8gSWYgYXBwbGljYWJsZSwgYWNjZXNzIHRoZSBhdHRyaWJ1dGUgdmlhIHRoZSBET00gMCB3YXkKCQkJaWYgKCBuYW1lIGluIGVsZW0gJiYgbm90eG1sICYmICFzcGVjaWFsICkgewoJCQkJaWYgKCBzZXQgKXsKCQkJCQkvLyBXZSBjYW4ndCBhbGxvdyB0aGUgdHlwZSBwcm9wZXJ0eSB0byBiZSBjaGFuZ2VkIChzaW5jZSBpdCBjYXVzZXMgcHJvYmxlbXMgaW4gSUUpCgkJCQkJaWYgKCBuYW1lID09ICJ0eXBlIiAmJiBqUXVlcnkubm9kZU5hbWUoIGVsZW0sICJpbnB1dCIgKSAmJiBlbGVtLnBhcmVudE5vZGUgKQoJCQkJCQl0aHJvdyAidHlwZSBwcm9wZXJ0eSBjYW4ndCBiZSBjaGFuZ2VkIjsKCgkJCQkJZWxlbVsgbmFtZSBdID0gdmFsdWU7CgkJCQl9CgoJCQkJLy8gYnJvd3NlcnMgaW5kZXggZWxlbWVudHMgYnkgaWQvbmFtZSBvbiBmb3JtcywgZ2l2ZSBwcmlvcml0eSB0byBhdHRyaWJ1dGVzLgoJCQkJaWYoIGpRdWVyeS5ub2RlTmFtZSggZWxlbSwgImZvcm0iICkgJiYgZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKG5hbWUpICkKCQkJCQlyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCBuYW1lICkubm9kZVZhbHVlOwoKCQkJCS8vIGVsZW0udGFiSW5kZXggZG9lc24ndCBhbHdheXMgcmV0dXJuIHRoZSBjb3JyZWN0IHZhbHVlIHdoZW4gaXQgaGFzbid0IGJlZW4gZXhwbGljaXRseSBzZXQKCQkJCS8vIGh0dHA6Ly9mbHVpZHByb2plY3Qub3JnL2Jsb2cvMjAwOC8wMS8wOS9nZXR0aW5nLXNldHRpbmctYW5kLXJlbW92aW5nLXRhYmluZGV4LXZhbHVlcy13aXRoLWphdmFzY3JpcHQvCgkJCQlpZiAoIG5hbWUgPT0gInRhYkluZGV4IiApIHsKCQkJCQl2YXIgYXR0cmlidXRlTm9kZSA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggInRhYkluZGV4IiApOwoJCQkJCXJldHVybiBhdHRyaWJ1dGVOb2RlICYmIGF0dHJpYnV0ZU5vZGUuc3BlY2lmaWVkCgkJCQkJCT8gYXR0cmlidXRlTm9kZS52YWx1ZQoJCQkJCQk6IGVsZW0ubm9kZU5hbWUubWF0Y2goLyhidXR0b258aW5wdXR8b2JqZWN0fHNlbGVjdHx0ZXh0YXJlYSkvaSkKCQkJCQkJCT8gMAoJCQkJCQkJOiBlbGVtLm5vZGVOYW1lLm1hdGNoKC9eKGF8YXJlYSkkL2kpICYmIGVsZW0uaHJlZgoJCQkJCQkJCT8gMAoJCQkJCQkJCTogdW5kZWZpbmVkOwoJCQkJfQoKCQkJCXJldHVybiBlbGVtWyBuYW1lIF07CgkJCX0KCgkJCWlmICggIWpRdWVyeS5zdXBwb3J0LnN0eWxlICYmIG5vdHhtbCAmJiAgbmFtZSA9PSAic3R5bGUiICkKCQkJCXJldHVybiBqUXVlcnkuYXR0ciggZWxlbS5zdHlsZSwgImNzc1RleHQiLCB2YWx1ZSApOwoKCQkJaWYgKCBzZXQgKQoJCQkJLy8gY29udmVydCB0aGUgdmFsdWUgdG8gYSBzdHJpbmcgKGFsbCBicm93c2VycyBkbyB0aGlzIGJ1dCBJRSkgc2VlICMxMDcwCgkJCQllbGVtLnNldEF0dHJpYnV0ZSggbmFtZSwgIiIgKyB2YWx1ZSApOwoKCQkJdmFyIGF0dHIgPSAhalF1ZXJ5LnN1cHBvcnQuaHJlZk5vcm1hbGl6ZWQgJiYgbm90eG1sICYmIHNwZWNpYWwKCQkJCQkvLyBTb21lIGF0dHJpYnV0ZXMgcmVxdWlyZSBhIHNwZWNpYWwgY2FsbCBvbiBJRQoJCQkJCT8gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUsIDIgKQoJCQkJCTogZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKTsKCgkJCS8vIE5vbi1leGlzdGVudCBhdHRyaWJ1dGVzIHJldHVybiBudWxsLCB3ZSBub3JtYWxpemUgdG8gdW5kZWZpbmVkCgkJCXJldHVybiBhdHRyID09PSBudWxsID8gdW5kZWZpbmVkIDogYXR0cjsKCQl9CgoJCS8vIGVsZW0gaXMgYWN0dWFsbHkgZWxlbS5zdHlsZSAuLi4gc2V0IHRoZSBzdHlsZQoKCQkvLyBJRSB1c2VzIGZpbHRlcnMgZm9yIG9wYWNpdHkKCQlpZiAoICFqUXVlcnkuc3VwcG9ydC5vcGFjaXR5ICYmIG5hbWUgPT0gIm9wYWNpdHkiICkgewoJCQlpZiAoIHNldCApIHsKCQkJCS8vIElFIGhhcyB0cm91YmxlIHdpdGggb3BhY2l0eSBpZiBpdCBkb2VzIG5vdCBoYXZlIGxheW91dAoJCQkJLy8gRm9yY2UgaXQgYnkgc2V0dGluZyB0aGUgem9vbSBsZXZlbAoJCQkJZWxlbS56b29tID0gMTsKCgkJCQkvLyBTZXQgdGhlIGFscGhhIGZpbHRlciB0byBzZXQgdGhlIG9wYWNpdHkKCQkJCWVsZW0uZmlsdGVyID0gKGVsZW0uZmlsdGVyIHx8ICIiKS5yZXBsYWNlKCAvYWxwaGFcKFteKV0qXCkvLCAiIiApICsKCQkJCQkocGFyc2VJbnQoIHZhbHVlICkgKyAnJyA9PSAiTmFOIiA/ICIiIDogImFscGhhKG9wYWNpdHk9IiArIHZhbHVlICogMTAwICsgIikiKTsKCQkJfQoKCQkJcmV0dXJuIGVsZW0uZmlsdGVyICYmIGVsZW0uZmlsdGVyLmluZGV4T2YoIm9wYWNpdHk9IikgPj0gMCA/CgkJCQkocGFyc2VGbG9hdCggZWxlbS5maWx0ZXIubWF0Y2goL29wYWNpdHk9KFteKV0qKS8pWzFdICkgLyAxMDApICsgJyc6CgkJCQkiIjsKCQl9CgoJCW5hbWUgPSBuYW1lLnJlcGxhY2UoLy0oW2Etel0pL2lnLCBmdW5jdGlvbihhbGwsIGxldHRlcil7CgkJCXJldHVybiBsZXR0ZXIudG9VcHBlckNhc2UoKTsKCQl9KTsKCgkJaWYgKCBzZXQgKQoJCQllbGVtWyBuYW1lIF0gPSB2YWx1ZTsKCgkJcmV0dXJuIGVsZW1bIG5hbWUgXTsKCX0sCgoJdHJpbTogZnVuY3Rpb24oIHRleHQgKSB7CgkJcmV0dXJuICh0ZXh0IHx8ICIiKS5yZXBsYWNlKCAvXlxzK3xccyskL2csICIiICk7Cgl9LAoKCW1ha2VBcnJheTogZnVuY3Rpb24oIGFycmF5ICkgewoJCXZhciByZXQgPSBbXTsKCgkJaWYoIGFycmF5ICE9IG51bGwgKXsKCQkJdmFyIGkgPSBhcnJheS5sZW5ndGg7CgkJCS8vIFRoZSB3aW5kb3csIHN0cmluZ3MgKGFuZCBmdW5jdGlvbnMpIGFsc28gaGF2ZSAnbGVuZ3RoJwoJCQlpZiggaSA9PSBudWxsIHx8IHR5cGVvZiBhcnJheSA9PT0gInN0cmluZyIgfHwgalF1ZXJ5LmlzRnVuY3Rpb24oYXJyYXkpIHx8IGFycmF5LnNldEludGVydmFsICkKCQkJCXJldFswXSA9IGFycmF5OwoJCQllbHNlCgkJCQl3aGlsZSggaSApCgkJCQkJcmV0Wy0taV0gPSBhcnJheVtpXTsKCQl9CgoJCXJldHVybiByZXQ7Cgl9LAoKCWluQXJyYXk6IGZ1bmN0aW9uKCBlbGVtLCBhcnJheSApIHsKCQlmb3IgKCB2YXIgaSA9IDAsIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrICkKCQkvLyBVc2UgPT09IGJlY2F1c2Ugb24gSUUsIHdpbmRvdyA9PSBkb2N1bWVudAoJCQlpZiAoIGFycmF5WyBpIF0gPT09IGVsZW0gKQoJCQkJcmV0dXJuIGk7CgoJCXJldHVybiAtMTsKCX0sCgoJbWVyZ2U6IGZ1bmN0aW9uKCBmaXJzdCwgc2Vjb25kICkgewoJCS8vIFdlIGhhdmUgdG8gbG9vcCB0aGlzIHdheSBiZWNhdXNlIElFICYgT3BlcmEgb3ZlcndyaXRlIHRoZSBsZW5ndGgKCQkvLyBleHBhbmRvIG9mIGdldEVsZW1lbnRzQnlUYWdOYW1lCgkJdmFyIGkgPSAwLCBlbGVtLCBwb3MgPSBmaXJzdC5sZW5ndGg7CgkJLy8gQWxzbywgd2UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCB0aGUgY29ycmVjdCBlbGVtZW50cyBhcmUgYmVpbmcgcmV0dXJuZWQKCQkvLyAoSUUgcmV0dXJucyBjb21tZW50IG5vZGVzIGluIGEgJyonIHF1ZXJ5KQoJCWlmICggIWpRdWVyeS5zdXBwb3J0LmdldEFsbCApIHsKCQkJd2hpbGUgKCAoZWxlbSA9IHNlY29uZFsgaSsrIF0pICE9IG51bGwgKQoJCQkJaWYgKCBlbGVtLm5vZGVUeXBlICE9IDggKQoJCQkJCWZpcnN0WyBwb3MrKyBdID0gZWxlbTsKCgkJfSBlbHNlCgkJCXdoaWxlICggKGVsZW0gPSBzZWNvbmRbIGkrKyBdKSAhPSBudWxsICkKCQkJCWZpcnN0WyBwb3MrKyBdID0gZWxlbTsKCgkJcmV0dXJuIGZpcnN0OwoJfSwKCgl1bmlxdWU6IGZ1bmN0aW9uKCBhcnJheSApIHsKCQl2YXIgcmV0ID0gW10sIGRvbmUgPSB7fTsKCgkJdHJ5IHsKCgkJCWZvciAoIHZhciBpID0gMCwgbGVuZ3RoID0gYXJyYXkubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKysgKSB7CgkJCQl2YXIgaWQgPSBqUXVlcnkuZGF0YSggYXJyYXlbIGkgXSApOwoKCQkJCWlmICggIWRvbmVbIGlkIF0gKSB7CgkJCQkJZG9uZVsgaWQgXSA9IHRydWU7CgkJCQkJcmV0LnB1c2goIGFycmF5WyBpIF0gKTsKCQkJCX0KCQkJfQoKCQl9IGNhdGNoKCBlICkgewoJCQlyZXQgPSBhcnJheTsKCQl9CgoJCXJldHVybiByZXQ7Cgl9LAoKCWdyZXA6IGZ1bmN0aW9uKCBlbGVtcywgY2FsbGJhY2ssIGludiApIHsKCQl2YXIgcmV0ID0gW107CgoJCS8vIEdvIHRocm91Z2ggdGhlIGFycmF5LCBvbmx5IHNhdmluZyB0aGUgaXRlbXMKCQkvLyB0aGF0IHBhc3MgdGhlIHZhbGlkYXRvciBmdW5jdGlvbgoJCWZvciAoIHZhciBpID0gMCwgbGVuZ3RoID0gZWxlbXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKysgKQoJCQlpZiAoICFpbnYgIT0gIWNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpICkgKQoJCQkJcmV0LnB1c2goIGVsZW1zWyBpIF0gKTsKCgkJcmV0dXJuIHJldDsKCX0sCgoJbWFwOiBmdW5jdGlvbiggZWxlbXMsIGNhbGxiYWNrICkgewoJCXZhciByZXQgPSBbXTsKCgkJLy8gR28gdGhyb3VnaCB0aGUgYXJyYXksIHRyYW5zbGF0aW5nIGVhY2ggb2YgdGhlIGl0ZW1zIHRvIHRoZWlyCgkJLy8gbmV3IHZhbHVlIChvciB2YWx1ZXMpLgoJCWZvciAoIHZhciBpID0gMCwgbGVuZ3RoID0gZWxlbXMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKysgKSB7CgkJCXZhciB2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpICk7CgoJCQlpZiAoIHZhbHVlICE9IG51bGwgKQoJCQkJcmV0WyByZXQubGVuZ3RoIF0gPSB2YWx1ZTsKCQl9CgoJCXJldHVybiByZXQuY29uY2F0LmFwcGx5KCBbXSwgcmV0ICk7Cgl9Cn0pOwoKLy8gVXNlIG9mIGpRdWVyeS5icm93c2VyIGlzIGRlcHJlY2F0ZWQuCi8vIEl0J3MgaW5jbHVkZWQgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IGFuZCBwbHVnaW5zLAovLyBhbHRob3VnaCB0aGV5IHNob3VsZCB3b3JrIHRvIG1pZ3JhdGUgYXdheS4KCnZhciB1c2VyQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50LnRvTG93ZXJDYXNlKCk7CgovLyBGaWd1cmUgb3V0IHdoYXQgYnJvd3NlciBpcyBiZWluZyB1c2VkCmpRdWVyeS5icm93c2VyID0gewoJdmVyc2lvbjogKHVzZXJBZ2VudC5tYXRjaCggLy4rKD86cnZ8aXR8cmF8aWUpW1wvOiBdKFtcZC5dKykvICkgfHwgWzAsJzAnXSlbMV0sCglzYWZhcmk6IC93ZWJraXQvLnRlc3QoIHVzZXJBZ2VudCApLAoJb3BlcmE6IC9vcGVyYS8udGVzdCggdXNlckFnZW50ICksCgltc2llOiAvbXNpZS8udGVzdCggdXNlckFnZW50ICkgJiYgIS9vcGVyYS8udGVzdCggdXNlckFnZW50ICksCgltb3ppbGxhOiAvbW96aWxsYS8udGVzdCggdXNlckFnZW50ICkgJiYgIS8oY29tcGF0aWJsZXx3ZWJraXQpLy50ZXN0KCB1c2VyQWdlbnQgKQp9OwoKalF1ZXJ5LmVhY2goewoJcGFyZW50OiBmdW5jdGlvbihlbGVtKXtyZXR1cm4gZWxlbS5wYXJlbnROb2RlO30sCglwYXJlbnRzOiBmdW5jdGlvbihlbGVtKXtyZXR1cm4galF1ZXJ5LmRpcihlbGVtLCJwYXJlbnROb2RlIik7fSwKCW5leHQ6IGZ1bmN0aW9uKGVsZW0pe3JldHVybiBqUXVlcnkubnRoKGVsZW0sMiwibmV4dFNpYmxpbmciKTt9LAoJcHJldjogZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGpRdWVyeS5udGgoZWxlbSwyLCJwcmV2aW91c1NpYmxpbmciKTt9LAoJbmV4dEFsbDogZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGpRdWVyeS5kaXIoZWxlbSwibmV4dFNpYmxpbmciKTt9LAoJcHJldkFsbDogZnVuY3Rpb24oZWxlbSl7cmV0dXJuIGpRdWVyeS5kaXIoZWxlbSwicHJldmlvdXNTaWJsaW5nIik7fSwKCXNpYmxpbmdzOiBmdW5jdGlvbihlbGVtKXtyZXR1cm4galF1ZXJ5LnNpYmxpbmcoZWxlbS5wYXJlbnROb2RlLmZpcnN0Q2hpbGQsZWxlbSk7fSwKCWNoaWxkcmVuOiBmdW5jdGlvbihlbGVtKXtyZXR1cm4galF1ZXJ5LnNpYmxpbmcoZWxlbS5maXJzdENoaWxkKTt9LAoJY29udGVudHM6IGZ1bmN0aW9uKGVsZW0pe3JldHVybiBqUXVlcnkubm9kZU5hbWUoZWxlbSwiaWZyYW1lIik/ZWxlbS5jb250ZW50RG9jdW1lbnR8fGVsZW0uY29udGVudFdpbmRvdy5kb2N1bWVudDpqUXVlcnkubWFrZUFycmF5KGVsZW0uY2hpbGROb2Rlcyk7fQp9LCBmdW5jdGlvbihuYW1lLCBmbil7CglqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBzZWxlY3RvciApIHsKCQl2YXIgcmV0ID0galF1ZXJ5Lm1hcCggdGhpcywgZm4gKTsKCgkJaWYgKCBzZWxlY3RvciAmJiB0eXBlb2Ygc2VsZWN0b3IgPT0gInN0cmluZyIgKQoJCQlyZXQgPSBqUXVlcnkubXVsdGlGaWx0ZXIoIHNlbGVjdG9yLCByZXQgKTsKCgkJcmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkudW5pcXVlKCByZXQgKSwgbmFtZSwgc2VsZWN0b3IgKTsKCX07Cn0pOwoKalF1ZXJ5LmVhY2goewoJYXBwZW5kVG86ICJhcHBlbmQiLAoJcHJlcGVuZFRvOiAicHJlcGVuZCIsCglpbnNlcnRCZWZvcmU6ICJiZWZvcmUiLAoJaW5zZXJ0QWZ0ZXI6ICJhZnRlciIsCglyZXBsYWNlQWxsOiAicmVwbGFjZVdpdGgiCn0sIGZ1bmN0aW9uKG5hbWUsIG9yaWdpbmFsKXsKCWpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNlbGVjdG9yICkgewoJCXZhciByZXQgPSBbXSwgaW5zZXJ0ID0galF1ZXJ5KCBzZWxlY3RvciApOwoKCQlmb3IgKCB2YXIgaSA9IDAsIGwgPSBpbnNlcnQubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCQl2YXIgZWxlbXMgPSAoaSA+IDAgPyB0aGlzLmNsb25lKHRydWUpIDogdGhpcykuZ2V0KCk7CgkJCWpRdWVyeS5mblsgb3JpZ2luYWwgXS5hcHBseSggalF1ZXJ5KGluc2VydFtpXSksIGVsZW1zICk7CgkJCXJldCA9IHJldC5jb25jYXQoIGVsZW1zICk7CgkJfQoKCQlyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHJldCwgbmFtZSwgc2VsZWN0b3IgKTsKCX07Cn0pOwoKalF1ZXJ5LmVhY2goewoJcmVtb3ZlQXR0cjogZnVuY3Rpb24oIG5hbWUgKSB7CgkJalF1ZXJ5LmF0dHIoIHRoaXMsIG5hbWUsICIiICk7CgkJaWYgKHRoaXMubm9kZVR5cGUgPT0gMSkKCQkJdGhpcy5yZW1vdmVBdHRyaWJ1dGUoIG5hbWUgKTsKCX0sCgoJYWRkQ2xhc3M6IGZ1bmN0aW9uKCBjbGFzc05hbWVzICkgewoJCWpRdWVyeS5jbGFzc05hbWUuYWRkKCB0aGlzLCBjbGFzc05hbWVzICk7Cgl9LAoKCXJlbW92ZUNsYXNzOiBmdW5jdGlvbiggY2xhc3NOYW1lcyApIHsKCQlqUXVlcnkuY2xhc3NOYW1lLnJlbW92ZSggdGhpcywgY2xhc3NOYW1lcyApOwoJfSwKCgl0b2dnbGVDbGFzczogZnVuY3Rpb24oIGNsYXNzTmFtZXMsIHN0YXRlICkgewoJCWlmKCB0eXBlb2Ygc3RhdGUgIT09ICJib29sZWFuIiApCgkJCXN0YXRlID0gIWpRdWVyeS5jbGFzc05hbWUuaGFzKCB0aGlzLCBjbGFzc05hbWVzICk7CgkJalF1ZXJ5LmNsYXNzTmFtZVsgc3RhdGUgPyAiYWRkIiA6ICJyZW1vdmUiIF0oIHRoaXMsIGNsYXNzTmFtZXMgKTsKCX0sCgoJcmVtb3ZlOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7CgkJaWYgKCAhc2VsZWN0b3IgfHwgalF1ZXJ5LmZpbHRlciggc2VsZWN0b3IsIFsgdGhpcyBdICkubGVuZ3RoICkgewoJCQkvLyBQcmV2ZW50IG1lbW9yeSBsZWFrcwoJCQlqUXVlcnkoICIqIiwgdGhpcyApLmFkZChbdGhpc10pLmVhY2goZnVuY3Rpb24oKXsKCQkJCWpRdWVyeS5ldmVudC5yZW1vdmUodGhpcyk7CgkJCQlqUXVlcnkucmVtb3ZlRGF0YSh0aGlzKTsKCQkJfSk7CgkJCWlmICh0aGlzLnBhcmVudE5vZGUpCgkJCQl0aGlzLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHRoaXMgKTsKCQl9Cgl9LAoKCWVtcHR5OiBmdW5jdGlvbigpIHsKCQkvLyBSZW1vdmUgZWxlbWVudCBub2RlcyBhbmQgcHJldmVudCBtZW1vcnkgbGVha3MKCQlqUXVlcnkodGhpcykuY2hpbGRyZW4oKS5yZW1vdmUoKTsKCgkJLy8gUmVtb3ZlIGFueSByZW1haW5pbmcgbm9kZXMKCQl3aGlsZSAoIHRoaXMuZmlyc3RDaGlsZCApCgkJCXRoaXMucmVtb3ZlQ2hpbGQoIHRoaXMuZmlyc3RDaGlsZCApOwoJfQp9LCBmdW5jdGlvbihuYW1lLCBmbil7CglqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCl7CgkJcmV0dXJuIHRoaXMuZWFjaCggZm4sIGFyZ3VtZW50cyApOwoJfTsKfSk7CgovLyBIZWxwZXIgZnVuY3Rpb24gdXNlZCBieSB0aGUgZGltZW5zaW9ucyBhbmQgb2Zmc2V0IG1vZHVsZXMKZnVuY3Rpb24gbnVtKGVsZW0sIHByb3ApIHsKCXJldHVybiBlbGVtWzBdICYmIHBhcnNlSW50KCBqUXVlcnkuY3VyQ1NTKGVsZW1bMF0sIHByb3AsIHRydWUpLCAxMCApIHx8IDA7Cn0KdmFyIGV4cGFuZG8gPSAialF1ZXJ5IiArIG5vdygpLCB1dWlkID0gMCwgd2luZG93RGF0YSA9IHt9OwoKalF1ZXJ5LmV4dGVuZCh7CgljYWNoZToge30sCgoJZGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGRhdGEgKSB7CgkJZWxlbSA9IGVsZW0gPT0gd2luZG93ID8KCQkJd2luZG93RGF0YSA6CgkJCWVsZW07CgoJCXZhciBpZCA9IGVsZW1bIGV4cGFuZG8gXTsKCgkJLy8gQ29tcHV0ZSBhIHVuaXF1ZSBJRCBmb3IgdGhlIGVsZW1lbnQKCQlpZiAoICFpZCApCgkJCWlkID0gZWxlbVsgZXhwYW5kbyBdID0gKyt1dWlkOwoKCQkvLyBPbmx5IGdlbmVyYXRlIHRoZSBkYXRhIGNhY2hlIGlmIHdlJ3JlCgkJLy8gdHJ5aW5nIHRvIGFjY2VzcyBvciBtYW5pcHVsYXRlIGl0CgkJaWYgKCBuYW1lICYmICFqUXVlcnkuY2FjaGVbIGlkIF0gKQoJCQlqUXVlcnkuY2FjaGVbIGlkIF0gPSB7fTsKCgkJLy8gUHJldmVudCBvdmVycmlkaW5nIHRoZSBuYW1lZCBjYWNoZSB3aXRoIHVuZGVmaW5lZCB2YWx1ZXMKCQlpZiAoIGRhdGEgIT09IHVuZGVmaW5lZCApCgkJCWpRdWVyeS5jYWNoZVsgaWQgXVsgbmFtZSBdID0gZGF0YTsKCgkJLy8gUmV0dXJuIHRoZSBuYW1lZCBjYWNoZSBkYXRhLCBvciB0aGUgSUQgZm9yIHRoZSBlbGVtZW50CgkJcmV0dXJuIG5hbWUgPwoJCQlqUXVlcnkuY2FjaGVbIGlkIF1bIG5hbWUgXSA6CgkJCWlkOwoJfSwKCglyZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHsKCQllbGVtID0gZWxlbSA9PSB3aW5kb3cgPwoJCQl3aW5kb3dEYXRhIDoKCQkJZWxlbTsKCgkJdmFyIGlkID0gZWxlbVsgZXhwYW5kbyBdOwoKCQkvLyBJZiB3ZSB3YW50IHRvIHJlbW92ZSBhIHNwZWNpZmljIHNlY3Rpb24gb2YgdGhlIGVsZW1lbnQncyBkYXRhCgkJaWYgKCBuYW1lICkgewoJCQlpZiAoIGpRdWVyeS5jYWNoZVsgaWQgXSApIHsKCQkJCS8vIFJlbW92ZSB0aGUgc2VjdGlvbiBvZiBjYWNoZSBkYXRhCgkJCQlkZWxldGUgalF1ZXJ5LmNhY2hlWyBpZCBdWyBuYW1lIF07CgoJCQkJLy8gSWYgd2UndmUgcmVtb3ZlZCBhbGwgdGhlIGRhdGEsIHJlbW92ZSB0aGUgZWxlbWVudCdzIGNhY2hlCgkJCQluYW1lID0gIiI7CgoJCQkJZm9yICggbmFtZSBpbiBqUXVlcnkuY2FjaGVbIGlkIF0gKQoJCQkJCWJyZWFrOwoKCQkJCWlmICggIW5hbWUgKQoJCQkJCWpRdWVyeS5yZW1vdmVEYXRhKCBlbGVtICk7CgkJCX0KCgkJLy8gT3RoZXJ3aXNlLCB3ZSB3YW50IHRvIHJlbW92ZSBhbGwgb2YgdGhlIGVsZW1lbnQncyBkYXRhCgkJfSBlbHNlIHsKCQkJLy8gQ2xlYW4gdXAgdGhlIGVsZW1lbnQgZXhwYW5kbwoJCQl0cnkgewoJCQkJZGVsZXRlIGVsZW1bIGV4cGFuZG8gXTsKCQkJfSBjYXRjaChlKXsKCQkJCS8vIElFIGhhcyB0cm91YmxlIGRpcmVjdGx5IHJlbW92aW5nIHRoZSBleHBhbmRvCgkJCQkvLyBidXQgaXQncyBvayB3aXRoIHVzaW5nIHJlbW92ZUF0dHJpYnV0ZQoJCQkJaWYgKCBlbGVtLnJlbW92ZUF0dHJpYnV0ZSApCgkJCQkJZWxlbS5yZW1vdmVBdHRyaWJ1dGUoIGV4cGFuZG8gKTsKCQkJfQoKCQkJLy8gQ29tcGxldGVseSByZW1vdmUgdGhlIGRhdGEgY2FjaGUKCQkJZGVsZXRlIGpRdWVyeS5jYWNoZVsgaWQgXTsKCQl9Cgl9LAoJcXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBkYXRhICkgewoJCWlmICggZWxlbSApewoJCgkJCXR5cGUgPSAodHlwZSB8fCAiZngiKSArICJxdWV1ZSI7CgkKCQkJdmFyIHEgPSBqUXVlcnkuZGF0YSggZWxlbSwgdHlwZSApOwoJCgkJCWlmICggIXEgfHwgalF1ZXJ5LmlzQXJyYXkoZGF0YSkgKQoJCQkJcSA9IGpRdWVyeS5kYXRhKCBlbGVtLCB0eXBlLCBqUXVlcnkubWFrZUFycmF5KGRhdGEpICk7CgkJCWVsc2UgaWYoIGRhdGEgKQoJCQkJcS5wdXNoKCBkYXRhICk7CgkKCQl9CgkJcmV0dXJuIHE7Cgl9LAoKCWRlcXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICl7CgkJdmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCBlbGVtLCB0eXBlICksCgkJCWZuID0gcXVldWUuc2hpZnQoKTsKCQkKCQlpZiggIXR5cGUgfHwgdHlwZSA9PT0gImZ4IiApCgkJCWZuID0gcXVldWVbMF07CgkJCQoJCWlmKCBmbiAhPT0gdW5kZWZpbmVkICkKCQkJZm4uY2FsbChlbGVtKTsKCX0KfSk7CgpqUXVlcnkuZm4uZXh0ZW5kKHsKCWRhdGE6IGZ1bmN0aW9uKCBrZXksIHZhbHVlICl7CgkJdmFyIHBhcnRzID0ga2V5LnNwbGl0KCIuIik7CgkJcGFydHNbMV0gPSBwYXJ0c1sxXSA/ICIuIiArIHBhcnRzWzFdIDogIiI7CgoJCWlmICggdmFsdWUgPT09IHVuZGVmaW5lZCApIHsKCQkJdmFyIGRhdGEgPSB0aGlzLnRyaWdnZXJIYW5kbGVyKCJnZXREYXRhIiArIHBhcnRzWzFdICsgIiEiLCBbcGFydHNbMF1dKTsKCgkJCWlmICggZGF0YSA9PT0gdW5kZWZpbmVkICYmIHRoaXMubGVuZ3RoICkKCQkJCWRhdGEgPSBqUXVlcnkuZGF0YSggdGhpc1swXSwga2V5ICk7CgoJCQlyZXR1cm4gZGF0YSA9PT0gdW5kZWZpbmVkICYmIHBhcnRzWzFdID8KCQkJCXRoaXMuZGF0YSggcGFydHNbMF0gKSA6CgkJCQlkYXRhOwoJCX0gZWxzZQoJCQlyZXR1cm4gdGhpcy50cmlnZ2VyKCJzZXREYXRhIiArIHBhcnRzWzFdICsgIiEiLCBbcGFydHNbMF0sIHZhbHVlXSkuZWFjaChmdW5jdGlvbigpewoJCQkJalF1ZXJ5LmRhdGEoIHRoaXMsIGtleSwgdmFsdWUgKTsKCQkJfSk7Cgl9LAoKCXJlbW92ZURhdGE6IGZ1bmN0aW9uKCBrZXkgKXsKCQlyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7CgkJCWpRdWVyeS5yZW1vdmVEYXRhKCB0aGlzLCBrZXkgKTsKCQl9KTsKCX0sCglxdWV1ZTogZnVuY3Rpb24odHlwZSwgZGF0YSl7CgkJaWYgKCB0eXBlb2YgdHlwZSAhPT0gInN0cmluZyIgKSB7CgkJCWRhdGEgPSB0eXBlOwoJCQl0eXBlID0gImZ4IjsKCQl9CgoJCWlmICggZGF0YSA9PT0gdW5kZWZpbmVkICkKCQkJcmV0dXJuIGpRdWVyeS5xdWV1ZSggdGhpc1swXSwgdHlwZSApOwoKCQlyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7CgkJCXZhciBxdWV1ZSA9IGpRdWVyeS5xdWV1ZSggdGhpcywgdHlwZSwgZGF0YSApOwoJCQkKCQkJIGlmKCB0eXBlID09ICJmeCIgJiYgcXVldWUubGVuZ3RoID09IDEgKQoJCQkJcXVldWVbMF0uY2FsbCh0aGlzKTsKCQl9KTsKCX0sCglkZXF1ZXVlOiBmdW5jdGlvbih0eXBlKXsKCQlyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7CgkJCWpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7CgkJfSk7Cgl9Cn0pOy8qIQogKiBTaXp6bGUgQ1NTIFNlbGVjdG9yIEVuZ2luZSAtIHYwLjkuMwogKiAgQ29weXJpZ2h0IDIwMDksIFRoZSBEb2pvIEZvdW5kYXRpb24KICogIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQsIEJTRCwgYW5kIEdQTCBMaWNlbnNlcy4KICogIE1vcmUgaW5mb3JtYXRpb246IGh0dHA6Ly9zaXp6bGVqcy5jb20vCiAqLwooZnVuY3Rpb24oKXsKCnZhciBjaHVua2VyID0gLygoPzpcKCg/OlwoW14oKV0rXCl8W14oKV0rKStcKXxcWyg/OlxbW15bXF1dKlxdfFsnIl1bXiciXSpbJyJdfFteW1xdJyJdKykrXF18XFwufFteID4rfiwoXFtcXF0rKSt8Wz4rfl0pKFxzKixccyopPy9nLAoJZG9uZSA9IDAsCgl0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7Cgp2YXIgU2l6emxlID0gZnVuY3Rpb24oc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQpIHsKCXJlc3VsdHMgPSByZXN1bHRzIHx8IFtdOwoJY29udGV4dCA9IGNvbnRleHQgfHwgZG9jdW1lbnQ7CgoJaWYgKCBjb250ZXh0Lm5vZGVUeXBlICE9PSAxICYmIGNvbnRleHQubm9kZVR5cGUgIT09IDkgKQoJCXJldHVybiBbXTsKCQoJaWYgKCAhc2VsZWN0b3IgfHwgdHlwZW9mIHNlbGVjdG9yICE9PSAic3RyaW5nIiApIHsKCQlyZXR1cm4gcmVzdWx0czsKCX0KCgl2YXIgcGFydHMgPSBbXSwgbSwgc2V0LCBjaGVja1NldCwgY2hlY2ssIG1vZGUsIGV4dHJhLCBwcnVuZSA9IHRydWU7CgkKCS8vIFJlc2V0IHRoZSBwb3NpdGlvbiBvZiB0aGUgY2h1bmtlciByZWdleHAgKHN0YXJ0IGZyb20gaGVhZCkKCWNodW5rZXIubGFzdEluZGV4ID0gMDsKCQoJd2hpbGUgKCAobSA9IGNodW5rZXIuZXhlYyhzZWxlY3RvcikpICE9PSBudWxsICkgewoJCXBhcnRzLnB1c2goIG1bMV0gKTsKCQkKCQlpZiAoIG1bMl0gKSB7CgkJCWV4dHJhID0gUmVnRXhwLnJpZ2h0Q29udGV4dDsKCQkJYnJlYWs7CgkJfQoJfQoKCWlmICggcGFydHMubGVuZ3RoID4gMSAmJiBvcmlnUE9TLmV4ZWMoIHNlbGVjdG9yICkgKSB7CgkJaWYgKCBwYXJ0cy5sZW5ndGggPT09IDIgJiYgRXhwci5yZWxhdGl2ZVsgcGFydHNbMF0gXSApIHsKCQkJc2V0ID0gcG9zUHJvY2VzcyggcGFydHNbMF0gKyBwYXJ0c1sxXSwgY29udGV4dCApOwoJCX0gZWxzZSB7CgkJCXNldCA9IEV4cHIucmVsYXRpdmVbIHBhcnRzWzBdIF0gPwoJCQkJWyBjb250ZXh0IF0gOgoJCQkJU2l6emxlKCBwYXJ0cy5zaGlmdCgpLCBjb250ZXh0ICk7CgoJCQl3aGlsZSAoIHBhcnRzLmxlbmd0aCApIHsKCQkJCXNlbGVjdG9yID0gcGFydHMuc2hpZnQoKTsKCgkJCQlpZiAoIEV4cHIucmVsYXRpdmVbIHNlbGVjdG9yIF0gKQoJCQkJCXNlbGVjdG9yICs9IHBhcnRzLnNoaWZ0KCk7CgoJCQkJc2V0ID0gcG9zUHJvY2Vzcyggc2VsZWN0b3IsIHNldCApOwoJCQl9CgkJfQoJfSBlbHNlIHsKCQl2YXIgcmV0ID0gc2VlZCA/CgkJCXsgZXhwcjogcGFydHMucG9wKCksIHNldDogbWFrZUFycmF5KHNlZWQpIH0gOgoJCQlTaXp6bGUuZmluZCggcGFydHMucG9wKCksIHBhcnRzLmxlbmd0aCA9PT0gMSAmJiBjb250ZXh0LnBhcmVudE5vZGUgPyBjb250ZXh0LnBhcmVudE5vZGUgOiBjb250ZXh0LCBpc1hNTChjb250ZXh0KSApOwoJCXNldCA9IFNpenpsZS5maWx0ZXIoIHJldC5leHByLCByZXQuc2V0ICk7CgoJCWlmICggcGFydHMubGVuZ3RoID4gMCApIHsKCQkJY2hlY2tTZXQgPSBtYWtlQXJyYXkoc2V0KTsKCQl9IGVsc2UgewoJCQlwcnVuZSA9IGZhbHNlOwoJCX0KCgkJd2hpbGUgKCBwYXJ0cy5sZW5ndGggKSB7CgkJCXZhciBjdXIgPSBwYXJ0cy5wb3AoKSwgcG9wID0gY3VyOwoKCQkJaWYgKCAhRXhwci5yZWxhdGl2ZVsgY3VyIF0gKSB7CgkJCQljdXIgPSAiIjsKCQkJfSBlbHNlIHsKCQkJCXBvcCA9IHBhcnRzLnBvcCgpOwoJCQl9CgoJCQlpZiAoIHBvcCA9PSBudWxsICkgewoJCQkJcG9wID0gY29udGV4dDsKCQkJfQoKCQkJRXhwci5yZWxhdGl2ZVsgY3VyIF0oIGNoZWNrU2V0LCBwb3AsIGlzWE1MKGNvbnRleHQpICk7CgkJfQoJfQoKCWlmICggIWNoZWNrU2V0ICkgewoJCWNoZWNrU2V0ID0gc2V0OwoJfQoKCWlmICggIWNoZWNrU2V0ICkgewoJCXRocm93ICJTeW50YXggZXJyb3IsIHVucmVjb2duaXplZCBleHByZXNzaW9uOiAiICsgKGN1ciB8fCBzZWxlY3Rvcik7Cgl9CgoJaWYgKCB0b1N0cmluZy5jYWxsKGNoZWNrU2V0KSA9PT0gIltvYmplY3QgQXJyYXldIiApIHsKCQlpZiAoICFwcnVuZSApIHsKCQkJcmVzdWx0cy5wdXNoLmFwcGx5KCByZXN1bHRzLCBjaGVja1NldCApOwoJCX0gZWxzZSBpZiAoIGNvbnRleHQubm9kZVR5cGUgPT09IDEgKSB7CgkJCWZvciAoIHZhciBpID0gMDsgY2hlY2tTZXRbaV0gIT0gbnVsbDsgaSsrICkgewoJCQkJaWYgKCBjaGVja1NldFtpXSAmJiAoY2hlY2tTZXRbaV0gPT09IHRydWUgfHwgY2hlY2tTZXRbaV0ubm9kZVR5cGUgPT09IDEgJiYgY29udGFpbnMoY29udGV4dCwgY2hlY2tTZXRbaV0pKSApIHsKCQkJCQlyZXN1bHRzLnB1c2goIHNldFtpXSApOwoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJZm9yICggdmFyIGkgPSAwOyBjaGVja1NldFtpXSAhPSBudWxsOyBpKysgKSB7CgkJCQlpZiAoIGNoZWNrU2V0W2ldICYmIGNoZWNrU2V0W2ldLm5vZGVUeXBlID09PSAxICkgewoJCQkJCXJlc3VsdHMucHVzaCggc2V0W2ldICk7CgkJCQl9CgkJCX0KCQl9Cgl9IGVsc2UgewoJCW1ha2VBcnJheSggY2hlY2tTZXQsIHJlc3VsdHMgKTsKCX0KCglpZiAoIGV4dHJhICkgewoJCVNpenpsZSggZXh0cmEsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTsKCgkJaWYgKCBzb3J0T3JkZXIgKSB7CgkJCWhhc0R1cGxpY2F0ZSA9IGZhbHNlOwoJCQlyZXN1bHRzLnNvcnQoc29ydE9yZGVyKTsKCgkJCWlmICggaGFzRHVwbGljYXRlICkgewoJCQkJZm9yICggdmFyIGkgPSAxOyBpIDwgcmVzdWx0cy5sZW5ndGg7IGkrKyApIHsKCQkJCQlpZiAoIHJlc3VsdHNbaV0gPT09IHJlc3VsdHNbaS0xXSApIHsKCQkJCQkJcmVzdWx0cy5zcGxpY2UoaS0tLCAxKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIHJlc3VsdHM7Cn07CgpTaXp6bGUubWF0Y2hlcyA9IGZ1bmN0aW9uKGV4cHIsIHNldCl7CglyZXR1cm4gU2l6emxlKGV4cHIsIG51bGwsIG51bGwsIHNldCk7Cn07CgpTaXp6bGUuZmluZCA9IGZ1bmN0aW9uKGV4cHIsIGNvbnRleHQsIGlzWE1MKXsKCXZhciBzZXQsIG1hdGNoOwoKCWlmICggIWV4cHIgKSB7CgkJcmV0dXJuIFtdOwoJfQoKCWZvciAoIHZhciBpID0gMCwgbCA9IEV4cHIub3JkZXIubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCXZhciB0eXBlID0gRXhwci5vcmRlcltpXSwgbWF0Y2g7CgkJCgkJaWYgKCAobWF0Y2ggPSBFeHByLm1hdGNoWyB0eXBlIF0uZXhlYyggZXhwciApKSApIHsKCQkJdmFyIGxlZnQgPSBSZWdFeHAubGVmdENvbnRleHQ7CgoJCQlpZiAoIGxlZnQuc3Vic3RyKCBsZWZ0Lmxlbmd0aCAtIDEgKSAhPT0gIlxcIiApIHsKCQkJCW1hdGNoWzFdID0gKG1hdGNoWzFdIHx8ICIiKS5yZXBsYWNlKC9cXC9nLCAiIik7CgkJCQlzZXQgPSBFeHByLmZpbmRbIHR5cGUgXSggbWF0Y2gsIGNvbnRleHQsIGlzWE1MICk7CgkJCQlpZiAoIHNldCAhPSBudWxsICkgewoJCQkJCWV4cHIgPSBleHByLnJlcGxhY2UoIEV4cHIubWF0Y2hbIHR5cGUgXSwgIiIgKTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCX0KCglpZiAoICFzZXQgKSB7CgkJc2V0ID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpOwoJfQoKCXJldHVybiB7c2V0OiBzZXQsIGV4cHI6IGV4cHJ9Owp9OwoKU2l6emxlLmZpbHRlciA9IGZ1bmN0aW9uKGV4cHIsIHNldCwgaW5wbGFjZSwgbm90KXsKCXZhciBvbGQgPSBleHByLCByZXN1bHQgPSBbXSwgY3VyTG9vcCA9IHNldCwgbWF0Y2gsIGFueUZvdW5kLAoJCWlzWE1MRmlsdGVyID0gc2V0ICYmIHNldFswXSAmJiBpc1hNTChzZXRbMF0pOwoKCXdoaWxlICggZXhwciAmJiBzZXQubGVuZ3RoICkgewoJCWZvciAoIHZhciB0eXBlIGluIEV4cHIuZmlsdGVyICkgewoJCQlpZiAoIChtYXRjaCA9IEV4cHIubWF0Y2hbIHR5cGUgXS5leGVjKCBleHByICkpICE9IG51bGwgKSB7CgkJCQl2YXIgZmlsdGVyID0gRXhwci5maWx0ZXJbIHR5cGUgXSwgZm91bmQsIGl0ZW07CgkJCQlhbnlGb3VuZCA9IGZhbHNlOwoKCQkJCWlmICggY3VyTG9vcCA9PSByZXN1bHQgKSB7CgkJCQkJcmVzdWx0ID0gW107CgkJCQl9CgoJCQkJaWYgKCBFeHByLnByZUZpbHRlclsgdHlwZSBdICkgewoJCQkJCW1hdGNoID0gRXhwci5wcmVGaWx0ZXJbIHR5cGUgXSggbWF0Y2gsIGN1ckxvb3AsIGlucGxhY2UsIHJlc3VsdCwgbm90LCBpc1hNTEZpbHRlciApOwoKCQkJCQlpZiAoICFtYXRjaCApIHsKCQkJCQkJYW55Rm91bmQgPSBmb3VuZCA9IHRydWU7CgkJCQkJfSBlbHNlIGlmICggbWF0Y2ggPT09IHRydWUgKSB7CgkJCQkJCWNvbnRpbnVlOwoJCQkJCX0KCQkJCX0KCgkJCQlpZiAoIG1hdGNoICkgewoJCQkJCWZvciAoIHZhciBpID0gMDsgKGl0ZW0gPSBjdXJMb29wW2ldKSAhPSBudWxsOyBpKysgKSB7CgkJCQkJCWlmICggaXRlbSApIHsKCQkJCQkJCWZvdW5kID0gZmlsdGVyKCBpdGVtLCBtYXRjaCwgaSwgY3VyTG9vcCApOwoJCQkJCQkJdmFyIHBhc3MgPSBub3QgXiAhIWZvdW5kOwoKCQkJCQkJCWlmICggaW5wbGFjZSAmJiBmb3VuZCAhPSBudWxsICkgewoJCQkJCQkJCWlmICggcGFzcyApIHsKCQkJCQkJCQkJYW55Rm91bmQgPSB0cnVlOwoJCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJCWN1ckxvb3BbaV0gPSBmYWxzZTsKCQkJCQkJCQl9CgkJCQkJCQl9IGVsc2UgaWYgKCBwYXNzICkgewoJCQkJCQkJCXJlc3VsdC5wdXNoKCBpdGVtICk7CgkJCQkJCQkJYW55Rm91bmQgPSB0cnVlOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJfQoKCQkJCWlmICggZm91bmQgIT09IHVuZGVmaW5lZCApIHsKCQkJCQlpZiAoICFpbnBsYWNlICkgewoJCQkJCQljdXJMb29wID0gcmVzdWx0OwoJCQkJCX0KCgkJCQkJZXhwciA9IGV4cHIucmVwbGFjZSggRXhwci5tYXRjaFsgdHlwZSBdLCAiIiApOwoKCQkJCQlpZiAoICFhbnlGb3VuZCApIHsKCQkJCQkJcmV0dXJuIFtdOwoJCQkJCX0KCgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJCS8vIEltcHJvcGVyIGV4cHJlc3Npb24KCQlpZiAoIGV4cHIgPT0gb2xkICkgewoJCQlpZiAoIGFueUZvdW5kID09IG51bGwgKSB7CgkJCQl0aHJvdyAiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogIiArIGV4cHI7CgkJCX0gZWxzZSB7CgkJCQlicmVhazsKCQkJfQoJCX0KCgkJb2xkID0gZXhwcjsKCX0KCglyZXR1cm4gY3VyTG9vcDsKfTsKCnZhciBFeHByID0gU2l6emxlLnNlbGVjdG9ycyA9IHsKCW9yZGVyOiBbICJJRCIsICJOQU1FIiwgIlRBRyIgXSwKCW1hdGNoOiB7CgkJSUQ6IC8jKCg/Oltcd1x1MDBjMC1cdUZGRkZfLV18XFwuKSspLywKCQlDTEFTUzogL1wuKCg/Oltcd1x1MDBjMC1cdUZGRkZfLV18XFwuKSspLywKCQlOQU1FOiAvXFtuYW1lPVsnIl0qKCg/Oltcd1x1MDBjMC1cdUZGRkZfLV18XFwuKSspWyciXSpcXS8sCgkJQVRUUjogL1xbXHMqKCg/Oltcd1x1MDBjMC1cdUZGRkZfLV18XFwuKSspXHMqKD86KFxTPz0pXHMqKFsnIl0qKSguKj8pXDN8KVxzKlxdLywKCQlUQUc6IC9eKCg/Oltcd1x1MDBjMC1cdUZGRkZcKl8tXXxcXC4pKykvLAoJCUNISUxEOiAvOihvbmx5fG50aHxsYXN0fGZpcnN0KS1jaGlsZCg/OlwoKGV2ZW58b2RkfFtcZG4rLV0qKVwpKT8vLAoJCVBPUzogLzoobnRofGVxfGd0fGx0fGZpcnN0fGxhc3R8ZXZlbnxvZGQpKD86XCgoXGQqKVwpKT8oPz1bXi1dfCQpLywKCQlQU0VVRE86IC86KCg/Oltcd1x1MDBjMC1cdUZGRkZfLV18XFwuKSspKD86XCgoWyciXSopKCg/OlwoW15cKV0rXCl8W15cMlwoXCldKikrKVwyXCkpPy8KCX0sCglhdHRyTWFwOiB7CgkJImNsYXNzIjogImNsYXNzTmFtZSIsCgkJImZvciI6ICJodG1sRm9yIgoJfSwKCWF0dHJIYW5kbGU6IHsKCQlocmVmOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCJocmVmIik7CgkJfQoJfSwKCXJlbGF0aXZlOiB7CgkJIisiOiBmdW5jdGlvbihjaGVja1NldCwgcGFydCwgaXNYTUwpewoJCQl2YXIgaXNQYXJ0U3RyID0gdHlwZW9mIHBhcnQgPT09ICJzdHJpbmciLAoJCQkJaXNUYWcgPSBpc1BhcnRTdHIgJiYgIS9cVy8udGVzdChwYXJ0KSwKCQkJCWlzUGFydFN0ck5vdFRhZyA9IGlzUGFydFN0ciAmJiAhaXNUYWc7CgoJCQlpZiAoIGlzVGFnICYmICFpc1hNTCApIHsKCQkJCXBhcnQgPSBwYXJ0LnRvVXBwZXJDYXNlKCk7CgkJCX0KCgkJCWZvciAoIHZhciBpID0gMCwgbCA9IGNoZWNrU2V0Lmxlbmd0aCwgZWxlbTsgaSA8IGw7IGkrKyApIHsKCQkJCWlmICggKGVsZW0gPSBjaGVja1NldFtpXSkgKSB7CgkJCQkJd2hpbGUgKCAoZWxlbSA9IGVsZW0ucHJldmlvdXNTaWJsaW5nKSAmJiBlbGVtLm5vZGVUeXBlICE9PSAxICkge30KCgkJCQkJY2hlY2tTZXRbaV0gPSBpc1BhcnRTdHJOb3RUYWcgfHwgZWxlbSAmJiBlbGVtLm5vZGVOYW1lID09PSBwYXJ0ID8KCQkJCQkJZWxlbSB8fCBmYWxzZSA6CgkJCQkJCWVsZW0gPT09IHBhcnQ7CgkJCQl9CgkJCX0KCgkJCWlmICggaXNQYXJ0U3RyTm90VGFnICkgewoJCQkJU2l6emxlLmZpbHRlciggcGFydCwgY2hlY2tTZXQsIHRydWUgKTsKCQkJfQoJCX0sCgkJIj4iOiBmdW5jdGlvbihjaGVja1NldCwgcGFydCwgaXNYTUwpewoJCQl2YXIgaXNQYXJ0U3RyID0gdHlwZW9mIHBhcnQgPT09ICJzdHJpbmciOwoKCQkJaWYgKCBpc1BhcnRTdHIgJiYgIS9cVy8udGVzdChwYXJ0KSApIHsKCQkJCXBhcnQgPSBpc1hNTCA/IHBhcnQgOiBwYXJ0LnRvVXBwZXJDYXNlKCk7CgoJCQkJZm9yICggdmFyIGkgPSAwLCBsID0gY2hlY2tTZXQubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCQkJCXZhciBlbGVtID0gY2hlY2tTZXRbaV07CgkJCQkJaWYgKCBlbGVtICkgewoJCQkJCQl2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlOwoJCQkJCQljaGVja1NldFtpXSA9IHBhcmVudC5ub2RlTmFtZSA9PT0gcGFydCA/IHBhcmVudCA6IGZhbHNlOwoJCQkJCX0KCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWZvciAoIHZhciBpID0gMCwgbCA9IGNoZWNrU2V0Lmxlbmd0aDsgaSA8IGw7IGkrKyApIHsKCQkJCQl2YXIgZWxlbSA9IGNoZWNrU2V0W2ldOwoJCQkJCWlmICggZWxlbSApIHsKCQkJCQkJY2hlY2tTZXRbaV0gPSBpc1BhcnRTdHIgPwoJCQkJCQkJZWxlbS5wYXJlbnROb2RlIDoKCQkJCQkJCWVsZW0ucGFyZW50Tm9kZSA9PT0gcGFydDsKCQkJCQl9CgkJCQl9CgoJCQkJaWYgKCBpc1BhcnRTdHIgKSB7CgkJCQkJU2l6emxlLmZpbHRlciggcGFydCwgY2hlY2tTZXQsIHRydWUgKTsKCQkJCX0KCQkJfQoJCX0sCgkJIiI6IGZ1bmN0aW9uKGNoZWNrU2V0LCBwYXJ0LCBpc1hNTCl7CgkJCXZhciBkb25lTmFtZSA9IGRvbmUrKywgY2hlY2tGbiA9IGRpckNoZWNrOwoKCQkJaWYgKCAhcGFydC5tYXRjaCgvXFcvKSApIHsKCQkJCXZhciBub2RlQ2hlY2sgPSBwYXJ0ID0gaXNYTUwgPyBwYXJ0IDogcGFydC50b1VwcGVyQ2FzZSgpOwoJCQkJY2hlY2tGbiA9IGRpck5vZGVDaGVjazsKCQkJfQoKCQkJY2hlY2tGbigicGFyZW50Tm9kZSIsIHBhcnQsIGRvbmVOYW1lLCBjaGVja1NldCwgbm9kZUNoZWNrLCBpc1hNTCk7CgkJfSwKCQkifiI6IGZ1bmN0aW9uKGNoZWNrU2V0LCBwYXJ0LCBpc1hNTCl7CgkJCXZhciBkb25lTmFtZSA9IGRvbmUrKywgY2hlY2tGbiA9IGRpckNoZWNrOwoKCQkJaWYgKCB0eXBlb2YgcGFydCA9PT0gInN0cmluZyIgJiYgIXBhcnQubWF0Y2goL1xXLykgKSB7CgkJCQl2YXIgbm9kZUNoZWNrID0gcGFydCA9IGlzWE1MID8gcGFydCA6IHBhcnQudG9VcHBlckNhc2UoKTsKCQkJCWNoZWNrRm4gPSBkaXJOb2RlQ2hlY2s7CgkJCX0KCgkJCWNoZWNrRm4oInByZXZpb3VzU2libGluZyIsIHBhcnQsIGRvbmVOYW1lLCBjaGVja1NldCwgbm9kZUNoZWNrLCBpc1hNTCk7CgkJfQoJfSwKCWZpbmQ6IHsKCQlJRDogZnVuY3Rpb24obWF0Y2gsIGNvbnRleHQsIGlzWE1MKXsKCQkJaWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50QnlJZCAhPT0gInVuZGVmaW5lZCIgJiYgIWlzWE1MICkgewoJCQkJdmFyIG0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKG1hdGNoWzFdKTsKCQkJCXJldHVybiBtID8gW21dIDogW107CgkJCX0KCQl9LAoJCU5BTUU6IGZ1bmN0aW9uKG1hdGNoLCBjb250ZXh0LCBpc1hNTCl7CgkJCWlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeU5hbWUgIT09ICJ1bmRlZmluZWQiICkgewoJCQkJdmFyIHJldCA9IFtdLCByZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5TmFtZShtYXRjaFsxXSk7CgoJCQkJZm9yICggdmFyIGkgPSAwLCBsID0gcmVzdWx0cy5sZW5ndGg7IGkgPCBsOyBpKysgKSB7CgkJCQkJaWYgKCByZXN1bHRzW2ldLmdldEF0dHJpYnV0ZSgibmFtZSIpID09PSBtYXRjaFsxXSApIHsKCQkJCQkJcmV0LnB1c2goIHJlc3VsdHNbaV0gKTsKCQkJCQl9CgkJCQl9CgoJCQkJcmV0dXJuIHJldC5sZW5ndGggPT09IDAgPyBudWxsIDogcmV0OwoJCQl9CgkJfSwKCQlUQUc6IGZ1bmN0aW9uKG1hdGNoLCBjb250ZXh0KXsKCQkJcmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUobWF0Y2hbMV0pOwoJCX0KCX0sCglwcmVGaWx0ZXI6IHsKCQlDTEFTUzogZnVuY3Rpb24obWF0Y2gsIGN1ckxvb3AsIGlucGxhY2UsIHJlc3VsdCwgbm90LCBpc1hNTCl7CgkJCW1hdGNoID0gIiAiICsgbWF0Y2hbMV0ucmVwbGFjZSgvXFwvZywgIiIpICsgIiAiOwoKCQkJaWYgKCBpc1hNTCApIHsKCQkJCXJldHVybiBtYXRjaDsKCQkJfQoKCQkJZm9yICggdmFyIGkgPSAwLCBlbGVtOyAoZWxlbSA9IGN1ckxvb3BbaV0pICE9IG51bGw7IGkrKyApIHsKCQkJCWlmICggZWxlbSApIHsKCQkJCQlpZiAoIG5vdCBeIChlbGVtLmNsYXNzTmFtZSAmJiAoIiAiICsgZWxlbS5jbGFzc05hbWUgKyAiICIpLmluZGV4T2YobWF0Y2gpID49IDApICkgewoJCQkJCQlpZiAoICFpbnBsYWNlICkKCQkJCQkJCXJlc3VsdC5wdXNoKCBlbGVtICk7CgkJCQkJfSBlbHNlIGlmICggaW5wbGFjZSApIHsKCQkJCQkJY3VyTG9vcFtpXSA9IGZhbHNlOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJcmV0dXJuIGZhbHNlOwoJCX0sCgkJSUQ6IGZ1bmN0aW9uKG1hdGNoKXsKCQkJcmV0dXJuIG1hdGNoWzFdLnJlcGxhY2UoL1xcL2csICIiKTsKCQl9LAoJCVRBRzogZnVuY3Rpb24obWF0Y2gsIGN1ckxvb3ApewoJCQlmb3IgKCB2YXIgaSA9IDA7IGN1ckxvb3BbaV0gPT09IGZhbHNlOyBpKysgKXt9CgkJCXJldHVybiBjdXJMb29wW2ldICYmIGlzWE1MKGN1ckxvb3BbaV0pID8gbWF0Y2hbMV0gOiBtYXRjaFsxXS50b1VwcGVyQ2FzZSgpOwoJCX0sCgkJQ0hJTEQ6IGZ1bmN0aW9uKG1hdGNoKXsKCQkJaWYgKCBtYXRjaFsxXSA9PSAibnRoIiApIHsKCQkJCS8vIHBhcnNlIGVxdWF0aW9ucyBsaWtlICdldmVuJywgJ29kZCcsICc1JywgJzJuJywgJzNuKzInLCAnNG4tMScsICctbis2JwoJCQkJdmFyIHRlc3QgPSAvKC0/KShcZCopbigoPzpcK3wtKT9cZCopLy5leGVjKAoJCQkJCW1hdGNoWzJdID09ICJldmVuIiAmJiAiMm4iIHx8IG1hdGNoWzJdID09ICJvZGQiICYmICIybisxIiB8fAoJCQkJCSEvXEQvLnRlc3QoIG1hdGNoWzJdICkgJiYgIjBuKyIgKyBtYXRjaFsyXSB8fCBtYXRjaFsyXSk7CgoJCQkJLy8gY2FsY3VsYXRlIHRoZSBudW1iZXJzIChmaXJzdCluKyhsYXN0KSBpbmNsdWRpbmcgaWYgdGhleSBhcmUgbmVnYXRpdmUKCQkJCW1hdGNoWzJdID0gKHRlc3RbMV0gKyAodGVzdFsyXSB8fCAxKSkgLSAwOwoJCQkJbWF0Y2hbM10gPSB0ZXN0WzNdIC0gMDsKCQkJfQoKCQkJLy8gVE9ETzogTW92ZSB0byBub3JtYWwgY2FjaGluZyBzeXN0ZW0KCQkJbWF0Y2hbMF0gPSBkb25lKys7CgoJCQlyZXR1cm4gbWF0Y2g7CgkJfSwKCQlBVFRSOiBmdW5jdGlvbihtYXRjaCwgY3VyTG9vcCwgaW5wbGFjZSwgcmVzdWx0LCBub3QsIGlzWE1MKXsKCQkJdmFyIG5hbWUgPSBtYXRjaFsxXS5yZXBsYWNlKC9cXC9nLCAiIik7CgkJCQoJCQlpZiAoICFpc1hNTCAmJiBFeHByLmF0dHJNYXBbbmFtZV0gKSB7CgkJCQltYXRjaFsxXSA9IEV4cHIuYXR0ck1hcFtuYW1lXTsKCQkJfQoKCQkJaWYgKCBtYXRjaFsyXSA9PT0gIn49IiApIHsKCQkJCW1hdGNoWzRdID0gIiAiICsgbWF0Y2hbNF0gKyAiICI7CgkJCX0KCgkJCXJldHVybiBtYXRjaDsKCQl9LAoJCVBTRVVETzogZnVuY3Rpb24obWF0Y2gsIGN1ckxvb3AsIGlucGxhY2UsIHJlc3VsdCwgbm90KXsKCQkJaWYgKCBtYXRjaFsxXSA9PT0gIm5vdCIgKSB7CgkJCQkvLyBJZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSBjb21wbGV4IGV4cHJlc3Npb24sIG9yIGEgc2ltcGxlIG9uZQoJCQkJaWYgKCBtYXRjaFszXS5tYXRjaChjaHVua2VyKS5sZW5ndGggPiAxIHx8IC9eXHcvLnRlc3QobWF0Y2hbM10pICkgewoJCQkJCW1hdGNoWzNdID0gU2l6emxlKG1hdGNoWzNdLCBudWxsLCBudWxsLCBjdXJMb29wKTsKCQkJCX0gZWxzZSB7CgkJCQkJdmFyIHJldCA9IFNpenpsZS5maWx0ZXIobWF0Y2hbM10sIGN1ckxvb3AsIGlucGxhY2UsIHRydWUgXiBub3QpOwoJCQkJCWlmICggIWlucGxhY2UgKSB7CgkJCQkJCXJlc3VsdC5wdXNoLmFwcGx5KCByZXN1bHQsIHJldCApOwoJCQkJCX0KCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCX0gZWxzZSBpZiAoIEV4cHIubWF0Y2guUE9TLnRlc3QoIG1hdGNoWzBdICkgfHwgRXhwci5tYXRjaC5DSElMRC50ZXN0KCBtYXRjaFswXSApICkgewoJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQkJCgkJCXJldHVybiBtYXRjaDsKCQl9LAoJCVBPUzogZnVuY3Rpb24obWF0Y2gpewoJCQltYXRjaC51bnNoaWZ0KCB0cnVlICk7CgkJCXJldHVybiBtYXRjaDsKCQl9Cgl9LAoJZmlsdGVyczogewoJCWVuYWJsZWQ6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZmFsc2UgJiYgZWxlbS50eXBlICE9PSAiaGlkZGVuIjsKCQl9LAoJCWRpc2FibGVkOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IHRydWU7CgkJfSwKCQljaGVja2VkOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuIGVsZW0uY2hlY2tlZCA9PT0gdHJ1ZTsKCQl9LAoJCXNlbGVjdGVkOiBmdW5jdGlvbihlbGVtKXsKCQkJLy8gQWNjZXNzaW5nIHRoaXMgcHJvcGVydHkgbWFrZXMgc2VsZWN0ZWQtYnktZGVmYXVsdAoJCQkvLyBvcHRpb25zIGluIFNhZmFyaSB3b3JrIHByb3Blcmx5CgkJCWVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4OwoJCQlyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTsKCQl9LAoJCXBhcmVudDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAhIWVsZW0uZmlyc3RDaGlsZDsKCQl9LAoJCWVtcHR5OiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICFlbGVtLmZpcnN0Q2hpbGQ7CgkJfSwKCQloYXM6IGZ1bmN0aW9uKGVsZW0sIGksIG1hdGNoKXsKCQkJcmV0dXJuICEhU2l6emxlKCBtYXRjaFszXSwgZWxlbSApLmxlbmd0aDsKCQl9LAoJCWhlYWRlcjogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAvaFxkL2kudGVzdCggZWxlbS5ub2RlTmFtZSApOwoJCX0sCgkJdGV4dDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAidGV4dCIgPT09IGVsZW0udHlwZTsKCQl9LAoJCXJhZGlvOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICJyYWRpbyIgPT09IGVsZW0udHlwZTsKCQl9LAoJCWNoZWNrYm94OiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICJjaGVja2JveCIgPT09IGVsZW0udHlwZTsKCQl9LAoJCWZpbGU6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gImZpbGUiID09PSBlbGVtLnR5cGU7CgkJfSwKCQlwYXNzd29yZDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAicGFzc3dvcmQiID09PSBlbGVtLnR5cGU7CgkJfSwKCQlzdWJtaXQ6IGZ1bmN0aW9uKGVsZW0pewoJCQlyZXR1cm4gInN1Ym1pdCIgPT09IGVsZW0udHlwZTsKCQl9LAoJCWltYWdlOiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICJpbWFnZSIgPT09IGVsZW0udHlwZTsKCQl9LAoJCXJlc2V0OiBmdW5jdGlvbihlbGVtKXsKCQkJcmV0dXJuICJyZXNldCIgPT09IGVsZW0udHlwZTsKCQl9LAoJCWJ1dHRvbjogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAiYnV0dG9uIiA9PT0gZWxlbS50eXBlIHx8IGVsZW0ubm9kZU5hbWUudG9VcHBlckNhc2UoKSA9PT0gIkJVVFRPTiI7CgkJfSwKCQlpbnB1dDogZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiAvaW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbi9pLnRlc3QoZWxlbS5ub2RlTmFtZSk7CgkJfQoJfSwKCXNldEZpbHRlcnM6IHsKCQlmaXJzdDogZnVuY3Rpb24oZWxlbSwgaSl7CgkJCXJldHVybiBpID09PSAwOwoJCX0sCgkJbGFzdDogZnVuY3Rpb24oZWxlbSwgaSwgbWF0Y2gsIGFycmF5KXsKCQkJcmV0dXJuIGkgPT09IGFycmF5Lmxlbmd0aCAtIDE7CgkJfSwKCQlldmVuOiBmdW5jdGlvbihlbGVtLCBpKXsKCQkJcmV0dXJuIGkgJSAyID09PSAwOwoJCX0sCgkJb2RkOiBmdW5jdGlvbihlbGVtLCBpKXsKCQkJcmV0dXJuIGkgJSAyID09PSAxOwoJCX0sCgkJbHQ6IGZ1bmN0aW9uKGVsZW0sIGksIG1hdGNoKXsKCQkJcmV0dXJuIGkgPCBtYXRjaFszXSAtIDA7CgkJfSwKCQlndDogZnVuY3Rpb24oZWxlbSwgaSwgbWF0Y2gpewoJCQlyZXR1cm4gaSA+IG1hdGNoWzNdIC0gMDsKCQl9LAoJCW50aDogZnVuY3Rpb24oZWxlbSwgaSwgbWF0Y2gpewoJCQlyZXR1cm4gbWF0Y2hbM10gLSAwID09IGk7CgkJfSwKCQllcTogZnVuY3Rpb24oZWxlbSwgaSwgbWF0Y2gpewoJCQlyZXR1cm4gbWF0Y2hbM10gLSAwID09IGk7CgkJfQoJfSwKCWZpbHRlcjogewoJCVBTRVVETzogZnVuY3Rpb24oZWxlbSwgbWF0Y2gsIGksIGFycmF5KXsKCQkJdmFyIG5hbWUgPSBtYXRjaFsxXSwgZmlsdGVyID0gRXhwci5maWx0ZXJzWyBuYW1lIF07CgoJCQlpZiAoIGZpbHRlciApIHsKCQkJCXJldHVybiBmaWx0ZXIoIGVsZW0sIGksIG1hdGNoLCBhcnJheSApOwoJCQl9IGVsc2UgaWYgKCBuYW1lID09PSAiY29udGFpbnMiICkgewoJCQkJcmV0dXJuIChlbGVtLnRleHRDb250ZW50IHx8IGVsZW0uaW5uZXJUZXh0IHx8ICIiKS5pbmRleE9mKG1hdGNoWzNdKSA+PSAwOwoJCQl9IGVsc2UgaWYgKCBuYW1lID09PSAibm90IiApIHsKCQkJCXZhciBub3QgPSBtYXRjaFszXTsKCgkJCQlmb3IgKCB2YXIgaSA9IDAsIGwgPSBub3QubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCQkJCWlmICggbm90W2ldID09PSBlbGVtICkgewoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfQoJCQkJfQoKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfSwKCQlDSElMRDogZnVuY3Rpb24oZWxlbSwgbWF0Y2gpewoJCQl2YXIgdHlwZSA9IG1hdGNoWzFdLCBub2RlID0gZWxlbTsKCQkJc3dpdGNoICh0eXBlKSB7CgkJCQljYXNlICdvbmx5JzoKCQkJCWNhc2UgJ2ZpcnN0JzoKCQkJCQl3aGlsZSAobm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nKSAgewoJCQkJCQlpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgKSByZXR1cm4gZmFsc2U7CgkJCQkJfQoJCQkJCWlmICggdHlwZSA9PSAnZmlyc3QnKSByZXR1cm4gdHJ1ZTsKCQkJCQlub2RlID0gZWxlbTsKCQkJCWNhc2UgJ2xhc3QnOgoJCQkJCXdoaWxlIChub2RlID0gbm9kZS5uZXh0U2libGluZykgIHsKCQkJCQkJaWYgKCBub2RlLm5vZGVUeXBlID09PSAxICkgcmV0dXJuIGZhbHNlOwoJCQkJCX0KCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCWNhc2UgJ250aCc6CgkJCQkJdmFyIGZpcnN0ID0gbWF0Y2hbMl0sIGxhc3QgPSBtYXRjaFszXTsKCgkJCQkJaWYgKCBmaXJzdCA9PSAxICYmIGxhc3QgPT0gMCApIHsKCQkJCQkJcmV0dXJuIHRydWU7CgkJCQkJfQoJCQkJCQoJCQkJCXZhciBkb25lTmFtZSA9IG1hdGNoWzBdLAoJCQkJCQlwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7CgkKCQkJCQlpZiAoIHBhcmVudCAmJiAocGFyZW50LnNpemNhY2hlICE9PSBkb25lTmFtZSB8fCAhZWxlbS5ub2RlSW5kZXgpICkgewoJCQkJCQl2YXIgY291bnQgPSAwOwoJCQkJCQlmb3IgKCBub2RlID0gcGFyZW50LmZpcnN0Q2hpbGQ7IG5vZGU7IG5vZGUgPSBub2RlLm5leHRTaWJsaW5nICkgewoJCQkJCQkJaWYgKCBub2RlLm5vZGVUeXBlID09PSAxICkgewoJCQkJCQkJCW5vZGUubm9kZUluZGV4ID0gKytjb3VudDsKCQkJCQkJCX0KCQkJCQkJfSAKCQkJCQkJcGFyZW50LnNpemNhY2hlID0gZG9uZU5hbWU7CgkJCQkJfQoJCQkJCQoJCQkJCXZhciBkaWZmID0gZWxlbS5ub2RlSW5kZXggLSBsYXN0OwoJCQkJCWlmICggZmlyc3QgPT0gMCApIHsKCQkJCQkJcmV0dXJuIGRpZmYgPT0gMDsKCQkJCQl9IGVsc2UgewoJCQkJCQlyZXR1cm4gKCBkaWZmICUgZmlyc3QgPT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApOwoJCQkJCX0KCQkJfQoJCX0sCgkJSUQ6IGZ1bmN0aW9uKGVsZW0sIG1hdGNoKXsKCQkJcmV0dXJuIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgZWxlbS5nZXRBdHRyaWJ1dGUoImlkIikgPT09IG1hdGNoOwoJCX0sCgkJVEFHOiBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXJldHVybiAobWF0Y2ggPT09ICIqIiAmJiBlbGVtLm5vZGVUeXBlID09PSAxKSB8fCBlbGVtLm5vZGVOYW1lID09PSBtYXRjaDsKCQl9LAoJCUNMQVNTOiBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXJldHVybiAoIiAiICsgKGVsZW0uY2xhc3NOYW1lIHx8IGVsZW0uZ2V0QXR0cmlidXRlKCJjbGFzcyIpKSArICIgIikKCQkJCS5pbmRleE9mKCBtYXRjaCApID4gLTE7CgkJfSwKCQlBVFRSOiBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXZhciBuYW1lID0gbWF0Y2hbMV0sCgkJCQlyZXN1bHQgPSBFeHByLmF0dHJIYW5kbGVbIG5hbWUgXSA/CgkJCQkJRXhwci5hdHRySGFuZGxlWyBuYW1lIF0oIGVsZW0gKSA6CgkJCQkJZWxlbVsgbmFtZSBdICE9IG51bGwgPwoJCQkJCQllbGVtWyBuYW1lIF0gOgoJCQkJCQllbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApLAoJCQkJdmFsdWUgPSByZXN1bHQgKyAiIiwKCQkJCXR5cGUgPSBtYXRjaFsyXSwKCQkJCWNoZWNrID0gbWF0Y2hbNF07CgoJCQlyZXR1cm4gcmVzdWx0ID09IG51bGwgPwoJCQkJdHlwZSA9PT0gIiE9IiA6CgkJCQl0eXBlID09PSAiPSIgPwoJCQkJdmFsdWUgPT09IGNoZWNrIDoKCQkJCXR5cGUgPT09ICIqPSIgPwoJCQkJdmFsdWUuaW5kZXhPZihjaGVjaykgPj0gMCA6CgkJCQl0eXBlID09PSAifj0iID8KCQkJCSgiICIgKyB2YWx1ZSArICIgIikuaW5kZXhPZihjaGVjaykgPj0gMCA6CgkJCQkhY2hlY2sgPwoJCQkJdmFsdWUgJiYgcmVzdWx0ICE9PSBmYWxzZSA6CgkJCQl0eXBlID09PSAiIT0iID8KCQkJCXZhbHVlICE9IGNoZWNrIDoKCQkJCXR5cGUgPT09ICJePSIgPwoJCQkJdmFsdWUuaW5kZXhPZihjaGVjaykgPT09IDAgOgoJCQkJdHlwZSA9PT0gIiQ9IiA/CgkJCQl2YWx1ZS5zdWJzdHIodmFsdWUubGVuZ3RoIC0gY2hlY2subGVuZ3RoKSA9PT0gY2hlY2sgOgoJCQkJdHlwZSA9PT0gInw9IiA/CgkJCQl2YWx1ZSA9PT0gY2hlY2sgfHwgdmFsdWUuc3Vic3RyKDAsIGNoZWNrLmxlbmd0aCArIDEpID09PSBjaGVjayArICItIiA6CgkJCQlmYWxzZTsKCQl9LAoJCVBPUzogZnVuY3Rpb24oZWxlbSwgbWF0Y2gsIGksIGFycmF5KXsKCQkJdmFyIG5hbWUgPSBtYXRjaFsyXSwgZmlsdGVyID0gRXhwci5zZXRGaWx0ZXJzWyBuYW1lIF07CgoJCQlpZiAoIGZpbHRlciApIHsKCQkJCXJldHVybiBmaWx0ZXIoIGVsZW0sIGksIG1hdGNoLCBhcnJheSApOwoJCQl9CgkJfQoJfQp9OwoKdmFyIG9yaWdQT1MgPSBFeHByLm1hdGNoLlBPUzsKCmZvciAoIHZhciB0eXBlIGluIEV4cHIubWF0Y2ggKSB7CglFeHByLm1hdGNoWyB0eXBlIF0gPSBSZWdFeHAoIEV4cHIubWF0Y2hbIHR5cGUgXS5zb3VyY2UgKyAvKD8hW15cW10qXF0pKD8hW15cKF0qXCkpLy5zb3VyY2UgKTsKfQoKdmFyIG1ha2VBcnJheSA9IGZ1bmN0aW9uKGFycmF5LCByZXN1bHRzKSB7CglhcnJheSA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCBhcnJheSApOwoKCWlmICggcmVzdWx0cyApIHsKCQlyZXN1bHRzLnB1c2guYXBwbHkoIHJlc3VsdHMsIGFycmF5ICk7CgkJcmV0dXJuIHJlc3VsdHM7Cgl9CgkKCXJldHVybiBhcnJheTsKfTsKCi8vIFBlcmZvcm0gYSBzaW1wbGUgY2hlY2sgdG8gZGV0ZXJtaW5lIGlmIHRoZSBicm93c2VyIGlzIGNhcGFibGUgb2YKLy8gY29udmVydGluZyBhIE5vZGVMaXN0IHRvIGFuIGFycmF5IHVzaW5nIGJ1aWx0aW4gbWV0aG9kcy4KdHJ5IHsKCUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2hpbGROb2RlcyApOwoKLy8gUHJvdmlkZSBhIGZhbGxiYWNrIG1ldGhvZCBpZiBpdCBkb2VzIG5vdCB3b3JrCn0gY2F0Y2goZSl7CgltYWtlQXJyYXkgPSBmdW5jdGlvbihhcnJheSwgcmVzdWx0cykgewoJCXZhciByZXQgPSByZXN1bHRzIHx8IFtdOwoKCQlpZiAoIHRvU3RyaW5nLmNhbGwoYXJyYXkpID09PSAiW29iamVjdCBBcnJheV0iICkgewoJCQlBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseSggcmV0LCBhcnJheSApOwoJCX0gZWxzZSB7CgkJCWlmICggdHlwZW9mIGFycmF5Lmxlbmd0aCA9PT0gIm51bWJlciIgKSB7CgkJCQlmb3IgKCB2YXIgaSA9IDAsIGwgPSBhcnJheS5sZW5ndGg7IGkgPCBsOyBpKysgKSB7CgkJCQkJcmV0LnB1c2goIGFycmF5W2ldICk7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlmb3IgKCB2YXIgaSA9IDA7IGFycmF5W2ldOyBpKysgKSB7CgkJCQkJcmV0LnB1c2goIGFycmF5W2ldICk7CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiByZXQ7Cgl9Owp9Cgp2YXIgc29ydE9yZGVyOwoKaWYgKCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY29tcGFyZURvY3VtZW50UG9zaXRpb24gKSB7Cglzb3J0T3JkZXIgPSBmdW5jdGlvbiggYSwgYiApIHsKCQl2YXIgcmV0ID0gYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihiKSAmIDQgPyAtMSA6IGEgPT09IGIgPyAwIDogMTsKCQlpZiAoIHJldCA9PT0gMCApIHsKCQkJaGFzRHVwbGljYXRlID0gdHJ1ZTsKCQl9CgkJcmV0dXJuIHJldDsKCX07Cn0gZWxzZSBpZiAoICJzb3VyY2VJbmRleCIgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICkgewoJc29ydE9yZGVyID0gZnVuY3Rpb24oIGEsIGIgKSB7CgkJdmFyIHJldCA9IGEuc291cmNlSW5kZXggLSBiLnNvdXJjZUluZGV4OwoJCWlmICggcmV0ID09PSAwICkgewoJCQloYXNEdXBsaWNhdGUgPSB0cnVlOwoJCX0KCQlyZXR1cm4gcmV0OwoJfTsKfSBlbHNlIGlmICggZG9jdW1lbnQuY3JlYXRlUmFuZ2UgKSB7Cglzb3J0T3JkZXIgPSBmdW5jdGlvbiggYSwgYiApIHsKCQl2YXIgYVJhbmdlID0gYS5vd25lckRvY3VtZW50LmNyZWF0ZVJhbmdlKCksIGJSYW5nZSA9IGIub3duZXJEb2N1bWVudC5jcmVhdGVSYW5nZSgpOwoJCWFSYW5nZS5zZWxlY3ROb2RlKGEpOwoJCWFSYW5nZS5jb2xsYXBzZSh0cnVlKTsKCQliUmFuZ2Uuc2VsZWN0Tm9kZShiKTsKCQliUmFuZ2UuY29sbGFwc2UodHJ1ZSk7CgkJdmFyIHJldCA9IGFSYW5nZS5jb21wYXJlQm91bmRhcnlQb2ludHMoUmFuZ2UuU1RBUlRfVE9fRU5ELCBiUmFuZ2UpOwoJCWlmICggcmV0ID09PSAwICkgewoJCQloYXNEdXBsaWNhdGUgPSB0cnVlOwoJCX0KCQlyZXR1cm4gcmV0OwoJfTsKfQoKLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBicm93c2VyIHJldHVybnMgZWxlbWVudHMgYnkgbmFtZSB3aGVuCi8vIHF1ZXJ5aW5nIGJ5IGdldEVsZW1lbnRCeUlkIChhbmQgcHJvdmlkZSBhIHdvcmthcm91bmQpCihmdW5jdGlvbigpewoJLy8gV2UncmUgZ29pbmcgdG8gaW5qZWN0IGEgZmFrZSBpbnB1dCBlbGVtZW50IHdpdGggYSBzcGVjaWZpZWQgbmFtZQoJdmFyIGZvcm0gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJmb3JtIiksCgkJaWQgPSAic2NyaXB0IiArIChuZXcgRGF0ZSkuZ2V0VGltZSgpOwoJZm9ybS5pbm5lckhUTUwgPSAiPGlucHV0IG5hbWU9JyIgKyBpZCArICInLz4iOwoKCS8vIEluamVjdCBpdCBpbnRvIHRoZSByb290IGVsZW1lbnQsIGNoZWNrIGl0cyBzdGF0dXMsIGFuZCByZW1vdmUgaXQgcXVpY2tseQoJdmFyIHJvb3QgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7Cglyb290Lmluc2VydEJlZm9yZSggZm9ybSwgcm9vdC5maXJzdENoaWxkICk7CgoJLy8gVGhlIHdvcmthcm91bmQgaGFzIHRvIGRvIGFkZGl0aW9uYWwgY2hlY2tzIGFmdGVyIGEgZ2V0RWxlbWVudEJ5SWQKCS8vIFdoaWNoIHNsb3dzIHRoaW5ncyBkb3duIGZvciBvdGhlciBicm93c2VycyAoaGVuY2UgdGhlIGJyYW5jaGluZykKCWlmICggISFkb2N1bWVudC5nZXRFbGVtZW50QnlJZCggaWQgKSApIHsKCQlFeHByLmZpbmQuSUQgPSBmdW5jdGlvbihtYXRjaCwgY29udGV4dCwgaXNYTUwpewoJCQlpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRCeUlkICE9PSAidW5kZWZpbmVkIiAmJiAhaXNYTUwgKSB7CgkJCQl2YXIgbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQobWF0Y2hbMV0pOwoJCQkJcmV0dXJuIG0gPyBtLmlkID09PSBtYXRjaFsxXSB8fCB0eXBlb2YgbS5nZXRBdHRyaWJ1dGVOb2RlICE9PSAidW5kZWZpbmVkIiAmJiBtLmdldEF0dHJpYnV0ZU5vZGUoImlkIikubm9kZVZhbHVlID09PSBtYXRjaFsxXSA/IFttXSA6IHVuZGVmaW5lZCA6IFtdOwoJCQl9CgkJfTsKCgkJRXhwci5maWx0ZXIuSUQgPSBmdW5jdGlvbihlbGVtLCBtYXRjaCl7CgkJCXZhciBub2RlID0gdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlTm9kZSAhPT0gInVuZGVmaW5lZCIgJiYgZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCJpZCIpOwoJCQlyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiBub2RlICYmIG5vZGUubm9kZVZhbHVlID09PSBtYXRjaDsKCQl9OwoJfQoKCXJvb3QucmVtb3ZlQ2hpbGQoIGZvcm0gKTsKfSkoKTsKCihmdW5jdGlvbigpewoJLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSBicm93c2VyIHJldHVybnMgb25seSBlbGVtZW50cwoJLy8gd2hlbiBkb2luZyBnZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpCgoJLy8gQ3JlYXRlIGEgZmFrZSBlbGVtZW50Cgl2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CglkaXYuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQoIiIpICk7CgoJLy8gTWFrZSBzdXJlIG5vIGNvbW1lbnRzIGFyZSBmb3VuZAoJaWYgKCBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIioiKS5sZW5ndGggPiAwICkgewoJCUV4cHIuZmluZC5UQUcgPSBmdW5jdGlvbihtYXRjaCwgY29udGV4dCl7CgkJCXZhciByZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZShtYXRjaFsxXSk7CgoJCQkvLyBGaWx0ZXIgb3V0IHBvc3NpYmxlIGNvbW1lbnRzCgkJCWlmICggbWF0Y2hbMV0gPT09ICIqIiApIHsKCQkJCXZhciB0bXAgPSBbXTsKCgkJCQlmb3IgKCB2YXIgaSA9IDA7IHJlc3VsdHNbaV07IGkrKyApIHsKCQkJCQlpZiAoIHJlc3VsdHNbaV0ubm9kZVR5cGUgPT09IDEgKSB7CgkJCQkJCXRtcC5wdXNoKCByZXN1bHRzW2ldICk7CgkJCQkJfQoJCQkJfQoKCQkJCXJlc3VsdHMgPSB0bXA7CgkJCX0KCgkJCXJldHVybiByZXN1bHRzOwoJCX07Cgl9CgoJLy8gQ2hlY2sgdG8gc2VlIGlmIGFuIGF0dHJpYnV0ZSByZXR1cm5zIG5vcm1hbGl6ZWQgaHJlZiBhdHRyaWJ1dGVzCglkaXYuaW5uZXJIVE1MID0gIjxhIGhyZWY9JyMnPjwvYT4iOwoJaWYgKCBkaXYuZmlyc3RDaGlsZCAmJiB0eXBlb2YgZGl2LmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlICE9PSAidW5kZWZpbmVkIiAmJgoJCQlkaXYuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoImhyZWYiKSAhPT0gIiMiICkgewoJCUV4cHIuYXR0ckhhbmRsZS5ocmVmID0gZnVuY3Rpb24oZWxlbSl7CgkJCXJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSgiaHJlZiIsIDIpOwoJCX07Cgl9Cn0pKCk7CgppZiAoIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwgKSAoZnVuY3Rpb24oKXsKCXZhciBvbGRTaXp6bGUgPSBTaXp6bGUsIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpOwoJZGl2LmlubmVySFRNTCA9ICI8cCBjbGFzcz0nVEVTVCc+PC9wPiI7CgoJLy8gU2FmYXJpIGNhbid0IGhhbmRsZSB1cHBlcmNhc2Ugb3IgdW5pY29kZSBjaGFyYWN0ZXJzIHdoZW4KCS8vIGluIHF1aXJrcyBtb2RlLgoJaWYgKCBkaXYucXVlcnlTZWxlY3RvckFsbCAmJiBkaXYucXVlcnlTZWxlY3RvckFsbCgiLlRFU1QiKS5sZW5ndGggPT09IDAgKSB7CgkJcmV0dXJuOwoJfQoJCglTaXp6bGUgPSBmdW5jdGlvbihxdWVyeSwgY29udGV4dCwgZXh0cmEsIHNlZWQpewoJCWNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50OwoKCQkvLyBPbmx5IHVzZSBxdWVyeVNlbGVjdG9yQWxsIG9uIG5vbi1YTUwgZG9jdW1lbnRzCgkJLy8gKElEIHNlbGVjdG9ycyBkb24ndCB3b3JrIGluIG5vbi1IVE1MIGRvY3VtZW50cykKCQlpZiAoICFzZWVkICYmIGNvbnRleHQubm9kZVR5cGUgPT09IDkgJiYgIWlzWE1MKGNvbnRleHQpICkgewoJCQl0cnkgewoJCQkJcmV0dXJuIG1ha2VBcnJheSggY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KSwgZXh0cmEgKTsKCQkJfSBjYXRjaChlKXt9CgkJfQoJCQoJCXJldHVybiBvbGRTaXp6bGUocXVlcnksIGNvbnRleHQsIGV4dHJhLCBzZWVkKTsKCX07CgoJU2l6emxlLmZpbmQgPSBvbGRTaXp6bGUuZmluZDsKCVNpenpsZS5maWx0ZXIgPSBvbGRTaXp6bGUuZmlsdGVyOwoJU2l6emxlLnNlbGVjdG9ycyA9IG9sZFNpenpsZS5zZWxlY3RvcnM7CglTaXp6bGUubWF0Y2hlcyA9IG9sZFNpenpsZS5tYXRjaGVzOwp9KSgpOwoKaWYgKCBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICkgKGZ1bmN0aW9uKCl7Cgl2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CglkaXYuaW5uZXJIVE1MID0gIjxkaXYgY2xhc3M9J3Rlc3QgZSc+PC9kaXY+PGRpdiBjbGFzcz0ndGVzdCc+PC9kaXY+IjsKCgkvLyBPcGVyYSBjYW4ndCBmaW5kIGEgc2Vjb25kIGNsYXNzbmFtZSAoaW4gOS42KQoJaWYgKCBkaXYuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgiZSIpLmxlbmd0aCA9PT0gMCApCgkJcmV0dXJuOwoKCS8vIFNhZmFyaSBjYWNoZXMgY2xhc3MgYXR0cmlidXRlcywgZG9lc24ndCBjYXRjaCBjaGFuZ2VzIChpbiAzLjIpCglkaXYubGFzdENoaWxkLmNsYXNzTmFtZSA9ICJlIjsKCglpZiAoIGRpdi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCJlIikubGVuZ3RoID09PSAxICkKCQlyZXR1cm47CgoJRXhwci5vcmRlci5zcGxpY2UoMSwgMCwgIkNMQVNTIik7CglFeHByLmZpbmQuQ0xBU1MgPSBmdW5jdGlvbihtYXRjaCwgY29udGV4dCwgaXNYTUwpIHsKCQlpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgIT09ICJ1bmRlZmluZWQiICYmICFpc1hNTCApIHsKCQkJcmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShtYXRjaFsxXSk7CgkJfQoJfTsKfSkoKTsKCmZ1bmN0aW9uIGRpck5vZGVDaGVjayggZGlyLCBjdXIsIGRvbmVOYW1lLCBjaGVja1NldCwgbm9kZUNoZWNrLCBpc1hNTCApIHsKCXZhciBzaWJEaXIgPSBkaXIgPT0gInByZXZpb3VzU2libGluZyIgJiYgIWlzWE1MOwoJZm9yICggdmFyIGkgPSAwLCBsID0gY2hlY2tTZXQubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCXZhciBlbGVtID0gY2hlY2tTZXRbaV07CgkJaWYgKCBlbGVtICkgewoJCQlpZiAoIHNpYkRpciAmJiBlbGVtLm5vZGVUeXBlID09PSAxICl7CgkJCQllbGVtLnNpemNhY2hlID0gZG9uZU5hbWU7CgkJCQllbGVtLnNpenNldCA9IGk7CgkJCX0KCQkJZWxlbSA9IGVsZW1bZGlyXTsKCQkJdmFyIG1hdGNoID0gZmFsc2U7CgoJCQl3aGlsZSAoIGVsZW0gKSB7CgkJCQlpZiAoIGVsZW0uc2l6Y2FjaGUgPT09IGRvbmVOYW1lICkgewoJCQkJCW1hdGNoID0gY2hlY2tTZXRbZWxlbS5zaXpzZXRdOwoJCQkJCWJyZWFrOwoJCQkJfQoKCQkJCWlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAhaXNYTUwgKXsKCQkJCQllbGVtLnNpemNhY2hlID0gZG9uZU5hbWU7CgkJCQkJZWxlbS5zaXpzZXQgPSBpOwoJCQkJfQoKCQkJCWlmICggZWxlbS5ub2RlTmFtZSA9PT0gY3VyICkgewoJCQkJCW1hdGNoID0gZWxlbTsKCQkJCQlicmVhazsKCQkJCX0KCgkJCQllbGVtID0gZWxlbVtkaXJdOwoJCQl9CgoJCQljaGVja1NldFtpXSA9IG1hdGNoOwoJCX0KCX0KfQoKZnVuY3Rpb24gZGlyQ2hlY2soIGRpciwgY3VyLCBkb25lTmFtZSwgY2hlY2tTZXQsIG5vZGVDaGVjaywgaXNYTUwgKSB7Cgl2YXIgc2liRGlyID0gZGlyID09ICJwcmV2aW91c1NpYmxpbmciICYmICFpc1hNTDsKCWZvciAoIHZhciBpID0gMCwgbCA9IGNoZWNrU2V0Lmxlbmd0aDsgaSA8IGw7IGkrKyApIHsKCQl2YXIgZWxlbSA9IGNoZWNrU2V0W2ldOwoJCWlmICggZWxlbSApIHsKCQkJaWYgKCBzaWJEaXIgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHsKCQkJCWVsZW0uc2l6Y2FjaGUgPSBkb25lTmFtZTsKCQkJCWVsZW0uc2l6c2V0ID0gaTsKCQkJfQoJCQllbGVtID0gZWxlbVtkaXJdOwoJCQl2YXIgbWF0Y2ggPSBmYWxzZTsKCgkJCXdoaWxlICggZWxlbSApIHsKCQkJCWlmICggZWxlbS5zaXpjYWNoZSA9PT0gZG9uZU5hbWUgKSB7CgkJCQkJbWF0Y2ggPSBjaGVja1NldFtlbGVtLnNpenNldF07CgkJCQkJYnJlYWs7CgkJCQl9CgoJCQkJaWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkgewoJCQkJCWlmICggIWlzWE1MICkgewoJCQkJCQllbGVtLnNpemNhY2hlID0gZG9uZU5hbWU7CgkJCQkJCWVsZW0uc2l6c2V0ID0gaTsKCQkJCQl9CgkJCQkJaWYgKCB0eXBlb2YgY3VyICE9PSAic3RyaW5nIiApIHsKCQkJCQkJaWYgKCBlbGVtID09PSBjdXIgKSB7CgkJCQkJCQltYXRjaCA9IHRydWU7CgkJCQkJCQlicmVhazsKCQkJCQkJfQoKCQkJCQl9IGVsc2UgaWYgKCBTaXp6bGUuZmlsdGVyKCBjdXIsIFtlbGVtXSApLmxlbmd0aCA+IDAgKSB7CgkJCQkJCW1hdGNoID0gZWxlbTsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoKCQkJCWVsZW0gPSBlbGVtW2Rpcl07CgkJCX0KCgkJCWNoZWNrU2V0W2ldID0gbWF0Y2g7CgkJfQoJfQp9Cgp2YXIgY29udGFpbnMgPSBkb2N1bWVudC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiA/ICBmdW5jdGlvbihhLCBiKXsKCXJldHVybiBhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGIpICYgMTY7Cn0gOiBmdW5jdGlvbihhLCBiKXsKCXJldHVybiBhICE9PSBiICYmIChhLmNvbnRhaW5zID8gYS5jb250YWlucyhiKSA6IHRydWUpOwp9OwoKdmFyIGlzWE1MID0gZnVuY3Rpb24oZWxlbSl7CglyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gOSAmJiBlbGVtLmRvY3VtZW50RWxlbWVudC5ub2RlTmFtZSAhPT0gIkhUTUwiIHx8CgkJISFlbGVtLm93bmVyRG9jdW1lbnQgJiYgaXNYTUwoIGVsZW0ub3duZXJEb2N1bWVudCApOwp9OwoKdmFyIHBvc1Byb2Nlc3MgPSBmdW5jdGlvbihzZWxlY3RvciwgY29udGV4dCl7Cgl2YXIgdG1wU2V0ID0gW10sIGxhdGVyID0gIiIsIG1hdGNoLAoJCXJvb3QgPSBjb250ZXh0Lm5vZGVUeXBlID8gW2NvbnRleHRdIDogY29udGV4dDsKCgkvLyBQb3NpdGlvbiBzZWxlY3RvcnMgbXVzdCBiZSBkb25lIGFmdGVyIHRoZSBmaWx0ZXIKCS8vIEFuZCBzbyBtdXN0IDpub3QocG9zaXRpb25hbCkgc28gd2UgbW92ZSBhbGwgUFNFVURPcyB0byB0aGUgZW5kCgl3aGlsZSAoIChtYXRjaCA9IEV4cHIubWF0Y2guUFNFVURPLmV4ZWMoIHNlbGVjdG9yICkpICkgewoJCWxhdGVyICs9IG1hdGNoWzBdOwoJCXNlbGVjdG9yID0gc2VsZWN0b3IucmVwbGFjZSggRXhwci5tYXRjaC5QU0VVRE8sICIiICk7Cgl9CgoJc2VsZWN0b3IgPSBFeHByLnJlbGF0aXZlW3NlbGVjdG9yXSA/IHNlbGVjdG9yICsgIioiIDogc2VsZWN0b3I7CgoJZm9yICggdmFyIGkgPSAwLCBsID0gcm9vdC5sZW5ndGg7IGkgPCBsOyBpKysgKSB7CgkJU2l6emxlKCBzZWxlY3Rvciwgcm9vdFtpXSwgdG1wU2V0ICk7Cgl9CgoJcmV0dXJuIFNpenpsZS5maWx0ZXIoIGxhdGVyLCB0bXBTZXQgKTsKfTsKCi8vIEVYUE9TRQpqUXVlcnkuZmluZCA9IFNpenpsZTsKalF1ZXJ5LmZpbHRlciA9IFNpenpsZS5maWx0ZXI7CmpRdWVyeS5leHByID0gU2l6emxlLnNlbGVjdG9yczsKalF1ZXJ5LmV4cHJbIjoiXSA9IGpRdWVyeS5leHByLmZpbHRlcnM7CgpTaXp6bGUuc2VsZWN0b3JzLmZpbHRlcnMuaGlkZGVuID0gZnVuY3Rpb24oZWxlbSl7CglyZXR1cm4gZWxlbS5vZmZzZXRXaWR0aCA9PT0gMCB8fCBlbGVtLm9mZnNldEhlaWdodCA9PT0gMDsKfTsKClNpenpsZS5zZWxlY3RvcnMuZmlsdGVycy52aXNpYmxlID0gZnVuY3Rpb24oZWxlbSl7CglyZXR1cm4gZWxlbS5vZmZzZXRXaWR0aCA+IDAgfHwgZWxlbS5vZmZzZXRIZWlnaHQgPiAwOwp9OwoKU2l6emxlLnNlbGVjdG9ycy5maWx0ZXJzLmFuaW1hdGVkID0gZnVuY3Rpb24oZWxlbSl7CglyZXR1cm4galF1ZXJ5LmdyZXAoalF1ZXJ5LnRpbWVycywgZnVuY3Rpb24oZm4pewoJCXJldHVybiBlbGVtID09PSBmbi5lbGVtOwoJfSkubGVuZ3RoOwp9OwoKalF1ZXJ5Lm11bHRpRmlsdGVyID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1zLCBub3QgKSB7CglpZiAoIG5vdCApIHsKCQlleHByID0gIjpub3QoIiArIGV4cHIgKyAiKSI7Cgl9CgoJcmV0dXJuIFNpenpsZS5tYXRjaGVzKGV4cHIsIGVsZW1zKTsKfTsKCmpRdWVyeS5kaXIgPSBmdW5jdGlvbiggZWxlbSwgZGlyICl7Cgl2YXIgbWF0Y2hlZCA9IFtdLCBjdXIgPSBlbGVtW2Rpcl07Cgl3aGlsZSAoIGN1ciAmJiBjdXIgIT0gZG9jdW1lbnQgKSB7CgkJaWYgKCBjdXIubm9kZVR5cGUgPT0gMSApCgkJCW1hdGNoZWQucHVzaCggY3VyICk7CgkJY3VyID0gY3VyW2Rpcl07Cgl9CglyZXR1cm4gbWF0Y2hlZDsKfTsKCmpRdWVyeS5udGggPSBmdW5jdGlvbihjdXIsIHJlc3VsdCwgZGlyLCBlbGVtKXsKCXJlc3VsdCA9IHJlc3VsdCB8fCAxOwoJdmFyIG51bSA9IDA7CgoJZm9yICggOyBjdXI7IGN1ciA9IGN1cltkaXJdICkKCQlpZiAoIGN1ci5ub2RlVHlwZSA9PSAxICYmICsrbnVtID09IHJlc3VsdCApCgkJCWJyZWFrOwoKCXJldHVybiBjdXI7Cn07CgpqUXVlcnkuc2libGluZyA9IGZ1bmN0aW9uKG4sIGVsZW0pewoJdmFyIHIgPSBbXTsKCglmb3IgKCA7IG47IG4gPSBuLm5leHRTaWJsaW5nICkgewoJCWlmICggbi5ub2RlVHlwZSA9PSAxICYmIG4gIT0gZWxlbSApCgkJCXIucHVzaCggbiApOwoJfQoKCXJldHVybiByOwp9OwoKcmV0dXJuOwoKd2luZG93LlNpenpsZSA9IFNpenpsZTsKCn0pKCk7Ci8qCiAqIEEgbnVtYmVyIG9mIGhlbHBlciBmdW5jdGlvbnMgdXNlZCBmb3IgbWFuYWdpbmcgZXZlbnRzLgogKiBNYW55IG9mIHRoZSBpZGVhcyBiZWhpbmQgdGhpcyBjb2RlIG9yaWdpbmF0ZWQgZnJvbQogKiBEZWFuIEVkd2FyZHMnIGFkZEV2ZW50IGxpYnJhcnkuCiAqLwpqUXVlcnkuZXZlbnQgPSB7CgoJLy8gQmluZCBhbiBldmVudCB0byBhbiBlbGVtZW50CgkvLyBPcmlnaW5hbCBieSBEZWFuIEVkd2FyZHMKCWFkZDogZnVuY3Rpb24oZWxlbSwgdHlwZXMsIGhhbmRsZXIsIGRhdGEpIHsKCQlpZiAoIGVsZW0ubm9kZVR5cGUgPT0gMyB8fCBlbGVtLm5vZGVUeXBlID09IDggKQoJCQlyZXR1cm47CgoJCS8vIEZvciB3aGF0ZXZlciByZWFzb24sIElFIGhhcyB0cm91YmxlIHBhc3NpbmcgdGhlIHdpbmRvdyBvYmplY3QKCQkvLyBhcm91bmQsIGNhdXNpbmcgaXQgdG8gYmUgY2xvbmVkIGluIHRoZSBwcm9jZXNzCgkJaWYgKCBlbGVtLnNldEludGVydmFsICYmIGVsZW0gIT0gd2luZG93ICkKCQkJZWxlbSA9IHdpbmRvdzsKCgkJLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGZ1bmN0aW9uIGJlaW5nIGV4ZWN1dGVkIGhhcyBhIHVuaXF1ZSBJRAoJCWlmICggIWhhbmRsZXIuZ3VpZCApCgkJCWhhbmRsZXIuZ3VpZCA9IHRoaXMuZ3VpZCsrOwoKCQkvLyBpZiBkYXRhIGlzIHBhc3NlZCwgYmluZCB0byBoYW5kbGVyCgkJaWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7CgkJCS8vIENyZWF0ZSB0ZW1wb3JhcnkgZnVuY3Rpb24gcG9pbnRlciB0byBvcmlnaW5hbCBoYW5kbGVyCgkJCXZhciBmbiA9IGhhbmRsZXI7CgoJCQkvLyBDcmVhdGUgdW5pcXVlIGhhbmRsZXIgZnVuY3Rpb24sIHdyYXBwZWQgYXJvdW5kIG9yaWdpbmFsIGhhbmRsZXIKCQkJaGFuZGxlciA9IHRoaXMucHJveHkoIGZuICk7CgoJCQkvLyBTdG9yZSBkYXRhIGluIHVuaXF1ZSBoYW5kbGVyCgkJCWhhbmRsZXIuZGF0YSA9IGRhdGE7CgkJfQoKCQkvLyBJbml0IHRoZSBlbGVtZW50J3MgZXZlbnQgc3RydWN0dXJlCgkJdmFyIGV2ZW50cyA9IGpRdWVyeS5kYXRhKGVsZW0sICJldmVudHMiKSB8fCBqUXVlcnkuZGF0YShlbGVtLCAiZXZlbnRzIiwge30pLAoJCQloYW5kbGUgPSBqUXVlcnkuZGF0YShlbGVtLCAiaGFuZGxlIikgfHwgalF1ZXJ5LmRhdGEoZWxlbSwgImhhbmRsZSIsIGZ1bmN0aW9uKCl7CgkJCQkvLyBIYW5kbGUgdGhlIHNlY29uZCBldmVudCBvZiBhIHRyaWdnZXIgYW5kIHdoZW4KCQkJCS8vIGFuIGV2ZW50IGlzIGNhbGxlZCBhZnRlciBhIHBhZ2UgaGFzIHVubG9hZGVkCgkJCQlyZXR1cm4gdHlwZW9mIGpRdWVyeSAhPT0gInVuZGVmaW5lZCIgJiYgIWpRdWVyeS5ldmVudC50cmlnZ2VyZWQgPwoJCQkJCWpRdWVyeS5ldmVudC5oYW5kbGUuYXBwbHkoYXJndW1lbnRzLmNhbGxlZS5lbGVtLCBhcmd1bWVudHMpIDoKCQkJCQl1bmRlZmluZWQ7CgkJCX0pOwoJCS8vIEFkZCBlbGVtIGFzIGEgcHJvcGVydHkgb2YgdGhlIGhhbmRsZSBmdW5jdGlvbgoJCS8vIFRoaXMgaXMgdG8gcHJldmVudCBhIG1lbW9yeSBsZWFrIHdpdGggbm9uLW5hdGl2ZQoJCS8vIGV2ZW50IGluIElFLgoJCWhhbmRsZS5lbGVtID0gZWxlbTsKCgkJLy8gSGFuZGxlIG11bHRpcGxlIGV2ZW50cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZQoJCS8vIGpRdWVyeSguLi4pLmJpbmQoIm1vdXNlb3ZlciBtb3VzZW91dCIsIGZuKTsKCQlqUXVlcnkuZWFjaCh0eXBlcy5zcGxpdCgvXHMrLyksIGZ1bmN0aW9uKGluZGV4LCB0eXBlKSB7CgkJCS8vIE5hbWVzcGFjZWQgZXZlbnQgaGFuZGxlcnMKCQkJdmFyIG5hbWVzcGFjZXMgPSB0eXBlLnNwbGl0KCIuIik7CgkJCXR5cGUgPSBuYW1lc3BhY2VzLnNoaWZ0KCk7CgkJCWhhbmRsZXIudHlwZSA9IG5hbWVzcGFjZXMuc2xpY2UoKS5zb3J0KCkuam9pbigiLiIpOwoKCQkJLy8gR2V0IHRoZSBjdXJyZW50IGxpc3Qgb2YgZnVuY3Rpb25zIGJvdW5kIHRvIHRoaXMgZXZlbnQKCQkJdmFyIGhhbmRsZXJzID0gZXZlbnRzW3R5cGVdOwoJCQkKCQkJaWYgKCBqUXVlcnkuZXZlbnQuc3BlY2lhbEFsbFt0eXBlXSApCgkJCQlqUXVlcnkuZXZlbnQuc3BlY2lhbEFsbFt0eXBlXS5zZXR1cC5jYWxsKGVsZW0sIGRhdGEsIG5hbWVzcGFjZXMpOwoKCQkJLy8gSW5pdCB0aGUgZXZlbnQgaGFuZGxlciBxdWV1ZQoJCQlpZiAoIWhhbmRsZXJzKSB7CgkJCQloYW5kbGVycyA9IGV2ZW50c1t0eXBlXSA9IHt9OwoKCQkJCS8vIENoZWNrIGZvciBhIHNwZWNpYWwgZXZlbnQgaGFuZGxlcgoJCQkJLy8gT25seSB1c2UgYWRkRXZlbnRMaXN0ZW5lci9hdHRhY2hFdmVudCBpZiB0aGUgc3BlY2lhbAoJCQkJLy8gZXZlbnRzIGhhbmRsZXIgcmV0dXJucyBmYWxzZQoJCQkJaWYgKCAhalF1ZXJ5LmV2ZW50LnNwZWNpYWxbdHlwZV0gfHwgalF1ZXJ5LmV2ZW50LnNwZWNpYWxbdHlwZV0uc2V0dXAuY2FsbChlbGVtLCBkYXRhLCBuYW1lc3BhY2VzKSA9PT0gZmFsc2UgKSB7CgkJCQkJLy8gQmluZCB0aGUgZ2xvYmFsIGV2ZW50IGhhbmRsZXIgdG8gdGhlIGVsZW1lbnQKCQkJCQlpZiAoZWxlbS5hZGRFdmVudExpc3RlbmVyKQoJCQkJCQllbGVtLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgaGFuZGxlLCBmYWxzZSk7CgkJCQkJZWxzZSBpZiAoZWxlbS5hdHRhY2hFdmVudCkKCQkJCQkJZWxlbS5hdHRhY2hFdmVudCgib24iICsgdHlwZSwgaGFuZGxlKTsKCQkJCX0KCQkJfQoKCQkJLy8gQWRkIHRoZSBmdW5jdGlvbiB0byB0aGUgZWxlbWVudCdzIGhhbmRsZXIgbGlzdAoJCQloYW5kbGVyc1toYW5kbGVyLmd1aWRdID0gaGFuZGxlcjsKCgkJCS8vIEtlZXAgdHJhY2sgb2Ygd2hpY2ggZXZlbnRzIGhhdmUgYmVlbiB1c2VkLCBmb3IgZ2xvYmFsIHRyaWdnZXJpbmcKCQkJalF1ZXJ5LmV2ZW50Lmdsb2JhbFt0eXBlXSA9IHRydWU7CgkJfSk7CgoJCS8vIE51bGxpZnkgZWxlbSB0byBwcmV2ZW50IG1lbW9yeSBsZWFrcyBpbiBJRQoJCWVsZW0gPSBudWxsOwoJfSwKCglndWlkOiAxLAoJZ2xvYmFsOiB7fSwKCgkvLyBEZXRhY2ggYW4gZXZlbnQgb3Igc2V0IG9mIGV2ZW50cyBmcm9tIGFuIGVsZW1lbnQKCXJlbW92ZTogZnVuY3Rpb24oZWxlbSwgdHlwZXMsIGhhbmRsZXIpIHsKCQkvLyBkb24ndCBkbyBldmVudHMgb24gdGV4dCBhbmQgY29tbWVudCBub2RlcwoJCWlmICggZWxlbS5ub2RlVHlwZSA9PSAzIHx8IGVsZW0ubm9kZVR5cGUgPT0gOCApCgkJCXJldHVybjsKCgkJdmFyIGV2ZW50cyA9IGpRdWVyeS5kYXRhKGVsZW0sICJldmVudHMiKSwgcmV0LCBpbmRleDsKCgkJaWYgKCBldmVudHMgKSB7CgkJCS8vIFVuYmluZCBhbGwgZXZlbnRzIGZvciB0aGUgZWxlbWVudAoJCQlpZiAoIHR5cGVzID09PSB1bmRlZmluZWQgfHwgKHR5cGVvZiB0eXBlcyA9PT0gInN0cmluZyIgJiYgdHlwZXMuY2hhckF0KDApID09ICIuIikgKQoJCQkJZm9yICggdmFyIHR5cGUgaW4gZXZlbnRzICkKCQkJCQl0aGlzLnJlbW92ZSggZWxlbSwgdHlwZSArICh0eXBlcyB8fCAiIikgKTsKCQkJZWxzZSB7CgkJCQkvLyB0eXBlcyBpcyBhY3R1YWxseSBhbiBldmVudCBvYmplY3QgaGVyZQoJCQkJaWYgKCB0eXBlcy50eXBlICkgewoJCQkJCWhhbmRsZXIgPSB0eXBlcy5oYW5kbGVyOwoJCQkJCXR5cGVzID0gdHlwZXMudHlwZTsKCQkJCX0KCgkJCQkvLyBIYW5kbGUgbXVsdGlwbGUgZXZlbnRzIHNlcGVyYXRlZCBieSBhIHNwYWNlCgkJCQkvLyBqUXVlcnkoLi4uKS51bmJpbmQoIm1vdXNlb3ZlciBtb3VzZW91dCIsIGZuKTsKCQkJCWpRdWVyeS5lYWNoKHR5cGVzLnNwbGl0KC9ccysvKSwgZnVuY3Rpb24oaW5kZXgsIHR5cGUpewoJCQkJCS8vIE5hbWVzcGFjZWQgZXZlbnQgaGFuZGxlcnMKCQkJCQl2YXIgbmFtZXNwYWNlcyA9IHR5cGUuc3BsaXQoIi4iKTsKCQkJCQl0eXBlID0gbmFtZXNwYWNlcy5zaGlmdCgpOwoJCQkJCXZhciBuYW1lc3BhY2UgPSBSZWdFeHAoIihefFxcLikiICsgbmFtZXNwYWNlcy5zbGljZSgpLnNvcnQoKS5qb2luKCIuKlxcLiIpICsgIihcXC58JCkiKTsKCgkJCQkJaWYgKCBldmVudHNbdHlwZV0gKSB7CgkJCQkJCS8vIHJlbW92ZSB0aGUgZ2l2ZW4gaGFuZGxlciBmb3IgdGhlIGdpdmVuIHR5cGUKCQkJCQkJaWYgKCBoYW5kbGVyICkKCQkJCQkJCWRlbGV0ZSBldmVudHNbdHlwZV1baGFuZGxlci5ndWlkXTsKCgkJCQkJCS8vIHJlbW92ZSBhbGwgaGFuZGxlcnMgZm9yIHRoZSBnaXZlbiB0eXBlCgkJCQkJCWVsc2UKCQkJCQkJCWZvciAoIHZhciBoYW5kbGUgaW4gZXZlbnRzW3R5cGVdICkKCQkJCQkJCQkvLyBIYW5kbGUgdGhlIHJlbW92YWwgb2YgbmFtZXNwYWNlZCBldmVudHMKCQkJCQkJCQlpZiAoIG5hbWVzcGFjZS50ZXN0KGV2ZW50c1t0eXBlXVtoYW5kbGVdLnR5cGUpICkKCQkJCQkJCQkJZGVsZXRlIGV2ZW50c1t0eXBlXVtoYW5kbGVdOwoJCQkJCQkJCQkKCQkJCQkJaWYgKCBqUXVlcnkuZXZlbnQuc3BlY2lhbEFsbFt0eXBlXSApCgkJCQkJCQlqUXVlcnkuZXZlbnQuc3BlY2lhbEFsbFt0eXBlXS50ZWFyZG93bi5jYWxsKGVsZW0sIG5hbWVzcGFjZXMpOwoKCQkJCQkJLy8gcmVtb3ZlIGdlbmVyaWMgZXZlbnQgaGFuZGxlciBpZiBubyBtb3JlIGhhbmRsZXJzIGV4aXN0CgkJCQkJCWZvciAoIHJldCBpbiBldmVudHNbdHlwZV0gKSBicmVhazsKCQkJCQkJaWYgKCAhcmV0ICkgewoJCQkJCQkJaWYgKCAhalF1ZXJ5LmV2ZW50LnNwZWNpYWxbdHlwZV0gfHwgalF1ZXJ5LmV2ZW50LnNwZWNpYWxbdHlwZV0udGVhcmRvd24uY2FsbChlbGVtLCBuYW1lc3BhY2VzKSA9PT0gZmFsc2UgKSB7CgkJCQkJCQkJaWYgKGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lcikKCQkJCQkJCQkJZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGpRdWVyeS5kYXRhKGVsZW0sICJoYW5kbGUiKSwgZmFsc2UpOwoJCQkJCQkJCWVsc2UgaWYgKGVsZW0uZGV0YWNoRXZlbnQpCgkJCQkJCQkJCWVsZW0uZGV0YWNoRXZlbnQoIm9uIiArIHR5cGUsIGpRdWVyeS5kYXRhKGVsZW0sICJoYW5kbGUiKSk7CgkJCQkJCQl9CgkJCQkJCQlyZXQgPSBudWxsOwoJCQkJCQkJZGVsZXRlIGV2ZW50c1t0eXBlXTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0pOwoJCQl9CgoJCQkvLyBSZW1vdmUgdGhlIGV4cGFuZG8gaWYgaXQncyBubyBsb25nZXIgdXNlZAoJCQlmb3IgKCByZXQgaW4gZXZlbnRzICkgYnJlYWs7CgkJCWlmICggIXJldCApIHsKCQkJCXZhciBoYW5kbGUgPSBqUXVlcnkuZGF0YSggZWxlbSwgImhhbmRsZSIgKTsKCQkJCWlmICggaGFuZGxlICkgaGFuZGxlLmVsZW0gPSBudWxsOwoJCQkJalF1ZXJ5LnJlbW92ZURhdGEoIGVsZW0sICJldmVudHMiICk7CgkJCQlqUXVlcnkucmVtb3ZlRGF0YSggZWxlbSwgImhhbmRsZSIgKTsKCQkJfQoJCX0KCX0sCgoJLy8gYnViYmxpbmcgaXMgaW50ZXJuYWwKCXRyaWdnZXI6IGZ1bmN0aW9uKCBldmVudCwgZGF0YSwgZWxlbSwgYnViYmxpbmcgKSB7CgkJLy8gRXZlbnQgb2JqZWN0IG9yIGV2ZW50IHR5cGUKCQl2YXIgdHlwZSA9IGV2ZW50LnR5cGUgfHwgZXZlbnQ7CgoJCWlmKCAhYnViYmxpbmcgKXsKCQkJZXZlbnQgPSB0eXBlb2YgZXZlbnQgPT09ICJvYmplY3QiID8KCQkJCS8vIGpRdWVyeS5FdmVudCBvYmplY3QKCQkJCWV2ZW50W2V4cGFuZG9dID8gZXZlbnQgOgoJCQkJLy8gT2JqZWN0IGxpdGVyYWwKCQkJCWpRdWVyeS5leHRlbmQoIGpRdWVyeS5FdmVudCh0eXBlKSwgZXZlbnQgKSA6CgkJCQkvLyBKdXN0IHRoZSBldmVudCB0eXBlIChzdHJpbmcpCgkJCQlqUXVlcnkuRXZlbnQodHlwZSk7CgoJCQlpZiAoIHR5cGUuaW5kZXhPZigiISIpID49IDAgKSB7CgkJCQlldmVudC50eXBlID0gdHlwZSA9IHR5cGUuc2xpY2UoMCwgLTEpOwoJCQkJZXZlbnQuZXhjbHVzaXZlID0gdHJ1ZTsKCQkJfQoKCQkJLy8gSGFuZGxlIGEgZ2xvYmFsIHRyaWdnZXIKCQkJaWYgKCAhZWxlbSApIHsKCQkJCS8vIERvbid0IGJ1YmJsZSBjdXN0b20gZXZlbnRzIHdoZW4gZ2xvYmFsICh0byBhdm9pZCB0b28gbXVjaCBvdmVyaGVhZCkKCQkJCWV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwoJCQkJLy8gT25seSB0cmlnZ2VyIGlmIHdlJ3ZlIGV2ZXIgYm91bmQgYW4gZXZlbnQgZm9yIGl0CgkJCQlpZiAoIHRoaXMuZ2xvYmFsW3R5cGVdICkKCQkJCQlqUXVlcnkuZWFjaCggalF1ZXJ5LmNhY2hlLCBmdW5jdGlvbigpewoJCQkJCQlpZiAoIHRoaXMuZXZlbnRzICYmIHRoaXMuZXZlbnRzW3R5cGVdICkKCQkJCQkJCWpRdWVyeS5ldmVudC50cmlnZ2VyKCBldmVudCwgZGF0YSwgdGhpcy5oYW5kbGUuZWxlbSApOwoJCQkJCX0pOwoJCQl9CgoJCQkvLyBIYW5kbGUgdHJpZ2dlcmluZyBhIHNpbmdsZSBlbGVtZW50CgoJCQkvLyBkb24ndCBkbyBldmVudHMgb24gdGV4dCBhbmQgY29tbWVudCBub2RlcwoJCQlpZiAoICFlbGVtIHx8IGVsZW0ubm9kZVR5cGUgPT0gMyB8fCBlbGVtLm5vZGVUeXBlID09IDggKQoJCQkJcmV0dXJuIHVuZGVmaW5lZDsKCQkJCgkJCS8vIENsZWFuIHVwIGluIGNhc2UgaXQgaXMgcmV1c2VkCgkJCWV2ZW50LnJlc3VsdCA9IHVuZGVmaW5lZDsKCQkJZXZlbnQudGFyZ2V0ID0gZWxlbTsKCQkJCgkJCS8vIENsb25lIHRoZSBpbmNvbWluZyBkYXRhLCBpZiBhbnkKCQkJZGF0YSA9IGpRdWVyeS5tYWtlQXJyYXkoZGF0YSk7CgkJCWRhdGEudW5zaGlmdCggZXZlbnQgKTsKCQl9CgoJCWV2ZW50LmN1cnJlbnRUYXJnZXQgPSBlbGVtOwoKCQkvLyBUcmlnZ2VyIHRoZSBldmVudCwgaXQgaXMgYXNzdW1lZCB0aGF0ICJoYW5kbGUiIGlzIGEgZnVuY3Rpb24KCQl2YXIgaGFuZGxlID0galF1ZXJ5LmRhdGEoZWxlbSwgImhhbmRsZSIpOwoJCWlmICggaGFuZGxlICkKCQkJaGFuZGxlLmFwcGx5KCBlbGVtLCBkYXRhICk7CgoJCS8vIEhhbmRsZSB0cmlnZ2VyaW5nIG5hdGl2ZSAub25mb28gaGFuZGxlcnMgKGFuZCBvbiBsaW5rcyBzaW5jZSB3ZSBkb24ndCBjYWxsIC5jbGljaygpIGZvciBsaW5rcykKCQlpZiAoICghZWxlbVt0eXBlXSB8fCAoalF1ZXJ5Lm5vZGVOYW1lKGVsZW0sICdhJykgJiYgdHlwZSA9PSAiY2xpY2siKSkgJiYgZWxlbVsib24iK3R5cGVdICYmIGVsZW1bIm9uIit0eXBlXS5hcHBseSggZWxlbSwgZGF0YSApID09PSBmYWxzZSApCgkJCWV2ZW50LnJlc3VsdCA9IGZhbHNlOwoKCQkvLyBUcmlnZ2VyIHRoZSBuYXRpdmUgZXZlbnRzIChleGNlcHQgZm9yIGNsaWNrcyBvbiBsaW5rcykKCQlpZiAoICFidWJibGluZyAmJiBlbGVtW3R5cGVdICYmICFldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSAmJiAhKGpRdWVyeS5ub2RlTmFtZShlbGVtLCAnYScpICYmIHR5cGUgPT0gImNsaWNrIikgKSB7CgkJCXRoaXMudHJpZ2dlcmVkID0gdHJ1ZTsKCQkJdHJ5IHsKCQkJCWVsZW1bIHR5cGUgXSgpOwoJCQkvLyBwcmV2ZW50IElFIGZyb20gdGhyb3dpbmcgYW4gZXJyb3IgZm9yIHNvbWUgaGlkZGVuIGVsZW1lbnRzCgkJCX0gY2F0Y2ggKGUpIHt9CgkJfQoKCQl0aGlzLnRyaWdnZXJlZCA9IGZhbHNlOwoKCQlpZiAoICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkgewoJCQl2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlIHx8IGVsZW0ub3duZXJEb2N1bWVudDsKCQkJaWYgKCBwYXJlbnQgKQoJCQkJalF1ZXJ5LmV2ZW50LnRyaWdnZXIoZXZlbnQsIGRhdGEsIHBhcmVudCwgdHJ1ZSk7CgkJfQoJfSwKCgloYW5kbGU6IGZ1bmN0aW9uKGV2ZW50KSB7CgkJLy8gcmV0dXJuZWQgdW5kZWZpbmVkIG9yIGZhbHNlCgkJdmFyIGFsbCwgaGFuZGxlcnM7CgoJCWV2ZW50ID0gYXJndW1lbnRzWzBdID0galF1ZXJ5LmV2ZW50LmZpeCggZXZlbnQgfHwgd2luZG93LmV2ZW50ICk7CgkJZXZlbnQuY3VycmVudFRhcmdldCA9IHRoaXM7CgkJCgkJLy8gTmFtZXNwYWNlZCBldmVudCBoYW5kbGVycwoJCXZhciBuYW1lc3BhY2VzID0gZXZlbnQudHlwZS5zcGxpdCgiLiIpOwoJCWV2ZW50LnR5cGUgPSBuYW1lc3BhY2VzLnNoaWZ0KCk7CgoJCS8vIENhY2hlIHRoaXMgbm93LCBhbGwgPSB0cnVlIG1lYW5zLCBhbnkgaGFuZGxlcgoJCWFsbCA9ICFuYW1lc3BhY2VzLmxlbmd0aCAmJiAhZXZlbnQuZXhjbHVzaXZlOwoJCQoJCXZhciBuYW1lc3BhY2UgPSBSZWdFeHAoIihefFxcLikiICsgbmFtZXNwYWNlcy5zbGljZSgpLnNvcnQoKS5qb2luKCIuKlxcLiIpICsgIihcXC58JCkiKTsKCgkJaGFuZGxlcnMgPSAoIGpRdWVyeS5kYXRhKHRoaXMsICJldmVudHMiKSB8fCB7fSApW2V2ZW50LnR5cGVdOwoKCQlmb3IgKCB2YXIgaiBpbiBoYW5kbGVycyApIHsKCQkJdmFyIGhhbmRsZXIgPSBoYW5kbGVyc1tqXTsKCgkJCS8vIEZpbHRlciB0aGUgZnVuY3Rpb25zIGJ5IGNsYXNzCgkJCWlmICggYWxsIHx8IG5hbWVzcGFjZS50ZXN0KGhhbmRsZXIudHlwZSkgKSB7CgkJCQkvLyBQYXNzIGluIGEgcmVmZXJlbmNlIHRvIHRoZSBoYW5kbGVyIGZ1bmN0aW9uIGl0c2VsZgoJCQkJLy8gU28gdGhhdCB3ZSBjYW4gbGF0ZXIgcmVtb3ZlIGl0CgkJCQlldmVudC5oYW5kbGVyID0gaGFuZGxlcjsKCQkJCWV2ZW50LmRhdGEgPSBoYW5kbGVyLmRhdGE7CgoJCQkJdmFyIHJldCA9IGhhbmRsZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKCgkJCQlpZiggcmV0ICE9PSB1bmRlZmluZWQgKXsKCQkJCQlldmVudC5yZXN1bHQgPSByZXQ7CgkJCQkJaWYgKCByZXQgPT09IGZhbHNlICkgewoJCQkJCQlldmVudC5wcmV2ZW50RGVmYXVsdCgpOwoJCQkJCQlldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKCQkJCQl9CgkJCQl9CgoJCQkJaWYoIGV2ZW50LmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKCkgKQoJCQkJCWJyZWFrOwoKCQkJfQoJCX0KCX0sCgoJcHJvcHM6ICJhbHRLZXkgYXR0ckNoYW5nZSBhdHRyTmFtZSBidWJibGVzIGJ1dHRvbiBjYW5jZWxhYmxlIGNoYXJDb2RlIGNsaWVudFggY2xpZW50WSBjdHJsS2V5IGN1cnJlbnRUYXJnZXQgZGF0YSBkZXRhaWwgZXZlbnRQaGFzZSBmcm9tRWxlbWVudCBoYW5kbGVyIGtleUNvZGUgbWV0YUtleSBuZXdWYWx1ZSBvcmlnaW5hbFRhcmdldCBwYWdlWCBwYWdlWSBwcmV2VmFsdWUgcmVsYXRlZE5vZGUgcmVsYXRlZFRhcmdldCBzY3JlZW5YIHNjcmVlblkgc2hpZnRLZXkgc3JjRWxlbWVudCB0YXJnZXQgdG9FbGVtZW50IHZpZXcgd2hlZWxEZWx0YSB3aGljaCIuc3BsaXQoIiAiKSwKCglmaXg6IGZ1bmN0aW9uKGV2ZW50KSB7CgkJaWYgKCBldmVudFtleHBhbmRvXSApCgkJCXJldHVybiBldmVudDsKCgkJLy8gc3RvcmUgYSBjb3B5IG9mIHRoZSBvcmlnaW5hbCBldmVudCBvYmplY3QKCQkvLyBhbmQgImNsb25lIiB0byBzZXQgcmVhZC1vbmx5IHByb3BlcnRpZXMKCQl2YXIgb3JpZ2luYWxFdmVudCA9IGV2ZW50OwoJCWV2ZW50ID0galF1ZXJ5LkV2ZW50KCBvcmlnaW5hbEV2ZW50ICk7CgoJCWZvciAoIHZhciBpID0gdGhpcy5wcm9wcy5sZW5ndGgsIHByb3A7IGk7ICl7CgkJCXByb3AgPSB0aGlzLnByb3BzWyAtLWkgXTsKCQkJZXZlbnRbIHByb3AgXSA9IG9yaWdpbmFsRXZlbnRbIHByb3AgXTsKCQl9CgoJCS8vIEZpeCB0YXJnZXQgcHJvcGVydHksIGlmIG5lY2Vzc2FyeQoJCWlmICggIWV2ZW50LnRhcmdldCApCgkJCWV2ZW50LnRhcmdldCA9IGV2ZW50LnNyY0VsZW1lbnQgfHwgZG9jdW1lbnQ7IC8vIEZpeGVzICMxOTI1IHdoZXJlIHNyY0VsZW1lbnQgbWlnaHQgbm90IGJlIGRlZmluZWQgZWl0aGVyCgoJCS8vIGNoZWNrIGlmIHRhcmdldCBpcyBhIHRleHRub2RlIChzYWZhcmkpCgkJaWYgKCBldmVudC50YXJnZXQubm9kZVR5cGUgPT0gMyApCgkJCWV2ZW50LnRhcmdldCA9IGV2ZW50LnRhcmdldC5wYXJlbnROb2RlOwoKCQkvLyBBZGQgcmVsYXRlZFRhcmdldCwgaWYgbmVjZXNzYXJ5CgkJaWYgKCAhZXZlbnQucmVsYXRlZFRhcmdldCAmJiBldmVudC5mcm9tRWxlbWVudCApCgkJCWV2ZW50LnJlbGF0ZWRUYXJnZXQgPSBldmVudC5mcm9tRWxlbWVudCA9PSBldmVudC50YXJnZXQgPyBldmVudC50b0VsZW1lbnQgOiBldmVudC5mcm9tRWxlbWVudDsKCgkJLy8gQ2FsY3VsYXRlIHBhZ2VYL1kgaWYgbWlzc2luZyBhbmQgY2xpZW50WC9ZIGF2YWlsYWJsZQoJCWlmICggZXZlbnQucGFnZVggPT0gbnVsbCAmJiBldmVudC5jbGllbnRYICE9IG51bGwgKSB7CgkJCXZhciBkb2MgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIGJvZHkgPSBkb2N1bWVudC5ib2R5OwoJCQlldmVudC5wYWdlWCA9IGV2ZW50LmNsaWVudFggKyAoZG9jICYmIGRvYy5zY3JvbGxMZWZ0IHx8IGJvZHkgJiYgYm9keS5zY3JvbGxMZWZ0IHx8IDApIC0gKGRvYy5jbGllbnRMZWZ0IHx8IDApOwoJCQlldmVudC5wYWdlWSA9IGV2ZW50LmNsaWVudFkgKyAoZG9jICYmIGRvYy5zY3JvbGxUb3AgfHwgYm9keSAmJiBib2R5LnNjcm9sbFRvcCB8fCAwKSAtIChkb2MuY2xpZW50VG9wIHx8IDApOwoJCX0KCgkJLy8gQWRkIHdoaWNoIGZvciBrZXkgZXZlbnRzCgkJaWYgKCAhZXZlbnQud2hpY2ggJiYgKChldmVudC5jaGFyQ29kZSB8fCBldmVudC5jaGFyQ29kZSA9PT0gMCkgPyBldmVudC5jaGFyQ29kZSA6IGV2ZW50LmtleUNvZGUpICkKCQkJZXZlbnQud2hpY2ggPSBldmVudC5jaGFyQ29kZSB8fCBldmVudC5rZXlDb2RlOwoKCQkvLyBBZGQgbWV0YUtleSB0byBub24tTWFjIGJyb3dzZXJzICh1c2UgY3RybCBmb3IgUEMncyBhbmQgTWV0YSBmb3IgTWFjcykKCQlpZiAoICFldmVudC5tZXRhS2V5ICYmIGV2ZW50LmN0cmxLZXkgKQoJCQlldmVudC5tZXRhS2V5ID0gZXZlbnQuY3RybEtleTsKCgkJLy8gQWRkIHdoaWNoIGZvciBjbGljazogMSA9PSBsZWZ0OyAyID09IG1pZGRsZTsgMyA9PSByaWdodAoJCS8vIE5vdGU6IGJ1dHRvbiBpcyBub3Qgbm9ybWFsaXplZCwgc28gZG9uJ3QgdXNlIGl0CgkJaWYgKCAhZXZlbnQud2hpY2ggJiYgZXZlbnQuYnV0dG9uICkKCQkJZXZlbnQud2hpY2ggPSAoZXZlbnQuYnV0dG9uICYgMSA/IDEgOiAoIGV2ZW50LmJ1dHRvbiAmIDIgPyAzIDogKCBldmVudC5idXR0b24gJiA0ID8gMiA6IDAgKSApKTsKCgkJcmV0dXJuIGV2ZW50OwoJfSwKCglwcm94eTogZnVuY3Rpb24oIGZuLCBwcm94eSApewoJCXByb3h5ID0gcHJveHkgfHwgZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7IH07CgkJLy8gU2V0IHRoZSBndWlkIG9mIHVuaXF1ZSBoYW5kbGVyIHRvIHRoZSBzYW1lIG9mIG9yaWdpbmFsIGhhbmRsZXIsIHNvIGl0IGNhbiBiZSByZW1vdmVkCgkJcHJveHkuZ3VpZCA9IGZuLmd1aWQgPSBmbi5ndWlkIHx8IHByb3h5Lmd1aWQgfHwgdGhpcy5ndWlkKys7CgkJLy8gU28gcHJveHkgY2FuIGJlIGRlY2xhcmVkIGFzIGFuIGFyZ3VtZW50CgkJcmV0dXJuIHByb3h5OwoJfSwKCglzcGVjaWFsOiB7CgkJcmVhZHk6IHsKCQkJLy8gTWFrZSBzdXJlIHRoZSByZWFkeSBldmVudCBpcyBzZXR1cAoJCQlzZXR1cDogYmluZFJlYWR5LAoJCQl0ZWFyZG93bjogZnVuY3Rpb24oKSB7fQoJCX0KCX0sCgkKCXNwZWNpYWxBbGw6IHsKCQlsaXZlOiB7CgkJCXNldHVwOiBmdW5jdGlvbiggc2VsZWN0b3IsIG5hbWVzcGFjZXMgKXsKCQkJCWpRdWVyeS5ldmVudC5hZGQoIHRoaXMsIG5hbWVzcGFjZXNbMF0sIGxpdmVIYW5kbGVyICk7CgkJCX0sCgkJCXRlYXJkb3duOiAgZnVuY3Rpb24oIG5hbWVzcGFjZXMgKXsKCQkJCWlmICggbmFtZXNwYWNlcy5sZW5ndGggKSB7CgkJCQkJdmFyIHJlbW92ZSA9IDAsIG5hbWUgPSBSZWdFeHAoIihefFxcLikiICsgbmFtZXNwYWNlc1swXSArICIoXFwufCQpIik7CgkJCQkJCgkJCQkJalF1ZXJ5LmVhY2goIChqUXVlcnkuZGF0YSh0aGlzLCAiZXZlbnRzIikubGl2ZSB8fCB7fSksIGZ1bmN0aW9uKCl7CgkJCQkJCWlmICggbmFtZS50ZXN0KHRoaXMudHlwZSkgKQoJCQkJCQkJcmVtb3ZlKys7CgkJCQkJfSk7CgkJCQkJCgkJCQkJaWYgKCByZW1vdmUgPCAxICkKCQkJCQkJalF1ZXJ5LmV2ZW50LnJlbW92ZSggdGhpcywgbmFtZXNwYWNlc1swXSwgbGl2ZUhhbmRsZXIgKTsKCQkJCX0KCQkJfQoJCX0KCX0KfTsKCmpRdWVyeS5FdmVudCA9IGZ1bmN0aW9uKCBzcmMgKXsKCS8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCB0aGUgJ25ldycga2V5d29yZAoJaWYoICF0aGlzLnByZXZlbnREZWZhdWx0ICkKCQlyZXR1cm4gbmV3IGpRdWVyeS5FdmVudChzcmMpOwoJCgkvLyBFdmVudCBvYmplY3QKCWlmKCBzcmMgJiYgc3JjLnR5cGUgKXsKCQl0aGlzLm9yaWdpbmFsRXZlbnQgPSBzcmM7CgkJdGhpcy50eXBlID0gc3JjLnR5cGU7CgkvLyBFdmVudCB0eXBlCgl9ZWxzZQoJCXRoaXMudHlwZSA9IHNyYzsKCgkvLyB0aW1lU3RhbXAgaXMgYnVnZ3kgZm9yIHNvbWUgZXZlbnRzIG9uIEZpcmVmb3goIzM4NDMpCgkvLyBTbyB3ZSB3b24ndCByZWx5IG9uIHRoZSBuYXRpdmUgdmFsdWUKCXRoaXMudGltZVN0YW1wID0gbm93KCk7CgkKCS8vIE1hcmsgaXQgYXMgZml4ZWQKCXRoaXNbZXhwYW5kb10gPSB0cnVlOwp9OwoKZnVuY3Rpb24gcmV0dXJuRmFsc2UoKXsKCXJldHVybiBmYWxzZTsKfQpmdW5jdGlvbiByZXR1cm5UcnVlKCl7CglyZXR1cm4gdHJ1ZTsKfQoKLy8galF1ZXJ5LkV2ZW50IGlzIGJhc2VkIG9uIERPTTMgRXZlbnRzIGFzIHNwZWNpZmllZCBieSB0aGUgRUNNQVNjcmlwdCBMYW5ndWFnZSBCaW5kaW5nCi8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMDMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMDMwMzMxL2VjbWEtc2NyaXB0LWJpbmRpbmcuaHRtbApqUXVlcnkuRXZlbnQucHJvdG90eXBlID0gewoJcHJldmVudERlZmF1bHQ6IGZ1bmN0aW9uKCkgewoJCXRoaXMuaXNEZWZhdWx0UHJldmVudGVkID0gcmV0dXJuVHJ1ZTsKCgkJdmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7CgkJaWYoICFlICkKCQkJcmV0dXJuOwoJCS8vIGlmIHByZXZlbnREZWZhdWx0IGV4aXN0cyBydW4gaXQgb24gdGhlIG9yaWdpbmFsIGV2ZW50CgkJaWYgKGUucHJldmVudERlZmF1bHQpCgkJCWUucHJldmVudERlZmF1bHQoKTsKCQkvLyBvdGhlcndpc2Ugc2V0IHRoZSByZXR1cm5WYWx1ZSBwcm9wZXJ0eSBvZiB0aGUgb3JpZ2luYWwgZXZlbnQgdG8gZmFsc2UgKElFKQoJCWUucmV0dXJuVmFsdWUgPSBmYWxzZTsKCX0sCglzdG9wUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkgewoJCXRoaXMuaXNQcm9wYWdhdGlvblN0b3BwZWQgPSByZXR1cm5UcnVlOwoKCQl2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDsKCQlpZiggIWUgKQoJCQlyZXR1cm47CgkJLy8gaWYgc3RvcFByb3BhZ2F0aW9uIGV4aXN0cyBydW4gaXQgb24gdGhlIG9yaWdpbmFsIGV2ZW50CgkJaWYgKGUuc3RvcFByb3BhZ2F0aW9uKQoJCQllLnN0b3BQcm9wYWdhdGlvbigpOwoJCS8vIG90aGVyd2lzZSBzZXQgdGhlIGNhbmNlbEJ1YmJsZSBwcm9wZXJ0eSBvZiB0aGUgb3JpZ2luYWwgZXZlbnQgdG8gdHJ1ZSAoSUUpCgkJZS5jYW5jZWxCdWJibGUgPSB0cnVlOwoJfSwKCXN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbjpmdW5jdGlvbigpewoJCXRoaXMuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSByZXR1cm5UcnVlOwoJCXRoaXMuc3RvcFByb3BhZ2F0aW9uKCk7Cgl9LAoJaXNEZWZhdWx0UHJldmVudGVkOiByZXR1cm5GYWxzZSwKCWlzUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZSwKCWlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZQp9OwovLyBDaGVja3MgaWYgYW4gZXZlbnQgaGFwcGVuZWQgb24gYW4gZWxlbWVudCB3aXRoaW4gYW5vdGhlciBlbGVtZW50Ci8vIFVzZWQgaW4galF1ZXJ5LmV2ZW50LnNwZWNpYWwubW91c2VlbnRlciBhbmQgbW91c2VsZWF2ZSBoYW5kbGVycwp2YXIgd2l0aGluRWxlbWVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7CgkvLyBDaGVjayBpZiBtb3VzZShvdmVyfG91dCkgYXJlIHN0aWxsIHdpdGhpbiB0aGUgc2FtZSBwYXJlbnQgZWxlbWVudAoJdmFyIHBhcmVudCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQ7CgkvLyBUcmF2ZXJzZSB1cCB0aGUgdHJlZQoJd2hpbGUgKCBwYXJlbnQgJiYgcGFyZW50ICE9IHRoaXMgKQoJCXRyeSB7IHBhcmVudCA9IHBhcmVudC5wYXJlbnROb2RlOyB9CgkJY2F0Y2goZSkgeyBwYXJlbnQgPSB0aGlzOyB9CgkKCWlmKCBwYXJlbnQgIT0gdGhpcyApewoJCS8vIHNldCB0aGUgY29ycmVjdCBldmVudCB0eXBlCgkJZXZlbnQudHlwZSA9IGV2ZW50LmRhdGE7CgkJLy8gaGFuZGxlIGV2ZW50IGlmIHdlIGFjdHVhbGx5IGp1c3QgbW91c2VkIG9uIHRvIGEgbm9uIHN1Yi1lbGVtZW50CgkJalF1ZXJ5LmV2ZW50LmhhbmRsZS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7Cgl9Cn07CgkKalF1ZXJ5LmVhY2goeyAKCW1vdXNlb3ZlcjogJ21vdXNlZW50ZXInLCAKCW1vdXNlb3V0OiAnbW91c2VsZWF2ZScKfSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApewoJalF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGZpeCBdID0gewoJCXNldHVwOiBmdW5jdGlvbigpewoJCQlqUXVlcnkuZXZlbnQuYWRkKCB0aGlzLCBvcmlnLCB3aXRoaW5FbGVtZW50LCBmaXggKTsKCQl9LAoJCXRlYXJkb3duOiBmdW5jdGlvbigpewoJCQlqUXVlcnkuZXZlbnQucmVtb3ZlKCB0aGlzLCBvcmlnLCB3aXRoaW5FbGVtZW50ICk7CgkJfQoJfTsJCQkgICAKfSk7CgpqUXVlcnkuZm4uZXh0ZW5kKHsKCWJpbmQ6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhLCBmbiApIHsKCQlyZXR1cm4gdHlwZSA9PSAidW5sb2FkIiA/IHRoaXMub25lKHR5cGUsIGRhdGEsIGZuKSA6IHRoaXMuZWFjaChmdW5jdGlvbigpewoJCQlqUXVlcnkuZXZlbnQuYWRkKCB0aGlzLCB0eXBlLCBmbiB8fCBkYXRhLCBmbiAmJiBkYXRhICk7CgkJfSk7Cgl9LAoKCW9uZTogZnVuY3Rpb24oIHR5cGUsIGRhdGEsIGZuICkgewoJCXZhciBvbmUgPSBqUXVlcnkuZXZlbnQucHJveHkoIGZuIHx8IGRhdGEsIGZ1bmN0aW9uKGV2ZW50KSB7CgkJCWpRdWVyeSh0aGlzKS51bmJpbmQoZXZlbnQsIG9uZSk7CgkJCXJldHVybiAoZm4gfHwgZGF0YSkuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApOwoJCX0pOwoJCXJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXsKCQkJalF1ZXJ5LmV2ZW50LmFkZCggdGhpcywgdHlwZSwgb25lLCBmbiAmJiBkYXRhKTsKCQl9KTsKCX0sCgoJdW5iaW5kOiBmdW5jdGlvbiggdHlwZSwgZm4gKSB7CgkJcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpewoJCQlqUXVlcnkuZXZlbnQucmVtb3ZlKCB0aGlzLCB0eXBlLCBmbiApOwoJCX0pOwoJfSwKCgl0cmlnZ2VyOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHsKCQlyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7CgkJCWpRdWVyeS5ldmVudC50cmlnZ2VyKCB0eXBlLCBkYXRhLCB0aGlzICk7CgkJfSk7Cgl9LAoKCXRyaWdnZXJIYW5kbGVyOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHsKCQlpZiggdGhpc1swXSApewoJCQl2YXIgZXZlbnQgPSBqUXVlcnkuRXZlbnQodHlwZSk7CgkJCWV2ZW50LnByZXZlbnREZWZhdWx0KCk7CgkJCWV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwoJCQlqUXVlcnkuZXZlbnQudHJpZ2dlciggZXZlbnQsIGRhdGEsIHRoaXNbMF0gKTsKCQkJcmV0dXJuIGV2ZW50LnJlc3VsdDsKCQl9CQkKCX0sCgoJdG9nZ2xlOiBmdW5jdGlvbiggZm4gKSB7CgkJLy8gU2F2ZSByZWZlcmVuY2UgdG8gYXJndW1lbnRzIGZvciBhY2Nlc3MgaW4gY2xvc3VyZQoJCXZhciBhcmdzID0gYXJndW1lbnRzLCBpID0gMTsKCgkJLy8gbGluayBhbGwgdGhlIGZ1bmN0aW9ucywgc28gYW55IG9mIHRoZW0gY2FuIHVuYmluZCB0aGlzIGNsaWNrIGhhbmRsZXIKCQl3aGlsZSggaSA8IGFyZ3MubGVuZ3RoICkKCQkJalF1ZXJ5LmV2ZW50LnByb3h5KCBmbiwgYXJnc1tpKytdICk7CgoJCXJldHVybiB0aGlzLmNsaWNrKCBqUXVlcnkuZXZlbnQucHJveHkoIGZuLCBmdW5jdGlvbihldmVudCkgewoJCQkvLyBGaWd1cmUgb3V0IHdoaWNoIGZ1bmN0aW9uIHRvIGV4ZWN1dGUKCQkJdGhpcy5sYXN0VG9nZ2xlID0gKCB0aGlzLmxhc3RUb2dnbGUgfHwgMCApICUgaTsKCgkJCS8vIE1ha2Ugc3VyZSB0aGF0IGNsaWNrcyBzdG9wCgkJCWV2ZW50LnByZXZlbnREZWZhdWx0KCk7CgoJCQkvLyBhbmQgZXhlY3V0ZSB0aGUgZnVuY3Rpb24KCQkJcmV0dXJuIGFyZ3NbIHRoaXMubGFzdFRvZ2dsZSsrIF0uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApIHx8IGZhbHNlOwoJCX0pKTsKCX0sCgoJaG92ZXI6IGZ1bmN0aW9uKGZuT3ZlciwgZm5PdXQpIHsKCQlyZXR1cm4gdGhpcy5tb3VzZWVudGVyKGZuT3ZlcikubW91c2VsZWF2ZShmbk91dCk7Cgl9LAoKCXJlYWR5OiBmdW5jdGlvbihmbikgewoJCS8vIEF0dGFjaCB0aGUgbGlzdGVuZXJzCgkJYmluZFJlYWR5KCk7CgoJCS8vIElmIHRoZSBET00gaXMgYWxyZWFkeSByZWFkeQoJCWlmICggalF1ZXJ5LmlzUmVhZHkgKQoJCQkvLyBFeGVjdXRlIHRoZSBmdW5jdGlvbiBpbW1lZGlhdGVseQoJCQlmbi5jYWxsKCBkb2N1bWVudCwgalF1ZXJ5ICk7CgoJCS8vIE90aGVyd2lzZSwgcmVtZW1iZXIgdGhlIGZ1bmN0aW9uIGZvciBsYXRlcgoJCWVsc2UKCQkJLy8gQWRkIHRoZSBmdW5jdGlvbiB0byB0aGUgd2FpdCBsaXN0CgkJCWpRdWVyeS5yZWFkeUxpc3QucHVzaCggZm4gKTsKCgkJcmV0dXJuIHRoaXM7Cgl9LAoJCglsaXZlOiBmdW5jdGlvbiggdHlwZSwgZm4gKXsKCQl2YXIgcHJveHkgPSBqUXVlcnkuZXZlbnQucHJveHkoIGZuICk7CgkJcHJveHkuZ3VpZCArPSB0aGlzLnNlbGVjdG9yICsgdHlwZTsKCgkJalF1ZXJ5KGRvY3VtZW50KS5iaW5kKCBsaXZlQ29udmVydCh0eXBlLCB0aGlzLnNlbGVjdG9yKSwgdGhpcy5zZWxlY3RvciwgcHJveHkgKTsKCgkJcmV0dXJuIHRoaXM7Cgl9LAoJCglkaWU6IGZ1bmN0aW9uKCB0eXBlLCBmbiApewoJCWpRdWVyeShkb2N1bWVudCkudW5iaW5kKCBsaXZlQ29udmVydCh0eXBlLCB0aGlzLnNlbGVjdG9yKSwgZm4gPyB7IGd1aWQ6IGZuLmd1aWQgKyB0aGlzLnNlbGVjdG9yICsgdHlwZSB9IDogbnVsbCApOwoJCXJldHVybiB0aGlzOwoJfQp9KTsKCmZ1bmN0aW9uIGxpdmVIYW5kbGVyKCBldmVudCApewoJdmFyIGNoZWNrID0gUmVnRXhwKCIoXnxcXC4pIiArIGV2ZW50LnR5cGUgKyAiKFxcLnwkKSIpLAoJCXN0b3AgPSB0cnVlLAoJCWVsZW1zID0gW107CgoJalF1ZXJ5LmVhY2goalF1ZXJ5LmRhdGEodGhpcywgImV2ZW50cyIpLmxpdmUgfHwgW10sIGZ1bmN0aW9uKGksIGZuKXsKCQlpZiAoIGNoZWNrLnRlc3QoZm4udHlwZSkgKSB7CgkJCXZhciBlbGVtID0galF1ZXJ5KGV2ZW50LnRhcmdldCkuY2xvc2VzdChmbi5kYXRhKVswXTsKCQkJaWYgKCBlbGVtICkKCQkJCWVsZW1zLnB1c2goeyBlbGVtOiBlbGVtLCBmbjogZm4gfSk7CgkJfQoJfSk7CgoJZWxlbXMuc29ydChmdW5jdGlvbihhLGIpIHsKCQlyZXR1cm4galF1ZXJ5LmRhdGEoYS5lbGVtLCAiY2xvc2VzdCIpIC0galF1ZXJ5LmRhdGEoYi5lbGVtLCAiY2xvc2VzdCIpOwoJfSk7CgkKCWpRdWVyeS5lYWNoKGVsZW1zLCBmdW5jdGlvbigpewoJCWlmICggdGhpcy5mbi5jYWxsKHRoaXMuZWxlbSwgZXZlbnQsIHRoaXMuZm4uZGF0YSkgPT09IGZhbHNlICkKCQkJcmV0dXJuIChzdG9wID0gZmFsc2UpOwoJfSk7CgoJcmV0dXJuIHN0b3A7Cn0KCmZ1bmN0aW9uIGxpdmVDb252ZXJ0KHR5cGUsIHNlbGVjdG9yKXsKCXJldHVybiBbImxpdmUiLCB0eXBlLCBzZWxlY3Rvci5yZXBsYWNlKC9cLi9nLCAiYCIpLnJlcGxhY2UoLyAvZywgInwiKV0uam9pbigiLiIpOwp9CgpqUXVlcnkuZXh0ZW5kKHsKCWlzUmVhZHk6IGZhbHNlLAoJcmVhZHlMaXN0OiBbXSwKCS8vIEhhbmRsZSB3aGVuIHRoZSBET00gaXMgcmVhZHkKCXJlYWR5OiBmdW5jdGlvbigpIHsKCQkvLyBNYWtlIHN1cmUgdGhhdCB0aGUgRE9NIGlzIG5vdCBhbHJlYWR5IGxvYWRlZAoJCWlmICggIWpRdWVyeS5pc1JlYWR5ICkgewoJCQkvLyBSZW1lbWJlciB0aGF0IHRoZSBET00gaXMgcmVhZHkKCQkJalF1ZXJ5LmlzUmVhZHkgPSB0cnVlOwoKCQkJLy8gSWYgdGhlcmUgYXJlIGZ1bmN0aW9ucyBib3VuZCwgdG8gZXhlY3V0ZQoJCQlpZiAoIGpRdWVyeS5yZWFkeUxpc3QgKSB7CgkJCQkvLyBFeGVjdXRlIGFsbCBvZiB0aGVtCgkJCQlqUXVlcnkuZWFjaCggalF1ZXJ5LnJlYWR5TGlzdCwgZnVuY3Rpb24oKXsKCQkJCQl0aGlzLmNhbGwoIGRvY3VtZW50LCBqUXVlcnkgKTsKCQkJCX0pOwoKCQkJCS8vIFJlc2V0IHRoZSBsaXN0IG9mIGZ1bmN0aW9ucwoJCQkJalF1ZXJ5LnJlYWR5TGlzdCA9IG51bGw7CgkJCX0KCgkJCS8vIFRyaWdnZXIgYW55IGJvdW5kIHJlYWR5IGV2ZW50cwoJCQlqUXVlcnkoZG9jdW1lbnQpLnRyaWdnZXJIYW5kbGVyKCJyZWFkeSIpOwoJCX0KCX0KfSk7Cgp2YXIgcmVhZHlCb3VuZCA9IGZhbHNlOwoKZnVuY3Rpb24gYmluZFJlYWR5KCl7CglpZiAoIHJlYWR5Qm91bmQgKSByZXR1cm47CglyZWFkeUJvdW5kID0gdHJ1ZTsKCgkvLyBNb3ppbGxhLCBPcGVyYSBhbmQgd2Via2l0IG5pZ2h0bGllcyBjdXJyZW50bHkgc3VwcG9ydCB0aGlzIGV2ZW50CglpZiAoIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIgKSB7CgkJLy8gVXNlIHRoZSBoYW5keSBldmVudCBjYWxsYmFjawoJCWRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoICJET01Db250ZW50TG9hZGVkIiwgZnVuY3Rpb24oKXsKCQkJZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggIkRPTUNvbnRlbnRMb2FkZWQiLCBhcmd1bWVudHMuY2FsbGVlLCBmYWxzZSApOwoJCQlqUXVlcnkucmVhZHkoKTsKCQl9LCBmYWxzZSApOwoKCS8vIElmIElFIGV2ZW50IG1vZGVsIGlzIHVzZWQKCX0gZWxzZSBpZiAoIGRvY3VtZW50LmF0dGFjaEV2ZW50ICkgewoJCS8vIGVuc3VyZSBmaXJpbmcgYmVmb3JlIG9ubG9hZCwKCQkvLyBtYXliZSBsYXRlIGJ1dCBzYWZlIGFsc28gZm9yIGlmcmFtZXMKCQlkb2N1bWVudC5hdHRhY2hFdmVudCgib25yZWFkeXN0YXRlY2hhbmdlIiwgZnVuY3Rpb24oKXsKCQkJaWYgKCBkb2N1bWVudC5yZWFkeVN0YXRlID09PSAiY29tcGxldGUiICkgewoJCQkJZG9jdW1lbnQuZGV0YWNoRXZlbnQoICJvbnJlYWR5c3RhdGVjaGFuZ2UiLCBhcmd1bWVudHMuY2FsbGVlICk7CgkJCQlqUXVlcnkucmVhZHkoKTsKCQkJfQoJCX0pOwoKCQkvLyBJZiBJRSBhbmQgbm90IGFuIGlmcmFtZQoJCS8vIGNvbnRpbnVhbGx5IGNoZWNrIHRvIHNlZSBpZiB0aGUgZG9jdW1lbnQgaXMgcmVhZHkKCQlpZiAoIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5kb1Njcm9sbCAmJiB3aW5kb3cgPT0gd2luZG93LnRvcCApIChmdW5jdGlvbigpewoJCQlpZiAoIGpRdWVyeS5pc1JlYWR5ICkgcmV0dXJuOwoKCQkJdHJ5IHsKCQkJCS8vIElmIElFIGlzIHVzZWQsIHVzZSB0aGUgdHJpY2sgYnkgRGllZ28gUGVyaW5pCgkJCQkvLyBodHRwOi8vamF2YXNjcmlwdC5ud2JveC5jb20vSUVDb250ZW50TG9hZGVkLwoJCQkJZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmRvU2Nyb2xsKCJsZWZ0Iik7CgkJCX0gY2F0Y2goIGVycm9yICkgewoJCQkJc2V0VGltZW91dCggYXJndW1lbnRzLmNhbGxlZSwgMCApOwoJCQkJcmV0dXJuOwoJCQl9CgoJCQkvLyBhbmQgZXhlY3V0ZSBhbnkgd2FpdGluZyBmdW5jdGlvbnMKCQkJalF1ZXJ5LnJlYWR5KCk7CgkJfSkoKTsKCX0KCgkvLyBBIGZhbGxiYWNrIHRvIHdpbmRvdy5vbmxvYWQsIHRoYXQgd2lsbCBhbHdheXMgd29yawoJalF1ZXJ5LmV2ZW50LmFkZCggd2luZG93LCAibG9hZCIsIGpRdWVyeS5yZWFkeSApOwp9CgpqUXVlcnkuZWFjaCggKCJibHVyLGZvY3VzLGxvYWQscmVzaXplLHNjcm9sbCx1bmxvYWQsY2xpY2ssZGJsY2xpY2ssIiArCgkibW91c2Vkb3duLG1vdXNldXAsbW91c2Vtb3ZlLG1vdXNlb3Zlcixtb3VzZW91dCxtb3VzZWVudGVyLG1vdXNlbGVhdmUsIiArCgkiY2hhbmdlLHNlbGVjdCxzdWJtaXQsa2V5ZG93bixrZXlwcmVzcyxrZXl1cCxlcnJvciIpLnNwbGl0KCIsIiksIGZ1bmN0aW9uKGksIG5hbWUpewoKCS8vIEhhbmRsZSBldmVudCBiaW5kaW5nCglqUXVlcnkuZm5bbmFtZV0gPSBmdW5jdGlvbihmbil7CgkJcmV0dXJuIGZuID8gdGhpcy5iaW5kKG5hbWUsIGZuKSA6IHRoaXMudHJpZ2dlcihuYW1lKTsKCX07Cn0pOwoKLy8gUHJldmVudCBtZW1vcnkgbGVha3MgaW4gSUUKLy8gQW5kIHByZXZlbnQgZXJyb3JzIG9uIHJlZnJlc2ggd2l0aCBldmVudHMgbGlrZSBtb3VzZW92ZXIgaW4gb3RoZXIgYnJvd3NlcnMKLy8gV2luZG93IGlzbid0IGluY2x1ZGVkIHNvIGFzIG5vdCB0byB1bmJpbmQgZXhpc3RpbmcgdW5sb2FkIGV2ZW50cwpqUXVlcnkoIHdpbmRvdyApLmJpbmQoICd1bmxvYWQnLCBmdW5jdGlvbigpeyAKCWZvciAoIHZhciBpZCBpbiBqUXVlcnkuY2FjaGUgKQoJCS8vIFNraXAgdGhlIHdpbmRvdwoJCWlmICggaWQgIT0gMSAmJiBqUXVlcnkuY2FjaGVbIGlkIF0uaGFuZGxlICkKCQkJalF1ZXJ5LmV2ZW50LnJlbW92ZSggalF1ZXJ5LmNhY2hlWyBpZCBdLmhhbmRsZS5lbGVtICk7Cn0pOyAKKGZ1bmN0aW9uKCl7CgoJalF1ZXJ5LnN1cHBvcnQgPSB7fTsKCgl2YXIgcm9vdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwKCQlzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJzY3JpcHQiKSwKCQlkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKSwKCQlpZCA9ICJzY3JpcHQiICsgKG5ldyBEYXRlKS5nZXRUaW1lKCk7CgoJZGl2LnN0eWxlLmRpc3BsYXkgPSAibm9uZSI7CglkaXYuaW5uZXJIVE1MID0gJyAgIDxsaW5rLz48dGFibGU+PC90YWJsZT48YSBocmVmPSIvYSIgc3R5bGU9ImNvbG9yOnJlZDtmbG9hdDpsZWZ0O29wYWNpdHk6LjU7Ij5hPC9hPjxzZWxlY3Q+PG9wdGlvbj50ZXh0PC9vcHRpb24+PC9zZWxlY3Q+PG9iamVjdD48cGFyYW0vPjwvb2JqZWN0Pic7CgoJdmFyIGFsbCA9IGRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZSgiKiIpLAoJCWEgPSBkaXYuZ2V0RWxlbWVudHNCeVRhZ05hbWUoImEiKVswXTsKCgkvLyBDYW4ndCBnZXQgYmFzaWMgdGVzdCBzdXBwb3J0CglpZiAoICFhbGwgfHwgIWFsbC5sZW5ndGggfHwgIWEgKSB7CgkJcmV0dXJuOwoJfQoKCWpRdWVyeS5zdXBwb3J0ID0gewoJCS8vIElFIHN0cmlwcyBsZWFkaW5nIHdoaXRlc3BhY2Ugd2hlbiAuaW5uZXJIVE1MIGlzIHVzZWQKCQlsZWFkaW5nV2hpdGVzcGFjZTogZGl2LmZpcnN0Q2hpbGQubm9kZVR5cGUgPT0gMywKCQkKCQkvLyBNYWtlIHN1cmUgdGhhdCB0Ym9keSBlbGVtZW50cyBhcmVuJ3QgYXV0b21hdGljYWxseSBpbnNlcnRlZAoJCS8vIElFIHdpbGwgaW5zZXJ0IHRoZW0gaW50byBlbXB0eSB0YWJsZXMKCQl0Ym9keTogIWRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZSgidGJvZHkiKS5sZW5ndGgsCgkJCgkJLy8gTWFrZSBzdXJlIHRoYXQgeW91IGNhbiBnZXQgYWxsIGVsZW1lbnRzIGluIGFuIDxvYmplY3Q+IGVsZW1lbnQKCQkvLyBJRSA3IGFsd2F5cyByZXR1cm5zIG5vIHJlc3VsdHMKCQlvYmplY3RBbGw6ICEhZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJvYmplY3QiKVswXQoJCQkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIioiKS5sZW5ndGgsCgkJCgkJLy8gTWFrZSBzdXJlIHRoYXQgbGluayBlbGVtZW50cyBnZXQgc2VyaWFsaXplZCBjb3JyZWN0bHkgYnkgaW5uZXJIVE1MCgkJLy8gVGhpcyByZXF1aXJlcyBhIHdyYXBwZXIgZWxlbWVudCBpbiBJRQoJCWh0bWxTZXJpYWxpemU6ICEhZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKCJsaW5rIikubGVuZ3RoLAoJCQoJCS8vIEdldCB0aGUgc3R5bGUgaW5mb3JtYXRpb24gZnJvbSBnZXRBdHRyaWJ1dGUKCQkvLyAoSUUgdXNlcyAuY3NzVGV4dCBpbnN0ZWQpCgkJc3R5bGU6IC9yZWQvLnRlc3QoIGEuZ2V0QXR0cmlidXRlKCJzdHlsZSIpICksCgkJCgkJLy8gTWFrZSBzdXJlIHRoYXQgVVJMcyBhcmVuJ3QgbWFuaXB1bGF0ZWQKCQkvLyAoSUUgbm9ybWFsaXplcyBpdCBieSBkZWZhdWx0KQoJCWhyZWZOb3JtYWxpemVkOiBhLmdldEF0dHJpYnV0ZSgiaHJlZiIpID09PSAiL2EiLAoJCQoJCS8vIE1ha2Ugc3VyZSB0aGF0IGVsZW1lbnQgb3BhY2l0eSBleGlzdHMKCQkvLyAoSUUgdXNlcyBmaWx0ZXIgaW5zdGVhZCkKCQlvcGFjaXR5OiBhLnN0eWxlLm9wYWNpdHkgPT09ICIwLjUiLAoJCQoJCS8vIFZlcmlmeSBzdHlsZSBmbG9hdCBleGlzdGVuY2UKCQkvLyAoSUUgdXNlcyBzdHlsZUZsb2F0IGluc3RlYWQgb2YgY3NzRmxvYXQpCgkJY3NzRmxvYXQ6ICEhYS5zdHlsZS5jc3NGbG9hdCwKCgkJLy8gV2lsbCBiZSBkZWZpbmVkIGxhdGVyCgkJc2NyaXB0RXZhbDogZmFsc2UsCgkJbm9DbG9uZUV2ZW50OiB0cnVlLAoJCWJveE1vZGVsOiBudWxsCgl9OwoJCglzY3JpcHQudHlwZSA9ICJ0ZXh0L2phdmFzY3JpcHQiOwoJdHJ5IHsKCQlzY3JpcHQuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCAid2luZG93LiIgKyBpZCArICI9MTsiICkgKTsKCX0gY2F0Y2goZSl7fQoKCXJvb3QuaW5zZXJ0QmVmb3JlKCBzY3JpcHQsIHJvb3QuZmlyc3RDaGlsZCApOwoJCgkvLyBNYWtlIHN1cmUgdGhhdCB0aGUgZXhlY3V0aW9uIG9mIGNvZGUgd29ya3MgYnkgaW5qZWN0aW5nIGEgc2NyaXB0CgkvLyB0YWcgd2l0aCBhcHBlbmRDaGlsZC9jcmVhdGVUZXh0Tm9kZQoJLy8gKElFIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzLCBmYWlscywgYW5kIHVzZXMgLnRleHQgaW5zdGVhZCkKCWlmICggd2luZG93WyBpZCBdICkgewoJCWpRdWVyeS5zdXBwb3J0LnNjcmlwdEV2YWwgPSB0cnVlOwoJCWRlbGV0ZSB3aW5kb3dbIGlkIF07Cgl9CgoJcm9vdC5yZW1vdmVDaGlsZCggc2NyaXB0ICk7CgoJaWYgKCBkaXYuYXR0YWNoRXZlbnQgJiYgZGl2LmZpcmVFdmVudCApIHsKCQlkaXYuYXR0YWNoRXZlbnQoIm9uY2xpY2siLCBmdW5jdGlvbigpewoJCQkvLyBDbG9uaW5nIGEgbm9kZSBzaG91bGRuJ3QgY29weSBvdmVyIGFueQoJCQkvLyBib3VuZCBldmVudCBoYW5kbGVycyAoSUUgZG9lcyB0aGlzKQoJCQlqUXVlcnkuc3VwcG9ydC5ub0Nsb25lRXZlbnQgPSBmYWxzZTsKCQkJZGl2LmRldGFjaEV2ZW50KCJvbmNsaWNrIiwgYXJndW1lbnRzLmNhbGxlZSk7CgkJfSk7CgkJZGl2LmNsb25lTm9kZSh0cnVlKS5maXJlRXZlbnQoIm9uY2xpY2siKTsKCX0KCgkvLyBGaWd1cmUgb3V0IGlmIHRoZSBXM0MgYm94IG1vZGVsIHdvcmtzIGFzIGV4cGVjdGVkCgkvLyBkb2N1bWVudC5ib2R5IG11c3QgZXhpc3QgYmVmb3JlIHdlIGNhbiBkbyB0aGlzCglqUXVlcnkoZnVuY3Rpb24oKXsKCQl2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZGl2Iik7CgkJZGl2LnN0eWxlLndpZHRoID0gZGl2LnN0eWxlLnBhZGRpbmdMZWZ0ID0gIjFweCI7CgoJCWRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoIGRpdiApOwoJCWpRdWVyeS5ib3hNb2RlbCA9IGpRdWVyeS5zdXBwb3J0LmJveE1vZGVsID0gZGl2Lm9mZnNldFdpZHRoID09PSAyOwoJCWRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoIGRpdiApLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7Cgl9KTsKfSkoKTsKCnZhciBzdHlsZUZsb2F0ID0galF1ZXJ5LnN1cHBvcnQuY3NzRmxvYXQgPyAiY3NzRmxvYXQiIDogInN0eWxlRmxvYXQiOwoKalF1ZXJ5LnByb3BzID0gewoJImZvciI6ICJodG1sRm9yIiwKCSJjbGFzcyI6ICJjbGFzc05hbWUiLAoJImZsb2F0Ijogc3R5bGVGbG9hdCwKCWNzc0Zsb2F0OiBzdHlsZUZsb2F0LAoJc3R5bGVGbG9hdDogc3R5bGVGbG9hdCwKCXJlYWRvbmx5OiAicmVhZE9ubHkiLAoJbWF4bGVuZ3RoOiAibWF4TGVuZ3RoIiwKCWNlbGxzcGFjaW5nOiAiY2VsbFNwYWNpbmciLAoJcm93c3BhbjogInJvd1NwYW4iLAoJdGFiaW5kZXg6ICJ0YWJJbmRleCIKfTsKalF1ZXJ5LmZuLmV4dGVuZCh7CgkvLyBLZWVwIGEgY29weSBvZiB0aGUgb2xkIGxvYWQKCV9sb2FkOiBqUXVlcnkuZm4ubG9hZCwKCglsb2FkOiBmdW5jdGlvbiggdXJsLCBwYXJhbXMsIGNhbGxiYWNrICkgewoJCWlmICggdHlwZW9mIHVybCAhPT0gInN0cmluZyIgKQoJCQlyZXR1cm4gdGhpcy5fbG9hZCggdXJsICk7CgoJCXZhciBvZmYgPSB1cmwuaW5kZXhPZigiICIpOwoJCWlmICggb2ZmID49IDAgKSB7CgkJCXZhciBzZWxlY3RvciA9IHVybC5zbGljZShvZmYsIHVybC5sZW5ndGgpOwoJCQl1cmwgPSB1cmwuc2xpY2UoMCwgb2ZmKTsKCQl9CgoJCS8vIERlZmF1bHQgdG8gYSBHRVQgcmVxdWVzdAoJCXZhciB0eXBlID0gIkdFVCI7CgoJCS8vIElmIHRoZSBzZWNvbmQgcGFyYW1ldGVyIHdhcyBwcm92aWRlZAoJCWlmICggcGFyYW1zICkKCQkJLy8gSWYgaXQncyBhIGZ1bmN0aW9uCgkJCWlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHBhcmFtcyApICkgewoJCQkJLy8gV2UgYXNzdW1lIHRoYXQgaXQncyB0aGUgY2FsbGJhY2sKCQkJCWNhbGxiYWNrID0gcGFyYW1zOwoJCQkJcGFyYW1zID0gbnVsbDsKCgkJCS8vIE90aGVyd2lzZSwgYnVpbGQgYSBwYXJhbSBzdHJpbmcKCQkJfSBlbHNlIGlmKCB0eXBlb2YgcGFyYW1zID09PSAib2JqZWN0IiApIHsKCQkJCXBhcmFtcyA9IGpRdWVyeS5wYXJhbSggcGFyYW1zICk7CgkJCQl0eXBlID0gIlBPU1QiOwoJCQl9CgoJCXZhciBzZWxmID0gdGhpczsKCgkJLy8gUmVxdWVzdCB0aGUgcmVtb3RlIGRvY3VtZW50CgkJalF1ZXJ5LmFqYXgoewoJCQl1cmw6IHVybCwKCQkJdHlwZTogdHlwZSwKCQkJZGF0YVR5cGU6ICJodG1sIiwKCQkJZGF0YTogcGFyYW1zLAoJCQljb21wbGV0ZTogZnVuY3Rpb24ocmVzLCBzdGF0dXMpewoJCQkJLy8gSWYgc3VjY2Vzc2Z1bCwgaW5qZWN0IHRoZSBIVE1MIGludG8gYWxsIHRoZSBtYXRjaGVkIGVsZW1lbnRzCgkJCQlpZiAoIHN0YXR1cyA9PSAic3VjY2VzcyIgfHwgc3RhdHVzID09ICJub3Rtb2RpZmllZCIgKQoJCQkJCS8vIFNlZSBpZiBhIHNlbGVjdG9yIHdhcyBzcGVjaWZpZWQKCQkJCQlzZWxmLmh0bWwoIHNlbGVjdG9yID8KCQkJCQkJLy8gQ3JlYXRlIGEgZHVtbXkgZGl2IHRvIGhvbGQgdGhlIHJlc3VsdHMKCQkJCQkJalF1ZXJ5KCI8ZGl2Lz4iKQoJCQkJCQkJLy8gaW5qZWN0IHRoZSBjb250ZW50cyBvZiB0aGUgZG9jdW1lbnQgaW4sIHJlbW92aW5nIHRoZSBzY3JpcHRzCgkJCQkJCQkvLyB0byBhdm9pZCBhbnkgJ1Blcm1pc3Npb24gRGVuaWVkJyBlcnJvcnMgaW4gSUUKCQkJCQkJCS5hcHBlbmQocmVzLnJlc3BvbnNlVGV4dC5yZXBsYWNlKC88c2NyaXB0KC58XHMpKj9cL3NjcmlwdD4vZywgIiIpKQoKCQkJCQkJCS8vIExvY2F0ZSB0aGUgc3BlY2lmaWVkIGVsZW1lbnRzCgkJCQkJCQkuZmluZChzZWxlY3RvcikgOgoKCQkJCQkJLy8gSWYgbm90LCBqdXN0IGluamVjdCB0aGUgZnVsbCByZXN1bHQKCQkJCQkJcmVzLnJlc3BvbnNlVGV4dCApOwoKCQkJCWlmKCBjYWxsYmFjayApCgkJCQkJc2VsZi5lYWNoKCBjYWxsYmFjaywgW3Jlcy5yZXNwb25zZVRleHQsIHN0YXR1cywgcmVzXSApOwoJCQl9CgkJfSk7CgkJcmV0dXJuIHRoaXM7Cgl9LAoKCXNlcmlhbGl6ZTogZnVuY3Rpb24oKSB7CgkJcmV0dXJuIGpRdWVyeS5wYXJhbSh0aGlzLnNlcmlhbGl6ZUFycmF5KCkpOwoJfSwKCXNlcmlhbGl6ZUFycmF5OiBmdW5jdGlvbigpIHsKCQlyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKXsKCQkJcmV0dXJuIHRoaXMuZWxlbWVudHMgPyBqUXVlcnkubWFrZUFycmF5KHRoaXMuZWxlbWVudHMpIDogdGhpczsKCQl9KQoJCS5maWx0ZXIoZnVuY3Rpb24oKXsKCQkJcmV0dXJuIHRoaXMubmFtZSAmJiAhdGhpcy5kaXNhYmxlZCAmJgoJCQkJKHRoaXMuY2hlY2tlZCB8fCAvc2VsZWN0fHRleHRhcmVhL2kudGVzdCh0aGlzLm5vZGVOYW1lKSB8fAoJCQkJCS90ZXh0fGhpZGRlbnxwYXNzd29yZHxzZWFyY2gvaS50ZXN0KHRoaXMudHlwZSkpOwoJCX0pCgkJLm1hcChmdW5jdGlvbihpLCBlbGVtKXsKCQkJdmFyIHZhbCA9IGpRdWVyeSh0aGlzKS52YWwoKTsKCQkJcmV0dXJuIHZhbCA9PSBudWxsID8gbnVsbCA6CgkJCQlqUXVlcnkuaXNBcnJheSh2YWwpID8KCQkJCQlqUXVlcnkubWFwKCB2YWwsIGZ1bmN0aW9uKHZhbCwgaSl7CgkJCQkJCXJldHVybiB7bmFtZTogZWxlbS5uYW1lLCB2YWx1ZTogdmFsfTsKCQkJCQl9KSA6CgkJCQkJe25hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbH07CgkJfSkuZ2V0KCk7Cgl9Cn0pOwoKLy8gQXR0YWNoIGEgYnVuY2ggb2YgZnVuY3Rpb25zIGZvciBoYW5kbGluZyBjb21tb24gQUpBWCBldmVudHMKalF1ZXJ5LmVhY2goICJhamF4U3RhcnQsYWpheFN0b3AsYWpheENvbXBsZXRlLGFqYXhFcnJvcixhamF4U3VjY2VzcyxhamF4U2VuZCIuc3BsaXQoIiwiKSwgZnVuY3Rpb24oaSxvKXsKCWpRdWVyeS5mbltvXSA9IGZ1bmN0aW9uKGYpewoJCXJldHVybiB0aGlzLmJpbmQobywgZik7Cgl9Owp9KTsKCnZhciBqc2MgPSBub3coKTsKCmpRdWVyeS5leHRlbmQoewogIAoJZ2V0OiBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjaywgdHlwZSApIHsKCQkvLyBzaGlmdCBhcmd1bWVudHMgaWYgZGF0YSBhcmd1bWVudCB3YXMgb21taXRlZAoJCWlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGRhdGEgKSApIHsKCQkJY2FsbGJhY2sgPSBkYXRhOwoJCQlkYXRhID0gbnVsbDsKCQl9CgoJCXJldHVybiBqUXVlcnkuYWpheCh7CgkJCXR5cGU6ICJHRVQiLAoJCQl1cmw6IHVybCwKCQkJZGF0YTogZGF0YSwKCQkJc3VjY2VzczogY2FsbGJhY2ssCgkJCWRhdGFUeXBlOiB0eXBlCgkJfSk7Cgl9LAoKCWdldFNjcmlwdDogZnVuY3Rpb24oIHVybCwgY2FsbGJhY2sgKSB7CgkJcmV0dXJuIGpRdWVyeS5nZXQodXJsLCBudWxsLCBjYWxsYmFjaywgInNjcmlwdCIpOwoJfSwKCglnZXRKU09OOiBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjayApIHsKCQlyZXR1cm4galF1ZXJ5LmdldCh1cmwsIGRhdGEsIGNhbGxiYWNrLCAianNvbiIpOwoJfSwKCglwb3N0OiBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjaywgdHlwZSApIHsKCQlpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBkYXRhICkgKSB7CgkJCWNhbGxiYWNrID0gZGF0YTsKCQkJZGF0YSA9IHt9OwoJCX0KCgkJcmV0dXJuIGpRdWVyeS5hamF4KHsKCQkJdHlwZTogIlBPU1QiLAoJCQl1cmw6IHVybCwKCQkJZGF0YTogZGF0YSwKCQkJc3VjY2VzczogY2FsbGJhY2ssCgkJCWRhdGFUeXBlOiB0eXBlCgkJfSk7Cgl9LAoKCWFqYXhTZXR1cDogZnVuY3Rpb24oIHNldHRpbmdzICkgewoJCWpRdWVyeS5leHRlbmQoIGpRdWVyeS5hamF4U2V0dGluZ3MsIHNldHRpbmdzICk7Cgl9LAoKCWFqYXhTZXR0aW5nczogewoJCXVybDogbG9jYXRpb24uaHJlZiwKCQlnbG9iYWw6IHRydWUsCgkJdHlwZTogIkdFVCIsCgkJY29udGVudFR5cGU6ICJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQiLAoJCXByb2Nlc3NEYXRhOiB0cnVlLAoJCWFzeW5jOiB0cnVlLAoJCS8qCgkJdGltZW91dDogMCwKCQlkYXRhOiBudWxsLAoJCXVzZXJuYW1lOiBudWxsLAoJCXBhc3N3b3JkOiBudWxsLAoJCSovCgkJLy8gQ3JlYXRlIHRoZSByZXF1ZXN0IG9iamVjdDsgTWljcm9zb2Z0IGZhaWxlZCB0byBwcm9wZXJseQoJCS8vIGltcGxlbWVudCB0aGUgWE1MSHR0cFJlcXVlc3QgaW4gSUU3LCBzbyB3ZSB1c2UgdGhlIEFjdGl2ZVhPYmplY3Qgd2hlbiBpdCBpcyBhdmFpbGFibGUKCQkvLyBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBvdmVycmlkZW4gYnkgY2FsbGluZyBqUXVlcnkuYWpheFNldHVwCgkJeGhyOmZ1bmN0aW9uKCl7CgkJCXJldHVybiB3aW5kb3cuQWN0aXZlWE9iamVjdCA/IG5ldyBBY3RpdmVYT2JqZWN0KCJNaWNyb3NvZnQuWE1MSFRUUCIpIDogbmV3IFhNTEh0dHBSZXF1ZXN0KCk7CgkJfSwKCQlhY2NlcHRzOiB7CgkJCXhtbDogImFwcGxpY2F0aW9uL3htbCwgdGV4dC94bWwiLAoJCQlodG1sOiAidGV4dC9odG1sIiwKCQkJc2NyaXB0OiAidGV4dC9qYXZhc2NyaXB0LCBhcHBsaWNhdGlvbi9qYXZhc2NyaXB0IiwKCQkJanNvbjogImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCIsCgkJCXRleHQ6ICJ0ZXh0L3BsYWluIiwKCQkJX2RlZmF1bHQ6ICIqLyoiCgkJfQoJfSwKCgkvLyBMYXN0LU1vZGlmaWVkIGhlYWRlciBjYWNoZSBmb3IgbmV4dCByZXF1ZXN0CglsYXN0TW9kaWZpZWQ6IHt9LAoKCWFqYXg6IGZ1bmN0aW9uKCBzICkgewoJCS8vIEV4dGVuZCB0aGUgc2V0dGluZ3MsIGJ1dCByZS1leHRlbmQgJ3MnIHNvIHRoYXQgaXQgY2FuIGJlCgkJLy8gY2hlY2tlZCBhZ2FpbiBsYXRlciAoaW4gdGhlIHRlc3Qgc3VpdGUsIHNwZWNpZmljYWxseSkKCQlzID0galF1ZXJ5LmV4dGVuZCh0cnVlLCBzLCBqUXVlcnkuZXh0ZW5kKHRydWUsIHt9LCBqUXVlcnkuYWpheFNldHRpbmdzLCBzKSk7CgoJCXZhciBqc29ucCwganNyZSA9IC89XD8oJnwkKS9nLCBzdGF0dXMsIGRhdGEsCgkJCXR5cGUgPSBzLnR5cGUudG9VcHBlckNhc2UoKTsKCgkJLy8gY29udmVydCBkYXRhIGlmIG5vdCBhbHJlYWR5IGEgc3RyaW5nCgkJaWYgKCBzLmRhdGEgJiYgcy5wcm9jZXNzRGF0YSAmJiB0eXBlb2Ygcy5kYXRhICE9PSAic3RyaW5nIiApCgkJCXMuZGF0YSA9IGpRdWVyeS5wYXJhbShzLmRhdGEpOwoKCQkvLyBIYW5kbGUgSlNPTlAgUGFyYW1ldGVyIENhbGxiYWNrcwoJCWlmICggcy5kYXRhVHlwZSA9PSAianNvbnAiICkgewoJCQlpZiAoIHR5cGUgPT0gIkdFVCIgKSB7CgkJCQlpZiAoICFzLnVybC5tYXRjaChqc3JlKSApCgkJCQkJcy51cmwgKz0gKHMudXJsLm1hdGNoKC9cPy8pID8gIiYiIDogIj8iKSArIChzLmpzb25wIHx8ICJjYWxsYmFjayIpICsgIj0/IjsKCQkJfSBlbHNlIGlmICggIXMuZGF0YSB8fCAhcy5kYXRhLm1hdGNoKGpzcmUpICkKCQkJCXMuZGF0YSA9IChzLmRhdGEgPyBzLmRhdGEgKyAiJiIgOiAiIikgKyAocy5qc29ucCB8fCAiY2FsbGJhY2siKSArICI9PyI7CgkJCXMuZGF0YVR5cGUgPSAianNvbiI7CgkJfQoKCQkvLyBCdWlsZCB0ZW1wb3JhcnkgSlNPTlAgZnVuY3Rpb24KCQlpZiAoIHMuZGF0YVR5cGUgPT0gImpzb24iICYmIChzLmRhdGEgJiYgcy5kYXRhLm1hdGNoKGpzcmUpIHx8IHMudXJsLm1hdGNoKGpzcmUpKSApIHsKCQkJanNvbnAgPSAianNvbnAiICsganNjKys7CgoJCQkvLyBSZXBsYWNlIHRoZSA9PyBzZXF1ZW5jZSBib3RoIGluIHRoZSBxdWVyeSBzdHJpbmcgYW5kIHRoZSBkYXRhCgkJCWlmICggcy5kYXRhICkKCQkJCXMuZGF0YSA9IChzLmRhdGEgKyAiIikucmVwbGFjZShqc3JlLCAiPSIgKyBqc29ucCArICIkMSIpOwoJCQlzLnVybCA9IHMudXJsLnJlcGxhY2UoanNyZSwgIj0iICsganNvbnAgKyAiJDEiKTsKCgkJCS8vIFdlIG5lZWQgdG8gbWFrZSBzdXJlCgkJCS8vIHRoYXQgYSBKU09OUCBzdHlsZSByZXNwb25zZSBpcyBleGVjdXRlZCBwcm9wZXJseQoJCQlzLmRhdGFUeXBlID0gInNjcmlwdCI7CgoJCQkvLyBIYW5kbGUgSlNPTlAtc3R5bGUgbG9hZGluZwoJCQl3aW5kb3dbIGpzb25wIF0gPSBmdW5jdGlvbih0bXApewoJCQkJZGF0YSA9IHRtcDsKCQkJCXN1Y2Nlc3MoKTsKCQkJCWNvbXBsZXRlKCk7CgkJCQkvLyBHYXJiYWdlIGNvbGxlY3QKCQkJCXdpbmRvd1sganNvbnAgXSA9IHVuZGVmaW5lZDsKCQkJCXRyeXsgZGVsZXRlIHdpbmRvd1sganNvbnAgXTsgfSBjYXRjaChlKXt9CgkJCQlpZiAoIGhlYWQgKQoJCQkJCWhlYWQucmVtb3ZlQ2hpbGQoIHNjcmlwdCApOwoJCQl9OwoJCX0KCgkJaWYgKCBzLmRhdGFUeXBlID09ICJzY3JpcHQiICYmIHMuY2FjaGUgPT0gbnVsbCApCgkJCXMuY2FjaGUgPSBmYWxzZTsKCgkJaWYgKCBzLmNhY2hlID09PSBmYWxzZSAmJiB0eXBlID09ICJHRVQiICkgewoJCQl2YXIgdHMgPSBub3coKTsKCQkJLy8gdHJ5IHJlcGxhY2luZyBfPSBpZiBpdCBpcyB0aGVyZQoJCQl2YXIgcmV0ID0gcy51cmwucmVwbGFjZSgvKFw/fCYpXz0uKj8oJnwkKS8sICIkMV89IiArIHRzICsgIiQyIik7CgkJCS8vIGlmIG5vdGhpbmcgd2FzIHJlcGxhY2VkLCBhZGQgdGltZXN0YW1wIHRvIHRoZSBlbmQKCQkJcy51cmwgPSByZXQgKyAoKHJldCA9PSBzLnVybCkgPyAocy51cmwubWF0Y2goL1w/LykgPyAiJiIgOiAiPyIpICsgIl89IiArIHRzIDogIiIpOwoJCX0KCgkJLy8gSWYgZGF0YSBpcyBhdmFpbGFibGUsIGFwcGVuZCBkYXRhIHRvIHVybCBmb3IgZ2V0IHJlcXVlc3RzCgkJaWYgKCBzLmRhdGEgJiYgdHlwZSA9PSAiR0VUIiApIHsKCQkJcy51cmwgKz0gKHMudXJsLm1hdGNoKC9cPy8pID8gIiYiIDogIj8iKSArIHMuZGF0YTsKCgkJCS8vIElFIGxpa2VzIHRvIHNlbmQgYm90aCBnZXQgYW5kIHBvc3QgZGF0YSwgcHJldmVudCB0aGlzCgkJCXMuZGF0YSA9IG51bGw7CgkJfQoKCQkvLyBXYXRjaCBmb3IgYSBuZXcgc2V0IG9mIHJlcXVlc3RzCgkJaWYgKCBzLmdsb2JhbCAmJiAhIGpRdWVyeS5hY3RpdmUrKyApCgkJCWpRdWVyeS5ldmVudC50cmlnZ2VyKCAiYWpheFN0YXJ0IiApOwoKCQkvLyBNYXRjaGVzIGFuIGFic29sdXRlIFVSTCwgYW5kIHNhdmVzIHRoZSBkb21haW4KCQl2YXIgcGFydHMgPSAvXihcdys6KT9cL1wvKFteXC8/I10rKS8uZXhlYyggcy51cmwgKTsKCgkJLy8gSWYgd2UncmUgcmVxdWVzdGluZyBhIHJlbW90ZSBkb2N1bWVudAoJCS8vIGFuZCB0cnlpbmcgdG8gbG9hZCBKU09OIG9yIFNjcmlwdCB3aXRoIGEgR0VUCgkJaWYgKCBzLmRhdGFUeXBlID09ICJzY3JpcHQiICYmIHR5cGUgPT0gIkdFVCIgJiYgcGFydHMKCQkJJiYgKCBwYXJ0c1sxXSAmJiBwYXJ0c1sxXSAhPSBsb2NhdGlvbi5wcm90b2NvbCB8fCBwYXJ0c1syXSAhPSBsb2NhdGlvbi5ob3N0ICkpewoKCQkJdmFyIGhlYWQgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiaGVhZCIpWzBdOwoJCQl2YXIgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic2NyaXB0Iik7CgkJCXNjcmlwdC5zcmMgPSBzLnVybDsKCQkJaWYgKHMuc2NyaXB0Q2hhcnNldCkKCQkJCXNjcmlwdC5jaGFyc2V0ID0gcy5zY3JpcHRDaGFyc2V0OwoKCQkJLy8gSGFuZGxlIFNjcmlwdCBsb2FkaW5nCgkJCWlmICggIWpzb25wICkgewoJCQkJdmFyIGRvbmUgPSBmYWxzZTsKCgkJCQkvLyBBdHRhY2ggaGFuZGxlcnMgZm9yIGFsbCBicm93c2VycwoJCQkJc2NyaXB0Lm9ubG9hZCA9IHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpewoJCQkJCWlmICggIWRvbmUgJiYgKCF0aGlzLnJlYWR5U3RhdGUgfHwKCQkJCQkJCXRoaXMucmVhZHlTdGF0ZSA9PSAibG9hZGVkIiB8fCB0aGlzLnJlYWR5U3RhdGUgPT0gImNvbXBsZXRlIikgKSB7CgkJCQkJCWRvbmUgPSB0cnVlOwoJCQkJCQlzdWNjZXNzKCk7CgkJCQkJCWNvbXBsZXRlKCk7CgoJCQkJCQkvLyBIYW5kbGUgbWVtb3J5IGxlYWsgaW4gSUUKCQkJCQkJc2NyaXB0Lm9ubG9hZCA9IHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsOwoJCQkJCQloZWFkLnJlbW92ZUNoaWxkKCBzY3JpcHQgKTsKCQkJCQl9CgkJCQl9OwoJCQl9CgoJCQloZWFkLmFwcGVuZENoaWxkKHNjcmlwdCk7CgoJCQkvLyBXZSBoYW5kbGUgZXZlcnl0aGluZyB1c2luZyB0aGUgc2NyaXB0IGVsZW1lbnQgaW5qZWN0aW9uCgkJCXJldHVybiB1bmRlZmluZWQ7CgkJfQoKCQl2YXIgcmVxdWVzdERvbmUgPSBmYWxzZTsKCgkJLy8gQ3JlYXRlIHRoZSByZXF1ZXN0IG9iamVjdAoJCXZhciB4aHIgPSBzLnhocigpOwoKCQkvLyBPcGVuIHRoZSBzb2NrZXQKCQkvLyBQYXNzaW5nIG51bGwgdXNlcm5hbWUsIGdlbmVyYXRlcyBhIGxvZ2luIHBvcHVwIG9uIE9wZXJhICgjMjg2NSkKCQlpZiggcy51c2VybmFtZSApCgkJCXhoci5vcGVuKHR5cGUsIHMudXJsLCBzLmFzeW5jLCBzLnVzZXJuYW1lLCBzLnBhc3N3b3JkKTsKCQllbHNlCgkJCXhoci5vcGVuKHR5cGUsIHMudXJsLCBzLmFzeW5jKTsKCgkJLy8gTmVlZCBhbiBleHRyYSB0cnkvY2F0Y2ggZm9yIGNyb3NzIGRvbWFpbiByZXF1ZXN0cyBpbiBGaXJlZm94IDMKCQl0cnkgewoJCQkvLyBTZXQgdGhlIGNvcnJlY3QgaGVhZGVyLCBpZiBkYXRhIGlzIGJlaW5nIHNlbnQKCQkJaWYgKCBzLmRhdGEgKQoJCQkJeGhyLnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsIHMuY29udGVudFR5cGUpOwoKCQkJLy8gU2V0IHRoZSBJZi1Nb2RpZmllZC1TaW5jZSBoZWFkZXIsIGlmIGlmTW9kaWZpZWQgbW9kZS4KCQkJaWYgKCBzLmlmTW9kaWZpZWQgKQoJCQkJeGhyLnNldFJlcXVlc3RIZWFkZXIoIklmLU1vZGlmaWVkLVNpbmNlIiwKCQkJCQlqUXVlcnkubGFzdE1vZGlmaWVkW3MudXJsXSB8fCAiVGh1LCAwMSBKYW4gMTk3MCAwMDowMDowMCBHTVQiICk7CgoJCQkvLyBTZXQgaGVhZGVyIHNvIHRoZSBjYWxsZWQgc2NyaXB0IGtub3dzIHRoYXQgaXQncyBhbiBYTUxIdHRwUmVxdWVzdAoJCQl4aHIuc2V0UmVxdWVzdEhlYWRlcigiWC1SZXF1ZXN0ZWQtV2l0aCIsICJYTUxIdHRwUmVxdWVzdCIpOwoKCQkJLy8gU2V0IHRoZSBBY2NlcHRzIGhlYWRlciBmb3IgdGhlIHNlcnZlciwgZGVwZW5kaW5nIG9uIHRoZSBkYXRhVHlwZQoJCQl4aHIuc2V0UmVxdWVzdEhlYWRlcigiQWNjZXB0Iiwgcy5kYXRhVHlwZSAmJiBzLmFjY2VwdHNbIHMuZGF0YVR5cGUgXSA/CgkJCQlzLmFjY2VwdHNbIHMuZGF0YVR5cGUgXSArICIsICovKiIgOgoJCQkJcy5hY2NlcHRzLl9kZWZhdWx0ICk7CgkJfSBjYXRjaChlKXt9CgoJCS8vIEFsbG93IGN1c3RvbSBoZWFkZXJzL21pbWV0eXBlcyBhbmQgZWFybHkgYWJvcnQKCQlpZiAoIHMuYmVmb3JlU2VuZCAmJiBzLmJlZm9yZVNlbmQoeGhyLCBzKSA9PT0gZmFsc2UgKSB7CgkJCS8vIEhhbmRsZSB0aGUgZ2xvYmFsIEFKQVggY291bnRlcgoJCQlpZiAoIHMuZ2xvYmFsICYmICEgLS1qUXVlcnkuYWN0aXZlICkKCQkJCWpRdWVyeS5ldmVudC50cmlnZ2VyKCAiYWpheFN0b3AiICk7CgkJCS8vIGNsb3NlIG9wZW5kZWQgc29ja2V0CgkJCXhoci5hYm9ydCgpOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoKCQlpZiAoIHMuZ2xvYmFsICkKCQkJalF1ZXJ5LmV2ZW50LnRyaWdnZXIoImFqYXhTZW5kIiwgW3hociwgc10pOwoKCQkvLyBXYWl0IGZvciBhIHJlc3BvbnNlIHRvIGNvbWUgYmFjawoJCXZhciBvbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbihpc1RpbWVvdXQpewoJCQkvLyBUaGUgcmVxdWVzdCB3YXMgYWJvcnRlZCwgY2xlYXIgdGhlIGludGVydmFsIGFuZCBkZWNyZW1lbnQgalF1ZXJ5LmFjdGl2ZQoJCQlpZiAoeGhyLnJlYWR5U3RhdGUgPT0gMCkgewoJCQkJaWYgKGl2YWwpIHsKCQkJCQkvLyBjbGVhciBwb2xsIGludGVydmFsCgkJCQkJY2xlYXJJbnRlcnZhbChpdmFsKTsKCQkJCQlpdmFsID0gbnVsbDsKCQkJCQkvLyBIYW5kbGUgdGhlIGdsb2JhbCBBSkFYIGNvdW50ZXIKCQkJCQlpZiAoIHMuZ2xvYmFsICYmICEgLS1qUXVlcnkuYWN0aXZlICkKCQkJCQkJalF1ZXJ5LmV2ZW50LnRyaWdnZXIoICJhamF4U3RvcCIgKTsKCQkJCX0KCQkJLy8gVGhlIHRyYW5zZmVyIGlzIGNvbXBsZXRlIGFuZCB0aGUgZGF0YSBpcyBhdmFpbGFibGUsIG9yIHRoZSByZXF1ZXN0IHRpbWVkIG91dAoJCQl9IGVsc2UgaWYgKCAhcmVxdWVzdERvbmUgJiYgeGhyICYmICh4aHIucmVhZHlTdGF0ZSA9PSA0IHx8IGlzVGltZW91dCA9PSAidGltZW91dCIpICkgewoJCQkJcmVxdWVzdERvbmUgPSB0cnVlOwoKCQkJCS8vIGNsZWFyIHBvbGwgaW50ZXJ2YWwKCQkJCWlmIChpdmFsKSB7CgkJCQkJY2xlYXJJbnRlcnZhbChpdmFsKTsKCQkJCQlpdmFsID0gbnVsbDsKCQkJCX0KCgkJCQlzdGF0dXMgPSBpc1RpbWVvdXQgPT0gInRpbWVvdXQiID8gInRpbWVvdXQiIDoKCQkJCQkhalF1ZXJ5Lmh0dHBTdWNjZXNzKCB4aHIgKSA/ICJlcnJvciIgOgoJCQkJCXMuaWZNb2RpZmllZCAmJiBqUXVlcnkuaHR0cE5vdE1vZGlmaWVkKCB4aHIsIHMudXJsICkgPyAibm90bW9kaWZpZWQiIDoKCQkJCQkic3VjY2VzcyI7CgoJCQkJaWYgKCBzdGF0dXMgPT0gInN1Y2Nlc3MiICkgewoJCQkJCS8vIFdhdGNoIGZvciwgYW5kIGNhdGNoLCBYTUwgZG9jdW1lbnQgcGFyc2UgZXJyb3JzCgkJCQkJdHJ5IHsKCQkJCQkJLy8gcHJvY2VzcyB0aGUgZGF0YSAocnVucyB0aGUgeG1sIHRocm91Z2ggaHR0cERhdGEgcmVnYXJkbGVzcyBvZiBjYWxsYmFjaykKCQkJCQkJZGF0YSA9IGpRdWVyeS5odHRwRGF0YSggeGhyLCBzLmRhdGFUeXBlLCBzICk7CgkJCQkJfSBjYXRjaChlKSB7CgkJCQkJCXN0YXR1cyA9ICJwYXJzZXJlcnJvciI7CgkJCQkJfQoJCQkJfQoKCQkJCS8vIE1ha2Ugc3VyZSB0aGF0IHRoZSByZXF1ZXN0IHdhcyBzdWNjZXNzZnVsIG9yIG5vdG1vZGlmaWVkCgkJCQlpZiAoIHN0YXR1cyA9PSAic3VjY2VzcyIgKSB7CgkJCQkJLy8gQ2FjaGUgTGFzdC1Nb2RpZmllZCBoZWFkZXIsIGlmIGlmTW9kaWZpZWQgbW9kZS4KCQkJCQl2YXIgbW9kUmVzOwoJCQkJCXRyeSB7CgkJCQkJCW1vZFJlcyA9IHhoci5nZXRSZXNwb25zZUhlYWRlcigiTGFzdC1Nb2RpZmllZCIpOwoJCQkJCX0gY2F0Y2goZSkge30gLy8gc3dhbGxvdyBleGNlcHRpb24gdGhyb3duIGJ5IEZGIGlmIGhlYWRlciBpcyBub3QgYXZhaWxhYmxlCgoJCQkJCWlmICggcy5pZk1vZGlmaWVkICYmIG1vZFJlcyApCgkJCQkJCWpRdWVyeS5sYXN0TW9kaWZpZWRbcy51cmxdID0gbW9kUmVzOwoKCQkJCQkvLyBKU09OUCBoYW5kbGVzIGl0cyBvd24gc3VjY2VzcyBjYWxsYmFjawoJCQkJCWlmICggIWpzb25wICkKCQkJCQkJc3VjY2VzcygpOwoJCQkJfSBlbHNlCgkJCQkJalF1ZXJ5LmhhbmRsZUVycm9yKHMsIHhociwgc3RhdHVzKTsKCgkJCQkvLyBGaXJlIHRoZSBjb21wbGV0ZSBoYW5kbGVycwoJCQkJY29tcGxldGUoKTsKCgkJCQlpZiAoIGlzVGltZW91dCApCgkJCQkJeGhyLmFib3J0KCk7CgoJCQkJLy8gU3RvcCBtZW1vcnkgbGVha3MKCQkJCWlmICggcy5hc3luYyApCgkJCQkJeGhyID0gbnVsbDsKCQkJfQoJCX07CgoJCWlmICggcy5hc3luYyApIHsKCQkJLy8gZG9uJ3QgYXR0YWNoIHRoZSBoYW5kbGVyIHRvIHRoZSByZXF1ZXN0LCBqdXN0IHBvbGwgaXQgaW5zdGVhZAoJCQl2YXIgaXZhbCA9IHNldEludGVydmFsKG9ucmVhZHlzdGF0ZWNoYW5nZSwgMTMpOwoKCQkJLy8gVGltZW91dCBjaGVja2VyCgkJCWlmICggcy50aW1lb3V0ID4gMCApCgkJCQlzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7CgkJCQkJLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSByZXF1ZXN0IGlzIHN0aWxsIGhhcHBlbmluZwoJCQkJCWlmICggeGhyICYmICFyZXF1ZXN0RG9uZSApCgkJCQkJCW9ucmVhZHlzdGF0ZWNoYW5nZSggInRpbWVvdXQiICk7CgkJCQl9LCBzLnRpbWVvdXQpOwoJCX0KCgkJLy8gU2VuZCB0aGUgZGF0YQoJCXRyeSB7CgkJCXhoci5zZW5kKHMuZGF0YSk7CgkJfSBjYXRjaChlKSB7CgkJCWpRdWVyeS5oYW5kbGVFcnJvcihzLCB4aHIsIG51bGwsIGUpOwoJCX0KCgkJLy8gZmlyZWZveCAxLjUgZG9lc24ndCBmaXJlIHN0YXRlY2hhbmdlIGZvciBzeW5jIHJlcXVlc3RzCgkJaWYgKCAhcy5hc3luYyApCgkJCW9ucmVhZHlzdGF0ZWNoYW5nZSgpOwoKCQlmdW5jdGlvbiBzdWNjZXNzKCl7CgkJCS8vIElmIGEgbG9jYWwgY2FsbGJhY2sgd2FzIHNwZWNpZmllZCwgZmlyZSBpdCBhbmQgcGFzcyBpdCB0aGUgZGF0YQoJCQlpZiAoIHMuc3VjY2VzcyApCgkJCQlzLnN1Y2Nlc3MoIGRhdGEsIHN0YXR1cyApOwoKCQkJLy8gRmlyZSB0aGUgZ2xvYmFsIGNhbGxiYWNrCgkJCWlmICggcy5nbG9iYWwgKQoJCQkJalF1ZXJ5LmV2ZW50LnRyaWdnZXIoICJhamF4U3VjY2VzcyIsIFt4aHIsIHNdICk7CgkJfQoKCQlmdW5jdGlvbiBjb21wbGV0ZSgpewoJCQkvLyBQcm9jZXNzIHJlc3VsdAoJCQlpZiAoIHMuY29tcGxldGUgKQoJCQkJcy5jb21wbGV0ZSh4aHIsIHN0YXR1cyk7CgoJCQkvLyBUaGUgcmVxdWVzdCB3YXMgY29tcGxldGVkCgkJCWlmICggcy5nbG9iYWwgKQoJCQkJalF1ZXJ5LmV2ZW50LnRyaWdnZXIoICJhamF4Q29tcGxldGUiLCBbeGhyLCBzXSApOwoKCQkJLy8gSGFuZGxlIHRoZSBnbG9iYWwgQUpBWCBjb3VudGVyCgkJCWlmICggcy5nbG9iYWwgJiYgISAtLWpRdWVyeS5hY3RpdmUgKQoJCQkJalF1ZXJ5LmV2ZW50LnRyaWdnZXIoICJhamF4U3RvcCIgKTsKCQl9CgoJCS8vIHJldHVybiBYTUxIdHRwUmVxdWVzdCB0byBhbGxvdyBhYm9ydGluZyB0aGUgcmVxdWVzdCBldGMuCgkJcmV0dXJuIHhocjsKCX0sCgoJaGFuZGxlRXJyb3I6IGZ1bmN0aW9uKCBzLCB4aHIsIHN0YXR1cywgZSApIHsKCQkvLyBJZiBhIGxvY2FsIGNhbGxiYWNrIHdhcyBzcGVjaWZpZWQsIGZpcmUgaXQKCQlpZiAoIHMuZXJyb3IgKSBzLmVycm9yKCB4aHIsIHN0YXR1cywgZSApOwoKCQkvLyBGaXJlIHRoZSBnbG9iYWwgY2FsbGJhY2sKCQlpZiAoIHMuZ2xvYmFsICkKCQkJalF1ZXJ5LmV2ZW50LnRyaWdnZXIoICJhamF4RXJyb3IiLCBbeGhyLCBzLCBlXSApOwoJfSwKCgkvLyBDb3VudGVyIGZvciBob2xkaW5nIHRoZSBudW1iZXIgb2YgYWN0aXZlIHF1ZXJpZXMKCWFjdGl2ZTogMCwKCgkvLyBEZXRlcm1pbmVzIGlmIGFuIFhNTEh0dHBSZXF1ZXN0IHdhcyBzdWNjZXNzZnVsIG9yIG5vdAoJaHR0cFN1Y2Nlc3M6IGZ1bmN0aW9uKCB4aHIgKSB7CgkJdHJ5IHsKCQkJLy8gSUUgZXJyb3Igc29tZXRpbWVzIHJldHVybnMgMTIyMyB3aGVuIGl0IHNob3VsZCBiZSAyMDQgc28gdHJlYXQgaXQgYXMgc3VjY2Vzcywgc2VlICMxNDUwCgkJCXJldHVybiAheGhyLnN0YXR1cyAmJiBsb2NhdGlvbi5wcm90b2NvbCA9PSAiZmlsZToiIHx8CgkJCQkoIHhoci5zdGF0dXMgPj0gMjAwICYmIHhoci5zdGF0dXMgPCAzMDAgKSB8fCB4aHIuc3RhdHVzID09IDMwNCB8fCB4aHIuc3RhdHVzID09IDEyMjM7CgkJfSBjYXRjaChlKXt9CgkJcmV0dXJuIGZhbHNlOwoJfSwKCgkvLyBEZXRlcm1pbmVzIGlmIGFuIFhNTEh0dHBSZXF1ZXN0IHJldHVybnMgTm90TW9kaWZpZWQKCWh0dHBOb3RNb2RpZmllZDogZnVuY3Rpb24oIHhociwgdXJsICkgewoJCXRyeSB7CgkJCXZhciB4aHJSZXMgPSB4aHIuZ2V0UmVzcG9uc2VIZWFkZXIoIkxhc3QtTW9kaWZpZWQiKTsKCgkJCS8vIEZpcmVmb3ggYWx3YXlzIHJldHVybnMgMjAwLiBjaGVjayBMYXN0LU1vZGlmaWVkIGRhdGUKCQkJcmV0dXJuIHhoci5zdGF0dXMgPT0gMzA0IHx8IHhoclJlcyA9PSBqUXVlcnkubGFzdE1vZGlmaWVkW3VybF07CgkJfSBjYXRjaChlKXt9CgkJcmV0dXJuIGZhbHNlOwoJfSwKCglodHRwRGF0YTogZnVuY3Rpb24oIHhociwgdHlwZSwgcyApIHsKCQl2YXIgY3QgPSB4aHIuZ2V0UmVzcG9uc2VIZWFkZXIoImNvbnRlbnQtdHlwZSIpLAoJCQl4bWwgPSB0eXBlID09ICJ4bWwiIHx8ICF0eXBlICYmIGN0ICYmIGN0LmluZGV4T2YoInhtbCIpID49IDAsCgkJCWRhdGEgPSB4bWwgPyB4aHIucmVzcG9uc2VYTUwgOiB4aHIucmVzcG9uc2VUZXh0OwoKCQlpZiAoIHhtbCAmJiBkYXRhLmRvY3VtZW50RWxlbWVudC50YWdOYW1lID09ICJwYXJzZXJlcnJvciIgKQoJCQl0aHJvdyAicGFyc2VyZXJyb3IiOwoJCQkKCQkvLyBBbGxvdyBhIHByZS1maWx0ZXJpbmcgZnVuY3Rpb24gdG8gc2FuaXRpemUgdGhlIHJlc3BvbnNlCgkJLy8gcyAhPSBudWxsIGlzIGNoZWNrZWQgdG8ga2VlcCBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eQoJCWlmKCBzICYmIHMuZGF0YUZpbHRlciApCgkJCWRhdGEgPSBzLmRhdGFGaWx0ZXIoIGRhdGEsIHR5cGUgKTsKCgkJLy8gVGhlIGZpbHRlciBjYW4gYWN0dWFsbHkgcGFyc2UgdGhlIHJlc3BvbnNlCgkJaWYoIHR5cGVvZiBkYXRhID09PSAic3RyaW5nIiApewoKCQkJLy8gSWYgdGhlIHR5cGUgaXMgInNjcmlwdCIsIGV2YWwgaXQgaW4gZ2xvYmFsIGNvbnRleHQKCQkJaWYgKCB0eXBlID09ICJzY3JpcHQiICkKCQkJCWpRdWVyeS5nbG9iYWxFdmFsKCBkYXRhICk7CgoJCQkvLyBHZXQgdGhlIEphdmFTY3JpcHQgb2JqZWN0LCBpZiBKU09OIGlzIHVzZWQuCgkJCWlmICggdHlwZSA9PSAianNvbiIgKQoJCQkJZGF0YSA9IHdpbmRvd1siZXZhbCJdKCIoIiArIGRhdGEgKyAiKSIpOwoJCX0KCQkKCQlyZXR1cm4gZGF0YTsKCX0sCgoJLy8gU2VyaWFsaXplIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMgb3IgYSBzZXQgb2YKCS8vIGtleS92YWx1ZXMgaW50byBhIHF1ZXJ5IHN0cmluZwoJcGFyYW06IGZ1bmN0aW9uKCBhICkgewoJCXZhciBzID0gWyBdOwoKCQlmdW5jdGlvbiBhZGQoIGtleSwgdmFsdWUgKXsKCQkJc1sgcy5sZW5ndGggXSA9IGVuY29kZVVSSUNvbXBvbmVudChrZXkpICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTsKCQl9OwoKCQkvLyBJZiBhbiBhcnJheSB3YXMgcGFzc2VkIGluLCBhc3N1bWUgdGhhdCBpdCBpcyBhbiBhcnJheQoJCS8vIG9mIGZvcm0gZWxlbWVudHMKCQlpZiAoIGpRdWVyeS5pc0FycmF5KGEpIHx8IGEuanF1ZXJ5ICkKCQkJLy8gU2VyaWFsaXplIHRoZSBmb3JtIGVsZW1lbnRzCgkJCWpRdWVyeS5lYWNoKCBhLCBmdW5jdGlvbigpewoJCQkJYWRkKCB0aGlzLm5hbWUsIHRoaXMudmFsdWUgKTsKCQkJfSk7CgoJCS8vIE90aGVyd2lzZSwgYXNzdW1lIHRoYXQgaXQncyBhbiBvYmplY3Qgb2Yga2V5L3ZhbHVlIHBhaXJzCgkJZWxzZQoJCQkvLyBTZXJpYWxpemUgdGhlIGtleS92YWx1ZXMKCQkJZm9yICggdmFyIGogaW4gYSApCgkJCQkvLyBJZiB0aGUgdmFsdWUgaXMgYW4gYXJyYXkgdGhlbiB0aGUga2V5IG5hbWVzIG5lZWQgdG8gYmUgcmVwZWF0ZWQKCQkJCWlmICggalF1ZXJ5LmlzQXJyYXkoYVtqXSkgKQoJCQkJCWpRdWVyeS5lYWNoKCBhW2pdLCBmdW5jdGlvbigpewoJCQkJCQlhZGQoIGosIHRoaXMgKTsKCQkJCQl9KTsKCQkJCWVsc2UKCQkJCQlhZGQoIGosIGpRdWVyeS5pc0Z1bmN0aW9uKGFbal0pID8gYVtqXSgpIDogYVtqXSApOwoKCQkvLyBSZXR1cm4gdGhlIHJlc3VsdGluZyBzZXJpYWxpemF0aW9uCgkJcmV0dXJuIHMuam9pbigiJiIpLnJlcGxhY2UoLyUyMC9nLCAiKyIpOwoJfQoKfSk7CnZhciBlbGVtZGlzcGxheSA9IHt9LAoJdGltZXJJZCwKCWZ4QXR0cnMgPSBbCgkJLy8gaGVpZ2h0IGFuaW1hdGlvbnMKCQlbICJoZWlnaHQiLCAibWFyZ2luVG9wIiwgIm1hcmdpbkJvdHRvbSIsICJwYWRkaW5nVG9wIiwgInBhZGRpbmdCb3R0b20iIF0sCgkJLy8gd2lkdGggYW5pbWF0aW9ucwoJCVsgIndpZHRoIiwgIm1hcmdpbkxlZnQiLCAibWFyZ2luUmlnaHQiLCAicGFkZGluZ0xlZnQiLCAicGFkZGluZ1JpZ2h0IiBdLAoJCS8vIG9wYWNpdHkgYW5pbWF0aW9ucwoJCVsgIm9wYWNpdHkiIF0KCV07CgpmdW5jdGlvbiBnZW5GeCggdHlwZSwgbnVtICl7Cgl2YXIgb2JqID0ge307CglqUXVlcnkuZWFjaCggZnhBdHRycy5jb25jYXQuYXBwbHkoW10sIGZ4QXR0cnMuc2xpY2UoMCxudW0pKSwgZnVuY3Rpb24oKXsKCQlvYmpbIHRoaXMgXSA9IHR5cGU7Cgl9KTsKCXJldHVybiBvYmo7Cn0KCmpRdWVyeS5mbi5leHRlbmQoewoJc2hvdzogZnVuY3Rpb24oc3BlZWQsY2FsbGJhY2spewoJCWlmICggc3BlZWQgKSB7CgkJCXJldHVybiB0aGlzLmFuaW1hdGUoIGdlbkZ4KCJzaG93IiwgMyksIHNwZWVkLCBjYWxsYmFjayk7CgkJfSBlbHNlIHsKCQkJZm9yICggdmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKysgKXsKCQkJCXZhciBvbGQgPSBqUXVlcnkuZGF0YSh0aGlzW2ldLCAib2xkZGlzcGxheSIpOwoJCQkJCgkJCQl0aGlzW2ldLnN0eWxlLmRpc3BsYXkgPSBvbGQgfHwgIiI7CgkJCQkKCQkJCWlmICggalF1ZXJ5LmNzcyh0aGlzW2ldLCAiZGlzcGxheSIpID09PSAibm9uZSIgKSB7CgkJCQkJdmFyIHRhZ05hbWUgPSB0aGlzW2ldLnRhZ05hbWUsIGRpc3BsYXk7CgkJCQkJCgkJCQkJaWYgKCBlbGVtZGlzcGxheVsgdGFnTmFtZSBdICkgewoJCQkJCQlkaXNwbGF5ID0gZWxlbWRpc3BsYXlbIHRhZ05hbWUgXTsKCQkJCQl9IGVsc2UgewoJCQkJCQl2YXIgZWxlbSA9IGpRdWVyeSgiPCIgKyB0YWdOYW1lICsgIiAvPiIpLmFwcGVuZFRvKCJib2R5Iik7CgkJCQkJCQoJCQkJCQlkaXNwbGF5ID0gZWxlbS5jc3MoImRpc3BsYXkiKTsKCQkJCQkJaWYgKCBkaXNwbGF5ID09PSAibm9uZSIgKQoJCQkJCQkJZGlzcGxheSA9ICJibG9jayI7CgkJCQkJCQoJCQkJCQllbGVtLnJlbW92ZSgpOwoJCQkJCQkKCQkJCQkJZWxlbWRpc3BsYXlbIHRhZ05hbWUgXSA9IGRpc3BsYXk7CgkJCQkJfQoJCQkJCQoJCQkJCWpRdWVyeS5kYXRhKHRoaXNbaV0sICJvbGRkaXNwbGF5IiwgZGlzcGxheSk7CgkJCQl9CgkJCX0KCgkJCS8vIFNldCB0aGUgZGlzcGxheSBvZiB0aGUgZWxlbWVudHMgaW4gYSBzZWNvbmQgbG9vcAoJCQkvLyB0byBhdm9pZCB0aGUgY29uc3RhbnQgcmVmbG93CgkJCWZvciAoIHZhciBpID0gMCwgbCA9IHRoaXMubGVuZ3RoOyBpIDwgbDsgaSsrICl7CgkJCQl0aGlzW2ldLnN0eWxlLmRpc3BsYXkgPSBqUXVlcnkuZGF0YSh0aGlzW2ldLCAib2xkZGlzcGxheSIpIHx8ICIiOwoJCQl9CgkJCQoJCQlyZXR1cm4gdGhpczsKCQl9Cgl9LAoKCWhpZGU6IGZ1bmN0aW9uKHNwZWVkLGNhbGxiYWNrKXsKCQlpZiAoIHNwZWVkICkgewoJCQlyZXR1cm4gdGhpcy5hbmltYXRlKCBnZW5GeCgiaGlkZSIsIDMpLCBzcGVlZCwgY2FsbGJhY2spOwoJCX0gZWxzZSB7CgkJCWZvciAoIHZhciBpID0gMCwgbCA9IHRoaXMubGVuZ3RoOyBpIDwgbDsgaSsrICl7CgkJCQl2YXIgb2xkID0galF1ZXJ5LmRhdGEodGhpc1tpXSwgIm9sZGRpc3BsYXkiKTsKCQkJCWlmICggIW9sZCAmJiBvbGQgIT09ICJub25lIiApCgkJCQkJalF1ZXJ5LmRhdGEodGhpc1tpXSwgIm9sZGRpc3BsYXkiLCBqUXVlcnkuY3NzKHRoaXNbaV0sICJkaXNwbGF5IikpOwoJCQl9CgoJCQkvLyBTZXQgdGhlIGRpc3BsYXkgb2YgdGhlIGVsZW1lbnRzIGluIGEgc2Vjb25kIGxvb3AKCQkJLy8gdG8gYXZvaWQgdGhlIGNvbnN0YW50IHJlZmxvdwoJCQlmb3IgKCB2YXIgaSA9IDAsIGwgPSB0aGlzLmxlbmd0aDsgaSA8IGw7IGkrKyApewoJCQkJdGhpc1tpXS5zdHlsZS5kaXNwbGF5ID0gIm5vbmUiOwoJCQl9CgoJCQlyZXR1cm4gdGhpczsKCQl9Cgl9LAoKCS8vIFNhdmUgdGhlIG9sZCB0b2dnbGUgZnVuY3Rpb24KCV90b2dnbGU6IGpRdWVyeS5mbi50b2dnbGUsCgoJdG9nZ2xlOiBmdW5jdGlvbiggZm4sIGZuMiApewoJCXZhciBib29sID0gdHlwZW9mIGZuID09PSAiYm9vbGVhbiI7CgoJCXJldHVybiBqUXVlcnkuaXNGdW5jdGlvbihmbikgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oZm4yKSA/CgkJCXRoaXMuX3RvZ2dsZS5hcHBseSggdGhpcywgYXJndW1lbnRzICkgOgoJCQlmbiA9PSBudWxsIHx8IGJvb2wgPwoJCQkJdGhpcy5lYWNoKGZ1bmN0aW9uKCl7CgkJCQkJdmFyIHN0YXRlID0gYm9vbCA/IGZuIDogalF1ZXJ5KHRoaXMpLmlzKCI6aGlkZGVuIik7CgkJCQkJalF1ZXJ5KHRoaXMpWyBzdGF0ZSA/ICJzaG93IiA6ICJoaWRlIiBdKCk7CgkJCQl9KSA6CgkJCQl0aGlzLmFuaW1hdGUoZ2VuRngoInRvZ2dsZSIsIDMpLCBmbiwgZm4yKTsKCX0sCgoJZmFkZVRvOiBmdW5jdGlvbihzcGVlZCx0byxjYWxsYmFjayl7CgkJcmV0dXJuIHRoaXMuYW5pbWF0ZSh7b3BhY2l0eTogdG99LCBzcGVlZCwgY2FsbGJhY2spOwoJfSwKCglhbmltYXRlOiBmdW5jdGlvbiggcHJvcCwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7CgkJdmFyIG9wdGFsbCA9IGpRdWVyeS5zcGVlZChzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayk7CgoJCXJldHVybiB0aGlzWyBvcHRhbGwucXVldWUgPT09IGZhbHNlID8gImVhY2giIDogInF1ZXVlIiBdKGZ1bmN0aW9uKCl7CgkJCgkJCXZhciBvcHQgPSBqUXVlcnkuZXh0ZW5kKHt9LCBvcHRhbGwpLCBwLAoJCQkJaGlkZGVuID0gdGhpcy5ub2RlVHlwZSA9PSAxICYmIGpRdWVyeSh0aGlzKS5pcygiOmhpZGRlbiIpLAoJCQkJc2VsZiA9IHRoaXM7CgkKCQkJZm9yICggcCBpbiBwcm9wICkgewoJCQkJaWYgKCBwcm9wW3BdID09ICJoaWRlIiAmJiBoaWRkZW4gfHwgcHJvcFtwXSA9PSAic2hvdyIgJiYgIWhpZGRlbiApCgkJCQkJcmV0dXJuIG9wdC5jb21wbGV0ZS5jYWxsKHRoaXMpOwoKCQkJCWlmICggKCBwID09ICJoZWlnaHQiIHx8IHAgPT0gIndpZHRoIiApICYmIHRoaXMuc3R5bGUgKSB7CgkJCQkJLy8gU3RvcmUgZGlzcGxheSBwcm9wZXJ0eQoJCQkJCW9wdC5kaXNwbGF5ID0galF1ZXJ5LmNzcyh0aGlzLCAiZGlzcGxheSIpOwoKCQkJCQkvLyBNYWtlIHN1cmUgdGhhdCBub3RoaW5nIHNuZWFrcyBvdXQKCQkJCQlvcHQub3ZlcmZsb3cgPSB0aGlzLnN0eWxlLm92ZXJmbG93OwoJCQkJfQoJCQl9CgoJCQlpZiAoIG9wdC5vdmVyZmxvdyAhPSBudWxsICkKCQkJCXRoaXMuc3R5bGUub3ZlcmZsb3cgPSAiaGlkZGVuIjsKCgkJCW9wdC5jdXJBbmltID0galF1ZXJ5LmV4dGVuZCh7fSwgcHJvcCk7CgoJCQlqUXVlcnkuZWFjaCggcHJvcCwgZnVuY3Rpb24obmFtZSwgdmFsKXsKCQkJCXZhciBlID0gbmV3IGpRdWVyeS5meCggc2VsZiwgb3B0LCBuYW1lICk7CgoJCQkJaWYgKCAvdG9nZ2xlfHNob3d8aGlkZS8udGVzdCh2YWwpICkKCQkJCQllWyB2YWwgPT0gInRvZ2dsZSIgPyBoaWRkZW4gPyAic2hvdyIgOiAiaGlkZSIgOiB2YWwgXSggcHJvcCApOwoJCQkJZWxzZSB7CgkJCQkJdmFyIHBhcnRzID0gdmFsLnRvU3RyaW5nKCkubWF0Y2goL14oWystXT0pPyhbXGQrLS5dKykoLiopJC8pLAoJCQkJCQlzdGFydCA9IGUuY3VyKHRydWUpIHx8IDA7CgoJCQkJCWlmICggcGFydHMgKSB7CgkJCQkJCXZhciBlbmQgPSBwYXJzZUZsb2F0KHBhcnRzWzJdKSwKCQkJCQkJCXVuaXQgPSBwYXJ0c1szXSB8fCAicHgiOwoKCQkJCQkJLy8gV2UgbmVlZCB0byBjb21wdXRlIHN0YXJ0aW5nIHZhbHVlCgkJCQkJCWlmICggdW5pdCAhPSAicHgiICkgewoJCQkJCQkJc2VsZi5zdHlsZVsgbmFtZSBdID0gKGVuZCB8fCAxKSArIHVuaXQ7CgkJCQkJCQlzdGFydCA9ICgoZW5kIHx8IDEpIC8gZS5jdXIodHJ1ZSkpICogc3RhcnQ7CgkJCQkJCQlzZWxmLnN0eWxlWyBuYW1lIF0gPSBzdGFydCArIHVuaXQ7CgkJCQkJCX0KCgkJCQkJCS8vIElmIGEgKz0vLT0gdG9rZW4gd2FzIHByb3ZpZGVkLCB3ZSdyZSBkb2luZyBhIHJlbGF0aXZlIGFuaW1hdGlvbgoJCQkJCQlpZiAoIHBhcnRzWzFdICkKCQkJCQkJCWVuZCA9ICgocGFydHNbMV0gPT0gIi09IiA/IC0xIDogMSkgKiBlbmQpICsgc3RhcnQ7CgoJCQkJCQllLmN1c3RvbSggc3RhcnQsIGVuZCwgdW5pdCApOwoJCQkJCX0gZWxzZQoJCQkJCQllLmN1c3RvbSggc3RhcnQsIHZhbCwgIiIgKTsKCQkJCX0KCQkJfSk7CgoJCQkvLyBGb3IgSlMgc3RyaWN0IGNvbXBsaWFuY2UKCQkJcmV0dXJuIHRydWU7CgkJfSk7Cgl9LAoKCXN0b3A6IGZ1bmN0aW9uKGNsZWFyUXVldWUsIGdvdG9FbmQpewoJCXZhciB0aW1lcnMgPSBqUXVlcnkudGltZXJzOwoKCQlpZiAoY2xlYXJRdWV1ZSkKCQkJdGhpcy5xdWV1ZShbXSk7CgoJCXRoaXMuZWFjaChmdW5jdGlvbigpewoJCQkvLyBnbyBpbiByZXZlcnNlIG9yZGVyIHNvIGFueXRoaW5nIGFkZGVkIHRvIHRoZSBxdWV1ZSBkdXJpbmcgdGhlIGxvb3AgaXMgaWdub3JlZAoJCQlmb3IgKCB2YXIgaSA9IHRpbWVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSApCgkJCQlpZiAoIHRpbWVyc1tpXS5lbGVtID09IHRoaXMgKSB7CgkJCQkJaWYgKGdvdG9FbmQpCgkJCQkJCS8vIGZvcmNlIHRoZSBuZXh0IHN0ZXAgdG8gYmUgdGhlIGxhc3QKCQkJCQkJdGltZXJzW2ldKHRydWUpOwoJCQkJCXRpbWVycy5zcGxpY2UoaSwgMSk7CgkJCQl9CgkJfSk7CgoJCS8vIHN0YXJ0IHRoZSBuZXh0IGluIHRoZSBxdWV1ZSBpZiB0aGUgbGFzdCBzdGVwIHdhc24ndCBmb3JjZWQKCQlpZiAoIWdvdG9FbmQpCgkJCXRoaXMuZGVxdWV1ZSgpOwoKCQlyZXR1cm4gdGhpczsKCX0KCn0pOwoKLy8gR2VuZXJhdGUgc2hvcnRjdXRzIGZvciBjdXN0b20gYW5pbWF0aW9ucwpqUXVlcnkuZWFjaCh7CglzbGlkZURvd246IGdlbkZ4KCJzaG93IiwgMSksCglzbGlkZVVwOiBnZW5GeCgiaGlkZSIsIDEpLAoJc2xpZGVUb2dnbGU6IGdlbkZ4KCJ0b2dnbGUiLCAxKSwKCWZhZGVJbjogeyBvcGFjaXR5OiAic2hvdyIgfSwKCWZhZGVPdXQ6IHsgb3BhY2l0eTogImhpZGUiIH0KfSwgZnVuY3Rpb24oIG5hbWUsIHByb3BzICl7CglqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBzcGVlZCwgY2FsbGJhY2sgKXsKCQlyZXR1cm4gdGhpcy5hbmltYXRlKCBwcm9wcywgc3BlZWQsIGNhbGxiYWNrICk7Cgl9Owp9KTsKCmpRdWVyeS5leHRlbmQoewoKCXNwZWVkOiBmdW5jdGlvbihzcGVlZCwgZWFzaW5nLCBmbikgewoJCXZhciBvcHQgPSB0eXBlb2Ygc3BlZWQgPT09ICJvYmplY3QiID8gc3BlZWQgOiB7CgkJCWNvbXBsZXRlOiBmbiB8fCAhZm4gJiYgZWFzaW5nIHx8CgkJCQlqUXVlcnkuaXNGdW5jdGlvbiggc3BlZWQgKSAmJiBzcGVlZCwKCQkJZHVyYXRpb246IHNwZWVkLAoJCQllYXNpbmc6IGZuICYmIGVhc2luZyB8fCBlYXNpbmcgJiYgIWpRdWVyeS5pc0Z1bmN0aW9uKGVhc2luZykgJiYgZWFzaW5nCgkJfTsKCgkJb3B0LmR1cmF0aW9uID0galF1ZXJ5LmZ4Lm9mZiA/IDAgOiB0eXBlb2Ygb3B0LmR1cmF0aW9uID09PSAibnVtYmVyIiA/IG9wdC5kdXJhdGlvbiA6CgkJCWpRdWVyeS5meC5zcGVlZHNbb3B0LmR1cmF0aW9uXSB8fCBqUXVlcnkuZnguc3BlZWRzLl9kZWZhdWx0OwoKCQkvLyBRdWV1ZWluZwoJCW9wdC5vbGQgPSBvcHQuY29tcGxldGU7CgkJb3B0LmNvbXBsZXRlID0gZnVuY3Rpb24oKXsKCQkJaWYgKCBvcHQucXVldWUgIT09IGZhbHNlICkKCQkJCWpRdWVyeSh0aGlzKS5kZXF1ZXVlKCk7CgkJCWlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIG9wdC5vbGQgKSApCgkJCQlvcHQub2xkLmNhbGwoIHRoaXMgKTsKCQl9OwoKCQlyZXR1cm4gb3B0OwoJfSwKCgllYXNpbmc6IHsKCQlsaW5lYXI6IGZ1bmN0aW9uKCBwLCBuLCBmaXJzdE51bSwgZGlmZiApIHsKCQkJcmV0dXJuIGZpcnN0TnVtICsgZGlmZiAqIHA7CgkJfSwKCQlzd2luZzogZnVuY3Rpb24oIHAsIG4sIGZpcnN0TnVtLCBkaWZmICkgewoJCQlyZXR1cm4gKCgtTWF0aC5jb3MocCpNYXRoLlBJKS8yKSArIDAuNSkgKiBkaWZmICsgZmlyc3ROdW07CgkJfQoJfSwKCgl0aW1lcnM6IFtdLAoKCWZ4OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgcHJvcCApewoJCXRoaXMub3B0aW9ucyA9IG9wdGlvbnM7CgkJdGhpcy5lbGVtID0gZWxlbTsKCQl0aGlzLnByb3AgPSBwcm9wOwoKCQlpZiAoICFvcHRpb25zLm9yaWcgKQoJCQlvcHRpb25zLm9yaWcgPSB7fTsKCX0KCn0pOwoKalF1ZXJ5LmZ4LnByb3RvdHlwZSA9IHsKCgkvLyBTaW1wbGUgZnVuY3Rpb24gZm9yIHNldHRpbmcgYSBzdHlsZSB2YWx1ZQoJdXBkYXRlOiBmdW5jdGlvbigpewoJCWlmICggdGhpcy5vcHRpb25zLnN0ZXAgKQoJCQl0aGlzLm9wdGlvbnMuc3RlcC5jYWxsKCB0aGlzLmVsZW0sIHRoaXMubm93LCB0aGlzICk7CgoJCShqUXVlcnkuZnguc3RlcFt0aGlzLnByb3BdIHx8IGpRdWVyeS5meC5zdGVwLl9kZWZhdWx0KSggdGhpcyApOwoKCQkvLyBTZXQgZGlzcGxheSBwcm9wZXJ0eSB0byBibG9jayBmb3IgaGVpZ2h0L3dpZHRoIGFuaW1hdGlvbnMKCQlpZiAoICggdGhpcy5wcm9wID09ICJoZWlnaHQiIHx8IHRoaXMucHJvcCA9PSAid2lkdGgiICkgJiYgdGhpcy5lbGVtLnN0eWxlICkKCQkJdGhpcy5lbGVtLnN0eWxlLmRpc3BsYXkgPSAiYmxvY2siOwoJfSwKCgkvLyBHZXQgdGhlIGN1cnJlbnQgc2l6ZQoJY3VyOiBmdW5jdGlvbihmb3JjZSl7CgkJaWYgKCB0aGlzLmVsZW1bdGhpcy5wcm9wXSAhPSBudWxsICYmICghdGhpcy5lbGVtLnN0eWxlIHx8IHRoaXMuZWxlbS5zdHlsZVt0aGlzLnByb3BdID09IG51bGwpICkKCQkJcmV0dXJuIHRoaXMuZWxlbVsgdGhpcy5wcm9wIF07CgoJCXZhciByID0gcGFyc2VGbG9hdChqUXVlcnkuY3NzKHRoaXMuZWxlbSwgdGhpcy5wcm9wLCBmb3JjZSkpOwoJCXJldHVybiByICYmIHIgPiAtMTAwMDAgPyByIDogcGFyc2VGbG9hdChqUXVlcnkuY3VyQ1NTKHRoaXMuZWxlbSwgdGhpcy5wcm9wKSkgfHwgMDsKCX0sCgoJLy8gU3RhcnQgYW4gYW5pbWF0aW9uIGZyb20gb25lIG51bWJlciB0byBhbm90aGVyCgljdXN0b206IGZ1bmN0aW9uKGZyb20sIHRvLCB1bml0KXsKCQl0aGlzLnN0YXJ0VGltZSA9IG5vdygpOwoJCXRoaXMuc3RhcnQgPSBmcm9tOwoJCXRoaXMuZW5kID0gdG87CgkJdGhpcy51bml0ID0gdW5pdCB8fCB0aGlzLnVuaXQgfHwgInB4IjsKCQl0aGlzLm5vdyA9IHRoaXMuc3RhcnQ7CgkJdGhpcy5wb3MgPSB0aGlzLnN0YXRlID0gMDsKCgkJdmFyIHNlbGYgPSB0aGlzOwoJCWZ1bmN0aW9uIHQoZ290b0VuZCl7CgkJCXJldHVybiBzZWxmLnN0ZXAoZ290b0VuZCk7CgkJfQoKCQl0LmVsZW0gPSB0aGlzLmVsZW07CgoJCWlmICggdCgpICYmIGpRdWVyeS50aW1lcnMucHVzaCh0KSAmJiAhdGltZXJJZCApIHsKCQkJdGltZXJJZCA9IHNldEludGVydmFsKGZ1bmN0aW9uKCl7CgkJCQl2YXIgdGltZXJzID0galF1ZXJ5LnRpbWVyczsKCgkJCQlmb3IgKCB2YXIgaSA9IDA7IGkgPCB0aW1lcnMubGVuZ3RoOyBpKysgKQoJCQkJCWlmICggIXRpbWVyc1tpXSgpICkKCQkJCQkJdGltZXJzLnNwbGljZShpLS0sIDEpOwoKCQkJCWlmICggIXRpbWVycy5sZW5ndGggKSB7CgkJCQkJY2xlYXJJbnRlcnZhbCggdGltZXJJZCApOwoJCQkJCXRpbWVySWQgPSB1bmRlZmluZWQ7CgkJCQl9CgkJCX0sIDEzKTsKCQl9Cgl9LAoKCS8vIFNpbXBsZSAnc2hvdycgZnVuY3Rpb24KCXNob3c6IGZ1bmN0aW9uKCl7CgkJLy8gUmVtZW1iZXIgd2hlcmUgd2Ugc3RhcnRlZCwgc28gdGhhdCB3ZSBjYW4gZ28gYmFjayB0byBpdCBsYXRlcgoJCXRoaXMub3B0aW9ucy5vcmlnW3RoaXMucHJvcF0gPSBqUXVlcnkuYXR0ciggdGhpcy5lbGVtLnN0eWxlLCB0aGlzLnByb3AgKTsKCQl0aGlzLm9wdGlvbnMuc2hvdyA9IHRydWU7CgoJCS8vIEJlZ2luIHRoZSBhbmltYXRpb24KCQkvLyBNYWtlIHN1cmUgdGhhdCB3ZSBzdGFydCBhdCBhIHNtYWxsIHdpZHRoL2hlaWdodCB0byBhdm9pZCBhbnkKCQkvLyBmbGFzaCBvZiBjb250ZW50CgkJdGhpcy5jdXN0b20odGhpcy5wcm9wID09ICJ3aWR0aCIgfHwgdGhpcy5wcm9wID09ICJoZWlnaHQiID8gMSA6IDAsIHRoaXMuY3VyKCkpOwoKCQkvLyBTdGFydCBieSBzaG93aW5nIHRoZSBlbGVtZW50CgkJalF1ZXJ5KHRoaXMuZWxlbSkuc2hvdygpOwoJfSwKCgkvLyBTaW1wbGUgJ2hpZGUnIGZ1bmN0aW9uCgloaWRlOiBmdW5jdGlvbigpewoJCS8vIFJlbWVtYmVyIHdoZXJlIHdlIHN0YXJ0ZWQsIHNvIHRoYXQgd2UgY2FuIGdvIGJhY2sgdG8gaXQgbGF0ZXIKCQl0aGlzLm9wdGlvbnMub3JpZ1t0aGlzLnByb3BdID0galF1ZXJ5LmF0dHIoIHRoaXMuZWxlbS5zdHlsZSwgdGhpcy5wcm9wICk7CgkJdGhpcy5vcHRpb25zLmhpZGUgPSB0cnVlOwoKCQkvLyBCZWdpbiB0aGUgYW5pbWF0aW9uCgkJdGhpcy5jdXN0b20odGhpcy5jdXIoKSwgMCk7Cgl9LAoKCS8vIEVhY2ggc3RlcCBvZiBhbiBhbmltYXRpb24KCXN0ZXA6IGZ1bmN0aW9uKGdvdG9FbmQpewoJCXZhciB0ID0gbm93KCk7CgoJCWlmICggZ290b0VuZCB8fCB0ID49IHRoaXMub3B0aW9ucy5kdXJhdGlvbiArIHRoaXMuc3RhcnRUaW1lICkgewoJCQl0aGlzLm5vdyA9IHRoaXMuZW5kOwoJCQl0aGlzLnBvcyA9IHRoaXMuc3RhdGUgPSAxOwoJCQl0aGlzLnVwZGF0ZSgpOwoKCQkJdGhpcy5vcHRpb25zLmN1ckFuaW1bIHRoaXMucHJvcCBdID0gdHJ1ZTsKCgkJCXZhciBkb25lID0gdHJ1ZTsKCQkJZm9yICggdmFyIGkgaW4gdGhpcy5vcHRpb25zLmN1ckFuaW0gKQoJCQkJaWYgKCB0aGlzLm9wdGlvbnMuY3VyQW5pbVtpXSAhPT0gdHJ1ZSApCgkJCQkJZG9uZSA9IGZhbHNlOwoKCQkJaWYgKCBkb25lICkgewoJCQkJaWYgKCB0aGlzLm9wdGlvbnMuZGlzcGxheSAhPSBudWxsICkgewoJCQkJCS8vIFJlc2V0IHRoZSBvdmVyZmxvdwoJCQkJCXRoaXMuZWxlbS5zdHlsZS5vdmVyZmxvdyA9IHRoaXMub3B0aW9ucy5vdmVyZmxvdzsKCgkJCQkJLy8gUmVzZXQgdGhlIGRpc3BsYXkKCQkJCQl0aGlzLmVsZW0uc3R5bGUuZGlzcGxheSA9IHRoaXMub3B0aW9ucy5kaXNwbGF5OwoJCQkJCWlmICggalF1ZXJ5LmNzcyh0aGlzLmVsZW0sICJkaXNwbGF5IikgPT0gIm5vbmUiICkKCQkJCQkJdGhpcy5lbGVtLnN0eWxlLmRpc3BsYXkgPSAiYmxvY2siOwoJCQkJfQoKCQkJCS8vIEhpZGUgdGhlIGVsZW1lbnQgaWYgdGhlICJoaWRlIiBvcGVyYXRpb24gd2FzIGRvbmUKCQkJCWlmICggdGhpcy5vcHRpb25zLmhpZGUgKQoJCQkJCWpRdWVyeSh0aGlzLmVsZW0pLmhpZGUoKTsKCgkJCQkvLyBSZXNldCB0aGUgcHJvcGVydGllcywgaWYgdGhlIGl0ZW0gaGFzIGJlZW4gaGlkZGVuIG9yIHNob3duCgkJCQlpZiAoIHRoaXMub3B0aW9ucy5oaWRlIHx8IHRoaXMub3B0aW9ucy5zaG93ICkKCQkJCQlmb3IgKCB2YXIgcCBpbiB0aGlzLm9wdGlvbnMuY3VyQW5pbSApCgkJCQkJCWpRdWVyeS5hdHRyKHRoaXMuZWxlbS5zdHlsZSwgcCwgdGhpcy5vcHRpb25zLm9yaWdbcF0pOwoJCQkJCQoJCQkJLy8gRXhlY3V0ZSB0aGUgY29tcGxldGUgZnVuY3Rpb24KCQkJCXRoaXMub3B0aW9ucy5jb21wbGV0ZS5jYWxsKCB0aGlzLmVsZW0gKTsKCQkJfQoKCQkJcmV0dXJuIGZhbHNlOwoJCX0gZWxzZSB7CgkJCXZhciBuID0gdCAtIHRoaXMuc3RhcnRUaW1lOwoJCQl0aGlzLnN0YXRlID0gbiAvIHRoaXMub3B0aW9ucy5kdXJhdGlvbjsKCgkJCS8vIFBlcmZvcm0gdGhlIGVhc2luZyBmdW5jdGlvbiwgZGVmYXVsdHMgdG8gc3dpbmcKCQkJdGhpcy5wb3MgPSBqUXVlcnkuZWFzaW5nW3RoaXMub3B0aW9ucy5lYXNpbmcgfHwgKGpRdWVyeS5lYXNpbmcuc3dpbmcgPyAic3dpbmciIDogImxpbmVhciIpXSh0aGlzLnN0YXRlLCBuLCAwLCAxLCB0aGlzLm9wdGlvbnMuZHVyYXRpb24pOwoJCQl0aGlzLm5vdyA9IHRoaXMuc3RhcnQgKyAoKHRoaXMuZW5kIC0gdGhpcy5zdGFydCkgKiB0aGlzLnBvcyk7CgoJCQkvLyBQZXJmb3JtIHRoZSBuZXh0IHN0ZXAgb2YgdGhlIGFuaW1hdGlvbgoJCQl0aGlzLnVwZGF0ZSgpOwoJCX0KCgkJcmV0dXJuIHRydWU7Cgl9Cgp9OwoKalF1ZXJ5LmV4dGVuZCggalF1ZXJ5LmZ4LCB7CglzcGVlZHM6ewoJCXNsb3c6IDYwMCwKIAkJZmFzdDogMjAwLAogCQkvLyBEZWZhdWx0IHNwZWVkCiAJCV9kZWZhdWx0OiA0MDAKCX0sCglzdGVwOiB7CgoJCW9wYWNpdHk6IGZ1bmN0aW9uKGZ4KXsKCQkJalF1ZXJ5LmF0dHIoZnguZWxlbS5zdHlsZSwgIm9wYWNpdHkiLCBmeC5ub3cpOwoJCX0sCgoJCV9kZWZhdWx0OiBmdW5jdGlvbihmeCl7CgkJCWlmICggZnguZWxlbS5zdHlsZSAmJiBmeC5lbGVtLnN0eWxlWyBmeC5wcm9wIF0gIT0gbnVsbCApCgkJCQlmeC5lbGVtLnN0eWxlWyBmeC5wcm9wIF0gPSBmeC5ub3cgKyBmeC51bml0OwoJCQllbHNlCgkJCQlmeC5lbGVtWyBmeC5wcm9wIF0gPSBmeC5ub3c7CgkJfQoJfQp9KTsKaWYgKCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbImdldEJvdW5kaW5nQ2xpZW50UmVjdCJdICkKCWpRdWVyeS5mbi5vZmZzZXQgPSBmdW5jdGlvbigpIHsKCQlpZiAoICF0aGlzWzBdICkgcmV0dXJuIHsgdG9wOiAwLCBsZWZ0OiAwIH07CgkJaWYgKCB0aGlzWzBdID09PSB0aGlzWzBdLm93bmVyRG9jdW1lbnQuYm9keSApIHJldHVybiBqUXVlcnkub2Zmc2V0LmJvZHlPZmZzZXQoIHRoaXNbMF0gKTsKCQl2YXIgYm94ICA9IHRoaXNbMF0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIGRvYyA9IHRoaXNbMF0ub3duZXJEb2N1bWVudCwgYm9keSA9IGRvYy5ib2R5LCBkb2NFbGVtID0gZG9jLmRvY3VtZW50RWxlbWVudCwKCQkJY2xpZW50VG9wID0gZG9jRWxlbS5jbGllbnRUb3AgfHwgYm9keS5jbGllbnRUb3AgfHwgMCwgY2xpZW50TGVmdCA9IGRvY0VsZW0uY2xpZW50TGVmdCB8fCBib2R5LmNsaWVudExlZnQgfHwgMCwKCQkJdG9wICA9IGJveC50b3AgICsgKHNlbGYucGFnZVlPZmZzZXQgfHwgalF1ZXJ5LmJveE1vZGVsICYmIGRvY0VsZW0uc2Nyb2xsVG9wICB8fCBib2R5LnNjcm9sbFRvcCApIC0gY2xpZW50VG9wLAoJCQlsZWZ0ID0gYm94LmxlZnQgKyAoc2VsZi5wYWdlWE9mZnNldCB8fCBqUXVlcnkuYm94TW9kZWwgJiYgZG9jRWxlbS5zY3JvbGxMZWZ0IHx8IGJvZHkuc2Nyb2xsTGVmdCkgLSBjbGllbnRMZWZ0OwoJCXJldHVybiB7IHRvcDogdG9wLCBsZWZ0OiBsZWZ0IH07Cgl9OwplbHNlIAoJalF1ZXJ5LmZuLm9mZnNldCA9IGZ1bmN0aW9uKCkgewoJCWlmICggIXRoaXNbMF0gKSByZXR1cm4geyB0b3A6IDAsIGxlZnQ6IDAgfTsKCQlpZiAoIHRoaXNbMF0gPT09IHRoaXNbMF0ub3duZXJEb2N1bWVudC5ib2R5ICkgcmV0dXJuIGpRdWVyeS5vZmZzZXQuYm9keU9mZnNldCggdGhpc1swXSApOwoJCWpRdWVyeS5vZmZzZXQuaW5pdGlhbGl6ZWQgfHwgalF1ZXJ5Lm9mZnNldC5pbml0aWFsaXplKCk7CgoJCXZhciBlbGVtID0gdGhpc1swXSwgb2Zmc2V0UGFyZW50ID0gZWxlbS5vZmZzZXRQYXJlbnQsIHByZXZPZmZzZXRQYXJlbnQgPSBlbGVtLAoJCQlkb2MgPSBlbGVtLm93bmVyRG9jdW1lbnQsIGNvbXB1dGVkU3R5bGUsIGRvY0VsZW0gPSBkb2MuZG9jdW1lbnRFbGVtZW50LAoJCQlib2R5ID0gZG9jLmJvZHksIGRlZmF1bHRWaWV3ID0gZG9jLmRlZmF1bHRWaWV3LAoJCQlwcmV2Q29tcHV0ZWRTdHlsZSA9IGRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGUoZWxlbSwgbnVsbCksCgkJCXRvcCA9IGVsZW0ub2Zmc2V0VG9wLCBsZWZ0ID0gZWxlbS5vZmZzZXRMZWZ0OwoKCQl3aGlsZSAoIChlbGVtID0gZWxlbS5wYXJlbnROb2RlKSAmJiBlbGVtICE9PSBib2R5ICYmIGVsZW0gIT09IGRvY0VsZW0gKSB7CgkJCWNvbXB1dGVkU3R5bGUgPSBkZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKGVsZW0sIG51bGwpOwoJCQl0b3AgLT0gZWxlbS5zY3JvbGxUb3AsIGxlZnQgLT0gZWxlbS5zY3JvbGxMZWZ0OwoJCQlpZiAoIGVsZW0gPT09IG9mZnNldFBhcmVudCApIHsKCQkJCXRvcCArPSBlbGVtLm9mZnNldFRvcCwgbGVmdCArPSBlbGVtLm9mZnNldExlZnQ7CgkJCQlpZiAoIGpRdWVyeS5vZmZzZXQuZG9lc05vdEFkZEJvcmRlciAmJiAhKGpRdWVyeS5vZmZzZXQuZG9lc0FkZEJvcmRlckZvclRhYmxlQW5kQ2VsbHMgJiYgL150KGFibGV8ZHxoKSQvaS50ZXN0KGVsZW0udGFnTmFtZSkpICkKCQkJCQl0b3AgICs9IHBhcnNlSW50KCBjb21wdXRlZFN0eWxlLmJvcmRlclRvcFdpZHRoLCAgMTApIHx8IDAsCgkJCQkJbGVmdCArPSBwYXJzZUludCggY29tcHV0ZWRTdHlsZS5ib3JkZXJMZWZ0V2lkdGgsIDEwKSB8fCAwOwoJCQkJcHJldk9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudCwgb2Zmc2V0UGFyZW50ID0gZWxlbS5vZmZzZXRQYXJlbnQ7CgkJCX0KCQkJaWYgKCBqUXVlcnkub2Zmc2V0LnN1YnRyYWN0c0JvcmRlckZvck92ZXJmbG93Tm90VmlzaWJsZSAmJiBjb21wdXRlZFN0eWxlLm92ZXJmbG93ICE9PSAidmlzaWJsZSIgKQoJCQkJdG9wICArPSBwYXJzZUludCggY29tcHV0ZWRTdHlsZS5ib3JkZXJUb3BXaWR0aCwgIDEwKSB8fCAwLAoJCQkJbGVmdCArPSBwYXJzZUludCggY29tcHV0ZWRTdHlsZS5ib3JkZXJMZWZ0V2lkdGgsIDEwKSB8fCAwOwoJCQlwcmV2Q29tcHV0ZWRTdHlsZSA9IGNvbXB1dGVkU3R5bGU7CgkJfQoKCQlpZiAoIHByZXZDb21wdXRlZFN0eWxlLnBvc2l0aW9uID09PSAicmVsYXRpdmUiIHx8IHByZXZDb21wdXRlZFN0eWxlLnBvc2l0aW9uID09PSAic3RhdGljIiApCgkJCXRvcCAgKz0gYm9keS5vZmZzZXRUb3AsCgkJCWxlZnQgKz0gYm9keS5vZmZzZXRMZWZ0OwoKCQlpZiAoIHByZXZDb21wdXRlZFN0eWxlLnBvc2l0aW9uID09PSAiZml4ZWQiICkKCQkJdG9wICArPSBNYXRoLm1heChkb2NFbGVtLnNjcm9sbFRvcCwgYm9keS5zY3JvbGxUb3ApLAoJCQlsZWZ0ICs9IE1hdGgubWF4KGRvY0VsZW0uc2Nyb2xsTGVmdCwgYm9keS5zY3JvbGxMZWZ0KTsKCgkJcmV0dXJuIHsgdG9wOiB0b3AsIGxlZnQ6IGxlZnQgfTsKCX07CgpqUXVlcnkub2Zmc2V0ID0gewoJaW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7CgkJaWYgKCB0aGlzLmluaXRpYWxpemVkICkgcmV0dXJuOwoJCXZhciBib2R5ID0gZG9jdW1lbnQuYm9keSwgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JyksIGlubmVyRGl2LCBjaGVja0RpdiwgdGFibGUsIHRkLCBydWxlcywgcHJvcCwgYm9keU1hcmdpblRvcCA9IGJvZHkuc3R5bGUubWFyZ2luVG9wLAoJCQlodG1sID0gJzxkaXYgc3R5bGU9InBvc2l0aW9uOmFic29sdXRlO3RvcDowO2xlZnQ6MDttYXJnaW46MDtib3JkZXI6NXB4IHNvbGlkICMwMDA7cGFkZGluZzowO3dpZHRoOjFweDtoZWlnaHQ6MXB4OyI+PGRpdj48L2Rpdj48L2Rpdj48dGFibGUgc3R5bGU9InBvc2l0aW9uOmFic29sdXRlO3RvcDowO2xlZnQ6MDttYXJnaW46MDtib3JkZXI6NXB4IHNvbGlkICMwMDA7cGFkZGluZzowO3dpZHRoOjFweDtoZWlnaHQ6MXB4OyIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj48dHI+PHRkPjwvdGQ+PC90cj48L3RhYmxlPic7CgoJCXJ1bGVzID0geyBwb3NpdGlvbjogJ2Fic29sdXRlJywgdG9wOiAwLCBsZWZ0OiAwLCBtYXJnaW46IDAsIGJvcmRlcjogMCwgd2lkdGg6ICcxcHgnLCBoZWlnaHQ6ICcxcHgnLCB2aXNpYmlsaXR5OiAnaGlkZGVuJyB9OwoJCWZvciAoIHByb3AgaW4gcnVsZXMgKSBjb250YWluZXIuc3R5bGVbcHJvcF0gPSBydWxlc1twcm9wXTsKCgkJY29udGFpbmVyLmlubmVySFRNTCA9IGh0bWw7CgkJYm9keS5pbnNlcnRCZWZvcmUoY29udGFpbmVyLCBib2R5LmZpcnN0Q2hpbGQpOwoJCWlubmVyRGl2ID0gY29udGFpbmVyLmZpcnN0Q2hpbGQsIGNoZWNrRGl2ID0gaW5uZXJEaXYuZmlyc3RDaGlsZCwgdGQgPSBpbm5lckRpdi5uZXh0U2libGluZy5maXJzdENoaWxkLmZpcnN0Q2hpbGQ7CgoJCXRoaXMuZG9lc05vdEFkZEJvcmRlciA9IChjaGVja0Rpdi5vZmZzZXRUb3AgIT09IDUpOwoJCXRoaXMuZG9lc0FkZEJvcmRlckZvclRhYmxlQW5kQ2VsbHMgPSAodGQub2Zmc2V0VG9wID09PSA1KTsKCgkJaW5uZXJEaXYuc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJywgaW5uZXJEaXYuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnOwoJCXRoaXMuc3VidHJhY3RzQm9yZGVyRm9yT3ZlcmZsb3dOb3RWaXNpYmxlID0gKGNoZWNrRGl2Lm9mZnNldFRvcCA9PT0gLTUpOwoKCQlib2R5LnN0eWxlLm1hcmdpblRvcCA9ICcxcHgnOwoJCXRoaXMuZG9lc05vdEluY2x1ZGVNYXJnaW5JbkJvZHlPZmZzZXQgPSAoYm9keS5vZmZzZXRUb3AgPT09IDApOwoJCWJvZHkuc3R5bGUubWFyZ2luVG9wID0gYm9keU1hcmdpblRvcDsKCgkJYm9keS5yZW1vdmVDaGlsZChjb250YWluZXIpOwoJCXRoaXMuaW5pdGlhbGl6ZWQgPSB0cnVlOwoJfSwKCglib2R5T2Zmc2V0OiBmdW5jdGlvbihib2R5KSB7CgkJalF1ZXJ5Lm9mZnNldC5pbml0aWFsaXplZCB8fCBqUXVlcnkub2Zmc2V0LmluaXRpYWxpemUoKTsKCQl2YXIgdG9wID0gYm9keS5vZmZzZXRUb3AsIGxlZnQgPSBib2R5Lm9mZnNldExlZnQ7CgkJaWYgKCBqUXVlcnkub2Zmc2V0LmRvZXNOb3RJbmNsdWRlTWFyZ2luSW5Cb2R5T2Zmc2V0ICkKCQkJdG9wICArPSBwYXJzZUludCggalF1ZXJ5LmN1ckNTUyhib2R5LCAnbWFyZ2luVG9wJywgIHRydWUpLCAxMCApIHx8IDAsCgkJCWxlZnQgKz0gcGFyc2VJbnQoIGpRdWVyeS5jdXJDU1MoYm9keSwgJ21hcmdpbkxlZnQnLCB0cnVlKSwgMTAgKSB8fCAwOwoJCXJldHVybiB7IHRvcDogdG9wLCBsZWZ0OiBsZWZ0IH07Cgl9Cn07CgoKalF1ZXJ5LmZuLmV4dGVuZCh7Cglwb3NpdGlvbjogZnVuY3Rpb24oKSB7CgkJdmFyIGxlZnQgPSAwLCB0b3AgPSAwLCByZXN1bHRzOwoKCQlpZiAoIHRoaXNbMF0gKSB7CgkJCS8vIEdldCAqcmVhbCogb2Zmc2V0UGFyZW50CgkJCXZhciBvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudCgpLAoKCQkJLy8gR2V0IGNvcnJlY3Qgb2Zmc2V0cwoJCQlvZmZzZXQgICAgICAgPSB0aGlzLm9mZnNldCgpLAoJCQlwYXJlbnRPZmZzZXQgPSAvXmJvZHl8aHRtbCQvaS50ZXN0KG9mZnNldFBhcmVudFswXS50YWdOYW1lKSA/IHsgdG9wOiAwLCBsZWZ0OiAwIH0gOiBvZmZzZXRQYXJlbnQub2Zmc2V0KCk7CgoJCQkvLyBTdWJ0cmFjdCBlbGVtZW50IG1hcmdpbnMKCQkJLy8gbm90ZTogd2hlbiBhbiBlbGVtZW50IGhhcyBtYXJnaW46IGF1dG8gdGhlIG9mZnNldExlZnQgYW5kIG1hcmdpbkxlZnQgCgkJCS8vIGFyZSB0aGUgc2FtZSBpbiBTYWZhcmkgY2F1c2luZyBvZmZzZXQubGVmdCB0byBpbmNvcnJlY3RseSBiZSAwCgkJCW9mZnNldC50b3AgIC09IG51bSggdGhpcywgJ21hcmdpblRvcCcgICk7CgkJCW9mZnNldC5sZWZ0IC09IG51bSggdGhpcywgJ21hcmdpbkxlZnQnICk7CgoJCQkvLyBBZGQgb2Zmc2V0UGFyZW50IGJvcmRlcnMKCQkJcGFyZW50T2Zmc2V0LnRvcCAgKz0gbnVtKCBvZmZzZXRQYXJlbnQsICdib3JkZXJUb3BXaWR0aCcgICk7CgkJCXBhcmVudE9mZnNldC5sZWZ0ICs9IG51bSggb2Zmc2V0UGFyZW50LCAnYm9yZGVyTGVmdFdpZHRoJyApOwoKCQkJLy8gU3VidHJhY3QgdGhlIHR3byBvZmZzZXRzCgkJCXJlc3VsdHMgPSB7CgkJCQl0b3A6ICBvZmZzZXQudG9wICAtIHBhcmVudE9mZnNldC50b3AsCgkJCQlsZWZ0OiBvZmZzZXQubGVmdCAtIHBhcmVudE9mZnNldC5sZWZ0CgkJCX07CgkJfQoKCQlyZXR1cm4gcmVzdWx0czsKCX0sCgoJb2Zmc2V0UGFyZW50OiBmdW5jdGlvbigpIHsKCQl2YXIgb2Zmc2V0UGFyZW50ID0gdGhpc1swXS5vZmZzZXRQYXJlbnQgfHwgZG9jdW1lbnQuYm9keTsKCQl3aGlsZSAoIG9mZnNldFBhcmVudCAmJiAoIS9eYm9keXxodG1sJC9pLnRlc3Qob2Zmc2V0UGFyZW50LnRhZ05hbWUpICYmIGpRdWVyeS5jc3Mob2Zmc2V0UGFyZW50LCAncG9zaXRpb24nKSA9PSAnc3RhdGljJykgKQoJCQlvZmZzZXRQYXJlbnQgPSBvZmZzZXRQYXJlbnQub2Zmc2V0UGFyZW50OwoJCXJldHVybiBqUXVlcnkob2Zmc2V0UGFyZW50KTsKCX0KfSk7CgoKLy8gQ3JlYXRlIHNjcm9sbExlZnQgYW5kIHNjcm9sbFRvcCBtZXRob2RzCmpRdWVyeS5lYWNoKCBbJ0xlZnQnLCAnVG9wJ10sIGZ1bmN0aW9uKGksIG5hbWUpIHsKCXZhciBtZXRob2QgPSAnc2Nyb2xsJyArIG5hbWU7CgkKCWpRdWVyeS5mblsgbWV0aG9kIF0gPSBmdW5jdGlvbih2YWwpIHsKCQlpZiAoIXRoaXNbMF0pIHJldHVybiBudWxsOwoKCQlyZXR1cm4gdmFsICE9PSB1bmRlZmluZWQgPwoKCQkJLy8gU2V0IHRoZSBzY3JvbGwgb2Zmc2V0CgkJCXRoaXMuZWFjaChmdW5jdGlvbigpIHsKCQkJCXRoaXMgPT0gd2luZG93IHx8IHRoaXMgPT0gZG9jdW1lbnQgPwoJCQkJCXdpbmRvdy5zY3JvbGxUbygKCQkJCQkJIWkgPyB2YWwgOiBqUXVlcnkod2luZG93KS5zY3JvbGxMZWZ0KCksCgkJCQkJCSBpID8gdmFsIDogalF1ZXJ5KHdpbmRvdykuc2Nyb2xsVG9wKCkKCQkJCQkpIDoKCQkJCQl0aGlzWyBtZXRob2QgXSA9IHZhbDsKCQkJfSkgOgoKCQkJLy8gUmV0dXJuIHRoZSBzY3JvbGwgb2Zmc2V0CgkJCXRoaXNbMF0gPT0gd2luZG93IHx8IHRoaXNbMF0gPT0gZG9jdW1lbnQgPwoJCQkJc2VsZlsgaSA/ICdwYWdlWU9mZnNldCcgOiAncGFnZVhPZmZzZXQnIF0gfHwKCQkJCQlqUXVlcnkuYm94TW9kZWwgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50WyBtZXRob2QgXSB8fAoJCQkJCWRvY3VtZW50LmJvZHlbIG1ldGhvZCBdIDoKCQkJCXRoaXNbMF1bIG1ldGhvZCBdOwoJfTsKfSk7Ci8vIENyZWF0ZSBpbm5lckhlaWdodCwgaW5uZXJXaWR0aCwgb3V0ZXJIZWlnaHQgYW5kIG91dGVyV2lkdGggbWV0aG9kcwpqUXVlcnkuZWFjaChbICJIZWlnaHQiLCAiV2lkdGgiIF0sIGZ1bmN0aW9uKGksIG5hbWUpewoKCXZhciB0bCA9IGkgPyAiTGVmdCIgIDogIlRvcCIsICAvLyB0b3Agb3IgbGVmdAoJCWJyID0gaSA/ICJSaWdodCIgOiAiQm90dG9tIiwgLy8gYm90dG9tIG9yIHJpZ2h0CgkJbG93ZXIgPSBuYW1lLnRvTG93ZXJDYXNlKCk7CgoJLy8gaW5uZXJIZWlnaHQgYW5kIGlubmVyV2lkdGgKCWpRdWVyeS5mblsiaW5uZXIiICsgbmFtZV0gPSBmdW5jdGlvbigpewoJCXJldHVybiB0aGlzWzBdID8KCQkJalF1ZXJ5LmNzcyggdGhpc1swXSwgbG93ZXIsIGZhbHNlLCAicGFkZGluZyIgKSA6CgkJCW51bGw7Cgl9OwoKCS8vIG91dGVySGVpZ2h0IGFuZCBvdXRlcldpZHRoCglqUXVlcnkuZm5bIm91dGVyIiArIG5hbWVdID0gZnVuY3Rpb24obWFyZ2luKSB7CgkJcmV0dXJuIHRoaXNbMF0gPwoJCQlqUXVlcnkuY3NzKCB0aGlzWzBdLCBsb3dlciwgZmFsc2UsIG1hcmdpbiA/ICJtYXJnaW4iIDogImJvcmRlciIgKSA6CgkJCW51bGw7Cgl9OwoJCgl2YXIgdHlwZSA9IG5hbWUudG9Mb3dlckNhc2UoKTsKCglqUXVlcnkuZm5bIHR5cGUgXSA9IGZ1bmN0aW9uKCBzaXplICkgewoJCS8vIEdldCB3aW5kb3cgd2lkdGggb3IgaGVpZ2h0CgkJcmV0dXJuIHRoaXNbMF0gPT0gd2luZG93ID8KCQkJLy8gRXZlcnlvbmUgZWxzZSB1c2UgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IG9yIGRvY3VtZW50LmJvZHkgZGVwZW5kaW5nIG9uIFF1aXJrcyB2cyBTdGFuZGFyZHMgbW9kZQoJCQlkb2N1bWVudC5jb21wYXRNb2RlID09ICJDU1MxQ29tcGF0IiAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbICJjbGllbnQiICsgbmFtZSBdIHx8CgkJCWRvY3VtZW50LmJvZHlbICJjbGllbnQiICsgbmFtZSBdIDoKCgkJCS8vIEdldCBkb2N1bWVudCB3aWR0aCBvciBoZWlnaHQKCQkJdGhpc1swXSA9PSBkb2N1bWVudCA/CgkJCQkvLyBFaXRoZXIgc2Nyb2xsW1dpZHRoL0hlaWdodF0gb3Igb2Zmc2V0W1dpZHRoL0hlaWdodF0sIHdoaWNoZXZlciBpcyBncmVhdGVyCgkJCQlNYXRoLm1heCgKCQkJCQlkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbImNsaWVudCIgKyBuYW1lXSwKCQkJCQlkb2N1bWVudC5ib2R5WyJzY3JvbGwiICsgbmFtZV0sIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudFsic2Nyb2xsIiArIG5hbWVdLAoJCQkJCWRvY3VtZW50LmJvZHlbIm9mZnNldCIgKyBuYW1lXSwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50WyJvZmZzZXQiICsgbmFtZV0KCQkJCSkgOgoKCQkJCS8vIEdldCBvciBzZXQgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50CgkJCQlzaXplID09PSB1bmRlZmluZWQgPwoJCQkJCS8vIEdldCB3aWR0aCBvciBoZWlnaHQgb24gdGhlIGVsZW1lbnQKCQkJCQkodGhpcy5sZW5ndGggPyBqUXVlcnkuY3NzKCB0aGlzWzBdLCB0eXBlICkgOiBudWxsKSA6CgoJCQkJCS8vIFNldCB0aGUgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50IChkZWZhdWx0IHRvIHBpeGVscyBpZiB2YWx1ZSBpcyB1bml0bGVzcykKCQkJCQl0aGlzLmNzcyggdHlwZSwgdHlwZW9mIHNpemUgPT09ICJzdHJpbmciID8gc2l6ZSA6IHNpemUgKyAicHgiICk7Cgl9OwoKfSk7Cn0pKCk7Cg==]]></data>
	</file>
	<file>
	  <filename>/js/nicEdit.js</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[LyogTmljRWRpdCAtIE1pY3JvIElubGluZSBXWVNJV1lHCiAqIENvcHlyaWdodCAyMDA3LTIwMDggQnJpYW4gS2lyY2hvZmYKICoKICogTmljRWRpdCBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIE1JVCBsaWNlbnNlCiAqIEZvciBtb3JlIGluZm9ybWF0aW9uIHZpc2l0IGh0dHA6Ly9uaWNlZGl0LmNvbS8KICogRG8gbm90IHJlbW92ZSB0aGlzIGNvcHlyaWdodCBtZXNzYWdlCiAqLw0KdmFyIGJrRXh0ZW5kID0gZnVuY3Rpb24oKXsKCXZhciBhcmdzID0gYXJndW1lbnRzOwoJaWYgKGFyZ3MubGVuZ3RoID09IDEpIGFyZ3MgPSBbdGhpcywgYXJnc1swXV07Cglmb3IgKHZhciBwcm9wIGluIGFyZ3NbMV0pIGFyZ3NbMF1bcHJvcF0gPSBhcmdzWzFdW3Byb3BdOwoJcmV0dXJuIGFyZ3NbMF07Cn07CmZ1bmN0aW9uIGJrQ2xhc3MoKSB7IH0KYmtDbGFzcy5wcm90b3R5cGUuY29uc3RydWN0ID0gZnVuY3Rpb24oKSB7fTsKYmtDbGFzcy5leHRlbmQgPSBmdW5jdGlvbihkZWYpIHsKICB2YXIgY2xhc3NEZWYgPSBmdW5jdGlvbigpIHsKICAgICAgaWYgKGFyZ3VtZW50c1swXSAhPT0gYmtDbGFzcykgeyByZXR1cm4gdGhpcy5jb25zdHJ1Y3QuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfQogIH07CiAgdmFyIHByb3RvID0gbmV3IHRoaXMoYmtDbGFzcyk7CiAgYmtFeHRlbmQocHJvdG8sZGVmKTsKICBjbGFzc0RlZi5wcm90b3R5cGUgPSBwcm90bzsKICBjbGFzc0RlZi5leHRlbmQgPSB0aGlzLmV4dGVuZDsgICAgICAKICByZXR1cm4gY2xhc3NEZWY7Cn07Cgp2YXIgYmtFbGVtZW50ID0gYmtDbGFzcy5leHRlbmQoewoJY29uc3RydWN0IDogZnVuY3Rpb24oZWxtLGQpIHsKCQlpZih0eXBlb2YoZWxtKSA9PSAic3RyaW5nIikgewoJCQllbG0gPSAoZCB8fCBkb2N1bWVudCkuY3JlYXRlRWxlbWVudChlbG0pOwoJCX0KCQllbG0gPSAkQksoZWxtKTsKCQlyZXR1cm4gZWxtOwoJfSwKCQoJYXBwZW5kVG8gOiBmdW5jdGlvbihlbG0pIHsKCQllbG0uYXBwZW5kQ2hpbGQodGhpcyk7CQoJCXJldHVybiB0aGlzOwoJfSwKCQoJYXBwZW5kQmVmb3JlIDogZnVuY3Rpb24oZWxtKSB7CgkJZWxtLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHRoaXMsZWxtKTsJCgkJcmV0dXJuIHRoaXM7Cgl9LAoJCglhZGRFdmVudCA6IGZ1bmN0aW9uKHR5cGUsIGZuKSB7CgkJYmtMaWIuYWRkRXZlbnQodGhpcyx0eXBlLGZuKTsKCQlyZXR1cm4gdGhpczsJCgl9LAoJCglzZXRDb250ZW50IDogZnVuY3Rpb24oYykgewoJCXRoaXMuaW5uZXJIVE1MID0gYzsKCQlyZXR1cm4gdGhpczsKCX0sCgkKCXBvcyA6IGZ1bmN0aW9uKCkgewoJCXZhciBjdXJsZWZ0ID0gY3VydG9wID0gMDsKCQl2YXIgbyA9IG9iaiA9IHRoaXM7CgkJaWYgKG9iai5vZmZzZXRQYXJlbnQpIHsKCQkJZG8gewoJCQkJY3VybGVmdCArPSBvYmoub2Zmc2V0TGVmdDsKCQkJCWN1cnRvcCArPSBvYmoub2Zmc2V0VG9wOwoJCQl9IHdoaWxlIChvYmogPSBvYmoub2Zmc2V0UGFyZW50KTsKCQl9CgkJdmFyIGIgPSAoIXdpbmRvdy5vcGVyYSkgPyBwYXJzZUludCh0aGlzLmdldFN0eWxlKCdib3JkZXItd2lkdGgnKSB8fCB0aGlzLnN0eWxlLmJvcmRlcikgfHwgMCA6IDA7CgkJcmV0dXJuIFtjdXJsZWZ0K2IsY3VydG9wK2IrdGhpcy5vZmZzZXRIZWlnaHRdOwoJfSwKCQoJbm9TZWxlY3QgOiBmdW5jdGlvbigpIHsKCQlia0xpYi5ub1NlbGVjdCh0aGlzKTsKCQlyZXR1cm4gdGhpczsKCX0sCgkKCXBhcmVudFRhZyA6IGZ1bmN0aW9uKHQpIHsKCQl2YXIgZWxtID0gdGhpczsKCQkgZG8gewoJCQlpZihlbG0gJiYgZWxtLm5vZGVOYW1lICYmIGVsbS5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpID09IHQpIHsKCQkJCXJldHVybiBlbG07CgkJCX0KCQkJZWxtID0gZWxtLnBhcmVudE5vZGU7CgkJfSB3aGlsZShlbG0pOwoJCXJldHVybiBmYWxzZTsKCX0sCgkKCWhhc0NsYXNzIDogZnVuY3Rpb24oY2xzKSB7CgkJcmV0dXJuIHRoaXMuY2xhc3NOYW1lLm1hdGNoKG5ldyBSZWdFeHAoJyhcXHN8XiluaWNFZGl0LScrY2xzKycoXFxzfCQpJykpOwoJfSwKCQoJYWRkQ2xhc3MgOiBmdW5jdGlvbihjbHMpIHsKCQlpZiAoIXRoaXMuaGFzQ2xhc3MoY2xzKSkgeyB0aGlzLmNsYXNzTmFtZSArPSAiIG5pY0VkaXQtIitjbHMgfTsKCQlyZXR1cm4gdGhpczsKCX0sCgkKCXJlbW92ZUNsYXNzIDogZnVuY3Rpb24oY2xzKSB7CgkJaWYgKHRoaXMuaGFzQ2xhc3MoY2xzKSkgewoJCQl0aGlzLmNsYXNzTmFtZSA9IHRoaXMuY2xhc3NOYW1lLnJlcGxhY2UobmV3IFJlZ0V4cCgnKFxcc3xeKW5pY0VkaXQtJytjbHMrJyhcXHN8JCknKSwnICcpOwoJCX0KCQlyZXR1cm4gdGhpczsKCX0sCgoJc2V0U3R5bGUgOiBmdW5jdGlvbihzdCkgewoJCXZhciBlbG1TdHlsZSA9IHRoaXMuc3R5bGU7CgkJZm9yKHZhciBpdG0gaW4gc3QpIHsKCQkJc3dpdGNoKGl0bSkgewoJCQkJY2FzZSAnZmxvYXQnOgoJCQkJCWVsbVN0eWxlWydjc3NGbG9hdCddID0gZWxtU3R5bGVbJ3N0eWxlRmxvYXQnXSA9IHN0W2l0bV07CgkJCQkJYnJlYWs7CgkJCQljYXNlICdvcGFjaXR5JzoKCQkJCQllbG1TdHlsZS5vcGFjaXR5ID0gc3RbaXRtXTsKCQkJCQllbG1TdHlsZS5maWx0ZXIgPSAiYWxwaGEob3BhY2l0eT0iICsgTWF0aC5yb3VuZChzdFtpdG1dKjEwMCkgKyAiKSI7IAoJCQkJCWJyZWFrOwoJCQkJY2FzZSAnY2xhc3NOYW1lJzoKCQkJCQl0aGlzLmNsYXNzTmFtZSA9IHN0W2l0bV07CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OgoJCQkJCS8vaWYoZG9jdW1lbnQuY29tcGF0TW9kZSB8fCBpdG0gIT0gImN1cnNvciIpIHsgLy8gTmFzdHkgV29ya2Fyb3VuZCBmb3IgSUUgNS41CgkJCQkJCWVsbVN0eWxlW2l0bV0gPSBzdFtpdG1dOwoJCQkJCS8vfQkJCgkJCX0KCQl9CgkJcmV0dXJuIHRoaXM7Cgl9LAoJCglnZXRTdHlsZSA6IGZ1bmN0aW9uKCBjc3NSdWxlLCBkICkgewoJCXZhciBkb2MgPSAoIWQpID8gZG9jdW1lbnQuZGVmYXVsdFZpZXcgOiBkOyAKCQlpZih0aGlzLm5vZGVUeXBlID09IDEpCgkJcmV0dXJuIChkb2MgJiYgZG9jLmdldENvbXB1dGVkU3R5bGUpID8gZG9jLmdldENvbXB1dGVkU3R5bGUoIHRoaXMsIG51bGwgKS5nZXRQcm9wZXJ0eVZhbHVlKGNzc1J1bGUpIDogdGhpcy5jdXJyZW50U3R5bGVbIGJrTGliLmNhbWVsaXplKGNzc1J1bGUpIF07Cgl9LAoJCglyZW1vdmUgOiBmdW5jdGlvbigpIHsKCQl0aGlzLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcyk7CgkJcmV0dXJuIHRoaXM7CQoJfSwKCQoJc2V0QXR0cmlidXRlcyA6IGZ1bmN0aW9uKGF0KSB7CgkJZm9yKHZhciBpdG0gaW4gYXQpIHsKCQkJdGhpc1tpdG1dID0gYXRbaXRtXTsKCQl9CgkJcmV0dXJuIHRoaXM7Cgl9Cn0pOwoKdmFyIGJrTGliID0gewoJaXNNU0lFIDogKG5hdmlnYXRvci5hcHBWZXJzaW9uLmluZGV4T2YoIk1TSUUiKSAhPSAtMSksCgkKCWFkZEV2ZW50IDogZnVuY3Rpb24ob2JqLCB0eXBlLCBmbikgewoJCShvYmouYWRkRXZlbnRMaXN0ZW5lcikgPyBvYmouYWRkRXZlbnRMaXN0ZW5lciggdHlwZSwgZm4sIGZhbHNlICkgOiBvYmouYXR0YWNoRXZlbnQoIm9uIit0eXBlLCBmbik7CQoJfSwKCQoJdG9BcnJheSA6IGZ1bmN0aW9uKGl0ZXJhYmxlKSB7CgkJdmFyIGxlbmd0aCA9IGl0ZXJhYmxlLmxlbmd0aCwgcmVzdWx0cyA9IG5ldyBBcnJheShsZW5ndGgpOwogICAgCXdoaWxlIChsZW5ndGgtLSkgeyByZXN1bHRzW2xlbmd0aF0gPSBpdGVyYWJsZVtsZW5ndGhdIH07CiAgICAJcmV0dXJuIHJlc3VsdHM7CQoJfSwKCQoJbm9TZWxlY3QgOiBmdW5jdGlvbihlbGVtZW50KSB7CgkJaWYoZWxlbWVudC5zZXRBdHRyaWJ1dGUgJiYgZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9ICdpbnB1dCcgJiYgZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICE9ICd0ZXh0YXJlYScpIHsKCQkJZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3Vuc2VsZWN0YWJsZScsJ29uJyk7CgkJfQoJCWZvcih2YXIgaT0wO2k8ZWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aDtpKyspIHsKCQkJYmtMaWIubm9TZWxlY3QoZWxlbWVudC5jaGlsZE5vZGVzW2ldKTsKCQl9Cgl9LAoJY2FtZWxpemUgOiBmdW5jdGlvbihzKSB7CgkJcmV0dXJuIHMucmVwbGFjZSgvXC0oLikvZywgZnVuY3Rpb24obSwgbCl7cmV0dXJuIGwudG9VcHBlckNhc2UoKX0pOwoJfSwKCWluQXJyYXkgOiBmdW5jdGlvbihhcnIsaXRlbSkgewoJICAgIHJldHVybiAoYmtMaWIuc2VhcmNoKGFycixpdGVtKSAhPSBudWxsKTsKCX0sCglzZWFyY2ggOiBmdW5jdGlvbihhcnIsaXRtKSB7CgkJZm9yKHZhciBpPTA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHsKCQkJaWYoYXJyW2ldID09IGl0bSkKCQkJCXJldHVybiBpOwoJCX0KCQlyZXR1cm4gbnVsbDsJCgl9LAoJY2FuY2VsRXZlbnQgOiBmdW5jdGlvbihlKSB7CgkJZSA9IGUgfHwgd2luZG93LmV2ZW50OwoJCWlmKGUucHJldmVudERlZmF1bHQgJiYgZS5zdG9wUHJvcGFnYXRpb24pIHsKCQkJZS5wcmV2ZW50RGVmYXVsdCgpOwoJCQllLnN0b3BQcm9wYWdhdGlvbigpOwoJCX0KCQlyZXR1cm4gZmFsc2U7Cgl9LAoJZG9tTG9hZCA6IFtdLAoJZG9tTG9hZGVkIDogZnVuY3Rpb24oKSB7CgkJaWYgKGFyZ3VtZW50cy5jYWxsZWUuZG9uZSkgcmV0dXJuOwoJCWFyZ3VtZW50cy5jYWxsZWUuZG9uZSA9IHRydWU7CgkJZm9yIChpID0gMDtpIDwgYmtMaWIuZG9tTG9hZC5sZW5ndGg7aSsrKSBia0xpYi5kb21Mb2FkW2ldKCk7Cgl9LAoJb25Eb21Mb2FkZWQgOiBmdW5jdGlvbihmaXJlVGhpcykgewoJCXRoaXMuZG9tTG9hZC5wdXNoKGZpcmVUaGlzKTsKCQlpZiAoZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcikgewoJCQlkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwgYmtMaWIuZG9tTG9hZGVkLCBudWxsKTsKCQl9IGVsc2UgaWYoYmtMaWIuaXNNU0lFKSB7CgkJCWRvY3VtZW50LndyaXRlKCI8c3R5bGU+Lm5pY0VkaXQtbWFpbiBwIHsgbWFyZ2luOiAwOyB9PC9zdHlsZT48c2NyIisiaXB0IGlkPV9faWVfb25sb2FkIGRlZmVyICIgKyAoKGxvY2F0aW9uLnByb3RvY29sID09ICJodHRwczoiKSA/ICJzcmM9J2phdmFzY3JpcHQ6dm9pZCgwKSciIDogInNyYz0vLzAiKSArICI+PFwvc2NyIisiaXB0PiIpOwoJCQkkQksoIl9faWVfb25sb2FkIikub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7CgkJCSAgICBpZiAodGhpcy5yZWFkeVN0YXRlID09ICJjb21wbGV0ZSIpe2JrTGliLmRvbUxvYWRlZCgpO30KCQkJfTsKCQl9CgkgICAgd2luZG93Lm9ubG9hZCA9IGJrTGliLmRvbUxvYWRlZDsKCX0KfTsKCmZ1bmN0aW9uICRCSyhlbG0pIHsKCWlmKHR5cGVvZihlbG0pID09ICJzdHJpbmciKSB7CgkJZWxtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxtKTsKCX0KCXJldHVybiAoZWxtICYmICFlbG0uYXBwZW5kVG8pID8gYmtFeHRlbmQoZWxtLGJrRWxlbWVudC5wcm90b3R5cGUpIDogZWxtOwp9Cgp2YXIgYmtFdmVudCA9IHsKCWFkZEV2ZW50IDogZnVuY3Rpb24oZXZUeXBlLCBldkZ1bmMpIHsKCQlpZihldkZ1bmMpIHsKCQkJdGhpcy5ldmVudExpc3QgPSB0aGlzLmV2ZW50TGlzdCB8fCB7fTsKCQkJdGhpcy5ldmVudExpc3RbZXZUeXBlXSA9IHRoaXMuZXZlbnRMaXN0W2V2VHlwZV0gfHwgW107CgkJCXRoaXMuZXZlbnRMaXN0W2V2VHlwZV0ucHVzaChldkZ1bmMpOwoJCX0KCQlyZXR1cm4gdGhpczsKCX0sCglmaXJlRXZlbnQgOiBmdW5jdGlvbigpIHsKCQl2YXIgYXJncyA9IGJrTGliLnRvQXJyYXkoYXJndW1lbnRzKSwgZXZUeXBlID0gYXJncy5zaGlmdCgpOwoJCWlmKHRoaXMuZXZlbnRMaXN0ICYmIHRoaXMuZXZlbnRMaXN0W2V2VHlwZV0pIHsKCQkJZm9yKHZhciBpPTA7aTx0aGlzLmV2ZW50TGlzdFtldlR5cGVdLmxlbmd0aDtpKyspIHsKCQkJCXRoaXMuZXZlbnRMaXN0W2V2VHlwZV1baV0uYXBwbHkodGhpcyxhcmdzKTsKCQkJfQoJCX0KCX0JCn07CgpmdW5jdGlvbiBfXyhzKSB7CglyZXR1cm4gczsKfQoKRnVuY3Rpb24ucHJvdG90eXBlLmNsb3N1cmUgPSBmdW5jdGlvbigpIHsKICB2YXIgX19tZXRob2QgPSB0aGlzLCBhcmdzID0gYmtMaWIudG9BcnJheShhcmd1bWVudHMpLCBvYmogPSBhcmdzLnNoaWZ0KCk7CiAgcmV0dXJuIGZ1bmN0aW9uKCkgeyBpZih0eXBlb2YoYmtMaWIpICE9ICd1bmRlZmluZWQnKSB7IHJldHVybiBfX21ldGhvZC5hcHBseShvYmosYXJncy5jb25jYXQoYmtMaWIudG9BcnJheShhcmd1bWVudHMpKSk7IH0gfTsKfQoJCkZ1bmN0aW9uLnByb3RvdHlwZS5jbG9zdXJlTGlzdGVuZXIgPSBmdW5jdGlvbigpIHsKICAJdmFyIF9fbWV0aG9kID0gdGhpcywgYXJncyA9IGJrTGliLnRvQXJyYXkoYXJndW1lbnRzKSwgb2JqZWN0ID0gYXJncy5zaGlmdCgpOyAKICAJcmV0dXJuIGZ1bmN0aW9uKGUpIHsgCiAgCWUgPSBlIHx8IHdpbmRvdy5ldmVudDsKICAJaWYoZS50YXJnZXQpIHsgdmFyIHRhcmdldCA9IGUudGFyZ2V0OyB9IGVsc2UgeyB2YXIgdGFyZ2V0ID0gIGUuc3JjRWxlbWVudCB9OwoJICAJcmV0dXJuIF9fbWV0aG9kLmFwcGx5KG9iamVjdCwgW2UsdGFyZ2V0XS5jb25jYXQoYXJncykgKTsgCgl9Owp9CQkKCg0KLyogU1RBUlQgQ09ORklHICovCg0KdmFyIG5pY0VkaXRvckNvbmZpZyA9IGJrQ2xhc3MuZXh0ZW5kKHsKCWJ1dHRvbnMgOiB7CgkJJ2JvbGQnIDoge25hbWUgOiBfXygnQ2xpY2sgdG8gQm9sZCcpLCBjb21tYW5kIDogJ0JvbGQnLCB0YWdzIDogWydCJywnU1RST05HJ10sIGNzcyA6IHsnZm9udC13ZWlnaHQnIDogJ2JvbGQnfSwga2V5IDogJ2InfSwKCQknaXRhbGljJyA6IHtuYW1lIDogX18oJ0NsaWNrIHRvIEl0YWxpYycpLCBjb21tYW5kIDogJ0l0YWxpYycsIHRhZ3MgOiBbJ0VNJywnSSddLCBjc3MgOiB7J2ZvbnQtc3R5bGUnIDogJ2l0YWxpYyd9LCBrZXkgOiAnaSd9LAoJCSd1bmRlcmxpbmUnIDoge25hbWUgOiBfXygnQ2xpY2sgdG8gVW5kZXJsaW5lJyksIGNvbW1hbmQgOiAnVW5kZXJsaW5lJywgdGFncyA6IFsnVSddLCBjc3MgOiB7J3RleHQtZGVjb3JhdGlvbicgOiAndW5kZXJsaW5lJ30sIGtleSA6ICd1J30sCgkJJ2xlZnQnIDoge25hbWUgOiBfXygnTGVmdCBBbGlnbicpLCBjb21tYW5kIDogJ2p1c3RpZnlsZWZ0Jywgbm9BY3RpdmUgOiB0cnVlfSwKCQknY2VudGVyJyA6IHtuYW1lIDogX18oJ0NlbnRlciBBbGlnbicpLCBjb21tYW5kIDogJ2p1c3RpZnljZW50ZXInLCBub0FjdGl2ZSA6IHRydWV9LAoJCSdyaWdodCcgOiB7bmFtZSA6IF9fKCdSaWdodCBBbGlnbicpLCBjb21tYW5kIDogJ2p1c3RpZnlyaWdodCcsIG5vQWN0aXZlIDogdHJ1ZX0sCgkJJ2p1c3RpZnknIDoge25hbWUgOiBfXygnSnVzdGlmeSBBbGlnbicpLCBjb21tYW5kIDogJ2p1c3RpZnlmdWxsJywgbm9BY3RpdmUgOiB0cnVlfSwKCQknb2wnIDoge25hbWUgOiBfXygnSW5zZXJ0IE9yZGVyZWQgTGlzdCcpLCBjb21tYW5kIDogJ2luc2VydG9yZGVyZWRsaXN0JywgdGFncyA6IFsnT0wnXX0sCgkJJ3VsJyA6IAl7bmFtZSA6IF9fKCdJbnNlcnQgVW5vcmRlcmVkIExpc3QnKSwgY29tbWFuZCA6ICdpbnNlcnR1bm9yZGVyZWRsaXN0JywgdGFncyA6IFsnVUwnXX0sCgkJJ3N1YnNjcmlwdCcgOiB7bmFtZSA6IF9fKCdDbGljayB0byBTdWJzY3JpcHQnKSwgY29tbWFuZCA6ICdzdWJzY3JpcHQnLCB0YWdzIDogWydTVUInXX0sCgkJJ3N1cGVyc2NyaXB0JyA6IHtuYW1lIDogX18oJ0NsaWNrIHRvIFN1cGVyc2NyaXB0JyksIGNvbW1hbmQgOiAnc3VwZXJzY3JpcHQnLCB0YWdzIDogWydTVVAnXX0sCgkJJ3N0cmlrZXRocm91Z2gnIDoge25hbWUgOiBfXygnQ2xpY2sgdG8gU3RyaWtlIFRocm91Z2gnKSwgY29tbWFuZCA6ICdzdHJpa2VUaHJvdWdoJywgY3NzIDogeyd0ZXh0LWRlY29yYXRpb24nIDogJ2xpbmUtdGhyb3VnaCd9fSwKCQkncmVtb3ZlZm9ybWF0JyA6IHtuYW1lIDogX18oJ1JlbW92ZSBGb3JtYXR0aW5nJyksIGNvbW1hbmQgOiAncmVtb3ZlZm9ybWF0Jywgbm9BY3RpdmUgOiB0cnVlfSwKCQknaW5kZW50JyA6IHtuYW1lIDogX18oJ0luZGVudCBUZXh0JyksIGNvbW1hbmQgOiAnaW5kZW50Jywgbm9BY3RpdmUgOiB0cnVlfSwKCQknb3V0ZGVudCcgOiB7bmFtZSA6IF9fKCdSZW1vdmUgSW5kZW50JyksIGNvbW1hbmQgOiAnb3V0ZGVudCcsIG5vQWN0aXZlIDogdHJ1ZX0sCgkJJ2hyJyA6IHtuYW1lIDogX18oJ0hvcml6b250YWwgUnVsZScpLCBjb21tYW5kIDogJ2luc2VydEhvcml6b250YWxSdWxlJywgbm9BY3RpdmUgOiB0cnVlfQoJfSwKCWljb25zUGF0aCA6ICcuLi9uaWNFZGl0b3JJY29ucy5naWYnLAoJYnV0dG9uTGlzdCA6IFsnc2F2ZScsJ2JvbGQnLCdpdGFsaWMnLCd1bmRlcmxpbmUnLCdsZWZ0JywnY2VudGVyJywncmlnaHQnLCdqdXN0aWZ5Jywnb2wnLCd1bCcsJ2ZvbnRTaXplJywnZm9udEZhbWlseScsJ2ZvbnRGb3JtYXQnLCdpbmRlbnQnLCdvdXRkZW50JywnaW1hZ2UnLCd1cGxvYWQnLCdsaW5rJywndW5saW5rJywnZm9yZWNvbG9yJywnYmdjb2xvciddLAoJaWNvbkxpc3QgOiB7ImJnY29sb3IiOjEsImZvcmVjb2xvciI6MiwiYm9sZCI6MywiY2VudGVyIjo0LCJociI6NSwiaW5kZW50Ijo2LCJpdGFsaWMiOjcsImp1c3RpZnkiOjgsImxlZnQiOjksIm9sIjoxMCwib3V0ZGVudCI6MTEsInJlbW92ZWZvcm1hdCI6MTIsInJpZ2h0IjoxMywic2F2ZSI6MjQsInN0cmlrZXRocm91Z2giOjE1LCJzdWJzY3JpcHQiOjE2LCJzdXBlcnNjcmlwdCI6MTcsInVsIjoxOCwidW5kZXJsaW5lIjoxOSwiaW1hZ2UiOjIwLCJsaW5rIjoyMSwidW5saW5rIjoyMiwiY2xvc2UiOjIzLCJhcnJvdyI6MjV9CgkKfSk7Ci8qIEVORCBDT05GSUcgKi8NCgoKdmFyIG5pY0VkaXRvcnMgPSB7CgluaWNQbHVnaW5zIDogW10sCgllZGl0b3JzIDogW10sCgkKCXJlZ2lzdGVyUGx1Z2luIDogZnVuY3Rpb24ocGx1Z2luLG9wdGlvbnMpIHsKCQl0aGlzLm5pY1BsdWdpbnMucHVzaCh7cCA6IHBsdWdpbiwgbyA6IG9wdGlvbnN9KTsKCX0sCgoJYWxsVGV4dEFyZWFzIDogZnVuY3Rpb24obmljT3B0aW9ucykgewoJCXZhciB0ZXh0YXJlYXMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgidGV4dGFyZWEiKTsKCQlmb3IodmFyIGk9MDtpPHRleHRhcmVhcy5sZW5ndGg7aSsrKSB7CgkJCW5pY0VkaXRvcnMuZWRpdG9ycy5wdXNoKG5ldyBuaWNFZGl0b3IobmljT3B0aW9ucykucGFuZWxJbnN0YW5jZSh0ZXh0YXJlYXNbaV0pKTsKCQl9CgkJcmV0dXJuIG5pY0VkaXRvcnMuZWRpdG9yczsKCX0sCgkKCWZpbmRFZGl0b3IgOiBmdW5jdGlvbihlKSB7CgkJdmFyIGVkaXRvcnMgPSBuaWNFZGl0b3JzLmVkaXRvcnM7CgkJZm9yKHZhciBpPTA7aTxlZGl0b3JzLmxlbmd0aDtpKyspIHsKCQkJaWYoZWRpdG9yc1tpXS5pbnN0YW5jZUJ5SWQoZSkpIHsKCQkJCXJldHVybiBlZGl0b3JzW2ldLmluc3RhbmNlQnlJZChlKTsKCQkJfQoJCX0KCX0KfTsKCgp2YXIgbmljRWRpdG9yID0gYmtDbGFzcy5leHRlbmQoewoJY29uc3RydWN0IDogZnVuY3Rpb24obykgewoJCXRoaXMub3B0aW9ucyA9IG5ldyBuaWNFZGl0b3JDb25maWcoKTsKCQlia0V4dGVuZCh0aGlzLm9wdGlvbnMsbyk7CgkJdGhpcy5uaWNJbnN0YW5jZXMgPSBuZXcgQXJyYXkoKTsKCQl0aGlzLmxvYWRlZFBsdWdpbnMgPSBuZXcgQXJyYXkoKTsKCQkKCQl2YXIgcGx1Z2lucyA9IG5pY0VkaXRvcnMubmljUGx1Z2luczsKCQlmb3IodmFyIGk9MDtpPHBsdWdpbnMubGVuZ3RoO2krKykgewoJCQl0aGlzLmxvYWRlZFBsdWdpbnMucHVzaChuZXcgcGx1Z2luc1tpXS5wKHRoaXMscGx1Z2luc1tpXS5vKSk7CgkJfQoJCW5pY0VkaXRvcnMuZWRpdG9ycy5wdXNoKHRoaXMpOwoJCWJrTGliLmFkZEV2ZW50KGRvY3VtZW50LmJvZHksJ21vdXNlZG93bicsIHRoaXMuc2VsZWN0Q2hlY2suY2xvc3VyZUxpc3RlbmVyKHRoaXMpICk7Cgl9LAoJCglwYW5lbEluc3RhbmNlIDogZnVuY3Rpb24oZSxvKSB7CgkJZSA9IHRoaXMuY2hlY2tSZXBsYWNlKCRCSyhlKSk7CgkJdmFyIHBhbmVsRWxtID0gbmV3IGJrRWxlbWVudCgnRElWJykuc2V0U3R5bGUoe3dpZHRoIDogKHBhcnNlSW50KGUuZ2V0U3R5bGUoJ3dpZHRoJykpIHx8IGUuY2xpZW50V2lkdGgpKydweCd9KS5hcHBlbmRCZWZvcmUoZSk7CgkJdGhpcy5zZXRQYW5lbChwYW5lbEVsbSk7CgkJcmV0dXJuIHRoaXMuYWRkSW5zdGFuY2UoZSxvKTsJCgl9LAoKCWNoZWNrUmVwbGFjZSA6IGZ1bmN0aW9uKGUpIHsKCQl2YXIgciA9IG5pY0VkaXRvcnMuZmluZEVkaXRvcihlKTsKCQlpZihyKSB7CgkJCXIucmVtb3ZlSW5zdGFuY2UoZSk7CgkJCXIucmVtb3ZlUGFuZWwoKTsKCQl9CgkJcmV0dXJuIGU7Cgl9LAoKCWFkZEluc3RhbmNlIDogZnVuY3Rpb24oZSxvKSB7CgkJZSA9IHRoaXMuY2hlY2tSZXBsYWNlKCRCSyhlKSk7CgkJaWYoIGUuY29udGVudEVkaXRhYmxlIHx8ICEhd2luZG93Lm9wZXJhICkgewoJCQl2YXIgbmV3SW5zdGFuY2UgPSBuZXcgbmljRWRpdG9ySW5zdGFuY2UoZSxvLHRoaXMpOwoJCX0gZWxzZSB7CgkJCXZhciBuZXdJbnN0YW5jZSA9IG5ldyBuaWNFZGl0b3JJRnJhbWVJbnN0YW5jZShlLG8sdGhpcyk7CgkJfQoJCXRoaXMubmljSW5zdGFuY2VzLnB1c2gobmV3SW5zdGFuY2UpOwoJCXJldHVybiB0aGlzOwoJfSwKCQoJcmVtb3ZlSW5zdGFuY2UgOiBmdW5jdGlvbihlKSB7CgkJZSA9ICRCSyhlKTsKCQl2YXIgaW5zdGFuY2VzID0gdGhpcy5uaWNJbnN0YW5jZXM7CgkJZm9yKHZhciBpPTA7aTxpbnN0YW5jZXMubGVuZ3RoO2krKykgewkKCQkJaWYoaW5zdGFuY2VzW2ldLmUgPT0gZSkgewoJCQkJaW5zdGFuY2VzW2ldLnJlbW92ZSgpOwoJCQkJdGhpcy5uaWNJbnN0YW5jZXMuc3BsaWNlKGksMSk7CgkJCX0KCQl9Cgl9LAoKCXJlbW92ZVBhbmVsIDogZnVuY3Rpb24oZSkgewoJCWlmKHRoaXMubmljUGFuZWwpIHsKCQkJdGhpcy5uaWNQYW5lbC5yZW1vdmUoKTsKCQkJdGhpcy5uaWNQYW5lbCA9IG51bGw7CgkJfQkKCX0sCgoJaW5zdGFuY2VCeUlkIDogZnVuY3Rpb24oZSkgewoJCWUgPSAkQksoZSk7CgkJdmFyIGluc3RhbmNlcyA9IHRoaXMubmljSW5zdGFuY2VzOwoJCWZvcih2YXIgaT0wO2k8aW5zdGFuY2VzLmxlbmd0aDtpKyspIHsKCQkJaWYoaW5zdGFuY2VzW2ldLmUgPT0gZSkgewoJCQkJcmV0dXJuIGluc3RhbmNlc1tpXTsKCQkJfQoJCX0JCgl9LAoKCXNldFBhbmVsIDogZnVuY3Rpb24oZSkgewoJCXRoaXMubmljUGFuZWwgPSBuZXcgbmljRWRpdG9yUGFuZWwoJEJLKGUpLHRoaXMub3B0aW9ucyx0aGlzKTsKCQl0aGlzLmZpcmVFdmVudCgncGFuZWwnLHRoaXMubmljUGFuZWwpOwoJCXJldHVybiB0aGlzOwoJfSwKCQoJbmljQ29tbWFuZCA6IGZ1bmN0aW9uKGNtZCxhcmdzKSB7CQoJCWlmKHRoaXMuc2VsZWN0ZWRJbnN0YW5jZSkgewoJCQl0aGlzLnNlbGVjdGVkSW5zdGFuY2UubmljQ29tbWFuZChjbWQsYXJncyk7CgkJfQoJfSwKCQoJZ2V0SWNvbiA6IGZ1bmN0aW9uKGljb25OYW1lLG9wdGlvbnMpIHsKCQl2YXIgaWNvbiA9IHRoaXMub3B0aW9ucy5pY29uTGlzdFtpY29uTmFtZV07CgkJdmFyIGZpbGUgPSAob3B0aW9ucy5pY29uRmlsZXMpID8gb3B0aW9ucy5pY29uRmlsZXNbaWNvbk5hbWVdIDogJyc7CgkJcmV0dXJuIHtiYWNrZ3JvdW5kSW1hZ2UgOiAidXJsKCciKygoaWNvbikgPyB0aGlzLm9wdGlvbnMuaWNvbnNQYXRoIDogZmlsZSkrIicpIiwgYmFja2dyb3VuZFBvc2l0aW9uIDogKChpY29uKSA/ICgoaWNvbi0xKSotMTgpIDogMCkrJ3B4IDBweCd9OwkKCX0sCgkJCglzZWxlY3RDaGVjayA6IGZ1bmN0aW9uKGUsdCkgewoJCXZhciBmb3VuZCA9IGZhbHNlOwoJCWRvewoJCQlpZih0LmNsYXNzTmFtZSAmJiB0LmNsYXNzTmFtZS5pbmRleE9mKCduaWNFZGl0JykgIT0gLTEpIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCX0gd2hpbGUodCA9IHQucGFyZW50Tm9kZSk7CgkJdGhpcy5maXJlRXZlbnQoJ2JsdXInLHRoaXMuc2VsZWN0ZWRJbnN0YW5jZSx0KTsKCQl0aGlzLmxhc3RTZWxlY3RlZEluc3RhbmNlID0gdGhpcy5zZWxlY3RlZEluc3RhbmNlOwoJCXRoaXMuc2VsZWN0ZWRJbnN0YW5jZSA9IG51bGw7CgkJcmV0dXJuIGZhbHNlOwoJfQoJCn0pOwpuaWNFZGl0b3IgPSBuaWNFZGl0b3IuZXh0ZW5kKGJrRXZlbnQpOw0KCiAKdmFyIG5pY0VkaXRvckluc3RhbmNlID0gYmtDbGFzcy5leHRlbmQoewoJaXNTZWxlY3RlZCA6IGZhbHNlLAoJCgljb25zdHJ1Y3QgOiBmdW5jdGlvbihlLG9wdGlvbnMsbmljRWRpdG9yKSB7CgkJdGhpcy5uZSA9IG5pY0VkaXRvcjsKCQl0aGlzLmVsbSA9IHRoaXMuZSA9IGU7CgkJdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCQkKCQluZXdYID0gcGFyc2VJbnQoZS5nZXRTdHlsZSgnd2lkdGgnKSkgfHwgZS5jbGllbnRXaWR0aDsKCQluZXdZID0gcGFyc2VJbnQoZS5nZXRTdHlsZSgnaGVpZ2h0JykpIHx8IGUuY2xpZW50SGVpZ2h0OwoJCXRoaXMuaW5pdGlhbEhlaWdodCA9IG5ld1ktODsKCQkKCQl2YXIgaXNUZXh0YXJlYSA9IChlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT0gInRleHRhcmVhIik7CgkJaWYoaXNUZXh0YXJlYSB8fCB0aGlzLm9wdGlvbnMuaGFzUGFuZWwpIHsKCQkJdmFyIGllN3MgPSAoYmtMaWIuaXNNU0lFICYmICEoKHR5cGVvZiBkb2N1bWVudC5ib2R5LnN0eWxlLm1heEhlaWdodCAhPSAidW5kZWZpbmVkIikgJiYgZG9jdW1lbnQuY29tcGF0TW9kZSA9PSAiQ1NTMUNvbXBhdCIpKQoJCQl2YXIgcyA9IHt3aWR0aDogbmV3WCsncHgnLCBib3JkZXIgOiAnMXB4IHNvbGlkICNjY2MnLCBib3JkZXJUb3AgOiAwLCBvdmVyZmxvd1kgOiAnYXV0bycsIG92ZXJmbG93WDogJ2hpZGRlbicgfTsKCQkJc1soaWU3cykgPyAnaGVpZ2h0JyA6ICdtYXhIZWlnaHQnXSA9ICh0aGlzLm5lLm9wdGlvbnMubWF4SGVpZ2h0KSA/IHRoaXMubmUub3B0aW9ucy5tYXhIZWlnaHQrJ3B4JyA6IG51bGw7CgkJCXRoaXMuZWRpdG9yQ29udGFpbiA9IG5ldyBia0VsZW1lbnQoJ0RJVicpLnNldFN0eWxlKHMpLmFwcGVuZEJlZm9yZShlKTsKCQkJdmFyIGVkaXRvckVsbSA9IG5ldyBia0VsZW1lbnQoJ0RJVicpLnNldFN0eWxlKHt3aWR0aCA6IChuZXdYLTgpKydweCcsIG1hcmdpbjogJzRweCcsIG1pbkhlaWdodCA6IG5ld1krJ3B4J30pLmFkZENsYXNzKCdtYWluJykuYXBwZW5kVG8odGhpcy5lZGl0b3JDb250YWluKTsKCgkJCWUuc2V0U3R5bGUoe2Rpc3BsYXkgOiAnbm9uZSd9KTsKCQkJCQoJCQllZGl0b3JFbG0uaW5uZXJIVE1MID0gZS5pbm5lckhUTUw7CQkKCQkJaWYoaXNUZXh0YXJlYSkgewoJCQkJZWRpdG9yRWxtLnNldENvbnRlbnQoZS52YWx1ZSk7CgkJCQl0aGlzLmNvcHlFbG0gPSBlOwoJCQkJdmFyIGYgPSBlLnBhcmVudFRhZygnRk9STScpOwoJCQkJaWYoZikgeyBia0xpYi5hZGRFdmVudCggZiwgJ3N1Ym1pdCcsIHRoaXMuc2F2ZUNvbnRlbnQuY2xvc3VyZSh0aGlzKSk7IH0KCQkJfQoJCQllZGl0b3JFbG0uc2V0U3R5bGUoKGllN3MpID8ge2hlaWdodCA6IG5ld1krJ3B4J30gOiB7b3ZlcmZsb3c6ICdoaWRkZW4nfSk7CgkJCXRoaXMuZWxtID0gZWRpdG9yRWxtOwkKCQl9CgkJdGhpcy5uZS5hZGRFdmVudCgnYmx1cicsdGhpcy5ibHVyLmNsb3N1cmUodGhpcykpOwoKCQl0aGlzLmluaXQoKTsKCQl0aGlzLmJsdXIoKTsKCX0sCgkKCWluaXQgOiBmdW5jdGlvbigpIHsKCQl0aGlzLmVsbS5zZXRBdHRyaWJ1dGUoJ2NvbnRlbnRFZGl0YWJsZScsJ3RydWUnKTsJCgkJaWYodGhpcy5nZXRDb250ZW50KCkgPT0gIiIpIHsKCQkJdGhpcy5zZXRDb250ZW50KCc8YnIgLz4nKTsKCQl9CgkJdGhpcy5pbnN0YW5jZURvYyA9IGRvY3VtZW50LmRlZmF1bHRWaWV3OwoJCXRoaXMuZWxtLmFkZEV2ZW50KCdtb3VzZWRvd24nLHRoaXMuc2VsZWN0ZWQuY2xvc3VyZUxpc3RlbmVyKHRoaXMpKS5hZGRFdmVudCgna2V5cHJlc3MnLHRoaXMua2V5RG93bi5jbG9zdXJlTGlzdGVuZXIodGhpcykpLmFkZEV2ZW50KCdmb2N1cycsdGhpcy5zZWxlY3RlZC5jbG9zdXJlKHRoaXMpKS5hZGRFdmVudCgnYmx1cicsdGhpcy5ibHVyLmNsb3N1cmUodGhpcykpLmFkZEV2ZW50KCdrZXl1cCcsdGhpcy5zZWxlY3RlZC5jbG9zdXJlKHRoaXMpKTsKCQl0aGlzLm5lLmZpcmVFdmVudCgnYWRkJyx0aGlzKTsKCX0sCgkKCXJlbW92ZSA6IGZ1bmN0aW9uKCkgewoJCXRoaXMuc2F2ZUNvbnRlbnQoKTsKCQlpZih0aGlzLmNvcHlFbG0gfHwgdGhpcy5vcHRpb25zLmhhc1BhbmVsKSB7CgkJCXRoaXMuZWRpdG9yQ29udGFpbi5yZW1vdmUoKTsKCQkJdGhpcy5lLnNldFN0eWxlKHsnZGlzcGxheScgOiAnYmxvY2snfSk7CgkJCXRoaXMubmUucmVtb3ZlUGFuZWwoKTsKCQl9CgkJdGhpcy5kaXNhYmxlKCk7CgkJdGhpcy5uZS5maXJlRXZlbnQoJ3JlbW92ZScsdGhpcyk7Cgl9LAoJCglkaXNhYmxlIDogZnVuY3Rpb24oKSB7CgkJdGhpcy5lbG0uc2V0QXR0cmlidXRlKCdjb250ZW50RWRpdGFibGUnLCdmYWxzZScpOwoJfSwKCQoJZ2V0U2VsIDogZnVuY3Rpb24oKSB7CgkJcmV0dXJuICh3aW5kb3cuZ2V0U2VsZWN0aW9uKSA/IHdpbmRvdy5nZXRTZWxlY3Rpb24oKSA6IGRvY3VtZW50LnNlbGVjdGlvbjsJCgl9LAoJCglnZXRSbmcgOiBmdW5jdGlvbigpIHsKCQl2YXIgcyA9IHRoaXMuZ2V0U2VsKCk7CgkJaWYoIXMpIHsgcmV0dXJuIG51bGw7IH0KCQlyZXR1cm4gKHMucmFuZ2VDb3VudCA+IDApID8gcy5nZXRSYW5nZUF0KDApIDogcy5jcmVhdGVSYW5nZSgpOwoJfSwKCQoJc2VsUm5nIDogZnVuY3Rpb24ocm5nLHMpIHsKCQlpZih3aW5kb3cuZ2V0U2VsZWN0aW9uKSB7CgkJCXMucmVtb3ZlQWxsUmFuZ2VzKCk7CgkJCXMuYWRkUmFuZ2Uocm5nKTsKCQl9IGVsc2UgewoJCQlybmcuc2VsZWN0KCk7CgkJfQoJfSwKCQoJc2VsRWxtIDogZnVuY3Rpb24oKSB7CgkJdmFyIHIgPSB0aGlzLmdldFJuZygpOwoJCWlmKHIuc3RhcnRDb250YWluZXIpIHsKCQkJdmFyIGNvbnRhaW4gPSByLnN0YXJ0Q29udGFpbmVyOwoJCQlpZihyLmNsb25lQ29udGVudHMoKS5jaGlsZE5vZGVzLmxlbmd0aCA9PSAxKSB7CgkJCQlmb3IodmFyIGk9MDtpPGNvbnRhaW4uY2hpbGROb2Rlcy5sZW5ndGg7aSsrKSB7CgkJCQkJdmFyIHJuZyA9IGNvbnRhaW4uY2hpbGROb2Rlc1tpXS5vd25lckRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7CgkJCQkJcm5nLnNlbGVjdE5vZGUoY29udGFpbi5jaGlsZE5vZGVzW2ldKTsJCQkJCQoJCQkJCWlmKHIuY29tcGFyZUJvdW5kYXJ5UG9pbnRzKFJhbmdlLlNUQVJUX1RPX1NUQVJULHJuZykgIT0gMSAmJiAKCQkJCQkJci5jb21wYXJlQm91bmRhcnlQb2ludHMoUmFuZ2UuRU5EX1RPX0VORCxybmcpICE9IC0xKSB7CgkJCQkJCXJldHVybiAkQksoY29udGFpbi5jaGlsZE5vZGVzW2ldKTsKCQkJCQl9CgkJCQl9CgkJCX0KCQkJcmV0dXJuICRCSyhjb250YWluKTsKCQl9IGVsc2UgewoJCQlyZXR1cm4gJEJLKCh0aGlzLmdldFNlbCgpLnR5cGUgPT0gIkNvbnRyb2wiKSA/IHIuaXRlbSgwKSA6IHIucGFyZW50RWxlbWVudCgpKTsKCQl9Cgl9LAoJCglzYXZlUm5nIDogZnVuY3Rpb24oKSB7CgkJdGhpcy5zYXZlZFJhbmdlID0gdGhpcy5nZXRSbmcoKTsKCQl0aGlzLnNhdmVkU2VsID0gdGhpcy5nZXRTZWwoKTsKCX0sCgkKCXJlc3RvcmVSbmcgOiBmdW5jdGlvbigpIHsKCQlpZih0aGlzLnNhdmVkUmFuZ2UpIHsKCQkJdGhpcy5zZWxSbmcodGhpcy5zYXZlZFJhbmdlLHRoaXMuc2F2ZWRTZWwpOwoJCX0KCX0sCgkKCWtleURvd24gOiBmdW5jdGlvbihlLHQpIHsKCQlpZihlLmN0cmxLZXkpIHsKCQkJdGhpcy5uZS5maXJlRXZlbnQoJ2tleScsdGhpcyxlKTsKCQl9Cgl9LAoJCglzZWxlY3RlZCA6IGZ1bmN0aW9uKGUsdCkgewoJCWlmKCF0KSB7dCA9IHRoaXMuc2VsRWxtKCl9CgkJaWYoIWUuY3RybEtleSkgewoJCQl2YXIgc2VsSW5zdGFuY2UgPSB0aGlzLm5lLnNlbGVjdGVkSW5zdGFuY2U7CgkJCWlmKHNlbEluc3RhbmNlICE9IHRoaXMpIHsKCQkJCWlmKHNlbEluc3RhbmNlKSB7CgkJCQkJdGhpcy5uZS5maXJlRXZlbnQoJ2JsdXInLHNlbEluc3RhbmNlLHQpOwoJCQkJfQoJCQkJdGhpcy5uZS5zZWxlY3RlZEluc3RhbmNlID0gdGhpczsJCgkJCQl0aGlzLm5lLmZpcmVFdmVudCgnZm9jdXMnLHNlbEluc3RhbmNlLHQpOwoJCQl9CgkJCXRoaXMubmUuZmlyZUV2ZW50KCdzZWxlY3RlZCcsc2VsSW5zdGFuY2UsdCk7CgkJCXRoaXMuaXNGb2N1c2VkID0gdHJ1ZTsKCQkJdGhpcy5lbG0uYWRkQ2xhc3MoJ3NlbGVjdGVkJyk7CgkJfQoJCXJldHVybiBmYWxzZTsKCX0sCgkKCWJsdXIgOiBmdW5jdGlvbigpIHsKCQl0aGlzLmlzRm9jdXNlZCA9IGZhbHNlOwoJCXRoaXMuZWxtLnJlbW92ZUNsYXNzKCdzZWxlY3RlZCcpOwoJfSwKCQoJc2F2ZUNvbnRlbnQgOiBmdW5jdGlvbigpIHsKCQlpZih0aGlzLmNvcHlFbG0gfHwgdGhpcy5vcHRpb25zLmhhc1BhbmVsKSB7CgkJCXRoaXMubmUuZmlyZUV2ZW50KCdzYXZlJyx0aGlzKTsKCQkJKHRoaXMuY29weUVsbSkgPyB0aGlzLmNvcHlFbG0udmFsdWUgPSB0aGlzLmdldENvbnRlbnQoKSA6IHRoaXMuZS5pbm5lckhUTUwgPSB0aGlzLmdldENvbnRlbnQoKTsKCQl9CQoJfSwKCQoJZ2V0RWxtIDogZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRoaXMuZWxtOwoJfSwKCQoJZ2V0Q29udGVudCA6IGZ1bmN0aW9uKCkgewoJCXRoaXMuY29udGVudCA9IHRoaXMuZ2V0RWxtKCkuaW5uZXJIVE1MOwoJCXRoaXMubmUuZmlyZUV2ZW50KCdnZXQnLHRoaXMpOwoJCXJldHVybiB0aGlzLmNvbnRlbnQ7Cgl9LAoJCglzZXRDb250ZW50IDogZnVuY3Rpb24oZSkgewoJCXRoaXMuY29udGVudCA9IGU7CgkJdGhpcy5uZS5maXJlRXZlbnQoJ3NldCcsdGhpcyk7CgkJdGhpcy5lbG0uaW5uZXJIVE1MID0gdGhpcy5jb250ZW50OwkKCX0sCgkKCW5pY0NvbW1hbmQgOiBmdW5jdGlvbihjbWQsYXJncykgewoJCWRvY3VtZW50LmV4ZWNDb21tYW5kKGNtZCxmYWxzZSxhcmdzKTsKCX0JCQp9KTsKDQp2YXIgbmljRWRpdG9ySUZyYW1lSW5zdGFuY2UgPSBuaWNFZGl0b3JJbnN0YW5jZS5leHRlbmQoewoJc2F2ZWRTdHlsZXMgOiBbXSwKCQoJaW5pdCA6IGZ1bmN0aW9uKCkgewkKCQl2YXIgYyA9IHRoaXMuZWxtLmlubmVySFRNTC5yZXBsYWNlKC9eXHMrfFxzKyQvZywgJycpOwoJCXRoaXMuZWxtLmlubmVySFRNTCA9ICcnOwoJCSghYykgPyBjID0gIjxiciAvPiIgOiBjOwoJCXRoaXMuaW5pdGlhbENvbnRlbnQgPSBjOwoJCQoJCXRoaXMuZWxtRnJhbWUgPSBuZXcgYmtFbGVtZW50KCdpZnJhbWUnKS5zZXRBdHRyaWJ1dGVzKHsnc3JjJyA6ICdqYXZhc2NyaXB0OjsnLCAnZnJhbWVCb3JkZXInIDogMCwgJ2FsbG93VHJhbnNwYXJlbmN5JyA6ICd0cnVlJywgJ3Njcm9sbGluZycgOiAnbm8nfSkuc2V0U3R5bGUoe2hlaWdodDogJzEwMHB4Jywgd2lkdGg6ICcxMDAlJ30pLmFkZENsYXNzKCdmcmFtZScpLmFwcGVuZFRvKHRoaXMuZWxtKTsKCgkJaWYodGhpcy5jb3B5RWxtKSB7IHRoaXMuZWxtRnJhbWUuc2V0U3R5bGUoe3dpZHRoIDogKHRoaXMuZWxtLm9mZnNldFdpZHRoLTQpKydweCd9KTsgfQoJCQoJCXZhciBzdHlsZUxpc3QgPSBbJ2ZvbnQtc2l6ZScsJ2ZvbnQtZmFtaWx5JywnZm9udC13ZWlnaHQnLCdjb2xvciddOwoJCWZvcihpdG0gaW4gc3R5bGVMaXN0KSB7CgkJCXRoaXMuc2F2ZWRTdHlsZXNbYmtMaWIuY2FtZWxpemUoaXRtKV0gPSB0aGlzLmVsbS5nZXRTdHlsZShpdG0pOwoJCX0KICAgICAJCgkJc2V0VGltZW91dCh0aGlzLmluaXRGcmFtZS5jbG9zdXJlKHRoaXMpLDUwKTsKCX0sCgkKCWRpc2FibGUgOiBmdW5jdGlvbigpIHsKCQl0aGlzLmVsbS5pbm5lckhUTUwgPSB0aGlzLmdldENvbnRlbnQoKTsKCX0sCgkKCWluaXRGcmFtZSA6IGZ1bmN0aW9uKCkgewoJCXZhciBmZCA9ICRCSyh0aGlzLmVsbUZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQpOwoJCWZkLmRlc2lnbk1vZGUgPSAib24iOwkJCgkJZmQub3BlbigpOwoJCXZhciBjc3MgPSB0aGlzLm5lLm9wdGlvbnMuZXh0ZXJuYWxDU1M7CgkJZmQud3JpdGUoJzxodG1sPjxoZWFkPicrKChjc3MpID8gJzxsaW5rIGhyZWY9IicrY3NzKyciIHJlbD0ic3R5bGVzaGVldCIgdHlwZT0idGV4dC9jc3MiIC8+JyA6ICcnKSsnPC9oZWFkPjxib2R5IGlkPSJuaWNFZGl0Q29udGVudCIgc3R5bGU9Im1hcmdpbjogMCAhaW1wb3J0YW50OyBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudCAhaW1wb3J0YW50OyI+Jyt0aGlzLmluaXRpYWxDb250ZW50Kyc8L2JvZHk+PC9odG1sPicpOwoJCWZkLmNsb3NlKCk7CgkJdGhpcy5mcmFtZURvYyA9IGZkOwoKCQl0aGlzLmZyYW1lV2luID0gJEJLKHRoaXMuZWxtRnJhbWUuY29udGVudFdpbmRvdyk7CgkJdGhpcy5mcmFtZUNvbnRlbnQgPSAkQksodGhpcy5mcmFtZVdpbi5kb2N1bWVudC5ib2R5KS5zZXRTdHlsZSh0aGlzLnNhdmVkU3R5bGVzKTsKCQl0aGlzLmluc3RhbmNlRG9jID0gdGhpcy5mcmFtZVdpbi5kb2N1bWVudC5kZWZhdWx0VmlldzsKCQkKCQl0aGlzLmhlaWdodFVwZGF0ZSgpOwoJCXRoaXMuZnJhbWVEb2MuYWRkRXZlbnQoJ21vdXNlZG93bicsIHRoaXMuc2VsZWN0ZWQuY2xvc3VyZUxpc3RlbmVyKHRoaXMpKS5hZGRFdmVudCgna2V5dXAnLHRoaXMuaGVpZ2h0VXBkYXRlLmNsb3N1cmVMaXN0ZW5lcih0aGlzKSkuYWRkRXZlbnQoJ2tleWRvd24nLHRoaXMua2V5RG93bi5jbG9zdXJlTGlzdGVuZXIodGhpcykpLmFkZEV2ZW50KCdrZXl1cCcsdGhpcy5zZWxlY3RlZC5jbG9zdXJlKHRoaXMpKTsKCQl0aGlzLm5lLmZpcmVFdmVudCgnYWRkJyx0aGlzKTsKCX0sCgkKCWdldEVsbSA6IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLmZyYW1lQ29udGVudDsKCX0sCgkKCXNldENvbnRlbnQgOiBmdW5jdGlvbihjKSB7CgkJdGhpcy5jb250ZW50ID0gYzsKCQl0aGlzLm5lLmZpcmVFdmVudCgnc2V0Jyx0aGlzKTsKCQl0aGlzLmZyYW1lQ29udGVudC5pbm5lckhUTUwgPSB0aGlzLmNvbnRlbnQ7CQoJCXRoaXMuaGVpZ2h0VXBkYXRlKCk7Cgl9LAoJCglnZXRTZWwgOiBmdW5jdGlvbigpIHsKCQlyZXR1cm4gKHRoaXMuZnJhbWVXaW4pID8gdGhpcy5mcmFtZVdpbi5nZXRTZWxlY3Rpb24oKSA6IHRoaXMuZnJhbWVEb2Muc2VsZWN0aW9uOwoJfSwKCQoJaGVpZ2h0VXBkYXRlIDogZnVuY3Rpb24oKSB7CQoJCXRoaXMuZWxtRnJhbWUuc3R5bGUuaGVpZ2h0ID0gTWF0aC5tYXgodGhpcy5mcmFtZUNvbnRlbnQub2Zmc2V0SGVpZ2h0LHRoaXMuaW5pdGlhbEhlaWdodCkrJ3B4JzsKCX0sCiAgICAKCW5pY0NvbW1hbmQgOiBmdW5jdGlvbihjbWQsYXJncykgewoJCXRoaXMuZnJhbWVEb2MuZXhlY0NvbW1hbmQoY21kLGZhbHNlLGFyZ3MpOwoJCXNldFRpbWVvdXQodGhpcy5oZWlnaHRVcGRhdGUuY2xvc3VyZSh0aGlzKSwxMDApOwoJfQoKCQp9KTsNCnZhciBuaWNFZGl0b3JQYW5lbCA9IGJrQ2xhc3MuZXh0ZW5kKHsKCWNvbnN0cnVjdCA6IGZ1bmN0aW9uKGUsb3B0aW9ucyxuaWNFZGl0b3IpIHsKCQl0aGlzLmVsbSA9IGU7CgkJdGhpcy5vcHRpb25zID0gb3B0aW9uczsKCQl0aGlzLm5lID0gbmljRWRpdG9yOwoJCXRoaXMucGFuZWxCdXR0b25zID0gbmV3IEFycmF5KCk7CgkJdGhpcy5idXR0b25MaXN0ID0gYmtFeHRlbmQoW10sdGhpcy5uZS5vcHRpb25zLmJ1dHRvbkxpc3QpOwoJCQoJCXRoaXMucGFuZWxDb250YWluID0gbmV3IGJrRWxlbWVudCgnRElWJykuc2V0U3R5bGUoe292ZXJmbG93IDogJ2hpZGRlbicsIHdpZHRoIDogJzEwMCUnLCBib3JkZXIgOiAnMXB4IHNvbGlkICNjY2NjY2MnLCBiYWNrZ3JvdW5kQ29sb3IgOiAnI2VmZWZlZid9KS5hZGRDbGFzcygncGFuZWxDb250YWluJyk7CgkJdGhpcy5wYW5lbEVsbSA9IG5ldyBia0VsZW1lbnQoJ0RJVicpLnNldFN0eWxlKHttYXJnaW4gOiAnMnB4JywgbWFyZ2luVG9wIDogJzBweCcsIHpvb20gOiAxLCBvdmVyZmxvdyA6ICdoaWRkZW4nfSkuYWRkQ2xhc3MoJ3BhbmVsJykuYXBwZW5kVG8odGhpcy5wYW5lbENvbnRhaW4pOwoJCXRoaXMucGFuZWxDb250YWluLmFwcGVuZFRvKGUpOwoKCQl2YXIgb3B0ID0gdGhpcy5uZS5vcHRpb25zOwoJCXZhciBidXR0b25zID0gb3B0LmJ1dHRvbnM7CgkJZm9yKGJ1dHRvbiBpbiBidXR0b25zKSB7CgkJCQl0aGlzLmFkZEJ1dHRvbihidXR0b24sb3B0LHRydWUpOwoJCX0KCQl0aGlzLnJlb3JkZXIoKTsKCQllLm5vU2VsZWN0KCk7Cgl9LAoJCglhZGRCdXR0b24gOiBmdW5jdGlvbihidXR0b25OYW1lLG9wdGlvbnMsbm9PcmRlcikgewoJCXZhciBidXR0b24gPSBvcHRpb25zLmJ1dHRvbnNbYnV0dG9uTmFtZV07CgkJdmFyIHR5cGUgPSAoYnV0dG9uWyd0eXBlJ10pID8gZXZhbCgnKHR5cGVvZignK2J1dHRvblsndHlwZSddKycpID09ICJ1bmRlZmluZWQiKSA/IG51bGwgOiAnK2J1dHRvblsndHlwZSddKyc7JykgOiBuaWNFZGl0b3JCdXR0b247CgkJdmFyIGhhc0J1dHRvbiA9IGJrTGliLmluQXJyYXkodGhpcy5idXR0b25MaXN0LGJ1dHRvbk5hbWUpOwoJCWlmKHR5cGUgJiYgKGhhc0J1dHRvbiB8fCB0aGlzLm5lLm9wdGlvbnMuZnVsbFBhbmVsKSkgewoJCQl0aGlzLnBhbmVsQnV0dG9ucy5wdXNoKG5ldyB0eXBlKHRoaXMucGFuZWxFbG0sYnV0dG9uTmFtZSxvcHRpb25zLHRoaXMubmUpKTsKCQkJaWYoIWhhc0J1dHRvbikgewkKCQkJCXRoaXMuYnV0dG9uTGlzdC5wdXNoKGJ1dHRvbk5hbWUpOwoJCQl9CgkJfQoJfSwKCQoJZmluZEJ1dHRvbiA6IGZ1bmN0aW9uKGl0bSkgewoJCWZvcih2YXIgaT0wO2k8dGhpcy5wYW5lbEJ1dHRvbnMubGVuZ3RoO2krKykgewoJCQlpZih0aGlzLnBhbmVsQnV0dG9uc1tpXS5uYW1lID09IGl0bSkKCQkJCXJldHVybiB0aGlzLnBhbmVsQnV0dG9uc1tpXTsKCQl9CQoJfSwKCQoJcmVvcmRlciA6IGZ1bmN0aW9uKCkgewoJCXZhciBibCA9IHRoaXMuYnV0dG9uTGlzdDsKCQlmb3IodmFyIGk9MDtpPGJsLmxlbmd0aDtpKyspIHsKCQkJdmFyIGJ1dHRvbiA9IHRoaXMuZmluZEJ1dHRvbihibFtpXSk7CgkJCWlmKGJ1dHRvbikgewoJCQkJdGhpcy5wYW5lbEVsbS5hcHBlbmRDaGlsZChidXR0b24ubWFyZ2luKTsKCQkJfQoJCX0JCgl9LAoJCglyZW1vdmUgOiBmdW5jdGlvbigpIHsKCQl0aGlzLmVsbS5yZW1vdmUoKTsKCX0KfSk7DQp2YXIgbmljRWRpdG9yQnV0dG9uID0gYmtDbGFzcy5leHRlbmQoewoJCgljb25zdHJ1Y3QgOiBmdW5jdGlvbihlLGJ1dHRvbk5hbWUsb3B0aW9ucyxuaWNFZGl0b3IpIHsKCQl0aGlzLm9wdGlvbnMgPSBvcHRpb25zLmJ1dHRvbnNbYnV0dG9uTmFtZV07CgkJdGhpcy5uYW1lID0gYnV0dG9uTmFtZTsKCQl0aGlzLm5lID0gbmljRWRpdG9yOwoJCXRoaXMuZWxtID0gZTsKCgkJdGhpcy5tYXJnaW4gPSBuZXcgYmtFbGVtZW50KCdESVYnKS5zZXRTdHlsZSh7J2Zsb2F0JyA6ICdsZWZ0JywgbWFyZ2luVG9wIDogJzJweCd9KS5hcHBlbmRUbyhlKTsKCQl0aGlzLmNvbnRhaW4gPSBuZXcgYmtFbGVtZW50KCdESVYnKS5zZXRTdHlsZSh7d2lkdGggOiAnMjBweCcsIGhlaWdodCA6ICcyMHB4J30pLmFkZENsYXNzKCdidXR0b25Db250YWluJykuYXBwZW5kVG8odGhpcy5tYXJnaW4pOwoJCXRoaXMuYm9yZGVyID0gbmV3IGJrRWxlbWVudCgnRElWJykuc2V0U3R5bGUoe2JhY2tncm91bmRDb2xvciA6ICcjZWZlZmVmJywgYm9yZGVyIDogJzFweCBzb2xpZCAjZWZlZmVmJ30pLmFwcGVuZFRvKHRoaXMuY29udGFpbik7CgkJdGhpcy5idXR0b24gPSBuZXcgYmtFbGVtZW50KCdESVYnKS5zZXRTdHlsZSh7d2lkdGggOiAnMThweCcsIGhlaWdodCA6ICcxOHB4Jywgb3ZlcmZsb3cgOiAnaGlkZGVuJywgem9vbSA6IDEsIGN1cnNvciA6ICdwb2ludGVyJ30pLmFkZENsYXNzKCdidXR0b24nKS5zZXRTdHlsZSh0aGlzLm5lLmdldEljb24oYnV0dG9uTmFtZSxvcHRpb25zKSkuYXBwZW5kVG8odGhpcy5ib3JkZXIpOwoJCXRoaXMuYnV0dG9uLmFkZEV2ZW50KCdtb3VzZW92ZXInLCB0aGlzLmhvdmVyT24uY2xvc3VyZSh0aGlzKSkuYWRkRXZlbnQoJ21vdXNlb3V0Jyx0aGlzLmhvdmVyT2ZmLmNsb3N1cmUodGhpcykpLmFkZEV2ZW50KCdtb3VzZWRvd24nLHRoaXMubW91c2VDbGljay5jbG9zdXJlKHRoaXMpKS5ub1NlbGVjdCgpOwoJCQoJCWlmKCF3aW5kb3cub3BlcmEpIHsKCQkJdGhpcy5idXR0b24ub25tb3VzZWRvd24gPSB0aGlzLmJ1dHRvbi5vbmNsaWNrID0gYmtMaWIuY2FuY2VsRXZlbnQ7CgkJfQoJCQoJCW5pY0VkaXRvci5hZGRFdmVudCgnc2VsZWN0ZWQnLCB0aGlzLmVuYWJsZS5jbG9zdXJlKHRoaXMpKS5hZGRFdmVudCgnYmx1cicsIHRoaXMuZGlzYWJsZS5jbG9zdXJlKHRoaXMpKS5hZGRFdmVudCgna2V5Jyx0aGlzLmtleS5jbG9zdXJlKHRoaXMpKTsKCQkKCQl0aGlzLmRpc2FibGUoKTsKCQl0aGlzLmluaXQoKTsKCX0sCgkKCWluaXQgOiBmdW5jdGlvbigpIHsgIH0sCgkKCWhpZGUgOiBmdW5jdGlvbigpIHsKCQl0aGlzLmNvbnRhaW4uc2V0U3R5bGUoe2Rpc3BsYXkgOiAnbm9uZSd9KTsKCX0sCgkKCXVwZGF0ZVN0YXRlIDogZnVuY3Rpb24oKSB7CgkJaWYodGhpcy5pc0Rpc2FibGVkKSB7IHRoaXMuc2V0QmcoKTsgfQoJCWVsc2UgaWYodGhpcy5pc0hvdmVyKSB7IHRoaXMuc2V0QmcoJ2hvdmVyJyk7IH0KCQllbHNlIGlmKHRoaXMuaXNBY3RpdmUpIHsgdGhpcy5zZXRCZygnYWN0aXZlJyk7IH0KCQllbHNlIHsgdGhpcy5zZXRCZygpOyB9Cgl9LAoJCglzZXRCZyA6IGZ1bmN0aW9uKHN0YXRlKSB7CgkJc3dpdGNoKHN0YXRlKSB7CgkJCWNhc2UgJ2hvdmVyJzoKCQkJCXZhciBzdGF0ZVN0eWxlID0ge2JvcmRlciA6ICcxcHggc29saWQgIzY2NicsIGJhY2tncm91bmRDb2xvciA6ICcjZGRkJ307CgkJCQlicmVhazsKCQkJY2FzZSAnYWN0aXZlJzoKCQkJCXZhciBzdGF0ZVN0eWxlID0ge2JvcmRlciA6ICcxcHggc29saWQgIzY2NicsIGJhY2tncm91bmRDb2xvciA6ICcjY2NjJ307CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCXZhciBzdGF0ZVN0eWxlID0ge2JvcmRlciA6ICcxcHggc29saWQgI2VmZWZlZicsIGJhY2tncm91bmRDb2xvciA6ICcjZWZlZmVmJ307CQoJCX0KCQl0aGlzLmJvcmRlci5zZXRTdHlsZShzdGF0ZVN0eWxlKS5hZGRDbGFzcygnYnV0dG9uLScrc3RhdGUpOwoJfSwKCQoJY2hlY2tOb2RlcyA6IGZ1bmN0aW9uKGUpIHsKCQl2YXIgZWxtID0gZTsJCgkJZG8gewoJCQlpZih0aGlzLm9wdGlvbnMudGFncyAmJiBia0xpYi5pbkFycmF5KHRoaXMub3B0aW9ucy50YWdzLGVsbS5ub2RlTmFtZSkpIHsKCQkJCXRoaXMuYWN0aXZhdGUoKTsKCQkJCXJldHVybiB0cnVlOwoJCQl9CgkJfSB3aGlsZShlbG0gPSBlbG0ucGFyZW50Tm9kZSAmJiBlbG0uY2xhc3NOYW1lICE9ICJuaWNFZGl0Iik7CgkJZWxtID0gJEJLKGUpOwoJCXdoaWxlKGVsbS5ub2RlVHlwZSA9PSAzKSB7CgkJCWVsbSA9ICRCSyhlbG0ucGFyZW50Tm9kZSk7CgkJfQoJCWlmKHRoaXMub3B0aW9ucy5jc3MpIHsKCQkJZm9yKGl0bSBpbiB0aGlzLm9wdGlvbnMuY3NzKSB7CgkJCQlpZihlbG0uZ2V0U3R5bGUoaXRtLHRoaXMubmUuc2VsZWN0ZWRJbnN0YW5jZS5pbnN0YW5jZURvYykgPT0gdGhpcy5vcHRpb25zLmNzc1tpdG1dKSB7CgkJCQkJdGhpcy5hY3RpdmF0ZSgpOwoJCQkJCXJldHVybiB0cnVlOwoJCQkJfQoJCQl9CgkJfQoJCXRoaXMuZGVhY3RpdmF0ZSgpOwoJCXJldHVybiBmYWxzZTsKCX0sCgkKCWFjdGl2YXRlIDogZnVuY3Rpb24oKSB7CgkJaWYoIXRoaXMuaXNEaXNhYmxlZCkgewoJCQl0aGlzLmlzQWN0aXZlID0gdHJ1ZTsKCQkJdGhpcy51cGRhdGVTdGF0ZSgpOwkKCQkJdGhpcy5uZS5maXJlRXZlbnQoJ2J1dHRvbkFjdGl2YXRlJyx0aGlzKTsKCQl9Cgl9LAoJCglkZWFjdGl2YXRlIDogZnVuY3Rpb24oKSB7CgkJdGhpcy5pc0FjdGl2ZSA9IGZhbHNlOwoJCXRoaXMudXBkYXRlU3RhdGUoKTsJCgkJaWYoIXRoaXMuaXNEaXNhYmxlZCkgewoJCQl0aGlzLm5lLmZpcmVFdmVudCgnYnV0dG9uRGVhY3RpdmF0ZScsdGhpcyk7CgkJfQoJfSwKCQoJZW5hYmxlIDogZnVuY3Rpb24oaW5zLHQpIHsKCQl0aGlzLmlzRGlzYWJsZWQgPSBmYWxzZTsKCQl0aGlzLmNvbnRhaW4uc2V0U3R5bGUoeydvcGFjaXR5JyA6IDF9KS5hZGRDbGFzcygnYnV0dG9uRW5hYmxlZCcpOwoJCXRoaXMudXBkYXRlU3RhdGUoKTsKCQl0aGlzLmNoZWNrTm9kZXModCk7Cgl9LAoJCglkaXNhYmxlIDogZnVuY3Rpb24oaW5zLHQpIHsJCQoJCXRoaXMuaXNEaXNhYmxlZCA9IHRydWU7CgkJdGhpcy5jb250YWluLnNldFN0eWxlKHsnb3BhY2l0eScgOiAwLjZ9KS5yZW1vdmVDbGFzcygnYnV0dG9uRW5hYmxlZCcpOwoJCXRoaXMudXBkYXRlU3RhdGUoKTsJCgl9LAoJCgl0b2dnbGVBY3RpdmUgOiBmdW5jdGlvbigpIHsKCQkodGhpcy5pc0FjdGl2ZSkgPyB0aGlzLmRlYWN0aXZhdGUoKSA6IHRoaXMuYWN0aXZhdGUoKTsJCgl9LAoJCglob3Zlck9uIDogZnVuY3Rpb24oKSB7CgkJaWYoIXRoaXMuaXNEaXNhYmxlZCkgewoJCQl0aGlzLmlzSG92ZXIgPSB0cnVlOwoJCQl0aGlzLnVwZGF0ZVN0YXRlKCk7CgkJCXRoaXMubmUuZmlyZUV2ZW50KCJidXR0b25PdmVyIix0aGlzKTsKCQl9Cgl9LCAKCQoJaG92ZXJPZmYgOiBmdW5jdGlvbigpIHsKCQl0aGlzLmlzSG92ZXIgPSBmYWxzZTsKCQl0aGlzLnVwZGF0ZVN0YXRlKCk7CgkJdGhpcy5uZS5maXJlRXZlbnQoImJ1dHRvbk91dCIsdGhpcyk7Cgl9LAoJCgltb3VzZUNsaWNrIDogZnVuY3Rpb24oKSB7CgkJaWYodGhpcy5vcHRpb25zLmNvbW1hbmQpIHsKCQkJdGhpcy5uZS5uaWNDb21tYW5kKHRoaXMub3B0aW9ucy5jb21tYW5kLHRoaXMub3B0aW9ucy5jb21tYW5kQXJncyk7CgkJCWlmKCF0aGlzLm9wdGlvbnMubm9BY3RpdmUpIHsKCQkJCXRoaXMudG9nZ2xlQWN0aXZlKCk7CgkJCX0KCQl9CgkJdGhpcy5uZS5maXJlRXZlbnQoImJ1dHRvbkNsaWNrIix0aGlzKTsKCX0sCgkKCWtleSA6IGZ1bmN0aW9uKG5pY0luc3RhbmNlLGUpIHsKCQlpZih0aGlzLm9wdGlvbnMua2V5ICYmIGUuY3RybEtleSAmJiBTdHJpbmcuZnJvbUNoYXJDb2RlKGUua2V5Q29kZSB8fCBlLmNoYXJDb2RlKS50b0xvd2VyQ2FzZSgpID09IHRoaXMub3B0aW9ucy5rZXkpIHsKCQkJdGhpcy5tb3VzZUNsaWNrKCk7CgkJCWlmKGUucHJldmVudERlZmF1bHQpIGUucHJldmVudERlZmF1bHQoKTsKCQl9Cgl9CgkKfSk7DQoKIAp2YXIgbmljUGx1Z2luID0gYmtDbGFzcy5leHRlbmQoewoJCgljb25zdHJ1Y3QgOiBmdW5jdGlvbihuaWNFZGl0b3Isb3B0aW9ucykgewoJCXRoaXMub3B0aW9ucyA9IG9wdGlvbnM7CgkJdGhpcy5uZSA9IG5pY0VkaXRvcjsKCQl0aGlzLm5lLmFkZEV2ZW50KCdwYW5lbCcsdGhpcy5sb2FkUGFuZWwuY2xvc3VyZSh0aGlzKSk7CgkJCgkJdGhpcy5pbml0KCk7Cgl9LAoKCWxvYWRQYW5lbCA6IGZ1bmN0aW9uKG5wKSB7CgkJdmFyIGJ1dHRvbnMgPSB0aGlzLm9wdGlvbnMuYnV0dG9uczsKCQlmb3IodmFyIGJ1dHRvbiBpbiBidXR0b25zKSB7CgkJCW5wLmFkZEJ1dHRvbihidXR0b24sdGhpcy5vcHRpb25zKTsKCQl9CgkJbnAucmVvcmRlcigpOwoJfSwKCglpbml0IDogZnVuY3Rpb24oKSB7ICB9Cn0pOwoNCg0KCiAKIC8qIFNUQVJUIENPTkZJRyAqLwp2YXIgbmljUGFuZU9wdGlvbnMgPSB7IH07Ci8qIEVORCBDT05GSUcgKi8KCnZhciBuaWNFZGl0b3JQYW5lID0gYmtDbGFzcy5leHRlbmQoewoJY29uc3RydWN0IDogZnVuY3Rpb24oZWxtLG5pY0VkaXRvcixvcHRpb25zLG9wZW5CdXR0b24pIHsKCQl0aGlzLm5lID0gbmljRWRpdG9yOwoJCXRoaXMuZWxtID0gZWxtOwoJCXRoaXMucG9zID0gZWxtLnBvcygpOwoJCQoJCXRoaXMuY29udGFpbiA9IG5ldyBia0VsZW1lbnQoJ2RpdicpLnNldFN0eWxlKHt6SW5kZXggOiAnOTk5OTknLCBvdmVyZmxvdyA6ICdoaWRkZW4nLCBwb3NpdGlvbiA6ICdhYnNvbHV0ZScsIGxlZnQgOiB0aGlzLnBvc1swXSsncHgnLCB0b3AgOiB0aGlzLnBvc1sxXSsncHgnfSkKCQl0aGlzLnBhbmUgPSBuZXcgYmtFbGVtZW50KCdkaXYnKS5zZXRTdHlsZSh7Zm9udFNpemUgOiAnMTJweCcsIGJvcmRlciA6ICcxcHggc29saWQgI2NjYycsICdvdmVyZmxvdyc6ICdoaWRkZW4nLCBwYWRkaW5nIDogJzRweCcsIHRleHRBbGlnbjogJ2xlZnQnLCBiYWNrZ3JvdW5kQ29sb3IgOiAnI2ZmZmZjOSd9KS5hZGRDbGFzcygncGFuZScpLnNldFN0eWxlKG9wdGlvbnMpLmFwcGVuZFRvKHRoaXMuY29udGFpbik7CgkJCgkJaWYob3BlbkJ1dHRvbiAmJiAhb3BlbkJ1dHRvbi5vcHRpb25zLm5vQ2xvc2UpIHsKCQkJdGhpcy5jbG9zZSA9IG5ldyBia0VsZW1lbnQoJ2RpdicpLnNldFN0eWxlKHsnZmxvYXQnIDogJ3JpZ2h0JywgaGVpZ2h0OiAnMTZweCcsIHdpZHRoIDogJzE2cHgnLCBjdXJzb3IgOiAncG9pbnRlcid9KS5zZXRTdHlsZSh0aGlzLm5lLmdldEljb24oJ2Nsb3NlJyxuaWNQYW5lT3B0aW9ucykpLmFkZEV2ZW50KCdtb3VzZWRvd24nLG9wZW5CdXR0b24ucmVtb3ZlUGFuZS5jbG9zdXJlKHRoaXMpKS5hcHBlbmRUbyh0aGlzLnBhbmUpOwoJCX0KCQkKCQl0aGlzLmNvbnRhaW4ubm9TZWxlY3QoKS5hcHBlbmRUbyhkb2N1bWVudC5ib2R5KTsKCQkKCQl0aGlzLnBvc2l0aW9uKCk7CgkJdGhpcy5pbml0KCk7CQoJfSwKCQoJaW5pdCA6IGZ1bmN0aW9uKCkgeyB9LAoJCglwb3NpdGlvbiA6IGZ1bmN0aW9uKCkgewoJCWlmKHRoaXMubmUubmljUGFuZWwpIHsKCQkJdmFyIHBhbmVsRWxtID0gdGhpcy5uZS5uaWNQYW5lbC5lbG07CQoJCQl2YXIgcGFuZWxQb3MgPSBwYW5lbEVsbS5wb3MoKTsKCQkJdmFyIG5ld0xlZnQgPSBwYW5lbFBvc1swXStwYXJzZUludChwYW5lbEVsbS5nZXRTdHlsZSgnd2lkdGgnKSktKHBhcnNlSW50KHRoaXMucGFuZS5nZXRTdHlsZSgnd2lkdGgnKSkrOCk7CgkJCWlmKG5ld0xlZnQgPCB0aGlzLnBvc1swXSkgewoJCQkJdGhpcy5jb250YWluLnNldFN0eWxlKHtsZWZ0IDogbmV3TGVmdCsncHgnfSk7CgkJCX0KCQl9Cgl9LAoJCgl0b2dnbGUgOiBmdW5jdGlvbigpIHsKCQl0aGlzLmlzVmlzaWJsZSA9ICF0aGlzLmlzVmlzaWJsZTsKCQl0aGlzLmNvbnRhaW4uc2V0U3R5bGUoe2Rpc3BsYXkgOiAoKHRoaXMuaXNWaXNpYmxlKSA/ICdibG9jaycgOiAnbm9uZScpfSk7Cgl9LAoJCglyZW1vdmUgOiBmdW5jdGlvbigpIHsKCQlpZih0aGlzLmNvbnRhaW4pIHsKCQkJdGhpcy5jb250YWluLnJlbW92ZSgpOwoJCQl0aGlzLmNvbnRhaW4gPSBudWxsOwoJCX0KCX0sCgkKCWFwcGVuZCA6IGZ1bmN0aW9uKGMpIHsKCQljLmFwcGVuZFRvKHRoaXMucGFuZSk7Cgl9LAoJCglzZXRDb250ZW50IDogZnVuY3Rpb24oYykgewoJCXRoaXMucGFuZS5zZXRDb250ZW50KGMpOwoJfQoJCn0pOw0KDQoKIAp2YXIgbmljRWRpdG9yQWR2YW5jZWRCdXR0b24gPSBuaWNFZGl0b3JCdXR0b24uZXh0ZW5kKHsKCQoJaW5pdCA6IGZ1bmN0aW9uKCkgewoJCXRoaXMubmUuYWRkRXZlbnQoJ3NlbGVjdGVkJyx0aGlzLnJlbW92ZVBhbmUuY2xvc3VyZSh0aGlzKSkuYWRkRXZlbnQoJ2JsdXInLHRoaXMucmVtb3ZlUGFuZS5jbG9zdXJlKHRoaXMpKTsJCgl9LAoJCgltb3VzZUNsaWNrIDogZnVuY3Rpb24oKSB7CgkJaWYoIXRoaXMuaXNEaXNhYmxlZCkgewoJCQlpZih0aGlzLnBhbmUgJiYgdGhpcy5wYW5lLnBhbmUpIHsKCQkJCXRoaXMucmVtb3ZlUGFuZSgpOwoJCQl9IGVsc2UgewoJCQkJdGhpcy5wYW5lID0gbmV3IG5pY0VkaXRvclBhbmUodGhpcy5jb250YWluLHRoaXMubmUse3dpZHRoIDogKHRoaXMud2lkdGggfHwgJzI3MHB4JyksIGJhY2tncm91bmRDb2xvciA6ICcjZmZmJ30sdGhpcyk7CgkJCQl0aGlzLmFkZFBhbmUoKTsKCQkJCXRoaXMubmUuc2VsZWN0ZWRJbnN0YW5jZS5zYXZlUm5nKCk7CgkJCX0KCQl9Cgl9LAoJCglhZGRGb3JtIDogZnVuY3Rpb24oZixlbG0pIHsKCQl0aGlzLmZvcm0gPSBuZXcgYmtFbGVtZW50KCdmb3JtJykuYWRkRXZlbnQoJ3N1Ym1pdCcsdGhpcy5zdWJtaXQuY2xvc3VyZUxpc3RlbmVyKHRoaXMpKTsKCQl0aGlzLnBhbmUuYXBwZW5kKHRoaXMuZm9ybSk7CgkJdGhpcy5pbnB1dHMgPSB7fTsKCQkKCQlmb3IoaXRtIGluIGYpIHsKCQkJdmFyIGZpZWxkID0gZltpdG1dOwoJCQl2YXIgdmFsID0gJyc7CgkJCWlmKGVsbSkgewoJCQkJdmFsID0gZWxtLmdldEF0dHJpYnV0ZShpdG0pOwoJCQl9CgkJCWlmKCF2YWwpIHsKCQkJCXZhbCA9IGZpZWxkWyd2YWx1ZSddIHx8ICcnOwoJCQl9CgkJCXZhciB0eXBlID0gZltpdG1dLnR5cGU7CgkJCQoJCQlpZih0eXBlID09ICd0aXRsZScpIHsKCQkJCQluZXcgYmtFbGVtZW50KCdkaXYnKS5zZXRDb250ZW50KGZpZWxkLnR4dCkuc2V0U3R5bGUoe2ZvbnRTaXplIDogJzE0cHgnLCBmb250V2VpZ2h0OiAnYm9sZCcsIHBhZGRpbmcgOiAnMHB4JywgbWFyZ2luIDogJzJweCAwJ30pLmFwcGVuZFRvKHRoaXMuZm9ybSk7CgkJCX0gZWxzZSB7CgkJCQl2YXIgY29udGFpbiA9IG5ldyBia0VsZW1lbnQoJ2RpdicpLnNldFN0eWxlKHtvdmVyZmxvdyA6ICdoaWRkZW4nLCBjbGVhciA6ICdib3RoJ30pLmFwcGVuZFRvKHRoaXMuZm9ybSk7CgkJCQlpZihmaWVsZC50eHQpIHsKCQkJCQluZXcgYmtFbGVtZW50KCdsYWJlbCcpLnNldEF0dHJpYnV0ZXMoeydmb3InIDogaXRtfSkuc2V0Q29udGVudChmaWVsZC50eHQpLnNldFN0eWxlKHttYXJnaW4gOiAnMnB4IDRweCcsIGZvbnRTaXplIDogJzEzcHgnLCB3aWR0aDogJzUwcHgnLCBsaW5lSGVpZ2h0IDogJzIwcHgnLCB0ZXh0QWxpZ24gOiAncmlnaHQnLCAnZmxvYXQnIDogJ2xlZnQnfSkuYXBwZW5kVG8oY29udGFpbik7CgkJCQl9CgkJCQkKCQkJCXN3aXRjaCh0eXBlKSB7CgkJCQkJY2FzZSAndGV4dCc6CgkJCQkJCXRoaXMuaW5wdXRzW2l0bV0gPSBuZXcgYmtFbGVtZW50KCdpbnB1dCcpLnNldEF0dHJpYnV0ZXMoe2lkIDogaXRtLCAndmFsdWUnIDogdmFsLCAndHlwZScgOiAndGV4dCd9KS5zZXRTdHlsZSh7bWFyZ2luIDogJzJweCAwJywgZm9udFNpemUgOiAnMTNweCcsICdmbG9hdCcgOiAnbGVmdCcsIGhlaWdodCA6ICcyMHB4JywgYm9yZGVyIDogJzFweCBzb2xpZCAjY2NjJywgb3ZlcmZsb3cgOiAnaGlkZGVuJ30pLnNldFN0eWxlKGZpZWxkLnN0eWxlKS5hcHBlbmRUbyhjb250YWluKTsKCQkJCQkJYnJlYWs7CgkJCQkJY2FzZSAnc2VsZWN0JzoKCQkJCQkJdGhpcy5pbnB1dHNbaXRtXSA9IG5ldyBia0VsZW1lbnQoJ3NlbGVjdCcpLnNldEF0dHJpYnV0ZXMoe2lkIDogaXRtfSkuc2V0U3R5bGUoe2JvcmRlciA6ICcxcHggc29saWQgI2NjYycsICdmbG9hdCcgOiAnbGVmdCcsIG1hcmdpbiA6ICcycHggMCd9KS5hcHBlbmRUbyhjb250YWluKTsKCQkJCQkJZm9yKG9wdCBpbiBmaWVsZC5vcHRpb25zKSB7CgkJCQkJCQl2YXIgbyA9IG5ldyBia0VsZW1lbnQoJ29wdGlvbicpLnNldEF0dHJpYnV0ZXMoe3ZhbHVlIDogb3B0LCBzZWxlY3RlZCA6IChvcHQgPT0gdmFsKSA/ICdzZWxlY3RlZCcgOiAnJ30pLnNldENvbnRlbnQoZmllbGQub3B0aW9uc1tvcHRdKS5hcHBlbmRUbyh0aGlzLmlucHV0c1tpdG1dKTsKCQkJCQkJfQoJCQkJCQlicmVhazsKCQkJCQljYXNlICdjb250ZW50JzoKCQkJCQkJdGhpcy5pbnB1dHNbaXRtXSA9IG5ldyBia0VsZW1lbnQoJ3RleHRhcmVhJykuc2V0QXR0cmlidXRlcyh7aWQgOiBpdG19KS5zZXRTdHlsZSh7Ym9yZGVyIDogJzFweCBzb2xpZCAjY2NjJywgJ2Zsb2F0JyA6ICdsZWZ0J30pLnNldFN0eWxlKGZpZWxkLnN0eWxlKS5hcHBlbmRUbyhjb250YWluKTsKCQkJCQkJdGhpcy5pbnB1dHNbaXRtXS52YWx1ZSA9IHZhbDsKCQkJCX0JCgkJCX0KCQl9CgkJbmV3IGJrRWxlbWVudCgnaW5wdXQnKS5zZXRBdHRyaWJ1dGVzKHsndHlwZScgOiAnc3VibWl0J30pLnNldFN0eWxlKHtiYWNrZ3JvdW5kQ29sb3IgOiAnI2VmZWZlZicsYm9yZGVyIDogJzFweCBzb2xpZCAjY2NjJywgbWFyZ2luIDogJzNweCAwJywgJ2Zsb2F0JyA6ICdsZWZ0JywgJ2NsZWFyJyA6ICdib3RoJ30pLmFwcGVuZFRvKHRoaXMuZm9ybSk7CgkJdGhpcy5mb3JtLm9uc3VibWl0ID0gYmtMaWIuY2FuY2VsRXZlbnQ7CQoJfSwKCQoJc3VibWl0IDogZnVuY3Rpb24oKSB7IH0sCgkKCWZpbmRFbG0gOiBmdW5jdGlvbih0YWcsYXR0cix2YWwpIHsKCQl2YXIgbGlzdCA9IHRoaXMubmUuc2VsZWN0ZWRJbnN0YW5jZS5nZXRFbG0oKS5nZXRFbGVtZW50c0J5VGFnTmFtZSh0YWcpOwoJCWZvcih2YXIgaT0wO2k8bGlzdC5sZW5ndGg7aSsrKSB7CgkJCWlmKGxpc3RbaV0uZ2V0QXR0cmlidXRlKGF0dHIpID09IHZhbCkgewoJCQkJcmV0dXJuICRCSyhsaXN0W2ldKTsKCQkJfQoJCX0KCX0sCgkKCXJlbW92ZVBhbmUgOiBmdW5jdGlvbigpIHsKCQlpZih0aGlzLnBhbmUpIHsKCQkJdGhpcy5wYW5lLnJlbW92ZSgpOwoJCQl0aGlzLnBhbmUgPSBudWxsOwoJCQl0aGlzLm5lLnNlbGVjdGVkSW5zdGFuY2UucmVzdG9yZVJuZygpOwoJCX0JCgl9CQp9KTsNCg0KCnZhciBuaWNCdXR0b25UaXBzID0gYmtDbGFzcy5leHRlbmQoewoJY29uc3RydWN0IDogZnVuY3Rpb24obmljRWRpdG9yKSB7CgkJdGhpcy5uZSA9IG5pY0VkaXRvcjsKCQluaWNFZGl0b3IuYWRkRXZlbnQoJ2J1dHRvbk92ZXInLHRoaXMuc2hvdy5jbG9zdXJlKHRoaXMpKS5hZGRFdmVudCgnYnV0dG9uT3V0Jyx0aGlzLmhpZGUuY2xvc3VyZSh0aGlzKSk7CgoJfSwKCQoJc2hvdyA6IGZ1bmN0aW9uKGJ1dHRvbikgewoJCXRoaXMudGltZXIgPSBzZXRUaW1lb3V0KHRoaXMuY3JlYXRlLmNsb3N1cmUodGhpcyxidXR0b24pLDQwMCk7Cgl9LAoJCgljcmVhdGUgOiBmdW5jdGlvbihidXR0b24pIHsKCQl0aGlzLnRpbWVyID0gbnVsbDsKCQlpZighdGhpcy5wYW5lKSB7CgkJCXRoaXMucGFuZSA9IG5ldyBuaWNFZGl0b3JQYW5lKGJ1dHRvbi5idXR0b24sdGhpcy5uZSx7Zm9udFNpemUgOiAnMTJweCcsIG1hcmdpblRvcCA6ICc1cHgnfSk7CgkJCXRoaXMucGFuZS5zZXRDb250ZW50KGJ1dHRvbi5vcHRpb25zLm5hbWUpOwoJCX0JCQoJfSwKCQoJaGlkZSA6IGZ1bmN0aW9uKGJ1dHRvbikgewoJCWlmKHRoaXMudGltZXIpIHsKCQkJY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpOwoJCX0KCQlpZih0aGlzLnBhbmUpIHsKCQkJdGhpcy5wYW5lID0gdGhpcy5wYW5lLnJlbW92ZSgpOwoJCX0KCX0KfSk7Cm5pY0VkaXRvcnMucmVnaXN0ZXJQbHVnaW4obmljQnV0dG9uVGlwcyk7DQoNCgogCiAvKiBTVEFSVCBDT05GSUcgKi8KdmFyIG5pY1NlbGVjdE9wdGlvbnMgPSB7CglidXR0b25zIDogewoJCSdmb250U2l6ZScgOiB7bmFtZSA6IF9fKCdTZWxlY3QgRm9udCBTaXplJyksIHR5cGUgOiAnbmljRWRpdG9yRm9udFNpemVTZWxlY3QnLCBjb21tYW5kIDogJ2ZvbnRzaXplJ30sCgkJJ2ZvbnRGYW1pbHknIDoge25hbWUgOiBfXygnU2VsZWN0IEZvbnQgRmFtaWx5JyksIHR5cGUgOiAnbmljRWRpdG9yRm9udEZhbWlseVNlbGVjdCcsIGNvbW1hbmQgOiAnZm9udG5hbWUnfSwKCQknZm9udEZvcm1hdCcgOiB7bmFtZSA6IF9fKCdTZWxlY3QgRm9udCBGb3JtYXQnKSwgdHlwZSA6ICduaWNFZGl0b3JGb250Rm9ybWF0U2VsZWN0JywgY29tbWFuZCA6ICdmb3JtYXRCbG9jayd9Cgl9Cn07Ci8qIEVORCBDT05GSUcgKi8KdmFyIG5pY0VkaXRvclNlbGVjdCA9IGJrQ2xhc3MuZXh0ZW5kKHsKCQoJY29uc3RydWN0IDogZnVuY3Rpb24oZSxidXR0b25OYW1lLG9wdGlvbnMsbmljRWRpdG9yKSB7CgkJdGhpcy5vcHRpb25zID0gb3B0aW9ucy5idXR0b25zW2J1dHRvbk5hbWVdOwoJCXRoaXMuZWxtID0gZTsKCQl0aGlzLm5lID0gbmljRWRpdG9yOwoJCXRoaXMubmFtZSA9IGJ1dHRvbk5hbWU7CgkJdGhpcy5zZWxPcHRpb25zID0gbmV3IEFycmF5KCk7CgkJCgkJdGhpcy5tYXJnaW4gPSBuZXcgYmtFbGVtZW50KCdkaXYnKS5zZXRTdHlsZSh7J2Zsb2F0JyA6ICdsZWZ0JywgbWFyZ2luIDogJzJweCAxcHggMCAxcHgnfSkuYXBwZW5kVG8odGhpcy5lbG0pOwoJCXRoaXMuY29udGFpbiA9IG5ldyBia0VsZW1lbnQoJ2RpdicpLnNldFN0eWxlKHt3aWR0aDogJzkwcHgnLCBoZWlnaHQgOiAnMjBweCcsIGN1cnNvciA6ICdwb2ludGVyJywgb3ZlcmZsb3c6ICdoaWRkZW4nfSkuYWRkQ2xhc3MoJ3NlbGVjdENvbnRhaW4nKS5hZGRFdmVudCgnY2xpY2snLHRoaXMudG9nZ2xlLmNsb3N1cmUodGhpcykpLmFwcGVuZFRvKHRoaXMubWFyZ2luKTsKCQl0aGlzLml0ZW1zID0gbmV3IGJrRWxlbWVudCgnZGl2Jykuc2V0U3R5bGUoe292ZXJmbG93IDogJ2hpZGRlbicsIHpvb20gOiAxLCBib3JkZXI6ICcxcHggc29saWQgI2NjYycsIHBhZGRpbmdMZWZ0IDogJzNweCcsIGJhY2tncm91bmRDb2xvciA6ICcjZmZmJ30pLmFwcGVuZFRvKHRoaXMuY29udGFpbik7CgkJdGhpcy5jb250cm9sID0gbmV3IGJrRWxlbWVudCgnZGl2Jykuc2V0U3R5bGUoe292ZXJmbG93IDogJ2hpZGRlbicsICdmbG9hdCcgOiAncmlnaHQnLCBoZWlnaHQ6ICcxOHB4Jywgd2lkdGggOiAnMTZweCd9KS5hZGRDbGFzcygnc2VsZWN0Q29udHJvbCcpLnNldFN0eWxlKHRoaXMubmUuZ2V0SWNvbignYXJyb3cnLG9wdGlvbnMpKS5hcHBlbmRUbyh0aGlzLml0ZW1zKTsKCQl0aGlzLnR4dCA9IG5ldyBia0VsZW1lbnQoJ2RpdicpLnNldFN0eWxlKHtvdmVyZmxvdyA6ICdoaWRkZW4nLCAnZmxvYXQnIDogJ2xlZnQnLCB3aWR0aCA6ICc2NnB4JywgaGVpZ2h0IDogJzE0cHgnLCBtYXJnaW5Ub3AgOiAnMXB4JywgZm9udEZhbWlseSA6ICdzYW5zLXNlcmlmJywgdGV4dEFsaWduIDogJ2NlbnRlcicsIGZvbnRTaXplIDogJzEycHgnfSkuYWRkQ2xhc3MoJ3NlbGVjdFR4dCcpLmFwcGVuZFRvKHRoaXMuaXRlbXMpOwoJCQoJCWlmKCF3aW5kb3cub3BlcmEpIHsKCQkJdGhpcy5jb250YWluLm9ubW91c2Vkb3duID0gdGhpcy5jb250cm9sLm9ubW91c2Vkb3duID0gdGhpcy50eHQub25tb3VzZWRvd24gPSBia0xpYi5jYW5jZWxFdmVudDsKCQl9CgkJCgkJdGhpcy5tYXJnaW4ubm9TZWxlY3QoKTsKCQkKCQl0aGlzLm5lLmFkZEV2ZW50KCdzZWxlY3RlZCcsIHRoaXMuZW5hYmxlLmNsb3N1cmUodGhpcykpLmFkZEV2ZW50KCdibHVyJywgdGhpcy5kaXNhYmxlLmNsb3N1cmUodGhpcykpOwoJCQoJCXRoaXMuZGlzYWJsZSgpOwoJCXRoaXMuaW5pdCgpOwoJfSwKCQoJZGlzYWJsZSA6IGZ1bmN0aW9uKCkgewoJCXRoaXMuaXNEaXNhYmxlZCA9IHRydWU7CgkJdGhpcy5jbG9zZSgpOwoJCXRoaXMuY29udGFpbi5zZXRTdHlsZSh7b3BhY2l0eSA6IDAuNn0pOwoJfSwKCQoJZW5hYmxlIDogZnVuY3Rpb24odCkgewoJCXRoaXMuaXNEaXNhYmxlZCA9IGZhbHNlOwoJCXRoaXMuY2xvc2UoKTsKCQl0aGlzLmNvbnRhaW4uc2V0U3R5bGUoe29wYWNpdHkgOiAxfSk7Cgl9LAoJCglzZXREaXNwbGF5IDogZnVuY3Rpb24odHh0KSB7CgkJdGhpcy50eHQuc2V0Q29udGVudCh0eHQpOwoJfSwKCQoJdG9nZ2xlIDogZnVuY3Rpb24oKSB7CgkJaWYoIXRoaXMuaXNEaXNhYmxlZCkgewoJCQkodGhpcy5wYW5lKSA/IHRoaXMuY2xvc2UoKSA6IHRoaXMub3BlbigpOwoJCX0KCX0sCgkKCW9wZW4gOiBmdW5jdGlvbigpIHsKCQl0aGlzLnBhbmUgPSBuZXcgbmljRWRpdG9yUGFuZSh0aGlzLml0ZW1zLHRoaXMubmUse3dpZHRoIDogJzg4cHgnLCBwYWRkaW5nOiAnMHB4JywgYm9yZGVyVG9wIDogMCwgYm9yZGVyTGVmdCA6ICcxcHggc29saWQgI2NjYycsIGJvcmRlclJpZ2h0IDogJzFweCBzb2xpZCAjY2NjJywgYm9yZGVyQm90dG9tIDogJzBweCcsIGJhY2tncm91bmRDb2xvciA6ICcjZmZmJ30pOwoJCQoJCWZvcih2YXIgaT0wO2k8dGhpcy5zZWxPcHRpb25zLmxlbmd0aDtpKyspIHsKCQkJdmFyIG9wdCA9IHRoaXMuc2VsT3B0aW9uc1tpXTsKCQkJdmFyIGl0bUNvbnRhaW4gPSBuZXcgYmtFbGVtZW50KCdkaXYnKS5zZXRTdHlsZSh7b3ZlcmZsb3cgOiAnaGlkZGVuJywgYm9yZGVyQm90dG9tIDogJzFweCBzb2xpZCAjY2NjJywgd2lkdGg6ICc4OHB4JywgdGV4dEFsaWduIDogJ2xlZnQnLCBvdmVyZmxvdyA6ICdoaWRkZW4nLCBjdXJzb3IgOiAncG9pbnRlcid9KTsKCQkJdmFyIGl0bSA9IG5ldyBia0VsZW1lbnQoJ2RpdicpLnNldFN0eWxlKHtwYWRkaW5nIDogJzBweCA0cHgnfSkuc2V0Q29udGVudChvcHRbMV0pLmFwcGVuZFRvKGl0bUNvbnRhaW4pLm5vU2VsZWN0KCk7CgkJCWl0bS5hZGRFdmVudCgnY2xpY2snLHRoaXMudXBkYXRlLmNsb3N1cmUodGhpcyxvcHRbMF0pKS5hZGRFdmVudCgnbW91c2VvdmVyJyx0aGlzLm92ZXIuY2xvc3VyZSh0aGlzLGl0bSkpLmFkZEV2ZW50KCdtb3VzZW91dCcsdGhpcy5vdXQuY2xvc3VyZSh0aGlzLGl0bSkpLnNldEF0dHJpYnV0ZXMoJ2lkJyxvcHRbMF0pOwoJCQl0aGlzLnBhbmUuYXBwZW5kKGl0bUNvbnRhaW4pOwoJCQlpZighd2luZG93Lm9wZXJhKSB7CgkJCQlpdG0ub25tb3VzZWRvd24gPSBia0xpYi5jYW5jZWxFdmVudDsKCQkJfQoJCX0KCX0sCgkKCWNsb3NlIDogZnVuY3Rpb24oKSB7CgkJaWYodGhpcy5wYW5lKSB7CgkJCXRoaXMucGFuZSA9IHRoaXMucGFuZS5yZW1vdmUoKTsKCQl9CQoJfSwKCQoJb3ZlciA6IGZ1bmN0aW9uKG9wdCkgewoJCW9wdC5zZXRTdHlsZSh7YmFja2dyb3VuZENvbG9yIDogJyNjY2MnfSk7CQkJCgl9LAoJCglvdXQgOiBmdW5jdGlvbihvcHQpIHsKCQlvcHQuc2V0U3R5bGUoe2JhY2tncm91bmRDb2xvciA6ICcjZmZmJ30pOwoJfSwKCQoJCglhZGQgOiBmdW5jdGlvbihrLHYpIHsKCQl0aGlzLnNlbE9wdGlvbnMucHVzaChuZXcgQXJyYXkoayx2KSk7CQoJfSwKCQoJdXBkYXRlIDogZnVuY3Rpb24oZWxtKSB7CgkJdGhpcy5uZS5uaWNDb21tYW5kKHRoaXMub3B0aW9ucy5jb21tYW5kLGVsbSk7CgkJdGhpcy5jbG9zZSgpOwkKCX0KfSk7Cgp2YXIgbmljRWRpdG9yRm9udFNpemVTZWxlY3QgPSBuaWNFZGl0b3JTZWxlY3QuZXh0ZW5kKHsKCXNlbCA6IHsxIDogJzEmbmJzcDsoOHB0KScsIDIgOiAnMiZuYnNwOygxMHB0KScsIDMgOiAnMyZuYnNwOygxMnB0KScsIDQgOiAnNCZuYnNwOygxNHB0KScsIDUgOiAnNSZuYnNwOygxOHB0KScsIDYgOiAnNiZuYnNwOygyNHB0KSd9LAoJaW5pdCA6IGZ1bmN0aW9uKCkgewoJCXRoaXMuc2V0RGlzcGxheSgnRm9udCZuYnNwO1NpemUuLi4nKTsKCQlmb3IoaXRtIGluIHRoaXMuc2VsKSB7CgkJCXRoaXMuYWRkKGl0bSwnPGZvbnQgc2l6ZT0iJytpdG0rJyI+Jyt0aGlzLnNlbFtpdG1dKyc8L2ZvbnQ+Jyk7CgkJfQkJCgl9Cn0pOwoKdmFyIG5pY0VkaXRvckZvbnRGYW1pbHlTZWxlY3QgPSBuaWNFZGl0b3JTZWxlY3QuZXh0ZW5kKHsKCXNlbCA6IHsnYXJpYWwnIDogJ0FyaWFsJywnY29taWMgc2FucyBtcycgOiAnQ29taWMgU2FucycsJ2NvdXJpZXIgbmV3JyA6ICdDb3VyaWVyIE5ldycsJ2dlb3JnaWEnIDogJ0dlb3JnaWEnLCAnaGVsdmV0aWNhJyA6ICdIZWx2ZXRpY2EnLCAnaW1wYWN0JyA6ICdJbXBhY3QnLCAndGltZXMgbmV3IHJvbWFuJyA6ICdUaW1lcycsICd0cmVidWNoZXQgbXMnIDogJ1RyZWJ1Y2hldCcsICd2ZXJkYW5hJyA6ICdWZXJkYW5hJ30sCgkKCWluaXQgOiBmdW5jdGlvbigpIHsKCQl0aGlzLnNldERpc3BsYXkoJ0ZvbnQmbmJzcDtGYW1pbHkuLi4nKTsKCQlmb3IoaXRtIGluIHRoaXMuc2VsKSB7CgkJCXRoaXMuYWRkKGl0bSwnPGZvbnQgZmFjZT0iJytpdG0rJyI+Jyt0aGlzLnNlbFtpdG1dKyc8L2ZvbnQ+Jyk7CgkJfQoJfQp9KTsKCnZhciBuaWNFZGl0b3JGb250Rm9ybWF0U2VsZWN0ID0gbmljRWRpdG9yU2VsZWN0LmV4dGVuZCh7CgkJc2VsIDogeydwJyA6ICdQYXJhZ3JhcGgnLCAncHJlJyA6ICdQcmUnLCAnaDYnIDogJ0hlYWRpbmcmbmJzcDs2JywgJ2g1JyA6ICdIZWFkaW5nJm5ic3A7NScsICdoNCcgOiAnSGVhZGluZyZuYnNwOzQnLCAnaDMnIDogJ0hlYWRpbmcmbmJzcDszJywgJ2gyJyA6ICdIZWFkaW5nJm5ic3A7MicsICdoMScgOiAnSGVhZGluZyZuYnNwOzEnfSwKCQkKCWluaXQgOiBmdW5jdGlvbigpIHsKCQl0aGlzLnNldERpc3BsYXkoJ0ZvbnQmbmJzcDtGb3JtYXQuLi4nKTsKCQlmb3IoaXRtIGluIHRoaXMuc2VsKSB7CgkJCXZhciB0YWcgPSBpdG0udG9VcHBlckNhc2UoKTsKCQkJdGhpcy5hZGQoJzwnK3RhZysnPicsJzwnK2l0bSsnIHN0eWxlPSJwYWRkaW5nOiAwcHg7IG1hcmdpbjogMHB4OyI+Jyt0aGlzLnNlbFtpdG1dKyc8LycrdGFnKyc+Jyk7CgkJfQoJfQp9KTsKCm5pY0VkaXRvcnMucmVnaXN0ZXJQbHVnaW4obmljUGx1Z2luLG5pY1NlbGVjdE9wdGlvbnMpOw0KDQoKCi8qIFNUQVJUIENPTkZJRyAqLwp2YXIgbmljTGlua09wdGlvbnMgPSB7CglidXR0b25zIDogewoJCSdsaW5rJyA6IHtuYW1lIDogJ0FkZCBMaW5rJywgdHlwZSA6ICduaWNMaW5rQnV0dG9uJywgdGFncyA6IFsnQSddfSwKCQkndW5saW5rJyA6IHtuYW1lIDogJ1JlbW92ZSBMaW5rJywgIGNvbW1hbmQgOiAndW5saW5rJywgbm9BY3RpdmUgOiB0cnVlfQoJfQp9OwovKiBFTkQgQ09ORklHICovCgp2YXIgbmljTGlua0J1dHRvbiA9IG5pY0VkaXRvckFkdmFuY2VkQnV0dG9uLmV4dGVuZCh7CQoJYWRkUGFuZSA6IGZ1bmN0aW9uKCkgewoJCXRoaXMubG4gPSB0aGlzLm5lLnNlbGVjdGVkSW5zdGFuY2Uuc2VsRWxtKCkucGFyZW50VGFnKCdBJyk7CgkJdGhpcy5hZGRGb3JtKHsKCQkJJycgOiB7dHlwZSA6ICd0aXRsZScsIHR4dCA6ICdBZGQvRWRpdCBMaW5rJ30sCgkJCSdocmVmJyA6IHt0eXBlIDogJ3RleHQnLCB0eHQgOiAnVVJMJywgdmFsdWUgOiAnaHR0cDovLycsIHN0eWxlIDoge3dpZHRoOiAnMTUwcHgnfX0sCgkJCSd0aXRsZScgOiB7dHlwZSA6ICd0ZXh0JywgdHh0IDogJ1RpdGxlJ30sCgkJCSd0YXJnZXQnIDoge3R5cGUgOiAnc2VsZWN0JywgdHh0IDogJ09wZW4gSW4nLCBvcHRpb25zIDogeycnIDogJ0N1cnJlbnQgV2luZG93JywgJ19ibGFuaycgOiAnTmV3IFdpbmRvdyd9LHN0eWxlIDoge3dpZHRoIDogJzEwMHB4J319CgkJfSx0aGlzLmxuKTsKCX0sCgkKCXN1Ym1pdCA6IGZ1bmN0aW9uKGUpIHsKCQl2YXIgdXJsID0gdGhpcy5pbnB1dHNbJ2hyZWYnXS52YWx1ZTsKCQlpZih1cmwgPT0gImh0dHA6Ly8iIHx8IHVybCA9PSAiIikgewoJCQlhbGVydCgiWW91IG11c3QgZW50ZXIgYSBVUkwgdG8gQ3JlYXRlIGEgTGluayIpOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCXRoaXMucmVtb3ZlUGFuZSgpOwoJCQoJCWlmKCF0aGlzLmxuKSB7CgkJCXZhciB0bXAgPSAnamF2YXNjcmlwdDpuaWNUZW1wKCk7JzsKCQkJdGhpcy5uZS5uaWNDb21tYW5kKCJjcmVhdGVsaW5rIix0bXApOwoJCQl0aGlzLmxuID0gdGhpcy5maW5kRWxtKCdBJywnaHJlZicsdG1wKTsKCQl9CgkJaWYodGhpcy5sbikgewoJCQl0aGlzLmxuLnNldEF0dHJpYnV0ZXMoewoJCQkJaHJlZiA6IHRoaXMuaW5wdXRzWydocmVmJ10udmFsdWUsCgkJCQl0aXRsZSA6IHRoaXMuaW5wdXRzWyd0aXRsZSddLnZhbHVlLAoJCQkJdGFyZ2V0IDogdGhpcy5pbnB1dHNbJ3RhcmdldCddLm9wdGlvbnNbdGhpcy5pbnB1dHNbJ3RhcmdldCddLnNlbGVjdGVkSW5kZXhdLnZhbHVlCgkJCX0pOwoJCX0KCX0KfSk7CgpuaWNFZGl0b3JzLnJlZ2lzdGVyUGx1Z2luKG5pY1BsdWdpbixuaWNMaW5rT3B0aW9ucyk7DQoNCgoKLyogU1RBUlQgQ09ORklHICovCnZhciBuaWNDb2xvck9wdGlvbnMgPSB7CglidXR0b25zIDogewoJCSdmb3JlY29sb3InIDoge25hbWUgOiBfXygnQ2hhbmdlIFRleHQgQ29sb3InKSwgdHlwZSA6ICduaWNFZGl0b3JDb2xvckJ1dHRvbicsIG5vQ2xvc2UgOiB0cnVlfSwKCQknYmdjb2xvcicgOiB7bmFtZSA6IF9fKCdDaGFuZ2UgQmFja2dyb3VuZCBDb2xvcicpLCB0eXBlIDogJ25pY0VkaXRvckJnQ29sb3JCdXR0b24nLCBub0Nsb3NlIDogdHJ1ZX0KCX0KfTsKLyogRU5EIENPTkZJRyAqLwoKdmFyIG5pY0VkaXRvckNvbG9yQnV0dG9uID0gbmljRWRpdG9yQWR2YW5jZWRCdXR0b24uZXh0ZW5kKHsJCglhZGRQYW5lIDogZnVuY3Rpb24oKSB7CgkJCXZhciBjb2xvckxpc3QgPSB7MCA6ICcwMCcsMSA6ICczMycsMiA6ICc2NicsMyA6Jzk5Jyw0IDogJ0NDJyw1IDogJ0ZGJ307CgkJCXZhciBjb2xvckl0ZW1zID0gbmV3IGJrRWxlbWVudCgnRElWJykuc2V0U3R5bGUoe3dpZHRoOiAnMjcwcHgnfSk7CgkJCQoJCQlmb3IodmFyIHIgaW4gY29sb3JMaXN0KSB7CgkJCQlmb3IodmFyIGIgaW4gY29sb3JMaXN0KSB7CgkJCQkJZm9yKHZhciBnIGluIGNvbG9yTGlzdCkgewoJCQkJCQl2YXIgY29sb3JDb2RlID0gJyMnK2NvbG9yTGlzdFtyXStjb2xvckxpc3RbZ10rY29sb3JMaXN0W2JdOwoJCQkJCQkKCQkJCQkJdmFyIGNvbG9yU3F1YXJlID0gbmV3IGJrRWxlbWVudCgnRElWJykuc2V0U3R5bGUoeydjdXJzb3InIDogJ3BvaW50ZXInLCAnaGVpZ2h0JyA6ICcxNXB4JywgJ2Zsb2F0JyA6ICdsZWZ0J30pLmFwcGVuZFRvKGNvbG9ySXRlbXMpOwoJCQkJCQl2YXIgY29sb3JCb3JkZXIgPSBuZXcgYmtFbGVtZW50KCdESVYnKS5zZXRTdHlsZSh7Ym9yZGVyOiAnMnB4IHNvbGlkICcrY29sb3JDb2RlfSkuYXBwZW5kVG8oY29sb3JTcXVhcmUpOwoJCQkJCQl2YXIgY29sb3JJbm5lciA9IG5ldyBia0VsZW1lbnQoJ0RJVicpLnNldFN0eWxlKHtiYWNrZ3JvdW5kQ29sb3IgOiBjb2xvckNvZGUsIG92ZXJmbG93IDogJ2hpZGRlbicsIHdpZHRoIDogJzExcHgnLCBoZWlnaHQgOiAnMTFweCd9KS5hZGRFdmVudCgnY2xpY2snLHRoaXMuY29sb3JTZWxlY3QuY2xvc3VyZSh0aGlzLGNvbG9yQ29kZSkpLmFkZEV2ZW50KCdtb3VzZW92ZXInLHRoaXMub24uY2xvc3VyZSh0aGlzLGNvbG9yQm9yZGVyKSkuYWRkRXZlbnQoJ21vdXNlb3V0Jyx0aGlzLm9mZi5jbG9zdXJlKHRoaXMsY29sb3JCb3JkZXIsY29sb3JDb2RlKSkuYXBwZW5kVG8oY29sb3JCb3JkZXIpOwoJCQkJCQkKCQkJCQkJaWYoIXdpbmRvdy5vcGVyYSkgewoJCQkJCQkJY29sb3JTcXVhcmUub25tb3VzZWRvd24gPSBjb2xvcklubmVyLm9ubW91c2Vkb3duID0gYmtMaWIuY2FuY2VsRXZlbnQ7CgkJCQkJCX0KCgkJCQkJfQkKCQkJCX0JCgkJCX0KCQkJdGhpcy5wYW5lLmFwcGVuZChjb2xvckl0ZW1zLm5vU2VsZWN0KCkpOwkKCX0sCgkKCWNvbG9yU2VsZWN0IDogZnVuY3Rpb24oYykgewoJCXRoaXMubmUubmljQ29tbWFuZCgnZm9yZUNvbG9yJyxjKTsKCQl0aGlzLnJlbW92ZVBhbmUoKTsKCX0sCgkKCW9uIDogZnVuY3Rpb24oY29sb3JCb3JkZXIpIHsKCQljb2xvckJvcmRlci5zZXRTdHlsZSh7Ym9yZGVyIDogJzJweCBzb2xpZCAjMDAwJ30pOwoJfSwKCQoJb2ZmIDogZnVuY3Rpb24oY29sb3JCb3JkZXIsY29sb3JDb2RlKSB7CgkJY29sb3JCb3JkZXIuc2V0U3R5bGUoe2JvcmRlciA6ICcycHggc29saWQgJytjb2xvckNvZGV9KTsJCQoJfQp9KTsKCnZhciBuaWNFZGl0b3JCZ0NvbG9yQnV0dG9uID0gbmljRWRpdG9yQ29sb3JCdXR0b24uZXh0ZW5kKHsKCWNvbG9yU2VsZWN0IDogZnVuY3Rpb24oYykgewoJCXRoaXMubmUubmljQ29tbWFuZCgnaGlsaXRlQ29sb3InLGMpOwoJCXRoaXMucmVtb3ZlUGFuZSgpOwoJfQkKfSk7CgpuaWNFZGl0b3JzLnJlZ2lzdGVyUGx1Z2luKG5pY1BsdWdpbixuaWNDb2xvck9wdGlvbnMpOw0KDQoKCi8qIFNUQVJUIENPTkZJRyAqLwp2YXIgbmljSW1hZ2VPcHRpb25zID0gewoJYnV0dG9ucyA6IHsKCQknaW1hZ2UnIDoge25hbWUgOiAnQWRkIEltYWdlJywgdHlwZSA6ICduaWNJbWFnZUJ1dHRvbicsIHRhZ3MgOiBbJ0lNRyddfQoJfQoJCn07Ci8qIEVORCBDT05GSUcgKi8KCnZhciBuaWNJbWFnZUJ1dHRvbiA9IG5pY0VkaXRvckFkdmFuY2VkQnV0dG9uLmV4dGVuZCh7CQoJYWRkUGFuZSA6IGZ1bmN0aW9uKCkgewoJCXRoaXMuaW0gPSB0aGlzLm5lLnNlbGVjdGVkSW5zdGFuY2Uuc2VsRWxtKCkucGFyZW50VGFnKCdJTUcnKTsKCQl0aGlzLmFkZEZvcm0oewoJCQknJyA6IHt0eXBlIDogJ3RpdGxlJywgdHh0IDogJ0FkZC9FZGl0IEltYWdlJ30sCgkJCSdzcmMnIDoge3R5cGUgOiAndGV4dCcsIHR4dCA6ICdVUkwnLCAndmFsdWUnIDogJ2h0dHA6Ly8nLCBzdHlsZSA6IHt3aWR0aDogJzE1MHB4J319LAoJCQknYWx0JyA6IHt0eXBlIDogJ3RleHQnLCB0eHQgOiAnQWx0IFRleHQnLCBzdHlsZSA6IHt3aWR0aDogJzEwMHB4J319LAoJCQknYWxpZ24nIDoge3R5cGUgOiAnc2VsZWN0JywgdHh0IDogJ0FsaWduJywgb3B0aW9ucyA6IHtub25lIDogJ0RlZmF1bHQnLCdsZWZ0JyA6ICdMZWZ0JywgJ3JpZ2h0JyA6ICdSaWdodCd9fQoJCX0sdGhpcy5pbSk7Cgl9LAoJCglzdWJtaXQgOiBmdW5jdGlvbihlKSB7CgkJdmFyIHNyYyA9IHRoaXMuaW5wdXRzWydzcmMnXS52YWx1ZTsKCQlpZihzcmMgPT0gIiIgfHwgc3JjID09ICJodHRwOi8vIikgewoJCQlhbGVydCgiWW91IG11c3QgZW50ZXIgYSBJbWFnZSBVUkwgdG8gaW5zZXJ0Iik7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJdGhpcy5yZW1vdmVQYW5lKCk7CgoJCWlmKCF0aGlzLmltKSB7CgkJCXZhciB0bXAgPSAnamF2YXNjcmlwdDpuaWNJbVRlbXAoKTsnOwoJCQl0aGlzLm5lLm5pY0NvbW1hbmQoImluc2VydEltYWdlIix0bXApOwoJCQl0aGlzLmltID0gdGhpcy5maW5kRWxtKCdJTUcnLCdzcmMnLHRtcCk7CgkJfQoJCWlmKHRoaXMuaW0pIHsKCQkJdGhpcy5pbS5zZXRBdHRyaWJ1dGVzKHsKCQkJCXNyYyA6IHRoaXMuaW5wdXRzWydzcmMnXS52YWx1ZSwKCQkJCWFsdCA6IHRoaXMuaW5wdXRzWydhbHQnXS52YWx1ZSwKCQkJCWFsaWduIDogdGhpcy5pbnB1dHNbJ2FsaWduJ10udmFsdWUKCQkJfSk7CgkJfQoJfQp9KTsKCm5pY0VkaXRvcnMucmVnaXN0ZXJQbHVnaW4obmljUGx1Z2luLG5pY0ltYWdlT3B0aW9ucyk7Cg0KDQoKCi8qIFNUQVJUIENPTkZJRyAqLwp2YXIgbmljU2F2ZU9wdGlvbnMgPSB7CglidXR0b25zIDogewoJCSdzYXZlJyA6IHtuYW1lIDogX18oJ1NhdmUgdGhpcyBjb250ZW50JyksIHR5cGUgOiAnbmljRWRpdG9yU2F2ZUJ1dHRvbid9Cgl9Cn07Ci8qIEVORCBDT05GSUcgKi8KCnZhciBuaWNFZGl0b3JTYXZlQnV0dG9uID0gbmljRWRpdG9yQnV0dG9uLmV4dGVuZCh7Cglpbml0IDogZnVuY3Rpb24oKSB7CgkJaWYoIXRoaXMubmUub3B0aW9ucy5vblNhdmUpIHsKCQkJdGhpcy5tYXJnaW4uc2V0U3R5bGUoeydkaXNwbGF5JyA6ICdub25lJ30pOwoJCX0KCX0sCgltb3VzZUNsaWNrIDogZnVuY3Rpb24oKSB7CgkJdmFyIG9uU2F2ZSA9IHRoaXMubmUub3B0aW9ucy5vblNhdmU7CgkJdmFyIHNlbGVjdGVkSW5zdGFuY2UgPSB0aGlzLm5lLnNlbGVjdGVkSW5zdGFuY2U7CgkJb25TYXZlKHNlbGVjdGVkSW5zdGFuY2UuZ2V0Q29udGVudCgpLCBzZWxlY3RlZEluc3RhbmNlLmVsbS5pZCwgc2VsZWN0ZWRJbnN0YW5jZSk7Cgl9Cn0pOwoKbmljRWRpdG9ycy5yZWdpc3RlclBsdWdpbihuaWNQbHVnaW4sbmljU2F2ZU9wdGlvbnMpOw0KDQo=]]></data>
	</file>
	<file>
	  <filename>/lang/</filename>
	  <isdir>1</isdir>
	</file>
	<file>
	  <filename>/lang/de_DE.php</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[PD9waHAKCiRsYW5nWydoZWxwJ10gPSAnPGgzPlVzYWdlPC9oMz4KPHVsPgoJPGxpPkxvYWQgbW9kdWxlIC0ge2Ntc19tb2R1bGUgbW9kdWxlPSJ0b3VjaElubGluZUVkaXQifTwvbGk+Cgk8bGk+TWFyayBlZGl0YWJsZSBjb250ZW50cyAtIHtjb250ZW50IGlzZWRpdGFibGU9XCd0cnVlXCd9PC9saT4KPC91bD4KPGgzPkFib3V0PC9oMz4KPHVsPgoJPGxpPkNvcHlyaWdodCBieSA8YSBocmVmPSJodHRwOi8vd3d3LnRvdWNoZGVzaWduLmRlLyI+dG91Y2hEZXNpZ248L2E+PC9saT4KCTxsaT5BdXRvciBDaHJpc3RvcGggR3J1YmVyPC9saT4KCTxsaT5TdXBwb3J0IHZpYSA8YSBocmVmPSJodHRwOi8vd3d3LmhvbWVwYWdlLWNvbW11bml0eS5kZS9pbmRleC5waHA/dG9waWM9MTY4MC4wIj5IUEM8L2E+PC9saT4KCTxsaT5MaWNlbnNlIEdQTCAyLjA8L2xpPgo8L3VsPic7CiRsYW5nWydzZXR0aW5ncyddID0gJ0VpbnN0ZWxsdW5nZW4nOwokbGFuZ1sneWVzJ10gPSAnSmEnOwokbGFuZ1snbm8nXSA9ICdOZWluJzsKJGxhbmdbJ3NhdmUnXSA9ICdTcGVpY2hlcm4nOwokbGFuZ1snY2FuY2VsJ10gPSAnQWJyZWNoZW4nOwokbGFuZ1snc2V0dGluZ3NzYXZlZCddID0gJ0VpbnN0ZWxsdW5nZW4gZ2VzcGVpY2hlcnQuJzsKJGxhbmdbJ2ZlRWRpdEJ1dHRvbl9sYWJlbCddID0gJ0VkaXQgQnV0dG9uIGltIEZFPyc7CiRsYW5nWydmZUVkaXRCdXR0b25faGVscCddID0gJ0bDvGdlIGVpbmVuIEJ1dHRvbiB6dW0gZWluL2F1c3NjaGFsdGVuIHZvbiBpbmxpbmVFZGl0IGltIEZyb250ZW5kIGhpbnp1Lic7CiRsYW5nWydmZUZ1bGxQYW5lbF9sYWJlbCddID0gJ0Vyd2VpdGVydGUgV2Vya3pldWdsZWlzdGU/JzsKJGxhbmdbJ2ZlRnVsbFBhbmVsX2hlbHAnXSA9ICdCbGVuZGUgZXJ3ZWl0ZXJ0ZSBXZXJremV1Z2xlaXN0ZSBpbSBFZGl0b3IgZWluLic7CiRsYW5nWydmZVVwZGF0ZUFsZXJ0X2xhYmVsJ10gPSAnVXBkYXRlIEFsZXJ0Pyc7CiRsYW5nWydmZVVwZGF0ZUFsZXJ0X2hlbHAnXSA9ICdBa3RpdmllcmUgVXBkYXRlIEpTIEFsZXJ0IGltIEZyb250ZW5kLic7CiRsYW5nWydmZUlubGluZUVkaXRCdXR0b24nXSA9ICdpbmxpbmVFZGl0JzsKJGxhbmdbJ2ZlVXBkYXRlQWxlcnQnXSA9ICdFcmZvbGdyZWljaCBnZXNwZWljaGVydC4uLic7CiRsYW5nWydwb3N0aW5zdGFsbCddID0gJ01vZHVsIGluc3RhbGxhdGlvbiBlcmZvbGdyZWljaC4nOwokbGFuZ1sncG9zdHVuaW5zdGFsbCddID0gJ01vZHVsIGVyZm9sZ3JlaWNoIGRlaW5zdGFsbGllcnQuJzsKCj8+Cg==]]></data>
	</file>
	<file>
	  <filename>/lang/en_US.php</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[PD9waHAKCiRsYW5nWydoZWxwJ10gPSAnPGgzPlVzYWdlPC9oMz4KPHVsPgoJPGxpPkxvYWQgbW9kdWxlIC0ge2Ntc19tb2R1bGUgbW9kdWxlPSJ0b3VjaElubGluZUVkaXQifTwvbGk+Cgk8bGk+TWFyayBlZGl0YWJsZSBjb250ZW50cyAtIHtjb250ZW50IGlzZWRpdGFibGU9XCd0cnVlXCd9PC9saT4KPC91bD4KPGgzPkFib3V0PC9oMz4KPHVsPgoJPGxpPkNvcHlyaWdodCBieSA8YSBocmVmPSJodHRwOi8vd3d3LnRvdWNoZGVzaWduLmRlLyI+dG91Y2hEZXNpZ248L2E+PC9saT4KCTxsaT5BdXRob3IgQ2hyaXN0b3BoIEdydWJlcjwvbGk+Cgk8bGk+U3VwcG9ydCB2aWEgPGEgaHJlZj0iaHR0cDovL3d3dy5ob21lcGFnZS1jb21tdW5pdHkuZGUvaW5kZXgucGhwP3RvcGljPTE2ODAuMCI+SFBDPC9hPjwvbGk+Cgk8bGk+TGljZW5zZSBHUEwgMi4wPC9saT4KPC91bD4nOwokbGFuZ1snc2V0dGluZ3MnXSA9ICdTZXR0aW5ncyc7CiRsYW5nWyd5ZXMnXSA9ICdZZXMnOwokbGFuZ1snbm8nXSA9ICdObyc7CiRsYW5nWydzYXZlJ10gPSAnU2F2ZSc7CiRsYW5nWydjYW5jZWwnXSA9ICdDYW5jZWwnOwokbGFuZ1snc2V0dGluZ3NzYXZlZCddID0gJ1NldHRpbmdzIHNhdmVkLic7CiRsYW5nWydmZUVkaXRCdXR0b25fbGFiZWwnXSA9ICdFZGl0IEJ1dHRvbiBpbiBGRT8nOwokbGFuZ1snZmVFZGl0QnV0dG9uX2hlbHAnXSA9ICdBZGQgZW5hYmxlL2Rpc2FibGUgYnV0dG9uIGZvciBpbmxpbmVFZGl0IGluIEZyb250ZW5kLic7CiRsYW5nWydmZUZ1bGxQYW5lbF9sYWJlbCddID0gJ0FkdmFuY2VkIFRvb2xiYXI/JzsKJGxhbmdbJ2ZlRnVsbFBhbmVsX2hlbHAnXSA9ICdFbmFibGUgYWR2YW5jZWQgdG9vbGJhciBmb3IgaW5saW5lRWRpdC4nOwokbGFuZ1snZmVVcGRhdGVBbGVydF9sYWJlbCddID0gJ1VwZGF0ZSBhbGVydD8nOwokbGFuZ1snZmVVcGRhdGVBbGVydF9oZWxwJ10gPSAnRW5hYmxlIHVwZGF0ZSBhbGVydCBpbiBmcm9udGVuZC4nOwokbGFuZ1snZmVJbmxpbmVFZGl0QnV0dG9uJ10gPSAnaW5saW5lRWRpdCc7CiRsYW5nWydmZVVwZGF0ZUFsZXJ0J10gPSAnQ29udGVudCBoYXMgYmVlbiBzYXZlZC4uLic7CiRsYW5nWydwb3N0aW5zdGFsbCddID0gJ0luc3RhbGwgc3VjY2Vzcy4uLic7CiRsYW5nWydwb3N0dW5pbnN0YWxsJ10gPSAnVW5pbnN0YWxsIHN1Y2Nlc3MuLi4nOwoKPz4K]]></data>
	</file>
	<file>
	  <filename>/LICENSE.txt</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[77u/ICAgICAgICAgICAgICAgICAgICBHTlUgR0VORVJBTCBQVUJMSUMgTElDRU5TRQ0KICAgICAgICAgICAgICAgICAgICAgICBWZXJzaW9uIDIsIEp1bmUgMTk5MQ0KDQogQ29weXJpZ2h0IChDKSAxOTg5LCAxOTkxIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwNCiA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBDQogRXZlcnlvbmUgaXMgcGVybWl0dGVkIHRvIGNvcHkgYW5kIGRpc3RyaWJ1dGUgdmVyYmF0aW0gY29waWVzDQogb2YgdGhpcyBsaWNlbnNlIGRvY3VtZW50LCBidXQgY2hhbmdpbmcgaXQgaXMgbm90IGFsbG93ZWQuDQoNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVhbWJsZQ0KDQogIFRoZSBsaWNlbnNlcyBmb3IgbW9zdCBzb2Z0d2FyZSBhcmUgZGVzaWduZWQgdG8gdGFrZSBhd2F5IHlvdXINCmZyZWVkb20gdG8gc2hhcmUgYW5kIGNoYW5nZSBpdC4gIEJ5IGNvbnRyYXN0LCB0aGUgR05VIEdlbmVyYWwgUHVibGljDQpMaWNlbnNlIGlzIGludGVuZGVkIHRvIGd1YXJhbnRlZSB5b3VyIGZyZWVkb20gdG8gc2hhcmUgYW5kIGNoYW5nZSBmcmVlDQpzb2Z0d2FyZS0tdG8gbWFrZSBzdXJlIHRoZSBzb2Z0d2FyZSBpcyBmcmVlIGZvciBhbGwgaXRzIHVzZXJzLiAgVGhpcw0KR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcHBsaWVzIHRvIG1vc3Qgb2YgdGhlIEZyZWUgU29mdHdhcmUNCkZvdW5kYXRpb24ncyBzb2Z0d2FyZSBhbmQgdG8gYW55IG90aGVyIHByb2dyYW0gd2hvc2UgYXV0aG9ycyBjb21taXQgdG8NCnVzaW5nIGl0LiAgKFNvbWUgb3RoZXIgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIHNvZnR3YXJlIGlzIGNvdmVyZWQgYnkNCnRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgaW5zdGVhZC4pICBZb3UgY2FuIGFwcGx5IGl0IHRvDQp5b3VyIHByb2dyYW1zLCB0b28uDQoNCiAgV2hlbiB3ZSBzcGVhayBvZiBmcmVlIHNvZnR3YXJlLCB3ZSBhcmUgcmVmZXJyaW5nIHRvIGZyZWVkb20sIG5vdA0KcHJpY2UuICBPdXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZXMgYXJlIGRlc2lnbmVkIHRvIG1ha2Ugc3VyZSB0aGF0IHlvdQ0KaGF2ZSB0aGUgZnJlZWRvbSB0byBkaXN0cmlidXRlIGNvcGllcyBvZiBmcmVlIHNvZnR3YXJlIChhbmQgY2hhcmdlIGZvcg0KdGhpcyBzZXJ2aWNlIGlmIHlvdSB3aXNoKSwgdGhhdCB5b3UgcmVjZWl2ZSBzb3VyY2UgY29kZSBvciBjYW4gZ2V0IGl0DQppZiB5b3Ugd2FudCBpdCwgdGhhdCB5b3UgY2FuIGNoYW5nZSB0aGUgc29mdHdhcmUgb3IgdXNlIHBpZWNlcyBvZiBpdA0KaW4gbmV3IGZyZWUgcHJvZ3JhbXM7IGFuZCB0aGF0IHlvdSBrbm93IHlvdSBjYW4gZG8gdGhlc2UgdGhpbmdzLg0KDQogIFRvIHByb3RlY3QgeW91ciByaWdodHMsIHdlIG5lZWQgdG8gbWFrZSByZXN0cmljdGlvbnMgdGhhdCBmb3JiaWQNCmFueW9uZSB0byBkZW55IHlvdSB0aGVzZSByaWdodHMgb3IgdG8gYXNrIHlvdSB0byBzdXJyZW5kZXIgdGhlIHJpZ2h0cy4NClRoZXNlIHJlc3RyaWN0aW9ucyB0cmFuc2xhdGUgdG8gY2VydGFpbiByZXNwb25zaWJpbGl0aWVzIGZvciB5b3UgaWYgeW91DQpkaXN0cmlidXRlIGNvcGllcyBvZiB0aGUgc29mdHdhcmUsIG9yIGlmIHlvdSBtb2RpZnkgaXQuDQoNCiAgRm9yIGV4YW1wbGUsIGlmIHlvdSBkaXN0cmlidXRlIGNvcGllcyBvZiBzdWNoIGEgcHJvZ3JhbSwgd2hldGhlcg0KZ3JhdGlzIG9yIGZvciBhIGZlZSwgeW91IG11c3QgZ2l2ZSB0aGUgcmVjaXBpZW50cyBhbGwgdGhlIHJpZ2h0cyB0aGF0DQp5b3UgaGF2ZS4gIFlvdSBtdXN0IG1ha2Ugc3VyZSB0aGF0IHRoZXksIHRvbywgcmVjZWl2ZSBvciBjYW4gZ2V0IHRoZQ0Kc291cmNlIGNvZGUuICBBbmQgeW91IG11c3Qgc2hvdyB0aGVtIHRoZXNlIHRlcm1zIHNvIHRoZXkga25vdyB0aGVpcg0KcmlnaHRzLg0KDQogIFdlIHByb3RlY3QgeW91ciByaWdodHMgd2l0aCB0d28gc3RlcHM6ICgxKSBjb3B5cmlnaHQgdGhlIHNvZnR3YXJlLCBhbmQNCigyKSBvZmZlciB5b3UgdGhpcyBsaWNlbnNlIHdoaWNoIGdpdmVzIHlvdSBsZWdhbCBwZXJtaXNzaW9uIHRvIGNvcHksDQpkaXN0cmlidXRlIGFuZC9vciBtb2RpZnkgdGhlIHNvZnR3YXJlLg0KDQogIEFsc28sIGZvciBlYWNoIGF1dGhvcidzIHByb3RlY3Rpb24gYW5kIG91cnMsIHdlIHdhbnQgdG8gbWFrZSBjZXJ0YWluDQp0aGF0IGV2ZXJ5b25lIHVuZGVyc3RhbmRzIHRoYXQgdGhlcmUgaXMgbm8gd2FycmFudHkgZm9yIHRoaXMgZnJlZQ0Kc29mdHdhcmUuICBJZiB0aGUgc29mdHdhcmUgaXMgbW9kaWZpZWQgYnkgc29tZW9uZSBlbHNlIGFuZCBwYXNzZWQgb24sIHdlDQp3YW50IGl0cyByZWNpcGllbnRzIHRvIGtub3cgdGhhdCB3aGF0IHRoZXkgaGF2ZSBpcyBub3QgdGhlIG9yaWdpbmFsLCBzbw0KdGhhdCBhbnkgcHJvYmxlbXMgaW50cm9kdWNlZCBieSBvdGhlcnMgd2lsbCBub3QgcmVmbGVjdCBvbiB0aGUgb3JpZ2luYWwNCmF1dGhvcnMnIHJlcHV0YXRpb25zLg0KDQogIEZpbmFsbHksIGFueSBmcmVlIHByb2dyYW0gaXMgdGhyZWF0ZW5lZCBjb25zdGFudGx5IGJ5IHNvZnR3YXJlDQpwYXRlbnRzLiAgV2Ugd2lzaCB0byBhdm9pZCB0aGUgZGFuZ2VyIHRoYXQgcmVkaXN0cmlidXRvcnMgb2YgYSBmcmVlDQpwcm9ncmFtIHdpbGwgaW5kaXZpZHVhbGx5IG9idGFpbiBwYXRlbnQgbGljZW5zZXMsIGluIGVmZmVjdCBtYWtpbmcgdGhlDQpwcm9ncmFtIHByb3ByaWV0YXJ5LiAgVG8gcHJldmVudCB0aGlzLCB3ZSBoYXZlIG1hZGUgaXQgY2xlYXIgdGhhdCBhbnkNCnBhdGVudCBtdXN0IGJlIGxpY2Vuc2VkIGZvciBldmVyeW9uZSdzIGZyZWUgdXNlIG9yIG5vdCBsaWNlbnNlZCBhdCBhbGwuDQoNCiAgVGhlIHByZWNpc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMgZm9yIGNvcHlpbmcsIGRpc3RyaWJ1dGlvbiBhbmQNCm1vZGlmaWNhdGlvbiBmb2xsb3cuDQoNCiAgICAgICAgICAgICAgICAgICAgR05VIEdFTkVSQUwgUFVCTElDIExJQ0VOU0UNCiAgIFRFUk1TIEFORCBDT05ESVRJT05TIEZPUiBDT1BZSU5HLCBESVNUUklCVVRJT04gQU5EIE1PRElGSUNBVElPTg0KDQogIDAuIFRoaXMgTGljZW5zZSBhcHBsaWVzIHRvIGFueSBwcm9ncmFtIG9yIG90aGVyIHdvcmsgd2hpY2ggY29udGFpbnMNCmEgbm90aWNlIHBsYWNlZCBieSB0aGUgY29weXJpZ2h0IGhvbGRlciBzYXlpbmcgaXQgbWF5IGJlIGRpc3RyaWJ1dGVkDQp1bmRlciB0aGUgdGVybXMgb2YgdGhpcyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLiAgVGhlICJQcm9ncmFtIiwgYmVsb3csDQpyZWZlcnMgdG8gYW55IHN1Y2ggcHJvZ3JhbSBvciB3b3JrLCBhbmQgYSAid29yayBiYXNlZCBvbiB0aGUgUHJvZ3JhbSINCm1lYW5zIGVpdGhlciB0aGUgUHJvZ3JhbSBvciBhbnkgZGVyaXZhdGl2ZSB3b3JrIHVuZGVyIGNvcHlyaWdodCBsYXc6DQp0aGF0IGlzIHRvIHNheSwgYSB3b3JrIGNvbnRhaW5pbmcgdGhlIFByb2dyYW0gb3IgYSBwb3J0aW9uIG9mIGl0LA0KZWl0aGVyIHZlcmJhdGltIG9yIHdpdGggbW9kaWZpY2F0aW9ucyBhbmQvb3IgdHJhbnNsYXRlZCBpbnRvIGFub3RoZXINCmxhbmd1YWdlLiAgKEhlcmVpbmFmdGVyLCB0cmFuc2xhdGlvbiBpcyBpbmNsdWRlZCB3aXRob3V0IGxpbWl0YXRpb24gaW4NCnRoZSB0ZXJtICJtb2RpZmljYXRpb24iLikgIEVhY2ggbGljZW5zZWUgaXMgYWRkcmVzc2VkIGFzICJ5b3UiLg0KDQpBY3Rpdml0aWVzIG90aGVyIHRoYW4gY29weWluZywgZGlzdHJpYnV0aW9uIGFuZCBtb2RpZmljYXRpb24gYXJlIG5vdA0KY292ZXJlZCBieSB0aGlzIExpY2Vuc2U7IHRoZXkgYXJlIG91dHNpZGUgaXRzIHNjb3BlLiAgVGhlIGFjdCBvZg0KcnVubmluZyB0aGUgUHJvZ3JhbSBpcyBub3QgcmVzdHJpY3RlZCwgYW5kIHRoZSBvdXRwdXQgZnJvbSB0aGUgUHJvZ3JhbQ0KaXMgY292ZXJlZCBvbmx5IGlmIGl0cyBjb250ZW50cyBjb25zdGl0dXRlIGEgd29yayBiYXNlZCBvbiB0aGUNClByb2dyYW0gKGluZGVwZW5kZW50IG9mIGhhdmluZyBiZWVuIG1hZGUgYnkgcnVubmluZyB0aGUgUHJvZ3JhbSkuDQpXaGV0aGVyIHRoYXQgaXMgdHJ1ZSBkZXBlbmRzIG9uIHdoYXQgdGhlIFByb2dyYW0gZG9lcy4NCg0KICAxLiBZb3UgbWF5IGNvcHkgYW5kIGRpc3RyaWJ1dGUgdmVyYmF0aW0gY29waWVzIG9mIHRoZSBQcm9ncmFtJ3MNCnNvdXJjZSBjb2RlIGFzIHlvdSByZWNlaXZlIGl0LCBpbiBhbnkgbWVkaXVtLCBwcm92aWRlZCB0aGF0IHlvdQ0KY29uc3BpY3VvdXNseSBhbmQgYXBwcm9wcmlhdGVseSBwdWJsaXNoIG9uIGVhY2ggY29weSBhbiBhcHByb3ByaWF0ZQ0KY29weXJpZ2h0IG5vdGljZSBhbmQgZGlzY2xhaW1lciBvZiB3YXJyYW50eTsga2VlcCBpbnRhY3QgYWxsIHRoZQ0Kbm90aWNlcyB0aGF0IHJlZmVyIHRvIHRoaXMgTGljZW5zZSBhbmQgdG8gdGhlIGFic2VuY2Ugb2YgYW55IHdhcnJhbnR5Ow0KYW5kIGdpdmUgYW55IG90aGVyIHJlY2lwaWVudHMgb2YgdGhlIFByb2dyYW0gYSBjb3B5IG9mIHRoaXMgTGljZW5zZQ0KYWxvbmcgd2l0aCB0aGUgUHJvZ3JhbS4NCg0KWW91IG1heSBjaGFyZ2UgYSBmZWUgZm9yIHRoZSBwaHlzaWNhbCBhY3Qgb2YgdHJhbnNmZXJyaW5nIGEgY29weSwgYW5kDQp5b3UgbWF5IGF0IHlvdXIgb3B0aW9uIG9mZmVyIHdhcnJhbnR5IHByb3RlY3Rpb24gaW4gZXhjaGFuZ2UgZm9yIGEgZmVlLg0KDQogIDIuIFlvdSBtYXkgbW9kaWZ5IHlvdXIgY29weSBvciBjb3BpZXMgb2YgdGhlIFByb2dyYW0gb3IgYW55IHBvcnRpb24NCm9mIGl0LCB0aHVzIGZvcm1pbmcgYSB3b3JrIGJhc2VkIG9uIHRoZSBQcm9ncmFtLCBhbmQgY29weSBhbmQNCmRpc3RyaWJ1dGUgc3VjaCBtb2RpZmljYXRpb25zIG9yIHdvcmsgdW5kZXIgdGhlIHRlcm1zIG9mIFNlY3Rpb24gMQ0KYWJvdmUsIHByb3ZpZGVkIHRoYXQgeW91IGFsc28gbWVldCBhbGwgb2YgdGhlc2UgY29uZGl0aW9uczoNCg0KICAgIGEpIFlvdSBtdXN0IGNhdXNlIHRoZSBtb2RpZmllZCBmaWxlcyB0byBjYXJyeSBwcm9taW5lbnQgbm90aWNlcw0KICAgIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgZmlsZXMgYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuDQoNCiAgICBiKSBZb3UgbXVzdCBjYXVzZSBhbnkgd29yayB0aGF0IHlvdSBkaXN0cmlidXRlIG9yIHB1Ymxpc2gsIHRoYXQgaW4NCiAgICB3aG9sZSBvciBpbiBwYXJ0IGNvbnRhaW5zIG9yIGlzIGRlcml2ZWQgZnJvbSB0aGUgUHJvZ3JhbSBvciBhbnkNCiAgICBwYXJ0IHRoZXJlb2YsIHRvIGJlIGxpY2Vuc2VkIGFzIGEgd2hvbGUgYXQgbm8gY2hhcmdlIHRvIGFsbCB0aGlyZA0KICAgIHBhcnRpZXMgdW5kZXIgdGhlIHRlcm1zIG9mIHRoaXMgTGljZW5zZS4NCg0KICAgIGMpIElmIHRoZSBtb2RpZmllZCBwcm9ncmFtIG5vcm1hbGx5IHJlYWRzIGNvbW1hbmRzIGludGVyYWN0aXZlbHkNCiAgICB3aGVuIHJ1biwgeW91IG11c3QgY2F1c2UgaXQsIHdoZW4gc3RhcnRlZCBydW5uaW5nIGZvciBzdWNoDQogICAgaW50ZXJhY3RpdmUgdXNlIGluIHRoZSBtb3N0IG9yZGluYXJ5IHdheSwgdG8gcHJpbnQgb3IgZGlzcGxheSBhbg0KICAgIGFubm91bmNlbWVudCBpbmNsdWRpbmcgYW4gYXBwcm9wcmlhdGUgY29weXJpZ2h0IG5vdGljZSBhbmQgYQ0KICAgIG5vdGljZSB0aGF0IHRoZXJlIGlzIG5vIHdhcnJhbnR5IChvciBlbHNlLCBzYXlpbmcgdGhhdCB5b3UgcHJvdmlkZQ0KICAgIGEgd2FycmFudHkpIGFuZCB0aGF0IHVzZXJzIG1heSByZWRpc3RyaWJ1dGUgdGhlIHByb2dyYW0gdW5kZXINCiAgICB0aGVzZSBjb25kaXRpb25zLCBhbmQgdGVsbGluZyB0aGUgdXNlciBob3cgdG8gdmlldyBhIGNvcHkgb2YgdGhpcw0KICAgIExpY2Vuc2UuICAoRXhjZXB0aW9uOiBpZiB0aGUgUHJvZ3JhbSBpdHNlbGYgaXMgaW50ZXJhY3RpdmUgYnV0DQogICAgZG9lcyBub3Qgbm9ybWFsbHkgcHJpbnQgc3VjaCBhbiBhbm5vdW5jZW1lbnQsIHlvdXIgd29yayBiYXNlZCBvbg0KICAgIHRoZSBQcm9ncmFtIGlzIG5vdCByZXF1aXJlZCB0byBwcmludCBhbiBhbm5vdW5jZW1lbnQuKQ0KDQpUaGVzZSByZXF1aXJlbWVudHMgYXBwbHkgdG8gdGhlIG1vZGlmaWVkIHdvcmsgYXMgYSB3aG9sZS4gIElmDQppZGVudGlmaWFibGUgc2VjdGlvbnMgb2YgdGhhdCB3b3JrIGFyZSBub3QgZGVyaXZlZCBmcm9tIHRoZSBQcm9ncmFtLA0KYW5kIGNhbiBiZSByZWFzb25hYmx5IGNvbnNpZGVyZWQgaW5kZXBlbmRlbnQgYW5kIHNlcGFyYXRlIHdvcmtzIGluDQp0aGVtc2VsdmVzLCB0aGVuIHRoaXMgTGljZW5zZSwgYW5kIGl0cyB0ZXJtcywgZG8gbm90IGFwcGx5IHRvIHRob3NlDQpzZWN0aW9ucyB3aGVuIHlvdSBkaXN0cmlidXRlIHRoZW0gYXMgc2VwYXJhdGUgd29ya3MuICBCdXQgd2hlbiB5b3UNCmRpc3RyaWJ1dGUgdGhlIHNhbWUgc2VjdGlvbnMgYXMgcGFydCBvZiBhIHdob2xlIHdoaWNoIGlzIGEgd29yayBiYXNlZA0Kb24gdGhlIFByb2dyYW0sIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIHdob2xlIG11c3QgYmUgb24gdGhlIHRlcm1zIG9mDQp0aGlzIExpY2Vuc2UsIHdob3NlIHBlcm1pc3Npb25zIGZvciBvdGhlciBsaWNlbnNlZXMgZXh0ZW5kIHRvIHRoZQ0KZW50aXJlIHdob2xlLCBhbmQgdGh1cyB0byBlYWNoIGFuZCBldmVyeSBwYXJ0IHJlZ2FyZGxlc3Mgb2Ygd2hvIHdyb3RlIGl0Lg0KDQpUaHVzLCBpdCBpcyBub3QgdGhlIGludGVudCBvZiB0aGlzIHNlY3Rpb24gdG8gY2xhaW0gcmlnaHRzIG9yIGNvbnRlc3QNCnlvdXIgcmlnaHRzIHRvIHdvcmsgd3JpdHRlbiBlbnRpcmVseSBieSB5b3U7IHJhdGhlciwgdGhlIGludGVudCBpcyB0bw0KZXhlcmNpc2UgdGhlIHJpZ2h0IHRvIGNvbnRyb2wgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkZXJpdmF0aXZlIG9yDQpjb2xsZWN0aXZlIHdvcmtzIGJhc2VkIG9uIHRoZSBQcm9ncmFtLg0KDQpJbiBhZGRpdGlvbiwgbWVyZSBhZ2dyZWdhdGlvbiBvZiBhbm90aGVyIHdvcmsgbm90IGJhc2VkIG9uIHRoZSBQcm9ncmFtDQp3aXRoIHRoZSBQcm9ncmFtIChvciB3aXRoIGEgd29yayBiYXNlZCBvbiB0aGUgUHJvZ3JhbSkgb24gYSB2b2x1bWUgb2YNCmEgc3RvcmFnZSBvciBkaXN0cmlidXRpb24gbWVkaXVtIGRvZXMgbm90IGJyaW5nIHRoZSBvdGhlciB3b3JrIHVuZGVyDQp0aGUgc2NvcGUgb2YgdGhpcyBMaWNlbnNlLg0KDQogIDMuIFlvdSBtYXkgY29weSBhbmQgZGlzdHJpYnV0ZSB0aGUgUHJvZ3JhbSAob3IgYSB3b3JrIGJhc2VkIG9uIGl0LA0KdW5kZXIgU2VjdGlvbiAyKSBpbiBvYmplY3QgY29kZSBvciBleGVjdXRhYmxlIGZvcm0gdW5kZXIgdGhlIHRlcm1zIG9mDQpTZWN0aW9ucyAxIGFuZCAyIGFib3ZlIHByb3ZpZGVkIHRoYXQgeW91IGFsc28gZG8gb25lIG9mIHRoZSBmb2xsb3dpbmc6DQoNCiAgICBhKSBBY2NvbXBhbnkgaXQgd2l0aCB0aGUgY29tcGxldGUgY29ycmVzcG9uZGluZyBtYWNoaW5lLXJlYWRhYmxlDQogICAgc291cmNlIGNvZGUsIHdoaWNoIG11c3QgYmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIFNlY3Rpb25zDQogICAgMSBhbmQgMiBhYm92ZSBvbiBhIG1lZGl1bSBjdXN0b21hcmlseSB1c2VkIGZvciBzb2Z0d2FyZSBpbnRlcmNoYW5nZTsgb3IsDQoNCiAgICBiKSBBY2NvbXBhbnkgaXQgd2l0aCBhIHdyaXR0ZW4gb2ZmZXIsIHZhbGlkIGZvciBhdCBsZWFzdCB0aHJlZQ0KICAgIHllYXJzLCB0byBnaXZlIGFueSB0aGlyZCBwYXJ0eSwgZm9yIGEgY2hhcmdlIG5vIG1vcmUgdGhhbiB5b3VyDQogICAgY29zdCBvZiBwaHlzaWNhbGx5IHBlcmZvcm1pbmcgc291cmNlIGRpc3RyaWJ1dGlvbiwgYSBjb21wbGV0ZQ0KICAgIG1hY2hpbmUtcmVhZGFibGUgY29weSBvZiB0aGUgY29ycmVzcG9uZGluZyBzb3VyY2UgY29kZSwgdG8gYmUNCiAgICBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgU2VjdGlvbnMgMSBhbmQgMiBhYm92ZSBvbiBhIG1lZGl1bQ0KICAgIGN1c3RvbWFyaWx5IHVzZWQgZm9yIHNvZnR3YXJlIGludGVyY2hhbmdlOyBvciwNCg0KICAgIGMpIEFjY29tcGFueSBpdCB3aXRoIHRoZSBpbmZvcm1hdGlvbiB5b3UgcmVjZWl2ZWQgYXMgdG8gdGhlIG9mZmVyDQogICAgdG8gZGlzdHJpYnV0ZSBjb3JyZXNwb25kaW5nIHNvdXJjZSBjb2RlLiAgKFRoaXMgYWx0ZXJuYXRpdmUgaXMNCiAgICBhbGxvd2VkIG9ubHkgZm9yIG5vbmNvbW1lcmNpYWwgZGlzdHJpYnV0aW9uIGFuZCBvbmx5IGlmIHlvdQ0KICAgIHJlY2VpdmVkIHRoZSBwcm9ncmFtIGluIG9iamVjdCBjb2RlIG9yIGV4ZWN1dGFibGUgZm9ybSB3aXRoIHN1Y2gNCiAgICBhbiBvZmZlciwgaW4gYWNjb3JkIHdpdGggU3Vic2VjdGlvbiBiIGFib3ZlLikNCg0KVGhlIHNvdXJjZSBjb2RlIGZvciBhIHdvcmsgbWVhbnMgdGhlIHByZWZlcnJlZCBmb3JtIG9mIHRoZSB3b3JrIGZvcg0KbWFraW5nIG1vZGlmaWNhdGlvbnMgdG8gaXQuICBGb3IgYW4gZXhlY3V0YWJsZSB3b3JrLCBjb21wbGV0ZSBzb3VyY2UNCmNvZGUgbWVhbnMgYWxsIHRoZSBzb3VyY2UgY29kZSBmb3IgYWxsIG1vZHVsZXMgaXQgY29udGFpbnMsIHBsdXMgYW55DQphc3NvY2lhdGVkIGludGVyZmFjZSBkZWZpbml0aW9uIGZpbGVzLCBwbHVzIHRoZSBzY3JpcHRzIHVzZWQgdG8NCmNvbnRyb2wgY29tcGlsYXRpb24gYW5kIGluc3RhbGxhdGlvbiBvZiB0aGUgZXhlY3V0YWJsZS4gIEhvd2V2ZXIsIGFzIGENCnNwZWNpYWwgZXhjZXB0aW9uLCB0aGUgc291cmNlIGNvZGUgZGlzdHJpYnV0ZWQgbmVlZCBub3QgaW5jbHVkZQ0KYW55dGhpbmcgdGhhdCBpcyBub3JtYWxseSBkaXN0cmlidXRlZCAoaW4gZWl0aGVyIHNvdXJjZSBvciBiaW5hcnkNCmZvcm0pIHdpdGggdGhlIG1ham9yIGNvbXBvbmVudHMgKGNvbXBpbGVyLCBrZXJuZWwsIGFuZCBzbyBvbikgb2YgdGhlDQpvcGVyYXRpbmcgc3lzdGVtIG9uIHdoaWNoIHRoZSBleGVjdXRhYmxlIHJ1bnMsIHVubGVzcyB0aGF0IGNvbXBvbmVudA0KaXRzZWxmIGFjY29tcGFuaWVzIHRoZSBleGVjdXRhYmxlLg0KDQpJZiBkaXN0cmlidXRpb24gb2YgZXhlY3V0YWJsZSBvciBvYmplY3QgY29kZSBpcyBtYWRlIGJ5IG9mZmVyaW5nDQphY2Nlc3MgdG8gY29weSBmcm9tIGEgZGVzaWduYXRlZCBwbGFjZSwgdGhlbiBvZmZlcmluZyBlcXVpdmFsZW50DQphY2Nlc3MgdG8gY29weSB0aGUgc291cmNlIGNvZGUgZnJvbSB0aGUgc2FtZSBwbGFjZSBjb3VudHMgYXMNCmRpc3RyaWJ1dGlvbiBvZiB0aGUgc291cmNlIGNvZGUsIGV2ZW4gdGhvdWdoIHRoaXJkIHBhcnRpZXMgYXJlIG5vdA0KY29tcGVsbGVkIHRvIGNvcHkgdGhlIHNvdXJjZSBhbG9uZyB3aXRoIHRoZSBvYmplY3QgY29kZS4NCg0KICA0LiBZb3UgbWF5IG5vdCBjb3B5LCBtb2RpZnksIHN1YmxpY2Vuc2UsIG9yIGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0NCmV4Y2VwdCBhcyBleHByZXNzbHkgcHJvdmlkZWQgdW5kZXIgdGhpcyBMaWNlbnNlLiAgQW55IGF0dGVtcHQNCm90aGVyd2lzZSB0byBjb3B5LCBtb2RpZnksIHN1YmxpY2Vuc2Ugb3IgZGlzdHJpYnV0ZSB0aGUgUHJvZ3JhbSBpcw0Kdm9pZCwgYW5kIHdpbGwgYXV0b21hdGljYWxseSB0ZXJtaW5hdGUgeW91ciByaWdodHMgdW5kZXIgdGhpcyBMaWNlbnNlLg0KSG93ZXZlciwgcGFydGllcyB3aG8gaGF2ZSByZWNlaXZlZCBjb3BpZXMsIG9yIHJpZ2h0cywgZnJvbSB5b3UgdW5kZXINCnRoaXMgTGljZW5zZSB3aWxsIG5vdCBoYXZlIHRoZWlyIGxpY2Vuc2VzIHRlcm1pbmF0ZWQgc28gbG9uZyBhcyBzdWNoDQpwYXJ0aWVzIHJlbWFpbiBpbiBmdWxsIGNvbXBsaWFuY2UuDQoNCiAgNS4gWW91IGFyZSBub3QgcmVxdWlyZWQgdG8gYWNjZXB0IHRoaXMgTGljZW5zZSwgc2luY2UgeW91IGhhdmUgbm90DQpzaWduZWQgaXQuICBIb3dldmVyLCBub3RoaW5nIGVsc2UgZ3JhbnRzIHlvdSBwZXJtaXNzaW9uIHRvIG1vZGlmeSBvcg0KZGlzdHJpYnV0ZSB0aGUgUHJvZ3JhbSBvciBpdHMgZGVyaXZhdGl2ZSB3b3Jrcy4gIFRoZXNlIGFjdGlvbnMgYXJlDQpwcm9oaWJpdGVkIGJ5IGxhdyBpZiB5b3UgZG8gbm90IGFjY2VwdCB0aGlzIExpY2Vuc2UuICBUaGVyZWZvcmUsIGJ5DQptb2RpZnlpbmcgb3IgZGlzdHJpYnV0aW5nIHRoZSBQcm9ncmFtIChvciBhbnkgd29yayBiYXNlZCBvbiB0aGUNClByb2dyYW0pLCB5b3UgaW5kaWNhdGUgeW91ciBhY2NlcHRhbmNlIG9mIHRoaXMgTGljZW5zZSB0byBkbyBzbywgYW5kDQphbGwgaXRzIHRlcm1zIGFuZCBjb25kaXRpb25zIGZvciBjb3B5aW5nLCBkaXN0cmlidXRpbmcgb3IgbW9kaWZ5aW5nDQp0aGUgUHJvZ3JhbSBvciB3b3JrcyBiYXNlZCBvbiBpdC4NCg0KICA2LiBFYWNoIHRpbWUgeW91IHJlZGlzdHJpYnV0ZSB0aGUgUHJvZ3JhbSAob3IgYW55IHdvcmsgYmFzZWQgb24gdGhlDQpQcm9ncmFtKSwgdGhlIHJlY2lwaWVudCBhdXRvbWF0aWNhbGx5IHJlY2VpdmVzIGEgbGljZW5zZSBmcm9tIHRoZQ0Kb3JpZ2luYWwgbGljZW5zb3IgdG8gY29weSwgZGlzdHJpYnV0ZSBvciBtb2RpZnkgdGhlIFByb2dyYW0gc3ViamVjdCB0bw0KdGhlc2UgdGVybXMgYW5kIGNvbmRpdGlvbnMuICBZb3UgbWF5IG5vdCBpbXBvc2UgYW55IGZ1cnRoZXINCnJlc3RyaWN0aW9ucyBvbiB0aGUgcmVjaXBpZW50cycgZXhlcmNpc2Ugb2YgdGhlIHJpZ2h0cyBncmFudGVkIGhlcmVpbi4NCllvdSBhcmUgbm90IHJlc3BvbnNpYmxlIGZvciBlbmZvcmNpbmcgY29tcGxpYW5jZSBieSB0aGlyZCBwYXJ0aWVzIHRvDQp0aGlzIExpY2Vuc2UuDQoNCiAgNy4gSWYsIGFzIGEgY29uc2VxdWVuY2Ugb2YgYSBjb3VydCBqdWRnbWVudCBvciBhbGxlZ2F0aW9uIG9mIHBhdGVudA0KaW5mcmluZ2VtZW50IG9yIGZvciBhbnkgb3RoZXIgcmVhc29uIChub3QgbGltaXRlZCB0byBwYXRlbnQgaXNzdWVzKSwNCmNvbmRpdGlvbnMgYXJlIGltcG9zZWQgb24geW91ICh3aGV0aGVyIGJ5IGNvdXJ0IG9yZGVyLCBhZ3JlZW1lbnQgb3INCm90aGVyd2lzZSkgdGhhdCBjb250cmFkaWN0IHRoZSBjb25kaXRpb25zIG9mIHRoaXMgTGljZW5zZSwgdGhleSBkbyBub3QNCmV4Y3VzZSB5b3UgZnJvbSB0aGUgY29uZGl0aW9ucyBvZiB0aGlzIExpY2Vuc2UuICBJZiB5b3UgY2Fubm90DQpkaXN0cmlidXRlIHNvIGFzIHRvIHNhdGlzZnkgc2ltdWx0YW5lb3VzbHkgeW91ciBvYmxpZ2F0aW9ucyB1bmRlciB0aGlzDQpMaWNlbnNlIGFuZCBhbnkgb3RoZXIgcGVydGluZW50IG9ibGlnYXRpb25zLCB0aGVuIGFzIGEgY29uc2VxdWVuY2UgeW91DQptYXkgbm90IGRpc3RyaWJ1dGUgdGhlIFByb2dyYW0gYXQgYWxsLiAgRm9yIGV4YW1wbGUsIGlmIGEgcGF0ZW50DQpsaWNlbnNlIHdvdWxkIG5vdCBwZXJtaXQgcm95YWx0eS1mcmVlIHJlZGlzdHJpYnV0aW9uIG9mIHRoZSBQcm9ncmFtIGJ5DQphbGwgdGhvc2Ugd2hvIHJlY2VpdmUgY29waWVzIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkgdGhyb3VnaCB5b3UsIHRoZW4NCnRoZSBvbmx5IHdheSB5b3UgY291bGQgc2F0aXNmeSBib3RoIGl0IGFuZCB0aGlzIExpY2Vuc2Ugd291bGQgYmUgdG8NCnJlZnJhaW4gZW50aXJlbHkgZnJvbSBkaXN0cmlidXRpb24gb2YgdGhlIFByb2dyYW0uDQoNCklmIGFueSBwb3J0aW9uIG9mIHRoaXMgc2VjdGlvbiBpcyBoZWxkIGludmFsaWQgb3IgdW5lbmZvcmNlYWJsZSB1bmRlcg0KYW55IHBhcnRpY3VsYXIgY2lyY3Vtc3RhbmNlLCB0aGUgYmFsYW5jZSBvZiB0aGUgc2VjdGlvbiBpcyBpbnRlbmRlZCB0bw0KYXBwbHkgYW5kIHRoZSBzZWN0aW9uIGFzIGEgd2hvbGUgaXMgaW50ZW5kZWQgdG8gYXBwbHkgaW4gb3RoZXINCmNpcmN1bXN0YW5jZXMuDQoNCkl0IGlzIG5vdCB0aGUgcHVycG9zZSBvZiB0aGlzIHNlY3Rpb24gdG8gaW5kdWNlIHlvdSB0byBpbmZyaW5nZSBhbnkNCnBhdGVudHMgb3Igb3RoZXIgcHJvcGVydHkgcmlnaHQgY2xhaW1zIG9yIHRvIGNvbnRlc3QgdmFsaWRpdHkgb2YgYW55DQpzdWNoIGNsYWltczsgdGhpcyBzZWN0aW9uIGhhcyB0aGUgc29sZSBwdXJwb3NlIG9mIHByb3RlY3RpbmcgdGhlDQppbnRlZ3JpdHkgb2YgdGhlIGZyZWUgc29mdHdhcmUgZGlzdHJpYnV0aW9uIHN5c3RlbSwgd2hpY2ggaXMNCmltcGxlbWVudGVkIGJ5IHB1YmxpYyBsaWNlbnNlIHByYWN0aWNlcy4gIE1hbnkgcGVvcGxlIGhhdmUgbWFkZQ0KZ2VuZXJvdXMgY29udHJpYnV0aW9ucyB0byB0aGUgd2lkZSByYW5nZSBvZiBzb2Z0d2FyZSBkaXN0cmlidXRlZA0KdGhyb3VnaCB0aGF0IHN5c3RlbSBpbiByZWxpYW5jZSBvbiBjb25zaXN0ZW50IGFwcGxpY2F0aW9uIG9mIHRoYXQNCnN5c3RlbTsgaXQgaXMgdXAgdG8gdGhlIGF1dGhvci9kb25vciB0byBkZWNpZGUgaWYgaGUgb3Igc2hlIGlzIHdpbGxpbmcNCnRvIGRpc3RyaWJ1dGUgc29mdHdhcmUgdGhyb3VnaCBhbnkgb3RoZXIgc3lzdGVtIGFuZCBhIGxpY2Vuc2VlIGNhbm5vdA0KaW1wb3NlIHRoYXQgY2hvaWNlLg0KDQpUaGlzIHNlY3Rpb24gaXMgaW50ZW5kZWQgdG8gbWFrZSB0aG9yb3VnaGx5IGNsZWFyIHdoYXQgaXMgYmVsaWV2ZWQgdG8NCmJlIGEgY29uc2VxdWVuY2Ugb2YgdGhlIHJlc3Qgb2YgdGhpcyBMaWNlbnNlLg0KDQogIDguIElmIHRoZSBkaXN0cmlidXRpb24gYW5kL29yIHVzZSBvZiB0aGUgUHJvZ3JhbSBpcyByZXN0cmljdGVkIGluDQpjZXJ0YWluIGNvdW50cmllcyBlaXRoZXIgYnkgcGF0ZW50cyBvciBieSBjb3B5cmlnaHRlZCBpbnRlcmZhY2VzLCB0aGUNCm9yaWdpbmFsIGNvcHlyaWdodCBob2xkZXIgd2hvIHBsYWNlcyB0aGUgUHJvZ3JhbSB1bmRlciB0aGlzIExpY2Vuc2UNCm1heSBhZGQgYW4gZXhwbGljaXQgZ2VvZ3JhcGhpY2FsIGRpc3RyaWJ1dGlvbiBsaW1pdGF0aW9uIGV4Y2x1ZGluZw0KdGhvc2UgY291bnRyaWVzLCBzbyB0aGF0IGRpc3RyaWJ1dGlvbiBpcyBwZXJtaXR0ZWQgb25seSBpbiBvciBhbW9uZw0KY291bnRyaWVzIG5vdCB0aHVzIGV4Y2x1ZGVkLiAgSW4gc3VjaCBjYXNlLCB0aGlzIExpY2Vuc2UgaW5jb3Jwb3JhdGVzDQp0aGUgbGltaXRhdGlvbiBhcyBpZiB3cml0dGVuIGluIHRoZSBib2R5IG9mIHRoaXMgTGljZW5zZS4NCg0KICA5LiBUaGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIG1heSBwdWJsaXNoIHJldmlzZWQgYW5kL29yIG5ldyB2ZXJzaW9ucw0Kb2YgdGhlIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZnJvbSB0aW1lIHRvIHRpbWUuICBTdWNoIG5ldyB2ZXJzaW9ucyB3aWxsDQpiZSBzaW1pbGFyIGluIHNwaXJpdCB0byB0aGUgcHJlc2VudCB2ZXJzaW9uLCBidXQgbWF5IGRpZmZlciBpbiBkZXRhaWwgdG8NCmFkZHJlc3MgbmV3IHByb2JsZW1zIG9yIGNvbmNlcm5zLg0KDQpFYWNoIHZlcnNpb24gaXMgZ2l2ZW4gYSBkaXN0aW5ndWlzaGluZyB2ZXJzaW9uIG51bWJlci4gIElmIHRoZSBQcm9ncmFtDQpzcGVjaWZpZXMgYSB2ZXJzaW9uIG51bWJlciBvZiB0aGlzIExpY2Vuc2Ugd2hpY2ggYXBwbGllcyB0byBpdCBhbmQgImFueQ0KbGF0ZXIgdmVyc2lvbiIsIHlvdSBoYXZlIHRoZSBvcHRpb24gb2YgZm9sbG93aW5nIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucw0KZWl0aGVyIG9mIHRoYXQgdmVyc2lvbiBvciBvZiBhbnkgbGF0ZXIgdmVyc2lvbiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUNClNvZnR3YXJlIEZvdW5kYXRpb24uICBJZiB0aGUgUHJvZ3JhbSBkb2VzIG5vdCBzcGVjaWZ5IGEgdmVyc2lvbiBudW1iZXIgb2YNCnRoaXMgTGljZW5zZSwgeW91IG1heSBjaG9vc2UgYW55IHZlcnNpb24gZXZlciBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUNCkZvdW5kYXRpb24uDQoNCiAgMTAuIElmIHlvdSB3aXNoIHRvIGluY29ycG9yYXRlIHBhcnRzIG9mIHRoZSBQcm9ncmFtIGludG8gb3RoZXIgZnJlZQ0KcHJvZ3JhbXMgd2hvc2UgZGlzdHJpYnV0aW9uIGNvbmRpdGlvbnMgYXJlIGRpZmZlcmVudCwgd3JpdGUgdG8gdGhlIGF1dGhvcg0KdG8gYXNrIGZvciBwZXJtaXNzaW9uLiAgRm9yIHNvZnR3YXJlIHdoaWNoIGlzIGNvcHlyaWdodGVkIGJ5IHRoZSBGcmVlDQpTb2Z0d2FyZSBGb3VuZGF0aW9uLCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyB3ZSBzb21ldGltZXMNCm1ha2UgZXhjZXB0aW9ucyBmb3IgdGhpcy4gIE91ciBkZWNpc2lvbiB3aWxsIGJlIGd1aWRlZCBieSB0aGUgdHdvIGdvYWxzDQpvZiBwcmVzZXJ2aW5nIHRoZSBmcmVlIHN0YXR1cyBvZiBhbGwgZGVyaXZhdGl2ZXMgb2Ygb3VyIGZyZWUgc29mdHdhcmUgYW5kDQpvZiBwcm9tb3RpbmcgdGhlIHNoYXJpbmcgYW5kIHJldXNlIG9mIHNvZnR3YXJlIGdlbmVyYWxseS4NCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5PIFdBUlJBTlRZDQoNCiAgMTEuIEJFQ0FVU0UgVEhFIFBST0dSQU0gSVMgTElDRU5TRUQgRlJFRSBPRiBDSEFSR0UsIFRIRVJFIElTIE5PIFdBUlJBTlRZDQpGT1IgVEhFIFBST0dSQU0sIFRPIFRIRSBFWFRFTlQgUEVSTUlUVEVEIEJZIEFQUExJQ0FCTEUgTEFXLiAgRVhDRVBUIFdIRU4NCk9USEVSV0lTRSBTVEFURUQgSU4gV1JJVElORyBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EL09SIE9USEVSIFBBUlRJRVMNClBST1ZJREUgVEhFIFBST0dSQU0gIkFTIElTIiBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEDQpPUiBJTVBMSUVELCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRg0KTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFRIRSBFTlRJUkUgUklTSyBBUw0KVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBQUk9HUkFNIElTIFdJVEggWU9VLiAgU0hPVUxEIFRIRQ0KUFJPR1JBTSBQUk9WRSBERUZFQ1RJVkUsIFlPVSBBU1NVTUUgVEhFIENPU1QgT0YgQUxMIE5FQ0VTU0FSWSBTRVJWSUNJTkcsDQpSRVBBSVIgT1IgQ09SUkVDVElPTi4NCg0KICAxMi4gSU4gTk8gRVZFTlQgVU5MRVNTIFJFUVVJUkVEIEJZIEFQUExJQ0FCTEUgTEFXIE9SIEFHUkVFRCBUTyBJTiBXUklUSU5HDQpXSUxMIEFOWSBDT1BZUklHSFQgSE9MREVSLCBPUiBBTlkgT1RIRVIgUEFSVFkgV0hPIE1BWSBNT0RJRlkgQU5EL09SDQpSRURJU1RSSUJVVEUgVEhFIFBST0dSQU0gQVMgUEVSTUlUVEVEIEFCT1ZFLCBCRSBMSUFCTEUgVE8gWU9VIEZPUiBEQU1BR0VTLA0KSU5DTFVESU5HIEFOWSBHRU5FUkFMLCBTUEVDSUFMLCBJTkNJREVOVEFMIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBBUklTSU5HDQpPVVQgT0YgVEhFIFVTRSBPUiBJTkFCSUxJVFkgVE8gVVNFIFRIRSBQUk9HUkFNIChJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEDQpUTyBMT1NTIE9GIERBVEEgT1IgREFUQSBCRUlORyBSRU5ERVJFRCBJTkFDQ1VSQVRFIE9SIExPU1NFUyBTVVNUQUlORUQgQlkNCllPVSBPUiBUSElSRCBQQVJUSUVTIE9SIEEgRkFJTFVSRSBPRiBUSEUgUFJPR1JBTSBUTyBPUEVSQVRFIFdJVEggQU5ZIE9USEVSDQpQUk9HUkFNUyksIEVWRU4gSUYgU1VDSCBIT0xERVIgT1IgT1RIRVIgUEFSVFkgSEFTIEJFRU4gQURWSVNFRCBPRiBUSEUNClBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFUy4NCg0KICAgICAgICAgICAgICAgICAgICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TDQoNCiAgICAgICAgICAgIEhvdyB0byBBcHBseSBUaGVzZSBUZXJtcyB0byBZb3VyIE5ldyBQcm9ncmFtcw0KDQogIElmIHlvdSBkZXZlbG9wIGEgbmV3IHByb2dyYW0sIGFuZCB5b3Ugd2FudCBpdCB0byBiZSBvZiB0aGUgZ3JlYXRlc3QNCnBvc3NpYmxlIHVzZSB0byB0aGUgcHVibGljLCB0aGUgYmVzdCB3YXkgdG8gYWNoaWV2ZSB0aGlzIGlzIHRvIG1ha2UgaXQNCmZyZWUgc29mdHdhcmUgd2hpY2ggZXZlcnlvbmUgY2FuIHJlZGlzdHJpYnV0ZSBhbmQgY2hhbmdlIHVuZGVyIHRoZXNlIHRlcm1zLg0KDQogIFRvIGRvIHNvLCBhdHRhY2ggdGhlIGZvbGxvd2luZyBub3RpY2VzIHRvIHRoZSBwcm9ncmFtLiAgSXQgaXMgc2FmZXN0DQp0byBhdHRhY2ggdGhlbSB0byB0aGUgc3RhcnQgb2YgZWFjaCBzb3VyY2UgZmlsZSB0byBtb3N0IGVmZmVjdGl2ZWx5DQpjb252ZXkgdGhlIGV4Y2x1c2lvbiBvZiB3YXJyYW50eTsgYW5kIGVhY2ggZmlsZSBzaG91bGQgaGF2ZSBhdCBsZWFzdA0KdGhlICJjb3B5cmlnaHQiIGxpbmUgYW5kIGEgcG9pbnRlciB0byB3aGVyZSB0aGUgZnVsbCBub3RpY2UgaXMgZm91bmQuDQoNCiAgICA8b25lIGxpbmUgdG8gZ2l2ZSB0aGUgcHJvZ3JhbSdzIG5hbWUgYW5kIGEgYnJpZWYgaWRlYSBvZiB3aGF0IGl0IGRvZXMuPg0KICAgIENvcHlyaWdodCAoQykgPHllYXI+ICA8bmFtZSBvZiBhdXRob3I+DQoNCiAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQ0KICAgIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5DQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3INCiAgICAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLg0KDQogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsDQogICAgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCiAgICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlDQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4NCg0KICAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nDQogICAgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwNCiAgICA1MSBGcmFua2xpbiBTdHJlZXQsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEgVVNBLg0KDQpBbHNvIGFkZCBpbmZvcm1hdGlvbiBvbiBob3cgdG8gY29udGFjdCB5b3UgYnkgZWxlY3Ryb25pYyBhbmQgcGFwZXIgbWFpbC4NCg0KSWYgdGhlIHByb2dyYW0gaXMgaW50ZXJhY3RpdmUsIG1ha2UgaXQgb3V0cHV0IGEgc2hvcnQgbm90aWNlIGxpa2UgdGhpcw0Kd2hlbiBpdCBzdGFydHMgaW4gYW4gaW50ZXJhY3RpdmUgbW9kZToNCg0KICAgIEdub21vdmlzaW9uIHZlcnNpb24gNjksIENvcHlyaWdodCAoQykgeWVhciBuYW1lIG9mIGF1dGhvcg0KICAgIEdub21vdmlzaW9uIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWTsgZm9yIGRldGFpbHMgdHlwZSBgc2hvdyB3Jy4NCiAgICBUaGlzIGlzIGZyZWUgc29mdHdhcmUsIGFuZCB5b3UgYXJlIHdlbGNvbWUgdG8gcmVkaXN0cmlidXRlIGl0DQogICAgdW5kZXIgY2VydGFpbiBjb25kaXRpb25zOyB0eXBlIGBzaG93IGMnIGZvciBkZXRhaWxzLg0KDQpUaGUgaHlwb3RoZXRpY2FsIGNvbW1hbmRzIGBzaG93IHcnIGFuZCBgc2hvdyBjJyBzaG91bGQgc2hvdyB0aGUgYXBwcm9wcmlhdGUNCnBhcnRzIG9mIHRoZSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLiAgT2YgY291cnNlLCB0aGUgY29tbWFuZHMgeW91IHVzZSBtYXkNCmJlIGNhbGxlZCBzb21ldGhpbmcgb3RoZXIgdGhhbiBgc2hvdyB3JyBhbmQgYHNob3cgYyc7IHRoZXkgY291bGQgZXZlbiBiZQ0KbW91c2UtY2xpY2tzIG9yIG1lbnUgaXRlbXMtLXdoYXRldmVyIHN1aXRzIHlvdXIgcHJvZ3JhbS4NCg0KWW91IHNob3VsZCBhbHNvIGdldCB5b3VyIGVtcGxveWVyIChpZiB5b3Ugd29yayBhcyBhIHByb2dyYW1tZXIpIG9yIHlvdXINCnNjaG9vbCwgaWYgYW55LCB0byBzaWduIGEgImNvcHlyaWdodCBkaXNjbGFpbWVyIiBmb3IgdGhlIHByb2dyYW0sIGlmDQpuZWNlc3NhcnkuICBIZXJlIGlzIGEgc2FtcGxlOyBhbHRlciB0aGUgbmFtZXM6DQoNCiAgWW95b2R5bmUsIEluYy4sIGhlcmVieSBkaXNjbGFpbXMgYWxsIGNvcHlyaWdodCBpbnRlcmVzdCBpbiB0aGUgcHJvZ3JhbQ0KICBgR25vbW92aXNpb24nICh3aGljaCBtYWtlcyBwYXNzZXMgYXQgY29tcGlsZXJzKSB3cml0dGVuIGJ5IEphbWVzIEhhY2tlci4NCg0KICA8c2lnbmF0dXJlIG9mIFR5IENvb24+LCAxIEFwcmlsIDE5ODkNCiAgVHkgQ29vbiwgUHJlc2lkZW50IG9mIFZpY2UNCg0KVGhpcyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGRvZXMgbm90IHBlcm1pdCBpbmNvcnBvcmF0aW5nIHlvdXIgcHJvZ3JhbSBpbnRvDQpwcm9wcmlldGFyeSBwcm9ncmFtcy4gIElmIHlvdXIgcHJvZ3JhbSBpcyBhIHN1YnJvdXRpbmUgbGlicmFyeSwgeW91IG1heQ0KY29uc2lkZXIgaXQgbW9yZSB1c2VmdWwgdG8gcGVybWl0IGxpbmtpbmcgcHJvcHJpZXRhcnkgYXBwbGljYXRpb25zIHdpdGggdGhlDQpsaWJyYXJ5LiAgSWYgdGhpcyBpcyB3aGF0IHlvdSB3YW50IHRvIGRvLCB1c2UgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbA0KUHVibGljIExpY2Vuc2UgaW5zdGVhZCBvZiB0aGlzIExpY2Vuc2UuDQo=]]></data>
	</file>
	<file>
	  <filename>/method.install.php</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[PD9waHAKLyoqCiAqICRJZDogbWV0aG9kLmluc3RhbGwucGhwIDggMjAxMC0wOC0yOCAwMzo1NjowOVogdG91Y2hkZXNpZ24gJAogKgogKiB0b3VjaElubGluZUVkaXQgTW9kdWxlCiAqCiAqIENvcHlyaWdodCAoYykgMjAxMCB0b3VjaERlc2lnbiwgPHd3dy50b3VjaGRlc2lnbi5kZT4KICoKICogQGNhdGVnb3J5IE1vZHVsZQogKiBAYXV0aG9yIENocmlzdG9waCBHcnViZXIgPHd3dy50b3VjaGRlc2lnbi5kZT4KICogQHZlcnNpb24gMS4yCiAqIEBjb3B5cmlnaHQgQ2hyaXN0b3BoIEdydWJlciB0b3VjaERlc2lnbi5kZSAwNC4wOC4yMDEwCiAqIEBsaW5rIGh0dHA6Ly93d3cudG91Y2hkZXNpZ24uZGUvCiAqIEBsaW5rIGh0dHA6Ly93d3cuaG9tZXBhZ2UtY29tbXVuaXR5LmRlL2luZGV4LnBocD90b3BpYz0xNjgwLjAKICogQGxpbmsgaHR0cDovL2Rldi5jbXNtYWRlc2ltcGxlLm9yZy9wcm9qZWN0cy90b3VjaElubGluZUVkaXQKICogQGxpY2Vuc2UgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2xpY2Vuc2VzLmh0bWwjR1BMIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIChHUEwgMi4wKQogKiBAdG9kbyBhZGQgY29udGVudF9ibG9jayBoYW5kbGluZwogKiAKICogLS0KICoKICogVXNhZ2U6IAogKgogKiB7Y21zX21vZHVsZSBtb2R1bGU9InRvdWNoSW5saW5lRWRpdCJ9CiAqCiAqIHtjb250ZW50IGlzZWRpdGFibGU9J3RydWUnfQogKgogKiAtLQogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3IFVTQQogKiBPciByZWFkIGl0IG9ubGluZTogaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2xpY2Vuc2VzLmh0bWwjR1BMCiAqCiAqLwoKJHRoaXMtPkNyZWF0ZVBlcm1pc3Npb24oJ1VzZSB0b3VjaElubGluZUVkaXQnLCAnVXNlIHRvdWNoSW5saW5lRWRpdCcpOwokdGhpcy0+U2V0UHJlZmVyZW5jZSgndG91Y2hJbmxpbmVFZGl0LmZlRWRpdEJ1dHRvbicsICdZJyk7CiR0aGlzLT5TZXRQcmVmZXJlbmNlKCd0b3VjaElubGluZUVkaXQuZmVGdWxsUGFuZWwnLCAndHJ1ZScpOwokdGhpcy0+U2V0UHJlZmVyZW5jZSgndG91Y2hJbmxpbmVFZGl0LmZlVXBkYXRlQWxlcnQnLCAndHJ1ZScpOwoKPz4=]]></data>
	</file>
	<file>
	  <filename>/method.uninstall.php</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[PD9waHAKLyoqCiAqICRJZDogbWV0aG9kLnVuaW5zdGFsbC5waHAgOCAyMDEwLTA4LTI4IDAzOjU2OjA5WiB0b3VjaGRlc2lnbiAkCiAqCiAqIHRvdWNoSW5saW5lRWRpdCBNb2R1bGUKICoKICogQ29weXJpZ2h0IChjKSAyMDEwIHRvdWNoRGVzaWduLCA8d3d3LnRvdWNoZGVzaWduLmRlPgogKgogKiBAY2F0ZWdvcnkgTW9kdWxlCiAqIEBhdXRob3IgQ2hyaXN0b3BoIEdydWJlciA8d3d3LnRvdWNoZGVzaWduLmRlPgogKiBAdmVyc2lvbiAxLjIKICogQGNvcHlyaWdodCBDaHJpc3RvcGggR3J1YmVyIHRvdWNoRGVzaWduLmRlIDA0LjA4LjIwMTAKICogQGxpbmsgaHR0cDovL3d3dy50b3VjaGRlc2lnbi5kZS8KICogQGxpbmsgaHR0cDovL3d3dy5ob21lcGFnZS1jb21tdW5pdHkuZGUvaW5kZXgucGhwP3RvcGljPTE2ODAuMAogKiBAbGluayBodHRwOi8vZGV2LmNtc21hZGVzaW1wbGUub3JnL3Byb2plY3RzL3RvdWNoSW5saW5lRWRpdAogKiBAbGljZW5zZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvbGljZW5zZXMuaHRtbCNHUEwgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgKEdQTCAyLjApCiAqIEB0b2RvIGFkZCBjb250ZW50X2Jsb2NrIGhhbmRsaW5nCiAqIAogKiAtLQogKgogKiBVc2FnZTogCiAqCiAqIHtjbXNfbW9kdWxlIG1vZHVsZT0idG91Y2hJbmxpbmVFZGl0In0KICoKICoge2NvbnRlbnQgaXNlZGl0YWJsZT0ndHJ1ZSd9CiAqCiAqIC0tCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcgVVNBCiAqIE9yIHJlYWQgaXQgb25saW5lOiBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvbGljZW5zZXMuaHRtbCNHUEwKICoKICovCgokdGhpcy0+UmVtb3ZlUHJlZmVyZW5jZSgpOwokdGhpcy0+UmVtb3ZlUGVybWlzc2lvbignVXNlIHRvdWNoSW5saW5lRWRpdCcsICdVc2UgdG91Y2hJbmxpbmVFZGl0Jyk7Cgo/Pg==]]></data>
	</file>
	<file>
	  <filename>/method.upgrade.php</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[PD9waHAKLyoqCiAqICRJZCQKICoKICogdG91Y2hJbmxpbmVFZGl0IE1vZHVsZQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAgdG91Y2hEZXNpZ24sIDx3d3cudG91Y2hkZXNpZ24uZGU+CiAqCiAqIEBjYXRlZ29yeSBNb2R1bGUKICogQGF1dGhvciBDaHJpc3RvcGggR3J1YmVyIDx3d3cudG91Y2hkZXNpZ24uZGU+CiAqIEB2ZXJzaW9uIDEuMgogKiBAY29weXJpZ2h0IENocmlzdG9waCBHcnViZXIgdG91Y2hEZXNpZ24uZGUgMDQuMDguMjAxMAogKiBAbGluayBodHRwOi8vd3d3LnRvdWNoZGVzaWduLmRlLwogKiBAbGluayBodHRwOi8vd3d3LmhvbWVwYWdlLWNvbW11bml0eS5kZS9pbmRleC5waHA/dG9waWM9MTY4MC4wCiAqIEBsaW5rIGh0dHA6Ly9kZXYuY21zbWFkZXNpbXBsZS5vcmcvcHJvamVjdHMvdG91Y2hJbmxpbmVFZGl0CiAqIEBsaWNlbnNlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9saWNlbnNlcy5odG1sI0dQTCBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSAoR1BMIDIuMCkKICogQHRvZG8gYWRkIGNvbnRlbnRfYmxvY2sgaGFuZGxpbmcKICogCiAqIC0tCiAqCiAqIFVzYWdlOiAKICoKICoge2Ntc19tb2R1bGUgbW9kdWxlPSJ0b3VjaElubGluZUVkaXQifQogKgogKiB7Y29udGVudCBpc2VkaXRhYmxlPSd0cnVlJ30KICoKICogLS0KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNyBVU0EKICogT3IgcmVhZCBpdCBvbmxpbmU6IGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9saWNlbnNlcy5odG1sI0dQTAogKgogKi8KCmdsb2JhbCAkZ0NtczsKCiRzbWFydHkgPSAmJGdDbXMtPnNtYXJ0eTsKCiRzbWFydHktPmNsZWFyX2NvbXBpbGVkX3RwbCgpOwoKPz4=]]></data>
	</file>
	<file>
	  <filename>/templates/</filename>
	  <isdir>1</isdir>
	</file>
	<file>
	  <filename>/templates/adminsettings.tpl</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[eyRmb3Jtc3RhcnR9Cgk8ZGl2IGNsYXNzPSJwYWdlb3ZlcmZsb3ciPgoJCTxwIGNsYXNzPSJwYWdldGV4dCI+eyRmZUVkaXRCdXR0b25fbGFiZWx9PC9wPgoJCTxwIGNsYXNzPSJwYWdlaW5wdXQiPnskZmVFZGl0QnV0dG9uX2lucHV0fTxici8+eyRmZUVkaXRCdXR0b25faGVscH08L3A+Cgk8L2Rpdj4KCTxkaXYgY2xhc3M9InBhZ2VvdmVyZmxvdyI+CgkJPHAgY2xhc3M9InBhZ2V0ZXh0Ij57JGZlRnVsbFBhbmVsX2xhYmVsfTwvcD4KCQk8cCBjbGFzcz0icGFnZWlucHV0Ij57JGZlRnVsbFBhbmVsX2lucHV0fTxici8+eyRmZUZ1bGxQYW5lbF9oZWxwfTwvcD4KCTwvZGl2PgoJPGRpdiBjbGFzcz0icGFnZW92ZXJmbG93Ij4KCQk8cCBjbGFzcz0icGFnZXRleHQiPnskZmVVcGRhdGVBbGVydF9sYWJlbH08L3A+CgkJPHAgY2xhc3M9InBhZ2VpbnB1dCI+eyRmZVVwZGF0ZUFsZXJ0X2lucHV0fTxici8+eyRmZVVwZGF0ZUFsZXJ0X2hlbHB9PC9wPgoJPC9kaXY+Cgk8ZGl2IGNsYXNzPSJwYWdlb3ZlcmZsb3ciPgoJCTxwIGNsYXNzPSJwYWdldGV4dCI+Jm5ic3A7PC9wPgoJCTxwIGNsYXNzPSJwYWdlaW5wdXQiPnskc3VibWl0fXskY2FuY2VsfTwvcD4KCTwvZGl2Pgp7JGZvcm1lbmR9]]></data>
	</file>
	<file>
	  <filename>/touchInlineEdit.module.php</filename>
	  <isdir>0</isdir>
	  <data><![CDATA[PD9waHAKLyoqCiAqICRJZDogdG91Y2hJbmxpbmVFZGl0Lm1vZHVsZS5waHAgOCAyMDEwLTA4LTI4IDAzOjU2OjA5WiB0b3VjaGRlc2lnbiAkCiAqCiAqIHRvdWNoSW5saW5lRWRpdCBNb2R1bGUKICoKICogQ29weXJpZ2h0IChjKSAyMDEwIHRvdWNoRGVzaWduLCA8d3d3LnRvdWNoZGVzaWduLmRlPgogKgogKiBAY2F0ZWdvcnkgTW9kdWxlCiAqIEBhdXRob3IgQ2hyaXN0b3BoIEdydWJlciA8d3d3LnRvdWNoZGVzaWduLmRlPgogKiBAdmVyc2lvbiAxLjIKICogQGNvcHlyaWdodCBDaHJpc3RvcGggR3J1YmVyIHRvdWNoRGVzaWduLmRlIDA0LjA4LjIwMTAKICogQGxpbmsgaHR0cDovL3d3dy50b3VjaGRlc2lnbi5kZS8KICogQGxpbmsgaHR0cDovL3d3dy5ob21lcGFnZS1jb21tdW5pdHkuZGUvaW5kZXgucGhwP3RvcGljPTE2ODAuMAogKiBAbGluayBodHRwOi8vZGV2LmNtc21hZGVzaW1wbGUub3JnL3Byb2plY3RzL3RvdWNoSW5saW5lRWRpdAogKiBAbGljZW5zZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvbGljZW5zZXMuaHRtbCNHUEwgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgKEdQTCAyLjApCiAqIEB0b2RvIGFkZCBjb250ZW50X2Jsb2NrIGhhbmRsaW5nCiAqIAogKiAtLQogKgogKiBVc2FnZTogCiAqCiAqIHtjbXNfbW9kdWxlIG1vZHVsZT0idG91Y2hJbmxpbmVFZGl0In0KICoKICoge2NvbnRlbnQgaXNlZGl0YWJsZT0ndHJ1ZSd9CiAqCiAqIC0tCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BIDAyMTExLTEzMDcgVVNBCiAqIE9yIHJlYWQgaXQgb25saW5lOiBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvbGljZW5zZXMuaHRtbCNHUEwKICoKICovCgpjbGFzcyB0b3VjaElubGluZUVkaXQgZXh0ZW5kcyBDTVNNb2R1bGUgewoKCWZ1bmN0aW9uIEdldE5hbWUoKSB7IAoJCXJldHVybiAndG91Y2hJbmxpbmVFZGl0JzsgCgl9CgoJZnVuY3Rpb24gR2V0RnJpZW5kbHlOYW1lKCkgeyAKCQlyZXR1cm4gJ0lubGluZUVkaXQnOyAKCX0KCglmdW5jdGlvbiBHZXRWZXJzaW9uKCkgeyAKCQlyZXR1cm4gJzEuMic7Cgl9CgoJZnVuY3Rpb24gR2V0SGVscCgpIHsgCgkJcmV0dXJuICR0aGlzLT5MYW5nKCdoZWxwJyk7Cgl9CgoJZnVuY3Rpb24gSXNQbHVnaW5Nb2R1bGUoKSB7IAoJCXJldHVybiB0cnVlOwoJfQoJCglmdW5jdGlvbiBIYXNBZG1pbigpIHsgCgkJcmV0dXJuIHRydWU7IAoJfQoKCWZ1bmN0aW9uIEdldEF1dGhvcigpIHsKCQlyZXR1cm4gJ0NocmlzdG9waCBHcnViZXIgPHRvdWNoRGVzaWduLmRlPic7Cgl9CgoJZnVuY3Rpb24gR2V0QXV0aG9yRW1haWwoKSB7CgkJcmV0dXJuICdjLmdydWJlckB0b3VjaGRlc2lnbi5kZSc7Cgl9CgoJZnVuY3Rpb24gR2V0QWRtaW5TZWN0aW9uKCkgewoJCXJldHVybiAnZXh0ZW5zaW9ucyc7Cgl9CgoJZnVuY3Rpb24gU2V0UGFyYW1ldGVycygpIHsJICAKCQkvKiBOb3RoaW5nIHlldCAqLwoJfQoKCWZ1bmN0aW9uIEluc3RhbGxQb3N0TWVzc2FnZSgpIHsKCQlyZXR1cm4gJHRoaXMtPkxhbmcoJ3Bvc3RpbnN0YWxsJyk7Cgl9CgoJZnVuY3Rpb24gVW5pbnN0YWxsUG9zdE1lc3NhZ2UoKSB7CgkJcmV0dXJuICR0aGlzLT5MYW5nKCdwb3N0dW5pbnN0YWxsJyk7Cgl9CgoJZnVuY3Rpb24gTWluaW11bUNNU1ZlcnNpb24oKSB7CgkJcmV0dXJuICIxLjYuOCI7Cgl9CgoJZnVuY3Rpb24gU21hcnR5UHJlQ29tcGlsZSgmJGNvbnRlbnQpIHsKCQlnbG9iYWwgJGdDbXM7CgoJCS8vIG5pY0VkaXQKCQkkaGVhZCA9ICd7aWYgJGhhc0lubGluZUVkaXRSaWdodHN9JyAuICJcbiI7CgkJJGhlYWQuPSAnCTwhLS0gJy4kdGhpcy0+Z2V0TmFtZSgpLicgbW9kdWxlIC0tPicgLiAiXG4iOwoJCSRoZWFkLj0gJwk8c2NyaXB0IHNyYz0ibW9kdWxlcy8nLiR0aGlzLT5nZXROYW1lKCkuJy9qcy9uaWNFZGl0LmpzIiB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiPjwvc2NyaXB0PicgLiAiXG4iOwoJCSRoZWFkLj0gJwk8c2NyaXB0IHNyYz0ibW9kdWxlcy8nLiR0aGlzLT5nZXROYW1lKCkuJy9qcy9qcXVlcnkuanMiIHR5cGU9InRleHQvamF2YXNjcmlwdCI+PC9zY3JpcHQ+JyAuICJcbiI7CgkJJGhlYWQuPSAney9pZn0nIC4gIlxuIjsKCgkJJHNjcmlwdCA9ICIKCQl7aWYgXCRoYXNJbmxpbmVFZGl0UmlnaHRzfQoJCQl7bGl0ZXJhbH0KCQkJPCEtLSAiLiR0aGlzLT5nZXROYW1lKCkuIiBtb2R1bGUgLS0+CgkJCTxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0JyBjaGFyc2V0PSd1dGYtOCc+CgkJCXZhciBjQmxvY2tNYWluOwoJCQlmdW5jdGlvbiB0b2dnbGVJbmxpbmVFZGl0KCkgewoJCQkJaWYoIWNCbG9ja01haW4pIHsKCQkJCQljQmxvY2tNYWluID0gbmV3IG5pY0VkaXRvcih7CgkJCQkJCWZ1bGxQYW5lbCA6IHsvbGl0ZXJhbH17XCR0aWVGZUZ1bGxQYW5lbH17bGl0ZXJhbH0sCgkJCQkJCWljb25zUGF0aCA6ICdtb2R1bGVzLyIuJHRoaXMtPmdldE5hbWUoKS4iL2ltZy9uaWNFZGl0b3JJY29ucy5naWYnLAoJCQkJCQlvblNhdmU6ZnVuY3Rpb24oY29udGVudCxpZCxpbnN0YW5jZSl7dG91Y2hJbmxpbmVFZGl0U2F2ZShpZCxjb250ZW50KX0KCQkJCQl9KS5wYW5lbEluc3RhbmNlKAoJCQkJCQkndG91Y2hJbmxpbmVFZGl0SWR7L2xpdGVyYWx9e1wkZ0Ntcy0+dmFyaWFibGVzLmNvbnRlbnRfaWR9e2xpdGVyYWx9JywKCQkJCQkJe2hhc1BhbmVsIDogdHJ1ZX0KCQkJCQkpOwoJCQkJfSBlbHNlIHsKCQkJCQljQmxvY2tNYWluLnJlbW92ZUluc3RhbmNlKCd0b3VjaElubGluZUVkaXRJZHsvbGl0ZXJhbH17XCRnQ21zLT52YXJpYWJsZXMuY29udGVudF9pZH17bGl0ZXJhbH0nKTsKCQkJCQljQmxvY2tNYWluID0gbnVsbDsKCQkJCX0KCQkJfQoJCQlia0xpYi5vbkRvbUxvYWRlZCgKCQkJCWZ1bmN0aW9uKCkgeyAKCQkJCQkvLyBOb3RoaW5nIHlldC4uLgoJCQkJfQoJCQkpOwoJCQlmdW5jdGlvbiB0b3VjaElubGluZUVkaXRTYXZlKGlkLGNvbnRlbnQpewoJCQkJJC5hamF4KHsKCQkJCQl0eXBlOiAnUE9TVCcsCgkJCQkJdXJsOiAney9saXRlcmFsfXtcJHNtYXJ0eS5zZXJ2ZXIuUkVRVUVTVF9VUkl9e2xpdGVyYWx9JywKCQkJCQlkYXRhOiAnaWQ9ey9saXRlcmFsfXtcJGdDbXMtPnZhcmlhYmxlcy5jb250ZW50X2lkfXtsaXRlcmFsfSZjb250ZW50PScgKyBjb250ZW50LAoJCQkJCXN1Y2Nlc3M6IGZ1bmN0aW9uKG1zZyl7CgkJCQkJCXsvbGl0ZXJhbH17aWYgXCR0aWVGZVVwZGF0ZUFsZXJ0ID09ICd0cnVlJ31hbGVydCgnIi4kdGhpcy0+TGFuZygnZmVVcGRhdGVBbGVydCcpLiInKTt7L2lmfXtsaXRlcmFsfQoJCQkJCQl0b2dnbGVJbmxpbmVFZGl0KCk7CgkJCQkJfQoJCQkJfSk7CgkJCX0KCQkJPC9zY3JpcHQ+CgkJCXsvbGl0ZXJhbH0KCQl7L2lmfSI7CgoJCSRjb250ZW50ID0gc3RyX3JlcGxhY2UoJzwvaGVhZD4nLCRoZWFkIC4gJHNjcmlwdCAuICc8L2hlYWQ+JywkY29udGVudCk7CgoJCS8vaWYocHJlZ19tYXRjaCgiL2Jsb2NrPVtcInwnXVx3K1tcInwnXS8iLCAkY29udGVudCwgJG1hdGNoKSl7CgkJLy8JJGJsb2NrID0gJG1hdGNoezB9OwoJCS8vfQoKCQkvLyBCZWZvcmUgY29udGVudAoJCSRjb250ZW50QmVmb3JlID0gJ3tpZiAkaGFzSW5saW5lRWRpdFJpZ2h0c30nOwoJCSRjb250ZW50QmVmb3JlLj0gJwl7aWYgJHRpZUZlRWRpdEJ1dHRvbiA9PSAiWSJ9JzsKCQkkY29udGVudEJlZm9yZS49ICcJCTxidXR0b24gY2xhc3M9InRvdWNoSW5saW5lRWRpdEJ1dHRvbiIgb25jbGljaz0idG9nZ2xlSW5saW5lRWRpdCgpOyI+Jy4kdGhpcy0+TGFuZygiZmVJbmxpbmVFZGl0QnV0dG9uIikuJzwvYnV0dG9uPic7CgkJJGNvbnRlbnRCZWZvcmUuPSAnCXsvaWZ9JzsKCQkkY29udGVudEJlZm9yZS49ICc8ZGl2IG9uZGJsY2xpY2s9InRvZ2dsZUlubGluZUVkaXQoKTsiIGlkPSJ0b3VjaElubGluZUVkaXRJZHtcJGdDbXMtPnZhcmlhYmxlcy5jb250ZW50X2lkfSIgY2xhc3M9InRvdWNoSW5saW5lRWRpdCI+JzsKCQkkY29udGVudEJlZm9yZS49ICd7L2lmfSc7CgoJCS8vIEFmdGVyIGNvbnRlbnQKCQkkY29udGVudEFmdGVyID0gJ3tpZiAkaGFzSW5saW5lRWRpdFJpZ2h0c30nOwoJCSRjb250ZW50QWZ0ZXIuPSAnPC9kaXY+JzsKCQkkY29udGVudEFmdGVyLj0gJ3svaWZ9JzsKCgkJLy8gQmFzaWMgY29udGVudAoJCSRjb250ZW50ID0gcHJlZ19yZXBsYWNlKCIvXHtjb250ZW50KC4qKSBpc2VkaXRhYmxlPVtcInwnXXRydWVbXCInXVx9LyIsICRjb250ZW50QmVmb3JlLiJ7Y29udGVudCBcXDF9Ii4kY29udGVudEFmdGVyLCAkY29udGVudCk7Cgl9CgoJZnVuY3Rpb24gaXNBSkFYUmVxdWVzdCgpewoKCQlyZXR1cm4gaXNzZXQoJF9TRVJWRVJbJ0hUVFBfWF9SRVFVRVNURURfV0lUSCddKSAKCQkJJiYgc3RydG9sb3dlcigkX1NFUlZFUlsnSFRUUF9YX1JFUVVFU1RFRF9XSVRIJ10pIAoJCQk9PSAneG1saHR0cHJlcXVlc3QnID8gdHJ1ZSA6IGZhbHNlOwoJfQoKCWZ1bmN0aW9uIHVwZGF0ZUNvbnRlbnQoKXsKCQlnbG9iYWwgJGdDbXM7CgoJCSRwYWdlSW5mbyA9ICRnQ21zLT52YXJpYWJsZXNbJ3BhZ2VpbmZvJ107CgoJCSRjb250ZW50SWQgPSAkcGFnZUluZm8tPmNvbnRlbnRfaWQ7CgkJJGNvbnRlbnRWYWx1ZSA9ICRfUE9TVFsnY29udGVudCddOwoKCQkkbWFuYWdlciA9JiAkZ0Ntcy0+R2V0SGllcmFyY2h5TWFuYWdlcigpOwoJCSRub2RlID0mICRtYW5hZ2VyLT5zdXJlR2V0Tm9kZUJ5SWQoJGNvbnRlbnRJZCk7CgoJCWlmKCFpc19vYmplY3QoJG5vZGUpKXsKCQkJcmV0dXJuICJJbnZhbGlkIENvbnRlbnRJZDogIiAuICRjb250ZW50SWQ7CgkJfQoKCQkkY29udGVudE9iaiA9JiAkbm9kZS0+R2V0Q29udGVudCh0cnVlLHRydWUpOwoKCQkkcGFyYW1zWydjb250ZW50X2VuJ10gPSAkY29udGVudFZhbHVlOwoKCQkkY29udGVudE9iai0+RmlsbFBhcmFtcygkcGFyYW1zKTsKCgkJJGNvbnRlbnRPYmotPlVwZGF0ZSgpOwoKCQlyZXR1cm4gJGNvbnRlbnRWYWx1ZTsKCX0KfQoKPz4=]]></data>
	</file>
</module>
