LyoKICogQ09NIHN0dWIgKENTdGRTdHViQnVmZmVyKSBpbXBsZW1lbnRhdGlvbgogKgogKiBDb3B5cmlnaHQgMjAwMSBPdmUgS+V2ZW4sIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJleGNwdC5oIgoKI2luY2x1ZGUgIm9iamJhc2UuaCIKI2luY2x1ZGUgInJwY3Byb3h5LmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKCiNpbmNsdWRlICJjcHNmLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKI2RlZmluZSBTVFVCX0hFQURFUihUaGlzKSAoKChjb25zdCBDSW50ZXJmYWNlU3R1YkhlYWRlciopKChUaGlzKS0+bHBWdGJsKSlbLTFdKQoKc3RhdGljIFdJTkVfRVhDRVBUSU9OX0ZJTFRFUihzdHViX2ZpbHRlcikKewogICAgaWYgKEdldEV4Y2VwdGlvbkNvZGUoKSA9PSBFWENFUFRJT05fQUNDRVNTX1ZJT0xBVElPTikKICAgICAgICByZXR1cm4gRVhDRVBUSU9OX0NPTlRJTlVFX1NFQVJDSDsKICAgIHJldHVybiBFWENFUFRJT05fRVhFQ1VURV9IQU5ETEVSOwp9Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBJVW5rbm93blZ0YmwgKmJhc2Vfb2JqOwogICAgSVJwY1N0dWJCdWZmZXIgKmJhc2Vfc3R1YjsKICAgIENTdGRTdHViQnVmZmVyIHN0dWJfYnVmZmVyOwp9IGNzdGRzdHViYnVmZmVyX2RlbGVnYXRpbmdfdDsKCnN0YXRpYyBpbmxpbmUgY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190ICppbXBsX2Zyb21fZGVsZWdhdGluZyggSVJwY1N0dWJCdWZmZXIgKmlmYWNlICkKewogICAgcmV0dXJuIChjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QqKSgoY2hhciAqKWlmYWNlIC0gRklFTERfT0ZGU0VUKGNzdGRzdHViYnVmZmVyX2RlbGVnYXRpbmdfdCwgc3R1Yl9idWZmZXIpKTsKfQoKSFJFU1VMVCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfQ29uc3RydWN0KFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFVOS05PV04gcFVua1NlcnZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUENJbnRlcmZhY2VOYW1lIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENJbnRlcmZhY2VTdHViVnRibCAqdnRibCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBQU0ZBQ1RPUllCVUZGRVIgcFBTRmFjdG9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENTVFVCQlVGRkVSICpwcFN0dWIpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpczsKICBJVW5rbm93biAqcHZTZXJ2ZXI7CiAgSFJFU1VMVCByOwogIFRSQUNFKCIoJXAsJXAsJXAsJXApICVzXG4iLCBwVW5rU2VydmVyLCB2dGJsLCBwUFNGYWN0b3J5LCBwcFN0dWIsIG5hbWUpOwogIFRSQUNFKCJpaWQ9JXNcbiIsIGRlYnVnc3RyX2d1aWQodnRibC0+aGVhZGVyLnBpaWQpKTsKICBUUkFDRSgidnRibD0lcFxuIiwgJnZ0YmwtPlZ0YmwpOwoKICBpZiAoIUlzRXF1YWxHVUlEKHZ0YmwtPmhlYWRlci5waWlkLCByaWlkKSkgewogICAgRVJSKCJJSUQgbWlzbWF0Y2ggZHVyaW5nIHN0dWIgY3JlYXRpb25cbiIpOwogICAgcmV0dXJuIFJQQ19FX1VORVhQRUNURUQ7CiAgfQoKICByID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UocFVua1NlcnZlciwgcmlpZCwgKHZvaWQqKikmcHZTZXJ2ZXIpOwogIGlmKEZBSUxFRChyKSkKICAgIHJldHVybiByOwoKICBUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksSEVBUF9aRVJPX01FTU9SWSxzaXplb2YoQ1N0ZFN0dWJCdWZmZXIpKTsKICBpZiAoIVRoaXMpIHsKICAgIElVbmtub3duX1JlbGVhc2UocHZTZXJ2ZXIpOwogICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgfQoKICBUaGlzLT5scFZ0YmwgPSAmdnRibC0+VnRibDsKICBUaGlzLT5SZWZDb3VudCA9IDE7CiAgVGhpcy0+cHZTZXJ2ZXJPYmplY3QgPSBwdlNlcnZlcjsKICBUaGlzLT5wUFNGYWN0b3J5ID0gcFBTRmFjdG9yeTsKICAqcHBTdHViID0gKExQUlBDU1RVQkJVRkZFUilUaGlzOwoKICBJUFNGYWN0b3J5QnVmZmVyX0FkZFJlZihwUFNGYWN0b3J5KTsKICByZXR1cm4gU19PSzsKfQoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gZGVsZWdhdGluZ192dGJsX3NlY3Rpb247CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNyaXRzZWN0X2RlYnVnID0KewogICAgMCwgMCwgJmRlbGVnYXRpbmdfdnRibF9zZWN0aW9uLAogICAgeyAmY3JpdHNlY3RfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmNyaXRzZWN0X2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgICAgMCwgMCwgeyAoRFdPUkRfUFRSKShfX0ZJTEVfXyAiOiBkZWxlZ2F0aW5nX3Z0Ymxfc2VjdGlvbiIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gZGVsZWdhdGluZ192dGJsX3NlY3Rpb24gPSB7ICZjcml0c2VjdF9kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCnR5cGVkZWYgc3RydWN0CnsKICAgIERXT1JEIHJlZjsKICAgIElVbmtub3duVnRibCB2dGJsOwp9IHJlZl9jb3VudGVkX3Z0Ymw7CgpzdGF0aWMgc3RydWN0CnsKICAgIHJlZl9jb3VudGVkX3Z0YmwgKnRhYmxlOwogICAgRFdPUkQgc2l6ZTsKfSBjdXJyZW50X3Z0Ymw7CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIGRlbGVnYXRpbmdfUXVlcnlJbnRlcmZhY2UoSVVua25vd24gKnBVbmssIFJFRklJRCBpaWQsIHZvaWQgKipwcHYpCnsKICAgICpwcHYgPSAodm9pZCAqKXBVbms7CiAgICByZXR1cm4gU19PSzsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBkZWxlZ2F0aW5nX0FkZFJlZihJVW5rbm93biAqcFVuaykKewogICAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgZGVsZWdhdGluZ19SZWxlYXNlKElVbmtub3duICpwVW5rKQp7CiAgICByZXR1cm4gMTsKfQoKI2lmIGRlZmluZWQoX19pMzg2X18pCgovKiBUaGUgaWRlYSBoZXJlIGlzIHRvIHJlcGxhY2UgdGhlIGZpcnN0IHBhcmFtIG9uIHRoZSBzdGFjawogICBpZS4gVGhpcyAod2hpY2ggd2lsbCBwb2ludCB0byBjc3Rkc3R1YmJ1ZmZlcl9kZWxlZ2F0aW5nX3QpCiAgIHdpdGggVGhpcy0+c3R1Yl9idWZmZXIucHZTZXJ2ZXJPYmplY3QgYW5kIHRoZW4ganVtcCB0byB0aGUKICAgcmVsZXZhbnQgb2Zmc2V0IGluIFRoaXMtPnN0dWJfYnVmZmVyLnB2U2VydmVyT2JqZWN0J3MgdnRibC4KKi8KI2luY2x1ZGUgInBzaHBhY2sxLmgiCnR5cGVkZWYgc3RydWN0IHsKICAgIERXT1JEIG1vdjE7ICAgIC8qIG1vdiAweDQoJWVzcCksICVlYXggICAgICA4YiA0NCAyNCAwNCAqLwogICAgV09SRCBtb3YyOyAgICAgLyogbW92IDB4MTAoJWVheCksICVlYXggICAgIDhiIDQwICovCiAgICBCWVRFIHNpeHRlZW47ICAvKiAgICAgICAgICAgICAgICAgICAgICAgICAgMTAgICAqLwogICAgRFdPUkQgbW92MzsgICAgLyogbW92ICVlYXgsIDB4NCglZXNwKSAgICAgIDg5IDQ0IDI0IDA0ICovCiAgICBXT1JEIG1vdjQ7ICAgICAvKiBtb3YgKCVlYXgpLCAlZWF4ICAgICAgICAgOGIgMDAgKi8KICAgIFdPUkQgbW92NTsgICAgIC8qIG1vdiBvZmZzZXQoJWVheCksICVlYXggICA4YiA4MCAqLwogICAgRFdPUkQgb2Zmc2V0OyAgLyogICAgICAgICAgICAgICAgICAgICAgICAgIHh4IHh4IHh4IHh4ICovCiAgICBXT1JEIGptcDsgICAgICAvKiBqbXAgKiVlYXggICAgICAgICAgICAgICAgZmYgZTAgKi8KICAgIEJZVEUgcGFkWzNdOyAgIC8qIGxlYSAweDAoJWVzaSksICVlc2kgICAgICA4ZCA3NiAwMCAqLwp9IHZ0YmxfbWV0aG9kX3Q7CiNpbmNsdWRlICJwb3BwYWNrLmgiCgpzdGF0aWMgdm9pZCBmaWxsX3RhYmxlKElVbmtub3duVnRibCAqdnRibCwgRFdPUkQgbnVtKQp7CiAgICB2dGJsX21ldGhvZF90ICptZXRob2Q7CiAgICB2b2lkICoqZW50cnk7CiAgICBEV09SRCBpOwoKICAgIHZ0YmwtPlF1ZXJ5SW50ZXJmYWNlID0gZGVsZWdhdGluZ19RdWVyeUludGVyZmFjZTsKICAgIHZ0YmwtPkFkZFJlZiA9IGRlbGVnYXRpbmdfQWRkUmVmOwogICAgdnRibC0+UmVsZWFzZSA9IGRlbGVnYXRpbmdfUmVsZWFzZTsKCiAgICBtZXRob2QgPSAodnRibF9tZXRob2RfdCopKCh2b2lkICoqKXZ0YmwgKyBudW0pOwogICAgZW50cnkgPSAodm9pZCoqKSh2dGJsICsgMSk7CgogICAgZm9yKGkgPSAzOyBpIDwgbnVtOyBpKyspCiAgICB7CiAgICAgICAgKmVudHJ5ID0gbWV0aG9kOwogICAgICAgIG1ldGhvZC0+bW92MSA9IDB4MDQyNDQ0OGI7CiAgICAgICAgbWV0aG9kLT5tb3YyID0gMHg0MDhiOwogICAgICAgIG1ldGhvZC0+c2l4dGVlbiA9IDB4MTA7CiAgICAgICAgbWV0aG9kLT5tb3YzID0gMHgwNDI0NDQ4OTsKICAgICAgICBtZXRob2QtPm1vdjQgPSAweDAwOGI7CiAgICAgICAgbWV0aG9kLT5tb3Y1ID0gMHg4MDhiOwogICAgICAgIG1ldGhvZC0+b2Zmc2V0ID0gaSA8PCAyOwogICAgICAgIG1ldGhvZC0+am1wID0gMHhlMGZmOwogICAgICAgIG1ldGhvZC0+cGFkWzBdID0gMHg4ZDsKICAgICAgICBtZXRob2QtPnBhZFsxXSA9IDB4NzY7CiAgICAgICAgbWV0aG9kLT5wYWRbMl0gPSAweDAwOwoKICAgICAgICBtZXRob2QrKzsKICAgICAgICBlbnRyeSsrOwogICAgfQp9CgojZWxzZSAgLyogX19pMzg2X18gKi8KCnR5cGVkZWYgc3RydWN0IHtpbnQgZHVtbXk7fSB2dGJsX21ldGhvZF90OwpzdGF0aWMgdm9pZCBmaWxsX3RhYmxlKElVbmtub3duVnRibCAqdnRibCwgRFdPUkQgbnVtKQp7CiAgICBFUlIoImRlbGVnYXRlZCBzdHVicyBhcmUgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZVxuIik7Cn0KCiNlbmRpZiAgLyogX19pMzg2X18gKi8KCnZvaWQgY3JlYXRlX2RlbGVnYXRpbmdfdnRibChEV09SRCBudW1fbWV0aG9kcykKewogICAgVFJBQ0UoIiVkXG4iLCBudW1fbWV0aG9kcyk7CiAgICBpZihudW1fbWV0aG9kcyA8PSAzKQogICAgewogICAgICAgIEVSUigic2hvdWxkIGhhdmUgbW9yZSB0aGFuICVkIG1ldGhvZHNcbiIsIG51bV9tZXRob2RzKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRlbGVnYXRpbmdfdnRibF9zZWN0aW9uKTsKICAgIGlmKG51bV9tZXRob2RzID4gY3VycmVudF92dGJsLnNpemUpCiAgICB7CiAgICAgICAgRFdPUkQgc2l6ZTsKICAgICAgICBpZihjdXJyZW50X3Z0YmwudGFibGUgJiYgY3VycmVudF92dGJsLnRhYmxlLT5yZWYgPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJmcmVlaW5nIG9sZCB0YWJsZVxuIik7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGN1cnJlbnRfdnRibC50YWJsZSk7CiAgICAgICAgfQogICAgICAgIHNpemUgPSBzaXplb2YoRFdPUkQpICsgbnVtX21ldGhvZHMgKiBzaXplb2Yodm9pZCopICsgKG51bV9tZXRob2RzIC0gMykgKiBzaXplb2YodnRibF9tZXRob2RfdCk7CiAgICAgICAgY3VycmVudF92dGJsLnRhYmxlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgICAgIGZpbGxfdGFibGUoJmN1cnJlbnRfdnRibC50YWJsZS0+dnRibCwgbnVtX21ldGhvZHMpOwogICAgICAgIGN1cnJlbnRfdnRibC50YWJsZS0+cmVmID0gMDsKICAgICAgICBjdXJyZW50X3Z0Ymwuc2l6ZSA9IG51bV9tZXRob2RzOwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRlbGVnYXRpbmdfdnRibF9zZWN0aW9uKTsKfQoKc3RhdGljIElVbmtub3duVnRibCAqZ2V0X2RlbGVnYXRpbmdfdnRibCh2b2lkKQp7CiAgICBJVW5rbm93blZ0YmwgKnJldDsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGVsZWdhdGluZ192dGJsX3NlY3Rpb24pOwogICAgY3VycmVudF92dGJsLnRhYmxlLT5yZWYrKzsKICAgIHJldCA9ICZjdXJyZW50X3Z0YmwudGFibGUtPnZ0Ymw7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGVsZWdhdGluZ192dGJsX3NlY3Rpb24pOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgcmVsZWFzZV9kZWxlZ2F0aW5nX3Z0YmwoSVVua25vd25WdGJsICp2dGJsKQp7CiAgICByZWZfY291bnRlZF92dGJsICp0YWJsZSA9IChyZWZfY291bnRlZF92dGJsKikoKERXT1JEICopdnRibCAtIDEpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZWxlZ2F0aW5nX3Z0Ymxfc2VjdGlvbik7CiAgICB0YWJsZS0+cmVmLS07CiAgICBUUkFDRSgicmVmIG5vdyAlZFxuIiwgdGFibGUtPnJlZik7CiAgICBpZih0YWJsZS0+cmVmID09IDAgJiYgdGFibGUgIT0gY3VycmVudF92dGJsLnRhYmxlKQogICAgewogICAgICAgIFRSQUNFKCIuLi4gYW5kIHdlJ3JlIG5vdCBjdXJyZW50IHNvIGZyZWUnaW5nXG4iKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCB0YWJsZSk7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGVsZWdhdGluZ192dGJsX3NlY3Rpb24pOwp9CgpIUkVTVUxUIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9EZWxlZ2F0aW5nX0NvbnN0cnVjdChSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBVTktOT1dOIHBVbmtTZXJ2ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBDSW50ZXJmYWNlTmFtZSBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDSW50ZXJmYWNlU3R1YlZ0YmwgKnZ0YmwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCBkZWxlZ2F0aW5nX2lpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBQU0ZBQ1RPUllCVUZGRVIgcFBTRmFjdG9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENTVFVCQlVGRkVSICpwcFN0dWIpCnsKICAgIGNzdGRzdHViYnVmZmVyX2RlbGVnYXRpbmdfdCAqVGhpczsKICAgIElVbmtub3duICpwdlNlcnZlcjsKICAgIEhSRVNVTFQgcjsKCiAgICBUUkFDRSgiKCVwLCVwLCVwLCVwKSAlc1xuIiwgcFVua1NlcnZlciwgdnRibCwgcFBTRmFjdG9yeSwgcHBTdHViLCBuYW1lKTsKICAgIFRSQUNFKCJpaWQ9JXMgZGVsZWdhdGluZyB0byAlc1xuIiwgZGVidWdzdHJfZ3VpZCh2dGJsLT5oZWFkZXIucGlpZCksIGRlYnVnc3RyX2d1aWQoZGVsZWdhdGluZ19paWQpKTsKICAgIFRSQUNFKCJ2dGJsPSVwXG4iLCAmdnRibC0+VnRibCk7CgogICAgaWYgKCFJc0VxdWFsR1VJRCh2dGJsLT5oZWFkZXIucGlpZCwgcmlpZCkpCiAgICB7CiAgICAgICAgRVJSKCJJSUQgbWlzbWF0Y2ggZHVyaW5nIHN0dWIgY3JlYXRpb25cbiIpOwogICAgICAgIHJldHVybiBSUENfRV9VTkVYUEVDVEVEOwogICAgfQoKICAgIHIgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShwVW5rU2VydmVyLCByaWlkLCAodm9pZCoqKSZwdlNlcnZlcik7CiAgICBpZihGQUlMRUQocikpIHJldHVybiByOwoKICAgIFRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpUaGlzKSk7CiAgICBpZiAoIVRoaXMpCiAgICB7CiAgICAgICAgSVVua25vd25fUmVsZWFzZShwdlNlcnZlcik7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgVGhpcy0+YmFzZV9vYmogPSBnZXRfZGVsZWdhdGluZ192dGJsKCk7CiAgICByID0gY3JlYXRlX3N0dWIoZGVsZWdhdGluZ19paWQsIChJVW5rbm93biopJlRoaXMtPmJhc2Vfb2JqLCAmVGhpcy0+YmFzZV9zdHViKTsKICAgIGlmKEZBSUxFRChyKSkKICAgIHsKICAgICAgICByZWxlYXNlX2RlbGVnYXRpbmdfdnRibChUaGlzLT5iYXNlX29iaik7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICAgICAgSVVua25vd25fUmVsZWFzZShwdlNlcnZlcik7CiAgICAgICAgcmV0dXJuIHI7CiAgICB9CgogICAgVGhpcy0+c3R1Yl9idWZmZXIubHBWdGJsID0gJnZ0YmwtPlZ0Ymw7CiAgICBUaGlzLT5zdHViX2J1ZmZlci5SZWZDb3VudCA9IDE7CiAgICBUaGlzLT5zdHViX2J1ZmZlci5wdlNlcnZlck9iamVjdCA9IHB2U2VydmVyOwogICAgVGhpcy0+c3R1Yl9idWZmZXIucFBTRmFjdG9yeSA9IHBQU0ZhY3Rvcnk7CiAgICAqcHBTdHViID0gKExQUlBDU1RVQkJVRkZFUikmVGhpcy0+c3R1Yl9idWZmZXI7CgogICAgSVBTRmFjdG9yeUJ1ZmZlcl9BZGRSZWYocFBTRmFjdG9yeSk7CiAgICByZXR1cm4gU19PSzsKfQoKSFJFU1VMVCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqb2JqKQp7CiAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+UXVlcnlJbnRlcmZhY2UoJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxvYmopOwoKICBpZiAoSXNFcXVhbElJRCgmSUlEX0lVbmtub3duLCByaWlkKSB8fAogICAgICBJc0VxdWFsSUlEKCZJSURfSVJwY1N0dWJCdWZmZXIsIHJpaWQpKQogIHsKICAgIElVbmtub3duX0FkZFJlZihpZmFjZSk7CiAgICAqb2JqID0gaWZhY2U7CiAgICByZXR1cm4gU19PSzsKICB9CiAgKm9iaiA9IE5VTEw7CiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KClVMT05HIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9BZGRSZWYoTFBSUENTVFVCQlVGRkVSIGlmYWNlKQp7CiAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+QWRkUmVmKClcbiIsVGhpcyk7CiAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5SZWZDb3VudCk7Cn0KClVMT05HIFdJTkFQSSBOZHJDU3RkU3R1YkJ1ZmZlcl9SZWxlYXNlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFBTRkFDVE9SWUJVRkZFUiBwUFNGKQp7CiAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICBVTE9ORyByZWZzOwoKICBUUkFDRSgiKCVwKS0+UmVsZWFzZSgpXG4iLFRoaXMpOwoKICByZWZzID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPlJlZkNvdW50KTsKICBpZiAoIXJlZnMpCiAgewogICAgLyogdGVzdF9SZWxlYXNlIHNob3dzIHRoYXQgbmF0aXZlIGRvZXNuJ3QgY2FsbCBEaXNjb25uZWN0IGhlcmUuCiAgICAgICBXZSdsbCBsZWF2ZSBpdCBpbiBmb3IgdGhlIHRpbWUgYmVpbmcuICovCiAgICBJUnBjU3R1YkJ1ZmZlcl9EaXNjb25uZWN0KGlmYWNlKTsKCiAgICBJUFNGYWN0b3J5QnVmZmVyX1JlbGVhc2UocFBTRik7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsVGhpcyk7CiAgfQogIHJldHVybiByZWZzOwp9CgpVTE9ORyBXSU5BUEkgTmRyQ1N0ZFN0dWJCdWZmZXIyX1JlbGVhc2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBQU0ZBQ1RPUllCVUZGRVIgcFBTRikKewogICAgY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190ICpUaGlzID0gaW1wbF9mcm9tX2RlbGVnYXRpbmcoIGlmYWNlICk7CiAgICBVTE9ORyByZWZzOwoKICAgIFRSQUNFKCIoJXApLT5SZWxlYXNlKClcbiIsIFRoaXMpOwoKICAgIHJlZnMgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+c3R1Yl9idWZmZXIuUmVmQ291bnQpOwogICAgaWYgKCFyZWZzKQogICAgewogICAgICAgIC8qIEp1c3QgbGlrZSBOZHJDU3RkU3R1YkJ1ZmZlcl9SZWxlYXNlLCB3ZSBzaG91bGRuJ3QgY2FsbAogICAgICAgICAgIERpc2Nvbm5lY3QgaGVyZSAqLwogICAgICAgIElScGNTdHViQnVmZmVyX0Rpc2Nvbm5lY3QoKElScGNTdHViQnVmZmVyICopJlRoaXMtPnN0dWJfYnVmZmVyKTsKCiAgICAgICAgSVJwY1N0dWJCdWZmZXJfUmVsZWFzZShUaGlzLT5iYXNlX3N0dWIpOwogICAgICAgIHJlbGVhc2VfZGVsZWdhdGluZ192dGJsKFRoaXMtPmJhc2Vfb2JqKTsKCiAgICAgICAgSVBTRmFjdG9yeUJ1ZmZlcl9SZWxlYXNlKHBQU0YpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogICAgfQoKICAgIHJldHVybiByZWZzOwp9CgpIUkVTVUxUIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9Db25uZWN0KExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVU5LTk9XTiBscFVua1NlcnZlcikKewogICAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICAgIEhSRVNVTFQgcjsKICAgIElVbmtub3duICpuZXcgPSBOVUxMOwoKICAgIFRSQUNFKCIoJXApLT5Db25uZWN0KCVwKVxuIixUaGlzLGxwVW5rU2VydmVyKTsKCiAgICByID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtTZXJ2ZXIsIFNUVUJfSEVBREVSKFRoaXMpLnBpaWQsICh2b2lkKiopJm5ldyk7CiAgICBuZXcgPSBJbnRlcmxvY2tlZEV4Y2hhbmdlUG9pbnRlcigodm9pZCoqKSZUaGlzLT5wdlNlcnZlck9iamVjdCwgbmV3KTsKICAgIGlmKG5ldykKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKG5ldyk7CiAgICByZXR1cm4gcjsKfQoKdm9pZCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfRGlzY29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICAgIENTdGRTdHViQnVmZmVyICpUaGlzID0gKENTdGRTdHViQnVmZmVyICopaWZhY2U7CiAgICBJVW5rbm93biAqb2xkOwogICAgVFJBQ0UoIiglcCktPkRpc2Nvbm5lY3QoKVxuIixUaGlzKTsKCiAgICBvbGQgPSBJbnRlcmxvY2tlZEV4Y2hhbmdlUG9pbnRlcigodm9pZCoqKSZUaGlzLT5wdlNlcnZlck9iamVjdCwgTlVMTCk7CgogICAgaWYob2xkKQogICAgICAgIElVbmtub3duX1JlbGVhc2Uob2xkKTsKfQoKSFJFU1VMVCBXSU5BUEkgQ1N0ZFN0dWJCdWZmZXJfSW52b2tlKExQUlBDU1RVQkJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFJQQ09MRU1FU1NBR0UgcE1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENDSEFOTkVMQlVGRkVSIHBDaGFubmVsKQp7CiAgQ1N0ZFN0dWJCdWZmZXIgKlRoaXMgPSAoQ1N0ZFN0dWJCdWZmZXIgKilpZmFjZTsKICBEV09SRCBkd1BoYXNlID0gU1RVQl9VTk1BUlNIQUw7CiAgSFJFU1VMVCBociA9IFNfT0s7CgogIFRSQUNFKCIoJXApLT5JbnZva2UoJXAsJXApXG4iLFRoaXMscE1zZyxwQ2hhbm5lbCk7CgogIF9fVFJZCiAgewogICAgaWYgKFNUVUJfSEVBREVSKFRoaXMpLnBEaXNwYXRjaFRhYmxlKQogICAgICBTVFVCX0hFQURFUihUaGlzKS5wRGlzcGF0Y2hUYWJsZVtwTXNnLT5pTWV0aG9kXShpZmFjZSwgcENoYW5uZWwsIChQUlBDX01FU1NBR0UpcE1zZywgJmR3UGhhc2UpOwogICAgZWxzZSAvKiBwdXJlIGludGVycHJldGVkICovCiAgICAgIE5kclN0dWJDYWxsMihpZmFjZSwgcENoYW5uZWwsIChQUlBDX01FU1NBR0UpcE1zZywgJmR3UGhhc2UpOwogIH0KICBfX0VYQ0VQVChzdHViX2ZpbHRlcikKICB7CiAgICBEV09SRCBkd0V4Y2VwdGlvbkNvZGUgPSBHZXRFeGNlcHRpb25Db2RlKCk7CiAgICBXQVJOKCJhIHN0dWIgY2FsbCBmYWlsZWQgd2l0aCBleGNlcHRpb24gMHglMDh4ICglZClcbiIsIGR3RXhjZXB0aW9uQ29kZSwgZHdFeGNlcHRpb25Db2RlKTsKICAgIGlmIChGQUlMRUQoZHdFeGNlcHRpb25Db2RlKSkKICAgICAgaHIgPSBkd0V4Y2VwdGlvbkNvZGU7CiAgICBlbHNlCiAgICAgIGhyID0gSFJFU1VMVF9GUk9NX1dJTjMyKGR3RXhjZXB0aW9uQ29kZSk7CiAgfQogIF9fRU5EVFJZCgogIHJldHVybiBocjsKfQoKTFBSUENTVFVCQlVGRkVSIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9Jc0lJRFN1cHBvcnRlZChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCkKewogIENTdGRTdHViQnVmZmVyICpUaGlzID0gKENTdGRTdHViQnVmZmVyICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPklzSUlEU3VwcG9ydGVkKCVzKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkpOwogIHJldHVybiBJc0VxdWFsR1VJRChTVFVCX0hFQURFUihUaGlzKS5waWlkLCByaWlkKSA/IGlmYWNlIDogTlVMTDsKfQoKVUxPTkcgV0lOQVBJIENTdGRTdHViQnVmZmVyX0NvdW50UmVmcyhMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5Db3VudFJlZnMoKVxuIixUaGlzKTsKICByZXR1cm4gVGhpcy0+UmVmQ291bnQ7Cn0KCkhSRVNVTFQgV0lOQVBJIENTdGRTdHViQnVmZmVyX0RlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpwcHYpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5EZWJ1Z1NlcnZlclF1ZXJ5SW50ZXJmYWNlKCVwKVxuIixUaGlzLHBwdik7CiAgcmV0dXJuIFNfT0s7Cn0KCnZvaWQgV0lOQVBJIENTdGRTdHViQnVmZmVyX0RlYnVnU2VydmVyUmVsZWFzZShMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBwdikKewogIENTdGRTdHViQnVmZmVyICpUaGlzID0gKENTdGRTdHViQnVmZmVyICopaWZhY2U7CiAgVFJBQ0UoIiglcCktPkRlYnVnU2VydmVyUmVsZWFzZSglcClcbiIsVGhpcyxwdik7Cn0KCmNvbnN0IElScGNTdHViQnVmZmVyVnRibCBDU3RkU3R1YkJ1ZmZlcl9WdGJsID0KewogICAgQ1N0ZFN0dWJCdWZmZXJfUXVlcnlJbnRlcmZhY2UsCiAgICBDU3RkU3R1YkJ1ZmZlcl9BZGRSZWYsCiAgICBOVUxMLAogICAgQ1N0ZFN0dWJCdWZmZXJfQ29ubmVjdCwKICAgIENTdGRTdHViQnVmZmVyX0Rpc2Nvbm5lY3QsCiAgICBDU3RkU3R1YkJ1ZmZlcl9JbnZva2UsCiAgICBDU3RkU3R1YkJ1ZmZlcl9Jc0lJRFN1cHBvcnRlZCwKICAgIENTdGRTdHViQnVmZmVyX0NvdW50UmVmcywKICAgIENTdGRTdHViQnVmZmVyX0RlYnVnU2VydmVyUXVlcnlJbnRlcmZhY2UsCiAgICBDU3RkU3R1YkJ1ZmZlcl9EZWJ1Z1NlcnZlclJlbGVhc2UKfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDU3RkU3R1YkJ1ZmZlcl9EZWxlZ2F0aW5nX0Nvbm5lY3QoTFBSUENTVFVCQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVU5LTk9XTiBscFVua1NlcnZlcikKewogICAgY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190ICpUaGlzID0gaW1wbF9mcm9tX2RlbGVnYXRpbmcoaWZhY2UpOwogICAgSFJFU1VMVCByOwogICAgVFJBQ0UoIiglcCktPkNvbm5lY3QoJXApXG4iLCBUaGlzLCBscFVua1NlcnZlcik7CgogICAgciA9IENTdGRTdHViQnVmZmVyX0Nvbm5lY3QoaWZhY2UsIGxwVW5rU2VydmVyKTsKICAgIGlmKFNVQ0NFRURFRChyKSkKICAgICAgICByID0gSVJwY1N0dWJCdWZmZXJfQ29ubmVjdChUaGlzLT5iYXNlX3N0dWIsIChJVW5rbm93biopJlRoaXMtPmJhc2Vfb2JqKTsKCiAgICByZXR1cm4gcjsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfRGlzY29ubmVjdChMUFJQQ1NUVUJCVUZGRVIgaWZhY2UpCnsKICAgIGNzdGRzdHViYnVmZmVyX2RlbGVnYXRpbmdfdCAqVGhpcyA9IGltcGxfZnJvbV9kZWxlZ2F0aW5nKGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT5EaXNjb25uZWN0KClcbiIsIFRoaXMpOwoKICAgIElScGNTdHViQnVmZmVyX0Rpc2Nvbm5lY3QoVGhpcy0+YmFzZV9zdHViKTsKICAgIENTdGRTdHViQnVmZmVyX0Rpc2Nvbm5lY3QoaWZhY2UpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfQ291bnRSZWZzKExQUlBDU1RVQkJVRkZFUiBpZmFjZSkKewogICAgY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190ICpUaGlzID0gaW1wbF9mcm9tX2RlbGVnYXRpbmcoaWZhY2UpOwogICAgVUxPTkcgcmV0OwogICAgVFJBQ0UoIiglcCktPkNvdW50UmVmcygpXG4iLCBUaGlzKTsKCiAgICByZXQgPSBDU3RkU3R1YkJ1ZmZlcl9Db3VudFJlZnMoaWZhY2UpOwogICAgcmV0ICs9IElScGNTdHViQnVmZmVyX0NvdW50UmVmcyhUaGlzLT5iYXNlX3N0dWIpOwoKICAgIHJldHVybiByZXQ7Cn0KCmNvbnN0IElScGNTdHViQnVmZmVyVnRibCBDU3RkU3R1YkJ1ZmZlcl9EZWxlZ2F0aW5nX1Z0YmwgPQp7CiAgICBDU3RkU3R1YkJ1ZmZlcl9RdWVyeUludGVyZmFjZSwKICAgIENTdGRTdHViQnVmZmVyX0FkZFJlZiwKICAgIE5VTEwsCiAgICBDU3RkU3R1YkJ1ZmZlcl9EZWxlZ2F0aW5nX0Nvbm5lY3QsCiAgICBDU3RkU3R1YkJ1ZmZlcl9EZWxlZ2F0aW5nX0Rpc2Nvbm5lY3QsCiAgICBDU3RkU3R1YkJ1ZmZlcl9JbnZva2UsCiAgICBDU3RkU3R1YkJ1ZmZlcl9Jc0lJRFN1cHBvcnRlZCwKICAgIENTdGRTdHViQnVmZmVyX0RlbGVnYXRpbmdfQ291bnRSZWZzLAogICAgQ1N0ZFN0dWJCdWZmZXJfRGVidWdTZXJ2ZXJRdWVyeUludGVyZmFjZSwKICAgIENTdGRTdHViQnVmZmVyX0RlYnVnU2VydmVyUmVsZWFzZQp9OwoKY29uc3QgTUlETF9TRVJWRVJfSU5GTyAqQ1N0ZFN0dWJCdWZmZXJfR2V0U2VydmVySW5mbyhJUnBjU3R1YkJ1ZmZlciAqaWZhY2UpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIHJldHVybiBTVFVCX0hFQURFUihUaGlzKS5wU2VydmVySW5mbzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyU3R1YkZvcndhcmRpbmdGdW5jdGlvbiBbUlBDUlQ0LkBdCiAqLwp2b2lkIF9fUlBDX1NUVUIgTmRyU3R1YkZvcndhcmRpbmdGdW5jdGlvbiggSVJwY1N0dWJCdWZmZXIgKmlmYWNlLCBJUnBjQ2hhbm5lbEJ1ZmZlciAqcENoYW5uZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX01FU1NBR0UgcE1zZywgRFdPUkQgKnBkd1N0dWJQaGFzZSApCnsKICAgIC8qIE5vdGUgcE1zZyBpcyBwYXNzZWQgaW50YWN0IHNpbmNlIFJQQ09MRU1FU1NBR0UgaXMgYmFzaWNhbGx5IGEgUlBDX01FU1NBR0UuICovCgogICAgY3N0ZHN0dWJidWZmZXJfZGVsZWdhdGluZ190ICpUaGlzID0gaW1wbF9mcm9tX2RlbGVnYXRpbmcoaWZhY2UpOwogICAgSFJFU1VMVCByID0gSVJwY1N0dWJCdWZmZXJfSW52b2tlKFRoaXMtPmJhc2Vfc3R1YiwgKFJQQ09MRU1FU1NBR0UqKXBNc2csIHBDaGFubmVsKTsKICAgIGlmKEZBSUxFRChyKSkgUnBjUmFpc2VFeGNlcHRpb24ocik7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyU3R1YkluaXRpYWxpemUgW1JQQ1JUNC5AXQogKi8Kdm9pZCBXSU5BUEkgTmRyU3R1YkluaXRpYWxpemUoUFJQQ19NRVNTQUdFIHBScGNNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBNSURMX1NUVUJfREVTQyBwU3R1YkRlc2NyaXB0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENDSEFOTkVMQlVGRkVSIHBScGNDaGFubmVsQnVmZmVyKQp7CiAgVFJBQ0UoIiglcCwlcCwlcCwlcClcbiIsIHBScGNNc2csIHBTdHViTXNnLCBwU3R1YkRlc2NyaXB0b3IsIHBScGNDaGFubmVsQnVmZmVyKTsKICBOZHJTZXJ2ZXJJbml0aWFsaXplTmV3KHBScGNNc2csIHBTdHViTXNnLCBwU3R1YkRlc2NyaXB0b3IpOwogIHBTdHViTXNnLT5wUnBjQ2hhbm5lbEJ1ZmZlciA9IHBScGNDaGFubmVsQnVmZmVyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kclN0dWJHZXRCdWZmZXIgW1JQQ1JUNC5AXQogKi8Kdm9pZCBXSU5BUEkgTmRyU3R1YkdldEJ1ZmZlcihMUFJQQ1NUVUJCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ0NIQU5ORUxCVUZGRVIgcFJwY0NoYW5uZWxCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2cpCnsKICBDU3RkU3R1YkJ1ZmZlciAqVGhpcyA9IChDU3RkU3R1YkJ1ZmZlciAqKWlmYWNlOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsICVwLCAlcClcbiIsIFRoaXMsIHBScGNDaGFubmVsQnVmZmVyLCBwU3R1Yk1zZyk7CgogIHBTdHViTXNnLT5ScGNNc2ctPkJ1ZmZlckxlbmd0aCA9IHBTdHViTXNnLT5CdWZmZXJMZW5ndGg7CiAgaHIgPSBJUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIocFJwY0NoYW5uZWxCdWZmZXIsCiAgICAoUlBDT0xFTUVTU0FHRSAqKXBTdHViTXNnLT5ScGNNc2csIFNUVUJfSEVBREVSKFRoaXMpLnBpaWQpOwogIGlmIChGQUlMRUQoaHIpKQogIHsKICAgIFJwY1JhaXNlRXhjZXB0aW9uKGhyKTsKICAgIHJldHVybjsKICB9CgogIHBTdHViTXNnLT5CdWZmZXJTdGFydCA9IHBTdHViTXNnLT5ScGNNc2ctPkJ1ZmZlcjsKICBwU3R1Yk1zZy0+QnVmZmVyRW5kID0gcFN0dWJNc2ctPkJ1ZmZlclN0YXJ0ICsgcFN0dWJNc2ctPkJ1ZmZlckxlbmd0aDsKICBwU3R1Yk1zZy0+QnVmZmVyID0gcFN0dWJNc2ctPkJ1ZmZlclN0YXJ0Owp9Cg==