LyoKICogQ29weXJpZ2h0IChjKSAxOTg5LCAxOTkzCiAqCVRoZSBSZWdlbnRzIG9mIHRoZSBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OgogKglUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mCiAqCUNhbGlmb3JuaWEsIEJlcmtlbGV5IGFuZCBpdHMgY29udHJpYnV0b3JzLgogKiA0LiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBVbml2ZXJzaXR5IG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBSRUdFTlRTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICogTW9kaWZpZWQgU3VuIE1hciAxMiAxMDozOToyMiAxOTk1LCBmYWl0aEBjcy51bmMuZWR1IGZvciBMaW51eAogKgogKi8KCiAvKiAxOTk5LTAyLTIyIEFya2FkaXVzeiBNabZraWV3aWN6IDxtaXNpZWtAcGxkLk9SRy5QTD4KICAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICAqIFN1biBNYXIgMjEgMTk5OSAtIEFybmFsZG8gQ2FydmFsaG8gZGUgTWVsbyA8YWNtZUBjb25lY3RpdmEuY29tLmJyPgogICogLSBmaXhlZCBzdHJlcnIoZXJybm8pIGluIGdldHRleHQgY2FsbHMKICAqLwoKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3Vpby5oPgojaW5jbHVkZSA8c2lnbmFsLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8ZGlyZW50Lmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8cGF0aHMuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlICJubHMuaCIKCiNpbmNsdWRlICJwYXRobmFtZXMuaCIKI2luY2x1ZGUgInR0eW1zZy5oIgoKLyoKICogRGlzcGxheSB0aGUgY29udGVudHMgb2YgYSB1aW8gc3RydWN0dXJlIG9uIGEgdGVybWluYWwuICBVc2VkIGJ5IHdhbGwoMSksCiAqIHN5c2xvZ2QoOCksIGFuZCB0YWxrZCg4KS4gIEZvcmtzIGFuZCBmaW5pc2hlcyBpbiBjaGlsZCBpZiB3cml0ZSB3b3VsZCBibG9jaywKICogd2FpdGluZyB1cCB0byB0bW91dCBzZWNvbmRzLiAgUmV0dXJucyBwb2ludGVyIHRvIGVycm9yIHN0cmluZyBvbiB1bmV4cGVjdGVkCiAqIGVycm9yOyBzdHJpbmcgaXMgbm90IG5ld2xpbmUtdGVybWluYXRlZC4gIFZhcmlvdXMgIm5vcm1hbCIgZXJyb3JzIGFyZQogKiBpZ25vcmVkIChleGNsdXNpdmUtdXNlLCBsYWNrIG9mIHBlcm1pc3Npb24sIGV0Yy4pLgogKi8KY2hhciAqCnR0eW1zZyhzdHJ1Y3QgaW92ZWMgKmlvdiwgaW50IGlvdmNudCwgY2hhciAqbGluZSwgaW50IHRtb3V0KSB7CglzdGF0aWMgY2hhciBkZXZpY2VbTUFYTkFNTEVOXTsKCXN0YXRpYyBjaGFyIGVycmJ1ZltNQVhOQU1MRU4rMTAyNF07CglyZWdpc3RlciBpbnQgY250LCBmZCwgbGVmdCwgd3JldDsKCXN0cnVjdCBpb3ZlYyBsb2NhbGlvdls2XTsKCWludCBmb3JrZWQgPSAwLCBlcnJzdjsKCglpZiAoaW92Y250ID4gc2l6ZW9mKGxvY2FsaW92KSAvIHNpemVvZihsb2NhbGlvdlswXSkpCgkJcmV0dXJuIChfKCJ0b28gbWFueSBpb3YncyAoY2hhbmdlIGNvZGUgaW4gd2FsbC90dHltc2cuYykiKSk7CgoJLyogVGhlIG9sZCBjb2RlIGhlcmUgcmVqZWN0ZWQgdGhlIGxpbmUgYXJndW1lbnQgd2hlbiBpdCBjb250YWluZWQgYSAnLycsCgkgICBzYXlpbmc6ICJBIHNsYXNoIG1heSBiZSBhbiBhdHRlbXB0IHRvIGJyZWFrIHNlY3VyaXR5Li4uIi4KCSAgIEhvd2V2ZXIsIGlmIGEgdXNlciBjYW4gY29udHJvbCB0aGUgbGluZSBhcmd1bWVudCBoZXJlCgkgICB0aGVuIGhlIGNhbiBtYWtlIHRoaXMgcm91dGluZSB3cml0ZSB0byAvZGV2L2hkYSBvciAvZGV2L3NkYQoJICAgYWxyZWFkeS4gU28sIHRoaXMgdGVzdCB3YXMgd29ydGhsZXNzLCBhbmQgdGhlc2UgZGF5cyBpdCBpcwoJICAgYWxzbyB3cm9uZyBzaW5jZSBwZW9wbGUgdXNlIC9kZXYvcHRzL3h4eC4gKi8KCglpZiAoc3RybGVuKGxpbmUpICsgc2l6ZW9mKF9QQVRIX0RFVikgKyAxID4gc2l6ZW9mKGRldmljZSkpIHsKCQkodm9pZCkgc3ByaW50ZihlcnJidWYsIF8oImV4Y2Vzc2l2ZWx5IGxvbmcgbGluZSBhcmciKSk7CgkJcmV0dXJuIChlcnJidWYpOwoJfQoJKHZvaWQpIHNwcmludGYoZGV2aWNlLCAiJXMlcyIsIF9QQVRIX0RFViwgbGluZSk7CgoJLyoKCSAqIG9wZW4gd2lsbCBmYWlsIG9uIHNsaXAgbGluZXMgb3IgZXhjbHVzaXZlLXVzZSBsaW5lcwoJICogaWYgbm90IHJ1bm5pbmcgYXMgcm9vdDsgbm90IGFuIGVycm9yLgoJICovCglpZiAoKGZkID0gb3BlbihkZXZpY2UsIE9fV1JPTkxZfE9fTk9OQkxPQ0ssIDApKSA8IDApIHsKCQlpZiAoZXJybm8gPT0gRUJVU1kgfHwgZXJybm8gPT0gRUFDQ0VTKQoJCQlyZXR1cm4gKE5VTEwpOwoJCWlmIChzdHJsZW4oc3RyZXJyb3IoZXJybm8pKSA+IDEwMDApCgkJCXJldHVybiAoTlVMTCk7CgkJKHZvaWQpIHNwcmludGYoZXJyYnVmLCAiJXM6ICVzIiwgZGV2aWNlLCBzdHJlcnJvcihlcnJubykpOwoJCWVycmJ1ZlsxMDI0XSA9IDA7CgkJcmV0dXJuIChlcnJidWYpOwoJfQoKCWZvciAoY250ID0gbGVmdCA9IDA7IGNudCA8IGlvdmNudDsgKytjbnQpCgkJbGVmdCArPSBpb3ZbY250XS5pb3ZfbGVuOwoKCWZvciAoOzspIHsKCQl3cmV0ID0gd3JpdGV2KGZkLCBpb3YsIGlvdmNudCk7CgkJaWYgKHdyZXQgPj0gbGVmdCkKCQkJYnJlYWs7CgkJaWYgKHdyZXQgPj0gMCkgewoJCQlsZWZ0IC09IHdyZXQ7CgkJCWlmIChpb3YgIT0gbG9jYWxpb3YpIHsKCQkJCW1lbW1vdmUobG9jYWxpb3YsIGlvdiwKCQkJCSAgICBpb3ZjbnQgKiBzaXplb2Yoc3RydWN0IGlvdmVjKSk7CgkJCQlpb3YgPSBsb2NhbGlvdjsKCQkJfQoJCQlmb3IgKGNudCA9IDA7IHdyZXQgPj0gaW92LT5pb3ZfbGVuOyArK2NudCkgewoJCQkJd3JldCAtPSBpb3YtPmlvdl9sZW47CgkJCQkrK2lvdjsKCQkJCS0taW92Y250OwoJCQl9CgkJCWlmICh3cmV0KSB7CgkJCQlpb3YtPmlvdl9iYXNlICs9IHdyZXQ7CgkJCQlpb3YtPmlvdl9sZW4gLT0gd3JldDsKCQkJfQoJCQljb250aW51ZTsKCQl9CgkJaWYgKGVycm5vID09IEVXT1VMREJMT0NLKSB7CgkJCWludCBjcGlkLCBmbGFnczsKCQkJc2lnc2V0X3Qgc2lnbWFzazsKCgkJCWlmIChmb3JrZWQpIHsKCQkJCSh2b2lkKSBjbG9zZShmZCk7CgkJCQlfZXhpdCgxKTsKCQkJfQoJCQljcGlkID0gZm9yaygpOwoJCQlpZiAoY3BpZCA8IDApIHsKCQkJCWlmIChzdHJsZW4oc3RyZXJyb3IoZXJybm8pKSA+IDEwMDApCgkJCQkJKHZvaWQpIHNwcmludGYoZXJyYnVmLCBfKCJjYW5ub3QgZm9yayIpKTsKCQkJCWVsc2UgewoJCQkJCWVycnN2ID0gZXJybm87CgkJCQkJKHZvaWQpIHNwcmludGYoZXJyYnVmLAoJCQkJCQkgXygiZm9yazogJXMiKSwgc3RyZXJyb3IoZXJyc3YpKTsKCQkJCX0KCQkJCSh2b2lkKSBjbG9zZShmZCk7CgkJCQlyZXR1cm4gKGVycmJ1Zik7CgkJCX0KCQkJaWYgKGNwaWQpIHsJLyogcGFyZW50ICovCgkJCQkodm9pZCkgY2xvc2UoZmQpOwoJCQkJcmV0dXJuIChOVUxMKTsKCQkJfQoJCQlmb3JrZWQrKzsKCQkJLyogd2FpdCBhdCBtb3N0IHRtb3V0IHNlY29uZHMgKi8KCQkJKHZvaWQpIHNpZ25hbChTSUdBTFJNLCBTSUdfREZMKTsKCQkJKHZvaWQpIHNpZ25hbChTSUdURVJNLCBTSUdfREZMKTsgLyogWFhYICovCgkJCXNpZ2VtcHR5c2V0KCZzaWdtYXNrKTsKCQkJc2lncHJvY21hc2sgKFNJR19TRVRNQVNLLCAmc2lnbWFzaywgTlVMTCk7CgkJCSh2b2lkKSBhbGFybSgodV9pbnQpdG1vdXQpOwoJCQlmbGFncyA9IGZjbnRsKGZkLCBGX0dFVEZMKTsKCQkJZmNudGwoZmxhZ3MsIEZfU0VURkwsIChsb25nKSAoZmxhZ3MgJiB+T19OT05CTE9DSykpOwoJCQljb250aW51ZTsKCQl9CgkJLyoKCQkgKiBXZSBnZXQgRU5PREVWIG9uIGEgc2xpcCBsaW5lIGlmIHdlJ3JlIHJ1bm5pbmcgYXMgcm9vdCwKCQkgKiBhbmQgRUlPIGlmIHRoZSBsaW5lIGp1c3Qgd2VudCBhd2F5LgoJCSAqLwoJCWlmIChlcnJubyA9PSBFTk9ERVYgfHwgZXJybm8gPT0gRUlPKQoJCQlicmVhazsKCQkodm9pZCkgY2xvc2UoZmQpOwoJCWlmIChmb3JrZWQpCgkJCV9leGl0KDEpOwoJCWlmIChzdHJsZW4oc3RyZXJyb3IoZXJybm8pKSA+IDEwMDApCgkJCSh2b2lkKSBzcHJpbnRmKGVycmJ1ZiwgXygiJXM6IEJBRCBFUlJPUiIpLCBkZXZpY2UpOwoJCWVsc2UgewoJCQllcnJzdiA9IGVycm5vOwoJCQkodm9pZCkgc3ByaW50ZihlcnJidWYsICIlczogJXMiLCBkZXZpY2UsCgkJCQkgICAgICAgc3RyZXJyb3IoZXJyc3YpKTsKCQl9CgkJZXJyYnVmWzEwMjRdID0gMDsKCQlyZXR1cm4gKGVycmJ1Zik7Cgl9CgoJKHZvaWQpIGNsb3NlKGZkKTsKCWlmIChmb3JrZWQpCgkJX2V4aXQoMCk7CglyZXR1cm4gKE5VTEwpOwp9Cg==