LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICogTm90ZTogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmZGVmIEhBVkVfU1lTX1NUQVRfSAojIGluY2x1ZGUgPHN5cy9zdGF0Lmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TWVNfVElNRV9ICiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmUvd2luYmFzZTE2LmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc3ZtLmgiCiNpbmNsdWRlICJ2Z2EuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CgpzdGF0aWMgQk9PTCBET1NWTV9pc2Rvc2V4ZTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgIERPU1ZNX0lzV2luMTYKICogCiAqIFJldHVybiBUUlVFIGlmIHdlIGFyZSBpbiBXaW5kb3dzIHByb2Nlc3MuCiAqLwpCT09MIERPU1ZNX0lzV2luMTYodm9pZCkKewogIHJldHVybiBET1NWTV9pc2Rvc2V4ZSA/IEZBTFNFIDogVFJVRTsKfQoKI2lmZGVmIE1aX1NVUFBPUlRFRAoKI2lmZGVmIEhBVkVfU1lTX01NQU5fSAojIGluY2x1ZGUgPHN5cy9tbWFuLmg+CiNlbmRpZgoKLyogZGVmaW5lIHRoaXMgdG8gdHJ5IG1hcHBpbmcgdGhyb3VnaCAvcHJvYy9waWQvbWVtIGluc3RlYWQgb2YgYSB0ZW1wIGZpbGUsCiAgIGJ1dCBMaW51cyBkb2Vzbid0IGxpa2UgbW1hcHBpbmcgL3Byb2MvcGlkL21lbSwgc28gaXQgZG9lc24ndCB3b3JrIGZvciBtZSAqLwojdW5kZWYgTVpfTUFQU0VMRgoKI2RlZmluZSBCSU9TX0RBVEFfU0VHTUVOVCAweDQwCiNkZWZpbmUgUFNQX1NJWkUgMHgxMAoKI2RlZmluZSBTRUcxNihwdHIsc2VnKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKShzZWcpPDw0KSkpCiNkZWZpbmUgU0VHUFRSMTYocHRyLHNlZ3B0cikgKChMUFZPSUQpKChCWVRFKilwdHIrKChEV09SRClTRUxFQ1RPUk9GKHNlZ3B0cik8PDQpK09GRlNFVE9GKHNlZ3B0cikpKQoKLyogc3RydWN0dXJlcyBmb3IgRVhFQyAqLwoKI2luY2x1ZGUgInBzaHBhY2sxLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBlbnZfc2VnOwogIERXT1JEIGNtZGxpbmU7CiAgRFdPUkQgZmNiMTsKICBEV09SRCBmY2IyOwogIFdPUkQgaW5pdF9zcDsKICBXT1JEIGluaXRfc3M7CiAgV09SRCBpbml0X2lwOwogIFdPUkQgaW5pdF9jczsKfSBFeGVjQmxvY2s7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBsb2FkX3NlZzsKICBXT1JEIHJlbF9zZWc7Cn0gT3ZlcmxheUJsb2NrOwoKI2luY2x1ZGUgInBvcHBhY2suaCIKCi8qIGdsb2JhbCB2YXJpYWJsZXMgKi8KCnBpZF90IGRvc3ZtX3BpZDsKCnN0YXRpYyBXT1JEIGluaXRfY3MsaW5pdF9pcCxpbml0X3NzLGluaXRfc3A7CnN0YXRpYyBIQU5ETEUgZG9zdm1fdGhyZWFkLCBsb29wX3RocmVhZDsKc3RhdGljIERXT1JEIGRvc3ZtX3RpZCwgbG9vcF90aWQ7CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2goIExQQ1NUUiBjbWR0YWlsLCBpbnQgbGVuZ3RoICk7CnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpOwoKc3RhdGljIHZvaWQgTVpfQ3JlYXRlUFNQKCBMUFZPSUQgbHBQU1AsIFdPUkQgZW52LCBXT1JEIHBhciApCnsKICBQREIxNipwc3A9bHBQU1A7CgogIHBzcC0+aW50MjA9MHgyMENEOyAvKiBpbnQgMjAgKi8KICAvKiBzb21lIHByb2dyYW1zIHVzZSB0aGlzIHRvIGNhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgdGhleSBuZWVkICovCiAgcHNwLT5uZXh0UGFyYWdyYXBoPTB4OUZGRjsgLyogRklYTUU6IHVzZSBhIHJlYWwgdmFsdWUgKi8KICAvKiBGSVhNRTogZGlzcGF0Y2hlciAqLwogIHBzcC0+c2F2ZWRpbnQyMiA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIyKTsKICBwc3AtPnNhdmVkaW50MjMgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyMyk7CiAgcHNwLT5zYXZlZGludDI0ID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjQpOwogIHBzcC0+cGFyZW50UFNQPXBhcjsKICBwc3AtPmVudmlyb25tZW50PWVudjsKICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIHZvaWQgTVpfRmlsbFBTUCggTFBWT0lEIGxwUFNQLCBMUENTVFIgY21kdGFpbCwgaW50IGxlbmd0aCApCnsKICAgIFBEQjE2ICpwc3AgPSBscFBTUDsKCiAgICBpZihsZW5ndGggPiAxMjcpIAogICAgewogICAgICAgIFdBUk4oICJDb21tYW5kIHRhaWwgdHJ1bmNhdGVkISAobGVuZ3RoICVkKVxuIiwgbGVuZ3RoICk7CiAgICAgICAgbGVuZ3RoID0gMTI2OwogICAgfQoKICAgIHBzcC0+Y21kTGluZVswXSA9IGxlbmd0aDsKCiAgICAvKgogICAgICogTGVuZ3RoIG9mIGV4YWN0bHkgMTI3IGJ5dGVzIG1lYW5zIHRoYXQgZnVsbCBjb21tYW5kIGxpbmUgaXMgCiAgICAgKiBzdG9yZWQgaW4gZW52aXJvbm1lbnQgdmFyaWFibGUgQ01ETElORSBhbmQgUFNQIGNvbnRhaW5zIAogICAgICogY29tbWFuZCB0YWlsIHRydW5jYXRlZCB0byAxMjYgYnl0ZXMuCiAgICAgKi8KICAgIGlmKGxlbmd0aCA9PSAxMjcpCiAgICAgICAgbGVuZ3RoID0gMTI2OwoKICAgIGlmKGxlbmd0aCA+IDApCiAgICAgICAgbWVtbW92ZShwc3AtPmNtZExpbmUrMSwgY21kdGFpbCwgbGVuZ3RoKTsKCiAgICBwc3AtPmNtZExpbmVbbGVuZ3RoKzFdID0gJ1xyJzsKCiAgICAvKiBGSVhNRTogbW9yZSBQU1Agc3R1ZmYgKi8KfQoKc3RhdGljIFdPUkQgTVpfSW5pdEVudmlyb25tZW50KCBMUENTVFIgZW52LCBMUENTVFIgbmFtZSApCnsKIHVuc2lnbmVkIHN6PTA7CiB1bnNpZ25lZCBpPTA7CiBXT1JEIHNlZzsKIExQU1RSIGVudmJsazsKCiBpZiAoZW52KSB7CiAgLyogZ2V0IHNpemUgb2YgZW52aXJvbm1lbnQgYmxvY2sgKi8KICB3aGlsZSAoZW52W3N6KytdKSBzeis9c3RybGVuKGVuditzeikrMTsKIH0gZWxzZSBzeisrOwogLyogYWxsb2NhdGUgaXQgKi8KIGVudmJsaz1ET1NNRU1fQWxsb2NCbG9jayhzeitzaXplb2YoV09SRCkrc3RybGVuKG5hbWUpKzEsJnNlZyk7CiAvKiBmaWxsIGl0ICovCiBpZiAoZW52KSB7CiAgbWVtY3B5KGVudmJsayxlbnYsc3opOwogfSBlbHNlIGVudmJsa1swXT0wOwogLyogRE9TIGVudmlyb25tZW50IHZhcmlhYmxlcyBhcmUgdXBwZXJjYXNlICovCiB3aGlsZSAoZW52YmxrW2ldKXsKICB3aGlsZSAoZW52YmxrW2ldICE9ICc9Jyl7CiAgIGlmIChlbnZibGtbaV0+PSdhJyAmJiBlbnZibGtbaV0gPD0gJ3onKXsKICAgIGVudmJsa1tpXSAtPSAzMjsKICAgfQogICBpKys7CiAgfQogIGkgKz0gc3RybGVuKGVudmJsaytpKSArIDE7CiB9CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSh2b2lkKQp7CiAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKICAgIERPU01FTV9NYXBEb3NMYXlvdXQoKTsKICAgIERPU0RFVl9JbnN0YWxsRE9TRGV2aWNlcygpOwoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTCBNWl9Eb0xvYWRJbWFnZSggSEFORExFIGhGaWxlLCBMUENTVFIgZmlsZW5hbWUsIE92ZXJsYXlCbG9jayAqb2JsaywgV09SRCBwYXJfZW52X3NlZyApCnsKICBJTUFHRV9ET1NfSEVBREVSIG16X2hlYWRlcjsKICBEV09SRCBpbWFnZV9zdGFydCxpbWFnZV9zaXplLG1pbl9zaXplLG1heF9zaXplLGF2YWlsOwogIEJZVEUqcHNwX3N0YXJ0LCpsb2FkX3N0YXJ0LCpvbGRlbnYgPSAwOwogIGludCB4LCBvbGRfY29tPTAsIGFsbG9jOwogIFNFR1BUUiByZWxvYzsKICBXT1JEIGVudl9zZWcsIGxvYWRfc2VnLCByZWxfc2VnLCBvbGRwc3Bfc2VnOwogIERXT1JEIGxlbjsKCiAgaWYgKERPU1ZNX3BzcCkgewogICAgLyogRE9TIHByb2Nlc3MgYWxyZWFkeSBydW5uaW5nLCBpbmhlcml0IGZyb20gaXQgKi8KICAgIFBEQjE2KiBwYXJfcHNwOwogICAgYWxsb2M9MDsKICAgIG9sZHBzcF9zZWcgPSBET1NWTV9wc3A7CiAgICBpZiggIXBhcl9lbnZfc2VnKSB7ICAKICAgICAgICBwYXJfcHNwID0gKFBEQjE2KikoKERXT1JEKURPU1ZNX3BzcCA8PCA0KTsKICAgICAgICBvbGRlbnYgPSAoTFBCWVRFKSgoRFdPUkQpcGFyX3BzcC0+ZW52aXJvbm1lbnQgPDwgNCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIGFsbG9jYXRlIG5ldyBET1MgcHJvY2VzcywgaW5oZXJpdGluZyBmcm9tIFdpbmUgZW52aXJvbm1lbnQgKi8KICAgIGFsbG9jPTE7CiAgICBvbGRwc3Bfc2VnID0gMDsKICAgIGlmKCAhcGFyX2Vudl9zZWcpCiAgICAgICAgb2xkZW52ID0gR2V0RW52aXJvbm1lbnRTdHJpbmdzQSgpOwogIH0KCiBTZXRGaWxlUG9pbnRlcihoRmlsZSwwLE5VTEwsRklMRV9CRUdJTik7CiBpZiAoICAgIVJlYWRGaWxlKGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlciksJmxlbixOVUxMKQogICAgIHx8IGxlbiAhPSBzaXplb2YobXpfaGVhZGVyKQogICAgIHx8IG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpIHsKICBjaGFyICpwID0gc3RycmNociggZmlsZW5hbWUsICcuJyApOwogIGlmICghcCB8fCBzdHJjYXNlY21wKCBwLCAiLmNvbSIgKSkgIC8qIGNoZWNrIGZvciAuQ09NIGV4dGVuc2lvbiAqLwogIHsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgfQogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgLyogRnJvbSBSYWxmIEJyb3duIEludGVycnVwdCBMaXN0OiBJZiB0aGUgd29yZCBhdCBvZmZzZXQgMDJoIGlzIDQsIGl0IHNob3VsZAogICAqIGJlIHRyZWF0ZWQgYXMgMDBoLCBzaW5jZSBwcmUtMS4xMCB2ZXJzaW9ucyBvZiB0aGUgTVMgbGlua2VyIHNldCBpdCB0aGF0CiAgICogd2F5LiAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiAgaWYgKGFsbG9jKSBNWl9Jbml0TWVtb3J5KCk7CgogIGlmIChvYmxrKSB7CiAgICAvKiBsb2FkIG92ZXJsYXkgaW50byBwcmVhbGxvY2F0ZWQgbWVtb3J5ICovCiAgICBsb2FkX3NlZz1vYmxrLT5sb2FkX3NlZzsKICAgIHJlbF9zZWc9b2Jsay0+cmVsX3NlZzsKICAgIGxvYWRfc3RhcnQ9KExQQllURSkoKERXT1JEKWxvYWRfc2VnPDw0KTsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgZW52aXJvbm1lbnQgYmxvY2sgKi8KICAgIGlmKCBwYXJfZW52X3NlZykKICAgICAgICBlbnZfc2VnID0gcGFyX2Vudl9zZWc7CiAgICBlbHNlCiAgICAgICAgZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQob2xkZW52LCBmaWxlbmFtZSk7CiAgICBpZiggYWxsb2MgJiYgb2xkZW52KQogICAgICAgIEZyZWVFbnZpcm9ubWVudFN0cmluZ3NBKCBvbGRlbnYpOwoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KICAgIFRSQUNFKCJBbGxvY2F0aW5nIERPUyBtZW1vcnkgKG1pbj0lbGQsIG1heD0lbGQpXG4iLG1pbl9zaXplLG1heF9zaXplKTsKICAgIGF2YWlsPURPU01FTV9BdmFpbGFibGUoKTsKICAgIGlmIChhdmFpbDxtaW5fc2l6ZSkgewogICAgICBFUlIoImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKICAgIHBzcF9zdGFydD1ET1NNRU1fQWxsb2NCbG9jayhhdmFpbCwmRE9TVk1fcHNwKTsKICAgIGlmICghcHNwX3N0YXJ0KSB7CiAgICAgIEVSUigiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgbG9hZF9zZWc9RE9TVk1fcHNwKyhvbGRfY29tPzA6UFNQX1NJWkUpOwogICAgcmVsX3NlZz1sb2FkX3NlZzsKICAgIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiAgICBNWl9DcmVhdGVQU1AocHNwX3N0YXJ0LCBlbnZfc2VnLCBvbGRwc3Bfc2VnKTsKICB9CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRSgibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBTZXRGaWxlUG9pbnRlcihoRmlsZSxpbWFnZV9zdGFydCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCFSZWFkRmlsZShoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUsJmxlbixOVUxMKSB8fCBsZW4gIT0gaW1hZ2Vfc2l6ZSkgewogIC8qIGNoZWNrIGlmIHRoaXMgaXMgZHVlIHRvIHRoZSB3b3JrYXJvdW5kIGZvciB0aGUgcHJlLTEuMTAgTVMgbGlua2VyIGFuZCB3ZQogICAgIHJlYWx5IGhhZCBvbmx5IDQgYnl0ZXMgb24gdGhlIGxhc3QgcGFnZSAqLwogIGlmIChtel9oZWFkZXIuZV9jYmxwICE9IDQgfHwgaW1hZ2Vfc2l6ZSAtIGxlbiAhPSA1MTIgLSA0KSB7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgICBnb3RvIGxvYWRfZXJyb3I7CiAgfQogfQoKIGlmIChtel9oZWFkZXIuZV9jcmxjKSB7CiAgLyogbG9hZCByZWxvY2F0aW9uIHRhYmxlICovCiAgVFJBQ0UoImxvYWRpbmcgRE9TIEVYRSByZWxvY2F0aW9uIHRhYmxlLCAlZCBlbnRyaWVzXG4iLG16X2hlYWRlci5lX2NybGMpOwogIC8qIEZJWE1FOiBpcyB0aGlzIHRvbyBzbG93IHdpdGhvdXQgcmVhZCBidWZmZXJpbmc/ICovCiAgU2V0RmlsZVBvaW50ZXIoaEZpbGUsbXpfaGVhZGVyLmVfbGZhcmxjLE5VTEwsRklMRV9CRUdJTik7CiAgZm9yICh4PTA7IHg8bXpfaGVhZGVyLmVfY3JsYzsgeCsrKSB7CiAgIGlmICghUmVhZEZpbGUoaEZpbGUsJnJlbG9jLHNpemVvZihyZWxvYyksJmxlbixOVUxMKSB8fCBsZW4gIT0gc2l6ZW9mKHJlbG9jKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgZ290byBsb2FkX2Vycm9yOwogICB9CiAgICooV09SRCopU0VHUFRSMTYobG9hZF9zdGFydCxyZWxvYykrPXJlbF9zZWc7CiAgfQogfQoKICBpZiAoIW9ibGspIHsKICAgIGluaXRfY3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9jczsKICAgIGluaXRfaXAgPSBtel9oZWFkZXIuZV9pcDsKICAgIGluaXRfc3MgPSBsb2FkX3NlZyttel9oZWFkZXIuZV9zczsKICAgIGluaXRfc3AgPSBtel9oZWFkZXIuZV9zcDsKICAgIGlmIChvbGRfY29tKXsKICAgICAgLyogLkNPTSBmaWxlcyBleGl0IHdpdGggcmV0LiBNYWtlIHN1cmUgdGhleSBqdW1wIHRvIHBzcCBzdGFydCAoPWludCAyMCkgKi8KICAgICAgV09SRCogc3RhY2sgPSBQVFJfUkVBTF9UT19MSU4oaW5pdF9zcywgaW5pdF9zcCk7CiAgICAgICpzdGFjayA9IDA7CiAgICB9CgogICAgVFJBQ0UoImVudHJ5IHBvaW50OiAlMDR4OiUwNHhcbiIsaW5pdF9jcyxpbml0X2lwKTsKICB9CgogIGlmIChhbGxvYyAmJiAhTVpfSW5pdFRhc2soKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0dFTl9GQUlMVVJFKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIHJldHVybiBUUlVFOwoKbG9hZF9lcnJvcjoKICBET1NWTV9wc3AgPSBvbGRwc3Bfc2VnOwoKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJd2luZV9sb2FkX2Rvc19leGUgKFdJTkVET1MuQCkKICoKICogQ2FsbGVkIGZyb20gV2luZVZETSB3aGVuIGEgbmV3IHJlYWwtbW9kZSBET1MgcHJvY2VzcyBpcyBzdGFydGVkLgogKiBMb2FkcyBET1MgcHJvZ3JhbSBpbnRvIG1lbW9yeSBhbmQgZXhlY3V0ZXMgdGhlIHByb2dyYW0uCiAqLwp2b2lkIFdJTkFQSSB3aW5lX2xvYWRfZG9zX2V4ZSggTFBDU1RSIGZpbGVuYW1lLCBMUENTVFIgY21kbGluZSApCnsKICAgIGNoYXIgZG9zX2NtZHRhaWxbMTI2XTsKICAgIGludCAgZG9zX2xlbmd0aCA9IDA7CgogICAgSEFORExFIGhGaWxlID0gQ3JlYXRlRmlsZUEoIGZpbGVuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm47CiAgICBET1NWTV9pc2Rvc2V4ZSA9IFRSVUU7CgogICAgaWYoY21kbGluZSAmJiAqY21kbGluZSkKICAgIHsKICAgICAgICBkb3NfbGVuZ3RoID0gc3RybGVuKGNtZGxpbmUpOwogICAgICAgIG1lbW1vdmUoIGRvc19jbWR0YWlsICsgMSwgY21kbGluZSwgCiAgICAgICAgICAgICAgICAgKGRvc19sZW5ndGggPCAxMjUpID8gZG9zX2xlbmd0aCA6IDEyNSApOwoKICAgICAgICAvKiBOb24tZW1wdHkgY29tbWFuZCB0YWlsIGFsd2F5cyBzdGFydHMgd2l0aCBhdCBsZWFzdCBvbmUgc3BhY2UuICovCiAgICAgICAgZG9zX2NtZHRhaWxbMF0gPSAnICc7CiAgICAgICAgZG9zX2xlbmd0aCsrOwoKICAgICAgICAvKgogICAgICAgICAqIElmIGNvbW1hbmQgdGFpbCBpcyBsb25nZXIgdGhhbiAxMjYgY2hhcmFjdGVycywKICAgICAgICAgKiBzZXQgdGFpbCBsZW5ndGggdG8gMTI3IGFuZCBmaWxsIENNRExJTkUgZW52aXJvbm1lbnQgdmFyaWFibGUgCiAgICAgICAgICogd2l0aCBmdWxsIGNvbW1hbmQgbGluZSAodGhpcyBpbmNsdWRlcyBmaWxlbmFtZSkuCiAgICAgICAgICovCiAgICAgICAgaWYgKGRvc19sZW5ndGggPiAxMjYpCiAgICAgICAgewogICAgICAgICAgICBjaGFyICpjbWQgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvc19sZW5ndGggKyBzdHJsZW4oZmlsZW5hbWUpICsgNCApOwogICAgICAgICAgICBjaGFyICpwdHIgPSBjbWQ7CgogICAgICAgICAgICBpZiAoIWNtZCkKICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEFwcGVuZCBmaWxlbmFtZS4gSWYgcGF0aCBpbmNsdWRlcyBzcGFjZXMsIHF1b3RlIHRoZSBwYXRoLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHN0cmNocihmaWxlbmFtZSwgJyAnKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgKnB0cisrID0gJ1wiJzsKICAgICAgICAgICAgICAgIHN0cmNweSggcHRyLCBmaWxlbmFtZSApOwogICAgICAgICAgICAgICAgcHRyICs9IHN0cmxlbihmaWxlbmFtZSk7ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgKnB0cisrID0gJ1wiJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweSggcHRyLCBmaWxlbmFtZSApOwogICAgICAgICAgICAgICAgcHRyICs9IHN0cmxlbihmaWxlbmFtZSk7ICAKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogQXBwZW5kIGNvbW1hbmQgdGFpbC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChjbWRsaW5lWzBdICE9ICcgJykKICAgICAgICAgICAgICAgICpwdHIrKyA9ICcgJzsKICAgICAgICAgICAgc3RyY3B5KCBwdHIsIGNtZGxpbmUgKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNldCBlbnZpcm9ubWVudCB2YXJpYWJsZS4gVGhpcyB3aWxsIGJlIHBhc3NlZCB0bwogICAgICAgICAgICAgKiBuZXcgRE9TIHByb2Nlc3MuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIVNldEVudmlyb25tZW50VmFyaWFibGVBKCAiQ01ETElORSIsIGNtZCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjbWQgKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY21kICk7CiAgICAgICAgICAgIGRvc19sZW5ndGggPSAxMjc7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBOVUxMLCAwICkpIAogICAgICAgIE1aX0xhdW5jaCggZG9zX2NtZHRhaWwsIGRvc19sZW5ndGggKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGVjCiAqCiAqIHRoaXMgbWF5IG9ubHkgYmUgY2FsbGVkIGZyb20gZXhpc3RpbmcgRE9TIHByb2Nlc3NlcwogKi8KQk9PTCBXSU5BUEkgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIERXT1JEIGJpblR5cGU7CiAgU1RBUlRVUElORk9BIHN0OwogIFBST0NFU1NfSU5GT1JNQVRJT04gcGU7CiAgSEFORExFIGhGaWxlOwoKICBCT09MIHJldCA9IEZBTFNFOwoKICBpZighR2V0QmluYXJ5VHlwZUEoZmlsZW5hbWUsICZiaW5UeXBlKSkgICAvKiBkZXRlcm1pbmUgd2hhdCBraW5kIG9mIGJpbmFyeSB0aGlzIGlzICovCiAgewogICAgcmV0dXJuIEZBTFNFOyAvKiBiaW5hcnkgaXMgbm90IGFuIGV4ZWN1dGFibGUgKi8KICB9CgogIC8qIGhhbmRsZSBub24tZG9zIGV4ZWN1dGFibGVzICovCiAgaWYoYmluVHlwZSAhPSBTQ1NfRE9TX0JJTkFSWSkKICB7CiAgICBpZihmdW5jID09IDApIC8qIGxvYWQgYW5kIGV4ZWN1dGUgKi8KICAgIHsKICAgICAgTFBCWVRFIGZ1bGxDbWRMaW5lOwogICAgICBXT1JEIGZ1bGxDbWRMZW5ndGg7CiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgICBFeGVjQmxvY2sgKmJsayA9IChFeGVjQmxvY2sgKilwYXJhbWJsazsKICAgICAgTFBCWVRFIGNtZGxpbmUgPSBQVFJfUkVBTF9UT19MSU4oU0VMRUNUT1JPRihibGstPmNtZGxpbmUpLE9GRlNFVE9GKGJsay0+Y21kbGluZSkpOwogICAgICBMUEJZVEUgZW52YmxvY2sgPSBQVFJfUkVBTF9UT19MSU4ocHNwLT5lbnZpcm9ubWVudCwgMCk7CiAgICAgIGludCAgICBjbWRMZW5ndGggPSBjbWRsaW5lWzBdOwoKICAgICAgLyoKICAgICAgICogSWYgY21kTGVuZ3RoIGlzIDEyNywgY29tbWFuZCB0YWlsIGlzIHRydW5jYXRlZCBhbmQgZW52aXJvbm1lbnQgCiAgICAgICAqIHZhcmlhYmxlIENNRExJTkUgc2hvdWxkIGNvbnRhaW4gZnVsbCBjb21tYW5kIGxpbmUgCiAgICAgICAqICh0aGlzIGluY2x1ZGVzIGZpbGVuYW1lKS4KICAgICAgICovCiAgICAgIGlmIChjbWRMZW5ndGggPT0gMTI3KQogICAgICB7CiAgICAgICAgICBGSVhNRSggIkNNRExJTkUgYXJndW1lbnQgcGFzc2luZyBpcyB1bmltcGxlbWVudGVkLlxuIiApOwogICAgICAgICAgY21kTGVuZ3RoID0gMTI2OyAvKiBGSVhNRSAqLwogICAgICB9CgogICAgICBmdWxsQ21kTGVuZ3RoID0gKHN0cmxlbihmaWxlbmFtZSkgKyAxKSArIGNtZExlbmd0aCArIDE7IC8qIGZpbGVuYW1lICsgc3BhY2UgKyBjbWRsaW5lICsgdGVybWluYXRpbmcgbnVsbCBjaGFyYWN0ZXIgKi8KCiAgICAgIGZ1bGxDbWRMaW5lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGZ1bGxDbWRMZW5ndGgpOwogICAgICBpZighZnVsbENtZExpbmUpIHJldHVybiBGQUxTRTsgLyogcmV0dXJuIGZhbHNlIG9uIG1lbW9yeSBhbGxvYyBmYWlsdXJlICovCgogICAgICAvKiBidWlsZCB0aGUgZnVsbCBjb21tYW5kIGxpbmUgZnJvbSB0aGUgZXhlY3V0YWJsZSBmaWxlIGFuZCB0aGUgY29tbWFuZCBsaW5lIGJlaW5nIHBhc3NlZCBpbiAqLwogICAgICBzbnByaW50ZihmdWxsQ21kTGluZSwgZnVsbENtZExlbmd0aCwgIiVzICIsIGZpbGVuYW1lKTsgLyogc3RhcnQgb2ZmIHdpdGggdGhlIGV4ZWN1dGFibGUgZmlsZW5hbWUgYW5kIGEgc3BhY2UgKi8KICAgICAgbWVtY3B5KGZ1bGxDbWRMaW5lICsgc3RybGVuKGZ1bGxDbWRMaW5lKSwgY21kbGluZSArIDEsIGNtZExlbmd0aCk7IC8qIGFwcGVuZCBjbWRsaW5lIG9udG8gdGhlIGVuZCAqLwogICAgICBmdWxsQ21kTGluZVtmdWxsQ21kTGVuZ3RoIC0gMV0gPSAwOyAvKiBudWxsIHRlcm1pbmF0ZSBzdHJpbmcgKi8KCiAgICAgIFplcm9NZW1vcnkgKCZzdCwgc2l6ZW9mKFNUQVJUVVBJTkZPQSkpOwogICAgICBzdC5jYiA9IHNpemVvZihTVEFSVFVQSU5GT0EpOwogICAgICByZXQgPSBDcmVhdGVQcm9jZXNzQSAoTlVMTCwgZnVsbENtZExpbmUsIE5VTEwsIE5VTEwsIFRSVUUsIDAsIGVudmJsb2NrLCBOVUxMLCAmc3QsICZwZSk7CgogICAgICAvKiB3YWl0IGZvciB0aGUgYXBwIHRvIGZpbmlzaCBhbmQgY2xlYW4gdXAgUFJPQ0VTU19JTkZPUk1BVElPTiBoYW5kbGVzICovCiAgICAgIGlmKHJldCkKICAgICAgewogICAgICAgIFdhaXRGb3JTaW5nbGVPYmplY3QocGUuaFByb2Nlc3MsIElORklOSVRFKTsgIC8qIHdhaXQgaGVyZSB1bnRpbCB0aGUgY2hpbGQgcHJvY2VzcyBpcyBjb21wbGV0ZSAqLwogICAgICAgIENsb3NlSGFuZGxlKHBlLmhQcm9jZXNzKTsKICAgICAgICBDbG9zZUhhbmRsZShwZS5oVGhyZWFkKTsKICAgICAgfQoKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZnVsbENtZExpbmUpOyAgLyogZnJlZSB0aGUgbWVtb3J5IHdlIGFsbG9jYXRlZCAqLwogICAgfQogICAgZWxzZQogICAgewogICAgICBGSVhNRSgiRVhFQyB0eXBlIG9mICVkIG5vdCBpbXBsZW1lbnRlZCBmb3Igbm9uLWRvcyBleGVjdXRhYmxlc1xuIiwgZnVuYyk7CiAgICAgIHJldCA9IEZBTFNFOwogICAgfQoKICAgIHJldHVybiByZXQ7CiAgfSAvKiBpZihiaW5UeXBlICE9IFNDU19ET1NfQklOQVJZKSAqLwoKCiAgLyogaGFuZGxlIGRvcyBleGVjdXRhYmxlcyAqLwoKICBoRmlsZSA9IENyZWF0ZUZpbGVBKCBmaWxlbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCgkJCSAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCk7CiAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm4gRkFMU0U7CgogIHN3aXRjaCAoZnVuYykgewogIGNhc2UgMDogLyogbG9hZCBhbmQgZXhlY3V0ZSAqLwogIGNhc2UgMTogLyogbG9hZCBidXQgZG9uJ3QgZXhlY3V0ZSAqLwogICAgewogICAgICAvKiBzYXZlIGN1cnJlbnQgcHJvY2VzcydzIHJldHVybiBTUzpTUCBub3cgKi8KICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIHBzcC0+c2F2ZVN0YWNrID0gKERXT1JEKU1BS0VTRUdQVFIoY29udGV4dC0+U2VnU3MsIExPV09SRChjb250ZXh0LT5Fc3ApKTsKICAgIH0KICAgIHJldCA9IE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIE5VTEwsICgoRXhlY0Jsb2NrICopcGFyYW1ibGspLT5lbnZfc2VnICk7CiAgICBpZiAocmV0KSB7CiAgICAgIC8qIE1aX0xvYWRJbWFnZSBjcmVhdGVkIGEgbmV3IFBTUCBhbmQgbG9hZGVkIG5ldyB2YWx1ZXMgaW50byBpdCwKICAgICAgICogbGV0J3Mgd29yayBvbiB0aGUgbmV3IHZhbHVlcyBub3cgKi8KICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIEV4ZWNCbG9jayAqYmxrID0gKEV4ZWNCbG9jayAqKXBhcmFtYmxrOwogICAgICBMUEJZVEUgY21kbGluZSA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGJsay0+Y21kbGluZSksT0ZGU0VUT0YoYmxrLT5jbWRsaW5lKSk7CgogICAgICAvKiBGaXJzdCBjaGFyYWN0ZXIgY29udGFpbnMgdGhlIGxlbmd0aCBvZiB0aGUgY29tbWFuZCBsaW5lLiAqLwogICAgICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgY21kbGluZSArIDEsIGNtZGxpbmVbMF0pOwoKICAgICAgLyogdGhlIGxhbWUgTVMtRE9TIGVuZ2luZWVycyBkZWNpZGVkIHRoYXQgdGhlIHJldHVybiBhZGRyZXNzIHNob3VsZCBiZSBpbiBpbnQyMiAqLwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMiwgKEZBUlBST0MxNilNQUtFU0VHUFRSKGNvbnRleHQtPlNlZ0NzLCBMT1dPUkQoY29udGV4dC0+RWlwKSkpOwogICAgICBpZiAoZnVuYykgewoJLyogZG9uJ3QgZXhlY3V0ZSwganVzdCByZXR1cm4gc3RhcnR1cCBzdGF0ZSAqLwogICAgICAgIC8qCiAgICAgICAgICogRnJvbSBSYWxwaCBCcm93bjoKICAgICAgICAgKiAgRm9yIGZ1bmN0aW9uIDAxaCwgdGhlIEFYIHZhbHVlIHRvIGJlIHBhc3NlZCB0byB0aGUgY2hpbGQgcHJvZ3JhbSAKICAgICAgICAgKiAgaXMgcHV0IG9uIHRvcCBvZiB0aGUgY2hpbGQncyBzdGFjawogICAgICAgICAqLwogICAgICAgIExQQllURSBzdGFjazsKICAgICAgICBpbml0X3NwIC09IDI7CiAgICAgICAgc3RhY2sgPSAoTFBCWVRFKSBDVFhfU0VHX09GRl9UT19MSU4oY29udGV4dCwgaW5pdF9zcywgaW5pdF9zcCk7CiAgICAgICAgLyogRklYTUU6IHB1c2ggQVggY29ycmVjdGx5ICovCiAgICAgICAgc3RhY2tbMF0gPSAweDAwOyAgICAvKiBwdXNoIEFMICovCiAgICAgICAgc3RhY2tbMV0gPSAweDAwOyAgICAvKiBwdXNoIEFIICovCgkKCWJsay0+aW5pdF9jcyA9IGluaXRfY3M7CglibGstPmluaXRfaXAgPSBpbml0X2lwOwoJYmxrLT5pbml0X3NzID0gaW5pdF9zczsKCWJsay0+aW5pdF9zcCA9IGluaXRfc3A7CiAgICAgIH0gZWxzZSB7CgkvKiBleGVjdXRlIGJ5IG1ha2luZyB1cyByZXR1cm4gdG8gbmV3IHByb2Nlc3MgKi8KCWNvbnRleHQtPlNlZ0NzID0gaW5pdF9jczsKCWNvbnRleHQtPkVpcCAgID0gaW5pdF9pcDsKCWNvbnRleHQtPlNlZ1NzID0gaW5pdF9zczsKCWNvbnRleHQtPkVzcCAgID0gaW5pdF9zcDsKCWNvbnRleHQtPlNlZ0RzID0gRE9TVk1fcHNwOwoJY29udGV4dC0+U2VnRXMgPSBET1NWTV9wc3A7Cgljb250ZXh0LT5FYXggICA9IDA7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2UgMzogLyogbG9hZCBvdmVybGF5ICovCiAgICB7CiAgICAgIE92ZXJsYXlCbG9jayAqYmxrID0gKE92ZXJsYXlCbG9jayAqKXBhcmFtYmxrOwogICAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBibGssIDApOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIEZJWE1FKCJFWEVDIGxvYWQgdHlwZSAlZCBub3QgaW1wbGVtZW50ZWRcbiIsIGZ1bmMpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRlVOQ1RJT04pOwogICAgYnJlYWs7CiAgfQogIENsb3NlSGFuZGxlKGhGaWxlKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0FsbG9jRFBNSVRhc2sKICovCnZvaWQgV0lOQVBJIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgTVpfSW5pdE1lbW9yeSgpOwogIE1aX0luaXRUYXNrKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfUnVuSW5UaHJlYWQKICovCnZvaWQgV0lOQVBJIE1aX1J1bkluVGhyZWFkKCBQQVBDRlVOQyBwcm9jLCBVTE9OR19QVFIgYXJnICkKewogIGlmIChsb29wX3RocmVhZCkgewogICAgRE9TX1NQQyBzcGM7CiAgICBIQU5ETEUgZXZlbnQ7CgogICAgc3BjLnByb2MgPSBwcm9jOwogICAgc3BjLmFyZyA9IGFyZzsKICAgIGV2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgIFBvc3RUaHJlYWRNZXNzYWdlQShsb29wX3RpZCwgV01fVVNFUiwgKFdQQVJBTSlldmVudCwgKExQQVJBTSkmc3BjKTsKICAgIFdhaXRGb3JTaW5nbGVPYmplY3QoZXZlbnQsIElORklOSVRFKTsKICAgIENsb3NlSGFuZGxlKGV2ZW50KTsKICB9IGVsc2UKICAgIHByb2MoYXJnKTsKfQoKc3RhdGljIERXT1JEIFdJTkFQSSBNWl9ET1NWTSggTFBWT0lEIGxwRXh0cmEgKQp7CiAgQ09OVEVYVCBjb250ZXh0OwogIERXT1JEIHJldDsKCiAgZG9zdm1fcGlkID0gZ2V0cGlkKCk7CgogIG1lbXNldCggJmNvbnRleHQsIDAsIHNpemVvZihjb250ZXh0KSApOwogIGNvbnRleHQuU2VnQ3MgID0gaW5pdF9jczsKICBjb250ZXh0LkVpcCAgICA9IGluaXRfaXA7CiAgY29udGV4dC5TZWdTcyAgPSBpbml0X3NzOwogIGNvbnRleHQuRXNwICAgID0gaW5pdF9zcDsKICBjb250ZXh0LlNlZ0RzICA9IERPU1ZNX3BzcDsKICBjb250ZXh0LlNlZ0VzICA9IERPU1ZNX3BzcDsKICBjb250ZXh0LkVGbGFncyA9IFY4Nl9GTEFHIHwgVklGX01BU0s7CiAgRE9TVk1fU2V0VGltZXIoMHgxMDAwMCk7CiAgcmV0ID0gRE9TVk1fRW50ZXIoICZjb250ZXh0ICk7CgogIGRvc3ZtX3BpZCA9IDA7CiAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCkKewogIGlmICghRHVwbGljYXRlSGFuZGxlKEdldEN1cnJlbnRQcm9jZXNzKCksIEdldEN1cnJlbnRUaHJlYWQoKSwKICAgICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50UHJvY2VzcygpLCAmbG9vcF90aHJlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgMCwgRkFMU0UsIERVUExJQ0FURV9TQU1FX0FDQ0VTUykpCiAgICByZXR1cm4gRkFMU0U7CiAgZG9zdm1fdGhyZWFkID0gQ3JlYXRlVGhyZWFkKE5VTEwsIDAsIE1aX0RPU1ZNLCBOVUxMLCBDUkVBVEVfU1VTUEVOREVELCAmZG9zdm1fdGlkKTsKICBpZiAoIWRvc3ZtX3RocmVhZCkgewogICAgQ2xvc2VIYW5kbGUobG9vcF90aHJlYWQpOwogICAgbG9vcF90aHJlYWQgPSAwOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICBsb29wX3RpZCA9IEdldEN1cnJlbnRUaHJlYWRJZCgpOwogIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2goIExQQ1NUUiBjbWR0YWlsLCBpbnQgbGVuZ3RoICkKewogIFREQiAqcFRhc2sgPSBHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKICBCWVRFICpwc3Bfc3RhcnQgPSBQVFJfUkVBTF9UT19MSU4oIERPU1ZNX3BzcCwgMCApOwogIERXT1JEIHJ2OwogIFNZU0xFVkVMICpsb2NrOwoKICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgY21kdGFpbCwgbGVuZ3RoKTsKICBwVGFzay0+ZmxhZ3MgfD0gVERCRl9XSU5PTERBUDsKCiAgLyogRFRBIGlzIHNldCB0byBQU1A6MDA4MGggd2hlbiBhIHByb2dyYW0gaXMgc3RhcnRlZC4gKi8KICBwVGFzay0+ZHRhID0gTUFLRVNFR1BUUiggRE9TVk1fcHNwLCAweDgwICk7CgogIEdldHBXaW4xNkxvY2soICZsb2NrICk7CiAgX0xlYXZlU3lzTGV2ZWwoIGxvY2sgKTsKCiAgUmVzdW1lVGhyZWFkKGRvc3ZtX3RocmVhZCk7CiAgcnYgPSBET1NWTV9Mb29wKGRvc3ZtX3RocmVhZCk7CgogIENsb3NlSGFuZGxlKGRvc3ZtX3RocmVhZCk7CiAgZG9zdm1fdGhyZWFkID0gMDsgZG9zdm1fdGlkID0gMDsKICBDbG9zZUhhbmRsZShsb29wX3RocmVhZCk7CiAgbG9vcF90aHJlYWQgPSAwOyBsb29wX3RpZCA9IDA7CgogIFZHQV9DbGVhbigpOwogIEV4aXRQcm9jZXNzKHJ2KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGl0CiAqLwp2b2lkIFdJTkFQSSBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBpZiAoRE9TVk1fcHNwKSB7CiAgICBXT1JEIHBzcF9zZWcgPSBjc19wc3AgPyBjb250ZXh0LT5TZWdDcyA6IERPU1ZNX3BzcDsKICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcHNwX3NlZyA8PCA0KTsKICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICBXT1JEIHBhcnBzcCA9IHBzcC0+cGFyZW50UFNQOyAvKiBjaGVjayBmb3IgcGFyZW50IERPUyBwcm9jZXNzICovCiAgICBpZiAocGFycHNwKSB7CiAgICAgIC8qIHJldHJpZXZlIHBhcmVudCdzIHJldHVybiBhZGRyZXNzICovCiAgICAgIEZBUlBST0MxNiByZXRhZGRyID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjIpOwogICAgICAvKiByZXN0b3JlIGludGVycnVwdHMgKi8KICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjIsIHBzcC0+c2F2ZWRpbnQyMik7CiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIzLCBwc3AtPnNhdmVkaW50MjMpOwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyNCwgcHNwLT5zYXZlZGludDI0KTsKICAgICAgLyogRklYTUU6IGRlYWxsb2NhdGUgZmlsZSBoYW5kbGVzIGV0YyAqLwogICAgICAvKiBmcmVlIHByb2Nlc3MncyBhc3NvY2lhdGVkIG1lbW9yeQogICAgICAgKiBGSVhNRTogd2FsayBtZW1vcnkgYW5kIGRlYWxsb2NhdGUgYWxsIGJsb2NrcyBvd25lZCBieSBwcm9jZXNzICovCiAgICAgIERPU01FTV9GcmVlQmxvY2soIFBUUl9SRUFMX1RPX0xJTihwc3AtPmVudmlyb25tZW50LDApICk7CiAgICAgIERPU01FTV9GcmVlQmxvY2soIFBUUl9SRUFMX1RPX0xJTihET1NWTV9wc3AsMCkgKTsKICAgICAgLyogc3dpdGNoIHRvIHBhcmVudCdzIFBTUCAqLwogICAgICBET1NWTV9wc3AgPSBwYXJwc3A7CiAgICAgIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClwYXJwc3AgPDwgNCk7CiAgICAgIHBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgLyogbm93IHJldHVybiB0byBwYXJlbnQgKi8KICAgICAgRE9TVk1fcmV0dmFsID0gcmV0dmFsOwogICAgICBjb250ZXh0LT5TZWdDcyA9IFNFTEVDVE9ST0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPkVpcCAgID0gT0ZGU0VUT0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPlNlZ1NzID0gU0VMRUNUT1JPRihwc3AtPnNhdmVTdGFjayk7CiAgICAgIGNvbnRleHQtPkVzcCAgID0gT0ZGU0VUT0YocHNwLT5zYXZlU3RhY2spOwogICAgICByZXR1cm47CiAgICB9IGVsc2UKICAgICAgVFJBQ0UoImtpbGxpbmcgRE9TIHRhc2tcbiIpOwogIH0KICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQ3VycmVudAogKi8KQk9PTCBXSU5BUEkgTVpfQ3VycmVudCggdm9pZCApCnsKICByZXR1cm4gKGRvc3ZtX3BpZCAhPSAwKTsgLyogRklYTUU6IGRvIGEgYmV0dGVyIGNoZWNrICovCn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJd2luZV9sb2FkX2Rvc19leGUgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIHdpbmVfbG9hZF9kb3NfZXhlKCBMUENTVFIgZmlsZW5hbWUsIExQQ1NUUiBjbWRsaW5lICkKewogIFdBUk4oIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm1cbiIpOwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGVjCiAqLwpCT09MIFdJTkFQSSBNWl9FeGVjKCBDT05URVhUODYgKmNvbnRleHQsIExQQ1NUUiBmaWxlbmFtZSwgQllURSBmdW5jLCBMUFZPSUQgcGFyYW1ibGsgKQp7CiAgLyogY2FuJ3QgaGFwcGVuICovCiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9BbGxvY0RQTUlUYXNrCiAqLwp2b2lkIFdJTkFQSSBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogICAgRVJSKCJBY3R1YWwgcmVhbC1tb2RlIGNhbGxzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybSFcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX1J1bkluVGhyZWFkCiAqLwp2b2lkIFdJTkFQSSBNWl9SdW5JblRocmVhZCggUEFQQ0ZVTkMgcHJvYywgVUxPTkdfUFRSIGFyZyApCnsKICAgIHByb2MoYXJnKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGl0CiAqLwp2b2lkIFdJTkFQSSBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9DdXJyZW50CiAqLwpCT09MIFdJTkFQSSBNWl9DdXJyZW50KCB2b2lkICkKewogICAgcmV0dXJuIEZBTFNFOwp9CgojZW5kaWYgLyogIU1aX1NVUFBPUlRFRCAqLwo=