LyoKICogTkRBIEFORCBORUVELVRPLUtOT1cgUkVRVUlSRUQKICoKICogQ29weXJpZ2h0IKkgMjAxMy0yMDE4IFN5bmFwdGljcyBJbmNvcnBvcmF0ZWQuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFRoaXMgZmlsZSBjb250YWlucyBpbmZvcm1hdGlvbiB0aGF0IGlzIHByb3ByaWV0YXJ5IHRvIFN5bmFwdGljcwogKiBJbmNvcnBvcmF0ZWQgKCJTeW5hcHRpY3MiKS4gVGhlIGhvbGRlciBvZiB0aGlzIGZpbGUgc2hhbGwgdHJlYXQgYWxsCiAqIGluZm9ybWF0aW9uIGNvbnRhaW5lZCBoZXJlaW4gYXMgY29uZmlkZW50aWFsLCBzaGFsbCB1c2UgdGhlCiAqIGluZm9ybWF0aW9uIG9ubHkgZm9yIGl0cyBpbnRlbmRlZCBwdXJwb3NlLCBhbmQgc2hhbGwgbm90IGR1cGxpY2F0ZSwKICogZGlzY2xvc2UsIG9yIGRpc3NlbWluYXRlIGFueSBvZiB0aGlzIGluZm9ybWF0aW9uIGluIGFueSBtYW5uZXIKICogdW5sZXNzIFN5bmFwdGljcyBoYXMgb3RoZXJ3aXNlIHByb3ZpZGVkIGV4cHJlc3MsIHdyaXR0ZW4KICogcGVybWlzc2lvbi4KICoKICogVXNlIG9mIHRoZSBtYXRlcmlhbHMgbWF5IHJlcXVpcmUgYSBsaWNlbnNlIG9mIGludGVsbGVjdHVhbCBwcm9wZXJ0eQogKiBmcm9tIGEgdGhpcmQgcGFydHkgb3IgZnJvbSBTeW5hcHRpY3MuIFRoaXMgZmlsZSBjb252ZXlzIG5vIGV4cHJlc3MKICogb3IgaW1wbGllZCBsaWNlbnNlcyB0byBhbnkgaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBiZWxvbmdpbmcKICogdG8gU3luYXB0aWNzLgogKgogKiBJTkZPUk1BVElPTiBDT05UQUlORUQgSU4gVEhJUyBET0NVTUVOVCBJUyBQUk9WSURFRCAiQVMtSVMsIiBBTkQKICogU1lOQVBUSUNTIEVYUFJFU1NMWSBESVNDTEFJTVMgQUxMIEVYUFJFU1MgQU5EIElNUExJRUQgV0FSUkFOVElFUywKICogSU5DTFVESU5HIEFOWSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwgQU5EIEFOWSBXQVJSQU5USUVTIE9GIE5PTi1JTkZSSU5HRU1FTlQgT0YgQU5ZCiAqIElOVEVMTEVDVFVBTCBQUk9QRVJUWSBSSUdIVFMuIElOIE5PIEVWRU5UIFNIQUxMIFNZTkFQVElDUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBQVU5JVElWRSwgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFCiAqIE9GIFRIRSBJTkZPUk1BVElPTiBDT05UQUlORUQgSU4gVEhJUyBET0NVTUVOVCwgSE9XRVZFUiBDQVVTRUQgQU5ECiAqIEJBU0VEIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwKICogTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFORCBFVkVOIElGIFNZTkFQVElDUyBXQVMKICogQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuIElGIEEgVFJJQlVOQUwgT0YKICogQ09NUEVURU5UIEpVUklTRElDVElPTiBET0VTIE5PVCBQRVJNSVQgVEhFIERJU0NMQUlNRVIgT0YgRElSRUNUCiAqIERBTUFHRVMgT1IgQU5ZIE9USEVSIERBTUFHRVMsIFNZTkFQVElDUycgVE9UQUwgQ1VNVUxBVElWRSBMSUFCSUxJVFkKICogVE8gQU5ZIFBBUlRZIFNIQUxMIE5PVCBFWENFRUQgT05FIEhVTkRSRUQgVS5TLiBET0xMQVJTLgogKi8KI2luY2x1ZGUgImkyY19kcml2ZXIuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAiaW8uaCIKI2luY2x1ZGUgImRlYnVnLmgiCiNpbmNsdWRlICJtZW1tYXAuaCIKI2luY2x1ZGUgImNoaXBfdm9sdGFnZV9pbmZvLmgiCiNpbmNsdWRlICJTeXNNZ3IuaCIKI2luY2x1ZGUgImFwYlJlZ0Jhc2UuaCIKI2luY2x1ZGUgImxncGxfcHJpbnRmLmgiCgojaW5jbHVkZSAicHZfY29tcC5oIgoKI2lmbmRlZiBWT1VUX0NQVV9JRAojZGVmaW5lIFZPVVRfQ1BVX0lEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMikKI2VuZGlmCgojaWZuZGVmIFZPVVRfQ09SRV9JRAojZGVmaW5lIFZPVVRfQ09SRV9JRCAgICAgICAgICAgICAgICAgICAgKDApCiNlbmRpZgoKI2lmbmRlZiBWT1VUX0NQVV9DSEFOTkVMCiNkZWZpbmUgVk9VVF9DUFVfQ0hBTk5FTCAgICAgICAgICAgICAgICAoMCkKI2VuZGlmCgojaWZuZGVmIFZPVVRfQ09SRV9DSEFOTkVMCiNkZWZpbmUgVk9VVF9DT1JFX0NIQU5ORUwgICAgICAgICAgICAgICAoMSkKI2VuZGlmCgovLyBhbGwgZGVmaW5lZCB1bmRlciB1dgojaWZuZGVmIE1JTklNQUxfVk9MX1NURVBfTTg4UEc4NlgKI2RlZmluZSBNSU5JTUFMX1ZPTF9TVEVQX004OFBHODZYIDI1MDAwCiNlbmRpZgojZGVmaW5lIE1JTl9WT0xUQUdFIDkwMDAwMAojZGVmaW5lIE1BWF9WT0xUQUdFIDE2MDAwMDAKCmV4dGVybiB2b2lkIHVkZWxheSh1bnNpZ25lZCBsb25nIHVzZWMpOwpleHRlcm4gaW50IGkyY19tYXN0ZXJfaW5pdChpbnQgaWQsIGludCBzcGVlZCwgaW50IGJfMTBiaXRfYWRkcik7CmV4dGVybiBpbnQgaTJjX21hc3Rlcl93cml0ZV9hbmRfcmVhZChpbnQgaWQsIGludCB0YXJnZXRfYWRkciwgdW5zaWduZWQgY2hhciogc2VuZF9idWZmLCBpbnQgc2VuZF9sZW4sIHVuc2lnbmVkIGNoYXIqIHJlY3ZfYnVmZiwgaW50IHJlY3ZfbGVuKTsKCi8vYXNzdW1lIHRoZSBsb3dlc3Qgdm9sdGFnZSBpcyA5MDBtdgovL2FsbCB2b2x0YWdlIGlzICoxMCBoZXJlIHRvIGhhbmRsZSAxMi41bXYgY2FzZQpzdGF0aWMgaW50IHBtaWNfdm9sdDJkYXRhKGludCB2b2x0LCBpbnQgKnBfZGF0YSkKewoJaWYoKHZvbHQgPCBNSU5fVk9MVEFHRSkgfHwgKHZvbHQgPiBNQVhfVk9MVEFHRSkpCgkJcmV0dXJuIC0xOwoJaWYoKHZvbHQgLSBNSU5fVk9MVEFHRSkgJSAyNTAwMCkKCQkqcF9kYXRhID0gKHZvbHQgLSBNSU5fVk9MVEFHRSkgLyAyNTAwMCArIDEgKyAweDc7CgllbHNlCgkJKnBfZGF0YSA9ICh2b2x0IC0gTUlOX1ZPTFRBR0UpIC8gMjUwMDAgKyAweDc7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgcG1pY19kYXRhMnZvbHQoaW50ICpwX3ZvbHQsIGludCBkYXRhKQp7CgkqcF92b2x0ID0gKE1JTl9WT0xUQUdFICsgKGRhdGEgLSAweDcpICogMjUwMDApOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGkyY19nZXRfdm9sdChpbnQgbWFzdGVyX2lkKQp7CglpbnQgcmV0LCB2b2x0OwoJdW5zaWduZWQgY2hhciBidWZmOwoJdW5zaWduZWQgY2hhciByZWFkID0gMHhmZjsKCXVuc2lnbmVkIGNoYXIgc2xhdmVBZGRyID0gMHgxOTsgLy8gUEc4Njcgc2xhdmUgYWRkcmVzcyBpcyAweDE5CglidWZmID0gMHgyNDsKCglpMmNfbWFzdGVyX2luaXQobWFzdGVyX2lkLCAxMDAsIDApOwoJcmV0ID0gaTJjX21hc3Rlcl93cml0ZV9hbmRfcmVhZChtYXN0ZXJfaWQsIChpbnQpc2xhdmVBZGRyLCAodW5zaWduZWQgY2hhciopJmJ1ZmYsIDEsICh1bnNpZ25lZCBjaGFyKikmcmVhZCwgMSk7CglpZiAocmV0ICE9IDApIHsKCQlsZ3BsX3ByaW50ZigiIGkyYyByZWFkIGZhaWxcbiIpOwoJCXJldHVybiAtcmV0OwoJfQoKCXBtaWNfZGF0YTJ2b2x0KCZ2b2x0LCAoaW50KXJlYWQpOwoKCXJldHVybiB2b2x0Owp9CgpzdGF0aWMgaW50IGRpYWdfaTJjX3ZvbHRfY29udHJvbChpbnQgbWFzdGVyX2lkLCBpbnQgdm9sdF9pbmRleCkKewoJdW5zaWduZWQgY2hhciBidWZmWzJdOwoJdW5zaWduZWQgY2hhciByZWFkID0gMHhmZjsKCWludCByZXQ7CgkvLyBWSW5kZXg6IFswLTAuOTAsMS0wLjkyNSwyLTAuOTUoZGVmYXVsdCksMy0wLjk3NSw0LTEuMDAsNS0xLjAyNSw2LTEuMDUwXQoJdW5zaWduZWQgY2hhciBzbGF2ZUFkZHIgPSAweDE5OyAvLyBQRzg2NyBzbGF2ZSBhZGRyZXNzIGlzIDB4MTkKCWJ1ZmZbMF0gPSAweDI0OyAgLy8gUEc4NjcgYnVjazEgdGFyZ2V0IHZvbHRhZ2UgMiAoYWN0aXZlKSByZWdpc3RlcgoJYnVmZlsxXSA9IDB4NyArIHZvbHRfaW5kZXg7IC8vIDB4NyBpcyAwLjkwdi4gZWFjaCBzdGVwIGlzIDAuMDI1CgoJaTJjX21hc3Rlcl9pbml0KG1hc3Rlcl9pZCwgMTAwLCAwKTsKCXJldCA9IGkyY19tYXN0ZXJfd3JpdGVfYW5kX3JlYWQobWFzdGVyX2lkLCAoaW50KXNsYXZlQWRkciwgYnVmZiwgMiwgKHVuc2lnbmVkIGNoYXIqKTAsIDApOwoJaWYgKHJldCAhPSAwKSB7CgkJbGdwbF9wcmludGYoIiBpMmMgd3JpdGUgZmFpbFxuIik7CgkJcmV0dXJuIHJldDsKCX0KCglyZXQgPSBpMmNfbWFzdGVyX3dyaXRlX2FuZF9yZWFkKG1hc3Rlcl9pZCwgKGludClzbGF2ZUFkZHIsIGJ1ZmYsIDEsICh1bnNpZ25lZCBjaGFyKikmcmVhZCwgMSk7CglpZiAocmV0ICE9IDApIHsKCQlsZ3BsX3ByaW50ZigiIGkyYyByZWFkIGZhaWxcbiIpOwoJCXJldHVybiByZXQ7Cgl9CgoJaWYgKGJ1ZmZbMV0gIT0gcmVhZCkgewoJCWxncGxfcHJpbnRmKCIgaTJjIHZjb3JlIGNvbnRyb2wgZmFpbCwgcmVhZDoweCUwMnggIT0gd3JpdGU6MHglMDJ4XG4iLCByZWFkLCBidWZmWzFdKTsKCQlyZXR1cm4gMTsKCX0KCS8vZGJnX3ByaW50ZihQUk5fREJHLCIgdmNvcmUgaXMgJTRkLiUwM2R2XG4iLCAoOTAwKzI1KnZvbHRfaW5kZXgpIC8gMTAwMCwgKDkwMCsyNSp2b2x0X2luZGV4KSAlIDEwMDApOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGkyY19nZXRfY3B1X3ZvbHQodm9pZCkKewoJaW50IHZvbHQgPSBpMmNfZ2V0X3ZvbHQoVk9VVF9DUFVfSUQpOwoKCWlmKHZvbHQgPCAwKQoJCXJldHVybiAwOwoKCXJldHVybiB2b2x0Owp9CgpzdGF0aWMgaW50IGkyY19nZXRfY29yZV92b2x0KHZvaWQpCnsKCWludCB2b2x0ID0gaTJjX2dldF92b2x0KFZPVVRfQ09SRV9JRCk7CgoJaWYodm9sdCA8IDApCgkJcmV0dXJuIDA7CgoJcmV0dXJuIHZvbHQ7Cn0KCnN0YXRpYyBpbnQgaTJjX3NldF92b2x0KGludCBtYXN0ZXJfaWQsIGludCBmcm9tLCBpbnQgdG8pCnsKCWludCB2b2x0X2luZGV4ID0gMCwgdm9sdCA9IGZyb207CgoJd2hpbGUgKHZvbHQgIT0gdG8pewoJCWlmICh2b2x0ID4gdG8pewoJCQl2b2x0IC09IE1JTklNQUxfVk9MX1NURVBfTTg4UEc4Nlg7CgkJCWlmICh2b2x0IDwgdG8pCgkJCQl2b2x0ID0gdG87CgkJfWVsc2V7CgkJCXZvbHQgKz0gTUlOSU1BTF9WT0xfU1RFUF9NODhQRzg2WDsKCQkJaWYgKHZvbHQgPiB0bykKCQkJCXZvbHQgPSB0bzsKCQl9CgkJaWYoMCAhPSBwbWljX3ZvbHQyZGF0YSh2b2x0LCAmdm9sdF9pbmRleCkpIHsKCQkJbGdwbF9wcmludGYoImVycm9yIGNvbnZlcnQgdm9sdCAlZCB0byBpbmRleCAlZC5cbiIsIHZvbHQsIHZvbHRfaW5kZXgpOwoJCQlyZXR1cm4gMTsKCQl9CgoJCWlmKDAgIT0gZGlhZ19pMmNfdm9sdF9jb250cm9sKG1hc3Rlcl9pZCwgdm9sdF9pbmRleCkpCgkJCXJldHVybiAxOwoJCXVkZWxheSg1MCk7IAkvLyBkZWxheSA1MHVzIHRvIHdhaXQgaXQgc3RhYmxlCgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgaTJjX3NldF92Y3B1X3ZvbHQoaW50IGZyb20sIGludCB0bykKewoJcmV0dXJuIGkyY19zZXRfdm9sdChWT1VUX0NQVV9JRCwgZnJvbSAsdG8pOwp9CgpzdGF0aWMgaW50IGkyY19zZXRfdmNvcmVfdm9sdChpbnQgZnJvbSwgaW50IHRvKQp7CglyZXR1cm4gaTJjX3NldF92b2x0KFZPVVRfQ09SRV9JRCwgZnJvbSAsdG8pOwp9Cgpjb25zdCBkdmZzX29wc190IG04OHBnODZ4X29wcyA9IHsKCS5nZXRfdmNwdV92b2x0ID0gaTJjX2dldF9jcHVfdm9sdCwKCS5nZXRfdmNvcmVfdm9sdCA9IGkyY19nZXRfY29yZV92b2x0LAoJLnNldF92Y3B1X3ZvbHQgPSBpMmNfc2V0X3ZjcHVfdm9sdCwKCS5zZXRfdmNvcmVfdm9sdCA9aTJjX3NldF92Y29yZV92b2x0Cn07Cg==