LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICogTm90ZTogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8c2lnbmFsLmg+CiNpZmRlZiBIQVZFX1VOSVNURF9ICiMgaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaWZkZWYgSEFWRV9TWVNfVElNRV9ICiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc3ZtLmgiCiNpbmNsdWRlICJ2Z2EuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CgpzdGF0aWMgQk9PTCBET1NWTV9pc2Rvc2V4ZTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgIERPU1ZNX0lzV2luMTYKICogCiAqIFJldHVybiBUUlVFIGlmIHdlIGFyZSBpbiBXaW5kb3dzIHByb2Nlc3MuCiAqLwpCT09MIERPU1ZNX0lzV2luMTYodm9pZCkKewogIHJldHVybiBET1NWTV9pc2Rvc2V4ZSA/IEZBTFNFIDogVFJVRTsKfQoKI2lmZGVmIE1aX1NVUFBPUlRFRAoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKLyogZGVmaW5lIHRoaXMgdG8gdHJ5IG1hcHBpbmcgdGhyb3VnaCAvcHJvYy9waWQvbWVtIGluc3RlYWQgb2YgYSB0ZW1wIGZpbGUsCiAgIGJ1dCBMaW51cyBkb2Vzbid0IGxpa2UgbW1hcHBpbmcgL3Byb2MvcGlkL21lbSwgc28gaXQgZG9lc24ndCB3b3JrIGZvciBtZSAqLwojdW5kZWYgTVpfTUFQU0VMRgoKI2RlZmluZSBCSU9TX0RBVEFfU0VHTUVOVCAweDQwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKLyogc3RydWN0dXJlcyBmb3IgRVhFQyAqLwoKdHlwZWRlZiBzdHJ1Y3QgewogIFdPUkQgZW52X3NlZzsKICBEV09SRCBjbWRsaW5lIFdJTkVfUEFDS0VEOwogIERXT1JEIGZjYjEgV0lORV9QQUNLRUQ7CiAgRFdPUkQgZmNiMiBXSU5FX1BBQ0tFRDsKICBXT1JEIGluaXRfc3A7CiAgV09SRCBpbml0X3NzOwogIFdPUkQgaW5pdF9pcDsKICBXT1JEIGluaXRfY3M7Cn0gRXhlY0Jsb2NrOwoKdHlwZWRlZiBzdHJ1Y3QgewogIFdPUkQgbG9hZF9zZWc7CiAgV09SRCByZWxfc2VnOwp9IE92ZXJsYXlCbG9jazsKCi8qIGdsb2JhbCB2YXJpYWJsZXMgKi8KCnBpZF90IGRvc3ZtX3BpZDsKCnN0YXRpYyBXT1JEIGluaXRfY3MsaW5pdF9pcCxpbml0X3NzLGluaXRfc3A7CnN0YXRpYyBIQU5ETEUgZG9zdm1fdGhyZWFkLCBsb29wX3RocmVhZDsKc3RhdGljIERXT1JEIGRvc3ZtX3RpZCwgbG9vcF90aWQ7CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2goIExQQ1NUUiBjbWR0YWlsLCBpbnQgbGVuZ3RoICk7CnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpOwoKc3RhdGljIHZvaWQgTVpfQ3JlYXRlUFNQKCBMUFZPSUQgbHBQU1AsIFdPUkQgZW52LCBXT1JEIHBhciApCnsKICBQREIxNipwc3A9bHBQU1A7CgogIHBzcC0+aW50MjA9MHgyMENEOyAvKiBpbnQgMjAgKi8KICAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiAgcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsgLyogRklYTUU6IHVzZSBhIHJlYWwgdmFsdWUgKi8KICAvKiBGSVhNRTogZGlzcGF0Y2hlciAqLwogIHBzcC0+c2F2ZWRpbnQyMiA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIyKTsKICBwc3AtPnNhdmVkaW50MjMgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyMyk7CiAgcHNwLT5zYXZlZGludDI0ID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjQpOwogIHBzcC0+cGFyZW50UFNQPXBhcjsKICBwc3AtPmVudmlyb25tZW50PWVudjsKICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIHZvaWQgTVpfRmlsbFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kdGFpbCwgaW50IGxlbmd0aCApCnsKICAgIFBEQjE2ICpwc3AgPSBscFBTUDsKCiAgICBpZihsZW5ndGggPiAxMjcpIAogICAgewogICAgICAgIFdBUk4oICJDb21tYW5kIHRhaWwgdHJ1bmNhdGVkISAobGVuZ3RoICVkKVxuIiwgbGVuZ3RoICk7CiAgICAgICAgbGVuZ3RoID0gMTI2OwogICAgfQoKICAgIHBzcC0+Y21kTGluZVswXSA9IGxlbmd0aDsKCiAgICAvKgogICAgICogTGVuZ3RoIG9mIGV4YWN0bHkgMTI3IGJ5dGVzIG1lYW5zIHRoYXQgZnVsbCBjb21tYW5kIGxpbmUgaXMgCiAgICAgKiBzdG9yZWQgaW4gZW52aXJvbm1lbnQgdmFyaWFibGUgQ01ETElORSBhbmQgUFNQIGNvbnRhaW5zIAogICAgICogY29tbWFuZCB0YWlsIHRydW5jYXRlZCB0byAxMjYgYnl0ZXMuCiAgICAgKi8KICAgIGlmKGxlbmd0aCA9PSAxMjcpCiAgICAgICAgbGVuZ3RoID0gMTI2OwoKICAgIGlmKGxlbmd0aCA+IDApCiAgICAgICAgbWVtbW92ZShwc3AtPmNtZExpbmUrMSwgY21kdGFpbCwgbGVuZ3RoKTsKCiAgICBwc3AtPmNtZExpbmVbbGVuZ3RoKzFdID0gJ1xyJzsKCiAgICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fR2V0QmxvY2soc3orc2l6ZW9mKFdPUkQpK3N0cmxlbihuYW1lKSsxLCZzZWcpOwogLyogZmlsbCBpdCAqLwogaWYgKGVudikgewogIG1lbWNweShlbnZibGssZW52LHN6KTsKIH0gZWxzZSBlbnZibGtbMF09MDsKIC8qIERPUyAzLng6IHRoZSBibG9jayBjb250YWlucyAxIGFkZGl0aW9uYWwgc3RyaW5nICovCiAqKFdPUkQqKShlbnZibGsrc3opPTE7CiAvKiBiZWluZyB0aGUgcHJvZ3JhbSBuYW1lIGl0c2VsZiAqLwogc3RyY3B5KGVudmJsaytzeitzaXplb2YoV09SRCksbmFtZSk7CiByZXR1cm4gc2VnOwp9CgpzdGF0aWMgQk9PTCBNWl9Jbml0TWVtb3J5KHZvaWQpCnsKICAgIC8qIGluaXRpYWxpemUgdGhlIG1lbW9yeSAqLwogICAgVFJBQ0UoIkluaXRpYWxpemluZyBET1MgbWVtb3J5IHN0cnVjdHVyZXNcbiIpOwogICAgRE9TTUVNX0luaXQoVFJVRSk7CiAgICBET1NERVZfSW5zdGFsbERPU0RldmljZXMoKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wgTVpfRG9Mb2FkSW1hZ2UoIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lLCBPdmVybGF5QmxvY2sgKm9ibGsgKQp7CiAgSU1BR0VfRE9TX0hFQURFUiBtel9oZWFkZXI7CiAgRFdPUkQgaW1hZ2Vfc3RhcnQsaW1hZ2Vfc2l6ZSxtaW5fc2l6ZSxtYXhfc2l6ZSxhdmFpbDsKICBCWVRFKnBzcF9zdGFydCwqbG9hZF9zdGFydCwqb2xkZW52OwogIGludCB4LCBvbGRfY29tPTAsIGFsbG9jOwogIFNFR1BUUiByZWxvYzsKICBXT1JEIGVudl9zZWcsIGxvYWRfc2VnLCByZWxfc2VnLCBvbGRwc3Bfc2VnOwogIERXT1JEIGxlbjsKCiAgaWYgKERPU1ZNX3BzcCkgewogICAgLyogRE9TIHByb2Nlc3MgYWxyZWFkeSBydW5uaW5nLCBpbmhlcml0IGZyb20gaXQgKi8KICAgIFBEQjE2KiBwYXJfcHNwID0gKFBEQjE2KikoKERXT1JEKURPU1ZNX3BzcCA8PCA0KTsKICAgIGFsbG9jPTA7CiAgICBvbGRlbnYgPSAoTFBCWVRFKSgoRFdPUkQpcGFyX3BzcC0+ZW52aXJvbm1lbnQgPDwgNCk7CiAgICBvbGRwc3Bfc2VnID0gRE9TVk1fcHNwOwogIH0gZWxzZSB7CiAgICAvKiBhbGxvY2F0ZSBuZXcgRE9TIHByb2Nlc3MsIGluaGVyaXRpbmcgZnJvbSBXaW5lIGVudmlyb25tZW50ICovCiAgICBhbGxvYz0xOwogICAgb2xkZW52ID0gR2V0RW52aXJvbm1lbnRTdHJpbmdzQSgpOwogICAgb2xkcHNwX3NlZyA9IDA7CiAgfQoKIFNldEZpbGVQb2ludGVyKGhGaWxlLDAsTlVMTCxGSUxFX0JFR0lOKTsKIGlmICggICAhUmVhZEZpbGUoaEZpbGUsJm16X2hlYWRlcixzaXplb2YobXpfaGVhZGVyKSwmbGVuLE5VTEwpCiAgICAgfHwgbGVuICE9IHNpemVvZihtel9oZWFkZXIpCiAgICAgfHwgbXpfaGVhZGVyLmVfbWFnaWMgIT0gSU1BR0VfRE9TX1NJR05BVFVSRSkgewogIGNoYXIgKnAgPSBzdHJyY2hyKCBmaWxlbmFtZSwgJy4nICk7CiAgaWYgKCFwIHx8IHN0cmNhc2VjbXAoIHAsICIuY29tIiApKSAgLyogY2hlY2sgZm9yIC5DT00gZXh0ZW5zaW9uICovCiAgewogICAgICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICB9CiAgb2xkX2NvbT0xOyAvKiBhc3N1bWUgLkNPTSBmaWxlICovCiAgaW1hZ2Vfc3RhcnQ9MDsKICBpbWFnZV9zaXplPUdldEZpbGVTaXplKGhGaWxlLE5VTEwpOwogIG1pbl9zaXplPTB4MTAwMDA7IG1heF9zaXplPTB4MTAwMDAwOwogIG16X2hlYWRlci5lX2NybGM9MDsKICBtel9oZWFkZXIuZV9zcz0wOyBtel9oZWFkZXIuZV9zcD0weEZGRkU7CiAgbXpfaGVhZGVyLmVfY3M9MDsgbXpfaGVhZGVyLmVfaXA9MHgxMDA7CiB9IGVsc2UgewogIC8qIGNhbGN1bGF0ZSBsb2FkIHNpemUgKi8KICBpbWFnZV9zdGFydD1tel9oZWFkZXIuZV9jcGFyaGRyPDw0OwogIGltYWdlX3NpemU9bXpfaGVhZGVyLmVfY3A8PDk7IC8qIHBhZ2VzIGFyZSA1MTIgYnl0ZXMgKi8KICBpZiAoKG16X2hlYWRlci5lX2NibHAhPTApJiYobXpfaGVhZGVyLmVfY2JscCE9NCkpIGltYWdlX3NpemUtPTUxMi1tel9oZWFkZXIuZV9jYmxwOwogIGltYWdlX3NpemUtPWltYWdlX3N0YXJ0OwogIG1pbl9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9taW5hbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKICBtYXhfc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWF4YWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiB9CgogIGlmIChhbGxvYykgTVpfSW5pdE1lbW9yeSgpOwoKICBpZiAob2JsaykgewogICAgLyogbG9hZCBvdmVybGF5IGludG8gcHJlYWxsb2NhdGVkIG1lbW9yeSAqLwogICAgbG9hZF9zZWc9b2Jsay0+bG9hZF9zZWc7CiAgICByZWxfc2VnPW9ibGstPnJlbF9zZWc7CiAgICBsb2FkX3N0YXJ0PShMUEJZVEUpKChEV09SRClsb2FkX3NlZzw8NCk7CiAgfSBlbHNlIHsKICAgIC8qIGFsbG9jYXRlIGVudmlyb25tZW50IGJsb2NrICovCiAgICBlbnZfc2VnPU1aX0luaXRFbnZpcm9ubWVudChvbGRlbnYsIGZpbGVuYW1lKTsKCiAgICAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBleGVjdXRhYmxlICovCiAgICBUUkFDRSgiQWxsb2NhdGluZyBET1MgbWVtb3J5IChtaW49JWxkLCBtYXg9JWxkKVxuIixtaW5fc2l6ZSxtYXhfc2l6ZSk7CiAgICBhdmFpbD1ET1NNRU1fQXZhaWxhYmxlKCk7CiAgICBpZiAoYXZhaWw8bWluX3NpemUpIHsKICAgICAgRVJSKCJpbnN1ZmZpY2llbnQgRE9TIG1lbW9yeVxuIik7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgIH0KICAgIGlmIChhdmFpbD5tYXhfc2l6ZSkgYXZhaWw9bWF4X3NpemU7CiAgICBwc3Bfc3RhcnQ9RE9TTUVNX0dldEJsb2NrKGF2YWlsLCZET1NWTV9wc3ApOwogICAgaWYgKCFwc3Bfc3RhcnQpIHsKICAgICAgRVJSKCJlcnJvciBhbGxvY2F0aW5nIERPUyBtZW1vcnlcbiIpOwogICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgICB9CiAgICBsb2FkX3NlZz1ET1NWTV9wc3ArKG9sZF9jb20/MDpQU1BfU0laRSk7CiAgICByZWxfc2VnPWxvYWRfc2VnOwogICAgbG9hZF9zdGFydD1wc3Bfc3RhcnQrKFBTUF9TSVpFPDw0KTsKICAgIE1aX0NyZWF0ZVBTUChwc3Bfc3RhcnQsIGVudl9zZWcsIG9sZHBzcF9zZWcpOwogIH0KCiAvKiBsb2FkIGV4ZWN1dGFibGUgaW1hZ2UgKi8KIFRSQUNFKCJsb2FkaW5nIERPUyAlcyBpbWFnZSwgJTA4bHggYnl0ZXNcbiIsb2xkX2NvbT8iQ09NIjoiRVhFIixpbWFnZV9zaXplKTsKIFNldEZpbGVQb2ludGVyKGhGaWxlLGltYWdlX3N0YXJ0LE5VTEwsRklMRV9CRUdJTik7CiBpZiAoIVJlYWRGaWxlKGhGaWxlLGxvYWRfc3RhcnQsaW1hZ2Vfc2l6ZSwmbGVuLE5VTEwpIHx8IGxlbiAhPSBpbWFnZV9zaXplKSB7CiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogIGdvdG8gbG9hZF9lcnJvcjsKIH0KCiBpZiAobXpfaGVhZGVyLmVfY3JsYykgewogIC8qIGxvYWQgcmVsb2NhdGlvbiB0YWJsZSAqLwogIFRSQUNFKCJsb2FkaW5nIERPUyBFWEUgcmVsb2NhdGlvbiB0YWJsZSwgJWQgZW50cmllc1xuIixtel9oZWFkZXIuZV9jcmxjKTsKICAvKiBGSVhNRTogaXMgdGhpcyB0b28gc2xvdyB3aXRob3V0IHJlYWQgYnVmZmVyaW5nPyAqLwogIFNldEZpbGVQb2ludGVyKGhGaWxlLG16X2hlYWRlci5lX2xmYXJsYyxOVUxMLEZJTEVfQkVHSU4pOwogIGZvciAoeD0wOyB4PG16X2hlYWRlci5lX2NybGM7IHgrKykgewogICBpZiAoIVJlYWRGaWxlKGhGaWxlLCZyZWxvYyxzaXplb2YocmVsb2MpLCZsZW4sTlVMTCkgfHwgbGVuICE9IHNpemVvZihyZWxvYykpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgfQogICAqKFdPUkQqKVNFR1BUUjE2KGxvYWRfc3RhcnQscmVsb2MpKz1yZWxfc2VnOwogIH0KIH0KCiAgaWYgKCFvYmxrKSB7CiAgICBpbml0X2NzID0gbG9hZF9zZWcrbXpfaGVhZGVyLmVfY3M7CiAgICBpbml0X2lwID0gbXpfaGVhZGVyLmVfaXA7CiAgICBpbml0X3NzID0gbG9hZF9zZWcrbXpfaGVhZGVyLmVfc3M7CiAgICBpbml0X3NwID0gbXpfaGVhZGVyLmVfc3A7CgogICAgVFJBQ0UoImVudHJ5IHBvaW50OiAlMDR4OiUwNHhcbiIsaW5pdF9jcyxpbml0X2lwKTsKICB9CgogIGlmIChhbGxvYyAmJiAhTVpfSW5pdFRhc2soKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0dFTl9GQUlMVVJFKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIHJldHVybiBUUlVFOwoKbG9hZF9lcnJvcjoKICBET1NWTV9wc3AgPSBvbGRwc3Bfc2VnOwoKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJd2luZV9sb2FkX2Rvc19leGUgKFdJTkVET1MuQCkKICoKICogQ2FsbGVkIGZyb20gV2luZVZETSB3aGVuIGEgbmV3IHJlYWwtbW9kZSBET1MgcHJvY2VzcyBpcyBzdGFydGVkLgogKiBMb2FkcyBET1MgcHJvZ3JhbSBpbnRvIG1lbW9yeSBhbmQgZXhlY3V0ZXMgdGhlIHByb2dyYW0uCiAqLwp2b2lkIFdJTkFQSSB3aW5lX2xvYWRfZG9zX2V4ZSggTFBDU1RSIGZpbGVuYW1lLCBMUENTVFIgY21kbGluZSApCnsKICAgIGNoYXIgZG9zX2NtZHRhaWxbMTI2XTsKICAgIGludCAgZG9zX2xlbmd0aCA9IDA7CgogICAgSEFORExFIGhGaWxlID0gQ3JlYXRlRmlsZUEoIGZpbGVuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm47CiAgICBET1NWTV9pc2Rvc2V4ZSA9IFRSVUU7CgogICAgaWYoY21kbGluZSAmJiAqY21kbGluZSkKICAgIHsKICAgICAgICBkb3NfbGVuZ3RoID0gc3RybGVuKGNtZGxpbmUpOwogICAgICAgIG1lbW1vdmUoIGRvc19jbWR0YWlsICsgMSwgY21kbGluZSwgCiAgICAgICAgICAgICAgICAgKGRvc19sZW5ndGggPCAxMjUpID8gZG9zX2xlbmd0aCA6IDEyNSApOwoKICAgICAgICAvKiBOb24tZW1wdHkgY29tbWFuZCB0YWlsIGFsd2F5cyBzdGFydHMgd2l0aCBhdCBsZWFzdCBvbmUgc3BhY2UuICovCiAgICAgICAgZG9zX2NtZHRhaWxbMF0gPSAnICc7CiAgICAgICAgZG9zX2xlbmd0aCsrOwoKICAgICAgICAvKgogICAgICAgICAqIElmIGNvbW1hbmQgdGFpbCBpcyBsb25nZXIgdGhhbiAxMjYgY2hhcmFjdGVycywKICAgICAgICAgKiBzZXQgdGFpbCBsZW5ndGggdG8gMTI3IGFuZCBmaWxsIENNRExJTkUgZW52aXJvbm1lbnQgdmFyaWFibGUgCiAgICAgICAgICogd2l0aCBmdWxsIGNvbW1hbmQgbGluZSAodGhpcyBpbmNsdWRlcyBmaWxlbmFtZSkuCiAgICAgICAgICovCiAgICAgICAgaWYgKGRvc19sZW5ndGggPiAxMjYpCiAgICAgICAgewogICAgICAgICAgICBjaGFyICpjbWQgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvc19sZW5ndGggKyBzdHJsZW4oZmlsZW5hbWUpICsgNCApOwogICAgICAgICAgICBjaGFyICpwdHIgPSBjbWQ7CgogICAgICAgICAgICBpZiAoIWNtZCkKICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEFwcGVuZCBmaWxlbmFtZS4gSWYgcGF0aCBpbmNsdWRlcyBzcGFjZXMsIHF1b3RlIHRoZSBwYXRoLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHN0cmNocihmaWxlbmFtZSwgJyAnKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgKnB0cisrID0gJ1wiJzsKICAgICAgICAgICAgICAgIHN0cmNweSggcHRyLCBmaWxlbmFtZSApOwogICAgICAgICAgICAgICAgcHRyICs9IHN0cmxlbihmaWxlbmFtZSk7ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgKnB0cisrID0gJ1wiJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweSggcHRyLCBmaWxlbmFtZSApOwogICAgICAgICAgICAgICAgcHRyICs9IHN0cmxlbihmaWxlbmFtZSk7ICAKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogQXBwZW5kIGNvbW1hbmQgdGFpbC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChjbWRsaW5lWzBdICE9ICcgJykKICAgICAgICAgICAgICAgICpwdHIrKyA9ICcgJzsKICAgICAgICAgICAgc3RyY3B5KCBwdHIsIGNtZGxpbmUgKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNldCBlbnZpcm9ubWVudCB2YXJpYWJsZS4gVGhpcyB3aWxsIGJlIHBhc3NlZCB0bwogICAgICAgICAgICAgKiBuZXcgRE9TIHByb2Nlc3MuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIVNldEVudmlyb25tZW50VmFyaWFibGVBKCAiQ01ETElORSIsIGNtZCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjbWQgKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY21kICk7CiAgICAgICAgICAgIGRvc19sZW5ndGggPSAxMjc7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBOVUxMICkpIAogICAgICAgIE1aX0xhdW5jaCggZG9zX2NtZHRhaWwsIGRvc19sZW5ndGggKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGVjCiAqCiAqIHRoaXMgbWF5IG9ubHkgYmUgY2FsbGVkIGZyb20gZXhpc3RpbmcgRE9TIHByb2Nlc3NlcwogKi8KQk9PTCBXSU5BUEkgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIERXT1JEIGJpblR5cGU7CiAgU1RBUlRVUElORk9BIHN0OwogIFBST0NFU1NfSU5GT1JNQVRJT04gcGU7CiAgSEFORExFIGhGaWxlOwoKICBCT09MIHJldCA9IEZBTFNFOwoKICBpZighR2V0QmluYXJ5VHlwZUEoZmlsZW5hbWUsICZiaW5UeXBlKSkgICAvKiBkZXRlcm1pbmUgd2hhdCBraW5kIG9mIGJpbmFyeSB0aGlzIGlzICovCiAgewogICAgcmV0dXJuIEZBTFNFOyAvKiBiaW5hcnkgaXMgbm90IGFuIGV4ZWN1dGFibGUgKi8KICB9CgogIC8qIGhhbmRsZSBub24tZG9zIGV4ZWN1dGFibGVzICovCiAgaWYoYmluVHlwZSAhPSBTQ1NfRE9TX0JJTkFSWSkKICB7CiAgICBpZihmdW5jID09IDApIC8qIGxvYWQgYW5kIGV4ZWN1dGUgKi8KICAgIHsKICAgICAgTFBCWVRFIGZ1bGxDbWRMaW5lOwogICAgICBXT1JEIGZ1bGxDbWRMZW5ndGg7CiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgICBFeGVjQmxvY2sgKmJsayA9IChFeGVjQmxvY2sgKilwYXJhbWJsazsKICAgICAgTFBCWVRFIGNtZGxpbmUgPSBQVFJfUkVBTF9UT19MSU4oU0VMRUNUT1JPRihibGstPmNtZGxpbmUpLE9GRlNFVE9GKGJsay0+Y21kbGluZSkpOwogICAgICBMUEJZVEUgZW52YmxvY2sgPSBQVFJfUkVBTF9UT19MSU4ocHNwLT5lbnZpcm9ubWVudCwgMCk7CiAgICAgIGludCAgICBjbWRMZW5ndGggPSBjbWRsaW5lWzBdOwoKICAgICAgLyoKICAgICAgICogSWYgY21kTGVuZ3RoIGlzIDEyNywgY29tbWFuZCB0YWlsIGlzIHRydW5jYXRlZCBhbmQgZW52aXJvbm1lbnQgCiAgICAgICAqIHZhcmlhYmxlIENNRExJTkUgc2hvdWxkIGNvbnRhaW4gZnVsbCBjb21tYW5kIGxpbmUgCiAgICAgICAqICh0aGlzIGluY2x1ZGVzIGZpbGVuYW1lKS4KICAgICAgICovCiAgICAgIGlmIChjbWRMZW5ndGggPT0gMTI3KQogICAgICB7CiAgICAgICAgICBGSVhNRSggIkNNRExJTkUgYXJndW1lbnQgcGFzc2luZyBpcyB1bmltcGxlbWVudGVkLlxuIiApOwogICAgICAgICAgY21kTGVuZ3RoID0gMTI2OyAvKiBGSVhNRSAqLwogICAgICB9CgogICAgICBmdWxsQ21kTGVuZ3RoID0gKHN0cmxlbihmaWxlbmFtZSkgKyAxKSArIGNtZExlbmd0aCArIDE7IC8qIGZpbGVuYW1lICsgc3BhY2UgKyBjbWRsaW5lICsgdGVybWluYXRpbmcgbnVsbCBjaGFyYWN0ZXIgKi8KCiAgICAgIGZ1bGxDbWRMaW5lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGZ1bGxDbWRMZW5ndGgpOwogICAgICBpZighZnVsbENtZExpbmUpIHJldHVybiBGQUxTRTsgLyogcmV0dXJuIGZhbHNlIG9uIG1lbW9yeSBhbGxvYyBmYWlsdXJlICovCgogICAgICAvKiBidWlsZCB0aGUgZnVsbCBjb21tYW5kIGxpbmUgZnJvbSB0aGUgZXhlY3V0YWJsZSBmaWxlIGFuZCB0aGUgY29tbWFuZCBsaW5lIGJlaW5nIHBhc3NlZCBpbiAqLwogICAgICBzbnByaW50ZihmdWxsQ21kTGluZSwgZnVsbENtZExlbmd0aCwgIiVzICIsIGZpbGVuYW1lKTsgLyogc3RhcnQgb2ZmIHdpdGggdGhlIGV4ZWN1dGFibGUgZmlsZW5hbWUgYW5kIGEgc3BhY2UgKi8KICAgICAgbWVtY3B5KGZ1bGxDbWRMaW5lICsgc3RybGVuKGZ1bGxDbWRMaW5lKSwgY21kbGluZSArIDEsIGNtZExlbmd0aCk7IC8qIGFwcGVuZCBjbWRsaW5lIG9udG8gdGhlIGVuZCAqLwogICAgICBmdWxsQ21kTGluZVtmdWxsQ21kTGVuZ3RoIC0gMV0gPSAwOyAvKiBudWxsIHRlcm1pbmF0ZSBzdHJpbmcgKi8KCiAgICAgIFplcm9NZW1vcnkgKCZzdCwgc2l6ZW9mKFNUQVJUVVBJTkZPQSkpOwogICAgICBzdC5jYiA9IHNpemVvZihTVEFSVFVQSU5GT0EpOwogICAgICByZXQgPSBDcmVhdGVQcm9jZXNzQSAoTlVMTCwgZnVsbENtZExpbmUsIE5VTEwsIE5VTEwsIFRSVUUsIDAsIGVudmJsb2NrLCBOVUxMLCAmc3QsICZwZSk7CgogICAgICAvKiB3YWl0IGZvciB0aGUgYXBwIHRvIGZpbmlzaCBhbmQgY2xlYW4gdXAgUFJPQ0VTU19JTkZPUk1BVElPTiBoYW5kbGVzICovCiAgICAgIGlmKHJldCkKICAgICAgewogICAgICAgIFdhaXRGb3JTaW5nbGVPYmplY3QocGUuaFByb2Nlc3MsIElORklOSVRFKTsgIC8qIHdhaXQgaGVyZSB1bnRpbCB0aGUgY2hpbGQgcHJvY2VzcyBpcyBjb21wbGV0ZSAqLwogICAgICAgIENsb3NlSGFuZGxlKHBlLmhQcm9jZXNzKTsKICAgICAgICBDbG9zZUhhbmRsZShwZS5oVGhyZWFkKTsKICAgICAgfQoKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZnVsbENtZExpbmUpOyAgLyogZnJlZSB0aGUgbWVtb3J5IHdlIGFsbG9jYXRlZCAqLwogICAgfQogICAgZWxzZQogICAgewogICAgICBGSVhNRSgiRVhFQyB0eXBlIG9mICVkIG5vdCBpbXBsZW1lbnRlZCBmb3Igbm9uLWRvcyBleGVjdXRhYmxlc1xuIiwgZnVuYyk7CiAgICAgIHJldCA9IEZBTFNFOwogICAgfQoKICAgIHJldHVybiByZXQ7CiAgfSAvKiBpZihiaW5UeXBlICE9IFNDU19ET1NfQklOQVJZKSAqLwoKCiAgLyogaGFuZGxlIGRvcyBleGVjdXRhYmxlcyAqLwoKICBoRmlsZSA9IENyZWF0ZUZpbGVBKCBmaWxlbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCgkJCSAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCk7CiAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm4gRkFMU0U7CgogIHN3aXRjaCAoZnVuYykgewogIGNhc2UgMDogLyogbG9hZCBhbmQgZXhlY3V0ZSAqLwogIGNhc2UgMTogLyogbG9hZCBidXQgZG9uJ3QgZXhlY3V0ZSAqLwogICAgewogICAgICAvKiBzYXZlIGN1cnJlbnQgcHJvY2VzcydzIHJldHVybiBTUzpTUCBub3cgKi8KICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIHBzcC0+c2F2ZVN0YWNrID0gKERXT1JEKU1BS0VTRUdQVFIoY29udGV4dC0+U2VnU3MsIExPV09SRChjb250ZXh0LT5Fc3ApKTsKICAgIH0KICAgIHJldCA9IE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIE5VTEwgKTsKICAgIGlmIChyZXQpIHsKICAgICAgLyogTVpfTG9hZEltYWdlIGNyZWF0ZWQgYSBuZXcgUFNQIGFuZCBsb2FkZWQgbmV3IHZhbHVlcyBpbnRvIGl0LAogICAgICAgKiBsZXQncyB3b3JrIG9uIHRoZSBuZXcgdmFsdWVzIG5vdyAqLwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKURPU1ZNX3BzcCA8PCA0KTsKICAgICAgRXhlY0Jsb2NrICpibGsgPSAoRXhlY0Jsb2NrICopcGFyYW1ibGs7CiAgICAgIExQQllURSBjbWRsaW5lID0gUFRSX1JFQUxfVE9fTElOKFNFTEVDVE9ST0YoYmxrLT5jbWRsaW5lKSxPRkZTRVRPRihibGstPmNtZGxpbmUpKTsKCiAgICAgIC8qIEZpcnN0IGNoYXJhY3RlciBjb250YWlucyB0aGUgbGVuZ3RoIG9mIHRoZSBjb21tYW5kIGxpbmUuICovCiAgICAgIE1aX0ZpbGxQU1AocHNwX3N0YXJ0LCBjbWRsaW5lICsgMSwgY21kbGluZVswXSk7CgogICAgICAvKiB0aGUgbGFtZSBNUy1ET1MgZW5naW5lZXJzIGRlY2lkZWQgdGhhdCB0aGUgcmV0dXJuIGFkZHJlc3Mgc2hvdWxkIGJlIGluIGludDIyICovCiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIyLCAoRkFSUFJPQzE2KU1BS0VTRUdQVFIoY29udGV4dC0+U2VnQ3MsIExPV09SRChjb250ZXh0LT5FaXApKSk7CiAgICAgIGlmIChmdW5jKSB7CgkvKiBkb24ndCBleGVjdXRlLCBqdXN0IHJldHVybiBzdGFydHVwIHN0YXRlICovCglibGstPmluaXRfY3MgPSBpbml0X2NzOwoJYmxrLT5pbml0X2lwID0gaW5pdF9pcDsKCWJsay0+aW5pdF9zcyA9IGluaXRfc3M7CglibGstPmluaXRfc3AgPSBpbml0X3NwOwogICAgICB9IGVsc2UgewoJLyogZXhlY3V0ZSBieSBtYWtpbmcgdXMgcmV0dXJuIHRvIG5ldyBwcm9jZXNzICovCgljb250ZXh0LT5TZWdDcyA9IGluaXRfY3M7Cgljb250ZXh0LT5FaXAgICA9IGluaXRfaXA7Cgljb250ZXh0LT5TZWdTcyA9IGluaXRfc3M7Cgljb250ZXh0LT5Fc3AgICA9IGluaXRfc3A7Cgljb250ZXh0LT5TZWdEcyA9IERPU1ZNX3BzcDsKCWNvbnRleHQtPlNlZ0VzID0gRE9TVk1fcHNwOwoJY29udGV4dC0+RWF4ICAgPSAwOwogICAgICB9CiAgICB9CiAgICBicmVhazsKICBjYXNlIDM6IC8qIGxvYWQgb3ZlcmxheSAqLwogICAgewogICAgICBPdmVybGF5QmxvY2sgKmJsayA9IChPdmVybGF5QmxvY2sgKilwYXJhbWJsazsKICAgICAgcmV0ID0gTVpfRG9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgYmxrICk7CiAgICB9CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgRklYTUUoIkVYRUMgbG9hZCB0eXBlICVkIG5vdCBpbXBsZW1lbnRlZFxuIiwgZnVuYyk7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GVU5DVElPTik7CiAgICBicmVhazsKICB9CiAgQ2xvc2VIYW5kbGUoaEZpbGUpOwogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQWxsb2NEUE1JVGFzawogKi8Kdm9pZCBXSU5BUEkgTVpfQWxsb2NEUE1JVGFzayggdm9pZCApCnsKICBNWl9Jbml0TWVtb3J5KCk7CiAgTVpfSW5pdFRhc2soKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9SdW5JblRocmVhZAogKi8Kdm9pZCBXSU5BUEkgTVpfUnVuSW5UaHJlYWQoIFBBUENGVU5DIHByb2MsIFVMT05HX1BUUiBhcmcgKQp7CiAgaWYgKGxvb3BfdGhyZWFkKSB7CiAgICBET1NfU1BDIHNwYzsKICAgIEhBTkRMRSBldmVudDsKCiAgICBzcGMucHJvYyA9IHByb2M7CiAgICBzcGMuYXJnID0gYXJnOwogICAgZXZlbnQgPSBDcmVhdGVFdmVudEEoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogICAgUG9zdFRocmVhZE1lc3NhZ2VBKGxvb3BfdGlkLCBXTV9VU0VSLCAoV1BBUkFNKWV2ZW50LCAoTFBBUkFNKSZzcGMpOwogICAgV2FpdEZvclNpbmdsZU9iamVjdChldmVudCwgSU5GSU5JVEUpOwogICAgQ2xvc2VIYW5kbGUoZXZlbnQpOwogIH0gZWxzZQogICAgcHJvYyhhcmcpOwp9CgpzdGF0aWMgRFdPUkQgV0lOQVBJIE1aX0RPU1ZNKCBMUFZPSUQgbHBFeHRyYSApCnsKICBDT05URVhUIGNvbnRleHQ7CiAgRFdPUkQgcmV0OwoKICBkb3N2bV9waWQgPSBnZXRwaWQoKTsKCiAgbWVtc2V0KCAmY29udGV4dCwgMCwgc2l6ZW9mKGNvbnRleHQpICk7CiAgY29udGV4dC5TZWdDcyAgPSBpbml0X2NzOwogIGNvbnRleHQuRWlwICAgID0gaW5pdF9pcDsKICBjb250ZXh0LlNlZ1NzICA9IGluaXRfc3M7CiAgY29udGV4dC5Fc3AgICAgPSBpbml0X3NwOwogIGNvbnRleHQuU2VnRHMgID0gRE9TVk1fcHNwOwogIGNvbnRleHQuU2VnRXMgID0gRE9TVk1fcHNwOwogIGNvbnRleHQuRUZsYWdzID0gMHgwMDA4MDAwMDsgIC8qIHZpcnR1YWwgaW50ZXJydXB0IGZsYWcgKi8KICBET1NWTV9TZXRUaW1lcigweDEwMDAwKTsKICByZXQgPSBET1NWTV9FbnRlciggJmNvbnRleHQgKTsKCiAgZG9zdm1fcGlkID0gMDsKICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgQk9PTCBNWl9Jbml0VGFzayh2b2lkKQp7CiAgaWYgKCFEdXBsaWNhdGVIYW5kbGUoR2V0Q3VycmVudFByb2Nlc3MoKSwgR2V0Q3VycmVudFRocmVhZCgpLAogICAgICAgICAgICAgICAgICAgICAgIEdldEN1cnJlbnRQcm9jZXNzKCksICZsb29wX3RocmVhZCwKICAgICAgICAgICAgICAgICAgICAgICAwLCBGQUxTRSwgRFVQTElDQVRFX1NBTUVfQUNDRVNTKSkKICAgIHJldHVybiBGQUxTRTsKICBkb3N2bV90aHJlYWQgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgTVpfRE9TVk0sIE5VTEwsIENSRUFURV9TVVNQRU5ERUQsICZkb3N2bV90aWQpOwogIGlmICghZG9zdm1fdGhyZWFkKSB7CiAgICBDbG9zZUhhbmRsZShsb29wX3RocmVhZCk7CiAgICBsb29wX3RocmVhZCA9IDA7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogIGxvb3BfdGlkID0gR2V0Q3VycmVudFRocmVhZElkKCk7CiAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCggTFBDU1RSIGNtZHRhaWwsIGludCBsZW5ndGggKQp7CiAgVERCICpwVGFzayA9IEdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogIEJZVEUgKnBzcF9zdGFydCA9IFBUUl9SRUFMX1RPX0xJTiggRE9TVk1fcHNwLCAwICk7CiAgRFdPUkQgcnY7CiAgU1lTTEVWRUwgKmxvY2s7CgogIE1aX0ZpbGxQU1AocHNwX3N0YXJ0LCBjbWR0YWlsLCBsZW5ndGgpOwogIHBUYXNrLT5mbGFncyB8PSBUREJGX1dJTk9MREFQOwoKICAvKiBEVEEgaXMgc2V0IHRvIFBTUDowMDgwaCB3aGVuIGEgcHJvZ3JhbSBpcyBzdGFydGVkLiAqLwogIHBUYXNrLT5kdGEgPSBNQUtFU0VHUFRSKCBET1NWTV9wc3AsIDB4ODAgKTsKCiAgR2V0cFdpbjE2TG9jayggJmxvY2sgKTsKICBfTGVhdmVTeXNMZXZlbCggbG9jayApOwoKICBSZXN1bWVUaHJlYWQoZG9zdm1fdGhyZWFkKTsKICBydiA9IERPU1ZNX0xvb3AoZG9zdm1fdGhyZWFkKTsKCiAgQ2xvc2VIYW5kbGUoZG9zdm1fdGhyZWFkKTsKICBkb3N2bV90aHJlYWQgPSAwOyBkb3N2bV90aWQgPSAwOwogIENsb3NlSGFuZGxlKGxvb3BfdGhyZWFkKTsKICBsb29wX3RocmVhZCA9IDA7IGxvb3BfdGlkID0gMDsKCiAgVkdBX0NsZWFuKCk7CiAgRXhpdFRocmVhZChydik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhpdAogKi8Kdm9pZCBXSU5BUEkgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgaWYgKERPU1ZNX3BzcCkgewogICAgV09SRCBwc3Bfc2VnID0gY3NfcHNwID8gY29udGV4dC0+U2VnQ3MgOiBET1NWTV9wc3A7CiAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKXBzcF9zZWcgPDwgNCk7CiAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgV09SRCBwYXJwc3AgPSBwc3AtPnBhcmVudFBTUDsgLyogY2hlY2sgZm9yIHBhcmVudCBET1MgcHJvY2VzcyAqLwogICAgaWYgKHBhcnBzcCkgewogICAgICAvKiByZXRyaWV2ZSBwYXJlbnQncyByZXR1cm4gYWRkcmVzcyAqLwogICAgICBGQVJQUk9DMTYgcmV0YWRkciA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIyKTsKICAgICAgLyogcmVzdG9yZSBpbnRlcnJ1cHRzICovCiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIyLCBwc3AtPnNhdmVkaW50MjIpOwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMywgcHNwLT5zYXZlZGludDIzKTsKICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjQsIHBzcC0+c2F2ZWRpbnQyNCk7CiAgICAgIC8qIEZJWE1FOiBkZWFsbG9jYXRlIGZpbGUgaGFuZGxlcyBldGMgKi8KICAgICAgLyogZnJlZSBwcm9jZXNzJ3MgYXNzb2NpYXRlZCBtZW1vcnkKICAgICAgICogRklYTUU6IHdhbGsgbWVtb3J5IGFuZCBkZWFsbG9jYXRlIGFsbCBibG9ja3Mgb3duZWQgYnkgcHJvY2VzcyAqLwogICAgICBET1NNRU1fRnJlZUJsb2NrKCBQVFJfUkVBTF9UT19MSU4ocHNwLT5lbnZpcm9ubWVudCwwKSApOwogICAgICBET1NNRU1fRnJlZUJsb2NrKCBQVFJfUkVBTF9UT19MSU4oRE9TVk1fcHNwLDApICk7CiAgICAgIC8qIHN3aXRjaCB0byBwYXJlbnQncyBQU1AgKi8KICAgICAgRE9TVk1fcHNwID0gcGFycHNwOwogICAgICBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcGFycHNwIDw8IDQpOwogICAgICBwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIC8qIG5vdyByZXR1cm4gdG8gcGFyZW50ICovCiAgICAgIERPU1ZNX3JldHZhbCA9IHJldHZhbDsKICAgICAgY29udGV4dC0+U2VnQ3MgPSBTRUxFQ1RPUk9GKHJldGFkZHIpOwogICAgICBjb250ZXh0LT5FaXAgICA9IE9GRlNFVE9GKHJldGFkZHIpOwogICAgICBjb250ZXh0LT5TZWdTcyA9IFNFTEVDVE9ST0YocHNwLT5zYXZlU3RhY2spOwogICAgICBjb250ZXh0LT5Fc3AgICA9IE9GRlNFVE9GKHBzcC0+c2F2ZVN0YWNrKTsKICAgICAgcmV0dXJuOwogICAgfSBlbHNlCiAgICAgIFRSQUNFKCJraWxsaW5nIERPUyB0YXNrXG4iKTsKICB9CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0N1cnJlbnQKICovCkJPT0wgV0lOQVBJIE1aX0N1cnJlbnQoIHZvaWQgKQp7CiAgcmV0dXJuIChkb3N2bV9waWQgIT0gMCk7IC8qIEZJWE1FOiBkbyBhIGJldHRlciBjaGVjayAqLwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXdpbmVfbG9hZF9kb3NfZXhlIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSB3aW5lX2xvYWRfZG9zX2V4ZSggTFBDU1RSIGZpbGVuYW1lLCBMUENTVFIgY21kbGluZSApCnsKICBXQVJOKCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIHBsYXRmb3JtXG4iKTsKICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhlYwogKi8KQk9PTCBXSU5BUEkgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIC8qIGNhbid0IGhhcHBlbiAqLwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQWxsb2NEUE1JVGFzawogKi8Kdm9pZCBXSU5BUEkgTVpfQWxsb2NEUE1JVGFzayggdm9pZCApCnsKICAgIEVSUigiQWN0dWFsIHJlYWwtbW9kZSBjYWxscyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm0hXG4iKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9SdW5JblRocmVhZAogKi8Kdm9pZCBXSU5BUEkgTVpfUnVuSW5UaHJlYWQoIFBBUENGVU5DIHByb2MsIFVMT05HX1BUUiBhcmcgKQp7CiAgICBwcm9jKGFyZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhpdAogKi8Kdm9pZCBXSU5BUEkgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQ3VycmVudAogKi8KQk9PTCBXSU5BUEkgTVpfQ3VycmVudCggdm9pZCApCnsKICAgIHJldHVybiBGQUxTRTsKfQoKI2VuZGlmIC8qICFNWl9TVVBQT1JURUQgKi8K