LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzZWxlY3RvcnMuaCIKI2luY2x1ZGUgImZpbGUuaCIKI2luY2x1ZGUgImxkdC5oIgojaW5jbHVkZSAicHJvY2Vzcy5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zbW9kLmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCgojaWZkZWYgTVpfU1VQUE9SVEVECgojaW5jbHVkZSA8c3lzL21tYW4uaD4KCi8qIGRlZmluZSB0aGlzIHRvIHRyeSBtYXBwaW5nIHRocm91Z2ggL3Byb2MvcGlkL21lbSBpbnN0ZWFkIG9mIGEgdGVtcCBmaWxlLAogICBidXQgTGludXMgZG9lc24ndCBsaWtlIG1tYXBwaW5nIC9wcm9jL3BpZC9tZW0sIHNvIGl0IGRvZXNuJ3Qgd29yayBmb3IgbWUgKi8KI3VuZGVmIE1aX01BUFNFTEYKCiNkZWZpbmUgQklPU19EQVRBX1NFR01FTlQgMHg0MAojZGVmaW5lIFNUQVJUX09GRlNFVCAwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKc3RhdGljIHZvaWQgTVpfSW5pdFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSwgV09SRCBlbnYgKQp7CiBQREIqcHNwPWxwUFNQOwogY29uc3QgY2hhcipjbWQ9Y21kbGluZT9zdHJjaHIoY21kbGluZSwnICcpOk5VTEw7CgogcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogLyogc29tZSBwcm9ncmFtcyB1c2UgdGhpcyB0byBjYWxjdWxhdGUgaG93IG11Y2ggbWVtb3J5IHRoZXkgbmVlZCAqLwogcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsKIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogLyogY29weSBwYXJhbWV0ZXJzICovCiBpZiAoY21kKSB7CiNpZiAwCiAgLyogY29tbWFuZC5jb20gZG9lc24ndCBkbyB0aGlzICovCiAgd2hpbGUgKCpjbWQgPT0gJyAnKSBjbWQrKzsKI2VuZGlmCiAgcHNwLT5jbWRMaW5lWzBdPXN0cmxlbihjbWQpOwogIHN0cmNweShwc3AtPmNtZExpbmUrMSxjbWQpOwogIHBzcC0+Y21kTGluZVtwc3AtPmNtZExpbmVbMF0rMV09J1xyJzsKIH0gZWxzZSBwc3AtPmNtZExpbmVbMV09J1xyJzsKIC8qIEZJWE1FOiBpbnRlZ3JhdGUgdGhlIG1lbW9yeSBzdHVmZiBmcm9tIFdpbmUgKG1zZG9zL2Rvc21lbS5jKSAqLwogLyogRklYTUU6IGludGVncmF0ZSB0aGUgUERCIHN0dWZmIGZyb20gV2luZSAobG9hZGVyL3Rhc2suYykgKi8KfQoKLyogZGVmYXVsdCBJTlQgMDggaGFuZGxlcjogaW5jcmVhc2VzIHRpbWVyIHRpY2sgY291bnRlciBidXQgbm90IG11Y2ggbW9yZSAqLwpzdGF0aWMgY2hhciBpbnQwOFtdPXsKIDB4Q0QsMHgxQywgICAgICAgICAgIC8qIGludCAkMHgxYyAqLwogMHg1MCwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWF4ICovCiAweDFFLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlZHMgKi8KIDB4QjgsMHg0MCwweDAwLCAgICAgIC8qIG1vdncgJDB4NDAsJWF4ICovCiAweDhFLDB4RDgsICAgICAgICAgICAvKiBtb3Z3ICVheCwlZHMgKi8KI2lmIDAKIDB4ODMsMHgwNiwweDZDLDB4MDAsMHgwMSwgLyogYWRkdyAkMSwoMHg2YykgKi8KIDB4ODMsMHgxNiwweDZFLDB4MDAsMHgwMCwgLyogYWRjdyAkMCwoMHg2ZSkgKi8KI2Vsc2UKIDB4NjYsMHhGRiwweDA2LDB4NkMsMHgwMCwgLyogaW5jbCAoMHg2YykgKi8KI2VuZGlmCiAweEIwLDB4MjAsICAgICAgICAgICAvKiBtb3ZiICQweDIwLCVhbCAqLwogMHhFNiwweDIwLCAgICAgICAgICAgLyogb3V0YiAlYWwsJDB4MjAgKi8KIDB4MUYsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweDU4LCAgICAgICAgICAgICAgICAvKiBwb3B3ICVheCAqLwogMHhDRiAgICAgICAgICAgICAgICAgLyogaXJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdEhhbmRsZXJzKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogV09SRCBzZWc7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxzaXplb2YoaW50MDgpLCZzZWcpOwogbWVtY3B5KHN0YXJ0LGludDA4LHNpemVvZihpbnQwOCkpOwovKiBJTlQgMDg6IHBvaW50IGl0IGF0IG91ciB0aWNrLWluY3JlbWVudGluZyBoYW5kbGVyICovCiAoKFNFR1BUUiopKGxwRG9zVGFzay0+aW1nKSlbMHgwOF09UFRSX1NFR19PRkZfVE9fU0VHUFRSKHNlZywwKTsKLyogSU5UIDFDOiBqdXN0IHBvaW50IGl0IHRvIElSRVQsIHdlIGRvbid0IHdhbnQgdG8gaGFuZGxlIGl0IG91cnNlbHZlcyAqLwogKChTRUdQVFIqKShscERvc1Rhc2stPmltZykpWzB4MUNdPVBUUl9TRUdfT0ZGX1RPX1NFR1BUUihzZWcsc2l6ZW9mKGludDA4KS0xKTsKfQoKc3RhdGljIGNoYXIgZW50ZXJfeG1zW109ewovKiBYTVMgaG9va2FibGUgZW50cnkgcG9pbnQgKi8KIDB4RUIsMHgwMywgICAgICAgICAgIC8qIGptcCBlbnRyeSAqLwogMHg5MCwweDkwLDB4OTAsICAgICAgLyogbm9wO25vcDtub3AgKi8KICAgICAgICAgICAgICAgICAgICAgIC8qIGVudHJ5OiAqLwovKiByZWFsIGVudHJ5IHBvaW50ICovCi8qIGZvciBzaW1wbGljaXR5LCB3ZSdsbCBqdXN0IHVzZSB0aGUgc2FtZSBob29rIGFzIERQTUkgYmVsb3cgKi8KIDB4Q0QsMHgzMSwgICAgICAgICAgIC8qIGludCAkMHgzMSAqLwogMHhDQiAgICAgICAgICAgICAgICAgLyogbHJldCAqLwp9OwoKc3RhdGljIHZvaWQgTVpfSW5pdFhNUyggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemVvZihlbnRlcl94bXMpLCYobHBEb3NUYXNrLT54bXNfc2VnKSk7CiBtZW1jcHkoc3RhcnQsZW50ZXJfeG1zLHNpemVvZihlbnRlcl94bXMpKTsKfQoKc3RhdGljIGNoYXIgZW50ZXJfcG1bXT17CiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4NTIsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkeCAqLwogMHg1NSwgICAgICAgICAgICAgICAgLyogcHVzaHcgJWJwICovCiAweDg5LDB4RTUsICAgICAgICAgICAvKiBtb3Z3ICVzcCwlYnAgKi8KLyogZ2V0IHJldHVybiBDUyAqLwogMHg4QiwweDU2LDB4MDgsICAgICAgLyogbW92dyA4KCVicCksJWR4ICovCi8qIGp1c3QgY2FsbCBpbnQgMzEgaGVyZSB0byBnZXQgaW50byBwcm90ZWN0ZWQgbW9kZS4uLiAqLwovKiBpdCdsbCBjaGVjayB3aGV0aGVyIGl0IHdhcyBjYWxsZWQgZnJvbSBkcG1pX3NlZy4uLiAqLwogMHhDRCwweDMxLCAgICAgICAgICAgLyogaW50ICQweDMxICovCi8qIHdlIGFyZSBub3cgaW4gdGhlIGNvbnRleHQgb2YgYSAxNi1iaXQgcmVsYXkgY2FsbCAqLwovKiBuZWVkIHRvIGZpeHVwIG91ciBzdGFjazsKICogMTYtYml0IHJlbGF5IHJldHVybiBhZGRyZXNzIHdpbGwgYmUgbG9zdCwgYnV0IHdlIHdvbid0IHdvcnJ5IHF1aXRlIHlldCAqLwogMHg4RSwweEQwLCAgICAgICAgICAgLyogbW92dyAlYXgsJXNzICovCiAweDY2LDB4MEYsMHhCNywweEU1LCAvKiBtb3Z6d2wgJWJwLCVlc3AgKi8KLyogc2V0IHJldHVybiBDUyAqLwogMHg4OSwweDU2LDB4MDgsICAgICAgLyogbW92dyAlZHgsOCglYnApICovCiAweDVELCAgICAgICAgICAgICAgICAvKiBwb3B3ICVicCAqLwogMHg1QSwgICAgICAgICAgICAgICAgLyogcG9wdyAlZHggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENCICAgICAgICAgICAgICAgICAvKiBscmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0RFBNSSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIHVuc2lnbmVkIHNpemU9c2l6ZW9mKGVudGVyX3BtKTsKIExQQllURSBzdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLHNpemUsJihscERvc1Rhc2stPmRwbWlfc2VnKSk7CiAKIGxwRG9zVGFzay0+ZHBtaV9zZWwgPSBTRUxFQ1RPUl9BbGxvY0Jsb2NrKCBzdGFydCwgc2l6ZSwgU0VHTUVOVF9DT0RFLCBGQUxTRSwgRkFMU0UgKTsKCiBtZW1jcHkoc3RhcnQsZW50ZXJfcG0sc2l6ZW9mKGVudGVyX3BtKSk7Cn0KCnN0YXRpYyBXT1JEIE1aX0luaXRFbnZpcm9ubWVudCggTFBET1NUQVNLIGxwRG9zVGFzaywgTFBDU1RSIGVudiwgTFBDU1RSIG5hbWUgKQp7CiB1bnNpZ25lZCBzej0wOwogV09SRCBzZWc7CiBMUFNUUiBlbnZibGs7CgogaWYgKGVudikgewogIC8qIGdldCBzaXplIG9mIGVudmlyb25tZW50IGJsb2NrICovCiAgd2hpbGUgKGVudltzeisrXSkgc3orPXN0cmxlbihlbnYrc3opKzE7CiB9IGVsc2Ugc3orKzsKIC8qIGFsbG9jYXRlIGl0ICovCiBlbnZibGs9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxzeitzaXplb2YoV09SRCkrc3RybGVuKG5hbWUpKzEsJnNlZyk7CiAvKiBmaWxsIGl0ICovCiBpZiAoZW52KSB7CiAgbWVtY3B5KGVudmJsayxlbnYsc3opOwogfSBlbHNlIGVudmJsa1swXT0wOwogLyogRE9TIDMueDogdGhlIGJsb2NrIGNvbnRhaW5zIDEgYWRkaXRpb25hbCBzdHJpbmcgKi8KICooV09SRCopKGVudmJsaytzeik9MTsKIC8qIGJlaW5nIHRoZSBwcm9ncmFtIG5hbWUgaXRzZWxmICovCiBzdHJjcHkoZW52YmxrK3N6K3NpemVvZihXT1JEKSxuYW1lKTsKIHJldHVybiBzZWc7Cn0KCmludCBNWl9Jbml0TWVtb3J5KCBMUERPU1RBU0sgbHBEb3NUYXNrLCBORV9NT0RVTEUgKnBNb2R1bGUgKQp7CiBpbnQgeDsKCiBpZiAobHBEb3NUYXNrLT5pbWdfb2ZzKSByZXR1cm4gMzI7IC8qIGFscmVhZHkgYWxsb2NhdGVkICovCgogLyogYWxsb2NhdGUgMU1CKzY0SyBzaGFyZWQgbWVtb3J5ICovCiBscERvc1Rhc2stPmltZ19vZnM9U1RBUlRfT0ZGU0VUOwojaWZkZWYgTVpfTUFQU0VMRgogbHBEb3NUYXNrLT5pbWc9VmlydHVhbEFsbG9jKE5VTEwsMHgxMTAwMDAsTUVNX0NPTU1JVCxQQUdFX1JFQURXUklURSk7CiAvKiBtYWtlIHN1cmUgbW1hcCBhY2NlcHRzIGl0ICovCiAoKGNoYXIqKWxwRG9zVGFzay0+aW1nKVsweDEwRkZGRl09MDsKI2Vsc2UKIHRtcG5hbShscERvc1Rhc2stPm1tX25hbWUpOwovKiBzdHJjcHkobHBEb3NUYXNrLT5tbV9uYW1lLCIvdG1wL215ZG9zaW1hZ2UiKTsgKi8KIGxwRG9zVGFzay0+bW1fZmQ9b3BlbihscERvc1Rhc2stPm1tX25hbWUsT19SRFdSfE9fQ1JFQVQgLyogfE9fVFJVTkMgKi8sU19JUlVTUnxTX0lXVVNSKTsKIGlmIChscERvc1Rhc2stPm1tX2ZkPDApIEVSUihtb2R1bGUsImZpbGUgJXMgY291bGQgbm90IGJlIG9wZW5lZFxuIixscERvc1Rhc2stPm1tX25hbWUpOwogLyogZXhwYW5kIGZpbGUgdG8gMU1CKzY0SyAqLwogbHNlZWsobHBEb3NUYXNrLT5tbV9mZCwweDExMDAwMC0xLFNFRUtfU0VUKTsKIHg9MDsgd3JpdGUobHBEb3NUYXNrLT5tbV9mZCwmeCwxKTsKIC8qIG1hcCBpdCBpbiAqLwogbHBEb3NUYXNrLT5pbWc9bW1hcChOVUxMLDB4MTEwMDAwLVNUQVJUX09GRlNFVCxQUk9UX1JFQUR8UFJPVF9XUklURSxNQVBfU0hBUkVELGxwRG9zVGFzay0+bW1fZmQsMCk7CiNlbmRpZgogaWYgKGxwRG9zVGFzay0+aW1nPT0oTFBWT0lEKS0xKSB7CiAgRVJSKG1vZHVsZSwiY291bGQgbm90IG1hcCBzaGFyZWQgbWVtb3J5LCBlcnJvcj0lc1xuIixzdHJlcnJvcihlcnJubykpOwogIHJldHVybiAwOwogfQogVFJBQ0UobW9kdWxlLCJET1MgVk04NiBpbWFnZSBtYXBwZWQgYXQgJTA4bHhcbiIsKERXT1JEKWxwRG9zVGFzay0+aW1nKTsKIHBNb2R1bGUtPmRvc19pbWFnZT1scERvc1Rhc2stPmltZzsKCiAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KIFRSQUNFKG1vZHVsZSwiSW5pdGlhbGl6aW5nIERPUyBtZW1vcnkgc3RydWN0dXJlc1xuIik7CiBET1NNRU1fSW5pdChscERvc1Rhc2stPmhNb2R1bGUpOwogTVpfSW5pdEhhbmRsZXJzKGxwRG9zVGFzayk7CiBNWl9Jbml0WE1TKGxwRG9zVGFzayk7CiBNWl9Jbml0RFBNSShscERvc1Rhc2spOwogcmV0dXJuIGxwRG9zVGFzay0+aE1vZHVsZTsKfQoKc3RhdGljIGludCBNWl9Mb2FkSW1hZ2UoIEhGSUxFMTYgaEZpbGUsIExQQ1NUUiBuYW1lLCBMUENTVFIgY21kbGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBlbnYsIExQRE9TVEFTSyBscERvc1Rhc2ssIE5FX01PRFVMRSAqcE1vZHVsZSApCnsKIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogRFdPUkQgaW1hZ2Vfc3RhcnQsaW1hZ2Vfc2l6ZSxtaW5fc2l6ZSxtYXhfc2l6ZSxhdmFpbDsKIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0OwogaW50IHgsb2xkX2NvbT0wOwogU0VHUFRSIHJlbG9jOwogV09SRCBlbnZfc2VnOwoKIGlmICgoX2hyZWFkMTYoaEZpbGUsJm16X2hlYWRlcixzaXplb2YobXpfaGVhZGVyKSkgIT0gc2l6ZW9mKG16X2hlYWRlcikpIHx8CiAgICAgKG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpKSB7CiNpZiAwCiAgICAgcmV0dXJuIDExOyAvKiBpbnZhbGlkIGV4ZSAqLwojZW5kaWYKICBvbGRfY29tPTE7IC8qIGFzc3VtZSAuQ09NIGZpbGUgKi8KICBpbWFnZV9zdGFydD0wOwogIGltYWdlX3NpemU9R2V0RmlsZVNpemUoSEZJTEUxNl9UT19IRklMRTMyKGhGaWxlKSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKIE1aX0luaXRNZW1vcnkobHBEb3NUYXNrLHBNb2R1bGUpOwoKIC8qIGFsbG9jYXRlIGVudmlyb25tZW50IGJsb2NrICovCiBlbnZfc2VnPU1aX0luaXRFbnZpcm9ubWVudChscERvc1Rhc2ssZW52LG5hbWUpOwoKIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KIFRSQUNFKG1vZHVsZSwiQWxsb2NhdGluZyBET1MgbWVtb3J5IChtaW49JWxkLCBtYXg9JWxkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKGxwRG9zVGFzay0+aE1vZHVsZSk7CiBpZiAoYXZhaWw8bWluX3NpemUpIHsKICBFUlIobW9kdWxlLCAiaW5zdWZmaWNpZW50IERPUyBtZW1vcnlcbiIpOwogIHJldHVybiAwOwogfQogaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKIHBzcF9zdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLGF2YWlsLCZscERvc1Rhc2stPnBzcF9zZWcpOwogaWYgKCFwc3Bfc3RhcnQpIHsKICBFUlIobW9kdWxlLCAiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICByZXR1cm4gMDsKIH0KIGxwRG9zVGFzay0+bG9hZF9zZWc9bHBEb3NUYXNrLT5wc3Bfc2VnKyhvbGRfY29tPzA6UFNQX1NJWkUpOwogbG9hZF9zdGFydD1wc3Bfc3RhcnQrKFBTUF9TSVpFPDw0KTsKIE1aX0luaXRQU1AocHNwX3N0YXJ0LCBjbWRsaW5lLCBlbnZfc2VnKTsKCiAvKiBsb2FkIGV4ZWN1dGFibGUgaW1hZ2UgKi8KIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBfbGxzZWVrMTYoaEZpbGUsaW1hZ2Vfc3RhcnQsRklMRV9CRUdJTik7CiBpZiAoKF9ocmVhZDE2KGhGaWxlLGxvYWRfc3RhcnQsaW1hZ2Vfc2l6ZSkpICE9IGltYWdlX3NpemUpCiAgcmV0dXJuIDExOyAvKiBpbnZhbGlkIGV4ZSAqLwoKIGlmIChtel9oZWFkZXIuZV9jcmxjKSB7CiAgLyogbG9hZCByZWxvY2F0aW9uIHRhYmxlICovCiAgVFJBQ0UobW9kdWxlLCJsb2FkaW5nIERPUyBFWEUgcmVsb2NhdGlvbiB0YWJsZSwgJWQgZW50cmllc1xuIixtel9oZWFkZXIuZV9jcmxjKTsKICAvKiBGSVhNRTogaXMgdGhpcyB0b28gc2xvdyB3aXRob3V0IHJlYWQgYnVmZmVyaW5nPyAqLwogIF9sbHNlZWsxNihoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsRklMRV9CRUdJTik7CiAgZm9yICh4PTA7IHg8bXpfaGVhZGVyLmVfY3JsYzsgeCsrKSB7CiAgIGlmIChfbHJlYWQxNihoRmlsZSwmcmVsb2Msc2l6ZW9mKHJlbG9jKSkgIT0gc2l6ZW9mKHJlbG9jKSkKICAgIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KICAgKihXT1JEKilTRUdQVFIxNihsb2FkX3N0YXJ0LHJlbG9jKSs9bHBEb3NUYXNrLT5sb2FkX3NlZzsKICB9CiB9CgogbHBEb3NUYXNrLT5pbml0X2NzPWxwRG9zVGFzay0+bG9hZF9zZWcrbXpfaGVhZGVyLmVfY3M7CiBscERvc1Rhc2stPmluaXRfaXA9bXpfaGVhZGVyLmVfaXA7CiBscERvc1Rhc2stPmluaXRfc3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9zczsKIGxwRG9zVGFzay0+aW5pdF9zcD1tel9oZWFkZXIuZV9zcDsKCiBUUkFDRShtb2R1bGUsImVudHJ5IHBvaW50OiAlMDR4OiUwNHhcbiIsbHBEb3NUYXNrLT5pbml0X2NzLGxwRG9zVGFzay0+aW5pdF9pcCk7CgogcmV0dXJuIGxwRG9zVGFzay0+aE1vZHVsZTsKfQoKTFBET1NUQVNLIE1aX0FsbG9jRFBNSVRhc2soIEhNT0RVTEUxNiBoTW9kdWxlICkKewogTFBET1NUQVNLIGxwRG9zVGFzayA9IGNhbGxvYygxLCBzaXplb2YoRE9TVEFTSykpOwogTkVfTU9EVUxFICpwTW9kdWxlOwoKIGlmIChscERvc1Rhc2spIHsKICBscERvc1Rhc2stPmhNb2R1bGUgPSBoTW9kdWxlOwoKICBwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNihoTW9kdWxlKTsKICBwTW9kdWxlLT5scERvc1Rhc2sgPSBscERvc1Rhc2s7CiAKICBscERvc1Rhc2stPmltZz1OVUxMOyBscERvc1Rhc2stPm1tX25hbWVbMF09MDsgbHBEb3NUYXNrLT5tbV9mZD0tMTsKCiAgTVpfSW5pdE1lbW9yeShscERvc1Rhc2ssIHBNb2R1bGUpOwoKICBHbG9iYWxVbmxvY2sxNihoTW9kdWxlKTsKIH0KIHJldHVybiBscERvc1Rhc2s7Cn0KCnN0YXRpYyB2b2lkIE1aX0luaXRUaW1lciggTFBET1NUQVNLIGxwRG9zVGFzaywgaW50IHZlciApCnsKIGlmICh2ZXI8MSkgewojaWYgMAogIC8qIHN0YXJ0IHNpbXVsYXRlZCBzeXN0ZW0gNTVIeiB0aW1lciAqLwogIGxwRG9zVGFzay0+c3lzdGVtX3RpbWVyID0gQ3JlYXRlU3lzdGVtVGltZXIoIDU1LCBNWl9UaWNrICk7CiAgVFJBQ0UobW9kdWxlLCJjcmVhdGVkIDU1SHogdGltZXIgdGljaywgaGFuZGxlPSVkXG4iLGxwRG9zVGFzay0+c3lzdGVtX3RpbWVyKTsKI2VuZGlmCiB9IGVsc2UgewogIGludCBmdW5jOwogIHN0cnVjdCB0aW1ldmFsIHRpbTsKCiAgLyogc3RhcnQgZG9zbW9kIHRpbWVyIGF0IDU1SHogKi8KICBmdW5jPURPU01PRF9TRVRfVElNRVI7CiAgdGltLnR2X3NlYz0wOyB0aW0udHZfdXNlYz01NDkyNTsKICB3cml0ZShscERvc1Rhc2stPndyaXRlX3BpcGUsJmZ1bmMsc2l6ZW9mKGZ1bmMpKTsKICB3cml0ZShscERvc1Rhc2stPndyaXRlX3BpcGUsJnRpbSxzaXplb2YodGltKSk7CiB9Cn0KCmludCBNWl9Jbml0VGFzayggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIGludCByZWFkX2ZkWzJdLHdyaXRlX2ZkWzJdOwogcGlkX3QgY2hpbGQ7CiBjaGFyICpmbmFtZSwqZmFyZyxhcmdbMTZdLGZwcm9jWzY0XSxwYXRoWzI1Nl0sKmZwYXRoOwoKIGlmICghbHBEb3NUYXNrKSByZXR1cm4gMDsKIC8qIGNyZWF0ZSByZWFkIHBpcGUgKi8KIGlmIChwaXBlKHJlYWRfZmQpPDApIHJldHVybiAwOwogaWYgKHBpcGUod3JpdGVfZmQpPDApIHsKICBjbG9zZShyZWFkX2ZkWzBdKTsgY2xvc2UocmVhZF9mZFsxXSk7IHJldHVybiAwOwogfQogbHBEb3NUYXNrLT5yZWFkX3BpcGU9cmVhZF9mZFswXTsKIGxwRG9zVGFzay0+d3JpdGVfcGlwZT13cml0ZV9mZFsxXTsKIC8qIGlmIHdlIGhhdmUgYSBtYXBwaW5nIGZpbGUsIHVzZSBpdCAqLwogZm5hbWU9bHBEb3NUYXNrLT5tbV9uYW1lOyBmYXJnPU5VTEw7CiBpZiAoIWZuYW1lWzBdKSB7CiAgLyogb3RoZXJ3aXNlLCBtYXAgb3VyIG93biBtZW1vcnkgaW1hZ2UgKi8KICBzcHJpbnRmKGZwcm9jLCIvcHJvYy8lZC9tZW0iLGdldHBpZCgpKTsKICBzcHJpbnRmKGFyZywiJWxkIiwodW5zaWduZWQgbG9uZylscERvc1Rhc2stPmltZyk7CiAgZm5hbWU9ZnByb2M7IGZhcmc9YXJnOwogfQoKIFRSQUNFKG1vZHVsZSwiTG9hZGluZyBET1MgVk0gc3VwcG9ydCBtb2R1bGUgKGhtb2R1bGU9JTA0eClcbiIsbHBEb3NUYXNrLT5oTW9kdWxlKTsKIGlmICgoY2hpbGQ9Zm9yaygpKTwwKSB7CiAgY2xvc2Uod3JpdGVfZmRbMF0pOyBjbG9zZSh3cml0ZV9mZFsxXSk7CiAgY2xvc2UocmVhZF9mZFswXSk7IGNsb3NlKHJlYWRfZmRbMV0pOyByZXR1cm4gMDsKIH0KIGlmIChjaGlsZCE9MCkgewogIC8qIHBhcmVudCBwcm9jZXNzICovCiAgaW50IHJldDsKCiAgY2xvc2UocmVhZF9mZFsxXSk7IGNsb3NlKHdyaXRlX2ZkWzBdKTsKICBscERvc1Rhc2stPnRhc2s9Y2hpbGQ7CiAgLyogd2FpdCBmb3IgY2hpbGQgcHJvY2VzcyB0byBzaWduYWwgcmVhZGluZXNzICovCiAgZG8gewogICBpZiAocmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmcmV0LHNpemVvZihyZXQpKSE9c2l6ZW9mKHJldCkpIHsKICAgIGlmICgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSBjb250aW51ZTsKICAgIC8qIGZhaWx1cmUgKi8KICAgIEVSUihtb2R1bGUsImRvc21vZCBoYXMgZmFpbGVkIHRvIGluaXRpYWxpemVcbiIpOwogICAgaWYgKGxwRG9zVGFzay0+bW1fbmFtZVswXSE9MCkgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgICByZXR1cm4gMDsKICAgfQogIH0gd2hpbGUgKDApOwogIC8qIHRoZSBjaGlsZCBoYXMgbm93IG1tYXBlZCB0aGUgdGVtcCBmaWxlLCBpdCdzIG5vdyBzYWZlIHRvIHVubGluay4KICAgKiBkbyBpdCBoZXJlIHRvIGF2b2lkIGxlYXZpbmcgYSBtZXNzIGluIC90bXAgaWYvd2hlbiBXaW5lIGNyYXNoZXMuLi4gKi8KICBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKICAvKiBzdGFydCBzaW11bGF0ZWQgc3lzdGVtIHRpbWVyICovCiAgTVpfSW5pdFRpbWVyKGxwRG9zVGFzayxyZXQpOwogIC8qIGFsbCBzeXN0ZW1zIGFyZSBub3cgZ28gKi8KIH0gZWxzZSB7CiAgLyogY2hpbGQgcHJvY2VzcyAqLwogIGNsb3NlKHJlYWRfZmRbMF0pOyBjbG9zZSh3cml0ZV9mZFsxXSk7CiAgLyogcHV0IG91ciBwaXBlcyBzb21ld2hlcmUgZG9zbW9kIGNhbiBmaW5kIHRoZW0gKi8KICBkdXAyKHdyaXRlX2ZkWzBdLDApOyAgICAgIC8qIHN0ZGluICovCiAgZHVwMihyZWFkX2ZkWzFdLDEpOyAgICAgICAvKiBzdGRvdXQgKi8KICAvKiBlbmFibGUgc2lnbmFscyAqLwogIFNJR05BTF9NYXNrQXN5bmNFdmVudHMoRkFMU0UpOwogIC8qIG5vdyBsb2FkIGRvc21vZCAqLwogIGV4ZWNscCgiZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIGV4ZWNsKCJkb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogaG1tLCB0aGV5IGRpZG4ndCBpbnN0YWxsIHByb3Blcmx5ICovCiAgZXhlY2woImxvYWRlci9kb3MvZG9zbW9kIixmbmFtZSxmYXJnLE5VTEwpOwogIC8qIGxhc3QgcmVzb3J0LCB0cnkgdG8gZmluZCBpdCB0aHJvdWdoIGFyZ3ZbMF0gKi8KICBmcGF0aD1zdHJyY2hyKHN0cmNweShwYXRoLE9wdGlvbnMuYXJndjApLCcvJyk7CiAgaWYgKGZwYXRoKSB7CiAgIHN0cmNweShmcGF0aCwiL2xvYWRlci9kb3MvZG9zbW9kIik7CiAgIGV4ZWNsKHBhdGgsZm5hbWUsZmFyZyxOVUxMKTsKICB9CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUihtb2R1bGUsIkZhaWxlZCB0byBzcGF3biBkb3Ntb2QsIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgZXhpdCgxKTsKIH0KIHJldHVybiBscERvc1Rhc2stPmhNb2R1bGU7Cn0KCkhJTlNUQU5DRTE2IE1aX0NyZWF0ZVByb2Nlc3MoIExQQ1NUUiBuYW1lLCBMUENTVFIgY21kbGluZSwgTFBDU1RSIGVudiwgQk9PTDMyIGluaGVyaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RBUlRVUElORk8zMkEgc3RhcnR1cCwgTFBQUk9DRVNTX0lORk9STUFUSU9OIGluZm8gKQp7CiBMUERPU1RBU0sgbHBEb3NUYXNrID0gTlVMTDsgLyoga2VlcCBnY2MgZnJvbSBjb21wbGFpbmluZyAqLwogSE1PRFVMRTE2IGhNb2R1bGU7CiBISU5TVEFOQ0UxNiBoSW5zdGFuY2U7CiBQREIzMiAqcGRiID0gUFJPQ0VTU19DdXJyZW50KCk7CiBUREIgKnBUYXNrID0gKFREQiopR2xvYmFsTG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiBORV9NT0RVTEUgKnBNb2R1bGUgPSBwVGFzayA/IE5FX0dldFB0ciggcFRhc2stPmhNb2R1bGUgKSA6IE5VTEw7CiBIRklMRTE2IGhGaWxlOwogT0ZTVFJVQ1Qgb2ZzOwogaW50IGVyciwgYWxsb2MgPSAhKHBNb2R1bGUgJiYgcE1vZHVsZS0+ZG9zX2ltYWdlKTsKCiBHbG9iYWxVbmxvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwoKIGlmIChhbGxvYyAmJiAobHBEb3NUYXNrID0gY2FsbG9jKDEsIHNpemVvZihET1NUQVNLKSkpID09IE5VTEwpCiAgcmV0dXJuIDA7CgogaWYgKChoRmlsZSA9IE9wZW5GaWxlMTYoIG5hbWUsICZvZnMsIE9GX1JFQUQgKSkgPT0gSEZJTEVfRVJST1IxNikKICByZXR1cm4gMjsgLyogRmlsZSBub3QgZm91bmQgKi8KCiBpZiAoKCFlbnYpJiZwZGIpIGVudiA9IHBkYi0+ZW52X2RiLT5lbnZpcm9uOwogaWYgKGFsbG9jKSB7CiAgaWYgKChoTW9kdWxlID0gTU9EVUxFX0NyZWF0ZUR1bW15TW9kdWxlKCZvZnMpKSA8IDMyKQogICByZXR1cm4gaE1vZHVsZTsKCiAgbHBEb3NUYXNrLT5oTW9kdWxlID0gaE1vZHVsZTsKCiAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoaE1vZHVsZSk7CiAgcE1vZHVsZS0+bHBEb3NUYXNrID0gbHBEb3NUYXNrOwogCiAgbHBEb3NUYXNrLT5pbWc9TlVMTDsgbHBEb3NUYXNrLT5tbV9uYW1lWzBdPTA7IGxwRG9zVGFzay0+bW1fZmQ9LTE7CiB9IGVsc2UgbHBEb3NUYXNrPXBNb2R1bGUtPmxwRG9zVGFzazsKIGVyciA9IE1aX0xvYWRJbWFnZSggaEZpbGUsIG5hbWUsIGNtZGxpbmUsIGVudiwgbHBEb3NUYXNrLCBwTW9kdWxlICk7CiBfbGNsb3NlMTYoaEZpbGUpOwogaWYgKGFsbG9jKSB7CiAgcE1vZHVsZS0+ZG9zX2ltYWdlID0gbHBEb3NUYXNrLT5pbWc7CiAgaWYgKGVycjwzMikgewogICBpZiAobHBEb3NUYXNrLT5tbV9uYW1lWzBdIT0wKSB7CiAgICBpZiAobHBEb3NUYXNrLT5pbWchPU5VTEwpIG11bm1hcChscERvc1Rhc2stPmltZywweDExMDAwMC1TVEFSVF9PRkZTRVQpOwogICAgaWYgKGxwRG9zVGFzay0+bW1fZmQ+PTApIGNsb3NlKGxwRG9zVGFzay0+bW1fZmQpOwogICAgdW5saW5rKGxwRG9zVGFzay0+bW1fbmFtZSk7CiAgIH0gZWxzZQogICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBWaXJ0dWFsRnJlZShscERvc1Rhc2stPmltZywweDExMDAwMCxNRU1fUkVMRUFTRSk7CiAgIHJldHVybiBlcnI7CiAgfQogIGVyciA9IE1aX0luaXRUYXNrKCBscERvc1Rhc2sgKTsKICBpZiAoZXJyPDMyKSB7CiAgIE1aX0tpbGxNb2R1bGUoIGxwRG9zVGFzayApOwogICAvKiBGSVhNRTogY2xlYW51cCBoTW9kdWxlICovCiAgIHJldHVybiBlcnI7CiAgfQoKICBoSW5zdGFuY2UgPSBORV9DcmVhdGVJbnN0YW5jZShwTW9kdWxlLCBOVUxMLCAoY21kbGluZSA9PSBOVUxMKSk7CiAgUFJPQ0VTU19DcmVhdGUoIHBNb2R1bGUsIGNtZGxpbmUsIGVudiwgaEluc3RhbmNlLCAwLCBpbmhlcml0LCBzdGFydHVwLCBpbmZvICk7CiAgcmV0dXJuIGhJbnN0YW5jZTsKIH0gZWxzZSB7CiAgcmV0dXJuIChlcnI8MzIpID8gZXJyIDogcFRhc2stPmhJbnN0YW5jZTsKIH0KfQoKdm9pZCBNWl9LaWxsTW9kdWxlKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogVFJBQ0UobW9kdWxlLCJraWxsaW5nIERPUyB0YXNrXG4iKTsKI2lmIDAKIFNZU1RFTV9LaWxsU3lzdGVtVGltZXIobHBEb3NUYXNrLT5zeXN0ZW1fdGltZXIpOwojZW5kaWYKIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKIH0gZWxzZSBWaXJ0dWFsRnJlZShscERvc1Rhc2stPmltZywweDExMDAwMCxNRU1fUkVMRUFTRSk7CiBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwoga2lsbChscERvc1Rhc2stPnRhc2ssU0lHVEVSTSk7CiNpZiAwCiAvKiBGSVhNRTogdGhpcyBzZWVtcyB0byBjcmFzaCAqLwogaWYgKGxwRG9zVGFzay0+ZHBtaV9zZWwpCiAgVW5NYXBMUyhQVFJfU0VHX09GRl9UT19TRUdQVFIobHBEb3NUYXNrLT5kcG1pX3NlbCwwKSk7CiNlbmRpZgp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgpISU5TVEFOQ0UxNiBNWl9DcmVhdGVQcm9jZXNzKCBMUENTVFIgbmFtZSwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsIEJPT0wzMiBpbmhlcml0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUQVJUVVBJTkZPMzJBIHN0YXJ0dXAsIExQUFJPQ0VTU19JTkZPUk1BVElPTiBpbmZvICkKewogV0FSTihtb2R1bGUsIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlXG4iKTsKIHJldHVybiAoSE1PRFVMRTE2KTExOyAgLyogaW52YWxpZCBleGUgKi8KfQoKI2VuZGlmCg==