LyoKICogQ29weXJpZ2h0IChjKSAyMDExLTIwMTcgVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFByZXZpb3VzbHkgbGljZW5zZWQgdW5kZXIgdGhlIElTQyBsaWNlbnNlIGJ5IFF1YWxjb21tIEF0aGVyb3MsIEluYy4KICoKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IKICogYW55IHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUKICogYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsCiAqIGNvcGllcy4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTAogKiBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVECiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKICogQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SCiAqIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgovKgogKiBUaGlzIGZpbGUgd2FzIG9yaWdpbmFsbHkgZGlzdHJpYnV0ZWQgYnkgUXVhbGNvbW0gQXRoZXJvcywgSW5jLgogKiB1bmRlciBwcm9wcmlldGFyeSB0ZXJtcyBiZWZvcmUgQ29weXJpZ2h0IG93bmVyc2hpcCB3YXMgYXNzaWduZWQKICogdG8gdGhlIExpbnV4IEZvdW5kYXRpb24uCiAqLwoKLyoqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKiAKICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKiAgCgogIAogICAgXGZpbGUgY3NyTmVpZ2hib3JSb2FtLmMKICAKICAgIEltcGxlbWVudGF0aW9uIGZvciB0aGUgc2ltcGxlIHJvYW1pbmcgYWxnb3JpdGhtIGZvciA4MDIuMTFyIEZhc3QgdHJhbnNpdGlvbnMgYW5kIExlZ2FjeSByb2FtaW5nIGZvciBBbmRyb2lkIHBsYXRmb3JtLgogIAogICAgQ29weXJpZ2h0IChDKSAyMDEwIFF1YWxjb21tLCBJbmNvcnBvcmF0ZWQKICAKIAogICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICAgICAgICAgICAgICAgICAgICBFRElUIEhJU1RPUlkgRk9SIEZJTEUKCgogIFRoaXMgc2VjdGlvbiBjb250YWlucyBjb21tZW50cyBkZXNjcmliaW5nIGNoYW5nZXMgbWFkZSB0byB0aGUgbW9kdWxlLgogIE5vdGljZSB0aGF0IGNoYW5nZXMgYXJlIGxpc3RlZCBpbiByZXZlcnNlIGNocm9ub2xvZ2ljYWwgb3JkZXIuCgoKCiAgd2hlbiAgICAgICAgICAgd2hvICAgICAgICAgICAgICAgICB3aGF0LCB3aGVyZSwgd2h5Ci0tLS0tLS0tLS0gICAgICAgLS0tICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjA4LzAxLzEwICAgICAgICAgIE11cmFsaSAgICAgICAgICAgICBDcmVhdGVkCgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwojaWZkZWYgV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcKI2luY2x1ZGUgIndsYW5fcWN0X3dkYS5oIgojaW5jbHVkZSAicGFsQXBpLmgiCiNpbmNsdWRlICJjc3JJbnNpZGVBcGkuaCIKI2luY2x1ZGUgInNtc0RlYnVnLmgiCiNpbmNsdWRlICJsb2dEdW1wLmgiCiNpbmNsdWRlICJzbWVRb3NJbnRlcm5hbC5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZUluc2lkZS5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9ldmVudC5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9sb2cuaCIKI2luY2x1ZGUgImNzckFwaS5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZV9BcGkuaCIKI2luY2x1ZGUgImNzck5laWdoYm9yUm9hbS5oIgojaW5jbHVkZSAibWFjVHJhY2UuaCIKI2lmIGRlZmluZWQoRkVBVFVSRV9XTEFOX0VTRSkgJiYgIWRlZmluZWQoRkVBVFVSRV9XTEFOX0VTRV9VUExPQUQpCiNpbmNsdWRlICJjc3JFc2UuaCIKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTEZSX01CQgojaW5jbHVkZSAiY3NyX3JvYW1fbWJiLmgiCiNlbmRpZgoKI2RlZmluZSBXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlOR19ERUJVRyAxCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlOR19ERUJVRwojZGVmaW5lIE5FSUdIQk9SX1JPQU1fREVCVUcgc21zTG9nCiNlbHNlCiNkZWZpbmUgTkVJR0hCT1JfUk9BTV9ERUJVRyh4Li4uKQojZW5kaWYKCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0Q2hhbm5lbEluZm8odHBDc3JOZWlnaGJvclJvYW1DaGFubmVsSW5mbyByQ2hJbmZvKTsKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDZmdMaXN0Q2hhblNjYW5Db250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKTsKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRQcmVhdXRoQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYyk7CnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24odHBBbmlTaXJHbG9iYWwgcE1hYyk7CgpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLCB2X1U4X3QgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSk7ClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgKHZfUFZPSURfdCBwQWRhcHRlciwgdl9VOF90IHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1BWT0lEX3QgcFVzZXJDdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9TN190IGF2Z1Jzc2kpOwp2b2lkIGNzck5laWdoYm9yUm9hbVJSTU5laWdoYm9yUmVwb3J0UmVzdWx0KHZvaWQgKmNvbnRleHQsIFZPU19TVEFUVVMgdm9zU3RhdHVzKTsKZUhhbFN0YXR1cyBjc3JSb2FtQ29weUNvbm5lY3RlZFByb2ZpbGUodHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkLCB0Q3NyUm9hbVByb2ZpbGUgKnBEc3RQcm9maWxlICk7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpOwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMpOwojZW5kaWYKCnZfVThfdCAqY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyh2X1U4X3Qgc3RhdGUpCnsKICAgIHN3aXRjaChzdGF0ZSkKICAgIHsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DTE9TRUQgKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyApOwogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWSApOwogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcgKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUgKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9MRlJfTUJCCiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9NQkJfUFJFQVVUSF9SRUFTU09DKTsKI2VuZGlmCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuICJlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVU5LTk9XTiI7CiAgICB9Cgp9CgovKiBTdGF0ZSBUcmFuc2l0aW9uIG1hY3JvICovCiNkZWZpbmUgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihuZXdTdGF0ZSlcCntcCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucHJldk5laWdoYm9yUm9hbVN0YXRlID0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlO1wKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSA9IG5ld1N0YXRlO1wKICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9ERUJVRywgXAogICAgICAgICAgICAgICBGTCgiTmVpZ2hib3IgUm9hbSBUcmFuc2l0aW9uIGZyb20gc3RhdGUgJXMgPT0+ICVzIiksIFwKICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnByZXZOZWlnaGJvclJvYW1TdGF0ZSksIFwKICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyAobmV3U3RhdGUpKTtcCn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1GcmVlTmVpZ2hib3JSb2FtQlNTTm9kZQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBmcmVlcyBhbGwgdGhlIGludGVybmFsIHBvaW50ZXJzIENTUiBOZWlnaGJvclJvYW0gQlNTIEluZm8gCiAgICAgICAgICAgIGFuZCBhbHNvIGZyZWVzIHRoZSBub2RlIGl0c2VsZgoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgbmVpZ2hib3JSb2FtQlNTTm9kZSAtIE5laWdoYm9yIFJvYW0gQlNTIE5vZGUgdG8gYmUgZnJlZWQKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtRnJlZU5laWdoYm9yUm9hbUJTU05vZGUodHBBbmlTaXJHbG9iYWwgcE1hYywgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIG5laWdoYm9yUm9hbUJTU05vZGUpCnsKICAgIGlmIChuZWlnaGJvclJvYW1CU1NOb2RlKQogICAgewogICAgICAgIGlmIChuZWlnaGJvclJvYW1CU1NOb2RlLT5wQnNzRGVzY3JpcHRpb24pCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2ZyZWUobmVpZ2hib3JSb2FtQlNTTm9kZS0+cEJzc0Rlc2NyaXB0aW9uKTsKICAgICAgICAgICAgbmVpZ2hib3JSb2FtQlNTTm9kZS0+cEJzc0Rlc2NyaXB0aW9uID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgdm9zX21lbV9mcmVlKG5laWdoYm9yUm9hbUJTU05vZGUpOwogICAgICAgIG5laWdoYm9yUm9hbUJTU05vZGUgPSBOVUxMOwogICAgfQoKICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlbW92ZVJvYW1hYmxlQVBMaXN0RW50cnkKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmVtb3ZlcyBhIGdpdmVuIGVudHJ5IGZyb20gdGhlIGdpdmVuIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBMaXN0IC0gVGhlIGxpc3QgZnJvbSB3aGljaCB0aGUgZW50cnkgc2hvdWxkIGJlIHJlbW92ZWQKICAgICAgICAgICAgcE5laWdoYm9yRW50cnkgLSBOZWlnaGJvciBSb2FtIEJTUyBOb2RlIHRvIGJlIHJlbW92ZWQKCiAgICBccmV0dXJuIFRSVUUgaWYgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQsIGVsc2UgRkFMU0UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1SZW1vdmVSb2FtYWJsZUFQTGlzdEVudHJ5KHRwQW5pU2lyR2xvYmFsIHBNYWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0RGJsTGlua0xpc3QgKnBMaXN0LCB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcE5laWdoYm9yRW50cnkpCnsKICAgIGlmKHBMaXN0KQogICAgewogICAgICAgIHJldHVybiBjc3JMTFJlbW92ZUVudHJ5KHBMaXN0LCAmcE5laWdoYm9yRW50cnktPkxpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgIH0KCiAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlbW92aW5nIG5laWdoYm9yIEJTUyBub2RlIGZyb20gbGlzdCBmYWlsZWQuIEN1cnJlbnQgY291bnQgPSAlZCIpLCBjc3JMTENvdW50KHBMaXN0KSk7CgogICAgcmV0dXJuIGVBTklfQk9PTEVBTl9GQUxTRTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5CgogICAgXGJyaWVmICBHZXRzIHRoZSBlbnRyeSBuZXh0IHRvIHBhc3NlZCBlbnRyeS4gSWYgTlVMTCBpcyBwYXNzZWQsIHJldHVybiB0aGUgZW50cnkgaW4gdGhlIGhlYWQgb2YgdGhlIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBMaXN0IC0gVGhlIGxpc3QgZnJvbSB3aGljaCB0aGUgZW50cnkgc2hvdWxkIGJlIHJldHVybmVkCiAgICAgICAgICAgIHBOZWlnaGJvckVudHJ5IC0gTmVpZ2hib3IgUm9hbSBCU1MgTm9kZSB3aG9zZSBuZXh0IGVudHJ5IHNob3VsZCBiZSByZXR1cm5lZAoKICAgIFxyZXR1cm4gTmVpZ2hib3IgUm9hbSBCU1MgTm9kZSB0byBiZSByZXR1cm5lZAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHRwQW5pU2lyR2xvYmFsIHBNYWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdERibExpbmtMaXN0ICpwTGlzdCwgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBOZWlnaGJvckVudHJ5KQp7CiAgICB0TGlzdEVsZW0gKnBFbnRyeSA9IE5VTEw7CiAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcFJlc3VsdCA9IE5VTEw7CiAgICAKICAgIGlmKHBMaXN0KQogICAgewogICAgICAgIGlmKE5VTEwgPT0gcE5laWdoYm9yRW50cnkpCiAgICAgICAgewogICAgICAgICAgICBwRW50cnkgPSBjc3JMTFBlZWtIZWFkKHBMaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHBFbnRyeSA9IGNzckxMTmV4dChwTGlzdCwgJnBOZWlnaGJvckVudHJ5LT5MaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CiAgICAgICAgfQogICAgICAgIGlmKHBFbnRyeSkKICAgICAgICB7CiAgICAgICAgICAgIHBSZXN1bHQgPSBHRVRfQkFTRV9BRERSKHBFbnRyeSwgdENzck5laWdoYm9yUm9hbUJTU0luZm8sIExpc3QpOwogICAgICAgIH0KICAgIH0KICAgIAogICAgcmV0dXJuIHBSZXN1bHQ7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0CgogICAgXGJyaWVmICAgRW1wdGllcyBhbmQgZnJlZXMgYWxsIHRoZSBub2RlcyBpbiB0aGUgcm9hbWFibGUgQVAgbGlzdCAKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBMaXN0IC0gTmVpZ2hib3IgUm9hbSBCU1MgTGlzdCB0byBiZSBlbXB0aWVkCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QodHBBbmlTaXJHbG9iYWwgcE1hYywgdERibExpbmtMaXN0ICpwTGlzdCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBSZXN1bHQgPSBOVUxMOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkVtcHR5aW5nIHRoZSBCU1MgbGlzdC4gQ3VycmVudCBjb3VudCA9ICVkIiksIGNzckxMQ291bnQocExpc3QpKTsKCiAgICAvKiBQaWNrIHVwIHRoZSBoZWFkLCByZW1vdmUgYW5kIGZyZWUgdGhlIG5vZGUgdGlsbCB0aGUgbGlzdCBiZWNvbWVzIGVtcHR5ICovCiAgICB3aGlsZSAoKHBSZXN1bHQgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCBwTGlzdCwgTlVMTCkpICE9IE5VTEwpCiAgICB7CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVtb3ZlUm9hbWFibGVBUExpc3RFbnRyeShwTWFjLCBwTGlzdCwgcFJlc3VsdCk7CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtRnJlZU5laWdoYm9yUm9hbUJTU05vZGUocE1hYywgcFJlc3VsdCk7CiAgICB9CiAgICByZXR1cm47Cn0KCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVRyaWdnZXJIYW5kb2ZmKHRwQW5pU2lyR2xvYmFsIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8pCnsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTEZSX01CQgogICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJlbmFibGVfbGZyX21iYiAlZCBpcyBtYmIgc3VwcG9ydGVkICVkIiksCiAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5lbmFibGVfbGZyX21iYiwKICAgICAgICAgICBzbWVfSXNGZWF0dXJlU3VwcG9ydGVkQnlGVyhNQUtFX0JFRk9SRV9CUkVBSykpOwoKICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmVuYWJsZV9sZnJfbWJiCiAgICAgICAgJiYgc21lX0lzRmVhdHVyZVN1cHBvcnRlZEJ5RlcoTUFLRV9CRUZPUkVfQlJFQUspCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgICAgICYmICghcE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpCiNlbmRpZgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgICYmICghcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpCiNlbmRpZgogICAgKSB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsCiAgICAgICAgICAgICAgIEZMKCJJc3N1aW5nIHByZWF1dGggcmVhc3NvYyIpKTsKICAgICAgICBzdGF0dXMgPSBjc3JfbmVpZ2hib3Jfcm9hbV9pc3N1ZV9wcmVhdXRoX3JlYXNzb2MocE1hYyk7CiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgcE1hYy0+ZnQuZnRTbWVDb250ZXh0LmlzX3ByZWF1dGhfbGZyX21iYiA9IGZhbHNlOwogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoImlzX3ByZWF1dGhfbGZyX21iYiAlZCIpLAogICAgICAgICAgICAgICAgICAgIHBNYWMtPmZ0LmZ0U21lQ29udGV4dC5pc19wcmVhdXRoX2xmcl9tYmIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQoKCiNlbmRpZgoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICApCiAgICB7CiAgICAgICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pKQogICAgICAgIHsKICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHBNYWMpOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuID0gZVNNRV9ST0FNX1RSSUdHRVJfTk9ORTsKICAgICAgICAgICAgdm9zX21lbV9zZXQoJnBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtYnNzSWRbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbWJzc0lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgMHhGRik7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiMTFSIFJlYXNzb2MgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiIKICAgICAgICAgICAgICAgICAgICJ1bmV4cGVjdGVkIHN0YXRlICVzIiksCiAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICBWT1NfQVNTRVJUKDApOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKI2VuZGlmCgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAmJiAhY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKQojZW5kaWYKICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHBNYWMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJFU0UgUmVhc3NvYyBpbmRpY2F0aW9uIHJlY2VpdmVkIGluIHVuZXhwZWN0ZWQgc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZShwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgICAgIFZPU19BU1NFUlQoMCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgaWYgKGNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLCBDU1JfU0VTU0lPTl9JRF9JTlZBTElEKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICB8fCBjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpIHx8CiAgICAgICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pCiNlbmRpZgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlUHJlYXV0aFJlcShwTWFjKTsKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuID0gZVNNRV9ST0FNX1RSSUdHRVJfTk9ORTsKICAgICAgICAgICAgICAgICAgICB2b3NfbWVtX3NldCgmcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1ic3NJZFswXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1ic3NJZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhGRik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJMRlIgUmVhc3NvYyBpbmRpY2F0aW9uIHJlY2VpdmVkIGluIgogICAgICAgICAgICAgICAgICAgICAgICAgICAidW5leHBlY3RlZCBzdGF0ZSAlcyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAgICAgVk9TX0FTU0VSVCgwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiNlbmRpZgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVxdWVzdEhhbmRvZmYocE1hYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOb24tMTFSIFJlYXNzb2MgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgInVuZXhwZWN0ZWQgc3RhdGUgJXMgb3IgUm9hbWluZyBpcyBkaXNhYmxlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgIHJldHVybiBzdGF0dXM7Cn0KClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtVXBkYXRlRmFzdFJvYW1pbmdFbmFibGVkKHRwQW5pU2lyR2xvYmFsIHBNYWMsIGNvbnN0IHZfQk9PTF90IGZhc3RSb2FtRW5hYmxlZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgaWYgKFZPU19UUlVFID09IGZhc3RSb2FtRW5hYmxlZCkKICAgICAgICB7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9DT05ORUNUKTsKICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIG5laWdoYm9yIGxvb2t1cCBET1dOIGV2ZW50IHdpdGggVEwsIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKTsKICAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgICBpZiAoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKFZPU19GQUxTRSA9PSBmYXN0Um9hbUVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJDdXJyZW50bHkgaW4gQ09OTkVDVEVEIHN0YXRlLCBzbyBkZXJlZ2lzdGVyIGFsbCBldmVudHMiKSk7CiAgICAgICAgICAgIC8qIERlLXJlZ2lzdGVyIGV4aXN0aW5nIGxvb2t1cCBVUC9ET1dOLCBSc3NpIGluZGljYXRpb25zICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLCBSRUFTT05fRElTQ09OTkVDVEVEKTsKICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIElOSVQgc3RhdGUsIE5vdGhpbmcgdG8gZG8iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLAogICAgICAgIEZMKCJVbmV4cGVjdGVkIHN0YXRlICVzLCByZXR1cm5pbmcgZmFpbHVyZSIpLAogICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1VcGRhdGVFc2VNb2RlRW5hYmxlZCh0cEFuaVNpckdsb2JhbCBwTWFjLCBjb25zdCB2X0JPT0xfdCBlc2VNb2RlKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBpZiAoVk9TX1RSVUUgPT0gZXNlTW9kZSkKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIG5laWdoYm9yIGxvb2t1cCBET1dOIGV2ZW50IHdpdGggVEwsIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwgUkVBU09OX0NPTk5FQ1QpOwogICAgICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgICBpZiAoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKFZPU19GQUxTRSA9PSBlc2VNb2RlKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIENPTk5FQ1RFRCBzdGF0ZSwgc28gZGVyZWdpc3RlciBhbGwgZXZlbnRzIikpOwogICAgICAgICAgICAvKiBEZS1yZWdpc3RlciBleGlzdGluZyBsb29rdXAgVVAvRE9XTiwgUnNzaSBpbmRpY2F0aW9ucyAqLwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCwgUkVBU09OX0RJU0NPTk5FQ1RFRCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkN1cnJlbnRseSBpbiBJTklUIHN0YXRlLCBOb3RoaW5nIHRvIGRvIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIlVuZXhwZWN0ZWQgc3RhdGUgJWQsIHJldHVybmluZyBmYWlsdXJlIiksIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICB9CiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgojZW5kaWYKCgpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVNldExvb2t1cFJzc2lUaHJlc2hvbGQodHBBbmlTaXJHbG9iYWwgcE1hYywgdl9VOF90IG5laWdoYm9yTG9va3VwUnNzaVRocmVzaG9sZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIENPTk5FQ1RFRCBzdGF0ZSwgc28gZGVyZWdpc3RlciBhbGwgYW5kIHJlLXJlZ2lzdGVyIGZvciBET1dOIGV2ZW50IGFnYWluIikpOwoKICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gbmVpZ2hib3JMb29rdXBSc3NpVGhyZXNob2xkOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwoKICAgICAgICAvKiBEZS1yZWdpc3RlciBleGlzdGluZyBsb29rdXAgVVAvRE9XTiwgUnNzaSBpbmRpY2F0aW9ucyAqLwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgIHsKICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1VQREFURV9DRkcsIFJFQVNPTl9MT09LVVBfVEhSRVNIX0NIQU5HRUQpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewojZW5kaWYKICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwoKICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgRkwoIlJlZ2lzdGVyaW5nIG5laWdoYm9yIGxvb2t1cCBET1dOIGV2ZW50IHdpdGggVEwsIFJTU0kgPSAlZCIpLAogICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpOwogICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgRE9XTiBldmVudCBvbmx5ICovCiAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiAgICAgICAgICAgaWYgKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICB7CiAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICB9CiNlbmRpZgogICAgfQogICAgZWxzZSBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkN1cnJlbnRseSBpbiBJTklUIHN0YXRlLCBzYWZlIHRvIHNldCBsb29rdXBSc3NpIHRocmVzaG9sZCIpKTsKICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gbmVpZ2hib3JMb29rdXBSc3NpVGhyZXNob2xkOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwKICAgICAgICBGTCgiVW5leHBlY3RlZCBzdGF0ZSAlcywgcmV0dXJuaW5nIGZhaWx1cmUiKSwKICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZShwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sKCiAgICBcYnJpZWYgUmVhc3NvYyBjYWxsYmFjayBpbnZva2VkIGJ5IFRMIG9uIGNyb3NzaW5nIHRoZSByZWdpc3RlcmVkIHJlLWFzc29jIHRocmVzaG9sZC4KICAgICAgICAgICBEaXJlY3RseSB0cmlnZ2VyZSBITyBpbiBjYXNlIG9mIG5vbi0xMXIgYXNzb2NpYXRpb24KICAgICAgICAgICBJbiBjYXNlIG9mIDExUiBhc3NvY2lhdGlvbiwgdHJpZ2dlcnMgYSBwcmUtYXV0aCBldmVudHVhbGx5IGZvbGxvd2VkIGJ5IGFjdHVhbCBITwoKICAgIFxwYXJhbSAgcEFkYXB0ZXIgLSBWT1MgQ29udGV4dAogICAgICAgICAgICB0cmFmZmljU3RhdHVzIC0gVVAvRE9XTiBpbmRpY2F0aW9uIGZyb20gVEwKICAgICAgICAgICAgcFVzZXJDdHh0IC0gUGFyYW1ldGVyIGZvciBjYWxsYmFjayByZWdpc3RlcmVkIGR1cmluZyBjYWxsYmFjayByZWdpc3RyYXRpb24uIFNob3VsZCBiZSBwTWFjCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjayh2X1BWT0lEX3QgcEFkYXB0ZXIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9VOF90IHRyYWZmaWNTdGF0dXMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9QVk9JRF90IHBVc2VyQ3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUzdfdCAgIGF2Z1Jzc2kpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVCggcFVzZXJDdHh0ICk7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOyAgIAoKICAgIGlmIChlU01FX1JPQU1fVFJJR0dFUl9GQVNUX1JPQU0gIT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJEZXJlZ2lzdGVyaW5nIERPV04gZXZlbnQgcmVhc3NvYyBjYWxsYmFjayB3aXRoIFRMLiBUaHJlc2hvbGQgUlNTSSA9ICVkIFJlcG9ydGVkIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgYXZnUnNzaSk7CgogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICB9CgogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJjdmQgcmVhc3NvYyBub3RpZmljYXRpb24tZGVyZWdpc3RlciBVUCBpbmRpY2F0aW9uLiBUaHJlc2hvbGQgUlNTSSA9ICVkIFJlcG9ydGVkIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSwgYXZnUnNzaSk7CiAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwoKICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgIHsKICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgfQogICAgfQogICAgLyogV2UgZG9udCBuZWVkIHRvIHJ1biB0aGlzIHRpbWVyIGFueSBtb3JlLiAqLwogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwoKICAgIGNzck5laWdoYm9yUm9hbVRyaWdnZXJIYW5kb2ZmKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvKTsKCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKkNsZWFuVVAgUm91dGluZXMqLwpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldENoYW5uZWxJbmZvKHRwQ3NyTmVpZ2hib3JSb2FtQ2hhbm5lbEluZm8gckNoSW5mbykKewogICAgICAgIGlmICgockNoSW5mby0+SUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID09IEZBTFNFKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAockNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzKSkKICAgICAgICB7CiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jdXJyZW50Q2hhbkluZGV4ID0gQ1NSX05FSUdIQk9SX1JPQU1fSU5WQUxJRF9DSEFOTkVMX0lOREVYOwogICAgICAgICAgICAgICAgckNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKCiAgICAgICAgICAgICAgICBpZiAockNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCkKICAgICAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwoKICAgICAgICAgICAgICAgIHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgckNoSW5mby0+Y2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICB9CiAgICAgICAgZWxzZSAKICAgICAgICB7CiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jdXJyZW50Q2hhbkluZGV4ID0gMDsKICAgICAgICAgICAgICAgIHJDaEluZm8tPmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICB9Cn0KCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0Q2ZnTGlzdENoYW5TY2FuQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgICAgICAvKiBTdG9wIG5laWdoYm9yIHNjYW4gdGltZXIgKi8KICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKCiAgICAgICAgLyogU3RvcCBuZWlnaGJvciBzY2FuIHJlc3VsdHMgcmVmcmVzaCB0aW1lciAqLwogICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKCiAgICAgICAgLyogU3RvcCBlbXB0eSBzY2FuIHJlc3VsdHMgcmVmcmVzaCB0aW1lciAqLwogICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKCiAgICAgICAgLyogQWJvcnQgYW55IG9uZ29pbmcgc2NhbiAqLwogICAgICAgIGlmIChlQU5JX0JPT0xFQU5fVFJVRSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJzcFBlbmRpbmcpCiAgICAgICAgewogICAgICAgICAgICBjc3JTY2FuQWJvcnRNYWNTY2FuKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9TQ0FOX0FCT1JUX0RFRkFVTFQpOwogICAgICAgIH0KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgICAgIC8qIFJlc2V0IHJvYW0gY2hhbm5lbCBsaXN0IGluZm9ybWF0aW9uICovCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDaGFubmVsSW5mbygmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mbyk7Cn0KCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0UHJlYXV0aENvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAvKiBQdXJnZSBwcmUtYXV0aCBmYWlsIGxpc3QgKi8KICAgICAgICBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsZWRMaXN0KHBNYWMpOwojZW5kaWYKCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICAvKiBEbyBub3QgZnJlZSB1cCB0aGUgcHJlYXV0aCBkb25lIGxpc3QgaGVyZSAqLwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtID0gMDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKICAgICAgICB2b3NfbWVtX3plcm8ocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm8sIHNpemVvZih0Q3NyTmVpZ2hib3JSZXBvcnRCc3NJbmZvKSAqIE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKTsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0ggPSAwOwogICAgdm9zX21lbV96ZXJvKCZwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8sIHNpemVvZih0Q3NySGFuZG9mZlJlcXVlc3QpKTsKI2VuZGlmCgp9CgpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgICAgICBWT1NfU1RBVFVTICAgICAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkRlcmVnaXN0ZXIgbmVpZ2hib3IgbG9va3VwIFVQIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSk7CgogICAgICAgIC8qIERlcmVnaXN0ZXIgcmVhc3NvYyBjYWxsYmFjay4gSWdub3JlIHJldHVybiBzdGF0dXMgKi8KICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsIAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsIAogICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICB9CgogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkRlcmVnaXN0ZXJpbmcgcmVhc3NvYyBET1dOIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpKTsKCiAgICAgICAgLyogRGVyZWdpc3RlciByZWFzc29jIGNhbGxiYWNrLiBJZ25vcmUgcmV0dXJuIHN0YXR1cyAqLwogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCIgQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sgd2l0aCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgfQoKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJEZXJlZ2lzdGVyaW5nIG5laWdoYm9yTG9va3VwIERPV04gY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkIiksIAogICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSk7CgogICAgICAgIC8qIERlcmVnaXN0ZXIgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrLiBJZ25vcmUgcmV0dXJuIHN0YXR1cyAqLwogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiIENvdWxkbid0IGRlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgfQoKICAgICAgICAvKiBSZXNldCB0aHJlc2hvbGRzIG9ubHkgYWZ0ZXIgZGVyZWdpc3RlcmluZyBET1dOIGV2ZW50IGZyb20gVEwgKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSAwOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9IERFRkFVTFRfU0NBTjsKI2VuZGlmCn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gd2lsbCByZXNldCB0aGUgbmVpZ2hib3Igcm9hbSBjb250cm9sIGluZm8gZGF0YSBzdHJ1Y3R1cmVzLiAKICAgICAgICAgICAgVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgaW52b2tlZCB3aGVuZXZlciB3ZSBtb3ZlIHRvIENPTk5FQ1RFRCBzdGF0ZSBmcm9tIAogICAgICAgICAgICBhbnkgc3RhdGUgb3RoZXIgdGhhbiBJTklUIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDaGFubmVsSW5mbygmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mbyk7CiAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgCiAvKiBXZSBkb250IG5lZWQgdG8gcnVuIHRoaXMgdGltZXIgYW55IG1vcmUuICovCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIC8qIERvIG5vdCBmcmVlIHVwIHRoZSBwcmVhdXRoIGRvbmUgbGlzdCBoZXJlICovCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPSAwOwogICAgdm9zX21lbV96ZXJvKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvLCBzaXplb2YodENzck5laWdoYm9yUmVwb3J0QnNzSW5mbykgKiBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCk7CiNlbmRpZgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIID0gMDsKICAgIHZvc19tZW1femVybygmcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLCBzaXplb2YodENzckhhbmRvZmZSZXF1ZXN0KSk7CiNlbmRpZgp9Cgp2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0UmVwb3J0U2NhblN0YXRlQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkICAgICAgICAgICAgPSAgIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQ7CiAgICB2b3NfbWVtX3NldChwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQYnNzaWQsIHNpemVvZih0Q3NyQnNzaWQpLCAwKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmlzVk9BZG1pdHRlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5NaW5RQnNzTG9hZFJlcXVpcmVkID0gMDsKI2VuZGlmCgogICAgLyogU3RvcCBzY2FuIHJlZnJlc2ggdGltZXIgKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIC8qIFN0b3AgZW1wdHkgc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAvKiBQdXJnZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOyAKICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlc2V0SW5pdFN0YXRlQ29udHJvbEluZm8KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gd2lsbCByZXNldCB0aGUgbmVpZ2hib3Igcm9hbSBjb250cm9sIGluZm8gZGF0YSBzdHJ1Y3R1cmVzLiAKICAgICAgICAgICAgVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgaW52b2tlZCB3aGVuZXZlciB3ZSBtb3ZlIHRvIENPTk5FQ1RFRCBzdGF0ZSBmcm9tIAogICAgICAgICAgICBJTklUIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldEluaXRTdGF0ZUNvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKCiAgICAvKiBJbiBhZGRpdGlvbiB0byB0aGUgYWJvdmUgcmVzZXRzLCB3ZSBzaG91bGQgY2xlYXIgb2ZmIHRoZSBjdXJBUEJzc0lkL1Nlc3Npb24gSUQgaW4gdGhlIHRpbWVycyAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRSZXBvcnRTY2FuU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKfQoKCgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUJzc0lkU2NhbkZpbHRlcgoKICAgIFxicmllZiAgVGhpcyBBUEkgaXMgdXNlZCB0byBwcmVwYXJlIGEgZmlsdGVyIHRvIG9idGFpbiBzY2FuIHJlc3VsdHMgd2hlbiAKICAgICAgICAgICAgd2UgY29tcGxldGUgdGhlIHNjYW4gaW4gdGhlIFJFUE9SVF9TQ0FOIHN0YXRlIGFmdGVyIHJlY2VpdmluZyBhIAogICAgICAgICAgICB2YWxpZCBuZWlnaGJvciByZXBvcnQgZnJvbSBBUC4gVGhpcyBmaWx0ZXIgaW5jbHVkZXMgQlNTSURzIHJlY2VpdmVkIGZyb20gCiAgICAgICAgICAgIHRoZSBuZWlnaGJvciByZXBvcnQgZnJvbSB0aGUgQVAgaW4gYWRkaXRpb24gdG8gdGhlIG90aGVyIGZpbHRlciBwYXJhbWV0ZXJzIAogICAgICAgICAgICBjcmVhdGVkIGZyb20gY29ubmVjdGVkIHByb2ZpbGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBTY2FuRmlsdGVyIC0gU2NhbiBmaWx0ZXIgdG8gYmUgZmlsbGVkIGFuZCByZXR1cm5lZAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNmdWwgZmlsdGVyIGNyZWF0aW9uLCBjb3JyZXNwb25kaW5nIGVycm9yIAogICAgICAgICAgICBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtQnNzSWRTY2FuRmlsdGVyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRDc3JTY2FuUmVzdWx0RmlsdGVyICpwU2NhbkZpbHRlcikKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0QU5JX1U4IGkgPSAwOwoKICAgIFZPU19BU1NFUlQocFNjYW5GaWx0ZXIgIT0gTlVMTCk7CiAgICBpZiAocFNjYW5GaWx0ZXIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIHZvc19tZW1femVybyhwU2NhbkZpbHRlciwgc2l6ZW9mKHRDc3JTY2FuUmVzdWx0RmlsdGVyKSk7CgogICAgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyA9IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydDsKICAgIHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodFNpck1hY0FkZHIpICogcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyk7CiAgICBpZiAoTlVMTCA9PSBwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgQlNTSUQgbWVtIGFsbG9jIGZhaWxlZCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTEVEX0FMTE9DOwogICAgfQoKICAgIHZvc19tZW1femVybyhwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpICogcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyk7CgogICAgLyogUG9wdWxhdGUgdGhlIEJTU0lEIGZyb20gTmVpZ2hib3IgQlNTIGluZm8gcmVjZWl2ZWQgZnJvbSBuZWlnaGJvciByZXBvcnQgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzOyBpKyspCiAgICB7CiAgICAgICAgdm9zX21lbV9jb3B5KCZwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkW2ldLCAKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvW2ldLm5laWdoYm9yQnNzSWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgfQoKICAgIC8qIEZpbGwgb3RoZXIgZ2VuZXJhbCBzY2FuIGZpbHRlciBwYXJhbXMgKi8KICAgIHJldHVybiBjc3JOZWlnaGJvclJvYW1QcmVwYXJlU2NhblByb2ZpbGVGaWx0ZXIocE1hYywgcFNjYW5GaWx0ZXIpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbExpc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gZW1wdGllcyB0aGUgcHJlYXV0aCBmYWlsIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxMaXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIlB1cmdpbmcgdGhlIHByZWF1dGggZmFpbCBsaXN0IikpOwogICAgd2hpbGUgKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzKQogICAgewogICAgICAgIHZvc19tZW1femVybyhwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubWFjQWRkcmVzc1twTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcy0xXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MtLTsKICAgIH0KICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUFkZEJzc0lkVG9QcmVhdXRoRmFpbExpc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gYWRkcyB0aGUgZ2l2ZW4gQlNTSUQgdG8gdGhlIFByZWF1dGggZmFpbCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBic3NJZCAtIEJTU0lEIHRvIGJlIGFkZGVkIHRvIHRoZSBwcmVhdXRoIGZhaWwgbGlzdAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBlSEFMX1NUQVRVU19GQUlMVVJFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1BZGRCc3NJZFRvUHJlYXV0aEZhaWxMaXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRTaXJNYWNBZGRyIGJzc0lkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCIgQWRkZWQgQlNTSUQgIk1BQ19BRERSRVNTX1NUUiIgdG8gUHJlYXV0aCBmYWlsZWQgbGlzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShic3NJZCkpOwoKCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzICsgMSkgPgogICAgICAgICAgICBNQVhfTlVNX1BSRUFVVEhfRkFJTF9MSVNUX0FERFJFU1MpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJQcmVhdXRoIGZhaWwgbGlzdCBhbHJlYWR5IGZ1bGwuLiBDYW5ub3QgYWRkIG5ldyBvbmUiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm1hY0FkZHJlc3NbCiAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzXSwKICAgICAgICAgICAgICAgICBic3NJZCwKICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzKys7CiAgICAKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXNQcmVhdXRoQ2FuZGlkYXRlCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGNoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiBNQUMgYWRkcmVzcyBpcyBhbHJlYWR5IAogICAgICAgICAgICBwcmVzZW50IGluIHRoZSBwcmVhdXRoIGZhaWwgbGlzdCBhbmQgcmV0dXJucyBUUlVFL0ZBTFNFIGFjY29yZGluZ2x5CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUFOSV9CT09MRUFOX1RSVUUgaWYgcHJlYXV0aCBjYW5kaWRhdGUsIGVBTklfQk9PTEVBTl9GQUxTRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUodHBBbmlTaXJHbG9iYWwgcE1hYywgdFNpck1hY0FkZHIgYnNzSWQpCnsKICAgIHRBTklfVTggaSA9IDA7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIGlmIChjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgewogICAgICAgIHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRTsKICAgIH0KI2VuZGlmCiAgICBpZiAoMCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcykKICAgICAgICByZXR1cm4gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAKICAgIGZvciAoaSA9IDA7IGkgPCBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzczsgaSsrKQogICAgewogICAgICAgIGlmIChWT1NfVFJVRSA9PSB2b3NfbWVtX2NvbXBhcmUocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm1hY0FkZHJlc3NbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKSkKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkJTU0lEICJNQUNfQUREUkVTU19TVFIiIGFscmVhZHkgcHJlc2VudCBpbiBwcmVhdXRoIGZhaWwgbGlzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShic3NJZCkpOwogICAgICAgICAgICByZXR1cm4gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gZUFOSV9CT09MRUFOX1RSVUU7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXNzdWVzIHByZWF1dGggcmVxdWVzdCB0byBQRSB3aXRoIHRoZSAxc3QgQVAgZW50cnkgaW4gdGhlIAogICAgICAgICAgICByb2FtYWJsZSBBUCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBlSEFMX1NUQVRVU19GQUlMVVJFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvICAgIHBOZWlnaGJvckJzc05vZGU7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICB0Q3NyUm9hbUluZm8gKnJvYW1JbmZvOwojZW5kaWYKICAgIAogICAgLyogVGhpcyBtdXN0IG5vdCBiZSB0cnVlIGhlcmUgKi8KICAgIFZPU19BU1NFUlQocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPT0gZUFOSV9CT09MRUFOX0ZBTFNFKTsKCiAgICAvKiBJc3N1ZSBQcmVhdXRoIHJlcXVlc3QgdG8gUEUgaGVyZSAqLwogICAgLyogTmVlZCB0byBpc3N1ZSB0aGUgcHJlYXV0aCByZXF1ZXN0IHdpdGggdGhlIEJTU0lEIHRoYXQgaXMgdGhlcmUgaW4gdGhlIGhlYWQgb2YgdGhlIHJvYW1hYmxlIEFQIGxpc3QgKi8KICAgIC8qIFBhcmFtZXRlcnMgdGhhdCBzaG91bGQgYmUgcGFzc2VkIGFyZSBCU1NJRCwgQ2hhbm5lbCBudW1iZXIgYW5kIHRoZSBuZWlnaGJvclNjYW5QZXJpb2QocHJvYmFibHkpICovCiAgICAvKiBJZiByb2FtYWJsZUFQTGlzdCBnZXRzIGVtcHR5LCBzaG91bGQgdHJhbnNpdGlvbiB0byBSRVBPUlRfU0NBTiBzdGF0ZSAqLwogICAgcE5laWdoYm9yQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsIE5VTEwpOwoKICAgIGlmIChOVUxMID09IHBOZWlnaGJvckJzc05vZGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJSb2FtYWJsZSBBUCBsaXN0IGlzIGVtcHR5Li4gIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgZWxzZQogICAgewojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAgICAgLyogTEZSIG1ldHJpY3MgLSBwcmUtYXV0aCBpbml0aWF0aW9uIG1ldHJpYy4KICAgICAgICAgICBTZW5kIHRoZSBldmVudCB0byBzdXBwbGljYW50IHRoYXQgcHJlLWF1dGggd2FzIGluaXRpYXRlZCAqLwogICAgICAgIHJvYW1JbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgICAgIGlmIChOVUxMID09IHJvYW1JbmZvKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQhIikpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkoKHZvaWQgKilyb2FtSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAodm9pZCAqKXBOZWlnaGJvckJzc05vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQsCiAgICAgICAgICAgICAgICBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2FtSW5mbywgMCwgZUNTUl9ST0FNX1BSRUFVVEhfSU5JVF9OT1RJRlksIDApOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocm9hbUluZm8pOwogICAgICAgIH0KI2VuZGlmCgogICAgICAgIHN0YXR1cyA9IGNzclJvYW1FbnF1ZXVlUHJlYXV0aChwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLCBwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICBlQ3NyUGVyZm9ybVByZWF1dGgsIGVBTklfQk9PTEVBTl9UUlVFKTsKCiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJCZWZvcmUgUHJlLUF1dGg6IEJTU0lEICJNQUNfQUREUkVTU19TVFIiLCBDaDolZCIpLAogICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkKSwKICAgICAgICAgICAgICAgKGludClwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmNoYW5uZWxJZCk7CgogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2VuZCBQcmVhdXRoIHJlcXVlc3QgdG8gUEUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIHN0YXR1cyk7CiAgICAgICAgICAgIHJldHVybiBzdGF0dXM7CiAgICAgICAgfQogICAgfQogICAgCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9UUlVFOwoKICAgIC8qIEluY3JlbWVudCB0aGUgcHJlYXV0aCByZXRyeSBjb3VudCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMrKzsKICAgIAogICAgLyogVHJhbnNpdGlvbiB0aGUgc3RhdGUgdG8gcHJlYXV0aGVudGljYXRpbmcgKi8KICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhFTlRJQ0FUSU5HKQogICAgCiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHJlYXV0aFJzcEhhbmRsZXIKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaGFuZGxlIHRoZSBQcmVhdXRoIHJlc3BvbnNlIGZyb20gUEUKICAgICAgICAgICAgRXZlcnkgcHJlYXV0aCBpcyBhbGxvd2VkIG1heCAzIHRyaWVzIGlmIGl0IGZhaWxzLiBJZiBhIGJzc2lkIGZhaWxlZCAKICAgICAgICAgICAgZm9yIG1vcmUgdGhhbiBNQVhfVFJJRVMsIHdlIHdpbGwgcmVtb3ZlIGl0IGZyb20gdGhlIGxpc3QgYW5kIHRyeSAKICAgICAgICAgICAgd2l0aCB0aGUgbmV4dCBub2RlIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0IGFuZCBhZGQgdGhlIEJTU0lEIHRvIHByZS1hdXRoIGZhaWxlZCAKICAgICAgICAgICAgbGlzdC4gSWYgbm8gbW9yZSBlbnRyaWVzIHByZXNlbnQgaW4gCiAgICAgICAgICAgIHJvYW1hYmxlIEFQIGxpc3QsIHRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIGxpbVN0YXR1cyAtIGVTSVJfU1VDQ0VTUy9lU0lSX0ZBSUxVUkUvZVNJUl9MSU1fTUFYX1NUQV9SRUFDSEVEX0VSUk9SLwogICAgICAgICAgICAgICAgICAgICBlU0lUX0xJTV9BVVRIX1JTUF9USU1FT1VUIHN0YXR1cyBmcm9tIFBFCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MgKGkuZS4gcHJlLWF1dGggcHJvY2Vzc2VkKSwKICAgICAgICAgICAgZUhBTF9TVEFUVVNfRkFJTFVSRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUHJlYXV0aFJzcEhhbmRsZXIodHBBbmlTaXJHbG9iYWwgcE1hYywgdFNpclJldFN0YXR1cyBsaW1TdGF0dXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIGVIYWxTdGF0dXMgIHByZWF1dGhQcm9jZXNzZWQgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBQcmVhdXRoUnNwTm9kZSA9IE5VTEw7CiAgICB0Q3NyUm9hbVNlc3Npb24gKnBTZXNzaW9uOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICB0Q3NyUm9hbUluZm8gKnJvYW1JbmZvOwojZW5kaWYKCiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nKQogICAgewogICAgICAgICAgICAKICAgICAgICAgICAgLyogVGhpcyBjYW4gaGFwcGVuIHdoZW4gd2UgZGlzY29ubmVjdCBpbW1lZGlhdGVseQogICAgICAgICAgICAgKiBhZnRlciBzZW5kaW5nIGEgcHJlLWF1dGggcmVxdWVzdC4gRHVyaW5nIHByb2Nlc3NpbmcKICAgICAgICAgICAgICogb2YgdGhlIGRpc2Nvbm5lY3QgY29tbWFuZCwgd2Ugd291bGQgaGF2ZSByZXNldAogICAgICAgICAgICAgKiBwcmVhdXRoUnNwUGVuZGluZyBhbmQgdHJhbnNpdGlvbmVkIHRvIElOSVQgc3RhdGUuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIlVuZXhwZWN0ZWQgcHJlLWF1dGggcmVzcG9uc2UgaW4gc3RhdGUgJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgICAgICBwcmVhdXRoUHJvY2Vzc2VkID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgZ290byBERVFfUFJFQVVUSDsKICAgIH0gICAgCgogICAgLy8gV2UgY2FuIHJlY2VpdmUgaXQgaW4gdGhlc2UgMiBzdGF0ZXMuCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSAhPSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcpICYmCiAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSAhPSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4pKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywKICAgICAgICBGTCgiUHJlYXV0aCByZXNwb25zZSByZWNlaXZlZCBpbiBzdGF0ZSAlcyIpLAogICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHByZWF1dGhQcm9jZXNzZWQgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIGdvdG8gREVRX1BSRUFVVEg7CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgaWYgKGVTSVJfU1VDQ0VTUyA9PSBsaW1TdGF0dXMpCiAgICB7CiAgICAgICAgcFByZWF1dGhSc3BOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgTlVMTCk7CiAgICB9CiAgICBpZiAoKGVTSVJfU1VDQ0VTUyA9PSBsaW1TdGF0dXMpICYmIChOVUxMICE9IHBQcmVhdXRoUnNwTm9kZSkpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiUHJlYXV0aCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5IGFmdGVyICVkIHRyaWVzIiksIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzKTsKCiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJBZnRlciBQcmUtQXV0aDogQlNTSUQgIk1BQ19BRERSRVNTX1NUUiIsIENoOiVkIiksCiAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKHBQcmVhdXRoUnNwTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCksCiAgICAgICAgICAgICAgIChpbnQpcFByZWF1dGhSc3BOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmNoYW5uZWxJZCk7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAgICAgLyogTEZSIG1ldHJpY3MgLSBwcmUtYXV0aCBjb21wbGV0aW9uIG1ldHJpYy4KICAgICAgICAgICBTZW5kIHRoZSBldmVudCB0byBzdXBwbGljYW50IHRoYXQgcHJlLWF1dGggc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZCAqLwogICAgICAgIHJvYW1JbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgICAgIGlmIChOVUxMID09IHJvYW1JbmZvKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQhIikpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkoKHZvaWQgKilyb2FtSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAodm9pZCAqKXBQcmVhdXRoUnNwTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwKICAgICAgICAgICAgICAgIHNpemVvZih0Q3NyQnNzaWQpKTsKICAgICAgICAgICAgY3NyUm9hbUNhbGxDYWxsYmFjayhwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLAogICAgICAgICAgICAgICAgcm9hbUluZm8sIDAsIGVDU1JfUk9BTV9QUkVBVVRIX1NUQVRVU19TVUNDRVNTLCAwKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHJvYW1JbmZvKTsKICAgICAgICB9CiNlbmRpZgoKICAgICAgICAvKiBQcmVhdXRoIGNvbXBldGVyIHN1Y2Nlc3NmdWxseS4gSW5zZXJ0IHRoZSBwcmVhdXRoZW50aWNhdGVkIG5vZGUgdG8gdGFpbCBvZiBwcmVBdXRoRG9uZUxpc3QgKi8KICAgICAgICBjc3JOZWlnaGJvclJvYW1SZW1vdmVSb2FtYWJsZUFQTGlzdEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsIHBQcmVhdXRoUnNwTm9kZSk7CiAgICAgICAgY3NyTExJbnNlcnRUYWlsKCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsICZwUHJlYXV0aFJzcE5vZGUtPkxpc3QsIExMX0FDQ0VTU19MT0NLKTsKCiAgICAgICAgLyogUHJlLWF1dGggY29tcGxldGVkIHN1Y2Nlc3NmdWxseS4gVHJhbnNpdGlvbiB0byBQUkVBVVRIIERvbmUgc3RhdGUgKi8KICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUpCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwoKICAgICAgICAvKiBUaGUgY2FsbGVyIG9mIHRoaXMgZnVuY3Rpb24gd291bGQgc3RhcnQgYSB0aW1lciBhbmQgYnkgdGhlIHRpbWUgaXQgZXhwaXJlcywgc3VwcGxpY2FudCBzaG91bGQgCiAgICAgICAgICAgaGF2ZSBwcm92aWRlZCB0aGUgdXBkYXRlZCBGVElFcyB0byBTTUUuIFNvLCB3aGVuIGl0IGV4cGlyZXMsIGhhbmRvZmYgd2lsbCBiZSB0cmlnZ2VyZWQgdGhlbiAqLwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICBwTmVpZ2hib3JCc3NOb2RlID0gTlVMTDsKICAgICAgICB0TGlzdEVsZW0gICAgICAgICAgICAgICAgICAgKnBFbnRyeTsKICAgICAgICB1aW50MzJfdCAgICAgICAgICAgICAgICAgICAgcmV0cmllczsKCiAgICAgICAgcmV0cmllcyA9IHBNYWMtPnN0YV9hdXRoX3JldHJpZXNfZm9yX2NvZGUxNyA+CiAgICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX01BWF9OVU1fUFJFQVVUSF9SRVRSSUVTID8KICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+c3RhX2F1dGhfcmV0cmllc19mb3JfY29kZTE3IDoKICAgICAgICAgICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fTUFYX05VTV9QUkVBVVRIX1JFVFJJRVM7CgogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUHJlYXV0aCBmYWlsZWQgcmV0cnkgbnVtYmVyICVkLCBzdGF0dXMgPSAweCV4IiksCiAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzLCBsaW1TdGF0dXMpOwogICAgICAgIAogICAgICAgIC8qIFByZWF1dGggZmFpbGVkLiBBZGQgdGhlIGJzc0lkIHRvIHRoZSBwcmVBdXRoIGZhaWxlZCBsaXN0IE1BQyBBZGRyZXNzLiBBbHNvIHJlbW92ZSB0aGUgQVAgZnJvbSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA+PSByZXRyaWVzKSB8fAogICAgICAgICAgICAgKChlU0lSX0xJTV9NQVhfU1RBX1JFQUNIRURfRVJST1IgPT0gbGltU3RhdHVzKSAmJgogICAgICAgICAgICAgKHBNYWMtPnN0YV9hdXRoX3JldHJpZXNfZm9yX2NvZGUxNyA9PSAwKSkpCiAgICAgICAgewogICAgICAgICAgICAvKiBXZSBhcmUgZ29pbmcgdG8gcmVtb3ZlIHRoZSBub2RlIGFzIGl0IGZhaWxzIGZvciBtb3JlIHRoYW4gTUFYIHRyaWVzLiBSZXNldCB0aGlzIGNvdW50IHRvIDAgKi8KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwoKICAgICAgICAgICAgLyogVGhlIG9uZSBpbiB0aGUgaGVhZCBvZiB0aGUgbGlzdCBzaG91bGQgYmUgb25lIHdpdGggd2hpY2ggd2UgaXNzdWVkIHByZS1hdXRoIGFuZCBmYWlsZWQgKi8KICAgICAgICAgICAgcEVudHJ5ID0gY3NyTExSZW1vdmVIZWFkKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgICAgICAgICAgaWYocEVudHJ5KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JCc3NOb2RlID0gR0VUX0JBU0VfQUREUihwRW50cnksIHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvLCBMaXN0KTsKICAgICAgICAgICAgICAgIC8qIEFkZCB0aGUgQlNTSUQgdG8gcHJlLWF1dGggZmFpbCBsaXN0IGlmIGl0IGlzIG5vdCByZXF1ZXN0ZWQgYnkgSEREICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIGlmKCFwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKI2VuZGlmCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUFkZEJzc0lkVG9QcmVhdXRoRmFpbExpc3QocE1hYywgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCk7CiAgICAgICAgICAgICAgICB9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAgICAgICAgICAgICAvKiBMRlIgbWV0cmljcyAtIHByZS1hdXRoIGNvbXBsZXRpb24gbWV0cmljLiBTZW5kIHRoZSBldmVudAogICAgICAgICAgICAgICAgICAgdG8gc3VwcGxpY2FudCB0aGF0IHByZS1hdXRoIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgKi8KICAgICAgICAgICAgICAgIHJvYW1JbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgICAgICAgICAgICAgaWYgKE5VTEwgPT0gcm9hbUluZm8pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQhIikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fY29weSgodm9pZCAqKXJvYW1JbmZvLT5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKilwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgICAgICAgICAgY3NyUm9hbUNhbGxDYWxsYmFjayhwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICByb2FtSW5mbywgMCwgZUNTUl9ST0FNX1BSRUFVVEhfU1RBVFVTX0ZBSUxVUkUsIDApOwogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShyb2FtSW5mbyk7CiAgICAgICAgICAgICAgICB9CiNlbmRpZgoKICAgICAgICAgICAgLyogTm93IHdlIGNhbiBmcmVlIHRoaXMgbm9kZSAqLwogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1GcmVlTmVpZ2hib3JSb2FtQlNTTm9kZShwTWFjLCBwTmVpZ2hib3JCc3NOb2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwU2Vzc2lvbiA9IENTUl9HRVRfU0VTU0lPTihwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkKTsKICAgICAgICBpZiAoKE5VTEwgIT0gcFNlc3Npb24pICYmIHBTZXNzaW9uLT5hYm9ydENvbm5lY3Rpb24pCiAgICAgICAgewogICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIERlYXV0aCBpbiBwcm9ncmVzcyBBYm9ydCBwcmVhdXRoIikpOwogICAgICAgICAgIGdvdG8gYWJvcnRfcHJlYXV0aDsKICAgICAgICB9CgogICAgICAgIGlmIChwTWFjLT5yb2FtLnBlbmRpbmdfcm9hbV9kaXNhYmxlKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJwcm9jZXNzIHBlbmRpbmcgcm9hbSBkaXNhYmxlIikpOwogICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzRmFzdFJvYW1JbmlGZWF0dXJlRW5hYmxlZCA9IEZBTFNFOwogICAgICAgICAgICBwTWFjLT5yb2FtLnBlbmRpbmdfcm9hbV9kaXNhYmxlID0gRkFMU0U7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVVwZGF0ZUZhc3RSb2FtaW5nRW5hYmxlZChwTWFjLCBGQUxTRSk7CiAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICAgICAgICAgIGdvdG8gREVRX1BSRUFVVEg7CiAgICAgICAgfQoKICAgICAgICAvKiBJc3N1ZSBwcmVhdXRoIHJlcXVlc3QgZm9yIHRoZSBzYW1lL25leHQgZW50cnkgKi8KICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyA9PSBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEocE1hYykpCiAgICAgICAgZ290byBERVFfUFJFQVVUSDsgCgphYm9ydF9wcmVhdXRoOgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewogICAgICAgICAgaWYocE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpCiAgICAgICAgICB7CiAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9QUkVBVVRIX0ZBSUxFRF9GT1JfQUxMKTsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgaWYocE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCkKICAgICAgICAgIHsKICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0ggPSAwOwogICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJGb3JjZWQgNUcgcm9hbWluZyBwcmVhdXRoIGdvdCBmYWlsZWQiCiAgICAgICAgICAgICAgICAgICAgInNlbmQgUlNPIFNUQVJUIGNtZCB0byBmd3IuIikpOwogICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsUkVBU09OX0NPTk5FQ1QpOwogICAgICAgICAgfQogICAgICAgICAgZWxzZQogICAgICAgICAgewogICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1JFU1RBUlQsIFJFQVNPTl9QUkVBVVRIX0ZBSUxFRF9GT1JfQUxMKTsKICAgICAgICAgIH0KICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICAgICAgfSBlbHNlCiAgICAgICAgewojZW5kaWYKICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOKTsKCiAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIFVQIGV2ZW50IG5vdyAqLwogICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiTm8gbW9yZSBwcmUtYXV0aCBjYW5kaWRhdGVzLSIKICAgICAgICAgICAgICAgICAgInJlZ2lzdGVyIFVQIGluZGljYXRpb24gd2l0aCBUTC4gUlNTSSA9ICVkLCIpLCBORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpKTsKCiAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgewogICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwQ2FsbGJhY2sgVVAgZXZlbnQgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgc3RhdHVzKTsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBTdGFydCB0aGUgbmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIGFuZCB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlIHRvIHBlcmZvcm0gc2NhbiBhZ2FpbiAqLwogICAgICAgICAgc3RhdHVzID0gdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCk7CiAgICAgICAgICBpZiAoIHN0YXR1cyAhPSBlSEFMX1NUQVRVU19TVUNDRVNTICkKICAgICAgICAgIHsKICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIHN0YXJ0IGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBzdGF0dXMpOwogICAgICAgICAgfQogICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgfQojZW5kaWYKCkRFUV9QUkVBVVRIOgogICAgY3NyUm9hbURlcXVldWVQcmVhdXRoKHBNYWMpOwogICAgcmV0dXJuIHByZWF1dGhQcm9jZXNzZWQ7Cn0KI2VuZGlmICAvKiBXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlORyAqLwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByZXBhcmVTY2FuUHJvZmlsZUZpbHRlcgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBjcmVhdGVzIGEgc2NhbiBmaWx0ZXIgYmFzZWQgb24gdGhlIGN1cnJlbnRseSBjb25uZWN0ZWQgcHJvZmlsZS4KICAgICAgICAgICAgQmFzZWQgb24gdGhpcyBmaWx0ZXIsIHNjYW4gcmVzdWx0cyBhcmUgb2J0YWluZWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBTY2FuRmlsdGVyIC0gUG9wdWxhdGVkIHNjYW4gZmlsdGVyIGJhc2VkIG9uIHRoZSBjb25uZWN0ZWQgcHJvZmlsZQoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBlSEFMX1NUQVRVU19GQUlMVVJFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1QcmVwYXJlU2NhblByb2ZpbGVGaWx0ZXIodHBBbmlTaXJHbG9iYWwgcE1hYywgdENzclNjYW5SZXN1bHRGaWx0ZXIgKnBTY2FuRmlsdGVyKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBTklfVTggc2Vzc2lvbklkICAgPSAodEFOSV9VOClwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkOwogICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwQ3VyUHJvZmlsZSA9ICZwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZTsKICAgIHRBTklfVTggaSA9IDA7CiAgICAKICAgIFZPU19BU1NFUlQocFNjYW5GaWx0ZXIgIT0gTlVMTCk7CiAgICBpZiAocFNjYW5GaWx0ZXIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKCiAgICB2b3NfbWVtX3plcm8ocFNjYW5GaWx0ZXIsIHNpemVvZih0Q3NyU2NhblJlc3VsdEZpbHRlcikpOwoKICAgIC8qIFdlIGRvbnQgd2FudCB0byBzZXQgQlNTSUQgYmFzZWQgRmlsdGVyICovCiAgICBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzID0gMDsKCiAgICAvL29ubHkgZm9yIEhERCByZXF1ZXN0ZWQgaGFuZG9mZiBmaWxsIGluIHRoZSBCU1NJRCBpbiB0aGUgZmlsdGVyCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKICAgIHsKCiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJPUyBSZXF1ZXN0ZWQgSGFuZG9mZiIpKTsKICAgICAgICBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzID0gMTsKICAgICAgICBwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwogICAgICAgIGlmIChOVUxMID09IHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlNjYW4gRmlsdGVyIEJTU0lEIG1lbSBhbGxvYyBmYWlsZWQiKSk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICAgICAgfQoKICAgICAgICB2b3NfbWVtX3plcm8ocFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwoKICAgICAgICAvKiBQb3B1bGF0ZSB0aGUgQlNTSUQgZnJvbSBoYW5kb2ZmIGluZm8gcmVjZWl2ZWQgZnJvbSBIREQgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEczsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KCZwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICB9CiAgICB9CiNlbmRpZgogICAgLyogUG9wdWxhdGUgYWxsIHRoZSBpbmZvcm1hdGlvbiBmcm9tIHRoZSBjb25uZWN0ZWQgcHJvZmlsZSAqLwogICAgcFNjYW5GaWx0ZXItPlNTSURzLm51bU9mU1NJRHMgPSAxOyAgCiAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodENzclNTSURJbmZvKSk7CiAgICBpZiAoTlVMTCA9PSBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBTU0lEIG1lbSBhbGxvYyBmYWlsZWQiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxFRF9BTExPQzsKICAgIH0KICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+aGFuZG9mZlBlcm1pdHRlZCA9IDE7CiAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPnNzaWRIaWRkZW4gPSAwOwogICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELmxlbmd0aCA9ICBwQ3VyUHJvZmlsZS0+U1NJRC5sZW5ndGg7CiAgICB2b3NfbWVtX2NvcHkoKHZvaWQgKilwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQuc3NJZCwgKHZvaWQgKilwQ3VyUHJvZmlsZS0+U1NJRC5zc0lkLCBwQ3VyUHJvZmlsZS0+U1NJRC5sZW5ndGgpOyAKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJGaWx0ZXJpbmcgZm9yIFNTSUQgJS4qcyBmcm9tIHNjYW4gcmVzdWx0cywiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImxlbmd0aCBvZiBTU0lEID0gJXUiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQubGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5zc0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5sZW5ndGgpOwogICAgcFNjYW5GaWx0ZXItPmF1dGhUeXBlLm51bUVudHJpZXMgPSAxOwogICAgcFNjYW5GaWx0ZXItPmF1dGhUeXBlLmF1dGhUeXBlWzBdID0gcEN1clByb2ZpbGUtPkF1dGhUeXBlOwoKICAgIHBTY2FuRmlsdGVyLT5FbmNyeXB0aW9uVHlwZS5udW1FbnRyaWVzID0gMTsgLy9UaGlzIG11c3QgYmUgMQogICAgcFNjYW5GaWx0ZXItPkVuY3J5cHRpb25UeXBlLmVuY3J5cHRpb25UeXBlWzBdID0gcEN1clByb2ZpbGUtPkVuY3J5cHRpb25UeXBlOwoKICAgIHBTY2FuRmlsdGVyLT5tY0VuY3J5cHRpb25UeXBlLm51bUVudHJpZXMgPSAxOwogICAgcFNjYW5GaWx0ZXItPm1jRW5jcnlwdGlvblR5cGUuZW5jcnlwdGlvblR5cGVbMF0gPSBwQ3VyUHJvZmlsZS0+bWNFbmNyeXB0aW9uVHlwZTsKCiAgICBwU2NhbkZpbHRlci0+QlNTVHlwZSA9IHBDdXJQcm9maWxlLT5CU1NUeXBlOwoKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscykKICAgIHsKICAgICAgIC8qIFdlIGFyZSBpbnRyZXN0ZWQgb25seSBpbiB0aGUgc2NhbiByZXN1bHRzIG9uIGNoYW5uZWxzIHRoYXQgd2Ugc2Nhbm5lZCAgKi8KICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVsczsKICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9CiAgICAgICAgdm9zX21lbV9tYWxsb2MocFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwogICAgICAgaWYgKE5VTEwgPT0gcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KQogICAgICAgewogICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBDaGFubmVsIGxpc3QgbWVtIGFsbG9jIGZhaWxlZCIpKTsKICAgICAgICAgIHZvc19tZW1fZnJlZShwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QpOwogICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0ID0gTlVMTDsKICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICAgICB9CiAgICAgICBmb3IgKGkgPSAwOyBpIDwgcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHM7IGkrKykKICAgICAgIHsKICAgICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdFtpXSA9CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdFtpXTsKICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIGlmIChwTWFjLT5QRVJyb2FtQ2FuZGlkYXRlc0NudCkKICAgICAgIHBTY2FuRmlsdGVyLT5pc1BFUlJvYW1TY2FuID0gdHJ1ZTsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQogICAgewogICAgICAgIC8qIE1ESUUgc2hvdWxkIGJlIGFkZGVkIGFzIGEgcGFydCBvZiBwcm9maWxlLiBUaGlzIHNob3VsZCBiZSBhZGRlZCBhcyBhIHBhcnQgb2YgZmlsdGVyIGFzIHdlbGwgICovCiAgICAgICAgcFNjYW5GaWx0ZXItPk1ESUQubWRpZVByZXNlbnQgPSBwQ3VyUHJvZmlsZS0+TURJRC5tZGllUHJlc2VudDsKICAgICAgICBwU2NhbkZpbHRlci0+TURJRC5tb2JpbGl0eURvbWFpbiA9IHBDdXJQcm9maWxlLT5NRElELm1vYmlsaXR5RG9tYWluOwogICAgfQojZW5kaWYKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfMTFXCiAgICBwU2NhbkZpbHRlci0+TUZQRW5hYmxlZCA9IHBDdXJQcm9maWxlLT5NRlBFbmFibGVkOwogICAgcFNjYW5GaWx0ZXItPk1GUFJlcXVpcmVkID0gcEN1clByb2ZpbGUtPk1GUFJlcXVpcmVkOwogICAgcFNjYW5GaWx0ZXItPk1GUENhcGFibGUgPSBwQ3VyUHJvZmlsZS0+TUZQQ2FwYWJsZTsKI2VuZGlmCgogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCnRBTklfVTMyIGNzckdldEN1cnJlbnRBUFJzc2kodHBBbmlTaXJHbG9iYWwgcE1hYywgdFNjYW5SZXN1bHRIYW5kbGUgKnBTY2FuUmVzdWx0TGlzdCkKewogICAgICAgIHRDc3JTY2FuUmVzdWx0SW5mbyAqcFNjYW5SZXN1bHQ7CiAgICAgICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgdEFOSV9VMzIgQ3VyckFQUnNzaSA9IHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaTsKI2Vsc2UKICAgICAgICAvKiBXZSBhcmUgc2V0dGluZyB0aGlzIGFzIGRlZmF1bHQgdmFsdWUgdG8gbWFrZSBzdXJlIHdlIHJldHVybiB0aGlzIHZhbHVlLAogICAgICAgIHdoZW4gd2UgZG8gbm90IHNlZSB0aGlzIEFQIGluIHRoZSBzY2FuIHJlc3VsdCBmb3Igc29tZSByZWFzb24uSG93ZXZlcixpdCBpcwogICAgICAgIGxlc3MgbGlrZWx5IHRoYXQgd2UgYXJlIGFzc29jaWF0ZWQgdG8gYW4gQVAgYW5kIGRvIG5vdCBzZWUgaXQgaW4gdGhlIHNjYW4gbGlzdCAqLwogICAgICAgIHRBTklfVTMyIEN1cnJBUFJzc2kgPSAtMTI1OwojZW5kaWYKCiAgICAgICAgd2hpbGUgKE5VTEwgIT0gKHBTY2FuUmVzdWx0ID0gY3NyU2NhblJlc3VsdEdldE5leHQocE1hYywgKnBTY2FuUmVzdWx0TGlzdCkpKQogICAgICAgIHsKCiAgICAgICAgICAgICAgICBpZiAoVk9TX1RSVUUgPT0gdm9zX21lbV9jb21wYXJlKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBXZSBnb3QgYSBtYXRjaCB3aXRoIHRoZSBjdXJyZW50bHkgYXNzb2NpYXRlZCBBUC4KICAgICAgICAgICAgICAgICAgICAgICAgICogQ2FwdHVyZSB0aGUgUlNTSSB2YWx1ZSBhbmQgY29tcGxldGUgdGhlIHdoaWxlIGxvb3AuCiAgICAgICAgICAgICAgICAgICAgICAgICAqIFRoZSB3aGlsZSBsb29wIGlzIGNvbXBsZXRlZCBpbiBvcmRlciB0byBtYWtlIHRoZSBjdXJyZW50IGVudHJ5IGdvIGJhY2sgdG8gTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICogYW5kIGluIHRoZSBuZXh0IHdoaWxlIGxvb3AsIGl0IHByb3Blcmx5IHN0YXJ0cyBzZWFyY2hpbmcgZnJvbSB0aGUgaGVhZCBvZiB0aGUgbGlzdC4KICAgICAgICAgICAgICAgICAgICAgICAgICogVE9ETzogQ2FuIGFsc28gdHJ5IHNldHRpbmcgdGhlIGN1cnJlbnQgZW50cnkgZGlyZWN0bHkgdG8gTlVMTCBhcyBzb29uIGFzIHdlIGZpbmQgdGhlIG5ldyBBUCovCgogICAgICAgICAgICAgICAgICAgICAgICAgQ3VyckFQUnNzaSA9IChpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSAqICgtMSkgOwoKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIEN1cnJBUFJzc2k7Cgp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5SZXN1bHRzCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGV4dHJhY3RzIHNjYW4gcmVzdWx0cywgc29ydHMgb24gdGhlIGJhc2lzIG9mIG5laWdoYm9yIHNjb3JlKHRvZG8pLiAKICAgICAgICAgICAgQXNzdW1lZCB0aGF0IHRoZSByZXN1bHRzIGFyZSBhbHJlYWR5IHNvcnRlZCBieSBSU1NJIGJ5IGNzclNjYW5HZXRSZXN1bHQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBTY2FuUmVzdWx0TGlzdCAtIFNjYW4gcmVzdWx0IHJlc3VsdCBvYnRhaW5lZCBmcm9tIGNzclNjYW5HZXRSZXN1bHQoKQoKICAgIFxyZXR1cm4gdEFOSV9CT09MRUFOIC0gcmV0dXJuIFRSVUUgaWYgd2UgaGF2ZSBhIGNhbmRpZGF0ZSB3ZSBjYW4gaW1tZWRpYXRlbHkKICAgICAgICAgICAgcm9hbSB0by4gT3RoZXJ3aXNlLCByZXR1cm4gRkFMU0UuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKc3RhdGljIHRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhblJlc3VsdHModHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRTY2FuUmVzdWx0SGFuZGxlICpwU2NhblJlc3VsdExpc3QpCnsKICAgIHRDc3JTY2FuUmVzdWx0SW5mbyAqcFNjYW5SZXN1bHQ7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICBwQnNzSW5mbzsKICAgIHRBTklfVTMyIEN1cnJBUFJzc2k7CiAgICB0QU5JX1U4IFJvYW1Sc3NpRGlmZiA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uUm9hbVJzc2lEaWZmOwojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICB0QU5JX1U4IGltbWVkaWF0ZVJvYW1Sc3NpRGlmZiA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubkltbWVkaWF0ZVJvYW1Sc3NpRGlmZjsKI2VuZGlmCiAgICB0QU5JX0JPT0xFQU4gcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgKiBGaW5kIG91dCB0aGUgQ3VycmVudCBBUCBSU1NJIGFuZCBrZWVwIGl0IGhhbmR5IHRvIGNoZWNrIGlmCiAgICAgKiBpdCBpcyBiZXR0ZXIgdGhhbiB0aGUgUlNTSSBvZiB0aGUgQVAgd2hpY2ggd2UgYXJlCiAgICAgKiBnb2luZyB0byByb2FtLklmIHNvLCB3ZSBhcmUgZ29pbmcgdG8gY29udGludWUgd2l0aCB0aGUKICAgICAqIGN1cnJlbnQgQVAuCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgQ3VyckFQUnNzaSA9IGNzckdldEN1cnJlbnRBUFJzc2kocE1hYywgcFNjYW5SZXN1bHRMaXN0KTsKCiAgICAvKiBFeHBlY3RpbmcgdGhlIHNjYW4gcmVzdWx0IGFscmVhZHkgdG8gYmUgaW4gdGhlIHNvcnRlZCBvcmRlciBiYXNlZCBvbiB0aGUgUlNTSSAqLwogICAgLyogQmFzZWQgb24gdGhlIHByZXZpb3VzIHN0YXRlIHdlIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGUgbGlzdCBzaG91bGQgYmUgc29ydGVkIGFnYWluIHRha2luZyBuZWlnaGJvciBzY29yZSBpbnRvIGNvbnNpZGVyYXRpb24gKi8KICAgIC8qIElmIHByZXZpb3VzIHN0YXRlIGlzIENGR19DSEFOX0xJU1RfU0NBTiwgdGhlcmUgc2hvdWxkIG5vdCBiZSBhbnkgbmVpZ2hib3Igc2NvcmUgYXNzb2NpYXRlZCB3aXRoIGFueSBvZiB0aGUgQlNTLgogICAgICAgSWYgdGhlIHByZXZpb3VzIHN0YXRlIGlzIFJFUE9SVF9RVUVSWSwgdGhlbiB0aGVyZSB3aWxsIGJlIG5laWdoYm9yIHNjb3JlIGZvciBlYWNoIG9mIHRoZSBBUHMgKi8KICAgIC8qIEZvciBub3csIGxldCB1cyB0YWtlIHRoZSB0b3Agb2YgdGhlIGxpc3QgcHJvdmlkZWQgYXMgaXQgaXMgYnkgdGhlIENTUiBTY2FuIHJlc3VsdCBBUEkuIFRoaXMgbWVhbnMgaXQgaXMgYXNzdW1lZCB0aGF0IG5laWdoYm9yIHNjb3JlIAogICAgICAgYW5kIHJzc2kgc2NvcmUgYXJlIGluIHRoZSBzYW1lIG9yZGVyLiBUaGlzIHdpbGwgYmUgdGFrZW4gY2FyZSBsYXRlciAqLwoKICAgIHdoaWxlIChOVUxMICE9IChwU2NhblJlc3VsdCA9IGNzclNjYW5SZXN1bHRHZXROZXh0KHBNYWMsICpwU2NhblJlc3VsdExpc3QpKSkKICAgIHsKICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLAogICAgICAgICAgICBGTCgiU2NhbiByZXN1bHQ6IEJTU0lEICJNQUNfQUREUkVTU19TVFIiIChSc3NpICVsZCwgQ2g6JWQpIiksCiAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSwKICAgICAgICAgICAgYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpLAogICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5jaGFubmVsSWQpOwoKICAgICAgIGlmICgoVk9TX1RSVUUgPT0gdm9zX21lbV9jb21wYXJlKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkLAogICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpIHx8CiAgICAgICAgICAgKChlU01FX1JPQU1fVFJJR0dFUl9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pICYmCiAgICAgICAgICAgKFZPU19UUlVFICE9IHZvc19tZW1fY29tcGFyZShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1ic3NJZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGN1cnJlbnRseSBhc3NvY2lhdGVkIEFQLiBEbyBub3QgaGF2ZSB0aGlzIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICJTS0lQLWN1cnJlbnRseSBhc3NvY2lhdGVkIEFQIik7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICBpZiAodm9zX2NvbmN1cnJlbnRfb3Blbl9zZXNzaW9uc19ydW5uaW5nKCkgJiYKICAgICAgICAgICFwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmZlbmFibGVNQ0NNb2RlICYmCiAgICAgICAgICAgIChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5jaGFubmVsSWQgIT0KICAgICAgICAgICAgY3NyR2V0Q29uY3VycmVudE9wZXJhdGlvbkNoYW5uZWwocE1hYykpKSB7CiAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk1DQyBub3Qgc3VwcG9ydGVkIHNvIElnbm9yZSBBUCBvbiBjaGFubmVsICVkIiksCiAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuY2hhbm5lbElkKTsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgLyogSW4gY2FzZSBvZiByZWFzc29jIHJlcXVlc3RlZCBieSB1cHBlciBsYXllciwgbG9vayBmb3IgZXhhY3QgbWF0Y2ggb2YgYnNzaWQgJiBjaGFubmVsOwogICAgICAgICAgY3NyIGNhY2hlIG1pZ2h0IGhhdmUgZHVwbGljYXRlcyovCiAgICAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmKSAmJgogICAgICAgICAgICgoVk9TX0ZBTFNFID09IHZvc19tZW1fY29tcGFyZShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uYnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpfHwKICAgICAgICAgICAgKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmNoYW5uZWxJZCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uY2hhbm5lbCkpKQoKICAgICAgIHsKICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICJTS0lQLW5vdCBhIGNhbmRpZGF0ZSBBUCBmb3IgT1MgcmVxdWVzdGVkIHJvYW0iKTsKICAgICAgICAgICBjb250aW51ZTsKICAgICAgIH0KI2VuZGlmCiNlbmRpZgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0gpCiAgICAgICB7CiAgICAgICAgICAgIC8vQmVsb3cgY2hlY2sgaXMgcmVxdWlyZWQgYmVjYXVzZSBzY2FubmluZyBmb3IgZm9yY2VkIGluaXRpYWwgcm9hbWluZyB3ZSBoYXZlIG5vdAogICAgICAgICAgICAvL2ZsdXNoIGFsbCB0aGUgMi40IEdIeiBDaGFubmVsLCBzbyBpdCBtYXkgcG9zc2JpbGUgd2UgbWF5IHJvYW0gYWdhaW4gdG8KICAgICAgICAgICAgLy8yLjQgR2h6IGFwIG9ubHkuCiAgICAgICAgICAgIGlmKEdldFJGQmFuZChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5jaGFubmVsSWQpICE9IFNJUl9CQU5EXzVfR0haKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBGb3JjZWQgUm9hbSB0byA1RyBTa2lwIE5vbiA1RyBTY2FuIHJlc3VsdHMgIiwgX19mdW5jX18pOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vcnNzaSdzIGFyZSAtdmUgdmFsdWUsIHNvIGlmIGFicyBvZiByc3NpIGlzIGdyZWF0ZXIKICAgICAgICAgICAgLy9tZWFucyBuZXcgYXAgaXMgcG9vciB0aGVuIGN1cnJlbnRseSBjb25uZWN0ZWQgYXAuCiAgICAgICAgICAgIC8vQ2hlY2sgaXQgaXMgb25seSBwb29yIHdpdGhpbiBuU2VsZWN0NUdIek1hcmdpbiB2YWx1ZS4KICAgICAgICAgICAgaWYgKGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSA+IGFicyhDdXJyQVBSc3NpKSAmJgogICAgICAgICAgICAgICAoKGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSAtIGFicyhDdXJyQVBSc3NpKSkKICAgICAgICAgICAgICAgID4gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uU2VsZWN0NUdIek1hcmdpbikKICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICIlczogRm9yY2VkIFJvYW0gdG8gNUcgQ3VycmVudCBBUCByc3NpPSVkIG5ldyBhcCByc3NpPSVkIG5vdCBnb29kIGVub3VnaCwgblNlbGVjdDVHSHpNYXJnaW49JWQiLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgIEN1cnJBUFJzc2ksCiAgICAgICAgICAgICAgICAgICAgICAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uU2VsZWN0NUdIek1hcmdpbik7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgIH0KI2VuZGlmCiNlbmRpZgoKICAgICAgIC8qIFRoaXMgY29uZGl0aW9uIGlzIHRvIGVuc3VyZSB0byByb2FtIHRvIGFuIEFQIHdpdGggYmV0dGVyIFJTU0kuIGlmIHRoZSB2YWx1ZSBvZiBSb2FtUnNzaURpZmYgaXMgWmVybywgdGhpcyBmZWF0dXJlCiAgICAgICAgKiBpcyBkaXNhYmxlZCBhbmQgd2UgY29udGludWUgdG8gcm9hbSB3aXRob3V0IGFueSBjaGVjayovCiAgICAgICBpZiAoKFJvYW1Sc3NpRGlmZiA+IDApCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgICAgJiYgKChlU01FX1JPQU1fVFJJR0dFUl9TQ0FOICE9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pICYmCiAgICAgICAgICAgKGVTTUVfUk9BTV9UUklHR0VSX0ZBU1RfUk9BTSAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSkpCiAgICAgICB7CiAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICogSWYgUlNTSSBpcyBsb3dlciB0aGFuIHRoZSBsb29rdXAgdGhyZXNob2xkLCB0aGVuIGNvbnRpbnVlLgogICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICBpZiAoYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpID4KICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpCiAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXSBuZXcgYXAgcnNzaSAoJWQpIGxvd2VyIHRoYW4gbG9va3VwIHRocmVzaG9sZCAoJWQpIiwKICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAoaW50KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgaWYgKGFicyhDdXJyQVBSc3NpKSA8IGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSkKICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgIC8qRG8gbm90IHJvYW0gdG8gYW4gQVAgd2l0aCB3b3JzZSBSU1NJIHRoYW4gdGhlIGN1cnJlbnQqLwogICAgICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXUN1cnJlbnQgQVAgcnNzaT0lZCBuZXcgYXAgcnNzaSB3b3JzZT0lZCIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDdXJyQVBSc3NpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpICk7CiAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgLypEbyBub3Qgcm9hbSB0byBhbiBBUCB3aGljaCBpcyBoYXZpbmcgYmV0dGVyIFJTU0kgdGhhbiB0aGUgY3VycmVudCBBUCwgYnV0IHN0aWxsIGxlc3MgdGhhbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgKiBtYXJnaW4gdGhhdCBpcyBwcm92aWRlZCBieSB1c2VyIGZyb20gdGhlIGluaSBmaWxlIChSb2FtUnNzaURpZmYpKi8KICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWJzKGFicyhDdXJyQVBSc3NpKSAtIGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSkgPCBSb2FtUnNzaURpZmYpCiAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR11DdXJyZW50IEFQIHJzc2k9JWQgbmV3IGFwIHJzc2k9JWQgbm90IGdvb2QgZW5vdWdoLCByb2FtUnNzaURpZmY9JWQiLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3VyckFQUnNzaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUm9hbVJzc2lEaWZmKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddQ3VycmVudCBBUCByc3NpPSVkIG5ldyBhcCByc3NpIGJldHRlcj0lZCIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1cnJBUFJzc2ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSApOwogICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgfQogICAgICAgfQoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUocE1hYywgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkJTU0lEIHByZXNlbnQgaW4gcHJlLWF1dGggZmFpbCBsaXN0Li4gSWdub3JpbmciKSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgaWYgKCFjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUocE1hYywgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJCU1NJRCBwcmVzZW50IGluIHByZS1hdXRoIGZhaWwgbGlzdC4uIElnbm9yaW5nIikpOwogICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX3ByZXNlbnQpICYmCiAgICAgICAgICAgICAgIChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9hdmFpbCkpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc1ZPQWRtaXR0ZWQpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk5ldyBBUCBoYXMgJXggQlcgYXZhaWxhYmxlIiksICh1bnNpZ25lZCBpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfYXZhaWwpOwogICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIldlIG5lZWQgJXggQlcgYXZhaWxhYmxlIiksKHVuc2lnbmVkIGludClwTmVpZ2hib3JSb2FtSW5mby0+TWluUUJzc0xvYWRSZXF1aXJlZCk7CiAgICAgICAgICAgICAgICAgIGlmIChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9hdmFpbCA8IHBOZWlnaGJvclJvYW1JbmZvLT5NaW5RQnNzTG9hZFJlcXVpcmVkKQogICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAiW0lORk9MT0ddQlNTSUQgOiAiTUFDX0FERFJFU1NfU1RSIiBoYXMgbm8gYmFuZHdpZHRoIGlnbm9yaW5nLi5ub3QgYWRkaW5nIHRvIHJvYW0gbGlzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKTsKICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgZWxzZQogICAgICAgICAgewogICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTm8gUUJzcyAleCAleCIpLCAodW5zaWduZWQgaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX2F2YWlsLCAodW5zaWduZWQgaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX3ByZXNlbnQpOwogICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNWT0FkbWl0dGVkKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAiW0lORk9MT0ddQlNTSUQgOiAiTUFDX0FERFJFU1NfU1RSIiBoYXMgbm8gUUJTU0xvYWQgSUUsIGlnbm9yaW5nLi5ub3QgYWRkaW5nIHRvIHJvYW0gbGlzdCIsCiAgICAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCkpOwogICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICB9CiNlbmRpZgojZW5kaWYgLyogRkVBVFVSRV9XTEFOX0VTRSAqLwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAvLyBJZiB3ZSBhcmUgc3VwcG9ydGluZyBsZWdhY3kgcm9hbWluZywgYW5kIAogICAgICAgIC8vIGlmIHRoZSBjYW5kaWRhdGUgaXMgb24gdGhlICJwcmUtYXV0aCBmYWlsZWQiIGxpc3QsIGlnbm9yZSBpdC4gCiAgICAgICAgaWYgKGNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLCBDU1JfU0VTU0lPTl9JRF9JTlZBTElEKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghY3NyTmVpZ2hib3JSb2FtSXNQcmVhdXRoQ2FuZGlkYXRlKHBNYWMsIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJCU1NJRCBwcmVzZW50IGluIHByZS1hdXRoIGZhaWwgbGlzdC4uIElnbm9yaW5nIikpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZiAvKiBGRUFUVVJFX1dMQU5fTEZSICovCgogICAgICAgIC8qIElmIHRoZSByZWNlaXZlZCB0aW1lc3RhbXAgaW4gQlNTIGRlc2NyaXB0aW9uIGlzIGVhcmxpZXIgdGhhbiB0aGUgc2NhbiByZXF1ZXN0IHRpbWVzdGFtcCwgc2tpcCAKICAgICAgICAgKiB0aGlzIHJlc3VsdCAqLwogICAgICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPnNjYW5SZXF1ZXN0VGltZVN0YW1wID49IHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLm5SZWNlaXZlZFRpbWUpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJZ25vcmluZyBCU1MgYXMgaXQgaXMgb2xkZXIgdGhhbiB0aGUgc2NhbiByZXF1ZXN0IHRpbWVzdGFtcCIpKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBwQnNzSW5mbyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyTmVpZ2hib3JSb2FtQlNTSW5mbykpOwogICAgICAgIGlmIChOVUxMID09IHBCc3NJbmZvKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgTmVpZ2hib3IgUm9hbSBCU1MgSW5mbyBmYWlsZWQuLiBKdXN0IGlnbm9yaW5nIikpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHBCc3NJbmZvLT5wQnNzRGVzY3JpcHRpb24gPSB2b3NfbWVtX21hbGxvYyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5sZW5ndGggKyBzaXplb2YocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IubGVuZ3RoKSk7CiAgICAgICAgaWYgKHBCc3NJbmZvLT5wQnNzRGVzY3JpcHRpb24gIT0gTlVMTCkKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fY29weShwQnNzSW5mby0+cEJzc0Rlc2NyaXB0aW9uLCAmcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IsIAogICAgICAgICAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmxlbmd0aCArIHNpemVvZihwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5sZW5ndGgpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgTmVpZ2hib3IgUm9hbSBCU1MgRGVzY3JpcHRvciBmYWlsZWQuLiBKdXN0IGlnbm9yaW5nIikpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocEJzc0luZm8pOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgCiAgICAgICAgfQogICAgICAgIHBCc3NJbmZvLT5hcFByZWZlcmVuY2VWYWwgPSAxMDsgLy9zb21lIHZhbHVlIGZvciBub3cuIE5lZWQgdG8gY2FsY3VsYXRlIHRoZSBhY3R1YWwgc2NvcmUgYmFzZWQgb24gUlNTSSBhbmQgbmVpZ2hib3IgQVAgc2NvcmUKCiAgICAgICAgLyogSnVzdCBhZGQgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBhcyBpdCBpcyBhbHJlYWR5IHNvcnRlZCBieSBSU1NJICovCiAgICAgICAgY3NyTExJbnNlcnRUYWlsKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsICZwQnNzSW5mby0+TGlzdCwgTExfQUNDRVNTX0xPQ0spOwoKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgIGlmICgoZVNNRV9ST0FNX1RSSUdHRVJfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSB8fAogICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pKQogICAgICAgIHsKICAgICAgICAgICByb2FtTm93ID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICgoYWJzKGFicyhDdXJyQVBSc3NpKSAtIGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSkgPj0gaW1tZWRpYXRlUm9hbVJzc2lEaWZmKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddIHBvdGVudGlhbCBjYW5kaWRhdGUgdG8gcm9hbSBpbW1lZGlhdGVseSAoZGlmZj0lbGQsIGV4cGVjdGVkPSVkKSIsCiAgICAgICAgICAgICAgICAgICAgICAgX19mdW5jX18sIGFicyhhYnMoQ3VyckFQUnNzaSkgLSBhYnMocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSkpLAogICAgICAgICAgICAgICAgICAgICAgIGltbWVkaWF0ZVJvYW1Sc3NpRGlmZik7CiAgICAgICAgICAgIHJvYW1Ob3cgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAvKiBJZiB3ZSBhcmUgaGVyZSBtZWFucywgRlcgYWxyZWFkeSBmb3VuZCBjYW5kaWRhdGVzIHRvIHJvYW0sIHNvIHdlIGFyZQogICAgICAgICAgIGdvb2QgdG8gZ28gd2l0aCBwcmUtYXV0aCAqLwogICAgICAgIGlmKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewogICAgICAgICAgICByb2FtTm93ID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgfQojZW5kaWYKI2VuZGlmCiAgICB9CgogICAgLyogTm93IHdlIGhhdmUgYWxsIHRoZSBzY2FuIHJlc3VsdHMgaW4gb3VyIGxvY2FsIGxpc3QuIEdvb2QgdGltZSB0byBmcmVlIHVwIHRoZSB0aGUgbGlzdCB3ZSBnb3QgYXMgYSBwYXJ0IG9mIGNzckdldFNjYW5SZXN1bHQgKi8KICAgIGNzclNjYW5SZXN1bHRQdXJnZShwTWFjLCAqcFNjYW5SZXN1bHRMaXN0KTsKCiAgICByZXR1cm4gcm9hbU5vdzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdAoKICAgIFxicmllZiAgICAgIFRoaXMgZnVuY3Rpb24gd2lsbCBiZSBpbnZva2VkIGluIENGR19DSEFOX0xJU1RfU0NBTiBzdGF0ZSB3aGVuIAogICAgICAgICAgICAgICAgdGhlcmUgYXJlIG5vIHZhbGlkIEFQcyBpbiB0aGUgc2NhbiByZXN1bHQgZm9yIHJvYW1pbmcuIFRoaXMgbWVhbnMgCiAgICAgICAgICAgICAgICBvdXIgQVAgaXMgdGhlIGJlc3QgYW5kIG5vIG90aGVyIEFQIGlzIGFyb3VuZC4gTm8gcG9pbnQgaW4gc2Nhbm5pbmcKICAgICAgICAgICAgICAgIGFnYWluIGFuZCBhZ2Fpbi4gUGVyZm9ybWluZyB0aGUgZm9sbG93aW5nIGhlcmUuCiAgICAgICAgICAgICAgICAxLiBTdG9wIHRoZSBuZWlnaGJvciBzY2FuIHRpbWVyLgogICAgICAgICAgICAgICAgMmEuIElmIHRoaXMgaXMgdGhlIGZpcnN0IHRpbWUgd2UgZW5jb3VudGVyZWQgZW1wdHkgc2NhbiwgdGhlbgogICAgICAgICAgICAgICAgcmUtcmVnaXN0ZXIgd2l0aCBUTCB3aXRoIG1vZGlmaWVkIGxvb2t1cCB0aHJlc2hvbGQuCiAgICAgICAgICAgICAgICAyYi4gRWxzZSBpZiB0aGlzIGlzIHRoZSBzZWNvbmQgdGltZSB3ZSBlbmNvdW50ZXJlZCBlbXB0eSBzY2FuLAogICAgICAgICAgICAgICAgdGhlbiBzdGFydCBuZWlnaGJvciBzY2FuIHJlc3VsdHMgcmVmcmVzaCB0aW1lciAoMjBzKS4KICAgICAgICAgICAgICAgIDJjLiBFbHNlLCBub3RoaW5nIG1vcmUgdG8gZG8uCiAgICAgICAgICAgICAgICBOT1RFOiBJbiBMRlIsIGNoYW5uZWxzIHNlbGVjdGVkIGZvciBzY2FubmluZyBpcyBkZXJ2aWVkIGZyb20KICAgICAgICAgICAgICAgIHRoZSBvY2N1cGVkIGNoYW5uZWwgbGlzdC4gU2NhbiBjeWNsZSBmb2xsb3dpbmcgb25lIHdoaWNoCiAgICAgICAgICAgICAgICB5aWVsZGVkIGVtcHR5IHJlc3VsdHMgaXMgc3BsaXQgaW50byB0d28gaGFsdmVzOiAoaSkgc2NhbiBvbgogICAgICAgICAgICAgICAgY2hhbm5lbHMgaW4gdGhlIG9jY3VwaWVkIGxpc3QsIGFuZCAoaWkpIHNjYW4gb24gY2hhbm5lbHMgbm90CiAgICAgICAgICAgICAgICBpbiB0aGUgb2NjdXBpZWQgbGlzdC4gVGhpcyBoZWxwcyBjb252ZXJnaW5nIGZhc3RlciAod2hpbGUKICAgICAgICAgICAgICAgIGxvb2tpbmcgZm9yIGNhbmRpZGF0ZXMgaW4gdGhlIG9jY3VwaWVkIGxpc3QgZmlyc3QpLCBhbmQgYWxzbywKICAgICAgICAgICAgICAgIGFkZHMgY2hhbm5lbHMgdG8gdGhlIG9jY3VwaWVkIGNoYW5uZWwgbGlzdCB1cG9uIGZpbmRpbmcgY2FuZGlkYXRlcwogICAgICAgICAgICAgICAgbWF0Y2hpbmcgU1NJRCBwcm9maWxlIG9mIGludGVyZXN0LgoKICAgICAgICAgICAgICAgIHVFbXB0eVNjYW5Db3VudCAgICAgICAgICAgICAgICAgICAgICAgICBDb21tZW50cwogICAgICAgICAgICAgICAgZUZpcnN0RW1wdHlTY2FuICAgICBQcmV2aW91cyBzY2FuIHdhcyBkb25lIG9uIGNoYW5uZWxzIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY2N1cGllZCBsaXN0IGFuZCB5aWVsZGVkIHBvdGVudGlhbCBjYW5kaWRhdGVzLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIHNjYW4gY3ljbGUgd2FzIGxpa2VseSB0cmlnZ2VyZWQgdGhyb3VnaAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXB0IG9mIGxvb2t1cCBET1dOIG5vdGlmaWNhdGlvbiBldmVudC4KICAgICAgICAgICAgICAgIGVTZWNvbmRFbXB0eVNjYW4gICAgUHJldmlvdXMgc2NhbiB3YXMgZG9uZSBvbiBjaGFubmVscyBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NjdXBpZWQgbGlzdCBhbmQgeWllbGRlZCBubyBjYW5kaWRhdGVzLiBUaGlzIHNjYW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3ljbGUgd2FzIHRyaWdnZXJlZCB0aHJvdWdoIFJTU0kgbm90aWZpY2F0aW9uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGggbW9kaWZpZWQgbG9va3VwIHRocmVzaG9sZC4KICAgICAgICAgICAgICAgIGVUaGlyZEVtcHR5U2NhbiAgICAgUHJldmlvdXMgc2NhbiB3YXMgZG9uZSBvbiBjaGFubmVscyBOT1QgaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIG9jY3VwaWVkIGxpc3QgYW5kIHlpZWxkZWQgbm8gY2FuZGlkYXRlcy4gVGhpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuIGN5Y2xlIHdhcyB0cmlnZ2VyZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgc2Nhbm5pbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbHMgaW4gdGhlIG9jY3VwaWVkIGxpc3QgYW5kIG5vIGNhbmRpZGF0ZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2VyZSBmb3VuZC4KICAgICAgICAgICAgICAgIGVGb3VydGhFbXB0eVNjYW4gICAgUHJldmlvdXMgc2NhbiB3YXMgZG9uZSBvbiBjaGFubmVscyBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NjdXBpZWQgbGlzdCBhbmQgeWllbGRlZCBubyBjYW5kaWRhdGVzLiBUaGlzIHNjYW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3ljbGUgd2FzIHRyaWdnZXJlZCB1cG9uIGV4cGlyeSBvZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZWlnaGJvclNjYW5SZXN1bHRzUmVmcmVzaFBlcmlvZCAoPTIwcykuCiAgICAgICAgICAgICAgICBlRmlmdGhFbXB0eVNjYW4gICAgIFByZXZpb3VzIHNjYW4gd2FzIGRvbmUgb24gY2hhbm5lbHMgTk9UIGluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBvY2N1cGllZCBsaXN0IGFuZCB5aWVsZGVkIG5vIGNhbmRpZGF0ZXMuIFRoaXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbiBjeWNsZSB3YXMgdHJpZ2dlcmVkIGltbWVkaWF0ZWx5IGFmdGVyIHNjYW5uaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBsaXN0IGFuZCBubyBjYW5kaWRhdGVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlcmUgZm91bmQuCgogICAgICAgICAgICAgICAgWzFdLCBbMiwzXSBhbmQgWzQsNV0gdG9nZXRoZXIgZm9ybSBvbmUgZGlzY3JldGUgc2V0IG9mIHNjYW4gY3ljbGUuCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICB0QU5JX0JPT0xFQU4gcGVyZm9ybVBlcmlvZGljU2NhbiA9CiAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuZW1wdHlTY2FuUmVmcmVzaFBlcmlvZCkgPyBUUlVFIDogRkFMU0U7CiNlbmRpZgoKICAgIC8qIFN0b3AgbmVpZ2hib3Igc2NhbiB0aW1lciAqLwogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAvKgogICAgICogSW5jcmVhc2UgdGhlIG5laWdoYm9yIGxvb2t1cCB0aHJlc2hvbGQgYnkgMyBkQgogICAgICogYWZ0ZXIgZXZlcnkgc2NhbiBjeWNsZS4gTk9URTogdUVtcHR5U2NhbkNvdW50CiAgICAgKiB3b3VsZCBiZSBlaXRoZXIgMSwgMyBvciA1IGF0IHRoZSBlbmQgb2YgZXZlcnkKICAgICAqIHNjYW4gY3ljbGUuCiAgICAgKi8KI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIGlmICgoKytwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50KSA+IGVGaWZ0aEVtcHR5U2NhbikKICAgIHsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gZUZpZnRoRW1wdHlTY2FuOwogICAgfQogICAgaWYgKCgoMCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpIHx8CiAgICAgICAgIChhYnMocE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpKSA+CiAgICAgICAgIGFicyhwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCkpKSAmJgogICAgICAgICgocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlU2Vjb25kRW1wdHlTY2FuKSB8fAogICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlRm91cnRoRW1wdHlTY2FuKSkpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiBJZiB0aGUgc2NhbiB3YXMgdHJpZ2dlcmVkIGR1ZSB0byBsb29rdXBET1dOUnNzaSA+IHJlYXNzb2MgdGhyZXNob2xkLAogICAgICAgICAqIHRoZW4gaXQgd291bGQgYmUgYSBjb250aWd1b3VzIHNjYW4gb24gYWxsIHZhbGlkIG5vbi1ERlMgY2hhbm5lbHMuCiAgICAgICAgICogSWYgY2hhbm5lbHMgYXJlIGNvbmZpZ3VyZWQgaW4gSU5JLCB0aGVuIG9ubHkgdGhvc2UgY2hhbm5lbHMgbmVlZAogICAgICAgICAqIHRvIGJlIHNjYW5uZWQuCiAgICAgICAgICogSW4gZWl0aGVyIG9mIHRoZXNlIG1vZGVzLCB0aGVyZSBpcyBubyBuZWVkIHRvIHRyaWdnZXIgYW4gaW1tZWRpYXRlCiAgICAgICAgICogc2NhbiB1cG9uIGVtcHR5IHNjYW4gcmVzdWx0cyBmb3IgdGhlIHNlY29uZCBhbmQgZm91cnRoIHRpbWUgKHdoaWNoCiAgICAgICAgICogd291bGQgYmUgZXF1aXZhbGVudCB0byBzY2FubmluZyBvbiBjaGFubmVscyBpbiBub24tb2NjdXBpZWQgbGlzdCkuCiAgICAgICAgICogSW5jcmVtZW50aW5nIHVFbXB0eVNjYW5Db3VudCB3aWxsIGNvcnJlc3BvbmQgdG8gc2tpcHBpbmcgdGhpcyBzdGVwLgogICAgICAgICAqIE5PVEU6IGRvdWJsZSBpbmNyZW1lbnQgb2YgdUVtcHR5U2NhbkNvdW50IGNvcnJlc3BvbmRzIHRvIGNvbXBsZXRpb24KICAgICAgICAgKiBvZiBzY2FucyBvbiBhbGwgdmFsaWQgY2hhbm5lbHMuCiAgICAgICAgICovCiAgICAgICAgKytwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50OwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIkV4dHJhIGluY3JlbWVudCBvZiBlbXB0eSBzY2FuIGNvdW50ICg9JWQpIgogICAgICAgICAgICAiIGluIGNvbnRpZ3VvdXMgc2NhbiBtb2RlIiwgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCk7CiAgICB9CiNlbmRpZgogICAgaWYgKCgocE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCszKSA8CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQpCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgJiYgKChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ICUgMikgPT0gMSkKI2VuZGlmCiAgICAgICAgKQogICAgewogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKz0gMzsKICAgIH0KCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgLyogQ2xlYXIgb2ZmIHRoZSBvbGQgbmVpZ2hib3IgcmVwb3J0IGRldGFpbHMgKi8KICAgIHZvc19tZW1femVybygmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm8sIHNpemVvZih0Q3NyTmVpZ2hib3JSZXBvcnRCc3NJbmZvKSAqIE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKTsKI2VuZGlmCgogICAgLyogVHJhbnNpdGlvbiB0byBDT05ORUNURUQgc3RhdGUgKi8KICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICAgICAgCiAgICAvKiBSZXNldCBhbGwgdGhlIG5lY2Vzc2FyeSB2YXJpYWJsZXMgYmVmb3JlIHRyYW5zaXRpb25pbmcgdG8gdGhlIENPTk5FQ1RFRCBzdGF0ZSAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwogICAgICAgIAojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPT0gZUZpcnN0RW1wdHlTY2FuKQogICAgewojZW5kaWYKICAgICAgICAvKiBFbXB0eSBzY2FuIHJlc3VsdHMgZm9yIHRoZSBmaXJzdCB0aW1lICovCiAgICAgICAgLyogUmUtcmVnaXN0ZXIgbmVpZ2hib3IgbG9va3VwIERPV04gdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgKi8KICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsCiAgICAgICAgICAgIEZMKCJSZWdpc3RlcmluZyBET1dOIGV2ZW50IG5laWdoYm9yIGxvb2t1cCBjYWxsYmFjayB3aXRoIFRMIGZvciBSU1NJID0gJWQiKSwKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSkpOwoKICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgRkwoIkNvdWxkbid0IHJlLXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIgogICAgICAgICAgICAgICAgICAgICAgIiB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgICAgIH0KI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgfQogICAgZWxzZSBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPT0gZVNlY29uZEVtcHR5U2NhbikgfHwKICAgICAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IGVGb3VydGhFbXB0eVNjYW4pKQogICAgewogICAgICAgIC8qIEVtcHR5IHNjYW4gcmVzdWx0cyBmb3IgdGhlIHNlY29uZCBvciBmb3VydGggdGltZSAqLwoKICAgICAgICAvKiBJbW1lZGlhdGVseSBzY2FuIG9uIGNoYW5uZWxzIGluIG5vbi1vY2N1cGllZCBsaXN0ICovCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4ocE1hYyk7CiAgICB9CiAgICBlbHNlIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID49IGVUaGlyZEVtcHR5U2NhbikKICAgIHsKICAgICAgICAvKiBFbXB0eSBzY2FuIHJlc3VsdHMgZm9yIHRoZSB0aGlyZCB0aW1lICovCiAgICAgICAgaWYgKHBlcmZvcm1QZXJpb2RpY1NjYW4pCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlBlcmZvcm1pbmcgcGVyaW9kaWMgc2NhbiwgdUVtcHR5U2NhbkNvdW50PSVkIiksCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50KTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNldCB1RW1wdHlTY2FuQ291bnQgdG8gTUFYIHNvIHRoYXQgd2UgYWx3YXlzIGVudGVyIHRoaXMKICAgICAgICAgICAgICogY29uZGl0aW9uIG9uIHN1YnNlcXVlbnQgZW1wdHkgc2NhbiByZXN1bHRzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gZU1heEVtcHR5U2NhbjsKCiAgICAgICAgICAgIC8qIEZyb20gaGVyZSBvbiwgT05MWSBzY2FuIG9uIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBsaXN0ICovCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPSBTUExJVF9TQ0FOX09DQ1VQSUVEX0xJU1Q7CgogICAgICAgICAgICAvKiBTdGFydCBlbXB0eSBzY2FuIHJlZnJlc2ggdGltZXIgKi8KICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPQogICAgICAgICAgICAgICAgdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuZW1wdHlTY2FuUmVmcmVzaFBlcmlvZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRW1wdHkgc2NhbiByZWZyZXNoIHRpbWVyIGZhaWxlZCB0byBzdGFydCAoJWQpIiksCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRW1wdHkgc2NhbiByZWZyZXNoIHRpbWVyIHN0YXJ0ZWQgKCVkIG1zKSIpLAogICAgICAgICAgICAgICAgICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5lbXB0eVNjYW5SZWZyZXNoUGVyaW9kKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoZVRoaXJkRW1wdHlTY2FuID09IHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQpCiAgICAgICAgewogICAgICAgICAgICAvKiBTdGFydCBuZWlnaGJvciBzY2FuIHJlc3VsdHMgcmVmcmVzaCB0aW1lciAqLwogICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9CiAgICAgICAgICAgICAgICAgICAgdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2QpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBmYWlsZWQgdG8gc3RhcnQgKCVkKSIpLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMiwgRkwoIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBzdGFydGVkICglZCBtcykiKSwKICAgICAgICAgICAgICAgICAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCAqIFBBTF9USU1FUl9UT19NU19VTklUKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCAiTmVpZ2hib3Igcm9hbSBlbXB0eSBzY2FuIGNvdW50PSVkIHNjYW4gbW9kZT0lZCIsCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCwgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSk7CiNlbmRpZgogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUgKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdENzclNjYW5SZXN1bHRGaWx0ZXIgICAgc2NhbkZpbHRlcjsKICAgIHRTY2FuUmVzdWx0SGFuZGxlICAgICAgIHNjYW5SZXN1bHQ7CiAgICB0QU5JX1UzMiAgICAgICAgICAgICAgICB0ZW1wVmFsID0gMDsKICAgIHRBTklfQk9PTEVBTiAgICAgICAgICAgIHJvYW1Ob3cgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBlSGFsU3RhdHVzICAgICAgICAgICAgICBoc3RhdHVzOwoKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgIC8qIElmIHRoZSBzdGF0ZSBpcyBSRVBPUlRfU0NBTiwgdGhlbiB0aGlzIG11c3QgYmUgdGhlIHNjYW4gYWZ0ZXIgdGhlIFJFUE9SVF9RVUVSWSBzdGF0ZS4gU28sIHdlIAogICAgICAgICAgIHNob3VsZCB1c2UgdGhlIEJTU0lEIGZpbHRlciBtYWRlIG91dCBvZiBuZWlnaGJvciByZXBvcnRzICovCiAgICAgICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgJiYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQojZW5kaWYKICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtQnNzSWRTY2FuRmlsdGVyKHBNYWMsICZzY2FuRmlsdGVyKTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiMTFSIG9yIEVTRSBBc3NvY2lhdGlvbjogUHJlcGFyZSBzY2FuIGZpbHRlciBzdGF0dXMgIHdpdGggbmVpZ2hib3IgQVAgPSAlZCIpLCBoc3RhdHVzKTsKICAgICAgICAgICAgdGVtcFZhbCA9IDE7CiAgICAgICAgfQogICAgICAgIGVsc2UKI2VuZGlmCiAgICAgICAgewogICAgICAgICAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJlcGFyZVNjYW5Qcm9maWxlRmlsdGVyKHBNYWMsICZzY2FuRmlsdGVyKTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiMTFSL0VTRS9PdGhlciBBc3NvY2lhdGlvbjogUHJlcGFyZSBzY2FuIHRvIGZpbmQgbmVpZ2hib3IgQVAgZmlsdGVyIHN0YXR1cyAgPSAlZCIpLCBoc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgcHJlcGFyYXRpb24gZmFpbGVkIGZvciBBc3NvYyB0eXBlICVkLi4gQmFpbGluZyBvdXQuLiIpLCB0ZW1wVmFsKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgfQogICAgICAgIGhzdGF0dXMgPSBjc3JTY2FuR2V0UmVzdWx0KHBNYWMsICZzY2FuRmlsdGVyLCAmc2NhblJlc3VsdCk7CiAgICAgICAgaWYgKGhzdGF0dXMgIT0gZUhBTF9TVEFUVVNfU1VDQ0VTUykKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkdldCBTY2FuIFJlc3VsdCBzdGF0dXMgY29kZSAlZCIpLCBoc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgLyogUHJvY2VzcyB0aGUgc2NhbiByZXN1bHRzIGFuZCB1cGRhdGUgcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgIHJvYW1Ob3cgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhblJlc3VsdHMocE1hYywgJnNjYW5SZXN1bHQpOwoKICAgICAgICAvKiBGcmVlIHRoZSBzY2FuIGZpbHRlciAqLwogICAgICAgIGNzckZyZWVTY2FuRmlsdGVyKHBNYWMsICZzY2FuRmlsdGVyKTsKCiAgICAgICAgdGVtcFZhbCA9IGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewojZW5kaWYKICAgICAgICAgc3dpdGNoKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICAgewogICAgICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU46CiAgICAgICAgICAgICAgICBpZiAodGVtcFZhbCkKICAgICAgICAgICAgICAgIHsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIFNpbmNlIHRoZXJlIGFyZSBub24temVybyBjYW5kaWRhdGVzIGZvdW5kCiAgICAgICAgICAgICAgICAgICAgICogYWZ0ZXIgdGhlIHNjYW4sIHJlc2V0IGVtcHR5IHNjYW4gY291bnQuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9IERFRkFVTFRfU0NBTjsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgICAgICAgICAgICAgICAgIC8qIElmIHRoaXMgaXMgYSBub24tMTFyIGFzc29jaWF0aW9uLCB0aGVuIHdlIGNhbiByZWdpc3RlciB0aGUgcmVhc3NvYyBjYWxsYmFjayBoZXJlIGFzIHdlIGhhdmUgc29tZSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFQcyBpbiB0aGUgcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFZhbGlkIEFQcyBhcmUgZm91bmQgYWZ0ZXIgc2Nhbi4gTm93IHdlIGNhbiBpbml0aWF0ZSBwcmUtYXV0aGVudGljYXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4pCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKI2VuZGlmCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCiAgICAgICAgICAgICAgICAgICAgLyogSWYgdGhpcyBpcyBhIG5vbi0xMXIgYXNzb2NpYXRpb24sIHRoZW4gd2UgY2FuIHJlZ2lzdGVyIHRoZSByZWFzc29jIGNhbGxiYWNrIGhlcmUgYXMgd2UgaGF2ZSBzb21lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVBzIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVmFsaWQgQVBzIGFyZSBmb3VuZCBhZnRlciBzY2FuLiBOb3cgd2UgY2FuIGluaXRpYXRlIHByZS1hdXRoZW50aWNhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgICAgICAgICAvKiBJZiBMRlIgaXMgZW5hYmxlZCwgdGhlbiB3ZSBjYW4gcmVnaXN0ZXIgdGhlIHJlYXNzb2MgY2FsbGJhY2sgaGVyZSBhcyB3ZSBoYXZlIHNvbWUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBUHMgaW4gdGhlIHJvYW1hYmxlIEFQIGxpc3QgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVmFsaWQgQVBzIGFyZSBmb3VuZCBhZnRlciBzY2FuLiBOb3cgd2UgY2FuIGluaXRpYXRlIHByZS1hdXRoZW50aWNhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQojZW5kaWYKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkNvbXBsZXRlZCBzY2FubmluZyBvZiBDRkcgQ0hBTiBMSVNUIGluIG5vbi0xMXIgYXNzb2NpYXRpb24uIFJlZ2lzdGVyaW5nIHJlYXNzb2MgY2FsbGJhY2siKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5vdGhpbmcgbXVjaCB0byBkbyBub3cuIFdpbGwgY29udGludWUgdG8gcmVtYWluIGluIHRoaXMgc3RhdGUgaW4gY2FzZSBvZiBub24tMTFyIGFzc29jaWF0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFN0b3AgdGhlIHRpbWVyLiBCdXQgaG93IGxvbmcgdGhlIHJvYW1hYmxlIEFQIGxpc3Qgd2lsbCBiZSB2YWxpZCBpbiBoZXJlLiBBdCBzb21lIHBvaW50IG9mIHRpbWUsIHdlIAogICAgICAgICAgICAgICAgICAgICAgICAgICBuZWVkIHRvIHJlc3RhcnQgdGhlIENGRyBDSEFOIGxpc3Qgc2NhbiBwcm9jZWR1cmUgaWYgcmVhc3NvYyBjYWxsYmFjayBpcyBub3QgaW52b2tlZCBmcm9tIFRMIAogICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoaW4gY2VydGFpbiBkdXJhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAKLy8gICAgICAgICAgICAgICAgICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICAgICAgIEZMKCJObyBjYW5kaWRhdGUgZm91bmQgYWZ0ZXIgc2Nhbm5pbmcgaW4gc3RhdGUgJXMgLi4gIiksCiAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAgICAgLyogSGFuZGxlIGl0IGFwcHJvcHJpYXRlbHkgKi8KICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1IYW5kbGVFbXB0eVNjYW5SZXN1bHQocE1hYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICAgICAgICAgICAgICAgIAogICAgICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTjoKICAgICAgICAgICAgICAgIGlmICghdGVtcFZhbCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5vIGNhbmRpZGF0ZSBmb3VuZCBhZnRlciBzY2FubmluZyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgImluIHN0YXRlICVzIC4uICIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAgICAgLyogU3RvcCB0aGUgdGltZXIgaGVyZSBhcyB0aGUgc2FtZSB0aW1lciB3aWxsIGJlIHN0YXJ0ZWQgYWdhaW4gaW4gQ0ZHX0NIQU5fU0NBTl9TVEFURSAqLwogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgLy8gQ2FuIGNvbWUgb25seSBpbiBJTklUIHN0YXRlLiBXaGVyZSBpbiB3ZSBhcmUgYXNzb2NpYXRlZCwgd2Ugc2VudCBzY2FuIGFuZCB1c2VyCiAgICAgICAgICAgICAgICAvLyBpbiB0aGUgbWVhbnRpbWUgZGVjaWRlcyB0byBkaXNhc3NvYywgd2Ugd2lsbCBiZSBpbiBpbml0IHN0YXRlIGFuZCBzdGlsbCByZWNlaXZlZCBjYWxsCiAgICAgICAgICAgICAgICAvLyBiYWNrIGlzc3VlZC4gU2hvdWxkIG5vdCBjb21lIGhlcmUgaW4gYW55IG90aGVyIHN0YXRlLCBwcmludGluZyBqdXN0IGluIGNhc2UKICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIlN0YXRlICVzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKCiAgICAgICAgICAgICAgICAvLyBMZXRzIGp1c3QgZXhpdCBvdXQgc2lsZW50bHkuCiAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgfQojZW5kaWYKCiAgICAgICAgaWYgKHRlbXBWYWwpCiAgICAgICAgewogICAgICAgICAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgICAgICAgICBpZiAocm9hbU5vdykKICAgICAgICAgICAgewojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICBpZighY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgIEZMKCJJbW1lZGlhdGUgcm9hbS1kZXJlZ2lzdGVyIFVQIGluZGljYXRpb24uIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSk7CgogICAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICAgICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkNvdWxkbid0IGRlcmVnaXN0ZXIgbG9va3VwIFVQIGNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgICAgfQojZW5kaWYKCiAgICAgICAgICAgICAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtVHJpZ2dlckhhbmRvZmYocE1hYyxwTmVpZ2hib3JSb2FtSW5mbyk7CiAgICAgICAgICAgICAgICBpZihlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJjc3JOZWlnaGJvclJvYW1UcmlnZ2VySGFuZG9mZiBmYWlsIHN0YXR1cyA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGhzdGF0dXMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgICAgIH0KCiAgICAgICAgaHN0YXR1cyA9IHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lciwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2QpOwoKICAgICAgICAgICAvKiBUaGlzIHRpbWVyIHNob3VsZCBiZSBzdGFydGVkIGJlZm9yZSByZWdpc3RlcmluZyB0aGUgUmVhc3NvYyBjYWxsYmFjayB3aXRoIFRMLiBUaGlzIGlzIGJlY2F1c2UsIGl0IGlzIHZlcnkgbGlrZWx5IAogICAgICAgICAgICAqIHRoYXQgdGhlIGNhbGxiYWNrIGdldHRpbmcgY2FsbGVkIGltbWVkaWF0ZWx5IGFuZCB0aGUgdGltZXIgd291bGQgbmV2ZXIgYmUgc3RvcHBlZCB3aGVuIHByZS1hdXRoIGlzIGluIHByb2dyZXNzICovCiAgICAgICAgaWYoIGhzdGF0dXMgIT0gZUhBTF9TVEFUVVNfU1VDQ0VTUykKICAgICAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBmYWlsZWQgdG8gc3RhcnQsIHN0YXR1cyA9ICVkIiksIGhzdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIERPV04gZXZlbnQgUmVhc3NvYyBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQiKSwgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpKTsKICAgICAgICAgICAgLyogUmVnaXN0ZXIgYSByZWFzc29jIEluZGljYXRpb24gY2FsbGJhY2sgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCByZWdpc3RlciBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgfQogCiAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIXRlbXBWYWwgfHwgIXJvYW1Ob3cpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKChlU01FX1JPQU1fVFJJR0dFUl9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pIHx8CiAgICAgICAgICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vVGhpcyBpcyBpb2N0bCBiYXNlZCByb2FtaW5nIGlmIHdlIGRpZCBub3QgZmluZCBhbnkgcm9hbWFibGUKICAgICAgICAgICAgICAgICAgICAvL2NhbmRpZGF0ZSB0aGVuIGp1c3QgbG9nIGl0LgogICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSggVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0ZW1wVmFsID0gJXUsIHJvYW1Ob3cgPSAlZCB1T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gJWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcFZhbCwgcm9hbU5vdywgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UoIFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5vIDVHIGNhbmRpZGF0ZSBmb3VuZCB0ZW1wVmFsPSV1LCByb2FtTm93PSVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBWYWwsIHJvYW1Ob3cpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9OT19DQU5EX0ZPVU5EX09SX05PVF9ST0FNSU5HX05PVyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFRoZXJlIGlzIG5vIGNhbmRpZGF0ZSBvciBXZSBhcmUgbm90IHJvYW1pbmcgTm93LgogICAgICAgICAgICAgICAgICAgICAgICAgKiBJbmZvcm0gdGhlIEZXIHRvIHJlc3RhcnQgUm9hbSBPZmZsb2FkIFNjYW4gICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9SRVNUQVJULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVBU09OX05PX0NBTkRfRk9VTkRfT1JfTk9UX1JPQU1JTkdfTk9XKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpOwogICAgICAgICAgICB9CiAgICAgICAgfQojZW5kaWYKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHJlZ2lzdGVyZWQgaW4gY3NyU2NhblJlcXVlc3QoKSB0byAKICAgICAgICAgICAgaW5kaWNhdGUgdGhlIGNvbXBsZXRpb24gb2Ygc2Nhbi4gSWYgc2NhbiBpcyBjb21wbGV0ZWQgZm9yIGFsbCB0aGUgY2hhbm5lbHMgaW4gCiAgICAgICAgICAgIHRoZSBjaGFubmVsIGxpc3QsIHRoaXMgZnVuY3Rpb24gZ2V0cyB0aGUgc2NhbiByZXN1bHQgYW5kIHN0YXJ0cyB0aGUgcmVmcmVzaCByZXN1bHRzCiAgICAgICAgICAgIHRpbWVyIHRvIGF2b2lkIGhhdmluZyBzdGFsZSByZXN1bHRzLiBJZiBzY2FuIGlzIG5vdCBjb21wbGV0ZWQgb24gYWxsIHRoZSBjaGFubmVscywKICAgICAgICAgICAgaXQgcmVzdGFydHMgdGhlIG5laWdoYm9yIHNjYW4gdGltZXIgd2hpY2ggb24gZXhwaXJ5IGlzc3VlcyBzY2FuIG9uIHRoZSBuZXh0IAogICAgICAgICAgICBjaGFubmVsCgogICAgXHBhcmFtICBoYWxIYW5kbGUgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBDb250ZXh0IC0gbm90IHVzZWQKICAgICAgICAgICAgc2NhbklkIC0gbm90IHVzZWQKICAgICAgICAgICAgc3RhdHVzIC0gbm90IHVzZWQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtU2NhblJlcXVlc3RDYWxsYmFjayh0SGFsSGFuZGxlIGhhbEhhbmRsZSwgdm9pZCAqcENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1UzMiBzY2FuSWQsIGVDc3JTY2FuU3RhdHVzIHN0YXR1cykKewogICAgdHBBbmlTaXJHbG9iYWwgICAgICAgICAgICAgICAgICBwTWFjID0gKHRwQW5pU2lyR2xvYmFsKSBoYWxIYW5kbGU7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBTklfVTggICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudENoYW5JbmRleDsKICAgIGVIYWxTdGF0dXMgICAgICAgICAgICAgIGhzdGF0dXM7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICB0QU5JX1UzMiBzZXNzaW9uSWQgPSBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgewogICAgICAgIHNlc3Npb25JZCA9ICooKHRBTklfVTMyKilwQ29udGV4dCk7CgogICAgICAgIGlmICghY3NyUm9hbUlzU3RhTW9kZShwTWFjLCBzZXNzaW9uSWQpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJZ25vcmluZyBzY2FuIHJlcXVlc3QgY2FsbGJhY2sgb24gbm9uLWluZnJhIgogICAgICAgICAgICAgICAgICAgInNlc3Npb24gJWQgaW4gc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQsIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICB9CgogICAgICAgIGlmICghY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsc2Vzc2lvbklkKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgd2hlbiBmYXN0IHJvYW0gaXMgZGlzYWJsZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQogICAgfQojZW5kaWYKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIAogICAgLyogVGhpcyBjYW4gaGFwcGVuIHdoZW4gd2UgcmVjZWl2ZSBhIFVQIGV2ZW50IGZyb20gVEwgaW4gYW55IG9mIHRoZSBzY2FuIHN0YXRlcy4gU2lsZW50bHkgaWdub3JlIGl0ICovCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBDT05ORUNURUQgc3RhdGUuIE11c3QgYmUgYmVjYXVzZSBhIFVQIGV2ZW50IGZyb20gVEwgYWZ0ZXIgaXNzdWluZyBzY2FuIHJlcXVlc3QuIElnbm9yZSBpdCIpKTsKICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIC8qIC0xIGlzIGRvbmUgYmVjYXVzZSB0aGUgY2hhbkluZGV4IHdvdWxkIGhhdmUgZ290IGluY3JlbWVudGVkIGFmdGVyIGlzc3VpbmcgYSBzdWNjZXNzZnVsIHNjYW4gcmVxdWVzdCAqLwogICAgY3VycmVudENoYW5JbmRleCA9IChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgpID8gKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCAtIDEpIDogMDsKCiAgICAvKiBWYWxpZGF0ZSBpbnB1dHMgKi8KICAgIGlmIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJjc3JOZWlnaGJvclJvYW1TY2FuUmVxdWVzdENhbGxiYWNrIHJlY2VpdmVkIGZvciBDaGFubmVsID0gJWQsIENoYW5JbmRleCA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0W2N1cnJlbnRDaGFuSW5kZXhdLCBjdXJyZW50Q2hhbkluZGV4KTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIlJlY2VpdmVkIGR1cmluZyBjbGVhbi11cC4gU2lsZW50bHkgaWdub3JlIHNjYW4gY29tcGxldGlvbiBldmVudC4iKSk7CiAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09IHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcykKICAgIHsKICAgICAgICAvKiBTY2FuIGlzIGNvbXBsZXRlZCBpbiB0aGUgIENGR19DSEFOX1NDQU4gc3RhdGUuIFdlIGNhbiB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlCiAgICAgICAgICAganVzdCB0byBnZXQgdGhlIHJlc3VsdHMgYW5kIHBlcmZvcm0gUFJFQVVUSCAqLwogICAgICAgIC8qIE5vdyB3ZSBoYXZlIGNvbXBsZXRlZCBzY2FubmluZyB0aGUgY2hhbm5lbCBsaXN0LiBXZSBoYXZlIGdldCB0aGUgcmVzdWx0IGJ5IGFwcGx5aW5nIGFwcHJvcHJpYXRlIGZpbHRlcgogICAgICAgICAgIHNvcnQgdGhlIHJlc3VsdHMgYmFzZWQgb24gbmVpZ2hib3JTY29yZSBhbmQgUlNTSSBhbmQgc2VsZWN0IHRoZSBiZXN0IGNhbmRpZGF0ZSBvdXQgb2YgdGhlIGxpc3QgKi8KICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJDaGFubmVsIGxpc3Qgc2NhbiBjb21wbGV0ZWQuIEN1cnJlbnQgY2hhbiBpbmRleCA9ICVkIiksIGN1cnJlbnRDaGFuSW5kZXgpOwogICAgICAgIFZPU19BU1NFUlQocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID09IDApOwoKICAgICAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZShwTWFjKTsKCiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBwcm9jZXNzIGNvbXBsZXRlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgICAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CgogICAgICAgIC8qIFJlc3RhcnQgdGhlIHRpbWVyIGZvciB0aGUgbmV4dCBzY2FuIHNlcXVlbmNlIGFzIHNjYW5uaW5nIGlzIG5vdCBvdmVyICovCiAgICAgICAgaHN0YXR1cyA9IHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kKTsKICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgLyogVGltZXIgc3RhcnQgZmFpbGVkLi4gU2hvdWxkIHdlIEFTU0VSVCBoZXJlPz8/ICovCiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBQQUwgVGltZXIgc3RhcnQgZmFpbGVkLCBzdGF0dXMgPSAlZCwgSWdub3Jpbmcgc3RhdGUgdHJhbnNpdGlvbiIpLCBzdGF0dXMpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVNjYW5SZXN1bHRSZXF1ZXN0Q2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHJlZ2lzdGVyZWQgaW4gY3NyU2NhblJlcXVlc3RMZnJSZXN1bHQoKSB0bwogICAgICAgICAgICBpbmRpY2F0ZSB0aGUgY29tcGxldGlvbiBvZiBzY2FuLiBJZiBzY2FuIGlzIGNvbXBsZXRlZCBmb3IgYWxsIHRoZSBjaGFubmVscyBpbgogICAgICAgICAgICB0aGUgY2hhbm5lbCBsaXN0LCB0aGlzIGZ1bmN0aW9uIGdldHMgdGhlIHNjYW4gcmVzdWx0IGFuZCB0cmVhdHMgdGhlbSBhcyBjYW5kaWRhdGVzCgogICAgXHBhcmFtICBoYWxIYW5kbGUgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBDb250ZXh0IC0gbm90IHVzZWQKICAgICAgICAgICAgc2NhbklkIC0gbm90IHVzZWQKICAgICAgICAgICAgc3RhdHVzIC0gbm90IHVzZWQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtU2NhblJlc3VsdFJlcXVlc3RDYWxsYmFjayh0SGFsSGFuZGxlIGhhbEhhbmRsZSwgdm9pZCAqcENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VMzIgc2NhbklkLCBlQ3NyU2NhblN0YXR1cyBzdGF0dXMpCnsKICAgIHRwQW5pU2lyR2xvYmFsICAgICAgICAgICAgICAgICAgcE1hYyA9ICh0cEFuaVNpckdsb2JhbCkgaGFsSGFuZGxlOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzICAgICAgICAgICAgICBoc3RhdHVzOwoKICAgIHNtc0xvZyhwTWFjLCBMT0cyLCBGTCgiY2FsbGVkICIpKTsKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZS4gSWdub3JlIGl0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIC8qIE5vdyB3ZSBoYXZlIGNvbXBsZXRlZCBzY2FubmluZyB0aGUgY2hhbm5lbCBsaXN0LiBXZSBoYXZlIGdldCB0aGUgcmVzdWx0IGJ5IGFwcGx5aW5nIGFwcHJvcHJpYXRlIGZpbHRlcgogICAgICAgc29ydCB0aGUgcmVzdWx0cyBiYXNlZCBvbiBuZWlnaGJvclNjb3JlIGFuZCBSU1NJIGFuZCBzZWxlY3QgdGhlIGJlc3QgY2FuZGlkYXRlIG91dCBvZiB0aGUgbGlzdCAqLwoKICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlKHBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHByb2Nlc3MgY29tcGxldGUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIGhzdGF0dXMpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KI2VuZGlmIC8vV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Gb3JjZVJvYW1UbzVHaFNjYW5DYih0SGFsSGFuZGxlIGhhbEhhbmRsZSwKICAgICAgICB2b2lkICpwQ29udGV4dCwgdEFOSV9VMzIgc2NhbklkLCBlQ3NyU2NhblN0YXR1cyBzdGF0dXMpCnsKICAgIHRwQW5pU2lyR2xvYmFsICAgICAgICAgICAgICAgICAgcE1hYyA9ICh0cEFuaVNpckdsb2JhbCkgaGFsSGFuZGxlOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzIGhzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdEFOSV9VMzIgc2Vzc2lvbklkID0gQ1NSX1NFU1NJT05fSURfSU5WQUxJRDsKCiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgIHsKICAgICAgICBzZXNzaW9uSWQgPSAqKCh0QU5JX1UzMiopcENvbnRleHQpOwogICAgICAgIGlmICghY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsc2Vzc2lvbklkKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgd2hlbiBmYXN0IHJvYW0gaXMgZGlzYWJsZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICAgICAgaHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIGdvdG8gZW5kOwogICAgICAgIH0KICAgIH0KCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uc2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU4gIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbmVpZ2hib3JSb2FtU3RhdGUgJWQgLiBJZ25vcmUgaXQiKSwKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgaHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgZ290byBlbmQ7CiAgICB9CgogICAgLy9rZWVwIHRyYWNrIG9mIGZvcmNlZCA1RyBzY2FuICYgcm9hbSBpcyBkdWUgdG8gRm9yY2VkIGluaXRpYWwgcm9hbSB0byA1R0h6CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIID0gMTsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICIlczogcHJvY2VzcyBzY2FuIHJlc3VsdHMiLCBfX2Z1bmNfXyk7CiAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZShwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRm9yY2UgUm9hbSBUbyA1R2hTY2FuQ2IgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksCiAgICAgICAgaHN0YXR1cyk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCA9IDA7CiAgICAgICAgLyoKICAgICAgICAgKiBTZW5kIFJTTyBzdGFydCBiZWNhdXNlIGluIGNhc2UgNUcgcm9hbWluZyBob3N0IGhhdmUKICAgICAgICAgKiBub3QgZW5hYmxlZCBhdCBpbml0aWFsIGNvbm5lY3Rpb24KICAgICAgICAgKi8KICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9DT05ORUNUKTsKICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpOwogICAgfQoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICByZXR1cm4gaHN0YXR1czsKCmVuZDoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICByZXR1cm4gaHN0YXR1czsKfQojZW5kaWYKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUNvbnRpZ3VvdXNTY2FuUmVxdWVzdENhbGxiYWNrKHRIYWxIYW5kbGUgaGFsSGFuZGxlLAogICAgICAgIHZvaWQgKnBDb250ZXh0LCB0QU5JX1UzMiBzY2FuSWQsIGVDc3JTY2FuU3RhdHVzIHN0YXR1cykKewogICAgdHBBbmlTaXJHbG9iYWwgICAgICAgICAgICAgICAgICBwTWFjID0gKHRwQW5pU2lyR2xvYmFsKSBoYWxIYW5kbGU7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgaHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0QU5JX1UzMiBzZXNzaW9uSWQgPSBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgewogICAgICAgIHNlc3Npb25JZCA9ICooKHRBTklfVTMyKilwQ29udGV4dCk7CiAgICAgICAgaWYgKCFjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYyxzZXNzaW9uSWQpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCB3aGVuIGZhc3Qgcm9hbSBpcyBkaXNhYmxlZC4gSWdub3JlIGl0IikpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICB9CiAgICB9CgogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIC8qIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIHJlY2VpdmUgYSBVUCBldmVudCBmcm9tIFRMIGluIGFueSBvZiB0aGUgc2NhbiBzdGF0ZXMuIFNpbGVudGx5IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlLiBNdXN0IGJlIGJlY2F1c2UgYSBVUCBldmVudCBmcm9tIFRMIGFmdGVyIGlzc3Vpbmcgc2NhbiByZXF1ZXN0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gSU5JVCBzdGF0ZS4gTXVzdCBoYXZlIGRpc2Nvbm5lY3RlZC4gSWdub3JlIGl0IikpOwogICAgICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCAiJXM6IHByb2Nlc3Mgc2NhbiByZXN1bHRzIiwgX19mdW5jX18pOwogICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUocE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gcHJvY2VzcyBjb21wbGV0ZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgaHN0YXR1cyk7CiAgICB9CgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKCiAgICByZXR1cm4gaHN0YXR1czsKfQojZW5kaWYKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc3N1ZUJnU2NhblJlcXVlc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXNzdWVzIENTUiBzY2FuIHJlcXVlc3QgYWZ0ZXIgcG9wdWxhdGluZyBhbGwgdGhlIEJHIHNjYW4gcGFyYW1zIAogICAgICAgICAgICBwYXNzZWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBCZ1NjYW5QYXJhbXMgLSBQYXJhbXMgdGhhdCBuZWVkIHRvIGJlIHBvcHVsYXRlZCBpbnRvIGNzciBTY2FuIHJlcXVlc3QKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jc3N1ZUJnU2NhblJlcXVlc3QodHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICpwQmdTY2FuUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1UzMiBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzclNjYW5Db21wbGV0ZUNhbGxiYWNrIGNhbGxiYWNrZm4pCnsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRBTklfVTMyIHNjYW5JZDsKICAgIHRDc3JTY2FuUmVxdWVzdCBzY2FuUmVxOwogICAgdEFOSV9VOCBjaGFubmVsOwogICAgdm9pZCAqIHVzZXJEYXRhID0gTlVMTDsKICAgIAogICAgaWYgKDEgPT0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJDaGFubmVsID0gJWQsIENoYW5JbmRleCA9ICVkIiksCiAgICAgICAgICAgIHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0WzBdLCAKICAgICAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4KTsKCiAgICAvL3NlbmQgZG93biB0aGUgc2NhbiByZXEgZm9yIDEgY2hhbm5lbCBvbiB0aGUgYXNzb2NpYXRlZCBTU0lECiAgICB2b3NfbWVtX3NldCgmc2NhblJlcSwgc2l6ZW9mKHRDc3JTY2FuUmVxdWVzdCksIDApOwogICAgLyogRmlsbCBpbiB0aGUgU1NJRCBJbmZvICovCiAgICBzY2FuUmVxLlNTSURzLm51bU9mU1NJRHMgPSAxOwogICAgc2NhblJlcS5TU0lEcy5TU0lETGlzdCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyU1NJREluZm8pICogc2NhblJlcS5TU0lEcy5udW1PZlNTSURzKTsKICAgIGlmIChOVUxMID09IHNjYW5SZXEuU1NJRHMuU1NJRExpc3QpCiAgICB7CiAgICAgICAvL2VyciBtc2cKICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQ291bGRuJ3QgYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgU1NJRC4uRnJlZWluZyBtZW1vcnkgYWxsb2NhdGVkIGZvciBDaGFubmVsIExpc3QiKSk7CiAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHZvc19tZW1femVybyhzY2FuUmVxLlNTSURzLlNTSURMaXN0LCBzaXplb2YodENzclNTSURJbmZvKSAqIHNjYW5SZXEuU1NJRHMubnVtT2ZTU0lEcyk7CgogICAgc2NhblJlcS5TU0lEcy5TU0lETGlzdFswXS5oYW5kb2ZmUGVybWl0dGVkID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICBzY2FuUmVxLlNTSURzLlNTSURMaXN0WzBdLnNzaWRIaWRkZW4gPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgIHZvc19tZW1fY29weSgodm9pZCAqKSZzY2FuUmVxLlNTSURzLlNTSURMaXN0WzBdLlNTSUQsICh2b2lkICopJnBCZ1NjYW5QYXJhbXMtPlNTSUQsIHNpemVvZihwQmdTY2FuUGFyYW1zLT5TU0lEKSk7CiAgICAKICAgIHNjYW5SZXEuQ2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyA9IHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHM7CiAgICBpZiAoMSA9PSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKQogICAgewogICAgICAgIGNoYW5uZWwgPSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdFswXTsKICAgICAgICBzY2FuUmVxLkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gJmNoYW5uZWw7ICAgIAogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHNjYW5SZXEuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdDsKICAgIH0KCiAgICBzY2FuUmVxLkJTU1R5cGUgPSBlQ1NSX0JTU19UWVBFX0lORlJBU1RSVUNUVVJFOwogICAgc2NhblJlcS5zY2FuVHlwZSA9IGVTSVJfQUNUSVZFX1NDQU47CiAgICBzY2FuUmVxLnJlcXVlc3RUeXBlID0gZUNTUl9TQ0FOX0hPX0JHX1NDQU47CiAgICBzY2FuUmVxLm1heENoblRpbWUgPSBwQmdTY2FuUGFyYW1zLT5tYXhDaG5UaW1lOwogICAgc2NhblJlcS5taW5DaG5UaW1lID0gcEJnU2NhblBhcmFtcy0+bWluQ2huVGltZTsKCiAgICB1c2VyRGF0YSA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0QU5JX1UzMikpOwogICAgaWYgKE5VTEwgPT0gdXNlckRhdGEpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJGYWlsZWQgdG8gYWxsb2NhdGUgbWVtb3J5IGZvciBzY2FuIHJlcXVlc3QiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHNjYW5SZXEuU1NJRHMuU1NJRExpc3QpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgKigodEFOSV9VMzIqKXVzZXJEYXRhKSA9IHNlc3Npb25JZDsKICAgIHN0YXR1cyA9IGNzclNjYW5SZXF1ZXN0KHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQsICZzY2FuUmVxLAogICAgICAgICAgICAgICAgICAgICAgICAmc2NhbklkLCBjYWxsYmFja2ZuLCAodm9pZCAqKSB1c2VyRGF0YSk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDU1IgU2NhbiBSZXF1ZXN0IGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBzdGF0dXMpOwogICAgICAgIHZvc19tZW1fZnJlZShzY2FuUmVxLlNTSURzLlNTSURMaXN0KTsKICAgICAgICB2b3NfbWVtX2ZyZWUodXNlckRhdGEpOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uc2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKCiAgICB2b3NfbWVtX2ZyZWUoc2NhblJlcS5TU0lEcy5TU0lETGlzdCk7CiAgICBpZiAoMSA9PSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKQogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIkNoYW5uZWwgTGlzdCBBZGRyZXNzID0gJXBLLCBBY3R1YWwgaW5kZXggPSAlZCIpLAogICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdFswXSwgCiAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgpOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbUZpbGxOb25DaGFubmVsQmdTY2FuUGFyYW1zICh0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwQ3NyQkdTY2FuUmVxdWVzdCBiZ1NjYW5QYXJhbXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCAgICAgICAgICAgICBicm9hZGNhc3RCc3NpZFtdID0geyAweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGIH07CgogICAgdm9zX21lbV9jb3B5KGJnU2NhblBhcmFtcy0+YnNzaWQsIGJyb2FkY2FzdEJzc2lkLCBzaXplb2YodENzckJzc2lkKSk7CiAgICBiZ1NjYW5QYXJhbXMtPlNTSUQubGVuZ3RoID0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQubGVuZ3RoOwogICAgdm9zX21lbV9jb3B5KGJnU2NhblBhcmFtcy0+U1NJRC5zc0lkLCAKICAgICAgICBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3BOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuU1NJRC5zc0lkLAogICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELmxlbmd0aCk7CgogICAgYmdTY2FuUGFyYW1zLT5taW5DaG5UaW1lID0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5taW5DaGFubmVsU2NhblRpbWU7CiAgICBiZ1NjYW5QYXJhbXMtPm1heENoblRpbWUgPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heENoYW5uZWxTY2FuVGltZTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVBlcmZvcm1CZ1NjYW4KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgaW52b2tlZCBvbiBldmVyeSBleHBpcnkgb2YgbmVpZ2hib3JTY2FuVGltZXIgdGlsbCBhbGwgCiAgICAgICAgICAgIHRoZSBjaGFubmVscyBpbiB0aGUgY2hhbm5lbCBsaXN0IGFyZSBzY2FubmVkLiBJdCBwb3B1bGF0ZXMgbmVjZXNzYXJ5IAogICAgICAgICAgICBwYXJhbWV0ZXJzIGZvciBCRyBzY2FuIGFuZCBjYWxscyBhcHByb3ByaWF0ZSBBUCB0byBpbnZva2UgdGhlIENTUiBzY2FuIAogICAgICAgICAgICByZXF1ZXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVBlcmZvcm1CZ1NjYW4odHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkKQp7CiAgICBlSGFsU3RhdHVzICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdENzckJHU2NhblJlcXVlc3QgICBiZ1NjYW5QYXJhbXM7CiAgICB0QU5JX1U4ICAgICAgICAgICAgIGNoYW5uZWwgPSAwOwoKICAgIGlmICggcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ICYmCiAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzICkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJDaGFubmVsIExpc3QgQWRkcmVzcyA9ICVwSyIpLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0WzBdKTsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiQ2hhbm5lbCBMaXN0IEVtcHR5IikpOwogICAgICAgIC8vIEdvIGJhY2sgYW5kIHJlc3RhcnQuIE1vc3RseSB0aW1lciBzdGFydCBmYWlsdXJlIGhhcyBvY2N1cnJlZC4KICAgICAgICAvLyBXaGVuIHRpbWVyIHN0YXJ0IGlzIGRlY2xhcmVkIGEgZmFpbHVyZSwgdGhlbiB3ZSBkZWxldGUgdGhlIGxpc3QuCiAgICAgICAgLy8gU2hvdWxkIG5vdCBoYXBwZW4gbm93IGFzIHdlIHN0b3AgYW5kIHRoZW4gb25seSBzdGFydCB0aGUgc2NhbiB0aW1lci4gCiAgICAgICAgLy8gc3RpbGwgaGFuZGxlIHRoZSB1bmxpa2VseSBjYXNlLgogICAgICAgIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdChwTWFjKTsKICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQoKICAgIC8qIFZhbGlkYXRlIHRoZSBjdXJyZW50Q2hhbkluZGV4IHZhbHVlIGJlZm9yZSB1c2luZyBpdCB0byBpbmRleCB0aGUgQ2hhbm5lbExpc3QgYXJyYXkgKi8KICAgIGlmICggcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4CiAgICAgICAgICAgID4gcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiSW52YWxpZCBjaGFubmVsIGluZGV4OiAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgpOwogICAgICAgIC8vIEdvIGJhY2sgYW5kIHJlc3RhcnQuCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtSGFuZGxlRW1wdHlTY2FuUmVzdWx0KHBNYWMpOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CgogICAgLyogTmVlZCB0byBwZXJmb3JtIHNjYW4gaGVyZSBiZWZvcmUgZ2V0dGluZyB0aGUgbGlzdCAqLwoKICAgIHZvc19tZW1fc2V0KCZiZ1NjYW5QYXJhbXMsIHNpemVvZih0Q3NyQkdTY2FuUmVxdWVzdCksIDApOwoKICAgIGNoYW5uZWwgPSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4XTsKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gMTsKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9ICZjaGFubmVsOwoKICAgIGNzck5laWdoYm9yUm9hbUZpbGxOb25DaGFubmVsQmdTY2FuUGFyYW1zKHBNYWMsICZiZ1NjYW5QYXJhbXMpOwoKICAgIC8qIFVwZGF0ZSB0aGUgcGFzc2l2ZSBzY2FuIHRpbWUgZm9yIERGUyBjaGFubmVsICovCiAgICBpZiAoKFRSVUUgPT0gQ1NSX0lTX0NIQU5ORUxfREZTKGNoYW5uZWwpKSAmJgogICAgICAgICAoVFJVRSA9PSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmFsbG93REZTQ2hhbm5lbFJvYW0pKQogICAgewogICAgICAgICBiZ1NjYW5QYXJhbXMubWluQ2huVGltZSA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ublBhc3NpdmVNaW5DaG5UaW1lOwogICAgICAgICBiZ1NjYW5QYXJhbXMubWF4Q2huVGltZSA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ublBhc3NpdmVNYXhDaG5UaW1lOwogICAgfQoKICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlQmdTY2FuUmVxdWVzdChwTWFjLCAmYmdTY2FuUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCwgY3NyTmVpZ2hib3JSb2FtU2NhblJlcXVlc3RDYWxsYmFjayk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJc3N1ZSBvZiBCRyBTY2FuIHJlcXVlc3QgZmFpbGVkOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCsrOwogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA+PSAKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICB7ICAgICAgCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiQ29tcGxldGVkIHNjYW5uaW5nIGNoYW5uZWxzIGluIENoYW5uZWwgTGlzdDogQ3VyckNoYW5JbmRleCA9ICVkLCBOdW0gQ2hhbm5lbHMgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpOwogICAgICAgIC8qIFdlIGhhdmUgY29tcGxldGVkIHNjYW5uaW5nIGFsbCB0aGUgY2hhbm5lbHMgKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSAwOwogICAgICAgIC8qIFdlIGFyZSBubyBsb25nZXIgc2Nhbm5pbmcgdGhlIGNoYW5uZWwgbGlzdC4gTmV4dCB0aW1lciBmaXJpbmcgc2hvdWxkIGJlIHVzZWQgdG8gZ2V0IHRoZSBzY2FuIHJlc3VsdHMgCiAgICAgICAgICAgYW5kIHNlbGVjdCB0aGUgYmVzdCBBUCBpbiB0aGUgbGlzdCAqLwogICAgICAgIGlmIChlQU5JX0JPT0xFQU5fVFJVRSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MpCiAgICAgICAgewogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICAvKgogICAgICAgICAqIElmIHRoZSBzdGF0dXMgaXMgbm90IHN1Y2Nlc3MsIHdlIG5lZWQgdG8gY2FsbCB0aGUgY2FsbGJhY2sKICAgICAgICAgKiByb3V0aW5lIHNvIHRoYXQgdGhlIHN0YXRlIG1hY2hpbmUgZG9lcyBub3QgZ2V0IHN0dWNrLgogICAgICAgICAqLwogICAgICAgIGNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2socE1hYywgTlVMTCwgMCwgZUNTUl9TQ0FOX0ZBSUxVUkUpOwogICAgfQoKICAgIHJldHVybiBzdGF0dXM7Cn0KCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtU2NhbkZvckluaXRpYWxGb3JjZWQ1R1JvYW1pbmcodHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkKQp7CiAgICBlSGFsU3RhdHVzICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICAgYmdTY2FuUGFyYW1zOwogICAgdEFOSV9VOCAgIG51bU9mQ2hhbm5lbHMgPSAwLCBpID0gMDsKICAgIHRBTklfVTggICB0ZW1wQ2hhbm5lbExpc3RbV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOXTsKICAgIHRBTklfVTggICBjaGFubmVsTGlzdFtXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU5dOwogICAgdEFOSV9VOCAgIHRlbXBOdW1PZkNoYW5uZWxzID0gMDsKCiAgICB2b3NfbWVtX3NldCgmYmdTY2FuUGFyYW1zLCBzaXplb2YodENzckJHU2NhblJlcXVlc3QpLCAwKTsKICAgIC8qIENvbnRpZ3VvdXNseSBzY2FuIGFsbCBjaGFubmVscyBmcm9tIHZhbGlkIGxpc3QgKi8KICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIiVzOiBnZXQgdmFsaWQgY2hhbm5lbCBsaXN0IiwgX19mdW5jX18pOwogICAgdGVtcE51bU9mQ2hhbm5lbHMgPSBzaXplb2YocE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0KTsKCiAgICBpZihIQUxfU1RBVFVTX1NVQ0NFU1MoY3NyR2V0Q2ZnVmFsaWRDaGFubmVscyhwTWFjLAogICAgICAgICAgICAgICAgICAgICh0QU5JX1U4ICopcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICh0QU5JX1UzMiAqKSAmdGVtcE51bU9mQ2hhbm5lbHMpKSkKICAgIHsKICAgICAgICAvL01ha2Ugc3VyZSB3ZSBhcmUgc2Nhbm5pbmcgb25seSBmb3IgNUdoeiBBUCBvbmx5CiAgICAgICAgLy9GaWxldHJpbmcgb3V0IHRoZSA1R0haIGJhc2VkIEFQLmZyb20gdmFsaWQgY2hhbm5lbCBsaXN0CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUJhbmQoCiAgICAgICAgICAgICAgICAgICAgIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgdGVtcE51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgIHRlbXBDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgJnRlbXBOdW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICBTSVJfQkFORF81X0dIWgogICAgICAgICAgICAgICAgICAgICApOwogICAgICAgIGZvciAoaSA9IDA7IChpIDwgdGVtcE51bU9mQ2hhbm5lbHMgJiYoaSA8IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikpOyBpKyspCiAgICAgICAgewogICAgICAgICAgICAvKiBERlMgY2hhbm5lbCB3aWxsIGJlIGFkZGVkIGluIHRoZSBsaXN0IG9ubHkgd2hlbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgREZTIFJvYW1pbmcgc2NhbiBmbGFnIGlzIGVuYWJsZWQqLwogICAgICAgICAgICBpZiAoQ1NSX0lTX0NIQU5ORUxfREZTKHRlbXBDaGFubmVsTGlzdFtpXSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmFsbG93REZTQ2hhbm5lbFJvYW0gPT0gVFJVRSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtudW1PZkNoYW5uZWxzKytdID0gdGVtcENoYW5uZWxMaXN0W2ldOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2hhbm5lbExpc3RbbnVtT2ZDaGFubmVscysrXSA9IHRlbXBDaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoImNzckdldENmZ1ZhbGlkQ2hhbm5lbHMgZ290IGZhaWxlZCAiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CgogICAgaWYobnVtT2ZDaGFubmVscyA9PSAwKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICBGTCgiIE5vIHZhbGlkIDVHaHogY2hhbm5lbCBwcmVzZW50IHNvIHNraXBwaW5nIEluaXRpYWwgRm9yY2VkIDVHaCByb2FtaW5nIikpOwogICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRU1QVFk7CiAgICB9CiAgICBpZiAobnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgIHsKICAgICAgICBudW1PZkNoYW5uZWxzID0gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOOwogICAgfQoKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gbnVtT2ZDaGFubmVsczsKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IGNoYW5uZWxMaXN0OwogICAgZm9yIChpID0gMDsgaSA8IG51bU9mQ2hhbm5lbHM7IGkrKykKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICIlczogdmFsaWQgY2hhbm5lbCBsaXN0ID0gJWQiLAogICAgICAgICAgICAgICAgX19mdW5jX18sIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdFtpXSk7CiAgICB9CiAgICBjc3JOZWlnaGJvclJvYW1GaWxsTm9uQ2hhbm5lbEJnU2NhblBhcmFtcyhwTWFjLCAmYmdTY2FuUGFyYW1zKTsKCiAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZUJnU2NhblJlcXVlc3QocE1hYywgJmJnU2NhblBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQsIGNzck5laWdoYm9yUm9hbUZvcmNlUm9hbVRvNUdoU2NhbkNiKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJGb3JjZWQgaW50aWFsIHJvYW0gdG8gNUdoIHJlcXVlc3QgZmFpbGVkOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQojZW5kaWYKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUNvbnRpZ3VvdXNCZ1NjYW4odHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkKQp7CiAgICBlSGFsU3RhdHVzICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICAgYmdTY2FuUGFyYW1zOwogICAgdEFOSV9VOCAgIG51bU9mQ2hhbm5lbHMgPSAwLCBpID0gMDsKICAgIHRBTklfVTggICAqY2hhbm5lbExpc3QgPSBOVUxMOwogICAgdEFOSV9VOCAgICpwSW5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICB0QU5JX1U4ICAgdG1wQ2hhbm5lbExpc3RbV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOXTsKCiAgICB2b3NfbWVtX3NldCgmYmdTY2FuUGFyYW1zLCBzaXplb2YodENzckJHU2NhblJlcXVlc3QpLCAwKTsKCiAgICAvKiBDb250aWd1b3VzbHkgc2NhbiBhbGwgY2hhbm5lbHMgZnJvbSB2YWxpZCBsaXN0ICovCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsICIlczogZ2V0IHZhbGlkIGNoYW5uZWwgbGlzdCIsIF9fZnVuY19fKTsKCiAgICBudW1PZkNoYW5uZWxzID0gc2l6ZW9mKHBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCk7CgogICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhjc3JHZXRDZmdWYWxpZENoYW5uZWxzKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTMyICopICZudW1PZkNoYW5uZWxzKSkpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDb3VsZCBub3QgZ2V0IHZhbGlkIGNoYW5uZWwgbGlzdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHBJbkNoYW5uZWxMaXN0ID0gcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0OwoKICAgIGlmIChDU1JfSVNfUk9BTV9JTlRSQV9CQU5EX0VOQUJMRUQocE1hYykpCiAgICB7CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUJhbmQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSW5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRtcENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFJGQmFuZChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY3VyckFQb3BlcmF0aW9uQ2hhbm5lbCkpOwogICAgICAgIHBJbkNoYW5uZWxMaXN0ID0gdG1wQ2hhbm5lbExpc3Q7CiAgICB9CgogICAgY2hhbm5lbExpc3QgPSB2b3NfbWVtX21hbGxvYyhudW1PZkNoYW5uZWxzKTsKICAgIGlmICggTlVMTCA9PSBjaGFubmVsTGlzdCApCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJjb3VsZCBub3QgYWxsb2NhdGUgbWVtb3J5IGZvciBjaGFubmVsTGlzdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHZvc19tZW1fY29weShjaGFubmVsTGlzdCwgKHRBTklfVTggKilwSW5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKCiAgICBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyA9IG51bU9mQ2hhbm5lbHM7CiAgICBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBjaGFubmVsTGlzdDsKICAgIGZvciAoaSA9IDA7IGkgPCBudW1PZkNoYW5uZWxzOyBpKyspCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCAiJXM6IHZhbGlkIGNoYW5uZWwgbGlzdCA9ICVkIiwKICAgICAgICAgICAgICAgIF9fZnVuY19fLCBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbaV0pOwogICAgfQogICAgY3NyTmVpZ2hib3JSb2FtRmlsbE5vbkNoYW5uZWxCZ1NjYW5QYXJhbXMocE1hYywgJmJnU2NhblBhcmFtcyk7CgogICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVCZ1NjYW5SZXF1ZXN0KHBNYWMsICZiZ1NjYW5QYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkLCBjc3JOZWlnaGJvclJvYW1Db250aWd1b3VzU2NhblJlcXVlc3RDYWxsYmFjayk7CgogICAgdm9zX21lbV9mcmVlKGNoYW5uZWxMaXN0KTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJc3N1ZSBvZiBCRyBTY2FuIHJlcXVlc3QgZmFpbGVkOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgfQoKICAgIHJldHVybiBzdGF0dXM7Cn0KI2VuZGlmCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JTY2FuVGltZXJDYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUgbmVpZ2hib3Igc2NhbiB0aW1lciBjYWxsYmFjayBmdW5jdGlvbi4gSXQgaW52b2tlcyAKICAgICAgICAgICAgdGhlIEJHIHNjYW4gcmVxdWVzdCBiYXNlZCBvbiB0aGUgY3VycmVudCBhbmQgcHJldmlvdXMgc3RhdGVzCgogICAgXHBhcmFtICBwdiAtIENTUiB0aW1lciBjb250ZXh0IGluZm8gd2hpY2ggaW5jbHVkZXMgcE1hYyBhbmQgc2Vzc2lvbiBJRAoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1OZWlnaGJvclNjYW5UaW1lckNhbGxiYWNrKHZvaWQgKnB2KQp7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gUE1BQ19TVFJVQ1QoIHB2ICk7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbzsKICAgIGlmKCFwTWFjKQogICAgewogICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9FUlJPUiwgRkwoInBNYWMgaXMgTnVsbCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgLy8gY2hlY2sgaWYgYmcgc2NhbiBpcyBvbiBnb2luZywgbm8gbmVlZCB0byBzZW5kIGRvd24gdGhlIG5ldyBwYXJhbXMgaWYgdHJ1ZQogICAgaWYoZUFOSV9CT09MRUFOX1RSVUUgPT0gcE5laWdoYm9yUm9hbUluZm8tPnNjYW5Sc3BQZW5kaW5nKQogICAgewogICAgICAgLy9tc2cKICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiQWxyZWFkeSBCZ1NjYW5Sc3AgaXMgUGVuZGluZyIpKTsKICAgICAgIHJldHVybjsKICAgIH0KCiAgICBzd2l0Y2ggKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU46CiAgICAgICAgICAgIHN3aXRjaChwTmVpZ2hib3JSb2FtSW5mby0+cHJldk5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfUVVFUlk6CiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUJnU2NhbihwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIGNhbGxiYWNrIHJlY2VpdmVkIGluIgogICAgICAgICAgICAgICAgICAgICAgICAgICJzdGF0ZSAlcywgcHJldiBzdGF0ZSA9ICVzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnByZXZOZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU46ICAgICAKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUJnU2NhbihwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuOwp9Cgp2b2lkIGNzck5laWdoYm9yUm9hbUVtcHR5U2NhblJlZnJlc2hUaW1lckNhbGxiYWNrKHZvaWQgKmNvbnRleHQpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVCggY29udGV4dCApOwogICAgVk9TX1NUQVRVUyAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm87CiAgICBpZighcE1hYykKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsIEZMKCJwTWFjIGlzIE51bGwiKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIC8qIFJlc2V0IGFsbCB0aGUgdmFyaWFibGVzIGp1c3QgYXMgbm8gc2NhbiBoYWQgaGFwcGVuZWQgYmVmb3JlICovCiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8ocE1hYyk7CgojaWYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAmJiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRkkKICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpICYmIChwTWFjLT5ycm0ucnJtU21lQ29udGV4dC5ycm1Db25maWcucnJtRW5hYmxlZCkpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiMTFSIEFzc29jaWF0aW9uOk5laWdoYm9yIExvb2t1cCBEb3duIGV2ZW50IHJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZSIpKTsKICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdChwTWFjKTsKICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVwb3J0IHJlcXVlc3QgZmFpbGVkLiBzdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIC8qIEluY3JlbWVudCB0aGUgbmVpZ2hib3IgcmVwb3J0IHJldHJ5IGNvdW50IGFmdGVyIHNlbmRpbmcgdGhlIG5laWdoYm9yIHJlcXVlc3Qgc3VjY2Vzc2Z1bGx5ICovCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0rKzsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfUVVFUlkpCiAgICB9CiAgICBlbHNlCiNlbmRpZgogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIk5vbiAxMVIgb3IgRVNFIEFzc29jaWF0aW9uOmVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBleHBpcmVkIikpOwogICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlc3VsdHNSZWZyZXNoVGltZXJDYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUgdGltZXIgY2FsbGJhY2sgZnVuY3Rpb24gZm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lci4KICAgICAgICAgICAgV2hlbiB0aGlzIGlzIGludm9rZWQsIGl0IGlzIGFzIGdvb2QgYXMgZG93biBldmVudCByZWNlaXZlZCBmcm9tIFRMLiBTbywgCiAgICAgICAgICAgIGNsZWFyIG9mZiB0aGUgcm9hbWFibGUgQVAgbGlzdCBhbmQgc3RhcnQgdGhlIHNjYW4gcHJvY2VkdXJlIGJhc2VkIG9uIDExUiAKICAgICAgICAgICAgb3Igbm9uLTExUiBhc3NvY2lhdGlvbgoKICAgIFxwYXJhbSAgY29udGV4dCAtIENTUiB0aW1lciBjb250ZXh0IGluZm8gd2hpY2ggaW5jbHVkZXMgcE1hYyBhbmQgc2Vzc2lvbiBJRAoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXN1bHRzUmVmcmVzaFRpbWVyQ2FsbGJhY2sodm9pZCAqY29udGV4dCkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKCBjb250ZXh0ICk7CiAgICBWT1NfU1RBVFVTICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbzsKCiAgICBpZighcE1hYykKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsIEZMKCJwTWFjIGlzIE51bGwiKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkRlcmVnaXN0ZXJpbmcgRE9XTiBldmVudCByZWFzc29jIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSkpOwoKICAgIC8qIERlcmVnaXN0ZXIgcmVhc3NvYyBjYWxsYmFjay4gSWdub3JlIHJldHVybiBzdGF0dXMgKi8KICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgIHsKICAgICAgICAvL2VyciBtc2cKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgfQoKICAgIC8qIFJlc2V0IGFsbCB0aGUgdmFyaWFibGVzIGp1c3QgYXMgbm8gc2NhbiBoYWQgaGFwcGVuZWQgYmVmb3JlICovCiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8ocE1hYyk7CgojaWYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAmJiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRkkKICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpICYmIChwTWFjLT5ycm0ucnJtU21lQ29udGV4dC5ycm1Db25maWcucnJtRW5hYmxlZCkpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiMTFSIEFzc29jaWF0aW9uOk5laWdoYm9yIExvb2t1cCBEb3duIGV2ZW50IHJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZSIpKTsKICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdChwTWFjKTsKICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVwb3J0IHJlcXVlc3QgZmFpbGVkLiBzdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIC8qIEluY3JlbWVudCB0aGUgbmVpZ2hib3IgcmVwb3J0IHJldHJ5IGNvdW50IGFmdGVyIHNlbmRpbmcgdGhlIG5laWdoYm9yIHJlcXVlc3Qgc3VjY2Vzc2Z1bGx5ICovCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0rKzsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfUVVFUlkpCiAgICB9CiAgICBlbHNlCiNlbmRpZiAgICAgIAogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIk5vbiAxMVIgb3IgRVNFIEFzc29jaWF0aW9uOnJlc3VsdHMgcmVmcmVzaCB0aW1lciBleHBpcmVkIikpOwogICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzckZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lckNhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHRoZSB0aW1lciBjYWxsYmFjayBmdW5jdGlvbiBmb3IgdHJpZ2dlcmluZwogICAgICAgICAgICAgIHJvYW1pbmcgdG8gNUdIeiBhZnRlciB0aGUgaW5pdGlhbCBhc3NvY2lhdGlvbi4KCiAgICBccGFyYW0gIGNvbnRleHQgLSBDU1IgdGltZXIgY29udGV4dCBpbmZvIHdoaWNoIGluY2x1ZGVzIHBNYWMgYW5kIHNlc3Npb24gSUQKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgp2b2lkIGNzckZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lckNhbGxiYWNrKHZvaWQgKmNvbnRleHQpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVCggY29udGV4dCApOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm87CiAgICBpZighcE1hYykKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsIEZMKCJwTWFjIGlzIE51bGwiKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoImZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lciB0aW1lciBleHBpcmVkIikpOwoKICAgIC8vd2UgZG9uJ3QgbmVlZCB0byBydW4gdGhpcyB0aW1lciBhbnkgbW9yZQogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5mb3JjZWRJbml0aWFsUm9hbVRvNUdIVGltZXIpOwoKICAgIC8vd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIG5vdCBDT05ORUNURUQgc3RhdGUuIElnbm9yZSBpdCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgLy9pdCBtYXkgcG9zc2libGUgdXNlciByZWNvbm5lY3RlZCAvIERVVCByb2FtZWQgdG8gb3RoZXIgYmFuZCBhcCBidHcKICAgIC8vdGltZXIgc3RhcnRlZCBhbmQgdGltZXIgY2FsbGJhY2sgaGl0LgogICAgaWYoR2V0UkZCYW5kKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSA9PSBTSVJfQkFORF81X0dIWikKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICAgICAgRkwoIkRVVCBpcyBhbHJlYWR5IGNvbm5lY3RlZCB0byA1R0ggYXAsIHNvIG5vIG5lZWQgdG8gdHJpZ2dlciBmb3JjZWQgcm9hbS4iKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA9IHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKICAgIC8qCiAgICAgKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlIGZvciBhbGwgdmFsaWQgY2hhbm5sZXMgZm9yIDVHaHoKICAgICAqIHB1cmdlIG5vbi1QMlAgcmVzdWx0cyBmcm9tIHRoZSBwYXN0IGZvciA1R2h6IGJhbmQKICAgICAqLwogICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0Rm9yQmFuZChwTWFjLCBWT1NfRkFMU0UsIFNJUl9CQU5EXzVfR0haKTsKICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVNjYW5Gb3JJbml0aWFsRm9yY2VkNUdSb2FtaW5nKAogICAgICAgICAgICAgICAgIHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQpOwogICAgaWYoc3RhdHVzICE9IGVIQUxfU1RBVFVTX1NVQ0NFU1MpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgIEZMKCJjc3JOZWlnaGJvclJvYW1TY2FuRm9ySW5pdGlhbEZvcmNlZDVHUm9hbWluZyBmYWlsZWQgc3RhdHVzPSVkIiksIHN0YXR1cyk7CiAgICAgICAgLy9TZW5kIFJTTyBzdGFydCBiZWNhdXNlIGluIGNhc2UgNUcgcm9hbWluZyBob3N0IGhhdmUgbm90IGVuYWJsZWQgYXQgaW5pdGlhbCBjb25uZWN0aW9uCiAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIFRyYW5zaXRpb24gdG8gQ0ZHX0NIQU5fTElTVF9TQ0FOICovCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU4pOwp9CgojaWYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAmJiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRkkKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGludm9rZWQgd2hlbiBUTCBpc3N1ZXMgYSBkb3duIGV2ZW50IGFuZCB0aGUgY3VycmVudCBhc3NvYyAKICAgICAgICAgICAgaXMgYSAxMVIgYXNzb2NpYXRpb24uIEl0IGludm9rZXMgU01FIFJSTSBBUEkgdG8gaXNzdWUgdGhlIG5laWdoYm9yIHJlcXVlc3QgdG8gCiAgICAgICAgICAgIHRoZSBjdXJyZW50bHkgYXNzb2NpYXRlZCBBUCB3aXRoIHRoZSBjdXJyZW50IFNTSUQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0UnJtTmVpZ2hib3JSc3BDYWxsYmFja0luZm8gY2FsbGJhY2tJbmZvOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0UnJtTmVpZ2hib3JSZXEgbmVpZ2hib3JSZXE7CgoKICAgIG5laWdoYm9yUmVxLm5vX3NzaWQgPSAwOwoKICAgIC8qIEZpbGwgaW4gdGhlIFNTSUQgKi8KICAgIG5laWdoYm9yUmVxLnNzaWQubGVuZ3RoID0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQubGVuZ3RoOwogICAgdm9zX21lbV9jb3B5KG5laWdoYm9yUmVxLnNzaWQuc3NJZCwgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQuc3NJZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELmxlbmd0aCk7CiAgICAKICAgIGNhbGxiYWNrSW5mby5uZWlnaGJvclJzcENhbGxiYWNrID0gY3NyTmVpZ2hib3JSb2FtUlJNTmVpZ2hib3JSZXBvcnRSZXN1bHQ7CiAgICBjYWxsYmFja0luZm8ubmVpZ2hib3JSc3BDYWxsYmFja0NvbnRleHQgPSBwTWFjOwogICAgY2FsbGJhY2tJbmZvLnRpbWVvdXQgPSBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJlcG9ydFRpbWVvdXQ7CgogICAgcmV0dXJuIHNtZV9OZWlnaGJvclJlcG9ydFJlcXVlc3QocE1hYywodEFOSV9VOCkgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwgJm5laWdoYm9yUmVxLCAmY2FsbGJhY2tJbmZvKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUNoYW5uZWxzRmlsdGVyQnlCYW5kCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZmlsdGVyIG91dCB0aGUgY2hhbm5lbHMKICAgICAgICAgICAgYmFzZWQgb24gdGhlIEJhbmQgZ2l2ZW4gYXMgaW5wdXQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGlucHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBpbnB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIGlucHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBwT3V0cHV0Q2hhbm5lbExpc3QgLSBUaGUgb3V0cHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBvdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBjaGFubmVscyBpbiBvdXRwdXQgY2hhbm5lbCBsaXN0CiAgICBccGFyYW0gIHBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIGZpbmFsIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgb3V0cHV0IGNoYW5uZWwgbGlzdC4KICAgIFxwYXJhbSBiYW5kIC0gVGhlICBiYW5kIHdoaWNoIHdpbGwgYmUgZ2V0IGNvbXBhcmVkIHdpdGggdGhlIGlucHV0IGNoYW5uZWwgbGlzdCBiYW5kCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUJhbmQoCiAgICAgICAgICAgICAgICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCogIHBJbnB1dENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCAgIGlucHV0TnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTgqICBwT3V0cHV0Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4KiAgcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICB0U2lyUkZCYW5kIGJhbmQKICAgICAgICAgICAgICAgICAgICAgICkKewogICAgdEFOSV9VOCBpID0gMDsKICAgIHRBTklfVTggbnVtQ2hhbm5lbHMgPSAwOwoKICAgIC8vIENoZWNrIGZvciBOVUxMIHBvaW50ZXIKICAgIGlmICghcElucHV0Q2hhbm5lbExpc3QpIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CgogICAgLy8gQ2hlY2sgZm9yIE5VTEwgcG9pbnRlcgogICAgaWYgKCFwT3V0cHV0Q2hhbm5lbExpc3QpIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CgogICAgaWYgKGlucHV0TnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgIHsKICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgIiVzOiBXcm9uZyBOdW1iZXIgb2YgSW5wdXQgQ2hhbm5lbHMgJWQiLAogICAgICAgICAgICAgX19mdW5jX18sIGlucHV0TnVtT2ZDaGFubmVscyk7CiAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgaW5wdXROdW1PZkNoYW5uZWxzOyBpKyspCiAgICB7CiAgICAgICAgaWYgKGJhbmQgPT0gR2V0UkZCYW5kKHBJbnB1dENoYW5uZWxMaXN0W2ldKSkKICAgICAgICB7CiAgICAgICAgICAgIHBPdXRwdXRDaGFubmVsTGlzdFtudW1DaGFubmVsc10gPSBwSW5wdXRDaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgbnVtQ2hhbm5lbHMrKzsKICAgICAgICB9CiAgICB9CgogICAgLy8gUmV0dXJuIGZpbmFsIG51bWJlciBvZiBjaGFubmVscwogICAgKnBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzID0gbnVtQ2hhbm5lbHM7CgogICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU1lcmdlQ2hhbm5lbExpc3RzIAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIG1lcmdlIHR3byBjaGFubmVsIGxpc3QuCiAgICAgICAgICAgIE5COiBJZiBjYWxsZWQgd2l0aCBvdXRwdXROdW1PZkNoYW5uZWxzID09IDAsIHRoaXMgcm91dGluZXMKICAgICAgICAgICAgICAgIHNpbXBseSBjb3BpZXMgdGhlIGlucHV0IGNoYW5uZWwgbGlzdCB0byB0aGUgb3V0cHV0IGNoYW5uZWwgbGlzdC4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGFkZHRpb25hbCBjaGFubmVscyB0byBtZXJnZSBpbiB0byB0aGUgIm1lcmdlZCIgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgaW5wdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBhZGRpdGlvbmFsIGNoYW5uZWxzLgogICAgXHBhcmFtICBwT3V0cHV0Q2hhbm5lbExpc3QgLSBUaGUgcGxhY2UgdG8gcHV0IHRoZSAibWVyZ2VkIiBjaGFubmVsIGxpc3QuCiAgICBccGFyYW0gIG91dHB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgb3JpZ2luYWwgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSAibWVyZ2VkIiBjaGFubmVscyBsaXN0LgogICAgXHBhcmFtICBwTWVyZ2VkT3V0cHV0TnVtT2ZDaGFubmVscyAtIFRoZSBmaW5hbCBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlICJtZXJnZWQiIGNoYW5uZWwgbGlzdC4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU1lcmdlQ2hhbm5lbExpc3RzKCAKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICB0QU5JX1U4ICAgKnBJbnB1dENoYW5uZWxMaXN0LCAKICAgICAgICB0QU5JX1U4ICBpbnB1dE51bU9mQ2hhbm5lbHMsCiAgICAgICAgdEFOSV9VOCAgICpwT3V0cHV0Q2hhbm5lbExpc3QsCiAgICAgICAgdEFOSV9VOCAgb3V0cHV0TnVtT2ZDaGFubmVscywKICAgICAgICB0QU5JX1U4ICAqcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMKICAgICAgICApCnsKICAgIHRBTklfVTggaSA9IDA7CiAgICB0QU5JX1U4IGogPSAwOwogICAgdEFOSV9VOCBudW1DaGFubmVscyA9IG91dHB1dE51bU9mQ2hhbm5lbHM7CgogICAgLy8gQ2hlY2sgZm9yIE5VTEwgcG9pbnRlcgogICAgaWYgKCFwSW5wdXRDaGFubmVsTGlzdCkgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKCiAgICAvLyBDaGVjayBmb3IgTlVMTCBwb2ludGVyCiAgICBpZiAoIXBPdXRwdXRDaGFubmVsTGlzdCkgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKCiAgICBpZiAoaW5wdXROdW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgewogICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAiJXM6IFdyb25nIE51bWJlciBvZiBJbnB1dCBDaGFubmVscyAlZCIsCiAgICAgICAgICAgICBfX2Z1bmNfXywgaW5wdXROdW1PZkNoYW5uZWxzKTsKICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKICAgIH0KICAgIGlmIChvdXRwdXROdW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgewogICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAiJXM6IFdyb25nIE51bWJlciBvZiBPdXRwdXQgQ2hhbm5lbHMgJWQiLAogICAgICAgICAgICAgX19mdW5jX18sIGlucHV0TnVtT2ZDaGFubmVscyk7CiAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CiAgICB9CgogICAgLyogQWRkIHRoZSAibmV3IiBjaGFubmVscyBpbiB0aGUgaW5wdXQgbGlzdCB0byB0aGUgZW5kIG9mIHRoZSBvdXRwdXQgbGlzdC4KICAgICAgIENoZWNrIGFkZGVkIGluIGZvciBsb29wIHRvIG1ha2Ugc3VyZSBvdXRwdXRsaXN0IGRvZXNuJ3QgZXhjZWVkcyB2YWxpZAogICAgICAgY2hhbm5lbCBsaXN0IGxlbmd0aC4gKi8KICAgIGZvciAoaSA9IDA7IChpIDwgaW5wdXROdW1PZkNoYW5uZWxzKSAmJiAobnVtQ2hhbm5lbHMgPCBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU4pOyBpKyspCiAgICB7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IG91dHB1dE51bU9mQ2hhbm5lbHM7IGorKykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwSW5wdXRDaGFubmVsTGlzdFtpXSA9PSBwT3V0cHV0Q2hhbm5lbExpc3Rbal0pCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKGogPT0gb3V0cHV0TnVtT2ZDaGFubmVscykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwSW5wdXRDaGFubmVsTGlzdFtpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sIAogICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXSBBZGRpbmcgZXh0cmEgJWQgdG8gTmVpZ2hib3IgY2hhbm5lbCBsaXN0IiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dENoYW5uZWxMaXN0W2ldKTsgCiAgICAgICAgICAgICAgICBwT3V0cHV0Q2hhbm5lbExpc3RbbnVtQ2hhbm5lbHNdID0gcElucHV0Q2hhbm5lbExpc3RbaV07IAogICAgICAgICAgICAgICAgbnVtQ2hhbm5lbHMrKzsgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gUmV0dXJuIGZpbmFsIG51bWJlciBvZiBjaGFubmVscwogICAgKnBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzID0gbnVtQ2hhbm5lbHM7IAoKICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1DcmVhdGVDaGFuTGlzdEZyb21OZWlnaGJvclJlcG9ydAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBpbnZva2VkIHdoZW4gbmVpZ2hib3IgcmVwb3J0IGlzIHJlY2VpdmVkIGZvciB0aGUgCiAgICAgICAgICAgIG5laWdoYm9yIHJlcXVlc3QuIEJhc2VkIG9uIHRoZSBjaGFubmVscyBwcmVzZW50IGluIHRoZSBuZWlnaGJvciByZXBvcnQsIAogICAgICAgICAgICBpdCBnZW5lcmF0ZXMgY2hhbm5lbCBsaXN0IHdoaWNoIHdpbGwgYmUgdXNlZCBpbiBSRVBPUlRfU0NBTiBzdGF0ZSB0bwogICAgICAgICAgICBzY2FuIGZvciB0aGVzZSBuZWlnaGJvciBBUHMKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1DcmVhdGVDaGFuTGlzdEZyb21OZWlnaGJvclJlcG9ydCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cFJybU5laWdoYm9yUmVwb3J0RGVzYyAgICAgICBwTmVpZ2hib3JCc3NEZXNjOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCAgICAgICAgICAgICAgICAgICAgICAgbnVtQ2hhbm5lbHMgPSAwOwogICAgdEFOSV9VOCAgICAgICAgICAgICAgICAgICAgICAgaSA9IDA7CiAgICB0QU5JX1U4ICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtNQVhfQlNTX0lOX05FSUdIQk9SX1JQVF07CiAgICB0QU5JX1U4ICAgICAgICAgICAgICAgICAgICAgICBtZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzID0gMDsKCiAgICAvKiBUaGlzIHNob3VsZCBhbHdheXMgc3RhcnQgZnJvbSAwIHdoZW5ldmVyIHdlIGNyZWF0ZSBhIGNoYW5uZWwgbGlzdCBvdXQgb2YgbmVpZ2hib3IgQVAgbGlzdCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKCiAgICBwTmVpZ2hib3JCc3NEZXNjID0gc21lUnJtR2V0Rmlyc3RCc3NFbnRyeUZyb21OZWlnaGJvckNhY2hlKHBNYWMpOwoKICAgIHdoaWxlIChwTmVpZ2hib3JCc3NEZXNjKQogICAgewogICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPj0gTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpIGJyZWFrOwogICAgICAgIAogICAgICAgIC8qIFVwZGF0ZSB0aGUgbmVpZ2hib3IgQlNTIEluZm8gaW4gdGhlIDExciBGVCBSb2FtIEluZm8gKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mb1twTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnRdLmNoYW5uZWxOdW0gPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWw7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm9bcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0XS5uZWlnaGJvclNjb3JlID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1U4KXBOZWlnaGJvckJzc0Rlc2MtPnJvYW1TY29yZTsKICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm9bcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0XS5uZWlnaGJvckJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQrKzsKCiAgICAgICAgLyogU2F2aW5nIHRoZSBjaGFubmVsIGxpc3Qgbm9uLXJlZHVuZGFudGx5ICovCiAgICAgICAgZm9yIChpID0gMDsgKGkgPCBudW1DaGFubmVscyAmJiBpIDwgTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAocE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWwgPT0gY2hhbm5lbExpc3RbaV0pCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmIChpID09IG51bUNoYW5uZWxzKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoQ1NSX0lTX1JPQU1fSU5UUkFfQkFORF9FTkFCTEVEKHBNYWMpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0byBhZGQgb25seSBpZiBpdHMgdGhlIHNhbWUgYmFuZAogICAgICAgICAgICAgICAgICAgIGlmIChHZXRSRkJhbmQocE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUG9wZXJhdGlvbkNoYW5uZWwpID09CiAgICAgICAgICAgICAgICAgICAgICAgIEdldFJGQmFuZChwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXSBBZGRpbmcgJWQgdG8gTmVpZ2hib3IgY2hhbm5lbCBsaXN0IChTYW1lIGJhbmQpXG4iLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtudW1DaGFubmVsc10gPSBwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbDsKICAgICAgICAgICAgICAgICAgICAgICAgbnVtQ2hhbm5lbHMrKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gQWRkaW5nICVkIHRvIE5laWdoYm9yIGNoYW5uZWwgbGlzdFxuIiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0W251bUNoYW5uZWxzXSA9IHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsOwogICAgICAgICAgICAgICAgICAgIG51bUNoYW5uZWxzKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIHBOZWlnaGJvckJzc0Rlc2MgPSBzbWVScm1HZXROZXh0QnNzRW50cnlGcm9tTmVpZ2hib3JDYWNoZShwTWFjLCBwTmVpZ2hib3JCc3NEZXNjKTsKICAgIH0KCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KQogICAgewogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAvKiBTdG9yZSB0aGUgb2J0YWluZWQgY2hhbm5lbCBsaXN0IHRvIHRoZSBOZWlnaGJvciBDb250cm9sIGRhdGEgc3RydWN0dXJlICovCiAgICBpZiAobnVtQ2hhbm5lbHMpCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gdm9zX21lbV9tYWxsb2MoKG51bUNoYW5uZWxzKSAqIHNpemVvZih0QU5JX1U4KSk7CiAgICBpZiAoTlVMTCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgQ2hhbm5lbCBsaXN0IGZhaWxlZC4uIFRMIGV2ZW50IGlnbm9yZWQiKSk7CiAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9SRVNPVVJDRVM7CiAgICB9CgogICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsIChudW1DaGFubmVscykgKiBzaXplb2YodEFOSV9VOCkpOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSBudW1DaGFubmVsczsKICAgIC8qCiAgICAgKiBDcmVhdGUgYSBVbmlvbiBvZiBvY2N1cGllZCBjaGFubmVsIGxpc3QgbGVhcm50IGJ5IHRoZSBEVVQgYWxvbmcgd2l0aCB0aGUgTmVpZ2hib3IKICAgICAqIHJlcG9ydCBDaGFubmVscy4gVGhpcyBpbmNyZWFzZXMgdGhlIGNoYW5jZXMgb2YgdGhlIERVVCB0byBnZXQgYSBjYW5kaWRhdGUgQVAgd2hpbGUKICAgICAqIHJvYW1pbmcgZXZlbiBpZiB0aGUgTmVpZ2hib3IgUmVwb3J0IGlzIG5vdCBhYmxlIHRvIHByb3ZpZGUgc3VmZmljaWVudCBpbmZvcm1hdGlvbi4KICAgICAqICovCiAgICBpZiAocE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLm51bUNoYW5uZWxzKQogICAgewogICAgICAgY3NyTmVpZ2hib3JSb2FtTWVyZ2VDaGFubmVsTGlzdHMocE1hYywKICAgICAgICAgICAgICAgICAgJnBNYWMtPnNjYW4ub2NjdXBpZWRDaGFubmVscy5jaGFubmVsTGlzdFswXSwKICAgICAgICAgICAgICAgICAgcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLm51bUNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0WzBdLAogICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgJm1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMpOwogICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPQogICAgICAgICAgICAgICAgICBtZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzOwoKICAgIH0KICAgIC8qSW5kaWNhdGUgdGhlIGZpcm13YXJlIGFib3V0IHRoZSB1cGRhdGUgb25seSBpZiBhbnkgbmV3IGNoYW5uZWxzIGFyZSBhZGRlZC4KICAgICAqIE90aGVyd2lzZSwgdGhlIGZpcm13YXJlIHdvdWxkIGFscmVhZHkgYmUga25vd2luZyB0aGUgbm9uLUlBUFBuZWlnaGJvcmxpc3QKICAgICAqIGNoYW5uZWxzLiBUaGVyZSBpcyBubyBuZWVkIHRvIHVwZGF0ZS4qLwogICAgaWYgKG51bUNoYW5uZWxzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiSUFQUCBOZWlnaGJvciBsaXN0IGNhbGxiYWNrIHJlY2VpdmVkIGFzIGV4cGVjdGVkIgogICAgICAgICAgICAgICAiaW4gc3RhdGUgJXMuIiksCiAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9UUlVFOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewogICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9VUERBVEVfQ0ZHLCBSRUFTT05fQ0hBTk5FTF9MSVNUX0NIQU5HRUQpOwogICAgICAgIH0KI2VuZGlmCiAgICB9CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAKICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SUk1OZWlnaGJvclJlcG9ydFJlc3VsdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUgbmVpZ2hib3IgcmVwb3J0IGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBpbnZva2VkIGJ5IAogICAgICAgICAgICBTTUUgUlJNIG9uIHJlY2VpdmluZyBhIG5laWdoYm9yIHJlcG9ydCBvciBvZiBuZWlnaGJvciByZXBvcnQgaXMgbm90IAogICAgICAgICAgICByZWNlaXZlZCBhZnRlciB0aW1lb3V0LiBPbiByZWNlaXZpbmcgYSB2YWxpZCByZXBvcnQsIGl0IGdlbmVyYXRlcyBhIAogICAgICAgICAgICBjaGFubmVsIGxpc3QgZnJvbSB0aGUgbmVpZ2hib3IgcmVwb3J0IGFuZCBzdGFydHMgdGhlIAogICAgICAgICAgICBuZWlnaGJvciBzY2FuIHRpbWVyCgogICAgXHBhcmFtICBjb250ZXh0IC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICB2b3NTdGF0dXMgLSBTdGF0dXMgb2YgdGhlIGNhbGxiYWNrKFNVQ0NFU1MvRkFJTFVSRSkKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUlJNTmVpZ2hib3JSZXBvcnRSZXN1bHQodm9pZCAqY29udGV4dCwgVk9TX1NUQVRVUyB2b3NTdGF0dXMpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVChjb250ZXh0KTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk5laWdoYm9yIHJlcG9ydCByZXN1bHQgY2FsbGJhY2sgd2l0aCBzdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgc3dpdGNoIChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZOgogICAgICAgICAgICAvKiBSZXNldCB0aGUgcmVwb3J0IHBlbmRpbmcgdmFyaWFibGUgKi8KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTID09IHZvc1N0YXR1cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogTmVlZCB0byBjcmVhdGUgY2hhbm5lbCBsaXN0IGJhc2VkIG9uIHRoZSBuZWlnaGJvciBBUCBsaXN0IGFuZCB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlICovCiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1DcmVhdGVDaGFuTGlzdEZyb21OZWlnaGJvclJlcG9ydChwTWFjKTsKICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgPT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkNoYW5uZWwgTGlzdCBjcmVhdGVkIGZyb20gTmVpZ2hib3IgcmVwb3J0LCBUcmFuc2l0aW9uaW5nIHRvIE5FSUdIQk9SX1NDQU4gc3RhdGUiKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyogV2UgYXJlIGdvbm5hIHNjYW4gbm93LiBSZW1lbWJlciB0aGUgdGltZSBzdGFtcCB0byBmaWx0ZXIgb3V0IHJlc3VsdHMgb25seSBhZnRlciB0aGlzIHRpbWVzdGFtcCAqLwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5SZXF1ZXN0VGltZVN0YW1wID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLyogTm93IHJlYWR5IGZvciBuZWlnaGJvciBzY2FuIGJhc2VkIG9uIHRoZSBjaGFubmVsIGxpc3QgY3JlYXRlZCAqLwogICAgICAgICAgICAgICAgLyogU3RhcnQgTmVpZ2hib3Igc2NhbiB0aW1lciBub3cuIE11bHRpcGxpY2F0aW9uIGJ5IFBBTF9USU1FUl9UT19NU19VTklUIGlzIHRvIGNvbnZlcnQgbXMgdG8gdXMgd2hpY2ggaXMgCiAgICAgICAgICAgICAgICAgICB3aGF0IHBhbFRpbWVyU3RhcnQgZXhwZWN0cyAqLwogICAgICAgICAgICAgICAgc3RhdHVzID0gdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclNjYW5QZXJpb2QpOwogICAgICAgICAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIFRpbWVyIHN0YXJ0IGZhaWxlZC4uIFNob3VsZCB3ZSBBU1NFUlQgaGVyZT8/PyAqLwogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUEFMIFRpbWVyIHN0YXJ0IGZvciBuZWlnaGJvciBzY2FuIHRpbWVyIGZhaWxlZCwgc3RhdHVzID0gJWQsIElnbm9yaW5nIHN0YXRlIHRyYW5zaXRpb24iKSwgc3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLyogTmVpZ2hib3Igc2NhbiB0aW1lciBzdGFydGVkLiBUcmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlICovCiAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIE5laWdoYm9yIHJlcG9ydCB0aW1lb3V0IGhhcHBlbmVkIGluIFNNRSBSUk0uIFdlIGNhbiB0cnkgc2VuZGluZyBtb3JlIG5laWdoYm9yIHJlcXVlc3RzIHVudGlsIHdlIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWNoIHRoZSBtYXhOZWlnaGJvclJldHJpZXMgb3IgcmVjZWl2aW5nIGEgc3VjY2Vzc2Z1bCBuZWlnaGJvciByZXNwb25zZSAqLwogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVzdWx0IGZhaWxlZCBhZnRlciAlZCByZXRyaWVzLCBNQVggUkVUUklFUyA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtLCBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heE5laWdoYm9yUmV0cmllcyk7CiAgICAgICAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPj0gCiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4TmVpZ2hib3JSZXRyaWVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQmFpbGluZyBvdXQgdG8gQ0ZHIENoYW5uZWwgbGlzdCBzY2FuLi4gIikpOwogICAgICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJUcmFuc2l0IHRvIENGRyBDaGFubmVsIGxpc3Qgc2NhbiBzdGF0ZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQgIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLyogV2UgdHJhbnNpdGlvbmVkIHRvIGRpZmZlcmVudCBzdGF0ZSBub3cuIFJlc2V0IHRoZSBOZWlnaGJvciByZXBvcnQgcmV0cnkgY291bnQgKi8KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVOZWlnaGJvclJwdFJlcXVlc3QocE1hYyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlcG9ydCByZXF1ZXN0IGZhaWxlZC4gc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICAgICAgICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXN1bHQgY2FsbGJhY2sgbm90IGV4cGVjdGVkIGluIgogICAgICAgICAgICAgICAgICAgInN0YXRlICVzLCBJZ25vcmluZy4uIiksCiAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybjsKfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KCgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUiAKdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUlzU3NpZEFuZFNlY3VyaXR5TWF0Y2goCiAgICAgICAgdHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwQ3VyUHJvZmlsZSwKICAgICAgICB0U2lyQnNzRGVzY3JpcHRpb24gKnBCc3NEZXNjLAogICAgICAgIHREb3QxMWZCZWFjb25JRXMgKnBJZXMpCnsKICAgIHRDc3JBdXRoTGlzdCBhdXRoVHlwZTsKICAgIHRDc3JFbmNyeXB0aW9uTGlzdCB1Q0VuY3J5cHRpb25UeXBlOwogICAgdENzckVuY3J5cHRpb25MaXN0IG1DRW5jcnlwdGlvblR5cGU7CiAgICB0QU5JX0JPT0xFQU4gZk1hdGNoID0gRkFMU0U7CgogICAgYXV0aFR5cGUubnVtRW50cmllcyA9IDE7CiAgICBhdXRoVHlwZS5hdXRoVHlwZVswXSA9IHBDdXJQcm9maWxlLT5BdXRoVHlwZTsKICAgIHVDRW5jcnlwdGlvblR5cGUubnVtRW50cmllcyA9IDE7CiAgICB1Q0VuY3J5cHRpb25UeXBlLmVuY3J5cHRpb25UeXBlWzBdID0gcEN1clByb2ZpbGUtPkVuY3J5cHRpb25UeXBlOwogICAgbUNFbmNyeXB0aW9uVHlwZS5udW1FbnRyaWVzID0gMTsKICAgIG1DRW5jcnlwdGlvblR5cGUuZW5jcnlwdGlvblR5cGVbMF0gPSBwQ3VyUHJvZmlsZS0+bWNFbmNyeXB0aW9uVHlwZTsKCiAgICBpZiggcEllcyApCiAgICB7CiAgICAgICAgaWYocEllcy0+U1NJRC5wcmVzZW50KQogICAgICAgIHsKICAgICAgICAgICAgZk1hdGNoID0gY3NySXNTc2lkTWF0Y2goIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgKHZvaWQgKilwQ3VyUHJvZmlsZS0+U1NJRC5zc0lkLCBwQ3VyUHJvZmlsZS0+U1NJRC5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgcEllcy0+U1NJRC5zc2lkLCBwSWVzLT5TU0lELm51bV9zc2lkLAogICAgICAgICAgICAgICAgICAgIGVBTklfQk9PTEVBTl9UUlVFICk7CiAgICAgICAgICAgIGlmKFRSVUUgPT0gZk1hdGNoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogZm9yIG5vdyB3ZSBhcmUgc2VuZGluZyBOVUxMIGZvciBhbGwgUE1GIHJlbGF0ZWQgZmlsdGVyCiAgICAgICAgICAgICAgICAgKiBwYXJhbWV0ZXJzIGR1cmluZyByb2FtIHRvIHRoZSBuZWlnaGJvciBBUCBiZWNhdXNlCiAgICAgICAgICAgICAgICAgKiBzbyBmYXIgODAyMTFXIHNwZWMgZG9lc24ndCBzcGVjaWZ5IGFueXRoaW5nIGFib3V0CiAgICAgICAgICAgICAgICAgKiByb2FtaW5nIHNjZW5hcmlvLgogICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAqIE9uY2Ugcm9hbWluZyBzY2VuYXJpbyBpcyBkZWZpbmVkLCB3ZSBzaG91bGQgcmUtdmlzaXQKICAgICAgICAgICAgICAgICAqIHRoaXMgc2VjdGlvbiBhbmQgcmVtb3ZlIHRoaXMgY29tbWVudC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgZk1hdGNoID0gY3NySXNTZWN1cml0eU1hdGNoKHBNYWMsICZhdXRoVHlwZSwgJnVDRW5jcnlwdGlvblR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1DRW5jcnlwdGlvblR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQnNzRGVzYywgcEllcywgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgICAgICByZXR1cm4gKGZNYXRjaCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gKGZNYXRjaCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsgIC8vIFRyZWF0IGEgbWlzc2luZyBTU0lEIGFzIGEgbm9uLW1hdGNoLgogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7ICAvLyBBZ2FpbiwgdHJlYXQgbWlzc2luZyBwSWVzIGFzIGEgbm9uLW1hdGNoLgogICAgfQp9Cgp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtSXNOZXdDb25uZWN0ZWRQcm9maWxlKAogICAgICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCBzZXNzaW9uSWQgICA9ICh0QU5JX1U4KXBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQ7CiAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBDdXJyUHJvZmlsZSA9IE5VTEw7CiAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBQcmV2UHJvZmlsZSA9IE5VTEw7CiAgICB0RG90MTFmQmVhY29uSUVzICpwSWVzID0gTlVMTDsKICAgIHRTaXJCc3NEZXNjcmlwdGlvbiAqcEJzc0Rlc2MgPSBOVUxMOwogICAgdEFOSV9CT09MRUFOIGZOZXcgPSBUUlVFOwoKICAgIGlmKCEocE1hYy0+cm9hbS5yb2FtU2Vzc2lvbiAmJiBDU1JfSVNfU0VTU0lPTl9WQUxJRChwTWFjLCBzZXNzaW9uSWQpKSkKICAgIHsKICAgICAgICByZXR1cm4gKGZOZXcpOwogICAgfQoKICAgIHBDdXJyUHJvZmlsZSA9ICZwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZTsKICAgIGlmKCAhcEN1cnJQcm9maWxlICkKICAgIHsKICAgICAgICByZXR1cm4gKGZOZXcpOwp9CgogICAgcFByZXZQcm9maWxlID0gJnBOZWlnaGJvclJvYW1JbmZvLT5wcmV2Q29ublByb2ZpbGU7CiAgICBpZiggIXBQcmV2UHJvZmlsZSApCiAgICB7CiAgICAgICAgcmV0dXJuIChmTmV3KTsKICAgIH0KCiAgICBwQnNzRGVzYyA9IHBQcmV2UHJvZmlsZS0+cEJzc0Rlc2M7CiAgICBpZiAocEJzc0Rlc2MpCiAgICB7CiAgICAgICAgaWYgKEhBTF9TVEFUVVNfU1VDQ0VTUyhjc3JHZXRQYXJzZWRCc3NEZXNjcmlwdGlvbklFcyhwTWFjLAogICAgICAgICAgICBwQnNzRGVzYywgJnBJZXMpKSAmJgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1Jc1NzaWRBbmRTZWN1cml0eU1hdGNoKHBNYWMsIHBDdXJyUHJvZmlsZSwgcEJzc0Rlc2MsIHBJZXMpKQogICAgICAgIHsKICAgICAgICAgICAgZk5ldyA9IEZBTFNFOwogICAgICAgIH0KICAgICAgICBpZiAocEllcykKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwSWVzKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGZOZXcpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJQcmV2IHJvYW0gcHJvZmlsZSBkaWQgbm90IG1hdGNoIGN1cnJlbnQiKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJQcmV2IHJvYW0gcHJvZmlsZSBtYXRjaGVzIGN1cnJlbnQiKSk7CiAgICB9CgogICAgcmV0dXJuIChmTmV3KTsKfQoKdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUNvbm5lY3RlZFByb2ZpbGVNYXRjaCgKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgIHRDc3JTY2FuUmVzdWx0ICpwUmVzdWx0LAogICAgICAgIHREb3QxMWZCZWFjb25JRXMgKnBJZXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCBzZXNzaW9uSWQgICA9ICh0QU5JX1U4KXBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQ7CiAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBDdXJQcm9maWxlID0gTlVMTDsKICAgIHRTaXJCc3NEZXNjcmlwdGlvbiAqcEJzc0Rlc2MgPSAmcFJlc3VsdC0+UmVzdWx0LkJzc0Rlc2NyaXB0b3I7CgogICAgaWYoICEocE1hYy0+cm9hbS5yb2FtU2Vzc2lvbgogICAgICAgICAgICAmJiBDU1JfSVNfU0VTU0lPTl9WQUxJRChwTWFjLCBzZXNzaW9uSWQpKSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcEN1clByb2ZpbGUgPSAmcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGU7CgogICAgaWYoICFwQ3VyUHJvZmlsZSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIGNzck5laWdoYm9yUm9hbUlzU3NpZEFuZFNlY3VyaXR5TWF0Y2gocE1hYywgcEN1clByb2ZpbGUsIHBCc3NEZXNjLCBwSWVzKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByZXBhcmVOb25PY2N1cGllZENoYW5uZWxMaXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gcHJlcGFyZSBhIGNoYW5uZWwgbGlzdCB0aGF0IGlzIGRlcml2ZWQgZnJvbQogICAgICAgICAgICB0aGUgbGlzdCBvZiB2YWxpZCBjaGFubmVscyBhbmQgZG9lcyBub3QgaW5jbHVkZSB0aG9zZSBpbiB0aGUgb2NjdXBpZWQKICAgICAgICAgICAgbGlzdC4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGRlZmF1bHQgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgbnVtT2ZDaGFubmVscyAtIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIGRlZmF1bHQgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgcE91dHB1dENoYW5uZWxMaXN0IC0gVGhlIHBsYWNlIHRvIHB1dCB0aGUgbm9uLW9jY3VwaWVkIGNoYW5uZWwgbGlzdC4KICAgIFxwYXJhbSAgcE91dHB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSBub24tb2NjdXBpZWQgY2hhbm5lbCBsaXN0LgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtUHJlcGFyZU5vbk9jY3VwaWVkQ2hhbm5lbExpc3QoCiAgICAgICAgdHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgdEFOSV9VOCAgICpwSW5wdXRDaGFubmVsTGlzdCwgCiAgICAgICAgdEFOSV9VOCBudW1PZkNoYW5uZWxzLAogICAgICAgIHRBTklfVTggICAqcE91dHB1dENoYW5uZWxMaXN0LAogICAgICAgIHRBTklfVTggKnBPdXRwdXROdW1PZkNoYW5uZWxzCiAgICAgICAgKQp7CiAgICB0QU5JX1U4IGkgPSAwOwogICAgdEFOSV9VOCBvdXRwdXROdW1PZkNoYW5uZWxzICA9IDA7IC8vIENsZWFyIHRoZSBvdXRwdXQgbnVtYmVyIG9mIGNoYW5uZWxzCiAgICB0QU5JX1U4IG51bU9jY3VwaWVkQ2hhbm5lbHMgPSBwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHMubnVtQ2hhbm5lbHM7CiAgICB0QU5JX1U4ICpwT2NjdXBpZWRDaGFubmVsTGlzdCA9IHBNYWMtPnNjYW4ub2NjdXBpZWRDaGFubmVscy5jaGFubmVsTGlzdDsKCiAgICBmb3IgKGkgPSAwOyAoaSA8IG51bU9mQ2hhbm5lbHMgJiYoaSA8IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikpOyBpKyspCiAgICB7CiAgICAgICAgaWYgKCFjc3JJc0NoYW5uZWxQcmVzZW50SW5MaXN0KHBPY2N1cGllZENoYW5uZWxMaXN0LCBudW1PY2N1cGllZENoYW5uZWxzLAogICAgICAgICAgICAgcElucHV0Q2hhbm5lbExpc3RbaV0pKQogICAgICAgIHsKICAgICAgICAgICAvKiBERlMgY2hhbm5lbCB3aWxsIGJlIGFkZGVkIGluIHRoZSBsaXN0IG9ubHkgd2hlbiB0aGUKICAgICAgICAgICAgICBERlMgUm9hbWluZyBzY2FuIGZsYWcgaXMgZW5hYmxlZCovCiAgICAgICAgICAgIGlmIChDU1JfSVNfQ0hBTk5FTF9ERlMocElucHV0Q2hhbm5lbExpc3RbaV0pKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5hbGxvd0RGU0NoYW5uZWxSb2FtID09IFRSVUUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcE91dHB1dENoYW5uZWxMaXN0W291dHB1dE51bU9mQ2hhbm5lbHMrK10gPSBwSW5wdXRDaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHBPdXRwdXRDaGFubmVsTGlzdFtvdXRwdXROdW1PZkNoYW5uZWxzKytdID0gcElucHV0Q2hhbm5lbExpc3RbaV07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgc21zTG9nKHBNYWMsIExPRzIsIEZMKCJOdW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIHZhbGlkIGNoYW5uZWwgbGlzdD0lZDsgIgogICAgICAgICAgICJOdW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIG5vbi1vY2N1cGllZCBsaXN0IGxpc3Q9JWQiKSwKICAgICAgICAgICAgbnVtT2ZDaGFubmVscywgb3V0cHV0TnVtT2ZDaGFubmVscyk7CgogICAgLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMKICAgICpwT3V0cHV0TnVtT2ZDaGFubmVscyA9IG91dHB1dE51bU9mQ2hhbm5lbHM7IAoKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CiNlbmRpZiAvKiBGRUFUVVJFX1dMQU5fTEZSICovCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW5ldmVyIHRoZXJlIGlzIGEgdHJhbnNpdGlvbiB0byBDRkcgY2hhbiBzY2FuIAogICAgICAgICAgICBzdGF0ZSBmcm9tIGFueSBzdGF0ZS4gSXQgZnJlZXMgdXAgdGhlIGN1cnJlbnQgY2hhbm5lbCBsaXN0IGFuZCBhbGxvY2F0ZXMgCiAgICAgICAgICAgIGEgbmV3IG1lbW9yeSBmb3IgdGhlIGNoYW5uZWxzIHJlY2VpdmVkIGZyb20gQ0ZHIGl0ZW0uIEl0IHRoZW4gc3RhcnRzIHRoZSAKICAgICAgICAgICAgbmVpZ2hib3Igc2NhbiB0aW1lciB0byBwZXJmb3JtIHRoZSBzY2FuIG9uIGVhY2ggY2hhbm5lbCBvbmUgYnkgb25lCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzICBzdGF0dXMgID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIGludCBpID0gMDsKICAgIHRBTklfVTggICBudW1PZkNoYW5uZWxzID0gMDsKICAgIHRBTklfVTggICBjaGFubmVsTGlzdFtXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU5dOwogICAgdHBDc3JDaGFubmVsSW5mbyAgICBjdXJyQ2hhbm5lbExpc3RJbmZvOwogICAgdEFOSV9VOCAgIHNjYW5DaGFubmVsTGlzdFtXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU5dOwogICAgaW50ICAgICAgIG91dHB1dE51bU9mQ2hhbm5lbHMgPSAwOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgdEFOSV9VMzIgc2Vzc2lvbklkID0gcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZDsKI2VuZGlmCiAgICBjdXJyQ2hhbm5lbExpc3RJbmZvID0gJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mbzsKCiAgICBpZiAoIAojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgICgocE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpICYmCiAgICAgICAgICAgICAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID09IGVBTklfQk9PTEVBTl9GQUxTRSkpIHx8CiAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jID09IGVBTklfQk9PTEVBTl9GQUxTRSkgfHwKI2VuZGlmIC8vIEVTRQogICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPT0gMCkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIkJ1aWxkaW5nIGNoYW5uZWwgbGlzdCB0byBzY2FuIikpOwoKCiAgICAgICAgLyogRnJlZSB1cCB0aGUgY2hhbm5lbCBsaXN0IGFuZCBhbGxvY2F0ZSBhIG5ldyBtZW1vcnkuIFRoaXMgaXMgYmVjYXVzZSB3ZSBkb250IGtub3cgaG93IG11Y2ggCiAgICAgICAgICAgIHdhcyBhbGxvY2F0ZWQgbGFzdCB0aW1lLiBJZiB3ZSBkaXJlY3RseSBjb3B5IG1vcmUgbnVtYmVyIG9mIGJ5dGVzIHRoYW4gYWxsb2NhdGVkIGVhcmxpZXIsIHRoaXMgbWlnaHQgCiAgICAgICAgICAgIHJlc3VsdCBpbiBtZW1vcnkgY29ycnVwdGlvbiAqLwogICAgICAgIGlmIChOVUxMICE9IGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICB9CgogICAgICAgIC8vIE5vdyBvYnRhaW4gdGhlIGNvbnRlbnRzIGZvciAiY2hhbm5lbExpc3QiICh0aGUgImRlZmF1bHQgdmFsaWQgY2hhbm5lbCBsaXN0IikgZnJvbSBFSVRIRVIKICAgICAgICAvLyB0aGUgZ05laWdoYm9yU2NhbkNoYW5uZWxMaXN0IGluICJjZmcuaW5pIiwgT1IgdGhlIGFjdHVhbCAidmFsaWQgY2hhbm5lbCBsaXN0IiBpbmZvcm1hdGlvbiBmb3JtZWQgYnkgQ1NSLgogICAgICAgIGlmICgwICE9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgICAgICB7CiAgICAgICAgICAgIC8vIENvcHkgdGhlICJkZWZhdWx0IHZhbGlkIGNoYW5uZWwgbGlzdCIgKGNoYW5uZWxMaXN0KSBmcm9tIHRoZSBnTmVpZ2hib3JTY2FuQ2hhbm5lbExpc3QgaW4gImNmZy5pbmkiLgogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsICJVc2luZyB0aGUgY2hhbm5lbCBsaXN0IGZyb20gY2ZnLmluaSIpOwogICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1NZXJnZUNoYW5uZWxMaXN0cyggCiAgICAgICAgICAgICAgICAgICAgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzLCAKICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICAgICAgMCwgLy9OQjogSWYgMCwgc2ltcGx5IGNvcHkgdGhlIGlucHV0IGNoYW5uZWwgbGlzdCB0byB0aGUgb3V0cHV0IGxpc3QuCiAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMgKTsKCiAgICAgICAgICAgIGlmIChDU1JfSVNfUk9BTV9JTlRSQV9CQU5EX0VOQUJMRUQocE1hYykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUNoYW5uZWxzRmlsdGVyQnlCYW5kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0UkZCYW5kKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYobnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCB3cm9uZyBudW1iZXIgb2YgQ2hhbm5lbCBsaXN0IikpOwogICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBSZW1vdmUgdGhlIERGUyBjaGFubmVscyBmcm9tIENGRyBjaGFubmVsIGxpc3Qgd2hlbiAnCiAgICAgICAgICAgICAgICAgICAgICAgIGdBbGxvd1JvYW1Ub0RGUyBpcyBkaXNhYmxlZCAqLwogICAgICAgICAgICBpZiAoIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uYWxsb3dERlNDaGFubmVsUm9hbSA9PSBGQUxTRSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpPTA7IGk8bnVtT2ZDaGFubmVsczsgaSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICggIShDU1JfSVNfQ0hBTk5FTF9ERlMoY2hhbm5lbExpc3RbaV0pKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuQ2hhbm5lbExpc3Rbb3V0cHV0TnVtT2ZDaGFubmVscysrXSA9IGNoYW5uZWxMaXN0W2ldOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsgICAvKiBNb3ZlIGFsbCB0aGUgY2hhbm5lbHMgdG8gcm9hbSBzY2FuIGNoYW5uZWwgbGlzdCAqLwogICAgICAgICAgICAgICAgdm9zX21lbV9jb3B5KHNjYW5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgICAgICAgICAgIG91dHB1dE51bU9mQ2hhbm5lbHMgPSBudW1PZkNoYW5uZWxzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAob3V0cHV0TnVtT2ZDaGFubmVscyA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5vIGNoYW5uZWxzIHRvIHNjYW4iKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QgPQogICAgICAgICAgICAgICAgdm9zX21lbV9tYWxsb2Mob3V0cHV0TnVtT2ZDaGFubmVscypzaXplb2YodEFOSV9VOCkpOwogICAgICAgICAgICBpZiAoTlVMTCA9PSBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgQ2hhbm5lbCBsaXN0IGZhaWxlZCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPSBvdXRwdXROdW1PZkNoYW5uZWxzOwogICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgIHNjYW5DaGFubmVsTGlzdCwgb3V0cHV0TnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgfSAKCgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIGVsc2UgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID09IERFRkFVTFRfU0NBTikgJiYKICAgICAgICAgICAgICAgICAoYWJzKHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSkgPgogICAgICAgICAgICAgICAgICBhYnMocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQpKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIAogICAgICAgICAgICAgKiBUcmlnZ2VyIGEgY29udGlndW91cyBzY2FuIG9uIGFsbCBjaGFubmVscyB3aGVuIHRoZQogICAgICAgICAgICAgKiBSU1NJIGluIHRoZSBsb29rdXAgRE9XTiBub3RpZmljYXRpb24gaXMgYmVsb3cgcmVhc3NvYyAKICAgICAgICAgICAgICogdGhyZXNob2xkLiBUaGlzIHdpbGwgaGVscCB1cyBmaW5kIHRoZSBiZXN0IGF2YWlsYWJsZSAKICAgICAgICAgICAgICogY2FuZGlkYXRlIGFuZCBhbHNvIHVwZGF0ZSB0aGUgY2hhbm5lbCBjYWNoZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIlRyaWdnZXJpbmcgY29udGlndW91cyBzY2FuICIKICAgICAgICAgICAgICAgICIobG9va3VwRE9XTlJzc2k9JWQscmVhc3NvY1RocmVzaG9sZD0lZCkiLAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpLAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQqKC0xKSk7CgogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJlcXVlc3RUaW1lU3RhbXAgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b3NfdGltZXJfZ2V0X3N5c3RlbV90aW1lKCk7CgogICAgICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKCiAgICAgICAgICAgIC8qIFdlIGFyZSBhYm91dCB0byBzdGFydCBhIGZyZXNoIHNjYW4gY3ljbGUsIAogICAgICAgICAgICAgKiBwdXJnZSBub24tUDJQIHJlc3VsdHMgZnJvbSB0aGUgcGFzdCAqLwogICAgICAgICAgICBjc3JTY2FuRmx1c2hTZWxlY3RpdmVSZXN1bHQocE1hYywgVk9TX0ZBTFNFKTsKCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVBlcmZvcm1Db250aWd1b3VzQmdTY2FuKHBNYWMsIHNlc3Npb25JZCk7CgogICAgICAgICAgICAvKiBUcmFuc2l0aW9uIHRvIENGR19DSEFOX0xJU1RfU0NBTiAqLwogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU4pOwoKICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgICAgICB9CiNlbmRpZgogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgPSBwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHMubnVtQ2hhbm5lbHM7CiAgICAgICAgICAgIGlmIChudW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzID0gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChudW1PZkNoYW5uZWxzCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAmJiAoKHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPT0gU1BMSVRfU0NBTl9PQ0NVUElFRF9MSVNUKSB8fAogICAgICAgICAgICAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IDApIHx8CiAgICAgICAgICAgICAgICAgICAgKChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ICUgMikgPT0gMSkpCiNlbmRpZgogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogQWx3YXlzIHNjYW4gY2hhbm5lbHMgaW4gdGhlIG9jY3VwaWVkIGNoYW5uZWwgbGlzdAogICAgICAgICAgICAgICAgICogYmVmb3JlIHNjYW5uaW5nIG9uIHRoZSBub24tb2NjdXBpZWQgbGlzdC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCAiU3dpdGNoaW5nIHRvIG9jY3VwaWVkIGNoYW5uZWwgbGlzdCIKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgICAgICAgICAiLXVTY2FuTW9kZT0lZCwgdUVtcHR5U2NhbkNvdW50PSVkIiwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQKI2VuZGlmCiAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIGlmIChDU1JfSVNfUk9BTV9JTlRSQV9CQU5EX0VOQUJMRUQocE1hYykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUJhbmQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnNjYW4ub2NjdXBpZWRDaGFubmVscy5jaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRSRkJhbmQocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmN1cnJBUG9wZXJhdGlvbkNoYW5uZWwpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2b3NfbWVtX2NvcHkoY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHMuY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIFJlbW92ZSB0aGUgREZTIGNoYW5uZWxzIGZyb20gQ0ZHIGNoYW5uZWwgbGlzdCB3aGVuICcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ0FsbG93Um9hbVRvREZTIGlzIGRpc2FibGVkICovCiAgICAgICAgICAgICAgICBpZiAoIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uYWxsb3dERlNDaGFubmVsUm9hbSA9PSBGQUxTRSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIGZvciAoaT0wOyBpPG51bU9mQ2hhbm5lbHM7IGkrKykKICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICBpZiAoICEoQ1NSX0lTX0NIQU5ORUxfREZTKGNoYW5uZWxMaXN0W2ldKSkpCiAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbkNoYW5uZWxMaXN0W291dHB1dE51bU9mQ2hhbm5lbHMrK10gPSBjaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9jb3B5KHNjYW5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgICAgICAgICAgICAgb3V0cHV0TnVtT2ZDaGFubmVscyA9IG51bU9mQ2hhbm5lbHM7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKG91dHB1dE51bU9mQ2hhbm5lbHMgPT0gMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5vIGNoYW5uZWxzIHRvIHNjYW4iKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QgPSB2b3NfbWVtX21hbGxvYyhvdXRwdXROdW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgICAgICAgICAgIGlmIChOVUxMID09IGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZm9yIENoYW5uZWwgbGlzdCBmYWlsZWQiKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9SRVNPVVJDRVM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzID0gb3V0cHV0TnVtT2ZDaGFubmVsczsKICAgICAgICAgICAgICAgIHZvc19tZW1fY29weShjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgc2NhbkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXROdW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIFNjYW4gYWxsIGNoYW5uZWxzIGZyb20gbm9uLW9jY3VwaWVkIGxpc3QgKi8KICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIkdldCB2YWxpZCBjaGFubmVsIGxpc3QiKTsKICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgPSBzaXplb2YocE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0KTsKCiAgICAgICAgICAgICAgICBpZihIQUxfU1RBVFVTX1NVQ0NFU1MoY3NyR2V0Q2ZnVmFsaWRDaGFubmVscyhwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1U4ICopcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1UzMiAqKSAmbnVtT2ZDaGFubmVscykpKQogICAgICAgICAgICB7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogUHJlcGFyZSBub24tb2NjdXBpZWQgY2hhbm5lbCBsaXN0IChjaGFubmVsTGlzdCkKICAgICAgICAgICAgICAgICAqIGZyb20gdGhlIGFjdHVhbCAidmFsaWQgY2hhbm5lbCBsaXN0IiBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICogZm9ybWVkIGJ5IENTUi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCAiU3dpdGNoaW5nIHRvIG5vbi1vY2N1cGllZCBjaGFubmVsIGxpc3QiKTsKICAgICAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByZXBhcmVOb25PY2N1cGllZENoYW5uZWxMaXN0KHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VOCAqKXBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzKTsKI2Vsc2UKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIk1lcmdpbmcgY2hhbm5lbCBsaXN0Iik7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1NZXJnZUNoYW5uZWxMaXN0cyggCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzLCAgIC8vIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIHZhbGlkQ2hhbm5lbExpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLy9OQjogSWYgMCwgc2ltcGx5IGNvcHkgdGhlIGlucHV0IGNoYW5uZWwgbGlzdCB0byB0aGUgb3V0cHV0IGxpc3QuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscyApOyAvLyBUaGUgZmluYWwgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSBvdXRwdXQgbGlzdC4gV2lsbCBiZSBudW1PZkNoYW5uZWxzCiNlbmRpZgogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDb3VsZCBub3QgZ2V0IHZhbGlkIGNoYW5uZWwgbGlzdCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKENTUl9JU19ST0FNX0lOVFJBX0JBTkRfRU5BQkxFRChwTWFjKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUNoYW5uZWxzRmlsdGVyQnlCYW5kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFJGQmFuZChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY3VyckFQb3BlcmF0aW9uQ2hhbm5lbCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAobnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyA9IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG51bU9mQ2hhbm5lbHMgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJObyBjaGFubmVscyB0byBzY2FuIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0KICAgICAgICAgICAgICAgIHZvc19tZW1fbWFsbG9jKG51bU9mQ2hhbm5lbHMqc2l6ZW9mKHRBTklfVTgpKTsKCiAgICAgICAgICAgIGlmIChOVUxMID09IGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZvciBDaGFubmVsIGxpc3QgZmFpbGVkIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9SRVNPVVJDRVM7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVscyA9IG51bU9mQ2hhbm5lbHM7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIHZvc19tZW1fY29weShjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwgbnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiNlbHNlCiAgICAgICAgICAgIHZvc19tZW1fY29weShjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAodEFOSV9VOCAqKXBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKI2VuZGlmCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgCiAgICAgICAgICAgICJOdW1iZXIgb2YgY2hhbm5lbHMgZnJvbSBDRkcgKG9yKSAobm9uLSlvY2N1cGllZCBsaXN0PSVkIiwKICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVscyk7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHM7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIkNoYW5uZWwgTGlzdCBmcm9tIENGRyAob3IpIChub24tKW9jY3VwaWVkIGxpc3QiCiAgICAgICAgICAgICAgICAgICAgIj0gJWQiLCBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdFtpXSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFdlIGFyZSBnb25uYSBzY2FuIG5vdy4gUmVtZW1iZXIgdGhlIHRpbWUgc3RhbXAgdG8gZmlsdGVyIG91dCByZXN1bHRzIG9ubHkgYWZ0ZXIgdGhpcyB0aW1lc3RhbXAgKi8KICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA9IHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKICAgIAogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAvKiBTdGFydCBOZWlnaGJvciBzY2FuIHRpbWVyIG5vdy4gTXVsdGlwbGljYXRpb24gYnkgUEFMX1RJTUVSX1RPX01TX1VOSVQgaXMgdG8gY29udmVydCBtcyB0byB1cyB3aGljaCBpcyAKICAgICAgICAgICAgd2hhdCBwYWxUaW1lclN0YXJ0IGV4cGVjdHMgKi8KICAgIHN0YXR1cyA9IHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kKTsKICAgIAogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIC8qIFRpbWVyIHN0YXJ0IGZhaWxlZC4uICAqLwogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBQQUwgVGltZXIgc3RhcnQgZmFpbGVkLCBzdGF0dXMgPSAlZCwgSWdub3Jpbmcgc3RhdGUgdHJhbnNpdGlvbiIpLCBzdGF0dXMpOwogICAgICAgIHZvc19tZW1fZnJlZShjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCk7CiAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIAogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgLyogV2UgYXJlIGFib3V0IHRvIHN0YXJ0IGEgZnJlc2ggc2NhbiBjeWNsZSwgCiAgICAgKiBwdXJnZSBub24tUDJQIHJlc3VsdHMgZnJvbSB0aGUgcGFzdCAqLwogICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0KHBNYWMsIFZPU19GQUxTRSk7CgogICAgLyogV2UgYXJlIGFib3V0IHRvIHN0YXJ0IGEgZnJlc2ggc2NhbiBjeWNsZSwKICAgICAqIHB1cmdlIGZhaWxlZCBwcmUtYXV0aCByZXN1bHRzIGZyb20gdGhlIHBhc3QgKi8KICAgIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxlZExpc3QocE1hYyk7CiAgICAKICAgIC8qIFRyYW5zaXRpb24gdG8gQ0ZHX0NIQU5fTElTVF9TQ0FOX1NUQVRFICovCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU4pCgogICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVXBFdmVudAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYXMgc29vbiBhcyBUTCBpbmRpY2F0ZXMgdGhhdCB0aGUgY3VycmVudCBBUCdzIAogICAgICAgICAgICBSU1NJIGlzIGJldHRlciB0aGFuIHRoZSBuZWlnaGJvciBsb29rdXAgdGhyZXNob2xkLiBIZXJlLCB3ZSB0cmFuc2l0aW9uIHRvIAogICAgICAgICAgICBDT05ORUNURUQgc3RhdGUgYW5kIHJlc2V0IGFsbCB0aGUgc2NhbiBwYXJhbWV0ZXJzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVXBFdmVudCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1czsKICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CgogICAgLyogUmVjaGVjayB3aGV0aGVyIHRoZSBiZWxvdyBjaGVjayBpcyBuZWVkZWQuICovCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSAhPSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEKQogICAgICAgICYmIChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFQVNTT0NJQVRJTkcpKQogICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCkKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIGlmICghY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMscE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNzclNlc3Npb25JZCkpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCB3aGVuIGZhc3Qgcm9hbSBpcyBkaXNhYmxlZC4gSWdub3JlIGl0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQojZW5kaWYKICAgIC8qIFJlc2V0IGFsbCB0aGUgbmVpZ2hib3Igcm9hbSBpbmZvIGNvbnRyb2wgdmFyaWFibGVzLiBGcmVlIGFsbCB0aGUgYWxsb2NhdGVkIG1lbW9yeS4gSXQgaXMgbGlrZSB3ZSBhcmUganVzdCBhc3NvY2lhdGVkIG5vdyAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwoKICAgIAogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgRE9XTiBldmVudCBuZWlnaGJvciBsb29rdXAgY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkLCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSk7CiAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIERPV04gZXZlbnQgbm93ICovCiAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiNlbmRpZgogICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgewogICAgICAgLy9lcnIgbXNnCiAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCByZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cENhbGxiYWNrIERPV04gZXZlbnQgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgIH0KCgogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRG93bkV2ZW50CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhcyBzb29uIGFzIFRMIGluZGljYXRlcyB0aGF0IHRoZSBjdXJyZW50IEFQJ3MgCiAgICAgICAgICAgIFJTU0kgZmFsbHMgYmVsb3cgdGhlIGN1cnJlbnQgZWlnaGJvciBsb29rdXAgdGhyZXNob2xkLiBIZXJlLCB3ZSB0cmFuc2l0aW9uIHRvIAogICAgICAgICAgICBSRVBPUlRfUVVFUlkgZm9yIDExciBhc3NvY2lhdGlvbiBhbmQgQ0ZHX0NIQU5fTElTVF9TQ0FOIHN0YXRlIGlmIHRoZSBhc3NvYyBpcyAKICAgICAgICAgICAgYSBub24tMTFSIGFzc29jaWF0aW9uLgoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERvd25FdmVudCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIGVIYWxTdGF0dXMgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CgogICAgc3dpdGNoIChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEOgogICAgICAgICAgICAKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiRGVyZWdpc3RlcmluZyBET1dOIGV2ZW50IG5laWdoYm9yIGxvb2t1cCBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQsIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpKTsKICAgICAgICAgICAgLyogRGUtcmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMICovCiAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IERlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBDYWxsYmFjayBET1dOIGV2ZW50IGZyb20gVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgIH0KI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgaWYgKCFjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYyxwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY3NyU2Vzc2lvbklkKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCB3aGVuIGZhc3Qgcm9hbSBpcyBkaXNhYmxlZC4gSWdub3JlIGl0IikpOwogICAgICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgCiNpZiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICYmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSQogICAgICAgICAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKSAmJiAocE1hYy0+cnJtLnJybVNtZUNvbnRleHQucnJtQ29uZmlnLnJybUVuYWJsZWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiMTFSIEFzc29jaWF0aW9uOk5laWdoYm9yIExvb2t1cCBEb3duIGV2ZW50IHJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZSIpKTsKICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHBNYWMpOwogICAgICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVxdWVzdCBmYWlsZWQuIHN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZvc1N0YXR1czsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIEluY3JlbWVudCB0aGUgbmVpZ2hib3IgcmVwb3J0IHJldHJ5IGNvdW50IGFmdGVyIHNlbmRpbmcgdGhlIG5laWdoYm9yIHJlcXVlc3Qgc3VjY2Vzc2Z1bGx5ICovCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSsrOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfUVVFUlkpCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQojZW5kaWYgICAgICAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiTm9uIDExUiBvciBFU0UgQXNzb2NpYXRpb246TmVpZ2hib3IgTG9va3VwIERvd24gZXZlbnQgcmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlIikpOwoKICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4gZmFpbGVkIgogICAgICAgICAgICAgICAgICAgICAgICAiIHdpdGggc3RhdHVzPSVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZvc1N0YXR1czsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJSZWdpc3RlcmluZyBVUCBldmVudCBuZWlnaGJvciBsb29rdXAgY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkLCIpLCBORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpKTsKICAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBVUCBldmVudCBub3cgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiAgICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBDYWxsYmFjayBVUCBldmVudCB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRE9XTiBldmVudCByZWNlaXZlZCBpbiBpbnZhbGlkIgogICAgICAgICAgICAgICAgICAgInN0YXRlICVzIC4uSWdub3JpbmcuLi4iKSwKICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgcmVnaXN0ZXJlZCB3aXRoIFRMIHRvIGluZGljYXRlIHdoZW5ldmVyIHRoZSBSU1NJIAogICAgICAgICAgICBnZXRzIGJldHRlciB0aGFuIHRoZSBuZWlnaGJvckxvb2t1cCBSU1NJIFRocmVzaG9sZAoKICAgIFxwYXJhbSAgcEFkYXB0ZXIgLSBWT1MgQ29udGV4dAogICAgICAgICAgICB0cmFmZmljU3RhdHVzIC0gVVAvRE9XTiBpbmRpY2F0aW9uIGZyb20gVEwKICAgICAgICAgICAgcFVzZXJDdHh0IC0gUGFyYW1ldGVyIGZvciBjYWxsYmFjayByZWdpc3RlcmVkIGR1cmluZyBjYWxsYmFjayByZWdpc3RyYXRpb24uIFNob3VsZCBiZSBwTWFjCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2sgKHZfUFZPSURfdCBwQWRhcHRlciwgdl9VOF90IHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1BWT0lEX3QgcFVzZXJDdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9TN190IGF2Z1Jzc2kpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVCggcFVzZXJDdHh0ICk7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiTmVpZ2hib3IgTG9va3VwIFVQIGluZGljYXRpb24gY2FsbGJhY2sgY2FsbGVkIHdpdGggbm90aWZpY2F0aW9uICVkIFJlcG9ydGVkIFJTU0kgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByc3NpTm90aWZpY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmdSc3NpKTsKCiAgICBpZighY3NySXNDb25uU3RhdGVDb25uZWN0ZWRJbmZyYShwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkKSkKICAgIHsKICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCAiSWdub3JpbmcgdGhlIGluZGljYXRpb24gYXMgd2UgYXJlIG5vdCBjb25uZWN0ZWQiKTsKICAgICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgVk9TX0FTU0VSVChXTEFOVExfSE9fVEhSRVNIT0xEX1VQID09IHJzc2lOb3RpZmljYXRpb24pOwogICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVcEV2ZW50KHBNYWMpOwogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHJlZ2lzdGVyZWQgd2l0aCBUTCB0byBpbmRpY2F0ZSB3aGVuZXZlciB0aGUgUlNTSSAKICAgICAgICAgICAgZmFsbHMgYmVsb3cgdGhlIGN1cnJlbnQgbmVpZ2hib3JMb29rdXAgUlNTSSBUaHJlc2hvbGQKCiAgICBccGFyYW0gIHBBZGFwdGVyIC0gVk9TIENvbnRleHQKICAgICAgICAgICAgdHJhZmZpY1N0YXR1cyAtIFVQL0RPV04gaW5kaWNhdGlvbiBmcm9tIFRMCiAgICAgICAgICAgIHBVc2VyQ3R4dCAtIFBhcmFtZXRlciBmb3IgY2FsbGJhY2sgcmVnaXN0ZXJlZCBkdXJpbmcgY2FsbGJhY2sgcmVnaXN0cmF0aW9uLiBTaG91bGQgYmUgcE1hYwoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgKHZfUFZPSURfdCBwQWRhcHRlciwgdl9VOF90IHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1BWT0lEX3QgcFVzZXJDdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9TN190IGF2Z1Jzc2kpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVCggcFVzZXJDdHh0ICk7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiTmVpZ2hib3IgTG9va3VwIERPV04gaW5kaWNhdGlvbiBjYWxsYmFjayBjYWxsZWQgd2l0aCBub3RpZmljYXRpb24gJWQgUmVwb3J0ZWQgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByc3NpTm90aWZpY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZnUnNzaSk7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpID0gYXZnUnNzaTsKI2VuZGlmCiAgICBpZighY3NySXNDb25uU3RhdGVDb25uZWN0ZWRJbmZyYShwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkKSkKICAgIHsKICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCAiSWdub3JpbmcgdGhlIGluZGljYXRpb24gYXMgd2UgYXJlIG5vdCBjb25uZWN0ZWQiKTsKICAgICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgVk9TX0FTU0VSVChXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04gPT0gcnNzaU5vdGlmaWNhdGlvbik7CiAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERvd25FdmVudChwTWFjKTsKCiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgojaWZkZWYgUlNTSV9IQUNLCmV4dGVybiBpbnQgZHVtcENtZFJTU0k7CiNlbmRpZgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUluZGljYXRlRGlzY29ubmVjdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgQ1NSIGFzIHNvb24gYXMgdGhlIHN0YXRpb24gZGlzY29ubmVjdHMgZnJvbSAKICAgICAgICAgICAgdGhlIEFQLiBUaGlzIGZ1bmN0aW9uIGRvZXMgdGhlIG5lY2Vzc2FyeSBjbGVhbnVwIG9mIG5laWdoYm9yIHJvYW0gZGF0YSAKICAgICAgICAgICAgc3RydWN0dXJlcy4gTmVpZ2hib3Igcm9hbSBzdGF0ZSB0cmFuc2l0aW9ucyB0byBJTklUIHN0YXRlIHdoZW5ldmVyIHRoaXMgCiAgICAgICAgICAgIGZ1bmN0aW9uIGlzIGNhbGxlZCBleGNlcHQgaWYgdGhlIGN1cnJlbnQgc3RhdGUgaXMgUkVBU1NPQ0lBVElORwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgc2Vzc2lvbklkIC0gQ1NSIHNlc3Npb24gaWQgdGhhdCBnb3QgZGlzY29ubmVjdGVkCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSW5kaWNhdGVEaXNjb25uZWN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRBTklfVTggc2Vzc2lvbklkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHRDc3JSb2FtQ29ubmVjdGVkUHJvZmlsZSAqcFByZXZQcm9maWxlID0gJnBOZWlnaGJvclJvYW1JbmZvLT5wcmV2Q29ublByb2ZpbGU7CiNlbmRpZgogICAgdENzclJvYW1TZXNzaW9uICpwU2Vzc2lvbiA9IENTUl9HRVRfU0VTU0lPTiggcE1hYywgc2Vzc2lvbklkKTsKCiAgICBpZiAoTlVMTCA9PSBwU2Vzc2lvbikKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoInBTZXNzaW9uIGlzIE5VTEwgIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgVk9TX1RSQUNFKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgIEZMKCJEaXNjb25uZWN0IGluZGljYXRpb24gb24gc2Vzc2lvbiAlZCBpbiBzdGF0ZSAlcyIKICAgICAgICAgICAgICAgICAgICAgICJmcm9tIEJTU0lEIDogIgogICAgICAgICAgICAgICAgICAgTUFDX0FERFJFU1NfU1RSKSwgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpLAogICAgICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkocFNlc3Npb24tPmNvbm5lY3RlZFByb2ZpbGUuYnNzaWQpKTsKIAojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgLypGcmVlIHRoZSBjdXJyZW50IHByZXZpb3VzIHByb2ZpbGUgYW5kIG1vdmUgdGhlIGN1cnJlbnQgcHJvZmlsZSB0byBwcmV2IHByb2ZpbGUuKi8KICAgIGNzclJvYW1GcmVlQ29ubmVjdFByb2ZpbGUocE1hYywgcFByZXZQcm9maWxlKTsKICAgIGNzclJvYW1Db3B5Q29ubmVjdFByb2ZpbGUocE1hYywgc2Vzc2lvbklkLCBwUHJldlByb2ZpbGUpOwojZW5kaWYKICAgIGlmIChOVUxMICE9IHBTZXNzaW9uKQogICAgewogICAgICAgIGlmIChOVUxMICE9IHBTZXNzaW9uLT5wQ3VyUm9hbVByb2ZpbGUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoVk9TX1NUQV9NT0RFICE9IHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5wQ3VyUm9hbVByb2ZpbGUtPmNzclBlcnNvbmEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSWdub3JpbmcgRGlzY29ubmVjdCBpbmRpY2F0aW9uIHJlY2VpdmVkIGZyb20gYSBub24gU1RBIHBlcnNvbmEuIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXNzaW9uSWQ6ICVkLCBjc3JQZXJzb25uYSAlZCIpLCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgKGludClwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0ucEN1clJvYW1Qcm9maWxlLT5jc3JQZXJzb25hKTsKICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgICAgICB9CiAgICAgICAgfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgICAgICBpZiAocFNlc3Npb24tPmNvbm5lY3RlZFByb2ZpbGUuaXNFU0VBc3NvYykKICAgICAgICB7CiAgICAgICAgICAgdm9zX21lbV9jb3B5KCZwU2Vzc2lvbi0+cHJldkFwU1NJRCwgJnBTZXNzaW9uLT5jb25uZWN0ZWRQcm9maWxlLlNTSUQsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0U2lyTWFjU1NpZCkpOwogICAgICAgICAgIHZvc19tZW1fY29weShwU2Vzc2lvbi0+cHJldkFwQnNzaWQsIHBTZXNzaW9uLT5jb25uZWN0ZWRQcm9maWxlLmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICAgICBwU2Vzc2lvbi0+cHJldk9wQ2hhbm5lbCA9IHBTZXNzaW9uLT5jb25uZWN0ZWRQcm9maWxlLm9wZXJhdGlvbkNoYW5uZWw7CiAgICAgICAgICAgcFNlc3Npb24tPmlzUHJldkFwSW5mb1ZhbGlkID0gVFJVRTsKICAgICAgICAgICBwU2Vzc2lvbi0+cm9hbVRTMSA9IHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKICAgICAgICB9CiNlbmRpZgogICAgfSAvL2lmIChOVUxMICE9IHBTZXNzaW9uKQogICAKI2lmZGVmIFJTU0lfSEFDSwogICAgZHVtcENtZFJTU0kgPSAtNDA7CiNlbmRpZgogICAgc3dpdGNoIChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORzoKICAgICAgICAgICAgLy8gU3RvcCBzY2FuIGFuZCBuZWlnaGJvciByZWZyZXNoIHRpbWVycy4KICAgICAgICAgICAgLy8gVGhlc2UgYXJlIGluZGVlZCBub3QgcmVxdWlyZWQgd2hlbiB3ZSBhcmUgaW4gcmVhc3NvY2lhdGluZwogICAgICAgICAgICAvLyBzdGF0ZS4KICAgICAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgICAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwogICAgICAgICAgICBpZiAoIUNTUl9JU19ST0FNX1NVQlNUQVRFX0RJU0FTU09DX0hPKCBwTWFjLCBzZXNzaW9uSWQgKSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIERpc2Nvbm5lY3QgaW5kaWNhdGlvbiBkdXJpbmcgRGlzYXNzb2MgSGFuZG9mZiBzdWItc3RhdGUKICAgICAgICAgICAgICAgICAqIGlzIHJlY2VpdmVkIHdoZW4gd2UgYXJlIHRyeWluZyB0byBkaXNjb25uZWN0IHdpdGggdGhlIG9sZAogICAgICAgICAgICAgICAgICogQVAgZHVyaW5nIHJvYW0uIEJVVCwgaWYgcmVjZWl2ZSBhIGRpc2Nvbm5lY3QgaW5kaWNhdGlvbiAKICAgICAgICAgICAgICAgICAqIG91dHNpZGUgb2YgRGlzYXNzb2MgSGFuZG9mZiBzdWItc3RhdGUsIHRoZW4gaXQgbWVhbnMgdGhhdCAKICAgICAgICAgICAgICAgICAqIHRoaXMgaXMgYSBnZW51aW5lIGRpc2Nvbm5lY3QgYW5kIHdlIG5lZWQgdG8gY2xlYW4gdXAuCiAgICAgICAgICAgICAgICAgKiBPdGhlcndpc2UsIHdlIHdpbGwgYmUgc3R1Y2sgaW4gcmVhc3NvYyBzdGF0ZSB3aGljaCB3aWxsCiAgICAgICAgICAgICAgICAgKiBpbi10dXJuIGJsb2NrIHNjYW5zIChzZWUgY3NySXNTY2FuQWxsb3dlZCkuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKI2VuZGlmCgogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUOgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXNldEluaXRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmICghY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgewojZW5kaWYKICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIGJyZWFrOyAKCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEOgogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmICghY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgewojZW5kaWYKICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCgojaWZkZWYgV0xBTl9GRUFUVVJFX0xGUl9NQkIKICAgICAgICAgICAgY3NyX3N0b3BfcHJlYXV0aF9yZWFzc29jX21iYl90aW1lcihwTWFjKTsKI2VuZGlmCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU46CiAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDZmdMaXN0Q2hhblNjYW5Db250cm9sSW5mbyhwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICAgICAgICAgIGlmICghY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgewojZW5kaWYKICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkU6CiAgICAgICAgICAgIC8qIFN0b3AgcHJlLWF1dGggdG8gcmVhc3NvYyBpbnRlcnZhbCB0aW1lciAqLwogICAgICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE1hYy0+ZnQuZnRTbWVDb250ZXh0LnByZUF1dGhSZWFzc29jSW50dmxUaW1lcik7CiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU46CiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkc6CiAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXNldFByZWF1dGhDb250cm9sSW5mbyhwTWFjKTsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRSZXBvcnRTY2FuU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiUmVjZWl2ZWQgZGlzY29ubmVjdCBldmVudCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW4gc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiVHJhbnNpdGlvbmluZyB0byBJTklUIHN0YXRlIikpOwogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiNlbmRpZgogICAgICAgICAgICBicmVhazsKICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgLypJbmZvcm0gdGhlIEZpcm13YXJlIHRvIFNUT1AgU2Nhbm5pbmcgYXMgdGhlIGhvc3QgaGFzIGEgZGlzY29ubmVjdC4qLwogICAgaWYgKGNzclJvYW1Jc1N0YU1vZGUocE1hYywgc2Vzc2lvbklkKSkKICAgIHsKICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLCBSRUFTT05fRElTQ09OTkVDVEVEKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUluZGljYXRlQ29ubmVjdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgQ1NSIGFzIHNvb24gYXMgdGhlIHN0YXRpb24gY29ubmVjdHMgdG8gYW4gQVAuCiAgICAgICAgICAgIFRoaXMgaW5pdGlhbGl6ZXMgYWxsIHRoZSBuZWNlc3NhcnkgZGF0YSBzdHJ1Y3R1cmVzIHJlbGF0ZWQgdG8gdGhlIAogICAgICAgICAgICBhc3NvY2lhdGVkIEFQIGFuZCB0cmFuc2l0aW9ucyB0aGUgc3RhdGUgdG8gQ09OTkVDVEVEIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBzZXNzaW9uSWQgLSBDU1Igc2Vzc2lvbiBpZCB0aGF0IGdvdCBjb25uZWN0ZWQKICAgICAgICAgICAgdm9zU3RhdHVzIC0gY29ubmVjdCBzdGF0dXMgU1VDQ0VTUy9GQUlMVVJFCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSW5kaWNhdGVDb25uZWN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRBTklfVTggc2Vzc2lvbklkLCBWT1NfU1RBVFVTIHZvc1N0YXR1cykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzICBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgVk9TX1NUQVRVUyAgdnN0YXR1czsKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgIGludCAgaW5pdF9mdF9mbGFnID0gRkFMU0U7CiNlbmRpZgoKICAgIC8vIGlmIHNlc3Npb24gaWQgaW52YWxpZCB0aGVuIHdlIG5lZWQgcmV0dXJuIGZhaWx1cmUKICAgIGlmIChOVUxMID09IHBOZWlnaGJvclJvYW1JbmZvIHx8ICFDU1JfSVNfU0VTU0lPTl9WQUxJRChwTWFjLCBzZXNzaW9uSWQpIHx8CiAgICAgICAgKE5VTEwgPT0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLnBDdXJSb2FtUHJvZmlsZSkpCiAgICB7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBzbXNMb2cocE1hYywgTE9HMiwgRkwoIkNvbm5lY3QgaW5kaWNhdGlvbiByZWNlaXZlZCB3aXRoIHNlc3Npb24gaWQgJWQiCiAgICAgICAgICAgImluIHN0YXRlICVzIiksCiAgICAgICAgICAgc2Vzc2lvbklkLCBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKCiAgICAvLyBCYWlsIG91dCBpZiB0aGlzIGlzIE5PVCBhIFNUQSBwZXJzb25hCiAgICBpZiAocE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLnBDdXJSb2FtUHJvZmlsZS0+Y3NyUGVyc29uYSAhPSBWT1NfU1RBX01PREUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJZ25vcmluZyBDb25uZWN0IGluZGljYXRpb24gcmVjZWl2ZWQgZnJvbSBhIG5vbiBTVEEgcGVyc29uYS4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXNzaW9uSWQ6ICVkLCBjc3JQZXJzb25uYSAlZCIpLAogICAgICAgICAgICAgICBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgIChpbnQpcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLnBDdXJSb2FtUHJvZmlsZS0+Y3NyUGVyc29uYSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgLy8gaWYgYSBjb25jdXJyZW50IHNlc3Npb24gaXMgcnVubmluZwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09IENTUl9JU19GQVNUUk9BTV9JTl9DT05DVVJSRU5DWV9JTklfRkVBVFVSRV9FTkFCTEVEKHBNYWMpKQogICAgewojZW5kaWYKICAgICAgICBpZiAoY3NySXNDb25jdXJyZW50U2Vzc2lvblJ1bm5pbmcocE1hYykpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIklnbm9yaW5nIENvbm5lY3QgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiBtdWx0aXNlc3Npb24gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzcklzQ29uY3VycmVudFNlc3Npb25SdW5uaW5nKHBNYWMpKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICB9CiNlbmRpZgoKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewojaWZkZWYgV0xBTl9GRUFUVVJFX0xGUl9NQkIKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9NQkJfUFJFQVVUSF9SRUFTU09DOgojZW5kaWYKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRUFTU09DSUFUSU5HOgogICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogSnVzdCB0cmFuc2l0aW9uIHRoZSBzdGF0ZSB0byBJTklUIHN0YXRlLiBSZXN0IG9mIHRoZSBjbGVhbiB1cCBoYXBwZW5zIHdoZW4gd2UgZ2V0IG5leHQgY29ubmVjdCBpbmRpY2F0aW9uICovCiAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwojZW5kaWYKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIEZhbGwgdGhyb3VnaCBpZiB0aGUgc3RhdHVzIGlzIFNVQ0NFU1MgKi8KICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUOgogICAgICAgICAgICAvKiBSZXNldCBhbGwgdGhlIGRhdGEgc3RydWN0dXJlcyBoZXJlICovIAogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXNldEluaXRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwoKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCA9IHNlc3Npb25JZDsKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEluaXRpYWxpemUgdGhlIG9jY3VwaWVkIGxpc3QgT05MWSBpZiB3ZSBhcmUKICAgICAgICAgICAgICogdHJhbnNpdGlvbmluZyBmcm9tIElOSVQgc3RhdGUgdG8gQ09OTkVDVEVEIHN0YXRlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICAgICAgICAgIGNzckluaXRPY2N1cGllZENoYW5uZWxzTGlzdChwTWFjKTsKI2VuZGlmCiAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CgogICAgICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuYnNzaWQsIHNpemVvZih0Q3NyQnNzaWQpKTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUG9wZXJhdGlvbkNoYW5uZWwgPSBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5vcGVyYXRpb25DaGFubmVsOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQ7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSAwOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gREVGQVVMVF9TQ0FOOwojZW5kaWYKCiAgICAgICAgICAgIAojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICAgICAgICAgIC8qIE5vdyB3ZSBjYW4gY2xlYXIgdGhlIHByZWF1dGhEb25lIHRoYXQgd2FzIHNhdmVkIGFzIHdlIGFyZSBjb25uZWN0ZWQgYWZyZXNoICovCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QocE1hYywgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCk7CiNlbmRpZgogICAgICAgICAgICAKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgICAgIC8vIEJhc2VkIG9uIHRoZSBhdXRoIHNjaGVtZSB0ZWxsIGlmIHdlIGFyZSAxMXIKICAgICAgICAgICAgaWYgKCBjc3JJc0F1dGhUeXBlMTFyKCBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5BdXRoVHlwZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuTURJRC5tZGllUHJlc2VudCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzRmFzdFRyYW5zaXRpb25FbmFibGVkKQogICAgICAgICAgICAgICAgICAgIGluaXRfZnRfZmxhZyA9IFRSVUU7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCIxMXJBc3NvYyBpcyA9ICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKTsKI2VuZGlmCgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgICAgICAvLyBCYXNlZCBvbiB0aGUgYXV0aCBzY2hlbWUgdGVsbCBpZiB3ZSBhcmUgMTFyCiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5pc0VTRUFzc29jKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc0Zhc3RUcmFuc2l0aW9uRW5hYmxlZCkKICAgICAgICAgICAgICAgICAgICBpbml0X2Z0X2ZsYWcgPSBUUlVFOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiaXNFU0VBc3NvYyBpcyA9ICVkIGZ0ID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYywgaW5pdF9mdF9mbGFnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAojZW5kaWYKCiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLnBlbmRpbmdfcm9hbV9kaXNhYmxlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoInByb2Nlc3MgcGVuZGluZyByb2FtIGRpc2FibGUiKSk7CiAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzRmFzdFJvYW1JbmlGZWF0dXJlRW5hYmxlZCA9IEZBTFNFOwogICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5wZW5kaW5nX3JvYW1fZGlzYWJsZSA9IEZBTFNFOwogICAgICAgICAgICB9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAvLyBJZiAiTGVnYWN5IEZhc3QgUm9hbWluZyIgaXMgZW5hYmxlZCAKICAgICAgICAgICAgaWYgKGNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLCBzZXNzaW9uSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbml0X2Z0X2ZsYWcgPSBUUlVFOwogICAgICAgICAgICB9CiNlbmRpZgoKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgICAgICBpZiAoIGluaXRfZnRfZmxhZyA9PSBUUlVFICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogSW5pdGlhbGl6ZSBhbGwgdGhlIGRhdGEgc3RydWN0dXJlcyBuZWVkZWQgZm9yIHRoZSAxMXIgRlQgUHJlYXV0aCAqLwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbGVkTGlzdChwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgIGlmIChjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAvKklmIHRoaXMgaXMgbm90IGEgSU5GUkEgdHlwZSBCU1MsIHRoZW4gZG8gbm90IHNlbmQgdGhlIGNvbW1hbmQKICAgICAgICAgICAgICAgICAgKiBkb3duIHRvIGZpcm13YXJlLkRvIG5vdCBzZW5kIHRoZSBTVEFSVCBjb21tYW5kIGZvciBvdGhlciBzZXNzaW9uCiAgICAgICAgICAgICAgICAgICogY29ubmVjdGlvbnMuKi8KICAgICAgICAgICAgICAgICBpZihjc3JSb2FtSXNTdGFNb2RlKHBNYWMsIHNlc3Npb25JZCkpCiAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0ggPSAwOwogICAgICAgICAgICAgICAgICAgICBpZihwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9ySW5pdGlhbEZvcmNlZFJvYW1UbzVHaEVuYWJsZSAmJgogICAgICAgICAgICAgICAgICAgICAgIChHZXRSRkJhbmQocE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUG9wZXJhdGlvbkNoYW5uZWwpID09CiAgICAgICAgICAgICAgICAgICAgICAgIFNJUl9CQU5EXzJfNF9HSFopKQogICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICogS2VlcCA1RyBhbmQgRndyIHJvYW1pbmcgbXV0dWFsbHkgZXhjbHVzaXZlIHNvIGRvIG5vdAogICAgICAgICAgICAgICAgICAgICAgICAgICogc2VuZCBSU08gc3RhcnQgTm90ZSB3ZSBoYXZlIHRvIHNlbmQgUlNPIHN0YXJ0IGluIGFsbAogICAgICAgICAgICAgICAgICAgICAgICAgICogZXJycm8gY2FzZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkRvIG5vdCBzZW5kIFJTTyBzdGFydCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmVjYXVzZSA1RyBmb3JjZSByb2FtaW5nIGlzIGVuYWJsZWQiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9DT05ORUNUKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCgogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgbmVpZ2hib3IgbG9va3VwIERPV04gZXZlbnQgd2l0aCBUTCwgUlNTSSA9ICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpOwogICAgICAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICAgICAgIHZzdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiNlbmRpZgogICAgICAgICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2c3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdnN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FEICovCiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQ29ubmVjdCBldmVudCByZWNlaXZlZCBpbiBpbnZhbGlkIHN0YXRlICVzIgogICAgICAgICAgICAgICAgICAgIi4uSWdub3JpbmcuLi4iKSwKICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQoKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbGVkTGlzdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBwdXJnZXMgYWxsIHRoZSBNQUMgYWRkcmVzc2VzIGluIHRoZSBwcmUtYXV0aCBmYWlsIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxlZExpc3QodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdEFOSV9VOCBpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzczsgaSsrKQogICAgewogICAgICAgIHZvc19tZW1femVybyhwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubWFjQWRkcmVzc1tpXSwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICB9CiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcyA9IDA7CgogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSW5pdDExckFzc29jSW5mbwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplcyAxMXIgcmVsYXRlZCBuZWlnaGJvciByb2FtIGRhdGEgc3RydWN0dXJlcwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jbml0MTFyQXNzb2NJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGVIYWxTdGF0dXMgIHN0YXR1czsKICAgIHRwQ3NyMTFyQXNzb2NOZWlnaGJvckluZm8gICBwRlRSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mbzsKCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uaXMxMXJBc3NvYyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubWF4TmVpZ2hib3JSZXRyaWVzID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk1heE5laWdoYm9yUmV0cmllczsKICAgIHBGVFJvYW1JbmZvLT5uZWlnaGJvclJlcG9ydFRpbWVvdXQgPSBDU1JfTkVJR0hCT1JfUk9BTV9SRVBPUlRfUVVFUllfVElNRU9VVDsKICAgIHBGVFJvYW1JbmZvLT5QRVByZWF1dGhSZXNwVGltZW91dCA9IENTUl9ORUlHSEJPUl9ST0FNX1BSRUFVVEhfUlNQX1dBSVRfTVVMVElQTElFUiAqIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kOwogICAgcEZUUm9hbUluZm8tPm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBGVFJvYW1JbmZvLT5wcmVhdXRoUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIAogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKICAgIHZvc19tZW1femVybyhwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodENzck5laWdoYm9yUmVwb3J0QnNzSW5mbykgKiBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCk7CgogICAgCiAgICBzdGF0dXMgPSBjc3JMTE9wZW4ocE1hYy0+aEhkZCwgJnBGVFJvYW1JbmZvLT5wcmVBdXRoRG9uZUxpc3QpOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTEwgT3BlbiBvZiBwcmVhdXRoIGRvbmUgQVAgTGlzdCBmYWlsZWQiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KICAgIHJldHVybiBzdGF0dXM7Cn0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSW5pdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplcyBuZWlnaGJvciByb2FtIGRhdGEgc3RydWN0dXJlcwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jbml0KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGVIYWxTdGF0dXMgc3RhdHVzOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlICAgICAgID0gICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0xPU0VEOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnByZXZOZWlnaGJvclJvYW1TdGF0ZSAgID0gICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0xPU0VEOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCAgICAgICAgICAgID0gICBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5tYXhDaGFubmVsU2NhblRpbWUgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JTY2FuTWF4Q2hhblRpbWU7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1pbkNoYW5uZWxTY2FuVGltZSA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvclNjYW5NaW5DaGFuVGltZTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4TmVpZ2hib3JSZXRyaWVzID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JMb29rdXBSc3NpVGhyZXNob2xkOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JSZWFzc29jUnNzaVRocmVzaG9sZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yU2NhblRpbWVyUGVyaW9kOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlc3VsdHNSZWZyZXNoUGVyaW9kID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2Q7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmVtcHR5U2NhblJlZnJlc2hQZXJpb2QgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uRW1wdHlTY2FuUmVmcmVzaFBlcmlvZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JJbml0aWFsRm9yY2VkUm9hbVRvNUdoRW5hYmxlID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9ySW5pdGlhbEZvcmNlZFJvYW1UbzVHaEVuYWJsZTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuV2Vha1pvbmVSc3NpVGhyZXNob2xkRm9yUm9hbSA9CiAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uV2Vha1pvbmVSc3NpVGhyZXNob2xkRm9yUm9hbTsKCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgICA9CiAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5laWdoYm9yU2NhbkNoYW5MaXN0Lm51bUNoYW5uZWxzOwoKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgIT0gMCkKICAgIHsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0KICAgICAgICAgICAgICAgIHZvc19tZW1fbWFsbG9jKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5laWdoYm9yU2NhbkNoYW5MaXN0Lm51bUNoYW5uZWxzKTsKCiAgICAgICAgaWYgKE5VTEwgPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IEFsbG9jYXRpb24gZm9yIENGRyBDaGFubmVsIExpc3QgZmFpbGVkIikpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgICAgIH0KCiAgICAgICAgLyogVXBkYXRlIHRoZSByb2FtIGdsb2JhbCBzdHJ1Y3R1cmUgZnJvbSBDRkcgKi8KICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubmVpZ2hib3JTY2FuQ2hhbkxpc3QuY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5laWdoYm9yU2NhbkNoYW5MaXN0Lm51bUNoYW5uZWxzKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICBGTCgiaW52YWxpZCBuZWlnaGJvciByb2FtIGNoYW5uZWwgbGlzdDogJXUiKSwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpOwogICAgfQoKICAgIHZvc19tZW1fc2V0KHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRDc3JCc3NpZCksIDApOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQ7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gREVGQVVMVF9TQ0FOOwogICAgdm9zX21lbV9zZXQoJnBOZWlnaGJvclJvYW1JbmZvLT5wcmV2Q29ublByb2ZpbGUsIHNpemVvZih0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUpLCAwKTsKI2VuZGlmCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgc3RhdHVzID0gdm9zX3RpbWVyX2luaXQoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lciwgVk9TX1RJTUVSX1RZUEVfU1csCiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JTY2FuVGltZXJDYWxsYmFjaywgKHZvaWQgKilwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHRpbWVyIGFsbG9jYXRpb24gZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IHZvc190aW1lcl9pbml0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLCBWT1NfVElNRVJfVFlQRV9TVywKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXN1bHRzUmVmcmVzaFRpbWVyQ2FsbGJhY2ssICh2b2lkICopcE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIGFsbG9jYXRpb24gZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IHZvc190aW1lcl9pbml0KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyLCBWT1NfVElNRVJfVFlQRV9TVywKICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUVtcHR5U2NhblJlZnJlc2hUaW1lckNhbGxiYWNrLAogICAgICAgICAgICAgICAgKHZvaWQgKilwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJFbXB0eSBzY2FuIHJlZnJlc2ggdGltZXIgYWxsb2NhdGlvbiBmYWlsZWQiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IHZvc190aW1lcl9pbml0KCZwTmVpZ2hib3JSb2FtSW5mby0+Zm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyLCBWT1NfVElNRVJfVFlQRV9TVywKICAgICAgICAgICAgICAgIGNzckZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lckNhbGxiYWNrLCAodm9pZCAqKXBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lciB0aW1lciBhbGxvY2F0aW9uIGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IGNzckxMT3BlbihwTWFjLT5oSGRkLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkxMIE9wZW4gb2Ygcm9hbWFibGUgQVAgTGlzdCBmYWlsZWQiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5mb3JjZWRJbml0aWFsUm9hbVRvNUdIVGltZXIpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID0gQ1NSX05FSUdIQk9SX1JPQU1fSU5WQUxJRF9DSEFOTkVMX0lOREVYOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jbml0MTFyQXNzb2NJbmZvKHBNYWMpOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTEwgT3BlbiBvZiByb2FtYWJsZSBBUCBMaXN0IGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPmZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lcik7CiAgICAgICAgY3NyTExDbG9zZSgmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQojZW5kaWYKICAgIC8qIEluaXRpYWxpemUgdGhpcyB3aXRoIHRoZSBjdXJyZW50IHRpY2sgY291bnQgKi8KICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA9IHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKI2VuZGlmCgogICAgLy9TZXQgdGhlIExhc3QgU2VudCBDbWQgYXMgUlNPX1NUT1AKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sYXN0U2VudENtZCA9IFJPQU1fU0NBTl9PRkZMT0FEX1NUT1A7CiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUNsb3NlCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGNsb3Nlcy9mcmVlcyBhbGwgdGhlIG5laWdoYm9yIHJvYW0gZGF0YSBzdHJ1Y3R1cmVzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1DbG9zZSh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBSb2FtIEFsZ29yaXRobSBBbHJlYWR5IENsb3NlZCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgCiAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+Zm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyKTsKCiAgICAvKiBTaG91bGQgZnJlZSB1cCB0aGUgbm9kZXMgaW4gdGhlIGxpc3QgYmVmb3JlIGNsb3NpbmcgdGhlIGRvdWJsZSBMaW5rZWQgbGlzdCAqLwogICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKICAgIGNzckxMQ2xvc2UoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICAKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpCiAgICB7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9IENTUl9ORUlHSEJPUl9ST0FNX0lOVkFMSURfQ0hBTk5FTF9JTkRFWDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7ICAgIAogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgLyogRnJlZSB0aGUgcHJvZmlsZS4uICovIAogICAgY3NyUmVsZWFzZVByb2ZpbGUocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIgICAgCiAgICBjc3JSb2FtRnJlZUNvbm5lY3RQcm9maWxlKHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cHJldkNvbm5Qcm9maWxlKTsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKICAgIHZvc19tZW1femVybyhwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodENzck5laWdoYm9yUmVwb3J0QnNzSW5mbykgKiBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCk7CiAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpOwogICAgY3NyTExDbG9zZSgmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KTsKI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0xPU0VEKQogICAgCiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZXF1ZXN0SGFuZG9mZgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiB0cmlnZ2VycyBhY3R1YWwgc3dpdGNoaW5nIGZyb20gb25lIEFQIHRvIHRoZSBuZXcgQVAuCiAgICAgICAgICAgIEl0IGlzc3VlcyBkaXNhc3NvY2lhdGUgd2l0aCByZWFzb24gY29kZSBhcyBIYW5kb2ZmIGFuZCBDU1IgYXMgYSBwYXJ0IG9mIAogICAgICAgICAgICBoYW5kbGluZyBkaXNhc3NvYyByc3AsIGlzc3VlcyByZWFzc29jaWF0ZSB0byB0aGUgbmV3IEFQCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXF1ZXN0SGFuZG9mZih0cEFuaVNpckdsb2JhbCBwTWFjKQp7CgogICAgdENzclJvYW1JbmZvIHJvYW1JbmZvOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0QU5JX1UzMiBzZXNzaW9uSWQgPSBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkOwogICAgdENzck5laWdoYm9yUm9hbUJTU0luZm8gICAgIGhhbmRvZmZOb2RlOwogICAgZXh0ZXJuIHZvaWQgY3NyUm9hbVJvYW1pbmdTdGF0ZURpc2Fzc29jUnNwUHJvY2Vzc29yKCB0cEFuaVNpckdsb2JhbCBwTWFjLCB0U2lyU21lRGlzYXNzb2NSc3AgKnBTbWVEaXNhc3NvY1JzcCApOwogICAgdEFOSV9VMzIgcm9hbUlkID0gMDsKICAgIGVIYWxTdGF0dXMgc3RhdHVzOwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgdENzclJvYW1JbmZvICpyb2FtSW5mb01ldHJpY3M7CiNlbmRpZgoKICAgIGlmIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORSkgCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSb2FtIHJlcXVlc3RlZCB3aGVuIE5laWdoYm9yIHJvYW0gaXMgaW4gJXMgc3RhdGUiKSwKICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09CiAgICAgICAgIGNzck5laWdoYm9yUm9hbUdldEhhbmRvZmZBUEluZm8ocE1hYywgJmhhbmRvZmZOb2RlKSkKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICBGTCgiZmFpbGVkIHRvIG9idGFpbiBoYW5kb2ZmIEFQIikpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfREVCVUcsCiAgICAgICAgICAgICAgIEZMKCJIQU5ET0ZGIENBTkRJREFURSBCU1NJRCAiTUFDX0FERFJFU1NfU1RSKSwKICAgICAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQpKTsKCiAgICB2b3NfbWVtX3plcm8oJnJvYW1JbmZvLCBzaXplb2YodENzclJvYW1JbmZvKSk7CiAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsICZyb2FtSW5mbywgcm9hbUlkLCBlQ1NSX1JPQU1fRlRfU1RBUlQsIAogICAgICAgICAgICAgICAgZVNJUl9TTUVfU1VDQ0VTUyk7CgogICAgdm9zX21lbV96ZXJvKCZyb2FtSW5mbywgc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORykKICAgIAojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAvKiBMRlIgbWV0cmljcyAtIHByZS1hdXRoIGNvbXBsZXRpb24gbWV0cmljLgogICAgICAgU2VuZCB0aGUgZXZlbnQgdG8gc3VwcGxpY2FudCB0aGF0IHByZS1hdXRoIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgKi8KICAgIHJvYW1JbmZvTWV0cmljcyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbUluZm8pKTsKICAgIGlmIChOVUxMID09IHJvYW1JbmZvTWV0cmljcykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZCEiKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdm9zX21lbV9jb3B5KCh2b2lkICopcm9hbUluZm9NZXRyaWNzLT5ic3NpZCwKICAgICAgICAgICAgKHZvaWQgKikmaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgc2l6ZW9mKHRDc3JCc3NpZCkpOwogICAgICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwKICAgICAgICAgICAgcm9hbUluZm9NZXRyaWNzLCAwLCBlQ1NSX1JPQU1fSEFORE9WRVJfU1VDQ0VTUywgMCk7CiAgICAgICAgdm9zX21lbV9mcmVlKHJvYW1JbmZvTWV0cmljcyk7CiAgICB9CiNlbmRpZgoKICAgIC8qIEZyZWUgdGhlIHByb2ZpbGUuLiBKdXN0IHRvIG1ha2Ugc3VyZSB3ZSBkb250IGxlYWsgbWVtb3J5IGhlcmUgKi8gCiAgICBjc3JSZWxlYXNlUHJvZmlsZShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPmNzck5laWdoYm9yUm9hbVByb2ZpbGUpOwogICAgLyogQ3JlYXRlIHRoZSBIYW5kb2ZmIEFQIHByb2ZpbGUuIENvcHkgdGhlIGN1cnJlbnRseSBjb25uZWN0ZWQgcHJvZmlsZSBhbmQgdXBkYXRlIG9ubHkgdGhlIEJTU0lEIGFuZCBjaGFubmVsIG51bWJlcgogICAgICAgIFRoaXMgc2hvdWxkIGhhcHBlbiBiZWZvcmUgaXNzdWluZyBkaXNjb25uZWN0ICovCiAgICBzdGF0dXMgPSBjc3JSb2FtQ29weUNvbm5lY3RlZFByb2ZpbGUocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZSk7CiAgICBpZihlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoImNzclJvYW1Db3B5Q29ubmVjdGVkUHJvZmlsZSByZXR1cm5lZCBmYWlsZWQgJWQiKSwgc3RhdHVzKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlLkJTU0lEcy5ic3NpZCwgaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZS5DaGFubmVsSW5mby5DaGFubmVsTGlzdFswXSA9IGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbElkOwogICAgCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICIgY3NyUm9hbUhhbmRvZmZSZXF1ZXN0ZWQ6IGRpc2Fzc29jaWF0aW5nIHdpdGggY3VycmVudCBBUCIpOwoKICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1MoY3NyUm9hbUlzc3VlRGlzYXNzb2NpYXRlQ21kKHBNYWMsIHNlc3Npb25JZCwgZUNTUl9ESVNDT05ORUNUX1JFQVNPTl9IQU5ET0ZGKSkpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csICJjc3JSb2FtSGFuZG9mZlJlcXVlc3RlZDogIGZhaWwgdG8gaXNzdWUgZGlzYXNzb2NpYXRlIik7CiAgICAgICAgcmV0dXJuOwogICAgfSAgICAgICAgICAgICAgICAgICAgICAgCgogICAgLy9ub3RpZnkgSEREIGZvciBoYW5kb2ZmLCBwcm92aWRpbmcgdGhlIEJTU0lEIHRvbwogICAgcm9hbUluZm8ucmVhc29uQ29kZSA9IGVDc3JSb2FtUmVhc29uQmV0dGVyQVA7CgogICAgdm9zX21lbV9jb3B5KHJvYW1JbmZvLmJzc2lkLCAKICAgICAgICAgICAgICAgICBoYW5kb2ZmTm9kZS5wQnNzRGVzY3JpcHRpb24tPmJzc0lkLCAKICAgICAgICAgICAgICAgICBzaXplb2YoIHRDc3JCc3NpZCApKTsKCiAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHNlc3Npb25JZCwgJnJvYW1JbmZvLCAwLCBlQ1NSX1JPQU1fUk9BTUlOR19TVEFSVCwgZUNTUl9ST0FNX1JFU1VMVF9OT05FKTsKCgogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXNIYW5kb2ZmSW5Qcm9ncmVzcwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHdoZXRoZXIgaGFuZG9mZiBpcyBpbiBwcm9ncmVzcyBvciBub3QgYmFzZWQgb24gCiAgICAgICAgICAgIHRoZSBjdXJyZW50IG5laWdoYm9yIHJvYW0gc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIGlzMTFyUmVhc3NvYyAtIFJldHVybiB3aGV0aGVyIHJlYXNzb2MgaXMgb2YgdHlwZSA4MDIuMTFyIHJlYXNzb2MKCiAgICBccmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFIGlmIHJlYXNzb2MgaW4gcHJvZ3Jlc3MsIGVBTklfQk9PTEVBTl9GQUxTRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Jc0hhbmRvZmZJblByb2dyZXNzKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwoKICAgIHJldHVybiBlQU5JX0JPT0xFQU5fRkFMU0U7Cn0KCiNpZiBkZWZpbmVkKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkKFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HKQovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXMxMXJBc3NvYwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHdoZXRoZXIgdGhlIGN1cnJlbnQgYXNzb2NpYXRpb24gaXMgYSAxMXIgYXNzb2Mgb3Igbm90CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUFOSV9CT09MRUFOX1RSVUUgaWYgY3VycmVudCBhc3NvYyBpcyAxMXIsIGVBTklfQk9PTEVBTl9GQUxTRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1JczExckFzc29jKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHJldHVybiBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uaXMxMXJBc3NvYzsKfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtR2V0SGFuZG9mZkFQSW5mbwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBiZXN0IHBvc3NpYmxlIEFQIGZvciBoYW5kb2ZmLiBGb3IgMTFSIGNhc2UsIGl0IAogICAgICAgICAgICByZXR1cm5zIHRoZSAxc3QgZW50cnkgZnJvbSBwcmUtYXV0aCBkb25lIGxpc3QuIEZvciBub24tMTFyIGNhc2UsIGl0IHJldHVybnMgCiAgICAgICAgICAgIHRoZSAxc3QgZW50cnkgZnJvbSByb2FtYWJsZSBBUCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwSGFuZG9mZk5vZGUgLSBBUCBub2RlIHRoYXQgaXMgdGhlIGhhbmRvZmYgY2FuZGlkYXRlIHJldHVybmVkCgogICAgXHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRSBpZiBhYmxlIGZpbmQgaGFuZG9mZiBBUCwgZUFOSV9CT09MRUFOX0ZBTFNFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUdldEhhbmRvZmZBUEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYywgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBIYW5kb2ZmTm9kZSkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gICAgICAgIHBCc3NOb2RlID0gTlVMTDsKICAgIAogICAgVk9TX0FTU0VSVChOVUxMICE9IHBIYW5kb2ZmTm9kZSk7IAogICAgICAgIAojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykKICAgIHsKICAgICAgICAvKiBBbHdheXMgdGhlIEJTUyBpbmZvIGluIHRoZSBoZWFkIGlzIHRoZSBoYW5kb2ZmIGNhbmRpZGF0ZSAqLwogICAgICAgIHBCc3NOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCwgTlVMTCk7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksIGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCkpOwogICAgfQogICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYykKICAgIHsKICAgICAgICAvKiBBbHdheXMgdGhlIEJTUyBpbmZvIGluIHRoZSBoZWFkIGlzIHRoZSBoYW5kb2ZmIGNhbmRpZGF0ZSAqLwogICAgICAgIHBCc3NOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCwgTlVMTCk7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksIGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCkpOwogICAgfQogICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgQ1NSX1NFU1NJT05fSURfSU5WQUxJRCkpCiAgICB7CiAgICAgICAgLyogQWx3YXlzIHRoZSBCU1MgaW5mbyBpbiB0aGUgaGVhZCBpcyB0aGUgaGFuZG9mZiBjYW5kaWRhdGUgKi8KICAgICAgICBwQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsIE5VTEwpOwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIk51bWJlciBvZiBIYW5kb2ZmIGNhbmRpZGF0ZXMgPSAlZCIpLCBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpKTsKICAgIH0KICAgIGVsc2UKI2VuZGlmCiAgICB7CiAgICAgICAgcEJzc05vZGUgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCBOVUxMKTsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJOdW1iZXIgb2YgSGFuZG9mZiBjYW5kaWRhdGVzID0gJWQiKSwgY3NyTExDb3VudCgmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KSk7CiAgICB9CgogICAgaWYgKE5VTEwgPT0gcEJzc05vZGUpCiAgICB7CiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIH0KCiAgICB2b3NfbWVtX2NvcHkocEhhbmRvZmZOb2RlLCBwQnNzTm9kZSwgc2l6ZW9mKHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvKSk7CgogICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIFRSVUUgaWYgcHJlYXV0aCBpcyBjb21wbGV0ZWQgCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gYm9vbGVhbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVN0YXRlUHJlYXV0aERvbmUodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgcmV0dXJuIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUgPT0gCiAgICAgICAgICAgICAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIFxicmllZiAgSW4gdGhlIGV2ZW50IHRoYXQgd2UgYXJlIGFzc29jaWF0ZWQgd2l0aCBBUDEgYW5kIHdlIGhhdmUKICAgIGNvbXBsZXRlZCBwcmUgYXV0aCB3aXRoIEFQMi4gVGhlbiB3ZSByZWNlaXZlIGEgZGVhdXRoL2Rpc2Fzc29jIGZyb20KICAgIEFQMS4gCiAgICBBdCB0aGlzIHBvaW50IG5laWdoYm9yIHJvYW0gaXMgaW4gcHJlIGF1dGggZG9uZSBzdGF0ZSwgcHJlIGF1dGggdGltZXIKICAgIGlzIHJ1bm5pbmcuIFdlIG5vdyBoYW5kbGUgdGhpcyBjYXNlIGJ5IHN0b3BwaW5nIHRpbWVyIGFuZCBjbGVhcmluZwogICAgdGhlIHByZS1hdXRoIHN0YXRlLiBXZSBiYXNpY2FsbHkgY2xlYXIgdXAgYW5kIGp1c3QgZ28gdG8gZGlzY29ubmVjdGVkCiAgICBzdGF0ZS4gCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gYm9vbGVhbgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVRyYW5pc3Rpb25QcmVhdXRoRG9uZVRvRGlzY29ubmVjdGVkKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgaWYgKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSAhPSAKICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORSkgcmV0dXJuOwoKICAgIC8vIFN0b3AgdGltZXIKICAgIHZvc190aW1lcl9zdG9wKCZwTWFjLT5mdC5mdFNtZUNvbnRleHQucHJlQXV0aFJlYXNzb2NJbnR2bFRpbWVyKTsKCiAgICAvLyBUcmFuc2l0aW9uIHRvIGluaXQgc3RhdGUKICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwojZW5kaWYKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIGJhY2tncm91bmQgc2NhbiB0cmlnZ2VyZWQgYnkKICAgICAgICAgICAgTEZSIGlzIGluIHByb2dyZXNzLgoKICAgIFxwYXJhbSAgaGFsSGFuZGxlIC0gVGhlIGhhbmRsZSBmcm9tIEhERCBjb250ZXh0LgoKICAgIFxyZXR1cm4gYm9vbGVhbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVNjYW5Sc3BQZW5kaW5nICh0SGFsSGFuZGxlIGhIYWwpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVChoSGFsKTsKICAgIHJldHVybiAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIFNUQSBpcyBpbiB0aGUgbWlkZGxlIG9mIHJvYW1pbmcgc3RhdGVzCgogICAgXHBhcmFtICBoYWxIYW5kbGUgLSBUaGUgaGFuZGxlIGZyb20gSEREIGNvbnRleHQuCgogICAgXHJldHVybiBib29sZWFuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JNaWRkbGVPZlJvYW1pbmcgKHRIYWxIYW5kbGUgaEhhbCkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKGhIYWwpOwogICAgdEFOSV9CT09MRUFOIHZhbCA9IChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIRU5USUNBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUgPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOID09IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSkKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTEZSX01CQgogICAgICAgICAgICAgICAgICAgICAgIHx8IChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfTUJCX1BSRUFVVEhfUkVBU1NPQyA9PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSk7CiNlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgOwojZW5kaWYKICAgIHJldHVybiAodmFsKTsKfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1DYW5kaWRhdGVGb3VuZEluZEhkbHIKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IENTUiBhcyBzb29uIGFzIFRMIHBvc3RzIHRoZSBjYW5kaWRhdGUKICAgICAgICAgICAgZm91bmQgaW5kaWNhdGlvbiB0byBTTUUgdmlhIE1DIHRocmVhZAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcE1zZyAtIE1zZyBzZW50IGJ5IFBFCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtQ2FuZGlkYXRlRm91bmRJbmRIZGxyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHZvaWQqIHBNc2cpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwoKICAgIGlmICh2b3NfY2hlY2tfbW9uaXRvcl9zdGF0ZSgpKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiSWdub3JlIHJhb20gY2FuZGlkYXRlIHdoZW4gcm9hbSBzdGFydGVkIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQoKICAgIC8qIHdlIG11c3QgYmUgaW4gY29ubmVjdGVkIHN0YXRlLCBpZiBub3QgaWdub3JlIGl0ICovCiAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgIHx8IChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBub3QgQ09OTkVDVEVEIHN0YXRlIE9SIHVPc1JlcXVlc3RlZEhhbmRvZmYgaXMgc2V0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLAogICAgICAgICAqIHB1cmdlIG5vbi1QMlAgcmVzdWx0cyBmcm9tIHRoZSBwYXN0ICovCiAgICAgICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0KHBNYWMsIFZPU19GQUxTRSk7CiAgICAgICAgLyogT25jZSBpdCBnZXRzIHRoZSBjYW5kaWRhdGVzIGZvdW5kIGluZGljYXRpb24gZnJvbSBQRSwgd2lsbCBpc3N1ZSBhIHNjYW4KICAgICAgICAgLSByZXEgdG8gUEUgd2l0aCCTZnJlc2hTY2FulCBpbiBzY2FucmVxIHN0cnVjdHVyZSBzZXQgYXMgZm9sbG93czoKICAgICAgICAgMHg0MiAtIFJldHVybiAmIHB1cmdlIExGUiBzY2FuIHJlc3VsdHMKICAgICAgICAqLwogICAgICAgIHN0YXR1cyA9IGNzclNjYW5SZXF1ZXN0TGZyUmVzdWx0KHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtU2NhblJlc3VsdFJlcXVlc3RDYWxsYmFjaywgcE1hYyk7CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByb2Nlc3NIYW5kb2ZmUmVxCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBzdGFydCB3aXRoIHRoZSBoYW5kb2ZmIHByb2Nlc3MuIEZpcnN0IGRvIGEKICAgIFNTSUQgc2NhbiBmb3IgdGhlIEJTU0lEIHByb3ZpZGVkCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByb2Nlc3NIYW5kb2ZmUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdEFOSV9VMzIgcm9hbUlkOwogICAgdENzclJvYW1Qcm9maWxlICpwUHJvZmlsZSA9IE5VTEw7CiAgICB0Q3NyUm9hbVNlc3Npb24gKnBTZXNzaW9uID0gQ1NSX0dFVF9TRVNTSU9OKCBwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkICk7CiAgICB0QU5JX1U4IGkgPSAwOwogICAgdWludDhfdCByb2FtX25vdyA9IDA7CiAgICB1aW50OF90IHJvYW1hYmxlX2FwX2NvdW50ID0gMDsKICAgIHRDc3JTY2FuUmVzdWx0RmlsdGVyICAgIHNjYW5fZmlsdGVyOwogICAgdFNjYW5SZXN1bHRIYW5kbGUgICAgICAgc2Nhbl9yZXN1bHQ7CgogICAgaWYgKE5VTEwgPT0gcFNlc3Npb24pCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJwU2Vzc2lvbiBpcyBOVUxMICIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KCiAgICBkbwogICAgewogICAgICAgIHJvYW1JZCA9IEdFVF9ORVhUX1JPQU1fSUQoJnBNYWMtPnJvYW0pOwogICAgICAgIHBQcm9maWxlID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JSb2FtUHJvZmlsZSkpOwogICAgICAgIGlmICggTlVMTCA9PSBwUHJvZmlsZSApCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvYyBmYWlsZWQiKSk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KICAgICAgICB2b3NfbWVtX3NldChwUHJvZmlsZSwgc2l6ZW9mKHRDc3JSb2FtUHJvZmlsZSksIDApOwogICAgICAgIHN0YXR1cyA9IGNzclJvYW1Db3B5UHJvZmlsZShwTWFjLCBwUHJvZmlsZSwgcFNlc3Npb24tPnBDdXJSb2FtUHJvZmlsZSk7CiAgICAgICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJQcm9maWxlIGNvcHkgZmFpbGVkIikpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8vQWRkIHRoZSBCU1NJRCAmIENoYW5uZWwKICAgICAgICBwUHJvZmlsZS0+QlNTSURzLm51bU9mQlNTSURzID0gMTsKICAgICAgICBwUHJvZmlsZS0+QlNTSURzLmJzc2lkID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBQcm9maWxlLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwogICAgICAgIGlmIChOVUxMID09IHBQcm9maWxlLT5CU1NJRHMuYnNzaWQpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIm1lbSBhbGxvYyBmYWlsZWQgZm9yIEJTU0lEIikpOwogICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIHZvc19tZW1femVybyhwUHJvZmlsZS0+QlNTSURzLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpICogcFByb2ZpbGUtPkJTU0lEcy5udW1PZkJTU0lEcyk7CgogICAgICAgIC8qIFBvcHVsYXRlIHRoZSBCU1NJRCBmcm9tIGhhbmRvZmYgaW5mbyByZWNlaXZlZCBmcm9tIEhERCAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBwUHJvZmlsZS0+QlNTSURzLm51bU9mQlNTSURzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkoJnBQcm9maWxlLT5CU1NJRHMuYnNzaWRbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgICAgIH0KCiAgICAgICAgcFByb2ZpbGUtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgPSAxOwogICAgICAgIHBQcm9maWxlLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9CiAgICAgICAgdm9zX21lbV9tYWxsb2Moc2l6ZW9mKCpwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgcFByb2ZpbGUtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpOwogICAgICAgIGlmIChOVUxMID09IHBQcm9maWxlLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgibWVtIGFsbG9jIGZhaWxlZCBmb3IgQ2hhbm5lbExpc3QiKSk7CiAgICAgICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbMF0gPSBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uY2hhbm5lbDsKCiAgICAgICAgLyoKICAgICAgICAgKiBGb3IgVXNlciBzcGFjZSBjb25uZWN0IHJlcXVlc3RzLCB0aGUgc2NhbiBoYXMgYWxyZWFkeSBiZWVuIGRvbmUuCiAgICAgICAgICogU28sIGNoZWNrIGlmIHRoZSBCU1MgZGVzY3JpcHRvciBleGlzdHMgaW4gdGhlIHNjYW4gY2FjaGUgYW5kCiAgICAgICAgICogcHJvY2VlZCB3aXRoIHRoZSBoYW5kb2ZmIGluc3RlYWQgb2YgYSByZWR1bmRhbnQgc2NhbiBhZ2Fpbi4KICAgICAgICAgKi8KICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLnNyYyA9PSBDT05ORUNUX0NNRF9VU0VSU1BBQ0UpIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJDb25uZWN0IGNtZCB3aXRoIGJzc2lkIHdpdGhpbiBzYW1lIEVTUyIpKTsKICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJlcGFyZVNjYW5Qcm9maWxlRmlsdGVyKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMsICZzY2FuX2ZpbHRlcik7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiRmlsdGVyIGNyZWF0aW9uIHN0YXR1cyA9ICVkIiksIHN0YXR1cyk7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzclNjYW5HZXRSZXN1bHQocE1hYywgJnNjYW5fZmlsdGVyLCAmc2Nhbl9yZXN1bHQpOwogICAgICAgICAgICByb2FtX25vdyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuUmVzdWx0cyhwTWFjLCAmc2Nhbl9yZXN1bHQpOwogICAgICAgICAgICByb2FtYWJsZV9hcF9jb3VudCA9IGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICAgICAgICAgIGNzckZyZWVTY2FuRmlsdGVyKHBNYWMsICZzY2FuX2ZpbHRlcik7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgicm9hbV9ub3c9JWQsIHJvYW1hYmxlX2FwX2NvdW50PSVkIiksCiAgICAgICAgICAgICAgICAgICByb2FtX25vdywgcm9hbWFibGVfYXBfY291bnQpOwogICAgICAgIH0KICAgICAgICBpZiAocm9hbV9ub3cgJiYgcm9hbWFibGVfYXBfY291bnQpIHsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtVHJpZ2dlckhhbmRvZmYocE1hYywgcE5laWdoYm9yUm9hbUluZm8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzclNjYW5Gb3JTU0lEKHBNYWMsIHBTZXNzaW9uLT5zZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUHJvZmlsZSwgcm9hbUlkLCBGQUxTRSk7CiAgICAgICAgICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTU0lEIHNjYW4gZmFpbGVkIikpOwogICAgICAgIH0KICAgIH13aGlsZSgwKTsKCiAgICBpZihOVUxMICE9IHBQcm9maWxlKQogICAgewogICAgICAgIGNzclJlbGVhc2VQcm9maWxlKHBNYWMsIHBQcm9maWxlKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocFByb2ZpbGUpOwogICAgfQoKICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Tc3NpZFNjYW5Eb25lCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbmNlIFNTSUQgc2NhbiBpcyBkb25lLiBJZiBTU0lEIHNjYW4gZmFpbGVkCiAgICB0byBmaW5kIG91ciBjYW5kaWRhdGUgYWRkIGFuIGVudHJ5IHRvIGNzciBzY2FuIGNhY2hlIG91cnNlbGYgYmVmb3JlIHN0YXJ0aW5nCiAgICB0aGUgaGFuZG9mZiBwcm9jZXNzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVNzc2lkU2NhbkRvbmUodHBBbmlTaXJHbG9iYWwgcE1hYywgZUhhbFN0YXR1cyBzdGF0dXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgICAgICAgICAgICAgICAgICAgICBoc3RhdHVzOwoKICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiY2FsbGVkICIpKTsKCiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZS4gSWdub3JlIGl0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQoKICAgIC8vaWYgU1NJRCBzY2FuIGZhaWxlZCB0byBmaW5kIG91ciBjYW5kaWRhdGUgYWRkIGFuIGVudHJ5IHRvIGNzciBzY2FuIGNhY2hlIG91cnNlbGYKICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkFkZCBhbiBlbnRyeSB0byBjc3Igc2NhbiBjYWNoZSIpKTsKICAgICAgICBoc3RhdHVzID0gY3NyU2NhbkNyZWF0ZUVudHJ5SW5TY2FuQ2FjaGUocE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uY2hhbm5lbCk7CiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiY3NyU2NhbkNyZWF0ZUVudHJ5SW5TY2FuQ2FjaGUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIGhzdGF0dXMpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CgogICAgLyogTm93IHdlIGhhdmUgY29tcGxldGVkIHNjYW5uaW5nIGZvciB0aGUgY2FuZGlkYXRlIHByb3ZpZGVkIGJ5IEhERC4gTGV0IG1vdmUgb24gdG8gSE8qLwogICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUocE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gcHJvY2VzcyBjb21wbGV0ZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyoqCiAqIGNzcl9uZWlnaGJvcl9yb2FtX2hhbmRsZXJfYXNzaWduX2hhbmRvZmZfc3JjKCkgLSBBc3NpZ24gc291cmNlIG9mCiAqCQkJCQkJCXJvYW0gaGFuZG9mZgogKiBAcE5laWdoYm9yUm9hbUluZm86IFBvaW50ZXIgdG8gY3NyIG5laWdoYm9yIHJvYW0gY29udHJvbCBpbmZvCiAqIEBwSGFuZG9mZlJlcUluZm86IFBvaW50ZXIgdG8gdGhlIEhhbmRvZmYgcmVxdWVzdAogKgogKiBSZXR1cm46IE5vbmUKICovCiNpZm5kZWYgUUNBX1dJRklfSVNPQwpzdGF0aWMgaW5saW5lIHZvaWQgY3NyX25laWdoYm9yX3JvYW1faGFuZGxlcl9hc3NpZ25faGFuZG9mZl9zcmMoCgkJCXRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvLAoJCQl0QW5pSGFuZG9mZlJlcSAqcEhhbmRvZmZSZXFJbmZvKQp7CglwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uc3JjCgkJPSBwSGFuZG9mZlJlcUluZm8tPmhhbmRvZmZfc3JjOwp9CiNlbHNlCnN0YXRpYyBpbmxpbmUgdm9pZCBjc3JfbmVpZ2hib3Jfcm9hbV9oYW5kbGVyX2Fzc2lnbl9oYW5kb2ZmX3NyYygKCQkJdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm8sCgkJCXRBbmlIYW5kb2ZmUmVxICpwSGFuZG9mZlJlcUluZm8pCnsKfQojZW5kaWYKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1IYW5kb2ZmUmVxSGRscgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgQ1NSIGFzIHNvb24gYXMgaXQgZ2V0cyBhIGhhbmRvZmYgcmVxdWVzdAogICAgICAgICAgICB0byBTTUUgdmlhIE1DIHRocmVhZAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcE1zZyAtIE1zZyBzZW50IGJ5IEhERAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUhhbmRvZmZSZXFIZGxyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHZvaWQqIHBNc2cpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFuaUhhbmRvZmZSZXEgICAgICAgICAgICAgICAgICpwSGFuZG9mZlJlcUluZm87CiAgICBlSGFsU3RhdHVzIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZS4gSWdub3JlIGl0IikpOwogICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLy9zYXZlIHRoZSBoYW5kb2ZmIGluZm8gY2FtZSBmcm9tIEhERCBhcyBwYXJ0IG9mIHRoZSByZWFzc29jIHJlcQogICAgICAgIHBIYW5kb2ZmUmVxSW5mbyA9ICh0QW5pSGFuZG9mZlJlcSAqKXBNc2c7CiAgICAgICAgaWYgKE5VTEwgIT0gcEhhbmRvZmZSZXFJbmZvKQogICAgICAgIHsKICAgICAgICAgICAgLy9zYW5pdHkgY2hlY2sKICAgICAgICAgICAgaWYgKFZPU19GQUxTRSA9PSB2b3NfbWVtX2NvbXBhcmUocEhhbmRvZmZSZXFJbmZvLT5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKSkKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5jaGFubmVsID0gcEhhbmRvZmZSZXFJbmZvLT5jaGFubmVsOwogICAgICAgICAgICAgICAgY3NyX25laWdoYm9yX3JvYW1faGFuZGxlcl9hc3NpZ25faGFuZG9mZl9zcmMocE5laWdoYm9yUm9hbUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBIYW5kb2ZmUmVxSW5mbyk7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBIYW5kb2ZmUmVxSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNik7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDE7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUFTT05fT1NfUkVRVUVTVEVEX1JPQU1JTkdfTk9XKTsKICAgICAgICAgICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImNzclJvYW1PZmZsb2FkU2NhbiBmYWlsZWQiKSk7CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCByZXEgaGFzIHNhbWUgQlNTSUQgYXMgY3VycmVudCBBUCEhIikpOwogICAgICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIG1zZyBpcyBOVUxMIikpOwogICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHJvY2VlZFdpdGhIYW5kb2ZmUmVxCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBDU1IgYXMgc29vbiBhcyBpdCBnZXRzIHJzcCBiYWNrIGZvcgogICAgICAgICAgICBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QIHdpdGggcmVhc29uIFJFQVNPTl9PU19SRVFVRVNURURfUk9BTUlOR19OT1cKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUHJvY2VlZFdpdGhIYW5kb2ZmUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgLyogd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQgKi8KICAgIGlmICgoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgfHwgKCFwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBub3QgQ09OTkVDVEVEIHN0YXRlIG9yIHVPc1JlcXVlc3RlZEhhbmRvZmYgaXMgbm90IHNldC4gSWdub3JlIGl0IikpOwogICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLy9MZXQncyBnbyBhaGVhZCB3aXRoIGhhbmRvZmYKICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzSGFuZG9mZlJlcShwTWFjKTsKICAgIH0KICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgIHsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtU3RhcnRMZnJTY2FuCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpZiBIREQgcmVxdWVzdGVkIGhhbmRvZmYgZmFpbGVkIGZvciBzb21lCiAgICByZWFzb24uIHN0YXJ0IHRoZSBMRlIgbG9naWMgYXQgdGhhdCBwb2ludC5CeSB0aGUgdGltZSwgdGhpcyBmdW5jdGlvbiBpcwogICAgY2FsbGVkLCBhIFNUT1AgY29tbWFuZCBoYXMgYWxyZWFkeSBiZWVuIGlzc3VlZC4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtU3RhcnRMZnJTY2FuKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRBTklfVTggT2ZmbG9hZENtZFN0b3BSZWFzb24pCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgIEZMKCIgdU9zUmVxdWVzdGVkSGFuZG9mZj0lZCBpc0ZvcmNlZEluaXRpYWxSb2FtVG81R0g9JWQgT2ZmbG9hZENtZFN0b3BSZWFzb24gPSAlZCIpLAogICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmLAogICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0gsCiAgICAgICAgICAgT2ZmbG9hZENtZFN0b3BSZWFzb24pOwoKICAgIGlmKE9mZmxvYWRDbWRTdG9wUmVhc29uID09IFJFQVNPTl9PU19SRVFVRVNURURfUk9BTUlOR19OT1cpCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICBpZihPZmZsb2FkQ21kU3RvcFJlYXNvbiA9PSBSRUFTT05fSU5JVElBTF9GT1JDRURfUk9BTV9UT181RykKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIID0gMDsKICAgIC8qIFRoZXJlIGlzIG5vIGNhbmRpZGF0ZSBvciBXZSBhcmUgbm90IHJvYW1pbmcgTm93LgogICAgICogSW5mb3JtIHRoZSBGVyB0byByZXN0YXJ0IFJvYW0gT2ZmbG9hZCBTY2FuICAqLwogICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fTk9fQ0FORF9GT1VORF9PUl9OT1RfUk9BTUlOR19OT1cpOwoKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CiNlbmRpZiAvL1dMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAojZW5kaWYgLyogV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcgKi8K