LyoKICogQ09NIHByb3h5L3N0dWIgZmFjdG9yeSAoQ1N0ZFBTRmFjdG9yeSkgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCgojaW5jbHVkZSAib2JqYmFzZS5oIgoKI2luY2x1ZGUgInJwY3Byb3h5LmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgImNwc2YuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7CgpzdGF0aWMgQk9PTCBGaW5kUHJveHlJbmZvKGNvbnN0IFByb3h5RmlsZUluZm8gKipwUHJveHlGaWxlTGlzdCwgUkVGSUlEIHJpaWQsIGNvbnN0IFByb3h5RmlsZUluZm8gKipwUHJveHlJbmZvLCBpbnQgKnBJbmRleCkKewogIHdoaWxlICgqcFByb3h5RmlsZUxpc3QpIHsKICAgIGlmICgoKnBQcm94eUZpbGVMaXN0KS0+cElJRExvb2t1cFJ0bihyaWlkLCBwSW5kZXgpKSB7CiAgICAgICpwUHJveHlJbmZvID0gKnBQcm94eUZpbGVMaXN0OwogICAgICBUUkFDRSgiZm91bmQ6IFByb3h5SW5mbyAlcCBJbmRleCAlZFxuIiwgKnBQcm94eUluZm8sICpwSW5kZXgpOwogICAgICByZXR1cm4gVFJVRTsKICAgIH0KICAgIHBQcm94eUZpbGVMaXN0Kys7CiAgfQogIFRSQUNFKCJub3QgZm91bmRcbiIpOwogIHJldHVybiBGQUxTRTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENTdGRQU0ZhY3RvcnlfUXVlcnlJbnRlcmZhY2UoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpvYmopCnsKICBDU3RkUFNGYWN0b3J5QnVmZmVyICpUaGlzID0gKENTdGRQU0ZhY3RvcnlCdWZmZXIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+UXVlcnlJbnRlcmZhY2UoJXMsJXApXG4iLGlmYWNlLGRlYnVnc3RyX2d1aWQocmlpZCksb2JqKTsKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93bixyaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lQU0ZhY3RvcnlCdWZmZXIscmlpZCkpIHsKICAgICpvYmogPSBUaGlzOwogICAgVGhpcy0+UmVmQ291bnQrKzsKICAgIHJldHVybiBTX09LOwogIH0KICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBDU3RkUFNGYWN0b3J5X0FkZFJlZihMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSkKewogIENTdGRQU0ZhY3RvcnlCdWZmZXIgKlRoaXMgPSAoQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqKWlmYWNlOwogIFRSQUNFKCIoJXApLT5BZGRSZWYoKVxuIixpZmFjZSk7CiAgcmV0dXJuICsrKFRoaXMtPlJlZkNvdW50KTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBDU3RkUFNGYWN0b3J5X1JlbGVhc2UoTFBQU0ZBQ1RPUllCVUZGRVIgaWZhY2UpCnsKICBDU3RkUFNGYWN0b3J5QnVmZmVyICpUaGlzID0gKENTdGRQU0ZhY3RvcnlCdWZmZXIgKilpZmFjZTsKICBUUkFDRSgiKCVwKS0+UmVsZWFzZSgpXG4iLGlmYWNlKTsKICByZXR1cm4gLS0oVGhpcy0+UmVmQ291bnQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ1N0ZFBTRmFjdG9yeV9DcmVhdGVQcm94eShMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFVOS05PV04gcFVua091dGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDUFJPWFlCVUZGRVIgKnBwUHJveHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpwcHYpCnsKICBDU3RkUFNGYWN0b3J5QnVmZmVyICpUaGlzID0gKENTdGRQU0ZhY3RvcnlCdWZmZXIgKilpZmFjZTsKICBjb25zdCBQcm94eUZpbGVJbmZvICpQcm94eUluZm87CiAgaW50IEluZGV4OwogIFRSQUNFKCIoJXApLT5DcmVhdGVQcm94eSglcCwlcywlcCwlcClcbiIsaWZhY2UscFVua091dGVyLAogICAgICAgZGVidWdzdHJfZ3VpZChyaWlkKSxwcFByb3h5LHBwdik7CiAgaWYgKCFGaW5kUHJveHlJbmZvKFRoaXMtPnBQcm94eUZpbGVMaXN0LHJpaWQsJlByb3h5SW5mbywmSW5kZXgpKQogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgcmV0dXJuIFN0ZFByb3h5X0NvbnN0cnVjdChyaWlkLCBwVW5rT3V0ZXIsIFByb3h5SW5mbywgSW5kZXgsIGlmYWNlLCBwcFByb3h5LCBwcHYpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ1N0ZFBTRmFjdG9yeV9DcmVhdGVTdHViKExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFVOS05PV04gcFVua1NlcnZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQUlBDU1RVQkJVRkZFUiAqcHBTdHViKQp7CiAgQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqVGhpcyA9IChDU3RkUFNGYWN0b3J5QnVmZmVyICopaWZhY2U7CiAgY29uc3QgUHJveHlGaWxlSW5mbyAqUHJveHlJbmZvOwogIGludCBJbmRleDsKICBUUkFDRSgiKCVwKS0+Q3JlYXRlU3R1YiglcywlcCwlcClcbiIsaWZhY2UsZGVidWdzdHJfZ3VpZChyaWlkKSwKICAgICAgIHBVbmtTZXJ2ZXIscHBTdHViKTsKICBpZiAoIUZpbmRQcm94eUluZm8oVGhpcy0+cFByb3h5RmlsZUxpc3QscmlpZCwmUHJveHlJbmZvLCZJbmRleCkpCiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKCiAgaWYoUHJveHlJbmZvLT5wRGVsZWdhdGVkSUlEcyAmJiBQcm94eUluZm8tPnBEZWxlZ2F0ZWRJSURzW0luZGV4XSkKICAgIHJldHVybiAgQ1N0ZFN0dWJCdWZmZXJfRGVsZWdhdGluZ19Db25zdHJ1Y3QocmlpZCwgcFVua1NlcnZlciwgUHJveHlJbmZvLT5wTmFtZXNBcnJheVtJbmRleF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByb3h5SW5mby0+cFN0dWJWdGJsTGlzdFtJbmRleF0sIFByb3h5SW5mby0+cERlbGVnYXRlZElJRHNbSW5kZXhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZmFjZSwgcHBTdHViKTsKCiAgcmV0dXJuIENTdGRTdHViQnVmZmVyX0NvbnN0cnVjdChyaWlkLCBwVW5rU2VydmVyLCBQcm94eUluZm8tPnBOYW1lc0FycmF5W0luZGV4XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByb3h5SW5mby0+cFN0dWJWdGJsTGlzdFtJbmRleF0sIGlmYWNlLCBwcFN0dWIpOwp9CgpzdGF0aWMgY29uc3QgSVBTRmFjdG9yeUJ1ZmZlclZ0YmwgQ1N0ZFBTRmFjdG9yeV9WdGJsID0KewogIENTdGRQU0ZhY3RvcnlfUXVlcnlJbnRlcmZhY2UsCiAgQ1N0ZFBTRmFjdG9yeV9BZGRSZWYsCiAgQ1N0ZFBTRmFjdG9yeV9SZWxlYXNlLAogIENTdGRQU0ZhY3RvcnlfQ3JlYXRlUHJveHksCiAgQ1N0ZFBTRmFjdG9yeV9DcmVhdGVTdHViCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckRsbEdldENsYXNzT2JqZWN0IFtSUENSVDQuQF0KICovCkhSRVNVTFQgV0lOQVBJIE5kckRsbEdldENsYXNzT2JqZWN0KFJFRkNMU0lEIHJjbHNpZCwgUkVGSUlEIGlpZCwgTFBWT0lEICpwcHYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUHJveHlGaWxlSW5mbyAqKnBQcm94eUZpbGVMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENMU0lEICpwY2xzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqcFBTRmFjdG9yeUJ1ZmZlcikKewogIFRSQUNFKCIoJXMsICVzLCAlcCwgJXAsICVzLCAlcClcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSwKICAgIGRlYnVnc3RyX2d1aWQoaWlkKSwgcHB2LCBwUHJveHlGaWxlTGlzdCwgZGVidWdzdHJfZ3VpZChwY2xzaWQpLAogICAgcFBTRmFjdG9yeUJ1ZmZlcik7CgogICpwcHYgPSBOVUxMOwogIGlmICghcFBTRmFjdG9yeUJ1ZmZlci0+bHBWdGJsKSB7CiAgICBjb25zdCBQcm94eUZpbGVJbmZvICoqcFByb3h5RmlsZUxpc3QyOwogICAgaW50IG1heF9kZWxlZ2F0aW5nX3Z0Ymxfc2l6ZSA9IDA7CiAgICBwUFNGYWN0b3J5QnVmZmVyLT5scFZ0YmwgPSAmQ1N0ZFBTRmFjdG9yeV9WdGJsOwogICAgcFBTRmFjdG9yeUJ1ZmZlci0+UmVmQ291bnQgPSAwOwogICAgcFBTRmFjdG9yeUJ1ZmZlci0+cFByb3h5RmlsZUxpc3QgPSBwUHJveHlGaWxlTGlzdDsKICAgIGZvciAocFByb3h5RmlsZUxpc3QyID0gcFByb3h5RmlsZUxpc3Q7ICpwUHJveHlGaWxlTGlzdDI7IHBQcm94eUZpbGVMaXN0MisrKSB7CiAgICAgIGludCBpOwogICAgICBmb3IgKGkgPSAwOyBpIDwgKCpwUHJveHlGaWxlTGlzdDIpLT5UYWJsZVNpemU7IGkrKykgewogICAgICAgIC8qIEZJWE1FOiBpIHRoaW5rIHRoYXQgZGlmZmVyZW50IHZ0YWJsZXMgc2hvdWxkIGJlIGNvcGllZCBmb3IKICAgICAgICAgKiBhc3luYyBpbnRlcmZhY2VzICovCiAgICAgICAgdm9pZCAqIGNvbnN0ICpwU3JjUnBjU3R1YlZ0YmwgPSAodm9pZCAqIGNvbnN0ICopJkNTdGRTdHViQnVmZmVyX1Z0Ymw7CiAgICAgICAgdm9pZCAqKnBScGNTdHViVnRibCA9ICh2b2lkICoqKSYoKnBQcm94eUZpbGVMaXN0MiktPnBTdHViVnRibExpc3RbaV0tPlZ0Ymw7CiAgICAgICAgaW50IGo7CgogICAgICAgIGlmICgoKnBQcm94eUZpbGVMaXN0MiktPnBEZWxlZ2F0ZWRJSURzICYmICgqcFByb3h5RmlsZUxpc3QyKS0+cERlbGVnYXRlZElJRHNbaV0pIHsKICAgICAgICAgIHBTcmNScGNTdHViVnRibCA9ICh2b2lkICogY29uc3QgKikmQ1N0ZFN0dWJCdWZmZXJfRGVsZWdhdGluZ19WdGJsOwogICAgICAgICAgaWYgKCgqcFByb3h5RmlsZUxpc3QyKS0+cFN0dWJWdGJsTGlzdFtpXS0+aGVhZGVyLkRpc3BhdGNoVGFibGVDb3VudCA+IG1heF9kZWxlZ2F0aW5nX3Z0Ymxfc2l6ZSkKICAgICAgICAgICAgbWF4X2RlbGVnYXRpbmdfdnRibF9zaXplID0gKCpwUHJveHlGaWxlTGlzdDIpLT5wU3R1YlZ0YmxMaXN0W2ldLT5oZWFkZXIuRGlzcGF0Y2hUYWJsZUNvdW50OwogICAgICAgIH0KCiAgICAgICAgZm9yIChqID0gMDsgaiA8IHNpemVvZihJUnBjU3R1YkJ1ZmZlclZ0YmwpL3NpemVvZih2b2lkICopOyBqKyspCiAgICAgICAgICBpZiAoIXBScGNTdHViVnRibFtqXSkKICAgICAgICAgICAgcFJwY1N0dWJWdGJsW2pdID0gcFNyY1JwY1N0dWJWdGJsW2pdOwogICAgICB9CiAgICB9CiAgICBpZihtYXhfZGVsZWdhdGluZ192dGJsX3NpemUgPiAwKQogICAgICBjcmVhdGVfZGVsZWdhdGluZ192dGJsKG1heF9kZWxlZ2F0aW5nX3Z0Ymxfc2l6ZSk7CiAgfQogIGlmIChJc0VxdWFsR1VJRChyY2xzaWQsIHBjbHNpZCkpCiAgICByZXR1cm4gSVBTRmFjdG9yeUJ1ZmZlcl9RdWVyeUludGVyZmFjZSgoTFBQU0ZBQ1RPUllCVUZGRVIpcFBTRmFjdG9yeUJ1ZmZlciwgaWlkLCBwcHYpOwogIGVsc2UgewogICAgY29uc3QgUHJveHlGaWxlSW5mbyAqaW5mbzsKICAgIGludCBpbmRleDsKICAgIC8qIG90aGVyd2lzZSwgdGhlIGRsbCBtYXkgYmUgdXNpbmcgdGhlIGlpZCBhcyB0aGUgY2xzaWQsIHNvCiAgICAgKiBzZWFyY2ggZm9yIGl0IGluIHRoZSBwcm94eSBmaWxlIGxpc3QgKi8KICAgIGlmIChGaW5kUHJveHlJbmZvKHBQcm94eUZpbGVMaXN0LCByY2xzaWQsICZpbmZvLCAmaW5kZXgpKQogICAgICByZXR1cm4gSVBTRmFjdG9yeUJ1ZmZlcl9RdWVyeUludGVyZmFjZSgoTFBQU0ZBQ1RPUllCVUZGRVIpcFBTRmFjdG9yeUJ1ZmZlciwgaWlkLCBwcHYpOwoKICAgIFdBUk4oImNsYXNzICVzIG5vdCBhdmFpbGFibGVcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSk7CiAgICByZXR1cm4gQ0xBU1NfRV9DTEFTU05PVEFWQUlMQUJMRTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyRGxsQ2FuVW5sb2FkTm93IFtSUENSVDQuQF0KICovCkhSRVNVTFQgV0lOQVBJIE5kckRsbENhblVubG9hZE5vdyhDU3RkUFNGYWN0b3J5QnVmZmVyICpwUFNGYWN0b3J5QnVmZmVyKQp7CiAgcmV0dXJuICEocFBTRmFjdG9yeUJ1ZmZlci0+UmVmQ291bnQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckRsbFJlZ2lzdGVyUHJveHkgW1JQQ1JUNC5AXQogKi8KSFJFU1VMVCBXSU5BUEkgTmRyRGxsUmVnaXN0ZXJQcm94eShITU9EVUxFIGhEbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQcm94eUZpbGVJbmZvICoqcFByb3h5RmlsZUxpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDTFNJRCAqcGNsc2lkKQp7CiAgTFBTVFIgY2xzaWQ7CiAgY2hhciBrZXluYW1lWzEyMF0sIG1vZHVsZVtNQVhfUEFUSF07CiAgSEtFWSBrZXksIHN1YmtleTsKICBEV09SRCBsZW47CgogIFRSQUNFKCIoJXAsJXAsJXMpXG4iLCBoRGxsLCBwUHJveHlGaWxlTGlzdCwgZGVidWdzdHJfZ3VpZChwY2xzaWQpKTsKICBVdWlkVG9TdHJpbmdBKChVVUlEKilwY2xzaWQsICh1bnNpZ25lZCBjaGFyKiopJmNsc2lkKTsKCiAgLyogcmVnaXN0ZXIgaW50ZXJmYWNlcyB0byBwb2ludCB0byBjbHNpZCAqLwogIHdoaWxlICgqcFByb3h5RmlsZUxpc3QpIHsKICAgIHVuc2lnbmVkIHU7CiAgICBmb3IgKHU9MDsgdTwoKnBQcm94eUZpbGVMaXN0KS0+VGFibGVTaXplOyB1KyspIHsKICAgICAgQ0ludGVyZmFjZVN0dWJWdGJsICpwcm94eSA9ICgqcFByb3h5RmlsZUxpc3QpLT5wU3R1YlZ0YmxMaXN0W3VdOwogICAgICBQQ0ludGVyZmFjZU5hbWUgbmFtZSA9ICgqcFByb3h5RmlsZUxpc3QpLT5wTmFtZXNBcnJheVt1XTsKICAgICAgTFBTVFIgaWlkOwoKICAgICAgVFJBQ0UoInJlZ2lzdGVyaW5nICVzICVzID0+ICVzXG4iLCBuYW1lLCBkZWJ1Z3N0cl9ndWlkKHByb3h5LT5oZWFkZXIucGlpZCksIGNsc2lkKTsKCiAgICAgIFV1aWRUb1N0cmluZ0EoKFVVSUQqKXByb3h5LT5oZWFkZXIucGlpZCwgKHVuc2lnbmVkIGNoYXIqKikmaWlkKTsKICAgICAgc25wcmludGYoa2V5bmFtZSwgc2l6ZW9mKGtleW5hbWUpLCAiSW50ZXJmYWNlXFx7JXN9IiwgaWlkKTsKICAgICAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmaWlkKTsKICAgICAgaWYgKFJlZ0NyZWF0ZUtleUV4QShIS0VZX0NMQVNTRVNfUk9PVCwga2V5bmFtZSwgMCwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfV1JJVEUsIE5VTEwsICZrZXksIE5VTEwpID09IEVSUk9SX1NVQ0NFU1MpIHsKICAgICAgICBpZiAobmFtZSkKICAgICAgICAgIFJlZ1NldFZhbHVlRXhBKGtleSwgTlVMTCwgMCwgUkVHX1NaLCAoY29uc3QgQllURSAqKW5hbWUsIHN0cmxlbihuYW1lKSk7CiAgICAgICAgaWYgKFJlZ0NyZWF0ZUtleUV4QShrZXksICJQcm94eVN0dWJDbHNpZDMyIiwgMCwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9XUklURSwgTlVMTCwgJnN1YmtleSwgTlVMTCkgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgICAgc25wcmludGYobW9kdWxlLCBzaXplb2YobW9kdWxlKSwgInslc30iLCBjbHNpZCk7CiAgICAgICAgICBSZWdTZXRWYWx1ZUV4QShzdWJrZXksIE5VTEwsIDAsIFJFR19TWiwgKExQQllURSltb2R1bGUsIHN0cmxlbihtb2R1bGUpKTsKICAgICAgICAgIFJlZ0Nsb3NlS2V5KHN1YmtleSk7CiAgICAgICAgfQogICAgICAgIFJlZ0Nsb3NlS2V5KGtleSk7CiAgICAgIH0KICAgIH0KICAgIHBQcm94eUZpbGVMaXN0Kys7CiAgfQoKICAvKiByZWdpc3RlciBjbHNpZCB0byBwb2ludCB0byBtb2R1bGUgKi8KICBzbnByaW50ZihrZXluYW1lLCBzaXplb2Yoa2V5bmFtZSksICJDTFNJRFxceyVzfSIsIGNsc2lkKTsKICBsZW4gPSBHZXRNb2R1bGVGaWxlTmFtZUEoaERsbCwgbW9kdWxlLCBzaXplb2YobW9kdWxlKSk7CiAgaWYgKGxlbiAmJiBsZW4gPCBzaXplb2YobW9kdWxlKSkgewogICAgVFJBQ0UoInJlZ2lzdGVyaW5nIENMU0lEICVzID0+ICVzXG4iLCBjbHNpZCwgbW9kdWxlKTsKICAgIGlmIChSZWdDcmVhdGVLZXlFeEEoSEtFWV9DTEFTU0VTX1JPT1QsIGtleW5hbWUsIDAsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9XUklURSwgTlVMTCwgJmtleSwgTlVMTCkgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICBSZWdTZXRWYWx1ZUV4QShzdWJrZXksIE5VTEwsIDAsIFJFR19TWiwgKGNvbnN0IEJZVEUgKikiUFNGYWN0b3J5QnVmZmVyIiwgc3RybGVuKCJQU0ZhY3RvcnlCdWZmZXIiKSk7CiAgICAgIGlmIChSZWdDcmVhdGVLZXlFeEEoa2V5LCAiSW5Qcm9jU2VydmVyMzIiLCAwLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9XUklURSwgTlVMTCwgJnN1YmtleSwgTlVMTCkgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgIFJlZ1NldFZhbHVlRXhBKHN1YmtleSwgTlVMTCwgMCwgUkVHX1NaLCAoTFBCWVRFKW1vZHVsZSwgc3RybGVuKG1vZHVsZSkpOwogICAgICAgIFJlZ1NldFZhbHVlRXhBKHN1YmtleSwgIlRocmVhZGluZ01vZGVsIiwgMCwgUkVHX1NaLCAoY29uc3QgQllURSAqKSJCb3RoIiwgc3RybGVuKCJCb3RoIikpOwogICAgICAgIFJlZ0Nsb3NlS2V5KHN1YmtleSk7CiAgICAgIH0KICAgICAgUmVnQ2xvc2VLZXkoa2V5KTsKICAgIH0KICB9CgogIC8qIGRvbmUgKi8KICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZjbHNpZCk7CiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyRGxsVW5yZWdpc3RlclByb3h5IFtSUENSVDQuQF0KICovCkhSRVNVTFQgV0lOQVBJIE5kckRsbFVucmVnaXN0ZXJQcm94eShITU9EVUxFIGhEbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFByb3h5RmlsZUluZm8gKipwUHJveHlGaWxlTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0xTSUQgKnBjbHNpZCkKewogIExQU1RSIGNsc2lkOwogIGNoYXIga2V5bmFtZVsxMjBdLCBtb2R1bGVbTUFYX1BBVEhdOwogIERXT1JEIGxlbjsKCiAgVFJBQ0UoIiglcCwlcCwlcylcbiIsIGhEbGwsIHBQcm94eUZpbGVMaXN0LCBkZWJ1Z3N0cl9ndWlkKHBjbHNpZCkpOwogIFV1aWRUb1N0cmluZ0EoKFVVSUQqKXBjbHNpZCwgKHVuc2lnbmVkIGNoYXIqKikmY2xzaWQpOwoKICAvKiB1bnJlZ2lzdGVyIGludGVyZmFjZXMgKi8KICB3aGlsZSAoKnBQcm94eUZpbGVMaXN0KSB7CiAgICB1bnNpZ25lZCB1OwogICAgZm9yICh1PTA7IHU8KCpwUHJveHlGaWxlTGlzdCktPlRhYmxlU2l6ZTsgdSsrKSB7CiAgICAgIENJbnRlcmZhY2VTdHViVnRibCAqcHJveHkgPSAoKnBQcm94eUZpbGVMaXN0KS0+cFN0dWJWdGJsTGlzdFt1XTsKICAgICAgUENJbnRlcmZhY2VOYW1lIG5hbWUgPSAoKnBQcm94eUZpbGVMaXN0KS0+cE5hbWVzQXJyYXlbdV07CiAgICAgIExQU1RSIGlpZDsKCiAgICAgIFRSQUNFKCJ1bnJlZ2lzdGVyaW5nICVzICVzIDw9ICVzXG4iLCBuYW1lLCBkZWJ1Z3N0cl9ndWlkKHByb3h5LT5oZWFkZXIucGlpZCksIGNsc2lkKTsKCiAgICAgIFV1aWRUb1N0cmluZ0EoKFVVSUQqKXByb3h5LT5oZWFkZXIucGlpZCwgKHVuc2lnbmVkIGNoYXIqKikmaWlkKTsKICAgICAgc25wcmludGYoa2V5bmFtZSwgc2l6ZW9mKGtleW5hbWUpLCAiSW50ZXJmYWNlXFx7JXN9IiwgaWlkKTsKICAgICAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmaWlkKTsKICAgICAgUmVnRGVsZXRlS2V5QShIS0VZX0NMQVNTRVNfUk9PVCwga2V5bmFtZSk7CiAgICB9CiAgICBwUHJveHlGaWxlTGlzdCsrOwogIH0KCiAgLyogdW5yZWdpc3RlciBjbHNpZCAqLwogIHNucHJpbnRmKGtleW5hbWUsIHNpemVvZihrZXluYW1lKSwgIkNMU0lEXFx7JXN9IiwgY2xzaWQpOwogIGxlbiA9IEdldE1vZHVsZUZpbGVOYW1lQShoRGxsLCBtb2R1bGUsIHNpemVvZihtb2R1bGUpKTsKICBpZiAobGVuICYmIGxlbiA8IHNpemVvZihtb2R1bGUpKSB7CiAgICBUUkFDRSgidW5yZWdpc3RlcmluZyBDTFNJRCAlcyA8PSAlc1xuIiwgY2xzaWQsIG1vZHVsZSk7CiAgICBSZWdEZWxldGVLZXlBKEhLRVlfQ0xBU1NFU19ST09ULCBrZXluYW1lKTsKICB9CgogIC8qIGRvbmUgKi8KICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZjbHNpZCk7CiAgcmV0dXJuIFNfT0s7Cn0K