LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uIG9mIG1hbmFnZW1lbnQobm9uLXJlbmRlcmluZykgZnVuY3Rpb25zCiAqCiAqIENvcHlyaWdodCAxOTk4IExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqIENvcHlyaWdodCAyMDA3IEhlbnJpIFZlcmJlZXQKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBSb2RlcmljayBDb2xlbmJyYW5kZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9zdXJmYWNlKTsKCi8qIERvIE5PVCBkZWZpbmUgR0xJTkZPX0xPQ0FUSU9OIGluIHRoaXMgZmlsZS4gVEhJUyBDT0RFIE1VU1QgTk9UIFVTRSBJVCAqLwoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVVua25vd24gcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfUXVlcnlJbnRlcmZhY2UoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBvYmopCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgLyogV2FybiAsYnV0IGJlIG5pY2UgYWJvdXQgdGhpbmdzICovCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEQmFzZSkKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEUmVzb3VyY2UpCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzRFN1cmZhY2UpKSB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKChJVW5rbm93biopaWZhY2UpOwogICAgICAgICpwcG9iaiA9IFRoaXM7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICAgICAgfQogICAgICAgICpwcG9iaiA9IE5VTEw7CiAgICAgICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KClVMT05HIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9BZGRSZWYoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogQWRkUmVmIGluY3JlYXNpbmcgZnJvbSAlZFxuIiwgVGhpcyxyZWYgLSAxKTsKICAgIHJldHVybiByZWY7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIElXaW5lRDNEUmVzb3VyY2UgcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0RGV2aWNlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNERGV2aWNlKiogcHBEZXZpY2UpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXREZXZpY2UoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcHBEZXZpY2UpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZHVUlEIHJlZmd1aWQsIENPTlNUIHZvaWQqIHBEYXRhLCBEV09SRCBTaXplT2ZEYXRhLCBEV09SRCBGbGFncykgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX1NldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBTaXplT2ZEYXRhLCBGbGFncyk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFByaXZhdGVEYXRhKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRkdVSUQgcmVmZ3VpZCwgdm9pZCogcERhdGEsIERXT1JEKiBwU2l6ZU9mRGF0YSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBwU2l6ZU9mRGF0YSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0ZyZWVQcml2YXRlRGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZHVUlEIHJlZmd1aWQpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9GcmVlUHJpdmF0ZURhdGEoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcmVmZ3VpZCk7Cn0KCkRXT1JEICAgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldFByaW9yaXR5KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIFByaW9yaXR5TmV3KSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfU2V0UHJpb3JpdHkoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgUHJpb3JpdHlOZXcpOwp9CgpEV09SRCAgIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQcmlvcml0eShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UHJpb3JpdHkoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSk7Cn0KCldJTkVEM0RSRVNPVVJDRVRZUEUgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFR5cGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgVFJBQ0UoIiglcCkgOiBjYWxsaW5nIHJlc291cmNlaW1wbF9HZXRUeXBlXG4iLCBpZmFjZSk7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0VHlwZSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UGFyZW50KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElVbmtub3duICoqcFBhcmVudCkgewogICAgVFJBQ0UoIiglcCkgOiBjYWxsaW5nIHJlc291cmNlaW1wbF9HZXRQYXJlbnRcbiIsIGlmYWNlKTsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXRQYXJlbnQoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcFBhcmVudCk7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVdpbmVEM0RTdXJmYWNlIHBhcnRzIGZvbGxvdwogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldENvbnRhaW5lcihJV2luZUQzRFN1cmZhY2UqIGlmYWNlLCBSRUZJSUQgcmlpZCwgdm9pZCoqIHBwQ29udGFpbmVyKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZSAqY29udGFpbmVyID0gMDsKCiAgICBUUkFDRSgiKFRoaXMgJXAsIHJpaWQgJXMsIHBwQ29udGFpbmVyICVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHBDb250YWluZXIpOwoKICAgIGlmICghcHBDb250YWluZXIpIHsKICAgICAgICBFUlIoIkNhbGxlZCB3aXRob3V0IGEgdmFsaWQgcHBDb250YWluZXIuXG4iKTsKICAgIH0KCiAgICAvKiogRnJvbSBNU0ROOgogICAgICogSWYgdGhlIHN1cmZhY2UgaXMgY3JlYXRlZCB1c2luZyBDcmVhdGVJbWFnZVN1cmZhY2UvQ3JlYXRlT2Zmc2NyZWVuUGxhaW5TdXJmYWNlLCBDcmVhdGVSZW5kZXJUYXJnZXQsCiAgICAgKiBvciBDcmVhdGVEZXB0aFN0ZW5jaWxTdXJmYWNlLCB0aGUgc3VyZmFjZSBpcyBjb25zaWRlcmVkIHN0YW5kIGFsb25lLiBJbiB0aGlzIGNhc2UsCiAgICAgKiBHZXRDb250YWluZXIgd2lsbCByZXR1cm4gdGhlIERpcmVjdDNEIGRldmljZSB1c2VkIHRvIGNyZWF0ZSB0aGUgc3VyZmFjZS4KICAgICAqLwogICAgaWYgKFRoaXMtPmNvbnRhaW5lcikgewogICAgICAgIGNvbnRhaW5lciA9IFRoaXMtPmNvbnRhaW5lcjsKICAgIH0gZWxzZSB7CiAgICAgICAgY29udGFpbmVyID0gKElXaW5lRDNEQmFzZSAqKVRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICB9CgogICAgVFJBQ0UoIlJlbGF5aW5nIHRvIFF1ZXJ5SW50ZXJmYWNlXG4iKTsKICAgIHJldHVybiBJVW5rbm93bl9RdWVyeUludGVyZmFjZShjb250YWluZXIsIHJpaWQsIHBwQ29udGFpbmVyKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0RGVzYyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBXSU5FRDNEU1VSRkFDRV9ERVNDICpwRGVzYykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBjb3B5aW5nIGludG8gJXBcbiIsIFRoaXMsIHBEZXNjKTsKICAgIGlmKHBEZXNjLT5Gb3JtYXQgIT0gTlVMTCkgICAgICAgICAgICAgKihwRGVzYy0+Rm9ybWF0KSA9IFRoaXMtPnJlc291cmNlLmZvcm1hdDsKICAgIGlmKHBEZXNjLT5UeXBlICE9IE5VTEwpICAgICAgICAgICAgICAgKihwRGVzYy0+VHlwZSkgICA9IFRoaXMtPnJlc291cmNlLnJlc291cmNlVHlwZTsKICAgIGlmKHBEZXNjLT5Vc2FnZSAhPSBOVUxMKSAgICAgICAgICAgICAgKihwRGVzYy0+VXNhZ2UpICAgICAgICAgICAgICA9IFRoaXMtPnJlc291cmNlLnVzYWdlOwogICAgaWYocERlc2MtPlBvb2wgIT0gTlVMTCkgICAgICAgICAgICAgICAqKHBEZXNjLT5Qb29sKSAgICAgICAgICAgICAgID0gVGhpcy0+cmVzb3VyY2UucG9vbDsKICAgIGlmKHBEZXNjLT5TaXplICE9IE5VTEwpICAgICAgICAgICAgICAgKihwRGVzYy0+U2l6ZSkgICAgICAgICAgICAgICA9IFRoaXMtPnJlc291cmNlLnNpemU7ICAgLyogZHg4IG9ubHkgKi8KICAgIGlmKHBEZXNjLT5NdWx0aVNhbXBsZVR5cGUgIT0gTlVMTCkgICAgKihwRGVzYy0+TXVsdGlTYW1wbGVUeXBlKSAgICA9IFRoaXMtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlVHlwZTsKICAgIGlmKHBEZXNjLT5NdWx0aVNhbXBsZVF1YWxpdHkgIT0gTlVMTCkgKihwRGVzYy0+TXVsdGlTYW1wbGVRdWFsaXR5KSA9IFRoaXMtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlUXVhbGl0eTsKICAgIGlmKHBEZXNjLT5XaWR0aCAhPSBOVUxMKSAgICAgICAgICAgICAgKihwRGVzYy0+V2lkdGgpICAgICAgICAgICAgICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgaWYocERlc2MtPkhlaWdodCAhPSBOVUxMKSAgICAgICAgICAgICAqKHBEZXNjLT5IZWlnaHQpICAgICAgICAgICAgID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCV4KVxuIiwgVGhpcywgRmxhZ3MpOwoKICAgIHN3aXRjaCAoRmxhZ3MpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRERHQlNfQ0FOQkxUOgogICAgICAgIGNhc2UgV0lORURER0JTX0lTQkxURE9ORToKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRGbGlwU3RhdHVzKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzKSB7CiAgICAvKiBYWFg6IERERVJSX0lOVkFMSURTVVJGQUNFVFlQRSAqLwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eClcbiIsaWZhY2UsRmxhZ3MpOwogICAgc3dpdGNoIChGbGFncykgewogICAgICAgIGNhc2UgV0lORURER0ZTX0NBTkZMSVA6CiAgICAgICAgY2FzZSBXSU5FRERHRlNfSVNGTElQRE9ORToKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9Jc0xvc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIEQzRDggYW5kIDkgbG9vc2UgZnVsbCBkZXZpY2VzLCBkZHJhdyBvbmx5IHN1cmZhY2VzICovCiAgICByZXR1cm4gVGhpcy0+RmxhZ3MgJiBTRkxBR19MT1NUID8gV0lORUQzREVSUl9ERVZJQ0VMT1NUIDogV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfUmVzdG9yZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgLyogU28gZmFyIHdlIGRvbid0IGxvc2UgYW55dGhpbmcgOikgKi8KICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19MT1NUOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldFBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RQYWxldHRlICpQYWwpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKlBhbEltcGwgPSAoSVdpbmVEM0RQYWxldHRlSW1wbCAqKSBQYWw7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICBpZihUaGlzLT5wYWxldHRlID09IFBhbEltcGwpIHsKICAgICAgICBUUkFDRSgiTm9wIHBhbGV0dGUgY2hhbmdlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihUaGlzLT5wYWxldHRlICE9IE5VTEwpCiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKQogICAgICAgICAgICBUaGlzLT5wYWxldHRlLT5GbGFncyAmPSB+V0lORUREUENBUFNfUFJJTUFSWVNVUkZBQ0U7CgogICAgaWYoUGFsSW1wbCAhPSBOVUxMKSB7CiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB7CiAgICAgICAgICAgIC8qIFNldCB0aGUgZGV2aWNlJ3MgbWFpbiBwYWxldHRlIGlmIHRoZSBwYWxldHRlCiAgICAgICAgICAgICogd2Fzbid0IGEgcHJpbWFyeSBwYWxldHRlIGJlZm9yZQogICAgICAgICAgICAqLwogICAgICAgICAgICBpZighKFBhbEltcGwtPkZsYWdzICYgV0lORUREUENBUFNfUFJJTUFSWVNVUkZBQ0UpKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICAgICAgICAgICAgICBmb3IoaT0wOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgICAgICAgICBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldID0gUGFsSW1wbC0+cGFsZW50c1tpXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgKFBhbEltcGwpLT5GbGFncyB8PSBXSU5FRERQQ0FQU19QUklNQVJZU1VSRkFDRTsKICAgICAgICB9CiAgICB9CiAgICBUaGlzLT5wYWxldHRlID0gUGFsSW1wbDsKCiAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX1JlYWxpemVQYWxldHRlKGlmYWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0Q29sb3JLZXkoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgRmxhZ3MsIFdJTkVERENPTE9SS0VZICpDS2V5KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApXG4iLCBUaGlzLCBGbGFncywgQ0tleSk7CgogICAgaWYgKChGbGFncyAmIFdJTkVERENLRVlfQ09MT1JTUEFDRSkgIT0gMCkgewogICAgICAgIEZJWE1FKCIgY29sb3JrZXkgdmFsdWUgbm90IHN1cHBvcnRlZCAoJTA4eCkgIVxuIiwgRmxhZ3MpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIERpcnRpZnkgdGhlIHN1cmZhY2UsIGJ1dCBvbmx5IGlmIGEga2V5IHdhcyBjaGFuZ2VkICovCiAgICBpZihDS2V5KSB7CiAgICAgICAgc3dpdGNoIChGbGFncyAmIH5XSU5FRERDS0VZX0NPTE9SU1BBQ0UpIHsKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX0RFU1RCTFQ6CiAgICAgICAgICAgICAgICBUaGlzLT5EZXN0Qmx0Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IFdJTkVERFNEX0NLREVTVEJMVDsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX0RFU1RPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+RGVzdE92ZXJsYXlDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gV0lORUREU0RfQ0tERVNUT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX1NSQ09WRVJMQVk6CiAgICAgICAgICAgICAgICBUaGlzLT5TcmNPdmVybGF5Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IFdJTkVERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX1NSQ0JMVDoKICAgICAgICAgICAgICAgIFRoaXMtPlNyY0JsdENLZXkgPSAqQ0tleTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyB8PSBXSU5FRERTRF9DS1NSQ0JMVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+V0lORUREQ0tFWV9DT0xPUlNQQUNFKSB7CiAgICAgICAgICAgIGNhc2UgV0lORUREQ0tFWV9ERVNUQkxUOgogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5XSU5FRERTRF9DS0RFU1RCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgV0lORUREQ0tFWV9ERVNUT1ZFUkxBWToKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyAmPSB+V0lORUREU0RfQ0tERVNUT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX1NSQ09WRVJMQVk6CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfldJTkVERFNEX0NLU1JDT1ZFUkxBWTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBXSU5FRERDS0VZX1NSQ0JMVDoKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyAmPSB+V0lORUREU0RfQ0tTUkNCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RQYWxldHRlICoqUGFsKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICAqUGFsID0gKElXaW5lRDNEUGFsZXR0ZSAqKSBUaGlzLT5wYWxldHRlOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkRXT1JEIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQaXRjaChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBEV09SRCByZXQ7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgLyogRFhUbiBmb3JtYXRzIGRvbid0IGhhdmUgZXhhY3QgcGl0Y2hlcyBhcyB0aGV5IGFyZSB0byB0aGUgbmV3IHJvdyBvZiBibG9ja3MsCiAgICB3aGVyZSBlYWNoIGJsb2NrIGlzIDR4NCBwaXhlbHMsIDggYnl0ZXMgKGR4dDEpIGFuZCAxNiBieXRlcyAoZHh0Mi8zLzQvNSkKICAgIGllIHBpdGNoID0gKHdpZHRoLzQpICogYnl0ZXMgcGVyIGJsb2NrICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBpZiAoVGhpcy0+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+cmVzb3VyY2UuaGVhcE1lbW9yeSk7CiAgICBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5ID0gTlVMTDsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKdm9pZCBjb252ZXJ0X3IzMmZfcjE2ZihCWVRFICpzcmMsIEJZVEUgKmRzdCwgRFdPUkQgcGl0Y2hfaW4sIERXT1JEIHBpdGNoX291dCwgdW5zaWduZWQgaW50IHcsIHVuc2lnbmVkIGludCBoKSB7CiAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgIGZsb2F0ICpzcmNfZjsKICAgIHVuc2lnbmVkIHNob3J0ICpkc3RfczsKCiAgICBUUkFDRSgiQ29udmVydGluZyAlZHglZCBwaXhlbHMsIHBpdGNoZXMgJWQgJWRcbiIsIHcsIGgsIHBpdGNoX2luLCBwaXRjaF9vdXQpOwogICAgZm9yKHkgPSAwOyB5IDwgaDsgeSsrKSB7CiAgICAgICAgc3JjX2YgPSAoZmxvYXQgKikgKHNyYyArIHkgKiBwaXRjaF9pbik7CiAgICAgICAgZHN0X3MgPSAodW5zaWduZWQgc2hvcnQgKikgKGRzdCArIHkgKiBwaXRjaF9vdXQpOwogICAgICAgIGZvcih4ID0gMDsgeCA8IHc7IHgrKykgewogICAgICAgICAgICBkc3Rfc1t4XSA9IGZsb2F0XzMyX3RvXzE2KHNyY19mICsgeCk7CiAgICAgICAgfQogICAgfQp9CgpzdHJ1Y3QgZDNkZm10X2NvbnZlcnRvcl9kZXNjIHsKICAgIFdJTkVEM0RGT1JNQVQgZnJvbSwgdG87CiAgICB2b2lkICgqY29udmVydCkoQllURSAqc3JjLCBCWVRFICpkc3QsIERXT1JEIHBpdGNoX2luLCBEV09SRCBwaXRjaF9vdXQsIHVuc2lnbmVkIGludCB3LCB1bnNpZ25lZCBpbnQgaCk7Cn07CgpzdHJ1Y3QgZDNkZm10X2NvbnZlcnRvcl9kZXNjIGNvbnZlcnRvcnNbXSA9IHsKICAgIHtXSU5FRDNERk1UX1IzMkYsICAgICAgIFdJTkVEM0RGTVRfUjE2RiwgICAgICAgIGNvbnZlcnRfcjMyZl9yMTZmfSwKfTsKCnN0YXRpYyBpbmxpbmUgc3RydWN0IGQzZGZtdF9jb252ZXJ0b3JfZGVzYyAqZmluZF9jb252ZXJ0b3IoV0lORUQzREZPUk1BVCBmcm9tLCBXSU5FRDNERk9STUFUIHRvKSB7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIGZvcihpID0gMDsgaSA8IChzaXplb2YoY29udmVydG9ycykgLyBzaXplb2YoY29udmVydG9yc1swXSkpOyBpKyspIHsKICAgICAgICBpZihjb252ZXJ0b3JzW2ldLmZyb20gPT0gZnJvbSAmJiBjb252ZXJ0b3JzW2ldLnRvID09IHRvKSB7CiAgICAgICAgICAgIHJldHVybiAmY29udmVydG9yc1tpXTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIHN1cmZhY2VfY29udmVydF9mb3JtYXQKICoKICogQ3JlYXRlcyBhIGR1cGxpY2F0ZSBvZiBhIHN1cmZhY2UgaW4gYSBkaWZmZXJlbnQgZm9ybWF0LiBJcyB1c2VkIGJ5IEJsdCB0bwogKiBibGl0IGJldHdlZW4gc3VyZmFjZXMgd2l0aCBkaWZmZXJlbnQgZm9ybWF0cwogKgogKiBQYXJhbWV0ZXJzCiAqICBzb3VyY2U6IFNvdXJjZSBzdXJmYWNlCiAqICBmbXQ6IFJlcXVlc3RlZCBkZXN0aW5hdGlvbiBmb3JtYXQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmYWNlX2NvbnZlcnRfZm9ybWF0KElXaW5lRDNEU3VyZmFjZUltcGwgKnNvdXJjZSwgV0lORUQzREZPUk1BVCB0b19mbXQpIHsKICAgIElXaW5lRDNEU3VyZmFjZSAqcmV0ID0gTlVMTDsKICAgIHN0cnVjdCBkM2RmbXRfY29udmVydG9yX2Rlc2MgKmNvbnY7CiAgICBXSU5FRDNETE9DS0VEX1JFQ1QgbG9ja19zcmMsIGxvY2tfZHN0OwogICAgSFJFU1VMVCBocjsKCiAgICBjb252ID0gZmluZF9jb252ZXJ0b3Ioc291cmNlLT5yZXNvdXJjZS5mb3JtYXQsIHRvX2ZtdCk7CiAgICBpZighY29udikgewogICAgICAgIEZJWE1FKCJDYW5ub3QgZmluZCBhIGNvbnZlcnNpb24gZnVuY3Rpb24gZnJvbSBmb3JtYXQgJXMgdG8gJXNcbiIsCiAgICAgICAgICAgICAgZGVidWdfZDNkZm9ybWF0KHNvdXJjZS0+cmVzb3VyY2UuZm9ybWF0KSwgZGVidWdfZDNkZm9ybWF0KHRvX2ZtdCkpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlX0NyZWF0ZVN1cmZhY2UoKElXaW5lRDNERGV2aWNlICopIHNvdXJjZS0+cmVzb3VyY2Uud2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc291cmNlLT5jdXJyZW50RGVzYy5IZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvX2ZtdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSwgIC8qIGxvY2thYmxlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUsICAvKiBkaXNjYXJkICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAgICAgLyogbGV2ZWwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFJUWVBFX1NVUkZBQ0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsICAgICAvKiB1c2FnZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEUE9PTF9TQ1JBVENILAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNETVVMVElTQU1QTEVfTk9ORSwgICAvKiBUT0RPOiBNdWx0aXNhbXBsZWQgY29udmVyc2lvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAgICAgLyogbXVsdGlzYW1wbGVxdWFsaXR5ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICAvKiBzaGFyZWRoYW5kbGUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldEltcGxUeXBlKChJV2luZUQzRFN1cmZhY2UgKikgc291cmNlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7IC8qIHBhcmVudCAqLwogICAgaWYoIXJldCkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIGRlc3RpbmF0aW9uIHN1cmZhY2UgZm9yIGNvbnZlcnNpb25cbiIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIG1lbXNldCgmbG9ja19zcmMsIDAsIHNpemVvZihsb2NrX3NyYykpOwogICAgbWVtc2V0KCZsb2NrX2RzdCwgMCwgc2l6ZW9mKGxvY2tfZHN0KSk7CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoKElXaW5lRDNEU3VyZmFjZSAqKSBzb3VyY2UsICZsb2NrX3NyYywgTlVMTCwgV0lORUQzRExPQ0tfUkVBRE9OTFkpOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGxvY2sgdGhlIHNvdXJjZSBzdXJmYWNlXG4iKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShyZXQpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QocmV0LCAmbG9ja19kc3QsIE5VTEwsIFdJTkVEM0RMT0NLX1JFQURPTkxZKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBsb2NrIHRoZSBkZXN0IHN1cmZhY2VcbiIpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KChJV2luZUQzRFN1cmZhY2UgKikgc291cmNlKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShyZXQpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGNvbnYtPmNvbnZlcnQobG9ja19zcmMucEJpdHMsIGxvY2tfZHN0LnBCaXRzLCBsb2NrX3NyYy5QaXRjaCwgbG9ja19kc3QuUGl0Y2gsCiAgICAgICAgICAgICAgICAgIHNvdXJjZS0+Y3VycmVudERlc2MuV2lkdGgsIHNvdXJjZS0+Y3VycmVudERlc2MuSGVpZ2h0KTsKCiAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChyZXQpOwogICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoKElXaW5lRDNEU3VyZmFjZSAqKSBzb3VyY2UpOwoKICAgIHJldHVybiAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBfQmx0X0NvbG9yRmlsbAogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBmaWxscyBhIG1lbW9yeSBhcmVhIHdpdGggYSBzcGVjaWZpYyBjb2xvcgogKgogKiBQYXJhbXM6CiAqICBidWY6IG1lbW9yeSBhZGRyZXNzIHRvIHN0YXJ0IGZpbGxpbmcgYXQKICogIHdpZHRoLCBoZWlnaHQ6IERpbWVuc2lvbnMgb2YgdGhlIGFyZWEgdG8gZmlsbAogKiAgYnBwOiBCaXQgZGVwdGggb2YgdGhlIHN1cmZhY2UKICogIGxQaXRjaDogcGl0Y2ggb2YgdGhlIHN1cmZhY2UKICogIGNvbG9yOiBDb2xvciB0byBmaWxsIHdpdGgKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVAogICAgICAgIF9CbHRfQ29sb3JGaWxsKEJZVEUgKmJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICBpbnQgd2lkdGgsIGludCBoZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgaW50IGJwcCwgTE9ORyBsUGl0Y2gsCiAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgY29sb3IpCnsKICAgIGludCB4LCB5OwogICAgTFBCWVRFIGZpcnN0OwoKICAgIC8qIERvIGZpcnN0IHJvdyAqLwoKI2RlZmluZSBDT0xPUkZJTExfUk9XKHR5cGUpIFwKICAgIHsgXAogICAgdHlwZSAqZCA9ICh0eXBlICopIGJ1ZjsgXAogICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIFwKICAgIGRbeF0gPSAodHlwZSkgY29sb3I7IFwKICAgIGJyZWFrOyBcCn0KICAgIHN3aXRjaChicHApCiAgICB7CiAgICAgICAgY2FzZSAxOiBDT0xPUkZJTExfUk9XKEJZVEUpCiAgICAgICAgICAgICAgICBjYXNlIDI6IENPTE9SRklMTF9ST1coV09SRCkKICAgICAgICBjYXNlIDM6CiAgICAgICAgewogICAgICAgICAgICBCWVRFICpkID0gYnVmOwogICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyxkKz0zKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkWzBdID0gKGNvbG9yICAgICkgJiAweEZGOwogICAgICAgICAgICAgICAgZFsxXSA9IChjb2xvcj4+IDgpICYgMHhGRjsKICAgICAgICAgICAgICAgIGRbMl0gPSAoY29sb3I+PjE2KSAmIDB4RkY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgNDogQ09MT1JGSUxMX1JPVyhEV09SRCkKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiQ29sb3IgZmlsbCBub3QgaW1wbGVtZW50ZWQgZm9yIGJwcCAlZCFcbiIsIGJwcCo4KTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgfQoKI3VuZGVmIENPTE9SRklMTF9ST1cKCiAgICAvKiBOb3cgY29weSBmaXJzdCByb3cgKi8KICAgIGZpcnN0ID0gYnVmOwogICAgZm9yICh5ID0gMTsgeSA8IGhlaWdodDsgeSsrKQogICAgewogICAgICAgIGJ1ZiArPSBsUGl0Y2g7CiAgICAgICAgbWVtY3B5KGJ1ZiwgZmlyc3QsIHdpZHRoICogYnBwKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpCbHQsIFNXIGVtdWxhdGlvbiB2ZXJzaW9uCiAqCiAqIFBlcmZvcm1zIGJsaXRzIHRvIGEgc3VyZmFjZSwgZWlnaGVyIGZyb20gYSBzb3VyY2Ugb2Ygc291cmNlLWxlc3MgYmx0cwogKiBUaGlzIGlzIHRoZSBtYWluIGZ1bmN0aW9uYWxpdHkgb2YgRGlyZWN0RHJhdwogKgogKiBQYXJhbXM6CiAqICBEZXN0UmVjdDogRGVzdGluYXRpb24gcmVjdGFuZ2xlIHRvIHdyaXRlIHRvCiAqICBTcmNTdXJmYWNlOiBTb3VyY2Ugc3VyZmFjZSwgY2FuIGJlIE5VTEwKICogIFNyY1JlY3Q6IFNvdXJjZSByZWN0YW5nbGUKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CbHQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKkRlc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpTcmNTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqU3JjUmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUREQkxURlggKkREQmx0RngsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgRmlsdGVyKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTcmNTdXJmYWNlOwogICAgUkVDVCAgICAgICAgeGRzdCx4c3JjOwogICAgSFJFU1VMVCAgICAgcmV0ID0gV0lORUQzRF9PSzsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCAgZGxvY2ssIHNsb2NrOwogICAgV0lORUQzREZPUk1BVCAgICAgICBkZm10ID0gV0lORUQzREZNVF9VTktOT1dOLCBzZm10ID0gV0lORUQzREZNVF9VTktOT1dOOwogICAgaW50IGJwcCwgc3JjaGVpZ2h0LCBzcmN3aWR0aCwgZHN0aGVpZ2h0LCBkc3R3aWR0aCwgd2lkdGg7CiAgICBpbnQgeCwgeTsKICAgIGNvbnN0IFN0YXRpY1BpeGVsRm9ybWF0RGVzYyAqc0VudHJ5LCAqZEVudHJ5OwogICAgTFBCWVRFIGRidWYsIHNidWY7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCV4LCVwKVxuIiwgVGhpcywgRGVzdFJlY3QsIFNyYywgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpOwoKICAgIGlmIChUUkFDRV9PTihkM2Rfc3VyZmFjZSkpCiAgICB7CiAgICAgICAgaWYgKERlc3RSZWN0KSBUUkFDRSgiXHRkZXN0cmVjdCA6JWR4JWQtJWR4JWRcbiIsCiAgICAgICAgICAgIERlc3RSZWN0LT5sZWZ0LCBEZXN0UmVjdC0+dG9wLCBEZXN0UmVjdC0+cmlnaHQsIERlc3RSZWN0LT5ib3R0b20pOwogICAgICAgIGlmIChTcmNSZWN0KSBUUkFDRSgiXHRzcmNyZWN0ICA6JWR4JWQtJWR4JWRcbiIsCiAgICAgICAgICAgIFNyY1JlY3QtPmxlZnQsIFNyY1JlY3QtPnRvcCwgU3JjUmVjdC0+cmlnaHQsIFNyY1JlY3QtPmJvdHRvbSk7CiNpZiAwCiAgICAgICAgVFJBQ0UoIlx0ZmxhZ3M6ICIpOwogICAgICAgICAgICAgICAgICAgICAgRERSQVdfZHVtcF9EREJMVChGbGFncyk7CiAgICAgICAgICAgICAgICAgICAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfRERGWCkKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRibGl0Zng6ICIpOwogICAgICAgICAgICAgICAgICAgICAgRERSQVdfZHVtcF9EREJMVEZYKEREQmx0RngtPmR3RERGWCk7CiAgICB9CiNlbmRpZgogICAgfQoKICAgIGlmICggKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSB8fCAoKFNyYyAhPSBOVUxMKSAmJiAoU3JjLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkpKQogICAgewogICAgICAgIFdBUk4oIiBTdXJmYWNlIGlzIGJ1c3ksIHJldHVybmluZyBEREVSUl9TVVJGQUNFQlVTWVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9TVVJGQUNFQlVTWTsKICAgIH0KCiAgICBpZihGaWx0ZXIgIT0gV0lORUQzRFRFWEZfTk9ORSAmJiBGaWx0ZXIgIT0gV0lORUQzRFRFWEZfUE9JTlQpIHsKICAgICAgICAvKiBDYW4gaGFwcGVuIHdoZW4gZDNkOSBhcHBzIGRvIGEgU3RyZXRjaFJlY3QgY2FsbCB3aGljaCBpc24ndCBoYW5kbGVkIGluIGdsICovCiAgICAgICAgRklYTUUoIkZpbHRlcnMgbm90IHN1cHBvcnRlZCBpbiBzb2Z0d2FyZSBibGl0XG4iKTsKICAgIH0KCiAgICBpZiAoU3JjID09IFRoaXMpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLCAmZGxvY2ssIE5VTEwsIDApOwogICAgICAgIGRmbXQgPSBUaGlzLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICAgICAgc2xvY2sgPSBkbG9jazsKICAgICAgICBzZm10ID0gZGZtdDsKICAgICAgICBzRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoc2ZtdCwgTlVMTCwgTlVMTCk7CiAgICAgICAgZEVudHJ5ID0gc0VudHJ5OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGRmbXQgPSBUaGlzLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICAgICAgZEVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KGRmbXQsIE5VTEwsIE5VTEwpOwogICAgICAgIGlmIChTcmMpCiAgICAgICAgewogICAgICAgICAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgIT0gU3JjLT5yZXNvdXJjZS5mb3JtYXQpIHsKICAgICAgICAgICAgICAgIFNyYyA9IHN1cmZhY2VfY29udmVydF9mb3JtYXQoU3JjLCBkZm10KTsKICAgICAgICAgICAgICAgIGlmKCFTcmMpIHsKICAgICAgICAgICAgICAgICAgICAvKiBUaGUgY29udiBmdW5jdGlvbiB3cml0ZXMgYSBGSVhNRSAqLwogICAgICAgICAgICAgICAgICAgIFdBUk4oIkNhbm5vdCBjb252ZXJ0IHNvdXJjZSBzdXJmYWNlIGZvcm1hdCB0byBkZXN0IGZvcm1hdFxuIik7CiAgICAgICAgICAgICAgICAgICAgZ290byByZWxlYXNlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdCgoSVdpbmVEM0RTdXJmYWNlICopIFNyYywgJnNsb2NrLCBOVUxMLCBXSU5FRDNETE9DS19SRUFET05MWSk7CiAgICAgICAgICAgIHNmbXQgPSBTcmMtPnJlc291cmNlLmZvcm1hdDsKICAgICAgICB9CiAgICAgICAgc0VudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KHNmbXQsIE5VTEwsIE5VTEwpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwgJmRsb2NrLE5VTEwsMCk7CiAgICB9CgogICAgaWYgKCFEREJsdEZ4IHx8ICEoRERCbHRGeC0+ZHdEREZYKSkgRmxhZ3MgJj0gfldJTkVEREJMVF9EREZYOwoKICAgIGlmIChzRW50cnktPmlzRm91cmNjICYmIGRFbnRyeS0+aXNGb3VyY2MpCiAgICB7CiAgICAgICAgbWVtY3B5KGRsb2NrLnBCaXRzLCBzbG9jay5wQml0cywgVGhpcy0+cmVzb3VyY2Uuc2l6ZSk7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQoKICAgIGlmIChEZXN0UmVjdCkKICAgIHsKICAgICAgICB4ZHN0ID0gKkRlc3RSZWN0OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHhkc3QudG9wICAgID0gMDsKICAgICAgICB4ZHN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICB4ZHN0LmxlZnQgICA9IDA7CiAgICAgICAgeGRzdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIH0KCiAgICBpZiAoU3JjUmVjdCkKICAgIHsKICAgICAgICB4c3JjID0gKlNyY1JlY3Q7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKFNyYykKICAgICAgICB7CiAgICAgICAgICAgIHhzcmMudG9wICAgID0gMDsKICAgICAgICAgICAgeHNyYy5ib3R0b20gPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgeHNyYy5sZWZ0ICAgPSAwOwogICAgICAgICAgICB4c3JjLnJpZ2h0ICA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIG1lbXNldCgmeHNyYywwLHNpemVvZih4c3JjKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEZpcnN0IGNoZWNrIGZvciB0aGUgdmFsaWRpdHkgb2Ygc291cmNlIC8gZGVzdGluYXRpb24gcmVjdGFuZ2xlcy4gVGhpcyB3YXMKICAgICAqIHZlcmlmaWVkIHVzaW5nIGEgdGVzdCBhcHBsaWNhdGlvbiArIGJ5IE1TRE4uCiAgICAgKi8KICAgIGlmICgoU3JjICE9IE5VTEwpICYmCiAgICAgICAgICgoeHNyYy5ib3R0b20gPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHhzcmMuYm90dG9tIDwgMCkgfHwKICAgICAgICAgKHhzcmMudG9wICAgICA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAoeHNyYy50b3AgICAgPCAwKSB8fAogICAgICAgICAoeHNyYy5sZWZ0ICAgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8ICh4c3JjLmxlZnQgICA8IDApIHx8CiAgICAgICAgICh4c3JjLnJpZ2h0ICAgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHhzcmMucmlnaHQgIDwgMCkgfHwKICAgICAgICAgKHhzcmMucmlnaHQgICA8IHhzcmMubGVmdCkgICAgICAgICAgICAgICB8fCAoeHNyYy5ib3R0b20gPCB4c3JjLnRvcCkpKQogICAgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIGdhdmUgdXMgYmFkIHNvdXJjZSByZWN0YW5nbGUgZm9yIEJsdC5cbiIpOwogICAgICAgIHJldCA9IFdJTkVEREVSUl9JTlZBTElEUkVDVDsKICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICB9CiAgICAvKiBGb3IgdGhlIERlc3RpbmF0aW9uIHJlY3QsIGl0IGNhbiBiZSBvdXQgb2YgYm91bmRzIG9uIHRoZSBjb25kaXRpb24gdGhhdCBhIGNsaXBwZXIKICAgICAqIGlzIHNldCBmb3IgdGhlIGdpdmVuIHN1cmZhY2UuCiAgICAgKi8KICAgIGlmICgoLypUaGlzLT5jbGlwcGVyID09IE5VTEwqLyBUUlVFKSAmJgogICAgICAgICAoKHhkc3QuYm90dG9tICA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHhkc3QuYm90dG9tIDwgMCkgfHwKICAgICAgICAgKHhkc3QudG9wICAgICAgPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4ZHN0LnRvcCAgICA8IDApIHx8CiAgICAgICAgICh4ZHN0LmxlZnQgICAgID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAoeGRzdC5sZWZ0ICAgPCAwKSB8fAogICAgICAgICAoeGRzdC5yaWdodCAgICA+IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHhkc3QucmlnaHQgIDwgMCkgfHwKICAgICAgICAgKHhkc3QucmlnaHQgICAgPCB4ZHN0LmxlZnQpICAgICAgICAgICAgICAgIHx8ICh4ZHN0LmJvdHRvbSA8IHhkc3QudG9wKSkpCiAgICB7CiAgICAgICAgV0FSTigiQXBwbGljYXRpb24gZ2F2ZSB1cyBiYWQgZGVzdGluYXRpb24gcmVjdGFuZ2xlIGZvciBCbHQgd2l0aG91dCBhIGNsaXBwZXIgc2V0LlxuIik7CiAgICAgICAgcmV0ID0gV0lORURERVJSX0lOVkFMSURSRUNUOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KCiAgICAvKiBOb3cgaGFuZGxlIG5lZ2F0aXZlIHZhbHVlcyBpbiB0aGUgcmVjdGFuZ2xlcy4gV2FybmluZzogb25seSBzdXBwb3J0ZWQgZm9yIG5vdwogICAgaW4gdGhlICdzaW1wbGUnIGNhc2VzIChpZSBub3QgaW4gYW55IHN0cmV0Y2hpbmcgLyByb3RhdGlvbiBjYXNlcykuCgogICAgRmlyc3QsIHRoZSBjYXNlIHdoZXJlIG5vdGhpbmcgaXMgdG8gYmUgZG9uZS4KICAgICovCiAgICBpZiAoKCh4ZHN0LmJvdHRvbSA8PSAwKSB8fCAoeGRzdC5yaWdodCA8PSAwKSAgICAgICAgIHx8CiAgICAgICAgICAoeGRzdC50b3AgICAgPj0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fAogICAgICAgICAgKHhkc3QubGVmdCAgID49IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKSkgfHwKICAgICAgICAgICgoU3JjICE9IE5VTEwpICYmCiAgICAgICAgICAoKHhzcmMuYm90dG9tIDw9IDApIHx8ICh4c3JjLnJpZ2h0IDw9IDApICAgICB8fAogICAgICAgICAgKHhzcmMudG9wID49IChpbnQpIFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fAogICAgICAgICAgKHhzcmMubGVmdCA+PSAoaW50KSBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSkgICkpCiAgICB7CiAgICAgICAgVFJBQ0UoIk5vdGhpbmcgdG8gYmUgZG9uZSAhXG4iKTsKICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICB9CgogICAgLyogVGhlIGVhc3kgY2FzZSA6IHRoZSBzb3VyY2UtbGVzcyBibGl0cy4uLi4gKi8KICAgIGlmIChTcmMgPT0gTlVMTCkKICAgIHsKICAgICAgICBSRUNUIGZ1bGxfcmVjdDsKICAgICAgICBSRUNUIHRlbXBfcmVjdDsgLyogTm8gaWRlYSBpZiBpbnRlcnNlY3QgcmVjdCBjYW4gYmUgdGhlIHNhbWUgYXMgb25lIG9mIHRoZSBzb3VyY2UgcmVjdCAqLwoKICAgICAgICBmdWxsX3JlY3QubGVmdCAgID0gMDsKICAgICAgICBmdWxsX3JlY3QudG9wICAgID0gMDsKICAgICAgICBmdWxsX3JlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgZnVsbF9yZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICBJbnRlcnNlY3RSZWN0KCZ0ZW1wX3JlY3QsICZmdWxsX3JlY3QsICZ4ZHN0KTsKICAgICAgICB4ZHN0ID0gdGVtcF9yZWN0OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qIE9ubHkgaGFuZGxlIGNsaXBwaW5nIG9uIHRoZSBkZXN0aW5hdGlvbiByZWN0YW5nbGUgKi8KICAgICAgICBpbnQgY2xpcF9ob3JpeiA9ICh4ZHN0LmxlZnQgPCAwKSB8fCAoeGRzdC5yaWdodCAgPiAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCApOwogICAgICAgIGludCBjbGlwX3ZlcnQgID0gKHhkc3QudG9wICA8IDApIHx8ICh4ZHN0LmJvdHRvbSA+IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCk7CiAgICAgICAgaWYgKGNsaXBfdmVydCB8fCBjbGlwX2hvcml6KQogICAgICAgIHsKICAgICAgICAgICAgLyogTm93IGNoZWNrIGlmIHRoaXMgaXMgYSBzcGVjaWFsIGNhc2Ugb3Igbm90Li4uICovCiAgICAgICAgICAgIGlmICgoKCh4ZHN0LmJvdHRvbSAtIHhkc3QudG9wICkgIT0gKHhzcmMuYm90dG9tIC0geHNyYy50b3AgKSkgJiYgY2xpcF92ZXJ0ICkgfHwKICAgICAgICAgICAgICAgICAgICgoKHhkc3QucmlnaHQgIC0geGRzdC5sZWZ0KSAhPSAoeHNyYy5yaWdodCAgLSB4c3JjLmxlZnQpKSAmJiBjbGlwX2hvcml6KSB8fAogICAgICAgICAgICAgICAgICAgKEZsYWdzICYgV0lORUREQkxUX0RERlgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBXQVJOKCJPdXQgb2Ygc2NyZWVuIHJlY3RhbmdsZSBpbiBzcGVjaWFsIGNhc2UuIE5vdCBoYW5kbGVkIHJpZ2h0IG5vdy5cbiIpOwogICAgICAgICAgICAgICAgZ290byByZWxlYXNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoY2xpcF9ob3JpeikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhkc3QubGVmdCA8IDApIHsgeHNyYy5sZWZ0IC09IHhkc3QubGVmdDsgeGRzdC5sZWZ0ID0gMDsgfQogICAgICAgICAgICAgICAgaWYgKHhkc3QucmlnaHQgPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4c3JjLnJpZ2h0IC09ICh4ZHN0LnJpZ2h0IC0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpOwogICAgICAgICAgICAgICAgICAgIHhkc3QucmlnaHQgPSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoY2xpcF92ZXJ0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoeGRzdC50b3AgPCAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhzcmMudG9wIC09IHhkc3QudG9wOwogICAgICAgICAgICAgICAgICAgIHhkc3QudG9wID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh4ZHN0LmJvdHRvbSA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4c3JjLmJvdHRvbSAtPSAoeGRzdC5ib3R0b20gLSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpOwogICAgICAgICAgICAgICAgICAgIHhkc3QuYm90dG9tID0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIEFuZCBjaGVjayBpZiBhZnRlciBjbGlwcGluZyBzb21ldGhpbmcgaXMgc3RpbGwgdG8gYmUgZG9uZS4uLiAqLwogICAgICAgICAgICBpZiAoKHhkc3QuYm90dG9tIDw9IDApICAgfHwgKHhkc3QucmlnaHQgPD0gMCkgICAgICAgfHwKICAgICAgICAgICAgICAgICAoeGRzdC50b3AgICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpICB8fAogICAgICAgICAgICAgICAgICh4ZHN0LmxlZnQgID49IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKSAgIHx8CiAgICAgICAgICAgICAgICAgKHhzcmMuYm90dG9tIDw9IDApICAgfHwgKHhzcmMucmlnaHQgPD0gMCkgICAgICAgfHwKICAgICAgICAgICAgICAgICAoeHNyYy50b3AgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpICAgICB8fAogICAgICAgICAgICAgICAgICh4c3JjLmxlZnQgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJOb3RoaW5nIHRvIGJlIGRvbmUgYWZ0ZXIgY2xpcHBpbmcgIVxuIik7CiAgICAgICAgICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKICAgIHNyY2hlaWdodCA9IHhzcmMuYm90dG9tIC0geHNyYy50b3A7CiAgICBzcmN3aWR0aCA9IHhzcmMucmlnaHQgLSB4c3JjLmxlZnQ7CiAgICBkc3RoZWlnaHQgPSB4ZHN0LmJvdHRvbSAtIHhkc3QudG9wOwogICAgZHN0d2lkdGggPSB4ZHN0LnJpZ2h0IC0geGRzdC5sZWZ0OwogICAgd2lkdGggPSAoeGRzdC5yaWdodCAtIHhkc3QubGVmdCkgKiBicHA7CgogICAgYXNzZXJ0KHdpZHRoIDw9IGRsb2NrLlBpdGNoKTsKCiAgICBkYnVmID0gKEJZVEUqKWRsb2NrLnBCaXRzKyh4ZHN0LnRvcCpkbG9jay5QaXRjaCkrKHhkc3QubGVmdCpicHApOwoKICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9XQUlUKQogICAgewogICAgICAgIEZsYWdzICY9IH5XSU5FRERCTFRfV0FJVDsKICAgIH0KICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9BU1lOQykKICAgIHsKICAgICAgICBzdGF0aWMgQk9PTCBkaXNwbGF5ZWQgPSBGQUxTRTsKICAgICAgICBpZiAoIWRpc3BsYXllZCkKICAgICAgICAgICAgRklYTUUoIkNhbid0IGhhbmRsZSBXSU5FRERCTFRfQVNZTkMgZmxhZyByaWdodCBub3cuXG4iKTsKICAgICAgICBkaXNwbGF5ZWQgPSBUUlVFOwogICAgICAgIEZsYWdzICY9IH5XSU5FRERCTFRfQVNZTkM7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfRE9OT1RXQUlUKQogICAgewogICAgICAgIC8qIFdJTkVEREJMVF9ET05PVFdBSVQgYXBwZWFyZWQgaW4gRFg3ICovCiAgICAgICAgc3RhdGljIEJPT0wgZGlzcGxheWVkID0gRkFMU0U7CiAgICAgICAgaWYgKCFkaXNwbGF5ZWQpCiAgICAgICAgICAgIEZJWE1FKCJDYW4ndCBoYW5kbGUgV0lORUREQkxUX0RPTk9UV0FJVCBmbGFnIHJpZ2h0IG5vdy5cbiIpOwogICAgICAgIGRpc3BsYXllZCA9IFRSVUU7CiAgICAgICAgRmxhZ3MgJj0gfldJTkVEREJMVF9ET05PVFdBSVQ7CiAgICB9CgogICAgLyogRmlyc3QsIGFsbCB0aGUgJ3NvdXJjZS1sZXNzJyBibGl0cyAqLwogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0NPTE9SRklMTCkKICAgIHsKICAgICAgICByZXQgPSBfQmx0X0NvbG9yRmlsbChkYnVmLCBkc3R3aWR0aCwgZHN0aGVpZ2h0LCBicHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGxvY2suUGl0Y2gsIEREQmx0RngtPnU1LmR3RmlsbENvbG9yKTsKICAgICAgICBGbGFncyAmPSB+V0lORUREQkxUX0NPTE9SRklMTDsKICAgIH0KCiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfREVQVEhGSUxMKQogICAgewogICAgICAgIEZJWE1FKCJEREJMVF9ERVBUSEZJTEwgbmVlZHMgdG8gYmUgaW1wbGVtZW50ZWQhXG4iKTsKICAgIH0KICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9ST1ApCiAgICB7CiAgICAgICAgLyogQ2F0Y2ggc29tZSBkZWdlbmVyYXRlIGNhc2VzIGhlcmUgKi8KICAgICAgICBzd2l0Y2goRERCbHRGeC0+ZHdST1ApCiAgICAgICAgewogICAgICAgICAgICBjYXNlIEJMQUNLTkVTUzoKICAgICAgICAgICAgICAgIHJldCA9IF9CbHRfQ29sb3JGaWxsKGRidWYsZHN0d2lkdGgsZHN0aGVpZ2h0LGJwcCxkbG9jay5QaXRjaCwwKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAweEFBMDAyOTogLyogTm8tb3AgKi8KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXSElURU5FU1M6CiAgICAgICAgICAgICAgICByZXQgPSBfQmx0X0NvbG9yRmlsbChkYnVmLGRzdHdpZHRoLGRzdGhlaWdodCxicHAsZGxvY2suUGl0Y2gsfjApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFNSQ0NPUFk6IC8qIHdlbGwsIHdlIGRvIHRoYXQgYmVsb3cgPyAqLwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIHJhc3RlciBvcDogJTA4eCAgUGF0dGVybjogJXBcbiIsIEREQmx0RngtPmR3Uk9QLCBEREJsdEZ4LT51NS5scEREU1BhdHRlcm4pOwogICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiAgICAgICAgRmxhZ3MgJj0gfldJTkVEREJMVF9ST1A7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfRERST1BTKQogICAgewogICAgICAgIEZJWE1FKCJcdERkcmF3IFJhc3RlciBPcHM6ICUwOHggIFBhdHRlcm46ICVwXG4iLCBEREJsdEZ4LT5kd0REUk9QLCBEREJsdEZ4LT51NS5scEREU1BhdHRlcm4pOwogICAgfQogICAgLyogTm93IHRoZSAnd2l0aCBzb3VyY2UnIGJsaXRzICovCiAgICBpZiAoU3JjKQogICAgewogICAgICAgIExQQllURSBzYmFzZTsKICAgICAgICBpbnQgc3gsIHhpbmMsIHN5LCB5aW5jOwoKICAgICAgICBpZiAoIWRzdHdpZHRoIHx8ICFkc3RoZWlnaHQpIC8qIGhtbS4uLiBzdHVwaWQgcHJvZ3JhbSA/ICovCiAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICBzYmFzZSA9IChCWVRFKilzbG9jay5wQml0cysoeHNyYy50b3Aqc2xvY2suUGl0Y2gpK3hzcmMubGVmdCpicHA7CiAgICAgICAgeGluYyA9IChzcmN3aWR0aCA8PCAxNikgLyBkc3R3aWR0aDsKICAgICAgICB5aW5jID0gKHNyY2hlaWdodCA8PCAxNikgLyBkc3RoZWlnaHQ7CgogICAgICAgIGlmICghRmxhZ3MpCiAgICAgICAgewogICAgICAgICAgICAvKiBObyBlZmZlY3RzLCB3ZSBjYW4gY2hlYXQgaGVyZSAqLwogICAgICAgICAgICBpZiAoZHN0d2lkdGggPT0gc3Jjd2lkdGgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChkc3RoZWlnaHQgPT0gc3JjaGVpZ2h0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIE5vIHN0cmV0Y2hpbmcgaW4gZWl0aGVyIGRpcmVjdGlvbi4gVGhpcyBuZWVkcyB0byBiZSBhcwogICAgICAgICAgICAgICAgICAgICogZmFzdCBhcyBwb3NzaWJsZSAqLwogICAgICAgICAgICAgICAgICAgIHNidWYgPSBzYmFzZTsKCiAgICAgICAgICAgICAgICAgICAgLyogY2hlY2sgZm9yIG92ZXJsYXBwaW5nIHN1cmZhY2VzICovCiAgICAgICAgICAgICAgICAgICAgaWYgKFNyYyAhPSBUaGlzIHx8IHhkc3QudG9wIDwgeHNyYy50b3AgfHwKICAgICAgICAgICAgICAgICAgICAgICAgeGRzdC5yaWdodCA8PSB4c3JjLmxlZnQgfHwgeHNyYy5yaWdodCA8PSB4ZHN0LmxlZnQpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBubyBvdmVybGFwLCBvciBkc3QgYWJvdmUgc3JjLCBzbyBjb3B5IGZyb20gdG9wIGRvd253YXJkcyAqLwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnVmICs9IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh4ZHN0LnRvcCA+IHhzcmMudG9wKSAgLyogY29weSBmcm9tIGJvdHRvbSB1cHdhcmRzICovCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzYnVmICs9IChzbG9jay5QaXRjaCpkc3RoZWlnaHQpOwogICAgICAgICAgICAgICAgICAgICAgICBkYnVmICs9IChkbG9jay5QaXRjaCpkc3RoZWlnaHQpOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgLT0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYnVmIC09IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRidWYsIHNidWYsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIC8qIHNyYyBhbmQgZHN0IG92ZXJsYXBwaW5nIG9uIHRoZSBzYW1lIGxpbmUsIHVzZSBtZW1tb3ZlICovCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyspCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbW1vdmUoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiArPSBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qIFN0cmV0Y2hpbmcgaW4gWSBkaXJlY3Rpb24gb25seSAqLwogICAgICAgICAgICAgICAgICAgIGZvciAoeSA9IHN5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrLCBzeSArPSB5aW5jKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgPSBzYmFzZSArIChzeSA+PiAxNikgKiBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRidWYsIHNidWYsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBTdHJldGNoaW5nIGluIFggZGlyZWN0aW9uICovCiAgICAgICAgICAgICAgICBpbnQgbGFzdF9zeSA9IC0xOwogICAgICAgICAgICAgICAgZm9yICh5ID0gc3kgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyssIHN5ICs9IHlpbmMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlICsgKHN5ID4+IDE2KSAqIHNsb2NrLlBpdGNoOwoKICAgICAgICAgICAgICAgICAgICBpZiAoKHN5ID4+IDE2KSA9PSAobGFzdF9zeSA+PiAxNikpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiB0aGlzIHNvdXJjZXJvdyBpcyB0aGUgc2FtZSBhcyBsYXN0IHNvdXJjZXJvdyAtCiAgICAgICAgICAgICAgICAgICAgICAgICogY29weSBhbHJlYWR5IHN0cmV0Y2hlZCByb3cKICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRidWYsIGRidWYgLSBkbG9jay5QaXRjaCwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewojZGVmaW5lIFNUUkVUQ0hfUk9XKHR5cGUpIHsgXAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlICpzID0gKHR5cGUgKikgc2J1ZiwgKmQgPSAodHlwZSAqKSBkYnVmOyBcCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IHN4ID0gMDsgeCA8IGRzdHdpZHRoOyB4KyssIHN4ICs9IHhpbmMpIFwKICAgICAgICAgICAgICAgICAgICAgICAgZFt4XSA9IHNbc3ggPj4gMTZdOyBcCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOyB9CgogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2goYnBwKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE6IFNUUkVUQ0hfUk9XKEJZVEUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjogU1RSRVRDSF9ST1coV09SRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IFNUUkVUQ0hfUk9XKERXT1JEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQllURSBzLGQgPSBkYnVmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IHN4ID0gMDsgeCA8IGRzdHdpZHRoOyB4KyssIHN4Kz0geGluYykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHBpeGVsOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHNidWYrMyooc3g+PjE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWwgPSBzWzBdfChzWzFdPDw4KXwoc1syXTw8MTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWzBdID0gKHBpeGVsICAgICkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFsxXSA9IChwaXhlbD4+IDgpJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbMl0gPSAocGl4ZWw+PjE2KSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkKz0zOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlN0cmV0Y2hlZCBibGl0IG5vdCBpbXBsZW1lbnRlZCBmb3IgYnBwICVkIVxuIiwgYnBwKjgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldCA9IFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KI3VuZGVmIFNUUkVUQ0hfUk9XCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgbGFzdF9zeSA9IHN5OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIExPTkcgZHN0eWluYyA9IGRsb2NrLlBpdGNoLCBkc3R4aW5jID0gYnBwOwogICAgICAgICAgICBEV09SRCBrZXlsb3cgPSAweEZGRkZGRkZGLCBrZXloaWdoID0gMCwga2V5bWFzayA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIERXT1JEIGRlc3RrZXlsb3cgPSAweDAsIGRlc3RrZXloaWdoID0gMHhGRkZGRkZGRiwgZGVzdGtleW1hc2sgPSAweEZGRkZGRkZGOwogICAgICAgICAgICBpZiAoRmxhZ3MgJiAoV0lORUREQkxUX0tFWVNSQyB8IFdJTkVEREJMVF9LRVlERVNUIHwgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFIHwgV0lORUREQkxUX0tFWURFU1RPVkVSUklERSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIFRoZSBjb2xvciBrZXlpbmcgZmxhZ3MgYXJlIGNoZWNrZWQgZm9yIGNvcnJlY3RuZXNzIGluIGRkcmF3ICovCiAgICAgICAgICAgICAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfS0VZU1JDKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGtleWxvdyAgPSBTcmMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgICAgICAgICAga2V5aGlnaCA9IFNyYy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfS0VZU1JDT1ZFUlJJREUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAga2V5bG93ICA9IEREQmx0RngtPmRkY2tTcmNDb2xvcmtleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZTsKICAgICAgICAgICAgICAgICAgICBrZXloaWdoID0gRERCbHRGeC0+ZGRja1NyY0NvbG9ya2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfS0VZREVTVCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBEZXN0aW5hdGlvbiBjb2xvciBrZXlzIGFyZSB0YWtlbiBmcm9tIHRoZSBzb3VyY2Ugc3VyZmFjZSAhICovCiAgICAgICAgICAgICAgICAgICAgZGVzdGtleWxvdyAgPSBTcmMtPkRlc3RCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAgICAgIGRlc3RrZXloaWdoID0gU3JjLT5EZXN0Qmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIGlmIChGbGFncyAmIFdJTkVEREJMVF9LRVlERVNUT1ZFUlJJREUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGVzdGtleWxvdyAgPSBEREJsdEZ4LT5kZGNrRGVzdENvbG9ya2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAgICAgIGRlc3RrZXloaWdoID0gRERCbHRGeC0+ZGRja0Rlc3RDb2xvcmtleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYoYnBwID09IDEpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAga2V5bWFzayA9IDB4ZmY7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAga2V5bWFzayA9IHNFbnRyeS0+cmVkTWFzayAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNFbnRyeS0+Z3JlZW5NYXNrIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNFbnRyeS0+Ymx1ZU1hc2s7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBGbGFncyAmPSB+KFdJTkVEREJMVF9LRVlTUkMgfCBXSU5FRERCTFRfS0VZREVTVCB8IFdJTkVEREJMVF9LRVlTUkNPVkVSUklERSB8IFdJTkVEREJMVF9LRVlERVNUT1ZFUlJJREUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfRERGWCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTFBCWVRFIGRUb3BMZWZ0LCBkVG9wUmlnaHQsIGRCb3R0b21MZWZ0LCBkQm90dG9tUmlnaHQsIHRtcDsKICAgICAgICAgICAgICAgIExPTkcgdG1weHk7CiAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSBkYnVmOwogICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gZGJ1ZisoKGRzdHdpZHRoLTEpKmJwcCk7CiAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSBkVG9wTGVmdCsoKGRzdGhlaWdodC0xKSpkbG9jay5QaXRjaCk7CiAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkQm90dG9tTGVmdCsoKGRzdHdpZHRoLTEpKmJwcCk7CgogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX0FSSVRIU1RSRVRDSFkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogSSBkb24ndCB0aGluayB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nIGFib3V0IHRoaXMgZmxhZyAqLwogICAgICAgICAgICAgICAgICAgIFdBUk4oIkZsYWdzPUREQkxUX0RERlggbm90aGluZyBkb25lIGZvciBXSU5FRERCTFRGWF9BUklUSFNUUkVUQ0hZXG4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9NSVJST1JMRUZUUklHSFQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcFJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IHRtcDsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gdG1wOwogICAgICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R4aW5jICotMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9NSVJST1JVUERPV04pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gdG1wOwogICAgICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gdG1wOwogICAgICAgICAgICAgICAgICAgIGRzdHlpbmMgPSBkc3R5aW5jICotMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9OT1RFQVJJTkcpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogSSBkb24ndCB0aGluayB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nIGFib3V0IHRoaXMgZmxhZyAqLwogICAgICAgICAgICAgICAgICAgIFdBUk4oIkZsYWdzPUREQkxUX0RERlggbm90aGluZyBkb25lIGZvciBXSU5FRERCTFRGWF9OT1RFQVJJTkdcbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX1JPVEFURTE4MCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gdG1wOwogICAgICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRCb3R0b21MZWZ0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSB0bXA7CiAgICAgICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHhpbmMgKiAtMTsKICAgICAgICAgICAgICAgICAgICBkc3R5aW5jID0gZHN0eWluYyAqIC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX1JPVEFURTI3MCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZFRvcFJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IHRtcDsKICAgICAgICAgICAgICAgICAgICB0bXB4eSAgID0gZHN0eGluYzsKICAgICAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eWluYzsKICAgICAgICAgICAgICAgICAgICBkc3R5aW5jID0gdG1weHk7CiAgICAgICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHhpbmMgKiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9ST1RBVEU5MCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRCb3R0b21MZWZ0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IHRtcDsKICAgICAgICAgICAgICAgICAgICB0bXB4eSAgID0gZHN0eGluYzsKICAgICAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eWluYzsKICAgICAgICAgICAgICAgICAgICBkc3R5aW5jID0gdG1weHk7CiAgICAgICAgICAgICAgICAgICAgZHN0eWluYyA9IGRzdHlpbmMgKiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9aQlVGRkVSQkFTRURFU1QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogSSBkb24ndCB0aGluayB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nIGFib3V0IHRoaXMgZmxhZyAqLwogICAgICAgICAgICAgICAgICAgIFdBUk4oIkZsYWdzPVdJTkVEREJMVF9EREZYIG5vdGhpbmcgZG9uZSBmb3IgV0lORUREQkxURlhfWkJVRkZFUkJBU0VERVNUXG4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRidWYgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgIEZsYWdzICY9IH4oV0lORUREQkxUX0RERlgpOwogICAgICAgICAgICB9CgojZGVmaW5lIENPUFlfQ09MT1JLRVlfRlgodHlwZSkgeyBcCiAgICAgICAgICAgIHR5cGUgKnMsICpkID0gKHR5cGUgKikgZGJ1ZiwgKmR4LCB0bXA7IFwKICAgICAgICAgICAgZm9yICh5ID0gc3kgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyssIHN5ICs9IHlpbmMpIHsgXAogICAgICAgICAgICBzID0gKHR5cGUqKShzYmFzZSArIChzeSA+PiAxNikgKiBzbG9jay5QaXRjaCk7IFwKICAgICAgICAgICAgZHggPSBkOyBcCiAgICAgICAgICAgIGZvciAoeCA9IHN4ID0gMDsgeCA8IGRzdHdpZHRoOyB4KyssIHN4ICs9IHhpbmMpIHsgXAogICAgICAgICAgICB0bXAgPSBzW3N4ID4+IDE2XTsgXAogICAgICAgICAgICBpZiAoKCh0bXAgJiBrZXltYXNrKSA8IGtleWxvdyB8fCAodG1wICYga2V5bWFzaykgPiBrZXloaWdoKSAmJiBcCiAgICAgICAgICAgICgoZHhbMF0gJiBkZXN0a2V5bWFzaykgPj0gZGVzdGtleWxvdyAmJiAoZHhbMF0gJiBkZXN0a2V5bWFzaykgPD0gZGVzdGtleWhpZ2gpKSB7IFwKICAgICAgICAgICAgZHhbMF0gPSB0bXA7IFwKICAgICAgICB9IFwKICAgICAgICAgICAgZHggPSAodHlwZSopKCgoTFBCWVRFKWR4KStkc3R4aW5jKTsgXAogICAgICAgIH0gXAogICAgICAgICAgICBkID0gKHR5cGUqKSgoKExQQllURSlkKStkc3R5aW5jKTsgXAogICAgICAgIH0gXAogICAgICAgICAgICBicmVhazsgfQoKICAgICAgICAgICAgc3dpdGNoIChicHApIHsKICAgICAgICAgICAgICAgIGNhc2UgMTogQ09QWV9DT0xPUktFWV9GWChCWVRFKQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IENPUFlfQ09MT1JLRVlfRlgoV09SRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IENPUFlfQ09MT1JLRVlfRlgoRFdPUkQpCiAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTFBCWVRFIHMsZCA9IGRidWYsIGR4OwogICAgICAgICAgICAgICAgICAgIGZvciAoeSA9IHN5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrLCBzeSArPSB5aW5jKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlICsgKHN5ID4+IDE2KSAqIHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICBkeCA9IGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IHN4ID0gMDsgeCA8IGRzdHdpZHRoOyB4KyssIHN4Kz0geGluYykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgcGl4ZWwsIGRwaXhlbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gc2J1ZiszKihzeD4+MTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl4ZWwgPSBzWzBdfChzWzFdPDw4KXwoc1syXTw8MTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBpeGVsID0gZHhbMF18KGR4WzFdPDw4KXwoZHhbMl08PDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoKHBpeGVsICYga2V5bWFzaykgPCBrZXlsb3cgfHwgKHBpeGVsICYga2V5bWFzaykgPiBrZXloaWdoKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChkcGl4ZWwgJiBrZXltYXNrKSA+PSBkZXN0a2V5bG93IHx8IChkcGl4ZWwgJiBrZXltYXNrKSA8PSBrZXloaWdoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeFswXSA9IChwaXhlbCAgICApJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHhbMV0gPSAocGl4ZWw+PiA4KSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4WzJdID0gKHBpeGVsPj4xNikmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4Kz0gZHN0eGluYzsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBkICs9IGRzdHlpbmM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiJXMgY29sb3Ita2V5ZWQgYmxpdCBub3QgaW1wbGVtZW50ZWQgZm9yIGJwcCAlZCFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKEZsYWdzICYgV0lORUREQkxUX0tFWVNSQykgPyAiU291cmNlIiA6ICJEZXN0aW5hdGlvbiIsIGJwcCo4KTsKICAgICAgICAgICAgICAgICAgICByZXQgPSBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwojdW5kZWYgQ09QWV9DT0xPUktFWV9GWAogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKZXJyb3I6CiAgICBpZiAoRmxhZ3MgJiYgRklYTUVfT04oZDNkX3N1cmZhY2UpKQogICAgewogICAgICAgIEZJWE1FKCJcdFVuc3VwcG9ydGVkIGZsYWdzOiAlMDh4XG4iLCBGbGFncyk7CiAgICB9CgpyZWxlYXNlOgogICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwogICAgaWYgKFNyYyAmJiBTcmMgIT0gVGhpcykgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMpOwogICAgLyogUmVsZWFzZSB0aGUgY29udmVydGVkIHN1cmZhY2UgaWYgYW55ICovCiAgICBpZiAoU3JjICYmIFNyY1N1cmZhY2UgIT0gKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMpIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKChJV2luZUQzRFN1cmZhY2UgKikgU3JjKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRFN1cmZhY2U6OkJsdEZhc3QsIFNXIGVtdWxhdGlvbiB2ZXJzaW9uCiAqCiAqIFRoaXMgaXMgdGhlIHNvZnR3YXJlIGltcGxlbWVudGF0aW9uIG9mIEJsdEZhc3QsIGFzIHVzZWQgYnkgR0RJIHN1cmZhY2VzCiAqIGFuZCBhcyBhIGZhbGxiYWNrIGZvciBPcGVuR0wgc3VyZmFjZXMuIFRoaXMgY29kZSBpcyB0YWtlbiBmcm9tIHRoZSBvbGQKICogRGlyZWN0RHJhdyBjb2RlLCBhbmQgd2FzIG9yaWdpbmFsbHkgd3JpdHRlbiBieSBUcmFuc0dhbWluZy4KICoKICogUGFyYW1zOgogKiAgZHN0eDoKICogIGRzdHk6CiAqICBTb3VyY2U6IFNvdXJjZSBzdXJmYWNlIHRvIGNvcHkgZnJvbQogKiAgcnNyYzogU291cmNlIHJlY3RhbmdsZQogKiAgdHJhbnM6IFNvbWUgRmxhZ3MKICoKICogUmV0dXJuczoKICogIFdJTkVEM0RfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCklXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0JsdEZhc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkc3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGRzdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpTb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqcnNyYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCB0cmFucykKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqU3JjID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgU291cmNlOwoKICAgIGludCAgICAgICAgICAgICAgICAgYnBwLCB3LCBoLCB4LCB5OwogICAgV0lORUQzRExPQ0tFRF9SRUNUICBkbG9jayxzbG9jazsKICAgIEhSRVNVTFQgICAgICAgICAgICAgcmV0ID0gV0lORUQzRF9PSzsKICAgIFJFQ1QgICAgICAgICAgICAgICAgcnNyYzI7CiAgICBSRUNUICAgICAgICAgICAgICAgIGxvY2tfc3JjLCBsb2NrX2RzdCwgbG9ja191bmlvbjsKICAgIEJZVEUgICAgICAgICAgICAgICAgKnNidWYsICpkYnVmOwogICAgY29uc3QgU3RhdGljUGl4ZWxGb3JtYXREZXNjICpzRW50cnksICpkRW50cnk7CgogICAgaWYgKFRSQUNFX09OKGQzZF9zdXJmYWNlKSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKS0+KCVkLCVkLCVwLCVwLCUwOHgpXG4iLCBUaGlzLGRzdHgsZHN0eSxTcmMscnNyYyx0cmFucyk7CgogICAgICAgIGlmIChyc3JjKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIlx0c3JjcmVjdDogJWR4JWQtJWR4JWRcbiIscnNyYy0+bGVmdCxyc3JjLT50b3AsCiAgICAgICAgICAgICAgICAgIHJzcmMtPnJpZ2h0LHJzcmMtPmJvdHRvbSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIgc3JjcmVjdDogTlVMTFxuIik7CiAgICAgICAgfQogICAgfQoKICAgIGlmICgoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpIHx8CiAgICAgICAgICgoU3JjICE9IE5VTEwpICYmIChTcmMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSkpCiAgICB7CiAgICAgICAgV0FSTigiIFN1cmZhY2UgaXMgYnVzeSwgcmV0dXJuaW5nIERERVJSX1NVUkZBQ0VCVVNZXG4iKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX1NVUkZBQ0VCVVNZOwogICAgfQoKICAgIGlmICghcnNyYykKICAgIHsKICAgICAgICBXQVJOKCJyc3JjIGlzIE5VTEwhXG4iKTsKICAgICAgICByc3JjID0gJnJzcmMyOwogICAgICAgIHJzcmMtPmxlZnQgPSAwOwogICAgICAgIHJzcmMtPnRvcCA9IDA7CiAgICAgICAgcnNyYy0+cmlnaHQgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHJzcmMtPmJvdHRvbSA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgfQoKICAgIC8qIENoZWNrIHNvdXJjZSByZWN0IGZvciB2YWxpZGl0eS4gQ29waWVkIGZyb20gbm9ybWFsIEJsdC4gRml4ZXMgQmFsZHVyJ3MgR2F0ZS4qLwogICAgaWYgKChyc3JjLT5ib3R0b20gPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHJzcmMtPmJvdHRvbSA8IDApIHx8CiAgICAgICAgIChyc3JjLT50b3AgICAgPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHJzcmMtPnRvcCAgICA8IDApIHx8CiAgICAgICAgIChyc3JjLT5sZWZ0ICAgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHJzcmMtPmxlZnQgICA8IDApIHx8CiAgICAgICAgIChyc3JjLT5yaWdodCAgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHJzcmMtPnJpZ2h0ICA8IDApIHx8CiAgICAgICAgIChyc3JjLT5yaWdodCAgPCByc3JjLT5sZWZ0KSAgICAgICAgICAgICAgfHwgKHJzcmMtPmJvdHRvbSA8IHJzcmMtPnRvcCkpCiAgICB7CiAgICAgICAgV0FSTigiQXBwbGljYXRpb24gZ2F2ZSB1cyBiYWQgc291cmNlIHJlY3RhbmdsZSBmb3IgQmx0RmFzdC5cbiIpOwogICAgICAgIHJldHVybiBXSU5FRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICB9CgogICAgaCA9IHJzcmMtPmJvdHRvbSAtIHJzcmMtPnRvcDsKICAgIGlmIChoID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LWRzdHkpIGggPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQtZHN0eTsKICAgIGlmIChoID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQtcnNyYy0+dG9wKSBoPVNyYy0+Y3VycmVudERlc2MuSGVpZ2h0LXJzcmMtPnRvcDsKICAgIGlmIChoIDw9IDApIHJldHVybiBXSU5FRERFUlJfSU5WQUxJRFJFQ1Q7CgogICAgdyA9IHJzcmMtPnJpZ2h0IC0gcnNyYy0+bGVmdDsKICAgIGlmICh3ID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgtZHN0eCkgdyA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLWRzdHg7CiAgICBpZiAodyA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgtcnNyYy0+bGVmdCkgdyA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGgtcnNyYy0+bGVmdDsKICAgIGlmICh3IDw9IDApIHJldHVybiBXSU5FRERFUlJfSU5WQUxJRFJFQ1Q7CgogICAgLyogTm93IGNvbXB1dGUgdGhlIGxvY2tpbmcgcmVjdGFuZ2xlLi4uICovCiAgICBsb2NrX3NyYy5sZWZ0ID0gcnNyYy0+bGVmdDsKICAgIGxvY2tfc3JjLnRvcCA9IHJzcmMtPnRvcDsKICAgIGxvY2tfc3JjLnJpZ2h0ID0gbG9ja19zcmMubGVmdCArIHc7CiAgICBsb2NrX3NyYy5ib3R0b20gPSBsb2NrX3NyYy50b3AgKyBoOwoKICAgIGxvY2tfZHN0LmxlZnQgPSBkc3R4OwogICAgbG9ja19kc3QudG9wID0gZHN0eTsKICAgIGxvY2tfZHN0LnJpZ2h0ID0gZHN0eCArIHc7CiAgICBsb2NrX2RzdC5ib3R0b20gPSBkc3R5ICsgaDsKCiAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwoKICAgIC8qIFdlIG5lZWQgdG8gbG9jayB0aGUgc3VyZmFjZXMsIG9yIHdlIHdvbid0IGdldCByZWZyZXNoZXMgd2hlbiBkb25lLiAqLwogICAgaWYgKFNyYyA9PSBUaGlzKQogICAgewogICAgICAgIGludCBwaXRjaDsKCiAgICAgICAgVW5pb25SZWN0KCZsb2NrX3VuaW9uLCAmbG9ja19zcmMsICZsb2NrX2RzdCk7CgogICAgICAgIC8qIExvY2sgdGhlIHVuaW9uIG9mIHRoZSB0d28gcmVjdGFuZ2xlcyAqLwogICAgICAgIHJldCA9IElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwgJmRsb2NrLCAmbG9ja191bmlvbiwgMCk7CiAgICAgICAgaWYocmV0ICE9IFdJTkVEM0RfT0spIGdvdG8gZXJyb3I7CgogICAgICAgIHBpdGNoID0gZGxvY2suUGl0Y2g7CiAgICAgICAgc2xvY2suUGl0Y2ggPSBkbG9jay5QaXRjaDsKCiAgICAgICAgLyogU2luY2Ugc2xvY2sgd2FzIG9yaWdpbmFsbHkgY29waWVkIGZyb20gdGhpcyBzdXJmYWNlJ3MgZGVzY3JpcHRpb24sIHdlIGNhbiBqdXN0IHJldXNlIGl0ICovCiAgICAgICAgYXNzZXJ0KFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSAhPSBOVUxMKTsKICAgICAgICBzYnVmID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgbG9ja19zcmMudG9wICogcGl0Y2ggKyBsb2NrX3NyYy5sZWZ0ICogYnBwOwogICAgICAgIGRidWYgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyBsb2NrX2RzdC50b3AgKiBwaXRjaCArIGxvY2tfZHN0LmxlZnQgKiBicHA7CiAgICAgICAgc0VudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFNyYy0+cmVzb3VyY2UuZm9ybWF0LCBOVUxMLCBOVUxMKTsKICAgICAgICBkRW50cnkgPSBzRW50cnk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgcmV0ID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KFNvdXJjZSwgJnNsb2NrLCAmbG9ja19zcmMsIFdJTkVEM0RMT0NLX1JFQURPTkxZKTsKICAgICAgICBpZihyZXQgIT0gV0lORUQzRF9PSykgZ290byBlcnJvcjsKICAgICAgICByZXQgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsICZkbG9jaywgJmxvY2tfZHN0LCAwKTsKICAgICAgICBpZihyZXQgIT0gV0lORUQzRF9PSykgZ290byBlcnJvcjsKCiAgICAgICAgc2J1ZiA9IHNsb2NrLnBCaXRzOwogICAgICAgIGRidWYgPSBkbG9jay5wQml0czsKICAgICAgICBUUkFDRSgiRHN0IGlzIGF0ICVwLCBTcmMgaXMgYXQgJXBcbiIsIGRidWYsIHNidWYpOwoKICAgICAgICBzRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoU3JjLT5yZXNvdXJjZS5mb3JtYXQsIE5VTEwsIE5VTEwpOwogICAgICAgIGRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQsIE5VTEwsIE5VTEwpOwogICAgfQoKICAgIC8qIEhhbmRsZSBmaXJzdCB0aGUgRk9VUkNDIHN1cmZhY2VzLi4uICovCiAgICBpZiAoc0VudHJ5LT5pc0ZvdXJjYyAmJiBkRW50cnktPmlzRm91cmNjKQogICAgewogICAgICAgIFRSQUNFKCJGb3VyY2MgLT4gRm91cmNjIGNvcHlcbiIpOwogICAgICAgIGlmICh0cmFucykKICAgICAgICAgICAgRklYTUUoInRyYW5zIGFyZyBub3Qgc3VwcG9ydGVkIHdoZW4gYSBGT1VSQ0Mgc3VyZmFjZSBpcyBpbnZvbHZlZFxuIik7CiAgICAgICAgaWYgKGRzdHggfHwgZHN0eSkKICAgICAgICAgICAgRklYTUUoIm9mZnNldCBmb3IgZGVzdGluYXRpb24gc3VyZmFjZSBpcyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgICAgICBpZiAoU3JjLT5yZXNvdXJjZS5mb3JtYXQgIT0gVGhpcy0+cmVzb3VyY2UuZm9ybWF0KQogICAgICAgIHsKICAgICAgICAgICAgRklYTUUoIkZPVVJDQy0+Rk9VUkNDIGNvcHkgb25seSBzdXBwb3J0ZWQgZm9yIHRoZSBzYW1lIHR5cGUgb2Ygc3VyZmFjZVxuIik7CiAgICAgICAgICAgIHJldCA9IFdJTkVEM0RFUlJfV1JPTkdURVhUVVJFRk9STUFUOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgICAgICAvKiBGSVhNRTogV2F0Y2ggb3V0IHRoYXQgdGhlIHNpemUgaXMgY29ycmVjdCBmb3IgRk9VUkNDIHN1cmZhY2VzICovCiAgICAgICAgbWVtY3B5KGRidWYsIHNidWYsIFRoaXMtPnJlc291cmNlLnNpemUpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICBpZiAoc0VudHJ5LT5pc0ZvdXJjYyAmJiAhZEVudHJ5LT5pc0ZvdXJjYykKICAgIHsKICAgICAgICAvKiBUT0RPOiBVc2UgdGhlIGxpYnR4Y19keHRuLnNvIHNoYXJlZCBsaWJyYXJ5IHRvIGRvCiAgICAgICAgICogc29mdHdhcmUgZGVjb21wcmVzc2lvbgogICAgICAgICAqLwogICAgICAgIEVSUigiRFhUQyBkZWNvbXByZXNzaW9uIG5vdCBzdXBwb3J0ZWQgYnkgbm93XG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIGlmICh0cmFucyAmIChXSU5FRERCTFRGQVNUX1NSQ0NPTE9SS0VZIHwgV0lORUREQkxURkFTVF9ERVNUQ09MT1JLRVkpKQogICAgewogICAgICAgIERXT1JEIGtleWxvdywga2V5aGlnaDsKICAgICAgICBUUkFDRSgiQ29sb3Iga2V5ZWQgY29weVxuIik7CiAgICAgICAgaWYgKHRyYW5zICYgV0lORUREQkxURkFTVF9TUkNDT0xPUktFWSkKICAgICAgICB7CiAgICAgICAgICAgIGtleWxvdyAgPSBTcmMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgIGtleWhpZ2ggPSBTcmMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBJJ20gbm90IHN1cmUgaWYgdGhpcyBpcyBjb3JyZWN0ICovCiAgICAgICAgICAgIEZJWE1FKCJXSU5FRERCTFRGQVNUX0RFU1RDT0xPUktFWSBub3QgZnVsbHkgc3VwcG9ydGVkIHlldC5cbiIpOwogICAgICAgICAgICBrZXlsb3cgID0gVGhpcy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgIGtleWhpZ2ggPSBUaGlzLT5EZXN0Qmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgfQoKI2RlZmluZSBDT1BZQk9YX0NPTE9SS0VZKHR5cGUpIHsgXAogICAgICAgIHR5cGUgKmQsICpzLCB0bXA7IFwKICAgICAgICBzID0gKHR5cGUgKikgc2J1ZjsgXAogICAgICAgIGQgPSAodHlwZSAqKSBkYnVmOyBcCiAgICAgICAgZm9yICh5ID0gMDsgeSA8IGg7IHkrKykgeyBcCiAgICAgICAgZm9yICh4ID0gMDsgeCA8IHc7IHgrKykgeyBcCiAgICAgICAgdG1wID0gc1t4XTsgXAogICAgICAgIGlmICh0bXAgPCBrZXlsb3cgfHwgdG1wID4ga2V5aGlnaCkgZFt4XSA9IHRtcDsgXAogICAgfSBcCiAgICAgICAgcyA9ICh0eXBlICopKChCWVRFICopcyArIHNsb2NrLlBpdGNoKTsgXAogICAgICAgIGQgPSAodHlwZSAqKSgoQllURSAqKWQgKyBkbG9jay5QaXRjaCk7IFwKICAgIH0gXAogICAgICAgIGJyZWFrOyBcCiAgICB9CgogICAgICAgIHN3aXRjaCAoYnBwKSB7CiAgICAgICAgICAgIGNhc2UgMTogQ09QWUJPWF9DT0xPUktFWShCWVRFKQogICAgICAgICAgICAgICAgICAgIGNhc2UgMjogQ09QWUJPWF9DT0xPUktFWShXT1JEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiBDT1BZQk9YX0NPTE9SS0VZKERXT1JEKQogICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEJZVEUgKmQsICpzOwogICAgICAgICAgICAgICAgRFdPUkQgdG1wOwogICAgICAgICAgICAgICAgcyA9IHNidWY7CiAgICAgICAgICAgICAgICBkID0gZGJ1ZjsKICAgICAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyB5KyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHcgKiAzOyB4ICs9IDMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSAoRFdPUkQpc1t4XSArICgoRFdPUkQpc1t4ICsgMV0gPDwgOCkgKyAoKERXT1JEKXNbeCArIDJdIDw8IDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRtcCA8IGtleWxvdyB8fCB0bXAgPiBrZXloaWdoKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkW3ggKyAwXSA9IHNbeCArIDBdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZFt4ICsgMV0gPSBzW3ggKyAxXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbeCArIDJdID0gc1t4ICsgMl07CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcyArPSBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICBkICs9IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEZJWE1FKCJTb3VyY2UgY29sb3Iga2V5IGJsaXR0aW5nIG5vdCBzdXBwb3J0ZWQgZm9yIGJwcCAlZFxuIixicHAqOCk7CiAgICAgICAgICAgICAgICByZXQgPSBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQojdW5kZWYgQ09QWUJPWF9DT0xPUktFWQogICAgICAgIFRSQUNFKCJDb3B5IERvbmVcbiIpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGludCB3aWR0aCA9IHcgKiBicHA7CiAgICAgICAgSU5UIHNidWZwaXRjaCwgZGJ1ZnBpdGNoOwoKICAgICAgICBUUkFDRSgiTk8gY29sb3Iga2V5IGNvcHlcbiIpOwogICAgICAgIC8qIEhhbmRsZSBvdmVybGFwcGluZyBzdXJmYWNlcyAqLwogICAgICAgIGlmIChzYnVmIDwgZGJ1ZikKICAgICAgICB7CiAgICAgICAgICAgIHNidWYgKz0gKGggLSAxKSAqIHNsb2NrLlBpdGNoOwogICAgICAgICAgICBkYnVmICs9IChoIC0gMSkgKiBkbG9jay5QaXRjaDsKICAgICAgICAgICAgc2J1ZnBpdGNoID0gLXNsb2NrLlBpdGNoOwogICAgICAgICAgICBkYnVmcGl0Y2ggPSAtZGxvY2suUGl0Y2g7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHNidWZwaXRjaCA9IHNsb2NrLlBpdGNoOwogICAgICAgICAgICBkYnVmcGl0Y2ggPSBkbG9jay5QaXRjaDsKICAgICAgICB9CiAgICAgICAgZm9yICh5ID0gMDsgeSA8IGg7IHkrKykKICAgICAgICB7CiAgICAgICAgICAgIC8qIFRoaXMgaXMgcHJldHR5IGVhc3ksIGEgbGluZSBmb3IgbGluZSBtZW1jcHkgKi8KICAgICAgICAgICAgbWVtbW92ZShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgIHNidWYgKz0gc2J1ZnBpdGNoOwogICAgICAgICAgICBkYnVmICs9IGRidWZwaXRjaDsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkNvcHkgZG9uZVxuIik7CiAgICB9CgplcnJvcjoKICAgIGlmIChTcmMgPT0gVGhpcykKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChpZmFjZSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KFNvdXJjZSk7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfTG9ja1JlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzRExPQ0tFRF9SRUNUKiBwTG9ja2VkUmVjdCwgQ09OU1QgUkVDVCogcFJlY3QsIERXT1JEIEZsYWdzKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IHJlY3RAJXAgZmxhZ3MoJTA4eCksIG91dHB1dCBsb2NrZWRSZWN0QCVwLCBtZW1vcnlAJXBcbiIsCiAgICAgICAgICBUaGlzLCBwUmVjdCwgRmxhZ3MsIHBMb2NrZWRSZWN0LCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwoKICAgIHBMb2NrZWRSZWN0LT5QaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CgogICAgaWYgKE5VTEwgPT0gcFJlY3QpCiAgICB7CiAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QubGVmdCAgID0gMDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnRvcCAgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKCiAgICAgICAgVFJBQ0UoIkxvY2tlZCBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLAogICAgICAgICAgICAgICZUaGlzLT5sb2NrZWRSZWN0LCBUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIFRoaXMtPmxvY2tlZFJlY3QudG9wLAogICAgICAgICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQsIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBUUkFDRSgiTG9jayBSZWN0ICglcCkgPSBsICVkLCB0ICVkLCByICVkLCBiICVkXG4iLAogICAgICAgICAgICAgIHBSZWN0LCBwUmVjdC0+bGVmdCwgcFJlY3QtPnRvcCwgcFJlY3QtPnJpZ2h0LCBwUmVjdC0+Ym90dG9tKTsKCiAgICAgICAgLyogRFhUbiB0ZXh0dXJlcyBhcmUgYmFzZWQgb24gY29tcHJlc3NlZCBibG9ja3Mgb2YgNHg0IHBpeGVscywgZWFjaAogICAgICAgICAqIDE2IGJ5dGVzIGxhcmdlICg4IGJ5dGVzIGluIGNhc2Ugb2YgRFhUMSkuIEJlY2F1c2Ugb2YgdGhhdCBQaXRjaCBoYXMKICAgICAgICAgKiBzbGlnaHRseSBkaWZmZXJlbnQgbWVhbmluZyBjb21wYXJlZCB0byByZWd1bGFyIHRleHR1cmVzLiBGb3IgRFhUbgogICAgICAgICAqIHRleHR1cmVzIFBpdGNoIGlzIHRoZSBzaXplIG9mIGEgcm93IG9mIGJsb2NrcywgNCBoaWdoIGFuZCAid2lkdGgiCiAgICAgICAgICogbG9uZy4gVGhlIHggb2Zmc2V0IGlzIGNhbGN1bGF0ZWQgZGlmZmVyZW50bHkgYXMgd2VsbCwgc2luY2UgbW92aW5nIDQKICAgICAgICAgKiBwaXhlbHMgdG8gdGhlIHJpZ2h0IGFjdHVhbGx5IG1vdmVzIGFuIGVudGlyZSA0eDQgYmxvY2sgdG8gcmlnaHQsIGllCiAgICAgICAgICogMTYgYnl0ZXMgKDggaW4gY2FzZSBvZiBEWFQxKS4gKi8KICAgICAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkKICAgICAgICB7CiAgICAgICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiBwUmVjdC0+dG9wIC8gNCkgKyAocFJlY3QtPmxlZnQgKiAyKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KQogICAgICAgIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIHBSZWN0LT50b3AgLyA0KSArIChwUmVjdC0+bGVmdCAqIDQpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKwogICAgICAgICAgICAgICAgICAgIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiBwUmVjdC0+dG9wKSArCiAgICAgICAgICAgICAgICAgICAgKHBSZWN0LT5sZWZ0ICogVGhpcy0+Ynl0ZXNQZXJQaXhlbCk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QubGVmdCAgID0gcFJlY3QtPmxlZnQ7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSBwUmVjdC0+dG9wOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gcFJlY3QtPnJpZ2h0OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tID0gcFJlY3QtPmJvdHRvbTsKICAgIH0KCiAgICAvKiBObyBkaXJ0aWZ5aW5nIGlzIG5lZWRlZCBmb3IgdGhpcyBzdXJmYWNlIGltcGxlbWVudGF0aW9uICovCiAgICBUUkFDRSgicmV0dXJuaW5nIG1lbW9yeUAlcCwgcGl0Y2goJWQpXG4iLCBwTG9ja2VkUmVjdC0+cEJpdHMsIHBMb2NrZWRSZWN0LT5QaXRjaCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnZvaWQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0JpbmRUZXh0dXJlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIEVSUigiU2hvdWxkIG5vdCBiZSBjYWxsZWQgb24gYmFzZSB0ZXh0dXJlXG4iKTsKICAgIHJldHVybjsKfQo=