Ly8gTW9yZ2VuR3JhdWVuIE1VRGxpYgovLwovLyBwbGF5ZXIvc2tpbGxzLmMgLS0gU3BpZWxlcnNraWxscwovLwovLyAkSWQ6IHNraWxscy5jIDg4MDkgMjAxNC0wNS0wOCAxOTo1Mjo0OFogWmVzc3RyYSAkCgovLwovLyAyMDAzLTAxLTIwOiBOdW4gWm9va3MgQmF1c3RlbGxlCi8vCiNwcmFnbWEgc3Ryb25nX3R5cGVzCiNwcmFnbWEgc2F2ZV90eXBlcwojcHJhZ21hIHJhbmdlX2NoZWNrCiNwcmFnbWEgbm9fY2xvbmUKI3ByYWdtYSBwZWRhbnRpYwoKaW5oZXJpdCAiL3N0ZC9saXZpbmcvc2tpbGxzIjsKCiNpbmNsdWRlIDxjb21iYXQuaD4KI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KI2luY2x1ZGUgPGJyZWFrX3N0cmluZy5oPgojaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CgojZGVmaW5lIE5FRURfUFJPVE9UWVBFUwojaW5jbHVkZSA8cGxheWVyL2Jhc2UuaD4KI2luY2x1ZGUgPHBsYXllci9nbWNwLmg+CiN1bmRlZiBORUVEX1BST1RPVFlQRVMKCi8vIERpZXNlcyBNYXBwaW5nIHNwZWljaGVydCBkaWUgZGVha3RpdmllcnRlbiBTa2lsbHMgZGVyIGVpbnplbG5lbiBHaWxkZW4KLy8gRGllc2Ugd2VyZGVuIGluIGRlbiBHaWxkZW4gdWViZXIgUF9HVUlMRF9ERUFDVElWQVRFRF9TS0lMTCBnZXNldHp0Lgpub3NhdmUgbWFwcGluZyBkZWFjdGl2YXRlZF9za2lsbHMgPSAoW10pOwoKLy8gRmxhZyBmdWVyIGRlbiBLb21wYXRpYmlsaXRhZXRzbW9kdXMgZGVzIEthbXBmcyAoRW11bGF0aW9uIHZvbgovLyAycy1BbGFybXplaXQpLiBXZW5uICE9IDAgc3BlaWNoZXJ0IGRhcyBGbGFnIGdsZWljaHplaXRpZyBkaWUgWmVpdCBkZXMKLy8gbGV0enRlbiBIZWFydGJlYXRzLiBBdWYgZGllc2UgWmVpdCB3aXJkIGRlciBTdGFydHB1bmt0IGVpbmVzIFNwZWxsZmF0aWd1ZXMKLy8gZ2dmLiB6dXJ1ZWNrZGF0aWVydC4gKG1heC4gZWluZSBTZWt1bmRlKQppbnQgc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZTsKCi8vIEVpbiBjcmVhdGUoKSBmdWVyIGRhcyBNYXBwaW5nCgpwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQp7CiAgbWFwcGluZyBhY3Q7CgogIDo6Y3JlYXRlKCk7CgogIC8vIFdpciBob2xlbiBkaWUgR2lsZGVuIGF1cyBkZW0gR2lsZGVubWFzdGVyIAogIGZvcmVhY2goc3RyaW5nIGd1aWxkOgogICAgICAoc3RyaW5nICopY2FsbF9vdGhlcihHVUlMRE1BU1RFUiwiUXVlcnlQcm9wIixQX1ZBTElEX0dVSUxEUykpCiAgewogICAgaWYoY2F0Y2goYWN0PWNhbGxfb3RoZXIoIi9naWxkZW4vIitndWlsZCwiUXVlcnlQcm9wIiwKICAgICAgICBQX0dVSUxEX0RFQUNUSVZBVEVfU0tJTExTKTsgcHVibGlzaCApKQogICAgICAgIGxvZ19maWxlKCJXRUFQT05fU0tJTExTIiwgc3ByaW50ZiAoIiVzOiBHaWxkZSBuaWNodCBsYWRiYXI6ICIKICAgICAgICAgICAgICArIlRQOiAlTywgVEk6ICVPLCBQTzogJU8sIEdpbGRlOiAlc1xuIiwgZHRpbWUodGltZSgpKSwKICAgICAgICAgICAgICB0aGlzX3BsYXllcigpLCB0aGlzX2ludGVyYWN0aXZlKCksIHByZXZpb3VzX29iamVjdCgpLCBndWlsZCkpOwogICAgZWxzZSBpZiAoYWN0KSAvLyB3ZW5uIGFjdCwgaW5zIE1hcHBpbmcgYXVmbmVobWVuLgogICAgICAgIGRlYWN0aXZhdGVkX3NraWxscys9KFtndWlsZDphY3RdKTsKICB9CiAgLy8ga2VpbmUgZWNodGUgUHJvcCBtZWhyLCBTYXZlLU1vZHVzIHVubm9ldGlnLgogIFNldChQX05FWFRfU1BFTExfVElNRSxTQVZFLEZfTU9ERV9BRCk7CgogIFNldChQX1NLSUxMU1ZFUlNJT04sIFNBVkV8U0VDVVJFRCwgRl9NT0RFX0FTKTsKfQoKLy8gRGFzIE1hcHBpbmcga2FubiBtYW4gYXVjaCBhYmZyYWdlbgoKcHVibGljIG1hcHBpbmcgR2V0RGVhY3RpdmF0ZWRTa2lsbHMoKQp7CiAgICByZXR1cm4gY29weShkZWFjdGl2YXRlZF9za2lsbHMpOwp9CgovLyBGdW5rdGlvbiwgZGllIHNhZ3Qgb2IgZWluIEFOWS1Ta2lsbCBkZWFrdGl2aWVydCBpc3QuCnB1YmxpYyBpbnQgaXNfZGVhY3RpdmF0ZWRfc2tpbGwoc3RyaW5nIHNuYW1lLHN0cmluZyBndWlsZCkKewogICAgICAgIGlmIChkZWFjdGl2YXRlZF9za2lsbHNbZ3VpbGRdKSAgICAgICAgCiAgICAgICAgICAgICAgICByZXR1cm4gZGVhY3RpdmF0ZWRfc2tpbGxzW2d1aWxkXVtzbmFtZV07CiAgICAgICAgcmV0dXJuIDA7Cn0KCgovLyBGdW5rdGlvbiBmdWVyIGRpZSBXYWZmZW5za2lsbHMKLy8gdHJhZWd0IGRpZSBhbGxnLiBXYWZmZW5za2lsbHMgZWluLiBXaXJkIGdnZi4gdm9uIEZpeFNraWxscygpIGdlcnVmZW4uCi8vIChEYXMgRWludHJhZ2VuIGJlZGV1dGV0IG5pY2h0LCBkYXNzIGRpZSBha3RpdiBzaW5kISBBYmVyIGJlaSBHaWxkZW53ZWNoc2VsCi8vIHdlcmRlbiBzaWUgbmljaHQgZWluZ2V0cmFnZW4pLgpwcml2YXRlIHZvaWQgc2V0X3dlYXBvbl9za2lsbHMoKSB7CgogIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9TV09SRCkpPD0wKSAgICAgICAgICAgICAgICAKICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfU1dPUkQpLChbU0lfU0tJTExBQklMSVRZOjBdKSwxNTAsIkFOWSIpOyAgICAKICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfQVhFKSk8PTApICAgICAgICAgICAgICAgIAogICAgICBNb2RpZnlTa2lsbChGSUdIVChXVF9BWEUpLChbU0lfU0tJTExBQklMSVRZOjBdKSwxNTAsIkFOWSIpOyAgICAgICAgICAKICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfU1BFQVIpKTw9MCkgICAgICAgIAogICAgICBNb2RpZnlTa2lsbChGSUdIVChXVF9TUEVBUiksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7ICAgICAgICAgIAogIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9XSElQKSk8PTApCiAgICAgIE1vZGlmeVNraWxsKEZJR0hUKFdUX1dISVApLChbU0lfU0tJTExBQklMSVRZOjBdKSwxNTAsIkFOWSIpOwogIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9LTklGRSkpPD0wKSAgICAgICAgICAgICAgICAKICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfS05JRkUpLChbU0lfU0tJTExBQklMSVRZOjBdKSwxNTAsIkFOWSIpOyAgICAgICAgICAKICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfQ0xVQikpPD0wKSAgICAgICAgICAgICAgICAKICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfQ0xVQiksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7ICAgICAgICAgIAogIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9TVEFGRikpPD0wKQogICAgICBNb2RpZnlTa2lsbChGSUdIVChXVF9TVEFGRiksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7Cn0gCgovLyBpbml0aWFsaXNpZXJ0IGRpZSBTa2lsbHMgZnVlciBTcGllbGVyIChtb21lbnRhbjogYWxsZy4gV2FmZmVuc2tpbGxzIHNldHplbgovLyB1bmQgUF9TS0lMTFNfVkVSU0lPTikKcHJvdGVjdGVkIHZvaWQgSW5pdFNraWxscygpIHsKICBtYXBwaW5nIHNraTsKICAvLyBzY2hvbm1hbCBpbml0aWFsaXNpZXJ0PwogIGlmIChtYXBwaW5ncChza2k9UXVlcnkoUF9ORVdTS0lMTFMsIEZfVkFMVUUpKSAmJiBzaXplb2Yoc2tpKSkKICAgIHJldHVybjsKCiAgLy8gYWxsZy4gV2FmZmVuc2tpbGxzIGFrdGl2aWVyZW4KICBzZXRfd2VhcG9uX3NraWxscygpOwoKICAvLyBWZXJzaW9uIHNldHplbgogIFNldFByb3AoUF9TS0lMTFNWRVJTSU9OLCBDVVJSRU5UX1NLSUxMX1ZFUlNJT04pOwogIFNldChQX1NLSUxMU1ZFUlNJT04sIFNBVkV8U0VDVVJFRCwgRl9NT0RFX0FTKTsKfQoKLy8gVXBkYXRlZCBTa2lsbHMgYXVzIFZlcnNpb24gMCB1bmQgMSBoZXJhdXMuCnByaXZhdGUgdm9pZCBGaXhTa2lsbFYxKHN0cmluZyBza2lsbG5hbWUsIG1peGVkIHNpbmZvKSB7CiAgLy8gYWx0ZSBTa2lsbHMgYXVmIG1hcHBpbmdzIG5vcm1pZXJlbgogIGlmIChpbnRwKHNpbmZvKSkgewogICAgc2luZm8gPSAoW1NJX1NLSUxMQUJJTElUWTogc2luZm8gXSk7CiAgfQogIC8vIEVpbmUgUmVpaGUgdm9uIERhdGVuIHdlcmRlbiBnZWxvZXNjaHQsIGRhIGRpZSBEYXRlbiBhdXMgZGVyCiAgLy8gR2lsZGUvU3BlbGxib29rIGZyaXNjaCBrb21tZW4gc29sbHRlbiB1bmQgc2llIG5pY2h0IHNwaWVsZXItaW5kaXZpZHVlbGwKICAvLyBzaW5kOiBTSV9DTE9TVVJFICh3aXJkIG9udGhlZmx5IGtvcnJla3QgbmV1IGVyemV1Z3QpLCBTSV9TS0lMTEFSRywKICAvLyBTSV9OVU1CRVJfRU5FTUlFUywgU0lfTlVNQkVSX0ZSSUVORFMsIFNJX0RJU1RBTkNFLCBTSV9XSURUSCwgU0lfREVQVEgsCiAgLy8gU0lfVEVTVEZMQUcsIFNJX0VORU1ZLCBTSV9GUklFTkQuCiAgLy8gQXVzc2VyZGVtIHNpbmQgYWxsZSBTUF8qIGltIHRvcGxldmVsIGZhbHNjaCwgZGllIG11ZXNzZW4gYSkgaW4gU0lfU1BFTEwKICAvLyB1bmQgc29sbHRlbiBiKSBuaWNodCBpbSBTcGllbGVyIGdlc3BlaWNoZXJ0IHdlcmRlbiwgc29uZGVybiB2b24KICAvLyBHaWxkZW4vU3BlbGxib29rIGpld2VpbHMgZnJpc2NoIGtvbW1lbi4KICAvLyBhbGwgZGllc2VzIFpldWcgbGFuZGV0ZSBpbiBhbHRlbiBTcGllbGVybiBpbSBTYXZlZmlsZS4KICBpZiAobWFwcGluZ3Aoc2luZm8pKQogICAgc2luZm8gLT0gKFtTSV9DTE9TVVJFLCBTSV9TS0lMTEFSRywgU0lfTlVNQkVSX0VORU1JRVMsIFNJX05VTUJFUl9GUklFTkRTLAogICAgICAgICAgICAgU0lfRElTVEFOQ0UsIFNJX1dJRFRILCBTSV9ERVBUSCwgU0lfVEVTVEZMQUcsIFNJX0VORU1ZLAogICAgICAgICAgICAgU0lfRlJJRU5ELCBTUF9OQU1FLCBTUF9TSE9XX0RBTUFHRSwgU1BfUkVEVUNFX0FSTU9VUiwKICAgICAgICAgICAgIFNQX1BIWVNJQ0FMX0FUVEFDSywgU1BfUkVDVVJTSVZFLCBTUF9OT19FTkVNWSwKICAgICAgICAgICAgIFNQX05PX0FDVElWRV9ERUZFTlNFLCBTUF9HTE9CQUxfQVRUQUNLIF0pOwogIGVsc2UKICB7CiAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLHNwcmludGYoCiAgICAgICJcbioqKiogQUNIVFVORyAtIEZFSExFUiAqKipcbiIgCiAgICAgICJEZWluZSBTa2lsbHMgZW50aGFsdGVuIGVpbmVuIGRlZmVrdGVuIFNraWxsICVPOlxuIgogICAgICAiQml0dGUgbGFzcyBkaWVzIHZvbiBlaW5lbSBFcnptYWdpZXIgdWViZXJwcnVlZmVuLlxuIiwKICAgICAgc2tpbGxuYW1lKSk7CiAgfQp9CgovLyBVcGRhdGV0IHVuZCByZXBhcmllcnQgZ2dmLiBTa2lsbG1hcHBpbmdzIGluIFNwaWVsZXJuCnByb3RlY3RlZCB2b2lkIEZpeFNraWxscygpIHsKCiAgLy8gbnVyIGJlaSBnZW51ZyByZWNoZW56ZWl0IGxvc2xlZ2VuCiAgaWYgKGdldF9ldmFsX2Nvc3QoKSA8IDc1MDAwMCkgewogICAgY2FsbF9vdXQoIydGaXhTa2lsbHMsIDEpOwogICAgcmV0dXJuOwogIH0KICAvLyB3ZW5uIGdhciBrZWluZSBTa2lsbHMgZGEgKD8pOiBJbml0U2tpbGxzKCkgcnVmZW4uCiAgbWFwcGluZyBhbGxza2lsbHMgPSBRdWVyeShQX05FV1NLSUxMUywgRl9WQUxVRSk7CiAgaWYgKCFtYXBwaW5ncChhbGxza2lsbHMpIHx8ICFzaXplb2YoYWxsc2tpbGxzKSkgewogICAgICBJbml0U2tpbGxzKCk7CiAgICAgIHJldHVybjsKICB9CgogIC8vIERpZSBGYWxsdGhyb3VnaHMgaW4gZGllc2VtIHN3aXRjaCBzaW5kIHZvbGwgQWJzaWNodCEKICBzd2l0Y2goUXVlcnlQcm9wKFBfU0tJTExTVkVSU0lPTikpIHsKICAgIC8vIGJlaSBWZXJzaW9uIDAgdW5kIDEgZGFzIGdsZWljaGUgdHVuCiAgICBjYXNlIDA6IC8vIHZvbiAwIGF1ZiAxCiAgICBjYXNlIDE6IC8vIHZvbiAxIGF1ZiAyCiAgICAgIGZvcmVhY2goc3RyaW5nIGdpbGRlLCBtYXBwaW5nIHNraWxsczogYWxsc2tpbGxzKSB7CiAgICAgICAgaWYgKCFzdHJpbmdwKGdpbGRlKSkgewogICAgICAgICAgLy8gc29sbHRlIG5pY2h0IHZvcmtvbW1lbiAtIHRhdCBhYmVyLi4uICpzZXVmeioKICAgICAgICAgIG1fZGVsZXRlKHNraWxscywgZ2lsZGUpOwogICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIHdhbGtfbWFwcGluZyhza2lsbHMsICMnRml4U2tpbGxWMSk7CiAgICAgIH0KICAgICAgLy8gYWxsZy4gV2FmZmVuc2tpbGxzIGFrdGl2aWVyZW4sIGVpbmlnZSBhbHRlIFNwaWVsZXIgaGFiZW4gZGllIG5vY2gKICAgICAgLy8gbmljaHQuCiAgICAgIHNldF93ZWFwb25fc2tpbGxzKCk7CiAgICAgIC8vIFNwZWljaGVyZmxhZyBmdWVyIGRpZSBWZXJzaW9uc3Byb3AgbXVzcyBub2NoIGdlc2V0enQgd2VyZGVuLgogICAgICBTZXQoUF9TS0lMTFNWRVJTSU9OLCBTQVZFfFNFQ1VSRUQsIEZfTU9ERV9BUyk7CiAgICAgIC8vIFZlcnNpb24gaXN0IGpldHp0IDIuCiAgICAgIFNldFByb3AoUF9TS0lMTFNWRVJTSU9OLCAyKTsKICAgICAgLy8gRmFsbC10aHJvdWdoCiAgIGNhc2UgMjoKICAgICAgLy8gZ2lidCBlcyBub2NoIG5pY2h0LCBuaWNodHMgbWFjaGVuLgogICAgICAvL1NldFByb3AoUF9TS0lMTFNWRVJTSU9OLCAzKTsKICAgICAgLy8gRmFsbC10aHJvdWdoLCBhdXNzZXIgZXMgc2luZCB6dXdlbmlnIFRpY2tzIGRhIQogICAgICBpZiAoZ2V0X2V2YWxfY29zdCgpIDwgNzUwMDAwKQogICAgICAgIGJyZWFrOyAKICB9CiAgLy8gRmFsbHMgbm9jaCBuaWNodCBhdWYgZGVyIGFrdHVlbGxlbiBWZXJzaW9uIGFuZ2Vrb21tZW4sIG5ldWVyIGNhbGxvdXQKICBpZiAoUXVlcnlQcm9wKFBfU0tJTExTVkVSU0lPTikgPCBDVVJSRU5UX1NLSUxMX1ZFUlNJT04pCiAgICAgIGNhbGxfb3V0KCMnRml4U2tpbGxzLCAyKTsKfQoKcHJvdGVjdGVkIHZvaWQgdXBkYXRlc19hZnRlcl9yZXN0b3JlKGludCBuZXdmbGFnKSB7CiAgLy9BbGxnZW1laW5lIFdhZmZlbnNraWxscyBha3RpdmllcmVuLCB3ZW5uIG5vZXRpZwogIC8vIFdpcmQgbnVuIHZvbiBJbml0U2tpbGxzIGJ6dy4gRml4U2tpbGxzIHVlYmVybm9tbWVuLCBmYWxscyBub2V0aWcuCiAgaWYgKG5ld2ZsYWcpIHsKICAgIEluaXRTa2lsbHMoKTsKICB9CiAgZWxzZSBpZiAoUXVlcnlQcm9wKFBfU0tJTExTVkVSU0lPTikgPCBDVVJSRU5UX1NLSUxMX1ZFUlNJT04pIHsKICAgIC8vIEZhbGxzIG5vZXRpZywgU2tpbGxzIGZpeGVuL3VwZGF0ZW4uICpncnVtbWVsKgogICAgRml4U2tpbGxzKCk7CiAgfQogIC8vIFByb3AgZ2lidCBlcyBuaWNodCBtZWhyLiBTQVZFLVN0YXR1cyBsb2VzY2hlbi4gCiAgU2V0KFBfR1VJTERfUFJFVkVOVFNfUkFDRVNLSUxMLFNBVkUsRl9NT0RFX0FEKTsKfQoKLy8gU3RhbmRhcmRpc2llcnRlIE5haGthbXBmLUZ1bmt0aW9uIGZ1ZXIgYWxsZSBOYWhrYW1wZi1XYWZmZW5hcnRlbgpwcm90ZWN0ZWQgbWFwcGluZyBTaG9ydFJhbmdlU2tpbGwob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pIAp7IAogIGludCB2YWwsIHc7CiAgb2JqZWN0IGVuZW15OwogIAogIGlmICghbWFwcGluZ3Aoc2luZm8pIHx8ICFvYmplY3RwKHNpbmZvW1BfV0VBUE9OXSkpCiAgICByZXR1cm4gMDsKCiAgdyA9IChbV1RfS05JRkUgOiA4LAogICAgICAgIFdUX1NXT1JEIDogNSwKICAgICAgICBXVF9BWEUgICA6IDQsCiAgICAgICAgV1RfU1BFQVIgOiA2LAogICAgICAgIFdUX0NMVUIgIDogMSwKICAgICAgICBXVF9XSElQICA6IDksCiAgICAgICAgV1RfU1RBRkYgOiA3XSlbc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9XRUFQT05fVFlQRSldOwogICAgICAKCiAgdmFsID0gc2luZm9bU0lfU0tJTExBQklMSVRZXSooc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9XQykqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHcqUXVlcnlBdHRyaWJ1dGUoQV9ERVgpKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMTAtdykqUXVlcnlBdHRyaWJ1dGUoQV9TVFIpKS83MDApCiAgICAgICAgL01BWF9BQklMSVRZOwoKICBpZiAodmFsID4gODUpIHsKICAgIGxvZ19maWxlKCJXRUFQT05fU0tJTExTIiwgc3ByaW50ZigiJXM6IFp1IGhvaGVyIFNjaGFkZW4gdm9uOiAiCiAgICArIlRPOiAlTywgVEk6ICVPLCBQTzogJU8sIHZhbDogJWQsIEFfREVYOiAlZCwgQV9TVFI6ICVkLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyJQX1dFQVBPTjogJU8sIFBfV0M6ICVkXG4iLCBkdGltZSh0aW1lKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfb2JqZWN0KCksIHRoaXNfaW50ZXJhY3RpdmUoKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNfb2JqZWN0KCksIHZhbCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlBdHRyaWJ1dGUoQV9ERVgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFF1ZXJ5QXR0cmlidXRlKEFfU1RSKSwgc2luZm9bUF9XRUFQT05dLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpbmZvW1BfV0VBUE9OXS0+UXVlcnlQcm9wKFBfV0MpKSk7CiAgICB2YWwgPSA4NTsKICB9CgogIC8qCiAgICBEZXIgenVz5HR6bGljaGUgU2NoYWRlbiBkZXIgYWxsZ2VtZWluZW4gV2FmZmVuc2tpbGxzIGJlcmVjaG5ldAogICAgc2ljaCB3aWUgZm9sZ3Q6IAoKICAgIHNpbmZvW1NJX1NLSUxMQUJJTElUWSkqIChQX1dDICogKCBYICkgLyA4MDApIC8gTUFYX0FCSUxJVFkKCiAgICBEYWJlaSBiZXJ1ZWNrc2ljaHRpZ3QgWCBqZSBuYWNoIFdhZmZlbnR5cCBpbiB1bnRlcnNjaGllZGxpY2hlcgogICAgR2V3aWNodHVuZyBkaWUgV2VydGUgZnVlciBHZXNjaGlja2xpY2hrZWl0IHVuZCBTdGFlcmtlLiAKCiAgICAgWCA9PSAKCiAgICAgICBNZXNzZXIgICA6IDgqQV9ERVggKyAyKkFfU1RSCiAgICAgICBTY2h3ZXJ0ICA6IDUqQV9ERVggKyA1KkFfU1RSCiAgICAgICBBeHQgICAgICA6IDQqQV9ERVggKyA2KkFfU1RSIAogICAgICAgU3BlZXIgICAgOiA2KkFfREVYICsgNCpBX1NUUgogICAgICAgS2V1bGUgICAgOiAxKkFfREVYICsgOSpBX1NUUgogICAgICAgUGVpdHNjaGUgOiA5KkFfREVYICsgMSpBX1NUUgogICovCgogIHNpbmZvW1NJX1NLSUxMREFNQUdFXSs9dmFsOwoKCiAgLyogTGVybmVuOiBXaXJkIGltbWVyIHNjaHdpZXJpZ2VyLCBudXIgYmVpIGplZGVtIDIwLiBTY2hsYWcgaW0gU2Nobml0dCwKICAgKiB1bmQgbnVyIGRhbm4sIHdlbm4gZGVyIEdlZ25lciBhdWNoIFhQIGdpYnQuICovCiAgaWYgKHJhbmRvbShNQVhfQUJJTElUWSsxKT5zaW5mb1tTSV9TS0lMTEFCSUxJVFldICYmICFyYW5kb20oMTApKQogIHsKICAgICAgICAgZW5lbXk9c2luZm9bU0lfRU5FTVldOwogICAgICAgICBpZiAob2JqZWN0cChlbmVteSkgJiYgKGVuZW15LT5RdWVyeVByb3AoUF9YUCk+MCkpCiAgICAgICAgIHsKICAgICAgICAgICBvYmplY3QgYXVzYmlsZGVyOwogICAgICAgIC8vICAgICAgICAgbG9nX2ZpbGUoImh1bW5pL2xvZ193dXJtIiwiSGF1dDogJXMgdW5kIHp3YXIgJXMsIG1pdCB4cCAlZFxuIixnZXRldWlkKHRoaXNfb2JqZWN0KCkpLHRvX3N0cmluZyhlbmVteSksZW5lbXktPlF1ZXJ5UHJvcChQX1hQKSk7CiAgICAgICAgICAgIExlYXJuU2tpbGwoc25hbWUsIHJhbmRvbSg1KSwgMTUwKTsKICAgICAgICAvLyBHaWJ0IGVzIGVpbmVuIEF1c2JpbGRlcj8KICAgICAgICBpZiAoUXVlcnlQcm9wKFBfV0VBUE9OX1RFQUNIRVIpICYmIAogICAgICAgICAgICAgICAgICAgICAgICBhdXNiaWxkZXI9ZmluZF9wbGF5ZXIoUXVlcnlQcm9wKFBfV0VBUE9OX1RFQUNIRVIpKSkKICAgICAgICAgIHsKICAgICAgICAgICAgLy8gSXN0IGRlciBBdXNiaWxkZXIgYW53ZXNlbmQ/CiAgICAgICAgICAgIGlmIChwcmVzZW50KGF1c2JpbGRlcixlbnZpcm9ubWVudCgpKSkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgLy8gQXVzYmlsZGVyIHVuZCBBenViaSBtdWVzc2VuIGRpZXNlbGJlIFdhZmZlIGhhYmVuLgogICAgICAgICAgICAgIC8vc3RyaW5nIHd0X2F1cyx3dF9henU7CiAgICAgICAgICAgICAgb2JqZWN0IHdhZl9hdXMsd2FmX2F6dTsKCiAgICAgICAgICAgICAgd2FmX2F6dT1RdWVyeVByb3AoUF9XRUFQT04pOwogICAgICAgICAgICAgIHdhZl9hdXM9Y2FsbF9vdGhlcihhdXNiaWxkZXIsIlF1ZXJ5UHJvcCIsUF9XRUFQT04pOwoKICAgICAgICAgICAgICAvL3d0X2F6dT1jYWxsX290aGVyKHdhZl9henUsIlF1ZXJ5UHJvcCIsUF9XRUFQT05fVFlQRSk7CiAgICAgICAgICAgICAgLy93dF9hdXM9Y2FsbF9vdGhlcih3YWZfYXVzLCJRdWVyeVByb3AiLFBfV0VBUE9OX1RZUEUpOwogICAgICAgICAgICAgIC8vaWYgKHd0X2F6dT09d3RfYXVzKQogICAgICAgICAgICAgIGlmIChvYmplY3RwKHdhZl9hdXMpICYmIG9iamVjdHAod2FmX2F6dSkgJiYKICAgICAgICAgICAgICAgICAgKHN0cmluZyl3YWZfYXVzLT5RdWVyeVByb3AoUF9XRUFQT05fVFlQRSkKICAgICAgICAgICAgICAgICAgICAgPT0gKHN0cmluZyl3YWZfYXp1LT5RdWVyeVByb3AoUF9XRUFQT05fVFlQRSkpIAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gQm9udXMgdm9uIGJpcyB6dSA1IFB1bmt0ZW4KICAgICAgICAgICAgICAgIC8vbG9nX2ZpbGUoImh1bW5pL2xvZ19henViaSIsCiAgICAgICAgICAgICAgICAgIC8vIHNwcmludGYoIkF6dWJpICVPIHVuZCBBdXNiaWxkZXIgJU8gOiBXYWZmZW50eXBlbiAlcyB1bmQgJXMsIGdlbGVybnRcbiIsdGhpc19vYmplY3QoKSwKICAgICAgICAgICAgICAgICAgICAvLyAgIGF1c2JpbGRlciwgd3RfYXp1LCB3dF9hdXMpKTsKICAgICAgICAgICAgICAgIExlYXJuU2tpbGwoc25hbWUscmFuZG9tKDYpLDE1MCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogIH0KCiAgLyogCiAgICAgRGllIFNjaHdpZXJpZ2tlaXQgbGllZ3QgYmVpIDE1MCwgc28gZGFzcyAKICAgICBlaW4gTHZsLiAxIFNwaWVsZXIgbWF4aW1hbCAxNSUgU2tpbGwgCiAgICAgdXN3Li4uCiAgICAgbGVybmVuIGthbm4uIChHZW5hdWUgVGFiZWxsZSBpbiAvc3RkL2xpdmluZy9za2lsbHMgYmVpIExpbWl0QWJpbGl0eSkKICAqLyAgICAgICAgIAoKICByZXR1cm4gc2luZm87Cn0KCgovLyBTdGFuZGFyZGlzaWVydGUgRmVybmthbXBmLUZ1bmt0aW9uIGZ1ZXIgYWxsZSBGZXJua2FtcGYtV2FmZmVuYXJ0ZW4KCi8vICoqKiBub2NoIGRlYWt0aXZpZXJ0ICoqKgoKcHJvdGVjdGVkIG1hcHBpbmcgTG9uZ1JhbmdlU2tpbGwob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8sIGludCBkYW0pIAp7IGludCBhYmlsLHZhbDsKCiAgaWYgKCFtYXBwaW5ncChzaW5mbykgfHwgIWRhbSB8fCAhb2JqZWN0cChzaW5mb1tQX1dFQVBPTl0pIHx8CiAgICAgIChzaW5mb1tQX1dFQVBPTl0tPlF1ZXJ5UHJvcChQX1NIT09USU5HX1dDKSk8NSkKICAgIHJldHVybiAwOwoKICBhYmlsPXNpbmZvW1NJX1NLSUxMQUJJTElUWV0rc2luZm9bT0ZGU0VUKFNJX1NLSUxMQUJJTElUWSldOyAKICB2YWw9ZGFtKmFiaWwvTUFYX0FCSUxJVFk7CiAgdmFsPXZhbC8yK3JhbmRvbSh2YWwvMisxKTsKICB2YWw9KHZhbCpRdWVyeVNraWxsQXR0cmlidXRlKFNBX0RBTUFHRSkpLzEwMDsKICBzaW5mb1tTSV9TS0lMTERBTUFHRV0rPXZhbDsKCiAgaWYgKHJhbmRvbShNQVhfQUJJTElUWSsxKT5zaW5mb1tTSV9TS0lMTEFCSUxJVFldICYmIHJhbmRvbSg1MCk9PTQyKQogICAgTGVhcm5Ta2lsbChzbmFtZSwgMSwgMTUwKTsKCiAgcmV0dXJuIHNpbmZvOwp9CgoKCi8vIERpZSBlaW56ZWxuZW4gV2FmZmVuc2tpbGxzIHJ1ZmVuIGRhbm4gbnVyIGRpZSBTdGFuZGFyZC1GdW5rdGlvbiBhdWYuCgpwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9GaWdodF9heGUob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCnsKICByZXR1cm4gU2hvcnRSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8pOwp9Cgpwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9GaWdodF9jbHViKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQp7CiAgcmV0dXJuIFNob3J0UmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvKTsKfQoKcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfa25pZmUob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCnsKICByZXR1cm4gU2hvcnRSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8pOwp9Cgpwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9GaWdodF9zcGVhcihvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKewogIHJldHVybiBTaG9ydFJhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbyk7Cn0KCnByb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X3N3b3JkKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKSAKewogIHJldHVybiBTaG9ydFJhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbyk7Cn0KCnByb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X3doaXAob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCnsKICByZXR1cm4gU2hvcnRSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8pOwp9Cgpwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9GaWdodF9zdGFmZihvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKewogIHJldHVybiBTaG9ydFJhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbyk7Cn0KCgoKCi8vIERpZSBGZXJud2FmZmVuc2tpbGxzIHNpbmQgTXVuaXRpb25zYWJoYWVuZ2lnCgovLyAqKiogbm9jaCBkZWFrdGl2aWVydCAqKioKCnByb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX1Nob290X2Fycm93KG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQp7CiAgcmV0dXJuIExvbmdSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8sIDQwKTsKfQoKcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfU2hvb3RfYm9sdChvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKeyAKICByZXR1cm4gTG9uZ1JhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbywgNDApOwp9Cgpwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9TaG9vdF9kYXJ0KG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQp7CiAgcmV0dXJuIExvbmdSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8sIDIwKTsKfQoKcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfU2hvb3Rfc3RvbmUob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCnsKICByZXR1cm4gTG9uZ1JhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbywgNDApOwp9Cgpwcm90ZWN0ZWQgbWl4ZWQgX3F1ZXJ5X2xvY2FsY21kcygpIHsKICAgIHJldHVybiAoeyAoeyJzcHJ1Y2hlcm11ZWR1bmciLCJlbmFibGVfc3BlbGxfZmF0aWd1ZV9jb21wYXQiLDAsMH0pIH0pOwp9CgoKCi8vICoqKiBLb21wYXRpYmlsaXRhZXRzbW9kdXMgZnVlciBTcGVsbGZhdGlndWVzIChFbXVsYXRpb24gMnMtQWxhcm16ZWl0KSAqKioKCi8qKiBTcGVpY2hlcnQgZWluZSBTcGVsbGZhdGlndWUgdm9uIDxkdXJhdGlvbj4gU2VrdW5kZW4gZnVlciA8a2V5Pi4KICogSXN0IGhpZXIgbnVyIGZ1ZXIgZGVuIFNwZWxsZmF0aWd1ZS1Db21wYXQtbW9kZS4KICogPGtleT4gZGFyZiAwIHNlaW4gdW5kIGJlemVpY2huZXQgZGFzIGdsb2JhbGUgU3BlbGxmYXRpZ3VlLgogKiBSdWVja2dhYmV3ZXJ0OiBBYmxhdWZ6ZWl0IGRlciBnZXNldHp0ZW4gU3BlcnJlCiAgICAgICAgICAgICAgICAgIC0xLCB3ZW5uIG5vY2ggZWluZSBuaWNodC1hYmdlbGF1ZmVuZSBTcGVycmUgYXVmIGRlbSA8a2V5PiBsYWcuCiAgICAgICAgICAgICAgICAgIDAsIHdlbm4gZHVyYXRpb24gMCBpc3QuCiAqLwpwdWJsaWMgdmFyYXJncyBpbnQgU2V0U3BlbGxGYXRpZ3VlKGludCBkdXJhdGlvbiwgc3RyaW5nIGtleSkgewoKICAvLyAwIHNvbGx0ZSBuaWUgZWluZSBTcGVycmUgYmV3aXJrZW4sIGF1Y2ggbmljaHQgaW0gY29tcGF0IG1vZGUuCiAgaWYgKCFkdXJhdGlvbikgcmV0dXJuIDA7CgogIGlmIChzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlKSB7CiAgICAvLyBTcGVsbC1GYXRpZ3VlcyBhdWYgSEJzIHN5bmNocm9uaXNpZXJlbiAoMnMtQWxhcm16ZWl0LUVtdWxhdGlvbikuCiAgICAvLyBBdWZydW5kZW4gYXVmIGdhbnp6YWhsaWdlIFZpZWxmYWNoZSB2b24gX19IRUFSVF9CRUFUX0lOVEVSVkFMX18KICAgIGlmIChkdXJhdGlvbiAlIF9fSEVBUlRfQkVBVF9JTlRFUlZBTF9fKQogICAgICAgICsrZHVyYXRpb247CgogICAgLy8gU3RhcnRwdW5rdCBkZXMgRGVsYXkgc29sbCBCZWdpbm4gZGVyIGFrdHVlbGxlbiBLYW1wZnJ1bmRlIChIQi1aeWtsdXMpCiAgICAvLyBzZWluLCBnZ2YuIHVtIG1heC4gZWluZSBTZWt1bmRlIHp1cnVlY2tkYXRpZXJlbi4KICAgIC8vIChzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlIGhhdCBkaWUgWmVpdCBkZXMgbGV0enRlbiBIQi1BdWZydWZzKQogICAgLy8gRmFsbHMgZHVyY2ggaXJnZW5kZWluIFByb2JsZW0gKHouQi4gc2VociBob2hlIExhc3QpLCBkZXIgbGV0enRlIEhCCiAgICAvLyBsYWVuZ2VyIGFscyAxcyB6dXJ1ZWNrbGllZ3QsIGZ1bmt0aW9uaWVydCBkYXMgbmF0dWVybGljaCBuaWNodCwgYWJlcgogICAgLy8gYmVpIGZhdGlndWUrPXNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGUga2FubiBkZXIgU3BpZWxlciB6dXZpZWwgWmVpdAogICAgLy8gZWluc3BhcmVuLgogICAgaWYgKHRpbWUoKSA+IHNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGUpCiAgICAgICAgLS1kdXJhdGlvbjsgIC8vMXMgenVydWVja2RhdGllcmVuCiAgfQoKICByZXR1cm4gOjpTZXRTcGVsbEZhdGlndWUoZHVyYXRpb24sIGtleSk7Cn0KCi8qKiBCZWZlaGxzZnVua3Rpb24gZnVlciBTcGllbGVyIHVtIGRlbiBTcGVsbGZhdGlndWUtS29tcGF0aWJpbGl0YWV0c21vZHVzCiAqIHVtenVzY2hhbHRlbi4KICovCnB1YmxpYyBpbnQgZW5hYmxlX3NwZWxsX2ZhdGlndWVfY29tcGF0KHN0cmluZyBjbWQpIHsKICBpZiAoUXVlcnlQcm9wKFBfTEFTVF9DT01CQVRfVElNRSkgKyA2MDAgPiB0aW1lKCkpIHsKICAgIHdyaXRlKGJyZWFrX3N0cmluZygKICAgICAgIkltIEthbXBmIG9kZXIga3VyeiBuYWNoIGVpbmVtIEthbXBmIGthbm5zdCBEdSBuaWNodCB6d2lzY2hlbiAiCiAgICAgICJhbHRlciB1bmQgbmV1ZXIgU3BydWNoZXJtdWVkdW5nIHVtc2NoYWx0ZW4uXG4iCiAgICAgICJNb21lbnRhbiBiZW51dHp0IER1IGRpZSAiCiAgICAgICsgKHNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGUgPyAiYWx0ZSAodW5nZW5hdWVyZSkiIDogIm5ldWUgKG5vcm1hbGUpIikKICAgICAgKyAiIFNwcnVjaGVybXVlZHVuZy4iLDc4LDAsQlNfTEVBVkVfTVlfTEZTKSk7CiAgICByZXR1cm4gMTsKICB9CgogIGlmIChjbWQ9PSJhbHQiKSB7CiAgICBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlPXRpbWUoKTsKICAgIHdyaXRlKGJyZWFrX3N0cmluZygKICAgICAgIkFsdGUgU3BydWNoZXJtdWVkdW5nIHd1cmRlIGVpbmdlc2NoYWx0ZXQuIEFsbGUgRXJtdWVkdW5nc3BhdXNlbiAiCiAgICAgICJ6d2lzY2hlbiBTcHJ1ZWNoZW4gd2VyZGVuIGF1ZiBWaWVsZmFjaGUgdm9uIDJzIGF1ZmdlcnVuZGV0IHVuZCAiCiAgICAgICJiZWdpbm5lbiBpbiBkZXIgUmVnZWwgYW0gQW5mYW5nIERlaW5lciBLYW1wZnJ1bmRlLiIpKTsKICAgIHJldHVybiAxOwogIH0KICBlbHNlIGlmIChjbWQ9PSJuZXUiIHx8IGNtZD09Im5vcm1hbCIpIHsKICAgIHNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGU9MDsKICAgIHdyaXRlKGJyZWFrX3N0cmluZygKICAgICAgIk5vcm1hbGUgU3BydWNoZXJtdWVkdW5nIHd1cmRlIGVpbmdlc2NoYWx0ZXQuIEFsbGUgRXJtdWVkdW5nc3BhdXNlbiAiCiAgICAgICJ6d2lzY2hlbiBTcHJ1ZWNoZW4gd2VyZGVuIHNla3VuZGVuZ2VuYXUgYmVyZWNobmV0LiIpKTsKICAgIHJldHVybiAxOwogIH0KCiAgbm90aWZ5X2ZhaWwoYnJlYWtfc3RyaW5nKAogICAgICAiTW9lY2h0ZXN0IER1IGRpZSBhbHRlIG9kZXIgZGllIG5ldWUgU3BydWNoZXJtdWVkdW5nP1xuIgogICAgICAiTW9tZW50YW4gYmVudXR6dCBEdSBkaWUgIgogICAgICArIChzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlID8gImFsdGUgKHVuZ2VuYXVlcmUpIiA6ICJuZXVlIChub3JtYWxlKSIpCiAgICAgICsgIiBTcHJ1Y2hlcm11ZWR1bmcuIiw3OCwwLEJTX0xFQVZFX01ZX0xGUykpOwogIHJldHVybiAwOwp9CgovKiogU3BlaWNoZXJ0IGRpZSBaZWl0IGRlcyBsZXR6dGVzIEhlYXJ0YmVhdHMuCiAqLwpwcm90ZWN0ZWQgdm9pZCBoZWFydF9iZWF0KCkgewogIGlmIChzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlKQogICAgc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSA9IHRpbWUoKTsKfQoKc3RhdGljIGludCBfc2V0X2d1aWxkX2xldmVsKGludCBudW0pCnsgc3RyaW5nIGdpbGRlOwogIG1hcHBpbmcgbGV2ZWxzOwoKICBpZiAoICEoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCiAgICByZXR1cm4gMDsKCiAgaWYgKCAhbWFwcGluZ3AobGV2ZWxzPVF1ZXJ5KFBfR1VJTERfTEVWRUwpKSApCiAgICBsZXZlbHM9KFtdKTsKCiAgbGV2ZWxzW2dpbGRlXT1udW07CiAgU2V0KFBfR1VJTERfTEVWRUwsbGV2ZWxzKTsKICBHTUNQX0NoYXIoIChbUF9HVUlMRF9MRVZFTDogbnVtXSkgKTsKCiAgcmV0dXJuIG51bTsKfQoKc3RhdGljIGludCBfcXVlcnlfZ3VpbGRfbGV2ZWwoKQp7IHN0cmluZyAgZ2lsZGU7CiAgbWFwcGluZyBsZXZlbHM7CgogIGlmICggIShnaWxkZT1RdWVyeVByb3AoUF9HVUlMRCkpICkKICAgIHJldHVybiAwOwoKICBpZiAoICFtYXBwaW5ncChsZXZlbHM9UXVlcnkoUF9HVUlMRF9MRVZFTCkpICkKICAgICAgcmV0dXJuIDA7CgogIHJldHVybiBsZXZlbHNbZ2lsZGVdOwp9CgpzdGF0aWMgc3RyaW5nIF9zZXRfZ3VpbGRfdGl0bGUoc3RyaW5nIHQpCnsgc3RyaW5nIGdpbGRlOwogIG1hcHBpbmcgdGl0bGVzOwoKICBpZiAoICEoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCiAgICByZXR1cm4gMDsKCiAgaWYgKCAhbWFwcGluZ3AodGl0bGVzPVF1ZXJ5KFBfR1VJTERfVElUTEUpKSApCiAgICB0aXRsZXM9KFtdKTsKCiAgdGl0bGVzW2dpbGRlXT10OwogIFNldChQX0dVSUxEX1RJVExFLHRpdGxlcyk7CiAgR01DUF9DaGFyKCAoW1BfR1VJTERfVElUTEU6IHRdKSApOwogIHJldHVybiB0Owp9CgpzdGF0aWMgc3RyaW5nIF9xdWVyeV9ndWlsZF90aXRsZSgpCnsgc3RyaW5nIGdpbGRlLHQ7CiAgb2JqZWN0IGc7CiAgbWFwcGluZyB0aXRsZXM7CgogIGlmICggIShnaWxkZT1RdWVyeVByb3AoUF9HVUlMRCkpICkKICAgIHJldHVybiAwOwoKICBpZiAoICFtYXBwaW5ncCh0aXRsZXM9UXVlcnkoUF9HVUlMRF9USVRMRSkpICkKICAgIHRpdGxlcz0oW10pOwoKICB0PXRpdGxlc1tnaWxkZV07CiAgaWYgKCAhdCAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpCiAgICAgICYmIG9iamVjdHAoZz1maW5kX29iamVjdCgiL2dpbGRlbi8iK2dpbGRlKSkgKQogIHsKICAgIGctPmFkanVzdF90aXRsZSh0aGlzX29iamVjdCgpKTsKICAgIFNldFByb3AoUF9USVRMRSwwKTsKCiAgICBpZiAoICFtYXBwaW5ncCh0aXRsZXM9UXVlcnkoUF9HVUlMRF9USVRMRSkpICkKICAgICAgcmV0dXJuIDA7CgogICAgdD10aXRsZXNbZ2lsZGVdOwogIH0KCiAgcmV0dXJuIHQ7Cn0KCgpzdGF0aWMgc3RyaW5nIF9zZXRfZ3VpbGQoc3RyaW5nIGdpbGRlbm5hbWUpCnsgb2JqZWN0IHByZTsKCiAgaWYgKCFvYmplY3RwKHByZT1wcmV2aW91c19vYmplY3QoKSkpCiAgICByZXR1cm4gMDsKCiAgaWYgKCBwcmUhPXRoaXNfb2JqZWN0KCkgLy8gRGFzIExlYmV3ZXNlbiBzZWxiZXIgZGFyZiBkaWUgR2lsZGUgc2V0emVuLAogICAgICAmJiBvYmplY3RfbmFtZShwcmUpIT1HVUlMRE1BU1RFUiAgLy8gZGVyIEdpbGRlbm1hc3RlciBhdWNoCiAgICAgICYmICghdGhpc19wbGF5ZXIoKQogICAgICAgICAgfHwgdGhpc19wbGF5ZXIoKSAhPSB0aGlzX2ludGVyYWN0aXZlKCkKICAgICAgICAgIHx8ICFJU19BUkNIKHRoaXNfcGxheWVyKCkpCiAgICAgICAgICkKICAgICAgKQogICAgcmV0dXJuIDA7CgogIFNldChQX0dVSUxELGdpbGRlbm5hbWUpOwogIEdNQ1BfQ2hhciggKFtQX0dVSUxEOiBnaWxkZW5uYW1lXSkgKTsKICByZXR1cm4gZ2lsZGVubmFtZTsKfQoKc3RhdGljIHN0cmluZyBfcXVlcnlfZ3VpbGQoKQp7IHN0cmluZyByZXM7CgogIGlmICggIShyZXM9UXVlcnkoUF9HVUlMRCkpICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkgKQogIHsKICAgIC8vIFNwaWVsZXIsIGRpZSBrZWluZXIgR2lsZGUgYW5nZWhvZXJlbiwgZ2Vob2VyZW4genVyIEFiZW50ZXVyZXJnaWxkZQogICAgaWYgKCAhKHJlcz1RdWVyeVByb3AoUF9ERUZBVUxUX0dVSUxEKSkgKQogICAgICByZXR1cm4gREVGQVVMVF9HVUlMRDsKICAgIGVsc2UKICAgICAgU2V0KFBfR1VJTEQscmVzKTsKICAgIHJldHVybiByZXM7CiAgfQoKICByZXR1cm4gcmVzOwp9CgpzdGF0aWMgc3RyaW5nIF9xdWVyeV90aXRsZSgpCnsgc3RyaW5nIHRpOwoKICBpZiAoIHN0cmluZ3AodGk9UXVlcnkoUF9USVRMRSkpICkKICAgIHJldHVybiB0aTsKCiAgcmV0dXJuIFF1ZXJ5UHJvcChQX0dVSUxEX1RJVExFKTsKfQoKc3RhdGljIHN0cmluZyBfc2V0X3RpdGxlKHN0cmluZyB0KQp7CiAgU2V0KFBfVElUTEUsIHQsIEZfVkFMVUUpOwogIEdNQ1BfQ2hhciggKFtQX1RJVExFOiB0XSkgKTsKICByZXR1cm4gdDsKfQoK