LyoKICogQ09NIHN0dWIgKENTdGRTdHViQnVmZmVyKSBpbXBsZW1lbnRhdGlvbgogKgogKiBDb3B5cmlnaHQgMjAwMSBPdmUgS+V2ZW4sIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJleGNwdC5oIgoKI2luY2x1ZGUgIm9iamJhc2UuaCIKI2luY2x1ZGUgInJwY3Byb3h5LmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKCiNpbmNsdWRlICJjcHNmLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKI2RlZmluZSBTVFVCX0hFQURFUihUaGlzKSAoKChjb25zdCBDSW50ZXJmYWNlU3R1YkhlYWRlciopKChUaGlzKS0+bHBWdGJsKSlbLTFdKQoKc3RhdGljIFdJTkVfRVhDRVBUSU9OX0ZJTFRFUihzdHViX2ZpbHRlcikKewogICAgaWYgKEdldEV4Y2VwdGlvbkluZm9ybWF0aW9uKCktPkV4Y2VwdGlvblJlY29yZC0+RXhjZXB0aW9uRmxhZ3MgJiBFWENFUFRJT05fTk9OQ09OVElOVUFCTEUpCiAgICAgICAgcmV0dXJuIEVYQ0VQVElPTl9DT05USU5VRV9TRUFSQ0g7CiAgICByZXR1cm4gRVhDRVBUSU9OX0VYRUNVVEVfSEFORExFUjsKfQoKdHlwZWRlZiBzdHJ1Y3QKewogICAgSVVua25vd25WdGJsICpiYXNlX29iajsKICAgIElScGNTdHViQnVmZmVyICpiYXNlX3N0dWI7CiAgICBDU3RkU3R1YkJ1ZmZlciBzdHViX2J1ZmZlcjsKfSBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3Q7CgpzdGF0aWMgaW5saW5lIGNzdGRzdHViYnVmZmVyX2RlbGVnYXRpbmdfdCAqaW1wbF9mcm9tX2RlbGVnYXRpbmcoIElScGNTdHViQnVmZmVyICppZmFjZSApCnsKICAgIHJldHVybiAoY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190KikoKGNoYXIgKilpZmFjZSAtIEZJRUxEX09GRlNFVChjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QsIHN0dWJfYnVmZmVyKSk7Cn0KCkhSRVNVTFQgV0lOQVBJIENTdGRTdHViQnVmZmVyX0NvbnN0cnVjdChSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBVTktOT1dOIHBVbmtTZXJ2ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBDSW50ZXJmYWNlTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDSW50ZXJmYWNlU3R1YlZ0YmwgKnZ0YmwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUFNGQUNUT1JZQlVGRkVSIHBQU0ZhY3RvcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDU1RVQkJVRkZFUiAqcHBTdHViKQp7CiAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXM7CiAgSVVua25vd24gKnB2U2VydmVyOwogIEhSRVNVTFQgcjsKICBUUkFDRSgiKCVwLCVwLCVwLCVwKSAlc1xuIiwgcFVua1NlcnZlciwgdnRibCwgcFBTRmFjdG9yeSwgcHBTdHViLCBuYW1lKTsKICBUUkFDRSgiaWlkPSVzXG4iLCBkZWJ1Z3N0cl9ndWlkKHZ0YmwtPmhlYWRlci5waWlkKSk7CiAgVFJBQ0UoInZ0Ymw9JXBcbiIsICZ2dGJsLT5WdGJsKTsKCiAgaWYgKCFJc0VxdWFsR1VJRCh2dGJsLT5oZWFkZXIucGlpZCwgcmlpZCkpIHsKICAgIEVSUigiSUlEIG1pc21hdGNoIGR1cmluZyBzdHViIGNyZWF0aW9uXG4iKTsKICAgIHJldHVybiBSUENfRV9VTkVYUEVDVEVEOwogIH0KCiAgciA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKHBVbmtTZXJ2ZXIsIHJpaWQsICh2b2lkKiopJnB2U2VydmVyKTsKICBpZihGQUlMRUQocikpCiAgICByZXR1cm4gcjsKCiAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKENTdGRTdHViQnVmZmVyKSk7CiAgaWYgKCFUaGlzKSB7CiAgICBJVW5rbm93bl9SZWxlYXNlKHB2U2VydmVyKTsKICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogIH0KCiAgVGhpcy0+bHBWdGJsID0gJnZ0YmwtPlZ0Ymw7CiAgVGhpcy0+UmVmQ291bnQgPSAxOwogIFRoaXMtPnB2U2VydmVyT2JqZWN0ID0gcHZTZXJ2ZXI7CiAgVGhpcy0+cFBTRmFjdG9yeSA9IHBQU0ZhY3Rvcnk7CiAgKnBwU3R1YiA9IChMUFJQQ1NUVUJCVUZGRVIpVGhpczsKCiAgSVBTRmFjdG9yeUJ1ZmZlcl9BZGRSZWYocFBTRmFjdG9yeSk7CiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGRlbGVnYXRpbmdfdnRibF9zZWN0aW9uOwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTl9ERUJVRyBjcml0c2VjdF9kZWJ1ZyA9CnsKICAgIDAsIDAsICZkZWxlZ2F0aW5nX3Z0Ymxfc2VjdGlvbiwKICAgIHsgJmNyaXRzZWN0X2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QsICZjcml0c2VjdF9kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAgIDAsIDAsIHsgKERXT1JEX1BUUikoX19GSUxFX18gIjogZGVsZWdhdGluZ192dGJsX3NlY3Rpb24iKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGRlbGVnYXRpbmdfdnRibF9zZWN0aW9uID0geyAmY3JpdHNlY3RfZGVidWcsIC0xLCAwLCAwLCAwLCAwIH07Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBEV09SRCByZWY7CiAgICBEV09SRCBzaXplOwogICAgdm9pZCAqKm1ldGhvZHM7CiAgICBJVW5rbm93blZ0YmwgdnRibDsKICAgIC8qIHJlbWFpbmluZyBlbnRyaWVzIGluIHZ0YmwgKi8KfSByZWZfY291bnRlZF92dGJsOwoKc3RhdGljIHN0cnVjdAp7CiAgICByZWZfY291bnRlZF92dGJsICp0YWJsZTsKfSBjdXJyZW50X3Z0Ymw7CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIGRlbGVnYXRpbmdfUXVlcnlJbnRlcmZhY2UoSVVua25vd24gKnBVbmssIFJFRklJRCBpaWQsIHZvaWQgKipwcHYpCnsKICAgICpwcHYgPSAodm9pZCAqKXBVbms7CiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBkZWxlZ2F0aW5nX0FkZFJlZihJVW5rbm93biAqcFVuaykKewogICAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgZGVsZWdhdGluZ19SZWxlYXNlKElVbmtub3duICpwVW5rKQp7CiAgICByZXR1cm4gMTsKfQoKI2lmIGRlZmluZWQoX19pMzg2X18pCgovKiBUaGUgaWRlYSBoZXJlIGlzIHRvIHJlcGxhY2UgdGhlIGZpcnN0IHBhcmFtIG9uIHRoZSBzdGFjawogICBpZS4gVGhpcyAod2hpY2ggd2lsbCBwb2ludCB0byBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QpCiAgIHdpdGggVGhpcy0+c3R1Yl9idWZmZXIucHZTZXJ2ZXJPYmplY3QgYW5kIHRoZW4ganVtcCB0byB0aGUKICAgcmVsZXZhbnQgb2Zmc2V0IGluIFRoaXMtPnN0dWJfYnVmZmVyLnB2U2VydmVyT2JqZWN0J3MgdnRibC4KKi8KI2luY2x1ZGUgInBzaHBhY2sxLmgiCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JEIG1vdjE7ICAgIC8qIG1vdiAweDQoJWVzcCksICVlYXggICAgICA4YiA0NCAyNCAwNCAqLwogICAgV09SRCBtb3YyOyAgICAgLyogbW92IDB4MTAoJWVheCksICVlYXggICAgIDhiIDQwICovCiAgICBCWVRFIHNpeHRlZW47ICAvKiAgICAgICAgICAgICAgICAgICAgICAgICAgMTAgICAqLwogICAgRFdPUkQgbW92MzsgICAgLyogbW92ICVlYXgsIDB4NCglZXNwKSAgICAgIDg5IDQ0IDI0IDA0ICovCiAgICBXT1JEIG1vdjQ7ICAgICAvKiBtb3YgKCVlYXgpLCAlZWF4ICAgICAgICAgOGIgMDAgKi8KICAgIFdPUkQgbW92NTsgICAgIC8qIG1vdiBvZmZzZXQoJWVheCksICVlYXggICA4YiA4MCAqLwogICAgRFdPUkQgb2Zmc2V0OyAgLyogICAgICAgICAgICAgICAgICAgICAgICAgIHh4IHh4IHh4IHh4ICovCiAgICBXT1JEIGptcDsgICAgICAvKiBqbXAgKiVlYXggICAgICAgICAgICAgICAgZmYgZTAgKi8KICAgIEJZVEUgcGFkWzNdOyAgIC8qIGxlYSAweDAoJWVzaSksICVlc2kgICAgICA4ZCA3NiAwMCAqLwp9IHZ0YmxfbWV0aG9kX3Q7CiNpbmNsdWRlICJwb3BwYWNrLmgiCgpzdGF0aWMgdm9pZCBmaWxsX3RhYmxlKElVbmtub3duVnRibCAqdnRibCwgdm9pZCAqKm1ldGhvZHMsIERXT1JEIG51bSkKewogICAgdnRibF9tZXRob2RfdCAqbWV0aG9kOwogICAgdm9pZCAqKmVudHJ5OwogICAgRFdPUkQgaTsKCiAgICB2dGJsLT5RdWVyeUludGVyZmFjZSA9IGRlbGVnYXRpbmdfUXVlcnlJbnRlcmZhY2U7CiAgICB2dGJsLT5BZGRSZWYgPSBkZWxlZ2F0aW5nX0FkZFJlZjsKICAgIHZ0YmwtPlJlbGVhc2UgPSBkZWxlZ2F0aW5nX1JlbGVhc2U7CgogICAgbWV0aG9kID0gKHZ0YmxfbWV0aG9kX3QqKW1ldGhvZHM7CiAgICBlbnRyeSA9ICh2b2lkKiopKHZ0YmwgKyAxKTsKCiAgICBmb3IoaSA9IDM7IGkgPCBudW07IGkrKykKICAgIHsKICAgICAgICAqZW50cnkgPSBtZXRob2Q7CiAgICAgICAgbWV0aG9kLT5tb3YxID0gMHgwNDI0NDQ4YjsKICAgICAgICBtZXRob2QtPm1vdjIgPSAweDQwOGI7CiAgICAgICAgbWV0aG9kLT5zaXh0ZWVuID0gMHgxMDsKICAgICAgICBtZXRob2QtPm1vdjMgPSAweDA0MjQ0NDg5OwogICAgICAgIG1ldGhvZC0+bW92NCA9IDB4MDA4YjsKICAgICAgICBtZXRob2QtPm1vdjUgPSAweDgwOGI7CiAgICAgICAgbWV0aG9kLT5vZmZzZXQgPSBpIDw8IDI7CiAgICAgICAgbWV0aG9kLT5qbXAgPSAweGUwZmY7CiAgICAgICAgbWV0aG9kLT5wYWRbMF0gPSAweDhkOwogICAgICAgIG1ldGhvZC0+cGFkWzFdID0gMHg3NjsKICAgICAgICBtZXRob2QtPnBhZFsyXSA9IDB4MDA7CgogICAgICAgIG1ldGhvZCsrOwogICAgICAgIGVudHJ5Kys7CiAgICB9Cn0KCiNlbHNlICAvKiBfX2kzODZfXyAqLwoKdHlwZWRlZiBzdHJ1Y3Qge2ludCBkdW1teTt9IHZ0YmxfbWV0aG9kX3Q7CnN0YXRpYyB2b2lkIGZpbGxfdGFibGUoSVVua25vd25WdGJsICp2dGJsLCBEV09SRCBudW0pCnsKICAgIEVSUigiZGVsZWdhdGVkIHN0dWJzIGFyZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgYXJjaGl0ZWN0dXJlXG4iKTsKfQoKI2VuZGlmICAvKiBfX2kzODZfXyAqLwoKdm9pZCBjcmVhdGVfZGVsZWdhdGluZ192dGJsKERXT1JEIG51bV9tZXRob2RzKQp7CiAgICBUUkFDRSgiJWRcbiIsIG51bV9tZXRob2RzKTsKICAgIGlmKG51bV9tZXRob2RzIDw9IDMpCiAgICB7CiAgICAgICAgRVJSKCJzaG91bGQgaGF2ZSBtb3JlIHRoYW4gJWQgbWV0aG9kc1xuIiwgbnVtX21ldGhvZHMpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGVsZWdhdGluZ192dGJsX3NlY3Rpb24pOwogICAgaWYoIWN1cnJlbnRfdnRibC50YWJsZSB8fCBudW1fbWV0aG9kcyA+IGN1cnJlbnRfdnRibC50YWJsZS0+c2l6ZSkKICAgIHsKICAgICAgICBEV09SRCBzaXplOwogICAgICAgIERXT1JEIG9sZF9wcm90ZWN0OwogICAgICAgIGlmKGN1cnJlbnRfdnRibC50YWJsZSAmJiBjdXJyZW50X3Z0YmwudGFibGUtPnJlZiA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoImZyZWVpbmcgb2xkIHRhYmxlXG4iKTsKICAgICAgICAgICAgVmlydHVhbEZyZWUoY3VycmVudF92dGJsLnRhYmxlLT5tZXRob2RzLAogICAgICAgICAgICAgICAgICAgICAgICAoY3VycmVudF92dGJsLnRhYmxlLT5zaXplIC0gMykgKiBzaXplb2YodnRibF9tZXRob2RfdCksCiAgICAgICAgICAgICAgICAgICAgICAgIE1FTV9SRUxFQVNFKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY3VycmVudF92dGJsLnRhYmxlKTsKICAgICAgICB9CiAgICAgICAgc2l6ZSA9IChudW1fbWV0aG9kcyAtIDMpICogc2l6ZW9mKHZ0YmxfbWV0aG9kX3QpOwogICAgICAgIGN1cnJlbnRfdnRibC50YWJsZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBGSUVMRF9PRkZTRVQocmVmX2NvdW50ZWRfdnRibCwgdnRibCkgKyBudW1fbWV0aG9kcyAqIHNpemVvZih2b2lkKikpOwogICAgICAgIGN1cnJlbnRfdnRibC50YWJsZS0+cmVmID0gMDsKICAgICAgICBjdXJyZW50X3Z0YmwudGFibGUtPnNpemUgPSBudW1fbWV0aG9kczsKICAgICAgICBjdXJyZW50X3Z0YmwudGFibGUtPm1ldGhvZHMgPSBWaXJ0dWFsQWxsb2MoTlVMTCwgc2l6ZSwgTUVNX0NPTU1JVCB8IE1FTV9SRVNFUlZFLCBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFKTsKICAgICAgICBmaWxsX3RhYmxlKCZjdXJyZW50X3Z0YmwudGFibGUtPnZ0YmwsIGN1cnJlbnRfdnRibC50YWJsZS0+bWV0aG9kcywgbnVtX21ldGhvZHMpOwogICAgICAgIFZpcnR1YWxQcm90ZWN0KGN1cnJlbnRfdnRibC50YWJsZS0+bWV0aG9kcywgc2l6ZSwgUEFHRV9FWEVDVVRFX1JFQUQsICZvbGRfcHJvdGVjdCk7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGVsZWdhdGluZ192dGJsX3NlY3Rpb24pOwp9CgpzdGF0aWMgSVVua25vd25WdGJsICpnZXRfZGVsZWdhdGluZ192dGJsKHZvaWQpCnsKICAgIElVbmtub3duVnRibCAqcmV0OwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZWxlZ2F0aW5nX3Z0Ymxfc2VjdGlvbik7CiAgICBjdXJyZW50X3Z0YmwudGFibGUtPnJlZisrOwogICAgcmV0ID0gJmN1cnJlbnRfdnRibC50YWJsZS0+dnRibDsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZWxlZ2F0aW5nX3Z0Ymxfc2VjdGlvbik7CiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCByZWxlYXNlX2RlbGVnYXRpbmdfdnRibChJVW5rbm93blZ0YmwgKnZ0YmwpCnsKICAgIHJlZl9jb3VudGVkX3Z0YmwgKnRhYmxlID0gKHJlZl9jb3VudGVkX3Z0YmwqKSgoRFdPUkQgKil2dGJsIC0gMSk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRlbGVnYXRpbmdfdnRibF9zZWN0aW9uKTsKICAgIHRhYmxlLT5yZWYtLTsKICAgIFRSQUNFKCJyZWYgbm93ICVkXG4iLCB0YWJsZS0+cmVmKTsKICAgIGlmKHRhYmxlLT5yZWYgPT0gMCAmJiB0YWJsZSAhPSBjdXJyZW50X3Z0YmwudGFibGUpCiAgICB7CiAgICAgICAgVFJBQ0UoIi4uLiBhbmQgd2UncmUgbm90IGN1cnJlbnQgc28gZnJlZSdpbmdcbiIpOwogICAgICAgIFZpcnR1YWxGcmVlKGN1cnJlbnRfdnRibC50YWJsZS0+bWV0aG9kcywKICAgICAgICAgICAgICAgICAgICAoY3VycmVudF92dGJsLnRhYmxlLT5zaXplIC0gMykgKiBzaXplb2YodnRibF9tZXRob2RfdCksCiAgICAgICAgICAgICAgICAgICAgTUVNX1JFTEVBU0UpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHRhYmxlKTsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZWxlZ2F0aW5nX3Z0Ymxfc2VjdGlvbik7Cn0KCkhSRVNVTFQgV0lOQVBJIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfQ29uc3RydWN0KFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFVOS05PV04gcFVua1NlcnZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUENJbnRlcmZhY2VOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENJbnRlcmZhY2VTdHViVnRibCAqdnRibCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIGRlbGVnYXRpbmdfaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFBTRkFDVE9SWUJVRkZFUiBwUFNGYWN0b3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ1NUVUJCVUZGRVIgKnBwU3R1YikKewogICAgY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190ICpUaGlzOwogICAgSVVua25vd24gKnB2U2VydmVyOwogICAgSFJFU1VMVCByOwoKICAgIFRSQUNFKCIoJXAsJXAsJXAsJXApICVzXG4iLCBwVW5rU2VydmVyLCB2dGJsLCBwUFNGYWN0b3J5LCBwcFN0dWIsIG5hbWUpOwogICAgVFJBQ0UoImlpZD0lcyBkZWxlZ2F0aW5nIHRvICVzXG4iLCBkZWJ1Z3N0cl9ndWlkKHZ0YmwtPmhlYWRlci5waWlkKSwgZGVidWdzdHJfZ3VpZChkZWxlZ2F0aW5nX2lpZCkpOwogICAgVFJBQ0UoInZ0Ymw9JXBcbiIsICZ2dGJsLT5WdGJsKTsKCiAgICBpZiAoIUlzRXF1YWxHVUlEKHZ0YmwtPmhlYWRlci5waWlkLCByaWlkKSkKICAgIHsKICAgICAgICBFUlIoIklJRCBtaXNtYXRjaCBkdXJpbmcgc3R1YiBjcmVhdGlvblxuIik7CiAgICAgICAgcmV0dXJuIFJQQ19FX1VORVhQRUNURUQ7CiAgICB9CgogICAgciA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKHBVbmtTZXJ2ZXIsIHJpaWQsICh2b2lkKiopJnB2U2VydmVyKTsKICAgIGlmKEZBSUxFRChyKSkgcmV0dXJuIHI7CgogICAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykKICAgIHsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKHB2U2VydmVyKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBUaGlzLT5iYXNlX29iaiA9IGdldF9kZWxlZ2F0aW5nX3Z0YmwoKTsKICAgIHIgPSBjcmVhdGVfc3R1YihkZWxlZ2F0aW5nX2lpZCwgKElVbmtub3duKikmVGhpcy0+YmFzZV9vYmosICZUaGlzLT5iYXNlX3N0dWIpOwogICAgaWYoRkFJTEVEKHIpKQogICAgewogICAgICAgIHJlbGVhc2VfZGVsZWdhdGluZ192dGJsKFRoaXMtPmJhc2Vfb2JqKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKHB2U2VydmVyKTsKICAgICAgICByZXR1cm4gcjsKICAgIH0KCiAgICBUaGlzLT5zdHViX2J1ZmZlci5scFZ0YmwgPSAmdnRibC0+VnRibDsKICAgIFRoaXMtPnN0dWJfYnVmZmVyLlJlZkNvdW50ID0gMTsKICAgIFRoaXMtPnN0dWJfYnVmZmVyLnB2U2VydmVyT2JqZWN0ID0gcHZTZXJ2ZXI7CiAgICBUaGlzLT5zdHViX2J1ZmZlci5wUFNGYWN0b3J5ID0gcFBTRmFjdG9yeTsKICAgICpwcFN0dWIgPSAoTFBSUENTVFVCQlVGRkVSKSZUaGlzLT5zdHViX2J1ZmZlcjsKCiAgICBJUFNGYWN0b3J5QnVmZmVyX0FkZFJlZihwUFNGYWN0b3J5KTsKICAgIHJldHVybiBTX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9RdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpvYmopCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5RdWVyeUludGVyZmFjZSglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CgogIGlmIChJc0VxdWFsSUlEKCZJSURfSVVua25vd24sIHJpaWQpIHx8CiAgICAgIElzRXF1YWxJSUQoJklJRF9JUnBjU3R1YkJ1ZmZlciwgcmlpZCkpCiAgewogICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICpvYmogPSBpZmFjZTsKICAgIHJldHVybiBTX09LOwogIH0KICAqb2JqID0gTlVMTDsKICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKVUxPTkcgV0lOQVBJIENTdGRTdHViQnVmZmVyX0FkZFJlZihMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5BZGRSZWYoKVxuIixUaGlzKTsKICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPlJlZkNvdW50KTsKfQoKVUxPTkcgV0lOQVBJIE5kckNTdGRTdHViQnVmZmVyX1JlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUFNGQUNUT1JZQlVGRkVSIHBQU0YpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIFVMT05HIHJlZnM7CgogIFRSQUNFKCIoJXApLT5SZWxlYXNlKClcbiIsVGhpcyk7CgogIHJlZnMgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+UmVmQ291bnQpOwogIGlmICghcmVmcykKICB7CiAgICAvKiB0ZXN0X1JlbGVhc2Ugc2hvd3MgdGhhdCBuYXRpdmUgZG9lc24ndCBjYWxsIERpc2Nvbm5lY3QgaGVyZS4KICAgICAgIFdlJ2xsIGxlYXZlIGl0IGluIGZvciB0aGUgdGltZSBiZWluZy4gKi8KICAgIElScGNTdHViQnVmZmVyX0Rpc2Nvbm5lY3QoaWZhY2UpOwoKICAgIElQU0ZhY3RvcnlCdWZmZXJfUmVsZWFzZShwUFNGKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxUaGlzKTsKICB9CiAgcmV0dXJuIHJlZnM7Cn0KClVMT05HIFdJTkFQSSBOZHJDU3RkU3R1YkJ1ZmZlcjJfUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFBTRkFDVE9SWUJVRkZFUiBwUFNGKQp7CiAgICBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QgKlRoaXMgPSBpbXBsX2Zyb21fZGVsZWdhdGluZyggaWZhY2UgKTsKICAgIFVMT05HIHJlZnM7CgogICAgVFJBQ0UoIiglcCktPlJlbGVhc2UoKVxuIiwgVGhpcyk7CgogICAgcmVmcyA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5zdHViX2J1ZmZlci5SZWZDb3VudCk7CiAgICBpZiAoIXJlZnMpCiAgICB7CiAgICAgICAgLyogSnVzdCBsaWtlIE5kckNTdGRTdHViQnVmZmVyX1JlbGVhc2UsIHdlIHNob3VsZG4ndCBjYWxsCiAgICAgICAgICAgRGlzY29ubmVjdCBoZXJlICovCiAgICAgICAgSVJwY1N0dWJCdWZmZXJfRGlzY29ubmVjdCgoSVJwY1N0dWJCdWZmZXIgKikmVGhpcy0+c3R1Yl9idWZmZXIpOwoKICAgICAgICBJUnBjU3R1YkJ1ZmZlcl9SZWxlYXNlKFRoaXMtPmJhc2Vfc3R1Yik7CiAgICAgICAgcmVsZWFzZV9kZWxlZ2F0aW5nX3Z0YmwoVGhpcy0+YmFzZV9vYmopOwoKICAgICAgICBJUFNGYWN0b3J5QnVmZmVyX1JlbGVhc2UocFBTRik7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICB9CgogICAgcmV0dXJuIHJlZnM7Cn0KCkhSRVNVTFQgV0lOQVBJIENTdGRTdHViQnVmZmVyX0Nvbm5lY3QoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBVTktOT1dOIGxwVW5rU2VydmVyKQp7CiAgICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogICAgSFJFU1VMVCByOwogICAgSVVua25vd24gKm5ldyA9IE5VTEw7CgogICAgVFJBQ0UoIiglcCktPkNvbm5lY3QoJXApXG4iLFRoaXMsbHBVbmtTZXJ2ZXIpOwoKICAgIHIgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua1NlcnZlciwgU1RVQl9IRUFERVIoVGhpcykucGlpZCwgKHZvaWQqKikmbmV3KTsKICAgIG5ldyA9IEludGVybG9ja2VkRXhjaGFuZ2VQb2ludGVyKCh2b2lkKiopJlRoaXMtPnB2U2VydmVyT2JqZWN0LCBuZXcpOwogICAgaWYobmV3KQogICAgICAgIElVbmtub3duX1JlbGVhc2UobmV3KTsKICAgIHJldHVybiByOwp9Cgp2b2lkIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9EaXNjb25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogICAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICAgIElVbmtub3duICpvbGQ7CiAgICBUUkFDRSgiKCVwKS0+RGlzY29ubmVjdCgpXG4iLFRoaXMpOwoKICAgIG9sZCA9IEludGVybG9ja2VkRXhjaGFuZ2VQb2ludGVyKCh2b2lkKiopJlRoaXMtPnB2U2VydmVyT2JqZWN0LCBOVUxMKTsKCiAgICBpZihvbGQpCiAgICAgICAgSVVua25vd25fUmVsZWFzZShvbGQpOwp9CgpIUkVTVUxUIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9JbnZva2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDT0xFTUVTU0FHRSBwTXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ0NIQU5ORUxCVUZGRVIgcENoYW5uZWwpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIERXT1JEIGR3UGhhc2UgPSBTVFVCX1VOTUFSU0hBTDsKICBIUkVTVUxUIGhyID0gU19PSzsKCiAgVFJBQ0UoIiglcCktPkludm9rZSglcCwlcClcbiIsVGhpcyxwTXNnLHBDaGFubmVsKTsKCiAgX19UUlkKICB7CiAgICBpZiAoU1RVQl9IRUFERVIoVGhpcykucERpc3BhdGNoVGFibGUpCiAgICAgIFNUVUJfSEVBREVSKFRoaXMpLnBEaXNwYXRjaFRhYmxlW3BNc2ctPmlNZXRob2RdKGlmYWNlLCBwQ2hhbm5lbCwgKFBSUENfTUVTU0FHRSlwTXNnLCAmZHdQaGFzZSk7CiAgICBlbHNlIC8qIHB1cmUgaW50ZXJwcmV0ZWQgKi8KICAgICAgTmRyU3R1YkNhbGwyKGlmYWNlLCBwQ2hhbm5lbCwgKFBSUENfTUVTU0FHRSlwTXNnLCAmZHdQaGFzZSk7CiAgfQogIF9fRVhDRVBUKHN0dWJfZmlsdGVyKQogIHsKICAgIERXT1JEIGR3RXhjZXB0aW9uQ29kZSA9IEdldEV4Y2VwdGlvbkNvZGUoKTsKICAgIFdBUk4oImEgc3R1YiBjYWxsIGZhaWxlZCB3aXRoIGV4Y2VwdGlvbiAweCUwOHggKCVkKVxuIiwgZHdFeGNlcHRpb25Db2RlLCBkd0V4Y2VwdGlvbkNvZGUpOwogICAgaWYgKEZBSUxFRChkd0V4Y2VwdGlvbkNvZGUpKQogICAgICBociA9IGR3RXhjZXB0aW9uQ29kZTsKICAgIGVsc2UKICAgICAgaHIgPSBIUkVTVUxUX0ZST01fV0lOMzIoZHdFeGNlcHRpb25Db2RlKTsKICB9CiAgX19FTkRUUlkKCiAgcmV0dXJuIGhyOwp9CgpMUFJQQ1NUVUJCVUZGRVIgV0lOQVBJIENTdGRTdHViQnVmZmVyX0lzSUlEU3VwcG9ydGVkKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkKQp7CiAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+SXNJSURTdXBwb3J0ZWQoJXMpXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgcmV0dXJuIElzRXF1YWxHVUlEKFNUVUJfSEVBREVSKFRoaXMpLnBpaWQsIHJpaWQpID8gaWZhY2UgOiBOVUxMOwp9CgpVTE9ORyBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfQ291bnRSZWZzKExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogIENTdGRTdHViQnVmZmVyICpUaGlzID0gKENTdGRTdHViQnVmZmVyICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkNvdW50UmVmcygpXG4iLFRoaXMpOwogIHJldHVybiBUaGlzLT5SZWZDb3VudDsKfQoKSFJFU1VMVCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKnBwdikKewogIENTdGRTdHViQnVmZmVyICpUaGlzID0gKENTdGRTdHViQnVmZmVyICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkRlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UoJXApXG4iLFRoaXMscHB2KTsKICByZXR1cm4gU19PSzsKfQoKdm9pZCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfRGVidWdTZXJ2ZXJSZWxlYXNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIHB2KQp7CiAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+RGVidWdTZXJ2ZXJSZWxlYXNlKCVwKVxuIixUaGlzLHB2KTsKfQoKY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsIENTdGRTdHViQnVmZmVyX1Z0YmwgPQp7CiAgICBDU3RkU3R1YkJ1ZmZlcl9RdWVyeUludGVyZmFjZSwKICAgIENTdGRTdHViQnVmZmVyX0FkZFJlZiwKICAgIE5VTEwsCiAgICBDU3RkU3R1YkJ1ZmZlcl9Db25uZWN0LAogICAgQ1N0ZFN0dWJCdWZmZXJfRGlzY29ubmVjdCwKICAgIENTdGRTdHViQnVmZmVyX0ludm9rZSwKICAgIENTdGRTdHViQnVmZmVyX0lzSUlEU3VwcG9ydGVkLAogICAgQ1N0ZFN0dWJCdWZmZXJfQ291bnRSZWZzLAogICAgQ1N0ZFN0dWJCdWZmZXJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZSwKICAgIENTdGRTdHViQnVmZmVyX0RlYnVnU2VydmVyUmVsZWFzZQp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfQ29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBVTktOT1dOIGxwVW5rU2VydmVyKQp7CiAgICBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QgKlRoaXMgPSBpbXBsX2Zyb21fZGVsZWdhdGluZyhpZmFjZSk7CiAgICBIUkVTVUxUIHI7CiAgICBUUkFDRSgiKCVwKS0+Q29ubmVjdCglcClcbiIsIFRoaXMsIGxwVW5rU2VydmVyKTsKCiAgICByID0gQ1N0ZFN0dWJCdWZmZXJfQ29ubmVjdChpZmFjZSwgbHBVbmtTZXJ2ZXIpOwogICAgaWYoU1VDQ0VFREVEKHIpKQogICAgICAgIHIgPSBJUnBjU3R1YkJ1ZmZlcl9Db25uZWN0KFRoaXMtPmJhc2Vfc3R1YiwgKElVbmtub3duKikmVGhpcy0+YmFzZV9vYmopOwoKICAgIHJldHVybiByOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfRGVsZWdhdGluZ19EaXNjb25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogICAgY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190ICpUaGlzID0gaW1wbF9mcm9tX2RlbGVnYXRpbmcoaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPkRpc2Nvbm5lY3QoKVxuIiwgVGhpcyk7CgogICAgSVJwY1N0dWJCdWZmZXJfRGlzY29ubmVjdChUaGlzLT5iYXNlX3N0dWIpOwogICAgQ1N0ZFN0dWJCdWZmZXJfRGlzY29ubmVjdChpZmFjZSk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfRGVsZWdhdGluZ19Db3VudFJlZnMoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgICBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QgKlRoaXMgPSBpbXBsX2Zyb21fZGVsZWdhdGluZyhpZmFjZSk7CiAgICBVTE9ORyByZXQ7CiAgICBUUkFDRSgiKCVwKS0+Q291bnRSZWZzKClcbiIsIFRoaXMpOwoKICAgIHJldCA9IENTdGRTdHViQnVmZmVyX0NvdW50UmVmcyhpZmFjZSk7CiAgICByZXQgKz0gSVJwY1N0dWJCdWZmZXJfQ291bnRSZWZzKFRoaXMtPmJhc2Vfc3R1Yik7CgogICAgcmV0dXJuIHJldDsKfQoKY29uc3QgSVJwY1N0dWJCdWZmZXJWdGJsIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfVnRibCA9CnsKICAgIENTdGRTdHViQnVmZmVyX1F1ZXJ5SW50ZXJmYWNlLAogICAgQ1N0ZFN0dWJCdWZmZXJfQWRkUmVmLAogICAgTlVMTCwKICAgIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfQ29ubmVjdCwKICAgIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfRGlzY29ubmVjdCwKICAgIENTdGRTdHViQnVmZmVyX0ludm9rZSwKICAgIENTdGRTdHViQnVmZmVyX0lzSUlEU3VwcG9ydGVkLAogICAgQ1N0ZFN0dWJCdWZmZXJfRGVsZWdhdGluZ19Db3VudFJlZnMsCiAgICBDU3RkU3R1YkJ1ZmZlcl9EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlLAogICAgQ1N0ZFN0dWJCdWZmZXJfRGVidWdTZXJ2ZXJSZWxlYXNlCn07Cgpjb25zdCBNSURMX1NFUlZFUl9JTkZPICpDU3RkU3R1YkJ1ZmZlcl9HZXRTZXJ2ZXJJbmZvKElScGNTdHViQnVmZmVyICppZmFjZSkKewogIENTdGRTdHViQnVmZmVyICpUaGlzID0gKENTdGRTdHViQnVmZmVyICopaWZhY2U7CiAgcmV0dXJuIFNUVUJfSEVBREVSKFRoaXMpLnBTZXJ2ZXJJbmZvOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJTdHViRm9yd2FyZGluZ0Z1bmN0aW9uIFtSUENSVDQuQF0KICovCnZvaWQgX19SUENfU1RVQiBOZHJTdHViRm9yd2FyZGluZ0Z1bmN0aW9uKCBJUnBjU3R1YkJ1ZmZlciAqaWZhY2UsIElScGNDaGFubmVsQnVmZmVyICpwQ2hhbm5lbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBSUENfTUVTU0FHRSBwTXNnLCBEV09SRCAqcGR3U3R1YlBoYXNlICkKewogICAgLyogTm90ZSBwTXNnIGlzIHBhc3NlZCBpbnRhY3Qgc2luY2UgUlBDT0xFTUVTU0FHRSBpcyBiYXNpY2FsbHkgYSBSUENfTUVTU0FHRS4gKi8KCiAgICBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QgKlRoaXMgPSBpbXBsX2Zyb21fZGVsZWdhdGluZyhpZmFjZSk7CiAgICBIUkVTVUxUIHIgPSBJUnBjU3R1YkJ1ZmZlcl9JbnZva2UoVGhpcy0+YmFzZV9zdHViLCAoUlBDT0xFTUVTU0FHRSopcE1zZywgcENoYW5uZWwpOwogICAgaWYoRkFJTEVEKHIpKSBScGNSYWlzZUV4Y2VwdGlvbihyKTsKICAgIHJldHVybjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJTdHViSW5pdGlhbGl6ZSBbUlBDUlQ0LkBdCiAqLwp2b2lkIFdJTkFQSSBOZHJTdHViSW5pdGlhbGl6ZShQUlBDX01FU1NBR0UgcFJwY01zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE1JRExfU1RVQl9ERVNDIHBTdHViRGVzY3JpcHRvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ0NIQU5ORUxCVUZGRVIgcFJwY0NoYW5uZWxCdWZmZXIpCnsKICBUUkFDRSgiKCVwLCVwLCVwLCVwKVxuIiwgcFJwY01zZywgcFN0dWJNc2csIHBTdHViRGVzY3JpcHRvciwgcFJwY0NoYW5uZWxCdWZmZXIpOwogIE5kclNlcnZlckluaXRpYWxpemVOZXcocFJwY01zZywgcFN0dWJNc2csIHBTdHViRGVzY3JpcHRvcik7CiAgcFN0dWJNc2ctPnBScGNDaGFubmVsQnVmZmVyID0gcFJwY0NoYW5uZWxCdWZmZXI7CiAgSVJwY0NoYW5uZWxCdWZmZXJfR2V0RGVzdEN0eChwU3R1Yk1zZy0+cFJwY0NoYW5uZWxCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFN0dWJNc2ctPmR3RGVzdENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFN0dWJNc2ctPnB2RGVzdENvbnRleHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kclN0dWJHZXRCdWZmZXIgW1JQQ1JUNC5AXQogKi8Kdm9pZCBXSU5BUEkgTmRyU3R1YkdldEJ1ZmZlcihMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ0NIQU5ORUxCVUZGRVIgcFJwY0NoYW5uZWxCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2cpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsICVwLCAlcClcbiIsIFRoaXMsIHBScGNDaGFubmVsQnVmZmVyLCBwU3R1Yk1zZyk7CgogIHBTdHViTXNnLT5ScGNNc2ctPkJ1ZmZlckxlbmd0aCA9IHBTdHViTXNnLT5CdWZmZXJMZW5ndGg7CiAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIocFJwY0NoYW5uZWxCdWZmZXIsCiAgICAoUlBDT0xFTUVTU0FHRSAqKXBTdHViTXNnLT5ScGNNc2csIFNUVUJfSEVBREVSKFRoaXMpLnBpaWQpOwogIGlmIChGQUlMRUQoaHIpKQogIHsKICAgIFJwY1JhaXNlRXhjZXB0aW9uKGhyKTsKICAgIHJldHVybjsKICB9CgogIHBTdHViTXNnLT5CdWZmZXIgPSBwU3R1Yk1zZy0+UnBjTXNnLT5CdWZmZXI7Cn0K