LyoKICogUlBDIHNlcnZlciBBUEkKICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKI2luY2x1ZGUgImV4Y3B0LmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKCiNpbmNsdWRlICJycGNfc2VydmVyLmgiCiNpbmNsdWRlICJycGNfbWlzYy5oIgojaW5jbHVkZSAicnBjX21lc3NhZ2UuaCIKI2luY2x1ZGUgInJwY19kZWZzLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChycGMpOwoKdHlwZWRlZiBzdHJ1Y3QgX1JwY1BhY2tldAp7CiAgc3RydWN0IF9ScGNDb25uZWN0aW9uKiBjb25uOwogIFJwY1BrdEhkciogaGRyOwogIFJQQ19NRVNTQUdFKiBtc2c7Cn0gUnBjUGFja2V0OwoKdHlwZWRlZiBzdHJ1Y3QgX1JwY09ialR5cGVNYXAKewogIC8qIEZJWE1FOiBhIGhhc2ggdGFibGUgd291bGQgYmUgYmV0dGVyLiAqLwogIHN0cnVjdCBfUnBjT2JqVHlwZU1hcCAqbmV4dDsKICBVVUlEIE9iamVjdDsKICBVVUlEIFR5cGU7Cn0gUnBjT2JqVHlwZU1hcDsKCnN0YXRpYyBScGNPYmpUeXBlTWFwICpScGNPYmpUeXBlTWFwczsKCnN0YXRpYyBScGNTZXJ2ZXJQcm90c2VxKiBwcm90c2VxczsKc3RhdGljIFJwY1NlcnZlckludGVyZmFjZSogaWZzOwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gc2VydmVyX2NzOwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTl9ERUJVRyBzZXJ2ZXJfY3NfZGVidWcgPQp7CiAgICAwLCAwLCAmc2VydmVyX2NzLAogICAgeyAmc2VydmVyX2NzX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QsICZzZXJ2ZXJfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IHNlcnZlcl9jcyIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gc2VydmVyX2NzID0geyAmc2VydmVyX2NzX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gbGlzdGVuX2NzOwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTl9ERUJVRyBsaXN0ZW5fY3NfZGVidWcgPQp7CiAgICAwLCAwLCAmbGlzdGVuX2NzLAogICAgeyAmbGlzdGVuX2NzX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QsICZsaXN0ZW5fY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGxpc3Rlbl9jcyIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gbGlzdGVuX2NzID0geyAmbGlzdGVuX2NzX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKLyogd2hldGhlciB0aGUgc2VydmVyIGlzIGN1cnJlbnRseSBsaXN0ZW5pbmcgKi8Kc3RhdGljIEJPT0wgc3RkX2xpc3RlbjsKLyogbnVtYmVyIG9mIG1hbnVhbCBsaXN0ZW5lcnMgKGNhbGxzIHRvIFJwY1NlcnZlckxpc3RlbikgKi8Kc3RhdGljIExPTkcgbWFudWFsX2xpc3Rlbl9jb3VudDsKLyogdG90YWwgbGlzdGVuZXJzIGluY2x1ZGluZyBhdXRvIGxpc3RlbmVycyAqLwpzdGF0aWMgTE9ORyBsaXN0ZW5fY291bnQ7Ci8qIHNldCBvbiBjaGFuZ2Ugb2YgY29uZmlndXJhdGlvbiAoZS5nLiBsaXN0ZW5pbmcgb24gbmV3IHByb3RzZXEpICovCnN0YXRpYyBIQU5ETEUgbWdyX2V2ZW50OwovKiBtdXRleCBmb3IgZW5zdXJpbmcgb25seSBvbmUgdGhyZWFkIGNhbiBjaGFuZ2Ugc3RhdGUgYXQgYSB0aW1lICovCnN0YXRpYyBIQU5ETEUgbWdyX211dGV4OwovKiBzZXQgd2hlbiBzZXJ2ZXIgdGhyZWFkIGhhcyBmaW5pc2hlZCBvcGVuaW5nIGNvbm5lY3Rpb25zICovCnN0YXRpYyBIQU5ETEUgc2VydmVyX3JlYWR5X2V2ZW50OwoKc3RhdGljIFVVSUQgdXVpZF9uaWw7CgppbmxpbmUgc3RhdGljIFJwY09ialR5cGVNYXAgKkxvb2t1cE9ialR5cGVNYXAoVVVJRCAqT2JqVXVpZCkKewogIFJwY09ialR5cGVNYXAgKnJzbHQgPSBScGNPYmpUeXBlTWFwczsKICBSUENfU1RBVFVTIGR1bW15OwoKICB3aGlsZSAocnNsdCkgewogICAgaWYgKCEgVXVpZENvbXBhcmUoT2JqVXVpZCwgJnJzbHQtPk9iamVjdCwgJmR1bW15KSkgYnJlYWs7CiAgICByc2x0ID0gcnNsdC0+bmV4dDsKICB9CgogIHJldHVybiByc2x0Owp9CgppbmxpbmUgc3RhdGljIFVVSUQgKkxvb2t1cE9ialR5cGUoVVVJRCAqT2JqVXVpZCkKewogIFJwY09ialR5cGVNYXAgKm1hcCA9IExvb2t1cE9ialR5cGVNYXAoT2JqVXVpZCk7CiAgaWYgKG1hcCkKICAgIHJldHVybiAmbWFwLT5UeXBlOwogIGVsc2UKICAgIHJldHVybiAmdXVpZF9uaWw7Cn0KCnN0YXRpYyBScGNTZXJ2ZXJJbnRlcmZhY2UqIFJQQ1JUNF9maW5kX2ludGVyZmFjZShVVUlEKiBvYmplY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfU1lOVEFYX0lERU5USUZJRVIqIGlmX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBjaGVja19vYmplY3QpCnsKICBVVUlEKiBNZ3JUeXBlID0gTlVMTDsKICBScGNTZXJ2ZXJJbnRlcmZhY2UqIGNpZiA9IE5VTEw7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIGlmIChjaGVja19vYmplY3QpCiAgICBNZ3JUeXBlID0gTG9va3VwT2JqVHlwZShvYmplY3QpOwogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIGNpZiA9IGlmczsKICB3aGlsZSAoY2lmKSB7CiAgICBpZiAoIW1lbWNtcChpZl9pZCwgJmNpZi0+SWYtPkludGVyZmFjZUlkLCBzaXplb2YoUlBDX1NZTlRBWF9JREVOVElGSUVSKSkgJiYKICAgICAgICAoY2hlY2tfb2JqZWN0ID09IEZBTFNFIHx8IFV1aWRFcXVhbChNZ3JUeXBlLCAmY2lmLT5NZ3JUeXBlVXVpZCwgJnN0YXR1cykpICYmCiAgICAgICAgc3RkX2xpc3RlbikgYnJlYWs7CiAgICBjaWYgPSBjaWYtPk5leHQ7CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIFRSQUNFKCJyZXR1cm5pbmcgJXAgZm9yICVzXG4iLCBjaWYsIGRlYnVnc3RyX2d1aWQob2JqZWN0KSk7CiAgcmV0dXJuIGNpZjsKfQoKc3RhdGljIFdJTkVfRVhDRVBUSU9OX0ZJTFRFUihycGNfZmlsdGVyKQp7CiAgV0FSTigiZXhjZXB0aW9uIGNhdWdodCB3aXRoIGNvZGUgMHglMDhseCA9ICVsZFxuIiwgR2V0RXhjZXB0aW9uQ29kZSgpLCBHZXRFeGNlcHRpb25Db2RlKCkpOwogIFRSQUNFKCJyZXR1cm5pbmcgZmFpbHVyZSBwYWNrZXRcbiIpOwogIC8qIGNhdGNoIGV2ZXJ5IGV4Y2VwdGlvbiAqLwogIHJldHVybiBFWENFUFRJT05fRVhFQ1VURV9IQU5ETEVSOwp9CgpzdGF0aWMgdm9pZCBSUENSVDRfcHJvY2Vzc19wYWNrZXQoUnBjQ29ubmVjdGlvbiogY29ubiwgUnBjUGt0SGRyKiBoZHIsIFJQQ19NRVNTQUdFKiBtc2cpCnsKICBScGNTZXJ2ZXJJbnRlcmZhY2UqIHNpZjsKICBSUENfRElTUEFUQ0hfRlVOQ1RJT04gZnVuYzsKICBVVUlEICpvYmplY3RfdXVpZDsKICBScGNQa3RIZHIgKnJlc3BvbnNlOwogIHZvaWQgKmJ1ZiA9IG1zZy0+QnVmZmVyOwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBzd2l0Y2ggKGhkci0+Y29tbW9uLnB0eXBlKSB7CiAgICBjYXNlIFBLVF9CSU5EOgogICAgICBUUkFDRSgiZ290IGJpbmQgcGFja2V0XG4iKTsKCiAgICAgIC8qIEZJWE1FOiBkbyBtb3JlIGNoZWNrcyEgKi8KICAgICAgaWYgKGhkci0+YmluZC5tYXhfdHNpemUgPCBSUENfTUlOX1BBQ0tFVF9TSVpFIHx8CiAgICAgICAgICAhVXVpZElzTmlsKCZjb25uLT5BY3RpdmVJbnRlcmZhY2UuU3ludGF4R1VJRCwgJnN0YXR1cykpIHsKICAgICAgICBUUkFDRSgicGFja2V0IHNpemUgbGVzcyB0aGFuIG1pbiBzaXplLCBvciBhY3RpdmUgaW50ZXJmYWNlIHN5bnRheCBndWlkIG5vbi1udWxsXG4iKTsKICAgICAgICBzaWYgPSBOVUxMOwogICAgICB9IGVsc2UgewogICAgICAgIHNpZiA9IFJQQ1JUNF9maW5kX2ludGVyZmFjZShOVUxMLCAmaGRyLT5iaW5kLmFic3RyYWN0LCBGQUxTRSk7CiAgICAgIH0KICAgICAgaWYgKHNpZiA9PSBOVUxMKSB7CiAgICAgICAgVFJBQ0UoInJlamVjdGluZyBiaW5kIHJlcXVlc3Qgb24gY29ubmVjdGlvbiAlcFxuIiwgY29ubik7CiAgICAgICAgLyogUmVwb3J0IGZhaWx1cmUgdG8gY2xpZW50LiAqLwogICAgICAgIHJlc3BvbnNlID0gUlBDUlQ0X0J1aWxkQmluZE5hY2tIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfVkVSX01BSk9SLCBSUENfVkVSX01JTk9SKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiYWNjZXB0aW5nIGJpbmQgcmVxdWVzdCBvbiBjb25uZWN0aW9uICVwXG4iLCBjb25uKTsKCiAgICAgICAgLyogYWNjZXB0LiAqLwogICAgICAgIHJlc3BvbnNlID0gUlBDUlQ0X0J1aWxkQmluZEFja0hlYWRlcihORFJfTE9DQUxfREFUQV9SRVBSRVNFTlRBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX01BWF9QQUNLRVRfU0laRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX01BWF9QQUNLRVRfU0laRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubi0+RW5kcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFU1VMVF9BQ0NFUFQsIE5PX1JFQVNPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNpZi0+SWYtPlRyYW5zZmVyU3ludGF4KTsKCiAgICAgICAgLyogc2F2ZSB0aGUgaW50ZXJmYWNlIGZvciBsYXRlciB1c2UgKi8KICAgICAgICBjb25uLT5BY3RpdmVJbnRlcmZhY2UgPSBoZHItPmJpbmQuYWJzdHJhY3Q7CiAgICAgICAgY29ubi0+TWF4VHJhbnNtaXNzaW9uU2l6ZSA9IGhkci0+YmluZC5tYXhfdHNpemU7CiAgICAgIH0KCiAgICAgIHN0YXR1cyA9IFJQQ1JUNF9TZW5kKGNvbm4sIHJlc3BvbnNlLCBOVUxMLCAwKTsKICAgICAgUlBDUlQ0X0ZyZWVIZWFkZXIocmVzcG9uc2UpOwogICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgIGdvdG8gZmFpbDsKCiAgICAgIGJyZWFrOwoKICAgIGNhc2UgUEtUX1JFUVVFU1Q6CiAgICAgIFRSQUNFKCJnb3QgcmVxdWVzdCBwYWNrZXRcbiIpOwoKICAgICAgLyogZmFpbCBpZiB0aGUgY29ubmVjdGlvbiBpc24ndCBib3VuZCB3aXRoIGFuIGludGVyZmFjZSAqLwogICAgICBpZiAoVXVpZElzTmlsKCZjb25uLT5BY3RpdmVJbnRlcmZhY2UuU3ludGF4R1VJRCwgJnN0YXR1cykpIHsKICAgICAgICByZXNwb25zZSA9IFJQQ1JUNF9CdWlsZEZhdWx0SGVhZGVyKE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKCiAgICAgICAgUlBDUlQ0X1NlbmQoY29ubiwgcmVzcG9uc2UsIE5VTEwsIDApOwogICAgICAgIFJQQ1JUNF9GcmVlSGVhZGVyKHJlc3BvbnNlKTsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgaWYgKGhkci0+Y29tbW9uLmZsYWdzICYgUlBDX0ZMR19PQkpFQ1RfVVVJRCkgewogICAgICAgIG9iamVjdF91dWlkID0gKFVVSUQqKSgmaGRyLT5yZXF1ZXN0ICsgMSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0X3V1aWQgPSBOVUxMOwogICAgICB9CgogICAgICBzaWYgPSBSUENSVDRfZmluZF9pbnRlcmZhY2Uob2JqZWN0X3V1aWQsICZjb25uLT5BY3RpdmVJbnRlcmZhY2UsIFRSVUUpOwogICAgICBtc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uID0gc2lmLT5JZjsKICAgICAgLyogY29weSB0aGUgZW5kcG9pbnQgdmVjdG9yIGZyb20gc2lmIHRvIG1zZyBzbyB0aGF0IG1pZGwtZ2VuZXJhdGVkIGNvZGUgd2lsbCB1c2UgaXQgKi8KICAgICAgbXNnLT5NYW5hZ2VyRXB2ID0gc2lmLT5NZ3JFcHY7CiAgICAgIGlmIChvYmplY3RfdXVpZCAhPSBOVUxMKSB7CiAgICAgICAgUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QobXNnLT5IYW5kbGUsIG9iamVjdF91dWlkKTsKICAgICAgfQoKICAgICAgLyogZmluZCBkaXNwYXRjaCBmdW5jdGlvbiAqLwogICAgICBtc2ctPlByb2NOdW0gPSBoZHItPnJlcXVlc3Qub3BudW07CiAgICAgIGlmIChzaWYtPkZsYWdzICYgUlBDX0lGX09MRSkgewogICAgICAgIC8qIG5hdGl2ZSBvbGUzMiBhbHdheXMgZ2l2ZXMgdXMgYSBkaXNwYXRjaCB0YWJsZSB3aXRoIGEgc2luZ2xlIGVudHJ5CiAgICAgICAgICogKEkgYXNzdW1lIHRoYXQncyBhIHdyYXBwZXIgZm9yIElScGNTdHViQnVmZmVyOjpJbnZva2UpICovCiAgICAgICAgZnVuYyA9ICpzaWYtPklmLT5EaXNwYXRjaFRhYmxlLT5EaXNwYXRjaFRhYmxlOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChtc2ctPlByb2NOdW0gPj0gc2lmLT5JZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZUNvdW50KSB7CiAgICAgICAgICBFUlIoImludmFsaWQgcHJvY251bVxuIik7CiAgICAgICAgICBmdW5jID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgZnVuYyA9IHNpZi0+SWYtPkRpc3BhdGNoVGFibGUtPkRpc3BhdGNoVGFibGVbbXNnLT5Qcm9jTnVtXTsKICAgICAgfQoKICAgICAgLyogcHV0IGluIHRoZSBkcmVwLiBGSVhNRTogaXMgdGhpcyBtb3JlIHVuaXZlcnNhbGx5IGFwcGxpY2FibGU/CiAgICAgICAgIHBlcmhhcHMgd2Ugc2hvdWxkIG1vdmUgdGhpcyBvdXR3YXJkLi4uICovCiAgICAgIG1zZy0+RGF0YVJlcHJlc2VudGF0aW9uID0gCiAgICAgICAgTUFLRUxPTkcoIE1BS0VXT1JEKGhkci0+Y29tbW9uLmRyZXBbMF0sIGhkci0+Y29tbW9uLmRyZXBbMV0pLAogICAgICAgICAgICAgICAgICBNQUtFV09SRChoZHItPmNvbW1vbi5kcmVwWzJdLCBoZHItPmNvbW1vbi5kcmVwWzNdKSk7CgogICAgICAvKiBkaXNwYXRjaCAqLwogICAgICBfX1RSWSB7CiAgICAgICAgaWYgKGZ1bmMpIGZ1bmMobXNnKTsKICAgICAgfSBfX0VYQ0VQVChycGNfZmlsdGVyKSB7CiAgICAgICAgaWYgKG1zZy0+QnVmZmVyICE9IGJ1ZikgSV9ScGNGcmVlQnVmZmVyKG1zZyk7CiAgICAgICAgLyogdGhpcyB3aWxsIGNhdXNlIGEgZmFpbHVyZSBwYWNrZXQgdG8gYmUgc2VudCBpbiBJX1JwY1NlbmQgKi8KICAgICAgICBtc2ctPlJwY0ZsYWdzIHw9IFdJTkVfUlBDRkxBR19FWENFUFRJT047CiAgICAgICAgbXNnLT5CdWZmZXJMZW5ndGggPSBzaXplb2YoRFdPUkQpOwogICAgICAgIElfUnBjR2V0QnVmZmVyKG1zZyk7CiAgICAgICAgKihEV09SRCopbXNnLT5CdWZmZXIgPSBHZXRFeGNlcHRpb25Db2RlKCk7CiAgICAgIH0gX19FTkRUUlkKCiAgICAgIC8qIHNlbmQgcmVzcG9uc2UgcGFja2V0ICovCiAgICAgIElfUnBjU2VuZChtc2cpOwoKICAgICAgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbiA9IE5VTEw7CgogICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICBGSVhNRSgidW5oYW5kbGVkIHBhY2tldCB0eXBlXG4iKTsKICAgICAgYnJlYWs7CiAgfQoKZmFpbDoKICAvKiBjbGVhbiB1cCAqLwogIGlmIChtc2ctPkJ1ZmZlciA9PSBidWYpIG1zZy0+QnVmZmVyID0gTlVMTDsKICBUUkFDRSgiZnJlZWluZyBCdWZmZXI9JXBcbiIsIGJ1Zik7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYnVmKTsKICBSUENSVDRfRGVzdHJveUJpbmRpbmcobXNnLT5IYW5kbGUpOwogIG1zZy0+SGFuZGxlID0gMDsKICBJX1JwY0ZyZWVCdWZmZXIobXNnKTsKICBtc2ctPkJ1ZmZlciA9IE5VTEw7CiAgUlBDUlQ0X0ZyZWVIZWFkZXIoaGRyKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2cpOwp9CgpzdGF0aWMgRFdPUkQgQ0FMTEJBQ0sgUlBDUlQ0X3dvcmtlcl90aHJlYWQoTFBWT0lEIHRoZV9hcmcpCnsKICBScGNQYWNrZXQgKnBrdCA9IHRoZV9hcmc7CiAgUlBDUlQ0X3Byb2Nlc3NfcGFja2V0KHBrdC0+Y29ubiwgcGt0LT5oZHIsIHBrdC0+bXNnKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwa3QpOwogIHJldHVybiAwOwp9CgpzdGF0aWMgRFdPUkQgQ0FMTEJBQ0sgUlBDUlQ0X2lvX3RocmVhZChMUFZPSUQgdGhlX2FyZykKewogIFJwY0Nvbm5lY3Rpb24qIGNvbm4gPSAoUnBjQ29ubmVjdGlvbiopdGhlX2FyZzsKICBScGNQa3RIZHIgKmhkcjsKICBScGNCaW5kaW5nICpwYmluZDsKICBSUENfTUVTU0FHRSAqbXNnOwogIFJQQ19TVEFUVVMgc3RhdHVzOwogIFJwY1BhY2tldCAqcGFja2V0OwoKICBUUkFDRSgiKCVwKVxuIiwgY29ubik7CgogIGZvciAoOzspIHsKICAgIG1zZyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUlBDX01FU1NBR0UpKTsKCiAgICAvKiBjcmVhdGUgdGVtcG9yYXJ5IGJpbmRpbmcgZm9yIGRpc3BhdGNoLCBpdCB3aWxsIGJlIGZyZWVkIGluCiAgICAgKiBSUENSVDRfcHJvY2Vzc19wYWNrZXQgKi8KICAgIFJQQ1JUNF9NYWtlQmluZGluZygmcGJpbmQsIGNvbm4pOwogICAgbXNnLT5IYW5kbGUgPSAoUlBDX0JJTkRJTkdfSEFORExFKXBiaW5kOwoKICAgIHN0YXR1cyA9IFJQQ1JUNF9SZWNlaXZlKGNvbm4sICZoZHIsIG1zZyk7CiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSB7CiAgICAgIFdBUk4oInJlY2VpdmUgZmFpbGVkIHdpdGggZXJyb3IgJWx4XG4iLCBzdGF0dXMpOwogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2cpOwogICAgICBicmVhazsKICAgIH0KCiNpZiAwCiAgICBSUENSVDRfcHJvY2Vzc19wYWNrZXQoY29ubiwgaGRyLCBtc2cpOwojZWxzZQogICAgcGFja2V0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihScGNQYWNrZXQpKTsKICAgIHBhY2tldC0+Y29ubiA9IGNvbm47CiAgICBwYWNrZXQtPmhkciA9IGhkcjsKICAgIHBhY2tldC0+bXNnID0gbXNnOwogICAgUXVldWVVc2VyV29ya0l0ZW0oUlBDUlQ0X3dvcmtlcl90aHJlYWQsIHBhY2tldCwgV1RfRVhFQ1VURURFRkFVTFQpOwojZW5kaWYKICAgIG1zZyA9IE5VTEw7CiAgfQogIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihjb25uKTsKICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgUlBDUlQ0X25ld19jbGllbnQoUnBjQ29ubmVjdGlvbiogY29ubikKewogIEhBTkRMRSB0aHJlYWQgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgUlBDUlQ0X2lvX3RocmVhZCwgY29ubiwgMCwgTlVMTCk7CiAgaWYgKCF0aHJlYWQpIHsKICAgIERXT1JEIGVyciA9IEdldExhc3RFcnJvcigpOwogICAgRVJSKCJmYWlsZWQgdG8gY3JlYXRlIHRocmVhZCwgZXJyb3I9JTA4bHhcbiIsIGVycik7CiAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oY29ubik7CiAgfQogIC8qIHdlIGNvdWxkIHNldCBjb25uLT50aHJlYWQsIGJ1dCB0aGVuIHdlJ2QgaGF2ZSB0byBtYWtlIHRoZSBpb190aHJlYWQgd2FpdAogICAqIGZvciB0aGF0LCBvdGhlcndpc2UgdGhlIHRocmVhZCBtaWdodCBmaW5pc2gsIGRlc3Ryb3kgdGhlIGNvbm5lY3Rpb24sIGFuZAogICAqIGZyZWUgdGhlIG1lbW9yeSB3ZSdkIHdyaXRlIHRvIGJlZm9yZSB3ZSBkaWQsIGNhdXNpbmcgY3Jhc2hlcyBhbmQgc3R1ZmYgLQogICAqIHNvIGxldCdzIGltcGxlbWVudCB0aGF0IGxhdGVyLCB3aGVuIHdlIHJlYWxseSBuZWVkIGNvbm4tPnRocmVhZCAqLwoKICBDbG9zZUhhbmRsZSggdGhyZWFkICk7Cn0KCnN0YXRpYyBEV09SRCBDQUxMQkFDSyBSUENSVDRfc2VydmVyX3RocmVhZChMUFZPSUQgdGhlX2FyZykKewogIEhBTkRMRSBtX2V2ZW50ID0gbWdyX2V2ZW50LCBiX2hhbmRsZTsKICBIQU5ETEUgKm9ianMgPSBOVUxMOwogIERXT1JEIGNvdW50LCByZXM7CiAgUnBjU2VydmVyUHJvdHNlcSogY3BzOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CiAgUnBjQ29ubmVjdGlvbiogY2Nvbm47CiAgQk9PTCBzZXRfcmVhZHlfZXZlbnQgPSBGQUxTRTsKCiAgVFJBQ0UoIih0aGVfYXJnID09IF4lcClcbiIsIHRoZV9hcmcpOwoKICBmb3IgKDs7KSB7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICAgIC8qIG9wZW4gYW5kIGNvdW50IGNvbm5lY3Rpb25zICovCiAgICBjb3VudCA9IDE7CiAgICBjcHMgPSBwcm90c2VxczsKICAgIHdoaWxlIChjcHMpIHsKICAgICAgY29ubiA9IGNwcy0+Y29ubjsKICAgICAgd2hpbGUgKGNvbm4pIHsKICAgICAgICBSUENSVDRfT3BlbkNvbm5lY3Rpb24oY29ubik7CiAgICAgICAgaWYgKHJwY3J0NF9jb25uX2dldF93YWl0X29iamVjdChjb25uKSkKICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgY29ubiA9IGNvbm4tPk5leHQ7CiAgICAgIH0KICAgICAgY3BzID0gY3BzLT5OZXh0OwogICAgfQogICAgLyogbWFrZSBhcnJheSBvZiBjb25uZWN0aW9ucyAqLwogICAgaWYgKG9ianMpCiAgICAgIG9ianMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmpzLCBjb3VudCpzaXplb2YoSEFORExFKSk7CiAgICBlbHNlCiAgICAgIG9ianMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY291bnQqc2l6ZW9mKEhBTkRMRSkpOwoKICAgIG9ianNbMF0gPSBtX2V2ZW50OwogICAgY291bnQgPSAxOwogICAgY3BzID0gcHJvdHNlcXM7CiAgICB3aGlsZSAoY3BzKSB7CiAgICAgIGNvbm4gPSBjcHMtPmNvbm47CiAgICAgIHdoaWxlIChjb25uKSB7CiAgICAgICAgaWYgKChvYmpzW2NvdW50XSA9IHJwY3J0NF9jb25uX2dldF93YWl0X29iamVjdChjb25uKSkpCiAgICAgICAgICBjb3VudCsrOwogICAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgICB9CiAgICAgIGNwcyA9IGNwcy0+TmV4dDsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwoKICAgIGlmIChzZXRfcmVhZHlfZXZlbnQpCiAgICB7CiAgICAgICAgLyogc2lnbmFsIHRvIGZ1bmN0aW9uIHRoYXQgY2hhbmdlZCBzdGF0ZSB0aGF0IHdlIGFyZSBub3cgc3luYydlZCAqLwogICAgICAgIFNldEV2ZW50KHNlcnZlcl9yZWFkeV9ldmVudCk7CiAgICAgICAgc2V0X3JlYWR5X2V2ZW50ID0gRkFMU0U7CiAgICB9CgogICAgLyogc3RhcnQgd2FpdGluZyAqLwogICAgcmVzID0gV2FpdEZvck11bHRpcGxlT2JqZWN0cyhjb3VudCwgb2JqcywgRkFMU0UsIElORklOSVRFKTsKICAgIGlmIChyZXMgPT0gV0FJVF9PQkpFQ1RfMCkgewogICAgICBpZiAoIXN0ZF9saXN0ZW4pCiAgICAgIHsKICAgICAgICBTZXRFdmVudChzZXJ2ZXJfcmVhZHlfZXZlbnQpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIHNldF9yZWFkeV9ldmVudCA9IFRSVUU7CiAgICB9CiAgICBlbHNlIGlmIChyZXMgPT0gV0FJVF9GQUlMRUQpIHsKICAgICAgRVJSKCJ3YWl0IGZhaWxlZFxuIik7CiAgICB9CiAgICBlbHNlIHsKICAgICAgYl9oYW5kbGUgPSBvYmpzW3JlcyAtIFdBSVRfT0JKRUNUXzBdOwogICAgICAvKiBmaW5kIHdoaWNoIGNvbm5lY3Rpb24gZ290IGEgUlBDICovCiAgICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogICAgICBjb25uID0gTlVMTDsKICAgICAgY3BzID0gcHJvdHNlcXM7CiAgICAgIHdoaWxlIChjcHMpIHsKICAgICAgICBjb25uID0gY3BzLT5jb25uOwogICAgICAgIHdoaWxlIChjb25uKSB7CiAgICAgICAgICBpZiAoYl9oYW5kbGUgPT0gcnBjcnQ0X2Nvbm5fZ2V0X3dhaXRfb2JqZWN0KGNvbm4pKSBicmVhazsKICAgICAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgICAgIH0KICAgICAgICBpZiAoY29ubikgYnJlYWs7CiAgICAgICAgY3BzID0gY3BzLT5OZXh0OwogICAgICB9CiAgICAgIGNjb25uID0gTlVMTDsKICAgICAgaWYgKGNvbm4pCiAgICAgICAgUlBDUlQ0X1NwYXduQ29ubmVjdGlvbigmY2Nvbm4sIGNvbm4pOwogICAgICBlbHNlCiAgICAgICAgRVJSKCJmYWlsZWQgdG8gbG9jYXRlIGNvbm5lY3Rpb24gZm9yIGhhbmRsZSAlcFxuIiwgYl9oYW5kbGUpOwogICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICAgICAgaWYgKGNjb25uKSBSUENSVDRfbmV3X2NsaWVudChjY29ubik7CiAgICB9CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9ianMpOwogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIC8qIGNsb3NlIGNvbm5lY3Rpb25zICovCiAgY3BzID0gcHJvdHNlcXM7CiAgd2hpbGUgKGNwcykgewogICAgY29ubiA9IGNwcy0+Y29ubjsKICAgIHdoaWxlIChjb25uKSB7CiAgICAgIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oY29ubik7CiAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgfQogICAgY3BzID0gY3BzLT5OZXh0OwogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICByZXR1cm4gMDsKfQoKLyogdGVsbHMgdGhlIHNlcnZlciB0aHJlYWQgdGhhdCB0aGUgc3RhdGUgaGFzIGNoYW5nZWQgYW5kIHdhaXRzIGZvciBpdCB0bwogKiBtYWtlIHRoZSBjaGFuZ2VzICovCnN0YXRpYyB2b2lkIFJQQ1JUNF9zeW5jX3dpdGhfc2VydmVyX3RocmVhZCh2b2lkKQp7CiAgLyogbWFrZSBzdXJlIHdlIGFyZSB0aGUgb25seSB0aHJlYWQgc3luYydpbmcgdGhlIHNlcnZlciBzdGF0ZSwgb3RoZXJ3aXNlCiAgICogdGhlcmUgaXMgYSByYWNlIHdpdGggdGhlIHNlcnZlciB0aHJlYWQgc2V0dGluZyBhbiBvbGRlciBzdGF0ZSBhbmQgc2V0dGluZwogICAqIHRoZSBzZXJ2ZXJfcmVhZHlfZXZlbnQgd2hlbiB0aGUgbmV3IHN0YXRlIGhhc24ndCB5ZXQgYmVlbiBhcHBsaWVkICovCiAgV2FpdEZvclNpbmdsZU9iamVjdChtZ3JfbXV0ZXgsIElORklOSVRFKTsKCiAgU2V0RXZlbnQobWdyX2V2ZW50KTsKICAvKiB3YWl0IGZvciBzZXJ2ZXIgdGhyZWFkIHRvIG1ha2UgdGhlIHJlcXVlc3RlZCBjaGFuZ2VzIGJlZm9yZSByZXR1cm5pbmcgKi8KICBXYWl0Rm9yU2luZ2xlT2JqZWN0KHNlcnZlcl9yZWFkeV9ldmVudCwgSU5GSU5JVEUpOwoKICBSZWxlYXNlTXV0ZXgobWdyX211dGV4KTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgUlBDUlQ0X3N0YXJ0X2xpc3RlbihCT09MIGF1dG9fbGlzdGVuKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXMgPSBSUENfU19BTFJFQURZX0xJU1RFTklORzsKCiAgVFJBQ0UoIlxuIik7CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogIGlmIChhdXRvX2xpc3RlbiB8fCAobWFudWFsX2xpc3Rlbl9jb3VudCsrID09IDApKQogIHsKICAgIHN0YXR1cyA9IFJQQ19TX09LOwogICAgaWYgKCsrbGlzdGVuX2NvdW50ID09IDEpIHsKICAgICAgSEFORExFIHNlcnZlcl90aHJlYWQ7CiAgICAgIC8qIGZpcnN0IGxpc3RlbmVyIGNyZWF0ZXMgc2VydmVyIHRocmVhZCAqLwogICAgICBpZiAoIW1ncl9tdXRleCkgbWdyX211dGV4ID0gQ3JlYXRlTXV0ZXhXKE5VTEwsIEZBTFNFLCBOVUxMKTsKICAgICAgaWYgKCFtZ3JfZXZlbnQpIG1ncl9ldmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBGQUxTRSwgRkFMU0UsIE5VTEwpOwogICAgICBpZiAoIXNlcnZlcl9yZWFkeV9ldmVudCkgc2VydmVyX3JlYWR5X2V2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIEZBTFNFLCBGQUxTRSwgTlVMTCk7CiAgICAgIHN0ZF9saXN0ZW4gPSBUUlVFOwogICAgICBzZXJ2ZXJfdGhyZWFkID0gQ3JlYXRlVGhyZWFkKE5VTEwsIDAsIFJQQ1JUNF9zZXJ2ZXJfdGhyZWFkLCBOVUxMLCAwLCBOVUxMKTsKICAgICAgQ2xvc2VIYW5kbGUoc2VydmVyX3RocmVhZCk7CiAgICB9CiAgfQogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwoKICByZXR1cm4gc3RhdHVzOwp9CgpzdGF0aWMgdm9pZCBSUENSVDRfc3RvcF9saXN0ZW4oQk9PTCBhdXRvX2xpc3RlbikKewogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZsaXN0ZW5fY3MpOwogIGlmIChhdXRvX2xpc3RlbiB8fCAoLS1tYW51YWxfbGlzdGVuX2NvdW50ID09IDApKQogIHsKICAgIGlmIChsaXN0ZW5fY291bnQgIT0gMCAmJiAtLWxpc3Rlbl9jb3VudCA9PSAwKSB7CiAgICAgIHN0ZF9saXN0ZW4gPSBGQUxTRTsKICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CiAgICAgIFJQQ1JUNF9zeW5jX3dpdGhfc2VydmVyX3RocmVhZCgpOwogICAgICByZXR1cm47CiAgICB9CiAgICBhc3NlcnQobGlzdGVuX2NvdW50ID49IDApOwogIH0KICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmbGlzdGVuX2NzKTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgUlBDUlQ0X3VzZV9wcm90c2VxKFJwY1NlcnZlclByb3RzZXEqIHBzKQp7CiAgUlBDUlQ0X0NyZWF0ZUNvbm5lY3Rpb24oJnBzLT5jb25uLCBUUlVFLCBwcy0+UHJvdHNlcSwgTlVMTCwgcHMtPkVuZHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwsIE5VTEwpOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmc2VydmVyX2NzKTsKICBwcy0+TmV4dCA9IHByb3RzZXFzOwogIHByb3RzZXFzID0gcHM7CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CgogIGlmIChzdGRfbGlzdGVuKSBSUENSVDRfc3luY193aXRoX3NlcnZlcl90aHJlYWQoKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVySW5xQmluZGluZ3MgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVySW5xQmluZGluZ3MoIFJQQ19CSU5ESU5HX1ZFQ1RPUioqIEJpbmRpbmdWZWN0b3IgKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgRFdPUkQgY291bnQ7CiAgUnBjU2VydmVyUHJvdHNlcSogcHM7CiAgUnBjQ29ubmVjdGlvbiogY29ubjsKCiAgaWYgKEJpbmRpbmdWZWN0b3IpCiAgICBUUkFDRSgiKCpCaW5kaW5nVmVjdG9yID09IF4lcClcbiIsICpCaW5kaW5nVmVjdG9yKTsKICBlbHNlCiAgICBFUlIoIihCaW5kaW5nVmVjdG9yID09IE5VTEwhIT8pXG4iKTsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgLyogY291bnQgY29ubmVjdGlvbnMgKi8KICBjb3VudCA9IDA7CiAgcHMgPSBwcm90c2VxczsKICB3aGlsZSAocHMpIHsKICAgIGNvbm4gPSBwcy0+Y29ubjsKICAgIHdoaWxlIChjb25uKSB7CiAgICAgIGNvdW50Kys7CiAgICAgIGNvbm4gPSBjb25uLT5OZXh0OwogICAgfQogICAgcHMgPSBwcy0+TmV4dDsKICB9CiAgaWYgKGNvdW50KSB7CiAgICAvKiBleHBvcnQgYmluZGluZ3MgKi8KICAgICpCaW5kaW5nVmVjdG9yID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihSUENfQklORElOR19WRUNUT1IpICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKFJQQ19CSU5ESU5HX0hBTkRMRSkqKGNvdW50LTEpKTsKICAgICgqQmluZGluZ1ZlY3RvciktPkNvdW50ID0gY291bnQ7CiAgICBjb3VudCA9IDA7CiAgICBwcyA9IHByb3RzZXFzOwogICAgd2hpbGUgKHBzKSB7CiAgICAgIGNvbm4gPSBwcy0+Y29ubjsKICAgICAgd2hpbGUgKGNvbm4pIHsKICAgICAgIFJQQ1JUNF9NYWtlQmluZGluZygoUnBjQmluZGluZyoqKSYoKkJpbmRpbmdWZWN0b3IpLT5CaW5kaW5nSFtjb3VudF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubik7CiAgICAgICBjb3VudCsrOwogICAgICAgY29ubiA9IGNvbm4tPk5leHQ7CiAgICAgIH0KICAgICAgcHMgPSBwcy0+TmV4dDsKICAgIH0KICAgIHN0YXR1cyA9IFJQQ19TX09LOwogIH0gZWxzZSB7CiAgICAqQmluZGluZ1ZlY3RvciA9IE5VTEw7CiAgICBzdGF0dXMgPSBSUENfU19OT19CSU5ESU5HUzsKICB9CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFFcEEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwQSggdW5zaWduZWQgY2hhciAqUHJvdHNlcSwgVUlOVCBNYXhDYWxscywgdW5zaWduZWQgY2hhciAqRW5kcG9pbnQsIExQVk9JRCBTZWN1cml0eURlc2NyaXB0b3IgKQp7CiAgUlBDX1BPTElDWSBwb2xpY3k7CiAgCiAgVFJBQ0UoICIoJXMsJXUsJXMsJXApXG4iLCBQcm90c2VxLCBNYXhDYWxscywgRW5kcG9pbnQsIFNlY3VyaXR5RGVzY3JpcHRvciApOwogIAogIC8qIFRoaXMgc2hvdWxkIHByb3ZpZGUgdGhlIGRlZmF1bHQgYmVoYXZpb3VyICovCiAgcG9saWN5Lkxlbmd0aCAgICAgICAgPSBzaXplb2YoIHBvbGljeSApOwogIHBvbGljeS5FbmRwb2ludEZsYWdzID0gMDsKICBwb2xpY3kuTklDRmxhZ3MgICAgICA9IDA7CiAgCiAgcmV0dXJuIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4QSggUHJvdHNlcSwgTWF4Q2FsbHMsIEVuZHBvaW50LCBTZWN1cml0eURlc2NyaXB0b3IsICZwb2xpY3kgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclVzZVByb3RzZXFFcFcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwVyggTFBXU1RSIFByb3RzZXEsIFVJTlQgTWF4Q2FsbHMsIExQV1NUUiBFbmRwb2ludCwgTFBWT0lEIFNlY3VyaXR5RGVzY3JpcHRvciApCnsKICBSUENfUE9MSUNZIHBvbGljeTsKICAKICBUUkFDRSggIiglcywldSwlcywlcClcbiIsIGRlYnVnc3RyX3coIFByb3RzZXEgKSwgTWF4Q2FsbHMsIGRlYnVnc3RyX3coIEVuZHBvaW50ICksIFNlY3VyaXR5RGVzY3JpcHRvciApOwogIAogIC8qIFRoaXMgc2hvdWxkIHByb3ZpZGUgdGhlIGRlZmF1bHQgYmVoYXZpb3VyICovCiAgcG9saWN5Lkxlbmd0aCAgICAgICAgPSBzaXplb2YoIHBvbGljeSApOwogIHBvbGljeS5FbmRwb2ludEZsYWdzID0gMDsKICBwb2xpY3kuTklDRmxhZ3MgICAgICA9IDA7CiAgCiAgcmV0dXJuIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4VyggUHJvdHNlcSwgTWF4Q2FsbHMsIEVuZHBvaW50LCBTZWN1cml0eURlc2NyaXB0b3IsICZwb2xpY3kgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIGFsbG9jX3NlcnZlcnByb3Rvc2VxIChpbnRlcm5hbCkKICovCnN0YXRpYyBScGNTZXJ2ZXJQcm90c2VxICphbGxvY19zZXJ2ZXJwcm90b3NlcShVSU5UIE1heENhbGxzLCBjaGFyICpQcm90c2VxLCBjaGFyICpFbmRwb2ludCkKewogIFJwY1NlcnZlclByb3RzZXEqIHBzOwoKICBwcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUnBjU2VydmVyUHJvdHNlcSkpOwogIHBzLT5NYXhDYWxscyA9IE1heENhbGxzOwogIHBzLT5Qcm90c2VxID0gUHJvdHNlcTsKICBwcy0+RW5kcG9pbnQgPSBFbmRwb2ludDsKCiAgcmV0dXJuIHBzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclVzZVByb3RzZXFFcEV4QSggdW5zaWduZWQgY2hhciAqUHJvdHNlcSwgVUlOVCBNYXhDYWxscywgdW5zaWduZWQgY2hhciAqRW5kcG9pbnQsIExQVk9JRCBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFJQQ19QT0xJQ1kgbHBQb2xpY3kgKQp7CiAgY2hhciAqc3pwcyA9IChjaGFyKilQcm90c2VxLCAqc3plcCA9IChjaGFyKilFbmRwb2ludDsKICBScGNTZXJ2ZXJQcm90c2VxKiBwczsKCiAgVFJBQ0UoIiglcywldSwlcywlcCx7JXUsJWx1LCVsdX0pXG4iLCBkZWJ1Z3N0cl9hKHN6cHMpLCBNYXhDYWxscywKICAgICAgIGRlYnVnc3RyX2Eoc3plcCksIFNlY3VyaXR5RGVzY3JpcHRvciwKICAgICAgIGxwUG9saWN5LT5MZW5ndGgsIGxwUG9saWN5LT5FbmRwb2ludEZsYWdzLCBscFBvbGljeS0+TklDRmxhZ3MgKTsKCiAgcHMgPSBhbGxvY19zZXJ2ZXJwcm90b3NlcShNYXhDYWxscywgUlBDUlQ0X3N0cmR1cEEoc3pwcyksIFJQQ1JUNF9zdHJkdXBBKHN6ZXApKTsKCiAgcmV0dXJuIFJQQ1JUNF91c2VfcHJvdHNlcShwcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxRXBFeFcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVXNlUHJvdHNlcUVwRXhXKCBMUFdTVFIgUHJvdHNlcSwgVUlOVCBNYXhDYWxscywgTFBXU1RSIEVuZHBvaW50LCBMUFZPSUQgU2VjdXJpdHlEZXNjcmlwdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBSUENfUE9MSUNZIGxwUG9saWN5ICkKewogIFJwY1NlcnZlclByb3RzZXEqIHBzOwoKICBUUkFDRSgiKCVzLCV1LCVzLCVwLHsldSwlbHUsJWx1fSlcbiIsIGRlYnVnc3RyX3coIFByb3RzZXEgKSwgTWF4Q2FsbHMsCiAgICAgICBkZWJ1Z3N0cl93KCBFbmRwb2ludCApLCBTZWN1cml0eURlc2NyaXB0b3IsCiAgICAgICBscFBvbGljeS0+TGVuZ3RoLCBscFBvbGljeS0+RW5kcG9pbnRGbGFncywgbHBQb2xpY3ktPk5JQ0ZsYWdzICk7CgogIHBzID0gYWxsb2Nfc2VydmVycHJvdG9zZXEoTWF4Q2FsbHMsIFJQQ1JUNF9zdHJkdXBXdG9BKFByb3RzZXEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDUlQ0X3N0cmR1cFd0b0EoRW5kcG9pbnQpKTsKCiAgcmV0dXJuIFJQQ1JUNF91c2VfcHJvdHNlcShwcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVc2VQcm90c2VxQSh1bnNpZ25lZCBjaGFyICpQcm90c2VxLCB1bnNpZ25lZCBpbnQgTWF4Q2FsbHMsIHZvaWQgKlNlY3VyaXR5RGVzY3JpcHRvcikKewogIFRSQUNFKCIoUHJvdHNlcSA9PSAlcywgTWF4Q2FsbHMgPT0gJWQsIFNlY3VyaXR5RGVzY3JpcHRvciA9PSBeJXApXG4iLCBkZWJ1Z3N0cl9hKChjaGFyKilQcm90c2VxKSwgTWF4Q2FsbHMsIFNlY3VyaXR5RGVzY3JpcHRvcik7CiAgcmV0dXJuIFJwY1NlcnZlclVzZVByb3RzZXFFcEEoUHJvdHNlcSwgTWF4Q2FsbHMsIE5VTEwsIFNlY3VyaXR5RGVzY3JpcHRvcik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVc2VQcm90c2VxVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVc2VQcm90c2VxVyhMUFdTVFIgUHJvdHNlcSwgdW5zaWduZWQgaW50IE1heENhbGxzLCB2b2lkICpTZWN1cml0eURlc2NyaXB0b3IpCnsKICBUUkFDRSgiUHJvdHNlcSA9PSAlcywgTWF4Q2FsbHMgPT0gJWQsIFNlY3VyaXR5RGVzY3JpcHRvciA9PSBeJXApXG4iLCBkZWJ1Z3N0cl93KFByb3RzZXEpLCBNYXhDYWxscywgU2VjdXJpdHlEZXNjcmlwdG9yKTsKICByZXR1cm4gUnBjU2VydmVyVXNlUHJvdHNlcUVwVyhQcm90c2VxLCBNYXhDYWxscywgTlVMTCwgU2VjdXJpdHlEZXNjcmlwdG9yKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVySWYgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyUmVnaXN0ZXJJZiggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBSUENfTUdSX0VQViogTWdyRXB2ICkKewogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBNZ3JFcHYpOwogIHJldHVybiBScGNTZXJ2ZXJSZWdpc3RlcklmMiggSWZTcGVjLCBNZ3JUeXBlVXVpZCwgTWdyRXB2LCAwLCBSUENfQ19MSVNURU5fTUFYX0NBTExTX0RFRkFVTFQsIChVSU5UKS0xLCBOVUxMICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJSZWdpc3RlcklmRXggKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyUmVnaXN0ZXJJZkV4KCBSUENfSUZfSEFORExFIElmU3BlYywgVVVJRCogTWdyVHlwZVV1aWQsIFJQQ19NR1JfRVBWKiBNZ3JFcHYsCiAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBGbGFncywgVUlOVCBNYXhDYWxscywgUlBDX0lGX0NBTExCQUNLX0ZOKiBJZkNhbGxiYWNrRm4gKQp7CiAgVFJBQ0UoIiglcCwlcywlcCwldSwldSwlcClcbiIsIElmU3BlYywgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIE1nckVwdiwgRmxhZ3MsIE1heENhbGxzLCBJZkNhbGxiYWNrRm4pOwogIHJldHVybiBScGNTZXJ2ZXJSZWdpc3RlcklmMiggSWZTcGVjLCBNZ3JUeXBlVXVpZCwgTWdyRXB2LCBGbGFncywgTWF4Q2FsbHMsIChVSU5UKS0xLCBJZkNhbGxiYWNrRm4gKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVySWYyIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVySWYyKCBSUENfSUZfSEFORExFIElmU3BlYywgVVVJRCogTWdyVHlwZVV1aWQsIFJQQ19NR1JfRVBWKiBNZ3JFcHYsCiAgICAgICAgICAgICAgICAgICAgICBVSU5UIEZsYWdzLCBVSU5UIE1heENhbGxzLCBVSU5UIE1heFJwY1NpemUsIFJQQ19JRl9DQUxMQkFDS19GTiogSWZDYWxsYmFja0ZuICkKewogIFBSUENfU0VSVkVSX0lOVEVSRkFDRSBJZiA9IChQUlBDX1NFUlZFUl9JTlRFUkZBQ0UpSWZTcGVjOwogIFJwY1NlcnZlckludGVyZmFjZSogc2lmOwogIHVuc2lnbmVkIGludCBpOwoKICBUUkFDRSgiKCVwLCVzLCVwLCV1LCV1LCV1LCVwKVxuIiwgSWZTcGVjLCBkZWJ1Z3N0cl9ndWlkKE1nclR5cGVVdWlkKSwgTWdyRXB2LCBGbGFncywgTWF4Q2FsbHMsCiAgICAgICAgIE1heFJwY1NpemUsIElmQ2FsbGJhY2tGbik7CiAgVFJBQ0UoIiBpbnRlcmZhY2UgaWQ6ICVzICVkLiVkXG4iLCBkZWJ1Z3N0cl9ndWlkKCZJZi0+SW50ZXJmYWNlSWQuU3ludGF4R1VJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZi0+SW50ZXJmYWNlSWQuU3ludGF4VmVyc2lvbi5NYWpvclZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJZi0+SW50ZXJmYWNlSWQuU3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb24pOwogIFRSQUNFKCIgdHJhbnNmZXIgc3ludGF4OiAlcyAlZC4lZFxuIiwgZGVidWdzdHJfZ3VpZCgmSWYtPlRyYW5zZmVyU3ludGF4LlN5bnRheEdVSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYtPlRyYW5zZmVyU3ludGF4LlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSWYtPlRyYW5zZmVyU3ludGF4LlN5bnRheFZlcnNpb24uTWlub3JWZXJzaW9uKTsKICBUUkFDRSgiIGRpc3BhdGNoIHRhYmxlOiAlcFxuIiwgSWYtPkRpc3BhdGNoVGFibGUpOwogIGlmIChJZi0+RGlzcGF0Y2hUYWJsZSkgewogICAgVFJBQ0UoIiAgZGlzcGF0Y2ggdGFibGUgY291bnQ6ICVkXG4iLCBJZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZUNvdW50KTsKICAgIGZvciAoaT0wOyBpPElmLT5EaXNwYXRjaFRhYmxlLT5EaXNwYXRjaFRhYmxlQ291bnQ7IGkrKykgewogICAgICBUUkFDRSgiICAgZW50cnkgJWQ6ICVwXG4iLCBpLCBJZi0+RGlzcGF0Y2hUYWJsZS0+RGlzcGF0Y2hUYWJsZVtpXSk7CiAgICB9CiAgICBUUkFDRSgiICByZXNlcnZlZDogJWxkXG4iLCBJZi0+RGlzcGF0Y2hUYWJsZS0+UmVzZXJ2ZWQpOwogIH0KICBUUkFDRSgiIHByb3RzZXEgZW5kcG9pbnQgY291bnQ6ICVkXG4iLCBJZi0+UnBjUHJvdHNlcUVuZHBvaW50Q291bnQpOwogIFRSQUNFKCIgZGVmYXVsdCBtYW5hZ2VyIGVwdjogJXBcbiIsIElmLT5EZWZhdWx0TWFuYWdlckVwdik7CiAgVFJBQ0UoIiBpbnRlcnByZXRlciBpbmZvOiAlcFxuIiwgSWYtPkludGVycHJldGVySW5mbyk7CgogIHNpZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUnBjU2VydmVySW50ZXJmYWNlKSk7CiAgc2lmLT5JZiAgICAgICAgICAgPSBJZjsKICBpZiAoTWdyVHlwZVV1aWQpIHsKICAgIG1lbWNweSgmc2lmLT5NZ3JUeXBlVXVpZCwgTWdyVHlwZVV1aWQsIHNpemVvZihVVUlEKSk7CiAgICBzaWYtPk1nckVwdiAgICAgICA9IE1nckVwdjsKICB9IGVsc2UgewogICAgbWVtc2V0KCZzaWYtPk1nclR5cGVVdWlkLCAwLCBzaXplb2YoVVVJRCkpOwogICAgc2lmLT5NZ3JFcHYgICAgICAgPSBJZi0+RGVmYXVsdE1hbmFnZXJFcHY7CiAgfQogIHNpZi0+RmxhZ3MgICAgICAgID0gRmxhZ3M7CiAgc2lmLT5NYXhDYWxscyAgICAgPSBNYXhDYWxsczsKICBzaWYtPk1heFJwY1NpemUgICA9IE1heFJwY1NpemU7CiAgc2lmLT5JZkNhbGxiYWNrRm4gPSBJZkNhbGxiYWNrRm47CgogIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZzZXJ2ZXJfY3MpOwogIHNpZi0+TmV4dCA9IGlmczsKICBpZnMgPSBzaWY7CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJnNlcnZlcl9jcyk7CgogIGlmIChzaWYtPkZsYWdzICYgUlBDX0lGX0FVVE9MSVNURU4pIHsKICAgIFJQQ1JUNF9zdGFydF9saXN0ZW4oVFJVRSk7CgogICAgLyogbWFrZSBzdXJlIHNlcnZlciBpcyBhY3R1YWxseSBsaXN0ZW5pbmcgb24gdGhlIGludGVyZmFjZSBiZWZvcmUKICAgICAqIHJldHVybmluZyAqLwogICAgUlBDUlQ0X3N5bmNfd2l0aF9zZXJ2ZXJfdGhyZWFkKCk7CiAgfQoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVbnJlZ2lzdGVySWYgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyVW5yZWdpc3RlcklmKCBSUENfSUZfSEFORExFIElmU3BlYywgVVVJRCogTWdyVHlwZVV1aWQsIFVJTlQgV2FpdEZvckNhbGxzVG9Db21wbGV0ZSApCnsKICBGSVhNRSgiKElmU3BlYyA9PSAoUlBDX0lGX0hBTkRMRSleJXAsIE1nclR5cGVVdWlkID09ICVzLCBXYWl0Rm9yQ2FsbHNUb0NvbXBsZXRlID09ICV1KTogc3R1YlxuIiwKICAgIElmU3BlYywgZGVidWdzdHJfZ3VpZChNZ3JUeXBlVXVpZCksIFdhaXRGb3JDYWxsc1RvQ29tcGxldGUpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJVbnJlZ2lzdGVySWZFeCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTZXJ2ZXJVbnJlZ2lzdGVySWZFeCggUlBDX0lGX0hBTkRMRSBJZlNwZWMsIFVVSUQqIE1nclR5cGVVdWlkLCBpbnQgUnVuZG93bkNvbnRleHRIYW5kbGVzICkKewogIEZJWE1FKCIoSWZTcGVjID09IChSUENfSUZfSEFORExFKV4lcCwgTWdyVHlwZVV1aWQgPT0gJXMsIFJ1bmRvd25Db250ZXh0SGFuZGxlcyA9PSAlZCk6IHN0dWJcbiIsCiAgICBJZlNwZWMsIGRlYnVnc3RyX2d1aWQoTWdyVHlwZVV1aWQpLCBSdW5kb3duQ29udGV4dEhhbmRsZXMpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNPYmplY3RTZXRUeXBlIChSUENSVDQuQCkKICoKICogUEFSQU1TCiAqICAgT2JqVXVpZCAgW0ldICJPYmplY3QiIFVVSUQKICogICBUeXBlVXVpZCBbSV0gIlR5cGUiIFVVSUQKICoKICogUkVUVVJOUwogKiAgIFJQQ19TX09LICAgICAgICAgICAgICAgICBUaGUgY2FsbCBzdWNjZWVkZWQKICogICBSUENfU19JTlZBTElEX09CSkVDVCAgICAgVGhlIHByb3ZpZGVkIG9iamVjdCAobmlsKSBpcyBub3QgdmFsaWQKICogICBSUENfU19BTFJFQURZX1JFR0lTVEVSRUQgVGhlIHByb3ZpZGVkIG9iamVjdCBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQKICoKICogTWFwcyAiT2JqZWN0IiBVVUlEcyB0byAiVHlwZSIgVVVJRCdzLiAgUGFzc2luZyB0aGUgbmlsIFVVSUQgYXMgdGhlIHR5cGUKICogcmVzZXRzIHRoZSBtYXBwaW5nIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCBVVUlEIHRvIG5pbCAodGhlIGRlZmF1bHQpLgogKiBUaGUgbmlsIG9iamVjdCBpcyBhbHdheXMgYXNzb2NpYXRlZCB3aXRoIHRoZSBuaWwgdHlwZSBhbmQgY2Fubm90IGJlCiAqIHJlYXNzaWduZWQuICBTZXJ2ZXJzIGNhbiBzdXBwb3J0IG11bHRpcGxlIGltcGxlbWVudGF0aW9ucyBvbiB0aGUgc2FtZQogKiBpbnRlcmZhY2UgYnkgcmVnaXN0ZXJpbmcgZGlmZmVyZW50IGVuZC1wb2ludCB2ZWN0b3JzIGZvciB0aGUgZGlmZmVyZW50CiAqIHR5cGVzLiAgVGhlcmUncyBubyBuZWVkIHRvIGNhbGwgdGhpcyBpZiBhIHNlcnZlciBvbmx5IHN1cHBvcnRzIHRoZSBuaWwKICogdHlwZSwgYXMgaXMgdHlwaWNhbC4KICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY09iamVjdFNldFR5cGUoIFVVSUQqIE9ialV1aWQsIFVVSUQqIFR5cGVVdWlkICkKewogIFJwY09ialR5cGVNYXAgKm1hcCA9IFJwY09ialR5cGVNYXBzLCAqcHJldiA9IE5VTEw7CiAgUlBDX1NUQVRVUyBkdW1teTsKCiAgVFJBQ0UoIihPYmpVVUlEID09ICVzLCBUeXBlVXVpZCA9PSAlcykuXG4iLCBkZWJ1Z3N0cl9ndWlkKE9ialV1aWQpLCBkZWJ1Z3N0cl9ndWlkKFR5cGVVdWlkKSk7CiAgaWYgKCghIE9ialV1aWQpIHx8IFV1aWRJc05pbChPYmpVdWlkLCAmZHVtbXkpKSB7CiAgICAvKiBuaWwgdXVpZCBjYW5ub3QgYmUgcmVtYXBwZWQgKi8KICAgIHJldHVybiBSUENfU19JTlZBTElEX09CSkVDVDsKICB9CgogIC8qIGZpbmQgdGhlIG1hcHBpbmcgZm9yIHRoaXMgb2JqZWN0IGlmIHRoZXJlIGlzIG9uZSAuLi4gKi8KICB3aGlsZSAobWFwKSB7CiAgICBpZiAoISBVdWlkQ29tcGFyZShPYmpVdWlkLCAmbWFwLT5PYmplY3QsICZkdW1teSkpIGJyZWFrOwogICAgcHJldiA9IG1hcDsKICAgIG1hcCA9IG1hcC0+bmV4dDsKICB9CiAgaWYgKCghIFR5cGVVdWlkKSB8fCBVdWlkSXNOaWwoVHlwZVV1aWQsICZkdW1teSkpIHsKICAgIC8qIC4uLiBhbmQgZHJvcCBpdCBmcm9tIHRoZSBsaXN0ICovCiAgICBpZiAobWFwKSB7CiAgICAgIGlmIChwcmV2KSAKICAgICAgICBwcmV2LT5uZXh0ID0gbWFwLT5uZXh0OwogICAgICBlbHNlCiAgICAgICAgUnBjT2JqVHlwZU1hcHMgPSBtYXAtPm5leHQ7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1hcCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIC4uLiAsIGZhaWwgaWYgd2UgZm91bmQgaXQgLi4uICovCiAgICBpZiAobWFwKQogICAgICByZXR1cm4gUlBDX1NfQUxSRUFEWV9SRUdJU1RFUkVEOwogICAgLyogLi4uIG90aGVyd2lzZSBjcmVhdGUgYSBuZXcgb25lIGFuZCBhZGQgaXQgaW4uICovCiAgICBtYXAgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFJwY09ialR5cGVNYXApKTsKICAgIG1lbWNweSgmbWFwLT5PYmplY3QsIE9ialV1aWQsIHNpemVvZihVVUlEKSk7CiAgICBtZW1jcHkoJm1hcC0+VHlwZSwgVHlwZVV1aWQsIHNpemVvZihVVUlEKSk7CiAgICBtYXAtPm5leHQgPSBOVUxMOwogICAgaWYgKHByZXYpCiAgICAgIHByZXYtPm5leHQgPSBtYXA7IC8qIHByZXYgaXMgdGhlIGxhc3QgbWFwIGluIHRoZSBsaW5rbGlzdCAqLwogICAgZWxzZQogICAgICBScGNPYmpUeXBlTWFwcyA9IG1hcDsKICB9CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9BIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1NlcnZlclJlZ2lzdGVyQXV0aEluZm9BKCB1bnNpZ25lZCBjaGFyICpTZXJ2ZXJQcmluY05hbWUsIHVuc2lnbmVkIGxvbmcgQXV0aG5TdmMsIFJQQ19BVVRIX0tFWV9SRVRSSUVWQUxfRk4gR2V0S2V5Rm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgQXJnICkKewogIEZJWE1FKCAiKCVzLCVsdSwlcCwlcCk6IHN0dWJcbiIsIFNlcnZlclByaW5jTmFtZSwgQXV0aG5TdmMsIEdldEtleUZuLCBBcmcgKTsKICAKICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRITl9TRVJWSUNFOyAvKiBXZSBkb24ndCBrbm93IGFueSBhdXRoZW50aWNhdGlvbiBzZXJ2aWNlcyAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU2VydmVyUmVnaXN0ZXJBdXRoSW5mb1cgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyUmVnaXN0ZXJBdXRoSW5mb1coIExQV1NUUiBTZXJ2ZXJQcmluY05hbWUsIHVuc2lnbmVkIGxvbmcgQXV0aG5TdmMsIFJQQ19BVVRIX0tFWV9SRVRSSUVWQUxfRk4gR2V0S2V5Rm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgQXJnICkKewogIEZJWE1FKCAiKCVzLCVsdSwlcCwlcCk6IHN0dWJcbiIsIGRlYnVnc3RyX3coIFNlcnZlclByaW5jTmFtZSApLCBBdXRoblN2YywgR2V0S2V5Rm4sIEFyZyApOwogIAogIHJldHVybiBSUENfU19VTktOT1dOX0FVVEhOX1NFUlZJQ0U7IC8qIFdlIGRvbid0IGtub3cgYW55IGF1dGhlbnRpY2F0aW9uIHNlcnZpY2VzICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTZXJ2ZXJMaXN0ZW4gKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU2VydmVyTGlzdGVuKCBVSU5UIE1pbmltdW1DYWxsVGhyZWFkcywgVUlOVCBNYXhDYWxscywgVUlOVCBEb250V2FpdCApCnsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgVFJBQ0UoIigldSwldSwldSlcbiIsIE1pbmltdW1DYWxsVGhyZWFkcywgTWF4Q2FsbHMsIERvbnRXYWl0KTsKCiAgaWYgKCFwcm90c2VxcykKICAgIHJldHVybiBSUENfU19OT19QUk9UU0VRU19SRUdJU1RFUkVEOwoKICBzdGF0dXMgPSBSUENSVDRfc3RhcnRfbGlzdGVuKEZBTFNFKTsKCiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgIFJQQ1JUNF9zeW5jX3dpdGhfc2VydmVyX3RocmVhZCgpOwoKICBpZiAoRG9udFdhaXQgfHwgKHN0YXR1cyAhPSBSUENfU19PSykpIHJldHVybiBzdGF0dXM7CgogIHJldHVybiBScGNNZ210V2FpdFNlcnZlckxpc3RlbigpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTWdtdFNlcnZlcldhaXRMaXN0ZW4gKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTWdtdFdhaXRTZXJ2ZXJMaXN0ZW4oIHZvaWQgKQp7CiAgVFJBQ0UoIigpXG4iKTsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogIGlmICghc3RkX2xpc3RlbikgewogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CiAgICByZXR1cm4gUlBDX1NfTk9UX0xJU1RFTklORzsKICB9CiAgCiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmxpc3Rlbl9jcyk7CgogIEZJWE1FKCJub3Qgd2FpdGluZyBmb3Igc2VydmVyIGNhbGxzIHRvIGZpbmlzaFxuIik7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRTdG9wU2VydmVyTGlzdGVuaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRTdG9wU2VydmVyTGlzdGVuaW5nICggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcgKQp7CiAgVFJBQ0UoIihCaW5kaW5nID09IChSUENfQklORElOR19IQU5ETEUpXiVwKVxuIiwgQmluZGluZyk7CgogIGlmIChCaW5kaW5nKSB7CiAgICBGSVhNRSgiY2xpZW50LXNpZGUgaW52b2NhdGlvbiBub3QgaW1wbGVtZW50ZWQuXG4iKTsKICAgIHJldHVybiBSUENfU19XUk9OR19LSU5EX09GX0JJTkRJTkc7CiAgfQogIAogIFJQQ1JUNF9zdG9wX2xpc3RlbihGQUxTRSk7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRFbmFibGVJZGxlQ2xlYW51cCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210RW5hYmxlSWRsZUNsZWFudXAodm9pZCkKewogICAgRklYTUUoIigpOiBzdHViXG4iKTsKICAgIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIElfUnBjU2VydmVyU3RhcnRMaXN0ZW5pbmcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNTZXJ2ZXJTdGFydExpc3RlbmluZyggSFdORCBoV25kICkKewogIEZJWE1FKCAiKCVwKTogc3R1YlxuIiwgaFduZCApOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBJX1JwY1NlcnZlclN0b3BMaXN0ZW5pbmcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNTZXJ2ZXJTdG9wTGlzdGVuaW5nKCB2b2lkICkKewogIEZJWE1FKCAiKCk6IHN0dWJcbiIgKTsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgSV9ScGNXaW5kb3dQcm9jIChSUENSVDQuQCkKICovClVJTlQgV0lOQVBJIElfUnBjV2luZG93UHJvYyggdm9pZCAqaFduZCwgVUlOVCBNZXNzYWdlLCBVSU5UIHdQYXJhbSwgVUxPTkcgbFBhcmFtICkKewogIEZJWE1FKCAiKCVwLCUwOHgsJTA4eCwlMDhseCk6IHN0dWJcbiIsIGhXbmQsIE1lc3NhZ2UsIHdQYXJhbSwgbFBhcmFtICk7CgogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTWdtdElucUlmSWRzIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRJbnFJZklkcyhSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX0lGX0lEX1ZFQ1RPUiAqKklmSWRWZWN0b3IpCnsKICBGSVhNRSgiKCVwLCVwKTogc3R1YlxuIiwgQmluZGluZywgSWZJZFZlY3Rvcik7CiAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRFcEVsdElucUJlZ2luIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRFcEVsdElucUJlZ2luKFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCB1bnNpZ25lZCBsb25nIElucXVpcnlUeXBlLAogICAgUlBDX0lGX0lEICpJZklkLCB1bnNpZ25lZCBsb25nIFZlcnNPcHRpb24sIFVVSUQgKk9iamVjdFV1aWQsIFJQQ19FUF9JTlFfSEFORExFKiBJbnF1aXJ5Q29udGV4dCkKewogIEZJWE1FKCIoJXAsJWx1LCVwLCVsdSwlcCwlcCk6IHN0dWJcbiIsCiAgICAgICAgQmluZGluZywgSW5xdWlyeVR5cGUsIElmSWQsIFZlcnNPcHRpb24sIE9iamVjdFV1aWQsIElucXVpcnlDb250ZXh0KTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTWdtdElzU2VydmVyTGlzdGVuaW5nIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRJc1NlcnZlckxpc3RlbmluZyhSUENfQklORElOR19IQU5ETEUgQmluZGluZykKewogIEZJWE1FKCIoJXApOiBzdHViXG4iLCBCaW5kaW5nKTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTWdtdFNldFNlcnZlclN0YWNrU2l6ZSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210U2V0U2VydmVyU3RhY2tTaXplKHVuc2lnbmVkIGludCBUaHJlYWRTdGFja1NpemUpCnsKICBGSVhNRSgiKDB4JXgpOiBzdHViXG4iLCBUaHJlYWRTdGFja1NpemUpOwogIHJldHVybiBSUENfU19PSzsKfQo=