LyoKICogQ29weXJpZ2h0IChjKSAyMDExLTIwMTcgVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFByZXZpb3VzbHkgbGljZW5zZWQgdW5kZXIgdGhlIElTQyBsaWNlbnNlIGJ5IFF1YWxjb21tIEF0aGVyb3MsIEluYy4KICoKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IKICogYW55IHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUKICogYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsCiAqIGNvcGllcy4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTAogKiBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVECiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKICogQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SCiAqIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgovKgogKiBUaGlzIGZpbGUgd2FzIG9yaWdpbmFsbHkgZGlzdHJpYnV0ZWQgYnkgUXVhbGNvbW0gQXRoZXJvcywgSW5jLgogKiB1bmRlciBwcm9wcmlldGFyeSB0ZXJtcyBiZWZvcmUgQ29weXJpZ2h0IG93bmVyc2hpcCB3YXMgYXNzaWduZWQKICogdG8gdGhlIExpbnV4IEZvdW5kYXRpb24uCiAqLwoKLyoqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKiAKICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKiAgCgogIAogICAgXGZpbGUgY3NyTmVpZ2hib3JSb2FtLmMKICAKICAgIEltcGxlbWVudGF0aW9uIGZvciB0aGUgc2ltcGxlIHJvYW1pbmcgYWxnb3JpdGhtIGZvciA4MDIuMTFyIEZhc3QgdHJhbnNpdGlvbnMgYW5kIExlZ2FjeSByb2FtaW5nIGZvciBBbmRyb2lkIHBsYXRmb3JtLgogIAogICAgQ29weXJpZ2h0IChDKSAyMDEwIFF1YWxjb21tLCBJbmNvcnBvcmF0ZWQKICAKIAogICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICAgICAgICAgICAgICAgICAgICBFRElUIEhJU1RPUlkgRk9SIEZJTEUKCgogIFRoaXMgc2VjdGlvbiBjb250YWlucyBjb21tZW50cyBkZXNjcmliaW5nIGNoYW5nZXMgbWFkZSB0byB0aGUgbW9kdWxlLgogIE5vdGljZSB0aGF0IGNoYW5nZXMgYXJlIGxpc3RlZCBpbiByZXZlcnNlIGNocm9ub2xvZ2ljYWwgb3JkZXIuCgoKCiAgd2hlbiAgICAgICAgICAgd2hvICAgICAgICAgICAgICAgICB3aGF0LCB3aGVyZSwgd2h5Ci0tLS0tLS0tLS0gICAgICAgLS0tICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjA4LzAxLzEwICAgICAgICAgIE11cmFsaSAgICAgICAgICAgICBDcmVhdGVkCgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwojaWZkZWYgV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcKI2luY2x1ZGUgIndsYW5fcWN0X3dkYS5oIgojaW5jbHVkZSAicGFsQXBpLmgiCiNpbmNsdWRlICJjc3JJbnNpZGVBcGkuaCIKI2luY2x1ZGUgInNtc0RlYnVnLmgiCiNpbmNsdWRlICJsb2dEdW1wLmgiCiNpbmNsdWRlICJzbWVRb3NJbnRlcm5hbC5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZUluc2lkZS5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9ldmVudC5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9sb2cuaCIKI2luY2x1ZGUgImNzckFwaS5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZV9BcGkuaCIKI2luY2x1ZGUgImNzck5laWdoYm9yUm9hbS5oIgojaW5jbHVkZSAibWFjVHJhY2UuaCIKI2lmIGRlZmluZWQoRkVBVFVSRV9XTEFOX0VTRSkgJiYgIWRlZmluZWQoRkVBVFVSRV9XTEFOX0VTRV9VUExPQUQpCiNpbmNsdWRlICJjc3JFc2UuaCIKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTEZSX01CQgojaW5jbHVkZSAiY3NyX3JvYW1fbWJiLmgiCiNlbmRpZgoKI2RlZmluZSBXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlOR19ERUJVRyAxCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlOR19ERUJVRwojZGVmaW5lIE5FSUdIQk9SX1JPQU1fREVCVUcgc21zTG9nCiNlbHNlCiNkZWZpbmUgTkVJR0hCT1JfUk9BTV9ERUJVRyh4Li4uKQojZW5kaWYKCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0Q2hhbm5lbEluZm8odHBDc3JOZWlnaGJvclJvYW1DaGFubmVsSW5mbyByQ2hJbmZvKTsKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDZmdMaXN0Q2hhblNjYW5Db250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKTsKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRQcmVhdXRoQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYyk7CnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24odHBBbmlTaXJHbG9iYWwgcE1hYyk7CgpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLCB2X1U4X3QgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSk7ClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgKHZfUFZPSURfdCBwQWRhcHRlciwgdl9VOF90IHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1BWT0lEX3QgcFVzZXJDdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9TN190IGF2Z1Jzc2kpOwp2b2lkIGNzck5laWdoYm9yUm9hbVJSTU5laWdoYm9yUmVwb3J0UmVzdWx0KHZvaWQgKmNvbnRleHQsIFZPU19TVEFUVVMgdm9zU3RhdHVzKTsKZUhhbFN0YXR1cyBjc3JSb2FtQ29weUNvbm5lY3RlZFByb2ZpbGUodHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkLCB0Q3NyUm9hbVByb2ZpbGUgKnBEc3RQcm9maWxlICk7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpOwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMpOwojZW5kaWYKCnZfVThfdCAqY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyh2X1U4X3Qgc3RhdGUpCnsKICAgIHN3aXRjaChzdGF0ZSkKICAgIHsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DTE9TRUQgKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyApOwogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWSApOwogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcgKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUgKTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gImVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9VTktOT1dOIjsKICAgIH0KCn0KCi8qIFN0YXRlIFRyYW5zaXRpb24gbWFjcm8gKi8KI2RlZmluZSBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKG5ld1N0YXRlKVwKe1wKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5wcmV2TmVpZ2hib3JSb2FtU3RhdGUgPSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGU7XAogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlID0gbmV3U3RhdGU7XAogICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLCBcCiAgICAgICAgICAgICAgIEZMKCJOZWlnaGJvciBSb2FtIFRyYW5zaXRpb24gZnJvbSBzdGF0ZSAlcyA9PT4gJXMiKSwgXAogICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1TdGF0ZVRvU3RyaW5nIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucHJldk5laWdoYm9yUm9hbVN0YXRlKSwgXAogICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1TdGF0ZVRvU3RyaW5nIChuZXdTdGF0ZSkpO1wKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUZyZWVOZWlnaGJvclJvYW1CU1NOb2RlCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGZyZWVzIGFsbCB0aGUgaW50ZXJuYWwgcG9pbnRlcnMgQ1NSIE5laWdoYm9yUm9hbSBCU1MgSW5mbyAKICAgICAgICAgICAgYW5kIGFsc28gZnJlZXMgdGhlIG5vZGUgaXRzZWxmCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBuZWlnaGJvclJvYW1CU1NOb2RlIC0gTmVpZ2hib3IgUm9hbSBCU1MgTm9kZSB0byBiZSBmcmVlZAoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1GcmVlTmVpZ2hib3JSb2FtQlNTTm9kZSh0cEFuaVNpckdsb2JhbCBwTWFjLCB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gbmVpZ2hib3JSb2FtQlNTTm9kZSkKewogICAgaWYgKG5laWdoYm9yUm9hbUJTU05vZGUpCiAgICB7CiAgICAgICAgaWYgKG5laWdoYm9yUm9hbUJTU05vZGUtPnBCc3NEZXNjcmlwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShuZWlnaGJvclJvYW1CU1NOb2RlLT5wQnNzRGVzY3JpcHRpb24pOwogICAgICAgICAgICBuZWlnaGJvclJvYW1CU1NOb2RlLT5wQnNzRGVzY3JpcHRpb24gPSBOVUxMOwogICAgICAgIH0KICAgICAgICB2b3NfbWVtX2ZyZWUobmVpZ2hib3JSb2FtQlNTTm9kZSk7CiAgICAgICAgbmVpZ2hib3JSb2FtQlNTTm9kZSA9IE5VTEw7CiAgICB9CgogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVtb3ZlUm9hbWFibGVBUExpc3RFbnRyeQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZW1vdmVzIGEgZ2l2ZW4gZW50cnkgZnJvbSB0aGUgZ2l2ZW4gbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcExpc3QgLSBUaGUgbGlzdCBmcm9tIHdoaWNoIHRoZSBlbnRyeSBzaG91bGQgYmUgcmVtb3ZlZAogICAgICAgICAgICBwTmVpZ2hib3JFbnRyeSAtIE5laWdoYm9yIFJvYW0gQlNTIE5vZGUgdG8gYmUgcmVtb3ZlZAoKICAgIFxyZXR1cm4gVFJVRSBpZiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCwgZWxzZSBGQUxTRQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVJlbW92ZVJvYW1hYmxlQVBMaXN0RW50cnkodHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHREYmxMaW5rTGlzdCAqcExpc3QsIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBwTmVpZ2hib3JFbnRyeSkKewogICAgaWYocExpc3QpCiAgICB7CiAgICAgICAgcmV0dXJuIGNzckxMUmVtb3ZlRW50cnkocExpc3QsICZwTmVpZ2hib3JFbnRyeS0+TGlzdCwgTExfQUNDRVNTX0xPQ0spOwogICAgfQoKICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVtb3ZpbmcgbmVpZ2hib3IgQlNTIG5vZGUgZnJvbSBsaXN0IGZhaWxlZC4gQ3VycmVudCBjb3VudCA9ICVkIiksIGNzckxMQ291bnQocExpc3QpKTsKCiAgICByZXR1cm4gZUFOSV9CT09MRUFOX0ZBTFNFOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkKCiAgICBcYnJpZWYgIEdldHMgdGhlIGVudHJ5IG5leHQgdG8gcGFzc2VkIGVudHJ5LiBJZiBOVUxMIGlzIHBhc3NlZCwgcmV0dXJuIHRoZSBlbnRyeSBpbiB0aGUgaGVhZCBvZiB0aGUgbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcExpc3QgLSBUaGUgbGlzdCBmcm9tIHdoaWNoIHRoZSBlbnRyeSBzaG91bGQgYmUgcmV0dXJuZWQKICAgICAgICAgICAgcE5laWdoYm9yRW50cnkgLSBOZWlnaGJvciBSb2FtIEJTUyBOb2RlIHdob3NlIG5leHQgZW50cnkgc2hvdWxkIGJlIHJldHVybmVkCgogICAgXHJldHVybiBOZWlnaGJvciBSb2FtIEJTUyBOb2RlIHRvIGJlIHJldHVybmVkCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0cENzck5laWdoYm9yUm9hbUJTU0luZm8gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkodHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0RGJsTGlua0xpc3QgKnBMaXN0LCB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcE5laWdoYm9yRW50cnkpCnsKICAgIHRMaXN0RWxlbSAqcEVudHJ5ID0gTlVMTDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBwUmVzdWx0ID0gTlVMTDsKICAgIAogICAgaWYocExpc3QpCiAgICB7CiAgICAgICAgaWYoTlVMTCA9PSBwTmVpZ2hib3JFbnRyeSkKICAgICAgICB7CiAgICAgICAgICAgIHBFbnRyeSA9IGNzckxMUGVla0hlYWQocExpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcEVudHJ5ID0gY3NyTExOZXh0KHBMaXN0LCAmcE5laWdoYm9yRW50cnktPkxpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgICAgICB9CiAgICAgICAgaWYocEVudHJ5KQogICAgICAgIHsKICAgICAgICAgICAgcFJlc3VsdCA9IEdFVF9CQVNFX0FERFIocEVudHJ5LCB0Q3NyTmVpZ2hib3JSb2FtQlNTSW5mbywgTGlzdCk7CiAgICAgICAgfQogICAgfQogICAgCiAgICByZXR1cm4gcFJlc3VsdDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QKCiAgICBcYnJpZWYgICBFbXB0aWVzIGFuZCBmcmVlcyBhbGwgdGhlIG5vZGVzIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0IAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcExpc3QgLSBOZWlnaGJvciBSb2FtIEJTUyBMaXN0IHRvIGJlIGVtcHRpZWQKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdCh0cEFuaVNpckdsb2JhbCBwTWFjLCB0RGJsTGlua0xpc3QgKnBMaXN0KQp7CiAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcFJlc3VsdCA9IE5VTEw7CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiRW1wdHlpbmcgdGhlIEJTUyBsaXN0LiBDdXJyZW50IGNvdW50ID0gJWQiKSwgY3NyTExDb3VudChwTGlzdCkpOwoKICAgIC8qIFBpY2sgdXAgdGhlIGhlYWQsIHJlbW92ZSBhbmQgZnJlZSB0aGUgbm9kZSB0aWxsIHRoZSBsaXN0IGJlY29tZXMgZW1wdHkgKi8KICAgIHdoaWxlICgocFJlc3VsdCA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsIHBMaXN0LCBOVUxMKSkgIT0gTlVMTCkKICAgIHsKICAgICAgICBjc3JOZWlnaGJvclJvYW1SZW1vdmVSb2FtYWJsZUFQTGlzdEVudHJ5KHBNYWMsIHBMaXN0LCBwUmVzdWx0KTsKICAgICAgICBjc3JOZWlnaGJvclJvYW1GcmVlTmVpZ2hib3JSb2FtQlNTTm9kZShwTWFjLCBwUmVzdWx0KTsKICAgIH0KICAgIHJldHVybjsKfQoKc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtVHJpZ2dlckhhbmRvZmYodHBBbmlTaXJHbG9iYWwgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbykKewogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9MRlJfTUJCCiAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5lbmFibGVfbGZyX21iYgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICAmJiAoIXBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgICAgICAmJiAoIXBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jKQojZW5kaWYKICAgICkgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLAogICAgICAgICAgICAgICBGTCgiSXNzdWluZyBwcmVhdXRoIHJlYXNzb2MiKSk7CiAgICAgICAgc3RhdHVzID0gY3NyX25laWdoYm9yX3JvYW1faXNzdWVfcHJlYXV0aF9yZWFzc29jKHBNYWMpOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CgoKI2VuZGlmCgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAmJiAhY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKQojZW5kaWYKICAgICkKICAgIHsKICAgICAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpIHx8CiAgICAgICAgICAgIChlU01FX1JPQU1fVFJJR0dFUl9GQVNUX1JPQU0gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikpCiAgICAgICAgewogICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEocE1hYyk7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4gPSBlU01FX1JPQU1fVFJJR0dFUl9OT05FOwogICAgICAgICAgICB2b3NfbWVtX3NldCgmcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1ic3NJZFswXSwKICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtYnNzSWQpLAogICAgICAgICAgICAgICAgICAgICAgICAweEZGKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCIxMVIgUmVhc3NvYyBpbmRpY2F0aW9uIHJlY2VpdmVkIGluIgogICAgICAgICAgICAgICAgICAgInVuZXhwZWN0ZWQgc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgIFZPU19BU1NFUlQoMCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQojZW5kaWYKCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCiAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYykKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEocE1hYyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkVTRSBSZWFzc29jIGluZGljYXRpb24gcmVjZWl2ZWQgaW4gdW5leHBlY3RlZCBzdGF0ZSAlcyIpLAogICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICAgICAgVk9TX0FTU0VSVCgwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiNlbmRpZgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIHx8IGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykgfHwKICAgICAgICAgICAgICAgIChlU01FX1JPQU1fVFJJR0dFUl9GQVNUX1JPQU0gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikKI2VuZGlmCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHBNYWMpOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4gPSBlU01FX1JPQU1fVFJJR0dFUl9OT05FOwogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fc2V0KCZwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbWJzc0lkWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbWJzc0lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweEZGKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkxGUiBSZWFzc29jIGluZGljYXRpb24gcmVjZWl2ZWQgaW4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmV4cGVjdGVkIHN0YXRlICVzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgICAgICAgICBWT1NfQVNTRVJUKDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKI2VuZGlmCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXF1ZXN0SGFuZG9mZihwTWFjKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5vbi0xMVIgUmVhc3NvYyBpbmRpY2F0aW9uIHJlY2VpdmVkIGluIgogICAgICAgICAgICAgICAgICAgICAgICAgICAidW5leHBlY3RlZCBzdGF0ZSAlcyBvciBSb2FtaW5nIGlzIGRpc2FibGVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQoKVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1VcGRhdGVGYXN0Um9hbWluZ0VuYWJsZWQodHBBbmlTaXJHbG9iYWwgcE1hYywgY29uc3Qgdl9CT09MX3QgZmFzdFJvYW1FbmFibGVkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBpZiAoVk9TX1RSVUUgPT0gZmFzdFJvYW1FbmFibGVkKQogICAgICAgIHsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwgUkVBU09OX0NPTk5FQ1QpOwogICAgICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgbmVpZ2hib3IgbG9va3VwIERPV04gZXZlbnQgd2l0aCBUTCwgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpOwogICAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIERPV04gZXZlbnQgb25seSAqLwogICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiAgICAgICAgICAgIGlmICghVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoVk9TX0ZBTFNFID09IGZhc3RSb2FtRW5hYmxlZCkKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkN1cnJlbnRseSBpbiBDT05ORUNURUQgc3RhdGUsIHNvIGRlcmVnaXN0ZXIgYWxsIGV2ZW50cyIpKTsKICAgICAgICAgICAgLyogRGUtcmVnaXN0ZXIgZXhpc3RpbmcgbG9va3VwIFVQL0RPV04sIFJzc2kgaW5kaWNhdGlvbnMgKi8KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUT1AsIFJFQVNPTl9ESVNDT05ORUNURUQpOwogICAgICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJDdXJyZW50bHkgaW4gSU5JVCBzdGF0ZSwgTm90aGluZyB0byBkbyIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsCiAgICAgICAgRkwoIlVuZXhwZWN0ZWQgc3RhdGUgJXMsIHJldHVybmluZyBmYWlsdXJlIiksCiAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICB9CiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVVwZGF0ZUVzZU1vZGVFbmFibGVkKHRwQW5pU2lyR2xvYmFsIHBNYWMsIGNvbnN0IHZfQk9PTF90IGVzZU1vZGUpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGlmIChWT1NfVFJVRSA9PSBlc2VNb2RlKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgbmVpZ2hib3IgbG9va3VwIERPV04gZXZlbnQgd2l0aCBUTCwgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIERPV04gZXZlbnQgb25seSAqLwogICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiAgICAgICAgICAgIGlmICghVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoVk9TX0ZBTFNFID09IGVzZU1vZGUpCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJDdXJyZW50bHkgaW4gQ09OTkVDVEVEIHN0YXRlLCBzbyBkZXJlZ2lzdGVyIGFsbCBldmVudHMiKSk7CiAgICAgICAgICAgIC8qIERlLXJlZ2lzdGVyIGV4aXN0aW5nIGxvb2t1cCBVUC9ET1dOLCBSc3NpIGluZGljYXRpb25zICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLCBSRUFTT05fRElTQ09OTkVDVEVEKTsKICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIElOSVQgc3RhdGUsIE5vdGhpbmcgdG8gZG8iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiVW5leHBlY3RlZCBzdGF0ZSAlZCwgcmV0dXJuaW5nIGZhaWx1cmUiKSwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCiNlbmRpZgoKClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtU2V0TG9va3VwUnNzaVRocmVzaG9sZCh0cEFuaVNpckdsb2JhbCBwTWFjLCB2X1U4X3QgbmVpZ2hib3JMb29rdXBSc3NpVGhyZXNob2xkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJDdXJyZW50bHkgaW4gQ09OTkVDVEVEIHN0YXRlLCBzbyBkZXJlZ2lzdGVyIGFsbCBhbmQgcmUtcmVnaXN0ZXIgZm9yIERPV04gZXZlbnQgYWdhaW4iKSk7CgogICAgICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPSBuZWlnaGJvckxvb2t1cFJzc2lUaHJlc2hvbGQ7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQ7CgogICAgICAgIC8qIERlLXJlZ2lzdGVyIGV4aXN0aW5nIGxvb2t1cCBVUC9ET1dOLCBSc3NpIGluZGljYXRpb25zICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfVVBEQVRFX0NGRywgUkVBU09OX0xPT0tVUF9USFJFU0hfQ0hBTkdFRCk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiNlbmRpZgogICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CgogICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICBGTCgiUmVnaXN0ZXJpbmcgbmVpZ2hib3IgbG9va3VwIERPV04gZXZlbnQgd2l0aCBUTCwgUlNTSSA9ICVkIiksCiAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCk7CiAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLAogICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKICAgICAgICAgICBpZiAoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgIHsKICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIiBDb3VsZG4ndCByZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIH0KI2VuZGlmCiAgICB9CiAgICBlbHNlIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIElOSVQgc3RhdGUsIHNhZmUgdG8gc2V0IGxvb2t1cFJzc2kgdGhyZXNob2xkIikpOwogICAgICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPSBuZWlnaGJvckxvb2t1cFJzc2lUaHJlc2hvbGQ7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQ7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLAogICAgICAgIEZMKCJVbmV4cGVjdGVkIHN0YXRlICVzLCByZXR1cm5pbmcgZmFpbHVyZSIpLAogICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjawoKICAgIFxicmllZiBSZWFzc29jIGNhbGxiYWNrIGludm9rZWQgYnkgVEwgb24gY3Jvc3NpbmcgdGhlIHJlZ2lzdGVyZWQgcmUtYXNzb2MgdGhyZXNob2xkLgogICAgICAgICAgIERpcmVjdGx5IHRyaWdnZXJlIEhPIGluIGNhc2Ugb2Ygbm9uLTExciBhc3NvY2lhdGlvbgogICAgICAgICAgIEluIGNhc2Ugb2YgMTFSIGFzc29jaWF0aW9uLCB0cmlnZ2VycyBhIHByZS1hdXRoIGV2ZW50dWFsbHkgZm9sbG93ZWQgYnkgYWN0dWFsIEhPCgogICAgXHBhcmFtICBwQWRhcHRlciAtIFZPUyBDb250ZXh0CiAgICAgICAgICAgIHRyYWZmaWNTdGF0dXMgLSBVUC9ET1dOIGluZGljYXRpb24gZnJvbSBUTAogICAgICAgICAgICBwVXNlckN0eHQgLSBQYXJhbWV0ZXIgZm9yIGNhbGxiYWNrIHJlZ2lzdGVyZWQgZHVyaW5nIGNhbGxiYWNrIHJlZ2lzdHJhdGlvbi4gU2hvdWxkIGJlIHBNYWMKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrKHZfUFZPSURfdCBwQWRhcHRlciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1U4X3QgdHJhZmZpY1N0YXR1cywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1BWT0lEX3QgcFVzZXJDdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9TN190ICAgYXZnUnNzaSkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKCBwVXNlckN0eHQgKTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7ICAgCgogICAgaWYgKGVTTUVfUk9BTV9UUklHR0VSX0ZBU1RfUk9BTSAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkRlcmVnaXN0ZXJpbmcgRE9XTiBldmVudCByZWFzc29jIGNhbGxiYWNrIHdpdGggVEwuIFRocmVzaG9sZCBSU1NJID0gJWQgUmVwb3J0ZWQgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICBhdmdSc3NpKTsKCiAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgIH0KCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmN2ZCByZWFzc29jIG5vdGlmaWNhdGlvbi1kZXJlZ2lzdGVyIFVQIGluZGljYXRpb24uIFRocmVzaG9sZCBSU1NJID0gJWQgUmVwb3J0ZWQgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpLCBhdmdSc3NpKTsKICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgewogICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IGRlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICB9CiAgICB9CiAgICAvKiBXZSBkb250IG5lZWQgdG8gcnVuIHRoaXMgdGltZXIgYW55IG1vcmUuICovCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CgogICAgY3NyTmVpZ2hib3JSb2FtVHJpZ2dlckhhbmRvZmYocE1hYywgcE5laWdoYm9yUm9hbUluZm8pOwoKICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qQ2xlYW5VUCBSb3V0aW5lcyovCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0Q2hhbm5lbEluZm8odHBDc3JOZWlnaGJvclJvYW1DaGFubmVsSW5mbyByQ2hJbmZvKQp7CiAgICAgICAgaWYgKChyQ2hJbmZvLT5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPT0gRkFMU0UpICYmCiAgICAgICAgICAgICAgICAgICAgICAgIChyQ2hJbmZvLT5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpKQogICAgICAgIHsKICAgICAgICAgICAgICAgIHJDaEluZm8tPmN1cnJlbnRDaGFuSW5kZXggPSBDU1JfTkVJR0hCT1JfUk9BTV9JTlZBTElEX0NIQU5ORUxfSU5ERVg7CiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwoKICAgICAgICAgICAgICAgIGlmIChyQ2hJbmZvLT5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KQogICAgICAgICAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUockNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CgogICAgICAgICAgICAgICAgckNoSW5mby0+Y3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIH0KICAgICAgICBlbHNlIAogICAgICAgIHsKICAgICAgICAgICAgICAgIHJDaEluZm8tPmN1cnJlbnRDaGFuSW5kZXggPSAwOwogICAgICAgICAgICAgICAgckNoSW5mby0+Y2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgIH0KfQoKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDZmdMaXN0Q2hhblNjYW5Db250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICAgICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgICAgIC8qIFN0b3AgbmVpZ2hib3Igc2NhbiB0aW1lciAqLwogICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwoKICAgICAgICAvKiBTdG9wIG5laWdoYm9yIHNjYW4gcmVzdWx0cyByZWZyZXNoIHRpbWVyICovCiAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwoKICAgICAgICAvKiBTdG9wIGVtcHR5IHNjYW4gcmVzdWx0cyByZWZyZXNoIHRpbWVyICovCiAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwoKICAgICAgICAvKiBBYm9ydCBhbnkgb25nb2luZyBzY2FuICovCiAgICAgICAgaWYgKGVBTklfQk9PTEVBTl9UUlVFID09IHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUnNwUGVuZGluZykKICAgICAgICB7CiAgICAgICAgICAgIGNzclNjYW5BYm9ydE1hY1NjYW4ocE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQ1NSX1NDQU5fQUJPUlRfREVGQVVMVCk7CiAgICAgICAgfQogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICAgICAgLyogUmVzZXQgcm9hbSBjaGFubmVsIGxpc3QgaW5mb3JtYXRpb24gKi8KICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXNldENoYW5uZWxJbmZvKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvKTsKfQoKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRQcmVhdXRoQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIC8qIFB1cmdlIHByZS1hdXRoIGZhaWwgbGlzdCAqLwogICAgICAgIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxlZExpc3QocE1hYyk7CiNlbmRpZgoKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA9IDA7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgICAgIC8qIERvIG5vdCBmcmVlIHVwIHRoZSBwcmVhdXRoIGRvbmUgbGlzdCBoZXJlICovCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPSAwOwogICAgICAgIHZvc19tZW1femVybyhwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwojZW5kaWYKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCA9IDA7CiAgICB2b3NfbWVtX3plcm8oJnBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mbywgc2l6ZW9mKHRDc3JIYW5kb2ZmUmVxdWVzdCkpOwojZW5kaWYKCn0KCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgICAgIFZPU19TVEFUVVMgICAgICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICAgICAgICAgICAgICAgICBGTCgiRGVyZWdpc3RlciBuZWlnaGJvciBsb29rdXAgVVAgY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkIiksIAogICAgICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpKTsKCiAgICAgICAgLyogRGVyZWdpc3RlciByZWFzc29jIGNhbGxiYWNrLiBJZ25vcmUgcmV0dXJuIHN0YXR1cyAqLwogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwoKICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkNvdWxkbid0IGRlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgIH0KCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICAgICAgICAgICAgICAgICBGTCgiRGVyZWdpc3RlcmluZyByZWFzc29jIERPV04gY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkIiksIAogICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSkpOwoKICAgICAgICAvKiBEZXJlZ2lzdGVyIHJlYXNzb2MgY2FsbGJhY2suIElnbm9yZSByZXR1cm4gc3RhdHVzICovCiAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAKICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwoKICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIiBDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjayB3aXRoICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICB9CgogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkRlcmVnaXN0ZXJpbmcgbmVpZ2hib3JMb29rdXAgRE9XTiBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpKTsKCiAgICAgICAgLyogRGVyZWdpc3RlciBuZWlnaGJvciBsb29rdXAgY2FsbGJhY2suIElnbm9yZSByZXR1cm4gc3RhdHVzICovCiAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAKICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCIgQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICB9CgogICAgICAgIC8qIFJlc2V0IHRocmVzaG9sZHMgb25seSBhZnRlciBkZXJlZ2lzdGVyaW5nIERPV04gZXZlbnQgZnJvbSBUTCAqLwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPSAKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQ7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9IDA7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpID0gMDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gREVGQVVMVF9TQ0FOOwojZW5kaWYKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiB3aWxsIHJlc2V0IHRoZSBuZWlnaGJvciByb2FtIGNvbnRyb2wgaW5mbyBkYXRhIHN0cnVjdHVyZXMuIAogICAgICAgICAgICBUaGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBpbnZva2VkIHdoZW5ldmVyIHdlIG1vdmUgdG8gQ09OTkVDVEVEIHN0YXRlIGZyb20gCiAgICAgICAgICAgIGFueSBzdGF0ZSBvdGhlciB0aGFuIElOSVQgc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENoYW5uZWxJbmZvKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvKTsKICAgIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICAKIC8qIFdlIGRvbnQgbmVlZCB0byBydW4gdGhpcyB0aW1lciBhbnkgbW9yZS4gKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgLyogRG8gbm90IGZyZWUgdXAgdGhlIHByZWF1dGggZG9uZSBsaXN0IGhlcmUgKi8KICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydCA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZyA9IDA7CiAgICB2b3NfbWVtX3plcm8ocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm8sIHNpemVvZih0Q3NyTmVpZ2hib3JSZXBvcnRCc3NJbmZvKSAqIE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKTsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0ggPSAwOwogICAgdm9zX21lbV96ZXJvKCZwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8sIHNpemVvZih0Q3NySGFuZG9mZlJlcXVlc3QpKTsKI2VuZGlmCn0KCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRSZXBvcnRTY2FuU3RhdGVDb250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQgICAgICAgICAgICA9ICAgQ1NSX1NFU1NJT05fSURfSU5WQUxJRDsKICAgIHZvc19tZW1fc2V0KHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRDc3JCc3NpZCksIDApOwojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNWT0FkbWl0dGVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE5laWdoYm9yUm9hbUluZm8tPk1pblFCc3NMb2FkUmVxdWlyZWQgPSAwOwojZW5kaWYKCiAgICAvKiBTdG9wIHNjYW4gcmVmcmVzaCB0aW1lciAqLwogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgLyogU3RvcCBlbXB0eSBzY2FuIHJlc3VsdHMgcmVmcmVzaCB0aW1lciAqLwogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwogICAgIC8qIFB1cmdlIHJvYW1hYmxlIEFQIGxpc3QgKi8KICAgICAgIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7IAogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVzZXRJbml0U3RhdGVDb250cm9sSW5mbwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiB3aWxsIHJlc2V0IHRoZSBuZWlnaGJvciByb2FtIGNvbnRyb2wgaW5mbyBkYXRhIHN0cnVjdHVyZXMuIAogICAgICAgICAgICBUaGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBpbnZva2VkIHdoZW5ldmVyIHdlIG1vdmUgdG8gQ09OTkVDVEVEIHN0YXRlIGZyb20gCiAgICAgICAgICAgIElOSVQgc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0SW5pdFN0YXRlQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwoKICAgIC8qIEluIGFkZGl0aW9uIHRvIHRoZSBhYm92ZSByZXNldHMsIHdlIHNob3VsZCBjbGVhciBvZmYgdGhlIGN1ckFQQnNzSWQvU2Vzc2lvbiBJRCBpbiB0aGUgdGltZXJzICovCiAgICBjc3JOZWlnaGJvclJvYW1SZXNldFJlcG9ydFNjYW5TdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwp9CgoKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQnNzSWRTY2FuRmlsdGVyCgogICAgXGJyaWVmICBUaGlzIEFQSSBpcyB1c2VkIHRvIHByZXBhcmUgYSBmaWx0ZXIgdG8gb2J0YWluIHNjYW4gcmVzdWx0cyB3aGVuIAogICAgICAgICAgICB3ZSBjb21wbGV0ZSB0aGUgc2NhbiBpbiB0aGUgUkVQT1JUX1NDQU4gc3RhdGUgYWZ0ZXIgcmVjZWl2aW5nIGEgCiAgICAgICAgICAgIHZhbGlkIG5laWdoYm9yIHJlcG9ydCBmcm9tIEFQLiBUaGlzIGZpbHRlciBpbmNsdWRlcyBCU1NJRHMgcmVjZWl2ZWQgZnJvbSAKICAgICAgICAgICAgdGhlIG5laWdoYm9yIHJlcG9ydCBmcm9tIHRoZSBBUCBpbiBhZGRpdGlvbiB0byB0aGUgb3RoZXIgZmlsdGVyIHBhcmFtZXRlcnMgCiAgICAgICAgICAgIGNyZWF0ZWQgZnJvbSBjb25uZWN0ZWQgcHJvZmlsZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcFNjYW5GaWx0ZXIgLSBTY2FuIGZpbHRlciB0byBiZSBmaWxsZWQgYW5kIHJldHVybmVkCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc2Z1bCBmaWx0ZXIgY3JlYXRpb24sIGNvcnJlc3BvbmRpbmcgZXJyb3IgCiAgICAgICAgICAgIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Cc3NJZFNjYW5GaWx0ZXIodHBBbmlTaXJHbG9iYWwgcE1hYywgdENzclNjYW5SZXN1bHRGaWx0ZXIgKnBTY2FuRmlsdGVyKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBTklfVTggaSA9IDA7CgogICAgVk9TX0FTU0VSVChwU2NhbkZpbHRlciAhPSBOVUxMKTsKICAgIGlmIChwU2NhbkZpbHRlciA9PSBOVUxMKQogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgdm9zX21lbV96ZXJvKHBTY2FuRmlsdGVyLCBzaXplb2YodENzclNjYW5SZXN1bHRGaWx0ZXIpKTsKCiAgICBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzID0gcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0OwogICAgcFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0U2lyTWFjQWRkcikgKiBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzKTsKICAgIGlmIChOVUxMID09IHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBCU1NJRCBtZW0gYWxsb2MgZmFpbGVkIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICB9CgogICAgdm9zX21lbV96ZXJvKHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikgKiBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzKTsKCiAgICAvKiBQb3B1bGF0ZSB0aGUgQlNTSUQgZnJvbSBOZWlnaGJvciBCU1MgaW5mbyByZWNlaXZlZCBmcm9tIG5laWdoYm9yIHJlcG9ydCAqLwogICAgZm9yIChpID0gMDsgaSA8IHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHM7IGkrKykKICAgIHsKICAgICAgICB2b3NfbWVtX2NvcHkoJnBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWRbaV0sIAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm9baV0ubmVpZ2hib3JCc3NJZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICB9CgogICAgLyogRmlsbCBvdGhlciBnZW5lcmFsIHNjYW4gZmlsdGVyIHBhcmFtcyAqLwogICAgcmV0dXJuIGNzck5laWdoYm9yUm9hbVByZXBhcmVTY2FuUHJvZmlsZUZpbHRlcihwTWFjLCBwU2NhbkZpbHRlcik7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsTGlzdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBlbXB0aWVzIHRoZSBwcmVhdXRoIGZhaWwgbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbExpc3QodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiUHVyZ2luZyB0aGUgcHJlYXV0aCBmYWlsIGxpc3QiKSk7CiAgICB3aGlsZSAocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MpCiAgICB7CiAgICAgICAgdm9zX21lbV96ZXJvKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5tYWNBZGRyZXNzW3BOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzLTFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcy0tOwogICAgfQogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQWRkQnNzSWRUb1ByZWF1dGhGYWlsTGlzdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBhZGRzIHRoZSBnaXZlbiBCU1NJRCB0byB0aGUgUHJlYXV0aCBmYWlsIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIGJzc0lkIC0gQlNTSUQgdG8gYmUgYWRkZWQgdG8gdGhlIHByZWF1dGggZmFpbCBsaXN0CgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGVIQUxfU1RBVFVTX0ZBSUxVUkUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUFkZEJzc0lkVG9QcmVhdXRoRmFpbExpc3QodHBBbmlTaXJHbG9iYWwgcE1hYywgdFNpck1hY0FkZHIgYnNzSWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIiBBZGRlZCBCU1NJRCAiTUFDX0FERFJFU1NfU1RSIiB0byBQcmVhdXRoIGZhaWxlZCBsaXN0IiksCiAgICAgICAgICAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKGJzc0lkKSk7CgoKICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MgKyAxKSA+CiAgICAgICAgICAgIE1BWF9OVU1fUFJFQVVUSF9GQUlMX0xJU1RfQUREUkVTUykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlByZWF1dGggZmFpbCBsaXN0IGFscmVhZHkgZnVsbC4uIENhbm5vdCBhZGQgbmV3IG9uZSIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHZvc19tZW1fY29weShwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubWFjQWRkcmVzc1sKICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3NdLAogICAgICAgICAgICAgICAgIGJzc0lkLAogICAgICAgICAgICAgICAgIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MrKzsKICAgIAogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gY2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIE1BQyBhZGRyZXNzIGlzIGFscmVhZHkgCiAgICAgICAgICAgIHByZXNlbnQgaW4gdGhlIHByZWF1dGggZmFpbCBsaXN0IGFuZCByZXR1cm5zIFRSVUUvRkFMU0UgYWNjb3JkaW5nbHkKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRSBpZiBwcmVhdXRoIGNhbmRpZGF0ZSwgZUFOSV9CT09MRUFOX0ZBTFNFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUlzUHJlYXV0aENhbmRpZGF0ZSh0cEFuaVNpckdsb2JhbCBwTWFjLCB0U2lyTWFjQWRkciBic3NJZCkKewogICAgdEFOSV9VOCBpID0gMDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICB7CiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwogICAgfQojZW5kaWYKICAgIGlmICgwID09IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzKQogICAgICAgIHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRTsKICAgIAogICAgZm9yIChpID0gMDsgaSA8IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzOyBpKyspCiAgICB7CiAgICAgICAgaWYgKFZPU19UUlVFID09IHZvc19tZW1fY29tcGFyZShwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubWFjQWRkcmVzc1tpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnNzSWQsIHNpemVvZih0U2lyTWFjQWRkcikpKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiQlNTSUQgIk1BQ19BRERSRVNTX1NUUiIgYWxyZWFkeSBwcmVzZW50IGluIHByZWF1dGggZmFpbCBsaXN0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKGJzc0lkKSk7CiAgICAgICAgICAgIHJldHVybiBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUlzc3VlUHJlYXV0aFJlcQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpc3N1ZXMgcHJlYXV0aCByZXF1ZXN0IHRvIFBFIHdpdGggdGhlIDFzdCBBUCBlbnRyeSBpbiB0aGUgCiAgICAgICAgICAgIHJvYW1hYmxlIEFQIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGVIQUxfU1RBVFVTX0ZBSUxVUkUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gICAgcE5laWdoYm9yQnNzTm9kZTsKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSX01FVFJJQ1MKICAgIHRDc3JSb2FtSW5mbyAqcm9hbUluZm87CiNlbmRpZgogICAgCiAgICAvKiBUaGlzIG11c3Qgbm90IGJlIHRydWUgaGVyZSAqLwogICAgVk9TX0FTU0VSVChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZyA9PSBlQU5JX0JPT0xFQU5fRkFMU0UpOwoKICAgIC8qIElzc3VlIFByZWF1dGggcmVxdWVzdCB0byBQRSBoZXJlICovCiAgICAvKiBOZWVkIHRvIGlzc3VlIHRoZSBwcmVhdXRoIHJlcXVlc3Qgd2l0aCB0aGUgQlNTSUQgdGhhdCBpcyB0aGVyZSBpbiB0aGUgaGVhZCBvZiB0aGUgcm9hbWFibGUgQVAgbGlzdCAqLwogICAgLyogUGFyYW1ldGVycyB0aGF0IHNob3VsZCBiZSBwYXNzZWQgYXJlIEJTU0lELCBDaGFubmVsIG51bWJlciBhbmQgdGhlIG5laWdoYm9yU2NhblBlcmlvZChwcm9iYWJseSkgKi8KICAgIC8qIElmIHJvYW1hYmxlQVBMaXN0IGdldHMgZW1wdHksIHNob3VsZCB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlICovCiAgICBwTmVpZ2hib3JCc3NOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgTlVMTCk7CgogICAgaWYgKE5VTEwgPT0gcE5laWdoYm9yQnNzTm9kZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIlJvYW1hYmxlIEFQIGxpc3QgaXMgZW1wdHkuLiAiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBlbHNlCiAgICB7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSX01FVFJJQ1MKICAgICAgICAvKiBMRlIgbWV0cmljcyAtIHByZS1hdXRoIGluaXRpYXRpb24gbWV0cmljLgogICAgICAgICAgIFNlbmQgdGhlIGV2ZW50IHRvIHN1cHBsaWNhbnQgdGhhdCBwcmUtYXV0aCB3YXMgaW5pdGlhdGVkICovCiAgICAgICAgcm9hbUluZm8gPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodENzclJvYW1JbmZvKSk7CiAgICAgICAgaWYgKE5VTEwgPT0gcm9hbUluZm8pCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZCEiKSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fY29weSgodm9pZCAqKXJvYW1JbmZvLT5ic3NpZCwKICAgICAgICAgICAgICAgICh2b2lkICopcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwKICAgICAgICAgICAgICAgIHNpemVvZih0Q3NyQnNzaWQpKTsKICAgICAgICAgICAgY3NyUm9hbUNhbGxDYWxsYmFjayhwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvYW1JbmZvLCAwLCBlQ1NSX1JPQU1fUFJFQVVUSF9JTklUX05PVElGWSwgMCk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShyb2FtSW5mbyk7CiAgICAgICAgfQojZW5kaWYKCiAgICAgICAgc3RhdHVzID0gY3NyUm9hbUVucXVldWVQcmVhdXRoKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsIHBOZWlnaGJvckJzc05vZGUtPnBCc3NEZXNjcmlwdGlvbiwKICAgICAgICAgICAgICAgIGVDc3JQZXJmb3JtUHJlYXV0aCwgZUFOSV9CT09MRUFOX1RSVUUpOwoKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIkJlZm9yZSBQcmUtQXV0aDogQlNTSUQgIk1BQ19BRERSRVNTX1NUUiIsIENoOiVkIiksCiAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKHBOZWlnaGJvckJzc05vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQpLAogICAgICAgICAgICAgICAoaW50KXBOZWlnaGJvckJzc05vZGUtPnBCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbElkKTsKCiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTZW5kIFByZWF1dGggcmVxdWVzdCB0byBQRSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgc3RhdHVzKTsKICAgICAgICAgICAgcmV0dXJuIHN0YXR1czsKICAgICAgICB9CiAgICB9CiAgICAKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX1RSVUU7CgogICAgLyogSW5jcmVtZW50IHRoZSBwcmVhdXRoIHJldHJ5IGNvdW50ICovCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcysrOwogICAgCiAgICAvKiBUcmFuc2l0aW9uIHRoZSBzdGF0ZSB0byBwcmVhdXRoZW50aWNhdGluZyAqLwogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcpCiAgICAKICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QcmVhdXRoUnNwSGFuZGxlcgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBoYW5kbGUgdGhlIFByZWF1dGggcmVzcG9uc2UgZnJvbSBQRQogICAgICAgICAgICBFdmVyeSBwcmVhdXRoIGlzIGFsbG93ZWQgbWF4IDMgdHJpZXMgaWYgaXQgZmFpbHMuIElmIGEgYnNzaWQgZmFpbGVkIAogICAgICAgICAgICBmb3IgbW9yZSB0aGFuIE1BWF9UUklFUywgd2Ugd2lsbCByZW1vdmUgaXQgZnJvbSB0aGUgbGlzdCBhbmQgdHJ5IAogICAgICAgICAgICB3aXRoIHRoZSBuZXh0IG5vZGUgaW4gdGhlIHJvYW1hYmxlIEFQIGxpc3QgYW5kIGFkZCB0aGUgQlNTSUQgdG8gcHJlLWF1dGggZmFpbGVkIAogICAgICAgICAgICBsaXN0LiBJZiBubyBtb3JlIGVudHJpZXMgcHJlc2VudCBpbiAKICAgICAgICAgICAgcm9hbWFibGUgQVAgbGlzdCwgdHJhbnNpdGlvbiB0byBSRVBPUlRfU0NBTiBzdGF0ZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgbGltU3RhdHVzIC0gZVNJUl9TVUNDRVNTL2VTSVJfRkFJTFVSRS9lU0lSX0xJTV9NQVhfU1RBX1JFQUNIRURfRVJST1IvCiAgICAgICAgICAgICAgICAgICAgIGVTSVRfTElNX0FVVEhfUlNQX1RJTUVPVVQgc3RhdHVzIGZyb20gUEUKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcyAoaS5lLiBwcmUtYXV0aCBwcm9jZXNzZWQpLAogICAgICAgICAgICBlSEFMX1NUQVRVU19GQUlMVVJFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1QcmVhdXRoUnNwSGFuZGxlcih0cEFuaVNpckdsb2JhbCBwTWFjLCB0U2lyUmV0U3RhdHVzIGxpbVN0YXR1cykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzICBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwogICAgZUhhbFN0YXR1cyAgcHJlYXV0aFByb2Nlc3NlZCA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcFByZWF1dGhSc3BOb2RlID0gTlVMTDsKICAgIHRDc3JSb2FtU2Vzc2lvbiAqcFNlc3Npb247CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSX01FVFJJQ1MKICAgIHRDc3JSb2FtSW5mbyAqcm9hbUluZm87CiNlbmRpZgoKICAgIGlmIChlQU5JX0JPT0xFQU5fRkFMU0UgPT0gcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcpCiAgICB7CiAgICAgICAgICAgIAogICAgICAgICAgICAvKiBUaGlzIGNhbiBoYXBwZW4gd2hlbiB3ZSBkaXNjb25uZWN0IGltbWVkaWF0ZWx5CiAgICAgICAgICAgICAqIGFmdGVyIHNlbmRpbmcgYSBwcmUtYXV0aCByZXF1ZXN0LiBEdXJpbmcgcHJvY2Vzc2luZwogICAgICAgICAgICAgKiBvZiB0aGUgZGlzY29ubmVjdCBjb21tYW5kLCB3ZSB3b3VsZCBoYXZlIHJlc2V0CiAgICAgICAgICAgICAqIHByZWF1dGhSc3BQZW5kaW5nIGFuZCB0cmFuc2l0aW9uZWQgdG8gSU5JVCBzdGF0ZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiVW5leHBlY3RlZCBwcmUtYXV0aCByZXNwb25zZSBpbiBzdGF0ZSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgICAgIHByZWF1dGhQcm9jZXNzZWQgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICBnb3RvIERFUV9QUkVBVVRIOwogICAgfSAgICAKCiAgICAvLyBXZSBjYW4gcmVjZWl2ZSBpdCBpbiB0aGVzZSAyIHN0YXRlcy4KICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlICE9IGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIRU5USUNBVElORykgJiYKICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlICE9IGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLAogICAgICAgIEZMKCJQcmVhdXRoIHJlc3BvbnNlIHJlY2VpdmVkIGluIHN0YXRlICVzIiksCiAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgcHJlYXV0aFByb2Nlc3NlZCA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgZ290byBERVFfUFJFQVVUSDsKICAgIH0KCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICBpZiAoZVNJUl9TVUNDRVNTID09IGxpbVN0YXR1cykKICAgIHsKICAgICAgICBwUHJlYXV0aFJzcE5vZGUgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCBOVUxMKTsKICAgIH0KICAgIGlmICgoZVNJUl9TVUNDRVNTID09IGxpbVN0YXR1cykgJiYgKE5VTEwgIT0gcFByZWF1dGhSc3BOb2RlKSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJQcmVhdXRoIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkgYWZ0ZXIgJWQgdHJpZXMiKSwgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMpOwoKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIkFmdGVyIFByZS1BdXRoOiBCU1NJRCAiTUFDX0FERFJFU1NfU1RSIiwgQ2g6JWQiKSwKICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkocFByZWF1dGhSc3BOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkKSwKICAgICAgICAgICAgICAgKGludClwUHJlYXV0aFJzcE5vZGUtPnBCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbElkKTsKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSX01FVFJJQ1MKICAgICAgICAvKiBMRlIgbWV0cmljcyAtIHByZS1hdXRoIGNvbXBsZXRpb24gbWV0cmljLgogICAgICAgICAgIFNlbmQgdGhlIGV2ZW50IHRvIHN1cHBsaWNhbnQgdGhhdCBwcmUtYXV0aCBzdWNjZXNzZnVsbHkgY29tcGxldGVkICovCiAgICAgICAgcm9hbUluZm8gPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodENzclJvYW1JbmZvKSk7CiAgICAgICAgaWYgKE5VTEwgPT0gcm9hbUluZm8pCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZCEiKSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fY29weSgodm9pZCAqKXJvYW1JbmZvLT5ic3NpZCwKICAgICAgICAgICAgICAgICh2b2lkICopcFByZWF1dGhSc3BOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkLAogICAgICAgICAgICAgICAgc2l6ZW9mKHRDc3JCc3NpZCkpOwogICAgICAgICAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICByb2FtSW5mbywgMCwgZUNTUl9ST0FNX1BSRUFVVEhfU1RBVFVTX1NVQ0NFU1MsIDApOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocm9hbUluZm8pOwogICAgICAgIH0KI2VuZGlmCgogICAgICAgIC8qIFByZWF1dGggY29tcGV0ZXIgc3VjY2Vzc2Z1bGx5LiBJbnNlcnQgdGhlIHByZWF1dGhlbnRpY2F0ZWQgbm9kZSB0byB0YWlsIG9mIHByZUF1dGhEb25lTGlzdCAqLwogICAgICAgIGNzck5laWdoYm9yUm9hbVJlbW92ZVJvYW1hYmxlQVBMaXN0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgcFByZWF1dGhSc3BOb2RlKTsKICAgICAgICBjc3JMTEluc2VydFRhaWwoJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCwgJnBQcmVhdXRoUnNwTm9kZS0+TGlzdCwgTExfQUNDRVNTX0xPQ0spOwoKICAgICAgICAvKiBQcmUtYXV0aCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LiBUcmFuc2l0aW9uIHRvIFBSRUFVVEggRG9uZSBzdGF0ZSAqLwogICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORSkKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA9IDA7CgogICAgICAgIC8qIFRoZSBjYWxsZXIgb2YgdGhpcyBmdW5jdGlvbiB3b3VsZCBzdGFydCBhIHRpbWVyIGFuZCBieSB0aGUgdGltZSBpdCBleHBpcmVzLCBzdXBwbGljYW50IHNob3VsZCAKICAgICAgICAgICBoYXZlIHByb3ZpZGVkIHRoZSB1cGRhdGVkIEZUSUVzIHRvIFNNRS4gU28sIHdoZW4gaXQgZXhwaXJlcywgaGFuZG9mZiB3aWxsIGJlIHRyaWdnZXJlZCB0aGVuICovCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvICAgIHBOZWlnaGJvckJzc05vZGUgPSBOVUxMOwogICAgICAgIHRMaXN0RWxlbSAgICAgICAgICAgICAgICAgICAqcEVudHJ5OwoKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlByZWF1dGggZmFpbGVkIHJldHJ5IG51bWJlciAlZCwgc3RhdHVzID0gMHgleCIpLAogICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcywgbGltU3RhdHVzKTsKICAgICAgICAKICAgICAgICAvKiBQcmVhdXRoIGZhaWxlZC4gQWRkIHRoZSBic3NJZCB0byB0aGUgcHJlQXV0aCBmYWlsZWQgbGlzdCBNQUMgQWRkcmVzcy4gQWxzbyByZW1vdmUgdGhlIEFQIGZyb20gcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPj0KICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX01BWF9OVU1fUFJFQVVUSF9SRVRSSUVTKSB8fAogICAgICAgICAgICAoZVNJUl9MSU1fTUFYX1NUQV9SRUFDSEVEX0VSUk9SID09IGxpbVN0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICAvKiBXZSBhcmUgZ29pbmcgdG8gcmVtb3ZlIHRoZSBub2RlIGFzIGl0IGZhaWxzIGZvciBtb3JlIHRoYW4gTUFYIHRyaWVzLiBSZXNldCB0aGlzIGNvdW50IHRvIDAgKi8KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwoKICAgICAgICAgICAgLyogVGhlIG9uZSBpbiB0aGUgaGVhZCBvZiB0aGUgbGlzdCBzaG91bGQgYmUgb25lIHdpdGggd2hpY2ggd2UgaXNzdWVkIHByZS1hdXRoIGFuZCBmYWlsZWQgKi8KICAgICAgICAgICAgcEVudHJ5ID0gY3NyTExSZW1vdmVIZWFkKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgICAgICAgICAgaWYocEVudHJ5KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JCc3NOb2RlID0gR0VUX0JBU0VfQUREUihwRW50cnksIHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvLCBMaXN0KTsKICAgICAgICAgICAgICAgIC8qIEFkZCB0aGUgQlNTSUQgdG8gcHJlLWF1dGggZmFpbCBsaXN0IGlmIGl0IGlzIG5vdCByZXF1ZXN0ZWQgYnkgSEREICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIGlmKCFwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKI2VuZGlmCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUFkZEJzc0lkVG9QcmVhdXRoRmFpbExpc3QocE1hYywgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCk7CiAgICAgICAgICAgICAgICB9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAgICAgICAgICAgICAvKiBMRlIgbWV0cmljcyAtIHByZS1hdXRoIGNvbXBsZXRpb24gbWV0cmljLiBTZW5kIHRoZSBldmVudAogICAgICAgICAgICAgICAgICAgdG8gc3VwcGxpY2FudCB0aGF0IHByZS1hdXRoIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgKi8KICAgICAgICAgICAgICAgIHJvYW1JbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgICAgICAgICAgICAgaWYgKE5VTEwgPT0gcm9hbUluZm8pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWQhIikpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fY29weSgodm9pZCAqKXJvYW1JbmZvLT5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKilwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgICAgICAgICAgY3NyUm9hbUNhbGxDYWxsYmFjayhwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICByb2FtSW5mbywgMCwgZUNTUl9ST0FNX1BSRUFVVEhfU1RBVFVTX0ZBSUxVUkUsIDApOwogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShyb2FtSW5mbyk7CiAgICAgICAgICAgICAgICB9CiNlbmRpZgoKICAgICAgICAgICAgLyogTm93IHdlIGNhbiBmcmVlIHRoaXMgbm9kZSAqLwogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1GcmVlTmVpZ2hib3JSb2FtQlNTTm9kZShwTWFjLCBwTmVpZ2hib3JCc3NOb2RlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBwU2Vzc2lvbiA9IENTUl9HRVRfU0VTU0lPTihwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkKTsKICAgICAgICBpZiAoKE5VTEwgIT0gcFNlc3Npb24pICYmIHBTZXNzaW9uLT5hYm9ydENvbm5lY3Rpb24pCiAgICAgICAgewogICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIERlYXV0aCBpbiBwcm9ncmVzcyBBYm9ydCBwcmVhdXRoIikpOwogICAgICAgICAgIGdvdG8gYWJvcnRfcHJlYXV0aDsKICAgICAgICB9CgogICAgICAgIC8qIElzc3VlIHByZWF1dGggcmVxdWVzdCBmb3IgdGhlIHNhbWUvbmV4dCBlbnRyeSAqLwogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTID09IGNzck5laWdoYm9yUm9hbUlzc3VlUHJlYXV0aFJlcShwTWFjKSkKICAgICAgICBnb3RvIERFUV9QUkVBVVRIOyAKCmFib3J0X3ByZWF1dGg6CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZiAoY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICB7CiAgICAgICAgICBpZihwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKICAgICAgICAgIHsKICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwgUkVBU09OX1BSRUFVVEhfRkFJTEVEX0ZPUl9BTEwpOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSBpZihwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIKQogICAgICAgICAgewogICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCA9IDA7CiAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkZvcmNlZCA1RyByb2FtaW5nIHByZWF1dGggZ290IGZhaWxlZCIKICAgICAgICAgICAgICAgICAgICAic2VuZCBSU08gU1RBUlQgY21kIHRvIGZ3ci4iKSk7CiAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYyxST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCxSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlCiAgICAgICAgICB7CiAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfUkVTVEFSVCwgUkVBU09OX1BSRUFVVEhfRkFJTEVEX0ZPUl9BTEwpOwogICAgICAgICAgfQogICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEKTsKICAgICAgICB9IGVsc2UKICAgICAgICB7CiNlbmRpZgogICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4pOwoKICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgVVAgZXZlbnQgbm93ICovCiAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJObyBtb3JlIHByZS1hdXRoIGNhbmRpZGF0ZXMtIgogICAgICAgICAgICAgICAgICAicmVnaXN0ZXIgVVAgaW5kaWNhdGlvbiB3aXRoIFRMLiBSU1NJID0gJWQsIiksIE5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSkpOwoKICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiAgICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBDYWxsYmFjayBVUCBldmVudCB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgICAgICAgfQoKICAgICAgICAgIC8qIFN0YXJ0IHRoZSBuZWlnaGJvciByZXN1bHRzIHJlZnJlc2ggdGltZXIgYW5kIHRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUgdG8gcGVyZm9ybSBzY2FuIGFnYWluICovCiAgICAgICAgICBzdGF0dXMgPSB2b3NfdGltZXJfc3RhcnQoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlc3VsdHNSZWZyZXNoUGVyaW9kKTsKICAgICAgICAgIGlmICggc3RhdHVzICE9IGVIQUxfU1RBVFVTX1NVQ0NFU1MgKQogICAgICAgICAgewogICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXN1bHRzIHJlZnJlc2ggdGltZXIgc3RhcnQgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIHN0YXR1cyk7CiAgICAgICAgICB9CiAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICB9CiNlbmRpZgoKREVRX1BSRUFVVEg6CiAgICBjc3JSb2FtRGVxdWV1ZVByZWF1dGgocE1hYyk7CiAgICByZXR1cm4gcHJlYXV0aFByb2Nlc3NlZDsKfQojZW5kaWYgIC8qIFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HICovCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHJlcGFyZVNjYW5Qcm9maWxlRmlsdGVyCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGNyZWF0ZXMgYSBzY2FuIGZpbHRlciBiYXNlZCBvbiB0aGUgY3VycmVudGx5IGNvbm5lY3RlZCBwcm9maWxlLgogICAgICAgICAgICBCYXNlZCBvbiB0aGlzIGZpbHRlciwgc2NhbiByZXN1bHRzIGFyZSBvYnRhaW5lZAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcFNjYW5GaWx0ZXIgLSBQb3B1bGF0ZWQgc2NhbiBmaWx0ZXIgYmFzZWQgb24gdGhlIGNvbm5lY3RlZCBwcm9maWxlCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGVIQUxfU1RBVFVTX0ZBSUxVUkUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByZXBhcmVTY2FuUHJvZmlsZUZpbHRlcih0cEFuaVNpckdsb2JhbCBwTWFjLCB0Q3NyU2NhblJlc3VsdEZpbHRlciAqcFNjYW5GaWx0ZXIpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCBzZXNzaW9uSWQgICA9ICh0QU5JX1U4KXBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQ7CiAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBDdXJQcm9maWxlID0gJnBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlOwogICAgdEFOSV9VOCBpID0gMDsKICAgIAogICAgVk9TX0FTU0VSVChwU2NhbkZpbHRlciAhPSBOVUxMKTsKICAgIGlmIChwU2NhbkZpbHRlciA9PSBOVUxMKQogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwoKICAgIHZvc19tZW1femVybyhwU2NhbkZpbHRlciwgc2l6ZW9mKHRDc3JTY2FuUmVzdWx0RmlsdGVyKSk7CgogICAgLyogV2UgZG9udCB3YW50IHRvIHNldCBCU1NJRCBiYXNlZCBGaWx0ZXIgKi8KICAgIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMgPSAwOwoKICAgIC8vb25seSBmb3IgSEREIHJlcXVlc3RlZCBoYW5kb2ZmIGZpbGwgaW4gdGhlIEJTU0lEIGluIHRoZSBmaWx0ZXIKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmKQogICAgewoKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk9TIFJlcXVlc3RlZCBIYW5kb2ZmIikpOwogICAgICAgIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMgPSAxOwogICAgICAgIHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodFNpck1hY0FkZHIpICogcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyk7CiAgICAgICAgaWYgKE5VTEwgPT0gcFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgQlNTSUQgbWVtIGFsbG9jIGZhaWxlZCIpKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxFRF9BTExPQzsKICAgICAgICB9CgogICAgICAgIHZvc19tZW1femVybyhwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpICogcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyk7CgogICAgICAgIC8qIFBvcHVsYXRlIHRoZSBCU1NJRCBmcm9tIGhhbmRvZmYgaW5mbyByZWNlaXZlZCBmcm9tIEhERCAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkoJnBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWRbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgICAgIH0KICAgIH0KI2VuZGlmCiAgICAvKiBQb3B1bGF0ZSBhbGwgdGhlIGluZm9ybWF0aW9uIGZyb20gdGhlIGNvbm5lY3RlZCBwcm9maWxlICovCiAgICBwU2NhbkZpbHRlci0+U1NJRHMubnVtT2ZTU0lEcyA9IDE7ICAKICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyU1NJREluZm8pKTsKICAgIGlmIChOVUxMID09IHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdCkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlNjYW4gRmlsdGVyIFNTSUQgbWVtIGFsbG9jIGZhaWxlZCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTEVEX0FMTE9DOwogICAgfQogICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5oYW5kb2ZmUGVybWl0dGVkID0gMTsKICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+c3NpZEhpZGRlbiA9IDA7CiAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQubGVuZ3RoID0gIHBDdXJQcm9maWxlLT5TU0lELmxlbmd0aDsKICAgIHZvc19tZW1fY29weSgodm9pZCAqKXBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5zc0lkLCAodm9pZCAqKXBDdXJQcm9maWxlLT5TU0lELnNzSWQsIHBDdXJQcm9maWxlLT5TU0lELmxlbmd0aCk7IAoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIkZpbHRlcmluZyBmb3IgU1NJRCAlLipzIGZyb20gc2NhbiByZXN1bHRzLCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibGVuZ3RoIG9mIFNTSUQgPSAldSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELnNzSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELmxlbmd0aCk7CiAgICBwU2NhbkZpbHRlci0+YXV0aFR5cGUubnVtRW50cmllcyA9IDE7CiAgICBwU2NhbkZpbHRlci0+YXV0aFR5cGUuYXV0aFR5cGVbMF0gPSBwQ3VyUHJvZmlsZS0+QXV0aFR5cGU7CgogICAgcFNjYW5GaWx0ZXItPkVuY3J5cHRpb25UeXBlLm51bUVudHJpZXMgPSAxOyAvL1RoaXMgbXVzdCBiZSAxCiAgICBwU2NhbkZpbHRlci0+RW5jcnlwdGlvblR5cGUuZW5jcnlwdGlvblR5cGVbMF0gPSBwQ3VyUHJvZmlsZS0+RW5jcnlwdGlvblR5cGU7CgogICAgcFNjYW5GaWx0ZXItPm1jRW5jcnlwdGlvblR5cGUubnVtRW50cmllcyA9IDE7CiAgICBwU2NhbkZpbHRlci0+bWNFbmNyeXB0aW9uVHlwZS5lbmNyeXB0aW9uVHlwZVswXSA9IHBDdXJQcm9maWxlLT5tY0VuY3J5cHRpb25UeXBlOwoKICAgIHBTY2FuRmlsdGVyLT5CU1NUeXBlID0gcEN1clByb2ZpbGUtPkJTU1R5cGU7CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzKQogICAgewogICAgICAgLyogV2UgYXJlIGludHJlc3RlZCBvbmx5IGluIHRoZSBzY2FuIHJlc3VsdHMgb24gY2hhbm5lbHMgdGhhdCB3ZSBzY2FubmVkICAqLwogICAgICAgcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgPQogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzOwogICAgICAgcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0KICAgICAgICB2b3NfbWVtX21hbGxvYyhwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICBpZiAoTlVMTCA9PSBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICB7CiAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlNjYW4gRmlsdGVyIENoYW5uZWwgbGlzdCBtZW0gYWxsb2MgZmFpbGVkIikpOwogICAgICAgICAgdm9zX21lbV9mcmVlKHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdCk7CiAgICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QgPSBOVUxMOwogICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxFRF9BTExPQzsKICAgICAgIH0KICAgICAgIGZvciAoaSA9IDA7IGkgPCBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVsczsgaSsrKQogICAgICAgewogICAgICAgICAgcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0W2ldID0KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0W2ldOwogICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgaWYgKHBNYWMtPlBFUnJvYW1DYW5kaWRhdGVzQ250KQogICAgICAgcFNjYW5GaWx0ZXItPmlzUEVSUm9hbVNjYW4gPSB0cnVlOwojZW5kaWYKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpCiAgICB7CiAgICAgICAgLyogTURJRSBzaG91bGQgYmUgYWRkZWQgYXMgYSBwYXJ0IG9mIHByb2ZpbGUuIFRoaXMgc2hvdWxkIGJlIGFkZGVkIGFzIGEgcGFydCBvZiBmaWx0ZXIgYXMgd2VsbCAgKi8KICAgICAgICBwU2NhbkZpbHRlci0+TURJRC5tZGllUHJlc2VudCA9IHBDdXJQcm9maWxlLT5NRElELm1kaWVQcmVzZW50OwogICAgICAgIHBTY2FuRmlsdGVyLT5NRElELm1vYmlsaXR5RG9tYWluID0gcEN1clByb2ZpbGUtPk1ESUQubW9iaWxpdHlEb21haW47CiAgICB9CiNlbmRpZgoKI2lmZGVmIFdMQU5fRkVBVFVSRV8xMVcKICAgIHBTY2FuRmlsdGVyLT5NRlBFbmFibGVkID0gcEN1clByb2ZpbGUtPk1GUEVuYWJsZWQ7CiAgICBwU2NhbkZpbHRlci0+TUZQUmVxdWlyZWQgPSBwQ3VyUHJvZmlsZS0+TUZQUmVxdWlyZWQ7CiAgICBwU2NhbkZpbHRlci0+TUZQQ2FwYWJsZSA9IHBDdXJQcm9maWxlLT5NRlBDYXBhYmxlOwojZW5kaWYKCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKdEFOSV9VMzIgY3NyR2V0Q3VycmVudEFQUnNzaSh0cEFuaVNpckdsb2JhbCBwTWFjLCB0U2NhblJlc3VsdEhhbmRsZSAqcFNjYW5SZXN1bHRMaXN0KQp7CiAgICAgICAgdENzclNjYW5SZXN1bHRJbmZvICpwU2NhblJlc3VsdDsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICB0QU5JX1UzMiBDdXJyQVBSc3NpID0gcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpOwojZWxzZQogICAgICAgIC8qIFdlIGFyZSBzZXR0aW5nIHRoaXMgYXMgZGVmYXVsdCB2YWx1ZSB0byBtYWtlIHN1cmUgd2UgcmV0dXJuIHRoaXMgdmFsdWUsCiAgICAgICAgd2hlbiB3ZSBkbyBub3Qgc2VlIHRoaXMgQVAgaW4gdGhlIHNjYW4gcmVzdWx0IGZvciBzb21lIHJlYXNvbi5Ib3dldmVyLGl0IGlzCiAgICAgICAgbGVzcyBsaWtlbHkgdGhhdCB3ZSBhcmUgYXNzb2NpYXRlZCB0byBhbiBBUCBhbmQgZG8gbm90IHNlZSBpdCBpbiB0aGUgc2NhbiBsaXN0ICovCiAgICAgICAgdEFOSV9VMzIgQ3VyckFQUnNzaSA9IC0xMjU7CiNlbmRpZgoKICAgICAgICB3aGlsZSAoTlVMTCAhPSAocFNjYW5SZXN1bHQgPSBjc3JTY2FuUmVzdWx0R2V0TmV4dChwTWFjLCAqcFNjYW5SZXN1bHRMaXN0KSkpCiAgICAgICAgewoKICAgICAgICAgICAgICAgIGlmIChWT1NfVFJVRSA9PSB2b3NfbWVtX2NvbXBhcmUocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFdlIGdvdCBhIG1hdGNoIHdpdGggdGhlIGN1cnJlbnRseSBhc3NvY2lhdGVkIEFQLgogICAgICAgICAgICAgICAgICAgICAgICAgKiBDYXB0dXJlIHRoZSBSU1NJIHZhbHVlIGFuZCBjb21wbGV0ZSB0aGUgd2hpbGUgbG9vcC4KICAgICAgICAgICAgICAgICAgICAgICAgICogVGhlIHdoaWxlIGxvb3AgaXMgY29tcGxldGVkIGluIG9yZGVyIHRvIG1ha2UgdGhlIGN1cnJlbnQgZW50cnkgZ28gYmFjayB0byBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgKiBhbmQgaW4gdGhlIG5leHQgd2hpbGUgbG9vcCwgaXQgcHJvcGVybHkgc3RhcnRzIHNlYXJjaGluZyBmcm9tIHRoZSBoZWFkIG9mIHRoZSBsaXN0LgogICAgICAgICAgICAgICAgICAgICAgICAgKiBUT0RPOiBDYW4gYWxzbyB0cnkgc2V0dGluZyB0aGUgY3VycmVudCBlbnRyeSBkaXJlY3RseSB0byBOVUxMIGFzIHNvb24gYXMgd2UgZmluZCB0aGUgbmV3IEFQKi8KCiAgICAgICAgICAgICAgICAgICAgICAgICBDdXJyQVBSc3NpID0gKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSA7CgogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gQ3VyckFQUnNzaTsKCn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhblJlc3VsdHMKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gZXh0cmFjdHMgc2NhbiByZXN1bHRzLCBzb3J0cyBvbiB0aGUgYmFzaXMgb2YgbmVpZ2hib3Igc2NvcmUodG9kbykuIAogICAgICAgICAgICBBc3N1bWVkIHRoYXQgdGhlIHJlc3VsdHMgYXJlIGFscmVhZHkgc29ydGVkIGJ5IFJTU0kgYnkgY3NyU2NhbkdldFJlc3VsdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcFNjYW5SZXN1bHRMaXN0IC0gU2NhbiByZXN1bHQgcmVzdWx0IG9idGFpbmVkIGZyb20gY3NyU2NhbkdldFJlc3VsdCgpCgogICAgXHJldHVybiB0QU5JX0JPT0xFQU4gLSByZXR1cm4gVFJVRSBpZiB3ZSBoYXZlIGEgY2FuZGlkYXRlIHdlIGNhbiBpbW1lZGlhdGVseQogICAgICAgICAgICByb2FtIHRvLiBPdGhlcndpc2UsIHJldHVybiBGQUxTRS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpzdGF0aWMgdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuUmVzdWx0cyh0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdFNjYW5SZXN1bHRIYW5kbGUgKnBTY2FuUmVzdWx0TGlzdCkKewogICAgdENzclNjYW5SZXN1bHRJbmZvICpwU2NhblJlc3VsdDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvICAgIHBCc3NJbmZvOwogICAgdEFOSV9VMzIgQ3VyckFQUnNzaTsKICAgIHRBTklfVTggUm9hbVJzc2lEaWZmID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5Sb2FtUnNzaURpZmY7CiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgIHRBTklfVTggaW1tZWRpYXRlUm9hbVJzc2lEaWZmID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uSW1tZWRpYXRlUm9hbVJzc2lEaWZmOwojZW5kaWYKICAgIHRBTklfQk9PTEVBTiByb2FtTm93ID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIC8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAqIEZpbmQgb3V0IHRoZSBDdXJyZW50IEFQIFJTU0kgYW5kIGtlZXAgaXQgaGFuZHkgdG8gY2hlY2sgaWYKICAgICAqIGl0IGlzIGJldHRlciB0aGFuIHRoZSBSU1NJIG9mIHRoZSBBUCB3aGljaCB3ZSBhcmUKICAgICAqIGdvaW5nIHRvIHJvYW0uSWYgc28sIHdlIGFyZSBnb2luZyB0byBjb250aW51ZSB3aXRoIHRoZQogICAgICogY3VycmVudCBBUC4KICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICBDdXJyQVBSc3NpID0gY3NyR2V0Q3VycmVudEFQUnNzaShwTWFjLCBwU2NhblJlc3VsdExpc3QpOwoKICAgIC8qIEV4cGVjdGluZyB0aGUgc2NhbiByZXN1bHQgYWxyZWFkeSB0byBiZSBpbiB0aGUgc29ydGVkIG9yZGVyIGJhc2VkIG9uIHRoZSBSU1NJICovCiAgICAvKiBCYXNlZCBvbiB0aGUgcHJldmlvdXMgc3RhdGUgd2UgbmVlZCB0byBjaGVjayB3aGV0aGVyIHRoZSBsaXN0IHNob3VsZCBiZSBzb3J0ZWQgYWdhaW4gdGFraW5nIG5laWdoYm9yIHNjb3JlIGludG8gY29uc2lkZXJhdGlvbiAqLwogICAgLyogSWYgcHJldmlvdXMgc3RhdGUgaXMgQ0ZHX0NIQU5fTElTVF9TQ0FOLCB0aGVyZSBzaG91bGQgbm90IGJlIGFueSBuZWlnaGJvciBzY29yZSBhc3NvY2lhdGVkIHdpdGggYW55IG9mIHRoZSBCU1MuCiAgICAgICBJZiB0aGUgcHJldmlvdXMgc3RhdGUgaXMgUkVQT1JUX1FVRVJZLCB0aGVuIHRoZXJlIHdpbGwgYmUgbmVpZ2hib3Igc2NvcmUgZm9yIGVhY2ggb2YgdGhlIEFQcyAqLwogICAgLyogRm9yIG5vdywgbGV0IHVzIHRha2UgdGhlIHRvcCBvZiB0aGUgbGlzdCBwcm92aWRlZCBhcyBpdCBpcyBieSB0aGUgQ1NSIFNjYW4gcmVzdWx0IEFQSS4gVGhpcyBtZWFucyBpdCBpcyBhc3N1bWVkIHRoYXQgbmVpZ2hib3Igc2NvcmUgCiAgICAgICBhbmQgcnNzaSBzY29yZSBhcmUgaW4gdGhlIHNhbWUgb3JkZXIuIFRoaXMgd2lsbCBiZSB0YWtlbiBjYXJlIGxhdGVyICovCgogICAgd2hpbGUgKE5VTEwgIT0gKHBTY2FuUmVzdWx0ID0gY3NyU2NhblJlc3VsdEdldE5leHQocE1hYywgKnBTY2FuUmVzdWx0TGlzdCkpKQogICAgewogICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfREVCVUcsCiAgICAgICAgICAgIEZMKCJTY2FuIHJlc3VsdDogQlNTSUQgIk1BQ19BRERSRVNTX1NUUiIgKFJzc2kgJWxkLCBDaDolZCkiKSwKICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpLAogICAgICAgICAgICBhYnMocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSksCiAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmNoYW5uZWxJZCk7CgogICAgICAgaWYgKChWT1NfVFJVRSA9PSB2b3NfbWVtX2NvbXBhcmUocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQsCiAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpKSkgfHwKICAgICAgICAgICAoKGVTTUVfUk9BTV9UUklHR0VSX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikgJiYKICAgICAgICAgICAoVk9TX1RSVUUgIT0gdm9zX21lbV9jb21wYXJlKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbWJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKSkpKQogICAgICAgIHsKICAgICAgICAgICAgLyogY3VycmVudGx5IGFzc29jaWF0ZWQgQVAuIERvIG5vdCBoYXZlIHRoaXMgaW4gdGhlIHJvYW1hYmxlIEFQIGxpc3QgKi8KICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgIlNLSVAtY3VycmVudGx5IGFzc29jaWF0ZWQgQVAiKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgIGlmICh2b3NfY29uY3VycmVudF9vcGVuX3Nlc3Npb25zX3J1bm5pbmcoKSAmJgogICAgICAgICAgIXBNYWMtPnJvYW0uY29uZmlnUGFyYW0uZmVuYWJsZU1DQ01vZGUgJiYKICAgICAgICAgICAgKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmNoYW5uZWxJZCAhPQogICAgICAgICAgICBjc3JHZXRDb25jdXJyZW50T3BlcmF0aW9uQ2hhbm5lbChwTWFjKSkpIHsKICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiTUNDIG5vdCBzdXBwb3J0ZWQgc28gSWdub3JlIEFQIG9uIGNoYW5uZWwgJWQiKSwKICAgICAgICAgICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5jaGFubmVsSWQpOwogICAgICAgICAgY29udGludWU7CiAgICAgICB9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAvKiBJbiBjYXNlIG9mIHJlYXNzb2MgcmVxdWVzdGVkIGJ5IHVwcGVyIGxheWVyLCBsb29rIGZvciBleGFjdCBtYXRjaCBvZiBic3NpZCAmIGNoYW5uZWw7CiAgICAgICAgICBjc3IgY2FjaGUgbWlnaHQgaGF2ZSBkdXBsaWNhdGVzKi8KICAgICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpICYmCiAgICAgICAgICAgKChWT1NfRkFMU0UgPT0gdm9zX21lbV9jb21wYXJlKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKSl8fAogICAgICAgICAgICAocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuY2hhbm5lbElkICE9IHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5jaGFubmVsKSkpCgogICAgICAgewogICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgIlNLSVAtbm90IGEgY2FuZGlkYXRlIEFQIGZvciBPUyByZXF1ZXN0ZWQgcm9hbSIpOwogICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgfQojZW5kaWYKI2VuZGlmCgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCkKICAgICAgIHsKICAgICAgICAgICAgLy9CZWxvdyBjaGVjayBpcyByZXF1aXJlZCBiZWNhdXNlIHNjYW5uaW5nIGZvciBmb3JjZWQgaW5pdGlhbCByb2FtaW5nIHdlIGhhdmUgbm90CiAgICAgICAgICAgIC8vZmx1c2ggYWxsIHRoZSAyLjQgR0h6IENoYW5uZWwsIHNvIGl0IG1heSBwb3NzYmlsZSB3ZSBtYXkgcm9hbSBhZ2FpbiB0bwogICAgICAgICAgICAvLzIuNCBHaHogYXAgb25seS4KICAgICAgICAgICAgaWYoR2V0UkZCYW5kKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmNoYW5uZWxJZCkgIT0gU0lSX0JBTkRfNV9HSFopCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IEZvcmNlZCBSb2FtIHRvIDVHIFNraXAgTm9uIDVHIFNjYW4gcmVzdWx0cyAiLCBfX2Z1bmNfXyk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy9yc3NpJ3MgYXJlIC12ZSB2YWx1ZSwgc28gaWYgYWJzIG9mIHJzc2kgaXMgZ3JlYXRlcgogICAgICAgICAgICAvL21lYW5zIG5ldyBhcCBpcyBwb29yIHRoZW4gY3VycmVudGx5IGNvbm5lY3RlZCBhcC4KICAgICAgICAgICAgLy9DaGVjayBpdCBpcyBvbmx5IHBvb3Igd2l0aGluIG5TZWxlY3Q1R0h6TWFyZ2luIHZhbHVlLgogICAgICAgICAgICBpZiAoYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpID4gYWJzKEN1cnJBUFJzc2kpICYmCiAgICAgICAgICAgICAgICgoYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpIC0gYWJzKEN1cnJBUFJzc2kpKQogICAgICAgICAgICAgICAgPiBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5TZWxlY3Q1R0h6TWFyZ2luKQogICAgICAgICAgICAgICApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgIiVzOiBGb3JjZWQgUm9hbSB0byA1RyBDdXJyZW50IEFQIHJzc2k9JWQgbmV3IGFwIHJzc2k9JWQgbm90IGdvb2QgZW5vdWdoLCBuU2VsZWN0NUdIek1hcmdpbj0lZCIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgQ3VyckFQUnNzaSwKICAgICAgICAgICAgICAgICAgICAgIChpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5TZWxlY3Q1R0h6TWFyZ2luKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgfQojZW5kaWYKI2VuZGlmCgogICAgICAgLyogVGhpcyBjb25kaXRpb24gaXMgdG8gZW5zdXJlIHRvIHJvYW0gdG8gYW4gQVAgd2l0aCBiZXR0ZXIgUlNTSS4gaWYgdGhlIHZhbHVlIG9mIFJvYW1Sc3NpRGlmZiBpcyBaZXJvLCB0aGlzIGZlYXR1cmUKICAgICAgICAqIGlzIGRpc2FibGVkIGFuZCB3ZSBjb250aW51ZSB0byByb2FtIHdpdGhvdXQgYW55IGNoZWNrKi8KICAgICAgIGlmICgoUm9hbVJzc2lEaWZmID4gMCkKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICAgICAmJiAoKGVTTUVfUk9BTV9UUklHR0VSX1NDQU4gIT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikgJiYKICAgICAgICAgICAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNICE9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pKSkKICAgICAgIHsKICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgKiBJZiBSU1NJIGlzIGxvd2VyIHRoYW4gdGhlIGxvb2t1cCB0aHJlc2hvbGQsIHRoZW4gY29udGludWUuCiAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgIGlmIChhYnMocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSkgPgogICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCkKICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddIG5ldyBhcCByc3NpICglZCkgbG93ZXIgdGhhbiBsb29rdXAgdGhyZXNob2xkICglZCkiLAogICAgICAgICAgICAgICAgICAgIF9fZnVuY19fLCAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgIChpbnQpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSkpOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICBpZiAoYWJzKEN1cnJBUFJzc2kpIDwgYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpKQogICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgLypEbyBub3Qgcm9hbSB0byBhbiBBUCB3aXRoIHdvcnNlIFJTU0kgdGhhbiB0aGUgY3VycmVudCovCiAgICAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddQ3VycmVudCBBUCByc3NpPSVkIG5ldyBhcCByc3NpIHdvcnNlPSVkIiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1cnJBUFJzc2ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSAqICgtMSkgKTsKICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAvKkRvIG5vdCByb2FtIHRvIGFuIEFQIHdoaWNoIGlzIGhhdmluZyBiZXR0ZXIgUlNTSSB0aGFuIHRoZSBjdXJyZW50IEFQLCBidXQgc3RpbGwgbGVzcyB0aGFuIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAqIG1hcmdpbiB0aGF0IGlzIHByb3ZpZGVkIGJ5IHVzZXIgZnJvbSB0aGUgaW5pIGZpbGUgKFJvYW1Sc3NpRGlmZikqLwogICAgICAgICAgICAgICAgICAgICAgIGlmIChhYnMoYWJzKEN1cnJBUFJzc2kpIC0gYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpKSA8IFJvYW1Sc3NpRGlmZikKICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXUN1cnJlbnQgQVAgcnNzaT0lZCBuZXcgYXAgcnNzaT0lZCBub3QgZ29vZCBlbm91Z2gsIHJvYW1Sc3NpRGlmZj0lZCIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDdXJyQVBSc3NpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSb2FtUnNzaURpZmYpOwogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR11DdXJyZW50IEFQIHJzc2k9JWQgbmV3IGFwIHJzc2kgYmV0dGVyPSVkIiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3VyckFQUnNzaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpICk7CiAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICB9CiAgICAgICB9CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIWNzck5laWdoYm9yUm9hbUlzUHJlYXV0aENhbmRpZGF0ZShwTWFjLCBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQlNTSUQgcHJlc2VudCBpbiBwcmUtYXV0aCBmYWlsIGxpc3QuLiBJZ25vcmluZyIpKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewojZW5kaWYKICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYykKICAgICAgICAgIHsKICAgICAgICAgICAgICBpZiAoIWNzck5laWdoYm9yUm9hbUlzUHJlYXV0aENhbmRpZGF0ZShwTWFjLCBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCkpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkJTU0lEIHByZXNlbnQgaW4gcHJlLWF1dGggZmFpbCBsaXN0Li4gSWdub3JpbmciKSk7CiAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmICgocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfcHJlc2VudCkgJiYKICAgICAgICAgICAgICAgKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX2F2YWlsKSkKICAgICAgICAgIHsKICAgICAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzVk9BZG1pdHRlZCkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiTmV3IEFQIGhhcyAleCBCVyBhdmFpbGFibGUiKSwgKHVuc2lnbmVkIGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9hdmFpbCk7CiAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiV2UgbmVlZCAleCBCVyBhdmFpbGFibGUiKSwodW5zaWduZWQgaW50KXBOZWlnaGJvclJvYW1JbmZvLT5NaW5RQnNzTG9hZFJlcXVpcmVkKTsKICAgICAgICAgICAgICAgICAgaWYgKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX2F2YWlsIDwgcE5laWdoYm9yUm9hbUluZm8tPk1pblFCc3NMb2FkUmVxdWlyZWQpCiAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICJbSU5GT0xPR11CU1NJRCA6ICJNQUNfQUREUkVTU19TVFIiIGhhcyBubyBiYW5kd2lkdGggaWdub3JpbmcuLm5vdCBhZGRpbmcgdG8gcm9hbSBsaXN0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCkpOwogICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlCiAgICAgICAgICB7CiAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJObyBRQnNzICV4ICV4IiksICh1bnNpZ25lZCBpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfYXZhaWwsICh1bnNpZ25lZCBpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfcHJlc2VudCk7CiAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc1ZPQWRtaXR0ZWQpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICJbSU5GT0xPR11CU1NJRCA6ICJNQUNfQUREUkVTU19TVFIiIGhhcyBubyBRQlNTTG9hZCBJRSwgaWdub3JpbmcuLm5vdCBhZGRpbmcgdG8gcm9hbSBsaXN0IiwKICAgICAgICAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSk7CiAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIH0KI2VuZGlmCiNlbmRpZiAvKiBGRUFUVVJFX1dMQU5fRVNFICovCgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIC8vIElmIHdlIGFyZSBzdXBwb3J0aW5nIGxlZ2FjeSByb2FtaW5nLCBhbmQgCiAgICAgICAgLy8gaWYgdGhlIGNhbmRpZGF0ZSBpcyBvbiB0aGUgInByZS1hdXRoIGZhaWxlZCIgbGlzdCwgaWdub3JlIGl0LiAKICAgICAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUocE1hYywgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkJTU0lEIHByZXNlbnQgaW4gcHJlLWF1dGggZmFpbCBsaXN0Li4gSWdub3JpbmciKSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KI2VuZGlmIC8qIEZFQVRVUkVfV0xBTl9MRlIgKi8KCiAgICAgICAgLyogSWYgdGhlIHJlY2VpdmVkIHRpbWVzdGFtcCBpbiBCU1MgZGVzY3JpcHRpb24gaXMgZWFybGllciB0aGFuIHRoZSBzY2FuIHJlcXVlc3QgdGltZXN0YW1wLCBza2lwIAogICAgICAgICAqIHRoaXMgcmVzdWx0ICovCiAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJlcXVlc3RUaW1lU3RhbXAgPj0gcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IublJlY2VpdmVkVGltZSkKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAmJiAhY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKQojZW5kaWYKICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIklnbm9yaW5nIEJTUyBhcyBpdCBpcyBvbGRlciB0aGFuIHRoZSBzY2FuIHJlcXVlc3QgdGltZXN0YW1wIikpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHBCc3NJbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvKSk7CiAgICAgICAgaWYgKE5VTEwgPT0gcEJzc0luZm8pCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZvciBOZWlnaGJvciBSb2FtIEJTUyBJbmZvIGZhaWxlZC4uIEp1c3QgaWdub3JpbmciKSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgcEJzc0luZm8tPnBCc3NEZXNjcmlwdGlvbiA9IHZvc19tZW1fbWFsbG9jKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmxlbmd0aCArIHNpemVvZihwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5sZW5ndGgpKTsKICAgICAgICBpZiAocEJzc0luZm8tPnBCc3NEZXNjcmlwdGlvbiAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KHBCc3NJbmZvLT5wQnNzRGVzY3JpcHRpb24sICZwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IubGVuZ3RoICsgc2l6ZW9mKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmxlbmd0aCkpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZvciBOZWlnaGJvciBSb2FtIEJTUyBEZXNjcmlwdG9yIGZhaWxlZC4uIEp1c3QgaWdub3JpbmciKSk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQnNzSW5mbyk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgcEJzc0luZm8tPmFwUHJlZmVyZW5jZVZhbCA9IDEwOyAvL3NvbWUgdmFsdWUgZm9yIG5vdy4gTmVlZCB0byBjYWxjdWxhdGUgdGhlIGFjdHVhbCBzY29yZSBiYXNlZCBvbiBSU1NJIGFuZCBuZWlnaGJvciBBUCBzY29yZQoKICAgICAgICAvKiBKdXN0IGFkZCB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IGFzIGl0IGlzIGFscmVhZHkgc29ydGVkIGJ5IFJTU0kgKi8KICAgICAgICBjc3JMTEluc2VydFRhaWwoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgJnBCc3NJbmZvLT5MaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICAgICAgaWYgKChlU01FX1JPQU1fVFJJR0dFUl9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pIHx8CiAgICAgICAgICAgIChlU01FX1JPQU1fVFJJR0dFUl9GQVNUX1JPQU0gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikpCiAgICAgICAgewogICAgICAgICAgIHJvYW1Ob3cgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKChhYnMoYWJzKEN1cnJBUFJzc2kpIC0gYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpKSA+PSBpbW1lZGlhdGVSb2FtUnNzaURpZmYpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gcG90ZW50aWFsIGNhbmRpZGF0ZSB0byByb2FtIGltbWVkaWF0ZWx5IChkaWZmPSVsZCwgZXhwZWN0ZWQ9JWQpIiwKICAgICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgYWJzKGFicyhDdXJyQVBSc3NpKSAtIGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSksCiAgICAgICAgICAgICAgICAgICAgICAgaW1tZWRpYXRlUm9hbVJzc2lEaWZmKTsKICAgICAgICAgICAgcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIC8qIElmIHdlIGFyZSBoZXJlIG1lYW5zLCBGVyBhbHJlYWR5IGZvdW5kIGNhbmRpZGF0ZXMgdG8gcm9hbSwgc28gd2UgYXJlCiAgICAgICAgICAgZ29vZCB0byBnbyB3aXRoIHByZS1hdXRoICovCiAgICAgICAgaWYoY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICB7CiAgICAgICAgICAgIHJvYW1Ob3cgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICB9CiNlbmRpZgojZW5kaWYKICAgIH0KCiAgICAvKiBOb3cgd2UgaGF2ZSBhbGwgdGhlIHNjYW4gcmVzdWx0cyBpbiBvdXIgbG9jYWwgbGlzdC4gR29vZCB0aW1lIHRvIGZyZWUgdXAgdGhlIHRoZSBsaXN0IHdlIGdvdCBhcyBhIHBhcnQgb2YgY3NyR2V0U2NhblJlc3VsdCAqLwogICAgY3NyU2NhblJlc3VsdFB1cmdlKHBNYWMsICpwU2NhblJlc3VsdExpc3QpOwoKICAgIHJldHVybiByb2FtTm93Owp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSGFuZGxlRW1wdHlTY2FuUmVzdWx0CgogICAgXGJyaWVmICAgICAgVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGludm9rZWQgaW4gQ0ZHX0NIQU5fTElTVF9TQ0FOIHN0YXRlIHdoZW4gCiAgICAgICAgICAgICAgICB0aGVyZSBhcmUgbm8gdmFsaWQgQVBzIGluIHRoZSBzY2FuIHJlc3VsdCBmb3Igcm9hbWluZy4gVGhpcyBtZWFucyAKICAgICAgICAgICAgICAgIG91ciBBUCBpcyB0aGUgYmVzdCBhbmQgbm8gb3RoZXIgQVAgaXMgYXJvdW5kLiBObyBwb2ludCBpbiBzY2FubmluZwogICAgICAgICAgICAgICAgYWdhaW4gYW5kIGFnYWluLiBQZXJmb3JtaW5nIHRoZSBmb2xsb3dpbmcgaGVyZS4KICAgICAgICAgICAgICAgIDEuIFN0b3AgdGhlIG5laWdoYm9yIHNjYW4gdGltZXIuCiAgICAgICAgICAgICAgICAyYS4gSWYgdGhpcyBpcyB0aGUgZmlyc3QgdGltZSB3ZSBlbmNvdW50ZXJlZCBlbXB0eSBzY2FuLCB0aGVuCiAgICAgICAgICAgICAgICByZS1yZWdpc3RlciB3aXRoIFRMIHdpdGggbW9kaWZpZWQgbG9va3VwIHRocmVzaG9sZC4KICAgICAgICAgICAgICAgIDJiLiBFbHNlIGlmIHRoaXMgaXMgdGhlIHNlY29uZCB0aW1lIHdlIGVuY291bnRlcmVkIGVtcHR5IHNjYW4sCiAgICAgICAgICAgICAgICB0aGVuIHN0YXJ0IG5laWdoYm9yIHNjYW4gcmVzdWx0cyByZWZyZXNoIHRpbWVyICgyMHMpLgogICAgICAgICAgICAgICAgMmMuIEVsc2UsIG5vdGhpbmcgbW9yZSB0byBkby4KICAgICAgICAgICAgICAgIE5PVEU6IEluIExGUiwgY2hhbm5lbHMgc2VsZWN0ZWQgZm9yIHNjYW5uaW5nIGlzIGRlcnZpZWQgZnJvbQogICAgICAgICAgICAgICAgdGhlIG9jY3VwZWQgY2hhbm5lbCBsaXN0LiBTY2FuIGN5Y2xlIGZvbGxvd2luZyBvbmUgd2hpY2gKICAgICAgICAgICAgICAgIHlpZWxkZWQgZW1wdHkgcmVzdWx0cyBpcyBzcGxpdCBpbnRvIHR3byBoYWx2ZXM6IChpKSBzY2FuIG9uCiAgICAgICAgICAgICAgICBjaGFubmVscyBpbiB0aGUgb2NjdXBpZWQgbGlzdCwgYW5kIChpaSkgc2NhbiBvbiBjaGFubmVscyBub3QKICAgICAgICAgICAgICAgIGluIHRoZSBvY2N1cGllZCBsaXN0LiBUaGlzIGhlbHBzIGNvbnZlcmdpbmcgZmFzdGVyICh3aGlsZQogICAgICAgICAgICAgICAgbG9va2luZyBmb3IgY2FuZGlkYXRlcyBpbiB0aGUgb2NjdXBpZWQgbGlzdCBmaXJzdCksIGFuZCBhbHNvLAogICAgICAgICAgICAgICAgYWRkcyBjaGFubmVscyB0byB0aGUgb2NjdXBpZWQgY2hhbm5lbCBsaXN0IHVwb24gZmluZGluZyBjYW5kaWRhdGVzCiAgICAgICAgICAgICAgICBtYXRjaGluZyBTU0lEIHByb2ZpbGUgb2YgaW50ZXJlc3QuCgogICAgICAgICAgICAgICAgdUVtcHR5U2NhbkNvdW50ICAgICAgICAgICAgICAgICAgICAgICAgIENvbW1lbnRzCiAgICAgICAgICAgICAgICBlRmlyc3RFbXB0eVNjYW4gICAgIFByZXZpb3VzIHNjYW4gd2FzIGRvbmUgb24gY2hhbm5lbHMgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jY3VwaWVkIGxpc3QgYW5kIHlpZWxkZWQgcG90ZW50aWFsIGNhbmRpZGF0ZXMuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMgc2NhbiBjeWNsZSB3YXMgbGlrZWx5IHRyaWdnZXJlZCB0aHJvdWdoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpcHQgb2YgbG9va3VwIERPV04gbm90aWZpY2F0aW9uIGV2ZW50LgogICAgICAgICAgICAgICAgZVNlY29uZEVtcHR5U2NhbiAgICBQcmV2aW91cyBzY2FuIHdhcyBkb25lIG9uIGNoYW5uZWxzIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY2N1cGllZCBsaXN0IGFuZCB5aWVsZGVkIG5vIGNhbmRpZGF0ZXMuIFRoaXMgc2NhbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjeWNsZSB3YXMgdHJpZ2dlcmVkIHRocm91Z2ggUlNTSSBub3RpZmljYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCBtb2RpZmllZCBsb29rdXAgdGhyZXNob2xkLgogICAgICAgICAgICAgICAgZVRoaXJkRW1wdHlTY2FuICAgICBQcmV2aW91cyBzY2FuIHdhcyBkb25lIG9uIGNoYW5uZWxzIE5PVCBpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgb2NjdXBpZWQgbGlzdCBhbmQgeWllbGRlZCBubyBjYW5kaWRhdGVzLiBUaGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4gY3ljbGUgd2FzIHRyaWdnZXJlZCBpbW1lZGlhdGVseSBhZnRlciBzY2FubmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVscyBpbiB0aGUgb2NjdXBpZWQgbGlzdCBhbmQgbm8gY2FuZGlkYXRlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZXJlIGZvdW5kLgogICAgICAgICAgICAgICAgZUZvdXJ0aEVtcHR5U2NhbiAgICBQcmV2aW91cyBzY2FuIHdhcyBkb25lIG9uIGNoYW5uZWxzIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY2N1cGllZCBsaXN0IGFuZCB5aWVsZGVkIG5vIGNhbmRpZGF0ZXMuIFRoaXMgc2NhbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjeWNsZSB3YXMgdHJpZ2dlcmVkIHVwb24gZXhwaXJ5IG9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5laWdoYm9yU2NhblJlc3VsdHNSZWZyZXNoUGVyaW9kICg9MjBzKS4KICAgICAgICAgICAgICAgIGVGaWZ0aEVtcHR5U2NhbiAgICAgUHJldmlvdXMgc2NhbiB3YXMgZG9uZSBvbiBjaGFubmVscyBOT1QgaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIG9jY3VwaWVkIGxpc3QgYW5kIHlpZWxkZWQgbm8gY2FuZGlkYXRlcy4gVGhpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuIGN5Y2xlIHdhcyB0cmlnZ2VyZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgc2Nhbm5pbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbHMgaW4gdGhlIG9jY3VwaWVkIGxpc3QgYW5kIG5vIGNhbmRpZGF0ZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2VyZSBmb3VuZC4KCiAgICAgICAgICAgICAgICBbMV0sIFsyLDNdIGFuZCBbNCw1XSB0b2dldGhlciBmb3JtIG9uZSBkaXNjcmV0ZSBzZXQgb2Ygc2NhbiBjeWNsZS4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIFZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtSGFuZGxlRW1wdHlTY2FuUmVzdWx0KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHRBTklfQk9PTEVBTiBwZXJmb3JtUGVyaW9kaWNTY2FuID0KICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5lbXB0eVNjYW5SZWZyZXNoUGVyaW9kKSA/IFRSVUUgOiBGQUxTRTsKI2VuZGlmCgogICAgLyogU3RvcCBuZWlnaGJvciBzY2FuIHRpbWVyICovCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgIC8qCiAgICAgKiBJbmNyZWFzZSB0aGUgbmVpZ2hib3IgbG9va3VwIHRocmVzaG9sZCBieSAzIGRCCiAgICAgKiBhZnRlciBldmVyeSBzY2FuIGN5Y2xlLiBOT1RFOiB1RW1wdHlTY2FuQ291bnQKICAgICAqIHdvdWxkIGJlIGVpdGhlciAxLCAzIG9yIDUgYXQgdGhlIGVuZCBvZiBldmVyeQogICAgICogc2NhbiBjeWNsZS4KICAgICAqLwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgaWYgKCgrK3BOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQpID4gZUZpZnRoRW1wdHlTY2FuKQogICAgewogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSBlRmlmdGhFbXB0eVNjYW47CiAgICB9CiAgICBpZiAoKCgwICE9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykgfHwKICAgICAgICAgKGFicyhwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kpID4KICAgICAgICAgYWJzKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkKSkpICYmCiAgICAgICAgKChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IGVTZWNvbmRFbXB0eVNjYW4pIHx8CiAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IGVGb3VydGhFbXB0eVNjYW4pKSkKICAgIHsKICAgICAgICAvKgogICAgICAgICAqIElmIHRoZSBzY2FuIHdhcyB0cmlnZ2VyZWQgZHVlIHRvIGxvb2t1cERPV05Sc3NpID4gcmVhc3NvYyB0aHJlc2hvbGQsCiAgICAgICAgICogdGhlbiBpdCB3b3VsZCBiZSBhIGNvbnRpZ3VvdXMgc2NhbiBvbiBhbGwgdmFsaWQgbm9uLURGUyBjaGFubmVscy4KICAgICAgICAgKiBJZiBjaGFubmVscyBhcmUgY29uZmlndXJlZCBpbiBJTkksIHRoZW4gb25seSB0aG9zZSBjaGFubmVscyBuZWVkCiAgICAgICAgICogdG8gYmUgc2Nhbm5lZC4KICAgICAgICAgKiBJbiBlaXRoZXIgb2YgdGhlc2UgbW9kZXMsIHRoZXJlIGlzIG5vIG5lZWQgdG8gdHJpZ2dlciBhbiBpbW1lZGlhdGUKICAgICAgICAgKiBzY2FuIHVwb24gZW1wdHkgc2NhbiByZXN1bHRzIGZvciB0aGUgc2Vjb25kIGFuZCBmb3VydGggdGltZSAod2hpY2gKICAgICAgICAgKiB3b3VsZCBiZSBlcXVpdmFsZW50IHRvIHNjYW5uaW5nIG9uIGNoYW5uZWxzIGluIG5vbi1vY2N1cGllZCBsaXN0KS4KICAgICAgICAgKiBJbmNyZW1lbnRpbmcgdUVtcHR5U2NhbkNvdW50IHdpbGwgY29ycmVzcG9uZCB0byBza2lwcGluZyB0aGlzIHN0ZXAuCiAgICAgICAgICogTk9URTogZG91YmxlIGluY3JlbWVudCBvZiB1RW1wdHlTY2FuQ291bnQgY29ycmVzcG9uZHMgdG8gY29tcGxldGlvbgogICAgICAgICAqIG9mIHNjYW5zIG9uIGFsbCB2YWxpZCBjaGFubmVscy4KICAgICAgICAgKi8KICAgICAgICArK3BOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQ7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCAiRXh0cmEgaW5jcmVtZW50IG9mIGVtcHR5IHNjYW4gY291bnQgKD0lZCkiCiAgICAgICAgICAgICIgaW4gY29udGlndW91cyBzY2FuIG1vZGUiLCBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50KTsKICAgIH0KI2VuZGlmCiAgICBpZiAoKChwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKzMpIDwKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCkKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAmJiAoKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgJSAyKSA9PSAxKQojZW5kaWYKICAgICAgICApCiAgICB7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCArPSAzOwogICAgfQoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAvKiBDbGVhciBvZmYgdGhlIG9sZCBuZWlnaGJvciByZXBvcnQgZGV0YWlscyAqLwogICAgdm9zX21lbV96ZXJvKCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwojZW5kaWYKCiAgICAvKiBUcmFuc2l0aW9uIHRvIENPTk5FQ1RFRCBzdGF0ZSAqLwogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEKTsKICAgICAgICAKICAgIC8qIFJlc2V0IGFsbCB0aGUgbmVjZXNzYXJ5IHZhcmlhYmxlcyBiZWZvcmUgdHJhbnNpdGlvbmluZyB0byB0aGUgQ09OTkVDVEVEIHN0YXRlICovCiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8ocE1hYyk7CiAgICAgICAgCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlRmlyc3RFbXB0eVNjYW4pCiAgICB7CiNlbmRpZgogICAgICAgIC8qIEVtcHR5IHNjYW4gcmVzdWx0cyBmb3IgdGhlIGZpcnN0IHRpbWUgKi8KICAgICAgICAvKiBSZS1yZWdpc3RlciBuZWlnaGJvciBsb29rdXAgRE9XTiB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCAqLwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwKICAgICAgICAgICAgRkwoIlJlZ2lzdGVyaW5nIERPV04gZXZlbnQgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrIHdpdGggVEwgZm9yIFJTU0kgPSAlZCIpLAogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSk7CgogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKCiAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICBGTCgiQ291bGRuJ3QgcmUtcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2siCiAgICAgICAgICAgICAgICAgICAgICAiIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHN0YXR1cyk7CiAgICAgICAgfQojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiAgICB9CiAgICBlbHNlIGlmICgocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlU2Vjb25kRW1wdHlTY2FuKSB8fAogICAgICAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPT0gZUZvdXJ0aEVtcHR5U2NhbikpCiAgICB7CiAgICAgICAgLyogRW1wdHkgc2NhbiByZXN1bHRzIGZvciB0aGUgc2Vjb25kIG9yIGZvdXJ0aCB0aW1lICovCgogICAgICAgIC8qIEltbWVkaWF0ZWx5IHNjYW4gb24gY2hhbm5lbHMgaW4gbm9uLW9jY3VwaWVkIGxpc3QgKi8KICAgICAgICBjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbihwTWFjKTsKICAgIH0KICAgIGVsc2UgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPj0gZVRoaXJkRW1wdHlTY2FuKQogICAgewogICAgICAgIC8qIEVtcHR5IHNjYW4gcmVzdWx0cyBmb3IgdGhlIHRoaXJkIHRpbWUgKi8KICAgICAgICBpZiAocGVyZm9ybVBlcmlvZGljU2NhbikKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUGVyZm9ybWluZyBwZXJpb2RpYyBzY2FuLCB1RW1wdHlTY2FuQ291bnQ9JWQiKSwKICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQpOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogU2V0IHVFbXB0eVNjYW5Db3VudCB0byBNQVggc28gdGhhdCB3ZSBhbHdheXMgZW50ZXIgdGhpcwogICAgICAgICAgICAgKiBjb25kaXRpb24gb24gc3Vic2VxdWVudCBlbXB0eSBzY2FuIHJlc3VsdHMKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSBlTWF4RW1wdHlTY2FuOwoKICAgICAgICAgICAgLyogRnJvbSBoZXJlIG9uLCBPTkxZIHNjYW4gb24gY2hhbm5lbHMgaW4gdGhlIG9jY3VwaWVkIGxpc3QgKi8KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9IFNQTElUX1NDQU5fT0NDVVBJRURfTElTVDsKCiAgICAgICAgICAgIC8qIFN0YXJ0IGVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciAqLwogICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9CiAgICAgICAgICAgICAgICB2b3NfdGltZXJfc3RhcnQoJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIsCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5lbXB0eVNjYW5SZWZyZXNoUGVyaW9kKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJFbXB0eSBzY2FuIHJlZnJlc2ggdGltZXIgZmFpbGVkIHRvIHN0YXJ0ICglZCkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJFbXB0eSBzY2FuIHJlZnJlc2ggdGltZXIgc3RhcnRlZCAoJWQgbXMpIiksCiAgICAgICAgICAgICAgICAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmVtcHR5U2NhblJlZnJlc2hQZXJpb2QpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChlVGhpcmRFbXB0eVNjYW4gPT0gcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCkKICAgICAgICB7CiAgICAgICAgICAgIC8qIFN0YXJ0IG5laWdoYm9yIHNjYW4gcmVzdWx0cyByZWZyZXNoIHRpbWVyICovCiAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0KICAgICAgICAgICAgICAgICAgICB2b3NfdGltZXJfc3RhcnQoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIGZhaWxlZCB0byBzdGFydCAoJWQpIiksCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cyLCBGTCgiTmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIHN0YXJ0ZWQgKCVkIG1zKSIpLAogICAgICAgICAgICAgICAgICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlc3VsdHNSZWZyZXNoUGVyaW9kICogUEFMX1RJTUVSX1RPX01TX1VOSVQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsICJOZWlnaGJvciByb2FtIGVtcHR5IHNjYW4gY291bnQ9JWQgc2NhbiBtb2RlPSVkIiwKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50LCBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlKTsKI2VuZGlmCiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgoKc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZSAodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0Q3NyU2NhblJlc3VsdEZpbHRlciAgICBzY2FuRmlsdGVyOwogICAgdFNjYW5SZXN1bHRIYW5kbGUgICAgICAgc2NhblJlc3VsdDsKICAgIHRBTklfVTMyICAgICAgICAgICAgICAgIHRlbXBWYWwgPSAwOwogICAgdEFOSV9CT09MRUFOICAgICAgICAgICAgcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIGVIYWxTdGF0dXMgICAgICAgICAgICAgIGhzdGF0dXM7CgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICAgICAgLyogSWYgdGhlIHN0YXRlIGlzIFJFUE9SVF9TQ0FOLCB0aGVuIHRoaXMgbXVzdCBiZSB0aGUgc2NhbiBhZnRlciB0aGUgUkVQT1JUX1FVRVJZIHN0YXRlLiBTbywgd2UgCiAgICAgICAgICAgc2hvdWxkIHVzZSB0aGUgQlNTSUQgZmlsdGVyIG1hZGUgb3V0IG9mIG5laWdoYm9yIHJlcG9ydHMgKi8KICAgICAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAmJiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiNlbmRpZgogICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Cc3NJZFNjYW5GaWx0ZXIocE1hYywgJnNjYW5GaWx0ZXIpOwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCIxMVIgb3IgRVNFIEFzc29jaWF0aW9uOiBQcmVwYXJlIHNjYW4gZmlsdGVyIHN0YXR1cyAgd2l0aCBuZWlnaGJvciBBUCA9ICVkIiksIGhzdGF0dXMpOwogICAgICAgICAgICB0ZW1wVmFsID0gMTsKICAgICAgICB9CiAgICAgICAgZWxzZQojZW5kaWYKICAgICAgICB7CiAgICAgICAgICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1QcmVwYXJlU2NhblByb2ZpbGVGaWx0ZXIocE1hYywgJnNjYW5GaWx0ZXIpOwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCIxMVIvRVNFL090aGVyIEFzc29jaWF0aW9uOiBQcmVwYXJlIHNjYW4gdG8gZmluZCBuZWlnaGJvciBBUCBmaWx0ZXIgc3RhdHVzICA9ICVkIiksIGhzdGF0dXMpOwogICAgICAgIH0KICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBwcmVwYXJhdGlvbiBmYWlsZWQgZm9yIEFzc29jIHR5cGUgJWQuLiBCYWlsaW5nIG91dC4uIiksIHRlbXBWYWwpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICAgICAgaHN0YXR1cyA9IGNzclNjYW5HZXRSZXN1bHQocE1hYywgJnNjYW5GaWx0ZXIsICZzY2FuUmVzdWx0KTsKICAgICAgICBpZiAoaHN0YXR1cyAhPSBlSEFMX1NUQVRVU19TVUNDRVNTKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiR2V0IFNjYW4gUmVzdWx0IHN0YXR1cyBjb2RlICVkIiksIGhzdGF0dXMpOwogICAgICAgIH0KICAgICAgICAvKiBQcm9jZXNzIHRoZSBzY2FuIHJlc3VsdHMgYW5kIHVwZGF0ZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgcm9hbU5vdyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuUmVzdWx0cyhwTWFjLCAmc2NhblJlc3VsdCk7CgogICAgICAgIC8qIEZyZWUgdGhlIHNjYW4gZmlsdGVyICovCiAgICAgICAgY3NyRnJlZVNjYW5GaWx0ZXIocE1hYywgJnNjYW5GaWx0ZXIpOwoKICAgICAgICB0ZW1wVmFsID0gY3NyTExDb3VudCgmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZighY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICB7CiNlbmRpZgogICAgICAgICBzd2l0Y2gocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTjoKICAgICAgICAgICAgICAgIGlmICh0ZW1wVmFsKQogICAgICAgICAgICAgICAgewojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogU2luY2UgdGhlcmUgYXJlIG5vbi16ZXJvIGNhbmRpZGF0ZXMgZm91bmQKICAgICAgICAgICAgICAgICAgICAgKiBhZnRlciB0aGUgc2NhbiwgcmVzZXQgZW1wdHkgc2NhbiBjb3VudC4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gMDsKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gREVGQVVMVF9TQ0FOOwojZW5kaWYKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgICAgICAgICAgICAgLyogSWYgdGhpcyBpcyBhIG5vbi0xMXIgYXNzb2NpYXRpb24sIHRoZW4gd2UgY2FuIHJlZ2lzdGVyIHRoZSByZWFzc29jIGNhbGxiYWNrIGhlcmUgYXMgd2UgaGF2ZSBzb21lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVBzIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVmFsaWQgQVBzIGFyZSBmb3VuZCBhZnRlciBzY2FuLiBOb3cgd2UgY2FuIGluaXRpYXRlIHByZS1hdXRoZW50aWNhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgICAgICAgICAgICAgICAgICAvKiBJZiB0aGlzIGlzIGEgbm9uLTExciBhc3NvY2lhdGlvbiwgdGhlbiB3ZSBjYW4gcmVnaXN0ZXIgdGhlIHJlYXNzb2MgY2FsbGJhY2sgaGVyZSBhcyB3ZSBoYXZlIHNvbWUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBUHMgaW4gdGhlIHJvYW1hYmxlIEFQIGxpc3QgKi8KICAgICAgICAgICAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBWYWxpZCBBUHMgYXJlIGZvdW5kIGFmdGVyIHNjYW4uIE5vdyB3ZSBjYW4gaW5pdGlhdGUgcHJlLWF1dGhlbnRpY2F0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiNlbmRpZgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAgICAgICAgIC8qIElmIExGUiBpcyBlbmFibGVkLCB0aGVuIHdlIGNhbiByZWdpc3RlciB0aGUgcmVhc3NvYyBjYWxsYmFjayBoZXJlIGFzIHdlIGhhdmUgc29tZSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFQcyBpbiB0aGUgcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgQ1NSX1NFU1NJT05fSURfSU5WQUxJRCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBWYWxpZCBBUHMgYXJlIGZvdW5kIGFmdGVyIHNjYW4uIE5vdyB3ZSBjYW4gaW5pdGlhdGUgcHJlLWF1dGhlbnRpY2F0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiNlbmRpZgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiQ29tcGxldGVkIHNjYW5uaW5nIG9mIENGRyBDSEFOIExJU1QgaW4gbm9uLTExciBhc3NvY2lhdGlvbi4gUmVnaXN0ZXJpbmcgcmVhc3NvYyBjYWxsYmFjayIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgLyogTm90aGluZyBtdWNoIHRvIGRvIG5vdy4gV2lsbCBjb250aW51ZSB0byByZW1haW4gaW4gdGhpcyBzdGF0ZSBpbiBjYXNlIG9mIG5vbi0xMXIgYXNzb2NpYXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgLyogU3RvcCB0aGUgdGltZXIuIEJ1dCBob3cgbG9uZyB0aGUgcm9hbWFibGUgQVAgbGlzdCB3aWxsIGJlIHZhbGlkIGluIGhlcmUuIEF0IHNvbWUgcG9pbnQgb2YgdGltZSwgd2UgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lZWQgdG8gcmVzdGFydCB0aGUgQ0ZHIENIQU4gbGlzdCBzY2FuIHByb2NlZHVyZSBpZiByZWFzc29jIGNhbGxiYWNrIGlzIG5vdCBpbnZva2VkIGZyb20gVEwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGhpbiBjZXJ0YWluIGR1cmF0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIAovLyAgICAgICAgICAgICAgICAgICAgICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgICAgICAgRkwoIk5vIGNhbmRpZGF0ZSBmb3VuZCBhZnRlciBzY2FubmluZyBpbiBzdGF0ZSAlcyAuLiAiKSwKICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgICAgICAgICAvKiBIYW5kbGUgaXQgYXBwcm9wcmlhdGVseSAqLwogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdChwTWFjKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOOgogICAgICAgICAgICAgICAgaWYgKCF0ZW1wVmFsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTm8gY2FuZGlkYXRlIGZvdW5kIGFmdGVyIHNjYW5uaW5nIgogICAgICAgICAgICAgICAgICAgICAgICAgICAiaW4gc3RhdGUgJXMgLi4gIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgICAgICAgICAvKiBTdG9wIHRoZSB0aW1lciBoZXJlIGFzIHRoZSBzYW1lIHRpbWVyIHdpbGwgYmUgc3RhcnRlZCBhZ2FpbiBpbiBDRkdfQ0hBTl9TQ0FOX1NUQVRFICovCiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4ocE1hYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAvLyBDYW4gY29tZSBvbmx5IGluIElOSVQgc3RhdGUuIFdoZXJlIGluIHdlIGFyZSBhc3NvY2lhdGVkLCB3ZSBzZW50IHNjYW4gYW5kIHVzZXIKICAgICAgICAgICAgICAgIC8vIGluIHRoZSBtZWFudGltZSBkZWNpZGVzIHRvIGRpc2Fzc29jLCB3ZSB3aWxsIGJlIGluIGluaXQgc3RhdGUgYW5kIHN0aWxsIHJlY2VpdmVkIGNhbGwKICAgICAgICAgICAgICAgIC8vIGJhY2sgaXNzdWVkLiBTaG91bGQgbm90IGNvbWUgaGVyZSBpbiBhbnkgb3RoZXIgc3RhdGUsIHByaW50aW5nIGp1c3QgaW4gY2FzZQogICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiU3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwoKICAgICAgICAgICAgICAgIC8vIExldHMganVzdCBleGl0IG91dCBzaWxlbnRseS4KICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICB9CiNlbmRpZgoKICAgICAgICBpZiAodGVtcFZhbCkKICAgICAgICB7CiAgICAgICAgICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKCiAgICAgICAgICAgIGlmIChyb2FtTm93KQogICAgICAgICAgICB7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIGlmKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgICAgICAgICAgewojZW5kaWYKICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICAgICAgICAgICAgICAgRkwoIkltbWVkaWF0ZSByb2FtLWRlcmVnaXN0ZXIgVVAgaW5kaWNhdGlvbi4gUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpKTsKCiAgICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwoKICAgICAgICAgICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiQ291bGRuJ3QgZGVyZWdpc3RlciBsb29rdXAgVVAgY2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICB9CiNlbmRpZgoKICAgICAgICAgICAgICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1UcmlnZ2VySGFuZG9mZihwTWFjLHBOZWlnaGJvclJvYW1JbmZvKTsKICAgICAgICAgICAgICAgIGlmKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoImNzck5laWdoYm9yUm9hbVRyaWdnZXJIYW5kb2ZmIGZhaWwgc3RhdHVzID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaHN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICAgICAgfQoKICAgICAgICBoc3RhdHVzID0gdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCk7CgogICAgICAgICAgIC8qIFRoaXMgdGltZXIgc2hvdWxkIGJlIHN0YXJ0ZWQgYmVmb3JlIHJlZ2lzdGVyaW5nIHRoZSBSZWFzc29jIGNhbGxiYWNrIHdpdGggVEwuIFRoaXMgaXMgYmVjYXVzZSwgaXQgaXMgdmVyeSBsaWtlbHkgCiAgICAgICAgICAgICogdGhhdCB0aGUgY2FsbGJhY2sgZ2V0dGluZyBjYWxsZWQgaW1tZWRpYXRlbHkgYW5kIHRoZSB0aW1lciB3b3VsZCBuZXZlciBiZSBzdG9wcGVkIHdoZW4gcHJlLWF1dGggaXMgaW4gcHJvZ3Jlc3MgKi8KICAgICAgICBpZiggaHN0YXR1cyAhPSBlSEFMX1NUQVRVU19TVUNDRVNTKQogICAgICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIGZhaWxlZCB0byBzdGFydCwgc3RhdHVzID0gJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgRE9XTiBldmVudCBSZWFzc29jIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSkpOwogICAgICAgICAgICAvKiBSZWdpc3RlciBhIHJlYXNzb2MgSW5kaWNhdGlvbiBjYWxsYmFjayAqLwogICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICB9CiAKICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZiAoY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghdGVtcFZhbCB8fCAhcm9hbU5vdykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoKGVTTUVfUk9BTV9UUklHR0VSX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikgfHwKICAgICAgICAgICAgICAgICAgIChlU01FX1JPQU1fVFJJR0dFUl9GQVNUX1JPQU0gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy9UaGlzIGlzIGlvY3RsIGJhc2VkIHJvYW1pbmcgaWYgd2UgZGlkIG5vdCBmaW5kIGFueSByb2FtYWJsZQogICAgICAgICAgICAgICAgICAgIC8vY2FuZGlkYXRlIHRoZW4ganVzdCBsb2cgaXQuCiAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFKCBWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInRlbXBWYWwgPSAldSwgcm9hbU5vdyA9ICVkIHVPc1JlcXVlc3RlZEhhbmRvZmYgPSAlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wVmFsLCByb2FtTm93LCBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSggVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTm8gNUcgY2FuZGlkYXRlIGZvdW5kIHRlbXBWYWw9JXUsIHJvYW1Ob3c9JWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcFZhbCwgcm9hbU5vdyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVBU09OX05PX0NBTkRfRk9VTkRfT1JfTk9UX1JPQU1JTkdfTk9XKTsKICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVGhlcmUgaXMgbm8gY2FuZGlkYXRlIG9yIFdlIGFyZSBub3Qgcm9hbWluZyBOb3cuCiAgICAgICAgICAgICAgICAgICAgICAgICAqIEluZm9ybSB0aGUgRlcgdG8gcmVzdGFydCBSb2FtIE9mZmxvYWQgU2NhbiAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1JFU1RBUlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUFTT05fTk9fQ0FORF9GT1VORF9PUl9OT1RfUk9BTUlOR19OT1cpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZgogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtU2NhblJlcXVlc3RDYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gcmVnaXN0ZXJlZCBpbiBjc3JTY2FuUmVxdWVzdCgpIHRvIAogICAgICAgICAgICBpbmRpY2F0ZSB0aGUgY29tcGxldGlvbiBvZiBzY2FuLiBJZiBzY2FuIGlzIGNvbXBsZXRlZCBmb3IgYWxsIHRoZSBjaGFubmVscyBpbiAKICAgICAgICAgICAgdGhlIGNoYW5uZWwgbGlzdCwgdGhpcyBmdW5jdGlvbiBnZXRzIHRoZSBzY2FuIHJlc3VsdCBhbmQgc3RhcnRzIHRoZSByZWZyZXNoIHJlc3VsdHMKICAgICAgICAgICAgdGltZXIgdG8gYXZvaWQgaGF2aW5nIHN0YWxlIHJlc3VsdHMuIElmIHNjYW4gaXMgbm90IGNvbXBsZXRlZCBvbiBhbGwgdGhlIGNoYW5uZWxzLAogICAgICAgICAgICBpdCByZXN0YXJ0cyB0aGUgbmVpZ2hib3Igc2NhbiB0aW1lciB3aGljaCBvbiBleHBpcnkgaXNzdWVzIHNjYW4gb24gdGhlIG5leHQgCiAgICAgICAgICAgIGNoYW5uZWwKCiAgICBccGFyYW0gIGhhbEhhbmRsZSAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcENvbnRleHQgLSBub3QgdXNlZAogICAgICAgICAgICBzY2FuSWQgLSBub3QgdXNlZAogICAgICAgICAgICBzdGF0dXMgLSBub3QgdXNlZAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1TY2FuUmVxdWVzdENhbGxiYWNrKHRIYWxIYW5kbGUgaGFsSGFuZGxlLCB2b2lkICpwQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTMyIHNjYW5JZCwgZUNzclNjYW5TdGF0dXMgc3RhdHVzKQp7CiAgICB0cEFuaVNpckdsb2JhbCAgICAgICAgICAgICAgICAgIHBNYWMgPSAodHBBbmlTaXJHbG9iYWwpIGhhbEhhbmRsZTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2hhbkluZGV4OwogICAgZUhhbFN0YXR1cyAgICAgICAgICAgICAgaHN0YXR1czsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHRBTklfVTMyIHNlc3Npb25JZCA9IENTUl9TRVNTSU9OX0lEX0lOVkFMSUQ7CgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICB7CiAgICAgICAgc2Vzc2lvbklkID0gKigodEFOSV9VMzIqKXBDb250ZXh0KTsKCiAgICAgICAgaWYgKCFjc3JSb2FtSXNTdGFNb2RlKHBNYWMsIHNlc3Npb25JZCkpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIklnbm9yaW5nIHNjYW4gcmVxdWVzdCBjYWxsYmFjayBvbiBub24taW5mcmEiCiAgICAgICAgICAgICAgICAgICAic2Vzc2lvbiAlZCBpbiBzdGF0ZSAlcyIpLAogICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCwgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYyxzZXNzaW9uSWQpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCB3aGVuIGZhc3Qgcm9hbSBpcyBkaXNhYmxlZC4gSWdub3JlIGl0IikpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICB9CiAgICB9CiNlbmRpZgogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgCiAgICAvKiBUaGlzIGNhbiBoYXBwZW4gd2hlbiB3ZSByZWNlaXZlIGEgVVAgZXZlbnQgZnJvbSBUTCBpbiBhbnkgb2YgdGhlIHNjYW4gc3RhdGVzLiBTaWxlbnRseSBpZ25vcmUgaXQgKi8KICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZS4gTXVzdCBiZSBiZWNhdXNlIGEgVVAgZXZlbnQgZnJvbSBUTCBhZnRlciBpc3N1aW5nIHNjYW4gcmVxdWVzdC4gSWdub3JlIGl0IikpOwogICAgICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgLyogLTEgaXMgZG9uZSBiZWNhdXNlIHRoZSBjaGFuSW5kZXggd291bGQgaGF2ZSBnb3QgaW5jcmVtZW50ZWQgYWZ0ZXIgaXNzdWluZyBhIHN1Y2Nlc3NmdWwgc2NhbiByZXF1ZXN0ICovCiAgICBjdXJyZW50Q2hhbkluZGV4ID0gKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCkgPyAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4IC0gMSkgOiAwOwoKICAgIC8qIFZhbGlkYXRlIGlucHV0cyAqLwogICAgaWYgKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCkgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoImNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2sgcmVjZWl2ZWQgZm9yIENoYW5uZWwgPSAlZCwgQ2hhbkluZGV4ID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbY3VycmVudENoYW5JbmRleF0sIGN1cnJlbnRDaGFuSW5kZXgpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiUmVjZWl2ZWQgZHVyaW5nIGNsZWFuLXVwLiBTaWxlbnRseSBpZ25vcmUgc2NhbiBjb21wbGV0aW9uIGV2ZW50LiIpKTsKICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIGlmIChlQU5JX0JPT0xFQU5fRkFMU0UgPT0gcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzKQogICAgewogICAgICAgIC8qIFNjYW4gaXMgY29tcGxldGVkIGluIHRoZSAgQ0ZHX0NIQU5fU0NBTiBzdGF0ZS4gV2UgY2FuIHRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUKICAgICAgICAgICBqdXN0IHRvIGdldCB0aGUgcmVzdWx0cyBhbmQgcGVyZm9ybSBQUkVBVVRIICovCiAgICAgICAgLyogTm93IHdlIGhhdmUgY29tcGxldGVkIHNjYW5uaW5nIHRoZSBjaGFubmVsIGxpc3QuIFdlIGhhdmUgZ2V0IHRoZSByZXN1bHQgYnkgYXBwbHlpbmcgYXBwcm9wcmlhdGUgZmlsdGVyCiAgICAgICAgICAgc29ydCB0aGUgcmVzdWx0cyBiYXNlZCBvbiBuZWlnaGJvclNjb3JlIGFuZCBSU1NJIGFuZCBzZWxlY3QgdGhlIGJlc3QgY2FuZGlkYXRlIG91dCBvZiB0aGUgbGlzdCAqLwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoIkNoYW5uZWwgbGlzdCBzY2FuIGNvbXBsZXRlZC4gQ3VycmVudCBjaGFuIGluZGV4ID0gJWQiKSwgY3VycmVudENoYW5JbmRleCk7CiAgICAgICAgVk9TX0FTU0VSVChwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPT0gMCk7CgogICAgICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlKHBNYWMpOwoKICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHByb2Nlc3MgY29tcGxldGUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIGhzdGF0dXMpOwogICAgICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKCiAgICAgICAgLyogUmVzdGFydCB0aGUgdGltZXIgZm9yIHRoZSBuZXh0IHNjYW4gc2VxdWVuY2UgYXMgc2Nhbm5pbmcgaXMgbm90IG92ZXIgKi8KICAgICAgICBoc3RhdHVzID0gdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIsCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclNjYW5QZXJpb2QpOwogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICAvKiBUaW1lciBzdGFydCBmYWlsZWQuLiBTaG91bGQgd2UgQVNTRVJUIGhlcmU/Pz8gKi8KICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIFBBTCBUaW1lciBzdGFydCBmYWlsZWQsIHN0YXR1cyA9ICVkLCBJZ25vcmluZyBzdGF0ZSB0cmFuc2l0aW9uIiksIHN0YXR1cyk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtU2NhblJlc3VsdFJlcXVlc3RDYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gcmVnaXN0ZXJlZCBpbiBjc3JTY2FuUmVxdWVzdExmclJlc3VsdCgpIHRvCiAgICAgICAgICAgIGluZGljYXRlIHRoZSBjb21wbGV0aW9uIG9mIHNjYW4uIElmIHNjYW4gaXMgY29tcGxldGVkIGZvciBhbGwgdGhlIGNoYW5uZWxzIGluCiAgICAgICAgICAgIHRoZSBjaGFubmVsIGxpc3QsIHRoaXMgZnVuY3Rpb24gZ2V0cyB0aGUgc2NhbiByZXN1bHQgYW5kIHRyZWF0cyB0aGVtIGFzIGNhbmRpZGF0ZXMKCiAgICBccGFyYW0gIGhhbEhhbmRsZSAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcENvbnRleHQgLSBub3QgdXNlZAogICAgICAgICAgICBzY2FuSWQgLSBub3QgdXNlZAogICAgICAgICAgICBzdGF0dXMgLSBub3QgdXNlZAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1TY2FuUmVzdWx0UmVxdWVzdENhbGxiYWNrKHRIYWxIYW5kbGUgaGFsSGFuZGxlLCB2b2lkICpwQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1UzMiBzY2FuSWQsIGVDc3JTY2FuU3RhdHVzIHN0YXR1cykKewogICAgdHBBbmlTaXJHbG9iYWwgICAgICAgICAgICAgICAgICBwTWFjID0gKHRwQW5pU2lyR2xvYmFsKSBoYWxIYW5kbGU7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgICAgICAgICAgICAgIGhzdGF0dXM7CgogICAgc21zTG9nKHBNYWMsIExPRzIsIEZMKCJjYWxsZWQgIikpOwogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIC8qIHdlIG11c3QgYmUgaW4gY29ubmVjdGVkIHN0YXRlLCBpZiBub3QgaWdub3JlIGl0ICovCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJSZWNlaXZlZCBpbiBub3QgQ09OTkVDVEVEIHN0YXRlLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgLyogTm93IHdlIGhhdmUgY29tcGxldGVkIHNjYW5uaW5nIHRoZSBjaGFubmVsIGxpc3QuIFdlIGhhdmUgZ2V0IHRoZSByZXN1bHQgYnkgYXBwbHlpbmcgYXBwcm9wcmlhdGUgZmlsdGVyCiAgICAgICBzb3J0IHRoZSByZXN1bHRzIGJhc2VkIG9uIG5laWdoYm9yU2NvcmUgYW5kIFJTU0kgYW5kIHNlbGVjdCB0aGUgYmVzdCBjYW5kaWRhdGUgb3V0IG9mIHRoZSBsaXN0ICovCgogICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUocE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gcHJvY2VzcyBjb21wbGV0ZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQojZW5kaWYgLy9XTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUZvcmNlUm9hbVRvNUdoU2NhbkNiKHRIYWxIYW5kbGUgaGFsSGFuZGxlLAogICAgICAgIHZvaWQgKnBDb250ZXh0LCB0QU5JX1UzMiBzY2FuSWQsIGVDc3JTY2FuU3RhdHVzIHN0YXR1cykKewogICAgdHBBbmlTaXJHbG9iYWwgICAgICAgICAgICAgICAgICBwTWFjID0gKHRwQW5pU2lyR2xvYmFsKSBoYWxIYW5kbGU7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgaHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0QU5JX1UzMiBzZXNzaW9uSWQgPSBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgewogICAgICAgIHNlc3Npb25JZCA9ICooKHRBTklfVTMyKilwQ29udGV4dCk7CiAgICAgICAgaWYgKCFjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYyxzZXNzaW9uSWQpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCB3aGVuIGZhc3Qgcm9hbSBpcyBkaXNhYmxlZC4gSWdub3JlIGl0IikpOwogICAgICAgICAgICBoc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgZ290byBlbmQ7CiAgICAgICAgfQogICAgfQoKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTiAhPSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBuZWlnaGJvclJvYW1TdGF0ZSAlZCAuIElnbm9yZSBpdCIpLAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICBoc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICBnb3RvIGVuZDsKICAgIH0KCiAgICAvL2tlZXAgdHJhY2sgb2YgZm9yY2VkIDVHIHNjYW4gJiByb2FtIGlzIGR1ZSB0byBGb3JjZWQgaW5pdGlhbCByb2FtIHRvIDVHSHoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0ggPSAxOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIiVzOiBwcm9jZXNzIHNjYW4gcmVzdWx0cyIsIF9fZnVuY19fKTsKICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlKHBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJGb3JjZSBSb2FtIFRvIDVHaFNjYW5DYiBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwKICAgICAgICBoc3RhdHVzKTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIID0gMDsKICAgICAgICAvKgogICAgICAgICAqIFNlbmQgUlNPIHN0YXJ0IGJlY2F1c2UgaW4gY2FzZSA1RyByb2FtaW5nIGhvc3QgaGF2ZQogICAgICAgICAqIG5vdCBlbmFibGVkIGF0IGluaXRpYWwgY29ubmVjdGlvbgogICAgICAgICAqLwogICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwgUkVBU09OX0NPTk5FQ1QpOwogICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICB9CgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgIHJldHVybiBoc3RhdHVzOwoKZW5kOgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgIHJldHVybiBoc3RhdHVzOwp9CiNlbmRpZgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtQ29udGlndW91c1NjYW5SZXF1ZXN0Q2FsbGJhY2sodEhhbEhhbmRsZSBoYWxIYW5kbGUsCiAgICAgICAgdm9pZCAqcENvbnRleHQsIHRBTklfVTMyIHNjYW5JZCwgZUNzclNjYW5TdGF0dXMgc3RhdHVzKQp7CiAgICB0cEFuaVNpckdsb2JhbCAgICAgICAgICAgICAgICAgIHBNYWMgPSAodHBBbmlTaXJHbG9iYWwpIGhhbEhhbmRsZTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBoc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRBTklfVTMyIHNlc3Npb25JZCA9IENTUl9TRVNTSU9OX0lEX0lOVkFMSUQ7CgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICB7CiAgICAgICAgc2Vzc2lvbklkID0gKigodEFOSV9VMzIqKXBDb250ZXh0KTsKICAgICAgICBpZiAoIWNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLHNlc3Npb25JZCkpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIHdoZW4gZmFzdCByb2FtIGlzIGRpc2FibGVkLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgIH0KICAgIH0KCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uc2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgLyogVGhpcyBjYW4gaGFwcGVuIHdoZW4gd2UgcmVjZWl2ZSBhIFVQIGV2ZW50IGZyb20gVEwgaW4gYW55IG9mIHRoZSBzY2FuIHN0YXRlcy4gU2lsZW50bHkgaWdub3JlIGl0ICovCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBDT05ORUNURUQgc3RhdGUuIE11c3QgYmUgYmVjYXVzZSBhIFVQIGV2ZW50IGZyb20gVEwgYWZ0ZXIgaXNzdWluZyBzY2FuIHJlcXVlc3QuIElnbm9yZSBpdCIpKTsKICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBJTklUIHN0YXRlLiBNdXN0IGhhdmUgZGlzY29ubmVjdGVkLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICIlczogcHJvY2VzcyBzY2FuIHJlc3VsdHMiLCBfX2Z1bmNfXyk7CiAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZShwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBwcm9jZXNzIGNvbXBsZXRlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgIH0KCiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwoKICAgIHJldHVybiBoc3RhdHVzOwp9CiNlbmRpZgoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUlzc3VlQmdTY2FuUmVxdWVzdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpc3N1ZXMgQ1NSIHNjYW4gcmVxdWVzdCBhZnRlciBwb3B1bGF0aW5nIGFsbCB0aGUgQkcgc2NhbiBwYXJhbXMgCiAgICAgICAgICAgIHBhc3NlZAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcEJnU2NhblBhcmFtcyAtIFBhcmFtcyB0aGF0IG5lZWQgdG8gYmUgcG9wdWxhdGVkIGludG8gY3NyIFNjYW4gcmVxdWVzdAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUlzc3VlQmdTY2FuUmVxdWVzdCh0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdENzckJHU2NhblJlcXVlc3QgKnBCZ1NjYW5QYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTMyIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyU2NhbkNvbXBsZXRlQ2FsbGJhY2sgY2FsbGJhY2tmbikKewogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdEFOSV9VMzIgc2NhbklkOwogICAgdENzclNjYW5SZXF1ZXN0IHNjYW5SZXE7CiAgICB0QU5JX1U4IGNoYW5uZWw7CiAgICB2b2lkICogdXNlckRhdGEgPSBOVUxMOwogICAgCiAgICBpZiAoMSA9PSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKQogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoIkNoYW5uZWwgPSAlZCwgQ2hhbkluZGV4ID0gJWQiKSwKICAgICAgICAgICAgcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbMF0sIAogICAgICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgpOwoKICAgIC8vc2VuZCBkb3duIHRoZSBzY2FuIHJlcSBmb3IgMSBjaGFubmVsIG9uIHRoZSBhc3NvY2lhdGVkIFNTSUQKICAgIHZvc19tZW1fc2V0KCZzY2FuUmVxLCBzaXplb2YodENzclNjYW5SZXF1ZXN0KSwgMCk7CiAgICAvKiBGaWxsIGluIHRoZSBTU0lEIEluZm8gKi8KICAgIHNjYW5SZXEuU1NJRHMubnVtT2ZTU0lEcyA9IDE7CiAgICBzY2FuUmVxLlNTSURzLlNTSURMaXN0ID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JTU0lESW5mbykgKiBzY2FuUmVxLlNTSURzLm51bU9mU1NJRHMpOwogICAgaWYgKE5VTEwgPT0gc2NhblJlcS5TU0lEcy5TU0lETGlzdCkKICAgIHsKICAgICAgIC8vZXJyIG1zZwogICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDb3VsZG4ndCBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBTU0lELi5GcmVlaW5nIG1lbW9yeSBhbGxvY2F0ZWQgZm9yIENoYW5uZWwgTGlzdCIpKTsKICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgdm9zX21lbV96ZXJvKHNjYW5SZXEuU1NJRHMuU1NJRExpc3QsIHNpemVvZih0Q3NyU1NJREluZm8pICogc2NhblJlcS5TU0lEcy5udW1PZlNTSURzKTsKCiAgICBzY2FuUmVxLlNTSURzLlNTSURMaXN0WzBdLmhhbmRvZmZQZXJtaXR0ZWQgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgIHNjYW5SZXEuU1NJRHMuU1NJRExpc3RbMF0uc3NpZEhpZGRlbiA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgdm9zX21lbV9jb3B5KCh2b2lkICopJnNjYW5SZXEuU1NJRHMuU1NJRExpc3RbMF0uU1NJRCwgKHZvaWQgKikmcEJnU2NhblBhcmFtcy0+U1NJRCwgc2l6ZW9mKHBCZ1NjYW5QYXJhbXMtPlNTSUQpKTsKICAgIAogICAgc2NhblJlcS5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVsczsKICAgIGlmICgxID09IHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICB7CiAgICAgICAgY2hhbm5lbCA9IHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0WzBdOwogICAgICAgIHNjYW5SZXEuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSAmY2hhbm5lbDsgICAgCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc2NhblJlcS5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0OwogICAgfQoKICAgIHNjYW5SZXEuQlNTVHlwZSA9IGVDU1JfQlNTX1RZUEVfSU5GUkFTVFJVQ1RVUkU7CiAgICBzY2FuUmVxLnNjYW5UeXBlID0gZVNJUl9BQ1RJVkVfU0NBTjsKICAgIHNjYW5SZXEucmVxdWVzdFR5cGUgPSBlQ1NSX1NDQU5fSE9fQkdfU0NBTjsKICAgIHNjYW5SZXEubWF4Q2huVGltZSA9IHBCZ1NjYW5QYXJhbXMtPm1heENoblRpbWU7CiAgICBzY2FuUmVxLm1pbkNoblRpbWUgPSBwQmdTY2FuUGFyYW1zLT5taW5DaG5UaW1lOwoKICAgIHVzZXJEYXRhID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRBTklfVTMyKSk7CiAgICBpZiAoTlVMTCA9PSB1c2VyRGF0YSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkZhaWxlZCB0byBhbGxvY2F0ZSBtZW1vcnkgZm9yIHNjYW4gcmVxdWVzdCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUoc2NhblJlcS5TU0lEcy5TU0lETGlzdCk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICAqKCh0QU5JX1UzMiopdXNlckRhdGEpID0gc2Vzc2lvbklkOwogICAgc3RhdHVzID0gY3NyU2NhblJlcXVlc3QocE1hYywgQ1NSX1NFU1NJT05fSURfSU5WQUxJRCwgJnNjYW5SZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICZzY2FuSWQsIGNhbGxiYWNrZm4sICh2b2lkICopIHVzZXJEYXRhKTsKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkNTUiBTY2FuIFJlcXVlc3QgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIHN0YXR1cyk7CiAgICAgICAgdm9zX21lbV9mcmVlKHNjYW5SZXEuU1NJRHMuU1NJRExpc3QpOwogICAgICAgIHZvc19tZW1fZnJlZSh1c2VyRGF0YSk7CiAgICAgICAgcmV0dXJuIHN0YXR1czsKICAgIH0KICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9UUlVFOwoKICAgIHZvc19tZW1fZnJlZShzY2FuUmVxLlNTSURzLlNTSURMaXN0KTsKICAgIGlmICgxID09IHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiQ2hhbm5lbCBMaXN0IEFkZHJlc3MgPSAlcCwgQWN0dWFsIGluZGV4ID0gJWQiKSwKICAgICAgICAgICAgICAgICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbMF0sIAogICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4KTsKCiAgICByZXR1cm4gc3RhdHVzOwp9CgpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1GaWxsTm9uQ2hhbm5lbEJnU2NhblBhcmFtcyAodHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cENzckJHU2NhblJlcXVlc3QgYmdTY2FuUGFyYW1zKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBTklfVTggICAgICAgICAgICAgYnJvYWRjYXN0QnNzaWRbXSA9IHsgMHhGRiwgMHhGRiwgMHhGRiwgMHhGRiwgMHhGRiwgMHhGRiB9OwoKICAgIHZvc19tZW1fY29weShiZ1NjYW5QYXJhbXMtPmJzc2lkLCBicm9hZGNhc3RCc3NpZCwgc2l6ZW9mKHRDc3JCc3NpZCkpOwogICAgYmdTY2FuUGFyYW1zLT5TU0lELmxlbmd0aCA9IHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELmxlbmd0aDsKICAgIHZvc19tZW1fY29weShiZ1NjYW5QYXJhbXMtPlNTSUQuc3NJZCwgCiAgICAgICAgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQuc3NJZCwKICAgICAgICBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3BOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuU1NJRC5sZW5ndGgpOwoKICAgIGJnU2NhblBhcmFtcy0+bWluQ2huVGltZSA9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWluQ2hhbm5lbFNjYW5UaW1lOwogICAgYmdTY2FuUGFyYW1zLT5tYXhDaG5UaW1lID0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5tYXhDaGFubmVsU2NhblRpbWU7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QZXJmb3JtQmdTY2FuCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGludm9rZWQgb24gZXZlcnkgZXhwaXJ5IG9mIG5laWdoYm9yU2NhblRpbWVyIHRpbGwgYWxsIAogICAgICAgICAgICB0aGUgY2hhbm5lbHMgaW4gdGhlIGNoYW5uZWwgbGlzdCBhcmUgc2Nhbm5lZC4gSXQgcG9wdWxhdGVzIG5lY2Vzc2FyeSAKICAgICAgICAgICAgcGFyYW1ldGVycyBmb3IgQkcgc2NhbiBhbmQgY2FsbHMgYXBwcm9wcmlhdGUgQVAgdG8gaW52b2tlIHRoZSBDU1Igc2NhbiAKICAgICAgICAgICAgcmVxdWVzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1QZXJmb3JtQmdTY2FuKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRBTklfVTMyIHNlc3Npb25JZCkKewogICAgZUhhbFN0YXR1cyAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICAgYmdTY2FuUGFyYW1zOwogICAgdEFOSV9VOCAgICAgICAgICAgICBjaGFubmVsID0gMDsKCiAgICBpZiAoIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCAmJgogICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyApCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiQ2hhbm5lbCBMaXN0IEFkZHJlc3MgPSAlcCIpLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0WzBdKTsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiQ2hhbm5lbCBMaXN0IEVtcHR5IikpOwogICAgICAgIC8vIEdvIGJhY2sgYW5kIHJlc3RhcnQuIE1vc3RseSB0aW1lciBzdGFydCBmYWlsdXJlIGhhcyBvY2N1cnJlZC4KICAgICAgICAvLyBXaGVuIHRpbWVyIHN0YXJ0IGlzIGRlY2xhcmVkIGEgZmFpbHVyZSwgdGhlbiB3ZSBkZWxldGUgdGhlIGxpc3QuCiAgICAgICAgLy8gU2hvdWxkIG5vdCBoYXBwZW4gbm93IGFzIHdlIHN0b3AgYW5kIHRoZW4gb25seSBzdGFydCB0aGUgc2NhbiB0aW1lci4gCiAgICAgICAgLy8gc3RpbGwgaGFuZGxlIHRoZSB1bmxpa2VseSBjYXNlLgogICAgICAgIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdChwTWFjKTsKICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQoKICAgIC8qIFZhbGlkYXRlIHRoZSBjdXJyZW50Q2hhbkluZGV4IHZhbHVlIGJlZm9yZSB1c2luZyBpdCB0byBpbmRleCB0aGUgQ2hhbm5lbExpc3QgYXJyYXkgKi8KICAgIGlmICggcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4CiAgICAgICAgICAgID4gcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiSW52YWxpZCBjaGFubmVsIGluZGV4OiAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+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+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgICAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwogICAgICAgICAgICBpZiAoIUNTUl9JU19ST0FNX1NVQlNUQVRFX0RJU0FTU09DX0hPKCBwTWFjLCBzZXNzaW9uSWQgKSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIERpc2Nvbm5lY3QgaW5kaWNhdGlvbiBkdXJpbmcgRGlzYXNzb2MgSGFuZG9mZiBzdWItc3RhdGUKICAgICAgICAgICAgICAgICAqIGlzIHJlY2VpdmVkIHdoZW4gd2UgYXJlIHRyeWluZyB0byBkaXNjb25uZWN0IHdpdGggdGhlIG9sZAogICAgICAgICAgICAgICAgICogQVAgZHVyaW5nIHJvYW0uIEJVVCwgaWYgcmVjZWl2ZSBhIGRpc2Nvbm5lY3QgaW5kaWNhdGlvbiAKICAgICAgICAgICAgICAgICAqIG91dHNpZGUgb2YgRGlzYXNzb2MgSGFuZG9mZiBzdWItc3RhdGUsIHRoZW4gaXQgbWVhbnMgdGhhdCAKICAgICAgICAgICAgICAgICAqIHRoaXMgaXMgYSBnZW51aW5lIGRpc2Nvbm5lY3QgYW5kIHdlIG5lZWQgdG8gY2xlYW4gdXAuCiAgICAgICAgICAgICAgICAgKiBPdGhlcndpc2UsIHdlIHdpbGwgYmUgc3R1Y2sgaW4gcmVhc3NvYyBzdGF0ZSB3aGljaCB3aWxsCiAgICAgICAgICAgICAgICAgKiBpbi10dXJuIGJsb2NrIHNjYW5zIChzZWUgY3NySXNTY2FuQWxsb3dlZCkuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQ6CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0SW5pdFN0YXRlQ29udHJvbEluZm8ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgICAgICB7CiNlbmRpZgogICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICAgICAgYnJlYWs7IAoKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQ6CiAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgICAgICB7CiNlbmRpZgogICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTEZSX01CQgogICAgICAgICAgICBjc3Jfc3RvcF9wcmVhdXRoX3JlYXNzb2NfbWJiX3RpbWVyKHBNYWMpOwojZW5kaWYKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTjoKICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCk7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXNldENmZ0xpc3RDaGFuU2NhbkNvbnRyb2xJbmZvKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmICghY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgewojZW5kaWYKICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkU6CiAgICAgICAgICAgIC8qIFN0b3AgcHJlLWF1dGggdG8gcmVhc3NvYyBpbnRlcnZhbCB0aW1lciAqLwogICAgICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE1hYy0+ZnQuZnRTbWVDb250ZXh0LnByZUF1dGhSZWFzc29jSW50dmxUaW1lcik7CiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU46CiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkc6CiAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXNldFByZWF1dGhDb250cm9sSW5mbyhwTWFjKTsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRSZXBvcnRTY2FuU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiUmVjZWl2ZWQgZGlzY29ubmVjdCBldmVudCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW4gc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiVHJhbnNpdGlvbmluZyB0byBJTklUIHN0YXRlIikpOwogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIC8qSW5mb3JtIHRoZSBGaXJtd2FyZSB0byBTVE9QIFNjYW5uaW5nIGFzIHRoZSBob3N0IGhhcyBhIGRpc2Nvbm5lY3QuKi8KICAgIGlmIChjc3JSb2FtSXNTdGFNb2RlKHBNYWMsIHNlc3Npb25JZCkpCiAgICB7CiAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCwgUkVBU09OX0RJU0NPTk5FQ1RFRCk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1JbmRpY2F0ZUNvbm5lY3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IENTUiBhcyBzb29uIGFzIHRoZSBzdGF0aW9uIGNvbm5lY3RzIHRvIGFuIEFQLgogICAgICAgICAgICBUaGlzIGluaXRpYWxpemVzIGFsbCB0aGUgbmVjZXNzYXJ5IGRhdGEgc3RydWN0dXJlcyByZWxhdGVkIHRvIHRoZSAKICAgICAgICAgICAgYXNzb2NpYXRlZCBBUCBhbmQgdHJhbnNpdGlvbnMgdGhlIHN0YXRlIHRvIENPTk5FQ1RFRCBzdGF0ZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgc2Vzc2lvbklkIC0gQ1NSIHNlc3Npb24gaWQgdGhhdCBnb3QgY29ubmVjdGVkCiAgICAgICAgICAgIHZvc1N0YXR1cyAtIGNvbm5lY3Qgc3RhdHVzIFNVQ0NFU1MvRkFJTFVSRQoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUluZGljYXRlQ29ubmVjdCh0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1U4IHNlc3Npb25JZCwgVk9TX1NUQVRVUyB2b3NTdGF0dXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIFZPU19TVEFUVVMgIHZzdGF0dXM7CgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICBpbnQgIGluaXRfZnRfZmxhZyA9IEZBTFNFOwojZW5kaWYKCiAgICAvLyBpZiBzZXNzaW9uIGlkIGludmFsaWQgdGhlbiB3ZSBuZWVkIHJldHVybiBmYWlsdXJlCiAgICBpZiAoTlVMTCA9PSBwTmVpZ2hib3JSb2FtSW5mbyB8fCAhQ1NSX0lTX1NFU1NJT05fVkFMSUQocE1hYywgc2Vzc2lvbklkKSB8fAogICAgICAgIChOVUxMID09IHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5wQ3VyUm9hbVByb2ZpbGUpKQogICAgewogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgc21zTG9nKHBNYWMsIExPRzIsIEZMKCJDb25uZWN0IGluZGljYXRpb24gcmVjZWl2ZWQgd2l0aCBzZXNzaW9uIGlkICVkIgogICAgICAgICAgICJpbiBzdGF0ZSAlcyIpLAogICAgICAgICAgIHNlc3Npb25JZCwgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CgogICAgLy8gQmFpbCBvdXQgaWYgdGhpcyBpcyBOT1QgYSBTVEEgcGVyc29uYQogICAgaWYgKHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5wQ3VyUm9hbVByb2ZpbGUtPmNzclBlcnNvbmEgIT0gVk9TX1NUQV9NT0RFKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSWdub3JpbmcgQ29ubmVjdCBpbmRpY2F0aW9uIHJlY2VpdmVkIGZyb20gYSBub24gU1RBIHBlcnNvbmEuIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2Vzc2lvbklkOiAlZCwgY3NyUGVyc29ubmEgJWQiKSwKICAgICAgICAgICAgICAgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAoaW50KXBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5wQ3VyUm9hbVByb2ZpbGUtPmNzclBlcnNvbmEpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIC8vIGlmIGEgY29uY3VycmVudCBzZXNzaW9uIGlzIHJ1bm5pbmcKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgaWYgKGVBTklfQk9PTEVBTl9GQUxTRSA9PSBDU1JfSVNfRkFTVFJPQU1fSU5fQ09OQ1VSUkVOQ1lfSU5JX0ZFQVRVUkVfRU5BQkxFRChwTWFjKSkKICAgIHsKI2VuZGlmCiAgICAgICAgaWYgKGNzcklzQ29uY3VycmVudFNlc3Npb25SdW5uaW5nKHBNYWMpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJZ25vcmluZyBDb25uZWN0IGluZGljYXRpb24gcmVjZWl2ZWQgaW4gbXVsdGlzZXNzaW9uICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JJc0NvbmN1cnJlbnRTZXNzaW9uUnVubmluZyhwTWFjKSk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgfQojZW5kaWYKCiAgICBzd2l0Y2ggKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRUFTU09DSUFUSU5HOgogICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogSnVzdCB0cmFuc2l0aW9uIHRoZSBzdGF0ZSB0byBJTklUIHN0YXRlLiBSZXN0IG9mIHRoZSBjbGVhbiB1cCBoYXBwZW5zIHdoZW4gd2UgZ2V0IG5leHQgY29ubmVjdCBpbmRpY2F0aW9uICovCiAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBGYWxsIHRocm91Z2ggaWYgdGhlIHN0YXR1cyBpcyBTVUNDRVNTICovCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVDoKICAgICAgICAgICAgLyogUmVzZXQgYWxsIHRoZSBkYXRhIHN0cnVjdHVyZXMgaGVyZSAqLyAKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRJbml0U3RhdGVDb250cm9sSW5mbyhwTWFjKTsKCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQgPSBzZXNzaW9uSWQ7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJbml0aWFsaXplIHRoZSBvY2N1cGllZCBsaXN0IE9OTFkgaWYgd2UgYXJlCiAgICAgICAgICAgICAqIHRyYW5zaXRpb25pbmcgZnJvbSBJTklUIHN0YXRlIHRvIENPTk5FQ1RFRCBzdGF0ZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgICAgICAgICBjc3JJbml0T2NjdXBpZWRDaGFubmVsc0xpc3QocE1hYyk7CiNlbmRpZgogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpOwoKICAgICAgICAgICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgCiAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLmJzc2lkLCBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBvcGVyYXRpb25DaGFubmVsID0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUub3BlcmF0aW9uQ2hhbm5lbDsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gMDsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpID0gMDsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9IERFRkFVTFRfU0NBTjsKI2VuZGlmCgogICAgICAgICAgICAKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgICAgICAvKiBOb3cgd2UgY2FuIGNsZWFyIHRoZSBwcmVhdXRoRG9uZSB0aGF0IHdhcyBzYXZlZCBhcyB3ZSBhcmUgY29ubmVjdGVkIGFmcmVzaCAqLwogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpOwojZW5kaWYKICAgICAgICAgICAgCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgICAgICAgICAvLyBCYXNlZCBvbiB0aGUgYXV0aCBzY2hlbWUgdGVsbCBpZiB3ZSBhcmUgMTFyCiAgICAgICAgICAgIGlmICggY3NySXNBdXRoVHlwZTExciggcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuQXV0aFR5cGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLk1ESUQubWRpZVByZXNlbnQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc0Zhc3RUcmFuc2l0aW9uRW5hYmxlZCkKICAgICAgICAgICAgICAgICAgICBpbml0X2Z0X2ZsYWcgPSBUUlVFOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiMTFyQXNzb2MgaXMgPSAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYyk7CiNlbmRpZgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgICAgICAgICAgLy8gQmFzZWQgb24gdGhlIGF1dGggc2NoZW1lIHRlbGwgaWYgd2UgYXJlIDExcgogICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuaXNFU0VBc3NvYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNGYXN0VHJhbnNpdGlvbkVuYWJsZWQpCiAgICAgICAgICAgICAgICAgICAgaW5pdF9mdF9mbGFnID0gVFJVRTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoImlzRVNFQXNzb2MgaXMgPSAlZCBmdCA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MsIGluaXRfZnRfZmxhZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKI2VuZGlmCgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAvLyBJZiAiTGVnYWN5IEZhc3QgUm9hbWluZyIgaXMgZW5hYmxlZCAKICAgICAgICAgICAgaWYgKGNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLCBzZXNzaW9uSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpbml0X2Z0X2ZsYWcgPSBUUlVFOwogICAgICAgICAgICB9CiNlbmRpZgoKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgICAgICBpZiAoIGluaXRfZnRfZmxhZyA9PSBUUlVFICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogSW5pdGlhbGl6ZSBhbGwgdGhlIGRhdGEgc3RydWN0dXJlcyBuZWVkZWQgZm9yIHRoZSAxMXIgRlQgUHJlYXV0aCAqLwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbGVkTGlzdChwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgIGlmIChjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAvKklmIHRoaXMgaXMgbm90IGEgSU5GUkEgdHlwZSBCU1MsIHRoZW4gZG8gbm90IHNlbmQgdGhlIGNvbW1hbmQKICAgICAgICAgICAgICAgICAgKiBkb3duIHRvIGZpcm13YXJlLkRvIG5vdCBzZW5kIHRoZSBTVEFSVCBjb21tYW5kIGZvciBvdGhlciBzZXNzaW9uCiAgICAgICAgICAgICAgICAgICogY29ubmVjdGlvbnMuKi8KICAgICAgICAgICAgICAgICBpZihjc3JSb2FtSXNTdGFNb2RlKHBNYWMsIHNlc3Npb25JZCkpCiAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0ggPSAwOwogICAgICAgICAgICAgICAgICAgICBpZihwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9ySW5pdGlhbEZvcmNlZFJvYW1UbzVHaEVuYWJsZSAmJgogICAgICAgICAgICAgICAgICAgICAgIChHZXRSRkJhbmQocE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUG9wZXJhdGlvbkNoYW5uZWwpID09CiAgICAgICAgICAgICAgICAgICAgICAgIFNJUl9CQU5EXzJfNF9HSFopKQogICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICogS2VlcCA1RyBhbmQgRndyIHJvYW1pbmcgbXV0dWFsbHkgZXhjbHVzaXZlIHNvIGRvIG5vdAogICAgICAgICAgICAgICAgICAgICAgICAgICogc2VuZCBSU08gc3RhcnQgTm90ZSB3ZSBoYXZlIHRvIHNlbmQgUlNPIHN0YXJ0IGluIGFsbAogICAgICAgICAgICAgICAgICAgICAgICAgICogZXJycm8gY2FzZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkRvIG5vdCBzZW5kIFJTTyBzdGFydCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmVjYXVzZSA1RyBmb3JjZSByb2FtaW5nIGlzIGVuYWJsZWQiKSk7CiAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9DT05ORUNUKTsKICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCgogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgbmVpZ2hib3IgbG9va3VwIERPV04gZXZlbnQgd2l0aCBUTCwgUlNTSSA9ICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpOwogICAgICAgICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG9ubHkgKi8KICAgICAgICAgICAgICAgIHZzdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiNlbmRpZgogICAgICAgICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2c3RhdHVzKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdnN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FEICovCiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQ29ubmVjdCBldmVudCByZWNlaXZlZCBpbiBpbnZhbGlkIHN0YXRlICVzIgogICAgICAgICAgICAgICAgICAgIi4uSWdub3JpbmcuLi4iKSwKICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQoKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbGVkTGlzdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBwdXJnZXMgYWxsIHRoZSBNQUMgYWRkcmVzc2VzIGluIHRoZSBwcmUtYXV0aCBmYWlsIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxlZExpc3QodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdEFOSV9VOCBpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzczsgaSsrKQogICAgewogICAgICAgIHZvc19tZW1femVybyhwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubWFjQWRkcmVzc1tpXSwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICB9CiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcyA9IDA7CgogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSW5pdDExckFzc29jSW5mbwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplcyAxMXIgcmVsYXRlZCBuZWlnaGJvciByb2FtIGRhdGEgc3RydWN0dXJlcwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jbml0MTFyQXNzb2NJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGVIYWxTdGF0dXMgIHN0YXR1czsKICAgIHRwQ3NyMTFyQXNzb2NOZWlnaGJvckluZm8gICBwRlRSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mbzsKCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uaXMxMXJBc3NvYyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubWF4TmVpZ2hib3JSZXRyaWVzID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk1heE5laWdoYm9yUmV0cmllczsKICAgIHBGVFJvYW1JbmZvLT5uZWlnaGJvclJlcG9ydFRpbWVvdXQgPSBDU1JfTkVJR0hCT1JfUk9BTV9SRVBPUlRfUVVFUllfVElNRU9VVDsKICAgIHBGVFJvYW1JbmZvLT5QRVByZWF1dGhSZXNwVGltZW91dCA9IENTUl9ORUlHSEJPUl9ST0FNX1BSRUFVVEhfUlNQX1dBSVRfTVVMVElQTElFUiAqIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kOwogICAgcEZUUm9hbUluZm8tPm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBGVFJvYW1JbmZvLT5wcmVhdXRoUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIAogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKICAgIHZvc19tZW1femVybyhwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodENzck5laWdoYm9yUmVwb3J0QnNzSW5mbykgKiBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCk7CgogICAgCiAgICBzdGF0dXMgPSBjc3JMTE9wZW4ocE1hYy0+aEhkZCwgJnBGVFJvYW1JbmZvLT5wcmVBdXRoRG9uZUxpc3QpOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTEwgT3BlbiBvZiBwcmVhdXRoIGRvbmUgQVAgTGlzdCBmYWlsZWQiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KICAgIHJldHVybiBzdGF0dXM7Cn0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSW5pdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpbml0aWFsaXplcyBuZWlnaGJvciByb2FtIGRhdGEgc3RydWN0dXJlcwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jbml0KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGVIYWxTdGF0dXMgc3RhdHVzOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlICAgICAgID0gICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0xPU0VEOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnByZXZOZWlnaGJvclJvYW1TdGF0ZSAgID0gICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0xPU0VEOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCAgICAgICAgICAgID0gICBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5tYXhDaGFubmVsU2NhblRpbWUgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JTY2FuTWF4Q2hhblRpbWU7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1pbkNoYW5uZWxTY2FuVGltZSA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvclNjYW5NaW5DaGFuVGltZTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4TmVpZ2hib3JSZXRyaWVzID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JMb29rdXBSc3NpVGhyZXNob2xkOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JSZWFzc29jUnNzaVRocmVzaG9sZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JTY2FuUGVyaW9kID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yU2NhblRpbWVyUGVyaW9kOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlc3VsdHNSZWZyZXNoUGVyaW9kID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2Q7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmVtcHR5U2NhblJlZnJlc2hQZXJpb2QgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uRW1wdHlTY2FuUmVmcmVzaFBlcmlvZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JJbml0aWFsRm9yY2VkUm9hbVRvNUdoRW5hYmxlID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9ySW5pdGlhbEZvcmNlZFJvYW1UbzVHaEVuYWJsZTsKCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgICA9CiAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5laWdoYm9yU2NhbkNoYW5MaXN0Lm51bUNoYW5uZWxzOwoKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgIT0gMCkKICAgIHsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0KICAgICAgICAgICAgICAgIHZvc19tZW1fbWFsbG9jKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5laWdoYm9yU2NhbkNoYW5MaXN0Lm51bUNoYW5uZWxzKTsKCiAgICAgICAgaWYgKE5VTEwgPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IEFsbG9jYXRpb24gZm9yIENGRyBDaGFubmVsIExpc3QgZmFpbGVkIikpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgICAgIH0KCiAgICAgICAgLyogVXBkYXRlIHRoZSByb2FtIGdsb2JhbCBzdHJ1Y3R1cmUgZnJvbSBDRkcgKi8KICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubmVpZ2hib3JTY2FuQ2hhbkxpc3QuY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5laWdoYm9yU2NhbkNoYW5MaXN0Lm51bUNoYW5uZWxzKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICBGTCgiaW52YWxpZCBuZWlnaGJvciByb2FtIGNoYW5uZWwgbGlzdDogJXUiKSwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpOwogICAgfQoKICAgIHZvc19tZW1fc2V0KHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRDc3JCc3NpZCksIDApOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQ7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gREVGQVVMVF9TQ0FOOwogICAgdm9zX21lbV9zZXQoJnBOZWlnaGJvclJvYW1JbmZvLT5wcmV2Q29ublByb2ZpbGUsIHNpemVvZih0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUpLCAwKTsKI2VuZGlmCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgc3RhdHVzID0gdm9zX3RpbWVyX2luaXQoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lciwgVk9TX1RJTUVSX1RZUEVfU1csCiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JTY2FuVGltZXJDYWxsYmFjaywgKHZvaWQgKilwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHRpbWVyIGFsbG9jYXRpb24gZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IHZvc190aW1lcl9pbml0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLCBWT1NfVElNRVJfVFlQRV9TVywKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXN1bHRzUmVmcmVzaFRpbWVyQ2FsbGJhY2ssICh2b2lkICopcE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIGFsbG9jYXRpb24gZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IHZvc190aW1lcl9pbml0KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyLCBWT1NfVElNRVJfVFlQRV9TVywKICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUVtcHR5U2NhblJlZnJlc2hUaW1lckNhbGxiYWNrLAogICAgICAgICAgICAgICAgKHZvaWQgKilwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJFbXB0eSBzY2FuIHJlZnJlc2ggdGltZXIgYWxsb2NhdGlvbiBmYWlsZWQiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IHZvc190aW1lcl9pbml0KCZwTmVpZ2hib3JSb2FtSW5mby0+Zm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyLCBWT1NfVElNRVJfVFlQRV9TVywKICAgICAgICAgICAgICAgIGNzckZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lckNhbGxiYWNrLCAodm9pZCAqKXBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lciB0aW1lciBhbGxvY2F0aW9uIGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IGNzckxMT3BlbihwTWFjLT5oSGRkLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkxMIE9wZW4gb2Ygcm9hbWFibGUgQVAgTGlzdCBmYWlsZWQiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5mb3JjZWRJbml0aWFsUm9hbVRvNUdIVGltZXIpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID0gQ1NSX05FSUdIQk9SX1JPQU1fSU5WQUxJRF9DSEFOTkVMX0lOREVYOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jbml0MTFyQXNzb2NJbmZvKHBNYWMpOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTEwgT3BlbiBvZiByb2FtYWJsZSBBUCBMaXN0IGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPmZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lcik7CiAgICAgICAgY3NyTExDbG9zZSgmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQojZW5kaWYKICAgIC8qIEluaXRpYWxpemUgdGhpcyB3aXRoIHRoZSBjdXJyZW50IHRpY2sgY291bnQgKi8KICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA9IHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgLy9TZXQgdGhlIExhc3QgU2VudCBDbWQgYXMgUlNPX1NUT1AKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sYXN0U2VudENtZCA9IFJPQU1fU0NBTl9PRkZMT0FEX1NUT1A7CiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUNsb3NlCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGNsb3Nlcy9mcmVlcyBhbGwgdGhlIG5laWdoYm9yIHJvYW0gZGF0YSBzdHJ1Y3R1cmVzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1DbG9zZSh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBSb2FtIEFsZ29yaXRobSBBbHJlYWR5IENsb3NlZCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgCiAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+Zm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyKTsKCiAgICAvKiBTaG91bGQgZnJlZSB1cCB0aGUgbm9kZXMgaW4gdGhlIGxpc3QgYmVmb3JlIGNsb3NpbmcgdGhlIGRvdWJsZSBMaW5rZWQgbGlzdCAqLwogICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKICAgIGNzckxMQ2xvc2UoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICAKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpCiAgICB7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9IENTUl9ORUlHSEJPUl9ST0FNX0lOVkFMSURfQ0hBTk5FTF9JTkRFWDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7ICAgIAogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgLyogRnJlZSB0aGUgcHJvZmlsZS4uICovIAogICAgY3NyUmVsZWFzZVByb2ZpbGUocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIgICAgCiAgICBjc3JSb2FtRnJlZUNvbm5lY3RQcm9maWxlKHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cHJldkNvbm5Qcm9maWxlKTsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKICAgIHZvc19tZW1femVybyhwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodENzck5laWdoYm9yUmVwb3J0QnNzSW5mbykgKiBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCk7CiAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpOwogICAgY3NyTExDbG9zZSgmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KTsKI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0xPU0VEKQogICAgCiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZXF1ZXN0SGFuZG9mZgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiB0cmlnZ2VycyBhY3R1YWwgc3dpdGNoaW5nIGZyb20gb25lIEFQIHRvIHRoZSBuZXcgQVAuCiAgICAgICAgICAgIEl0IGlzc3VlcyBkaXNhc3NvY2lhdGUgd2l0aCByZWFzb24gY29kZSBhcyBIYW5kb2ZmIGFuZCBDU1IgYXMgYSBwYXJ0IG9mIAogICAgICAgICAgICBoYW5kbGluZyBkaXNhc3NvYyByc3AsIGlzc3VlcyByZWFzc29jaWF0ZSB0byB0aGUgbmV3IEFQCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXF1ZXN0SGFuZG9mZih0cEFuaVNpckdsb2JhbCBwTWFjKQp7CgogICAgdENzclJvYW1JbmZvIHJvYW1JbmZvOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0QU5JX1UzMiBzZXNzaW9uSWQgPSBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkOwogICAgdENzck5laWdoYm9yUm9hbUJTU0luZm8gICAgIGhhbmRvZmZOb2RlOwogICAgZXh0ZXJuIHZvaWQgY3NyUm9hbVJvYW1pbmdTdGF0ZURpc2Fzc29jUnNwUHJvY2Vzc29yKCB0cEFuaVNpckdsb2JhbCBwTWFjLCB0U2lyU21lRGlzYXNzb2NSc3AgKnBTbWVEaXNhc3NvY1JzcCApOwogICAgdEFOSV9VMzIgcm9hbUlkID0gMDsKICAgIGVIYWxTdGF0dXMgc3RhdHVzOwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgdENzclJvYW1JbmZvICpyb2FtSW5mb01ldHJpY3M7CiNlbmRpZgoKICAgIGlmIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORSkgCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSb2FtIHJlcXVlc3RlZCB3aGVuIE5laWdoYm9yIHJvYW0gaXMgaW4gJXMgc3RhdGUiKSwKICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09CiAgICAgICAgIGNzck5laWdoYm9yUm9hbUdldEhhbmRvZmZBUEluZm8ocE1hYywgJmhhbmRvZmZOb2RlKSkKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICBGTCgiZmFpbGVkIHRvIG9idGFpbiBoYW5kb2ZmIEFQIikpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfREVCVUcsCiAgICAgICAgICAgICAgIEZMKCJIQU5ET0ZGIENBTkRJREFURSBCU1NJRCAiTUFDX0FERFJFU1NfU1RSKSwKICAgICAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQpKTsKCiAgICB2b3NfbWVtX3plcm8oJnJvYW1JbmZvLCBzaXplb2YodENzclJvYW1JbmZvKSk7CiAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsICZyb2FtSW5mbywgcm9hbUlkLCBlQ1NSX1JPQU1fRlRfU1RBUlQsIAogICAgICAgICAgICAgICAgZVNJUl9TTUVfU1VDQ0VTUyk7CgogICAgdm9zX21lbV96ZXJvKCZyb2FtSW5mbywgc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORykKICAgIAojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAvKiBMRlIgbWV0cmljcyAtIHByZS1hdXRoIGNvbXBsZXRpb24gbWV0cmljLgogICAgICAgU2VuZCB0aGUgZXZlbnQgdG8gc3VwcGxpY2FudCB0aGF0IHByZS1hdXRoIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgKi8KICAgIHJvYW1JbmZvTWV0cmljcyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbUluZm8pKTsKICAgIGlmIChOVUxMID09IHJvYW1JbmZvTWV0cmljcykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZCEiKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdm9zX21lbV9jb3B5KCh2b2lkICopcm9hbUluZm9NZXRyaWNzLT5ic3NpZCwKICAgICAgICAgICAgKHZvaWQgKikmaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgc2l6ZW9mKHRDc3JCc3NpZCkpOwogICAgICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwKICAgICAgICAgICAgcm9hbUluZm9NZXRyaWNzLCAwLCBlQ1NSX1JPQU1fSEFORE9WRVJfU1VDQ0VTUywgMCk7CiAgICAgICAgdm9zX21lbV9mcmVlKHJvYW1JbmZvTWV0cmljcyk7CiAgICB9CiNlbmRpZgoKICAgIC8qIEZyZWUgdGhlIHByb2ZpbGUuLiBKdXN0IHRvIG1ha2Ugc3VyZSB3ZSBkb250IGxlYWsgbWVtb3J5IGhlcmUgKi8gCiAgICBjc3JSZWxlYXNlUHJvZmlsZShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPmNzck5laWdoYm9yUm9hbVByb2ZpbGUpOwogICAgLyogQ3JlYXRlIHRoZSBIYW5kb2ZmIEFQIHByb2ZpbGUuIENvcHkgdGhlIGN1cnJlbnRseSBjb25uZWN0ZWQgcHJvZmlsZSBhbmQgdXBkYXRlIG9ubHkgdGhlIEJTU0lEIGFuZCBjaGFubmVsIG51bWJlcgogICAgICAgIFRoaXMgc2hvdWxkIGhhcHBlbiBiZWZvcmUgaXNzdWluZyBkaXNjb25uZWN0ICovCiAgICBzdGF0dXMgPSBjc3JSb2FtQ29weUNvbm5lY3RlZFByb2ZpbGUocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZSk7CiAgICBpZihlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoImNzclJvYW1Db3B5Q29ubmVjdGVkUHJvZmlsZSByZXR1cm5lZCBmYWlsZWQgJWQiKSwgc3RhdHVzKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlLkJTU0lEcy5ic3NpZCwgaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZS5DaGFubmVsSW5mby5DaGFubmVsTGlzdFswXSA9IGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbElkOwogICAgCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICIgY3NyUm9hbUhhbmRvZmZSZXF1ZXN0ZWQ6IGRpc2Fzc29jaWF0aW5nIHdpdGggY3VycmVudCBBUCIpOwoKICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1MoY3NyUm9hbUlzc3VlRGlzYXNzb2NpYXRlQ21kKHBNYWMsIHNlc3Npb25JZCwgZUNTUl9ESVNDT05ORUNUX1JFQVNPTl9IQU5ET0ZGKSkpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csICJjc3JSb2FtSGFuZG9mZlJlcXVlc3RlZDogIGZhaWwgdG8gaXNzdWUgZGlzYXNzb2NpYXRlIik7CiAgICAgICAgcmV0dXJuOwogICAgfSAgICAgICAgICAgICAgICAgICAgICAgCgogICAgLy9ub3RpZnkgSEREIGZvciBoYW5kb2ZmLCBwcm92aWRpbmcgdGhlIEJTU0lEIHRvbwogICAgcm9hbUluZm8ucmVhc29uQ29kZSA9IGVDc3JSb2FtUmVhc29uQmV0dGVyQVA7CgogICAgdm9zX21lbV9jb3B5KHJvYW1JbmZvLmJzc2lkLCAKICAgICAgICAgICAgICAgICBoYW5kb2ZmTm9kZS5wQnNzRGVzY3JpcHRpb24tPmJzc0lkLCAKICAgICAgICAgICAgICAgICBzaXplb2YoIHRDc3JCc3NpZCApKTsKCiAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHNlc3Npb25JZCwgJnJvYW1JbmZvLCAwLCBlQ1NSX1JPQU1fUk9BTUlOR19TVEFSVCwgZUNTUl9ST0FNX1JFU1VMVF9OT05FKTsKCgogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXNIYW5kb2ZmSW5Qcm9ncmVzcwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHdoZXRoZXIgaGFuZG9mZiBpcyBpbiBwcm9ncmVzcyBvciBub3QgYmFzZWQgb24gCiAgICAgICAgICAgIHRoZSBjdXJyZW50IG5laWdoYm9yIHJvYW0gc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIGlzMTFyUmVhc3NvYyAtIFJldHVybiB3aGV0aGVyIHJlYXNzb2MgaXMgb2YgdHlwZSA4MDIuMTFyIHJlYXNzb2MKCiAgICBccmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFIGlmIHJlYXNzb2MgaW4gcHJvZ3Jlc3MsIGVBTklfQk9PTEVBTl9GQUxTRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Jc0hhbmRvZmZJblByb2dyZXNzKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwoKICAgIHJldHVybiBlQU5JX0JPT0xFQU5fRkFMU0U7Cn0KCiNpZiBkZWZpbmVkKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkKFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HKQovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXMxMXJBc3NvYwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHdoZXRoZXIgdGhlIGN1cnJlbnQgYXNzb2NpYXRpb24gaXMgYSAxMXIgYXNzb2Mgb3Igbm90CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUFOSV9CT09MRUFOX1RSVUUgaWYgY3VycmVudCBhc3NvYyBpcyAxMXIsIGVBTklfQk9PTEVBTl9GQUxTRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1JczExckFzc29jKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHJldHVybiBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uaXMxMXJBc3NvYzsKfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtR2V0SGFuZG9mZkFQSW5mbwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBiZXN0IHBvc3NpYmxlIEFQIGZvciBoYW5kb2ZmLiBGb3IgMTFSIGNhc2UsIGl0IAogICAgICAgICAgICByZXR1cm5zIHRoZSAxc3QgZW50cnkgZnJvbSBwcmUtYXV0aCBkb25lIGxpc3QuIEZvciBub24tMTFyIGNhc2UsIGl0IHJldHVybnMgCiAgICAgICAgICAgIHRoZSAxc3QgZW50cnkgZnJvbSByb2FtYWJsZSBBUCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwSGFuZG9mZk5vZGUgLSBBUCBub2RlIHRoYXQgaXMgdGhlIGhhbmRvZmYgY2FuZGlkYXRlIHJldHVybmVkCgogICAgXHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRSBpZiBhYmxlIGZpbmQgaGFuZG9mZiBBUCwgZUFOSV9CT09MRUFOX0ZBTFNFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUdldEhhbmRvZmZBUEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYywgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBIYW5kb2ZmTm9kZSkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gICAgICAgIHBCc3NOb2RlID0gTlVMTDsKICAgIAogICAgVk9TX0FTU0VSVChOVUxMICE9IHBIYW5kb2ZmTm9kZSk7IAogICAgICAgIAojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykKICAgIHsKICAgICAgICAvKiBBbHdheXMgdGhlIEJTUyBpbmZvIGluIHRoZSBoZWFkIGlzIHRoZSBoYW5kb2ZmIGNhbmRpZGF0ZSAqLwogICAgICAgIHBCc3NOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCwgTlVMTCk7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksIGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCkpOwogICAgfQogICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYykKICAgIHsKICAgICAgICAvKiBBbHdheXMgdGhlIEJTUyBpbmZvIGluIHRoZSBoZWFkIGlzIHRoZSBoYW5kb2ZmIGNhbmRpZGF0ZSAqLwogICAgICAgIHBCc3NOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCwgTlVMTCk7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksIGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCkpOwogICAgfQogICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgQ1NSX1NFU1NJT05fSURfSU5WQUxJRCkpCiAgICB7CiAgICAgICAgLyogQWx3YXlzIHRoZSBCU1MgaW5mbyBpbiB0aGUgaGVhZCBpcyB0aGUgaGFuZG9mZiBjYW5kaWRhdGUgKi8KICAgICAgICBwQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsIE5VTEwpOwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIk51bWJlciBvZiBIYW5kb2ZmIGNhbmRpZGF0ZXMgPSAlZCIpLCBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpKTsKICAgIH0KICAgIGVsc2UKI2VuZGlmCiAgICB7CiAgICAgICAgcEJzc05vZGUgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCBOVUxMKTsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJOdW1iZXIgb2YgSGFuZG9mZiBjYW5kaWRhdGVzID0gJWQiKSwgY3NyTExDb3VudCgmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KSk7CiAgICB9CgogICAgaWYgKE5VTEwgPT0gcEJzc05vZGUpCiAgICB7CiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIH0KCiAgICB2b3NfbWVtX2NvcHkocEhhbmRvZmZOb2RlLCBwQnNzTm9kZSwgc2l6ZW9mKHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvKSk7CgogICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIFRSVUUgaWYgcHJlYXV0aCBpcyBjb21wbGV0ZWQgCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gYm9vbGVhbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVN0YXRlUHJlYXV0aERvbmUodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgcmV0dXJuIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUgPT0gCiAgICAgICAgICAgICAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIFxicmllZiAgSW4gdGhlIGV2ZW50IHRoYXQgd2UgYXJlIGFzc29jaWF0ZWQgd2l0aCBBUDEgYW5kIHdlIGhhdmUKICAgIGNvbXBsZXRlZCBwcmUgYXV0aCB3aXRoIEFQMi4gVGhlbiB3ZSByZWNlaXZlIGEgZGVhdXRoL2Rpc2Fzc29jIGZyb20KICAgIEFQMS4gCiAgICBBdCB0aGlzIHBvaW50IG5laWdoYm9yIHJvYW0gaXMgaW4gcHJlIGF1dGggZG9uZSBzdGF0ZSwgcHJlIGF1dGggdGltZXIKICAgIGlzIHJ1bm5pbmcuIFdlIG5vdyBoYW5kbGUgdGhpcyBjYXNlIGJ5IHN0b3BwaW5nIHRpbWVyIGFuZCBjbGVhcmluZwogICAgdGhlIHByZS1hdXRoIHN0YXRlLiBXZSBiYXNpY2FsbHkgY2xlYXIgdXAgYW5kIGp1c3QgZ28gdG8gZGlzY29ubmVjdGVkCiAgICBzdGF0ZS4gCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gYm9vbGVhbgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVRyYW5pc3Rpb25QcmVhdXRoRG9uZVRvRGlzY29ubmVjdGVkKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgaWYgKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSAhPSAKICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORSkgcmV0dXJuOwoKICAgIC8vIFN0b3AgdGltZXIKICAgIHZvc190aW1lcl9zdG9wKCZwTWFjLT5mdC5mdFNtZUNvbnRleHQucHJlQXV0aFJlYXNzb2NJbnR2bFRpbWVyKTsKCiAgICAvLyBUcmFuc2l0aW9uIHRvIGluaXQgc3RhdGUKICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIGJhY2tncm91bmQgc2NhbiB0cmlnZ2VyZWQgYnkKICAgICAgICAgICAgTEZSIGlzIGluIHByb2dyZXNzLgoKICAgIFxwYXJhbSAgaGFsSGFuZGxlIC0gVGhlIGhhbmRsZSBmcm9tIEhERCBjb250ZXh0LgoKICAgIFxyZXR1cm4gYm9vbGVhbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVNjYW5Sc3BQZW5kaW5nICh0SGFsSGFuZGxlIGhIYWwpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVChoSGFsKTsKICAgIHJldHVybiAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIFNUQSBpcyBpbiB0aGUgbWlkZGxlIG9mIHJvYW1pbmcgc3RhdGVzCgogICAgXHBhcmFtICBoYWxIYW5kbGUgLSBUaGUgaGFuZGxlIGZyb20gSEREIGNvbnRleHQuCgogICAgXHJldHVybiBib29sZWFuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JNaWRkbGVPZlJvYW1pbmcgKHRIYWxIYW5kbGUgaEhhbCkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKGhIYWwpOwogICAgdEFOSV9CT09MRUFOIHZhbCA9IChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIRU5USUNBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUgPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOID09IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICByZXR1cm4gKHZhbCk7Cn0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQ2FuZGlkYXRlRm91bmRJbmRIZGxyCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBDU1IgYXMgc29vbiBhcyBUTCBwb3N0cyB0aGUgY2FuZGlkYXRlCiAgICAgICAgICAgIGZvdW5kIGluZGljYXRpb24gdG8gU01FIHZpYSBNQyB0aHJlYWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBNc2cgLSBNc2cgc2VudCBieSBQRQoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUNhbmRpZGF0ZUZvdW5kSW5kSGRscih0cEFuaVNpckdsb2JhbCBwTWFjLCB2b2lkKiBwTXNnKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIC8qIHdlIG11c3QgYmUgaW4gY29ubmVjdGVkIHN0YXRlLCBpZiBub3QgaWdub3JlIGl0ICovCiAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgIHx8IChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBub3QgQ09OTkVDVEVEIHN0YXRlIE9SIHVPc1JlcXVlc3RlZEhhbmRvZmYgaXMgc2V0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLAogICAgICAgICAqIHB1cmdlIG5vbi1QMlAgcmVzdWx0cyBmcm9tIHRoZSBwYXN0ICovCiAgICAgICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0KHBNYWMsIFZPU19GQUxTRSk7CiAgICAgICAgLyogT25jZSBpdCBnZXRzIHRoZSBjYW5kaWRhdGVzIGZvdW5kIGluZGljYXRpb24gZnJvbSBQRSwgd2lsbCBpc3N1ZSBhIHNjYW4KICAgICAgICAgLSByZXEgdG8gUEUgd2l0aCCTZnJlc2hTY2FulCBpbiBzY2FucmVxIHN0cnVjdHVyZSBzZXQgYXMgZm9sbG93czoKICAgICAgICAgMHg0MiAtIFJldHVybiAmIHB1cmdlIExGUiBzY2FuIHJlc3VsdHMKICAgICAgICAqLwogICAgICAgIHN0YXR1cyA9IGNzclNjYW5SZXF1ZXN0TGZyUmVzdWx0KHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtU2NhblJlc3VsdFJlcXVlc3RDYWxsYmFjaywgcE1hYyk7CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByb2Nlc3NIYW5kb2ZmUmVxCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBzdGFydCB3aXRoIHRoZSBoYW5kb2ZmIHByb2Nlc3MuIEZpcnN0IGRvIGEKICAgIFNTSUQgc2NhbiBmb3IgdGhlIEJTU0lEIHByb3ZpZGVkCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByb2Nlc3NIYW5kb2ZmUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdEFOSV9VMzIgcm9hbUlkOwogICAgdENzclJvYW1Qcm9maWxlICpwUHJvZmlsZSA9IE5VTEw7CiAgICB0Q3NyUm9hbVNlc3Npb24gKnBTZXNzaW9uID0gQ1NSX0dFVF9TRVNTSU9OKCBwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkICk7CiAgICB0QU5JX1U4IGkgPSAwOwogICAgdWludDhfdCByb2FtX25vdyA9IDA7CiAgICB1aW50OF90IHJvYW1hYmxlX2FwX2NvdW50ID0gMDsKICAgIHRDc3JTY2FuUmVzdWx0RmlsdGVyICAgIHNjYW5fZmlsdGVyOwogICAgdFNjYW5SZXN1bHRIYW5kbGUgICAgICAgc2Nhbl9yZXN1bHQ7CgogICAgaWYgKE5VTEwgPT0gcFNlc3Npb24pCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJwU2Vzc2lvbiBpcyBOVUxMICIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KCiAgICBkbwogICAgewogICAgICAgIHJvYW1JZCA9IEdFVF9ORVhUX1JPQU1fSUQoJnBNYWMtPnJvYW0pOwogICAgICAgIHBQcm9maWxlID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JSb2FtUHJvZmlsZSkpOwogICAgICAgIGlmICggTlVMTCA9PSBwUHJvZmlsZSApCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvYyBmYWlsZWQiKSk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KICAgICAgICB2b3NfbWVtX3NldChwUHJvZmlsZSwgc2l6ZW9mKHRDc3JSb2FtUHJvZmlsZSksIDApOwogICAgICAgIHN0YXR1cyA9IGNzclJvYW1Db3B5UHJvZmlsZShwTWFjLCBwUHJvZmlsZSwgcFNlc3Npb24tPnBDdXJSb2FtUHJvZmlsZSk7CiAgICAgICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJQcm9maWxlIGNvcHkgZmFpbGVkIikpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8vQWRkIHRoZSBCU1NJRCAmIENoYW5uZWwKICAgICAgICBwUHJvZmlsZS0+QlNTSURzLm51bU9mQlNTSURzID0gMTsKICAgICAgICBwUHJvZmlsZS0+QlNTSURzLmJzc2lkID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBQcm9maWxlLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwogICAgICAgIGlmIChOVUxMID09IHBQcm9maWxlLT5CU1NJRHMuYnNzaWQpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIm1lbSBhbGxvYyBmYWlsZWQgZm9yIEJTU0lEIikpOwogICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIHZvc19tZW1femVybyhwUHJvZmlsZS0+QlNTSURzLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpICogcFByb2ZpbGUtPkJTU0lEcy5udW1PZkJTU0lEcyk7CgogICAgICAgIC8qIFBvcHVsYXRlIHRoZSBCU1NJRCBmcm9tIGhhbmRvZmYgaW5mbyByZWNlaXZlZCBmcm9tIEhERCAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBwUHJvZmlsZS0+QlNTSURzLm51bU9mQlNTSURzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkoJnBQcm9maWxlLT5CU1NJRHMuYnNzaWRbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgICAgIH0KCiAgICAgICAgcFByb2ZpbGUtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgPSAxOwogICAgICAgIHBQcm9maWxlLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9CiAgICAgICAgdm9zX21lbV9tYWxsb2Moc2l6ZW9mKCpwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgcFByb2ZpbGUtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpOwogICAgICAgIGlmIChOVUxMID09IHBQcm9maWxlLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgibWVtIGFsbG9jIGZhaWxlZCBmb3IgQ2hhbm5lbExpc3QiKSk7CiAgICAgICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbMF0gPSBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uY2hhbm5lbDsKCiAgICAgICAgLyoKICAgICAgICAgKiBGb3IgVXNlciBzcGFjZSBjb25uZWN0IHJlcXVlc3RzLCB0aGUgc2NhbiBoYXMgYWxyZWFkeSBiZWVuIGRvbmUuCiAgICAgICAgICogU28sIGNoZWNrIGlmIHRoZSBCU1MgZGVzY3JpcHRvciBleGlzdHMgaW4gdGhlIHNjYW4gY2FjaGUgYW5kCiAgICAgICAgICogcHJvY2VlZCB3aXRoIHRoZSBoYW5kb2ZmIGluc3RlYWQgb2YgYSByZWR1bmRhbnQgc2NhbiBhZ2Fpbi4KICAgICAgICAgKi8KICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLnNyYyA9PSBDT05ORUNUX0NNRF9VU0VSU1BBQ0UpIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJDb25uZWN0IGNtZCB3aXRoIGJzc2lkIHdpdGhpbiBzYW1lIEVTUyIpKTsKICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJlcGFyZVNjYW5Qcm9maWxlRmlsdGVyKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMsICZzY2FuX2ZpbHRlcik7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiRmlsdGVyIGNyZWF0aW9uIHN0YXR1cyA9ICVkIiksIHN0YXR1cyk7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzclNjYW5HZXRSZXN1bHQocE1hYywgJnNjYW5fZmlsdGVyLCAmc2Nhbl9yZXN1bHQpOwogICAgICAgICAgICByb2FtX25vdyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuUmVzdWx0cyhwTWFjLCAmc2Nhbl9yZXN1bHQpOwogICAgICAgICAgICByb2FtYWJsZV9hcF9jb3VudCA9IGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICAgICAgICAgIGNzckZyZWVTY2FuRmlsdGVyKHBNYWMsICZzY2FuX2ZpbHRlcik7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgicm9hbV9ub3c9JWQsIHJvYW1hYmxlX2FwX2NvdW50PSVkIiksCiAgICAgICAgICAgICAgICAgICByb2FtX25vdywgcm9hbWFibGVfYXBfY291bnQpOwogICAgICAgIH0KICAgICAgICBpZiAocm9hbV9ub3cgJiYgcm9hbWFibGVfYXBfY291bnQpIHsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtVHJpZ2dlckhhbmRvZmYocE1hYywgcE5laWdoYm9yUm9hbUluZm8pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzclNjYW5Gb3JTU0lEKHBNYWMsIHBTZXNzaW9uLT5zZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUHJvZmlsZSwgcm9hbUlkLCBGQUxTRSk7CiAgICAgICAgICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTU0lEIHNjYW4gZmFpbGVkIikpOwogICAgICAgIH0KICAgIH13aGlsZSgwKTsKCiAgICBpZihOVUxMICE9IHBQcm9maWxlKQogICAgewogICAgICAgIGNzclJlbGVhc2VQcm9maWxlKHBNYWMsIHBQcm9maWxlKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocFByb2ZpbGUpOwogICAgfQoKICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Tc3NpZFNjYW5Eb25lCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBvbmNlIFNTSUQgc2NhbiBpcyBkb25lLiBJZiBTU0lEIHNjYW4gZmFpbGVkCiAgICB0byBmaW5kIG91ciBjYW5kaWRhdGUgYWRkIGFuIGVudHJ5IHRvIGNzciBzY2FuIGNhY2hlIG91cnNlbGYgYmVmb3JlIHN0YXJ0aW5nCiAgICB0aGUgaGFuZG9mZiBwcm9jZXNzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVNzc2lkU2NhbkRvbmUodHBBbmlTaXJHbG9iYWwgcE1hYywgZUhhbFN0YXR1cyBzdGF0dXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgICAgICAgICAgICAgICAgICAgICBoc3RhdHVzOwoKICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiY2FsbGVkICIpKTsKCiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZS4gSWdub3JlIGl0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQoKICAgIC8vaWYgU1NJRCBzY2FuIGZhaWxlZCB0byBmaW5kIG91ciBjYW5kaWRhdGUgYWRkIGFuIGVudHJ5IHRvIGNzciBzY2FuIGNhY2hlIG91cnNlbGYKICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkFkZCBhbiBlbnRyeSB0byBjc3Igc2NhbiBjYWNoZSIpKTsKICAgICAgICBoc3RhdHVzID0gY3NyU2NhbkNyZWF0ZUVudHJ5SW5TY2FuQ2FjaGUocE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uY2hhbm5lbCk7CiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiY3NyU2NhbkNyZWF0ZUVudHJ5SW5TY2FuQ2FjaGUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIGhzdGF0dXMpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CgogICAgLyogTm93IHdlIGhhdmUgY29tcGxldGVkIHNjYW5uaW5nIGZvciB0aGUgY2FuZGlkYXRlIHByb3ZpZGVkIGJ5IEhERC4gTGV0IG1vdmUgb24gdG8gSE8qLwogICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUocE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gcHJvY2VzcyBjb21wbGV0ZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyoqCiAqIGNzcl9uZWlnaGJvcl9yb2FtX2hhbmRsZXJfYXNzaWduX2hhbmRvZmZfc3JjKCkgLSBBc3NpZ24gc291cmNlIG9mCiAqCQkJCQkJCXJvYW0gaGFuZG9mZgogKiBAcE5laWdoYm9yUm9hbUluZm86IFBvaW50ZXIgdG8gY3NyIG5laWdoYm9yIHJvYW0gY29udHJvbCBpbmZvCiAqIEBwSGFuZG9mZlJlcUluZm86IFBvaW50ZXIgdG8gdGhlIEhhbmRvZmYgcmVxdWVzdAogKgogKiBSZXR1cm46IE5vbmUKICovCiNpZm5kZWYgUUNBX1dJRklfSVNPQwpzdGF0aWMgaW5saW5lIHZvaWQgY3NyX25laWdoYm9yX3JvYW1faGFuZGxlcl9hc3NpZ25faGFuZG9mZl9zcmMoCgkJCXRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvLAoJCQl0QW5pSGFuZG9mZlJlcSAqcEhhbmRvZmZSZXFJbmZvKQp7CglwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uc3JjCgkJPSBwSGFuZG9mZlJlcUluZm8tPmhhbmRvZmZfc3JjOwp9CiNlbHNlCnN0YXRpYyBpbmxpbmUgdm9pZCBjc3JfbmVpZ2hib3Jfcm9hbV9oYW5kbGVyX2Fzc2lnbl9oYW5kb2ZmX3NyYygKCQkJdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm8sCgkJCXRBbmlIYW5kb2ZmUmVxICpwSGFuZG9mZlJlcUluZm8pCnsKfQojZW5kaWYKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1IYW5kb2ZmUmVxSGRscgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgQ1NSIGFzIHNvb24gYXMgaXQgZ2V0cyBhIGhhbmRvZmYgcmVxdWVzdAogICAgICAgICAgICB0byBTTUUgdmlhIE1DIHRocmVhZAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcE1zZyAtIE1zZyBzZW50IGJ5IEhERAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUhhbmRvZmZSZXFIZGxyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHZvaWQqIHBNc2cpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFuaUhhbmRvZmZSZXEgICAgICAgICAgICAgICAgICpwSGFuZG9mZlJlcUluZm87CiAgICBlSGFsU3RhdHVzIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZS4gSWdub3JlIGl0IikpOwogICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLy9zYXZlIHRoZSBoYW5kb2ZmIGluZm8gY2FtZSBmcm9tIEhERCBhcyBwYXJ0IG9mIHRoZSByZWFzc29jIHJlcQogICAgICAgIHBIYW5kb2ZmUmVxSW5mbyA9ICh0QW5pSGFuZG9mZlJlcSAqKXBNc2c7CiAgICAgICAgaWYgKE5VTEwgIT0gcEhhbmRvZmZSZXFJbmZvKQogICAgICAgIHsKICAgICAgICAgICAgLy9zYW5pdHkgY2hlY2sKICAgICAgICAgICAgaWYgKFZPU19GQUxTRSA9PSB2b3NfbWVtX2NvbXBhcmUocEhhbmRvZmZSZXFJbmZvLT5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKSkKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5jaGFubmVsID0gcEhhbmRvZmZSZXFJbmZvLT5jaGFubmVsOwogICAgICAgICAgICAgICAgY3NyX25laWdoYm9yX3JvYW1faGFuZGxlcl9hc3NpZ25faGFuZG9mZl9zcmMocE5laWdoYm9yUm9hbUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBIYW5kb2ZmUmVxSW5mbyk7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBIYW5kb2ZmUmVxSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNik7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDE7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUFTT05fT1NfUkVRVUVTVEVEX1JPQU1JTkdfTk9XKTsKICAgICAgICAgICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImNzclJvYW1PZmZsb2FkU2NhbiBmYWlsZWQiKSk7CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCByZXEgaGFzIHNhbWUgQlNTSUQgYXMgY3VycmVudCBBUCEhIikpOwogICAgICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIG1zZyBpcyBOVUxMIikpOwogICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHJvY2VlZFdpdGhIYW5kb2ZmUmVxCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBDU1IgYXMgc29vbiBhcyBpdCBnZXRzIHJzcCBiYWNrIGZvcgogICAgICAgICAgICBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QIHdpdGggcmVhc29uIFJFQVNPTl9PU19SRVFVRVNURURfUk9BTUlOR19OT1cKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUHJvY2VlZFdpdGhIYW5kb2ZmUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgLyogd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQgKi8KICAgIGlmICgoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgfHwgKCFwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBub3QgQ09OTkVDVEVEIHN0YXRlIG9yIHVPc1JlcXVlc3RlZEhhbmRvZmYgaXMgbm90IHNldC4gSWdub3JlIGl0IikpOwogICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLy9MZXQncyBnbyBhaGVhZCB3aXRoIGhhbmRvZmYKICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzSGFuZG9mZlJlcShwTWFjKTsKICAgIH0KICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgIHsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtU3RhcnRMZnJTY2FuCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpZiBIREQgcmVxdWVzdGVkIGhhbmRvZmYgZmFpbGVkIGZvciBzb21lCiAgICByZWFzb24uIHN0YXJ0IHRoZSBMRlIgbG9naWMgYXQgdGhhdCBwb2ludC5CeSB0aGUgdGltZSwgdGhpcyBmdW5jdGlvbiBpcwogICAgY2FsbGVkLCBhIFNUT1AgY29tbWFuZCBoYXMgYWxyZWFkeSBiZWVuIGlzc3VlZC4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtU3RhcnRMZnJTY2FuKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRBTklfVTggT2ZmbG9hZENtZFN0b3BSZWFzb24pCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgIEZMKCIgdU9zUmVxdWVzdGVkSGFuZG9mZj0lZCBpc0ZvcmNlZEluaXRpYWxSb2FtVG81R0g9JWQgT2ZmbG9hZENtZFN0b3BSZWFzb24gPSAlZCIpLAogICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmLAogICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0gsCiAgICAgICAgICAgT2ZmbG9hZENtZFN0b3BSZWFzb24pOwoKICAgIGlmKE9mZmxvYWRDbWRTdG9wUmVhc29uID09IFJFQVNPTl9PU19SRVFVRVNURURfUk9BTUlOR19OT1cpCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICBpZihPZmZsb2FkQ21kU3RvcFJlYXNvbiA9PSBSRUFTT05fSU5JVElBTF9GT1JDRURfUk9BTV9UT181RykKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIID0gMDsKICAgIC8qIFRoZXJlIGlzIG5vIGNhbmRpZGF0ZSBvciBXZSBhcmUgbm90IHJvYW1pbmcgTm93LgogICAgICogSW5mb3JtIHRoZSBGVyB0byByZXN0YXJ0IFJvYW0gT2ZmbG9hZCBTY2FuICAqLwogICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fTk9fQ0FORF9GT1VORF9PUl9OT1RfUk9BTUlOR19OT1cpOwoKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CiNlbmRpZiAvL1dMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAojZW5kaWYgLyogV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcgKi8K