LyoKICogQ29weXJpZ2h0IChjKSAyMDA3LTIwMDggQXRoZXJvcyBDb21tdW5pY2F0aW9ucyBJbmMuCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueQogKiBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlIGFib3ZlCiAqIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIGFsbCBjb3BpZXMuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUwogKiBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GCiAqIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SCiAqIEFOWSBTUEVDSUFMLCBESVJFQ1QsIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMKICogV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOCiAqIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GCiAqIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgTW9kdWxlIE5hbWUgOiBjYWdnLmMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgQWJzdHJhY3QgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFRoaXMgbW9kdWxlIGNvbnRhaW5zIEEtTVBEVSBhZ2dyZWdhdGlvbiByZWxhdGVkIGZ1bmN0aW9ucy4gICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgTk9URVMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIE5vbmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgImNwcmVjb21wLmgiCgpleHRlcm4gdThfdCB6Y1VwVG9BY1s4XTsKY29uc3QgdThfdCBwcmlbXSA9IHszLDMsMiwzLDIsMSwzLDIsMSwwfTsKCgp1MTZfdCBhZ2dyX2NvdW50Owp1MzJfdCBzdWNjZXNzX21wZHU7CnUzMl90IHRvdGFsX21wZHU7Cgp2b2lkIHpmQWdnSW5pdCh6ZGV2X3QqIGRldikKewogICAgdTE2X3QgaSxqOwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwogICAgLyoKICAgICAqIHJlc2V0IHN0YSBpbmZvcm1hdGlvbgogICAgICovCgogICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgIHdkLT5hZ2dJbml0aWF0ZWQgPSAwOwogICAgd2QtPmFkZGJhQ29tcGxldGUgPSAwOwogICAgd2QtPmFkZGJhQ291bnQgPSAwOwogICAgd2QtPnJlb3JkZXIgPSAxOwogICAgZm9yIChpPTA7IGk8Wk1fTUFYX1NUQV9TVVBQT1JUOyBpKyspCiAgICB7CiAgICAgICAgZm9yIChqPTA7IGo8Wk1fQUM7IGorKykKICAgICAgICB7CiAgICAgICAgICAgIC8vd2QtPmFnZ1N0YVtpXS5hZ2dRTnVtYmVyW2pdID0gWk1fQUdHX1BPT0xfU0laRTsKICAgICAgICAgICAgd2QtPmFnZ1N0YVtpXS5hZ2dGbGFnW2pdID0gd2QtPmFnZ1N0YVtpXS5jb3VudFtqXSA9IDA7CiAgICAgICAgICAgIHdkLT5hZ2dTdGFbaV0udGlkX3R4W2pdID0gTlVMTDsKICAgICAgICAgICAgd2QtPmFnZ1N0YVtpXS50aWRfdHhbaisxXSA9IE5VTEw7CgogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogcmVzZXQgVHgvUnggYWdncmVnYXRpb24gcXVldWUgaW5mb3JtYXRpb24KICAgICAqLwogICAgd2QtPmFnZ1N0YXRlID0gMDsKICAgIGZvciAoaT0wOyBpPFpNX0FHR19QT09MX1NJWkU7IGkrKykKICAgIHsKICAgICAgICAvKgogICAgICAgICAqIHJlc2V0IHR4IGFnZ3JlZ2F0aW9uIHF1ZXVlCiAgICAgICAgICovCiAgICAgICAgd2QtPmFnZ1FQb29sW2ldID0gemZ3TWVtQWxsb2NhdGUoZGV2LCBzaXplb2Yoc3RydWN0IGFnZ1F1ZXVlKSk7CiAgICAgICAgaWYoIXdkLT5hZ2dRUG9vbFtpXSkKICAgICAgICB7CiAgICAgICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgd2QtPmFnZ1FQb29sW2ldLT5hZ2dIZWFkID0gd2QtPmFnZ1FQb29sW2ldLT5hZ2dUYWlsID0KICAgICAgICB3ZC0+YWdnUVBvb2xbaV0tPmFnZ1FFbmFibGVkID0gd2QtPmFnZ1FQb29sW2ldLT5hZ2dSZWFkeSA9CiAgICAgICAgd2QtPmFnZ1FQb29sW2ldLT5jbGVhckZsYWcgPSB3ZC0+YWdnUVBvb2xbaV0tPmRlbGV0ZUZsYWcgPSAwOwogICAgICAgIC8vd2QtPmFnZ1FQb29sW2ldLT5hZ2dTaXplID0gMTY7CgogICAgICAgIC8qCiAgICAgICAgICogcmVzZXQgcnggYWdncmVnYXRpb24gcXVldWUKICAgICAgICAgKi8KICAgICAgICB3ZC0+dGlkX3J4W2ldID0gemZ3TWVtQWxsb2NhdGUoZGV2LCBzaXplb2Yoc3RydWN0IGFnZ190aWRfcngpKTsKICAgICAgICBpZiAoIXdkLT50aWRfcnhbaV0pCiAgICAgICAgewogICAgICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHdkLT50aWRfcnhbaV0tPmFpZCA9IFpNX01BWF9TVEFfU1VQUE9SVDsKICAgICAgICB3ZC0+dGlkX3J4W2ldLT5zZXFfc3RhcnQgPSB3ZC0+dGlkX3J4W2ldLT5iYXdfaGVhZCA9IFwKICAgICAgICB3ZC0+dGlkX3J4W2ldLT5iYXdfdGFpbCA9IDA7CiAgICAgICAgd2QtPnRpZF9yeFtpXS0+c3FfZXhjZWVkX2NvdW50ID0gd2QtPnRpZF9yeFtpXS0+c3FfYmVoaW5kX2NvdW50ID0gMDsKICAgICAgICBmb3IgKGo9MDsgajw9Wk1fQUdHX0JBV19TSVpFOyBqKyspCiAgICAgICAgICAgIHdkLT50aWRfcnhbaV0tPmZyYW1lW2pdLmJ1ZiA9IDA7CiAgICAgICAgLyoKICAgICAgICAgKiByZXNldCBBRERCQSBleGNoYW5nZSBzdGF0dXMgY29kZQogICAgICAgICAqIDA6IE5VTEwKICAgICAgICAgKiAxOiBBRERCQSBSZXF1ZXN0IHNlbnQvcmVjZWl2ZWQKICAgICAgICAgKiAyOiBBQ0sgZm9yIEFEREJBIFJlcXVlc3Qgc2VudC9yZWNlaXZlZAogICAgICAgICAqIDM6IEFEREJBIFJlc3BvbnNlIHNlbnQvcmVjZWl2ZWQKICAgICAgICAgKiA0OiBBQ0sgZm9yIEFEREJBIFJlc3BvbnNlIHNlbnQvcmVjZWl2ZWQKICAgICAgICAgKi8KICAgICAgICB3ZC0+dGlkX3J4W2ldLT5hZGRCYUV4Y2hhbmdlU3RhdHVzQ29kZSA9IDA7CgogICAgfQogICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgIHpmQWdnVGFsbHlSZXNldChkZXYpOwogICAgREVTVFEuaW5pdCA9IHpmQWdnRGVzdEluaXQ7CiAgICBERVNUUS5pbml0KGRldik7CiAgICB3ZC0+YWdnSW5pdGlhdGVkID0gMTsKICAgIGFnZ3JfY291bnQgPSAwOwogICAgc3VjY2Vzc19tcGR1ID0gMDsKICAgIHRvdGFsX21wZHUgPSAwOwojaWZkZWYgWk1fRU5BQkxFX0FHR1JFR0FUSU9OCiNpZm5kZWYgWk1fRU5BQkxFX0ZXX0JBX1JFVFJBTlNNSVNTSU9OIC8vZGlzYWJsZSBCQVcKICAgIEJBVyA9IHpmd01lbUFsbG9jYXRlKGRldiwgc2l6ZW9mKHN0cnVjdCBiYXdfZW5hYmxlcikpOwogICAgaWYoIUJBVykKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBCQVctPmluaXQgPSB6ZkJhd0luaXQ7CiAgICBCQVctPmluaXQoZGV2KTsKI2VuZGlmIC8vZGlzYWJsZSBCQVcKI2VuZGlmCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZBZ2dHZXRTdGEgICAgICAgICAgICAgICAgICovCi8qICAgICAgcmV0dXJuIFNUQSBBSUQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgdGFrZSBidWYgYXMgaW5wdXQsIHVzZSB0aGUgZGVzdCBhZGRyZXNzIG9mIGJ1ZiBhcyBpbmRleCB0byAgICAgICovCi8qICAgICAgc2VhcmNoIFNUQSBBSUQuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYnVmIDogYnVmZmVyIGZvciBvbmUgcGFydGljdWxhciBwYWNrZXQgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIE9VVFBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgQUlEICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEFVVEhPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgSG9uZGEgICAgICAgICAgICAgICBaeURBUyBUZWNobm9sb2d5IENvcnBvcmF0aW9uICAgIDIwMDYuMTEgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKCnUxNl90IHpmQWdnR2V0U3RhKHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZikKewogICAgdTE2X3QgaWQ7CiAgICB1MTZfdCBkc3RbM107CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgZHN0WzBdID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIGJ1ZiwgMCk7CiAgICBkc3RbMV0gPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCAyKTsKICAgIGRzdFsyXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDQpOwoKICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgaWYod2QtPndsYW5Nb2RlID09IFpNX01PREVfQVApIHsKICAgICAgICBpZCA9IHpmQXBGaW5kU3RhKGRldiwgZHN0KTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGlkID0gMDsKICAgIH0KICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgojaWYgWk1fQUdHX0ZQR0FfREVCVUcKICAgIGlkID0gMDsKI2VuZGlmCgogICAgcmV0dXJuIGlkOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgRlVOQ1RJT04gREVTQ1JJUFRJT04gICAgICAgICAgICAgICAgICB6ZkFnZ1R4R2V0UXVldWUgICAgICAgICAgICAgKi8KLyogICAgICByZXR1cm4gUXVldWUgUG9vbCBpbmRleC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICB0YWtlIGFpZCBhcyBpbnB1dCwgbG9vayBmb3IgdGhlIHF1ZXVlIGluZGV4IGFzc29jaWF0ZWQgICAgICAgICAgKi8KLyogICAgICB3aXRoIHRoaXMgYWlkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgSU5QVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBkZXYgOiBkZXZpY2UgcG9pbnRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBhaWQgOiBhc3NvY2lhdGVkIGlkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgT1VUUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBRdWV1ZSBudW1iZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgQVVUSE9SICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBIb25kYSAgICAgICAgICAgICAgIFp5REFTIFRlY2hub2xvZ3kgQ29ycG9yYXRpb24gICAgMjAwNi4xMSAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KVElEX1RYIHpmQWdnVHhHZXRRdWV1ZSh6ZGV2X3QqIGRldiwgdTE2X3QgYWlkLCB1MTZfdCB0aWQpCnsKICAgIC8vdTE2X3QgICBpOwogICAgVElEX1RYICB0aWRfdHg7CiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgLy96bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIC8qCiAgICAgKiBub3QgYSBTVEEgYWlkCiAgICAgKi8KICAgIGlmICgweGZmZmYgPT0gYWlkKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIC8vem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICB0aWRfdHggPSB3ZC0+YWdnU3RhW2FpZF0udGlkX3R4W3RpZF07CiAgICBpZiAoIXRpZF90eCkgcmV0dXJuIE5VTEw7CiAgICBpZiAoMCA9PSB0aWRfdHgtPmFnZ1FFbmFibGVkKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIC8vem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICByZXR1cm4gdGlkX3R4Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmQWdnVHhOZXdRdWV1ZSAgICAgICAgICAgICAqLwovKiAgICAgIHJldHVybiBRdWV1ZSBQb29sIGluZGV4LiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIHRha2UgYWlkIGFzIGlucHV0LCBmaW5kIGEgbmV3IHF1ZXVlIGZvciB0aGlzIGFpZC4gICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiA6IGRldmljZSBwb2ludGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGFpZCA6IGFzc29jaWF0ZWQgaWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFF1ZXVlIG51bWJlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIEhvbmRhICAgICAgICAgICAgICAgWnlEQVMgVGVjaG5vbG9neSBDb3Jwb3JhdGlvbiAgICAyMDA2LjEyICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpUSURfVFggemZBZ2dUeE5ld1F1ZXVlKHpkZXZfdCogZGV2LCB1MTZfdCBhaWQsIHUxNl90IHRpZCwgemJ1Zl90KiBidWYpCnsKICAgIHUxNl90ICAgaTsKICAgIFRJRF9UWCAgdGlkX3R4PU5VTEw7CiAgICB1MTZfdCAgIGFjID0gemNVcFRvQWNbdGlkJjB4N10gJiAweDM7CiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCiAgICAvKgogICAgICogbm90IGEgU1RBIGFpZAogICAgICovCiAgICBpZiAoMHhmZmZmID09IGFpZCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgIC8qCiAgICAgKiBmaW5kIG9uZSBuZXcgcXVldWUgZm9yIHN0YQogICAgICovCiAgICBmb3IgKGk9MDsgaTxaTV9BR0dfUE9PTF9TSVpFOyBpKyspCiAgICB7CiAgICAgICAgaWYgKHdkLT5hZ2dRUG9vbFtpXS0+YWdnUUVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIHRoaXMgcSBpcyBlbmFibGVkCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgdGlkX3R4ID0gd2QtPmFnZ1FQb29sW2ldOwogICAgICAgICAgICB0aWRfdHgtPmFnZ1FFbmFibGVkID0gMTsKICAgICAgICAgICAgdGlkX3R4LT5hZ2dRU1RBID0gYWlkOwogICAgICAgICAgICB0aWRfdHgtPmFjID0gYWM7CiAgICAgICAgICAgIHRpZF90eC0+dGlkID0gdGlkOwogICAgICAgICAgICB0aWRfdHgtPmFnZ0hlYWQgPSB0aWRfdHgtPmFnZ1RhaWwgPSB0aWRfdHgtPnNpemUgPSAwOwogICAgICAgICAgICB0aWRfdHgtPmFnZ1JlYWR5ID0gMDsKICAgICAgICAgICAgd2QtPmFnZ1N0YVthaWRdLnRpZF90eFt0aWRdID0gdGlkX3R4OwogICAgICAgICAgICB0aWRfdHgtPmRzdFswXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDApOwogICAgICAgICAgICB0aWRfdHgtPmRzdFsxXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDIpOwogICAgICAgICAgICB0aWRfdHgtPmRzdFsyXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICByZXR1cm4gdGlkX3R4Owp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZBZ2dUeEVucXVldWUgICAgICAgICAgICAgICovCi8qICAgICAgcmV0dXJuIFN0YXR1cyBjb2RlIFpNX1NVQ0NFU1Mgb3IgZXJyb3IgY29kZSAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgdGFrZSAoYWlkLGFjLHFudW0sYnVmKSBhcyBpbnB1dCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYWlkIDogYXNzb2NpYXRlZCBpZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYWMgIDogYWNjZXNzIGNhdGVnb3J5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgcW51bTogdGhlIHF1ZXVlIG51bWJlciB0byB3aGljaCB3aWxsIGJlIGVucXVldWVkICAgICAgICAgICAgICAgICovCi8qICAgICAgYnVmIDogdGhlIHBhY2tldCB0byBiZSBxdWV1ZWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIE9VVFBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgc3RhdHVzIGNvZGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEFVVEhPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgSG9uZGEgICAgICAgICAgICAgICBBdGhlcm9zIENvbW11bmljYXRpb25zLCBJTkMuICAgIDIwMDYuMTIgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnUxNl90IHpmQWdnVHhFbnF1ZXVlKHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZiwgdTE2X3QgYWlkLCBUSURfVFggdGlkX3R4KQp7CiAgICAvL3UxNl90ICAgcWxlbiwgZnJhbWVMZW47CiAgICB1MzJfdCAgIHRpbWU7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICB0aWRfdHgtPnNpemUgPSB6bV9hZ2dfcWxlbihkZXYsIHRpZF90eC0+YWdnSGVhZCwgdGlkX3R4LT5hZ2dUYWlsKTsKCiAgICBpZiAodGlkX3R4LT5zaXplIDwgKFpNX0FHR1FfU0laRSAtIDIpKQogICAgewogICAgICAgIC8qIFF1ZXVlIG5vdCBmdWxsICovCgoKICAgICAgICAvKgogICAgICAgICAqIGJ1ZmZlciBjb3B5CiAgICAgICAgICogaW4gemZ3QnVmRnJlZSB3aWxsIHJldHVybiBhIG5kaXNtc2VuZGNvbXBsZXRlCiAgICAgICAgICogdG8gcmVzb2x2ZSB0aGUgc3luY2hyb25pemUgcHJvYmxlbSBpbiBhZ2dyZWdhdGUKICAgICAgICAgKi8KCiAgICAgICAgdThfdCAgICBzZW5kQ29tcGxldGUgPSAwOwoKICAgICAgICB0aWRfdHgtPmFnZ3Z0eHFbdGlkX3R4LT5hZ2dIZWFkXS5idWYgPSBidWY7CiAgICAgICAgdGltZSA9IHptX2FnZ19HZXRUaW1lKCk7CiAgICAgICAgdGlkX3R4LT5hZ2d2dHhxW3RpZF90eC0+YWdnSGVhZF0uYXJyaXZhbFRpbWUgPSB0aW1lOwogICAgICAgIHRpZF90eC0+YWdndnR4cVt0aWRfdHgtPmFnZ0hlYWRdLmJhd19yZXRyYW5zbWl0ID0gMDsKCiAgICAgICAgdGlkX3R4LT5hZ2dIZWFkID0gKCh0aWRfdHgtPmFnZ0hlYWQgKyAxKSAmIFpNX0FHR1FfU0laRV9NQVNLKTsKICAgICAgICB0aWRfdHgtPmxhc3RBcnJpdmFsID0gdGltZTsKICAgICAgICB0aWRfdHgtPnNpemUrKzsKICAgICAgICB0aWRfdHgtPnNpemUgPSB6bV9hZ2dfcWxlbihkZXYsIHRpZF90eC0+YWdnSGVhZCwgdGlkX3R4LT5hZ2dUYWlsKTsKICAgICAgICBpZiAoYnVmICYmICh0aWRfdHgtPnNpemUgPCAoWk1fQUdHUV9TSVpFIC0gMTApKSkgewogICAgICAgICAgICB0aWRfdHgtPmNvbXBsZXRlID0gdGlkX3R4LT5hZ2dIZWFkOwogICAgICAgICAgICBzZW5kQ29tcGxldGUgPSAxOwogICAgICAgIH0KICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgICAgICBpZiAoIURFU1RRLmV4aXN0KGRldiwgMCwgdGlkX3R4LT5hYywgdGlkX3R4LCBOVUxMKSkgewogICAgICAgICAgICBERVNUUS5pbnNlcnQoZGV2LCAwLCB0aWRfdHgtPmFjLCB0aWRfdHgsIE5VTEwpOwogICAgICAgIH0KCiAgICAgICAgem1fbXNnMV9hZ2coWk1fTFZfMCwgInRpZF90eC0+c2l6ZT0iLCB0aWRfdHgtPnNpemUpOwogICAgICAgIC8vem1fZGVidWdfbXNnMSgidGlkX3R4LT5zaXplPSIsIHRpZF90eC0+c2l6ZSk7CgogICAgICAgIGlmIChidWYgJiYgc2VuZENvbXBsZXRlICYmIHdkLT56ZmNiU2VuZENvbXBsZXRlSW5kaWNhdGlvbikgewogICAgICAgICAgICAvL3ptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgIHdkLT56ZmNiU2VuZENvbXBsZXRlSW5kaWNhdGlvbihkZXYsIGJ1Zik7CiAgICAgICAgfQoKICAgICAgICAvKmlmICh0aWRfdHgtPnNpemUgPj0gMTYgJiYgemZIcEdldEZyZWVUeGRDb3VudChkZXYpID4gMjApCiAgICAgICAgICAgIHpmQWdnVHhTZW5kKGRldiwgemZIcEdldEZyZWVUeGRDb3VudChkZXYpLCB0aWRfdHgpOwogICAgICAgICovCiAgICAgICAgcmV0dXJuIFpNX1NVQ0NFU1M7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgem1fbXNnMV9hZ2coWk1fTFZfMCwgImNhbid0IGVucXVldWUsIHRpZF90eC0+c2l6ZT0iLCB0aWRfdHgtPnNpemUpOwogICAgICAgIC8qCiAgICAgICAgICogUXVldWUgRnVsbAogICAgICAgICAqLwoKICAgICAgICAvKgogICAgICAgICAqIHptX21zZzFfYWdnKFpNX0xWXzAsICJRdWV1ZSBmdWxsLCBxbnVtID0gIiwgcW51bSk7CiAgICAgICAgICogd2QtPmNvbW1UYWxseS50eFFvc0Ryb3BDb3VudFthY10rKzsKICAgICAgICAgKiB6ZndCdWZGcmVlKGRldiwgYnVmLCBaTV9TVUNDRVNTKTsKICAgICAgICAgKiB6bV9tc2cxX2FnZyhaTV9MVl8xLCAiUGFja2V0IGRpc2NhcmRlZCwgVlRYUSBmdWxsLCBhYz0iLCBhYyk7CiAgICAgICAgICoKICAgICAgICAgKiByZXR1cm4gWk1fRVJSX0VYQ0VFRF9QUklPUklUWV9USFJFU0hPTEQ7CiAgICAgICAgICovCiAgICB9CgogICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICBpZiAoIURFU1RRLmV4aXN0KGRldiwgMCwgdGlkX3R4LT5hYywgdGlkX3R4LCBOVUxMKSkgewogICAgICAgICAgICBERVNUUS5pbnNlcnQoZGV2LCAwLCB0aWRfdHgtPmFjLCB0aWRfdHgsIE5VTEwpOwogICAgfQoKICAgIHJldHVybiBaTV9FUlJfRVhDRUVEX1BSSU9SSVRZX1RIUkVTSE9MRDsKfQoKdTE2X3QgICAgemZBZ2dEZXN0RXhpc3QoemRldl90KiBkZXYsIHUxNl90IFF0eXBlLCB1MTZfdCBhYywgVElEX1RYIHRpZF90eCwgdm9pZCogdnR4cSkgewogICAgc3RydWN0IGRlc3QqIGRlc3Q7CiAgICB1MTZfdCAgIGV4aXN0ID0gMDsKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICBpZiAoIURFU1RRLkhlYWRbYWNdKSB7CiAgICAgICAgZXhpc3QgPSAwOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgZGVzdCA9IERFU1RRLkhlYWRbYWNdOwogICAgICAgIGlmIChkZXN0LT50aWRfdHggPT0gdGlkX3R4KSB7CiAgICAgICAgICAgIGV4aXN0ID0gMTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHdoaWxlIChkZXN0LT5uZXh0ICE9IERFU1RRLkhlYWRbYWNdKSB7CiAgICAgICAgICAgICAgICBkZXN0ID0gZGVzdC0+bmV4dDsKICAgICAgICAgICAgICAgIGlmIChkZXN0LT50aWRfdHggPT0gdGlkX3R4KXsKICAgICAgICAgICAgICAgICAgICBleGlzdCA9IDE7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICByZXR1cm4gZXhpc3Q7Cn0KCnZvaWQgICAgemZBZ2dEZXN0SW5zZXJ0KHpkZXZfdCogZGV2LCB1MTZfdCBRdHlwZSwgdTE2X3QgYWMsIFRJRF9UWCB0aWRfdHgsIHZvaWQqIHZ0eHEpCnsKICAgIHN0cnVjdCBkZXN0KiBuZXdfZGVzdDsKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIG5ld19kZXN0ID0gemZ3TWVtQWxsb2NhdGUoZGV2LCBzaXplb2Yoc3RydWN0IGRlc3QpKTsKICAgIGlmKCFuZXdfZGVzdCkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBuZXdfZGVzdC0+UXR5cGUgPSBRdHlwZTsKICAgIG5ld19kZXN0LT50aWRfdHggPSB0aWRfdHg7CiAgICBpZiAoMCA9PSBRdHlwZSkKICAgICAgICBuZXdfZGVzdC0+dGlkX3R4ID0gdGlkX3R4OwogICAgZWxzZQogICAgICAgIG5ld19kZXN0LT52dHhxID0gdnR4cTsKICAgIGlmICghREVTVFEuSGVhZFthY10pIHsKCiAgICAgICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICBuZXdfZGVzdC0+bmV4dCA9IG5ld19kZXN0OwogICAgICAgIERFU1RRLkhlYWRbYWNdID0gREVTVFEuZGVzdFthY10gPSBuZXdfZGVzdDsKICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgfQogICAgZWxzZSB7CgogICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgbmV3X2Rlc3QtPm5leHQgPSBERVNUUS5kZXN0W2FjXS0+bmV4dDsKICAgICAgICBERVNUUS5kZXN0W2FjXS0+bmV4dCA9IG5ld19kZXN0OwogICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICB9CgoKICAgIC8vREVTVFEuc2l6ZVthY10rKzsKICAgIHJldHVybjsKfQoKdm9pZCAgICB6ZkFnZ0Rlc3REZWxldGUoemRldl90KiBkZXYsIHUxNl90IFF0eXBlLCBUSURfVFggdGlkX3R4LCB2b2lkKiB2dHhxKQp7CiAgICBzdHJ1Y3QgZGVzdCogZGVzdCwgKnRlbXA7CiAgICB1MTZfdCAgIGk7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgIGlmICh3ZC0+ZGVzdExvY2spIHsKICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgIHJldHVybjsKICAgIH0KCgogICAgLy96bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwogICAgZm9yIChpPTA7IGk8NDsgaSsrKSB7CiAgICAgICAgaWYgKCFERVNUUS5IZWFkW2ldKSBjb250aW51ZTsKICAgICAgICBkZXN0ID0gREVTVFEuSGVhZFtpXTsKICAgICAgICBpZiAoIWRlc3QpIGNvbnRpbnVlOwoKCiAgICAgICAgd2hpbGUgKGRlc3QgJiYgKGRlc3QtPm5leHQgIT0gREVTVFEuSGVhZFtpXSkpIHsKICAgICAgICAgICAgaWYgKFF0eXBlID09IDAgJiYgZGVzdC0+bmV4dC0+dGlkX3R4ID09IHRpZF90eCl7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoUXR5cGUgPT0gMSAmJiBkZXN0LT5uZXh0LT52dHhxID09IHZ0eHEpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlc3QgPSBkZXN0LT5uZXh0OwogICAgICAgIH0KCiAgICAgICAgaWYgKChRdHlwZSA9PSAwICYmIGRlc3QtPm5leHQtPnRpZF90eCA9PSB0aWRfdHgpIHx8IChRdHlwZSA9PSAxICYmIGRlc3QtPm5leHQtPnZ0eHEgPT0gdnR4cSkpIHsKCiAgICAgICAgICAgIHRpZF90eC0+c2l6ZSA9IHptX2FnZ19xbGVuKGRldiwgdGlkX3R4LT5hZ2dIZWFkLCB0aWRfdHgtPmFnZ1RhaWwpOwogICAgICAgICAgICBpZiAodGlkX3R4LT5zaXplKSB7CiAgICAgICAgICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghREVTVFEuSGVhZFtpXSkgewogICAgICAgICAgICAgICAgdGVtcCA9IE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB0ZW1wID0gZGVzdC0+bmV4dDsKICAgICAgICAgICAgICAgIGlmICh0ZW1wID09IGRlc3QpIHsKICAgICAgICAgICAgICAgICAgICBERVNUUS5IZWFkW2ldID0gREVTVFEuZGVzdFtpXSA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgLy9ERVNUUS5zaXplW2ldID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGRlc3QtPm5leHQgPSBkZXN0LT5uZXh0LT5uZXh0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGVtcCA9PSBOVUxMKQogICAgICAgICAgICAgICAgey8qIGRvIG5vdGhpbmcgKi99IC8vemZ3TWVtRnJlZShkZXYsIHRlbXAsIHNpemVvZihzdHJ1Y3QgZGVzdCkpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB6ZndNZW1GcmVlKGRldiwgdGVtcCwgc2l6ZW9mKHN0cnVjdCBkZXN0KSk7CgogICAgICAgICAgICAvKnptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgIGlmIChERVNUUS5zaXplW2ldID4gMCkKICAgICAgICAgICAgICAgIERFU1RRLnNpemVbaV0tLTsKICAgICAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICAgICAgKi8KICAgICAgICB9CgogICAgfQogICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgIHJldHVybjsKfQoKdm9pZCAgICB6ZkFnZ0Rlc3RJbml0KHpkZXZfdCogZGV2KQp7CiAgICB1MTZfdCBpOwogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCiAgICBmb3IgKGk9MDsgaTw0OyBpKyspIHsKICAgICAgICAvL3dkLT5kZXN0US5IZWFkW2ldLm5leHQgPSB3ZC0+ZGVzdFEuSGVhZFtpXTsKICAgICAgICAvL3dkLT5kZXN0US5kZXN0W2ldID0gd2QtPmRlc3RRLkhlYWRbaV07CiAgICAgICAgLy9ERVNUUS5zaXplW2ldID0gMDsKICAgICAgICBERVNUUS5IZWFkW2ldID0gTlVMTDsKICAgIH0KICAgIERFU1RRLmluc2VydCAgPSB6ZkFnZ0Rlc3RJbnNlcnQ7CiAgICBERVNUUS5kZWxldGUgID0gemZBZ2dEZXN0RGVsZXRlOwogICAgREVTVFEuaW5pdCAgICA9IHpmQWdnRGVzdEluaXQ7CiAgICBERVNUUS5nZXROZXh0ID0gemZBZ2dEZXN0R2V0TmV4dDsKICAgIERFU1RRLmV4aXN0ICAgPSB6ZkFnZ0Rlc3RFeGlzdDsKICAgIERFU1RRLnBwcmkgPSAwOwogICAgcmV0dXJuOwp9CgpzdHJ1Y3QgZGVzdCogemZBZ2dEZXN0R2V0TmV4dCh6ZGV2X3QqIGRldiwgdTE2X3QgYWMpCnsKICAgIHN0cnVjdCBkZXN0ICpkZXN0ID0gTlVMTDsKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICBpZiAoREVTVFEuZGVzdFthY10pIHsKICAgICAgICBkZXN0ID0gREVTVFEuZGVzdFthY107CiAgICAgICAgREVTVFEuZGVzdFthY10gPSBERVNUUS5kZXN0W2FjXS0+bmV4dDsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGRlc3QgPSBOVUxMOwogICAgfQogICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICByZXR1cm4gZGVzdDsKfQoKI2lmZGVmIFpNX0VOQUJMRV9BR0dSRUdBVElPTgojaWZuZGVmIFpNX0VOQUJMRV9GV19CQV9SRVRSQU5TTUlTU0lPTiAvL2Rpc2FibGUgQkFXCnUxNl90ICAgemZBZ2dUaWRUeEluc2VydEhlYWQoemRldl90KiBkZXYsIHN0cnVjdCBidWZJbmZvICpidWZfaW5mbyxUSURfVFggdGlkX3R4KQp7CiAgICB6YnVmX3QqIGJ1ZjsKICAgIHUzMl90IHRpbWU7CiAgICBzdHJ1Y3QgYmF3X2hlYWRlciAqYmF3X2hlYWRlcjsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCgogICAgYnVmID0gYnVmX2luZm8tPmJ1ZjsKCiAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgdGlkX3R4LT5zaXplID0gem1fYWdnX3FsZW4oZGV2LCB0aWRfdHgtPmFnZ0hlYWQsIHRpZF90eC0+YWdnVGFpbCk7CiAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgIGlmICh0aWRfdHgtPnNpemUgPj0gKFpNX0FHR1FfU0laRSAtIDIpKSB7CiAgICAgICAgemZ3QnVmRnJlZShkZXYsIGJ1ZiwgWk1fU1VDQ0VTUyk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgIHRpZF90eC0+YWdnVGFpbCA9ICh0aWRfdHgtPmFnZ1RhaWwgPT0gMCk/IFpNX0FHR1FfU0laRV9NQVNLOiB0aWRfdHgtPmFnZ1RhaWwgLSAxOwogICAgdGlkX3R4LT5hZ2d2dHhxW3RpZF90eC0+YWdnVGFpbF0uYnVmID0gYnVmOwogICAgLy90aW1lID0gem1fYWdnX0dldFRpbWUoKTsKICAgIHRpZF90eC0+YWdndnR4cVt0aWRfdHgtPmFnZ1RhaWxdLmFycml2YWxUaW1lID0gYnVmX2luZm8tPnRpbWVzdGFtcDsKICAgIHRpZF90eC0+YWdndnR4cVt0aWRfdHgtPmFnZ1RhaWxdLmJhd19yZXRyYW5zbWl0ID0gYnVmX2luZm8tPmJhd19yZXRyYW5zbWl0OwoKICAgIGJhd19oZWFkZXIgPSAmdGlkX3R4LT5hZ2d2dHhxW3RpZF90eC0+YWdnVGFpbF0uYmF3X2hlYWRlcjsKICAgIGJhd19oZWFkZXItPmhlYWRlckxlbiAgID0gYnVmX2luZm8tPmJhd19oZWFkZXItPmhlYWRlckxlbjsKICAgIGJhd19oZWFkZXItPm1pY0xlbiAgICAgID0gYnVmX2luZm8tPmJhd19oZWFkZXItPm1pY0xlbjsKICAgIGJhd19oZWFkZXItPnNuYXBMZW4gICAgID0gYnVmX2luZm8tPmJhd19oZWFkZXItPnNuYXBMZW47CiAgICBiYXdfaGVhZGVyLT5yZW1vdmVMZW4gICA9IGJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5yZW1vdmVMZW47CiAgICBiYXdfaGVhZGVyLT5rZXlJZHggICAgICA9IGJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5rZXlJZHg7CiAgICB6ZndNZW1vcnlDb3B5KCh1OF90ICopYmF3X2hlYWRlci0+aGVhZGVyLCAodThfdCAqKWJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5oZWFkZXIsIDU4KTsKICAgIHpmd01lbW9yeUNvcHkoKHU4X3QgKiliYXdfaGVhZGVyLT5taWMgICAsICh1OF90ICopYnVmX2luZm8tPmJhd19oZWFkZXItPm1pYyAgICwgOCk7CiAgICB6ZndNZW1vcnlDb3B5KCh1OF90ICopYmF3X2hlYWRlci0+c25hcCAgLCAodThfdCAqKWJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5zbmFwICAsIDgpOwoKICAgIHRpZF90eC0+c2l6ZSsrOwogICAgdGlkX3R4LT5zaXplID0gem1fYWdnX3FsZW4oZGV2LCB0aWRfdHgtPmFnZ0hlYWQsIHRpZF90eC0+YWdnVGFpbCk7CiAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgIC8vdGlkX3R4LT5sYXN0QXJyaXZhbCA9IHRpbWU7CiAgICBpZiAoMSA9PSB0aWRfdHgtPnNpemUpIHsKICAgICAgICBERVNUUS5pbnNlcnQoZGV2LCAwLCB0aWRfdHgtPmFjLCB0aWRfdHgsIE5VTEwpOwogICAgfQoKCiAgICB6bV9tc2cxX2FnZyhaTV9MVl8wLCAiMHhDMjppbnNlcnRIZWFkLCB0aWRfdHgtPnNpemU9IiwgdGlkX3R4LT5zaXplKTsKCiAgICByZXR1cm4gVFJVRTsKfQojZW5kaWYgLy9kaXNhYmxlIEJBVwojZW5kaWYKCnZvaWQgICAgemZpVHhDb21wbGV0ZSh6ZGV2X3QqIGRldikKewoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICAvL3ptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgaWYoICh3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9BUCkgfHwKICAgICAgICAod2QtPndsYW5Nb2RlID09IFpNX01PREVfSU5GUkFTVFJVQ1RVUkUgJiYgd2QtPnN0YS5FbmFibGVIVCkgfHwKICAgICAgICAod2QtPndsYW5Nb2RlID09IFpNX01PREVfUFNFVURPKSApIHsKICAgICAgICB6ZkFnZ1R4U2NoZWR1bGVyKGRldiwgMCk7CiAgICB9CgogICAgcmV0dXJuOwp9CgpUSURfVFggIHpmQWdnVHhSZWFkeSh6ZGV2X3QqIGRldikgewogICAgLy9zdHJ1Y3QgZGVzdCogZGVzdDsKICAgIHUxNl90ICAgaTsKICAgIFRJRF9UWCAgdGlkX3R4ID0gTlVMTDsKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICBmb3IgKGk9MDsgaTxaTV9BR0dfUE9PTF9TSVpFOyBpKyspCiAgICB7CiAgICAgICAgaWYgKHdkLT5hZ2dRUG9vbFtpXS0+YWdnUUVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICBpZiAod2QtPmFnZ1FQb29sW2ldLT5zaXplID49IDE2KSB7CiAgICAgICAgICAgICAgICB0aWRfdHggPSB3ZC0+YWdnUVBvb2xbaV07CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICB9CiAgICB9CiAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgcmV0dXJuIHRpZF90eDsKfQoKdTE2X3QgICB6ZkFnZ1ZhbGlkVGlkVHgoemRldl90KiBkZXYsIFRJRF9UWCB0aWRfdHgpIHsKICAgIHUxNl90ICAgaSwgdmFsaWQgPSAwOwogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgIGZvciAoaT0wOyBpPFpNX0FHR19QT09MX1NJWkU7IGkrKykKICAgIHsKICAgICAgICBpZiAod2QtPmFnZ1FQb29sW2ldID09IHRpZF90eCkKICAgICAgICB7CiAgICAgICAgICAgIHZhbGlkID0gMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgIH0KICAgIH0KICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgcmV0dXJuIHZhbGlkOwp9Cgp2b2lkICAgIHpmQWdnVHhTY2hlZHVsZXIoemRldl90KiBkZXYsIHU4X3QgU2NhbkFuZENsZWFyKQp7CiAgICBUSURfVFggIHRpZF90eCA9IE5VTEw7CiAgICB2b2lkKiAgIHZ0eHE7CiAgICBzdHJ1Y3QgZGVzdCogZGVzdDsKICAgIHpidWZfdCogIGJ1ZjsKICAgIHUzMl90IHR4cWwsIG1pbl90eHFsOwogICAgLy91MTZfdCBhZ2dyX3NpemUgPSAxOwogICAgdTE2X3QgdHhxX3RocmVzaG9sZDsKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIGlmICghd2QtPmFnZ0luaXRpYXRlZCkKICAgIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyogZGVidWcgKi8KICAgIHR4cWwgPSBUWFFMOwogICAgbWluX3R4cWwgPSBBR0dfTUlOX1RYUUw7CgogICAgaWYod2QtPnR4cV90aHJlc2hvbGQpCiAgICAgICAgdHhxX3RocmVzaG9sZCA9IHdkLT50eHFfdGhyZXNob2xkOwogICAgZWxzZQogICAgICAgIHR4cV90aHJlc2hvbGQgPSBBR0dfTUlOX1RYUUw7CgogICAgdGlkX3R4ID0gemZBZ2dUeFJlYWR5KGRldik7CiAgICBpZiAodGlkX3R4KSBTY2FuQW5kQ2xlYXIgPSAwOwogICAgd2hpbGUgKHpmSHBHZXRGcmVlVHhkQ291bnQoZGV2KSA+IDIwICYmIChUWFFMIDwgdHhxX3RocmVzaG9sZCB8fCB0aWRfdHgpKSB7CiAgICAvL3doaWxlICh6ZkhwR2V0RnJlZVR4ZENvdW50KGRldikgPiAyMCAmJiAoU2NhbkFuZENsZWFyIHx8IHRpZF90eCkpIHsKICAgIC8vd2hpbGUgKFRYUUwgPCB0eHFfdGhyZXNob2xkKSB7CiAgICAgICAgdTE2X3QgaTsKICAgICAgICB1OF90IGFjOwogICAgICAgIHM4X3QgZGVzdFFfY291bnQgPSAwOwogICAgLy93aGlsZSAoKHpmSHBHZXRGcmVlVHhkQ291bnQoZGV2KSkgPiAzMikgewoKICAgICAgICAvL0RiZ1ByaW50KCJ6ZkFnZ1R4U2NoZWR1bGVyOiBpbiB3aGlsZSBsb29wIik7CiAgICAgICAgZm9yIChpPTA7IGk8NDsgaSsrKSB7CiAgICAgICAgICAgIGlmIChERVNUUS5IZWFkW2ldKSBkZXN0UV9jb3VudCsrOwogICAgICAgIH0KICAgICAgICBpZiAoMCA+PSBkZXN0UV9jb3VudCkgYnJlYWs7CgogICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgYWMgPSBwcmlbREVTVFEucHByaV07IERFU1RRLnBwcmkgPSAoREVTVFEucHByaSArIDEpICUgMTA7CiAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICAgICAgZm9yIChpPTA7IGk8MTA7IGkrKyl7CiAgICAgICAgICAgIGlmKERFU1RRLkhlYWRbYWNdKSBicmVhazsKCiAgICAgICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgIGFjID0gcHJpW0RFU1RRLnBwcmldOyBERVNUUS5wcHJpID0gKERFU1RRLnBwcmkgKyAxKSAlIDEwOwogICAgICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgIH0KICAgICAgICBpZiAoaSA9PSAxMCkgYnJlYWs7CiAgICAgICAgLy9EYmdQcmludCgiemZBZ2dUeFNjaGVkdWxlcjogaGF2ZSBkZXN0IFEiKTsKICAgICAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgIHdkLT5kZXN0TG9jayA9IDE7CiAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICAgICAgZGVzdCA9IERFU1RRLmdldE5leHQoZGV2LCBhYyk7CiAgICAgICAgaWYgKCFkZXN0KSB7CiAgICAgICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgIHdkLT5kZXN0TG9jayA9IDA7CiAgICAgICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgICAgICAgICBEYmdQcmludCgiYnVnIHJlcG9ydCEgREVTVFEuZ2V0TmV4dCBnb3Qgbm90aGluZyEiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGlmIChkZXN0LT5RdHlwZSA9PSAwKSB7CiAgICAgICAgICAgIHRpZF90eCA9IGRlc3QtPnRpZF90eDsKCiAgICAgICAgICAgIC8vRGJnUHJpbnQoInpmQWdnVHhTY2hlZHVsZXI6IGhhdmUgdGlkX3R4IFEiKTsKCiAgICAgICAgICAgIGlmKHRpZF90eCAmJiB6ZkFnZ1ZhbGlkVGlkVHgoZGV2LCB0aWRfdHgpKQogICAgICAgICAgICAgICAgdGlkX3R4LT5zaXplID0gem1fYWdnX3FsZW4oZGV2LCB0aWRfdHgtPmFnZ0hlYWQsIHRpZF90eC0+YWdnVGFpbCk7CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICAgICAgICAgIHdkLT5kZXN0TG9jayA9IDA7CiAgICAgICAgICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgICAgICAgICAgICAgIHRpZF90eCA9IHpmQWdnVHhSZWFkeShkZXYpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgIHdkLT5kZXN0TG9jayA9IDA7CiAgICAgICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgIC8vem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICAgICAgaWYgKHRpZF90eCAmJiAhdGlkX3R4LT5zaXplKSB7CgogICAgICAgICAgICAgICAgLy96bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgICAgICAgICAgLy9ERVNUUS5kZWxldGUoZGV2LCAwLCB0aWRfdHgsIE5VTEwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYod2QtPmFnZ1N0YXRlID09IDApewogICAgICAgICAgICAgICAgLy93ZC0+YWdnU3RhdGUgPSAxOwogICAgICAgICAgICAgICAgLy96bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgICAgICAgICAgemZBZ2dUeFNlbmQoZGV2LCB6ZkhwR2V0RnJlZVR4ZENvdW50KGRldiksIHRpZF90eCk7CiAgICAgICAgICAgICAgICAvL3dkLT5hZ2dTdGF0ZSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvL3ptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgdnR4cSA9IGRlc3QtPnZ0eHE7CiAgICAgICAgICAgIGJ1ZiA9IHpmR2V0VnR4cShkZXYsIGFjKTsKICAgICAgICAgICAgem1fYXNzZXJ0KCBidWYgIT0gMCApOwoKICAgICAgICAgICAgemZUeFNlbmRFdGgoZGV2LCBidWYsIDAsIFpNX0VYVEVSTkFMX0FMTE9DX0JVRiwgMCk7CgogICAgICAgIH0KICAgICAgICAvKmZsdXNoIGFsbCBidXQgPCAxNiBmcmFtZXMgaW4gdGlkX3R4IHRvIFRYUSovCiAgICAgICAgdGlkX3R4ID0gemZBZ2dUeFJlYWR5KGRldik7CiAgICB9CgogICAgLyp3aGlsZSAoKHpmSHBHZXRGcmVlVHhkQ291bnQoZGV2KSkgPiAzMikgewogICAgLy93aGlsZSAoKHpmSHBHZXRGcmVlVHhkQ291bnQoZGV2KSkgPiAzMikgewoKICAgICAgICBkZXN0UV9jb3VudCA9IDA7CiAgICAgICAgZm9yIChpPTA7IGk8NDsgaSsrKSBkZXN0UV9jb3VudCArPSB3ZC0+ZGVzdFEuc2l6ZVtpXTsKICAgICAgICBpZiAoMCA+PSBkZXN0UV9jb3VudCkgYnJlYWs7CgogICAgICAgIGFjID0gcHJpW3dkLT5kZXN0US5wcHJpXTsgd2QtPmRlc3RRLnBwcmkgPSAod2QtPmRlc3RRLnBwcmkgKyAxKSAlIDEwOwogICAgICAgIGZvciAoaT0wOyBpPDEwOyBpKyspewogICAgICAgICAgICBpZih3ZC0+ZGVzdFEuc2l6ZVthY10hPTApIGJyZWFrOwogICAgICAgICAgICBhYyA9IHByaVt3ZC0+ZGVzdFEucHByaV07IHdkLT5kZXN0US5wcHJpID0gKHdkLT5kZXN0US5wcHJpICsgMSkgJSAxMDsKICAgICAgICB9CiAgICAgICAgaWYgKGkgPT0gMTApIGJyZWFrOwogICAgICAgIGRlc3QgPSB3ZC0+ZGVzdFEuZ2V0TmV4dChkZXYsIGFjKTsKICAgICAgICBpZiAoZGVzdC0+UXR5cGUgPT0gMCkgewogICAgICAgICAgICB0aWRfdHggPSBkZXN0LT50aWRfdHg7CiAgICAgICAgICAgIHRpZF90eC0+c2l6ZSA9IHptX2FnZ19xbGVuKGRldiwgdGlkX3R4LT5hZ2dIZWFkLCB0aWRfdHgtPmFnZ1RhaWwpOwogICAgICAgICAgICBpZiAoIXRpZF90eC0+c2l6ZSkgewogICAgICAgICAgICAgICAgd2QtPmRlc3RRLmRlbGV0ZShkZXYsIDAsIHRpZF90eCwgTlVMTCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKCh3ZC0+YWdnU3RhdGUgPT0gMCkgJiYgKHRpZF90eC0+c2l6ZSA+PSAxNikpewogICAgICAgICAgICAgICAgemZBZ2dUeFNlbmQoZGV2LCB6ZkhwR2V0RnJlZVR4ZENvdW50KGRldiksIHRpZF90eCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9CiAgICAqLwogICAgcmV0dXJuOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmQWdnVHggICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIHJldHVybiBTdGF0dXMgY29kZSBaTV9TVUNDRVNTIG9yIGVycm9yIGNvZGUgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIG1hbmFnZW1lbnQgQS1NUERVIGFnZ3JlZ2F0aW9uIGZ1bmN0aW9uLCAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIG1hbmFnZW1lbnQgYWdncmVnYXRpb24gcXVldWUsIGNhbGN1bGF0ZSBhcnJpdmFscmF0ZSwgICAgICAgICAgICAqLwovKiAgICAgIGFkZC9kZWxldGUgYW4gYWdncmVnYXRpb24gcXVldWUgb2YgYSBzdHJlYW0sICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGVucXVldWUgcGFja2V0cyBpbnRvIHJlc3BvbnNpYmxlIGFnZ3JlZ2F0ZSBxdWV1ZS4gICAgICAgICAgICAgICAqLwovKiAgICAgIHRha2UgKGRldiwgYnVmLCBhYykgYXMgaW5wdXQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiA6IGRldmljZSBwb2ludGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGJ1ZiA6IHBhY2tldCBidWZmICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGFjICA6IGFjY2VzcyBjYXRlZ29yeSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIHN0YXR1cyBjb2RlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIEhvbmRhICAgICAgICAgICAgICAgQXRoZXJvcyBDb21tdW5pY2F0aW9ucywgSU5DLiAgICAyMDA2LjEyICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1MTZfdCB6ZkFnZ1R4KHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZiwgdTE2X3QgdGlkKQp7CiAgICB1MTZfdCBhaWQ7CiAgICAvL3UxNl90IHFudW07CiAgICAvL3UxNl90IGFnZ2ZsYWcgPSAwOwogICAgLy91MTZfdCBhcnJpdmFscmF0ZSA9IDA7CiAgICBUSURfVFggdGlkX3R4OwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIGlmKCF3ZC0+YWdnSW5pdGlhdGVkKQogICAgewogICAgICAgIHJldHVybiBaTV9FUlJfVFhfQlVGRkVSX1VOQVZBSUxBQkxFOwogICAgfQoKICAgIGFpZCA9IHpmQWdnR2V0U3RhKGRldiwgYnVmKTsKCiAgICAvL2Fycml2YWxyYXRlID0gemZBZ2dUeEFycml2YWxSYXRlKGRldiwgYWlkLCB0aWQpOwoKICAgIGlmICgweGZmZmYgPT0gYWlkKQogICAgewogICAgICAgIC8qCiAgICAgICAgICogU1RBIG5vdCBhc3NvY2lhdGVkLCB0aGlzIGlzIGEgQkMvTUMgb3IgU1RBLT5BUCBwYWNrZXQKICAgICAgICAgKi8KCiAgICAgICAgcmV0dXJuIFpNX0VSUl9UWF9CVUZGRVJfVU5BVkFJTEFCTEU7CiAgICB9CgogICAgLyoKICAgICAqIFNUQSBhc3NvY2lhdGVkLCBhIHVuaWNhc3QgcGFja2V0CiAgICAgKi8KCiAgICB0aWRfdHggPSB6ZkFnZ1R4R2V0UXVldWUoZGV2LCBhaWQsIHRpZCk7CgogICAgLyp0aWRfcS50aWRfdHggPSB0aWRfdHg7CiAgICB3ZC0+ZGVzdFEuaW5zZXJ0ID0gemZBZ2dEZXN0SW5zZXJ0OwogICAgd2QtPmRlc3RRLmluc2VydChkZXYsIDAsIHRpZF9xKTsKICAgICovCiAgICBpZiAodGlkX3R4ICE9IE5VTEwpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGlzIChhaWQsIGFjKSBpcyBhZ2dyZWdhdGVkCiAgICAgICAgICovCgogICAgICAgIC8vaWYgKGFycml2YWxyYXRlIDwgWk1fQUdHX0xPV19USFJFU0hPTEQpCiAgICAgICAgaWYgKDApCiAgICAgICAgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhcnJpdmFsIHJhdGUgdG9vIGxvdwogICAgICAgICAgICAgKiBkZWxldGUgdGhpcyBhZ2dyZWdhdGUgcXVldWUKICAgICAgICAgICAgICovCgogICAgICAgICAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgICAgICAgICAgLy93ZC0+YWdnUVBvb2xbcW51bV0tPmNsZWFyRmxhZyA9IHdkLT5hZ2dRUG9vbFtxbnVtXS0+ZGVsZXRlRmxhZyA9MTsKCiAgICAgICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHpmQWdnVHhFbnF1ZXVlKGRldiwgYnVmLCBhaWQsIHRpZF90eCk7CgogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qCiAgICAgICAgICogdGhpcyAoYWlkLCBhYykgbm90IHlldCBhZ2dyZWdhdGVkCiAgICAgICAgICogcXVldWUgbm90IGZvdW5kCiAgICAgICAgICovCgogICAgICAgIC8vaWYgKGFycml2YWxyYXRlID4gWk1fQUdHX0hJR0hfVEhSRVNIT0xEKQogICAgICAgIGlmICgxKQogICAgICAgIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogYXJyaXZhbHJhdGUgaGlnaCBlbm91Z2ggdG8gZ2V0IGEgbmV3IGFnZyBxdWV1ZQogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIHRpZF90eCA9IHpmQWdnVHhOZXdRdWV1ZShkZXYsIGFpZCwgdGlkLCBidWYpOwoKICAgICAgICAgICAgLy96bV9tc2cxX2FnZyhaTV9MVl8wLCAiZ2V0IG5ldyBBZ2dRdWV1ZSBxbnVtID0gIiwgdGlkX3R4LT4pOwoKICAgICAgICAgICAgaWYgKHRpZF90eCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGdvdCBhIG5ldyBhZ2dyZWdhdGUgcXVldWUKICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgIC8vem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICAgICAgICAgICAgICAvL3dkLT5hZ2dTdGFbYWlkXS5hZ2dGbGFnW2FjXSA9IDE7CgogICAgICAgICAgICAgICAgLy96bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBhZGQgQUREQkEgZnVuY3Rpb25zIGhlcmUKICAgICAgICAgICAgICAgICAqIHJldHVybiBaTV9FUlJfVFhfQlVGRkVSX1VOQVZBSUxBQkxFOwogICAgICAgICAgICAgICAgICovCgoKICAgICAgICAgICAgICAgIC8vemZBZ2dTZW5kQWRkYmFSZXF1ZXN0KGRldiwgdGlkX3R4LT5kc3QsIHRpZF90eC0+YWMsIHRpZF90eC0+dGlkKTsKICAgICAgICAgICAgICAgIC8vem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICAgICAgICAgICAgICAvL3dkLT5hZ2dTdGFbYWlkXS5hZ2dGbGFnW2FjXSA9IDA7CgogICAgICAgICAgICAgICAgLy96bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgICAgICAgICAgICAgIHJldHVybiB6ZkFnZ1R4RW5xdWV1ZShkZXYsIGJ1ZiwgYWlkLCB0aWRfdHgpOwoKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBqdXN0IGNhbid0IGdldCBhIG5ldyBhZ2dyZWdhdGUgcXVldWUKICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgIHJldHVybiBaTV9FUlJfVFhfQlVGRkVSX1VOQVZBSUxBQkxFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFycml2YWwgcmF0ZSBpcyBub3QgaGlnaCBlbm91Z2ggdG8gZ2V0IGEgbmV3IGFnZyBxdWV1ZQogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIHJldHVybiBaTV9FUlJfVFhfQlVGRkVSX1VOQVZBSUxBQkxFOwogICAgICAgIH0KICAgIH0KCgoKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZBZ2dUeFJlYWR5Q291bnQgICAgICAgICAgICovCi8qICAgICAgcmV0dXJuIGNvdW50ZXIgb2YgcmVhZHkgdG8gYWdncmVnYXRlIHF1ZXVlcy4gICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgdGFrZSAoZGV2LCBhYykgYXMgaW5wdXQsIG9ubHkgY2FsY3VsYXRlIHRoZSByZWFkeSB0byBhZ2dyZWdhdGUgICovCi8qICAgICAgcXVldWVzIG9mIG9uZSBwYXJ0aWN1bGFyIGFjLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYWMgIDogYWNjZXNzIGNhdGVnb3J5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIE9VVFBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgY291bnRlciBvZiByZWFkeSB0byBhZ2dyZWdhdGUgcXVldWVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEFVVEhPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgSG9uZGEgICAgICAgICAgICAgICBBdGhlcm9zIENvbW11bmljYXRpb25zLCBJTkMuICAgIDIwMDYuMTIgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnUxNl90IHpmQWdnVHhSZWFkeUNvdW50KHpkZXZfdCogZGV2LCB1MTZfdCBhYykKewogICAgdTE2X3QgaTsKICAgIHUxNl90IHJlYWR5Y291bnQgPSAwOwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgZm9yIChpPTAgOyBpPFpNX0FHR19QT09MX1NJWkU7IGkrKykKICAgIHsKICAgICAgICBpZiAod2QtPmFnZ1FQb29sW2ldLT5hZ2dRRW5hYmxlZCAmJiAod2QtPmFnZ1FQb29sW2ldLT5hZ2dSZWFkeSB8fCBcCiAgICAgICAgICAgICAgICB3ZC0+YWdnUVBvb2xbaV0tPmNsZWFyRmxhZykgJiYgYWMgPT0gd2QtPmFnZ1FQb29sW2ldLT5hYykKICAgICAgICAgICAgcmVhZHljb3VudCsrOwogICAgfQoKICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgcmV0dXJuIHJlYWR5Y291bnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZBZ2dUeFBhcnRpYWwgICAgICAgICAgICAgICovCi8qICAgICAgcmV0dXJuIHRoZSBudW1iZXIgdGhhdCBWdHhxIGhhcyB0byBzZW5kLiAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgdGFrZSAoZGV2LCBhYywgcmVhZHljb3VudCkgYXMgaW5wdXQsIGNhbGN1bGF0ZSB0aGUgcmF0aW8gb2YgICAgICovCi8qICAgICAgVnR4cSBsZW5ndGggdG8gKFZ0eHEgbGVuZ3RoICsgcmVhZHljb3VudCkgb2YgYSBwYXJ0aWN1bGFyIGFjLCAgICovCi8qICAgICAgYW5kIHJldHVybnMgdGhlIFZ0eHEgbGVuZ3RoICogdGhlIHJhdGlvICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYWMgIDogYWNjZXNzIGNhdGVnb3J5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgcmVhZHljb3VudDogdGhlIG51bWJlciBvZiByZWFkeSB0byBhZ2dyZWdhdGUgcXVldWVzIG9mIHRoaXMgYWMgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIE9VVFBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgVnR4cSBsZW5ndGggKiByYXRpbyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEFVVEhPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgSG9uZGEgICAgICAgICAgICAgICBBdGhlcm9zIENvbW11bmljYXRpb25zLCBJTkMuICAgIDIwMDYuMTIgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnUxNl90IHpmQWdnVHhQYXJ0aWFsKHpkZXZfdCogZGV2LCB1MTZfdCBhYywgdTE2X3QgcmVhZHljb3VudCkKewogICAgdTE2X3QgcWxlbjsKICAgIHUxNl90IHBhcnRpYWw7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICBxbGVuID0gem1fYWdnX3FsZW4oZGV2LCB3ZC0+dnR4cUhlYWRbYWNdLCB3ZC0+dnR4cVRhaWxbYWNdKTsKCiAgICBpZiAoKHFsZW4gKyByZWFkeWNvdW50KSA+IDApCiAgICB7CiAgICAgICAgcGFydGlhbCA9ICh1MTZfdCkoIHptX2FnZ193ZWlnaHQoYWMpICogKCh1MTZfdClxbGVuLyhxbGVuICsgXAogICAgICAgICAgICAgICAgICAgICAgICByZWFkeWNvdW50KSkgKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBwYXJ0aWFsID0gMDsKICAgIH0KCiAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgIGlmIChwYXJ0aWFsID4gcWxlbikKICAgICAgICBwYXJ0aWFsID0gcWxlbjsKCiAgICByZXR1cm4gcGFydGlhbDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZBZ2dUeFNlbmQgICAgICAgICAgICAgICAgICovCi8qICAgICAgcmV0dXJuIHNlbnRjb3VudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgdGFrZSAoZGV2LCBhYywgbikgYXMgaW5wdXQsIG4gaXMgdGhlIG51bWJlciBvZiBzY2hlZHVsZWQgYWdnICAgICovCi8qICAgICAgcXVldWVzIHRvIGJlIHNlbnQgb2YgdGhlIHBhcnRpY3VsYXIgYWMuICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYWMgIDogYWNjZXNzIGNhdGVnb3J5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgbiAgIDogdGhlIG51bWJlciBvZiBzY2hlZHVsZWQgYWdncmVnYXRpb24gcXVldWVzIHRvIGJlIHNlbnQgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIE9VVFBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgc2VudGNvdW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEFVVEhPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgSG9uZGEgICAgICAgICAgICAgICBBdGhlcm9zIENvbW11bmljYXRpb25zLCBJTkMuICAgIDIwMDYuMTIgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnUxNl90IHpmQWdnVHhTZW5kKHpkZXZfdCogZGV2LCB1MzJfdCBmcmVlVHhkLCBUSURfVFggdGlkX3R4KQp7CiAgICAvL3UxNl90ICAgcW51bTsKICAgIC8vdTE2X3QgICBxbGVuOwogICAgdTE2X3QgICBqOwogICAgLy91MTZfdCAgIHNlbnRjb3VudCA9IDA7CiAgICB6YnVmX3QqIGJ1ZjsKICAgIHN0cnVjdCAgYWdnQ29udHJvbCBhZ2dDb250cm9sOwogICAgdTE2X3QgICBhZ2dMZW47CiAgICAvL3pidWZfdCogIG5ld0J1ZjsKICAgIC8vdTE2X3QgICBidWZMZW47CiAgICAvL1RJRF9CQVcgdGlkX2JhdyA9IE5VTEw7CiAgICAvL3N0cnVjdCBidWZJbmZvICpidWZfaW5mbzsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCiAgICAvL3doaWxlICh0aWRfdHgtPnNpemUgPiAwKQoKICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICB0aWRfdHgtPnNpemUgPSB6bV9hZ2dfcWxlbihkZXYsIHRpZF90eC0+YWdnSGVhZCwgdGlkX3R4LT5hZ2dUYWlsKTsKICAgIGFnZ0xlbiA9IHptX2FnZ19taW4oMTYsIHptX2FnZ19taW4odGlkX3R4LT5zaXplLCAodTE2X3QpKGZyZWVUeGQgLSAyKSkpOwogICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHdoeSB0aGVyZSBoYXZlIHRvIGJlIDIgZnJlZSBUeGQ/CiAgICAgICAgICAgICAqLwogICAgaWYgKGFnZ0xlbiA8PTAgKQogICAgICAgIHJldHVybiAwOwoKCiAgICBpZiAoYWdnTGVuID09IDEpIHsKICAgICAgICBidWYgPSB6ZkFnZ1R4R2V0VnR4cShkZXYsIHRpZF90eCk7CiAgICAgICAgaWYgKGJ1ZikKICAgICAgICAgICAgemZUeFNlbmRFdGgoZGV2LCBidWYsIDAsIFpNX0VYVEVSTkFMX0FMTE9DX0JVRiwgMCk7CiAgICAgICAgaWYgKHRpZF90eC0+c2l6ZSA9PSAwKSB7CiAgICAgICAgICAgIC8vREVTVFEuZGVsZXRlKGRldiwgMCwgdGlkX3R4LCBOVUxMKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiAxOwogICAgfQogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIEZyZWUgVHhkIHF1ZXVlIGlzIGJpZyBlbm91Z2ggdG8gcHV0IGFnZ3JlZ2F0aW9uCiAgICAgICAgICAgICAgICAgKi8KICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICBpZiAod2QtPmFnZ1N0YXRlID09IDEpIHsKICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgd2QtPmFnZ1N0YXRlID0gMTsKICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgoKICAgIHptX21zZzFfYWdnKFpNX0xWXzAsICJhZ2dMZW49IiwgYWdnTGVuKTsKICAgIHRpZF90eC0+YWdnRnJhbWVTaXplID0gMDsKICAgIGZvciAoaj0wOyBqIDwgYWdnTGVuOyBqKyspIHsKICAgICAgICBidWYgPSB6ZkFnZ1R4R2V0VnR4cShkZXYsIHRpZF90eCk7CgogICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgdGlkX3R4LT5zaXplID0gem1fYWdnX3FsZW4oZGV2LCB0aWRfdHgtPmFnZ0hlYWQsIHRpZF90eC0+YWdnVGFpbCk7CiAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICAgICAgaWYgKCBidWYgKSB7CiAgICAgICAgICAgIC8vc3RydWN0IGFnZ1RhbGx5ICphZ2dfdGFsOwogICAgICAgICAgICB1MTZfdCBjb21wbGV0ZUluZGV4OwoKICAgICAgICAgICAgaWYgKDAgPT0gaikgewogICAgICAgICAgICAgICAgYWdnQ29udHJvbC5hbXBkdUluZGljYXRpb24gPSBaTV9BR0dfRklSU1RfTVBEVTsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKGogPT0gKGFnZ0xlbiAtIDEpKSB8fCB0aWRfdHgtPnNpemUgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYWdnQ29udHJvbC5hbXBkdUluZGljYXRpb24gPSBaTV9BR0dfTEFTVF9NUERVOwogICAgICAgICAgICAgICAgLy93ZC0+YWdnU3RhdGUgPSAwOwoKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGFnZ0NvbnRyb2wuYW1wZHVJbmRpY2F0aW9uID0gWk1fQUdHX01JRERMRV9NUERVOwogICAgICAgICAgICAgICAgLyogdGhlIHBhY2tldCBpcyBkZWxheWVkIG1vcmUgdGhhbiA1MDAgbXMsIGRyb3AgaXQgKi8KCiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGlkX3R4LT5hZ2dGcmFtZVNpemUgKz0gemZ3QnVmR2V0U2l6ZShkZXYsIGJ1Zik7CiAgICAgICAgICAgIGFnZ0NvbnRyb2wuYWRkYmFJbmRpY2F0aW9uID0gMDsKICAgICAgICAgICAgYWdnQ29udHJvbC5hZ2dFbmFibGVkID0gMTsKCiNpZmRlZiBaTV9BR0dfVEFMTFkKICAgICAgICAgICAgYWdnX3RhbCA9ICZ3ZC0+YWdnX3RhbDsKICAgICAgICAgICAgYWdnX3RhbC0+c2VudF9wYWNrZXRzX3N1bSsrOwoKI2VuZGlmCgogICAgICAgICAgICB6ZkFnZ1R4U2VuZEV0aChkZXYsIGJ1ZiwgMCwgWk1fRVhURVJOQUxfQUxMT0NfQlVGLCAwLCAmYWdnQ29udHJvbCwgdGlkX3R4KTsKCiAgICAgICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgIGNvbXBsZXRlSW5kZXggPSB0aWRfdHgtPmNvbXBsZXRlOwogICAgICAgICAgICBpZih6bV9hZ2dfaW5RKHRpZF90eCwgdGlkX3R4LT5jb21wbGV0ZSkpCiAgICAgICAgICAgICAgICB6bV9hZ2dfcGx1cyh0aWRfdHgtPmNvbXBsZXRlKTsKICAgICAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICAgICAgICAgIGlmKHptX2FnZ19pblEodGlkX3R4LCBjb21wbGV0ZUluZGV4KSAmJiB3ZC0+emZjYlNlbmRDb21wbGV0ZUluZGljYXRpb24KICAgICAgICAgICAgICAgICAgICAmJiB0aWRfdHgtPmFnZ3Z0eHFbY29tcGxldGVJbmRleF0uYnVmKSB7CiAgICAgICAgICAgICAgICB3ZC0+emZjYlNlbmRDb21wbGV0ZUluZGljYXRpb24oZGV2LCB0aWRfdHgtPmFnZ3Z0eHFbY29tcGxldGVJbmRleF0uYnVmKTsKICAgICAgICAgICAgICAgIHptX2RlYnVnX21zZzAoImluIHF1ZXVlIGNvbXBsZXRlIHdvcmtlZCEiKTsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHRoaXMgYWdncmVnYXRpb24gcXVldWUgaXMgZW1wdHkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHptX21zZzFfYWdnKFpNX0xWXzAsICJhZ2dMZW4gbm90IHJlYWNoZWQsIGJ1dCBubyBtb3JlIGZyYW1lLCBqPSIsIGopOwoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgIHdkLT5hZ2dTdGF0ZSA9IDA7CiAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgIC8vem1fYWNxdWlyZV9hZ2dfc3Bpbl9sb2NrKEFkYXB0ZXIpOwogICAgdGlkX3R4LT5zaXplID0gem1fYWdnX3FsZW4oZGV2LCB0aWRfdHgtPmFnZ0hlYWQsIHRpZF90eC0+YWdnVGFpbCk7CiAgICAvL3ptX3JlbGVhc2VfYWdnX3NwaW5fbG9jayhBZGFwdGVyKTsKCiAgICBpZiAodGlkX3R4LT5zaXplID09IDApIHsKICAgICAgICAvL0RFU1RRLmRlbGV0ZShkZXYsIDAsIHRpZF90eCwgTlVMTCk7CiAgICB9CgoKCiAgICAvL3pmQWdnSW52b2tlQmFyKGRldiwgdGlkX3R4KTsKICAgIGlmKGo+MCkgewogICAgICAgIGFnZ3JfY291bnQrKzsKICAgICAgICB6bV9tc2cxX2FnZyhaTV9MVl8wLCAiMHhDMjpzZW50IDEgYWdnciwgYWdncl9jb3VudD0iLCBhZ2dyX2NvdW50KTsKICAgICAgICB6bV9tc2cxX2FnZyhaTV9MVl8wLCAiMHhDMjpzZW50IDEgYWdnciwgYWdncl9zaXplPSIsIGopOwogICAgfQogICAgcmV0dXJuIGo7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmQWdnVHhHZXRSZWFkeVF1ZXVlICAgICAgICAqLwovKiAgICAgIHJldHVybiB0aGUgbnVtYmVyIG9mIHRoZSBhZ2dyZWdhdGlvbiBxdWV1ZSAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIHRha2UgKGRldiwgYWMpIGFzIGlucHV0LCBmaW5kIHRoZSBhZ2cgcXVldWUgd2l0aCBzbWFsbGVzdCAgICAgICAqLwovKiAgICAgIGFycml2YWwgdGltZSAod2FpdGVkIGxvbmdlc3QpIGFtb25nIHRob3NlIHJlYWR5IG9yIGNsZWFyRmxhZyAgICAqLwovKiAgICAgIHNldCBxdWV1ZXMuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiA6IGRldmljZSBwb2ludGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGFjICA6IGFjY2VzcyBjYXRlZ29yeSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGFnZ3JlZ2F0aW9uIHF1ZXVlIG51bWJlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIEhvbmRhICAgICAgICAgICAgICAgQXRoZXJvcyBDb21tdW5pY2F0aW9ucywgSU5DLiAgICAyMDA2LjEyICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpUSURfVFggemZBZ2dUeEdldFJlYWR5UXVldWUoemRldl90KiBkZXYsIHUxNl90IGFjKQp7CiAgICAvL3UxNl90ICAgICAgIHFudW0gPSBaTV9BR0dfUE9PTF9TSVpFOwogICAgdTE2X3QgICAgICAgaTsKICAgIHUzMl90ICAgICAgIHRpbWUgPSAwOwogICAgVElEX1RYICAgICAgdGlkX3R4ID0gTlVMTDsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCiAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgIGZvciAoaT0wIDtpPFpNX0FHR19QT09MX1NJWkU7IGkrKykKICAgIHsKICAgICAgICBpZiAoMSA9PSB3ZC0+YWdnUVBvb2xbaV0tPmFnZ1FFbmFibGVkICYmIGFjID09IHdkLT5hZ2dRUG9vbFtpXS0+YWMgJiYKICAgICAgICAgICAgICAgICh3ZC0+YWdnUVBvb2xbaV0tPnNpemUgPiAwKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICgwID09IHRpbWUgfHwgdGltZSA+IHdkLT5hZ2dRUG9vbFtpXS0+YWdndnR4cVsgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2QtPmFnZ1FQb29sW2ldLT5hZ2dIZWFkIF0uYXJyaXZhbFRpbWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRpZF90eCA9IHdkLT5hZ2dRUG9vbFtpXTsKICAgICAgICAgICAgICAgIHRpbWUgPSB0aWRfdHgtPmFnZ3Z0eHFbIHRpZF90eC0+YWdnSGVhZCBdLmFycml2YWxUaW1lOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgcmV0dXJuIHRpZF90eDsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmQWdnVHhHZXRWdHhxICAgICAgICAgICAgICAqLwovKiAgICAgIHJldHVybiBhbiBNU0RVICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIHRha2UgKGRldiwgcW51bSkgYXMgaW5wdXQsIHJldHVybiBhbiBNU0RVIG91dCBvZiB0aGUgYWdnIHF1ZXVlLiAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiA6IGRldmljZSBwb2ludGVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIHFudW06IHF1ZXVlIG51bWJlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGEgTVNEVSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIEhvbmRhICAgICAgICAgICAgICAgQXRoZXJvcyBDb21tdW5pY2F0aW9ucywgSU5DLiAgICAyMDA2LjEyICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp6YnVmX3QqIHpmQWdnVHhHZXRWdHhxKHpkZXZfdCogZGV2LCBUSURfVFggdGlkX3R4KQp7CiAgICB6YnVmX3QqIGJ1ZiA9IE5VTEw7CgogICAgem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCiAgICBpZiAodGlkX3R4LT5hZ2dIZWFkICE9IHRpZF90eC0+YWdnVGFpbCkKICAgIHsKICAgICAgICBidWYgPSB0aWRfdHgtPmFnZ3Z0eHFbIHRpZF90eC0+YWdnVGFpbCBdLmJ1ZjsKCiAgICAgICAgdGlkX3R4LT5hZ2d2dHhxW3RpZF90eC0+YWdnVGFpbF0uYnVmID0gTlVMTDsKCiAgICAgICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICB0aWRfdHgtPmFnZ1RhaWwgPSAoKHRpZF90eC0+YWdnVGFpbCArIDEpICYgWk1fQUdHUV9TSVpFX01BU0spOwogICAgICAgIGlmKHRpZF90eC0+c2l6ZSA+IDApIHRpZF90eC0+c2l6ZS0tOwogICAgICAgIHRpZF90eC0+c2l6ZSA9IHptX2FnZ19xbGVuKGRldiwgdGlkX3R4LT5hZ2dIZWFkLCB0aWRfdHgtPmFnZ1RhaWwpOwogICAgICAgIGlmIChOVUxMID09IGJ1ZikgewogICAgICAgICAgICAvL3RpZF90eC0+YWdnVGFpbCA9IHRpZF90eC0+YWdnSGVhZCA9IHRpZF90eC0+c2l6ZSA9IDA7CiAgICAgICAgICAgIC8vem1fbXNnMV9hZ2coWk1fTFZfMCwgIkdldFZ0eHEgYnVmID09IE5VTEwsIHRpZF90eC0+c2l6ZT0iLCB0aWRfdHgtPnNpemUpOwogICAgICAgIH0KICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qCiAgICAgICAgICogcXVldWUgaXMgZW1wdHkKICAgICAgICAgKi8KICAgICAgICB6bV9tc2cxX2FnZyhaTV9MVl8wLCAidGlkX3R4LT5hZ2dIZWFkID09IHRpZF90eC0+YWdnVGFpbCwgdGlkX3R4LT5zaXplPSIsIHRpZF90eC0+c2l6ZSk7CgogICAgfQoKICAgIGlmICh6bV9hZ2dfcWxlbihkZXYsIHRpZF90eC0+YWdnSGVhZCwgdGlkX3R4LT5hZ2dUYWlsKSAhPSB0aWRfdHgtPnNpemUpCiAgICAgICAgem1fbXNnMV9hZ2coWk1fTFZfMCwgInFsZW4hPXRpZF90eC0+c2l6ZSEgdGlkX3R4LT5zaXplPSIsIHRpZF90eC0+c2l6ZSk7CiAgICByZXR1cm4gYnVmOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgRlVOQ1RJT04gREVTQ1JJUFRJT04gICAgICAgICAgICAgICAgICB6ZkFnZ1R4RGVsZXRlUXVldWUgICAgICAgICAgKi8KLyogICAgICByZXR1cm4gWk1fU1VDQ0VTUyAoY2FuJ3QgZmFpbCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICB0YWtlIChkZXYsIHFudW0pIGFzIGlucHV0LCByZXNldCAoZGVsZXRlKSB0aGlzIGFnZ3JlZ2F0ZSBxdWV1ZSwgKi8KLyogICAgICB0aGlzIHF1ZXVlIGlzIHZpcnR1YWxseSByZXR1cm5lZCB0byB0aGUgYWdncmVnYXRlIHF1ZXVlIHBvb2wuICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgSU5QVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBkZXYgOiBkZXZpY2UgcG9pbnRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBxbnVtOiBxdWV1ZSBudW1iZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgT1VUUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBaTV9TVUNDRVNTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgQVVUSE9SICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyogICAgICBIb25kYSAgICAgICAgICAgICAgIEF0aGVyb3MgQ29tbXVuaWNhdGlvbnMsIElOQy4gICAgMjAwNi4xMiAgICAgKi8KLyogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KdTE2X3QgemZBZ2dUeERlbGV0ZVF1ZXVlKHpkZXZfdCogZGV2LCB1MTZfdCBxbnVtKQp7CiAgICB1MTZfdCBhYywgdGlkOwogICAgc3RydWN0IGFnZ1F1ZXVlICp0eF90aWQ7CiAgICBzdHJ1Y3QgYWdnU3RhICAgKmFnZ19zdGE7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgdHhfdGlkID0gd2QtPmFnZ1FQb29sW3FudW1dOwogICAgYWdnX3N0YSA9ICZ3ZC0+YWdnU3RhW3R4X3RpZC0+YWdnUVNUQV07CiAgICBhYyA9IHR4X3RpZC0+YWM7CiAgICB0aWQgPSB0eF90aWQtPnRpZDsKCiAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgIHR4X3RpZC0+YWdnUUVuYWJsZWQgPSAwOwogICAgdHhfdGlkLT5hZ2dIZWFkID0gdHhfdGlkLT5hZ2dUYWlsID0gMDsKICAgIHR4X3RpZC0+YWdnUmVhZHkgPSAwOwogICAgdHhfdGlkLT5jbGVhckZsYWcgPSB0eF90aWQtPmRlbGV0ZUZsYWcgPSAwOwogICAgdHhfdGlkLT5zaXplID0gMDsKICAgIGFnZ19zdGEtPmNvdW50W2FjXSA9IDA7CgogICAgYWdnX3N0YS0+dGlkX3R4W3RpZF0gPSBOVUxMOwogICAgYWdnX3N0YS0+YWdnRmxhZ1thY10gPSAwOwoKICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgem1fbXNnMV9hZ2coWk1fTFZfMCwgInF1ZXVlIGRlbGV0ZWQhIHFudW09IiwgcW51bSk7CgogICAgcmV0dXJuIFpNX1NVQ0NFU1M7Cn0KCiNpZmRlZiBaTV9FTkFCTEVfQUdHUkVHQVRJT04KI2lmbmRlZiBaTV9FTkFCTEVfRldfQkFfUkVUUkFOU01JU1NJT04gLy9kaXNhYmxlIEJBVwp2b2lkIHpmQmF3Q29yZSh6ZGV2X3QqIGRldiwgdTE2X3QgYmF3X3NlcSwgdTMyX3QgYml0bWFwLCB1MTZfdCBhZ2dMZW4pIHsKICAgIFRJRF9CQVcgdGlkX2JhdzsKICAgIHMxNl90IGk7CiAgICB6YnVmX3QqIGJ1ZjsKICAgIHN0cnVjdCBidWZJbmZvICpidWZfaW5mbzsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CiAgICAvL3ptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CiAgICB0aWRfYmF3ID0gQkFXLT5nZXRRKGRldiwgYmF3X3NlcSk7CiAgICAvL3RpZF9iYXcgPSBOVUxMOwogICAgaWYgKE5VTEwgPT0gdGlkX2JhdykKICAgICAgICByZXR1cm47CgogICAgdG90YWxfbXBkdSArPSBhZ2dMZW47CiAgICBmb3IgKGkgPSBhZ2dMZW4gLSAxOyBpPj0wOyBpLS0pIHsKICAgICAgICBpZiAoKChiaXRtYXAgPj4gaSkgJiAweDEpID09IDApIHsKICAgICAgICAgICAgYnVmX2luZm8gPSBCQVctPnBvcChkZXYsIGksIHRpZF9iYXcpOwogICAgICAgICAgICBidWYgPSBidWZfaW5mby0+YnVmOwogICAgICAgICAgICBpZiAoYnVmKSB7CiAgICAgICAgICAgICAgICAvL3dkLT56ZmNiU2V0QmF3UShkZXYsIGJ1ZiwgMCk7CiAgICAgICAgICAgICAgICB6ZkFnZ1RpZFR4SW5zZXJ0SGVhZChkZXYsIGJ1Zl9pbmZvLCB0aWRfYmF3LT50aWRfdHgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBzdWNjZXNzX21wZHUrKzsKICAgICAgICB9CiAgICB9CiAgICBCQVctPmRpc2FibGUoZGV2LCB0aWRfYmF3KTsKICAgIHpmQWdnVHhTY2hlZHVsZXIoZGV2KTsKICAgIHptX2RlYnVnX21zZzEoInN1Y2Nlc3NfbXBkdSA9ICIsIHN1Y2Nlc3NfbXBkdSk7CiAgICB6bV9kZWJ1Z19tc2cxKCIgIHRvdGFsX21wZHUgPSAiLCB0b3RhbF9tcGR1KTsKfQoKdm9pZCAgICB6ZkJhd0luaXQoemRldl90KiBkZXYpIHsKICAgIFRJRF9CQVcgdGlkX2JhdzsKICAgIHUxNl90IGksajsKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCiAgICBmb3IgKGk9MDsgaTxaTV9CQVdfUE9PTF9TSVpFOyBpKyspewogICAgICAgIHRpZF9iYXcgPSAmQkFXLT50aWRfYmF3W2ldOwogICAgICAgIGZvciAoaj0wOyBqPFpNX1ZUWFFfU0laRTsgaisrKSB7CiAgICAgICAgICAgIHRpZF9iYXctPmZyYW1lW2pdLmJ1ZiA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIHRpZF9iYXctPmVuYWJsZWQgPSB0aWRfYmF3LT5oZWFkID0gdGlkX2Jhdy0+dGFpbCA9IHRpZF9iYXctPnNpemUgPSAwOwogICAgICAgIHRpZF9iYXctPnN0YXJ0X3NlcSA9IDA7CiAgICB9CiAgICBCQVctPmRlbFBvaW50ID0gMDsKICAgIEJBVy0+Y29yZSA9IHpmQmF3Q29yZTsKICAgIEJBVy0+Z2V0TmV3USA9IHpmQmF3R2V0TmV3UTsKICAgIEJBVy0+aW5zZXJ0ID0gemZCYXdJbnNlcnQ7CiAgICBCQVctPnBvcCA9IHpmQmF3UG9wOwogICAgQkFXLT5lbmFibGUgPSB6ZkJhd0VuYWJsZTsKICAgIEJBVy0+ZGlzYWJsZSA9IHpmQmF3RGlzYWJsZTsKICAgIEJBVy0+Z2V0USA9IHpmQmF3R2V0UTsKfQoKCgpUSURfQkFXIHpmQmF3R2V0TmV3USh6ZGV2X3QqIGRldiwgdTE2X3Qgc3RhcnRfc2VxLCBUSURfVFggdGlkX3R4KSB7CiAgICBUSURfQkFXIHRpZF9iYXc9TlVMTDsKICAgIFRJRF9CQVcgbmV4dF9iYXc9TlVMTDsKICAgIHUxNl90IGk7CiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CiAgICAvL3ptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgLyoKICAgIGZvciAoaT0wOyBpPFpNX0JBV19QT09MX1NJWkU7IGkrKyl7CiAgICAgICAgdGlkX2JhdyA9ICZCQVctPnRpZF9iYXdbaV07CiAgICAgICAgaWYgKEZBTFNFID09IHRpZF9iYXctPmVuYWJsZWQpCiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgKi8KCiAgICB0aWRfYmF3ID0gJkJBVy0+dGlkX2Jhd1tCQVctPmRlbFBvaW50XTsKICAgIGkgPSBCQVctPmRlbFBvaW50OwogICAgLy9pZiAoWk1fQkFXX1BPT0xfU0laRSA9PSBpKSB7CiAgICAgICAgLy9yZXR1cm4gTlVMTDsKICAgIC8vICAgIHU4X3QgdGVtcCA9IEJBVy0+ZGVsUG9pbnQ7CiAgICAvLyAgICB0aWRfYmF3ID0gJkJBVy0+dGlkX2Jhd1tCQVctPmRlbFBvaW50XTsKICAgIC8vICAgIEJBVy0+ZGlzYWJsZShkZXYsIHRpZF9iYXcpOwogICAgLy8gICAgQkFXLT5kZWxQb2ludCA9IChCQVctPmRlbFBvaW50IDwgKFpNX0JBV19QT09MX1NJWkUgLSAxKSk/IChCQVctPmRlbFBvaW50ICsgMSk6IDA7CiAgICAvLyAgICB0ZW1wID0gQkFXLT5kZWxQb2ludDsKICAgIC8vfQoKICAgIHptX21zZzFfYWdnKFpNX0xWXzAsICJnZXQgbmV3IHRpZF9iYXcsIGluZGV4PSIsIGkpOwogICAgQkFXLT5kZWxQb2ludCA9IChpIDwgKFpNX0JBV19QT09MX1NJWkUgLTEpKT8gKGkgKyAxKTogMDsKICAgIG5leHRfYmF3ID0gJkJBVy0+dGlkX2Jhd1tCQVctPmRlbFBvaW50XTsKICAgIGlmICgxID09IG5leHRfYmF3LT5lbmFibGVkKSBCQVctPmRpc2FibGUoZGV2LCBuZXh0X2Jhdyk7CgogICAgQkFXLT5lbmFibGUoZGV2LCB0aWRfYmF3LCBzdGFydF9zZXEpOwogICAgdGlkX2Jhdy0+dGlkX3R4ID0gdGlkX3R4OwoKICAgIHJldHVybiB0aWRfYmF3Owp9Cgp1MTZfdCAgIHpmQmF3SW5zZXJ0KHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZiwgdTE2X3QgYmF3X3NlcSwgVElEX0JBVyB0aWRfYmF3LCB1OF90IGJhd19yZXRyYW5zbWl0LCBzdHJ1Y3QgYmF3X2hlYWRlcl9yICpoZWFkZXJfcikgewogICAgLy9USURfQkFXIHRpZF9iYXc7CiAgICAvL3UxNl90ICAgYnVmTGVuOwoKICAgIC8vem13X2dldF93bGFuX2RldihkZXYpOwogICAgLy96bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIGlmKHRpZF9iYXctPnNpemUgPCAoWk1fVlRYUV9TSVpFIC0gMSkpIHsKICAgICAgICBzdHJ1Y3QgYmF3X2hlYWRlciAqYmF3X2hlYWRlciA9ICZ0aWRfYmF3LT5mcmFtZVt0aWRfYmF3LT5oZWFkXS5iYXdfaGVhZGVyOwoKICAgICAgICBiYXdfaGVhZGVyLT5oZWFkZXJMZW4gICA9IGhlYWRlcl9yLT5oZWFkZXJMZW47CiAgICAgICAgYmF3X2hlYWRlci0+bWljTGVuICAgICAgPSBoZWFkZXJfci0+bWljTGVuOwogICAgICAgIGJhd19oZWFkZXItPnNuYXBMZW4gICAgID0gaGVhZGVyX3ItPnNuYXBMZW47CiAgICAgICAgYmF3X2hlYWRlci0+cmVtb3ZlTGVuICAgPSBoZWFkZXJfci0+cmVtb3ZlTGVuOwogICAgICAgIGJhd19oZWFkZXItPmtleUlkeCAgICAgID0gaGVhZGVyX3ItPmtleUlkeDsKICAgICAgICB6ZndNZW1vcnlDb3B5KCh1OF90ICopYmF3X2hlYWRlci0+aGVhZGVyLCAodThfdCAqKWhlYWRlcl9yLT5oZWFkZXIsIDU4KTsKICAgICAgICB6ZndNZW1vcnlDb3B5KCh1OF90ICopYmF3X2hlYWRlci0+bWljICAgLCAodThfdCAqKWhlYWRlcl9yLT5taWMgICAsIDgpOwogICAgICAgIHpmd01lbW9yeUNvcHkoKHU4X3QgKiliYXdfaGVhZGVyLT5zbmFwICAsICh1OF90ICopaGVhZGVyX3ItPnNuYXAgICwgOCk7CiAgICAgICAgLy93ZC0+emZjYlNldEJhd1EoZGV2LCBidWYsIDEpOwogICAgICAgIHRpZF9iYXctPmZyYW1lW3RpZF9iYXctPmhlYWRdLmJ1ZiA9IGJ1ZjsKICAgICAgICB0aWRfYmF3LT5mcmFtZVt0aWRfYmF3LT5oZWFkXS5iYXdfc2VxID0gYmF3X3NlcTsKICAgICAgICB0aWRfYmF3LT5mcmFtZVt0aWRfYmF3LT5oZWFkXS5iYXdfcmV0cmFuc21pdCA9IGJhd19yZXRyYW5zbWl0ICsgMTsKCiAgICAgICAgLy90aWRfYmF3LT5mcmFtZVt0aWRfYmF3LT5oZWFkXS5kYXRhID0gcEJ1Zi0+ZGF0YTsKICAgICAgICB0aWRfYmF3LT5oZWFkKys7CiAgICAgICAgdGlkX2Jhdy0+c2l6ZSsrOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgLy93ZC0+emZjYlNldEJhd1EoZGV2LCBidWYsIDApOwogICAgICAgIHpmd0J1ZkZyZWUoZGV2LCBidWYsIFpNX1NVQ0NFU1MpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgpzdHJ1Y3QgYnVmSW5mbyogemZCYXdQb3AoemRldl90KiBkZXYsIHUxNl90IGluZGV4LCBUSURfQkFXIHRpZF9iYXcpIHsKICAgIC8vVElEX0JBVyB0aWRfYmF3OwogICAgLy96YnVmX3QqIGJ1ZjsKICAgIHN0cnVjdCBidWZJbmZvICpidWZfaW5mbzsKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICBidWZfaW5mbyA9ICZ3ZC0+YnVmX2luZm87CiAgICBidWZfaW5mby0+YmF3X2hlYWRlciA9IE5VTEw7CgogICAgaWYgKE5VTEwgPT0gKGJ1Zl9pbmZvLT5idWYgPSB0aWRfYmF3LT5mcmFtZVtpbmRleF0uYnVmKSkKICAgICAgICByZXR1cm4gYnVmX2luZm87CgogICAgYnVmX2luZm8tPmJhd19yZXRyYW5zbWl0ID0gdGlkX2Jhdy0+ZnJhbWVbaW5kZXhdLmJhd19yZXRyYW5zbWl0OwogICAgYnVmX2luZm8tPmJhd19oZWFkZXIgPSAmdGlkX2Jhdy0+ZnJhbWVbaW5kZXhdLmJhd19oZWFkZXI7CiAgICBidWZfaW5mby0+dGltZXN0YW1wID0gdGlkX2Jhdy0+ZnJhbWVbaW5kZXhdLnRpbWVzdGFtcDsKICAgIC8vcEJ1Zi0+ZGF0YSA9IHBCdWYtPmJ1ZmZlcjsKICAgIC8vd2QtPnpmY2JSZXN0b3JlQnVmRGF0YShkZXYsIGJ1Zik7CiAgICB0aWRfYmF3LT5mcmFtZVtpbmRleF0uYnVmID0gTlVMTDsKCiAgICByZXR1cm4gYnVmX2luZm87Cn0KCnZvaWQgICAgemZCYXdFbmFibGUoemRldl90KiBkZXYsIFRJRF9CQVcgdGlkX2JhdywgdTE2X3Qgc3RhcnRfc2VxKSB7CiAgICAvL1RJRF9CQVcgdGlkX2JhdzsKCiAgICAvL3ptd19nZXRfd2xhbl9kZXYoZGV2KTsKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCiAgICB0aWRfYmF3LT5lbmFibGVkID0gVFJVRTsKICAgIHRpZF9iYXctPmhlYWQgPSB0aWRfYmF3LT50YWlsID0gdGlkX2Jhdy0+c2l6ZSA9IDA7CiAgICB0aWRfYmF3LT5zdGFydF9zZXEgPSBzdGFydF9zZXE7Cn0KCnZvaWQgICAgemZCYXdEaXNhYmxlKHpkZXZfdCogZGV2LCBUSURfQkFXIHRpZF9iYXcpIHsKICAgIC8vVElEX0JBVyB0aWRfYmF3OwogICAgdTE2X3QgaTsKCiAgICAvL3ptd19nZXRfd2xhbl9kZXYoZGV2KTsKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKICAgIGZvciAoaT0wOyBpPFpNX1ZUWFFfU0laRTsgaSsrKSB7CiAgICAgICAgaWYgKHRpZF9iYXctPmZyYW1lW2ldLmJ1ZikgewoKICAgICAgICAgICAgLy93ZC0+emZjYlNldEJhd1EoZGV2LCB0aWRfYmF3LT5mcmFtZVtpXS5idWYsIDApOwogICAgICAgICAgICB6ZndCdWZGcmVlKGRldiwgdGlkX2Jhdy0+ZnJhbWVbaV0uYnVmLCBaTV9TVUNDRVNTKTsKICAgICAgICAgICAgdGlkX2Jhdy0+ZnJhbWVbaV0uYnVmID0gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgdGlkX2Jhdy0+ZW5hYmxlZCA9IEZBTFNFOwp9CgpUSURfQkFXIHpmQmF3R2V0USh6ZGV2X3QqIGRldiwgdTE2X3QgYmF3X3NlcSkgewogICAgVElEX0JBVyB0aWRfYmF3PU5VTEw7CiAgICB1MTZfdCBpOwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKICAgIGZvciAoaT0wOyBpPFpNX0JBV19QT09MX1NJWkU7IGkrKyl7CiAgICAgICAgdGlkX2JhdyA9ICZCQVctPnRpZF9iYXdbaV07CiAgICAgICAgaWYgKFRSVUUgPT0gdGlkX2Jhdy0+ZW5hYmxlZCkKICAgICAgICB7CiAgICAgICAgICAgIHptX21zZzFfYWdnKFpNX0xWXzAsICJnZXQgYW4gb2xkIHRpZF9iYXcsIGJhd19zZXE9IiwgYmF3X3NlcSk7CiAgICAgICAgICAgIHptX21zZzFfYWdnKFpNX0xWXzAsICJjaGVjayBhICB0aWRfYmF3LT5zdGFydF9zZXE9IiwgdGlkX2Jhdy0+c3RhcnRfc2VxKTsKICAgICAgICAgICAgaWYoYmF3X3NlcSA9PSB0aWRfYmF3LT5zdGFydF9zZXEpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgfQogICAgaWYgKFpNX0JBV19QT09MX1NJWkUgPT0gaSkKICAgICAgICByZXR1cm4gTlVMTDsKICAgIHJldHVybiB0aWRfYmF3Owp9CiNlbmRpZiAvL2Rpc2FibGUgQkFXCiNlbmRpZgoKdTE2X3QgemZBZ2dUYWxseVJlc2V0KHpkZXZfdCogZGV2KQp7CiAgICBzdHJ1Y3QgYWdnVGFsbHkqIGFnZ190YWw7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCiAgICBhZ2dfdGFsID0gJndkLT5hZ2dfdGFsOwogICAgYWdnX3RhbC0+Z290X3BhY2tldHNfc3VtID0gMDsKICAgIGFnZ190YWwtPmdvdF9ieXRlc19zdW0gPSAwOwogICAgYWdnX3RhbC0+c2VudF9ieXRlc19zdW0gPSAwOwogICAgYWdnX3RhbC0+c2VudF9wYWNrZXRzX3N1bSA9IDA7CiAgICBhZ2dfdGFsLT5hdmdfZ290X3BhY2tldHMgPSAwOwogICAgYWdnX3RhbC0+YXZnX2dvdF9ieXRlcyA9IDA7CiAgICBhZ2dfdGFsLT5hdmdfc2VudF9wYWNrZXRzID0gMDsKICAgIGFnZ190YWwtPmF2Z19zZW50X2J5dGVzID0gMDsKICAgIGFnZ190YWwtPnRpbWUgPSAwOwogICAgcmV0dXJuIDA7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmQWdnU2NhbkFuZENsZWFyICAgICAgICAgICAqLwovKiAgICAgIElmIHRoZSBwYWNrZXRzIGluIGEgcXVldWUgaGF2ZSB3YWl0ZWQgZm9yIHRvbyBsb25nLCBjbGVhciBhbmQgICAqLwovKiAgICAgIGRlbGV0ZSB0aGlzIGFnZ3JlZ2F0aW9uIHF1ZXVlLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiAgICAgOiBkZXZpY2UgcG9pbnRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIHRpbWUgICAgOiBjdXJyZW50IHRpbWUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFpNX1NVQ0NFU1MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIEhvbmRhICAgICAgICAgICAgICAgQXRoZXJvcyBDb21tdW5pY2F0aW9ucywgSU5DLiAgICAyMDA2LjEyICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1MTZfdCAgIHpmQWdnU2NhbkFuZENsZWFyKHpkZXZfdCogZGV2LCB1MzJfdCB0aW1lKQp7CiAgICB1MTZfdCBpOwogICAgdTE2X3QgaGVhZDsKICAgIHUxNl90IHRhaWw7CiAgICB1MzJfdCB0aWNrOwogICAgdTMyX3QgYXJyaXZhbFRpbWU7CiAgICAvL3UxNl90IGFpZCwgYWM7CiAgICBUSURfVFggdGlkX3R4OwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIGlmKCEod2QtPnN0YXRlID09IFpNX1dMQU5fU1RBVEVfRU5BQkxFRCkpIHJldHVybiAwOwogICAgemZBZ2dUeFNjaGVkdWxlcihkZXYsIDEpOwogICAgdGljayA9IHptX2FnZ19HZXRUaW1lKCk7CiAgICBmb3IgKGk9MDsgaTxaTV9BR0dfUE9PTF9TSVpFOyBpKyspCiAgICB7CiAgICAgICAgaWYgKCF3ZC0+YWdnUVBvb2xbaV0pIHJldHVybiAwOwogICAgICAgIGlmICgxID09IHdkLT5hZ2dRUG9vbFtpXS0+YWdnUUVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICB0aWRfdHggPSB3ZC0+YWdnUVBvb2xbaV07CiAgICAgICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgICAgICAgICBoZWFkID0gdGlkX3R4LT5hZ2dIZWFkOwogICAgICAgICAgICB0YWlsID0gdGlkX3R4LT5hZ2dUYWlsOwoKICAgICAgICAgICAgYXJyaXZhbFRpbWUgPSAodTMyX3QpdGlkX3R4LT5hZ2d2dHhxW3RpZF90eC0+YWdnVGFpbF0uYXJyaXZhbFRpbWU7CgoKICAgICAgICAgICAgaWYoKHRpY2sgLSBhcnJpdmFsVGltZSkgPD0gWk1fQUdHX0NMRUFSX1RJTUUpCiAgICAgICAgICAgIHsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZigodGlkX3R4LT5zaXplID0gem1fYWdnX3FsZW4oZGV2LCB0aWRfdHgtPmFnZ0hlYWQsIHRpZF90eC0+YWdnVGFpbCkpID4gMCkKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgIHRpZF90eC0+Y2xlYXJGbGFnID0gMTsKCiAgICAgICAgICAgICAgICAvL3ptX21zZzFfYWdnKFpNX0xWXzAsICJjbGVhciBxdWV1ZSAgICB0aWNrID0iLCB0aWNrKTsKICAgICAgICAgICAgICAgIC8vem1fbXNnMV9hZ2coWk1fTFZfMCwgImNsZWFyIHF1ZXVlIGFycml2YWwgPSIsIGFycml2YWxUaW1lKTsKCgogICAgICAgICAgICAgICAgLy96bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgICAgICAgICAgLy96ZkFnZ1R4U2NoZWR1bGVyKGRldik7CiAgICAgICAgICAgICAgICAvL3ptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodGlkX3R4LT5zaXplID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBxdWV1ZSBlbXB0eQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAodGljayAtIHRpZF90eC0+bGFzdEFycml2YWwgPiBaTV9BR0dfREVMRVRFX1RJTUUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgem1fbXNnMV9hZ2coWk1fTFZfMCwgImRlbGV0ZSBxdWV1ZSwgaWRsZSBmb3IgbiBzZWMuIG4gPSAiLCBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBaTV9BR0dfREVMRVRFX1RJTUUvMTApOwoKICAgICAgICAgICAgICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgICAgICAgICAgICAgIHpmQWdnVHhEZWxldGVRdWV1ZShkZXYsIGkpOwogICAgICAgICAgICAgICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgfQogICAgfQoKICAgICAgICB6ZkFnZ1J4Q2xlYXIoZGV2LCB0aW1lKTsKCiNpZmRlZiBaTV9BR0dfVEFMTFkKICAgIGlmKCh3ZC0+dGljayAlIDEwMCkgPT0gMCkgewogICAgICAgIHpmQWdnUHJpbnRUYWxseShkZXYpOwogICAgfQojZW5kaWYKCiAgICByZXR1cm4gWk1fU1VDQ0VTUzsKfQoKdTE2X3QgICB6ZkFnZ1ByaW50VGFsbHkoemRldl90KiBkZXYpCnsKICAgIHN0cnVjdCBhZ2dUYWxseSogYWdnX3RhbDsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgLy96bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIGFnZ190YWwgPSAmd2QtPmFnZ190YWw7CgogICAgaWYoYWdnX3RhbC0+Z290X3BhY2tldHNfc3VtIDwgMTApCiAgICB7CiAgICAgICAgemZBZ2dUYWxseVJlc2V0KGRldik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgYWdnX3RhbC0+dGltZSsrOwogICAgYWdnX3RhbC0+YXZnX2dvdF9wYWNrZXRzID0gKGFnZ190YWwtPmF2Z19nb3RfcGFja2V0cyAqIChhZ2dfdGFsLT50aW1lIC0gMSkgKwogICAgICAgICAgICBhZ2dfdGFsLT5nb3RfcGFja2V0c19zdW0pIC8gYWdnX3RhbC0+dGltZTsKICAgIGFnZ190YWwtPmF2Z19nb3RfYnl0ZXMgPSAoYWdnX3RhbC0+YXZnX2dvdF9ieXRlcyAqIChhZ2dfdGFsLT50aW1lIC0gMSkgKwogICAgICAgICAgICBhZ2dfdGFsLT5nb3RfYnl0ZXNfc3VtKSAvIGFnZ190YWwtPnRpbWU7CiAgICBhZ2dfdGFsLT5hdmdfc2VudF9wYWNrZXRzID0gKGFnZ190YWwtPmF2Z19zZW50X3BhY2tldHMgKiAoYWdnX3RhbC0+dGltZSAtIDEpCiAgICAgICAgICAgICsgYWdnX3RhbC0+c2VudF9wYWNrZXRzX3N1bSkgLyBhZ2dfdGFsLT50aW1lOwogICAgYWdnX3RhbC0+YXZnX3NlbnRfYnl0ZXMgPSAoYWdnX3RhbC0+YXZnX3NlbnRfYnl0ZXMgKiAoYWdnX3RhbC0+dGltZSAtIDEpICsKICAgICAgICAgICAgYWdnX3RhbC0+c2VudF9ieXRlc19zdW0pIC8gYWdnX3RhbC0+dGltZTsKICAgIHptX21zZzFfYWdnKFpNX0xWXzAsICJnb3RfcGFja2V0c19zdW0gPSIsIGFnZ190YWwtPmdvdF9wYWNrZXRzX3N1bSk7CiAgICB6bV9tc2cxX2FnZyhaTV9MVl8wLCAiICBnb3RfYnl0ZXNfc3VtID0iLCBhZ2dfdGFsLT5nb3RfYnl0ZXNfc3VtKTsKICAgIHptX21zZzFfYWdnKFpNX0xWXzAsICJzZW50X3BhY2tldHNfc3VtPSIsIGFnZ190YWwtPnNlbnRfcGFja2V0c19zdW0pOwogICAgem1fbXNnMV9hZ2coWk1fTFZfMCwgIiBzZW50X2J5dGVzX3N1bSA9IiwgYWdnX3RhbC0+c2VudF9ieXRlc19zdW0pOwogICAgYWdnX3RhbC0+Z290X3BhY2tldHNfc3VtID0gYWdnX3RhbC0+Z290X2J5dGVzX3N1bSA9YWdnX3RhbC0+c2VudF9wYWNrZXRzX3N1bQogICAgICAgICAgICAgICAgPSBhZ2dfdGFsLT5zZW50X2J5dGVzX3N1bSA9IDA7CiAgICB6bV9tc2cxX2FnZyhaTV9MVl8wLCAiYXZnX2dvdF9wYWNrZXRzID0iLCBhZ2dfdGFsLT5hdmdfZ290X3BhY2tldHMpOwogICAgem1fbXNnMV9hZ2coWk1fTFZfMCwgIiAgYXZnX2dvdF9ieXRlcyA9IiwgYWdnX3RhbC0+YXZnX2dvdF9ieXRlcyk7CiAgICB6bV9tc2cxX2FnZyhaTV9MVl8wLCAiYXZnX3NlbnRfcGFja2V0cz0iLCBhZ2dfdGFsLT5hdmdfc2VudF9wYWNrZXRzKTsKICAgIHptX21zZzFfYWdnKFpNX0xWXzAsICIgYXZnX3NlbnRfYnl0ZXMgPSIsIGFnZ190YWwtPmF2Z19zZW50X2J5dGVzKTsKICAgIGlmICgod2QtPmNvbW1UYWxseS5CQV9GYWlsID09IDApIHx8ICh3ZC0+Y29tbVRhbGx5Lkh3X1R4X01QRFUgPT0gMCkpCiAgICB7CiAgICAgICAgem1fbXNnMV9hZ2coWk1fTFZfMCwgIkhhcmR3YXJlIFR4IE1QRFU9Iiwgd2QtPmNvbW1UYWxseS5Id19UeF9NUERVKTsKICAgICAgICB6bV9tc2cxX2FnZyhaTV9MVl8wLCAiICBCQSBGYWlsIG51bWJlcj0iLCB3ZC0+Y29tbVRhbGx5LkJBX0ZhaWwpOwogICAgfQogICAgZWxzZQogICAgICAgIHptX21zZzFfYWdnKFpNX0xWXzAsICIxLyhCQSBmYWlsIHJhdGUpPSIsIHdkLT5jb21tVGFsbHkuSHdfVHhfTVBEVS93ZC0+Y29tbVRhbGx5LkJBX0ZhaWwpOwoKICAgIHJldHVybiAwOwp9Cgp1MTZfdCB6ZkFnZ1J4Q2xlYXIoemRldl90KiBkZXYsIHUzMl90IHRpbWUpCnsKICAgIHUxNl90ICAgaTsKICAgIHN0cnVjdCBhZ2dfdGlkX3J4ICp0aWRfcng7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgZm9yIChpPTA7IGk8Wk1fQUdHX1BPT0xfU0laRTsgaSsrKQogICAgewogICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgdGlkX3J4ID0gd2QtPnRpZF9yeFtpXTsKICAgICAgICBpZiAodGlkX3J4LT5iYXdfaGVhZCAhPSB0aWRfcngtPmJhd190YWlsKQogICAgICAgIHsKICAgICAgICAgICAgdTE2X3QgaiA9IHRpZF9yeC0+YmF3X3RhaWw7CiAgICAgICAgICAgIHdoaWxlICgoaiAhPSB0aWRfcngtPmJhd19oZWFkKSAmJiAhdGlkX3J4LT5mcmFtZVtqXS5idWYpIHsKICAgICAgICAgICAgCWogPSAoaiArIDEpICYgWk1fQUdHX0JBV19NQVNLOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgoaiAhPSB0aWRfcngtPmJhd19oZWFkKSAmJiAodGltZSAtIHRpZF9yeC0+ZnJhbWVbal0uYXJyaXZhbFRpbWUpID4KICAgICAgICAgICAgICAgICAgICAoWk1fQUdHX0NMRUFSX1RJTUUgLSA1KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICAgICAgICAgIHptX21zZzBfYWdnKFpNX0xWXzEsICJxdWV1ZSBSeEZsdXNoIGJ5IFJ4Q2xlYXIiKTsKICAgICAgICAgICAgICAgIHpmQWdnUnhGbHVzaChkZXYsIDAsIHRpZF9yeCk7CiAgICAgICAgICAgICAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICB9CgogICAgcmV0dXJuIFpNX1NVQ0NFU1M7Cn0KCnN0cnVjdCBhZ2dfdGlkX3J4KiB6ZkFnZ1J4RW5hYmxlZCh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYpCnsKICAgIHUxNl90ICAgZHN0MCwgc3JjWzNdLCBhaWQ7CiAgICB1MTZfdCAgIG9mZnNldCA9IDA7CiAgICB1MTZfdCAgIHNlcV9ubzsKICAgIHUxNl90IGZyYW1lVHlwZTsKICAgIHUxNl90IGZyYW1lQ3RybDsKICAgIHUxNl90IGZyYW1lU3VidHlwZTsKICAgIC8vc3RydWN0IGFnZ1N0YSAqYWdnX3N0YTsKI2lmIFpNX0FHR19GUEdBX1JFT1JERVJJTkcKICAgIHN0cnVjdCBhZ2dfdGlkX3J4ICp0aWRfcng7CiNlbmRpZgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKICAgIHNlcV9ubyA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDIyKSA+PiA0OwogICAgLy9EYmdQcmludCgiUnggc2VxPSVkXG4iLCBzZXFfbm8pOwogICAgaWYgKHdkLT5zdGEuRW5hYmxlSFQgPT0gMCkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBmcmFtZUN0cmwgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCAwKTsKICAgIGZyYW1lVHlwZSA9IGZyYW1lQ3RybCAmIDB4ZjsKICAgIGZyYW1lU3VidHlwZSA9IGZyYW1lQ3RybCAmIDB4ZjA7CgoKICAgIGlmIChmcmFtZVR5cGUgIT0gWk1fV0xBTl9EQVRBX0ZSQU1FKSAvL25vbi1Rb3MgRGF0YT8gKGZyYW1lU3VidHlwZSYweDgwKQogICAgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQojaWZkZWYgWk1fRU5BQkxFX1BFUkZPUk1BTkNFX0VWQUxVQVRJT04KICAgIHsKICAgICAgICB1MzJfdCB0Y3Bfc2VxOwoKICAgICAgICB0Y3Bfc2VxID0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1ZiwgMjIrMzYpIDw8IDI0OwogICAgICAgIHRjcF9zZXEgKz0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1ZiwgMjIrMzcpIDw8IDE2OwogICAgICAgIHRjcF9zZXEgKz0gem13X3J4X2J1Zl9yZWFkYihkZXYsIGJ1ZiwgMjIrMzgpIDw8IDg7CiAgICAgICAgdGNwX3NlcSArPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCAyMiszOSk7CiAgICAgICAgWk1fU0VRX0RFQlVHKCJJbiAgICAgICAgICAgICAgICAgICAlNWQsICUxMnVcbiIsIHNlcV9ubywgdGNwX3NlcSk7CiAgICB9CiNlbmRpZgoKICAgIGRzdDAgPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCBvZmZzZXQrNCk7CgogICAgc3JjWzBdID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIGJ1Ziwgb2Zmc2V0KzEwKTsKICAgIHNyY1sxXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIG9mZnNldCsxMik7CiAgICBzcmNbMl0gPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCBvZmZzZXQrMTQpOwoKI2lmIFpNX0FHR19GUEdBX0RFQlVHCiAgICBhaWQgPSAwOwojZWxzZQogICAgYWlkID0gemZBcEZpbmRTdGEoZGV2LCBzcmMpOwojZW5kaWYKCiAgICAvL2FnZ19zdGEgPSAmd2QtPmFnZ1N0YVthaWRdOwogICAgLy96ZlR4R2V0SXBUb3NBbmRGcmFnKGRldiwgYnVmLCAmdXAsICZmcmFnT2ZmKTsKICAgIC8vYWMgPSB6Y1VwVG9BY1t1cCYweDddICYgMHgzOwoKICAgIC8qCiAgICAgKiBGaWx0ZXIgdW5pY2FzdCBmcmFtZSBvbmx5LCBhaWQgPT0gMCBpcyBmb3IgZGVidWcgb25seQogICAgICovCiAgICBpZiAoKGRzdDAgJiAweDEpID09IDAgJiYgYWlkID09IDApCiAgICB7CiNpZiBaTV9BR0dfRlBHQV9SRU9SREVSSU5HCiAgICAgICAgdGlkX3J4ID0gemZBZ2dSeEdldFF1ZXVlKGRldiwgYnVmKSA7CiAgICAgICAgaWYoIXRpZF9yeCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLy9pZiAodGlkX3J4LT5hZGRCYUV4Y2hhbmdlU3RhdHVzQ29kZSA9PSBaTV9BR0dfQUREQkFfUkVTUE9OU0UpCiAgICAgICAgICAgIHJldHVybiB0aWRfcng7CiAgICAgICAgfQojZWxzZQogICAgICAgIHJldHVybiBOVUxMOwojZW5kaWYKICAgIH0KCiAgICByZXR1cm4gTlVMTDsKfQoKdTE2X3QgemZBZ2dSeCh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYsIHN0cnVjdCB6c0FkZGl0aW9uSW5mbyAqYWRkSW5mbywgc3RydWN0IGFnZ190aWRfcnggKnRpZF9yeCkKewogICAgdTE2X3QgICBzZXFfbm87CiAgICBzMTZfdCAgIGluZGV4OwogICAgdTE2X3QgICBvZmZzZXQgPSAwOwogICAgemJ1Zl90KiBwYnVmOwogICAgdThfdCAgICBmcmFtZVN1YlR5cGU7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgWk1fQlVGRkVSX1RSQUNFKGRldiwgYnVmKQoKICAgIFpNX1BFUkZPUk1BTkNFX1JYX1JFT1JERVIoZGV2KTsKCiAgICBzZXFfbm8gPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCBvZmZzZXQrMjIpID4+IDQ7CgogICAgaW5kZXggPSBzZXFfbm8gLSB0aWRfcngtPnNlcV9zdGFydDsKICAgIC8qCiAgICAgKiBmb3IgZGVidWcKICAgICAqLwoKICAgIC8qIHptX21zZzJfYWdnKFpNX0xWXzAsICJxdWV1ZSBzZXEgPSAiLCBzZXFfbm8pOwogICAgICogRGJnUHJpbnQoIiVzOiVzJWx4aCAlcyVseGhcbiIsIF9fZnVuY19fLCAicXVldWUgc2VxPSIsIHNlcV9ubywKICAgICAqICAgIjsgc2VxX3N0YXJ0PSIsIHRpZF9yeC0+c2VxX3N0YXJ0KTsKICAgICAqLwoKICAgIC8vRGJnUHJpbnQoInNlcV9ubz0lZCwgc2VxX3N0YXJ0PSVkXG4iLCBzZXFfbm8sIHRpZF9yeC0+c2VxX3N0YXJ0KTsKCiAgICAvKiBJbiBzb21lIEFQcywgd2UgZm91bmQgdGhhdCBpdCBtaWdodCB0cmFuc21pdCBOVUxMIGRhdGEgd2hvc2Ugc2VxdWVuY2UgbnVtYmVyCiAgICAgICBpcyBvdXQgb3Igb3JkZXIuIEluIG9yZGVyIHRvIGF2b2lkIHRoaXMgcHJvYmxlbSwgd2UgaWdub3JlIHRoZXNlIE5VTEwgZGF0YS4KICAgICAqLwoKICAgIGZyYW1lU3ViVHlwZSA9ICh6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCAwKSAmIDB4RjApID4+IDQ7CgogICAgLyogSWYgdGhpcyBpcyBhIE5VTEwgZGF0YSBpbnN0ZWFkIG9mIFFvcyBOVUxMIGRhdGEgKi8KICAgIGlmICgoZnJhbWVTdWJUeXBlICYgMHgwQykgPT0gMHgwNCkKICAgIHsKICAgICAgICBzMTZfdCBzZXFfZGlmZjsKCiAgICAgICAgc2VxX2RpZmYgPSAoc2VxX25vID4gdGlkX3J4LT5zZXFfc3RhcnQpID8KICAgICAgICAgICAgICAgICAgICAgICBzZXFfbm8gLSB0aWRfcngtPnNlcV9zdGFydCA6IHRpZF9yeC0+c2VxX3N0YXJ0IC0gc2VxX25vOwoKICAgICAgICBpZiAoc2VxX2RpZmYgPiBaTV9BR0dfQkFXX1NJWkUpCiAgICAgICAgewogICAgICAgICAgICB6bV9kZWJ1Z19tc2cwKCJGcmVlIFJ4IE5VTEwgZGF0YSBpbiB6ZkFnZ1J4Iik7CgogICAgICAgICAgICAvKiBGcmVlIFJ4IGJ1ZmZlciAqLwogICAgICAgICAgICB6ZndCdWZGcmVlKGRldiwgYnVmLCAwKTsKICAgICAgICAgICAgcmV0dXJuIFpNX0VSUl9PVVRfT0ZfT1JERVJfTlVMTF9EQVRBOwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogc2VxdWVuY2UgbnVtYmVyIHdyYXAgYXQgNGsKICAgICAqLwogICAgaWYgKHRpZF9yeC0+c2VxX3N0YXJ0ID4gc2VxX25vKQogICAgewogICAgICAgIC8vaW5kZXggKz0gNDA5NjsKCiAgICAgICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICBpZiAodGlkX3J4LT5zZXFfc3RhcnQgPj0gNDA5NikgewogICAgICAgICAgICB0aWRfcngtPnNlcV9zdGFydCA9IDA7CiAgICAgICAgfQogICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgfQoKICAgIGlmICh0aWRfcngtPnNlcV9zdGFydCA9PSBzZXFfbm8pIHsKICAgIAl6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgCWlmICgoKHRpZF9yeC0+YmF3X2hlYWQgLSB0aWRfcngtPmJhd190YWlsKSAmIFpNX0FHR19CQVdfTUFTSykgPiAwKSB7CiAgICAJICAgIC8vRGJnUHJpbnQoImhlYWQ9JWQsIHRhaWw9JWQiLCB0aWRfcngtPmJhd19oZWFkLCB0aWRfcngtPmJhd190YWlsKTsKICAgICAgICAgICAgdGlkX3J4LT5iYXdfdGFpbCA9ICh0aWRfcngtPmJhd190YWlsICsgMSkgJiBaTV9BR0dfQkFXX01BU0s7CiAgICAgICAgfQogICAgICAgIHRpZF9yeC0+c2VxX3N0YXJ0ID0gKHRpZF9yeC0+c2VxX3N0YXJ0ICsgMSkgJiAoNDA5NiAtIDEpOwogICAgCXptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgICAgIFpNX1BFUkZPUk1BTkNFX1JYX1NFUShkZXYsIGJ1Zik7CgogICAgCWlmICh3ZC0+emZjYlJlY3Y4MDIxMSAhPSBOVUxMKSB7CiAgICAgICAgICAgIC8vc2VxX25vID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIGJ1Ziwgb2Zmc2V0KzIyKSA+PiA0OwogICAgICAgICAgICAvL0RiZ1ByaW50KCJSZWN2IGluZGljYXRlIHNlcT0lZFxuIiwgc2VxX25vKTsKICAgICAgICAgICAgLy9EYmdQcmludCgiMS4gc2VxPSVkXG4iLCBzZXFfbm8pOwoKICAgICAgICAgICAgd2QtPnpmY2JSZWN2ODAyMTEoZGV2LCBidWYsIGFkZEluZm8pOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgemZpUmVjdjgwMjExKGRldiwgYnVmLCBhZGRJbmZvKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmICghemZBZ2dSeEVucXVldWUoZGV2LCBidWYsIHRpZF9yeCwgYWRkSW5mbykpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiBkdXBsaWNhdGVkIHBhY2tldAogICAgICAgICAqLwogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIHdoaWxlICh0aWRfcngtPmJhd19oZWFkICE9IHRpZF9yeC0+YmF3X3RhaWwpIHsvLyAmJiB0aWRfcngtPmZyYW1lW3RpZF9yeC0+YmF3X3RhaWxdLmJ1ZikKICAgICAgICB1MTZfdCB0YWlsSW5kZXg7CgogICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgICAgIHRhaWxJbmRleCA9IHRpZF9yeC0+YmF3X3RhaWw7CiAgICAgICAgcGJ1ZiA9IHRpZF9yeC0+ZnJhbWVbdGFpbEluZGV4XS5idWY7CiAgICAgICAgdGlkX3J4LT5mcmFtZVt0YWlsSW5kZXhdLmJ1ZiA9IDA7CiAgICAgICAgaWYgKCFwYnVmKQogICAgICAgIHsKICAgICAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICB0aWRfcngtPmJhd190YWlsID0gKHRpZF9yeC0+YmF3X3RhaWwgKyAxKSAmIFpNX0FHR19CQVdfTUFTSzsKICAgICAgICB0aWRfcngtPnNlcV9zdGFydCA9ICh0aWRfcngtPnNlcV9zdGFydCArIDEpICYgKDQwOTYgLSAxKTsKCgogICAgICAgIC8vaWYocGJ1ZiAmJiB0aWRfcngtPmJhd19zaXplID4gMCkKICAgICAgICAvLyAgICB0aWRfcngtPmJhd19zaXplLS07CgogICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgICAgIFpNX1BFUkZPUk1BTkNFX1JYX1NFUShkZXYsIHBidWYpOwoKICAgICAgICBpZiAod2QtPnpmY2JSZWN2ODAyMTEgIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIC8vc2VxX25vID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIHBidWYsIG9mZnNldCsyMikgPj4gNDsKICAgICAgICAgICAgLy9EYmdQcmludCgiUmVjdiBpbmRpY2F0ZSBzZXE9JWRcbiIsIHNlcV9ubyk7CiAgICAgICAgICAgIC8vRGJnUHJpbnQoIjEuIHNlcT0lZFxuIiwgc2VxX25vKTsKICAgICAgICAgICAgd2QtPnpmY2JSZWN2ODAyMTEoZGV2LCBwYnVmLCBhZGRJbmZvKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLy9zZXFfbm8gPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgcGJ1Ziwgb2Zmc2V0KzIyKSA+PiA0OwogICAgICAgICAgICAvL0RiZ1ByaW50KCJSZWN2IGluZGljYXRlIHNlcT0lZFxuIiwgc2VxX25vKTsKICAgICAgICAgICAgemZpUmVjdjgwMjExKGRldiwgcGJ1ZiwgYWRkSW5mbyk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAxOwp9CgpzdHJ1Y3QgYWdnX3RpZF9yeCAqemZBZ2dSeEdldFF1ZXVlKHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZikKewogICAgdTE2X3QgICBzcmNbM107CiAgICB1MTZfdCAgIGFpZCwgYWMsIGk7CiAgICB1MTZfdCAgIG9mZnNldCA9IDA7CiAgICBzdHJ1Y3QgYWdnX3RpZF9yeCAqdGlkX3J4ID0gTlVMTDsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgLy96bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIHNyY1swXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIG9mZnNldCsxMCk7CiAgICBzcmNbMV0gPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCBvZmZzZXQrMTIpOwogICAgc3JjWzJdID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIGJ1Ziwgb2Zmc2V0KzE0KTsKICAgIGFpZCA9IHpmQXBGaW5kU3RhKGRldiwgc3JjKTsKCiAgICBhYyA9ICh6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCAyNCkgJiAweEYpOwoKICAgIC8vIG1hcmsgYnkgc3BpbiBsb2NrIGRlYnVnCiAgICAvL3ptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgZm9yIChpPTA7IGk8Wk1fQUdHX1BPT0xfU0laRSA7IGkrKykKICAgIHsKICAgICAgICBpZigod2QtPnRpZF9yeFtpXS0+YWlkID09IGFpZCkgJiYgKHdkLT50aWRfcnhbaV0tPmFjID09IGFjKSkKICAgICAgICB7CiAgICAgICAgICAgIHRpZF9yeCA9IHdkLT50aWRfcnhbaV07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBtYXJrIGJ5IHNwaW4gbG9jayBkZWJ1ZwogICAgLy96bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgcmV0dXJuIHRpZF9yeDsKfQoKCnUxNl90ICAgemZBZ2dSeEVucXVldWUoemRldl90KiBkZXYsIHpidWZfdCogYnVmLCBzdHJ1Y3QgYWdnX3RpZF9yeCAqdGlkX3J4LCBzdHJ1Y3QgenNBZGRpdGlvbkluZm8gKmFkZEluZm8pCnsKICAgIHUxNl90IHNlcV9ubywgb2Zmc2V0ID0gMDsKICAgIHUxNl90IHFfaW5kZXg7CiAgICBzMTZfdCBpbmRleDsKICAgIHU4X3QgIGJkcm9wZnJhbWUgPSAwOwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIFpNX0JVRkZFUl9UUkFDRShkZXYsIGJ1ZikKCiAgICBzZXFfbm8gPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCBvZmZzZXQrMjIpID4+IDQ7CiAgICBpbmRleCAgPSBzZXFfbm8gLSB0aWRfcngtPnNlcV9zdGFydDsKCiAgICAvKgogICAgICogc2VxdWVuY2UgbnVtYmVyIHdyYXAgYXQgNGsKICAgICAqIC0xMDAwOiBjaGVjayBmb3IgZHVwbGljYXRlIHBhc3QgcGFja2V0CiAgICAgKi8KICAgIGJkcm9wZnJhbWUgPSAwOwogICAgaWYgKHRpZF9yeC0+c2VxX3N0YXJ0ID4gc2VxX25vKSB7CiAgICAgICAgaWYgKCh0aWRfcngtPnNlcV9zdGFydCA+IDM5NjcpICYmIChzZXFfbm8gPCAxMjgpKSB7CiAgICAgICAgICAgIGluZGV4ICs9IDQwOTY7CiAgICAgICAgfSBlbHNlIGlmICh0aWRfcngtPnNlcV9zdGFydCAtIHNlcV9ubyA+IDcwKSB7CiAgICAgICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgIHRpZF9yeC0+c3FfYmVoaW5kX2NvdW50Kys7CiAgICAgICAgICAgIGlmICh0aWRfcngtPnNxX2JlaGluZF9jb3VudCA+IDMpIHsKICAgICAgICAgICAgICAgIHRpZF9yeC0+c3FfYmVoaW5kX2NvdW50ID0gMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGJkcm9wZnJhbWUgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYmRyb3BmcmFtZSA9IDE7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBpZiAoc2VxX25vIC0gdGlkX3J4LT5zZXFfc3RhcnQgPiA3MCkgewogICAgICAgICAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgICAgICB0aWRfcngtPnNxX2V4Y2VlZF9jb3VudCsrOwogICAgICAgICAgICBpZiAodGlkX3J4LT5zcV9leGNlZWRfY291bnQgPiAzKSB7CiAgICAgICAgICAgICAgICB0aWRfcngtPnNxX2V4Y2VlZF9jb3VudCA9IDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBiZHJvcGZyYW1lID0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoYmRyb3BmcmFtZSA9PSAxKSB7CiAgICAgICAgLyppZiAod2QtPnpmY2JSZWN2ODAyMTEgIT0gTlVMTCkgewogICAgICAgICAgICB3ZC0+emZjYlJlY3Y4MDIxMShkZXYsIGJ1ZiwgYWRkSW5mbyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICB6ZmlSZWN2ODAyMTEoZGV2LCBidWYsIGFkZEluZm8pOwogICAgICAgIH0qLwoKICAgICAgICBaTV9QRVJGT1JNQU5DRV9GUkVFKGRldiwgYnVmKTsKCiAgICAgICAgemZ3QnVmRnJlZShkZXYsIGJ1ZiwgMCk7CiAgICAgICAgLyp6ZkFnZ1J4Rmx1c2goZGV2LCBzZXFfbm8sIHRpZF9yeCk7CiAgICAgICAgdGlkX3J4LT5zZXFfc3RhcnQgPSBzZXFfbm87CiAgICAgICAgaW5kZXggPSBzZXFfbm8gLSB0aWRfcngtPnNlcV9zdGFydDsKICAgICAgICAqLwoKICAgICAgICAvL0RiZ1ByaW50KCJGcmVlIGFuIG9sZCBwYWNrZXQsIHNlcV9zdGFydD0lZCwgc2VxX25vPSVkXG4iLCB0aWRfcngtPnNlcV9zdGFydCwgc2VxX25vKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBkdXBsaWNhdGUgcGFzdCBwYWNrZXQKICAgICAgICAgKiBoYXBwZW5zIG9ubHkgaW4gc2ltdWxhdGVkIGFnZ3JlZ2F0aW9uIGVudmlyb25tZW50CiAgICAgICAgICovCiAgICAgICAgcmV0dXJuIDA7CiAgICB9IGVsc2UgewogICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgaWYgKHRpZF9yeC0+c3FfZXhjZWVkX2NvdW50ID4gMCl7CiAgICAgICAgICAgIHRpZF9yeC0+c3FfZXhjZWVkX2NvdW50LS07CiAgICAgICAgfQoKICAgICAgICBpZiAodGlkX3J4LT5zcV9iZWhpbmRfY291bnQgPiAwKSB7CiAgICAgICAgICAgIHRpZF9yeC0+c3FfYmVoaW5kX2NvdW50LS07CiAgICAgICAgfQogICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICB9CgogICAgaWYgKGluZGV4IDwgMCkgewogICAgICAgIHpmQWdnUnhGbHVzaChkZXYsIHNlcV9ubywgdGlkX3J4KTsKICAgICAgICB0aWRfcngtPnNlcV9zdGFydCA9IHNlcV9ubzsKICAgICAgICBpbmRleCA9IDA7CiAgICB9CgogICAgLy9pZiAoaW5kZXggPj0gKFpNX0FHR19CQVdfU0laRSAtIDEpKQogICAgaWYgKGluZGV4ID49IChaTV9BR0dfQkFXX01BU0spKQogICAgewogICAgICAgIC8qCiAgICAgICAgICogcXVldWUgZnVsbAogICAgICAgICAqLwogICAgICAgIC8vRGJnUHJpbnQoImluZGV4ID49IDY0LCBzZXFfc3RhcnQ9JWQsIHNlcV9ubz0lZFxuIiwgdGlkX3J4LT5zZXFfc3RhcnQsIHNlcV9ubyk7CiAgICAgICAgemZBZ2dSeEZsdXNoKGRldiwgc2VxX25vLCB0aWRfcngpOwogICAgICAgIC8vdGlkX3J4LT5zZXFfc3RhcnQgPSBzZXFfbm87CiAgICAgICAgaW5kZXggPSBzZXFfbm8gLSB0aWRfcngtPnNlcV9zdGFydDsKICAgICAgICBpZiAoKHRpZF9yeC0+c2VxX3N0YXJ0ID4gc2VxX25vKSAmJiAodGlkX3J4LT5zZXFfc3RhcnQgPiAxMDAwKSAmJiAodGlkX3J4LT5zZXFfc3RhcnQgLSAxMDAwKSA+IHNlcV9ubykKICAgICAgICB7CiAgICAgICAgLy9pbmRleCA9IHNlcV9ubyAtIHRpZF9yeC0+c2VxX3N0YXJ0OwogICAgICAgICAgICBpbmRleCArPSA0MDk2OwogICAgICAgIH0KICAgICAgICAvL2luZGV4ID0gc2VxX25vIC0gdGlkX3J4LT5zZXFfc3RhcnQ7CiAgICAgICAgd2hpbGUgKGluZGV4ID49IChaTV9BR0dfQkFXX01BU0spKSB7CiAgICAgICAgICAgIC8vRGJnUHJpbnQoImluZGV4ID49IDY0LCBzZXFfc3RhcnQ9JWQsIHNlcV9ubz0lZFxuIiwgdGlkX3J4LT5zZXFfc3RhcnQsIHNlcV9ubyk7CiAgICAgICAgICAgIHRpZF9yeC0+c2VxX3N0YXJ0ID0gKHRpZF9yeC0+c2VxX3N0YXJ0ICsgWk1fQUdHX0JBV19NQVNLKSAmICg0MDk2IC0gMSk7CiAgICAgICAgICAgIGluZGV4ID0gc2VxX25vIC0gdGlkX3J4LT5zZXFfc3RhcnQ7CiAgICAgICAgICAgIGlmICgodGlkX3J4LT5zZXFfc3RhcnQgPiBzZXFfbm8pICYmICh0aWRfcngtPnNlcV9zdGFydCA+IDEwMDApICYmICh0aWRfcngtPnNlcV9zdGFydCAtIDEwMDApID4gc2VxX25vKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbmRleCArPSA0MDk2OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKCiAgICBxX2luZGV4ID0gKHRpZF9yeC0+YmF3X3RhaWwgKyBpbmRleCkgJiBaTV9BR0dfQkFXX01BU0s7CiAgICBpZiAodGlkX3J4LT5mcmFtZVtxX2luZGV4XS5idWYgJiYgKCgodGlkX3J4LT5iYXdfaGVhZCAtIHRpZF9yeC0+YmF3X3RhaWwpICYgWk1fQUdHX0JBV19NQVNLKSA+CiAgICAgICAgICAgICAgICAoKChxX2luZGV4KSAtIHRpZF9yeC0+YmF3X3RhaWwpICYgWk1fQUdHX0JBV19NQVNLKSkpCiAgICB7CgogICAgICAgIFpNX1BFUkZPUk1BTkNFX0RVUChkZXYsIHRpZF9yeC0+ZnJhbWVbcV9pbmRleF0uYnVmLCBidWYpOwogICAgICAgIHpmd0J1ZkZyZWUoZGV2LCBidWYsIDApOwogICAgICAgIC8vRGJnUHJpbnQoIkZyZWUgYSBkdXBsaWNhdGUgcGFja2V0LCBzZXFfc3RhcnQ9JWQsIHNlcV9ubz0lZFxuIiwgdGlkX3J4LT5zZXFfc3RhcnQsIHNlcV9ubyk7CiAgICAgICAgLy9EYmdQcmludCgiaGVhZD0lZCwgdGFpbD0lZCIsIHRpZF9yeC0+YmF3X2hlYWQsIHRpZF9yeC0+YmF3X3RhaWwpOwogICAgICAgIC8qCiAgICAgICAgICogZHVwbGljYXRlIHBhY2tldAogICAgICAgICAqLwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICBpZih0aWRfcngtPmZyYW1lW3FfaW5kZXhdLmJ1ZikgewogICAgICAgIHpmd0J1ZkZyZWUoZGV2LCB0aWRfcngtPmZyYW1lW3FfaW5kZXhdLmJ1ZiwgMCk7CiAgICAgICAgdGlkX3J4LT5mcmFtZVtxX2luZGV4XS5idWYgPSAwOwogICAgfQoKICAgIHRpZF9yeC0+ZnJhbWVbcV9pbmRleF0uYnVmID0gYnVmOwogICAgdGlkX3J4LT5mcmFtZVtxX2luZGV4XS5hcnJpdmFsVGltZSA9IHptX2FnZ19HZXRUaW1lKCk7CiAgICB6ZndNZW1vcnlDb3B5KCh2b2lkKikmdGlkX3J4LT5mcmFtZVtxX2luZGV4XS5hZGRJbmZvLCAodm9pZCopYWRkSW5mbywgc2l6ZW9mKHN0cnVjdCB6c0FkZGl0aW9uSW5mbykpOwoKICAgIC8qCiAgICAgKiBmb3IgZGVidWcgc2ltdWxhdGVkIGFnZ3JlZ2F0aW9uIG9ubHksCiAgICAgKiBzaG91bGQgYmUgZG9uZSBpbiByeCBvZiBBRERCQSBSZXF1ZXN0CiAgICAgKi8KICAgIC8vdGlkX3J4LT5hZGRJbmZvID0gYWRkSW5mbzsKCgogICAgaWYgKCgodGlkX3J4LT5iYXdfaGVhZCAtIHRpZF9yeC0+YmF3X3RhaWwpICYgWk1fQUdHX0JBV19NQVNLKSA8PSBpbmRleCkKICAgIHsKICAgICAgICAvL3RpZF9yeC0+YmF3X3NpemUgPSBpbmRleCArIDE7CiAgICAgICAgaWYgKCgodGlkX3J4LT5iYXdfaGVhZCAtIHRpZF9yeC0+YmF3X3RhaWwpICYgWk1fQUdHX0JBV19NQVNLKSA8PQogICAgICAgICAgICAgICAgLy8oKHFfaW5kZXggKyAxKSAmIFpNX0FHR19CQVdfTUFTSykpCiAgICAgICAgICAgICAgICAoKChxX2luZGV4KSAtIHRpZF9yeC0+YmF3X3RhaWwpICYgWk1fQUdHX0JBV19NQVNLKSkvL3RpZF9yeC0+YmF3X3NpemUgKQogICAgICAgICAgICB0aWRfcngtPmJhd19oZWFkID0gKHFfaW5kZXggKyAxKSAmIFpNX0FHR19CQVdfTUFTSzsKICAgIH0KICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgLyoKICAgICAqIHN1Y2Nlc3MKICAgICAqLwogICAgLy9EYmdQcmludCgiaGVhZD0lZCwgdGFpbD0lZCwgc3RhcnQ9JWQiLCB0aWRfcngtPmJhd19oZWFkLCB0aWRfcngtPmJhd190YWlsLCB0aWRfcngtPnNlcV9zdGFydCk7CiAgICByZXR1cm4gMTsKfQoKdTE2X3QgemZBZ2dSeEZsdXNoKHpkZXZfdCogZGV2LCB1MTZfdCBzZXFfbm8sIHN0cnVjdCBhZ2dfdGlkX3J4ICp0aWRfcngpCnsKICAgIHpidWZfdCogcGJ1ZjsKICAgIHUxNl90ICAgc2VxOwogICAgc3RydWN0IHpzQWRkaXRpb25JbmZvIGFkZEluZm87CiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIFpNX1BFUkZPUk1BTkNFX1JYX0ZMVVNIKGRldik7CgogICAgd2hpbGUgKDEpCiAgICB7CiAgICAgICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICBpZiAodGlkX3J4LT5iYXdfdGFpbCA9PSB0aWRfcngtPmJhd19oZWFkKSB7CiAgICAgICAgICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgcGJ1ZiA9IHRpZF9yeC0+ZnJhbWVbdGlkX3J4LT5iYXdfdGFpbF0uYnVmOwogICAgICAgIHpmd01lbW9yeUNvcHkoKHZvaWQqKSZhZGRJbmZvLCAodm9pZCopJnRpZF9yeC0+ZnJhbWVbdGlkX3J4LT5iYXdfdGFpbF0uYWRkSW5mbywgc2l6ZW9mKHN0cnVjdCB6c0FkZGl0aW9uSW5mbykpOwogICAgICAgIHRpZF9yeC0+ZnJhbWVbdGlkX3J4LT5iYXdfdGFpbF0uYnVmID0gMDsKICAgICAgICAvL2lmKHBidWYgJiYgdGlkX3J4LT5iYXdfc2l6ZSA+IDApIHRpZF9yeC0+YmF3X3NpemUtLTsKICAgICAgICB0aWRfcngtPmJhd190YWlsID0gKHRpZF9yeC0+YmF3X3RhaWwgKyAxKSAmIFpNX0FHR19CQVdfTUFTSzsKICAgICAgICB0aWRfcngtPnNlcV9zdGFydCA9ICh0aWRfcngtPnNlcV9zdGFydCArIDEpICYgKDQwOTYgLSAxKTsKCSAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgICAgICBpZiAocGJ1ZikKICAgICAgICB7CgogICAgICAgICAgICBaTV9QRVJGT1JNQU5DRV9SWF9TRVEoZGV2LCBwYnVmKTsKCiAgICAgICAgICAgIGlmICh3ZC0+emZjYlJlY3Y4MDIxMSAhPSBOVUxMKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzZXEgPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgcGJ1ZiwgMjIpID4+IDQ7CiAgICAgICAgICAgICAgICAvL0RiZ1ByaW50KCJSZWN2IGluZGljYXRlIHNlcT0lZFxuIiwgc2VxKTsKICAgICAgICAgICAgICAgIC8vRGJnUHJpbnQoIjIuIHNlcT0lZFxuIiwgc2VxKTsKICAgICAgICAgICAgICAgIHdkLT56ZmNiUmVjdjgwMjExKGRldiwgcGJ1ZiwgJmFkZEluZm8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc2VxID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIHBidWYsIDIyKSA+PiA0OwogICAgICAgICAgICAgICAgLy9EYmdQcmludCgiUmVjdiBpbmRpY2F0ZSBzZXE9JWRcbiIsIHNlcSk7CiAgICAgICAgICAgICAgICB6ZmlSZWN2ODAyMTEoZGV2LCBwYnVmLCAmYWRkSW5mbyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgIHRpZF9yeC0+YmF3X2hlYWQgPSB0aWRfcngtPmJhd190YWlsID0gMDsKICAgIHptd19sZWF2ZV9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICByZXR1cm4gMTsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBGVU5DVElPTiBERVNDUklQVElPTiAgICAgICAgICAgICAgICAgIHpmQWdnUnhGcmVlQnVmICAgICAgICAgICAgICAqLwovKiAgICAgIEZyZWVzIGFsbCBxdWV1ZWQgcGFja2V0cyBpbiBidWZmZXIgd2hlbiB0aGUgZHJpdmVyIGlzIGRvd24uICAgICAqLwovKiAgICAgIFRoZSB6ZkZyZWVSZXNvdXJjZSgpIHdpbGwgY2hlY2sgaWYgdGhlIGJ1ZmZlciBpcyBhbGwgZnJlZWQuICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBJTlBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIGRldiAgICAgOiBkZXZpY2UgcG9pbnRlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBPVVRQVVRTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIFpNX1NVQ0NFU1MgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICBBVVRIT1IgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKiAgICAgIEhvbmRhICAgICAgICAgICAgICAgQXRoZXJvcyBDb21tdW5pY2F0aW9ucywgSU5DLiAgICAyMDA2LjEyICAgICAqLwovKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp1MTZfdCAgIHpmQWdnUnhGcmVlQnVmKHpkZXZfdCogZGV2LCB1MTZfdCBkZXN0cm95KQp7CiAgICB1MTZfdCAgIGk7CiAgICB6YnVmX3QqIGJ1ZjsKICAgIHN0cnVjdCBhZ2dfdGlkX3J4ICp0aWRfcng7CgogICAgVElEX1RYICB0aWRfdHg7CiAgICAvL3N0cnVjdCBidWZJbmZvICpidWZfaW5mbzsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIGZvciAoaT0wOyBpPFpNX0FHR19QT09MX1NJWkU7IGkrKykKICAgIHsKICAgICAgICB1MTZfdCBqOwoKICAgICAgICB0aWRfcnggPSB3ZC0+dGlkX3J4W2ldOwoKICAgICAgICBmb3Ioaj0wOyBqIDw9IFpNX0FHR19CQVdfU0laRTsgaisrKQogICAgICAgIHsKICAgICAgICAgICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICAgICAgYnVmID0gdGlkX3J4LT5mcmFtZVtqXS5idWY7CiAgICAgICAgICAgIHRpZF9yeC0+ZnJhbWVbal0uYnVmID0gMDsKICAgICAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICAgICAgICAgIGlmIChidWYpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHpmd0J1ZkZyZWUoZGV2LCBidWYsIDApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAjaWYgMAogICAgICAgIGlmICggdGlkX3J4LT5iYXdfaGVhZCAhPSB0aWRfcngtPmJhd190YWlsICkKICAgICAgICB7CiAgICAgICAgICAgIHdoaWxlICh0aWRfcngtPmJhd19oZWFkICE9IHRpZF9yeC0+YmF3X3RhaWwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGJ1ZiA9IHRpZF9yeC0+ZnJhbWVbdGlkX3J4LT5iYXdfdGFpbF0uYnVmOwogICAgICAgICAgICAgICAgdGlkX3J4LT5mcmFtZVt0aWRfcngtPmJhd190YWlsXS5idWYgPSAwOwogICAgICAgICAgICAgICAgaWYgKGJ1ZikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB6ZndCdWZGcmVlKGRldiwgYnVmLCAwKTsKCiAgICAgICAgICAgICAgICAgICAgem13X2VudGVyX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICAgICAgICAgICAgICB0aWRfcngtPmZyYW1lW3RpZF9yeC0+YmF3X3RhaWxdLmJ1ZiA9IDA7CiAgICAgICAgICAgICAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICAgICAgICAgICAgICAvL2lmICh0aWRfcngtPmJhd19zaXplID4gMCl0aWRfcngtPmJhd19zaXplLS07CiAgICAgICAgICAgICAgICB0aWRfcngtPmJhd190YWlsID0gKHRpZF9yeC0+YmF3X3RhaWwgKyAxKSAmIFpNX0FHR19CQVdfTUFTSzsKICAgICAgICAgICAgICAgIHRpZF9yeC0+c2VxX3N0YXJ0Kys7CiAgICAgICAgICAgICAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICNlbmRpZgoKICAgICAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgICAgIHRpZF9yeC0+c2VxX3N0YXJ0ID0gMDsKICAgICAgICB0aWRfcngtPmJhd19oZWFkID0gdGlkX3J4LT5iYXdfdGFpbCA9IDA7CiAgICAgICAgdGlkX3J4LT5haWQgPSBaTV9NQVhfU1RBX1NVUFBPUlQ7CiAgICAgICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICAgICAgI2lmZGVmIFpNX0VOQUJMRV9BR0dSRUdBVElPTgogICAgICAgICNpZm5kZWYgWk1fRU5BQkxFX0ZXX0JBX1JFVFJBTlNNSVNTSU9OIC8vZGlzYWJsZSBCQVcKICAgICAgICBpZiAodGlkX2Jhdy0+ZW5hYmxlZCkgewogICAgICAgICAgICB6bV9tc2cxX2FnZyhaTV9MVl8wLCAiRGV2aWNlIGRvd24sIGNsZWFyIEJBVyBxdWV1ZToiLCBpKTsKICAgICAgICAgICAgQkFXLT5kaXNhYmxlKGRldiwgdGlkX2Jhdyk7CiAgICAgICAgfQogICAgICAgICNlbmRpZgogICAgICAgICNlbmRpZgogICAgICAgIGlmICgxID09IHdkLT5hZ2dRUG9vbFtpXS0+YWdnUUVuYWJsZWQpIHsKICAgICAgICAgICAgdGlkX3R4ID0gd2QtPmFnZ1FQb29sW2ldOwogICAgICAgICAgICBidWYgPSB6ZkFnZ1R4R2V0VnR4cShkZXYsIHRpZF90eCk7CiAgICAgICAgICAgIHdoaWxlIChidWYpIHsKICAgICAgICAgICAgICAgIHpmd0J1ZkZyZWUoZGV2LCBidWYsIDApOwogICAgICAgICAgICAgICAgYnVmID0gemZBZ2dUeEdldFZ0eHEoZGV2LCB0aWRfdHgpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZihkZXN0cm95KSB7CiAgICAgICAgICAgIHpmd01lbUZyZWUoZGV2LCB3ZC0+YWdnUVBvb2xbaV0sIHNpemVvZihzdHJ1Y3QgYWdnUXVldWUpKTsKICAgICAgICAgICAgemZ3TWVtRnJlZShkZXYsIHdkLT50aWRfcnhbaV0sIHNpemVvZihzdHJ1Y3QgYWdnX3RpZF9yeCkpOwogICAgICAgIH0KICAgIH0KICAgICNpZmRlZiBaTV9FTkFCTEVfQUdHUkVHQVRJT04KICAgICNpZm5kZWYgWk1fRU5BQkxFX0ZXX0JBX1JFVFJBTlNNSVNTSU9OIC8vZGlzYWJsZSBCQVcKICAgIGlmKGRlc3Ryb3kpIHpmd01lbUZyZWUoZGV2LCBCQVcsIHNpemVvZihzdHJ1Y3QgYmF3X2VuYWJsZXIpKTsKICAgICNlbmRpZgogICAgI2VuZGlmCiAgICByZXR1cm4gWk1fU1VDQ0VTUzsKfQoKCnZvaWQgemZBZ2dSZWN2QkFSKHpkZXZfdCogZGV2LCB6YnVmX3QgKmJ1ZikgewogICAgdTE2X3Qgc3RhcnRfc2VxLCBsZW47CiAgICB1OF90IGksIGJpdG1hcFs4XTsKICAgIGxlbiA9IHpmd0J1ZkdldFNpemUoZGV2LCBidWYpOwogICAgc3RhcnRfc2VxID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIGJ1ZiwgbGVuLTIpOwogICAgRGJnUHJpbnQoIlJlY2VpdmVkIGEgQkFSIENvbnRyb2wgZnJhbWUsIHN0YXJ0X3NlcT0lZCIsIHN0YXJ0X3NlcT4+NCk7CiAgICAvKiB0b2RvOiBzZXQgdGhlIGJpdG1hcCBieSByZW9yZGVyaW5nIGJ1ZmZlciEgKi8KICAgIGZvciAoaT0wOyBpPDg7IGkrKykgYml0bWFwW2ldPTA7CiAgICB6ZlNlbmRCQShkZXYsIHN0YXJ0X3NlcSwgYml0bWFwKTsKfQoKI2lmZGVmIFpNX0VOQUJMRV9BR0dSRUdBVElPTgojaWZuZGVmIFpNX0VOQUJMRV9GV19CQV9SRVRSQU5TTUlTU0lPTiAvL2Rpc2FibGUgQkFXCnZvaWQgemZBZ2dUeFJldHJhbnNtaXQoemRldl90KiBkZXYsIHN0cnVjdCBidWZJbmZvICpidWZfaW5mbywgc3RydWN0IGFnZ0NvbnRyb2wgKmFnZ0NvbnRyb2wsIFRJRF9UWCB0aWRfdHgpIHsKICAgIHUxNl90IHJlbW92ZUxlbjsKICAgIHUxNl90IGVycjsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CiAgICBpZiAoYWdnQ29udHJvbCAmJiAoWk1fQUdHX0ZJUlNUX01QRFUgPT0gYWdnQ29udHJvbC0+YW1wZHVJbmRpY2F0aW9uKSApIHsKICAgICAgICB0aWRfdHgtPmJhcl9zc24gPSBidWZfaW5mby0+YmF3X2hlYWRlci0+aGVhZGVyWzE1XTsKICAgICAgICBhZ2dDb250cm9sLT50aWRfYmF3LT5zdGFydF9zZXEgPSB0aWRfdHgtPmJhcl9zc24gPj4gNDsKICAgICAgICB6bV9tc2cxX2FnZyhaTV9MVl8wLCAic3RhcnQgc2VxPSIsIHRpZF90eC0+YmFyX3NzbiA+PiA0KTsKICAgIH0KICAgIGJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5oZWFkZXJbNF0gfD0gKDEgPDwgMTEpOwogICAgaWYgKGFnZ0NvbnRyb2wgJiYgYWdnQ29udHJvbC0+YWdnRW5hYmxlZCkgewogICAgICAgIC8vaWYgKHdkLT5lbmFibGVBZ2dyZWdhdGlvbj09MCAmJiAhKGJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5oZWFkZXJbNl0mMHgxKSkKICAgICAgICAvL3sKICAgICAgICAgICAgLy9pZiAoKChidWZfaW5mby0+YmF3X2hlYWRlci0+aGVhZGVyWzJdICYgMHgzKSA9PSAyKSkKICAgICAgICAgICAgLy97CiAgICAgICAgICAgICAgICAvKiBFbmFibGUgYWdncmVnYXRpb24gKi8KICAgICAgICAgICAgICAgIGJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5oZWFkZXJbMV0gfD0gMHgyMDsKICAgICAgICAgICAgICAgIGlmIChaTV9BR0dfTEFTVF9NUERVID09IGFnZ0NvbnRyb2wtPmFtcGR1SW5kaWNhdGlvbikgewogICAgICAgICAgICAgICAgICAgIGJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5oZWFkZXJbMV0gfD0gMHg0MDAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgYnVmX2luZm8tPmJhd19oZWFkZXItPmhlYWRlclsxXSAmPSB+MHg0MDAwOwogICAgICAgICAgICAgICAgICAgIC8vem1fZGVidWdfbXNnMCgiWk1fQUdHX0xBU1RfTVBEVSIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAvL30KICAgICAgICAgICAgLy9lbHNlIHsKICAgICAgICAgICAgLy8gICAgem1fZGVidWdfbXNnMSgibm8gYWdnciwgaGVhZGVyWzJdJjB4MyA9ICIsYnVmX2luZm8tPmJhd19oZWFkZXItPmhlYWRlclsyXSAmIDB4MykKICAgICAgICAgICAgLy8gICAgYWdnQ29udHJvbC0+YWdnRW5hYmxlZCA9IDA7CiAgICAgICAgICAgIC8vfQogICAgICAgIC8vfQogICAgICAgIC8vZWxzZSB7CiAgICAgICAgLy8gICAgem1fZGVidWdfbXNnMSgibm8gYWdnciwgd2QtPmVuYWJsZUFnZ3JlZ2F0aW9uID0gIiwgd2QtPmVuYWJsZUFnZ3JlZ2F0aW9uKTsKICAgICAgICAvLyAgICB6bV9kZWJ1Z19tc2cxKCJubyBhZ2dyLCAhaGVhZGVyWzZdJjB4MSA9ICIsIShidWZfaW5mby0+YmF3X2hlYWRlci0+aGVhZGVyWzZdJjB4MSkpOwogICAgICAgIC8vICAgIGFnZ0NvbnRyb2wtPmFnZ0VuYWJsZWQgPSAwOwogICAgICAgIC8vfQogICAgfQoKICAgIC8qaWYgKGFnZ0NvbnRyb2wtPnRpZF9iYXcpIHsKICAgICAgICBzdHJ1Y3QgYmF3X2hlYWRlcl9yIGhlYWRlcl9yOwoKICAgICAgICBoZWFkZXJfci5oZWFkZXIgICAgICA9IGJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5oZWFkZXI7CiAgICAgICAgaGVhZGVyX3IubWljICAgICAgICAgPSBidWZfaW5mby0+YmF3X2hlYWRlci0+bWljOwogICAgICAgIGhlYWRlcl9yLnNuYXAgICAgICAgID0gYnVmX2luZm8tPmJhd19oZWFkZXItPnNuYXA7CiAgICAgICAgaGVhZGVyX3IuaGVhZGVyTGVuICAgPSBidWZfaW5mby0+YmF3X2hlYWRlci0+aGVhZGVyTGVuOwogICAgICAgIGhlYWRlcl9yLm1pY0xlbiAgICAgID0gYnVmX2luZm8tPmJhd19oZWFkZXItPm1pY0xlbjsKICAgICAgICBoZWFkZXJfci5zbmFwTGVuICAgICA9IGJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5zbmFwTGVuOwogICAgICAgIGhlYWRlcl9yLnJlbW92ZUxlbiAgID0gYnVmX2luZm8tPmJhd19oZWFkZXItPnJlbW92ZUxlbjsKICAgICAgICBoZWFkZXJfci5rZXlJZHggICAgICA9IGJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5rZXlJZHg7CgogICAgICAgIEJBVy0+aW5zZXJ0KGRldiwgYnVmX2luZm8tPmJ1ZiwgdGlkX3R4LT5iYXJfc3NuID4+IDQsIGFnZ0NvbnRyb2wtPnRpZF9iYXcsIGJ1Zl9pbmZvLT5iYXdfcmV0cmFuc21pdCwgJmhlYWRlcl9yKTsKICAgIH0qLwoKICAgIGVyciA9IHpmSHBTZW5kKGRldiwKICAgICAgICAgICAgICAgICAgICBidWZfaW5mby0+YmF3X2hlYWRlci0+aGVhZGVyLAogICAgICAgICAgICAgICAgICAgIGJ1Zl9pbmZvLT5iYXdfaGVhZGVyLT5oZWFkZXJMZW4sCiAgICAgICAgICAgICAgICAgICAgYnVmX2luZm8tPmJhd19oZWFkZXItPnNuYXAsCiAgICAgICAgICAgICAgICAgICAgYnVmX2luZm8tPmJhd19oZWFkZXItPnNuYXBMZW4sCiAgICAgICAgICAgICAgICAgICAgYnVmX2luZm8tPmJhd19oZWFkZXItPm1pYywKICAgICAgICAgICAgICAgICAgICBidWZfaW5mby0+YmF3X2hlYWRlci0+bWljTGVuLAogICAgICAgICAgICAgICAgICAgIGJ1Zl9pbmZvLT5idWYsCiAgICAgICAgICAgICAgICAgICAgYnVmX2luZm8tPmJhd19oZWFkZXItPnJlbW92ZUxlbiwKICAgICAgICAgICAgICAgICAgICBaTV9FWFRFUk5BTF9BTExPQ19CVUYsCiAgICAgICAgICAgICAgICAgICAgKHU4X3QpdGlkX3R4LT5hYywKICAgICAgICAgICAgICAgICAgICBidWZfaW5mby0+YmF3X2hlYWRlci0+a2V5SWR4KTsKICAgIGlmIChlcnIgIT0gWk1fU1VDQ0VTUykKICAgIHsKICAgICAgICBnb3RvIHpsRXJyb3I7CiAgICB9CgogICAgcmV0dXJuOwoKemxFcnJvcjoKICAgIHpmd0J1ZkZyZWUoZGV2LCBidWZfaW5mby0+YnVmLCAwKTsKICAgIHJldHVybjsKCn0KI2VuZGlmIC8vZGlzYWJsZSBCQVcKI2VuZGlmCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEZVTkNUSU9OIERFU0NSSVBUSU9OICAgICAgICAgICAgICAgICAgemZBZ2dUeFNlbmRFdGggICAgICAgICAgICAgICovCi8qICAgICAgQ2FsbGVkIHRvIHRyYW5zbWl0IEV0aGVybmV0IGZyYW1lIGZyb20gdXBwZXIgZWxheWVyLiAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIElOUFVUUyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZGV2IDogZGV2aWNlIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgYnVmIDogYnVmZmVyIHBvaW50ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgcG9ydCA6IFdMQU4gcG9ydCwgMD0+c3RhbmRhcmQsIDB4MTAtMHgxNz0+VkFQLCAweDIwLTB4MjU9PldEUyAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIE9VVFBVVFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgZXJyb3IgY29kZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgIEFVVEhPUiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qICAgICAgU3RlcGhlbiwgSG9uZGEgICAgICBBdGhlcm9zIENvbW11bmljYXRpb25zLCBJbmMuICAgIDIwMDYuMTIgICAgICovCi8qICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnUxNl90IHpmQWdnVHhTZW5kRXRoKHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZiwgdTE2X3QgcG9ydCwgdTE2X3QgYnVmVHlwZSwgdThfdCBmbGFnLCBzdHJ1Y3QgYWdnQ29udHJvbCAqYWdnQ29udHJvbCwgVElEX1RYIHRpZF90eCkKewogICAgdTE2X3QgZXJyOwogICAgLy91MTZfdCBhZGRyVGJsU2l6ZTsKICAgIC8vc3RydWN0IHpzQWRkclRibCBhZGRyVGJsOwogICAgdTE2X3QgcmVtb3ZlTGVuOwogICAgdTE2X3QgaGVhZGVyWyg4KzMwKzIrMTgpLzJdOyAgICAvKiBjdHIrKDQrYTErYTIrYTMrMithNCkrcW9zK2l2ICovCiAgICB1MTZfdCBoZWFkZXJMZW47CiAgICB1MTZfdCBtaWNbOC8yXTsKICAgIHUxNl90IG1pY0xlbjsKICAgIHUxNl90IHNuYXBbOC8yXTsKICAgIHUxNl90IHNuYXBMZW47CiAgICB1MTZfdCBmcmFnTGVuOwogICAgdTE2X3QgZnJhbWVMZW47CiAgICB1MTZfdCBmcmFnTnVtOwogICAgc3RydWN0IHpzRnJhZyBmcmFnOwogICAgdTE2X3QgaSwgaWQ7CiAgICB1MTZfdCBkYVszXTsKICAgIHUxNl90IHNhWzNdOwogICAgdThfdCB1cDsKICAgIHU4X3QgcW9zVHlwZSwga2V5SWR4ID0gMDsKICAgIHUxNl90IGZyYWdPZmY7CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgem1fbXNnMV90eChaTV9MVl8yLCAiemZUeFNlbmRFdGgoKSwgcG9ydD0iLCBwb3J0KTsKCiAgICAvKiBHZXQgSVAgVE9TIGZvciBRb1MgQUMgYW5kIElQIGZyYWcgb2Zmc2V0ICovCiAgICB6ZlR4R2V0SXBUb3NBbmRGcmFnKGRldiwgYnVmLCAmdXAsICZmcmFnT2ZmKTsKCiNpZmRlZiBaTV9FTkFCTEVfTkFUSVZFX1dJRkkKICAgIGlmICggd2QtPndsYW5Nb2RlID09IFpNX01PREVfSU5GUkFTVFJVQ1RVUkUgKQogICAgewogICAgICAgIC8qIERBICovCiAgICAgICAgZGFbMF0gPSB6bXdfdHhfYnVmX3JlYWRoKGRldiwgYnVmLCAxNik7CiAgICAgICAgZGFbMV0gPSB6bXdfdHhfYnVmX3JlYWRoKGRldiwgYnVmLCAxOCk7CiAgICAgICAgZGFbMl0gPSB6bXdfdHhfYnVmX3JlYWRoKGRldiwgYnVmLCAyMCk7CiAgICAgICAgLyogU0EgKi8KICAgICAgICBzYVswXSA9IHptd190eF9idWZfcmVhZGgoZGV2LCBidWYsIDEwKTsKICAgICAgICBzYVsxXSA9IHptd190eF9idWZfcmVhZGgoZGV2LCBidWYsIDEyKTsKICAgICAgICBzYVsyXSA9IHptd190eF9idWZfcmVhZGgoZGV2LCBidWYsIDE0KTsKICAgIH0KICAgIGVsc2UgaWYgKCB3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9JQlNTICkKICAgIHsKICAgICAgICAvKiBEQSAqLwogICAgICAgIGRhWzBdID0gem13X3R4X2J1Zl9yZWFkaChkZXYsIGJ1ZiwgNCk7CiAgICAgICAgZGFbMV0gPSB6bXdfdHhfYnVmX3JlYWRoKGRldiwgYnVmLCA2KTsKICAgICAgICBkYVsyXSA9IHptd190eF9idWZfcmVhZGgoZGV2LCBidWYsIDgpOwogICAgICAgIC8qIFNBICovCiAgICAgICAgc2FbMF0gPSB6bXdfdHhfYnVmX3JlYWRoKGRldiwgYnVmLCAxMCk7CiAgICAgICAgc2FbMV0gPSB6bXdfdHhfYnVmX3JlYWRoKGRldiwgYnVmLCAxMik7CiAgICAgICAgc2FbMl0gPSB6bXdfdHhfYnVmX3JlYWRoKGRldiwgYnVmLCAxNCk7CiAgICB9CiAgICBlbHNlIGlmICggd2QtPndsYW5Nb2RlID09IFpNX01PREVfQVAgKQogICAgewogICAgICAgIC8qIERBICovCiAgICAgICAgZGFbMF0gPSB6bXdfdHhfYnVmX3JlYWRoKGRldiwgYnVmLCA0KTsKICAgICAgICBkYVsxXSA9IHptd190eF9idWZfcmVhZGgoZGV2LCBidWYsIDYpOwogICAgICAgIGRhWzJdID0gem13X3R4X2J1Zl9yZWFkaChkZXYsIGJ1ZiwgOCk7CiAgICAgICAgLyogU0EgKi8KICAgICAgICBzYVswXSA9IHptd190eF9idWZfcmVhZGgoZGV2LCBidWYsIDE2KTsKICAgICAgICBzYVsxXSA9IHptd190eF9idWZfcmVhZGgoZGV2LCBidWYsIDE4KTsKICAgICAgICBzYVsyXSA9IHptd190eF9idWZfcmVhZGgoZGV2LCBidWYsIDIwKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvLwogICAgfQojZWxzZQogICAgLyogREEgKi8KICAgIGRhWzBdID0gem13X3R4X2J1Zl9yZWFkaChkZXYsIGJ1ZiwgMCk7CiAgICBkYVsxXSA9IHptd190eF9idWZfcmVhZGgoZGV2LCBidWYsIDIpOwogICAgZGFbMl0gPSB6bXdfdHhfYnVmX3JlYWRoKGRldiwgYnVmLCA0KTsKICAgIC8qIFNBICovCiAgICBzYVswXSA9IHptd190eF9idWZfcmVhZGgoZGV2LCBidWYsIDYpOwogICAgc2FbMV0gPSB6bXdfdHhfYnVmX3JlYWRoKGRldiwgYnVmLCA4KTsKICAgIHNhWzJdID0gem13X3R4X2J1Zl9yZWFkaChkZXYsIGJ1ZiwgMTApOwojZW5kaWYKICAgIC8vRGVjaWRlIEtleSBJbmRleCBpbiBBVE9NLCBObyBtZWFuaW5nIGluIE9UVVMtLUNXWWFuZyhtKQogICAgaWYgKHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX0FQKQogICAgewogICAgICAgIGtleUlkeCA9IHdkLT5hcC5iY0hhbEtleUlkeFtwb3J0XTsKICAgICAgICBpZCA9IHpmQXBGaW5kU3RhKGRldiwgZGEpOwogICAgICAgIGlmIChpZCAhPSAweGZmZmYpCiAgICAgICAgewogICAgICAgICAgICBzd2l0Y2ggKHdkLT5hcC5zdGFUYWJsZVtpZF0uZW5jcnlNb2RlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgWk1fQUVTOgogICAgICAgICAgICBjYXNlIFpNX1RLSVA6CiNpZmRlZiBaTV9FTkFCTEVfQ0VOQwogICAgICAgICAgICBjYXNlIFpNX0NFTkM6CiNlbmRpZiAvL1pNX0VOQUJMRV9DRU5DCiAgICAgICAgICAgICAgICBrZXlJZHggPSB3ZC0+YXAuc3RhVGFibGVbaWRdLmtleUlkeDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN3aXRjaCAod2QtPnN0YS5lbmNyeU1vZGUpCiAgICAgICAgewogICAgICAgIGNhc2UgWk1fV0VQNjQ6CiAgICAgICAgY2FzZSBaTV9XRVAxMjg6CiAgICAgICAgY2FzZSBaTV9XRVAyNTY6CiAgICAgICAgICAgIGtleUlkeCA9IHdkLT5zdGEua2V5SWQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWk1fQUVTOgogICAgICAgIGNhc2UgWk1fVEtJUDoKICAgICAgICAgICAgaWYgKChkYVswXSYgMHgxKSkKICAgICAgICAgICAgICAgIGtleUlkeCA9IDU7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGtleUlkeCA9IDQ7CiAgICAgICAgICAgIGJyZWFrOwojaWZkZWYgWk1fRU5BQkxFX0NFTkMKICAgICAgICBjYXNlIFpNX0NFTkM6CiAgICAgICAgICAgIGtleUlkeCA9IHdkLT5zdGEuY2VuY0tleUlkOwogICAgICAgICAgICBicmVhazsKI2VuZGlmIC8vWk1fRU5BQkxFX0NFTkMKICAgICAgICB9CiAgICB9CgogICAgLyogQ3JlYXRlIFNOQVAgKi8KICAgIHJlbW92ZUxlbiA9IHpmVHhHZW5XbGFuU25hcChkZXYsIGJ1Ziwgc25hcCwgJnNuYXBMZW4pOwogICAgLy96bV9tc2cxX3R4KFpNX0xWXzAsICJmcmFnT2ZmPSIsIGZyYWdPZmYpOwoKICAgIGZyYWdMZW4gPSB3ZC0+ZnJhZ1RocmVzaG9sZDsKICAgIGZyYW1lTGVuID0gemZ3QnVmR2V0U2l6ZShkZXYsIGJ1Zik7CiAgICBmcmFtZUxlbiAtPSByZW1vdmVMZW47CgojaWYgMAogICAgLyogQ3JlYXRlIE1JQyAqLwogICAgaWYgKCAod2QtPndsYW5Nb2RlID09IFpNX01PREVfSU5GUkFTVFJVQ1RVUkUpJiYKICAgICAgICAgKHdkLT5zdGEuZW5jcnlNb2RlID09IFpNX1RLSVApICkKICAgIHsKICAgICAgICBpZiAoIGZyYW1lTGVuID4gZnJhZ0xlbiApCiAgICAgICAgewogICAgICAgICAgICBtaWNMZW4gPSB6ZlR4R2VuV2xhblRhaWwoZGV2LCBidWYsIHNuYXAsIHNuYXBMZW4sIG1pYyk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIGFwcGVuZCBNSUMgYnkgSE1BQyAqLwogICAgICAgICAgICBtaWNMZW4gPSA4OwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBtaWNMZW4gPSAwOwogICAgfQojZWxzZQogICAgaWYgKCBmcmFtZUxlbiA+IGZyYWdMZW4gKQogICAgewogICAgICAgIG1pY0xlbiA9IHpmVHhHZW5XbGFuVGFpbChkZXYsIGJ1Ziwgc25hcCwgc25hcExlbiwgbWljKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBhcHBlbmQgTUlDIGJ5IEhNQUMgKi8KICAgICAgICBtaWNMZW4gPSAwOwogICAgfQojZW5kaWYKCiAgICAvKiBBY2Nlc3MgQ2F0ZWdvcnkgKi8KICAgIGlmICh3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9BUCkKICAgIHsKICAgICAgICB6ZkFwR2V0U3RhUW9zVHlwZShkZXYsIGRhLCAmcW9zVHlwZSk7CiAgICAgICAgaWYgKHFvc1R5cGUgPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHVwID0gMDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmICh3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9JTkZSQVNUUlVDVFVSRSkKICAgIHsKICAgICAgICBpZiAod2QtPnN0YS53bWVDb25uZWN0ZWQgPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHVwID0gMDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogVE9ETyA6IFNUQSBRb1MgY29udHJvbCBmaWVsZCAqLwogICAgICAgIHVwID0gMDsKICAgIH0KCiAgICAvKiBBc3NpZ24gc2VxdWVuY2UgbnVtYmVyICovCiAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgZnJhZy5zZXFbMF0gPSAoKHdkLT5zZXFbemNVcFRvQWNbdXAmMHg3XV0rKykgPDwgNCk7CiAgICBpZiAoYWdnQ29udHJvbCAmJiAoWk1fQUdHX0ZJUlNUX01QRFUgPT0gYWdnQ29udHJvbC0+YW1wZHVJbmRpY2F0aW9uKSApIHsKICAgICAgICB0aWRfdHgtPmJhcl9zc24gPSBmcmFnLnNlcVswXTsKCiAgICAgICAgem1fbXNnMV9hZ2coWk1fTFZfMCwgInN0YXJ0IHNlcT0iLCB0aWRfdHgtPmJhcl9zc24gPj4gNCk7CiAgICB9CiAgICAvL3RpZF90eC0+YmF3X2J1Zlt0aWRfdHgtPmJhd19oZWFkLTFdLmJhd19zZXE9ZnJhZy5zZXFbMF07CiAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKCiAgICAgICAgZnJhZy5idWZbMF0gPSBidWY7CiAgICAgICAgZnJhZy5idWZUeXBlWzBdID0gYnVmVHlwZTsKICAgICAgICBmcmFnLmZsYWdbMF0gPSBmbGFnOwogICAgICAgIGZyYWdOdW0gPSAxOwoKICAgIGZvciAoaT0wOyBpPGZyYWdOdW07IGkrKykKICAgIHsKICAgICAgICAvKiBDcmVhdGUgV0xBTiBoZWFkZXIoQ29udHJvbCBTZXR0aW5nICsgODAyLjExIGhlYWRlciArIElWKSAqLwogICAgICAgIGlmICh1cCAhPTAgKSB6bV9kZWJ1Z19tc2cxKCJ1cCBub3QgMCwgdXA9Iix1cCk7CiAgICAgICAgaGVhZGVyTGVuID0gemZUeEdlbldsYW5IZWFkZXIoZGV2LCBmcmFnLmJ1ZltpXSwgaGVhZGVyLCBmcmFnLnNlcVtpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFnLmZsYWdbaV0sIHNuYXBMZW4rbWljTGVuLCByZW1vdmVMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9ydCwgZGEsIHNhLCB1cCwgJm1pY0xlbiwgc25hcCwgc25hcExlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2dDb250cm9sKTsKCiAgICAgICAgLyogR2V0IGJ1ZmZlciBETUEgYWRkcmVzcyAqLwogICAgICAgIC8vaWYgKChhZGRyVGJsU2l6ZSA9IHpmd0J1Zk1hcERtYShkZXYsIGZyYWcuYnVmW2ldLCAmYWRkclRibCkpID09IDApCiAgICAgICAgLy9pZiAoKGFkZHJUYmxTaXplID0gemZ3TWFwVHhEbWEoZGV2LCBmcmFnLmJ1ZltpXSwgJmFkZHJUYmwpKSA9PSAwKQogICAgICAgIC8vewogICAgICAgIC8vICAgIGVyciA9IFpNX0VSUl9CVUZGRVJfRE1BX0FERFI7CiAgICAgICAgLy8gICAgZ290byB6bEVycm9yOwogICAgICAgIC8vfQoKICAgICAgICAvKiBGbHVzaCBidWZmZXIgb24gY2FjaGUgKi8KICAgICAgICAvL3pmd0J1ZkZsdXNoKGRldiwgZnJhZy5idWZbaV0pOwoKI2lmIDAKICAgICAgICB6bV9tc2cxX3R4KFpNX0xWXzAsICJoZWFkZXJMZW49IiwgaGVhZGVyTGVuKTsKICAgICAgICB6bV9tc2cxX3R4KFpNX0xWXzAsICJzbmFwTGVuPSIsIHNuYXBMZW4pOwogICAgICAgIHptX21zZzFfdHgoWk1fTFZfMCwgIm1pY0xlbj0iLCBtaWNMZW4pOwogICAgICAgIHptX21zZzFfdHgoWk1fTFZfMCwgInJlbW92ZUxlbj0iLCByZW1vdmVMZW4pOwogICAgICAgIHptX21zZzFfdHgoWk1fTFZfMCwgImFkZHJUYmxTaXplPSIsIGFkZHJUYmxTaXplKTsKICAgICAgICB6bV9tc2cxX3R4KFpNX0xWXzAsICJmcmFnLmJ1ZlR5cGVbMF09IiwgZnJhZy5idWZUeXBlWzBdKTsKI2VuZGlmCgogICAgICAgIGZyYWdMZW4gPSB6ZndCdWZHZXRTaXplKGRldiwgZnJhZy5idWZbaV0pOwogICAgICAgIGlmICgoZGFbMF0mMHgxKSA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgd2QtPmNvbW1UYWxseS50eFVuaWNhc3RGcm0rKzsKICAgICAgICAgICAgd2QtPmNvbW1UYWxseS50eFVuaWNhc3RPY3RldHMgKz0gKGZyYWdMZW4rc25hcExlbik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKChkYVswXSYgMHgxKSkKICAgICAgICB7CiAgICAgICAgICAgIHdkLT5jb21tVGFsbHkudHhCcm9hZGNhc3RGcm0rKzsKICAgICAgICAgICAgd2QtPmNvbW1UYWxseS50eEJyb2FkY2FzdE9jdGV0cyArPSAoZnJhZ0xlbitzbmFwTGVuKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgd2QtPmNvbW1UYWxseS50eE11bHRpY2FzdEZybSsrOwogICAgICAgICAgICB3ZC0+Y29tbVRhbGx5LnR4TXVsdGljYXN0T2N0ZXRzICs9IChmcmFnTGVuK3NuYXBMZW4pOwogICAgICAgIH0KICAgICAgICB3ZC0+bGVkU3RydWN0LnR4VHJhZmZpYysrOwoKI2lmIDAgLy9XaG8gY2FyZSB0aGlzPwogICAgICAgIGlmICggKGkpJiYoaSA9PSAoZnJhZ051bS0xKSkgKQogICAgICAgIHsKICAgICAgICAgICAgd2QtPnRyYWZUYWxseS50eERhdGFCeXRlQ291bnQgLT0gbWljTGVuOwogICAgICAgIH0KI2VuZGlmCgogICAgICAgIC8qaWYgKGFnZ0NvbnRyb2wtPnRpZF9iYXcgJiYgYWdnQ29udHJvbC0+YWdnRW5hYmxlZCkgewogICAgICAgICAgICBzdHJ1Y3QgYmF3X2hlYWRlcl9yIGhlYWRlcl9yOwoKICAgICAgICAgICAgaGVhZGVyX3IuaGVhZGVyICAgICAgPSBoZWFkZXI7CiAgICAgICAgICAgIGhlYWRlcl9yLm1pYyAgICAgICAgID0gbWljOwogICAgICAgICAgICBoZWFkZXJfci5zbmFwICAgICAgICA9IHNuYXA7CiAgICAgICAgICAgIGhlYWRlcl9yLmhlYWRlckxlbiAgID0gaGVhZGVyTGVuOwogICAgICAgICAgICBoZWFkZXJfci5taWNMZW4gICAgICA9IG1pY0xlbjsKICAgICAgICAgICAgaGVhZGVyX3Iuc25hcExlbiAgICAgPSBzbmFwTGVuOwogICAgICAgICAgICBoZWFkZXJfci5yZW1vdmVMZW4gICA9IHJlbW92ZUxlbjsKICAgICAgICAgICAgaGVhZGVyX3Iua2V5SWR4ICAgICAgPSBrZXlJZHg7CgogICAgICAgICAgICBCQVctPmluc2VydChkZXYsIGJ1ZiwgdGlkX3R4LT5iYXJfc3NuID4+IDQsIGFnZ0NvbnRyb2wtPnRpZF9iYXcsIDAsICZoZWFkZXJfcik7CiAgICAgICAgfSovCgogICAgICAgIGVyciA9IHpmSHBTZW5kKGRldiwgaGVhZGVyLCBoZWFkZXJMZW4sIHNuYXAsIHNuYXBMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWljLCBtaWNMZW4sIGZyYWcuYnVmW2ldLCByZW1vdmVMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhZy5idWZUeXBlW2ldLCB6Y1VwVG9BY1t1cCYweDddLCBrZXlJZHgpOwogICAgICAgIGlmIChlcnIgIT0gWk1fU1VDQ0VTUykKICAgICAgICB7CiAgICAgICAgICAgIGdvdG8gemxFcnJvcjsKICAgICAgICB9CgoKICAgICAgICBjb250aW51ZTsKCnpsRXJyb3I6CiAgICAgICAgaWYgKGZyYWcuYnVmVHlwZVtpXSA9PSBaTV9FWFRFUk5BTF9BTExPQ19CVUYpCiAgICAgICAgewogICAgICAgICAgICB6ZndCdWZGcmVlKGRldiwgZnJhZy5idWZbaV0sIGVycik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGZyYWcuYnVmVHlwZVtpXSA9PSBaTV9JTlRFUk5BTF9BTExPQ19CVUYpCiAgICAgICAgewogICAgICAgICAgICB6ZndCdWZGcmVlKGRldiwgZnJhZy5idWZbaV0sIDApOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICB6bV9hc3NlcnQoMCk7CiAgICAgICAgfQogICAgfSAvKiBmb3IgKGk9MDsgaTxmcmFnTnVtOyBpKyspICovCgogICAgcmV0dXJuIFpNX1NVQ0NFU1M7Cn0KCi8qCiAqIHpmQWdnU2VuZEFEREJBKCkgcmVmZXJzIHpmU2VuZE1tRnJhbWUoKSBpbiBjbW0uYwogKi8KdTE2X3QgICB6ZkFnZ1NlbmRBZGRiYVJlcXVlc3QoemRldl90KiBkZXYsIHUxNl90ICpkc3QsIHUxNl90IGFjLCB1MTZfdCB1cCkKewogICAgemJ1Zl90KiBidWY7CiAgICAvL3UxNl90IGFkZHJUYmxTaXplOwogICAgLy9zdHJ1Y3QgenNBZGRyVGJsIGFkZHJUYmw7CiAgICAvL3UxNl90IGVycjsKICAgIHUxNl90IG9mZnNldCA9IDA7CiAgICB1MTZfdCBobGVuID0gMzI7CiAgICB1MTZfdCBoZWFkZXJbKDI0KzI1KzEpLzJdOwogICAgdTE2X3QgdmFwID0gMDsKICAgIHUxNl90IGk7CiAgICB1OF90IGVuY3J5cHQgPSAwOwoKICAgIC8vem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCgogICAgLyoKICAgICAqIFRCRCA6IE1heGltdW0gc2l6ZSBvZiBtYW5hZ2VtZW50IGZyYW1lCiAgICAgKi8KICAgIGJ1ZiA9IHpmd0J1ZkFsbG9jYXRlKGRldiwgMTAyNCk7CiAgICBpZiAoYnVmID09IE5VTEwpCiAgICB7CiAgICAgICAgem1fbXNnMF9tbShaTV9MVl8wLCAiQWxsb2MgbW0gYnVmIEZhaWwhIik7CiAgICAgICAgcmV0dXJuIFpNX1NVQ0NFU1M7CiAgICB9CgogICAgLyoKICAgICAqIFJlc2VydmUgcm9vbSBmb3Igd2xhbiBoZWFkZXIKICAgICAqLwogICAgb2Zmc2V0ID0gaGxlbjsKCiAgICAvKgogICAgICogYWRkIGFkZGJhIGZyYW1lIGJvZHkKICAgICAqLwogICAgb2Zmc2V0ID0gemZBZ2dTZXRBZGRiYUZyYW1lQm9keShkZXYsIGJ1Ziwgb2Zmc2V0LCBhYywgdXApOwoKCiAgICB6ZndCdWZTZXRTaXplKGRldiwgYnVmLCBvZmZzZXQpOwoKICAgIC8qCiAgICAgKiBDb3B5IHdsYW4gaGVhZGVyCiAgICAgKi8KICAgIHpmQWdnR2VuQWRkYmFIZWFkZXIoZGV2LCBkc3QsIGhlYWRlciwgb2Zmc2V0LWhsZW4sIGJ1ZiwgdmFwLCBlbmNyeXB0KTsKICAgIGZvciAoaT0wOyBpPChobGVuPj4xKTsgaSsrKQogICAgewogICAgICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBpKjIsIGhlYWRlcltpXSk7CiAgICB9CgogICAgLyogR2V0IGJ1ZmZlciBETUEgYWRkcmVzcyAqLwogICAgLy9pZiAoKGFkZHJUYmxTaXplID0gemZ3QnVmTWFwRG1hKGRldiwgYnVmLCAmYWRkclRibCkpID09IDApCiAgICAvL2lmICgoYWRkclRibFNpemUgPSB6ZndNYXBUeERtYShkZXYsIGJ1ZiwgJmFkZHJUYmwpKSA9PSAwKQogICAgLy97CiAgICAvLyAgICBnb3RvIHpsRXJyb3I7CiAgICAvL30KCiAgICAvL3ptX21zZzJfbW0oWk1fTFZfMiwgIm9mZnNldD0iLCBvZmZzZXQpOwogICAgLy96bV9tc2cyX21tKFpNX0xWXzIsICJobGVuPSIsIGhsZW4pOwogICAgLy96bV9tc2cyX21tKFpNX0xWXzIsICJhZGRyVGJsU2l6ZT0iLCBhZGRyVGJsU2l6ZSk7CiAgICAvL3ptX21zZzJfbW0oWk1fTFZfMiwgImFkZHJUYmwubGVuWzBdPSIsIGFkZHJUYmwubGVuWzBdKTsKICAgIC8vem1fbXNnMl9tbShaTV9MVl8yLCAiYWRkclRibC5waHlzQWRkcmxbMF09IiwgYWRkclRibC5waHlzQWRkcmxbMF0pOwogICAgLy96bV9tc2cyX21tKFpNX0xWXzIsICJidWYtPmRhdGE9IiwgYnVmLT5kYXRhKTsKCiAgICAjaWYgMAogICAgZXJyID0gemZIcFNlbmQoZGV2LCBOVUxMLCAwLCBOVUxMLCAwLCBOVUxMLCAwLCBidWYsIDAsCgkJICAgWk1fSU5URVJOQUxfQUxMT0NfQlVGLCAwLCAweGZmKTsKICAgIGlmIChlcnIgIT0gWk1fU1VDQ0VTUykKICAgIHsKICAgICAgICBnb3RvIHpsRXJyb3I7CiAgICB9CiAgICAjZWxzZQogICAgemZQdXRWbW1xKGRldiwgYnVmKTsKICAgIHpmUHVzaFZ0eHEoZGV2KTsKICAgICNlbmRpZgoKICAgIHJldHVybiBaTV9TVUNDRVNTOwoKfQoKdTE2X3QgICB6ZkFnZ1NldEFkZGJhRnJhbWVCb2R5KHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZiwgdTE2X3Qgb2Zmc2V0LCB1MTZfdCBhYywgdTE2X3QgdXApCnsKICAgIHUxNl90IGJhX3BhcmFtZXRlciwgc3RhcnRfc2VxOwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICAvL3ptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CiAgICAvKgogICAgICogQUREQkEgUmVxdWVzdCBmcmFtZSBib2R5CiAgICAgKi8KCiAgICAvKgogICAgICogQ2F0ZWdvcnkKICAgICAqLwogICAgem13X3R4X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCAzKTsKICAgIC8qCiAgICAgKiBBY3Rpb24gZGV0YWlscyA9IDAKICAgICAqLwogICAgem13X3R4X2J1Zl93cml0ZWIoZGV2LCBidWYsIG9mZnNldCsrLCBaTV9XTEFOX0FEREJBX1JFUVVFU1RfRlJBTUUpOwogICAgLyoKICAgICAqIERpYWxvZyBUb2tlbiA9IG5vbnplcm8KICAgICAqIFRCRDogZGVmaW5lIGhvdyB0byBnZXQgZGlhbG9nIHRva2VuPwogICAgICovCiAgICB6bXdfdHhfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIDIpOwogICAgLyoKICAgICAqIEJsb2NrIEFjayBwYXJhbWV0ZXIgc2V0CiAgICAgKiBCQSBwb2xpY3kgPSAxIGZvciBpbW1lZGlhdGUgQkEsIDAgZm9yIGRlbGF5ZWQgQkEKICAgICAqIFRJRCg0Yml0cykgJiBidWZmZXIgc2l6ZSg0Yml0cykgKFRJRD11cCAmIGJ1ZmZlciBzaXplPTB4ODApCiAgICAgKiBUQkQ6IGhvdyB0byBnZXQgYnVmZmVyIHNpemU/CiAgICAgKiCieqJ3oneid6J3oneid6J3oneid6J3onOid6J3oneid6J3oneid6J3oneid6J3onOid6J3oneid6J3oneid6J3onOid6J3oneid6J3oneid6J3oneid6J3oneid6J7CiAgICAgKiCieCAgICBCMCAgICCieCAgICBCMSAgICAgonggQjIgIEI1IKJ4IEI2ICAgICAgQjE1IKJ4CiAgICAgKiCidaJ3oneid6J3oneid6J3oneid6J3onGid6J3oneid6J3oneid6J3oneid6J3onGid6J3oneid6J3oneid6J3onGid6J3oneid6J3oneid6J3oneid6J3oneid6J0CiAgICAgKiCieCBSZXNlcnZlZCCieCBCQSBwb2xpY3kgonggIFRJRCAgIKJ4IEJ1ZmZlciBzaXplIKJ4CiAgICAgKiCifKJ3oneid6J3oneid6J3oneid6J3onKid6J3oneid6J3oneid6J3oneid6J3onKid6J3oneid6J3oneid6J3onKid6J3oneid6J3oneid6J3oneid6J3oneid6J9CiAgICAgKi8KICAgIGJhX3BhcmFtZXRlciA9IDEgPDwgMTI7ICAgICAvLyBidWZmZXIgc2l6ZSA9IDB4NDAoNjQpCiAgICBiYV9wYXJhbWV0ZXIgfD0gdXAgPDwgMjsgICAgLy8gdGlkID0gdXAKICAgIGJhX3BhcmFtZXRlciB8PSAyOyAgICAgICAgICAvLyBiYSBwb2xpY3kgPSAxCiAgICB6bXdfdHhfYnVmX3dyaXRlaChkZXYsIGJ1Ziwgb2Zmc2V0LCBiYV9wYXJhbWV0ZXIpOwogICAgb2Zmc2V0Kz0yOwogICAgLyoKICAgICAqIEJBIHRpbWVvdXQgdmFsdWUKICAgICAqLwogICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIG9mZnNldCwgMCk7CiAgICBvZmZzZXQrPTI7CiAgICAvKgogICAgICogQkEgc3RhcnRpbmcgc2VxdWVuY2UgbnVtYmVyCiAgICAgKiCieqJ3oneid6J3oneid6J3oneid6J3oneid6J3onOid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneiewogICAgICogonggQjAgICAgICAgQjMgonggQjQgICAgICAgICAgICAgIEIxNSCieAogICAgICogonWid6J3oneid6J3oneid6J3oneid6J3oneid6Jxoneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3onQKICAgICAqIKJ4IEZyYWcgbnVtKDApIKJ4IEJBIHN0YXJ0aW5nIHNlcSBudW0gongKICAgICAqIKJ8oneid6J3oneid6J3oneid6J3oneid6J3oneicqJ3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J9CiAgICAgKi8KICAgIHN0YXJ0X3NlcSA9ICgod2QtPnNlcVthY10pIDw8IDQpICYgMHhGRkYwOwogICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIG9mZnNldCwgc3RhcnRfc2VxKTsKICAgIG9mZnNldCs9MjsKCiAgICByZXR1cm4gb2Zmc2V0Owp9Cgp1MTZfdCB6ZkFnZ0dlbkFkZGJhSGVhZGVyKHpkZXZfdCogZGV2LCB1MTZfdCogZHN0LAogICAgICAgIHUxNl90KiBoZWFkZXIsIHUxNl90IGxlbiwgemJ1Zl90KiBidWYsIHUxNl90IHZhcCwgdThfdCBlbmNyeXB0KQp7CiAgICB1OF90ICBobGVuID0gMzI7ICAgICAgICAvLyBNQUMgY3RybCArIFBIWSBjdHJsICsgODAyLjExIE1NIGhlYWRlcgogICAgLy91OF90IGZyYW1lVHlwZSA9IFpNX1dMQU5fRlJBTUVfVFlQRV9BQ1RJT047CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgLyoKICAgICAqIEdlbmVyYXRlIGNvbnRyb2wgc2V0dGluZwogICAgICovCiAgICAvL2JvZHlMZW4gPSB6ZndCdWZHZXRTaXplKGRldiwgYnVmKTsKICAgIGhlYWRlclswXSA9IDI0K2xlbis0OyAgIC8vTGVuZ3RoCiAgICBoZWFkZXJbMV0gPSAweDg7ICAgICAgICAvL01BQyBjb250cm9sLCBiYWNrb2ZmICsgKGFjaykKCiNpZiAwCiAgICAvKiBDQ0sgMU0gKi8KICAgIGhlYWRlclsyXSA9IDB4MGYwMDsgICAgICAgICAgLy9QSFkgY29udHJvbCBMCiAgICBoZWFkZXJbM10gPSAweDAwMDA7ICAgICAgICAgIC8vUEhZIGNvbnRyb2wgSAojZWxzZQogICAgLyogT0ZETSA2TSAqLwogICAgaGVhZGVyWzJdID0gMHgwZjAxOyAgICAgICAgICAvL1BIWSBjb250cm9sIEwKICAgIGhlYWRlclszXSA9IDB4MDAwQjsgICAgICAgICAgLy9QSFkgY29udHJvbCBICiNlbmRpZgoKICAgIC8qCiAgICAgKiBHZW5lcmF0ZSBXTEFOIGhlYWRlcgogICAgICogRnJhbWUgY29udHJvbCBmcmFtZSB0eXBlIGFuZCBzdWJ0eXBlCiAgICAgKi8KICAgIGhlYWRlcls0KzBdID0gWk1fV0xBTl9GUkFNRV9UWVBFX0FDVElPTjsKICAgIC8qCiAgICAgKiBEdXJhdGlvbgogICAgICovCiAgICBoZWFkZXJbNCsxXSA9IDA7CgogICAgaWYgKHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX0lORlJBU1RSVUNUVVJFKQogICAgewogICAgICAgIGhlYWRlcls0KzhdID0gd2QtPnN0YS5ic3NpZFswXTsKICAgICAgICBoZWFkZXJbNCs5XSA9IHdkLT5zdGEuYnNzaWRbMV07CiAgICAgICAgaGVhZGVyWzQrMTBdID0gd2QtPnN0YS5ic3NpZFsyXTsKICAgIH0KICAgIGVsc2UgaWYgKHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX1BTRVVETykKICAgIHsKICAgICAgICAvKiBBZGRyZXNzIDMgPSAwMDowMDowMDowMDowMDowMCAqLwogICAgICAgIGhlYWRlcls0KzhdID0gMDsKICAgICAgICBoZWFkZXJbNCs5XSA9IDA7CiAgICAgICAgaGVhZGVyWzQrMTBdID0gMDsKICAgIH0KICAgIGVsc2UgaWYgKHdkLT53bGFuTW9kZSA9PSBaTV9NT0RFX0lCU1MpCiAgICB7CiAgICAgICAgaGVhZGVyWzQrOF0gPSB3ZC0+c3RhLmJzc2lkWzBdOwogICAgICAgIGhlYWRlcls0KzldID0gd2QtPnN0YS5ic3NpZFsxXTsKICAgICAgICBoZWFkZXJbNCsxMF0gPSB3ZC0+c3RhLmJzc2lkWzJdOwogICAgfQogICAgZWxzZSBpZiAod2QtPndsYW5Nb2RlID09IFpNX01PREVfQVApCiAgICB7CiAgICAgICAgLyogQWRkcmVzcyAzID0gQlNTSUQgKi8KICAgICAgICBoZWFkZXJbNCs4XSA9IHdkLT5tYWNBZGRyWzBdOwogICAgICAgIGhlYWRlcls0KzldID0gd2QtPm1hY0FkZHJbMV07CiAgICAgICAgaGVhZGVyWzQrMTBdID0gd2QtPm1hY0FkZHJbMl0gKyAodmFwPDw4KTsKICAgIH0KCiAgICAvKiBBZGRyZXNzIDEgPSBEQSAqLwogICAgaGVhZGVyWzQrMl0gPSBkc3RbMF07CiAgICBoZWFkZXJbNCszXSA9IGRzdFsxXTsKICAgIGhlYWRlcls0KzRdID0gZHN0WzJdOwoKICAgIC8qIEFkZHJlc3MgMiA9IFNBICovCiAgICBoZWFkZXJbNCs1XSA9IHdkLT5tYWNBZGRyWzBdOwogICAgaGVhZGVyWzQrNl0gPSB3ZC0+bWFjQWRkclsxXTsKICAgIGlmICh3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9BUCkKICAgIHsKICAgICAgICBoZWFkZXJbNCs3XSA9IHdkLT5tYWNBZGRyWzJdICsgKHZhcDw8OCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaGVhZGVyWzQrN10gPSB3ZC0+bWFjQWRkclsyXTsKICAgIH0KCiAgICAvKiBTZXF1ZW5jZSBDb250cm9sICovCiAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwogICAgaGVhZGVyWzQrMTFdID0gKCh3ZC0+bW1zZXErKyk8PDQpOwogICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCgogICAgcmV0dXJuIGhsZW47Cn0KCgp1MTZfdCAgIHpmQWdnUHJvY2Vzc0FjdGlvbih6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYpCnsKICAgIHUxNl90IGNhdGVnb3J5OwoKICAgIC8vem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCiAgICBjYXRlZ29yeSA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIDI0KTsKCiAgICBzd2l0Y2ggKGNhdGVnb3J5KQogICAgewogICAgY2FzZSBaTV9XTEFOX0JMT0NLX0FDS19BQ1RJT05fRlJBTUU6CiAgICAgICAgemZBZ2dCbG9ja0Fja0FjdGlvbkZyYW1lKGRldiwgYnVmKTsKICAgICAgICBicmVhazsKCiAgICB9CgogICAgcmV0dXJuIFpNX1NVQ0NFU1M7Cn0KCgp1MTZfdCAgIHpmQWdnQmxvY2tBY2tBY3Rpb25GcmFtZSh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYpCnsKICAgIHU4X3QgYWN0aW9uOwoKICAgIC8vem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCiAgICBhY3Rpb24gPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCAyNSk7CiNpZmRlZiBaTV9FTkFCTEVfQUdHUkVHQVRJT04KICAgIHN3aXRjaCAoYWN0aW9uKQogICAgewogICAgY2FzZSBaTV9XTEFOX0FEREJBX1JFUVVFU1RfRlJBTUU6CiAgICAgICAgem1fbXNnMF9hZ2coWk1fTFZfMCwgIlJlY2VpdmVkIEJBIEFjdGlvbiBmcmFtZSBpcyBBRERCQSByZXF1ZXN0Iik7CiAgICAgICAgemZBZ2dSZWN2QWRkYmFSZXF1ZXN0KGRldiwgYnVmKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgWk1fV0xBTl9BRERCQV9SRVNQT05TRV9GUkFNRToKICAgICAgICB6bV9tc2cwX2FnZyhaTV9MVl8wLCAiUmVjZWl2ZWQgQkEgQWN0aW9uIGZyYW1lIGlzIEFEREJBIHJlc3BvbnNlIik7CiAgICAgICAgemZBZ2dSZWN2QWRkYmFSZXNwb25zZShkZXYsIGJ1Zik7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFpNX1dMQU5fREVMQkFfRlJBTUU6CiAgICAgICAgemZBZ2dSZWN2RGVsYmEoZGV2LCBidWYpOwogICAgICAgIGJyZWFrOwogICAgfQojZW5kaWYKICAgIHJldHVybiBaTV9TVUNDRVNTOwp9Cgp1MTZfdCAgIHpmQWdnUmVjdkFkZGJhUmVxdWVzdCh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYpCnsKICAgIC8vdTE2X3QgZGlhbG9nOwogICAgc3RydWN0IGFnZ0JhRnJhbWVQYXJhbWV0ZXIgYmY7CiAgICB1MTZfdCBpOwogICAgLy96bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgLy96bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIGJmLmJ1ZiA9IGJ1ZjsKICAgIGJmLmRpYWxvZyA9IHptd19yeF9idWZfcmVhZGIoZGV2LCBidWYsIDI2KTsKICAgIC8qCiAgICAgKiBiYSBwYXJhbWV0ZXIgc2V0CiAgICAgKi8KICAgIGJmLmJhX3BhcmFtZXRlciA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDI3KTsKICAgIGJmLmJhX3BvbGljeSAgID0gKGJmLmJhX3BhcmFtZXRlciA+PiAxKSAmIDE7CiAgICBiZi50aWQgICAgICAgICA9IChiZi5iYV9wYXJhbWV0ZXIgPj4gMikgJiAweEY7CiAgICBiZi5idWZmZXJfc2l6ZSA9IChiZi5iYV9wYXJhbWV0ZXIgPj4gNik7CiAgICAvKgogICAgICogQkEgdGltZW91dCB2YWx1ZQogICAgICovCiAgICBiZi5iYV90aW1lb3V0ID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIGJ1ZiwgMjkpOwogICAgLyoKICAgICAqIEJBIHN0YXJ0aW5nIHNlcXVlbmNlIG51bWJlcgogICAgICovCiAgICBiZi5iYV9zdGFydF9zZXEgPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCAzMSkgPj4gNDsKCiAgICBpPTI2OwogICAgd2hpbGUoaSA8IDMyKSB7CiAgICAgICAgem1fZGVidWdfbXNnMigiUmVjdiBBRERCQSBSZXE6Iiwgem13X3J4X2J1Zl9yZWFkYihkZXYsYnVmLGkpKTsKICAgICAgICBpKys7CiAgICB9CgogICAgemZBZ2dTZW5kQWRkYmFSZXNwb25zZShkZXYsICZiZik7CgogICAgemZBZ2dBZGRiYVNldFRpZFJ4KGRldiwgYnVmLCAmYmYpOwoKICAgIHJldHVybiBaTV9TVUNDRVNTOwp9Cgp1MTZfdCAgIHpmQWdnQWRkYmFTZXRUaWRSeCh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYsIHN0cnVjdCBhZ2dCYUZyYW1lUGFyYW1ldGVyICpiZikKewogICAgdTE2X3QgaSwgYWMsIGFpZCwgZnJhZ09mZjsKICAgIHUxNl90IHNyY1szXTsKICAgIHUxNl90IG9mZnNldCA9IDA7CiAgICB1OF90ICB1cDsKICAgIHN0cnVjdCBhZ2dfdGlkX3J4ICp0aWRfcnggPSBOVUxMOwoKICAgIHptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICB6bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIHNyY1swXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIG9mZnNldCsxMCk7CiAgICBzcmNbMV0gPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCBvZmZzZXQrMTIpOwogICAgc3JjWzJdID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIGJ1Ziwgb2Zmc2V0KzE0KTsKICAgIGFpZCA9IHpmQXBGaW5kU3RhKGRldiwgc3JjKTsKCiAgICB6ZlR4R2V0SXBUb3NBbmRGcmFnKGRldiwgYnVmLCAmdXAsICZmcmFnT2ZmKTsKICAgIGFjID0gemNVcFRvQWNbdXAmMHg3XSAmIDB4MzsKCiAgICBhYyA9IGJmLT50aWQ7CgogICAgZm9yIChpPTA7IGk8Wk1fQUdHX1BPT0xfU0laRSA7IGkrKykKICAgIHsKICAgICAgICBpZigod2QtPnRpZF9yeFtpXS0+YWlkID09IGFpZCkgJiYgKHdkLT50aWRfcnhbaV0tPmFjID09IGFjKSkKICAgICAgICB7CiAgICAgICAgICAgIHRpZF9yeCA9IHdkLT50aWRfcnhbaV07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoIXRpZF9yeCkKICAgIHsKICAgICAgICBmb3IgKGk9MDsgaTxaTV9BR0dfUE9PTF9TSVpFOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAod2QtPnRpZF9yeFtpXS0+YWlkID09IFpNX01BWF9TVEFfU1VQUE9SVCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGlkX3J4ID0gd2QtPnRpZF9yeFtpXTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmICghdGlkX3J4KQogICAgICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICB6bXdfZW50ZXJfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKICAgIHRpZF9yeC0+YWlkID0gYWlkOwogICAgdGlkX3J4LT5hYyA9IGFjOwogICAgdGlkX3J4LT5hZGRCYUV4Y2hhbmdlU3RhdHVzQ29kZSA9IFpNX0FHR19BRERCQV9SRVNQT05TRTsKICAgIHRpZF9yeC0+c2VxX3N0YXJ0ID0gYmYtPmJhX3N0YXJ0X3NlcTsKICAgIHRpZF9yeC0+YmF3X2hlYWQgPSB0aWRfcngtPmJhd190YWlsID0gMDsKICAgIHRpZF9yeC0+c3FfZXhjZWVkX2NvdW50ID0gdGlkX3J4LT5zcV9iZWhpbmRfY291bnQgPSAwOwogICAgem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICByZXR1cm4gMDsKfQoKdTE2X3QgICB6ZkFnZ1JlY3ZBZGRiYVJlc3BvbnNlKHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZikKewogICAgdTE2X3QgaSxhYywgYWlkPTA7CiAgICB1MTZfdCBzcmNbM107CiAgICBzdHJ1Y3QgYWdnQmFGcmFtZVBhcmFtZXRlciBiZjsKCiAgICB6bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgLy96bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwoKICAgIHNyY1swXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDEwKTsKICAgIHNyY1sxXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDEyKTsKICAgIHNyY1syXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDE0KTsKCiAgICBpZiAod2QtPndsYW5Nb2RlID09IFpNX01PREVfQVApCiAgICAgICAgYWlkID0gemZBcEZpbmRTdGEoZGV2LCBzcmMpOwoKCiAgICBiZi5idWYgPSBidWY7CiAgICBiZi5kaWFsb2cgPSB6bXdfcnhfYnVmX3JlYWRiKGRldiwgYnVmLCAyNik7CiAgICBiZi5zdGF0dXNfY29kZSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDI3KTsKICAgIGlmICghYmYuc3RhdHVzX2NvZGUpCiAgICB7CiAgICAgICAgd2QtPmFkZGJhQ29tcGxldGU9MTsKICAgIH0KCiAgICAvKgogICAgICogYmEgcGFyYW1ldGVyIHNldAogICAgICovCiAgICBiZi5iYV9wYXJhbWV0ZXIgPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYnVmLCAyOSk7CiAgICBiZi5iYV9wb2xpY3kgICA9IChiZi5iYV9wYXJhbWV0ZXIgPj4gMSkgJiAxOwogICAgYmYudGlkICAgICAgICAgPSAoYmYuYmFfcGFyYW1ldGVyID4+IDIpICYgMHhGOwogICAgYmYuYnVmZmVyX3NpemUgPSAoYmYuYmFfcGFyYW1ldGVyID4+IDYpOwogICAgLyoKICAgICAqIEJBIHRpbWVvdXQgdmFsdWUKICAgICAqLwogICAgYmYuYmFfdGltZW91dCA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBidWYsIDMxKTsKCiAgICBpPTI2OwogICAgd2hpbGUoaSA8IDMyKSB7CiAgICAgICAgem1fZGVidWdfbXNnMigiUmVjdiBBRERCQSBSc3A6Iiwgem13X3J4X2J1Zl9yZWFkYihkZXYsYnVmLGkpKTsKICAgICAgICBpKys7CiAgICB9CgogICAgYWMgPSB6Y1VwVG9BY1tiZi50aWQmMHg3XSAmIDB4MzsKCiAgICAvL3ptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CgogICAgLy93ZC0+YWdnU3RhW2FpZF0uYWdnRmxhZ1thY10gPSAwOwoKICAgIC8vem13X2xlYXZlX2NyaXRpY2FsX3NlY3Rpb24oZGV2KTsKCiAgICByZXR1cm4gWk1fU1VDQ0VTUzsKfQoKdTE2X3QgICB6ZkFnZ1JlY3ZEZWxiYSh6ZGV2X3QqIGRldiwgemJ1Zl90KiBidWYpCnsKICAgIC8vem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKICAgIHJldHVybiBaTV9TVUNDRVNTOwp9Cgp1MTZfdCAgIHpmQWdnU2VuZEFkZGJhUmVzcG9uc2UoemRldl90KiBkZXYsIHN0cnVjdCBhZ2dCYUZyYW1lUGFyYW1ldGVyICpiZikKewogICAgemJ1Zl90KiBidWY7CiAgICAvL3UxNl90IGFkZHJUYmxTaXplOwogICAgLy9zdHJ1Y3QgenNBZGRyVGJsIGFkZHJUYmw7CiAgICAvL3UxNl90IGVycjsKICAgIHUxNl90IG9mZnNldCA9IDA7CiAgICB1MTZfdCBobGVuID0gMzI7CiAgICB1MTZfdCBoZWFkZXJbKDI0KzI1KzEpLzJdOwogICAgdTE2X3QgdmFwID0gMDsKICAgIHUxNl90IGk7CiAgICB1OF90IGVuY3J5cHQgPSAwOwogICAgdTE2X3QgZHN0WzNdOwoKICAgIC8vem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKCgogICAgLyoKICAgICAqIFRCRCA6IE1heGltdW0gc2l6ZSBvZiBtYW5hZ2VtZW50IGZyYW1lCiAgICAgKi8KICAgIGJ1ZiA9IHpmd0J1ZkFsbG9jYXRlKGRldiwgMTAyNCk7CiAgICBpZiAoYnVmID09IE5VTEwpCiAgICB7CiAgICAgICAgem1fbXNnMF9tbShaTV9MVl8wLCAiQWxsb2MgbW0gYnVmIEZhaWwhIik7CiAgICAgICAgcmV0dXJuIFpNX1NVQ0NFU1M7CiAgICB9CgogICAgLyoKICAgICAqIFJlc2VydmUgcm9vbSBmb3Igd2xhbiBoZWFkZXIKICAgICAqLwogICAgb2Zmc2V0ID0gaGxlbjsKCiAgICAvKgogICAgICogYWRkIGFkZGJhIGZyYW1lIGJvZHkKICAgICAqLwogICAgb2Zmc2V0ID0gemZBZ2dTZXRBZGRiYVJlc3BvbnNlRnJhbWVCb2R5KGRldiwgYnVmLCBiZiwgb2Zmc2V0KTsKCgogICAgemZ3QnVmU2V0U2l6ZShkZXYsIGJ1Ziwgb2Zmc2V0KTsKCiAgICAvKgogICAgICogQ29weSB3bGFuIGhlYWRlcgogICAgICovCgogICAgZHN0WzBdID0gem13X3J4X2J1Zl9yZWFkaChkZXYsIGJmLT5idWYsIDEwKTsKICAgIGRzdFsxXSA9IHptd19yeF9idWZfcmVhZGgoZGV2LCBiZi0+YnVmLCAxMik7CiAgICBkc3RbMl0gPSB6bXdfcnhfYnVmX3JlYWRoKGRldiwgYmYtPmJ1ZiwgMTQpOwogICAgemZBZ2dHZW5BZGRiYUhlYWRlcihkZXYsIGRzdCwgaGVhZGVyLCBvZmZzZXQtaGxlbiwgYnVmLCB2YXAsIGVuY3J5cHQpOwogICAgZm9yIChpPTA7IGk8KGhsZW4+PjEpOyBpKyspCiAgICB7CiAgICAgICAgem13X3R4X2J1Zl93cml0ZWgoZGV2LCBidWYsIGkqMiwgaGVhZGVyW2ldKTsKICAgIH0KCiAgICAvKiBHZXQgYnVmZmVyIERNQSBhZGRyZXNzICovCiAgICAvL2lmICgoYWRkclRibFNpemUgPSB6ZndCdWZNYXBEbWEoZGV2LCBidWYsICZhZGRyVGJsKSkgPT0gMCkKICAgIC8vaWYgKChhZGRyVGJsU2l6ZSA9IHpmd01hcFR4RG1hKGRldiwgYnVmLCAmYWRkclRibCkpID09IDApCiAgICAvL3sKICAgIC8vICAgIGdvdG8gemxFcnJvcjsKICAgIC8vfQoKICAgIC8vem1fbXNnMl9tbShaTV9MVl8yLCAib2Zmc2V0PSIsIG9mZnNldCk7CiAgICAvL3ptX21zZzJfbW0oWk1fTFZfMiwgImhsZW49IiwgaGxlbik7CiAgICAvL3ptX21zZzJfbW0oWk1fTFZfMiwgImFkZHJUYmxTaXplPSIsIGFkZHJUYmxTaXplKTsKICAgIC8vem1fbXNnMl9tbShaTV9MVl8yLCAiYWRkclRibC5sZW5bMF09IiwgYWRkclRibC5sZW5bMF0pOwogICAgLy96bV9tc2cyX21tKFpNX0xWXzIsICJhZGRyVGJsLnBoeXNBZGRybFswXT0iLCBhZGRyVGJsLnBoeXNBZGRybFswXSk7CiAgICAvL3ptX21zZzJfbW0oWk1fTFZfMiwgImJ1Zi0+ZGF0YT0iLCBidWYtPmRhdGEpOwoKICAgICNpZiAwCiAgICBlcnIgPSB6ZkhwU2VuZChkZXYsIE5VTEwsIDAsIE5VTEwsIDAsIE5VTEwsIDAsIGJ1ZiwgMCwKCQkgICBaTV9JTlRFUk5BTF9BTExPQ19CVUYsIDAsIDB4ZmYpOwogICAgaWYgKGVyciAhPSBaTV9TVUNDRVNTKQogICAgewogICAgICAgIGdvdG8gemxFcnJvcjsKICAgIH0KICAgICNlbHNlCiAgICB6ZlB1dFZtbXEoZGV2LCBidWYpOwogICAgemZQdXNoVnR4cShkZXYpOwogICAgI2VuZGlmCgogICAgLy96ZkFnZ1NlbmRBZGRiYVJlcXVlc3QoZGV2LCBkc3QsIHpjVXBUb0FjW2JmLT50aWQmMHg3XSAmIDB4MywgYmYtPnRpZCk7CiAgICByZXR1cm4gWk1fU1VDQ0VTUzsKCn0KCnUxNl90ICAgemZBZ2dTZXRBZGRiYVJlc3BvbnNlRnJhbWVCb2R5KHpkZXZfdCogZGV2LCB6YnVmX3QqIGJ1ZiwKICAgICAgICAgICAgICAgIHN0cnVjdCBhZ2dCYUZyYW1lUGFyYW1ldGVyICpiZiwgdTE2X3Qgb2Zmc2V0KQp7CgogICAgLy96bXdfZ2V0X3dsYW5fZGV2KGRldik7CgogICAgLy96bXdfZGVjbGFyZV9mb3JfY3JpdGljYWxfc2VjdGlvbigpOwogICAgLyoKICAgICAqIEFEREJBIFJlcXVlc3QgZnJhbWUgYm9keQogICAgICovCgogICAgLyoKICAgICAqIENhdGVnb3J5CiAgICAgKi8KICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgMyk7CiAgICAvKgogICAgICogQWN0aW9uIGRldGFpbHMgPSAwCiAgICAgKi8KICAgIHptd190eF9idWZfd3JpdGViKGRldiwgYnVmLCBvZmZzZXQrKywgWk1fV0xBTl9BRERCQV9SRVNQT05TRV9GUkFNRSk7CiAgICAvKgogICAgICogRGlhbG9nIFRva2VuID0gbm9uemVybwogICAgICovCiAgICB6bXdfdHhfYnVmX3dyaXRlYihkZXYsIGJ1Ziwgb2Zmc2V0KyssIGJmLT5kaWFsb2cpOwogICAgLyoKICAgICAqIFN0YXR1cyBjb2RlCiAgICAgKi8KICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBvZmZzZXQsIDApOwogICAgb2Zmc2V0Kz0yOwogICAgLyoKICAgICAqIEJsb2NrIEFjayBwYXJhbWV0ZXIgc2V0CiAgICAgKiBCQSBwb2xpY3kgPSAxIGZvciBpbW1lZGlhdGUgQkEsIDAgZm9yIGRlbGF5ZWQgQkEKICAgICAqIFRJRCg0Yml0cykgJiBidWZmZXIgc2l6ZSg0Yml0cykgKFRJRD0weDEgJiBidWZmZXIgc2l6ZT0weDgwKQogICAgICogVEJEOiBob3cgdG8gZ2V0IFRJRCBudW1iZXIgYW5kIGJ1ZmZlciBzaXplPwogICAgICogonqid6J3oneid6J3oneid6J3oneid6Jzoneid6J3oneid6J3oneid6J3oneid6Jzoneid6J3oneid6J3oneid6Jzoneid6J3oneid6J3oneid6J3oneid6J3oneiewogICAgICogonggICAgQjAgICAgonggICAgQjEgICAgIKJ4IEIyICBCNSCieCBCNiAgICAgIEIxNSCieAogICAgICogonWid6J3oneid6J3oneid6J3oneid6Jxoneid6J3oneid6J3oneid6J3oneid6Jxoneid6J3oneid6J3oneid6Jxoneid6J3oneid6J3oneid6J3oneid6J3oneidAogICAgICogonggUmVzZXJ2ZWQgonggQkEgcG9saWN5IKJ4ICBUSUQgICCieCBCdWZmZXIgc2l6ZSCieAogICAgICogonyid6J3oneid6J3oneid6J3oneid6Jyoneid6J3oneid6J3oneid6J3oneid6Jyoneid6J3oneid6J3oneid6Jyoneid6J3oneid6J3oneid6J3oneid6J3oneifQogICAgICovCiAgICB6bXdfdHhfYnVmX3dyaXRlaChkZXYsIGJ1Ziwgb2Zmc2V0LCBiZi0+YmFfcGFyYW1ldGVyKTsKICAgIG9mZnNldCs9MjsKICAgIC8qCiAgICAgKiBCQSB0aW1lb3V0IHZhbHVlCiAgICAgKi8KICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBvZmZzZXQsIGJmLT5iYV90aW1lb3V0KTsKICAgIG9mZnNldCs9MjsKCiAgICByZXR1cm4gb2Zmc2V0Owp9Cgp2b2lkICAgemZBZ2dJbnZva2VCYXIoemRldl90KiBkZXYsIFRJRF9UWCB0aWRfdHgpCnsKICAgIHN0cnVjdCBhZ2dCYXJDb250cm9sIGFnZ0JhckNvbnRyb2w7CiAgICAvL3ptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICAvL3ptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CiAgICAvL2Jhcl9jb250cm9sID0gYWdnQmFyQ29udHJvbC0+dGlkX2luZm8gPDwgMTIgfCBhZ2dCYXJDb250cm9sLT5jb21wcmVzc2VkX2JpdG1hcCA8PCAyCiAgICAvLyAgICAgICAgfCBhZ2dCYXJDb250cm9sLT5tdWx0aV90aWQgPDwgMSB8IGFnZ0JhckNvbnRyb2wtPmJhcl9hY2tfcG9saWN5OwogICAgYWdnQmFyQ29udHJvbC5iYXJfYWNrX3BvbGljeSA9IDA7CiAgICBhZ2dCYXJDb250cm9sLm11bHRpX3RpZCA9IDA7CiAgICBhZ2dCYXJDb250cm9sLmNvbXByZXNzZWRfYml0bWFwID0gMDsKICAgIGFnZ0JhckNvbnRyb2wudGlkX2luZm8gPSB0aWRfdHgtPnRpZDsKICAgIHpmQWdnU2VuZEJhcihkZXYsIHRpZF90eCwgJmFnZ0JhckNvbnRyb2wpOwoKICAgIHJldHVybjsKCn0KLyoKICogemZBZ2dTZW5kQmFyKCkgcmVmZXJzIHpmQWdnU2VuZEFkZGJhUmVxdWVzdCgpCiAqLwp1MTZfdCAgIHpmQWdnU2VuZEJhcih6ZGV2X3QqIGRldiwgVElEX1RYIHRpZF90eCwgc3RydWN0IGFnZ0JhckNvbnRyb2wgKmFnZ0JhckNvbnRyb2wpCnsKICAgIHpidWZfdCogYnVmOwogICAgLy91MTZfdCBhZGRyVGJsU2l6ZTsKICAgIC8vc3RydWN0IHpzQWRkclRibCBhZGRyVGJsOwogICAgLy91MTZfdCBlcnI7CiAgICB1MTZfdCBvZmZzZXQgPSAwOwogICAgdTE2X3QgaGxlbiA9IDE2Kzg7ICAvKiBtYWMgaGVhZGVyICsgY29udHJvbCBoZWFkZXJzKi8KICAgIHUxNl90IGhlYWRlclsoOCsyNCsxKS8yXTsKICAgIHUxNl90IHZhcCA9IDA7CiAgICB1MTZfdCBpOwogICAgdThfdCBlbmNyeXB0ID0gMDsKCiAgICAvL3ptd19nZXRfd2xhbl9kZXYoZGV2KTsKCiAgICAvL3ptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgoKICAgIC8qCiAgICAgKiBUQkQgOiBNYXhpbXVtIHNpemUgb2YgbWFuYWdlbWVudCBmcmFtZQogICAgICovCiAgICBidWYgPSB6ZndCdWZBbGxvY2F0ZShkZXYsIDEwMjQpOwogICAgaWYgKGJ1ZiA9PSBOVUxMKQogICAgewogICAgICAgIHptX21zZzBfbW0oWk1fTFZfMCwgIkFsbG9jIG1tIGJ1ZiBGYWlsISIpOwogICAgICAgIHJldHVybiBaTV9TVUNDRVNTOwogICAgfQoKICAgIC8qCiAgICAgKiBSZXNlcnZlIHJvb20gZm9yIHdsYW4gaGVhZGVyCiAgICAgKi8KICAgIG9mZnNldCA9IGhsZW47CgogICAgLyoKICAgICAqIGFkZCBhZGRiYSBmcmFtZSBib2R5CiAgICAgKi8KICAgIG9mZnNldCA9IHpmQWdnU2V0QmFyQm9keShkZXYsIGJ1Ziwgb2Zmc2V0LCB0aWRfdHgsIGFnZ0JhckNvbnRyb2wpOwoKCiAgICB6ZndCdWZTZXRTaXplKGRldiwgYnVmLCBvZmZzZXQpOwoKICAgIC8qCiAgICAgKiBDb3B5IHdsYW4gaGVhZGVyCiAgICAgKi8KICAgIHpmQWdnR2VuQmFySGVhZGVyKGRldiwgdGlkX3R4LT5kc3QsIGhlYWRlciwgb2Zmc2V0LWhsZW4sIGJ1ZiwgdmFwLCBlbmNyeXB0KTsKICAgIGZvciAoaT0wOyBpPChobGVuPj4xKTsgaSsrKQogICAgewogICAgICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBpKjIsIGhlYWRlcltpXSk7CiAgICB9CgogICAgLyogR2V0IGJ1ZmZlciBETUEgYWRkcmVzcyAqLwogICAgLy9pZiAoKGFkZHJUYmxTaXplID0gemZ3QnVmTWFwRG1hKGRldiwgYnVmLCAmYWRkclRibCkpID09IDApCiAgICAvL2lmICgoYWRkclRibFNpemUgPSB6ZndNYXBUeERtYShkZXYsIGJ1ZiwgJmFkZHJUYmwpKSA9PSAwKQogICAgLy97CiAgICAvLyAgICBnb3RvIHpsRXJyb3I7CiAgICAvL30KCiAgICAvL3ptX21zZzJfbW0oWk1fTFZfMiwgIm9mZnNldD0iLCBvZmZzZXQpOwogICAgLy96bV9tc2cyX21tKFpNX0xWXzIsICJobGVuPSIsIGhsZW4pOwogICAgLy96bV9tc2cyX21tKFpNX0xWXzIsICJhZGRyVGJsU2l6ZT0iLCBhZGRyVGJsU2l6ZSk7CiAgICAvL3ptX21zZzJfbW0oWk1fTFZfMiwgImFkZHJUYmwubGVuWzBdPSIsIGFkZHJUYmwubGVuWzBdKTsKICAgIC8vem1fbXNnMl9tbShaTV9MVl8yLCAiYWRkclRibC5waHlzQWRkcmxbMF09IiwgYWRkclRibC5waHlzQWRkcmxbMF0pOwogICAgLy96bV9tc2cyX21tKFpNX0xWXzIsICJidWYtPmRhdGE9IiwgYnVmLT5kYXRhKTsKCiAgICAjaWYgMAogICAgZXJyID0gemZIcFNlbmQoZGV2LCBOVUxMLCAwLCBOVUxMLCAwLCBOVUxMLCAwLCBidWYsIDAsCgkJICAgWk1fSU5URVJOQUxfQUxMT0NfQlVGLCAwLCAweGZmKTsKICAgIGlmIChlcnIgIT0gWk1fU1VDQ0VTUykKICAgIHsKICAgICAgICBnb3RvIHpsRXJyb3I7CiAgICB9CiAgICAjZWxzZQogICAgemZQdXRWbW1xKGRldiwgYnVmKTsKICAgIHpmUHVzaFZ0eHEoZGV2KTsKICAgICNlbmRpZgoKICAgIHJldHVybiBaTV9TVUNDRVNTOwoKfQoKdTE2X3QgICB6ZkFnZ1NldEJhckJvZHkoemRldl90KiBkZXYsIHpidWZfdCogYnVmLCB1MTZfdCBvZmZzZXQsIFRJRF9UWCB0aWRfdHgsIHN0cnVjdCBhZ2dCYXJDb250cm9sICphZ2dCYXJDb250cm9sKQp7CiAgICB1MTZfdCBiYXJfY29udHJvbCwgc3RhcnRfc2VxOwoKICAgIC8vem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIC8vem13X2RlY2xhcmVfZm9yX2NyaXRpY2FsX3NlY3Rpb24oKTsKICAgIC8qCiAgICAgKiBCQVIgQ29udHJvbCBmcmFtZSBib2R5CiAgICAgKi8KCiAgICAvKgogICAgICogQkFSIENvbnRyb2wgRmllbGQKICAgICAqIKJ6oneid6J3oneid6J3oneid6J3onOid6J3oneid6J3oneid6J3oneid6J3onOid6J3oneid6J3oneid6J3oneid6J3oneic6J3oneid6J3oneid6J3oneid6J3onOid6J3oneid6J3oneid6J3oneid6J7CiAgICAgKiCieCAgICBCMCAgIKJ4ICAgIEIxICAgICCieCAgICAgQjIgICAgIKJ4IEIzICAgQjExIKJ4IEIxMiAgQjE1IKJ4CiAgICAgKiCidaJ3oneid6J3oneid6J3oneid6Jxoneid6J3oneid6J3oneid6J3oneid6Jxoneid6J3oneid6J3oneid6J3oneid6J3onGid6J3oneid6J3oneid6J3oneid6Jxoneid6J3oneid6J3oneid6J3oneidAogICAgICogonggQkFSIEFjayCieCBNdWx0aS1USUQgonggQ29tcHJlc3NlZCCieCBSZXNlcnZlZCCieCBUSURfSU5GTyCieAogICAgICogonggIFBvbGljeSCieCAgICAgICAgICAgonggICBCaXRtYXAgICCieCAgICAgICAgICCieCAgICAgICAgICCieAogICAgICogonyid6J3oneid6J3oneid6J3oneicqJ3oneid6J3oneid6J3oneid6J3oneicqJ3oneid6J3oneid6J3oneid6J3oneid6Jyoneid6J3oneid6J3oneid6J3oneicqJ3oneid6J3oneid6J3oneid6J3on0KICAgICAqLwogICAgYmFyX2NvbnRyb2wgPSBhZ2dCYXJDb250cm9sLT50aWRfaW5mbyA8PCAxMiB8IGFnZ0JhckNvbnRyb2wtPmNvbXByZXNzZWRfYml0bWFwIDw8IDIKICAgICAgICAgICAgfCBhZ2dCYXJDb250cm9sLT5tdWx0aV90aWQgPDwgMSB8IGFnZ0JhckNvbnRyb2wtPmJhcl9hY2tfcG9saWN5OwoKICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBvZmZzZXQsIGJhcl9jb250cm9sKTsKICAgIG9mZnNldCs9MjsKICAgIGlmICgwID09IGFnZ0JhckNvbnRyb2wtPm11bHRpX3RpZCkgewogICAgICAgIC8qCiAgICAgICAgICogQkEgc3RhcnRpbmcgc2VxdWVuY2UgbnVtYmVyCiAgICAgICAgICogonqid6J3oneid6J3oneid6J3oneid6J3oneid6Jzoneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3onsKICAgICAgICAgKiCieCBCMCAgICAgICBCMyCieCBCNCAgICAgICAgICAgICAgQjE1IKJ4CiAgICAgICAgICogonWid6J3oneid6J3oneid6J3oneid6J3oneid6Jxoneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3onQKICAgICAgICAgKiCieCBGcmFnIG51bSgwKSCieCBCQSBzdGFydGluZyBzZXEgbnVtIKJ4CiAgICAgICAgICogonyid6J3oneid6J3oneid6J3oneid6J3oneid6Jyoneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3oneid6J3on0KICAgICAgICAgKi8KICAgICAgICBzdGFydF9zZXEgPSAodGlkX3R4LT5iYXJfc3NuIDw8IDQpICYgMHhGRkYwOwogICAgICAgIHptd190eF9idWZfd3JpdGVoKGRldiwgYnVmLCBvZmZzZXQsIHN0YXJ0X3NlcSk7CiAgICAgICAgb2Zmc2V0Kz0yOwogICAgfQogICAgaWYgKDEgPT0gYWdnQmFyQ29udHJvbC0+bXVsdGlfdGlkICYmIDEgPT0gYWdnQmFyQ29udHJvbC0+Y29tcHJlc3NlZF9iaXRtYXApIHsKICAgICAgICAvKiBtdWx0aS10aWQgQmxvY2tBY2tSZXEgdmFyaWFudCwgbm90IGltcGxlbWVudGVkKi8KICAgIH0KCiAgICByZXR1cm4gb2Zmc2V0Owp9Cgp1MTZfdCB6ZkFnZ0dlbkJhckhlYWRlcih6ZGV2X3QqIGRldiwgdTE2X3QqIGRzdCwKICAgICAgICB1MTZfdCogaGVhZGVyLCB1MTZfdCBsZW4sIHpidWZfdCogYnVmLCB1MTZfdCB2YXAsIHU4X3QgZW5jcnlwdCkKewogICAgdThfdCAgaGxlbiA9IDE2Kzg7ICAgICAgICAvLyBNQUMgY3RybCArIFBIWSBjdHJsICsgODAyLjExIE1NIGhlYWRlcgogICAgLy91OF90IGZyYW1lVHlwZSA9IFpNX1dMQU5fRlJBTUVfVFlQRV9BQ1RJT047CgogICAgem13X2dldF93bGFuX2RldihkZXYpOwoKICAgIHptd19kZWNsYXJlX2Zvcl9jcml0aWNhbF9zZWN0aW9uKCk7CgogICAgLyoKICAgICAqIEdlbmVyYXRlIGNvbnRyb2wgc2V0dGluZwogICAgICovCiAgICAvL2JvZHlMZW4gPSB6ZndCdWZHZXRTaXplKGRldiwgYnVmKTsKICAgIGhlYWRlclswXSA9IDE2K2xlbis0OyAgIC8vTGVuZ3RoCiAgICBoZWFkZXJbMV0gPSAweDg7ICAgICAgICAvL01BQyBjb250cm9sLCBiYWNrb2ZmICsgKGFjaykKCiNpZiAxCiAgICAvKiBDQ0sgMU0gKi8KICAgIGhlYWRlclsyXSA9IDB4MGYwMDsgICAgICAgICAgLy9QSFkgY29udHJvbCBMCiAgICBoZWFkZXJbM10gPSAweDAwMDA7ICAgICAgICAgIC8vUEhZIGNvbnRyb2wgSAojZWxzZQogICAgLyogQ0NLIDZNICovCiAgICBoZWFkZXJbMl0gPSAweDBmMDE7ICAgICAgICAgIC8vUEhZIGNvbnRyb2wgTAogICAgaGVhZGVyWzNdID0gMHgwMDBCOyAgICAgICAgICAvL1BIWSBjb250cm9sIEgKCiNlbmRpZgogICAgLyoKICAgICAqIEdlbmVyYXRlIFdMQU4gaGVhZGVyCiAgICAgKiBGcmFtZSBjb250cm9sIGZyYW1lIHR5cGUgYW5kIHN1YnR5cGUKICAgICAqLwogICAgaGVhZGVyWzQrMF0gPSBaTV9XTEFOX0ZSQU1FX1RZUEVfQkFSOwogICAgLyoKICAgICAqIER1cmF0aW9uCiAgICAgKi8KICAgIGhlYWRlcls0KzFdID0gMDsKCiAgICAvKiBBZGRyZXNzIDEgPSBEQSAqLwogICAgaGVhZGVyWzQrMl0gPSBkc3RbMF07CiAgICBoZWFkZXJbNCszXSA9IGRzdFsxXTsKICAgIGhlYWRlcls0KzRdID0gZHN0WzJdOwoKICAgIC8qIEFkZHJlc3MgMiA9IFNBICovCiAgICBoZWFkZXJbNCs1XSA9IHdkLT5tYWNBZGRyWzBdOwogICAgaGVhZGVyWzQrNl0gPSB3ZC0+bWFjQWRkclsxXTsKICAgIGlmICh3ZC0+d2xhbk1vZGUgPT0gWk1fTU9ERV9BUCkKICAgIHsKI2lmZGVmIFpNX1ZBUE1PREVfTVVMVElMRV9TU0lECiAgICAgICAgaGVhZGVyWzQrN10gPSB3ZC0+bWFjQWRkclsyXTsgLy9NdWx0aXBsZSBTU0lECiNlbHNlCiAgICAgICAgaGVhZGVyWzQrN10gPSB3ZC0+bWFjQWRkclsyXSArICh2YXA8PDgpOyAvL1ZBUAojZW5kaWYKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBoZWFkZXJbNCs3XSA9IHdkLT5tYWNBZGRyWzJdOwogICAgfQoKICAgIC8qIFNlcXVlbmNlIENvbnRyb2wgKi8KICAgIHptd19lbnRlcl9jcml0aWNhbF9zZWN0aW9uKGRldik7CiAgICBoZWFkZXJbNCsxMV0gPSAoKHdkLT5tbXNlcSsrKTw8NCk7CiAgICB6bXdfbGVhdmVfY3JpdGljYWxfc2VjdGlvbihkZXYpOwoKCiAgICByZXR1cm4gaGxlbjsKfQo=