ZGlmZiAtLWdpdCBhL3N0ZC90aGluZy9jb21tYW5kcy5jIGIvc3RkL3RoaW5nL2NvbW1hbmRzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjc0NWI2NwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC90aGluZy9jb21tYW5kcy5jCkBAIC0wLDAgKzEsNTMyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdGhpbmcvY29tbWFuZHMuYyAtLSB0aGluZyBkZXNjcmlwdGlvbgorLy8KKy8vICRJZDogY29tbWFuZHMuYyA5NTE0IDIwMTYtMDItMjMgMjA6MzM6MDlaIEdsb2luc29uICQKKy8vCisvLyBBdXMgUmVnZW5ib2dlbiBNVURMaWIKKy8vIGF1cyBHdWVsZGVubGFuZC9XdW5kZXJsYW5kIE1VRGxpYiAoTW9yZ2VuZ3JhdWVuIE1VRGxpYikKKy8vCisvLyBQX0NPTU1BTkRTIGRhdGEtc3RydWN0dXJlOgorLy8KKy8vIEFkZENtZCh2ZXJiLGZ1bjEsMSk7CisvLyBBZGRDbWQodmVyYitzeW4xYXxzeW4xYiZzeW4yYXxzeW4yYnxzeW4yYyxmdW4yLAorLy8JICAgZXJyb3IxX25vdGlmeXxlcnJvcjJfbm90aWZ5XmVycm9yMl93cml0ZSk7CisvLyAtLT4KKy8vIChbdmVyYjooe2Z1bjEsZnVuMn0pOwkJCQkJLy8gZnVucworLy8JICAoezEsKHtlcnJvcjFfbm90aWZ5LCBlcnJvcjJfd3JpdGVeZXJyb3IyX3NheSwgMX0pfSk7ICAvLyBmbGFncworLy8gICAgICAgICh7MCwoeyh7c3luMWEsc3luMWJ9KSwoe3N5bjJhLHN5bjJiLHN5bjJjfSl9KX0pOwkvLyBydWxlcworLy8gICAgICAgIDBdKQkJCQkJCQkvLyBJRHMKKy8vCisvLyBSdWxlczogKHs8UmVnZWxzYXR6IGZ1ZXIgZnVuMT4sICh7PDEuIFN5bm9ueW1ncnVwcGU+LAorLy8JCQkJICAgICA8Mi4gU3lub255bWdydXBwZSwgLi4ufSksIC4uLn0pCisvLyBGbGFnczogKHs8RmxhZyBmdWVyIGZ1bjE+LCAoezxGZWhsZXJtZWxkdW5nIDEuIFN5bm9ueW1ncnVwcGU+LCAuLi4gLAorLy8JCQkJWywgSW5kZXggZnVlciB3cml0ZSBhbnN0YXR0IG5vdGlmeV9mYWlsXX0pLAorLy8JICAgIC4uLiB9KQorLy8gSURzOiAgIDAgb2RlciAoezxJRCBmdWVyIGZ1bjE+fSkgb2RlciAoezAsIDxJRCBmdWVyIGZ1bjI+fSkgLi4uCisvLworLy8gSURFQTogc2F2ZSBubyAwcyBpbiBydWxlcy9mbGFncyBpZiBwb3NzaWJsZSAoYXMgaW4gSURzKQorLy8gICAgICAgKGFkcmVzc2luZyBlc3BlY2lhbGx5IG9sZC1zdHlsZS1BZGRDbWQtTVVEcykKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPHRoaW5nL2xhbmd1YWdlLmg+CisjaW5jbHVkZSA8ZXhwbG9yYXRpb24uaD4KKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPHRoaW5nL2NvbW1hbmRzLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpZmRlZiBEQkcKKyN1bmRlZiBEQkcKKyNlbmRpZgorI2RlZmluZSBEQkcoeCkgcHJpbnRmKCJPYmplY3QgJU8gdG1wc3RyPSVzXG4iLCBleHBsb2RlKG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpLCIjIilbMV0sIHgpOworCitwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIGFkZGVkX2NtZHM7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfSAgICAgCisKK3ZhcmFyZ3Mgdm9pZCBBZGRDbWQobWl4ZWQgY21kLCBtaXhlZCBmdW5jLCBtaXhlZCBmbGFnLCBtaXhlZCBjbWRpZCkgeworIGludCBpLGo7CisgY2xvc3VyZSBjbDsKKyBtaXhlZCAqcnVsZTsKKworIC8vIHBvdGVudGllbGxlIEFkZENtZCBtaXQgUmVnZWw/CisgaWYoc3RyaW5ncChjbWQpKSB7CisgIC8vIGVpbmUgUmVnZWw/IC0gYXVmc3BsaXR0ZW4KKyAgaWYoKGk9bWVtYmVyKGNtZCwnJicpKT4wKSB7CisgICAvLyAuLi4gaW4gQXJyYXkgbWl0IFZlcmtudWVwZnVuZ3NlbGVtZW50ZW4KKyAgIHJ1bGU9ZXhwbG9kZShjbWRbKGkrMSkuLl0sIiYiKTsKKyAgIGo9c2l6ZW9mKHJ1bGUpOworICAgLy8gLi4uIGluIEFycmF5IG1pdCBBcnJheXMgbWl0IEFsdGVybmF0aXZlbGVtZW50ZW46CisgICAvLyAicHxxJnJ8cyIgLT4gKHsgKHsicCIsInEifSksICh7InIiLCJzIn19IH0pCisgICB3aGlsZShqLS0pCisgICAgcnVsZVtqXT1leHBsb2RlKHJ1bGVbal0sInwiKTsKKworICAgLy8gUmVnZWxuIHZvbiBLb21tYW5kb3ZlcmJlbiBhYnNjaG5laWRlbgorICAgY21kPWNtZFswLi4oaS0xKV07CisgIH0KKyAgLy8gS29tbWFuZG92ZXJiZW4gZXh0cmFoaWVyZW4KKyAgY21kPWV4cGxvZGUoY21kLCJ8Iik7CisKKyAgLy8gU2F0eiB2b24gUmVnZWxuIGV4aXN0aWVydDogQXVmc3BsaXR0ZW4gdm9uIEZlaGxlcm1lbGR1bmdlbgorICBpZihydWxlKQorICAgaWYoc3RyaW5ncChmbGFnKSkgeworICAgIG1peGVkICpmYWlsOworICAgIC8vIGluIGVpbmZhY2hlcyBBcnJheSBtaXQgamV3ZWlsaWdlbiBGZWhsZXJtZWxkdW5nZW4KKyAgICBmYWlsPWV4cGxvZGUoZmxhZywifCIpOworICAgIGo9MDsKKyAgICBpPXNpemVvZihmYWlsKTsKKyAgICB3aGlsZShqPGkpIHsKKyAgICAgLy8gd3JpdGUgLSBGZWhsZXJtZWxkdW5nIGVudGRlY2t0IC0gUG9zaXRpb24gZ2dmLiBlaW50cmFnZW4KKyAgICAgaWYobWVtYmVyKGZhaWxbal0sJ14nKT49MCAmJiAhaW50cChmYWlsWzwxXSkpCisgICAgICBmYWlsKz0oe2p9KTsKKyAgICAgaWYobWVtYmVyKGZhaWxbal0sJ0AnKT49MCkgeworICAgICAgaW50IHM7CisgICAgICBmbGFnPXJlZ2V4cGxvZGUoZmFpbFtqXSwgIkBXRVtBLVNVXSpbMC05XSIpOworICAgICAgcz1zaXplb2YoZmxhZyk7CisgICAgICB3aGlsZSgocy09Mik+MCkgeworICAgICAgIGludCB0bXBpbnQ7CisgICAgICAgdG1waW50PWZsYWdbc11bPDFdLScxJzsKKyAgICAgICBpZih0bXBpbnQ8MCB8fCB0bXBpbnQ+aikKKyAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICJBZGRDbWQ6IGVycm9yLW1lc3NhZ2UgJWQgY29udGFpbnMgb3V0LW9mLWJvdW5kcyBAV0V4eC1ydWxlLlxuIixqKzEpKTsKKyAgICAgIH0KKyAgICAgfQorICAgICBqKys7CisgICAgfQorICAgIC8vICJXYXM/fFdpZSBkYXM/IiAtPiAoeyJXYXM/IiwiV2llIGRhcz8ifSkKKyAgICAvLyAiV2FzP3xXaWUgZGFzP158V29taXQgZGFzP3xXb3JhdWYgZGFzP15AV0VSMSBtYWNodCB3YXMuIiAtPgorICAgIC8vICAoeyJXYXM/IiwKKyAgICAvLyAgICAiV2llIGRhcz9eV29taXQgZGFzPyIsCisgICAgLy8JICAiV29yYXVmIGRhcz9eQFdFUjEgbWFjaHQgd2FzLiIsMX0pCisgICAgZmxhZz1zaXplb2YoZmFpbCk7CisgICAgaWYoZmxhZyAmJiBmbGFnPHNpemVvZihydWxlKSkKKyAgICAgcmFpc2VfZXJyb3IoCisgICAgICAiQWRkQ21kOiBudW1iZXIgb2YgZXJyb3ItbWVzc2FnZXMgZG9lcyBub3QgbWF0Y2ggbnVtYmVyIG9mIHJ1bGVzLlxuIik7CisgICAgZmxhZz1mYWlsOyAvLyB1ZWJlcnNjaHJlaWJlbiBtaXQgZGVuIHBhcnNlZnJldW5kbGljaGVuIEZvcm1hdAorICB9IGVsc2UgaWYoZmxhZykKKyAgIHJhaXNlX2Vycm9yKCJBZGRDbWQ6IHJ1bGVzIGV4aXN0IGJ1dCBmbGFncyBhcmUgbm90IGFuIGVycm9yLXN0cmluZy5cbiIpOworIH0gLy8gZW5kIGlmKHN0cmluZ3AoY21kKSkgLi4uIGtlaW4gUmVnZWxzdHJpbmcgdm9yaGFuZGVuCisKKyAvLyBrZWluIEtvbW1hbmRvYXJyYXkgZ2V3ZXNlbiBub2NoIGVyemV1Z3Q/CisgaWYoIXBvaW50ZXJwKGNtZCkpCisgICByYWlzZV9lcnJvcigiQWRkQ21kOiBtaXNzaW5nIHN0cmluZy9wb2ludGVyLXBhcmFtZXRlciBmb3IgY29tbWFuZC5cbiIpOworCisgLy8gQ2xvc3VyZSBhdXMgZWluZW0gU3RyaW5nIGVyemV1Z2VuLCB3ZW5uIG1vZWdsaWNoIHVuZCBzaWNoZXIKKyAvLyAoZnVuY3Rpb25fZXhpc3RzKCkgZmlsdGVydCB1bm5vZXRpZ2Vyd2Vpc2UgYXVjaCByZWluZSAic3RhdGljIiBmdW5zLAorIC8vICBkaWUgZ2VuYXVlIFBydWVmdW5nIHVlYmVyIGZ1bmN0aW9ubGlzdCgpIGtvc3RldCBqZWRvY2ggenV2aWVsKQorIGlmKHN0cmluZ3AoZnVuYykgJiYKKyAgICAoIWV4dGVybl9jYWxsKCkgfHwgZnVuY3Rpb25fZXhpc3RzKGZ1bmMsdGhpc19vYmplY3QoKSkpICYmCisgICAgY2xvc3VyZXAoY2w9c3ltYm9sX2Z1bmN0aW9uKGZ1bmMsdGhpc19vYmplY3QoKSkpKQorICBmdW5jPWNsOworCisgLy8gamVkZXMgZWluemVsbmUgVmVyYiBtaXQgc2VpbmVuIFJlZ2VsbiB1bmQgRnVua3Rpb25lbiBlaW50cmFnZW4KKyBpPXNpemVvZihjbWQpOworIGlmKCFhZGRlZF9jbWRzKSBhZGRlZF9jbWRzPW1fYWxsb2NhdGUoaSw0KTsKKyB3aGlsZShpLS0pIHsKKyAgc3RyaW5nIHN0cjsKKyAgc3RyPWNtZFtpXTsKKyAgaWYoIWZ1bmMpCisgICBpZihleHRlcm5fY2FsbCgpKSBmdW5jPXByZXZpb3VzX29iamVjdCgpOworICAgZWxzZSBmdW5jPXRoaXNfb2JqZWN0KCk7CisgIGlmKCFtZW1iZXIoYWRkZWRfY21kcyxzdHIpKQorICAgYWRkZWRfY21kcys9KFtzdHI6YWxsb2NhdGUoMCk7YWxsb2NhdGUoMCk7YWxsb2NhdGUoMCk7MF0pOworICAvLyBleGlzdGllcmVuZGVzIFZlcmIgZXJnYWVuemVuCisgIGFkZGVkX2NtZHNbc3RyLDBdKz0oe2Z1bmN9KTsKKyAgYWRkZWRfY21kc1tzdHIsMV0rPSh7ZmxhZ30pOworICBhZGRlZF9jbWRzW3N0ciwyXSs9KHtydWxlfSk7CisgIC8vIGdnZi4gaWQgaW4gZGFzIElELU1hcHBpbmcgZWludHJhZ2VuCisgIGlmKGNtZGlkKSB7CisgICBtaXhlZCAqdG1wOworICAgaj1zaXplb2YoKHN0cmluZyopYWRkZWRfY21kc1tzdHIsMF0pOworICAgdG1wPWFkZGVkX2NtZHNbc3RyLDNdfHxhbGxvY2F0ZShqKTsKKyAgIGlmKHNpemVvZih0bXApPGopIHRtcCs9YWxsb2NhdGUoai1zaXplb2YodG1wKSk7CisgICB0bXBbPDFdPWNtZGlkOworICAgYWRkZWRfY21kc1tzdHIsM109dG1wOworICB9CisgfQorfQorCisvLyBBdXN3ZXJ0dW5nIGZ1ZXIgZWluIFZlcmIgbG9lc2NoZW4KK3ZhcmFyZ3MgaW50IFJlbW92ZUNtZChtaXhlZCBjbWQsIGludCBkZWxfbm9ydWxlLCBtaXhlZCBvbmx5aWQpIHsKKyBpbnQgcmV0OworCisgLy8gRmFsbHMgTWFnaWVyIGRhcyBSZW1vdmVDbWQgZmFsc2NoIG51dHplbiAoei5CLiBhbmFsb2cgenUgQWRkQ21kKQorIC8vIHdpcmQgZGFzIFJlZ2Vsc3lzdGVtIHZlcndpcnJ0LiBEYSBkYXMgZGVsX25vcnVsZSBudXIgaW50IHNlaW4gZGFyZiwKKyAvLyBnaWJ0IGVzIGhpZXIgZWluZSBndXRlIENoYW5jZSBkZW4gRmVobGVyIGFid2FlcnRza29tcGF0aWJlbCB6dSBlbnQtCisgLy8gZGVja2VuLiBEYW1pdCBTcGllbGVyIGRlbiBGZWhsZXIgbmljaHQgbWl0YmVrb21tZW4sIHdpcmQgaGllciBhdWYKKyAvLyBlaW4gcmFpc2VfZXJyb3IgdmVyemljaHRldCwgdW5kIHN0YXR0IGRlc3NlbiBpbiBlaW4gTG9nZmlsZSBnZS0KKyAvLyBzY2hyaWViZW4uCisgaWYgKCFpbnRwKGRlbF9ub3J1bGUpKQorIHsKKyAgIGxvZ19maWxlKCJSRU1PVkVfQ01EIiwKKyAgICAgc3ByaW50ZigiXG4tLSAlcyAtLVxuSWxsZWdhbCBSZW1vdmVDb21tYW5kKCkgaW4gT2JqZWN0IFslT106XG4gJU9cbiIsCisgICAgICAgZHRpbWUodGltZSgpKSwgdGhpc19vYmplY3QoKSwgY21kKSk7CisgICBkZWxfbm9ydWxlPTA7CisgICBvbmx5aWQ9MDsKKyB9CisgCisgaWYoIWFkZGVkX2NtZHMgfHwgKCFjbWQgJiYgIWRlbF9ub3J1bGUgJiYgIW9ubHlpZCkpCisgIGFkZGVkX2NtZHM9KG1hcHBpbmcpMDsgCisgZWxzZSB7CisgIGludCBpLCBqOworICBtaXhlZCAqcnVsZSwgKmZsYWcsICpmdW4sICpkZWxydWxlLCAqaWRzOworCisgIGlmKHN0cmluZ3AoY21kKSkgeworICAgLy8gUmVnZWxuIGVudGRlY2t0IC0gWmVybGVnZW4gKHdpZSBBZGRDbWQpCisgICBpZigoaT1tZW1iZXIoY21kLCcmJykpPjApIHsKKyAgICBkZWxydWxlPWV4cGxvZGUoY21kWyhpKzEpLi5dLCImIik7CisgICAgaj1zaXplb2YoZGVscnVsZSk7CisgICAgd2hpbGUoai0tKQorICAgICBkZWxydWxlW2pdPWV4cGxvZGUoZGVscnVsZVtqXSwifCIpOworICAgIGNtZD1jbWRbMC4uKGktMSldOworICAgfQorICAgY21kPWV4cGxvZGUoY21kLCJ8Iik7CisgIH0gZWxzZSBpZihkZWxfbm9ydWxlIHx8IG9ubHlpZCkgY21kPW1faW5kaWNlcyhhZGRlZF9jbWRzKTsKKworICBpZighcG9pbnRlcnAoY21kKSkKKyAgIHJhaXNlX2Vycm9yKCJSZW1vdmVDbWQ6IG1pc3Npbmcgc3RyaW5nL3BvaW50ZXItcGFyYW1ldGVyLlxuIik7CisgIGk9c2l6ZW9mKGNtZCk7CisKKyAgd2hpbGUoaS0tKSB7CisgICAvLyBrZWluZSBSZWdlbG4gZGEgdW5kIFJlZ2VsbiBsb2VzY2hlbiBlcmxhdWJ0OiBhbGxlcyBsb2VzY2hlbgorICAgaWYoIWRlbHJ1bGUgJiYgIWRlbF9ub3J1bGUgJiYgIW9ubHlpZCkgbV9kZWxldGUoYWRkZWRfY21kcyxjbWRbaV0pOworICAgZWxzZSBpZihtX2NvbnRhaW5zKCZmdW4sICZmbGFnLCAmcnVsZSwgJmlkcywgYWRkZWRfY21kcywgY21kW2ldKSkgeworICAgIGo9c2l6ZW9mKGZ1bik7CisgICAgd2hpbGUoai0tKSB7CisgICAgIGludCBrOworICAgICAvLyBEQkcocnVsZVtqXSk7CisgICAgCS8vIFJlZ2VsbiBuaWNodCBs9nNjaGVuIHVuZCBSZWdlbD8KKyAgICAgaWYoIShkZWxfbm9ydWxlICYmIHBvaW50ZXJwKHJ1bGVbal0pKSAmJgorICAgICAgICAvLyBudXIgYmVzdGltbXRlIElEIGz2c2NoZW4gdW5kIElEIHBhc3N0IG5pY2h0PworICAgICAgICAhKG9ubHlpZCAmJiAoIXBvaW50ZXJwKGlkcykgfHwgc2l6ZW9mKGlkcyk8PWogfHwgaWRzW2pdIT1vbmx5aWQpKSAmJgorICAgICAgICAvLyBM9nNjaHJlZ2VsIGV4aXN0aWVydCB1bmQgcGFzc3QgbmljaHQgYXVmIFJlZ2VsPworICAgICAgICAhKGRlbHJ1bGUgJiYgKGs9c2l6ZW9mKHJ1bGVbal0pKSE9c2l6ZW9mKGRlbHJ1bGUpKSkgeworICAgICAgLy8gcGFydGllbGxlcyBUZXN0ZW4gZWluZXIgTPZzY2hyZWdlbCAuLi4KKyAgICAgIGlmKGRlbHJ1bGUpIHsKKyAgICAgICB3aGlsZShrLS0pCisgICAgICAgIGlmKCFzaXplb2YocnVsZVtqXVtrXSZkZWxydWxlW2tdKSkgYnJlYWs7CisgICAgICAgaWYoaz49MCkgY29udGludWU7CisgICAgICB9CisgICAgICAvLyBhbGxlcyBrb3JyZWt0OiBM9nNjaGVuIQorICAgICAgLy8gKEFycmF5YmVyZWljaCBkdXJjaCBsZWVyZXMgQXJyYXkgbG9lc2NoZW4pCisgICAgICBmbGFnW2ouLmpdICA9IGFsbG9jYXRlKDApOworICAgICAgZnVuW2ouLmpdICAgPSBhbGxvY2F0ZSgwKTsKKyAgICAgIHJ1bGVbai4ual0gID0gYWxsb2NhdGUoMCk7CisgICAgICBpZihpZHMpIHsKKyAgICAgICBpZHNbai4ual0gPSBhbGxvY2F0ZSgwKTsKKyAgICAgICBpZighc2l6ZW9mKGlkcy1hbGxvY2F0ZSgxKSkpIGlkcz0obWl4ZWQqKTA7CisgICAgICB9CisgICAgICByZXQrKzsKKyAgICAgfQorICAgIH0gLy8gZW5kIHdoaWxlKGotLSkgeworICAgfQorICAgLy8gRnVua3Rpb25zL1JlZ2VsbGlzdGUgdXBkYXRlIG9kZXIgZ2dmLiBLb21tYW5kbyB2b2VsbGlnIGxvZXNjaGVuCisgICBpZihzaXplb2YocnVsZSkpIHsKKyAgICBhZGRlZF9jbWRzW2NtZFtpXSwwXT1mdW47CisgICAgYWRkZWRfY21kc1tjbWRbaV0sMV09ZmxhZzsKKyAgICBhZGRlZF9jbWRzW2NtZFtpXSwyXT1ydWxlOworICAgIGFkZGVkX2NtZHNbY21kW2ldLDNdPWlkczsKKyAgIH0gZWxzZSBtX2RlbGV0ZShhZGRlZF9jbWRzLGNtZFtpXSk7CisgIH0KKyAgaWYoIXNpemVvZihhZGRlZF9jbWRzKSkgYWRkZWRfY21kcz0obWFwcGluZykwOworIH0KKyByZXR1cm4gcmV0OworfQorCisvLyBBdXNmdWVocmVuIHNhbXQgZ2VwYXJzdGVtIElucHV0c3RyaW5nIHVuZCBnZXRyaWdnZXJ0ZW4gUGFyc2VyZXJnZWJuaXNzZW4KK3N0YXRpYyBpbnQgX2V4ZWN1dGUobWl4ZWQgZnVuLCBzdHJpbmcgc3RyLCBtaXhlZCAqcGFyc2VkKSB7CisgaWYoY2xvc3VyZXAoZnVuKSkKKyAgcmV0dXJuICgoaW50KWZ1bmNhbGwoZnVuLHN0ciwmcGFyc2VkKSk7CisgaWYoc3RyaW5ncChmdW4pKQorICByZXR1cm4gKChpbnQpY2FsbF9vdGhlcih0aGlzX29iamVjdCgpLGZ1bixzdHIsJnBhcnNlZCkpOworIHJldHVybiAwOworfQorCisjZGVmaW5lIENIRUNLX1BSRVNFTlQgICAgIDEKKyNkZWZpbmUgQ0hFQ0tfSUQgICAgICAgICAgMgorI2RlZmluZSBDSEVDS19QVVRHRVROT05FICA0CisjZGVmaW5lIENIRUNLX1BVVEdFVERST1AgIDgKKyNkZWZpbmUgQ0hFQ0tfUFVUR0VUVEFLRSAgMTYKKyNkZWZpbmUgQ0hFQ0tfUFVUR0VUICAgICAgKENIRUNLX1BVVEdFVE5PTkV8Q0hFQ0tfUFVUR0VURFJPUHxDSEVDS19QVVRHRVRUQUtFKQorCisvLyBXZXJ0IGZ1ZXIgRmVobHNjaGxhZywgRmFsbGJhY2stV2VydCBkZXIgYmVudXR6dGVuIHdoaWxlLS0gLSBTY2hsZWlmZW4KKyNkZWZpbmUgTk9NQVRDSEZPVU5EICAgICAgLTEKKworLy8gUmVnZWxuIGZ1ZXIgZWluIChudW4gdW53aWNodGlnZXMpIFZlcmIgdHJpZ2dlcm4KK3N0YXRpYyBpbnQgX3Byb2Nlc3NfY29tbWFuZChzdHJpbmcgc3RyLCBzdHJpbmcgKm5vcGFyc2VzdHIsCisJCQkgICAgIG1peGVkIGZ1biwgbWl4ZWQgZmxhZywgbWl4ZWQgcnVsZSkgeworIG1peGVkICpwYXJzZWQsICpvYmptYXRjaGVzOworCisgLy8gZWluZSBSZWdlbCAuLi4gYXVzd2VydGVuIC4uLgorIGlmKHBvaW50ZXJwKHJ1bGUpKSB7CisgIGludCBucnVsOworICBwYXJzZWQ9b2JqbWF0Y2hlcz1hbGxvY2F0ZSgwKTsKKyAgaW50IGxhc3RtYXRjaHBvcz1OT01BVENIRk9VTkQ7CisKKyAgLy8gQWJnbGVpY2hlbiBkZXIgZ2VzcGxpdHRldGVuIEVpbmdhYmUgbWl0IFJlZ2VsbjoKKyAgLy8gdm9yd2FlcnRzIGR1cmNoIGRpZSBTeW5vbnltZ3J1cHBlbgorICBpbnQgcnM9c2l6ZW9mKHJ1bGUpOworICB3aGlsZShucnVsPHJzKSB7CisgICBpbnQgbWF0Y2hwb3M7CisgICBzdHJpbmcgKnN5bm9ueW07CisgICBtaXhlZCBtYXRjaHN0cjsKKworICAgbWF0Y2hwb3M9Tk9NQVRDSEZPVU5EOworICAgbWF0Y2hzdHI9MDsKKworICAgLy8gU3lub255bWUgZXh0cmFoaWVyZW4KKyAgIGludCBucnN5bm9ueW1zPXNpemVvZihzeW5vbnltPXJ1bGVbbnJ1bF0pOworCisgICAvLyBlZ2FsIHdpZSBkdXJjaCBTeW5vbnltZSBiaXMgTWF0Y2ggLSBBYmdsZWljaCBtaXQgRWluZ2FiZQorICAgd2hpbGUobnJzeW5vbnltcy0tKSB7CisgICAgaW50IHRtcHBvcyA9IG1lbWJlcihub3BhcnNlc3RyLHN5bm9ueW1bbnJzeW5vbnltc10pOworICAgIC8vIGlzdCBTeW5vbnltIGltIEVpbmdhYmVzdHJpbmcgdW5kIGtvbW10IHNwYWV0ZXIgYWxzIHZvcmhlcmlnZXMgU3lub255bT8KKyAgICBpZih0bXBwb3M+PTAgJiYgdG1wcG9zPmxhc3RtYXRjaHBvcykgeworICAgICAvLyBFcmZvbGc6IG1lcmtlbiBkZXIgUG9zaXRpb24gaW0gRWluZ2FiZXN0cmluZyB1bmQgZGVuIG1hdGNoZW5kZW4gU3RyaW5nCisgICAgIG1hdGNocG9zPXRtcHBvczsKKyAgICAgbWF0Y2hzdHI9bm9wYXJzZXN0clt0bXBwb3NdOworICAgICBicmVhazsKKyAgICB9CisgICB9CisKKyAgIC8vIGtlaW4gTWF0Y2ggZHVyY2ggU3lub255bWU/IFBydWVmZSBkaWUgQC1TcGV6aWFsdmFyaWFibGVuLgorICAgaWYobWF0Y2hwb3MgPT0gTk9NQVRDSEZPVU5EKSB7CisgICAgaW50IGNoZWNrX3ByZXNlbnQ7CisgICAgLy8gaXN0IEFicHJ1ZWZlbiB2b24gSUQvUFJFU0VOVCBpbiBkZXIgU3lub255bWdydXBwZSB2ZXJsYW5ndAorICAgIC8vIGJlaSBwcmVzZW50KCkvZmluZF9vYnMgZ2xlaWNoIFZvcmF1c3NldHp1bmcgZ3VlbHRpZ2VyIFRQIG1pdHBydWZlbgorICAgIGlmKG1lbWJlcihzeW5vbnltLCJASUQiKT49MCkgY2hlY2tfcHJlc2VudD1DSEVDS19JRDsKKyAgICBpZih0aGlzX3BsYXllcigpKSB7CisgICAgIGlmKG1lbWJlcihzeW5vbnltLCJAUFJFU0VOVCIpPj0wKSBjaGVja19wcmVzZW50fD1DSEVDS19QUkVTRU5UOworICAgICBlbHNlIGlmKG1lbWJlcihzeW5vbnltLCJAUFVUX0dFVF9OT05FIik+PTApCisJCWNoZWNrX3ByZXNlbnR8PUNIRUNLX1BVVEdFVE5PTkU7CisgICAgIGVsc2UgaWYobWVtYmVyKHN5bm9ueW0sIkBQVVRfR0VUX1RBS0UiKT49MCkKKwkJY2hlY2tfcHJlc2VudHw9Q0hFQ0tfUFVUR0VURFJPUDsKKyAgICAgZWxzZSBpZihtZW1iZXIoc3lub255bSwiQFBVVF9HRVRfRFJPUCIpPj0wKQorCQljaGVja19wcmVzZW50fD1DSEVDS19QVVRHRVRUQUtFOworICAgIH0KKworICAgIGlmKGNoZWNrX3ByZXNlbnQpIHsKKyAgICAgLy8gd2lyIGZhbmdlbiBoaW50ZXIgZGVtIGxldHp0ZW4gTWF0Y2ggYW4KKyAgICAgaW50IHFfc3RhcnQ9bGFzdG1hdGNocG9zKzE7CisgICAgIGludCByX2VuZD1zaXplb2Yobm9wYXJzZXN0ciktMTsKKworICAgICBpbnQgcmFuZ2U7CisgICAgIHdoaWxlKChyYW5nZT1yX2VuZC1xX3N0YXJ0KT49MCkgeworICAgICAgbWl4ZWQgdG1wb2JqOworCisgICAgICAvLyB3aWUgd2VpdCB3b2xsZW4gd2lyIHp1cvxja2dlaGVuPworICAgICAgaWYocmFuZ2UpCisgICAgICAgIGlmKCEoY2hlY2tfcHJlc2VudCZDSEVDS19QVVRHRVQpKQorICAgICAgICAgIHJhbmdlPXJhbmdlPjI/MjpyYW5nZTsgLy8gMyBGcmFnbWVudGUgZnVlciBASUQvQFBSRVNFTlQgKEFkdmVyYi9OcikKKyAgICAgICAgZWxzZSBpZihyYW5nZT40KQorICAgICAgICAgIHJhbmdlPTQ7ICAgICAgICAgICAgICAgLy8gNSBGcmFnbWVudGUgZnVlciBAUFVUX1hYWCAKKworICAgICAgLy8gdW5kIGpldHp0IGRpZSBTdWJzdHJpbmdzIHBydWVmZW4KKyAgICAgIHdoaWxlKHJhbmdlPj0wICYmICFtYXRjaHN0cikgeworICAgICAgIHN0cmluZyB0bXBzdHI7CisKKyAgICAgICAvLyB6dSBwcnVlZmVuZGVuIFN0cmluZyBhdXMgZGVuIFRlaWxlbiB6dXNhbW1lbnNldHplbgorICAgICAgIGlmKHJhbmdlKSB0bXBzdHI9aW1wbG9kZShub3BhcnNlc3RyW3Ffc3RhcnQuLihxX3N0YXJ0K3JhbmdlKV0sIiAiKTsKKyAgICAgICBlbHNlIHRtcHN0cj1ub3BhcnNlc3RyW3Ffc3RhcnRdOworCisgICAgICAgLy9EQkcodG1wc3RyKTsKKyAgICAgICBpZihjaGVja19wcmVzZW50JkNIRUNLX1BSRVNFTlQgJiYJCQkvLyBQUkVTRU5UID8KKyAgICAgICAgICAoKHRtcG9iaj1wcmVzZW50KHRtcHN0cix0aGlzX3BsYXllcigpKSkgfHwKKyAgICAgICAgICAgKHRtcG9iaj1wcmVzZW50KHRtcHN0cixlbnZpcm9ubWVudCh0aGlzX3BsYXllcigpKSkpKSkKKyAgICAgICAgbWF0Y2hzdHI9dG1wb2JqOworICAgICAgIGVsc2UgaWYoY2hlY2tfcHJlc2VudCZDSEVDS19JRCAmJiBpZCh0bXBzdHIpKQkvLyBJRCA/CisgICAgICAgIG1hdGNoc3RyPXRoaXNfb2JqZWN0KCk7CisgICAgICAgZWxzZSBpZigoY2hlY2tfcHJlc2VudCZDSEVDS19QVVRHRVQpICYmCS8vIFBVVF9HRVRfPz8/ID8KKyAgICAgICAgICAgICAgICh0bXBvYmo9KG9iamVjdCopCisgICAgICAgICAgICAgICAgICB0aGlzX3BsYXllcigpLT5maW5kX29icyh0bXBzdHIsCisgICAgICAgICAgICAgICAgICAgICAgKFtDSEVDS19QVVRHRVROT05FOlBVVF9HRVRfTk9ORSwKKyAgICAgICAgICAgICAgICAgICAgICAgIENIRUNLX1BVVEdFVERST1A6UFVUX0dFVF9UQUtFLAorICAgICAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfUFVUR0VUVEFLRTpQVVRfR0VUX0RST1BdKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtDSEVDS19QVVRHRVQmY2hlY2tfcHJlc2VudF0pKSAmJgorICAgICAgICAgICAgICAgc2l6ZW9mKHRtcG9iaikpIHsKKyAgICAgICAgaWYoc2l6ZW9mKHRtcG9iaik9PTEpIG1hdGNoc3RyPXRtcG9ialswXTsKKyAgICAgICAgZWxzZSB7CS8vIEFycmF5cyB3ZXJkZW4gendpc2NoZW5nZXNwZWljaGVydCAuLi4KKyAgICAgICAgIG9iam1hdGNoZXMrPSh7c2l6ZW9mKHBhcnNlZCksdG1wb2JqfSk7CisgICAgICAgICBtYXRjaHN0cj10bXBzdHI7CisgICAgICAgIH0KKyAgICAgICB9IGVsc2UgeyAvLyBkaWVzZXIgU3Vic3RyaW5nIGhhdCBuaWNodCBnZW1hdGNodAorICAgICAgICAvLyBhYiB3ZW5pZ2VyIGFscyAzIFRlaWxlbiBpc3QgZGFzIE5pY2h0bWF0Y2hpbmcgZWluZXMgU3Vic3RyaW5ncyBtaXQKKyAgICAgICAgLy8gYmVlbmRlbmRlbSBOdW1lcmFsIEtyaXRlcml1bSBmdWVyIEFiYnJ1Y2ggKCJvYmpla3QgMiIgc29sbCBtYXRjaGVuKQorICAgICAgICBzdHJpbmcgbnVtZXJhbGNoZWNrOworICAgICAgICBpZihyYW5nZSAmJiByYW5nZTw9MiAmJgorICAgICAgICAgICBzaXplb2YobnVtZXJhbGNoZWNrPW5vcGFyc2VzdHJbcV9zdGFydCtyYW5nZV0pICYmCisgICAgICAgICAgIHRvX3N0cmluZyh0b19pbnQobnVtZXJhbGNoZWNrKSk9PW51bWVyYWxjaGVjaykKKyAgICAgICAgICBicmVhazsKKworICAgICAgICAvLyBTdWJzdHJpbmdsYWVuZ2UgdmVya3VlcnplbiB1bmQgd2VpdGVyCisgICAgICAgIHJhbmdlLS07CisgICAgICAgfQorICAgICAgfQorCisgICAgICAvLyBNYXRjaCBnZWZ1bmRlbiEKKyAgICAgIGlmKG1hdGNoc3RyKSB7CisgICAgICAgbWF0Y2hwb3M9cmFuZ2UrcV9zdGFydDsKKyAgICAgICAvLyBEQkcobWF0Y2hwb3MpOworICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgcV9zdGFydCsrOworICAgICB9IC8vIGVuZCB3aGlsZQorICAgIH0KKyAgIH0KKworICAgLy8gRmVobGVybWVsZHVuZyBmdWVyIGRpZXNlIGZlaGxnZXNjaGxhZ2VuZSBTeW5vbnltZ3J1cHBlIHNldHplbgorICAgaWYobWF0Y2hwb3MgPT0gTk9NQVRDSEZPVU5EKSB7CisgICAgLy8gRmVobGVybWVsZHVuZ2VuIHVuZCBlaW4gRWludHJhZyBhbiBkZXIgRmVobGVyc3RlbGxlPworICAgIGlmKHBvaW50ZXJwKGZsYWcpICYmIHNpemVvZihmbGFnKT5ucnVsKSB7CisKKyAgICAgbWF0Y2hzdHI9ZmxhZ1tucnVsXTsKKworICAgICBpZihzdHJpbmdwKG1hdGNoc3RyKSAmJiBzaXplb2YobWF0Y2hzdHIpKSB7CisgICAgICBpZihtZW1iZXIobWF0Y2hzdHIsJ0AnKT49MCkgeworICAgICAgIG1hdGNoc3RyPXJlcGxhY2VfcGVyc29uYWwoJm1hdGNoc3RyLCh7dGhpc19wbGF5ZXIoKX0pK3BhcnNlZCwxKTsKKyAgICAgICBzdHJpbmcgc3RhbW09KChxdWVyeV92ZXJiKClbPDFdXidlJyk/cXVlcnlfdmVyYigpOnF1ZXJ5X3ZlcmIoKVswLi48Ml0pOworICAgICAgIG1hdGNoc3RyPXJlZ3JlcGxhY2UobWF0Y2hzdHIsIkBWRVJCIixjYXBpdGFsaXplKHN0YW1tKSwxKTsKKyAgICAgICBtYXRjaHN0cj1yZWdyZXBsYWNlKG1hdGNoc3RyLCJAdmVyYiIsc3RhbW0sMSk7CisgICAgICB9CisKKyAgICAgIC8vIGlzdCBGZWhsZXJtZWxkdW5nIGVpbiBXUklURT8KKyAgICAgIC8vIGRhbm4gcmV0dXJuIDEgIQorICAgICAgaWYoaW50cChmbGFnWzwxXSkgJiYgZmxhZ1s8MV08PW5ydWwpIHsKKyAgICAgICBpZihtZW1iZXIobWF0Y2hzdHIsJ14nKT49MCkgeworICAgICAgICBtYXRjaHN0cj1leHBsb2RlKG1hdGNoc3RyLCJeIik7CisgICAgICAgIHdyaXRlKGNhcGl0YWxpemUoYnJlYWtfc3RyaW5nKG1hdGNoc3RyWzBdLDc4LDAsMSkpKTsKKyAgICAgICAgaWYoc2l6ZW9mKG1hdGNoc3RyWzFdKSkKKyAgICAgICAgIHNheShjYXBpdGFsaXplKGJyZWFrX3N0cmluZyhtYXRjaHN0clsxXSw3OCwwLDEpKSwoe3RoaXNfcGxheWVyKCl9KSApOworICAgICAgIH0gZWxzZSB3cml0ZShjYXBpdGFsaXplKGJyZWFrX3N0cmluZyhtYXRjaHN0ciw3OCwwLDEpKSk7CisgICAgICAgcmV0dXJuIDE7CisgICAgICB9IGVsc2Ugbm90aWZ5X2ZhaWwoY2FwaXRhbGl6ZShicmVha19zdHJpbmcobWF0Y2hzdHIsNzgsMCwxKSkpOworICAgICB9CisgICAgfQorICAgIHJldHVybiAwOworICAgfQorCisgICAvLyBVcGRhdGVuIGRlciBIaWxmc3ZhcmlhYmxlbgorICAgcGFyc2VkKz0oe21hdGNoc3RyfSk7CisgICBsYXN0bWF0Y2hwb3M9bWF0Y2hwb3M7CisgICBucnVsKys7CisgIH0gLy8gZW5kIHdoaWxlKG5ydWw8cnMpIC4uLiBFcmZvbGcgLi4uIGFiIHp1bSBuYWVjaHN0ZW4gUmVnZWx0ZWlsCisgfQorCisgLy8gQXJyYXlzIGRlciBALU9iamVjdG1hdGNoZXMgaW4gUGFyYW1ldGVyIGZ1ZXIgTWV0aG9kZSByZXN1YnN0aXR1aWVyZW4KKyBpbnQgb2Jqc2l6ZTsKKyBpZigob2Jqc2l6ZT1zaXplb2Yob2JqbWF0Y2hlcykpKQorICB3aGlsZSgob2Jqc2l6ZS09Mik+PTApCisgICBwYXJzZWRbb2JqbWF0Y2hlc1tvYmpzaXplXV09b2JqbWF0Y2hlc1tvYmpzaXplKzFdOworCisgLy8gZXJmb2xncmVpY2ggTWV0aG9kZSBnZWZ1bmRlbi9laW5lIFJlZ2VsIGJpcyB6dW0gRW5kZSBkdXJjaGdlcGFyc3Q6CisgcmV0dXJuKF9leGVjdXRlKCZmdW4sJnN0ciwmcGFyc2VkKSk7Cit9CisKKy8vIEF1c3dlcnR1bmcgLSBhZGRfYWN0aW9uLUZ1biAKK3B1YmxpYyBpbnQgX2NsKHN0cmluZyBzdHIpIHsKKyBpbnQgbmluZGV4OworIHN0cmluZyAqa2V5czsKKyBtaXhlZCAqZmxhZzsKKyAvLyBWZXJiIGV4aXN0aWVydCwgS29tbWFuZG9zIGF1Y2gsIEVpbnRyYWcgZnVlciBWZXJiIGdlZnVuZGVuCisgaWYobWFwcGluZ3AoYWRkZWRfY21kcykgJiYgcXVlcnlfdmVyYigpKSB7CisgIG1peGVkICpmdW4sICpydWxlLCAqaWRzOworCisgIC8vIGlzdCBkYXMgVmVyYiBlaW4gS2V5IGltIEtvbW1hbmRvbWFwcGluZz8KKyAgaWYobV9jb250YWlucygmZnVuLCAmZmxhZywgJnJ1bGUsICZpZHMsIGFkZGVkX2NtZHMsIHF1ZXJ5X3ZlcmIoKSkpIHsKKyAgIHN0cmluZyAqbm9wYXJzZXN0cjsKKyAgIG5pbmRleD1zaXplb2YoZnVuKTsKKyAgIG5vcGFyc2VzdHI9ZXhwbG9kZSgoc3RyfHwiIiksIiAiKS0oeyIifSk7CisgICAvLyBkYW5uIG1hdGNoZSB1bmdlcGFyc3RlbiBJbnB1dCBnZWdlbiBldHdhaWdlIFJlZ2VsbgorICAgLy8gLS0gbmljaHQgYWVuZGVybjogbmV1ZSBLb21tYW5kb3Mgc29sbGVuIGFsdGUgInVlYmVyc2NocmVpYmVuIiBrb2VubmVuCisgICB3aGlsZShuaW5kZXgtLSkKKyAgICBpZihfcHJvY2Vzc19jb21tYW5kKCZzdHIsIG5vcGFyc2VzdHIsCisJCSAgICAgICBmdW5bbmluZGV4XSwgZmxhZ1tuaW5kZXhdLCBydWxlW25pbmRleF0pKQorICAgIHsKKyAgICAgIEdpdmVFUChFUF9DTUQsIHF1ZXJ5X3ZlcmIoKSk7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKworICAvLyBrZWluZSBSZWdlbCBwYXNzdGUsIHVuc2NoYXJmZSBBdXN3ZXJ0dW5nIGF1ZiBhbGxlCisgIC8vIEFkZENtZHZlcmJlbiBhdXNkZWhuZW4KKyAga2V5cz1tX2luZGljZXMoYWRkZWRfY21kcyk7CisgIG5pbmRleD1zaXplb2Yoa2V5cyk7CisgIHdoaWxlKG5pbmRleC0tKQorICAgaWYoIXN0cnN0cihxdWVyeV92ZXJiKCksa2V5c1tuaW5kZXhdKSAmJgorICAgICAgbWVtYmVyKChmbGFnPWFkZGVkX2NtZHNba2V5c1tuaW5kZXhdLDFdKSwxKT49MCkgeworICAgIGludCBpLHJldDsKKyAgICBpPXNpemVvZihmbGFnKTsKKyAgICAvLyBSZWloZW5mb2xnZSBuaWNodCBhZW5kZXJuICEKKyAgICB3aGlsZShpLS0pCisgICAgICBpZihmbGFnW2ldPT0xKSB7CisgICAgICAgIG1peGVkICpleGVjID0gYWRkZWRfY21kc1trZXlzW25pbmRleF0sMF07CisgICAgICAgIGlmKCFwb2ludGVycChleGVjKSB8fCBzaXplb2YoZXhlYyk8PWkpCisgICAgICAgICAgY2F0Y2gocmFpc2VfZXJyb3IoCisgICAgICAgICAgICAiQWRkQ21kLUF1c3dlcnR1bmc6IENhdGNoQWxsLUtvbW1hbmRvIFwiIitrZXlzW25pbmRleF0rIlwiIgorICAgICAgICAgICAgIiB3dXJkZSB3YWVocmVuZCBkZXIgQXVzZnVlaHJ1bmcgdmVyYWVuZGVydCBvZGVyIGdlbG9lc2NodC4gIgorICAgICAgICAgICAgIktsYXJ0ZXh0OiBEYXMgaXN0IHNjaGxlY2h0LiBTdWNodCBlaW4gUmVtb3ZlQ21kPyAiKTsKKyAgICAgICAgICAgIHB1Ymxpc2gpOworICAgICAgICBlbHNlIGlmKF9leGVjdXRlKGV4ZWNbaV0sc3RyLDApKSB7CisgICAgICAgICAgR2l2ZUVQKEVQX0NNRCwgcXVlcnlfdmVyYigpKTsKKyAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgICAgfQorICAgfQorIH0KKyByZXR1cm4gMDsKK30KKwordm9pZCBpbml0KCkgeworIGFkZF9hY3Rpb24oIl9jbCIsIiIsMSk7Cit9CisKKworc3RhdGljIHZvaWQgX2NoZWNrX2NvcHlfY29tbWFuZHMoc3RyaW5nIGluZCwgbWl4ZWQgKmZ1biwKKwkJCQkgIG1peGVkICpmbGFnLCBtaXhlZCAqcnVsZSkgeworIGlmKHBvaW50ZXJwKGZ1bikpIGFkZGVkX2NtZHNbaW5kLDBdPWZ1bithbGxvY2F0ZSgwKTsKKyBlbHNlIGFkZGVkX2NtZHNbaW5kLDBdPSh7ZnVufSk7CisgaWYocG9pbnRlcnAoZmxhZykpIGFkZGVkX2NtZHNbaW5kLDFdPWZsYWcrYWxsb2NhdGUoMCk7CisgZWxzZSBpZihmbGFnKSBhZGRlZF9jbWRzW2luZCwxXT0oe2ZsYWd9KTsKKyBlbHNlIGFkZGVkX2NtZHNbaW5kLDFdPWFsbG9jYXRlKHNpemVvZihhZGRlZF9jbWRzW2luZF0pKTsKKyBpZihwb2ludGVycChydWxlKSkgYWRkZWRfY21kc1tpbmQsMl09cnVsZSthbGxvY2F0ZSgwKTsKKyBlbHNlIGFkZGVkX2NtZHNbaW5kLDJdPWFsbG9jYXRlKHNpemVvZihhZGRlZF9jbWRzW2luZF0pKTsKKworIGlmKHNpemVvZihhZGRlZF9jbWRzW2luZF0pIT1zaXplb2YoYWRkZWRfY21kc1tpbmQsMV0pIHx8CisgICAgc2l6ZW9mKGFkZGVkX2NtZHNbaW5kXSkhPXNpemVvZihhZGRlZF9jbWRzW2luZCwyXSkpIHsKKyAgYWRkZWRfY21kcz0obWFwcGluZykwOworICByYWlzZV9lcnJvcigiU2V0UHJvcChQX0NPTU1BTkRTKTogY29ycnVwdCBjb21tYW5kcy1tYXBwaW5nLlxuIik7CisgfQorfQorCitzdGF0aWMgbWFwcGluZyBfc2V0X2NvbW1hbmRzKG1hcHBpbmcgY29tbWFuZHMpIHsKKyBpZighY29tbWFuZHMpIGFkZGVkX2NtZHM9KG1hcHBpbmcpMDsKKyBlbHNlIGlmKG1hcHBpbmdwKGNvbW1hbmRzKSkgeworICBhZGRlZF9jbWRzPW1fYWxsb2NhdGUoc2l6ZW9mKGNvbW1hbmRzKSw0KTsKKyAgd2Fsa19tYXBwaW5nKGNvbW1hbmRzLCMnX2NoZWNrX2NvcHlfY29tbWFuZHMpOworIH0KKyBpZiAobWFwcGluZ3AoYWRkZWRfY21kcykpCisgICByZXR1cm4oZGVlcF9jb3B5KGFkZGVkX2NtZHMpKTsKKyBlbHNlCisgICByZXR1cm4gKG1hcHBpbmcpMDsKK30KKworc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X2NvbW1hbmRzKCkgeworIGlmIChtYXBwaW5ncChhZGRlZF9jbWRzKSkKKyAgIHJldHVybihkZWVwX2NvcHkoYWRkZWRfY21kcykpOworIGVsc2UKKyAgIHJldHVybiAobWFwcGluZykwOworfQorCmRpZmYgLS1naXQgYS9zdGQvdGhpbmcvZGVzY3JpcHRpb24uYyBiL3N0ZC90aGluZy9kZXNjcmlwdGlvbi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ3YmZiMGUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdGhpbmcvZGVzY3JpcHRpb24uYwpAQCAtMCwwICsxLDg1MSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHRoaW5nL2Rlc2NyaXB0aW9uLmMgLS0gZGVzY3JpcHRpb24gaGFuZGxpbmcgZm9yIHN0YW5kYXJkIG9iamVjdHMKKy8vCisvLyAkSWQ6IGRlc2NyaXB0aW9uLmMgOTU2MSAyMDE2LTA1LTI1IDE5OjMzOjIyWiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjaW5jbHVkZSA8dGxzLmg+CisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKyNpbmNsdWRlIDx0aGluZy9tYXRlcmlhbC5oPgorI2luY2x1ZGUgPHRoaW5nL2xpZ2h0dHlwZXMuaD4KKyNpbmNsdWRlIDxleHBsb3JhdGlvbi5oPiAgICAgICAgICAgICAgICAgIC8vIHdlZ2VuIEVQTUFTVEVSCisjaW5jbHVkZSA8Y2xhc3MuaD4KKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8dGhpbmcvbGFuZ3VhZ2UuaD4KKworI3VuZGVmIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKworLy8gVmFyaWFibGUgdW0gZGVuIEZQIGFienVzcGVpY2hlcm4gCitwcml2YXRlIG5vc2F2ZSBtaXhlZCAqZXhwbG9yZTsKKworLy8gUHJvdG90eXBlbgorcHVibGljIHN0cmluZyBzaG9ydCgpOworcHVibGljIHZhcmFyZ3Mgc3RyaW5nIGxvbmcoaW50IG1vZGUpOworCisvLyAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBTeXN0ZW0tRnVua3Rpb25lbiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisKKy8vIE9iamVrdCBlcnpldWdlbgorcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgc3RyaW5nIHBvaWQsIHRwaWQ7CisgIG9iamVjdCB0cDsKKworICBTZXRQcm9wKCBQX05BTUUsICJEaW5nIiApOworICBTZXRQcm9wKCBQX1NIT1JULCAiTmljaHRzIGJlc29uZGVyZXMiICk7CisgIFNldFByb3AoIFBfTE9ORywgMCApOworCisgIFNldCggUF9BREpFQ1RJVkVTLCAoe30pICk7CisgIFNldCggUF9OQU1FX0FESiwgKHt9KSApOworICBTZXQoIFBfSURTLCAoe30pICk7CisgIFNldCggUF9DTEFTUywgKHt9KSApOworCisgIFNldCggUF9SRUFEX0RFVEFJTFMsIChbXSksIEZfVkFMVUUpOworICBTZXQoIFBfUkVBRF9ERVRBSUxTLCBTRUNVUkVEfE5PU0VUTUVUSE9ELCBGX01PREVfQVMpOworCisgIFNldCggUF9ERVRBSUxTLCAoW10pLCBGX1ZBTFVFKTsKKyAgU2V0KCBQX0RFVEFJTFMsIFNFQ1VSRUR8Tk9TRVRNRVRIT0QsIEZfTU9ERV9BUyApOworCisgIFNldCggUF9TTUVMTFMsIChbXSksIEZfVkFMVUUpOworICBTZXQoIFBfU01FTExTLCBTRUNVUkVEfE5PU0VUTUVUSE9ELCBGX01PREVfQVMgKTsKKworICBTZXQoIFBfU09VTkRTLCAoW10pLCBGX1ZBTFVFKTsKKyAgU2V0KCBQX1NPVU5EUywgU0VDVVJFRHxOT1NFVE1FVEhPRCwgRl9NT0RFX0FTICk7CisKKyAgU2V0KCBQX1RPVUNIX0RFVEFJTFMsIChbXSksIEZfVkFMVUUpOworICBTZXQoIFBfVE9VQ0hfREVUQUlMUywgU0VDVVJFRHxOT1NFVE1FVEhPRCwgRl9NT0RFX0FTICk7CisKKyAgLy8gQWVuZGVydW5nZW4gYW4gZGllc2VyIFByb3Agc2luZCB0YWJ1LgorICBTZXQoIFBfQ0xPTkVfVElNRSwgTk9TRVRNRVRIT0R8U0VDVVJFRCwgRl9NT0RFX0FTICk7CisKKyAgLy8gSWQgZGVzIENsb25lcnMgdW5kIGRlcyBCZXNpdHplcnMga29tbWVuIG5hY2ggUF9DTE9ORVIKKyAgaWYgKG9iamVjdHAoIHRwPXRoaXNfaW50ZXJhY3RpdmUoKXx8dGhpc19wbGF5ZXIoKSApKQorICB7CisgICAgdHBpZD1nZXRldWlkKHRwKTsKKyAgICBpZiAoISh0cGlkPWdldGV1aWQodHApKSkgdHBpZD1nZXR1aWQodHApOworICB9CisgIGVsc2UKKyAgICB0cGlkPSJVTktOT1dOIjsKKworICBpZiAocHJldmlvdXNfb2JqZWN0KCkpCisgIHsKKyAgICBpZiAoIShwb2lkID0gZ2V0ZXVpZChwcmV2aW91c19vYmplY3QoKSkpKQorICAgICAgcG9pZCA9IGdldHVpZChwcmV2aW91c19vYmplY3QoKSk7CisgIH0KKyAgZWxzZQorICAgIHBvaWQ9IlVOS05PV04iOworCisgIFNldCggUF9DTE9ORVIsIChwb2lkICE9IHRwaWQgPyBwb2lkKyI6Iit0cGlkOiB0cGlkKSApOworICBTZXQoIFBfQ0xPTkVSLCBOT1NFVE1FVEhPRHxTRUNVUkVELCBGX01PREVfQVMgKTsKKworICAvLyBHaWJ0IGVzIEZQcyA/CisgIGV4cGxvcmUgPSAobWl4ZWQgKilFUE1BU1RFUi0+UXVlcnlFeHBsb3JlKCk7CisKKyAgcmV0dXJuOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBGb3JzY2hlcnB1bmt0ZSAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjCisKKy8vIEZQIHZlcmdlYmVuCitzdGF0aWMgdm9pZCBHaXZlRVAoIGludCB0eXBlLCBzdHJpbmcga2V5ICkKK3sKKyAgLy9BYmJydWNoLCB3ZW5uIHZlcmdlYmVuZGVzIE9iamVrdCBzY2hvbiB6ZXJzdG9lcnQgaXN0LiBBQ0hUVU5HOiBBdWNoCisgIC8vZGllc2UgQWJmcmFnZSB3dWVyZGUga2VpbiBGUCB2ZXJnZWJlbiB3ZXJkZW4sIHdlbm4gc2ljaCBkYXMgT2JqZWt0IGltCisgIC8vdmVyZ2ViZW5kZW4gS29tbWFuZG8gemVyc3RvZXJ0LCBkYSBkZXIgRHJpdmVyIGNhbGxfb3RoZXIoKSB2b24gemVyc3RvZXJ0ZW4KKyAgLy9PYmpla3RlbiBpZ25vcmllcnQhCisgIGlmICghb2JqZWN0cCh0aGlzX29iamVjdCgpKSkgcmV0dXJuOworICBpZiAodGhpc19wbGF5ZXIoKSkgdGhpc19wbGF5ZXIoKS0+Y291bnRDbWRzKCB0eXBlLCBrZXkgKTsKKyAgCisgIGlmIChleHBsb3JlJiYhZXh0ZXJuX2NhbGwoKSYmCisgICAgICAoZXhwbG9yZVswXSA9PSB0eXBlKSAmJiAobWVtYmVyKGV4cGxvcmVbMV0sIGtleSkgPj0gMCkgKQorICAgIEVQTUFTVEVSLT5HaXZlRXhwbG9yYXRpb25Qb2ludChrZXkpOworICByZXR1cm47Cit9CisKKy8vIE1hbmNoZSBPYmpla3RlIGtvZW5uZW4gbWl0IHJlbmFtZV9vYmplY3QgZWluZW4gbmV1ZW4gRmlsZW5hbWVuIGJla29tbWVuLgorLy8gRGFuYWNoIHNvbGx0ZSBkZXIgRVBNQVNURVIgbmV1IG5hY2ggZGVuIERldGFpbHMgYmVmcmFndCB3ZXJkZW4uCit2b2lkIF9fcmVsb2FkX2V4cGxvcmUoKQoreworICBleHBsb3JlID0gKG1peGVkICopRVBNQVNURVItPlF1ZXJ5RXhwbG9yZSgpOworICByZXR1cm47Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIElELU1hbmFnZW1lbnQgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIworCisvLyBHaWJ0IGVpbmUgSUQgenVydWVjaywgZGllIGRlbiBMYWRlbmFtZW4sIGRpZSBha3R1ZWxsZSBLdXJ6YmVzY2hyZWlidW5nIHVuZAorLy8gZGllIGFrdHVlbGxlIExhbmdiZXNjaHJlaWJ1bmcgYmVydWVja3NpY2h0aWd0LiBEaWVzZSBJRCBpc3QgZWluIEhhc2h3ZXJ0LgorcHVibGljIHN0cmluZyBkZXNjcmlwdGlvbl9pZCgpIHsKKyAgcmV0dXJuIGhhc2goVExTX0hBU0hfTUQ1LCBsb2FkX25hbWUoKSArIHNob3J0KCkgKyBsb25nKCkpOworfQorCisvKiBJZHMgbXVlc3NlbiB1ZWJlcmdlYmVuIHdlcmRlbiwgZGEgdW5pdCBtYWNobWFsIG1pdCBwbHVyYWwtSWRzLCAqLworLyogYWxzbyBhbmRlcmVuIGFscyBkZW4gbm9ybWFsZW4gYXJiZWl0ZW4gbXVzcy4gKi8KK2ludCBtYXRjaF9pdGVtKCBzdHJpbmcgc3RyLCBzdHJpbmcgKmlkcyApCit7CisgIHN0cmluZyAqb2JqLCphZHM7CisgIGludCBsZW4sIGk7CisgIAorICAvLyBQYXJhbWV0ZXIgZmFsc2NoPyBQYXNzdCBuaWNodCAuLi4KKyAgaWYoIXN0cikgICAgICAgICAgIHJldHVybiAwOworICBpZighcG9pbnRlcnAoaWRzKSkgcmV0dXJuIDA7CisgIGlmKCFzaXplb2YoaWRzKSkgICByZXR1cm4gMDsKKyAgCisgIC8vIElzdCBzY2hvbiBzbyBkYWJlaT8gTmEgS2xhc3NlIDotKQorICBpZihtZW1iZXIoaWRzLHN0cik+LTEpIHJldHVybiAxOworICAKKyAgLy8gS2VpbmUgQWRqZWt0aXZlIHZvcmhhbmRlbiAuLi4gcGFzc3QgbmljaHQuCisgIGlmICghKGFkcz1RdWVyeVByb3AoUF9BREpFQ1RJVkVTKSkpIHJldHVybiAwOworICBpZiAoIXNpemVvZihhZHMpKSAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgCisgIC8vIE51ciBlaW4gV29ydD8gRGFubiBwYXNzdCBlcyBuaWNodAorICBvYmo9ZXhwbG9kZShzdHIsIiAiKTsKKyAgaWYgKCEobGVuPXNpemVvZihvYmopLTEpKSByZXR1cm4gMDsKKyAgCisgIC8vIEFkamVrdGl2ZSBzdGVoZW4gYW0gQW5mYW5nLiBTb2JhbGQgZXMgbmljaHQgbWVociBwYXNzdCwKKyAgLy8gbXVzcyBlcyBkYXMgT2JqZWt0aXYgc2Vpbi4KKyAgd2hpbGUoaTxsZW4mJm1lbWJlcihhZHMsb2JqW2ldKT4tMSkgaSsrOworCisgIHJldHVybiAobWVtYmVyKGlkcyxpbXBsb2RlKG9ialtpLi5sZW5dLCIgIikpPi0xKTsKK30KKworLy8gV2lyZCB2b20gR2FtZWRyaXZlciBhdWZnZXJ1ZmVuIChwcmVzZW50KQorLy8gSGF0IGRpZXNlciBHZWdlbnN0YW5kIGRpZSBJRCBzdHI/CisvLyBsdmwgd2lyZCBpZ25vcmllcnQKK3ZhcmFyZ3MgaW50IGlkKCBzdHJpbmcgc3RyLCBpbnQgbHZsICkgCit7IAorICBzdHJpbmcgc3RyMiwgdG1wOworICBpbnQgY291bnQ7CQorICBzdHJpbmd8c3RyaW5nKiBpZHM7CisKKyAgLy8gS2VpbiBBcmd1bWVudD8gRGFubiBwYXNzdCBlcyBuaWNodCAuLi4KKyAgaWYgKCFzdHJpbmdwKHN0cikpIHJldHVybiAwOworCisgIC8vIEtlaW5lIElEcz8gQXVjaCBuaWNodCBndXQgLi4uCisgIGlmICghcG9pbnRlcnAoaWRzPVF1ZXJ5UHJvcChQX0lEUykpKSByZXR1cm4gMDsKKyAgaWYgKCFzaXplb2YoaWRzKSkgcmV0dXJuIDA7CisKKyAgaWRzICs9ICh7ICgiXG4iICsgb2JqZWN0X25hbWUoKSksCisgICAgICAgICAgICAoIlxuIiArIGV4cGxvZGUob2JqZWN0X25hbWUoKSwiIyIpWzBdKSB9KTsKKworICAvLyBJZCBwYXNzdD8gQWxsZXMga2xhciA6LSkKKyAgaWYgKG1hdGNoX2l0ZW0oIHN0ciwgaWRzICkpIHJldHVybiAxOworCisgIC8vIERpZSBpZCBoYXQgZWluZSBaYWhsIGRyaW4uIFdlbm4gWmFobCBkaWUgUm9oaWQgcGFzc3QsCisgIC8vIGRhbm4gZ3Vja2VuLCBvYiBtYW4gc2VsYmVyIGRhcyBudGUgRWxlbWVudCBpc3QuCisgIGlmIChzc2NhbmYoIHN0ciwgIiVzICVkJXMiLCBzdHIyLCBjb3VudCwgdG1wKTwyKSByZXR1cm4gMDsKKyAgaWYgKGNvdW50PDEpIHJldHVybiAwOworICBpZiAoc2l6ZW9mKHRtcCkpIHJldHVybiAwOworICBpZiAoIW1hdGNoX2l0ZW0oIHN0cjIsIGlkcyApKSByZXR1cm4gMDsKKyAgaWYgKCFlbnZpcm9ubWVudCgpKSByZXR1cm4gMDsKKyAgcmV0dXJuIHByZXNlbnQoc3RyMixjb3VudCxlbnZpcm9ubWVudCgpKT09dGhpc19vYmplY3QoKTsKK30KKworLy8gR2xlaWNoIGVpbmUgZ2FuemUgTGlzdGUgdm9uIGlkcyB0ZXN0ZW4KK2ludCBtYXRjaF9pZHMoc3RyaW5nICpsaXN0KQoreworICBzdHJpbmcgKmlkczsKKworICAvLyBVbmd1ZWx0aWdlIFBhcmFtZXRlcj8gV2VnIGhpZXIgLi4uICAKKyAgaWYgKCFwb2ludGVycChsaXN0KSkgcmV0dXJuIDA7CisgIGlmICghcG9pbnRlcnAoaWRzPVF1ZXJ5UHJvcChQX0lEUykpKSByZXR1cm4gMDsKKworICBpZHMgKz0gKHsgKCJcbiIgKyBvYmplY3RfbmFtZSgpKSwKKyAgICAgICAgICAgICgiXG4iICsgZXhwbG9kZShvYmplY3RfbmFtZSgpLCIjIilbMF0pIH0pOworCisgIHJldHVybiBzaXplb2YoIGxpc3QgJiBpZHMgKTsKK30KKworLy8gSUQgaGluenVmdWVnZW4KK3ZvaWQgQWRkSWQoIHN0cmluZ3xzdHJpbmcqIHN0ciApCit7CisgIGlmIChzdHJpbmdwKHN0cikpIHN0ciA9ICh7IHN0ciB9KTsKKyAgaWYgKHBvaW50ZXJwKHN0cikpCisgICAgLy8gRG9wcGVsdGUgZWxpbWluaWVyZW4KKyAgICBTZXQoIFBfSURTLCBRdWVyeShQX0lEUywgRl9WQUxVRSktc3RyK3N0ciwgRl9WQUxVRSk7CisgIHJldHVybjsKK30KKworLy8gSUQgZW50ZmVybmVuCit2b2lkIFJlbW92ZUlkKHN0cmluZ3xzdHJpbmcqIHN0cikKK3sKKyAgaWYgKHN0cmluZ3Aoc3RyKSkgc3RyID0gKHsgc3RyIH0pOworICBpZiAocG9pbnRlcnAoc3RyKSkKKyAgICBTZXQoUF9JRFMsUXVlcnkoUF9JRFMsIEZfVkFMVUUpLXN0ciwgRl9WQUxVRSk7CisgIHJldHVybjsKK30KKworLy8gQWxsZSBJZHMgYXVmIGVpbm1hbCBzZXR6ZW4KK3N0YXRpYyBzdHJpbmcqIF9zZXRfaWRzKCBzdHJpbmcqIGlkcyApCit7CisgICAgU2V0KCBQX0lEUywoe30pKTsKKyAgICBBZGRJZChpZHMpOworICAgIHJldHVybiBRdWVyeShQX0lEUywgRl9WQUxVRSk7Cit9CisKKy8vIEFkamVrdGl2IGhpbnp1ZnVlZ2VuCit2b2lkIEFkZEFkamVjdGl2ZShzdHJpbmd8c3RyaW5nKiBzdHIpCit7CisgIGlmIChzdHJpbmdwKHN0cikpIHN0ciA9ICh7IHN0ciB9KTsKKyAgaWYgKHBvaW50ZXJwKHN0cikpCisgICAgLy8gRG9wcGVsdGUgZWxpbWluaWVyZW4KKyAgICAgIFNldCggUF9BREpFQ1RJVkVTLCBRdWVyeShQX0FESkVDVElWRVMsIEZfVkFMVUUpLXN0citzdHIsIEZfVkFMVUUgKTsKKyAgcmV0dXJuOworfQorCisvLyBBZGpla3RpdiBlbnRmZXJuZW4KK3ZvaWQgUmVtb3ZlQWRqZWN0aXZlKHN0cmluZ3xzdHJpbmcqIHN0cikKK3sKKyAgaWYgKHN0cmluZ3Aoc3RyKSkgc3RyID0gKHsgc3RyIH0pOworICBpZiAocG9pbnRlcnAoc3RyKSkKKyAgICBTZXQoIFBfQURKRUNUSVZFUywgUXVlcnkoUF9BREpFQ1RJVkVTLCBGX1ZBTFVFKSAtIHN0ciwgRl9WQUxVRSApOworICByZXR1cm47Cit9CisKKy8vIEFsbGUgQWRqZWt0aXZlIGF1ZiBlaW5tYWwgc2V0emVuCitzdGF0aWMgc3RyaW5nKiBfc2V0X2FkamVjdGl2ZXMoc3RyaW5nKiBhZGplY3RpdmVzKQoreworICBTZXQoIFBfQURKRUNUSVZFUywoe30pLCBGX1ZBTFVFKTsKKyAgQWRkQWRqZWN0aXZlKGFkamVjdGl2ZXMpOworICByZXR1cm4gUXVlcnkoUF9BREpFQ1RJVkVTLCBGX1ZBTFVFKTsKK30KKworCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIE5hbWVuc2dlYnVuZyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjCisKKy8vIEltIEZhbGwgdm9uIG1laHJlcmVuIEFkamVrdGl2ZW4gbXVlc3NlbiBkaWVzZSBtaXQga29tbWEKKy8vIHp1c2FtZW5nZWJhdXQgd2VyZGVuLCBkYXp1IG11c3MgaWNoIGRhcyBsZWVyemVpY2hlbiBhYmVyIGVyc3RtYWwKKy8vIGFic2NobmVpZGVuIHVuZCBzbyB3ZWl0ZXIgLi4uCitwcml2YXRlIHN0cmluZyBkZXBvaW50ZXJfYWRqKCBzdHJpbmcqIGFkaiwgaW50IGNhc3VzLCBpbnQgZGVtb24gKSB7CisgIHN0cmluZyBtc2c7CisgIGludCBzdGFydDsKKyAgc3RyaW5nIHJlcyxhOworCWFkaiA9IG1hcCggYWRqLCAjJ0RlY2xBZGosIGNhc3VzLCBkZW1vbiApOworICBzdGFydCA9IDE7CisgIHJlcyA9ICIiOworICBmb3JlYWNoKCBhOiBhZGogKSB7CisgICAgcmVzICs9IChzdGFydCA/ICIiIDogIiwgIikgKyBhWzAuLjwyXTsKKyAgICBzdGFydCA9IDA7CisgIH0KKyAgcmV0dXJuIHJlcyArICIgIjsKK30KKworLy8gV2llIGxhdXRldCBkZXIgTmFtZSBkZXMgT2JqZWt0cz8KK3ZhcmFyZ3Mgc3RyaW5nIG5hbWUoaW50IGNhc3VzLGludCBkZW1vbikKK3sKKyAgbWl4ZWQgc2gsIGFkajsKKyAgaW50IGFydCwgcGx1cmFsOworCisgIGFydCA9IFF1ZXJ5UHJvcChQX0FSVElDTEUpOworCisgIC8vIFJBVzogZGlyZWt0IHp1cnVlY2tnZWJlbiBvaG5lIFZlcmFyYmVpdHVuZworICBpZiAoY2FzdXMgPT0gUkFXICkKKyAgeworICAgIGlmKHBvaW50ZXJwKFF1ZXJ5UHJvcChQX05BTUUpKSkKKyAgICAgIHJldHVybiBRdWVyeVByb3AoUF9OQU1FKVtXRVJdOworICAgIHJldHVybiBRdWVyeVByb3AoUF9OQU1FKTsKKyAgfQorCisgIC8vIFVuc2ljaHRiYXI6IEV0d2FzCisgIGlmIChRdWVyeVByb3AoUF9JTlZJUykpCisgICAgcmV0dXJuICh7ICJldHdhcyIsICJ2b24gZXR3YXMiLCAiZXR3YXMiLCAiZXR3YXMiIH0pW2Nhc3VzXTsKKworICAvLyBLZWluIE5hbWU/IFNjaGFkZSAuLi4KKyAgaWYgKCEoc2g9UXVlcnlQcm9wKFBfTkFNRSkpIHx8CisgICAgICAoc3RyaW5ncChzaCkgJiYgIXNpemVvZihzaCkpKSByZXR1cm4gMDsKKworICAvLyBQX05BTUUgcHJ1ZWZlbi4KKyAgaWYgKHBvaW50ZXJwKHNoKSAmJiBzaXplb2Yoc2gpICE9IDQpCisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJVbmd1ZWx0aWdlIEFycmF5Z3JvZXNzZSBpbiBQX05BTUU6ICVkXG4iLAorICAgICAgICAgICAgc2l6ZW9mKHNoKSkpOworCisgIC8vIFBsdXJhbCAuLiBOYW1lbiB2ZXJ3dXJzdGVuCisgIGlmIChwbHVyYWwgPSBRdWVyeVByb3AoUF9QTFVSQUwpKQorICB7CisgICAgLy8gU2VsYmVyIEFydGlrZWwgc3VjaGVuIGlzdCBuaWNodCAuLi4KKyAgICBpZiAoZGVtb249PTJ8fCFhcnQpIGRlbW9uID0gMDsKKworICAgIC8vIGZhbGxzIFBfTkFNRSBlaW4gQXJyYXkgbWl0IEZhZWxsZW4gZW50aGFlbHQsIGRlbiByaWNodGlnZW4KKyAgICAvLyBleHRyYWhpZXJlbi4uLgorICAgIGlmIChwb2ludGVycChzaCkpIHsKKyAgICAgICAgc2ggPSBzaFtjYXN1c107CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvLyBzb25zdCB2ZXJzdWNoZW4sIHp1IGRla2xpbmllcmVuLgorICAgICAgICBpbnQgbGFzdCA9IHNoWzwxXTsKKyAgICAgICAgaWYgKGNhc3VzID09IFdFTSYmbGFzdCE9J3MnJiZsYXN0IT0nbicpIHNoID0gc2ggKyAibiI7CisgICAgfQorCisgICAgLy8gU2luZCBBZGpla3RpdmUgdm9yaGFuZGVuPworICAgIGlmICggcG9pbnRlcnAoYWRqID0gUXVlcnlQcm9wKFBfTkFNRV9BREopKSAmJiBzaXplb2YoYWRqKSkKKyAgICAgICAgYWRqID0gZGVwb2ludGVyX2FkaihhZGosY2FzdXMsZGVtb24pOworICAgIGlmICghc3RyaW5ncChhZGopKSBhZGogPSAiIjsKKworICAgIHJldHVybiBzcHJpbnRmKCIlcyVzJXMlcyIsUXVlcnlBcnRpY2xlKGNhc3VzLGRlbW9uLDApLGFkaiwKKyAgICAgICAgICAgICAgICAgICAocGx1cmFsIDwgMiA/ICIiOihwbHVyYWwgPCA4ID8KKyAgICAgICAgICAgICAgICAgICAgKHsgInp3ZWkgIiwgImRyZWkgIiwgInZpZXIgIiwgImZ1ZW5mICIsICJzZWNocyAiLAorICAgICAgICAgICAgICAgICAgICAgICAic2llYmVuICIgfSlbcGx1cmFsLTJdIDogdG9fc3RyaW5nKHBsdXJhbCkrIiAiKSksc2gpOworICB9CisKKyAgLy8gTmFtZSBpc3QgUG9pbnRlcjogRWluZmFjaCBkZW4gcmljaHRpZ2VuIGF1c3dhZWhsZW4KKyAgaWYgKHBvaW50ZXJwKHNoKSkKKyAgICBzaCA9IHNoW2Nhc3VzXTsKKworICAvLyBBbnNvbnN0ZW4gZG9jaCB3aWVkZXIgdmVyd3Vyc3RlbiAuLi4KKyAgZWxzZSBpZiAoc3RyaW5ncChzaCkpCisgIHsKKyAgICBpbnQgbGFzdCA9IHNoWzwxXTsKKworICAgIHN3aXRjaChjYXN1cykKKyAgICB7CisgICAgICBjYXNlIFdFTToKKyAgICAgIGNhc2UgV0VOOgorICAgICAgICBpZiAoIGFydCAmJiBsYXN0PT0nZScmJlF1ZXJ5UHJvcChQX0dFTkRFUikgPT0gTUFMRSkKKyAgICAgICAgICBzaCA9IChzdHJpbmcpc2ggKyAibiI7CisgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIFdFU1NFTjoKKyAgICAgICAgaWYoICFhcnQgKQorICAgICAgICB7CisgICAgICAgICAgc3dpdGNoKGxhc3QpCisgICAgICAgICAgeworICAgICAgICAgICAgY2FzZSAneCc6CisgICAgICAgICAgICBjYXNlICdzJzoKKyAgICAgICAgICAgIGNhc2UgJ3onOgorICAgICAgICAgICAgICBzaCA9IChzdHJpbmcpc2ggKyAiJyI7CisgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHNoID0gKHN0cmluZylzaCArICJzIjsKKyAgICAgICAgICB9CisgICAgICAgIH0gCisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgIHN3aXRjaChsYXN0KQorICAgICAgICAgIHsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgIGlmIChRdWVyeVByb3AoUF9HRU5ERVIpIT1GRU1BTEUpCisgICAgICAgICAgICAgICAgc2g9KHN0cmluZylzaCsicyI7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnZSc6CisgICAgICAgICAgICAgIGlmIChRdWVyeVByb3AoUF9HRU5ERVIpPT1NQUxFKQorICAgICAgICAgICAgICAgIHNoPShzdHJpbmcpc2grIm4iOworICAgICAgICAgICAgY2FzZSAneCc6CisgICAgICAgICAgICBjYXNlICdzJzoKKyAgICAgICAgICAgIGNhc2UgJ3onOgorICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICB9IC8qIHN3aXRjaCAobGFzdCkgKi8KKyAgICAgICAgfSAvKiBpZiggIWFydCApIGVsc2UgKi8KKyAgICB9IC8qIHN3aXRjaCggY2FzdXMgKSAqLworICB9IC8qIHBvaW50ZXJwKHNoKSAqLworCisgIC8vIFJBVz8gRGFubiBtYWwgenVydWVjaworICBpZiAoZGVtb24gPT0gUkFXKSByZXR1cm4gKHN0cmluZylzaDsKKworICAvLyBTZWxiZXIgQXJ0aWtlbCBzdWNoZW4gLi4uCisgIGlmIChkZW1vbj09MikKKyAgeworICAgIGlmIChhcnQpCisgICAgICBkZW1vbiA9IFN1Z2dlc3RBcnRpY2xlKCk7CisgICAgZWxzZQorICAgICAgZGVtb249MDsgLy8gS2VpbiBBcnRpa2VsOiBlZ2FsIChTdWdnZXN0QXJ0aWNsZSBpc3QgemVpdGF1ZndlbmRpZykKKyAgfQorCisgIGlmIChwb2ludGVycChhZGogPSBRdWVyeVByb3AoUF9OQU1FX0FESikpICYmIHNpemVvZihhZGopKQorICAgIGFkaiA9IGRlcG9pbnRlcl9hZGooYWRqLGNhc3VzLGRlbW9uKTsKKworICBpZiAoIXN0cmluZ3AoYWRqKSkgIGFkaiA9ICIiOworCisgIHJldHVybiBRdWVyeUFydGljbGUoIGNhc3VzLCBkZW1vbiApK2FkaitzaDsKK30KKworLy8gR3Jvc3NnZXNjaHJpZWJlbmVuIE5hbWVuIHp1cnVlY2tnZWJlbgordmFyYXJncyBzdHJpbmcgTmFtZSggaW50IGNhc3VzLCBpbnQgZGVtb24gKQoreworICAgIHJldHVybiBjYXBpdGFsaXplKG5hbWUoIGNhc3VzLCBkZW1vbiApfHwiIik7Cit9CisKKy8vIExhbmdiZXNjaHJlaWJ1bmcgYW56ZWlnZW4KK3B1YmxpYyB2YXJhcmdzIHN0cmluZyBsb25nKGludCBtb2RlKQoreworICAgIHJldHVybiBwcm9jZXNzX3N0cmluZyggUXVlcnlQcm9wKFBfTE9ORykgKTsKK30KKworLy8gS3VyemJlc2NocmVpYnVuZyBhbnplaWdlbiwgZmFsbHMgbmljaHQgdW5zaWNodGJhcgorcHVibGljIHN0cmluZyBzaG9ydCgpCit7CisgIHN0cmluZyBzaDsKKworICAvLyBVbnNpY2h0YmFyPyBEYW5uIGdpYnRzIG5pY2h0cyB6dSBzZWhlbiAuLi4KKyAgaWYgKFF1ZXJ5UHJvcChQX0lOVklTKXx8IShzaD1RdWVyeVByb3AoUF9TSE9SVCkpKQorICAgIHJldHVybiAwOworICAKKyAgcmV0dXJuIHByb2Nlc3Nfc3RyaW5nKHNoKSsiLlxuIjsKK30KKworLy8gTmFtZW5zLUFkamVrdGl2ZSBzZXR6ZW4KK3N0YXRpYyBzdHJpbmcqIF9zZXRfbmFtZV9hZGooc3RyaW5nfHN0cmluZyogYWRqZWN0aXZlcykKK3sKKyAgaWYgKCFhZGplY3RpdmVzKQorICAgICAgYWRqZWN0aXZlcz0oe30pOworICAvLyBJbiBBcnJheSB1bXdhbmRlbG4KKyAgZWxzZSBpZiAoICFwb2ludGVycChhZGplY3RpdmVzKSkgCisgICAgICBhZGplY3RpdmVzID0gKHsgdG9fc3RyaW5nKGFkamVjdGl2ZXMpIH0pOworICByZXR1cm4gU2V0KCBQX05BTUVfQURKLCBhZGplY3RpdmVzICk7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMgRGV0YWlscywgR2VydWVjaGUsIExhZXJtICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKworLy8gTG93LWxldmVsIEZ1bmt0aW9uIHp1bSBFcmdhZW56ZW4gdm9uIERldGFpbHMsIHdpcmQgdm9uIGRlbiBkaXYuIEFkZC4uLigpCisvLyBnZXJ1ZmVuLCBkaWUgZGFzIHJpY2h0aWdlIE1hcHBpbmcgdWViZXJnZWJlbi4KKy8vIEFlbmRlcnQgZGFzIE1hcHBpbmcgPGRldGFpbHM+IGRpcmVrdC4KK3ByaXZhdGUgdm9pZCBfYWRkX2RldGFpbHMoc3RyaW5nfHN0cmluZyoga2V5cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nfHN0cmluZyp8bWFwcGluZ3xjbG9zdXJlIGRlc2NyLAorICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBwaW5nIGRldGFpbHMgKQoreworICBpZiAoc3RyaW5ncChrZXlzKSkKKyAgICBkZXRhaWxzW2tleXNdPWRlc2NyOworICBlbHNlIGlmIChwb2ludGVycChrZXlzKSkKKyAgeworICAgIGZvcmVhY2goc3RyaW5nIGtleSA6IGtleXMpCisgICAgICBkZXRhaWxzW2xvd2VyX2Nhc2Uoa2V5KV09ZGVzY3I7CisgIH0KKyAgZWxzZQorICAgIHJhaXNlX2Vycm9yKCJXcm9uZyB0eXBlIHRvIGFyZ3VtZW50IDEsIGV4cGVjdGVkIHN0cmluZ3xzdHJpbmcqLlxuIik7Cit9CisKKy8vIExvdy1sZXZlbCBGdW5rdGlvbiB6dW0gRW50ZmVybmVuIHZvbiBEZXRhaWxzLCB3aXJkIHZvbiBkZW4gZGl2LiBSZW1vdmUuLi4oKQorLy8gZ2VydWZlbiwgZGllIGRhcyByaWNodGlnZSBNYXBwaW5nIHVlYmVyZ2ViZW4uCisvLyBBZW5kZXJ0IGRhcyBNYXBwaW5nIDxkZXRhaWxzPiBkaXJla3QuCitwcml2YXRlIHZvaWQgX3JlbW92ZV9kZXRhaWxzKHN0cmluZ3xzdHJpbmcqIGtleXMsIG1hcHBpbmcgZGV0YWlscyApCit7CisgIGlmIChzdHJpbmdwKGtleXMpKQorICAgIGRldGFpbHMgLT0gKFtrZXlzXSk7CisgIGVsc2UgaWYgKHBvaW50ZXJwKGtleXMpKQorICAgIGRldGFpbHMgLT0gbWttYXBwaW5nKGtleXMpOworICBlbHNlCisgICAgcmFpc2VfZXJyb3IoIldyb25nIHR5cGUgdG8gYXJndW1lbnQgMSwgZXhwZWN0ZWQgc3RyaW5nfHN0cmluZyouXG4iKTsKK30KKworLy8gRGV0YWlsKHMpIGhpbnp1ZnVlZ2VuCit2b2lkIEFkZERldGFpbChzdHJpbmd8c3RyaW5nKiBrZXlzLCBzdHJpbmd8c3RyaW5nKnxtYXBwaW5nfGNsb3N1cmUgZGVzY3IpCit7CisgICAgaW50IGk7CisgICAgbWFwcGluZyBkZXRhaWxzOworCisgICAgZGV0YWlscyA9IFF1ZXJ5KFBfREVUQUlMUywgRl9WQUxVRSk7CisKKyAgICAvLyBfYWRkX2RldGFpbHMoKSBhZW5kZXJuIGRhcyBNYXBwaW5nIGRpcmVrdCwgU2V0IGV0Yy4gbmljaHQgbm9ldGlnLgorICAgIHJldHVybiBfYWRkX2RldGFpbHMoa2V5cywgZGVzY3IsIGRldGFpbHMpOworfQorCisvLyBEZXRhaWwocykgZW50ZmVybmVuCit2YXJhcmdzIHZvaWQgUmVtb3ZlRGV0YWlsKHN0cmluZ3xzdHJpbmcqIGtleXMgKQoreworICAvLyBBbGxlIGxvZXNjaGVuIGdlaHQgZGlyZWt0IC4uLgorICBpZiAoIWtleXMgKQorICAgIFNldChQX0RFVEFJTFMsIChbXSksIEZfVkFMVUUpOworICBlbHNlCisgICAgLy8gX3JlbW92ZV9kZXRhaWxzKCkgYWVuZGVybiBkYXMgTWFwcGluZyBkaXJla3QsIFNldCBldGMuIG5pY2h0IG5vZXRpZy4KKyAgICBfcmVtb3ZlX2RldGFpbHMoa2V5cywgUXVlcnkoUF9ERVRBSUxTLCBGX1ZBTFVFKSk7Cit9CisKKy8vIFNwZWNpYWxEZXRhaWwgaGluenVmdWVnZW4KK3ZvaWQgQWRkU3BlY2lhbERldGFpbChzdHJpbmd8c3RyaW5nKiBrZXlzLCBzdHJpbmcgZnVuY3Rpb25uYW1lICkKK3sKKyAgICBjbG9zdXJlIGNsOworCisgICAgLy8gQWJzaWNoZXJuISBTb25zdCBrb2VubnRlIGplZGVyIGludGVybmUgRnVua3Rpb25lbiBhdWZydWZlbgorICAgIGlmIChleHRlcm5fY2FsbCgpICYmCisgICAgICAgIChnZXRldWlkKHByZXZpb3VzX29iamVjdCgpKSAhPSBnZXRldWlkKCkgfHwgcHJvY2Vzc19jYWxsKCkpICYmCisgICAgICAgICEob2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpID09ICIvb2JqL2Rvb3JtYXN0ZXIiICYmCisgICAgICAgICAgZnVuY3Rpb25uYW1lID09ICJzcGVjaWFsX2RldGFpbF9kb29ycyIpICkKKyAgICAgIHJhaXNlX2Vycm9yKCAiSWxsZWdhbCB1c2Ugb2YgQWRkU3BlY2lhbERldGFpbCFcbiIgKTsKKworICAgIC8vIENsb3N1cmUgZ2VuZXJpZXJlbgorICAgIGlmICggIXN0cmluZ3AoZnVuY3Rpb25uYW1lKXx8CisgICAgICAgICAhKGNsID0gc3ltYm9sX2Z1bmN0aW9uKCBmdW5jdGlvbm5hbWUsIHRoaXNfb2JqZWN0KCkpKSApCisgICAgICByZXR1cm47CisKKyAgICAvLyBEZXRhaWwgaGluenVmdWVnZW4KKyAgICBBZGREZXRhaWwoIGtleXMsIGNsICk7CisgICAgcmV0dXJuOworfQorCisvLyBTcGVjaWFsRGV0YWlsKHMpIGVudGZlcm5lbgordm9pZCBSZW1vdmVTcGVjaWFsRGV0YWlsKHN0cmluZ3xzdHJpbmcqIGtleXMgKQoreworICAvLyBSZW1vdmVTcGVjaWFsRGV0YWlsKDApIHd1ZXJkZSBzb25zdCBBTExFIERldGFpbHMgKGF1Y2ggZGllCisgIC8vICdub3JtYWxlbicpIGxvZXNjaGVuCisgIGlmIChwb2ludGVycChrZXlzKXx8c3RyaW5ncChrZXlzKSkKKyAgICBSZW1vdmVEZXRhaWwoa2V5cyk7CisgIHJldHVybjsKK30KKworLy8gTGVzYmFyZXMgRGV0YWlsIGVpbmZ1ZWdlbgordm9pZCBBZGRSZWFkRGV0YWlsKHN0cmluZ3xzdHJpbmcqIGtleXMsCisgICAgICAgICAgICAgICAgICAgc3RyaW5nfHN0cmluZyp8bWFwcGluZ3xjbG9zdXJlIGRlc2NyICkKK3sKKyAgLy8gX2FkZF9kZXRhaWxzKCkgYWVuZGVybiBkYXMgTWFwcGluZyBkaXJla3QsIFNldCBldGMuIG5pY2h0IG5vZXRpZy4KKyAgcmV0dXJuIF9hZGRfZGV0YWlscyhrZXlzLCBkZXNjciwgUXVlcnkoUF9SRUFEX0RFVEFJTFMsIEZfVkFMVUUpKTsKK30KKworLy8gTGVzYmFyZShzKSBEZXRhaWwocykgZW50ZmVybmVuCit2YXJhcmdzIHZvaWQgUmVtb3ZlUmVhZERldGFpbChzdHJpbmd8c3RyaW5nKiBrZXlzICkKK3sKKyAgLy8gQWxsZSBsb2VzY2hlbiBnZWh0IGRpcmVrdCAuLi4KKyAgaWYgKCFrZXlzICkKKyAgICBTZXQoUF9SRUFEX0RFVEFJTFMsIChbXSksIEZfVkFMVUUpOworICBlbHNlCisgICAgLy8gX3JlbW92ZV9kZXRhaWxzKCkgYWVuZGVybiBkYXMgTWFwcGluZyBkaXJla3QsIFNldCBldGMuIG5pY2h0IG5vZXRpZy4KKyAgICBfcmVtb3ZlX2RldGFpbHMoa2V5cywgUXVlcnkoUF9SRUFEX0RFVEFJTFMsIEZfVkFMVUUpKTsKK30KKworLy8gR2VyYWV1c2NoKGUpIGRhenVmdWVnZW4KK3ZvaWQgQWRkU291bmRzKHN0cmluZ3xzdHJpbmcqIGtleXMsCisgICAgICAgICAgICAgICBzdHJpbmd8c3RyaW5nKnxtYXBwaW5nfGNsb3N1cmUgZGVzY3IgKQoreworICAvLyBfYWRkX2RldGFpbHMoKSBhZW5kZXJuIGRhcyBNYXBwaW5nIGRpcmVrdCwgU2V0IGV0Yy4gbmljaHQgbm9ldGlnLgorICByZXR1cm4gX2FkZF9kZXRhaWxzKGtleXMsIGRlc2NyLCBRdWVyeShQX1NPVU5EUywgRl9WQUxVRSkpOworfQorCisvLyBHZXJhZXVzY2goZSkgZW50ZmVybmVuCit2YXJhcmdzIHZvaWQgUmVtb3ZlU291bmRzKHN0cmluZ3xzdHJpbmcqIGtleXMgKQoreworICAvLyBBbGxlIGxvZXNjaGVuIGdlaHQgZGlyZWt0IC4uLgorICBpZiAoIWtleXMgKQorICAgIFNldChQX1NPVU5EUywgKFtdKSwgRl9WQUxVRSk7CisgIGVsc2UKKyAgICAvLyBfcmVtb3ZlX2RldGFpbHMoKSBhZW5kZXJuIGRhcyBNYXBwaW5nIGRpcmVrdCwgU2V0IGV0Yy4gbmljaHQgbm9ldGlnLgorICAgIF9yZW1vdmVfZGV0YWlscyhrZXlzLCBRdWVyeShQX1NPVU5EUywgRl9WQUxVRSkpOworfQorCisvLyBHZXJ1KGUpY2goZSkgaGluenVmdWVnZW4KK3ZvaWQgQWRkU21lbGxzKHN0cmluZ3xzdHJpbmcqIGtleXMsCisgICAgICAgICAgICAgICBzdHJpbmd8c3RyaW5nKnxtYXBwaW5nfGNsb3N1cmUgZGVzY3IgKQoreworICAvLyBfYWRkX2RldGFpbHMoKSBhZW5kZXJuIGRhcyBNYXBwaW5nIGRpcmVrdCwgU2V0IGV0Yy4gbmljaHQgbm9ldGlnLgorICByZXR1cm4gX2FkZF9kZXRhaWxzKGtleXMsIGRlc2NyLCBRdWVyeShQX1NNRUxMUywgRl9WQUxVRSkpOworfQorCisvLyBHZXJ1KGUpY2goZSkgZW50ZmVybmVuCit2YXJhcmdzIHZvaWQgUmVtb3ZlU21lbGxzKHN0cmluZ3xzdHJpbmcqIGtleXMgKQoreworICAvLyBBbGxlIGxvZXNjaGVuIGdlaHQgZGlyZWt0IC4uLgorICBpZiAoIWtleXMgKQorICAgIFNldChQX1NNRUxMUywgKFtdKSwgRl9WQUxVRSk7CisgIGVsc2UKKyAgICAvLyBfcmVtb3ZlX2RldGFpbHMoKSBhZW5kZXJuIGRhcyBNYXBwaW5nIGRpcmVrdCwgU2V0IGV0Yy4gbmljaHQgbm9ldGlnLgorICAgIF9yZW1vdmVfZGV0YWlscyhrZXlzLCBRdWVyeShQX1NNRUxMUywgRl9WQUxVRSkpOworfQorCisvLyBUYXN0YmFyZShzKSBEZXRhaWwocykgaGluenVmdWVnZW4KK3ZvaWQgQWRkVG91Y2hEZXRhaWwoc3RyaW5nfHN0cmluZyoga2V5cywKKyAgICAgICAgICAgICAgICAgICAgc3RyaW5nfHN0cmluZyp8bWFwcGluZ3xjbG9zdXJlIGRlc2NyICkKK3sKKyAgLy8gX2FkZF9kZXRhaWxzKCkgYWVuZGVybiBkYXMgTWFwcGluZyBkaXJla3QsIFNldCBldGMuIG5pY2h0IG5vZXRpZy4KKyAgcmV0dXJuIF9hZGRfZGV0YWlscyhrZXlzLCBkZXNjciwgUXVlcnkoUF9UT1VDSF9ERVRBSUxTLCBGX1ZBTFVFKSk7Cit9CisKKy8vIFRhc3RiYXJlKHMpIERldGFpbChzKSBlbnRmZXJuZW4KK3ZhcmFyZ3Mgdm9pZCBSZW1vdmVUb3VjaERldGFpbHMoc3RyaW5nfHN0cmluZyoga2V5cyApCit7CisgIC8vIEFsbGUgbG9lc2NoZW4gZ2VodCBkaXJla3QgLi4uCisgIGlmICgha2V5cyApCisgICAgU2V0KFBfVE9VQ0hfREVUQUlMUywgKFtdKSwgRl9WQUxVRSk7CisgIGVsc2UKKyAgICAvLyBfcmVtb3ZlX2RldGFpbHMoKSBhZW5kZXJuIGRhcyBNYXBwaW5nIGRpcmVrdCwgU2V0IGV0Yy4gbmljaHQgbm9ldGlnLgorICAgIF9yZW1vdmVfZGV0YWlscyhrZXlzLCBRdWVyeShQX1RPVUNIX0RFVEFJTFMsIEZfVkFMVUUpKTsKK30KKworLy8gRGV0YWlsaW5mb3MgZnVlciBEZXRhaWwga2V5LCBTcGllbGVyIGhhdCBkaWUgUmFzc2UgcmFjZQorLy8gdW5kIGJlbnV0enQgc2VpbmVuIFNpbm4gc2Vuc2UKK3ZhcmFyZ3Mgc3RyaW5nIEdldERldGFpbChzdHJpbmcga2V5LCBzdHJpbmcgcmFjZSwgaW50IHNlbnNlKQoreworICBzdHJpbmd8c3RyaW5nKnxtYXBwaW5nfGNsb3N1cmUgZGV0YWlsOworICAKKyAgaWYgKHN0cmluZ3AocmFjZSkpIHJhY2UgPSBsb3dlcl9jYXNlKHJhY2UpOworICAKKyAgc3dpdGNoKHNlbnNlKQorICB7CisgICAgY2FzZSBTRU5TRV9TTUVMTDogZGV0YWlsPVF1ZXJ5KFBfU01FTExTLCBGX1ZBTFVFKVtrZXldOworICAgICAgICAgICAgICAgICAgICAgIHNlbnNlPUVQX1NNRUxMOyBicmVhazsKKyAgICBjYXNlIFNFTlNFX1NPVU5EOiBkZXRhaWw9UXVlcnkoUF9TT1VORFMsIEZfVkFMVUUpW2tleV07CisgICAgICAgICAgICAgICAgICAgICAgc2Vuc2U9RVBfU09VTkQ7IGJyZWFrOworICAgIGNhc2UgU0VOU0VfVE9VQ0g6IGRldGFpbD1RdWVyeShQX1RPVUNIX0RFVEFJTFMsIEZfVkFMVUUpW2tleV07CisgICAgICAgICAgICAgICAgICAgICAgc2Vuc2U9RVBfVE9VQ0g7IGJyZWFrOworICAgIGNhc2UgU0VOU0VfUkVBRDogIGRldGFpbD1RdWVyeShQX1JFQURfREVUQUlMUywgRl9WQUxVRSlba2V5XTsKKyAgICAgICAgICAgICAgICAgICAgICBzZW5zZT1FUF9SREVUOworICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDogICAgICAgICAgZGV0YWlsPVF1ZXJ5KFBfREVUQUlMUywgRl9WQUxVRSlba2V5XTsKKyAgICAgICAgICAgICAgICAgICAgICBzZW5zZT1FUF9ERVRBSUw7IGJyZWFrOworICB9CisKKyAgaWYgKCFzdHJpbmdwKGRldGFpbCkpCisgIHsKKyAgICBpZiAoY2xvc3VyZXAoZGV0YWlsKSkKKyAgICAgIGRldGFpbCA9IChzdHJpbmcpZnVuY2FsbChkZXRhaWwsa2V5KTsKKyAgICBlbHNlIGlmIChtYXBwaW5ncChkZXRhaWwpKQorICAgICAgZGV0YWlsID0gKHN0cmluZykoZGV0YWlsW3JhY2VdfHxkZXRhaWxbMF0pOworICAgIGVsc2UgaWYgKHBvaW50ZXJwKGRldGFpbCkpCisgICAgICBkZXRhaWwgPSAoc3RyaW5nKShkZXRhaWxbcmFuZG9tKHNpemVvZihkZXRhaWwpKV0pOworICB9CisKKyAgLy8gRlAgdmVyZ2ViZW4gKHNvIHZvcmhhbmRlbiA7LSkgKQorICBpZiAoZGV0YWlsKSBHaXZlRVAoc2Vuc2Usa2V5KTsKKworICByZXR1cm4gZGV0YWlsOworfQorCisvLyBUT0RPOiBPQlNPTEVUIChMaWJncmVwIG5vdHdlbmRpZykKK3ZvaWQgcmVhZCggc3RyaW5nIHN0ciApIHsKKyAgcmFpc2VfZXJyb3IoIkRpZXNlIEZ1bmt0aW9uIGV4aXN0aWVydCBuaWNodCBtZWhyLlxuIik7Cit9CisKKworLy8gICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBadWdyaWZmc2Z1bmt0aW9uZW4gIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworCisvLyBEaWVuZW4gZGF6dSwgZGllIGRpcmVrdGUgTWFuaXB1bGF0aW9uIGRlciBQcm9wcyB2b24gYXVzc2VuIHp1IGVyc2Nod2VyZW4uCisKKy8vIEZpbHRlciwgdW0gU3BlY2lhbGRldGFpbHMgenUgZWxpbWluaWVyZW4KKy8vIGVyc3RlbGx0IGF1c3NlcmRlbSBuZSBLb3BpZSB2b20gTWFwcGluZy4gKFdpY2h0aWchKQorLy8gV2lyZCB2b3IgYWxsZW0gYmVub2V0aWd0LCB1bSBQX0RFVEFJTFMgaW4gUF9ERVRBSUxTIHVuZCAKKy8vIFBfU1BFQ0lBTF9ERVRBSUxTIHp1IHRyZWZmZW4uCitwcml2YXRlIGludCBfY2xvc3VyZXMoc3RyaW5nIHgsIG1hcHBpbmcgZGV0YWlscywgaW50IHllcyApIAoreyAKKyAgICByZXR1cm4geWVzID8gY2xvc3VyZXAoZGV0YWlsc1t4XSkgOiAhY2xvc3VyZXAoZGV0YWlsc1t4XSk7IAorfQorCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfZGV0YWlscygpCit7CisgIHJldHVybiBmaWx0ZXJfaW5kaWNlcyhRdWVyeShQX0RFVEFJTFMsIEZfVkFMVUUpLCAjJ19jbG9zdXJlcywKKyAgICAgIFF1ZXJ5KFBfREVUQUlMUywgRl9WQUxVRSksMCk7Cit9CisKK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV9zcGVjaWFsX2RldGFpbHMoKQoreworICByZXR1cm4gZmlsdGVyX2luZGljZXMoUXVlcnkoUF9ERVRBSUxTLCBGX1ZBTFVFKSwjJ19jbG9zdXJlcywKKyAgICAgIFF1ZXJ5KFBfREVUQUlMUywgRl9WQUxVRSksMSk7Cit9CisKK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV9yZWFkX2RldGFpbHMoKSB7CisgIHJldHVybiBkZWVwX2NvcHkoUXVlcnkoUF9SRUFEX0RFVEFJTFMsIEZfVkFMVUUpKTsKK30KKworc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X3NvdW5kX2RldGFpbHMoKSB7CisgIHJldHVybiBkZWVwX2NvcHkoUXVlcnkoUF9TT1VORFMsIEZfVkFMVUUpKTsKK30KKworc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X3NtZWxsX2RldGFpbHMoKSB7CisgIHJldHVybiBkZWVwX2NvcHkoUXVlcnkoUF9TTUVMTFMsIEZfVkFMVUUpKTsKK30KKworCisvLyAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIEtsYXNzZW4tTWl0Z2xpZWRzY2hhZnQgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworCisvLyBLbGFzc2UgaGluenVmdWVnZW4KK3B1YmxpYyB2b2lkIEFkZENsYXNzKHN0cmluZ3xzdHJpbmcqIHN0cikKK3sKKyAgaWYgKHN0cmluZ3Aoc3RyKSkgCisgICAgICBzdHIgPSAoeyBzdHIgfSk7CisgIC8vIEFsaWFzZSBhdWZsb2VzZW4gdW5kIGltcGxpeml0ZSBLbGFzc2VuIGFkZGllcmVuLgorICBzdHIgPSAoc3RyaW5nKilDTEFTU0RCLT5BZGRJbXBsaWNpdENsYXNzZXMoc3RyKTsKKyAgLy8gU3VtbWUgbWl0IGFsdGVuIEtsYXNzZW4gYmlsZGVuIHVuZCBEb3BwZWx0ZSBlbGltaW5pZXJlbgorICBzdHIgPSBzdHIgKyBRdWVyeShQX0NMQVNTLCBGX1ZBTFVFKTsKKyAgU2V0KCBQX0NMQVNTLCBtX2luZGljZXMobWttYXBwaW5nKHN0cikpLCBGX1ZBTFVFKTsKKworICByZXR1cm47Cit9CisKKy8vIEtsYXNzZSBlbnRmZXJuZW4KK3ZvaWQgUmVtb3ZlQ2xhc3Moc3RyaW5nfHN0cmluZyogc3RyKQoreworIGlmIChzdHJpbmdwKHN0cikpIAorICAgICAgc3RyID0gKHsgc3RyIH0pOworCisgIC8vIEFsaWFzZSBhdWZsb2VzZW4gdW5kIGltcGxpeml0ZSBLbGFzc2VuIGFkZGllcmVuLgorICBzdHIgPSAoc3RyaW5nKilDTEFTU0RCLT5BZGRJbXBsaWNpdENsYXNzZXMoc3RyKTsKKworICAvLyBVbmQgYWxsZSAtIGlua2x1c2l2ZSBpbXBsaXppdGVyIEtsYXNzZW4gLSBlbnRmZXJuZW4KKyAgLy8gVE9ETzogUHJ1ZWZlbiwgb2IgZGllcyBkaWUgcmljaHRpZ2UgRW50c2NoZWlkdW5nIGlzdC4KKyAgU2V0KCBQX0NMQVNTLCBRdWVyeShQX0NMQVNTLCBGX1ZBTFVFKS1zdHIsIEZfVkFMVUUpOworCisgIHJldHVybjsKK30KKworLy8gSXN0IGRhcyBPYmpla3QgTWl0Z2xpZWQgZGVyIEtsYXNzZSBzdHI/CitpbnQgaXNfY2xhc3NfbWVtYmVyKHN0cmluZ3xzdHJpbmcqIHN0cikKK3sKKyAgLy8gS2VpbmUgS2xhc3NlLCBrZWluZSBNaXRnbGllZHNjaGFmdCAuLi4KKyAgaWYgKCFzdHIgfHwgc3RyPT0iIikgCisgICAgICByZXR1cm4gMDsKKworICAvLyBFcyBzb2xsdGUgc2Nob24gZWluIEFycmF5IHNlaW4KKyAgaWYgKHN0cmluZ3Aoc3RyKSkgCisgICAgICBzdHIgPSAoeyBzdHIgfSk7CisKKyAgLy8gS2xhc3NlbiB1bmQgSWRzIGlucyBBcnJheQorICBzdHJpbmcgKmNsYXNzZXM9UXVlcnlQcm9wKFBfQ0xBU1MpOworICBpZiAoIXBvaW50ZXJwKGNsYXNzZXMpKQorICAgIHJldHVybiAwOworCisgIC8vIC4uIHVuZCB0ZXN0ZW4KKyAgZm9yZWFjaChzdHJpbmcgY2xhc3MgOiBzdHIpCisgICAgaWYgKG1lbWJlcihjbGFzc2VzLGNsYXNzKSA+IC0xICkgcmV0dXJuIDE7CisKKyAgcmV0dXJuIDA7Cit9CisKKy8vIEtsYXNzZSBkaXJla3Qgc2V0emVuIGFiZmFuZ2VuCitzdGF0aWMgc3RyaW5nKiBfc2V0X2NsYXNzKHN0cmluZyogY2xhc3NlcyApCit7CisgIFNldCggUF9DTEFTUywgKHt9KSwgRl9WQUxVRSApOworICBBZGRDbGFzcyhjbGFzc2VzKTsKKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX0NMQVNTKTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgTWF0ZXJpYWwtSGFuZGxpbmcgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIworCisvLyBNYXRlcmlhbCBzZXR6ZW4KK3N0YXRpYyBtYXBwaW5nIF9zZXRfbWF0ZXJpYWwobWFwcGluZ3xzdHJpbmd8c3RyaW5nKiBtYXQgKQoreworICBtYXBwaW5nIG1hdHMgPSAoW10pOworICAKKyAgaWYgKG1hcHBpbmdwKG1hdCkpIAorICB7CisgICAgaWYoICFzaXplb2YobWF0KSB8fCAhd2lkdGhvZihtYXQpICkKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIlBfTUFURVJJQUw6IGV4cGVjdGVkIG1hcHBpbmcgd2l0aCBhdCBsZWFzdCBvbmUgIgorICAgICAgICAia2V5IGFuZCBvbmUgdmFsdWUsIGdvdCAlLjUwT1xuIixtYXQpKTsKKyAgICBlbHNlIAorICAgICAgbWF0cyA9IG1hdDsKKyAgfQorICBlbHNlIGlmIChzdHJpbmdwKG1hdCkpCisgICAgbWF0c1ttYXRdPTEwMDsKKyAgZWxzZQorICB7CisgICAgaW50IHN6ID0gc2l6ZW9mKG1hdCk7CisgICAgLy8gS29tbXQgZGFubiB2b3IsIHdlbm4gPG1hdD4gMCBvZGVyICh7fSkgaXN0LgorICAgIGlmICggIXN6ICkKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIlBfTUFURVJJQUw6IGV4cGVjdGVkIHN0cmluZyBvciBub24tZW1wdHkgIgorICAgICAgICAibWFwcGluZ3xzdHJpbmcqLCBnb3QgJS41ME8uXG4iLCBtYXQpKTsKKyAgICBtYXRzID0gbWttYXBwaW5nKG1hdCwgYWxsb2NhdGUoc3osIDEwMC9zeikpOworICB9IAorICByZXR1cm4gU2V0KCBQX01BVEVSSUFMLCBtYXRzLCBGX1ZBTFVFICk7Cit9CisKKy8vIFdvcmF1cyBiZXN0ZWh0IGRhcyBPYmpla3Q/CitzdGF0aWMgbWFwcGluZyBfcXVlcnlfbWF0ZXJpYWwoKQoreworICBtaXhlZCByZXM7CisgIAorICBpZiAoICFtYXBwaW5ncChyZXMgPSBRdWVyeShQX01BVEVSSUFMLCBGX1ZBTFVFKSkgKQorICAgIHJldHVybiAoW01BVF9NSVNDOjEwMF0pOworICAKKyAgcmV0dXJuIHJlczsKK30KKworLy8gQW50ZWlsIHZvbiBtYXQgYW0gT2JqZWt0PworaW50IFF1ZXJ5TWF0ZXJpYWwoIHN0cmluZyBtYXQgKQoreworICBtYXBwaW5nIG1hdHM7CisgIAorICBpZiAoICFtYXBwaW5ncChtYXRzID0gUXVlcnlQcm9wKFBfTUFURVJJQUwpKSApCisgICAgcmV0dXJuIDA7CisgIAorICByZXR1cm4gbWF0c1ttYXRdOworfQorCisvLyBBbnRlaWwgZGVyIEdydXBwZSBhbSBPYmpla3QKK2ludCBRdWVyeU1hdGVyaWFsR3JvdXAoIHN0cmluZyBtYXRncm91cCApCit7CisgIHJldHVybiAoaW50KWNhbGxfb3RoZXIoIE1BVEVSSUFMREIsICJNYXRlcmlhbEdyb3VwIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlQcm9wKFBfTUFURVJJQUwpLCBtYXRncm91cCApOworfQorCisKK3N0cmluZyBNYXRlcmlhbExpc3QoIGludCBjYXN1cywgbWl4ZWQgaWRpbmYgKQoreworICByZXR1cm4gKHN0cmluZyljYWxsX290aGVyKCBNQVRFUklBTERCLCAiQ29udk1hdGVyaWFsTGlzdCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFF1ZXJ5UHJvcChQX01BVEVSSUFMKSwgY2FzdXMsIGlkaW5mICk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9zaXplKGludCBzeikgeworLy9Hcm9lc3NlIG11c3MgPiAwIHNlaW4sIGFsbGVzIGFuZGVyZSBpc3QgdW5zaW5uaWchICgwIHVuZCBuZWcuIEdyb2Vzc2VuCisvL2hhYmVuIGtlaW5lIHBoeXMuIFJlbGV2YW56IHVuZCBtYWNoZW4gdS5VLiBQcm9ibGVtZSBtaXQgT2JqZWt0ZW4sIGRpZQorLy9TY2hhZGVuIGluIEFiaGFlbmdpZ2tlaXQgZGVyIEdyb2Vzc2UgbWFjaGVuKQorICBpZiAoc3o+MCkKKyAgICBTZXQoUF9TSVpFLHN6LEZfVkFMVUUpOworICByZXR1cm4oUXVlcnkoUF9TSVpFLEZfVkFMVUUpKTsKK30KKworLy8gUF9DTE9ORV9USU1FCitzdGF0aWMgaW50IF9xdWVyeV9jbG9uZV90aW1lKCkgeyByZXR1cm4gb2JqZWN0X3RpbWUoKTsgfQorCmRpZmYgLS1naXQgYS9zdGQvdGhpbmcvZW52Y2hrLmMgYi9zdGQvdGhpbmcvZW52Y2hrLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjZjZTEzYgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC90aGluZy9lbnZjaGsuYwpAQCAtMCwwICsxLDM2IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gZW52Y2hrLmMgLS0gdmVyaGluZGVybiwgZGFzcyBvYmpla3RlIG9obmUgZW52IGhlcnVtZmxpZWdlbgorLy8KKy8vICRJZDogdGhpbmcuYyA2MjgzIDIwMDctMDUtMDkgMjE6MzA6MzNaIFplc3N0cmEgJCAgICAgICAgICAgICAgICAgICAgICAKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjaW5jbHVkZSA8bW92aW5nLmg+CisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL21vdmluZy5oPgorCitwcm90ZWN0ZWQgdm9pZCBjaGVja19mb3JfZW52aXJvbm1lbnQoc3RyaW5nIGNsb25lcikKK3sKKyAgLy8gQ2xvbmVzLCBkaWUgaW5uZXJoYWxiIHZvbiAxMCBTZWt1bmRlbiBrZWluIEVudmlyb25tZW50IGhhYmVuLAorICAvLyBzb2xsZW4gYXVmIC1kZWJ1ZyBzY3JvbGxlbi4KKyAgaWYgKCBjbG9uZXAoKSAmJiAhZW52aXJvbm1lbnQoKSApIHsKKyAgICAvLyBtYWwgaW4gZGVuIE11ZWxscmF1bSBiZXdlZ2VuLCBkYW1pdCBkaWVzZSBPYmpla3RlIHp3YXIgbmljaHQgemVyc3RvZXJ0CisgICAgLy8gd2VyZGVuLCBhYmVyIHp1bWluZGVzdCBoaW50ZXJoZXIgbm9jaCBlaW5mYWNoIGF1ZmZpbmRiYXIgc2luZC4gKFVuZAorICAgIC8vIGVudHdlZGVyIHBlciBoYW5kIG9kZXIgYXV0b21hdGlzY2ggYXVmZ2VyYWV1bXQgd2VyZGVuIGtvZW5uZW4uKQorICAgIG1vdmUoIi9yb29tL211ZWxscmF1bSIsTV9OT0NIRUNLfE1fU0lMRU5UKTsKKyAgICBpZiAoICFzdHJpbmdwKGNsb25lcikgfHwgIXNpemVvZihjbG9uZXIpICkKKyAgICAgIGNsb25lciA9ICI8VW5iZWthbm50PiI7CisgICAgcmFpc2VfZXJyb3IoIk9iamVrdCBoYXQga2VpbiBFbnZpcm9ubWVudC4gQ2xvbmVyOiBbIitjbG9uZXIrIl0gIik7CisgIH0KK30KKwordm9pZCBjcmVhdGUoKQoreworCWlmKCBjbG9uZXAoKSApIAorICAgIGNhbGxfb3V0KCMnY2hlY2tfZm9yX2Vudmlyb25tZW50LCAzLCBvYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSkpOworfQpkaWZmIC0tZ2l0IGEvc3RkL3RoaW5nL2xhbmd1YWdlLmMgYi9zdGQvdGhpbmcvbGFuZ3VhZ2UuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YTNkNmY5Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3RoaW5nL2xhbmd1YWdlLmMKQEAgLTAsMCArMSwxOTkgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB0aGluZy9sYW5ndWFnZS5jIC0tIGxhbmd1YWdlIGhhbmRsaW5nIG9iamVjdAorLy8KKy8vICRJZDogbGFuZ3VhZ2UuYyA4MzU5IDIwMTMtMDItMDkgMTE6NDM6MzlaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorCisvLyBLZWluIGNyZWF0ZSgpCit2b2lkIGNyZWF0ZSgpCit7CisgIHJldHVybjsKK30KKworLy9JbnZlcnNpb24sIGRhbWl0IERlZmF1bHR3ZXJ0IHZvbiAwIGVpbmVuIEFydGlrZWwgYXVzZ2lidAorc3RhdGljIGludCBfcXVlcnlfYXJ0aWNsZSgpIHsgcmV0dXJuICFRdWVyeShQX0FSVElDTEUpOyB9CisKK3N0YXRpYyBpbnQgX3NldF9hcnRpY2xlKGludCBhcnQpIHsgcmV0dXJuICFTZXQoUF9BUlRJQ0xFLCFhcnQpOyB9CisKKy8vIEJlc3RpbW10ZW4gQXJ0aWtlbCBiZXN0aW1tZW4KK3ByaXZhdGUgc3RyaW5nIHF1ZXJ5X2NfYXJ0aWNsZShpbnQgY2FzdXMpCit7CisgIGlmIChRdWVyeVByb3AoUF9QTFVSQUwpKQorICAgIHJldHVybiAoeyAiZGllICIsICJkZXIgIiwgImRlbiAiLCAiZGllICJ9KVtjYXN1c107CisKKyAgcmV0dXJuICh7ICh7ICJkYXMgIiwgImRlcyAiLCAiZGVtICIsICJkYXMgIiB9KSwKKyAgICAgICAgICAgICh7ICJkZXIgIiwgImRlcyAiLCAiZGVtICIsICJkZW4gIiB9KSwKKyAgICAgICAgICAgICh7ICJkaWUgIiwgImRlciAiLCAiZGVyICIsICJkaWUgIiB9KSB9KQorICAgIFsoaW50KVF1ZXJ5UHJvcChQX0dFTkRFUildW2Nhc3VzXTsKK30KKworLy8gRW5kZSBmdWVyIEFydGlrZWwgdW5kIEFkamVrdGl2ZQorcHJpdmF0ZSB2YXJhcmdzIHN0cmluZyBxdWVyeV9nX3N1ZmZpeChpbnQgZ2VuLCBpbnQgY2FzdXMsIGludCBhbnphaGwpCit7CisgIHJldHVybiAoeyAoeyAoeyAiIiwiZSJ9KSwgKHsiZXMiLCJlciJ9KSwgKHsiZW0iLCJlbiJ9KSwgKHsgICIiLCJlIn0pIH0pLAorCSAgICAoeyAoeyAiIiwiZSJ9KSwgKHsiZXMiLCJlciJ9KSwgKHsiZW0iLCJlbiJ9KSwgKHsiZW4iLCJlIn0pIH0pLAorCSAgICAoeyAoeyJlIiwiZSJ9KSwgKHsiZXIiLCJlciJ9KSwgKHsiZXIiLCJlbiJ9KSwgKHsgImUiLCJlIn0pIH0pIH0pCisgICAgW2dlbl1bY2FzdXNdW2FuemFobF07Cit9CisKKy8vIEFydGlrZWwgdm9yc2NobGFnZW46IGdpYnQgZXMgbm9jaCBtZWhyIE9iamVrdGUgaW0gaW52PwordmFyYXJncyBpbnQgU3VnZ2VzdEFydGljbGUoc3RyaW5nIGlkKQoreworICBvYmplY3Qgb2IsKm9iczsKKworICAvLyBSYXVtIG9kZXIgTWFzdGVyOiBCZXN0aW1tdC4KKyAgaWYgKCFlbnZpcm9ubWVudCgpKSByZXR1cm4gMTsKKworICAvLyBLZWluZSBpZD8gRGFubiByYXVzCisgIGlmICghaWQpIHJldHVybiAxOworCisgIC8vIE9iamVrdCBtaXQgZ2xlaWNoZW0gTmFtZW4gaW0gZW52PyBEYW5uIHVuYmVzdGltbXQKKyAgZm9yICggb2I9Zmlyc3RfaW52ZW50b3J5KGVudmlyb25tZW50KCkpIDsgb2IgOyBvYj1uZXh0X2ludmVudG9yeShvYikgKQorICAgIGlmICggb2IhPXRoaXNfb2JqZWN0KCkmJiBpZD09KHN0cmluZylvYi0+UXVlcnlQcm9wKFBfTkFNRSkgKQorICAgICAgcmV0dXJuIDA7CisKKyAgLy8gc29uc3QgYmVzdGltbXQKKyAgcmV0dXJuIDE7Cit9CisKKy8vIEFydGlrZWwgYmVzdGltbWVuCit2YXJhcmdzIHN0cmluZyBRdWVyeUFydGljbGUoaW50IGNhc3VzLCBpbnQgZGVtLCBpbnQgZm9yY2UpCit7CisgIC8vIEtlaW4gQXJ0aWtlbAorICBpZiAoIWZvcmNlICYmIShRdWVyeVByb3AoUF9BUlRJQ0xFKSkpIHJldHVybiAiIjsKKworICAvLyBBcnRpa2VsYXJ0IGF1c3N1Y2hlbgorICBpZiAoIGRlbT09MiApIGRlbSA9IFN1Z2dlc3RBcnRpY2xlKFF1ZXJ5UHJvcChQX05BTUUpKTsKKworICAvLyBCZXN0aW1tdGVyIEFydGlrZWwKKyAgaWYgKGRlbSkgcmV0dXJuIHF1ZXJ5X2NfYXJ0aWNsZShjYXN1cyk7CisKKyAgLy8gVW5iZXN0aW1tdGVyIEFydGlrZWwKKyAgaWYgKFF1ZXJ5UHJvcChQX1BMVVJBTCkpIHJldHVybiAiIjsKKyAgCisgIHJldHVybiBzcHJpbnRmKCJlaW4lcyAiLHF1ZXJ5X2dfc3VmZml4KChpbnQpUXVlcnlQcm9wKFBfR0VOREVSKSxjYXN1cykpOworfQorCisvLyBCZXNpdHphbnplaWdlciBmdWVyIE9iamVrdCBiZXN0aW1tZW4KK3ZhcmFyZ3Mgc3RyaW5nIFF1ZXJ5T3duKGludCBjYXN1cykKK3sKKyAgcmV0dXJuIHNwcmludGYoIkRlaW4lcyIscXVlcnlfZ19zdWZmaXgoUXVlcnlQcm9wKFBfR0VOREVSKSxjYXN1cykpOworfQorCisvLyBQb3NzZXNzaXZwcm9ub21lbiBiZXN0aW1tZW4KK3ZhcmFyZ3Mgc3RyaW5nIFF1ZXJ5UG9zc1Byb25vdW4obWl4ZWQgd2hhdCwgaW50IGNhc3VzLCBpbnQgbnVtYmVyKQoreworICBpbnQgZ2VuMjsKKworICAvLyBHZXNjaGxlY2h0IGVybWl0dGVsbgorICBnZW4yID0gKG9iamVjdHAod2hhdCk/KGludCl3aGF0LT5RdWVyeVByb3AoUF9HRU5ERVIpOihpbnQpd2hhdCk7CisKKyAgLy8gUGx1cmFsIGlzdCBzY2hvZW4gZWluZmFjaAorICBpZiAoUXVlcnlQcm9wKFBfUExVUkFMKSkgcmV0dXJuICJpaHIiK3F1ZXJ5X2dfc3VmZml4KGdlbjIsIGNhc3VzLCBudW1iZXIpOworCisgIHJldHVybiAoKCgoKGludClRdWVyeVByb3AoIFBfR0VOREVSICkpPT1GRU1BTEUgKT8gImlociI6InNlaW4iKSsKKyAgICAgICAgICBxdWVyeV9nX3N1ZmZpeChnZW4yJTMsIGNhc3VzLCBudW1iZXIpKTsKK30KKworLy8gUHJvbm9tZW4gYmVzdGltbWVuIG5hY2ggS05HCit2YXJhcmdzIHN0cmluZyBRdWVyeVByb25vdW4oaW50IGNhc3VzKQoreworICBpbnQgZ2VuZGVyOworCisgIC8vIFBsdXJhbCBpc3QgaW1tZXIgZWluZmFjaCAuLi4KKyAgaWYgKFF1ZXJ5UHJvcChQX1BMVVJBTCkpIAorICB7CisgICAgIGlmIChjYXN1cz09V0VNKSByZXR1cm4gImlobmVuIjsKKyAgICAgcmV0dXJuICJzaWUiOworICB9CisKKyAgc3dpdGNoKFF1ZXJ5UHJvcChQX0dFTkRFUikpCisgIHsKKyAgICBjYXNlIEZFTUFMRToKKyAgICAgIGlmIChjYXN1cz09V0VTU0VOKSByZXR1cm4gImlocmVyIjsKKyAgICAgIGlmIChjYXN1cz09V0VNKSByZXR1cm4gImlociI7CisgICAgICByZXR1cm4gInNpZSI7CisKKyAgICBjYXNlIE1BTEU6CisgICAgICBpZiAoY2FzdXM9PVdFUikgcmV0dXJuICJlciI7CisgICAgICBpZiAoY2FzdXM9PVdFU1NFTikgcmV0dXJuICJzZWluZXIiOworICAgICAgaWYgKGNhc3VzPT1XRU0pIHJldHVybiAiaWhtIjsKKyAgICAgIHJldHVybiAiaWhuIjsKKyAgfSAgICAKKyAgaWYgKGNhc3VzPT1XRVNTRU4pIHJldHVybiAic2VpbmVyIjsKKyAgaWYgKGNhc3VzPT1XRU0pIHJldHVybiAiaWhtIjsKKyAgcmV0dXJuICJlcyI7IC8vZmFsbC10aHJvdWdoCit9CisKKy8vIEFucmVkZSBmdWVyIFNwaWVsZXIgYmVzdGltbWVuCit2YXJhcmdzIHN0cmluZyBRdWVyeUR1KGludCBjYXN1cyxpbnQgZ2VuZGVyLGludCB6YWhsKQoreworICByZXR1cm4KKyAgICAoeyAoeyh7ICAgICJkdSIsICAgImlociJ9KSwoeyAgICAiZHUiLCAgICJpaHIifSksKHsgICAgImR1IiwgICAiaWhyIn0pfSksCisgICAgICAgKHsoeyJkZWluZXIiLCAgImV1ZXIifSksKHsiZGVpbmVyIiwgICJldWVyIn0pLCh7ImRlaW5lciIsICAiZXVlciJ9KX0pLAorICAgICAgICh7KHsgICAiZGlyIiwgICJldWNoIn0pLCh7ICAgImRpciIsICAiZXVjaCJ9KSwoeyAgICJkaXIiLCAgImV1Y2gifSl9KSwKKyAgICAgICAoeyh7ICAiZGljaCIsICAiZXVjaCJ9KSwoeyAgImRpY2giLCAgImV1Y2gifSksKHsgICJkaWNoIiwgICJldWNoIn0pfSkKKyAgICAgfSlbY2FzdXNdW2dlbmRlcl1bemFobF07Cit9CisKKy8vIFdlbGNoZXMgR2VzY2hsZWNodCBoYXQgZGFzIE9iamVrdCBhbHMgU3RyaW5nPworc3RyaW5nIFF1ZXJ5R2VuZGVyU3RyaW5nKCkKK3sKKyAgc3dpdGNoKCAoaW50KVF1ZXJ5UHJvcCggUF9HRU5ERVIgKSkKKyAgeworICAgIGNhc2UgTUFMRTogICByZXR1cm4gIm1hZW5ubGljaCI7CisgICAgY2FzZSBGRU1BTEU6IHJldHVybiAid2VpYmxpY2giOworICB9CisgIHJldHVybigic2FlY2hsaWNoIik7IC8vZmFsbC10aHJvdWdoCit9CisKKy8vIEFydGlrZWwgZHVyY2hkZWtsaW5pZXJlbiBuYWNoIEthc3VzLCBOdW1lcnVzLCBHZW51cyB1bmQgQXJ0CisvLyBkZXMgQXJ0aWtlbHMgKGRlbW9uPT1iZXN0aW1tdCkKK3ZhcmFyZ3Mgc3RyaW5nIERlY2xBZGoobWl4ZWQgYWRqLCBpbnQgY2FzdXMsIGludCBkZW1vbikKK3sKKwkvLyBVbnJlZ2VsbWFlc3NpZ2UgQWRqZWt0aXZlCisJaWYoIHBvaW50ZXJwKGFkaikgKSByZXR1cm4gYWRqW2Nhc3VzXSsiICI7CisKKyAgLy8gRmFsc2NoZXIgVHlwPyBVbmQgVHNjaHVlc3MgLi4uCisgIGlmICghc3RyaW5ncChhZGopKSByZXR1cm4gIiI7CisKKyAgLy8gUGx1cmFsIGlzdCBlaW5mYWNoCisgIGlmIChRdWVyeVByb3AoUF9QTFVSQUwpKQorICB7CisgICAgLy8gQmVzdGltbXQKKyAgICBpZiAoZGVtb24pIHJldHVybiBhZGorImVuICI7CisKKyAgICAvLyBVbmJlc3RpbW10CisgICAgcmV0dXJuIGFkaiArICh7ICJlICIsICJlciAiLCAiZW4gIiwgImUgIiB9KVtjYXN1c107CisgIH0KKyAgCisgIGlmICggZGVtb24gKQorICAgIHJldHVybiBhZGogKyAoeyAoeyAiZSAiICwgImVuICIsICJlbiAiLCAiZSAiICB9KSwKKwkJICAgICh7ICJlICIgLCAiZW4gIiwgImVuICIsICJlbiAiIH0pLAorCQkgICAgKHsgImUgIiAsICJlbiAiLCAiZW4gIiwgImUgIiAgfSkgfSkKKyAgICAgIFsoaW50KVF1ZXJ5UHJvcCggUF9HRU5ERVIgKV1bY2FzdXNdOworICBlbHNlCisgICAgcmV0dXJuIGFkaiArICh7ICh7ICJlcyAiLCAiZW4gIiwgImVuICIsICJlcyAiIH0pLAorCQkgICAgKHsgImVyICIsICJlbiAiLCAiZW4gIiwgImVuICIgfSksCisJCSAgICAoeyAiZSAiICwgImVuICIsICJlbiAiLCAiZSAiICB9KSB9KQorICAgICAgWyhpbnQpUXVlcnlQcm9wKCBQX0dFTkRFUiApXVtjYXN1c107Cit9CisKKy8vIFBfR0VOREVSIHNldHplbi4gRXMgc2luZCBudXIgMCwxIHVuZCAyIChNQUxFLEZFTUFMRSxORVVURVIpIGVybGF1YnQKK3N0YXRpYyBpbnQgX3NldF9nZW5kZXIoaW50IGkpCit7CisgIGlmIChpPi0xJiZpPDMpIHJldHVybiBTZXQoUF9HRU5ERVIsaSk7CisgIHJldHVybiBRdWVyeShQX0dFTkRFUik7Cit9CmRpZmYgLS1naXQgYS9zdGQvdGhpbmcvbGlnaHQuYyBiL3N0ZC90aGluZy9saWdodC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM2NDExYjQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdGhpbmcvbGlnaHQuYwpAQCAtMCwwICsxLDYyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdGhpbmcvZGVzY3JpcHRpb24uYyAtLSBMaWNodHN5c3RlbWtvbXBvbmVudGVuIGZ1ZXIgU3RhbmRhcmRvYmpla3RlCisvLworLy8gJElkOiBkZXNjcmlwdGlvbi5jIDc2MzUgMjAxMC0wOC0xOSAyMToyMTozMFogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMscnR0X2NoZWNrcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgorI2luY2x1ZGUgPGhvb2suaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHRoaW5nL2xpZ2h0dHlwZXMuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFN5c3RlbS1GdW5rdGlvbmVuICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKworLy8gT2JqZWt0IGVyemV1Z2VuCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBTZXQoIFBfTElHSFQsIDAgKTsKKyAgU2V0KCBQX0xJR0hUX1RZUEUsIExUX01JU0MpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30gICAgIAorCisvLyBMaWNodHN5IC4uLiBzeXMgLi4uCitzdGF0aWMgaW50IF9xdWVyeV90b3RhbF9saWdodCgpIHsgcmV0dXJuIFF1ZXJ5UHJvcChQX0xJR0hUKTsgfQorCitzdGF0aWMgaW50IF9zZXRfbGlnaHQoIGludCBsaWdodCApCit7CisgICAgb2JqZWN0IGVudiA9IHRoaXNfb2JqZWN0KCk7CisKKyAgICAvLyBUT0RPOiBUZW1wb3JhZXIgTGljaHRsZXZlbCBpbiBnZWVpZ25ldGUgV2VydGVmZW5zdGVyIHp3aW5nZW4uCisgICAgaWYgKGxpZ2h0ID4gMTAwKQorICAgICAgbGlnaHQgPSAxMDA7CisgICAgZWxzZSBpZiAobGlnaHQgPCAtMTAwKQorICAgICAgbGlnaHQgPSAtMTAwOworICAgCisgICAgd2hpbGUgKCBvYmplY3RwKGVudiA9IGVudmlyb25tZW50KGVudikpICkKKyAgICAgICAgLy8gSmEuIE1hbiBydWZ0IGRpZSBfc2V0X3h4eCgpLUZ1bmt0aW9uZW4gZWlnZW50bGljaCBuaWNodCBkaXJla3QgYXVmLgorICAgICAgICAvLyBBYmVyIGRhcyBMaWNodHN5c3RlbSBpc3Qgc2Nob24gKnNvKiByZWNoZW5pbnRlbnNpdiB1bmQgZ2VyYWRlIGRlcgorICAgICAgICAvLyBQX0xBU1RfQ09OVEVOVF9DSEFOR0UtQ2FjaGUgd2lyZCAqc28qIG9mdCBiZW5vZXRpZ3QsIGRhc3MgZXMgbWlyCisgICAgICAgIC8vIGRhIHVtIGplZGVzIGJpc3NjaGVuIFJlY2hlbnplaXQgZ2VodC4KKyAgICAgICAgLy8gRGVyIFp3ZWNrIGhlaWxpZ3QgamEgYmVrYW5udGxpY2ggZGllIE1pdHRlbC4gOy0pCisgICAgICAgIC8vCisgICAgICAgIC8vIFRpYW1haworICAgICAgICBlbnYtPl9zZXRfbGFzdF9jb250ZW50X2NoYW5nZSgpOworICAgIAorICAgIHJldHVybiBTZXQoIFBfTElHSFQsIGxpZ2h0LCBGX1ZBTFVFKTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3RoaW5nL21vdmluZy5jIGIvc3RkL3RoaW5nL21vdmluZy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc4MGFjNDEKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdGhpbmcvbW92aW5nLmMKQEAgLTAsMCArMSwyMDEgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB0aGluZy9tb3ZpbmcuYyAtLSBvYmplY3QgbW92aW5nCisvLworLy8gJElkOiBtb3ZpbmcuYyA4ODkyIDIwMTQtMDgtMDQgMTk6NDg6MjhaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisKKy8vIERhcyBPYmpla3QgYmV3ZWdlbi4KKy8vIFJ1ZWNrZ2FiZSAxIGlzdCBFcmZvbGcsIDw9MCBpc3QgRmVobGVyCisKKy8vIGEpIFBfTk9EUk9QL1BfTk9HRVQtQmVoYW5kbHVuZy4KKy8vIGIpIHp1bSBVZWJlcnNjaHJlaWJlbgorcHJvdGVjdGVkIGludCBQcmV2ZW50TW92ZShvYmplY3QgZGVzdCwgb2JqZWN0IG9sZGVudiwgaW50IG1ldGhvZCkgeworICBpbnQgdG1wOworICAKKyAgLy8gTV9OT0NIRUNLPyAtPiBCZXdlZ3VuZyBlaCBlcmxhdWJ0ICh1bmQgUnVlY2tnYWJld2VydCB3dWVyZGUgaWdub3JpZXJ0KQorICBpZiAoKG1ldGhvZCZNX05PQ0hFQ0spKSB7CisgICAgLy8gQmVpIE1fTk9DSEVDSyB6d2FyIFByZXZlbnQqIGF1ZnJ1ZmVuLCBhYmVyIGRhcyBSZXN1bHRhdCBpZ25vcmllcmVuCisgICAgaWYgKG9sZGVudikgb2xkZW52LT5QcmV2ZW50TGVhdmUodGhpc19vYmplY3QoKSxkZXN0KTsKKyAgICBkZXN0LT5QcmV2ZW50SW5zZXJ0KHRoaXNfb2JqZWN0KCkpOworCisgICAgcmV0dXJuIDA7IC8vIGRhcyB3YXJzLCByZXN0IGlzdCBlZ2FsLgorICB9CisKKyAgLy8gUF9OT0RST1AgdmVyaGluZGVydCB3ZWdnZWJlbgorICBpZiAoKG1ldGhvZCAmIChNX1BVVHxNX0dJVkUpKSAmJiBRdWVyeVByb3AoUF9OT0RST1ApKQorICAgICAgcmV0dXJuIE1FX0NBTlRfQkVfRFJPUFBFRDsKKworICAvLyBQX05PR0VUIHZlcmhpbmRlcnQgbmVobWVuCisgIGlmICgobWV0aG9kICYgKE1fR0VUfE1fR0lWRSkpICYmIFF1ZXJ5UHJvcChQX05PR0VUKSkKKyAgICAgIHJldHVybiBNRV9DQU5UX0JFX1RBS0VOOworCisgIC8vIEdld2ljaHQgZXJtaXR0ZWxuCisgIGlmICggISh0bXAgPSAoaW50KVF1ZXJ5UHJvcChQX1RPVEFMX1dFSUdIVCkpICkKKyAgICAgIHRtcCA9IChpbnQpUXVlcnlQcm9wKFBfV0VJR0hUKTsKKyAgICAgICAgCisgIC8vIElzdCBkYXMgT2JqZWt0IG5pY2h0IHp1IHNjaHdlcj8KKyAgaWYgKCAodG1wID0gKGludClkZXN0LT5NYXlBZGRXZWlnaHQodG1wKSkgPCAwKSB7CisgICAgICBpZiAoIHRtcCA9PSAtMiApIHJldHVybiBNRV9UT09fSEVBVllfRk9SX0VOVjsKKyAgICAgIHJldHVybiBNRV9UT09fSEVBVlk7CisgIH0KKworICAvLyBJc3QgZGFzIFppZWxvYmpla3Qgc2Nob24gdm9sbD8KKyAgaWYgKCAhZGVzdC0+TWF5QWRkT2JqZWN0KHRoaXNfb2JqZWN0KCkpICkKKyAgICAgIHJldHVybiBUT09fTUFOWV9PQkpFQ1RTOworCisgIC8vIERhcmYgaGluYXVzYmV3ZWd0IHdlcmRlbj8KKyAgaWYgKCBvbGRlbnYgJiYgb2xkZW52LT5QcmV2ZW50TGVhdmUodGhpc19vYmplY3QoKSwgZGVzdCkgKQorICAgICAgcmV0dXJuIE1FX0NBTlRfTEVBVkVfRU5WOworCisgIC8vIERhcmYgaGluZWluYmV3ZWd0IHdlcmRlbj8KKyAgaWYgKCBkZXN0LT5QcmV2ZW50SW5zZXJ0KHRoaXNfb2JqZWN0KCkpICkKKyAgICAgIHJldHVybiBNRV9DQU5UX0JFX0lOU0VSVEVEOworCisgIHJldHVybigwKTsKK30KKworLy8genVtIFVlYmVyc2NocmVpYmVuLi4uCitwcm90ZWN0ZWQgdm9pZCBOb3RpZnlNb3ZlKG9iamVjdCBkZXN0LCBvYmplY3Qgb2xkZW52LCBpbnQgbWV0aG9kKSB7Cit9CisKK3ZhcmFyZ3MgaW50IG1vdmUoIG9iamVjdHxzdHJpbmcgZGVzdCwgaW50IG1ldGhvZCApCit7CisgIG9iamVjdCBvbGRlbnY7CisgIGludCB0bXA7CisgIHN0cmluZyBmbix2YzsKKyAgbWl4ZWQgc2VuczsKKworICBpZiAoIW9iamVjdHAoZGVzdCkgJiYgIXN0cmluZ3AoZGVzdCkpCisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJXcm9uZyBhcmd1bWVudCAxIHRvIG1vdmUoKS4gJ2Rlc3QnIG11c3QgYmUgYSAiCisgICAgICAgICAgICAic3RyaW5nIG9yIG9iamVjdCEgQXJndW1lbnQgd2FzOiAlLjEwME9cbiIsCisgICAgICAgICAgICBkZXN0KSk7CisKKyAgLy8gSmV0emlnZSBVbWdlYnVuZyBtZXJrZW4KKyAgb2xkZW52ID0gZW52aXJvbm1lbnQoKTsKKworICAvLyBCZXdlZ3VuZyBpbiBQYXJhLVdlbHQtUmFldW1lPworICAvLyB0bXAgaXN0IGRpZSBaaWVsLVBhcmFsbGVsd2VsdG51bW1lcgorICBpZiAoIWVudmlyb25tZW50KCl8fCFsaXZpbmcoZW52aXJvbm1lbnQoKSl8fAorICAgICAgIWludHAodG1wID0oaW50KWVudmlyb25tZW50KCktPlF1ZXJ5KFBfUEFSQSkpKQorICAgIHRtcD0wOworICAgIAorICAvLyBXZW5uIGRhcyBPYmpla3Qgdm9uIGVpbmVtIGluIGRlciBQYXJhd2VsdCBiZWZpbmRsaWNoZW4gU3BpZWxlcgorICAvLyBvZGVyIE5QQyBiZXdlZ3Qgd2lyZCwgc29sbHRlIGVzIGF1Y2ggd2llZGVyIGluIGRlciBQYXJhd2VsdCBsYW5kZW4uCisgIC8vIFVtIFJlY2hlbnplaXQgenUgc3BhcmVuLCB3aXJkIGFuZ2Vub21tZW4sIGRhc3MgYmVpIEJld2VndW5nZW4gaW4KKyAgLy8gZGFzIEludiBvZGVyIEVudiBkZXMgU3BpZWxlcnMgJ2Rlc3QnIGFscyBPYmpla3QgdWViZXJnZWJlbiB3aXJkLAorICAvLyB3b2hpbmdlZ2VuIGJlaSBCZXdlZ3VuZ2VuIGluIE5hY2hiYXJyYWV1bWUgKGRpZSBlaWdlbnRsaWNoIG51cgorICAvLyBpbnRlcmVzc2FudCBzaW5kKSAnZGVzdCcgYWxzIEZpbGVuYW1lIGFuZ2VnZWJlbiB3aXJkLgorICBpZiAodG1wJiYhb2JqZWN0cChkZXN0KSYmIWVudmlyb25tZW50KGRlc3QpKSB7CisgICAgICAvLyBGYWxscyBkZXIgWmllbHJhdW0gbmljaHQgc2Nob24gZXhwbGl6aXQgaW4gZGVyIFBhcmFsbGVsd2VsdCBpc3QsCisgICAgICAvLyBuZXVlbiBaaWVscmF1bSBzdWNoZW4uIEFiZXIgbnVyLCB3ZW5uIGRhcyBaaWVsIGtlaW4gQ2xvbmUgaXN0LiBTb25zdAorICAgICAgLy8gYnVnZ3QsIHdlbm4gbWFuIHZlcnN1Y2h0LCBuYWNoIHJhdW0jNDJecGFyYSB6dSBiZXdlZ2VuLgorICAgICAgaWYgKCFJU19QQVJBKGRlc3QpICYmIHN0cnJzdHIoZGVzdCwiIyIpPT0tMSkgeworICAgICAgICBmbj1kZXN0KyJeIit0bXA7CisKKyAgICAgICAgLy8gRGVyIFBhcmF3ZWx0LVJhdW0gd2lyZCBudXIgenVtIFppZWwsIHdlbm4gZXIgYSkgZXhpc3RpZXJ0CisgICAgICAgIC8vIHVuZCBiKSBhdWNoIHZvbiBTcGllbGVybiBiZXRyZXRlbiB3ZXJkZW4gZGFyZi4gTGV0enRlcmVzCisgICAgICAgIC8vIEtyaXRlcml1bSBrYW5uIG51ciBtaXQgaW0gT2JqZWt0IGdlc2V0enRlciBQcm9wZXJ0eQorICAgICAgICAvLyBQX1RFU1RQTEFZRVIgdW1nYW5nZW4gd2VyZGVuLgorICAgICAgICAgIGlmICggKGZpbmRfb2JqZWN0KGZuKSB8fCAoKGZpbGVfc2l6ZShmbisiLmMiKT4wfHwKKyAgICAgICAgICAgICAgICAgIChmaWxlX3NpemUodmM9aW1wbG9kZShleHBsb2RlKGZuLCIvIilbMC4uPDJdLCIvIikrCisgICAgICAgICAgICAgICAgICAiL3ZpcnR1YWxfY29tcGlsZXIuYyIpPjAgJiYKKyAgICAgICAgICAgICAgICAgICFjYXRjaCh0bXA9KGludCljYWxsX290aGVyKHZjLCJRdWVyeVZhbGlkT2JqZWN0Iixmbik7CisgICAgICAgICAgICAgICAgICAgIHB1Ymxpc2gpICYmIHRtcD4wKSkgJiYKKyAgICAgICAgICAgICAgICAgICFjYXRjaChsb2FkX29iamVjdCggZm4gKTtwdWJsaXNoKSkpICYmCisgICAgICAgICAgICAgICghZm4tPlF1ZXJ5UHJvcChQX05PX1BMQVlFUlMpIHx8IFF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpKSApCisgICAgICAgICAgIGRlc3QgPSBmbjsKKyAgICAgIH0KKyAgfQorICAgIAorICAvLyBkZXN0IGF1ZiBPYmpla3Qgbm9ybWllcmVuLgorICBpZiAoc3RyaW5ncChkZXN0KSkKKyAgICAgIGRlc3QgPSBsb2FkX29iamVjdChkZXN0KTsKKyAgICAKKyAgLy8gdGVzdGVuLCBvYiBkYXMgT2JqZWt0IGJld2VndCB3ZXJkZW4gd2lsbAorICBpZiAodG1wPVByZXZlbnRNb3ZlKGRlc3QsIG9sZGVudiwgbWV0aG9kKSkgeworICAgICAgLy8gYXVmIGd1ZWx0aWdlbiBGZWhsZXIgcHJ1ZWZlbiwgd2VyIHdlaXNzLCB3YXMgTWFnaWVyIGRhIGV2dGwuCisgICAgICAvLyB2ZXJzZWhlbnRsaWNoZSB6dXJ1ZWNrZ2ViZW4uCisgICAgICBpZiAoVkFMSURfTU9WRV9FUlJPUih0bXApKQorICAgICAgICByZXR1cm4odG1wKTsKKyAgICAgIGVsc2UKKyAgICAgICAgcmV0dXJuKE1FX0RPTlRfV0FOVF9UT19CRV9NT1ZFRCk7CisgIH0KKworICAvLyBTZW5zaXRpdmUgT2JqZWt0ZSBtdWVzc2VuIGVudGZlcm50IHdlcmRlbgorICBzZW5zID0gUXVlcnlQcm9wKFBfU0VOU0lUSVZFKTsKKworICBpZiAoc2VucyAmJiBlbnZpcm9ubWVudCgpKQorICB7CisgICAgZW52aXJvbm1lbnQoKS0+UmVtb3ZlU2Vuc2l0aXZlT2JqZWN0KCB0aGlzX29iamVjdCgpICk7CisgICAgaWYgKCFvYmplY3RwKE1FKSkKKyAgICAgIHJldHVybiBNRV9XQVNfREVTVFJVQ1RFRDsKKyAgfQorICAvLyBCZXdlZ2VuCisgIG1vdmVfb2JqZWN0KE1FLCBkZXN0KTsKKworICAvL2ZhbGxzIChzaWNoKSBkYXMgb2JqZWt0IGltIGluaXQoKSB6ZXJzdG9lcnQgKHd1cmRlKS4gKERpZSB1LiBzdGVoZW5kZW4KKyAgLy9GdW5rdGlvbnNhdWZydWZlIHdlcmRlbiBkYW5uIHZvbSBEcml2ZXIgZWggZ3JvZXNzdGVudGVpbHMgaWdub3JpZXJ0LikKKyAgaWYgKCFvYmplY3RwKHRoaXNfb2JqZWN0KCkpKSByZXR1cm4oTUVfV0FTX0RFU1RSVUNURUQpOworCisgIC8vIE9iamVrdCBpbmZvcm1pZXJlbi4gOy0pCisgIE5vdGlmeU1vdmUoZW52aXJvbm1lbnQoKSwgb2xkZW52LCBtZXRob2QpOworCisgIC8vIEFsdGUgVW1nZWJ1bmcgaW5mb3JtaWVyZW4KKyAgaWYgKG9sZGVudikgb2xkZW52LT5Ob3RpZnlMZWF2ZSh0aGlzX29iamVjdCgpLCBkZXN0KTsKKworICAvLyBXZW5uIGRhcyBPYmpla3QgZWluZSBVbWdlYnVuZyBoYXQsIHNlbGJpZ2UgaW5mb3JtaWVyZW4KKyAgaWYgKGVudmlyb25tZW50KCkpIHsKKyAgICBpZiAoc2VucykKKyAgICB7CisgICAgICBlbnZpcm9ubWVudCgpLT5JbnNlcnRTZW5zaXRpdmVPYmplY3QodGhpc19vYmplY3QoKSxzZW5zKTsKKyAgICAgIGlmICghb2JqZWN0cChNRSkpIHJldHVybiBNRV9XQVNfREVTVFJVQ1RFRDsKKyAgICB9CisgICAgZW52aXJvbm1lbnQoKS0+Tm90aWZ5SW5zZXJ0KHRoaXNfb2JqZWN0KCksIG9sZGVudik7CisgIH0KKyAgLy93dXJkZSBkYXMgT2JqZWt0IHZpZWxsZWljaHQgbm9jaCB6ZXJzdG9lcnQ/CisgIGlmICghb2JqZWN0cChNRSkpIHJldHVybihNRV9XQVNfREVTVFJVQ1RFRCk7CisgIAorICAvL3NjaGVpbnQgd29obCBhbGxlcyBvayB6dSBzZWluLgorICByZXR1cm4gTU9WRV9PSzsKK30KKworLy8gRGFzIE9iamVrdCB6ZXJzdG9lcmVuCit2YXJhcmdzIGludCByZW1vdmUoaW50IHNpbGVudCkKK3sgCisgICAgaWYgKGVudmlyb25tZW50KCkgKSB7CisgICAgICAgIGlmKFF1ZXJ5UHJvcChQX1NFTlNJVElWRSkpCisgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQoKS0+UmVtb3ZlU2Vuc2l0aXZlT2JqZWN0KHRoaXNfb2JqZWN0KCkpOworICAgICAgICBlbnZpcm9ubWVudCgpLT5Ob3RpZnlSZW1vdmUodGhpc19vYmplY3QoKSk7CisgICAgfQorICAgIGlmIChvYmplY3RwKHRoaXNfb2JqZWN0KCkpKQorICAgICAgICBkZXN0cnVjdCh0aGlzX29iamVjdCgpKTsKKyAgICByZXR1cm4gMTsKK30KKworcHVibGljIHN0cmluZyBOb3RpZnlEZXN0cnVjdChvYmplY3QgY2FsbGVyKSB7CisgIC8vIExpY2h0c3lzdGVtIG1pdCBkZXIgYWVuZGVydW5nIHZlcnNvcmdlbi4gOi0vCisgIGZvcmVhY2gob2JqZWN0IGVudiA6IGFsbF9lbnZpcm9ubWVudCgpIHx8ICh7fSkpIHsKKyAgICAgIC8vIEphLiBNYW4gcnVmdCBkaWUgX3NldF94eHgoKS1GdW5rdGlvbmVuIGVpZ2VudGxpY2ggbmljaHQgZGlyZWt0IGF1Zi4KKyAgICAgIC8vIEFiZXIgZGFzIExpY2h0c3lzdGVtIGlzdCBzY2hvbiAqc28qIHJlY2hlbmludGVuc2l2IHVuZCBnZXJhZGUgZGVyCisgICAgICAvLyBQX0xBU1RfQ09OVEVOVF9DSEFOR0UtQ2FjaGUgd2lyZCAqc28qIG9mdCBiZW5vZXRpZ3QsIGRhc3MgZXMgbWlyCisgICAgICAvLyBkYSB1bSBqZWRlcyBiaXNzY2hlbiBSZWNoZW56ZWl0IGdlaHQuCisgICAgICAvLyBEZXIgWndlY2sgaGVpbGlndCBqYSBiZWthbm50bGljaCBkaWUgTWl0dGVsLiA7LSkKKyAgICAgIC8vCisgICAgICAvLyBUaWFtYWsKKyAgICAgIGVudi0+X3NldF9sYXN0X2NvbnRlbnRfY2hhbmdlKCk7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC90aGluZy9wcm9wZXJ0aWVzLmMgYi9zdGQvdGhpbmcvcHJvcGVydGllcy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2NTkyYmYKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdGhpbmcvcHJvcGVydGllcy5jCkBAIC0wLDAgKzEsMzI2IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdGhpbmcvcHJvcGVydGllcy5jIC0tIG1vc3QgZ2VuZXJhbCBjbGFzcyAocHJvcGVydHkgaGFuZGxpbmcpCisvLworLy8gJElkOiBwcm9wZXJ0aWVzLmMgNjk1MSAyMDA4LTA4LTA5IDIzOjA4OjMxWiBaZXNzdHJhICQKKworLy8gUHJvcGVydGllcy5jIC0tIFByb3BlcnR5dmVyd2FsdHVuZworLy8gKGMpIDE5OTMgSGF0ZUBNb3JnZW5HcmF1ZW4sIE1hdGVlc2VATmlnaHRGYWxsCisvLyAgICAgICAgICBJZGVhIGFuZCBDb2RlICAgICAgRmxhbWVzIGFuZCBEZXN0cnVjdGlvbnMKKy8vIC0+ICpncmluKiB0aGF0cyB0aGUgcG9pbnQgYWN0dWFsbHkgOikgCisvLworLy8gVWViZXJhcmJlaXRldCB2b24gSm9mICAgICAgIGFtIDEyLjA2LjE5OTQKKy8vIFVlYmVyYXJiZWl0ZXQgdm9uIE1hbmRyYWdvbiBhbSAxMS4wNS4yMDAzCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgIi9zeXMvdGhpbmcvcHJvcGVydGllcy5oIgorI2luY2x1ZGUgIi9zZWN1cmUvd2l6bGV2ZWxzLmgiCisKKworLy8gdGhlIG1hcHBpbmcgd2hlcmUgdGhlIGFjdHVhbCBwcm9wZXJ0aWVzIGFyZSBzdG9yZWQuIERpcmVjdCBpbml0aWFsaXphdGlvbi4KK3ByaXZhdGUgbm9zYXZlIG1hcHBpbmcgKnByb3AgPSAoeyAoW10pLCAoW10pLCAoW10pLCAoW10pIH0pOworCisvLyB0aGUgbWFwcGluZyB0aGF0IGlzIHVzZWQgZm9yIHNhdmluZworcHJpdmF0ZSBtYXBwaW5nIHByb3BlcnRpZXM7CisKKy8vIHNlY3VyaXR5LWZsYWcKK3ByaXZhdGUgbm9zYXZlIGludCBjbG9zdXJlX2NhbGw7CisKKy8vIEluaXRpYWxpc2llcnVuZyBkZXIgUHJvcHMuIEthbm4gbGVpZGVyIG1vbWVudGFuIG5pY2h0IHByaXZhdGUgc2Vpbiwgd2VpbAorLy8gUGFkcmVpYyBzb24ga29taXNjaGVzIE9iamVrdCBoYXQsIHdhcyBkaWUgRnVua3Rpb24gaGllciBydWZ0LgorLy8gVE9ETzogaXJnZW5kd2FubiBtYWwgcHJpdmF0ZSBtYWNoZW4uCisvLyBUT0RPOiBEYSBwcm9wcyBqZXR6dCBlaW5mYWNoIGJlaSBkZXIgRGVrbGFyYXRpb24gaW5pdGxpc2llcnQgd2lyZCwKKy8vIGVydWVicmlndCBzaWNoIGRpZXNlIEZ1bmt0aW9uIGVpZ2VudGxpY2guIEJpcyBhdWYgUGFkcmVpY3MgT2JqZWt0Li4uCitwcm90ZWN0ZWQgdm9pZCBJbml0aWFsaXplUHJvcGVydGllcygpIHsKKyAgcHJvcCA9ICh7IChbXSksIChbXSksIChbXSksIChbXSkgfSk7CisgIHJldHVybjsKK30KKworLy8gUHJvcHMgbnVyIGRhbm4gaW5pdGlhbGlzaWVyZW4sIHdlbm4gc2llIGVzIG5vY2ggbmljaHQgc2luZAorcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkgeworICAvLyBCbHVlcHJpbnRzIGluIC9zdGQgYmVub2V0aWdlbmtlaW5lbiBSZXNldCAuLi4uCisgIGlmIChvYmplY3RfbmFtZSgpPT0iL3N0ZC90aGluZy9wcm9wZXJ0aWVzIikKKyAgICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCisvLyBXZWxjaGUgZXh0ZXJuZW4gT2JqZWt0ZSBkdWVyZmVuIHp1Z3JlaWZlbj8KK25vbWFzayBwcml2YXRlIGludCBhbGxvd2VkKCkKK3sKKyAgICBpZiAoIChwcmV2aW91c19vYmplY3QoKSAmJiBJU19BUkNIKGdldHVpZChwcmV2aW91c19vYmplY3QoKSkpICYmCisgICAgICAgICAgdGhpc19pbnRlcmFjdGl2ZSgpICYmIElTX0FSQ0godGhpc19pbnRlcmFjdGl2ZSgpKSkgfHwKKyAgICAgICAgIChwcmV2aW91c19vYmplY3QoKSAmJiBnZXR1aWQocHJldmlvdXNfb2JqZWN0KCkpID09IFJPT1RJRCAmJgorICAgICAgICAgIGdldGV1aWQocHJldmlvdXNfb2JqZWN0KCkpID09IFJPT1RJRCkgKQorICAgICAgICByZXR1cm4gMTsKKyAgICByZXR1cm4gMDsKK30KKworCisvLyBTZXQoKSAtLSBwcm92aWRlcyBkaXJlY3QgYWNjZXNzIHRvIGEgcHJvcGVydHksIG5vIGZpbHRlcnMKK3B1YmxpYyB2YXJhcmdzIG1peGVkIFNldCggc3RyaW5nIG5hbWUsIG1peGVkIFZhbHVlLCBpbnQgVHlwZSwgaW50IGV4dGVybiApCit7CisKKyAgaWYgKCFvYmplY3RwKHRoaXNfb2JqZWN0KCkpKQorICAgIHJldHVybiAwOworCisgIC8vIFByb3BlcnRpZXMsIGRpZSBTRUNVUkVEIG9kZXIgUFJPVEVDVEVEIHNpbmQsIGR1ZXJmZW4gbnVyIHZvbSBPYmpla3QKKyAgLy8gc2VsYmVyLCBFTSsgb2RlciBST09UIHZlcmFlbmRlcnQgd2VyZGVuCisgIGlmICgocHJvcFtGX01PREVdW25hbWVdJihQUk9URUNURUR8U0VDVVJFRCkpJiYKKyAgICAgIChjbG9zdXJlX2NhbGx8fGV4dGVybnx8ZXh0ZXJuX2NhbGwoKSkgJiYKKyAgICAgICBwcmV2aW91c19vYmplY3QoKSAhPSB0aGlzX29iamVjdCgpICYmICFhbGxvd2VkKCkpCisgICAgcmV0dXJuIC0xOworICAKKyAgLy8gRGFzIFNFQ1VSRUQtRmxhZyBkYXJmIGJlaSBQcm9wZXJ0aWVzIG5pY2h0IG1laHIgZ2Vsb2VzY2h0IHdlcmRlbgorICBpZiAoKHByb3BbRl9NT0RFXVtuYW1lXSZTRUNVUkVEKSYmCisgICAgICAoVHlwZT09Rl9NT0RFfHxUeXBlPT1GX01PREVfQUQpJiYoVmFsdWUgJiBTRUNVUkVEKSkKKyAgICByZXR1cm4gLTI7CisgIAorICAvLyBTZXR6ZW4gZHVlcmZlbiBkYXMgU0VDVVJFRC1GbGFnIG51ciBkYXMgT2JqZWt0IHNlbGJlciwgRU0rIG9kZXIgUk9PVAorICBpZiAoKFR5cGU9PUZfTU9ERXx8VHlwZT09Rl9NT0RFX0FTKSYmKFZhbHVlJlNFQ1VSRUQpJiYKKyAgICAgIChjbG9zdXJlX2NhbGwgfHxleHRlcm4gfHwgZXh0ZXJuX2NhbGwoKSkgJiYKKyAgICAgICBwcmV2aW91c19vYmplY3QoKSAhPSB0aGlzX29iamVjdCgpICYmICFhbGxvd2VkKCkgKQorICAgIHJldHVybiAtMzsKKworICBzd2l0Y2goVHlwZSkKKyAgeworICAgIC8vIEplIG5hY2ggTW9kdXMgRmxhZ3MgdmVyYWVuZGVybgorICAgIGNhc2UgRl9NT0RFX0FTOiAgcHJvcFtGX01PREVdW25hbWVdfD0gVmFsdWU7CisgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvcFtGX01PREVdW25hbWVdOworICAgIGNhc2UgRl9NT0RFX0FEOiAgcHJvcFtGX01PREVdW25hbWVdJj0gflZhbHVlOworICAgICAgICAgICAgICAgICAgICAgaWYgKCFwcm9wW0ZfTU9ERV1bbmFtZV0pIHByb3BbRl9NT0RFXS09KFtuYW1lXSk7CisgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvcFtGX01PREVdW25hbWVdOworICAgIGNhc2UgRl9NT0RFOiAgICAgcHJvcFtGX01PREVdW25hbWVdXj0gVmFsdWU7CisgICAgICAgICAgICAgICAgICAgICBpZiAoIXByb3BbRl9NT0RFXVtuYW1lXSkgcHJvcFtGX01PREVdLT0oW25hbWVdKTsKKyAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9wW0ZfTU9ERV1bbmFtZV07CisgICAgY2FzZSBGX1NFVF9NRVRIT0Q6CisgICAgICAvLyAtMSBhbHMgU2V0ei1NZXRob2RlOiBOb3NldG1ldGhvZCBzZXR6ZW4KKyAgICAgIGlmIChWYWx1ZSA9PSAtMSkKKyAgICAgIHsKKyAgICAgICAgcHJvcFtGX1NFVF9NRVRIT0RdLT0oW25hbWVdKTsKKyAgICAgICAgcHJvcFtGX01PREVdW25hbWVdIHw9IE5PU0VUTUVUSE9EOworICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICAgIC8vIEtlaW4gYnJlYWshCisgICAgY2FzZSBGX1FVRVJZX01FVEhPRDoKKyAgICAgIC8vIFVuZ2VidW5kZW5lIExhbWJkYV9DbG9zdXJlPyBCaW5kZW4hCisgICAgICBpZiAoY2xvc3VyZXAoVmFsdWUpJiYhcXVlcnlfY2xvc3VyZV9vYmplY3QoVmFsdWUpKQorICAgICAgeworICAgICAgICBpZiAoZXh0ZXJuX2NhbGwoKSAmJgorICAgICAgICAgICAgIChnZXR1aWQocHJldmlvdXNfb2JqZWN0KCkpICE9IGdldHVpZCgpfHwKKyAgICAgICAgICAgICAgZ2V0ZXVpZChwcmV2aW91c19vYmplY3QoKSkgIT0gZ2V0ZXVpZCgpKSkKKyAgICAgICAgICByZXR1cm4gcHJvcFtUeXBlXVtuYW1lXTsKKyAgICAgICAgCisgICAgICAgIFZhbHVlID0gYmluZF9sYW1iZGEoIFZhbHVlLHRoaXNfb2JqZWN0KCkpOworICAgICAgfQorICAgICAgLy8gS2VpbiBicmVhayEKKyAgICBkZWZhdWx0OgorICAgICAgaWYgKCFWYWx1ZSkgcHJvcFtUeXBlXS09KFtuYW1lXSk7CisgICAgICBlbHNlIHByb3BbVHlwZV1bbmFtZV0gPSBWYWx1ZTsKKyAgfQorCisgIC8vIEdlc2FtdHdlcnQgenVydWVja2dlYmVuCisgIHJldHVybiBwcm9wW1R5cGVdW25hbWVdOworfQorCisKKy8vIERpcmVrdGVzIEF1c2xlc2VuIGRlciBQcm9wZXJ0eSBvaG5lIEZpbHRlciAuLi4KK3B1YmxpYyB2YXJhcmdzIG1peGVkIFF1ZXJ5KCBzdHJpbmcgbmFtZSwgaW50IFR5cGUgKQoreworICAgIGlmIChwb2ludGVycChwcm9wKSkgcmV0dXJuIHByb3BbVHlwZV1bbmFtZV07CisgICAgcmV0dXJuIDA7Cit9CisKKy8vIFByb3BlcnR5IHNldHplbiB1bnRlciBWZXJ3ZW5kdW5nIGV2dGwuIHZvcmhhbmRlbmVyIFp1Z3JpZmZzZnVua3Rpb25lbgorcHVibGljIG1peGVkIFNldFByb3AoIHN0cmluZyBuYW1lLCBtaXhlZCBWYWx1ZSApCit7CisgIGNsb3N1cmUgZnVuYzsKKyAgbWl4ZWQgcmVzdWx0OworICAgCisgIC8vIG51ciBmdWVyIGhldXRlCisgIGlmICghb2JqZWN0cCh0aGlzX29iamVjdCgpKSkKKyAgICByZXR1cm4gMDsKKworICAvLyBOT1NFVE1FVEhPRDogRGFyZiBuaWNodCBnZXNldHp0IHdlcmRlbgorICBpZiAocHJvcFtGX01PREVdW25hbWVdICYgTk9TRVRNRVRIT0QgKSByZXR1cm4gLTE7CisKKyAgLy8gU2V0LU1ldGhvZCBhYmZyYWdlbiwgc28gdm9yaGFuZGVuCisgIGlmIChmdW5jPXByb3BbRl9TRVRfTUVUSE9EXVtuYW1lXSkKKyAgeworICAgIGludCBmbGFnOworCisgICAgLy8gV2VydCBhbHMgU2V0LU1ldGhvZD8gZ2xlaWNoIHp1cnVlY2tnZWJlbgorICAgIGlmICghY2xvc3VyZXAoZnVuYykpIHJldHVybiBmdW5jOworCisgICAgLy8gQW4gZGllc2VyIFN0ZWxsZSBtdXNzIGZ1bmMgZWluZSBDbG9zdXJlIHNlaW4uIERhIFNldCgpIHVuZ2VidW5kZW5lCisgICAgLy8gTGFtYmRhcyBiaW5kZXQsIGthbm4gZXMgYXVjaCBudXIgZWluZSBnZWJ1bmRlbmUgQ2xvc3VyZSBzZWluIHVuZCBkYXMKKyAgICAvLyBPYmpla3QgZXhpc3RpZXJ0IGF1Y2ggbm9jaCAoc29uc3Qgd2FlcmUgZnVuYyA9PSAwKS4KKworICAgIC8vIGNsb3N1cmVfY2FsbCBzZXR6ZW4sIGZhbGxzIG5vY2ggbmljaHQgZ2VzZXR6dAorICAgIGlmICgoZmxhZz1jbG9zdXJlX2NhbGw8dGltZSgpKSkKKyAgICAgIGNsb3N1cmVfY2FsbCA9IHRpbWUoKSs1OTsKKworICAgIC8vIERhbm4gbWFsIGRpZSBDbG9zdXJlIGF1ZnJ1ZmVuLiBCZWkgRmVobGVyIHNlbGJpZ2UgbG9lc2NoZW4KKyAgICBpZiAoY2F0Y2gocmVzdWx0PWZ1bmNhbGwoZnVuYywgVmFsdWUsIG5hbWUpO3B1Ymxpc2gpKQorICAgIHsKKyAgICAgIHByb3BbRl9TRVRfTUVUSE9EXS09KFtuYW1lXSk7CisgICAgfQorICAgICAgCisgICAgLy8gV2VubiBjbG9zdXJlX2NhbGwgZ2VzZXR6dCB3dXJkZSwgd2llZGVyIGxvZXNjaGVuCisgICAgaWYgKGZsYWcpIGNsb3N1cmVfY2FsbCA9IDA7CisKKyAgICAvLyBVbmQgenVydWVja2dlYmVuCisgICAgcmV0dXJuIHJlc3VsdDsgCisgIH0KKworICAvLyBfc2V0XyotTWV0aG9kZSB2b3JoYW5kZW4/IGZhbGxzIGphLCBhdWZydWZlbi5pCisgIC8vIFRPRE86IENsb3N1cmVjYWNoZSBlaW5mdWVocmVuIHVuZCBGdW5rdGlvbmF1ZnJ1ZiBudXIgbm9jaCBtYWNoZW4sIHdlbm4gZXMKKyAgLy8gZGllIF9zZXRfKiBhdWNoIGdpYnQ/CisgIGlmIChjYWxsX3Jlc29sdmVkKCZyZXN1bHQsdGhpc19vYmplY3QoKSwiX3NldF8iK25hbWUsVmFsdWUgKSkKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKworICAvLyBMZXR6dGUgTW9lZ2xpY2hrZWl0OiBNdXNzIGVpbmUgJ25vcm1hbGUnIFByb3BlcnR5IHNlaW4KKyAgcmV0dXJuIFNldCggbmFtZSwgVmFsdWUsIEZfVkFMVUUsIGV4dGVybl9jYWxsKCkgKTsKK30KKworCisvLyBQcm9wZXJ0eSBhdXNsZXNlbiB1bnRlciBWZXJ3ZW5kdW5nIGV2dGwuIHZvcmhhbmRlbmVyIFp1Z3JpZmZzZnVua3Rpb25lbgorcHVibGljIG1peGVkIFF1ZXJ5UHJvcCggc3RyaW5nIG5hbWUgKQoreworICBjbG9zdXJlIGZ1bmM7CisgIG1peGVkIHJlc3VsdDsKKyAKKyAgLy8gbnVyIGZ1ZXIgaGV1dGUKKyAgaWYgKCFvYmplY3RwKHRoaXNfb2JqZWN0KCkpKQorICAgIHJldHVybjsKKworICAvLyBRdWVyeS1NZXRob2RlIHZvcmhhbmRlbj8KKyAgaWYgKCBmdW5jID0gcHJvcFtGX1FVRVJZX01FVEhPRF1bbmFtZV0gKQorICB7CisgICAgaW50IGZsYWc7CisKKyAgICAvLyBXZXJ0IGFscyBRdWVyeS1NZXRob2Q/IEdsZWljaCB6dXJ1ZWNrZ2ViZW4gLi4uCisgICAgaWYgKCFjbG9zdXJlcChmdW5jKSkgcmV0dXJuIGZ1bmM7CisgCisgICAgLy8gQW4gZGllc2VyIFN0ZWxsZSBtdXNzIGZ1bmMgZWluZSBDbG9zdXJlIHNlaW4uIERhIFNldCgpIHVuZ2VidW5kZW5lCisgICAgLy8gTGFtYmRhcyBiaW5kZXQsIGthbm4gZXMgYXVjaCBudXIgZWluZSBnZWJ1bmRlbmUgQ2xvc3VyZSBzZWluIHVuZCBkYXMKKyAgICAvLyBPYmpla3QgZXhpc3RpZXJ0IGF1Y2ggbm9jaCAoc29uc3Qgd2FlcmUgZnVuYyA9PSAwKS4KKyAgIAorICAgIC8vIGNsb3N1cmVfY2FsbCBzZXR6ZW4sIGZhbGxzIG5vY2ggbmljaHQgZ2VzZXR6dAorICAgIGlmICgoZmxhZz1jbG9zdXJlX2NhbGw8dGltZSgpKSkKKyAgICAgIGNsb3N1cmVfY2FsbCA9IHRpbWUoKSs1OTsKKyAgICAKKyAgICAvLyBEYW5uIE1hbCBkaWUgQ2xvc3VyZSBhdWZydWZlbi4gQmVpIEZlaGxlciBzZWxiaWdlIGxvZXNjaGVuCisgICAgaWYgKGNhdGNoKHJlc3VsdD1mdW5jYWxsKGZ1bmMpO3B1Ymxpc2gpKQorICAgIHsKKyAgICAgIHByb3BbRl9RVUVSWV9NRVRIT0RdLT0oW25hbWVdKTsKKyAgICB9CisgICAgLy8gV2VubiBjbG9zdXJlX2NhbGwgZ2VzZXR6dCB3dXJkZSwgd2llZGVyIGxvZXNjaGVuICAgIAorICAgIGlmIChmbGFnKSBjbG9zdXJlX2NhbGwgPSAwOworICAgIAorICAgIC8vIFVuZCB6dXJ1ZWNrZ2ViZW4KKyAgICByZXR1cm4gcmVzdWx0OworICB9CisgIAorICAvLyBfcXVlcnlfKi1NZXRob2RlIHZvcmhhbmRlbj8gZmFsbHMgamEsIGF1ZnJ1ZmVuLgorICAvLyBUT0RPOiBDbG9zdXJlY2FjaGUgdW5kIG51ciBydWZlbiwgd2VubiBlcyBfcXVlcnlfKiBhdWNoIGdpYnQ/CisgIGlmIChjYWxsX3Jlc29sdmVkKCZyZXN1bHQsdGhpc19vYmplY3QoKSwiX3F1ZXJ5XyIrbmFtZSkpCisgICAgcmV0dXJuIHJlc3VsdDsKKyAgCisgIC8vIEhpbGZ0IGFsbGVzIG5pY2h0cy4gRXMgaXN0IGVpbmUgJ25vcm1hbGUnIFByb3BlcnR5IC4uLgorICByZXR1cm4gcHJvcFtGX1ZBTFVFXVtuYW1lXTsKK30KKworCisvLyBEYXMgZ2VzYW10ZSBQcm9wZXJ0eS1NYXBwaW5nIGF1ZiBlaW5lbiBTY2hsYWcgc2V0emVuCitwdWJsaWMgdm9pZCBTZXRQcm9wZXJ0aWVzKCBtYXBwaW5nIHByb3BzICkKK3sKKyAgc3RyaW5nICpuYW1lczsKKyAgaW50IGksIGosIHNhbWVfb2JqZWN0OworIAorICAvLyBLZWluIE1hcHBpbmc/IFNjaGxlY2h0IC4uLgorICBpZighbWFwcGluZ3AocHJvcHMpKSByZXR1cm47CisKKyAgLy8gU2V0emVuIHdpciBzZWxiZXI/CisgIHNhbWVfb2JqZWN0ID0gKCFjbG9zdXJlX2NhbGwgJiYKKyAgICAgICAgICAgICAgICAgKCFleHRlcm5fY2FsbCgpfHxwcmV2aW91c19vYmplY3QoKT09dGhpc19vYmplY3QoKXx8CisgICAgICAgICAgICAgICAgICBhbGxvd2VkKCkpKTsKKyAgbmFtZXMgPSBtX2luZGljZXMocHJvcHMpOworICAKKyAgLy8gRGFzIFNFQ1VSRUQtRmxhZyBkYXJmIG51ciBkdXJjaCBkYXMgT2JqZWt0IHNlbGJlciBnZXNldHp0IHdlcmRlbjoKKyAgLy8gQWxsZSBTRUNVUkVELUZsYWdzIGF1cyBwcm9wcyBsb2VzY2hlbgorICBpZiAoIXNhbWVfb2JqZWN0KQorICB7CisgICAgaj1zaXplb2YobmFtZXMpOworICAgIHdoaWxlKGotLSkgcHJvcHNbbmFtZXNbal0sIEZfTU9ERV0gJj0gflNFQ1VSRUQ7CisgIH0KKworICBqPXNpemVvZihuYW1lcyk7CisgIHdoaWxlKGotLSkKKyAgeworICAgIC8vIFByb3BlcnRpZXMsIGRpZSBzY2hvbiBTRUNVUkVEIG9kZXIgUFJPVEVDVEVEIHNpbmQsIGR1ZXJmZW4KKyAgICAvLyBudXIgdm9tIE9iamVrdCBzZWxiZXIgbWFuaXB1bGllcnQgd2VyZGVuCisgICAgaWYgKHNhbWVfb2JqZWN0fHwhKHByb3BbRl9NT0RFXVtuYW1lc1tqXV0gJiAoUFJPVEVDVEVEfFNFQ1VSRUQpKSApCisgICAgeworICAgICAgaT00OworICAgICAgd2hpbGUoaS0tKQorICAgICAgeworICAgICAgICBpZihwcm9wc1tuYW1lc1tqXSxpXSkKKyAgICAgICAgICBwcm9wW2ldW25hbWVzW2pdXSA9IHByb3BzW25hbWVzW2pdLCBpXTsKKyAgICAgICAgZWxzZQorICAgICAgICAgIHByb3BbaV0tPShbbmFtZXNbal1dKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuOworfQorCisKKy8vIEVpbiBNYXBwaW5nIG1pdCBhbGxlbiBQcm9wZXJ0aWVzIHp1cnVlY2tnZWJlbgorcHVibGljIG1hcHBpbmcgUXVlcnlQcm9wZXJ0aWVzKCkKK3sKKyAgbWFwcGluZyBwcm9wczsKKyAgaW50IGksIGo7CisgIHN0cmluZyAqbmFtZXM7CisKKyAgcHJvcHMgPSBtX2FsbG9jYXRlKCAwLCA0ICk7CisgIAorICBpZiAocG9pbnRlcnAocHJvcCkpCisgIHsKKyAgICBpPTQ7CisgICAgd2hpbGUoaS0tKQorICAgIHsKKyAgICAgIG5hbWVzID0gbV9pbmRpY2VzKHByb3BbaV0pOworICAgICAgaj1zaXplb2YobmFtZXMpOworICAgICAgd2hpbGUoai0tKSBwcm9wc1tuYW1lc1tqXSwgaV0gPSBwcm9wW2ldW25hbWVzW2pdXTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHByb3BzOworfQorCisvLyBEaWUgUHJvcGVydGllcyBhbHMgdXJzcHJ1ZW5nbGljaGVzIEFycmF5IHp1cnVlY2tnZWJlbgorcHVibGljIG1peGVkICpfX3F1ZXJ5X3Byb3BlcnRpZXMoKQoreworICBpZiAoIHBvaW50ZXJwKHByb3ApICkKKyAgICByZXR1cm4oZGVlcF9jb3B5KHByb3ApKTsKKyAgZWxzZQorICAgIHJldHVybiAoeyAoW10pLChbXSksKFtdKSwoW10pIH0pOworfQorCisKKy8vIG1hcHBpbmcgUHJvcGVydGllcyBzZXR6ZW4genVtIFNwZWljaGVybiAocGVyIHNhdmVfb2JqZWN0KCkpCisvLyBBdWZydWYgbnVyIGF1cyBzaW11bF9lZnVuIGhlcmF1cworcHVibGljIHZvaWQgIF9zZXRfc2F2ZV9kYXRhKG1peGVkIGRhdGEpIHsgcHJvcGVydGllcyA9IGRhdGE7IH0KKworLy8gbWFwcGluZyBQcm9wZXJ0aWVzIHp1bSBSZXN0b3JlbiB6dXJ1ZWNrZ2ViZW4KK3B1YmxpYyBtaXhlZCBfZ2V0X3NhdmVfZGF0YSgpICAgICAgICAgICB7IHJldHVybiBwcm9wZXJ0aWVzOyB9CisKZGlmZiAtLWdpdCBhL3N0ZC90aGluZy9yZXN0cmljdGlvbnMuYyBiL3N0ZC90aGluZy9yZXN0cmljdGlvbnMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lOGQwZjgzCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3RoaW5nL3Jlc3RyaWN0aW9ucy5jCkBAIC0wLDAgKzEsMTQyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdGhpbmcvcmVzdHJpY3Rpb25zLmMgLS0gR2V3aWNodCB1LmFlLiBlaW5lcyBPYmpla3RzCisvLworLy8gJElkOiByZXN0cmljdGlvbnMuYyA2ODA5IDIwMDgtMDMtMjkgMjE6NTQ6MDRaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUyAKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisKKy8vIEdld2ljaHQgaXN0IDFrZywgd2VubiBuaWNodCBhbmRlcnMgYmVzdGltbXQKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIAoreyAgCisgIFNldFByb3AoUF9XRUlHSFQsIDEwMDApOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30gICAgIAorCisvLyBQX1RPVEFMX1dFSUdIVCBiZWkgTmljaHQtQ29udGFpbmVybiBhdWYgUF9XRUlHSFQgdW1sZWl0ZW4KK3N0YXRpYyBpbnQgX3NldF93ZWlnaHQoaW50IHdlaWdodCkgeworICByZXR1cm4gU2V0UHJvcChQX1RPVEFMX1dFSUdIVCwKKwkgIFNldChQX1dFSUdIVCwgd2VpZ2h0LCBGX1ZBTFVFKSApOworfQorCisvLyBQX1hfQVRUUl9NT0QgYWVuZGVybiAoQXR0cmlidXRhZW5kZXJ1bmdlbiBkdXJjaCBBdXNydWVzdHVuZykKK3N0YXRpYyBtYXBwaW5nIF9zZXRfZXh0ZXJuX2F0dHJpYnV0ZXNfbW9kaWZpZXIobWFwcGluZyB4bW9kKSAKK3sKKyAgbWFwcGluZyByZXM7CisKKyAgLy8gd2VubiBNdWVsbCBvZGVyIGVpbiBsZWVyZXMgTWFwcGluZyB1ZWJlcmdlYmVuIHd1cmRlLCB3aXJkIGRpZSBwcm9wCisgIC8vIGdlbG9lc2NodCB1bmQgZ2dmLiBkYXMgT2JqZWt0IGltIExpdmluZyBhYmdlbWVsZGV0LgorICBpZiAoIW1hcHBpbmdwKHhtb2QpKSB4bW9kPShbXSk7CisgIAorICBpZiAoIXNpemVvZih4bW9kKSkgeworIAorICAgIHJlcz1TZXQoUF9YX0FUVFJfTU9ELCB4bW9kKTsKKyAgCisgICAgLy8gd2VubiBQcm9wIGdlbG9lc2NodCB3aXJkLCBrYW5uIG1hbiBkYXMgSXRlbSBhdWNoIGF1cyBkZXIgTGlzdGUgZGVyCisgICAgLy8gU3RhdG1vZGlmaXppZXJlciBkZXMgTGViZXdlc2VucyBhdXN0cmFnZW4uCisgICAgaWYgKGxpdmluZyhlbnZpcm9ubWVudCgpKSkgeyAgCisgICAgICBlbnZpcm9ubWVudCgpLT5kZXJlZ2lzdGVyX21vZGlmaWVyKE1FKTsKKyAgICAgIGVudmlyb25tZW50KCktPlVwZGF0ZUF0dHJpYnV0ZXMoKTsKKyAgICB9CisgIH0KKyAgZWxzZSB7CisgICAgLy8gb2ssIFByb3Agd2lyZCBhdWYgbmVuIGludGVyZXNzYW50ZW4gV2VydCBnZXNldHp0LiA7LSkKKworICAgIC8vIERhbWl0IEluc2VydC9SZW1vdmVTZW5zaXRpdmVPYmplY3QgYmVpbSBNb3ZlIGF1ZmdlcnVmZW4gd2lyZCwKKyAgICAvLyBtdXNzIFBfU0VOU0lUSVZFIGdlc2V0enQgc2VpbgorICAgIGlmICghUXVlcnlQcm9wKFBfU0VOU0lUSVZFKSkgU2V0UHJvcChQX1NFTlNJVElWRSwoe30pKTsKKyAgCisgICAgaWYgKGxpdmluZyhlbnZpcm9ubWVudCgpKSAmJiAKKyAgICAgICAgKCFtYXBwaW5ncChyZXM9UXVlcnlQcm9wKFBfWF9BVFRSX01PRCkpIHx8ICFzaXplb2YocmVzKSkpIHsKKyAgICAgIC8vIFdlbm4gZGllc2VzIE9iamVrdCBpbiBlaW5lbSBMaXZpbmcgaXN0IHVuZCBiaXNoZXIgZGllIHByb3AgbmljaHQKKyAgICAgIC8vIGdlc2V0enQgd2FyLCBtdXNzIHNpY2ggZGFzIE9iamVrdCBub2NoIGltIExpdmluZyBhbHMgU3RhdG1vZGlmaXppZXJlcgorICAgICAgLy8gcmVnaXN0cmllcmVuLgorICAgICAgcmVzPVNldChQX1hfQVRUUl9NT0QsIHhtb2QpOworICAgICAgZW52aXJvbm1lbnQoKS0+cmVnaXN0ZXJfbW9kaWZpZXIoTUUpOworICAgICAgZW52aXJvbm1lbnQoKS0+VXBkYXRlQXR0cmlidXRlcyhNRSk7CisgICAgfQorICAgIGVsc2UgaWYgKGxpdmluZyhlbnZpcm9ubWVudCgpKSl7CisgICAgICAvLyBzb25zdCByZWljaHQgZWluIGVpbmZhY2hlcyBVcGRhdGVBdHRyaWJ1dGVzKCkgdW0gZGFzIExlYmV3ZXNlbiB6dQorICAgICAgLy8gaW5mb3JtaWVyZW4uCisgICAgICByZXM9U2V0KFBfWF9BVFRSX01PRCwgeG1vZCk7CisgICAgICBlbnZpcm9ubWVudCgpLT5VcGRhdGVBdHRyaWJ1dGVzKCk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgLy8gd2VubiBrZWluIGxlYmVuZGVzIEVudiwgcmVpY2h0IGVpbmZhY2hlcyBTZXR6ZW4uCisgICAgICByZXM9U2V0KFBfWF9BVFRSX01PRCx4bW9kKTsKKyAgICB9CisgIH0KKworICByZXR1cm4gcmVzOworfQorCisvLyBQX1hfSEVBTFRIX01PRCBhZW5kZXJuIChMUC9LUC1BZW5kZXJ1bmcgZHVyY2ggQXVzcnVlc3R1bmcpCitzdGF0aWMgbWFwcGluZyBfc2V0X2V4dGVybl9oZWFsdGhfbW9kaWZpZXIobWFwcGluZyB4bW9kKSB7CisgIG1hcHBpbmcgcmVzOworCisgIC8vIHdlbm4gTXVlbGwgb2RlciBlaW4gbGVlcmVzIE1hcHBpbmcgdWViZXJnZWJlbiB3dXJkZSwgd2lyZCBkaWUgcHJvcAorICAvLyBnZWxvZXNjaHQgdW5kIGdnZi4gZGFzIE9iamVrdCBpbSBMaXZpbmcgYWJnZW1lbGRldC4KKyAgaWYgKCFtYXBwaW5ncCh4bW9kKSkgeG1vZD0oW10pOworICAKKyAgaWYgKCFzaXplb2YoeG1vZCkpIHsKKyAKKyAgICByZXM9U2V0KFBfWF9IRUFMVEhfTU9ELCB4bW9kKTsKKyAgCisgICAgLy8gd2VubiBQcm9wIGdlbG9lc2NodCB3aXJkLCBrYW5uIG1hbiBkYXMgSXRlbSBhdWNoIGF1cyBkZXIgTGlzdGUgZGVyCisgICAgLy8gU3RhdG1vZGlmaXppZXJlciBkZXMgTGViZXdlc2VucyBhdXN0cmFnZW4uCisgICAgaWYgKGxpdmluZyhlbnZpcm9ubWVudCgpKSkgeyAgCisgICAgICBlbnZpcm9ubWVudCgpLT5kZXJlZ2lzdGVyX21vZGlmaWVyKE1FKTsKKyAgICAgIGVudmlyb25tZW50KCktPlVwZGF0ZUF0dHJpYnV0ZXMoKTsKKyAgICB9CisgIH0KKyAgZWxzZSB7CisgICAgLy8gb2ssIFByb3Agd2lyZCBhdWYgbmVuIGludGVyZXNzYW50ZW4gV2VydCBnZXNldHp0LiA7LSkKKworICAgIC8vIERhbWl0IEluc2VydC9SZW1vdmVTZW5zaXRpdmVPYmplY3QgYmVpbSBNb3ZlIGF1ZmdlcnVmZW4gd2lyZCwKKyAgICAvLyBtdXNzIFBfU0VOU0lUSVZFIGdlc2V0enQgc2VpbgorICAgIGlmICghUXVlcnlQcm9wKFBfU0VOU0lUSVZFKSkgU2V0UHJvcChQX1NFTlNJVElWRSwoe30pKTsKKyAgCisgICAgaWYgKGxpdmluZyhlbnZpcm9ubWVudCgpKSAmJiAKKyAgICAgICAgKCFtYXBwaW5ncChyZXM9UXVlcnlQcm9wKFBfWF9IRUFMVEhfTU9EKSkgfHwgIXNpemVvZihyZXMpKSkgeworICAgICAgLy8gV2VubiBkaWVzZXMgT2JqZWt0IGluIGVpbmVtIExpdmluZyBpc3QgdW5kIGJpc2hlciBkaWUgcHJvcCBuaWNodAorICAgICAgLy8gZ2VzZXR6dCB3YXIsIG11c3Mgc2ljaCBkYXMgT2JqZWt0IG5vY2ggaW0gTGl2aW5nIGFscyBTdGF0bW9kaWZpemllcmVyCisgICAgICAvLyByZWdpc3RyaWVyZW4uCisgICAgICByZXM9U2V0KFBfWF9IRUFMVEhfTU9ELCB4bW9kKTsKKyAgICAgIGVudmlyb25tZW50KCktPnJlZ2lzdGVyX21vZGlmaWVyKE1FKTsKKyAgICAgIGVudmlyb25tZW50KCktPlVwZGF0ZUF0dHJpYnV0ZXMoTUUpOworICAgIH0KKyAgICBlbHNlIGlmIChsaXZpbmcoZW52aXJvbm1lbnQoKSkpeworICAgICAgLy8gc29uc3QgcmVpY2h0IGVpbiBlaW5mYWNoZXMgVXBkYXRlQXR0cmlidXRlcygpIHVtIGRhcyBMZWJld2VzZW4genUKKyAgICAgIC8vIGluZm9ybWllcmVuLgorICAgICAgcmVzPVNldChQX1hfSEVBTFRIX01PRCwgeG1vZCk7CisgICAgICBlbnZpcm9ubWVudCgpLT5VcGRhdGVBdHRyaWJ1dGVzKCk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgLy8gd2VubiBrZWluIGxlYmVuZGVzIEVudiwgcmVpY2h0IGVpbmZhY2hlcyBTZXR6ZW4uCisgICAgICByZXM9U2V0KFBfWF9IRUFMVEhfTU9ELHhtb2QpOworICAgIH0KKyAgfQorCisgIHJldHVybiByZXM7CisKK30KKworLy8gUF9YL01fQVRUUl9NT0Qgd2VyZGVuIG5pY2h0IGJlcnVlY2tzaWNodGlndCwgZGEgQ1VNVUxBVElWRV9BVFRSX0xJTUlUCisvLyB1ZWJlcnNjaHJpdHRlbiBpc3QKK3ZvaWQgTm90aWZ5WE1BdHRyTW9kTGltaXRWaW9sYXRpb24oKQoreworfQorICAKZGlmZiAtLWdpdCBhL3N0ZC90aGluZy9zb2NrZXRzLmMgYi9zdGQvdGhpbmcvc29ja2V0cy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY0ZDk4OTkKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdGhpbmcvc29ja2V0cy5jCkBAIC0wLDAgKzEsMjU0IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvKiogQGZpbGUKKyogSW1wbGVtZW50YXRpb24gZnVlciBTb2NrZWxpdGVtcy4KKyogTGFuZ2Jlc2NocmVpYnVuZy4uLiBUT0RPCisqIEBhdXRob3IgWmVzc3RyYSArIEFyYXRob3JuCisqIEBkYXRlIHh4LjA1LjIwMDgKKyogQHZlcnNpb24gJElkJAorKi8KKworLyogQ2hhbmdlbG9nOgorKi8KKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgbm9fc2hhZG93CisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvc29ja2V0cy5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxscGN0eXBlcy5oPgorCisjaWZuZGVmIERFQlVHCisvKiogT3V0cHV0cyBkZWJ1ZyBtZXNzYWdlIHRvIE1haW50YWluZXIsIGlmIE1haW50YWluZXIgaXMgbG9nZ2VkIGluLiAKKyovCisjZGVmaW5lIERFQlVHKHgpIF9fZGVidWdfbXNnX18oeCkKKyNlbmRpZgorCisKK3ByaXZhdGUgdm9pZCBfX2RlYnVnX21zZ19fKHN0cmluZyB4KSB7CisgIGlmIChmaW5kX3BsYXllcigiemVzc3RyYSIpKQorICAgICAgdGVsbF9vYmplY3QoZmluZF9wbGF5ZXIoInplc3N0cmEiKSwiU0RCRzogIit4KyJcbiIpOworfQorCisvKiogU2V0enQgXGEgaXRlbSBpbiBlaW5lbiBwYXNzZW5kZW4gU29ja2VsIGVpbi4KKyAgV2lyZCB2b20gSGFuZHdlcmtlciBnZXJ1ZmVuLiBTb2Zlcm4gZGllIFBydWVmdW5nIG1pdHRlbHMgVGVzdFNvY2tldEl0ZW0oKQorICBlcmZvbGdyZWljaCBpc3QsIHdlcmRlbiBkaWUgUHJvcHMgZGllc2VzIE9iamVrdCBkdXJjaCBkaWUgaW0gSXRlbQorICBnZXNwZWljaGVydGVuIGluIFBfU09DS0VUX1BST1BTIGVyZ2Flbnp0LCBnZ2YuIFBfUkVTVFJJQ1RJT04gZ2VhZW5kZXJ0IHVuZAorICBOYW1lIGRlciBCbHVlcHJpbnQsIE5hbWUgdW5kIFBfU09DS0VUX1BST1BTIGluIFBfU09DS0VUUyBnZXNwZWljaGVydCwgdW0KKyAgc3BhZXRlciBuYWNodm9sbHppZWhlbiB6dSBrb2VubmVuLCB3aWUgZGllc2VzIE9iamVrdCBiZXJlaXRzIG1vZGlmaXppZXJ0CisgIHd1cmRlLgorICBAYXR0ZW50aW9uIEFtIEVuZGUgZGVyIEZ1bmt0aW9uIHdpcmQgXGEgaXRlbSB6ZXJzdG9lcnQgdW5kIGRhcmYgbmljaHQgbWVocgorICBiZW51dHp0IHdlcmRlbiEKKyAgQHBhcmFtW2luXSBpdGVtIE9iamVrdCwgd2VsY2hlcyBpbiBlaW5lbiBwYXNzZW5kZW4gU29ja2V0IGVpbmdlc2V0enQgd2VyZGVuCisgIHNvbGwuCisgIEByZXR1cm4gMSwgZmFsbHMgRWluc2V0emVuIGVyZm9sZ3JlaWNoLCA8MCB3ZW5uIG5pY2h0LgorICBAc2EgVGVzdFNvY2tldEl0ZW0ob2JqZWN0KQorICovCitwdWJsaWMgaW50IE1vdW50U29ja2V0SXRlbShvYmplY3QgaXRlbSkgeworICBpZiAoIW9iamVjdHAoaXRlbSkpIHJldHVybiBTT0NLRVRfTk9fT0JKRUNUOworICBpZiAoKGludCByZXM9VGVzdFNvY2tldEl0ZW0oaXRlbSkpICE9IFNPQ0tFVF9PSykKKyAgICByZXR1cm4gcmVzOworICBtYXBwaW5nIGlkYXRhPShtYXBwaW5nKWl0ZW0tPlF1ZXJ5UHJvcChQX1NPQ0tFVF9QUk9QUyk7CisgIC8vIFRPRE86IFNwZXppYWxiZWhhbmRsdW5nIGZ1ZXIgUHJvcHMsIGJlaSBkZW5lbiBkYXMgT2JqZWt0IGVyaGFsdGVuIGJsZWliZW4KKyAgLy8gbXVzcy4gKHouQi4gUF9ERUZFTkRfRlVOQykuCisKKyAgLy8genUgbW9kaWZpemllcmVuZGUgUHJvcHMgYWRkaWVyZW4KKyAgZm9yZWFjaChzdHJpbmcgcHJvcG5hbWUsIG1peGVkIHB2YWw6IGlkYXRhKSB7CisgICAgU2V0UHJvcChwcm9wbmFtZSwgQWRkVG9FbnRpdHkoUXVlcnlQcm9wKHByb3BuYW1lKSwgcHZhbCkgKTsKKyAgfQorICAvLyBSZXN0cmljdGlvbnMgaGluenVmdWVnZW4uCisgIFNldFByb3AoUF9SRVNUUklDVElPTlMsIAorICAgICAgQWRkVG9FbnRpdHkoUXVlcnlQcm9wKFBfUkVTVFJJQ1RJT05TKSwgCisJaXRlbS0+UXVlcnlQcm9wKFBfU09DS0VUX1JFU1RSX1VTRSkpICk7CisKKyAgLy8gRGF0ZW4gdWViZXIgZGllc2VzIFNvY2tldGl0ZW0gYWJzcGVpY2hlcm4uCisgIG1peGVkIHNvY2tldHM9UXVlcnlQcm9wKFBfU09DS0VUUylbaXRlbS0+UXVlcnlQcm9wKFBfU09DS0VUX1RZUEUpXTsKKyAgLy8gZnJlaWVyIFNvY2tlbCBtdXNzIGV4aXN0aWVyZW4gKC0+VGVzdFNvY2tldEl0ZW0oKSkKKyAgaW50IGluZGV4PW1lbWJlcihzb2NrZXRzLCBTT0NLRVRfRlJFRSk7CisgIHNvY2tldHNbaW5kZXhdID0gaWRhdGEgKyAoWyJCTFVFX05BTUUiOiBsb2FkX25hbWUoaXRlbSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiREVTQ1JJUFRJT04iOiBpdGVtLT5uYW1lKFdFUikgXSk7CisKKyAgLy8gZ2dmLiBCZXNjaHJlaWJ1bmcgYWt0dWFsaXNpZXJlbj8KKyAgLy8gZ2dmLiBTb25kZXJiZWhhbmRsdW5nIGZ1ZXIgUHJvcHMsIGJlaSBkZW5lbiBkYXMgT2JqZWt0IG5vY2ggZ2VicmF1Y2h0CisgIC8vIHdpcmQgKHouQi4gUF9ERUZFTkRfSU5GTykKKworICAvLyBQcm9wIHNjaHVldHplbiwgc29iYWxkIERhdGVuIGRyaW4gc3RlaGVuLgorICBTZXQoUF9TT0NLRVRTLCBQUk9URUNURUR8Tk9TRVRNRVRIT0QsIEZfTU9ERV9BUyk7CisKKyAgLy8gaXRlbSBlbnRzb3JnZW4KKyAgaWYgKCFpdGVtLT5yZW1vdmUoMSkpCisgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiTW91bnRTb2NrZXRJdGVtKCkgaW4gJU86ICVPIGhhdCBBdXNmdWVocnVuZyB2b24gIgorCSAgInJlbW92ZSgpIHZlcndlaWdlcnQuXG4iLCBNRSwgaXRlbSkpOworICByZXR1cm4gU09DS0VUX09LOworfQorCisvKiogUHJ1ZWZ0LCBvYiBcYSBpdGVtIGluIGVpbmVuIFNvY2tlbCBlaW5nZXNldHp0IHdlcmRlbiBrYW5uLgorICBQcnVlZnQsIG9iIGVzIGZ1ZXIgZGFzIEl0ZW0gZWluZW4gcGFzc2VuZGVuIFNvY2tlbCBnaWJ0IHVuZCBvYiAKKyAgZXMgZGllIGZvcm1hbGVuIEFuZm9yZGVydW5nZW4gZXJmdWVsbHQsIGRvcnQgZWluZ2VzZXR6dCB6dSB3ZXJkZW4uIAorICBLYW5uIHZvbSBIYW5kd2Vya2VyIHZvciBkZW0gZWNodGVuIEVpbnNldHplbiBnZXJ1ZmVuIHdlcmRlbi4KKyAgV2lyZCBhdWNoIHZvbiBNb3VudFNvY2tldEl0ZW0ob2JqZWN0KSBnZXJ1ZmVuLgorICBAcGFyYW1baW5dIGl0ZW0gT2JqZWt0LCB3ZWxjaGVzIGF1ZiBFaWdudW5nIHp1bSBFaW5zZXR6ZW4gaW4gZWluZW4gU29ja2VsCisgIGdldGVzdGV0IHdlcmRlbiBzb2xsLgorICBAcmV0dXJuIDEsIGZhbGxzIGVpbiBwYXNzZW5kZXIgdW5kIGZyZWllciBTb2NrZWwgZXhpc3RpZXJ0LCAwIHNvbnN0LgorICBAc2EgTW91bnRTb2NrZXQob2JqZWN0KQorKi8KK3B1YmxpYyBpbnQgVGVzdFNvY2tldEl0ZW0ob2JqZWN0IGl0ZW0pIHsKKworICBpZiAoIW9iamVjdHAoaXRlbSkpIHJldHVybiBTT0NLRVRfTk9fT0JKRUNUOworICAKKyAgLy8gaXN0IGVzIGVpbiBTb2NrZWxpdGVtIHVuZCBoYXQgZXMgZWluZW4gZ3VlbHRpZ2VuIFR5cD8KKyAgbWFwcGluZyBpZGF0YSA9IChtYXBwaW5nKWl0ZW0tPlF1ZXJ5UHJvcChQX1NPQ0tFVF9QUk9QUyk7CisgIGlmICghbWFwcGluZ3AoaWRhdGEpIHx8ICFzaXplb2YoaWRhdGEpKQorICAgIHJldHVybiBTT0NLRVRfTk9fREFUQTsKKyAgc3RyaW5nIHN0eXA9KHN0cmluZylpdGVtLT5RdWVyeVByb3AoUF9TT0NLRVRfVFlQRSk7CisgIGlmICghc3RyaW5ncChzdHlwKQorICAgICAgfHwgbWVtYmVyKFZBTElEX1NPQ0tFVF9UWVBFUywgc3R5cCkgPT0gLTEpCisgICAgcmV0dXJuIFNPQ0tFVF9JTlZBTElEX1RZUEU7CisKKyAgLy8gSGF0IGRpZXNlcyBJdGVtIHVlYmVyaGF1cHQgU29ja2VsPyBVbmQgd2VubiBqYSwgaGFiZW4gd2lyIG5lbiBmcmVpZW4KKyAgLy8gU29ja2UgZnVlciBkZW4gYmV0cmVmZmVuZGVuIFR5cD8KKyAgbWFwcGluZyBteXNvY2tldHMgPSBRdWVyeVByb3AoUF9TT0NLRVRTKTsKKyAgaWYgKCFtYXBwaW5ncChteXNvY2tldHMpIHx8ICFzaXplb2YobXlzb2NrZXRzKSkgCisgICAgcmV0dXJuIFNPQ0tFVF9OT19TT0NLRVRTOworICBpZiAoIW1lbWJlcihteXNvY2tldHMsIHN0eXApCisgICAgICB8fCAhbWVtYmVyKG15c29ja2V0c1tzdHlwXSwgU09DS0VUX0ZSRUUpID09IC0xICkKKyAgICByZXR1cm4gU09DS0VUX05PTkVfQVZBSUxBQkxFOworCisgIC8vIEhhbmR3ZXJrZXIgcHJ1ZWZlbi4KKyAgLy8gVE9ETzogU29sbCBkaWUgRmVobGVybWVsZHVuZyBrb21wbGV0dCB2b20gQXVmcnVmZXIgZXJsZWRpZ3Qgd2VyZGVuIG9kZXIKKyAgLy8gc29sbCBlcyBlaW5lbiBIZWlud2VpcyBnZWJlbiwgd2FydW0gZGVyIEhhbmR3ZXJrZXIgbmljaHQgZ2VlaWduZXQgaXN0PworICBvYmplY3QgY3JhZnRzbWFuID0gcHJldmlvdXNfb2JqZWN0KCk7CisgIG1hcHBpbmcgcmVzdHIgPSAobWFwcGluZylpdGVtLT5RdWVyeVByb3AoUF9TT0NLRVRfUkVTVFJfTU9VTlQpOworICBpZiAoIW9iamVjdHAoY3JhZnRzbWFuKQorICAgICAgfHwgKG1hcHBpbmdwKHJlc3RyKQorCSYmICIvc3RkL3Jlc3RyaWN0aW9uX2NoZWNrZXIiLT5jaGVja19yZXN0cmljdGlvbnMoY3JhZnRzbWFuLAorCSAgcmVzdHIpKSkKKyAgICByZXR1cm4gU09DS0VUX05PX0VYUEVSVElTRTsKKworICAvLyBkYSBQX1JFU1RSSUNUSU9OIG51ciBiZWltIEFuemllaGVuL1p1ZWNrZW4gZ2VwcnVlZnQgd2lyZCwgZGFyZiBtYW4gZWluCisgIC8vIEl0ZW0gbmljaHQgaW4gZ2V0cmFnZW5lbSBadXN0YW5kIG1vZGlmaXppZXJlbi4KKyAgaWYgKG9iamVjdHAoKG9iamVjdClpdGVtLT5RdWVyeVByb3AoUF9XSUVMREVEKSkKKyAgICAgIHx8IG9iamVjdHAoKG9iamVjdClpdGVtLT5RdWVyeVByb3AoUF9XT1JOKSkpCisgICAgcmV0dXJuIFNPQ0tFVF9JVEVNX0lOVVNFOworCisgIHJldHVybiBTT0NLRVRfT0s7Cit9CisKKy8qKiBMaWVmZXJ0IEluZm9zIHVlYmVyIGRpZSBTb2NrZXRzIChUeXAsIHdhcyBkcmluIGlzdCwgZXRjLlwgKS4KKyAgUHJpbWFlciBmdWVyIEdpbGRlbiBnZWRhY2h0LgorKi8KK3B1YmxpYyBtaXhlZCBHZXRTb2NrZXRJbmZvKCkgeworfQorCisvKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqIHByaXZhdGUgKioqKioqKioqKioqKioqKioqKioqKioqKiAqLworCisvKiogQWRkaWVydCB6d2VpIFZhcmlhYmxlbiwgc29mZXJuIHNpZSBrb21wYXRpYmVsIHNpbmQuCisgIExhc3NlbiBzaWNoIGRpZSBiZWlkZW4gRGF0ZW50eXBlbiBuaWNodCBzaW5udm9sbCBhZGRpZXJlbiwgZXJmb2xndCBrZWluZQorICBBZGRpdGlvbiB1bmQgXGEgb2xkIHdpcmQgenVydWVjayBnZWxpZWZlcnQgKHouQi4gYmVpIE9iamVrdGVuLCBDbG9zdXJlcykuCisgIEhpZXJiZWkgZXJmb2xndCB6LkIuIGJlaSBNYXBwaW5ncyBlaW5lIHdlcnR3ZWlzZSBBZGRpdGlvbiwga2VpbmUgYmxvc3NlCisgIEVyc2V0enVuZyBkZXIgS2V5cyB3aWUgYmVpIGRlciBub3JtYWxlbiBNYXBwaW5nLUFkZGl0aW9uLgorICBAcGFyYW1baW4sb3V0XSBvbGQgRGF0dW0sIHp1IGRlbSBhZGRpZXJ0IHdlcmRlbiBzb2xsLiBXaXJkIGJlaSBNYXBwaW5ncworICBnZWFlbmRlcnQuCisgIEBwYXJhbVtpbl0gbmV3IERhdHVtLCB3ZWxjaGVzIGFkZGllcnRlbiBzb2xsLgorICBAcmV0dXJuIFN1bW1lIHZvbiBvbGQgdW5kIG5ldywgZmFsbHMgZGllIERhdGVudHlwZW4ga29tcGF0aWJlbCBzaW5kLiBGYWxscworICBuaWNodCwga2FubiBvbGQgenVydWVja2dlZ2ViZW4gd2VyZGVuLiBEZXIgRGF0ZW50eXAgdm9uIAorICBAYXR0ZW50aW9uIFxiIFJla3Vyc2l2ISBLYW5uIHRldWVyIHdlcmRlbi5cbgorICAgIEthbm4gKG1vZGlmaXppZXJ0ZSkgXGEgb2xkIG9kZXIgXGEgbmV3IG9kZXIgZ2FueiBuZXVlcyBEYXR1bSAKKyAgICB6dXJ1ZWNrbGllZmVybiwgZC5oLiBkZXIgenVydWVja2dlbGllZmVydGUgRGF0ZW50eXAgbXVzcyBuaWNodCBkZW0KKyAgICBEYXRlbnR5cCB2b24gb2xkIGVudHNwcmVjaGVuLiBFYmVuc28gZXJ6ZXVndCB6LkIuIGRpZSBBZGRpdGlvbiB6d2VpZXIKKyAgICBBcnJheXMgZWluIG5ldWVzIEFycmF5LgorICAgIFdlbm4gZGllIGtvcnJlc3BvbmRpZXJlbmRlbiBXZXJ0ZSBuaWNodCBkZW4gZ2xlaWNoZW4gRGF0ZW50eXAgaGFiZW4sCisgICAgZmluZGV0IHUuVS4ga2VpbmUgQWRkaXRpb24gc3RhdHQgb2RlciBlcyB3aXJkIGVpbmUgRGF0ZW50eXAtVW13YW5kbHVuZworICAgIGR1cmNoZ2VmdWVocnQsIHouQi4gSW50ICsgRmxvYXQgPT0gRmxvYXQuXG4KKyAgKi8KK3ByaXZhdGUgbWl4ZWQgQWRkVG9FbnRpdHkobWl4ZWQgb2xkLCBtaXhlZCBuZXcpIHsKKworICAvLyBlaW5mYWNoc3RlIEZhZWxsZToKKyAgaWYgKCFvbGQpCisgICAgcmV0dXJuIG5ldzsKKyAgZWxzZSBpZiAoIW5ldykKKyAgICByZXR1cm4gb2xkOworCisgIC8vIFR5cCBiZXN0aW1tZW4KKyAgaW50IG9sZHR5cGUgPSB0eXBlb2Yob2xkKTsKKyAgaW50IG5ld3R5cGUgPSB0eXBlb2YobmV3KTsKKyAgLy8gVmFyaWFibGVuIGdsZWljaGVuIFR5cHMgc2luZCBlaW5mYWNoLgorICBpZiAob2xkdHlwZSA9PSBuZXd0eXBlKSB7CisgICAgc3dpdGNoIChvbGR0eXBlKSB7CisgICAgICAvLyBlaW5pZ2UgVHlwZW4gd2VyZGVuIHN0dW1wZiBhZGRpZXJ0LgorICAgICAgY2FzZSBUX05VTUJFUjoKKyAgICAgIGNhc2UgVF9TVFJJTkc6CisgICAgICBjYXNlIFRfRkxPQVQ6CisgICAgICBjYXNlIFRfUE9JTlRFUjogLy8gVE9ETzogYW5kZXJlcyBWZXJoYWx0ZW4/CisJcmV0dXJuIG9sZCtuZXc7CisgICAgICAvLyBNYXBwaW5ncyB3ZXJkZW4gd2VydHdlaXNlIGFkZGllcnQuCisgICAgICBjYXNlIFRfTUFQUElORzoKKwkvLyBudXIgd2VubiBkaWUgQnJlaXRlIGRlcyAyLiBTdW1tYW5kZW4gPD0gZGVyIGRlcyAxLiBTdW1tYW5kZW4gaXN0LAorCS8vIGxhc3NlbiBzaWNoIE1hcHBpbmdzIGhpZXJtaXQgYWRkaWVyZW4uCisJaWYgKHdpZHRob2YobmV3KSA+IHdpZHRob2Yob2xkKSkKKwkgIHJldHVybiBvbGQ7CisJLy8gbmV3IGF1ZiBvbGQgYWRkaWVyZW4uIEtleXMgd2VyZGVuIG5pY2h0IGVyc2V0enQsIHNvbmRlcm4gbmFjaAorCS8vIE1vZWdsaWNoa2VpdCBkaWUgd2VydGUgdW50ZXIgZGVuIGtleXMgamV3ZWlscyBhZGRpZXJ0LgorCS8vIG1hcCgpIG51ciB6dW0gVWViZXJnZWJlbiBhbGxlciBLZXlzK1ZhbHVlLiBBZGRUb01hcHBpbmcgYWVuZGVydAorCS8vIGRpcmVrdCBkYXMgdWViZXJnZWJlbmUgTWFwcGluZyBvbGQuCisJbWFwKG5ldywgIydBZGRUb01hcHBpbmcsIG9sZCk7IAorCS8vIGFsbGVzIGhpZXIgbmljaHQgYXVmZ2VmdWVocnRlIGthbm4gbmljaHQgYWRkaWVydCB3ZXJkZW4uCisgICAgICBkZWZhdWx0OiByZXR1cm4gb2xkOworICAgIH0KKyAgfQorICAvLyBJbnRzIHVuZCBGbG9hdHMgc2luZCBhdWNoIG5vY2ggZ3V0IGFkZGllcmJhci4KKyAgZWxzZSBpZiAoKG9sZHR5cGUgPT0gVF9GTE9BVCAmJiBuZXd0eXBlID09IFRfTlVNQkVSKSB8fAorICAgICAgICAgICAob2xkdHlwZSA9PSBUX05VTUJFUiAmJiBuZXd0eXBlID09IFRfRkxPQVQpICkKKyAgICByZXR1cm4gb2xkICsgbmV3OworICAvLyBBcnJheXMgbGFzc2VuIHNpY2ggYXVjaCBndXQgdmVyd3Vyc3RlbiAobmV3IGthbm4ga2VpbiBBcnJheSBzZWluKS4KKyAgLy8gVW1nZWtlaHJ0ZXIgRmFsbCB3YWVyZSBhdWNoIG1lb2dsaWNoLCBhYmVyIGRlciBEYXRlbnR5cCB2b24gb2xkIHdhZXJlCisgIC8vIHNlaHIgZGV1dGxpY2ggdW50ZXJzY2hpZWRsaWNoIHZvbSB1cnNwcnVlbmdsaWNoZW4uCisgIGVsc2UgaWYgKG9sZHR5cGUgPT0gVF9QT0lOVEVSKQorICAgIHJldHVybiBvbGQrKHtuZXd9KTsKKyAgLy8gU3RyaW5ncyB1bmQgWmVpY2hlbmxpdGVyYWxlIChJbnRzKSBzaW5kIEFuc2ljaHRzc2FjaGUuCisgIGVsc2UgaWYgKG9sZHR5cGUgPT0gVF9TVFJJTkcgJiYgbmV3dHlwZSA9PSBUX05VTUJFUikKKyAgICByZXR1cm4gc3ByaW50ZigiJXMlYyIsb2xkLG5ldyk7CisgIGVsc2UgaWYgKG9sZHR5cGUgPT0gVF9OVU1CRVIgJiYgbmV3dHlwZSA9PSBUX1NUUklORykKKyAgICByZXR1cm4gc3ByaW50ZigiJWMlcyIsb2xkLG5ldyk7CisKKyAgLy8gRmFsbC10aHJvdWdoCisgIHJldHVybiBvbGQ7Cit9CisKKy8qKiBBZGRpZXJ0IGVpbmVuIFNjaGx1ZXNzZWwgdW5kIHNlaW5lIFdlcnRlIHp1IGVpbmVtIE1hcHBpbmcsIGdnZi5cIGF1ZiBkaWUKKyAqIGJlc3RlaGVuZGVuIFdlcnRlIGRlcyBNYXBwaW5ncyBcYSBvbGQuCisgKiBEZXIgS2V5IHVuZCBzZWluZSBXZXJ0ZSBlcnNldHplbiBiZXN0ZWhlbmRlIFdlcnRlIGluIFxhIG9sZCBuaWNodCwgd2llIGVzCisgKiBkaWUgbm9ybWFsZSBNYXBwaW5nLUFkZGl0aW9uIGRlcyBEcml2ZXIgbWFjaHQuIFN0YXR0ZGVzc2VuIHdpcmQgdmVyc3VjaHQsCisgKiBkaWUgbmV1ZW4gV2VydGUgYXVmIGRpZSBlbnRzcHJlY2hlbmRlbiBhbHRlbiBXZXJ0ZSB6dSBhZGRpZXJlbi4gRmFsbHMgZGllCisgKiBEYXRlbnR5cGVuIHp3ZWllciBXZXJ0ZSBpbmtvbXBhdGliZWwgc2luZCwgZXJmb2xndCBrZWluZSBBZGRpdGlvbiB1bmQgZGVyCisgKiBhbHRlIFdlcnRlIGhhdCBCZXN0YW5kLgorICBAcGFyYW1baW5dIGtleSAobWl4ZWQpIFdlcnQsIGRlciBpbiBkYXMgTWFwcGluZyBhZGRpZXJ0IHdpcmQuCisgIEBwYXJhbVtpbl0gdmFsdWVzIChtaXhlZCkKKyAgQHBhcmFtW2luLG91dF0gb2xkIE1hcHBpbmcsIGluIGRhcyBhZGRpZXJ0IHdpcmQuCisgIEBhdHRlbnRpb24gRGllIEJyZWl0ZXMgZGVzIDIuIFN1bW1hbmRlbiBkYXJmIFxiIG5pY2h0IGdyb2Vzc2VyIHNlaW4gYWxzIGRpZQorICBCcmVpdGUgZGVzIDEsIFN1bW1hbmRlbiEgXG4KKyAgICBEaWUga29ycmVzcG9uZGllcmVuIFdlcnRlIHNvbGx0ZW4gZGVuIGdsZWljaGVuIERhdGVudHlwIGhhYmVuLCBzb25zdAorICAgIGZpbmRldCB1LlUuIGtlaW5lIEFkZGl0aW9uIHN0YXR0IG9kZXIgZXMgd2lyZCBlaW5lIERhdGVudHlwLVVtd2FuZGx1bmcKKyAgICBkdXJjaGdlZnVlaHJ0LCB6LkIuIEludCArIEZsb2F0ID09IEZsb2F0LlxuCisgICovCitwcml2YXRlIHZvaWQgQWRkVG9NYXBwaW5nKG1peGVkIGtleSwgbWl4ZWQgdmFsdWVzLCBtYXBwaW5nIG9sZCkgeworICBpZiAoIW1hcHBpbmdwKG9sZCkpIHJldHVybjsKKyAgaWYgKCFwb2ludGVycCh2YWx1ZXMpKSB2YWx1ZXMgPSAoe3ZhbHVlc30pOworCisgIC8vIHdlbm4gZGVyIEtleSBub2NoIG5pY2h0IGV4aXN0aWVydCwgaXN0cyBlaW5mYWNoLgorICBpZiAoIW1lbWJlcihvbGQsIGtleSkpCisgICAgbV9hZGQob2xkLCBrZXksIHZhbHVlcy4uLik7IC8vIGZsYXR0ZW4gb3BlcmF0b3IgLi4uIGNvb2wuIDstKQorICBlbHNlIHsKKyAgICAvLyBzb25zdCBtdWVzc2VuIHdpciB0ZXVyZSBoYW5kYXJiZWl0IG1hY2hlbi4gSW5zYi4gd2VpbCBkaWUgVmFsdWVzIGVpbmVuCisgICAgLy8gYmVsaWViaWdlbiBEYXRlbnR5cCBoYWJlbiBrb2VubmVuLCB1LmEuIE1hcHBpbmdzLCB3ZXN3ZWdlbiB3aXIgd2llZGVyCisgICAgLy8gcmVrdXJzaXYgQWRkVG9FbnRpdHkoKSBydWZlbiBtdWVzc2VuLgorICAgIGZvcihpbnQgaT1zaXplb2YodmFsdWVzKSA7IGktLSA7ICkgeworICAgICAgb2xkW2tleSxpXSA9IEFkZFRvRW50aXR5KG9sZFtrZXksaV0sIHZhbHVlc1tpXSk7CisgICAgfQorICB9Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC90aGluZy91dGlsLmMgYi9zdGQvdGhpbmcvdXRpbC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ0MzQ2NDIKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdGhpbmcvdXRpbC5jCkBAIC0wLDAgKzEsMTExIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdGhpbmcvdXRpbC5jIC0tIFV0aWxpdGllcworLy8KKy8vICRJZDogdXRpbC5jIDYzNjYgMjAwNy0wNy0xNSAyMTowNjoyNFogWmVzc3RyYSAkCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSAiL3N5cy90aGluZy91dGlsLmgiCisjaW5jbHVkZSAiL3N5cy90aGluZy9wcm9wZXJ0aWVzLmgiCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworcHVibGljIHZvaWQgU2hvd1Byb3BMaXN0KHN0cmluZyAqcHJvcHMpIAoreworICBpbnQgaSxqOworCisgIGo9c2l6ZW9mKHByb3BzKTsKKworICBmb3IgKCBpPTA7IGk8aiA7IGkrKykgCisgIHsKKyAgICB3cml0ZSgiKiIrcHJvcHNbaV0rIjogIik7CisgICAgUHJldHR5RHVtcChRdWVyeVByb3AocHJvcHNbaV0pKTsKKyAgICB3cml0ZSgiXG4iKTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBQcmV0dHlEdW1wKG1peGVkIHgpIAoreworICBpZiAocG9pbnRlcnAoeCkpIAorICB7CisgICAgRHVtcEFycmF5KHgpOworICB9CisgIGVsc2UgaWYgKG1hcHBpbmdwKHgpKQorICB7CisgICAgRHVtcE1hcHBpbmcoeCk7CisgIH0KKyAgZWxzZSBpZiAob2JqZWN0cCh4KSkgCisgIHsKKyAgICB3cml0ZSAoIk9CSigiK29iamVjdF9uYW1lKHgpKyIpIik7CisgIH0KKyAgZWxzZSBpZiAoc3RyaW5ncCh4KSkKKyAgeworICAgIHdyaXRlKCJcIiIreCsiXCIiKTsKKyAgfQorICBlbHNlCisgIHsKKyAgICB3cml0ZSAoeCk7CisgIH0KK30KKworc3RhdGljIHZvaWQgRHVtcEFycmF5KG1peGVkICp4KSAKK3sKKyAgaW50IGksajsKKworICB3cml0ZSAoIih7ICIpOworICBpZiAoIChqPXNpemVvZih4KSk+MCApCisgIHsKKyAgICBmb3IgKCBpPTAgOyBpPChqLTEpIDsgaSsrKSAKKyAgICB7CisgICAgICBQcmV0dHlEdW1wKHhbaV0pOworICAgICAgd3JpdGUoIiwgIik7CisgICAgfQorICAgIFByZXR0eUR1bXAoeFtpXSk7CisgICAgd3JpdGUoIiAiKTsKKyAgfQorICB3cml0ZSAoIn0pIik7Cit9CisKK3N0YXRpYyB2b2lkIER1bXBNYXBwaW5nKG1hcHBpbmcgeCkKK3sKKyAgaW50ICAgaSwgYywgczsKKyAgbWl4ZWQgKmluZDsKKworICB3cml0ZSgiKFsgIik7CisKKyAgaWYgKCAoYz1zaXplb2YoaW5kPW1faW5kaWNlcyh4KSkpPDEgKQorICB7CisgICAgd3JpdGUoIiBdKSIpOworICAgIHJldHVybjsKKyAgfQorCisgIHM9Z2V0X3R5cGVfaW5mbyh4LDEpOworCisgIER1bXBLZXlWYWxQYWlyKHgsIGluZFswXSwgcyk7CisgIGZvciAoIGk9MSA7IGk8YyA7IGkrKyApCisgIHsKKyAgICB3cml0ZSgiLCAiKTsKKyAgICBEdW1wS2V5VmFsUGFpcih4LCBpbmRbaV0sIHMpOworICB9CisgIHdyaXRlKCIgXSkiKTsKK30KKworLy8gTGFjaHQgbmljaHQgdWViZXIgZGVuIE5hbWVuISEhIC1Cb2luZworLy8gTmVpbiwgdWViZXIgZGVuIE5hbWVuIGxhY2hlIGljaCBuaWNodCAuLi4gLVBhcmFjZWxzdXMKK3N0YXRpYyB2b2lkIER1bXBLZXlWYWxQYWlyKG1hcHBpbmcgeCwgbWl4ZWQga2V5LCBpbnQgc2l6ZSkKK3sgaW50IGosIHZjOworCisgIFByZXR0eUR1bXAoa2V5KTsKKyAgd3JpdGUoIiA6ICIpOworICBQcmV0dHlEdW1wKHhba2V5LDBdKTsKKworICBmb3IgKCBqPTE7IGo8c2l6ZTsgaisrKQorICB7CisgICAgd3JpdGUoIjsgIik7CisgICAgUHJldHR5RHVtcCh4W2tleSwgal0pOworICB9Cit9Cg==