LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGNvZGUgaGFzbid0IGJlZW4gY29tcGxldGVseSBjbGVhbmVkIHVwIHlldC4KICovCgojaWZkZWYgbGludXgKIAojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojaW5jbHVkZSA8c3lzL3ZtODYuaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBCSU9TX1NFR01FTlQgQklPU1NFRyAvKiBCSU9TU0VHIGlzIGRlZmluZWQgdG8gMHhmMDAwIGluIHN5cy92bTg2LmggKi8KI2RlZmluZSBTVFVCX1NFR01FTlQgQklPU19TRUdNRU5UCiNkZWZpbmUgU1RBUlRfT0ZGU0VUIDAKI2RlZmluZSBQU1BfU0laRSAweDEwCgojZGVmaW5lIFNFRzE2KHB0cixzZWcpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpKHNlZyk8PDQpKSkKI2RlZmluZSBTRUdQVFIxNihwdHIsc2VncHRyKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKVNFTEVDVE9ST0Yoc2VncHRyKTw8NCkrT0ZGU0VUT0Yoc2VncHRyKSkpCgojZGVmaW5lIFNUVUIoeCkgKDB4OTBDRjAwQ0R8KHg8PDgpKSAvKiBJTlQgeDsgSVJFVDsgTk9QICovCgpzdGF0aWMgdm9pZCBNWl9Jbml0U3lzdGVtKCBMUFZPSUQgbHBJbWFnZSApCnsKIFNFR1BUUippc3I9bHBJbWFnZTsKIERXT1JEKnN0dWI9U0VHMTYobHBJbWFnZSxTVFVCX1NFR01FTlQpOwogaW50IHg7CiAKIC8qIGluaXRpYWxpemUgSVNSIHRhYmxlIHRvIG1ha2UgaXQgcG9pbnQgdG8gSU5UIHN0dWJzIGluIEJJT1NTRUc7CiAgICBMaW51eCBvbmx5IHNlbmRzIElOVHMgcGVyZm9ybWVkIGZyb20gb3IgZGVzdGluZWQgdG8gQklPU1NFRyBhdCB1cywKICAgIGlmIHRoZSBpbnRfcmV2ZWN0b3JlZCB0YWJsZSBpcyBlbXB0eS4KICAgIFRoaXMgYWxsb3dzIERPUyBwcm9ncmFtcyB0byBob29rIGludGVycnVwdHMsIGFzIHdlbGwgYXMgdXNlIHRoZWlyCiAgICBmYW1pbGlhciByZXRmIHRyaWNrcyB0byBjYWxsIHRoZW0uLi4gKi8KIC8qIChub3RlIHRoYXQgdGhlIGhvb2tpbmcgbWlnaHQgbm90IGFjdHVhbGx5IHdvcmsgc2luY2UgRE9TM0NhbGwgc3R1ZmYKICAgICBpc24ndCBmdWxseSBpbnRlZ3JhdGVkIHdpdGggdGhlIERPUyBWTSB5ZXQuLi4pICovCiBUUkFDRShtb2R1bGUsIkluaXRpYWxpemluZyBpbnRlcnJ1cHQgdmVjdG9yIHRhYmxlXG4iKTsKIGZvciAoeD0wOyB4PDI1NjsgeCsrKSBpc3JbeF09UFRSX1NFR19PRkZfVE9fU0VHUFRSKFNUVUJfU0VHTUVOVCx4KjQpOwogVFJBQ0UobW9kdWxlLCJJbml0aWFsaXppbmcgaW50ZXJydXB0IHN0dWIgdGFibGVcbiIpOwogZm9yICh4PTA7IHg8MjU2OyB4KyspIHN0dWJbeF09U1RVQih4KTsKfQoKc3RhdGljIHZvaWQgTVpfSW5pdFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSwgTFBDU1RSIGVudiApCnsKIFBEQipwc3A9bHBQU1A7CiBjb25zdCBjaGFyKmNtZD1jbWRsaW5lP3N0cmNocihjbWRsaW5lLCcgJyk6TlVMTDsKCiBwc3AtPmludDIwPTB4MjBDRDsgLyogaW50IDIwICovCiAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOwogLyogY29weSBwYXJhbWV0ZXJzICovCiBpZiAoY21kKSB7CiNpZiAwCiAgLyogY29tbWFuZC5jb20gZG9lc24ndCBkbyB0aGlzICovCiAgd2hpbGUgKCpjbWQgPT0gJyAnKSBjbWQrKzsKI2VuZGlmCiAgcHNwLT5jbWRMaW5lWzBdPXN0cmxlbihjbWQpOwogIHN0cmNweShwc3AtPmNtZExpbmUrMSxjbWQpOwogIHBzcC0+Y21kTGluZVtwc3AtPmNtZExpbmVbMF0rMV09J1xyJzsKIH0gZWxzZSBwc3AtPmNtZExpbmVbMV09J1xyJzsKIC8qIEZJWE1FOiBpbnRlZ3JhdGUgdGhlIG1lbW9yeSBzdHVmZiBmcm9tIFdpbmUgKG1zZG9zL2Rvc21lbS5jKSAqLwogLyogRklYTUU6IGludGVncmF0ZSB0aGUgUERCIHN0dWZmIGZyb20gV2luZSAobG9hZGVyL3Rhc2suYykgKi8KfQoKc3RhdGljIGludCBNWl9Mb2FkSW1hZ2UoIEhGSUxFMTYgaEZpbGUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LAogICAgICAgICAgICAgICAgICAgICAgICAgTFBET1NUQVNLIGxwRG9zVGFzaywgTkVfTU9EVUxFICpwTW9kdWxlICkKewogSU1BR0VfRE9TX0hFQURFUiBtel9oZWFkZXI7CiBEV09SRCBpbWFnZV9zdGFydCxpbWFnZV9zaXplLG1pbl9zaXplLG1heF9zaXplLGF2YWlsOwogQllURSpwc3Bfc3RhcnQsKmxvYWRfc3RhcnQ7CiBpbnQgeDsKIFNFR1BUUiByZWxvYzsKCiBpZiAoKF9ocmVhZDE2KGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlcikpICE9IHNpemVvZihtel9oZWFkZXIpKSB8fAogICAgIChtel9oZWFkZXIuZV9tYWdpYyAhPSBJTUFHRV9ET1NfU0lHTkFUVVJFKSkKICAgICByZXR1cm4gMTE7IC8qIGludmFsaWQgZXhlICovCiAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiBpbWFnZV9zdGFydD1tel9oZWFkZXIuZV9jcGFyaGRyPDw0OwogaW1hZ2Vfc2l6ZT1tel9oZWFkZXIuZV9jcDw8OTsgLyogcGFnZXMgYXJlIDUxMiBieXRlcyAqLwogaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKIGltYWdlX3NpemUtPWltYWdlX3N0YXJ0OwogbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwoKIC8qIGFsbG9jYXRlIDFNQis2NEsgc2hhcmVkIG1lbW9yeSAqLwogbHBEb3NUYXNrLT5pbWdfb2ZzPVNUQVJUX09GRlNFVDsKI2lmZGVmIE1aX01BUFNFTEYKIGxwRG9zVGFzay0+aW1nPVZpcnR1YWxBbGxvYyhOVUxMLDB4MTEwMDAwLE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwogLyogbWFrZSBzdXJlIG1tYXAgYWNjZXB0cyBpdCAqLwogKChjaGFyKilscERvc1Rhc2stPmltZylbMHgxMEZGRkZdPTA7CiNlbHNlCiB0bXBuYW0obHBEb3NUYXNrLT5tbV9uYW1lKTsKLyogc3RyY3B5KGxwRG9zVGFzay0+bW1fbmFtZSwiL3RtcC9teWRvc2ltYWdlIik7ICovCiBscERvc1Rhc2stPm1tX2ZkPW9wZW4obHBEb3NUYXNrLT5tbV9uYW1lLE9fUkRXUnxPX0NSRUFUIC8qIHxPX1RSVU5DICovLFNfSVJVU1J8U19JV1VTUik7CiBpZiAobHBEb3NUYXNrLT5tbV9mZDwwKSBFUlIobW9kdWxlLCJmaWxlICVzIGNvdWxkIG5vdCBiZSBvcGVuZWRcbiIsbHBEb3NUYXNrLT5tbV9uYW1lKTsKIC8qIGV4cGFuZCBmaWxlIHRvIDFNQis2NEsgKi8KIGxzZWVrKGxwRG9zVGFzay0+bW1fZmQsMHgxMTAwMDAtMSxTRUVLX1NFVCk7CiB4PTA7IHdyaXRlKGxwRG9zVGFzay0+bW1fZmQsJngsMSk7CiAvKiBtYXAgaXQgaW4gKi8KIGxwRG9zVGFzay0+aW1nPW1tYXAoTlVMTCwweDExMDAwMC1TVEFSVF9PRkZTRVQsUFJPVF9SRUFEfFBST1RfV1JJVEUsTUFQX1NIQVJFRCxscERvc1Rhc2stPm1tX2ZkLDApOwojZW5kaWYKIGlmIChscERvc1Rhc2stPmltZz09KExQVk9JRCktMSkgewogIEVSUihtb2R1bGUsImNvdWxkIG5vdCBtYXAgc2hhcmVkIG1lbW9yeSwgZXJyb3I9JXNcbiIsc3RyZXJyb3IoZXJybm8pKTsKICByZXR1cm4gMDsKIH0KIFRSQUNFKG1vZHVsZSwiRE9TIFZNODYgaW1hZ2UgbWFwcGVkIGF0ICUwOGx4XG4iLChEV09SRClscERvc1Rhc2stPmltZyk7CiBwTW9kdWxlLT5kb3NfaW1hZ2U9bHBEb3NUYXNrLT5pbWc7CgogLyogaW5pdGlhbGl6ZSB0aGUgbWVtb3J5ICovCiBNWl9Jbml0U3lzdGVtKGxwRG9zVGFzay0+aW1nKTsKIFRSQUNFKG1vZHVsZSwiSW5pdGlhbGl6aW5nIERPUyBtZW1vcnkgc3RydWN0dXJlc1xuIik7CiBET1NNRU1fSW5pdChscERvc1Rhc2stPmhNb2R1bGUpOwoKIC8qIEZJWE1FOiBhbGxvY2F0ZSBtZW1vcnkgZm9yIGVudmlyb25tZW50IHZhcmlhYmxlcyAqLwoKIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KIFRSQUNFKG1vZHVsZSwiQWxsb2NhdGluZyBET1MgbWVtb3J5IChtaW49JWxkLCBtYXg9JWxkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKGxwRG9zVGFzay0+aE1vZHVsZSk7CiBpZiAoYXZhaWw8bWluX3NpemUpIHsKICBFUlIobW9kdWxlLCAiaW5zdWZmaWNpZW50IERPUyBtZW1vcnlcbiIpOwogIHJldHVybiAwOwogfQogaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKIHBzcF9zdGFydD1ET1NNRU1fR2V0QmxvY2sobHBEb3NUYXNrLT5oTW9kdWxlLGF2YWlsLCZscERvc1Rhc2stPnBzcF9zZWcpOwogaWYgKCFwc3Bfc3RhcnQpIHsKICBFUlIobW9kdWxlLCAiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICByZXR1cm4gMDsKIH0KIGxwRG9zVGFzay0+bG9hZF9zZWc9bHBEb3NUYXNrLT5wc3Bfc2VnK1BTUF9TSVpFOwogbG9hZF9zdGFydD1wc3Bfc3RhcnQrKFBTUF9TSVpFPDw0KTsKIE1aX0luaXRQU1AocHNwX3N0YXJ0LCBjbWRsaW5lLCBlbnYpOwoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UobW9kdWxlLCJsb2FkaW5nIERPUyBFWEUgaW1hZ2Ugc2l6ZSwgJTA4bHggYnl0ZXNcbiIsaW1hZ2Vfc2l6ZSk7CiBfbGxzZWVrMTYoaEZpbGUsaW1hZ2Vfc3RhcnQsRklMRV9CRUdJTik7CiBpZiAoKF9ocmVhZDE2KGhGaWxlLGxvYWRfc3RhcnQsaW1hZ2Vfc2l6ZSkpICE9IGltYWdlX3NpemUpCiAgcmV0dXJuIDExOyAvKiBpbnZhbGlkIGV4ZSAqLwoKIC8qIGxvYWQgcmVsb2NhdGlvbiB0YWJsZSAqLwogVFJBQ0UobW9kdWxlLCJsb2FkaW5nIERPUyBFWEUgcmVsb2NhdGlvbiB0YWJsZSwgJWQgZW50cmllc1xuIixtel9oZWFkZXIuZV9sZmFybGMpOwogLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KIF9sbHNlZWsxNihoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsRklMRV9CRUdJTik7CiBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICBpZiAoX2xyZWFkMTYoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYykpICE9IHNpemVvZihyZWxvYykpCiAgIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KICAqKFdPUkQqKVNFR1BUUjE2KGxvYWRfc3RhcnQscmVsb2MpKz1scERvc1Rhc2stPmxvYWRfc2VnOwogfQoKIC8qIGluaXRpYWxpemUgdm04NiBzdHJ1Y3QgKi8KIG1lbXNldCgmbHBEb3NUYXNrLT5WTTg2LDAsc2l6ZW9mKGxwRG9zVGFzay0+Vk04NikpOwogbHBEb3NUYXNrLT5WTTg2LnJlZ3MuY3M9bHBEb3NUYXNrLT5sb2FkX3NlZyttel9oZWFkZXIuZV9jczsKIGxwRG9zVGFzay0+Vk04Ni5yZWdzLmVpcD1tel9oZWFkZXIuZV9pcDsKIGxwRG9zVGFzay0+Vk04Ni5yZWdzLnNzPWxwRG9zVGFzay0+bG9hZF9zZWcrbXpfaGVhZGVyLmVfc3M7CiBscERvc1Rhc2stPlZNODYucmVncy5lc3A9bXpfaGVhZGVyLmVfc3A7CiBscERvc1Rhc2stPlZNODYucmVncy5kcz1scERvc1Rhc2stPnBzcF9zZWc7CiBscERvc1Rhc2stPlZNODYucmVncy5lcz1scERvc1Rhc2stPnBzcF9zZWc7CiAvKiBobW0sIHdoYXQgZWxzZSBkbyB3ZSBuZWVkPyAqLwoKIHJldHVybiAzMjsKfQoKaW50IE1aX0luaXRUYXNrKCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogaW50IHJlYWRfZmRbMl0sd3JpdGVfZmRbMl07CiBwaWRfdCBjaGlsZDsKIGNoYXIgKmZuYW1lLCpmYXJnLGFyZ1sxNl0sZnByb2NbNjRdOwoKIC8qIGNyZWF0ZSByZWFkIHBpcGUgKi8KIGlmIChwaXBlKHJlYWRfZmQpPDApIHJldHVybiAwOwogaWYgKHBpcGUod3JpdGVfZmQpPDApIHsKICBjbG9zZShyZWFkX2ZkWzBdKTsgY2xvc2UocmVhZF9mZFsxXSk7IHJldHVybiAwOwogfQogbHBEb3NUYXNrLT5yZWFkX3BpcGU9cmVhZF9mZFswXTsKIGxwRG9zVGFzay0+d3JpdGVfcGlwZT13cml0ZV9mZFsxXTsKIGxwRG9zVGFzay0+Zm49Vk04Nl9FTlRFUjsKIGxwRG9zVGFzay0+c3RhdGU9MTsKIC8qIGlmIHdlIGhhdmUgYSBtYXBwaW5nIGZpbGUsIHVzZSBpdCAqLwogZm5hbWU9bHBEb3NUYXNrLT5tbV9uYW1lOyBmYXJnPU5VTEw7CiBpZiAoIWZuYW1lWzBdKSB7CiAgLyogb3RoZXJ3aXNlLCBtYXAgb3VyIG93biBtZW1vcnkgaW1hZ2UgKi8KICBzcHJpbnRmKGZwcm9jLCIvcHJvYy8lZC9tZW0iLGdldHBpZCgpKTsKICBzcHJpbnRmKGFyZywiJWxkIiwodW5zaWduZWQgbG9uZylscERvc1Rhc2stPmltZyk7CiAgZm5hbWU9ZnByb2M7IGZhcmc9YXJnOwogfQoKIFRSQUNFKG1vZHVsZSwiUHJlcGFyaW5nIHRvIGxvYWQgRE9TIFZNIHN1cHBvcnQgbW9kdWxlOiBmb3JraW5nXG4iKTsKIGlmICgoY2hpbGQ9Zm9yaygpKTwwKSB7CiAgY2xvc2Uod3JpdGVfZmRbMF0pOyBjbG9zZSh3cml0ZV9mZFsxXSk7CiAgY2xvc2UocmVhZF9mZFswXSk7IGNsb3NlKHJlYWRfZmRbMV0pOyByZXR1cm4gMDsKIH0KIGlmIChjaGlsZCE9MCkgewogIC8qIHBhcmVudCBwcm9jZXNzICovCiAgaW50IHJldDsKCiAgY2xvc2UocmVhZF9mZFsxXSk7IGNsb3NlKHdyaXRlX2ZkWzBdKTsKICBscERvc1Rhc2stPnRhc2s9Y2hpbGQ7CiAgLyogd2FpdCBmb3IgY2hpbGQgcHJvY2VzcyB0byBzaWduYWwgcmVhZGluZXNzICovCiAgZG8gewogICBpZiAocmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmcmV0LHNpemVvZihyZXQpKSE9c2l6ZW9mKHJldCkpIHsKICAgIGlmICgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSBjb250aW51ZTsKICAgIC8qIGZhaWx1cmUgKi8KICAgIEVSUihtb2R1bGUsImRvc21vZCBoYXMgZmFpbGVkIHRvIGluaXRpYWxpemVcbiIpOwogICAgcmV0dXJuIDA7CiAgIH0KICB9IHdoaWxlICgwKTsKICAvKiBhbGwgc3lzdGVtcyBhcmUgbm93IGdvICovCiB9IGVsc2UgewogIC8qIGNoaWxkIHByb2Nlc3MgKi8KICBjbG9zZShyZWFkX2ZkWzBdKTsgY2xvc2Uod3JpdGVfZmRbMV0pOwogIC8qIHB1dCBvdXIgcGlwZXMgc29tZXdoZXJlIGRvc21vZCBjYW4gZmluZCB0aGVtICovCiAgZHVwMih3cml0ZV9mZFswXSwwKTsgICAgICAvKiBzdGRpbiAqLwogIGR1cDIocmVhZF9mZFsxXSwxKTsgICAgICAgLyogc3Rkb3V0ICovCiAgLyogbm93IGxvYWQgZG9zbW9kICovCiAgZXhlY2xwKCJkb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgZXhlY2woImRvc21vZCIsZm5hbWUsZmFyZyxOVUxMKTsKICBleGVjbCgibG9hZGVyL2Rvcy9kb3Ntb2QiLGZuYW1lLGZhcmcsTlVMTCk7CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUihtb2R1bGUsIkZhaWxlZCB0byBzcGF3biBkb3Ntb2QsIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgZXhpdCgxKTsKIH0KIHJldHVybiAzMjsKfQoKSElOU1RBTkNFMTYgTVpfQ3JlYXRlUHJvY2VzcyggTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFSVFVQSU5GTzMyQSBzdGFydHVwLCBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKIExQRE9TVEFTSyBscERvc1Rhc2s7CiBITU9EVUxFMTYgaE1vZHVsZTsKIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKIE5FX01PRFVMRSAqcE1vZHVsZTsKIEhGSUxFMTYgaEZpbGU7CiBPRlNUUlVDVCBvZnM7CiBpbnQgZXJyOwoKIGlmICgobHBEb3NUYXNrID0gY2FsbG9jKDEsIHNpemVvZihET1NUQVNLKSkpID09IE5VTEwpCiAgcmV0dXJuIDA7CgogaWYgKChoRmlsZSA9IE9wZW5GaWxlMTYoIG5hbWUsICZvZnMsIE9GX1JFQUQgKSkgPT0gSEZJTEVfRVJST1IxNikKICByZXR1cm4gMjsgLyogRmlsZSBub3QgZm91bmQgKi8KCiBpZiAoKGhNb2R1bGUgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoJm9mcykpIDwgMzIpCiAgcmV0dXJuIGhNb2R1bGU7CgogbHBEb3NUYXNrLT5oTW9kdWxlID0gaE1vZHVsZTsKCiBwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNihoTW9kdWxlKTsKIHBNb2R1bGUtPmxwRG9zVGFzayA9IGxwRG9zVGFzazsKIAogbHBEb3NUYXNrLT5pbWc9TlVMTDsgbHBEb3NUYXNrLT5tbV9uYW1lWzBdPTA7IGxwRG9zVGFzay0+bW1fZmQ9LTE7CiBlcnIgPSBNWl9Mb2FkSW1hZ2UoIGhGaWxlLCBjbWRsaW5lLCBlbnYsIGxwRG9zVGFzaywgcE1vZHVsZSApOwogX2xjbG9zZTE2KGhGaWxlKTsKIHBNb2R1bGUtPmRvc19pbWFnZSA9IGxwRG9zVGFzay0+aW1nOwogaWYgKGVycjwzMikgewogIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICAgaWYgKGxwRG9zVGFzay0+bW1fZmQ+PTApIGNsb3NlKGxwRG9zVGFzay0+bW1fZmQpOwogICB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKICB9IGVsc2UKICAgaWYgKGxwRG9zVGFzay0+aW1nIT1OVUxMKSBWaXJ0dWFsRnJlZShscERvc1Rhc2stPmltZywweDExMDAwMCxNRU1fUkVMRUFTRSk7CiAgcmV0dXJuIGVycjsKIH0KIGVyciA9IE1aX0luaXRUYXNrKCBscERvc1Rhc2sgKTsKIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICAvKiB3ZSB1bmxpbmsgdGhlIHRlbXAgZmlsZSBoZXJlIHRvIGF2b2lkIGxlYXZpbmcgYSBtZXNzIGluIC90bXAKICAgICBpZi93aGVuIFdpbmUgY3Jhc2hlczsgdGhlIG1hcHBpbmcgc3RpbGwgcmVtYWlucyBvcGVuLCB0aG91Z2ggKi8KICB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKIH0KIGlmIChlcnI8MzIpIHsKICBNWl9LaWxsTW9kdWxlKCBscERvc1Rhc2sgKTsKICAvKiBGSVhNRTogY2xlYW51cCBoTW9kdWxlICovCiAgcmV0dXJuIGVycjsKIH0KCiBoSW5zdGFuY2UgPSBORV9DcmVhdGVJbnN0YW5jZShwTW9kdWxlLCBOVUxMLCAoY21kbGluZSA9PSBOVUxMKSk7CiBQUk9DRVNTX0NyZWF0ZSggcE1vZHVsZSwgY21kbGluZSwgZW52LCBoSW5zdGFuY2UsIDAsIHN0YXJ0dXAsIGluZm8gKTsKIHJldHVybiBoSW5zdGFuY2U7Cn0KCnZvaWQgTVpfS2lsbE1vZHVsZSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHsKICBtdW5tYXAobHBEb3NUYXNrLT5pbWcsMHgxMTAwMDAtU1RBUlRfT0ZGU0VUKTsKICBjbG9zZShscERvc1Rhc2stPm1tX2ZkKTsKIH0gZWxzZSBWaXJ0dWFsRnJlZShscERvc1Rhc2stPmltZywweDExMDAwMCxNRU1fUkVMRUFTRSk7CiBjbG9zZShscERvc1Rhc2stPnJlYWRfcGlwZSk7CiBjbG9zZShscERvc1Rhc2stPndyaXRlX3BpcGUpOwoga2lsbChscERvc1Rhc2stPnRhc2ssU0lHVEVSTSk7Cn0KCmludCBNWl9SdW5Nb2R1bGUoIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7Ci8qIHRyYW5zbWl0IHRoZSBjdXJyZW50IGNvbnRleHQgc3RydWN0dXJlIHRvIHRoZSBET1MgdGFzayAqLwogaWYgKGxwRG9zVGFzay0+c3RhdGU9PTEpIHsKICBpZiAod3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZscERvc1Rhc2stPmZuLHNpemVvZihscERvc1Rhc2stPmZuKSkhPXNpemVvZihscERvc1Rhc2stPmZuKSkKICAgcmV0dXJuIC0xOwogIGlmICh3cml0ZShscERvc1Rhc2stPndyaXRlX3BpcGUsJmxwRG9zVGFzay0+Vk04NixzaXplb2YobHBEb3NUYXNrLT5WTTg2KSkhPXNpemVvZihscERvc1Rhc2stPlZNODYpKQogICByZXR1cm4gLTE7CiAgbHBEb3NUYXNrLT5zdGF0ZT0yOwogfQovKiB3YWl0IGZvciBhbm90aGVyIGNvbnRleHQgc3RydWN0dXJlIHRvIGFwcGVhciAodGhpcyBtYXkgYmxvY2spICovCiBpZiAobHBEb3NUYXNrLT5zdGF0ZT09MikgewogIGlmIChyZWFkKGxwRG9zVGFzay0+cmVhZF9waXBlLCZscERvc1Rhc2stPmZuLHNpemVvZihscERvc1Rhc2stPmZuKSkhPXNpemVvZihscERvc1Rhc2stPmZuKSkgewogICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgcmV0dXJuIDA7CiAgIHJldHVybiAtMTsKICB9CiAgbHBEb3NUYXNrLT5zdGF0ZT0zOwogfQogaWYgKGxwRG9zVGFzay0+c3RhdGU9PTMpIHsKICBpZiAocmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmbHBEb3NUYXNrLT5WTTg2LHNpemVvZihscERvc1Rhc2stPlZNODYpKSE9c2l6ZW9mKGxwRG9zVGFzay0+Vk04NikpIHsKICAgaWYgKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpIHJldHVybiAwOwogICByZXR1cm4gLTE7CiAgfQovKiBnb3Qgb25lICovCiAgbHBEb3NUYXNrLT5zdGF0ZT0xOwogIHJldHVybiAxOwogfQogcmV0dXJuIDA7Cn0KCiNlbHNlIC8qICFsaW51eCAqLwoKSElOU1RBTkNFMTYgTVpfQ3JlYXRlUHJvY2VzcyggTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVEFSVFVQSU5GTzMyQSBzdGFydHVwLCBMUFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbyApCnsKIFdBUk4obW9kdWxlLCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZVxuIik7CiByZXR1cm4gKEhNT0RVTEUxNikxMTsgIC8qIGludmFsaWQgZXhlICovCn0KCiNlbmRpZgo=