LyoKICogUlBDIHNlcnZlciBBUEkKICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKI2luY2x1ZGUgImV4Y3B0LmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKCiNpbmNsdWRlICJycGNfc2VydmVyLmgiCiNpbmNsdWRlICJycGNfbWlzYy5oIgojaW5jbHVkZSAicnBjX21lc3NhZ2UuaCIKI2luY2x1ZGUgInJwY19kZWZzLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChycGMpOwoKdHlwZWRlZiBzdHJ1Y3QgX1JwY1BhY2tldAp7CiAgc3RydWN0IF9ScGNDb25uZWN0aW9uKiBjb25uOwogIFJwY1BrdEhkciogaGRyOwogIFJQQ19NRVNTQUdFKiBtc2c7Cn0gUnBjUGFja2V0OwoKdHlwZWRlZiBzdHJ1Y3QgX1JwY09ialR5cGVNYXAKewogIC8qIEZJWE1FOiBhIGhhc2ggdGFibGUgd291bGQgYmUgYmV0dGVyLiAqLwogIHN0cnVjdCBfUnBjT2JqVHlwZU1hcCAqbmV4dDsKICBVVUlEIE9iamVjdDsKICBVVUlEIFR5cGU7Cn0gUnBjT2JqVHlwZU1hcDsKCnN0YXRpYyBScGNPYmpUeXBlTWFwICpScGNPYmpUeXBlTWFwczsKCi8qIGxpc3Qgb2YgdHlwZSBScGNTZXJ2ZXJQcm90c2VxICovCnN0YXRpYyBzdHJ1Y3QgbGlzdCBwcm90c2VxcyA9IExJU1RfSU5JVChwcm90c2Vxcyk7CnN0YXRpYyBzdHJ1Y3QgbGlzdCBzZXJ2ZXJfaW50ZXJmYWNlcyA9IExJU1RfSU5JVChzZXJ2ZXJfaW50ZXJmYWNlcyk7CgpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBzZXJ2ZXJfY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIHNlcnZlcl9jc19kZWJ1ZyA9CnsKICAgIDAsIDAsICZzZXJ2ZXJfY3MsCiAgICB7ICZzZXJ2ZXJfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJnNlcnZlcl9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAgIDAsIDAsIHsgKERXT1JEX1BUUikoX19GSUxFX18gIjogc2VydmVyX2NzIikgfQp9OwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBzZXJ2ZXJfY3MgPSB7ICZzZXJ2ZXJfY3NfZGVidWcsIC0xLCAwLCAwLCAwLCAwIH07CgpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBsaXN0ZW5fY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGxpc3Rlbl9jc19kZWJ1ZyA9CnsKICAgIDAsIDAsICZsaXN0ZW5fY3MsCiAgICB7ICZsaXN0ZW5fY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmxpc3Rlbl9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAgIDAsIDAsIHsgKERXT1JEX1BUUikoX19GSUxFX18gIjogbGlzdGVuX2NzIikgfQp9OwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiBsaXN0ZW5fY3MgPSB7ICZsaXN0ZW5fY3NfZGVidWcsIC0xLCAwLCAwLCAwLCAwIH07CgovKiB3aGV0aGVyIHRoZSBzZXJ2ZXIgaXMgY3VycmVudGx5IGxpc3RlbmluZyAqLwpzdGF0aWMgQk9PTCBzdGRfbGlzdGVuOwovKiBudW1iZXIgb2YgbWFudWFsIGxpc3RlbmVycyAoY2FsbHMgdG8gUnBjU2VydmVyTGlzdGVuKSAqLwpzdGF0aWMgTE9ORyBtYW51YWxfbGlzdGVuX2NvdW50OwovKiB0b3RhbCBsaXN0ZW5lcnMgaW5jbHVkaW5nIGF1dG8gbGlzdGVuZXJzICovCnN0YXRpYyBMT05HIGxpc3Rlbl9jb3VudDsKCnN0YXRpYyBVVUlEIHV1aWRfbmlsOwoKaW5saW5lIHN0YXRpYyBScGNPYmpUeXBlTWFwICpMb29rdXBPYmpUeXBlTWFwKFVVSUQgKk9ialV1aWQpCnsKICBScGNPYmpUeXBlTWFwICpyc2x0ID0gUnBjT2JqVHlwZU1hcHM7CiAgUlBDX1NUQVRVUyBkdW1teTsKCiAgd2hpbGUgKHJzbHQpIHsKICAgIGlmICghIFV1aWRDb21wYXJlKE9ialV1aWQsICZyc2x0LT5PYmplY3QsICZkdW1teSkpIGJyZWFrOwogICAgcnNsdCA9IHJzbHQtPm5leHQ7CiAgfQoKICByZXR1cm4gcnNsdDsKfQoKaW5saW5lIHN0YXRpYyBVVUlEICpMb29rdXBPYmpUeXBlKFVVSUQgKk9ialV1aWQpCnsKICBScGNPYmpUeXBlTWFwICptYXAgPSBMb29rdXBPYmpUeXBlTWFwKE9ialV1aWQpOwogIGlmIChtYXApCiAgICByZXR1cm4gJm1hcC0+VHlwZTsKICBlbHNlCiAgICByZXR1cm4gJnV1aWRfbmlsOwp9CgpzdGF0aWMgUnBjU2VydmVySW50ZXJmYWNlKiBSUENSVDRfZmluZF9pbnRlcmZhY2UoVVVJRCogb2JqZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NZTlRBWF9JREVOVElGSUVSKiBpZl9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgY2hlY2tfb2JqZWN0KQp7CiAgVVVJRCogTWdyVHlwZSA9IE5VTEw7CiAgUnBjU2VydmVySW50ZXJmYWNlKiBjaWY7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIGlmIChjaGVja19vYmplY3QpCiAgICBNZ3JUeXBlID0gTG9va3VwT2JqVHlwZShvYmplY3QpOwogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIExJU1RfRk9SX0VBQ0hfRU5UUlkoY2lmLCAmc2VydmVyX2ludGVyZmFjZXMsIFJwY1NlcnZlckludGVyZmFjZSwgZW50cnkpIHsKICAgIGlmICghbWVtY21wKGlmX2lkLCAmY2lmLT5JZi0+SW50ZXJmYWNlSWQsIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKSAmJgogICAgICAgIChjaGVja19vYmplY3QgPT0gRkFMU0UgfHwgVXVpZEVxdWFsKE1nclR5cGUsICZjaWYtPk1nclR5cGVVdWlkLCAmc3RhdHVzKSkgJiYKICAgICAgICBzdGRfbGlzdGVuKSB7CiAgICAgIEludGVybG9ja2VkSW5jcmVtZW50KCZjaWYtPkN1cnJlbnRDYWxscyk7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICBpZiAoJmNpZi0+ZW50cnkgPT0gJnNlcnZlcl9pbnRlcmZhY2VzKSBjaWYgPSBOVUxMOwogIFRSQUNFKCJyZXR1cm5pbmcgJXAgZm9yICVzXG4iLCBjaWYsIGRlYnVnc3RyX2d1aWQob2JqZWN0KSk7CiAgcmV0dXJuIGNpZjsKfQoKc3RhdGljIHZvaWQgUlBDUlQ0X3JlbGVhc2Vfc2VydmVyX2ludGVyZmFjZShScGNTZXJ2ZXJJbnRlcmZhY2UgKnNpZikKewogIGlmICghSW50ZXJsb2NrZWREZWNyZW1lbnQoJnNpZi0+Q3VycmVudENhbGxzKSAmJgogICAgICBzaWYtPkNhbGxzQ29tcGxldGVkRXZlbnQpIHsKICAgIC8qIHNpZiBtdXN0IGhhdmUgYmVlbiByZW1vdmVkIGZyb20gc2VydmVyX2ludGVyZmFjZXMgYmVmb3JlCiAgICAgKiBDYWxsc0NvbXBsZXRlZEV2ZW50IGlzIHNldCAqLwogICAgU2V0RXZlbnQoc2lmLT5DYWxsc0NvbXBsZXRlZEV2ZW50KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpZik7CiAgfQp9CgpzdGF0aWMgV0lORV9FWENFUFRJT05fRklMVEVSKHJwY19maWx0ZXIpCnsKICBXQVJOKCJleGNlcHRpb24gY2F1Z2h0IHdpdGggY29kZSAweCUwOHggPSAlZFxuIiwgR2V0RXhjZXB0aW9uQ29kZSgpLCBHZXRFeGNlcHRpb25Db2RlKCkpOwogIFRSQUNFKCJyZXR1cm5pbmcgZmFpbHVyZSBwYWNrZXRcbiIpOwogIC8qIGNhdGNoIGV2ZXJ5IGV4Y2VwdGlvbiAqLwogIHJldHVybiBFWENFUFRJT05fRVhFQ1VURV9IQU5ETEVSOwp9CgpzdGF0aWMgdm9pZCBSUENSVDRfcHJvY2Vzc19wYWNrZXQoUnBjQ29ubmVjdGlvbiogY29ubiwgUnBjUGt0SGRyKiBoZHIsIFJQQ19NRVNTQUdFKiBtc2cpCnsKICBScGNTZXJ2ZXJJbnRlcmZhY2UqIHNpZjsKICBSUENfRElTUEFUQ0hfRlVOQ1RJT04gZnVuYzsKICBVVUlEICpvYmplY3RfdXVpZDsKICBScGNQa3RIZHIgKnJlc3BvbnNlOwogIHZvaWQgKmJ1ZiA9IG1zZy0+QnVmZmVyOwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBzd2l0Y2ggKGhkci0+Y29tbW9uLnB0eXBlKSB7CiAgICBjYXNlIFBLVF9CSU5EOgogICAgICBUUkFDRSgiZ290IGJpbmQgcGFja2V0XG4iKTsKCiAgICAgIC8qIEZJWE1FOiBkbyBtb3JlIGNoZWNrcyEgKi8KICAgICAgaWYgKGhkci0+YmluZC5tYXhfdHNpemUgPCBSUENfTUlOX1BBQ0tFVF9TSVpFIHx8CiAgICAgICAgICAhVXVpZElzTmlsKCZjb25uLT5BY3RpdmVJbnRlcmZhY2UuU3ludGF4R1VJRCwgJnN0YXR1cykpIHsKICAgICAgICBUUkFDRSgicGFja2V0IHNpemUgbGVzcyB0aGFuIG1pbiBzaXplLCBvciBhY3RpdmUgaW50ZXJmYWNlIHN5bnRheCBndWlkIG5vbi1udWxsXG4iKTsKICAgICAgICBzaWYgPSBOVUxMOwogICAgICB9IGVsc2UgewogICAgICAgIHNpZiA9IFJQQ1JUNF9maW5kX2ludGVyZmFjZShOVUxMLCAmaGRyLT5iaW5kLmFic3RyYWN0LCBGQUxTRSk7CiAgICAgIH0KICAgICAgaWYgKHNpZiA9PSBOVUxMKSB7CiAgICAgICAgVFJBQ0UoInJlamVjdGluZyBiaW5kIHJlcXVlc3Qgb24gY29ubmVjdGlvbiAlcFxuIiwgY29ubik7CiAgICAgICAgLyogUmVwb3J0IGZhaWx1cmUgdG8gY2xpZW50LiAqLwogICAgICAgIHJlc3BvbnNlID0gUlBDUlQ0X0J1aWxkQmluZE5hY2tIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfVkVSX01BSk9SLCBSUENfVkVSX01JTk9SKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiYWNjZXB0aW5nIGJpbmQgcmVxdWVzdCBvbiBjb25uZWN0aW9uICVwIGZvciAlc1xuIiwgY29ubiwKICAgICAgICAgICAgICBkZWJ1Z3N0cl9ndWlkKCZoZHItPmJpbmQuYWJzdHJhY3QuU3ludGF4R1VJRCkpOwoKICAgICAgICAvKiBhY2NlcHQuICovCiAgICAgICAgcmVzcG9uc2UgPSBSUENSVDRfQnVpbGRCaW5kQWNrSGVhZGVyKE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25uLT5FbmRwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVTVUxUX0FDQ0VQVCwgTk9fUkVBU09OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2lmLT5JZi0+VHJhbnNmZXJTeW50YXgpOwoKICAgICAgICAvKiBzYXZlIHRoZSBpbnRlcmZhY2UgZm9yIGxhdGVyIHVzZSAqLwogICAgICAgIGNvbm4tPkFjdGl2ZUludGVyZmFjZSA9IGhkci0+YmluZC5hYnN0cmFjdDsKICAgICAgICBjb25uLT5NYXhUcmFuc21pc3Npb25TaXplID0gaGRyLT5iaW5kLm1heF90c2l6ZTsKCiAgICAgICAgUlBDUlQ0X3JlbGVhc2Vfc2VydmVyX2ludGVyZmFjZShzaWYpOwogICAgICB9CgogICAgICBzdGF0dXMgPSBSUENSVDRfU2VuZChjb25uLCByZXNwb25zZSwgTlVMTCwgMCk7CiAgICAgIFJQQ1JUNF9GcmVlSGVhZGVyKHJlc3BvbnNlKTsKICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgICBnb3RvIGZhaWw7CgogICAgICBicmVhazsKCiAgICBjYXNlIFBLVF9SRVFVRVNUOgogICAgICBUUkFDRSgiZ290IHJlcXVlc3QgcGFja2V0XG4iKTsKCiAgICAgIC8qIGZhaWwgaWYgdGhlIGNvbm5lY3Rpb24gaXNuJ3QgYm91bmQgd2l0aCBhbiBpbnRlcmZhY2UgKi8KICAgICAgaWYgKFV1aWRJc05pbCgmY29ubi0+QWN0aXZlSW50ZXJmYWNlLlN5bnRheEdVSUQsICZzdGF0dXMpKSB7CiAgICAgICAgcmVzcG9uc2UgPSBSUENSVDRfQnVpbGRGYXVsdEhlYWRlcihORFJfTE9DQUxfREFUQV9SRVBSRVNFTlRBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CgogICAgICAgIFJQQ1JUNF9TZW5kKGNvbm4sIHJlc3BvbnNlLCBOVUxMLCAwKTsKICAgICAgICBSUENSVDRfRnJlZUhlYWRlcihyZXNwb25zZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICAgIGlmIChoZHItPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfT0JKRUNUX1VVSUQpIHsKICAgICAgICBvYmplY3RfdXVpZCA9IChVVUlEKikoJmhkci0+cmVxdWVzdCArIDEpOwogICAgICB9IGVsc2UgewogICAgICAgIG9iamVjdF91dWlkID0gTlVMTDsKICAgICAgfQoKICAgICAgc2lmID0gUlBDUlQ0X2ZpbmRfaW50ZXJmYWNlKG9iamVjdF91dWlkLCAmY29ubi0+QWN0aXZlSW50ZXJmYWNlLCBUUlVFKTsKICAgICAgaWYgKCFzaWYpIHsKICAgICAgICAvKiBGSVhNRTogc2VuZCBmYXVsdCBwYWNrZXQ/ICovCiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbiA9IHNpZi0+SWY7CiAgICAgIC8qIGNvcHkgdGhlIGVuZHBvaW50IHZlY3RvciBmcm9tIHNpZiB0byBtc2cgc28gdGhhdCBtaWRsLWdlbmVyYXRlZCBjb2RlIHdpbGwgdXNlIGl0ICovCiAgICAgIG1zZy0+TWFuYWdlckVwdiA9IHNpZi0+TWdyRXB2OwogICAgICBpZiAob2JqZWN0X3V1aWQgIT0gTlVMTCkgewogICAgICAgIFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KG1zZy0+SGFuZGxlLCBvYmplY3RfdXVpZCk7CiAgICAgIH0KCiAgICAgIC8qIGZpbmQgZGlzcGF0Y2ggZnVuY3Rpb24gKi8KICAgICAgbXNnLT5Qcm9jTnVtID0gaGRyLT5yZXF1ZXN0Lm9wbnVtOwogICAgICBpZiAoc2lmLT5GbGFncyAmIFJQQ19JRl9PTEUpIHsKICAgICAgICAvKiBuYXRpdmUgb2xlMzIgYWx3YXlzIGdpdmVzIHVzIGEgZGlzcGF0Y2ggdGFibGUgd2l0aCBhIHNpbmdsZSBlbnRyeQogICAgICAgICAqIChJIGFzc3VtZSB0aGF0J3MgYSB3cmFwcGVyIGZvciBJUnBjU3R1YkJ1ZmZlcjo6SW52b2tlKSAqLwogICAgICAgIGZ1bmMgPSAqc2lmLT5JZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAobXNnLT5Qcm9jTnVtID49IHNpZi0+SWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVDb3VudCkgewogICAgICAgICAgRVJSKCJpbnZhbGlkIHByb2NudW1cbiIpOwogICAgICAgICAgZnVuYyA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGZ1bmMgPSBzaWYtPklmLT5EaXNwYXRjaFRhYmxlLT5EaXNwYXRjaFRhYmxlW21zZy0+UHJvY051bV07CiAgICAgIH0KCiAgICAgIC8qIHB1dCBpbiB0aGUgZHJlcC4gRklYTUU6IGlzIHRoaXMgbW9yZSB1bml2ZXJzYWxseSBhcHBsaWNhYmxlPwogICAgICAgICBwZXJoYXBzIHdlIHNob3VsZCBtb3ZlIHRoaXMgb3V0d2FyZC4uLiAqLwogICAgICBtc2ctPkRhdGFSZXByZXNlbnRhdGlvbiA9IAogICAgICAgIE1BS0VMT05HKCBNQUtFV09SRChoZHItPmNvbW1vbi5kcmVwWzBdLCBoZHItPmNvbW1vbi5kcmVwWzFdKSwKICAgICAgICAgICAgICAgICAgTUFLRVdPUkQoaGRyLT5jb21tb24uZHJlcFsyXSwgaGRyLT5jb21tb24uZHJlcFszXSkpOwoKICAgICAgLyogZGlzcGF0Y2ggKi8KICAgICAgX19UUlkgewogICAgICAgIGlmIChmdW5jKSBmdW5jKG1zZyk7CiAgICAgIH0gX19FWENFUFQocnBjX2ZpbHRlcikgewogICAgICAgIGlmIChtc2ctPkJ1ZmZlciAhPSBidWYpIElfUnBjRnJlZUJ1ZmZlcihtc2cpOwogICAgICAgIC8qIHRoaXMgd2lsbCBjYXVzZSBhIGZhaWx1cmUgcGFja2V0IHRvIGJlIHNlbnQgaW4gSV9ScGNTZW5kICovCiAgICAgICAgbXNnLT5ScGNGbGFncyB8PSBXSU5FX1JQQ0ZMQUdfRVhDRVBUSU9OOwogICAgICAgIG1zZy0+QnVmZmVyTGVuZ3RoID0gc2l6ZW9mKERXT1JEKTsKICAgICAgICBJX1JwY0dldEJ1ZmZlcihtc2cpOwogICAgICAgICooRFdPUkQqKW1zZy0+QnVmZmVyID0gR2V0RXhjZXB0aW9uQ29kZSgpOwogICAgICB9IF9fRU5EVFJZCgogICAgICAvKiBzZW5kIHJlc3BvbnNlIHBhY2tldCAqLwogICAgICBJX1JwY1NlbmQobXNnKTsKCiAgICAgIG1zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb24gPSBOVUxMOwogICAgICBSUENSVDRfcmVsZWFzZV9zZXJ2ZXJfaW50ZXJmYWNlKHNpZik7CgogICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICBGSVhNRSgidW5oYW5kbGVkIHBhY2tldCB0eXBlICV1XG4iLCBoZHItPmNvbW1vbi5wdHlwZSk7CiAgICAgIGJyZWFrOwogIH0KCmZhaWw6CiAgLyogY2xlYW4gdXAgKi8KICBpZiAobXNnLT5CdWZmZXIgPT0gYnVmKSBtc2ctPkJ1ZmZlciA9IE5VTEw7CiAgVFJBQ0UoImZyZWVpbmcgQnVmZmVyPSVwXG4iLCBidWYpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGJ1Zik7CiAgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKG1zZy0+SGFuZGxlKTsKICBtc2ctPkhhbmRsZSA9IDA7CiAgSV9ScGNGcmVlQnVmZmVyKG1zZyk7CiAgbXNnLT5CdWZmZXIgPSBOVUxMOwogIFJQQ1JUNF9GcmVlSGVhZGVyKGhkcik7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXNnKTsKfQoKc3RhdGljIERXT1JEIENBTExCQUNLIFJQQ1JUNF93b3JrZXJfdGhyZWFkKExQVk9JRCB0aGVfYXJnKQp7CiAgUnBjUGFja2V0ICpwa3QgPSB0aGVfYXJnOwogIFJQQ1JUNF9wcm9jZXNzX3BhY2tldChwa3QtPmNvbm4sIHBrdC0+aGRyLCBwa3QtPm1zZyk7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGt0KTsKICByZXR1cm4gMDsKfQoKc3RhdGljIERXT1JEIENBTExCQUNLIFJQQ1JUNF9pb190aHJlYWQoTFBWT0lEIHRoZV9hcmcpCnsKICBScGNDb25uZWN0aW9uKiBjb25uID0gKFJwY0Nvbm5lY3Rpb24qKXRoZV9hcmc7CiAgUnBjUGt0SGRyICpoZHI7CiAgUnBjQmluZGluZyAqcGJpbmQ7CiAgUlBDX01FU1NBR0UgKm1zZzsKICBSUENfU1RBVFVTIHN0YXR1czsKICBScGNQYWNrZXQgKnBhY2tldDsKCiAgVFJBQ0UoIiglcClcbiIsIGNvbm4pOwoKICBmb3IgKDs7KSB7CiAgICBtc2cgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJQQ19NRVNTQUdFKSk7CgogICAgLyogY3JlYXRlIHRlbXBvcmFyeSBiaW5kaW5nIGZvciBkaXNwYXRjaCwgaXQgd2lsbCBiZSBmcmVlZCBpbgogICAgICogUlBDUlQ0X3Byb2Nlc3NfcGFja2V0ICovCiAgICBSUENSVDRfTWFrZUJpbmRpbmcoJnBiaW5kLCBjb25uKTsKICAgIG1zZy0+SGFuZGxlID0gKFJQQ19CSU5ESU5HX0hBTkRMRSlwYmluZDsKCiAgICBzdGF0dXMgPSBSUENSVDRfUmVjZWl2ZShjb25uLCAmaGRyLCBtc2cpOwogICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgewogICAgICBXQVJOKCJyZWNlaXZlIGZhaWxlZCB3aXRoIGVycm9yICVseFxuIiwgc3RhdHVzKTsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXNnKTsKICAgICAgYnJlYWs7CiAgICB9CgojaWYgMAogICAgUlBDUlQ0X3Byb2Nlc3NfcGFja2V0KGNvbm4sIGhkciwgbXNnKTsKI2Vsc2UKICAgIHBhY2tldCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoUnBjUGFja2V0KSk7CiAgICBwYWNrZXQtPmNvbm4gPSBjb25uOwogICAgcGFja2V0LT5oZHIgPSBoZHI7CiAgICBwYWNrZXQtPm1zZyA9IG1zZzsKICAgIFF1ZXVlVXNlcldvcmtJdGVtKFJQQ1JUNF93b3JrZXJfdGhyZWFkLCBwYWNrZXQsIFdUX0VYRUNVVEVMT05HRlVOQ1RJT04pOwojZW5kaWYKICAgIG1zZyA9IE5VTEw7CiAgfQogIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihjb25uKTsKICByZXR1cm4gMDsKfQoKdm9pZCBSUENSVDRfbmV3X2NsaWVudChScGNDb25uZWN0aW9uKiBjb25uKQp7CiAgSEFORExFIHRocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBSUENSVDRfaW9fdGhyZWFkLCBjb25uLCAwLCBOVUxMKTsKICBpZiAoIXRocmVhZCkgewogICAgRFdPUkQgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICBFUlIoImZhaWxlZCB0byBjcmVhdGUgdGhyZWFkLCBlcnJvcj0lMDh4XG4iLCBlcnIpOwogICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKGNvbm4pOwogIH0KICAvKiB3ZSBjb3VsZCBzZXQgY29ubi0+dGhyZWFkLCBidXQgdGhlbiB3ZSdkIGhhdmUgdG8gbWFrZSB0aGUgaW9fdGhyZWFkIHdhaXQKICAgKiBmb3IgdGhhdCwgb3RoZXJ3aXNlIHRoZSB0aHJlYWQgbWlnaHQgZmluaXNoLCBkZXN0cm95IHRoZSBjb25uZWN0aW9uLCBhbmQKICAgKiBmcmVlIHRoZSBtZW1vcnkgd2UnZCB3cml0ZSB0byBiZWZvcmUgd2UgZGlkLCBjYXVzaW5nIGNyYXNoZXMgYW5kIHN0dWZmIC0KICAgKiBzbyBsZXQncyBpbXBsZW1lbnQgdGhhdCBsYXRlciwgd2hlbiB3ZSByZWFsbHkgbmVlZCBjb25uLT50aHJlYWQgKi8KCiAgQ2xvc2VIYW5kbGUoIHRocmVhZCApOwp9CgpzdGF0aWMgRFdPUkQgQ0FMTEJBQ0sgUlBDUlQ0X3NlcnZlcl90aHJlYWQoTFBWT0lEIHRoZV9hcmcpCnsKICBpbnQgcmVzOwogIHVuc2lnbmVkIGludCBjb3VudDsKICB2b2lkICpvYmpzID0gTlVMTDsKICBScGNTZXJ2ZXJQcm90c2VxKiBjcHMgPSB0aGVfYXJnOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CiAgQk9PTCBzZXRfcmVhZHlfZXZlbnQgPSBGQUxTRTsKCiAgVFJBQ0UoIih0aGVfYXJnID09IF4lcClcbiIsIHRoZV9hcmcpOwoKICBmb3IgKDs7KSB7CiAgICBvYmpzID0gY3BzLT5vcHMtPmdldF93YWl0X2FycmF5KGNwcywgb2JqcywgJmNvdW50KTsKCiAgICBpZiAoc2V0X3JlYWR5X2V2ZW50KQogICAgewogICAgICAgIC8qIHNpZ25hbCB0byBmdW5jdGlvbiB0aGF0IGNoYW5nZWQgc3RhdGUgdGhhdCB3ZSBhcmUgbm93IHN5bmMnZWQgKi8KICAgICAgICBTZXRFdmVudChjcHMtPnNlcnZlcl9yZWFkeV9ldmVudCk7CiAgICAgICAgc2V0X3JlYWR5X2V2ZW50ID0gRkFMU0U7CiAgICB9CgogICAgLyogc3RhcnQgd2FpdGluZyAqLwogICAgcmVzID0gY3BzLT5vcHMtPndhaXRfZm9yX25ld19jb25uZWN0aW9uKGNwcywgY291bnQsIG9ianMpOwogICAgaWYgKHJlcyA9PSAtMSkKICAgICAgYnJlYWs7CiAgICBlbHNlIGlmIChyZXMgPT0gMCkKICAgIHsKICAgICAgaWYgKCFzdGRfbGlzdGVuKQogICAgICB7CiAgICAgICAgU2V0RXZlbnQoY3BzLT5zZXJ2ZXJfcmVhZHlfZXZlbnQpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIHNldF9yZWFkeV9ldmVudCA9IFRSVUU7CiAgICB9CiAgfQogIGNwcy0+b3BzLT5mcmVlX3dhaXRfYXJyYXkoY3BzLCBvYmpzKTsKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY3BzLT5jcyk7CiAgLyogY2xvc2UgY29ubmVjdGlvbnMgKi8KICBjb25uID0gY3BzLT5jb25uOwogIHdoaWxlIChjb25uKSB7CiAgICBSUENSVDRfQ2xvc2VDb25uZWN0aW9uKGNvbm4pOwogICAgY29ubiA9IGNvbm4tPk5leHQ7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZjcHMtPmNzKTsKICByZXR1cm4gMDsKfQoKLyogdGVsbHMgdGhlIHNlcnZlciB0aHJlYWQgdGhhdCB0aGUgc3RhdGUgaGFzIGNoYW5nZWQgYW5kIHdhaXRzIGZvciBpdCB0bwogKiBtYWtlIHRoZSBjaGFuZ2VzICovCnN0YXRpYyB2b2lkIFJQQ1JUNF9zeW5jX3dpdGhfc2VydmVyX3RocmVhZChScGNTZXJ2ZXJQcm90c2VxICpwcykKewogIC8qIG1ha2Ugc3VyZSB3ZSBhcmUgdGhlIG9ubHkgdGhyZWFkIHN5bmMnaW5nIHRoZSBzZXJ2ZXIgc3RhdGUsIG90aGVyd2lzZQogICAqIHRoZXJlIGlzIGEgcmFjZSB3aXRoIHRoZSBzZXJ2ZXIgdGhyZWFkIHNldHRpbmcgYW4gb2xkZXIgc3RhdGUgYW5kIHNldHRpbmcKICAgKiB0aGUgc2VydmVyX3JlYWR5X2V2ZW50IHdoZW4gdGhlIG5ldyBzdGF0ZSBoYXNuJ3QgeWV0IGJlZW4gYXBwbGllZCAqLwogIFdhaXRGb3JTaW5nbGVPYmplY3QocHMtPm1ncl9tdXRleCwgSU5GSU5JVEUpOwoKICBwcy0+b3BzLT5zaWduYWxfc3RhdGVfY2hhbmdlZChwcyk7CgogIC8qIHdhaXQgZm9yIHNlcnZlciB0aHJlYWQgdG8gbWFrZSB0aGUgcmVxdWVzdGVkIGNoYW5nZXMgYmVmb3JlIHJldHVybmluZyAqLwogIFdhaXRGb3JTaW5nbGVPYmplY3QocHMtPnNlcnZlcl9yZWFkeV9ldmVudCwgSU5GSU5JVEUpOwoKICBSZWxlYXNlTXV0ZXgocHMtPm1ncl9tdXRleCk7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUNF9zdGFydF9saXN0ZW5fcHJvdHNlcShScGNTZXJ2ZXJQcm90c2VxICpwcywgQk9PTCBhdXRvX2xpc3RlbikKewogIFJQQ19TVEFUVVMgc3RhdHVzID0gUlBDX1NfT0s7CiAgSEFORExFIHNlcnZlcl90aHJlYWQ7CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogIGlmIChwcy0+aXNfbGlzdGVuaW5nKSBnb3RvIGRvbmU7CgogIGlmICghcHMtPm1ncl9tdXRleCkgcHMtPm1ncl9tdXRleCA9IENyZWF0ZU11dGV4VyhOVUxMLCBGQUxTRSwgTlVMTCk7CiAgaWYgKCFwcy0+c2VydmVyX3JlYWR5X2V2ZW50KSBwcy0+c2VydmVyX3JlYWR5X2V2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CiAgc2VydmVyX3RocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBSUENSVDRfc2VydmVyX3RocmVhZCwgcHMsIDAsIE5VTEwpOwogIGlmICghc2VydmVyX3RocmVhZCkKICB7CiAgICBzdGF0dXMgPSBSUENfU19PVVRfT0ZfUkVTT1VSQ0VTOwogICAgZ290byBkb25lOwogIH0KICBwcy0+aXNfbGlzdGVuaW5nID0gVFJVRTsKICBDbG9zZUhhbmRsZShzZXJ2ZXJfdGhyZWFkKTsKCmRvbmU6CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CiAgcmV0dXJuIHN0YXR1czsKfQoKc3RhdGljIFJQQ19TVEFUVVMgUlBDUlQ0X3N0YXJ0X2xpc3RlbihCT09MIGF1dG9fbGlzdGVuKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXMgPSBSUENfU19BTFJFQURZX0xJU1RFTklORzsKICBScGNTZXJ2ZXJQcm90c2VxICpjcHM7CgogIFRSQUNFKCJcbiIpOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKICBpZiAoYXV0b19saXN0ZW4gfHwgKG1hbnVhbF9saXN0ZW5fY291bnQrKyA9PSAwKSkKICB7CiAgICBzdGF0dXMgPSBSUENfU19PSzsKICAgIGlmICgrK2xpc3Rlbl9jb3VudCA9PSAxKQogICAgICBzdGRfbGlzdGVuID0gVFJVRTsKICB9CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogIGlmIChzdGRfbGlzdGVuKQogIHsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogICAgTElTVF9GT1JfRUFDSF9FTlRSWShjcHMsICZwcm90c2VxcywgUnBjU2VydmVyUHJvdHNlcSwgZW50cnkpCiAgICB7CiAgICAgIHN0YXR1cyA9IFJQQ1JUNF9zdGFydF9saXN0ZW5fcHJvdHNlcShjcHMsIFRSVUUpOwogICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgIGJyZWFrOwogICAgICAKICAgICAgLyogbWFrZSBzdXJlIHNlcnZlciBpcyBhY3R1YWxseSBsaXN0ZW5pbmcgb24gdGhlIGludGVyZmFjZSBiZWZvcmUKICAgICAgICogcmV0dXJuaW5nICovCiAgICAgIFJQQ1JUNF9zeW5jX3dpdGhfc2VydmVyX3RocmVhZChjcHMpOwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgfQoKICByZXR1cm4gc3RhdHVzOwp9CgpzdGF0aWMgdm9pZCBSUENSVDRfc3RvcF9saXN0ZW4oQk9PTCBhdXRvX2xpc3RlbikKewogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogIGlmIChhdXRvX2xpc3RlbiB8fCAoLS1tYW51YWxfbGlzdGVuX2NvdW50ID09IDApKQogIHsKICAgIGlmIChsaXN0ZW5fY291bnQgIT0gMCAmJiAtLWxpc3Rlbl9jb3VudCA9PSAwKSB7CiAgICAgIFJwY1NlcnZlclByb3RzZXEgKmNwczsKCiAgICAgIHN0ZF9saXN0ZW4gPSBGQUxTRTsKICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogICAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGNwcywgJnByb3RzZXFzLCBScGNTZXJ2ZXJQcm90c2VxLCBlbnRyeSkKICAgICAgICBSUENSVDRfc3luY193aXRoX3NlcnZlcl90aHJlYWQoY3BzKTsKCiAgICAgIHJldHVybjsKICAgIH0KICAgIGFzc2VydChsaXN0ZW5fY291bnQgPj0gMCk7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfdXNlX3Byb3RzZXEoUnBjU2VydmVyUHJvdHNlcSogcHMsIExQU1RSIGVuZHBvaW50KQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIHN0YXR1cyA9IHBzLT5vcHMtPm9wZW5fZW5kcG9pbnQocHMsIGVuZHBvaW50KTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgcmV0dXJuIHN0YXR1czsKCiAgaWYgKHN0ZF9saXN0ZW4pCiAgewogICAgc3RhdHVzID0gUlBDUlQ0X3N0YXJ0X2xpc3Rlbl9wcm90c2VxKHBzLCBGQUxTRSk7CiAgICBpZiAoc3RhdHVzID09IFJQQ19TX09LKQogICAgICBSUENSVDRfc3luY193aXRoX3NlcnZlcl90aHJlYWQocHMpOwogIH0KCiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlcklucUJpbmRpbmdzIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlcklucUJpbmRpbmdzKCBSUENfQklORElOR19WRUNUT1IqKiBCaW5kaW5nVmVjdG9yICkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIERXT1JEIGNvdW50OwogIFJwY1NlcnZlclByb3RzZXEqIHBzOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CgogIGlmIChCaW5kaW5nVmVjdG9yKQogICAgVFJBQ0UoIigqQmluZGluZ1ZlY3RvciA9PSBeJXApXG4iLCAqQmluZGluZ1ZlY3Rvcik7CiAgZWxzZQogICAgRVJSKCIoQmluZGluZ1ZlY3RvciA9PSBOVUxMISE/KVxuIik7CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIC8qIGNvdW50IGNvbm5lY3Rpb25zICovCiAgY291bnQgPSAwOwogIExJU1RfRk9SX0VBQ0hfRU5UUlkocHMsICZwcm90c2VxcywgUnBjU2VydmVyUHJvdHNlcSwgZW50cnkpIHsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZwcy0+Y3MpOwogICAgY29ubiA9IHBzLT5jb25uOwogICAgd2hpbGUgKGNvbm4pIHsKICAgICAgY291bnQrKzsKICAgICAgY29ubiA9IGNvbm4tPk5leHQ7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcHMtPmNzKTsKICB9CiAgaWYgKGNvdW50KSB7CiAgICAvKiBleHBvcnQgYmluZGluZ3MgKi8KICAgICpCaW5kaW5nVmVjdG9yID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihSUENfQklORElOR19WRUNUT1IpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKFJQQ19CSU5ESU5HX0hBTkRMRSkqKGNvdW50LTEpKTsKICAgICgqQmluZGluZ1ZlY3RvciktPkNvdW50ID0gY291bnQ7CiAgICBjb3VudCA9IDA7CiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKHBzLCAmcHJvdHNlcXMsIFJwY1NlcnZlclByb3RzZXEsIGVudHJ5KSB7CiAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZwcy0+Y3MpOwogICAgICBjb25uID0gcHMtPmNvbm47CiAgICAgIHdoaWxlIChjb25uKSB7CiAgICAgICBSUENSVDRfTWFrZUJpbmRpbmcoKFJwY0JpbmRpbmcqKikmKCpCaW5kaW5nVmVjdG9yKS0+QmluZGluZ0hbY291bnRdLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm4pOwogICAgICAgY291bnQrKzsKICAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgICB9CiAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZwcy0+Y3MpOwogICAgfQogICAgc3RhdHVzID0gUlBDX1NfT0s7CiAgfSBlbHNlIHsKICAgICpCaW5kaW5nVmVjdG9yID0gTlVMTDsKICAgIHN0YXR1cyA9IFJQQ19TX05PX0JJTkRJTkdTOwogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcUVwQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVc2VQcm90c2VxRXBBKCBSUENfQ1NUUiBQcm90c2VxLCBVSU5UIE1heENhbGxzLCBSUENfQ1NUUiBFbmRwb2ludCwgTFBWT0lEIFNlY3VyaXR5RGVzY3JpcHRvciApCnsKICBSUENfUE9MSUNZIHBvbGljeTsKICAKICBUUkFDRSggIiglcywldSwlcywlcClcbiIsIFByb3RzZXEsIE1heENhbGxzLCBFbmRwb2ludCwgU2VjdXJpdHlEZXNjcmlwdG9yICk7CiAgCiAgLyogVGhpcyBzaG91bGQgcHJvdmlkZSB0aGUgZGVmYXVsdCBiZWhhdmlvdXIgKi8KICBwb2xpY3kuTGVuZ3RoICAgICAgICA9IHNpemVvZiggcG9saWN5ICk7CiAgcG9saWN5LkVuZHBvaW50RmxhZ3MgPSAwOwogIHBvbGljeS5OSUNGbGFncyAgICAgID0gMDsKICAKICByZXR1cm4gUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhBKCBQcm90c2VxLCBNYXhDYWxscywgRW5kcG9pbnQsIFNlY3VyaXR5RGVzY3JpcHRvciwgJnBvbGljeSApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcUVwVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVc2VQcm90c2VxRXBXKCBSUENfV1NUUiBQcm90c2VxLCBVSU5UIE1heENhbGxzLCBSUENfV1NUUiBFbmRwb2ludCwgTFBWT0lEIFNlY3VyaXR5RGVzY3JpcHRvciApCnsKICBSUENfUE9MSUNZIHBvbGljeTsKICAKICBUUkFDRSggIiglcywldSwlcywlcClcbiIsIGRlYnVnc3RyX3coIFByb3RzZXEgKSwgTWF4Q2FsbHMsIGRlYnVnc3RyX3coIEVuZHBvaW50ICksIFNlY3VyaXR5RGVzY3JpcHRvciApOwogIAogIC8qIFRoaXMgc2hvdWxkIHByb3ZpZGUgdGhlIGRlZmF1bHQgYmVoYXZpb3VyICovCiAgcG9saWN5Lkxlbmd0aCAgICAgICAgPSBzaXplb2YoIHBvbGljeSApOwogIHBvbGljeS5FbmRwb2ludEZsYWdzID0gMDsKICBwb2xpY3kuTklDRmxhZ3MgICAgICA9IDA7CiAgCiAgcmV0dXJuIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4VyggUHJvdHNlcSwgTWF4Q2FsbHMsIEVuZHBvaW50LCBTZWN1cml0eURlc2NyaXB0b3IsICZwb2xpY3kgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIGFsbG9jX3NlcnZlcnByb3Rvc2VxIChpbnRlcm5hbCkKICoKICogTXVzdCBiZSBjYWxsZWQgd2l0aCBzZXJ2ZXJfY3MgaGVsZC4KICovCnN0YXRpYyBSUENfU1RBVFVTIGFsbG9jX3NlcnZlcnByb3Rvc2VxKFVJTlQgTWF4Q2FsbHMsIGNoYXIgKlByb3RzZXEsIFJwY1NlcnZlclByb3RzZXEgKipwcykKewogIGNvbnN0IHN0cnVjdCBwcm90c2VxX29wcyAqb3BzID0gcnBjcnQ0X2dldF9wcm90c2VxX29wcyhQcm90c2VxKTsKCiAgaWYgKCFvcHMpCiAgewogICAgRklYTUUoInByb3RzZXEgJXMgbm90IHN1cHBvcnRlZFxuIiwgZGVidWdzdHJfYShQcm90c2VxKSk7CiAgICByZXR1cm4gUlBDX1NfUFJPVFNFUV9OT1RfU1VQUE9SVEVEOwogIH0KCiAgKnBzID0gb3BzLT5hbGxvYygpOwogIGlmICghKnBzKQogICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgKCpwcyktPk1heENhbGxzID0gTWF4Q2FsbHM7CiAgKCpwcyktPlByb3RzZXEgPSBQcm90c2VxOwogICgqcHMpLT5vcHMgPSBvcHM7CiAgKCpwcyktPk1heENhbGxzID0gMDsKICAoKnBzKS0+Y29ubiA9IE5VTEw7CiAgSW5pdGlhbGl6ZUNyaXRpY2FsU2VjdGlvbigmKCpwcyktPmNzKTsKICAoKnBzKS0+aXNfbGlzdGVuaW5nID0gRkFMU0U7CiAgKCpwcyktPm1ncl9tdXRleCA9IE5VTEw7CiAgKCpwcyktPnNlcnZlcl9yZWFkeV9ldmVudCA9IE5VTEw7CgogIGxpc3RfYWRkX2hlYWQoJnByb3RzZXFzLCAmKCpwcyktPmVudHJ5KTsKCiAgVFJBQ0UoIm5ldyBwcm90c2VxICVwIGNyZWF0ZWQgZm9yICVzXG4iLCAqcHMsIFByb3RzZXEpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qIEZpbmRzIGEgZ2l2ZW4gcHJvdHNlcSBvciBjcmVhdGVzIGEgbmV3IG9uZSBpZiBvbmUgZG9lc24ndCBhbHJlYWR5IGV4aXN0ICovCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUNF9nZXRfb3JfY3JlYXRlX3NlcnZlcnByb3RzZXEoVUlOVCBNYXhDYWxscywgY2hhciAqUHJvdHNlcSwgUnBjU2VydmVyUHJvdHNlcSAqKnBzKQp7CiAgICBSUENfU1RBVFVTIHN0YXR1czsKICAgIFJwY1NlcnZlclByb3RzZXEgKmNwczsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKCiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGNwcywgJnByb3RzZXFzLCBScGNTZXJ2ZXJQcm90c2VxLCBlbnRyeSkKICAgICAgICBpZiAoIXN0cmNtcChjcHMtPlByb3RzZXEsIFByb3RzZXEpKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoImZvdW5kIGV4aXN0aW5nIHByb3RzZXEgb2JqZWN0IGZvciAlc1xuIiwgUHJvdHNlcSk7CiAgICAgICAgICAgICpwcyA9IGNwczsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgICAgICAgICAgIHJldHVybiBTX09LOwogICAgICAgIH0KCiAgICBzdGF0dXMgPSBhbGxvY19zZXJ2ZXJwcm90b3NlcShNYXhDYWxscywgUHJvdHNlcSwgcHMpOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeEEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhBKCBSUENfQ1NUUiBQcm90c2VxLCBVSU5UIE1heENhbGxzLCBSUENfQ1NUUiBFbmRwb2ludCwgTFBWT0lEIFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1BPTElDWSBscFBvbGljeSApCnsKICBjaGFyICpzenBzID0gKGNoYXIqKVByb3RzZXEsICpzemVwID0gKGNoYXIqKUVuZHBvaW50OwogIFJwY1NlcnZlclByb3RzZXEqIHBzOwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBUUkFDRSgiKCVzLCV1LCVzLCVwLHsldSwlbHUsJWx1fSlcbiIsIGRlYnVnc3RyX2Eoc3pwcyksIE1heENhbGxzLAogICAgICAgZGVidWdzdHJfYShzemVwKSwgU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgbHBQb2xpY3ktPkxlbmd0aCwgbHBQb2xpY3ktPkVuZHBvaW50RmxhZ3MsIGxwUG9saWN5LT5OSUNGbGFncyApOwoKICBzdGF0dXMgPSBSUENSVDRfZ2V0X29yX2NyZWF0ZV9zZXJ2ZXJwcm90c2VxKE1heENhbGxzLCBSUENSVDRfc3RyZHVwQShzenBzKSwgJnBzKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgcmV0dXJuIHN0YXR1czsKCiAgcmV0dXJuIFJQQ1JUNF91c2VfcHJvdHNlcShwcywgc3plcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeFcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhXKCBSUENfV1NUUiBQcm90c2VxLCBVSU5UIE1heENhbGxzLCBSUENfV1NUUiBFbmRwb2ludCwgTFBWT0lEIFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX1BPTElDWSBscFBvbGljeSApCnsKICBScGNTZXJ2ZXJQcm90c2VxKiBwczsKICBSUENfU1RBVFVTIHN0YXR1czsKICBMUFNUUiBFbmRwb2ludEE7CgogIFRSQUNFKCIoJXMsJXUsJXMsJXAseyV1LCVsdSwlbHV9KVxuIiwgZGVidWdzdHJfdyggUHJvdHNlcSApLCBNYXhDYWxscywKICAgICAgIGRlYnVnc3RyX3coIEVuZHBvaW50ICksIFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgIGxwUG9saWN5LT5MZW5ndGgsIGxwUG9saWN5LT5FbmRwb2ludEZsYWdzLCBscFBvbGljeS0+TklDRmxhZ3MgKTsKCiAgc3RhdHVzID0gUlBDUlQ0X2dldF9vcl9jcmVhdGVfc2VydmVycHJvdHNlcShNYXhDYWxscywgUlBDUlQ0X3N0cmR1cFd0b0EoUHJvdHNlcSksICZwcyk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgIHJldHVybiBzdGF0dXM7CgogIEVuZHBvaW50QSA9IFJQQ1JUNF9zdHJkdXBXdG9BKEVuZHBvaW50KTsKICBzdGF0dXMgPSBSUENSVDRfdXNlX3Byb3RzZXEocHMsIEVuZHBvaW50QSk7CiAgUlBDUlQ0X3N0cmZyZWUoRW5kcG9pbnRBKTsKICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcUEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUEoUlBDX0NTVFIgUHJvdHNlcSwgdW5zaWduZWQgaW50IE1heENhbGxzLCB2b2lkICpTZWN1cml0eURlc2NyaXB0b3IpCnsKICBUUkFDRSgiKFByb3RzZXEgPT0gJXMsIE1heENhbGxzID09ICVkLCBTZWN1cml0eURlc2NyaXB0b3IgPT0gXiVwKVxuIiwgZGVidWdzdHJfYSgoY2hhciopUHJvdHNlcSksIE1heENhbGxzLCBTZWN1cml0eURlc2NyaXB0b3IpOwogIHJldHVybiBScGNTZXJ2ZXJVc2VQcm90c2VxRXBBKFByb3RzZXEsIE1heENhbGxzLCBOVUxMLCBTZWN1cml0eURlc2NyaXB0b3IpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcVcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcVcoUlBDX1dTVFIgUHJvdHNlcSwgdW5zaWduZWQgaW50IE1heENhbGxzLCB2b2lkICpTZWN1cml0eURlc2NyaXB0b3IpCnsKICBUUkFDRSgiUHJvdHNlcSA9PSAlcywgTWF4Q2FsbHMgPT0gJWQsIFNlY3VyaXR5RGVzY3JpcHRvciA9PSBeJXApXG4iLCBkZWJ1Z3N0cl93KFByb3RzZXEpLCBNYXhDYWxscywgU2VjdXJpdHlEZXNjcmlwdG9yKTsKICByZXR1cm4gUnBjU2VydmVyVXNlUHJvdHNlcUVwVyhQcm90c2VxLCBNYXhDYWxscywgTlVMTCwgU2VjdXJpdHlEZXNjcmlwdG9yKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVySWYgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyUmVnaXN0ZXJJZiggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBSUENfTUdSX0VQViogTWdyRXB2ICkKewogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBNZ3JFcHYpOwogIHJldHVybiBScGNTZXJ2ZXJSZWdpc3RlcklmMiggSWZTcGVjLCBNZ3JUeXBlVXVpZCwgTWdyRXB2LCAwLCBSUENfQ19MSVNURU5fTUFYX0NBTExTX0RFRkFVTFQsIChVSU5UKS0xLCBOVUxMICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJSZWdpc3RlcklmRXggKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyUmVnaXN0ZXJJZkV4KCBSUENfSUZfSEFORExFIElmU3BlYywgVVVJRCogTWdyVHlwZVV1aWQsIFJQQ19NR1JfRVBWKiBNZ3JFcHYsCiAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBGbGFncywgVUlOVCBNYXhDYWxscywgUlBDX0lGX0NBTExCQUNLX0ZOKiBJZkNhbGxiYWNrRm4gKQp7CiAgVFJBQ0UoIiglcCwlcywlcCwldSwldSwlcClcbiIsIElmU3BlYywgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIE1nckVwdiwgRmxhZ3MsIE1heENhbGxzLCBJZkNhbGxiYWNrRm4pOwogIHJldHVybiBScGNTZXJ2ZXJSZWdpc3RlcklmMiggSWZTcGVjLCBNZ3JUeXBlVXVpZCwgTWdyRXB2LCBGbGFncywgTWF4Q2FsbHMsIChVSU5UKS0xLCBJZkNhbGxiYWNrRm4gKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVySWYyIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVySWYyKCBSUENfSUZfSEFORExFIElmU3BlYywgVVVJRCogTWdyVHlwZVV1aWQsIFJQQ19NR1JfRVBWKiBNZ3JFcHYsCiAgICAgICAgICAgICAgICAgICAgICBVSU5UIEZsYWdzLCBVSU5UIE1heENhbGxzLCBVSU5UIE1heFJwY1NpemUsIFJQQ19JRl9DQUxMQkFDS19GTiogSWZDYWxsYmFja0ZuICkKewogIFBSUENfU0VSVkVSX0lOVEVSRkFDRSBJZiA9IChQUlBDX1NFUlZFUl9JTlRFUkZBQ0UpSWZTcGVjOwogIFJwY1NlcnZlckludGVyZmFjZSogc2lmOwogIHVuc2lnbmVkIGludCBpOwoKICBUUkFDRSgiKCVwLCVzLCVwLCV1LCV1LCV1LCVwKVxuIiwgSWZTcGVjLCBkZWJ1Z3N0cl9ndWlkKE1nclR5cGVVdWlkKSwgTWdyRXB2LCBGbGFncywgTWF4Q2FsbHMsCiAgICAgICAgIE1heFJwY1NpemUsIElmQ2FsbGJhY2tGbik7CiAgVFJBQ0UoIiBpbnRlcmZhY2UgaWQ6ICVzICVkLiVkXG4iLCBkZWJ1Z3N0cl9ndWlkKCZJZi0+SW50ZXJmYWNlSWQuU3ludGF4R1VJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZi0+SW50ZXJmYWNlSWQuU3ludGF4VmVyc2lvbi5NYWpvclZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZi0+SW50ZXJmYWNlSWQuU3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb24pOwogIFRSQUNFKCIgdHJhbnNmZXIgc3ludGF4OiAlcyAlZC4lZFxuIiwgZGVidWdzdHJfZ3VpZCgmSWYtPlRyYW5zZmVyU3ludGF4LlN5bnRheEdVSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYtPlRyYW5zZmVyU3ludGF4LlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYtPlRyYW5zZmVyU3ludGF4LlN5bnRheFZlcnNpb24uTWlub3JWZXJzaW9uKTsKICBUUkFDRSgiIGRpc3BhdGNoIHRhYmxlOiAlcFxuIiwgSWYtPkRpc3BhdGNoVGFibGUpOwogIGlmIChJZi0+RGlzcGF0Y2hUYWJsZSkgewogICAgVFJBQ0UoIiAgZGlzcGF0Y2ggdGFibGUgY291bnQ6ICVkXG4iLCBJZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZUNvdW50KTsKICAgIGZvciAoaT0wOyBpPElmLT5EaXNwYXRjaFRhYmxlLT5EaXNwYXRjaFRhYmxlQ291bnQ7IGkrKykgewogICAgICBUUkFDRSgiICAgZW50cnkgJWQ6ICVwXG4iLCBpLCBJZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZVtpXSk7CiAgICB9CiAgICBUUkFDRSgiICByZXNlcnZlZDogJWxkXG4iLCBJZi0+RGlzcGF0Y2hUYWJsZS0+UmVzZXJ2ZWQpOwogIH0KICBUUkFDRSgiIHByb3RzZXEgZW5kcG9pbnQgY291bnQ6ICVkXG4iLCBJZi0+UnBjUHJvdHNlcUVuZHBvaW50Q291bnQpOwogIFRSQUNFKCIgZGVmYXVsdCBtYW5hZ2VyIGVwdjogJXBcbiIsIElmLT5EZWZhdWx0TWFuYWdlckVwdik7CiAgVFJBQ0UoIiBpbnRlcnByZXRlciBpbmZvOiAlcFxuIiwgSWYtPkludGVycHJldGVySW5mbyk7CgogIHNpZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUnBjU2VydmVySW50ZXJmYWNlKSk7CiAgc2lmLT5JZiAgICAgICAgICAgPSBJZjsKICBpZiAoTWdyVHlwZVV1aWQpIHsKICAgIG1lbWNweSgmc2lmLT5NZ3JUeXBlVXVpZCwgTWdyVHlwZVV1aWQsIHNpemVvZihVVUlEKSk7CiAgICBzaWYtPk1nckVwdiAgICAgICA9IE1nckVwdjsKICB9IGVsc2UgewogICAgbWVtc2V0KCZzaWYtPk1nclR5cGVVdWlkLCAwLCBzaXplb2YoVVVJRCkpOwogICAgc2lmLT5NZ3JFcHYgICAgICAgPSBJZi0+RGVmYXVsdE1hbmFnZXJFcHY7CiAgfQogIHNpZi0+RmxhZ3MgICAgICAgID0gRmxhZ3M7CiAgc2lmLT5NYXhDYWxscyAgICAgPSBNYXhDYWxsczsKICBzaWYtPk1heFJwY1NpemUgICA9IE1heFJwY1NpemU7CiAgc2lmLT5JZkNhbGxiYWNrRm4gPSBJZkNhbGxiYWNrRm47CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIGxpc3RfYWRkX2hlYWQoJnNlcnZlcl9pbnRlcmZhY2VzLCAmc2lmLT5lbnRyeSk7CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CgogIGlmIChzaWYtPkZsYWdzICYgUlBDX0lGX0FVVE9MSVNURU4pCiAgICAgIFJQQ1JUNF9zdGFydF9saXN0ZW4oVFJVRSk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVucmVnaXN0ZXJJZiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVbnJlZ2lzdGVySWYoIFJQQ19JRl9IQU5ETEUgSWZTcGVjLCBVVUlEKiBNZ3JUeXBlVXVpZCwgVUlOVCBXYWl0Rm9yQ2FsbHNUb0NvbXBsZXRlICkKewogIFBSUENfU0VSVkVSX0lOVEVSRkFDRSBJZiA9IChQUlBDX1NFUlZFUl9JTlRFUkZBQ0UpSWZTcGVjOwogIEhBTkRMRSBldmVudCA9IE5VTEw7CiAgQk9PTCBmb3VuZCA9IEZBTFNFOwogIEJPT0wgY29tcGxldGVkID0gVFJVRTsKICBScGNTZXJ2ZXJJbnRlcmZhY2UgKmNpZjsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgVFJBQ0UoIihJZlNwZWMgPT0gKFJQQ19JRl9IQU5ETEUpXiVwICglcyksIE1nclR5cGVVdWlkID09ICVzLCBXYWl0Rm9yQ2FsbHNUb0NvbXBsZXRlID09ICV1KVxuIiwKICAgIElmU3BlYywgZGVidWdzdHJfZ3VpZCgmSWYtPkludGVyZmFjZUlkLlN5bnRheEdVSUQpLCBkZWJ1Z3N0cl9ndWlkKE1nclR5cGVVdWlkKSwgV2FpdEZvckNhbGxzVG9Db21wbGV0ZSk7CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIExJU1RfRk9SX0VBQ0hfRU5UUlkoY2lmLCAmc2VydmVyX2ludGVyZmFjZXMsIFJwY1NlcnZlckludGVyZmFjZSwgZW50cnkpIHsKICAgIGlmICgoIUlmU3BlYyB8fCAhbWVtY21wKCZJZi0+SW50ZXJmYWNlSWQsICZjaWYtPklmLT5JbnRlcmZhY2VJZCwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpKSAmJgogICAgICAgIFV1aWRFcXVhbChNZ3JUeXBlVXVpZCwgJmNpZi0+TWdyVHlwZVV1aWQsICZzdGF0dXMpKSB7CiAgICAgIGxpc3RfcmVtb3ZlKCZjaWYtPmVudHJ5KTsKICAgICAgaWYgKGNpZi0+Q3VycmVudENhbGxzKSB7CiAgICAgICAgY29tcGxldGVkID0gRkFMU0U7CiAgICAgICAgaWYgKFdhaXRGb3JDYWxsc1RvQ29tcGxldGUpCiAgICAgICAgICBjaWYtPkNhbGxzQ29tcGxldGVkRXZlbnQgPSBldmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOwogICAgICB9CiAgICAgIGZvdW5kID0gVFJVRTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwoKICBpZiAoIWZvdW5kKSB7CiAgICBFUlIoIm5vdCBmb3VuZCBmb3Igb2JqZWN0ICVzXG4iLCBkZWJ1Z3N0cl9ndWlkKE1nclR5cGVVdWlkKSk7CiAgICByZXR1cm4gUlBDX1NfVU5LTk9XTl9JRjsKICB9CgogIGlmIChjb21wbGV0ZWQpCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjaWYpOwogIGVsc2UgaWYgKGV2ZW50KSB7CiAgICAvKiBzaWYgd2lsbCBiZSBmcmVlZCB3aGVuIHRoZSBsYXN0IGNhbGwgaXMgY29tcGxldGVkLCBzbyBiZSBjYXJlZnVsIG5vdCB0bwogICAgICogdG91Y2ggdGhhdCBtZW1vcnkgaGVyZSBhcyB0aGF0IGNvdWxkIGhhcHBlbiBiZWZvcmUgd2UgZ2V0IGhlcmUgKi8KICAgIFdhaXRGb3JTaW5nbGVPYmplY3QoZXZlbnQsIElORklOSVRFKTsKICAgIENsb3NlSGFuZGxlKGV2ZW50KTsKICB9CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVucmVnaXN0ZXJJZkV4IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVucmVnaXN0ZXJJZkV4KCBSUENfSUZfSEFORExFIElmU3BlYywgVVVJRCogTWdyVHlwZVV1aWQsIGludCBSdW5kb3duQ29udGV4dEhhbmRsZXMgKQp7CiAgRklYTUUoIihJZlNwZWMgPT0gKFJQQ19JRl9IQU5ETEUpXiVwLCBNZ3JUeXBlVXVpZCA9PSAlcywgUnVuZG93bkNvbnRleHRIYW5kbGVzID09ICVkKTogc3R1YlxuIiwKICAgIElmU3BlYywgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIFJ1bmRvd25Db250ZXh0SGFuZGxlcyk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY09iamVjdFNldFR5cGUgKFJQQ1JUNC5AKQogKgogKiBQQVJBTVMKICogICBPYmpVdWlkICBbSV0gIk9iamVjdCIgVVVJRAogKiAgIFR5cGVVdWlkIFtJXSAiVHlwZSIgVVVJRAogKgogKiBSRVRVUk5TCiAqICAgUlBDX1NfT0sgICAgICAgICAgICAgICAgIFRoZSBjYWxsIHN1Y2NlZWRlZAogKiAgIFJQQ19TX0lOVkFMSURfT0JKRUNUICAgICBUaGUgcHJvdmlkZWQgb2JqZWN0IChuaWwpIGlzIG5vdCB2YWxpZAogKiAgIFJQQ19TX0FMUkVBRFlfUkVHSVNURVJFRCBUaGUgcHJvdmlkZWQgb2JqZWN0IGlzIGFscmVhZHkgcmVnaXN0ZXJlZAogKgogKiBNYXBzICJPYmplY3QiIFVVSURzIHRvICJUeXBlIiBVVUlEJ3MuICBQYXNzaW5nIHRoZSBuaWwgVVVJRCBhcyB0aGUgdHlwZQogKiByZXNldHMgdGhlIG1hcHBpbmcgZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0IFVVSUQgdG8gbmlsICh0aGUgZGVmYXVsdCkuCiAqIFRoZSBuaWwgb2JqZWN0IGlzIGFsd2F5cyBhc3NvY2lhdGVkIHdpdGggdGhlIG5pbCB0eXBlIGFuZCBjYW5ub3QgYmUKICogcmVhc3NpZ25lZC4gIFNlcnZlcnMgY2FuIHN1cHBvcnQgbXVsdGlwbGUgaW1wbGVtZW50YXRpb25zIG9uIHRoZSBzYW1lCiAqIGludGVyZmFjZSBieSByZWdpc3RlcmluZyBkaWZmZXJlbnQgZW5kLXBvaW50IHZlY3RvcnMgZm9yIHRoZSBkaWZmZXJlbnQKICogdHlwZXMuICBUaGVyZSdzIG5vIG5lZWQgdG8gY2FsbCB0aGlzIGlmIGEgc2VydmVyIG9ubHkgc3VwcG9ydHMgdGhlIG5pbAogKiB0eXBlLCBhcyBpcyB0eXBpY2FsLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjT2JqZWN0U2V0VHlwZSggVVVJRCogT2JqVXVpZCwgVVVJRCogVHlwZVV1aWQgKQp7CiAgUnBjT2JqVHlwZU1hcCAqbWFwID0gUnBjT2JqVHlwZU1hcHMsICpwcmV2ID0gTlVMTDsKICBSUENfU1RBVFVTIGR1bW15OwoKICBUUkFDRSgiKE9ialVVSUQgPT0gJXMsIFR5cGVVdWlkID09ICVzKS5cbiIsIGRlYnVnc3RyX2d1aWQoT2JqVXVpZCksIGRlYnVnc3RyX2d1aWQoVHlwZVV1aWQpKTsKICBpZiAoKCEgT2JqVXVpZCkgfHwgVXVpZElzTmlsKE9ialV1aWQsICZkdW1teSkpIHsKICAgIC8qIG5pbCB1dWlkIGNhbm5vdCBiZSByZW1hcHBlZCAqLwogICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfT0JKRUNUOwogIH0KCiAgLyogZmluZCB0aGUgbWFwcGluZyBmb3IgdGhpcyBvYmplY3QgaWYgdGhlcmUgaXMgb25lIC4uLiAqLwogIHdoaWxlIChtYXApIHsKICAgIGlmICghIFV1aWRDb21wYXJlKE9ialV1aWQsICZtYXAtPk9iamVjdCwgJmR1bW15KSkgYnJlYWs7CiAgICBwcmV2ID0gbWFwOwogICAgbWFwID0gbWFwLT5uZXh0OwogIH0KICBpZiAoKCEgVHlwZVV1aWQpIHx8IFV1aWRJc05pbChUeXBlVXVpZCwgJmR1bW15KSkgewogICAgLyogLi4uIGFuZCBkcm9wIGl0IGZyb20gdGhlIGxpc3QgKi8KICAgIGlmIChtYXApIHsKICAgICAgaWYgKHByZXYpIAogICAgICAgIHByZXYtPm5leHQgPSBtYXAtPm5leHQ7CiAgICAgIGVsc2UKICAgICAgICBScGNPYmpUeXBlTWFwcyA9IG1hcC0+bmV4dDsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWFwKTsKICAgIH0KICB9IGVsc2UgewogICAgLyogLi4uICwgZmFpbCBpZiB3ZSBmb3VuZCBpdCAuLi4gKi8KICAgIGlmIChtYXApCiAgICAgIHJldHVybiBSUENfU19BTFJFQURZX1JFR0lTVEVSRUQ7CiAgICAvKiAuLi4gb3RoZXJ3aXNlIGNyZWF0ZSBhIG5ldyBvbmUgYW5kIGFkZCBpdCBpbi4gKi8KICAgIG1hcCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoUnBjT2JqVHlwZU1hcCkpOwogICAgbWVtY3B5KCZtYXAtPk9iamVjdCwgT2JqVXVpZCwgc2l6ZW9mKFVVSUQpKTsKICAgIG1lbWNweSgmbWFwLT5UeXBlLCBUeXBlVXVpZCwgc2l6ZW9mKFVVSUQpKTsKICAgIG1hcC0+bmV4dCA9IE5VTEw7CiAgICBpZiAocHJldikKICAgICAgcHJldi0+bmV4dCA9IG1hcDsgLyogcHJldiBpcyB0aGUgbGFzdCBtYXAgaW4gdGhlIGxpbmtsaXN0ICovCiAgICBlbHNlCiAgICAgIFJwY09ialR5cGVNYXBzID0gbWFwOwogIH0KCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyUmVnaXN0ZXJBdXRoSW5mb0EgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyUmVnaXN0ZXJBdXRoSW5mb0EoIFJQQ19DU1RSIFNlcnZlclByaW5jTmFtZSwgVUxPTkcgQXV0aG5TdmMsIFJQQ19BVVRIX0tFWV9SRVRSSUVWQUxfRk4gR2V0S2V5Rm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgQXJnICkKewogIEZJWE1FKCAiKCVzLCV1LCVwLCVwKTogc3R1YlxuIiwgU2VydmVyUHJpbmNOYW1lLCBBdXRoblN2YywgR2V0S2V5Rm4sIEFyZyApOwogIAogIHJldHVybiBSUENfU19VTktOT1dOX0FVVEhOX1NFUlZJQ0U7IC8qIFdlIGRvbid0IGtub3cgYW55IGF1dGhlbnRpY2F0aW9uIHNlcnZpY2VzICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJSZWdpc3RlckF1dGhJbmZvVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJSZWdpc3RlckF1dGhJbmZvVyggUlBDX1dTVFIgU2VydmVyUHJpbmNOYW1lLCBVTE9ORyBBdXRoblN2YywgUlBDX0FVVEhfS0VZX1JFVFJJRVZBTF9GTiBHZXRLZXlGbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBBcmcgKQp7CiAgRklYTUUoICIoJXMsJXUsJXAsJXApOiBzdHViXG4iLCBkZWJ1Z3N0cl93KCBTZXJ2ZXJQcmluY05hbWUgKSwgQXV0aG5TdmMsIEdldEtleUZuLCBBcmcgKTsKICAKICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRITl9TRVJWSUNFOyAvKiBXZSBkb24ndCBrbm93IGFueSBhdXRoZW50aWNhdGlvbiBzZXJ2aWNlcyAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyTGlzdGVuIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlckxpc3RlbiggVUlOVCBNaW5pbXVtQ2FsbFRocmVhZHMsIFVJTlQgTWF4Q2FsbHMsIFVJTlQgRG9udFdhaXQgKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXMgPSBSUENfU19PSzsKCiAgVFJBQ0UoIigldSwldSwldSlcbiIsIE1pbmltdW1DYWxsVGhyZWFkcywgTWF4Q2FsbHMsIERvbnRXYWl0KTsKCiAgaWYgKGxpc3RfZW1wdHkoJnByb3RzZXFzKSkKICAgIHJldHVybiBSUENfU19OT19QUk9UU0VRU19SRUdJU1RFUkVEOwoKICBzdGF0dXMgPSBSUENSVDRfc3RhcnRfbGlzdGVuKEZBTFNFKTsKCiAgaWYgKERvbnRXYWl0IHx8IChzdGF0dXMgIT0gUlBDX1NfT0spKSByZXR1cm4gc3RhdHVzOwoKICByZXR1cm4gUnBjTWdtdFdhaXRTZXJ2ZXJMaXN0ZW4oKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRTZXJ2ZXJXYWl0TGlzdGVuIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRXYWl0U2VydmVyTGlzdGVuKCB2b2lkICkKewogIFRSQUNFKCIoKVxuIik7CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwoKICBpZiAoIXN0ZF9saXN0ZW4pIHsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogICAgcmV0dXJuIFJQQ19TX05PVF9MSVNURU5JTkc7CiAgfQogIAogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwoKICBGSVhNRSgibm90IHdhaXRpbmcgZm9yIHNlcnZlciBjYWxscyB0byBmaW5pc2hcbiIpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNNZ210U3RvcFNlcnZlckxpc3RlbmluZyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210U3RvcFNlcnZlckxpc3RlbmluZyAoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nICkKewogIFRSQUNFKCIoQmluZGluZyA9PSAoUlBDX0JJTkRJTkdfSEFORExFKV4lcClcbiIsIEJpbmRpbmcpOwoKICBpZiAoQmluZGluZykgewogICAgRklYTUUoImNsaWVudC1zaWRlIGludm9jYXRpb24gbm90IGltcGxlbWVudGVkLlxuIik7CiAgICByZXR1cm4gUlBDX1NfV1JPTkdfS0lORF9PRl9CSU5ESU5HOwogIH0KICAKICBSUENSVDRfc3RvcF9saXN0ZW4oRkFMU0UpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNNZ210RW5hYmxlSWRsZUNsZWFudXAgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTWdtdEVuYWJsZUlkbGVDbGVhbnVwKHZvaWQpCnsKICAgIEZJWE1FKCIoKTogc3R1YlxuIik7CiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBJX1JwY1NlcnZlclN0YXJ0TGlzdGVuaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjU2VydmVyU3RhcnRMaXN0ZW5pbmcoIEhXTkQgaFduZCApCnsKICBGSVhNRSggIiglcCk6IHN0dWJcbiIsIGhXbmQgKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgSV9ScGNTZXJ2ZXJTdG9wTGlzdGVuaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjU2VydmVyU3RvcExpc3RlbmluZyggdm9pZCApCnsKICBGSVhNRSggIigpOiBzdHViXG4iICk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIElfUnBjV2luZG93UHJvYyAoUlBDUlQ0LkApCiAqLwpVSU5UIFdJTkFQSSBJX1JwY1dpbmRvd1Byb2MoIHZvaWQgKmhXbmQsIFVJTlQgTWVzc2FnZSwgVUlOVCB3UGFyYW0sIFVMT05HIGxQYXJhbSApCnsKICBGSVhNRSggIiglcCwlMDh4LCUwOHgsJTA4eCk6IHN0dWJcbiIsIGhXbmQsIE1lc3NhZ2UsIHdQYXJhbSwgbFBhcmFtICk7CgogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTWdtdElucUlmSWRzIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRJbnFJZklkcyhSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX0lGX0lEX1ZFQ1RPUiAqKklmSWRWZWN0b3IpCnsKICBGSVhNRSgiKCVwLCVwKTogc3R1YlxuIiwgQmluZGluZywgSWZJZFZlY3Rvcik7CiAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRFcEVsdElucUJlZ2luIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRFcEVsdElucUJlZ2luKFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBVTE9ORyBJbnF1aXJ5VHlwZSwKICAgIFJQQ19JRl9JRCAqSWZJZCwgVUxPTkcgVmVyc09wdGlvbiwgVVVJRCAqT2JqZWN0VXVpZCwgUlBDX0VQX0lOUV9IQU5ETEUqIElucXVpcnlDb250ZXh0KQp7CiAgRklYTUUoIiglcCwldSwlcCwldSwlcCwlcCk6IHN0dWJcbiIsCiAgICAgICAgQmluZGluZywgSW5xdWlyeVR5cGUsIElmSWQsIFZlcnNPcHRpb24sIE9iamVjdFV1aWQsIElucXVpcnlDb250ZXh0KTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTWdtdElzU2VydmVyTGlzdGVuaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRJc1NlcnZlckxpc3RlbmluZyhSUENfQklORElOR19IQU5ETEUgQmluZGluZykKewogIEZJWE1FKCIoJXApOiBzdHViXG4iLCBCaW5kaW5nKTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTWdtdFNldFNlcnZlclN0YWNrU2l6ZSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210U2V0U2VydmVyU3RhY2tTaXplKFVMT05HIFRocmVhZFN0YWNrU2l6ZSkKewogIEZJWE1FKCIoMHgleCk6IHN0dWJcbiIsIFRocmVhZFN0YWNrU2l6ZSk7CiAgcmV0dXJuIFJQQ19TX09LOwp9Cg==