LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uIG9mIG1hbmFnZW1lbnQobm9uLXJlbmRlcmluZykgZnVuY3Rpb25zCiAqCiAqIENvcHlyaWdodCAxOTk4IExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqIENvcHlyaWdodCAyMDA3IEhlbnJpIFZlcmJlZXQKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBSb2RlcmljayBDb2xlbmJyYW5kZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9zdXJmYWNlKTsKCi8qIERvIE5PVCBkZWZpbmUgR0xJTkZPX0xPQ0FUSU9OIGluIHRoaXMgZmlsZS4gVEhJUyBDT0RFIE1VU1QgTk9UIFVTRSBJVCAqLwoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVVua25vd24gcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfUXVlcnlJbnRlcmZhY2UoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBvYmopCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgLyogV2FybiAsYnV0IGJlIG5pY2UgYWJvdXQgdGhpbmdzICovCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEQmFzZSkKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEUmVzb3VyY2UpCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzRFN1cmZhY2UpKSB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKChJVW5rbm93biopaWZhY2UpOwogICAgICAgICpwcG9iaiA9IFRoaXM7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICAgICAgfQogICAgICAgICpwcG9iaiA9IE5VTEw7CiAgICAgICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KClVMT05HIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9BZGRSZWYoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogQWRkUmVmIGluY3JlYXNpbmcgZnJvbSAlZFxuIiwgVGhpcyxyZWYgLSAxKTsKICAgIHJldHVybiByZWY7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIElXaW5lRDNEUmVzb3VyY2UgcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0RGV2aWNlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNERGV2aWNlKiogcHBEZXZpY2UpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXREZXZpY2UoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcHBEZXZpY2UpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZHVUlEIHJlZmd1aWQsIENPTlNUIHZvaWQqIHBEYXRhLCBEV09SRCBTaXplT2ZEYXRhLCBEV09SRCBGbGFncykgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX1NldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBTaXplT2ZEYXRhLCBGbGFncyk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFByaXZhdGVEYXRhKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRkdVSUQgcmVmZ3VpZCwgdm9pZCogcERhdGEsIERXT1JEKiBwU2l6ZU9mRGF0YSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBwU2l6ZU9mRGF0YSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0ZyZWVQcml2YXRlRGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZHVUlEIHJlZmd1aWQpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9GcmVlUHJpdmF0ZURhdGEoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcmVmZ3VpZCk7Cn0KCkRXT1JEICAgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldFByaW9yaXR5KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIFByaW9yaXR5TmV3KSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfU2V0UHJpb3JpdHkoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgUHJpb3JpdHlOZXcpOwp9CgpEV09SRCAgIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQcmlvcml0eShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UHJpb3JpdHkoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSk7Cn0KCldJTkVEM0RSRVNPVVJDRVRZUEUgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFR5cGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgVFJBQ0UoIiglcCkgOiBjYWxsaW5nIHJlc291cmNlaW1wbF9HZXRUeXBlXG4iLCBpZmFjZSk7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0VHlwZSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UGFyZW50KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElVbmtub3duICoqcFBhcmVudCkgewogICAgVFJBQ0UoIiglcCkgOiBjYWxsaW5nIHJlc291cmNlaW1wbF9HZXRQYXJlbnRcbiIsIGlmYWNlKTsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXRQYXJlbnQoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcFBhcmVudCk7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVdpbmVEM0RTdXJmYWNlIHBhcnRzIGZvbGxvdwogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldENvbnRhaW5lcihJV2luZUQzRFN1cmZhY2UqIGlmYWNlLCBSRUZJSUQgcmlpZCwgdm9pZCoqIHBwQ29udGFpbmVyKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZSAqY29udGFpbmVyID0gMDsKCiAgICBUUkFDRSgiKFRoaXMgJXAsIHJpaWQgJXMsIHBwQ29udGFpbmVyICVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHBDb250YWluZXIpOwoKICAgIGlmICghcHBDb250YWluZXIpIHsKICAgICAgICBFUlIoIkNhbGxlZCB3aXRob3V0IGEgdmFsaWQgcHBDb250YWluZXIuXG4iKTsKICAgIH0KCiAgICAvKiogRnJvbSBNU0ROOgogICAgICogSWYgdGhlIHN1cmZhY2UgaXMgY3JlYXRlZCB1c2luZyBDcmVhdGVJbWFnZVN1cmZhY2UvQ3JlYXRlT2Zmc2NyZWVuUGxhaW5TdXJmYWNlLCBDcmVhdGVSZW5kZXJUYXJnZXQsCiAgICAgKiBvciBDcmVhdGVEZXB0aFN0ZW5jaWxTdXJmYWNlLCB0aGUgc3VyZmFjZSBpcyBjb25zaWRlcmVkIHN0YW5kIGFsb25lLiBJbiB0aGlzIGNhc2UsCiAgICAgKiBHZXRDb250YWluZXIgd2lsbCByZXR1cm4gdGhlIERpcmVjdDNEIGRldmljZSB1c2VkIHRvIGNyZWF0ZSB0aGUgc3VyZmFjZS4KICAgICAqLwogICAgaWYgKFRoaXMtPmNvbnRhaW5lcikgewogICAgICAgIGNvbnRhaW5lciA9IFRoaXMtPmNvbnRhaW5lcjsKICAgIH0gZWxzZSB7CiAgICAgICAgY29udGFpbmVyID0gKElXaW5lRDNEQmFzZSAqKVRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICB9CgogICAgVFJBQ0UoIlJlbGF5aW5nIHRvIFF1ZXJ5SW50ZXJmYWNlXG4iKTsKICAgIHJldHVybiBJVW5rbm93bl9RdWVyeUludGVyZmFjZShjb250YWluZXIsIHJpaWQsIHBwQ29udGFpbmVyKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0RGVzYyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBXSU5FRDNEU1VSRkFDRV9ERVNDICpwRGVzYykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBjb3B5aW5nIGludG8gJXBcbiIsIFRoaXMsIHBEZXNjKTsKICAgIGlmKHBEZXNjLT5Gb3JtYXQgIT0gTlVMTCkgICAgICAgICAgICAgKihwRGVzYy0+Rm9ybWF0KSA9IFRoaXMtPnJlc291cmNlLmZvcm1hdDsKICAgIGlmKHBEZXNjLT5UeXBlICE9IE5VTEwpICAgICAgICAgICAgICAgKihwRGVzYy0+VHlwZSkgICA9IFRoaXMtPnJlc291cmNlLnJlc291cmNlVHlwZTsKICAgIGlmKHBEZXNjLT5Vc2FnZSAhPSBOVUxMKSAgICAgICAgICAgICAgKihwRGVzYy0+VXNhZ2UpICAgICAgICAgICAgICA9IFRoaXMtPnJlc291cmNlLnVzYWdlOwogICAgaWYocERlc2MtPlBvb2wgIT0gTlVMTCkgICAgICAgICAgICAgICAqKHBEZXNjLT5Qb29sKSAgICAgICAgICAgICAgID0gVGhpcy0+cmVzb3VyY2UucG9vbDsKICAgIGlmKHBEZXNjLT5TaXplICE9IE5VTEwpICAgICAgICAgICAgICAgKihwRGVzYy0+U2l6ZSkgICAgICAgICAgICAgICA9IFRoaXMtPnJlc291cmNlLnNpemU7ICAgLyogZHg4IG9ubHkgKi8KICAgIGlmKHBEZXNjLT5NdWx0aVNhbXBsZVR5cGUgIT0gTlVMTCkgICAgKihwRGVzYy0+TXVsdGlTYW1wbGVUeXBlKSAgICA9IFRoaXMtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlVHlwZTsKICAgIGlmKHBEZXNjLT5NdWx0aVNhbXBsZVF1YWxpdHkgIT0gTlVMTCkgKihwRGVzYy0+TXVsdGlTYW1wbGVRdWFsaXR5KSA9IFRoaXMtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlUXVhbGl0eTsKICAgIGlmKHBEZXNjLT5XaWR0aCAhPSBOVUxMKSAgICAgICAgICAgICAgKihwRGVzYy0+V2lkdGgpICAgICAgICAgICAgICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgaWYocERlc2MtPkhlaWdodCAhPSBOVUxMKSAgICAgICAgICAgICAqKHBEZXNjLT5IZWlnaHQpICAgICAgICAgICAgID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCV4KVxuIiwgVGhpcywgRmxhZ3MpOwoKICAgIHN3aXRjaCAoRmxhZ3MpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRERHQlNfQ0FOQkxUOgogICAgICAgIGNhc2UgV0lORURER0JTX0lTQkxURE9ORToKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRGbGlwU3RhdHVzKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzKSB7CiAgICAvKiBYWFg6IERERVJSX0lOVkFMSURTVVJGQUNFVFlQRSAqLwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eClcbiIsaWZhY2UsRmxhZ3MpOwogICAgc3dpdGNoIChGbGFncykgewogICAgICAgIGNhc2UgV0lORURER0ZTX0NBTkZMSVA6CiAgICAgICAgY2FzZSBXSU5FRERHRlNfSVNGTElQRE9ORToKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9Jc0xvc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIEQzRDggYW5kIDkgbG9vc2UgZnVsbCBkZXZpY2VzLCBkZHJhdyBvbmx5IHN1cmZhY2VzICovCiAgICByZXR1cm4gVGhpcy0+RmxhZ3MgJiBTRkxBR19MT1NUID8gV0lORUQzREVSUl9ERVZJQ0VMT1NUIDogV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfUmVzdG9yZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgLyogU28gZmFyIHdlIGRvbid0IGxvc2UgYW55dGhpbmcgOikgKi8KICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19MT1NUOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldFBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RQYWxldHRlICpQYWwpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKlBhbEltcGwgPSAoSVdpbmVEM0RQYWxldHRlSW1wbCAqKSBQYWw7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICBpZihUaGlzLT5wYWxldHRlICE9IE5VTEwpCiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKQogICAgICAgICAgICBUaGlzLT5wYWxldHRlLT5GbGFncyAmPSB+V0lORUREUENBUFNfUFJJTUFSWVNVUkZBQ0U7CgogICAgaWYoUGFsSW1wbCAhPSBOVUxMKSB7CiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB7CiAgICAgICAgICAgIC8qIFNldCB0aGUgZGV2aWNlJ3MgbWFpbiBwYWxldHRlIGlmIHRoZSBwYWxldHRlCiAgICAgICAgICAgICogd2Fzbid0IGEgcHJpbWFyeSBwYWxldHRlIGJlZm9yZQogICAgICAgICAgICAqLwogICAgICAgICAgICBpZighKFBhbEltcGwtPkZsYWdzICYgV0lORUREUENBUFNfUFJJTUFSWVNVUkZBQ0UpKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICAgICAgICAgICAgICBmb3IoaT0wOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldID0gUGFsSW1wbC0+cGFsZW50c1tpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgKFBhbEltcGwpLT5GbGFncyB8PSBXSU5FRERQQ0FQU19QUklNQVJZU1VSRkFDRTsKICAgICAgICB9CiAgICB9CiAgICBUaGlzLT5wYWxldHRlID0gUGFsSW1wbDsKCiAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX1JlYWxpemVQYWxldHRlKGlmYWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0Q29sb3JLZXkoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgRmxhZ3MsIFdJTkVERENPTE9SS0VZICpDS2V5KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApXG4iLCBUaGlzLCBGbGFncywgQ0tleSk7CgogICAgaWYgKChGbGFncyAmIFdJTkVERENLRVlfQ09MT1JTUEFDRSkgIT0gMCkgewogICAgICAgIEZJWE1FKCIgY29sb3JrZXkgdmFsdWUgbm90IHN1cHBvcnRlZCAoJTA4eCkgIVxuIiwgRmxhZ3MpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIERpcnRpZnkgdGhlIHN1cmZhY2UsIGJ1dCBvbmx5IGlmIGEga2V5IHdhcyBjaGFuZ2VkICovCiAgICBpZihDS2V5KSB7CiAgICAgICAgc3dpdGNoIChGbGFncyAmIH5XSU5FRERDS0VZX0NPTE9SU1BBQ0UpIHsKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX0RFU1RCTFQ6CiAgICAgICAgICAgICAgICBUaGlzLT5EZXN0Qmx0Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IFdJTkVERFNEX0NLREVTVEJMVDsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+RGVzdE92ZXJsYXlDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gV0lORUREU0RfQ0tERVNUT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX1NSQ09WRVJMQVk6CiAgICAgICAgICAgICAgICBUaGlzLT5TcmNPdmVybGF5Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IFdJTkVERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX1NSQ0JMVDoKICAgICAgICAgICAgICAgIFRoaXMtPlNyY0JsdENLZXkgPSAqQ0tleTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyB8PSBXSU5FRERTRF9DS1NSQ0JMVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+V0lORUREQ0tFWV9DT0xPUlNQQUNFKSB7CiAgICAgICAgICAgIGNhc2UgV0lORUREQ0tFWV9ERVNUQkxUOgogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5XSU5FRERTRF9DS0RFU1RCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgV0lORUREQ0tFWV9ERVNUT1ZFUkxBWToKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyAmPSB+V0lORUREU0RfQ0tERVNUT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX1NSQ09WRVJMQVk6CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfldJTkVERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX1NSQ0JMVDoKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyAmPSB+V0lORUREU0RfQ0tTUkNCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RQYWxldHRlICoqUGFsKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICAqUGFsID0gKElXaW5lRDNEUGFsZXR0ZSAqKSBUaGlzLT5wYWxldHRlOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1JlYWxpemVQYWxldHRlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFJHQlFVQUQgY29sWzI1Nl07CiAgICBJV2luZUQzRFBhbGV0dGVJbXBsICpwYWwgPSBUaGlzLT5wYWxldHRlOwogICAgdW5zaWduZWQgaW50IG47CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwKICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UDgpCiAgICB7CiAgICAgICAgaWYoIVRoaXMtPkZsYWdzICYgU0ZMQUdfSU5TWVNNRU0pIHsKICAgICAgICAgICAgRklYTUUoIlBhbGV0dGUgY2hhbmdlZCB3aXRoIHN1cmZhY2UgdGhhdCBkb2VzIG5vdCBoYXZlIGFuIHVwIHRvIGRhdGUgc3lzdGVtIG1lbW9yeSBjb3B5XG4iKTsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkRpcnRpZnlpbmcgc3VyZmFjZVxuIik7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKGlmYWNlLCBTRkxBR19JTlNZU01FTSwgVFJVRSk7CiAgICB9CgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgVFJBQ0UoIiglcCk6IFVwZGF0aW5nIHRoZSBoZGMncyBwYWxldHRlXG4iLCBUaGlzKTsKICAgICAgICBmb3IgKG49MDsgbjwyNTY7IG4rKykgewogICAgICAgICAgICBpZihwYWwpIHsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IHBhbC0+cGFsZW50c1tuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IHBhbC0+cGFsZW50c1tuXS5wZUdyZWVuOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkJsdWUgID0gcGFsLT5wYWxlbnRzW25dLnBlQmx1ZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgICAgICAgICAgICAgIC8qIFVzZSB0aGUgZGVmYXVsdCBkZXZpY2UgcGFsZXR0ZSAqLwogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlZCAgID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVCbHVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgfQogICAgICAgIFNldERJQkNvbG9yVGFibGUoVGhpcy0+aERDLCAwLCAyNTYsIGNvbCk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkRXT1JEIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQaXRjaChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBEV09SRCByZXQ7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgLyogRFhUbiBmb3JtYXRzIGRvbid0IGhhdmUgZXhhY3QgcGl0Y2hlcyBhcyB0aGV5IGFyZSB0byB0aGUgbmV3IHJvdyBvZiBibG9ja3MsCiAgICB3aGVyZSBlYWNoIGJsb2NrIGlzIDR4NCBwaXhlbHMsIDggYnl0ZXMgKGR4dDEpIGFuZCAxNiBieXRlcyAoZHh0Mi8zLzQvNSkKICAgIGllIHBpdGNoID0gKHdpZHRoLzQpICogYnl0ZXMgcGVyIGJsb2NrICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgLyogRFhUMSBpcyA4IGJ5dGVzIHBlciBibG9jayAqLwogICAgICAgIHJldCA9ICgoVGhpcy0+Y3VycmVudERlc2MuV2lkdGggKyAzKSA+PiAyKSA8PCAzOwogICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIC8qIERYVDIvMy80LzUgaXMgMTYgYnl0ZXMgcGVyIGJsb2NrICovCiAgICAgICAgcmV0ID0gKChUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCArIDMpID4+IDIpIDw8IDQ7CiAgICBlbHNlIHsKICAgICAgICB1bnNpZ25lZCBjaGFyIGFsaWdubWVudCA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPnN1cmZhY2VfYWxpZ25tZW50OwogICAgICAgIHJldCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsgIC8qIEJ5dGVzIC8gcm93ICovCiAgICAgICAgcmV0ID0gKHJldCArIGFsaWdubWVudCAtIDEpICYgfihhbGlnbm1lbnQgLSAxKTsKICAgIH0KICAgIFRSQUNFKCIoJXApIFJldHVybmluZyAlZFxuIiwgVGhpcywgcmV0KTsKICAgIHJldHVybiByZXQ7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBMT05HIFgsIExPTkcgWSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwoKICAgIEZJWE1FKCIoJXApLT4oJWQsJWQpIFN0dWIhXG4iLCBUaGlzLCBYLCBZKTsKCiAgICBpZighKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX09WRVJMQVkpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApOiBOb3QgYW4gb3ZlcmxheSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX05PVEFPVkVSTEFZU1VSRkFDRTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0T3ZlcmxheVBvc2l0aW9uKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIExPTkcgKlgsIExPTkcgKlkpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKCiAgICBGSVhNRSgiKCVwKS0+KCVwLCVwKSBTdHViIVxuIiwgVGhpcywgWCwgWSk7CgogICAgaWYoIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9PVkVSTEFZKSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKTogTm90IGFuIG92ZXJsYXkgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0U7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXlaT3JkZXIoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgRmxhZ3MsIElXaW5lRDNEU3VyZmFjZSAqUmVmKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpSZWZJbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgUmVmOwoKICAgIEZJWE1FKCIoJXApLT4oJTA4eCwlcCkgU3R1YiFcbiIsIFRoaXMsIEZsYWdzLCBSZWZJbXBsKTsKCiAgICBpZighKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX09WRVJMQVkpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApOiBOb3QgYW4gb3ZlcmxheSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX05PVEFPVkVSTEFZU1VSRkFDRTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUNUICpTcmNSZWN0LCBJV2luZUQzRFN1cmZhY2UgKkRzdFN1cmZhY2UsIFJFQ1QgKkRzdFJlY3QsIERXT1JEIEZsYWdzLCBXSU5FRERPVkVSTEFZRlggKkZYKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpEc3QgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBEc3RTdXJmYWNlOwogICAgRklYTUUoIiglcCktPiglcCwgJXAsICVwLCAlMDh4LCAlcClcbiIsIFRoaXMsIFNyY1JlY3QsIERzdCwgRHN0UmVjdCwgRmxhZ3MsIEZYKTsKCiAgICBpZighKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX09WRVJMQVkpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApOiBOb3QgYW4gb3ZlcmxheSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX05PVEFPVkVSTEFZU1VSRkFDRTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0Q2xpcHBlcihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRENsaXBwZXIgKmNsaXBwZXIpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBjbGlwcGVyKTsKCiAgICBUaGlzLT5jbGlwcGVyID0gY2xpcHBlcjsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRDbGlwcGVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEQ2xpcHBlciAqKmNsaXBwZXIpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBjbGlwcGVyKTsKCiAgICAqY2xpcHBlciA9IFRoaXMtPmNsaXBwZXI7CiAgICBpZigqY2xpcHBlcikgewogICAgICAgIElXaW5lRDNEQ2xpcHBlcl9BZGRSZWYoKmNsaXBwZXIpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldENvbnRhaW5lcihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzREJhc2UgKmNvbnRhaW5lcikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIlRoaXMgJXAsIGNvbnRhaW5lciAlcFxuIiwgVGhpcywgY29udGFpbmVyKTsKCiAgICAvKiBXZSBjYW4ndCBrZWVwIGEgcmVmZXJlbmNlIHRvIHRoZSBjb250YWluZXIsIHNpbmNlIHRoZSBjb250YWluZXIgYWxyZWFkeSBrZWVwcyBhIHJlZmVyZW5jZSB0byB1cy4gKi8KCiAgICBUUkFDRSgiU2V0dGluZyBjb250YWluZXIgdG8gJXAgZnJvbSAlcFxuIiwgY29udGFpbmVyLCBUaGlzLT5jb250YWluZXIpOwogICAgVGhpcy0+Y29udGFpbmVyID0gY29udGFpbmVyOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRGb3JtYXQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzREZPUk1BVCBmb3JtYXQpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgY29uc3QgU3RhdGljUGl4ZWxGb3JtYXREZXNjICpmb3JtYXRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShmb3JtYXQsIE5VTEwsIE5VTEwpOwoKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgIT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBUaGUgZm9ybWF0IG9mIHRoZSBzdXJmYWNlIG11c3QgYmUgV0lORUQzREZPUk1BVF9VTktOT1dOXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IFNldHRpbmcgdGV4dHVyZSBmb3JtYXQgdG8gKCVkLCVzKVxuIiwgVGhpcywgZm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoZm9ybWF0KSk7CiAgICBpZiAoZm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSAwOwogICAgfSBlbHNlIGlmIChmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxKSB7CiAgICAgICAgLyogRFhUMSBpcyBoYWxmIGJ5dGUgcGVyIHBpeGVsICovCiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9ICgobWF4KFRoaXMtPnBvdzJXaWR0aCwgNCkgKiBmb3JtYXRFbnRyeS0+YnBwKSAqIG1heChUaGlzLT5wb3cySGVpZ2h0LCA0KSkgPj4gMTsKCiAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICAgICBmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gKChtYXgoVGhpcy0+cG93MldpZHRoLCA0KSAqIGZvcm1hdEVudHJ5LT5icHApICogbWF4KFRoaXMtPnBvdzJIZWlnaHQsIDQpKTsKICAgIH0gZWxzZSB7CiAgICAgICAgdW5zaWduZWQgY2hhciBhbGlnbm1lbnQgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5zdXJmYWNlX2FsaWdubWVudDsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gKChUaGlzLT5wb3cyV2lkdGggKiBmb3JtYXRFbnRyeS0+YnBwKSArIGFsaWdubWVudCAtIDEpICYgfihhbGlnbm1lbnQgLSAxKTsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplICo9IFRoaXMtPnBvdzJIZWlnaHQ7CiAgICB9CgogICAgaWYgKGZvcm1hdCAhPSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBUaGlzLT5ieXRlc1BlclBpeGVsID0gZm9ybWF0RW50cnktPmJwcDsKICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+Ynl0ZXNQZXJQaXhlbCA9IDA7CiAgICB9CgogICAgVGhpcy0+RmxhZ3MgfD0gKFdJTkVEM0RGTVRfRDE2X0xPQ0tBQkxFID09IGZvcm1hdCkgPyBTRkxBR19MT0NLQUJMRSA6IDA7CgogICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID0gZm9ybWF0OwoKICAgIFRSQUNFKCIoJXApIDogU2l6ZSAlZCwgYnl0ZXNQZXJQaXhlbCAlZFxuIiwgVGhpcywgVGhpcy0+cmVzb3VyY2Uuc2l6ZSwgVGhpcy0+Ynl0ZXNQZXJQaXhlbCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfQ3JlYXRlRElCU2VjdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIGludCBleHRyYWxpbmUgPSAwOwogICAgU1lTVEVNX0lORk8gc3lzSW5mbzsKICAgIEJJVE1BUElORk8qIGJfaW5mbzsKICAgIEhEQyBkZGM7CiAgICBEV09SRCAqbWFza3M7CiAgICBjb25zdCBTdGF0aWNQaXhlbEZvcm1hdERlc2MgKmZvcm1hdEVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFRoaXMtPnJlc291cmNlLmZvcm1hdCwgTlVMTCwgTlVMTCk7CiAgICBVSU5UIHVzYWdlOwoKICAgIHN3aXRjaCAoVGhpcy0+Ynl0ZXNQZXJQaXhlbCkgewogICAgICAgIGNhc2UgMjoKICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgIC8qIEFsbG9jYXRlIGV4dHJhIHNwYWNlIHRvIHN0b3JlIHRoZSBSR0IgYml0IG1hc2tzLiAqLwogICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpICsgMyAqIHNpemVvZihEV09SRCkpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAzOgogICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIC8qIEFsbG9jYXRlIGV4dHJhIHNwYWNlIGZvciBhIHBhbGV0dGUuICovCiAgICAgICAgICAgIGJfaW5mbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKEJJVE1BUElORk9IRUFERVIpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHNpemVvZihSR0JRVUFEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAoMSA8PCAoVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIDgpKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmICghYl9pbmZvKQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgICAgICAvKiBTb21lIGFwcHMgYWNjZXNzIHRoZSBzdXJmYWNlIGluIHZpYSBEV09SRHMsIGFuZCBkbyBub3QgdGFrZSB0aGUgbmVjZXNzYXJ5IGNhcmUgYXQgdGhlIGVuZCBvZiB0aGUKICAgICogc3VyZmFjZS4gU28gd2UgbmVlZCBhdCBsZWFzdCBleHRyYSA0IGJ5dGVzIGF0IHRoZSBlbmQgb2YgdGhlIHN1cmZhY2UuIENoZWNrIGFnYWluc3QgdGhlIHBhZ2Ugc2l6ZSwKICAgICogaWYgdGhlIGxhc3QgcGFnZSB1c2VkIGZvciB0aGUgc3VyZmFjZSBoYXMgYXQgbGVhc3QgNCBzcGFyZSBieXRlcyB3ZSdyZSBzYWZlLCBvdGhlcndpc2UKICAgICogYWRkIGFuIGV4dHJhIGxpbmUgdG8gdGhlIGRpYiBzZWN0aW9uCiAgICAgICAgKi8KICAgIEdldFN5c3RlbUluZm8oJnN5c0luZm8pOwogICAgaWYoICgoVGhpcy0+cmVzb3VyY2Uuc2l6ZSArIDMpICUgc3lzSW5mby5kd1BhZ2VTaXplKSA8IDQpIHsKICAgICAgICBleHRyYWxpbmUgPSAxOwogICAgICAgIFRSQUNFKCJBZGRpbmcgYW4gZXh0cmEgbGluZSB0byB0aGUgZGliIHNlY3Rpb25cbiIpOwogICAgfQoKICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZSA9IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKTsKICAgIC8qIFRPRE86IElzIHRoZXJlIGEgbmljZXIgd2F5IHRvIGZvcmNlIGEgc3BlY2lmaWMgYWxpZ25tZW50PyAoOCBieXRlIGZvciBkZHJhdykgKi8KICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpV2lkdGggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpIC8gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpSGVpZ2h0ID0gLVRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCAtZXh0cmFsaW5lOwogICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlTaXplSW1hZ2UgPSAoIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCArIGV4dHJhbGluZSkgKiBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpOwogICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlQbGFuZXMgPSAxOwogICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlCaXRDb3VudCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiA4OwoKICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpWFBlbHNQZXJNZXRlciA9IDA7CiAgICBiX2luZm8tPmJtaUhlYWRlci5iaVlQZWxzUGVyTWV0ZXIgPSAwOwogICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDbHJVc2VkID0gMDsKICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ2xySW1wb3J0YW50ID0gMDsKCiAgICAvKiBHZXQgdGhlIGJpdCBtYXNrcyAqLwogICAgbWFza3MgPSAoRFdPUkQgKikgJihiX2luZm8tPmJtaUNvbG9ycyk7CiAgICBzd2l0Y2ggKFRoaXMtPnJlc291cmNlLmZvcm1hdCkgewogICAgICAgIGNhc2UgV0lORUQzREZNVF9SOEc4Qjg6CiAgICAgICAgICAgIHVzYWdlID0gRElCX1JHQl9DT0xPUlM7CiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9SR0I7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDFSNUc1QjU6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0ExUjVHNUI1OgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BNFI0RzRCNDoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDRSNEc0QjQ6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1IzRzNCMjoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThSM0czQjI6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0EyQjEwRzEwUjEwOgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BOEI4RzhSODoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhCOEc4Ujg6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0EyUjEwRzEwQjEwOgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SNUc2QjU6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0ExNkIxNkcxNlIxNjoKICAgICAgICAgICAgdXNhZ2UgPSAwOwogICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUNvbXByZXNzaW9uID0gQklfQklURklFTERTOwogICAgICAgICAgICBtYXNrc1swXSA9IGZvcm1hdEVudHJ5LT5yZWRNYXNrOwogICAgICAgICAgICBtYXNrc1sxXSA9IGZvcm1hdEVudHJ5LT5ncmVlbk1hc2s7CiAgICAgICAgICAgIG1hc2tzWzJdID0gZm9ybWF0RW50cnktPmJsdWVNYXNrOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgLyogRG9uJ3Qga25vdyBwYWxldHRlICovCiAgICAgICAgICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ29tcHJlc3Npb24gPSBCSV9SR0I7CiAgICAgICAgICAgIHVzYWdlID0gMDsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgZGRjID0gR2V0REMoMCk7CiAgICBpZiAoZGRjID09IDApIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwogICAgICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoR2V0TGFzdEVycm9yKCkpOwogICAgfQoKICAgIFRSQUNFKCJDcmVhdGluZyBhIERJQiBzZWN0aW9uIHdpdGggc2l6ZSAlZHglZHglZCwgc2l6ZT0lZFxuIiwgYl9pbmZvLT5ibWlIZWFkZXIuYmlXaWR0aCwgYl9pbmZvLT5ibWlIZWFkZXIuYmlIZWlnaHQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQsIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgIFRoaXMtPmRpYi5ESUJzZWN0aW9uID0gQ3JlYXRlRElCU2VjdGlvbihkZGMsIGJfaW5mbywgdXNhZ2UsICZUaGlzLT5kaWIuYml0bWFwX2RhdGEsIDAgLyogSGFuZGxlICovLCAwIC8qIE9mZnNldCAqLyk7CiAgICBSZWxlYXNlREMoMCwgZGRjKTsKCiAgICBpZiAoIVRoaXMtPmRpYi5ESUJzZWN0aW9uKSB7CiAgICAgICAgRVJSKCJDcmVhdGVESUJTZWN0aW9uIGZhaWxlZCFcbiIpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGJfaW5mbyk7CiAgICAgICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICB9CgogICAgVFJBQ0UoIkRJQlNlY3Rpb24gYXQgOiAlcFxuIiwgVGhpcy0+ZGliLmJpdG1hcF9kYXRhKTsKICAgIC8qIGNvcHkgdGhlIGV4aXN0aW5nIHN1cmZhY2UgdG8gdGhlIGRpYiBzZWN0aW9uICovCiAgICBpZihUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKICAgICAgICBtZW1jcHkoVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogVGhpcyBpcyB0byBtYWtlIExvY2tSZWN0IHJlYWQgdGhlIGdsIFRleHR1cmUgYWx0aG91Z2ggbWVtb3J5IGlzIGFsbG9jYXRlZCAqLwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19JTlNZU01FTTsKICAgIH0KICAgIFRoaXMtPmRpYi5iaXRtYXBfc2l6ZSA9IGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGJfaW5mbyk7CgogICAgLyogTm93IGFsbG9jYXRlIGEgSERDICovCiAgICBUaGlzLT5oREMgPSBDcmVhdGVDb21wYXRpYmxlREMoMCk7CiAgICBUaGlzLT5kaWIuaG9sZGJpdG1hcCA9IFNlbGVjdE9iamVjdChUaGlzLT5oREMsIFRoaXMtPmRpYi5ESUJzZWN0aW9uKTsKICAgIFRSQUNFKCJ1c2luZyB3aW5lZDNkIHBhbGV0dGUgJXBcbiIsIFRoaXMtPnBhbGV0dGUpOwogICAgU2VsZWN0UGFsZXR0ZShUaGlzLT5oREMsCiAgICAgICAgICAgICAgICAgIFRoaXMtPnBhbGV0dGUgPyBUaGlzLT5wYWxldHRlLT5ocGFsIDogMCwKICAgICAgICAgICAgICAgICAgRkFMU0UpOwoKICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0RJQlNFQ1RJT047CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSk7CiAgICBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5ID0gTlVMTDsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIF9CbHRfQ29sb3JGaWxsCiAqCiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IGZpbGxzIGEgbWVtb3J5IGFyZWEgd2l0aCBhIHNwZWNpZmljIGNvbG9yCiAqCiAqIFBhcmFtczoKICogIGJ1ZjogbWVtb3J5IGFkZHJlc3MgdG8gc3RhcnQgZmlsbGluZyBhdAogKiAgd2lkdGgsIGhlaWdodDogRGltZW5zaW9ucyBvZiB0aGUgYXJlYSB0byBmaWxsCiAqICBicHA6IEJpdCBkZXB0aCBvZiB0aGUgc3VyZmFjZQogKiAgbFBpdGNoOiBwaXRjaCBvZiB0aGUgc3VyZmFjZQogKiAgY29sb3I6IENvbG9yIHRvIGZpbGwgd2l0aAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCiAgICAgICAgX0JsdF9Db2xvckZpbGwoQllURSAqYnVmLAogICAgICAgICAgICAgICAgICAgICAgIGludCB3aWR0aCwgaW50IGhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICBpbnQgYnBwLCBMT05HIGxQaXRjaCwKICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBjb2xvcikKewogICAgaW50IHgsIHk7CiAgICBMUEJZVEUgZmlyc3Q7CgogICAgLyogRG8gZmlyc3Qgcm93ICovCgojZGVmaW5lIENPTE9SRklMTF9ST1codHlwZSkgXAogICAgeyBcCiAgICB0eXBlICpkID0gKHR5cGUgKikgYnVmOyBcCiAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgXAogICAgZFt4XSA9ICh0eXBlKSBjb2xvcjsgXAogICAgYnJlYWs7IFwKfQogICAgc3dpdGNoKGJwcCkKICAgIHsKICAgICAgICBjYXNlIDE6IENPTE9SRklMTF9ST1coQllURSkKICAgICAgICAgICAgICAgIGNhc2UgMjogQ09MT1JGSUxMX1JPVyhXT1JEKQogICAgICAgIGNhc2UgMzoKICAgICAgICB7CiAgICAgICAgICAgIEJZVEUgKmQgPSAoQllURSAqKSBidWY7CiAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrLGQrPTMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRbMF0gPSAoY29sb3IgICAgKSAmIDB4RkY7CiAgICAgICAgICAgICAgICBkWzFdID0gKGNvbG9yPj4gOCkgJiAweEZGOwogICAgICAgICAgICAgICAgZFsyXSA9IChjb2xvcj4+MTYpICYgMHhGRjsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSA0OiBDT0xPUkZJTExfUk9XKERXT1JEKQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCJDb2xvciBmaWxsIG5vdCBpbXBsZW1lbnRlZCBmb3IgYnBwICVkIVxuIiwgYnBwKjgpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICB9CgojdW5kZWYgQ09MT1JGSUxMX1JPVwoKICAgIC8qIE5vdyBjb3B5IGZpcnN0IHJvdyAqLwogICAgZmlyc3QgPSBidWY7CiAgICBmb3IgKHkgPSAxOyB5IDwgaGVpZ2h0OyB5KyspCiAgICB7CiAgICAgICAgYnVmICs9IGxQaXRjaDsKICAgICAgICBtZW1jcHkoYnVmLCBmaXJzdCwgd2lkdGggKiBicHApOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OkJsdCwgU1cgZW11bGF0aW9uIHZlcnNpb24KICoKICogUGVyZm9ybXMgYmxpdHMgdG8gYSBzdXJmYWNlLCBlaWdoZXIgZnJvbSBhIHNvdXJjZSBvZiBzb3VyY2UtbGVzcyBibHRzCiAqIFRoaXMgaXMgdGhlIG1haW4gZnVuY3Rpb25hbGl0eSBvZiBEaXJlY3REcmF3CiAqCiAqIFBhcmFtczoKICogIERlc3RSZWN0OiBEZXN0aW5hdGlvbiByZWN0YW5nbGUgdG8gd3JpdGUgdG8KICogIFNyY1N1cmZhY2U6IFNvdXJjZSBzdXJmYWNlLCBjYW4gYmUgTlVMTAogKiAgU3JjUmVjdDogU291cmNlIHJlY3RhbmdsZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCklXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0JsdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqRGVzdFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpTcmNSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRERCTFRGWCAqRERCbHRGeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSBGaWx0ZXIpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CiAgICBSRUNUICAgICAgICB4ZHN0LHhzcmM7CiAgICBIUkVTVUxUICAgICByZXQgPSBXSU5FRDNEX09LOwogICAgV0lORUQzRExPQ0tFRF9SRUNUICBkbG9jaywgc2xvY2s7CiAgICBXSU5FRDNERk9STUFUICAgICAgIGRmbXQgPSBXSU5FRDNERk1UX1VOS05PV04sIHNmbXQgPSBXSU5FRDNERk1UX1VOS05PV047CiAgICBpbnQgYnBwLCBzcmNoZWlnaHQsIHNyY3dpZHRoLCBkc3RoZWlnaHQsIGRzdHdpZHRoLCB3aWR0aDsKICAgIGludCB4LCB5OwogICAgY29uc3QgU3RhdGljUGl4ZWxGb3JtYXREZXNjICpzRW50cnksICpkRW50cnk7CiAgICBMUEJZVEUgZGJ1Ziwgc2J1ZjsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXAsJXgsJXApXG4iLCBUaGlzLCBEZXN0UmVjdCwgU3JjLCBTcmNSZWN0LCBGbGFncywgRERCbHRGeCk7CgogICAgaWYgKFRSQUNFX09OKGQzZF9zdXJmYWNlKSkKICAgIHsKICAgICAgICBpZiAoRGVzdFJlY3QpIFRSQUNFKCJcdGRlc3RyZWN0IDolZHglZC0lZHglZFxuIiwKICAgICAgICAgICAgRGVzdFJlY3QtPmxlZnQsIERlc3RSZWN0LT50b3AsIERlc3RSZWN0LT5yaWdodCwgRGVzdFJlY3QtPmJvdHRvbSk7CiAgICAgICAgaWYgKFNyY1JlY3QpIFRSQUNFKCJcdHNyY3JlY3QgIDolZHglZC0lZHglZFxuIiwKICAgICAgICAgICAgU3JjUmVjdC0+bGVmdCwgU3JjUmVjdC0+dG9wLCBTcmNSZWN0LT5yaWdodCwgU3JjUmVjdC0+Ym90dG9tKTsKI2lmIDAKICAgICAgICBUUkFDRSgiXHRmbGFnczogIik7CiAgICAgICAgICAgICAgICAgICAgICBERFJBV19kdW1wX0REQkxUKEZsYWdzKTsKICAgICAgICAgICAgICAgICAgICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9EREZYKQogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdGJsaXRmeDogIik7CiAgICAgICAgICAgICAgICAgICAgICBERFJBV19kdW1wX0REQkxURlgoRERCbHRGeC0+ZHdEREZYKTsKICAgIH0KI2VuZGlmCiAgICB9CgogICAgaWYgKCAoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpIHx8ICgoU3JjICE9IE5VTEwpICYmIChTcmMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSkpCiAgICB7CiAgICAgICAgV0FSTigiIFN1cmZhY2UgaXMgYnVzeSwgcmV0dXJuaW5nIERERVJSX1NVUkZBQ0VCVVNZXG4iKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX1NVUkZBQ0VCVVNZOwogICAgfQoKICAgIGlmKEZpbHRlciAhPSBXSU5FRDNEVEVYRl9OT05FICYmIEZpbHRlciAhPSBXSU5FRDNEVEVYRl9QT0lOVCkgewogICAgICAgIC8qIENhbiBoYXBwZW4gd2hlbiBkM2Q5IGFwcHMgZG8gYSBTdHJldGNoUmVjdCBjYWxsIHdoaWNoIGlzbid0IGhhbmRsZWQgaW4gZ2wgKi8KICAgICAgICBGSVhNRSgiRmlsdGVycyBub3Qgc3VwcG9ydGVkIGluIHNvZnR3YXJlIGJsaXRcbiIpOwogICAgfQoKICAgIGlmIChTcmMgPT0gVGhpcykKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsICZkbG9jaywgTlVMTCwgMCk7CiAgICAgICAgZGZtdCA9IFRoaXMtPnJlc291cmNlLmZvcm1hdDsKICAgICAgICBzbG9jayA9IGRsb2NrOwogICAgICAgIHNmbXQgPSBkZm10OwogICAgICAgIHNFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShzZm10LCBOVUxMLCBOVUxMKTsKICAgICAgICBkRW50cnkgPSBzRW50cnk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKFNyYykKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChTcmNTdXJmYWNlLCAmc2xvY2ssIE5VTEwsIFdJTkVEM0RMT0NLX1JFQURPTkxZKTsKICAgICAgICAgICAgc2ZtdCA9IFNyYy0+cmVzb3VyY2UuZm9ybWF0OwogICAgICAgIH0KICAgICAgICBzRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoc2ZtdCwgTlVMTCwgTlVMTCk7CiAgICAgICAgZGZtdCA9IFRoaXMtPnJlc291cmNlLmZvcm1hdDsKICAgICAgICBkRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoZGZtdCwgTlVMTCwgTlVMTCk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLCAmZGxvY2ssTlVMTCwwKTsKICAgIH0KCiAgICBpZiAoIUREQmx0RnggfHwgIShEREJsdEZ4LT5kd0RERlgpKSBGbGFncyAmPSB+V0lORUREQkxUX0RERlg7CgogICAgaWYgKHNFbnRyeS0+aXNGb3VyY2MgJiYgZEVudHJ5LT5pc0ZvdXJjYykKICAgIHsKICAgICAgICBpZiAoc2ZtdCAhPSBkZm10KQogICAgICAgIHsKICAgICAgICAgICAgRklYTUUoIkZPVVJDQy0+Rk9VUkNDIGNvcHkgb25seSBzdXBwb3J0ZWQgZm9yIHRoZSBzYW1lIHR5cGUgb2Ygc3VyZmFjZVxuIik7CiAgICAgICAgICAgIHJldCA9IFdJTkVEM0RFUlJfV1JPTkdURVhUVVJFRk9STUFUOwogICAgICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICAgICAgfQogICAgICAgIG1lbWNweShkbG9jay5wQml0cywgc2xvY2sucEJpdHMsIFRoaXMtPnJlc291cmNlLnNpemUpOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KCiAgICBpZiAoc0VudHJ5LT5pc0ZvdXJjYyAmJiAhZEVudHJ5LT5pc0ZvdXJjYykKICAgIHsKICAgICAgICBGSVhNRSgiRFhUQyBkZWNvbXByZXNzaW9uIG5vdCBzdXBwb3J0ZWQgcmlnaHQgbm93XG4iKTsKICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICB9CgogICAgaWYgKERlc3RSZWN0KQogICAgewogICAgICAgIG1lbWNweSgmeGRzdCxEZXN0UmVjdCxzaXplb2YoeGRzdCkpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHhkc3QudG9wICAgID0gMDsKICAgICAgICB4ZHN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICB4ZHN0LmxlZnQgICA9IDA7CiAgICAgICAgeGRzdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIH0KCiAgICBpZiAoU3JjUmVjdCkKICAgIHsKICAgICAgICBtZW1jcHkoJnhzcmMsU3JjUmVjdCxzaXplb2YoeHNyYykpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChTcmMpCiAgICAgICAgewogICAgICAgICAgICB4c3JjLnRvcCAgICA9IDA7CiAgICAgICAgICAgIHhzcmMuYm90dG9tID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgICAgIHhzcmMubGVmdCAgID0gMDsKICAgICAgICAgICAgeHNyYy5yaWdodCAgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBtZW1zZXQoJnhzcmMsMCxzaXplb2YoeHNyYykpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBGaXJzdCBjaGVjayBmb3IgdGhlIHZhbGlkaXR5IG9mIHNvdXJjZSAvIGRlc3RpbmF0aW9uIHJlY3RhbmdsZXMuIFRoaXMgd2FzCiAgICAgKiB2ZXJpZmllZCB1c2luZyBhIHRlc3QgYXBwbGljYXRpb24gKyBieSBNU0ROLgogICAgICovCiAgICBpZiAoKFNyYyAhPSBOVUxMKSAmJgogICAgICAgICAoKHhzcmMuYm90dG9tID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4c3JjLmJvdHRvbSA8IDApIHx8CiAgICAgICAgICh4c3JjLnRvcCAgICAgPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHhzcmMudG9wICAgIDwgMCkgfHwKICAgICAgICAgKHhzcmMubGVmdCAgICA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAoeHNyYy5sZWZ0ICAgPCAwKSB8fAogICAgICAgICAoeHNyYy5yaWdodCAgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8ICh4c3JjLnJpZ2h0ICA8IDApIHx8CiAgICAgICAgICh4c3JjLnJpZ2h0ICAgPCB4c3JjLmxlZnQpICAgICAgICAgICAgICAgfHwgKHhzcmMuYm90dG9tIDwgeHNyYy50b3ApKSkKICAgIHsKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiBnYXZlIHVzIGJhZCBzb3VyY2UgcmVjdGFuZ2xlIGZvciBCbHQuXG4iKTsKICAgICAgICByZXQgPSBXSU5FRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQogICAgLyogRm9yIHRoZSBEZXN0aW5hdGlvbiByZWN0LCBpdCBjYW4gYmUgb3V0IG9mIGJvdW5kcyBvbiB0aGUgY29uZGl0aW9uIHRoYXQgYSBjbGlwcGVyCiAgICAgKiBpcyBzZXQgZm9yIHRoZSBnaXZlbiBzdXJmYWNlLgogICAgICovCiAgICBpZiAoKC8qVGhpcy0+Y2xpcHBlciA9PSBOVUxMKi8gVFJVRSkgJiYKICAgICAgICAgKCh4ZHN0LmJvdHRvbSAgPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4ZHN0LmJvdHRvbSA8IDApIHx8CiAgICAgICAgICh4ZHN0LnRvcCAgICAgID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAoeGRzdC50b3AgICAgPCAwKSB8fAogICAgICAgICAoeGRzdC5sZWZ0ICAgICA+IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHhkc3QubGVmdCAgIDwgMCkgfHwKICAgICAgICAgKHhkc3QucmlnaHQgICAgPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8ICh4ZHN0LnJpZ2h0ICA8IDApIHx8CiAgICAgICAgICh4ZHN0LnJpZ2h0ICAgIDwgeGRzdC5sZWZ0KSAgICAgICAgICAgICAgICB8fCAoeGRzdC5ib3R0b20gPCB4ZHN0LnRvcCkpKQogICAgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIGdhdmUgdXMgYmFkIGRlc3RpbmF0aW9uIHJlY3RhbmdsZSBmb3IgQmx0IHdpdGhvdXQgYSBjbGlwcGVyIHNldC5cbiIpOwogICAgICAgIHJldCA9IFdJTkVEREVSUl9JTlZBTElEUkVDVDsKICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICB9CgogICAgLyogTm93IGhhbmRsZSBuZWdhdGl2ZSB2YWx1ZXMgaW4gdGhlIHJlY3RhbmdsZXMuIFdhcm5pbmc6IG9ubHkgc3VwcG9ydGVkIGZvciBub3cKICAgIGluIHRoZSAnc2ltcGxlJyBjYXNlcyAoaWUgbm90IGluIGFueSBzdHJldGNoaW5nIC8gcm90YXRpb24gY2FzZXMpLgoKICAgIEZpcnN0LCB0aGUgY2FzZSB3aGVyZSBub3RoaW5nIGlzIHRvIGJlIGRvbmUuCiAgICAqLwogICAgaWYgKCgoeGRzdC5ib3R0b20gPD0gMCkgfHwgKHhkc3QucmlnaHQgPD0gMCkgICAgICAgICB8fAogICAgICAgICAgKHhkc3QudG9wICAgID49IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwKICAgICAgICAgICh4ZHN0LmxlZnQgICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkpIHx8CiAgICAgICAgICAoKFNyYyAhPSBOVUxMKSAmJgogICAgICAgICAgKCh4c3JjLmJvdHRvbSA8PSAwKSB8fCAoeHNyYy5yaWdodCA8PSAwKSAgICAgfHwKICAgICAgICAgICh4c3JjLnRvcCA+PSAoaW50KSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwKICAgICAgICAgICh4c3JjLmxlZnQgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkpICApKQogICAgewogICAgICAgIFRSQUNFKCJOb3RoaW5nIHRvIGJlIGRvbmUgIVxuIik7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQoKICAgIC8qIFRoZSBlYXN5IGNhc2UgOiB0aGUgc291cmNlLWxlc3MgYmxpdHMuLi4uICovCiAgICBpZiAoU3JjID09IE5VTEwpCiAgICB7CiAgICAgICAgUkVDVCBmdWxsX3JlY3Q7CiAgICAgICAgUkVDVCB0ZW1wX3JlY3Q7IC8qIE5vIGlkZWEgaWYgaW50ZXJzZWN0IHJlY3QgY2FuIGJlIHRoZSBzYW1lIGFzIG9uZSBvZiB0aGUgc291cmNlIHJlY3QgKi8KCiAgICAgICAgZnVsbF9yZWN0LmxlZnQgICA9IDA7CiAgICAgICAgZnVsbF9yZWN0LnRvcCAgICA9IDA7CiAgICAgICAgZnVsbF9yZWN0LnJpZ2h0ICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIGZ1bGxfcmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgSW50ZXJzZWN0UmVjdCgmdGVtcF9yZWN0LCAmZnVsbF9yZWN0LCAmeGRzdCk7CiAgICAgICAgeGRzdCA9IHRlbXBfcmVjdDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBPbmx5IGhhbmRsZSBjbGlwcGluZyBvbiB0aGUgZGVzdGluYXRpb24gcmVjdGFuZ2xlICovCiAgICAgICAgaW50IGNsaXBfaG9yaXogPSAoeGRzdC5sZWZ0IDwgMCkgfHwgKHhkc3QucmlnaHQgID4gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGggKTsKICAgICAgICBpbnQgY2xpcF92ZXJ0ICA9ICh4ZHN0LnRvcCAgPCAwKSB8fCAoeGRzdC5ib3R0b20gPiAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpOwogICAgICAgIGlmIChjbGlwX3ZlcnQgfHwgY2xpcF9ob3JpeikKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vdyBjaGVjayBpZiB0aGlzIGlzIGEgc3BlY2lhbCBjYXNlIG9yIG5vdC4uLiAqLwogICAgICAgICAgICBpZiAoKCgoeGRzdC5ib3R0b20gLSB4ZHN0LnRvcCApICE9ICh4c3JjLmJvdHRvbSAtIHhzcmMudG9wICkpICYmIGNsaXBfdmVydCApIHx8CiAgICAgICAgICAgICAgICAgICAoKCh4ZHN0LnJpZ2h0ICAtIHhkc3QubGVmdCkgIT0gKHhzcmMucmlnaHQgIC0geHNyYy5sZWZ0KSkgJiYgY2xpcF9ob3JpeikgfHwKICAgICAgICAgICAgICAgICAgIChGbGFncyAmIFdJTkVEREJMVF9EREZYKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0FSTigiT3V0IG9mIHNjcmVlbiByZWN0YW5nbGUgaW4gc3BlY2lhbCBjYXNlLiBOb3QgaGFuZGxlZCByaWdodCBub3cuXG4iKTsKICAgICAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNsaXBfaG9yaXopCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh4ZHN0LmxlZnQgPCAwKSB7IHhzcmMubGVmdCAtPSB4ZHN0LmxlZnQ7IHhkc3QubGVmdCA9IDA7IH0KICAgICAgICAgICAgICAgIGlmICh4ZHN0LnJpZ2h0ID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeHNyYy5yaWdodCAtPSAoeGRzdC5yaWdodCAtIChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKTsKICAgICAgICAgICAgICAgICAgICB4ZHN0LnJpZ2h0ID0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNsaXBfdmVydCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhkc3QudG9wIDwgMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4c3JjLnRvcCAtPSB4ZHN0LnRvcDsKICAgICAgICAgICAgICAgICAgICB4ZHN0LnRvcCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoeGRzdC5ib3R0b20gPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeHNyYy5ib3R0b20gLT0gKHhkc3QuYm90dG9tIC0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICB4ZHN0LmJvdHRvbSA9IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBBbmQgY2hlY2sgaWYgYWZ0ZXIgY2xpcHBpbmcgc29tZXRoaW5nIGlzIHN0aWxsIHRvIGJlIGRvbmUuLi4gKi8KICAgICAgICAgICAgaWYgKCh4ZHN0LmJvdHRvbSA8PSAwKSAgIHx8ICh4ZHN0LnJpZ2h0IDw9IDApICAgICAgIHx8CiAgICAgICAgICAgICAgICAgKHhkc3QudG9wICAgPj0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSAgfHwKICAgICAgICAgICAgICAgICAoeGRzdC5sZWZ0ICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgICB8fAogICAgICAgICAgICAgICAgICh4c3JjLmJvdHRvbSA8PSAwKSAgIHx8ICh4c3JjLnJpZ2h0IDw9IDApICAgICAgIHx8CiAgICAgICAgICAgICAgICAgKHhzcmMudG9wID49IChpbnQpIFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSAgICAgfHwKICAgICAgICAgICAgICAgICAoeHNyYy5sZWZ0ID49IChpbnQpIFNyYy0+Y3VycmVudERlc2MuV2lkdGgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUUkFDRSgiTm90aGluZyB0byBiZSBkb25lIGFmdGVyIGNsaXBwaW5nICFcbiIpOwogICAgICAgICAgICAgICAgZ290byByZWxlYXNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICBzcmNoZWlnaHQgPSB4c3JjLmJvdHRvbSAtIHhzcmMudG9wOwogICAgc3Jjd2lkdGggPSB4c3JjLnJpZ2h0IC0geHNyYy5sZWZ0OwogICAgZHN0aGVpZ2h0ID0geGRzdC5ib3R0b20gLSB4ZHN0LnRvcDsKICAgIGRzdHdpZHRoID0geGRzdC5yaWdodCAtIHhkc3QubGVmdDsKICAgIHdpZHRoID0gKHhkc3QucmlnaHQgLSB4ZHN0LmxlZnQpICogYnBwOwoKICAgIGFzc2VydCh3aWR0aCA8PSBkbG9jay5QaXRjaCk7CgogICAgZGJ1ZiA9IChCWVRFKilkbG9jay5wQml0cysoeGRzdC50b3AqZGxvY2suUGl0Y2gpKyh4ZHN0LmxlZnQqYnBwKTsKCiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfV0FJVCkKICAgIHsKICAgICAgICBGbGFncyAmPSB+V0lORUREQkxUX1dBSVQ7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfQVNZTkMpCiAgICB7CiAgICAgICAgc3RhdGljIEJPT0wgZGlzcGxheWVkID0gRkFMU0U7CiAgICAgICAgaWYgKCFkaXNwbGF5ZWQpCiAgICAgICAgICAgIEZJWE1FKCJDYW4ndCBoYW5kbGUgV0lORUREQkxUX0FTWU5DIGZsYWcgcmlnaHQgbm93LlxuIik7CiAgICAgICAgZGlzcGxheWVkID0gVFJVRTsKICAgICAgICBGbGFncyAmPSB+V0lORUREQkxUX0FTWU5DOwogICAgfQogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0RPTk9UV0FJVCkKICAgIHsKICAgICAgICAvKiBXSU5FRERCTFRfRE9OT1RXQUlUIGFwcGVhcmVkIGluIERYNyAqLwogICAgICAgIHN0YXRpYyBCT09MIGRpc3BsYXllZCA9IEZBTFNFOwogICAgICAgIGlmICghZGlzcGxheWVkKQogICAgICAgICAgICBGSVhNRSgiQ2FuJ3QgaGFuZGxlIFdJTkVEREJMVF9ET05PVFdBSVQgZmxhZyByaWdodCBub3cuXG4iKTsKICAgICAgICBkaXNwbGF5ZWQgPSBUUlVFOwogICAgICAgIEZsYWdzICY9IH5XSU5FRERCTFRfRE9OT1RXQUlUOwogICAgfQoKICAgIC8qIEZpcnN0LCBhbGwgdGhlICdzb3VyY2UtbGVzcycgYmxpdHMgKi8KICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9DT0xPUkZJTEwpCiAgICB7CiAgICAgICAgcmV0ID0gX0JsdF9Db2xvckZpbGwoZGJ1ZiwgZHN0d2lkdGgsIGRzdGhlaWdodCwgYnBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRsb2NrLlBpdGNoLCBEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcik7CiAgICAgICAgRmxhZ3MgJj0gfldJTkVEREJMVF9DT0xPUkZJTEw7CiAgICB9CgogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0RFUFRIRklMTCkKICAgIHsKICAgICAgICBGSVhNRSgiRERCTFRfREVQVEhGSUxMIG5lZWRzIHRvIGJlIGltcGxlbWVudGVkIVxuIik7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfUk9QKQogICAgewogICAgICAgIC8qIENhdGNoIHNvbWUgZGVnZW5lcmF0ZSBjYXNlcyBoZXJlICovCiAgICAgICAgc3dpdGNoKEREQmx0RngtPmR3Uk9QKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBCTEFDS05FU1M6CiAgICAgICAgICAgICAgICByZXQgPSBfQmx0X0NvbG9yRmlsbChkYnVmLGRzdHdpZHRoLGRzdGhlaWdodCxicHAsZGxvY2suUGl0Y2gsMCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMHhBQTAwMjk6IC8qIE5vLW9wICovCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV0hJVEVORVNTOgogICAgICAgICAgICAgICAgcmV0ID0gX0JsdF9Db2xvckZpbGwoZGJ1Zixkc3R3aWR0aCxkc3RoZWlnaHQsYnBwLGRsb2NrLlBpdGNoLH4wKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBTUkNDT1BZOiAvKiB3ZWxsLCB3ZSBkbyB0aGF0IGJlbG93ID8gKi8KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCByYXN0ZXIgb3A6ICUwOHggIFBhdHRlcm46ICVwXG4iLCBEREJsdEZ4LT5kd1JPUCwgRERCbHRGeC0+dTUubHBERFNQYXR0ZXJuKTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIEZsYWdzICY9IH5XSU5FRERCTFRfUk9QOwogICAgfQogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0REUk9QUykKICAgIHsKICAgICAgICBGSVhNRSgiXHREZHJhdyBSYXN0ZXIgT3BzOiAlMDh4ICBQYXR0ZXJuOiAlcFxuIiwgRERCbHRGeC0+ZHdERFJPUCwgRERCbHRGeC0+dTUubHBERFNQYXR0ZXJuKTsKICAgIH0KICAgIC8qIE5vdyB0aGUgJ3dpdGggc291cmNlJyBibGl0cyAqLwogICAgaWYgKFNyYykKICAgIHsKICAgICAgICBMUEJZVEUgc2Jhc2U7CiAgICAgICAgaW50IHN4LCB4aW5jLCBzeSwgeWluYzsKCiAgICAgICAgaWYgKCFkc3R3aWR0aCB8fCAhZHN0aGVpZ2h0KSAvKiBobW0uLi4gc3R1cGlkIHByb2dyYW0gPyAqLwogICAgICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICAgICAgc2Jhc2UgPSAoQllURSopc2xvY2sucEJpdHMrKHhzcmMudG9wKnNsb2NrLlBpdGNoKSt4c3JjLmxlZnQqYnBwOwogICAgICAgIHhpbmMgPSAoc3Jjd2lkdGggPDwgMTYpIC8gZHN0d2lkdGg7CiAgICAgICAgeWluYyA9IChzcmNoZWlnaHQgPDwgMTYpIC8gZHN0aGVpZ2h0OwoKICAgICAgICBpZiAoIUZsYWdzKQogICAgICAgIHsKICAgICAgICAgICAgLyogTm8gZWZmZWN0cywgd2UgY2FuIGNoZWF0IGhlcmUgKi8KICAgICAgICAgICAgaWYgKGRzdHdpZHRoID09IHNyY3dpZHRoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZHN0aGVpZ2h0ID09IHNyY2hlaWdodCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBObyBzdHJldGNoaW5nIGluIGVpdGhlciBkaXJlY3Rpb24uIFRoaXMgbmVlZHMgdG8gYmUgYXMKICAgICAgICAgICAgICAgICAgICAqIGZhc3QgYXMgcG9zc2libGUgKi8KICAgICAgICAgICAgICAgICAgICBzYnVmID0gc2Jhc2U7CgogICAgICAgICAgICAgICAgICAgIC8qIGNoZWNrIGZvciBvdmVybGFwcGluZyBzdXJmYWNlcyAqLwogICAgICAgICAgICAgICAgICAgIGlmIChTcmNTdXJmYWNlICE9IGlmYWNlIHx8IHhkc3QudG9wIDwgeHNyYy50b3AgfHwKICAgICAgICAgICAgICAgICAgICAgICAgeGRzdC5yaWdodCA8PSB4c3JjLmxlZnQgfHwgeHNyYy5yaWdodCA8PSB4ZHN0LmxlZnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBubyBvdmVybGFwLCBvciBkc3QgYWJvdmUgc3JjLCBzbyBjb3B5IGZyb20gdG9wIGRvd253YXJkcyAqLwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnVmICs9IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh4ZHN0LnRvcCA+IHhzcmMudG9wKSAgLyogY29weSBmcm9tIGJvdHRvbSB1cHdhcmRzICovCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzYnVmICs9IChzbG9jay5QaXRjaCpkc3RoZWlnaHQpOwogICAgICAgICAgICAgICAgICAgICAgICBkYnVmICs9IChkbG9jay5QaXRjaCpkc3RoZWlnaHQpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgLT0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYnVmIC09IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRidWYsIHNidWYsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIC8qIHNyYyBhbmQgZHN0IG92ZXJsYXBwaW5nIG9uIHRoZSBzYW1lIGxpbmUsIHVzZSBtZW1tb3ZlICovCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbW1vdmUoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiArPSBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qIFN0cmV0Y2hpbmcgaW4gWSBkaXJlY3Rpb24gb25seSAqLwogICAgICAgICAgICAgICAgICAgIGZvciAoeSA9IHN5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrLCBzeSArPSB5aW5jKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgPSBzYmFzZSArIChzeSA+PiAxNikgKiBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRidWYsIHNidWYsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBTdHJldGNoaW5nIGluIFggZGlyZWN0aW9uICovCiAgICAgICAgICAgICAgICBpbnQgbGFzdF9zeSA9IC0xOwogICAgICAgICAgICAgICAgZm9yICh5ID0gc3kgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyssIHN5ICs9IHlpbmMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlICsgKHN5ID4+IDE2KSAqIHNsb2NrLlBpdGNoOwoKICAgICAgICAgICAgICAgICAgICBpZiAoKHN5ID4+IDE2KSA9PSAobGFzdF9zeSA+PiAxNikpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiB0aGlzIHNvdXJjZXJvdyBpcyB0aGUgc2FtZSBhcyBsYXN0IHNvdXJjZXJvdyAtCiAgICAgICAgICAgICAgICAgICAgICAgICogY29weSBhbHJlYWR5IHN0cmV0Y2hlZCByb3cKICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRidWYsIGRidWYgLSBkbG9jay5QaXRjaCwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewojZGVmaW5lIFNUUkVUQ0hfUk9XKHR5cGUpIHsgXAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlICpzID0gKHR5cGUgKikgc2J1ZiwgKmQgPSAodHlwZSAqKSBkYnVmOyBcCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IHN4ID0gMDsgeCA8IGRzdHdpZHRoOyB4KyssIHN4ICs9IHhpbmMpIFwKICAgICAgICAgICAgICAgICAgICAgICAgZFt4XSA9IHNbc3ggPj4gMTZdOyBcCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOyB9CgogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2goYnBwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IFNUUkVUQ0hfUk9XKEJZVEUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjogU1RSRVRDSF9ST1coV09SRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IFNUUkVUQ0hfUk9XKERXT1JEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBzLGQgPSBkYnVmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IHN4ID0gMDsgeCA8IGRzdHdpZHRoOyB4KyssIHN4Kz0geGluYykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHBpeGVsOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHNidWYrMyooc3g+PjE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWwgPSBzWzBdfChzWzFdPDw4KXwoc1syXTw8MTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWzBdID0gKHBpeGVsICAgICkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFsxXSA9IChwaXhlbD4+IDgpJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbMl0gPSAocGl4ZWw+PjE2KSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkKz0zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlN0cmV0Y2hlZCBibGl0IG5vdCBpbXBsZW1lbnRlZCBmb3IgYnBwICVkIVxuIiwgYnBwKjgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KI3VuZGVmIFNUUkVUQ0hfUk9XCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgbGFzdF9zeSA9IHN5OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIExPTkcgZHN0eWluYyA9IGRsb2NrLlBpdGNoLCBkc3R4aW5jID0gYnBwOwogICAgICAgICAgICBEV09SRCBrZXlsb3cgPSAweEZGRkZGRkZGLCBrZXloaWdoID0gMCwga2V5bWFzayA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIERXT1JEIGRlc3RrZXlsb3cgPSAweDAsIGRlc3RrZXloaWdoID0gMHhGRkZGRkZGRiwgZGVzdGtleW1hc2sgPSAweEZGRkZGRkZGOwogICAgICAgICAgICBpZiAoRmxhZ3MgJiAoV0lORUREQkxUX0tFWVNSQyB8IFdJTkVEREJMVF9LRVlERVNUIHwgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFIHwgV0lORUREQkxUX0tFWURFU1RPVkVSUklERSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIFRoZSBjb2xvciBrZXlpbmcgZmxhZ3MgYXJlIGNoZWNrZWQgZm9yIGNvcnJlY3RuZXNzIGluIGRkcmF3ICovCiAgICAgICAgICAgICAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfS0VZU1JDKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGtleWxvdyAgPSBTcmMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgICAgICAgICAga2V5aGlnaCA9IFNyYy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfS0VZU1JDT1ZFUlJJREUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAga2V5bG93ICA9IEREQmx0RngtPmRkY2tTcmNDb2xvcmtleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZTsKICAgICAgICAgICAgICAgICAgICBrZXloaWdoID0gRERCbHRGeC0+ZGRja1NyY0NvbG9ya2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfS0VZREVTVCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBEZXN0aW5hdGlvbiBjb2xvciBrZXlzIGFyZSB0YWtlbiBmcm9tIHRoZSBzb3VyY2Ugc3VyZmFjZSAhICovCiAgICAgICAgICAgICAgICAgICAgZGVzdGtleWxvdyAgPSBTcmMtPkRlc3RCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAgICAgIGRlc3RrZXloaWdoID0gU3JjLT5EZXN0Qmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChGbGFncyAmIFdJTkVEREJMVF9LRVlERVNUT1ZFUlJJREUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGVzdGtleWxvdyAgPSBEREJsdEZ4LT5kZGNrRGVzdENvbG9ya2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAgICAgIGRlc3RrZXloaWdoID0gRERCbHRGeC0+ZGRja0Rlc3RDb2xvcmtleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYoYnBwID09IDEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAga2V5bWFzayA9IDB4ZmY7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAga2V5bWFzayA9IHNFbnRyeS0+cmVkTWFzayAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNFbnRyeS0+Z3JlZW5NYXNrIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNFbnRyeS0+Ymx1ZU1hc2s7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBGbGFncyAmPSB+KFdJTkVEREJMVF9LRVlTUkMgfCBXSU5FRERCTFRfS0VZREVTVCB8IFdJTkVEREJMVF9LRVlTUkNPVkVSUklERSB8IFdJTkVEREJMVF9LRVlERVNUT1ZFUlJJREUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfRERGWCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTFBCWVRFIGRUb3BMZWZ0LCBkVG9wUmlnaHQsIGRCb3R0b21MZWZ0LCBkQm90dG9tUmlnaHQsIHRtcDsKICAgICAgICAgICAgICAgIExPTkcgdG1weHk7CiAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSBkYnVmOwogICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gZGJ1ZisoKGRzdHdpZHRoLTEpKmJwcCk7CiAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSBkVG9wTGVmdCsoKGRzdGhlaWdodC0xKSpkbG9jay5QaXRjaCk7CiAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkQm90dG9tTGVmdCsoKGRzdHdpZHRoLTEpKmJwcCk7CgogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX0FSSVRIU1RSRVRDSFkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogSSBkb24ndCB0aGluayB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nIGFib3V0IHRoaXMgZmxhZyAqLwogICAgICAgICAgICAgICAgICAgIFdBUk4oIkZsYWdzPUREQkxUX0RERlggbm90aGluZyBkb25lIGZvciBXSU5FRERCTFRGWF9BUklUSFNUUkVUQ0hZXG4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9NSVJST1JMRUZUUklHSFQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcFJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IHRtcDsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gdG1wOwogICAgICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R4aW5jICotMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9NSVJST1JVUERPV04pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gdG1wOwogICAgICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gdG1wOwogICAgICAgICAgICAgICAgICAgIGRzdHlpbmMgPSBkc3R5aW5jICotMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9OT1RFQVJJTkcpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogSSBkb24ndCB0aGluayB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nIGFib3V0IHRoaXMgZmxhZyAqLwogICAgICAgICAgICAgICAgICAgIFdBUk4oIkZsYWdzPUREQkxUX0RERlggbm90aGluZyBkb25lIGZvciBXSU5FRERCTFRGWF9OT1RFQVJJTkdcbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX1JPVEFURTE4MCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gdG1wOwogICAgICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRCb3R0b21MZWZ0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSB0bXA7CiAgICAgICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHhpbmMgKiAtMTsKICAgICAgICAgICAgICAgICAgICBkc3R5aW5jID0gZHN0eWluYyAqIC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX1JPVEFURTI3MCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZFRvcFJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IHRtcDsKICAgICAgICAgICAgICAgICAgICB0bXB4eSAgID0gZHN0eGluYzsKICAgICAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eWluYzsKICAgICAgICAgICAgICAgICAgICBkc3R5aW5jID0gdG1weHk7CiAgICAgICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHhpbmMgKiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9ST1RBVEU5MCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRCb3R0b21MZWZ0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IHRtcDsKICAgICAgICAgICAgICAgICAgICB0bXB4eSAgID0gZHN0eGluYzsKICAgICAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eWluYzsKICAgICAgICAgICAgICAgICAgICBkc3R5aW5jID0gdG1weHk7CiAgICAgICAgICAgICAgICAgICAgZHN0eWluYyA9IGRzdHlpbmMgKiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9aQlVGRkVSQkFTRURFU1QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogSSBkb24ndCB0aGluayB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nIGFib3V0IHRoaXMgZmxhZyAqLwogICAgICAgICAgICAgICAgICAgIFdBUk4oIkZsYWdzPVdJTkVEREJMVF9EREZYIG5vdGhpbmcgZG9uZSBmb3IgV0lORUREQkxURlhfWkJVRkZFUkJBU0VERVNUXG4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRidWYgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgIEZsYWdzICY9IH4oV0lORUREQkxUX0RERlgpOwogICAgICAgICAgICB9CgojZGVmaW5lIENPUFlfQ09MT1JLRVlfRlgodHlwZSkgeyBcCiAgICAgICAgICAgIHR5cGUgKnMsICpkID0gKHR5cGUgKikgZGJ1ZiwgKmR4LCB0bXA7IFwKICAgICAgICAgICAgZm9yICh5ID0gc3kgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyssIHN5ICs9IHlpbmMpIHsgXAogICAgICAgICAgICBzID0gKHR5cGUqKShzYmFzZSArIChzeSA+PiAxNikgKiBzbG9jay5QaXRjaCk7IFwKICAgICAgICAgICAgZHggPSBkOyBcCiAgICAgICAgICAgIGZvciAoeCA9IHN4ID0gMDsgeCA8IGRzdHdpZHRoOyB4KyssIHN4ICs9IHhpbmMpIHsgXAogICAgICAgICAgICB0bXAgPSBzW3N4ID4+IDE2XTsgXAogICAgICAgICAgICBpZiAoKCh0bXAgJiBrZXltYXNrKSA8IGtleWxvdyB8fCAodG1wICYga2V5bWFzaykgPiBrZXloaWdoKSAmJiBcCiAgICAgICAgICAgICgoZHhbMF0gJiBkZXN0a2V5bWFzaykgPj0gZGVzdGtleWxvdyAmJiAoZHhbMF0gJiBkZXN0a2V5bWFzaykgPD0gZGVzdGtleWhpZ2gpKSB7IFwKICAgICAgICAgICAgZHhbMF0gPSB0bXA7IFwKICAgICAgICB9IFwKICAgICAgICAgICAgZHggPSAodHlwZSopKCgoTFBCWVRFKWR4KStkc3R4aW5jKTsgXAogICAgICAgIH0gXAogICAgICAgICAgICBkID0gKHR5cGUqKSgoKExQQllURSlkKStkc3R5aW5jKTsgXAogICAgICAgIH0gXAogICAgICAgICAgICBicmVhazsgfQoKICAgICAgICAgICAgc3dpdGNoIChicHApIHsKICAgICAgICAgICAgICAgIGNhc2UgMTogQ09QWV9DT0xPUktFWV9GWChCWVRFKQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IENPUFlfQ09MT1JLRVlfRlgoV09SRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IENPUFlfQ09MT1JLRVlfRlgoRFdPUkQpCiAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTFBCWVRFIHMsZCA9IGRidWYsIGR4OwogICAgICAgICAgICAgICAgICAgIGZvciAoeSA9IHN5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrLCBzeSArPSB5aW5jKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlICsgKHN5ID4+IDE2KSAqIHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICBkeCA9IGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IHN4ID0gMDsgeCA8IGRzdHdpZHRoOyB4KyssIHN4Kz0geGluYykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgcGl4ZWwsIGRwaXhlbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gc2J1ZiszKihzeD4+MTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWwgPSBzWzBdfChzWzFdPDw4KXwoc1syXTw8MTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBpeGVsID0gZHhbMF18KGR4WzFdPDw4KXwoZHhbMl08PDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKHBpeGVsICYga2V5bWFzaykgPCBrZXlsb3cgfHwgKHBpeGVsICYga2V5bWFzaykgPiBrZXloaWdoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChkcGl4ZWwgJiBrZXltYXNrKSA+PSBkZXN0a2V5bG93IHx8IChkcGl4ZWwgJiBrZXltYXNrKSA8PSBrZXloaWdoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeFswXSA9IChwaXhlbCAgICApJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHhbMV0gPSAocGl4ZWw+PiA4KSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4WzJdID0gKHBpeGVsPj4xNikmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4Kz0gZHN0eGluYzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBkICs9IGRzdHlpbmM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiJXMgY29sb3Ita2V5ZWQgYmxpdCBub3QgaW1wbGVtZW50ZWQgZm9yIGJwcCAlZCFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKEZsYWdzICYgV0lORUREQkxUX0tFWVNSQykgPyAiU291cmNlIiA6ICJEZXN0aW5hdGlvbiIsIGJwcCo4KTsKICAgICAgICAgICAgICAgICAgICByZXQgPSBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwojdW5kZWYgQ09QWV9DT0xPUktFWV9GWAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKZXJyb3I6CiAgICBpZiAoRmxhZ3MgJiYgRklYTUVfT04oZDNkX3N1cmZhY2UpKQogICAgewogICAgICAgIEZJWE1FKCJcdFVuc3VwcG9ydGVkIGZsYWdzOiAlMDh4XG4iLCBGbGFncyk7CiAgICB9CgpyZWxlYXNlOgogICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwogICAgaWYgKFNyY1N1cmZhY2UgJiYgU3JjU3VyZmFjZSAhPSBpZmFjZSkgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoU3JjU3VyZmFjZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpCbHRGYXN0LCBTVyBlbXVsYXRpb24gdmVyc2lvbgogKgogKiBUaGlzIGlzIHRoZSBzb2Z0d2FyZSBpbXBsZW1lbnRhdGlvbiBvZiBCbHRGYXN0LCBhcyB1c2VkIGJ5IEdESSBzdXJmYWNlcwogKiBhbmQgYXMgYSBmYWxsYmFjayBmb3IgT3BlbkdMIHN1cmZhY2VzLiBUaGlzIGNvZGUgaXMgdGFrZW4gZnJvbSB0aGUgb2xkCiAqIERpcmVjdERyYXcgY29kZSwgYW5kIHdhcyBvcmlnaW5hbGx5IHdyaXR0ZW4gYnkgVHJhbnNHYW1pbmcuCiAqCiAqIFBhcmFtczoKICogIGRzdHg6CiAqICBkc3R5OgogKiAgU291cmNlOiBTb3VyY2Ugc3VyZmFjZSB0byBjb3B5IGZyb20KICogIHJzcmM6IFNvdXJjZSByZWN0YW5nbGUKICogIHRyYW5zOiBTb21lIEZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CbHRGYXN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkc3R5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKnJzcmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgdHJhbnMpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNvdXJjZTsKCiAgICBpbnQgICAgICAgICAgICAgICAgIGJwcCwgdywgaCwgeCwgeTsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCAgZGxvY2ssc2xvY2s7CiAgICBIUkVTVUxUICAgICAgICAgICAgIHJldCA9IFdJTkVEM0RfT0s7CiAgICBSRUNUICAgICAgICAgICAgICAgIHJzcmMyOwogICAgUkVDVCAgICAgICAgICAgICAgICBsb2NrX3NyYywgbG9ja19kc3QsIGxvY2tfdW5pb247CiAgICBCWVRFICAgICAgICAgICAgICAgICpzYnVmLCAqZGJ1ZjsKICAgIGNvbnN0IFN0YXRpY1BpeGVsRm9ybWF0RGVzYyAqc0VudHJ5LCAqZEVudHJ5OwoKICAgIGlmIChUUkFDRV9PTihkM2Rfc3VyZmFjZSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCktPiglZCwlZCwlcCwlcCwlMDh4KVxuIiwgVGhpcyxkc3R4LGRzdHksU3JjLHJzcmMsdHJhbnMpOwoKICAgICAgICBpZiAocnNyYykKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJcdHNyY3JlY3Q6ICVkeCVkLSVkeCVkXG4iLHJzcmMtPmxlZnQscnNyYy0+dG9wLAogICAgICAgICAgICAgICAgICByc3JjLT5yaWdodCxyc3JjLT5ib3R0b20pOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiIHNyY3JlY3Q6IE5VTExcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSB8fAogICAgICAgICAoKFNyYyAhPSBOVUxMKSAmJiAoU3JjLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkpKQogICAgewogICAgICAgIFdBUk4oIiBTdXJmYWNlIGlzIGJ1c3ksIHJldHVybmluZyBEREVSUl9TVVJGQUNFQlVTWVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9TVVJGQUNFQlVTWTsKICAgIH0KCiAgICBpZiAoIXJzcmMpCiAgICB7CiAgICAgICAgV0FSTigicnNyYyBpcyBOVUxMIVxuIik7CiAgICAgICAgcnNyYyA9ICZyc3JjMjsKICAgICAgICByc3JjLT5sZWZ0ID0gMDsKICAgICAgICByc3JjLT50b3AgPSAwOwogICAgICAgIHJzcmMtPnJpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICByc3JjLT5ib3R0b20gPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KCiAgICAvKiBDaGVjayBzb3VyY2UgcmVjdCBmb3IgdmFsaWRpdHkuIENvcGllZCBmcm9tIG5vcm1hbCBCbHQuIEZpeGVzIEJhbGR1cidzIEdhdGUuKi8KICAgIGlmICgocnNyYy0+Ym90dG9tID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8IChyc3JjLT5ib3R0b20gPCAwKSB8fAogICAgICAgICAocnNyYy0+dG9wICAgID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8IChyc3JjLT50b3AgICAgPCAwKSB8fAogICAgICAgICAocnNyYy0+bGVmdCAgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8IChyc3JjLT5sZWZ0ICAgPCAwKSB8fAogICAgICAgICAocnNyYy0+cmlnaHQgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8IChyc3JjLT5yaWdodCAgPCAwKSB8fAogICAgICAgICAocnNyYy0+cmlnaHQgIDwgcnNyYy0+bGVmdCkgICAgICAgICAgICAgIHx8IChyc3JjLT5ib3R0b20gPCByc3JjLT50b3ApKQogICAgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIGdhdmUgdXMgYmFkIHNvdXJjZSByZWN0YW5nbGUgZm9yIEJsdEZhc3QuXG4iKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX0lOVkFMSURSRUNUOwogICAgfQoKICAgIGggPSByc3JjLT5ib3R0b20gLSByc3JjLT50b3A7CiAgICBpZiAoaCA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodC1kc3R5KSBoID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LWRzdHk7CiAgICBpZiAoaCA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0LXJzcmMtPnRvcCkgaD1TcmMtPmN1cnJlbnREZXNjLkhlaWdodC1yc3JjLT50b3A7CiAgICBpZiAoaCA8PSAwKSByZXR1cm4gV0lORURERVJSX0lOVkFMSURSRUNUOwoKICAgIHcgPSByc3JjLT5yaWdodCAtIHJzcmMtPmxlZnQ7CiAgICBpZiAodyA+IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLWRzdHgpIHcgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aC1kc3R4OwogICAgaWYgKHcgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoLXJzcmMtPmxlZnQpIHcgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoLXJzcmMtPmxlZnQ7CiAgICBpZiAodyA8PSAwKSByZXR1cm4gV0lORURERVJSX0lOVkFMSURSRUNUOwoKICAgIC8qIE5vdyBjb21wdXRlIHRoZSBsb2NraW5nIHJlY3RhbmdsZS4uLiAqLwogICAgbG9ja19zcmMubGVmdCA9IHJzcmMtPmxlZnQ7CiAgICBsb2NrX3NyYy50b3AgPSByc3JjLT50b3A7CiAgICBsb2NrX3NyYy5yaWdodCA9IGxvY2tfc3JjLmxlZnQgKyB3OwogICAgbG9ja19zcmMuYm90dG9tID0gbG9ja19zcmMudG9wICsgaDsKCiAgICBsb2NrX2RzdC5sZWZ0ID0gZHN0eDsKICAgIGxvY2tfZHN0LnRvcCA9IGRzdHk7CiAgICBsb2NrX2RzdC5yaWdodCA9IGRzdHggKyB3OwogICAgbG9ja19kc3QuYm90dG9tID0gZHN0eSArIGg7CgogICAgYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKCiAgICAvKiBXZSBuZWVkIHRvIGxvY2sgdGhlIHN1cmZhY2VzLCBvciB3ZSB3b24ndCBnZXQgcmVmcmVzaGVzIHdoZW4gZG9uZS4gKi8KICAgIGlmIChTcmMgPT0gVGhpcykKICAgIHsKICAgICAgICBpbnQgcGl0Y2g7CgogICAgICAgIFVuaW9uUmVjdCgmbG9ja191bmlvbiwgJmxvY2tfc3JjLCAmbG9ja19kc3QpOwoKICAgICAgICAvKiBMb2NrIHRoZSB1bmlvbiBvZiB0aGUgdHdvIHJlY3RhbmdsZXMgKi8KICAgICAgICByZXQgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsICZkbG9jaywgJmxvY2tfdW5pb24sIDApOwogICAgICAgIGlmKHJldCAhPSBXSU5FRDNEX09LKSBnb3RvIGVycm9yOwoKICAgICAgICBwaXRjaCA9IGRsb2NrLlBpdGNoOwogICAgICAgIHNsb2NrLlBpdGNoID0gZGxvY2suUGl0Y2g7CgogICAgICAgIC8qIFNpbmNlIHNsb2NrIHdhcyBvcmlnaW5hbGx5IGNvcGllZCBmcm9tIHRoaXMgc3VyZmFjZSdzIGRlc2NyaXB0aW9uLCB3ZSBjYW4ganVzdCByZXVzZSBpdCAqLwogICAgICAgIGFzc2VydChUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgIT0gTlVMTCk7CiAgICAgICAgc2J1ZiA9IChCWVRFICopVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgbG9ja19zcmMudG9wICogcGl0Y2ggKyBsb2NrX3NyYy5sZWZ0ICogYnBwOwogICAgICAgIGRidWYgPSAoQllURSAqKVRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIGxvY2tfZHN0LnRvcCAqIHBpdGNoICsgbG9ja19kc3QubGVmdCAqIGJwcDsKICAgICAgICBzRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoU3JjLT5yZXNvdXJjZS5mb3JtYXQsIE5VTEwsIE5VTEwpOwogICAgICAgIGRFbnRyeSA9IHNFbnRyeTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXQgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoU291cmNlLCAmc2xvY2ssICZsb2NrX3NyYywgV0lORUQzRExPQ0tfUkVBRE9OTFkpOwogICAgICAgIGlmKHJldCAhPSBXSU5FRDNEX09LKSBnb3RvIGVycm9yOwogICAgICAgIHJldCA9IElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwgJmRsb2NrLCAmbG9ja19kc3QsIDApOwogICAgICAgIGlmKHJldCAhPSBXSU5FRDNEX09LKSBnb3RvIGVycm9yOwoKICAgICAgICBzYnVmID0gc2xvY2sucEJpdHM7CiAgICAgICAgZGJ1ZiA9IGRsb2NrLnBCaXRzOwogICAgICAgIFRSQUNFKCJEc3QgaXMgYXQgJXAsIFNyYyBpcyBhdCAlcFxuIiwgZGJ1Ziwgc2J1Zik7CgogICAgICAgIHNFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShTcmMtPnJlc291cmNlLmZvcm1hdCwgTlVMTCwgTlVMTCk7CiAgICAgICAgZEVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFRoaXMtPnJlc291cmNlLmZvcm1hdCwgTlVMTCwgTlVMTCk7CiAgICB9CgogICAgLyogSGFuZGxlIGZpcnN0IHRoZSBGT1VSQ0Mgc3VyZmFjZXMuLi4gKi8KICAgIGlmIChzRW50cnktPmlzRm91cmNjICYmIGRFbnRyeS0+aXNGb3VyY2MpCiAgICB7CiAgICAgICAgVFJBQ0UoIkZvdXJjYyAtPiBGb3VyY2MgY29weVxuIik7CiAgICAgICAgaWYgKHRyYW5zKQogICAgICAgICAgICBGSVhNRSgidHJhbnMgYXJnIG5vdCBzdXBwb3J0ZWQgd2hlbiBhIEZPVVJDQyBzdXJmYWNlIGlzIGludm9sdmVkXG4iKTsKICAgICAgICBpZiAoZHN0eCB8fCBkc3R5KQogICAgICAgICAgICBGSVhNRSgib2Zmc2V0IGZvciBkZXN0aW5hdGlvbiBzdXJmYWNlIGlzIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIGlmIChTcmMtPnJlc291cmNlLmZvcm1hdCAhPSBUaGlzLT5yZXNvdXJjZS5mb3JtYXQpCiAgICAgICAgewogICAgICAgICAgICBGSVhNRSgiRk9VUkNDLT5GT1VSQ0MgY29weSBvbmx5IHN1cHBvcnRlZCBmb3IgdGhlIHNhbWUgdHlwZSBvZiBzdXJmYWNlXG4iKTsKICAgICAgICAgICAgcmV0ID0gV0lORUQzREVSUl9XUk9OR1RFWFRVUkVGT1JNQVQ7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIC8qIEZJWE1FOiBXYXRjaCBvdXQgdGhhdCB0aGUgc2l6ZSBpcyBjb3JyZWN0IGZvciBGT1VSQ0Mgc3VyZmFjZXMgKi8KICAgICAgICBtZW1jcHkoZGJ1Ziwgc2J1ZiwgVGhpcy0+cmVzb3VyY2Uuc2l6ZSk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChzRW50cnktPmlzRm91cmNjICYmICFkRW50cnktPmlzRm91cmNjKQogICAgewogICAgICAgIC8qIFRPRE86IFVzZSB0aGUgbGlidHhjX2R4dG4uc28gc2hhcmVkIGxpYnJhcnkgdG8gZG8KICAgICAgICAgKiBzb2Z0d2FyZSBkZWNvbXByZXNzaW9uCiAgICAgICAgICovCiAgICAgICAgRVJSKCJEWFRDIGRlY29tcHJlc3Npb24gbm90IHN1cHBvcnRlZCBieSBub3dcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKHRyYW5zICYgKFdJTkVEREJMVEZBU1RfU1JDQ09MT1JLRVkgfCBXSU5FRERCTFRGQVNUX0RFU1RDT0xPUktFWSkpCiAgICB7CiAgICAgICAgRFdPUkQga2V5bG93LCBrZXloaWdoOwogICAgICAgIFRSQUNFKCJDb2xvciBrZXllZCBjb3B5XG4iKTsKICAgICAgICBpZiAodHJhbnMgJiBXSU5FRERCTFRGQVNUX1NSQ0NPTE9SS0VZKQogICAgICAgIHsKICAgICAgICAgICAga2V5bG93ICA9IFNyYy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZTsKICAgICAgICAgICAga2V5aGlnaCA9IFNyYy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIEknbSBub3Qgc3VyZSBpZiB0aGlzIGlzIGNvcnJlY3QgKi8KICAgICAgICAgICAgRklYTUUoIldJTkVEREJMVEZBU1RfREVTVENPTE9SS0VZIG5vdCBmdWxseSBzdXBwb3J0ZWQgeWV0LlxuIik7CiAgICAgICAgICAgIGtleWxvdyAgPSBUaGlzLT5EZXN0Qmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZTsKICAgICAgICAgICAga2V5aGlnaCA9IFRoaXMtPkRlc3RCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICB9CgojZGVmaW5lIENPUFlCT1hfQ09MT1JLRVkodHlwZSkgeyBcCiAgICAgICAgdHlwZSAqZCwgKnMsIHRtcDsgXAogICAgICAgIHMgPSAodHlwZSAqKSBzYnVmOyBcCiAgICAgICAgZCA9ICh0eXBlICopIGRidWY7IFwKICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaDsgeSsrKSB7IFwKICAgICAgICBmb3IgKHggPSAwOyB4IDwgdzsgeCsrKSB7IFwKICAgICAgICB0bXAgPSBzW3hdOyBcCiAgICAgICAgaWYgKHRtcCA8IGtleWxvdyB8fCB0bXAgPiBrZXloaWdoKSBkW3hdID0gdG1wOyBcCiAgICB9IFwKICAgICAgICBzID0gKHR5cGUgKikoKEJZVEUgKilzICsgc2xvY2suUGl0Y2gpOyBcCiAgICAgICAgZCA9ICh0eXBlICopKChCWVRFICopZCArIGRsb2NrLlBpdGNoKTsgXAogICAgfSBcCiAgICAgICAgYnJlYWs7IFwKICAgIH0KCiAgICAgICAgc3dpdGNoIChicHApIHsKICAgICAgICAgICAgY2FzZSAxOiBDT1BZQk9YX0NPTE9SS0VZKEJZVEUpCiAgICAgICAgICAgICAgICAgICAgY2FzZSAyOiBDT1BZQk9YX0NPTE9SS0VZKFdPUkQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IENPUFlCT1hfQ09MT1JLRVkoRFdPUkQpCiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQllURSAqZCwgKnM7CiAgICAgICAgICAgICAgICBEV09SRCB0bXA7CiAgICAgICAgICAgICAgICBzID0gKEJZVEUgKikgc2J1ZjsKICAgICAgICAgICAgICAgIGQgPSAoQllURSAqKSBkYnVmOwogICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGg7IHkrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgdyAqIDM7IHggKz0gMykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IChEV09SRClzW3hdICsgKChEV09SRClzW3ggKyAxXSA8PCA4KSArICgoRFdPUkQpc1t4ICsgMl0gPDwgMTYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodG1wIDwga2V5bG93IHx8IHRtcCA+IGtleWhpZ2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbeCArIDBdID0gc1t4ICsgMF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkW3ggKyAxXSA9IHNbeCArIDFdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZFt4ICsgMl0gPSBzW3ggKyAyXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzICs9IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgIGQgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIlNvdXJjZSBjb2xvciBrZXkgYmxpdHRpbmcgbm90IHN1cHBvcnRlZCBmb3IgYnBwICVkXG4iLGJwcCo4KTsKICAgICAgICAgICAgICAgIHJldCA9IFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiN1bmRlZiBDT1BZQk9YX0NPTE9SS0VZCiAgICAgICAgVFJBQ0UoIkNvcHkgRG9uZVxuIik7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaW50IHdpZHRoID0gdyAqIGJwcDsKICAgICAgICBUUkFDRSgiTk8gY29sb3Iga2V5IGNvcHlcbiIpOwogICAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyB5KyspCiAgICAgICAgewogICAgICAgICAgICAvKiBUaGlzIGlzIHByZXR0eSBlYXN5LCBhIGxpbmUgZm9yIGxpbmUgbWVtY3B5ICovCiAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgIHNidWYgKz0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDb3B5IGRvbmVcbiIpOwogICAgfQoKZXJyb3I6CiAgICBpZiAoU3JjID09IFRoaXMpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChTb3VyY2UpOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0xvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RMT0NLRURfUkVDVCogcExvY2tlZFJlY3QsIENPTlNUIFJFQ1QqIHBSZWN0LCBEV09SRCBGbGFncykKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiByZWN0QCVwIGZsYWdzKCUwOHgpLCBvdXRwdXQgbG9ja2VkUmVjdEAlcCwgbWVtb3J5QCVwXG4iLAogICAgICAgICAgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICBwTG9ja2VkUmVjdC0+UGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpOwoKICAgIGlmIChOVUxMID09IHBSZWN0KQogICAgewogICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSAwOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgogICAgICAgIFRSQUNFKCJMb2NrZWQgUmVjdCAoJXApID0gbCAlZCwgdCAlZCwgciAlZCwgYiAlZFxuIiwKICAgICAgICAgICAgICAmVGhpcy0+bG9ja2VkUmVjdCwgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwKICAgICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0LCBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgVFJBQ0UoIkxvY2sgUmVjdCAoJXApID0gbCAlZCwgdCAlZCwgciAlZCwgYiAlZFxuIiwKICAgICAgICAgICAgICBwUmVjdCwgcFJlY3QtPmxlZnQsIHBSZWN0LT50b3AsIHBSZWN0LT5yaWdodCwgcFJlY3QtPmJvdHRvbSk7CgogICAgICAgIC8qIERYVG4gdGV4dHVyZXMgYXJlIGJhc2VkIG9uIGNvbXByZXNzZWQgYmxvY2tzIG9mIDR4NCBwaXhlbHMsIGVhY2gKICAgICAgICAgKiAxNiBieXRlcyBsYXJnZSAoOCBieXRlcyBpbiBjYXNlIG9mIERYVDEpLiBCZWNhdXNlIG9mIHRoYXQgUGl0Y2ggaGFzCiAgICAgICAgICogc2xpZ2h0bHkgZGlmZmVyZW50IG1lYW5pbmcgY29tcGFyZWQgdG8gcmVndWxhciB0ZXh0dXJlcy4gRm9yIERYVG4KICAgICAgICAgKiB0ZXh0dXJlcyBQaXRjaCBpcyB0aGUgc2l6ZSBvZiBhIHJvdyBvZiBibG9ja3MsIDQgaGlnaCBhbmQgIndpZHRoIgogICAgICAgICAqIGxvbmcuIFRoZSB4IG9mZnNldCBpcyBjYWxjdWxhdGVkIGRpZmZlcmVudGx5IGFzIHdlbGwsIHNpbmNlIG1vdmluZyA0CiAgICAgICAgICogcGl4ZWxzIHRvIHRoZSByaWdodCBhY3R1YWxseSBtb3ZlcyBhbiBlbnRpcmUgNHg0IGJsb2NrIHRvIHJpZ2h0LCBpZQogICAgICAgICAqIDE2IGJ5dGVzICg4IGluIGNhc2Ugb2YgRFhUMSkuICovCiAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpCiAgICAgICAgewogICAgICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyAocExvY2tlZFJlY3QtPlBpdGNoICogcFJlY3QtPnRvcCAvIDQpICsgKHBSZWN0LT5sZWZ0ICogMik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkKICAgICAgICB7CiAgICAgICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiBwUmVjdC0+dG9wIC8gNCkgKyAocFJlY3QtPmxlZnQgKiA0KTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsKICAgICAgICAgICAgICAgICAgICAocExvY2tlZFJlY3QtPlBpdGNoICogcFJlY3QtPnRvcCkgKwogICAgICAgICAgICAgICAgICAgIChwUmVjdC0+bGVmdCAqIFRoaXMtPmJ5dGVzUGVyUGl4ZWwpOwogICAgICAgIH0KICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICA9IHBSZWN0LT5sZWZ0OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QudG9wICAgID0gcFJlY3QtPnRvcDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0ICA9IHBSZWN0LT5yaWdodDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSA9IHBSZWN0LT5ib3R0b207CiAgICB9CgogICAgLyogTm8gZGlydGlmeWluZyBpcyBuZWVkZWQgZm9yIHRoaXMgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiAqLwogICAgVFJBQ0UoInJldHVybmluZyBtZW1vcnlAJXAsIHBpdGNoKCVkKVxuIiwgcExvY2tlZFJlY3QtPnBCaXRzLCBwTG9ja2VkUmVjdC0+UGl0Y2gpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CaW5kVGV4dHVyZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBFUlIoIlNob3VsZCBub3QgYmUgY2FsbGVkIG9uIGJhc2UgdGV4dHVyZVxuIik7CiAgICByZXR1cm47Cn0K