LyoKICogQ29weXJpZ2h0IChjKSAyMDEyLTIwMTUgVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFByZXZpb3VzbHkgbGljZW5zZWQgdW5kZXIgdGhlIElTQyBsaWNlbnNlIGJ5IFF1YWxjb21tIEF0aGVyb3MsIEluYy4KICoKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IKICogYW55IHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUKICogYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsCiAqIGNvcGllcy4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTAogKiBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVECiAqIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKICogQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SCiAqIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgovKgogKiBUaGlzIGZpbGUgd2FzIG9yaWdpbmFsbHkgZGlzdHJpYnV0ZWQgYnkgUXVhbGNvbW0gQXRoZXJvcywgSW5jLgogKiB1bmRlciBwcm9wcmlldGFyeSB0ZXJtcyBiZWZvcmUgQ29weXJpZ2h0IG93bmVyc2hpcCB3YXMgYXNzaWduZWQKICogdG8gdGhlIExpbnV4IEZvdW5kYXRpb24uCiAqLwoKLyoqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKiAKICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKiAgCgogIAogICAgXGZpbGUgY3NyTmVpZ2hib3JSb2FtLmMKICAKICAgIEltcGxlbWVudGF0aW9uIGZvciB0aGUgc2ltcGxlIHJvYW1pbmcgYWxnb3JpdGhtIGZvciA4MDIuMTFyIEZhc3QgdHJhbnNpdGlvbnMgYW5kIExlZ2FjeSByb2FtaW5nIGZvciBBbmRyb2lkIHBsYXRmb3JtLgogIAogICAgQ29weXJpZ2h0IChDKSAyMDEwIFF1YWxjb21tLCBJbmNvcnBvcmF0ZWQKICAKIAogICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiAgICAgICAgICAgICAgICAgICAgICBFRElUIEhJU1RPUlkgRk9SIEZJTEUKCgogIFRoaXMgc2VjdGlvbiBjb250YWlucyBjb21tZW50cyBkZXNjcmliaW5nIGNoYW5nZXMgbWFkZSB0byB0aGUgbW9kdWxlLgogIE5vdGljZSB0aGF0IGNoYW5nZXMgYXJlIGxpc3RlZCBpbiByZXZlcnNlIGNocm9ub2xvZ2ljYWwgb3JkZXIuCgoKCiAgd2hlbiAgICAgICAgICAgd2hvICAgICAgICAgICAgICAgICB3aGF0LCB3aGVyZSwgd2h5Ci0tLS0tLS0tLS0gICAgICAgLS0tICAgICAgICAgICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCjA4LzAxLzEwICAgICAgICAgIE11cmFsaSAgICAgICAgICAgICBDcmVhdGVkCgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwojaWZkZWYgV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcKI2luY2x1ZGUgIndsYW5fcWN0X3dkYS5oIgojaW5jbHVkZSAicGFsQXBpLmgiCiNpbmNsdWRlICJjc3JJbnNpZGVBcGkuaCIKI2luY2x1ZGUgInNtc0RlYnVnLmgiCiNpbmNsdWRlICJsb2dEdW1wLmgiCiNpbmNsdWRlICJzbWVRb3NJbnRlcm5hbC5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZUluc2lkZS5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9ldmVudC5oIgojaW5jbHVkZSAidm9zX2RpYWdfY29yZV9sb2cuaCIKI2luY2x1ZGUgImNzckFwaS5oIgojaW5jbHVkZSAid2xhbl9xY3RfdGwuaCIKI2luY2x1ZGUgInNtZV9BcGkuaCIKI2luY2x1ZGUgImNzck5laWdoYm9yUm9hbS5oIgojaW5jbHVkZSAibWFjVHJhY2UuaCIKI2lmIGRlZmluZWQoRkVBVFVSRV9XTEFOX0VTRSkgJiYgIWRlZmluZWQoRkVBVFVSRV9XTEFOX0VTRV9VUExPQUQpCiNpbmNsdWRlICJjc3JFc2UuaCIKI2VuZGlmCgojZGVmaW5lIFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HX0RFQlVHIDEKI2lmZGVmIFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HX0RFQlVHCiNkZWZpbmUgTkVJR0hCT1JfUk9BTV9ERUJVRyBzbXNMb2cKI2Vsc2UKI2RlZmluZSBORUlHSEJPUl9ST0FNX0RFQlVHKHguLi4pCiNlbmRpZgoKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDaGFubmVsSW5mbyh0cENzck5laWdoYm9yUm9hbUNoYW5uZWxJbmZvIHJDaEluZm8pOwpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldENmZ0xpc3RDaGFuU2NhbkNvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpOwpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldFByZWF1dGhDb250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKTsKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbih0cEFuaVNpckdsb2JhbCBwTWFjKTsKClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrICh2X1BWT0lEX3QgcEFkYXB0ZXIsIHZfVThfdCByc3NpTm90aWZpY2F0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdl9QVk9JRF90IHBVc2VyQ3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUzdfdCBhdmdSc3NpKTsKVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLCB2X1U4X3QgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSk7CnZvaWQgY3NyTmVpZ2hib3JSb2FtUlJNTmVpZ2hib3JSZXBvcnRSZXN1bHQodm9pZCAqY29udGV4dCwgVk9TX1NUQVRVUyB2b3NTdGF0dXMpOwplSGFsU3RhdHVzIGNzclJvYW1Db3B5Q29ubmVjdGVkUHJvZmlsZSh0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1UzMiBzZXNzaW9uSWQsIHRDc3JSb2FtUHJvZmlsZSAqcERzdFByb2ZpbGUgKTsKCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEodHBBbmlTaXJHbG9iYWwgcE1hYyk7ClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtSXNzdWVOZWlnaGJvclJwdFJlcXVlc3QodHBBbmlTaXJHbG9iYWwgcE1hYyk7CiNlbmRpZgoKdl9VOF90ICpjc3JOZWlnaGJvclJvYW1TdGF0ZVRvU3RyaW5nKHZfVThfdCBzdGF0ZSkKewogICAgc3dpdGNoKHN0YXRlKQogICAgewogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRCApOwogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU4gKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRUFTU09DSUFUSU5HICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZICk7CiAgICAgICAgQ0FTRV9SRVRVUk5fU1RSSU5HKCBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gKTsKICAgICAgICBDQVNFX1JFVFVSTl9TVFJJTkcoIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIRU5USUNBVElORyApOwogICAgICAgIENBU0VfUkVUVVJOX1NUUklORyggZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORSApOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiAiZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1VOS05PV04iOwogICAgfQoKfQoKLyogU3RhdGUgVHJhbnNpdGlvbiBtYWNybyAqLwojZGVmaW5lIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04obmV3U3RhdGUpXAp7XAogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnByZXZOZWlnaGJvclJvYW1TdGF0ZSA9IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZTtcCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUgPSBuZXdTdGF0ZTtcCiAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfREVCVUcsIFwKICAgICAgICAgICAgICAgRkwoIk5laWdoYm9yIFJvYW0gVHJhbnNpdGlvbiBmcm9tIHN0YXRlICVzID09PiAlcyIpLCBcCiAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVN0YXRlVG9TdHJpbmcgKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5wcmV2TmVpZ2hib3JSb2FtU3RhdGUpLCBcCiAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVN0YXRlVG9TdHJpbmcgKG5ld1N0YXRlKSk7XAp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtRnJlZU5laWdoYm9yUm9hbUJTU05vZGUKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gZnJlZXMgYWxsIHRoZSBpbnRlcm5hbCBwb2ludGVycyBDU1IgTmVpZ2hib3JSb2FtIEJTUyBJbmZvIAogICAgICAgICAgICBhbmQgYWxzbyBmcmVlcyB0aGUgbm9kZSBpdHNlbGYKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIG5laWdoYm9yUm9hbUJTU05vZGUgLSBOZWlnaGJvciBSb2FtIEJTUyBOb2RlIHRvIGJlIGZyZWVkCgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbUZyZWVOZWlnaGJvclJvYW1CU1NOb2RlKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBuZWlnaGJvclJvYW1CU1NOb2RlKQp7CiAgICBpZiAobmVpZ2hib3JSb2FtQlNTTm9kZSkKICAgIHsKICAgICAgICBpZiAobmVpZ2hib3JSb2FtQlNTTm9kZS0+cEJzc0Rlc2NyaXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKG5laWdoYm9yUm9hbUJTU05vZGUtPnBCc3NEZXNjcmlwdGlvbik7CiAgICAgICAgICAgIG5laWdoYm9yUm9hbUJTU05vZGUtPnBCc3NEZXNjcmlwdGlvbiA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIHZvc19tZW1fZnJlZShuZWlnaGJvclJvYW1CU1NOb2RlKTsKICAgICAgICBuZWlnaGJvclJvYW1CU1NOb2RlID0gTlVMTDsKICAgIH0KCiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZW1vdmVSb2FtYWJsZUFQTGlzdEVudHJ5CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHJlbW92ZXMgYSBnaXZlbiBlbnRyeSBmcm9tIHRoZSBnaXZlbiBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwTGlzdCAtIFRoZSBsaXN0IGZyb20gd2hpY2ggdGhlIGVudHJ5IHNob3VsZCBiZSByZW1vdmVkCiAgICAgICAgICAgIHBOZWlnaGJvckVudHJ5IC0gTmVpZ2hib3IgUm9hbSBCU1MgTm9kZSB0byBiZSByZW1vdmVkCgogICAgXHJldHVybiBUUlVFIGlmIHN1Y2Nlc3NmdWxseSByZW1vdmVkLCBlbHNlIEZBTFNFCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtUmVtb3ZlUm9hbWFibGVBUExpc3RFbnRyeSh0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdERibExpbmtMaXN0ICpwTGlzdCwgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBOZWlnaGJvckVudHJ5KQp7CiAgICBpZihwTGlzdCkKICAgIHsKICAgICAgICByZXR1cm4gY3NyTExSZW1vdmVFbnRyeShwTGlzdCwgJnBOZWlnaGJvckVudHJ5LT5MaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CiAgICB9CgogICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZW1vdmluZyBuZWlnaGJvciBCU1Mgbm9kZSBmcm9tIGxpc3QgZmFpbGVkLiBDdXJyZW50IGNvdW50ID0gJWQiKSwgY3NyTExDb3VudChwTGlzdCkpOwoKICAgIHJldHVybiBlQU5JX0JPT0xFQU5fRkFMU0U7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeQoKICAgIFxicmllZiAgR2V0cyB0aGUgZW50cnkgbmV4dCB0byBwYXNzZWQgZW50cnkuIElmIE5VTEwgaXMgcGFzc2VkLCByZXR1cm4gdGhlIGVudHJ5IGluIHRoZSBoZWFkIG9mIHRoZSBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwTGlzdCAtIFRoZSBsaXN0IGZyb20gd2hpY2ggdGhlIGVudHJ5IHNob3VsZCBiZSByZXR1cm5lZAogICAgICAgICAgICBwTmVpZ2hib3JFbnRyeSAtIE5laWdoYm9yIFJvYW0gQlNTIE5vZGUgd2hvc2UgbmV4dCBlbnRyeSBzaG91bGQgYmUgcmV0dXJuZWQKCiAgICBccmV0dXJuIE5laWdoYm9yIFJvYW0gQlNTIE5vZGUgdG8gYmUgcmV0dXJuZWQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeSh0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHREYmxMaW5rTGlzdCAqcExpc3QsIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBwTmVpZ2hib3JFbnRyeSkKewogICAgdExpc3RFbGVtICpwRW50cnkgPSBOVUxMOwogICAgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBSZXN1bHQgPSBOVUxMOwogICAgCiAgICBpZihwTGlzdCkKICAgIHsKICAgICAgICBpZihOVUxMID09IHBOZWlnaGJvckVudHJ5KQogICAgICAgIHsKICAgICAgICAgICAgcEVudHJ5ID0gY3NyTExQZWVrSGVhZChwTGlzdCwgTExfQUNDRVNTX0xPQ0spOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBwRW50cnkgPSBjc3JMTE5leHQocExpc3QsICZwTmVpZ2hib3JFbnRyeS0+TGlzdCwgTExfQUNDRVNTX0xPQ0spOwogICAgICAgIH0KICAgICAgICBpZihwRW50cnkpCiAgICAgICAgewogICAgICAgICAgICBwUmVzdWx0ID0gR0VUX0JBU0VfQUREUihwRW50cnksIHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvLCBMaXN0KTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIHJldHVybiBwUmVzdWx0Owp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdAoKICAgIFxicmllZiAgIEVtcHRpZXMgYW5kIGZyZWVzIGFsbCB0aGUgbm9kZXMgaW4gdGhlIHJvYW1hYmxlIEFQIGxpc3QgCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwTGlzdCAtIE5laWdoYm9yIFJvYW0gQlNTIExpc3QgdG8gYmUgZW1wdGllZAoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsIHREYmxMaW5rTGlzdCAqcExpc3QpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBwUmVzdWx0ID0gTlVMTDsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJFbXB0eWluZyB0aGUgQlNTIGxpc3QuIEN1cnJlbnQgY291bnQgPSAlZCIpLCBjc3JMTENvdW50KHBMaXN0KSk7CgogICAgLyogUGljayB1cCB0aGUgaGVhZCwgcmVtb3ZlIGFuZCBmcmVlIHRoZSBub2RlIHRpbGwgdGhlIGxpc3QgYmVjb21lcyBlbXB0eSAqLwogICAgd2hpbGUgKChwUmVzdWx0ID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgcExpc3QsIE5VTEwpKSAhPSBOVUxMKQogICAgewogICAgICAgIGNzck5laWdoYm9yUm9hbVJlbW92ZVJvYW1hYmxlQVBMaXN0RW50cnkocE1hYywgcExpc3QsIHBSZXN1bHQpOwogICAgICAgIGNzck5laWdoYm9yUm9hbUZyZWVOZWlnaGJvclJvYW1CU1NOb2RlKHBNYWMsIHBSZXN1bHQpOwogICAgfQogICAgcmV0dXJuOwp9CgpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1UcmlnZ2VySGFuZG9mZih0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvKQp7CiAgICBlSGFsU3RhdHVzIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgKQogICAgewogICAgICAgIGlmICgoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkgfHwKICAgICAgICAgICAgKGVTTUVfUk9BTV9UUklHR0VSX0ZBU1RfUk9BTSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSkKICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlUHJlYXV0aFJlcShwTWFjKTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbiA9IGVTTUVfUk9BTV9UUklHR0VSX05PTkU7CiAgICAgICAgICAgIHZvc19tZW1fc2V0KCZwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbWJzc0lkWzBdLAogICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1ic3NJZCksCiAgICAgICAgICAgICAgICAgICAgICAgIDB4RkYpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIjExUiBSZWFzc29jIGluZGljYXRpb24gcmVjZWl2ZWQgaW4iCiAgICAgICAgICAgICAgICAgICAidW5leHBlY3RlZCBzdGF0ZSAlcyIpLAogICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgVk9TX0FTU0VSVCgwKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiNlbmRpZgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgICAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgJiYgIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykKI2VuZGlmCiAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlUHJlYXV0aFJlcShwTWFjKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRVNFIFJlYXNzb2MgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiB1bmV4cGVjdGVkIHN0YXRlICVzIiksCiAgICAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICBWT1NfQVNTRVJUKDApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKI2VuZGlmCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgQ1NSX1NFU1NJT05fSURfSU5WQUxJRCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgICAgfHwgY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSB8fAogICAgICAgICAgICAgICAgKGVTTUVfUk9BTV9UUklHR0VSX0ZBU1RfUk9BTSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKQojZW5kaWYKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZVByZWF1dGhSZXEocE1hYyk7CiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbiA9IGVTTUVfUk9BTV9UUklHR0VSX05PTkU7CiAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9zZXQoJnBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtYnNzSWRbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtYnNzSWQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4RkYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTEZSIFJlYXNzb2MgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiIKICAgICAgICAgICAgICAgICAgICAgICAgICAgInVuZXhwZWN0ZWQgc3RhdGUgJXMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICAgICAgICAgIFZPU19BU1NFUlQoMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQojZW5kaWYKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlcXVlc3RIYW5kb2ZmKHBNYWMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTm9uLTExUiBSZWFzc29jIGluZGljYXRpb24gcmVjZWl2ZWQgaW4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmV4cGVjdGVkIHN0YXRlICVzIG9yIFJvYW1pbmcgaXMgZGlzYWJsZWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CgpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbVVwZGF0ZUZhc3RSb2FtaW5nRW5hYmxlZCh0cEFuaVNpckdsb2JhbCBwTWFjLCBjb25zdCB2X0JPT0xfdCBmYXN0Um9hbUVuYWJsZWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGlmIChWT1NfVFJVRSA9PSBmYXN0Um9hbUVuYWJsZWQpCiAgICAgICAgewojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJSZWdpc3RlcmluZyBuZWlnaGJvciBsb29rdXAgRE9XTiBldmVudCB3aXRoIFRMLCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCk7CiAgICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgRE9XTiBldmVudCBvbmx5ICovCiAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKICAgICAgICAgICAgaWYgKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIiBDb3VsZG4ndCByZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChWT1NfRkFMU0UgPT0gZmFzdFJvYW1FbmFibGVkKQogICAgICAgIHsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiQ3VycmVudGx5IGluIENPTk5FQ1RFRCBzdGF0ZSwgc28gZGVyZWdpc3RlciBhbGwgZXZlbnRzIikpOwogICAgICAgICAgICAvKiBEZS1yZWdpc3RlciBleGlzdGluZyBsb29rdXAgVVAvRE9XTiwgUnNzaSBpbmRpY2F0aW9ucyAqLwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCwgUkVBU09OX0RJU0NPTk5FQ1RFRCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkN1cnJlbnRseSBpbiBJTklUIHN0YXRlLCBOb3RoaW5nIHRvIGRvIikpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwKICAgICAgICBGTCgiVW5leHBlY3RlZCBzdGF0ZSAlcywgcmV0dXJuaW5nIGZhaWx1cmUiKSwKICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtVXBkYXRlRXNlTW9kZUVuYWJsZWQodHBBbmlTaXJHbG9iYWwgcE1hYywgY29uc3Qgdl9CT09MX3QgZXNlTW9kZSkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgaWYgKFZPU19UUlVFID09IGVzZU1vZGUpCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJSZWdpc3RlcmluZyBuZWlnaGJvciBsb29rdXAgRE9XTiBldmVudCB3aXRoIFRMLCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uaXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsIFJFQVNPTl9DT05ORUNUKTsKICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgRE9XTiBldmVudCBvbmx5ICovCiAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKICAgICAgICAgICAgaWYgKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIiBDb3VsZG4ndCByZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChWT1NfRkFMU0UgPT0gZXNlTW9kZSkKICAgICAgICB7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkN1cnJlbnRseSBpbiBDT05ORUNURUQgc3RhdGUsIHNvIGRlcmVnaXN0ZXIgYWxsIGV2ZW50cyIpKTsKICAgICAgICAgICAgLyogRGUtcmVnaXN0ZXIgZXhpc3RpbmcgbG9va3VwIFVQL0RPV04sIFJzc2kgaW5kaWNhdGlvbnMgKi8KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUT1AsIFJFQVNPTl9ESVNDT05ORUNURUQpOwogICAgICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJDdXJyZW50bHkgaW4gSU5JVCBzdGF0ZSwgTm90aGluZyB0byBkbyIpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJVbmV4cGVjdGVkIHN0YXRlICVkLCByZXR1cm5pbmcgZmFpbHVyZSIpLCBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKI2VuZGlmCgoKVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1TZXRMb29rdXBSc3NpVGhyZXNob2xkKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHZfVThfdCBuZWlnaGJvckxvb2t1cFJzc2lUaHJlc2hvbGQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIkN1cnJlbnRseSBpbiBDT05ORUNURUQgc3RhdGUsIHNvIGRlcmVnaXN0ZXIgYWxsIGFuZCByZS1yZWdpc3RlciBmb3IgRE9XTiBldmVudCBhZ2FpbiIpKTsKCiAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IG5laWdoYm9yTG9va3VwUnNzaVRocmVzaG9sZDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZDsKCiAgICAgICAgLyogRGUtcmVnaXN0ZXIgZXhpc3RpbmcgbG9va3VwIFVQL0RPV04sIFJzc2kgaW5kaWNhdGlvbnMgKi8KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZCkKICAgICAgICB7CiAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9VUERBVEVfQ0ZHLCBSRUFTT05fTE9PS1VQX1RIUkVTSF9DSEFOR0VEKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKCiAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICAgIEZMKCJSZWdpc3RlcmluZyBuZWlnaGJvciBsb29rdXAgRE9XTiBldmVudCB3aXRoIFRMLCBSU1NJID0gJWQiKSwKICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKTsKICAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIERPV04gZXZlbnQgb25seSAqLwogICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sCiAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwogICAgICAgICAgIGlmICghVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgewogICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgfQojZW5kaWYKICAgIH0KICAgIGVsc2UgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJDdXJyZW50bHkgaW4gSU5JVCBzdGF0ZSwgc2FmZSB0byBzZXQgbG9va3VwUnNzaSB0aHJlc2hvbGQiKSk7CiAgICAgICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IG5laWdoYm9yTG9va3VwUnNzaVRocmVzaG9sZDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsCiAgICAgICAgRkwoIlVuZXhwZWN0ZWQgc3RhdGUgJXMsIHJldHVybmluZyBmYWlsdXJlIiksCiAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICB9CiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrCgogICAgXGJyaWVmIFJlYXNzb2MgY2FsbGJhY2sgaW52b2tlZCBieSBUTCBvbiBjcm9zc2luZyB0aGUgcmVnaXN0ZXJlZCByZS1hc3NvYyB0aHJlc2hvbGQuCiAgICAgICAgICAgRGlyZWN0bHkgdHJpZ2dlcmUgSE8gaW4gY2FzZSBvZiBub24tMTFyIGFzc29jaWF0aW9uCiAgICAgICAgICAgSW4gY2FzZSBvZiAxMVIgYXNzb2NpYXRpb24sIHRyaWdnZXJzIGEgcHJlLWF1dGggZXZlbnR1YWxseSBmb2xsb3dlZCBieSBhY3R1YWwgSE8KCiAgICBccGFyYW0gIHBBZGFwdGVyIC0gVk9TIENvbnRleHQKICAgICAgICAgICAgdHJhZmZpY1N0YXR1cyAtIFVQL0RPV04gaW5kaWNhdGlvbiBmcm9tIFRMCiAgICAgICAgICAgIHBVc2VyQ3R4dCAtIFBhcmFtZXRlciBmb3IgY2FsbGJhY2sgcmVnaXN0ZXJlZCBkdXJpbmcgY2FsbGJhY2sgcmVnaXN0cmF0aW9uLiBTaG91bGQgYmUgcE1hYwoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1SZWFzc29jSW5kQ2FsbGJhY2sodl9QVk9JRF90IHBBZGFwdGVyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfVThfdCB0cmFmZmljU3RhdHVzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgICBhdmdSc3NpKQp7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gUE1BQ19TVFJVQ1QoIHBVc2VyQ3R4dCApOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBWT1NfU1RBVFVTIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsgICAKCiAgICBpZiAoZVNNRV9ST0FNX1RSSUdHRVJfRkFTVF9ST0FNICE9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtRW4pCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiRGVyZWdpc3RlcmluZyBET1dOIGV2ZW50IHJlYXNzb2MgY2FsbGJhY2sgd2l0aCBUTC4gVGhyZXNob2xkIFJTU0kgPSAlZCBSZXBvcnRlZCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgIGF2Z1Jzc2kpOwoKICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IGRlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgfQoKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJSY3ZkIHJlYXNzb2Mgbm90aWZpY2F0aW9uLWRlcmVnaXN0ZXIgVVAgaW5kaWNhdGlvbi4gVGhyZXNob2xkIFJTU0kgPSAlZCBSZXBvcnRlZCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSksIGF2Z1Jzc2kpOwogICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9EZXJlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX1VQLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKCiAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICB7CiAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2sgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgIH0KICAgIH0KICAgIC8qIFdlIGRvbnQgbmVlZCB0byBydW4gdGhpcyB0aW1lciBhbnkgbW9yZS4gKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKCiAgICBjc3JOZWlnaGJvclJvYW1UcmlnZ2VySGFuZG9mZihwTWFjLCBwTmVpZ2hib3JSb2FtSW5mbyk7CgogICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKfQoKLypDbGVhblVQIFJvdXRpbmVzKi8Kc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDaGFubmVsSW5mbyh0cENzck5laWdoYm9yUm9hbUNoYW5uZWxJbmZvIHJDaEluZm8pCnsKICAgICAgICBpZiAoKHJDaEluZm8tPklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9PSBGQUxTRSkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgKHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscykpCiAgICAgICAgewogICAgICAgICAgICAgICAgckNoSW5mby0+Y3VycmVudENoYW5JbmRleCA9IENTUl9ORUlHSEJPUl9ST0FNX0lOVkFMSURfQ0hBTk5FTF9JTkRFWDsKICAgICAgICAgICAgICAgIHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CgogICAgICAgICAgICAgICAgaWYgKHJDaEluZm8tPmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShyQ2hJbmZvLT5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKCiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgICAgIHJDaEluZm8tPmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgfQogICAgICAgIGVsc2UgCiAgICAgICAgewogICAgICAgICAgICAgICAgckNoSW5mby0+Y3VycmVudENoYW5JbmRleCA9IDA7CiAgICAgICAgICAgICAgICByQ2hJbmZvLT5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgfQp9CgpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldENmZ0xpc3RDaGFuU2NhbkNvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICAgICAgLyogU3RvcCBuZWlnaGJvciBzY2FuIHRpbWVyICovCiAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CgogICAgICAgIC8qIFN0b3AgbmVpZ2hib3Igc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CgogICAgICAgIC8qIFN0b3AgZW1wdHkgc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CgogICAgICAgIC8qIEFib3J0IGFueSBvbmdvaW5nIHNjYW4gKi8KICAgICAgICBpZiAoZUFOSV9CT09MRUFOX1RSVUUgPT0gcE5laWdoYm9yUm9hbUluZm8tPnNjYW5Sc3BQZW5kaW5nKQogICAgICAgIHsKICAgICAgICAgICAgY3NyU2NhbkFib3J0TWFjU2NhbihwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVDU1JfU0NBTl9BQk9SVF9ERUZBVUxUKTsKICAgICAgICB9CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgICAgICAvKiBSZXNldCByb2FtIGNoYW5uZWwgbGlzdCBpbmZvcm1hdGlvbiAqLwogICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q2hhbm5lbEluZm8oJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8pOwp9CgpzdGF0aWMgdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldFByZWF1dGhDb250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICAgICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgLyogUHVyZ2UgcHJlLWF1dGggZmFpbCBsaXN0ICovCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbGVkTGlzdChwTWFjKTsKI2VuZGlmCgogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzID0gMDsKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgLyogRG8gbm90IGZyZWUgdXAgdGhlIHByZWF1dGggZG9uZSBsaXN0IGhlcmUgKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bUJzc0Zyb21OZWlnaGJvclJlcG9ydCA9IDA7CiAgICAgICAgdm9zX21lbV96ZXJvKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvLCBzaXplb2YodENzck5laWdoYm9yUmVwb3J0QnNzSW5mbykgKiBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCk7CiNlbmRpZgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIID0gMDsKICAgIHZvc19tZW1femVybygmcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLCBzaXplb2YodENzckhhbmRvZmZSZXF1ZXN0KSk7CiNlbmRpZgoKfQoKc3RhdGljIHZvaWQgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbih0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICAgICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICAgICAgVk9TX1NUQVRVUyAgICAgICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwoKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJEZXJlZ2lzdGVyIG5laWdoYm9yIGxvb2t1cCBVUCBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSkpOwoKICAgICAgICAvKiBEZXJlZ2lzdGVyIHJlYXNzb2MgY2FsbGJhY2suIElnbm9yZSByZXR1cm4gc3RhdHVzICovCiAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAKICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX1VQLCAKICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVUENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiQ291bGRuJ3QgZGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2sgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIndpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgfQoKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJEZXJlZ2lzdGVyaW5nIHJlYXNzb2MgRE9XTiBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSk7CgogICAgICAgIC8qIERlcmVnaXN0ZXIgcmVhc3NvYyBjYWxsYmFjay4gSWdub3JlIHJldHVybiBzdGF0dXMgKi8KICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsIAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiIENvdWxkbid0IGRlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrIHdpdGggIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgIH0KCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLAogICAgICAgICAgICAgICAgICAgICAgICBGTCgiRGVyZWdpc3RlcmluZyBuZWlnaGJvckxvb2t1cCBET1dOIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSkpOwoKICAgICAgICAvKiBEZXJlZ2lzdGVyIG5laWdoYm9yIGxvb2t1cCBjYWxsYmFjay4gSWdub3JlIHJldHVybiBzdGF0dXMgKi8KICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfRGVyZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsIAogICAgICAgICAgICAgICAgICAgICAgICAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUpOwoKICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoIiBDb3VsZG4ndCBkZXJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgIH0KCiAgICAgICAgLyogUmVzZXQgdGhyZXNob2xkcyBvbmx5IGFmdGVyIGRlcmVnaXN0ZXJpbmcgRE9XTiBldmVudCBmcm9tIFRMICovCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZDsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gMDsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPSBERUZBVUxUX1NDQU47CiNlbmRpZgp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHdpbGwgcmVzZXQgdGhlIG5laWdoYm9yIHJvYW0gY29udHJvbCBpbmZvIGRhdGEgc3RydWN0dXJlcy4gCiAgICAgICAgICAgIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIGludm9rZWQgd2hlbmV2ZXIgd2UgbW92ZSB0byBDT05ORUNURUQgc3RhdGUgZnJvbSAKICAgICAgICAgICAgYW55IHN0YXRlIG90aGVyIHRoYW4gSU5JVCBzdGF0ZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRDb25uZWN0ZWRTdGF0ZUNvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwoKICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q2hhbm5lbEluZm8oJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8pOwogICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKICAgIAogLyogV2UgZG9udCBuZWVkIHRvIHJ1biB0aGlzIHRpbWVyIGFueSBtb3JlLiAqLwogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAvKiBEbyBub3QgZnJlZSB1cCB0aGUgcHJlYXV0aCBkb25lIGxpc3QgaGVyZSAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtUHJlQXV0aFJldHJpZXMgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nID0gMDsKICAgIHZvc19tZW1femVybyhwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgc2l6ZW9mKHRDc3JOZWlnaGJvclJlcG9ydEJzc0luZm8pICogTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOwojZW5kaWYKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCA9IDA7CiAgICB2b3NfbWVtX3plcm8oJnBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mbywgc2l6ZW9mKHRDc3JIYW5kb2ZmUmVxdWVzdCkpOwojZW5kaWYKfQoKdm9pZCBjc3JOZWlnaGJvclJvYW1SZXNldFJlcG9ydFNjYW5TdGF0ZUNvbnRyb2xJbmZvKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCAgICAgICAgICAgID0gICBDU1JfU0VTU0lPTl9JRF9JTlZBTElEOwogICAgdm9zX21lbV9zZXQocE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLCBzaXplb2YodENzckJzc2lkKSwgMCk7CiNpZmRlZiBGRUFUVVJFX1dMQU5fRVNFCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc1ZPQWRtaXR0ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+TWluUUJzc0xvYWRSZXF1aXJlZCA9IDA7CiNlbmRpZgoKICAgIC8qIFN0b3Agc2NhbiByZWZyZXNoIHRpbWVyICovCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICAvKiBTdG9wIGVtcHR5IHNjYW4gcmVzdWx0cyByZWZyZXNoIHRpbWVyICovCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CiAgICAgLyogUHVyZ2Ugcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsgCiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZXNldEluaXRTdGF0ZUNvbnRyb2xJbmZvCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHdpbGwgcmVzZXQgdGhlIG5laWdoYm9yIHJvYW0gY29udHJvbCBpbmZvIGRhdGEgc3RydWN0dXJlcy4gCiAgICAgICAgICAgIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIGludm9rZWQgd2hlbmV2ZXIgd2UgbW92ZSB0byBDT05ORUNURUQgc3RhdGUgZnJvbSAKICAgICAgICAgICAgSU5JVCBzdGF0ZQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUmVzZXRJbml0U3RhdGVDb250cm9sSW5mbyh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8ocE1hYyk7CgogICAgLyogSW4gYWRkaXRpb24gdG8gdGhlIGFib3ZlIHJlc2V0cywgd2Ugc2hvdWxkIGNsZWFyIG9mZiB0aGUgY3VyQVBCc3NJZC9TZXNzaW9uIElEIGluIHRoZSB0aW1lcnMgKi8KICAgIGNzck5laWdoYm9yUm9hbVJlc2V0UmVwb3J0U2NhblN0YXRlQ29udHJvbEluZm8ocE1hYyk7Cn0KCgoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Cc3NJZFNjYW5GaWx0ZXIKCiAgICBcYnJpZWYgIFRoaXMgQVBJIGlzIHVzZWQgdG8gcHJlcGFyZSBhIGZpbHRlciB0byBvYnRhaW4gc2NhbiByZXN1bHRzIHdoZW4gCiAgICAgICAgICAgIHdlIGNvbXBsZXRlIHRoZSBzY2FuIGluIHRoZSBSRVBPUlRfU0NBTiBzdGF0ZSBhZnRlciByZWNlaXZpbmcgYSAKICAgICAgICAgICAgdmFsaWQgbmVpZ2hib3IgcmVwb3J0IGZyb20gQVAuIFRoaXMgZmlsdGVyIGluY2x1ZGVzIEJTU0lEcyByZWNlaXZlZCBmcm9tIAogICAgICAgICAgICB0aGUgbmVpZ2hib3IgcmVwb3J0IGZyb20gdGhlIEFQIGluIGFkZGl0aW9uIHRvIHRoZSBvdGhlciBmaWx0ZXIgcGFyYW1ldGVycyAKICAgICAgICAgICAgY3JlYXRlZCBmcm9tIGNvbm5lY3RlZCBwcm9maWxlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwU2NhbkZpbHRlciAtIFNjYW4gZmlsdGVyIHRvIGJlIGZpbGxlZCBhbmQgcmV0dXJuZWQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzZnVsIGZpbHRlciBjcmVhdGlvbiwgY29ycmVzcG9uZGluZyBlcnJvciAKICAgICAgICAgICAgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUJzc0lkU2NhbkZpbHRlcih0cEFuaVNpckdsb2JhbCBwTWFjLCB0Q3NyU2NhblJlc3VsdEZpbHRlciAqcFNjYW5GaWx0ZXIpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCBpID0gMDsKCiAgICBWT1NfQVNTRVJUKHBTY2FuRmlsdGVyICE9IE5VTEwpOwogICAgaWYgKHBTY2FuRmlsdGVyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB2b3NfbWVtX3plcm8ocFNjYW5GaWx0ZXIsIHNpemVvZih0Q3NyU2NhblJlc3VsdEZpbHRlcikpOwoKICAgIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMgPSBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQ7CiAgICBwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwogICAgaWYgKE5VTEwgPT0gcFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlNjYW4gRmlsdGVyIEJTU0lEIG1lbSBhbGxvYyBmYWlsZWQiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxFRF9BTExPQzsKICAgIH0KCiAgICB2b3NfbWVtX3plcm8ocFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwoKICAgIC8qIFBvcHVsYXRlIHRoZSBCU1NJRCBmcm9tIE5laWdoYm9yIEJTUyBpbmZvIHJlY2VpdmVkIGZyb20gbmVpZ2hib3IgcmVwb3J0ICovCiAgICBmb3IgKGkgPSAwOyBpIDwgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEczsgaSsrKQogICAgewogICAgICAgIHZvc19tZW1fY29weSgmcFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZFtpXSwgCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mb1tpXS5uZWlnaGJvckJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgIH0KCiAgICAvKiBGaWxsIG90aGVyIGdlbmVyYWwgc2NhbiBmaWx0ZXIgcGFyYW1zICovCiAgICByZXR1cm4gY3NyTmVpZ2hib3JSb2FtUHJlcGFyZVNjYW5Qcm9maWxlRmlsdGVyKHBNYWMsIHBTY2FuRmlsdGVyKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVB1cmdlUHJlYXV0aEZhaWxMaXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGVtcHRpZXMgdGhlIHByZWF1dGggZmFpbCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsTGlzdCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJQdXJnaW5nIHRoZSBwcmVhdXRoIGZhaWwgbGlzdCIpKTsKICAgIHdoaWxlIChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcykKICAgIHsKICAgICAgICB2b3NfbWVtX3plcm8ocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm1hY0FkZHJlc3NbcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MtMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzLS07CiAgICB9CiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1BZGRCc3NJZFRvUHJlYXV0aEZhaWxMaXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGFkZHMgdGhlIGdpdmVuIEJTU0lEIHRvIHRoZSBQcmVhdXRoIGZhaWwgbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgYnNzSWQgLSBCU1NJRCB0byBiZSBhZGRlZCB0byB0aGUgcHJlYXV0aCBmYWlsIGxpc3QKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgZUhBTF9TVEFUVVNfRkFJTFVSRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtQWRkQnNzSWRUb1ByZWF1dGhGYWlsTGlzdCh0cEFuaVNpckdsb2JhbCBwTWFjLCB0U2lyTWFjQWRkciBic3NJZCkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiIEFkZGVkIEJTU0lEICJNQUNfQUREUkVTU19TVFIiIHRvIFByZWF1dGggZmFpbGVkIGxpc3QiKSwKICAgICAgICAgICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkoYnNzSWQpKTsKCgogICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcyArIDEpID4KICAgICAgICAgICAgTUFYX05VTV9QUkVBVVRIX0ZBSUxfTElTVF9BRERSRVNTKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUHJlYXV0aCBmYWlsIGxpc3QgYWxyZWFkeSBmdWxsLi4gQ2Fubm90IGFkZCBuZXcgb25lIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5tYWNBZGRyZXNzWwogICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzc10sCiAgICAgICAgICAgICAgICAgYnNzSWQsCiAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRmFpbExpc3QubnVtTUFDQWRkcmVzcysrOwogICAgCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUlzUHJlYXV0aENhbmRpZGF0ZQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBjaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gTUFDIGFkZHJlc3MgaXMgYWxyZWFkeSAKICAgICAgICAgICAgcHJlc2VudCBpbiB0aGUgcHJlYXV0aCBmYWlsIGxpc3QgYW5kIHJldHVybnMgVFJVRS9GQUxTRSBhY2NvcmRpbmdseQoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFIGlmIHByZWF1dGggY2FuZGlkYXRlLCBlQU5JX0JPT0xFQU5fRkFMU0Ugb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtSXNQcmVhdXRoQ2FuZGlkYXRlKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRTaXJNYWNBZGRyIGJzc0lkKQp7CiAgICB0QU5JX1U4IGkgPSAwOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICBpZiAoY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgIHsKICAgICAgICByZXR1cm4gZUFOSV9CT09MRUFOX1RSVUU7CiAgICB9CiNlbmRpZgogICAgaWYgKDAgPT0gcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3MpCiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwogICAgCiAgICBmb3IgKGkgPSAwOyBpIDwgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aEZhaWxMaXN0Lm51bU1BQ0FkZHJlc3M7IGkrKykKICAgIHsKICAgICAgICBpZiAoVk9TX1RSVUUgPT0gdm9zX21lbV9jb21wYXJlKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5tYWNBZGRyZXNzW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBic3NJZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSkpCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJCU1NJRCAiTUFDX0FERFJFU1NfU1RSIiBhbHJlYWR5IHByZXNlbnQgaW4gcHJlYXV0aCBmYWlsIGxpc3QiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkoYnNzSWQpKTsKICAgICAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzc3VlcyBwcmVhdXRoIHJlcXVlc3QgdG8gUEUgd2l0aCB0aGUgMXN0IEFQIGVudHJ5IGluIHRoZSAKICAgICAgICAgICAgcm9hbWFibGUgQVAgbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgZUhBTF9TVEFUVVNfRkFJTFVSRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUlzc3VlUHJlYXV0aFJlcSh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyAgICBwTmVpZ2hib3JCc3NOb2RlOwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgdENzclJvYW1JbmZvICpyb2FtSW5mbzsKI2VuZGlmCiAgICAKICAgIC8qIFRoaXMgbXVzdCBub3QgYmUgdHJ1ZSBoZXJlICovCiAgICBWT1NfQVNTRVJUKHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nID09IGVBTklfQk9PTEVBTl9GQUxTRSk7CgogICAgLyogSXNzdWUgUHJlYXV0aCByZXF1ZXN0IHRvIFBFIGhlcmUgKi8KICAgIC8qIE5lZWQgdG8gaXNzdWUgdGhlIHByZWF1dGggcmVxdWVzdCB3aXRoIHRoZSBCU1NJRCB0aGF0IGlzIHRoZXJlIGluIHRoZSBoZWFkIG9mIHRoZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAvKiBQYXJhbWV0ZXJzIHRoYXQgc2hvdWxkIGJlIHBhc3NlZCBhcmUgQlNTSUQsIENoYW5uZWwgbnVtYmVyIGFuZCB0aGUgbmVpZ2hib3JTY2FuUGVyaW9kKHByb2JhYmx5KSAqLwogICAgLyogSWYgcm9hbWFibGVBUExpc3QgZ2V0cyBlbXB0eSwgc2hvdWxkIHRyYW5zaXRpb24gdG8gUkVQT1JUX1NDQU4gc3RhdGUgKi8KICAgIHBOZWlnaGJvckJzc05vZGUgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCBOVUxMKTsKCiAgICBpZiAoTlVMTCA9PSBwTmVpZ2hib3JCc3NOb2RlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiUm9hbWFibGUgQVAgbGlzdCBpcyBlbXB0eS4uICIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIGVsc2UKICAgIHsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgICAgIC8qIExGUiBtZXRyaWNzIC0gcHJlLWF1dGggaW5pdGlhdGlvbiBtZXRyaWMuCiAgICAgICAgICAgU2VuZCB0aGUgZXZlbnQgdG8gc3VwcGxpY2FudCB0aGF0IHByZS1hdXRoIHdhcyBpbml0aWF0ZWQgKi8KICAgICAgICByb2FtSW5mbyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbUluZm8pKTsKICAgICAgICBpZiAoTlVMTCA9PSByb2FtSW5mbykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkISIpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KCh2b2lkICopcm9hbUluZm8tPmJzc2lkLAogICAgICAgICAgICAgICAgKHZvaWQgKilwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkLAogICAgICAgICAgICAgICAgc2l6ZW9mKHRDc3JCc3NpZCkpOwogICAgICAgICAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9hbUluZm8sIDAsIGVDU1JfUk9BTV9QUkVBVVRIX0lOSVRfTk9USUZZLCAwKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHJvYW1JbmZvKTsKICAgICAgICB9CiNlbmRpZgoKICAgICAgICBzdGF0dXMgPSBjc3JSb2FtRW5xdWV1ZVByZWF1dGgocE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwgcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgZUNzclBlcmZvcm1QcmVhdXRoLCBlQU5JX0JPT0xFQU5fVFJVRSk7CgogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiQmVmb3JlIFByZS1BdXRoOiBCU1NJRCAiTUFDX0FERFJFU1NfU1RSIiwgQ2g6JWQiKSwKICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkocE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCksCiAgICAgICAgICAgICAgIChpbnQpcE5laWdoYm9yQnNzTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsSWQpOwoKICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlNlbmQgUHJlYXV0aCByZXF1ZXN0IHRvIFBFIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBzdGF0dXMpOwogICAgICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgICAgIH0KICAgIH0KICAgIAogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlYXV0aFJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKCiAgICAvKiBJbmNyZW1lbnQgdGhlIHByZWF1dGggcmV0cnkgY291bnQgKi8KICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzKys7CiAgICAKICAgIC8qIFRyYW5zaXRpb24gdGhlIHN0YXRlIHRvIHByZWF1dGhlbnRpY2F0aW5nICovCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIRU5USUNBVElORykKICAgIAogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByZWF1dGhSc3BIYW5kbGVyCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGhhbmRsZSB0aGUgUHJlYXV0aCByZXNwb25zZSBmcm9tIFBFCiAgICAgICAgICAgIEV2ZXJ5IHByZWF1dGggaXMgYWxsb3dlZCBtYXggMyB0cmllcyBpZiBpdCBmYWlscy4gSWYgYSBic3NpZCBmYWlsZWQgCiAgICAgICAgICAgIGZvciBtb3JlIHRoYW4gTUFYX1RSSUVTLCB3ZSB3aWxsIHJlbW92ZSBpdCBmcm9tIHRoZSBsaXN0IGFuZCB0cnkgCiAgICAgICAgICAgIHdpdGggdGhlIG5leHQgbm9kZSBpbiB0aGUgcm9hbWFibGUgQVAgbGlzdCBhbmQgYWRkIHRoZSBCU1NJRCB0byBwcmUtYXV0aCBmYWlsZWQgCiAgICAgICAgICAgIGxpc3QuIElmIG5vIG1vcmUgZW50cmllcyBwcmVzZW50IGluIAogICAgICAgICAgICByb2FtYWJsZSBBUCBsaXN0LCB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBsaW1TdGF0dXMgLSBlU0lSX1NVQ0NFU1MvZVNJUl9GQUlMVVJFL2VTSVJfTElNX01BWF9TVEFfUkVBQ0hFRF9FUlJPUi8KICAgICAgICAgICAgICAgICAgICAgZVNJVF9MSU1fQVVUSF9SU1BfVElNRU9VVCBzdGF0dXMgZnJvbSBQRQoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzIChpLmUuIHByZS1hdXRoIHByb2Nlc3NlZCksCiAgICAgICAgICAgIGVIQUxfU1RBVFVTX0ZBSUxVUkUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByZWF1dGhSc3BIYW5kbGVyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRTaXJSZXRTdGF0dXMgbGltU3RhdHVzKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICBWT1NfU1RBVFVTICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICBlSGFsU3RhdHVzICBwcmVhdXRoUHJvY2Vzc2VkID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQlNTSW5mbyBwUHJlYXV0aFJzcE5vZGUgPSBOVUxMOwogICAgdENzclJvYW1TZXNzaW9uICpwU2Vzc2lvbjsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgdENzclJvYW1JbmZvICpyb2FtSW5mbzsKI2VuZGlmCgogICAgaWYgKGVBTklfQk9PTEVBTl9GQUxTRSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVhdXRoUnNwUGVuZGluZykKICAgIHsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIGRpc2Nvbm5lY3QgaW1tZWRpYXRlbHkKICAgICAgICAgICAgICogYWZ0ZXIgc2VuZGluZyBhIHByZS1hdXRoIHJlcXVlc3QuIER1cmluZyBwcm9jZXNzaW5nCiAgICAgICAgICAgICAqIG9mIHRoZSBkaXNjb25uZWN0IGNvbW1hbmQsIHdlIHdvdWxkIGhhdmUgcmVzZXQKICAgICAgICAgICAgICogcHJlYXV0aFJzcFBlbmRpbmcgYW5kIHRyYW5zaXRpb25lZCB0byBJTklUIHN0YXRlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJVbmV4cGVjdGVkIHByZS1hdXRoIHJlc3BvbnNlIGluIHN0YXRlICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKTsKICAgICAgICAgICAgcHJlYXV0aFByb2Nlc3NlZCA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIGdvdG8gREVRX1BSRUFVVEg7CiAgICB9ICAgIAoKICAgIC8vIFdlIGNhbiByZWNlaXZlIGl0IGluIHRoZXNlIDIgc3RhdGVzLgogICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhFTlRJQ0FUSU5HKSAmJgogICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOKSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csCiAgICAgICAgRkwoIlByZWF1dGggcmVzcG9uc2UgcmVjZWl2ZWQgaW4gc3RhdGUgJXMiKSwKICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICBwcmVhdXRoUHJvY2Vzc2VkID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICBnb3RvIERFUV9QUkVBVVRIOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZWF1dGhSc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIGlmIChlU0lSX1NVQ0NFU1MgPT0gbGltU3RhdHVzKQogICAgewogICAgICAgIHBQcmVhdXRoUnNwTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QsIE5VTEwpOwogICAgfQogICAgaWYgKChlU0lSX1NVQ0NFU1MgPT0gbGltU3RhdHVzKSAmJiAoTlVMTCAhPSBwUHJlYXV0aFJzcE5vZGUpKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIlByZWF1dGggY29tcGxldGVkIHN1Y2Nlc3NmdWxseSBhZnRlciAlZCB0cmllcyIpLCBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyk7CgogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiQWZ0ZXIgUHJlLUF1dGg6IEJTU0lEICJNQUNfQUREUkVTU19TVFIiLCBDaDolZCIpLAogICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwUHJlYXV0aFJzcE5vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQpLAogICAgICAgICAgICAgICAoaW50KXBQcmVhdXRoUnNwTm9kZS0+cEJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsSWQpOwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgICAgIC8qIExGUiBtZXRyaWNzIC0gcHJlLWF1dGggY29tcGxldGlvbiBtZXRyaWMuCiAgICAgICAgICAgU2VuZCB0aGUgZXZlbnQgdG8gc3VwcGxpY2FudCB0aGF0IHByZS1hdXRoIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgKi8KICAgICAgICByb2FtSW5mbyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbUluZm8pKTsKICAgICAgICBpZiAoTlVMTCA9PSByb2FtSW5mbykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkISIpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KCh2b2lkICopcm9hbUluZm8tPmJzc2lkLAogICAgICAgICAgICAgICAgKHZvaWQgKilwUHJlYXV0aFJzcE5vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQsCiAgICAgICAgICAgICAgICBzaXplb2YodENzckJzc2lkKSk7CiAgICAgICAgICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwKICAgICAgICAgICAgICAgIHJvYW1JbmZvLCAwLCBlQ1NSX1JPQU1fUFJFQVVUSF9TVEFUVVNfU1VDQ0VTUywgMCk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShyb2FtSW5mbyk7CiAgICAgICAgfQojZW5kaWYKCiAgICAgICAgLyogUHJlYXV0aCBjb21wZXRlciBzdWNjZXNzZnVsbHkuIEluc2VydCB0aGUgcHJlYXV0aGVudGljYXRlZCBub2RlIHRvIHRhaWwgb2YgcHJlQXV0aERvbmVMaXN0ICovCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVtb3ZlUm9hbWFibGVBUExpc3RFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCBwUHJlYXV0aFJzcE5vZGUpOwogICAgICAgIGNzckxMSW5zZXJ0VGFpbCgmcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0LCAmcFByZWF1dGhSc3BOb2RlLT5MaXN0LCBMTF9BQ0NFU1NfTE9DSyk7CgogICAgICAgIC8qIFByZS1hdXRoIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkuIFRyYW5zaXRpb24gdG8gUFJFQVVUSCBEb25lIHN0YXRlICovCiAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUFJFQVVUSF9ET05FKQogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzID0gMDsKCiAgICAgICAgLyogVGhlIGNhbGxlciBvZiB0aGlzIGZ1bmN0aW9uIHdvdWxkIHN0YXJ0IGEgdGltZXIgYW5kIGJ5IHRoZSB0aW1lIGl0IGV4cGlyZXMsIHN1cHBsaWNhbnQgc2hvdWxkIAogICAgICAgICAgIGhhdmUgcHJvdmlkZWQgdGhlIHVwZGF0ZWQgRlRJRXMgdG8gU01FLiBTbywgd2hlbiBpdCBleHBpcmVzLCBoYW5kb2ZmIHdpbGwgYmUgdHJpZ2dlcmVkIHRoZW4gKi8KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gICAgcE5laWdoYm9yQnNzTm9kZSA9IE5VTEw7CiAgICAgICAgdExpc3RFbGVtICAgICAgICAgICAgICAgICAgICpwRW50cnk7CgogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUHJlYXV0aCBmYWlsZWQgcmV0cnkgbnVtYmVyICVkLCBzdGF0dXMgPSAweCV4IiksCiAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm51bVByZUF1dGhSZXRyaWVzLCBsaW1TdGF0dXMpOwogICAgICAgIAogICAgICAgIC8qIFByZWF1dGggZmFpbGVkLiBBZGQgdGhlIGJzc0lkIHRvIHRoZSBwcmVBdXRoIGZhaWxlZCBsaXN0IE1BQyBBZGRyZXNzLiBBbHNvIHJlbW92ZSB0aGUgQVAgZnJvbSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA+PQogICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fTUFYX05VTV9QUkVBVVRIX1JFVFJJRVMpIHx8CiAgICAgICAgICAgIChlU0lSX0xJTV9NQVhfU1RBX1JFQUNIRURfRVJST1IgPT0gbGltU3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIFdlIGFyZSBnb2luZyB0byByZW1vdmUgdGhlIG5vZGUgYXMgaXQgZmFpbHMgZm9yIG1vcmUgdGhhbiBNQVggdHJpZXMuIFJlc2V0IHRoaXMgY291bnQgdG8gMCAqLwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1QcmVBdXRoUmV0cmllcyA9IDA7CgogICAgICAgICAgICAvKiBUaGUgb25lIGluIHRoZSBoZWFkIG9mIHRoZSBsaXN0IHNob3VsZCBiZSBvbmUgd2l0aCB3aGljaCB3ZSBpc3N1ZWQgcHJlLWF1dGggYW5kIGZhaWxlZCAqLwogICAgICAgICAgICBwRW50cnkgPSBjc3JMTFJlbW92ZUhlYWQoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCwgTExfQUNDRVNTX0xPQ0spOwogICAgICAgICAgICBpZihwRW50cnkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHBOZWlnaGJvckJzc05vZGUgPSBHRVRfQkFTRV9BRERSKHBFbnRyeSwgdENzck5laWdoYm9yUm9hbUJTU0luZm8sIExpc3QpOwogICAgICAgICAgICAgICAgLyogQWRkIHRoZSBCU1NJRCB0byBwcmUtYXV0aCBmYWlsIGxpc3QgaWYgaXQgaXMgbm90IHJlcXVlc3RlZCBieSBIREQgKi8KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgICAgaWYoIXBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmKQojZW5kaWYKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtQWRkQnNzSWRUb1ByZWF1dGhGYWlsTGlzdChwTWFjLCBwTmVpZ2hib3JCc3NOb2RlLT5wQnNzRGVzY3JpcHRpb24tPmJzc0lkKTsKICAgICAgICAgICAgICAgIH0KCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSX01FVFJJQ1MKICAgICAgICAgICAgICAgIC8qIExGUiBtZXRyaWNzIC0gcHJlLWF1dGggY29tcGxldGlvbiBtZXRyaWMuIFNlbmQgdGhlIGV2ZW50CiAgICAgICAgICAgICAgICAgICB0byBzdXBwbGljYW50IHRoYXQgcHJlLWF1dGggc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZCAqLwogICAgICAgICAgICAgICAgcm9hbUluZm8gPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodENzclJvYW1JbmZvKSk7CiAgICAgICAgICAgICAgICBpZiAoTlVMTCA9PSByb2FtSW5mbykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZCEiKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9jb3B5KCh2b2lkICopcm9hbUluZm8tPmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKXBOZWlnaGJvckJzc05vZGUtPnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0Q3NyQnNzaWQpKTsKICAgICAgICAgICAgICAgICAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgIHJvYW1JbmZvLCAwLCBlQ1NSX1JPQU1fUFJFQVVUSF9TVEFUVVNfRkFJTFVSRSwgMCk7CiAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHJvYW1JbmZvKTsKICAgICAgICAgICAgICAgIH0KI2VuZGlmCgogICAgICAgICAgICAvKiBOb3cgd2UgY2FuIGZyZWUgdGhpcyBub2RlICovCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUZyZWVOZWlnaGJvclJvYW1CU1NOb2RlKHBNYWMsIHBOZWlnaGJvckJzc05vZGUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHBTZXNzaW9uID0gQ1NSX0dFVF9TRVNTSU9OKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQpOwogICAgICAgIGlmICgoTlVMTCAhPSBwU2Vzc2lvbikgJiYgcFNlc3Npb24tPmFib3J0Q29ubmVjdGlvbikKICAgICAgICB7CiAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCIgRGVhdXRoIGluIHByb2dyZXNzIEFib3J0IHByZWF1dGgiKSk7CiAgICAgICAgICAgZ290byBhYm9ydF9wcmVhdXRoOwogICAgICAgIH0KCiAgICAgICAgLyogSXNzdWUgcHJlYXV0aCByZXF1ZXN0IGZvciB0aGUgc2FtZS9uZXh0IGVudHJ5ICovCiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgPT0gY3NyTmVpZ2hib3JSb2FtSXNzdWVQcmVhdXRoUmVxKHBNYWMpKQogICAgICAgIGdvdG8gREVRX1BSRUFVVEg7IAoKYWJvcnRfcHJlYXV0aDoKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmIChjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgIHsKICAgICAgICAgIGlmKHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmKQogICAgICAgICAgewogICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgICAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fUFJFQVVUSF9GQUlMRURfRk9SX0FMTCk7CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIGlmKHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0gpCiAgICAgICAgICB7CiAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIID0gMDsKICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRm9yY2VkIDVHIHJvYW1pbmcgcHJlYXV0aCBnb3QgZmFpbGVkIgogICAgICAgICAgICAgICAgICAgICJzZW5kIFJTTyBTVEFSVCBjbWQgdG8gZndyLiIpKTsKICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULFJFQVNPTl9DT05ORUNUKTsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UKICAgICAgICAgIHsKICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9SRVNUQVJULCBSRUFTT05fUFJFQVVUSF9GQUlMRURfRk9SX0FMTCk7CiAgICAgICAgICB9CiAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpOwogICAgICAgIH0gZWxzZQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTik7CgogICAgICAgICAgLyogUmVnaXN0ZXIgTmVpZ2hib3IgTG9va3VwIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMIGZvciBVUCBldmVudCBub3cgKi8KICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIk5vIG1vcmUgcHJlLWF1dGggY2FuZGlkYXRlcy0iCiAgICAgICAgICAgICAgICAgICJyZWdpc3RlciBVUCBpbmRpY2F0aW9uIHdpdGggVEwuIFJTU0kgPSAlZCwiKSwgTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSk7CgogICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClORUlHSEJPUl9ST0FNX0xPT0tVUF9VUF9USFJFU0hPTEQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX1VQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgIHsKICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIiBDb3VsZG4ndCByZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cENhbGxiYWNrIFVQIGV2ZW50IHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHN0YXR1cyk7CiAgICAgICAgICB9CgogICAgICAgICAgLyogU3RhcnQgdGhlIG5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBhbmQgdHJhbnNpdGlvbiB0byBSRVBPUlRfU0NBTiBzdGF0ZSB0byBwZXJmb3JtIHNjYW4gYWdhaW4gKi8KICAgICAgICAgIHN0YXR1cyA9IHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lciwKICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2QpOwogICAgICAgICAgaWYgKCBzdGF0dXMgIT0gZUhBTF9TVEFUVVNfU1VDQ0VTUyApCiAgICAgICAgICB7CiAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlc3VsdHMgcmVmcmVzaCB0aW1lciBzdGFydCBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgc3RhdHVzKTsKICAgICAgICAgIH0KICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgIH0KI2VuZGlmCgpERVFfUFJFQVVUSDoKICAgIGNzclJvYW1EZXF1ZXVlUHJlYXV0aChwTWFjKTsKICAgIHJldHVybiBwcmVhdXRoUHJvY2Vzc2VkOwp9CiNlbmRpZiAgLyogV0xBTl9GRUFUVVJFX05FSUdIQk9SX1JPQU1JTkcgKi8KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QcmVwYXJlU2NhblByb2ZpbGVGaWx0ZXIKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyBhIHNjYW4gZmlsdGVyIGJhc2VkIG9uIHRoZSBjdXJyZW50bHkgY29ubmVjdGVkIHByb2ZpbGUuCiAgICAgICAgICAgIEJhc2VkIG9uIHRoaXMgZmlsdGVyLCBzY2FuIHJlc3VsdHMgYXJlIG9idGFpbmVkCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwU2NhbkZpbHRlciAtIFBvcHVsYXRlZCBzY2FuIGZpbHRlciBiYXNlZCBvbiB0aGUgY29ubmVjdGVkIHByb2ZpbGUKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgZUhBTF9TVEFUVVNfRkFJTFVSRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtUHJlcGFyZVNjYW5Qcm9maWxlRmlsdGVyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRDc3JTY2FuUmVzdWx0RmlsdGVyICpwU2NhbkZpbHRlcikKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0QU5JX1U4IHNlc3Npb25JZCAgID0gKHRBTklfVTgpcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZDsKICAgIHRDc3JSb2FtQ29ubmVjdGVkUHJvZmlsZSAqcEN1clByb2ZpbGUgPSAmcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGU7CiAgICB0QU5JX1U4IGkgPSAwOwogICAgCiAgICBWT1NfQVNTRVJUKHBTY2FuRmlsdGVyICE9IE5VTEwpOwogICAgaWYgKHBTY2FuRmlsdGVyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CgogICAgdm9zX21lbV96ZXJvKHBTY2FuRmlsdGVyLCBzaXplb2YodENzclNjYW5SZXN1bHRGaWx0ZXIpKTsKCiAgICAvKiBXZSBkb250IHdhbnQgdG8gc2V0IEJTU0lEIGJhc2VkIEZpbHRlciAqLwogICAgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyA9IDA7CgogICAgLy9vbmx5IGZvciBIREQgcmVxdWVzdGVkIGhhbmRvZmYgZmlsbCBpbiB0aGUgQlNTSUQgaW4gdGhlIGZpbHRlcgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpCiAgICB7CiAgICAgICAgcFNjYW5GaWx0ZXItPkJTU0lEcy5udW1PZkJTU0lEcyA9IDE7CiAgICAgICAgcFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0U2lyTWFjQWRkcikgKiBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzKTsKICAgICAgICBpZiAoTlVMTCA9PSBwU2NhbkZpbHRlci0+QlNTSURzLmJzc2lkKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJTY2FuIEZpbHRlciBCU1NJRCBtZW0gYWxsb2MgZmFpbGVkIikpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTEVEX0FMTE9DOwogICAgICAgIH0KCiAgICAgICAgdm9zX21lbV96ZXJvKHBTY2FuRmlsdGVyLT5CU1NJRHMuYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikgKiBwU2NhbkZpbHRlci0+QlNTSURzLm51bU9mQlNTSURzKTsKCiAgICAgICAgLyogUG9wdWxhdGUgdGhlIEJTU0lEIGZyb20gaGFuZG9mZiBpbmZvIHJlY2VpdmVkIGZyb20gSEREICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IHBTY2FuRmlsdGVyLT5CU1NJRHMubnVtT2ZCU1NJRHM7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fY29weSgmcFNjYW5GaWx0ZXItPkJTU0lEcy5ic3NpZFtpXSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5ic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICAgICAgfQogICAgfQojZW5kaWYKICAgIC8qIFBvcHVsYXRlIGFsbCB0aGUgaW5mb3JtYXRpb24gZnJvbSB0aGUgY29ubmVjdGVkIHByb2ZpbGUgKi8KICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5udW1PZlNTSURzID0gMTsgIAogICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0ID0gdm9zX21lbV9tYWxsb2Moc2l6ZW9mKHRDc3JTU0lESW5mbykpOwogICAgaWYgKE5VTEwgPT0gcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0KQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgU1NJRCBtZW0gYWxsb2MgZmFpbGVkIikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMRURfQUxMT0M7CiAgICB9CiAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPmhhbmRvZmZQZXJtaXR0ZWQgPSAxOwogICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5zc2lkSGlkZGVuID0gMDsKICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdC0+U1NJRC5sZW5ndGggPSAgcEN1clByb2ZpbGUtPlNTSUQubGVuZ3RoOwogICAgdm9zX21lbV9jb3B5KCh2b2lkICopcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELnNzSWQsICh2b2lkICopcEN1clByb2ZpbGUtPlNTSUQuc3NJZCwgcEN1clByb2ZpbGUtPlNTSUQubGVuZ3RoKTsgCgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiRmlsdGVyaW5nIGZvciBTU0lEICUuKnMgZnJvbSBzY2FuIHJlc3VsdHMsIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJsZW5ndGggb2YgU1NJRCA9ICV1IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0LT5TU0lELmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQuc3NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU2NhbkZpbHRlci0+U1NJRHMuU1NJRExpc3QtPlNTSUQubGVuZ3RoKTsKICAgIHBTY2FuRmlsdGVyLT5hdXRoVHlwZS5udW1FbnRyaWVzID0gMTsKICAgIHBTY2FuRmlsdGVyLT5hdXRoVHlwZS5hdXRoVHlwZVswXSA9IHBDdXJQcm9maWxlLT5BdXRoVHlwZTsKCiAgICBwU2NhbkZpbHRlci0+RW5jcnlwdGlvblR5cGUubnVtRW50cmllcyA9IDE7IC8vVGhpcyBtdXN0IGJlIDEKICAgIHBTY2FuRmlsdGVyLT5FbmNyeXB0aW9uVHlwZS5lbmNyeXB0aW9uVHlwZVswXSA9IHBDdXJQcm9maWxlLT5FbmNyeXB0aW9uVHlwZTsKCiAgICBwU2NhbkZpbHRlci0+bWNFbmNyeXB0aW9uVHlwZS5udW1FbnRyaWVzID0gMTsKICAgIHBTY2FuRmlsdGVyLT5tY0VuY3J5cHRpb25UeXBlLmVuY3J5cHRpb25UeXBlWzBdID0gcEN1clByb2ZpbGUtPm1jRW5jcnlwdGlvblR5cGU7CgogICAgcFNjYW5GaWx0ZXItPkJTU1R5cGUgPSBwQ3VyUHJvZmlsZS0+QlNTVHlwZTsKCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICB7CiAgICAgICAvKiBXZSBhcmUgaW50cmVzdGVkIG9ubHkgaW4gdGhlIHNjYW4gcmVzdWx0cyBvbiBjaGFubmVscyB0aGF0IHdlIHNjYW5uZWQgICovCiAgICAgICBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyA9CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHM7CiAgICAgICBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPQogICAgICAgIHZvc19tZW1fbWFsbG9jKHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgIGlmIChOVUxMID09IHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdCkKICAgICAgIHsKICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU2NhbiBGaWx0ZXIgQ2hhbm5lbCBsaXN0IG1lbSBhbGxvYyBmYWlsZWQiKSk7CiAgICAgICAgICB2b3NfbWVtX2ZyZWUocFNjYW5GaWx0ZXItPlNTSURzLlNTSURMaXN0KTsKICAgICAgICAgIHBTY2FuRmlsdGVyLT5TU0lEcy5TU0lETGlzdCA9IE5VTEw7CiAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTEVEX0FMTE9DOwogICAgICAgfQogICAgICAgZm9yIChpID0gMDsgaSA8IHBTY2FuRmlsdGVyLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzOyBpKyspCiAgICAgICB7CiAgICAgICAgICBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbaV0gPQogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbaV07CiAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICBwU2NhbkZpbHRlci0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykKICAgIHsKICAgICAgICAvKiBNRElFIHNob3VsZCBiZSBhZGRlZCBhcyBhIHBhcnQgb2YgcHJvZmlsZS4gVGhpcyBzaG91bGQgYmUgYWRkZWQgYXMgYSBwYXJ0IG9mIGZpbHRlciBhcyB3ZWxsICAqLwogICAgICAgIHBTY2FuRmlsdGVyLT5NRElELm1kaWVQcmVzZW50ID0gcEN1clByb2ZpbGUtPk1ESUQubWRpZVByZXNlbnQ7CiAgICAgICAgcFNjYW5GaWx0ZXItPk1ESUQubW9iaWxpdHlEb21haW4gPSBwQ3VyUHJvZmlsZS0+TURJRC5tb2JpbGl0eURvbWFpbjsKICAgIH0KI2VuZGlmCgojaWZkZWYgV0xBTl9GRUFUVVJFXzExVwogICAgcFNjYW5GaWx0ZXItPk1GUEVuYWJsZWQgPSBwQ3VyUHJvZmlsZS0+TUZQRW5hYmxlZDsKICAgIHBTY2FuRmlsdGVyLT5NRlBSZXF1aXJlZCA9IHBDdXJQcm9maWxlLT5NRlBSZXF1aXJlZDsKICAgIHBTY2FuRmlsdGVyLT5NRlBDYXBhYmxlID0gcEN1clByb2ZpbGUtPk1GUENhcGFibGU7CiNlbmRpZgoKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9Cgp0QU5JX1UzMiBjc3JHZXRDdXJyZW50QVBSc3NpKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRTY2FuUmVzdWx0SGFuZGxlICpwU2NhblJlc3VsdExpc3QpCnsKICAgICAgICB0Q3NyU2NhblJlc3VsdEluZm8gKnBTY2FuUmVzdWx0OwogICAgICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIHRBTklfVTMyIEN1cnJBUFJzc2kgPSBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2k7CiNlbHNlCiAgICAgICAgLyogV2UgYXJlIHNldHRpbmcgdGhpcyBhcyBkZWZhdWx0IHZhbHVlIHRvIG1ha2Ugc3VyZSB3ZSByZXR1cm4gdGhpcyB2YWx1ZSwKICAgICAgICB3aGVuIHdlIGRvIG5vdCBzZWUgdGhpcyBBUCBpbiB0aGUgc2NhbiByZXN1bHQgZm9yIHNvbWUgcmVhc29uLkhvd2V2ZXIsaXQgaXMKICAgICAgICBsZXNzIGxpa2VseSB0aGF0IHdlIGFyZSBhc3NvY2lhdGVkIHRvIGFuIEFQIGFuZCBkbyBub3Qgc2VlIGl0IGluIHRoZSBzY2FuIGxpc3QgKi8KICAgICAgICB0QU5JX1UzMiBDdXJyQVBSc3NpID0gLTEyNTsKI2VuZGlmCgogICAgICAgIHdoaWxlIChOVUxMICE9IChwU2NhblJlc3VsdCA9IGNzclNjYW5SZXN1bHRHZXROZXh0KHBNYWMsICpwU2NhblJlc3VsdExpc3QpKSkKICAgICAgICB7CgogICAgICAgICAgICAgICAgaWYgKFZPU19UUlVFID09IHZvc19tZW1fY29tcGFyZShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogV2UgZ290IGEgbWF0Y2ggd2l0aCB0aGUgY3VycmVudGx5IGFzc29jaWF0ZWQgQVAuCiAgICAgICAgICAgICAgICAgICAgICAgICAqIENhcHR1cmUgdGhlIFJTU0kgdmFsdWUgYW5kIGNvbXBsZXRlIHRoZSB3aGlsZSBsb29wLgogICAgICAgICAgICAgICAgICAgICAgICAgKiBUaGUgd2hpbGUgbG9vcCBpcyBjb21wbGV0ZWQgaW4gb3JkZXIgdG8gbWFrZSB0aGUgY3VycmVudCBlbnRyeSBnbyBiYWNrIHRvIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAqIGFuZCBpbiB0aGUgbmV4dCB3aGlsZSBsb29wLCBpdCBwcm9wZXJseSBzdGFydHMgc2VhcmNoaW5nIGZyb20gdGhlIGhlYWQgb2YgdGhlIGxpc3QuCiAgICAgICAgICAgICAgICAgICAgICAgICAqIFRPRE86IENhbiBhbHNvIHRyeSBzZXR0aW5nIHRoZSBjdXJyZW50IGVudHJ5IGRpcmVjdGx5IHRvIE5VTEwgYXMgc29vbiBhcyB3ZSBmaW5kIHRoZSBuZXcgQVAqLwoKICAgICAgICAgICAgICAgICAgICAgICAgIEN1cnJBUFJzc2kgPSAoaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kgKiAoLTEpIDsKCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBDdXJyQVBSc3NpOwoKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuUmVzdWx0cwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBleHRyYWN0cyBzY2FuIHJlc3VsdHMsIHNvcnRzIG9uIHRoZSBiYXNpcyBvZiBuZWlnaGJvciBzY29yZSh0b2RvKS4gCiAgICAgICAgICAgIEFzc3VtZWQgdGhhdCB0aGUgcmVzdWx0cyBhcmUgYWxyZWFkeSBzb3J0ZWQgYnkgUlNTSSBieSBjc3JTY2FuR2V0UmVzdWx0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwU2NhblJlc3VsdExpc3QgLSBTY2FuIHJlc3VsdCByZXN1bHQgb2J0YWluZWQgZnJvbSBjc3JTY2FuR2V0UmVzdWx0KCkKCiAgICBccmV0dXJuIHRBTklfQk9PTEVBTiAtIHJldHVybiBUUlVFIGlmIHdlIGhhdmUgYSBjYW5kaWRhdGUgd2UgY2FuIGltbWVkaWF0ZWx5CiAgICAgICAgICAgIHJvYW0gdG8uIE90aGVyd2lzZSwgcmV0dXJuIEZBTFNFLgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCnN0YXRpYyB0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5SZXN1bHRzKHRwQW5pU2lyR2xvYmFsIHBNYWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0U2NhblJlc3VsdEhhbmRsZSAqcFNjYW5SZXN1bHRMaXN0KQp7CiAgICB0Q3NyU2NhblJlc3VsdEluZm8gKnBTY2FuUmVzdWx0OwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gICAgcEJzc0luZm87CiAgICB0QU5JX1UzMiBDdXJyQVBSc3NpOwogICAgdEFOSV9VOCBSb2FtUnNzaURpZmYgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLlJvYW1Sc3NpRGlmZjsKI2lmICBkZWZpbmVkIChXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUikgfHwgZGVmaW5lZCAoRkVBVFVSRV9XTEFOX0VTRSkgfHwgZGVmaW5lZChGRUFUVVJFX1dMQU5fTEZSKQogICAgdEFOSV9VOCBpbW1lZGlhdGVSb2FtUnNzaURpZmYgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5JbW1lZGlhdGVSb2FtUnNzaURpZmY7CiNlbmRpZgogICAgdEFOSV9CT09MRUFOIHJvYW1Ob3cgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICogRmluZCBvdXQgdGhlIEN1cnJlbnQgQVAgUlNTSSBhbmQga2VlcCBpdCBoYW5keSB0byBjaGVjayBpZgogICAgICogaXQgaXMgYmV0dGVyIHRoYW4gdGhlIFJTU0kgb2YgdGhlIEFQIHdoaWNoIHdlIGFyZQogICAgICogZ29pbmcgdG8gcm9hbS5JZiBzbywgd2UgYXJlIGdvaW5nIHRvIGNvbnRpbnVlIHdpdGggdGhlCiAgICAgKiBjdXJyZW50IEFQLgogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIEN1cnJBUFJzc2kgPSBjc3JHZXRDdXJyZW50QVBSc3NpKHBNYWMsIHBTY2FuUmVzdWx0TGlzdCk7CgogICAgLyogRXhwZWN0aW5nIHRoZSBzY2FuIHJlc3VsdCBhbHJlYWR5IHRvIGJlIGluIHRoZSBzb3J0ZWQgb3JkZXIgYmFzZWQgb24gdGhlIFJTU0kgKi8KICAgIC8qIEJhc2VkIG9uIHRoZSBwcmV2aW91cyBzdGF0ZSB3ZSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgdGhlIGxpc3Qgc2hvdWxkIGJlIHNvcnRlZCBhZ2FpbiB0YWtpbmcgbmVpZ2hib3Igc2NvcmUgaW50byBjb25zaWRlcmF0aW9uICovCiAgICAvKiBJZiBwcmV2aW91cyBzdGF0ZSBpcyBDRkdfQ0hBTl9MSVNUX1NDQU4sIHRoZXJlIHNob3VsZCBub3QgYmUgYW55IG5laWdoYm9yIHNjb3JlIGFzc29jaWF0ZWQgd2l0aCBhbnkgb2YgdGhlIEJTUy4KICAgICAgIElmIHRoZSBwcmV2aW91cyBzdGF0ZSBpcyBSRVBPUlRfUVVFUlksIHRoZW4gdGhlcmUgd2lsbCBiZSBuZWlnaGJvciBzY29yZSBmb3IgZWFjaCBvZiB0aGUgQVBzICovCiAgICAvKiBGb3Igbm93LCBsZXQgdXMgdGFrZSB0aGUgdG9wIG9mIHRoZSBsaXN0IHByb3ZpZGVkIGFzIGl0IGlzIGJ5IHRoZSBDU1IgU2NhbiByZXN1bHQgQVBJLiBUaGlzIG1lYW5zIGl0IGlzIGFzc3VtZWQgdGhhdCBuZWlnaGJvciBzY29yZSAKICAgICAgIGFuZCByc3NpIHNjb3JlIGFyZSBpbiB0aGUgc2FtZSBvcmRlci4gVGhpcyB3aWxsIGJlIHRha2VuIGNhcmUgbGF0ZXIgKi8KCiAgICB3aGlsZSAoTlVMTCAhPSAocFNjYW5SZXN1bHQgPSBjc3JTY2FuUmVzdWx0R2V0TmV4dChwTWFjLCAqcFNjYW5SZXN1bHRMaXN0KSkpCiAgICB7CiAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9ERUJVRywKICAgICAgICAgICAgRkwoIlNjYW4gcmVzdWx0OiBCU1NJRCAiTUFDX0FERFJFU1NfU1RSIiAoUnNzaSAlbGQsIENoOiVkKSIpLAogICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCksCiAgICAgICAgICAgIGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSwKICAgICAgICAgICAgcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuY2hhbm5lbElkKTsKCiAgICAgICBpZiAoKFZPU19UUlVFID09IHZvc19tZW1fY29tcGFyZShwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCwKICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQYnNzaWQsIHNpemVvZih0U2lyTWFjQWRkcikpKSB8fAogICAgICAgICAgICgoZVNNRV9ST0FNX1RSSUdHRVJfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSAmJgogICAgICAgICAgIChWT1NfVFJVRSAhPSB2b3NfbWVtX2NvbXBhcmUocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQsCiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdSb2FtYnNzSWQsIHNpemVvZih0U2lyTWFjQWRkcikpKSkpCiAgICAgICAgewogICAgICAgICAgICAvKiBjdXJyZW50bHkgYXNzb2NpYXRlZCBBUC4gRG8gbm90IGhhdmUgdGhpcyBpbiB0aGUgcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAiU0tJUC1jdXJyZW50bHkgYXNzb2NpYXRlZCBBUCIpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgaWYgKHZvc19jb25jdXJyZW50X29wZW5fc2Vzc2lvbnNfcnVubmluZygpICYmCiAgICAgICAgICAhcE1hYy0+cm9hbS5jb25maWdQYXJhbS5mZW5hYmxlTUNDTW9kZSAmJgogICAgICAgICAgICAocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuY2hhbm5lbElkICE9CiAgICAgICAgICAgIGNzckdldENvbmN1cnJlbnRPcGVyYXRpb25DaGFubmVsKHBNYWMpKSkgewogICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJNQ0Mgbm90IHN1cHBvcnRlZCBzbyBJZ25vcmUgQVAgb24gY2hhbm5lbCAlZCIpLAogICAgICAgICAgICAgICAgICAgIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmNoYW5uZWxJZCk7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgIH0KCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgIC8qIEluIGNhc2Ugb2YgcmVhc3NvYyByZXF1ZXN0ZWQgYnkgdXBwZXIgbGF5ZXIsIGxvb2sgZm9yIGV4YWN0IG1hdGNoIG9mIGJzc2lkICYgY2hhbm5lbDsKICAgICAgICAgIGNzciBjYWNoZSBtaWdodCBoYXZlIGR1cGxpY2F0ZXMqLwogICAgICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikgJiYKICAgICAgICAgICAoKFZPU19GQUxTRSA9PSB2b3NfbWVtX2NvbXBhcmUocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0U2lyTWFjQWRkcikpKXx8CiAgICAgICAgICAgIChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5jaGFubmVsSWQgIT0gcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmNoYW5uZWwpKSkKCiAgICAgICB7CiAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAiU0tJUC1ub3QgYSBjYW5kaWRhdGUgQVAgZm9yIE9TIHJlcXVlc3RlZCByb2FtIik7CiAgICAgICAgICAgY29udGludWU7CiAgICAgICB9CiNlbmRpZgojZW5kaWYKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIKQogICAgICAgewogICAgICAgICAgICAvL0JlbG93IGNoZWNrIGlzIHJlcXVpcmVkIGJlY2F1c2Ugc2Nhbm5pbmcgZm9yIGZvcmNlZCBpbml0aWFsIHJvYW1pbmcgd2UgaGF2ZSBub3QKICAgICAgICAgICAgLy9mbHVzaCBhbGwgdGhlIDIuNCBHSHogQ2hhbm5lbCwgc28gaXQgbWF5IHBvc3NiaWxlIHdlIG1heSByb2FtIGFnYWluIHRvCiAgICAgICAgICAgIC8vMi40IEdoeiBhcCBvbmx5LgogICAgICAgICAgICBpZihHZXRSRkJhbmQocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuY2hhbm5lbElkKSAhPSBTSVJfQkFORF81X0dIWikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogRm9yY2VkIFJvYW0gdG8gNUcgU2tpcCBOb24gNUcgU2NhbiByZXN1bHRzICIsIF9fZnVuY19fKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvL3Jzc2kncyBhcmUgLXZlIHZhbHVlLCBzbyBpZiBhYnMgb2YgcnNzaSBpcyBncmVhdGVyCiAgICAgICAgICAgIC8vbWVhbnMgbmV3IGFwIGlzIHBvb3IgdGhlbiBjdXJyZW50bHkgY29ubmVjdGVkIGFwLgogICAgICAgICAgICAvL0NoZWNrIGl0IGlzIG9ubHkgcG9vciB3aXRoaW4gblNlbGVjdDVHSHpNYXJnaW4gdmFsdWUuCiAgICAgICAgICAgIGlmIChhYnMocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSkgPiBhYnMoQ3VyckFQUnNzaSkgJiYKICAgICAgICAgICAgICAgKChhYnMocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSkgLSBhYnMoQ3VyckFQUnNzaSkpCiAgICAgICAgICAgICAgICA+IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ublNlbGVjdDVHSHpNYXJnaW4pCiAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAiJXM6IEZvcmNlZCBSb2FtIHRvIDVHIEN1cnJlbnQgQVAgcnNzaT0lZCBuZXcgYXAgcnNzaT0lZCBub3QgZ29vZCBlbm91Z2gsIG5TZWxlY3Q1R0h6TWFyZ2luPSVkIiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICBDdXJyQVBSc3NpLAogICAgICAgICAgICAgICAgICAgICAgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ublNlbGVjdDVHSHpNYXJnaW4pOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICB9CiNlbmRpZgojZW5kaWYKCiAgICAgICAvKiBUaGlzIGNvbmRpdGlvbiBpcyB0byBlbnN1cmUgdG8gcm9hbSB0byBhbiBBUCB3aXRoIGJldHRlciBSU1NJLiBpZiB0aGUgdmFsdWUgb2YgUm9hbVJzc2lEaWZmIGlzIFplcm8sIHRoaXMgZmVhdHVyZQogICAgICAgICogaXMgZGlzYWJsZWQgYW5kIHdlIGNvbnRpbnVlIHRvIHJvYW0gd2l0aG91dCBhbnkgY2hlY2sqLwogICAgICAgaWYgKChSb2FtUnNzaURpZmYgPiAwKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAmJiAhY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKQojZW5kaWYKICAgICAgICYmICgoZVNNRV9ST0FNX1RSSUdHRVJfU0NBTiAhPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSAmJgogICAgICAgICAgIChlU01FX1JPQU1fVFJJR0dFUl9GQVNUX1JPQU0gIT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikpKQogICAgICAgewogICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAqIElmIFJTU0kgaXMgbG93ZXIgdGhhbiB0aGUgbG9va3VwIHRocmVzaG9sZCwgdGhlbiBjb250aW51ZS4KICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgaWYgKGFicyhwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpKSA+CiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkKQogICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gbmV3IGFwIHJzc2kgKCVkKSBsb3dlciB0aGFuIGxvb2t1cCB0aHJlc2hvbGQgKCVkKSIsCiAgICAgICAgICAgICAgICAgICAgX19mdW5jX18sIChpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgKGludClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSk7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgIGlmIChhYnMoQ3VyckFQUnNzaSkgPCBhYnMocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSkpCiAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAvKkRvIG5vdCByb2FtIHRvIGFuIEFQIHdpdGggd29yc2UgUlNTSSB0aGFuIHRoZSBjdXJyZW50Ki8KICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR11DdXJyZW50IEFQIHJzc2k9JWQgbmV3IGFwIHJzc2kgd29yc2U9JWQiLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3VyckFQUnNzaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5yc3NpICogKC0xKSApOwogICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgIC8qRG8gbm90IHJvYW0gdG8gYW4gQVAgd2hpY2ggaXMgaGF2aW5nIGJldHRlciBSU1NJIHRoYW4gdGhlIGN1cnJlbnQgQVAsIGJ1dCBzdGlsbCBsZXNzIHRoYW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICogbWFyZ2luIHRoYXQgaXMgcHJvdmlkZWQgYnkgdXNlciBmcm9tIHRoZSBpbmkgZmlsZSAoUm9hbVJzc2lEaWZmKSovCiAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFicyhhYnMoQ3VyckFQUnNzaSkgLSBhYnMocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSkpIDwgUm9hbVJzc2lEaWZmKQogICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlczogW0lORk9MT0ddQ3VycmVudCBBUCByc3NpPSVkIG5ldyBhcCByc3NpPSVkIG5vdCBnb29kIGVub3VnaCwgcm9hbVJzc2lEaWZmPSVkIiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEN1cnJBUFJzc2ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJvYW1Sc3NpRGlmZik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXUN1cnJlbnQgQVAgcnNzaT0lZCBuZXcgYXAgcnNzaSBiZXR0ZXI9JWQiLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDdXJyQVBSc3NpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpcFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSAqICgtMSkgKTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgIH0KICAgICAgIH0KCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykKICAgICAgICB7CiAgICAgICAgICAgIGlmICghY3NyTmVpZ2hib3JSb2FtSXNQcmVhdXRoQ2FuZGlkYXRlKHBNYWMsIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJCU1NJRCBwcmVzZW50IGluIHByZS1hdXRoIGZhaWwgbGlzdC4uIElnbm9yaW5nIikpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmICghY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICB7CiNlbmRpZgogICAgICAgICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jKQogICAgICAgICAgewogICAgICAgICAgICAgIGlmICghY3NyTmVpZ2hib3JSb2FtSXNQcmVhdXRoQ2FuZGlkYXRlKHBNYWMsIHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQlNTSUQgcHJlc2VudCBpbiBwcmUtYXV0aCBmYWlsIGxpc3QuLiBJZ25vcmluZyIpKTsKICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgaWYgKChwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9wcmVzZW50KSAmJgogICAgICAgICAgICAgICAocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfYXZhaWwpKQogICAgICAgICAgewogICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNWT0FkbWl0dGVkKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJOZXcgQVAgaGFzICV4IEJXIGF2YWlsYWJsZSIpLCAodW5zaWduZWQgaW50KXBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLlFCU1NMb2FkX2F2YWlsKTsKICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJXZSBuZWVkICV4IEJXIGF2YWlsYWJsZSIpLCh1bnNpZ25lZCBpbnQpcE5laWdoYm9yUm9hbUluZm8tPk1pblFCc3NMb2FkUmVxdWlyZWQpOwogICAgICAgICAgICAgICAgICBpZiAocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuUUJTU0xvYWRfYXZhaWwgPCBwTmVpZ2hib3JSb2FtSW5mby0+TWluUUJzc0xvYWRSZXF1aXJlZCkKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIltJTkZPTE9HXUJTU0lEIDogIk1BQ19BRERSRVNTX1NUUiIgaGFzIG5vIGJhbmR3aWR0aCBpZ25vcmluZy4ubm90IGFkZGluZyB0byByb2FtIGxpc3QiLAogICAgICAgICAgICAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmJzc0lkKSk7CiAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGVsc2UKICAgICAgICAgIHsKICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5vIFFCc3MgJXggJXgiKSwgKHVuc2lnbmVkIGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9hdmFpbCwgKHVuc2lnbmVkIGludClwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5RQlNTTG9hZF9wcmVzZW50KTsKICAgICAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzVk9BZG1pdHRlZCkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgICAgIltJTkZPTE9HXUJTU0lEIDogIk1BQ19BRERSRVNTX1NUUiIgaGFzIG5vIFFCU1NMb2FkIElFLCBpZ25vcmluZy4ubm90IGFkZGluZyB0byByb2FtIGxpc3QiLAogICAgICAgICAgICAgICAgICAgICAgTUFDX0FERFJfQVJSQVkocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IuYnNzSWQpKTsKICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgfQojZW5kaWYKI2VuZGlmIC8qIEZFQVRVUkVfV0xBTl9FU0UgKi8KCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgLy8gSWYgd2UgYXJlIHN1cHBvcnRpbmcgbGVnYWN5IHJvYW1pbmcsIGFuZCAKICAgICAgICAvLyBpZiB0aGUgY2FuZGlkYXRlIGlzIG9uIHRoZSAicHJlLWF1dGggZmFpbGVkIiBsaXN0LCBpZ25vcmUgaXQuIAogICAgICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgQ1NSX1NFU1NJT05fSURfSU5WQUxJRCkpCiAgICAgICAgewogICAgICAgICAgICBpZiAoIWNzck5laWdoYm9yUm9hbUlzUHJlYXV0aENhbmRpZGF0ZShwTWFjLCBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5ic3NJZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQlNTSUQgcHJlc2VudCBpbiBwcmUtYXV0aCBmYWlsIGxpc3QuLiBJZ25vcmluZyIpKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQojZW5kaWYgLyogRkVBVFVSRV9XTEFOX0xGUiAqLwoKICAgICAgICAvKiBJZiB0aGUgcmVjZWl2ZWQgdGltZXN0YW1wIGluIEJTUyBkZXNjcmlwdGlvbiBpcyBlYXJsaWVyIHRoYW4gdGhlIHNjYW4gcmVxdWVzdCB0aW1lc3RhbXAsIHNraXAgCiAgICAgICAgICogdGhpcyByZXN1bHQgKi8KICAgICAgICBpZiAoKHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUmVxdWVzdFRpbWVTdGFtcCA+PSBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5uUmVjZWl2ZWRUaW1lKQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICYmICFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpCiNlbmRpZgogICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSWdub3JpbmcgQlNTIGFzIGl0IGlzIG9sZGVyIHRoYW4gdGhlIHNjYW4gcmVxdWVzdCB0aW1lc3RhbXAiKSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgcEJzc0luZm8gPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodENzck5laWdoYm9yUm9hbUJTU0luZm8pKTsKICAgICAgICBpZiAoTlVMTCA9PSBwQnNzSW5mbykKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZm9yIE5laWdoYm9yIFJvYW0gQlNTIEluZm8gZmFpbGVkLi4gSnVzdCBpZ25vcmluZyIpKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBwQnNzSW5mby0+cEJzc0Rlc2NyaXB0aW9uID0gdm9zX21lbV9tYWxsb2MocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IubGVuZ3RoICsgc2l6ZW9mKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLmxlbmd0aCkpOwogICAgICAgIGlmIChwQnNzSW5mby0+cEJzc0Rlc2NyaXB0aW9uICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICB2b3NfbWVtX2NvcHkocEJzc0luZm8tPnBCc3NEZXNjcmlwdGlvbiwgJnBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLCAKICAgICAgICAgICAgICAgICAgICBwU2NhblJlc3VsdC0+QnNzRGVzY3JpcHRvci5sZW5ndGggKyBzaXplb2YocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IubGVuZ3RoKSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTWVtb3J5IGFsbG9jYXRpb24gZm9yIE5laWdoYm9yIFJvYW0gQlNTIERlc2NyaXB0b3IgZmFpbGVkLi4gSnVzdCBpZ25vcmluZyIpKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBCc3NJbmZvKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIAogICAgICAgIH0KICAgICAgICBwQnNzSW5mby0+YXBQcmVmZXJlbmNlVmFsID0gMTA7IC8vc29tZSB2YWx1ZSBmb3Igbm93LiBOZWVkIHRvIGNhbGN1bGF0ZSB0aGUgYWN0dWFsIHNjb3JlIGJhc2VkIG9uIFJTU0kgYW5kIG5laWdoYm9yIEFQIHNjb3JlCgogICAgICAgIC8qIEp1c3QgYWRkIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QgYXMgaXQgaXMgYWxyZWFkeSBzb3J0ZWQgYnkgUlNTSSAqLwogICAgICAgIGNzckxMSW5zZXJ0VGFpbCgmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCAmcEJzc0luZm8tPkxpc3QsIExMX0FDQ0VTU19MT0NLKTsKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgICAgICBpZiAoKGVTTUVfUk9BTV9UUklHR0VSX1NDQU4gPT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1JvYW1FbikgfHwKICAgICAgICAgICAgKGVTTUVfUk9BTV9UUklHR0VSX0ZBU1RfUk9BTSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSkKICAgICAgICB7CiAgICAgICAgICAgcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoKGFicyhhYnMoQ3VyckFQUnNzaSkgLSBhYnMocFNjYW5SZXN1bHQtPkJzc0Rlc2NyaXB0b3IucnNzaSkpID49IGltbWVkaWF0ZVJvYW1Sc3NpRGlmZikKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAmJiAhY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKQojZW5kaWYKICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXSBwb3RlbnRpYWwgY2FuZGlkYXRlIHRvIHJvYW0gaW1tZWRpYXRlbHkgKGRpZmY9JWxkLCBleHBlY3RlZD0lZCkiLAogICAgICAgICAgICAgICAgICAgICAgIF9fZnVuY19fLCBhYnMoYWJzKEN1cnJBUFJzc2kpIC0gYWJzKHBTY2FuUmVzdWx0LT5Cc3NEZXNjcmlwdG9yLnJzc2kpKSwKICAgICAgICAgICAgICAgICAgICAgICBpbW1lZGlhdGVSb2FtUnNzaURpZmYpOwogICAgICAgICAgICByb2FtTm93ID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgLyogSWYgd2UgYXJlIGhlcmUgbWVhbnMsIEZXIGFscmVhZHkgZm91bmQgY2FuZGlkYXRlcyB0byByb2FtLCBzbyB3ZSBhcmUKICAgICAgICAgICBnb29kIHRvIGdvIHdpdGggcHJlLWF1dGggKi8KICAgICAgICBpZihjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgIHsKICAgICAgICAgICAgcm9hbU5vdyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgIH0KI2VuZGlmCiNlbmRpZgogICAgfQoKICAgIC8qIE5vdyB3ZSBoYXZlIGFsbCB0aGUgc2NhbiByZXN1bHRzIGluIG91ciBsb2NhbCBsaXN0LiBHb29kIHRpbWUgdG8gZnJlZSB1cCB0aGUgdGhlIGxpc3Qgd2UgZ290IGFzIGEgcGFydCBvZiBjc3JHZXRTY2FuUmVzdWx0ICovCiAgICBjc3JTY2FuUmVzdWx0UHVyZ2UocE1hYywgKnBTY2FuUmVzdWx0TGlzdCk7CgogICAgcmV0dXJuIHJvYW1Ob3c7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1IYW5kbGVFbXB0eVNjYW5SZXN1bHQKCiAgICBcYnJpZWYgICAgICBUaGlzIGZ1bmN0aW9uIHdpbGwgYmUgaW52b2tlZCBpbiBDRkdfQ0hBTl9MSVNUX1NDQU4gc3RhdGUgd2hlbiAKICAgICAgICAgICAgICAgIHRoZXJlIGFyZSBubyB2YWxpZCBBUHMgaW4gdGhlIHNjYW4gcmVzdWx0IGZvciByb2FtaW5nLiBUaGlzIG1lYW5zIAogICAgICAgICAgICAgICAgb3VyIEFQIGlzIHRoZSBiZXN0IGFuZCBubyBvdGhlciBBUCBpcyBhcm91bmQuIE5vIHBvaW50IGluIHNjYW5uaW5nCiAgICAgICAgICAgICAgICBhZ2FpbiBhbmQgYWdhaW4uIFBlcmZvcm1pbmcgdGhlIGZvbGxvd2luZyBoZXJlLgogICAgICAgICAgICAgICAgMS4gU3RvcCB0aGUgbmVpZ2hib3Igc2NhbiB0aW1lci4KICAgICAgICAgICAgICAgIDJhLiBJZiB0aGlzIGlzIHRoZSBmaXJzdCB0aW1lIHdlIGVuY291bnRlcmVkIGVtcHR5IHNjYW4sIHRoZW4KICAgICAgICAgICAgICAgIHJlLXJlZ2lzdGVyIHdpdGggVEwgd2l0aCBtb2RpZmllZCBsb29rdXAgdGhyZXNob2xkLgogICAgICAgICAgICAgICAgMmIuIEVsc2UgaWYgdGhpcyBpcyB0aGUgc2Vjb25kIHRpbWUgd2UgZW5jb3VudGVyZWQgZW1wdHkgc2NhbiwKICAgICAgICAgICAgICAgIHRoZW4gc3RhcnQgbmVpZ2hib3Igc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKDIwcykuCiAgICAgICAgICAgICAgICAyYy4gRWxzZSwgbm90aGluZyBtb3JlIHRvIGRvLgogICAgICAgICAgICAgICAgTk9URTogSW4gTEZSLCBjaGFubmVscyBzZWxlY3RlZCBmb3Igc2Nhbm5pbmcgaXMgZGVydmllZCBmcm9tCiAgICAgICAgICAgICAgICB0aGUgb2NjdXBlZCBjaGFubmVsIGxpc3QuIFNjYW4gY3ljbGUgZm9sbG93aW5nIG9uZSB3aGljaAogICAgICAgICAgICAgICAgeWllbGRlZCBlbXB0eSByZXN1bHRzIGlzIHNwbGl0IGludG8gdHdvIGhhbHZlczogKGkpIHNjYW4gb24KICAgICAgICAgICAgICAgIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBsaXN0LCBhbmQgKGlpKSBzY2FuIG9uIGNoYW5uZWxzIG5vdAogICAgICAgICAgICAgICAgaW4gdGhlIG9jY3VwaWVkIGxpc3QuIFRoaXMgaGVscHMgY29udmVyZ2luZyBmYXN0ZXIgKHdoaWxlCiAgICAgICAgICAgICAgICBsb29raW5nIGZvciBjYW5kaWRhdGVzIGluIHRoZSBvY2N1cGllZCBsaXN0IGZpcnN0KSwgYW5kIGFsc28sCiAgICAgICAgICAgICAgICBhZGRzIGNoYW5uZWxzIHRvIHRoZSBvY2N1cGllZCBjaGFubmVsIGxpc3QgdXBvbiBmaW5kaW5nIGNhbmRpZGF0ZXMKICAgICAgICAgICAgICAgIG1hdGNoaW5nIFNTSUQgcHJvZmlsZSBvZiBpbnRlcmVzdC4KCiAgICAgICAgICAgICAgICB1RW1wdHlTY2FuQ291bnQgICAgICAgICAgICAgICAgICAgICAgICAgQ29tbWVudHMKICAgICAgICAgICAgICAgIGVGaXJzdEVtcHR5U2NhbiAgICAgUHJldmlvdXMgc2NhbiB3YXMgZG9uZSBvbiBjaGFubmVscyBpbiB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NjdXBpZWQgbGlzdCBhbmQgeWllbGRlZCBwb3RlbnRpYWwgY2FuZGlkYXRlcy4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBzY2FuIGN5Y2xlIHdhcyBsaWtlbHkgdHJpZ2dlcmVkIHRocm91Z2gKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWlwdCBvZiBsb29rdXAgRE9XTiBub3RpZmljYXRpb24gZXZlbnQuCiAgICAgICAgICAgICAgICBlU2Vjb25kRW1wdHlTY2FuICAgIFByZXZpb3VzIHNjYW4gd2FzIGRvbmUgb24gY2hhbm5lbHMgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jY3VwaWVkIGxpc3QgYW5kIHlpZWxkZWQgbm8gY2FuZGlkYXRlcy4gVGhpcyBzY2FuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN5Y2xlIHdhcyB0cmlnZ2VyZWQgdGhyb3VnaCBSU1NJIG5vdGlmaWNhdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aXRoIG1vZGlmaWVkIGxvb2t1cCB0aHJlc2hvbGQuCiAgICAgICAgICAgICAgICBlVGhpcmRFbXB0eVNjYW4gICAgIFByZXZpb3VzIHNjYW4gd2FzIGRvbmUgb24gY2hhbm5lbHMgTk9UIGluCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBvY2N1cGllZCBsaXN0IGFuZCB5aWVsZGVkIG5vIGNhbmRpZGF0ZXMuIFRoaXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NhbiBjeWNsZSB3YXMgdHJpZ2dlcmVkIGltbWVkaWF0ZWx5IGFmdGVyIHNjYW5uaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBsaXN0IGFuZCBubyBjYW5kaWRhdGVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlcmUgZm91bmQuCiAgICAgICAgICAgICAgICBlRm91cnRoRW1wdHlTY2FuICAgIFByZXZpb3VzIHNjYW4gd2FzIGRvbmUgb24gY2hhbm5lbHMgaW4gdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jY3VwaWVkIGxpc3QgYW5kIHlpZWxkZWQgbm8gY2FuZGlkYXRlcy4gVGhpcyBzY2FuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN5Y2xlIHdhcyB0cmlnZ2VyZWQgdXBvbiBleHBpcnkgb2YKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmVpZ2hib3JTY2FuUmVzdWx0c1JlZnJlc2hQZXJpb2QgKD0yMHMpLgogICAgICAgICAgICAgICAgZUZpZnRoRW1wdHlTY2FuICAgICBQcmV2aW91cyBzY2FuIHdhcyBkb25lIG9uIGNoYW5uZWxzIE5PVCBpbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGUgb2NjdXBpZWQgbGlzdCBhbmQgeWllbGRlZCBubyBjYW5kaWRhdGVzLiBUaGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW4gY3ljbGUgd2FzIHRyaWdnZXJlZCBpbW1lZGlhdGVseSBhZnRlciBzY2FubmluZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVscyBpbiB0aGUgb2NjdXBpZWQgbGlzdCBhbmQgbm8gY2FuZGlkYXRlcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZXJlIGZvdW5kLgoKICAgICAgICAgICAgICAgIFsxXSwgWzIsM10gYW5kIFs0LDVdIHRvZ2V0aGVyIGZvcm0gb25lIGRpc2NyZXRlIHNldCBvZiBzY2FuIGN5Y2xlLgoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpzdGF0aWMgVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1IYW5kbGVFbXB0eVNjYW5SZXN1bHQodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzICBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgdEFOSV9CT09MRUFOIHBlcmZvcm1QZXJpb2RpY1NjYW4gPQogICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmVtcHR5U2NhblJlZnJlc2hQZXJpb2QpID8gVFJVRSA6IEZBTFNFOwojZW5kaWYKCiAgICAvKiBTdG9wIG5laWdoYm9yIHNjYW4gdGltZXIgKi8KICAgIHZvc190aW1lcl9zdG9wKCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgLyoKICAgICAqIEluY3JlYXNlIHRoZSBuZWlnaGJvciBsb29rdXAgdGhyZXNob2xkIGJ5IDMgZEIKICAgICAqIGFmdGVyIGV2ZXJ5IHNjYW4gY3ljbGUuIE5PVEU6IHVFbXB0eVNjYW5Db3VudAogICAgICogd291bGQgYmUgZWl0aGVyIDEsIDMgb3IgNSBhdCB0aGUgZW5kIG9mIGV2ZXJ5CiAgICAgKiBzY2FuIGN5Y2xlLgogICAgICovCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBpZiAoKCsrcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCkgPiBlRmlmdGhFbXB0eVNjYW4pCiAgICB7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9IGVGaWZ0aEVtcHR5U2NhbjsKICAgIH0KICAgIGlmICgoKDAgIT0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKSB8fAogICAgICAgICAoYWJzKHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSkgPgogICAgICAgICBhYnMocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQpKSkgJiYKICAgICAgICAoKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPT0gZVNlY29uZEVtcHR5U2NhbikgfHwKICAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPT0gZUZvdXJ0aEVtcHR5U2NhbikpKQogICAgewogICAgICAgIC8qCiAgICAgICAgICogSWYgdGhlIHNjYW4gd2FzIHRyaWdnZXJlZCBkdWUgdG8gbG9va3VwRE9XTlJzc2kgPiByZWFzc29jIHRocmVzaG9sZCwKICAgICAgICAgKiB0aGVuIGl0IHdvdWxkIGJlIGEgY29udGlndW91cyBzY2FuIG9uIGFsbCB2YWxpZCBub24tREZTIGNoYW5uZWxzLgogICAgICAgICAqIElmIGNoYW5uZWxzIGFyZSBjb25maWd1cmVkIGluIElOSSwgdGhlbiBvbmx5IHRob3NlIGNoYW5uZWxzIG5lZWQKICAgICAgICAgKiB0byBiZSBzY2FubmVkLgogICAgICAgICAqIEluIGVpdGhlciBvZiB0aGVzZSBtb2RlcywgdGhlcmUgaXMgbm8gbmVlZCB0byB0cmlnZ2VyIGFuIGltbWVkaWF0ZQogICAgICAgICAqIHNjYW4gdXBvbiBlbXB0eSBzY2FuIHJlc3VsdHMgZm9yIHRoZSBzZWNvbmQgYW5kIGZvdXJ0aCB0aW1lICh3aGljaAogICAgICAgICAqIHdvdWxkIGJlIGVxdWl2YWxlbnQgdG8gc2Nhbm5pbmcgb24gY2hhbm5lbHMgaW4gbm9uLW9jY3VwaWVkIGxpc3QpLgogICAgICAgICAqIEluY3JlbWVudGluZyB1RW1wdHlTY2FuQ291bnQgd2lsbCBjb3JyZXNwb25kIHRvIHNraXBwaW5nIHRoaXMgc3RlcC4KICAgICAgICAgKiBOT1RFOiBkb3VibGUgaW5jcmVtZW50IG9mIHVFbXB0eVNjYW5Db3VudCBjb3JyZXNwb25kcyB0byBjb21wbGV0aW9uCiAgICAgICAgICogb2Ygc2NhbnMgb24gYWxsIHZhbGlkIGNoYW5uZWxzLgogICAgICAgICAqLwogICAgICAgICsrcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudDsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsICJFeHRyYSBpbmNyZW1lbnQgb2YgZW1wdHkgc2NhbiBjb3VudCAoPSVkKSIKICAgICAgICAgICAgIiBpbiBjb250aWd1b3VzIHNjYW4gbW9kZSIsIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQpOwogICAgfQojZW5kaWYKICAgIGlmICgoKHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQrMykgPAogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkKQojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICYmICgocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCAlIDIpID09IDEpCiNlbmRpZgogICAgICAgICkKICAgIHsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICs9IDM7CiAgICB9CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIC8qIENsZWFyIG9mZiB0aGUgb2xkIG5laWdoYm9yIHJlcG9ydCBkZXRhaWxzICovCiAgICB2b3NfbWVtX3plcm8oJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvLCBzaXplb2YodENzck5laWdoYm9yUmVwb3J0QnNzSW5mbykgKiBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCk7CiNlbmRpZgoKICAgIC8qIFRyYW5zaXRpb24gdG8gQ09OTkVDVEVEIHN0YXRlICovCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpOwogICAgICAgIAogICAgLyogUmVzZXQgYWxsIHRoZSBuZWNlc3NhcnkgdmFyaWFibGVzIGJlZm9yZSB0cmFuc2l0aW9uaW5nIHRvIHRoZSBDT05ORUNURUQgc3RhdGUgKi8KICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKICAgICAgICAKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IGVGaXJzdEVtcHR5U2NhbikKICAgIHsKI2VuZGlmCiAgICAgICAgLyogRW1wdHkgc2NhbiByZXN1bHRzIGZvciB0aGUgZmlyc3QgdGltZSAqLwogICAgICAgIC8qIFJlLXJlZ2lzdGVyIG5laWdoYm9yIGxvb2t1cCBET1dOIHRocmVzaG9sZCBjYWxsYmFjayB3aXRoIFRMICovCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLAogICAgICAgICAgICBGTCgiUmVnaXN0ZXJpbmcgRE9XTiBldmVudCBuZWlnaGJvciBsb29rdXAgY2FsbGJhY2sgd2l0aCBUTCBmb3IgUlNTSSA9ICVkIiksCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpKTsKCiAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX1JlZ1JTU0lJbmRpY2F0aW9uQ0IocE1hYy0+cm9hbS5nVm9zQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgKHZfUzdfdClwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLAogICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwoKICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgICAgIEZMKCJDb3VsZG4ndCByZS1yZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayIKICAgICAgICAgICAgICAgICAgICAgICIgd2l0aCBUTDogU3RhdHVzID0gJWQiKSwgc3RhdHVzKTsKICAgICAgICB9CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpID0gMDsKICAgIH0KICAgIGVsc2UgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID09IGVTZWNvbmRFbXB0eVNjYW4pIHx8CiAgICAgICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSBlRm91cnRoRW1wdHlTY2FuKSkKICAgIHsKICAgICAgICAvKiBFbXB0eSBzY2FuIHJlc3VsdHMgZm9yIHRoZSBzZWNvbmQgb3IgZm91cnRoIHRpbWUgKi8KCiAgICAgICAgLyogSW1tZWRpYXRlbHkgc2NhbiBvbiBjaGFubmVscyBpbiBub24tb2NjdXBpZWQgbGlzdCAqLwogICAgICAgIGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgfQogICAgZWxzZSBpZiAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA+PSBlVGhpcmRFbXB0eVNjYW4pCiAgICB7CiAgICAgICAgLyogRW1wdHkgc2NhbiByZXN1bHRzIGZvciB0aGUgdGhpcmQgdGltZSAqLwogICAgICAgIGlmIChwZXJmb3JtUGVyaW9kaWNTY2FuKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJQZXJmb3JtaW5nIHBlcmlvZGljIHNjYW4sIHVFbXB0eVNjYW5Db3VudD0lZCIpLAogICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCk7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTZXQgdUVtcHR5U2NhbkNvdW50IHRvIE1BWCBzbyB0aGF0IHdlIGFsd2F5cyBlbnRlciB0aGlzCiAgICAgICAgICAgICAqIGNvbmRpdGlvbiBvbiBzdWJzZXF1ZW50IGVtcHR5IHNjYW4gcmVzdWx0cwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9IGVNYXhFbXB0eVNjYW47CgogICAgICAgICAgICAvKiBGcm9tIGhlcmUgb24sIE9OTFkgc2NhbiBvbiBjaGFubmVscyBpbiB0aGUgb2NjdXBpZWQgbGlzdCAqLwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gU1BMSVRfU0NBTl9PQ0NVUElFRF9MSVNUOwoKICAgICAgICAgICAgLyogU3RhcnQgZW1wdHkgc2NhbiByZWZyZXNoIHRpbWVyICovCiAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0KICAgICAgICAgICAgICAgIHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lciwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmVtcHR5U2NhblJlZnJlc2hQZXJpb2QpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBmYWlsZWQgdG8gc3RhcnQgKCVkKSIpLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMpOwogICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSAwOwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBzdGFydGVkICglZCBtcykiKSwKICAgICAgICAgICAgICAgICAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuZW1wdHlTY2FuUmVmcmVzaFBlcmlvZCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGVUaGlyZEVtcHR5U2NhbiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50KQogICAgICAgIHsKICAgICAgICAgICAgLyogU3RhcnQgbmVpZ2hib3Igc2NhbiByZXN1bHRzIHJlZnJlc2ggdGltZXIgKi8KICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPQogICAgICAgICAgICAgICAgICAgIHZvc190aW1lcl9zdGFydCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lciwKICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlc3VsdHNSZWZyZXNoUGVyaW9kKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXN1bHRzIHJlZnJlc2ggdGltZXIgZmFpbGVkIHRvIHN0YXJ0ICglZCkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPRzIsIEZMKCJOZWlnaGJvciByZXN1bHRzIHJlZnJlc2ggdGltZXIgc3RhcnRlZCAoJWQgbXMpIiksCiAgICAgICAgICAgICAgICAgICAgICAgIChwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2QgKiBQQUxfVElNRVJfVE9fTVNfVU5JVCkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIk5laWdoYm9yIHJvYW0gZW1wdHkgc2NhbiBjb3VudD0lZCBzY2FuIG1vZGU9JWQiLAogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQsIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUpOwojZW5kaWYKICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCgpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlICh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIHRDc3JTY2FuUmVzdWx0RmlsdGVyICAgIHNjYW5GaWx0ZXI7CiAgICB0U2NhblJlc3VsdEhhbmRsZSAgICAgICBzY2FuUmVzdWx0OwogICAgdEFOSV9VMzIgICAgICAgICAgICAgICAgdGVtcFZhbCA9IDA7CiAgICB0QU5JX0JPT0xFQU4gICAgICAgICAgICByb2FtTm93ID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgZUhhbFN0YXR1cyAgICAgICAgICAgICAgaHN0YXR1czsKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgICAgICAvKiBJZiB0aGUgc3RhdGUgaXMgUkVQT1JUX1NDQU4sIHRoZW4gdGhpcyBtdXN0IGJlIHRoZSBzY2FuIGFmdGVyIHRoZSBSRVBPUlRfUVVFUlkgc3RhdGUuIFNvLCB3ZSAKICAgICAgICAgICBzaG91bGQgdXNlIHRoZSBCU1NJRCBmaWx0ZXIgbWFkZSBvdXQgb2YgbmVpZ2hib3IgcmVwb3J0cyAqLwogICAgICAgIGlmICgoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICYmICghY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKI2VuZGlmCiAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUJzc0lkU2NhbkZpbHRlcihwTWFjLCAmc2NhbkZpbHRlcik7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoIjExUiBvciBFU0UgQXNzb2NpYXRpb246IFByZXBhcmUgc2NhbiBmaWx0ZXIgc3RhdHVzICB3aXRoIG5laWdoYm9yIEFQID0gJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgICAgIHRlbXBWYWwgPSAxOwogICAgICAgIH0KICAgICAgICBlbHNlCiNlbmRpZgogICAgICAgIHsKICAgICAgICAgICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByZXBhcmVTY2FuUHJvZmlsZUZpbHRlcihwTWFjLCAmc2NhbkZpbHRlcik7CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgRkwoIjExUi9FU0UvT3RoZXIgQXNzb2NpYXRpb246IFByZXBhcmUgc2NhbiB0byBmaW5kIG5laWdoYm9yIEFQIGZpbHRlciBzdGF0dXMgID0gJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgfQogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlNjYW4gRmlsdGVyIHByZXBhcmF0aW9uIGZhaWxlZCBmb3IgQXNzb2MgdHlwZSAlZC4uIEJhaWxpbmcgb3V0Li4iKSwgdGVtcFZhbCk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIH0KICAgICAgICBoc3RhdHVzID0gY3NyU2NhbkdldFJlc3VsdChwTWFjLCAmc2NhbkZpbHRlciwgJnNjYW5SZXN1bHQpOwogICAgICAgIGlmIChoc3RhdHVzICE9IGVIQUxfU1RBVFVTX1NVQ0NFU1MpCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJHZXQgU2NhbiBSZXN1bHQgc3RhdHVzIGNvZGUgJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgfQogICAgICAgIC8qIFByb2Nlc3MgdGhlIHNjYW4gcmVzdWx0cyBhbmQgdXBkYXRlIHJvYW1hYmxlIEFQIGxpc3QgKi8KICAgICAgICByb2FtTm93ID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5SZXN1bHRzKHBNYWMsICZzY2FuUmVzdWx0KTsKCiAgICAgICAgLyogRnJlZSB0aGUgc2NhbiBmaWx0ZXIgKi8KICAgICAgICBjc3JGcmVlU2NhbkZpbHRlcihwTWFjLCAmc2NhbkZpbHRlcik7CgogICAgICAgIHRlbXBWYWwgPSBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwoKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgIHsKI2VuZGlmCiAgICAgICAgIHN3aXRjaChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOOgogICAgICAgICAgICAgICAgaWYgKHRlbXBWYWwpCiAgICAgICAgICAgICAgICB7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBTaW5jZSB0aGVyZSBhcmUgbm9uLXplcm8gY2FuZGlkYXRlcyBmb3VuZAogICAgICAgICAgICAgICAgICAgICAqIGFmdGVyIHRoZSBzY2FuLCByZXNldCBlbXB0eSBzY2FuIGNvdW50LgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPSBERUZBVUxUX1NDQU47CiNlbmRpZgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICAgICAgICAgICAgICAvKiBJZiB0aGlzIGlzIGEgbm9uLTExciBhc3NvY2lhdGlvbiwgdGhlbiB3ZSBjYW4gcmVnaXN0ZXIgdGhlIHJlYXNzb2MgY2FsbGJhY2sgaGVyZSBhcyB3ZSBoYXZlIHNvbWUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBUHMgaW4gdGhlIHJvYW1hYmxlIEFQIGxpc3QgKi8KICAgICAgICAgICAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBWYWxpZCBBUHMgYXJlIGZvdW5kIGFmdGVyIHNjYW4uIE5vdyB3ZSBjYW4gaW5pdGlhdGUgcHJlLWF1dGhlbnRpY2F0aW9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9TQ0FOKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiNlbmRpZgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgICAgICAgICAgICAgIC8qIElmIHRoaXMgaXMgYSBub24tMTFyIGFzc29jaWF0aW9uLCB0aGVuIHdlIGNhbiByZWdpc3RlciB0aGUgcmVhc3NvYyBjYWxsYmFjayBoZXJlIGFzIHdlIGhhdmUgc29tZSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFQcyBpbiB0aGUgcm9hbWFibGUgQVAgbGlzdCAqLwogICAgICAgICAgICAgICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFZhbGlkIEFQcyBhcmUgZm91bmQgYWZ0ZXIgc2Nhbi4gTm93IHdlIGNhbiBpbml0aWF0ZSBwcmUtYXV0aGVudGljYXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4pCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKI2VuZGlmCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAgICAgLyogSWYgTEZSIGlzIGVuYWJsZWQsIHRoZW4gd2UgY2FuIHJlZ2lzdGVyIHRoZSByZWFzc29jIGNhbGxiYWNrIGhlcmUgYXMgd2UgaGF2ZSBzb21lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVBzIGluIHRoZSByb2FtYWJsZSBBUCBsaXN0ICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLCBDU1JfU0VTU0lPTl9JRF9JTlZBTElEKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFZhbGlkIEFQcyBhcmUgZm91bmQgYWZ0ZXIgc2Nhbi4gTm93IHdlIGNhbiBpbml0aWF0ZSBwcmUtYXV0aGVudGljYXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4pCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKI2VuZGlmCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJDb21wbGV0ZWQgc2Nhbm5pbmcgb2YgQ0ZHIENIQU4gTElTVCBpbiBub24tMTFyIGFzc29jaWF0aW9uLiBSZWdpc3RlcmluZyByZWFzc29jIGNhbGxiYWNrIikpOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBOb3RoaW5nIG11Y2ggdG8gZG8gbm93LiBXaWxsIGNvbnRpbnVlIHRvIHJlbWFpbiBpbiB0aGlzIHN0YXRlIGluIGNhc2Ugb2Ygbm9uLTExciBhc3NvY2lhdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAvKiBTdG9wIHRoZSB0aW1lci4gQnV0IGhvdyBsb25nIHRoZSByb2FtYWJsZSBBUCBsaXN0IHdpbGwgYmUgdmFsaWQgaW4gaGVyZS4gQXQgc29tZSBwb2ludCBvZiB0aW1lLCB3ZSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmVlZCB0byByZXN0YXJ0IHRoZSBDRkcgQ0hBTiBsaXN0IHNjYW4gcHJvY2VkdXJlIGlmIHJlYXNzb2MgY2FsbGJhY2sgaXMgbm90IGludm9rZWQgZnJvbSBUTCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aGluIGNlcnRhaW4gZHVyYXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgCi8vICAgICAgICAgICAgICAgICAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwKICAgICAgICAgICAgICAgICAgICBGTCgiTm8gY2FuZGlkYXRlIGZvdW5kIGFmdGVyIHNjYW5uaW5nIGluIHN0YXRlICVzIC4uICIpLAogICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICAgICAgICAgIC8qIEhhbmRsZSBpdCBhcHByb3ByaWF0ZWx5ICovCiAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtSGFuZGxlRW1wdHlTY2FuUmVzdWx0KHBNYWMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU46CiAgICAgICAgICAgICAgICBpZiAoIXRlbXBWYWwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJObyBjYW5kaWRhdGUgZm91bmQgYWZ0ZXIgc2Nhbm5pbmciCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbiBzdGF0ZSAlcyAuLiAiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICAgICAgICAgIC8qIFN0b3AgdGhlIHRpbWVyIGhlcmUgYXMgdGhlIHNhbWUgdGltZXIgd2lsbCBiZSBzdGFydGVkIGFnYWluIGluIENGR19DSEFOX1NDQU5fU1RBVEUgKi8KICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbihwTWFjKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIC8vIENhbiBjb21lIG9ubHkgaW4gSU5JVCBzdGF0ZS4gV2hlcmUgaW4gd2UgYXJlIGFzc29jaWF0ZWQsIHdlIHNlbnQgc2NhbiBhbmQgdXNlcgogICAgICAgICAgICAgICAgLy8gaW4gdGhlIG1lYW50aW1lIGRlY2lkZXMgdG8gZGlzYXNzb2MsIHdlIHdpbGwgYmUgaW4gaW5pdCBzdGF0ZSBhbmQgc3RpbGwgcmVjZWl2ZWQgY2FsbAogICAgICAgICAgICAgICAgLy8gYmFjayBpc3N1ZWQuIFNob3VsZCBub3QgY29tZSBoZXJlIGluIGFueSBvdGhlciBzdGF0ZSwgcHJpbnRpbmcganVzdCBpbiBjYXNlCiAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJTdGF0ZSAlcyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKSk7CgogICAgICAgICAgICAgICAgLy8gTGV0cyBqdXN0IGV4aXQgb3V0IHNpbGVudGx5LgogICAgICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIH0KI2VuZGlmCgogICAgICAgIGlmICh0ZW1wVmFsKQogICAgICAgIHsKICAgICAgICAgICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwoKICAgICAgICAgICAgaWYgKHJvYW1Ob3cpCiAgICAgICAgICAgIHsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICAgICAgaWYoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgICAgICB7CiNlbmRpZgogICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsCiAgICAgICAgICAgICAgICAgICAgICBGTCgiSW1tZWRpYXRlIHJvYW0tZGVyZWdpc3RlciBVUCBpbmRpY2F0aW9uLiBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSkpOwoKICAgICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX1VQLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CgogICAgICAgICAgICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLAogICAgICAgICAgICAgICAgICAgICAgICAgIEZMKCJDb3VsZG4ndCBkZXJlZ2lzdGVyIGxvb2t1cCBVUCBjYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgICAgICAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICAgIH0KI2VuZGlmCgogICAgICAgICAgICAgICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyaWdnZXJIYW5kb2ZmKHBNYWMscE5laWdoYm9yUm9hbUluZm8pOwogICAgICAgICAgICAgICAgaWYoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiY3NyTmVpZ2hib3JSb2FtVHJpZ2dlckhhbmRvZmYgZmFpbCBzdGF0dXMgPSAlZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBoc3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgICAgICB9CgogICAgICAgIGhzdGF0dXMgPSB2b3NfdGltZXJfc3RhcnQoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIsCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlc3VsdHNSZWZyZXNoUGVyaW9kKTsKCiAgICAgICAgICAgLyogVGhpcyB0aW1lciBzaG91bGQgYmUgc3RhcnRlZCBiZWZvcmUgcmVnaXN0ZXJpbmcgdGhlIFJlYXNzb2MgY2FsbGJhY2sgd2l0aCBUTC4gVGhpcyBpcyBiZWNhdXNlLCBpdCBpcyB2ZXJ5IGxpa2VseSAKICAgICAgICAgICAgKiB0aGF0IHRoZSBjYWxsYmFjayBnZXR0aW5nIGNhbGxlZCBpbW1lZGlhdGVseSBhbmQgdGhlIHRpbWVyIHdvdWxkIG5ldmVyIGJlIHN0b3BwZWQgd2hlbiBwcmUtYXV0aCBpcyBpbiBwcm9ncmVzcyAqLwogICAgICAgIGlmKCBoc3RhdHVzICE9IGVIQUxfU1RBVFVTX1NVQ0NFU1MpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXN1bHRzIHJlZnJlc2ggdGltZXIgZmFpbGVkIHRvIHN0YXJ0LCBzdGF0dXMgPSAlZCIpLCBoc3RhdHVzKTsKICAgICAgICAgICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICB9CgogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJSZWdpc3RlcmluZyBET1dOIGV2ZW50IFJlYXNzb2MgY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSk7CiAgICAgICAgICAgIC8qIFJlZ2lzdGVyIGEgcmVhc3NvYyBJbmRpY2F0aW9uIGNhbGxiYWNrICovCiAgICAgICAgICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgIH0KIAogICAgICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgIGlmIChjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCF0ZW1wVmFsIHx8ICFyb2FtTm93KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZigoZVNNRV9ST0FNX1RSSUdHRVJfU0NBTiA9PSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSB8fAogICAgICAgICAgICAgICAgICAgKGVTTUVfUk9BTV9UUklHR0VSX0ZBU1RfUk9BTSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUm9hbUVuKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvL1RoaXMgaXMgaW9jdGwgYmFzZWQgcm9hbWluZyBpZiB3ZSBkaWQgbm90IGZpbmQgYW55IHJvYW1hYmxlCiAgICAgICAgICAgICAgICAgICAgLy9jYW5kaWRhdGUgdGhlbiBqdXN0IGxvZyBpdC4KICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UoIFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGVtcFZhbCA9ICV1LCByb2FtTm93ID0gJWQgdU9zUmVxdWVzdGVkSGFuZG9mZiA9ICVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBWYWwsIHJvYW1Ob3csIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0gpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFKCBWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJObyA1RyBjYW5kaWRhdGUgZm91bmQgdGVtcFZhbD0ldSwgcm9hbU5vdz0lZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wVmFsLCByb2FtTm93KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfU1RBUlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUFTT05fTk9fQ0FORF9GT1VORF9PUl9OT1RfUk9BTUlOR19OT1cpOwogICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBUaGVyZSBpcyBubyBjYW5kaWRhdGUgb3IgV2UgYXJlIG5vdCByb2FtaW5nIE5vdy4KICAgICAgICAgICAgICAgICAgICAgICAgICogSW5mb3JtIHRoZSBGVyB0byByZXN0YXJ0IFJvYW0gT2ZmbG9hZCBTY2FuICAqLwogICAgICAgICAgICAgICAgICAgICAgICBjc3JSb2FtT2ZmbG9hZFNjYW4ocE1hYywgUk9BTV9TQ0FOX09GRkxPQURfUkVTVEFSVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQVNPTl9OT19DQU5EX0ZPVU5EX09SX05PVF9ST0FNSU5HX05PVyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEKTsKICAgICAgICAgICAgfQogICAgICAgIH0KI2VuZGlmCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1TY2FuUmVxdWVzdENhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHRoZSBjYWxsYmFjayBmdW5jdGlvbiByZWdpc3RlcmVkIGluIGNzclNjYW5SZXF1ZXN0KCkgdG8gCiAgICAgICAgICAgIGluZGljYXRlIHRoZSBjb21wbGV0aW9uIG9mIHNjYW4uIElmIHNjYW4gaXMgY29tcGxldGVkIGZvciBhbGwgdGhlIGNoYW5uZWxzIGluIAogICAgICAgICAgICB0aGUgY2hhbm5lbCBsaXN0LCB0aGlzIGZ1bmN0aW9uIGdldHMgdGhlIHNjYW4gcmVzdWx0IGFuZCBzdGFydHMgdGhlIHJlZnJlc2ggcmVzdWx0cwogICAgICAgICAgICB0aW1lciB0byBhdm9pZCBoYXZpbmcgc3RhbGUgcmVzdWx0cy4gSWYgc2NhbiBpcyBub3QgY29tcGxldGVkIG9uIGFsbCB0aGUgY2hhbm5lbHMsCiAgICAgICAgICAgIGl0IHJlc3RhcnRzIHRoZSBuZWlnaGJvciBzY2FuIHRpbWVyIHdoaWNoIG9uIGV4cGlyeSBpc3N1ZXMgc2NhbiBvbiB0aGUgbmV4dCAKICAgICAgICAgICAgY2hhbm5lbAoKICAgIFxwYXJhbSAgaGFsSGFuZGxlIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwQ29udGV4dCAtIG5vdCB1c2VkCiAgICAgICAgICAgIHNjYW5JZCAtIG5vdCB1c2VkCiAgICAgICAgICAgIHN0YXR1cyAtIG5vdCB1c2VkCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVNjYW5SZXF1ZXN0Q2FsbGJhY2sodEhhbEhhbmRsZSBoYWxIYW5kbGUsIHZvaWQgKnBDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VMzIgc2NhbklkLCBlQ3NyU2NhblN0YXR1cyBzdGF0dXMpCnsKICAgIHRwQW5pU2lyR2xvYmFsICAgICAgICAgICAgICAgICAgcE1hYyA9ICh0cEFuaVNpckdsb2JhbCkgaGFsSGFuZGxlOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0QU5JX1U4ICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRDaGFuSW5kZXg7CiAgICBlSGFsU3RhdHVzICAgICAgICAgICAgICBoc3RhdHVzOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgdEFOSV9VMzIgc2Vzc2lvbklkID0gQ1NSX1NFU1NJT05fSURfSU5WQUxJRDsKCiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgIHsKICAgICAgICBzZXNzaW9uSWQgPSAqKCh0QU5JX1UzMiopcENvbnRleHQpOwoKICAgICAgICBpZiAoIWNzclJvYW1Jc1N0YU1vZGUocE1hYywgc2Vzc2lvbklkKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiSWdub3Jpbmcgc2NhbiByZXF1ZXN0IGNhbGxiYWNrIG9uIG5vbi1pbmZyYSIKICAgICAgICAgICAgICAgICAgICJzZXNzaW9uICVkIGluIHN0YXRlICVzIiksCiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkLCBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLHNlc3Npb25JZCkpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIHdoZW4gZmFzdCByb2FtIGlzIGRpc2FibGVkLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgICAgIH0KICAgIH0KI2VuZGlmCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uc2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAKICAgIC8qIFRoaXMgY2FuIGhhcHBlbiB3aGVuIHdlIHJlY2VpdmUgYSBVUCBldmVudCBmcm9tIFRMIGluIGFueSBvZiB0aGUgc2NhbiBzdGF0ZXMuIFNpbGVudGx5IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgPT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlLiBNdXN0IGJlIGJlY2F1c2UgYSBVUCBldmVudCBmcm9tIFRMIGFmdGVyIGlzc3Vpbmcgc2NhbiByZXF1ZXN0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICAvKiAtMSBpcyBkb25lIGJlY2F1c2UgdGhlIGNoYW5JbmRleCB3b3VsZCBoYXZlIGdvdCBpbmNyZW1lbnRlZCBhZnRlciBpc3N1aW5nIGEgc3VjY2Vzc2Z1bCBzY2FuIHJlcXVlc3QgKi8KICAgIGN1cnJlbnRDaGFuSW5kZXggPSAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4KSA/IChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggLSAxKSA6IDA7CgogICAgLyogVmFsaWRhdGUgaW5wdXRzICovCiAgICBpZiAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KSB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiY3NyTmVpZ2hib3JSb2FtU2NhblJlcXVlc3RDYWxsYmFjayByZWNlaXZlZCBmb3IgQ2hhbm5lbCA9ICVkLCBDaGFuSW5kZXggPSAlZCIpLAogICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdFtjdXJyZW50Q2hhbkluZGV4XSwgY3VycmVudENoYW5JbmRleCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJSZWNlaXZlZCBkdXJpbmcgY2xlYW4tdXAuIFNpbGVudGx5IGlnbm9yZSBzY2FuIGNvbXBsZXRpb24gZXZlbnQuIikpOwogICAgICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgaWYgKGVBTklfQk9PTEVBTl9GQUxTRSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MpCiAgICB7CiAgICAgICAgLyogU2NhbiBpcyBjb21wbGV0ZWQgaW4gdGhlICBDRkdfQ0hBTl9TQ0FOIHN0YXRlLiBXZSBjYW4gdHJhbnNpdGlvbiB0byBSRVBPUlRfU0NBTiBzdGF0ZQogICAgICAgICAgIGp1c3QgdG8gZ2V0IHRoZSByZXN1bHRzIGFuZCBwZXJmb3JtIFBSRUFVVEggKi8KICAgICAgICAvKiBOb3cgd2UgaGF2ZSBjb21wbGV0ZWQgc2Nhbm5pbmcgdGhlIGNoYW5uZWwgbGlzdC4gV2UgaGF2ZSBnZXQgdGhlIHJlc3VsdCBieSBhcHBseWluZyBhcHByb3ByaWF0ZSBmaWx0ZXIKICAgICAgICAgICBzb3J0IHRoZSByZXN1bHRzIGJhc2VkIG9uIG5laWdoYm9yU2NvcmUgYW5kIFJTU0kgYW5kIHNlbGVjdCB0aGUgYmVzdCBjYW5kaWRhdGUgb3V0IG9mIHRoZSBsaXN0ICovCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiQ2hhbm5lbCBsaXN0IHNjYW4gY29tcGxldGVkLiBDdXJyZW50IGNoYW4gaW5kZXggPSAlZCIpLCBjdXJyZW50Q2hhbkluZGV4KTsKICAgICAgICBWT1NfQVNTRVJUKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9PSAwKTsKCiAgICAgICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUocE1hYyk7CgogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gcHJvY2VzcyBjb21wbGV0ZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgaHN0YXR1cyk7CiAgICAgICAgICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewoKICAgICAgICAvKiBSZXN0YXJ0IHRoZSB0aW1lciBmb3IgdGhlIG5leHQgc2NhbiBzZXF1ZW5jZSBhcyBzY2FubmluZyBpcyBub3Qgb3ZlciAqLwogICAgICAgIGhzdGF0dXMgPSB2b3NfdGltZXJfc3RhcnQoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lciwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yU2NhblBlcmlvZCk7CiAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgICAgICB7CiAgICAgICAgICAgIC8qIFRpbWVyIHN0YXJ0IGZhaWxlZC4uIFNob3VsZCB3ZSBBU1NFUlQgaGVyZT8/PyAqLwogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gUEFMIFRpbWVyIHN0YXJ0IGZhaWxlZCwgc3RhdHVzID0gJWQsIElnbm9yaW5nIHN0YXRlIHRyYW5zaXRpb24iKSwgc3RhdHVzKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICAgICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CgojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1TY2FuUmVzdWx0UmVxdWVzdENhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHRoZSBjYWxsYmFjayBmdW5jdGlvbiByZWdpc3RlcmVkIGluIGNzclNjYW5SZXF1ZXN0TGZyUmVzdWx0KCkgdG8KICAgICAgICAgICAgaW5kaWNhdGUgdGhlIGNvbXBsZXRpb24gb2Ygc2Nhbi4gSWYgc2NhbiBpcyBjb21wbGV0ZWQgZm9yIGFsbCB0aGUgY2hhbm5lbHMgaW4KICAgICAgICAgICAgdGhlIGNoYW5uZWwgbGlzdCwgdGhpcyBmdW5jdGlvbiBnZXRzIHRoZSBzY2FuIHJlc3VsdCBhbmQgdHJlYXRzIHRoZW0gYXMgY2FuZGlkYXRlcwoKICAgIFxwYXJhbSAgaGFsSGFuZGxlIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwQ29udGV4dCAtIG5vdCB1c2VkCiAgICAgICAgICAgIHNjYW5JZCAtIG5vdCB1c2VkCiAgICAgICAgICAgIHN0YXR1cyAtIG5vdCB1c2VkCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnN0YXRpYyBlSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVNjYW5SZXN1bHRSZXF1ZXN0Q2FsbGJhY2sodEhhbEhhbmRsZSBoYWxIYW5kbGUsIHZvaWQgKnBDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTMyIHNjYW5JZCwgZUNzclNjYW5TdGF0dXMgc3RhdHVzKQp7CiAgICB0cEFuaVNpckdsb2JhbCAgICAgICAgICAgICAgICAgIHBNYWMgPSAodHBBbmlTaXJHbG9iYWwpIGhhbEhhbmRsZTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgICAgICAgICAgICAgaHN0YXR1czsKCiAgICBzbXNMb2cocE1hYywgTE9HMiwgRkwoImNhbGxlZCAiKSk7CiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uc2NhblJzcFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgLyogd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQgKi8KICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIlJlY2VpdmVkIGluIG5vdCBDT05ORUNURUQgc3RhdGUuIElnbm9yZSBpdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICAvKiBOb3cgd2UgaGF2ZSBjb21wbGV0ZWQgc2Nhbm5pbmcgdGhlIGNoYW5uZWwgbGlzdC4gV2UgaGF2ZSBnZXQgdGhlIHJlc3VsdCBieSBhcHBseWluZyBhcHByb3ByaWF0ZSBmaWx0ZXIKICAgICAgIHNvcnQgdGhlIHJlc3VsdHMgYmFzZWQgb24gbmVpZ2hib3JTY29yZSBhbmQgUlNTSSBhbmQgc2VsZWN0IHRoZSBiZXN0IGNhbmRpZGF0ZSBvdXQgb2YgdGhlIGxpc3QgKi8KCiAgICBoc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc1NjYW5Db21wbGV0ZShwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBoc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTmVpZ2hib3Igc2NhbiBwcm9jZXNzIGNvbXBsZXRlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CiNlbmRpZiAvL1dMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKc3RhdGljIGVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtRm9yY2VSb2FtVG81R2hTY2FuQ2IodEhhbEhhbmRsZSBoYWxIYW5kbGUsCiAgICAgICAgdm9pZCAqcENvbnRleHQsIHRBTklfVTMyIHNjYW5JZCwgZUNzclNjYW5TdGF0dXMgc3RhdHVzKQp7CiAgICB0cEFuaVNpckdsb2JhbCAgICAgICAgICAgICAgICAgIHBNYWMgPSAodHBBbmlTaXJHbG9iYWwpIGhhbEhhbmRsZTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBoc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRBTklfVTMyIHNlc3Npb25JZCA9IENTUl9TRVNTSU9OX0lEX0lOVkFMSUQ7CgogICAgaWYgKE5VTEwgIT0gcENvbnRleHQpCiAgICB7CiAgICAgICAgc2Vzc2lvbklkID0gKigodEFOSV9VMzIqKXBDb250ZXh0KTsKICAgICAgICBpZiAoIWNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLHNlc3Npb25JZCkpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIHdoZW4gZmFzdCByb2FtIGlzIGRpc2FibGVkLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgICAgIGhzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICBnb3RvIGVuZDsKICAgICAgICB9CiAgICB9CgogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwoKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIG5laWdoYm9yUm9hbVN0YXRlICVkIC4gSWdub3JlIGl0IiksCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpOwogICAgICAgIGhzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgIGdvdG8gZW5kOwogICAgfQoKICAgIC8va2VlcCB0cmFjayBvZiBmb3JjZWQgNUcgc2NhbiAmIHJvYW0gaXMgZHVlIHRvIEZvcmNlZCBpbml0aWFsIHJvYW0gdG8gNUdIegogICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCA9IDE7CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCAiJXM6IHByb2Nlc3Mgc2NhbiByZXN1bHRzIiwgX19mdW5jX18pOwogICAgaHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVByb2Nlc3NTY2FuQ29tcGxldGUocE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gaHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkZvcmNlIFJvYW0gVG8gNUdoU2NhbkNiIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLAogICAgICAgIGhzdGF0dXMpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pc0ZvcmNlZEluaXRpYWxSb2FtVG81R0ggPSAwOwogICAgICAgIC8qCiAgICAgICAgICogU2VuZCBSU08gc3RhcnQgYmVjYXVzZSBpbiBjYXNlIDVHIHJvYW1pbmcgaG9zdCBoYXZlCiAgICAgICAgICogbm90IGVuYWJsZWQgYXQgaW5pdGlhbCBjb25uZWN0aW9uCiAgICAgICAgICovCiAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEKTsKICAgIH0KCiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgcmV0dXJuIGhzdGF0dXM7CgplbmQ6CiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgcmV0dXJuIGhzdGF0dXM7Cn0KI2VuZGlmCgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgpzdGF0aWMgZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Db250aWd1b3VzU2NhblJlcXVlc3RDYWxsYmFjayh0SGFsSGFuZGxlIGhhbEhhbmRsZSwKICAgICAgICB2b2lkICpwQ29udGV4dCwgdEFOSV9VMzIgc2NhbklkLCBlQ3NyU2NhblN0YXR1cyBzdGF0dXMpCnsKICAgIHRwQW5pU2lyR2xvYmFsICAgICAgICAgICAgICAgICAgcE1hYyA9ICh0cEFuaVNpckdsb2JhbCkgaGFsSGFuZGxlOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzIGhzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdEFOSV9VMzIgc2Vzc2lvbklkID0gQ1NSX1NFU1NJT05fSURfSU5WQUxJRDsKCiAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgIHsKICAgICAgICBzZXNzaW9uSWQgPSAqKCh0QU5JX1UzMiopcENvbnRleHQpOwogICAgICAgIGlmICghY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsc2Vzc2lvbklkKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgd2hlbiBmYXN0IHJvYW0gaXMgZGlzYWJsZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKHBDb250ZXh0KTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQogICAgfQoKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICAvKiBUaGlzIGNhbiBoYXBwZW4gd2hlbiB3ZSByZWNlaXZlIGEgVVAgZXZlbnQgZnJvbSBUTCBpbiBhbnkgb2YgdGhlIHNjYW4gc3RhdGVzLiBTaWxlbnRseSBpZ25vcmUgaXQgKi8KICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIENPTk5FQ1RFRCBzdGF0ZS4gTXVzdCBiZSBiZWNhdXNlIGEgVVAgZXZlbnQgZnJvbSBUTCBhZnRlciBpc3N1aW5nIHNjYW4gcmVxdWVzdC4gSWdub3JlIGl0IikpOwogICAgICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIElOSVQgc3RhdGUuIE11c3QgaGF2ZSBkaXNjb25uZWN0ZWQuIElnbm9yZSBpdCIpKTsKICAgICAgICBpZiAoTlVMTCAhPSBwQ29udGV4dCkKICAgICAgICAgICB2b3NfbWVtX2ZyZWUocENvbnRleHQpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgfQoKICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIiVzOiBwcm9jZXNzIHNjYW4gcmVzdWx0cyIsIF9fZnVuY19fKTsKICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlKHBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHByb2Nlc3MgY29tcGxldGUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIGhzdGF0dXMpOwogICAgfQoKICAgIGlmIChOVUxMICE9IHBDb250ZXh0KQogICAgICAgIHZvc19tZW1fZnJlZShwQ29udGV4dCk7CgogICAgcmV0dXJuIGhzdGF0dXM7Cn0KI2VuZGlmCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXNzdWVCZ1NjYW5SZXF1ZXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzc3VlcyBDU1Igc2NhbiByZXF1ZXN0IGFmdGVyIHBvcHVsYXRpbmcgYWxsIHRoZSBCRyBzY2FuIHBhcmFtcyAKICAgICAgICAgICAgcGFzc2VkCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwQmdTY2FuUGFyYW1zIC0gUGFyYW1zIHRoYXQgbmVlZCB0byBiZSBwb3B1bGF0ZWQgaW50byBjc3IgU2NhbiByZXF1ZXN0CgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSXNzdWVCZ1NjYW5SZXF1ZXN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0Q3NyQkdTY2FuUmVxdWVzdCAqcEJnU2NhblBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdEFOSV9VMzIgc2Vzc2lvbklkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JTY2FuQ29tcGxldGVDYWxsYmFjayBjYWxsYmFja2ZuKQp7CiAgICBlSGFsU3RhdHVzIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0QU5JX1UzMiBzY2FuSWQ7CiAgICB0Q3NyU2NhblJlcXVlc3Qgc2NhblJlcTsKICAgIHRBTklfVTggY2hhbm5lbDsKICAgIHZvaWQgKiB1c2VyRGF0YSA9IE5VTEw7CiAgICAKICAgIGlmICgxID09IHBCZ1NjYW5QYXJhbXMtPkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMpCiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dXLCBGTCgiQ2hhbm5lbCA9ICVkLCBDaGFuSW5kZXggPSAlZCIpLAogICAgICAgICAgICBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5DaGFubmVsTGlzdFswXSwgCiAgICAgICAgICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCk7CgogICAgLy9zZW5kIGRvd24gdGhlIHNjYW4gcmVxIGZvciAxIGNoYW5uZWwgb24gdGhlIGFzc29jaWF0ZWQgU1NJRAogICAgdm9zX21lbV9zZXQoJnNjYW5SZXEsIHNpemVvZih0Q3NyU2NhblJlcXVlc3QpLCAwKTsKICAgIC8qIEZpbGwgaW4gdGhlIFNTSUQgSW5mbyAqLwogICAgc2NhblJlcS5TU0lEcy5udW1PZlNTSURzID0gMTsKICAgIHNjYW5SZXEuU1NJRHMuU1NJRExpc3QgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodENzclNTSURJbmZvKSAqIHNjYW5SZXEuU1NJRHMubnVtT2ZTU0lEcyk7CiAgICBpZiAoTlVMTCA9PSBzY2FuUmVxLlNTSURzLlNTSURMaXN0KQogICAgewogICAgICAgLy9lcnIgbXNnCiAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkNvdWxkbid0IGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIFNTSUQuLkZyZWVpbmcgbWVtb3J5IGFsbG9jYXRlZCBmb3IgQ2hhbm5lbCBMaXN0IikpOwogICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICB2b3NfbWVtX3plcm8oc2NhblJlcS5TU0lEcy5TU0lETGlzdCwgc2l6ZW9mKHRDc3JTU0lESW5mbykgKiBzY2FuUmVxLlNTSURzLm51bU9mU1NJRHMpOwoKICAgIHNjYW5SZXEuU1NJRHMuU1NJRExpc3RbMF0uaGFuZG9mZlBlcm1pdHRlZCA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgc2NhblJlcS5TU0lEcy5TU0lETGlzdFswXS5zc2lkSGlkZGVuID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICB2b3NfbWVtX2NvcHkoKHZvaWQgKikmc2NhblJlcS5TU0lEcy5TU0lETGlzdFswXS5TU0lELCAodm9pZCAqKSZwQmdTY2FuUGFyYW1zLT5TU0lELCBzaXplb2YocEJnU2NhblBhcmFtcy0+U1NJRCkpOwogICAgCiAgICBzY2FuUmVxLkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgPSBwQmdTY2FuUGFyYW1zLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzOwogICAgaWYgKDEgPT0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgIHsKICAgICAgICBjaGFubmVsID0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3RbMF07CiAgICAgICAgc2NhblJlcS5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9ICZjaGFubmVsOyAgICAKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzY2FuUmVxLkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3Q7CiAgICB9CgogICAgc2NhblJlcS5CU1NUeXBlID0gZUNTUl9CU1NfVFlQRV9JTkZSQVNUUlVDVFVSRTsKICAgIHNjYW5SZXEuc2NhblR5cGUgPSBlU0lSX0FDVElWRV9TQ0FOOwogICAgc2NhblJlcS5yZXF1ZXN0VHlwZSA9IGVDU1JfU0NBTl9IT19CR19TQ0FOOwogICAgc2NhblJlcS5tYXhDaG5UaW1lID0gcEJnU2NhblBhcmFtcy0+bWF4Q2huVGltZTsKICAgIHNjYW5SZXEubWluQ2huVGltZSA9IHBCZ1NjYW5QYXJhbXMtPm1pbkNoblRpbWU7CgogICAgdXNlckRhdGEgPSB2b3NfbWVtX21hbGxvYyhzaXplb2YodEFOSV9VMzIpKTsKICAgIGlmIChOVUxMID09IHVzZXJEYXRhKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiRmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeSBmb3Igc2NhbiByZXF1ZXN0IikpOwogICAgICAgIHZvc19tZW1fZnJlZShzY2FuUmVxLlNTSURzLlNTSURMaXN0KTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgICooKHRBTklfVTMyKil1c2VyRGF0YSkgPSBzZXNzaW9uSWQ7CiAgICBzdGF0dXMgPSBjc3JTY2FuUmVxdWVzdChwTWFjLCBDU1JfU0VTU0lPTl9JRF9JTlZBTElELCAmc2NhblJlcSwKICAgICAgICAgICAgICAgICAgICAgICAgJnNjYW5JZCwgY2FsbGJhY2tmbiwgKHZvaWQgKikgdXNlckRhdGEpOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQ1NSIFNjYW4gUmVxdWVzdCBmYWlsZWQgd2l0aCBzdGF0dXMgJWQiKSwgc3RhdHVzKTsKICAgICAgICB2b3NfbWVtX2ZyZWUoc2NhblJlcS5TU0lEcy5TU0lETGlzdCk7CiAgICAgICAgdm9zX21lbV9mcmVlKHVzZXJEYXRhKTsKICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX1RSVUU7CgogICAgdm9zX21lbV9mcmVlKHNjYW5SZXEuU1NJRHMuU1NJRExpc3QpOwogICAgaWYgKDEgPT0gcEJnU2NhblBhcmFtcy0+Q2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJDaGFubmVsIExpc3QgQWRkcmVzcyA9ICVwLCBBY3R1YWwgaW5kZXggPSAlZCIpLAogICAgICAgICAgICAgICAgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdFswXSwgCiAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ucm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgpOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCnN0YXRpYyB2b2lkIGNzck5laWdoYm9yUm9hbUZpbGxOb25DaGFubmVsQmdTY2FuUGFyYW1zICh0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwQ3NyQkdTY2FuUmVxdWVzdCBiZ1NjYW5QYXJhbXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCAgICAgICAgICAgICBicm9hZGNhc3RCc3NpZFtdID0geyAweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGLCAweEZGIH07CgogICAgdm9zX21lbV9jb3B5KGJnU2NhblBhcmFtcy0+YnNzaWQsIGJyb2FkY2FzdEJzc2lkLCBzaXplb2YodENzckJzc2lkKSk7CiAgICBiZ1NjYW5QYXJhbXMtPlNTSUQubGVuZ3RoID0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQubGVuZ3RoOwogICAgdm9zX21lbV9jb3B5KGJnU2NhblBhcmFtcy0+U1NJRC5zc0lkLCAKICAgICAgICBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3BOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuU1NJRC5zc0lkLAogICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELmxlbmd0aCk7CgogICAgYmdTY2FuUGFyYW1zLT5taW5DaG5UaW1lID0gcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5taW5DaGFubmVsU2NhblRpbWU7CiAgICBiZ1NjYW5QYXJhbXMtPm1heENoblRpbWUgPSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heENoYW5uZWxTY2FuVGltZTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVBlcmZvcm1CZ1NjYW4KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgaW52b2tlZCBvbiBldmVyeSBleHBpcnkgb2YgbmVpZ2hib3JTY2FuVGltZXIgdGlsbCBhbGwgCiAgICAgICAgICAgIHRoZSBjaGFubmVscyBpbiB0aGUgY2hhbm5lbCBsaXN0IGFyZSBzY2FubmVkLiBJdCBwb3B1bGF0ZXMgbmVjZXNzYXJ5IAogICAgICAgICAgICBwYXJhbWV0ZXJzIGZvciBCRyBzY2FuIGFuZCBjYWxscyBhcHByb3ByaWF0ZSBBUCB0byBpbnZva2UgdGhlIENTUiBzY2FuIAogICAgICAgICAgICByZXF1ZXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVBlcmZvcm1CZ1NjYW4odHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VMzIgc2Vzc2lvbklkKQp7CiAgICBlSGFsU3RhdHVzICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdENzckJHU2NhblJlcXVlc3QgICBiZ1NjYW5QYXJhbXM7CiAgICB0QU5JX1U4ICAgICAgICAgICAgIGNoYW5uZWwgPSAwOwoKICAgIGlmICggcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ICYmCiAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzICkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJDaGFubmVsIExpc3QgQWRkcmVzcyA9ICVwIiksICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3RbMF0pOwogICAgfQogICAgZWxzZSAKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJDaGFubmVsIExpc3QgRW1wdHkiKSk7CiAgICAgICAgLy8gR28gYmFjayBhbmQgcmVzdGFydC4gTW9zdGx5IHRpbWVyIHN0YXJ0IGZhaWx1cmUgaGFzIG9jY3VycmVkLgogICAgICAgIC8vIFdoZW4gdGltZXIgc3RhcnQgaXMgZGVjbGFyZWQgYSBmYWlsdXJlLCB0aGVuIHdlIGRlbGV0ZSB0aGUgbGlzdC4KICAgICAgICAvLyBTaG91bGQgbm90IGhhcHBlbiBub3cgYXMgd2Ugc3RvcCBhbmQgdGhlbiBvbmx5IHN0YXJ0IHRoZSBzY2FuIHRpbWVyLiAKICAgICAgICAvLyBzdGlsbCBoYW5kbGUgdGhlIHVubGlrZWx5IGNhc2UuCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtSGFuZGxlRW1wdHlTY2FuUmVzdWx0KHBNYWMpOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CgogICAgLyogVmFsaWRhdGUgdGhlIGN1cnJlbnRDaGFuSW5kZXggdmFsdWUgYmVmb3JlIHVzaW5nIGl0IHRvIGluZGV4IHRoZSBDaGFubmVsTGlzdCBhcnJheSAqLwogICAgaWYgKCBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXgKICAgICAgICAgICAgPiBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscykKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJJbnZhbGlkIGNoYW5uZWwgaW5kZXg6ICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCk7CiAgICAgICAgLy8gR28gYmFjayBhbmQgcmVzdGFydC4KICAgICAgICBjc3JOZWlnaGJvclJvYW1IYW5kbGVFbXB0eVNjYW5SZXN1bHQocE1hYyk7CiAgICAgICAgcmV0dXJuIHN0YXR1czsKICAgIH0KCiAgICAvKiBOZWVkIHRvIHBlcmZvcm0gc2NhbiBoZXJlIGJlZm9yZSBnZXR0aW5nIHRoZSBsaXN0ICovCgogICAgdm9zX21lbV9zZXQoJmJnU2NhblBhcmFtcywgc2l6ZW9mKHRDc3JCR1NjYW5SZXF1ZXN0KSwgMCk7CgogICAgY2hhbm5lbCA9IHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdFtwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXhdOwogICAgYmdTY2FuUGFyYW1zLkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgPSAxOwogICAgYmdTY2FuUGFyYW1zLkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gJmNoYW5uZWw7CgogICAgY3NyTmVpZ2hib3JSb2FtRmlsbE5vbkNoYW5uZWxCZ1NjYW5QYXJhbXMocE1hYywgJmJnU2NhblBhcmFtcyk7CgogICAgLyogVXBkYXRlIHRoZSBwYXNzaXZlIHNjYW4gdGltZSBmb3IgREZTIGNoYW5uZWwgKi8KICAgIGlmICgoVFJVRSA9PSBDU1JfSVNfQ0hBTk5FTF9ERlMoY2hhbm5lbCkpICYmCiAgICAgICAgIChUUlVFID09IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uYWxsb3dERlNDaGFubmVsUm9hbSkpCiAgICB7CiAgICAgICAgIGJnU2NhblBhcmFtcy5taW5DaG5UaW1lID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uUGFzc2l2ZU1pbkNoblRpbWU7CiAgICAgICAgIGJnU2NhblBhcmFtcy5tYXhDaG5UaW1lID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uUGFzc2l2ZU1heENoblRpbWU7CiAgICB9CgogICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVCZ1NjYW5SZXF1ZXN0KHBNYWMsICZiZ1NjYW5QYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbklkLCBjc3JOZWlnaGJvclJvYW1TY2FuUmVxdWVzdENhbGxiYWNrKTsKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIklzc3VlIG9mIEJHIFNjYW4gcmVxdWVzdCBmYWlsZWQ6IFN0YXR1cyA9ICVkIiksIHN0YXR1cyk7CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4Kys7CiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4ID49IAogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscykKICAgIHsgICAgICAKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJDb21wbGV0ZWQgc2Nhbm5pbmcgY2hhbm5lbHMgaW4gQ2hhbm5lbCBMaXN0OiBDdXJyQ2hhbkluZGV4ID0gJWQsIE51bSBDaGFubmVscyA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbkluZGV4LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyk7CiAgICAgICAgLyogV2UgaGF2ZSBjb21wbGV0ZWQgc2Nhbm5pbmcgYWxsIHRoZSBjaGFubmVscyAqLwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9IDA7CiAgICAgICAgLyogV2UgYXJlIG5vIGxvbmdlciBzY2FubmluZyB0aGUgY2hhbm5lbCBsaXN0LiBOZXh0IHRpbWVyIGZpcmluZyBzaG91bGQgYmUgdXNlZCB0byBnZXQgdGhlIHNjYW4gcmVzdWx0cyAKICAgICAgICAgICBhbmQgc2VsZWN0IHRoZSBiZXN0IEFQIGluIHRoZSBsaXN0ICovCiAgICAgICAgaWYgKGVBTklfQk9PTEVBTl9UUlVFID09IHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcykKICAgICAgICB7CiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY2hhbkxpc3RTY2FuSW5Qcm9ncmVzcyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIC8qCiAgICAgICAgICogSWYgdGhlIHN0YXR1cyBpcyBub3Qgc3VjY2Vzcywgd2UgbmVlZCB0byBjYWxsIHRoZSBjYWxsYmFjawogICAgICAgICAqIHJvdXRpbmUgc28gdGhhdCB0aGUgc3RhdGUgbWFjaGluZSBkb2VzIG5vdCBnZXQgc3R1Y2suCiAgICAgICAgICovCiAgICAgICAgY3NyTmVpZ2hib3JSb2FtU2NhblJlcXVlc3RDYWxsYmFjayhwTWFjLCBOVUxMLCAwLCBlQ1NSX1NDQU5fRkFJTFVSRSk7CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1TY2FuRm9ySW5pdGlhbEZvcmNlZDVHUm9hbWluZyh0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1UzMiBzZXNzaW9uSWQpCnsKICAgIGVIYWxTdGF0dXMgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdENzckJHU2NhblJlcXVlc3QgICBiZ1NjYW5QYXJhbXM7CiAgICB0QU5JX1U4ICAgbnVtT2ZDaGFubmVscyA9IDAsIGkgPSAwOwogICAgdEFOSV9VOCAgIHRlbXBDaGFubmVsTGlzdFtXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU5dOwogICAgdEFOSV9VOCAgIGNoYW5uZWxMaXN0W1dOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTl07CiAgICB0QU5JX1U4ICAgdGVtcE51bU9mQ2hhbm5lbHMgPSAwOwoKICAgIHZvc19tZW1fc2V0KCZiZ1NjYW5QYXJhbXMsIHNpemVvZih0Q3NyQkdTY2FuUmVxdWVzdCksIDApOwogICAgLyogQ29udGlndW91c2x5IHNjYW4gYWxsIGNoYW5uZWxzIGZyb20gdmFsaWQgbGlzdCAqLwogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCAiJXM6IGdldCB2YWxpZCBjaGFubmVsIGxpc3QiLCBfX2Z1bmNfXyk7CiAgICB0ZW1wTnVtT2ZDaGFubmVscyA9IHNpemVvZihwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QpOwoKICAgIGlmKEhBTF9TVEFUVVNfU1VDQ0VTUyhjc3JHZXRDZmdWYWxpZENoYW5uZWxzKHBNYWMsCiAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgKHRBTklfVTMyICopICZ0ZW1wTnVtT2ZDaGFubmVscykpKQogICAgewogICAgICAgIC8vTWFrZSBzdXJlIHdlIGFyZSBzY2FubmluZyBvbmx5IGZvciA1R2h6IEFQIG9ubHkKICAgICAgICAvL0ZpbGV0cmluZyBvdXQgdGhlIDVHSFogYmFzZWQgQVAuZnJvbSB2YWxpZCBjaGFubmVsIGxpc3QKICAgICAgICBjc3JOZWlnaGJvclJvYW1DaGFubmVsc0ZpbHRlckJ5QmFuZCgKICAgICAgICAgICAgICAgICAgICAgcE1hYywKICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICB0ZW1wTnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgdGVtcENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAmdGVtcE51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgIFNJUl9CQU5EXzVfR0haCiAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgZm9yIChpID0gMDsgKGkgPCB0ZW1wTnVtT2ZDaGFubmVscyAmJihpIDwgV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKSk7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIC8qIERGUyBjaGFubmVsIHdpbGwgYmUgYWRkZWQgaW4gdGhlIGxpc3Qgb25seSB3aGVuIHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgICBERlMgUm9hbWluZyBzY2FuIGZsYWcgaXMgZW5hYmxlZCovCiAgICAgICAgICAgIGlmIChDU1JfSVNfQ0hBTk5FTF9ERlModGVtcENoYW5uZWxMaXN0W2ldKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uYWxsb3dERlNDaGFubmVsUm9hbSA9PSBUUlVFKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0W251bU9mQ2hhbm5lbHMrK10gPSB0ZW1wQ2hhbm5lbExpc3RbaV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtudW1PZkNoYW5uZWxzKytdID0gdGVtcENoYW5uZWxMaXN0W2ldOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiY3NyR2V0Q2ZnVmFsaWRDaGFubmVscyBnb3QgZmFpbGVkICIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KCiAgICBpZihudW1PZkNoYW5uZWxzID09IDApCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgIEZMKCIgTm8gdmFsaWQgNUdoeiBjaGFubmVsIHByZXNlbnQgc28gc2tpcHBpbmcgSW5pdGlhbCBGb3JjZWQgNUdoIHJvYW1pbmciKSk7CiAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9FTVBUWTsKICAgIH0KICAgIGlmIChudW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgewogICAgICAgIG51bU9mQ2hhbm5lbHMgPSBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU47CiAgICB9CgogICAgYmdTY2FuUGFyYW1zLkNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMgPSBudW1PZkNoYW5uZWxzOwogICAgYmdTY2FuUGFyYW1zLkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gY2hhbm5lbExpc3Q7CiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtT2ZDaGFubmVsczsgaSsrKQogICAgewogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIiVzOiB2YWxpZCBjaGFubmVsIGxpc3QgPSAlZCIsCiAgICAgICAgICAgICAgICBfX2Z1bmNfXywgYmdTY2FuUGFyYW1zLkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0W2ldKTsKICAgIH0KICAgIGNzck5laWdoYm9yUm9hbUZpbGxOb25DaGFubmVsQmdTY2FuUGFyYW1zKHBNYWMsICZiZ1NjYW5QYXJhbXMpOwoKICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlQmdTY2FuUmVxdWVzdChwTWFjLCAmYmdTY2FuUGFyYW1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb25JZCwgY3NyTmVpZ2hib3JSb2FtRm9yY2VSb2FtVG81R2hTY2FuQ2IpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkZvcmNlZCBpbnRpYWwgcm9hbSB0byA1R2ggcmVxdWVzdCBmYWlsZWQ6IFN0YXR1cyA9ICVkIiksIHN0YXR1cyk7CiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CiNlbmRpZgoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1QZXJmb3JtQ29udGlndW91c0JnU2Nhbih0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1UzMiBzZXNzaW9uSWQpCnsKICAgIGVIYWxTdGF0dXMgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdENzckJHU2NhblJlcXVlc3QgICBiZ1NjYW5QYXJhbXM7CiAgICB0QU5JX1U4ICAgbnVtT2ZDaGFubmVscyA9IDAsIGkgPSAwOwogICAgdEFOSV9VOCAgICpjaGFubmVsTGlzdCA9IE5VTEw7CiAgICB0QU5JX1U4ICAgKnBJbkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgIHRBTklfVTggICB0bXBDaGFubmVsTGlzdFtXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU5dOwoKICAgIHZvc19tZW1fc2V0KCZiZ1NjYW5QYXJhbXMsIHNpemVvZih0Q3NyQkdTY2FuUmVxdWVzdCksIDApOwoKICAgIC8qIENvbnRpZ3VvdXNseSBzY2FuIGFsbCBjaGFubmVscyBmcm9tIHZhbGlkIGxpc3QgKi8KICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIiVzOiBnZXQgdmFsaWQgY2hhbm5lbCBsaXN0IiwgX19mdW5jX18pOwoKICAgIG51bU9mQ2hhbm5lbHMgPSBzaXplb2YocE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0KTsKCiAgICBpZighSEFMX1NUQVRVU19TVUNDRVNTKGNzckdldENmZ1ZhbGlkQ2hhbm5lbHMocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VOCAqKXBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VMzIgKikgJm51bU9mQ2hhbm5lbHMpKSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkNvdWxkIG5vdCBnZXQgdmFsaWQgY2hhbm5lbCBsaXN0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgcEluQ2hhbm5lbExpc3QgPSBwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3Q7CgogICAgaWYgKENTUl9JU19ST0FNX0lOVFJBX0JBTkRfRU5BQkxFRChwTWFjKSkKICAgIHsKICAgICAgICBjc3JOZWlnaGJvclJvYW1DaGFubmVsc0ZpbHRlckJ5QmFuZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBJbkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0UkZCYW5kKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSk7CiAgICAgICAgcEluQ2hhbm5lbExpc3QgPSB0bXBDaGFubmVsTGlzdDsKICAgIH0KCiAgICBjaGFubmVsTGlzdCA9IHZvc19tZW1fbWFsbG9jKG51bU9mQ2hhbm5lbHMpOwogICAgaWYgKCBOVUxMID09IGNoYW5uZWxMaXN0ICkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImNvdWxkIG5vdCBhbGxvY2F0ZSBtZW1vcnkgZm9yIGNoYW5uZWxMaXN0IikpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgdm9zX21lbV9jb3B5KGNoYW5uZWxMaXN0LCAodEFOSV9VOCAqKXBJbkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwoKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gbnVtT2ZDaGFubmVsczsKICAgIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IGNoYW5uZWxMaXN0OwogICAgZm9yIChpID0gMDsgaSA8IG51bU9mQ2hhbm5lbHM7IGkrKykKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICIlczogdmFsaWQgY2hhbm5lbCBsaXN0ID0gJWQiLAogICAgICAgICAgICAgICAgX19mdW5jX18sIGJnU2NhblBhcmFtcy5DaGFubmVsSW5mby5DaGFubmVsTGlzdFtpXSk7CiAgICB9CiAgICBjc3JOZWlnaGJvclJvYW1GaWxsTm9uQ2hhbm5lbEJnU2NhblBhcmFtcyhwTWFjLCAmYmdTY2FuUGFyYW1zKTsKCiAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Jc3N1ZUJnU2NhblJlcXVlc3QocE1hYywgJmJnU2NhblBhcmFtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uSWQsIGNzck5laWdoYm9yUm9hbUNvbnRpZ3VvdXNTY2FuUmVxdWVzdENhbGxiYWNrKTsKCiAgICB2b3NfbWVtX2ZyZWUoY2hhbm5lbExpc3QpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIklzc3VlIG9mIEJHIFNjYW4gcmVxdWVzdCBmYWlsZWQ6IFN0YXR1cyA9ICVkIiksIHN0YXR1cyk7CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQojZW5kaWYKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1OZWlnaGJvclNjYW5UaW1lckNhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHRoZSBuZWlnaGJvciBzY2FuIHRpbWVyIGNhbGxiYWNrIGZ1bmN0aW9uLiBJdCBpbnZva2VzIAogICAgICAgICAgICB0aGUgQkcgc2NhbiByZXF1ZXN0IGJhc2VkIG9uIHRoZSBjdXJyZW50IGFuZCBwcmV2aW91cyBzdGF0ZXMKCiAgICBccGFyYW0gIHB2IC0gQ1NSIHRpbWVyIGNvbnRleHQgaW5mbyB3aGljaCBpbmNsdWRlcyBwTWFjIGFuZCBzZXNzaW9uIElECgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbU5laWdoYm9yU2NhblRpbWVyQ2FsbGJhY2sodm9pZCAqcHYpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVCggcHYgKTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvOwogICAgaWYoIXBNYWMpCiAgICB7CiAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLCBGTCgicE1hYyBpcyBOdWxsIikpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICAvLyBjaGVjayBpZiBiZyBzY2FuIGlzIG9uIGdvaW5nLCBubyBuZWVkIHRvIHNlbmQgZG93biB0aGUgbmV3IHBhcmFtcyBpZiB0cnVlCiAgICBpZihlQU5JX0JPT0xFQU5fVFJVRSA9PSBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJzcFBlbmRpbmcpCiAgICB7CiAgICAgICAvL21zZwogICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJBbHJlYWR5IEJnU2NhblJzcCBpcyBQZW5kaW5nIikpOwogICAgICAgcmV0dXJuOwogICAgfQoKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTjoKICAgICAgICAgICAgc3dpdGNoKHBOZWlnaGJvclJvYW1JbmZvLT5wcmV2TmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWToKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1QZXJmb3JtQmdTY2FuKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gY2FsbGJhY2sgcmVjZWl2ZWQgaW4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgInN0YXRlICVzLCBwcmV2IHN0YXRlID0gJXMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cHJldk5laWdoYm9yUm9hbVN0YXRlKSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAqLwogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTjogICAgIAogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1QZXJmb3JtQmdTY2FuKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm47Cn0KCnZvaWQgY3NyTmVpZ2hib3JSb2FtRW1wdHlTY2FuUmVmcmVzaFRpbWVyQ2FsbGJhY2sodm9pZCAqY29udGV4dCkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKCBjb250ZXh0ICk7CiAgICBWT1NfU1RBVFVTICAgICB2b3NTdGF0dXMgPSBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbzsKICAgIGlmKCFwTWFjKQogICAgewogICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9FUlJPUiwgRkwoInBNYWMgaXMgTnVsbCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgLyogUmVzZXQgYWxsIHRoZSB2YXJpYWJsZXMganVzdCBhcyBubyBzY2FuIGhhZCBoYXBwZW5lZCBiZWZvcmUgKi8KICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKCiNpZiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICYmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSQogICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykgJiYgKHBNYWMtPnJybS5ycm1TbWVDb250ZXh0LnJybUNvbmZpZy5ycm1FbmFibGVkKSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCIxMVIgQXNzb2NpYXRpb246TmVpZ2hib3IgTG9va3VwIERvd24gZXZlbnQgcmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlIikpOwogICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHBNYWMpOwogICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVxdWVzdCBmYWlsZWQuIHN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgLyogSW5jcmVtZW50IHRoZSBuZWlnaGJvciByZXBvcnQgcmV0cnkgY291bnQgYWZ0ZXIgc2VuZGluZyB0aGUgbmVpZ2hib3IgcmVxdWVzdCBzdWNjZXNzZnVsbHkgKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSsrOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWSkKICAgIH0KICAgIGVsc2UKI2VuZGlmCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiTm9uIDExUiBvciBFU0UgQXNzb2NpYXRpb246ZW1wdHkgc2NhbiByZWZyZXNoIHRpbWVyIGV4cGlyZWQiKSk7CiAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4ocE1hYyk7CiAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtUmVzdWx0c1JlZnJlc2hUaW1lckNhbGxiYWNrCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHRoZSB0aW1lciBjYWxsYmFjayBmdW5jdGlvbiBmb3IgcmVzdWx0cyByZWZyZXNoIHRpbWVyLgogICAgICAgICAgICBXaGVuIHRoaXMgaXMgaW52b2tlZCwgaXQgaXMgYXMgZ29vZCBhcyBkb3duIGV2ZW50IHJlY2VpdmVkIGZyb20gVEwuIFNvLCAKICAgICAgICAgICAgY2xlYXIgb2ZmIHRoZSByb2FtYWJsZSBBUCBsaXN0IGFuZCBzdGFydCB0aGUgc2NhbiBwcm9jZWR1cmUgYmFzZWQgb24gMTFSIAogICAgICAgICAgICBvciBub24tMTFSIGFzc29jaWF0aW9uCgogICAgXHBhcmFtICBjb250ZXh0IC0gQ1NSIHRpbWVyIGNvbnRleHQgaW5mbyB3aGljaCBpbmNsdWRlcyBwTWFjIGFuZCBzZXNzaW9uIElECgogICAgXHJldHVybiBWT0lECgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVJlc3VsdHNSZWZyZXNoVGltZXJDYWxsYmFjayh2b2lkICpjb250ZXh0KQp7CiAgICB0cEFuaVNpckdsb2JhbCBwTWFjID0gUE1BQ19TVFJVQ1QoIGNvbnRleHQgKTsKICAgIFZPU19TVEFUVVMgICAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gIHBOZWlnaGJvclJvYW1JbmZvOwoKICAgIGlmKCFwTWFjKQogICAgewogICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9FUlJPUiwgRkwoInBNYWMgaXMgTnVsbCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiRGVyZWdpc3RlcmluZyBET1dOIGV2ZW50IHJlYXNzb2MgY2FsbGJhY2sgd2l0aCBUTC4gUlNTSSA9ICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSk7CgogICAgLyogRGVyZWdpc3RlciByZWFzc29jIGNhbGxiYWNrLiBJZ25vcmUgcmV0dXJuIHN0YXR1cyAqLwogICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JSZWFzc29jVGhyZXNob2xkICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX0RPV04sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlYXNzb2NJbmRDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWT1NfTU9EVUxFX0lEX1NNRSk7CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgewogICAgICAgIC8vZXJyIG1zZwogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IGRlcmVnaXN0ZXIgY3NyTmVpZ2hib3JSb2FtUmVhc3NvY0luZENhbGxiYWNrIHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICB9CgogICAgLyogUmVzZXQgYWxsIHRoZSB2YXJpYWJsZXMganVzdCBhcyBubyBzY2FuIGhhZCBoYXBwZW5lZCBiZWZvcmUgKi8KICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKCiNpZiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICYmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSQogICAgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykgJiYgKHBNYWMtPnJybS5ycm1TbWVDb250ZXh0LnJybUNvbmZpZy5ycm1FbmFibGVkKSkKICAgIHsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCIxMVIgQXNzb2NpYXRpb246TmVpZ2hib3IgTG9va3VwIERvd24gZXZlbnQgcmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlIikpOwogICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0KHBNYWMpOwogICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVxdWVzdCBmYWlsZWQuIHN0YXR1cyA9ICVkIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgLyogSW5jcmVtZW50IHRoZSBuZWlnaGJvciByZXBvcnQgcmV0cnkgY291bnQgYWZ0ZXIgc2VuZGluZyB0aGUgbmVpZ2hib3IgcmVxdWVzdCBzdWNjZXNzZnVsbHkgKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSsrOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLm5laWdoYm9yUnB0UGVuZGluZyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWSkKICAgIH0KICAgIGVsc2UKI2VuZGlmICAgICAgCiAgICB7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiTm9uIDExUiBvciBFU0UgQXNzb2NpYXRpb246cmVzdWx0cyByZWZyZXNoIHRpbWVyIGV4cGlyZWQiKSk7CiAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4ocE1hYyk7CiAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyRm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyQ2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgdGhlIHRpbWVyIGNhbGxiYWNrIGZ1bmN0aW9uIGZvciB0cmlnZ2VyaW5nCiAgICAgICAgICAgICAgcm9hbWluZyB0byA1R0h6IGFmdGVyIHRoZSBpbml0aWFsIGFzc29jaWF0aW9uLgoKICAgIFxwYXJhbSAgY29udGV4dCAtIENTUiB0aW1lciBjb250ZXh0IGluZm8gd2hpY2ggaW5jbHVkZXMgcE1hYyBhbmQgc2Vzc2lvbiBJRAoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCnZvaWQgY3NyRm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyQ2FsbGJhY2sodm9pZCAqY29udGV4dCkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKCBjb250ZXh0ICk7CiAgICBlSGFsU3RhdHVzIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICBwTmVpZ2hib3JSb2FtSW5mbzsKICAgIGlmKCFwTWFjKQogICAgewogICAgICAgIFZPU19UUkFDRSAoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9FUlJPUiwgRkwoInBNYWMgaXMgTnVsbCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CgogICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0dFLCBGTCgiZm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyIHRpbWVyIGV4cGlyZWQiKSk7CgogICAgLy93ZSBkb24ndCBuZWVkIHRvIHJ1biB0aGlzIHRpbWVyIGFueSBtb3JlCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPmZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lcik7CgogICAgLy93ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdAogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZS4gSWdub3JlIGl0IikpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvL2l0IG1heSBwb3NzaWJsZSB1c2VyIHJlY29ubmVjdGVkIC8gRFVUIHJvYW1lZCB0byBvdGhlciBiYW5kIGFwIGJ0dwogICAgLy90aW1lciBzdGFydGVkIGFuZCB0aW1lciBjYWxsYmFjayBoaXQuCiAgICBpZihHZXRSRkJhbmQocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmN1cnJBUG9wZXJhdGlvbkNoYW5uZWwpID09IFNJUl9CQU5EXzVfR0haKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLAogICAgICAgICAgICAgICBGTCgiRFVUIGlzIGFscmVhZHkgY29ubmVjdGVkIHRvIDVHSCBhcCwgc28gbm8gbmVlZCB0byB0cmlnZ2VyIGZvcmNlZCByb2FtLiIpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5SZXF1ZXN0VGltZVN0YW1wID0gKHRBTklfVElNRVNUQU1QKXBhbEdldFRpY2tDb3VudChwTWFjLT5oSGRkKTsKICAgIC8qCiAgICAgKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlIGZvciBhbGwgdmFsaWQgY2hhbm5sZXMgZm9yIDVHaHoKICAgICAqIHB1cmdlIG5vbi1QMlAgcmVzdWx0cyBmcm9tIHRoZSBwYXN0IGZvciA1R2h6IGJhbmQKICAgICAqLwogICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0Rm9yQmFuZChwTWFjLCBWT1NfRkFMU0UsIFNJUl9CQU5EXzVfR0haKTsKICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbVNjYW5Gb3JJbml0aWFsRm9yY2VkNUdSb2FtaW5nKAogICAgICAgICAgICAgICAgIHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQpOwogICAgaWYoc3RhdHVzICE9IGVIQUxfU1RBVFVTX1NVQ0NFU1MpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsCiAgICAgICAgICAgICAgIEZMKCJjc3JOZWlnaGJvclJvYW1TY2FuRm9ySW5pdGlhbEZvcmNlZDVHUm9hbWluZyBmYWlsZWQgc3RhdHVzPSVkIiksIHN0YXR1cyk7CiAgICAgICAgLy9TZW5kIFJTTyBzdGFydCBiZWNhdXNlIGluIGNhc2UgNUcgcm9hbWluZyBob3N0IGhhdmUgbm90IGVuYWJsZWQgYXQgaW5pdGlhbCBjb25uZWN0aW9uCiAgICAgICAgY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUQVJULCBSRUFTT05fQ09OTkVDVCk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIFRyYW5zaXRpb24gdG8gQ0ZHX0NIQU5fTElTVF9TQ0FOICovCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DRkdfQ0hBTl9MSVNUX1NDQU4pOwp9CgojaWYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUiAmJiBkZWZpbmVkIFdMQU5fRkVBVFVSRV9WT1dJRkkKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUlzc3VlTmVpZ2hib3JScHRSZXF1ZXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGludm9rZWQgd2hlbiBUTCBpc3N1ZXMgYSBkb3duIGV2ZW50IGFuZCB0aGUgY3VycmVudCBhc3NvYyAKICAgICAgICAgICAgaXMgYSAxMVIgYXNzb2NpYXRpb24uIEl0IGludm9rZXMgU01FIFJSTSBBUEkgdG8gaXNzdWUgdGhlIG5laWdoYm9yIHJlcXVlc3QgdG8gCiAgICAgICAgICAgIHRoZSBjdXJyZW50bHkgYXNzb2NpYXRlZCBBUCB3aXRoIHRoZSBjdXJyZW50IFNTSUQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1Jc3N1ZU5laWdoYm9yUnB0UmVxdWVzdCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0UnJtTmVpZ2hib3JSc3BDYWxsYmFja0luZm8gY2FsbGJhY2tJbmZvOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0UnJtTmVpZ2hib3JSZXEgbmVpZ2hib3JSZXE7CgoKICAgIG5laWdoYm9yUmVxLm5vX3NzaWQgPSAwOwoKICAgIC8qIEZpbGwgaW4gdGhlIFNTSUQgKi8KICAgIG5laWdoYm9yUmVxLnNzaWQubGVuZ3RoID0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQubGVuZ3RoOwogICAgdm9zX21lbV9jb3B5KG5laWdoYm9yUmVxLnNzaWQuc3NJZCwgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkXS5jb25uZWN0ZWRQcm9maWxlLlNTSUQuc3NJZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ucm9hbVNlc3Npb25bcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5TU0lELmxlbmd0aCk7CiAgICAKICAgIGNhbGxiYWNrSW5mby5uZWlnaGJvclJzcENhbGxiYWNrID0gY3NyTmVpZ2hib3JSb2FtUlJNTmVpZ2hib3JSZXBvcnRSZXN1bHQ7CiAgICBjYWxsYmFja0luZm8ubmVpZ2hib3JSc3BDYWxsYmFja0NvbnRleHQgPSBwTWFjOwogICAgY2FsbGJhY2tJbmZvLnRpbWVvdXQgPSBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJlcG9ydFRpbWVvdXQ7CgogICAgcmV0dXJuIHNtZV9OZWlnaGJvclJlcG9ydFJlcXVlc3QocE1hYywodEFOSV9VOCkgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwgJm5laWdoYm9yUmVxLCAmY2FsbGJhY2tJbmZvKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUNoYW5uZWxzRmlsdGVyQnlCYW5kCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZmlsdGVyIG91dCB0aGUgY2hhbm5lbHMKICAgICAgICAgICAgYmFzZWQgb24gdGhlIEJhbmQgZ2l2ZW4gYXMgaW5wdXQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGlucHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBpbnB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIGlucHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBwT3V0cHV0Q2hhbm5lbExpc3QgLSBUaGUgb3V0cHV0IGNoYW5uZWwgbGlzdAogICAgXHBhcmFtICBvdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBjaGFubmVscyBpbiBvdXRwdXQgY2hhbm5lbCBsaXN0CiAgICBccGFyYW0gIHBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzIC0gVGhlIGZpbmFsIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgb3V0cHV0IGNoYW5uZWwgbGlzdC4KICAgIFxwYXJhbSBiYW5kIC0gVGhlICBiYW5kIHdoaWNoIHdpbGwgYmUgZ2V0IGNvbXBhcmVkIHdpdGggdGhlIGlucHV0IGNoYW5uZWwgbGlzdCBiYW5kCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtQ2hhbm5lbHNGaWx0ZXJCeUJhbmQoCiAgICAgICAgICAgICAgICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCogIHBJbnB1dENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgdEFOSV9VOCAgIGlucHV0TnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgIHRBTklfVTgqICBwT3V0cHV0Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICB0QU5JX1U4KiAgcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICB0U2lyUkZCYW5kIGJhbmQKICAgICAgICAgICAgICAgICAgICAgICkKewogICAgdEFOSV9VOCBpID0gMDsKICAgIHRBTklfVTggbnVtQ2hhbm5lbHMgPSAwOwoKICAgIC8vIENoZWNrIGZvciBOVUxMIHBvaW50ZXIKICAgIGlmICghcElucHV0Q2hhbm5lbExpc3QpIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CgogICAgLy8gQ2hlY2sgZm9yIE5VTEwgcG9pbnRlcgogICAgaWYgKCFwT3V0cHV0Q2hhbm5lbExpc3QpIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CgogICAgaWYgKGlucHV0TnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgIHsKICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgIiVzOiBXcm9uZyBOdW1iZXIgb2YgSW5wdXQgQ2hhbm5lbHMgJWQiLAogICAgICAgICAgICAgX19mdW5jX18sIGlucHV0TnVtT2ZDaGFubmVscyk7CiAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgaW5wdXROdW1PZkNoYW5uZWxzOyBpKyspCiAgICB7CiAgICAgICAgaWYgKGJhbmQgPT0gR2V0UkZCYW5kKHBJbnB1dENoYW5uZWxMaXN0W2ldKSkKICAgICAgICB7CiAgICAgICAgICAgIHBPdXRwdXRDaGFubmVsTGlzdFtudW1DaGFubmVsc10gPSBwSW5wdXRDaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgbnVtQ2hhbm5lbHMrKzsKICAgICAgICB9CiAgICB9CgogICAgLy8gUmV0dXJuIGZpbmFsIG51bWJlciBvZiBjaGFubmVscwogICAgKnBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzID0gbnVtQ2hhbm5lbHM7CgogICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU1lcmdlQ2hhbm5lbExpc3RzIAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIG1lcmdlIHR3byBjaGFubmVsIGxpc3QuCiAgICAgICAgICAgIE5COiBJZiBjYWxsZWQgd2l0aCBvdXRwdXROdW1PZkNoYW5uZWxzID09IDAsIHRoaXMgcm91dGluZXMKICAgICAgICAgICAgICAgIHNpbXBseSBjb3BpZXMgdGhlIGlucHV0IGNoYW5uZWwgbGlzdCB0byB0aGUgb3V0cHV0IGNoYW5uZWwgbGlzdC4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGFkZHRpb25hbCBjaGFubmVscyB0byBtZXJnZSBpbiB0byB0aGUgIm1lcmdlZCIgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgaW5wdXROdW1PZkNoYW5uZWxzIC0gVGhlIG51bWJlciBvZiBhZGRpdGlvbmFsIGNoYW5uZWxzLgogICAgXHBhcmFtICBwT3V0cHV0Q2hhbm5lbExpc3QgLSBUaGUgcGxhY2UgdG8gcHV0IHRoZSAibWVyZ2VkIiBjaGFubmVsIGxpc3QuCiAgICBccGFyYW0gIG91dHB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgb3JpZ2luYWwgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSAibWVyZ2VkIiBjaGFubmVscyBsaXN0LgogICAgXHBhcmFtICBwTWVyZ2VkT3V0cHV0TnVtT2ZDaGFubmVscyAtIFRoZSBmaW5hbCBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlICJtZXJnZWQiIGNoYW5uZWwgbGlzdC4KCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU1lcmdlQ2hhbm5lbExpc3RzKCAKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLCAKICAgICAgICB0QU5JX1U4ICAgKnBJbnB1dENoYW5uZWxMaXN0LCAKICAgICAgICB0QU5JX1U4ICBpbnB1dE51bU9mQ2hhbm5lbHMsCiAgICAgICAgdEFOSV9VOCAgICpwT3V0cHV0Q2hhbm5lbExpc3QsCiAgICAgICAgdEFOSV9VOCAgb3V0cHV0TnVtT2ZDaGFubmVscywKICAgICAgICB0QU5JX1U4ICAqcE1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMKICAgICAgICApCnsKICAgIHRBTklfVTggaSA9IDA7CiAgICB0QU5JX1U4IGogPSAwOwogICAgdEFOSV9VOCBudW1DaGFubmVscyA9IG91dHB1dE51bU9mQ2hhbm5lbHM7CgogICAgLy8gQ2hlY2sgZm9yIE5VTEwgcG9pbnRlcgogICAgaWYgKCFwSW5wdXRDaGFubmVsTGlzdCkgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKCiAgICAvLyBDaGVjayBmb3IgTlVMTCBwb2ludGVyCiAgICBpZiAoIXBPdXRwdXRDaGFubmVsTGlzdCkgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKCiAgICBpZiAoaW5wdXROdW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgewogICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAiJXM6IFdyb25nIE51bWJlciBvZiBJbnB1dCBDaGFubmVscyAlZCIsCiAgICAgICAgICAgICBfX2Z1bmNfXywgaW5wdXROdW1PZkNoYW5uZWxzKTsKICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKICAgIH0KICAgIGlmIChvdXRwdXROdW1PZkNoYW5uZWxzID4gV05JX0NGR19WQUxJRF9DSEFOTkVMX0xJU1RfTEVOKQogICAgewogICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAiJXM6IFdyb25nIE51bWJlciBvZiBPdXRwdXQgQ2hhbm5lbHMgJWQiLAogICAgICAgICAgICAgX19mdW5jX18sIGlucHV0TnVtT2ZDaGFubmVscyk7CiAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfSU5WQUw7CiAgICB9CgogICAgLyogQWRkIHRoZSAibmV3IiBjaGFubmVscyBpbiB0aGUgaW5wdXQgbGlzdCB0byB0aGUgZW5kIG9mIHRoZSBvdXRwdXQgbGlzdC4KICAgICAgIENoZWNrIGFkZGVkIGluIGZvciBsb29wIHRvIG1ha2Ugc3VyZSBvdXRwdXRsaXN0IGRvZXNuJ3QgZXhjZWVkcyB2YWxpZAogICAgICAgY2hhbm5lbCBsaXN0IGxlbmd0aC4gKi8KICAgIGZvciAoaSA9IDA7IChpIDwgaW5wdXROdW1PZkNoYW5uZWxzKSAmJiAobnVtQ2hhbm5lbHMgPCBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU4pOyBpKyspCiAgICB7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IG91dHB1dE51bU9mQ2hhbm5lbHM7IGorKykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwSW5wdXRDaGFubmVsTGlzdFtpXSA9PSBwT3V0cHV0Q2hhbm5lbExpc3Rbal0pCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKGogPT0gb3V0cHV0TnVtT2ZDaGFubmVscykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChwSW5wdXRDaGFubmVsTGlzdFtpXSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sIAogICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXSBBZGRpbmcgZXh0cmEgJWQgdG8gTmVpZ2hib3IgY2hhbm5lbCBsaXN0IiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgIHBJbnB1dENoYW5uZWxMaXN0W2ldKTsgCiAgICAgICAgICAgICAgICBwT3V0cHV0Q2hhbm5lbExpc3RbbnVtQ2hhbm5lbHNdID0gcElucHV0Q2hhbm5lbExpc3RbaV07IAogICAgICAgICAgICAgICAgbnVtQ2hhbm5lbHMrKzsgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gUmV0dXJuIGZpbmFsIG51bWJlciBvZiBjaGFubmVscwogICAgKnBNZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzID0gbnVtQ2hhbm5lbHM7IAoKICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1DcmVhdGVDaGFuTGlzdEZyb21OZWlnaGJvclJlcG9ydAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBpbnZva2VkIHdoZW4gbmVpZ2hib3IgcmVwb3J0IGlzIHJlY2VpdmVkIGZvciB0aGUgCiAgICAgICAgICAgIG5laWdoYm9yIHJlcXVlc3QuIEJhc2VkIG9uIHRoZSBjaGFubmVscyBwcmVzZW50IGluIHRoZSBuZWlnaGJvciByZXBvcnQsIAogICAgICAgICAgICBpdCBnZW5lcmF0ZXMgY2hhbm5lbCBsaXN0IHdoaWNoIHdpbGwgYmUgdXNlZCBpbiBSRVBPUlRfU0NBTiBzdGF0ZSB0bwogICAgICAgICAgICBzY2FuIGZvciB0aGVzZSBuZWlnaGJvciBBUHMKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1DcmVhdGVDaGFuTGlzdEZyb21OZWlnaGJvclJlcG9ydCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cFJybU5laWdoYm9yUmVwb3J0RGVzYyAgICAgICBwTmVpZ2hib3JCc3NEZXNjOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCAgICAgICAgICAgICAgICAgICAgICAgbnVtQ2hhbm5lbHMgPSAwOwogICAgdEFOSV9VOCAgICAgICAgICAgICAgICAgICAgICAgaSA9IDA7CiAgICB0QU5JX1U4ICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtNQVhfQlNTX0lOX05FSUdIQk9SX1JQVF07CiAgICB0QU5JX1U4ICAgICAgICAgICAgICAgICAgICAgICBtZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzID0gMDsKCiAgICAvKiBUaGlzIHNob3VsZCBhbHdheXMgc3RhcnQgZnJvbSAwIHdoZW5ldmVyIHdlIGNyZWF0ZSBhIGNoYW5uZWwgbGlzdCBvdXQgb2YgbmVpZ2hib3IgQVAgbGlzdCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKCiAgICBwTmVpZ2hib3JCc3NEZXNjID0gc21lUnJtR2V0Rmlyc3RCc3NFbnRyeUZyb21OZWlnaGJvckNhY2hlKHBNYWMpOwoKICAgIHdoaWxlIChwTmVpZ2hib3JCc3NEZXNjKQogICAgewogICAgICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPj0gTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpIGJyZWFrOwogICAgICAgIAogICAgICAgIC8qIFVwZGF0ZSB0aGUgbmVpZ2hib3IgQlNTIEluZm8gaW4gdGhlIDExciBGVCBSb2FtIEluZm8gKi8KICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mb1twTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnRdLmNoYW5uZWxOdW0gPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWw7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm9bcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0XS5uZWlnaGJvclNjb3JlID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1U4KXBOZWlnaGJvckJzc0Rlc2MtPnJvYW1TY29yZTsKICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib1JlcG9ydEJzc0luZm9bcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0XS5uZWlnaGJvckJzc0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmJzc0lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQrKzsKCiAgICAgICAgLyogU2F2aW5nIHRoZSBjaGFubmVsIGxpc3Qgbm9uLXJlZHVuZGFudGx5ICovCiAgICAgICAgZm9yIChpID0gMDsgKGkgPCBudW1DaGFubmVscyAmJiBpIDwgTUFYX0JTU19JTl9ORUlHSEJPUl9SUFQpOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBpZiAocE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWwgPT0gY2hhbm5lbExpc3RbaV0pCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmIChpID09IG51bUNoYW5uZWxzKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoQ1NSX0lTX1JPQU1fSU5UUkFfQkFORF9FTkFCTEVEKHBNYWMpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0byBhZGQgb25seSBpZiBpdHMgdGhlIHNhbWUgYmFuZAogICAgICAgICAgICAgICAgICAgIGlmIChHZXRSRkJhbmQocE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUG9wZXJhdGlvbkNoYW5uZWwpID09CiAgICAgICAgICAgICAgICAgICAgICAgIEdldFJGQmFuZChwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbCkpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfSU5GTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXM6IFtJTkZPTE9HXSBBZGRpbmcgJWQgdG8gTmVpZ2hib3IgY2hhbm5lbCBsaXN0IChTYW1lIGJhbmQpXG4iLCBfX2Z1bmNfXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFtudW1DaGFubmVsc10gPSBwTmVpZ2hib3JCc3NEZXNjLT5wTmVpZ2hib3JCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbDsKICAgICAgICAgICAgICAgICAgICAgICAgbnVtQ2hhbm5lbHMrKzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVk9TX1RSQUNFIChWT1NfTU9EVUxFX0lEX1NNRSwgVk9TX1RSQUNFX0xFVkVMX0lORk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVzOiBbSU5GT0xPR10gQWRkaW5nICVkIHRvIE5laWdoYm9yIGNoYW5uZWwgbGlzdFxuIiwgX19mdW5jX18sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yQnNzRGVzYy0+cE5laWdoYm9yQnNzRGVzY3JpcHRpb24tPmNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0W251bUNoYW5uZWxzXSA9IHBOZWlnaGJvckJzc0Rlc2MtPnBOZWlnaGJvckJzc0Rlc2NyaXB0aW9uLT5jaGFubmVsOwogICAgICAgICAgICAgICAgICAgIG51bUNoYW5uZWxzKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIHBOZWlnaGJvckJzc0Rlc2MgPSBzbWVScm1HZXROZXh0QnNzRW50cnlGcm9tTmVpZ2hib3JDYWNoZShwTWFjLCBwTmVpZ2hib3JCc3NEZXNjKTsKICAgIH0KCiAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KQogICAgewogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpOwogICAgfQoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICAvKiBTdG9yZSB0aGUgb2J0YWluZWQgY2hhbm5lbCBsaXN0IHRvIHRoZSBOZWlnaGJvciBDb250cm9sIGRhdGEgc3RydWN0dXJlICovCiAgICBpZiAobnVtQ2hhbm5lbHMpCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gdm9zX21lbV9tYWxsb2MoKG51bUNoYW5uZWxzKSAqIHNpemVvZih0QU5JX1U4KSk7CiAgICBpZiAoTlVMTCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgQ2hhbm5lbCBsaXN0IGZhaWxlZC4uIFRMIGV2ZW50IGlnbm9yZWQiKSk7CiAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9SRVNPVVJDRVM7CiAgICB9CgogICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsIChudW1DaGFubmVscykgKiBzaXplb2YodEFOSV9VOCkpOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPSBudW1DaGFubmVsczsKICAgIC8qCiAgICAgKiBDcmVhdGUgYSBVbmlvbiBvZiBvY2N1cGllZCBjaGFubmVsIGxpc3QgbGVhcm50IGJ5IHRoZSBEVVQgYWxvbmcgd2l0aCB0aGUgTmVpZ2hib3IKICAgICAqIHJlcG9ydCBDaGFubmVscy4gVGhpcyBpbmNyZWFzZXMgdGhlIGNoYW5jZXMgb2YgdGhlIERVVCB0byBnZXQgYSBjYW5kaWRhdGUgQVAgd2hpbGUKICAgICAqIHJvYW1pbmcgZXZlbiBpZiB0aGUgTmVpZ2hib3IgUmVwb3J0IGlzIG5vdCBhYmxlIHRvIHByb3ZpZGUgc3VmZmljaWVudCBpbmZvcm1hdGlvbi4KICAgICAqICovCiAgICBpZiAocE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLm51bUNoYW5uZWxzKQogICAgewogICAgICAgY3NyTmVpZ2hib3JSb2FtTWVyZ2VDaGFubmVsTGlzdHMocE1hYywKICAgICAgICAgICAgICAgICAgJnBNYWMtPnNjYW4ub2NjdXBpZWRDaGFubmVscy5jaGFubmVsTGlzdFswXSwKICAgICAgICAgICAgICAgICAgcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLm51bUNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0WzBdLAogICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgJm1lcmdlZE91dHB1dE51bU9mQ2hhbm5lbHMpOwogICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLm51bU9mQ2hhbm5lbHMgPQogICAgICAgICAgICAgICAgICBtZXJnZWRPdXRwdXROdW1PZkNoYW5uZWxzOwoKICAgIH0KICAgIC8qSW5kaWNhdGUgdGhlIGZpcm13YXJlIGFib3V0IHRoZSB1cGRhdGUgb25seSBpZiBhbnkgbmV3IGNoYW5uZWxzIGFyZSBhZGRlZC4KICAgICAqIE90aGVyd2lzZSwgdGhlIGZpcm13YXJlIHdvdWxkIGFscmVhZHkgYmUga25vd2luZyB0aGUgbm9uLUlBUFBuZWlnaGJvcmxpc3QKICAgICAqIGNoYW5uZWxzLiBUaGVyZSBpcyBubyBuZWVkIHRvIHVwZGF0ZS4qLwogICAgaWYgKG51bUNoYW5uZWxzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0cxLCBGTCgiSUFQUCBOZWlnaGJvciBsaXN0IGNhbGxiYWNrIHJlY2VpdmVkIGFzIGV4cGVjdGVkIgogICAgICAgICAgICAgICAiaW4gc3RhdGUgJXMuIiksCiAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9UUlVFOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgewogICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9VUERBVEVfQ0ZHLCBSRUFTT05fQ0hBTk5FTF9MSVNUX0NIQU5HRUQpOwogICAgICAgIH0KI2VuZGlmCiAgICB9CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAKICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SUk1OZWlnaGJvclJlcG9ydFJlc3VsdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyB0aGUgbmVpZ2hib3IgcmVwb3J0IGNhbGxiYWNrIHRoYXQgd2lsbCBiZSBpbnZva2VkIGJ5IAogICAgICAgICAgICBTTUUgUlJNIG9uIHJlY2VpdmluZyBhIG5laWdoYm9yIHJlcG9ydCBvciBvZiBuZWlnaGJvciByZXBvcnQgaXMgbm90IAogICAgICAgICAgICByZWNlaXZlZCBhZnRlciB0aW1lb3V0LiBPbiByZWNlaXZpbmcgYSB2YWxpZCByZXBvcnQsIGl0IGdlbmVyYXRlcyBhIAogICAgICAgICAgICBjaGFubmVsIGxpc3QgZnJvbSB0aGUgbmVpZ2hib3IgcmVwb3J0IGFuZCBzdGFydHMgdGhlIAogICAgICAgICAgICBuZWlnaGJvciBzY2FuIHRpbWVyCgogICAgXHBhcmFtICBjb250ZXh0IC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICB2b3NTdGF0dXMgLSBTdGF0dXMgb2YgdGhlIGNhbGxiYWNrKFNVQ0NFU1MvRkFJTFVSRSkKCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUlJNTmVpZ2hib3JSZXBvcnRSZXN1bHQodm9pZCAqY29udGV4dCwgVk9TX1NUQVRVUyB2b3NTdGF0dXMpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVChjb250ZXh0KTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk5laWdoYm9yIHJlcG9ydCByZXN1bHQgY2FsbGJhY2sgd2l0aCBzdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgc3dpdGNoIChwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1FVRVJZOgogICAgICAgICAgICAvKiBSZXNldCB0aGUgcmVwb3J0IHBlbmRpbmcgdmFyaWFibGUgKi8KICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8ubmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTID09IHZvc1N0YXR1cykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogTmVlZCB0byBjcmVhdGUgY2hhbm5lbCBsaXN0IGJhc2VkIG9uIHRoZSBuZWlnaGJvciBBUCBsaXN0IGFuZCB0cmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlICovCiAgICAgICAgICAgICAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1DcmVhdGVDaGFuTGlzdEZyb21OZWlnaGJvclJlcG9ydChwTWFjKTsKICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgPT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HRSwgRkwoIkNoYW5uZWwgTGlzdCBjcmVhdGVkIGZyb20gTmVpZ2hib3IgcmVwb3J0LCBUcmFuc2l0aW9uaW5nIHRvIE5FSUdIQk9SX1NDQU4gc3RhdGUiKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyogV2UgYXJlIGdvbm5hIHNjYW4gbm93LiBSZW1lbWJlciB0aGUgdGltZSBzdGFtcCB0byBmaWx0ZXIgb3V0IHJlc3VsdHMgb25seSBhZnRlciB0aGlzIHRpbWVzdGFtcCAqLwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5SZXF1ZXN0VGltZVN0YW1wID0gKHRBTklfVElNRVNUQU1QKXBhbEdldFRpY2tDb3VudChwTWFjLT5oSGRkKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLyogTm93IHJlYWR5IGZvciBuZWlnaGJvciBzY2FuIGJhc2VkIG9uIHRoZSBjaGFubmVsIGxpc3QgY3JlYXRlZCAqLwogICAgICAgICAgICAgICAgLyogU3RhcnQgTmVpZ2hib3Igc2NhbiB0aW1lciBub3cuIE11bHRpcGxpY2F0aW9uIGJ5IFBBTF9USU1FUl9UT19NU19VTklUIGlzIHRvIGNvbnZlcnQgbXMgdG8gdXMgd2hpY2ggaXMgCiAgICAgICAgICAgICAgICAgICB3aGF0IHBhbFRpbWVyU3RhcnQgZXhwZWN0cyAqLwogICAgICAgICAgICAgICAgc3RhdHVzID0gdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclNjYW5QZXJpb2QpOwogICAgICAgICAgICAgICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIFRpbWVyIHN0YXJ0IGZhaWxlZC4uIFNob3VsZCB3ZSBBU1NFUlQgaGVyZT8/PyAqLwogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUEFMIFRpbWVyIHN0YXJ0IGZvciBuZWlnaGJvciBzY2FuIHRpbWVyIGZhaWxlZCwgc3RhdHVzID0gJWQsIElnbm9yaW5nIHN0YXRlIHRyYW5zaXRpb24iKSwgc3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7ICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLyogTmVpZ2hib3Igc2NhbiB0aW1lciBzdGFydGVkLiBUcmFuc2l0aW9uIHRvIFJFUE9SVF9TQ0FOIHN0YXRlICovCiAgICAgICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTikKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIE5laWdoYm9yIHJlcG9ydCB0aW1lb3V0IGhhcHBlbmVkIGluIFNNRSBSUk0uIFdlIGNhbiB0cnkgc2VuZGluZyBtb3JlIG5laWdoYm9yIHJlcXVlc3RzIHVudGlsIHdlIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWNoIHRoZSBtYXhOZWlnaGJvclJldHJpZXMgb3IgcmVjZWl2aW5nIGEgc3VjY2Vzc2Z1bCBuZWlnaGJvciByZXNwb25zZSAqLwogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXBvcnQgcmVzdWx0IGZhaWxlZCBhZnRlciAlZCByZXRyaWVzLCBNQVggUkVUUklFUyA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtLCBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heE5laWdoYm9yUmV0cmllcyk7CiAgICAgICAgICAgICAgICBpZiAocE5laWdoYm9yUm9hbUluZm8tPkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPj0gCiAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWF4TmVpZ2hib3JSZXRyaWVzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQmFpbGluZyBvdXQgdG8gQ0ZHIENoYW5uZWwgbGlzdCBzY2FuLi4gIikpOwogICAgICAgICAgICAgICAgICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbVRyYW5zaXRUb0NGR0NoYW5TY2FuKHBNYWMpOwogICAgICAgICAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJUcmFuc2l0IHRvIENGRyBDaGFubmVsIGxpc3Qgc2NhbiBzdGF0ZSBmYWlsZWQgd2l0aCBzdGF0dXMgJWQgIiksIHZvc1N0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgLyogV2UgdHJhbnNpdGlvbmVkIHRvIGRpZmZlcmVudCBzdGF0ZSBub3cuIFJlc2V0IHRoZSBOZWlnaGJvciByZXBvcnQgcmV0cnkgY291bnQgKi8KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVOZWlnaGJvclJwdFJlcXVlc3QocE1hYyk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFZPU19TVEFUVVNfU1VDQ0VTUyAhPSB2b3NTdGF0dXMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlcG9ydCByZXF1ZXN0IGZhaWxlZC4gc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICAgICAgICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIG5laWdoYm9yIHJlcG9ydCByZXRyeSBjb3VudCBhZnRlciBzZW5kaW5nIHRoZSBuZWlnaGJvciByZXF1ZXN0IHN1Y2Nlc3NmdWxseSAqLwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtKys7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXN1bHQgY2FsbGJhY2sgbm90IGV4cGVjdGVkIGluIgogICAgICAgICAgICAgICAgICAgInN0YXRlICVzLCBJZ25vcmluZy4uIiksCiAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybjsKfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KCgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUiAKdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUlzU3NpZEFuZFNlY3VyaXR5TWF0Y2goCiAgICAgICAgdHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwQ3VyUHJvZmlsZSwKICAgICAgICB0U2lyQnNzRGVzY3JpcHRpb24gKnBCc3NEZXNjLAogICAgICAgIHREb3QxMWZCZWFjb25JRXMgKnBJZXMpCnsKICAgIHRDc3JBdXRoTGlzdCBhdXRoVHlwZTsKICAgIHRDc3JFbmNyeXB0aW9uTGlzdCB1Q0VuY3J5cHRpb25UeXBlOwogICAgdENzckVuY3J5cHRpb25MaXN0IG1DRW5jcnlwdGlvblR5cGU7CiAgICB0QU5JX0JPT0xFQU4gZk1hdGNoID0gRkFMU0U7CgogICAgYXV0aFR5cGUubnVtRW50cmllcyA9IDE7CiAgICBhdXRoVHlwZS5hdXRoVHlwZVswXSA9IHBDdXJQcm9maWxlLT5BdXRoVHlwZTsKICAgIHVDRW5jcnlwdGlvblR5cGUubnVtRW50cmllcyA9IDE7CiAgICB1Q0VuY3J5cHRpb25UeXBlLmVuY3J5cHRpb25UeXBlWzBdID0gcEN1clByb2ZpbGUtPkVuY3J5cHRpb25UeXBlOwogICAgbUNFbmNyeXB0aW9uVHlwZS5udW1FbnRyaWVzID0gMTsKICAgIG1DRW5jcnlwdGlvblR5cGUuZW5jcnlwdGlvblR5cGVbMF0gPSBwQ3VyUHJvZmlsZS0+bWNFbmNyeXB0aW9uVHlwZTsKCiAgICBpZiggcEllcyApCiAgICB7CiAgICAgICAgaWYocEllcy0+U1NJRC5wcmVzZW50KQogICAgICAgIHsKICAgICAgICAgICAgZk1hdGNoID0gY3NySXNTc2lkTWF0Y2goIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgKHZvaWQgKilwQ3VyUHJvZmlsZS0+U1NJRC5zc0lkLCBwQ3VyUHJvZmlsZS0+U1NJRC5sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgcEllcy0+U1NJRC5zc2lkLCBwSWVzLT5TU0lELm51bV9zc2lkLAogICAgICAgICAgICAgICAgICAgIGVBTklfQk9PTEVBTl9UUlVFICk7CiAgICAgICAgICAgIGlmKFRSVUUgPT0gZk1hdGNoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogZm9yIG5vdyB3ZSBhcmUgc2VuZGluZyBOVUxMIGZvciBhbGwgUE1GIHJlbGF0ZWQgZmlsdGVyCiAgICAgICAgICAgICAgICAgKiBwYXJhbWV0ZXJzIGR1cmluZyByb2FtIHRvIHRoZSBuZWlnaGJvciBBUCBiZWNhdXNlCiAgICAgICAgICAgICAgICAgKiBzbyBmYXIgODAyMTFXIHNwZWMgZG9lc24ndCBzcGVjaWZ5IGFueXRoaW5nIGFib3V0CiAgICAgICAgICAgICAgICAgKiByb2FtaW5nIHNjZW5hcmlvLgogICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAqIE9uY2Ugcm9hbWluZyBzY2VuYXJpbyBpcyBkZWZpbmVkLCB3ZSBzaG91bGQgcmUtdmlzaXQKICAgICAgICAgICAgICAgICAqIHRoaXMgc2VjdGlvbiBhbmQgcmVtb3ZlIHRoaXMgY29tbWVudC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgZk1hdGNoID0gY3NySXNTZWN1cml0eU1hdGNoKHBNYWMsICZhdXRoVHlwZSwgJnVDRW5jcnlwdGlvblR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1DRW5jcnlwdGlvblR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwQnNzRGVzYywgcEllcywgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgICAgICByZXR1cm4gKGZNYXRjaCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gKGZNYXRjaCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBGQUxTRTsgIC8vIFRyZWF0IGEgbWlzc2luZyBTU0lEIGFzIGEgbm9uLW1hdGNoLgogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7ICAvLyBBZ2FpbiwgdHJlYXQgbWlzc2luZyBwSWVzIGFzIGEgbm9uLW1hdGNoLgogICAgfQp9Cgp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JSb2FtSXNOZXdDb25uZWN0ZWRQcm9maWxlKAogICAgICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCBzZXNzaW9uSWQgICA9ICh0QU5JX1U4KXBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQ7CiAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBDdXJyUHJvZmlsZSA9IE5VTEw7CiAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBQcmV2UHJvZmlsZSA9IE5VTEw7CiAgICB0RG90MTFmQmVhY29uSUVzICpwSWVzID0gTlVMTDsKICAgIHRTaXJCc3NEZXNjcmlwdGlvbiAqcEJzc0Rlc2MgPSBOVUxMOwogICAgdEFOSV9CT09MRUFOIGZOZXcgPSBUUlVFOwoKICAgIGlmKCEocE1hYy0+cm9hbS5yb2FtU2Vzc2lvbiAmJiBDU1JfSVNfU0VTU0lPTl9WQUxJRChwTWFjLCBzZXNzaW9uSWQpKSkKICAgIHsKICAgICAgICByZXR1cm4gKGZOZXcpOwogICAgfQoKICAgIHBDdXJyUHJvZmlsZSA9ICZwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZTsKICAgIGlmKCAhcEN1cnJQcm9maWxlICkKICAgIHsKICAgICAgICByZXR1cm4gKGZOZXcpOwp9CgogICAgcFByZXZQcm9maWxlID0gJnBOZWlnaGJvclJvYW1JbmZvLT5wcmV2Q29ublByb2ZpbGU7CiAgICBpZiggIXBQcmV2UHJvZmlsZSApCiAgICB7CiAgICAgICAgcmV0dXJuIChmTmV3KTsKICAgIH0KCiAgICBwQnNzRGVzYyA9IHBQcmV2UHJvZmlsZS0+cEJzc0Rlc2M7CiAgICBpZiAocEJzc0Rlc2MpCiAgICB7CiAgICAgICAgaWYgKEhBTF9TVEFUVVNfU1VDQ0VTUyhjc3JHZXRQYXJzZWRCc3NEZXNjcmlwdGlvbklFcyhwTWFjLAogICAgICAgICAgICBwQnNzRGVzYywgJnBJZXMpKSAmJgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1Jc1NzaWRBbmRTZWN1cml0eU1hdGNoKHBNYWMsIHBDdXJyUHJvZmlsZSwgcEJzc0Rlc2MsIHBJZXMpKQogICAgICAgIHsKICAgICAgICAgICAgZk5ldyA9IEZBTFNFOwogICAgICAgIH0KICAgICAgICBpZiAocEllcykKICAgICAgICB7CiAgICAgICAgICAgIHZvc19tZW1fZnJlZShwSWVzKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGZOZXcpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJQcmV2IHJvYW0gcHJvZmlsZSBkaWQgbm90IG1hdGNoIGN1cnJlbnQiKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPRzEsIEZMKCJQcmV2IHJvYW0gcHJvZmlsZSBtYXRjaGVzIGN1cnJlbnQiKSk7CiAgICB9CgogICAgcmV0dXJuIChmTmV3KTsKfQoKdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUNvbm5lY3RlZFByb2ZpbGVNYXRjaCgKICAgICAgICB0cEFuaVNpckdsb2JhbCBwTWFjLAogICAgICAgIHRDc3JTY2FuUmVzdWx0ICpwUmVzdWx0LAogICAgICAgIHREb3QxMWZCZWFjb25JRXMgKnBJZXMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFOSV9VOCBzZXNzaW9uSWQgICA9ICh0QU5JX1U4KXBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQ7CiAgICB0Q3NyUm9hbUNvbm5lY3RlZFByb2ZpbGUgKnBDdXJQcm9maWxlID0gTlVMTDsKICAgIHRTaXJCc3NEZXNjcmlwdGlvbiAqcEJzc0Rlc2MgPSAmcFJlc3VsdC0+UmVzdWx0LkJzc0Rlc2NyaXB0b3I7CgogICAgaWYoICEocE1hYy0+cm9hbS5yb2FtU2Vzc2lvbgogICAgICAgICAgICAmJiBDU1JfSVNfU0VTU0lPTl9WQUxJRChwTWFjLCBzZXNzaW9uSWQpKSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcEN1clByb2ZpbGUgPSAmcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGU7CgogICAgaWYoICFwQ3VyUHJvZmlsZSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIGNzck5laWdoYm9yUm9hbUlzU3NpZEFuZFNlY3VyaXR5TWF0Y2gocE1hYywgcEN1clByb2ZpbGUsIHBCc3NEZXNjLCBwSWVzKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByZXBhcmVOb25PY2N1cGllZENoYW5uZWxMaXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gcHJlcGFyZSBhIGNoYW5uZWwgbGlzdCB0aGF0IGlzIGRlcml2ZWQgZnJvbQogICAgICAgICAgICB0aGUgbGlzdCBvZiB2YWxpZCBjaGFubmVscyBhbmQgZG9lcyBub3QgaW5jbHVkZSB0aG9zZSBpbiB0aGUgb2NjdXBpZWQKICAgICAgICAgICAgbGlzdC4KCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICBccGFyYW0gIHBJbnB1dENoYW5uZWxMaXN0IC0gVGhlIGRlZmF1bHQgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgbnVtT2ZDaGFubmVscyAtIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIGRlZmF1bHQgY2hhbm5lbHMgbGlzdC4KICAgIFxwYXJhbSAgcE91dHB1dENoYW5uZWxMaXN0IC0gVGhlIHBsYWNlIHRvIHB1dCB0aGUgbm9uLW9jY3VwaWVkIGNoYW5uZWwgbGlzdC4KICAgIFxwYXJhbSAgcE91dHB1dE51bU9mQ2hhbm5lbHMgLSBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSBub24tb2NjdXBpZWQgY2hhbm5lbCBsaXN0LgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtUHJlcGFyZU5vbk9jY3VwaWVkQ2hhbm5lbExpc3QoCiAgICAgICAgdHBBbmlTaXJHbG9iYWwgcE1hYywgCiAgICAgICAgdEFOSV9VOCAgICpwSW5wdXRDaGFubmVsTGlzdCwgCiAgICAgICAgdEFOSV9VOCBudW1PZkNoYW5uZWxzLAogICAgICAgIHRBTklfVTggICAqcE91dHB1dENoYW5uZWxMaXN0LAogICAgICAgIHRBTklfVTggKnBPdXRwdXROdW1PZkNoYW5uZWxzCiAgICAgICAgKQp7CiAgICB0QU5JX1U4IGkgPSAwOwogICAgdEFOSV9VOCBvdXRwdXROdW1PZkNoYW5uZWxzICA9IDA7IC8vIENsZWFyIHRoZSBvdXRwdXQgbnVtYmVyIG9mIGNoYW5uZWxzCiAgICB0QU5JX1U4IG51bU9jY3VwaWVkQ2hhbm5lbHMgPSBwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHMubnVtQ2hhbm5lbHM7CiAgICB0QU5JX1U4ICpwT2NjdXBpZWRDaGFubmVsTGlzdCA9IHBNYWMtPnNjYW4ub2NjdXBpZWRDaGFubmVscy5jaGFubmVsTGlzdDsKCiAgICBmb3IgKGkgPSAwOyAoaSA8IG51bU9mQ2hhbm5lbHMgJiYoaSA8IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikpOyBpKyspCiAgICB7CiAgICAgICAgaWYgKCFjc3JJc0NoYW5uZWxQcmVzZW50SW5MaXN0KHBPY2N1cGllZENoYW5uZWxMaXN0LCBudW1PY2N1cGllZENoYW5uZWxzLAogICAgICAgICAgICAgcElucHV0Q2hhbm5lbExpc3RbaV0pKQogICAgICAgIHsKICAgICAgICAgICAvKiBERlMgY2hhbm5lbCB3aWxsIGJlIGFkZGVkIGluIHRoZSBsaXN0IG9ubHkgd2hlbiB0aGUKICAgICAgICAgICAgICBERlMgUm9hbWluZyBzY2FuIGZsYWcgaXMgZW5hYmxlZCovCiAgICAgICAgICAgIGlmIChDU1JfSVNfQ0hBTk5FTF9ERlMocElucHV0Q2hhbm5lbExpc3RbaV0pKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5hbGxvd0RGU0NoYW5uZWxSb2FtID09IFRSVUUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcE91dHB1dENoYW5uZWxMaXN0W291dHB1dE51bU9mQ2hhbm5lbHMrK10gPSBwSW5wdXRDaGFubmVsTGlzdFtpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHBPdXRwdXRDaGFubmVsTGlzdFtvdXRwdXROdW1PZkNoYW5uZWxzKytdID0gcElucHV0Q2hhbm5lbExpc3RbaV07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgc21zTG9nKHBNYWMsIExPRzIsIEZMKCJOdW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIHZhbGlkIGNoYW5uZWwgbGlzdD0lZDsgIgogICAgICAgICAgICJOdW1iZXIgb2YgY2hhbm5lbHMgaW4gdGhlIG5vbi1vY2N1cGllZCBsaXN0IGxpc3Q9JWQiKSwKICAgICAgICAgICAgbnVtT2ZDaGFubmVscywgb3V0cHV0TnVtT2ZDaGFubmVscyk7CgogICAgLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMKICAgICpwT3V0cHV0TnVtT2ZDaGFubmVscyA9IG91dHB1dE51bU9mQ2hhbm5lbHM7IAoKICAgIHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTOwp9CiNlbmRpZiAvKiBGRUFUVVJFX1dMQU5fTEZSICovCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4KCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW5ldmVyIHRoZXJlIGlzIGEgdHJhbnNpdGlvbiB0byBDRkcgY2hhbiBzY2FuIAogICAgICAgICAgICBzdGF0ZSBmcm9tIGFueSBzdGF0ZS4gSXQgZnJlZXMgdXAgdGhlIGN1cnJlbnQgY2hhbm5lbCBsaXN0IGFuZCBhbGxvY2F0ZXMgCiAgICAgICAgICAgIGEgbmV3IG1lbW9yeSBmb3IgdGhlIGNoYW5uZWxzIHJlY2VpdmVkIGZyb20gQ0ZHIGl0ZW0uIEl0IHRoZW4gc3RhcnRzIHRoZSAKICAgICAgICAgICAgbmVpZ2hib3Igc2NhbiB0aW1lciB0byBwZXJmb3JtIHRoZSBzY2FuIG9uIGVhY2ggY2hhbm5lbCBvbmUgYnkgb25lCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzICBzdGF0dXMgID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIGludCBpID0gMDsKICAgIHRBTklfVTggICBudW1PZkNoYW5uZWxzID0gMDsKICAgIHRBTklfVTggICBjaGFubmVsTGlzdFtXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU5dOwogICAgdHBDc3JDaGFubmVsSW5mbyAgICBjdXJyQ2hhbm5lbExpc3RJbmZvOwogICAgdEFOSV9VOCAgIHNjYW5DaGFubmVsTGlzdFtXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU5dOwogICAgaW50ICAgICAgIG91dHB1dE51bU9mQ2hhbm5lbHMgPSAwOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgdEFOSV9VMzIgc2Vzc2lvbklkID0gcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZDsKI2VuZGlmCiAgICBjdXJyQ2hhbm5lbExpc3RJbmZvID0gJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mbzsKCiAgICBpZiAoIAojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgICgocE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MpICYmCiAgICAgICAgICAgICAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID09IGVBTklfQk9PTEVBTl9GQUxTRSkpIHx8CiAgICAgICAgKHBOZWlnaGJvclJvYW1JbmZvLT5pc0VTRUFzc29jID09IGVBTklfQk9PTEVBTl9GQUxTRSkgfHwKI2VuZGlmIC8vIEVTRQogICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPT0gMCkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIkJ1aWxkaW5nIGNoYW5uZWwgbGlzdCB0byBzY2FuIikpOwoKCiAgICAgICAgLyogRnJlZSB1cCB0aGUgY2hhbm5lbCBsaXN0IGFuZCBhbGxvY2F0ZSBhIG5ldyBtZW1vcnkuIFRoaXMgaXMgYmVjYXVzZSB3ZSBkb250IGtub3cgaG93IG11Y2ggCiAgICAgICAgICAgIHdhcyBhbGxvY2F0ZWQgbGFzdCB0aW1lLiBJZiB3ZSBkaXJlY3RseSBjb3B5IG1vcmUgbnVtYmVyIG9mIGJ5dGVzIHRoYW4gYWxsb2NhdGVkIGVhcmxpZXIsIHRoaXMgbWlnaHQgCiAgICAgICAgICAgIHJlc3VsdCBpbiBtZW1vcnkgY29ycnVwdGlvbiAqLwogICAgICAgIGlmIChOVUxMICE9IGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9mcmVlKGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KTsKICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzID0gMDsKICAgICAgICB9CgogICAgICAgIC8vIE5vdyBvYnRhaW4gdGhlIGNvbnRlbnRzIGZvciAiY2hhbm5lbExpc3QiICh0aGUgImRlZmF1bHQgdmFsaWQgY2hhbm5lbCBsaXN0IikgZnJvbSBFSVRIRVIKICAgICAgICAvLyB0aGUgZ05laWdoYm9yU2NhbkNoYW5uZWxMaXN0IGluICJjZmcuaW5pIiwgT1IgdGhlIGFjdHVhbCAidmFsaWQgY2hhbm5lbCBsaXN0IiBpbmZvcm1hdGlvbiBmb3JtZWQgYnkgQ1NSLgogICAgICAgIGlmICgwICE9IHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscykKICAgICAgICB7CiAgICAgICAgICAgIC8vIENvcHkgdGhlICJkZWZhdWx0IHZhbGlkIGNoYW5uZWwgbGlzdCIgKGNoYW5uZWxMaXN0KSBmcm9tIHRoZSBnTmVpZ2hib3JTY2FuQ2hhbm5lbExpc3QgaW4gImNmZy5pbmkiLgogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsICJVc2luZyB0aGUgY2hhbm5lbCBsaXN0IGZyb20gY2ZnLmluaSIpOwogICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1NZXJnZUNoYW5uZWxMaXN0cyggCiAgICAgICAgICAgICAgICAgICAgcE1hYywgCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5udW1PZkNoYW5uZWxzLCAKICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwgCiAgICAgICAgICAgICAgICAgICAgMCwgLy9OQjogSWYgMCwgc2ltcGx5IGNvcHkgdGhlIGlucHV0IGNoYW5uZWwgbGlzdCB0byB0aGUgb3V0cHV0IGxpc3QuCiAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMgKTsKCiAgICAgICAgICAgIGlmIChDU1JfSVNfUk9BTV9JTlRSQV9CQU5EX0VOQUJMRUQocE1hYykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUNoYW5uZWxzRmlsdGVyQnlCYW5kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNYWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLm51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0UkZCYW5kKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYobnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCB3cm9uZyBudW1iZXIgb2YgQ2hhbm5lbCBsaXN0IikpOwogICAgICAgICAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9JTlZBTDsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBSZW1vdmUgdGhlIERGUyBjaGFubmVscyBmcm9tIENGRyBjaGFubmVsIGxpc3Qgd2hlbiAnCiAgICAgICAgICAgICAgICAgICAgICAgIGdBbGxvd1JvYW1Ub0RGUyBpcyBkaXNhYmxlZCAqLwogICAgICAgICAgICBpZiAoIHBNYWMtPnJvYW0uY29uZmlnUGFyYW0uYWxsb3dERlNDaGFubmVsUm9hbSA9PSBGQUxTRSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpPTA7IGk8bnVtT2ZDaGFubmVsczsgaSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmICggIShDU1JfSVNfQ0hBTk5FTF9ERlMoY2hhbm5lbExpc3RbaV0pKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICBzY2FuQ2hhbm5lbExpc3Rbb3V0cHV0TnVtT2ZDaGFubmVscysrXSA9IGNoYW5uZWxMaXN0W2ldOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsgICAvKiBNb3ZlIGFsbCB0aGUgY2hhbm5lbHMgdG8gcm9hbSBzY2FuIGNoYW5uZWwgbGlzdCAqLwogICAgICAgICAgICAgICAgdm9zX21lbV9jb3B5KHNjYW5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzICogc2l6ZW9mKHRBTklfVTgpKTsKICAgICAgICAgICAgICAgIG91dHB1dE51bU9mQ2hhbm5lbHMgPSBudW1PZkNoYW5uZWxzOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAob3V0cHV0TnVtT2ZDaGFubmVscyA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5vIGNoYW5uZWxzIHRvIHNjYW4iKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QgPQogICAgICAgICAgICAgICAgdm9zX21lbV9tYWxsb2Mob3V0cHV0TnVtT2ZDaGFubmVscypzaXplb2YodEFOSV9VOCkpOwogICAgICAgICAgICBpZiAoTlVMTCA9PSBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgQ2hhbm5lbCBsaXN0IGZhaWxlZCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPSBvdXRwdXROdW1PZkNoYW5uZWxzOwogICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgIHNjYW5DaGFubmVsTGlzdCwgb3V0cHV0TnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgfSAKCgojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgIGVsc2UgaWYgKChwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID09IERFRkFVTFRfU0NBTikgJiYKICAgICAgICAgICAgICAgICAoYWJzKHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSkgPgogICAgICAgICAgICAgICAgICBhYnMocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQpKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIAogICAgICAgICAgICAgKiBUcmlnZ2VyIGEgY29udGlndW91cyBzY2FuIG9uIGFsbCBjaGFubmVscyB3aGVuIHRoZQogICAgICAgICAgICAgKiBSU1NJIGluIHRoZSBsb29rdXAgRE9XTiBub3RpZmljYXRpb24gaXMgYmVsb3cgcmVhc3NvYyAKICAgICAgICAgICAgICogdGhyZXNob2xkLiBUaGlzIHdpbGwgaGVscCB1cyBmaW5kIHRoZSBiZXN0IGF2YWlsYWJsZSAKICAgICAgICAgICAgICogY2FuZGlkYXRlIGFuZCBhbHNvIHVwZGF0ZSB0aGUgY2hhbm5lbCBjYWNoZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HVywgIlRyaWdnZXJpbmcgY29udGlndW91cyBzY2FuICIKICAgICAgICAgICAgICAgICIobG9va3VwRE9XTlJzc2k9JWQscmVhc3NvY1RocmVzaG9sZD0lZCkiLAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpLAogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclJlYXNzb2NUaHJlc2hvbGQqKC0xKSk7CgogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJlcXVlc3RUaW1lU3RhbXAgPSAodEFOSV9USU1FU1RBTVApcGFsR2V0VGlja0NvdW50KHBNYWMtPmhIZGQpOwoKICAgICAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CgogICAgICAgICAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLCAKICAgICAgICAgICAgICogcHVyZ2Ugbm9uLVAyUCByZXN1bHRzIGZyb20gdGhlIHBhc3QgKi8KICAgICAgICAgICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0KHBNYWMsIFZPU19GQUxTRSk7CgogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1QZXJmb3JtQ29udGlndW91c0JnU2NhbihwTWFjLCBzZXNzaW9uSWQpOwoKICAgICAgICAgICAgLyogVHJhbnNpdGlvbiB0byBDRkdfQ0hBTl9MSVNUX1NDQU4gKi8KICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOKTsKCiAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQojZW5kaWYKICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBudW1PZkNoYW5uZWxzID0gcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLm51bUNoYW5uZWxzOwogICAgICAgICAgICBpZiAobnVtT2ZDaGFubmVscyA+IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyA9IFdOSV9DRkdfVkFMSURfQ0hBTk5FTF9MSVNUX0xFTjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobnVtT2ZDaGFubmVscwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAgICAgJiYgKChwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID09IFNQTElUX1NDQU5fT0NDVVBJRURfTElTVCkgfHwKICAgICAgICAgICAgICAgICAgICAocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCA9PSAwKSB8fAogICAgICAgICAgICAgICAgICAgICgocE5laWdoYm9yUm9hbUluZm8tPnVFbXB0eVNjYW5Db3VudCAlIDIpID09IDEpKQojZW5kaWYKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIEFsd2F5cyBzY2FuIGNoYW5uZWxzIGluIHRoZSBvY2N1cGllZCBjaGFubmVsIGxpc3QKICAgICAgICAgICAgICAgICAqIGJlZm9yZSBzY2FubmluZyBvbiB0aGUgbm9uLW9jY3VwaWVkIGxpc3QuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgIlN3aXRjaGluZyB0byBvY2N1cGllZCBjaGFubmVsIGxpc3QiCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgICAgICAgICAgIi11U2Nhbk1vZGU9JWQsIHVFbXB0eVNjYW5Db3VudD0lZCIsCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVTY2FuTW9kZSwKICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50CiNlbmRpZgogICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBpZiAoQ1NSX0lTX1JPQU1fSU5UUkFfQkFORF9FTkFCTEVEKHBNYWMpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUNoYW5uZWxzRmlsdGVyQnlCYW5kKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5zY2FuLm9jY3VwaWVkQ2hhbm5lbHMuY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0UkZCYW5kKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jdXJyQVBvcGVyYXRpb25DaGFubmVsKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdm9zX21lbV9jb3B5KGNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+c2Nhbi5vY2N1cGllZENoYW5uZWxzLmNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBSZW1vdmUgdGhlIERGUyBjaGFubmVscyBmcm9tIENGRyBjaGFubmVsIGxpc3Qgd2hlbiAnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdBbGxvd1JvYW1Ub0RGUyBpcyBkaXNhYmxlZCAqLwogICAgICAgICAgICAgICAgaWYgKCBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmFsbG93REZTQ2hhbm5lbFJvYW0gPT0gRkFMU0UpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICBmb3IgKGk9MDsgaTxudW1PZkNoYW5uZWxzOyBpKyspCiAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhKENTUl9JU19DSEFOTkVMX0RGUyhjaGFubmVsTGlzdFtpXSkpKQogICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5DaGFubmVsTGlzdFtvdXRwdXROdW1PZkNoYW5uZWxzKytdID0gY2hhbm5lbExpc3RbaV07CiAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZvc19tZW1fY29weShzY2FuQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwogICAgICAgICAgICAgICAgICAgIG91dHB1dE51bU9mQ2hhbm5lbHMgPSBudW1PZkNoYW5uZWxzOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChvdXRwdXROdW1PZkNoYW5uZWxzID09IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJObyBjaGFubmVscyB0byBzY2FuIikpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0ID0gdm9zX21lbV9tYWxsb2Mob3V0cHV0TnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgICAgICAgICBpZiAoTlVMTCA9PSBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZvciBDaGFubmVsIGxpc3QgZmFpbGVkIikpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVscyA9IG91dHB1dE51bU9mQ2hhbm5lbHM7CiAgICAgICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5DaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0TnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBTY2FuIGFsbCBjaGFubmVscyBmcm9tIG5vbi1vY2N1cGllZCBsaXN0ICovCiAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsICJHZXQgdmFsaWQgY2hhbm5lbCBsaXN0Iik7CiAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzID0gc2l6ZW9mKHBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCk7CgogICAgICAgICAgICAgICAgaWYoSEFMX1NUQVRVU19TVUNDRVNTKGNzckdldENmZ1ZhbGlkQ2hhbm5lbHMocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VOCAqKXBNYWMtPnJvYW0udmFsaWRDaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodEFOSV9VMzIgKikgJm51bU9mQ2hhbm5lbHMpKSkKICAgICAgICAgICAgewojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFByZXBhcmUgbm9uLW9jY3VwaWVkIGNoYW5uZWwgbGlzdCAoY2hhbm5lbExpc3QpCiAgICAgICAgICAgICAgICAgKiBmcm9tIHRoZSBhY3R1YWwgInZhbGlkIGNoYW5uZWwgbGlzdCIgaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgICAqIGZvcm1lZCBieSBDU1IuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgIlN3aXRjaGluZyB0byBub24tb2NjdXBpZWQgY2hhbm5lbCBsaXN0Iik7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1QcmVwYXJlTm9uT2NjdXBpZWRDaGFubmVsTGlzdChwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbnVtT2ZDaGFubmVscyk7CiNlbHNlCiAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsICJNZXJnaW5nIGNoYW5uZWwgbGlzdCIpOwogICAgICAgICAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtTWVyZ2VDaGFubmVsTGlzdHMoIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1U4ICopcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscywgICAvLyBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGluIHRoZSB2YWxpZENoYW5uZWxMaXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8vTkI6IElmIDAsIHNpbXBseSBjb3B5IHRoZSBpbnB1dCBjaGFubmVsIGxpc3QgdG8gdGhlIG91dHB1dCBsaXN0LgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJm51bU9mQ2hhbm5lbHMgKTsgLy8gVGhlIGZpbmFsIG51bWJlciBvZiBjaGFubmVscyBpbiB0aGUgb3V0cHV0IGxpc3QuIFdpbGwgYmUgbnVtT2ZDaGFubmVscwojZW5kaWYKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiQ291bGQgbm90IGdldCB2YWxpZCBjaGFubmVsIGxpc3QiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChDU1JfSVNfUk9BTV9JTlRSQV9CQU5EX0VOQUJMRUQocE1hYykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1DaGFubmVsc0ZpbHRlckJ5QmFuZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTWFjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0QU5JX1U4ICopcE1hYy0+cm9hbS52YWxpZENoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZudW1PZkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRSRkJhbmQocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmN1cnJBUG9wZXJhdGlvbkNoYW5uZWwpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKG51bU9mQ2hhbm5lbHMgPiBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU4pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG51bU9mQ2hhbm5lbHMgPSBXTklfQ0ZHX1ZBTElEX0NIQU5ORUxfTElTVF9MRU47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChudW1PZkNoYW5uZWxzID09IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTm8gY2hhbm5lbHMgdG8gc2NhbiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCA9CiAgICAgICAgICAgICAgICB2b3NfbWVtX21hbGxvYyhudW1PZkNoYW5uZWxzKnNpemVvZih0QU5JX1U4KSk7CgogICAgICAgICAgICBpZiAoTlVMTCA9PSBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2NhdGlvbiBmb3IgQ2hhbm5lbCBsaXN0IGZhaWxlZCIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMgPSBudW1PZkNoYW5uZWxzOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgY2hhbm5lbExpc3QsIG51bU9mQ2hhbm5lbHMgKiBzaXplb2YodEFOSV9VOCkpOwojZWxzZQogICAgICAgICAgICB2b3NfbWVtX2NvcHkoY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgKHRBTklfVTggKilwTWFjLT5yb2FtLnZhbGlkQ2hhbm5lbExpc3QsCiAgICAgICAgICAgICAgICAgICAgbnVtT2ZDaGFubmVscyAqIHNpemVvZih0QU5JX1U4KSk7CiNlbmRpZgogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIAogICAgICAgICAgICAiTnVtYmVyIG9mIGNoYW5uZWxzIGZyb20gQ0ZHIChvcikgKG5vbi0pb2NjdXBpZWQgbGlzdD0lZCIsCiAgICAgICAgICAgIGN1cnJDaGFubmVsTGlzdEluZm8tPm51bU9mQ2hhbm5lbHMpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjdXJyQ2hhbm5lbExpc3RJbmZvLT5udW1PZkNoYW5uZWxzOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICJDaGFubmVsIExpc3QgZnJvbSBDRkcgKG9yKSAobm9uLSlvY2N1cGllZCBsaXN0IgogICAgICAgICAgICAgICAgICAgICI9ICVkIiwgY3VyckNoYW5uZWxMaXN0SW5mby0+Q2hhbm5lbExpc3RbaV0pOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBXZSBhcmUgZ29ubmEgc2NhbiBub3cuIFJlbWVtYmVyIHRoZSB0aW1lIHN0YW1wIHRvIGZpbHRlciBvdXQgcmVzdWx0cyBvbmx5IGFmdGVyIHRoaXMgdGltZXN0YW1wICovCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+c2NhblJlcXVlc3RUaW1lU3RhbXAgPSAodEFOSV9USU1FU1RBTVApcGFsR2V0VGlja0NvdW50KHBNYWMtPmhIZGQpOwogICAgCiAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgIC8qIFN0YXJ0IE5laWdoYm9yIHNjYW4gdGltZXIgbm93LiBNdWx0aXBsaWNhdGlvbiBieSBQQUxfVElNRVJfVE9fTVNfVU5JVCBpcyB0byBjb252ZXJ0IG1zIHRvIHVzIHdoaWNoIGlzIAogICAgICAgICAgICB3aGF0IHBhbFRpbWVyU3RhcnQgZXhwZWN0cyAqLwogICAgc3RhdHVzID0gdm9zX3RpbWVyX3N0YXJ0KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIsCiAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclNjYW5QZXJpb2QpOwogICAgCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgLyogVGltZXIgc3RhcnQgZmFpbGVkLi4gICovCiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIFBBTCBUaW1lciBzdGFydCBmYWlsZWQsIHN0YXR1cyA9ICVkLCBJZ25vcmluZyBzdGF0ZSB0cmFuc2l0aW9uIiksIHN0YXR1cyk7CiAgICAgICAgdm9zX21lbV9mcmVlKGN1cnJDaGFubmVsTGlzdEluZm8tPkNoYW5uZWxMaXN0KTsKICAgICAgICBjdXJyQ2hhbm5lbExpc3RJbmZvLT5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgY3VyckNoYW5uZWxMaXN0SW5mby0+bnVtT2ZDaGFubmVscyA9IDA7CiAgICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICAgfQogICAgCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX1RSVUU7CiAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLCAKICAgICAqIHB1cmdlIG5vbi1QMlAgcmVzdWx0cyBmcm9tIHRoZSBwYXN0ICovCiAgICBjc3JTY2FuRmx1c2hTZWxlY3RpdmVSZXN1bHQocE1hYywgVk9TX0ZBTFNFKTsKCiAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLAogICAgICogcHVyZ2UgZmFpbGVkIHByZS1hdXRoIHJlc3VsdHMgZnJvbSB0aGUgcGFzdCAqLwogICAgY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbGVkTGlzdChwTWFjKTsKICAgIAogICAgLyogVHJhbnNpdGlvbiB0byBDRkdfQ0hBTl9MSVNUX1NDQU5fU1RBVEUgKi8KICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NGR19DSEFOX0xJU1RfU0NBTikKCiAgICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVcEV2ZW50CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhcyBzb29uIGFzIFRMIGluZGljYXRlcyB0aGF0IHRoZSBjdXJyZW50IEFQJ3MgCiAgICAgICAgICAgIFJTU0kgaXMgYmV0dGVyIHRoYW4gdGhlIG5laWdoYm9yIGxvb2t1cCB0aHJlc2hvbGQuIEhlcmUsIHdlIHRyYW5zaXRpb24gdG8gCiAgICAgICAgICAgIENPTk5FQ1RFRCBzdGF0ZSBhbmQgcmVzZXQgYWxsIHRoZSBzY2FuIHBhcmFtZXRlcnMKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBVcEV2ZW50KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzOwogICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKCiAgICAvKiBSZWNoZWNrIHdoZXRoZXIgdGhlIGJlbG93IGNoZWNrIGlzIG5lZWRlZC4gKi8KICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlICE9IGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQpCiAgICAgICAgJiYgKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSAhPSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORykpCiAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEKQojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgaWYgKCFjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYyxwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uY3NyU2Vzc2lvbklkKSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIHdoZW4gZmFzdCByb2FtIGlzIGRpc2FibGVkLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CiNlbmRpZgogICAgLyogUmVzZXQgYWxsIHRoZSBuZWlnaGJvciByb2FtIGluZm8gY29udHJvbCB2YXJpYWJsZXMuIEZyZWUgYWxsIHRoZSBhbGxvY2F0ZWQgbWVtb3J5LiBJdCBpcyBsaWtlIHdlIGFyZSBqdXN0IGFzc29jaWF0ZWQgbm93ICovCiAgICBjc3JOZWlnaGJvclJvYW1SZXNldENvbm5lY3RlZFN0YXRlQ29udHJvbEluZm8ocE1hYyk7CgogICAgCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJSZWdpc3RlcmluZyBET1dOIGV2ZW50IG5laWdoYm9yIGxvb2t1cCBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQsIiksIHBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpKTsKICAgIC8qIFJlZ2lzdGVyIE5laWdoYm9yIExvb2t1cCB0aHJlc2hvbGQgY2FsbGJhY2sgd2l0aCBUTCBmb3IgRE9XTiBldmVudCBub3cgKi8KICAgIHZvc1N0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRE9XTkNhbGxiYWNrLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpID0gMDsKI2VuZGlmCiAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgICB7CiAgICAgICAvL2VyciBtc2cKICAgICAgIHNtc0xvZyhwTWFjLCBMT0dXLCBGTCgiIENvdWxkbid0IHJlZ2lzdGVyIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwQ2FsbGJhY2sgRE9XTiBldmVudCB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2b3NTdGF0dXMpOwogICAgfQoKCiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBEb3duRXZlbnQKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGFzIHNvb24gYXMgVEwgaW5kaWNhdGVzIHRoYXQgdGhlIGN1cnJlbnQgQVAncyAKICAgICAgICAgICAgUlNTSSBmYWxscyBiZWxvdyB0aGUgY3VycmVudCBlaWdoYm9yIGxvb2t1cCB0aHJlc2hvbGQuIEhlcmUsIHdlIHRyYW5zaXRpb24gdG8gCiAgICAgICAgICAgIFJFUE9SVF9RVUVSWSBmb3IgMTFyIGFzc29jaWF0aW9uIGFuZCBDRkdfQ0hBTl9MSVNUX1NDQU4gc3RhdGUgaWYgdGhlIGFzc29jIGlzIAogICAgICAgICAgICBhIG5vbi0xMVIgYXNzb2NpYXRpb24uCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovClZPU19TVEFUVVMgIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRG93bkV2ZW50KHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzID0gVk9TX1NUQVRVU19TVUNDRVNTOwogICAgZUhhbFN0YXR1cyAgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgICBzd2l0Y2ggKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQ6CiAgICAgICAgICAgIAogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJEZXJlZ2lzdGVyaW5nIERPV04gZXZlbnQgbmVpZ2hib3IgbG9va3VwIGNhbGxiYWNrIHdpdGggVEwuIFJTU0kgPSAlZCwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSkpOwogICAgICAgICAgICAvKiBEZS1yZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgKi8KICAgICAgICAgICAgdm9zU3RhdHVzID0gV0xBTlRMX0RlcmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LCAodl9TN190KXBOZWlnaGJvclJvYW1JbmZvLT5jdXJyZW50TmVpZ2hib3JMb29rdXBUaHJlc2hvbGQgKiAoLTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2ssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmKCFWT1NfSVNfU1RBVFVTX1NVQ0NFU1Modm9zU3RhdHVzKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAvL2VyciBtc2cKICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCIgQ291bGRuJ3QgRGVyZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cENhbGxiYWNrIERPV04gZXZlbnQgZnJvbSBUTDogU3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgfQojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICBpZiAoIWNzclJvYW1Jc0Zhc3RSb2FtRW5hYmxlZChwTWFjLHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5jc3JTZXNzaW9uSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIHdoZW4gZmFzdCByb2FtIGlzIGRpc2FibGVkLiBJZ25vcmUgaXQiKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICAgICAKI2lmIGRlZmluZWQgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgJiYgZGVmaW5lZCBXTEFOX0ZFQVRVUkVfVk9XSUZJCiAgICAgICAgICAgIGlmICgocE5laWdoYm9yUm9hbUluZm8tPmlzMTFyQXNzb2MpICYmIChwTWFjLT5ycm0ucnJtU21lQ29udGV4dC5ycm1Db25maWcucnJtRW5hYmxlZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCIxMVIgQXNzb2NpYXRpb246TmVpZ2hib3IgTG9va3VwIERvd24gZXZlbnQgcmVjZWl2ZWQgaW4gQ09OTkVDVEVEIHN0YXRlIikpOwogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtSXNzdWVOZWlnaGJvclJwdFJlcXVlc3QocE1hYyk7CiAgICAgICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHJlcG9ydCByZXF1ZXN0IGZhaWxlZC4gc3RhdHVzID0gJWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdm9zU3RhdHVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLyogSW5jcmVtZW50IHRoZSBuZWlnaGJvciByZXBvcnQgcmV0cnkgY291bnQgYWZ0ZXIgc2VuZGluZyB0aGUgbmVpZ2hib3IgcmVxdWVzdCBzdWNjZXNzZnVsbHkgKi8KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLmN1cnJlbnROZWlnaGJvclJwdFJldHJ5TnVtKys7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5uZWlnaGJvclJwdFBlbmRpbmcgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFUE9SVF9RVUVSWSkKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiNlbmRpZiAgICAgIAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJOb24gMTFSIG9yIEVTRSBBc3NvY2lhdGlvbjpOZWlnaGJvciBMb29rdXAgRG93biBldmVudCByZWNlaXZlZCBpbiBDT05ORUNURUQgc3RhdGUiKSk7CgogICAgICAgICAgICAgICAgdm9zU3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtVHJhbnNpdFRvQ0ZHQ2hhblNjYW4ocE1hYyk7CiAgICAgICAgICAgICAgICBpZiAoVk9TX1NUQVRVU19TVUNDRVNTICE9IHZvc1N0YXR1cykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR0UsIEZMKCJjc3JOZWlnaGJvclJvYW1UcmFuc2l0VG9DRkdDaGFuU2NhbiBmYWlsZWQiCiAgICAgICAgICAgICAgICAgICAgICAgICIgd2l0aCBzdGF0dXM9JWQiKSwgdm9zU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdm9zU3RhdHVzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMiwgRkwoIlJlZ2lzdGVyaW5nIFVQIGV2ZW50IG5laWdoYm9yIGxvb2t1cCBjYWxsYmFjayB3aXRoIFRMLiBSU1NJID0gJWQsIiksIE5FSUdIQk9SX1JPQU1fTE9PS1VQX1VQX1RIUkVTSE9MRCAqICgtMSkpOwogICAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIFVQIGV2ZW50IG5vdyAqLwogICAgICAgICAgICB2b3NTdGF0dXMgPSBXTEFOVExfUmVnUlNTSUluZGljYXRpb25DQihwTWFjLT5yb2FtLmdWb3NDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2X1M3X3QpTkVJR0hCT1JfUk9BTV9MT09LVVBfVVBfVEhSRVNIT0xEICogKC0xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXTEFOVExfSE9fVEhSRVNIT0xEX1VQLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVQQ2FsbGJhY2ssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZPU19NT0RVTEVfSURfU01FLCBwTWFjKTsKICAgICAgICAgICAgaWYoIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NTdGF0dXMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgIC8vZXJyIG1zZwogICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIiBDb3VsZG4ndCByZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cENhbGxiYWNrIFVQIGV2ZW50IHdpdGggVEw6IFN0YXR1cyA9ICVkIiksIHN0YXR1cyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJET1dOIGV2ZW50IHJlY2VpdmVkIGluIGludmFsaWQiCiAgICAgICAgICAgICAgICAgICAic3RhdGUgJXMgLi5JZ25vcmluZy4uLiIpLAogICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIAogICAgfQogICAgcmV0dXJuIHZvc1N0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjawoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyByZWdpc3RlcmVkIHdpdGggVEwgdG8gaW5kaWNhdGUgd2hlbmV2ZXIgdGhlIFJTU0kgCiAgICAgICAgICAgIGdldHMgYmV0dGVyIHRoYW4gdGhlIG5laWdoYm9yTG9va3VwIFJTU0kgVGhyZXNob2xkCgogICAgXHBhcmFtICBwQWRhcHRlciAtIFZPUyBDb250ZXh0CiAgICAgICAgICAgIHRyYWZmaWNTdGF0dXMgLSBVUC9ET1dOIGluZGljYXRpb24gZnJvbSBUTAogICAgICAgICAgICBwVXNlckN0eHQgLSBQYXJhbWV0ZXIgZm9yIGNhbGxiYWNrIHJlZ2lzdGVyZWQgZHVyaW5nIGNhbGxiYWNrIHJlZ2lzdHJhdGlvbi4gU2hvdWxkIGJlIHBNYWMKCiAgICBccmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwVVBDYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLCB2X1U4X3QgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKCBwVXNlckN0eHQgKTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBMb29rdXAgVVAgaW5kaWNhdGlvbiBjYWxsYmFjayBjYWxsZWQgd2l0aCBub3RpZmljYXRpb24gJWQgUmVwb3J0ZWQgUlNTSSA9ICVkIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2Z1Jzc2kpOwoKICAgIGlmKCFjc3JJc0Nvbm5TdGF0ZUNvbm5lY3RlZEluZnJhKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQpKQogICAgewogICAgICAgc21zTG9nKHBNYWMsIExPR1csICJJZ25vcmluZyB0aGUgaW5kaWNhdGlvbiBhcyB3ZSBhcmUgbm90IGNvbm5lY3RlZCIpOwogICAgICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBWT1NfQVNTRVJUKFdMQU5UTF9IT19USFJFU0hPTERfVVAgPT0gcnNzaU5vdGlmaWNhdGlvbik7CiAgICB2b3NTdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cFVwRXZlbnQocE1hYyk7CiAgICByZXR1cm4gdm9zU3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtTmVpZ2hib3JMb29rdXBET1dOQ2FsbGJhY2sKCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gaXMgcmVnaXN0ZXJlZCB3aXRoIFRMIHRvIGluZGljYXRlIHdoZW5ldmVyIHRoZSBSU1NJIAogICAgICAgICAgICBmYWxscyBiZWxvdyB0aGUgY3VycmVudCBuZWlnaGJvckxvb2t1cCBSU1NJIFRocmVzaG9sZAoKICAgIFxwYXJhbSAgcEFkYXB0ZXIgLSBWT1MgQ29udGV4dAogICAgICAgICAgICB0cmFmZmljU3RhdHVzIC0gVVAvRE9XTiBpbmRpY2F0aW9uIGZyb20gVEwKICAgICAgICAgICAgcFVzZXJDdHh0IC0gUGFyYW1ldGVyIGZvciBjYWxsYmFjayByZWdpc3RlcmVkIGR1cmluZyBjYWxsYmFjayByZWdpc3RyYXRpb24uIFNob3VsZCBiZSBwTWFjCgogICAgXHJldHVybiBWT1NfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KVk9TX1NUQVRVUyBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayAodl9QVk9JRF90IHBBZGFwdGVyLCB2X1U4X3QgcnNzaU5vdGlmaWNhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZfUFZPSURfdCBwVXNlckN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2X1M3X3QgYXZnUnNzaSkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKCBwVXNlckN0eHQgKTsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgVk9TX1NUQVRVUyAgdm9zU3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBMb29rdXAgRE9XTiBpbmRpY2F0aW9uIGNhbGxiYWNrIGNhbGxlZCB3aXRoIG5vdGlmaWNhdGlvbiAlZCBSZXBvcnRlZCBSU1NJID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJzc2lOb3RpZmljYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdmdSc3NpKTsKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSBhdmdSc3NpOwojZW5kaWYKICAgIGlmKCFjc3JJc0Nvbm5TdGF0ZUNvbm5lY3RlZEluZnJhKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQpKQogICAgewogICAgICAgc21zTG9nKHBNYWMsIExPR1csICJJZ25vcmluZyB0aGUgaW5kaWNhdGlvbiBhcyB3ZSBhcmUgbm90IGNvbm5lY3RlZCIpOwogICAgICAgcmV0dXJuIFZPU19TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICBWT1NfQVNTRVJUKFdMQU5UTF9IT19USFJFU0hPTERfRE9XTiA9PSByc3NpTm90aWZpY2F0aW9uKTsKICAgIHZvc1N0YXR1cyA9IGNzck5laWdoYm9yUm9hbU5laWdoYm9yTG9va3VwRG93bkV2ZW50KHBNYWMpOwoKICAgIHJldHVybiB2b3NTdGF0dXM7Cn0KCiNpZmRlZiBSU1NJX0hBQ0sKZXh0ZXJuIGludCBkdW1wQ21kUlNTSTsKI2VuZGlmCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSW5kaWNhdGVEaXNjb25uZWN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBDU1IgYXMgc29vbiBhcyB0aGUgc3RhdGlvbiBkaXNjb25uZWN0cyBmcm9tIAogICAgICAgICAgICB0aGUgQVAuIFRoaXMgZnVuY3Rpb24gZG9lcyB0aGUgbmVjZXNzYXJ5IGNsZWFudXAgb2YgbmVpZ2hib3Igcm9hbSBkYXRhIAogICAgICAgICAgICBzdHJ1Y3R1cmVzLiBOZWlnaGJvciByb2FtIHN0YXRlIHRyYW5zaXRpb25zIHRvIElOSVQgc3RhdGUgd2hlbmV2ZXIgdGhpcyAKICAgICAgICAgICAgZnVuY3Rpb24gaXMgY2FsbGVkIGV4Y2VwdCBpZiB0aGUgY3VycmVudCBzdGF0ZSBpcyBSRUFTU09DSUFUSU5HCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBzZXNzaW9uSWQgLSBDU1Igc2Vzc2lvbiBpZCB0aGF0IGdvdCBkaXNjb25uZWN0ZWQKCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1JbmRpY2F0ZURpc2Nvbm5lY3QodHBBbmlTaXJHbG9iYWwgcE1hYywgdEFOSV9VOCBzZXNzaW9uSWQpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgdENzclJvYW1Db25uZWN0ZWRQcm9maWxlICpwUHJldlByb2ZpbGUgPSAmcE5laWdoYm9yUm9hbUluZm8tPnByZXZDb25uUHJvZmlsZTsKI2VuZGlmCiAgICB0Q3NyUm9hbVNlc3Npb24gKnBTZXNzaW9uID0gQ1NSX0dFVF9TRVNTSU9OKCBwTWFjLCBzZXNzaW9uSWQpOwoKICAgIGlmIChOVUxMID09IHBTZXNzaW9uKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgicFNlc3Npb24gaXMgTlVMTCAiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBWT1NfVFJBQ0UoVk9TX01PRFVMRV9JRF9TTUUsIFZPU19UUkFDRV9MRVZFTF9JTkZPLAogICAgICAgICAgICAgICAgICAgRkwoIkRpc2Nvbm5lY3QgaW5kaWNhdGlvbiBvbiBzZXNzaW9uICVkIGluIHN0YXRlICVzIgogICAgICAgICAgICAgICAgICAgICAgImZyb20gQlNTSUQgOiAiCiAgICAgICAgICAgICAgICAgICBNQUNfQUREUkVTU19TVFIpLCBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSksCiAgICAgICAgICAgICAgICAgICBNQUNfQUREUl9BUlJBWShwU2Vzc2lvbi0+Y29ubmVjdGVkUHJvZmlsZS5ic3NpZCkpOwogCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAvKkZyZWUgdGhlIGN1cnJlbnQgcHJldmlvdXMgcHJvZmlsZSBhbmQgbW92ZSB0aGUgY3VycmVudCBwcm9maWxlIHRvIHByZXYgcHJvZmlsZS4qLwogICAgY3NyUm9hbUZyZWVDb25uZWN0UHJvZmlsZShwTWFjLCBwUHJldlByb2ZpbGUpOwogICAgY3NyUm9hbUNvcHlDb25uZWN0UHJvZmlsZShwTWFjLCBzZXNzaW9uSWQsIHBQcmV2UHJvZmlsZSk7CiNlbmRpZgogICAgaWYgKE5VTEwgIT0gcFNlc3Npb24pCiAgICB7CiAgICAgICAgaWYgKE5VTEwgIT0gcFNlc3Npb24tPnBDdXJSb2FtUHJvZmlsZSkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChWT1NfU1RBX01PREUgIT0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLnBDdXJSb2FtUHJvZmlsZS0+Y3NyUGVyc29uYSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJZ25vcmluZyBEaXNjb25uZWN0IGluZGljYXRpb24gcmVjZWl2ZWQgZnJvbSBhIG5vbiBTVEEgcGVyc29uYS4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNlc3Npb25JZDogJWQsIGNzclBlcnNvbm5hICVkIiksIHNlc3Npb25JZCwKICAgICAgICAgICAgICAgICAgICAgICAoaW50KXBNYWMtPnJvYW0ucm9hbVNlc3Npb25bc2Vzc2lvbklkXS5wQ3VyUm9hbVByb2ZpbGUtPmNzclBlcnNvbmEpOwogICAgICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgICAgIH0KICAgICAgICB9CgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgIGlmIChwU2Vzc2lvbi0+Y29ubmVjdGVkUHJvZmlsZS5pc0VTRUFzc29jKQogICAgICAgIHsKICAgICAgICAgICB2b3NfbWVtX2NvcHkoJnBTZXNzaW9uLT5wcmV2QXBTU0lELCAmcFNlc3Npb24tPmNvbm5lY3RlZFByb2ZpbGUuU1NJRCwKICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHRTaXJNYWNTU2lkKSk7CiAgICAgICAgICAgdm9zX21lbV9jb3B5KHBTZXNzaW9uLT5wcmV2QXBCc3NpZCwgcFNlc3Npb24tPmNvbm5lY3RlZFByb2ZpbGUuYnNzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0U2lyTWFjQWRkcikpOwogICAgICAgICAgIHBTZXNzaW9uLT5wcmV2T3BDaGFubmVsID0gcFNlc3Npb24tPmNvbm5lY3RlZFByb2ZpbGUub3BlcmF0aW9uQ2hhbm5lbDsKICAgICAgICAgICBwU2Vzc2lvbi0+aXNQcmV2QXBJbmZvVmFsaWQgPSBUUlVFOwogICAgICAgICAgIHBTZXNzaW9uLT5yb2FtVFMxID0gdm9zX3RpbWVyX2dldF9zeXN0ZW1fdGltZSgpOwogICAgICAgIH0KI2VuZGlmCiAgICB9IC8vaWYgKE5VTEwgIT0gcFNlc3Npb24pCiAgIAojaWZkZWYgUlNTSV9IQUNLCiAgICBkdW1wQ21kUlNTSSA9IC00MDsKI2VuZGlmCiAgICBzd2l0Y2ggKHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRUFTU09DSUFUSU5HOgogICAgICAgICAgICAvLyBTdG9wIHNjYW4gYW5kIG5laWdoYm9yIHJlZnJlc2ggdGltZXJzLgogICAgICAgICAgICAvLyBUaGVzZSBhcmUgaW5kZWVkIG5vdCByZXF1aXJlZCB3aGVuIHdlIGFyZSBpbiByZWFzc29jaWF0aW5nCiAgICAgICAgICAgIC8vIHN0YXRlLgogICAgICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICAgICAgdm9zX3RpbWVyX3N0b3AoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgICAgICB2b3NfdGltZXJfc3RvcCgmcE5laWdoYm9yUm9hbUluZm8tPmVtcHR5U2NhblJlZnJlc2hUaW1lcik7CiAgICAgICAgICAgIGlmICghQ1NSX0lTX1JPQU1fU1VCU1RBVEVfRElTQVNTT0NfSE8oIHBNYWMsIHNlc3Npb25JZCApKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogRGlzY29ubmVjdCBpbmRpY2F0aW9uIGR1cmluZyBEaXNhc3NvYyBIYW5kb2ZmIHN1Yi1zdGF0ZQogICAgICAgICAgICAgICAgICogaXMgcmVjZWl2ZWQgd2hlbiB3ZSBhcmUgdHJ5aW5nIHRvIGRpc2Nvbm5lY3Qgd2l0aCB0aGUgb2xkCiAgICAgICAgICAgICAgICAgKiBBUCBkdXJpbmcgcm9hbS4gQlVULCBpZiByZWNlaXZlIGEgZGlzY29ubmVjdCBpbmRpY2F0aW9uIAogICAgICAgICAgICAgICAgICogb3V0c2lkZSBvZiBEaXNhc3NvYyBIYW5kb2ZmIHN1Yi1zdGF0ZSwgdGhlbiBpdCBtZWFucyB0aGF0IAogICAgICAgICAgICAgICAgICogdGhpcyBpcyBhIGdlbnVpbmUgZGlzY29ubmVjdCBhbmQgd2UgbmVlZCB0byBjbGVhbiB1cC4KICAgICAgICAgICAgICAgICAqIE90aGVyd2lzZSwgd2Ugd2lsbCBiZSBzdHVjayBpbiByZWFzc29jIHN0YXRlIHdoaWNoIHdpbGwKICAgICAgICAgICAgICAgICAqIGluLXR1cm4gYmxvY2sgc2NhbnMgKHNlZSBjc3JJc1NjYW5BbGxvd2VkKS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCk7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVDoKICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtUmVzZXRJbml0U3RhdGVDb250cm9sSW5mbyhwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsgCgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRDoKICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCkKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q29ubmVjdGVkU3RhdGVDb250cm9sSW5mbyhwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICBpZiAoIWNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgIHsKI2VuZGlmCiAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRGVyZWdBbGxSc3NpSW5kaWNhdGlvbihwTWFjKTsKI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOOgogICAgICAgICAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0Q2ZnTGlzdENoYW5TY2FuQ29udHJvbEluZm8ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgaWYgKCFjc3JSb2FtSXNSb2FtT2ZmbG9hZFNjYW5FbmFibGVkKHBNYWMpKQogICAgICAgICAgICB7CiNlbmRpZgogICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbURlcmVnQWxsUnNzaUluZGljYXRpb24ocE1hYyk7CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORToKICAgICAgICAgICAgLyogU3RvcCBwcmUtYXV0aCB0byByZWFzc29jIGludGVydmFsIHRpbWVyICovCiAgICAgICAgICAgIHZvc190aW1lcl9zdG9wKCZwTWFjLT5mdC5mdFNtZUNvbnRleHQucHJlQXV0aFJlYXNzb2NJbnR2bFRpbWVyKTsKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9SRVBPUlRfU0NBTjoKICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIRU5USUNBVElORzoKICAgICAgICAgICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfSU5JVCkKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc2V0UHJlYXV0aENvbnRyb2xJbmZvKHBNYWMpOwogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXNldFJlcG9ydFNjYW5TdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIGlmICghY3NyUm9hbUlzUm9hbU9mZmxvYWRTY2FuRW5hYmxlZChwTWFjKSkKICAgICAgICAgICAgewojZW5kaWYKICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1EZXJlZ0FsbFJzc2lJbmRpY2F0aW9uKHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJSZWNlaXZlZCBkaXNjb25uZWN0IGV2ZW50IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbiBzdGF0ZSAlcyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hY1RyYWNlR2V0TmVpZ2hib3VyUm9hbVN0YXRlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csIEZMKCJUcmFuc2l0aW9uaW5nIHRvIElOSVQgc3RhdGUiKSk7CiAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uSUFQUE5laWdoYm9yTGlzdFJlY2VpdmVkID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgICAgICBicmVhazsKICAgIH0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAogICAgLypJbmZvcm0gdGhlIEZpcm13YXJlIHRvIFNUT1AgU2Nhbm5pbmcgYXMgdGhlIGhvc3QgaGFzIGEgZGlzY29ubmVjdC4qLwogICAgaWYgKGNzclJvYW1Jc1N0YU1vZGUocE1hYywgc2Vzc2lvbklkKSkKICAgIHsKICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVE9QLCBSRUFTT05fRElTQ09OTkVDVEVEKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUluZGljYXRlQ29ubmVjdAoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgQ1NSIGFzIHNvb24gYXMgdGhlIHN0YXRpb24gY29ubmVjdHMgdG8gYW4gQVAuCiAgICAgICAgICAgIFRoaXMgaW5pdGlhbGl6ZXMgYWxsIHRoZSBuZWNlc3NhcnkgZGF0YSBzdHJ1Y3R1cmVzIHJlbGF0ZWQgdG8gdGhlIAogICAgICAgICAgICBhc3NvY2lhdGVkIEFQIGFuZCB0cmFuc2l0aW9ucyB0aGUgc3RhdGUgdG8gQ09OTkVDVEVEIHN0YXRlCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBzZXNzaW9uSWQgLSBDU1Igc2Vzc2lvbiBpZCB0aGF0IGdvdCBjb25uZWN0ZWQKICAgICAgICAgICAgdm9zU3RhdHVzIC0gY29ubmVjdCBzdGF0dXMgU1VDQ0VTUy9GQUlMVVJFCgogICAgXHJldHVybiBlSEFMX1NUQVRVU19TVUNDRVNTIG9uIHN1Y2Nlc3MsIGNvcnJlc3BvbmRpbmcgZXJyb3IgY29kZSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCmVIYWxTdGF0dXMgY3NyTmVpZ2hib3JSb2FtSW5kaWNhdGVDb25uZWN0KHRwQW5pU2lyR2xvYmFsIHBNYWMsIHRBTklfVTggc2Vzc2lvbklkLCBWT1NfU1RBVFVTIHZvc1N0YXR1cykKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICBlSGFsU3RhdHVzICBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgVk9TX1NUQVRVUyAgdnN0YXR1czsKCiNpZiAgZGVmaW5lZCAoV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIpIHx8IGRlZmluZWQgKEZFQVRVUkVfV0xBTl9FU0UpIHx8IGRlZmluZWQoRkVBVFVSRV9XTEFOX0xGUikKICAgIGludCAgaW5pdF9mdF9mbGFnID0gRkFMU0U7CiNlbmRpZgoKICAgIC8vIGlmIHNlc3Npb24gaWQgaW52YWxpZCB0aGVuIHdlIG5lZWQgcmV0dXJuIGZhaWx1cmUKICAgIGlmIChOVUxMID09IHBOZWlnaGJvclJvYW1JbmZvIHx8ICFDU1JfSVNfU0VTU0lPTl9WQUxJRChwTWFjLCBzZXNzaW9uSWQpIHx8CiAgICAgICAgKE5VTEwgPT0gcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLnBDdXJSb2FtUHJvZmlsZSkpCiAgICB7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBzbXNMb2cocE1hYywgTE9HMiwgRkwoIkNvbm5lY3QgaW5kaWNhdGlvbiByZWNlaXZlZCB3aXRoIHNlc3Npb24gaWQgJWQiCiAgICAgICAgICAgImluIHN0YXRlICVzIiksCiAgICAgICAgICAgc2Vzc2lvbklkLCBtYWNUcmFjZUdldE5laWdoYm91clJvYW1TdGF0ZSgKICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKCiAgICAvLyBCYWlsIG91dCBpZiB0aGlzIGlzIE5PVCBhIFNUQSBwZXJzb25hCiAgICBpZiAocE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLnBDdXJSb2FtUHJvZmlsZS0+Y3NyUGVyc29uYSAhPSBWT1NfU1RBX01PREUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJJZ25vcmluZyBDb25uZWN0IGluZGljYXRpb24gcmVjZWl2ZWQgZnJvbSBhIG5vbiBTVEEgcGVyc29uYS4iCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzZXNzaW9uSWQ6ICVkLCBjc3JQZXJzb25uYSAlZCIpLAogICAgICAgICAgICAgICBzZXNzaW9uSWQsCiAgICAgICAgICAgICAgIChpbnQpcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLnBDdXJSb2FtUHJvZmlsZS0+Y3NyUGVyc29uYSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgLy8gaWYgYSBjb25jdXJyZW50IHNlc3Npb24gaXMgcnVubmluZwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09IENTUl9JU19GQVNUUk9BTV9JTl9DT05DVVJSRU5DWV9JTklfRkVBVFVSRV9FTkFCTEVEKHBNYWMpKQogICAgewojZW5kaWYKICAgICAgICBpZiAoY3NySXNDb25jdXJyZW50U2Vzc2lvblJ1bm5pbmcocE1hYykpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIklnbm9yaW5nIENvbm5lY3QgaW5kaWNhdGlvbiByZWNlaXZlZCBpbiBtdWx0aXNlc3Npb24gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzcklzQ29uY3VycmVudFNlc3Npb25SdW5uaW5nKHBNYWMpKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfQojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICB9CiNlbmRpZgoKICAgIHN3aXRjaCAocE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIGNhc2UgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1JFQVNTT0NJQVRJTkc6CiAgICAgICAgICAgIGlmIChWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBKdXN0IHRyYW5zaXRpb24gdGhlIHN0YXRlIHRvIElOSVQgc3RhdGUuIFJlc3Qgb2YgdGhlIGNsZWFuIHVwIGhhcHBlbnMgd2hlbiB3ZSBnZXQgbmV4dCBjb25uZWN0IGluZGljYXRpb24gKi8KICAgICAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIEZhbGwgdGhyb3VnaCBpZiB0aGUgc3RhdHVzIGlzIFNVQ0NFU1MgKi8KICAgICAgICBjYXNlIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUOgogICAgICAgICAgICAvKiBSZXNldCBhbGwgdGhlIGRhdGEgc3RydWN0dXJlcyBoZXJlICovIAogICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1SZXNldEluaXRTdGF0ZUNvbnRyb2xJbmZvKHBNYWMpOwoKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCA9IHNlc3Npb25JZDsKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEluaXRpYWxpemUgdGhlIG9jY3VwaWVkIGxpc3QgT05MWSBpZiB3ZSBhcmUKICAgICAgICAgICAgICogdHJhbnNpdGlvbmluZyBmcm9tIElOSVQgc3RhdGUgdG8gQ09OTkVDVEVEIHN0YXRlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUID09IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgICAgICAgICAgICAgIGNzckluaXRPY2N1cGllZENoYW5uZWxzTGlzdChwTWFjKTsKI2VuZGlmCiAgICAgICAgICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NPTk5FQ1RFRCk7CgogICAgICAgICAgICB2b3NfbWVtX2NvcHkocE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuYnNzaWQsIHNpemVvZih0Q3NyQnNzaWQpKTsKICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUG9wZXJhdGlvbkNoYW5uZWwgPSBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5vcGVyYXRpb25DaGFubmVsOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0KICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JMb29rdXBUaHJlc2hvbGQ7CiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51RW1wdHlTY2FuQ291bnQgPSAwOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bG9va3VwRE9XTlJzc2kgPSAwOwogICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dVNjYW5Nb2RlID0gREVGQVVMVF9TQ0FOOwojZW5kaWYKCiAgICAgICAgICAgIAojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICAgICAgICAgIC8qIE5vdyB3ZSBjYW4gY2xlYXIgdGhlIHByZWF1dGhEb25lIHRoYXQgd2FzIHNhdmVkIGFzIHdlIGFyZSBjb25uZWN0ZWQgYWZyZXNoICovCiAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbUZyZWVSb2FtYWJsZUJTU0xpc3QocE1hYywgJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCk7CiNlbmRpZgogICAgICAgICAgICAKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCiAgICAgICAgICAgIC8vIEJhc2VkIG9uIHRoZSBhdXRoIHNjaGVtZSB0ZWxsIGlmIHdlIGFyZSAxMXIKICAgICAgICAgICAgaWYgKCBjc3JJc0F1dGhUeXBlMTFyKCBwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5BdXRoVHlwZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5yb2FtU2Vzc2lvbltzZXNzaW9uSWRdLmNvbm5lY3RlZFByb2ZpbGUuTURJRC5tZGllUHJlc2VudCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLmlzRmFzdFRyYW5zaXRpb25FbmFibGVkKQogICAgICAgICAgICAgICAgICAgIGluaXRfZnRfZmxhZyA9IFRSVUU7CiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYyA9IGVBTklfQk9PTEVBTl9UUlVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCIxMXJBc3NvYyBpcyA9ICVkIiksIHBOZWlnaGJvclJvYW1JbmZvLT5pczExckFzc29jKTsKI2VuZGlmCgojaWZkZWYgRkVBVFVSRV9XTEFOX0VTRQogICAgICAgICAgICAvLyBCYXNlZCBvbiB0aGUgYXV0aCBzY2hlbWUgdGVsbCBpZiB3ZSBhcmUgMTFyCiAgICAgICAgICAgIGlmIChwTWFjLT5yb2FtLnJvYW1TZXNzaW9uW3Nlc3Npb25JZF0uY29ubmVjdGVkUHJvZmlsZS5pc0VTRUFzc29jKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocE1hYy0+cm9hbS5jb25maWdQYXJhbS5pc0Zhc3RUcmFuc2l0aW9uRW5hYmxlZCkKICAgICAgICAgICAgICAgICAgICBpbml0X2Z0X2ZsYWcgPSBUUlVFOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRVNFQXNzb2MgPSBlQU5JX0JPT0xFQU5fVFJVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKICAgICAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cyLCBGTCgiaXNFU0VBc3NvYyBpcyA9ICVkIGZ0ID0gJWQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYywgaW5pdF9mdF9mbGFnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAojZW5kaWYKCiNpZmRlZiBGRUFUVVJFX1dMQU5fTEZSCiAgICAgICAgICAgIC8vIElmICJMZWdhY3kgRmFzdCBSb2FtaW5nIiBpcyBlbmFibGVkIAogICAgICAgICAgICBpZiAoY3NyUm9hbUlzRmFzdFJvYW1FbmFibGVkKHBNYWMsIHNlc3Npb25JZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGluaXRfZnRfZmxhZyA9IFRSVUU7CiAgICAgICAgICAgIH0KI2VuZGlmCgojaWYgIGRlZmluZWQgKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkIChGRUFUVVJFX1dMQU5fRVNFKSB8fCBkZWZpbmVkKEZFQVRVUkVfV0xBTl9MRlIpCiAgICAgICAgICAgIGlmICggaW5pdF9mdF9mbGFnID09IFRSVUUgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBJbml0aWFsaXplIGFsbCB0aGUgZGF0YSBzdHJ1Y3R1cmVzIG5lZWRlZCBmb3IgdGhlIDExciBGVCBQcmVhdXRoICovCiAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsZWRMaXN0KHBNYWMpOwojaWZkZWYgV0xBTl9GRUFUVVJFX1JPQU1fU0NBTl9PRkZMT0FECiAgICAgICAgICAgICAgaWYgKGNzclJvYW1Jc1JvYW1PZmZsb2FkU2NhbkVuYWJsZWQocE1hYykpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgIC8qSWYgdGhpcyBpcyBub3QgYSBJTkZSQSB0eXBlIEJTUywgdGhlbiBkbyBub3Qgc2VuZCB0aGUgY29tbWFuZAogICAgICAgICAgICAgICAgICAqIGRvd24gdG8gZmlybXdhcmUuRG8gbm90IHNlbmQgdGhlIFNUQVJUIGNvbW1hbmQgZm9yIG90aGVyIHNlc3Npb24KICAgICAgICAgICAgICAgICAgKiBjb25uZWN0aW9ucy4qLwogICAgICAgICAgICAgICAgIGlmKGNzclJvYW1Jc1N0YU1vZGUocE1hYywgc2Vzc2lvbklkKSkKICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCA9IDA7CiAgICAgICAgICAgICAgICAgICAgIGlmKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubmVpZ2hib3JJbml0aWFsRm9yY2VkUm9hbVRvNUdoRW5hYmxlICYmCiAgICAgICAgICAgICAgICAgICAgICAgKEdldFJGQmFuZChwTmVpZ2hib3JSb2FtSW5mby0+Y3VyckFQb3BlcmF0aW9uQ2hhbm5lbCkgPT0KICAgICAgICAgICAgICAgICAgICAgICAgU0lSX0JBTkRfMl80X0dIWikpCiAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAgKiBLZWVwIDVHIGFuZCBGd3Igcm9hbWluZyBtdXR1YWxseSBleGNsdXNpdmUgc28gZG8gbm90CiAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzZW5kIFJTTyBzdGFydCBOb3RlIHdlIGhhdmUgdG8gc2VuZCBSU08gc3RhcnQgaW4gYWxsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKiBlcnJybyBjYXNlLgogICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGTCgiRG8gbm90IHNlbmQgUlNPIHN0YXJ0IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiZWNhdXNlIDVHIGZvcmNlIHJvYW1pbmcgaXMgZW5hYmxlZCIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwgUkVBU09OX0NPTk5FQ1QpOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9IGVsc2UgewojZW5kaWYKCiAgICAgICAgICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzIsIEZMKCJSZWdpc3RlcmluZyBuZWlnaGJvciBsb29rdXAgRE9XTiBldmVudCB3aXRoIFRMLCBSU1NJID0gJWQiKSwgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCk7CiAgICAgICAgICAgICAgICAvKiBSZWdpc3RlciBOZWlnaGJvciBMb29rdXAgdGhyZXNob2xkIGNhbGxiYWNrIHdpdGggVEwgZm9yIERPV04gZXZlbnQgb25seSAqLwogICAgICAgICAgICAgICAgdnN0YXR1cyA9IFdMQU5UTF9SZWdSU1NJSW5kaWNhdGlvbkNCKHBNYWMtPnJvYW0uZ1Zvc0NvbnRleHQsICh2X1M3X3QpcE5laWdoYm9yUm9hbUluZm8tPmN1cnJlbnROZWlnaGJvckxvb2t1cFRocmVzaG9sZCAqICgtMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0xBTlRMX0hPX1RIUkVTSE9MRF9ET1dOLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjaywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVk9TX01PRFVMRV9JRF9TTUUsIHBNYWMpOwojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUgogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmxvb2t1cERPV05Sc3NpID0gMDsKI2VuZGlmCiAgICAgICAgICAgICAgICBpZighVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZzdGF0dXMpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgLy9lcnIgbXNnCiAgICAgICAgICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HVywgRkwoIiBDb3VsZG4ndCByZWdpc3RlciBjc3JOZWlnaGJvclJvYW1OZWlnaGJvckxvb2t1cERPV05DYWxsYmFjayB3aXRoIFRMOiBTdGF0dXMgPSAlZCIpLCB2c3RhdHVzKTsKICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgICAgICB9CiNpZmRlZiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKICAgICAgICAgICAgICB9CiNlbmRpZiAvKiBXTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQgKi8KICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJDb25uZWN0IGV2ZW50IHJlY2VpdmVkIGluIGludmFsaWQgc3RhdGUgJXMiCiAgICAgICAgICAgICAgICAgICAiLi5JZ25vcmluZy4uLiIpLAogICAgICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CgoKI2lmZGVmIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1QdXJnZVByZWF1dGhGYWlsZWRMaXN0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIHB1cmdlcyBhbGwgdGhlIE1BQyBhZGRyZXNzZXMgaW4gdGhlIHByZS1hdXRoIGZhaWwgbGlzdAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIFZPSUQKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgY3NyTmVpZ2hib3JSb2FtUHVyZ2VQcmVhdXRoRmFpbGVkTGlzdCh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0QU5JX1U4IGk7CgogICAgZm9yIChpID0gMDsgaSA8IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzOyBpKyspCiAgICB7CiAgICAgICAgdm9zX21lbV96ZXJvKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5tYWNBZGRyZXNzW2ldLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgIH0KICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLnByZUF1dGhGYWlsTGlzdC5udW1NQUNBZGRyZXNzID0gMDsKCiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jbml0MTFyQXNzb2NJbmZvCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGluaXRpYWxpemVzIDExciByZWxhdGVkIG5laWdoYm9yIHJvYW0gZGF0YSBzdHJ1Y3R1cmVzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUluaXQxMXJBc3NvY0luZm8odHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgZUhhbFN0YXR1cyAgc3RhdHVzOwogICAgdHBDc3IxMXJBc3NvY05laWdoYm9ySW5mbyAgIHBGVFJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvOwoKICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5pczExckFzc29jID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5tYXhOZWlnaGJvclJldHJpZXMgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTWF4TmVpZ2hib3JSZXRyaWVzOwogICAgcEZUUm9hbUluZm8tPm5laWdoYm9yUmVwb3J0VGltZW91dCA9IENTUl9ORUlHSEJPUl9ST0FNX1JFUE9SVF9RVUVSWV9USU1FT1VUOwogICAgcEZUUm9hbUluZm8tPlBFUHJlYXV0aFJlc3BUaW1lb3V0ID0gQ1NSX05FSUdIQk9SX1JPQU1fUFJFQVVUSF9SU1BfV0FJVF9NVUxUSVBMSUVSICogcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvclNjYW5QZXJpb2Q7CiAgICBwRlRSb2FtSW5mby0+bmVpZ2hib3JScHRQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcEZUUm9hbUluZm8tPnByZWF1dGhSc3BQZW5kaW5nID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgCiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5jdXJyZW50TmVpZ2hib3JScHRSZXRyeU51bSA9IDA7CiAgICBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5udW1Cc3NGcm9tTmVpZ2hib3JSZXBvcnQgPSAwOwogICAgdm9zX21lbV96ZXJvKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5GVFJvYW1JbmZvLm5laWdoYm9SZXBvcnRCc3NJbmZvLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih0Q3NyTmVpZ2hib3JSZXBvcnRCc3NJbmZvKSAqIE1BWF9CU1NfSU5fTkVJR0hCT1JfUlBUKTsKCiAgICAKICAgIHN0YXR1cyA9IGNzckxMT3BlbihwTWFjLT5oSGRkLCAmcEZUUm9hbUluZm8tPnByZUF1dGhEb25lTGlzdCk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJMTCBPcGVuIG9mIHByZWF1dGggZG9uZSBBUCBMaXN0IGZhaWxlZCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfUkVTT1VSQ0VTOwogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1Jbml0CgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGluaXRpYWxpemVzIG5laWdoYm9yIHJvYW0gZGF0YSBzdHJ1Y3R1cmVzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUluaXQodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgZUhhbFN0YXR1cyBzdGF0dXM7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUgICAgICAgPSAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DTE9TRUQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cHJldk5laWdoYm9yUm9hbVN0YXRlICAgPSAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DTE9TRUQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkICAgICAgICAgICAgPSAgIENTUl9TRVNTSU9OX0lEX0lOVkFMSUQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm1heENoYW5uZWxTY2FuVGltZSA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvclNjYW5NYXhDaGFuVGltZTsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMubWluQ2hhbm5lbFNjYW5UaW1lID0gcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubk5laWdoYm9yU2Nhbk1pbkNoYW5UaW1lOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5tYXhOZWlnaGJvclJldHJpZXMgPSAwOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZCA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvckxvb2t1cFJzc2lUaHJlc2hvbGQ7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVhc3NvY1RocmVzaG9sZCA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5OZWlnaGJvclJlYXNzb2NSc3NpVGhyZXNob2xkOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvclNjYW5QZXJpb2QgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JTY2FuVGltZXJQZXJpb2Q7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLm5laWdoYm9yUmVzdWx0c1JlZnJlc2hQZXJpb2QgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JSZXN1bHRzUmVmcmVzaFBlcmlvZDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuZW1wdHlTY2FuUmVmcmVzaFBlcmlvZCA9IHBNYWMtPnJvYW0uY29uZmlnUGFyYW0ubmVpZ2hib3JSb2FtQ29uZmlnLm5FbXB0eVNjYW5SZWZyZXNoUGVyaW9kOwogICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5uZWlnaGJvckluaXRpYWxGb3JjZWRSb2FtVG81R2hFbmFibGUgPSBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uTmVpZ2hib3JJbml0aWFsRm9yY2VkUm9hbVRvNUdoRW5hYmxlOwoKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyAgID0KICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubmVpZ2hib3JTY2FuQ2hhbkxpc3QubnVtQ2hhbm5lbHM7CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyAhPSAwKQogICAgewogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPQogICAgICAgICAgICAgICAgdm9zX21lbV9tYWxsb2MocE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubmVpZ2hib3JTY2FuQ2hhbkxpc3QubnVtQ2hhbm5lbHMpOwoKICAgICAgICBpZiAoTlVMTCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgQWxsb2NhdGlvbiBmb3IgQ0ZHIENoYW5uZWwgTGlzdCBmYWlsZWQiKSk7CiAgICAgICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICAgICAgfQoKICAgICAgICAvKiBVcGRhdGUgdGhlIHJvYW0gZ2xvYmFsIHN0cnVjdHVyZSBmcm9tIENGRyAqLwogICAgICAgIHZvc19tZW1fY29weShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICBwTWFjLT5yb2FtLmNvbmZpZ1BhcmFtLm5laWdoYm9yUm9hbUNvbmZpZy5uZWlnaGJvclNjYW5DaGFuTGlzdC5jaGFubmVsTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgcE1hYy0+cm9hbS5jb25maWdQYXJhbS5uZWlnaGJvclJvYW1Db25maWcubmVpZ2hib3JTY2FuQ2hhbkxpc3QubnVtQ2hhbm5lbHMpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgICBzbXNMb2cocE1hYywgTE9HVywKICAgICAgICAgICAgICAgIEZMKCJpbnZhbGlkIG5laWdoYm9yIHJvYW0gY2hhbm5lbCBsaXN0OiAldSIpLAogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8ubnVtT2ZDaGFubmVscyk7CiAgICB9CgogICAgdm9zX21lbV9zZXQocE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLCBzaXplb2YodENzckJzc2lkKSwgMCk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3VycmVudE5laWdoYm9yTG9va3VwVGhyZXNob2xkID0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLmNmZ1BhcmFtcy5uZWlnaGJvckxvb2t1cFRocmVzaG9sZDsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sb29rdXBET1dOUnNzaSA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+dUVtcHR5U2NhbkNvdW50ID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT51U2Nhbk1vZGUgPSBERUZBVUxUX1NDQU47CiAgICB2b3NfbWVtX3NldCgmcE5laWdoYm9yUm9hbUluZm8tPnByZXZDb25uUHJvZmlsZSwgc2l6ZW9mKHRDc3JSb2FtQ29ubmVjdGVkUHJvZmlsZSksIDApOwojZW5kaWYKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5zY2FuUnNwUGVuZGluZyA9IGVBTklfQk9PTEVBTl9GQUxTRTsKCiAgICBzdGF0dXMgPSB2b3NfdGltZXJfaW5pdCgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyLCBWT1NfVElNRVJfVFlQRV9TVywKICAgICAgICAgICAgICAgICAgICBjc3JOZWlnaGJvclJvYW1OZWlnaGJvclNjYW5UaW1lckNhbGxiYWNrLCAodm9pZCAqKXBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIk5laWdoYm9yIHNjYW4gdGltZXIgYWxsb2NhdGlvbiBmYWlsZWQiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CgogICAgc3RhdHVzID0gdm9zX3RpbWVyX2luaXQoJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIsIFZPU19USU1FUl9UWVBFX1NXLAogICAgICAgICAgICAgICAgICAgIGNzck5laWdoYm9yUm9hbVJlc3VsdHNSZWZyZXNoVGltZXJDYWxsYmFjaywgKHZvaWQgKilwTWFjKTsKCiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciByZXN1bHRzIHJlZnJlc2ggdGltZXIgYWxsb2NhdGlvbiBmYWlsZWQiKSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JTY2FuVGltZXIpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CgogICAgc3RhdHVzID0gdm9zX3RpbWVyX2luaXQoJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIsIFZPU19USU1FUl9UWVBFX1NXLAogICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtRW1wdHlTY2FuUmVmcmVzaFRpbWVyQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAodm9pZCAqKXBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIkVtcHR5IHNjYW4gcmVmcmVzaCB0aW1lciBhbGxvY2F0aW9uIGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CgogICAgc3RhdHVzID0gdm9zX3RpbWVyX2luaXQoJnBOZWlnaGJvclJvYW1JbmZvLT5mb3JjZWRJbml0aWFsUm9hbVRvNUdIVGltZXIsIFZPU19USU1FUl9UWVBFX1NXLAogICAgICAgICAgICAgICAgY3NyRm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyQ2FsbGJhY2ssICh2b2lkICopcE1hYyk7CgogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiZm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyIHRpbWVyIGFsbG9jYXRpb24gZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CgogICAgc3RhdHVzID0gY3NyTExPcGVuKHBNYWMtPmhIZGQsICZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgaWYgKGVIQUxfU1RBVFVTX1NVQ0NFU1MgIT0gc3RhdHVzKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiTEwgT3BlbiBvZiByb2FtYWJsZSBBUCBMaXN0IGZhaWxlZCIpKTsKICAgICAgICB2b3NfbWVtX2ZyZWUocE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCk7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmNmZ1BhcmFtcy5jaGFubmVsSW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclNjYW5UaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJlc3VsdHNSZWZyZXNoVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPmZvcmNlZEluaXRpYWxSb2FtVG81R0hUaW1lcik7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX1JFU09VUkNFUzsKICAgIH0KCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFuSW5kZXggPSBDU1JfTkVJR0hCT1JfUk9BTV9JTlZBTElEX0NIQU5ORUxfSU5ERVg7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8ubnVtT2ZDaGFubmVscyA9IDA7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jaGFuTGlzdFNjYW5JblByb2dyZXNzID0gZUFOSV9CT09MRUFOX0ZBTFNFOwogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIHN0YXR1cyA9IGNzck5laWdoYm9yUm9hbUluaXQxMXJBc3NvY0luZm8ocE1hYyk7CiAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJMTCBPcGVuIG9mIHJvYW1hYmxlIEFQIExpc3QgZmFpbGVkIikpOwogICAgICAgIHZvc19tZW1fZnJlZShwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KTsKICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y2ZnUGFyYW1zLmNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgICAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUmVzdWx0c1JlZnJlc2hUaW1lcik7CiAgICAgICAgdm9zX3RpbWVyX2Rlc3Ryb3koJnBOZWlnaGJvclJvYW1JbmZvLT5lbXB0eVNjYW5SZWZyZXNoVGltZXIpOwogICAgICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+Zm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyKTsKICAgICAgICBjc3JMTENsb3NlKCZwTmVpZ2hib3JSb2FtSW5mby0+cm9hbWFibGVBUExpc3QpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19SRVNPVVJDRVM7CiAgICB9CiNlbmRpZgogICAgLyogSW5pdGlhbGl6ZSB0aGlzIHdpdGggdGhlIGN1cnJlbnQgdGljayBjb3VudCAqLwogICAgcE5laWdoYm9yUm9hbUluZm8tPnNjYW5SZXF1ZXN0VGltZVN0YW1wID0gKHRBTklfVElNRVNUQU1QKXBhbEdldFRpY2tDb3VudChwTWFjLT5oSGRkKTsKCiAgICBDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9UUkFOU0lUSU9OKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9JTklUKQogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgLy9TZXQgdGhlIExhc3QgU2VudCBDbWQgYXMgUlNPX1NUT1AKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5sYXN0U2VudENtZCA9IFJPQU1fU0NBTl9PRkZMT0FEX1NUT1A7CiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbUNsb3NlCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGNsb3Nlcy9mcmVlcyBhbGwgdGhlIG5laWdoYm9yIHJvYW0gZGF0YSBzdHJ1Y3R1cmVzCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1DbG9zZSh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBpZiAoZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0NMT1NFRCA9PSBwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSb2FtU3RhdGUpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csIEZMKCJOZWlnaGJvciBSb2FtIEFsZ29yaXRobSBBbHJlYWR5IENsb3NlZCIpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpOwogICAKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jZmdQYXJhbXMuY2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPSBOVUxMOwogICAgCiAgICB2b3NfdGltZXJfZGVzdHJveSgmcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yU2NhblRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+bmVpZ2hib3JSZXN1bHRzUmVmcmVzaFRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+ZW1wdHlTY2FuUmVmcmVzaFRpbWVyKTsKICAgIHZvc190aW1lcl9kZXN0cm95KCZwTmVpZ2hib3JSb2FtSW5mby0+Zm9yY2VkSW5pdGlhbFJvYW1UbzVHSFRpbWVyKTsKCiAgICAvKiBTaG91bGQgZnJlZSB1cCB0aGUgbm9kZXMgaW4gdGhlIGxpc3QgYmVmb3JlIGNsb3NpbmcgdGhlIGRvdWJsZSBMaW5rZWQgbGlzdCAqLwogICAgY3NyTmVpZ2hib3JSb2FtRnJlZVJvYW1hYmxlQlNTTGlzdChwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KTsKICAgIGNzckxMQ2xvc2UoJnBOZWlnaGJvclJvYW1JbmZvLT5yb2FtYWJsZUFQTGlzdCk7CiAgICAKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmN1cnJlbnRDaGFubmVsTGlzdEluZm8uQ2hhbm5lbExpc3QpCiAgICB7CiAgICAgICAgdm9zX21lbV9mcmVlKHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCk7CiAgICB9CgogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5jdXJyZW50Q2hhbm5lbExpc3RJbmZvLkNoYW5uZWxMaXN0ID0gTlVMTDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5JbmRleCA9IENTUl9ORUlHSEJPUl9ST0FNX0lOVkFMSURfQ0hBTk5FTF9JTkRFWDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5udW1PZkNoYW5uZWxzID0gMDsKICAgIHBOZWlnaGJvclJvYW1JbmZvLT5yb2FtQ2hhbm5lbEluZm8uY3VycmVudENoYW5uZWxMaXN0SW5mby5DaGFubmVsTGlzdCA9IE5VTEw7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLmNoYW5MaXN0U2NhbkluUHJvZ3Jlc3MgPSBlQU5JX0JPT0xFQU5fRkFMU0U7ICAgIAogICAgcE5laWdoYm9yUm9hbUluZm8tPnJvYW1DaGFubmVsSW5mby5JQVBQTmVpZ2hib3JMaXN0UmVjZWl2ZWQgPSBlQU5JX0JPT0xFQU5fRkFMU0U7CgogICAgLyogRnJlZSB0aGUgcHJvZmlsZS4uICovIAogICAgY3NyUmVsZWFzZVByb2ZpbGUocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlKTsKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIgICAgCiAgICBjc3JSb2FtRnJlZUNvbm5lY3RQcm9maWxlKHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+cHJldkNvbm5Qcm9maWxlKTsKI2VuZGlmCiNpZmRlZiBXTEFOX0ZFQVRVUkVfVk9XSUZJXzExUgogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8uY3VycmVudE5laWdoYm9yUnB0UmV0cnlOdW0gPSAwOwogICAgcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ubnVtQnNzRnJvbU5laWdoYm9yUmVwb3J0ID0gMDsKICAgIHZvc19tZW1femVybyhwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5uZWlnaGJvUmVwb3J0QnNzSW5mbywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodENzck5laWdoYm9yUmVwb3J0QnNzSW5mbykgKiBNQVhfQlNTX0lOX05FSUdIQk9SX1JQVCk7CiAgICBjc3JOZWlnaGJvclJvYW1GcmVlUm9hbWFibGVCU1NMaXN0KHBNYWMsICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uRlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpOwogICAgY3NyTExDbG9zZSgmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLkZUUm9hbUluZm8ucHJlQXV0aERvbmVMaXN0KTsKI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSICovCgogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0xPU0VEKQogICAgCiAgICByZXR1cm47Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1SZXF1ZXN0SGFuZG9mZgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiB0cmlnZ2VycyBhY3R1YWwgc3dpdGNoaW5nIGZyb20gb25lIEFQIHRvIHRoZSBuZXcgQVAuCiAgICAgICAgICAgIEl0IGlzc3VlcyBkaXNhc3NvY2lhdGUgd2l0aCByZWFzb24gY29kZSBhcyBIYW5kb2ZmIGFuZCBDU1IgYXMgYSBwYXJ0IG9mIAogICAgICAgICAgICBoYW5kbGluZyBkaXNhc3NvYyByc3AsIGlzc3VlcyByZWFzc29jaWF0ZSB0byB0aGUgbmV3IEFQCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gVk9JRAoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kdm9pZCBjc3JOZWlnaGJvclJvYW1SZXF1ZXN0SGFuZG9mZih0cEFuaVNpckdsb2JhbCBwTWFjKQp7CgogICAgdENzclJvYW1JbmZvIHJvYW1JbmZvOwogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0QU5JX1UzMiBzZXNzaW9uSWQgPSBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkOwogICAgdENzck5laWdoYm9yUm9hbUJTU0luZm8gICAgIGhhbmRvZmZOb2RlOwogICAgZXh0ZXJuIHZvaWQgY3NyUm9hbVJvYW1pbmdTdGF0ZURpc2Fzc29jUnNwUHJvY2Vzc29yKCB0cEFuaVNpckdsb2JhbCBwTWFjLCB0U2lyU21lRGlzYXNzb2NSc3AgKnBTbWVEaXNhc3NvY1JzcCApOwogICAgdEFOSV9VMzIgcm9hbUlkID0gMDsKICAgIGVIYWxTdGF0dXMgc3RhdHVzOwoKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlJfTUVUUklDUwogICAgdENzclJvYW1JbmZvICpyb2FtSW5mb01ldHJpY3M7CiNlbmRpZgoKICAgIGlmIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUgIT0gZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORSkgCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSb2FtIHJlcXVlc3RlZCB3aGVuIE5laWdoYm9yIHJvYW0gaXMgaW4gJXMgc3RhdGUiKSwKICAgICAgICAgICAgICAgbWFjVHJhY2VHZXROZWlnaGJvdXJSb2FtU3RhdGUoCiAgICAgICAgICAgICAgIHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSkpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoZUFOSV9CT09MRUFOX0ZBTFNFID09CiAgICAgICAgIGNzck5laWdoYm9yUm9hbUdldEhhbmRvZmZBUEluZm8ocE1hYywgJmhhbmRvZmZOb2RlKSkKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICBGTCgiZmFpbGVkIHRvIG9idGFpbiBoYW5kb2ZmIEFQIikpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfREVCVUcsCiAgICAgICAgICAgICAgIEZMKCJIQU5ET0ZGIENBTkRJREFURSBCU1NJRCAiTUFDX0FERFJFU1NfU1RSKSwKICAgICAgICAgICAgICAgICAgIE1BQ19BRERSX0FSUkFZKGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+YnNzSWQpKTsKCiAgICB2b3NfbWVtX3plcm8oJnJvYW1JbmZvLCBzaXplb2YodENzclJvYW1JbmZvKSk7CiAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsICZyb2FtSW5mbywgcm9hbUlkLCBlQ1NSX1JPQU1fRlRfU1RBUlQsIAogICAgICAgICAgICAgICAgZVNJUl9TTUVfU1VDQ0VTUyk7CgogICAgdm9zX21lbV96ZXJvKCZyb2FtSW5mbywgc2l6ZW9mKHRDc3JSb2FtSW5mbykpOwogICAgQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfVFJBTlNJVElPTihlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORykKICAgIAojaWZkZWYgRkVBVFVSRV9XTEFOX0xGUl9NRVRSSUNTCiAgICAvKiBMRlIgbWV0cmljcyAtIHByZS1hdXRoIGNvbXBsZXRpb24gbWV0cmljLgogICAgICAgU2VuZCB0aGUgZXZlbnQgdG8gc3VwcGxpY2FudCB0aGF0IHByZS1hdXRoIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQgKi8KICAgIHJvYW1JbmZvTWV0cmljcyA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbUluZm8pKTsKICAgIGlmIChOVUxMID09IHJvYW1JbmZvTWV0cmljcykKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HMSwgRkwoIk1lbW9yeSBhbGxvY2F0aW9uIGZhaWxlZCEiKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdm9zX21lbV9jb3B5KCh2b2lkICopcm9hbUluZm9NZXRyaWNzLT5ic3NpZCwKICAgICAgICAgICAgKHZvaWQgKikmaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgc2l6ZW9mKHRDc3JCc3NpZCkpOwogICAgICAgIGNzclJvYW1DYWxsQ2FsbGJhY2socE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwKICAgICAgICAgICAgcm9hbUluZm9NZXRyaWNzLCAwLCBlQ1NSX1JPQU1fSEFORE9WRVJfU1VDQ0VTUywgMCk7CiAgICAgICAgdm9zX21lbV9mcmVlKHJvYW1JbmZvTWV0cmljcyk7CiAgICB9CiNlbmRpZgoKICAgIC8qIEZyZWUgdGhlIHByb2ZpbGUuLiBKdXN0IHRvIG1ha2Ugc3VyZSB3ZSBkb250IGxlYWsgbWVtb3J5IGhlcmUgKi8gCiAgICBjc3JSZWxlYXNlUHJvZmlsZShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPmNzck5laWdoYm9yUm9hbVByb2ZpbGUpOwogICAgLyogQ3JlYXRlIHRoZSBIYW5kb2ZmIEFQIHByb2ZpbGUuIENvcHkgdGhlIGN1cnJlbnRseSBjb25uZWN0ZWQgcHJvZmlsZSBhbmQgdXBkYXRlIG9ubHkgdGhlIEJTU0lEIGFuZCBjaGFubmVsIG51bWJlcgogICAgICAgIFRoaXMgc2hvdWxkIGhhcHBlbiBiZWZvcmUgaXNzdWluZyBkaXNjb25uZWN0ICovCiAgICBzdGF0dXMgPSBjc3JSb2FtQ29weUNvbm5lY3RlZFByb2ZpbGUocE1hYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZSk7CiAgICBpZihlSEFMX1NUQVRVU19TVUNDRVNTICE9IHN0YXR1cykKICAgIHsKICAgICAgICBWT1NfVFJBQ0UgKFZPU19NT0RVTEVfSURfU01FLCBWT1NfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgRkwoImNzclJvYW1Db3B5Q29ubmVjdGVkUHJvZmlsZSByZXR1cm5lZCBmYWlsZWQgJWQiKSwgc3RhdHVzKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5jc3JOZWlnaGJvclJvYW1Qcm9maWxlLkJTU0lEcy5ic3NpZCwgaGFuZG9mZk5vZGUucEJzc0Rlc2NyaXB0aW9uLT5ic3NJZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSk7CiAgICBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyTmVpZ2hib3JSb2FtUHJvZmlsZS5DaGFubmVsSW5mby5DaGFubmVsTGlzdFswXSA9IGhhbmRvZmZOb2RlLnBCc3NEZXNjcmlwdGlvbi0+Y2hhbm5lbElkOwogICAgCiAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPR1csICIgY3NyUm9hbUhhbmRvZmZSZXF1ZXN0ZWQ6IGRpc2Fzc29jaWF0aW5nIHdpdGggY3VycmVudCBBUCIpOwoKICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1MoY3NyUm9hbUlzc3VlRGlzYXNzb2NpYXRlQ21kKHBNYWMsIHNlc3Npb25JZCwgZUNTUl9ESVNDT05ORUNUX1JFQVNPTl9IQU5ET0ZGKSkpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR1csICJjc3JSb2FtSGFuZG9mZlJlcXVlc3RlZDogIGZhaWwgdG8gaXNzdWUgZGlzYXNzb2NpYXRlIik7CiAgICAgICAgcmV0dXJuOwogICAgfSAgICAgICAgICAgICAgICAgICAgICAgCgogICAgLy9ub3RpZnkgSEREIGZvciBoYW5kb2ZmLCBwcm92aWRpbmcgdGhlIEJTU0lEIHRvbwogICAgcm9hbUluZm8ucmVhc29uQ29kZSA9IGVDc3JSb2FtUmVhc29uQmV0dGVyQVA7CgogICAgdm9zX21lbV9jb3B5KHJvYW1JbmZvLmJzc2lkLCAKICAgICAgICAgICAgICAgICBoYW5kb2ZmTm9kZS5wQnNzRGVzY3JpcHRpb24tPmJzc0lkLCAKICAgICAgICAgICAgICAgICBzaXplb2YoIHRDc3JCc3NpZCApKTsKCiAgICBjc3JSb2FtQ2FsbENhbGxiYWNrKHBNYWMsIHNlc3Npb25JZCwgJnJvYW1JbmZvLCAwLCBlQ1NSX1JPQU1fUk9BTUlOR19TVEFSVCwgZUNTUl9ST0FNX1JFU1VMVF9OT05FKTsKCgogICAgcmV0dXJuOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXNIYW5kb2ZmSW5Qcm9ncmVzcwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHdoZXRoZXIgaGFuZG9mZiBpcyBpbiBwcm9ncmVzcyBvciBub3QgYmFzZWQgb24gCiAgICAgICAgICAgIHRoZSBjdXJyZW50IG5laWdoYm9yIHJvYW0gc3RhdGUKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIGlzMTFyUmVhc3NvYyAtIFJldHVybiB3aGV0aGVyIHJlYXNzb2MgaXMgb2YgdHlwZSA4MDIuMTFyIHJlYXNzb2MKCiAgICBccmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFIGlmIHJlYXNzb2MgaW4gcHJvZ3Jlc3MsIGVBTklfQk9PTEVBTl9GQUxTRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1Jc0hhbmRvZmZJblByb2dyZXNzKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpCiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwoKICAgIHJldHVybiBlQU5JX0JPT0xFQU5fRkFMU0U7Cn0KCiNpZiBkZWZpbmVkKFdMQU5fRkVBVFVSRV9WT1dJRklfMTFSKSB8fCBkZWZpbmVkKFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HKQovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtSXMxMXJBc3NvYwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHdoZXRoZXIgdGhlIGN1cnJlbnQgYXNzb2NpYXRpb24gaXMgYSAxMXIgYXNzb2Mgb3Igbm90CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUFOSV9CT09MRUFOX1RSVUUgaWYgY3VycmVudCBhc3NvYyBpcyAxMXIsIGVBTklfQk9PTEVBTl9GQUxTRSBvdGhlcndpc2UKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnRBTklfQk9PTEVBTiBjc3JOZWlnaGJvclJvYW1JczExckFzc29jKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHJldHVybiBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8uaXMxMXJBc3NvYzsKfQojZW5kaWYgLyogV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIgKi8KCgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtR2V0SGFuZG9mZkFQSW5mbwoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIHRoZSBiZXN0IHBvc3NpYmxlIEFQIGZvciBoYW5kb2ZmLiBGb3IgMTFSIGNhc2UsIGl0IAogICAgICAgICAgICByZXR1cm5zIHRoZSAxc3QgZW50cnkgZnJvbSBwcmUtYXV0aCBkb25lIGxpc3QuIEZvciBub24tMTFyIGNhc2UsIGl0IHJldHVybnMgCiAgICAgICAgICAgIHRoZSAxc3QgZW50cnkgZnJvbSByb2FtYWJsZSBBUCBsaXN0CgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgogICAgICAgICAgICBwSGFuZG9mZk5vZGUgLSBBUCBub2RlIHRoYXQgaXMgdGhlIGhhbmRvZmYgY2FuZGlkYXRlIHJldHVybmVkCgogICAgXHJldHVybiBlQU5JX0JPT0xFQU5fVFJVRSBpZiBhYmxlIGZpbmQgaGFuZG9mZiBBUCwgZUFOSV9CT09MRUFOX0ZBTFNFIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbUdldEhhbmRvZmZBUEluZm8odHBBbmlTaXJHbG9iYWwgcE1hYywgdHBDc3JOZWlnaGJvclJvYW1CU1NJbmZvIHBIYW5kb2ZmTm9kZSkKewogICAgdHBDc3JOZWlnaGJvclJvYW1Db250cm9sSW5mbyAgICBwTmVpZ2hib3JSb2FtSW5mbyA9ICZwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm87CiAgICB0cENzck5laWdoYm9yUm9hbUJTU0luZm8gICAgICAgIHBCc3NOb2RlID0gTlVMTDsKICAgIAogICAgVk9TX0FTU0VSVChOVUxMICE9IHBIYW5kb2ZmTm9kZSk7IAogICAgICAgIAojaWZkZWYgV0xBTl9GRUFUVVJFX1ZPV0lGSV8xMVIKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXMxMXJBc3NvYykKICAgIHsKICAgICAgICAvKiBBbHdheXMgdGhlIEJTUyBpbmZvIGluIHRoZSBoZWFkIGlzIHRoZSBoYW5kb2ZmIGNhbmRpZGF0ZSAqLwogICAgICAgIHBCc3NOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCwgTlVMTCk7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksIGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCkpOwogICAgfQogICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9FU0UKICAgIGlmIChwTmVpZ2hib3JSb2FtSW5mby0+aXNFU0VBc3NvYykKICAgIHsKICAgICAgICAvKiBBbHdheXMgdGhlIEJTUyBpbmZvIGluIHRoZSBoZWFkIGlzIHRoZSBoYW5kb2ZmIGNhbmRpZGF0ZSAqLwogICAgICAgIHBCc3NOb2RlID0gY3NyTmVpZ2hib3JSb2FtR2V0Um9hbWFibGVBUExpc3ROZXh0RW50cnkocE1hYywgJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCwgTlVMTCk7CiAgICAgICAgTkVJR0hCT1JfUk9BTV9ERUJVRyhwTWFjLCBMT0cxLCBGTCgiTnVtYmVyIG9mIEhhbmRvZmYgY2FuZGlkYXRlcyA9ICVkIiksIGNzckxMQ291bnQoJnBOZWlnaGJvclJvYW1JbmZvLT5GVFJvYW1JbmZvLnByZUF1dGhEb25lTGlzdCkpOwogICAgfQogICAgZWxzZQojZW5kaWYKI2lmZGVmIEZFQVRVUkVfV0xBTl9MRlIKICAgIGlmIChjc3JSb2FtSXNGYXN0Um9hbUVuYWJsZWQocE1hYywgQ1NSX1NFU1NJT05fSURfSU5WQUxJRCkpCiAgICB7CiAgICAgICAgLyogQWx3YXlzIHRoZSBCU1MgaW5mbyBpbiB0aGUgaGVhZCBpcyB0aGUgaGFuZG9mZiBjYW5kaWRhdGUgKi8KICAgICAgICBwQnNzTm9kZSA9IGNzck5laWdoYm9yUm9hbUdldFJvYW1hYmxlQVBMaXN0TmV4dEVudHJ5KHBNYWMsICZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QsIE5VTEwpOwogICAgICAgIE5FSUdIQk9SX1JPQU1fREVCVUcocE1hYywgTE9HMSwgRkwoIk51bWJlciBvZiBIYW5kb2ZmIGNhbmRpZGF0ZXMgPSAlZCIpLCBjc3JMTENvdW50KCZwTmVpZ2hib3JSb2FtSW5mby0+RlRSb2FtSW5mby5wcmVBdXRoRG9uZUxpc3QpKTsKICAgIH0KICAgIGVsc2UKI2VuZGlmCiAgICB7CiAgICAgICAgcEJzc05vZGUgPSBjc3JOZWlnaGJvclJvYW1HZXRSb2FtYWJsZUFQTGlzdE5leHRFbnRyeShwTWFjLCAmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0LCBOVUxMKTsKICAgICAgICBORUlHSEJPUl9ST0FNX0RFQlVHKHBNYWMsIExPRzEsIEZMKCJOdW1iZXIgb2YgSGFuZG9mZiBjYW5kaWRhdGVzID0gJWQiKSwgY3NyTExDb3VudCgmcE5laWdoYm9yUm9hbUluZm8tPnJvYW1hYmxlQVBMaXN0KSk7CiAgICB9CgogICAgaWYgKE5VTEwgPT0gcEJzc05vZGUpCiAgICB7CiAgICAgICAgcmV0dXJuIGVBTklfQk9PTEVBTl9GQUxTRTsKICAgIH0KCiAgICB2b3NfbWVtX2NvcHkocEhhbmRvZmZOb2RlLCBwQnNzTm9kZSwgc2l6ZW9mKHRDc3JOZWlnaGJvclJvYW1CU1NJbmZvKSk7CgogICAgcmV0dXJuIGVBTklfQk9PTEVBTl9UUlVFOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiByZXR1cm5zIFRSVUUgaWYgcHJlYXV0aCBpcyBjb21wbGV0ZWQgCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gYm9vbGVhbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVN0YXRlUHJlYXV0aERvbmUodHBBbmlTaXJHbG9iYWwgcE1hYykKewogICAgcmV0dXJuIChwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUgPT0gCiAgICAgICAgICAgICAgIGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIFxicmllZiAgSW4gdGhlIGV2ZW50IHRoYXQgd2UgYXJlIGFzc29jaWF0ZWQgd2l0aCBBUDEgYW5kIHdlIGhhdmUKICAgIGNvbXBsZXRlZCBwcmUgYXV0aCB3aXRoIEFQMi4gVGhlbiB3ZSByZWNlaXZlIGEgZGVhdXRoL2Rpc2Fzc29jIGZyb20KICAgIEFQMS4gCiAgICBBdCB0aGlzIHBvaW50IG5laWdoYm9yIHJvYW0gaXMgaW4gcHJlIGF1dGggZG9uZSBzdGF0ZSwgcHJlIGF1dGggdGltZXIKICAgIGlzIHJ1bm5pbmcuIFdlIG5vdyBoYW5kbGUgdGhpcyBjYXNlIGJ5IHN0b3BwaW5nIHRpbWVyIGFuZCBjbGVhcmluZwogICAgdGhlIHByZS1hdXRoIHN0YXRlLiBXZSBiYXNpY2FsbHkgY2xlYXIgdXAgYW5kIGp1c3QgZ28gdG8gZGlzY29ubmVjdGVkCiAgICBzdGF0ZS4gCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gYm9vbGVhbgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2b2lkIGNzck5laWdoYm9yUm9hbVRyYW5pc3Rpb25QcmVhdXRoRG9uZVRvRGlzY29ubmVjdGVkKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgaWYgKHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSAhPSAKICAgICAgICAgICAgICAgZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1BSRUFVVEhfRE9ORSkgcmV0dXJuOwoKICAgIC8vIFN0b3AgdGltZXIKICAgIHZvc190aW1lcl9zdG9wKCZwTWFjLT5mdC5mdFNtZUNvbnRleHQucHJlQXV0aFJlYXNzb2NJbnR2bFRpbWVyKTsKCiAgICAvLyBUcmFuc2l0aW9uIHRvIGluaXQgc3RhdGUKICAgIENTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX1RSQU5TSVRJT04oZUNTUl9ORUlHSEJPUl9ST0FNX1NUQVRFX0lOSVQpCiAgICBwTmVpZ2hib3JSb2FtSW5mby0+cm9hbUNoYW5uZWxJbmZvLklBUFBOZWlnaGJvckxpc3RSZWNlaXZlZCA9IGVBTklfQk9PTEVBTl9GQUxTRTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIGJhY2tncm91bmQgc2NhbiB0cmlnZ2VyZWQgYnkKICAgICAgICAgICAgTEZSIGlzIGluIHByb2dyZXNzLgoKICAgIFxwYXJhbSAgaGFsSGFuZGxlIC0gVGhlIGhhbmRsZSBmcm9tIEhERCBjb250ZXh0LgoKICAgIFxyZXR1cm4gYm9vbGVhbgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdEFOSV9CT09MRUFOIGNzck5laWdoYm9yUm9hbVNjYW5Sc3BQZW5kaW5nICh0SGFsSGFuZGxlIGhIYWwpCnsKICAgIHRwQW5pU2lyR2xvYmFsIHBNYWMgPSBQTUFDX1NUUlVDVChoSGFsKTsKICAgIHJldHVybiAocE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLnNjYW5Sc3BQZW5kaW5nKTsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICBcYnJpZWYgIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBUUlVFIGlmIFNUQSBpcyBpbiB0aGUgbWlkZGxlIG9mIHJvYW1pbmcgc3RhdGVzCgogICAgXHBhcmFtICBoYWxIYW5kbGUgLSBUaGUgaGFuZGxlIGZyb20gSEREIGNvbnRleHQuCgogICAgXHJldHVybiBib29sZWFuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp0QU5JX0JPT0xFQU4gY3NyTmVpZ2hib3JNaWRkbGVPZlJvYW1pbmcgKHRIYWxIYW5kbGUgaEhhbCkKewogICAgdHBBbmlTaXJHbG9iYWwgcE1hYyA9IFBNQUNfU1RSVUNUKGhIYWwpOwogICAgdEFOSV9CT09MRUFOIHZhbCA9IChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVBU1NPQ0lBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIRU5USUNBVElORyA9PSBwTWFjLT5yb2FtLm5laWdoYm9yUm9hbUluZm8ubmVpZ2hib3JSb2FtU3RhdGUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9QUkVBVVRIX0RPTkUgPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfUkVQT1JUX1NDQU4gPT0gcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvLm5laWdoYm9yUm9hbVN0YXRlKSB8fAogICAgICAgICAgICAgICAgICAgICAgIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ0ZHX0NIQU5fTElTVF9TQ0FOID09IHBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mby5uZWlnaGJvclJvYW1TdGF0ZSk7CiAgICByZXR1cm4gKHZhbCk7Cn0KI2lmZGVmIFdMQU5fRkVBVFVSRV9ST0FNX1NDQU5fT0ZGTE9BRAovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtQ2FuZGlkYXRlRm91bmRJbmRIZGxyCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBDU1IgYXMgc29vbiBhcyBUTCBwb3N0cyB0aGUgY2FuZGlkYXRlCiAgICAgICAgICAgIGZvdW5kIGluZGljYXRpb24gdG8gU01FIHZpYSBNQyB0aHJlYWQKCiAgICBccGFyYW0gIHBNYWMgLSBUaGUgaGFuZGxlIHJldHVybmVkIGJ5IG1hY09wZW4uCiAgICAgICAgICAgIHBNc2cgLSBNc2cgc2VudCBieSBQRQoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUNhbmRpZGF0ZUZvdW5kSW5kSGRscih0cEFuaVNpckdsb2JhbCBwTWFjLCB2b2lkKiBwTXNnKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIC8qIHdlIG11c3QgYmUgaW4gY29ubmVjdGVkIHN0YXRlLCBpZiBub3QgaWdub3JlIGl0ICovCiAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgIHx8IChwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZikpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBpbiBub3QgQ09OTkVDVEVEIHN0YXRlIE9SIHVPc1JlcXVlc3RlZEhhbmRvZmYgaXMgc2V0LiBJZ25vcmUgaXQiKSk7CiAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBXZSBhcmUgYWJvdXQgdG8gc3RhcnQgYSBmcmVzaCBzY2FuIGN5Y2xlLAogICAgICAgICAqIHB1cmdlIG5vbi1QMlAgcmVzdWx0cyBmcm9tIHRoZSBwYXN0ICovCiAgICAgICAgY3NyU2NhbkZsdXNoU2VsZWN0aXZlUmVzdWx0KHBNYWMsIFZPU19GQUxTRSk7CiAgICAgICAgLyogT25jZSBpdCBnZXRzIHRoZSBjYW5kaWRhdGVzIGZvdW5kIGluZGljYXRpb24gZnJvbSBQRSwgd2lsbCBpc3N1ZSBhIHNjYW4KICAgICAgICAgLSByZXEgdG8gUEUgd2l0aCCTZnJlc2hTY2FulCBpbiBzY2FucmVxIHN0cnVjdHVyZSBzZXQgYXMgZm9sbG93czoKICAgICAgICAgMHg0MiAtIFJldHVybiAmIHB1cmdlIExGUiBzY2FuIHJlc3VsdHMKICAgICAgICAqLwogICAgICAgIHN0YXR1cyA9IGNzclNjYW5SZXF1ZXN0TGZyUmVzdWx0KHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3NyTmVpZ2hib3JSb2FtU2NhblJlc3VsdFJlcXVlc3RDYWxsYmFjaywgcE1hYyk7CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByb2Nlc3NIYW5kb2ZmUmVxCgogICAgXGJyaWVmICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBzdGFydCB3aXRoIHRoZSBoYW5kb2ZmIHByb2Nlc3MuIEZpcnN0IGRvIGEKICAgIFNTSUQgc2NhbiBmb3IgdGhlIEJTU0lEIHByb3ZpZGVkCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByb2Nlc3NIYW5kb2ZmUmVxKHRwQW5pU2lyR2xvYmFsIHBNYWMpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgZUhhbFN0YXR1cyBzdGF0dXMgPSBlSEFMX1NUQVRVU19TVUNDRVNTOwogICAgdEFOSV9VMzIgcm9hbUlkOwogICAgdENzclJvYW1Qcm9maWxlICpwUHJvZmlsZSA9IE5VTEw7CiAgICB0Q3NyUm9hbVNlc3Npb24gKnBTZXNzaW9uID0gQ1NSX0dFVF9TRVNTSU9OKCBwTWFjLCBwTmVpZ2hib3JSb2FtSW5mby0+Y3NyU2Vzc2lvbklkICk7CiAgICB0QU5JX1U4IGkgPSAwOwoKICAgIGlmIChOVUxMID09IHBTZXNzaW9uKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgicFNlc3Npb24gaXMgTlVMTCAiKSk7CiAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CgogICAgZG8KICAgIHsKICAgICAgICByb2FtSWQgPSBHRVRfTkVYVF9ST0FNX0lEKCZwTWFjLT5yb2FtKTsKICAgICAgICBwUHJvZmlsZSA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0Q3NyUm9hbVByb2ZpbGUpKTsKICAgICAgICBpZiAoIE5VTEwgPT0gcFByb2ZpbGUgKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJNZW1vcnkgYWxsb2MgZmFpbGVkIikpOwogICAgICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICAgICAgdm9zX21lbV9zZXQocFByb2ZpbGUsIHNpemVvZih0Q3NyUm9hbVByb2ZpbGUpLCAwKTsKICAgICAgICBzdGF0dXMgPSBjc3JSb2FtQ29weVByb2ZpbGUocE1hYywgcFByb2ZpbGUsIHBTZXNzaW9uLT5wQ3VyUm9hbVByb2ZpbGUpOwogICAgICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUHJvZmlsZSBjb3B5IGZhaWxlZCIpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICAvL0FkZCB0aGUgQlNTSUQgJiBDaGFubmVsCiAgICAgICAgcFByb2ZpbGUtPkJTU0lEcy5udW1PZkJTU0lEcyA9IDE7CiAgICAgICAgcFByb2ZpbGUtPkJTU0lEcy5ic3NpZCA9IHZvc19tZW1fbWFsbG9jKHNpemVvZih0U2lyTWFjQWRkcikgKiBwUHJvZmlsZS0+QlNTSURzLm51bU9mQlNTSURzKTsKICAgICAgICBpZiAoTlVMTCA9PSBwUHJvZmlsZS0+QlNTSURzLmJzc2lkKQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJtZW0gYWxsb2MgZmFpbGVkIGZvciBCU1NJRCIpKTsKICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICB2b3NfbWVtX3plcm8ocFByb2ZpbGUtPkJTU0lEcy5ic3NpZCwgc2l6ZW9mKHRTaXJNYWNBZGRyKSAqIHBQcm9maWxlLT5CU1NJRHMubnVtT2ZCU1NJRHMpOwoKICAgICAgICAvKiBQb3B1bGF0ZSB0aGUgQlNTSUQgZnJvbSBoYW5kb2ZmIGluZm8gcmVjZWl2ZWQgZnJvbSBIREQgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcFByb2ZpbGUtPkJTU0lEcy5udW1PZkJTU0lEczsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgdm9zX21lbV9jb3B5KCZwUHJvZmlsZS0+QlNTSURzLmJzc2lkW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmJzc2lkLCBzaXplb2YodFNpck1hY0FkZHIpKTsKICAgICAgICB9CgogICAgICAgIHBQcm9maWxlLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzID0gMTsKICAgICAgICBwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QgPQogICAgICAgIHZvc19tZW1fbWFsbG9jKHNpemVvZigqcFByb2ZpbGUtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0KSAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQcm9maWxlLT5DaGFubmVsSW5mby5udW1PZkNoYW5uZWxzKTsKICAgICAgICBpZiAoTlVMTCA9PSBwUHJvZmlsZS0+Q2hhbm5lbEluZm8uQ2hhbm5lbExpc3QpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIm1lbSBhbGxvYyBmYWlsZWQgZm9yIENoYW5uZWxMaXN0IikpOwogICAgICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgcFByb2ZpbGUtPkNoYW5uZWxJbmZvLkNoYW5uZWxMaXN0WzBdID0gcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmNoYW5uZWw7CgogICAgICAgIC8vY2xlYW4gdXAgY3NyIGNhY2hlIGZpcnN0CiAgICAgICAgLy9jc3JTY2FuRmx1c2hTZWxlY3RpdmVSZXN1bHQocE1hYywgVk9TX0ZBTFNFKTsKICAgICAgICAvL2RvIGEgU1NJRCBzY2FuCiAgICAgICAgc3RhdHVzID0gY3NyU2NhbkZvclNTSUQocE1hYywgcE5laWdoYm9yUm9hbUluZm8tPmNzclNlc3Npb25JZCwgcFByb2ZpbGUsIHJvYW1JZCwgRkFMU0UpOwogICAgICAgIGlmKCFIQUxfU1RBVFVTX1NVQ0NFU1Moc3RhdHVzKSkKICAgICAgICB7CiAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiU1NJRCBzY2FuIGZhaWxlZCIpKTsKICAgICAgICB9CiAgICB9d2hpbGUoMCk7CgogICAgaWYoTlVMTCAhPSBwUHJvZmlsZSkKICAgIHsKICAgICAgICBjc3JSZWxlYXNlUHJvZmlsZShwTWFjLCBwUHJvZmlsZSk7CiAgICAgICAgdm9zX21lbV9mcmVlKHBQcm9maWxlKTsKICAgIH0KCiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICBcZm4gY3NyTmVpZ2hib3JSb2FtU3NzaWRTY2FuRG9uZQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgb25jZSBTU0lEIHNjYW4gaXMgZG9uZS4gSWYgU1NJRCBzY2FuIGZhaWxlZAogICAgdG8gZmluZCBvdXIgY2FuZGlkYXRlIGFkZCBhbiBlbnRyeSB0byBjc3Igc2NhbiBjYWNoZSBvdXJzZWxmIGJlZm9yZSBzdGFydGluZwogICAgdGhlIGhhbmRvZmYgcHJvY2VzcwoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KCiAgICBccmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1Mgb24gc3VjY2VzcywgY29ycmVzcG9uZGluZyBlcnJvciBjb2RlIG90aGVyd2lzZQoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KZUhhbFN0YXR1cyBjc3JOZWlnaGJvclJvYW1Tc3NpZFNjYW5Eb25lKHRwQW5pU2lyR2xvYmFsIHBNYWMsIGVIYWxTdGF0dXMgc3RhdHVzKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgICAgICAgICAgICAgICAgICAgICAgaHN0YXR1czsKCiAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImNhbGxlZCAiKSk7CgogICAgLyogd2UgbXVzdCBiZSBpbiBjb25uZWN0ZWQgc3RhdGUsIGlmIG5vdCBpZ25vcmUgaXQgKi8KICAgIGlmIChlQ1NSX05FSUdIQk9SX1JPQU1fU1RBVEVfQ09OTkVDVEVEICE9IHBOZWlnaGJvclJvYW1JbmZvLT5uZWlnaGJvclJvYW1TdGF0ZSkKICAgIHsKICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoIlJlY2VpdmVkIGluIG5vdCBDT05ORUNURUQgc3RhdGUuIElnbm9yZSBpdCIpKTsKICAgICAgICByZXR1cm4gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgIH0KCiAgICAvL2lmIFNTSUQgc2NhbiBmYWlsZWQgdG8gZmluZCBvdXIgY2FuZGlkYXRlIGFkZCBhbiBlbnRyeSB0byBjc3Igc2NhbiBjYWNoZSBvdXJzZWxmCiAgICBpZighSEFMX1NUQVRVU19TVUNDRVNTKHN0YXR1cykpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJBZGQgYW4gZW50cnkgdG8gY3NyIHNjYW4gY2FjaGUiKSk7CiAgICAgICAgaHN0YXR1cyA9IGNzclNjYW5DcmVhdGVFbnRyeUluU2NhbkNhY2hlKHBNYWMsIHBOZWlnaGJvclJvYW1JbmZvLT5jc3JTZXNzaW9uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmhhbmRvZmZSZXFJbmZvLmNoYW5uZWwpOwogICAgICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICAgICAgewogICAgICAgICAgICBzbXNMb2cocE1hYywgTE9HRSwgRkwoImNzclNjYW5DcmVhdGVFbnRyeUluU2NhbkNhY2hlIGZhaWxlZCB3aXRoIHN0YXR1cyAlZCIpLCBoc3RhdHVzKTsKICAgICAgICAgICAgcmV0dXJuIGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgfQogICAgfQoKICAgIC8qIE5vdyB3ZSBoYXZlIGNvbXBsZXRlZCBzY2FubmluZyBmb3IgdGhlIGNhbmRpZGF0ZSBwcm92aWRlZCBieSBIREQuIExldCBtb3ZlIG9uIHRvIEhPKi8KICAgIGhzdGF0dXMgPSBjc3JOZWlnaGJvclJvYW1Qcm9jZXNzU2NhbkNvbXBsZXRlKHBNYWMpOwoKICAgIGlmIChlSEFMX1NUQVRVU19TVUNDRVNTICE9IGhzdGF0dXMpCiAgICB7CiAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJOZWlnaGJvciBzY2FuIHByb2Nlc3MgY29tcGxldGUgZmFpbGVkIHdpdGggc3RhdHVzICVkIiksIGhzdGF0dXMpOwogICAgICAgIHJldHVybiBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgcmV0dXJuIGVIQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFxmbiBjc3JOZWlnaGJvclJvYW1IYW5kb2ZmUmVxSGRscgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgQ1NSIGFzIHNvb24gYXMgaXQgZ2V0cyBhIGhhbmRvZmYgcmVxdWVzdAogICAgICAgICAgICB0byBTTUUgdmlhIE1DIHRocmVhZAoKICAgIFxwYXJhbSAgcE1hYyAtIFRoZSBoYW5kbGUgcmV0dXJuZWQgYnkgbWFjT3Blbi4KICAgICAgICAgICAgcE1zZyAtIE1zZyBzZW50IGJ5IEhERAoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbUhhbmRvZmZSZXFIZGxyKHRwQW5pU2lyR2xvYmFsIHBNYWMsIHZvaWQqIHBNc2cpCnsKICAgIHRwQ3NyTmVpZ2hib3JSb2FtQ29udHJvbEluZm8gICAgcE5laWdoYm9yUm9hbUluZm8gPSAmcE1hYy0+cm9hbS5uZWlnaGJvclJvYW1JbmZvOwogICAgdEFuaUhhbmRvZmZSZXEgICAgICAgICAgICAgICAgICpwSGFuZG9mZlJlcUluZm87CiAgICBlSGFsU3RhdHVzIHN0YXR1cyA9IGVIQUxfU1RBVFVTX1NVQ0NFU1M7CiAgICAvKiB3ZSBtdXN0IGJlIGluIGNvbm5lY3RlZCBzdGF0ZSwgaWYgbm90IGlnbm9yZSBpdCAqLwogICAgaWYgKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZS4gSWdub3JlIGl0IikpOwogICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLy9zYXZlIHRoZSBoYW5kb2ZmIGluZm8gY2FtZSBmcm9tIEhERCBhcyBwYXJ0IG9mIHRoZSByZWFzc29jIHJlcQogICAgICAgIHBIYW5kb2ZmUmVxSW5mbyA9ICh0QW5pSGFuZG9mZlJlcSAqKXBNc2c7CiAgICAgICAgaWYgKE5VTEwgIT0gcEhhbmRvZmZSZXFJbmZvKQogICAgICAgIHsKICAgICAgICAgICAgLy9zYW5pdHkgY2hlY2sKICAgICAgICAgICAgaWYgKFZPU19GQUxTRSA9PSB2b3NfbWVtX2NvbXBhcmUocEhhbmRvZmZSZXFJbmZvLT5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmN1cnJBUGJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodFNpck1hY0FkZHIpKSkKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5jaGFubmVsID0gcEhhbmRvZmZSZXFJbmZvLT5jaGFubmVsOwogICAgICAgICAgICAgICAgdm9zX21lbV9jb3B5KHBOZWlnaGJvclJvYW1JbmZvLT5oYW5kb2ZmUmVxSW5mby5ic3NpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwSGFuZG9mZlJlcUluZm8tPmJzc2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDYpOwogICAgICAgICAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAxOwogICAgICAgICAgICAgICAgc3RhdHVzID0gY3NyUm9hbU9mZmxvYWRTY2FuKHBNYWMsIFJPQU1fU0NBTl9PRkZMT0FEX1NUT1AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVBU09OX09TX1JFUVVFU1RFRF9ST0FNSU5HX05PVyk7CiAgICAgICAgICAgICAgICBpZiAoZUhBTF9TVEFUVVNfU1VDQ0VTUyAhPSBzdGF0dXMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJjc3JSb2FtT2ZmbG9hZFNjYW4gZmFpbGVkIikpOwogICAgICAgICAgICAgICAgICAgIHBOZWlnaGJvclJvYW1JbmZvLT51T3NSZXF1ZXN0ZWRIYW5kb2ZmID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgcmVxIGhhcyBzYW1lIEJTU0lEIGFzIGN1cnJlbnQgQVAhISIpKTsKICAgICAgICAgICAgICAgIHN0YXR1cyA9IGVIQUxfU1RBVFVTX0ZBSUxVUkU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgc21zTG9nKHBNYWMsIExPR0UsIEZMKCJSZWNlaXZlZCBtc2cgaXMgTlVMTCIpKTsKICAgICAgICAgICAgc3RhdHVzID0gZUhBTF9TVEFUVVNfRkFJTFVSRTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVByb2NlZWRXaXRoSGFuZG9mZlJlcQoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgQ1NSIGFzIHNvb24gYXMgaXQgZ2V0cyByc3AgYmFjayBmb3IKICAgICAgICAgICAgUk9BTV9TQ0FOX09GRkxPQURfU1RPUCB3aXRoIHJlYXNvbiBSRUFTT05fT1NfUkVRVUVTVEVEX1JPQU1JTkdfTk9XCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVByb2NlZWRXaXRoSGFuZG9mZlJlcSh0cEFuaVNpckdsb2JhbCBwTWFjKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKICAgIGVIYWxTdGF0dXMgc3RhdHVzID0gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKICAgIC8qIHdlIG11c3QgYmUgaW4gY29ubmVjdGVkIHN0YXRlLCBpZiBub3QgaWdub3JlIGl0ICovCiAgICBpZiAoKGVDU1JfTkVJR0hCT1JfUk9BTV9TVEFURV9DT05ORUNURUQgIT0gcE5laWdoYm9yUm9hbUluZm8tPm5laWdoYm9yUm9hbVN0YXRlKQogICAgICAgIHx8ICghcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYpKQogICAgewogICAgICAgIHNtc0xvZyhwTWFjLCBMT0dFLCBGTCgiUmVjZWl2ZWQgaW4gbm90IENPTk5FQ1RFRCBzdGF0ZSBvciB1T3NSZXF1ZXN0ZWRIYW5kb2ZmIGlzIG5vdCBzZXQuIElnbm9yZSBpdCIpKTsKICAgICAgICBzdGF0dXMgPSBlSEFMX1NUQVRVU19GQUlMVVJFOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8vTGV0J3MgZ28gYWhlYWQgd2l0aCBoYW5kb2ZmCiAgICAgICAgc3RhdHVzID0gY3NyTmVpZ2hib3JSb2FtUHJvY2Vzc0hhbmRvZmZSZXEocE1hYyk7CiAgICB9CiAgICBpZighSEFMX1NUQVRVU19TVUNDRVNTKHN0YXR1cykpCiAgICB7CiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICAgXGZuIGNzck5laWdoYm9yUm9hbVN0YXJ0TGZyU2NhbgoKICAgIFxicmllZiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgaWYgSEREIHJlcXVlc3RlZCBoYW5kb2ZmIGZhaWxlZCBmb3Igc29tZQogICAgcmVhc29uLiBzdGFydCB0aGUgTEZSIGxvZ2ljIGF0IHRoYXQgcG9pbnQuQnkgdGhlIHRpbWUsIHRoaXMgZnVuY3Rpb24gaXMKICAgIGNhbGxlZCwgYSBTVE9QIGNvbW1hbmQgaGFzIGFscmVhZHkgYmVlbiBpc3N1ZWQuCgogICAgXHBhcmFtICBwTWFjIC0gVGhlIGhhbmRsZSByZXR1cm5lZCBieSBtYWNPcGVuLgoKICAgIFxyZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUyBvbiBzdWNjZXNzLCBjb3JyZXNwb25kaW5nIGVycm9yIGNvZGUgb3RoZXJ3aXNlCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwplSGFsU3RhdHVzIGNzck5laWdoYm9yUm9hbVN0YXJ0TGZyU2Nhbih0cEFuaVNpckdsb2JhbCBwTWFjLCB0QU5JX1U4IE9mZmxvYWRDbWRTdG9wUmVhc29uKQp7CiAgICB0cENzck5laWdoYm9yUm9hbUNvbnRyb2xJbmZvICAgIHBOZWlnaGJvclJvYW1JbmZvID0gJnBNYWMtPnJvYW0ubmVpZ2hib3JSb2FtSW5mbzsKCiAgICBzbXNMb2cocE1hYywgTE9HRSwKICAgICAgICAgICBGTCgiIHVPc1JlcXVlc3RlZEhhbmRvZmY9JWQgaXNGb3JjZWRJbml0aWFsUm9hbVRvNUdIPSVkIE9mZmxvYWRDbWRTdG9wUmVhc29uID0gJWQiKSwKICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+dU9zUmVxdWVzdGVkSGFuZG9mZiwKICAgICAgICAgICBwTmVpZ2hib3JSb2FtSW5mby0+aXNGb3JjZWRJbml0aWFsUm9hbVRvNUdILAogICAgICAgICAgIE9mZmxvYWRDbWRTdG9wUmVhc29uKTsKCiAgICBpZihPZmZsb2FkQ21kU3RvcFJlYXNvbiA9PSBSRUFTT05fT1NfUkVRVUVTVEVEX1JPQU1JTkdfTk9XKQogICAgcE5laWdoYm9yUm9hbUluZm8tPnVPc1JlcXVlc3RlZEhhbmRvZmYgPSAwOwogICAgaWYoT2ZmbG9hZENtZFN0b3BSZWFzb24gPT0gUkVBU09OX0lOSVRJQUxfRk9SQ0VEX1JPQU1fVE9fNUcpCiAgICAgICAgcE5laWdoYm9yUm9hbUluZm8tPmlzRm9yY2VkSW5pdGlhbFJvYW1UbzVHSCA9IDA7CiAgICAvKiBUaGVyZSBpcyBubyBjYW5kaWRhdGUgb3IgV2UgYXJlIG5vdCByb2FtaW5nIE5vdy4KICAgICAqIEluZm9ybSB0aGUgRlcgdG8gcmVzdGFydCBSb2FtIE9mZmxvYWQgU2NhbiAgKi8KICAgIGNzclJvYW1PZmZsb2FkU2NhbihwTWFjLCBST0FNX1NDQU5fT0ZGTE9BRF9TVEFSVCwgUkVBU09OX05PX0NBTkRfRk9VTkRfT1JfTk9UX1JPQU1JTkdfTk9XKTsKCiAgICByZXR1cm4gZUhBTF9TVEFUVVNfU1VDQ0VTUzsKfQojZW5kaWYgLy9XTEFOX0ZFQVRVUkVfUk9BTV9TQ0FOX09GRkxPQUQKI2VuZGlmIC8qIFdMQU5fRkVBVFVSRV9ORUlHSEJPUl9ST0FNSU5HICovCg==