Ly8gTW9yZ2VuR3JhdWVuIE1VRGxpYgovLwovLyBwbGF5ZXIvc2tpbGxzLmMgLS0gU3BpZWxlcnNraWxscwovLwovLyAkSWQ6IHNraWxscy5jIDg4MDkgMjAxNC0wNS0wOCAxOTo1Mjo0OFogWmVzc3RyYSAkCgovLwovLyAyMDAzLTAxLTIwOiBOdW4gWm9va3MgQmF1c3RlbGxlCi8vCiNwcmFnbWEgc3Ryb25nX3R5cGVzCiNwcmFnbWEgc2F2ZV90eXBlcwojcHJhZ21hIHJhbmdlX2NoZWNrCiNwcmFnbWEgbm9fY2xvbmUKI3ByYWdtYSBwZWRhbnRpYwoKaW5oZXJpdCAiL3N0ZC9saXZpbmcvc2tpbGxzIjsKCiNpbmNsdWRlIDxjb21iYXQuaD4KI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KI2luY2x1ZGUgPGJyZWFrX3N0cmluZy5oPgojaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CgojZGVmaW5lIE5FRURfUFJPVE9UWVBFUwojaW5jbHVkZSA8cGxheWVyL2Jhc2UuaD4KI2luY2x1ZGUgPHBsYXllci9nbWNwLmg+CiN1bmRlZiBORUVEX1BST1RPVFlQRVMKCi8vIERpZXNlcyBNYXBwaW5nIHNwZWljaGVydCBkaWUgZGVha3RpdmllcnRlbiBTa2lsbHMgZGVyIGVpbnplbG5lbiBHaWxkZW4KLy8gRGllc2Ugd2VyZGVuIGluIGRlbiBHaWxkZW4gdWViZXIgUF9HVUlMRF9ERUFDVElWQVRFRF9TS0lMTCBnZXNldHp0Lgpub3NhdmUgbWFwcGluZyBkZWFjdGl2YXRlZF9za2lsbHMgPSAoW10pOwoKLy8gRmxhZyBmdWVyIGRlbiBLb21wYXRpYmlsaXRhZXRzbW9kdXMgZGVzIEthbXBmcyAoRW11bGF0aW9uIHZvbgovLyAycy1BbGFybXplaXQpLiBXZW5uICE9IDAgc3BlaWNoZXJ0IGRhcyBGbGFnIGdsZWljaHplaXRpZyBkaWUgWmVpdCBkZXMKLy8gbGV0enRlbiBIZWFydGJlYXRzLiBBdWYgZGllc2UgWmVpdCB3aXJkIGRlciBTdGFydHB1bmt0IGVpbmVzIFNwZWxsZmF0aWd1ZXMKLy8gZ2dmLiB6dXJ1ZWNrZGF0aWVydC4gKG1heC4gZWluZSBTZWt1bmRlKQppbnQgc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZTsKCi8vIEVpbiBjcmVhdGUoKSBmdWVyIGRhcyBNYXBwaW5nCgpwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQp7CiAgbWFwcGluZyBhY3Q7CgogIDo6Y3JlYXRlKCk7CgogIC8vIFdpciBob2xlbiBkaWUgR2lsZGVuIGF1cyBkZW0gR2lsZGVubWFzdGVyIAogIGZvcmVhY2goc3RyaW5nIGd1aWxkOgogICAgICAoc3RyaW5nICopY2FsbF9vdGhlcihHVUlMRE1BU1RFUiwiUXVlcnlQcm9wIixQX1ZBTElEX0dVSUxEUykpCiAgewogICAgaWYoY2F0Y2goYWN0PWNhbGxfb3RoZXIoIi9naWxkZW4vIitndWlsZCwiUXVlcnlQcm9wIiwKICAgICAgICBQX0dVSUxEX0RFQUNUSVZBVEVfU0tJTExTKTsgcHVibGlzaCApKQogICAgICAgIGxvZ19maWxlKCJXRUFQT05fU0tJTExTIiwgc3ByaW50ZiAoIiVzOiBHaWxkZSBuaWNodCBsYWRiYXI6ICIKICAgICAgICAgICAgICArIlRQOiAlTywgVEk6ICVPLCBQTzogJU8sIEdpbGRlOiAlc1xuIiwgZHRpbWUodGltZSgpKSwKICAgICAgICAgICAgICB0aGlzX3BsYXllcigpLCB0aGlzX2ludGVyYWN0aXZlKCksIHByZXZpb3VzX29iamVjdCgpLCBndWlsZCkpOwogICAgZWxzZSBpZiAoYWN0KSAvLyB3ZW5uIGFjdCwgaW5zIE1hcHBpbmcgYXVmbmVobWVuLgogICAgICAgIGRlYWN0aXZhdGVkX3NraWxscys9KFtndWlsZDphY3RdKTsKICB9CiAgLy8ga2VpbmUgZWNodGUgUHJvcCBtZWhyLCBTYXZlLU1vZHVzIHVubm9ldGlnLgogIFNldChQX05FWFRfU1BFTExfVElNRSxTQVZFLEZfTU9ERV9BRCk7CgogIFNldChQX1NLSUxMU1ZFUlNJT04sIFNBVkV8U0VDVVJFRCwgRl9NT0RFX0FTKTsKfQoKLy8gRGFzIE1hcHBpbmcga2FubiBtYW4gYXVjaCBhYmZyYWdlbgoKcHVibGljIG1hcHBpbmcgR2V0RGVhY3RpdmF0ZWRTa2lsbHMoKQp7CiAgICByZXR1cm4gY29weShkZWFjdGl2YXRlZF9za2lsbHMpOwp9CgovLyBGdW5rdGlvbiwgZGllIHNhZ3Qgb2IgZWluIEFOWS1Ta2lsbCBkZWFrdGl2aWVydCBpc3QuCnB1YmxpYyBpbnQgaXNfZGVhY3RpdmF0ZWRfc2tpbGwoc3RyaW5nIHNuYW1lLHN0cmluZyBndWlsZCkKewogICAgICAgIGlmIChkZWFjdGl2YXRlZF9za2lsbHNbZ3VpbGRdKSAgICAgICAgCiAgICAgICAgICAgICAgICByZXR1cm4gZGVhY3RpdmF0ZWRfc2tpbGxzW2d1aWxkXVtzbmFtZV07CiAgICAgICAgcmV0dXJuIDA7Cn0KCgovLyBGdW5rdGlvbiBmdWVyIGRpZSBXYWZmZW5za2lsbHMKLy8gdHJhZWd0IGRpZSBhbGxnLiBXYWZmZW5za2lsbHMgZWluLiBXaXJkIGdnZi4gdm9uIEZpeFNraWxscygpIGdlcnVmZW4uCi8vIChEYXMgRWludHJhZ2VuIGJlZGV1dGV0IG5pY2h0LCBkYXNzIGRpZSBha3RpdiBzaW5kISBBYmVyIGJlaSBHaWxkZW53ZWNoc2VsCi8vIHdlcmRlbiBzaWUgbmljaHQgZWluZ2V0cmFnZW4pLgpwcml2YXRlIHZvaWQgc2V0X3dlYXBvbl9za2lsbHMoKSB7CgogIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9TV09SRCkpPD0wKSAgICAgICAgICAgICAgICAKICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfU1dPUkQpLChbU0lfU0tJTExBQklMSVRZOjBdKSwxNTAsIkFOWSIpOyAgICAKICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfQVhFKSk8PTApICAgICAgICAgICAgICAgIAogICAgICBNb2RpZnlTa2lsbChGSUdIVChXVF9BWEUpLChbU0lfU0tJTExBQklMSVRZOjBdKSwxNTAsIkFOWSIpOyAgICAgICAgICAKICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfU1BFQVIpKTw9MCkgICAgICAgIAogICAgICBNb2RpZnlTa2lsbChGSUdIVChXVF9TUEVBUiksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7ICAgICAgICAgIAogIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9XSElQKSk8PTApCiAgICAgIE1vZGlmeVNraWxsKEZJR0hUKFdUX1dISVApLChbU0lfU0tJTExBQklMSVRZOjBdKSwxNTAsIkFOWSIpOwogIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9LTklGRSkpPD0wKSAgICAgICAgICAgICAgICAKICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfS05JRkUpLChbU0lfU0tJTExBQklMSVRZOjBdKSwxNTAsIkFOWSIpOyAgICAgICAgICAKICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfQ0xVQikpPD0wKSAgICAgICAgICAgICAgICAKICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfQ0xVQiksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7ICAgICAgICAgIAogIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9TVEFGRikpPD0wKQogICAgICBNb2RpZnlTa2lsbChGSUdIVChXVF9TVEFGRiksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7Cn0gCgovLyBpbml0aWFsaXNpZXJ0IGRpZSBTa2lsbHMgZnVlciBTcGllbGVyIChtb21lbnRhbjogYWxsZy4gV2FmZmVuc2tpbGxzIHNldHplbgovLyB1bmQgUF9TS0lMTFNfVkVSU0lPTikKcHJvdGVjdGVkIHZvaWQgSW5pdFNraWxscygpIHsKICBtYXBwaW5nIHNraTsKICAvLyBzY2hvbm1hbCBpbml0aWFsaXNpZXJ0PwogIGlmIChtYXBwaW5ncChza2k9UXVlcnkoUF9ORVdTS0lMTFMsIEZfVkFMVUUpKSAmJiBzaXplb2Yoc2tpKSkKICAgIHJldHVybjsKCiAgLy8gYWxsZy4gV2FmZmVuc2tpbGxzIGFrdGl2aWVyZW4KICBzZXRfd2VhcG9uX3NraWxscygpOwoKICAvLyBWZXJzaW9uIHNldHplbgogIFNldFByb3AoUF9TS0lMTFNWRVJTSU9OLCBDVVJSRU5UX1NLSUxMX1ZFUlNJT04pOwogIFNldChQX1NLSUxMU1ZFUlNJT04sIFNBVkV8U0VDVVJFRCwgRl9NT0RFX0FTKTsKfQoKLy8gVXBkYXRlZCBTa2lsbHMgYXVzIFZlcnNpb24gMCB1bmQgMSBoZXJhdXMuCnByaXZhdGUgdm9pZCBGaXhTa2lsbFYxKHN0cmluZyBza2lsbG5hbWUsIG1peGVkIHNpbmZvKSB7CiAgLy8gYWx0ZSBTa2lsbHMgYXVmIG1hcHBpbmdzIG5vcm1pZXJlbgogIGlmIChpbnRwKHNpbmZvKSkgewogICAgc2luZm8gPSAoW1NJX1NLSUxMQUJJTElUWTogc2luZm8gXSk7CiAgfQogIC8vIEVpbmUgUmVpaGUgdm9uIERhdGVuIHdlcmRlbiBnZWxvZXNjaHQsIGRhIGRpZSBEYXRlbiBhdXMgZGVyCiAgLy8gR2lsZGUvU3BlbGxib29rIGZyaXNjaCBrb21tZW4gc29sbHRlbiB1bmQgc2llIG5pY2h0IHNwaWVsZXItaW5kaXZpZHVlbGwKICAvLyBzaW5kOiBTSV9DTE9TVVJFICh3aXJkIG9udGhlZmx5IGtvcnJla3QgbmV1IGVyemV1Z3QpLCBTSV9TS0lMTEFSRywKICAvLyBTSV9OVU1CRVJfRU5FTUlFUywgU0lfTlVNQkVSX0ZSSUVORFMsIFNJX0RJU1RBTkNFLCBTSV9XSURUSCwgU0lfREVQVEgsCiAgLy8gU0lfVEVTVEZMQUcsIFNJX0VORU1ZLCBTSV9GUklFTkQuCiAgLy8gQXVzc2VyZGVtIHNpbmQgYWxsZSBTUF8qIGltIHRvcGxldmVsIGZhbHNjaCwgZGllIG11ZXNzZW4gYSkgaW4gU0lfU1BFTEwKICAvLyB1bmQgc29sbHRlbiBiKSBuaWNodCBpbSBTcGllbGVyIGdlc3BlaWNoZXJ0IHdlcmRlbiwgc29uZGVybiB2b24KICAvLyBHaWxkZW4vU3BlbGxib29rIGpld2VpbHMgZnJpc2NoIGtvbW1lbi4KICAvLyBhbGwgZGllc2VzIFpldWcgbGFuZGV0ZSBpbiBhbHRlbiBTcGllbGVybiBpbSBTYXZlZmlsZS4KICBpZiAobWFwcGluZ3Aoc2luZm8pKQogICAgc2luZm8gLT0gKFtTSV9DTE9TVVJFLCBTSV9TS0lMTEFSRywgU0lfTlVNQkVSX0VORU1JRVMsIFNJX05VTUJFUl9GUklFTkRTLAogICAgICAgICAgICAgU0lfRElTVEFOQ0UsIFNJX1dJRFRILCBTSV9ERVBUSCwgU0lfVEVTVEZMQUcsIFNJX0VORU1ZLAogICAgICAgICAgICAgU0lfRlJJRU5ELCBTUF9OQU1FLCBTUF9TSE9XX0RBTUFHRSwgU1BfUkVEVUNFX0FSTU9VUiwKICAgICAgICAgICAgIFNQX1BIWVNJQ0FMX0FUVEFDSywgU1BfUkVDVVJTSVZFLCBTUF9OT19FTkVNWSwKICAgICAgICAgICAgIFNQX05PX0FDVElWRV9ERUZFTlNFLCBTUF9HTE9CQUxfQVRUQUNLIF0pOwogIGVsc2UKICB7CiAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLHNwcmludGYoCiAgICAgICJcbioqKiogQUNIVFVORyAtIEZFSExFUiAqKipcbiIgCiAgICAgICJEZWluZSBTa2lsbHMgZW50aGFsdGVuIGVpbmVuIGRlZmVrdGVuIFNraWxsICVPOlxuIgogICAgICAiQml0dGUgbGFzcyBkaWVzIHZvbiBlaW5lbSBFcnptYWdpZXIgdWViZXJwcnVlZmVuLlxuIiwKICAgICAgc2tpbGxuYW1lKSk7CiAgfQp9CgovLyBVcGRhdGV0IHVuZCByZXBhcmllcnQgZ2dmLiBTa2lsbG1hcHBpbmdzIGluIFNwaWVsZXJuCnByb3RlY3RlZCB2b2lkIEZpeFNraWxscygpIHsKCiAgLy8gbnVyIGJlaSBnZW51ZyByZWNoZW56ZWl0IGxvc2xlZ2VuCiAgaWYgKGdldF9ldmFsX2Nvc3QoKSA8IDc1MDAwMCkgewogICAgY2FsbF9vdXQoIydGaXhTa2lsbHMsIDEpOwogICAgcmV0dXJuOwogIH0KICAvLyB3ZW5uIGdhciBrZWluZSBTa2lsbHMgZGEgKD8pOiBJbml0U2tpbGxzKCkgcnVmZW4uCiAgbWFwcGluZyBhbGxza2lsbHMgPSBRdWVyeShQX05FV1NLSUxMUywgRl9WQUxVRSk7CiAgaWYgKCFtYXBwaW5ncChhbGxza2lsbHMpIHx8ICFzaXplb2YoYWxsc2tpbGxzKSkgewogICAgICBJbml0U2tpbGxzKCk7CiAgICAgIHJldHVybjsKICB9CgogIC8vIERpZSBGYWxsdGhyb3VnaHMgaW4gZGllc2VtIHN3aXRjaCBzaW5kIHZvbGwgQWJzaWNodCEKICBzd2l0Y2goUXVlcnlQcm9wKFBfU0tJTExTVkVSU0lPTikpIHsKICAgIC8vIGJlaSBWZXJzaW9uIDAgdW5kIDEgZGFzIGdsZWljaGUgdHVuCiAgICBjYXNlIDA6IC8vIHZvbiAwIGF1ZiAxCiAgICBjYXNlIDE6IC8vIHZvbiAxIGF1ZiAyCiAgICAgIGZvcmVhY2goc3RyaW5nIGdpbGRlLCBtYXBwaW5nIHNraWxsczogYWxsc2tpbGxzKSB7CiAgICAgICAgaWYgKCFzdHJpbmdwKGdpbGRlKSkgewogICAgICAgICAgLy8gc29sbHRlIG5pY2h0IHZvcmtvbW1lbiAtIHRhdCBhYmVyLi4uICpzZXVmeioKICAgICAgICAgIG1fZGVsZXRlKHNraWxscywgZ2lsZGUpOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIHdhbGtfbWFwcGluZyhza2lsbHMsICMnRml4U2tpbGxWMSk7CiAgICAgIH0KICAgICAgLy8gYWxsZy4gV2FmZmVuc2tpbGxzIGFrdGl2aWVyZW4sIGVpbmlnZSBhbHRlIFNwaWVsZXIgaGFiZW4gZGllIG5vY2gKICAgICAgLy8gbmljaHQuCiAgICAgIHNldF93ZWFwb25fc2tpbGxzKCk7CiAgICAgIC8vIFNwZWljaGVyZmxhZyBmdWVyIGRpZSBWZXJzaW9uc3Byb3AgbXVzcyBub2NoIGdlc2V0enQgd2VyZGVuLgogICAgICBTZXQoUF9TS0lMTFNWRVJTSU9OLCBTQVZFfFNFQ1VSRUQsIEZfTU9ERV9BUyk7CiAgICAgIC8vIFZlcnNpb24gaXN0IGpldHp0IDIuCiAgICAgIFNldFByb3AoUF9TS0lMTFNWRVJTSU9OLCAyKTsKICAgICAgLy8gRmFsbC10aHJvdWdoCiAgIGNhc2UgMjoKICAgICAgLy8gZ2lidCBlcyBub2NoIG5pY2h0LCBuaWNodHMgbWFjaGVuLgogICAgICAvL1NldFByb3AoUF9TS0lMTFNWRVJTSU9OLCAzKTsKICAgICAgLy8gRmFsbC10aHJvdWdoLCBhdXNzZXIgZXMgc2luZCB6dXdlbmlnIFRpY2tzIGRhIQogICAgICBpZiAoZ2V0X2V2YWxfY29zdCgpIDwgNzUwMDAwKQogICAgICAgIGJyZWFrOyAKICB9CiAgLy8gRmFsbHMgbm9jaCBuaWNodCBhdWYgZGVyIGFrdHVlbGxlbiBWZXJzaW9uIGFuZ2Vrb21tZW4sIG5ldWVyIGNhbGxvdXQKICBpZiAoUXVlcnlQcm9wKFBfU0tJTExTVkVSU0lPTikgPCBDVVJSRU5UX1NLSUxMX1ZFUlNJT04pCiAgICAgIGNhbGxfb3V0KCMnRml4U2tpbGxzLCAyKTsKfQoKcHJvdGVjdGVkIHZvaWQgdXBkYXRlc19hZnRlcl9yZXN0b3JlKGludCBuZXdmbGFnKSB7CiAgLy9BbGxnZW1laW5lIFdhZmZlbnNraWxscyBha3RpdmllcmVuLCB3ZW5uIG5vZXRpZwogIC8vIFdpcmQgbnVuIHZvbiBJbml0U2tpbGxzIGJ6dy4gRml4U2tpbGxzIHVlYmVybm9tbWVuLCBmYWxscyBub2V0aWcuCiAgaWYgKG5ld2ZsYWcpIHsKICAgIEluaXRTa2lsbHMoKTsKICB9CiAgZWxzZSBpZiAoUXVlcnlQcm9wKFBfU0tJTExTVkVSU0lPTikgPCBDVVJSRU5UX1NLSUxMX1ZFUlNJT04pIHsKICAgIC8vIEZhbGxzIG5vZXRpZywgU2tpbGxzIGZpeGVuL3VwZGF0ZW4uICpncnVtbWVsKgogICAgRml4U2tpbGxzKCk7CiAgfQogIC8vIFByb3AgZ2lidCBlcyBuaWNodCBtZWhyLiBTQVZFLVN0YXR1cyBsb2VzY2hlbi4gCiAgU2V0KFBfR1VJTERfUFJFVkVOVFNfUkFDRVNLSUxMLFNBVkUsRl9NT0RFX0FEKTsKfQoKLy8gU3RhbmRhcmRpc2llcnRlIE5haGthbXBmLUZ1bmt0aW9uIGZ1ZXIgYWxsZSBOYWhrYW1wZi1XYWZmZW5hcnRlbgpwcm90ZWN0ZWQgbWFwcGluZyBTaG9ydFJhbmdlU2tpbGwob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pIAp7IAogIGludCB2YWwsIHc7CiAgb2JqZWN0IGVuZW15OwogIAogIGlmICghbWFwcGluZ3Aoc2luZm8pIHx8ICFvYmplY3RwKHNpbmZvW1BfV0VBUE9OXSkpCiAgICByZXR1cm4gMDsKCiAgdyA9IChbV1RfS05JRkUgOiA4LAogICAgICAgIFdUX1NXT1JEIDogNSwKICAgICAgICBXVF9BWEUgICA6IDQsCiAgICAgICAgV1RfU1BFQVIgOiA2LAogICAgICAgIFdUX0NMVUIgIDogMSwKICAgICAgICBXVF9XSElQICA6IDksCiAgICAgICAgV1RfU1RBRkYgOiA3XSlbc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9XRUFQT05fVFlQRSldOwogICAgICAKCiAgdmFsID0gc2luZm9bU0lfU0tJTExBQklMSVRZXSooc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9XQykqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHcqUXVlcnlBdHRyaWJ1dGUoQV9ERVgpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMTAtdykqUXVlcnlBdHRyaWJ1dGUoQV9TVFIpKS83MDApCiAgICAgICAgL01BWF9BQklMSVRZOwoKICBpZiAodmFsID4gODUpIHsKICAgIGxvZ19maWxlKCJXRUFQT05fU0tJTExTIiwgc3ByaW50ZigiJXM6IFp1IGhvaGVyIFNjaGFkZW4gdm9uOiAiCiAgICArIlRPOiAlTywgVEk6ICVPLCBQTzogJU8sIHZhbDogJWQsIEFfREVYOiAlZCwgQV9TVFI6ICVkLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyJQX1dFQVBPTjogJU8sIFBfV0M6ICVkXG4iLCBkdGltZSh0aW1lKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfb2JqZWN0KCksIHRoaXNfaW50ZXJhY3RpdmUoKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNfb2JqZWN0KCksIHZhbCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlBdHRyaWJ1dGUoQV9ERVgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFF1ZXJ5QXR0cmlidXRlKEFfU1RSKSwgc2luZm9bUF9XRUFQT05dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpbmZvW1BfV0VBUE9OXS0+UXVlcnlQcm9wKFBfV0MpKSk7CiAgICB2YWwgPSA4NTsKICB9CgogIC8qCiAgICBEZXIgenVz5HR6bGljaGUgU2NoYWRlbiBkZXIgYWxsZ2VtZWluZW4gV2FmZmVuc2tpbGxzIGJlcmVjaG5ldAogICAgc2ljaCB3aWUgZm9sZ3Q6IAoKICAgIHNpbmZvW1NJX1NLSUxMQUJJTElUWSkqIChQX1dDICogKCBYICkgLyA4MDApIC8gTUFYX0FCSUxJVFkKCiAgICBEYWJlaSBiZXJ1ZWNrc2ljaHRpZ3QgWCBqZSBuYWNoIFdhZmZlbnR5cCBpbiB1bnRlcnNjaGllZGxpY2hlcgogICAgR2V3aWNodHVuZyBkaWUgV2VydGUgZnVlciBHZXNjaGlja2xpY2hrZWl0IHVuZCBTdGFlcmtlLiAKCiAgICAgWCA9PSAKCiAgICAgICBNZXNzZXIgICA6IDgqQV9ERVggKyAyKkFfU1RSCiAgICAgICBTY2h3ZXJ0ICA6IDUqQV9ERVggKyA1KkFfU1RSCiAgICAgICBBeHQgICAgICA6IDQqQV9ERVggKyA2KkFfU1RSIAogICAgICAgU3BlZXIgICAgOiA2KkFfREVYICsgNCpBX1NUUgogICAgICAgS2V1bGUgICAgOiAxKkFfREVYICsgOSpBX1NUUgogICAgICAgUGVpdHNjaGUgOiA5KkFfREVYICsgMSpBX1NUUgogICovCgogIHNpbmZvW1NJX1NLSUxMREFNQUdFXSs9dmFsOwoKCiAgLyogTGVybmVuOiBXaXJkIGltbWVyIHNjaHdpZXJpZ2VyLCBudXIgYmVpIGplZGVtIDIwLiBTY2hsYWcgaW0gU2Nobml0dCwKICAgKiB1bmQgbnVyIGRhbm4sIHdlbm4gZGVyIEdlZ25lciBhdWNoIFhQIGdpYnQuIAogICAqIEVNLUJlc2NobHVzczogTGVybmVuIHdpcmQgbGVpY2h0ZXIgKGplZGVyIDUuIFNjaGxhZywgc2tpbGxhYmhhZW5naWcpCiAgICogdW5kIGJlaSBqZWRlbSAzMDAuIFNjaGxhZyBsZXJudCBtYW4gYXVjaCBzby4gRmVybmVyIHdpcmQgbm9jaCAKICAgKiB1ZWJlcnBydWVmdCwgb2IgZGVyIFNraWxsIHNjaG9uIG1heGltYWwgaXN0LCB3ZW5uIG1hbiBzb25zdCBpbgogICAqIGplZGVtIEZhbGxlIGxlcm5lbiB3dXJkZS4gCiAgICovCiAgaWYgKChyYW5kb20oTUFYX0FCSUxJVFkrMSk+c2luZm9bU0lfU0tJTExBQklMSVRZXSAmJiAhcmFuZG9tKDUpKQogICAgICAgfHwgKCFyYW5kb20oMzAwKSAmJiBzaW5mb1tTSV9TS0lMTEFCSUxJVFldPE1BWF9BQklMSVRZKSkKICB7CiAgICAgICAgIGVuZW15PXNpbmZvW1NJX0VORU1ZXTsKICAgICAgICAgaWYgKG9iamVjdHAoZW5lbXkpICYmIChlbmVteS0+UXVlcnlQcm9wKFBfWFApPjApKQogICAgICAgICB7CiAgICAgICAgICAgb2JqZWN0IGF1c2JpbGRlcjsKICAgICAgICAvLyAgICAgICAgIGxvZ19maWxlKCJodW1uaS9sb2dfd3VybSIsIkhhdXQ6ICVzIHVuZCB6d2FyICVzLCBtaXQgeHAgJWRcbiIsZ2V0ZXVpZCh0aGlzX29iamVjdCgpKSx0b19zdHJpbmcoZW5lbXkpLGVuZW15LT5RdWVyeVByb3AoUF9YUCkpOwogICAgICAgICAgICBMZWFyblNraWxsKHNuYW1lLCByYW5kb20oNSksIDE1MCk7CiAgICAgICAgLy8gR2lidCBlcyBlaW5lbiBBdXNiaWxkZXI/CiAgICAgICAgaWYgKFF1ZXJ5UHJvcChQX1dFQVBPTl9URUFDSEVSKSAmJiAKICAgICAgICAgICAgICAgICAgICAgICAgYXVzYmlsZGVyPWZpbmRfcGxheWVyKFF1ZXJ5UHJvcChQX1dFQVBPTl9URUFDSEVSKSkpCiAgICAgICAgICB7CiAgICAgICAgICAgIC8vIElzdCBkZXIgQXVzYmlsZGVyIGFud2VzZW5kPwogICAgICAgICAgICBpZiAocHJlc2VudChhdXNiaWxkZXIsZW52aXJvbm1lbnQoKSkpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgIC8vIEF1c2JpbGRlciB1bmQgQXp1YmkgbXVlc3NlbiBkaWVzZWxiZSBXYWZmZSBoYWJlbi4KICAgICAgICAgICAgICAvL3N0cmluZyB3dF9hdXMsd3RfYXp1OwogICAgICAgICAgICAgIG9iamVjdCB3YWZfYXVzLHdhZl9henU7CgogICAgICAgICAgICAgIHdhZl9henU9UXVlcnlQcm9wKFBfV0VBUE9OKTsKICAgICAgICAgICAgICB3YWZfYXVzPWNhbGxfb3RoZXIoYXVzYmlsZGVyLCJRdWVyeVByb3AiLFBfV0VBUE9OKTsKCiAgICAgICAgICAgICAgLy93dF9henU9Y2FsbF9vdGhlcih3YWZfYXp1LCJRdWVyeVByb3AiLFBfV0VBUE9OX1RZUEUpOwogICAgICAgICAgICAgIC8vd3RfYXVzPWNhbGxfb3RoZXIod2FmX2F1cywiUXVlcnlQcm9wIixQX1dFQVBPTl9UWVBFKTsKICAgICAgICAgICAgICAvL2lmICh3dF9henU9PXd0X2F1cykKICAgICAgICAgICAgICBpZiAob2JqZWN0cCh3YWZfYXVzKSAmJiBvYmplY3RwKHdhZl9henUpICYmCiAgICAgICAgICAgICAgICAgIChzdHJpbmcpd2FmX2F1cy0+UXVlcnlQcm9wKFBfV0VBUE9OX1RZUEUpCiAgICAgICAgICAgICAgICAgICAgID09IChzdHJpbmcpd2FmX2F6dS0+UXVlcnlQcm9wKFBfV0VBUE9OX1RZUEUpKSAKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIEJvbnVzIHZvbiBiaXMgenUgNSBQdW5rdGVuCiAgICAgICAgICAgICAgICAvL2xvZ19maWxlKCJodW1uaS9sb2dfYXp1YmkiLAogICAgICAgICAgICAgICAgICAvLyBzcHJpbnRmKCJBenViaSAlTyB1bmQgQXVzYmlsZGVyICVPIDogV2FmZmVudHlwZW4gJXMgdW5kICVzLCBnZWxlcm50XG4iLHRoaXNfb2JqZWN0KCksCiAgICAgICAgICAgICAgICAgICAgLy8gICBhdXNiaWxkZXIsIHd0X2F6dSwgd3RfYXVzKSk7CiAgICAgICAgICAgICAgICBMZWFyblNraWxsKHNuYW1lLHJhbmRvbSg2KSwxNTApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICB9CgogIC8qIAogICAgIERpZSBTY2h3aWVyaWdrZWl0IGxpZWd0IGJlaSAxNTAsIHNvIGRhc3MgCiAgICAgZWluIEx2bC4gMSBTcGllbGVyIG1heGltYWwgMTUlIFNraWxsIAogICAgIHVzdy4uLgogICAgIGxlcm5lbiBrYW5uLiAoR2VuYXVlIFRhYmVsbGUgaW4gL3N0ZC9saXZpbmcvc2tpbGxzIGJlaSBMaW1pdEFiaWxpdHkpCiAgKi8gICAgICAgICAKCiAgcmV0dXJuIHNpbmZvOwp9CgoKLy8gU3RhbmRhcmRpc2llcnRlIEZlcm5rYW1wZi1GdW5rdGlvbiBmdWVyIGFsbGUgRmVybmthbXBmLVdhZmZlbmFydGVuCgovLyAqKiogbm9jaCBkZWFrdGl2aWVydCAqKioKCnByb3RlY3RlZCBtYXBwaW5nIExvbmdSYW5nZVNraWxsKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvLCBpbnQgZGFtKSAKeyBpbnQgYWJpbCx2YWw7CgogIGlmICghbWFwcGluZ3Aoc2luZm8pIHx8ICFkYW0gfHwgIW9iamVjdHAoc2luZm9bUF9XRUFQT05dKSB8fAogICAgICAoc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9TSE9PVElOR19XQykpPDUpCiAgICByZXR1cm4gMDsKCiAgYWJpbD1zaW5mb1tTSV9TS0lMTEFCSUxJVFldK3NpbmZvW09GRlNFVChTSV9TS0lMTEFCSUxJVFkpXTsgCiAgdmFsPWRhbSphYmlsL01BWF9BQklMSVRZOwogIHZhbD12YWwvMityYW5kb20odmFsLzIrMSk7CiAgdmFsPSh2YWwqUXVlcnlTa2lsbEF0dHJpYnV0ZShTQV9EQU1BR0UpKS8xMDA7CiAgc2luZm9bU0lfU0tJTExEQU1BR0VdKz12YWw7CgogIGlmIChyYW5kb20oTUFYX0FCSUxJVFkrMSk+c2luZm9bU0lfU0tJTExBQklMSVRZXSAmJiByYW5kb20oNTApPT00MikKICAgIExlYXJuU2tpbGwoc25hbWUsIDEsIDE1MCk7CgogIHJldHVybiBzaW5mbzsKfQoKCgovLyBEaWUgZWluemVsbmVuIFdhZmZlbnNraWxscyBydWZlbiBkYW5uIG51ciBkaWUgU3RhbmRhcmQtRnVua3Rpb24gYXVmLgoKcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfYXhlKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQp7CiAgcmV0dXJuIFNob3J0UmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvKTsKfQoKcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfY2x1YihvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKewogIHJldHVybiBTaG9ydFJhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbyk7Cn0KCnByb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X2tuaWZlKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQp7CiAgcmV0dXJuIFNob3J0UmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvKTsKfQoKcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfc3BlYXIob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCnsKICByZXR1cm4gU2hvcnRSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8pOwp9Cgpwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9GaWdodF9zd29yZChvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykgCnsKICByZXR1cm4gU2hvcnRSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8pOwp9Cgpwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9GaWdodF93aGlwKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQp7CiAgcmV0dXJuIFNob3J0UmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvKTsKfQoKcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfc3RhZmYob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCnsKICByZXR1cm4gU2hvcnRSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8pOwp9CgoKCgovLyBEaWUgRmVybndhZmZlbnNraWxscyBzaW5kIE11bml0aW9uc2FiaGFlbmdpZwoKLy8gKioqIG5vY2ggZGVha3RpdmllcnQgKioqCgpwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9TaG9vdF9hcnJvdyhvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKewogIHJldHVybiBMb25nUmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvLCA0MCk7Cn0KCnByb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX1Nob290X2JvbHQob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCnsgCiAgcmV0dXJuIExvbmdSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8sIDQwKTsKfQoKcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfU2hvb3RfZGFydChvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKewogIHJldHVybiBMb25nUmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvLCAyMCk7Cn0KCnByb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX1Nob290X3N0b25lKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQp7CiAgcmV0dXJuIExvbmdSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8sIDQwKTsKfQoKcHJvdGVjdGVkIG1peGVkIF9xdWVyeV9sb2NhbGNtZHMoKSB7CiAgICByZXR1cm4gKHsgKHsic3BydWNoZXJtdWVkdW5nIiwiZW5hYmxlX3NwZWxsX2ZhdGlndWVfY29tcGF0IiwwLDB9KSB9KTsKfQoKCgovLyAqKiogS29tcGF0aWJpbGl0YWV0c21vZHVzIGZ1ZXIgU3BlbGxmYXRpZ3VlcyAoRW11bGF0aW9uIDJzLUFsYXJtemVpdCkgKioqCgovKiogU3BlaWNoZXJ0IGVpbmUgU3BlbGxmYXRpZ3VlIHZvbiA8ZHVyYXRpb24+IFNla3VuZGVuIGZ1ZXIgPGtleT4uCiAqIElzdCBoaWVyIG51ciBmdWVyIGRlbiBTcGVsbGZhdGlndWUtQ29tcGF0LW1vZGUuCiAqIDxrZXk+IGRhcmYgMCBzZWluIHVuZCBiZXplaWNobmV0IGRhcyBnbG9iYWxlIFNwZWxsZmF0aWd1ZS4KICogUnVlY2tnYWJld2VydDogQWJsYXVmemVpdCBkZXIgZ2VzZXR6dGVuIFNwZXJyZQogICAgICAgICAgICAgICAgICAtMSwgd2VubiBub2NoIGVpbmUgbmljaHQtYWJnZWxhdWZlbmUgU3BlcnJlIGF1ZiBkZW0gPGtleT4gbGFnLgogICAgICAgICAgICAgICAgICAwLCB3ZW5uIGR1cmF0aW9uIDAgaXN0LgogKi8KcHVibGljIHZhcmFyZ3MgaW50IFNldFNwZWxsRmF0aWd1ZShpbnQgZHVyYXRpb24sIHN0cmluZyBrZXkpIHsKCiAgLy8gMCBzb2xsdGUgbmllIGVpbmUgU3BlcnJlIGJld2lya2VuLCBhdWNoIG5pY2h0IGltIGNvbXBhdCBtb2RlLgogIGlmICghZHVyYXRpb24pIHJldHVybiAwOwoKICBpZiAoc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSkgewogICAgLy8gU3BlbGwtRmF0aWd1ZXMgYXVmIEhCcyBzeW5jaHJvbmlzaWVyZW4gKDJzLUFsYXJtemVpdC1FbXVsYXRpb24pLgogICAgLy8gQXVmcnVuZGVuIGF1ZiBnYW56emFobGlnZSBWaWVsZmFjaGUgdm9uIF9fSEVBUlRfQkVBVF9JTlRFUlZBTF9fCiAgICBpZiAoZHVyYXRpb24gJSBfX0hFQVJUX0JFQVRfSU5URVJWQUxfXykKICAgICAgICArK2R1cmF0aW9uOwoKICAgIC8vIFN0YXJ0cHVua3QgZGVzIERlbGF5IHNvbGwgQmVnaW5uIGRlciBha3R1ZWxsZW4gS2FtcGZydW5kZSAoSEItWnlrbHVzKQogICAgLy8gc2VpbiwgZ2dmLiB1bSBtYXguIGVpbmUgU2VrdW5kZSB6dXJ1ZWNrZGF0aWVyZW4uCiAgICAvLyAoc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSBoYXQgZGllIFplaXQgZGVzIGxldHp0ZW4gSEItQXVmcnVmcykKICAgIC8vIEZhbGxzIGR1cmNoIGlyZ2VuZGVpbiBQcm9ibGVtICh6LkIuIHNlaHIgaG9oZSBMYXN0KSwgZGVyIGxldHp0ZSBIQgogICAgLy8gbGFlbmdlciBhbHMgMXMgenVydWVja2xpZWd0LCBmdW5rdGlvbmllcnQgZGFzIG5hdHVlcmxpY2ggbmljaHQsIGFiZXIKICAgIC8vIGJlaSBmYXRpZ3VlKz1zcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlIGthbm4gZGVyIFNwaWVsZXIgenV2aWVsIFplaXQKICAgIC8vIGVpbnNwYXJlbi4KICAgIGlmICh0aW1lKCkgPiBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlKQogICAgICAgIC0tZHVyYXRpb247ICAvLzFzIHp1cnVlY2tkYXRpZXJlbgogIH0KCiAgcmV0dXJuIDo6U2V0U3BlbGxGYXRpZ3VlKGR1cmF0aW9uLCBrZXkpOwp9CgovKiogQmVmZWhsc2Z1bmt0aW9uIGZ1ZXIgU3BpZWxlciB1bSBkZW4gU3BlbGxmYXRpZ3VlLUtvbXBhdGliaWxpdGFldHNtb2R1cwogKiB1bXp1c2NoYWx0ZW4uCiAqLwpwdWJsaWMgaW50IGVuYWJsZV9zcGVsbF9mYXRpZ3VlX2NvbXBhdChzdHJpbmcgY21kKSB7CiAgaWYgKFF1ZXJ5UHJvcChQX0xBU1RfQ09NQkFUX1RJTUUpICsgNjAwID4gdGltZSgpKSB7CiAgICB3cml0ZShicmVha19zdHJpbmcoCiAgICAgICJJbSBLYW1wZiBvZGVyIGt1cnogbmFjaCBlaW5lbSBLYW1wZiBrYW5uc3QgRHUgbmljaHQgendpc2NoZW4gIgogICAgICAiYWx0ZXIgdW5kIG5ldWVyIFNwcnVjaGVybXVlZHVuZyB1bXNjaGFsdGVuLlxuIgogICAgICAiTW9tZW50YW4gYmVudXR6dCBEdSBkaWUgIgogICAgICArIChzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlID8gImFsdGUgKHVuZ2VuYXVlcmUpIiA6ICJuZXVlIChub3JtYWxlKSIpCiAgICAgICsgIiBTcHJ1Y2hlcm11ZWR1bmcuIiw3OCwwLEJTX0xFQVZFX01ZX0xGUykpOwogICAgcmV0dXJuIDE7CiAgfQoKICBpZiAoY21kPT0iYWx0IikgewogICAgc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZT10aW1lKCk7CiAgICB3cml0ZShicmVha19zdHJpbmcoCiAgICAgICJBbHRlIFNwcnVjaGVybXVlZHVuZyB3dXJkZSBlaW5nZXNjaGFsdGV0LiBBbGxlIEVybXVlZHVuZ3NwYXVzZW4gIgogICAgICAiendpc2NoZW4gU3BydWVjaGVuIHdlcmRlbiBhdWYgVmllbGZhY2hlIHZvbiAycyBhdWZnZXJ1bmRldCB1bmQgIgogICAgICAiYmVnaW5uZW4gaW4gZGVyIFJlZ2VsIGFtIEFuZmFuZyBEZWluZXIgS2FtcGZydW5kZS4iKSk7CiAgICByZXR1cm4gMTsKICB9CiAgZWxzZSBpZiAoY21kPT0ibmV1IiB8fCBjbWQ9PSJub3JtYWwiKSB7CiAgICBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlPTA7CiAgICB3cml0ZShicmVha19zdHJpbmcoCiAgICAgICJOb3JtYWxlIFNwcnVjaGVybXVlZHVuZyB3dXJkZSBlaW5nZXNjaGFsdGV0LiBBbGxlIEVybXVlZHVuZ3NwYXVzZW4gIgogICAgICAiendpc2NoZW4gU3BydWVjaGVuIHdlcmRlbiBzZWt1bmRlbmdlbmF1IGJlcmVjaG5ldC4iKSk7CiAgICByZXR1cm4gMTsKICB9CgogIG5vdGlmeV9mYWlsKGJyZWFrX3N0cmluZygKICAgICAgIk1vZWNodGVzdCBEdSBkaWUgYWx0ZSBvZGVyIGRpZSBuZXVlIFNwcnVjaGVybXVlZHVuZz9cbiIKICAgICAgIk1vbWVudGFuIGJlbnV0enQgRHUgZGllICIKICAgICAgKyAoc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSA/ICJhbHRlICh1bmdlbmF1ZXJlKSIgOiAibmV1ZSAobm9ybWFsZSkiKQogICAgICArICIgU3BydWNoZXJtdWVkdW5nLiIsNzgsMCxCU19MRUFWRV9NWV9MRlMpKTsKICByZXR1cm4gMDsKfQoKLyoqIFNwZWljaGVydCBkaWUgWmVpdCBkZXMgbGV0enRlcyBIZWFydGJlYXRzLgogKi8KcHJvdGVjdGVkIHZvaWQgaGVhcnRfYmVhdCgpIHsKICBpZiAoc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSkKICAgIHNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGUgPSB0aW1lKCk7Cn0KCnN0YXRpYyBpbnQgX3NldF9ndWlsZF9sZXZlbChpbnQgbnVtKQp7IHN0cmluZyBnaWxkZTsKICBtYXBwaW5nIGxldmVsczsKCiAgaWYgKCAhKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgKQogICAgcmV0dXJuIDA7CgogIGlmICggIW1hcHBpbmdwKGxldmVscz1RdWVyeShQX0dVSUxEX0xFVkVMKSkgKQogICAgbGV2ZWxzPShbXSk7CgogIGxldmVsc1tnaWxkZV09bnVtOwogIFNldChQX0dVSUxEX0xFVkVMLGxldmVscyk7CiAgR01DUF9DaGFyKCAoW1BfR1VJTERfTEVWRUw6IG51bV0pICk7CgogIHJldHVybiBudW07Cn0KCnN0YXRpYyBpbnQgX3F1ZXJ5X2d1aWxkX2xldmVsKCkKeyBzdHJpbmcgIGdpbGRlOwogIG1hcHBpbmcgbGV2ZWxzOwoKICBpZiAoICEoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCiAgICByZXR1cm4gMDsKCiAgaWYgKCAhbWFwcGluZ3AobGV2ZWxzPVF1ZXJ5KFBfR1VJTERfTEVWRUwpKSApCiAgICAgIHJldHVybiAwOwoKICByZXR1cm4gbGV2ZWxzW2dpbGRlXTsKfQoKc3RhdGljIHN0cmluZyBfc2V0X2d1aWxkX3RpdGxlKHN0cmluZyB0KQp7IHN0cmluZyBnaWxkZTsKICBtYXBwaW5nIHRpdGxlczsKCiAgaWYgKCAhKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgKQogICAgcmV0dXJuIDA7CgogIGlmICggIW1hcHBpbmdwKHRpdGxlcz1RdWVyeShQX0dVSUxEX1RJVExFKSkgKQogICAgdGl0bGVzPShbXSk7CgogIHRpdGxlc1tnaWxkZV09dDsKICBTZXQoUF9HVUlMRF9USVRMRSx0aXRsZXMpOwogIEdNQ1BfQ2hhciggKFtQX0dVSUxEX1RJVExFOiB0XSkgKTsKICByZXR1cm4gdDsKfQoKc3RhdGljIHN0cmluZyBfcXVlcnlfZ3VpbGRfdGl0bGUoKQp7IHN0cmluZyBnaWxkZSx0OwogIG9iamVjdCBnOwogIG1hcHBpbmcgdGl0bGVzOwoKICBpZiAoICEoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCiAgICByZXR1cm4gMDsKCiAgaWYgKCAhbWFwcGluZ3AodGl0bGVzPVF1ZXJ5KFBfR1VJTERfVElUTEUpKSApCiAgICB0aXRsZXM9KFtdKTsKCiAgdD10aXRsZXNbZ2lsZGVdOwogIGlmICggIXQgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKQogICAgICAmJiBvYmplY3RwKGc9ZmluZF9vYmplY3QoIi9naWxkZW4vIitnaWxkZSkpICkKICB7CiAgICBnLT5hZGp1c3RfdGl0bGUodGhpc19vYmplY3QoKSk7CiAgICBTZXRQcm9wKFBfVElUTEUsMCk7CgogICAgaWYgKCAhbWFwcGluZ3AodGl0bGVzPVF1ZXJ5KFBfR1VJTERfVElUTEUpKSApCiAgICAgIHJldHVybiAwOwoKICAgIHQ9dGl0bGVzW2dpbGRlXTsKICB9CgogIHJldHVybiB0Owp9CgoKc3RhdGljIHN0cmluZyBfc2V0X2d1aWxkKHN0cmluZyBnaWxkZW5uYW1lKQp7IG9iamVjdCBwcmU7CgogIGlmICghb2JqZWN0cChwcmU9cHJldmlvdXNfb2JqZWN0KCkpKQogICAgcmV0dXJuIDA7CgogIGlmICggcHJlIT10aGlzX29iamVjdCgpIC8vIERhcyBMZWJld2VzZW4gc2VsYmVyIGRhcmYgZGllIEdpbGRlIHNldHplbiwKICAgICAgJiYgb2JqZWN0X25hbWUocHJlKSE9R1VJTERNQVNURVIgIC8vIGRlciBHaWxkZW5tYXN0ZXIgYXVjaAogICAgICAmJiAoIXRoaXNfcGxheWVyKCkKICAgICAgICAgIHx8IHRoaXNfcGxheWVyKCkgIT0gdGhpc19pbnRlcmFjdGl2ZSgpCiAgICAgICAgICB8fCAhSVNfQVJDSCh0aGlzX3BsYXllcigpKQogICAgICAgICApCiAgICAgICkKICAgIHJldHVybiAwOwoKICBTZXQoUF9HVUlMRCxnaWxkZW5uYW1lKTsKICBHTUNQX0NoYXIoIChbUF9HVUlMRDogZ2lsZGVubmFtZV0pICk7CiAgcmV0dXJuIGdpbGRlbm5hbWU7Cn0KCnN0YXRpYyBzdHJpbmcgX3F1ZXJ5X2d1aWxkKCkKeyBzdHJpbmcgcmVzOwoKICBpZiAoICEocmVzPVF1ZXJ5KFBfR1VJTEQpKSAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpICkKICB7CiAgICAvLyBTcGllbGVyLCBkaWUga2VpbmVyIEdpbGRlIGFuZ2Vob2VyZW4sIGdlaG9lcmVuIHp1ciBBYmVudGV1cmVyZ2lsZGUKICAgIGlmICggIShyZXM9UXVlcnlQcm9wKFBfREVGQVVMVF9HVUlMRCkpICkKICAgICAgcmV0dXJuIERFRkFVTFRfR1VJTEQ7CiAgICBlbHNlCiAgICAgIFNldChQX0dVSUxELHJlcyk7CiAgICByZXR1cm4gcmVzOwogIH0KCiAgcmV0dXJuIHJlczsKfQoKc3RhdGljIHN0cmluZyBfcXVlcnlfdGl0bGUoKQp7IHN0cmluZyB0aTsKCiAgaWYgKCBzdHJpbmdwKHRpPVF1ZXJ5KFBfVElUTEUpKSApCiAgICByZXR1cm4gdGk7CgogIHJldHVybiBRdWVyeVByb3AoUF9HVUlMRF9USVRMRSk7Cn0KCnN0YXRpYyBzdHJpbmcgX3NldF90aXRsZShzdHJpbmcgdCkKewogIFNldChQX1RJVExFLCB0LCBGX1ZBTFVFKTsKICBHTUNQX0NoYXIoIChbUF9USVRMRTogdF0pICk7CiAgcmV0dXJuIHQ7Cn0KCg==