LyoKICogTkRBIEFORCBORUVELVRPLUtOT1cgUkVRVUlSRUQKICoKICogQ29weXJpZ2h0IKkgMjAxMy0yMDE4IFN5bmFwdGljcyBJbmNvcnBvcmF0ZWQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFRoaXMgZmlsZSBjb250YWlucyBpbmZvcm1hdGlvbiB0aGF0IGlzIHByb3ByaWV0YXJ5IHRvIFN5bmFwdGljcwogKiBJbmNvcnBvcmF0ZWQgKCJTeW5hcHRpY3MiKS4gVGhlIGhvbGRlciBvZiB0aGlzIGZpbGUgc2hhbGwgdHJlYXQgYWxsCiAqIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gYXMgY29uZmlkZW50aWFsLCBzaGFsbCB1c2UgdGhlCiAqIGluZm9ybWF0aW9uIG9ubHkgZm9yIGl0cyBpbnRlbmRlZCBwdXJwb3NlLCBhbmQgc2hhbGwgbm90IGR1cGxpY2F0ZSwKICogZGlzY2xvc2UsIG9yIGRpc3NlbWluYXRlIGFueSBvZiB0aGlzIGluZm9ybWF0aW9uIGluIGFueSBtYW5uZXIKICogdW5sZXNzIFN5bmFwdGljcyBoYXMgb3RoZXJ3aXNlIHByb3ZpZGVkIGV4cHJlc3MsIHdyaXR0ZW4KICogcGVybWlzc2lvbi4KICoKICogVXNlIG9mIHRoZSBtYXRlcmlhbHMgbWF5IHJlcXVpcmUgYSBsaWNlbnNlIG9mIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiBmcm9tIGEgdGhpcmQgcGFydHkgb3IgZnJvbSBTeW5hcHRpY3MuIFRoaXMgZmlsZSBjb252ZXlzIG5vIGV4cHJlc3MKICogb3IgaW1wbGllZCBsaWNlbnNlcyB0byBhbnkgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBiZWxvbmdpbmcKICogdG8gU3luYXB0aWNzLgogKgogKiBJTkZPUk1BVElPTiBDT05UQUlORUQgSU4gVEhJUyBET0NVTUVOVCBJUyBQUk9WSURFRCAiQVMtSVMsIiBBTkQKICogU1lOQVBUSUNTIEVYUFJFU1NMWSBESVNDTEFJTVMgQUxMIEVYUFJFU1MgQU5EIElNUExJRUQgV0FSUkFOVElFUywKICogSU5DTFVESU5HIEFOWSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwgQU5EIEFOWSBXQVJSQU5USUVTIE9GIE5PTi1JTkZSSU5HRU1FTlQgT0YgQU5ZCiAqIElOVEVMTEVDVFVBTCBQUk9QRVJUWSBSSUdIVFMuIElOIE5PIEVWRU5UIFNIQUxMIFNZTkFQVElDUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBQVU5JVElWRSwgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFCiAqIE9GIFRIRSBJTkZPUk1BVElPTiBDT05UQUlORUQgSU4gVEhJUyBET0NVTUVOVCwgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIEJBU0VEIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwKICogTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFORCBFVkVOIElGIFNZTkFQVElDUyBXQVMKICogQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuIElGIEEgVFJJQlVOQUwgT0YKICogQ09NUEVURU5UIEpVUklTRElDVElPTiBET0VTIE5PVCBQRVJNSVQgVEhFIERJU0NMQUlNRVIgT0YgRElSRUNUCiAqIERBTUFHRVMgT1IgQU5ZIE9USEVSIERBTUFHRVMsIFNZTkFQVElDUycgVE9UQUwgQ1VNVUxBVElWRSBMSUFCSUxJVFkKICogVE8gQU5ZIFBBUlRZIFNIQUxMIE5PVCBFWENFRUQgT05FIEhVTkRSRUQgVS5TLiBET0xMQVJTLgogKi8KI2luY2x1ZGUgImkyY19kcml2ZXIuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAiaW8uaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJtZW1tYXAuaCIKI2luY2x1ZGUgImNoaXBfdm9sdGFnZV9pbmZvLmgiCiNpbmNsdWRlICJTeXNNZ3IuaCIKI2luY2x1ZGUgImFwYlJlZ0Jhc2UuaCIKI2luY2x1ZGUgImFwYl90aW1lci5oIgojaW5jbHVkZSAibGdwbF9wcmludGYuaCIKCiNpbmNsdWRlICJwdl9jb21wLmgiCgpleHRlcm4gdm9pZCBkZWxheV9tcyh1bnNpZ25lZCBpbnQgbXMpOwoKI2lmbmRlZiBWT1VUX0NQVV9JRAojZGVmaW5lIFZPVVRfQ1BVX0lEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMikKI2VuZGlmCgojaWZuZGVmIFZPVVRfQ09SRV9JRAojZGVmaW5lIFZPVVRfQ09SRV9JRCAgICAgICAgICAgICAgICAgICAgKDApCiNlbmRpZgoKI2lmbmRlZiBWT1VUX0NQVV9DSEFOTkVMCiNkZWZpbmUgVk9VVF9DUFVfQ0hBTk5FTCAgICAgICAgICAgICAgICAoMCkKI2VuZGlmCgojaWZuZGVmIFZPVVRfQ09SRV9DSEFOTkVMCiNkZWZpbmUgVk9VVF9DT1JFX0NIQU5ORUwgICAgICAgICAgICAgICAoMSkKI2VuZGlmCgovLyBhbGwgZGVmaW5lZCB1bmRlciB1dgojaWZuZGVmIE1JTklNQUxfVk9MX1NURVBfU1kyMDI3NgojZGVmaW5lIE1JTklNQUxfVk9MX1NURVBfU1kyMDI3NiAxMDAwMAojZW5kaWYKI2RlZmluZSBNSU5fVk9MVEFHRSA2MDAwMDAKI2RlZmluZSBNQVhfVk9MVEFHRSAxNTAwMDAwCgojZGVmaW5lIFNMQVZFX0FERFIgMHg2MAojZGVmaW5lIFJTVkQgICAgICAgICAgICAweEZGRkZGRkZGCiNkZWZpbmUgUkVHX1ZTRUwwICAgICAgIDB4MAoKZXh0ZXJuIHZvaWQgdWRlbGF5KHVuc2lnbmVkIGxvbmcgdXNlYyk7CmV4dGVybiBpbnQgaTJjX21hc3Rlcl9pbml0KGludCBpZCwgaW50IHNwZWVkLCBpbnQgYl8xMGJpdF9hZGRyKTsKZXh0ZXJuIGludCBpMmNfbWFzdGVyX3dyaXRlX2FuZF9yZWFkKGludCBpZCwgaW50IHRhcmdldF9hZGRyLCB1bnNpZ25lZCBjaGFyKiBzZW5kX2J1ZmYsIGludCBzZW5kX2xlbiwgdW5zaWduZWQgY2hhciogcmVjdl9idWZmLCBpbnQgcmVjdl9sZW4pOwoKc3RhdGljIGludCBwbWljX3ZvbHQyZGF0YShpbnQgdm9sdCwgaW50ICpwX2RhdGEpCnsKCXVuc2lnbmVkIGludCBkYXRhOwoKCWlmICgodm9sdCA+PSBNSU5fVk9MVEFHRSkgJiYgKHZvbHQgPD0gTUFYX1ZPTFRBR0UpKQoJCWRhdGEgPSAodm9sdCAtIE1JTl9WT0xUQUdFKSAvIDEwMDAwOwoJZWxzZQoJCWRhdGEgPSBSU1ZEOwoKCWlmIChkYXRhID09IFJTVkQpCgkJcmV0dXJuIC0xOwoJZWxzZSB7CgkJKnBfZGF0YSA9IGRhdGE7CgkJcmV0dXJuIDA7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcG1pY19kYXRhMnZvbHQoaW50ICpwX3ZvbHQsIGludCB2ZGF0YSkKewoJdW5zaWduZWQgaW50IHZvbDsKCWludCBkYXRhID0gdmRhdGE7CgoJZGF0YSA9IGRhdGEgJiAweDdGOwoJaWYgKGRhdGEgPD0gMHg3ZiAmJiAweDVhIDw9IGRhdGEpCgkJdm9sID0gTUFYX1ZPTFRBR0U7CgllbHNlIGlmIChkYXRhIDwgMHg1YSkKCQl2b2wgPSBNSU5fVk9MVEFHRSArIGRhdGEgKiAxMDAwMDsKCWVsc2UKCQl2b2wgPSBSU1ZEOwoKCWlmICh2b2wgPT0gUlNWRCkKCQlyZXR1cm4gLTE7CgllbHNlIHsKCQkqcF92b2x0ID0gdm9sOwoJCXJldHVybiAwOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHN5MjAyNzZfc2V0X3ZvbChpbnQgbWFzdGVyX2lkLCBpbnQgc2xhdmVBZGRyLCBpbnQgdm9sdCkKewoJaW50IHRhcmdldCA9IHZvbHQsIHZkYXRhID0gMDsKCXVuc2lnbmVkIGNoYXIgYnVmZlsyXTsKCXVuc2lnbmVkIGNoYXIgZGF0YV9yZWcwLCBkYXRhOwoJdW5zaWduZWQgaW50IGJ1bGtfcmVnMCA9IFJFR19WU0VMMDsKCWludCByZXQgPSAxOwoKCS8vIHJlYWQsIFNZMjAyNzZiIHNsYXZlIGFkZHJlc3MgaXMgMHg2MAoJaTJjX21hc3Rlcl9pbml0KG1hc3Rlcl9pZCwgMTAwLCAwKTsgIC8vaW50IGlkLCBpbnQgc3BlZWQsIGludCBiXzEwYml0X2FkZHIKCXJldCA9IGkyY19tYXN0ZXJfd3JpdGVfYW5kX3JlYWQobWFzdGVyX2lkLCBzbGF2ZUFkZHIsICh1bnNpZ25lZCBjaGFyKikmYnVsa19yZWcwLCAxLCAodW5zaWduZWQgY2hhciopJmRhdGFfcmVnMCwgMSk7CglpZiAocmV0KQoJewoJCWxncGxfcHJpbnRmKCJQTUlDIGkyYyByZWFkIGZhaWwgIVxuIik7CgkJcmV0dXJuIHJldDsKCX0KCWRhdGFfcmVnMCA9IGRhdGFfcmVnMCAmIDB4ODA7CgoJcmV0ID0gcG1pY192b2x0MmRhdGEodGFyZ2V0LCAmdmRhdGEpOwoJaWYgKHJldCA9PSAwKSB7CgkJZGF0YV9yZWcwID0gZGF0YV9yZWcwIHwgKHVuc2lnbmVkIGNoYXIpdmRhdGE7CgkJbGdwbF9wcmludGYoICJkYXRhX3JlZzAgPSAweCV4IFxuIiwgZGF0YV9yZWcwKTsKCgkJYnVmZlswXSA9ICh1bnNpZ25lZCBjaGFyKVJFR19WU0VMMDsKCQlidWZmWzFdID0gKHVuc2lnbmVkIGNoYXIpZGF0YV9yZWcwOwoJCS8vaTJjX21hc3Rlcl9pbml0KG1hc3Rlcl9pZCwgMTAwLCAwKTsKCQkvLyB3cml0ZQoJCXJldCA9IGkyY19tYXN0ZXJfd3JpdGVfYW5kX3JlYWQobWFzdGVyX2lkLCBzbGF2ZUFkZHIsIGJ1ZmYsIDIsICh1bnNpZ25lZCBjaGFyKikwLCAwKTsKCQlpZiAocmV0KSB7CgkJCWxncGxfcHJpbnRmKCJQTUlDIGkyYyB3cml0ZSBmYWlsICFcbiIpOwoJCQlyZXR1cm4gcmV0OwoJCX0KCgkJLy9pMmNfbWFzdGVyX2luaXQobWFzdGVyX2lkLCAxMDAsIDApOyAgLy9pbnQgaWQsIGludCBzcGVlZCwgaW50IGJfMTBiaXRfYWRkcgoJCS8vIHJlYWQKCQlidWZmWzBdID0gKHVuc2lnbmVkIGNoYXIpUkVHX1ZTRUwwOwoJCXJldCA9IGkyY19tYXN0ZXJfd3JpdGVfYW5kX3JlYWQobWFzdGVyX2lkLCBzbGF2ZUFkZHIsIGJ1ZmYsIDEsICh1bnNpZ25lZCBjaGFyICopJmRhdGEsIDEpOwoJCWlmIChyZXQpIHsKCQkJbGdwbF9wcmludGYoIlBNSUMgaTJjIHJlYWQgZmFpbCAhXG4iKTsKCQkJcmV0dXJuIHJldDsKCQl9CgoJCWlmIChkYXRhX3JlZzAgIT0gZGF0YSkgewoJCQlsZ3BsX3ByaW50ZiggIlBNSUMgc3kyMDI3NjogcmVhZDoweCUwMnggIT0gd3JpdGU6MHglMDJ4XG4iLCBkYXRhLCBkYXRhX3JlZzApOwoJCQlyZXR1cm4gLTE7CgkJfQoKCQlsZ3BsX3ByaW50ZiggInNldCB0byAlZCBtdlxuIiwgdGFyZ2V0KTsKCQlkZWxheV9tcygxKTsKCX0KCWVsc2UgewoJCWxncGxfcHJpbnRmKCAiSWxsZWdhbCB0YXJnZXQgdm9sdGFnZSBmb3IgUE1JQyBzeTIwMjc2ICFcbiIpOwoJCXJldHVybiAtMTsKCX0KCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgc3kyMDI3Nl9nZXRfdm9sKGludCBtYXN0ZXJfaWQsIGludCBzbGF2ZUFkZHIpCnsKCWludCByZWFkID0gMHhmZjsKCWludCB2b2x0OwoJdW5zaWduZWQgaW50IGJ1bGtfcmVnID0gUkVHX1ZTRUwwOwoJaW50IHJldCA9IDE7CgoJaTJjX21hc3Rlcl9pbml0KG1hc3Rlcl9pZCwgMTAwLCAwKTsgIC8vaW50IGlkLCBpbnQgc3BlZWQsIGludCBiXzEwYml0X2FkZHIKCS8vIHJlYWQsIFNZMjAyNzYgc2xhdmUgYWRkcmVzcyBpcyAweDYwCglyZXQgPSBpMmNfbWFzdGVyX3dyaXRlX2FuZF9yZWFkKG1hc3Rlcl9pZCwgc2xhdmVBZGRyLCAodW5zaWduZWQgY2hhciopJmJ1bGtfcmVnLCAxLCAodW5zaWduZWQgY2hhciopJnJlYWQsIDEpOwoKCWxncGxfcHJpbnRmKCAiXG5SRUdfVlNFTDAgPSAweCV4IFxuIiwgcmVhZCk7CglyZXQgfD0gcG1pY19kYXRhMnZvbHQoJnZvbHQsIHJlYWQpOwoJaWYocmV0KSB7CgkJbGdwbF9wcmludGYoIiBpMmMgcmVhZCBmYWlsXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CgoJcmV0dXJuIHZvbHQ7Cn0KCnN0YXRpYyBpbnQgaTJjX2dldF9jcHVfdm9sdCh2b2lkKQp7CglpbnQgdm9sdCA9IHN5MjAyNzZfZ2V0X3ZvbChWT1VUX0NQVV9JRCwgU0xBVkVfQUREUik7CgoJaWYodm9sdCA8IDApCgkJcmV0dXJuIDA7CgoJcmV0dXJuIHZvbHQ7Cn0KCnN0YXRpYyBpbnQgaTJjX2dldF9jb3JlX3ZvbHQodm9pZCkKewoJaW50IHZvbHQgPSBzeTIwMjc2X2dldF92b2woVk9VVF9DT1JFX0lELCBTTEFWRV9BRERSKTsKCglpZih2b2x0IDwgMCkKCQlyZXR1cm4gMDsKCglyZXR1cm4gdm9sdDsKfQoKc3RhdGljIGludCBpMmNfc2V0X3ZvbHQoaW50IG1hc3Rlcl9pZCwgaW50IGZyb20sIGludCB0bykKewoJaW50IHZvbHQgPSBmcm9tOwoKCXdoaWxlICh2b2x0ICE9IHRvKXsKCQlpZiAodm9sdCA+IHRvKXsKCQkJdm9sdCAtPSBNSU5JTUFMX1ZPTF9TVEVQX1NZMjAyNzY7CgkJCWlmICh2b2x0IDwgdG8pCgkJCQl2b2x0ID0gdG87CgkJfWVsc2V7CgkJCXZvbHQgKz0gTUlOSU1BTF9WT0xfU1RFUF9TWTIwMjc2OwoJCQlpZiAodm9sdCA+IHRvKQoJCQkJdm9sdCA9IHRvOwoJCX0KCgkJaWYoMCAhPSBzeTIwMjc2X3NldF92b2wobWFzdGVyX2lkLCBTTEFWRV9BRERSLCB2b2x0KSkKCQkJcmV0dXJuIDE7CgkJLy91ZGVsYXkoNTApOyAJLy9GSVhNRTogMW1zIGRlbGF5ZWQKCX0KCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBpMmNfc2V0X3ZjcHVfdm9sdChpbnQgZnJvbSwgaW50IHRvKQp7CglyZXR1cm4gaTJjX3NldF92b2x0KFZPVVRfQ1BVX0lELCBmcm9tICx0byk7Cn0KCnN0YXRpYyBpbnQgaTJjX3NldF92Y29yZV92b2x0KGludCBmcm9tLCBpbnQgdG8pCnsKCXJldHVybiBpMmNfc2V0X3ZvbHQoVk9VVF9DT1JFX0lELCBmcm9tICx0byk7Cn0KCmNvbnN0IGR2ZnNfb3BzX3Qgc3kyMDI3Nl9vcHMgPSB7CgkuZ2V0X3ZjcHVfdm9sdCA9IGkyY19nZXRfY3B1X3ZvbHQsCgkuZ2V0X3Zjb3JlX3ZvbHQgPSBpMmNfZ2V0X2NvcmVfdm9sdCwKCS5zZXRfdmNwdV92b2x0ID0gaTJjX3NldF92Y3B1X3ZvbHQsCgkuc2V0X3Zjb3JlX3ZvbHQgPWkyY19zZXRfdmNvcmVfdm9sdAp9Owo=