Ly8gQ29weXJpZ2h0IDIwMTQgUERGaXVtIEF1dGhvcnMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCi8vIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGEgQlNELXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmUKLy8gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZS4KIAovLyBPcmlnaW5hbCBjb2RlIGNvcHlyaWdodCAyMDE0IEZveGl0IFNvZnR3YXJlIEluYy4gaHR0cDovL3d3dy5mb3hpdHNvZnR3YXJlLmNvbQoKI2lmbmRlZiBfSlNfQ09OU09MRV9IXwojZGVmaW5lIF9KU19DT05TT0xFX0hfCgojaW5jbHVkZSAiLi4vcmVzL3Jlc291cmNlLmgiCgojZGVmaW5lIFdTVF9OT05FCQkweDAwCQkJCQkvLyBObyBzaXplIGNoYW5nZWQKI2RlZmluZSBXU1RfTEVGVAkJMHgwMQkJCQkJLy8gc2l6ZSB0byBsZWZ0CiNkZWZpbmUgV1NUX1RPUAkJCTB4MDIJCQkJCS8vIHNpemUgdG8gdG9wCiNkZWZpbmUgV1NUX1JJR0hUCQkweDA0CQkJCQkvLyBzaXplIHRvIHJpZ2h0CiNkZWZpbmUgV1NUX0JPVFRPTQkJMHgwOAkJCQkJLy8gc2l6ZSB0byBib3R0b20KI2RlZmluZSBXU1RfVE9QTEVGVAkJKFdTVF9UT1B8V1NUX0xFRlQpCQkvLyBzaXplIHRvIHRvcCAmIGxlZnQKI2RlZmluZSBXU1RfVE9QUklHSFQJKFdTVF9UT1B8V1NUX1JJR0hUKQkJLy8gc2l6ZSB0byB0b3AgJiByaWdodAojZGVmaW5lIFdTVF9CT1RUT01SSUdIVAkoV1NUX0JPVFRPTXxXU1RfUklHSFQpCS8vIHNpemUgdG8gYm90dG9tICYgcmlnaHQKI2RlZmluZSBXU1RfQk9UVE9NTEVGVAkoV1NUX0JPVFRPTXxXU1RfTEVGVCkJLy8gc2l6ZSB0byBib3R0b20gJiByaWdodAoKI2lmbmRlZiBJRENfRExHU0laRUJPWAojZGVmaW5lIElEQ19ETEdTSVpFQk9YICA1MAojZW5kaWYJLyogSURDX0RMR1NJWkVCT1ggKi8KCmVudW0geyBtX2lkU2l6ZUljb24gPSBJRENfRExHU0laRUJPWCB9OwplbnVtIHsJCQkJLy8gcG9zc2libGUgQ29udHJvbCByZVNpemUgVHlwZQoJQ1NUX05PTkUgPSAwLAoJQ1NUX1JFU0laRSwJCS8vIE5PTU9WRSArIFNJWkUsIGFkZCBhbGwgZGVsdGEtc2l6ZSBvZiBkbGcgdG8gY29udHJvbAoJQ1NUX1JFUE9TLAkJLy8gTU9WRShhYnNvbHV0ZWx5KSArIE5PU0laRSwgbW92ZSBjb250cm9sJ3MgcG9zIGJ5IGRlbHRhLXNpemUKCUNTVF9SRUxBVElWRSwJLy8gTU9WRShwcm9wb3J0aW9uYWwpICArIE5PU0laRSwga2VlcCBjb250cm9sIGFsd2F5cyBhdCBhIHJlbGF0aXZlIHBvcwoJQ1NUX1pPT00sCQkvLyBNT1ZFICsgU0laRSAoYm90aCBhcmUgYXV0b21hdGljYWxseSBwcm9wb3J0aW9uYWwpCglDU1RfREVMVEFfWk9PTQkvLyBNT1ZFKHByb3BvcnRpb25hbCwgc2V0IG1hbnVhbGx5KSArIFNJWkUocHJvcG9ydGlvbmFsLCBzZXQgbWFudWFsbCkKfTsKCi8vIGNvbnRhaW5lZCBjbGFzcyB0byBob2xkIGl0ZW0gc3RhdGUKLy8KY2xhc3MgQ0pTX0l0ZW1DdHJsCnsKcHVibGljOgoJVUlOVAltX25JRDsKCVVJTlQJbV9zdHhMZWZ0ICAJICAgOiA0OwkJCS8vIHdoZW4gbGVmdCByZXNpemluZyAuLi4KCVVJTlQJbV9zdHhSaWdodCAgICAgOiA0OwkJCS8vIHdoZW4gcmlnaHQgcmVzaXppbmcgLi4uCglVSU5UCW1fc3R5VG9wICAgCSAgIDogNDsJCQkvLyB3aGVuIHRvcCByZXNpemluZyAuLi4KCVVJTlQJbV9zdHlCb3R0b20gICAgOiA0OwkJCS8vIHdoZW4gYm90dG9tIHJlc2l6aW5nIC4uLgoJVUlOVAltX2JGbGlja2VyRnJlZSA6IDE7CglVSU5UCW1fYkludmFsaWRhdGUgIDogMTsJCQkvLyBJbnZhbGlkYXRlIGN0cmwncyByZWN0KGVnLiBuby1hdXRvbWF0aWNhbCB1cGRhdGUgZm9yIHN0YXRpYyB3aGVuIHJlc2l6ZSttb3ZlKQoJVUlOVAltX3IwCQkgICA6IDE0OwoJQ1JlY3QJbV93UmVjdDsKCWRvdWJsZQltX3hSYXRpbywgbV9jeFJhdGlvOwoJZG91YmxlCW1feVJhdGlvLCBtX2N5UmF0aW87Cgpwcm90ZWN0ZWQ6Cgl2b2lkIEFzc2lnbihjb25zdCBDSlNfSXRlbUN0cmwmIHNyYyk7CgpwdWJsaWM6CglDSlNfSXRlbUN0cmwoKTsKCUNKU19JdGVtQ3RybChjb25zdCBDSlNfSXRlbUN0cmwmIHNyYyk7CgoJSERXUCBPblNpemUoSERXUCBoZHdwLCBpbnQgc2l6ZVR5cGUsIENSZWN0ICpwbkNsdFJlY3QsIENSZWN0ICpwb0NsdFJlY3QsIENSZWN0ICpwUjAsIENXbmQgKnBEbGcpOwoKCUNKU19JdGVtQ3RybCYgb3BlcmF0b3I9KGNvbnN0IENKU19JdGVtQ3RybCYgc3JjKTsKfTsKCmNsYXNzIENKU19SZXNpemVEbGcgOiBwdWJsaWMgQ0RpYWxvZwp7Ci8vCURFQ0xBUkVfRFlOQU1JQyhDSlNfUmVzaXplRGxnKQpwdWJsaWM6CglDSlNfUmVzaXplRGxnKFVJTlQgbklELENXbmQgKnBQYXJlbnRXbmQgPSBOVUxMKTsKCXZpcnR1YWwgfkNKU19SZXNpemVEbGcoKTsKCgpwdWJsaWM6CglzdGQ6OnZlY3RvcjxDSlNfSXRlbUN0cmw+CW1fSXRlbXM7ICAgICAgICAgICAvLyBhcnJheSBvZiBjb250cm9sbGVkIGl0ZW1zCglDUmVjdAkJCQkJbV9jbHRSZWN0LCBtX2NsdFIwOwoJaW50CQkJCQkJbV94TWluLCBtX3lNaW47CglpbnQJCQkJCQltX3hTdCwgIG1feVN0OwkJLy9zdGVwPwoJVUlOVAkJCQkJbV9uRGVsYXlTaWRlOwkJLy9kcmFnIHNpZGUgb2Ygd2luZG93CglDU3RhdGljCQkJCQltX3duZFNpemVJY29uOyAgICAgLy8gc2l6ZSBpY29uIHdpbmRvdwoKcHJvdGVjdGVkOgoJdm9pZCAJCQkJCUFkZENvbnRyb2woIFVJTlQgbklELCBpbnQgeGwsIGludCB4ciwgaW50IHl0LCBpbnQgeWIsIGludCBiRmxpY2tlckZyZWUgPSAwLCAKCQkJCQkJCQkJICAgIGRvdWJsZSB4UmF0aW8gPSAtMS4wLCBkb3VibGUgY3hSYXRpbyA9IC0xLjAsCgkJCQkJCQkJCSAgICBkb3VibGUgeVJhdGlvID0gLTEuMCwgZG91YmxlIGN5UmF0aW8gPSAtMS4wICk7Cgl2b2lkIAkJCQkJQWxsb3dTaXppbmcoaW50IHhzdCwgaW50IHlzdCk7Cgl2b2lkIAkJCQkJSGlkZVNpemVJY29uKHZvaWQpOwkKCXZpcnR1YWwgQk9PTAkJCU9uSW5pdERpYWxvZygpOwoKCXZvaWQJCQkJCU9uU2l6aW5nKFVJTlQgblNpZGUsIExQUkVDVCBscFJlY3QpOwoJdm9pZAkJCQkJT25TaXplKFVJTlQgblR5cGUsIGludCBjeCwgaW50IGN5KTsKCXZvaWQJCQkJCU9uR2V0TWluTWF4SW5mbyhNSU5NQVhJTkZPICpwbW1pKTsKCUJPT0wJCQkJCU9uRXJhc2VCa2duZChDREMqIHBEQyk7CgpwdWJsaWM6CglpbnQJCQkJCQlVcGRhdGVDb250cm9sUmVjdChVSU5UIG5JRCwgQ1JlY3QgKnBucik7Cn07CgoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1DSWNvbkxpc3RCb3ggZm9yIENXbmRFbGVtZW50TGlzdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmNsYXNzIENJY29uTGlzdEJveCA6IHB1YmxpYyBDTGlzdEJveAp7CnB1YmxpYzoKCUNJY29uTGlzdEJveCgpOwoJdmlydHVhbCB+Q0ljb25MaXN0Qm94KCk7CgpwdWJsaWM6CglpbnQJCQkJSW5zZXJ0U3RyaW5nKGludCBuSW5kZXgsIExQQ1dTVFIgbHBzekl0ZW0gLCBpbnQgbkltYWdlKTsKCXZpcnR1YWwJdm9pZAlSZXNldENvbnRlbnQoKTsKCXZpcnR1YWwgdm9pZAlHZXRUZXh0KGludCBuSW5kZXgsIENTdHJpbmcmIHJTdHJpbmcpOwoKCXZpcnR1YWwgdm9pZAlEcmF3SXRlbShMUERSQVdJVEVNU1RSVUNUIGxwRHJhd0l0ZW1TdHJ1Y3QpOwoJdm9pZAkJCU1lYXN1cmVJdGVtKExQTUVBU1VSRUlURU1TVFJVQ1QgbHBNZWFzdXJlSXRlbVN0cnVjdCk7CglpbnQJCQkJQ29tcGFyZUl0ZW0oTFBDT01QQVJFSVRFTVNUUlVDVCBscENvbXBhcmVJdGVtU3RydWN0KTsKCnByb3RlY3RlZDoKCS8vIEdlbmVyYXRlZCBtZXNzYWdlIG1hcCBmdW5jdGlvbnMKCS8ve3tBRlhfTVNHKENJY29uTGlzdEJveCkKCWFmeF9tc2cgdm9pZCBPbk1vdXNlTW92ZShVSU5UIG5GbGFncywgQ1BvaW50IHBvaW50KTsKCS8vfX1BRlhfTVNHCQoJREVDTEFSRV9NRVNTQUdFX01BUCgpCgpwcm90ZWN0ZWQ6CglzdHJ1Y3QgSXRlbURhdGFzIAoJewoJCUNTdHJpbmcJY3NUZXh0OwoJCWludAkJbkltYWdlOwoJfTsKfTsKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tQ1duZEVsZW1lbnRMaXN0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KI2RlZmluZSBJRENfTElTVF9KU19FTEVNRU5UIDEwMDcwCgojZGVmaW5lIEVMRU1FTlRfTElTVF9XSURUSCAxNDAKI2RlZmluZSBFTEVNRU5UX0xJU1RfSEVJR0hUIDE4MAojZGVmaW5lIEVMRU1FTlRfTElTVF9UT1BfT0ZGU0VUIDEzCgojZGVmaW5lIEVMRU1FTlRfVFlQRV9OQU1FCTAKI2RlZmluZSBFTEVNRU5UX1RZUEVfQ09OU1QJMQojZGVmaW5lIEVMRU1FTlRfVFlQRV9GVU4JMgojZGVmaW5lIEVMRU1FTlRfVFlQRV9QUk8JMwoKY2xhc3MgQ1duZEVsZW1lbnRMaXN0IDogcHVibGljIENXbmQKewpwdWJsaWM6CglDV25kRWxlbWVudExpc3QoKTsKCXZpcnR1YWwgfkNXbmRFbGVtZW50TGlzdCgpOwoJCnB1YmxpYzoKCXZpcnR1YWwgdm9pZAlPblNpemUoVUlOVCBuVHlwZSwgaW50IGN4LCBpbnQgY3kpOwoJdmlydHVhbCBCT09MCUNyZWF0ZShDV25kKiBwUGFyZW50V25kKTsKCXZpcnR1YWwgQk9PTAlTaG93V2luZG93KGludCBuQ21kU2hvdyk7Cgl2b2lkCQkJUmVtb3ZlQWxsRWxlbWVudCgpOwoJdm9pZAkJCVNldEVsZW1lbnRMaXN0KExQQ1dTVFIqIHBFbGVtZW50LCBpbnQqIHBUeXBlICwgIGludCBpQ291bnQpOwoJdm9pZAkJCUFkZEVsZW1lbnQoQ0ZYX1dpZGVTdHJpbmcgY3NWYWx1ZSAsIGludCBuVHlwZSk7CglCT09MCQkJR2V0RWxlbWVudFNlbChDU3RyaW5nICZjc0VsZW1lbnQpOwoJQk9PTAkJCVNlbGVjdE5leHQoKTsKCUJPT0wJCQlTZWxlY3RQcmV2aW91cygpOwoJQk9PTAkJCVNlbGVjdEZpcnN0KCk7CglCT09MCQkJU2VsZWN0TGFzdCgpOwoJQk9PTAkJCVNlbGVjdE5leHRQYWdlKCk7CglCT09MCQkJU2VsZWN0UHJldmlvdXNQYWdlKCk7CglpbnQJCQkJR2V0TGlzdEhlaWdodCgpOwoJCnByb3RlY3RlZDoKCS8vIEdlbmVyYXRlZCBtZXNzYWdlIG1hcCBmdW5jdGlvbnMKCS8ve3tBRlhfTVNHKENXbmRFbGVtZW50TGlzdCkKCWFmeF9tc2cgdm9pZCBPblBhaW50KCk7CglhZnhfbXNnIEJPT0wgT25OY0FjdGl2YXRlKEJPT0wgYkFjdGl2ZSk7CglhZnhfbXNnIHZvaWQgT25TZWxKU0VsZW1lbnQoKTsKCWFmeF9tc2cgdm9pZCBPbkRibGNsa0pTRWxlbWVudCgpOwoJYWZ4X21zZyB2b2lkIE9uRGVzdHJveSgpOwoJLy99fUFGWF9NU0cJCglERUNMQVJFX01FU1NBR0VfTUFQKCkKcHJvdGVjdGVkOgoJQ0ljb25MaXN0Qm94CW1fTGlzdEJveDsKCUJPT0wJCQltX2JCbG9jazsKfTsKCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCi8vIENKU19Db25zb2xlRGxnILbUu7C/8gpjbGFzcyBDSlNfQ29uc29sZURsZyA6IHB1YmxpYyBDSlNfUmVzaXplRGxnCnsKCURFQ0xBUkVfRFlOQU1JQyhDSlNfQ29uc29sZURsZykKCnB1YmxpYzoKCUNKU19Db25zb2xlRGxnKENSZWFkZXJfQXBwKiBwQXBwLCBDV25kKiBwUGFyZW50KTsJCgl2aXJ0dWFsIH5DSlNfQ29uc29sZURsZygpOwoKCWVudW0geyBJREQgPSBJRERfSlNfQ09OU09MRSB9OwoKCXZvaWQJCQkJQ3JlYXRlKCk7CgoJdm9pZAkJCQlBcHBlbmRDb25zb2xlVGV4dChjb25zdCBDRlhfV2lkZVN0cmluZyYgc3dUZXh0KTsKCXZvaWQJCQkJU2V0Q29uc29sZVRleHQoY29uc3QgQ0ZYX1dpZGVTdHJpbmcmIHN3VGV4dCk7CglDRlhfV2lkZVN0cmluZwkJR2V0Q29uc29sZVRleHQoKSBjb25zdDsKCUNGWF9XaWRlU3RyaW5nCQlHZXRTY3JpcHRUZXh0KCkgY29uc3Q7CgoJQk9PTAkJCQlSZXNldEVsZW1lbnRMaXN0KExQQ1dTVFIgbHBzdHJSZWYpOwoJSUZYSlNfUnVudGltZSoJCUdldEpTUnVudGltZSgpOwoKcHJvdGVjdGVkOgoJdmlydHVhbCB2b2lkCQlEb0RhdGFFeGNoYW5nZShDRGF0YUV4Y2hhbmdlKiBwRFgpOwkvLyBERFgvRERWINans9YKCnByb3RlY3RlZDoKCXZpcnR1YWwgQk9PTAkJT25Jbml0RGlhbG9nKCk7CQoJdmlydHVhbCB2b2lkCQlPbkNhbmNlbCgpOwoKCXZpcnR1YWwgQk9PTAkJUHJlVHJhbnNsYXRlTWVzc2FnZShNU0cqIHBNc2cpOwoKcHJvdGVjdGVkOgoJLy8gR2VuZXJhdGVkIG1lc3NhZ2UgbWFwIGZ1bmN0aW9ucwoJLy97e0FGWF9NU0coQ0pTX0NvbnNvbGVEbGcpCglhZnhfbXNnIHZvaWQgT25CbkNsaWNrZWRDbGVhcigpOwoJYWZ4X21zZyB2b2lkIE9uQm5DbGlja2VkT2soKTsKCWFmeF9tc2cgdm9pZCBPbkJuQ2xpY2tUaXBzKCk7CglhZnhfbXNnIHZvaWQgT25TaXppbmcoVUlOVCBuU2lkZSwgTFBSRUNUIGxwUmVjdCk7CglhZnhfbXNnIHZvaWQgT25TaXplKFVJTlQgblR5cGUsIGludCBjeCwgaW50IGN5KTsKCWFmeF9tc2cgdm9pZCBPbkdldE1pbk1heEluZm8oTUlOTUFYSU5GTyAqcG1taSk7CglhZnhfbXNnIEJPT0wgT25FcmFzZUJrZ25kKENEQyogcERDKTsKCWFmeF9tc2cgdm9pZCBPblNob3dXaW5kb3coQk9PTCBiU2hvdywgVUlOVCBuU3RhdHVzKTsKCglhZnhfbXNnIHZvaWQgT25MQnV0dG9uRG93bihVSU5UIG5GbGFncywgQ1BvaW50IHBvaW50KTsKCWFmeF9tc2cgdm9pZCBPbkNoYW5nZVNjcmlwdEVkaXQoV1BBUkFNIHdQYXJhbSAsIExQQVJBTSBsUGFyYW0pOwoJYWZ4X21zZyB2b2lkIE9uTW92ZShpbnQgeCAsIGludCB5KTsKCXB1YmxpYzoKCXZpcnR1YWwgaW50CURvTW9kYWwoKTsJCgkvL319QUZYX01TRwoJREVDTEFSRV9NRVNTQUdFX01BUCgpCgpwdWJsaWM6CglDR1dfTGluZU51bWJlckVkaXQJCQltX2VkdFNDOwoJQk9PTAkJCQkJCW1fYlRpcHM7Cgljb25zdCBVSU5UCQkJCQltX3VUZXh0bGltaXRlZDsKCUZYX0hHTE9CQUwJCQkJCW1faEdsb2JhbDsKCUNSZWFkZXJfQXBwICoJCQkJbV9wQXBwOwoJQ1duZEVsZW1lbnRMaXN0CQkJCW1fV25kRWxlbWVudExpc3Q7Cn07CgojZW5kaWYgLy9fSlNfQ09OU09MRV9IXw==