LyoKICogQ29weXJpZ2h0IChjKSAyMDEyLTIwMTMsIFRoZSBMaW51eCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBQcmV2aW91c2x5IGxpY2Vuc2VkIHVuZGVyIHRoZSBJU0MgbGljZW5zZSBieSBRdWFsY29tbSBBdGhlcm9zLCBJbmMuCiAqCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yCiAqIGFueSBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlCiAqIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIGFsbAogKiBjb3BpZXMuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwKICogV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRAogKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAqIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMCiAqIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUgogKiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwovKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIsIFRoZSBMaW51eCBGb3VuZGF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBQcmV2aW91c2x5IGxpY2Vuc2VkIHVuZGVyIHRoZSBJU0MgbGljZW5zZSBieSBRdWFsY29tbSBBdGhlcm9zLCBJbmMuCiAqCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yCiAqIGFueSBwdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIHByb3ZpZGVkIHRoYXQgdGhlCiAqIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2UgYXBwZWFyIGluIGFsbAogKiBjb3BpZXMuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwKICogV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRAogKiBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAqIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsIElORElSRUNULCBPUiBDT05TRVFVRU5USUFMCiAqIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTSBMT1NTIE9GIFVTRSwgREFUQSBPUgogKiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUgogKiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SCiAqIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCiAqLwoKLyoqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKiAKICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKiAgCgogIAogICAgXGZpbGUgY3NyTmVpZ2hib3JSb2FtLmMKICAKICAgIEltcGxlbWVudGF0aW9uIGZvciB0aGUgc2ltcGxlIHJvYW1pbmcgYWxnb3JpdGhtIGZvciA4MDIuMTFyIEZhc3QgdHJhbnNpdGlvbnMgYW5kIExlZ2FjeSByb2FtaW5nIGZvciBBbmRyb2lkIHBsYXRmb3JtLgogIAogICAgQ29weXJpZ2h0IChDKSAyMDEwIFF1YWxjb21tLCBJbmNvcnBvcmF0ZWQKICAKIAogICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICAgICAgICAgICAgICAgICAgICBFRElUIEhJU1RPUlkgRk9SIEZJTEUKCgogIFRoaXMgc2VjdGlvbiBjb250YWlucyBjb21tZW50cyBkZXNjcmliaW5nIGNoYW5nZXMgbWFkZSB0byB0aGUgbW9kdWxlLgogIE5vdGljZSB0aGF0IGNoYW5nZXMgYXJlIGxpc3RlZCBpbiByZXZlcnNlIGNocm9ub2xvZ2ljYWwgb3JkZXIuCgoKCiAgd2hlbiAgICAgICAgICAgd2hvICAgICAgICAgICAgICAgICB3aGF0LCB3aGVyZSwgd2h5Ci0tLS0tLS0tLS0gICAgICAgLS0tICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjA4LzAxLzEwICAgICAgICAgIE11cmFsaSAgICAgICAgICAgICBDcmVhdGVkCgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwojaWZkZWYgV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcKI2luY2x1ZGUgIndsYW5fcWN0X3dkYS5oIgojaW5jbHVkZSAicGFsQXBpLmgiCiNpbmNsdWRlICJjc3JJbnNpZGVBcGkuaCIKI2luY2x1ZGUgInNtc0RlYnVnLmgiCiNpbmNsdWRlICJsb2dEdW1wLmgiCiNpbmNsdWRlICJzbWVRb3NJbnRlcm5hbC5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZUluc2lkZS5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9ldmVudC5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9sb2cuaCIKI2luY2x1ZGUgImNzckFwaS5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZV9BcGkuaCIKI2luY2x1ZGUgImNzck5laWdoYm9yUm9hbS5oIgojaWZkZWYgRkVBVFVSRV9XTEFOX0NDWAojaW5jbHVkZSAiY3NyQ2N4LmgiCiNlbmRpZgoKI2RlZmluZSBXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlOR19ERUJVRyAxCiNpZmRlZiBXTEFOX0ZFQVRVUkVfTkVJR0hCT1JfUk9BTUlOR19ERUJVRwojZGVmaW5lIE5FSUdIQk9SX1JPQU1fREVCVUcgc21zTG9nCiNlbHNlCiNkZWZpbmUgTkVJR0hCT1JfUk9BTV9ERUJVRyh4Li4uKQojZW5kaWYKCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbVJlc2V0Q2hhbm5lbEluZm8odHBDc3JOZWlnaGJvclJvYW1DaGFubmVsSW5mbyByQ2hJbmZvKTsKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDZmdMaXN0Q2hhblNjYW5Db250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKTsKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRQcmVhdXRoQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYyk7CnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24odHBBbmlTaXJHbG9iYWwgcE1hYyk7CgpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLCB2X1U4X3QgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSk7ClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgKHZfUFZPSURfdCBwQWRhcHRlciwgdl9VOF90IHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1BWT0lEX3QgcFVzZXJDdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9TN190IGF2Z1Jzc2kpOwp2b2lkIGNzck5laWdoYm9yUm9hbVJSTU5laWdoYm9yUmVwb3J0UmVzdWx0KHZvaWQgKmNvbnRleHQsIFZPU19TVEFUVVMgdm9zU3RhdHVzKTsKZUhhbFN0YXR1cyBjc3JSb2FtQ29weUNvbm5lY3RlZFByb2ZpbGUodHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkLCB0Q3NyUm9hbVByb2ZpbGUgKnBEc3RQcm9maWxlICk7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpOwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMpOwojZW5kaWYKCiNkZWZpbmUgUk9BTV9TVEFURV9SRVRVUk5fU1RSSU5HKCBzdHIgKVwKICAgICAgICBjYXNlICggKCBzdHIgKSApOiByZXR1cm4oICNzdHIgKQoKCnZfVThfdCAqY3NyTmVpZ2hib3JSb2FtU3RhdGVUb1N0cmluZyh2X1U4X3Qgc3RhdGUpCnsKICAgIHN3aXRjaChzdGF0ZSkKICAgIHsKICAgICAgICBST0FNX1NUQVRFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DTE9TRUQgKTsKICAgICAgICBST0FNX1NUQVRFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUICk7CiAgICAgICAgUk9BTV9TVEFURV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICk7CiAgICAgICAgUk9BTV9TVEFURV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOICk7CiAgICAgICAgUk9BTV9TVEFURV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyApOwogICAgICAgIFJPQU1fU1RBVEVfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWSApOwogICAgICAgIFJPQU1fU1RBVEVfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOICk7CiAgICAgICAgUk9BTV9TVEFURV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSEVOVElDQVRJTkcgKTsKICAgICAgICBST0FNX1NUQVRFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUgKTsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gImVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9VTktOT1dOIjsKICAgIH0KCn0KCi8qIFN0YXRlIFRyYW5zaXRpb24gbWFjcm8gKi8KI2RlZmluZSBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKG5ld1N0YXRlKVwKe1wKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5wcmV2TmVpZ2hib3JSb2FtU3RhdGUgPSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGU7XAogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlID0gbmV3U3RhdGU7XAogICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLCBcCiAgICAgICAgICAgICAgIEZMKCJOZWlnaGJvciBSb2FtIFRyYW5zaXRpb24gZnJvbSBzdGF0ZSAlcyA9PT4gJXMiKSwgXAogICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1TdGF0ZVRvU3RyaW5nIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucHJldk5laWdoYm9yUm9hbVN0YXRlKSwgXAogICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1TdGF0ZVRvU3RyaW5nIChuZXdTdGF0ZSkpO1wKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUZyZWVOZWlnaGJvclJvYW1CU1NOb2RlCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGZyZWVzIGFsbCB0aGUgaW50ZXJuYWwgcG9pbnRlcnMgQ1NSIE5laWdoYm9yUm9hbSBCU1MgSW5mbyAKICAgICAgICAgICAgYW5kIGFsc28gZnJlZXMgdGhlIG5vZGUgaXRzZWxmCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBuZWlnaGJvclJvYW1CU1NOb2RlIC0gTmVpZ2hib3IgUm9hbSBCU1MgTm9kZSB0byBiZSBmcmVlZAoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1GcmVlTmVpZ2hib3JSb2FtQlNTTm9kZSh0cEFuaVNpckdsb2JhbCBwTWFjLCB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gbmVpZ2hib3JSb2FtQlNTTm9kZSkKewogICAgaWYgKG5laWdoYm9yUm9hbUJTU05vZGUpCiAgICB7CiAgICAgICAgaWYgKG5laWdoYm9yUm9hbUJTU05vZGUtPnBCc3NEZXNjcmlwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShuZWlnaGJvclJvYW1CU1NOb2RlLT5wQnNzRGVzY3JpcHRpb24pOwogICAgICAgICAgICBuZWlnaGJvclJvYW1CU1NOb2RlLT5wQnNzRGVzY3JpcHRpb24gPSBOVUxMOwogICAgICAgIH0KICAgICAgICB2b3NfbWVtX2ZyZWUobmVpZ2hib3JSb2FtQlNTTm9kZSk7CiAgICAgICAgbmVpZ2hib3JSb2FtQlNTTm9kZSA9IE5VTEw7CiAgICB9CgogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVtb3ZlUm9hbWFibGVBUExpc3RFbnRyeQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZW1vdmVzIGEgZ2l2ZW4gZW50cnkgZnJvbSB0aGUgZ2l2ZW4gbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcExpc3QgLSBUaGUgbGlzdCBmcm9tIHdoaWNoIHRoZSBlbnRyeSBzaG91bGQgYmUgcmVtb3ZlZAogICAgICAgICAgICBwTmVpZ2hib3JFbnRyeSAtIE5laWdoYm9yIFJvYW0gQlNTIE5vZGUgdG8gYmUgcmVtb3ZlZAoKICAgIFxyZXR1cm4gVFJVRSBpZiBzdWNjZXNzZnVsbHkgcmVtb3ZlZCwgZWxzZSBGQUxTRQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVJlbW92ZVJvYW1hYmxlQVBMaXN0RW50cnkodHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHREYmxMaW5rTGlzdCAqcExpc3QsIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBwTmVpZ2hib3JFbnRyeSkKewogICAgaWYocExpc3QpCiAgICB7CiAgICAgICAgcmV0dXJuIGNzckxMUmVtb3ZlRW50cnkocExpc3QsICZwTmVpZ2hib3JFbnRyeS0+TGlzdCwgTExfQUNDRVNTX0xPQ0spOwogICAgfQoKICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVtb3ZpbmcgbmVpZ2hib3IgQlNTIG5vZGUgZnJvbSBsaXN0IGZhaWxlZC4gQ3VycmVudCBjb3VudCA9ICVkIiksIGNzckxMQ291bnQocExpc3QpKTsKCiAgICByZXR1cm4gZUFOSV9CT09MRUFOX0ZBTFNFOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkKCiAgICBcYnJpZWYgIEdldHMgdGhlIGVudHJ5IG5leHQgdG8gcGFzc2VkIGVudHJ5LiBJZiBOVUxMIGlzIHBhc3NlZCwgcmV0dXJuIHRoZSBlbnRyeSBpbiB0aGUgaGVhZCBvZiB0aGUgbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcExpc3QgLSBUaGUgbGlzdCBmcm9tIHdoaWNoIHRoZSBlbnRyeSBzaG91bGQgYmUgcmV0dXJuZWQKICAgICAgICAgICAgcE5laWdoYm9yRW50cnkgLSBOZWlnaGJvciBSb2FtIEJTUyBOb2RlIHdob3NlIG5leHQgZW50cnkgc2hvdWxkIGJlIHJldHVybmVkCgogICAgXHJldHVybiBOZWlnaGJvciBSb2FtIEJTUyBOb2RlIHRvIGJlIHJldHVybmVkCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0cENzck5laWdoYm9yUm9hbUJTU0luZm8gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkodHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0RGJsTGlua0xpc3QgKnBMaXN0LCB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcE5laWdoYm9yRW50cnkpCnsKICAgIHRMaXN0RWxlbSAqcEVudHJ5ID0gTlVMTDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBwUmVzdWx0ID0gTlVMTDsKICAgIAogICAgaWYocExpc3QpCiAgICB7CiAgICAgICAgaWYoTlVMTCA9PSBwTmVpZ2hib3JFbnRyeSkKICAgICAgICB7CiAgICAgICAgICAgIHBFbnRyeSA9IGNzckxMUGVla0hlYWQocExpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcEVudHJ5ID0gY3NyTExOZXh0KHBMaXN0LCAmcE5laWdoYm9yRW50cnktPkxpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgICAgICB9CiAgICAgICAgaWYocEVudHJ5KQogICAgICAgIHsKICAgICAgICAgICAgcFJlc3VsdCA9IEdFVF9CQVNFX0FERFIocEVudHJ5LCB0Q3NyTmVpZ2hib3JSb2FtQlNTSW5mbywgTGlzdCk7CiAgICAgICAgfQogICAgfQogICAgCiAgICByZXR1cm4gcFJlc3VsdDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QKCiAgICBcYnJpZWYgICBFbXB0aWVzIGFuZCBmcmVlcyBhbGwgdGhlIG5vZGVzIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0IAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcExpc3QgLSBOZWlnaGJvciBSb2FtIEJTUyBMaXN0IHRvIGJlIGVtcHRpZWQKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdCh0cEFuaVNpckdsb2JhbCBwTWFjLCB0RGJsTGlua0xpc3QgKnBMaXN0KQp7CiAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcFJlc3VsdCA9IE5VTEw7CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiRW1wdHlpbmcgdGhlIEJTUyBsaXN0LiBDdXJyZW50IGNvdW50ID0gJWQiKSwgY3NyTExDb3VudChwTGlzdCkpOwoKICAgIC8qIFBpY2sgdXAgdGhlIGhlYWQsIHJlbW92ZSBhbmQgZnJlZSB0aGUgbm9kZSB0aWxsIHRoZSBsaXN0IGJlY29tZXMgZW1wdHkgKi8KICAgIHdoaWxlICgocFJlc3VsdCA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsIHBMaXN0LCBOVUxMKSkgIT0gTlVMTCkKICAgIHsKICAgICAgICBjc3JOZWlnaGJvclJvYW1SZW1vdmVSb2FtYWJsZUFQTGlzdEVudHJ5KHBNYWMsIHBMaXN0LCBwUmVzdWx0KTsKICAgICAgICBjc3JOZWlnaGJvclJvYW1GcmVlTmVpZ2hib3JSb2FtQlNTTm9kZShwTWFjLCBwUmVzdWx0KTsKICAgIH0KICAgIHJldHVybjsKfQoKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtVHJpZ2dlckhhbmRvZmYodHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8pCnsKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICApCiAgICB7CiAgICAgICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgewogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEocE1hYyk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiMTFSIFJlYXNzb2MgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiB1bmV4cGVjdGVkIHN0YXRlICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgICAgIFZPU19BU1NFUlQoMCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQojZW5kaWYKCiNpZmRlZiBGRUFUVVJFX1dMQU5fQ0NYCiAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+aXNDQ1hBc3NvYykKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEocE1hYyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkNDWCBSZWFzc29jIGluZGljYXRpb24gcmVjZWl2ZWQgaW4gdW5leHBlY3RlZCBzdGF0ZSAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgICAgICAgICAgVk9TX0FTU0VSVCgwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiNlbmRpZgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIHx8IGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHBNYWMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTEZSIFJlYXNzb2MgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiB1bmV4cGVjdGVkIHN0YXRlICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgVk9TX0FTU0VSVCgwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiNlbmRpZgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVxdWVzdEhhbmRvZmYocE1hYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOb24tMTFSIFJlYXNzb2MgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiB1bmV4cGVjdGVkIHN0YXRlICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgVk9TX0FTU0VSVCgwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQp9CgpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVVwZGF0ZUZhc3RSb2FtaW5nRW5hYmxlZCh0cEFuaVNpckdsb2JhbCBwTWFjLCBjb25zdCB2X0JPT0xfdCBmYXN0Um9hbUVuYWJsZWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGlmIChWT1NfVFJVRSA9PSBmYXN0Um9hbUVuYWJsZWQpCiAgICAgICAgewojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJSZWdpc3RlcmluZyBuZWlnaGJvciBsb29rdXAgRE9XTiBldmVudCB3aXRoIFRMLCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCk7CiAgICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgRE9XTiBldmVudCBvbmx5ICovCiAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKICAgICAgICAgICAgaWYgKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCByZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChWT1NfRkFMU0UgPT0gZmFzdFJvYW1FbmFibGVkKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIENPTk5FQ1RFRCBzdGF0ZSwgc28gZGVyZWdpc3RlciBhbGwgZXZlbnRzIikpOwogICAgICAgICAgICAvKiBEZS1yZWdpc3RlciBleGlzdGluZyBsb29rdXAgVVAvRE9XTiwgUnNzaSBpbmRpY2F0aW9ucyAqLwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCwgUkVBU09OX0RJU0NPTk5FQ1RFRCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkN1cnJlbnRseSBpbiBJTklUIHN0YXRlLCBOb3RoaW5nIHRvIGRvIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIlVuZXhwZWN0ZWQgc3RhdGUgJWQsIHJldHVybmluZyBmYWlsdXJlIiksIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICB9CiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0NDWApWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVVwZGF0ZUNjeE1vZGVFbmFibGVkKHRwQW5pU2lyR2xvYmFsIHBNYWMsIGNvbnN0IHZfQk9PTF90IGNjeE1vZGUpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGlmIChWT1NfVFJVRSA9PSBjY3hNb2RlKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgbmVpZ2hib3IgbG9va3VwIERPV04gZXZlbnQgd2l0aCBUTCwgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIERPV04gZXZlbnQgb25seSAqLwogICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiAgICAgICAgICAgIGlmICghVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoVk9TX0ZBTFNFID09IGNjeE1vZGUpCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJDdXJyZW50bHkgaW4gQ09OTkVDVEVEIHN0YXRlLCBzbyBkZXJlZ2lzdGVyIGFsbCBldmVudHMiKSk7CiAgICAgICAgICAgIC8qIERlLXJlZ2lzdGVyIGV4aXN0aW5nIGxvb2t1cCBVUC9ET1dOLCBSc3NpIGluZGljYXRpb25zICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLCBSRUFTT05fRElTQ09OTkVDVEVEKTsKICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIElOSVQgc3RhdGUsIE5vdGhpbmcgdG8gZG8iKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiVW5leHBlY3RlZCBzdGF0ZSAlZCwgcmV0dXJuaW5nIGZhaWx1cmUiKSwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCiNlbmRpZgoKClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtU2V0TG9va3VwUnNzaVRocmVzaG9sZCh0cEFuaVNpckdsb2JhbCBwTWFjLCB2X1U4X3QgbmVpZ2hib3JMb29rdXBSc3NpVGhyZXNob2xkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIFZPU19TVEFUVVMgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJDdXJyZW50bHkgaW4gQ09OTkVDVEVEIHN0YXRlLCBzbyBkZXJlZ2lzdGVyIGFsbCBhbmQgcmUtcmVnaXN0ZXIgZm9yIERPV04gZXZlbnQgYWdhaW4iKSk7CiAgICAgICAgLyogRGUtcmVnaXN0ZXIgZXhpc3RpbmcgbG9va3VwIFVQL0RPV04sIFJzc2kgaW5kaWNhdGlvbnMgKi8KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICB7CiAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLCBSRUFTT05fRElTQ09OTkVDVEVEKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIH0KI2VuZGlmCiAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IG5laWdoYm9yTG9va3VwUnNzaVRocmVzaG9sZDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZDsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgewogICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9DT05ORUNUKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICAgIEZMKCJSZWdpc3RlcmluZyBuZWlnaGJvciBsb29rdXAgRE9XTiBldmVudCB3aXRoIFRMLCBSU1NJID0gJWQiKSwKICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKTsKICAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIERPV04gZXZlbnQgb25seSAqLwogICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgIGlmICghVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgewogICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgfQojZW5kaWYKICAgIH0KICAgIGVsc2UgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJDdXJyZW50bHkgaW4gSU5JVCBzdGF0ZSwgc2FmZSB0byBzZXQgbG9va3VwUnNzaSB0aHJlc2hvbGQiKSk7CiAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IG5laWdoYm9yTG9va3VwUnNzaVRocmVzaG9sZDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJVbmV4cGVjdGVkIHN0YXRlICVkLCByZXR1cm5pbmcgZmFpbHVyZSIpLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjawoKICAgIFxicmllZiBSZWFzc29jIGNhbGxiYWNrIGludm9rZWQgYnkgVEwgb24gY3Jvc3NpbmcgdGhlIHJlZ2lzdGVyZWQgcmUtYXNzb2MgdGhyZXNob2xkLgogICAgICAgICAgIERpcmVjdGx5IHRyaWdnZXJlIEhPIGluIGNhc2Ugb2Ygbm9uLTExciBhc3NvY2lhdGlvbgogICAgICAgICAgIEluIGNhc2Ugb2YgMTFSIGFzc29jaWF0aW9uLCB0cmlnZ2VycyBhIHByZS1hdXRoIGV2ZW50dWFsbHkgZm9sbG93ZWQgYnkgYWN0dWFsIEhPCgogICAgXHBhcmFtICBwQWRhcHRlciAtIFZPUyBDb250ZXh0CiAgICAgICAgICAgIHRyYWZmaWNTdGF0dXMgLSBVUC9ET1dOIGluZGljYXRpb24gZnJvbSBUTAogICAgICAgICAgICBwVXNlckN0eHQgLSBQYXJhbWV0ZXIgZm9yIGNhbGxiYWNrIHJlZ2lzdGVyZWQgZHVyaW5nIGNhbGxiYWNrIHJlZ2lzdHJhdGlvbi4gU2hvdWxkIGJlIHBNYWMKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrKHZfUFZPSURfdCBwQWRhcHRlciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1U4X3QgdHJhZmZpY1N0YXR1cywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1BWT0lEX3QgcFVzZXJDdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9TN190ICAgYXZnUnNzaSkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKCBwVXNlckN0eHQgKTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7ICAgCiAKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkRlcmVnaXN0ZXJpbmcgRE9XTiBldmVudCByZWFzc29jIGNhbGxiYWNrIHdpdGggVEwuIFRocmVzaG9sZCBSU1NJID0gJWQgUmVwb3J0ZWQgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICBhdmdSc3NpKTsKCiAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICB7CiAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgIH0KICAgIAogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmN2ZCByZWFzc29jIG5vdGlmaWNhdGlvbi1kZXJlZ2lzdGVyIFVQIGluZGljYXRpb24uIFRocmVzaG9sZCBSU1NJID0gJWQgUmVwb3J0ZWQgUlNTSSA9ICVkIiksCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksIGF2Z1Jzc2kpOwogICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgIHsKICAgICAgICAvL2VyciBtc2cKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgfQoKICAgIC8qIFdlIGRvbnQgbmVlZCB0byBydW4gdGhpcyB0aW1lciBhbnkgbW9yZS4gKi8KICAgIHBhbFRpbWVyU3RvcChwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIHBhbFRpbWVyU3RvcChwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKCiAgICBjc3JOZWlnaGJvclJvYW1UcmlnZ2VySGFuZG9mZihwTWFjLCBwTmVpZ2hib3JSb2FtSW5mbyk7CgogICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKfQoKLypDbGVhblVQIFJvdXRpbmVzKi8Kc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDaGFubmVsSW5mbyh0cENzck5laWdoYm9yUm9hbUNoYW5uZWxJbmZvIHJDaEluZm8pCnsKICAgICAgICBpZiAoKHJDaEluZm8tPklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9PSBGQUxTRSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscykpCiAgICAgICAgewogICAgICAgICAgICAgICAgckNoSW5mby0+Y3VycmVudENoYW5JbmRleCA9IENTUl9ORUlHSEJPUl9ST0FNX0lOVkFMSURfQ0hBTk5FTF9JTkRFWDsKICAgICAgICAgICAgICAgIHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CgogICAgICAgICAgICAgICAgaWYgKHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShyQ2hJbmZvLT5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKCiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgICAgIHJDaEluZm8tPmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgfQogICAgICAgIGVsc2UgCiAgICAgICAgewogICAgICAgICAgICAgICAgckNoSW5mby0+Y3VycmVudENoYW5JbmRleCA9IDA7CiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgfQp9CgpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldENmZ0xpc3RDaGFuU2NhbkNvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICAgICAgLyogU3RvcCBuZWlnaGJvciBzY2FuIHRpbWVyICovCiAgICAgICAgcGFsVGltZXJTdG9wKHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CgogICAgICAgIC8qIFN0b3AgbmVpZ2hib3Igc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgICAgICBwYWxUaW1lclN0b3AocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CgogICAgICAgIC8qIFN0b3AgZW1wdHkgc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgICAgICBwYWxUaW1lclN0b3AocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CgogICAgICAgIC8qIEFib3J0IGFueSBvbmdvaW5nIHNjYW4gKi8KICAgICAgICBpZiAoZUFOSV9CT09MRUFOX1RSVUUgPT0gcE5laWdoYm9yUm9hbUluZm8tPnNjYW5Sc3BQZW5kaW5nKQogICAgICAgIHsKICAgICAgICAgICAgICAgIGNzclNjYW5BYm9ydE1hY1NjYW4ocE1hYyk7CiAgICAgICAgfQogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICAgICAgLyogUmVzZXQgcm9hbSBjaGFubmVsIGxpc3QgaW5mb3JtYXRpb24gKi8KICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXNldENoYW5uZWxJbmZvKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvKTsKfQoKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRQcmVhdXRoQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0NDWCkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIC8qIFB1cmdlIHByZS1hdXRoIGZhaWwgbGlzdCAqLwogICAgICAgIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxlZExpc3QocE1hYyk7CiNlbmRpZgoKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA9IDA7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgICAgIC8qIERvIG5vdCBmcmVlIHVwIHRoZSBwcmVhdXRoIGRvbmUgbGlzdCBoZXJlICovCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPSAwOwogICAgICAgIHZvc19tZW1femVybyhwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwojZW5kaWYKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgdm9zX21lbV96ZXJvKCZwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8sIHNpemVvZih0Q3NySGFuZG9mZlJlcXVlc3QpKTsKI2VuZGlmCgp9CgpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgICAgICBWT1NfU1RBVFVTICAgICAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkRlcmVnaXN0ZXIgbmVpZ2hib3IgbG9va3VwIFVQIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSk7CgogICAgICAgIC8qIERlcmVnaXN0ZXIgcmVhc3NvYyBjYWxsYmFjay4gSWdub3JlIHJldHVybiBzdGF0dXMgKi8KICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsIAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsIAogICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICB9CgogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwKICAgICAgICAgICAgICAgICAgICAgICAgRkwoIkRlcmVnaXN0ZXJpbmcgcmVhc3NvYyBET1dOIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpKTsKCiAgICAgICAgLyogRGVyZWdpc3RlciByZWFzc29jIGNhbGxiYWNrLiBJZ25vcmUgcmV0dXJuIHN0YXR1cyAqLwogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCIgQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sgd2l0aCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgfQoKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJEZXJlZ2lzdGVyaW5nIG5laWdoYm9yTG9va3VwIERPV04gY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkIiksIAogICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSk7CgogICAgICAgIC8qIERlcmVnaXN0ZXIgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrLiBJZ25vcmUgcmV0dXJuIHN0YXR1cyAqLwogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiIENvdWxkbid0IGRlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgfQoKICAgICAgICAvKiBSZXNldCB0aHJlc2hvbGRzIG9ubHkgYWZ0ZXIgZGVyZWdpc3RlcmluZyBET1dOIGV2ZW50IGZyb20gVEwgKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yTG9va3VwVGhyZXNob2xkOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSAwOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSA9IERFRkFVTFRfU0NBTjsKI2VuZGlmCn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gd2lsbCByZXNldCB0aGUgbmVpZ2hib3Igcm9hbSBjb250cm9sIGluZm8gZGF0YSBzdHJ1Y3R1cmVzLiAKICAgICAgICAgICAgVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgaW52b2tlZCB3aGVuZXZlciB3ZSBtb3ZlIHRvIENPTk5FQ1RFRCBzdGF0ZSBmcm9tIAogICAgICAgICAgICBhbnkgc3RhdGUgb3RoZXIgdGhhbiBJTklUIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDaGFubmVsSW5mbygmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mbyk7CiAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgCiAvKiBXZSBkb250IG5lZWQgdG8gcnVuIHRoaXMgdGltZXIgYW55IG1vcmUuICovCiAgICBwYWxUaW1lclN0b3AocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7ICAgIAogICAgcGFsVGltZXJTdG9wKHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAvKiBEbyBub3QgZnJlZSB1cCB0aGUgcHJlYXV0aCBkb25lIGxpc3QgaGVyZSAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nID0gMDsKICAgIHZvc19tZW1femVybyhwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwojZW5kaWYKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgdm9zX21lbV96ZXJvKCZwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8sIHNpemVvZih0Q3NySGFuZG9mZlJlcXVlc3QpKTsKI2VuZGlmCn0KCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRSZXBvcnRTY2FuU3RhdGVDb250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQgICAgICAgICAgICA9ICAgQ1NSX1NFU1NJT05fSURfSU5WQUxJRDsKICAgIHZvc19tZW1fc2V0KHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRDc3JCc3NpZCksIDApOwogICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVySW5mby5wTWFjID0gcE1hYzsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lckluZm8uc2Vzc2lvbklkID0gQ1NSX1NFU1NJT05fSURfSU5WQUxJRDsKI2lmZGVmIEZFQVRVUkVfV0xBTl9DQ1gKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0NDWEFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmlzVk9BZG1pdHRlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5NaW5RQnNzTG9hZFJlcXVpcmVkID0gMDsKI2VuZGlmCgogICAgLyogU3RvcCBzY2FuIHJlZnJlc2ggdGltZXIgKi8KICAgIHBhbFRpbWVyU3RvcChwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIC8qIFN0b3AgZW1wdHkgc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgIHBhbFRpbWVyU3RvcChwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAvKiBQdXJnZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOyAKICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVJlc2V0SW5pdFN0YXRlQ29udHJvbEluZm8KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gd2lsbCByZXNldCB0aGUgbmVpZ2hib3Igcm9hbSBjb250cm9sIGluZm8gZGF0YSBzdHJ1Y3R1cmVzLiAKICAgICAgICAgICAgVGhpcyBmdW5jdGlvbiBzaG91bGQgYmUgaW52b2tlZCB3aGVuZXZlciB3ZSBtb3ZlIHRvIENPTk5FQ1RFRCBzdGF0ZSBmcm9tIAogICAgICAgICAgICBJTklUIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldEluaXRTdGF0ZUNvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKCiAgICAvKiBJbiBhZGRpdGlvbiB0byB0aGUgYWJvdmUgcmVzZXRzLCB3ZSBzaG91bGQgY2xlYXIgb2ZmIHRoZSBjdXJBUEJzc0lkL1Nlc3Npb24gSUQgaW4gdGhlIHRpbWVycyAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRSZXBvcnRTY2FuU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKfQoKCgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUJzc0lkU2NhbkZpbHRlcgoKICAgIFxicmllZiAgVGhpcyBBUEkgaXMgdXNlZCB0byBwcmVwYXJlIGEgZmlsdGVyIHRvIG9idGFpbiBzY2FuIHJlc3VsdHMgd2hlbiAKICAgICAgICAgICAgd2UgY29tcGxldGUgdGhlIHNjYW4gaW4gdGhlIFJFUE9SVF9TQ0FOIHN0YXRlIGFmdGVyIHJlY2VpdmluZyBhIAogICAgICAgICAgICB2YWxpZCBuZWlnaGJvciByZXBvcnQgZnJvbSBBUC4gVGhpcyBmaWx0ZXIgaW5jbHVkZXMgQlNTSURzIHJlY2VpdmVkIGZyb20gCiAgICAgICAgICAgIHRoZSBuZWlnaGJvciByZXBvcnQgZnJvbSB0aGUgQVAgaW4gYWRkaXRpb24gdG8gdGhlIG90aGVyIGZpbHRlciBwYXJhbWV0ZXJzIAogICAgICAgICAgICBjcmVhdGVkIGZyb20gY29ubmVjdGVkIHByb2ZpbGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBTY2FuRmlsdGVyIC0gU2NhbiBmaWx0ZXIgdG8gYmUgZmlsbGVkIGFuZCByZXR1cm5lZAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNmdWwgZmlsdGVyIGNyZWF0aW9uLCBjb3JyZXNwb25kaW5nIGVycm9yIAogICAgICAgICAgICBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtQnNzSWRTY2FuRmlsdGVyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRDc3JTY2FuUmVzdWx0RmlsdGVyICpwU2NhbkZpbHRlcikKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0QU5JX1U4IGkgPSAwOwoKICAgIFZPU19BU1NFUlQocFNjYW5GaWx0ZXIgIT0gTlVMTCk7CiAgICBpZiAocFNjYW5GaWx0ZXIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIHZvc19tZW1femVybyhwU2NhbkZpbHRlciwgc2l6ZW9mKHRDc3JTY2FuUmVzdWx0RmlsdGVyKSk7CgogICAgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyA9IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydDsKICAgIHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodFNpck1hY0FkZHIpICogcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyk7CiAgICBpZiAoTlVMTCA9PSBwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgQlNTSUQgbWVtIGFsbG9jIGZhaWxlZCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTEVEX0FMTE9DOwogICAgfQoKICAgIHZvc19tZW1femVybyhwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpICogcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyk7CgogICAgLyogUG9wdWxhdGUgdGhlIEJTU0lEIGZyb20gTmVpZ2hib3IgQlNTIGluZm8gcmVjZWl2ZWQgZnJvbSBuZWlnaGJvciByZXBvcnQgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzOyBpKyspCiAgICB7CiAgICAgICAgdm9zX21lbV9jb3B5KCZwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkW2ldLCAKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvW2ldLm5laWdoYm9yQnNzSWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgfQoKICAgIC8qIEZpbGwgb3RoZXIgZ2VuZXJhbCBzY2FuIGZpbHRlciBwYXJhbXMgKi8KICAgIHJldHVybiBjc3JOZWlnaGJvclJvYW1QcmVwYXJlU2NhblByb2ZpbGVGaWx0ZXIocE1hYywgcFNjYW5GaWx0ZXIpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbExpc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gZW1wdGllcyB0aGUgcHJlYXV0aCBmYWlsIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxMaXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIlB1cmdpbmcgdGhlIHByZWF1dGggZmFpbCBsaXN0IikpOwogICAgd2hpbGUgKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzKQogICAgewogICAgICAgIHZvc19tZW1femVybyhwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubWFjQWRkcmVzc1twTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcy0xXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MtLTsKICAgIH0KICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUFkZEJzc0lkVG9QcmVhdXRoRmFpbExpc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gYWRkcyB0aGUgZ2l2ZW4gQlNTSUQgdG8gdGhlIFByZWF1dGggZmFpbCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBic3NJZCAtIEJTU0lEIHRvIGJlIGFkZGVkIHRvIHRoZSBwcmVhdXRoIGZhaWwgbGlzdAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBlSEFMX1NUQVRVU19GQUlMVVJFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1BZGRCc3NJZFRvUHJlYXV0aEZhaWxMaXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRTaXJNYWNBZGRyIGJzc0lkKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCIgQWRkZWQgQlNTSUQgJTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4OiUwMnggdG8gUHJlYXV0aCBmYWlsZWQgbGlzdCIpLAogICAgICAgICAgICAgICAgICAgICAgICBic3NJZFswXSwgYnNzSWRbMV0sIGJzc0lkWzJdLCBic3NJZFszXSwgYnNzSWRbNF0sIGJzc0lkWzVdKTsKCgogICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcyArIDEpID4KICAgICAgICAgICAgTUFYX05VTV9QUkVBVVRIX0ZBSUxfTElTVF9BRERSRVNTKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUHJlYXV0aCBmYWlsIGxpc3QgYWxyZWFkeSBmdWxsLi4gQ2Fubm90IGFkZCBuZXcgb25lIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5tYWNBZGRyZXNzW3BOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzXSwKICAgICAgICAgICAgICAgICAgICAgICAgYnNzSWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MrKzsKICAgIAogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gY2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIE1BQyBhZGRyZXNzIGlzIGFscmVhZHkgCiAgICAgICAgICAgIHByZXNlbnQgaW4gdGhlIHByZWF1dGggZmFpbCBsaXN0IGFuZCByZXR1cm5zIFRSVUUvRkFMU0UgYWNjb3JkaW5nbHkKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRSBpZiBwcmVhdXRoIGNhbmRpZGF0ZSwgZUFOSV9CT09MRUFOX0ZBTFNFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUlzUHJlYXV0aENhbmRpZGF0ZSh0cEFuaVNpckdsb2JhbCBwTWFjLCB0U2lyTWFjQWRkciBic3NJZCkKewogICAgdEFOSV9VOCBpID0gMDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICB7CiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwogICAgfQojZW5kaWYKICAgIGlmICgwID09IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzKQogICAgICAgIHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRTsKICAgIAogICAgZm9yIChpID0gMDsgaSA8IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzOyBpKyspCiAgICB7CiAgICAgICAgaWYgKFZPU19UUlVFID09IHZvc19tZW1fY29tcGFyZShwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubWFjQWRkcmVzc1tpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnNzSWQsIHNpemVvZih0U2lyTWFjQWRkcikpKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiQlNTSUQgJTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4OiUwMnggYWxyZWFkeSBwcmVzZW50IGluIHByZWF1dGggZmFpbCBsaXN0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJzc0lkWzBdLCBic3NJZFsxXSwgYnNzSWRbMl0sIGJzc0lkWzNdLCBic3NJZFs0XSwgYnNzSWRbNV0pOwogICAgICAgICAgICByZXR1cm4gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gZUFOSV9CT09MRUFOX1RSVUU7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXNzdWVzIHByZWF1dGggcmVxdWVzdCB0byBQRSB3aXRoIHRoZSAxc3QgQVAgZW50cnkgaW4gdGhlIAogICAgICAgICAgICByb2FtYWJsZSBBUCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBlSEFMX1NUQVRVU19GQUlMVVJFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvICAgIHBOZWlnaGJvckJzc05vZGU7CiAgICAKICAgIC8qIFRoaXMgbXVzdCBub3QgYmUgdHJ1ZSBoZXJlICovCiAgICBWT1NfQVNTRVJUKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nID09IGVBTklfQk9PTEVBTl9GQUxTRSk7CgogICAgLyogSXNzdWUgUHJlYXV0aCByZXF1ZXN0IHRvIFBFIGhlcmUgKi8KICAgIC8qIE5lZWQgdG8gaXNzdWUgdGhlIHByZWF1dGggcmVxdWVzdCB3aXRoIHRoZSBCU1NJRCB0aGF0IGlzIHRoZXJlIGluIHRoZSBoZWFkIG9mIHRoZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAvKiBQYXJhbWV0ZXJzIHRoYXQgc2hvdWxkIGJlIHBhc3NlZCBhcmUgQlNTSUQsIENoYW5uZWwgbnVtYmVyIGFuZCB0aGUgbmVpZ2hib3JTY2FuUGVyaW9kKHByb2JhYmx5KSAqLwogICAgLyogSWYgcm9hbWFibGVBUExpc3QgZ2V0cyBlbXB0eSwgc2hvdWxkIHRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUgKi8KICAgIHBOZWlnaGJvckJzc05vZGUgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCBOVUxMKTsKCiAgICBpZiAoTlVMTCA9PSBwTmVpZ2hib3JCc3NOb2RlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiUm9hbWFibGUgQVAgbGlzdCBpcyBlbXB0eS4uICIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzdGF0dXMgPSBjc3JSb2FtRW5xdWV1ZVByZWF1dGgocE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgZUNzclBlcmZvcm1QcmVhdXRoLCBlQU5JX0JPT0xFQU5fVFJVRSk7CgogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiQmVmb3JlIFByZS1BdXRoOiBCU1NJRCAlMDJ4OiUwMng6JTAyeDolMDJ4OiUwMng6JTAyeCwgQ2g6JWQiKSwKICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZFswXSwKICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZFsxXSwKICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZFsyXSwKICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZFszXSwKICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZFs0XSwKICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZFs1XSwKICAgICAgICAgICAgICAgKGludClwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmNoYW5uZWxJZCk7CgogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2VuZCBQcmVhdXRoIHJlcXVlc3QgdG8gUEUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIHN0YXR1cyk7CiAgICAgICAgICAgIHJldHVybiBzdGF0dXM7CiAgICAgICAgfQogICAgfQogICAgCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9UUlVFOwoKICAgIC8qIEluY3JlbWVudCB0aGUgcHJlYXV0aCByZXRyeSBjb3VudCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMrKzsKICAgIAogICAgLyogVHJhbnNpdGlvbiB0aGUgc3RhdGUgdG8gcHJlYXV0aGVudGljYXRpbmcgKi8KICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhFTlRJQ0FUSU5HKQogICAgCiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHJlYXV0aFJzcEhhbmRsZXIKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaGFuZGxlIHRoZSBQcmVhdXRoIHJlc3BvbnNlIGZyb20gUEUKICAgICAgICAgICAgRXZlcnkgcHJlYXV0aCBpcyBhbGxvd2VkIG1heCAzIHRyaWVzIGlmIGl0IGZhaWxzLiBJZiBhIGJzc2lkIGZhaWxlZCAKICAgICAgICAgICAgZm9yIG1vcmUgdGhhbiBNQVhfVFJJRVMsIHdlIHdpbGwgcmVtb3ZlIGl0IGZyb20gdGhlIGxpc3QgYW5kIHRyeSAKICAgICAgICAgICAgd2l0aCB0aGUgbmV4dCBub2RlIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0IGFuZCBhZGQgdGhlIEJTU0lEIHRvIHByZS1hdXRoIGZhaWxlZCAKICAgICAgICAgICAgbGlzdC4gSWYgbm8gbW9yZSBlbnRyaWVzIHByZXNlbnQgaW4gCiAgICAgICAgICAgIHJvYW1hYmxlIEFQIGxpc3QsIHRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIGxpbVN0YXR1cyAtIGVTSVJfU1VDQ0VTUy9lU0lSX0ZBSUxVUkUvZVNJUl9MSU1fTUFYX1NUQV9SRUFDSEVEX0VSUk9SLwogICAgICAgICAgICAgICAgICAgICBlU0lUX0xJTV9BVVRIX1JTUF9USU1FT1VUIHN0YXR1cyBmcm9tIFBFCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MgKGkuZS4gcHJlLWF1dGggcHJvY2Vzc2VkKSwKICAgICAgICAgICAgZUhBTF9TVEFUVVNfRkFJTFVSRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUHJlYXV0aFJzcEhhbmRsZXIodHBBbmlTaXJHbG9iYWwgcE1hYywgdFNpclJldFN0YXR1cyBsaW1TdGF0dXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIGVIYWxTdGF0dXMgIHByZWF1dGhQcm9jZXNzZWQgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBQcmVhdXRoUnNwTm9kZSA9IE5VTEw7CgogICAgaWYgKGVBTklfQk9PTEVBTl9GQUxTRSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZykKICAgIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIGRpc2Nvbm5lY3QgaW1tZWRpYXRlbHkKICAgICAgICAgICAgICogYWZ0ZXIgc2VuZGluZyBhIHByZS1hdXRoIHJlcXVlc3QuIER1cmluZyBwcm9jZXNzaW5nCiAgICAgICAgICAgICAqIG9mIHRoZSBkaXNjb25uZWN0IGNvbW1hbmQsIHdlIHdvdWxkIGhhdmUgcmVzZXQKICAgICAgICAgICAgICogcHJlYXV0aFJzcFBlbmRpbmcgYW5kIHRyYW5zaXRpb25lZCB0byBJTklUIHN0YXRlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJVbmV4cGVjdGVkIHByZS1hdXRoIHJlc3BvbnNlIGluIHN0YXRlICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICAgICAgcHJlYXV0aFByb2Nlc3NlZCA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIGdvdG8gREVRX1BSRUFVVEg7CiAgICB9ICAgIAoKICAgIC8vIFdlIGNhbiByZWNlaXZlIGl0IGluIHRoZXNlIDIgc3RhdGVzLgogICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhFTlRJQ0FUSU5HKSAmJgogICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOKSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJQcmVhdXRoIHJlc3BvbnNlIHJlY2VpdmVkIGluIHN0YXRlICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgIHByZWF1dGhQcm9jZXNzZWQgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIGdvdG8gREVRX1BSRUFVVEg7CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgaWYgKGVTSVJfU1VDQ0VTUyA9PSBsaW1TdGF0dXMpCiAgICB7CiAgICAgICAgcFByZWF1dGhSc3BOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgTlVMTCk7CiAgICB9CiAgICBpZiAoKGVTSVJfU1VDQ0VTUyA9PSBsaW1TdGF0dXMpICYmIChOVUxMICE9IHBQcmVhdXRoUnNwTm9kZSkpCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiUHJlYXV0aCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5IGFmdGVyICVkIHRyaWVzIiksIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzKTsKCiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJBZnRlciBQcmUtQXV0aDogQlNTSUQgJTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4OiUwMngsIENoOiVkIiksCiAgICAgICAgICAgICAgIHBQcmVhdXRoUnNwTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZFswXSwKICAgICAgICAgICAgICAgcFByZWF1dGhSc3BOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkWzFdLAogICAgICAgICAgICAgICBwUHJlYXV0aFJzcE5vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWRbMl0sCiAgICAgICAgICAgICAgIHBQcmVhdXRoUnNwTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZFszXSwKICAgICAgICAgICAgICAgcFByZWF1dGhSc3BOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkWzRdLAogICAgICAgICAgICAgICBwUHJlYXV0aFJzcE5vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWRbNV0sCiAgICAgICAgICAgICAgIChpbnQpcFByZWF1dGhSc3BOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmNoYW5uZWxJZCk7CgogICAgICAgIC8qIFByZWF1dGggY29tcGV0ZXIgc3VjY2Vzc2Z1bGx5LiBJbnNlcnQgdGhlIHByZWF1dGhlbnRpY2F0ZWQgbm9kZSB0byB0YWlsIG9mIHByZUF1dGhEb25lTGlzdCAqLwogICAgICAgIGNzck5laWdoYm9yUm9hbVJlbW92ZVJvYW1hYmxlQVBMaXN0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgcFByZWF1dGhSc3BOb2RlKTsKICAgICAgICBjc3JMTEluc2VydFRhaWwoJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCwgJnBQcmVhdXRoUnNwTm9kZS0+TGlzdCwgTExfQUNDRVNTX0xPQ0spOwoKICAgICAgICAvKiBQcmUtYXV0aCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LiBUcmFuc2l0aW9uIHRvIFBSRUFVVEggRG9uZSBzdGF0ZSAqLwogICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORSkKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA9IDA7CgogICAgICAgIC8qIFRoZSBjYWxsZXIgb2YgdGhpcyBmdW5jdGlvbiB3b3VsZCBzdGFydCBhIHRpbWVyIGFuZCBieSB0aGUgdGltZSBpdCBleHBpcmVzLCBzdXBwbGljYW50IHNob3VsZCAKICAgICAgICAgICBoYXZlIHByb3ZpZGVkIHRoZSB1cGRhdGVkIEZUSUVzIHRvIFNNRS4gU28sIHdoZW4gaXQgZXhwaXJlcywgaGFuZG9mZiB3aWxsIGJlIHRyaWdnZXJlZCB0aGVuICovCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvICAgIHBOZWlnaGJvckJzc05vZGUgPSBOVUxMOwogICAgICAgIHRMaXN0RWxlbSAgICAgICAgICAgICAgICAgICAqcEVudHJ5OwoKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlByZWF1dGggZmFpbGVkIHJldHJ5IG51bWJlciAlZCwgc3RhdHVzID0gMHgleCIpLAogICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcywgbGltU3RhdHVzKTsKICAgICAgICAKICAgICAgICAvKiBQcmVhdXRoIGZhaWxlZC4gQWRkIHRoZSBic3NJZCB0byB0aGUgcHJlQXV0aCBmYWlsZWQgbGlzdCBNQUMgQWRkcmVzcy4gQWxzbyByZW1vdmUgdGhlIEFQIGZyb20gcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPj0KICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX01BWF9OVU1fUFJFQVVUSF9SRVRSSUVTKSB8fAogICAgICAgICAgICAoZVNJUl9MSU1fTUFYX1NUQV9SRUFDSEVEX0VSUk9SID09IGxpbVN0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICAvKiBXZSBhcmUgZ29pbmcgdG8gcmVtb3ZlIHRoZSBub2RlIGFzIGl0IGZhaWxzIGZvciBtb3JlIHRoYW4gTUFYIHRyaWVzLiBSZXNldCB0aGlzIGNvdW50IHRvIDAgKi8KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwoKICAgICAgICAgICAgLyogVGhlIG9uZSBpbiB0aGUgaGVhZCBvZiB0aGUgbGlzdCBzaG91bGQgYmUgb25lIHdpdGggd2hpY2ggd2UgaXNzdWVkIHByZS1hdXRoIGFuZCBmYWlsZWQgKi8KICAgICAgICAgICAgcEVudHJ5ID0gY3NyTExSZW1vdmVIZWFkKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsIExMX0FDQ0VTU19MT0NLKTsKICAgICAgICAgICAgaWYocEVudHJ5KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JCc3NOb2RlID0gR0VUX0JBU0VfQUREUihwRW50cnksIHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvLCBMaXN0KTsKICAgICAgICAgICAgICAgIC8qIEFkZCB0aGUgQlNTSUQgdG8gcHJlLWF1dGggZmFpbCBsaXN0IGlmIGl0IGlzIG5vdCByZXF1ZXN0ZWQgYnkgSEREICovCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIGlmKCFwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKI2VuZGlmCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUFkZEJzc0lkVG9QcmVhdXRoRmFpbExpc3QocE1hYywgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIE5vdyB3ZSBjYW4gZnJlZSB0aGlzIG5vZGUgKi8KICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRnJlZU5laWdoYm9yUm9hbUJTU05vZGUocE1hYywgcE5laWdoYm9yQnNzTm9kZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIElzc3VlIHByZWF1dGggcmVxdWVzdCBmb3IgdGhlIHNhbWUvbmV4dCBlbnRyeSAqLwogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTID09IGNzck5laWdoYm9yUm9hbUlzc3VlUHJlYXV0aFJlcShwTWFjKSkKICAgICAgICBnb3RvIERFUV9QUkVBVVRIOyAKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZiAoY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICB7CiAgICAgICAgICBpZihwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikKICAgICAgICAgIHsKICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwgUkVBU09OX1BSRUFVVEhfRkFJTEVEX0ZPUl9BTEwpOwogICAgICAgICAgfQogICAgICAgICAgZWxzZQogICAgICAgICAgewogICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1JFU1RBUlQsIFJFQVNPTl9QUkVBVVRIX0ZBSUxFRF9GT1JfQUxMKTsKICAgICAgICAgIH0KICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICAgICAgfSBlbHNlCiAgICAgICAgewojZW5kaWYKICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOKTsKCiAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIFVQIGV2ZW50IG5vdyAqLwogICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiTm8gbW9yZSBwcmUtYXV0aCBjYW5kaWRhdGVzLSIKICAgICAgICAgICAgICAgICAgInJlZ2lzdGVyIFVQIGluZGljYXRpb24gd2l0aCBUTC4gUlNTSSA9ICVkLCIpLCBORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpKTsKCiAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgewogICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwQ2FsbGJhY2sgVVAgZXZlbnQgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgc3RhdHVzKTsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBTdGFydCB0aGUgbmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIGFuZCB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlIHRvIHBlcmZvcm0gc2NhbiBhZ2FpbiAqLwogICAgICAgICAgc3RhdHVzID0gcGFsVGltZXJTdGFydChwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCAqIFBBTF9USU1FUl9UT19NU19VTklULAogICAgICAgICAgICAgICAgICAgICAgICAgIGVBTklfQk9PTEVBTl9GQUxTRSk7CiAgICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICAgICAgICB7CiAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBzdGFydCBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgc3RhdHVzKTsKICAgICAgICAgIH0KICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIH0KI2VuZGlmCgpERVFfUFJFQVVUSDoKICAgIGNzclJvYW1EZXF1ZXVlUHJlYXV0aChwTWFjKTsKICAgIHJldHVybiBwcmVhdXRoUHJvY2Vzc2VkOwp9CiNlbmRpZiAgLyogV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcgKi8KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QcmVwYXJlU2NhblByb2ZpbGVGaWx0ZXIKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyBhIHNjYW4gZmlsdGVyIGJhc2VkIG9uIHRoZSBjdXJyZW50bHkgY29ubmVjdGVkIHByb2ZpbGUuCiAgICAgICAgICAgIEJhc2VkIG9uIHRoaXMgZmlsdGVyLCBzY2FuIHJlc3VsdHMgYXJlIG9idGFpbmVkCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwU2NhbkZpbHRlciAtIFBvcHVsYXRlZCBzY2FuIGZpbHRlciBiYXNlZCBvbiB0aGUgY29ubmVjdGVkIHByb2ZpbGUKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgZUhBTF9TVEFUVVNfRkFJTFVSRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUHJlcGFyZVNjYW5Qcm9maWxlRmlsdGVyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRDc3JTY2FuUmVzdWx0RmlsdGVyICpwU2NhbkZpbHRlcikKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0QU5JX1U4IHNlc3Npb25JZCAgID0gKHRBTklfVTgpcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZDsKICAgIHRDc3JSb2FtQ29ubmVjdGVkUHJvZmlsZSAqcEN1clByb2ZpbGUgPSAmcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGU7CiAgICB0QU5JX1U4IGkgPSAwOwogICAgCiAgICBWT1NfQVNTRVJUKHBTY2FuRmlsdGVyICE9IE5VTEwpOwogICAgaWYgKHBTY2FuRmlsdGVyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CgogICAgdm9zX21lbV96ZXJvKHBTY2FuRmlsdGVyLCBzaXplb2YodENzclNjYW5SZXN1bHRGaWx0ZXIpKTsKCiAgICAvKiBXZSBkb250IHdhbnQgdG8gc2V0IEJTU0lEIGJhc2VkIEZpbHRlciAqLwogICAgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyA9IDA7CgogICAgLy9vbmx5IGZvciBIREQgcmVxdWVzdGVkIGhhbmRvZmYgZmlsbCBpbiB0aGUgQlNTSUQgaW4gdGhlIGZpbHRlcgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpCiAgICB7CiAgICAgICAgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyA9IDE7CiAgICAgICAgcFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0U2lyTWFjQWRkcikgKiBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzKTsKICAgICAgICBpZiAoTlVMTCA9PSBwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBCU1NJRCBtZW0gYWxsb2MgZmFpbGVkIikpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTEVEX0FMTE9DOwogICAgICAgIH0KCiAgICAgICAgdm9zX21lbV96ZXJvKHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikgKiBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzKTsKCiAgICAgICAgLyogUG9wdWxhdGUgdGhlIEJTU0lEIGZyb20gaGFuZG9mZiBpbmZvIHJlY2VpdmVkIGZyb20gSEREICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHM7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fY29weSgmcFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZFtpXSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5ic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICAgICAgfQogICAgfQojZW5kaWYKICAgIC8qIFBvcHVsYXRlIGFsbCB0aGUgaW5mb3JtYXRpb24gZnJvbSB0aGUgY29ubmVjdGVkIHByb2ZpbGUgKi8KICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5udW1PZlNTSURzID0gMTsgIAogICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0ID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JTU0lESW5mbykpOwogICAgaWYgKE5VTEwgPT0gcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0KQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgU1NJRCBtZW0gYWxsb2MgZmFpbGVkIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICB9CiAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPmhhbmRvZmZQZXJtaXR0ZWQgPSAxOwogICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5zc2lkSGlkZGVuID0gMDsKICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5sZW5ndGggPSAgcEN1clByb2ZpbGUtPlNTSUQubGVuZ3RoOwogICAgdm9zX21lbV9jb3B5KCh2b2lkICopcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELnNzSWQsICh2b2lkICopcEN1clByb2ZpbGUtPlNTSUQuc3NJZCwgcEN1clByb2ZpbGUtPlNTSUQubGVuZ3RoKTsgCgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiRmlsdGVyaW5nIGZyb20gc2NhbiByZXN1bHRzIGZvciIKICAgICAgICAgICAgICAgICAgICAgICAgIlNTSUQgPSAweCUwOGx4JTA4bHglMDhseCUwOGx4JTA4bHglMDhseCUwOGx4JTA4bHhcblNTSUQgTGVuZ3RoID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELnNzSWRbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5zc0lkWzRdLAogICAgICAgICAgICAgICAgICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQuc3NJZFs4XSwKICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELnNzSWRbMTJdLAogICAgICAgICAgICAgICAgICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQuc3NJZFsxNl0sCiAgICAgICAgICAgICAgICAgICAgICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5zc0lkWzIwXSwKICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELnNzSWRbMjRdLAogICAgICAgICAgICAgICAgICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQuc3NJZFsyOF0sCiAgICAgICAgICAgICAgICAgICAgICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5sZW5ndGgpOwogICAgcFNjYW5GaWx0ZXItPmF1dGhUeXBlLm51bUVudHJpZXMgPSAxOwogICAgcFNjYW5GaWx0ZXItPmF1dGhUeXBlLmF1dGhUeXBlWzBdID0gcEN1clByb2ZpbGUtPkF1dGhUeXBlOwoKICAgIHBTY2FuRmlsdGVyLT5FbmNyeXB0aW9uVHlwZS5udW1FbnRyaWVzID0gMTsgLy9UaGlzIG11c3QgYmUgMQogICAgcFNjYW5GaWx0ZXItPkVuY3J5cHRpb25UeXBlLmVuY3J5cHRpb25UeXBlWzBdID0gcEN1clByb2ZpbGUtPkVuY3J5cHRpb25UeXBlOwoKICAgIHBTY2FuRmlsdGVyLT5tY0VuY3J5cHRpb25UeXBlLm51bUVudHJpZXMgPSAxOwogICAgcFNjYW5GaWx0ZXItPm1jRW5jcnlwdGlvblR5cGUuZW5jcnlwdGlvblR5cGVbMF0gPSBwQ3VyUHJvZmlsZS0+bWNFbmNyeXB0aW9uVHlwZTsKCiAgICBwU2NhbkZpbHRlci0+QlNTVHlwZSA9IHBDdXJQcm9maWxlLT5CU1NUeXBlOwoKICAgIC8qIFdlIGFyZSBpbnRyZXN0ZWQgb25seSBpbiB0aGUgc2NhbiByZXN1bHRzIG9uIGNoYW5uZWxzIHRoYXQgd2Ugc2Nhbm5lZCAgKi8KICAgIHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHM7CiAgICBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSB2b3NfbWVtX21hbGxvYyhwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICBpZiAoTlVMTCA9PSBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBDaGFubmVsIGxpc3QgbWVtIGFsbG9jIGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0KTsKICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QgPSBOVUxMOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgcFNjYW5GaWx0ZXItPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHM7IGkrKykKICAgIHsKICAgICAgICBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbaV0gPSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbaV07CiAgICB9CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykKICAgIHsKICAgICAgICAvKiBNRElFIHNob3VsZCBiZSBhZGRlZCBhcyBhIHBhcnQgb2YgcHJvZmlsZS4gVGhpcyBzaG91bGQgYmUgYWRkZWQgYXMgYSBwYXJ0IG9mIGZpbHRlciBhcyB3ZWxsICAqLwogICAgICAgIHBTY2FuRmlsdGVyLT5NRElELm1kaWVQcmVzZW50ID0gcEN1clByb2ZpbGUtPk1ESUQubWRpZVByZXNlbnQ7CiAgICAgICAgcFNjYW5GaWx0ZXItPk1ESUQubW9iaWxpdHlEb21haW4gPSBwQ3VyUHJvZmlsZS0+TURJRC5tb2JpbGl0eURvbWFpbjsKICAgIH0KI2VuZGlmCgogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCnRBTklfVTMyIGNzckdldEN1cnJlbnRBUFJzc2kodHBBbmlTaXJHbG9iYWwgcE1hYywgdFNjYW5SZXN1bHRIYW5kbGUgKnBTY2FuUmVzdWx0TGlzdCkKewogICAgICAgIHRDc3JTY2FuUmVzdWx0SW5mbyAqcFNjYW5SZXN1bHQ7CiAgICAgICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgdEFOSV9VMzIgQ3VyckFQUnNzaSA9IHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaTsKI2Vsc2UKICAgICAgICAvKiBXZSBhcmUgc2V0dGluZyB0aGlzIGFzIGRlZmF1bHQgdmFsdWUgdG8gbWFrZSBzdXJlIHdlIHJldHVybiB0aGlzIHZhbHVlLAogICAgICAgIHdoZW4gd2UgZG8gbm90IHNlZSB0aGlzIEFQIGluIHRoZSBzY2FuIHJlc3VsdCBmb3Igc29tZSByZWFzb24uSG93ZXZlcixpdCBpcwogICAgICAgIGxlc3MgbGlrZWx5IHRoYXQgd2UgYXJlIGFzc29jaWF0ZWQgdG8gYW4gQVAgYW5kIGRvIG5vdCBzZWUgaXQgaW4gdGhlIHNjYW4gbGlzdCAqLwogICAgICAgIHRBTklfVTMyIEN1cnJBUFJzc2kgPSAtMTI1OwojZW5kaWYKCiAgICAgICAgd2hpbGUgKE5VTEwgIT0gKHBTY2FuUmVzdWx0ID0gY3NyU2NhblJlc3VsdEdldE5leHQocE1hYywgKnBTY2FuUmVzdWx0TGlzdCkpKQogICAgICAgIHsKCiAgICAgICAgICAgICAgICBpZiAoVk9TX1RSVUUgPT0gdm9zX21lbV9jb21wYXJlKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBXZSBnb3QgYSBtYXRjaCB3aXRoIHRoZSBjdXJyZW50bHkgYXNzb2NpYXRlZCBBUC4KICAgICAgICAgICAgICAgICAgICAgICAgICogQ2FwdHVyZSB0aGUgUlNTSSB2YWx1ZSBhbmQgY29tcGxldGUgdGhlIHdoaWxlIGxvb3AuCiAgICAgICAgICAgICAgICAgICAgICAgICAqIFRoZSB3aGlsZSBsb29wIGlzIGNvbXBsZXRlZCBpbiBvcmRlciB0byBtYWtlIHRoZSBjdXJyZW50IGVudHJ5IGdvIGJhY2sgdG8gTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICogYW5kIGluIHRoZSBuZXh0IHdoaWxlIGxvb3AsIGl0IHByb3Blcmx5IHN0YXJ0cyBzZWFyY2hpbmcgZnJvbSB0aGUgaGVhZCBvZiB0aGUgbGlzdC4KICAgICAgICAgICAgICAgICAgICAgICAgICogVE9ETzogQ2FuIGFsc28gdHJ5IHNldHRpbmcgdGhlIGN1cnJlbnQgZW50cnkgZGlyZWN0bHkgdG8gTlVMTCBhcyBzb29uIGFzIHdlIGZpbmQgdGhlIG5ldyBBUCovCgogICAgICAgICAgICAgICAgICAgICAgICAgQ3VyckFQUnNzaSA9IChpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSAqICgtMSkgOwoKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIEN1cnJBUFJzc2k7Cgp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5SZXN1bHRzCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGV4dHJhY3RzIHNjYW4gcmVzdWx0cywgc29ydHMgb24gdGhlIGJhc2lzIG9mIG5laWdoYm9yIHNjb3JlKHRvZG8pLiAKICAgICAgICAgICAgQXNzdW1lZCB0aGF0IHRoZSByZXN1bHRzIGFyZSBhbHJlYWR5IHNvcnRlZCBieSBSU1NJIGJ5IGNzclNjYW5HZXRSZXN1bHQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBTY2FuUmVzdWx0TGlzdCAtIFNjYW4gcmVzdWx0IHJlc3VsdCBvYnRhaW5lZCBmcm9tIGNzclNjYW5HZXRSZXN1bHQoKQoKICAgIFxyZXR1cm4gdEFOSV9CT09MRUFOIC0gcmV0dXJuIFRSVUUgaWYgd2UgaGF2ZSBhIGNhbmRpZGF0ZSB3ZSBjYW4gaW1tZWRpYXRlbHkKICAgICAgICAgICAgcm9hbSB0by4gT3RoZXJ3aXNlLCByZXR1cm4gRkFMU0UuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKc3RhdGljIHRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhblJlc3VsdHModHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRTY2FuUmVzdWx0SGFuZGxlICpwU2NhblJlc3VsdExpc3QpCnsKICAgIHRDc3JTY2FuUmVzdWx0SW5mbyAqcFNjYW5SZXN1bHQ7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICBwQnNzSW5mbzsKICAgIHRBTklfVTMyIEN1cnJBUFJzc2k7CiAgICB0QU5JX1U4IFJvYW1Sc3NpRGlmZiA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uUm9hbVJzc2lEaWZmOwojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fQ0NYKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICB0QU5JX1U4IGltbWVkaWF0ZVJvYW1Sc3NpRGlmZiA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubkltbWVkaWF0ZVJvYW1Sc3NpRGlmZjsKI2VuZGlmCiAgICB0QU5JX0JPT0xFQU4gcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgKiBGaW5kIG91dCB0aGUgQ3VycmVudCBBUCBSU1NJIGFuZCBrZWVwIGl0IGhhbmR5IHRvIGNoZWNrIGlmCiAgICAgKiBpdCBpcyBiZXR0ZXIgdGhhbiB0aGUgUlNTSSBvZiB0aGUgQVAgd2hpY2ggd2UgYXJlCiAgICAgKiBnb2luZyB0byByb2FtLklmIHNvLCB3ZSBhcmUgZ29pbmcgdG8gY29udGludWUgd2l0aCB0aGUKICAgICAqIGN1cnJlbnQgQVAuCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgQ3VyckFQUnNzaSA9IGNzckdldEN1cnJlbnRBUFJzc2kocE1hYywgcFNjYW5SZXN1bHRMaXN0KTsKCiAgICAvKiBFeHBlY3RpbmcgdGhlIHNjYW4gcmVzdWx0IGFscmVhZHkgdG8gYmUgaW4gdGhlIHNvcnRlZCBvcmRlciBiYXNlZCBvbiB0aGUgUlNTSSAqLwogICAgLyogQmFzZWQgb24gdGhlIHByZXZpb3VzIHN0YXRlIHdlIG5lZWQgdG8gY2hlY2sgd2hldGhlciB0aGUgbGlzdCBzaG91bGQgYmUgc29ydGVkIGFnYWluIHRha2luZyBuZWlnaGJvciBzY29yZSBpbnRvIGNvbnNpZGVyYXRpb24gKi8KICAgIC8qIElmIHByZXZpb3VzIHN0YXRlIGlzIENGR19DSEFOX0xJU1RfU0NBTiwgdGhlcmUgc2hvdWxkIG5vdCBiZSBhbnkgbmVpZ2hib3Igc2NvcmUgYXNzb2NpYXRlZCB3aXRoIGFueSBvZiB0aGUgQlNTLgogICAgICAgSWYgdGhlIHByZXZpb3VzIHN0YXRlIGlzIFJFUE9SVF9RVUVSWSwgdGhlbiB0aGVyZSB3aWxsIGJlIG5laWdoYm9yIHNjb3JlIGZvciBlYWNoIG9mIHRoZSBBUHMgKi8KICAgIC8qIEZvciBub3csIGxldCB1cyB0YWtlIHRoZSB0b3Agb2YgdGhlIGxpc3QgcHJvdmlkZWQgYXMgaXQgaXMgYnkgdGhlIENTUiBTY2FuIHJlc3VsdCBBUEkuIFRoaXMgbWVhbnMgaXQgaXMgYXNzdW1lZCB0aGF0IG5laWdoYm9yIHNjb3JlIAogICAgICAgYW5kIHJzc2kgc2NvcmUgYXJlIGluIHRoZSBzYW1lIG9yZGVyLiBUaGlzIHdpbGwgYmUgdGFrZW4gY2FyZSBsYXRlciAqLwoKICAgIHdoaWxlIChOVUxMICE9IChwU2NhblJlc3VsdCA9IGNzclNjYW5SZXN1bHRHZXROZXh0KHBNYWMsICpwU2NhblJlc3VsdExpc3QpKSkKICAgIHsKICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLAogICAgICAgICAgICBGTCgiU2NhbiByZXN1bHQ6IEJTU0lEICUwMng6JTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4IChSc3NpICVkLCBDaDolZCkiKSwKICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWRbMF0sCiAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkWzFdLAogICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZFsyXSwKICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWRbM10sCiAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkWzRdLAogICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZFs1XSwKICAgICAgICAgICAgYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpLAogICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5jaGFubmVsSWQpOwoKICAgICAgIGlmIChWT1NfVFJVRSA9PSB2b3NfbWVtX2NvbXBhcmUocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQsIAogICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpCiAgICAgICAgewogICAgICAgICAgICAvKiBjdXJyZW50bHkgYXNzb2NpYXRlZCBBUC4gRG8gbm90IGhhdmUgdGhpcyBpbiB0aGUgcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAiU0tJUC1jdXJyZW50bHkgYXNzb2NpYXRlZCBBUCIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgLyogVGhpcyBjb25kaXRpb24gaXMgdG8gZW5zdXJlIHRvIHJvYW0gdG8gYW4gQVAgd2l0aCBiZXR0ZXIgUlNTSS4gaWYgdGhlIHZhbHVlIG9mIFJvYW1Sc3NpRGlmZiBpcyBaZXJvLCB0aGlzIGZlYXR1cmUKICAgICAgICAqIGlzIGRpc2FibGVkIGFuZCB3ZSBjb250aW51ZSB0byByb2FtIHdpdGhvdXQgYW55IGNoZWNrKi8KICAgICAgIGlmICgoUm9hbVJzc2lEaWZmID4gMCkKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICAgICApCiAgICAgICB7CiAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICogSWYgUlNTSSBpcyBsb3dlciB0aGFuIHRoZSBsb29rdXAgdGhyZXNob2xkLCB0aGVuIGNvbnRpbnVlLgogICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICBpZiAoYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpID4KICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQpCiAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXSBuZXcgYXAgcnNzaSAoJWQpIGxvd2VyIHRoYW4gbG9va3VwIHRocmVzaG9sZCAoJWQpIiwKICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAoaW50KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpKTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgaWYgKGFicyhDdXJyQVBSc3NpKSA8IGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSkKICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgIC8qRG8gbm90IHJvYW0gdG8gYW4gQVAgd2l0aCB3b3JzZSBSU1NJIHRoYW4gdGhlIGN1cnJlbnQqLwogICAgICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXUN1cnJlbnQgQVAgcnNzaT0lZCBuZXcgYXAgcnNzaSB3b3JzZT0lZCIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDdXJyQVBSc3NpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpICk7CiAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgLypEbyBub3Qgcm9hbSB0byBhbiBBUCB3aGljaCBpcyBoYXZpbmcgYmV0dGVyIFJTU0kgdGhhbiB0aGUgY3VycmVudCBBUCwgYnV0IHN0aWxsIGxlc3MgdGhhbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgKiBtYXJnaW4gdGhhdCBpcyBwcm92aWRlZCBieSB1c2VyIGZyb20gdGhlIGluaSBmaWxlIChSb2FtUnNzaURpZmYpKi8KICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWJzKGFicyhDdXJyQVBSc3NpKSAtIGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSkgPCBSb2FtUnNzaURpZmYpCiAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR11DdXJyZW50IEFQIHJzc2k9JWQgbmV3IGFwIHJzc2k9JWQgbm90IGdvb2QgZW5vdWdoLCByb2FtUnNzaURpZmY9JWQiLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3VyckFQUnNzaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUm9hbVJzc2lEaWZmKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddQ3VycmVudCBBUCByc3NpPSVkIG5ldyBhcCByc3NpIGJldHRlcj0lZCIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1cnJBUFJzc2ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSApOwogICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgfQogICAgICAgfQoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUocE1hYywgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkJTU0lEIHByZXNlbnQgaW4gcHJlLWF1dGggZmFpbCBsaXN0Li4gSWdub3JpbmciKSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgojaWZkZWYgRkVBVFVSRV9XTEFOX0NDWAojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzQ0NYQXNzb2MpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgaWYgKCFjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUocE1hYywgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJCU1NJRCBwcmVzZW50IGluIHByZS1hdXRoIGZhaWwgbGlzdC4uIElnbm9yaW5nIikpOwogICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX3ByZXNlbnQpICYmCiAgICAgICAgICAgICAgIChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9hdmFpbCkpCiAgICAgICAgICB7CiAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc1ZPQWRtaXR0ZWQpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk5ldyBBUCBoYXMgJXggQlcgYXZhaWxhYmxlIiksICh1bnNpZ25lZCBpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfYXZhaWwpOwogICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIldlIG5lZWQgJXggQlcgYXZhaWxhYmxlIiksKHVuc2lnbmVkIGludClwTmVpZ2hib3JSb2FtSW5mby0+TWluUUJzc0xvYWRSZXF1aXJlZCk7CiAgICAgICAgICAgICAgICAgIGlmIChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9hdmFpbCA8IHBOZWlnaGJvclJvYW1JbmZvLT5NaW5RQnNzTG9hZFJlcXVpcmVkKQogICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAiW0lORk9MT0ddQlNTSUQgOiAlMDJ4OiUwMng6JTAyeDolMDJ4OiUwMng6JTAyeCBoYXMgbm8gYmFuZHdpZHRoIGlnbm9yaW5nLi5ub3QgYWRkaW5nIHRvIHJvYW0gbGlzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWRbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWRbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWRbMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWRbM10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWRbNF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWRbNV0pOwogICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlCiAgICAgICAgICB7CiAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJObyBRQnNzICV4ICV4IiksICh1bnNpZ25lZCBpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfYXZhaWwsICh1bnNpZ25lZCBpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfcHJlc2VudCk7CiAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc1ZPQWRtaXR0ZWQpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICJbSU5GT0xPR11CU1NJRCA6ICUwMng6JTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4IGhhcyBubyBRQlNTTG9hZCBJRSwgaWdub3JpbmcuLm5vdCBhZGRpbmcgdG8gcm9hbSBsaXN0IiwKICAgICAgICAgICAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkWzBdLAogICAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWRbMV0sCiAgICAgICAgICAgICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZFsyXSwKICAgICAgICAgICAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkWzNdLAogICAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWRbNF0sCiAgICAgICAgICAgICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZFs1XSk7CiAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIH0KI2VuZGlmCiNlbmRpZiAvKiBGRUFUVVJFX1dMQU5fQ0NYICovCgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIC8vIElmIHdlIGFyZSBzdXBwb3J0aW5nIGxlZ2FjeSByb2FtaW5nLCBhbmQgCiAgICAgICAgLy8gaWYgdGhlIGNhbmRpZGF0ZSBpcyBvbiB0aGUgInByZS1hdXRoIGZhaWxlZCIgbGlzdCwgaWdub3JlIGl0LiAKICAgICAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFjc3JOZWlnaGJvclJvYW1Jc1ByZWF1dGhDYW5kaWRhdGUocE1hYywgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkJTU0lEIHByZXNlbnQgaW4gcHJlLWF1dGggZmFpbCBsaXN0Li4gSWdub3JpbmciKSk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KI2VuZGlmIC8qIEZFQVRVUkVfV0xBTl9MRlIgKi8KCiAgICAgICAgLyogSWYgdGhlIHJlY2VpdmVkIHRpbWVzdGFtcCBpbiBCU1MgZGVzY3JpcHRpb24gaXMgZWFybGllciB0aGFuIHRoZSBzY2FuIHJlcXVlc3QgdGltZXN0YW1wLCBza2lwIAogICAgICAgICAqIHRoaXMgcmVzdWx0ICovCiAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJlcXVlc3RUaW1lU3RhbXAgPj0gcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IublJlY2VpdmVkVGltZSkKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAmJiAhY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKQojZW5kaWYKICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIklnbm9yaW5nIEJTUyBhcyBpdCBpcyBvbGRlciB0aGFuIHRoZSBzY2FuIHJlcXVlc3QgdGltZXN0YW1wIikpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHBCc3NJbmZvID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvKSk7CiAgICAgICAgaWYgKE5VTEwgPT0gcEJzc0luZm8pCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZvciBOZWlnaGJvciBSb2FtIEJTUyBJbmZvIGZhaWxlZC4uIEp1c3QgaWdub3JpbmciKSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgcEJzc0luZm8tPnBCc3NEZXNjcmlwdGlvbiA9IHZvc19tZW1fbWFsbG9jKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmxlbmd0aCArIHNpemVvZihwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5sZW5ndGgpKTsKICAgICAgICBpZiAocEJzc0luZm8tPnBCc3NEZXNjcmlwdGlvbiAhPSBOVUxMKQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KHBCc3NJbmZvLT5wQnNzRGVzY3JpcHRpb24sICZwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvciwgCiAgICAgICAgICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IubGVuZ3RoICsgc2l6ZW9mKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmxlbmd0aCkpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZvciBOZWlnaGJvciBSb2FtIEJTUyBEZXNjcmlwdG9yIGZhaWxlZC4uIEp1c3QgaWdub3JpbmciKSk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQnNzSW5mbyk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgcEJzc0luZm8tPmFwUHJlZmVyZW5jZVZhbCA9IDEwOyAvL3NvbWUgdmFsdWUgZm9yIG5vdy4gTmVlZCB0byBjYWxjdWxhdGUgdGhlIGFjdHVhbCBzY29yZSBiYXNlZCBvbiBSU1NJIGFuZCBuZWlnaGJvciBBUCBzY29yZQoKICAgICAgICAvKiBKdXN0IGFkZCB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IGFzIGl0IGlzIGFscmVhZHkgc29ydGVkIGJ5IFJTU0kgKi8KICAgICAgICBjc3JMTEluc2VydFRhaWwoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgJnBCc3NJbmZvLT5MaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fQ0NYKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICAgICAgaWYgKChhYnMoYWJzKEN1cnJBUFJzc2kpIC0gYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpKSA+PSBpbW1lZGlhdGVSb2FtUnNzaURpZmYpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gcG90ZW50aWFsIGNhbmRpZGF0ZSB0byByb2FtIGltbWVkaWF0ZWx5IChkaWZmPSVkLCBleHBlY3RlZD0lZCkiLCAKICAgICAgICAgICAgICAgICAgICAgICBfX2Z1bmNfXywgYWJzKGFicyhDdXJyQVBSc3NpKSAtIGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSksCiAgICAgICAgICAgICAgICAgICAgICAgaW1tZWRpYXRlUm9hbVJzc2lEaWZmKTsKICAgICAgICAgICAgcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIC8qIElmIHdlIGFyZSBoZXJlIG1lYW5zLCBGVyBhbHJlYWR5IGZvdW5kIGNhbmRpZGF0ZXMgdG8gcm9hbSwgc28gd2UgYXJlCiAgICAgICAgICAgZ29vZCB0byBnbyB3aXRoIHByZS1hdXRoICovCiAgICAgICAgaWYoY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICB7CiAgICAgICAgICAgIHJvYW1Ob3cgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICB9CiNlbmRpZgojZW5kaWYKICAgIH0KCiAgICAvKiBOb3cgd2UgaGF2ZSBhbGwgdGhlIHNjYW4gcmVzdWx0cyBpbiBvdXIgbG9jYWwgbGlzdC4gR29vZCB0aW1lIHRvIGZyZWUgdXAgdGhlIHRoZSBsaXN0IHdlIGdvdCBhcyBhIHBhcnQgb2YgY3NyR2V0U2NhblJlc3VsdCAqLwogICAgY3NyU2NhblJlc3VsdFB1cmdlKHBNYWMsICpwU2NhblJlc3VsdExpc3QpOwoKICAgIHJldHVybiByb2FtTm93Owp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSGFuZGxlRW1wdHlTY2FuUmVzdWx0CgogICAgXGJyaWVmICAgICAgVGhpcyBmdW5jdGlvbiB3aWxsIGJlIGludm9rZWQgaW4gQ0ZHX0NIQU5fTElTVF9TQ0FOIHN0YXRlIHdoZW4gCiAgICAgICAgICAgICAgICB0aGVyZSBhcmUgbm8gdmFsaWQgQVBzIGluIHRoZSBzY2FuIHJlc3VsdCBmb3Igcm9hbWluZy4gVGhpcyBtZWFucyAKICAgICAgICAgICAgICAgIG91ciBBUCBpcyB0aGUgYmVzdCBhbmQgbm8gb3RoZXIgQVAgaXMgYXJvdW5kLiBObyBwb2ludCBpbiBzY2FubmluZwogICAgICAgICAgICAgICAgYWdhaW4gYW5kIGFnYWluLiBQZXJmb3JtaW5nIHRoZSBmb2xsb3dpbmcgaGVyZS4KICAgICAgICAgICAgICAgIDEuIFN0b3AgdGhlIG5laWdoYm9yIHNjYW4gdGltZXIuCiAgICAgICAgICAgICAgICAyYS4gSWYgdGhpcyBpcyB0aGUgZmlyc3QgdGltZSB3ZSBlbmNvdW50ZXJlZCBlbXB0eSBzY2FuLCB0aGVuCiAgICAgICAgICAgICAgICByZS1yZWdpc3RlciB3aXRoIFRMIHdpdGggbW9kaWZpZWQgbG9va3VwIHRocmVzaG9sZC4KICAgICAgICAgICAgICAgIDJiLiBFbHNlIGlmIHRoaXMgaXMgdGhlIHNlY29uZCB0aW1lIHdlIGVuY291bnRlcmVkIGVtcHR5IHNjYW4sCiAgICAgICAgICAgICAgICB0aGVuIHN0YXJ0IG5laWdoYm9yIHNjYW4gcmVzdWx0cyByZWZyZXNoIHRpbWVyICgyMHMpLgogICAgICAgICAgICAgICAgMmMuIEVsc2UsIG5vdGhpbmcgbW9yZSB0byBkby4KICAgICAgICAgICAgICAgIE5PVEU6IEluIExGUiwgY2hhbm5lbHMgc2VsZWN0ZWQgZm9yIHNjYW5uaW5nIGlzIGRlcnZpZWQgZnJvbQogICAgICAgICAgICAgICAgdGhlIG9jY3VwZWQgY2hhbm5lbCBsaXN0LiBTY2FuIGN5Y2xlIGZvbGxvd2luZyBvbmUgd2hpY2gKICAgICAgICAgICAgICAgIHlpZWxkZWQgZW1wdHkgcmVzdWx0cyBpcyBzcGxpdCBpbnRvIHR3byBoYWx2ZXM6IChpKSBzY2FuIG9uCiAgICAgICAgICAgICAgICBjaGFubmVscyBpbiB0aGUgb2NjdXBpZWQgbGlzdCwgYW5kIChpaSkgc2NhbiBvbiBjaGFubmVscyBub3QKICAgICAgICAgICAgICAgIGluIHRoZSBvY2N1cGllZCBsaXN0LiBUaGlzIGhlbHBzIGNvbnZlcmdpbmcgZmFzdGVyICh3aGlsZQogICAgICAgICAgICAgICAgbG9va2luZyBmb3IgY2FuZGlkYXRlcyBpbiB0aGUgb2NjdXBpZWQgbGlzdCBmaXJzdCksIGFuZCBhbHNvLAogICAgICAgICAgICAgICAgYWRkcyBjaGFubmVscyB0byB0aGUgb2NjdXBpZWQgY2hhbm5lbCBsaXN0IHVwb24gZmluZGluZyBjYW5kaWRhdGVzCiAgICAgICAgICAgICAgICBtYXRjaGluZyBTU0lEIHByb2ZpbGUgb2YgaW50ZXJlc3QuCgogICAgICAgICAgICAgICAgdUVtcHR5U2NhbkNvdW50ICAgICAgICAgICAgICAgICAgICAgICAgIENvbW1lbnRzCiAgICAgICAgICAgICAgICBlRmlyc3RFbXB0eVNjYW4gICAgIFByZXZpb3VzIHNjYW4gd2FzIGRvbmUgb24gY2hhbm5lbHMgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jY3VwaWVkIGxpc3QgYW5kIHlpZWxkZWQgcG90ZW50aWFsIGNhbmRpZGF0ZXMuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMgc2NhbiBjeWNsZSB3YXMgbGlrZWx5IHRyaWdnZXJlZCB0aHJvdWdoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpcHQgb2YgbG9va3VwIERPV04gbm90aWZpY2F0aW9uIGV2ZW50LgogICAgICAgICAgICAgICAgZVNlY29uZEVtcHR5U2NhbiAgICBQcmV2aW91cyBzY2FuIHdhcyBkb25lIG9uIGNoYW5uZWxzIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY2N1cGllZCBsaXN0IGFuZCB5aWVsZGVkIG5vIGNhbmRpZGF0ZXMuIFRoaXMgc2NhbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjeWNsZSB3YXMgdHJpZ2dlcmVkIHRocm91Z2ggUlNTSSBub3RpZmljYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aCBtb2RpZmllZCBsb29rdXAgdGhyZXNob2xkLgogICAgICAgICAgICAgICAgZVRoaXJkRW1wdHlTY2FuICAgICBQcmV2aW91cyBzY2FuIHdhcyBkb25lIG9uIGNoYW5uZWxzIE5PVCBpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgb2NjdXBpZWQgbGlzdCBhbmQgeWllbGRlZCBubyBjYW5kaWRhdGVzLiBUaGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4gY3ljbGUgd2FzIHRyaWdnZXJlZCBpbW1lZGlhdGVseSBhZnRlciBzY2FubmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVscyBpbiB0aGUgb2NjdXBpZWQgbGlzdCBhbmQgbm8gY2FuZGlkYXRlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZXJlIGZvdW5kLgogICAgICAgICAgICAgICAgZUZvdXJ0aEVtcHR5U2NhbiAgICBQcmV2aW91cyBzY2FuIHdhcyBkb25lIG9uIGNoYW5uZWxzIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvY2N1cGllZCBsaXN0IGFuZCB5aWVsZGVkIG5vIGNhbmRpZGF0ZXMuIFRoaXMgc2NhbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjeWNsZSB3YXMgdHJpZ2dlcmVkIHVwb24gZXhwaXJ5IG9mCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5laWdoYm9yU2NhblJlc3VsdHNSZWZyZXNoUGVyaW9kICg9MjBzKS4KICAgICAgICAgICAgICAgIGVGaWZ0aEVtcHR5U2NhbiAgICAgUHJldmlvdXMgc2NhbiB3YXMgZG9uZSBvbiBjaGFubmVscyBOT1QgaW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIG9jY3VwaWVkIGxpc3QgYW5kIHlpZWxkZWQgbm8gY2FuZGlkYXRlcy4gVGhpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuIGN5Y2xlIHdhcyB0cmlnZ2VyZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgc2Nhbm5pbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbHMgaW4gdGhlIG9jY3VwaWVkIGxpc3QgYW5kIG5vIGNhbmRpZGF0ZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2VyZSBmb3VuZC4KCiAgICAgICAgICAgICAgICBbMV0sIFsyLDNdIGFuZCBbNCw1XSB0b2dldGhlciBmb3JtIG9uZSBkaXNjcmV0ZSBzZXQgb2Ygc2NhbiBjeWNsZS4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kc3RhdGljIFZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtSGFuZGxlRW1wdHlTY2FuUmVzdWx0KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHRBTklfQk9PTEVBTiBwZXJmb3JtUGVyaW9kaWNTY2FuID0KICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5lbXB0eVNjYW5SZWZyZXNoUGVyaW9kKSA/IFRSVUUgOiBGQUxTRTsKI2VuZGlmCgogICAgLyogU3RvcCBuZWlnaGJvciBzY2FuIHRpbWVyICovCiAgICBzdGF0dXMgPSBwYWxUaW1lclN0b3AocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykgCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJzdG9wcGluZyBuZWlnaGJvclNjYW5UaW1lciBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgc3RhdHVzKTsKICAgIH0KCiAgICAvKgogICAgICogSW5jcmVhc2UgdGhlIG5laWdoYm9yIGxvb2t1cCB0aHJlc2hvbGQgYnkgMyBkQgogICAgICogYWZ0ZXIgZXZlcnkgc2NhbiBjeWNsZS4gTk9URTogdUVtcHR5U2NhbkNvdW50CiAgICAgKiB3b3VsZCBiZSBlaXRoZXIgMSwgMyBvciA1IGF0IHRoZSBlbmQgb2YgZXZlcnkKICAgICAqIHNjYW4gY3ljbGUuCiAgICAgKi8KI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIGlmICgoKytwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50KSA+IGVGaWZ0aEVtcHR5U2NhbikKICAgIHsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gZUZpZnRoRW1wdHlTY2FuOwogICAgfQogICAgaWYgKCgoMCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpIHx8CiAgICAgICAgIChhYnMocE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpKSA+CiAgICAgICAgIGFicyhwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCkpKSAmJgogICAgICAgICgocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlU2Vjb25kRW1wdHlTY2FuKSB8fAogICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlRm91cnRoRW1wdHlTY2FuKSkpCiAgICB7CiAgICAgICAgLyoKICAgICAgICAgKiBJZiB0aGUgc2NhbiB3YXMgdHJpZ2dlcmVkIGR1ZSB0byBsb29rdXBET1dOUnNzaSA+IHJlYXNzb2MgdGhyZXNob2xkLAogICAgICAgICAqIHRoZW4gaXQgd291bGQgYmUgYSBjb250aWd1b3VzIHNjYW4gb24gYWxsIHZhbGlkIG5vbi1ERlMgY2hhbm5lbHMuCiAgICAgICAgICogSWYgY2hhbm5lbHMgYXJlIGNvbmZpZ3VyZWQgaW4gSU5JLCB0aGVuIG9ubHkgdGhvc2UgY2hhbm5lbHMgbmVlZAogICAgICAgICAqIHRvIGJlIHNjYW5uZWQuCiAgICAgICAgICogSW4gZWl0aGVyIG9mIHRoZXNlIG1vZGVzLCB0aGVyZSBpcyBubyBuZWVkIHRvIHRyaWdnZXIgYW4gaW1tZWRpYXRlCiAgICAgICAgICogc2NhbiB1cG9uIGVtcHR5IHNjYW4gcmVzdWx0cyBmb3IgdGhlIHNlY29uZCBhbmQgZm91cnRoIHRpbWUgKHdoaWNoCiAgICAgICAgICogd291bGQgYmUgZXF1aXZhbGVudCB0byBzY2FubmluZyBvbiBjaGFubmVscyBpbiBub24tb2NjdXBpZWQgbGlzdCkuCiAgICAgICAgICogSW5jcmVtZW50aW5nIHVFbXB0eVNjYW5Db3VudCB3aWxsIGNvcnJlc3BvbmQgdG8gc2tpcHBpbmcgdGhpcyBzdGVwLgogICAgICAgICAqIE5PVEU6IGRvdWJsZSBpbmNyZW1lbnQgb2YgdUVtcHR5U2NhbkNvdW50IGNvcnJlc3BvbmRzIHRvIGNvbXBsZXRpb24KICAgICAgICAgKiBvZiBzY2FucyBvbiBhbGwgdmFsaWQgY2hhbm5lbHMuCiAgICAgICAgICovCiAgICAgICAgKytwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50OwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIkV4dHJhIGluY3JlbWVudCBvZiBlbXB0eSBzY2FuIGNvdW50ICg9JWQpIgogICAgICAgICAgICAiIGluIGNvbnRpZ3VvdXMgc2NhbiBtb2RlIiwgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCk7CiAgICB9CiNlbmRpZgogICAgaWYgKCgocE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCszKSA8CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQpCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgJiYgKChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ICUgMikgPT0gMSkKI2VuZGlmCiAgICAgICAgKQogICAgewogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKz0gMzsKICAgIH0KCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgLyogQ2xlYXIgb2ZmIHRoZSBvbGQgbmVpZ2hib3IgcmVwb3J0IGRldGFpbHMgKi8KICAgIHZvc19tZW1femVybygmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm8sIHNpemVvZih0Q3NyTmVpZ2hib3JSZXBvcnRCc3NJbmZvKSAqIE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKTsKI2VuZGlmCgogICAgLyogVHJhbnNpdGlvbiB0byBDT05ORUNURUQgc3RhdGUgKi8KICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICAgICAgCiAgICAvKiBSZXNldCBhbGwgdGhlIG5lY2Vzc2FyeSB2YXJpYWJsZXMgYmVmb3JlIHRyYW5zaXRpb25pbmcgdG8gdGhlIENPTk5FQ1RFRCBzdGF0ZSAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwogICAgICAgIAojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPT0gZUZpcnN0RW1wdHlTY2FuKQogICAgewojZW5kaWYKICAgICAgICAvKiBFbXB0eSBzY2FuIHJlc3VsdHMgZm9yIHRoZSBmaXJzdCB0aW1lICovCiAgICAgICAgLyogUmUtcmVnaXN0ZXIgbmVpZ2hib3IgbG9va3VwIERPV04gdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgKi8KICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsCiAgICAgICAgICAgIEZMKCJSZWdpc3RlcmluZyBET1dOIGV2ZW50IG5laWdoYm9yIGxvb2t1cCBjYWxsYmFjayB3aXRoIFRMIGZvciBSU1NJID0gJWQiKSwKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSkpOwoKICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgRkwoIkNvdWxkbid0IHJlLXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIgogICAgICAgICAgICAgICAgICAgICAgIiB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgICAgIH0KI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgfQogICAgZWxzZSBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPT0gZVNlY29uZEVtcHR5U2NhbikgfHwKICAgICAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IGVGb3VydGhFbXB0eVNjYW4pKQogICAgewogICAgICAgIC8qIEVtcHR5IHNjYW4gcmVzdWx0cyBmb3IgdGhlIHNlY29uZCBvciBmb3VydGggdGltZSAqLwoKICAgICAgICAvKiBJbW1lZGlhdGVseSBzY2FuIG9uIGNoYW5uZWxzIGluIG5vbi1vY2N1cGllZCBsaXN0ICovCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4ocE1hYyk7CiAgICB9CiAgICBlbHNlIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID49IGVUaGlyZEVtcHR5U2NhbikKICAgIHsKICAgICAgICAvKiBFbXB0eSBzY2FuIHJlc3VsdHMgZm9yIHRoZSB0aGlyZCB0aW1lICovCiAgICAgICAgaWYgKHBlcmZvcm1QZXJpb2RpY1NjYW4pCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlBlcmZvcm1pbmcgcGVyaW9kaWMgc2NhbiwgdUVtcHR5U2NhbkNvdW50PSVkIiksCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50KTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNldCB1RW1wdHlTY2FuQ291bnQgdG8gTUFYIHNvIHRoYXQgd2UgYWx3YXlzIGVudGVyIHRoaXMKICAgICAgICAgICAgICogY29uZGl0aW9uIG9uIHN1YnNlcXVlbnQgZW1wdHkgc2NhbiByZXN1bHRzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gZU1heEVtcHR5U2NhbjsKCiAgICAgICAgICAgIC8qIEZyb20gaGVyZSBvbiwgT05MWSBzY2FuIG9uIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBsaXN0ICovCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPSBTUExJVF9TQ0FOX09DQ1VQSUVEX0xJU1Q7CgogICAgICAgICAgICAvKiBTdGFydCBlbXB0eSBzY2FuIHJlZnJlc2ggdGltZXIgKi8KICAgICAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0KICAgICAgICAgICAgICAgIHBhbFRpbWVyU3RhcnQocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lciwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmVtcHR5U2NhblJlZnJlc2hQZXJpb2QgKiBQQUxfVElNRVJfVE9fTVNfVU5JVCwKICAgICAgICAgICAgICAgICAgICBlQU5JX0JPT0xFQU5fRkFMU0UpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBmYWlsZWQgdG8gc3RhcnQgKCVkKSIpLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBzdGFydGVkICglbGQgbXMpIiksCiAgICAgICAgICAgICAgICAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmVtcHR5U2NhblJlZnJlc2hQZXJpb2QpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChlVGhpcmRFbXB0eVNjYW4gPT0gcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCkKICAgICAgICB7CiAgICAgICAgICAgIC8qIFN0YXJ0IG5laWdoYm9yIHNjYW4gcmVzdWx0cyByZWZyZXNoIHRpbWVyICovCiAgICAgICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9CiAgICAgICAgICAgICAgICAgICAgcGFsVGltZXJTdGFydChwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyLAogICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2QgKiBQQUxfVElNRVJfVE9fTVNfVU5JVCwKICAgICAgICAgICAgICAgICAgICAgICAgZUFOSV9CT09MRUFOX0ZBTFNFKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXN1bHRzIHJlZnJlc2ggdGltZXIgZmFpbGVkIHRvIHN0YXJ0ICglZCkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzIsIEZMKCJOZWlnaGJvciByZXN1bHRzIHJlZnJlc2ggdGltZXIgc3RhcnRlZCAoJWxkIG1zKSIpLAogICAgICAgICAgICAgICAgICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlc3VsdHNSZWZyZXNoUGVyaW9kICogUEFMX1RJTUVSX1RPX01TX1VOSVQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsICJOZWlnaGJvciByb2FtIGVtcHR5IHNjYW4gY291bnQ9JWQgc2NhbiBtb2RlPSVkIiwKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50LCBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlKTsKI2VuZGlmCiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgoKc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZSAodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0Q3NyU2NhblJlc3VsdEZpbHRlciAgICBzY2FuRmlsdGVyOwogICAgdFNjYW5SZXN1bHRIYW5kbGUgICAgICAgc2NhblJlc3VsdDsKICAgIHRBTklfVTMyICAgICAgICAgICAgICAgIHRlbXBWYWwgPSAwOwogICAgdEFOSV9CT09MRUFOICAgICAgICAgICAgcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIGVIYWxTdGF0dXMgICAgICAgICAgICAgIGhzdGF0dXM7CgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fQ0NYKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICAgICAgLyogSWYgdGhlIHN0YXRlIGlzIFJFUE9SVF9TQ0FOLCB0aGVuIHRoaXMgbXVzdCBiZSB0aGUgc2NhbiBhZnRlciB0aGUgUkVQT1JUX1FVRVJZIHN0YXRlLiBTbywgd2UgCiAgICAgICAgICAgc2hvdWxkIHVzZSB0aGUgQlNTSUQgZmlsdGVyIG1hZGUgb3V0IG9mIG5laWdoYm9yIHJlcG9ydHMgKi8KICAgICAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAmJiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiNlbmRpZgogICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Cc3NJZFNjYW5GaWx0ZXIocE1hYywgJnNjYW5GaWx0ZXIpOwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCIxMVIgb3IgQ0NYIEFzc29jaWF0aW9uOiBQcmVwYXJlIHNjYW4gZmlsdGVyIHN0YXR1cyAgd2l0aCBuZWlnaGJvciBBUCA9ICVkIiksIGhzdGF0dXMpOwogICAgICAgICAgICB0ZW1wVmFsID0gMTsKICAgICAgICB9CiAgICAgICAgZWxzZQojZW5kaWYKICAgICAgICB7CiAgICAgICAgICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1QcmVwYXJlU2NhblByb2ZpbGVGaWx0ZXIocE1hYywgJnNjYW5GaWx0ZXIpOwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCIxMVIvQ0NYL090aGVyIEFzc29jaWF0aW9uOiBQcmVwYXJlIHNjYW4gdG8gZmluZCBuZWlnaGJvciBBUCBmaWx0ZXIgc3RhdHVzICA9ICVkIiksIGhzdGF0dXMpOwogICAgICAgIH0KICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBwcmVwYXJhdGlvbiBmYWlsZWQgZm9yIEFzc29jIHR5cGUgJWQuLiBCYWlsaW5nIG91dC4uIiksIHRlbXBWYWwpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICAgICAgaHN0YXR1cyA9IGNzclNjYW5HZXRSZXN1bHQocE1hYywgJnNjYW5GaWx0ZXIsICZzY2FuUmVzdWx0KTsKICAgICAgICBpZiAoaHN0YXR1cyAhPSBlSEFMX1NUQVRVU19TVUNDRVNTKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiR2V0IFNjYW4gUmVzdWx0IHN0YXR1cyBjb2RlICVkIiksIGhzdGF0dXMpOwogICAgICAgIH0KICAgICAgICAvKiBQcm9jZXNzIHRoZSBzY2FuIHJlc3VsdHMgYW5kIHVwZGF0ZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgcm9hbU5vdyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuUmVzdWx0cyhwTWFjLCAmc2NhblJlc3VsdCk7CgogICAgICAgIC8qIEZyZWUgdGhlIHNjYW4gZmlsdGVyICovCiAgICAgICAgY3NyRnJlZVNjYW5GaWx0ZXIocE1hYywgJnNjYW5GaWx0ZXIpOwoKICAgICAgICB0ZW1wVmFsID0gY3NyTExDb3VudCgmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICBpZighY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICB7CiNlbmRpZgogICAgICAgICBzd2l0Y2gocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTjoKICAgICAgICAgICAgICAgIGlmICh0ZW1wVmFsKQogICAgICAgICAgICAgICAgewojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogU2luY2UgdGhlcmUgYXJlIG5vbi16ZXJvIGNhbmRpZGF0ZXMgZm91bmQKICAgICAgICAgICAgICAgICAgICAgKiBhZnRlciB0aGUgc2NhbiwgcmVzZXQgZW1wdHkgc2NhbiBjb3VudC4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gMDsKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gREVGQVVMVF9TQ0FOOwojZW5kaWYKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgICAgICAgICAgICAgLyogSWYgdGhpcyBpcyBhIG5vbi0xMXIgYXNzb2NpYXRpb24sIHRoZW4gd2UgY2FuIHJlZ2lzdGVyIHRoZSByZWFzc29jIGNhbGxiYWNrIGhlcmUgYXMgd2UgaGF2ZSBzb21lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVBzIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVmFsaWQgQVBzIGFyZSBmb3VuZCBhZnRlciBzY2FuLiBOb3cgd2UgY2FuIGluaXRpYXRlIHByZS1hdXRoZW50aWNhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9DQ1gKICAgICAgICAgICAgICAgICAgICAvKiBJZiB0aGlzIGlzIGEgbm9uLTExciBhc3NvY2lhdGlvbiwgdGhlbiB3ZSBjYW4gcmVnaXN0ZXIgdGhlIHJlYXNzb2MgY2FsbGJhY2sgaGVyZSBhcyB3ZSBoYXZlIHNvbWUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBUHMgaW4gdGhlIHJvYW1hYmxlIEFQIGxpc3QgKi8KICAgICAgICAgICAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzQ0NYQXNzb2MpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBWYWxpZCBBUHMgYXJlIGZvdW5kIGFmdGVyIHNjYW4uIE5vdyB3ZSBjYW4gaW5pdGlhdGUgcHJlLWF1dGhlbnRpY2F0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiNlbmRpZgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAgICAgICAgIC8qIElmIExGUiBpcyBlbmFibGVkLCB0aGVuIHdlIGNhbiByZWdpc3RlciB0aGUgcmVhc3NvYyBjYWxsYmFjayBoZXJlIGFzIHdlIGhhdmUgc29tZSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFQcyBpbiB0aGUgcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgQ1NSX1NFU1NJT05fSURfSU5WQUxJRCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBWYWxpZCBBUHMgYXJlIGZvdW5kIGFmdGVyIHNjYW4uIE5vdyB3ZSBjYW4gaW5pdGlhdGUgcHJlLWF1dGhlbnRpY2F0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiNlbmRpZgogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiQ29tcGxldGVkIHNjYW5uaW5nIG9mIENGRyBDSEFOIExJU1QgaW4gbm9uLTExciBhc3NvY2lhdGlvbi4gUmVnaXN0ZXJpbmcgcmVhc3NvYyBjYWxsYmFjayIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgLyogTm90aGluZyBtdWNoIHRvIGRvIG5vdy4gV2lsbCBjb250aW51ZSB0byByZW1haW4gaW4gdGhpcyBzdGF0ZSBpbiBjYXNlIG9mIG5vbi0xMXIgYXNzb2NpYXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgLyogU3RvcCB0aGUgdGltZXIuIEJ1dCBob3cgbG9uZyB0aGUgcm9hbWFibGUgQVAgbGlzdCB3aWxsIGJlIHZhbGlkIGluIGhlcmUuIEF0IHNvbWUgcG9pbnQgb2YgdGltZSwgd2UgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lZWQgdG8gcmVzdGFydCB0aGUgQ0ZHIENIQU4gbGlzdCBzY2FuIHByb2NlZHVyZSBpZiByZWFzc29jIGNhbGxiYWNrIGlzIG5vdCBpbnZva2VkIGZyb20gVEwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpdGhpbiBjZXJ0YWluIGR1cmF0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIAovLyAgICAgICAgICAgICAgICAgICAgICAgIHBhbFRpbWVyU3RvcChwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJObyBjYW5kaWRhdGUgZm91bmQgYWZ0ZXIgc2Nhbm5pbmcgaW4gc3RhdGUgJWQuLiAiKSwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAvKiBIYW5kbGUgaXQgYXBwcm9wcmlhdGVseSAqLwogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdChwTWFjKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgICAgICAgICAgICAgICAgCiAgICAgICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOOgogICAgICAgICAgICAgICAgaWYgKCF0ZW1wVmFsKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTm8gY2FuZGlkYXRlIGZvdW5kIGFmdGVyIHNjYW5uaW5nIGluIHN0YXRlICVkLi4gIiksIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgLyogU3RvcCB0aGUgdGltZXIgaGVyZSBhcyB0aGUgc2FtZSB0aW1lciB3aWxsIGJlIHN0YXJ0ZWQgYWdhaW4gaW4gQ0ZHX0NIQU5fU0NBTl9TVEFURSAqLwogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgLy8gQ2FuIGNvbWUgb25seSBpbiBJTklUIHN0YXRlLiBXaGVyZSBpbiB3ZSBhcmUgYXNzb2NpYXRlZCwgd2Ugc2VudCBzY2FuIGFuZCB1c2VyCiAgICAgICAgICAgICAgICAvLyBpbiB0aGUgbWVhbnRpbWUgZGVjaWRlcyB0byBkaXNhc3NvYywgd2Ugd2lsbCBiZSBpbiBpbml0IHN0YXRlIGFuZCBzdGlsbCByZWNlaXZlZCBjYWxsCiAgICAgICAgICAgICAgICAvLyBiYWNrIGlzc3VlZC4gU2hvdWxkIG5vdCBjb21lIGhlcmUgaW4gYW55IG90aGVyIHN0YXRlLCBwcmludGluZyBqdXN0IGluIGNhc2UKICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLCAKICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gU3RhdGUgJWQiLCBfX2Z1bmNfXywgKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwoKICAgICAgICAgICAgICAgIC8vIExldHMganVzdCBleGl0IG91dCBzaWxlbnRseS4KICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICB9CiNlbmRpZgoKICAgICAgICBpZiAodGVtcFZhbCkKICAgICAgICB7CiAgICAgICAgICAgIFZPU19TVEFUVVMgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKCiAgICAgICAgICAgIGlmIChyb2FtTm93KQogICAgICAgICAgICB7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIGlmKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgICAgICAgICAgewojZW5kaWYKICAgICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICAgICAgICAgICAgICAgRkwoIkltbWVkaWF0ZSByb2FtLWRlcmVnaXN0ZXIgVVAgaW5kaWNhdGlvbi4gUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpKTsKCiAgICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KU5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9VUCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwoKICAgICAgICAgICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiQ291bGRuJ3QgZGVyZWdpc3RlciBsb29rdXAgVVAgY2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgICB9CiNlbmRpZgoKICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVRyaWdnZXJIYW5kb2ZmKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvKTsKICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgICAgICB9CgogICAgICAgIGhzdGF0dXMgPSBwYWxUaW1lclN0YXJ0KHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIsIAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZCAqIFBBTF9USU1FUl9UT19NU19VTklULAogICAgICAgICAgICAgICAgICAgIGVBTklfQk9PTEVBTl9GQUxTRSk7CgogICAgICAgICAgIC8qIFRoaXMgdGltZXIgc2hvdWxkIGJlIHN0YXJ0ZWQgYmVmb3JlIHJlZ2lzdGVyaW5nIHRoZSBSZWFzc29jIGNhbGxiYWNrIHdpdGggVEwuIFRoaXMgaXMgYmVjYXVzZSwgaXQgaXMgdmVyeSBsaWtlbHkgCiAgICAgICAgICAgICogdGhhdCB0aGUgY2FsbGJhY2sgZ2V0dGluZyBjYWxsZWQgaW1tZWRpYXRlbHkgYW5kIHRoZSB0aW1lciB3b3VsZCBuZXZlciBiZSBzdG9wcGVkIHdoZW4gcHJlLWF1dGggaXMgaW4gcHJvZ3Jlc3MgKi8KICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIGZhaWxlZCB0byBzdGFydCwgc3RhdHVzID0gJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgRE9XTiBldmVudCBSZWFzc29jIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCAqICgtMSkpOwogICAgICAgICAgICAvKiBSZWdpc3RlciBhIHJlYXNzb2MgSW5kaWNhdGlvbiBjYWxsYmFjayAqLwogICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICB9CiAKICAgICAgICB9CgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECmlmIChjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICB7CiAgICBpZiAoIXRlbXBWYWwgfHwgIXJvYW1Ob3cpCiAgICB7CiAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpCiAgICAgICB7CiAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9OT19DQU5EX0ZPVU5EX09SX05PVF9ST0FNSU5HX05PVyk7CiAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICAgICB9CiAgICAgICBlbHNlCiAgICAgICB7CiAgICAgICAgIC8qIFRoZXJlIGlzIG5vIGNhbmRpZGF0ZSBvciBXZSBhcmUgbm90IHJvYW1pbmcgTm93LgogICAgICAgICAgKiBJbmZvcm0gdGhlIEZXIHRvIHJlc3RhcnQgUm9hbSBPZmZsb2FkIFNjYW4gICovCiAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfUkVTVEFSVCwgUkVBU09OX05PX0NBTkRfRk9VTkRfT1JfTk9UX1JPQU1JTkdfTk9XKTsKICAgICAgIH0KICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CiAgICB9CiAgIH0KI2VuZGlmCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCn0KCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtU2NhblJlcXVlc3RDYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gcmVnaXN0ZXJlZCBpbiBjc3JTY2FuUmVxdWVzdCgpIHRvIAogICAgICAgICAgICBpbmRpY2F0ZSB0aGUgY29tcGxldGlvbiBvZiBzY2FuLiBJZiBzY2FuIGlzIGNvbXBsZXRlZCBmb3IgYWxsIHRoZSBjaGFubmVscyBpbiAKICAgICAgICAgICAgdGhlIGNoYW5uZWwgbGlzdCwgdGhpcyBmdW5jdGlvbiBnZXRzIHRoZSBzY2FuIHJlc3VsdCBhbmQgc3RhcnRzIHRoZSByZWZyZXNoIHJlc3VsdHMKICAgICAgICAgICAgdGltZXIgdG8gYXZvaWQgaGF2aW5nIHN0YWxlIHJlc3VsdHMuIElmIHNjYW4gaXMgbm90IGNvbXBsZXRlZCBvbiBhbGwgdGhlIGNoYW5uZWxzLAogICAgICAgICAgICBpdCByZXN0YXJ0cyB0aGUgbmVpZ2hib3Igc2NhbiB0aW1lciB3aGljaCBvbiBleHBpcnkgaXNzdWVzIHNjYW4gb24gdGhlIG5leHQgCiAgICAgICAgICAgIGNoYW5uZWwKCiAgICBccGFyYW0gIGhhbEhhbmRsZSAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcENvbnRleHQgLSBub3QgdXNlZAogICAgICAgICAgICBzY2FuSWQgLSBub3QgdXNlZAogICAgICAgICAgICBzdGF0dXMgLSBub3QgdXNlZAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1TY2FuUmVxdWVzdENhbGxiYWNrKHRIYWxIYW5kbGUgaGFsSGFuZGxlLCB2b2lkICpwQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTMyIHNjYW5JZCwgZUNzclNjYW5TdGF0dXMgc3RhdHVzKQp7CiAgICB0cEFuaVNpckdsb2JhbCAgICAgICAgICAgICAgICAgIHBNYWMgPSAodHBBbmlTaXJHbG9iYWwpIGhhbEhhbmRsZTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50Q2hhbkluZGV4OwogICAgZUhhbFN0YXR1cyAgICAgICAgICAgICAgaHN0YXR1czsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHRBTklfVTMyIHNlc3Npb25JZCA9IENTUl9TRVNTSU9OX0lEX0lOVkFMSUQ7CgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICB7CiAgICAgICAgc2Vzc2lvbklkID0gKigodEFOSV9VMzIqKXBDb250ZXh0KTsKICAgICAgICBpZiAoIWNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLHNlc3Npb25JZCkpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIHdoZW4gZmFzdCByb2FtIGlzIGRpc2FibGVkLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgIH0KICAgIH0KI2VuZGlmCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uc2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAKICAgIC8qIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIHJlY2VpdmUgYSBVUCBldmVudCBmcm9tIFRMIGluIGFueSBvZiB0aGUgc2NhbiBzdGF0ZXMuIFNpbGVudGx5IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlLiBNdXN0IGJlIGJlY2F1c2UgYSBVUCBldmVudCBmcm9tIFRMIGFmdGVyIGlzc3Vpbmcgc2NhbiByZXF1ZXN0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICAvKiAtMSBpcyBkb25lIGJlY2F1c2UgdGhlIGNoYW5JbmRleCB3b3VsZCBoYXZlIGdvdCBpbmNyZW1lbnRlZCBhZnRlciBpc3N1aW5nIGEgc3VjY2Vzc2Z1bCBzY2FuIHJlcXVlc3QgKi8KICAgIGN1cnJlbnRDaGFuSW5kZXggPSAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4KSA/IChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggLSAxKSA6IDA7CgogICAgLyogVmFsaWRhdGUgaW5wdXRzICovCiAgICBpZiAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KSB7IAogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoImNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2sgcmVjZWl2ZWQgZm9yIENoYW5uZWwgPSAlZCwgQ2hhbkluZGV4ID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbY3VycmVudENoYW5JbmRleF0sIGN1cnJlbnRDaGFuSW5kZXgpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiUmVjZWl2ZWQgZHVyaW5nIGNsZWFuLXVwLiBTaWxlbnRseSBpZ25vcmUgc2NhbiBjb21wbGV0aW9uIGV2ZW50LiIpKTsKICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIGlmIChlQU5JX0JPT0xFQU5fRkFMU0UgPT0gcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzKQogICAgewogICAgICAgIC8qIFNjYW4gaXMgY29tcGxldGVkIGluIHRoZSAgQ0ZHX0NIQU5fU0NBTiBzdGF0ZS4gV2UgY2FuIHRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUgCiAgICAgICAgICAganVzdCB0byBnZXQgdGhlIHJlc3VsdHMgYW5kIHBlcmZvcm0gUFJFQVVUSCAqLwogICAgICAgIC8qIE5vdyB3ZSBoYXZlIGNvbXBsZXRlZCBzY2FubmluZyB0aGUgY2hhbm5lbCBsaXN0LiBXZSBoYXZlIGdldCB0aGUgcmVzdWx0IGJ5IGFwcGx5aW5nIGFwcHJvcHJpYXRlIGZpbHRlcgogICAgICAgICAgIHNvcnQgdGhlIHJlc3VsdHMgYmFzZWQgb24gbmVpZ2hib3JTY29yZSBhbmQgUlNTSSBhbmQgc2VsZWN0IHRoZSBiZXN0IGNhbmRpZGF0ZSBvdXQgb2YgdGhlIGxpc3QgKi8KICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJDaGFubmVsIGxpc3Qgc2NhbiBjb21wbGV0ZWQuIEN1cnJlbnQgY2hhbiBpbmRleCA9ICVkIiksIGN1cnJlbnRDaGFuSW5kZXgpOwogICAgICAgIFZPU19BU1NFUlQocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID09IDApOwoKICAgICAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZShwTWFjKTsKCiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBwcm9jZXNzIGNvbXBsZXRlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgICAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CgogICAgICAgIC8qIFJlc3RhcnQgdGhlIHRpbWVyIGZvciB0aGUgbmV4dCBzY2FuIHNlcXVlbmNlIGFzIHNjYW5uaW5nIGlzIG5vdCBvdmVyICovCiAgICAgICAgaHN0YXR1cyA9IHBhbFRpbWVyU3RhcnQocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLCAKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yU2NhblBlcmlvZCAqIFBBTF9USU1FUl9UT19NU19VTklULCAKICAgICAgICAgICAgICAgICAgICBlQU5JX0JPT0xFQU5fRkFMU0UpOwogICAgCiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIC8qIFRpbWVyIHN0YXJ0IGZhaWxlZC4uIFNob3VsZCB3ZSBBU1NFUlQgaGVyZT8/PyAqLwogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gUEFMIFRpbWVyIHN0YXJ0IGZhaWxlZCwgc3RhdHVzID0gJWQsIElnbm9yaW5nIHN0YXRlIHRyYW5zaXRpb24iKSwgc3RhdHVzKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1TY2FuUmVzdWx0UmVxdWVzdENhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHRoZSBjYWxsYmFjayBmdW5jdGlvbiByZWdpc3RlcmVkIGluIGNzclNjYW5SZXF1ZXN0TGZyUmVzdWx0KCkgdG8KICAgICAgICAgICAgaW5kaWNhdGUgdGhlIGNvbXBsZXRpb24gb2Ygc2Nhbi4gSWYgc2NhbiBpcyBjb21wbGV0ZWQgZm9yIGFsbCB0aGUgY2hhbm5lbHMgaW4KICAgICAgICAgICAgdGhlIGNoYW5uZWwgbGlzdCwgdGhpcyBmdW5jdGlvbiBnZXRzIHRoZSBzY2FuIHJlc3VsdCBhbmQgdHJlYXRzIHRoZW0gYXMgY2FuZGlkYXRlcwoKICAgIFxwYXJhbSAgaGFsSGFuZGxlIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwQ29udGV4dCAtIG5vdCB1c2VkCiAgICAgICAgICAgIHNjYW5JZCAtIG5vdCB1c2VkCiAgICAgICAgICAgIHN0YXR1cyAtIG5vdCB1c2VkCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVNjYW5SZXN1bHRSZXF1ZXN0Q2FsbGJhY2sodEhhbEhhbmRsZSBoYWxIYW5kbGUsIHZvaWQgKnBDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTMyIHNjYW5JZCwgZUNzclNjYW5TdGF0dXMgc3RhdHVzKQp7CiAgICB0cEFuaVNpckdsb2JhbCAgICAgICAgICAgICAgICAgIHBNYWMgPSAodHBBbmlTaXJHbG9iYWwpIGhhbEhhbmRsZTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgICAgICAgICAgICAgaHN0YXR1czsKCiAgICBzbXNMb2cocE1hYywgTE9HMiwgRkwoImNhbGxlZCAiKSk7CiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uc2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgLyogd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQgKi8KICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIlJlY2VpdmVkIGluIG5vdCBDT05ORUNURUQgc3RhdGUuIElnbm9yZSBpdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICAvKiBOb3cgd2UgaGF2ZSBjb21wbGV0ZWQgc2Nhbm5pbmcgdGhlIGNoYW5uZWwgbGlzdC4gV2UgaGF2ZSBnZXQgdGhlIHJlc3VsdCBieSBhcHBseWluZyBhcHByb3ByaWF0ZSBmaWx0ZXIKICAgICAgIHNvcnQgdGhlIHJlc3VsdHMgYmFzZWQgb24gbmVpZ2hib3JTY29yZSBhbmQgUlNTSSBhbmQgc2VsZWN0IHRoZSBiZXN0IGNhbmRpZGF0ZSBvdXQgb2YgdGhlIGxpc3QgKi8KCiAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZShwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBwcm9jZXNzIGNvbXBsZXRlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CiNlbmRpZiAvL1dMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtQ29udGlndW91c1NjYW5SZXF1ZXN0Q2FsbGJhY2sodEhhbEhhbmRsZSBoYWxIYW5kbGUsIAogICAgICAgIHZvaWQgKnBDb250ZXh0LCB0QU5JX1UzMiBzY2FuSWQsIGVDc3JTY2FuU3RhdHVzIHN0YXR1cykKewogICAgdHBBbmlTaXJHbG9iYWwgICAgICAgICAgICAgICAgICBwTWFjID0gKHRwQW5pU2lyR2xvYmFsKSBoYWxIYW5kbGU7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgaHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0QU5JX1UzMiBzZXNzaW9uSWQgPSBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgewogICAgICAgIHNlc3Npb25JZCA9ICooKHRBTklfVTMyKilwQ29udGV4dCk7CiAgICAgICAgaWYgKCFjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYyxzZXNzaW9uSWQpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCB3aGVuIGZhc3Qgcm9hbSBpcyBkaXNhYmxlZC4gSWdub3JlIGl0IikpOwogICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICB9CiAgICB9CgogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgCiAgICAvKiBUaGlzIGNhbiBoYXBwZW4gd2hlbiB3ZSByZWNlaXZlIGEgVVAgZXZlbnQgZnJvbSBUTCBpbiBhbnkgb2YgdGhlIHNjYW4gc3RhdGVzLiBTaWxlbnRseSBpZ25vcmUgaXQgKi8KICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZS4gTXVzdCBiZSBiZWNhdXNlIGEgVVAgZXZlbnQgZnJvbSBUTCBhZnRlciBpc3N1aW5nIHNjYW4gcmVxdWVzdC4gSWdub3JlIGl0IikpOwogICAgICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIElOSVQgc3RhdGUuIE11c3QgaGF2ZSBkaXNjb25uZWN0ZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIiVzOiBwcm9jZXNzIHNjYW4gcmVzdWx0cyIsIF9fZnVuY19fKTsKICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlKHBNYWMpOwogICAgCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBwcm9jZXNzIGNvbXBsZXRlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgIH0KICAgIAogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKCiAgICByZXR1cm4gaHN0YXR1czsKfQojZW5kaWYKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc3N1ZUJnU2NhblJlcXVlc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXNzdWVzIENTUiBzY2FuIHJlcXVlc3QgYWZ0ZXIgcG9wdWxhdGluZyBhbGwgdGhlIEJHIHNjYW4gcGFyYW1zIAogICAgICAgICAgICBwYXNzZWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBCZ1NjYW5QYXJhbXMgLSBQYXJhbXMgdGhhdCBuZWVkIHRvIGJlIHBvcHVsYXRlZCBpbnRvIGNzciBTY2FuIHJlcXVlc3QKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jc3N1ZUJnU2NhblJlcXVlc3QodHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICpwQmdTY2FuUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0QU5JX1UzMiBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzclNjYW5Db21wbGV0ZUNhbGxiYWNrIGNhbGxiYWNrZm4pCnsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRBTklfVTMyIHNjYW5JZDsKICAgIHRDc3JTY2FuUmVxdWVzdCBzY2FuUmVxOwogICAgdEFOSV9VOCBjaGFubmVsOwogICAgdm9pZCAqIHVzZXJEYXRhID0gTlVMTDsKICAgIAogICAgaWYgKDEgPT0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJDaGFubmVsID0gJWQsIENoYW5JbmRleCA9ICVkIiksCiAgICAgICAgICAgIHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0WzBdLCAKICAgICAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4KTsKCiAgICAvL3NlbmQgZG93biB0aGUgc2NhbiByZXEgZm9yIDEgY2hhbm5lbCBvbiB0aGUgYXNzb2NpYXRlZCBTU0lECiAgICBwYWxaZXJvTWVtb3J5KHBNYWMtPmhIZGQsICZzY2FuUmVxLCBzaXplb2YodENzclNjYW5SZXF1ZXN0KSk7CiAgICAvKiBGaWxsIGluIHRoZSBTU0lEIEluZm8gKi8KICAgIHNjYW5SZXEuU1NJRHMubnVtT2ZTU0lEcyA9IDE7CiAgICBzY2FuUmVxLlNTSURzLlNTSURMaXN0ID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JTU0lESW5mbykgKiBzY2FuUmVxLlNTSURzLm51bU9mU1NJRHMpOwogICAgaWYoTlVMTCA9PSBzY2FuUmVxLlNTSURzLlNTSURMaXN0KQogICAgewogICAgICAgLy9lcnIgbXNnCiAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkNvdWxkbid0IGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIFNTSUQuLkZyZWVpbmcgbWVtb3J5IGFsbG9jYXRlZCBmb3IgQ2hhbm5lbCBMaXN0IikpOwogICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICB2b3NfbWVtX3plcm8oc2NhblJlcS5TU0lEcy5TU0lETGlzdCwgc2l6ZW9mKHRDc3JTU0lESW5mbykgKiBzY2FuUmVxLlNTSURzLm51bU9mU1NJRHMpOwoKICAgIHNjYW5SZXEuU1NJRHMuU1NJRExpc3RbMF0uaGFuZG9mZlBlcm1pdHRlZCA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgc2NhblJlcS5TU0lEcy5TU0lETGlzdFswXS5zc2lkSGlkZGVuID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICB2b3NfbWVtX2NvcHkoKHZvaWQgKikmc2NhblJlcS5TU0lEcy5TU0lETGlzdFswXS5TU0lELCAodm9pZCAqKSZwQmdTY2FuUGFyYW1zLT5TU0lELCBzaXplb2YocEJnU2NhblBhcmFtcy0+U1NJRCkpOwogICAgCiAgICBzY2FuUmVxLkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgPSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzOwogICAgaWYgKDEgPT0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgIHsKICAgICAgICBjaGFubmVsID0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbMF07CiAgICAgICAgc2NhblJlcS5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9ICZjaGFubmVsOyAgICAKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzY2FuUmVxLkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3Q7CiAgICB9CgogICAgc2NhblJlcS5CU1NUeXBlID0gZUNTUl9CU1NfVFlQRV9JTkZSQVNUUlVDVFVSRTsKICAgIHNjYW5SZXEuc2NhblR5cGUgPSBlU0lSX0FDVElWRV9TQ0FOOwogICAgc2NhblJlcS5yZXF1ZXN0VHlwZSA9IGVDU1JfU0NBTl9IT19CR19TQ0FOOwogICAgc2NhblJlcS5tYXhDaG5UaW1lID0gcEJnU2NhblBhcmFtcy0+bWF4Q2huVGltZTsKICAgIHNjYW5SZXEubWluQ2huVGltZSA9IHBCZ1NjYW5QYXJhbXMtPm1pbkNoblRpbWU7CgogICAgdXNlckRhdGEgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodEFOSV9VMzIpKTsKICAgIGlmIChOVUxMID09IHVzZXJEYXRhKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeSBmb3Igc2NhbiByZXF1ZXN0IikpOwogICAgICAgIHZvc19tZW1fZnJlZShzY2FuUmVxLlNTSURzLlNTSURMaXN0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgICooKHRBTklfVTMyKil1c2VyRGF0YSkgPSBzZXNzaW9uSWQ7CiAgICBzdGF0dXMgPSBjc3JTY2FuUmVxdWVzdChwTWFjLCBDU1JfU0VTU0lPTl9JRF9JTlZBTElELCAmc2NhblJlcSwKICAgICAgICAgICAgICAgICAgICAgICAgJnNjYW5JZCwgY2FsbGJhY2tmbiwgKHZvaWQgKikgdXNlckRhdGEpOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQ1NSIFNjYW4gUmVxdWVzdCBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgc3RhdHVzKTsKICAgICAgICB2b3NfbWVtX2ZyZWUoc2NhblJlcS5TU0lEcy5TU0lETGlzdCk7CiAgICAgICAgdm9zX21lbV9mcmVlKHVzZXJEYXRhKTsKICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX1RSVUU7CgogICAgdm9zX21lbV9mcmVlKHNjYW5SZXEuU1NJRHMuU1NJRExpc3QpOwogICAgaWYgKDEgPT0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJDaGFubmVsIExpc3QgQWRkcmVzcyA9ICUwOHgsIEFjdHVhbCBpbmRleCA9ICVkIiksCiAgICAgICAgICAgICAgICAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0WzBdLCAKICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCk7CgogICAgcmV0dXJuIHN0YXR1czsKfQoKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtRmlsbE5vbkNoYW5uZWxCZ1NjYW5QYXJhbXMgKHRwQW5pU2lyR2xvYmFsIHBNYWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHBDc3JCR1NjYW5SZXF1ZXN0IGJnU2NhblBhcmFtcykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0QU5JX1U4ICAgICAgICAgICAgIGJyb2FkY2FzdEJzc2lkW10gPSB7IDB4RkYsIDB4RkYsIDB4RkYsIDB4RkYsIDB4RkYsIDB4RkYgfTsKCiAgICB2b3NfbWVtX2NvcHkoYmdTY2FuUGFyYW1zLT5ic3NpZCwgYnJvYWRjYXN0QnNzaWQsIHNpemVvZih0Q3NyQnNzaWQpKTsKICAgIGJnU2NhblBhcmFtcy0+U1NJRC5sZW5ndGggPSBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3BOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuU1NJRC5sZW5ndGg7CiAgICB2b3NfbWVtX2NvcHkoYmdTY2FuUGFyYW1zLT5TU0lELnNzSWQsIAogICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELnNzSWQsCiAgICAgICAgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQubGVuZ3RoKTsKCiAgICBiZ1NjYW5QYXJhbXMtPm1pbkNoblRpbWUgPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1pbkNoYW5uZWxTY2FuVGltZTsKICAgIGJnU2NhblBhcmFtcy0+bWF4Q2huVGltZSA9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4Q2hhbm5lbFNjYW5UaW1lOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUJnU2NhbgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBpbnZva2VkIG9uIGV2ZXJ5IGV4cGlyeSBvZiBuZWlnaGJvclNjYW5UaW1lciB0aWxsIGFsbCAKICAgICAgICAgICAgdGhlIGNoYW5uZWxzIGluIHRoZSBjaGFubmVsIGxpc3QgYXJlIHNjYW5uZWQuIEl0IHBvcHVsYXRlcyBuZWNlc3NhcnkgCiAgICAgICAgICAgIHBhcmFtZXRlcnMgZm9yIEJHIHNjYW4gYW5kIGNhbGxzIGFwcHJvcHJpYXRlIEFQIHRvIGludm9rZSB0aGUgQ1NSIHNjYW4gCiAgICAgICAgICAgIHJlcXVlc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUJnU2Nhbih0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1UzMiBzZXNzaW9uSWQpCnsKICAgIGVIYWxTdGF0dXMgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0Q3NyQkdTY2FuUmVxdWVzdCAgIGJnU2NhblBhcmFtczsKICAgIHRBTklfVTggICAgICAgICAgICAgY2hhbm5lbCA9IDA7CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJDaGFubmVsIExpc3QgQWRkcmVzcyA9ICUwOHgiKSwgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdFswXSk7CiAgICB9CiAgICBlbHNlIAogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkNoYW5uZWwgTGlzdCBFbXB0eSIpKTsKICAgICAgICAvLyBHbyBiYWNrIGFuZCByZXN0YXJ0LiBNb3N0bHkgdGltZXIgc3RhcnQgZmFpbHVyZSBoYXMgb2NjdXJyZWQuCiAgICAgICAgLy8gV2hlbiB0aW1lciBzdGFydCBpcyBkZWNsYXJlZCBhIGZhaWx1cmUsIHRoZW4gd2UgZGVsZXRlIHRoZSBsaXN0LgogICAgICAgIC8vIFNob3VsZCBub3QgaGFwcGVuIG5vdyBhcyB3ZSBzdG9wIGFuZCB0aGVuIG9ubHkgc3RhcnQgdGhlIHNjYW4gdGltZXIuIAogICAgICAgIC8vIHN0aWxsIGhhbmRsZSB0aGUgdW5saWtlbHkgY2FzZS4KICAgICAgICBjc3JOZWlnaGJvclJvYW1IYW5kbGVFbXB0eVNjYW5SZXN1bHQocE1hYyk7CiAgICAgICAgcmV0dXJuIHN0YXR1czsKICAgIH0KCiAgICAvKiBWYWxpZGF0ZSB0aGUgY3VycmVudENoYW5JbmRleCB2YWx1ZSBiZWZvcmUgdXNpbmcgaXQgdG8gaW5kZXggdGhlIENoYW5uZWxMaXN0IGFycmF5ICovCiAgICBpZiAoIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleAogICAgICAgICAgICA+IHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkludmFsaWQgY2hhbm5lbCBpbmRleDogJWQiKSwgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4KTsKICAgICAgICAvLyBHbyBiYWNrIGFuZCByZXN0YXJ0LgogICAgICAgIGNzck5laWdoYm9yUm9hbUhhbmRsZUVtcHR5U2NhblJlc3VsdChwTWFjKTsKICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQoKICAgIC8qIE5lZWQgdG8gcGVyZm9ybSBzY2FuIGhlcmUgYmVmb3JlIGdldHRpbmcgdGhlIGxpc3QgKi8KCiAgICBwYWxaZXJvTWVtb3J5KHBNYWMtPmhIZGQsICZiZ1NjYW5QYXJhbXMsIHNpemVvZih0Q3NyQkdTY2FuUmVxdWVzdCkpOwoKICAgIGNoYW5uZWwgPSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4XTsKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gMTsKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9ICZjaGFubmVsOwogICAKICAgIGNzck5laWdoYm9yUm9hbUZpbGxOb25DaGFubmVsQmdTY2FuUGFyYW1zKHBNYWMsICZiZ1NjYW5QYXJhbXMpOwoKICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlQmdTY2FuUmVxdWVzdChwTWFjLCAmYmdTY2FuUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCwgY3NyTmVpZ2hib3JSb2FtU2NhblJlcXVlc3RDYWxsYmFjayk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJc3N1ZSBvZiBCRyBTY2FuIHJlcXVlc3QgZmFpbGVkOiBTdGF0dXMgPSAlZCIpLCBzdGF0dXMpOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCsrOwogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA+PSAKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICB7ICAgICAgCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiQ29tcGxldGVkIHNjYW5uaW5nIGNoYW5uZWxzIGluIENoYW5uZWwgTGlzdDogQ3VyckNoYW5JbmRleCA9ICVkLCBOdW0gQ2hhbm5lbHMgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpOwogICAgICAgIC8qIFdlIGhhdmUgY29tcGxldGVkIHNjYW5uaW5nIGFsbCB0aGUgY2hhbm5lbHMgKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSAwOwogICAgICAgIC8qIFdlIGFyZSBubyBsb25nZXIgc2Nhbm5pbmcgdGhlIGNoYW5uZWwgbGlzdC4gTmV4dCB0aW1lciBmaXJpbmcgc2hvdWxkIGJlIHVzZWQgdG8gZ2V0IHRoZSBzY2FuIHJlc3VsdHMgCiAgICAgICAgICAgYW5kIHNlbGVjdCB0aGUgYmVzdCBBUCBpbiB0aGUgbGlzdCAqLwogICAgICAgIGlmIChlQU5JX0JPT0xFQU5fVFJVRSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MpCiAgICAgICAgewogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICAvKgogICAgICAgICAqIElmIHRoZSBzdGF0dXMgaXMgbm90IHN1Y2Nlc3MsIHdlIG5lZWQgdG8gY2FsbCB0aGUgY2FsbGJhY2sKICAgICAgICAgKiByb3V0aW5lIHNvIHRoYXQgdGhlIHN0YXRlIG1hY2hpbmUgZG9lcyBub3QgZ2V0IHN0dWNrLgogICAgICAgICAqLwogICAgICAgIGNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2socE1hYywgTlVMTCwgMCwgZUNTUl9TQ0FOX0ZBSUxVUkUpOwogICAgfQoKICAgIHJldHVybiBzdGF0dXM7Cn0KCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUGVyZm9ybUNvbnRpZ3VvdXNCZ1NjYW4odHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkKQp7CiAgICBlSGFsU3RhdHVzICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRDc3JCR1NjYW5SZXF1ZXN0ICAgYmdTY2FuUGFyYW1zOwogICAgaW50IG51bU9mQ2hhbm5lbHMgPSAwLCBpID0gMDsKICAgIHRBTklfVTggICAqY2hhbm5lbExpc3QgPSBOVUxMOwogICAgdEFOSV9VOCAgICpwSW5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICB0QU5JX1U4ICAgdG1wQ2hhbm5lbExpc3RbV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOXTsKCiAgICBwYWxaZXJvTWVtb3J5KHBNYWMtPmhIZGQsICZiZ1NjYW5QYXJhbXMsIHNpemVvZih0Q3NyQkdTY2FuUmVxdWVzdCkpOwoKICAgIC8qIENvbnRpZ3VvdXNseSBzY2FuIGFsbCBjaGFubmVscyBmcm9tIHZhbGlkIGxpc3QgKi8KICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIiVzOiBnZXQgdmFsaWQgY2hhbm5lbCBsaXN0IiwgX19mdW5jX18pOwoKICAgIGlmIChOVUxMICE9IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMuY291bnRyeUNoYW5uZWxJbmZvLmNvdW50cnlWYWxpZENoYW5uZWxMaXN0LkNoYW5uZWxMaXN0KQogICAgewogICAgICAgIC8qIHRoaXMgbGlzdCBpcyBmaWxsZWQgb25seSBpZiB0aGUgY291bnRyeSBjb2RlIGlzIHNldCB0byBLUiAqLwogICAgICAgIG51bU9mQ2hhbm5lbHMgPSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY2ZnUGFyYW1zLmNvdW50cnlDaGFubmVsSW5mby5jb3VudHJ5VmFsaWRDaGFubmVsTGlzdC5udW1PZkNoYW5uZWxzOwogICAgICAgIHBJbkNoYW5uZWxMaXN0ID0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5jb3VudHJ5Q2hhbm5lbEluZm8uY291bnRyeVZhbGlkQ2hhbm5lbExpc3QuQ2hhbm5lbExpc3Q7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgbnVtT2ZDaGFubmVscyA9IHNpemVvZihwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QpOwoKICAgICAgICBpZighSEFMX1NUQVRVU19TVUNDRVNTKGNzckdldENmZ1ZhbGlkQ2hhbm5lbHMocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1UzMiAqKSAmbnVtT2ZDaGFubmVscykpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDb3VsZCBub3QgZ2V0IHZhbGlkIGNoYW5uZWwgbGlzdCIpKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgfQogICAgICAgIHBJbkNoYW5uZWxMaXN0ID0gcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0OwogICAgfQoKICAgIGlmIChDU1JfSVNfUk9BTV9JTlRSQV9CQU5EX0VOQUJMRUQocE1hYykpCiAgICB7CiAgICAgICAgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUN1cnJlbnRCYW5kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEluQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bXBDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscyk7CiAgICAgICAgcEluQ2hhbm5lbExpc3QgPSB0bXBDaGFubmVsTGlzdDsKICAgIH0KCiAgICBjaGFubmVsTGlzdCA9IHZvc19tZW1fbWFsbG9jKCBudW1PZkNoYW5uZWxzICk7CiAgICBpZiggTlVMTCA9PSBjaGFubmVsTGlzdCApCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJjb3VsZCBub3QgYWxsb2NhdGUgbWVtb3J5IGZvciBjaGFubmVsTGlzdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHZvc19tZW1fY29weShjaGFubmVsTGlzdCwgKHRBTklfVTggKilwSW5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKCiAgICBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyA9IG51bU9mQ2hhbm5lbHM7CiAgICBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBjaGFubmVsTGlzdDsKICAgIGZvciAoaSA9IDA7IGkgPCBudW1PZkNoYW5uZWxzOyBpKyspCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCAiJXM6IHZhbGlkIGNoYW5uZWwgbGlzdCA9ICVkIiwKICAgICAgICAgICAgICAgIF9fZnVuY19fLCBiZ1NjYW5QYXJhbXMuQ2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbaV0pOwogICAgfQogICAgY3NyTmVpZ2hib3JSb2FtRmlsbE5vbkNoYW5uZWxCZ1NjYW5QYXJhbXMocE1hYywgJmJnU2NhblBhcmFtcyk7CgogICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVCZ1NjYW5SZXF1ZXN0KHBNYWMsICZiZ1NjYW5QYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkLCBjc3JOZWlnaGJvclJvYW1Db250aWd1b3VzU2NhblJlcXVlc3RDYWxsYmFjayk7CgogICAgdm9zX21lbV9mcmVlKCBjaGFubmVsTGlzdCApOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIklzc3VlIG9mIEJHIFNjYW4gcmVxdWVzdCBmYWlsZWQ6IFN0YXR1cyA9ICVkIiksIHN0YXR1cyk7CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQojZW5kaWYKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1OZWlnaGJvclNjYW5UaW1lckNhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHRoZSBuZWlnaGJvciBzY2FuIHRpbWVyIGNhbGxiYWNrIGZ1bmN0aW9uLiBJdCBpbnZva2VzIAogICAgICAgICAgICB0aGUgQkcgc2NhbiByZXF1ZXN0IGJhc2VkIG9uIHRoZSBjdXJyZW50IGFuZCBwcmV2aW91cyBzdGF0ZXMKCiAgICBccGFyYW0gIHB2IC0gQ1NSIHRpbWVyIGNvbnRleHQgaW5mbyB3aGljaCBpbmNsdWRlcyBwTWFjIGFuZCBzZXNzaW9uIElECgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbU5laWdoYm9yU2NhblRpbWVyQ2FsbGJhY2sodm9pZCAqcHYpCnsKICAgIHRDc3JUaW1lckluZm8gKnBJbmZvID0gKHRDc3JUaW1lckluZm8gKilwdjsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBwSW5mby0+cE1hYzsKICAgIHRBTklfVTMyICAgICAgICAgc2Vzc2lvbklkID0gcEluZm8tPnNlc3Npb25JZDsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIC8vIGNoZWNrIGlmIGJnIHNjYW4gaXMgb24gZ29pbmcsIG5vIG5lZWQgdG8gc2VuZCBkb3duIHRoZSBuZXcgcGFyYW1zIGlmIHRydWUKICAgIGlmKGVBTklfQk9PTEVBTl9UUlVFID09IHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUnNwUGVuZGluZykKICAgIHsKICAgICAgIC8vbXNnCiAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIkFscmVhZHkgQmdTY2FuUnNwIGlzIFBlbmRpbmciKSk7CiAgICAgICByZXR1cm47CiAgICB9CgogICAgVk9TX0FTU0VSVChzZXNzaW9uSWQgPT0gcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCk7CgogICAgc3dpdGNoIChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOOgogICAgICAgICAgICBzd2l0Y2gocE5laWdoYm9yUm9hbUluZm8tPnByZXZOZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZOgogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVBlcmZvcm1CZ1NjYW4ocE1hYywgc2Vzc2lvbklkKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIGNhbGxiYWNrIHJlY2VpdmVkIGluIHN0YXRlICVkLCBwcmV2IHN0YXRlID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlLCBwTmVpZ2hib3JSb2FtSW5mby0+cHJldk5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOOiAgICAgCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVBlcmZvcm1CZ1NjYW4ocE1hYywgc2Vzc2lvbklkKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm47Cn0KCnZvaWQgY3NyTmVpZ2hib3JSb2FtRW1wdHlTY2FuUmVmcmVzaFRpbWVyQ2FsbGJhY2sodm9pZCAqY29udGV4dCkKewogICAgdENzclRpbWVySW5mbyAqcEluZm8gPSAodENzclRpbWVySW5mbyAqKWNvbnRleHQ7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gcEluZm8tPnBNYWM7CiAgICBWT1NfU1RBVFVTICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICAvKiBSZXNldCBhbGwgdGhlIHZhcmlhYmxlcyBqdXN0IGFzIG5vIHNjYW4gaGFkIGhhcHBlbmVkIGJlZm9yZSAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwoKI2lmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgJiYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKSAmJiAocE1hYy0+cnJtLnJybVNtZUNvbnRleHQucnJtQ29uZmlnLnJybUVuYWJsZWQpKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIjExUiBBc3NvY2lhdGlvbjpOZWlnaGJvciBMb29rdXAgRG93biBldmVudCByZWNlaXZlZCBpbiBDT05ORUNURUQgc3RhdGUiKSk7CiAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVOZWlnaGJvclJwdFJlcXVlc3QocE1hYyk7CiAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlcG9ydCByZXF1ZXN0IGZhaWxlZC4gc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtKys7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZKQogICAgfQogICAgZWxzZQojZW5kaWYKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJOb24gMTFSIG9yIENDWCBBc3NvY2lhdGlvbjplbXB0eSBzY2FuIHJlZnJlc2ggdGltZXIgZXhwaXJlZCIpKTsKICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbihwTWFjKTsKICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZXN1bHRzUmVmcmVzaFRpbWVyQ2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIHRpbWVyIGNhbGxiYWNrIGZ1bmN0aW9uIGZvciByZXN1bHRzIHJlZnJlc2ggdGltZXIuCiAgICAgICAgICAgIFdoZW4gdGhpcyBpcyBpbnZva2VkLCBpdCBpcyBhcyBnb29kIGFzIGRvd24gZXZlbnQgcmVjZWl2ZWQgZnJvbSBUTC4gU28sIAogICAgICAgICAgICBjbGVhciBvZmYgdGhlIHJvYW1hYmxlIEFQIGxpc3QgYW5kIHN0YXJ0IHRoZSBzY2FuIHByb2NlZHVyZSBiYXNlZCBvbiAxMVIgCiAgICAgICAgICAgIG9yIG5vbi0xMVIgYXNzb2NpYXRpb24KCiAgICBccGFyYW0gIGNvbnRleHQgLSBDU1IgdGltZXIgY29udGV4dCBpbmZvIHdoaWNoIGluY2x1ZGVzIHBNYWMgYW5kIHNlc3Npb24gSUQKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzdWx0c1JlZnJlc2hUaW1lckNhbGxiYWNrKHZvaWQgKmNvbnRleHQpCnsKICAgIHRDc3JUaW1lckluZm8gKnBJbmZvID0gKHRDc3JUaW1lckluZm8gKiljb250ZXh0OwogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IHBJbmZvLT5wTWFjOwogICAgVk9TX1NUQVRVUyAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICAgCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJEZXJlZ2lzdGVyaW5nIERPV04gZXZlbnQgcmVhc3NvYyBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQiKSwgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpKTsKCiAgICAvKiBEZXJlZ2lzdGVyIHJlYXNzb2MgY2FsbGJhY2suIElnbm9yZSByZXR1cm4gc3RhdHVzICovCiAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICB7CiAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgIH0KCiAgICAvKiBSZXNldCBhbGwgdGhlIHZhcmlhYmxlcyBqdXN0IGFzIG5vIHNjYW4gaGFkIGhhcHBlbmVkIGJlZm9yZSAqLwogICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwoKI2lmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgJiYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJCiAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKSAmJiAocE1hYy0+cnJtLnJybVNtZUNvbnRleHQucnJtQ29uZmlnLnJybUVuYWJsZWQpKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIjExUiBBc3NvY2lhdGlvbjpOZWlnaGJvciBMb29rdXAgRG93biBldmVudCByZWNlaXZlZCBpbiBDT05ORUNURUQgc3RhdGUiKSk7CiAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVOZWlnaGJvclJwdFJlcXVlc3QocE1hYyk7CiAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlcG9ydCByZXF1ZXN0IGZhaWxlZC4gc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtKys7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZKQogICAgfQogICAgZWxzZQojZW5kaWYgICAgICAKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJOb24gMTFSIG9yIENDWCBBc3NvY2lhdGlvbjpyZXN1bHRzIHJlZnJlc2ggdGltZXIgZXhwaXJlZCIpKTsKICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbihwTWFjKTsKICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm47Cn0KCiNpZiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICYmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSQovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXNzdWVOZWlnaGJvclJwdFJlcXVlc3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgaW52b2tlZCB3aGVuIFRMIGlzc3VlcyBhIGRvd24gZXZlbnQgYW5kIHRoZSBjdXJyZW50IGFzc29jIAogICAgICAgICAgICBpcyBhIDExUiBhc3NvY2lhdGlvbi4gSXQgaW52b2tlcyBTTUUgUlJNIEFQSSB0byBpc3N1ZSB0aGUgbmVpZ2hib3IgcmVxdWVzdCB0byAKICAgICAgICAgICAgdGhlIGN1cnJlbnRseSBhc3NvY2lhdGVkIEFQIHdpdGggdGhlIGN1cnJlbnQgU1NJRAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRScm1OZWlnaGJvclJzcENhbGxiYWNrSW5mbyBjYWxsYmFja0luZm87CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRScm1OZWlnaGJvclJlcSBuZWlnaGJvclJlcTsKCgogICAgbmVpZ2hib3JSZXEubm9fc3NpZCA9IDA7CgogICAgLyogRmlsbCBpbiB0aGUgU1NJRCAqLwogICAgbmVpZ2hib3JSZXEuc3NpZC5sZW5ndGggPSBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3BOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuU1NJRC5sZW5ndGg7CiAgICB2b3NfbWVtX2NvcHkobmVpZ2hib3JSZXEuc3NpZC5zc0lkLCBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3BOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuU1NJRC5zc0lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQubGVuZ3RoKTsKICAgIAogICAgY2FsbGJhY2tJbmZvLm5laWdoYm9yUnNwQ2FsbGJhY2sgPSBjc3JOZWlnaGJvclJvYW1SUk1OZWlnaGJvclJlcG9ydFJlc3VsdDsKICAgIGNhbGxiYWNrSW5mby5uZWlnaGJvclJzcENhbGxiYWNrQ29udGV4dCA9IHBNYWM7CiAgICBjYWxsYmFja0luZm8udGltZW91dCA9IHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUmVwb3J0VGltZW91dDsKCiAgICByZXR1cm4gc21lX05laWdoYm9yUmVwb3J0UmVxdWVzdChwTWFjLCh0QU5JX1U4KSBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLCAmbmVpZ2hib3JSZXEsICZjYWxsYmFja0luZm8pOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUN1cnJlbnRCYW5kCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZmlsdGVyIG91dCB0aGUgY2hhbm5lbHMKICAgICAgICAgICAgYmFzZWQgb24gdGhlIGN1cnJlbnRseSBhc3NvY2lhdGVkIEFQIGNoYW5uZWwKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGlucHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBpbnB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIGlucHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBwT3V0cHV0Q2hhbm5lbExpc3QgLSBUaGUgb3V0cHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBvdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBjaGFubmVscyBpbiBvdXRwdXQgY2hhbm5lbCBsaXN0CiAgICBccGFyYW0gIHBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIGZpbmFsIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgb3V0cHV0IGNoYW5uZWwgbGlzdC4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1DaGFubmVsc0ZpbHRlckJ5Q3VycmVudEJhbmQoCiAgICAgICAgICAgICAgICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCogIHBJbnB1dENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgaW50ICAgICAgIGlucHV0TnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTgqICBwT3V0cHV0Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICBpbnQqICAgICAgcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMKICAgICAgICAgICAgICAgICAgICAgICkKewogICAgaW50IGkgPSAwOwogICAgaW50IG51bUNoYW5uZWxzID0gMDsKICAgIHRBTklfVTggICBjdXJyQVBvcGVyYXRpb25DaGFubmVsID0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmN1cnJBUG9wZXJhdGlvbkNoYW5uZWw7CiAgICAvLyBDaGVjayBmb3IgTlVMTCBwb2ludGVyCiAgICBpZiAoIXBJbnB1dENoYW5uZWxMaXN0KSByZXR1cm4gVk9TX1NUQVRVU19FX0lOVkFMOwoKICAgIC8vIENoZWNrIGZvciBOVUxMIHBvaW50ZXIKICAgIGlmICghcE91dHB1dENoYW5uZWxMaXN0KSByZXR1cm4gVk9TX1NUQVRVU19FX0lOVkFMOwoKICAgIGlmIChpbnB1dE51bU9mQ2hhbm5lbHMgPiBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU4pCiAgICB7CiAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICIlczogV3JvbmcgTnVtYmVyIG9mIElucHV0IENoYW5uZWxzICVkIiwKICAgICAgICAgICAgIF9fZnVuY19fLCBpbnB1dE51bU9mQ2hhbm5lbHMpOwogICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0lOVkFMOwogICAgfQogICAgZm9yIChpID0gMDsgaSA8IGlucHV0TnVtT2ZDaGFubmVsczsgaSsrKQogICAgewogICAgICAgIGlmIChHZXRSRkJhbmQoY3VyckFQb3BlcmF0aW9uQ2hhbm5lbCkgPT0gR2V0UkZCYW5kKHBJbnB1dENoYW5uZWxMaXN0W2ldKSkKICAgICAgICB7CiAgICAgICAgICAgIHBPdXRwdXRDaGFubmVsTGlzdFtudW1DaGFubmVsc10gPSBwSW5wdXRDaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgbnVtQ2hhbm5lbHMrKzsKICAgICAgICB9CiAgICB9CgogICAgLy8gUmV0dXJuIGZpbmFsIG51bWJlciBvZiBjaGFubmVscwogICAgKnBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzID0gbnVtQ2hhbm5lbHM7CgogICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU1lcmdlQ2hhbm5lbExpc3RzIAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIG1lcmdlIHR3byBjaGFubmVsIGxpc3QuCiAgICAgICAgICAgIE5COiBJZiBjYWxsZWQgd2l0aCBvdXRwdXROdW1PZkNoYW5uZWxzID09IDAsIHRoaXMgcm91dGluZXMKICAgICAgICAgICAgICAgIHNpbXBseSBjb3BpZXMgdGhlIGlucHV0IGNoYW5uZWwgbGlzdCB0byB0aGUgb3V0cHV0IGNoYW5uZWwgbGlzdC4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGFkZHRpb25hbCBjaGFubmVscyB0byBtZXJnZSBpbiB0byB0aGUgIm1lcmdlZCIgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgaW5wdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBhZGRpdGlvbmFsIGNoYW5uZWxzLgogICAgXHBhcmFtICBwT3V0cHV0Q2hhbm5lbExpc3QgLSBUaGUgcGxhY2UgdG8gcHV0IHRoZSAibWVyZ2VkIiBjaGFubmVsIGxpc3QuCiAgICBccGFyYW0gIG91dHB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgb3JpZ2luYWwgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSAibWVyZ2VkIiBjaGFubmVscyBsaXN0LgogICAgXHBhcmFtICBwTWVyZ2VkT3V0cHV0TnVtT2ZDaGFubmVscyAtIFRoZSBmaW5hbCBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlICJtZXJnZWQiIGNoYW5uZWwgbGlzdC4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU1lcmdlQ2hhbm5lbExpc3RzKCAKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICB0QU5JX1U4ICAgKnBJbnB1dENoYW5uZWxMaXN0LCAKICAgICAgICBpbnQgaW5wdXROdW1PZkNoYW5uZWxzLAogICAgICAgIHRBTklfVTggICAqcE91dHB1dENoYW5uZWxMaXN0LAogICAgICAgIGludCBvdXRwdXROdW1PZkNoYW5uZWxzLAogICAgICAgIGludCAqcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMgCiAgICAgICAgKQp7CiAgICBpbnQgaSA9IDA7CiAgICBpbnQgaiA9IDA7CiAgICBpbnQgbnVtQ2hhbm5lbHMgPSBvdXRwdXROdW1PZkNoYW5uZWxzOwoKICAgIC8vIENoZWNrIGZvciBOVUxMIHBvaW50ZXIKICAgIGlmICghcElucHV0Q2hhbm5lbExpc3QpIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CgogICAgLy8gQ2hlY2sgZm9yIE5VTEwgcG9pbnRlcgogICAgaWYgKCFwT3V0cHV0Q2hhbm5lbExpc3QpIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CgogICAgaWYgKGlucHV0TnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgIHsKICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgIiVzOiBXcm9uZyBOdW1iZXIgb2YgSW5wdXQgQ2hhbm5lbHMgJWQiLAogICAgICAgICAgICAgX19mdW5jX18sIGlucHV0TnVtT2ZDaGFubmVscyk7CiAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CiAgICB9CiAgICAvLyBBZGQgdGhlICJuZXciIGNoYW5uZWxzIGluIHRoZSBpbnB1dCBsaXN0IHRvIHRoZSBlbmQgb2YgdGhlIG91dHB1dCBsaXN0LgogICAgZm9yIChpID0gMDsgaSA8IGlucHV0TnVtT2ZDaGFubmVsczsgaSsrKQogICAgewogICAgICAgIGZvciAoaiA9IDA7IGogPCBvdXRwdXROdW1PZkNoYW5uZWxzOyBqKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAocElucHV0Q2hhbm5lbExpc3RbaV0gPT0gcE91dHB1dENoYW5uZWxMaXN0W2pdKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGlmIChqID09IG91dHB1dE51bU9mQ2hhbm5lbHMpCiAgICAgICAgewogICAgICAgICAgICBpZiAocElucHV0Q2hhbm5lbExpc3RbaV0pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLCAKICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gQWRkaW5nIGV4dHJhICVkIHRvIE5laWdoYm9yIGNoYW5uZWwgbGlzdCIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICBwSW5wdXRDaGFubmVsTGlzdFtpXSk7IAogICAgICAgICAgICAgICAgcE91dHB1dENoYW5uZWxMaXN0W251bUNoYW5uZWxzXSA9IHBJbnB1dENoYW5uZWxMaXN0W2ldOyAKICAgICAgICAgICAgICAgIG51bUNoYW5uZWxzKys7IAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIFJldHVybiBmaW5hbCBudW1iZXIgb2YgY2hhbm5lbHMKICAgICpwTWVyZ2VkT3V0cHV0TnVtT2ZDaGFubmVscyA9IG51bUNoYW5uZWxzOyAKCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQ3JlYXRlQ2hhbkxpc3RGcm9tTmVpZ2hib3JSZXBvcnQKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgaW52b2tlZCB3aGVuIG5laWdoYm9yIHJlcG9ydCBpcyByZWNlaXZlZCBmb3IgdGhlIAogICAgICAgICAgICBuZWlnaGJvciByZXF1ZXN0LiBCYXNlZCBvbiB0aGUgY2hhbm5lbHMgcHJlc2VudCBpbiB0aGUgbmVpZ2hib3IgcmVwb3J0LCAKICAgICAgICAgICAgaXQgZ2VuZXJhdGVzIGNoYW5uZWwgbGlzdCB3aGljaCB3aWxsIGJlIHVzZWQgaW4gUkVQT1JUX1NDQU4gc3RhdGUgdG8KICAgICAgICAgICAgc2NhbiBmb3IgdGhlc2UgbmVpZ2hib3IgQVBzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtQ3JlYXRlQ2hhbkxpc3RGcm9tTmVpZ2hib3JSZXBvcnQodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBScm1OZWlnaGJvclJlcG9ydERlc2MgcE5laWdoYm9yQnNzRGVzYzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCAgICAgICAgIG51bUNoYW5uZWxzID0gMCwgaSA9IDA7CiAgICB0QU5JX1U4ICAgICAgICAgY2hhbm5lbExpc3RbTUFYX0JTU19JTl9ORUlHSEJPUl9SUFRdOwojaWYgMAogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKI2VuZGlmCgogICAgLyogVGhpcyBzaG91bGQgYWx3YXlzIHN0YXJ0IGZyb20gMCB3aGVuZXZlciB3ZSBjcmVhdGUgYSBjaGFubmVsIGxpc3Qgb3V0IG9mIG5laWdoYm9yIEFQIGxpc3QgKi8KICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydCA9IDA7CgogICAgcE5laWdoYm9yQnNzRGVzYyA9IHNtZVJybUdldEZpcnN0QnNzRW50cnlGcm9tTmVpZ2hib3JDYWNoZShwTWFjKTsKCiAgICB3aGlsZSAocE5laWdoYm9yQnNzRGVzYykKICAgIHsKICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID49IE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKSBicmVhazsKICAgICAgICAKICAgICAgICAvKiBVcGRhdGUgdGhlIG5laWdoYm9yIEJTUyBJbmZvIGluIHRoZSAxMXIgRlQgUm9hbSBJbmZvICovCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm9bcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0XS5jaGFubmVsTnVtID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvW3BOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydF0ubmVpZ2hib3JTY29yZSA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VOClwTmVpZ2hib3JCc3NEZXNjLT5yb2FtU2NvcmU7CiAgICAgICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvW3BOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydF0ubmVpZ2hib3JCc3NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0Kys7CgogICAgICAgIC8qIFNhdmluZyB0aGUgY2hhbm5lbCBsaXN0IG5vbi1yZWR1bmRhbnRseSAqLwogICAgICAgIGlmIChudW1DaGFubmVscyA+IDApCiAgICAgICAgewogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtQ2hhbm5lbHM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsID09IGNoYW5uZWxMaXN0W2ldKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIH0KICAgICAgICBpZiAoaSA9PSBudW1DaGFubmVscykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKENTUl9JU19ST0FNX0lOVFJBX0JBTkRfRU5BQkxFRChwTWFjKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdG8gYWRkIG9ubHkgaWYgaXRzIHRoZSBzYW1lIGJhbmQKICAgICAgICAgICAgICAgICAgICBpZiAoR2V0UkZCYW5kKHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSA9PQogICAgICAgICAgICAgICAgICAgICAgICBHZXRSRkJhbmQocE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWwpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gQWRkaW5nICVkIHRvIE5laWdoYm9yIGNoYW5uZWwgbGlzdCAoU2FtZSBiYW5kKVxuIiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3RbbnVtQ2hhbm5lbHNdID0gcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWw7CiAgICAgICAgICAgICAgICAgICAgICAgIG51bUNoYW5uZWxzKys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddIEFkZGluZyAlZCB0byBOZWlnaGJvciBjaGFubmVsIGxpc3RcbiIsIF9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsKTsKICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtudW1DaGFubmVsc10gPSBwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbDsKICAgICAgICAgICAgICAgICAgICBudW1DaGFubmVscysrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICBwTmVpZ2hib3JCc3NEZXNjID0gc21lUnJtR2V0TmV4dEJzc0VudHJ5RnJvbU5laWdoYm9yQ2FjaGUocE1hYywgcE5laWdoYm9yQnNzRGVzYyk7CiAgICB9CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCkKICAgIHsKI2lmIDAKICAgICAgICAvLyBCZWZvcmUgd2UgZnJlZSB0aGUgZXhpc3RpbmcgY2hhbm5lbCBsaXN0IGZvciBhIHNhZmV0eSBuZXQgbWFrZSBzdXJlCiAgICAgICAgLy8gd2UgaGF2ZSBhIHVuaW9uIG9mIHRoZSBJQVBQIGFuZCB0aGUgYWxyZWFkeSBleGlzdGluZyBsaXN0LiAKICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1NZXJnZUNoYW5uZWxMaXN0cyggCiAgICAgICAgICAgICAgICBwTWFjLCAKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscywgCiAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICBudW1DaGFubmVscywgCiAgICAgICAgICAgICAgICAmbnVtQ2hhbm5lbHMgKTsKI2VuZGlmCgogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAvKiBTdG9yZSB0aGUgb2J0YWluZWQgY2hhbm5lbCBsaXN0IHRvIHRoZSBOZWlnaGJvciBDb250cm9sIGRhdGEgc3RydWN0dXJlICovCiAgICBpZiAobnVtQ2hhbm5lbHMpCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gdm9zX21lbV9tYWxsb2MoKG51bUNoYW5uZWxzKSAqIHNpemVvZih0QU5JX1U4KSk7CiAgICBpZiAoTlVMTCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgQ2hhbm5lbCBsaXN0IGZhaWxlZC4uIFRMIGV2ZW50IGlnbm9yZWQiKSk7CiAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9SRVNPVVJDRVM7CiAgICB9CgogICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsIChudW1DaGFubmVscykgKiBzaXplb2YodEFOSV9VOCkpOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSBudW1DaGFubmVsczsKICAgIGlmIChudW1DaGFubmVscykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIklBUFAgTmVpZ2hib3IgbGlzdCBjYWxsYmFjayByZWNlaXZlZCBhcyBleHBlY3RlZCBpbiBzdGF0ZSAlZC4iKSwKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9UUlVFOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgIHsKICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfVVBEQVRFX0NGRywgUkVBU09OX0NIQU5ORUxfTElTVF9DSEFOR0VEKTsKICAgICAgICB9CiNlbmRpZgogICAgfQogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUlJNTmVpZ2hib3JSZXBvcnRSZXN1bHQKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIG5laWdoYm9yIHJlcG9ydCBjYWxsYmFjayB0aGF0IHdpbGwgYmUgaW52b2tlZCBieSAKICAgICAgICAgICAgU01FIFJSTSBvbiByZWNlaXZpbmcgYSBuZWlnaGJvciByZXBvcnQgb3Igb2YgbmVpZ2hib3IgcmVwb3J0IGlzIG5vdCAKICAgICAgICAgICAgcmVjZWl2ZWQgYWZ0ZXIgdGltZW91dC4gT24gcmVjZWl2aW5nIGEgdmFsaWQgcmVwb3J0LCBpdCBnZW5lcmF0ZXMgYSAKICAgICAgICAgICAgY2hhbm5lbCBsaXN0IGZyb20gdGhlIG5laWdoYm9yIHJlcG9ydCBhbmQgc3RhcnRzIHRoZSAKICAgICAgICAgICAgbmVpZ2hib3Igc2NhbiB0aW1lcgoKICAgIFxwYXJhbSAgY29udGV4dCAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgdm9zU3RhdHVzIC0gU3RhdHVzIG9mIHRoZSBjYWxsYmFjayhTVUNDRVNTL0ZBSUxVUkUpCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVJSTU5laWdoYm9yUmVwb3J0UmVzdWx0KHZvaWQgKmNvbnRleHQsIFZPU19TVEFUVVMgdm9zU3RhdHVzKQp7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gUE1BQ19TVFJVQ1QoY29udGV4dCk7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CgogICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVzdWx0IGNhbGxiYWNrIHdpdGggc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWToKICAgICAgICAgICAgLyogUmVzZXQgdGhlIHJlcG9ydCBwZW5kaW5nIHZhcmlhYmxlICovCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyA9PSB2b3NTdGF0dXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIE5lZWQgdG8gY3JlYXRlIGNoYW5uZWwgbGlzdCBiYXNlZCBvbiB0aGUgbmVpZ2hib3IgQVAgbGlzdCBhbmQgdHJhbnNpdGlvbiB0byBSRVBPUlRfU0NBTiBzdGF0ZSAqLwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtQ3JlYXRlQ2hhbkxpc3RGcm9tTmVpZ2hib3JSZXBvcnQocE1hYyk7CiAgICAgICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTID09IHZvc1N0YXR1cykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJDaGFubmVsIExpc3QgY3JlYXRlZCBmcm9tIE5laWdoYm9yIHJlcG9ydCwgVHJhbnNpdGlvbmluZyB0byBORUlHSEJPUl9TQ0FOIHN0YXRlIikpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIFdlIGFyZSBnb25uYSBzY2FuIG5vdy4gUmVtZW1iZXIgdGhlIHRpbWUgc3RhbXAgdG8gZmlsdGVyIG91dCByZXN1bHRzIG9ubHkgYWZ0ZXIgdGhpcyB0aW1lc3RhbXAgKi8KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA9ICh0QU5JX1RJTUVTVEFNUClwYWxHZXRUaWNrQ291bnQocE1hYy0+aEhkZCk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8qIE5vdyByZWFkeSBmb3IgbmVpZ2hib3Igc2NhbiBiYXNlZCBvbiB0aGUgY2hhbm5lbCBsaXN0IGNyZWF0ZWQgKi8KICAgICAgICAgICAgICAgIC8qIFN0YXJ0IE5laWdoYm9yIHNjYW4gdGltZXIgbm93LiBNdWx0aXBsaWNhdGlvbiBieSBQQUxfVElNRVJfVE9fTVNfVU5JVCBpcyB0byBjb252ZXJ0IG1zIHRvIHVzIHdoaWNoIGlzIAogICAgICAgICAgICAgICAgICAgd2hhdCBwYWxUaW1lclN0YXJ0IGV4cGVjdHMgKi8KICAgICAgICAgICAgICAgIHN0YXR1cyA9IHBhbFRpbWVyU3RhcnQocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yU2NhblBlcmlvZCAqIFBBTF9USU1FUl9UT19NU19VTklULCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlQU5JX0JPT0xFQU5fRkFMU0UpOwogICAgICAgICAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIFRpbWVyIHN0YXJ0IGZhaWxlZC4uIFNob3VsZCB3ZSBBU1NFUlQgaGVyZT8/PyAqLwogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUEFMIFRpbWVyIHN0YXJ0IGZvciBuZWlnaGJvciBzY2FuIHRpbWVyIGZhaWxlZCwgc3RhdHVzID0gJWQsIElnbm9yaW5nIHN0YXRlIHRyYW5zaXRpb24iKSwgc3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLyogTmVpZ2hib3Igc2NhbiB0aW1lciBzdGFydGVkLiBUcmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlICovCiAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIE5laWdoYm9yIHJlcG9ydCB0aW1lb3V0IGhhcHBlbmVkIGluIFNNRSBSUk0uIFdlIGNhbiB0cnkgc2VuZGluZyBtb3JlIG5laWdoYm9yIHJlcXVlc3RzIHVudGlsIHdlIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWNoIHRoZSBtYXhOZWlnaGJvclJldHJpZXMgb3IgcmVjZWl2aW5nIGEgc3VjY2Vzc2Z1bCBuZWlnaGJvciByZXNwb25zZSAqLwogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVzdWx0IGZhaWxlZCBhZnRlciAlZCByZXRyaWVzLCBNQVggUkVUUklFUyA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtLCBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heE5laWdoYm9yUmV0cmllcyk7CiAgICAgICAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPj0gCiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4TmVpZ2hib3JSZXRyaWVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQmFpbGluZyBvdXQgdG8gQ0ZHIENoYW5uZWwgbGlzdCBzY2FuLi4gIikpOwogICAgICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJUcmFuc2l0IHRvIENGRyBDaGFubmVsIGxpc3Qgc2NhbiBzdGF0ZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQgIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLyogV2UgdHJhbnNpdGlvbmVkIHRvIGRpZmZlcmVudCBzdGF0ZSBub3cuIFJlc2V0IHRoZSBOZWlnaGJvciByZXBvcnQgcmV0cnkgY291bnQgKi8KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVOZWlnaGJvclJwdFJlcXVlc3QocE1hYyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlcG9ydCByZXF1ZXN0IGZhaWxlZC4gc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICAgICAgICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXN1bHQgY2FsbGJhY2sgbm90IGV4cGVjdGVkIGluIHN0YXRlICVkLCBJZ25vcmluZy4uIiksIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuOwp9CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwoKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSIAp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtSXNTc2lkQW5kU2VjdXJpdHlNYXRjaCgKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBDdXJQcm9maWxlLAogICAgICAgIHRTaXJCc3NEZXNjcmlwdGlvbiAqcEJzc0Rlc2MsCiAgICAgICAgdERvdDExZkJlYWNvbklFcyAqcEllcykKewogICAgdENzckF1dGhMaXN0IGF1dGhUeXBlOwogICAgdENzckVuY3J5cHRpb25MaXN0IHVDRW5jcnlwdGlvblR5cGU7CiAgICB0Q3NyRW5jcnlwdGlvbkxpc3QgbUNFbmNyeXB0aW9uVHlwZTsKICAgIHRBTklfQk9PTEVBTiBmTWF0Y2ggPSBGQUxTRTsKCiAgICBhdXRoVHlwZS5udW1FbnRyaWVzID0gMTsKICAgIGF1dGhUeXBlLmF1dGhUeXBlWzBdID0gcEN1clByb2ZpbGUtPkF1dGhUeXBlOwogICAgdUNFbmNyeXB0aW9uVHlwZS5udW1FbnRyaWVzID0gMTsKICAgIHVDRW5jcnlwdGlvblR5cGUuZW5jcnlwdGlvblR5cGVbMF0gPSBwQ3VyUHJvZmlsZS0+RW5jcnlwdGlvblR5cGU7CiAgICBtQ0VuY3J5cHRpb25UeXBlLm51bUVudHJpZXMgPSAxOwogICAgbUNFbmNyeXB0aW9uVHlwZS5lbmNyeXB0aW9uVHlwZVswXSA9IHBDdXJQcm9maWxlLT5tY0VuY3J5cHRpb25UeXBlOwoKICAgIGlmKCBwSWVzICkKICAgIHsKICAgICAgICBpZihwSWVzLT5TU0lELnByZXNlbnQpCiAgICAgICAgewogICAgICAgICAgICBmTWF0Y2ggPSBjc3JJc1NzaWRNYXRjaCggcE1hYywKICAgICAgICAgICAgICAgICAgICAodm9pZCAqKXBDdXJQcm9maWxlLT5TU0lELnNzSWQsIHBDdXJQcm9maWxlLT5TU0lELmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICBwSWVzLT5TU0lELnNzaWQsIHBJZXMtPlNTSUQubnVtX3NzaWQsCiAgICAgICAgICAgICAgICAgICAgZUFOSV9CT09MRUFOX1RSVUUgKTsKICAgICAgICAgICAgaWYoVFJVRSA9PSBmTWF0Y2gpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZNYXRjaCA9IGNzcklzU2VjdXJpdHlNYXRjaCggcE1hYywgJmF1dGhUeXBlLCAmdUNFbmNyeXB0aW9uVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZtQ0VuY3J5cHRpb25UeXBlLCBwQnNzRGVzYywgcEllcywgTlVMTCwgTlVMTCwgTlVMTCApOwogICAgICAgICAgICAgICAgcmV0dXJuIChmTWF0Y2gpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIChmTWF0Y2gpOwogICAgICAgICAgICB9CgogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gRkFMU0U7ICAvLyBUcmVhdCBhIG1pc3NpbmcgU1NJRCBhcyBhIG5vbi1tYXRjaC4KICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOyAgLy8gQWdhaW4sIHRyZWF0IG1pc3NpbmcgcEllcyBhcyBhIG5vbi1tYXRjaC4KICAgIH0KfQoKdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUlzTmV3Q29ubmVjdGVkUHJvZmlsZSgKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBTklfVTggc2Vzc2lvbklkICAgPSAodEFOSV9VOClwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkOwogICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwQ3VyclByb2ZpbGUgPSBOVUxMOwogICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwUHJldlByb2ZpbGUgPSBOVUxMOwogICAgdERvdDExZkJlYWNvbklFcyAqcEllcyA9IE5VTEw7CiAgICB0U2lyQnNzRGVzY3JpcHRpb24gKnBCc3NEZXNjID0gTlVMTDsKICAgIHRBTklfQk9PTEVBTiBmTmV3ID0gVFJVRTsKCiAgICBpZighKHBNYWMtPnJvYW0ucm9hbVNlc3Npb24gJiYgQ1NSX0lTX1NFU1NJT05fVkFMSUQocE1hYywgc2Vzc2lvbklkKSkpCiAgICB7CiAgICAgICAgcmV0dXJuIChmTmV3KTsKICAgIH0KCiAgICBwQ3VyclByb2ZpbGUgPSAmcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGU7CiAgICBpZiggIXBDdXJyUHJvZmlsZSApCiAgICB7CiAgICAgICAgcmV0dXJuIChmTmV3KTsKfQoKICAgIHBQcmV2UHJvZmlsZSA9ICZwTmVpZ2hib3JSb2FtSW5mby0+cHJldkNvbm5Qcm9maWxlOwogICAgaWYoICFwUHJldlByb2ZpbGUgKQogICAgewogICAgICAgIHJldHVybiAoZk5ldyk7CiAgICB9CgogICAgcEJzc0Rlc2MgPSBwUHJldlByb2ZpbGUtPnBCc3NEZXNjOwogICAgaWYgKHBCc3NEZXNjKQogICAgewogICAgICAgIGlmIChIQUxfU1RBVFVTX1NVQ0NFU1MoY3NyR2V0UGFyc2VkQnNzRGVzY3JpcHRpb25JRXMocE1hYywKICAgICAgICAgICAgcEJzc0Rlc2MsICZwSWVzKSkgJiYKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtSXNTc2lkQW5kU2VjdXJpdHlNYXRjaChwTWFjLCBwQ3VyclByb2ZpbGUsIHBCc3NEZXNjLCBwSWVzKSkKICAgICAgICB7CiAgICAgICAgICAgIGZOZXcgPSBGQUxTRTsKICAgICAgICB9CiAgICAgICAgaWYgKHBJZXMpIHsKICAgICAgICAgICAgcGFsRnJlZU1lbW9yeShwTWFjLT5oSGRkLCBwSWVzKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGZOZXcpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJQcmV2IHJvYW0gcHJvZmlsZSBkaWQgbm90IG1hdGNoIGN1cnJlbnQiKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJQcmV2IHJvYW0gcHJvZmlsZSBtYXRjaGVzIGN1cnJlbnQiKSk7CiAgICB9CgogICAgcmV0dXJuIChmTmV3KTsKfQoKdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUNvbm5lY3RlZFByb2ZpbGVNYXRjaCgKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgIHRDc3JTY2FuUmVzdWx0ICpwUmVzdWx0LAogICAgICAgIHREb3QxMWZCZWFjb25JRXMgKnBJZXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCBzZXNzaW9uSWQgICA9ICh0QU5JX1U4KXBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQ7CiAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBDdXJQcm9maWxlID0gTlVMTDsKICAgIHRTaXJCc3NEZXNjcmlwdGlvbiAqcEJzc0Rlc2MgPSAmcFJlc3VsdC0+UmVzdWx0LkJzc0Rlc2NyaXB0b3I7CgogICAgaWYoICEocE1hYy0+cm9hbS5yb2FtU2Vzc2lvbgogICAgICAgICAgICAmJiBDU1JfSVNfU0VTU0lPTl9WQUxJRChwTWFjLCBzZXNzaW9uSWQpKSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcEN1clByb2ZpbGUgPSAmcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGU7CgogICAgaWYoICFwQ3VyUHJvZmlsZSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIGNzck5laWdoYm9yUm9hbUlzU3NpZEFuZFNlY3VyaXR5TWF0Y2gocE1hYywgcEN1clByb2ZpbGUsIHBCc3NEZXNjLCBwSWVzKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByZXBhcmVOb25PY2N1cGllZENoYW5uZWxMaXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gcHJlcGFyZSBhIGNoYW5uZWwgbGlzdCB0aGF0IGlzIGRlcml2ZWQgZnJvbQogICAgICAgICAgICB0aGUgbGlzdCBvZiB2YWxpZCBjaGFubmVscyBhbmQgZG9lcyBub3QgaW5jbHVkZSB0aG9zZSBpbiB0aGUgb2NjdXBpZWQKICAgICAgICAgICAgbGlzdC4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGRlZmF1bHQgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgbnVtT2ZDaGFubmVscyAtIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIGRlZmF1bHQgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgcE91dHB1dENoYW5uZWxMaXN0IC0gVGhlIHBsYWNlIHRvIHB1dCB0aGUgbm9uLW9jY3VwaWVkIGNoYW5uZWwgbGlzdC4KICAgIFxwYXJhbSAgcE91dHB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSBub24tb2NjdXBpZWQgY2hhbm5lbCBsaXN0LgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtUHJlcGFyZU5vbk9jY3VwaWVkQ2hhbm5lbExpc3QoCiAgICAgICAgdHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgdEFOSV9VOCAgICpwSW5wdXRDaGFubmVsTGlzdCwgCiAgICAgICAgaW50IG51bU9mQ2hhbm5lbHMsCiAgICAgICAgdEFOSV9VOCAgICpwT3V0cHV0Q2hhbm5lbExpc3QsCiAgICAgICAgaW50ICpwT3V0cHV0TnVtT2ZDaGFubmVscyAKICAgICAgICApCnsKICAgIGludCBpID0gMDsKICAgIGludCBvdXRwdXROdW1PZkNoYW5uZWxzICA9IDA7IC8vIENsZWFyIHRoZSBvdXRwdXQgbnVtYmVyIG9mIGNoYW5uZWxzCiAgICB0QU5JX1U4IG51bU9jY3VwaWVkQ2hhbm5lbHMgPSBwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHMubnVtQ2hhbm5lbHM7CiAgICB0QU5JX1U4ICpwT2NjdXBpZWRDaGFubmVsTGlzdCA9IHBNYWMtPnNjYW4ub2NjdXBpZWRDaGFubmVscy5jaGFubmVsTGlzdDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtT2ZDaGFubmVsczsgaSsrKQogICAgewogICAgICAgIGlmICghY3NySXNDaGFubmVsUHJlc2VudEluTGlzdChwT2NjdXBpZWRDaGFubmVsTGlzdCwgbnVtT2NjdXBpZWRDaGFubmVscywKICAgICAgICAgICAgIHBJbnB1dENoYW5uZWxMaXN0W2ldKSkKICAgICAgICB7CiAgICAgICAgICAgIHBPdXRwdXRDaGFubmVsTGlzdFtvdXRwdXROdW1PZkNoYW5uZWxzKytdID0gcElucHV0Q2hhbm5lbExpc3RbaV07CiAgICAgICAgfQogICAgfQoKICAgIHNtc0xvZyhwTWFjLCBMT0cyLCBGTCgiTnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSB2YWxpZCBjaGFubmVsIGxpc3Q9JWQ7ICIKICAgICAgICAgICAiTnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSBub24tb2NjdXBpZWQgbGlzdCBsaXN0PSVkIiksCiAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsIG91dHB1dE51bU9mQ2hhbm5lbHMpOwoKICAgIC8vIFJldHVybiB0aGUgbnVtYmVyIG9mIGNoYW5uZWxzCiAgICAqcE91dHB1dE51bU9mQ2hhbm5lbHMgPSBvdXRwdXROdW1PZkNoYW5uZWxzOyAKCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQojZW5kaWYgLyogRkVBVFVSRV9XTEFOX0xGUiAqLwoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuZXZlciB0aGVyZSBpcyBhIHRyYW5zaXRpb24gdG8gQ0ZHIGNoYW4gc2NhbiAKICAgICAgICAgICAgc3RhdGUgZnJvbSBhbnkgc3RhdGUuIEl0IGZyZWVzIHVwIHRoZSBjdXJyZW50IGNoYW5uZWwgbGlzdCBhbmQgYWxsb2NhdGVzIAogICAgICAgICAgICBhIG5ldyBtZW1vcnkgZm9yIHRoZSBjaGFubmVscyByZWNlaXZlZCBmcm9tIENGRyBpdGVtLiBJdCB0aGVuIHN0YXJ0cyB0aGUgCiAgICAgICAgICAgIG5laWdoYm9yIHNjYW4gdGltZXIgdG8gcGVyZm9ybSB0aGUgc2NhbiBvbiBlYWNoIGNoYW5uZWwgb25lIGJ5IG9uZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzICA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICBpbnQgaSA9IDA7CiAgICBpbnQgbnVtT2ZDaGFubmVscyA9IDA7CiAgICB0QU5JX1U4ICAgY2hhbm5lbExpc3RbV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOXTsKICAgIHRwQ3NyQ2hhbm5lbEluZm8gICAgY3VyckNoYW5uZWxMaXN0SW5mbzsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHRBTklfVTMyIHNlc3Npb25JZCA9IHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQ7CiNlbmRpZgogICAgY3VyckNoYW5uZWxMaXN0SW5mbyA9ICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm87CgogICAgaWYgKCAKI2lmZGVmIEZFQVRVUkVfV0xBTl9DQ1gKICAgICAgICAoKHBOZWlnaGJvclJvYW1JbmZvLT5pc0NDWEFzc29jKSAmJiAKICAgICAgICAgICAgICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPT0gZUFOSV9CT09MRUFOX0ZBTFNFKSkgfHwKICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPmlzQ0NYQXNzb2MgPT0gZUFOSV9CT09MRUFOX0ZBTFNFKSB8fCAKI2VuZGlmIC8vIENDWAogICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPT0gMCkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIkJ1aWxkaW5nIGNoYW5uZWwgbGlzdCB0byBzY2FuIikpOwoKCiAgICAgICAgLyogRnJlZSB1cCB0aGUgY2hhbm5lbCBsaXN0IGFuZCBhbGxvY2F0ZSBhIG5ldyBtZW1vcnkuIFRoaXMgaXMgYmVjYXVzZSB3ZSBkb250IGtub3cgaG93IG11Y2ggCiAgICAgICAgICAgIHdhcyBhbGxvY2F0ZWQgbGFzdCB0aW1lLiBJZiB3ZSBkaXJlY3RseSBjb3B5IG1vcmUgbnVtYmVyIG9mIGJ5dGVzIHRoYW4gYWxsb2NhdGVkIGVhcmxpZXIsIHRoaXMgbWlnaHQgCiAgICAgICAgICAgIHJlc3VsdCBpbiBtZW1vcnkgY29ycnVwdGlvbiAqLwogICAgICAgIGlmIChOVUxMICE9IGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICB9CgogICAgICAgIC8vIE5vdyBvYnRhaW4gdGhlIGNvbnRlbnRzIGZvciAiY2hhbm5lbExpc3QiICh0aGUgImRlZmF1bHQgdmFsaWQgY2hhbm5lbCBsaXN0IikgZnJvbSBFSVRIRVIKICAgICAgICAvLyB0aGUgZ05laWdoYm9yU2NhbkNoYW5uZWxMaXN0IGluICJjZmcuaW5pIiwgT1IgdGhlIGFjdHVhbCAidmFsaWQgY2hhbm5lbCBsaXN0IiBpbmZvcm1hdGlvbiBmb3JtZWQgYnkgQ1NSLgogICAgICAgIGlmICgwICE9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgICAgICB7CiAgICAgICAgICAgIC8vIENvcHkgdGhlICJkZWZhdWx0IHZhbGlkIGNoYW5uZWwgbGlzdCIgKGNoYW5uZWxMaXN0KSBmcm9tIHRoZSBnTmVpZ2hib3JTY2FuQ2hhbm5lbExpc3QgaW4gImNmZy5pbmkiLgogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsICJVc2luZyB0aGUgY2hhbm5lbCBsaXN0IGZyb20gY2ZnLmluaSIpOwogICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1NZXJnZUNoYW5uZWxMaXN0cyggCiAgICAgICAgICAgICAgICAgICAgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzLCAKICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICAgICAgMCwgLy9OQjogSWYgMCwgc2ltcGx5IGNvcHkgdGhlIGlucHV0IGNoYW5uZWwgbGlzdCB0byB0aGUgb3V0cHV0IGxpc3QuCiAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMgKTsKCiAgICAgICAgICAgIGlmIChDU1JfSVNfUk9BTV9JTlRSQV9CQU5EX0VOQUJMRUQocE1hYykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUNoYW5uZWxzRmlsdGVyQnlDdXJyZW50QmFuZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihudW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIHdyb25nIG51bWJlciBvZiBDaGFubmVsIGxpc3QiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0lOVkFMOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0KICAgICAgICAgICAgICAgIHZvc19tZW1fbWFsbG9jKG51bU9mQ2hhbm5lbHMqc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgICAgICAgaWYgKE5VTEwgPT0gY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZm9yIENoYW5uZWwgbGlzdCBmYWlsZWQiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX1JFU09VUkNFUzsKICAgICAgICAgICAgfQogICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LCBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgICB9IAojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIGVsc2UgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID09IERFRkFVTFRfU0NBTikgJiYKICAgICAgICAgICAgICAgICAoYWJzKHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSkgPgogICAgICAgICAgICAgICAgICBhYnMocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQpKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIAogICAgICAgICAgICAgKiBUcmlnZ2VyIGEgY29udGlndW91cyBzY2FuIG9uIGFsbCBjaGFubmVscyB3aGVuIHRoZQogICAgICAgICAgICAgKiBSU1NJIGluIHRoZSBsb29rdXAgRE9XTiBub3RpZmljYXRpb24gaXMgYmVsb3cgcmVhc3NvYyAKICAgICAgICAgICAgICogdGhyZXNob2xkLiBUaGlzIHdpbGwgaGVscCB1cyBmaW5kIHRoZSBiZXN0IGF2YWlsYWJsZSAKICAgICAgICAgICAgICogY2FuZGlkYXRlIGFuZCBhbHNvIHVwZGF0ZSB0aGUgY2hhbm5lbCBjYWNoZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIlRyaWdnZXJpbmcgY29udGlndW91cyBzY2FuICIKICAgICAgICAgICAgICAgICIobG9va3VwRE9XTlJzc2k9JWQscmVhc3NvY1RocmVzaG9sZD0lZCkiLAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpLAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQqKC0xKSk7CgogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJlcXVlc3RUaW1lU3RhbXAgPSAodEFOSV9USU1FU1RBTVApcGFsR2V0VGlja0NvdW50KHBNYWMtPmhIZGQpOwoKICAgICAgICAgICAgcGFsVGltZXJTdG9wKHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CgogICAgICAgICAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLCAKICAgICAgICAgICAgICogcHVyZ2Ugbm9uLVAyUCByZXN1bHRzIGZyb20gdGhlIHBhc3QgKi8KICAgICAgICAgICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0KHBNYWMsIFZPU19GQUxTRSk7CgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1QZXJmb3JtQ29udGlndW91c0JnU2NhbihwTWFjLCBzZXNzaW9uSWQpOwoKICAgICAgICAgICAgLyogVHJhbnNpdGlvbiB0byBDRkdfQ0hBTl9MSVNUX1NDQU4gKi8KICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOKTsKCiAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQojZW5kaWYKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBudW1PZkNoYW5uZWxzID0gcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLm51bUNoYW5uZWxzOwogICAgICAgICAgICBpZiAobnVtT2ZDaGFubmVscwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAgICAgJiYgKChwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID09IFNQTElUX1NDQU5fT0NDVVBJRURfTElTVCkgfHwKICAgICAgICAgICAgICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSAwKSB8fAogICAgICAgICAgICAgICAgICAgICgocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCAlIDIpID09IDEpKQojZW5kaWYKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIEFsd2F5cyBzY2FuIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBjaGFubmVsIGxpc3QKICAgICAgICAgICAgICAgICAqIGJlZm9yZSBzY2FubmluZyBvbiB0aGUgbm9uLW9jY3VwaWVkIGxpc3QuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIlN3aXRjaGluZyB0byBvY2N1cGllZCBjaGFubmVsIGxpc3QiCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAgICAgIi11U2Nhbk1vZGU9JWQsIHVFbXB0eVNjYW5Db3VudD0lZCIsCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50CiNlbmRpZgogICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBpZiAoQ1NSX0lTX1JPQU1fSU5UUkFfQkFORF9FTkFCTEVEKHBNYWMpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUNoYW5uZWxzRmlsdGVyQnlDdXJyZW50QmFuZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLmNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChudW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyA9IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9jb3B5KGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLmNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgVk9TX0FTU0VSVChjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCA9PSBOVUxMKTsKICAgICAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0gdm9zX21lbV9tYWxsb2MobnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CgogICAgICAgICAgICAgICAgaWYgKE5VTEwgPT0gY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgQ2hhbm5lbCBsaXN0IGZhaWxlZCIpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX1JFU09VUkNFUzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChudW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgPSBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIFNjYW4gYWxsIGNoYW5uZWxzIGZyb20gbm9uLW9jY3VwaWVkIGxpc3QgKi8KICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIkdldCB2YWxpZCBjaGFubmVsIGxpc3QiKTsKICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgPSBzaXplb2YocE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0KTsKCiAgICAgICAgICAgICAgICBpZihIQUxfU1RBVFVTX1NVQ0NFU1MoY3NyR2V0Q2ZnVmFsaWRDaGFubmVscyhwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1U4ICopcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1UzMiAqKSAmbnVtT2ZDaGFubmVscykpKQogICAgICAgICAgICB7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogUHJlcGFyZSBub24tb2NjdXBpZWQgY2hhbm5lbCBsaXN0IChjaGFubmVsTGlzdCkKICAgICAgICAgICAgICAgICAqIGZyb20gdGhlIGFjdHVhbCAidmFsaWQgY2hhbm5lbCBsaXN0IiBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICogZm9ybWVkIGJ5IENTUi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCAiU3dpdGNoaW5nIHRvIG5vbi1vY2N1cGllZCBjaGFubmVsIGxpc3QiKTsKICAgICAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByZXBhcmVOb25PY2N1cGllZENoYW5uZWxMaXN0KHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VOCAqKXBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzKTsKI2Vsc2UKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIk1lcmdpbmcgY2hhbm5lbCBsaXN0Iik7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1NZXJnZUNoYW5uZWxMaXN0cyggCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzLCAgIC8vIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIHZhbGlkQ2hhbm5lbExpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLy9OQjogSWYgMCwgc2ltcGx5IGNvcHkgdGhlIGlucHV0IGNoYW5uZWwgbGlzdCB0byB0aGUgb3V0cHV0IGxpc3QuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscyApOyAvLyBUaGUgZmluYWwgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSBvdXRwdXQgbGlzdC4gV2lsbCBiZSBudW1PZkNoYW5uZWxzCiNlbmRpZgogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDb3VsZCBub3QgZ2V0IHZhbGlkIGNoYW5uZWwgbGlzdCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKENTUl9JU19ST0FNX0lOVFJBX0JBTkRfRU5BQkxFRChwTWFjKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUN1cnJlbnRCYW5kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0KICAgICAgICAgICAgICAgIHZvc19tZW1fbWFsbG9jKG51bU9mQ2hhbm5lbHMqc2l6ZW9mKHRBTklfVTgpKTsKCiAgICAgICAgICAgIGlmIChOVUxMID09IGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZvciBDaGFubmVsIGxpc3QgZmFpbGVkIikpOwogICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9SRVNPVVJDRVM7CiAgICAgICAgICAgIH0KI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgdm9zX21lbV9jb3B5KGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LCBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKI2Vsc2UKICAgICAgICAgICAgaWYgKG51bU9mQ2hhbm5lbHMgPiBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU4pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgPSBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU47CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdm9zX21lbV9jb3B5KGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICh0QU5JX1U4ICopcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwojZW5kaWYKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogQWRqdXN0IGZvciB0aGUgYWN0dWFsIG51bWJlciB0aGF0IGFyZSB1c2VkICovCiAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVscyA9IG51bU9mQ2hhbm5lbHM7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCAKICAgICAgICAgICAgIk51bWJlciBvZiBjaGFubmVscyBmcm9tIENGRyAob3IpIChub24tKW9jY3VwaWVkIGxpc3Q9JWQiLAogICAgICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzKTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVsczsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCAiQ2hhbm5lbCBMaXN0IGZyb20gQ0ZHIChvcikgKG5vbi0pb2NjdXBpZWQgbGlzdCIKICAgICAgICAgICAgICAgICAgICAiPSAlZCIsIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0W2ldKTsKICAgICAgICB9CiAgICB9CgogICAgLyogV2UgYXJlIGdvbm5hIHNjYW4gbm93LiBSZW1lbWJlciB0aGUgdGltZSBzdGFtcCB0byBmaWx0ZXIgb3V0IHJlc3VsdHMgb25seSBhZnRlciB0aGlzIHRpbWVzdGFtcCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5SZXF1ZXN0VGltZVN0YW1wID0gKHRBTklfVElNRVNUQU1QKXBhbEdldFRpY2tDb3VudChwTWFjLT5oSGRkKTsKICAgIAogICAgcGFsVGltZXJTdG9wKHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAvKiBTdGFydCBOZWlnaGJvciBzY2FuIHRpbWVyIG5vdy4gTXVsdGlwbGljYXRpb24gYnkgUEFMX1RJTUVSX1RPX01TX1VOSVQgaXMgdG8gY29udmVydCBtcyB0byB1cyB3aGljaCBpcyAKICAgICAgICAgICAgd2hhdCBwYWxUaW1lclN0YXJ0IGV4cGVjdHMgKi8KICAgIHN0YXR1cyA9IHBhbFRpbWVyU3RhcnQocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLCAKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yU2NhblBlcmlvZCAqIFBBTF9USU1FUl9UT19NU19VTklULCAKICAgICAgICAgICAgICAgICAgICBlQU5JX0JPT0xFQU5fRkFMU0UpOwogICAgCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgLyogVGltZXIgc3RhcnQgZmFpbGVkLi4gICovCiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIFBBTCBUaW1lciBzdGFydCBmYWlsZWQsIHN0YXR1cyA9ICVkLCBJZ25vcmluZyBzdGF0ZSB0cmFuc2l0aW9uIiksIHN0YXR1cyk7CiAgICAgICAgdm9zX21lbV9mcmVlKGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KTsKICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQogICAgCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLCAKICAgICAqIHB1cmdlIG5vbi1QMlAgcmVzdWx0cyBmcm9tIHRoZSBwYXN0ICovCiAgICBjc3JTY2FuRmx1c2hTZWxlY3RpdmVSZXN1bHQocE1hYywgVk9TX0ZBTFNFKTsKCiAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLAogICAgICogcHVyZ2UgZmFpbGVkIHByZS1hdXRoIHJlc3VsdHMgZnJvbSB0aGUgcGFzdCAqLwogICAgY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbGVkTGlzdChwTWFjKTsKICAgIAogICAgLyogVHJhbnNpdGlvbiB0byBDRkdfQ0hBTl9MSVNUX1NDQU5fU1RBVEUgKi8KICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTikKCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVcEV2ZW50CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhcyBzb29uIGFzIFRMIGluZGljYXRlcyB0aGF0IHRoZSBjdXJyZW50IEFQJ3MgCiAgICAgICAgICAgIFJTU0kgaXMgYmV0dGVyIHRoYW4gdGhlIG5laWdoYm9yIGxvb2t1cCB0aHJlc2hvbGQuIEhlcmUsIHdlIHRyYW5zaXRpb24gdG8gCiAgICAgICAgICAgIENPTk5FQ1RFRCBzdGF0ZSBhbmQgcmVzZXQgYWxsIHRoZSBzY2FuIHBhcmFtZXRlcnMKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVcEV2ZW50KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzOwogICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKCiAgICAvKiBSZWNoZWNrIHdoZXRoZXIgdGhlIGJlbG93IGNoZWNrIGlzIG5lZWRlZC4gKi8KICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCkKICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBpZiAoIWNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jc3JTZXNzaW9uSWQpKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgd2hlbiBmYXN0IHJvYW0gaXMgZGlzYWJsZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KI2VuZGlmCiAgICAvKiBSZXNldCBhbGwgdGhlIG5laWdoYm9yIHJvYW0gaW5mbyBjb250cm9sIHZhcmlhYmxlcy4gRnJlZSBhbGwgdGhlIGFsbG9jYXRlZCBtZW1vcnkuIEl0IGlzIGxpa2Ugd2UgYXJlIGp1c3QgYXNzb2NpYXRlZCBub3cgKi8KICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKCiAgICAKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIERPV04gZXZlbnQgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCwiKSwgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSkpOwogICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBET1dOIGV2ZW50IG5vdyAqLwogICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwojZW5kaWYKICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgIHsKICAgICAgIC8vZXJyIG1zZwogICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBDYWxsYmFjayBET1dOIGV2ZW50IHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICB9CgoKICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERvd25FdmVudAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYXMgc29vbiBhcyBUTCBpbmRpY2F0ZXMgdGhhdCB0aGUgY3VycmVudCBBUCdzIAogICAgICAgICAgICBSU1NJIGZhbGxzIGJlbG93IHRoZSBjdXJyZW50IGVpZ2hib3IgbG9va3VwIHRocmVzaG9sZC4gSGVyZSwgd2UgdHJhbnNpdGlvbiB0byAKICAgICAgICAgICAgUkVQT1JUX1FVRVJZIGZvciAxMXIgYXNzb2NpYXRpb24gYW5kIENGR19DSEFOX0xJU1RfU0NBTiBzdGF0ZSBpZiB0aGUgYXNzb2MgaXMgCiAgICAgICAgICAgIGEgbm9uLTExUiBhc3NvY2lhdGlvbi4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBEb3duRXZlbnQodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICBlSGFsU3RhdHVzICBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwoKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRDoKICAgICAgICAgICAgCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkRlcmVnaXN0ZXJpbmcgRE9XTiBldmVudCBuZWlnaGJvciBsb29rdXAgY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkLCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSk7CiAgICAgICAgICAgIC8qIERlLXJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCAqLwogICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCBEZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwQ2FsbGJhY2sgRE9XTiBldmVudCBmcm9tIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICB9CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIGlmICghY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMscE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNzclNlc3Npb25JZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgd2hlbiBmYXN0IHJvYW0gaXMgZGlzYWJsZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgIAojaWYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAmJiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRkkKICAgICAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykgJiYgKHBNYWMtPnJybS5ycm1TbWVDb250ZXh0LnJybUNvbmZpZy5ycm1FbmFibGVkKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIjExUiBBc3NvY2lhdGlvbjpOZWlnaGJvciBMb29rdXAgRG93biBldmVudCByZWNlaXZlZCBpbiBDT05ORUNURUQgc3RhdGUiKSk7CiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdChwTWFjKTsKICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVwb3J0IHJlcXVlc3QgZmFpbGVkLiBzdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB2b3NTdGF0dXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0rKzsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZKQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKI2VuZGlmICAgICAgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIk5vbiAxMVIgb3IgQ0NYIEFzc29jaWF0aW9uOk5laWdoYm9yIExvb2t1cCBEb3duIGV2ZW50IHJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZSIpKTsKCiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbihwTWFjKTsKICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoImNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuIGZhaWxlZCIKICAgICAgICAgICAgICAgICAgICAgICAgIiB3aXRoIHN0YXR1cz0lZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiB2b3NTdGF0dXM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiUmVnaXN0ZXJpbmcgVVAgZXZlbnQgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCwiKSwgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSk7CiAgICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgVVAgZXZlbnQgbm93ICovCiAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfVVAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwQ2FsbGJhY2sgVVAgZXZlbnQgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgc3RhdHVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkRPV04gZXZlbnQgcmVjZWl2ZWQgaW4gaW52YWxpZCBzdGF0ZSAlZC4uSWdub3JpbmcuLi4iKSwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIAogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyByZWdpc3RlcmVkIHdpdGggVEwgdG8gaW5kaWNhdGUgd2hlbmV2ZXIgdGhlIFJTU0kgCiAgICAgICAgICAgIGdldHMgYmV0dGVyIHRoYW4gdGhlIG5laWdoYm9yTG9va3VwIFJTU0kgVGhyZXNob2xkCgogICAgXHBhcmFtICBwQWRhcHRlciAtIFZPUyBDb250ZXh0CiAgICAgICAgICAgIHRyYWZmaWNTdGF0dXMgLSBVUC9ET1dOIGluZGljYXRpb24gZnJvbSBUTAogICAgICAgICAgICBwVXNlckN0eHQgLSBQYXJhbWV0ZXIgZm9yIGNhbGxiYWNrIHJlZ2lzdGVyZWQgZHVyaW5nIGNhbGxiYWNrIHJlZ2lzdHJhdGlvbi4gU2hvdWxkIGJlIHBNYWMKCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLCB2X1U4X3QgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKCBwVXNlckN0eHQgKTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBMb29rdXAgVVAgaW5kaWNhdGlvbiBjYWxsYmFjayBjYWxsZWQgd2l0aCBub3RpZmljYXRpb24gJWQgUmVwb3J0ZWQgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2Z1Jzc2kpOwoKICAgIGlmKCFjc3JJc0Nvbm5TdGF0ZUNvbm5lY3RlZEluZnJhKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQpKQogICAgewogICAgICAgc21zTG9nKHBNYWMsIExPR1csICJJZ25vcmluZyB0aGUgaW5kaWNhdGlvbiBhcyB3ZSBhcmUgbm90IGNvbm5lY3RlZCIpOwogICAgICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBWT1NfQVNTRVJUKFdMQU5UTF9IT19USFJFU0hPTERfVVAgPT0gcnNzaU5vdGlmaWNhdGlvbik7CiAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVwRXZlbnQocE1hYyk7CiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgcmVnaXN0ZXJlZCB3aXRoIFRMIHRvIGluZGljYXRlIHdoZW5ldmVyIHRoZSBSU1NJIAogICAgICAgICAgICBmYWxscyBiZWxvdyB0aGUgY3VycmVudCBuZWlnaGJvckxvb2t1cCBSU1NJIFRocmVzaG9sZAoKICAgIFxwYXJhbSAgcEFkYXB0ZXIgLSBWT1MgQ29udGV4dAogICAgICAgICAgICB0cmFmZmljU3RhdHVzIC0gVVAvRE9XTiBpbmRpY2F0aW9uIGZyb20gVEwKICAgICAgICAgICAgcFVzZXJDdHh0IC0gUGFyYW1ldGVyIGZvciBjYWxsYmFjayByZWdpc3RlcmVkIGR1cmluZyBjYWxsYmFjayByZWdpc3RyYXRpb24uIFNob3VsZCBiZSBwTWFjCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLCB2X1U4X3QgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKCBwVXNlckN0eHQgKTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBMb29rdXAgRE9XTiBpbmRpY2F0aW9uIGNhbGxiYWNrIGNhbGxlZCB3aXRoIG5vdGlmaWNhdGlvbiAlZCBSZXBvcnRlZCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmdSc3NpKTsKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSBhdmdSc3NpOwojZW5kaWYKICAgIGlmKCFjc3JJc0Nvbm5TdGF0ZUNvbm5lY3RlZEluZnJhKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQpKQogICAgewogICAgICAgc21zTG9nKHBNYWMsIExPR1csICJJZ25vcmluZyB0aGUgaW5kaWNhdGlvbiBhcyB3ZSBhcmUgbm90IGNvbm5lY3RlZCIpOwogICAgICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBWT1NfQVNTRVJUKFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiA9PSByc3NpTm90aWZpY2F0aW9uKTsKICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRG93bkV2ZW50KHBNYWMpOwoKICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCiNpZmRlZiBSU1NJX0hBQ0sKZXh0ZXJuIGludCBkdW1wQ21kUlNTSTsKI2VuZGlmCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSW5kaWNhdGVEaXNjb25uZWN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBDU1IgYXMgc29vbiBhcyB0aGUgc3RhdGlvbiBkaXNjb25uZWN0cyBmcm9tIAogICAgICAgICAgICB0aGUgQVAuIFRoaXMgZnVuY3Rpb24gZG9lcyB0aGUgbmVjZXNzYXJ5IGNsZWFudXAgb2YgbmVpZ2hib3Igcm9hbSBkYXRhIAogICAgICAgICAgICBzdHJ1Y3R1cmVzLiBOZWlnaGJvciByb2FtIHN0YXRlIHRyYW5zaXRpb25zIHRvIElOSVQgc3RhdGUgd2hlbmV2ZXIgdGhpcyAKICAgICAgICAgICAgZnVuY3Rpb24gaXMgY2FsbGVkIGV4Y2VwdCBpZiB0aGUgY3VycmVudCBzdGF0ZSBpcyBSRUFTU09DSUFUSU5HCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBzZXNzaW9uSWQgLSBDU1Igc2Vzc2lvbiBpZCB0aGF0IGdvdCBkaXNjb25uZWN0ZWQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1JbmRpY2F0ZURpc2Nvbm5lY3QodHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwUHJldlByb2ZpbGUgPSAmcE5laWdoYm9yUm9hbUluZm8tPnByZXZDb25uUHJvZmlsZTsKI2VuZGlmCiAgICB0Q3NyUm9hbVNlc3Npb24gKnBTZXNzaW9uID0gQ1NSX0dFVF9TRVNTSU9OKCBwTWFjLCBzZXNzaW9uSWQpOwoKICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRGlzY29ubmVjdCBpbmRpY2F0aW9uIG9uIHNlc3Npb24gJWQgaW4gc3RhdGUgJWQiKSwKICAgICAgICAgICBzZXNzaW9uSWQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIC8qRnJlZSB0aGUgY3VycmVudCBwcmV2aW91cyBwcm9maWxlIGFuZCBtb3ZlIHRoZSBjdXJyZW50IHByb2ZpbGUgdG8gcHJldiBwcm9maWxlLiovCiAgICBjc3JSb2FtRnJlZUNvbm5lY3RQcm9maWxlKHBNYWMsIHBQcmV2UHJvZmlsZSk7CiAgICBjc3JSb2FtR2V0Q29ubmVjdFByb2ZpbGUocE1hYywgc2Vzc2lvbklkLCBwUHJldlByb2ZpbGUpOwojZW5kaWYKICAgIGlmIChOVUxMICE9IHBTZXNzaW9uKQogICAgewogICAgICAgIGlmIChOVUxMICE9IHBTZXNzaW9uLT5wQ3VyUm9hbVByb2ZpbGUpCiAgICAgICAgewogICAgICAgICAgICBpZiAoVk9TX1NUQV9NT0RFICE9IHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5wQ3VyUm9hbVByb2ZpbGUtPmNzclBlcnNvbmEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSWdub3JpbmcgRGlzY29ubmVjdCBpbmRpY2F0aW9uIHJlY2VpdmVkIGZyb20gYSBub24gU1RBIHBlcnNvbmEuIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXNzaW9uSWQ6ICVkLCBjc3JQZXJzb25uYSAlZCIpLCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgKGludClwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0ucEN1clJvYW1Qcm9maWxlLT5jc3JQZXJzb25hKTsKICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9DQ1gKICAgIHsKICAgICAgaWYgKHBTZXNzaW9uLT5jb25uZWN0ZWRQcm9maWxlLmlzQ0NYQXNzb2MpCiAgICAgIHsKICAgICAgICAgIHZvc19tZW1fY29weSgmcFNlc3Npb24tPnByZXZBcFNTSUQsICZwU2Vzc2lvbi0+Y29ubmVjdGVkUHJvZmlsZS5TU0lELCBzaXplb2YodFNpck1hY1NTaWQpKTsKICAgICAgICAgIHZvc19tZW1fY29weShwU2Vzc2lvbi0+cHJldkFwQnNzaWQsIHBTZXNzaW9uLT5jb25uZWN0ZWRQcm9maWxlLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICAgIHBTZXNzaW9uLT5wcmV2T3BDaGFubmVsID0gcFNlc3Npb24tPmNvbm5lY3RlZFByb2ZpbGUub3BlcmF0aW9uQ2hhbm5lbDsKICAgICAgICAgIHBTZXNzaW9uLT5pc1ByZXZBcEluZm9WYWxpZCA9IFRSVUU7CiAgICAgICAgICBwU2Vzc2lvbi0+cm9hbVRTMSA9IHZvc190aW1lcl9nZXRfc3lzdGVtX3RpbWUoKTsKCiAgICAgIH0KICAgIH0KI2VuZGlmCiAgIAojaWZkZWYgUlNTSV9IQUNLCiAgICBkdW1wQ21kUlNTSSA9IC00MDsKI2VuZGlmCiAgICBzd2l0Y2ggKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRUFTU09DSUFUSU5HOgogICAgICAgICAgICAvLyBTdG9wIHNjYW4gYW5kIG5laWdoYm9yIHJlZnJlc2ggdGltZXJzLgogICAgICAgICAgICAvLyBUaGVzZSBhcmUgaW5kZWVkIG5vdCByZXF1aXJlZCB3aGVuIHdlIGFyZSBpbiByZWFzc29jaWF0aW5nCiAgICAgICAgICAgIC8vIHN0YXRlLgogICAgICAgICAgICBwYWxUaW1lclN0b3AocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICAgICAgcGFsVGltZXJTdG9wKHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgICAgICBwYWxUaW1lclN0b3AocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CiAgICAgICAgICAgIGlmICghQ1NSX0lTX1JPQU1fU1VCU1RBVEVfRElTQVNTT0NfSE8oIHBNYWMsIHNlc3Npb25JZCApKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogRGlzY29ubmVjdCBpbmRpY2F0aW9uIGR1cmluZyBEaXNhc3NvYyBIYW5kb2ZmIHN1Yi1zdGF0ZQogICAgICAgICAgICAgICAgICogaXMgcmVjZWl2ZWQgd2hlbiB3ZSBhcmUgdHJ5aW5nIHRvIGRpc2Nvbm5lY3Qgd2l0aCB0aGUgb2xkCiAgICAgICAgICAgICAgICAgKiBBUCBkdXJpbmcgcm9hbS4gQlVULCBpZiByZWNlaXZlIGEgZGlzY29ubmVjdCBpbmRpY2F0aW9uIAogICAgICAgICAgICAgICAgICogb3V0c2lkZSBvZiBEaXNhc3NvYyBIYW5kb2ZmIHN1Yi1zdGF0ZSwgdGhlbiBpdCBtZWFucyB0aGF0IAogICAgICAgICAgICAgICAgICogdGhpcyBpcyBhIGdlbnVpbmUgZGlzY29ubmVjdCBhbmQgd2UgbmVlZCB0byBjbGVhbiB1cC4KICAgICAgICAgICAgICAgICAqIE90aGVyd2lzZSwgd2Ugd2lsbCBiZSBzdHVjayBpbiByZWFzc29jIHN0YXRlIHdoaWNoIHdpbGwKICAgICAgICAgICAgICAgICAqIGluLXR1cm4gYmxvY2sgc2NhbnMgKHNlZSBjc3JJc1NjYW5BbGxvd2VkKS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQ6CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0SW5pdFN0YXRlQ29udHJvbEluZm8ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYoIXBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgICAgICB7CiNlbmRpZgogICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICAgICAgYnJlYWs7IAoKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQ6CiAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZighcE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOOgogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKTsKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRDZmdMaXN0Q2hhblNjYW5Db250cm9sSW5mbyhwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAoIXBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgICAgICB7CiNlbmRpZgogICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORToKICAgICAgICAgICAgLyogU3RvcCBwcmUtYXV0aCB0byByZWFzc29jIGludGVydmFsIHRpbWVyICovCiAgICAgICAgICAgIHBhbFRpbWVyU3RvcChwTWFjLT5oSGRkLCBwTWFjLT5mdC5mdFNtZUNvbnRleHQucHJlQXV0aFJlYXNzb2NJbnR2bFRpbWVyKTsKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTjoKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIRU5USUNBVElORzoKICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCkKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRQcmVhdXRoQ29udHJvbEluZm8ocE1hYyk7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0UmVwb3J0U2NhblN0YXRlQ29udHJvbEluZm8ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKCFwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewojZW5kaWYKICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJSZWNlaXZlZCBkaXNjb25uZWN0IGV2ZW50IGluIHN0YXRlICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoIlRyYW5zaXRpb25pbmcgdG8gSU5JVCBzdGF0ZSIpKTsKICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCkKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIC8qSW5mb3JtIHRoZSBGaXJtd2FyZSB0byBTVE9QIFNjYW5uaW5nIGFzIHRoZSBob3N0IGhhcyBhIGRpc2Nvbm5lY3QuKi8KICAgIGlmIChjc3JSb2FtSXNTdGFNb2RlKHBNYWMsIHNlc3Npb25JZCkpCiAgICB7CiAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCwgUkVBU09OX0RJU0NPTk5FQ1RFRCk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1JbmRpY2F0ZUNvbm5lY3QKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IENTUiBhcyBzb29uIGFzIHRoZSBzdGF0aW9uIGNvbm5lY3RzIHRvIGFuIEFQLgogICAgICAgICAgICBUaGlzIGluaXRpYWxpemVzIGFsbCB0aGUgbmVjZXNzYXJ5IGRhdGEgc3RydWN0dXJlcyByZWxhdGVkIHRvIHRoZSAKICAgICAgICAgICAgYXNzb2NpYXRlZCBBUCBhbmQgdHJhbnNpdGlvbnMgdGhlIHN0YXRlIHRvIENPTk5FQ1RFRCBzdGF0ZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgc2Vzc2lvbklkIC0gQ1NSIHNlc3Npb24gaWQgdGhhdCBnb3QgY29ubmVjdGVkCiAgICAgICAgICAgIHZvc1N0YXR1cyAtIGNvbm5lY3Qgc3RhdHVzIFNVQ0NFU1MvRkFJTFVSRQoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUluZGljYXRlQ29ubmVjdCh0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1U4IHNlc3Npb25JZCwgVk9TX1NUQVRVUyB2b3NTdGF0dXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIFZPU19TVEFUVVMgIHZzdGF0dXM7CgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fQ0NYKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICBpbnQgIGluaXRfZnRfZmxhZyA9IEZBTFNFOwojZW5kaWYKCiAgICBzbXNMb2cocE1hYywgTE9HMiwgRkwoIkNvbm5lY3QgaW5kaWNhdGlvbiByZWNlaXZlZCB3aXRoIHNlc3Npb24gaWQgJWQgaW4gc3RhdGUgJWQiKSwgc2Vzc2lvbklkLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwoKICAgIC8vIEJhaWwgb3V0IGlmIHRoaXMgaXMgTk9UIGEgU1RBIHBlcnNvbmEgb3IgaWYgYSBjb25jdXJyZW50IHNlc3Npb24gaXMgcnVubmluZwogICAgaWYgKChwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0ucEN1clJvYW1Qcm9maWxlLT5jc3JQZXJzb25hICE9IFZPU19TVEFfTU9ERSl8fAogICAgICAgIGNzcklzQ29uY3VycmVudFNlc3Npb25SdW5uaW5nKHBNYWMpKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSWdub3JpbmcgQ29ubmVjdCBpbmRpY2F0aW9uIHJlY2VpdmVkIGZyb20gYSBub24gU1RBIHBlcnNvbmEuIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2Vzc2lvbklkOiAlZCwgY3NyUGVyc29ubmEgJWQsIGlzIG11bHRpc2Vzc2lvbiAlZCIpLAogICAgICAgICAgICAgICBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgIChpbnQpcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLnBDdXJSb2FtUHJvZmlsZS0+Y3NyUGVyc29uYSwKICAgICAgICAgICAgICAgY3NySXNDb25jdXJyZW50U2Vzc2lvblJ1bm5pbmcocE1hYykpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFQVNTT0NJQVRJTkc6CiAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBKdXN0IHRyYW5zaXRpb24gdGhlIHN0YXRlIHRvIElOSVQgc3RhdGUuIFJlc3Qgb2YgdGhlIGNsZWFuIHVwIGhhcHBlbnMgd2hlbiB3ZSBnZXQgbmV4dCBjb25uZWN0IGluZGljYXRpb24gKi8KICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBGYWxsIHRocm91Z2ggaWYgdGhlIHN0YXR1cyBpcyBTVUNDRVNTICovCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVDoKICAgICAgICAgICAgLyogUmVzZXQgYWxsIHRoZSBkYXRhIHN0cnVjdHVyZXMgaGVyZSAqLyAKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRJbml0U3RhdGVDb250cm9sSW5mbyhwTWFjKTsKCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQgPSBzZXNzaW9uSWQ7CgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJbml0aWFsaXplIHRoZSBvY2N1cGllZCBsaXN0IE9OTFkgaWYgd2UgYXJlCiAgICAgICAgICAgICAqIHRyYW5zaXRpb25pbmcgZnJvbSBJTklUIHN0YXRlIHRvIENPTk5FQ1RFRCBzdGF0ZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgICAgICAgICBjc3JJbml0T2NjdXBpZWRDaGFubmVsc0xpc3QocE1hYyk7CiNlbmRpZgogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpOwoKICAgICAgICAgICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgCiAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLmJzc2lkLCBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBvcGVyYXRpb25DaGFubmVsID0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUub3BlcmF0aW9uQ2hhbm5lbDsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVySW5mby5wTWFjID0gcE1hYzsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVySW5mby5zZXNzaW9uSWQgPSBzZXNzaW9uSWQ7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgPQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZDsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9IDA7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPSBERUZBVUxUX1NDQU47CiNlbmRpZgoKICAgICAgICAgICAgCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9DQ1gpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgICAgICAgICAgLyogTm93IHdlIGNhbiBjbGVhciB0aGUgcHJlYXV0aERvbmUgdGhhdCB3YXMgc2F2ZWQgYXMgd2UgYXJlIGNvbm5lY3RlZCBhZnJlc2ggKi8KICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLCAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KTsKI2VuZGlmCiAgICAgICAgICAgIAojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICAgICAgLy8gQmFzZWQgb24gdGhlIGF1dGggc2NoZW1lIHRlbGwgaWYgd2UgYXJlIDExcgogICAgICAgICAgICBpZiAoIGNzcklzQXV0aFR5cGUxMXIoIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLkF1dGhUeXBlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5NRElELm1kaWVQcmVzZW50KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNGYXN0VHJhbnNpdGlvbkVuYWJsZWQpCiAgICAgICAgICAgICAgICAgICAgaW5pdF9mdF9mbGFnID0gVFJVRTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIjExckFzc29jIGlzID0gJWQiKSwgcE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpOwojZW5kaWYKCiNpZmRlZiBGRUFUVVJFX1dMQU5fQ0NYCiAgICAgICAgICAgIC8vIEJhc2VkIG9uIHRoZSBhdXRoIHNjaGVtZSB0ZWxsIGlmIHdlIGFyZSAxMXIKICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLmlzQ0NYQXNzb2MpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzRmFzdFRyYW5zaXRpb25FbmFibGVkKQogICAgICAgICAgICAgICAgICAgIGluaXRfZnRfZmxhZyA9IFRSVUU7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNDQ1hBc3NvYyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0NDWEFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJpc0NDWEFzc29jIGlzID0gJWQgZnQgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0NDWEFzc29jLCBpbml0X2Z0X2ZsYWcpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgCiNlbmRpZgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICAgICAgLy8gSWYgIkxlZ2FjeSBGYXN0IFJvYW1pbmciIGlzIGVuYWJsZWQgCiAgICAgICAgICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgc2Vzc2lvbklkKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaW5pdF9mdF9mbGFnID0gVFJVRTsKICAgICAgICAgICAgfQojZW5kaWYKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9DQ1gpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgICAgICAgICAgaWYgKCBpbml0X2Z0X2ZsYWcgPT0gVFJVRSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIEluaXRpYWxpemUgYWxsIHRoZSBkYXRhIHN0cnVjdHVyZXMgbmVlZGVkIGZvciB0aGUgMTFyIEZUIFByZWF1dGggKi8KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtID0gMDsKICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxlZExpc3QocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIC8qSWYgdGhpcyBpcyBub3QgYSBJTkZSQSB0eXBlIEJTUywgdGhlbiBkbyBub3Qgc2VuZCB0aGUgY29tbWFuZAogICAgICAgICAgICAgICAgICAqIGRvd24gdG8gZmlybXdhcmUuRG8gbm90IHNlbmQgdGhlIFNUQVJUIGNvbW1hbmQgZm9yIG90aGVyIHNlc3Npb24KICAgICAgICAgICAgICAgICAgKiBjb25uZWN0aW9ucy4qLwogICAgICAgICAgICAgICAgIGlmKGNzclJvYW1Jc1N0YU1vZGUocE1hYywgc2Vzc2lvbklkKSkKICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgoKICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIG5laWdoYm9yIGxvb2t1cCBET1dOIGV2ZW50IHdpdGggVEwsIFJTU0kgPSAlZCIpLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKTsKICAgICAgICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgRE9XTiBldmVudCBvbmx5ICovCiAgICAgICAgICAgICAgICB2c3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSwgcE1hYyk7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwojZW5kaWYKICAgICAgICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1ModnN0YXR1cykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZzdGF0dXMpOwogICAgICAgICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgIH0KI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRCAqLwogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkNvbm5lY3QgZXZlbnQgcmVjZWl2ZWQgaW4gaW52YWxpZCBzdGF0ZSAlZC4uSWdub3JpbmcuLi4iKSwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CgoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsZWRMaXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHB1cmdlcyBhbGwgdGhlIE1BQyBhZGRyZXNzZXMgaW4gdGhlIHByZS1hdXRoIGZhaWwgbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbGVkTGlzdCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0QU5JX1U4IGk7CgogICAgZm9yIChpID0gMDsgaSA8IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzOyBpKyspCiAgICB7CiAgICAgICAgdm9zX21lbV96ZXJvKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5tYWNBZGRyZXNzW2ldLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgIH0KICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzID0gMDsKCiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jbml0MTFyQXNzb2NJbmZvCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGluaXRpYWxpemVzIDExciByZWxhdGVkIG5laWdoYm9yIHJvYW0gZGF0YSBzdHJ1Y3R1cmVzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUluaXQxMXJBc3NvY0luZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgZUhhbFN0YXR1cyAgc3RhdHVzOwogICAgdHBDc3IxMXJBc3NvY05laWdoYm9ySW5mbyAgIHBGVFJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvOwoKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5pczExckFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5tYXhOZWlnaGJvclJldHJpZXMgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTWF4TmVpZ2hib3JSZXRyaWVzOwogICAgcEZUUm9hbUluZm8tPm5laWdoYm9yUmVwb3J0VGltZW91dCA9IENTUl9ORUlHSEJPUl9ST0FNX1JFUE9SVF9RVUVSWV9USU1FT1VUOwogICAgcEZUUm9hbUluZm8tPlBFUHJlYXV0aFJlc3BUaW1lb3V0ID0gQ1NSX05FSUdIQk9SX1JPQU1fUFJFQVVUSF9SU1BfV0FJVF9NVUxUSVBMSUVSICogcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvclNjYW5QZXJpb2Q7CiAgICBwRlRSb2FtSW5mby0+bmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcEZUUm9hbUluZm8tPnByZWF1dGhSc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPSAwOwogICAgdm9zX21lbV96ZXJvKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0Q3NyTmVpZ2hib3JSZXBvcnRCc3NJbmZvKSAqIE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKTsKCiAgICAKICAgIHN0YXR1cyA9IGNzckxMT3BlbihwTWFjLT5oSGRkLCAmcEZUUm9hbUluZm8tPnByZUF1dGhEb25lTGlzdCk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJMTCBPcGVuIG9mIHByZWF1dGggZG9uZSBBUCBMaXN0IGZhaWxlZCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jbml0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGluaXRpYWxpemVzIG5laWdoYm9yIHJvYW0gZGF0YSBzdHJ1Y3R1cmVzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUluaXQodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgZUhhbFN0YXR1cyBzdGF0dXM7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgICAgICAgPSAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DTE9TRUQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cHJldk5laWdoYm9yUm9hbVN0YXRlICAgPSAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DTE9TRUQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkICAgICAgICAgICAgPSAgIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heENoYW5uZWxTY2FuVGltZSA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvclNjYW5NYXhDaGFuVGltZTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWluQ2hhbm5lbFNjYW5UaW1lID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yU2Nhbk1pbkNoYW5UaW1lOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5tYXhOZWlnaGJvclJldHJpZXMgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvckxvb2t1cFJzc2lUaHJlc2hvbGQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvclJlYXNzb2NSc3NpVGhyZXNob2xkOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclNjYW5QZXJpb2QgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JTY2FuVGltZXJQZXJpb2Q7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2QgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuZW1wdHlTY2FuUmVmcmVzaFBlcmlvZCA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5FbXB0eVNjYW5SZWZyZXNoUGVyaW9kOwoKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0NDWCkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jb3VudHJ5Q2hhbm5lbEluZm8ucmV2aXNpb24gPSBTTUVfS1JfMjU7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNvdW50cnlDaGFubmVsSW5mby5jb3VudHJ5VmFsaWRDaGFubmVsTGlzdC5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNvdW50cnlDaGFubmVsSW5mby5jb3VudHJ5VmFsaWRDaGFubmVsTGlzdC5udW1PZkNoYW5uZWxzID0gMDsKCiAgICBpZiAoMCA9PSBzdHJuY21wKHBNYWMtPnNjYW4uY291bnRyeUNvZGVDdXJyZW50LCAiS1IiLCAyKSkKICAgIHsKICAgICAgIGNzckluaXRDb3VudHJ5VmFsaWRDaGFubmVsTGlzdChwTWFjLCBTTUVfS1JfMjUpOwogICAgfQojZW5kaWYKCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgICA9CiAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5laWdoYm9yU2NhbkNoYW5MaXN0Lm51bUNoYW5uZWxzOwoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPQogICAgICAgICAgICAgICAgdm9zX21lbV9tYWxsb2MocE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubmVpZ2hib3JTY2FuQ2hhbkxpc3QubnVtQ2hhbm5lbHMpOwoKICAgIGlmIChOVUxMID09IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgQWxsb2NhdGlvbiBmb3IgQ0ZHIENoYW5uZWwgTGlzdCBmYWlsZWQiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KCiAgICAvKiBVcGRhdGUgdGhlIHJvYW0gZ2xvYmFsIHN0cnVjdHVyZSBmcm9tIENGRyAqLwogICAgcGFsQ29weU1lbW9yeShwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uZWlnaGJvclNjYW5DaGFuTGlzdC5jaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubmVpZ2hib3JTY2FuQ2hhbkxpc3QubnVtQ2hhbm5lbHMpOwoKICAgIHZvc19tZW1fc2V0KHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwgc2l6ZW9mKHRDc3JCc3NpZCksIDApOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQ7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gREVGQVVMVF9TQ0FOOwogICAgcGFsWmVyb01lbW9yeShwTWFjLT5oSGRkLCAmcE5laWdoYm9yUm9hbUluZm8tPnByZXZDb25uUHJvZmlsZSwKICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRDc3JSb2FtQ29ubmVjdGVkUHJvZmlsZSkpOwojZW5kaWYKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXJJbmZvLnBNYWMgPSBwTWFjOwogICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVySW5mby5zZXNzaW9uSWQgPSBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwogICAgc3RhdHVzID0gcGFsVGltZXJBbGxvYyhwTWFjLT5oSGRkLCAmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLCAKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvclNjYW5UaW1lckNhbGxiYWNrLCAodm9pZCAqKSZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXJJbmZvKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHRpbWVyIGFsbG9jYXRpb24gZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IHBhbFRpbWVyQWxsb2MocE1hYy0+aEhkZCwgJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIsIAogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc3VsdHNSZWZyZXNoVGltZXJDYWxsYmFjaywgKHZvaWQgKikmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVySW5mbyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyIGFsbG9jYXRpb24gZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICBwYWxUaW1lckZyZWUocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHN0YXR1cyA9IHBhbFRpbWVyQWxsb2MocE1hYy0+aEhkZCwgJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIsCiAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1FbXB0eVNjYW5SZWZyZXNoVGltZXJDYWxsYmFjaywKICAgICAgICAgICAgICAgICh2b2lkICopJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lckluZm8pOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBhbGxvY2F0aW9uIGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgcGFsVGltZXJGcmVlKHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgcGFsVGltZXJGcmVlKHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CgogICAgc3RhdHVzID0gY3NyTExPcGVuKHBNYWMtPmhIZGQsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTEwgT3BlbiBvZiByb2FtYWJsZSBBUCBMaXN0IGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgcGFsVGltZXJGcmVlKHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgcGFsVGltZXJGcmVlKHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgIHBhbFRpbWVyRnJlZShwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9IENTUl9ORUlHSEJPUl9ST0FNX0lOVkFMSURfQ0hBTk5FTF9JTkRFWDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSW5pdDExckFzc29jSW5mbyhwTWFjKTsKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkxMIE9wZW4gb2Ygcm9hbWFibGUgQVAgTGlzdCBmYWlsZWQiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHBhbFRpbWVyRnJlZShwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgIHBhbFRpbWVyRnJlZShwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsgICAgICAgIAogICAgICAgIHBhbFRpbWVyRnJlZShwTWFjLT5oSGRkLCBwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAgICBjc3JMTENsb3NlKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CiNlbmRpZgogICAgLyogSW5pdGlhbGl6ZSB0aGlzIHdpdGggdGhlIGN1cnJlbnQgdGljayBjb3VudCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5SZXF1ZXN0VGltZVN0YW1wID0gKHRBTklfVElNRVNUQU1QKXBhbEdldFRpY2tDb3VudChwTWFjLT5oSGRkKTsKCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUNsb3NlCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGNsb3Nlcy9mcmVlcyBhbGwgdGhlIG5laWdoYm9yIHJvYW0gZGF0YSBzdHJ1Y3R1cmVzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1DbG9zZSh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBSb2FtIEFsZ29yaXRobSBBbHJlYWR5IENsb3NlZCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXJJbmZvLnBNYWMgPSBOVUxMOwogICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVySW5mby5zZXNzaW9uSWQgPSBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwogICAgcGFsVGltZXJGcmVlKHBNYWMtPmhIZGQsIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICBwYWxUaW1lckZyZWUocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICBwYWxUaW1lckZyZWUocE1hYy0+aEhkZCwgcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CgogICAgLyogU2hvdWxkIGZyZWUgdXAgdGhlIG5vZGVzIGluIHRoZSBsaXN0IGJlZm9yZSBjbG9zaW5nIHRoZSBkb3VibGUgTGlua2VkIGxpc3QgKi8KICAgIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICBjc3JMTENsb3NlKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KQogICAgewogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSBDU1JfTkVJR0hCT1JfUk9BTV9JTlZBTElEX0NIQU5ORUxfSU5ERVg7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX0ZBTFNFOyAgICAKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIC8qIEZyZWUgdGhlIHByb2ZpbGUuLiAqLyAKICAgIGNzclJlbGVhc2VQcm9maWxlKHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZSk7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSICAgIAogICAgY3NyUm9hbUZyZWVDb25uZWN0UHJvZmlsZShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnByZXZDb25uUHJvZmlsZSk7CiNlbmRpZgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtID0gMDsKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydCA9IDA7CiAgICB2b3NfbWVtX3plcm8ocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm8sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwogICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLCAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KTsKICAgIGNzckxMQ2xvc2UoJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCk7CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwoKICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRCkKICAgIAogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVxdWVzdEhhbmRvZmYKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gdHJpZ2dlcnMgYWN0dWFsIHN3aXRjaGluZyBmcm9tIG9uZSBBUCB0byB0aGUgbmV3IEFQLgogICAgICAgICAgICBJdCBpc3N1ZXMgZGlzYXNzb2NpYXRlIHdpdGggcmVhc29uIGNvZGUgYXMgSGFuZG9mZiBhbmQgQ1NSIGFzIGEgcGFydCBvZiAKICAgICAgICAgICAgaGFuZGxpbmcgZGlzYXNzb2MgcnNwLCBpc3N1ZXMgcmVhc3NvY2lhdGUgdG8gdGhlIG5ldyBBUAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVxdWVzdEhhbmRvZmYodHBBbmlTaXJHbG9iYWwgcE1hYykKewoKICAgIHRDc3JSb2FtSW5mbyByb2FtSW5mbzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VMzIgc2Vzc2lvbklkID0gcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZDsKICAgIHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvICAgICBoYW5kb2ZmTm9kZTsKICAgIGV4dGVybiB2b2lkIGNzclJvYW1Sb2FtaW5nU3RhdGVEaXNhc3NvY1JzcFByb2Nlc3NvciggdHBBbmlTaXJHbG9iYWwgcE1hYywgdFNpclNtZURpc2Fzc29jUnNwICpwU21lRGlzYXNzb2NSc3AgKTsKICAgIHRBTklfVTMyIHJvYW1JZCA9IDA7CgogICAgaWYgKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSAhPSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FKSAKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJvYW0gcmVxdWVzdGVkIHdoZW4gTmVpZ2hib3Igcm9hbSBpcyBpbiAlZCBzdGF0ZSIpLAogICAgICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICB2b3NfbWVtX3plcm8oJnJvYW1JbmZvLCBzaXplb2YodENzclJvYW1JbmZvKSk7CiAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsICZyb2FtSW5mbywgcm9hbUlkLCBlQ1NSX1JPQU1fRlRfU1RBUlQsIAogICAgICAgICAgICAgICAgZVNJUl9TTUVfU1VDQ0VTUyk7CgogICAgdm9zX21lbV96ZXJvKCZyb2FtSW5mbywgc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORykKICAgIAogICAgY3NyTmVpZ2hib3JSb2FtR2V0SGFuZG9mZkFQSW5mbyhwTWFjLCAmaGFuZG9mZk5vZGUpOwogICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0RFQlVHLAogICAgICAgICAgICAgICBGTCgiSEFORE9GRiBDQU5ESURBVEUgQlNTSUQgJTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4OiUwMngiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZFswXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+YnNzSWRbMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kb2ZmTm9kZS5wQnNzRGVzY3JpcHRpb24tPmJzc0lkWzJdLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZFszXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+YnNzSWRbNF0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYW5kb2ZmTm9kZS5wQnNzRGVzY3JpcHRpb24tPmJzc0lkWzVdKTsKICAgCiAgICAvKiBGcmVlIHRoZSBwcm9maWxlLi4gSnVzdCB0byBtYWtlIHN1cmUgd2UgZG9udCBsZWFrIG1lbW9yeSBoZXJlICovIAogICAgY3NyUmVsZWFzZVByb2ZpbGUocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlKTsKICAgIC8qIENyZWF0ZSB0aGUgSGFuZG9mZiBBUCBwcm9maWxlLiBDb3B5IHRoZSBjdXJyZW50bHkgY29ubmVjdGVkIHByb2ZpbGUgYW5kIHVwZGF0ZSBvbmx5IHRoZSBCU1NJRCBhbmQgY2hhbm5lbCBudW1iZXIKICAgICAgICBUaGlzIHNob3VsZCBoYXBwZW4gYmVmb3JlIGlzc3VpbmcgZGlzY29ubmVjdCAqLwogICAgY3NyUm9hbUNvcHlDb25uZWN0ZWRQcm9maWxlKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsICZwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZSk7CiAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPmNzck5laWdoYm9yUm9hbVByb2ZpbGUuQlNTSURzLmJzc2lkLCBoYW5kb2ZmTm9kZS5wQnNzRGVzY3JpcHRpb24tPmJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlLkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0WzBdID0gaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsSWQ7CiAgICAKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIiBjc3JSb2FtSGFuZG9mZlJlcXVlc3RlZDogZGlzYXNzb2NpYXRpbmcgd2l0aCBjdXJyZW50IEFQIik7CgogICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhjc3JSb2FtSXNzdWVEaXNhc3NvY2lhdGVDbWQocE1hYywgc2Vzc2lvbklkLCBlQ1NSX0RJU0NPTk5FQ1RfUkVBU09OX0hBTkRPRkYpKSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgImNzclJvYW1IYW5kb2ZmUmVxdWVzdGVkOiAgZmFpbCB0byBpc3N1ZSBkaXNhc3NvY2lhdGUiKTsKICAgICAgICByZXR1cm47CiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAKCiAgICAvL25vdGlmeSBIREQgZm9yIGhhbmRvZmYsIHByb3ZpZGluZyB0aGUgQlNTSUQgdG9vCiAgICByb2FtSW5mby5yZWFzb25Db2RlID0gZUNzclJvYW1SZWFzb25CZXR0ZXJBUDsKCiAgICB2b3NfbWVtX2NvcHkocm9hbUluZm8uYnNzaWQsIAogICAgICAgICAgICAgICAgIGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQsIAogICAgICAgICAgICAgICAgIHNpemVvZiggdENzckJzc2lkICkpOwoKICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgc2Vzc2lvbklkLCAmcm9hbUluZm8sIDAsIGVDU1JfUk9BTV9ST0FNSU5HX1NUQVJULCBlQ1NSX1JPQU1fUkVTVUxUX05PTkUpOwoKCiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jc0hhbmRvZmZJblByb2dyZXNzCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHJldHVybnMgd2hldGhlciBoYW5kb2ZmIGlzIGluIHByb2dyZXNzIG9yIG5vdCBiYXNlZCBvbiAKICAgICAgICAgICAgdGhlIGN1cnJlbnQgbmVpZ2hib3Igcm9hbSBzdGF0ZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgaXMxMXJSZWFzc29jIC0gUmV0dXJuIHdoZXRoZXIgcmVhc3NvYyBpcyBvZiB0eXBlIDgwMi4xMXIgcmVhc3NvYwoKICAgIFxyZXR1cm4gZUFOSV9CT09MRUFOX1RSVUUgaWYgcmVhc3NvYyBpbiBwcm9ncmVzcywgZUFOSV9CT09MRUFOX0ZBTFNFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUlzSGFuZG9mZkluUHJvZ3Jlc3ModHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRUFTU09DSUFUSU5HID09IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICByZXR1cm4gZUFOSV9CT09MRUFOX1RSVUU7CgogICAgcmV0dXJuIGVBTklfQk9PTEVBTl9GQUxTRTsKfQoKI2lmIGRlZmluZWQoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQoV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcpCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1JczExckFzc29jCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHJldHVybnMgd2hldGhlciB0aGUgY3VycmVudCBhc3NvY2lhdGlvbiBpcyBhIDExciBhc3NvYyBvciBub3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRSBpZiBjdXJyZW50IGFzc29jIGlzIDExciwgZUFOSV9CT09MRUFOX0ZBTFNFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUlzMTFyQXNzb2ModHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgcmV0dXJuIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5pczExckFzc29jOwp9CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwoKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1HZXRIYW5kb2ZmQVBJbmZvCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIGJlc3QgcG9zc2libGUgQVAgZm9yIGhhbmRvZmYuIEZvciAxMVIgY2FzZSwgaXQgCiAgICAgICAgICAgIHJldHVybnMgdGhlIDFzdCBlbnRyeSBmcm9tIHByZS1hdXRoIGRvbmUgbGlzdC4gRm9yIG5vbi0xMXIgY2FzZSwgaXQgcmV0dXJucyAKICAgICAgICAgICAgdGhlIDFzdCBlbnRyeSBmcm9tIHJvYW1hYmxlIEFQIGxpc3QKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBIYW5kb2ZmTm9kZSAtIEFQIG5vZGUgdGhhdCBpcyB0aGUgaGFuZG9mZiBjYW5kaWRhdGUgcmV0dXJuZWQKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtR2V0SGFuZG9mZkFQSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjLCB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gcEhhbmRvZmZOb2RlKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICAgICAgcEJzc05vZGU7CiAgICAKICAgIFZPU19BU1NFUlQoTlVMTCAhPSBwSGFuZG9mZk5vZGUpOyAKICAgICAgICAKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpCiAgICB7CiAgICAgICAgLyogQWx3YXlzIHRoZSBCU1MgaW5mbyBpbiB0aGUgaGVhZCBpcyB0aGUgaGFuZG9mZiBjYW5kaWRhdGUgKi8KICAgICAgICBwQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsIE5VTEwpOwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIk51bWJlciBvZiBIYW5kb2ZmIGNhbmRpZGF0ZXMgPSAlZCIpLCBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpKTsKICAgIH0KICAgIGVsc2UKI2VuZGlmCiNpZmRlZiBGRUFUVVJFX1dMQU5fQ0NYCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzQ0NYQXNzb2MpCiAgICB7CiAgICAgICAgLyogQWx3YXlzIHRoZSBCU1MgaW5mbyBpbiB0aGUgaGVhZCBpcyB0aGUgaGFuZG9mZiBjYW5kaWRhdGUgKi8KICAgICAgICBwQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsIE5VTEwpOwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIk51bWJlciBvZiBIYW5kb2ZmIGNhbmRpZGF0ZXMgPSAlZCIpLCBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpKTsKICAgIH0KICAgIGVsc2UKI2VuZGlmCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQpKQogICAgewogICAgICAgIC8qIEFsd2F5cyB0aGUgQlNTIGluZm8gaW4gdGhlIGhlYWQgaXMgdGhlIGhhbmRvZmYgY2FuZGlkYXRlICovCiAgICAgICAgcEJzc05vZGUgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0LCBOVUxMKTsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJOdW1iZXIgb2YgSGFuZG9mZiBjYW5kaWRhdGVzID0gJWQiKSwgY3NyTExDb3VudCgmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KSk7CiAgICB9CiAgICBlbHNlCiNlbmRpZgogICAgewogICAgICAgIHBCc3NOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgTlVMTCk7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksIGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCkpOwogICAgfQogICAgdm9zX21lbV9jb3B5KHBIYW5kb2ZmTm9kZSwgcEJzc05vZGUsIHNpemVvZih0Q3NyTmVpZ2hib3JSb2FtQlNTSW5mbykpOwoKICAgIHJldHVybjsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIHByZWF1dGggaXMgY29tcGxldGVkIAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGJvb2xlYW4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1TdGF0ZVByZWF1dGhEb25lKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHJldHVybiAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlID09IAogICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIEluIHRoZSBldmVudCB0aGF0IHdlIGFyZSBhc3NvY2lhdGVkIHdpdGggQVAxIGFuZCB3ZSBoYXZlCiAgICBjb21wbGV0ZWQgcHJlIGF1dGggd2l0aCBBUDIuIFRoZW4gd2UgcmVjZWl2ZSBhIGRlYXV0aC9kaXNhc3NvYyBmcm9tCiAgICBBUDEuIAogICAgQXQgdGhpcyBwb2ludCBuZWlnaGJvciByb2FtIGlzIGluIHByZSBhdXRoIGRvbmUgc3RhdGUsIHByZSBhdXRoIHRpbWVyCiAgICBpcyBydW5uaW5nLiBXZSBub3cgaGFuZGxlIHRoaXMgY2FzZSBieSBzdG9wcGluZyB0aW1lciBhbmQgY2xlYXJpbmcKICAgIHRoZSBwcmUtYXV0aCBzdGF0ZS4gV2UgYmFzaWNhbGx5IGNsZWFyIHVwIGFuZCBqdXN0IGdvIHRvIGRpc2Nvbm5lY3RlZAogICAgc3RhdGUuIAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGJvb2xlYW4KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1UcmFuaXN0aW9uUHJlYXV0aERvbmVUb0Rpc2Nvbm5lY3RlZCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICBpZiAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlICE9IAogICAgICAgICAgICAgICBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FKSByZXR1cm47CgogICAgLy8gU3RvcCB0aW1lcgogICAgcGFsVGltZXJTdG9wKHBNYWMtPmhIZGQsIHBNYWMtPmZ0LmZ0U21lQ29udGV4dC5wcmVBdXRoUmVhc3NvY0ludHZsVGltZXIpOwoKICAgIC8vIFRyYW5zaXRpb24gdG8gaW5pdCBzdGF0ZQogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCkKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIGJhY2tncm91bmQgc2NhbiB0cmlnZ2VyZWQgYnkKICAgICAgICAgICAgTEZSIGlzIGluIHByb2dyZXNzLgoKICAgIFxwYXJhbSAgaGFsSGFuZGxlIC0gVGhlIGhhbmRsZSBmcm9tIEhERCBjb250ZXh0LgoKICAgIFxyZXR1cm4gYm9vbGVhbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVNjYW5Sc3BQZW5kaW5nICh0SGFsSGFuZGxlIGhIYWwpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVChoSGFsKTsKICAgIHJldHVybiAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIFNUQSBpcyBpbiB0aGUgbWlkZGxlIG9mIHJvYW1pbmcgc3RhdGVzCgogICAgXHBhcmFtICBoYWxIYW5kbGUgLSBUaGUgaGFuZGxlIGZyb20gSEREIGNvbnRleHQuCgogICAgXHJldHVybiBib29sZWFuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JNaWRkbGVPZlJvYW1pbmcgKHRIYWxIYW5kbGUgaEhhbCkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKGhIYWwpOwogICAgdEFOSV9CT09MRUFOIHZhbCA9IChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIRU5USUNBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUgPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOID09IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICByZXR1cm4gKHZhbCk7Cn0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQ2FuZGlkYXRlRm91bmRJbmRIZGxyCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBDU1IgYXMgc29vbiBhcyBUTCBwb3N0cyB0aGUgY2FuZGlkYXRlCiAgICAgICAgICAgIGZvdW5kIGluZGljYXRpb24gdG8gU01FIHZpYSBNQyB0aHJlYWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBNc2cgLSBNc2cgc2VudCBieSBQRQoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUNhbmRpZGF0ZUZvdW5kSW5kSGRscih0cEFuaVNpckdsb2JhbCBwTWFjLCB2b2lkKiBwTXNnKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIC8qIHdlIG11c3QgYmUgaW4gY29ubmVjdGVkIHN0YXRlLCBpZiBub3QgaWdub3JlIGl0ICovCiAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgIHx8IChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBub3QgQ09OTkVDVEVEIHN0YXRlIE9SIHVPc1JlcXVlc3RlZEhhbmRvZmYgaXMgc2V0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLAogICAgICAgICAqIHB1cmdlIG5vbi1QMlAgcmVzdWx0cyBmcm9tIHRoZSBwYXN0ICovCiAgICAgICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0KHBNYWMsIFZPU19GQUxTRSk7CiAgICAgICAgLyogT25jZSBpdCBnZXRzIHRoZSBjYW5kaWRhdGVzIGZvdW5kIGluZGljYXRpb24gZnJvbSBQRSwgd2lsbCBpc3N1ZSBhIHNjYW4KICAgICAgICAgLSByZXEgdG8gUEUgd2l0aCCTZnJlc2hTY2FulCBpbiBzY2FucmVxIHN0cnVjdHVyZSBzZXQgYXMgZm9sbG93czoKICAgICAgICAgMHg0MiAtIFJldHVybiAmIHB1cmdlIExGUiBzY2FuIHJlc3VsdHMKICAgICAgICAqLwogICAgICAgIHN0YXR1cyA9IGNzclNjYW5SZXF1ZXN0TGZyUmVzdWx0KHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtU2NhblJlc3VsdFJlcXVlc3RDYWxsYmFjaywgcE1hYyk7CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByb2Nlc3NIYW5kb2ZmUmVxCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBzdGFydCB3aXRoIHRoZSBoYW5kb2ZmIHByb2Nlc3MuIEZpcnN0IGRvIGEKICAgIFNTSUQgc2NhbiBmb3IgdGhlIEJTU0lEIHByb3ZpZGVkCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByb2Nlc3NIYW5kb2ZmUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdEFOSV9VMzIgcm9hbUlkOwogICAgdENzclJvYW1Qcm9maWxlICpwUHJvZmlsZSA9IE5VTEw7CiAgICB0Q3NyUm9hbVNlc3Npb24gKnBTZXNzaW9uID0gQ1NSX0dFVF9TRVNTSU9OKCBwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkICk7CiAgICB0QU5JX1U4IGkgPSAwOwoKICAgIGRvCiAgICB7CiAgICAgICAgcm9hbUlkID0gR0VUX05FWFRfUk9BTV9JRCgmcE1hYy0+cm9hbSk7CiAgICAgICAgc3RhdHVzID0gcGFsQWxsb2NhdGVNZW1vcnkocE1hYy0+aEhkZCwgKHZvaWQgKiopJnBQcm9maWxlLCBzaXplb2YodENzclJvYW1Qcm9maWxlKSk7CiAgICAgICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2MgZmFpbGVkIikpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgcGFsWmVyb01lbW9yeShwTWFjLT5oSGRkLCBwUHJvZmlsZSwgc2l6ZW9mKHRDc3JSb2FtUHJvZmlsZSkpOwogICAgICAgIHN0YXR1cyA9IGNzclJvYW1Db3B5UHJvZmlsZShwTWFjLCBwUHJvZmlsZSwgcFNlc3Npb24tPnBDdXJSb2FtUHJvZmlsZSk7CiAgICAgICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJQcm9maWxlIGNvcHkgZmFpbGVkIikpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8vQWRkIHRoZSBCU1NJRCAmIENoYW5uZWwKICAgICAgICBwUHJvZmlsZS0+QlNTSURzLm51bU9mQlNTSURzID0gMTsKICAgICAgICBwUHJvZmlsZS0+QlNTSURzLmJzc2lkID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBQcm9maWxlLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwogICAgICAgIGlmIChOVUxMID09IHBQcm9maWxlLT5CU1NJRHMuYnNzaWQpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIm1lbSBhbGxvYyBmYWlsZWQgZm9yIEJTU0lEIikpOwogICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIHZvc19tZW1femVybyhwUHJvZmlsZS0+QlNTSURzLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpICogcFByb2ZpbGUtPkJTU0lEcy5udW1PZkJTU0lEcyk7CgogICAgICAgIC8qIFBvcHVsYXRlIHRoZSBCU1NJRCBmcm9tIGhhbmRvZmYgaW5mbyByZWNlaXZlZCBmcm9tIEhERCAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBwUHJvZmlsZS0+QlNTSURzLm51bU9mQlNTSURzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkoJnBQcm9maWxlLT5CU1NJRHMuYnNzaWRbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgICAgIH0KCiAgICAgICAgcFByb2ZpbGUtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgPSAxOwogICAgICAgIHBQcm9maWxlLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9CiAgICAgICAgICAgIHZvc19tZW1fbWFsbG9jKHNpemVvZigqcFByb2ZpbGUtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KSAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQcm9maWxlLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKTsKICAgICAgICBpZiAoTlVMTCA9PSBwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIm1lbSBhbGxvYyBmYWlsZWQgZm9yIENoYW5uZWxMaXN0IikpOwogICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgcFByb2ZpbGUtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0WzBdID0gcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmNoYW5uZWw7CgogICAgICAgIC8vY2xlYW4gdXAgY3NyIGNhY2hlIGZpcnN0CiAgICAgICAgLy9jc3JTY2FuRmx1c2hTZWxlY3RpdmVSZXN1bHQocE1hYywgVk9TX0ZBTFNFKTsKICAgICAgICAvL2RvIGEgU1NJRCBzY2FuCiAgICAgICAgc3RhdHVzID0gY3NyU2NhbkZvclNTSUQocE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwgcFByb2ZpbGUsIHJvYW1JZCwgRkFMU0UpOwogICAgICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU1NJRCBzY2FuIGZhaWxlZCIpKTsKICAgICAgICB9CiAgICB9d2hpbGUoMCk7CgogICAgaWYoTlVMTCAhPSBwUHJvZmlsZSkKICAgIHsKICAgICAgICBjc3JSZWxlYXNlUHJvZmlsZShwTWFjLCBwUHJvZmlsZSk7CiAgICAgICAgcGFsRnJlZU1lbW9yeShwTWFjLT5oSGRkLCBwUHJvZmlsZSk7CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVNzc2lkU2NhbkRvbmUKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG9uY2UgU1NJRCBzY2FuIGlzIGRvbmUuIElmIFNTSUQgc2NhbiBmYWlsZWQKICAgIHRvIGZpbmQgb3VyIGNhbmRpZGF0ZSBhZGQgYW4gZW50cnkgdG8gY3NyIHNjYW4gY2FjaGUgb3Vyc2VsZiBiZWZvcmUgc3RhcnRpbmcKICAgIHRoZSBoYW5kb2ZmIHByb2Nlc3MKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtU3NzaWRTY2FuRG9uZSh0cEFuaVNpckdsb2JhbCBwTWFjLCBlSGFsU3RhdHVzIHN0YXR1cykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzICAgICAgICAgICAgICAgICAgICAgIGhzdGF0dXM7CgogICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJjYWxsZWQgIikpOwoKICAgIC8qIHdlIG11c3QgYmUgaW4gY29ubmVjdGVkIHN0YXRlLCBpZiBub3QgaWdub3JlIGl0ICovCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCAhPSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBub3QgQ09OTkVDVEVEIHN0YXRlLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CgogICAgLy9pZiBTU0lEIHNjYW4gZmFpbGVkIHRvIGZpbmQgb3VyIGNhbmRpZGF0ZSBhZGQgYW4gZW50cnkgdG8gY3NyIHNjYW4gY2FjaGUgb3Vyc2VsZgogICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhzdGF0dXMpKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQWRkIGFuIGVudHJ5IHRvIGNzciBzY2FuIGNhY2hlIikpOwogICAgICAgIGhzdGF0dXMgPSBjc3JTY2FuQ3JlYXRlRW50cnlJblNjYW5DYWNoZShwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uYnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5jaGFubmVsKTsKICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJjc3JTY2FuQ3JlYXRlRW50cnlJblNjYW5DYWNoZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBOb3cgd2UgaGF2ZSBjb21wbGV0ZWQgc2Nhbm5pbmcgZm9yIHRoZSBjYW5kaWRhdGUgcHJvdmlkZWQgYnkgSERELiBMZXQgbW92ZSBvbiB0byBITyovCiAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZShwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBwcm9jZXNzIGNvbXBsZXRlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSGFuZG9mZlJlcUhkbHIKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IENTUiBhcyBzb29uIGFzIGl0IGdldHMgYSBoYW5kb2ZmIHJlcXVlc3QKICAgICAgICAgICAgdG8gU01FIHZpYSBNQyB0aHJlYWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBNc2cgLSBNc2cgc2VudCBieSBIREQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1IYW5kb2ZmUmVxSGRscih0cEFuaVNpckdsb2JhbCBwTWFjLCB2b2lkKiBwTXNnKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRBbmlIYW5kb2ZmUmVxICAgICAgICAgICAgICAgICAqcEhhbmRvZmZSZXFJbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgLyogd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQgKi8KICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIG5vdCBDT05ORUNURUQgc3RhdGUuIElnbm9yZSBpdCIpKTsKICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8vc2F2ZSB0aGUgaGFuZG9mZiBpbmZvIGNhbWUgZnJvbSBIREQgYXMgcGFydCBvZiB0aGUgcmVhc3NvYyByZXEKICAgICAgICBwSGFuZG9mZlJlcUluZm8gPSAodEFuaUhhbmRvZmZSZXEgKilwTXNnOwogICAgICAgIGlmIChOVUxMICE9IHBIYW5kb2ZmUmVxSW5mbykKICAgICAgICB7CiAgICAgICAgICAgIC8vc2FuaXR5IGNoZWNrCiAgICAgICAgICAgIGlmIChWT1NfRkFMU0UgPT0gdm9zX21lbV9jb21wYXJlKHBIYW5kb2ZmUmVxSW5mby0+YnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyQVBic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpCiAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uY2hhbm5lbCA9IHBIYW5kb2ZmUmVxSW5mby0+Y2hhbm5lbDsKICAgICAgICAgICAgICAgIHZvc19tZW1fY29weShwTmVpZ2hib3JSb2FtSW5mby0+aGFuZG9mZlJlcUluZm8uYnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEhhbmRvZmZSZXFJbmZvLT5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICA2KTsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMTsKICAgICAgICAgICAgICAgIHN0YXR1cyA9IGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9PU19SRVFVRVNURURfUk9BTUlOR19OT1cpOwogICAgICAgICAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiY3NyUm9hbU9mZmxvYWRTY2FuIGZhaWxlZCIpKTsKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIHJlcSBoYXMgc2FtZSBCU1NJRCBhcyBjdXJyZW50IEFQISEiKSk7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgbXNnIGlzIE5VTEwiKSk7CiAgICAgICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Qcm9jZWVkV2l0aEhhbmRvZmZSZXEKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IENTUiBhcyBzb29uIGFzIGl0IGdldHMgcnNwIGJhY2sgZm9yCiAgICAgICAgICAgIFJPQU1fU0NBTl9PRkZMT0FEX1NUT1Agd2l0aCByZWFzb24gUkVBU09OX09TX1JFUVVFU1RFRF9ST0FNSU5HX05PVwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Qcm9jZWVkV2l0aEhhbmRvZmZSZXEodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICB8fCAoIXBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmKSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIG5vdCBDT05ORUNURUQgc3RhdGUgb3IgdU9zUmVxdWVzdGVkSGFuZG9mZiBpcyBub3Qgc2V0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvL0xldCdzIGdvIGFoZWFkIHdpdGggaGFuZG9mZgogICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NIYW5kb2ZmUmVxKHBNYWMpOwogICAgfQogICAgaWYoIUhBTF9TVEFUVVNfU1VDQ0VTUyhzdGF0dXMpKQogICAgewogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgIH0KICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1TdGFydExmclNjYW4KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGlmIEhERCByZXF1ZXN0ZWQgaGFuZG9mZiBmYWlsZWQgZm9yIHNvbWUKICAgIHJlYXNvbi4gc3RhcnQgdGhlIExGUiBsb2dpYyBhdCB0aGF0IHBvaW50LkJ5IHRoZSB0aW1lLCB0aGlzIGZ1bmN0aW9uIGlzCiAgICBjYWxsZWQsIGEgU1RPUCBjb21tYW5kIGhhcyBhbHJlYWR5IGJlZW4gaXNzdWVkLgoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1TdGFydExmclNjYW4odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICAvKiBUaGVyZSBpcyBubyBjYW5kaWRhdGUgb3IgV2UgYXJlIG5vdCByb2FtaW5nIE5vdy4KICAgICAqIEluZm9ybSB0aGUgRlcgdG8gcmVzdGFydCBSb2FtIE9mZmxvYWQgU2NhbiAgKi8KICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwgUkVBU09OX05PX0NBTkRfRk9VTkRfT1JfTk9UX1JPQU1JTkdfTk9XKTsKCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQojZW5kaWYgLy9XTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HICovCg==