LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAic2VsZWN0b3JzLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJsZHQuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgIm1pc2NlbXUuaCIKI2luY2x1ZGUgImRlYnVndG9vbHMuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zbW9kLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJ2Z2EuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChtb2R1bGUpOwoKc3RhdGljIExQRE9TVEFTSyBkb3NfY3VycmVudDsKCiNpZmRlZiBNWl9TVVBQT1JURUQKCiNpZmRlZiBIQVZFX1NZU19NTUFOX0gKIyBpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFBTUF9TSVpFIDB4MTAKCiNkZWZpbmUgU0VHMTYocHRyLHNlZykgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRCkoc2VnKTw8NCkpKQojZGVmaW5lIFNFR1BUUjE2KHB0cixzZWdwdHIpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpU0VMRUNUT1JPRihzZWdwdHIpPDw0KStPRkZTRVRPRihzZWdwdHIpKSkKCi8qIHN0cnVjdHVyZXMgZm9yIEVYRUMgKi8KCnR5cGVkZWYgc3RydWN0IHsKICBXT1JEIGVudl9zZWc7CiAgRFdPUkQgY21kbGluZSBXSU5FX1BBQ0tFRDsKICBEV09SRCBmY2IxIFdJTkVfUEFDS0VEOwogIERXT1JEIGZjYjIgV0lORV9QQUNLRUQ7CiAgV09SRCBpbml0X3NwOwogIFdPUkQgaW5pdF9zczsKICBXT1JEIGluaXRfaXA7CiAgV09SRCBpbml0X2NzOwp9IEV4ZWNCbG9jazsKCnR5cGVkZWYgc3RydWN0IHsKICBXT1JEIGxvYWRfc2VnOwogIFdPUkQgcmVsX3NlZzsKfSBPdmVybGF5QmxvY2s7CgovKiBnbG9iYWwgdmFyaWFibGVzICovCgpzdGF0aWMgV09SRCBpbml0X2NzLGluaXRfaXAsaW5pdF9zcyxpbml0X3NwOwpzdGF0aWMgY2hhciBtbV9uYW1lWzEyOF07CgppbnQgcmVhZF9waXBlLCB3cml0ZV9waXBlOwpIQU5ETEUgaFJlYWRQaXBlLCBoV3JpdGVQaXBlOwpwaWRfdCBkb3Ntb2RfcGlkOwoKc3RhdGljIHZvaWQgTVpfTGF1bmNoKHZvaWQpOwpzdGF0aWMgQk9PTCBNWl9Jbml0VGFzayh2b2lkKTsKc3RhdGljIHZvaWQgTVpfS2lsbFRhc2sodm9pZCk7CgpzdGF0aWMgdm9pZCBNWl9DcmVhdGVQU1AoIExQVk9JRCBscFBTUCwgV09SRCBlbnYsIFdPUkQgcGFyICkKewogIFBEQjE2KnBzcD1scFBTUDsKCiAgcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogIC8qIHNvbWUgcHJvZ3JhbXMgdXNlIHRoaXMgdG8gY2FsY3VsYXRlIGhvdyBtdWNoIG1lbW9yeSB0aGV5IG5lZWQgKi8KICBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOyAvKiBGSVhNRTogdXNlIGEgcmVhbCB2YWx1ZSAqLwogIC8qIEZJWE1FOiBkaXNwYXRjaGVyICovCiAgcHNwLT5zYXZlZGludDIyID0gSU5UX0dldFJNSGFuZGxlcigweDIyKTsKICBwc3AtPnNhdmVkaW50MjMgPSBJTlRfR2V0Uk1IYW5kbGVyKDB4MjMpOwogIHBzcC0+c2F2ZWRpbnQyNCA9IElOVF9HZXRSTUhhbmRsZXIoMHgyNCk7CiAgcHNwLT5wYXJlbnRQU1A9cGFyOwogIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgpzdGF0aWMgdm9pZCBNWl9GaWxsUFNQKCBMUFZPSUQgbHBQU1AsIExQQ1NUUiBjbWRsaW5lICkKewogUERCMTYqcHNwPWxwUFNQOwogY29uc3QgY2hhcipjbWQ9Y21kbGluZT9zdHJjaHIoY21kbGluZSwnICcpOk5VTEw7CgogLyogY29weSBwYXJhbWV0ZXJzICovCiBpZiAoY21kKSB7CiNpZiAwCiAgLyogY29tbWFuZC5jb20gZG9lc24ndCBkbyB0aGlzICovCiAgd2hpbGUgKCpjbWQgPT0gJyAnKSBjbWQrKzsKI2VuZGlmCiAgcHNwLT5jbWRMaW5lWzBdPXN0cmxlbihjbWQpOwogIHN0cmNweShwc3AtPmNtZExpbmUrMSxjbWQpOwogIHBzcC0+Y21kTGluZVtwc3AtPmNtZExpbmVbMF0rMV09J1xyJzsKIH0gZWxzZSBwc3AtPmNtZExpbmVbMV09J1xyJzsKIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgovKiBkZWZhdWx0IElOVCAwOCBoYW5kbGVyOiBpbmNyZWFzZXMgdGltZXIgdGljayBjb3VudGVyIGJ1dCBub3QgbXVjaCBtb3JlICovCnN0YXRpYyBjaGFyIGludDA4W109ewogMHhDRCwweDFDLCAgICAgICAgICAgLyogaW50ICQweDFjICovCiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4MUUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkcyAqLwogMHhCOCwweDQwLDB4MDAsICAgICAgLyogbW92dyAkMHg0MCwlYXggKi8KIDB4OEUsMHhEOCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVkcyAqLwojaWYgMAogMHg4MywweDA2LDB4NkMsMHgwMCwweDAxLCAvKiBhZGR3ICQxLCgweDZjKSAqLwogMHg4MywweDE2LDB4NkUsMHgwMCwweDAwLCAvKiBhZGN3ICQwLCgweDZlKSAqLwojZWxzZQogMHg2NiwweEZGLDB4MDYsMHg2QywweDAwLCAvKiBpbmNsICgweDZjKSAqLwojZW5kaWYKIDB4QjAsMHgyMCwgICAgICAgICAgIC8qIG1vdmIgJDB4MjAsJWFsICovCiAweEU2LDB4MjAsICAgICAgICAgICAvKiBvdXRiICVhbCwkMHgyMCAqLwogMHgxRiwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENGICAgICAgICAgICAgICAgICAvKiBpcmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0SGFuZGxlcnModm9pZCkKewogV09SRCBzZWc7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKHNpemVvZihpbnQwOCksJnNlZyk7CiBtZW1jcHkoc3RhcnQsaW50MDgsc2l6ZW9mKGludDA4KSk7Ci8qIElOVCAwODogcG9pbnQgaXQgYXQgb3VyIHRpY2staW5jcmVtZW50aW5nIGhhbmRsZXIgKi8KICgoU0VHUFRSKikwKVsweDA4XT1QVFJfU0VHX09GRl9UT19TRUdQVFIoc2VnLDApOwovKiBJTlQgMUM6IGp1c3QgcG9pbnQgaXQgdG8gSVJFVCwgd2UgZG9uJ3Qgd2FudCB0byBoYW5kbGUgaXQgb3Vyc2VsdmVzICovCiAoKFNFR1BUUiopMClbMHgxQ109UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZyxzaXplb2YoaW50MDgpLTEpOwp9CgpzdGF0aWMgV09SRCBNWl9Jbml0RW52aXJvbm1lbnQoIExQQ1NUUiBlbnYsIExQQ1NUUiBuYW1lICkKewogdW5zaWduZWQgc3o9MDsKIFdPUkQgc2VnOwogTFBTVFIgZW52YmxrOwoKIGlmIChlbnYpIHsKICAvKiBnZXQgc2l6ZSBvZiBlbnZpcm9ubWVudCBibG9jayAqLwogIHdoaWxlIChlbnZbc3orK10pIHN6Kz1zdHJsZW4oZW52K3N6KSsxOwogfSBlbHNlIHN6Kys7CiAvKiBhbGxvY2F0ZSBpdCAqLwogZW52YmxrPURPU01FTV9HZXRCbG9jayhzeitzaXplb2YoV09SRCkrc3RybGVuKG5hbWUpKzEsJnNlZyk7CiAvKiBmaWxsIGl0ICovCiBpZiAoZW52KSB7CiAgbWVtY3B5KGVudmJsayxlbnYsc3opOwogfSBlbHNlIGVudmJsa1swXT0wOwogLyogRE9TIDMueDogdGhlIGJsb2NrIGNvbnRhaW5zIDEgYWRkaXRpb25hbCBzdHJpbmcgKi8KICooV09SRCopKGVudmJsaytzeik9MTsKIC8qIGJlaW5nIHRoZSBwcm9ncmFtIG5hbWUgaXRzZWxmICovCiBzdHJjcHkoZW52YmxrK3N6K3NpemVvZihXT1JEKSxuYW1lKTsKIHJldHVybiBzZWc7Cn0KCnN0YXRpYyBCT09MIE1aX0luaXRNZW1vcnkodm9pZCkKewogICAgaW50IG1tX2ZkOwogICAgdm9pZCAqaW1nX2Jhc2U7CgogICAgLyogaW5pdGlhbGl6ZSB0aGUgbWVtb3J5ICovCiAgICBUUkFDRSgiSW5pdGlhbGl6aW5nIERPUyBtZW1vcnkgc3RydWN0dXJlc1xuIik7CiAgICBET1NNRU1fSW5pdChUUlVFKTsKCiAgICAvKiBhbGxvY2F0ZSAxTUIrNjRLIHNoYXJlZCBtZW1vcnkgKi8KICAgIHRtcG5hbShtbV9uYW1lKTsKICAgIC8qIHN0cmNweShtbV9uYW1lLCIvdG1wL215ZG9zaW1hZ2UiKTsgKi8KICAgIG1tX2ZkID0gb3BlbihtbV9uYW1lLE9fUkRXUnxPX0NSRUFUIC8qIHxPX1RSVU5DICovLFNfSVJVU1J8U19JV1VTUik7CiAgICBpZiAobW1fZmQgPCAwKSBFUlIoImZpbGUgJXMgY291bGQgbm90IGJlIG9wZW5lZFxuIixtbV9uYW1lKTsKICAgIC8qIGZpbGwgdGhlIGZpbGUgd2l0aCB0aGUgRE9TIG1lbW9yeSAqLwogICAgaWYgKHdyaXRlKCBtbV9mZCwgTlVMTCwgMHgxMTAwMDAgKSAhPSAweDExMDAwMCkgRVJSKCJjYW5ub3Qgd3JpdGUgRE9TIG1lbVxuIik7CiAgICAvKiBtYXAgaXQgaW4gKi8KICAgIGltZ19iYXNlID0gbW1hcChOVUxMLDB4MTEwMDAwLFBST1RfUkVBRHxQUk9UX1dSSVRFfFBST1RfRVhFQyxNQVBfU0hBUkVEfE1BUF9GSVhFRCxtbV9mZCwwKTsKICAgIGNsb3NlKCBtbV9mZCApOwoKICAgIGlmIChpbWdfYmFzZSkKICAgIHsKICAgICAgICBFUlIoImNvdWxkIG5vdCBtYXAgc2hhcmVkIG1lbW9yeSwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBNWl9Jbml0SGFuZGxlcnMoKTsKICAgIHJldHVybiBUUlVFOwp9CgpCT09MIE1aX0RvTG9hZEltYWdlKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgT3ZlcmxheUJsb2NrICpvYmxrICkKewogIExQRE9TVEFTSyBscERvc1Rhc2sgPSBkb3NfY3VycmVudDsKICBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKICBEV09SRCBpbWFnZV9zdGFydCxpbWFnZV9zaXplLG1pbl9zaXplLG1heF9zaXplLGF2YWlsOwogIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0LCpvbGRlbnY7CiAgaW50IHgsIG9sZF9jb209MCwgYWxsb2M7CiAgU0VHUFRSIHJlbG9jOwogIFdPUkQgZW52X3NlZywgbG9hZF9zZWcsIHJlbF9zZWcsIG9sZHBzcF9zZWc7CiAgRFdPUkQgbGVuOwoKICBpZiAobHBEb3NUYXNrKSB7CiAgICAvKiBET1MgcHJvY2VzcyBhbHJlYWR5IHJ1bm5pbmcsIGluaGVyaXQgZnJvbSBpdCAqLwogICAgUERCMTYqIHBhcl9wc3AgPSAoUERCMTYqKSgoRFdPUkQpbHBEb3NUYXNrLT5wc3Bfc2VnIDw8IDQpOwogICAgYWxsb2M9MDsKICAgIG9sZGVudiA9IChMUEJZVEUpKChEV09SRClwYXJfcHNwLT5lbnZpcm9ubWVudCA8PCA0KTsKICAgIG9sZHBzcF9zZWcgPSBscERvc1Rhc2stPnBzcF9zZWc7CiAgfSBlbHNlIHsKICAgIC8qIGFsbG9jYXRlIG5ldyBET1MgcHJvY2VzcywgaW5oZXJpdGluZyBmcm9tIFdpbmUgZW52aXJvbm1lbnQgKi8KICAgIGFsbG9jPTE7CiAgICBscERvc1Rhc2sgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKERPU1RBU0spKTsKICAgIGRvc19jdXJyZW50ID0gbHBEb3NUYXNrOwogICAgb2xkZW52ID0gR2V0RW52aXJvbm1lbnRTdHJpbmdzQSgpOwogICAgb2xkcHNwX3NlZyA9IDA7CiAgfQoKIFNldEZpbGVQb2ludGVyKGhGaWxlLDAsTlVMTCxGSUxFX0JFR0lOKTsKIGlmICggICAhUmVhZEZpbGUoaEZpbGUsJm16X2hlYWRlcixzaXplb2YobXpfaGVhZGVyKSwmbGVuLE5VTEwpCiAgICAgfHwgbGVuICE9IHNpemVvZihtel9oZWFkZXIpIAogICAgIHx8IG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpIHsKICBjaGFyICpwID0gc3RycmNociggZmlsZW5hbWUsICcuJyApOwogIGlmICghcCB8fCBzdHJjYXNlY21wKCBwLCAiLmNvbSIgKSkgIC8qIGNoZWNrIGZvciAuQ09NIGV4dGVuc2lvbiAqLwogIHsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgfQogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKICBpZiAoYWxsb2MpIE1aX0luaXRNZW1vcnkoKTsKCiAgaWYgKG9ibGspIHsKICAgIC8qIGxvYWQgb3ZlcmxheSBpbnRvIHByZWFsbG9jYXRlZCBtZW1vcnkgKi8KICAgIGxvYWRfc2VnPW9ibGstPmxvYWRfc2VnOwogICAgcmVsX3NlZz1vYmxrLT5yZWxfc2VnOwogICAgbG9hZF9zdGFydD0oTFBCWVRFKSgoRFdPUkQpbG9hZF9zZWc8PDQpOwogIH0gZWxzZSB7CiAgICAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogICAgZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQob2xkZW52LCBmaWxlbmFtZSk7CgogICAgLyogYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgZXhlY3V0YWJsZSAqLwogICAgVFJBQ0UoIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogICAgYXZhaWw9RE9TTUVNX0F2YWlsYWJsZSgpOwogICAgaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgICAgIEVSUigiaW5zdWZmaWNpZW50IERPUyBtZW1vcnlcbiIpOwogICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgICB9CiAgICBpZiAoYXZhaWw+bWF4X3NpemUpIGF2YWlsPW1heF9zaXplOwogICAgcHNwX3N0YXJ0PURPU01FTV9HZXRCbG9jayhhdmFpbCwmbHBEb3NUYXNrLT5wc3Bfc2VnKTsKICAgIGlmICghcHNwX3N0YXJ0KSB7CiAgICAgIEVSUigiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgbG9hZF9zZWc9bHBEb3NUYXNrLT5wc3Bfc2VnKyhvbGRfY29tPzA6UFNQX1NJWkUpOwogICAgcmVsX3NlZz1sb2FkX3NlZzsKICAgIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiAgICBNWl9DcmVhdGVQU1AocHNwX3N0YXJ0LCBlbnZfc2VnLCBvbGRwc3Bfc2VnKTsKICB9CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRSgibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBTZXRGaWxlUG9pbnRlcihoRmlsZSxpbWFnZV9zdGFydCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCFSZWFkRmlsZShoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUsJmxlbixOVUxMKSB8fCBsZW4gIT0gaW1hZ2Vfc2l6ZSkgewogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICBnb3RvIGxvYWRfZXJyb3I7CiB9CgogaWYgKG16X2hlYWRlci5lX2NybGMpIHsKICAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KICBUUkFDRSgibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfY3JsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBTZXRGaWxlUG9pbnRlcihoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsTlVMTCxGSUxFX0JFR0lOKTsKICBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICAgaWYgKCFSZWFkRmlsZShoRmlsZSwmcmVsb2Msc2l6ZW9mKHJlbG9jKSwmbGVuLE5VTEwpIHx8IGxlbiAhPSBzaXplb2YocmVsb2MpKSB7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgICBnb3RvIGxvYWRfZXJyb3I7CiAgIH0KICAgKihXT1JEKilTRUdQVFIxNihsb2FkX3N0YXJ0LHJlbG9jKSs9cmVsX3NlZzsKICB9CiB9CgogIGlmICghb2JsaykgewogICAgaW5pdF9jcyA9IGxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogICAgaW5pdF9pcCA9IG16X2hlYWRlci5lX2lwOwogICAgaW5pdF9zcyA9IGxvYWRfc2VnK216X2hlYWRlci5lX3NzOwogICAgaW5pdF9zcCA9IG16X2hlYWRlci5lX3NwOwoKICAgIFRSQUNFKCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGluaXRfY3MsaW5pdF9pcCk7CiAgfQoKICBpZiAoYWxsb2MgJiYgIU1aX0luaXRUYXNrKCkpIHsKICAgIE1aX0tpbGxUYXNrKCk7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfR0VOX0ZBSUxVUkUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgcmV0dXJuIFRSVUU7Cgpsb2FkX2Vycm9yOgogIGxwRG9zVGFzay0+cHNwX3NlZyA9IG9sZHBzcF9zZWc7CiAgaWYgKGFsbG9jKSB7CiAgICBkb3NfY3VycmVudCA9IE5VTEw7CiAgICBpZiAobW1fbmFtZVswXSE9MCkgdW5saW5rKG1tX25hbWUpOwogIH0KCiAgcmV0dXJuIEZBTFNFOwp9CgpCT09MIE1aX0xvYWRJbWFnZSggTFBDU1RSIGNtZGxpbmUgKQp7CiAgICBIRklMRSBoRmlsZTsKICAgIGNoYXIgKm5hbWUsIGJ1ZmZlcltNQVhfUEFUSF07CiAgICBMUENTVFIgcCA9IHN0cmNociggY21kbGluZSwgJyAnICk7CgogICAgaWYgKHApCiAgICB7CiAgICAgICAgaWYgKCEobmFtZSA9IEhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcCAtIGNtZGxpbmUgKyAxICkpKSByZXR1cm4gRkFMU0U7CiAgICAgICAgbWVtY3B5KCBuYW1lLCBjbWRsaW5lLCBwIC0gY21kbGluZSApOwogICAgICAgIG5hbWVbcCAtIGNtZGxpbmVdID0gMDsKICAgIH0KICAgIGVsc2UgbmFtZSA9IChjaGFyICopY21kbGluZTsKCiAgICBpZiAoIVNlYXJjaFBhdGhBKCBOVUxMLCBuYW1lLCAiLmV4ZSIsIHNpemVvZihidWZmZXIpLCBidWZmZXIsIE5VTEwgKSkgZ290byBlcnJvcjsKICAgIGlmICgoaEZpbGUgPSBDcmVhdGVGaWxlQSggYnVmZmVyLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgLTEgKSkgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpCiAgICAgICAgZ290byBlcnJvcjsKICAgIGlmICghTVpfRG9Mb2FkSW1hZ2UoIGhGaWxlLCBidWZmZXIsIE5VTEwgKSkKICAgIHsKICAgICAgICBDbG9zZUhhbmRsZSggaEZpbGUgKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgTVpfTGF1bmNoKCk7CiBlcnJvcjoKICAgIGlmIChuYW1lICE9IGNtZGxpbmUpIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBuYW1lICk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCkJPT0wgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIC8qIHRoaXMgbWF5IG9ubHkgYmUgY2FsbGVkIGZyb20gZXhpc3RpbmcgRE9TIHByb2Nlc3NlcwogICAqIChpLmUuIG9uZSBET1MgYXBwIHNwYXduaW5nIGFub3RoZXIpICovCiAgLyogRklYTUU6IGRvIHdlIHdhbnQgdG8gY2hlY2sgYmluYXJ5IHR5cGUgZmlyc3QsIHRvIGNoZWNrCiAgICogd2hldGhlciBpdCdzIGEgTkUvUEUgZXhlY3V0YWJsZT8gKi8KICBMUERPU1RBU0sgbHBEb3NUYXNrID0gTVpfQ3VycmVudCgpOwogIEhGSUxFIGhGaWxlID0gQ3JlYXRlRmlsZUEoIGZpbGVuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwKCQkJICAgICBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAtMSk7CiAgQk9PTCByZXQgPSBGQUxTRTsKICBpZiAoaEZpbGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHJldHVybiBGQUxTRTsKICBzd2l0Y2ggKGZ1bmMpIHsKICBjYXNlIDA6IC8qIGxvYWQgYW5kIGV4ZWN1dGUgKi8KICBjYXNlIDE6IC8qIGxvYWQgYnV0IGRvbid0IGV4ZWN1dGUgKi8KICAgIHsKICAgICAgLyogc2F2ZSBjdXJyZW50IHByb2Nlc3MncyByZXR1cm4gU1M6U1Agbm93ICovCiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpbHBEb3NUYXNrLT5wc3Bfc2VnIDw8IDQpOwogICAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgICBwc3AtPnNhdmVTdGFjayA9IChEV09SRClQVFJfU0VHX09GRl9UT19TRUdQVFIoY29udGV4dC0+U2VnU3MsIExPV09SRChjb250ZXh0LT5Fc3ApKTsKICAgIH0KICAgIHJldCA9IE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIE5VTEwgKTsKICAgIGlmIChyZXQpIHsKICAgICAgLyogTVpfTG9hZEltYWdlIGNyZWF0ZWQgYSBuZXcgUFNQIGFuZCBsb2FkZWQgbmV3IHZhbHVlcyBpbnRvIGxwRG9zVGFzaywKICAgICAgICogbGV0J3Mgd29yayBvbiB0aGUgbmV3IHZhbHVlcyBub3cgKi8KICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClscERvc1Rhc2stPnBzcF9zZWcgPDwgNCk7CiAgICAgIEV4ZWNCbG9jayAqYmxrID0gKEV4ZWNCbG9jayAqKXBhcmFtYmxrOwogICAgICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgRE9TTUVNX01hcFJlYWxUb0xpbmVhcihibGstPmNtZGxpbmUpKTsKICAgICAgLyogdGhlIGxhbWUgTVMtRE9TIGVuZ2luZWVycyBkZWNpZGVkIHRoYXQgdGhlIHJldHVybiBhZGRyZXNzIHNob3VsZCBiZSBpbiBpbnQyMiAqLwogICAgICBJTlRfU2V0Uk1IYW5kbGVyKDB4MjIsIChGQVJQUk9DMTYpUFRSX1NFR19PRkZfVE9fU0VHUFRSKGNvbnRleHQtPlNlZ0NzLCBMT1dPUkQoY29udGV4dC0+RWlwKSkpOwogICAgICBpZiAoZnVuYykgewoJLyogZG9uJ3QgZXhlY3V0ZSwganVzdCByZXR1cm4gc3RhcnR1cCBzdGF0ZSAqLwoJYmxrLT5pbml0X2NzID0gaW5pdF9jczsKCWJsay0+aW5pdF9pcCA9IGluaXRfaXA7CglibGstPmluaXRfc3MgPSBpbml0X3NzOwoJYmxrLT5pbml0X3NwID0gaW5pdF9zcDsKICAgICAgfSBlbHNlIHsKCS8qIGV4ZWN1dGUgYnkgbWFraW5nIHVzIHJldHVybiB0byBuZXcgcHJvY2VzcyAqLwoJY29udGV4dC0+U2VnQ3MgPSBpbml0X2NzOwoJY29udGV4dC0+RWlwICAgPSBpbml0X2lwOwoJY29udGV4dC0+U2VnU3MgPSBpbml0X3NzOwoJY29udGV4dC0+RXNwICAgPSBpbml0X3NwOwoJY29udGV4dC0+U2VnRHMgPSBscERvc1Rhc2stPnBzcF9zZWc7Cgljb250ZXh0LT5TZWdFcyA9IGxwRG9zVGFzay0+cHNwX3NlZzsKCWNvbnRleHQtPkVheCAgID0gMDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSAzOiAvKiBsb2FkIG92ZXJsYXkgKi8KICAgIHsKICAgICAgT3ZlcmxheUJsb2NrICpibGsgPSAoT3ZlcmxheUJsb2NrICopcGFyYW1ibGs7CiAgICAgIHJldCA9IE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIGJsayApOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIEZJWE1FKCJFWEVDIGxvYWQgdHlwZSAlZCBub3QgaW1wbGVtZW50ZWRcbiIsIGZ1bmMpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRlVOQ1RJT04pOwogICAgYnJlYWs7CiAgfQogIENsb3NlSGFuZGxlKGhGaWxlKTsKICByZXR1cm4gcmV0Owp9CgpMUERPU1RBU0sgTVpfQWxsb2NEUE1JVGFzayggdm9pZCApCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihET1NUQVNLKSk7CgogIGlmIChscERvc1Rhc2spIHsKICAgIGRvc19jdXJyZW50ID0gbHBEb3NUYXNrOwogICAgTVpfSW5pdE1lbW9yeSgpOwogICAgTVpfSW5pdFRhc2soKTsKICB9CiAgcmV0dXJuIGxwRG9zVGFzazsKfQoKc3RhdGljIHZvaWQgTVpfSW5pdFRpbWVyKCBpbnQgdmVyICkKewogaWYgKHZlcjwxKSB7CiAgLyogY2FuJ3QgbWFrZSB0aW1lciB0aWNrcyAqLwogfSBlbHNlIHsKICBpbnQgZnVuYzsKICBzdHJ1Y3QgdGltZXZhbCB0aW07CgogIC8qIHN0YXJ0IGRvc21vZCB0aW1lciBhdCA1NW1zICgxOC4ySHopICovCiAgZnVuYz1ET1NNT0RfU0VUX1RJTUVSOwogIHRpbS50dl9zZWM9MDsgdGltLnR2X3VzZWM9NTQ5MjU7CiAgd3JpdGUod3JpdGVfcGlwZSwmZnVuYyxzaXplb2YoZnVuYykpOwogIHdyaXRlKHdyaXRlX3BpcGUsJnRpbSxzaXplb2YodGltKSk7CiB9Cn0KCnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpCnsKICBpbnQgd3JpdGVfZmRbMl0seF9mZDsKICBwaWRfdCBjaGlsZDsKICBjaGFyIHBhdGhbMjU2XSwqZnBhdGg7CgogIC8qIGNyZWF0ZSBwaXBlcyAqLwogIGlmICghQ3JlYXRlUGlwZSgmaFJlYWRQaXBlLCZoV3JpdGVQaXBlLE5VTEwsMCkpIHJldHVybiBGQUxTRTsKICBpZiAocGlwZSh3cml0ZV9mZCk8MCkgewogICAgQ2xvc2VIYW5kbGUoaFJlYWRQaXBlKTsKICAgIENsb3NlSGFuZGxlKGhXcml0ZVBpcGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgcmVhZF9waXBlID0gRklMRV9HZXRVbml4SGFuZGxlKCBoUmVhZFBpcGUsIEdFTkVSSUNfUkVBRCApOwogIHhfZmQgPSBGSUxFX0dldFVuaXhIYW5kbGUoIGhXcml0ZVBpcGUsIEdFTkVSSUNfV1JJVEUgKTsKCiAgVFJBQ0UoIndpbjMyIHBpcGU6IHJlYWQ9JWQsIHdyaXRlPSVkLCB1bml4IHBpcGU6IHJlYWQ9JWQsIHdyaXRlPSVkXG4iLAogICAgICAgIGhSZWFkUGlwZSxoV3JpdGVQaXBlLHJlYWRfcGlwZSx4X2ZkKTsKICBUUkFDRSgib3V0Ym91bmQgdW5peCBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZCwgcGlkPSVkXG4iLHdyaXRlX2ZkWzBdLHdyaXRlX2ZkWzFdLGdldHBpZCgpKTsKCiAgd3JpdGVfcGlwZT13cml0ZV9mZFsxXTsKCiAgVFJBQ0UoIkxvYWRpbmcgRE9TIFZNIHN1cHBvcnQgbW9kdWxlXG4iKTsKICBpZiAoKGNoaWxkPWZvcmsoKSk8MCkgewogICAgY2xvc2Uod3JpdGVfZmRbMF0pOwogICAgY2xvc2UocmVhZF9waXBlKTsKICAgIGNsb3NlKHdyaXRlX3BpcGUpOwogICAgY2xvc2UoeF9mZCk7CiAgICBDbG9zZUhhbmRsZShoUmVhZFBpcGUpOwogICAgQ2xvc2VIYW5kbGUoaFdyaXRlUGlwZSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogaWYgKGNoaWxkIT0wKSB7CiAgLyogcGFyZW50IHByb2Nlc3MgKi8KICBpbnQgcmV0OwoKICBjbG9zZSh3cml0ZV9mZFswXSk7CiAgY2xvc2UoeF9mZCk7CiAgZG9zbW9kX3BpZCA9IGNoaWxkOwogIC8qIHdhaXQgZm9yIGNoaWxkIHByb2Nlc3MgdG8gc2lnbmFsIHJlYWRpbmVzcyAqLwogIHdoaWxlICgxKSB7CiAgICBpZiAocmVhZChyZWFkX3BpcGUsJnJldCxzaXplb2YocmV0KSk9PXNpemVvZihyZXQpKSBicmVhazsKICAgIGlmICgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSBjb250aW51ZTsKICAgIC8qIGZhaWx1cmUgKi8KICAgIEVSUigiZG9zbW9kIGhhcyBmYWlsZWQgdG8gaW5pdGlhbGl6ZVxuIik7CiAgICBpZiAobW1fbmFtZVswXSE9MCkgdW5saW5rKG1tX25hbWUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICAvKiB0aGUgY2hpbGQgaGFzIG5vdyBtbWFwZWQgdGhlIHRlbXAgZmlsZSwgaXQncyBub3cgc2FmZSB0byB1bmxpbmsuCiAgICogZG8gaXQgaGVyZSB0byBhdm9pZCBsZWF2aW5nIGEgbWVzcyBpbiAvdG1wIGlmL3doZW4gV2luZSBjcmFzaGVzLi4uICovCiAgaWYgKG1tX25hbWVbMF0hPTApIHVubGluayhtbV9uYW1lKTsKICAvKiBzdGFydCBzaW11bGF0ZWQgc3lzdGVtIHRpbWVyICovCiAgTVpfSW5pdFRpbWVyKHJldCk7CiAgaWYgKHJldDwyKSB7CiAgICBFUlIoImRvc21vZCB2ZXJzaW9uIHRvbyBvbGQhIFBsZWFzZSBpbnN0YWxsIG5ld2VyIGRvc21vZCBwcm9wZXJseVxuIik7CiAgICBFUlIoIklmIHlvdSBkb24ndCwgdGhlIG5ldyBkb3Ntb2QgZXZlbnQgaGFuZGxpbmcgc3lzdGVtIHdpbGwgbm90IHdvcmtcbiIpOwogIH0KICAvKiBhbGwgc3lzdGVtcyBhcmUgbm93IGdvICovCiB9IGVsc2UgewogIC8qIGNoaWxkIHByb2Nlc3MgKi8KICBjbG9zZShyZWFkX3BpcGUpOwogIGNsb3NlKHdyaXRlX3BpcGUpOwogIC8qIHB1dCBvdXIgcGlwZXMgc29tZXdoZXJlIGRvc21vZCBjYW4gZmluZCB0aGVtICovCiAgZHVwMih3cml0ZV9mZFswXSwwKTsgLyogc3RkaW4gKi8KICBkdXAyKHhfZmQsMSk7ICAgICAgICAvKiBzdGRvdXQgKi8KICAvKiBub3cgbG9hZCBkb3Ntb2QgKi8KICAvKiBjaGVjayBhcmd2WzBdLWRlcml2ZWQgcGF0aHMgZmlyc3QsIHNpbmNlIHRoZSBuZXdlc3QgZG9zbW9kIGlzIG1vc3QgbGlrZWx5IHRoZXJlCiAgICogKGF0IGxlYXN0IGl0IHdhcyBvbmNlIGZvciBBbmRyZWFzIE1vaHIsIHNvIEkgZGVjaWRlZCB0byBtYWtlIGl0IGVhc2llciBmb3IgaGltKSAqLwogIGZwYXRoPXN0cnJjaHIoc3RyY3B5KHBhdGgsZnVsbF9hcmd2MCksJy8nKTsKICBpZiAoZnBhdGgpIHsKICAgc3RyY3B5KGZwYXRoLCIvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsbW1fbmFtZSxOVUxMKTsKICAgc3RyY3B5KGZwYXRoLCIvbG9hZGVyL2Rvcy9kb3Ntb2QiKTsKICAgZXhlY2wocGF0aCxtbV9uYW1lLE5VTEwpOwogIH0KICAvKiBva2F5LCBpdCB3YXNuJ3QgdGhlcmUsIHRyeSBpbiB0aGUgcGF0aCAqLwogIGV4ZWNscCgiZG9zbW9kIixtbV9uYW1lLE5VTEwpOwogIC8qIGxhc3QgZGVzcGVyYXRlIGF0dGVtcHRzOiBjdXJyZW50IGRpcmVjdG9yeSAqLwogIGV4ZWNsKCJkb3Ntb2QiLG1tX25hbWUsTlVMTCk7CiAgLyogYW5kLCBqdXN0IGZvciBjb21wbGV0ZW5lc3MuLi4gKi8KICBleGVjbCgibG9hZGVyL2Rvcy9kb3Ntb2QiLG1tX25hbWUsTlVMTCk7CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUigiRmFpbGVkIHRvIHNwYXduIGRvc21vZCwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICBleGl0KDEpOwogfQogcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKQp7CiAgTFBET1NUQVNLIGxwRG9zVGFzayA9IE1aX0N1cnJlbnQoKTsKICBDT05URVhUIGNvbnRleHQ7CiAgVERCICpwVGFzayA9IChUREIgKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKICBCWVRFICpwc3Bfc3RhcnQgPSBQVFJfUkVBTF9UT19MSU4oIGxwRG9zVGFzay0+cHNwX3NlZywgMCApOwoKICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgR2V0Q29tbWFuZExpbmVBKCkpOwogIHBUYXNrLT5mbGFncyB8PSBUREJGX1dJTk9MREFQOwoKICBtZW1zZXQoICZjb250ZXh0LCAwLCBzaXplb2YoY29udGV4dCkgKTsKICBjb250ZXh0LlNlZ0NzICA9IGluaXRfY3M7CiAgY29udGV4dC5FaXAgICAgPSBpbml0X2lwOwogIGNvbnRleHQuU2VnU3MgID0gaW5pdF9zczsKICBjb250ZXh0LkVzcCAgICA9IGluaXRfc3A7CiAgY29udGV4dC5TZWdEcyAgPSBscERvc1Rhc2stPnBzcF9zZWc7CiAgY29udGV4dC5TZWdFcyAgPSBscERvc1Rhc2stPnBzcF9zZWc7CiAgY29udGV4dC5FRmxhZ3MgPSAweDAwMDgwMDAwOyAgLyogdmlydHVhbCBpbnRlcnJ1cHQgZmxhZyAqLwogIERPU1ZNX0VudGVyKCAmY29udGV4dCApOwp9CgpzdGF0aWMgdm9pZCBNWl9LaWxsVGFzayh2b2lkKQp7CiAgVFJBQ0UoImtpbGxpbmcgRE9TIHRhc2tcbiIpOwogIFZHQV9DbGVhbigpOwogIGtpbGwoZG9zbW9kX3BpZCxTSUdURVJNKTsKfQoKdm9pZCBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBMUERPU1RBU0sgbHBEb3NUYXNrID0gTVpfQ3VycmVudCgpOwogIGlmIChscERvc1Rhc2spIHsKICAgIFdPUkQgcHNwX3NlZyA9IGNzX3BzcCA/IGNvbnRleHQtPlNlZ0NzIDogbHBEb3NUYXNrLT5wc3Bfc2VnOwogICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClwc3Bfc2VnIDw8IDQpOwogICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgIFdPUkQgcGFycHNwID0gcHNwLT5wYXJlbnRQU1A7IC8qIGNoZWNrIGZvciBwYXJlbnQgRE9TIHByb2Nlc3MgKi8KICAgIGlmIChwYXJwc3ApIHsKICAgICAgLyogcmV0cmlldmUgcGFyZW50J3MgcmV0dXJuIGFkZHJlc3MgKi8KICAgICAgRkFSUFJPQzE2IHJldGFkZHIgPSBJTlRfR2V0Uk1IYW5kbGVyKDB4MjIpOwogICAgICAvKiByZXN0b3JlIGludGVycnVwdHMgKi8KICAgICAgSU5UX1NldFJNSGFuZGxlcigweDIyLCBwc3AtPnNhdmVkaW50MjIpOwogICAgICBJTlRfU2V0Uk1IYW5kbGVyKDB4MjMsIHBzcC0+c2F2ZWRpbnQyMyk7CiAgICAgIElOVF9TZXRSTUhhbmRsZXIoMHgyNCwgcHNwLT5zYXZlZGludDI0KTsKICAgICAgLyogRklYTUU6IGRlYWxsb2NhdGUgZmlsZSBoYW5kbGVzIGV0YyAqLwogICAgICAvKiBmcmVlIHByb2Nlc3MncyBhc3NvY2lhdGVkIG1lbW9yeQogICAgICAgKiBGSVhNRTogd2FsayBtZW1vcnkgYW5kIGRlYWxsb2NhdGUgYWxsIGJsb2NrcyBvd25lZCBieSBwcm9jZXNzICovCiAgICAgIERPU01FTV9GcmVlQmxvY2soRE9TTUVNX01hcFJlYWxUb0xpbmVhcihNQUtFTE9ORygwLHBzcC0+ZW52aXJvbm1lbnQpKSk7CiAgICAgIERPU01FTV9GcmVlQmxvY2soRE9TTUVNX01hcFJlYWxUb0xpbmVhcihNQUtFTE9ORygwLGxwRG9zVGFzay0+cHNwX3NlZykpKTsKICAgICAgLyogc3dpdGNoIHRvIHBhcmVudCdzIFBTUCAqLwogICAgICBscERvc1Rhc2stPnBzcF9zZWcgPSBwYXJwc3A7CiAgICAgIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClwYXJwc3AgPDwgNCk7CiAgICAgIHBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgLyogbm93IHJldHVybiB0byBwYXJlbnQgKi8KICAgICAgbHBEb3NUYXNrLT5yZXR2YWwgPSByZXR2YWw7CiAgICAgIGNvbnRleHQtPlNlZ0NzID0gU0VMRUNUT1JPRihyZXRhZGRyKTsKICAgICAgY29udGV4dC0+RWlwICAgPSBPRkZTRVRPRihyZXRhZGRyKTsKICAgICAgY29udGV4dC0+U2VnU3MgPSBTRUxFQ1RPUk9GKHBzcC0+c2F2ZVN0YWNrKTsKICAgICAgY29udGV4dC0+RXNwICAgPSBPRkZTRVRPRihwc3AtPnNhdmVTdGFjayk7CiAgICAgIHJldHVybjsKICAgIH0gZWxzZQogICAgICBNWl9LaWxsVGFzaygpOwogIH0KICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKQk9PTCBNWl9Mb2FkSW1hZ2UoIExQQ1NUUiBjbWRsaW5lICkKewogIFdBUk4oIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm1cbiIpOwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICByZXR1cm4gRkFMU0U7Cn0KCkJPT0wgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIC8qIGNhbid0IGhhcHBlbiAqLwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICByZXR1cm4gRkFMU0U7Cn0KCkxQRE9TVEFTSyBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogICAgRVJSKCJBY3R1YWwgcmVhbC1tb2RlIGNhbGxzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybSFcbiIpOwogICAgcmV0dXJuIE5VTEw7Cn0KCnZvaWQgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCiNlbmRpZiAvKiAhTVpfU1VQUE9SVEVEICovCgpMUERPU1RBU0sgTVpfQ3VycmVudCggdm9pZCApCnsKICByZXR1cm4gZG9zX2N1cnJlbnQ7Cn0K