LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgIm5lZXhlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzZWxlY3RvcnMuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAicHJvY2Vzcy5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zbW9kLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJzZXJ2ZXIuaCIKCkRFRkFVTFRfREVCVUdfQ0hBTk5FTChtb2R1bGUpCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaW5jbHVkZSA8c3lzL21tYW4uaD4KCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKc3RhdGljIHZvaWQgTVpfSW5pdFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSwgV09SRCBlbnYgKQp7CiBQREIxNipwc3A9bHBQU1A7CiBjb25zdCBjaGFyKmNtZD1jbWRsaW5lP3N0cmNocihjbWRsaW5lLCcgJyk6TlVMTDsKCiBwc3AtPmludDIwPTB4MjBDRDsgLyogaW50IDIwICovCiAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOwogcHNwLT5lbnZpcm9ubWVudD1lbnY7CiAvKiBjb3B5IHBhcmFtZXRlcnMgKi8KIGlmIChjbWQpIHsKI2lmIDAKICAvKiBjb21tYW5kLmNvbSBkb2Vzbid0IGRvIHRoaXMgKi8KICB3aGlsZSAoKmNtZCA9PSAnICcpIGNtZCsrOwojZW5kaWYKICBwc3AtPmNtZExpbmVbMF09c3RybGVuKGNtZCk7CiAgc3RyY3B5KHBzcC0+Y21kTGluZSsxLGNtZCk7CiAgcHNwLT5jbWRMaW5lW3BzcC0+Y21kTGluZVswXSsxXT0nXHInOwogfSBlbHNlIHBzcC0+Y21kTGluZVsxXT0nXHInOwogLyogRklYTUU6IGludGVncmF0ZSB0aGUgbWVtb3J5IHN0dWZmIGZyb20gV2luZSAobXNkb3MvZG9zbWVtLmMpICovCiAvKiBGSVhNRTogaW50ZWdyYXRlIHRoZSBQREIgc3R1ZmYgZnJvbSBXaW5lIChsb2FkZXIvdGFzay5jKSAqLwp9CgovKiBkZWZhdWx0IElOVCAwOCBoYW5kbGVyOiBpbmNyZWFzZXMgdGltZXIgdGljayBjb3VudGVyIGJ1dCBub3QgbXVjaCBtb3JlICovCnN0YXRpYyBjaGFyIGludDA4W109ewogMHhDRCwweDFDLCAgICAgICAgICAgLyogaW50ICQweDFjICovCiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4MUUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkcyAqLwogMHhCOCwweDQwLDB4MDAsICAgICAgLyogbW92dyAkMHg0MCwlYXggKi8KIDB4OEUsMHhEOCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVkcyAqLwojaWYgMAogMHg4MywweDA2LDB4NkMsMHgwMCwweDAxLCAvKiBhZGR3ICQxLCgweDZjKSAqLwogMHg4MywweDE2LDB4NkUsMHgwMCwweDAwLCAvKiBhZGN3ICQwLCgweDZlKSAqLwojZWxzZQogMHg2NiwweEZGLDB4MDYsMHg2QywweDAwLCAvKiBpbmNsICgweDZjKSAqLwojZW5kaWYKIDB4QjAsMHgyMCwgICAgICAgICAgIC8qIG1vdmIgJDB4MjAsJWFsICovCiAweEU2LDB4MjAsICAgICAgICAgICAvKiBvdXRiICVhbCwkMHgyMCAqLwogMHgxRiwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENGICAgICAgICAgICAgICAgICAvKiBpcmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0SGFuZGxlcnMoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBXT1JEIHNlZzsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihpbnQwOCksJnNlZyk7CiBtZW1jcHkoc3RhcnQsaW50MDgsc2l6ZW9mKGludDA4KSk7Ci8qIElOVCAwODogcG9pbnQgaXQgYXQgb3VyIHRpY2staW5jcmVtZW50aW5nIGhhbmRsZXIgKi8KICgoU0VHUFRSKikobHBEb3NUYXNrLT5pbWcpKVsweDA4XT1QVFJfU0VHX09GRl9UT19TRUdQVFIoc2VnLDApOwovKiBJTlQgMUM6IGp1c3QgcG9pbnQgaXQgdG8gSVJFVCwgd2UgZG9uJ3Qgd2FudCB0byBoYW5kbGUgaXQgb3Vyc2VsdmVzICovCiAoKFNFR1BUUiopKGxwRG9zVGFzay0+aW1nKSlbMHgxQ109UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZyxzaXplb2YoaW50MDgpLTEpOwp9CgpzdGF0aWMgY2hhciBlbnRlcl94bXNbXT17Ci8qIFhNUyBob29rYWJsZSBlbnRyeSBwb2ludCAqLwogMHhFQiwweDAzLCAgICAgICAgICAgLyogam1wIGVudHJ5ICovCiAweDkwLDB4OTAsMHg5MCwgICAgICAvKiBub3A7bm9wO25vcCAqLwogICAgICAgICAgICAgICAgICAgICAgLyogZW50cnk6ICovCi8qIHJlYWwgZW50cnkgcG9pbnQgKi8KLyogZm9yIHNpbXBsaWNpdHksIHdlJ2xsIGp1c3QgdXNlIHRoZSBzYW1lIGhvb2sgYXMgRFBNSSBiZWxvdyAqLwogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0WE1TKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsc2l6ZW9mKGVudGVyX3htcyksJihscERvc1Rhc2stPnhtc19zZWcpKTsKIG1lbWNweShzdGFydCxlbnRlcl94bXMsc2l6ZW9mKGVudGVyX3htcykpOwp9CgpzdGF0aWMgY2hhciBlbnRlcl9wbVtdPXsKIDB4NTAsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVheCAqLwogMHg1MiwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWR4ICovCiAweDU1LCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYnAgKi8KIDB4ODksMHhFNSwgICAgICAgICAgIC8qIG1vdncgJXNwLCVicCAqLwovKiBnZXQgcmV0dXJuIENTICovCiAweDhCLDB4NTYsMHgwOCwgICAgICAvKiBtb3Z3IDgoJWJwKSwlZHggKi8KLyoganVzdCBjYWxsIGludCAzMSBoZXJlIHRvIGdldCBpbnRvIHByb3RlY3RlZCBtb2RlLi4uICovCi8qIGl0J2xsIGNoZWNrIHdoZXRoZXIgaXQgd2FzIGNhbGxlZCBmcm9tIGRwbWlfc2VnLi4uICovCiAweENELDB4MzEsICAgICAgICAgICAvKiBpbnQgJDB4MzEgKi8KLyogd2UgYXJlIG5vdyBpbiB0aGUgY29udGV4dCBvZiBhIDE2LWJpdCByZWxheSBjYWxsICovCi8qIG5lZWQgdG8gZml4dXAgb3VyIHN0YWNrOwogKiAxNi1iaXQgcmVsYXkgcmV0dXJuIGFkZHJlc3Mgd2lsbCBiZSBsb3N0LCBidXQgd2Ugd29uJ3Qgd29ycnkgcXVpdGUgeWV0ICovCiAweDhFLDB4RDAsICAgICAgICAgICAvKiBtb3Z3ICVheCwlc3MgKi8KIDB4NjYsMHgwRiwweEI3LDB4RTUsIC8qIG1vdnp3bCAlYnAsJWVzcCAqLwovKiBzZXQgcmV0dXJuIENTICovCiAweDg5LDB4NTYsMHgwOCwgICAgICAvKiBtb3Z3ICVkeCw4KCVicCkgKi8KIDB4NUQsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWJwICovCiAweDVBLCAgICAgICAgICAgICAgICAvKiBwb3B3ICVkeCAqLwogMHg1OCwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4Q0IgICAgICAgICAgICAgICAgIC8qIGxyZXQgKi8KfTsKCnN0YXRpYyB2b2lkIE1aX0luaXREUE1JKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogdW5zaWduZWQgc2l6ZT1zaXplb2YoZW50ZXJfcG0pOwogTFBCWVRFIHN0YXJ0PURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsc2l6ZSwmKGxwRG9zVGFzay0+ZHBtaV9zZWcpKTsKIAogbHBEb3NUYXNrLT5kcG1pX3NlbCA9IFNFTEVDVE9SX0FsbG9jQmxvY2soIHN0YXJ0LCBzaXplLCBTRUdNRU5UX0NPREUsIEZBTFNFLCBGQUxTRSApOwoKIG1lbWNweShzdGFydCxlbnRlcl9wbSxzaXplb2YoZW50ZXJfcG0pKTsKfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUERPU1RBU0sgbHBEb3NUYXNrLCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSggTFBET1NUQVNLIGxwRG9zVGFzaywgTkVfTU9EVUxFICpwTW9kdWxlICkKewogaW50IHg7CgogaWYgKGxwRG9zVGFzay0+aW1nKSByZXR1cm4gVFJVRTsgLyogYWxyZWFkeSBhbGxvY2F0ZWQgKi8KCiAvKiBhbGxvY2F0ZSAxTUIrNjRLIHNoYXJlZCBtZW1vcnkgKi8KIGxwRG9zVGFzay0+aW1nX29mcz1TVEFSVF9PRkZTRVQ7CiNpZmRlZiBNWl9NQVBTRUxGCiBscERvc1Rhc2stPmltZz1WaXJ0dWFsQWxsb2MoTlVMTCwweDExMDAwMCxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKIC8qIG1ha2Ugc3VyZSBtbWFwIGFjY2VwdHMgaXQgKi8KICgoY2hhciopbHBEb3NUYXNrLT5pbWcpWzB4MTBGRkZGXT0wOwojZWxzZQogdG1wbmFtKGxwRG9zVGFzay0+bW1fbmFtZSk7Ci8qIHN0cmNweShscERvc1Rhc2stPm1tX25hbWUsIi90bXAvbXlkb3NpbWFnZSIpOyAqLwogbHBEb3NUYXNrLT5tbV9mZD1vcGVuKGxwRG9zVGFzay0+bW1fbmFtZSxPX1JEV1J8T19DUkVBVCAvKiB8T19UUlVOQyAqLyxTX0lSVVNSfFNfSVdVU1IpOwogaWYgKGxwRG9zVGFzay0+bW1fZmQ8MCkgRVJSKG1vZHVsZSwiZmlsZSAlcyBjb3VsZCBub3QgYmUgb3BlbmVkXG4iLGxwRG9zVGFzay0+bW1fbmFtZSk7CiAvKiBleHBhbmQgZmlsZSB0byAxTUIrNjRLICovCiBsc2VlayhscERvc1Rhc2stPm1tX2ZkLDB4MTEwMDAwLTEsU0VFS19TRVQpOwogeD0wOyB3cml0ZShscERvc1Rhc2stPm1tX2ZkLCZ4LDEpOwogLyogbWFwIGl0IGluICovCiBscERvc1Rhc2stPmltZz1tbWFwKE5VTEwsMHgxMTAwMDAtU1RBUlRfT0ZGU0VULFBST1RfUkVBRHxQUk9UX1dSSVRFLE1BUF9TSEFSRUQsbHBEb3NUYXNrLT5tbV9mZCwwKTsKI2VuZGlmCiBpZiAobHBEb3NUYXNrLT5pbWc9PShMUFZPSUQpLTEpIHsKICBFUlIobW9kdWxlLCJjb3VsZCBub3QgbWFwIHNoYXJlZCBtZW1vcnksIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgcmV0dXJuIEZBTFNFOwogfQogVFJBQ0UobW9kdWxlLCJET1MgVk04NiBpbWFnZSBtYXBwZWQgYXQgJTA4bHhcbiIsKERXT1JEKWxwRG9zVGFzay0+aW1nKTsKIHBNb2R1bGUtPmRvc19pbWFnZT1scERvc1Rhc2stPmltZzsKCiAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KIFRSQUNFKG1vZHVsZSwiSW5pdGlhbGl6aW5nIERPUyBtZW1vcnkgc3RydWN0dXJlc1xuIik7CiBET1NNRU1fSW5pdChscERvc1Rhc2stPmhNb2R1bGUpOwogTVpfSW5pdEhhbmRsZXJzKGxwRG9zVGFzayk7CiBNWl9Jbml0WE1TKGxwRG9zVGFzayk7CiBNWl9Jbml0RFBNSShscERvc1Rhc2spOwogcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MIE1aX0xvYWRJbWFnZSggSEZJTEUgaEZpbGUsIE9GU1RSVUNUICpvZnMsIExQQ1NUUiBjbWRsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBlbnYsIExQRE9TVEFTSyBscERvc1Rhc2ssIE5FX01PRFVMRSAqcE1vZHVsZSApCnsKIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogRFdPUkQgaW1hZ2Vfc3RhcnQsaW1hZ2Vfc2l6ZSxtaW5fc2l6ZSxtYXhfc2l6ZSxhdmFpbDsKIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0OwogaW50IHgsb2xkX2NvbT0wOwogU0VHUFRSIHJlbG9jOwogV09SRCBlbnZfc2VnOwoKIF9sbHNlZWsoaEZpbGUsMCxGSUxFX0JFR0lOKTsKIGlmICgoX2xyZWFkKGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlcikpICE9IHNpemVvZihtel9oZWFkZXIpKSB8fAogICAgIChtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSkgewogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKIE1aX0luaXRNZW1vcnkobHBEb3NUYXNrLHBNb2R1bGUpOwoKIC8qIGFsbG9jYXRlIGVudmlyb25tZW50IGJsb2NrICovCiBlbnZfc2VnPU1aX0luaXRFbnZpcm9ubWVudChscERvc1Rhc2ssZW52LG9mcy0+c3pQYXRoTmFtZSk7CgogLyogYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgZXhlY3V0YWJsZSAqLwogVFJBQ0UobW9kdWxlLCJBbGxvY2F0aW5nIERPUyBtZW1vcnkgKG1pbj0lbGQsIG1heD0lbGQpXG4iLG1pbl9zaXplLG1heF9zaXplKTsKIGF2YWlsPURPU01FTV9BdmFpbGFibGUobHBEb3NUYXNrLT5oTW9kdWxlKTsKIGlmIChhdmFpbDxtaW5fc2l6ZSkgewogIEVSUihtb2R1bGUsICJpbnN1ZmZpY2llbnQgRE9TIG1lbW9yeVxuIik7CiAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICByZXR1cm4gRkFMU0U7CiB9CiBpZiAoYXZhaWw+bWF4X3NpemUpIGF2YWlsPW1heF9zaXplOwogcHNwX3N0YXJ0PURPU01FTV9HZXRCbG9jayhscERvc1Rhc2stPmhNb2R1bGUsYXZhaWwsJmxwRG9zVGFzay0+cHNwX3NlZyk7CiBpZiAoIXBzcF9zdGFydCkgewogIEVSUihtb2R1bGUsICJlcnJvciBhbGxvY2F0aW5nIERPUyBtZW1vcnlcbiIpOwogIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgcmV0dXJuIEZBTFNFOwogfQogbHBEb3NUYXNrLT5sb2FkX3NlZz1scERvc1Rhc2stPnBzcF9zZWcrKG9sZF9jb20/MDpQU1BfU0laRSk7CiBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogTVpfSW5pdFBTUChwc3Bfc3RhcnQsIGNtZGxpbmUsIGVudl9zZWcpOwoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UobW9kdWxlLCJsb2FkaW5nIERPUyAlcyBpbWFnZSwgJTA4bHggYnl0ZXNcbiIsb2xkX2NvbT8iQ09NIjoiRVhFIixpbWFnZV9zaXplKTsKIF9sbHNlZWsoaEZpbGUsaW1hZ2Vfc3RhcnQsRklMRV9CRUdJTik7CiBpZiAoKF9scmVhZChoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUpKSAhPSBpbWFnZV9zaXplKSB7CiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogIHJldHVybiBGQUxTRTsKIH0KCiBpZiAobXpfaGVhZGVyLmVfY3JsYykgewogIC8qIGxvYWQgcmVsb2NhdGlvbiB0YWJsZSAqLwogIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfY3JsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBfbGxzZWVrKGhGaWxlLG16X2hlYWRlci5lX2xmYXJsYyxGSUxFX0JFR0lOKTsKICBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICAgaWYgKF9scmVhZChoRmlsZSwmcmVsb2Msc2l6ZW9mKHJlbG9jKSkgIT0gc2l6ZW9mKHJlbG9jKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgcmV0dXJuIEZBTFNFOwogICB9CiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPWxwRG9zVGFzay0+bG9hZF9zZWc7CiAgfQogfQoKIGxwRG9zVGFzay0+aW5pdF9jcz1scERvc1Rhc2stPmxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogbHBEb3NUYXNrLT5pbml0X2lwPW16X2hlYWRlci5lX2lwOwogbHBEb3NUYXNrLT5pbml0X3NzPWxwRG9zVGFzay0+bG9hZF9zZWcrbXpfaGVhZGVyLmVfc3M7CiBscERvc1Rhc2stPmluaXRfc3A9bXpfaGVhZGVyLmVfc3A7CgogVFJBQ0UobW9kdWxlLCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGxwRG9zVGFzay0+aW5pdF9jcyxscERvc1Rhc2stPmluaXRfaXApOwogcmV0dXJuIFRSVUU7Cn0KCkxQRE9TVEFTSyBNWl9BbGxvY0RQTUlUYXNrKCBITU9EVUxFMTYgaE1vZHVsZSApCnsKIExQRE9TVEFTSyBscERvc1Rhc2sgPSBjYWxsb2MoMSwgc2l6ZW9mKERPU1RBU0spKTsKIE5FX01PRFVMRSAqcE1vZHVsZTsKCiBpZiAobHBEb3NUYXNrKSB7CiAgbHBEb3NUYXNrLT5oTW9kdWxlID0gaE1vZHVsZTsKCiAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoaE1vZHVsZSk7CiAgcE1vZHVsZS0+bHBEb3NUYXNrID0gbHBEb3NUYXNrOwogCiAgbHBEb3NUYXNrLT5pbWc9TlVMTDsgbHBEb3NUYXNrLT5tbV9uYW1lWzBdPTA7IGxwRG9zVGFzay0+bW1fZmQ9LTE7CgogIE1aX0luaXRNZW1vcnkobHBEb3NUYXNrLCBwTW9kdWxlKTsKCiAgR2xvYmFsVW5sb2NrMTYoaE1vZHVsZSk7CiB9CiByZXR1cm4gbHBEb3NUYXNrOwp9CgpzdGF0aWMgdm9pZCBNWl9Jbml0VGltZXIoIExQRE9TVEFTSyBscERvc1Rhc2ssIGludCB2ZXIgKQp7CiBpZiAodmVyPDEpIHsKICAvKiBjYW4ndCBtYWtlIHRpbWVyIHRpY2tzICovCiB9IGVsc2UgewogIGludCBmdW5jOwogIHN0cnVjdCB0aW1ldmFsIHRpbTsKCiAgLyogc3RhcnQgZG9zbW9kIHRpbWVyIGF0IDU1bXMgKDE4LjJIeikgKi8KICBmdW5jPURPU01PRF9TRVRfVElNRVI7CiAgdGltLnR2X3NlYz0wOyB0aW0udHZfdXNlYz01NDkyNTsKICB3cml0ZShscERvc1Rhc2stPndyaXRlX3BpcGUsJmZ1bmMsc2l6ZW9mKGZ1bmMpKTsKICB3cml0ZShscERvc1Rhc2stPndyaXRlX3BpcGUsJnRpbSxzaXplb2YodGltKSk7CiB9Cn0KCkJPT0wgTVpfSW5pdFRhc2soIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiAgaW50IHdyaXRlX2ZkWzJdLHhfZmQ7CiAgcGlkX3QgY2hpbGQ7CiAgY2hhciAqZm5hbWUsKmZhcmcsYXJnWzE2XSxmcHJvY1s2NF0scGF0aFsyNTZdLCpmcGF0aDsKICBTRUNVUklUWV9BVFRSSUJVVEVTIGF0dHI9e3NpemVvZihhdHRyKSxOVUxMLFRSVUV9OwogIHN0cnVjdCBnZXRfcmVhZF9mZF9yZXF1ZXN0IHJfcmVxOwogIHN0cnVjdCBnZXRfd3JpdGVfZmRfcmVxdWVzdCB3X3JlcTsKCiAgaWYgKCFscERvc1Rhc2spIHJldHVybiBGQUxTRTsKICAvKiBjcmVhdGUgcGlwZXMgKi8KICAvKiB0aGlzIGhhcHBlbnMgaW4gdGhlIHdyb25nIHByb2Nlc3MgY29udGV4dCwgc28gd2UgaGF2ZSB0byBsZXQgdGhlIG5ldyBwcm9jZXNzCiAgICAgaW5oZXJpdCBpdC4uLiAoRklYTUU6IGNhbGwgTVpfSW5pdFRhc2sgaW4gdGhlIHJpZ2h0IHByb2Nlc3MgY29udGV4dCkgKi8KICBpZiAoIUNyZWF0ZVBpcGUoJihscERvc1Rhc2stPmhSZWFkUGlwZSksJihscERvc1Rhc2stPmhYUGlwZSksJmF0dHIsMCkpIHJldHVybiBGQUxTRTsKICBpZiAocGlwZSh3cml0ZV9mZCk8MCkgewogICAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oUmVhZFBpcGUpOwogICAgQ2xvc2VIYW5kbGUobHBEb3NUYXNrLT5oWFBpcGUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICByX3JlcS5oYW5kbGUgPSBscERvc1Rhc2stPmhSZWFkUGlwZTsKICBDTElFTlRfU2VuZFJlcXVlc3QoIFJFUV9HRVRfUkVBRF9GRCwgLTEsIDEsICZyX3JlcSwgc2l6ZW9mKHJfcmVxKSApOwogIENMSUVOVF9XYWl0UmVwbHkoIE5VTEwsICYobHBEb3NUYXNrLT5yZWFkX3BpcGUpLCAwICk7CiAgd19yZXEuaGFuZGxlID0gbHBEb3NUYXNrLT5oWFBpcGU7CiAgQ0xJRU5UX1NlbmRSZXF1ZXN0KCBSRVFfR0VUX1dSSVRFX0ZELCAtMSwgMSwgJndfcmVxLCBzaXplb2Yod19yZXEpICk7CiAgQ0xJRU5UX1dhaXRSZXBseSggTlVMTCwgJnhfZmQsIDAgKTsKCiAgVFJBQ0UobW9kdWxlLCJ3aW4zMiBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZCwgdW5peCBwaXBlOiByZWFkPSVkLCB3cml0ZT0lZFxuIiwKCSAgICAgICBscERvc1Rhc2stPmhSZWFkUGlwZSxscERvc1Rhc2stPmhYUGlwZSxscERvc1Rhc2stPnJlYWRfcGlwZSx4X2ZkKTsKICBUUkFDRShtb2R1bGUsIm91dGJvdW5kIHVuaXggcGlwZTogcmVhZD0lZCwgd3JpdGU9JWQsIHBpZD0lZFxuIix3cml0ZV9mZFswXSx3cml0ZV9mZFsxXSxnZXRwaWQoKSk7CgogIGxwRG9zVGFzay0+d3JpdGVfcGlwZT13cml0ZV9mZFsxXTsKCiAgbHBEb3NUYXNrLT5oQ29uSW5wdXQ9R2V0U3RkSGFuZGxlKFNURF9JTlBVVF9IQU5ETEUpOwogIGxwRG9zVGFzay0+aENvbk91dHB1dD1HZXRTdGRIYW5kbGUoU1REX09VVFBVVF9IQU5ETEUpOwoKICAvKiBpZiB3ZSBoYXZlIGEgbWFwcGluZyBmaWxlLCB1c2UgaXQgKi8KICBmbmFtZT1scERvc1Rhc2stPm1tX25hbWU7IGZhcmc9TlVMTDsKICBpZiAoIWZuYW1lWzBdKSB7CiAgICAvKiBvdGhlcndpc2UsIG1hcCBvdXIgb3duIG1lbW9yeSBpbWFnZSAqLwogICAgc3ByaW50ZihmcHJvYywiL3Byb2MvJWQvbWVtIixnZXRwaWQoKSk7CiAgICBzcHJpbnRmKGFyZywiJWxkIiwodW5zaWduZWQgbG9uZylscERvc1Rhc2stPmltZyk7CiAgICBmbmFtZT1mcHJvYzsgZmFyZz1hcmc7CiAgfQoKICBUUkFDRShtb2R1bGUsIkxvYWRpbmcgRE9TIFZNIHN1cHBvcnQgbW9kdWxlIChobW9kdWxlPSUwNHgpXG4iLGxwRG9zVGFzay0+aE1vZHVsZSk7CiAgaWYgKChjaGlsZD1mb3JrKCkpPDApIHsKICAgIGNsb3NlKHdyaXRlX2ZkWzBdKTsKICAgIGNsb3NlKGxwRG9zVGFzay0+cmVhZF9waXBlKTsKICAgIGNsb3NlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSk7CiAgICBjbG9zZSh4X2ZkKTsKICAgIENsb3NlSGFuZGxlKGxwRG9zVGFzay0+aFJlYWRQaXBlKTsKICAgIENsb3NlSGFuZGxlKGxwRG9zVGFzay0+aFhQaXBlKTsKICAgIHJldHVybiBGQUxTRTsKICB9CiBpZiAoY2hpbGQhPTApIHsKICAvKiBwYXJlbnQgcHJvY2VzcyAqLwogIGludCByZXQ7CgogIGNsb3NlKHdyaXRlX2ZkWzBdKTsKICBjbG9zZSh4X2ZkKTsKICBscERvc1Rhc2stPnRhc2s9Y2hpbGQ7CiAgLyogd2FpdCBmb3IgY2hpbGQgcHJvY2VzcyB0byBzaWduYWwgcmVhZGluZXNzICovCiAgd2hpbGUgKDEpIHsKICAgIGlmIChyZWFkKGxwRG9zVGFzay0+cmVhZF9waXBlLCZyZXQsc2l6ZW9mKHJldCkpPT1zaXplb2YocmV0KSkgYnJlYWs7CiAgICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgY29udGludWU7CiAgICAvKiBmYWlsdXJlICovCiAgICBFUlIobW9kdWxlLCJkb3Ntb2QgaGFzIGZhaWxlZCB0byBpbml0aWFsaXplXG4iKTsKICAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICAvKiB0aGUgY2hpbGQgaGFzIG5vdyBtbWFwZWQgdGhlIHRlbXAgZmlsZSwgaXQncyBub3cgc2FmZSB0byB1bmxpbmsuCiAgICogZG8gaXQgaGVyZSB0byBhdm9pZCBsZWF2aW5nIGEgbWVzcyBpbiAvdG1wIGlmL3doZW4gV2luZSBjcmFzaGVzLi4uICovCiAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgLyogc3RhcnQgc2ltdWxhdGVkIHN5c3RlbSB0aW1lciAqLwogIE1aX0luaXRUaW1lcihscERvc1Rhc2sscmV0KTsKICBpZiAocmV0PDIpIHsKICAgIEVSUihtb2R1bGUsImRvc21vZCB2ZXJzaW9uIHRvbyBvbGQhIFBsZWFzZSBpbnN0YWxsIG5ld2VyIGRvc21vZCBwcm9wZXJseVxuIik7CiAgICBFUlIobW9kdWxlLCJJZiB5b3UgZG9uJ3QsIHRoZSBuZXcgZG9zbW9kIGV2ZW50IGhhbmRsaW5nIHN5c3RlbSB3aWxsIG5vdCB3b3JrXG4iKTsKICB9CiAgLyogYWxsIHN5c3RlbXMgYXJlIG5vdyBnbyAqLwogfSBlbHNlIHsKICAvKiBjaGlsZCBwcm9jZXNzICovCiAgY2xvc2UobHBEb3NUYXNrLT5yZWFkX3BpcGUpOwogIGNsb3NlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSk7CiAgLyogcHV0IG91ciBwaXBlcyBzb21ld2hlcmUgZG9zbW9kIGNhbiBmaW5kIHRoZW0gKi8KICBkdXAyKHdyaXRlX2ZkWzBdLDApOyAvKiBzdGRpbiAqLwogIGR1cDIoeF9mZCwxKTsgICAgICAgIC8qIHN0ZG91dCAqLwogIC8qIGVuYWJsZSBzaWduYWxzICovCiAgU0lHTkFMX01hc2tBc3luY0V2ZW50cyhGQUxTRSk7CiAgLyogbm93IGxvYWQgZG9zbW9kICovCiAgLyogY2hlY2sgYXJndlswXS1kZXJpdmVkIHBhdGhzIGZpcnN0LCBzaW5jZSB0aGUgbmV3ZXN0IGRvc21vZCBpcyBtb3N0IGxpa2VseSB0aGVyZQogICAqIChhdCBsZWFzdCBpdCB3YXMgb25jZSBmb3IgQW5kcmVhcyBNb2hyLCBzbyBJIGRlY2lkZWQgdG8gbWFrZSBpdCBlYXNpZXIgZm9yIGhpbSkgKi8KICBmcGF0aD1zdHJyY2hyKHN0cmNweShwYXRoLE9wdGlvbnMuYXJndjApLCcvJyk7CiAgaWYgKGZwYXRoKSB7CiAgIHN0cmNweShmcGF0aCwiL2Rvc21vZCIpOwogICBleGVjbChwYXRoLGZuYW1lLGZhcmcsTlVMTCk7CiAgIHN0cmNweShmcGF0aCwiL2xvYWRlci9kb3MvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsZm5hbWUsZmFyZyxOVUxMKTsKICB9CiAgLyogb2theSwgaXQgd2Fzbid0IHRoZXJlLCB0cnkgaW4gdGhlIHBhdGggKi8KICBleGVjbHAoImRvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICAvKiBsYXN0IGRlc3BlcmF0ZSBhdHRlbXB0czogY3VycmVudCBkaXJlY3RvcnkgKi8KICBleGVjbCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGFuZCwganVzdCBmb3IgY29tcGxldGVuZXNzLi4uICovCiAgZXhlY2woImxvYWRlci9kb3MvZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGlmIGZhaWx1cmUsIGV4aXQgKi8KICBFUlIobW9kdWxlLCJGYWlsZWQgdG8gc3Bhd24gZG9zbW9kLCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIGV4aXQoMSk7CiB9CiByZXR1cm4gVFJVRTsKfQoKQk9PTCBNWl9DcmVhdGVQcm9jZXNzKCBIRklMRSBoRmlsZSwgT0ZTVFJVQ1QgKm9mcywgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsIAogICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBwc2EsIExQU0VDVVJJVFlfQVRUUklCVVRFUyB0c2EsCiAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBpbmhlcml0LCBEV09SRCBmbGFncywgTFBTVEFSVFVQSU5GT0Egc3RhcnR1cCwgCiAgICAgICAgICAgICAgICAgICAgICAgTFBQUk9DRVNTX0lORk9STUFUSU9OIGluZm8gKQp7CiBMUERPU1RBU0sgbHBEb3NUYXNrID0gTlVMTDsgLyoga2VlcCBnY2MgZnJvbSBjb21wbGFpbmluZyAqLwogSE1PRFVMRTE2IGhNb2R1bGU7CiBQREIgKnBkYiA9IFBST0NFU1NfQ3VycmVudCgpOwogVERCICpwVGFzayA9IChUREIqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogTkVfTU9EVUxFICpwTW9kdWxlID0gcFRhc2sgPyBORV9HZXRQdHIoIHBUYXNrLT5oTW9kdWxlICkgOiBOVUxMOwogaW50IGFsbG9jID0gIShwTW9kdWxlICYmIHBNb2R1bGUtPmRvc19pbWFnZSk7CgogaWYgKGFsbG9jICYmIChscERvc1Rhc2sgPSBjYWxsb2MoMSwgc2l6ZW9mKERPU1RBU0spKSkgPT0gTlVMTCkgewogIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgcmV0dXJuIEZBTFNFOwogfQoKIGlmICgoIWVudikmJnBkYikgZW52ID0gcGRiLT5lbnZfZGItPmVudmlyb247CiBpZiAoYWxsb2MpIHsKICBpZiAoKGhNb2R1bGUgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUob2ZzLCBOVUxMKSkgPCAzMikgewogICBTZXRMYXN0RXJyb3IoaE1vZHVsZSk7CiAgIHJldHVybiBGQUxTRTsKICB9CiAgbHBEb3NUYXNrLT5oTW9kdWxlID0gaE1vZHVsZTsKCiAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoaE1vZHVsZSk7CiAgcE1vZHVsZS0+bHBEb3NUYXNrID0gbHBEb3NUYXNrOwogCiAgbHBEb3NUYXNrLT5pbWc9TlVMTDsgbHBEb3NUYXNrLT5tbV9uYW1lWzBdPTA7IGxwRG9zVGFzay0+bW1fZmQ9LTE7CiB9IGVsc2UgbHBEb3NUYXNrPXBNb2R1bGUtPmxwRG9zVGFzazsKIGlmICghTVpfTG9hZEltYWdlKCBoRmlsZSwgb2ZzLCBjbWRsaW5lLCBlbnYsIGxwRG9zVGFzaywgcE1vZHVsZSApKSB7CiAgaWYgKGFsbG9jKSB7CiAgIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICAgIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgbXVubWFwKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLVNUQVJUX09GRlNFVCk7CiAgICBpZiAobHBEb3NUYXNrLT5tbV9mZD49MCkgY2xvc2UobHBEb3NUYXNrLT5tbV9mZCk7CiAgICB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKICAgfSBlbHNlCiAgICBpZiAobHBEb3NUYXNrLT5pbWchPU5VTEwpIFZpcnR1YWxGcmVlKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLE1FTV9SRUxFQVNFKTsKICB9CiAgcmV0dXJuIEZBTFNFOwogfQogaWYgKGFsbG9jKSB7CiAgcE1vZHVsZS0+ZG9zX2ltYWdlID0gbHBEb3NUYXNrLT5pbWc7CiAgaWYgKCFNWl9Jbml0VGFzayggbHBEb3NUYXNrICkpIHsKICAgTVpfS2lsbE1vZHVsZSggbHBEb3NUYXNrICk7CiAgIC8qIEZJWE1FOiBjbGVhbnVwIGhNb2R1bGUgKi8KICAgU2V0TGFzdEVycm9yKEVSUk9SX0dFTl9GQUlMVVJFKTsKICAgcmV0dXJuIEZBTFNFOwogIH0KICBpbmhlcml0ID0gVFJVRTsgLyogYmFkIGhhY2sgZm9yIGluaGVyaXRpbmcgdGhlIENyZWF0ZVBpcGUuLi4gKi8KICBpZiAoIVBST0NFU1NfQ3JlYXRlKCBwTW9kdWxlLCBjbWRsaW5lLCBlbnYsIDAsIDAsIAogICAgICAgICAgICAgICAgICAgICAgIHBzYSwgdHNhLCBpbmhlcml0LCBmbGFncywgc3RhcnR1cCwgaW5mbyApKQogICByZXR1cm4gRkFMU0U7CiB9CiByZXR1cm4gVFJVRTsKfQoKdm9pZCBNWl9LaWxsTW9kdWxlKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogIERPU0VWRU5UICpldmVudCwqcF9ldmVudDsKICBET1NTWVNURU0gKnN5cywqcF9zeXM7CgogIFRSQUNFKG1vZHVsZSwia2lsbGluZyBET1MgdGFza1xuIik7CiAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgewogICAgbXVubWFwKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLVNUQVJUX09GRlNFVCk7CiAgICBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKICB9IGVsc2UgVmlydHVhbEZyZWUobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAsTUVNX1JFTEVBU0UpOwogIGNsb3NlKGxwRG9zVGFzay0+cmVhZF9waXBlKTsKICBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwogIENsb3NlSGFuZGxlKGxwRG9zVGFzay0+aFJlYWRQaXBlKTsKICBDbG9zZUhhbmRsZShscERvc1Rhc2stPmhYUGlwZSk7CiAga2lsbChscERvc1Rhc2stPnRhc2ssU0lHVEVSTSk7Ci8qIGZyZWUgbWVtb3J5IGFsbG9jYXRlZCBmb3IgZXZlbnRzIGFuZCBzeXN0ZW1zICovCiNkZWZpbmUgREZSRUUodmFyLHB2YXIsc3ZhcikgXAogIHZhciA9IGxwRG9zVGFzay0+c3ZhcjsgXAogIHdoaWxlICh2YXIpIHsgXAogICAgaWYgKHZhci0+ZGF0YSkgZnJlZSh2YXItPmRhdGEpOyBcCiAgICBwdmFyID0gdmFyLT5uZXh0OyBmcmVlKHZhcik7IHZhciA9IHB2YXI7IFwKICB9CgogIERGUkVFKGV2ZW50LHBfZXZlbnQscGVuZGluZykKICBERlJFRShldmVudCxwX2V2ZW50LGN1cnJlbnQpCiAgREZSRUUoc3lzLHBfc3lzLHN5cykKCiN1bmRlZiBERlJFRQoKI2lmIDAKICAvKiBGSVhNRTogdGhpcyBzZWVtcyB0byBjcmFzaCAqLwogIGlmIChscERvc1Rhc2stPmRwbWlfc2VsKQogICAgU0VMRUNUT1JfRnJlZUJsb2NrKGxwRG9zVGFzay0+ZHBtaV9zZWwsIDEpOwojZW5kaWYKfQoKTFBET1NUQVNLIE1aX0N1cnJlbnQoIHZvaWQgKQp7CiAgVERCICpwVGFzayA9IChUREIgKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKICBORV9NT0RVTEUgKnBNb2R1bGUgPSBwVGFzayA/IE5FX0dldFB0ciggcFRhc2stPmhNb2R1bGUgKSA6IE5VTEw7CgogIEdsb2JhbFVubG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CgogIGlmIChwTW9kdWxlKQogICAgcmV0dXJuIHBNb2R1bGUtPmxwRG9zVGFzazsKCiAgcmV0dXJuIE5VTEw7Cn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCkJPT0wgTVpfQ3JlYXRlUHJvY2VzcyggSEZJTEUgaEZpbGUsIE9GU1RSVUNUICpvZnMsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LAogICAgICAgICAgICAgICAgICAgICAgIExQU0VDVVJJVFlfQVRUUklCVVRFUyBwc2EsIExQU0VDVVJJVFlfQVRUUklCVVRFUyB0c2EsCiAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBpbmhlcml0LCBEV09SRCBmbGFncywgTFBTVEFSVFVQSU5GT0Egc3RhcnR1cCwKICAgICAgICAgICAgICAgICAgICAgICBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKIFdBUk4obW9kdWxlLCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZVxuIik7CiBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiByZXR1cm4gRkFMU0U7Cn0KCkxQRE9TVEFTSyBNWl9DdXJyZW50KCB2b2lkICkKewogIHJldHVybiBOVUxMOwp9CgojZW5kaWYK