LyoKICogTkRBIEFORCBORUVELVRPLUtOT1cgUkVRVUlSRUQKICoKICogQ29weXJpZ2h0IKkgMjAxMy0yMDE4IFN5bmFwdGljcyBJbmNvcnBvcmF0ZWQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFRoaXMgZmlsZSBjb250YWlucyBpbmZvcm1hdGlvbiB0aGF0IGlzIHByb3ByaWV0YXJ5IHRvIFN5bmFwdGljcwogKiBJbmNvcnBvcmF0ZWQgKCJTeW5hcHRpY3MiKS4gVGhlIGhvbGRlciBvZiB0aGlzIGZpbGUgc2hhbGwgdHJlYXQgYWxsCiAqIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gYXMgY29uZmlkZW50aWFsLCBzaGFsbCB1c2UgdGhlCiAqIGluZm9ybWF0aW9uIG9ubHkgZm9yIGl0cyBpbnRlbmRlZCBwdXJwb3NlLCBhbmQgc2hhbGwgbm90IGR1cGxpY2F0ZSwKICogZGlzY2xvc2UsIG9yIGRpc3NlbWluYXRlIGFueSBvZiB0aGlzIGluZm9ybWF0aW9uIGluIGFueSBtYW5uZXIKICogdW5sZXNzIFN5bmFwdGljcyBoYXMgb3RoZXJ3aXNlIHByb3ZpZGVkIGV4cHJlc3MsIHdyaXR0ZW4KICogcGVybWlzc2lvbi4KICoKICogVXNlIG9mIHRoZSBtYXRlcmlhbHMgbWF5IHJlcXVpcmUgYSBsaWNlbnNlIG9mIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiBmcm9tIGEgdGhpcmQgcGFydHkgb3IgZnJvbSBTeW5hcHRpY3MuIFRoaXMgZmlsZSBjb252ZXlzIG5vIGV4cHJlc3MKICogb3IgaW1wbGllZCBsaWNlbnNlcyB0byBhbnkgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBiZWxvbmdpbmcKICogdG8gU3luYXB0aWNzLgogKgogKiBJTkZPUk1BVElPTiBDT05UQUlORUQgSU4gVEhJUyBET0NVTUVOVCBJUyBQUk9WSURFRCAiQVMtSVMsIiBBTkQKICogU1lOQVBUSUNTIEVYUFJFU1NMWSBESVNDTEFJTVMgQUxMIEVYUFJFU1MgQU5EIElNUExJRUQgV0FSUkFOVElFUywKICogSU5DTFVESU5HIEFOWSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwgQU5EIEFOWSBXQVJSQU5USUVTIE9GIE5PTi1JTkZSSU5HRU1FTlQgT0YgQU5ZCiAqIElOVEVMTEVDVFVBTCBQUk9QRVJUWSBSSUdIVFMuIElOIE5PIEVWRU5UIFNIQUxMIFNZTkFQVElDUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBQVU5JVElWRSwgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFCiAqIE9GIFRIRSBJTkZPUk1BVElPTiBDT05UQUlORUQgSU4gVEhJUyBET0NVTUVOVCwgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIEJBU0VEIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwKICogTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFORCBFVkVOIElGIFNZTkFQVElDUyBXQVMKICogQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuIElGIEEgVFJJQlVOQUwgT0YKICogQ09NUEVURU5UIEpVUklTRElDVElPTiBET0VTIE5PVCBQRVJNSVQgVEhFIERJU0NMQUlNRVIgT0YgRElSRUNUCiAqIERBTUFHRVMgT1IgQU5ZIE9USEVSIERBTUFHRVMsIFNZTkFQVElDUycgVE9UQUwgQ1VNVUxBVElWRSBMSUFCSUxJVFkKICogVE8gQU5ZIFBBUlRZIFNIQUxMIE5PVCBFWENFRUQgT05FIEhVTkRSRUQgVS5TLiBET0xMQVJTLgogKi8KI2luY2x1ZGUgImkyY19kcml2ZXIuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAiaW8uaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJtZW1tYXAuaCIKI2luY2x1ZGUgImNoaXBfdm9sdGFnZV9pbmZvLmgiCiNpbmNsdWRlICJTeXNNZ3IuaCIKI2luY2x1ZGUgImFwYlJlZ0Jhc2UuaCIKI2luY2x1ZGUgImxncGxfcHJpbnRmLmgiCgojaW5jbHVkZSAicHZfY29tcC5oIgoKZXh0ZXJuIHZvaWQgZGVsYXlfbXModW5zaWduZWQgaW50IG1zKTsKCiNpZm5kZWYgVk9VVF9DUFVfSUQKI2RlZmluZSBWT1VUX0NQVV9JRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDIpCiNlbmRpZgoKI2lmbmRlZiBWT1VUX0NPUkVfSUQKI2RlZmluZSBWT1VUX0NPUkVfSUQgICAgICAgICAgICAgICAgICAgICgwKQojZW5kaWYKCiNpZm5kZWYgVk9VVF9DUFVfQ0hBTk5FTAojZGVmaW5lIFZPVVRfQ1BVX0NIQU5ORUwgICAgICAgICAgICAgICAgKDApCiNlbmRpZgoKI2lmbmRlZiBWT1VUX0NPUkVfQ0hBTk5FTAojZGVmaW5lIFZPVVRfQ09SRV9DSEFOTkVMICAgICAgICAgICAgICAgKDEpCiNlbmRpZgoKLy8gYWxsIGRlZmluZWQgdW5kZXIgdXYKI2lmbmRlZiBNSU5JTUFMX1ZPTF9TVEVQX1NZODgyNEIKI2RlZmluZSBNSU5JTUFMX1ZPTF9TVEVQX1NZODgyNEIgMTI1MDAKI2VuZGlmCiNkZWZpbmUgTUlOX1ZPTFRBR0UgNzYyNTAwCiNkZWZpbmUgTUFYX1ZPTFRBR0UgMTU1MDAwMAoKI2RlZmluZSBTTEFWRV9BRERSIDB4NjYKI2RlZmluZSBSU1ZEICAgICAgICAgICAgMHhGRkZGRkZGRgojZGVmaW5lIFJFR19WU0VMMCAgICAgICAweDAKCmV4dGVybiB2b2lkIHVkZWxheSh1bnNpZ25lZCBsb25nIHVzZWMpOwpleHRlcm4gaW50IGkyY19tYXN0ZXJfaW5pdChpbnQgaWQsIGludCBzcGVlZCwgaW50IGJfMTBiaXRfYWRkcik7CmV4dGVybiBpbnQgaTJjX21hc3Rlcl93cml0ZV9hbmRfcmVhZChpbnQgaWQsIGludCB0YXJnZXRfYWRkciwgdW5zaWduZWQgY2hhciogc2VuZF9idWZmLCBpbnQgc2VuZF9sZW4sIHVuc2lnbmVkIGNoYXIqIHJlY3ZfYnVmZiwgaW50IHJlY3ZfbGVuKTsKCnN0YXRpYyBpbnQgcG1pY192b2x0MmRhdGEoaW50IHZvbHQsIGludCAqcF9kYXRhKQp7Cgl1bnNpZ25lZCBpbnQgZGF0YTsKCglpZiAoKHZvbHQgPj0gTUlOX1ZPTFRBR0UpICYmICh2b2x0IDw9IE1BWF9WT0xUQUdFKSkKCQlkYXRhID0gKHZvbHQgLSBNSU5fVk9MVEFHRSkgLyAxMjUwMDsKCWVsc2UKCQlkYXRhID0gUlNWRDsKCglpZiAoZGF0YSA9PSBSU1ZEKQoJCXJldHVybiAtMTsKCWVsc2UgewoJCSpwX2RhdGEgPSBkYXRhOwoJCXJldHVybiAwOwoJfQp9CgpzdGF0aWMgaW50IHBtaWNfZGF0YTJ2b2x0KGludCAqcF92b2x0LCBpbnQgdmRhdGEpCnsKCXVuc2lnbmVkIGludCB2b2x0OwoJdW5zaWduZWQgaW50IGRhdGEgPSB2ZGF0YTsKCglkYXRhID0gZGF0YSAmIDB4M0Y7CglpZiAoZGF0YSA8PSAweDNmKQoJCXZvbHQgPSBNSU5fVk9MVEFHRSArIChkYXRhICogMTI1MDApOwoJZWxzZQoJCXZvbHQgPSBSU1ZEOwoKCWlmICh2b2x0ID09IFJTVkQpCgkJcmV0dXJuIC0xOwoJZWxzZSB7CgkJKnBfdm9sdCA9IHZvbHQ7CgkJcmV0dXJuIDA7Cgl9Cn0KCnN0YXRpYyBpbnQgc3k4ODI0Yl9zZXRfdm9sKGludCBtYXN0ZXJfaWQsIGludCBzbGF2ZUFkZHIsIGludCB2b2x0KQp7CglpbnQgdGFyZ2V0ID0gdm9sdDsKCXVuc2lnbmVkIGNoYXIgYnVmZlsyXTsKCXVuc2lnbmVkIGNoYXIgZGF0YV9yZWcwLCBkYXRhOwoJaW50IHZkYXRhID0gMDsKCXVuc2lnbmVkIGludCBidWxrX3JlZzAgPSBSRUdfVlNFTDA7CglpbnQgcmV0ID0gMTsKCgkvLyByZWFkLCBTWTg4MjRiIHNsYXZlIGFkZHJlc3MgaXMgMHg2NgoJaTJjX21hc3Rlcl9pbml0KG1hc3Rlcl9pZCwgMTAwLCAwKTsgIC8vaW50IGlkLCBpbnQgc3BlZWQsIGludCBiXzEwYml0X2FkZHIKCXJldCA9IGkyY19tYXN0ZXJfd3JpdGVfYW5kX3JlYWQobWFzdGVyX2lkLCBzbGF2ZUFkZHIsICh1bnNpZ25lZCBjaGFyKikmYnVsa19yZWcwLCAxLCAodW5zaWduZWQgY2hhciopJmRhdGFfcmVnMCwgMSk7CglpZiAocmV0KSB7CgkJbGdwbF9wcmludGYoIlBNSUMgaTJjIHJlYWQgZmFpbCAhXG4iKTsKCQlyZXR1cm4gcmV0OwoJfQoJZGF0YV9yZWcwID0gZGF0YV9yZWcwICYgMHhjMDsKCglyZXQgPSBwbWljX3ZvbHQyZGF0YSh0YXJnZXQsICZ2ZGF0YSk7CglpZiAocmV0ID09IDApIHsKCQlkYXRhX3JlZzAgPSBkYXRhX3JlZzAgfCAodW5zaWduZWQgY2hhcil2ZGF0YTsKCQkvL2xncGxfcHJpbnRmKCJkYXRhX3JlZzAgPSAweCV4IFxuIiwgZGF0YV9yZWcwKTsKCgkJYnVmZlswXSA9ICh1bnNpZ25lZCBjaGFyKVJFR19WU0VMMDsKCQlidWZmWzFdID0gKHVuc2lnbmVkIGNoYXIpZGF0YV9yZWcwOwoJCS8vaTJjX21hc3Rlcl9pbml0KG1hc3Rlcl9pZCwgMTAwLCAwKTsKCQkvLyB3cml0ZQoJCXJldCA9IGkyY19tYXN0ZXJfd3JpdGVfYW5kX3JlYWQobWFzdGVyX2lkLCBzbGF2ZUFkZHIsIGJ1ZmYsIDIsICh1bnNpZ25lZCBjaGFyKikwLCAwKTsKCQlpZiAocmV0KSB7CgkJCWxncGxfcHJpbnRmKCJQTUlDIGkyYyB3cml0ZSBmYWlsICFcbiIpOwoJCQlyZXR1cm4gcmV0OwoJCX0KCgkJLy9pMmNfbWFzdGVyX2luaXQobWFzdGVyX2lkLCAxMDAsIDApOyAgLy9pbnQgaWQsIGludCBzcGVlZCwgaW50IGJfMTBiaXRfYWRkcgoJCS8vIHJlYWQKCQlidWZmWzBdID0gKHVuc2lnbmVkIGNoYXIpUkVHX1ZTRUwwOwoJCXJldCA9IGkyY19tYXN0ZXJfd3JpdGVfYW5kX3JlYWQobWFzdGVyX2lkLCBzbGF2ZUFkZHIsIGJ1ZmYsIDEsICZkYXRhLCAxKTsKCQlpZiAocmV0KSB7CgkJCWxncGxfcHJpbnRmKCJQTUlDIGkyYyByZWFkIGZhaWwgIVxuIik7CgkJCXJldHVybiByZXQ7CgkJfQoKCQlpZiAoZGF0YV9yZWcwICE9IGRhdGEpIHsKCQkJbGdwbF9wcmludGYoIlBNSUMgc3k4ODI0YjogcmVhZDoweCUwMnggIT0gd3JpdGU6MHglMDJ4XG4iLCBkYXRhLCBkYXRhX3JlZzApOwoJCQlyZXR1cm4gLTE7CgkJfQoJfQoJZWxzZSB7CgkJbGdwbF9wcmludGYoIklsbGVnYWwgdGFyZ2V0IHZvbHRhZ2UgZm9yIFBNSUMgc3k4ODI0YiAhXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IHN5ODgyNGJfZ2V0X3ZvbChpbnQgbWFzdGVyX2lkLCBpbnQgc2xhdmVBZGRyKQp7Cgl1bnNpZ25lZCBjaGFyIHJlYWQgPSAweGZmOwoJaW50IHZvbHQ7Cgl1bnNpZ25lZCBpbnQgYnVsa19yZWcgPSBSRUdfVlNFTDA7CglpbnQgcmV0ID0gMTsKCglpMmNfbWFzdGVyX2luaXQobWFzdGVyX2lkLCAxMDAsIDApOyAgLy9pbnQgaWQsIGludCBzcGVlZCwgaW50IGJfMTBiaXRfYWRkcgoJLy8gcmVhZCwgU1k4ODI0YiBzbGF2ZSBhZGRyZXNzIGlzIDB4NjYKCXJldCA9IGkyY19tYXN0ZXJfd3JpdGVfYW5kX3JlYWQobWFzdGVyX2lkLCBzbGF2ZUFkZHIsICh1bnNpZ25lZCBjaGFyKikmYnVsa19yZWcsIDEsICh1bnNpZ25lZCBjaGFyKikmcmVhZCwgMSk7CgoJLy9sZ3BsX3ByaW50ZigiXG5SRUdfVlNFTDAgPSAweCV4IFxuIiwgcmVhZCk7CgoJcmV0IHw9IHBtaWNfZGF0YTJ2b2x0KCZ2b2x0LCAoaW50KXJlYWQpOwoJaWYocmV0KSB7CgkJbGdwbF9wcmludGYoIiBpMmMgcmVhZCBmYWlsXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CgoJcmV0dXJuIHZvbHQ7Cn0KCnN0YXRpYyBpbnQgaTJjX2dldF9jcHVfdm9sdCh2b2lkKQp7CglpbnQgdm9sdCA9IHN5ODgyNGJfZ2V0X3ZvbChWT1VUX0NQVV9JRCwgU0xBVkVfQUREUik7CgoJaWYodm9sdCA8IDApCgkJcmV0dXJuIDA7CgoJcmV0dXJuIHZvbHQ7Cn0KCnN0YXRpYyBpbnQgaTJjX2dldF9jb3JlX3ZvbHQodm9pZCkKewoJaW50IHZvbHQgPSBzeTg4MjRiX2dldF92b2woVk9VVF9DT1JFX0lELCBTTEFWRV9BRERSKTsKCglpZih2b2x0IDwgMCkKCQlyZXR1cm4gMDsKCglyZXR1cm4gdm9sdDsKfQoKc3RhdGljIGludCBpMmNfc2V0X3ZvbHQoaW50IG1hc3Rlcl9pZCwgaW50IGZyb20sIGludCB0bykKewoJaW50IHZvbHQgPSBmcm9tOwoKCXdoaWxlICh2b2x0ICE9IHRvKXsKCQlpZiAodm9sdCA+IHRvKXsKCQkJdm9sdCAtPSBNSU5JTUFMX1ZPTF9TVEVQX1NZODgyNEI7CgkJCWlmICh2b2x0IDwgdG8pCgkJCQl2b2x0ID0gdG87CgkJfWVsc2V7CgkJCXZvbHQgKz0gTUlOSU1BTF9WT0xfU1RFUF9TWTg4MjRCOwoJCQlpZiAodm9sdCA+IHRvKQoJCQkJdm9sdCA9IHRvOwoJCX0KCgkJaWYoMCAhPSBzeTg4MjRiX3NldF92b2wobWFzdGVyX2lkLCBTTEFWRV9BRERSLCB2b2x0KSkKCQkJcmV0dXJuIDE7CgkJZGVsYXlfbXMoMTApOwkvL2RlbGF5IGZvciB2b2x0YWdlIHRvIGJlY29tZSBzdGFibGUKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBpMmNfc2V0X3ZjcHVfdm9sdChpbnQgZnJvbSwgaW50IHRvKQp7CglyZXR1cm4gaTJjX3NldF92b2x0KFZPVVRfQ1BVX0lELCBmcm9tICx0byk7Cn0KCnN0YXRpYyBpbnQgaTJjX3NldF92Y29yZV92b2x0KGludCBmcm9tLCBpbnQgdG8pCnsKCXJldHVybiBpMmNfc2V0X3ZvbHQoVk9VVF9DT1JFX0lELCBmcm9tICx0byk7Cn0KCmNvbnN0IGR2ZnNfb3BzX3Qgc3k4ODI0Yl9vcHMgPSB7CgkuZ2V0X3ZjcHVfdm9sdCA9IGkyY19nZXRfY3B1X3ZvbHQsCgkuZ2V0X3Zjb3JlX3ZvbHQgPSBpMmNfZ2V0X2NvcmVfdm9sdCwKCS5zZXRfdmNwdV92b2x0ID0gaTJjX3NldF92Y3B1X3ZvbHQsCgkuc2V0X3Zjb3JlX3ZvbHQgPWkyY19zZXRfdmNvcmVfdm9sdAp9Owo=