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+cmVzb3VyY2Uuc2l6ZSk7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQoKICAgIGlmIChEZXN0UmVjdCkKICAgIHsKICAgICAgICBtZW1jcHkoJnhkc3QsRGVzdFJlY3Qsc2l6ZW9mKHhkc3QpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICB4ZHN0LnRvcCAgICA9IDA7CiAgICAgICAgeGRzdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgeGRzdC5sZWZ0ICAgPSAwOwogICAgICAgIHhkc3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICB9CgogICAgaWYgKFNyY1JlY3QpCiAgICB7CiAgICAgICAgbWVtY3B5KCZ4c3JjLFNyY1JlY3Qsc2l6ZW9mKHhzcmMpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoU3JjKQogICAgICAgIHsKICAgICAgICAgICAgeHNyYy50b3AgICAgPSAwOwogICAgICAgICAgICB4c3JjLmJvdHRvbSA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICB4c3JjLmxlZnQgICA9IDA7CiAgICAgICAgICAgIHhzcmMucmlnaHQgID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgbWVtc2V0KCZ4c3JjLDAsc2l6ZW9mKHhzcmMpKTsKICAgICAgICB9CiAgICB9CgogICAgLyogRmlyc3QgY2hlY2sgZm9yIHRoZSB2YWxpZGl0eSBvZiBzb3VyY2UgLyBkZXN0aW5hdGlvbiByZWN0YW5nbGVzLiBUaGlzIHdhcwogICAgICogdmVyaWZpZWQgdXNpbmcgYSB0ZXN0IGFwcGxpY2F0aW9uICsgYnkgTVNETi4KICAgICAqLwogICAgaWYgKChTcmMgIT0gTlVMTCkgJiYKICAgICAgICAgKCh4c3JjLmJvdHRvbSA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAoeHNyYy5ib3R0b20gPCAwKSB8fAogICAgICAgICAoeHNyYy50b3AgICAgID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4c3JjLnRvcCAgICA8IDApIHx8CiAgICAgICAgICh4c3JjLmxlZnQgICAgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHhzcmMubGVmdCAgIDwgMCkgfHwKICAgICAgICAgKHhzcmMucmlnaHQgICA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAoeHNyYy5yaWdodCAgPCAwKSB8fAogICAgICAgICAoeHNyYy5yaWdodCAgIDwgeHNyYy5sZWZ0KSAgICAgICAgICAgICAgIHx8ICh4c3JjLmJvdHRvbSA8IHhzcmMudG9wKSkpCiAgICB7CiAgICAgICAgV0FSTigiQXBwbGljYXRpb24gZ2F2ZSB1cyBiYWQgc291cmNlIHJlY3RhbmdsZSBmb3IgQmx0LlxuIik7CiAgICAgICAgcmV0ID0gV0lORURERVJSX0lOVkFMSURSRUNUOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KICAgIC8qIEZvciB0aGUgRGVzdGluYXRpb24gcmVjdCwgaXQgY2FuIGJlIG91dCBvZiBib3VuZHMgb24gdGhlIGNvbmRpdGlvbiB0aGF0IGEgY2xpcHBlcgogICAgICogaXMgc2V0IGZvciB0aGUgZ2l2ZW4gc3VyZmFjZS4KICAgICAqLwogICAgaWYgKCgvKlRoaXMtPmNsaXBwZXIgPT0gTlVMTCovIFRSVUUpICYmCiAgICAgICAgICgoeGRzdC5ib3R0b20gID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAoeGRzdC5ib3R0b20gPCAwKSB8fAogICAgICAgICAoeGRzdC50b3AgICAgICA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHhkc3QudG9wICAgIDwgMCkgfHwKICAgICAgICAgKHhkc3QubGVmdCAgICAgPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8ICh4ZHN0LmxlZnQgICA8IDApIHx8CiAgICAgICAgICh4ZHN0LnJpZ2h0ICAgID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAoeGRzdC5yaWdodCAgPCAwKSB8fAogICAgICAgICAoeGRzdC5yaWdodCAgICA8IHhkc3QubGVmdCkgICAgICAgICAgICAgICAgfHwgKHhkc3QuYm90dG9tIDwgeGRzdC50b3ApKSkKICAgIHsKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiBnYXZlIHVzIGJhZCBkZXN0aW5hdGlvbiByZWN0YW5nbGUgZm9yIEJsdCB3aXRob3V0IGEgY2xpcHBlciBzZXQuXG4iKTsKICAgICAgICByZXQgPSBXSU5FRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQoKICAgIC8qIE5vdyBoYW5kbGUgbmVnYXRpdmUgdmFsdWVzIGluIHRoZSByZWN0YW5nbGVzLiBXYXJuaW5nOiBvbmx5IHN1cHBvcnRlZCBmb3Igbm93CiAgICBpbiB0aGUgJ3NpbXBsZScgY2FzZXMgKGllIG5vdCBpbiBhbnkgc3RyZXRjaGluZyAvIHJvdGF0aW9uIGNhc2VzKS4KCiAgICBGaXJzdCwgdGhlIGNhc2Ugd2hlcmUgbm90aGluZyBpcyB0byBiZSBkb25lLgogICAgKi8KICAgIGlmICgoKHhkc3QuYm90dG9tIDw9IDApIHx8ICh4ZHN0LnJpZ2h0IDw9IDApICAgICAgICAgfHwKICAgICAgICAgICh4ZHN0LnRvcCAgICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8CiAgICAgICAgICAoeGRzdC5sZWZ0ICAgPj0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpKSB8fAogICAgICAgICAgKChTcmMgIT0gTlVMTCkgJiYKICAgICAgICAgICgoeHNyYy5ib3R0b20gPD0gMCkgfHwgKHhzcmMucmlnaHQgPD0gMCkgICAgIHx8CiAgICAgICAgICAoeHNyYy50b3AgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8CiAgICAgICAgICAoeHNyYy5sZWZ0ID49IChpbnQpIFNyYy0+Y3VycmVudERlc2MuV2lkdGgpKSAgKSkKICAgIHsKICAgICAgICBUUkFDRSgiTm90aGluZyB0byBiZSBkb25lICFcbiIpOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KCiAgICAvKiBUaGUgZWFzeSBjYXNlIDogdGhlIHNvdXJjZS1sZXNzIGJsaXRzLi4uLiAqLwogICAgaWYgKFNyYyA9PSBOVUxMKQogICAgewogICAgICAgIFJFQ1QgZnVsbF9yZWN0OwogICAgICAgIFJFQ1QgdGVtcF9yZWN0OyAvKiBObyBpZGVhIGlmIGludGVyc2VjdCByZWN0IGNhbiBiZSB0aGUgc2FtZSBhcyBvbmUgb2YgdGhlIHNvdXJjZSByZWN0ICovCgogICAgICAgIGZ1bGxfcmVjdC5sZWZ0ICAgPSAwOwogICAgICAgIGZ1bGxfcmVjdC50b3AgICAgPSAwOwogICAgICAgIGZ1bGxfcmVjdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBmdWxsX3JlY3QuYm90dG9tID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIEludGVyc2VjdFJlY3QoJnRlbXBfcmVjdCwgJmZ1bGxfcmVjdCwgJnhkc3QpOwogICAgICAgIHhkc3QgPSB0ZW1wX3JlY3Q7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogT25seSBoYW5kbGUgY2xpcHBpbmcgb24gdGhlIGRlc3RpbmF0aW9uIHJlY3RhbmdsZSAqLwogICAgICAgIGludCBjbGlwX2hvcml6ID0gKHhkc3QubGVmdCA8IDApIHx8ICh4ZHN0LnJpZ2h0ICA+IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoICk7CiAgICAgICAgaW50IGNsaXBfdmVydCAgPSAoeGRzdC50b3AgIDwgMCkgfHwgKHhkc3QuYm90dG9tID4gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KTsKICAgICAgICBpZiAoY2xpcF92ZXJ0IHx8IGNsaXBfaG9yaXopCiAgICAgICAgewogICAgICAgICAgICAvKiBOb3cgY2hlY2sgaWYgdGhpcyBpcyBhIHNwZWNpYWwgY2FzZSBvciBub3QuLi4gKi8KICAgICAgICAgICAgaWYgKCgoKHhkc3QuYm90dG9tIC0geGRzdC50b3AgKSAhPSAoeHNyYy5ib3R0b20gLSB4c3JjLnRvcCApKSAmJiBjbGlwX3ZlcnQgKSB8fAogICAgICAgICAgICAgICAgICAgKCgoeGRzdC5yaWdodCAgLSB4ZHN0LmxlZnQpICE9ICh4c3JjLnJpZ2h0ICAtIHhzcmMubGVmdCkpICYmIGNsaXBfaG9yaXopIHx8CiAgICAgICAgICAgICAgICAgICAoRmxhZ3MgJiBXSU5FRERCTFRfRERGWCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFdBUk4oIk91dCBvZiBzY3JlZW4gcmVjdGFuZ2xlIGluIHNwZWNpYWwgY2FzZS4gTm90IGhhbmRsZWQgcmlnaHQgbm93LlxuIik7CiAgICAgICAgICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChjbGlwX2hvcml6KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoeGRzdC5sZWZ0IDwgMCkgeyB4c3JjLmxlZnQgLT0geGRzdC5sZWZ0OyB4ZHN0LmxlZnQgPSAwOyB9CiAgICAgICAgICAgICAgICBpZiAoeGRzdC5yaWdodCA+IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhzcmMucmlnaHQgLT0gKHhkc3QucmlnaHQgLSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCk7CiAgICAgICAgICAgICAgICAgICAgeGRzdC5yaWdodCA9IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjbGlwX3ZlcnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh4ZHN0LnRvcCA8IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeHNyYy50b3AgLT0geGRzdC50b3A7CiAgICAgICAgICAgICAgICAgICAgeGRzdC50b3AgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKHhkc3QuYm90dG9tID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHhzcmMuYm90dG9tIC09ICh4ZHN0LmJvdHRvbSAtIChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCk7CiAgICAgICAgICAgICAgICAgICAgeGRzdC5ib3R0b20gPSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogQW5kIGNoZWNrIGlmIGFmdGVyIGNsaXBwaW5nIHNvbWV0aGluZyBpcyBzdGlsbCB0byBiZSBkb25lLi4uICovCiAgICAgICAgICAgIGlmICgoeGRzdC5ib3R0b20gPD0gMCkgICB8fCAoeGRzdC5yaWdodCA8PSAwKSAgICAgICB8fAogICAgICAgICAgICAgICAgICh4ZHN0LnRvcCAgID49IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgIHx8CiAgICAgICAgICAgICAgICAgKHhkc3QubGVmdCAgPj0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpICAgfHwKICAgICAgICAgICAgICAgICAoeHNyYy5ib3R0b20gPD0gMCkgICB8fCAoeHNyYy5yaWdodCA8PSAwKSAgICAgICB8fAogICAgICAgICAgICAgICAgICh4c3JjLnRvcCA+PSAoaW50KSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgICAgIHx8CiAgICAgICAgICAgICAgICAgKHhzcmMubGVmdCA+PSAoaW50KSBTcmMtPmN1cnJlbnREZXNjLldpZHRoKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVFJBQ0UoIk5vdGhpbmcgdG8gYmUgZG9uZSBhZnRlciBjbGlwcGluZyAhXG4iKTsKICAgICAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgc3JjaGVpZ2h0ID0geHNyYy5ib3R0b20gLSB4c3JjLnRvcDsKICAgIHNyY3dpZHRoID0geHNyYy5yaWdodCAtIHhzcmMubGVmdDsKICAgIGRzdGhlaWdodCA9IHhkc3QuYm90dG9tIC0geGRzdC50b3A7CiAgICBkc3R3aWR0aCA9IHhkc3QucmlnaHQgLSB4ZHN0LmxlZnQ7CiAgICB3aWR0aCA9ICh4ZHN0LnJpZ2h0IC0geGRzdC5sZWZ0KSAqIGJwcDsKCiAgICBhc3NlcnQod2lkdGggPD0gZGxvY2suUGl0Y2gpOwoKICAgIGRidWYgPSAoQllURSopZGxvY2sucEJpdHMrKHhkc3QudG9wKmRsb2NrLlBpdGNoKSsoeGRzdC5sZWZ0KmJwcCk7CgogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX1dBSVQpCiAgICB7CiAgICAgICAgRmxhZ3MgJj0gfldJTkVEREJMVF9XQUlUOwogICAgfQogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0FTWU5DKQogICAgewogICAgICAgIHN0YXRpYyBCT09MIGRpc3BsYXllZCA9IEZBTFNFOwogICAgICAgIGlmICghZGlzcGxheWVkKQogICAgICAgICAgICBGSVhNRSgiQ2FuJ3QgaGFuZGxlIFdJTkVEREJMVF9BU1lOQyBmbGFnIHJpZ2h0IG5vdy5cbiIpOwogICAgICAgIGRpc3BsYXllZCA9IFRSVUU7CiAgICAgICAgRmxhZ3MgJj0gfldJTkVEREJMVF9BU1lOQzsKICAgIH0KICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9ET05PVFdBSVQpCiAgICB7CiAgICAgICAgLyogV0lORUREQkxUX0RPTk9UV0FJVCBhcHBlYXJlZCBpbiBEWDcgKi8KICAgICAgICBzdGF0aWMgQk9PTCBkaXNwbGF5ZWQgPSBGQUxTRTsKICAgICAgICBpZiAoIWRpc3BsYXllZCkKICAgICAgICAgICAgRklYTUUoIkNhbid0IGhhbmRsZSBXSU5FRERCTFRfRE9OT1RXQUlUIGZsYWcgcmlnaHQgbm93LlxuIik7CiAgICAgICAgZGlzcGxheWVkID0gVFJVRTsKICAgICAgICBGbGFncyAmPSB+V0lORUREQkxUX0RPTk9UV0FJVDsKICAgIH0KCiAgICAvKiBGaXJzdCwgYWxsIHRoZSAnc291cmNlLWxlc3MnIGJsaXRzICovCiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfQ09MT1JGSUxMKQogICAgewogICAgICAgIHJldCA9IF9CbHRfQ29sb3JGaWxsKGRidWYsIGRzdHdpZHRoLCBkc3RoZWlnaHQsIGJwcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkbG9jay5QaXRjaCwgRERCbHRGeC0+dTUuZHdGaWxsQ29sb3IpOwogICAgICAgIEZsYWdzICY9IH5XSU5FRERCTFRfQ09MT1JGSUxMOwogICAgfQoKICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9ERVBUSEZJTEwpCiAgICB7CiAgICAgICAgRklYTUUoIkREQkxUX0RFUFRIRklMTCBuZWVkcyB0byBiZSBpbXBsZW1lbnRlZCFcbiIpOwogICAgfQogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX1JPUCkKICAgIHsKICAgICAgICAvKiBDYXRjaCBzb21lIGRlZ2VuZXJhdGUgY2FzZXMgaGVyZSAqLwogICAgICAgIHN3aXRjaChEREJsdEZ4LT5kd1JPUCkKICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgQkxBQ0tORVNTOgogICAgICAgICAgICAgICAgcmV0ID0gX0JsdF9Db2xvckZpbGwoZGJ1Zixkc3R3aWR0aCxkc3RoZWlnaHQsYnBwLGRsb2NrLlBpdGNoLDApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDB4QUEwMDI5OiAvKiBOby1vcCAqLwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdISVRFTkVTUzoKICAgICAgICAgICAgICAgIHJldCA9IF9CbHRfQ29sb3JGaWxsKGRidWYsZHN0d2lkdGgsZHN0aGVpZ2h0LGJwcCxkbG9jay5QaXRjaCx+MCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgU1JDQ09QWTogLyogd2VsbCwgd2UgZG8gdGhhdCBiZWxvdyA/ICovCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgcmFzdGVyIG9wOiAlMDh4ICBQYXR0ZXJuOiAlcFxuIiwgRERCbHRGeC0+ZHdST1AsIEREQmx0RngtPnU1LmxwRERTUGF0dGVybik7CiAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KICAgICAgICBGbGFncyAmPSB+V0lORUREQkxUX1JPUDsKICAgIH0KICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9ERFJPUFMpCiAgICB7CiAgICAgICAgRklYTUUoIlx0RGRyYXcgUmFzdGVyIE9wczogJTA4eCAgUGF0dGVybjogJXBcbiIsIEREQmx0RngtPmR3RERST1AsIEREQmx0RngtPnU1LmxwRERTUGF0dGVybik7CiAgICB9CiAgICAvKiBOb3cgdGhlICd3aXRoIHNvdXJjZScgYmxpdHMgKi8KICAgIGlmIChTcmMpCiAgICB7CiAgICAgICAgTFBCWVRFIHNiYXNlOwogICAgICAgIGludCBzeCwgeGluYywgc3ksIHlpbmM7CgogICAgICAgIGlmICghZHN0d2lkdGggfHwgIWRzdGhlaWdodCkgLyogaG1tLi4uIHN0dXBpZCBwcm9ncmFtID8gKi8KICAgICAgICAgICAgZ290byByZWxlYXNlOwogICAgICAgIHNiYXNlID0gKEJZVEUqKXNsb2NrLnBCaXRzKyh4c3JjLnRvcCpzbG9jay5QaXRjaCkreHNyYy5sZWZ0KmJwcDsKICAgICAgICB4aW5jID0gKHNyY3dpZHRoIDw8IDE2KSAvIGRzdHdpZHRoOwogICAgICAgIHlpbmMgPSAoc3JjaGVpZ2h0IDw8IDE2KSAvIGRzdGhlaWdodDsKCiAgICAgICAgaWYgKCFGbGFncykKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vIGVmZmVjdHMsIHdlIGNhbiBjaGVhdCBoZXJlICovCiAgICAgICAgICAgIGlmIChkc3R3aWR0aCA9PSBzcmN3aWR0aCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGRzdGhlaWdodCA9PSBzcmNoZWlnaHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogTm8gc3RyZXRjaGluZyBpbiBlaXRoZXIgZGlyZWN0aW9uLiBUaGlzIG5lZWRzIHRvIGJlIGFzCiAgICAgICAgICAgICAgICAgICAgKiBmYXN0IGFzIHBvc3NpYmxlICovCiAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlOwoKICAgICAgICAgICAgICAgICAgICAvKiBjaGVjayBmb3Igb3ZlcmxhcHBpbmcgc3VyZmFjZXMgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoU3JjICE9IFRoaXMgfHwgeGRzdC50b3AgPCB4c3JjLnRvcCB8fAogICAgICAgICAgICAgICAgICAgICAgICB4ZHN0LnJpZ2h0IDw9IHhzcmMubGVmdCB8fCB4c3JjLnJpZ2h0IDw9IHhkc3QubGVmdCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5vIG92ZXJsYXAsIG9yIGRzdCBhYm92ZSBzcmMsIHNvIGNvcHkgZnJvbSB0b3AgZG93bndhcmRzICovCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGRidWYsIHNidWYsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgKz0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYnVmICs9IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHhkc3QudG9wID4geHNyYy50b3ApICAvKiBjb3B5IGZyb20gYm90dG9tIHVwd2FyZHMgKi8KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgKz0gKHNsb2NrLlBpdGNoKmRzdGhlaWdodCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgKz0gKGRsb2NrLlBpdGNoKmRzdGhlaWdodCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiAtPSBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgLT0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1jcHkoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgLyogc3JjIGFuZCBkc3Qgb3ZlcmxhcHBpbmcgb24gdGhlIHNhbWUgbGluZSwgdXNlIG1lbW1vdmUgKi8KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKykKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtbW92ZShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnVmICs9IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyogU3RyZXRjaGluZyBpbiBZIGRpcmVjdGlvbiBvbmx5ICovCiAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gc3kgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyssIHN5ICs9IHlpbmMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiA9IHNiYXNlICsgKHN5ID4+IDE2KSAqIHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICBtZW1jcHkoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICBkYnVmICs9IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIFN0cmV0Y2hpbmcgaW4gWCBkaXJlY3Rpb24gKi8KICAgICAgICAgICAgICAgIGludCBsYXN0X3N5ID0gLTE7CiAgICAgICAgICAgICAgICBmb3IgKHkgPSBzeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKywgc3kgKz0geWluYykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzYnVmID0gc2Jhc2UgKyAoc3kgPj4gMTYpICogc2xvY2suUGl0Y2g7CgogICAgICAgICAgICAgICAgICAgIGlmICgoc3kgPj4gMTYpID09IChsYXN0X3N5ID4+IDE2KSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRoaXMgc291cmNlcm93IGlzIHRoZSBzYW1lIGFzIGxhc3Qgc291cmNlcm93IC0KICAgICAgICAgICAgICAgICAgICAgICAgKiBjb3B5IGFscmVhZHkgc3RyZXRjaGVkIHJvdwogICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICBtZW1jcHkoZGJ1ZiwgZGJ1ZiAtIGRsb2NrLlBpdGNoLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiNkZWZpbmUgU1RSRVRDSF9ST1codHlwZSkgeyBcCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUgKnMgPSAodHlwZSAqKSBzYnVmLCAqZCA9ICh0eXBlICopIGRidWY7IFwKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gc3ggPSAwOyB4IDwgZHN0d2lkdGg7IHgrKywgc3ggKz0geGluYykgXAogICAgICAgICAgICAgICAgICAgICAgICBkW3hdID0gc1tzeCA+PiAxNl07IFwKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7IH0KCiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaChicHApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTogU1RSRVRDSF9ST1coQllURSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOiBTVFJFVENIX1JPVyhXT1JEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNDogU1RSRVRDSF9ST1coRFdPUkQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBCWVRFIHMsZCA9IGRidWY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gc3ggPSAwOyB4IDwgZHN0d2lkdGg7IHgrKywgc3grPSB4aW5jKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgcGl4ZWw7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzID0gc2J1ZiszKihzeD4+MTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbCA9IHNbMF18KHNbMV08PDgpfChzWzJdPDwxNik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbMF0gPSAocGl4ZWwgICAgKSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWzFdID0gKHBpeGVsPj4gOCkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFsyXSA9IChwaXhlbD4+MTYpJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQrPTM7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiU3RyZXRjaGVkIGJsaXQgbm90IGltcGxlbWVudGVkIGZvciBicHAgJWQhXG4iLCBicHAqOCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0ID0gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgICAgICAgICAgfQojdW5kZWYgU1RSRVRDSF9ST1cKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICBsYXN0X3N5ID0gc3k7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgTE9ORyBkc3R5aW5jID0gZGxvY2suUGl0Y2gsIGRzdHhpbmMgPSBicHA7CiAgICAgICAgICAgIERXT1JEIGtleWxvdyA9IDB4RkZGRkZGRkYsIGtleWhpZ2ggPSAwLCBrZXltYXNrID0gMHhGRkZGRkZGRjsKICAgICAgICAgICAgRFdPUkQgZGVzdGtleWxvdyA9IDB4MCwgZGVzdGtleWhpZ2ggPSAweEZGRkZGRkZGLCBkZXN0a2V5bWFzayA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgIGlmIChGbGFncyAmIChXSU5FRERCTFRfS0VZU1JDIHwgV0lORUREQkxUX0tFWURFU1QgfCBXSU5FRERCTFRfS0VZU1JDT1ZFUlJJREUgfCBXSU5FRERCTFRfS0VZREVTVE9WRVJSSURFKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogVGhlIGNvbG9yIGtleWluZyBmbGFncyBhcmUgY2hlY2tlZCBmb3IgY29ycmVjdG5lc3MgaW4gZGRyYXcgKi8KICAgICAgICAgICAgICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9LRVlTUkMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAga2V5bG93ICA9IFNyYy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZTsKICAgICAgICAgICAgICAgICAgICBrZXloaWdoID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgIGlmIChGbGFncyAmIFdJTkVEREJMVF9LRVlTUkNPVkVSUklERSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBrZXlsb3cgID0gRERCbHRGeC0+ZGRja1NyY0NvbG9ya2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAgICAgIGtleWhpZ2ggPSBEREJsdEZ4LT5kZGNrU3JjQ29sb3JrZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9LRVlERVNUKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIERlc3RpbmF0aW9uIGNvbG9yIGtleXMgYXJlIHRha2VuIGZyb20gdGhlIHNvdXJjZSBzdXJmYWNlICEgKi8KICAgICAgICAgICAgICAgICAgICBkZXN0a2V5bG93ICA9IFNyYy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgICAgICAgICAgZGVzdGtleWhpZ2ggPSBTcmMtPkRlc3RCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKEZsYWdzICYgV0lORUREQkxUX0tFWURFU1RPVkVSUklERSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkZXN0a2V5bG93ICA9IEREQmx0RngtPmRkY2tEZXN0Q29sb3JrZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgICAgICAgICAgZGVzdGtleWhpZ2ggPSBEREJsdEZ4LT5kZGNrRGVzdENvbG9ya2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZihicHAgPT0gMSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBrZXltYXNrID0gMHhmZjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBrZXltYXNrID0gc0VudHJ5LT5yZWRNYXNrICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc0VudHJ5LT5ncmVlbk1hc2sgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc0VudHJ5LT5ibHVlTWFzazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEZsYWdzICY9IH4oV0lORUREQkxUX0tFWVNSQyB8IFdJTkVEREJMVF9LRVlERVNUIHwgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFIHwgV0lORUREQkxUX0tFWURFU1RPVkVSUklERSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9EREZYKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMUEJZVEUgZFRvcExlZnQsIGRUb3BSaWdodCwgZEJvdHRvbUxlZnQsIGRCb3R0b21SaWdodCwgdG1wOwogICAgICAgICAgICAgICAgTE9ORyB0bXB4eTsKICAgICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IGRidWY7CiAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSBkYnVmKygoZHN0d2lkdGgtMSkqYnBwKTsKICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IGRUb3BMZWZ0KygoZHN0aGVpZ2h0LTEpKmRsb2NrLlBpdGNoKTsKICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRCb3R0b21MZWZ0KygoZHN0d2lkdGgtMSkqYnBwKTsKCiAgICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgV0lORUREQkxURlhfQVJJVEhTVFJFVENIWSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBJIGRvbid0IHRoaW5rIHdlIG5lZWQgdG8gZG8gYW55dGhpbmcgYWJvdXQgdGhpcyBmbGFnICovCiAgICAgICAgICAgICAgICAgICAgV0FSTigiRmxhZ3M9RERCTFRfRERGWCBub3RoaW5nIGRvbmUgZm9yIFdJTkVEREJMVEZYX0FSSVRIU1RSRVRDSFlcbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX01JUlJPUkxFRlRSSUdIVCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gdG1wOwogICAgICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRCb3R0b21SaWdodDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSB0bXA7CiAgICAgICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHhpbmMgKi0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX01JUlJPUlVQRE9XTikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSB0bXA7CiAgICAgICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcFJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IGRCb3R0b21SaWdodDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSB0bXA7CiAgICAgICAgICAgICAgICAgICAgZHN0eWluYyA9IGRzdHlpbmMgKi0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX05PVEVBUklORykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBJIGRvbid0IHRoaW5rIHdlIG5lZWQgdG8gZG8gYW55dGhpbmcgYWJvdXQgdGhpcyBmbGFnICovCiAgICAgICAgICAgICAgICAgICAgV0FSTigiRmxhZ3M9RERCTFRfRERGWCBub3RoaW5nIGRvbmUgZm9yIFdJTkVEREJMVEZYX05PVEVBUklOR1xuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgV0lORUREQkxURlhfUk9UQVRFMTgwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRCb3R0b21SaWdodDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSB0bXA7CiAgICAgICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gZFRvcFJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IHRtcDsKICAgICAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eGluYyAqIC0xOwogICAgICAgICAgICAgICAgICAgIGRzdHlpbmMgPSBkc3R5aW5jICogLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgV0lORUREQkxURlhfUk9UQVRFMjcwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IGRCb3R0b21MZWZ0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IGRCb3R0b21SaWdodDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gdG1wOwogICAgICAgICAgICAgICAgICAgIHRtcHh5ICAgPSBkc3R4aW5jOwogICAgICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R5aW5jOwogICAgICAgICAgICAgICAgICAgIGRzdHlpbmMgPSB0bXB4eTsKICAgICAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eGluYyAqIC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX1JPVEFURTkwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSBkQm90dG9tUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gdG1wOwogICAgICAgICAgICAgICAgICAgIHRtcHh5ICAgPSBkc3R4aW5jOwogICAgICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R5aW5jOwogICAgICAgICAgICAgICAgICAgIGRzdHlpbmMgPSB0bXB4eTsKICAgICAgICAgICAgICAgICAgICBkc3R5aW5jID0gZHN0eWluYyAqIC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKEREQmx0RngtPmR3RERGWCAmIFdJTkVEREJMVEZYX1pCVUZGRVJCQVNFREVTVCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBJIGRvbid0IHRoaW5rIHdlIG5lZWQgdG8gZG8gYW55dGhpbmcgYWJvdXQgdGhpcyBmbGFnICovCiAgICAgICAgICAgICAgICAgICAgV0FSTigiRmxhZ3M9V0lORUREQkxUX0RERlggbm90aGluZyBkb25lIGZvciBXSU5FRERCTFRGWF9aQlVGRkVSQkFTRURFU1RcbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGJ1ZiA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgRmxhZ3MgJj0gfihXSU5FRERCTFRfRERGWCk7CiAgICAgICAgICAgIH0KCiNkZWZpbmUgQ09QWV9DT0xPUktFWV9GWCh0eXBlKSB7IFwKICAgICAgICAgICAgdHlwZSAqcywgKmQgPSAodHlwZSAqKSBkYnVmLCAqZHgsIHRtcDsgXAogICAgICAgICAgICBmb3IgKHkgPSBzeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKywgc3kgKz0geWluYykgeyBcCiAgICAgICAgICAgIHMgPSAodHlwZSopKHNiYXNlICsgKHN5ID4+IDE2KSAqIHNsb2NrLlBpdGNoKTsgXAogICAgICAgICAgICBkeCA9IGQ7IFwKICAgICAgICAgICAgZm9yICh4ID0gc3ggPSAwOyB4IDwgZHN0d2lkdGg7IHgrKywgc3ggKz0geGluYykgeyBcCiAgICAgICAgICAgIHRtcCA9IHNbc3ggPj4gMTZdOyBcCiAgICAgICAgICAgIGlmICgoKHRtcCAmIGtleW1hc2spIDwga2V5bG93IHx8ICh0bXAgJiBrZXltYXNrKSA+IGtleWhpZ2gpICYmIFwKICAgICAgICAgICAgKChkeFswXSAmIGRlc3RrZXltYXNrKSA+PSBkZXN0a2V5bG93ICYmIChkeFswXSAmIGRlc3RrZXltYXNrKSA8PSBkZXN0a2V5aGlnaCkpIHsgXAogICAgICAgICAgICBkeFswXSA9IHRtcDsgXAogICAgICAgIH0gXAogICAgICAgICAgICBkeCA9ICh0eXBlKikoKChMUEJZVEUpZHgpK2RzdHhpbmMpOyBcCiAgICAgICAgfSBcCiAgICAgICAgICAgIGQgPSAodHlwZSopKCgoTFBCWVRFKWQpK2RzdHlpbmMpOyBcCiAgICAgICAgfSBcCiAgICAgICAgICAgIGJyZWFrOyB9CgogICAgICAgICAgICBzd2l0Y2ggKGJwcCkgewogICAgICAgICAgICAgICAgY2FzZSAxOiBDT1BZX0NPTE9SS0VZX0ZYKEJZVEUpCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjogQ09QWV9DT0xPUktFWV9GWChXT1JEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNDogQ09QWV9DT0xPUktFWV9GWChEV09SRCkKICAgICAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBMUEJZVEUgcyxkID0gZGJ1ZiwgZHg7CiAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gc3kgPSAwOyB5IDwgZHN0aGVpZ2h0OyB5KyssIHN5ICs9IHlpbmMpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzYnVmID0gc2Jhc2UgKyAoc3kgPj4gMTYpICogc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgIGR4ID0gZDsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gc3ggPSAwOyB4IDwgZHN0d2lkdGg7IHgrKywgc3grPSB4aW5jKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBwaXhlbCwgZHBpeGVsID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBzYnVmKzMqKHN4Pj4xNik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXhlbCA9IHNbMF18KHNbMV08PDgpfChzWzJdPDwxNik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGl4ZWwgPSBkeFswXXwoZHhbMV08PDgpfChkeFsyXTw8MTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCgocGl4ZWwgJiBrZXltYXNrKSA8IGtleWxvdyB8fCAocGl4ZWwgJiBrZXltYXNrKSA+IGtleWhpZ2gpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKGRwaXhlbCAmIGtleW1hc2spID49IGRlc3RrZXlsb3cgfHwgKGRwaXhlbCAmIGtleW1hc2spIDw9IGtleWhpZ2gpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4WzBdID0gKHBpeGVsICAgICkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeFsxXSA9IChwaXhlbD4+IDgpJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHhbMl0gPSAocGl4ZWw+PjE2KSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHgrPSBkc3R4aW5jOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGQgKz0gZHN0eWluYzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEZJWE1FKCIlcyBjb2xvci1rZXllZCBibGl0IG5vdCBpbXBsZW1lbnRlZCBmb3IgYnBwICVkIVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAoRmxhZ3MgJiBXSU5FRERCTFRfS0VZU1JDKSA/ICJTb3VyY2UiIDogIkRlc3RpbmF0aW9uIiwgYnBwKjgpOwogICAgICAgICAgICAgICAgICAgIHJldCA9IFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiN1bmRlZiBDT1BZX0NPTE9SS0VZX0ZYCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgplcnJvcjoKICAgIGlmIChGbGFncyAmJiBGSVhNRV9PTihkM2Rfc3VyZmFjZSkpCiAgICB7CiAgICAgICAgRklYTUUoIlx0VW5zdXBwb3J0ZWQgZmxhZ3M6ICUwOHhcbiIsIEZsYWdzKTsKICAgIH0KCnJlbGVhc2U6CiAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChpZmFjZSk7CiAgICBpZiAoU3JjICYmIFNyYyAhPSBUaGlzKSBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdCgoSVdpbmVEM0RTdXJmYWNlICopIFNyYyk7CiAgICAvKiBSZWxlYXNlIHRoZSBjb252ZXJ0ZWQgc3VyZmFjZSBpZiBhbnkgKi8KICAgIGlmIChTcmMgJiYgU3JjU3VyZmFjZSAhPSAoSVdpbmVEM0RTdXJmYWNlICopIFNyYykgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6Qmx0RmFzdCwgU1cgZW11bGF0aW9uIHZlcnNpb24KICoKICogVGhpcyBpcyB0aGUgc29mdHdhcmUgaW1wbGVtZW50YXRpb24gb2YgQmx0RmFzdCwgYXMgdXNlZCBieSBHREkgc3VyZmFjZXMKICogYW5kIGFzIGEgZmFsbGJhY2sgZm9yIE9wZW5HTCBzdXJmYWNlcy4gVGhpcyBjb2RlIGlzIHRha2VuIGZyb20gdGhlIG9sZAogKiBEaXJlY3REcmF3IGNvZGUsIGFuZCB3YXMgb3JpZ2luYWxseSB3cml0dGVuIGJ5IFRyYW5zR2FtaW5nLgogKgogKiBQYXJhbXM6CiAqICBkc3R4OgogKiAgZHN0eToKICogIFNvdXJjZTogU291cmNlIHN1cmZhY2UgdG8gY29weSBmcm9tCiAqICByc3JjOiBTb3VyY2UgcmVjdGFuZ2xlCiAqICB0cmFuczogU29tZSBGbGFncwogKgogKiBSZXR1cm5zOgogKiAgV0lORUQzRF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfQmx0RmFzdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGRzdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHN0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKlNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpyc3JjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHRyYW5zKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTb3VyY2U7CgogICAgaW50ICAgICAgICAgICAgICAgICBicHAsIHcsIGgsIHgsIHk7CiAgICBXSU5FRDNETE9DS0VEX1JFQ1QgIGRsb2NrLHNsb2NrOwogICAgSFJFU1VMVCAgICAgICAgICAgICByZXQgPSBXSU5FRDNEX09LOwogICAgUkVDVCAgICAgICAgICAgICAgICByc3JjMjsKICAgIFJFQ1QgICAgICAgICAgICAgICAgbG9ja19zcmMsIGxvY2tfZHN0LCBsb2NrX3VuaW9uOwogICAgQllURSAgICAgICAgICAgICAgICAqc2J1ZiwgKmRidWY7CiAgICBjb25zdCBTdGF0aWNQaXhlbEZvcm1hdERlc2MgKnNFbnRyeSwgKmRFbnRyeTsKCiAgICBpZiAoVFJBQ0VfT04oZDNkX3N1cmZhY2UpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApLT4oJWQsJWQsJXAsJXAsJTA4eClcbiIsIFRoaXMsZHN0eCxkc3R5LFNyYyxyc3JjLHRyYW5zKTsKCiAgICAgICAgaWYgKHJzcmMpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiXHRzcmNyZWN0OiAlZHglZC0lZHglZFxuIixyc3JjLT5sZWZ0LHJzcmMtPnRvcCwKICAgICAgICAgICAgICAgICAgcnNyYy0+cmlnaHQscnNyYy0+Ym90dG9tKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiBzcmNyZWN0OiBOVUxMXG4iKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKChUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkgfHwKICAgICAgICAgKChTcmMgIT0gTlVMTCkgJiYgKFNyYy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpKSkKICAgIHsKICAgICAgICBXQVJOKCIgU3VyZmFjZSBpcyBidXN5LCByZXR1cm5pbmcgRERFUlJfU1VSRkFDRUJVU1lcbiIpOwogICAgICAgIHJldHVybiBXSU5FRERFUlJfU1VSRkFDRUJVU1k7CiAgICB9CgogICAgaWYgKCFyc3JjKQogICAgewogICAgICAgIFdBUk4oInJzcmMgaXMgTlVMTCFcbiIpOwogICAgICAgIHJzcmMgPSAmcnNyYzI7CiAgICAgICAgcnNyYy0+bGVmdCA9IDA7CiAgICAgICAgcnNyYy0+dG9wID0gMDsKICAgICAgICByc3JjLT5yaWdodCA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgcnNyYy0+Ym90dG9tID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICB9CgogICAgLyogQ2hlY2sgc291cmNlIHJlY3QgZm9yIHZhbGlkaXR5LiBDb3BpZWQgZnJvbSBub3JtYWwgQmx0LiBGaXhlcyBCYWxkdXIncyBHYXRlLiovCiAgICBpZiAoKHJzcmMtPmJvdHRvbSA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAocnNyYy0+Ym90dG9tIDwgMCkgfHwKICAgICAgICAgKHJzcmMtPnRvcCAgICA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAocnNyYy0+dG9wICAgIDwgMCkgfHwKICAgICAgICAgKHJzcmMtPmxlZnQgICA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAocnNyYy0+bGVmdCAgIDwgMCkgfHwKICAgICAgICAgKHJzcmMtPnJpZ2h0ICA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAocnNyYy0+cmlnaHQgIDwgMCkgfHwKICAgICAgICAgKHJzcmMtPnJpZ2h0ICA8IHJzcmMtPmxlZnQpICAgICAgICAgICAgICB8fCAocnNyYy0+Ym90dG9tIDwgcnNyYy0+dG9wKSkKICAgIHsKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiBnYXZlIHVzIGJhZCBzb3VyY2UgcmVjdGFuZ2xlIGZvciBCbHRGYXN0LlxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9JTlZBTElEUkVDVDsKICAgIH0KCiAgICBoID0gcnNyYy0+Ym90dG9tIC0gcnNyYy0+dG9wOwogICAgaWYgKGggPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQtZHN0eSkgaCA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodC1kc3R5OwogICAgaWYgKGggPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodC1yc3JjLT50b3ApIGg9U3JjLT5jdXJyZW50RGVzYy5IZWlnaHQtcnNyYy0+dG9wOwogICAgaWYgKGggPD0gMCkgcmV0dXJuIFdJTkVEREVSUl9JTlZBTElEUkVDVDsKCiAgICB3ID0gcnNyYy0+cmlnaHQgLSByc3JjLT5sZWZ0OwogICAgaWYgKHcgPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aC1kc3R4KSB3ID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgtZHN0eDsKICAgIGlmICh3ID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aC1yc3JjLT5sZWZ0KSB3ID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aC1yc3JjLT5sZWZ0OwogICAgaWYgKHcgPD0gMCkgcmV0dXJuIFdJTkVEREVSUl9JTlZBTElEUkVDVDsKCiAgICAvKiBOb3cgY29tcHV0ZSB0aGUgbG9ja2luZyByZWN0YW5nbGUuLi4gKi8KICAgIGxvY2tfc3JjLmxlZnQgPSByc3JjLT5sZWZ0OwogICAgbG9ja19zcmMudG9wID0gcnNyYy0+dG9wOwogICAgbG9ja19zcmMucmlnaHQgPSBsb2NrX3NyYy5sZWZ0ICsgdzsKICAgIGxvY2tfc3JjLmJvdHRvbSA9IGxvY2tfc3JjLnRvcCArIGg7CgogICAgbG9ja19kc3QubGVmdCA9IGRzdHg7CiAgICBsb2NrX2RzdC50b3AgPSBkc3R5OwogICAgbG9ja19kc3QucmlnaHQgPSBkc3R4ICsgdzsKICAgIGxvY2tfZHN0LmJvdHRvbSA9IGRzdHkgKyBoOwoKICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CgogICAgLyogV2UgbmVlZCB0byBsb2NrIHRoZSBzdXJmYWNlcywgb3Igd2Ugd29uJ3QgZ2V0IHJlZnJlc2hlcyB3aGVuIGRvbmUuICovCiAgICBpZiAoU3JjID09IFRoaXMpCiAgICB7CiAgICAgICAgaW50IHBpdGNoOwoKICAgICAgICBVbmlvblJlY3QoJmxvY2tfdW5pb24sICZsb2NrX3NyYywgJmxvY2tfZHN0KTsKCiAgICAgICAgLyogTG9jayB0aGUgdW5pb24gb2YgdGhlIHR3byByZWN0YW5nbGVzICovCiAgICAgICAgcmV0ID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLCAmZGxvY2ssICZsb2NrX3VuaW9uLCAwKTsKICAgICAgICBpZihyZXQgIT0gV0lORUQzRF9PSykgZ290byBlcnJvcjsKCiAgICAgICAgcGl0Y2ggPSBkbG9jay5QaXRjaDsKICAgICAgICBzbG9jay5QaXRjaCA9IGRsb2NrLlBpdGNoOwoKICAgICAgICAvKiBTaW5jZSBzbG9jayB3YXMgb3JpZ2luYWxseSBjb3BpZWQgZnJvbSB0aGlzIHN1cmZhY2UncyBkZXNjcmlwdGlvbiwgd2UgY2FuIGp1c3QgcmV1c2UgaXQgKi8KICAgICAgICBhc3NlcnQoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICE9IE5VTEwpOwogICAgICAgIHNidWYgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyBsb2NrX3NyYy50b3AgKiBwaXRjaCArIGxvY2tfc3JjLmxlZnQgKiBicHA7CiAgICAgICAgZGJ1ZiA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIGxvY2tfZHN0LnRvcCAqIHBpdGNoICsgbG9ja19kc3QubGVmdCAqIGJwcDsKICAgICAgICBzRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoU3JjLT5yZXNvdXJjZS5mb3JtYXQsIE5VTEwsIE5VTEwpOwogICAgICAgIGRFbnRyeSA9IHNFbnRyeTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXQgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoU291cmNlLCAmc2xvY2ssICZsb2NrX3NyYywgV0lORUQzRExPQ0tfUkVBRE9OTFkpOwogICAgICAgIGlmKHJldCAhPSBXSU5FRDNEX09LKSBnb3RvIGVycm9yOwogICAgICAgIHJldCA9IElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwgJmRsb2NrLCAmbG9ja19kc3QsIDApOwogICAgICAgIGlmKHJldCAhPSBXSU5FRDNEX09LKSBnb3RvIGVycm9yOwoKICAgICAgICBzYnVmID0gc2xvY2sucEJpdHM7CiAgICAgICAgZGJ1ZiA9IGRsb2NrLnBCaXRzOwogICAgICAgIFRSQUNFKCJEc3QgaXMgYXQgJXAsIFNyYyBpcyBhdCAlcFxuIiwgZGJ1Ziwgc2J1Zik7CgogICAgICAgIHNFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShTcmMtPnJlc291cmNlLmZvcm1hdCwgTlVMTCwgTlVMTCk7CiAgICAgICAgZEVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFRoaXMtPnJlc291cmNlLmZvcm1hdCwgTlVMTCwgTlVMTCk7CiAgICB9CgogICAgLyogSGFuZGxlIGZpcnN0IHRoZSBGT1VSQ0Mgc3VyZmFjZXMuLi4gKi8KICAgIGlmIChzRW50cnktPmlzRm91cmNjICYmIGRFbnRyeS0+aXNGb3VyY2MpCiAgICB7CiAgICAgICAgVFJBQ0UoIkZvdXJjYyAtPiBGb3VyY2MgY29weVxuIik7CiAgICAgICAgaWYgKHRyYW5zKQogICAgICAgICAgICBGSVhNRSgidHJhbnMgYXJnIG5vdCBzdXBwb3J0ZWQgd2hlbiBhIEZPVVJDQyBzdXJmYWNlIGlzIGludm9sdmVkXG4iKTsKICAgICAgICBpZiAoZHN0eCB8fCBkc3R5KQogICAgICAgICAgICBGSVhNRSgib2Zmc2V0IGZvciBkZXN0aW5hdGlvbiBzdXJmYWNlIGlzIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIGlmIChTcmMtPnJlc291cmNlLmZvcm1hdCAhPSBUaGlzLT5yZXNvdXJjZS5mb3JtYXQpCiAgICAgICAgewogICAgICAgICAgICBGSVhNRSgiRk9VUkNDLT5GT1VSQ0MgY29weSBvbmx5IHN1cHBvcnRlZCBmb3IgdGhlIHNhbWUgdHlwZSBvZiBzdXJmYWNlXG4iKTsKICAgICAgICAgICAgcmV0ID0gV0lORUQzREVSUl9XUk9OR1RFWFRVUkVGT1JNQVQ7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIC8qIEZJWE1FOiBXYXRjaCBvdXQgdGhhdCB0aGUgc2l6ZSBpcyBjb3JyZWN0IGZvciBGT1VSQ0Mgc3VyZmFjZXMgKi8KICAgICAgICBtZW1jcHkoZGJ1Ziwgc2J1ZiwgVGhpcy0+cmVzb3VyY2Uuc2l6ZSk7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIGlmIChzRW50cnktPmlzRm91cmNjICYmICFkRW50cnktPmlzRm91cmNjKQogICAgewogICAgICAgIC8qIFRPRE86IFVzZSB0aGUgbGlidHhjX2R4dG4uc28gc2hhcmVkIGxpYnJhcnkgdG8gZG8KICAgICAgICAgKiBzb2Z0d2FyZSBkZWNvbXByZXNzaW9uCiAgICAgICAgICovCiAgICAgICAgRVJSKCJEWFRDIGRlY29tcHJlc3Npb24gbm90IHN1cHBvcnRlZCBieSBub3dcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKHRyYW5zICYgKFdJTkVEREJMVEZBU1RfU1JDQ09MT1JLRVkgfCBXSU5FRERCTFRGQVNUX0RFU1RDT0xPUktFWSkpCiAgICB7CiAgICAgICAgRFdPUkQga2V5bG93LCBrZXloaWdoOwogICAgICAgIFRSQUNFKCJDb2xvciBrZXllZCBjb3B5XG4iKTsKICAgICAgICBpZiAodHJhbnMgJiBXSU5FRERCTFRGQVNUX1NSQ0NPTE9SS0VZKQogICAgICAgIHsKICAgICAgICAgICAga2V5bG93ICA9IFNyYy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZTsKICAgICAgICAgICAga2V5aGlnaCA9IFNyYy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIEknbSBub3Qgc3VyZSBpZiB0aGlzIGlzIGNvcnJlY3QgKi8KICAgICAgICAgICAgRklYTUUoIldJTkVEREJMVEZBU1RfREVTVENPTE9SS0VZIG5vdCBmdWxseSBzdXBwb3J0ZWQgeWV0LlxuIik7CiAgICAgICAgICAgIGtleWxvdyAgPSBUaGlzLT5EZXN0Qmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZTsKICAgICAgICAgICAga2V5aGlnaCA9IFRoaXMtPkRlc3RCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICB9CgojZGVmaW5lIENPUFlCT1hfQ09MT1JLRVkodHlwZSkgeyBcCiAgICAgICAgdHlwZSAqZCwgKnMsIHRtcDsgXAogICAgICAgIHMgPSAodHlwZSAqKSBzYnVmOyBcCiAgICAgICAgZCA9ICh0eXBlICopIGRidWY7IFwKICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaDsgeSsrKSB7IFwKICAgICAgICBmb3IgKHggPSAwOyB4IDwgdzsgeCsrKSB7IFwKICAgICAgICB0bXAgPSBzW3hdOyBcCiAgICAgICAgaWYgKHRtcCA8IGtleWxvdyB8fCB0bXAgPiBrZXloaWdoKSBkW3hdID0gdG1wOyBcCiAgICB9IFwKICAgICAgICBzID0gKHR5cGUgKikoKEJZVEUgKilzICsgc2xvY2suUGl0Y2gpOyBcCiAgICAgICAgZCA9ICh0eXBlICopKChCWVRFICopZCArIGRsb2NrLlBpdGNoKTsgXAogICAgfSBcCiAgICAgICAgYnJlYWs7IFwKICAgIH0KCiAgICAgICAgc3dpdGNoIChicHApIHsKICAgICAgICAgICAgY2FzZSAxOiBDT1BZQk9YX0NPTE9SS0VZKEJZVEUpCiAgICAgICAgICAgICAgICAgICAgY2FzZSAyOiBDT1BZQk9YX0NPTE9SS0VZKFdPUkQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6IENPUFlCT1hfQ09MT1JLRVkoRFdPUkQpCiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQllURSAqZCwgKnM7CiAgICAgICAgICAgICAgICBEV09SRCB0bXA7CiAgICAgICAgICAgICAgICBzID0gc2J1ZjsKICAgICAgICAgICAgICAgIGQgPSBkYnVmOwogICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGg7IHkrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgdyAqIDM7IHggKz0gMykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRtcCA9IChEV09SRClzW3hdICsgKChEV09SRClzW3ggKyAxXSA8PCA4KSArICgoRFdPUkQpc1t4ICsgMl0gPDwgMTYpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodG1wIDwga2V5bG93IHx8IHRtcCA+IGtleWhpZ2gpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbeCArIDBdID0gc1t4ICsgMF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkW3ggKyAxXSA9IHNbeCArIDFdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZFt4ICsgMl0gPSBzW3ggKyAyXTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzICs9IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgIGQgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIlNvdXJjZSBjb2xvciBrZXkgYmxpdHRpbmcgbm90IHN1cHBvcnRlZCBmb3IgYnBwICVkXG4iLGJwcCo4KTsKICAgICAgICAgICAgICAgIHJldCA9IFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiN1bmRlZiBDT1BZQk9YX0NPTE9SS0VZCiAgICAgICAgVFJBQ0UoIkNvcHkgRG9uZVxuIik7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaW50IHdpZHRoID0gdyAqIGJwcDsKICAgICAgICBUUkFDRSgiTk8gY29sb3Iga2V5IGNvcHlcbiIpOwogICAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyB5KyspCiAgICAgICAgewogICAgICAgICAgICAvKiBUaGlzIGlzIHByZXR0eSBlYXN5LCBhIGxpbmUgZm9yIGxpbmUgbWVtY3B5ICovCiAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgIHNidWYgKz0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDb3B5IGRvbmVcbiIpOwogICAgfQoKZXJyb3I6CiAgICBpZiAoU3JjID09IFRoaXMpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChTb3VyY2UpOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0xvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RMT0NLRURfUkVDVCogcExvY2tlZFJlY3QsIENPTlNUIFJFQ1QqIHBSZWN0LCBEV09SRCBGbGFncykKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiByZWN0QCVwIGZsYWdzKCUwOHgpLCBvdXRwdXQgbG9ja2VkUmVjdEAlcCwgbWVtb3J5QCVwXG4iLAogICAgICAgICAgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICBwTG9ja2VkUmVjdC0+UGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpOwoKICAgIGlmIChOVUxMID09IHBSZWN0KQogICAgewogICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSAwOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgogICAgICAgIFRSQUNFKCJMb2NrZWQgUmVjdCAoJXApID0gbCAlZCwgdCAlZCwgciAlZCwgYiAlZFxuIiwKICAgICAgICAgICAgICAmVGhpcy0+bG9ja2VkUmVjdCwgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwKICAgICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0LCBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgVFJBQ0UoIkxvY2sgUmVjdCAoJXApID0gbCAlZCwgdCAlZCwgciAlZCwgYiAlZFxuIiwKICAgICAgICAgICAgICBwUmVjdCwgcFJlY3QtPmxlZnQsIHBSZWN0LT50b3AsIHBSZWN0LT5yaWdodCwgcFJlY3QtPmJvdHRvbSk7CgogICAgICAgIC8qIERYVG4gdGV4dHVyZXMgYXJlIGJhc2VkIG9uIGNvbXByZXNzZWQgYmxvY2tzIG9mIDR4NCBwaXhlbHMsIGVhY2gKICAgICAgICAgKiAxNiBieXRlcyBsYXJnZSAoOCBieXRlcyBpbiBjYXNlIG9mIERYVDEpLiBCZWNhdXNlIG9mIHRoYXQgUGl0Y2ggaGFzCiAgICAgICAgICogc2xpZ2h0bHkgZGlmZmVyZW50IG1lYW5pbmcgY29tcGFyZWQgdG8gcmVndWxhciB0ZXh0dXJlcy4gRm9yIERYVG4KICAgICAgICAgKiB0ZXh0dXJlcyBQaXRjaCBpcyB0aGUgc2l6ZSBvZiBhIHJvdyBvZiBibG9ja3MsIDQgaGlnaCBhbmQgIndpZHRoIgogICAgICAgICAqIGxvbmcuIFRoZSB4IG9mZnNldCBpcyBjYWxjdWxhdGVkIGRpZmZlcmVudGx5IGFzIHdlbGwsIHNpbmNlIG1vdmluZyA0CiAgICAgICAgICogcGl4ZWxzIHRvIHRoZSByaWdodCBhY3R1YWxseSBtb3ZlcyBhbiBlbnRpcmUgNHg0IGJsb2NrIHRvIHJpZ2h0LCBpZQogICAgICAgICAqIDE2IGJ5dGVzICg4IGluIGNhc2Ugb2YgRFhUMSkuICovCiAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpCiAgICAgICAgewogICAgICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyAocExvY2tlZFJlY3QtPlBpdGNoICogcFJlY3QtPnRvcCAvIDQpICsgKHBSZWN0LT5sZWZ0ICogMik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkKICAgICAgICB7CiAgICAgICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiBwUmVjdC0+dG9wIC8gNCkgKyAocFJlY3QtPmxlZnQgKiA0KTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsKICAgICAgICAgICAgICAgICAgICAocExvY2tlZFJlY3QtPlBpdGNoICogcFJlY3QtPnRvcCkgKwogICAgICAgICAgICAgICAgICAgIChwUmVjdC0+bGVmdCAqIFRoaXMtPmJ5dGVzUGVyUGl4ZWwpOwogICAgICAgIH0KICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICA9IHBSZWN0LT5sZWZ0OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QudG9wICAgID0gcFJlY3QtPnRvcDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0ICA9IHBSZWN0LT5yaWdodDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSA9IHBSZWN0LT5ib3R0b207CiAgICB9CgogICAgLyogTm8gZGlydGlmeWluZyBpcyBuZWVkZWQgZm9yIHRoaXMgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiAqLwogICAgVFJBQ0UoInJldHVybmluZyBtZW1vcnlAJXAsIHBpdGNoKCVkKVxuIiwgcExvY2tlZFJlY3QtPnBCaXRzLCBwTG9ja2VkUmVjdC0+UGl0Y2gpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CaW5kVGV4dHVyZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBFUlIoIlNob3VsZCBub3QgYmUgY2FsbGVkIG9uIGJhc2UgdGV4dHVyZVxuIik7CiAgICByZXR1cm47Cn0K