LyogV2luZG93cyBHVUkgQmVoYXZpb3VyIFRlc3RlciAqLwovKiBieSBPdmUgS+V2ZW4gKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHdpbmRvd3MuaD4KCiNpbmNsdWRlICJndWl0ZXN0LnJoIgoKLyogY2hlY2tzIHRvIGluY2x1ZGUgKi8KI2RlZmluZSBMT0dHSU5HIC8qIGNhbiBiZSB1bmRlZmluZWQgdW5kZXIgV2luZSBhbmQgdXNlIC1kZWJ1Z21zZyArbWVzc2FnZSBpbnN0ZWFkICovCiNkZWZpbmUgTUFJTl9TVFlMRSBXU19PVkVSTEFQUEVEV0lORE9XfFdTX0hTQ1JPTEwKI2RlZmluZSBNQUlOX0VYU1RZTEUgMAojdW5kZWYgVEVTVF9ERVNUUk9ZX01BSU4KI2RlZmluZSBTSE9XX1NVQgojdW5kZWYgVEVTVF9ESUFMT0cKI2RlZmluZSBSRVNJWkVfRElBTE9HCiN1bmRlZiBURVNUX1NVQkRJQUxPRwojdW5kZWYgVEVTVF9DT01NQ1RMCgovKioqKioqKioqKioqKioqKioqKioqKioqLwovKioqIEdMT0JBTCBWQVJJQUJMRVMgKioqLwovKioqKioqKioqKioqKioqKioqKioqKioqLwoKSElOU1RBTkNFIGhJbnN0OwpEV09SRCBTdGFydFRpbWU7CkhXTkQgaExpc3RCb3gsaE1haW5XbmQsaFN1YlduZDsKSFdORCBoQnV0dG9uWzRdPXswLDAsMCwwfTsKSFdORCBoRGlhbG9nPTAsaEdyb3VwPTAsaFN1YkRsZz0wOwpXTkRQUk9DIHduZEJ1dHRvbls0XSx3bmREaWFsb2csd25kR3JvdXAsd25kU3ViRGxnOwpCT09MIENsaWNrZWQ9MCxSZWFkeT0wOwppbnQgU3RhdGU9MCxSZWM9MDsKI2RlZmluZSBTVEFURV9DUkVBVEUgMAojZGVmaW5lIFNUQVRFX0RFU1RST1kgMQojZGVmaW5lIFNUQVRFX1NIT1cgMgojZGVmaW5lIFNUQVRFX1VQREFURSAzCiNkZWZpbmUgU1RBVEVfRElBTE9HIDQKI2RlZmluZSBTVEFURV9URVNUIDUKI2RlZmluZSBTVEFURV9ESVJFQ1QgNgojZGVmaW5lIFNUQVRFX0RJU1BBVENIIDcKI2RlZmluZSBTVEFURV9SRUNVUlMgOApjaGFyKlN0YXRlTmFtZVtdPXsKICJDcmVhdCIsCiAiRGVzdHIiLAogIlNob3cgIiwKICJVcGRhdCIsCiAiRGlhbGciLAogIlRlc3QgIiwKICJDYWxsICIsCiAiRGlzcCAiLAogIlJDYWxsIgp9OwoKc3RhdGljIGNoYXIgd2NsYXNzbmFtZVtdID0gIkdVSVRlc3RDbGFzcyI7CnN0YXRpYyBjaGFyIHdjY2xhc3NuYW1lW10gPSAiR1VJVGVzdENoaWxkQ2xhc3MiOwpzdGF0aWMgY2hhciB3aW5uYW1lW10gPSAiR1VJVGVzdCI7CgovKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKiogTE9HR0lORyBGQUNJTElUSUVTICoqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RydWN0IE1TR05BTUVTIHsKIGludCBtc2c7CiBjaGFyKm5hbWU7Cn0gTXNnTmFtZXNbXT17CiNkZWZpbmUgTVNHKHgpIHt4LCN4fSwKI2RlZmluZSBNU0cyKHgseSkge3ksI3h9LAojZGVmaW5lIEVORE1TRyB7MH0KCi8qIHdlIGdldCB0aGVzZSBpbiBDcmVhdGVXaW5kb3cgKi8KTVNHKFdNX0dFVE1JTk1BWElORk8pCk1TRyhXTV9OQ0NSRUFURSkKTVNHKFdNX05DQ0FMQ1NJWkUpCk1TRyhXTV9DUkVBVEUpCk1TRyhXTV9QQVJFTlROT1RJRlkpCgovKiB3ZSBnZXQgdGhlc2UgaW4gU2hvd1dpbmRvdyAqLwpNU0coV01fU0hPV1dJTkRPVykKTVNHKFdNX1dJTkRPV1BPU0NIQU5HSU5HKQpNU0coV01fUVVFUllORVdQQUxFVFRFKQpNU0coV01fQUNUSVZBVEVBUFApCk1TRyhXTV9OQ0FDVElWQVRFKQpNU0coV01fR0VUVEVYVCkKTVNHKFdNX0FDVElWQVRFKQpNU0coV01fU0VURk9DVVMpCk1TRyhXTV9OQ1BBSU5UKQpNU0coV01fRVJBU0VCS0dORCkKTVNHKFdNX1dJTkRPV1BPU0NIQU5HRUQpCk1TRyhXTV9TSVpFKQpNU0coV01fTU9WRSkKCi8qIHdlIGdldCB0aGVzZSBpbiBEZXN0cm95V2luZG93ICovCk1TRyhXTV9LSUxMRk9DVVMpCk1TRyhXTV9ERVNUUk9ZKQpNU0coV01fTkNERVNUUk9ZKQoKLyogd2UgZ2V0IHRoZXNlIGRpcmVjdGx5IHNlbnQgKi8KTVNHKFdNX05DSElUVEVTVCkKTVNHKFdNX1NFVENVUlNPUikKTVNHKFdNX01PVVNFQUNUSVZBVEUpCk1TRyhXTV9DSElMREFDVElWQVRFKQpNU0coV01fQ09NTUFORCkKTVNHKFdNX1NZU0NPTU1BTkQpCgovKiBwb3N0ZWQgZXZlbnRzICovCk1TRyhXTV9NT1VTRU1PVkUpCk1TRyhXTV9OQ01PVVNFTU9WRSkKTVNHKFdNX1BBSU5UKQpNU0coV01fTEJVVFRPTkRPV04pCk1TRyhXTV9MQlVUVE9OVVApCk1TRyhXTV9MQlVUVE9OREJMQ0xLKQpNU0coV01fTkNMQlVUVE9ORE9XTikKTVNHKFdNX05DTEJVVFRPTlVQKQpNU0coV01fTkNMQlVUVE9OREJMQ0xLKQoKTVNHKFdNX0tFWURPV04pCk1TRyhXTV9LRVlVUCkKTVNHKFdNX0NIQVIpCgojaWZkZWYgV0lOMzIKTVNHKFdNX0NUTENPTE9SQlROKQpNU0coV01fQ1RMQ09MT1JETEcpCk1TRyhXTV9DVExDT0xPUlNUQVRJQykKI2Vsc2UKTVNHKFdNX0NUTENPTE9SKQojZW5kaWYKCi8qIG1vdmluZyBhbmQgc2l6aW5nICovCk1TRzIoV01fRU5URVJTSVpFTU9WRSwweDAyMzEpCk1TRzIoV01fRVhJVFNJWkVNT1ZFLDB4MDIzMikKI2lmZGVmIFdJTjMyCk1TRyhXTV9TSVpJTkcpCiNlbmRpZgoKLyogbWVudXMvZGlhbG9nIGJveGVzICovCk1TRyhXTV9DQU5DRUxNT0RFKQpNU0coV01fRU5BQkxFKQpNU0coV01fU0VURk9OVCkKTVNHKFdNX0lOSVRESUFMT0cpCk1TRyhXTV9HRVRETEdDT0RFKQpNU0coV01fRU5URVJJRExFKQoKLyogc2Nyb2xsIGJhcnMgKi8KTVNHKFdNX0hTQ1JPTEwpCk1TRyhXTV9WU0NST0xMKQoKLyogZ2V0dGluZyB0aGVzZSBmcm9tIFdpbmUgYnV0IG5vdCBmcm9tIFdpbmRvd3MgKi8KTVNHMihXTV9TRVRWSVNJQkxFLDB4MDAwOSkgLyogdW5oZWFyZCBvZiBpbiBCQysrIDQuNTIgKi8KI2lmZGVmIFdJTjMyCk1TRyhXTV9DQVBUVVJFQ0hBTkdFRCkKI2VuZGlmCgpFTkRNU0d9OwoKc3RydWN0IE1TR05BTUVTIEJ1dE1zZ3NbXT17Ck1TRyhCTV9TRVRTVEFURSkKTVNHKEJNX1NFVFNUWUxFKQoKRU5ETVNHfTsKCmNoYXIqTXNnTmFtZShVSU5UIG1zZyxIV05EIGhXbmQpCnsKIGludCBpOwogc3RhdGljIGNoYXIgYnVmZmVyWzY0XSx3Y2xhc3NbNjRdOwogR2V0Q2xhc3NOYW1lKGhXbmQsd2NsYXNzLHNpemVvZih3Y2xhc3MpKTsKCiNkZWZpbmUgTVNHU0VBUkNIKG1zZ3MpIHsgXAogIGZvciAoaT0wOyBtc2dzW2ldLm5hbWUmJm1zZ3NbaV0ubXNnIT1tc2c7IGkrKyk7IFwKICBpZiAobXNnc1tpXS5uYW1lKSByZXR1cm4gbXNnc1tpXS5uYW1lOyBcCiB9CgogaWYgKCFzdHJpY21wKHdjbGFzcywiQnV0dG9uIikpIE1TR1NFQVJDSChCdXRNc2dzKTsKIE1TR1NFQVJDSChNc2dOYW1lcyk7CiAvKiBXTV9VU0VSICovCiBpZiAobXNnPj1XTV9VU0VSKSB7CiAgc3ByaW50ZihidWZmZXIsIldNX1VTRVIrJTA0eHslc30iLG1zZy1XTV9VU0VSLHdjbGFzcyk7CiAgcmV0dXJuIGJ1ZmZlcjsKIH0KIC8qIG1lc3NhZ2Ugbm90IGZvdW5kICovCiBzcHJpbnRmKGJ1ZmZlciwiJTA0eHslc30iLG1zZyx3Y2xhc3MpOwogcmV0dXJuIGJ1ZmZlcjsKfQoKY2hhcipXbmROYW1lKEhXTkQgaFduZCxpbnQgc3RhdGUpCnsKIHN0YXRpYyBjaGFyIGJ1ZmZlclsxNl07CiBpZiAoIWhXbmQpIHJldHVybiAiMDAwMCI7CiBpZiAoaFduZD09aE1haW5XbmQgfHwgKHN0YXRlPT1TVEFURV9DUkVBVEUgJiYgIWhNYWluV25kKSkgcmV0dXJuICJtYWluIjsKIGlmIChoV25kPT1oU3ViV25kIHx8IChzdGF0ZT09U1RBVEVfQ1JFQVRFICYmICFoU3ViV25kKSkgcmV0dXJuICJjaGxkIjsKIGlmIChoV25kPT1oRGlhbG9nIHx8IChzdGF0ZT09U1RBVEVfRElBTE9HICYmICFoRGlhbG9nKSkgcmV0dXJuICJ0ZGxnIjsKIGlmIChoV25kPT1oR3JvdXApIHJldHVybiAidGdycCI7CiBpZiAoaFduZD09aEJ1dHRvblswXSkgcmV0dXJuICJidXQxIjsKIGlmIChoV25kPT1oQnV0dG9uWzFdKSByZXR1cm4gImJ1dDIiOwogaWYgKGhXbmQ9PWhCdXR0b25bMl0pIHJldHVybiAiYnV0MyI7CiBpZiAoaFduZD09aEJ1dHRvblszXSkgcmV0dXJuICJidXQ0IjsKIGlmIChoV25kPT1oU3ViRGxnIHx8IChzdGF0ZT09U1RBVEVfQ1JFQVRFICYmICFoU3ViRGxnKSkgcmV0dXJuICJzZGxnIjsKIGlmIChoRGlhbG9nKSB7CiAgaW50IGlkPUdldERsZ0N0cmxJRChoV25kKTsKICBpZiAoaWQpIHsKICAgc3ByaW50ZihidWZmZXIsImRsZ2l0ZW0oJWQpIixpZCk7CiAgIHJldHVybiBidWZmZXI7CiAgfQogfQogc3ByaW50ZihidWZmZXIsIiUwNHgiLGhXbmQpOwogcmV0dXJuIGJ1ZmZlcjsKfQoKdm9pZCBMb2coY29uc3QgY2hhcipmbXQpCnsKI2lmZGVmIExPR0dJTkcKIGlmICghQ2xpY2tlZCkgU2VuZE1lc3NhZ2UoaExpc3RCb3gsTEJfQUREU1RSSU5HLDAsKExQQVJBTSlmbXQpOwojZW5kaWYKfQoKdm9pZCBMb2dmKGNvbnN0IGNoYXIqZm10LC4uLikKewogdmFfbGlzdCBwYXI7CiBzdGF0aWMgY2hhciBidWZmZXJbMjU2XTsKCiB2YV9zdGFydChwYXIsZm10KTsKIHZzcHJpbnRmKGJ1ZmZlcixmbXQscGFyKTsKIHZhX2VuZChwYXIpOwogTG9nKGJ1ZmZlcik7Cn0KCnZvaWQgTG9nQ2hpbGRPcmRlcihIV05EIGhXbmQpCnsKIEhXTkQgaFduZENoaWxkID0gR2V0V2luZG93KGhXbmQsR1dfQ0hJTEQpOwogc3RhdGljIGNoYXIgYnVmZmVyWzI1Nl07Cgogc3RyY3B5KGJ1ZmZlciwiY2hpbGQgbGlzdDoiKTsKIHdoaWxlIChoV25kQ2hpbGQpIHsKICBzdHJjYXQoc3RyY2F0KGJ1ZmZlciwiICIpLFduZE5hbWUoaFduZENoaWxkLFN0YXRlKSk7CiAgaFduZENoaWxkPUdldFdpbmRvdyhoV25kQ2hpbGQsR1dfSFdORE5FWFQpOwogfQogTG9nKGJ1ZmZlcik7Cn0KCnZvaWQgTG9nTWVzc2FnZShpbnQgc3RhdGUsSFdORCBoV25kLFVJTlQgbXNnLFdQQVJBTSB3UGFyYW0sTFBBUkFNIGxQYXJhbSxjaGFyKm5hbWUpCnsKIHN0YXRpYyBjaGFyIGJ1ZmZlclsyNTZdOwogRFdPUkQgdGljaz1HZXRUaWNrQ291bnQoKS1TdGFydFRpbWU7CiBjaGFyKm1zZ25hbWU9TXNnTmFtZShtc2csaFduZCk7CiBpZiAoIW5hbWUpIG5hbWU9V25kTmFtZShoV25kLHN0YXRlKTsKIHN3aXRjaCAobXNnKSB7CiAgY2FzZSBXTV9TRVRGT0NVUzoKICBjYXNlIFdNX0tJTExGT0NVUzoKICBjYXNlIFdNX1NFVENVUlNPUjoKICAgTG9nZigiJTA0ZFslcyglZCk6JXNdJXMoJXMsJTA4eCkiLHRpY2ssU3RhdGVOYW1lW3N0YXRlXSxSZWMsCiAgICAgICAgbmFtZSxtc2duYW1lLFduZE5hbWUoKEhXTkQpd1BhcmFtLFN0YXRlKSxsUGFyYW0pOwogICBicmVhazsKI2lmZGVmIFdJTjMyCiAgY2FzZSBXTV9FTlRFUklETEU6CiAgY2FzZSBXTV9DVExDT0xPUkJUTjoKICBjYXNlIFdNX0NUTENPTE9SRExHOgogICBMb2dmKCIlMDRkWyVzKCVkKTolc10lcyglMDh4LCVzKSIsdGljayxTdGF0ZU5hbWVbc3RhdGVdLFJlYywKICAgICAgICBuYW1lLG1zZ25hbWUsd1BhcmFtLFduZE5hbWUoKEhXTkQpbFBhcmFtLFN0YXRlKSk7CiAgIGJyZWFrOwojZWxzZQogIGNhc2UgV01fRU5URVJJRExFOgogIGNhc2UgV01fQ1RMQ09MT1I6CiAgIExvZ2YoIiUwNGRbJXMoJWQpOiVzXSVzKCUwOHgsJTA0eDolcykiLHRpY2ssU3RhdGVOYW1lW3N0YXRlXSxSZWMsCiAgICAgICAgbmFtZSxtc2duYW1lLHdQYXJhbSxISVdPUkQobFBhcmFtKSxXbmROYW1lKChIV05EKUxPV09SRChsUGFyYW0pLFN0YXRlKSk7CiAgIGJyZWFrOwojZW5kaWYKICBjYXNlIFdNX1dJTkRPV1BPU0NIQU5HSU5HOgogIGNhc2UgV01fV0lORE9XUE9TQ0hBTkdFRDoKICAgewogICAgV0lORE9XUE9TKnBvcz0oV0lORE9XUE9TKilsUGFyYW07CiNpZmRlZiBXSU4zMgoJIExvZ2YoIiUwNGRbJXMoJWQpOiVzXSVzKCUwOHgsJXApIix0aWNrLFN0YXRlTmFtZVtzdGF0ZV0sUmVjLAoJCQluYW1lLG1zZ25hbWUsd1BhcmFtLHBvcyk7CiNlbHNlCgkgTG9nZigiJTA0ZFslcyglZCk6JXNdJXMoJTA0eCwlcCkiLHRpY2ssU3RhdGVOYW1lW3N0YXRlXSxSZWMsCgkJCW5hbWUsbXNnbmFtZSx3UGFyYW0scG9zKTsKI2VuZGlmCgkgc3RyY3B5KGJ1ZmZlciwiRkxBR1M6Iik7CgkgaWYgKHBvcy0+ZmxhZ3MmU1dQX0RSQVdGUkFNRSkgc3RyY2F0KGJ1ZmZlciwiIERSQVdGUkFNRSIpOwoJIGlmIChwb3MtPmZsYWdzJlNXUF9ISURFV0lORE9XKSBzdHJjYXQoYnVmZmVyLCIgSElERVdJTkRPVyIpOwoJIGlmIChwb3MtPmZsYWdzJlNXUF9OT0FDVElWQVRFKSBzdHJjYXQoYnVmZmVyLCIgTk9BQ1RJVkFURSIpOwoJIGlmIChwb3MtPmZsYWdzJlNXUF9OT0NPUFlCSVRTKSBzdHJjYXQoYnVmZmVyLCIgTk9DT1BZQklUUyIpOwoJIGlmIChwb3MtPmZsYWdzJlNXUF9OT01PVkUpIHN0cmNhdChidWZmZXIsIiBOT01PVkUiKTsKCSBpZiAocG9zLT5mbGFncyZTV1BfTk9PV05FUlpPUkRFUikgc3RyY2F0KGJ1ZmZlciwiIE5PT1dORVJaT1JERVIiKTsKCSBpZiAocG9zLT5mbGFncyZTV1BfTk9TSVpFKSBzdHJjYXQoYnVmZmVyLCIgTk9TSVpFIik7CgkgaWYgKHBvcy0+ZmxhZ3MmU1dQX05PUkVEUkFXKSBzdHJjYXQoYnVmZmVyLCIgTk9SRURSQVciKTsKCSBpZiAocG9zLT5mbGFncyZTV1BfTk9aT1JERVIpIHN0cmNhdChidWZmZXIsIiBOT1pPUkRFUiIpOwoJIGlmIChwb3MtPmZsYWdzJlNXUF9TSE9XV0lORE9XKSBzdHJjYXQoYnVmZmVyLCIgU0hPV1dJTkRPVyIpOwoJIExvZyhidWZmZXIpOwoJfQoJYnJlYWs7CiAgY2FzZSBXTV9TWVNDT01NQU5EOgoJewoJIGNoYXIqY21kPU5VTEw7Cgkgc3dpdGNoICh3UGFyYW0mMHhGRkYwKSB7CiNkZWZpbmUgQ0FTRSh4KSBjYXNlIFNDXyMjeDogY21kPSN4OyBicmVhazsKCSAgQ0FTRShDTE9TRSkKCSAgQ0FTRShERUZBVUxUKQoJICBDQVNFKEhPVEtFWSkKCSAgQ0FTRShIU0NST0xMKQoJICBDQVNFKEtFWU1FTlUpCgkgIENBU0UoTUFYSU1JWkUpCgkgIENBU0UoTUlOSU1JWkUpCgkgIENBU0UoTU9VU0VNRU5VKQoJICBDQVNFKE1PVkUpCgkgIENBU0UoTkVYVFdJTkRPVykKCSAgQ0FTRShQUkVWV0lORE9XKQoJICBDQVNFKFJFU1RPUkUpCgkgIENBU0UoU0NSRUVOU0FWRSkKCSAgQ0FTRShTSVpFKQoJICBDQVNFKFRBU0tMSVNUKQoJICBDQVNFKFZTQ1JPTEwpCiN1bmRlZiBDQVNFCgkgfQoJIGlmIChjbWQpIHsKCSAgTG9nZigiJTA0ZFslcyglZCk6JXNdJXMoJXMrJXgsJTA4eCkiLHRpY2ssU3RhdGVOYW1lW3N0YXRlXSxSZWMsCgkJCSBuYW1lLG1zZ25hbWUsY21kLHdQYXJhbSYweEYsbFBhcmFtKTsKCSB9IGVsc2UgZ290byBHRU5FUklDX01TRzsKCX0KCWJyZWFrOwogIGNhc2UgV01fSFNDUk9MTDoKICBjYXNlIFdNX1ZTQ1JPTEw6Cgl7CgkgY2hhcipjbWQ9TlVMTDsKCSBzd2l0Y2ggKExPV09SRCh3UGFyYW0pKSB7CiNkZWZpbmUgQ0FTRSh4KSBjYXNlIFNCXyMjeDogY21kPSN4OyBicmVhazsKI2RlZmluZSBDQVNFMihoLHYpIGNhc2UgU0JfIyNoOiBpZiAobXNnPT1XTV9IU0NST0xMKSBjbWQ9I2g7IGVsc2UgY21kPSN2OyBicmVhazsKCSAgQ0FTRShCT1RUT00pCgkgIENBU0UoRU5EU0NST0xMKQoJICBDQVNFMihMSU5FTEVGVCxMSU5FVVApCgkgIENBU0UyKExJTkVSSUdIVCxMSU5FRE9XTikKCSAgQ0FTRTIoUEFHRUxFRlQsUEFHRVVQKQoJICBDQVNFMihQQUdFUklHSFQsUEFHRURPV04pCgkgIENBU0UoVEhVTUJQT1NJVElPTikKCSAgQ0FTRShUSFVNQlRSQUNLKQogICAgIENBU0UoVE9QKQojdW5kZWYgQ0FTRQoJIH0KCSBpZiAoY21kKSB7CiNpZmRlZiBXSU4zMgoJICBMb2dmKCIlMDRkWyVzKCVkKTolc10lcyglcywlMDR4LCVzKSIsdGljayxTdGF0ZU5hbWVbc3RhdGVdLFJlYywKCQkJIG5hbWUsbXNnbmFtZSxjbWQsSElXT1JEKHdQYXJhbSksV25kTmFtZSgoSFdORClsUGFyYW0sU3RhdGUpKTsKI2Vsc2UKCSAgTG9nZigiJTA0ZFslcyglZCk6JXNdJXMoJTA0eCwlMDR4LCVzKSIsdGljayxTdGF0ZU5hbWVbc3RhdGVdLFJlYywKCQkJIG5hbWUsbXNnbmFtZSxjbWQsTE9XT1JEKGxQYXJhbSksV25kTmFtZSgoSFdORClISVdPUkQobFBhcmFtKSxTdGF0ZSkpOwojZW5kaWYKCSB9IGVsc2UgZ290byBHRU5FUklDX01TRzsKCX0KCWJyZWFrOwogIGRlZmF1bHQ6CkdFTkVSSUNfTVNHOgojaWZkZWYgV0lOMzIKCUxvZ2YoIiUwNGRbJXMoJWQpOiVzXSVzKCUwOHgsJTA4eCkiLHRpY2ssU3RhdGVOYW1lW3N0YXRlXSxSZWMsCgkJICBuYW1lLG1zZ25hbWUsd1BhcmFtLGxQYXJhbSk7CiNlbHNlCglMb2dmKCIlMDRkWyVzKCVkKTolc10lcyglMDR4LCUwOHgpIix0aWNrLFN0YXRlTmFtZVtzdGF0ZV0sUmVjLAoJCSAgbmFtZSxtc2duYW1lLHdQYXJhbSxsUGFyYW0pOwojZW5kaWYKIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKiBHUkFQSElDUyBGQUNJTElUSUVTICoqKi8KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnZvaWQgUGFpbnQoSFdORCBoV25kKQp7CiBIREMgZGM7CiBQQUlOVFNUUlVDVCBwczsKIGRjPUJlZ2luUGFpbnQoaFduZCwmcHMpOwogRW5kUGFpbnQoaFduZCwmcHMpOwp9Cgp2b2lkIEZpbGxQYXR0ZXJuKEhXTkQgaFduZCxIREMgcGRjKQp7CiBIREMgZGM9cGRjP3BkYzpHZXREQyhoV25kKTsKIEhCUlVTSCBvbGRicnVzaDsKIFJFQ1QgcmVjdDsKIGlmICghZGMpIHsKICBMb2dmKCJmYWlsZWQgdG8gYWNxdWlyZSBEQyBmb3Igd2luZG93ICVzIixXbmROYW1lKGhXbmQsU3RhdGUpKTsKICByZXR1cm47CiB9IGVsc2UgewogIExvZ2YoImFjcXVpcmVkIERDIGZvciAlcyB3aW5kb3cgJXMsIHBhaW50aW5nIiwKICAgICAgIElzV2luZG93VmlzaWJsZShoV25kKT8idmlzaWJsZSI6ImludmlzaWJsZSIsV25kTmFtZShoV25kLFN0YXRlKSk7CiB9CiBHZXRDbGllbnRSZWN0KGhXbmQsJnJlY3QpOwogb2xkYnJ1c2g9U2VsZWN0T2JqZWN0KGRjLEdldFN0b2NrT2JqZWN0KExUR1JBWV9CUlVTSCkpOwogUGF0Qmx0KGRjLDAsMCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLFBBVENPUFkpOwogU2VsZWN0T2JqZWN0KGRjLG9sZGJydXNoKTsKIGlmICghcGRjKSBSZWxlYXNlREMoaFduZCxkYyk7Cn0KCnZvaWQgUGFpbnRQYXR0ZXJuKEhXTkQgaFduZCkKewogSERDIGRjOwogUEFJTlRTVFJVQ1QgcHM7CiBkYz1CZWdpblBhaW50KGhXbmQsJnBzKTsKIEZpbGxQYXR0ZXJuKGhXbmQsZGMpOwogRW5kUGFpbnQoaFduZCwmcHMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqKiBXSU5ET1cgUFJPQ0VEVVJFUyAqKiovCi8qKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogTUFJTiBXSU5ET1cgKi8KTFJFU1VMVCBGQVIgQ0FMTEJBQ0sgX2V4cG9ydCBNYWluV2luZG93UHJvYyhIV05EIGhXbmQsIFVJTlQgbXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiBMUkVTVUxUIGxSZXN1bHQ9MDsKIFJFQ1QgcmVjdDsKIGludCBPbGRTdGF0ZT1TdGF0ZTsKCiBTdGF0ZT1TVEFURV9SRUNVUlM7IFJlYysrOwogaWYgKCFDbGlja2VkKSBMb2dNZXNzYWdlKE9sZFN0YXRlLGhXbmQsbXNnLHdQYXJhbSxsUGFyYW0sTlVMTCk7CiBzd2l0Y2ggKG1zZykgewogIGNhc2UgV01fTkNISVRURVNUOgogICBsUmVzdWx0PURlZldpbmRvd1Byb2MoaFduZCxtc2csd1BhcmFtLGxQYXJhbSk7CiAgIGJyZWFrOwogIGNhc2UgV01fTEJVVFRPTkRPV046CiAgY2FzZSBXTV9DSEFSOgogICBpZiAoIUNsaWNrZWQpIHsKICAgIFNldFBhcmVudChoTGlzdEJveCxoV25kKTsKICAgIEdldENsaWVudFJlY3QoaFduZCwmcmVjdCk7CiAgICBNb3ZlV2luZG93KGhMaXN0Qm94LDAsMCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLFRSVUUpOwogICAgU2hvd1dpbmRvdyhoTGlzdEJveCxTV19TSE9XKTsKICAgIFNldEZvY3VzKGhMaXN0Qm94KTsKICAgIENsaWNrZWQ9VFJVRTsKICAgfQogICBicmVhazsKICBjYXNlIFdNX1NJWkU6CiAgIEdldENsaWVudFJlY3QoaFduZCwmcmVjdCk7CiAgIGlmIChDbGlja2VkKSB7CiAgICBNb3ZlV2luZG93KGhMaXN0Qm94LDAsMCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLFRSVUUpOwogICB9CiAgIE1vdmVXaW5kb3coaFN1YlduZCwwLHJlY3QuYm90dG9tLzIscmVjdC5yaWdodCxyZWN0LmJvdHRvbS0ocmVjdC5ib3R0b20vMiksVFJVRSk7CiAgIGJyZWFrOwogIGNhc2UgV01fUEFJTlQ6CiAgIFBhaW50KGhXbmQpOwogICBicmVhazsKICBjYXNlIFdNX0RFU1RST1k6CiAgIFBvc3RRdWl0TWVzc2FnZSgwKTsKICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgbFJlc3VsdD1EZWZXaW5kb3dQcm9jKGhXbmQsbXNnLHdQYXJhbSxsUGFyYW0pOwogfQogU3RhdGU9T2xkU3RhdGU7IFJlYy0tOwogcmV0dXJuIGxSZXN1bHQ7Cn0KCi8qIENISUxEIFdJTkRPVyAqLwpMUkVTVUxUIEZBUiBDQUxMQkFDSyBfZXhwb3J0IFN1YldpbmRvd1Byb2MoSFdORCBoV25kLCBVSU5UIG1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogTFJFU1VMVCBsUmVzdWx0PTA7CiBSRUNUIHJlY3Q7CiBpbnQgT2xkU3RhdGU9U3RhdGU7CgogU3RhdGU9U1RBVEVfUkVDVVJTOyBSZWMrKzsKIGlmICghQ2xpY2tlZCkgTG9nTWVzc2FnZShPbGRTdGF0ZSxoV25kLG1zZyx3UGFyYW0sbFBhcmFtLE5VTEwpOwogc3dpdGNoIChtc2cpIHsKICBjYXNlIFdNX1BBSU5UOgogICBQYWludChoV25kKTsKICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgbFJlc3VsdD1EZWZXaW5kb3dQcm9jKGhXbmQsbXNnLHdQYXJhbSxsUGFyYW0pOwogfQogU3RhdGU9T2xkU3RhdGU7IFJlYy0tOwogcmV0dXJuIGxSZXN1bHQ7Cn0KCkJPT0wgRkFSIENBTExCQUNLIF9leHBvcnQgU3ViRGlhbG9nUHJvYyhIV05EIGhXbmREbGcsIFVJTlQgbXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKTsKCi8qIFNVQkNMQVNTRUQgQ09OVFJPTFMgKi8KTFJFU1VMVCBGQVIgQ0FMTEJBQ0sgX2V4cG9ydCBTdWJDbGFzc1dpbmRvd1Byb2MoSFdORCBoV25kLCBVSU5UIG1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogTFJFU1VMVCBsUmVzdWx0PTA7CiBSRUNUIHJlY3Q7CiBpbnQgT2xkU3RhdGU9U3RhdGU7CiBpbnQgQnV0PS0xOwoKIGlmIChoV25kPT1oQnV0dG9uWzBdKSBCdXQ9MDsgZWxzZQogaWYgKGhXbmQ9PWhCdXR0b25bMV0pIEJ1dD0xOyBlbHNlCiBpZiAoaFduZD09aEJ1dHRvblsyXSkgQnV0PTI7IGVsc2UKIGlmIChoV25kPT1oQnV0dG9uWzNdKSBCdXQ9MzsKCiBTdGF0ZT1TVEFURV9SRUNVUlM7IFJlYysrOwogaWYgKCFDbGlja2VkKSB7CiAgTG9nTWVzc2FnZShPbGRTdGF0ZSxoV25kLG1zZyx3UGFyYW0sbFBhcmFtLE5VTEwpOwogIGlmIChCdXQhPS0xKSB7CiAgIGxSZXN1bHQ9Q2FsbFdpbmRvd1Byb2MoKEZBUlBST0Mpd25kQnV0dG9uW0J1dF0saFduZCxtc2csd1BhcmFtLGxQYXJhbSk7CiAgIGlmIChtc2c9PVdNX0xCVVRUT05VUCkgewogICAgTG9nQ2hpbGRPcmRlcihHZXRQYXJlbnQoaFduZCkpOwogICB9CiAgfQogIGVsc2UgaWYgKGhXbmQ9PWhEaWFsb2cpIHsKICAgbFJlc3VsdD1DYWxsV2luZG93UHJvYygoRkFSUFJPQyl3bmREaWFsb2csaFduZCxtc2csd1BhcmFtLGxQYXJhbSk7CiAgfQogIGVsc2UgaWYgKGhXbmQ9PWhTdWJEbGcpIHsKICAgbFJlc3VsdD1DYWxsV2luZG93UHJvYygoRkFSUFJPQyl3bmRTdWJEbGcsaFduZCxtc2csd1BhcmFtLGxQYXJhbSk7CiAgfQogIGVsc2UgaWYgKGhXbmQ9PWhHcm91cCkgewogICBsUmVzdWx0PUNhbGxXaW5kb3dQcm9jKChGQVJQUk9DKXduZEdyb3VwLGhXbmQsbXNnLHdQYXJhbSxsUGFyYW0pOwogICBpZiAobXNnPT1XTV9TRVRGT0NVUykgewogICAgLyogY3JlYXRlIHN1YmRpYWxvZyAqLwogICAgaWYgKGhTdWJEbGcpIHsKI2lmIDAKICAgICBTZXRSZWN0KCZyZWN0LDAsMCwxLDEpOwogICAgIEludmFsaWRhdGVSZWN0KGhXbmQsJnJlY3QsRkFMU0UpOwojZW5kaWYKICAgIH0gZWxzZSB7CiNpZmRlZiBURVNUX1NVQkRJQUxPRwogICAgIFN0YXRlPVNUQVRFX0NSRUFURTsKICAgICBoU3ViRGxnPUNyZWF0ZURpYWxvZyhoSW5zdCxNQUtFSU5UUkVTT1VSQ0UoMiksaFduZCwoRkFSUFJPQylTdWJEaWFsb2dQcm9jKTsKICAgICBTdGF0ZT1TVEFURV9SRUNVUlM7CiNlbHNlCiNpZmRlZiBSRVNJWkVfRElBTE9HCiAgICAgR2V0V2luZG93UmVjdChHZXRQYXJlbnQoaFduZCksJnJlY3QpOwogICAgIHJlY3QucmlnaHQrKzsKICAgICBTZXRXaW5kb3dQb3MoR2V0UGFyZW50KGhXbmQpLDAsMCwwLAogICAgICAgICAgICAgICAgICByZWN0LnJpZ2h0LXJlY3QubGVmdCxyZWN0LmJvdHRvbS1yZWN0LnRvcCwKICAgICAgICAgICAgICAgICAgU1dQX05PTU9WRXxTV1BfTk9aT1JERVIpOwojZW5kaWYKI2VuZGlmCiAgICB9CiAgIH0KICB9CiB9CiBTdGF0ZT1PbGRTdGF0ZTsgUmVjLS07CiByZXR1cm4gbFJlc3VsdDsKfQoKLyogTUFJTiBESUFMT0cgUFJPQ0VEVVJFICovCkJPT0wgRkFSIENBTExCQUNLIF9leHBvcnQgVGVzdERpYWxvZ1Byb2MoSFdORCBoV25kRGxnLCBVSU5UIG1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogQk9PTCBiUmVzdWx0PTA7CiBSRUNUIHJlY3Q7CiBpbnQgT2xkU3RhdGU9U3RhdGU7CiBpbnQgQnV0PS0xOwoKIFN0YXRlPVNUQVRFX1JFQ1VSUzsgUmVjKys7CiBpZiAoIUNsaWNrZWQpIExvZ01lc3NhZ2UoT2xkU3RhdGUsaFduZERsZyxtc2csd1BhcmFtLGxQYXJhbSwiZGxncCIpOwogc3dpdGNoIChtc2cpIHsKICBjYXNlIFdNX0lOSVRESUFMT0c6CiAgIGhEaWFsb2cgPSBoV25kRGxnOwogICAvKiBzdWJjbGFzcyBkaWFsb2cgd2luZG93IHByb2MgKi8KICAgd25kRGlhbG9nID0gKFdORFBST0MpU2V0V2luZG93TG9uZyhoRGlhbG9nLEdXTF9XTkRQUk9DLChMT05HKVN1YkNsYXNzV2luZG93UHJvYyk7CiAgIExvZ2YoImRpYWxvZyB2aXNpYmxlPSVzIixJc1dpbmRvd1Zpc2libGUoaFduZERsZyk/IlRSVUUiOiJGQUxTRSIpOwogICAvKiBzdWJjbGFzcyBPSyBidXR0b24gKi8KICAgaEJ1dHRvblszXSA9IEdldERsZ0l0ZW0oaFduZERsZyxJRE9LKTsKICAgd25kQnV0dG9uWzNdID0gKFdORFBST0MpU2V0V2luZG93TG9uZyhoQnV0dG9uWzNdLEdXTF9XTkRQUk9DLChMT05HKVN1YkNsYXNzV2luZG93UHJvYyk7CiAgIC8qIHN1YmNsYXNzIGdyb3VwIGJveCAqLwogICBoR3JvdXAgPSBHZXREbGdJdGVtKGhXbmREbGcsSURDX0dST1VQQk9YMSk7CiAgIHduZEdyb3VwID0gKFdORFBST0MpU2V0V2luZG93TG9uZyhoR3JvdXAsR1dMX1dORFBST0MsKExPTkcpU3ViQ2xhc3NXaW5kb3dQcm9jKTsKCiNpZmRlZiBSRVNJWkVfRElBTE9HCiAgIEdldFdpbmRvd1JlY3QoaFduZERsZywmcmVjdCk7CiAgIHJlY3QucmlnaHQtLTsKICAgU2V0V2luZG93UG9zKGhXbmREbGcsMCwwLDAsCiAgICAgICAgICAgICAgICByZWN0LnJpZ2h0LXJlY3QubGVmdCxyZWN0LmJvdHRvbS1yZWN0LnRvcCwKICAgICAgICAgICAgICAgIFNXUF9OT01PVkV8U1dQX05PWk9SREVSKTsKLy8gICBTaG93V2luZG93KEdldERsZ0l0ZW0oaFduZERsZyxJRENBTkNFTCksU1dfSElERSk7CiNlbmRpZgoKICAgYlJlc3VsdD1UUlVFOyAvKiB3ZSBkb24ndCBkbyBTZXRGb2N1cyAqLwogICBicmVhazsKICBjYXNlIFdNX1BBSU5UOgogICBQYWludFBhdHRlcm4oaFduZERsZyk7CiAgIGJSZXN1bHQ9VFJVRTsKICAgYnJlYWs7CiAgY2FzZSBXTV9DT01NQU5EOgogICBFbmREaWFsb2coaFduZERsZyxMT1dPUkQod1BhcmFtKSk7CiAgIGJSZXN1bHQ9VFJVRTsKICAgYnJlYWs7CiAgY2FzZSBXTV9DTE9TRToKICAgRW5kRGlhbG9nKGhXbmREbGcsSURDQU5DRUwpOwogICBiUmVzdWx0PVRSVUU7CiAgIGJyZWFrOwogIGNhc2UgV01fTkNERVNUUk9ZOgogICBoRGlhbG9nID0gMDsKICAgYnJlYWs7CiB9CiBTdGF0ZT1PbGRTdGF0ZTsgUmVjLS07CiByZXR1cm4gYlJlc3VsdDsKfQoKLyogU1VCRElBTE9HIFBST0NFRFVSRSAqLwpCT09MIEZBUiBDQUxMQkFDSyBfZXhwb3J0IFN1YkRpYWxvZ1Byb2MoSFdORCBoV25kRGxnLCBVSU5UIG1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogQk9PTCBiUmVzdWx0PTA7CiBSRUNUIHJlY3Q7CiBpbnQgT2xkU3RhdGU9U3RhdGU7CiBpbnQgQnV0PS0xOwoKIFN0YXRlPVNUQVRFX1JFQ1VSUzsgUmVjKys7CiBpZiAoIUNsaWNrZWQpIExvZ01lc3NhZ2UoT2xkU3RhdGUsaFduZERsZyxtc2csd1BhcmFtLGxQYXJhbSxOVUxMKTsKIHN3aXRjaCAobXNnKSB7CiAgY2FzZSBXTV9JTklURElBTE9HOgogICBoU3ViRGxnID0gaFduZERsZzsKICAgLyogc3ViY2xhc3MgZGlhbG9nIHdpbmRvdyBwcm9jICovCiAgIHduZFN1YkRsZyA9IChXTkRQUk9DKVNldFdpbmRvd0xvbmcoaERpYWxvZyxHV0xfV05EUFJPQywoTE9ORylTdWJDbGFzc1dpbmRvd1Byb2MpOwoKICAgYlJlc3VsdD1UUlVFOyAvKiB3ZSBkb24ndCBkbyBTZXRGb2N1cyAqLwogICBicmVhazsKICBjYXNlIFdNX05DREVTVFJPWToKICAgaFN1YkRsZyA9IDA7CiAgIGJyZWFrOwogfQogU3RhdGU9T2xkU3RhdGU7IFJlYy0tOwogcmV0dXJuIGJSZXN1bHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKi8KLyoqKiBNQUlOIFBST0dSQU0gKioqLwovKioqKioqKioqKioqKioqKioqKiovCgpCT09MIEFwcEluaXQodm9pZCkKewogV05EQ0xBU1Mgd2NsYXNzOwoKIHdjbGFzcy5zdHlsZSA9IENTX0hSRURSQVd8Q1NfVlJFRFJBVzsKIHdjbGFzcy5scGZuV25kUHJvYyA9IE1haW5XaW5kb3dQcm9jOwogd2NsYXNzLmNiQ2xzRXh0cmEgPSAwOwogd2NsYXNzLmNiV25kRXh0cmEgPSAwOwogd2NsYXNzLmhJbnN0YW5jZSA9IGhJbnN0Owogd2NsYXNzLmhJY29uID0gTG9hZEljb24oaEluc3QsTUFLRUlOVFJFU09VUkNFKDEpKTsKIHdjbGFzcy5oQ3Vyc29yID0gTG9hZEN1cnNvcigwLElEQ19BUlJPVyk7CiB3Y2xhc3MuaGJyQmFja2dyb3VuZCA9IEdldFN0b2NrT2JqZWN0KFdISVRFX0JSVVNIKTsKIHdjbGFzcy5scHN6TWVudU5hbWUgPSBOVUxMOwogd2NsYXNzLmxwc3pDbGFzc05hbWUgPSB3Y2xhc3NuYW1lOwogaWYgKCFSZWdpc3RlckNsYXNzKCZ3Y2xhc3MpKSByZXR1cm4gRkFMU0U7CiB3Y2xhc3MubHBmblduZFByb2MgPSBTdWJXaW5kb3dQcm9jOwogd2NsYXNzLmxwc3pDbGFzc05hbWUgPSB3Y2NsYXNzbmFtZTsKIGlmICghUmVnaXN0ZXJDbGFzcygmd2NsYXNzKSkgcmV0dXJuIEZBTFNFOwogcmV0dXJuIFRSVUU7Cn0KCmludCBQQVNDQUwgV2luTWFpbihISU5TVEFOQ0UgaEluc3RhbmNlLCBISU5TVEFOQ0UgaFByZXZJbnN0YW5jZSwKICAgICAgICAgICAgICAgICAgIExQU1RSIGxwc3pDbWRMaW5lLCBpbnQgbkNtZFNob3cpCnsKIE1TRyBtc2c7CiBSRUNUIHJlY3Q7CgogaEluc3QgPSBoSW5zdGFuY2U7CiBpZiAoIWhQcmV2SW5zdGFuY2UpCiAgaWYgKCFBcHBJbml0KCkpCiAgIHJldHVybiAwOwoKIFN0YXJ0VGltZT1HZXRUaWNrQ291bnQoKTsKIGhMaXN0Qm94ID0gQ3JlYXRlV2luZG93KCJMSVNUQk9YIiwiTWVzc2FnZXMiLFdTX0JPUkRFUnxXU19WU0NST0xMfFdTX0NISUxEfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTEJTX0hBU1NUUklOR1N8TEJTX05PVElGWXxMQlNfV0FOVEtFWUJPQVJESU5QVVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAwLDAsMCwwLEdldERlc2t0b3BXaW5kb3coKSwwLGhJbnN0LDApOwogaWYgKCFoTGlzdEJveCkgewogIE1lc3NhZ2VCb3goMCwiQ291bGQgbm90IGNyZWF0ZSBsaXN0IGJveCIsIkVycm9yIixNQl9PSyk7CiB9CgogU3RhdGU9U1RBVEVfQ1JFQVRFOwogaE1haW5XbmQgPSBDcmVhdGVXaW5kb3dFeChNQUlOX0VYU1RZTEUsd2NsYXNzbmFtZSx3aW5uYW1lLE1BSU5fU1RZTEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIENXX1VTRURFRkFVTFQsMCw0MDAsMzAwLDAsMCxoSW5zdCwwKTsKIGlmICghaE1haW5XbmQpIHJldHVybiAwOwogU3RhdGU9U1RBVEVfU0hPVzsKIFNob3dXaW5kb3coaE1haW5XbmQsbkNtZFNob3cpOwojaWZkZWYgVEVTVF9ERVNUUk9ZX01BSU4KIFN0YXRlPVNUQVRFX0RFU1RST1k7CiBEZXN0cm95V2luZG93KGhNYWluV25kKTsKIFN0YXRlPVNUQVRFX0RJUkVDVDsKIHdoaWxlIChHZXRNZXNzYWdlKCZtc2csMCwwLDApKSB7CiAgVHJhbnNsYXRlTWVzc2FnZSgmbXNnKTsKICBTdGF0ZT1TVEFURV9ESVNQQVRDSDsKICBEaXNwYXRjaE1lc3NhZ2UoJm1zZyk7CiAgU3RhdGU9U1RBVEVfRElSRUNUOwogfQogU3RhdGU9U1RBVEVfQ1JFQVRFOwogaE1haW5XbmQgPSBDcmVhdGVXaW5kb3dFeChNQUlOX0VYU1RZTEUsd2NsYXNzbmFtZSx3aW5uYW1lLE1BSU5fU1RZTEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIENXX1VTRURFRkFVTFQsMCw0MDAsMzAwLDAsMCxoSW5zdCwwKTsKIGlmICghaE1haW5XbmQpIHJldHVybiAwOwogU3RhdGU9U1RBVEVfU0hPVzsKIFNob3dXaW5kb3coaE1haW5XbmQsbkNtZFNob3cpOwojZW5kaWYKLyogdXBkYXRlLCBzbyBubyBXTV9QQUlOVHMgYXJlIHBlbmRpbmcgKi8KIFN0YXRlPVNUQVRFX1VQREFURTsKLy8gVXBkYXRlV2luZG93KGhNYWluV25kKTsKIFJlYWR5PVRSVUU7Ci8qIGZpbGwgY2xpZW50IGFyZWEgd2l0aCBhIHBhdHRlcm4gKi8KIEZpbGxQYXR0ZXJuKGhNYWluV25kLDApOwovKiBjcmVhdGUgc3Vid2luZG93ICovCiBTdGF0ZT1TVEFURV9DUkVBVEU7CiBHZXRDbGllbnRSZWN0KGhNYWluV25kLCZyZWN0KTsKIGhTdWJXbmQgPSBDcmVhdGVXaW5kb3cod2NjbGFzc25hbWUsd2lubmFtZSxXU19DSElMRHxXU19CT1JERVJ8V1NfQ0xJUFNJQkxJTkdTLAogICAgICAgICAgICAgICAgICAgICAgICAwLHJlY3QuYm90dG9tLzIscmVjdC5yaWdodCxyZWN0LmJvdHRvbS0ocmVjdC5ib3R0b20vMiksaE1haW5XbmQsMCxoSW5zdCwwKTsKIGlmICghaFN1YlduZCkgcmV0dXJuIDA7Ci8qIGNyZWF0ZSBidXR0b25zICovCiBoQnV0dG9uWzBdID0gQ3JlYXRlV2luZG93KCJCVVRUT04iLCIxIixXU19DSElMRHxXU19DTElQU0lCTElOR1N8V1NfVklTSUJMRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgOCw4LDQ4LDIwLGhNYWluV25kLDAsaEluc3QsMCk7CiBoQnV0dG9uWzFdID0gQ3JlYXRlV2luZG93KCJCVVRUT04iLCIyIixXU19DSElMRHxXU19DTElQU0lCTElOR1N8V1NfVklTSUJMRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgMzIsMTIsNDgsMjAsaE1haW5XbmQsMCxoSW5zdCwwKTsKIGhCdXR0b25bMl0gPSBDcmVhdGVXaW5kb3coIkJVVFRPTiIsIjMiLFdTX0NISUxEfFdTX0NMSVBTSUJMSU5HU3xXU19WSVNJQkxFLAogICAgICAgICAgICAgICAgICAgICAgICAgICA1NiwxNiw0OCwyMCxoTWFpblduZCwwLGhJbnN0LDApOwovKiBzdWJjbGFzcyB0aGVtICovCiB3bmRCdXR0b25bMF0gPSAoV05EUFJPQylTZXRXaW5kb3dMb25nKGhCdXR0b25bMF0sR1dMX1dORFBST0MsKExPTkcpU3ViQ2xhc3NXaW5kb3dQcm9jKTsKIHduZEJ1dHRvblsxXSA9IChXTkRQUk9DKVNldFdpbmRvd0xvbmcoaEJ1dHRvblsxXSxHV0xfV05EUFJPQywoTE9ORylTdWJDbGFzc1dpbmRvd1Byb2MpOwogd25kQnV0dG9uWzJdID0gKFdORFBST0MpU2V0V2luZG93TG9uZyhoQnV0dG9uWzJdLEdXTF9XTkRQUk9DLChMT05HKVN1YkNsYXNzV2luZG93UHJvYyk7Ci8qIHNob3cgdGhlbSAqLwogU3RhdGU9U1RBVEVfVVBEQVRFOwogVXBkYXRlV2luZG93KGhCdXR0b25bMF0pOwogTG9nQ2hpbGRPcmRlcihoTWFpblduZCk7CiBMb2dmKCJidXQxIHZpc2libGU9JWQiLElzV2luZG93VmlzaWJsZShoQnV0dG9uWzBdKSk7CgovKiBub3cgcmVwYXJlbnQgdGhlIGJ1dHRvbiB0byBvdXIgKGludmlzaWJsZSkgc3Vid2luZG93ICovCiBTdGF0ZT1TVEFURV9URVNUOwogLyogaW4gZGlmZmVyZW50IG9yZGVyLCBzZWVpbmcgd2hvIGdldHMgdG9wbW9zdCAqLwogU2V0UGFyZW50KGhCdXR0b25bMF0saFN1YlduZCk7CiBTZXRQYXJlbnQoaEJ1dHRvblsyXSxoU3ViV25kKTsKIFNldFBhcmVudChoQnV0dG9uWzFdLGhTdWJXbmQpOwogTG9nQ2hpbGRPcmRlcihoU3ViV25kKTsKLyogdGhlIGJ1dHRvbiBzaG91bGQgbm93IGJlIGludmlzaWJsZSAqLwogTG9nZigiYnV0MSB2aXNpYmxlPSVkIixJc1dpbmRvd1Zpc2libGUoaEJ1dHRvblswXSkpOwovKiBzZWUgaWYgd2UgY2FuIGRyYXcgb24gdGhlbSAqLwogRmlsbFBhdHRlcm4oaEJ1dHRvblswXSwwKTsKCiNpZmRlZiBTSE9XX1NVQgogU3RhdGU9U1RBVEVfU0hPVzsKIFNob3dXaW5kb3coaFN1YlduZCxTV19TSE9XTk9STUFMKTsKIFN0YXRlPVNUQVRFX1VQREFURTsKIFVwZGF0ZVdpbmRvdyhoU3ViV25kKTsKIEZpbGxQYXR0ZXJuKGhTdWJXbmQsMCk7Ci8vIEludmFsaWRhdGVSZWN0KGhNYWluV25kLE5VTEwsVFJVRSk7CiBMb2dmKCJidXQxIHZpc2libGU9JWQiLElzV2luZG93VmlzaWJsZShoQnV0dG9uWzBdKSk7CiNlbmRpZgoKI2lmZGVmIFRFU1RfRElBTE9HCiBTdGF0ZT1TVEFURV9ESUFMT0c7CiBEaWFsb2dCb3goaEluc3QsTUFLRUlOVFJFU09VUkNFKDEpLGhNYWluV25kLChGQVJQUk9DKVRlc3REaWFsb2dQcm9jKTsKI2VuZGlmCiNpZmRlZiBURVNUX0NPTU1DVEwKIHsKICBEV09SRCBhcnJbMTZdOwogIENIT09TRUNPTE9SIGNjPXtzaXplb2YoY2MpLDAsaEluc3QsMCxhcnIsMH07CiAgQ2hvb3NlQ29sb3IoJmNjKTsKIH0KI2VuZGlmCgogU3RhdGU9U1RBVEVfRElSRUNUOwogd2hpbGUgKEdldE1lc3NhZ2UoJm1zZywwLDAsMCkpIHsKICBUcmFuc2xhdGVNZXNzYWdlKCZtc2cpOwogIFN0YXRlPVNUQVRFX0RJU1BBVENIOwogIERpc3BhdGNoTWVzc2FnZSgmbXNnKTsKICBTdGF0ZT1TVEFURV9ESVJFQ1Q7CiB9CiByZXR1cm4gMDsKfQoKCg==