LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgInNpZ19jb250ZXh0LmgiCiNpbmNsdWRlICJtc2Rvcy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZGVidWdnZXIuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc21vZC5oIgojaW5jbHVkZSAic3RhY2tmcmFtZS5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKREVDTEFSRV9ERUJVR19DSEFOTkVMKGludCkKREVDTEFSRV9ERUJVR19DSEFOTkVMKG1vZHVsZSkKREVDTEFSRV9ERUJVR19DSEFOTkVMKHJlbGF5KQoKI2lmZGVmIE1aX1NVUFBPUlRFRAoKI2luY2x1ZGUgPHN5cy9tbWFuLmg+CiNpbmNsdWRlIDxzeXMvdm04Ni5oPgoKI2RlZmluZSBJRl9DTFIoY3R4KSBFRkxfcmVnKGN0eCkgJj0gflZJRl9NQVNLCiNkZWZpbmUgSUZfRU5BQkxFRChjdHgpIChFRkxfcmVnKGN0eCkgJiBWSUZfTUFTSykKI2RlZmluZSBTRVRfUEVORChjdHgpIEVGTF9yZWcoY3R4KSB8PSBWSVBfTUFTSwojZGVmaW5lIENMUl9QRU5EKGN0eCkgRUZMX3JlZyhjdHgpICY9IH5WSVBfTUFTSwojZGVmaW5lIElTX1BFTkQoY3R4KSAoRUZMX3JlZyhjdHgpICYgVklQX01BU0spCgojdW5kZWYgVFJZX1BJQ1JFVFVSTgoKc3RhdGljIHZvaWQgZG9fZXhjZXB0aW9uKCBpbnQgc2lnbmFsLCBDT05URVhUODYgKmNvbnRleHQgKQp7CiAgICBFWENFUFRJT05fUkVDT1JEIHJlYzsKICAgIGV4dGVybiB2b2lkIFdJTkFQSSBSRUdTX0ZVTkMoUnRsUmFpc2VFeGNlcHRpb24pKCBFWENFUFRJT05fUkVDT1JEICpyZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ09OVEVYVCAqY29udGV4dCApOwogICAgaWYgKChzaWduYWwgPT0gU0lHVFJBUCkgfHwgKHNpZ25hbCA9PSBTSUdIVVApKQogICAgewogICAgICAgIHJlYy5FeGNlcHRpb25Db2RlICA9IEVYQ0VQVElPTl9CUkVBS1BPSU5UOwogICAgICAgIHJlYy5FeGNlcHRpb25GbGFncyA9IEVYQ0VQVElPTl9DT05USU5VQUJMRTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZWMuRXhjZXB0aW9uQ29kZSAgPSBFWENFUFRJT05fSUxMRUdBTF9JTlNUUlVDVElPTjsgIC8qIGdlbmVyaWMgZXJyb3IgKi8KICAgICAgICByZWMuRXhjZXB0aW9uRmxhZ3MgPSBFSF9OT05DT05USU5VQUJMRTsKICAgIH0KICAgIHJlYy5FeGNlcHRpb25SZWNvcmQgID0gTlVMTDsKICAgIHJlYy5FeGNlcHRpb25BZGRyZXNzID0gKExQVk9JRClFSVBfcmVnKGNvbnRleHQpOwogICAgcmVjLk51bWJlclBhcmFtZXRlcnMgPSAwOwogICAgUkVHU19GVU5DKFJ0bFJhaXNlRXhjZXB0aW9uKSggJnJlYywgY29udGV4dCApOwp9CgpzdGF0aWMgdm9pZCBET1NWTV9EdW1wKCBMUERPU1RBU0sgbHBEb3NUYXNrLCBpbnQgZm4sIGludCBzaWcsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB2bTg2cGx1c19zdHJ1Y3QqVk04NiApCnsKIHVuc2lnbmVkIGlvZnM7CiBCWVRFKmluc3Q7CiBpbnQgeDsKCiBzd2l0Y2ggKFZNODZfVFlQRShmbikpIHsKICBjYXNlIFZNODZfU0lHTkFMOgogICBwcmludGYoIlRyYXBwZWQgc2lnbmFsICVkXG4iLHNpZyk7IGJyZWFrOwogIGNhc2UgVk04Nl9VTktOT1dOOgogICBwcmludGYoIlRyYXBwZWQgdW5oYW5kbGVkIEdQRlxuIik7IGJyZWFrOwogIGNhc2UgVk04Nl9JTlR4OgogICBwcmludGYoIlRyYXBwZWQgSU5UICUwMnhcbiIsVk04Nl9BUkcoZm4pKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1NUSToKICAgcHJpbnRmKCJUcmFwcGVkIFNUSVxuIik7IGJyZWFrOwogIGNhc2UgVk04Nl9QSUNSRVRVUk46CiAgIHByaW50ZigiVHJhcHBlZCBkdWUgdG8gcGVuZGluZyBQSUMgcmVxdWVzdFxuIik7IGJyZWFrOwogIGNhc2UgVk04Nl9UUkFQOgogICBwcmludGYoIlRyYXBwZWQgZGVidWcgcmVxdWVzdFxuIik7IGJyZWFrOwogIGRlZmF1bHQ6CiAgIHByaW50ZigiVHJhcHBlZCB1bmtub3duIFZNODYgdHlwZSAlZCBhcmcgJWRcbiIsVk04Nl9UWVBFKGZuKSxWTTg2X0FSRyhmbikpOyBicmVhazsKIH0KI2RlZmluZSBSRUdTIFZNODYtPnJlZ3MKIGZwcmludGYoc3RkZXJyLCJBWD0lMDRsWCBDWD0lMDRsWCBEWD0lMDRsWCBCWD0lMDRsWFxuIixSRUdTLmVheCxSRUdTLmVjeCxSRUdTLmVkeCxSRUdTLmVieCk7CiBmcHJpbnRmKHN0ZGVyciwiU0k9JTA0bFggREk9JTA0bFggU1A9JTA0bFggQlA9JTA0bFhcbiIsUkVHUy5lc2ksUkVHUy5lZGksUkVHUy5lc3AsUkVHUy5lYnApOwogZnByaW50ZihzdGRlcnIsIkNTPSUwNFggRFM9JTA0WCBFUz0lMDRYIFNTPSUwNFhcbiIsUkVHUy5jcyxSRUdTLmRzLFJFR1MuZXMsUkVHUy5zcyk7CiBmcHJpbnRmKHN0ZGVyciwiSVA9JTA0bFggRUZMQUdTPSUwOGxYXG4iLFJFR1MuZWlwLFJFR1MuZWZsYWdzKTsKCiBpb2ZzPSgoRFdPUkQpUkVHUy5jczw8NCkrUkVHUy5laXA7CiN1bmRlZiBSRUdTCiBpbnN0PShCWVRFKilscERvc1Rhc2stPmltZytpb2ZzOwogcHJpbnRmKCJPcGNvZGVzOiIpOwogZm9yICh4PTA7IHg8ODsgeCsrKSBwcmludGYoIiAlMDJ4IixpbnN0W3hdKTsKIHByaW50ZigiXG4iKTsKfQoKc3RhdGljIGludCBET1NWTV9JbnQoIGludCB2ZWN0LCBDT05URVhUODYgKmNvbnRleHQsIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBleHRlcm4gVUlOVDE2IERQTUlfd3JhcF9zZWc7CgogaWYgKHZlY3Q9PTB4MzEpIHsKICBpZiAoQ1NfcmVnKGNvbnRleHQpPT1EUE1JX3dyYXBfc2VnKSB7CiAgIC8qIGV4aXQgZnJvbSByZWFsLW1vZGUgd3JhcHBlciAqLwogICByZXR1cm4gLTE7CiAgfQogIC8qIHdlIGNvdWxkIHByb2JhYmx5IG1vdmUgc29tZSBvdGhlciBkb2RneSBzdHVmZiBoZXJlIHRvbyBmcm9tIGRwbWkuYyAqLwogfQogSU5UX1JlYWxNb2RlSW50ZXJydXB0KHZlY3QsY29udGV4dCk7CiByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgRE9TVk1fU2ltdWxhdGVJbnQoIGludCB2ZWN0LCBDT05URVhUODYgKmNvbnRleHQsIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiAgRkFSUFJPQzE2IGhhbmRsZXI9SU5UX0dldFJNSGFuZGxlcih2ZWN0KTsKCiAgaWYgKFNFTEVDVE9ST0YoaGFuZGxlcik9PTB4ZjAwMCkgewogICAgLyogaWYgaW50ZXJuYWwgaW50ZXJydXB0LCBjYWxsIGl0IGRpcmVjdGx5ICovCiAgICBJTlRfUmVhbE1vZGVJbnRlcnJ1cHQodmVjdCxjb250ZXh0KTsKICB9IGVsc2UgewogICAgV09SRCpzdGFjaz0oV09SRCopKFY4NkJBU0UoY29udGV4dCkrKCgoRFdPUkQpU1NfcmVnKGNvbnRleHQpKTw8NCkrU1BfcmVnKGNvbnRleHQpKTsKICAgIFdPUkQgZmxhZz1GTF9yZWcoY29udGV4dCk7CgogICAgaWYgKElGX0VOQUJMRUQoY29udGV4dCkpIGZsYWd8PUlGX01BU0s7CiAgICBlbHNlIGZsYWcmPX5JRl9NQVNLOwoKICAgICooLS1zdGFjayk9ZmxhZzsKICAgICooLS1zdGFjayk9Q1NfcmVnKGNvbnRleHQpOwogICAgKigtLXN0YWNrKT1JUF9yZWcoY29udGV4dCk7CiAgICBTUF9yZWcoY29udGV4dCktPTY7CiAgICBDU19yZWcoY29udGV4dCk9U0VMRUNUT1JPRihoYW5kbGVyKTsKICAgIElQX3JlZyhjb250ZXh0KT1PRkZTRVRPRihoYW5kbGVyKTsKICAgIElGX0NMUihjb250ZXh0KTsKICB9Cn0KCiNkZWZpbmUgU0hPVUxEX1BFTkQoeCkgXAogICh4ICYmICgoIWxwRG9zVGFzay0+Y3VycmVudCkgfHwgKHgtPnByaW9yaXR5IDwgbHBEb3NUYXNrLT5jdXJyZW50LT5wcmlvcml0eSkpKQoKc3RhdGljIHZvaWQgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50KENPTlRFWFQ4NiAqY29udGV4dCwgTFBET1NUQVNLIGxwRG9zVGFzaykKewogIExQRE9TRVZFTlQgZXZlbnQgPSBscERvc1Rhc2stPnBlbmRpbmc7CgogIGlmIChTSE9VTERfUEVORChldmVudCkpIHsKICAgIC8qIHJlbW92ZSBmcm9tICJwZW5kaW5nIiBsaXN0ICovCiAgICBscERvc1Rhc2stPnBlbmRpbmcgPSBldmVudC0+bmV4dDsKICAgIC8qIHByb2Nlc3MgZXZlbnQgKi8KICAgIGlmIChldmVudC0+aXJxPj0wKSB7CiAgICAgIC8qIGl0J3MgYW4gSVJRLCBtb3ZlIGl0IHRvICJjdXJyZW50IiBsaXN0ICovCiAgICAgIGV2ZW50LT5uZXh0ID0gbHBEb3NUYXNrLT5jdXJyZW50OwogICAgICBscERvc1Rhc2stPmN1cnJlbnQgPSBldmVudDsKICAgICAgVFJBQ0VfKGludCkoImRpc3BhdGNoaW5nIElSUSAlZFxuIixldmVudC0+aXJxKTsKICAgICAgLyogbm90ZSB0aGF0IGlmIERPU1ZNX1NpbXVsYXRlSW50IGNhbGxzIGFuIGludGVybmFsIGludGVycnVwdCBkaXJlY3RseSwKICAgICAgICogbHBEb3NUYXNrLT5jdXJyZW50IG1pZ2h0IGJlIGNsZWFyZWQgKGFuZCBldmVudCBmcmVlZCkgaW4gdGhpcyB2ZXJ5IGNhbGwhICovCiAgICAgIERPU1ZNX1NpbXVsYXRlSW50KChldmVudC0+aXJxPDgpPyhldmVudC0+aXJxKzgpOihldmVudC0+aXJxLTgrMHg3MCksY29udGV4dCxscERvc1Rhc2spOwogICAgfSBlbHNlIHsKICAgICAgLyogY2FsbGJhY2sgZXZlbnQgKi8KICAgICAgVFJBQ0VfKGludCkoImRpc3BhdGNoaW5nIGNhbGxiYWNrIGV2ZW50XG4iKTsKICAgICAgKCpldmVudC0+cmVsYXkpKGxwRG9zVGFzayxjb250ZXh0LGV2ZW50LT5kYXRhKTsKICAgICAgZnJlZShldmVudCk7CiAgICB9CiAgfQogIGlmICghU0hPVUxEX1BFTkQobHBEb3NUYXNrLT5wZW5kaW5nKSkgewogICAgVFJBQ0VfKGludCkoImNsZWFyaW5nIFBlbmRpbmcgZmxhZ1xuIik7CiAgICBDTFJfUEVORChjb250ZXh0KTsKICB9Cn0KCnN0YXRpYyB2b2lkIERPU1ZNX1NlbmRRdWV1ZWRFdmVudHMoQ09OVEVYVDg2ICpjb250ZXh0LCBMUERPU1RBU0sgbHBEb3NUYXNrKQp7CiAgLyogd2Ugd2lsbCBzZW5kIGFsbCBxdWV1ZWQgZXZlbnRzIGFzIGxvbmcgYXMgaW50ZXJydXB0cyBhcmUgZW5hYmxlZCwKICAgKiBidXQgSVJRIGV2ZW50cyB3aWxsIGRpc2FibGUgaW50ZXJydXB0cyBhZ2FpbiAqLwogIHdoaWxlIChJU19QRU5EKGNvbnRleHQpICYmIElGX0VOQUJMRUQoY29udGV4dCkpCiAgICBET1NWTV9TZW5kUXVldWVkRXZlbnQoY29udGV4dCxscERvc1Rhc2spOwp9Cgp2b2lkIERPU1ZNX1F1ZXVlRXZlbnQoIGludCBpcnEsIGludCBwcmlvcml0eSwgdm9pZCAoKnJlbGF5KShMUERPU1RBU0ssQ09OVEVYVDg2Kix2b2lkKiksIHZvaWQgKmRhdGEpCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gTVpfQ3VycmVudCgpOwogIExQRE9TRVZFTlQgZXZlbnQsIGN1ciwgcHJldjsKCiAgaWYgKGxwRG9zVGFzaykgewogICAgZXZlbnQgPSBtYWxsb2Moc2l6ZW9mKERPU0VWRU5UKSk7CiAgICBpZiAoIWV2ZW50KSB7CiAgICAgIEVSUl8oaW50KSgib3V0IG9mIG1lbW9yeSBhbGxvY2F0aW5nIGV2ZW50IGVudHJ5XG4iKTsKICAgICAgcmV0dXJuOwogICAgfQogICAgZXZlbnQtPmlycSA9IGlycTsgZXZlbnQtPnByaW9yaXR5ID0gcHJpb3JpdHk7CiAgICBldmVudC0+cmVsYXkgPSByZWxheTsgZXZlbnQtPmRhdGEgPSBkYXRhOwoKICAgIC8qIGluc2VydCBldmVudCBpbnRvIGxpbmtlZCBsaXN0LCBpbiBvcmRlciAqYWZ0ZXIqCiAgICAgKiBhbGwgZWFybGllciBldmVudHMgb2YgaGlnaGVyIG9yIGVxdWFsIHByaW9yaXR5ICovCiAgICBjdXIgPSBscERvc1Rhc2stPnBlbmRpbmc7IHByZXYgPSBOVUxMOwogICAgd2hpbGUgKGN1ciAmJiBjdXItPnByaW9yaXR5PD1wcmlvcml0eSkgewogICAgICBwcmV2ID0gY3VyOwogICAgICBjdXIgPSBjdXItPm5leHQ7CiAgICB9CiAgICBldmVudC0+bmV4dCA9IGN1cjsKICAgIGlmIChwcmV2KSBwcmV2LT5uZXh0ID0gZXZlbnQ7CiAgICBlbHNlIGxwRG9zVGFzay0+cGVuZGluZyA9IGV2ZW50OwogICAgCiAgICAvKiBnZXQgZG9zbW9kJ3MgYXR0ZW50aW9uIHRvIHRoZSBuZXcgZXZlbnQsIGV4Y2VwdCBmb3IgaXJxPT0wIHdoZXJlIHdlIGFscmVhZHkgaGF2ZSBpdCAqLwogICAgaWYgKGlycSAmJiAhbHBEb3NUYXNrLT5zaWdfc2VudCkgewogICAgICBUUkFDRV8oaW50KSgibmV3IGV2ZW50IHF1ZXVlZCwgc2lnbmFsbGluZyBkb3Ntb2RcbiIpOwogICAgICBraWxsKGxwRG9zVGFzay0+dGFzayxTSUdVU1IyKTsKICAgICAgbHBEb3NUYXNrLT5zaWdfc2VudCsrOwogICAgfSBlbHNlIHsKICAgICAgVFJBQ0VfKGludCkoIm5ldyBldmVudCBxdWV1ZWRcbiIpOwogICAgfQogIH0KfQoKI2RlZmluZSBDViBDUChlYXgsRUFYKTsgQ1AoZWN4LEVDWCk7IENQKGVkeCxFRFgpOyBDUChlYngsRUJYKTsgXAogICAgICAgICAgIENQKGVzaSxFU0kpOyBDUChlZGksRURJKTsgQ1AoZXNwLEVTUCk7IENQKGVicCxFQlApOyBcCiAgICAgICAgICAgQ1AoY3MsQ1MpOyBDUChkcyxEUyk7IENQKGVzLEVTKTsgXAogICAgICAgICAgIENQKHNzLFNTKTsgQ1AoZnMsRlMpOyBDUChncyxHUyk7IFwKICAgICAgICAgICBDUChlaXAsRUlQKTsgQ1AoZWZsYWdzLEVGTCkKCnN0YXRpYyBpbnQgRE9TVk1fUHJvY2VzcyggTFBET1NUQVNLIGxwRG9zVGFzaywgaW50IGZuLCBpbnQgc2lnLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB2bTg2cGx1c19zdHJ1Y3QqVk04NiApCnsKIFNJR0NPTlRFWFQgc2lnY29udGV4dDsKIENPTlRFWFQ4NiBjb250ZXh0OwogaW50IHJldD0wOwoKIGlmIChWTTg2X1RZUEUoZm4pPT1WTTg2X1VOS05PV04pIHsKICAvKiBJTlNUUl9FbXVsYXRlSW5zdHJ1Y3Rpb24gbmVlZHMgYSBTSUdDT05URVhULCBub3QgYSBDT05URVhULi4uICovCiNkZWZpbmUgQ1AoeCx5KSB5IyNfc2lnKCZzaWdjb250ZXh0KSA9IFZNODYtPnJlZ3MueAogIENWOwojdW5kZWYgQ1AKICByZXQ9SU5TVFJfRW11bGF0ZUluc3RydWN0aW9uKCZzaWdjb250ZXh0KTsKI2RlZmluZSBDUCh4LHkpIFZNODYtPnJlZ3MueCA9IHkjI19zaWcoJnNpZ2NvbnRleHQpCiAgQ1Y7CiN1bmRlZiBDUAogIGlmIChyZXQpIHJldHVybiAwOwogIHJldD0wOwogfQojZGVmaW5lIENQKHgseSkgeSMjX3JlZygmY29udGV4dCkgPSBWTTg2LT5yZWdzLngKIENWOwojdW5kZWYgQ1AKICh2b2lkKilWODZCQVNFKCZjb250ZXh0KT1scERvc1Rhc2stPmltZzsKI2lmZGVmIFRSWV9QSUNSRVRVUk4KIGlmIChWTTg2LT52bTg2cGx1cy5mb3JjZV9yZXR1cm5fZm9yX3BpYykgewogICBTRVRfUEVORCgmY29udGV4dCk7CiB9CiNlbHNlCiAvKiBsaW51eCBkb2Vzbid0IHByZXNlcnZlIHBlbmRpbmcgZmxhZyBvbiByZXR1cm4gKi8KIGlmIChTSE9VTERfUEVORChscERvc1Rhc2stPnBlbmRpbmcpKSB7CiAgIFNFVF9QRU5EKCZjb250ZXh0KTsKIH0KI2VuZGlmCgogc3dpdGNoIChWTTg2X1RZUEUoZm4pKSB7CiAgY2FzZSBWTTg2X1NJR05BTDoKICAgVFJBQ0VfKGludCkoIkRPUyBtb2R1bGUgY2F1Z2h0IHNpZ25hbCAlZFxuIixzaWcpOwogICBpZiAoKHNpZz09U0lHQUxSTSkgfHwgKHNpZz09U0lHVVNSMikpIHsKICAgICBpZiAoc2lnPT1TSUdBTFJNKSB7CiAgICAgICBET1NWTV9RdWV1ZUV2ZW50KDAsRE9TX1BSSU9SSVRZX1JFQUxUSU1FLE5VTEwsTlVMTCk7CiAgICAgfQogICAgIGlmIChscERvc1Rhc2stPnBlbmRpbmcpIHsKICAgICAgIFRSQUNFXyhpbnQpKCJzZXR0aW5nIFBlbmRpbmcgZmxhZywgaW50ZXJydXB0cyBhcmUgY3VycmVudGx5ICVzXG4iLAogICAgICAgICAgICAgICAgIElGX0VOQUJMRUQoJmNvbnRleHQpID8gImVuYWJsZWQiIDogImRpc2FibGVkIik7CiAgICAgICBTRVRfUEVORCgmY29udGV4dCk7CiAgICAgICBET1NWTV9TZW5kUXVldWVkRXZlbnRzKCZjb250ZXh0LGxwRG9zVGFzayk7CiAgICAgfSBlbHNlIHsKICAgICAgIFRSQUNFXyhpbnQpKCJubyBldmVudHMgYXJlIHBlbmRpbmcsIGNsZWFyaW5nIFBlbmRpbmcgZmxhZ1xuIik7CiAgICAgICBDTFJfUEVORCgmY29udGV4dCk7CiAgICAgfQogICAgIGlmIChzaWc9PVNJR1VTUjIpIGxwRG9zVGFzay0+c2lnX3NlbnQtLTsKICAgfQogICBlbHNlIGlmICgoc2lnPT1TSUdIVVApIHx8IChzaWc9PVNJR0lMTCkgfHwgKHNpZz09U0lHU0VHVikpIHsKICAgICAgIGRvX2V4Y2VwdGlvbiggc2lnLCAmY29udGV4dCApOwogICB9IGVsc2UgewogICAgRE9TVk1fRHVtcChscERvc1Rhc2ssZm4sc2lnLFZNODYpOwogICAgcmV0PS0xOwogICB9CiAgIGJyZWFrOwogIGNhc2UgVk04Nl9VTktOT1dOOiAvKiB1bmhhbmRsZWQgR1BGICovCiAgIERPU1ZNX0R1bXAobHBEb3NUYXNrLGZuLHNpZyxWTTg2KTsKICAgZG9fZXhjZXB0aW9uKCBTSUdTRUdWLCAmY29udGV4dCApOwogICBicmVhazsKICBjYXNlIFZNODZfSU5UeDoKICAgaWYgKFRSQUNFX09OKHJlbGF5KSkKICAgIERQUklOVEYoIkNhbGwgRE9TIGludCAweCUwMnggKEVBWD0lMDhseCkgcmV0PSUwNGx4OiUwNGx4XG4iLFZNODZfQVJHKGZuKSxjb250ZXh0LkVheCxjb250ZXh0LlNlZ0NzLGNvbnRleHQuRWlwKTsKICAgcmV0PURPU1ZNX0ludChWTTg2X0FSRyhmbiksJmNvbnRleHQsbHBEb3NUYXNrKTsKICAgaWYgKFRSQUNFX09OKHJlbGF5KSkKICAgIERQUklOVEYoIlJldCAgRE9TIGludCAweCUwMnggKEVBWD0lMDhseCkgcmV0PSUwNGx4OiUwNGx4XG4iLFZNODZfQVJHKGZuKSxjb250ZXh0LkVheCxjb250ZXh0LlNlZ0NzLGNvbnRleHQuRWlwKTsKICAgYnJlYWs7CiAgY2FzZSBWTTg2X1NUSToKICBjYXNlIFZNODZfUElDUkVUVVJOOgogICAgVFJBQ0VfKGludCkoIkRPUyB0YXNrIGVuYWJsZWQgaW50ZXJydXB0cyB3aXRoIGV2ZW50cyBwZW5kaW5nLCBzZW5kaW5nIGV2ZW50c1xuIik7CiAgICBET1NWTV9TZW5kUXVldWVkRXZlbnRzKCZjb250ZXh0LGxwRG9zVGFzayk7CiAgICBicmVhazsKICBjYXNlIFZNODZfVFJBUDoKICAgZG9fZXhjZXB0aW9uKCBTSUdUUkFQLCAmY29udGV4dCApOwogICBicmVhazsKICBkZWZhdWx0OgogICBET1NWTV9EdW1wKGxwRG9zVGFzayxmbixzaWcsVk04Nik7CiAgIHJldD0tMTsKIH0KCiNkZWZpbmUgQ1AoeCx5KSBWTTg2LT5yZWdzLnggPSB5IyNfcmVnKCZjb250ZXh0KQogQ1Y7CiN1bmRlZiBDUAojaWZkZWYgVFJZX1BJQ1JFVFVSTgogVk04Ni0+dm04NnBsdXMuZm9yY2VfcmV0dXJuX2Zvcl9waWMgPSBJU19QRU5EKCZjb250ZXh0KSA/IDEgOiAwOwogQ0xSX1BFTkQoJmNvbnRleHQpOwojZW5kaWYKIHJldHVybiByZXQ7Cn0KCnZvaWQgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoTFBET1NUQVNLIGxwRG9zVGFzayxNU0cgKm1zZykKewogIEJZVEUgc2NhbiA9IDA7CgogIGZwcmludGYoc3RkZXJyLCJnb3QgbWVzc2FnZSAlMDR4LCB3cGFyYW09JTA4eCwgbHBhcmFtPSUwOGx4XG4iLG1zZy0+bWVzc2FnZSxtc2ctPndQYXJhbSxtc2ctPmxQYXJhbSk7CiAgaWYgKChtc2ctPm1lc3NhZ2U+PVdNX01PVVNFRklSU1QpJiYKICAgICAgKG1zZy0+bWVzc2FnZTw9V01fTU9VU0VMQVNUKSkgewogICAgSU5UX0ludDMzTWVzc2FnZShtc2ctPm1lc3NhZ2UsbXNnLT53UGFyYW0sbXNnLT5sUGFyYW0pOwogIH0gZWxzZSB7CiAgICBzd2l0Y2ggKG1zZy0+bWVzc2FnZSkgewogICAgY2FzZSBXTV9LRVlVUDoKICAgICAgc2NhbiA9IDB4ODA7CiAgICBjYXNlIFdNX0tFWURPV046CiAgICAgIHNjYW4gfD0gKG1zZy0+bFBhcmFtID4+IDE2KSAmIDB4N2Y7CgogICAgICAvKiBjaGVjayB3aGV0aGVyIGV4dGVuZGVkIGJpdCBpcyBzZXQsCiAgICAgICAqIGFuZCBpZiBzbywgcXVldWUgdGhlIGV4dGVuc2lvbiBwcmVmaXggKi8KICAgICAgaWYgKG1zZy0+bFBhcmFtICYgMHgxMDAwMDAwKSB7CgkvKiBGSVhNRTogc29tZSBrZXlzIChmdW5jdGlvbiBrZXlzKSBoYXZlCgkgKiBleHRlbmRlZCBiaXQgc2V0IGV2ZW4gd2hlbiB0aGV5IHNob3VsZG4ndCwKCSAqIHNob3VsZCBjaGVjayBmb3IgdGhlbSAqLwoJSU5UX0ludDA5U2VuZFNjYW4oMHhFMCk7CiAgICAgIH0KICAgICAgSU5UX0ludDA5U2VuZFNjYW4oc2Nhbik7CiAgICAgIGJyZWFrOwogICAgfQogIH0KfQoKdm9pZCBET1NWTV9XYWl0KCBpbnQgcmVhZF9waXBlLCBIQU5ETEUgaE9iamVjdCApCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gTVpfQ3VycmVudCgpOwogIE1TRyBtc2c7CiAgRFdPUkQgd2FpdHJldDsKICBCT09MIGdvdF9tc2cgPSBGQUxTRTsKCiAgZG8gewogICAgLyogY2hlY2sgZm9yIG1lc3NhZ2VzICh3YXN0ZSB0aW1lIGJlZm9yZSB0aGUgcmVzcG9uc2UgY2hlY2sgYmVsb3cpICovCiAgICB3aGlsZSAoUGVla01lc3NhZ2VBKCZtc2csMCwwLDAsUE1fUkVNT1ZFfFBNX05PWUlFTEQpKSB7CiAgICAgIC8qIGdvdCBhIG1lc3NhZ2UgKi8KICAgICAgRE9TVk1fUHJvY2Vzc01lc3NhZ2UobHBEb3NUYXNrLCZtc2cpOwogICAgICAvKiB3ZSBkb24ndCBuZWVkIGEgVHJhbnNsYXRlTWVzc2FnZSBoZXJlICovCiAgICAgIERpc3BhdGNoTWVzc2FnZUEoJm1zZyk7CiAgICAgIGdvdF9tc2cgPSBUUlVFOwogICAgfQogICAgaWYgKHJlYWRfcGlwZSA9PSAtMSkgewogICAgICBpZiAoZ290X21zZykgYnJlYWs7CiAgICB9IGVsc2UgewogICAgICBmZF9zZXQgcmVhZGZkczsKICAgICAgc3RydWN0IHRpbWV2YWwgdGltZW91dD17MCwwfTsKICAgICAgLyogcXVpY2sgY2hlY2sgZm9yIHJlc3BvbnNlIGZyb20gZG9zbW9kCiAgICAgICAqIChmYXN0ZXIgdGhhbiBkb2luZyB0aGUgZnVsbCBibG9ja2luZyB3YWl0LCBpZiBkYXRhIGFscmVhZHkgYXZhaWxhYmxlKSAqLwogICAgICBGRF9aRVJPKCZyZWFkZmRzKTsgRkRfU0VUKHJlYWRfcGlwZSwmcmVhZGZkcyk7CiAgICAgIGlmIChzZWxlY3QocmVhZF9waXBlKzEsJnJlYWRmZHMsTlVMTCxOVUxMLCZ0aW1lb3V0KT4wKQoJYnJlYWs7CiAgICB9CiAgICAvKiBjaGVjayBmb3IgZGF0YSBmcm9tIHdpbjMyIGNvbnNvbGUgZGV2aWNlICovCgogICAgLyogbm90aGluZyB5ZXQsIGJsb2NrIHdoaWxlIHdhaXRpbmcgZm9yIHNvbWV0aGluZyB0byBkbyAqLwogICAgd2FpdHJldD1Nc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzKDEsJmhPYmplY3QsRkFMU0UsSU5GSU5JVEUsUVNfQUxMSU5QVVQpOwogICAgaWYgKHdhaXRyZXQ9PShEV09SRCktMSkgewogICAgICBFUlJfKG1vZHVsZSkoImRvc3ZtIHdhaXQgZXJyb3I9JWxkXG4iLEdldExhc3RFcnJvcigpKTsKICAgIH0KICAgIGlmIChyZWFkX3BpcGUgIT0gLTEpIHsKICAgICAgaWYgKHdhaXRyZXQ9PVdBSVRfT0JKRUNUXzApIGJyZWFrOwogICAgfQogIH0gd2hpbGUgKFRSVUUpOwp9CgppbnQgRE9TVk1fRW50ZXIoIENPTlRFWFQ4NiAqY29udGV4dCApCnsKIExQRE9TVEFTSyBscERvc1Rhc2sgPSBNWl9DdXJyZW50KCk7CiBzdHJ1Y3Qgdm04NnBsdXNfc3RydWN0IFZNODY7CiBpbnQgc3RhdCxsZW4sc2lnOwoKIGlmICghbHBEb3NUYXNrKSB7CiAgLyogTVpfQ3JlYXRlUHJvY2VzcyBvciBNWl9BbGxvY0RQTUlUYXNrIHNob3VsZCBoYXZlIGJlZW4gY2FsbGVkIGZpcnN0ICovCiAgRVJSXyhtb2R1bGUpKCJkb3Ntb2QgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkISIpOwogIHJldHVybiAtMTsKIH0KCiBpZiAoY29udGV4dCkgewojZGVmaW5lIENQKHgseSkgVk04Ni5yZWdzLnggPSB5IyNfcmVnKGNvbnRleHQpCiAgQ1Y7CiN1bmRlZiBDUAogIGlmIChWTTg2LnJlZ3MuZWZsYWdzICYgSUZfTUFTSykKICAgIFZNODYucmVncy5lZmxhZ3MgfD0gVklGX01BU0s7CiB9IGVsc2UgewovKiBpbml0aWFsIHNldHVwICovCiAgLyogYWxsb2NhdGUgc3RhbmRhcmQgRE9TIGhhbmRsZXMgKi8KICBGSUxFX0luaXRQcm9jZXNzRG9zSGFuZGxlcygpOyAKICAvKiByZWdpc3RlcnMgKi8KICBtZW1zZXQoJlZNODYsMCxzaXplb2YoVk04NikpOwogIFZNODYucmVncy5jcz1scERvc1Rhc2stPmluaXRfY3M7CiAgVk04Ni5yZWdzLmVpcD1scERvc1Rhc2stPmluaXRfaXA7CiAgVk04Ni5yZWdzLnNzPWxwRG9zVGFzay0+aW5pdF9zczsKICBWTTg2LnJlZ3MuZXNwPWxwRG9zVGFzay0+aW5pdF9zcDsKICBWTTg2LnJlZ3MuZHM9bHBEb3NUYXNrLT5wc3Bfc2VnOwogIFZNODYucmVncy5lcz1scERvc1Rhc2stPnBzcF9zZWc7CiAgVk04Ni5yZWdzLmVmbGFncz1WSUZfTUFTSzsKICAvKiBobW0sIHdoYXQgZWxzZSBkbyB3ZSBuZWVkPyAqLwogfQoKIC8qIG1haW4gZXhjaGFuZ2UgbG9vcCAqLwogZG8gewogIHN0YXQgPSBWTTg2X0VOVEVSOwogIGVycm5vID0gMDsKICAvKiB0cmFuc21pdCBWTTg2IHN0cnVjdHVyZSB0byBkb3Ntb2QgdGFzayAqLwogIGlmICh3cml0ZShscERvc1Rhc2stPndyaXRlX3BpcGUsJnN0YXQsc2l6ZW9mKHN0YXQpKSE9c2l6ZW9mKHN0YXQpKSB7CiAgIEVSUl8obW9kdWxlKSgiZG9zbW9kIHN5bmMgbG9zdCwgZXJybm89JWQsIGZkPSVkLCBwaWQ9JWRcbiIsZXJybm8sbHBEb3NUYXNrLT53cml0ZV9waXBlLGdldHBpZCgpKTsKICAgcmV0dXJuIC0xOwogIH0KICBpZiAod3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZWTTg2LHNpemVvZihWTTg2KSkhPXNpemVvZihWTTg2KSkgewogICBFUlJfKG1vZHVsZSkoImRvc21vZCBzeW5jIGxvc3QsIGVycm5vPSVkXG4iLGVycm5vKTsKICAgcmV0dXJuIC0xOwogIH0KICAvKiB3YWl0IGZvciByZXNwb25zZSwgZG9pbmcgb3RoZXIgdGhpbmdzIGluIHRoZSBtZWFudGltZSAqLwogIERPU1ZNX1dhaXQobHBEb3NUYXNrLT5yZWFkX3BpcGUsIGxwRG9zVGFzay0+aFJlYWRQaXBlKTsKICAvKiByZWFkIHJlc3BvbnNlICovCiAgd2hpbGUgKDEpIHsKICAgIGlmICgobGVuPXJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJnN0YXQsc2l6ZW9mKHN0YXQpKSk9PXNpemVvZihzdGF0KSkgYnJlYWs7CiAgICBpZiAoKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpJiYobGVuPD0wKSkgewogICAgIFdBUk5fKG1vZHVsZSkoInJlcmVhZGluZyBkb3Ntb2QgcmV0dXJuIGNvZGUgZHVlIHRvIGVycm5vPSVkLCByZXN1bHQ9JWRcbiIsZXJybm8sbGVuKTsKICAgICBjb250aW51ZTsKICAgIH0KICAgIEVSUl8obW9kdWxlKSgiZG9zbW9kIHN5bmMgbG9zdCByZWFkaW5nIHJldHVybiBjb2RlLCBlcnJubz0lZCwgcmVzdWx0PSVkXG4iLGVycm5vLGxlbik7CiAgICByZXR1cm4gLTE7CiAgfQogIFRSQUNFXyhtb2R1bGUpKCJkb3Ntb2QgcmV0dXJuIGNvZGU9JWRcbiIsc3RhdCk7CiAgd2hpbGUgKDEpIHsKICAgIGlmICgobGVuPXJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJlZNODYsc2l6ZW9mKFZNODYpKSk9PXNpemVvZihWTTg2KSkgYnJlYWs7CiAgICBpZiAoKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpJiYobGVuPD0wKSkgewogICAgIFdBUk5fKG1vZHVsZSkoInJlcmVhZGluZyBkb3Ntb2QgVk04NiBzdHJ1Y3R1cmUgZHVlIHRvIGVycm5vPSVkLCByZXN1bHQ9JWRcbiIsZXJybm8sbGVuKTsKICAgICBjb250aW51ZTsKICAgIH0KICAgIEVSUl8obW9kdWxlKSgiZG9zbW9kIHN5bmMgbG9zdCByZWFkaW5nIFZNODYgc3RydWN0dXJlLCBlcnJubz0lZCwgcmVzdWx0PSVkXG4iLGVycm5vLGxlbik7CiAgICByZXR1cm4gLTE7CiAgfQogIGlmICgoc3RhdCYweGZmKT09RE9TTU9EX1NJR05BTCkgewogICAgd2hpbGUgKDEpIHsKICAgICAgaWYgKChsZW49cmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmc2lnLHNpemVvZihzaWcpKSk9PXNpemVvZihzaWcpKSBicmVhazsKICAgICAgaWYgKCgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSYmKGxlbjw9MCkpIHsKCVdBUk5fKG1vZHVsZSkoInJlcmVhZGluZyBkb3Ntb2Qgc2lnbmFsIGR1ZSB0byBlcnJubz0lZCwgcmVzdWx0PSVkXG4iLGVycm5vLGxlbik7Cgljb250aW51ZTsKICAgICAgfQogICAgICBFUlJfKG1vZHVsZSkoImRvc21vZCBzeW5jIGxvc3QgcmVhZGluZyBzaWduYWwsIGVycm5vPSVkLCByZXN1bHQ9JWRcbiIsZXJybm8sbGVuKTsKICAgICAgcmV0dXJuIC0xOwogICAgfSB3aGlsZSAoMCk7CiAgfSBlbHNlIHNpZz0wOwogIC8qIGdvdCByZXNwb25zZSAqLwogfSB3aGlsZSAoRE9TVk1fUHJvY2VzcyhscERvc1Rhc2ssc3RhdCxzaWcsJlZNODYpPj0wKTsKCiBpZiAoY29udGV4dCkgewojZGVmaW5lIENQKHgseSkgeSMjX3JlZyhjb250ZXh0KSA9IFZNODYucmVncy54CiAgQ1Y7CiN1bmRlZiBDUAogfQogcmV0dXJuIDA7Cn0KCnZvaWQgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gTVpfQ3VycmVudCgpOwogIExQRE9TRVZFTlQgZXZlbnQ7CgogIGlmIChscERvc1Rhc2spIHsKICAgIGlmICgocG9ydD09MHgyMCkgJiYgKHZhbD09MHgyMCkpIHsKICAgICAgaWYgKGxwRG9zVGFzay0+Y3VycmVudCkgewoJLyogRU9JIChFbmQgT2YgSW50ZXJydXB0KSAqLwoJVFJBQ0VfKGludCkoInJlY2VpdmVkIEVPSSBmb3IgY3VycmVudCBJUlEsIGNsZWFyaW5nXG4iKTsKCWV2ZW50ID0gbHBEb3NUYXNrLT5jdXJyZW50OwoJbHBEb3NUYXNrLT5jdXJyZW50ID0gZXZlbnQtPm5leHQ7CglpZiAoZXZlbnQtPnJlbGF5KQoJKCpldmVudC0+cmVsYXkpKGxwRG9zVGFzayxOVUxMLGV2ZW50LT5kYXRhKTsKCWZyZWUoZXZlbnQpOwoKCWlmIChscERvc1Rhc2stPnBlbmRpbmcgJiYKCSAgICAhbHBEb3NUYXNrLT5zaWdfc2VudCkgewoJICAvKiBhbm90aGVyIGV2ZW50IGlzIHBlbmRpbmcsIHdoaWNoIHdlIHNob3VsZCBwcm9iYWJseQoJICAgKiBiZSBhYmxlIHRvIHByb2Nlc3Mgbm93LCBzbyB0ZWxsIGRvc21vZCBhYm91dCBpdCAqLwoJICBUUkFDRV8oaW50KSgiYW5vdGhlciBldmVudCBwZW5kaW5nLCBzaWduYWxsaW5nIGRvc21vZFxuIik7CgkgIGtpbGwobHBEb3NUYXNrLT50YXNrLFNJR1VTUjIpOwoJICBscERvc1Rhc2stPnNpZ19zZW50Kys7Cgl9CiAgICAgIH0gZWxzZSB7CglXQVJOXyhpbnQpKCJFT0kgd2l0aG91dCBhY3RpdmUgSVJRXG4iKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgRklYTUVfKGludCkoInVucmVjb2duaXplZCBQSUMgY29tbWFuZCAlMDJ4XG4iLHZhbCk7CiAgICB9CiAgfQp9Cgp2b2lkIERPU1ZNX1NldFRpbWVyKCB1bnNpZ25lZCB0aWNrcyApCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gTVpfQ3VycmVudCgpOwogIGludCBzdGF0PURPU01PRF9TRVRfVElNRVI7CiAgc3RydWN0IHRpbWV2YWwgdGltOwoKICBpZiAobHBEb3NUYXNrKSB7CiAgICAvKiB0aGUgUEMgY2xvY2tzIHRpY2tzIGF0IDExOTMxODAgSHogKi8KICAgIHRpbS50dl9zZWM9MDsKICAgIHRpbS50dl91c2VjPSgodW5zaWduZWQgbG9uZyBsb25nKXRpY2tzKjEwMDAwMDApLzExOTMxODA7CiAgICAvKiBzYW5pdHkgY2hlY2sgKi8KICAgIGlmICghdGltLnR2X3VzZWMpIHRpbS50dl91c2VjPTE7CgogICAgaWYgKHdyaXRlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSwmc3RhdCxzaXplb2Yoc3RhdCkpIT1zaXplb2Yoc3RhdCkpIHsKICAgICAgRVJSXyhtb2R1bGUpKCJkb3Ntb2Qgc3luYyBsb3N0LCBlcnJubz0lZFxuIixlcnJubyk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGlmICh3cml0ZShscERvc1Rhc2stPndyaXRlX3BpcGUsJnRpbSxzaXplb2YodGltKSkhPXNpemVvZih0aW0pKSB7CiAgICAgIEVSUl8obW9kdWxlKSgiZG9zbW9kIHN5bmMgbG9zdCwgZXJybm89JWRcbiIsZXJybm8pOwogICAgICByZXR1cm47CiAgICB9CiAgICAvKiB0aGVyZSdzIG5vIHJldHVybiAqLwogIH0KfQoKdW5zaWduZWQgRE9TVk1fR2V0VGltZXIoIHZvaWQgKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBpbnQgc3RhdD1ET1NNT0RfR0VUX1RJTUVSOwogIHN0cnVjdCB0aW1ldmFsIHRpbTsKCiAgaWYgKGxwRG9zVGFzaykgewogICAgaWYgKHdyaXRlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSwmc3RhdCxzaXplb2Yoc3RhdCkpIT1zaXplb2Yoc3RhdCkpIHsKICAgICAgRVJSXyhtb2R1bGUpKCJkb3Ntb2Qgc3luYyBsb3N0LCBlcnJubz0lZFxuIixlcnJubyk7CiAgICAgIHJldHVybiAwOwogICAgfQogICAgLyogcmVhZCByZXNwb25zZSAqLwogICAgd2hpbGUgKDEpIHsKICAgICAgaWYgKHJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJnRpbSxzaXplb2YodGltKSk9PXNpemVvZih0aW0pKSBicmVhazsKICAgICAgaWYgKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpIGNvbnRpbnVlOwogICAgICBFUlJfKG1vZHVsZSkoImRvc21vZCBzeW5jIGxvc3QsIGVycm5vPSVkXG4iLGVycm5vKTsKICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gKCh1bnNpZ25lZCBsb25nIGxvbmcpdGltLnR2X3VzZWMqMTE5MzE4MCkvMTAwMDAwMDsKICB9CiAgcmV0dXJuIDA7Cn0KCnZvaWQgRE9TVk1fU2V0U3lzdGVtRGF0YSggaW50IGlkLCB2b2lkICpkYXRhICkKewogIExQRE9TVEFTSyBscERvc1Rhc2sgPSBNWl9DdXJyZW50KCk7CiAgRE9TU1lTVEVNICpzeXMsICpwcmV2OwoKICBpZiAobHBEb3NUYXNrKSB7CiAgICBzeXMgPSBscERvc1Rhc2stPnN5czsKICAgIHByZXYgPSBOVUxMOwogICAgd2hpbGUgKHN5cyAmJiAoc3lzLT5pZCAhPSBpZCkpIHsKICAgICAgcHJldiA9IHN5czsKICAgICAgc3lzID0gc3lzLT5uZXh0OwogICAgfQogICAgaWYgKHN5cykgewogICAgICBmcmVlKHN5cy0+ZGF0YSk7CiAgICAgIHN5cy0+ZGF0YSA9IGRhdGE7CiAgICB9IGVsc2UgewogICAgICBzeXMgPSBtYWxsb2Moc2l6ZW9mKERPU1NZU1RFTSkpOwogICAgICBzeXMtPmlkID0gaWQ7CiAgICAgIHN5cy0+ZGF0YSA9IGRhdGE7CiAgICAgIHN5cy0+bmV4dCA9IE5VTEw7CiAgICAgIGlmIChwcmV2KSBwcmV2LT5uZXh0ID0gc3lzOwogICAgICBlbHNlIGxwRG9zVGFzay0+c3lzID0gc3lzOwogICAgfQogIH0gZWxzZSBmcmVlKGRhdGEpOwp9Cgp2b2lkKiBET1NWTV9HZXRTeXN0ZW1EYXRhKCBpbnQgaWQgKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBET1NTWVNURU0gKnN5czsKCiAgaWYgKGxwRG9zVGFzaykgewogICAgc3lzID0gbHBEb3NUYXNrLT5zeXM7CiAgICB3aGlsZSAoc3lzICYmIChzeXMtPmlkICE9IGlkKSkKICAgICAgc3lzID0gc3lzLT5uZXh0OwogICAgaWYgKHN5cykKICAgICAgcmV0dXJuIHN5cy0+ZGF0YTsKICB9CiAgcmV0dXJuIE5VTEw7Cn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCmludCBET1NWTV9FbnRlciggQ09OVEVYVDg2ICpjb250ZXh0ICkKewogRVJSXyhtb2R1bGUpKCJET1MgcmVhbG1vZGUgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZSFcbiIpOwogcmV0dXJuIC0xOwp9Cgp2b2lkIERPU1ZNX1dhaXQoIGludCByZWFkX3BpcGUsIEhBTkRMRSBoT2JqZWN0KSB7fQp2b2lkIERPU1ZNX1BJQ19pb3BvcnRfb3V0KCBXT1JEIHBvcnQsIEJZVEUgdmFsKSB7fQp2b2lkIERPU1ZNX1NldFRpbWVyKCB1bnNpZ25lZCB0aWNrcyApIHt9CnVuc2lnbmVkIERPU1ZNX0dldFRpbWVyKCB2b2lkICkgeyByZXR1cm4gMDsgfQp2b2lkIERPU1ZNX1NldFN5c3RlbURhdGEoIGludCBpZCwgdm9pZCAqZGF0YSApIHsgZnJlZShkYXRhKTsgfQp2b2lkKiBET1NWTV9HZXRTeXN0ZW1EYXRhKCBpbnQgaWQgKSB7IHJldHVybiBOVUxMOyB9CnZvaWQgRE9TVk1fUXVldWVFdmVudCggaW50IGlycSwgaW50IHByaW9yaXR5LCB2b2lkICgqcmVsYXkpKExQRE9TVEFTSyxDT05URVhUODYqLHZvaWQqKSwgdm9pZCAqZGF0YSkge30KCiNlbmRpZgo=