LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKi8KCiNpZmRlZiBsaW51eAogCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8c2lnbmFsLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2lmZGVmIE1aX1VTRVNZU1YKI2luY2x1ZGUgPHN5cy9pcGMuaD4KI2luY2x1ZGUgPHN5cy9zaG0uaD4KI2Vsc2UKI2luY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3ZtODYuaD4KI2lmZGVmIE1aX1VTRVNZU1YKI2luY2x1ZGUgPGxpbnV4L21tLmg+IC8qIEZJWE1FOiB3aGVyZSBlbHNlIHNob3VsZCBJIGZldGNoIHRoZSBQQUdFX1NJWkUgZGVmaW5lPyAqLwojZW5kaWYKI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJwcm9jZXNzLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAiZG9zZXhlLmgiCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBCSU9TX1NFR01FTlQgQklPU1NFRyAvKiBCSU9TU0VHIGlzIGRlZmluZWQgdG8gMHhmMDAwIGluIHN5cy92bTg2LmggKi8KI2RlZmluZSBTVFVCX1NFR01FTlQgQklPU19TRUdNRU5UCiNpZmRlZiBNWl9VU0VTWVNWCi8qIGl0IG1pZ2h0IGJlIHRoYXQgU1lTViBzdXBwb3J0cyBTVEFSVF9PRkZTRVQgMCBhZnRlciBhbGwsIGhhdmVuJ3QgY2hlY2tlZCAqLwojZGVmaW5lIFNUQVJUX09GRlNFVCBQQUdFX1NJWkUKI2Vsc2UKI2RlZmluZSBTVEFSVF9PRkZTRVQgMAojZW5kaWYKI2RlZmluZSBQU1BfU0laRSAweDEwCgojZGVmaW5lIFNFRzE2KHB0cixzZWcpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpKHNlZyk8PDQpKSkKI2RlZmluZSBTRUdQVFIxNihwdHIsc2VncHRyKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKVNFTEVDVE9ST0Yoc2VncHRyKTw8NCkrT0ZGU0VUT0Yoc2VncHRyKSkpCgojZGVmaW5lIFNUVUIoeCkgKDB4OTBDRjAwQ0R8KHg8PDgpKSAvKiBJTlQgeDsgSVJFVDsgTk9QICovCgpzdGF0aWMgdm9pZCBNWl9Jbml0U3lzdGVtKCBMUFZPSUQgbHBJbWFnZSApCnsKIFNFR1BUUippc3I9bHBJbWFnZTsKIERXT1JEKnN0dWI9U0VHMTYobHBJbWFnZSxTVFVCX1NFR01FTlQpOwogaW50IHg7CiAKIC8qIGluaXRpYWxpemUgSVNSIHRhYmxlIHRvIG1ha2UgaXQgcG9pbnQgdG8gSU5UIHN0dWJzIGluIEJJT1NTRUc7CiAgICBMaW51eCBvbmx5IHNlbmRzIElOVHMgcGVyZm9ybWVkIGZyb20gb3IgZGVzdGluZWQgdG8gQklPU1NFRyBhdCB1cywKICAgIGlmIHRoZSBpbnRfcmV2ZWN0b3JlZCB0YWJsZSBpcyBlbXB0eS4KICAgIFRoaXMgYWxsb3dzIERPUyBwcm9ncmFtcyB0byBob29rIGludGVycnVwdHMsIGFzIHdlbGwgYXMgdXNlIHRoZWlyCiAgICBmYW1pbGlhciByZXRmIHRyaWNrcyB0byBjYWxsIHRoZW0uLi4gKi8KIC8qIChub3RlIHRoYXQgdGhlIGhvb2tpbmcgbWlnaHQgbm90IGFjdHVhbGx5IHdvcmsgc2luY2UgRE9TM0NhbGwgc3R1ZmYKICAgICBpc24ndCBmdWxseSBpbnRlZ3JhdGVkIHdpdGggdGhlIERPUyBWTSB5ZXQuLi4pICovCiBUUkFDRShtb2R1bGUsIkluaXRpYWxpemluZyBpbnRlcnJ1cHQgdmVjdG9yIHRhYmxlXG4iKTsKIGZvciAoeD0wOyB4PDI1NjsgeCsrKSBpc3JbeF09UFRSX1NFR19PRkZfVE9fU0VHUFRSKFNUVUJfU0VHTUVOVCx4KjQpOwogVFJBQ0UobW9kdWxlLCJJbml0aWFsaXppbmcgaW50ZXJydXB0IHN0dWIgdGFibGVcbiIpOwogZm9yICh4PTA7IHg8MjU2OyB4KyspIHN0dWJbeF09U1RVQih4KTsKfQoKc3RhdGljIHZvaWQgTVpfSW5pdFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kbGluZSwgTFBDU1RSIGVudiApCnsKIFBEQipwc3A9bHBQU1A7CiBjb25zdCBjaGFyKmNtZD1jbWRsaW5lP3N0cmNocihjbWRsaW5lLCcgJyk6TlVMTDsKCiBwc3AtPmludDIwPTB4MjBDRDsgLyogaW50IDIwICovCiAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOwogLyogY29weSBwYXJhbWV0ZXJzICovCiBpZiAoY21kKSB7CiAgd2hpbGUgKCpjbWQgPT0gJyAnKSBjbWQrKzsKICBwc3AtPmNtZExpbmVbMF09c3RybGVuKGNtZCk7CiAgc3RyY3B5KHBzcC0+Y21kTGluZSsxLGNtZCk7CiAgcHNwLT5jbWRMaW5lW3BzcC0+Y21kTGluZVswXSsxXT0nXHInOwogfSBlbHNlIHBzcC0+Y21kTGluZVsxXT0nXHInOwogLyogRklYTUU6IGludGVncmF0ZSB0aGUgbWVtb3J5IHN0dWZmIGZyb20gV2luZSAobXNkb3MvZG9zbWVtLmMpICovCiAvKiBGSVhNRTogaW50ZWdyYXRlIHRoZSBQREIgc3R1ZmYgZnJvbSBXaW5lIChsb2FkZXIvdGFzay5jKSAqLwp9CgpzdGF0aWMgaW50IE1aX0xvYWRJbWFnZSggSEZJTEUxNiBoRmlsZSwgTFBDU1RSIGNtZGxpbmUsIExQQ1NUUiBlbnYsIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiBXT1JEIHBzcF9zZWcsbG9hZF9zZWc7CiBCWVRFKnBzcF9zdGFydCwqbG9hZF9zdGFydDsKIGludCB4OwogU0VHUFRSIHJlbG9jOwoKIGlmICgoX2hyZWFkMTYoaEZpbGUsJm16X2hlYWRlcixzaXplb2YobXpfaGVhZGVyKSkgIT0gc2l6ZW9mKG16X2hlYWRlcikpIHx8CiAgICAgKG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpKQogICAgIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KIC8qIGNhbGN1bGF0ZSBsb2FkIHNpemUgKi8KIGltYWdlX3N0YXJ0PW16X2hlYWRlci5lX2NwYXJoZHI8PDQ7CiBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiBpZiAoKG16X2hlYWRlci5lX2NibHAhPTApJiYobXpfaGVhZGVyLmVfY2JscCE9NCkpIGltYWdlX3NpemUtPTUxMi1tel9oZWFkZXIuZV9jYmxwOwogaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiBtYXhfc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWF4YWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CgogLyogYWxsb2NhdGUgMU1CKzY0SyBzaGFyZWQgbWVtb3J5ICovCiBscERvc1Rhc2stPmltZ19vZnM9U1RBUlRfT0ZGU0VUOwojaWZkZWYgTVpfVVNFU1lTVgogbHBEb3NUYXNrLT5rZXk9ZnRvaygiLiIsJ2QnKTsgLyogRklYTUU6IHRoaXMgaXMgZnJvbSBteSBJUEMgaW50cm8gZG9jICovCiBscERvc1Rhc2stPnNobV9pZD1zaG1nZXQobHBEb3NUYXNrLT5rZXksMHgxMTAwMDAtU1RBUlRfT0ZGU0VULElQQ19DUkVBVHxTSE1fUnxTSE1fVyk7CiBscERvc1Rhc2stPmltZz1zaG1hdChscERvc1Rhc2stPnNobV9pZCxOVUxMLDApOwojZWxzZQogdG1wbmFtKGxwRG9zVGFzay0+bW1fbmFtZSk7Ci8qIHN0cmNweShscERvc1Rhc2stPm1tX25hbWUsIi90bXAvbXlkb3NpbWFnZSIpOyAqLwogbHBEb3NUYXNrLT5tbV9mZD1vcGVuKGxwRG9zVGFzay0+bW1fbmFtZSxPX1JEV1J8T19DUkVBVCAvKiB8T19UUlVOQyAqLyxTX0lSVVNSfFNfSVdVU1IpOwogaWYgKGxwRG9zVGFzay0+bW1fZmQ8MCkgRVJSKG1vZHVsZSwiZmlsZSAlcyBjb3VsZCBub3QgYmUgb3BlbmVkXG4iLGxwRG9zVGFzay0+bW1fbmFtZSk7CiAvKiBleHBhbmQgZmlsZSB0byAxTUIrNjRLICovCiBsc2VlayhscERvc1Rhc2stPm1tX2ZkLDB4MTEwMDAwLTEsU0VFS19TRVQpOwogeD0wOyB3cml0ZShscERvc1Rhc2stPm1tX2ZkLCZ4LDEpOwogLyogbWFwIGl0IGluICovCiBscERvc1Rhc2stPmltZz1tbWFwKE5VTEwsMHgxMTAwMDAtU1RBUlRfT0ZGU0VULFBST1RfUkVBRHxQUk9UX1dSSVRFLE1BUF9TSEFSRUQsbHBEb3NUYXNrLT5tbV9mZCwwKTsKI2VuZGlmCiBpZiAobHBEb3NUYXNrLT5pbWc9PShMUFZPSUQpLTEpIHsKICBFUlIobW9kdWxlLCJjb3VsZCBub3QgbWFwIHNoYXJlZCBtZW1vcnksIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgcmV0dXJuIDA7CiB9CiBUUkFDRShtb2R1bGUsIkRPUyBWTTg2IGltYWdlIG1hcHBlZCBhdCAlMDhseFxuIiwoRFdPUkQpbHBEb3NUYXNrLT5pbWcpOwoKIC8qIGluaXRpYWxpemUgdGhlIG1lbW9yeSAqLwogTVpfSW5pdFN5c3RlbShscERvc1Rhc2stPmltZyk7CiBUUkFDRShtb2R1bGUsIkluaXRpYWxpemluZyBET1MgbWVtb3J5IHN0cnVjdHVyZXNcbiIpOwogRE9TTUVNX0luaXQobHBEb3NUYXNrLT5oTW9kdWxlKTsKCiAvKiBGSVhNRTogYWxsb2NhdGUgbWVtb3J5IGZvciBlbnZpcm9ubWVudCB2YXJpYWJsZXMgKi8KCiAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBleGVjdXRhYmxlICovCiBUUkFDRShtb2R1bGUsIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogYXZhaWw9RE9TTUVNX0F2YWlsYWJsZShscERvc1Rhc2stPmhNb2R1bGUpOwogaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgRVJSKG1vZHVsZSwgImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICByZXR1cm4gMDsKIH0KIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiBwc3Bfc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGxwRG9zVGFzay0+aE1vZHVsZSxhdmFpbCwmcHNwX3NlZyk7CiBpZiAoIXBzcF9zdGFydCkgewogIEVSUihtb2R1bGUsICJlcnJvciBhbGxvY2F0aW5nIERPUyBtZW1vcnlcbiIpOwogIHJldHVybiAwOwogfQogbG9hZF9zZWc9cHNwX3NlZytQU1BfU0laRTsKIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiBNWl9Jbml0UFNQKHBzcF9zdGFydCwgY21kbGluZSwgZW52KTsKCiAvKiBsb2FkIGV4ZWN1dGFibGUgaW1hZ2UgKi8KIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgRVhFIGltYWdlIHNpemUsICUwOGx4IGJ5dGVzXG4iLGltYWdlX3NpemUpOwogX2xsc2VlazE2KGhGaWxlLGltYWdlX3N0YXJ0LEZJTEVfQkVHSU4pOwogaWYgKChfaHJlYWQxNihoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUpKSAhPSBpbWFnZV9zaXplKQogIHJldHVybiAxMTsgLyogaW52YWxpZCBleGUgKi8KCiAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KIFRSQUNFKG1vZHVsZSwibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfbGZhcmxjKTsKIC8qIEZJWE1FOiBpcyB0aGlzIHRvbyBzbG93IHdpdGhvdXQgcmVhZCBidWZmZXJpbmc/ICovCiBfbGxzZWVrMTYoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLEZJTEVfQkVHSU4pOwogZm9yICh4PTA7IHg8bXpfaGVhZGVyLmVfY3JsYzsgeCsrKSB7CiAgaWYgKF9scmVhZDE2KGhGaWxlLCZyZWxvYyxzaXplb2YocmVsb2MpKSAhPSBzaXplb2YocmVsb2MpKQogICByZXR1cm4gMTE7IC8qIGludmFsaWQgZXhlICovCiAgKihXT1JEKilTRUdQVFIxNihsb2FkX3N0YXJ0LHJlbG9jKSs9bG9hZF9zZWc7CiB9CgogLyogaW5pdGlhbGl6ZSB2bTg2IHN0cnVjdCAqLwogbWVtc2V0KCZscERvc1Rhc2stPlZNODYsMCxzaXplb2YobHBEb3NUYXNrLT5WTTg2KSk7CiBscERvc1Rhc2stPlZNODYucmVncy5jcz1sb2FkX3NlZyttel9oZWFkZXIuZV9jczsKIGxwRG9zVGFzay0+Vk04Ni5yZWdzLmVpcD1tel9oZWFkZXIuZV9pcDsKIGxwRG9zVGFzay0+Vk04Ni5yZWdzLnNzPWxvYWRfc2VnK216X2hlYWRlci5lX3NzOwogbHBEb3NUYXNrLT5WTTg2LnJlZ3MuZXNwPW16X2hlYWRlci5lX3NwOwogbHBEb3NUYXNrLT5WTTg2LnJlZ3MuZHM9cHNwX3NlZzsKIGxwRG9zVGFzay0+Vk04Ni5yZWdzLmVzPXBzcF9zZWc7CiAvKiBobW0sIHdoYXQgZWxzZSBkbyB3ZSBuZWVkPyAqLwoKIHJldHVybiAzMjsKfQoKc3RhdGljIGludCBNWl9Jbml0VGFzayggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIGludCByZWFkX2ZkWzJdLHdyaXRlX2ZkWzJdOwogcGlkX3QgY2hpbGQ7CgogLyogY3JlYXRlIHJlYWQgcGlwZSAqLwogaWYgKHBpcGUocmVhZF9mZCk8MCkgcmV0dXJuIDA7CiBpZiAocGlwZSh3cml0ZV9mZCk8MCkgewogIGNsb3NlKHJlYWRfZmRbMF0pOyBjbG9zZShyZWFkX2ZkWzFdKTsgcmV0dXJuIDA7CiB9CiBscERvc1Rhc2stPnJlYWRfcGlwZT1yZWFkX2ZkWzBdOwogbHBEb3NUYXNrLT53cml0ZV9waXBlPXdyaXRlX2ZkWzFdOwogbHBEb3NUYXNrLT5mbj1WTTg2X0VOVEVSOwogbHBEb3NUYXNrLT5zdGF0ZT0xOwogVFJBQ0UobW9kdWxlLCJQcmVwYXJpbmcgdG8gbG9hZCBET1MgRVhFIHN1cHBvcnQgbW9kdWxlOiBmb3JraW5nXG4iKTsKIGlmICgoY2hpbGQ9Zm9yaygpKTwwKSB7CiAgY2xvc2Uod3JpdGVfZmRbMF0pOyBjbG9zZSh3cml0ZV9mZFsxXSk7CiAgY2xvc2UocmVhZF9mZFswXSk7IGNsb3NlKHJlYWRfZmRbMV0pOyByZXR1cm4gMDsKIH0KIGlmIChjaGlsZCE9MCkgewogIC8qIHBhcmVudCBwcm9jZXNzICovCiAgY2xvc2UocmVhZF9mZFsxXSk7IGNsb3NlKHdyaXRlX2ZkWzBdKTsKICBscERvc1Rhc2stPnRhc2s9Y2hpbGQ7CiB9IGVsc2UgewogIC8qIGNoaWxkIHByb2Nlc3MgKi8KICBjbG9zZShyZWFkX2ZkWzBdKTsgY2xvc2Uod3JpdGVfZmRbMV0pOwogIC8qIHB1dCBvdXIgcGlwZXMgc29tZXdoZXJlIGRvc21vZCBjYW4gZmluZCB0aGVtICovCiAgZHVwMih3cml0ZV9mZFswXSwwKTsgICAgICAvKiBzdGRpbiAqLwogIGR1cDIocmVhZF9mZFsxXSwxKTsgICAgICAgLyogc3Rkb3V0ICovCiAgLyogbm93IGxvYWQgZG9zbW9kICovCiAgZXhlY2xwKCJkb3Ntb2QiLGxwRG9zVGFzay0+bW1fbmFtZSxOVUxMKTsKICBleGVjbCgiZG9zbW9kIixscERvc1Rhc2stPm1tX25hbWUsTlVMTCk7CiAgZXhlY2woImxvYWRlci9kb3MvZG9zbW9kIixscERvc1Rhc2stPm1tX25hbWUsTlVMTCk7CiAgLyogaWYgZmFpbHVyZSwgZXhpdCAqLwogIEVSUihtb2R1bGUsIkZhaWxlZCB0byBzcGF3biBkb3Ntb2QsIGVycm9yPSVzXG4iLHN0cmVycm9yKGVycm5vKSk7CiAgZXhpdCgxKTsKIH0KIHJldHVybiAzMjsKfQoKSElOU1RBTkNFMTYgTVpfTG9hZE1vZHVsZSggTFBDU1RSIG5hbWUsIExQQ1NUUiBjbWRsaW5lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGVudiwgVUlOVDE2IHNob3dfY21kICkKewogTFBET1NUQVNLIGxwRG9zVGFzazsKIEhNT0RVTEUxNiBoTW9kdWxlOwogSElOU1RBTkNFMTYgaEluc3RhbmNlOwogTkVfTU9EVUxFICpwTW9kdWxlOwogSEZJTEUxNiBoRmlsZTsKIE9GU1RSVUNUIG9mczsKIFBST0NFU1NfSU5GT1JNQVRJT04gaW5mbzsKIGludCBlcnI7CgogaWYgKChscERvc1Rhc2sgPSBjYWxsb2MoMSwgc2l6ZW9mKERPU1RBU0spKSkgPT0gTlVMTCkKICByZXR1cm4gMDsKCiBpZiAoKGhGaWxlID0gT3BlbkZpbGUxNiggbmFtZSwgJm9mcywgT0ZfUkVBRCApKSA9PSBIRklMRV9FUlJPUjE2KQogIHJldHVybiAyOyAvKiBGaWxlIG5vdCBmb3VuZCAqLwoKIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSgmb2ZzKSkgPCAzMikKICByZXR1cm4gaE1vZHVsZTsKCiBscERvc1Rhc2stPmhNb2R1bGUgPSBoTW9kdWxlOwoKIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KGhNb2R1bGUpOwogcE1vZHVsZS0+bHBEb3NUYXNrID0gbHBEb3NUYXNrOwogCiBscERvc1Rhc2stPmltZz1OVUxMOyBscERvc1Rhc2stPm1tX25hbWVbMF09MDsgbHBEb3NUYXNrLT5tbV9mZD0tMTsKIGVyciA9IE1aX0xvYWRJbWFnZSggaEZpbGUsIGNtZGxpbmUsIGVudiwgbHBEb3NUYXNrICk7CiBfbGNsb3NlMTYoaEZpbGUpOwogaWYgKGVycjwzMikgewogIGlmIChscERvc1Rhc2stPmltZyE9TlVMTCkgbXVubWFwKGxwRG9zVGFzay0+aW1nLDB4MTEwMDAwLVNUQVJUX09GRlNFVCk7CiAgaWYgKGxwRG9zVGFzay0+bW1fZmQ+PTApIGNsb3NlKGxwRG9zVGFzay0+bW1fZmQpOwogIGlmIChscERvc1Rhc2stPm1tX25hbWVbMF0hPTApIHVubGluayhscERvc1Rhc2stPm1tX25hbWUpOwogIHJldHVybiBlcnI7CiB9CiBNWl9Jbml0VGFzayggbHBEb3NUYXNrICk7CgogaEluc3RhbmNlID0gTkVfQ3JlYXRlSW5zdGFuY2UocE1vZHVsZSwgTlVMTCwgKGNtZGxpbmUgPT0gTlVMTCkpOwogUFJPQ0VTU19DcmVhdGUoIHBNb2R1bGUsIGNtZGxpbmUsIGVudiwgaEluc3RhbmNlLCAwLCBzaG93X2NtZCwgJmluZm8gKTsKIC8qIHdlIGRvbid0IG5lZWQgdGhlIGhhbmRsZXMgZm9yIG5vdyAqLwogQ2xvc2VIYW5kbGUoIGluZm8uaFRocmVhZCApOwogQ2xvc2VIYW5kbGUoIGluZm8uaFByb2Nlc3MgKTsKIHJldHVybiBoSW5zdGFuY2U7Cn0KCnZvaWQgTVpfS2lsbE1vZHVsZSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKIG11bm1hcChscERvc1Rhc2stPmltZywweDExMDAwMC1TVEFSVF9PRkZTRVQpOwogY2xvc2UobHBEb3NUYXNrLT5tbV9mZCk7CiB1bmxpbmsobHBEb3NUYXNrLT5tbV9uYW1lKTsKIGNsb3NlKGxwRG9zVGFzay0+cmVhZF9waXBlKTsKIGNsb3NlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSk7CiBraWxsKGxwRG9zVGFzay0+dGFzayxTSUdURVJNKTsKfQoKaW50IE1aX1J1bk1vZHVsZSggTFBET1NUQVNLIGxwRG9zVGFzayApCnsKLyogdHJhbnNtaXQgdGhlIGN1cnJlbnQgY29udGV4dCBzdHJ1Y3R1cmUgdG8gdGhlIERPUyB0YXNrICovCiBpZiAobHBEb3NUYXNrLT5zdGF0ZT09MSkgewogIGlmICh3cml0ZShscERvc1Rhc2stPndyaXRlX3BpcGUsJmxwRG9zVGFzay0+Zm4sc2l6ZW9mKGxwRG9zVGFzay0+Zm4pKSE9c2l6ZW9mKGxwRG9zVGFzay0+Zm4pKQogICByZXR1cm4gLTE7CiAgaWYgKHdyaXRlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSwmbHBEb3NUYXNrLT5WTTg2LHNpemVvZihscERvc1Rhc2stPlZNODYpKSE9c2l6ZW9mKGxwRG9zVGFzay0+Vk04NikpCiAgIHJldHVybiAtMTsKICBscERvc1Rhc2stPnN0YXRlPTI7CiB9Ci8qIHdhaXQgZm9yIGFub3RoZXIgY29udGV4dCBzdHJ1Y3R1cmUgdG8gYXBwZWFyICh0aGlzIG1heSBibG9jaykgKi8KIGlmIChscERvc1Rhc2stPnN0YXRlPT0yKSB7CiAgaWYgKHJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJmxwRG9zVGFzay0+Zm4sc2l6ZW9mKGxwRG9zVGFzay0+Zm4pKSE9c2l6ZW9mKGxwRG9zVGFzay0+Zm4pKSB7CiAgIGlmICgoZXJybm89PUVJTlRSKXx8KGVycm5vPT1FQUdBSU4pKSByZXR1cm4gMDsKICAgcmV0dXJuIC0xOwogIH0KICBscERvc1Rhc2stPnN0YXRlPTM7CiB9CiBpZiAobHBEb3NUYXNrLT5zdGF0ZT09MykgewogIGlmIChyZWFkKGxwRG9zVGFzay0+cmVhZF9waXBlLCZscERvc1Rhc2stPlZNODYsc2l6ZW9mKGxwRG9zVGFzay0+Vk04NikpIT1zaXplb2YobHBEb3NUYXNrLT5WTTg2KSkgewogICBpZiAoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkgcmV0dXJuIDA7CiAgIHJldHVybiAtMTsKICB9Ci8qIGdvdCBvbmUgKi8KICBscERvc1Rhc2stPnN0YXRlPTE7CiAgcmV0dXJuIDE7CiB9CiByZXR1cm4gMDsKfQoKI2VuZGlmIC8qIGxpbnV4ICovCg==