LyoKICogU0hMV0FQSSBvcmRpbmFsIGZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NyBNYXJjdXMgTWVpc3NuZXIKICogICAgICAgICAgIDE5OTggSvxyZ2VuIFNjaG1pZWQKICogICAgICAgICAgIDIwMDEtMjAwMyBKb24gR3JpZmZpdGhzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNkZWZpbmUgQ09NX05PX1dJTkRPV1NfSAojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAiZG9jb2JqLmgiCiNpbmNsdWRlICJleGRpc3AuaCIKI2luY2x1ZGUgInNobGd1aWQuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAic2hsb2JqLmgiCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgInNobHdhcGkuaCIKCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChzaGVsbCk7CgovKiBHZXQgYSBmdW5jdGlvbiBwb2ludGVyIGZyb20gYSBETEwgaGFuZGxlICovCiNkZWZpbmUgR0VUX0ZVTkMoZnVuYywgbW9kdWxlLCBuYW1lLCBmYWlsKSBcCiAgZG8geyBcCiAgICBpZiAoIWZ1bmMpIHsgXAogICAgICBpZiAoIVNITFdBUElfaCMjbW9kdWxlICYmICEoU0hMV0FQSV9oIyNtb2R1bGUgPSBMb2FkTGlicmFyeUEoI21vZHVsZSAiLmRsbCIpKSkgcmV0dXJuIGZhaWw7IFwKICAgICAgZnVuYyA9IChmbiMjZnVuYylHZXRQcm9jQWRkcmVzcyhTSExXQVBJX2gjI21vZHVsZSwgbmFtZSk7IFwKICAgICAgaWYgKCFmdW5jKSByZXR1cm4gZmFpbDsgXAogICAgfSBcCiAgfSB3aGlsZSAoMCkKCi8qIERMTCBoYW5kbGVzIGZvciBsYXRlIGJvdW5kIGNhbGxzICovCmV4dGVybiBISU5TVEFOQ0Ugc2hsd2FwaV9oSW5zdGFuY2U7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaHNoZWxsMzI7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaHdpbm1tOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2hjb21kbGczMjsKZXh0ZXJuIEhNT0RVTEUgU0hMV0FQSV9oY29tY3RsMzI7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaG1wcjsKZXh0ZXJuIEhNT0RVTEUgU0hMV0FQSV9odXJsbW9uOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2h2ZXJzaW9uOwoKZXh0ZXJuIERXT1JEIFNITFdBUElfVGhyZWFkUmVmX2luZGV4OwoKLyogZm9sbG93aW5nIGlzIEdVSUQgZm9yIElPYmplY3RXaXRoU2l0ZTo6U2V0U2l0ZSAgLS0gc2VlIF8xNzQgICAgICAgICAgICovCnN0YXRpYyBEV09SRCBpZDFbNF0gPSB7MHhmYzQ4MDFhMywgMHgxMWNmMmJhOSwgMHhhYTAwMjlhMiwgMHg1MjczM2QwMH07Ci8qIGZvbGxvd2luZyBpcyBHVUlEIGZvciBJUGVyc2lzdE1vbmlrZXI6OkdldENsYXNzSUQgIC0tIHNlZSBfMTc0ICAgICAgICAqLwpzdGF0aWMgRFdPUkQgaWQyWzRdID0gezB4NzllYWM5ZWUsIDB4MTFjZWJhZjksIDB4YWEwMDgyOGMsIDB4MGJhOTRiMDB9OwoKLyogRnVuY3Rpb24gcG9pbnRlcnMgZm9yIEdFVF9GVU5DIG1hY3JvOyB0aGVzZSBuZWVkIHRvIGJlIGdsb2JhbCBiZWNhdXNlIG9mIGdjYyBidWcgKi8KdHlwZWRlZiBMUElURU1JRExJU1QgKFdJTkFQSSAqZm5wU0hCcm93c2VGb3JGb2xkZXJXKShMUEJST1dTRUlORk9XKTsKc3RhdGljICBmbnBTSEJyb3dzZUZvckZvbGRlclcgcFNIQnJvd3NlRm9yRm9sZGVyVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFBsYXlTb3VuZFcpKExQQ1dTVFIsIEhNT0RVTEUsIERXT1JEKTsKc3RhdGljICBmbnBQbGF5U291bmRXIHBQbGF5U291bmRXOwp0eXBlZGVmIERXT1JEICAgKFdJTkFQSSAqZm5wU0hHZXRGaWxlSW5mb1cpKExQQ1dTVFIsRFdPUkQsU0hGSUxFSU5GT1cqLFVJTlQsVUlOVCk7CnN0YXRpYyAgZm5wU0hHZXRGaWxlSW5mb1cgcFNIR2V0RmlsZUluZm9XOwp0eXBlZGVmIFVJTlQgICAgKFdJTkFQSSAqZm5wRHJhZ1F1ZXJ5RmlsZVcpKEhEUk9QLCBVSU5ULCBMUFdTVFIsIFVJTlQpOwpzdGF0aWMgIGZucERyYWdRdWVyeUZpbGVXIHBEcmFnUXVlcnlGaWxlVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFNIR2V0UGF0aEZyb21JRExpc3RXKShMUENJVEVNSURMSVNULCBMUFdTVFIpOwpzdGF0aWMgIGZucFNIR2V0UGF0aEZyb21JRExpc3RXIHBTSEdldFBhdGhGcm9tSURMaXN0VzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFNoZWxsRXhlY3V0ZUV4VykoTFBTSEVMTEVYRUNVVEVJTkZPVyk7CnN0YXRpYyAgZm5wU2hlbGxFeGVjdXRlRXhXIHBTaGVsbEV4ZWN1dGVFeFc7CnR5cGVkZWYgSElDT04gICAoV0lOQVBJICpmbnBTSEZpbGVPcGVyYXRpb25XKShMUFNIRklMRU9QU1RSVUNUVyk7CnN0YXRpYyAgZm5wU0hGaWxlT3BlcmF0aW9uVyBwU0hGaWxlT3BlcmF0aW9uVzsKdHlwZWRlZiBVSU5UICAgIChXSU5BUEkgKmZucEV4dHJhY3RJY29uRXhXKShMUENXU1RSLCBJTlQsSElDT04gKixISUNPTiAqLCBVSU5UKTsKc3RhdGljICBmbnBFeHRyYWN0SWNvbkV4VyBwRXh0cmFjdEljb25FeFc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBTSEdldE5ld0xpbmtJbmZvVykoTFBDV1NUUiwgTFBDV1NUUiwgTFBDV1NUUiwgQk9PTCosIFVJTlQpOwpzdGF0aWMgIGZucFNIR2V0TmV3TGlua0luZm9XIHBTSEdldE5ld0xpbmtJbmZvVzsKdHlwZWRlZiBIUkVTVUxUIChXSU5BUEkgKmZucFNIRGVmRXh0cmFjdEljb25XKShMUENXU1RSLCBpbnQsIFVJTlQsIEhJQ09OKiwgSElDT04qLCBVSU5UKTsKc3RhdGljICBmbnBTSERlZkV4dHJhY3RJY29uVyBwU0hEZWZFeHRyYWN0SWNvblc7CnR5cGVkZWYgSElDT04gICAoV0lOQVBJICpmbnBFeHRyYWN0SWNvblcpKEhJTlNUQU5DRSwgTFBDV1NUUiwgVUlOVCk7CnN0YXRpYyAgZm5wRXh0cmFjdEljb25XIHBFeHRyYWN0SWNvblc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBHZXRTYXZlRmlsZU5hbWVXKShMUE9QRU5GSUxFTkFNRVcpOwpzdGF0aWMgIGZucEdldFNhdmVGaWxlTmFtZVcgcEdldFNhdmVGaWxlTmFtZVc7CnR5cGVkZWYgRFdPUkQgICAoV0lOQVBJICpmbnBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XKShIV05ELCBMUFdTVFIpOwpzdGF0aWMgIGZucFdOZXRSZXN0b3JlQ29ubmVjdGlvblcgcFdOZXRSZXN0b3JlQ29ubmVjdGlvblc7CnR5cGVkZWYgRFdPUkQgICAoV0lOQVBJICpmbnBXTmV0R2V0TGFzdEVycm9yVykoTFBEV09SRCwgTFBXU1RSLCBEV09SRCwgTFBXU1RSLCBEV09SRCk7CnN0YXRpYyAgZm5wV05ldEdldExhc3RFcnJvclcgcFdOZXRHZXRMYXN0RXJyb3JXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wUGFnZVNldHVwRGxnVykoTFBQQUdFU0VUVVBETEdXKTsKc3RhdGljICBmbnBQYWdlU2V0dXBEbGdXIHBQYWdlU2V0dXBEbGdXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wUHJpbnREbGdXKShMUFBSSU5URExHVyk7CnN0YXRpYyAgZm5wUHJpbnREbGdXIHBQcmludERsZ1c7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBHZXRPcGVuRmlsZU5hbWVXKShMUE9QRU5GSUxFTkFNRVcpOwpzdGF0aWMgIGZucEdldE9wZW5GaWxlTmFtZVcgcEdldE9wZW5GaWxlTmFtZVc7CnR5cGVkZWYgRFdPUkQgICAoV0lOQVBJICpmbnBHZXRGaWxlVmVyc2lvbkluZm9TaXplVykoTFBDV1NUUixMUERXT1JEKTsKc3RhdGljICBmbnBHZXRGaWxlVmVyc2lvbkluZm9TaXplVyBwR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBHZXRGaWxlVmVyc2lvbkluZm9XKShMUENXU1RSLERXT1JELERXT1JELExQVk9JRCk7CnN0YXRpYyAgZm5wR2V0RmlsZVZlcnNpb25JbmZvVyBwR2V0RmlsZVZlcnNpb25JbmZvVzsKdHlwZWRlZiBXT1JEICAgIChXSU5BUEkgKmZucFZlclF1ZXJ5VmFsdWVXKShMUFZPSUQsTFBDV1NUUixMUFZPSUQqLFVJTlQqKTsKc3RhdGljICBmbnBWZXJRdWVyeVZhbHVlVyBwVmVyUXVlcnlWYWx1ZVc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBDT01DVEwzMl80MTcpKEhEQyxJTlQsSU5ULFVJTlQsY29uc3QgUkVDVCosTFBDV1NUUixVSU5ULGNvbnN0IElOVCopOwpzdGF0aWMgIGZucENPTUNUTDMyXzQxNyBwQ09NQ1RMMzJfNDE3Owp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqZm5wRGxsR2V0VmVyc2lvbikoRExMVkVSU0lPTklORk8qKTsKc3RhdGljICBmbnBEbGxHZXRWZXJzaW9uIHBEbGxHZXRWZXJzaW9uOwp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqZm5wQ3JlYXRlRm9ybWF0RW51bWVyYXRvcikoVUlOVCxGT1JNQVRFVEMqLElFbnVtRk9STUFURVRDKiopOwpzdGF0aWMgZm5wQ3JlYXRlRm9ybWF0RW51bWVyYXRvciBwQ3JlYXRlRm9ybWF0RW51bWVyYXRvcjsKdHlwZWRlZiBIUkVTVUxUIChXSU5BUEkgKmZucFJlZ2lzdGVyRm9ybWF0RW51bWVyYXRvcikoTFBCQyxJRW51bUZPUk1BVEVUQyosRFdPUkQpOwpzdGF0aWMgZm5wUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yIHBSZWdpc3RlckZvcm1hdEVudW1lcmF0b3I7CgpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVNlcnZpY2UoSVVua25vd24qLFJFRkdVSUQsUkVGSUlELExQVk9JRCopOwpIUkVTVUxUIFdJTkFQSSBTSEludm9rZUNvbW1hbmQoSFdORCxJU2hlbGxGb2xkZXIqLExQQ0lURU1JRExJU1QsQk9PTCk7CkhSRVNVTFQgV0lOQVBJIENMU0lERnJvbVN0cmluZ1dyYXAoTFBDV1NUUixDTFNJRCopOwpCT09MICAgIFdJTkFQSSBTSEFib3V0SW5mb1coTFBXU1RSLERXT1JEKTsKCi8qCiBOT1RFUzogTW9zdCBmdW5jdGlvbnMgZXhwb3J0ZWQgYnkgb3JkaW5hbCBzZWVtIHRvIGJlIHN1cGVyZmxvdXMuCiBUaGUgcmVhc29uIGZvciB0aGVzZSBmdW5jdGlvbnMgdG8gYmUgdGhlcmUgaXMgdG8gcHJvdmlkZSBhIHdyYXBwZXIKIGZvciB1bmljb2RlIGZ1bmN0aW9ucyB0byBwcm92aWRlIHRoZXNlIGZ1bmN0aW9ucyBvbiBzeXN0ZW1zIHdpdGhvdXQKIHVuaWNvZGUgZnVuY3Rpb25zIGVnLiB3aW45NS93aW45OC4gU2luY2Ugd2UgaGF2ZSBzdWNoIGZ1bmN0aW9ucyB3ZSBqdXN0CiBjYWxsIHRoZXNlLiBJZiBydW5uaW5nIFdpbmUgd2l0aCBuYXRpdmUgRExMJ3MsIHNvbWUgbGF0ZSBib3VuZCBjYWxscyBtYXkKIGZhaWwuIEhvd2V2ZXIsIGl0IGlzIGJldHRlciB0byBpbXBsZW1lbnQgdGhlIGZ1bmN0aW9ucyBpbiB0aGUgZm9yd2FyZCBETEwKIGFuZCByZWNvbW1lbmQgdGhlIGJ1aWx0aW4gcmF0aGVyIHRoYW4gcmVpbXBsZW1lbnRpbmcgdGhlIGNhbGxzIGhlcmUhCiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZQogKgogKiBJbnRlcm5hbCBpbXBsZW1ldGF0aW9uIG9mIFNITFdBUElfMTEuCiAqLwpzdGF0aWMKSEFORExFIFdJTkFQSSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShIQU5ETEUgaFNoYXJlZCwgRFdPUkQgZHdEc3RQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3U3JjUHJvY0lkLCBEV09SRCBkd0FjY2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdPcHRpb25zKQp7CiAgSEFORExFIGhEc3QsIGhTcmM7CiAgRFdPUkQgZHdNeVByb2NJZCA9IEdldEN1cnJlbnRQcm9jZXNzSWQoKTsKICBIQU5ETEUgaFJldCA9IE5VTEw7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlMDhseCwlMDhseClcbiIsIGhTaGFyZWQsIGR3RHN0UHJvY0lkLCBkd1NyY1Byb2NJZCwKICAgICAgICBkd0FjY2VzcywgZHdPcHRpb25zKTsKCiAgLyogR2V0IGRlc3QgcHJvY2VzcyBoYW5kbGUgKi8KICBpZiAoZHdEc3RQcm9jSWQgPT0gZHdNeVByb2NJZCkKICAgIGhEc3QgPSBHZXRDdXJyZW50UHJvY2VzcygpOwogIGVsc2UKICAgIGhEc3QgPSBPcGVuUHJvY2VzcyhQUk9DRVNTX0RVUF9IQU5ETEUsIDAsIGR3RHN0UHJvY0lkKTsKCiAgaWYgKGhEc3QpCiAgewogICAgLyogR2V0IHNyYyBwcm9jZXNzIGhhbmRsZSAqLwogICAgaWYgKGR3U3JjUHJvY0lkID09IGR3TXlQcm9jSWQpCiAgICAgIGhTcmMgPSBHZXRDdXJyZW50UHJvY2VzcygpOwogICAgZWxzZQogICAgICBoU3JjID0gT3BlblByb2Nlc3MoUFJPQ0VTU19EVVBfSEFORExFLCAwLCBkd1NyY1Byb2NJZCk7CgogICAgaWYgKGhTcmMpCiAgICB7CiAgICAgIC8qIE1ha2UgaGFuZGxlIGF2YWlsYWJsZSB0byBkZXN0IHByb2Nlc3MgKi8KICAgICAgaWYgKCFEdXBsaWNhdGVIYW5kbGUoaERzdCwgaFNoYXJlZCwgaFNyYywgJmhSZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3QWNjZXNzLCAwLCBkd09wdGlvbnMgfCBEVVBMSUNBVEVfU0FNRV9BQ0NFU1MpKQogICAgICAgIGhSZXQgPSBOVUxMOwoKICAgICAgaWYgKGR3U3JjUHJvY0lkICE9IGR3TXlQcm9jSWQpCiAgICAgICAgQ2xvc2VIYW5kbGUoaFNyYyk7CiAgICB9CgogICAgaWYgKGR3RHN0UHJvY0lkICE9IGR3TXlQcm9jSWQpCiAgICAgIENsb3NlSGFuZGxlKGhEc3QpOwogIH0KCiAgVFJBQ0UoIlJldHVybmluZyBoYW5kbGUgJXBcbiIsIGhSZXQpOwogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS43XQogKgogKiBDcmVhdGUgYSBibG9jayBvZiBzaGFyYWJsZSBtZW1vcnkgYW5kIGluaXRpYWxpc2UgaXQgd2l0aCBkYXRhLgogKgogKiBQQVJBTVMKICogbHB2RGF0YSAgW0ldIFBvaW50ZXIgdG8gZGF0YSB0byB3cml0ZQogKiBkd1NpemUgICBbSV0gU2l6ZSBvZiBkYXRhCiAqIGR3UHJvY0lkIFtJXSBJRCBvZiBwcm9jZXNzIG93bmluZyBkYXRhCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogQSBzaGFyZWQgbWVtb3J5IGhhbmRsZQogKiBGYWlsdXJlOiBOVUxMCiAqCiAqIE5PVEVTCiAqIE9yZGluYWxzIDctMTEgcHJvdmlkZSBhIHNldCBvZiBjYWxscyB0byBjcmVhdGUgc2hhcmVkIG1lbW9yeSBiZXR3ZWVuIGEKICogZ3JvdXAgb2YgcHJvY2Vzc2VzLiBUaGUgc2hhcmVkIG1lbW9yeSBpcyB0cmVhdGVkIG9wYXF1ZWx5IGluIHRoYXQgaXRzIHNpemUKICogaXMgbm90IGV4cG9zZWQgdG8gY2xpZW50cyB3aG8gbWFwIGl0LiBUaGlzIGlzIGFjY29tcGxpc2hlZCBieSBzdG9yaW5nCiAqIHRoZSBzaXplIG9mIHRoZSBtYXAgYXMgdGhlIGZpcnN0IERXT1JEIG9mIG1hcHBlZCBkYXRhLCBhbmQgdGhlbiBvZmZzZXR0aW5nCiAqIHRoZSB2aWV3IHBvaW50ZXIgcmV0dXJuZWQgYnkgdGhpcyBzaXplLgogKgogKi8KSEFORExFIFdJTkFQSSBTSEFsbG9jU2hhcmVkKExQQ1ZPSUQgbHB2RGF0YSwgRFdPUkQgZHdTaXplLCBEV09SRCBkd1Byb2NJZCkKewogIEhBTkRMRSBoTWFwOwogIExQVk9JRCBwTWFwcGVkOwogIEhBTkRMRSBoUmV0ID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkKVxuIiwgbHB2RGF0YSwgZHdTaXplLCBkd1Byb2NJZCk7CgogIC8qIENyZWF0ZSBmaWxlIG1hcHBpbmcgb2YgdGhlIGNvcnJlY3QgbGVuZ3RoICovCiAgaE1hcCA9IENyZWF0ZUZpbGVNYXBwaW5nQShJTlZBTElEX0hBTkRMRV9WQUxVRSwgTlVMTCwgRklMRV9NQVBfUkVBRCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3U2l6ZSArIHNpemVvZihkd1NpemUpLCBOVUxMKTsKICBpZiAoIWhNYXApCiAgICByZXR1cm4gaFJldDsKCiAgLyogR2V0IGEgdmlldyBpbiBvdXIgcHJvY2VzcyBhZGRyZXNzIHNwYWNlICovCiAgcE1hcHBlZCA9IE1hcFZpZXdPZkZpbGUoaE1hcCwgRklMRV9NQVBfUkVBRCB8IEZJTEVfTUFQX1dSSVRFLCAwLCAwLCAwKTsKCiAgaWYgKHBNYXBwZWQpCiAgewogICAgLyogV3JpdGUgc2l6ZSBvZiBkYXRhLCBmb2xsb3dlZCBieSB0aGUgZGF0YSwgdG8gdGhlIHZpZXcgKi8KICAgICooKERXT1JEKilwTWFwcGVkKSA9IGR3U2l6ZTsKICAgIGlmIChscHZEYXRhKQogICAgICBtZW1jcHkoKGNoYXIgKikgcE1hcHBlZCArIHNpemVvZihkd1NpemUpLCBscHZEYXRhLCBkd1NpemUpOwoKICAgIC8qIFJlbGVhc2Ugdmlldy4gQWxsIGZ1cnRoZXIgdmlld3MgbWFwcGVkIHdpbGwgYmUgb3BhcXVlICovCiAgICBVbm1hcFZpZXdPZkZpbGUocE1hcHBlZCk7CiAgICBoUmV0ID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaE1hcCwgZHdQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0Q3VycmVudFByb2Nlc3NJZCgpLCBGSUxFX01BUF9BTExfQUNDRVNTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERVUExJQ0FURV9TQU1FX0FDQ0VTUyk7CiAgfQoKICBDbG9zZUhhbmRsZShoTWFwKTsKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCBbU0hMV0FQSS44XQogKgogKiBHZXQgYSBwb2ludGVyIHRvIGEgYmxvY2sgb2Ygc2hhcmVkIG1lbW9yeSBmcm9tIGEgc2hhcmVkIG1lbW9yeSBoYW5kbGUuCiAqCiAqIFBBUkFNUwogKiBoU2hhcmVkICBbSV0gU2hhcmVkIG1lbW9yeSBoYW5kbGUKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGhTaGFyZWQKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBBIHBvaW50ZXIgdG8gdGhlIHNoYXJlZCBtZW1vcnkKICogRmFpbHVyZTogTlVMTAogKgogKi8KUFZPSUQgV0lOQVBJIFNITG9ja1NoYXJlZChIQU5ETEUgaFNoYXJlZCwgRFdPUkQgZHdQcm9jSWQpCnsKICBIQU5ETEUgaER1cDsKICBMUFZPSUQgcE1hcHBlZDsKCiAgVFJBQ0UoIiglcCAlbGQpXG4iLCBoU2hhcmVkLCBkd1Byb2NJZCk7CgogIC8qIEdldCBoYW5kbGUgdG8gc2hhcmVkIG1lbW9yeSBmb3IgY3VycmVudCBwcm9jZXNzICovCiAgaER1cCA9IFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKGhTaGFyZWQsIGR3UHJvY0lkLCBHZXRDdXJyZW50UHJvY2Vzc0lkKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfTUFQX0FMTF9BQ0NFU1MsIDApOwogIC8qIEdldCBWaWV3ICovCiAgcE1hcHBlZCA9IE1hcFZpZXdPZkZpbGUoaER1cCwgRklMRV9NQVBfUkVBRCB8IEZJTEVfTUFQX1dSSVRFLCAwLCAwLCAwKTsKICBDbG9zZUhhbmRsZShoRHVwKTsKCiAgaWYgKHBNYXBwZWQpCiAgICByZXR1cm4gKGNoYXIgKikgcE1hcHBlZCArIHNpemVvZihEV09SRCk7IC8qIEhpZGUgc2l6ZSAqLwogIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAIFtTSExXQVBJLjldCiAqCiAqIFJlbGVhc2UgYSBwb2ludGVyIHRvIGEgYmxvY2sgb2Ygc2hhcmVkIG1lbW9yeS4KICoKICogUEFSQU1TCiAqIGxwVmlldyBbSV0gU2hhcmVkIG1lbW9yeSBwb2ludGVyCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogVFJVRQogKiBGYWlsdXJlOiBGQUxTRQogKgogKi8KQk9PTCBXSU5BUEkgU0hVbmxvY2tTaGFyZWQoTFBWT0lEIGxwVmlldykKewogIFRSQUNFKCIoJXApXG4iLCBscFZpZXcpOwogIHJldHVybiBVbm1hcFZpZXdPZkZpbGUoKGNoYXIgKikgbHBWaWV3IC0gc2l6ZW9mKERXT1JEKSk7IC8qIEluY2x1ZGUgc2l6ZSAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAIFtTSExXQVBJLjEwXQogKgogKiBEZXN0cm95IGEgYmxvY2sgb2Ygc2hhcmFibGUgbWVtb3J5LgogKgogKiBQQVJBTVMKICogaFNoYXJlZCAgW0ldIFNoYXJlZCBtZW1vcnkgaGFuZGxlCiAqIGR3UHJvY0lkIFtJXSBJRCBvZiBwcm9jZXNzIG93bmluZyBoU2hhcmVkCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogVFJVRQogKiBGYWlsdXJlOiBGQUxTRQogKgogKi8KQk9PTCBXSU5BUEkgU0hGcmVlU2hhcmVkKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd1Byb2NJZCkKewogIEhBTkRMRSBoQ2xvc2U7CgogIFRSQUNFKCIoJXAgJWxkKVxuIiwgaFNoYXJlZCwgZHdQcm9jSWQpOwoKICAvKiBHZXQgYSBjb3B5IG9mIHRoZSBoYW5kbGUgZm9yIG91ciBwcm9jZXNzLCBjbG9zaW5nIHRoZSBzb3VyY2UgaGFuZGxlICovCiAgaENsb3NlID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaFNoYXJlZCwgZHdQcm9jSWQsIEdldEN1cnJlbnRQcm9jZXNzSWQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFX01BUF9BTExfQUNDRVNTLERVUExJQ0FURV9DTE9TRV9TT1VSQ0UpOwogIC8qIENsb3NlIGxvY2FsIGNvcHkgKi8KICByZXR1cm4gQ2xvc2VIYW5kbGUoaENsb3NlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgIFtTSExXQVBJLjExXQogKgogKiBDb3B5IGEgc2hhcmFibGUgbWVtb3J5IGhhbmRsZSBmcm9tIG9uZSBwcm9jZXNzIHRvIGFub3RoZXIuCiAqCiAqIFBBUkFNUwogKiBoU2hhcmVkICAgICBbSV0gU2hhcmVkIG1lbW9yeSBoYW5kbGUgdG8gZHVwbGljYXRlCiAqIGR3RHN0UHJvY0lkIFtJXSBJRCBvZiB0aGUgcHJvY2VzcyB3YW50aW5nIHRoZSBkdXBsaWNhdGVkIGhhbmRsZQogKiBkd1NyY1Byb2NJZCBbSV0gSUQgb2YgdGhlIHByb2Nlc3Mgb3duaW5nIGhTaGFyZWQKICogZHdBY2Nlc3MgICAgW0ldIERlc2lyZWQgRHVwbGljYXRlSGFuZGxlKCkgYWNjZXNzCiAqIGR3T3B0aW9ucyAgIFtJXSBEZXNpcmVkIER1cGxpY2F0ZUhhbmRsZSgpIG9wdGlvbnMKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBBIGhhbmRsZSBzdWl0YWJsZSBmb3IgdXNlIGJ5IHRoZSBkd0RzdFByb2NJZCBwcm9jZXNzLgogKiBGYWlsdXJlOiBBIE5VTEwgaGFuZGxlLgogKgogKi8KSEFORExFIFdJTkFQSSBTSE1hcEhhbmRsZShIQU5ETEUgaFNoYXJlZCwgRFdPUkQgZHdEc3RQcm9jSWQsIERXT1JEIGR3U3JjUHJvY0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3QWNjZXNzLCBEV09SRCBkd09wdGlvbnMpCnsKICBIQU5ETEUgaFJldDsKCiAgaFJldCA9IFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKGhTaGFyZWQsIGR3RHN0UHJvY0lkLCBkd1NyY1Byb2NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdBY2Nlc3MsIGR3T3B0aW9ucyk7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xM10KICoKICogQ3JlYXRlIGFuZCByZWdpc3RlciBhIGNsaXBib2FyZCBlbnVtZXJhdG9yIGZvciBhIHdlYiBicm93c2VyLgogKgogKiBQQVJBTVMKICogIGxwQkMgICAgICBbSV0gQmluZGluZyBjb250ZXh0CiAqICBscFVua25vd24gW0ldIEFuIG9iamVjdCBleHBvc2luZyB0aGUgSVdlYkJyb3dzZXJBcHAgaW50ZXJmYWNlCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUuCiAqCiAqIE5PVEVTCiAqICBUaGUgZW51bWVyYXRvciBpcyBzdG9yZWQgYXMgYSBwcm9wZXJ0eSBvZiB0aGUgd2ViIGJyb3dzZXIuIElmIGl0IGRvZXMgbm90CiAqICB5ZXQgZXhpc3QsIGl0IGlzIGNyZWF0ZWQgYW5kIHNldCBiZWZvcmUgYmVpbmcgcmVnaXN0ZXJlZC4KICovCkhSRVNVTFQgV0lOQVBJIFJlZ2lzdGVyRGVmYXVsdEFjY2VwdEhlYWRlcnMoTFBCQyBscEJDLCBJVW5rbm93biAqbHBVbmtub3duKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6UHJvcGVydHlbXSA9IHsgJ3snLCdEJywnMCcsJ0YnLCdDJywnQScsJzQnLCcyJywnMCcsCiAgICAgICctJywnRCcsJzMnLCdGJywnNScsJy0nLCcxJywnMScsJ0MnLCdGJywgJy0nLCdCJywnMicsJzEnLCcxJywnLScsJzAnLAogICAgICAnMCcsJ0EnLCdBJywnMCcsJzAnLCc0JywnQScsJ0UnLCc4JywnMycsJzcnLCd9JywnXDAnIH07CiAgSUVudW1GT1JNQVRFVEMqIHBJRW51bUZvcm1hdEV0YyA9IE5VTEw7CiAgVkFSSUFOVEFSRyB2YXI7CiAgSFJFU1VMVCBoUmV0OwogIElXZWJCcm93c2VyQXBwKiBwQnJvd3NlciA9IE5VTEw7CgogIFRSQUNFKCIoJXAsICVwKVxuIiwgbHBCQywgbHBVbmtub3duKTsKCiAgLyogR2V0IEFuIElXZWJCcm93c2VyQXBwIGludGVyZmFjZSBmcm9tICBscFVua25vd24gKi8KICBoUmV0ID0gSVVua25vd25fUXVlcnlTZXJ2aWNlKGxwVW5rbm93biwgJklJRF9JV2ViQnJvd3NlckFwcCwgJklJRF9JV2ViQnJvd3NlckFwcCwgKFBWT0lEKSZwQnJvd3Nlcik7CiAgaWYgKEZBSUxFRChoUmV0KSB8fCAhcEJyb3dzZXIpCiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKCiAgVl9WVCgmdmFyKSA9IFZUX0VNUFRZOwoKICAvKiBUaGUgcHJvcGVydHkgd2UgZ2V0IGlzIHRoZSBicm93c2VycyBjbGlwYm9hcmQgZW51bWVyYXRvciAqLwogIGhSZXQgPSBJV2ViQnJvd3NlckFwcF9HZXRQcm9wZXJ0eShwQnJvd3NlciwgKEJTVFIpc3pQcm9wZXJ0eSwgJnZhcik7CiAgaWYgKEZBSUxFRChoUmV0KSkKICAgIHJldHVybiBoUmV0OwoKICBpZiAoVl9WVCgmdmFyKSA9PSBWVF9FTVBUWSkKICB7CiAgICAvKiBJdGVyYXRlIHRocm91Z2ggYWNjZXB0ZWQgZG9jdW1lbnRzIGFuZCBSZWdpc3RlckNsaXBCb2FyZEZvcm1hdEEoKSB0aGVtICovCiAgICBjaGFyIHN6S2V5QnVmZlsxMjhdLCBzelZhbHVlQnVmZlsxMjhdOwogICAgRFdPUkQgZHdLZXlTaXplLCBkd1ZhbHVlU2l6ZSwgZHdSZXQgPSAwLCBkd0NvdW50ID0gMCwgZHdOdW1WYWx1ZXMsIGR3VHlwZTsKICAgIEZPUk1BVEVUQyogZm9ybWF0TGlzdCwgKmZvcm1hdDsKICAgIEhLRVkgaERvY3M7CgogICAgVFJBQ0UoIlJlZ2lzdGVyaW5nIGZvcm1hdHMgYW5kIGNyZWF0aW5nIElFbnVtRk9STUFURVRDIGluc3RhbmNlXG4iKTsKCiAgICBpZiAoIVJlZ09wZW5LZXlBKEhLRVlfTE9DQUxfTUFDSElORSwgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnQiCiAgICAgICAgICAgICAgICAgICAgICJWZXJzaW9uXFxJbnRlcm5ldCBTZXR0aW5nc1xcQWNjZXB0ZWQgRG9jdW1lbnRzIiwgJmhEb2NzKSkKICAgICAgcmV0dXJuIEVfRkFJTDsKCiAgICAvKiBHZXQgY291bnQgb2YgdmFsdWVzIGluIGtleSAqLwogICAgd2hpbGUgKCFkd1JldCkKICAgIHsKICAgICAgZHdLZXlTaXplID0gc2l6ZW9mKHN6S2V5QnVmZik7CiAgICAgIGR3UmV0ID0gUmVnRW51bVZhbHVlQShoRG9jcyxkd0NvdW50LHN6S2V5QnVmZiwmZHdLZXlTaXplLDAsJmR3VHlwZSwwLDApOwogICAgICBkd0NvdW50Kys7CiAgICB9CgogICAgZHdOdW1WYWx1ZXMgPSBkd0NvdW50OwoKICAgIC8qIE5vdGU6IGR3Q291bnQgPSBudW1iZXIgb2YgaXRlbXMgKyAxOyBUaGUgZXh0cmEgaXRlbSBpcyB0aGUgZW5kIG5vZGUgKi8KICAgIGZvcm1hdCA9IGZvcm1hdExpc3QgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHdDb3VudCAqIHNpemVvZihGT1JNQVRFVEMpKTsKICAgIGlmICghZm9ybWF0TGlzdCkKICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgaWYgKGR3TnVtVmFsdWVzID4gMSkKICAgIHsKICAgICAgZHdSZXQgPSAwOwogICAgICBkd0NvdW50ID0gMDsKCiAgICAgIGR3TnVtVmFsdWVzLS07CgogICAgICAvKiBSZWdpc3RlciBjbGlwYm9hcmQgZm9ybWF0cyBmb3IgdGhlIHZhbHVlcyBhbmQgcG9wdWxhdGUgZm9ybWF0IGxpc3QgKi8KICAgICAgd2hpbGUoIWR3UmV0ICYmIGR3Q291bnQgPCBkd051bVZhbHVlcykKICAgICAgewogICAgICAgIGR3S2V5U2l6ZSA9IHNpemVvZihzektleUJ1ZmYpOwogICAgICAgIGR3VmFsdWVTaXplID0gc2l6ZW9mKHN6VmFsdWVCdWZmKTsKICAgICAgICBkd1JldCA9IFJlZ0VudW1WYWx1ZUEoaERvY3MsIGR3Q291bnQsIHN6S2V5QnVmZiwgJmR3S2V5U2l6ZSwgMCwgJmR3VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFBCWVRFKXN6VmFsdWVCdWZmLCAmZHdWYWx1ZVNpemUpOwogICAgICAgIGlmICghZHdSZXQpCiAgICAgICAgICByZXR1cm4gRV9GQUlMOwoKICAgICAgICBmb3JtYXQtPmNmRm9ybWF0ID0gUmVnaXN0ZXJDbGlwYm9hcmRGb3JtYXRBKHN6VmFsdWVCdWZmKTsKICAgICAgICBmb3JtYXQtPnB0ZCA9IE5VTEw7CiAgICAgICAgZm9ybWF0LT5kd0FzcGVjdCA9IDE7CiAgICAgICAgZm9ybWF0LT5saW5kZXggPSA0OwogICAgICAgIGZvcm1hdC0+dHltZWQgPSAtMTsKCiAgICAgICAgZm9ybWF0Kys7CiAgICAgICAgZHdDb3VudCsrOwogICAgICB9CiAgICB9CgogICAgLyogVGVybWluYXRlIHRoZSAobWF5YmUgZW1wdHkpIGxpc3QsIGxhc3QgZW50cnkgaGFzIGEgY2ZGb3JtYXQgb2YgMCAqLwogICAgZm9ybWF0LT5jZkZvcm1hdCA9IDA7CiAgICBmb3JtYXQtPnB0ZCA9IE5VTEw7CiAgICBmb3JtYXQtPmR3QXNwZWN0ID0gMTsKICAgIGZvcm1hdC0+bGluZGV4ID0gNDsKICAgIGZvcm1hdC0+dHltZWQgPSAtMTsKCiAgICAvKiBDcmVhdGUgYSBjbGlwYm9hcmQgZW51bWVyYXRvciAqLwogICAgR0VUX0ZVTkMocENyZWF0ZUZvcm1hdEVudW1lcmF0b3IsIHVybG1vbiwgIkNyZWF0ZUZvcm1hdEVudW1lcmF0b3IiLCBFX0ZBSUwpOwogICAgaFJldCA9IHBDcmVhdGVGb3JtYXRFbnVtZXJhdG9yKGR3TnVtVmFsdWVzLCBmb3JtYXRMaXN0LCAmcElFbnVtRm9ybWF0RXRjKTsKCiAgICBpZiAoRkFJTEVEKGhSZXQpIHx8ICFwSUVudW1Gb3JtYXRFdGMpCiAgICAgIHJldHVybiBoUmV0OwoKICAgIC8qIFNldCBvdXIgZW51bWVyYXRvciBhcyB0aGUgYnJvd3NlcnMgcHJvcGVydHkgKi8KICAgIFZfVlQoJnZhcikgPSBWVF9VTktOT1dOOwogICAgVl9VTktOT1dOKCZ2YXIpID0gKElVbmtub3duKilwSUVudW1Gb3JtYXRFdGM7CgogICAgaFJldCA9IElXZWJCcm93c2VyQXBwX1B1dFByb3BlcnR5KHBCcm93c2VyLCAoQlNUUilzelByb3BlcnR5LCB2YXIpOwogICAgaWYgKEZBSUxFRChoUmV0KSkKICAgIHsKICAgICAgIElFbnVtRk9STUFURVRDX1JlbGVhc2UocElFbnVtRm9ybWF0RXRjKTsKICAgICAgIGdvdG8gUmVnaXN0ZXJEZWZhdWx0QWNjZXB0SGVhZGVyc19FeGl0OwogICAgfQogIH0KCiAgaWYgKFZfVlQoJnZhcikgPT0gVlRfVU5LTk9XTikKICB7CiAgICAvKiBPdXIgdmFyaWFudCBpcyBob2xkaW5nIHRoZSBjbGlwYm9hcmQgZW51bWVyYXRvciAqLwogICAgSVVua25vd24qIHBJVW5rbm93biA9IFZfVU5LTk9XTigmdmFyKTsKICAgIElFbnVtRk9STUFURVRDKiBwQ2xvbmUgPSBOVUxMOwoKICAgIFRSQUNFKCJSZXRyaWV2ZWQgSUVudW1GT1JNQVRFVEMgcHJvcGVydHlcbiIpOwoKICAgIC8qIEdldCBhbiBJRW51bUZvcm1hdEV0YyBpbnRlcmZhY2UgZnJvbSB0aGUgdmFyaWFudHMgdmFsdWUgKi8KICAgIHBJRW51bUZvcm1hdEV0YyA9IE5VTEw7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UocElVbmtub3duLCAmSUlEX0lFbnVtRk9STUFURVRDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQVk9JRCkmcElFbnVtRm9ybWF0RXRjKTsKICAgIGlmICghaFJldCAmJiBwSUVudW1Gb3JtYXRFdGMpCiAgICB7CiAgICAgIC8qIENsb25lIGFuZCByZWdpc3RlciB0aGUgZW51bWVyYXRvciAqLwogICAgICBoUmV0ID0gSUVudW1GT1JNQVRFVENfQ2xvbmUocElFbnVtRm9ybWF0RXRjLCAmcENsb25lKTsKICAgICAgaWYgKCFoUmV0ICYmIHBDbG9uZSkKICAgICAgewogICAgICAgIEdFVF9GVU5DKHBSZWdpc3RlckZvcm1hdEVudW1lcmF0b3IsIHVybG1vbiwgIlJlZ2lzdGVyRm9ybWF0RW51bWVyYXRvciIsIEVfRkFJTCk7CiAgICAgICAgcFJlZ2lzdGVyRm9ybWF0RW51bWVyYXRvcihscEJDLCBwQ2xvbmUsIDApOwoKICAgICAgICBJRW51bUZPUk1BVEVUQ19SZWxlYXNlKHBDbG9uZSk7CiAgICAgIH0KCiAgICAgIC8qIFJlbGVhc2UgdGhlIElFbnVtRm9ybWF0RXRjIGludGVyZmFjZSAqLwogICAgICBJRW51bUZPUk1BVEVUQ19SZWxlYXNlKHBJVW5rbm93bik7CiAgICB9CiAgICBJVW5rbm93bl9SZWxlYXNlKFZfVU5LTk9XTigmdmFyKSk7CiAgfQoKUmVnaXN0ZXJEZWZhdWx0QWNjZXB0SGVhZGVyc19FeGl0OgogIElXZWJCcm93c2VyQXBwX1JlbGVhc2UocEJyb3dzZXIpOwogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTVdCiAqCiAqIEdldCBFeHBsb3JlcnMgIkFjY2VwdExhbmd1YWdlIiBzZXR0aW5nLgogKgogKiBQQVJBTVMKICogIGxhbmdidWYgW09dIERlc3RpbmF0aW9uIGZvciBsYW5ndWFnZSBzdHJpbmcKICogIGJ1ZmxlbiAgW0ldIExlbmd0aCBvZiBsYW5nYnVmCiAqICAgICAgICAgIFswXSBTdWNjZXNzOiB1c2VkIGxlbmd0aCBvZiBsYW5nYnVmCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suICAgbGFuZ2J1ZiBpcyBzZXQgdG8gdGhlIGxhbmd1YWdlIHN0cmluZyBmb3VuZC4KICogIEZhaWx1cmU6IEVfRkFJTCwgSWYgYW55IGFyZ3VtZW50cyBhcmUgaW52YWxpZCwgZXJyb3Igb2NjdXJyZWQsIG9yIEV4cGxvcmVyCiAqICAgICAgICAgICBkb2VzIG5vdCBjb250YWluIHRoZSBzZXR0aW5nLgogKiAgICAgICAgICAgRV9JTlZBTElEQVJHLCBJZiB0aGUgYnVmZmVyIGlzIG5vdCBiaWcgZW5vdWdoCiAqLwpIUkVTVUxUIFdJTkFQSSBHZXRBY2NlcHRMYW5ndWFnZXNXKCBMUFdTVFIgbGFuZ2J1ZiwgTFBEV09SRCBidWZsZW4pCnsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzemtleVdbXSA9IHsKCSdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKCSdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsCgknSScsJ24nLCd0JywnZScsJ3InLCduJywnZScsJ3QnLCcgJywnRScsJ3gnLCdwJywnbCcsJ28nLCdyJywnZScsJ3InLCdcXCcsCgknSScsJ24nLCd0JywnZScsJ3InLCduJywnYScsJ3QnLCdpJywnbycsJ24nLCdhJywnbCcsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgdmFsdWVXW10gPSB7CgknQScsJ2MnLCdjJywnZScsJ3AnLCd0JywnTCcsJ2EnLCduJywnZycsJ3UnLCdhJywnZycsJ2UnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIGVudXNXW10gPSB7J2UnLCduJywnLScsJ3UnLCdzJywwfTsKICAgIERXT1JEIG15c3RybGVuLCBteXR5cGU7CiAgICBIS0VZIG15a2V5OwogICAgSFJFU1VMVCByZXR2YWw7CiAgICBMQ0lEIG15bGNpZDsKICAgIFdDSEFSICpteXN0cjsKCiAgICBpZighbGFuZ2J1ZiB8fCAhYnVmbGVuIHx8ICEqYnVmbGVuKQoJcmV0dXJuIEVfRkFJTDsKCiAgICBteXN0cmxlbiA9ICgqYnVmbGVuID4gMjApID8gKmJ1ZmxlbiA6IDIwIDsKICAgIG15c3RyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXQ0hBUikgKiBteXN0cmxlbik7CiAgICBSZWdPcGVuS2V5VyhIS0VZX0NVUlJFTlRfVVNFUiwgc3prZXlXLCAmbXlrZXkpOwogICAgaWYoUmVnUXVlcnlWYWx1ZUV4VyhteWtleSwgdmFsdWVXLCAwLCAmbXl0eXBlLCAoUEJZVEUpbXlzdHIsICZteXN0cmxlbikpIHsKICAgICAgICAvKiBEaWQgbm90IGZpbmQgdmFsdWUgKi8KICAgICAgICBteWxjaWQgPSBHZXRVc2VyRGVmYXVsdExDSUQoKTsKICAgICAgICAvKiBzb21laG93IHRoZSBteWxjaWQgdHJhbnNsYXRlcyBpbnRvICJlbi11cyIKICAgICAgICAgKiAgdGhpcyBpcyBzaW1pbGFyIHRvICJMT0NBTEVfU0FCQlJFVkxBTkdOQU1FIgogICAgICAgICAqICB3aGljaCBjb3VsZCBiZSBnb3R0ZW4gdmlhIEdldExvY2FsZUluZm8uCiAgICAgICAgICogIFRoZSBvbmx5IHByb2JsZW0gaXMgTE9DQUxFX1NBQkJSRVZMQU5HVUFHRSIgaXMKICAgICAgICAgKiAgYSAzIGNoYXIgc3RyaW5nIChmaXJzdCAyIGFyZSBjb3VudHJ5IGNvZGUgYW5kIHRoaXJkIGlzCiAgICAgICAgICogIGxldHRlciBmb3IgInN1Ymxhbmd1YWdlIiwgd2hpY2ggZG9lcyBub3QgY29tZSBjbG9zZSB0bwogICAgICAgICAqICAiZW4tdXMiCiAgICAgICAgICovCiAgICAgICAgbHN0cmNweVcobXlzdHIsIGVudXNXKTsKICAgICAgICBteXN0cmxlbiA9IGxzdHJsZW5XKG15c3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogaGFuZGxlIHJldHVybmVkIHN0cmluZyAqLwogICAgICAgIEZJWE1FKCJtaXNzaW5nIGNvZGVcbiIpOwogICAgfQogICAgbWVtY3B5KCBsYW5nYnVmLCBteXN0ciwgbWluKCpidWZsZW4sc3RybGVuVyhteXN0cikrMSkqc2l6ZW9mKFdDSEFSKSApOwoKICAgIGlmKCpidWZsZW4gPiBzdHJsZW5XKG15c3RyKSkgewoJKmJ1ZmxlbiA9IHN0cmxlblcobXlzdHIpOwoJcmV0dmFsID0gU19PSzsKICAgIH0gZWxzZSB7CgkqYnVmbGVuID0gMDsKCXJldHZhbCA9IEVfSU5WQUxJREFSRzsKCVNldExhc3RFcnJvcihFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKTsKICAgIH0KICAgIFJlZ0Nsb3NlS2V5KG15a2V5KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG15c3RyKTsKICAgIHJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNF0KICoKICogQXNjaWkgdmVyc2lvbiBvZiBHZXRBY2NlcHRMYW5ndWFnZXNXLgogKi8KSFJFU1VMVCBXSU5BUEkgR2V0QWNjZXB0TGFuZ3VhZ2VzQSggTFBTVFIgbGFuZ2J1ZiwgTFBEV09SRCBidWZsZW4pCnsKICAgIFdDSEFSICpsYW5nYnVmVzsKICAgIERXT1JEIGJ1ZmxlblcsIGNvbnZsZW47CiAgICBIUkVTVUxUIHJldHZhbDsKCiAgICBpZighbGFuZ2J1ZiB8fCAhYnVmbGVuIHx8ICEqYnVmbGVuKSByZXR1cm4gRV9GQUlMOwoKICAgIGJ1ZmxlblcgPSAqYnVmbGVuOwogICAgbGFuZ2J1ZlcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSAqIGJ1ZmxlblcpOwogICAgcmV0dmFsID0gR2V0QWNjZXB0TGFuZ3VhZ2VzVyhsYW5nYnVmVywgJmJ1ZmxlblcpOwoKICAgIC8qIEZJWE1FOiB0aGlzIGlzIHdyb25nLCB0aGUgc3RyaW5nIG1heSBub3QgYmUgbnVsbC10ZXJtaW5hdGVkICovCiAgICBjb252bGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGxhbmdidWZXLCAtMSwgbGFuZ2J1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpidWZsZW4sIE5VTEwsIE5VTEwpOwogICAgKmJ1ZmxlbiA9IGJ1ZmxlblcgPyBjb252bGVuIDogMDsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBsYW5nYnVmVyk7CiAgICByZXR1cm4gcmV0dmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjNdCiAqCiAqIENvbnZlcnQgYSBHVUlEIHRvIGEgc3RyaW5nLgogKgogKiBQQVJBTVMKICogIGd1aWQgICAgIFtJXSBHVUlEIHRvIGNvbnZlcnQKICogIGxwc3pEZXN0IFtPXSBEZXN0aW5hdGlvbiBmb3Igc3RyaW5nCiAqICBjY2hNYXggICBbSV0gTGVuZ3RoIG9mIG91dHB1dCBidWZmZXIKICoKICogUkVUVVJOUwogKiAgVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nIGNyZWF0ZWQuCiAqLwpJTlQgV0lOQVBJIFNIU3RyaW5nRnJvbUdVSURBKFJFRkdVSUQgZ3VpZCwgTFBTVFIgbHBzekRlc3QsIElOVCBjY2hNYXgpCnsKICBjaGFyIHhndWlkWzQwXTsKICBJTlQgaUxlbjsKCiAgVFJBQ0UoIiglcywlcCwlZClcbiIsIGRlYnVnc3RyX2d1aWQoZ3VpZCksIGxwc3pEZXN0LCBjY2hNYXgpOwoKICBzcHJpbnRmKHhndWlkLCAieyUwOGxYLSUwNFgtJTA0WC0lMDJYJTAyWC0lMDJYJTAyWCUwMlglMDJYJTAyWCUwMlh9IiwKICAgICAgICAgIGd1aWQtPkRhdGExLCBndWlkLT5EYXRhMiwgZ3VpZC0+RGF0YTMsCiAgICAgICAgICBndWlkLT5EYXRhNFswXSwgZ3VpZC0+RGF0YTRbMV0sIGd1aWQtPkRhdGE0WzJdLCBndWlkLT5EYXRhNFszXSwKICAgICAgICAgIGd1aWQtPkRhdGE0WzRdLCBndWlkLT5EYXRhNFs1XSwgZ3VpZC0+RGF0YTRbNl0sIGd1aWQtPkRhdGE0WzddKTsKCiAgaUxlbiA9IHN0cmxlbih4Z3VpZCkgKyAxOwoKICBpZiAoaUxlbiA+IGNjaE1heCkKICAgIHJldHVybiAwOwogIG1lbWNweShscHN6RGVzdCwgeGd1aWQsIGlMZW4pOwogIHJldHVybiBpTGVuOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjRdCiAqCiAqIENvbnZlcnQgYSBHVUlEIHRvIGEgc3RyaW5nLgogKgogKiBQQVJBTVMKICogIGd1aWQgW0ldIEdVSUQgdG8gY29udmVydAogKiAgc3RyICBbT10gRGVzdGluYXRpb24gZm9yIHN0cmluZwogKiAgY21heCBbSV0gTGVuZ3RoIG9mIG91dHB1dCBidWZmZXIKICoKICogUkVUVVJOUwogKiAgVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nIGNyZWF0ZWQuCiAqLwpJTlQgV0lOQVBJIFNIU3RyaW5nRnJvbUdVSURXKFJFRkdVSUQgZ3VpZCwgTFBXU1RSIGxwc3pEZXN0LCBJTlQgY2NoTWF4KQp7CiAgV0NIQVIgeGd1aWRbNDBdOwogIElOVCBpTGVuOwogIHN0YXRpYyBjb25zdCBXQ0hBUiB3c3pGb3JtYXRbXSA9IHsneycsJyUnLCcwJywnOCcsJ2wnLCdYJywnLScsJyUnLCcwJywnNCcsJ1gnLCctJywnJScsJzAnLCc0JywnWCcsJy0nLAogICAgICAnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsJ1gnLCctJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywKICAgICAgJ1gnLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJ30nLDB9OwoKICBUUkFDRSgiKCVzLCVwLCVkKVxuIiwgZGVidWdzdHJfZ3VpZChndWlkKSwgbHBzekRlc3QsIGNjaE1heCk7CgogIHNwcmludGZXKHhndWlkLCB3c3pGb3JtYXQsIGd1aWQtPkRhdGExLCBndWlkLT5EYXRhMiwgZ3VpZC0+RGF0YTMsCiAgICAgICAgICBndWlkLT5EYXRhNFswXSwgZ3VpZC0+RGF0YTRbMV0sIGd1aWQtPkRhdGE0WzJdLCBndWlkLT5EYXRhNFszXSwKICAgICAgICAgIGd1aWQtPkRhdGE0WzRdLCBndWlkLT5EYXRhNFs1XSwgZ3VpZC0+RGF0YTRbNl0sIGd1aWQtPkRhdGE0WzddKTsKCiAgaUxlbiA9IHN0cmxlblcoeGd1aWQpICsgMTsKCiAgaWYgKGlMZW4gPiBjY2hNYXgpCiAgICByZXR1cm4gMDsKICBtZW1jcHkobHBzekRlc3QsIHhndWlkLCBpTGVuKnNpemVvZihXQ0hBUikpOwogIHJldHVybiBpTGVuOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjVdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGFscGhhYmV0aWMuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYWxwaGFiZXRpYywKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhckFscGhhV3JhcFcoV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgQzFfQUxQSEEpICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNl0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgdXBwZXItY2FzZS4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyB1cHBlci1jYXNlLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyVXBwZXJXcmFwVyhXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiBDMV9VUFBFUikgIT0gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBsb3dlci1jYXNlLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGxvd2VyLWNhc2UsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJMb3dlcldyYXBXKFdDSEFSIHdjKQp7CiAgICByZXR1cm4gKGdldF9jaGFyX3R5cGVXKHdjKSAmIEMxX0xPV0VSKSAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjhdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGFscGhhYmV0aWMgb3IgYSBkaWdpdC4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhbHBoYWJldGljIG9yIGEgZGlnaXQsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJBbHBoYU51bWVyaWNXcmFwVyhXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiAoQzFfQUxQSEF8QzFfRElHSVQpKSAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjldCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgc3BhY2UuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBzcGFjZSwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhclNwYWNlVyhXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiBDMV9TUEFDRSkgIT0gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMwXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGJsYW5rLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgYmxhbmssCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJCbGFua1coV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgQzFfQkxBTkspICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMV0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgcHVuY3R1YXRpb24uCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgcHVuY3R1YXRpb24sCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJQdW5jdFcoV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgQzFfUFVOQ1QpICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMl0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgYSBjb250cm9sIGNoYXJhY3Rlci4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIGNvbnRyb2wgY2hhcmFjdGVyLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyQ250cmxXKFdDSEFSIHdjKQp7CiAgICByZXR1cm4gKGdldF9jaGFyX3R5cGVXKHdjKSAmIEMxX0NOVFJMKSAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzNdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgZGlnaXQuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBkaWdpdCwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhckRpZ2l0VyhXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiBDMV9ESUdJVCkgIT0gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM0XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGhleCBkaWdpdC4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIGhleCBkaWdpdCwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhclhEaWdpdFcoV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgQzFfWERJR0lUKSAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzVdCiAqCiAqLwpCT09MIFdJTkFQSSBHZXRTdHJpbmdUeXBlM0V4VyhMUFdTVFIgbHBzelN0ciwgRFdPUkQgZHdMZW4sIExQVk9JRCBwMykKewogICAgRklYTUUoIiglcywweCUwOGx4LCVwKTogc3R1YlxuIiwgZGVidWdzdHJfdyhscHN6U3RyKSwgZHdMZW4sIHAzKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzZdCiAqCiAqIEluc2VydCBhIGJpdG1hcCBtZW51IGl0ZW0gYXQgdGhlIGJvdHRvbSBvZiBhIG1lbnUuCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgW0ldIE1lbnUgdG8gaW5zZXJ0IGludG8KICogIGZsYWdzIFtJXSBGbGFncyBmb3IgaW5zZXJ0aW9uCiAqICBpZCAgICBbSV0gTWVudSBJRCBvZiB0aGUgaXRlbQogKiAgc3RyICAgW0ldIE1lbnUgdGV4dCBmb3IgdGhlIGl0ZW0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRSwgIHRoZSBpdGVtIGlzIGluc2VydGVkIGludG8gdGhlIG1lbnUKICogIEZhaWx1cmU6IEZBTFNFLCBpZiBhbnkgcGFyYW1ldGVyIGlzIGludmFsaWQKICovCkJPT0wgV0lOQVBJIEFwcGVuZE1lbnVXcmFwVyhITUVOVSBoTWVudSwgVUlOVCBmbGFncywgVUlOVCBpZCwgTFBDV1NUUiBzdHIpCnsKICAgIFRSQUNFKCIoJXAsMHglMDh4LDB4JTA4eCwlcylcbiIsaE1lbnUsIGZsYWdzLCBpZCwgZGVidWdzdHJfdyhzdHIpKTsKICAgIHJldHVybiBJbnNlcnRNZW51VyhoTWVudSwgLTEsIGZsYWdzIHwgTUZfQklUTUFQLCBpZCwgc3RyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjc0XQogKgogKiBHZXQgdGhlIHRleHQgZnJvbSBhIGdpdmVuIGRpYWxvZyBpdGVtLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgIFtJXSBIYW5kbGUgb2YgZGlhbG9nCiAqICBuSXRlbSAgICBbSV0gSW5kZXggb2YgaXRlbQogKiAgbHBzRGVzdCAgW09dIEJ1ZmZlciBmb3IgcmVjZWl2aW5nIHdpbmRvdyB0ZXh0CiAqICBuRGVzdExlbiBbSV0gTGVuZ3RoIG9mIGJ1ZmZlci4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIGxlbmd0aCBvZiB0aGUgcmV0dXJuZWQgdGV4dC4KICogIEZhaWx1cmU6IDAuCiAqLwpJTlQgV0lOQVBJIEdldERsZ0l0ZW1UZXh0V3JhcFcoSFdORCBoV25kLCBJTlQgbkl0ZW0sIExQV1NUUiBscHNEZXN0LElOVCBuRGVzdExlbikKewogIEhXTkQgaEl0ZW0gPSBHZXREbGdJdGVtKGhXbmQsIG5JdGVtKTsKCiAgaWYgKGhJdGVtKQogICAgcmV0dXJuIEdldFdpbmRvd1RleHRXKGhJdGVtLCBscHNEZXN0LCBuRGVzdExlbik7CiAgaWYgKG5EZXN0TGVuKQogICAgKmxwc0Rlc3QgPSAoV0NIQVIpJ1wwJzsKICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgW1NITFdBUEkuMTM4XQogKgogKiBTZXQgdGhlIHRleHQgb2YgYSBnaXZlbiBkaWFsb2cgaXRlbS4KICoKICogUEFSQU1TCiAqICBoV25kICAgICBbSV0gSGFuZGxlIG9mIGRpYWxvZwogKiAgaUl0ZW0gICAgW0ldIEluZGV4IG9mIGl0ZW0KICogIGxwc3pUZXh0IFtPXSBUZXh0IHRvIHNldAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiAgVGhlIHRleHQgb2YgdGhlIGRpYWxvZyBpcyBzZXQgdG8gbHBzelRleHQuCiAqICBGYWlsdXJlOiBGQUxTRSwgT3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU2V0RGxnSXRlbVRleHRXcmFwVyhIV05EIGhXbmQsIElOVCBpSXRlbSwgTFBDV1NUUiBscHN6VGV4dCkKewogICAgSFdORCBoV25kSXRlbSA9IEdldERsZ0l0ZW0oaFduZCwgaUl0ZW0pOwogICAgaWYgKGhXbmRJdGVtKQogICAgICAgIHJldHVybiBTZXRXaW5kb3dUZXh0VyhoV25kSXRlbSwgbHBzelRleHQpOwogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTUxXQogKgogKiBDb21wYXJlIHR3byBBc2NpaSBzdHJpbmdzIHVwIHRvIGEgZ2l2ZW4gbGVuZ3RoLgogKgogKiBQQVJBTVMKICogIGxwc3pTcmMgW0ldIFNvdXJjZSBzdHJpbmcKICogIGxwc3pDbXAgW0ldIFN0cmluZyB0byBjb21wYXJlIHRvIGxwc3pTcmMKICogIGxlbiAgICAgW0ldIE1heGltdW0gbGVuZ3RoCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBOQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wLCBJTlQgbGVuKQp7CiAgICByZXR1cm4gc3RybmNtcChscHN6U3JjLCBscHN6Q21wLCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTUyXQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU3RyQ21wTkNBLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5DVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCwgSU5UIGxlbikKewogICAgcmV0dXJuIHN0cm5jbXBXKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTNdCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MgdXAgdG8gYSBnaXZlbiBsZW5ndGgsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKiAgbGVuICAgICBbSV0gTWF4aW11bSBsZW5ndGgKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5JQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wLCBEV09SRCBsZW4pCnsKICAgIHJldHVybiBzdHJuY2FzZWNtcChscHN6U3JjLCBscHN6Q21wLCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTU0XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU3RyQ21wTklDQS4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBOSUNXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wLCBEV09SRCBsZW4pCnsKICAgIHJldHVybiBzdHJuY21waVcobHBzelNyYywgbHBzekNtcCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1NV0KICoKICogQ29tcGFyZSB0d28gQXNjaWkgc3RyaW5ncy4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTb3VyY2Ugc3RyaW5nCiAqICBscHN6Q21wIFtJXSBTdHJpbmcgdG8gY29tcGFyZSB0byBscHN6U3JjCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBDQShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXApCnsKICAgIHJldHVybiBzdHJjbXAobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTZdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBDQS4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBDVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNtcFcobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTddCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MsIGlnbm9yaW5nIGNhc2UuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKgogKiBSRVRVUk5TCiAqICBBIG51bWJlciBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICBscHN6U3JjIGlzIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxwc3pDbXAuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wSUNBKExQQ1NUUiBscHN6U3JjLCBMUENTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNhc2VjbXAobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNThdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBJQ0EuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wSUNXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gc3RyY21waVcobHBzelNyYywgbHBzekNtcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjBdCiAqCiAqIEdldCBhbiBpZGVudGlmaWNhdGlvbiBzdHJpbmcgZm9yIHRoZSBPUyBhbmQgZXhwbG9yZXIuCiAqCiAqIFBBUkFNUwogKiAgbHBzekRlc3QgIFtPXSBEZXN0aW5hdGlvbiBmb3IgSWQgc3RyaW5nCiAqICBkd0Rlc3RMZW4gW0ldIExlbmd0aCBvZiBscHN6RGVzdAogKgogKiBSRVRVUk5TCiAqICBUUlVFLCAgSWYgdGhlIHN0cmluZyB3YXMgY3JlYXRlZCBzdWNjZXNzZnVsbHkKICogIEZBTFNFLCBPdGhlcndpc2UKICovCkJPT0wgV0lOQVBJIFNIQWJvdXRJbmZvQShMUFNUUiBscHN6RGVzdCwgRFdPUkQgZHdEZXN0TGVuKQp7CiAgV0NIQVIgYnVmZlsyMDg0XTsKCiAgVFJBQ0UoIiglcCwlbGQpXG4iLCBscHN6RGVzdCwgZHdEZXN0TGVuKTsKCiAgaWYgKGxwc3pEZXN0ICYmIFNIQWJvdXRJbmZvVyhidWZmLCBkd0Rlc3RMZW4pKQogIHsKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBidWZmLCAtMSwgbHBzekRlc3QsIGR3RGVzdExlbiwgTlVMTCwgTlVMTCk7CiAgICByZXR1cm4gVFJVRTsKICB9CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTYxXQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hBYm91dEluZm9BLgogKi8KQk9PTCBXSU5BUEkgU0hBYm91dEluZm9XKExQV1NUUiBscHN6RGVzdCwgRFdPUkQgZHdEZXN0TGVuKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6SUVLZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnSScsJ24nLCd0JywnZScsJ3InLCduJywnZScsJ3QnLAogICAgJyAnLCdFJywneCcsJ3AnLCdsJywnbycsJ3InLCdlJywncicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzeldpbk50S2V5W10gPSB7ICdTJywnTycsJ0YnLCdUJywnVycsJ0EnLCdSJywnRScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCcgJywKICAgICdOJywnVCcsJ1xcJywnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pXaW5LZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1xcJywKICAgICdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelJlZ0tleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsCiAgICAnICcsJ0UnLCd4JywncCcsJ2wnLCdvJywncicsJ2UnLCdyJywnXFwnLAogICAgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ3InLCdhJywndCcsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelZlcnNpb25bXSA9IHsgJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pDdXN0b21pemVkW10gPSB7ICdDJywndScsJ3MnLCd0JywnbycsJ20nLCdpJywneicsJ2UnLCdkJywKICAgICdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6T3duZXJbXSA9IHsgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ2UnLCdyJywnZScsJ2QnLAogICAgJ08nLCd3JywnbicsJ2UnLCdyJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6T3JnW10gPSB7ICdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdlJywncicsJ2UnLCdkJywKICAgICdPJywncicsJ2cnLCdhJywnbicsJ2knLCd6JywnYScsJ3QnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pQcm9kdWN0W10gPSB7ICdQJywncicsJ28nLCdkJywndScsJ2MnLCd0JywnSScsJ2QnLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pVcGRhdGVbXSA9IHsgJ0knLCdFJywnQScsJ0snLAogICAgJ1UnLCdwJywnZCcsJ2EnLCd0JywnZScsJ1UnLCdyJywnbCcsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekhlbHBbXSA9IHsgJ0knLCdFJywnQScsJ0snLAogICAgJ0gnLCdlJywnbCcsJ3AnLCdTJywndCcsJ3InLCdpJywnbicsJ2cnLCdcMCcgfTsKICBXQ0hBUiBidWZmWzIwODRdOwogIEhLRVkgaFJlZzsKICBEV09SRCBkd1R5cGUsIGR3TGVuOwoKICBUUkFDRSgiKCVwLCVsZClcbiIsIGxwc3pEZXN0LCBkd0Rlc3RMZW4pOwoKICBpZiAoIWxwc3pEZXN0KQogICAgcmV0dXJuIEZBTFNFOwoKICAqbHBzekRlc3QgPSAnXDAnOwoKICAvKiBUcnkgdGhlIE5UIGtleSBmaXJzdCwgZm9sbG93ZWQgYnkgOTUvOTgga2V5ICovCiAgaWYgKFJlZ09wZW5LZXlFeFcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeldpbk50S2V5LCAwLCBLRVlfUkVBRCwgJmhSZWcpICYmCiAgICAgIFJlZ09wZW5LZXlFeFcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeldpbktleSwgMCwgS0VZX1JFQUQsICZoUmVnKSkKICAgIHJldHVybiBGQUxTRTsKCiAgLyogT1MgVmVyc2lvbiAqLwogIGJ1ZmZbMF0gPSAnXDAnOwogIGR3TGVuID0gMzA7CiAgaWYgKCFTSEdldFZhbHVlVyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6SUVLZXksIHN6VmVyc2lvbiwgJmR3VHlwZSwgYnVmZiwgJmR3TGVuKSkKICB7CiAgICBEV09SRCBkd1N0ckxlbiA9IHN0cmxlblcoYnVmZik7CiAgICBkd0xlbiA9IDMwIC0gZHdTdHJMZW47CiAgICBTSEdldFZhbHVlVyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6SUVLZXksCiAgICAgICAgICAgICAgICBzekN1c3RvbWl6ZWQsICZkd1R5cGUsIGJ1ZmYrZHdTdHJMZW4sICZkd0xlbik7CiAgfQogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+UmVnaXN0ZXJlZCBPd25lciAqLwogIGJ1ZmZbMF0gPSAnfic7CiAgZHdMZW4gPSAyNTY7CiAgaWYgKFNIR2V0VmFsdWVXKGhSZWcsIHN6T3duZXIsIDAsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+UmVnaXN0ZXJlZCBPcmdhbml6YXRpb24gKi8KICBkd0xlbiA9IDI1NjsKICBpZiAoU0hHZXRWYWx1ZVcoaFJlZywgc3pPcmcsIDAsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiBGSVhNRTogTm90IHN1cmUgd2hlcmUgdGhpcyBudW1iZXIgY29tZXMgZnJvbSAgKi8KICBidWZmWzBdID0gJ34nOwogIGJ1ZmZbMV0gPSAnMCc7CiAgYnVmZlsyXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5Qcm9kdWN0IElkICovCiAgZHdMZW4gPSAyNTY7CiAgaWYgKFNIR2V0VmFsdWVXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pSZWdLZXksIHN6UHJvZHVjdCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5JRSBVcGRhdGUgVXJsICovCiAgZHdMZW4gPSAyMDQ4OwogIGlmKFNIR2V0VmFsdWVXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pXaW5LZXksIHN6VXBkYXRlLCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogfklFIEhlbHAgU3RyaW5nICovCiAgZHdMZW4gPSAyNTY7CiAgaWYoU0hHZXRWYWx1ZVcoaFJlZywgc3pIZWxwLCAwLCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgUmVnQ2xvc2VLZXkoaFJlZyk7CiAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjNdCiAqCiAqIENhbGwgSU9sZUNvbW1hbmRUYXJnZXRfUXVlcnlTdGF0dXMoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duICAgICBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElPbGVDb21tYW5kVGFyZ2V0IGludGVyZmFjZQogKiAgcGd1aWRDbWRHcm91cCBbSV0gR1VJRCBmb3IgdGhlIGNvbW1hbmQgZ3JvdXAKICogIGNDbWRzICAgICAgICAgW0ldCiAqICBwcmdDbWRzICAgICAgIFtPXSBDb21tYW5kcwogKiAgcENtZFRleHQgICAgICBbT10gQ29tbWFuZCB0ZXh0CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX0ZBSUwsIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKiAgICAgICAgICAgRV9OT0lOVEVSRkFDRSwgaWYgbHBVbmtub3duIGRvZXMgbm90IHN1cHBvcnQgSU9sZUNvbW1hbmRUYXJnZXQuCiAqICAgICAgICAgICBPdGhlcndpc2UsIGFuIGVycm9yIGNvZGUgZnJvbSBJT2xlQ29tbWFuZFRhcmdldF9RdWVyeVN0YXR1cygpLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fUXVlcnlTdGF0dXMoSVVua25vd24qIGxwVW5rbm93biwgUkVGR1VJRCBwZ3VpZENtZEdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyBjQ21kcywgT0xFQ01EICpwcmdDbWRzLCBPTEVDTURURVhUKiBwQ21kVGV4dCkKewogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcCwlbGQsJXAsJXApXG4iLGxwVW5rbm93biwgcGd1aWRDbWRHcm91cCwgY0NtZHMsIHByZ0NtZHMsIHBDbWRUZXh0KTsKCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBJT2xlQ29tbWFuZFRhcmdldCogbHBPbGU7CgogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlQ29tbWFuZFRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscE9sZSk7CgogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscE9sZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb21tYW5kVGFyZ2V0X1F1ZXJ5U3RhdHVzKGxwT2xlLCBwZ3VpZENtZEdyb3VwLCBjQ21kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZ0NtZHMsIHBDbWRUZXh0KTsKICAgICAgSU9sZUNvbW1hbmRUYXJnZXRfUmVsZWFzZShscE9sZSk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJCVtTSExXQVBJLjE2NF0KICoKICogQ2FsbCBJT2xlQ29tbWFuZFRhcmdldF9FeGVjKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biAgICAgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJT2xlQ29tbWFuZFRhcmdldCBpbnRlcmZhY2UKICogIHBndWlkQ21kR3JvdXAgW0ldIEdVSUQgZm9yIHRoZSBjb21tYW5kIGdyb3VwCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX0ZBSUwsIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKiAgICAgICAgICAgRV9OT0lOVEVSRkFDRSwgaWYgbHBVbmtub3duIGRvZXMgbm90IHN1cHBvcnQgSU9sZUNvbW1hbmRUYXJnZXQuCiAqICAgICAgICAgICBPdGhlcndpc2UsIGFuIGVycm9yIGNvZGUgZnJvbSBJT2xlQ29tbWFuZFRhcmdldF9FeGVjKCkuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9FeGVjKElVbmtub3duKiBscFVua25vd24sIFJFRkdVSUQgcGd1aWRDbWRHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbkNtZElELCBEV09SRCBuQ21kZXhlY29wdCwgVkFSSUFOVCogcHZhSW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBUklBTlQqIHB2YU91dCkKewogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcCwlbGQsJWxkLCVwLCVwKVxuIixscFVua25vd24sIHBndWlkQ21kR3JvdXAsIG5DbWRJRCwKICAgICAgICBuQ21kZXhlY29wdCwgcHZhSW4sIHB2YU91dCk7CgogIGlmIChscFVua25vd24pCiAgewogICAgSU9sZUNvbW1hbmRUYXJnZXQqIGxwT2xlOwoKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9sZUNvbW1hbmRUYXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBPbGUpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscE9sZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb21tYW5kVGFyZ2V0X0V4ZWMobHBPbGUsIHBndWlkQ21kR3JvdXAsIG5DbWRJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkNtZGV4ZWNvcHQsIHB2YUluLCBwdmFPdXQpOwogICAgICBJT2xlQ29tbWFuZFRhcmdldF9SZWxlYXNlKGxwT2xlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjVdCiAqCiAqIFJldHJpZXZlLCBtb2RpZnksIGFuZCByZS1zZXQgYSB2YWx1ZSBmcm9tIGEgd2luZG93LgogKgogKiBQQVJBTVMKICogIGhXbmQgICBbSV0gV2luZG93IHRvIGdldCB2YWx1ZSBmcm9tCiAqICBvZmZzZXQgW0ldIE9mZnNldCBvZiB2YWx1ZQogKiAgd01hc2sgIFtJXSBNYXNrIGZvciB1aUZsYWdzCiAqICB3RmxhZ3MgW0ldIEJpdHMgdG8gc2V0IGluIHdpbmRvdyB2YWx1ZQogKgogKiBSRVRVUk5TCiAqICBUaGUgbmV3IHZhbHVlIGFzIGl0IHdhcyBzZXQsIG9yIDAgaWYgYW55IHBhcmFtZXRlciBpcyBpbnZhbGlkLgogKgogKiBOT1RFUwogKiAgQW55IGJpdHMgc2V0IGluIHVpTWFzayBhcmUgY2xlYXJlZCBmcm9tIHRoZSB2YWx1ZSwgdGhlbiBhbnkgYml0cyBzZXQgaW4KICogIHVpRmxhZ3MgYXJlIHNldCBpbiB0aGUgdmFsdWUuCiAqLwpMT05HIFdJTkFQSSBTSFNldFdpbmRvd0JpdHMoSFdORCBod25kLCBJTlQgb2Zmc2V0LCBVSU5UIHdNYXNrLCBVSU5UIHdGbGFncykKewogIExPTkcgcmV0ID0gR2V0V2luZG93TG9uZ0EoaHduZCwgb2Zmc2V0KTsKICBMT05HIG5ld0ZsYWdzID0gKHdGbGFncyAmIHdNYXNrKSB8IChyZXQgJiB+d0ZsYWdzKTsKCiAgaWYgKG5ld0ZsYWdzICE9IHJldCkKICAgIHJldCA9IFNldFdpbmRvd0xvbmdBKGh3bmQsIG9mZnNldCwgbmV3RmxhZ3MpOwogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjddCiAqCiAqIENoYW5nZSBhIHdpbmRvdydzIHBhcmVudC4KICoKICogUEFSQU1TCiAqICBoV25kICAgICAgIFtJXSBXaW5kb3cgdG8gY2hhbmdlIHBhcmVudCBvZgogKiAgaFduZFBhcmVudCBbSV0gTmV3IHBhcmVudCB3aW5kb3cKICoKICogUkVUVVJOUwogKiAgVGhlIG9sZCBwYXJlbnQgb2YgaFduZC4KICoKICogTk9URVMKICogIElmIGhXbmRQYXJlbnQgaXMgTlVMTCAoZGVza3RvcCksIHRoZSB3aW5kb3cgc3R5bGUgaXMgY2hhbmdlZCB0byBXU19QT1BVUC4KICogIElmIGhXbmRQYXJlbnQgaXMgTk9UIE5VTEwgdGhlbiB3ZSBzZXQgdGhlIFdTX0NISUxEIHN0eWxlLgogKi8KSFdORCBXSU5BUEkgU0hTZXRQYXJlbnRId25kKEhXTkQgaFduZCwgSFdORCBoV25kUGFyZW50KQp7CiAgVFJBQ0UoIiVwLCAlcFxuIiwgaFduZCwgaFduZFBhcmVudCk7CgogIGlmKEdldFBhcmVudChoV25kKSA9PSBoV25kUGFyZW50KQogICAgcmV0dXJuIDA7CgogIGlmKGhXbmRQYXJlbnQpCiAgICBTSFNldFdpbmRvd0JpdHMoaFduZCwgR1dMX1NUWUxFLCBXU19DSElMRCwgV1NfQ0hJTEQpOwogIGVsc2UKICAgIFNIU2V0V2luZG93Qml0cyhoV25kLCBHV0xfU1RZTEUsIFdTX1BPUFVQLCBXU19QT1BVUCk7CgogIHJldHVybiBTZXRQYXJlbnQoaFduZCwgaFduZFBhcmVudCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICBbU0hMV0FQSS4xNjhdCiAqCiAqIExvY2F0ZSBhbmQgYWR2aXNlIGEgY29ubmVjdGlvbiBwb2ludCBpbiBhbiBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua1NpbmsgICBbSV0gU2luayBmb3IgdGhlIGNvbm5lY3Rpb24gcG9pbnQgYWR2aXNlIGNhbGwKICogIHJpaWQgICAgICAgIFtJXSBSRUZJSUQgb2YgY29ubmVjdGlvbiBwb2ludCB0byBhZHZpc2UKICogIGJBZHZpc2VPbmx5IFtJXSBUUlVFID0gQWR2aXNlIG9ubHksIEZBTFNFID0gVW5hZHZpc2UgZmlyc3QKICogIGxwVW5rbm93biAgIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciBpbnRlcmZhY2UKICogIGxwQ29va2llICAgIFtPXSBQb2ludGVyIHRvIGNvbm5lY3Rpb24gcG9pbnQgY29va2llCiAqICBscHBDUCAgICAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBJQ29ubmVjdGlvblBvaW50IGZvdW5kCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIElmIGxwcENQIGlzIG5vbi1OVUxMLCBpdCBpcyBmaWxsZWQgd2l0aCB0aGUgSUNvbm5lY3Rpb25Qb2ludAogKiAgICAgICAgICAgdGhhdCB3YXMgYWR2aXNlZC4gVGhlIGNhbGxlciBpcyByZXNwb25zYWJsZSBmb3IgcmVsZWFzaW5nIGl0LgogKiAgRmFpbHVyZTogRV9GQUlMLCBpZiBhbnkgYXJndW1lbnRzIGFyZSBpbnZhbGlkLgogKiAgICAgICAgICAgRV9OT0lOVEVSRkFDRSwgaWYgbHBVbmtub3duIGlzbid0IGFuIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIsCiAqICAgICAgICAgICBPciBhbiBIUkVTVUxUIGVycm9yIGNvZGUgaWYgYW55IGNhbGwgZmFpbHMuCiAqLwpIUkVTVUxUIFdJTkFQSSBDb25uZWN0VG9Db25uZWN0aW9uUG9pbnQoSVVua25vd24qIGxwVW5rU2luaywgUkVGSUlEIHJpaWQsIEJPT0wgYkFkdmlzZU9ubHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duKiBscFVua25vd24sIExQRFdPUkQgbHBDb29raWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIElDb25uZWN0aW9uUG9pbnQgKipscHBDUCkKewogIEhSRVNVTFQgaFJldDsKICBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyKiBscENvbnRhaW5lcjsKICBJQ29ubmVjdGlvblBvaW50ICpscENQOwoKICBpZighbHBVbmtub3duIHx8IChiQWR2aXNlT25seSAmJiAhbHBVbmtTaW5rKSkKICAgIHJldHVybiBFX0ZBSUw7CgogIGlmKGxwcENQKQogICAgKmxwcENQID0gTlVMTDsKCiAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JQ29ubmVjdGlvblBvaW50Q29udGFpbmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscENvbnRhaW5lcik7CiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lcl9GaW5kQ29ubmVjdGlvblBvaW50KGxwQ29udGFpbmVyLCByaWlkLCAmbHBDUCk7CgogICAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICAgIHsKICAgICAgaWYoIWJBZHZpc2VPbmx5KQogICAgICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50X1VuYWR2aXNlKGxwQ1AsICpscENvb2tpZSk7CiAgICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50X0FkdmlzZShscENQLCBscFVua1NpbmssIGxwQ29va2llKTsKCiAgICAgIGlmIChGQUlMRUQoaFJldCkpCiAgICAgICAgKmxwQ29va2llID0gMDsKCiAgICAgIGlmIChscHBDUCAmJiBTVUNDRUVERUQoaFJldCkpCiAgICAgICAgKmxwcENQID0gbHBDUDsgLyogQ2FsbGVyIGtlZXBzIHRoZSBpbnRlcmZhY2UgKi8KICAgICAgZWxzZQogICAgICAgIElDb25uZWN0aW9uUG9pbnRfUmVsZWFzZShscENQKTsgLyogUmVsZWFzZSBpdCAqLwogICAgfQoKICAgIElVbmtub3duX1JlbGVhc2UobHBDb250YWluZXIpOwogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJQAlbU0hMV0FQSS4xNjldCiAqCiAqIFJlbGVhc2UgYW4gaW50ZXJmYWNlLgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIHJlbGVhc2UKICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICovCkRXT1JEIFdJTkFQSSBJVW5rbm93bl9BdG9taWNSZWxlYXNlKElVbmtub3duICoqIGxwVW5rbm93bikKewogICAgSVVua25vd24gKnRlbXA7CgogICAgVFJBQ0UoIiglcClcbiIsbHBVbmtub3duKTsKCiAgICBpZighbHBVbmtub3duIHx8ICEqKChMUERXT1JEKWxwVW5rbm93bikpIHJldHVybiAwOwogICAgdGVtcCA9ICpscFVua25vd247CiAgICAqbHBVbmtub3duID0gTlVMTDsKCiAgICBUUkFDRSgiZG9pbmcgUmVsZWFzZVxuIik7CiAgICAKICAgIHJldHVybiBJVW5rbm93bl9SZWxlYXNlKHRlbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTcwXQogKgogKiBTa2lwICcvLycgaWYgcHJlc2VudCBpbiBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTdHJpbmcgdG8gY2hlY2sgZm9yICcvLycKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIG5leHQgY2hhcmFjdGVyIGFmdGVyIHRoZSAnLy8nIG9yIHRoZSBzdHJpbmcgaWYgbm90IHByZXNlbnQKICogIEZhaWx1cmU6IE5VTEwsIGlmIGxwc3pTdHIgaXMgTlVMTC4KICovCkxQQ1NUUiBXSU5BUEkgUGF0aFNraXBMZWFkaW5nU2xhc2hlc0EoTFBDU1RSIGxwc3pTcmMpCnsKICBpZiAobHBzelNyYyAmJiBscHN6U3JjWzBdID09ICcvJyAmJiBscHN6U3JjWzFdID09ICcvJykKICAgIGxwc3pTcmMgKz0gMjsKICByZXR1cm4gbHBzelNyYzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACQlbU0hMV0FQSS4xNzFdCiAqCiAqIENoZWNrIGlmIHR3byBpbnRlcmZhY2VzIGNvbWUgZnJvbSB0aGUgc2FtZSBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgIGxwSW50MSBbSV0gSW50ZXJmYWNlIHRvIGNoZWNrIGFnYWluc3QgbHBJbnQyLgogKiAgIGxwSW50MiBbSV0gSW50ZXJmYWNlIHRvIGNoZWNrIGFnYWluc3QgbHBJbnQxLgogKgogKiBSRVRVUk5TCiAqICAgVFJVRSwgSWYgdGhlIGludGVyZmFjZXMgY29tZSBmcm9tIHRoZSBzYW1lIG9iamVjdC4KICogICBGQUxTRSBPdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTSElzU2FtZU9iamVjdChJVW5rbm93biogbHBJbnQxLCBJVW5rbm93biogbHBJbnQyKQp7CiAgTFBWT0lEIGxwVW5rbm93bjEsIGxwVW5rbm93bjI7CgogIFRSQUNFKCIlcCAlcFxuIiwgbHBJbnQxLCBscEludDIpOwoKICBpZiAoIWxwSW50MSB8fCAhbHBJbnQyKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAobHBJbnQxID09IGxwSW50MikKICAgIHJldHVybiBUUlVFOwoKICBpZiAoIVNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShscEludDEsICZJSURfSVVua25vd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQgKikmbHBVbmtub3duMSkpKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAoIVNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShscEludDIsICZJSURfSVVua25vd24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQgKikmbHBVbmtub3duMikpKQogICAgcmV0dXJuIEZBTFNFOwoKICBpZiAobHBVbmtub3duMSA9PSBscFVua25vd24yKQogICAgcmV0dXJuIFRSVUU7CiAgCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTcyXQogKgogKiBHZXQgdGhlIHdpbmRvdyBoYW5kbGUgb2YgYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIGdldCB0aGUgd2luZG93IGhhbmRsZSBvZgogKiAgbHBoV25kICAgIFtPXSBEZXN0aW5hdGlvbiBmb3Igd2luZG93IGhhbmRsZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBscGhXbmQgY29udGFpbnMgdGhlIG9iamVjdHMgd2luZG93IGhhbmRsZS4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogIGxwVW5rbm93biBpcyBleHBlY3RlZCB0byBzdXBwb3J0IG9uZSBvZiB0aGUgZm9sbG93aW5nIGludGVyZmFjZXM6CiAqICBJT2xlV2luZG93KCksIElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSgpLCBvciBJU2hlbGxWaWV3KCkuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9HZXRXaW5kb3coSVVua25vd24gKmxwVW5rbm93biwgSFdORCAqbHBoV25kKQp7CiAgLyogRklYTUU6IFdpbmUgaGFzIG5vIGhlYWRlciBmb3IgdGhpcyBvYmplY3QgKi8KICBzdGF0aWMgY29uc3QgR1VJRCBJSURfSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlID0geyAweDc5ZWFjOWVkLAogICAgMHhiYWY5LCAweDExY2UsIHsgMHg4YywgMHg4MiwgMHgwMCwgMHhhYSwgMHgwMCwgMHg0YiwgMHhhOSwgMHgwYiB9fTsKICBJVW5rbm93biAqbHBPbGU7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBscGhXbmQpOwoKICBpZiAoIWxwVW5rbm93bikKICAgIHJldHVybiBoUmV0OwoKICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVXaW5kb3csICh2b2lkKiopJmxwT2xlKTsKCiAgaWYgKEZBSUxFRChoUmV0KSkKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCZJSURfSVNoZWxsVmlldywgKHZvaWQqKikmbHBPbGUpOwoKICAgIGlmIChGQUlMRUQoaFJldCkpCiAgICB7CiAgICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwT2xlKTsKICAgIH0KICB9CgogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgLyogTGF6eW5lc3MgaGVyZSAtIFNpbmNlIEdldFdpbmRvdygpIGlzIHRoZSBmaXJzdCBtZXRob2QgZm9yIHRoZSBhYm92ZSAzCiAgICAgKiBpbnRlcmZhY2VzLCB3ZSB1c2UgdGhlIHNhbWUgY2FsbCBmb3IgdGhlbSBhbGwuCiAgICAgKi8KICAgIGhSZXQgPSBJT2xlV2luZG93X0dldFdpbmRvdygoSU9sZVdpbmRvdyopbHBPbGUsIGxwaFduZCk7CiAgICBJVW5rbm93bl9SZWxlYXNlKGxwT2xlKTsKICAgIGlmIChscGhXbmQpCiAgICAgIFRSQUNFKCJSZXR1cm5pbmcgSFdORD0lcFxuIiwgKmxwaFduZCk7CiAgfQoKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3M10KICoKICogQ2FsbCBhIG1ldGhvZCBvbiBhcyBhcyB5ZXQgdW5pZGVudGlmaWVkIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBwVW5rIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgdW5pZGVudGlmaWVkIGludGVyZmFjZSwKICogIGFyZyAgW0ldIEFyZ3VtZW50IGZvciB0aGUgY2FsbCBvbiB0aGUgb2JqZWN0LgogKgogKiBSRVRVUk5TCiAqICBTX09LLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fU2V0T3duZXIoSVVua25vd24gKnBVbmssIFVMT05HIGFyZykKewogIHN0YXRpYyBjb25zdCBHVUlEIGd1aWRfMTczID0gewogICAgMHg1ODM2ZmIwMCwgMHg4MTg3LCAweDExY2YsIHsgMHhhMSwweDJiLDB4MDAsMHhhYSwweDAwLDB4NGEsMHhlOCwweDM3IH0KICB9OwogIElNYWxsb2MgKnBVbmsyOwoKICBUUkFDRSgiKCVwLCVsZClcbiIsIHBVbmssIGFyZyk7CgogIC8qIE5vdGU6IGFyZyBtYXkgbm90IGJlIGEgVUxPTkcgYW5kIHBVbmsyIGlzIGZvciBzdXJlIG5vdCBhbiBJTWFsbG9jIC0KICAgKiAgICAgICBXZSB1c2UgdGhpcyBpbnRlcmZhY2UgYXMgaXRzIHZ0YWJsZSBlbnRyeSBpcyBjb21wYXRpYmxlIHdpdGggdGhlCiAgICogICAgICAgb2JqZWN0IGluIHF1ZXN0aW9uLgogICAqIEZJWE1FOiBGaW5kIG91dCB3aGF0IHRoaXMgb2JqZWN0IGlzIGFuZCB3aGVyZSBpdCBzaG91bGQgYmUgZGVmaW5lZC4KICAgKi8KICBpZiAocFVuayAmJgogICAgICBTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UocFVuaywgJmd1aWRfMTczLCAodm9pZCoqKSZwVW5rMikpKQogIHsKICAgIElNYWxsb2NfQWxsb2MocFVuazIsIGFyZyk7IC8qIEZha2VkIGNhbGwhISAqLwogICAgSU1hbGxvY19SZWxlYXNlKHBVbmsyKTsKICB9CiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzRdCiAqCiAqIENhbGwgZWl0aGVyIElPYmplY3RXaXRoU2l0ZV9TZXRTaXRlKCkgb3IgSVBlcnNpc3RNb25pa2VyX0dldENsYXNzSUQoKSBvbgogKiBhbiBpbnRlcmZhY2UuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX0ZBSUwsIGlmIHAxIGlzIE5VTEwuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFIElmIHAxIGRvZXMgbm90IHN1cHBvcnQgdGhlIElQZXJzaXN0IGludGVyZmFjZSwKICogICAgICAgICAgIE9yIGFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICovCkRXT1JEIFdJTkFQSSBJVW5rbm93bl9TZXRTaXRlKAogICAgICAgIElVbmtub3duICpwMSwgICAgIC8qIFtpbl0gICBPTEUgb2JqZWN0ICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgIExQVk9JRCAqcDIpICAgICAgIC8qIFtvdXRdICBwdHIgZm9yIGNhbGwgcmVzdWx0cyAqLwp7CiAgICBEV09SRCByZXQsIGFhOwoKICAgIGlmICghcDEpIHJldHVybiBFX0ZBSUw7CgogICAgLyogc2VlIGlmIFNldFNpdGUgaW50ZXJmYWNlIGV4aXN0cyBmb3IgSU9iamVjdFdpdGhTaXRlIG9iamVjdCAqLwogICAgcmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UoKElVbmtub3duICopcDEsIChSRUZJSUQpaWQxLCAoTFBWT0lEICopJnAxKTsKICAgIFRSQUNFKCJmaXJzdCBJVV9RSSByZXQ9JTA4bHgsIHAxPSVwXG4iLCByZXQsIHAxKTsKICAgIGlmIChyZXQpIHsKCgkvKiBzZWUgaWYgR2V0Q2xhc3NJZCBpbnRlcmZhY2UgZXhpc3RzIGZvciBJUGVyc2lzdE1vbmlrZXIgb2JqZWN0ICovCglyZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZSgoSVVua25vd24gKilwMSwgKFJFRklJRClpZDIsIChMUFZPSUQgKikmYWEpOwoJVFJBQ0UoInNlY29uZCBJVV9RSSByZXQ9JTA4bHgsIGFhPSUwOGx4XG4iLCByZXQsIGFhKTsKCWlmIChyZXQpIHJldHVybiByZXQ7CgoJLyogZmFrZSBhIEdldENsYXNzSWQgY2FsbCAqLwoJcmV0ID0gSU9sZVdpbmRvd19HZXRXaW5kb3coKElPbGVXaW5kb3cgKilhYSwgKEhXTkQqKXAyKTsKCVRSQUNFKCJzZWNvbmQgSVVfUUkgZG9pbmcgMHgwYyByZXQ9JTA4bHgsICpwMj0lMDhseFxuIiwgcmV0LAoJICAgICAgKihMUERXT1JEKXAyKTsKCUlVbmtub3duX1JlbGVhc2UoKElVbmtub3duICopYWEpOwogICAgfQogICAgZWxzZSB7CgkvKiBmYWtlIGEgU2V0U2l0ZSBjYWxsICovCglyZXQgPSBJT2xlV2luZG93X0dldFdpbmRvdygoSU9sZVdpbmRvdyAqKXAxLCAoSFdORCopcDIpOwoJVFJBQ0UoImZpcnN0IElVX1FJIGRvaW5nIDB4MGMgcmV0PSUwOGx4LCAqcDI9JTA4bHhcbiIsIHJldCwKCSAgICAgICooTFBEV09SRClwMik7CglJVW5rbm93bl9SZWxlYXNlKChJVW5rbm93biAqKXAxKTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzVdCiAqCiAqIENhbGwgSVBlcnNpc3RfR2V0Q2xhc3NJRCgpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJUGVyc2lzdCBpbnRlcmZhY2UKICogIGxwQ2xhc3NJZCBbT10gRGVzdGluYXRpb24gZm9yIENsYXNzIElkCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIGxwQ2xhc3NJZCBjb250YWlucyB0aGUgQ2xhc3MgSWQgcmVxdWVzdGVkLgogKiAgRmFpbHVyZTogRV9GQUlMLCBJZiBscFVua25vd24gaXMgTlVMTCwKICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UgSWYgbHBVbmtub3duIGRvZXMgbm90IHN1cHBvcnQgSVBlcnNpc3QsCiAqICAgICAgICAgICBPciBhbiBIUkVTVUxUIGVycm9yIGNvZGUuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9HZXRDbGFzc0lEKElVbmtub3duICpscFVua25vd24sIENMU0lEKiBscENsYXNzSWQpCnsKICBJUGVyc2lzdCogbHBQZXJzaXN0OwogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwVW5rbm93biwgZGVidWdzdHJfZ3VpZChscENsYXNzSWQpKTsKCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCZJSURfSVBlcnNpc3QsKHZvaWQqKikmbHBQZXJzaXN0KTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkpCiAgICB7CiAgICAgIElQZXJzaXN0X0dldENsYXNzSUQobHBQZXJzaXN0LCBscENsYXNzSWQpOwogICAgICBJUGVyc2lzdF9SZWxlYXNlKGxwUGVyc2lzdCk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTc2XQogKgogKiBSZXRyaWV2ZSBhIFNlcnZpY2UgSW50ZXJmYWNlIGZyb20gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIGdldCBhbiBJU2VydmljZVByb3ZpZGVyIGludGVyZmFjZSBmcm9tCiAqICBzaWQgICAgICAgW0ldIFNlcnZpY2UgSUQgZm9yIElTZXJ2aWNlUHJvdmlkZXJfUXVlcnlTZXJ2aWNlKCkgY2FsbAogKiAgcmlpZCAgICAgIFtJXSBGdW5jdGlvbiByZXF1ZXN0ZWQgZm9yIFF1ZXJ5U2VydmljZSBjYWxsCiAqICBscHBPdXQgICAgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgc2VydmljZSBpbnRlcmZhY2UgcG9pbnRlcgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBscHBPdXQgY29udGFpbnMgYW4gb2JqZWN0IHByb3ZpZGluZyB0aGUgcmVxdWVzdGVkIHNlcnZpY2UKICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZQogKgogKiBOT1RFUwogKiAgbHBVbmtub3duIGlzIGV4cGVjdGVkIHRvIHN1cHBvcnQgdGhlIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fUXVlcnlTZXJ2aWNlKElVbmtub3duKiBscFVua25vd24sIFJFRkdVSUQgc2lkLCBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEICpscHBPdXQpCnsKICBJU2VydmljZVByb3ZpZGVyKiBwU2VydmljZSA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0OwoKICBpZiAoIWxwcE91dCkKICAgIHJldHVybiBFX0ZBSUw7CgogICpscHBPdXQgPSBOVUxMOwoKICBpZiAoIWxwVW5rbm93bikKICAgIHJldHVybiBFX0ZBSUw7CgogIC8qIEdldCBhbiBJU2VydmljZVByb3ZpZGVyIGludGVyZmFjZSBmcm9tIHRoZSBvYmplY3QgKi8KICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lTZXJ2aWNlUHJvdmlkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFZPSUQqKSZwU2VydmljZSk7CgogIGlmICghaFJldCAmJiBwU2VydmljZSkKICB7CiAgICBUUkFDRSgiUXVlcnlJbnRlcmZhY2UgcmV0dXJuZWQgKElTZXJ2aWNlUHJvdmlkZXIqKSVwXG4iLCBwU2VydmljZSk7CgogICAgLyogR2V0IGEgU2VydmljZSBpbnRlcmZhY2UgZnJvbSB0aGUgb2JqZWN0ICovCiAgICBoUmV0ID0gSVNlcnZpY2VQcm92aWRlcl9RdWVyeVNlcnZpY2UocFNlcnZpY2UsIHNpZCwgcmlpZCwgbHBwT3V0KTsKCiAgICBUUkFDRSgiKElTZXJ2aWNlUHJvdmlkZXIqKSVwIHJldHVybmVkIChJVW5rbm93biopJXBcbiIsIHBTZXJ2aWNlLCAqbHBwT3V0KTsKCiAgICAvKiBSZWxlYXNlIHRoZSBJU2VydmljZVByb3ZpZGVyIGludGVyZmFjZSAqLwogICAgSVVua25vd25fUmVsZWFzZShwU2VydmljZSk7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTc3XQogKgogKiBMb2FkcyBhIHBvcHVwIG1lbnUuCiAqCiAqIFBBUkFNUwogKiAgaEluc3QgIFtJXSBJbnN0YW5jZSBoYW5kbGUKICogIHN6TmFtZSBbSV0gTWVudSBuYW1lCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuCiAqICBGYWlsdXJlOiBGQUxTRS4KICovCkJPT0wgV0lOQVBJIFNITG9hZE1lbnVQb3B1cChISU5TVEFOQ0UgaEluc3QsIExQQ1dTVFIgc3pOYW1lKQp7CiAgSE1FTlUgaE1lbnUsIGhTdWJNZW51OwoKICBpZiAoKGhNZW51ID0gTG9hZE1lbnVXKGhJbnN0LCBzek5hbWUpKSkKICB7CiAgICBpZiAoKGhTdWJNZW51ID0gR2V0U3ViTWVudShoTWVudSwgMCkpKQogICAgICBSZW1vdmVNZW51KGhNZW51LCAwLCBNRl9CWVBPU0lUSU9OKTsKCiAgICBEZXN0cm95TWVudShoTWVudSk7CiAgICByZXR1cm4gVFJVRTsKICB9CiAgcmV0dXJuIEZBTFNFOwp9Cgp0eXBlZGVmIHN0cnVjdCBfZW51bVduZERhdGEKewogIFVJTlQgICB1aU1zZ0lkOwogIFdQQVJBTSB3UGFyYW07CiAgTFBBUkFNIGxQYXJhbTsKICBMUkVTVUxUIChXSU5BUEkgKnBmblBvc3QpKEhXTkQsVUlOVCxXUEFSQU0sTFBBUkFNKTsKfSBlbnVtV25kRGF0YTsKCi8qIENhbGxiYWNrIGZvciBTSExXQVBJXzE3OCAqLwpzdGF0aWMgQk9PTCBDQUxMQkFDSyBTSExXQVBJX0VudW1DaGlsZFByb2MoSFdORCBoV25kLCBMUEFSQU0gbFBhcmFtKQp7CiAgZW51bVduZERhdGEgKmRhdGEgPSAoZW51bVduZERhdGEgKilsUGFyYW07CgogIFRSQUNFKCIoJXAsJXApXG4iLCBoV25kLCBkYXRhKTsKICBkYXRhLT5wZm5Qb3N0KGhXbmQsIGRhdGEtPnVpTXNnSWQsIGRhdGEtPndQYXJhbSwgZGF0YS0+bFBhcmFtKTsKICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgW1NITFdBUEkuMTc4XQogKgogKiBTZW5kIG9yIHBvc3QgYSBtZXNzYWdlIHRvIGV2ZXJ5IGNoaWxkIG9mIGEgd2luZG93LgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgW0ldIFdpbmRvdyB3aG9zZSBjaGlsZHJlbiB3aWxsIGdldCB0aGUgbWVzc2FnZXMKICogIHVpTXNnSWQgW0ldIE1lc3NhZ2UgSWQKICogIHdQYXJhbSAgW0ldIFdQQVJBTSBvZiBtZXNzYWdlCiAqICBsUGFyYW0gIFtJXSBMUEFSQU0gb2YgbWVzc2FnZQogKiAgYlNlbmQgICBbSV0gVFJVRSA9IFVzZSBTZW5kTWVzc2FnZUEoKSwgRkFMU0UgPSBVc2UgUG9zdE1lc3NhZ2VBKCkKICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICoKICogTk9URVMKICogIFRoZSBhcHByb3ByaWF0ZSBBU0NJSSBvciBVbmljb2RlIGZ1bmN0aW9uIGlzIGNhbGxlZCBmb3IgdGhlIHdpbmRvdy4KICovCnZvaWQgV0lOQVBJIFNIUHJvcGFnYXRlTWVzc2FnZShIV05EIGhXbmQsIFVJTlQgdWlNc2dJZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSwgQk9PTCBiU2VuZCkKewogIGVudW1XbmREYXRhIGRhdGE7CgogIFRSQUNFKCIoJXAsJXUsJWQsJWxkLCVkKVxuIiwgaFduZCwgdWlNc2dJZCwgd1BhcmFtLCBsUGFyYW0sIGJTZW5kKTsKCiAgaWYoaFduZCkKICB7CiAgICBkYXRhLnVpTXNnSWQgPSB1aU1zZ0lkOwogICAgZGF0YS53UGFyYW0gID0gd1BhcmFtOwogICAgZGF0YS5sUGFyYW0gID0gbFBhcmFtOwoKICAgIGlmIChiU2VuZCkKICAgICAgZGF0YS5wZm5Qb3N0ID0gSXNXaW5kb3dVbmljb2RlKGhXbmQpID8gKHZvaWQqKVNlbmRNZXNzYWdlVyA6ICh2b2lkKilTZW5kTWVzc2FnZUE7CiAgICBlbHNlCiAgICAgIGRhdGEucGZuUG9zdCA9IElzV2luZG93VW5pY29kZShoV25kKSA/ICh2b2lkKilQb3N0TWVzc2FnZVcgOiAodm9pZCopUG9zdE1lc3NhZ2VBOwoKICAgIEVudW1DaGlsZFdpbmRvd3MoaFduZCwgU0hMV0FQSV9FbnVtQ2hpbGRQcm9jLCAoTFBBUkFNKSZkYXRhKTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODBdCiAqCiAqIFJlbW92ZSBhbGwgc3ViLW1lbnVzIGZyb20gYSBtZW51LgogKgogKiBQQVJBTVMKICogIGhNZW51IFtJXSBNZW51IHRvIHJlbW92ZSBzdWItbWVudXMgZnJvbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiAwLiAgQWxsIHN1Yi1tZW51cyB1bmRlciBoTWVudSBhcmUgcmVtb3ZlZAogKiAgRmFpbHVyZTogLTEsIGlmIGFueSBwYXJhbWV0ZXIgaXMgaW52YWxpZAogKi8KRFdPUkQgV0lOQVBJIFNIUmVtb3ZlQWxsU3ViTWVudXMoSE1FTlUgaE1lbnUpCnsKICBpbnQgaUl0ZW1Db3VudCA9IEdldE1lbnVJdGVtQ291bnQoaE1lbnUpIC0gMTsKICB3aGlsZSAoaUl0ZW1Db3VudCA+PSAwKQogIHsKICAgIEhNRU5VIGhTdWJNZW51ID0gR2V0U3ViTWVudShoTWVudSwgaUl0ZW1Db3VudCk7CiAgICBpZiAoaFN1Yk1lbnUpCiAgICAgIFJlbW92ZU1lbnUoaE1lbnUsIGlJdGVtQ291bnQsIE1GX0JZUE9TSVRJT04pOwogICAgaUl0ZW1Db3VudC0tOwogIH0KICByZXR1cm4gaUl0ZW1Db3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4MV0KICoKICogRW5hYmxlIG9yIGRpc2FibGUgYSBtZW51IGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgICBbSV0gTWVudSBob2xkaW5nIG1lbnUgaXRlbQogKiAgdUlEICAgICBbSV0gSUQgb2YgbWVudSBpdGVtIHRvIGVuYWJsZS9kaXNhYmxlCiAqICBiRW5hYmxlIFtJXSBXaGV0aGVyIHRvIGVuYWJsZSAoVFJVRSkgb3IgZGlzYWJsZSAoRkFMU0UpIHRoZSBpdGVtLgogKgogKiBSRVRVUk5TCiAqICBUaGUgcmV0dXJuIGNvZGUgZnJvbSBFbmFibGVNZW51SXRlbS4KICovClVJTlQgV0lOQVBJIFNIRW5hYmxlTWVudUl0ZW0oSE1FTlUgaE1lbnUsIFVJTlQgd0l0ZW1JRCwgQk9PTCBiRW5hYmxlKQp7CiAgcmV0dXJuIEVuYWJsZU1lbnVJdGVtKGhNZW51LCB3SXRlbUlELCBiRW5hYmxlID8gTUZfRU5BQkxFRCA6IE1GX0dSQVlFRCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAJW1NITFdBUEkuMTgyXQogKgogKiBDaGVjayBvciB1bmNoZWNrIGEgbWVudSBpdGVtLgogKgogKiBQQVJBTVMKICogIGhNZW51ICBbSV0gTWVudSBob2xkaW5nIG1lbnUgaXRlbQogKiAgdUlEICAgIFtJXSBJRCBvZiBtZW51IGl0ZW0gdG8gY2hlY2svdW5jaGVjawogKiAgYkNoZWNrIFtJXSBXaGV0aGVyIHRvIGNoZWNrIChUUlVFKSBvciB1bmNoZWNrIChGQUxTRSkgdGhlIGl0ZW0uCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXR1cm4gY29kZSBmcm9tIENoZWNrTWVudUl0ZW0uCiAqLwpEV09SRCBXSU5BUEkgU0hDaGVja01lbnVJdGVtKEhNRU5VIGhNZW51LCBVSU5UIHVJRCwgQk9PTCBiQ2hlY2spCnsKICByZXR1cm4gQ2hlY2tNZW51SXRlbShoTWVudSwgdUlELCBiQ2hlY2sgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4M10KICoKICogUmVnaXN0ZXIgYSB3aW5kb3cgY2xhc3MgaWYgaXQgaXNuJ3QgYWxyZWFkeS4KICoKICogUEFSQU1TCiAqICBscFduZENsYXNzIFtJXSBXaW5kb3cgY2xhc3MgdG8gcmVnaXN0ZXIKICoKICogUkVUVVJOUwogKiAgVGhlIHJlc3VsdCBvZiB0aGUgUmVnaXN0ZXJDbGFzc0EgY2FsbC4KICovCkRXT1JEIFdJTkFQSSBTSFJlZ2lzdGVyQ2xhc3NBKFdORENMQVNTQSAqd25kY2xhc3MpCnsKICBXTkRDTEFTU0Egd2NhOwogIGlmIChHZXRDbGFzc0luZm9BKHduZGNsYXNzLT5oSW5zdGFuY2UsIHduZGNsYXNzLT5scHN6Q2xhc3NOYW1lLCAmd2NhKSkKICAgIHJldHVybiBUUlVFOwogIHJldHVybiAoRFdPUkQpUmVnaXN0ZXJDbGFzc0Eod25kY2xhc3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTg2XQogKi8KQk9PTCBXSU5BUEkgU0hTaW11bGF0ZURyb3AoSURyb3BUYXJnZXQgKnBEcm9wLCBJRGF0YU9iamVjdCAqcERhdGFPYmosCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGdyZktleVN0YXRlLCBQUE9JTlRMIGxwUHQsIERXT1JEKiBwZHdFZmZlY3QpCnsKICBEV09SRCBkd0VmZmVjdCA9IERST1BFRkZFQ1RfTElOSyB8IERST1BFRkZFQ1RfTU9WRSB8IERST1BFRkZFQ1RfQ09QWTsKICBQT0lOVEwgcHQgPSB7IDAsIDAgfTsKCiAgaWYgKCFscFB0KQogICAgbHBQdCA9ICZwdDsKCiAgaWYgKCFwZHdFZmZlY3QpCiAgICBwZHdFZmZlY3QgPSAmZHdFZmZlY3Q7CgogIElEcm9wVGFyZ2V0X0RyYWdFbnRlcihwRHJvcCwgcERhdGFPYmosIGdyZktleVN0YXRlLCAqbHBQdCwgcGR3RWZmZWN0KTsKCiAgaWYgKCpwZHdFZmZlY3QpCiAgICByZXR1cm4gSURyb3BUYXJnZXRfRHJvcChwRHJvcCwgcERhdGFPYmosIGdyZktleVN0YXRlLCAqbHBQdCwgcGR3RWZmZWN0KTsKCiAgSURyb3BUYXJnZXRfRHJhZ0xlYXZlKHBEcm9wKTsKICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4N10KICoKICogQ2FsbCBJUGVyc2lzdFByb3BlcnR5QmFnX0xvYWQoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSVBlcnNpc3RQcm9wZXJ0eUJhZyBpbnRlcmZhY2UKICogIGxwUHJvcEJhZyBbT10gRGVzdGluYXRpb24gZm9yIGxvYWRlZCBJUHJvcGVydHlCYWcKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSwgb3IgRV9GQUlMIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKi8KRFdPUkQgV0lOQVBJIFNITG9hZEZyb21Qcm9wZXJ0eUJhZyhJVW5rbm93biAqbHBVbmtub3duLCBJUHJvcGVydHlCYWcqIGxwUHJvcEJhZykKewogIElQZXJzaXN0UHJvcGVydHlCYWcqIGxwUFBCYWc7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBscFByb3BCYWcpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSVBlcnNpc3RQcm9wZXJ0eUJhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscFBQQmFnKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBQUEJhZykKICAgIHsKICAgICAgaFJldCA9IElQZXJzaXN0UHJvcGVydHlCYWdfTG9hZChscFBQQmFnLCBscFByb3BCYWcsIE5VTEwpOwogICAgICBJUGVyc2lzdFByb3BlcnR5QmFnX1JlbGVhc2UobHBQUEJhZyk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xODldCiAqCiAqIENhbGwgSU9sZUNvbnRyb2xTaXRlX0dldEV4dGVuZGVkQ29udHJvbCgpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJT2xlQ29udHJvbFNpdGUgaW50ZXJmYWNlCiAqICBscHBEaXNwICAgW09dIERlc3RpbmF0aW9uIGZvciByZXN1bHRpbmcgSURpc3BhdGNoLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0ZBSUwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpEV09SRCBXSU5BUEkgSVVua25vd25fT25Gb2N1c09DUyhJVW5rbm93biAqbHBVbmtub3duLCBJRGlzcGF0Y2gqKiBscHBEaXNwKQp7CiAgSU9sZUNvbnRyb2xTaXRlKiBscENTaXRlOwogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwVW5rbm93biwgbHBwRGlzcCk7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb250cm9sU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscENTaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBDU2l0ZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb250cm9sU2l0ZV9HZXRFeHRlbmRlZENvbnRyb2wobHBDU2l0ZSwgbHBwRGlzcCk7CiAgICAgIElPbGVDb250cm9sU2l0ZV9SZWxlYXNlKGxwQ1NpdGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgICBbU0hMV0FQSS4xOTJdCiAqCiAqIEdldCBhIHN1Yi1tZW51IGZyb20gYSBtZW51IGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgW0ldIE1lbnUgdG8gZ2V0IHN1Yi1tZW51IGZyb20KICogIHVJRCAgIFtJXSBJRCBvZiBtZW51IGl0ZW0gY29udGFpbmluZyBzdWItbWVudQogKgogKiBSRVRVUk5TCiAqICBUaGUgc3ViLW1lbnUgb2YgdGhlIGl0ZW0sIG9yIGEgTlVMTCBoYW5kbGUgaWYgYW55IHBhcmFtZXRlcnMgYXJlIGludmFsaWQuCiAqLwpITUVOVSBXSU5BUEkgU0hHZXRNZW51RnJvbUlEKEhNRU5VIGhNZW51LCBVSU5UIHVJRCkKewogIE1FTlVJVEVNSU5GT0EgbWk7CgogIFRSQUNFKCIoJXAsJXVsZClcbiIsIGhNZW51LCB1SUQpOwoKICBtaS5jYlNpemUgPSBzaXplb2YoTUVOVUlURU1JTkZPQSk7CiAgbWkuZk1hc2sgPSBNSUlNX1NVQk1FTlU7CgogIGlmICghR2V0TWVudUl0ZW1JbmZvQShoTWVudSwgdUlELCAwLCAmbWkpKQogICAgcmV0dXJuIE5VTEw7CgogIHJldHVybiBtaS5oU3ViTWVudTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE5M10KICoKICogR2V0IHRoZSBjb2xvciBkZXB0aCBvZiB0aGUgcHJpbWFyeSBkaXNwbGF5LgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIFRoZSBjb2xvciBkZXB0aCBvZiB0aGUgcHJpbWFyeSBkaXNwbGF5LgogKi8KRFdPUkQgV0lOQVBJIFNIR2V0Q3VyQ29sb3JSZXMoKQp7CiAgICBIREMgaGRjOwogICAgRFdPUkQgcmV0OwoKICAgIFRSQUNFKCIoKVxuIik7CgogICAgaGRjID0gR2V0REMoMCk7CiAgICByZXQgPSBHZXREZXZpY2VDYXBzKGhkYywgQklUU1BJWEVMKSAqIEdldERldmljZUNhcHMoaGRjLCBQTEFORVMpOwogICAgUmVsZWFzZURDKDAsIGhkYyk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTk0XQogKgogKiBXYWl0IGZvciBhIG1lc3NhZ2UgdG8gYXJyaXZlLCB3aXRoIGEgdGltZW91dC4KICoKICogUEFSQU1TCiAqICBoYW5kICAgICAgW0ldIEhhbmRsZSB0byBxdWVyeQogKiAgZHdUaW1lb3V0IFtJXSBUaW1lb3V0IGluIHRpY2tzIG9yIElORklOSVRFIHRvIG5ldmVyIHRpbWVvdXQKICoKICogUkVUVVJOUwogKiAgU1RBVFVTX1RJTUVPVVQgaWYgbm8gbWVzc2FnZSBpcyByZWNlaXZlZCBiZWZvcmUgZHdUaW1lb3V0IHRpY2tzIHBhc3Nlcy4KICogIE90aGVyd2lzZSByZXR1cm5zIHRoZSB2YWx1ZSBmcm9tIE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHNFeCB3aGVuIGEKICogIG1lc3NhZ2UgaXMgYXZhaWxhYmxlLgogKi8KRFdPUkQgV0lOQVBJIFNIV2FpdEZvclNlbmRNZXNzYWdlVGhyZWFkKEhBTkRMRSBoYW5kLCBEV09SRCBkd1RpbWVvdXQpCnsKICBEV09SRCBkd0VuZFRpY2tzID0gR2V0VGlja0NvdW50KCkgKyBkd1RpbWVvdXQ7CiAgRFdPUkQgZHdSZXQ7CgogIHdoaWxlICgoZHdSZXQgPSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzRXgoMSwgJmhhbmQsIGR3VGltZW91dCwgUVNfU0VORE1FU1NBR0UsIDApKSA9PSAxKQogIHsKICAgIE1TRyBtc2c7CgogICAgUGVla01lc3NhZ2VXKCZtc2csIE5VTEwsIDAsIDAsIFBNX05PUkVNT1ZFKTsKCiAgICBpZiAoZHdUaW1lb3V0ICE9IElORklOSVRFKQogICAgewogICAgICAgIGlmICgoaW50KShkd1RpbWVvdXQgPSBkd0VuZFRpY2tzIC0gR2V0VGlja0NvdW50KCkpIDw9IDApCiAgICAgICAgICAgIHJldHVybiBXQUlUX1RJTUVPVVQ7CiAgICB9CiAgfQoKICByZXR1cm4gZHdSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICBbU0hMV0FQSS4xOTddCiAqCiAqIEJsYW5rIG91dCBhIHJlZ2lvbiBvZiB0ZXh0IGJ5IGRyYXdpbmcgdGhlIGJhY2tncm91bmQgb25seS4KICoKICogUEFSQU1TCiAqICBoREMgICBbSV0gRGV2aWNlIGNvbnRleHQgdG8gZHJhdyBpbgogKiAgcFJlY3QgW0ldIEFyZWEgdG8gZHJhdyBpbgogKiAgY1JlZiAgW0ldIENvbG9yIHRvIGRyYXcgaW4KICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICovCkRXT1JEIFdJTkFQSSBTSEZpbGxSZWN0Q2xyKEhEQyBoREMsIExQQ1JFQ1QgcFJlY3QsIENPTE9SUkVGIGNSZWYpCnsKICAgIENPTE9SUkVGIGNPbGRDb2xvciA9IFNldEJrQ29sb3IoaERDLCBjUmVmKTsKICAgIEV4dFRleHRPdXRBKGhEQywgMCwgMCwgRVRPX09QQVFVRSwgcFJlY3QsIDAsIDAsIDApOwogICAgU2V0QmtDb2xvcihoREMsIGNPbGRDb2xvcik7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE5OF0KICoKICogUmV0dXJuIHRoZSB2YWx1ZSBhc29jaWF0ZWQgd2l0aCBhIGtleSBpbiBhIG1hcC4KICoKICogUEFSQU1TCiAqICBscEtleXMgICBbSV0gQSBsaXN0IG9mIGtleXMgb2YgbGVuZ3RoIGlMZW4KICogIGxwVmFsdWVzIFtJXSBBIGxpc3Qgb2YgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBscEtleXMsIG9mIGxlbmd0aCBpTGVuCiAqICBpTGVuICAgICBbSV0gTGVuZ3RoIG9mIGJvdGggbHBLZXlzIGFuZCBscFZhbHVlcwogKiAgaUtleSAgICAgW0ldIFRoZSBrZXkgdmFsdWUgdG8gbG9vayB1cCBpbiBscEtleXMKICoKICogUkVUVVJOUwogKiAgVGhlIHZhbHVlIGluIGxwVmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBpS2V5LCBvciAtMSBpZiBpS2V5IGlzIG5vdAogKiAgZm91bmQgaW4gbHBLZXlzLgogKgogKiBOT1RFUwogKiAgLSBJZiB0d28gZWxlbWVudHMgaW4gdGhlIG1hcCBzaGFyZSB0aGUgc2FtZSBrZXksIHRoaXMgZnVuY3Rpb24gcmV0dXJucwogKiAgICB0aGUgdmFsdWUgY2xvc2VzdCB0byB0aGUgc3RhcnQgb2YgdGhlIG1hcAogKiAgLSBUaGUgbmF0aXZlIHZlcnNpb24gb2YgdGhpcyBmdW5jdGlvbiBjcmFzaGVzIGlmIGxwS2V5cyBvciBscFZhbHVlcyBpcyBOVUxMLgogKi8KaW50IFdJTkFQSSBTSFNlYXJjaE1hcEludChjb25zdCBpbnQgKmxwS2V5cywgY29uc3QgaW50ICpscFZhbHVlcywgaW50IGlMZW4sIGludCBpS2V5KQp7CiAgaWYgKGxwS2V5cyAmJiBscFZhbHVlcykKICB7CiAgICBpbnQgaSA9IDA7CgogICAgd2hpbGUgKGkgPCBpTGVuKQogICAgewogICAgICBpZiAobHBLZXlzW2ldID09IGlLZXkpCiAgICAgICAgcmV0dXJuIGxwVmFsdWVzW2ldOyAvKiBGb3VuZCAqLwogICAgICBpKys7CiAgICB9CiAgfQogIHJldHVybiAtMTsgLyogTm90IGZvdW5kICovCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTk5XQogKgogKiBDb3B5IGFuIGludGVyZmFjZSBwb2ludGVyCiAqCiAqIFBBUkFNUwogKiAgIGxwcERlc3QgICBbT10gRGVzdGluYXRpb24gZm9yIGNvcHkKICogICBscFVua25vd24gW0ldIFNvdXJjZSBmb3IgY29weQogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KVk9JRCBXSU5BUEkgSVVua25vd25fU2V0KElVbmtub3duICoqbHBwRGVzdCwgSVVua25vd24gKmxwVW5rbm93bikKewogIFRSQUNFKCIoJXAsJXApXG4iLCBscHBEZXN0LCBscFVua25vd24pOwoKICBpZiAobHBwRGVzdCkKICAgIElVbmtub3duX0F0b21pY1JlbGVhc2UobHBwRGVzdCk7IC8qIFJlbGVhc2UgZXhpc3RpbmcgaW50ZXJmYWNlICovCgogIGlmIChscFVua25vd24pCiAgewogICAgLyogQ29weSAqLwogICAgSVVua25vd25fQWRkUmVmKGxwVW5rbm93bik7CiAgICAqbHBwRGVzdCA9IGxwVW5rbm93bjsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBNYXlFeGVjRm9yd2FyZChJVW5rbm93biogbHBVbmtub3duLCBJTlQgaVVuaywgUkVGR1VJRCBwZ3VpZENtZEdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBuQ21kSUQsIERXT1JEIG5DbWRleGVjb3B0LCBWQVJJQU5UKiBwdmFJbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFSSUFOVCogcHZhT3V0KQp7CiAgRklYTUUoIiglcCwlZCwlcCwlbGQsJWxkLCVwLCVwKSAtIHN0dWIhXG4iLCBscFVua25vd24sIGlVbmssIHBndWlkQ21kR3JvdXAsCiAgICAgICAgbkNtZElELCBuQ21kZXhlY29wdCwgcHZhSW4sIHB2YU91dCk7CiAgcmV0dXJuIERSQUdEUk9QX0VfTk9UUkVHSVNURVJFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwMl0KICoKICovCkhSRVNVTFQgV0lOQVBJIElzUVNGb3J3YXJkKFJFRkdVSUQgcGd1aWRDbWRHcm91cCxVTE9ORyBjQ21kcywgT0xFQ01EICpwcmdDbWRzKQp7CiAgRklYTUUoIiglcCwlbGQsJXApIC0gc3R1YiFcbiIsIHBndWlkQ21kR3JvdXAsIGNDbWRzLCBwcmdDbWRzKTsKICByZXR1cm4gRFJBR0RST1BfRV9OT1RSRUdJU1RFUkVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBACVtTSExXQVBJLjIwNF0KICoKICogRGV0ZXJtaW5lIGlmIGEgd2luZG93IGlzIG5vdCBhIGNoaWxkIG9mIGFub3RoZXIgd2luZG93LgogKgogKiBQQVJBTVMKICogaFBhcmVudCBbSV0gU3VzcGVjdGVkIHBhcmVudCB3aW5kb3cKICogaENoaWxkICBbSV0gU3VzcGVjdGVkIGNoaWxkIHdpbmRvdwogKgogKiBSRVRVUk5TCiAqIFRSVUU6ICBJZiBoQ2hpbGQgaXMgYSBjaGlsZCB3aW5kb3cgb2YgaFBhcmVudAogKiBGQUxTRTogSWYgaENoaWxkIGlzIG5vdCBhIGNoaWxkIHdpbmRvdyBvZiBoUGFyZW50LCBvciB0aGV5IGFyZSBlcXVhbAogKi8KQk9PTCBXSU5BUEkgU0hJc0NoaWxkT3JTZWxmKEhXTkQgaFBhcmVudCwgSFdORCBoQ2hpbGQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaFBhcmVudCwgaENoaWxkKTsKCiAgaWYgKCFoUGFyZW50IHx8ICFoQ2hpbGQpCiAgICByZXR1cm4gVFJVRTsKICBlbHNlIGlmKGhQYXJlbnQgPT0gaENoaWxkKQogICAgcmV0dXJuIEZBTFNFOwogIHJldHVybiAhSXNDaGlsZChoUGFyZW50LCBoQ2hpbGQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjA4XQogKgogKiBTb21lIHNvcnQgb2YgbWVtb3J5IG1hbmFnZW1lbnQgcHJvY2Vzcy4KICovCkRXT1JEIFdJTkFQSSBGRFNBX0luaXRpYWxpemUoCglEV09SRCAgICBhLAoJRFdPUkQgICAgYiwKCUxQVk9JRCAgIGMsCglMUFZPSUQgICBkLAoJRFdPUkQgICAgZSkKewogICAgRklYTUUoIigweCUwOGx4IDB4JTA4bHggJXAgJXAgMHglMDhseCkgc3R1YlxuIiwKCSAgYSwgYiwgYywgZCwgZSk7CiAgICByZXR1cm4gMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwOV0KICoKICogU29tZSBzb3J0IG9mIG1lbW9yeSBtYW5hZ2VtZW50IHByb2Nlc3MuCiAqLwpEV09SRCBXSU5BUEkgRkRTQV9EZXN0cm95KAoJTFBWT0lEICAgYSkKewogICAgRklYTUUoIiglcCkgc3R1YlxuIiwKCSAgYSk7CiAgICByZXR1cm4gMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIxMF0KICoKICogU29tZSBzb3J0IG9mIG1lbW9yeSBtYW5hZ2VtZW50IHByb2Nlc3MuCiAqLwpEV09SRCBXSU5BUEkgRkRTQV9JbnNlcnRJdGVtKAoJTFBWT0lEICAgYSwKCURXT1JEICAgIGIsCglMUFZPSUQgICBjKQp7CiAgICBGSVhNRSgiKCVwIDB4JTA4bHggJXApIHN0dWJcbiIsCgkgIGEsIGIsIGMpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMTFdCiAqLwpEV09SRCBXSU5BUEkgRkRTQV9EZWxldGVJdGVtKAoJTFBWT0lEICAgYSwKCURXT1JEICAgIGIpCnsKICAgIEZJWE1FKCIoJXAgMHglMDhseCkgc3R1YlxuIiwKCSAgYSwgYik7CiAgICByZXR1cm4gMTsKfQoKdHlwZWRlZiBzdHJ1Y3QgewogICAgUkVGSUlEICAgcmVmaWQ7CiAgICBEV09SRCAgICBpbmR4Owp9IElGQUNFX0lOREVYX1RCTDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMTldCiAqCiAqIENhbGwgSVVua25vd25fUXVlcnlJbnRlcmZhY2UoKSBvbiBhIHRhYmxlIG9mIG9iamVjdHMuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX1BPSU5URVIgb3IgRV9OT0lOVEVSRkFDRS4KICovCkhSRVNVTFQgV0lOQVBJIFFJU2VhcmNoKAoJTFBWT0lEIHcsICAgICAgICAgICAvKiBbaW5dICAgVGFibGUgb2YgaW50ZXJmYWNlcyAqLwoJSUZBQ0VfSU5ERVhfVEJMICp4LCAvKiBbaW5dICAgQXJyYXkgb2YgUkVGSUlEcyBhbmQgaW5kZXhlcyBpbnRvIHRoZSB0YWJsZSAqLwoJUkVGSUlEIHJpaWQsICAgICAgICAvKiBbaW5dICAgUkVGSUlEIHRvIGdldCBpbnRlcmZhY2UgZm9yICovCglMUFZPSUQgKnBwdikgICAgICAgICAgLyogW291dF0gIERlc3RpbmF0aW9uIGZvciBpbnRlcmZhY2UgcG9pbnRlciAqLwp7CglIUkVTVUxUIHJldDsKCUlVbmtub3duICphX3Z0Ymw7CglJRkFDRV9JTkRFWF9UQkwgKnhtb3ZlOwoKCVRSQUNFKCIoJXAgJXAgJXMgJXApXG4iLCB3LHgsZGVidWdzdHJfZ3VpZChyaWlkKSxwcHYpOwoJaWYgKHBwdikgewoJICAgIHhtb3ZlID0geDsKCSAgICB3aGlsZSAoeG1vdmUtPnJlZmlkKSB7CgkJVFJBQ0UoInRyeWluZyAoaW5keCAlbGQpICVzXG4iLCB4bW92ZS0+aW5keCwgZGVidWdzdHJfZ3VpZCh4bW92ZS0+cmVmaWQpKTsKCQlpZiAoSXNFcXVhbElJRChyaWlkLCB4bW92ZS0+cmVmaWQpKSB7CgkJICAgIGFfdnRibCA9IChJVW5rbm93biopKHhtb3ZlLT5pbmR4ICsgKExQQllURSl3KTsKCQkgICAgVFJBQ0UoIm1hdGNoZWQsIHJldHVybmluZyAoJXApXG4iLCBhX3Z0YmwpOwoJCSAgICAqcHB2ID0gKExQVk9JRClhX3Z0Ymw7CgkJICAgIElVbmtub3duX0FkZFJlZihhX3Z0YmwpOwoJCSAgICByZXR1cm4gU19PSzsKCQl9CgkJeG1vdmUrKzsKCSAgICB9CgoJICAgIGlmIChJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKSB7CgkJYV92dGJsID0gKElVbmtub3duKikoeC0+aW5keCArIChMUEJZVEUpdyk7CgkJVFJBQ0UoInJldHVybmluZyBmaXJzdCBmb3IgSVVua25vd24gKCVwKVxuIiwgYV92dGJsKTsKCQkqcHB2ID0gKExQVk9JRClhX3Z0Ymw7CgkJSVVua25vd25fQWRkUmVmKGFfdnRibCk7CgkJcmV0dXJuIFNfT0s7CgkgICAgfQoJICAgICpwcHYgPSAwOwoJICAgIHJldCA9IEVfTk9JTlRFUkZBQ0U7Cgl9IGVsc2UKCSAgICByZXQgPSBFX1BPSU5URVI7CgoJVFJBQ0UoIi0tIDB4JTA4bHhcbiIsIHJldCk7CglyZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjIxXQogKgogKiBSZW1vdmUgdGhlICJQcm9wRGxnRm9udCIgcHJvcGVydHkgZnJvbSBhIHdpbmRvdy4KICoKICogUEFSQU1TCiAqICBoV25kIFtJXSBXaW5kb3cgdG8gcmVtb3ZlIHRoZSBwcm9wZXJ0eSBmcm9tCiAqCiAqIFJFVFVSTlMKICogIEEgaGFuZGxlIHRvIHRoZSByZW1vdmVkIHByb3BlcnR5LCBvciBOVUxMIGlmIGl0IGRpZCBub3QgZXhpc3QuCiAqLwpIQU5ETEUgV0lOQVBJIFNIUmVtb3ZlRGVmYXVsdERpYWxvZ0ZvbnQoSFdORCBoV25kKQp7CiAgSEFORExFIGhQcm9wOwoKICBUUkFDRSgiKCVwKVxuIiwgaFduZCk7CgogIGhQcm9wID0gR2V0UHJvcEEoaFduZCwgIlByb3BEbGdGb250Iik7CgogIGlmKGhQcm9wKQogIHsKICAgIERlbGV0ZU9iamVjdChoUHJvcCk7CiAgICBoUHJvcCA9IFJlbW92ZVByb3BBKGhXbmQsICJQcm9wRGxnRm9udCIpOwogIH0KICByZXR1cm4gaFByb3A7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMzZdCiAqCiAqIExvYWQgdGhlIGluLXByb2Nlc3Mgc2VydmVyIG9mIGEgZ2l2ZW4gR1VJRC4KICoKICogUEFSQU1TCiAqICByZWZpaWQgW0ldIEdVSUQgb2YgdGhlIHNlcnZlciB0byBsb2FkLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBBIGhhbmRsZSB0byB0aGUgbG9hZGVkIHNlcnZlciBkbGwuCiAqICBGYWlsdXJlOiBBIE5VTEwgaGFuZGxlLgogKi8KSE1PRFVMRSBXSU5BUEkgU0hQaW5EbGxPZkNMU0lEKFJFRklJRCByZWZpaWQpCnsKICAgIEhLRVkgbmV3a2V5OwogICAgRFdPUkQgdHlwZSwgY291bnQ7CiAgICBDSEFSIHZhbHVlW01BWF9QQVRIXSwgc3RyaW5nW01BWF9QQVRIXTsKCiAgICBzdHJjcHkoc3RyaW5nLCAiQ0xTSURcXCIpOwogICAgU0hTdHJpbmdGcm9tR1VJREEocmVmaWlkLCBzdHJpbmcgKyA2LCBzaXplb2Yoc3RyaW5nKS9zaXplb2YoY2hhcikgLSA2KTsKICAgIHN0cmNhdChzdHJpbmcsICJcXEluUHJvY1NlcnZlcjMyIik7CgogICAgY291bnQgPSBNQVhfUEFUSDsKICAgIFJlZ09wZW5LZXlFeEEoSEtFWV9DTEFTU0VTX1JPT1QsIHN0cmluZywgMCwgMSwgJm5ld2tleSk7CiAgICBSZWdRdWVyeVZhbHVlRXhBKG5ld2tleSwgMCwgMCwgJnR5cGUsIChQQllURSl2YWx1ZSwgJmNvdW50KTsKICAgIFJlZ0Nsb3NlS2V5KG5ld2tleSk7CiAgICByZXR1cm4gTG9hZExpYnJhcnlFeEEodmFsdWUsIDAsIDApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjM3XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hMV0FQSV8xODMuCiAqLwpEV09SRCBXSU5BUEkgU0hSZWdpc3RlckNsYXNzVyhXTkRDTEFTU1cgKiBscFduZENsYXNzKQp7CglXTkRDTEFTU1cgV25kQ2xhc3M7CgoJVFJBQ0UoIiglcCAlcylcbiIsbHBXbmRDbGFzcy0+aEluc3RhbmNlLCBkZWJ1Z3N0cl93KGxwV25kQ2xhc3MtPmxwc3pDbGFzc05hbWUpKTsKCglpZiAoR2V0Q2xhc3NJbmZvVyhscFduZENsYXNzLT5oSW5zdGFuY2UsIGxwV25kQ2xhc3MtPmxwc3pDbGFzc05hbWUsICZXbmRDbGFzcykpCgkJcmV0dXJuIFRSVUU7CglyZXR1cm4gUmVnaXN0ZXJDbGFzc1cobHBXbmRDbGFzcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMzhdCiAqCiAqIFVucmVnaXN0ZXIgYSBsaXN0IG9mIGNsYXNzZXMuCiAqCiAqIFBBUkFNUwogKiAgaEluc3QgICAgICBbSV0gQXBwbGljYXRpb24gaW5zdGFuY2UgdGhhdCByZWdpc3RlcmVkIHRoZSBjbGFzc2VzCiAqICBscHBDbGFzc2VzIFtJXSBMaXN0IG9mIGNsYXNzIG5hbWVzCiAqICBpQ291bnQgICAgIFtJXSBOdW1iZXIgb2YgbmFtZXMgaW4gbHBwQ2xhc3NlcwogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8Kdm9pZCBXSU5BUEkgU0hVbnJlZ2lzdGVyQ2xhc3Nlc0EoSElOU1RBTkNFIGhJbnN0LCBMUENTVFIgKmxwcENsYXNzZXMsIElOVCBpQ291bnQpCnsKICBXTkRDTEFTU0EgV25kQ2xhc3M7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBoSW5zdCwgbHBwQ2xhc3NlcywgaUNvdW50KTsKCiAgd2hpbGUgKGlDb3VudCA+IDApCiAgewogICAgaWYgKEdldENsYXNzSW5mb0EoaEluc3QsICpscHBDbGFzc2VzLCAmV25kQ2xhc3MpKQogICAgICBVbnJlZ2lzdGVyQ2xhc3NBKCpscHBDbGFzc2VzLCBoSW5zdCk7CiAgICBscHBDbGFzc2VzKys7CiAgICBpQ291bnQtLTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMzldCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSFVucmVnaXN0ZXJDbGFzc2VzQS4KICovCnZvaWQgV0lOQVBJIFNIVW5yZWdpc3RlckNsYXNzZXNXKEhJTlNUQU5DRSBoSW5zdCwgTFBDV1NUUiAqbHBwQ2xhc3NlcywgSU5UIGlDb3VudCkKewogIFdORENMQVNTVyBXbmRDbGFzczsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsIGhJbnN0LCBscHBDbGFzc2VzLCBpQ291bnQpOwoKICB3aGlsZSAoaUNvdW50ID4gMCkKICB7CiAgICBpZiAoR2V0Q2xhc3NJbmZvVyhoSW5zdCwgKmxwcENsYXNzZXMsICZXbmRDbGFzcykpCiAgICAgIFVucmVnaXN0ZXJDbGFzc1coKmxwcENsYXNzZXMsIGhJbnN0KTsKICAgIGxwcENsYXNzZXMrKzsKICAgIGlDb3VudC0tOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI0MF0KICoKICogQ2FsbCBUaGUgY29ycmVjdCAoQXNjaWkvVW5pY29kZSkgZGVmYXVsdCB3aW5kb3cgcHJvY2VkdXJlIGZvciBhIHdpbmRvdy4KICoKICogUEFSQU1TCiAqICBoV25kICAgICBbSV0gV2luZG93IHRvIGNhbGwgdGhlIGRlZmF1bHQgcHJvY2VkdXJlIGZvcgogKiAgdU1lc3NhZ2UgW0ldIE1lc3NhZ2UgSUQKICogIHdQYXJhbSAgIFtJXSBXUEFSQU0gb2YgbWVzc2FnZQogKiAgbFBhcmFtICAgW0ldIExQQVJBTSBvZiBtZXNzYWdlCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXN1bHQgb2YgY2FsbGluZyBEZWZXaW5kb3dQcm9jQSgpIG9yIERlZldpbmRvd1Byb2NXKCkuCiAqLwpMUkVTVUxUIENBTExCQUNLIFNIRGVmV2luZG93UHJvYyhIV05EIGhXbmQsIFVJTlQgdU1lc3NhZ2UsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKCWlmIChJc1dpbmRvd1VuaWNvZGUoaFduZCkpCgkJcmV0dXJuIERlZldpbmRvd1Byb2NXKGhXbmQsIHVNZXNzYWdlLCB3UGFyYW0sIGxQYXJhbSk7CglyZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1lc3NhZ2UsIHdQYXJhbSwgbFBhcmFtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI1N10KICoKICogQ3JlYXRlIGEgd29ya2VyIHdpbmRvdyB1c2luZyBDcmVhdGVXaW5kb3dFeEEoKS4KICoKICogUEFSQU1TCiAqICB3bmRQcm9jICAgIFtJXSBXaW5kb3cgcHJvY2VkdXJlCiAqICBoV25kUGFyZW50IFtJXSBQYXJlbnQgd2luZG93CiAqICBkd0V4U3R5bGUgIFtJXSBFeHRyYSBzdHlsZSBmbGFncwogKiAgZHdTdHlsZSAgICBbSV0gU3R5bGUgZmxhZ3MKICogIGhNZW51ICAgICAgW0ldIFdpbmRvdyBtZW51CiAqICB6ICAgICAgICAgIFtJXSBVbmtub3duCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSB3aW5kb3cgaGFuZGxlIG9mIHRoZSBuZXdseSBjcmVhdGVkIHdpbmRvdy4KICogIEZhaWx1cmU6IDAuCiAqLwpIV05EIFdJTkFQSSBTSENyZWF0ZVdvcmtlcldpbmRvd0EoTE9ORyB3bmRQcm9jLCBIV05EIGhXbmRQYXJlbnQsIERXT1JEIGR3RXhTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdTdHlsZSwgSE1FTlUgaE1lbnUsIExPTkcgeikKewogIHN0YXRpYyBjb25zdCBjaGFyKiBzekNsYXNzID0gIldvcmtlckEiOwogIFdORENMQVNTQSB3YzsKICBIV05EIGhXbmQ7CgogIFRSQUNFKCIoMHglMDhseCwlcCwweCUwOGx4LDB4JTA4bHgsJXAsMHglMDhseClcbiIsCiAgICAgICAgIHduZFByb2MsIGhXbmRQYXJlbnQsIGR3RXhTdHlsZSwgZHdTdHlsZSwgaE1lbnUsIHopOwoKICAvKiBDcmVhdGUgV2luZG93IGNsYXNzICovCiAgd2Muc3R5bGUgICAgICAgICA9IDA7CiAgd2MubHBmblduZFByb2MgICA9IERlZldpbmRvd1Byb2NBOwogIHdjLmNiQ2xzRXh0cmEgICAgPSAwOwogIHdjLmNiV25kRXh0cmEgICAgPSA0OwogIHdjLmhJbnN0YW5jZSAgICAgPSBzaGx3YXBpX2hJbnN0YW5jZTsKICB3Yy5oSWNvbiAgICAgICAgID0gTlVMTDsKICB3Yy5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvckEoTlVMTCwgKExQU1RSKUlEQ19BUlJPVyk7CiAgd2MuaGJyQmFja2dyb3VuZCA9IChIQlJVU0gpQ09MT1JfQlROU0hBRE9XOwogIHdjLmxwc3pNZW51TmFtZSAgPSBOVUxMOwogIHdjLmxwc3pDbGFzc05hbWUgPSBzekNsYXNzOwoKICBTSFJlZ2lzdGVyQ2xhc3NBKCZ3Yyk7IC8qIFJlZ2lzdGVyIGNsYXNzICovCgogIC8qIEZJWE1FOiBTZXQgZXh0cmEgYml0cyBpbiBkd0V4U3R5bGUgKi8KCiAgaFduZCA9IENyZWF0ZVdpbmRvd0V4QShkd0V4U3R5bGUsIHN6Q2xhc3MsIDAsIGR3U3R5bGUsIDAsIDAsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBoV25kUGFyZW50LCBoTWVudSwgc2hsd2FwaV9oSW5zdGFuY2UsIDApOwogIGlmIChoV25kKQogIHsKICAgIFNldFdpbmRvd0xvbmdBKGhXbmQsIERXTF9NU0dSRVNVTFQsIHopOwoKICAgIGlmICh3bmRQcm9jKQogICAgICBTZXRXaW5kb3dMb25nUHRyQShoV25kLCBHV0xQX1dORFBST0MsIHduZFByb2MpOwogIH0KICByZXR1cm4gaFduZDsKfQoKdHlwZWRlZiBzdHJ1Y3QgdGFnUE9MSUNZREFUQQp7CiAgRFdPUkQgcG9saWN5OyAgICAgICAgLyogZmxhZ3MgdmFsdWUgcGFzc2VkIHRvIFNIUmVzdHJpY3RlZCAqLwogIExQQ1dTVFIgYXBwc3RyOyAgICAgIC8qIGFwcGxpY2F0aW9uIHN0ciBzdWNoIGFzICJFeHBsb3JlciIgKi8KICBMUENXU1RSIGtleXN0cjsgICAgICAvKiBuYW1lIG9mIHRoZSBhY3R1YWwgcmVnaXN0cnkga2V5IC8gcG9saWN5ICovCn0gUE9MSUNZREFUQSwgKkxQUE9MSUNZREFUQTsKCiNkZWZpbmUgU0hFTExfTk9fUE9MSUNZIDB4ZmZmZmZmZmYKCi8qIGRlZmF1bHQgc2hlbGwgcG9saWN5IHJlZ2lzdHJ5IGtleSAqLwpzdGF0aWMgY29uc3QgV0NIQVIgc3RyUmVnaXN0cnlQb2xpY3lXW10gPSB7J1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLCdNJywnaScsJ2MnLCdyJywnbycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCdcXCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXFwnLCdQJywnbycsJ2wnLCdpJywnYycsJ2knLCdlJywncycsMH07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgICAgICAgICAgICAgICAgICAgICAgICBbU0hMV0FQSS4yNzFdCiAqCiAqIFJldHJpZXZlIGEgcG9saWN5IHZhbHVlIGZyb20gdGhlIHJlZ2lzdHJ5LgogKgogKiBQQVJBTVMKICogIGxwU3ViS2V5ICAgW0ldICAgcmVnaXN0cnkga2V5IG5hbWUKICogIGxwU3ViTmFtZSAgW0ldICAgc3VibmFtZSBvZiByZWdpc3RyeSBrZXkKICogIGxwVmFsdWUgICAgW0ldICAgdmFsdWUgbmFtZSBvZiByZWdpc3RyeSB2YWx1ZQogKgogKiBSRVRVUk5TCiAqICB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSByZWdpc3RyeSBrZXkgb3IgMCBpZiBub3QgZm91bmQKICovCkRXT1JEIFdJTkFQSSBTSEdldFJlc3RyaWN0aW9uKExQQ1dTVFIgbHBTdWJLZXksIExQQ1dTVFIgbHBTdWJOYW1lLCBMUENXU1RSIGxwVmFsdWUpCnsKCURXT1JEIHJldHZhbCwgZGF0c2l6ZSA9IHNpemVvZihyZXR2YWwpOwoJSEtFWSBoS2V5OwoKCWlmICghbHBTdWJLZXkpCgkgIGxwU3ViS2V5ID0gc3RyUmVnaXN0cnlQb2xpY3lXOwoKCXJldHZhbCA9IFJlZ09wZW5LZXlXKEhLRVlfTE9DQUxfTUFDSElORSwgbHBTdWJLZXksICZoS2V5KTsKICAgIGlmIChyZXR2YWwgIT0gRVJST1JfU1VDQ0VTUykKCSAgcmV0dmFsID0gUmVnT3BlbktleVcoSEtFWV9DVVJSRU5UX1VTRVIsIGxwU3ViS2V5LCAmaEtleSk7CglpZiAocmV0dmFsICE9IEVSUk9SX1NVQ0NFU1MpCgkgIHJldHVybiAwOwoKCVNIR2V0VmFsdWVXKGhLZXksIGxwU3ViTmFtZSwgbHBWYWx1ZSwgTlVMTCwgKExQQllURSkmcmV0dmFsLCAmZGF0c2l6ZSk7CglSZWdDbG9zZUtleShoS2V5KTsKCXJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICAgICAgICAgICAgICAgICAgICAgICAgW1NITFdBUEkuMjY2XQogKgogKiBIZWxwZXIgZnVuY3Rpb24gdG8gcmV0cmlldmUgdGhlIHBvc3NpYmx5IGNhY2hlZCB2YWx1ZSBmb3IgYSBzcGVjaWZpYyBwb2xpY3kKICoKICogUEFSQU1TCiAqICBwb2xpY3kgICAgIFtJXSAgIFRoZSBwb2xpY3kgdG8gbG9vayBmb3IKICogIGluaXRpYWwgICAgW0ldICAgTWFpbiByZWdpc3RyeSBrZXkgdG8gb3BlbiwgaWYgTlVMTCB1c2UgZGVmYXVsdAogKiAgcG9sVGFibGUgICBbSV0gICBUYWJsZSBvZiBrbm93biBwb2xpY2llcywgMCB0ZXJtaW5hdGVkCiAqICBwb2xBcnIgICAgIFtJXSAgIENhY2hlIGFycmF5IG9mIHBvbGljeSB2YWx1ZXMKICoKICogUkVUVVJOUwogKiAgVGhlIHJldHJpZXZlZCBwb2xpY3kgdmFsdWUgb3IgMCBpZiBub3Qgc3VjY2Vzc2Z1bAogKgogKiBOT1RFUwogKiAgVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGJ5IHRoZSBuYXRpdmUgU0hSZXN0cmljdGVkIGZ1bmN0aW9uIHRvIHNlYXJjaCBmb3IgdGhlCiAqICBwb2xpY3kgYW5kIGNhY2hlIGl0IG9uY2UgcmV0cmlldmVkLiBUaGUgY3VycmVudCBXaW5lIGltcGxlbWVudGF0aW9uIHVzZXMgYQogKiAgZGlmZmVyZW50IFBPTElDWURBVEEgc3RydWN0dXJlIGFuZCBpbXBsZW1lbnRzIGEgc2ltaWxhciBhbGdvcml0aG1lIGFkYXB0ZWQgdG8KICogIHRoYXQgc3RydWN0dXJlLgogKi8KRFdPUkQgV0lOQVBJIFNIUmVzdHJpY3Rpb25Mb29rdXAoCglEV09SRCBwb2xpY3ksCglMUENXU1RSIGluaXRpYWwsCglMUFBPTElDWURBVEEgcG9sVGFibGUsCglMUERXT1JEIHBvbEFycikKewoJVFJBQ0UoIigweCUwOGx4ICVzICVwICVwKVxuIiwgcG9saWN5LCBkZWJ1Z3N0cl93KGluaXRpYWwpLCBwb2xUYWJsZSwgcG9sQXJyKTsKCglpZiAoIXBvbFRhYmxlIHx8ICFwb2xBcnIpCgkgIHJldHVybiAwOwoKCWZvciAoO3BvbFRhYmxlLT5wb2xpY3k7IHBvbFRhYmxlKyssIHBvbEFycisrKQoJewoJICBpZiAocG9saWN5ID09IHBvbFRhYmxlLT5wb2xpY3kpCgkgIHsKCSAgICAvKiB3ZSBoYXZlIGEga25vd24gcG9saWN5ICovCgoJICAgIC8qIGNoZWNrIGlmIHRoaXMgcG9saWN5IGhhcyBiZWVuIGNhY2hlZCAqLwoJCWlmICgqcG9sQXJyID09IFNIRUxMX05PX1BPTElDWSkKCSAgICAgICpwb2xBcnIgPSBTSEdldFJlc3RyaWN0aW9uKGluaXRpYWwsIHBvbFRhYmxlLT5hcHBzdHIsIHBvbFRhYmxlLT5rZXlzdHIpOwoJICAgIHJldHVybiAqcG9sQXJyOwoJICB9Cgl9CgkvKiB3ZSBkb24ndCBrbm93IHRoaXMgcG9saWN5LCByZXR1cm4gMCAqLwoJVFJBQ0UoInVua25vd24gcG9saWN5OiAoJTA4bHgpXG4iLCBwb2xpY3kpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjddCiAqCiAqIEdldCBhbiBpbnRlcmZhY2UgZnJvbSBhbiBvYmplY3QuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIHBwdiBjb250YWlucyB0aGUgcmVxdWVzdGVkIGludGVyZmFjZS4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogICBUaGlzIFF1ZXJ5SW50ZXJmYWNlIGFza3MgdGhlIGlubmVyIG9iamVjdCBmb3IgYSBpbnRlcmZhY2UuIEluIGNhc2UKICogICBvZiBhZ2dyZWdhdGlvbiB0aGlzIHJlcXVlc3Qgd291bGQgYmUgZm9yd2FyZGVkIGJ5IHRoZSBpbm5lciB0byB0aGUKICogICBvdXRlciBvYmplY3QuIFRoaXMgZnVuY3Rpb24gYXNrcyB0aGUgaW5uZXIgb2JqZWN0IGRpcmVjdGx5IGZvciB0aGUKICogICBpbnRlcmZhY2UgY2lyY3VtdmVudGluZyB0aGUgZm9yd2FyZGluZyB0byB0aGUgb3V0ZXIgb2JqZWN0LgogKi8KSFJFU1VMVCBXSU5BUEkgU0hXZWFrUXVlcnlJbnRlcmZhY2UoCglJVW5rbm93biAqIHBVbmssICAgLyogW2luXSBPdXRlciBvYmplY3QgKi8KCUlVbmtub3duICogcElubmVyLCAvKiBbaW5dIElubmVyIG9iamVjdCAqLwoJSUlEICogcmlpZCwgLyogW2luXSBJbnRlcmZhY2UgR1VJRCB0byBxdWVyeSBmb3IgKi8KCUxQVk9JRCogcHB2KSAvKiBbb3V0XSBEZXN0aW5hdGlvbiBmb3IgcXVlcmllZCBpbnRlcmZhY2UgKi8KewoJSFJFU1VMVCBocmV0ID0gRV9OT0lOVEVSRkFDRTsKCVRSQUNFKCIocFVuaz0lcCBwSW5uZXI9JXBcblx0SUlEOiAgJXMgJXApXG4iLHBVbmsscElubmVyLGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdik7CgoJKnBwdiA9IE5VTEw7CglpZihwVW5rICYmIHBJbm5lcikgewoJICAgIGhyZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShwSW5uZXIsIHJpaWQsIChMUFZPSUQqKXBwdik7CgkgICAgaWYgKFNVQ0NFRURFRChocmV0KSkgSVVua25vd25fUmVsZWFzZShwVW5rKTsKCX0KCVRSQUNFKCItLSAweCUwOGx4XG4iLCBocmV0KTsKCXJldHVybiBocmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjY4XQogKgogKiBNb3ZlIGEgcmVmZXJlbmNlIGZyb20gb25lIGludGVyZmFjZSB0byBhbm90aGVyLgogKgogKiBQQVJBTVMKICogICBscERlc3QgICAgIFtPXSBEZXN0aW5hdGlvbiB0byByZWNlaXZlIHRoZSByZWZlcmVuY2UKICogICBscHBVbmtub3duIFtPXSBTb3VyY2UgdG8gZ2l2ZSB1cCB0aGUgcmVmZXJlbmNlIHRvIGxwRGVzdAogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KVk9JRCBXSU5BUEkgU0hXZWFrUmVsZWFzZUludGVyZmFjZShJVW5rbm93biAqbHBEZXN0LCBJVW5rbm93biAqKmxwcFVua25vd24pCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBEZXN0LCBscHBVbmtub3duKTsKCiAgaWYgKCpscHBVbmtub3duKQogIHsKICAgIC8qIENvcHkgUmVmZXJlbmNlKi8KICAgIElVbmtub3duX0FkZFJlZihscERlc3QpOwogICAgSVVua25vd25fQXRvbWljUmVsZWFzZShscHBVbmtub3duKTsgLyogUmVsZWFzZSBleGlzdGluZyBpbnRlcmZhY2UgKi8KICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjldCiAqCiAqIENvbnZlcnQgYW4gQVNDSUkgc3RyaW5nIG9mIGEgQ0xTSUQgaW50byBhIENMU0lELgogKgogKiBQQVJBTVMKICogIGlkc3RyIFtJXSBTdHJpbmcgcmVwcmVzZW50aW5nIGEgQ0xTSUQgaW4gcmVnaXN0cnkgZm9ybWF0CiAqICBpZCAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBjb252ZXJ0ZWQgQ0xTSUQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gaWQgY29udGFpbnMgdGhlIGNvbnZlcnRlZCBDTFNJRC4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgR1VJREZyb21TdHJpbmdBKExQQ1NUUiBpZHN0ciwgQ0xTSUQgKmlkKQp7CiAgV0NIQVIgd0Nsc2lkWzQwXTsKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgaWRzdHIsIC0xLCB3Q2xzaWQsIHNpemVvZih3Q2xzaWQpL3NpemVvZihXQ0hBUikpOwogIHJldHVybiBTVUNDRUVERUQoQ0xTSURGcm9tU3RyaW5nV3JhcCh3Q2xzaWQsIGlkKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzBdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBHVUlERnJvbVN0cmluZ0EuCiAqLwpCT09MIFdJTkFQSSBHVUlERnJvbVN0cmluZ1coTFBDV1NUUiBpZHN0ciwgQ0xTSUQgKmlkKQp7CiAgcmV0dXJuIFNVQ0NFRURFRChDTFNJREZyb21TdHJpbmdXcmFwKGlkc3RyLCBpZCkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjc2XQogKgogKiBEZXRlcm1pbmUgaWYgdGhlIGJyb3dzZXIgaXMgaW50ZWdyYXRlZCBpbnRvIHRoZSBzaGVsbCwgYW5kIHNldCBhIHJlZ2lzdHJ5CiAqIGtleSBhY2NvcmRpbmdseS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICAxLCBJZiB0aGUgYnJvd3NlciBpcyBub3QgaW50ZWdyYXRlZC4KICogIDIsIElmIHRoZSBicm93c2VyIGlzIGludGVncmF0ZWQuCiAqCiAqIE5PVEVTCiAqICBUaGUga2V5ICJIS0xNXFNvZnR3YXJlXE1pY3Jvc29mdFxJbnRlcm5ldCBFeHBsb3JlclxJbnRlZ3JhdGVkQnJvd3NlciIgaXMKICogIGVpdGhlciBzZXQgdG8gVFJVRSwgb3IgcmVtb3ZlZCBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgYnJvd3NlciBpcyBkZWVtZWQKICogIHRvIGJlIGludGVncmF0ZWQuCiAqLwpEV09SRCBXSU5BUEkgV2hpY2hQbGF0Zm9ybSgpCnsKICBzdGF0aWMgTFBDU1RSIHN6SW50ZWdyYXRlZEJyb3dzZXIgPSAiSW50ZWdyYXRlZEJyb3dzZXIiOwogIHN0YXRpYyBEV09SRCBkd1N0YXRlID0gMDsKICBIS0VZIGhLZXk7CiAgRFdPUkQgZHdSZXQsIGR3RGF0YSwgZHdTaXplOwoKICBpZiAoZHdTdGF0ZSkKICAgIHJldHVybiBkd1N0YXRlOwoKICAvKiBJZiBzaGVsbDMyIGV4cG9ydHMgRGxsR2V0VmVyc2lvbigpLCB0aGUgYnJvd3NlciBpcyBpbnRlZ3JhdGVkICovCiAgR0VUX0ZVTkMocERsbEdldFZlcnNpb24sIHNoZWxsMzIsICJEbGxHZXRWZXJzaW9uIiwgMSk7CiAgZHdTdGF0ZSA9IHBEbGxHZXRWZXJzaW9uID8gMiA6IDE7CgogIC8qIFNldCBvciBkZWxldGUgdGhlIGtleSBhY2NvcmRpbmdseSAqLwogIGR3UmV0ID0gUmVnT3BlbktleUV4QShIS0VZX0xPQ0FMX01BQ0hJTkUsCiAgICAgICAgICAgICAgICAgICAgICAgICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxJbnRlcm5ldCBFeHBsb3JlciIsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfQUxMX0FDQ0VTUywgJmhLZXkpOwogIGlmICghZHdSZXQpCiAgewogICAgZHdSZXQgPSBSZWdRdWVyeVZhbHVlRXhBKGhLZXksIHN6SW50ZWdyYXRlZEJyb3dzZXIsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQQllURSkmZHdEYXRhLCAmZHdTaXplKTsKCiAgICBpZiAoIWR3UmV0ICYmIGR3U3RhdGUgPT0gMSkKICAgIHsKICAgICAgLyogVmFsdWUgZXhpc3RzIGJ1dCBicm93c2VyIGlzIG5vdCBpbnRlZ3JhdGVkICovCiAgICAgIFJlZ0RlbGV0ZVZhbHVlQShoS2V5LCBzekludGVncmF0ZWRCcm93c2VyKTsKICAgIH0KICAgIGVsc2UgaWYgKGR3UmV0ICYmIGR3U3RhdGUgPT0gMikKICAgIHsKICAgICAgLyogQnJvd3NlciBpcyBpbnRlZ3JhdGVkIGJ1dCB2YWx1ZSBkb2VzIG5vdCBleGlzdCAqLwogICAgICBkd0RhdGEgPSBUUlVFOwogICAgICBSZWdTZXRWYWx1ZUV4QShoS2V5LCBzekludGVncmF0ZWRCcm93c2VyLCAwLCBSRUdfRFdPUkQsCiAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpJmR3RGF0YSwgc2l6ZW9mKGR3RGF0YSkpOwogICAgfQogICAgUmVnQ2xvc2VLZXkoaEtleSk7CiAgfQogIHJldHVybiBkd1N0YXRlOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjc4XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hDcmVhdGVXb3JrZXJXaW5kb3dBLgogKi8KSFdORCBXSU5BUEkgU0hDcmVhdGVXb3JrZXJXaW5kb3dXKExPTkcgd25kUHJvYywgSFdORCBoV25kUGFyZW50LCBEV09SRCBkd0V4U3R5bGUsCiAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3U3R5bGUsIEhNRU5VIGhNZW51LCBMT05HIHopCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pDbGFzc1tdID0geyAnVycsICdvJywgJ3InLCAnaycsICdlJywgJ3InLCAnVycsICdcMCcgfTsKICBXTkRDTEFTU1cgd2M7CiAgSFdORCBoV25kOwoKICBUUkFDRSgiKDB4JTA4bHgsJXAsMHglMDhseCwweCUwOGx4LCVwLDB4JTA4bHgpXG4iLAogICAgICAgICB3bmRQcm9jLCBoV25kUGFyZW50LCBkd0V4U3R5bGUsIGR3U3R5bGUsIGhNZW51LCB6KTsKCiAgLyogSWYgb3VyIE9TIGlzIG5hdGl2ZWx5IEFTQ0lJLCB1c2UgdGhlIEFTQ0lJIHZlcnNpb24gKi8KICBpZiAoIShHZXRWZXJzaW9uKCkgJiAweDgwMDAwMDAwKSkgIC8qIE5UICovCiAgICByZXR1cm4gU0hDcmVhdGVXb3JrZXJXaW5kb3dBKHduZFByb2MsIGhXbmRQYXJlbnQsIGR3RXhTdHlsZSwgZHdTdHlsZSwgaE1lbnUsIHopOwoKICAvKiBDcmVhdGUgV2luZG93IGNsYXNzICovCiAgd2Muc3R5bGUgICAgICAgICA9IDA7CiAgd2MubHBmblduZFByb2MgICA9IERlZldpbmRvd1Byb2NXOwogIHdjLmNiQ2xzRXh0cmEgICAgPSAwOwogIHdjLmNiV25kRXh0cmEgICAgPSA0OwogIHdjLmhJbnN0YW5jZSAgICAgPSBzaGx3YXBpX2hJbnN0YW5jZTsKICB3Yy5oSWNvbiAgICAgICAgID0gTlVMTDsKICB3Yy5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvclcoTlVMTCwgKExQV1NUUilJRENfQVJST1cpOwogIHdjLmhickJhY2tncm91bmQgPSAoSEJSVVNIKUNPTE9SX0JUTlNIQURPVzsKICB3Yy5scHN6TWVudU5hbWUgID0gTlVMTDsKICB3Yy5scHN6Q2xhc3NOYW1lID0gc3pDbGFzczsKCiAgU0hSZWdpc3RlckNsYXNzVygmd2MpOyAvKiBSZWdpc3RlciBjbGFzcyAqLwoKICAvKiBGSVhNRTogU2V0IGV4dHJhIGJpdHMgaW4gZHdFeFN0eWxlICovCgogIGhXbmQgPSBDcmVhdGVXaW5kb3dFeFcoZHdFeFN0eWxlLCBzekNsYXNzLCAwLCBkd1N0eWxlLCAwLCAwLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgaFduZFBhcmVudCwgaE1lbnUsIHNobHdhcGlfaEluc3RhbmNlLCAwKTsKICBpZiAoaFduZCkKICB7CiAgICBTZXRXaW5kb3dMb25nVyhoV25kLCBEV0xfTVNHUkVTVUxULCB6KTsKCiAgICBpZiAod25kUHJvYykKICAgICAgU2V0V2luZG93TG9uZ1B0clcoaFduZCwgR1dMUF9XTkRQUk9DLCB3bmRQcm9jKTsKICB9CiAgcmV0dXJuIGhXbmQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzldCiAqCiAqIEdldCBhbmQgc2hvdyBhIGNvbnRleHQgbWVudSBmcm9tIGEgc2hlbGwgZm9sZGVyLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgICAgIFtJXSBXaW5kb3cgZGlzcGxheWluZyB0aGUgc2hlbGwgZm9sZGVyCiAqICBscEZvbGRlciAgICAgICBbSV0gSVNoZWxsRm9sZGVyIGludGVyZmFjZQogKiAgbHBBcGlkbCAgICAgICAgW0ldIElkIGZvciB0aGUgcGFydGljdWxhciBmb2xkZXIgZGVzaXJlZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlIGluZGljYXRpbmcgdGhlIGVycm9yLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hJbnZva2VEZWZhdWx0Q29tbWFuZChIV05EIGhXbmQsIElTaGVsbEZvbGRlciogbHBGb2xkZXIsIExQQ0lURU1JRExJU1QgbHBBcGlkbCkKewogIHJldHVybiBTSEludm9rZUNvbW1hbmQoaFduZCwgbHBGb2xkZXIsIGxwQXBpZGwsIEZBTFNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4MV0KICoKICogX1NIUGFja0Rpc3BQYXJhbXNWCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFBhY2tEaXNwUGFyYW1zVihMUFZPSUQgdywgTFBWT0lEIHgsIExQVk9JRCB5LCBMUFZPSUQgeikKewoJRklYTUUoIiVwICVwICVwICVwXG4iLHcseCx5LHopOwoJcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjI4Ml0KICoKICogVGhpcyBmdW5jdGlvbiBzZWVtcyB0byBiZSBhIGZvcndhcmQgdG8gU0hQYWNrRGlzcFBhcmFtc1YgKHdoYXRldmVyIFRIQVQKICogZnVuY3Rpb24gZG9lcy4uLikuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFBhY2tEaXNwUGFyYW1zKExQVk9JRCB3LCBMUFZPSUQgeCwgTFBWT0lEIHksIExQVk9JRCB6KQp7CiAgRklYTUUoIiVwICVwICVwICVwXG4iLCB3LCB4LCB5LCB6KTsKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg0XQogKgogKiBfSUNvbm5lY3Rpb25Qb2ludF9TaW1wbGVJbnZva2UKICovCkRXT1JEIFdJTkFQSSBJQ29ubmVjdGlvblBvaW50X1NpbXBsZUludm9rZSgKCUxQVk9JRCB4LAoJTFBWT0lEIHksCglMUFZPSUQgeikKewogICAgICAgIEZJWE1FKCIoJXAgJXAgJXApIHN0dWJcbiIseCx5LHopOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODVdCiAqCiAqIE5vdGlmeSBhbiBJQ29ubmVjdGlvblBvaW50IG9iamVjdCBvZiBjaGFuZ2VzLgogKgogKiBQQVJBTVMKICogIGxwQ1AgICBbSV0gT2JqZWN0IHRvIG5vdGlmeQogKiAgZGlzcElEIFtJXQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9OT0lOVEVSRkFDRSwgaWYgbHBDUCBpcyBOVUxMIG9yIGRvZXMgbm90IHN1cHBvcnQgdGhlCiAqICAgICAgICAgICBJQ29ubmVjdGlvblBvaW50IGludGVyZmFjZS4KICovCkhSRVNVTFQgV0lOQVBJIElDb25uZWN0aW9uUG9pbnRfT25DaGFuZ2VkKElDb25uZWN0aW9uUG9pbnQqIGxwQ1AsIERJU1BJRCBkaXNwSUQpCnsKICBJRW51bUNvbm5lY3Rpb25zICpscEVudW07CiAgSFJFU1VMVCBoUmV0ID0gRV9OT0lOVEVSRkFDRTsKCiAgVFJBQ0UoIiglcCwweCU4bFgpXG4iLCBscENQLCBkaXNwSUQpOwoKICAvKiBHZXQgYW4gZW51bWVyYXRvciBmb3IgdGhlIGNvbm5lY3Rpb25zICovCiAgaWYgKGxwQ1ApCiAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9FbnVtQ29ubmVjdGlvbnMobHBDUCwgJmxwRW51bSk7CgogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgSVByb3BlcnR5Tm90aWZ5U2luayAqbHBTaW5rOwogICAgQ09OTkVDVERBVEEgY29ubkRhdGE7CiAgICBVTE9ORyB1bEZldGNoZWQ7CgogICAgLyogQ2FsbCBPbkNoYW5nZWQoKSBmb3IgZXZlcnkgbm90aWZ5IHNpbmsgaW4gdGhlIGNvbm5lY3Rpb24gcG9pbnQgKi8KICAgIHdoaWxlIChJRW51bUNvbm5lY3Rpb25zX05leHQobHBFbnVtLCAxLCAmY29ubkRhdGEsICZ1bEZldGNoZWQpID09IFNfT0spCiAgICB7CiAgICAgIGlmIChTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UoY29ubkRhdGEucFVuaywgJklJRF9JUHJvcGVydHlOb3RpZnlTaW5rLCAodm9pZCoqKSZscFNpbmspKSAmJgogICAgICAgICAgbHBTaW5rKQogICAgICB7CiAgICAgICAgSVByb3BlcnR5Tm90aWZ5U2lua19PbkNoYW5nZWQobHBTaW5rLCBkaXNwSUQpOwogICAgICAgIElQcm9wZXJ0eU5vdGlmeVNpbmtfUmVsZWFzZShscFNpbmspOwogICAgICB9CiAgICAgIElVbmtub3duX1JlbGVhc2UoY29ubkRhdGEucFVuayk7CiAgICB9CgogICAgSUVudW1Db25uZWN0aW9uc19SZWxlYXNlKGxwRW51bSk7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg3XQogKgogKiBOb3RpZnkgYW4gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciBvYmplY3Qgb2YgY2hhbmdlcy4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byBub3RpZnkKICogIGRpc3BJRCAgICBbSV0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfTk9JTlRFUkZBQ0UsIGlmIGxwVW5rbm93biBpcyBOVUxMIG9yIGRvZXMgbm90IHN1cHBvcnQgdGhlCiAqICAgICAgICAgICBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIGludGVyZmFjZS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0NQQ29udGFpbmVyT25DaGFuZ2VkKElVbmtub3duICpscFVua25vd24sIERJU1BJRCBkaXNwSUQpCnsKICBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyKiBscENQQyA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0ID0gRV9OT0lOVEVSRkFDRTsKCiAgVFJBQ0UoIiglcCwweCU4bFgpXG4iLCBscFVua25vd24sIGRpc3BJRCk7CgogIGlmIChscFVua25vd24pCiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lDb25uZWN0aW9uUG9pbnRDb250YWluZXIsICh2b2lkKiopJmxwQ1BDKTsKCiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICBJQ29ubmVjdGlvblBvaW50KiBscENQOwoKICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyX0ZpbmRDb25uZWN0aW9uUG9pbnQobHBDUEMsICZJSURfSVByb3BlcnR5Tm90aWZ5U2luaywgJmxwQ1ApOwogICAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lcl9SZWxlYXNlKGxwQ1BDKTsKCiAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9PbkNoYW5nZWQobHBDUCwgZGlzcElEKTsKICAgIElDb25uZWN0aW9uUG9pbnRfUmVsZWFzZShscENQKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODldCiAqCiAqIFNlZSBQbGF5U291bmRXLgogKi8KQk9PTCBXSU5BUEkgUGxheVNvdW5kV3JhcFcoTFBDV1NUUiBwc3pTb3VuZCwgSE1PRFVMRSBobW9kLCBEV09SRCBmZHdTb3VuZCkKewogIEdFVF9GVU5DKHBQbGF5U291bmRXLCB3aW5tbSwgIlBsYXlTb3VuZFciLCBGQUxTRSk7CiAgcmV0dXJuIHBQbGF5U291bmRXKHBzelNvdW5kLCBobW9kLCBmZHdTb3VuZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOTRdCiAqLwpCT09MIFdJTkFQSSBTSEdldEluaVN0cmluZ1coTFBTVFIgc3RyMSwgTFBTVFIgc3RyMiwgTFBTVFIgcFN0ciwgRFdPUkQgc29tZV9sZW4sICBMUENTVFIgbHBTdHIyKQp7CiAgICAvKgogICAgICogc3RyMToJCSJJIgkiSSIJcHVzaGwgZXNwKzB4MjAKICAgICAqIHN0cjI6CQkiVSIJIkkiCXB1c2hsIDB4NzdjOTM4MTAKICAgICAqIChpcyAiSSIgYW5kICJVIiAiaW50ZWdlciIgYW5kICJ1bnNpZ25lZCIgPz8pCiAgICAgKgogICAgICogcFN0cjoJCSIiCSIiCXB1c2hsIGVheAogICAgICogc29tZV9sZW46CTB4ODI0CTB4MTA0CXB1c2hsIDB4ODI0CiAgICAgKiBscFN0cjI6CQkiJWwiCSIlbCIJcHVzaGwgZXNwKzB4YwogICAgICoKICAgICAqIHNobHdhcGkuIFN0ckNweU5XKGxwU3RyMiwgaXJyZWxldmFudF92YXIsIDB4MTA0KTsKICAgICAqIExvY2FsQWxsb2MoMHgwMCwgc29tZV9sZW4pIC0+IGlycmVsZXZhbnRfdmFyCiAgICAgKiBMb2NhbEFsbG9jKDB4NDAsIGlycmVsZXZhbnRfbGVuKSAtPiBwU3RyCiAgICAgKiBzaGx3YXBpLjI5NChzdHIxLCBzdHIyLCBwU3RyLCBzb21lX2xlbiwgbHBTdHIyKTsKICAgICAqIHNobHdhcGkuUGF0aFJlbW92ZUJsYW5rc1cocFN0cik7CiAgICAgKi8KICAgIEZJWE1FKCIoJyVzJywgJyVzJywgJyVzJywgJTA4bHgsICclcycpOiBzdHViIVxuIiwgc3RyMSwgc3RyMiwgcFN0ciwgc29tZV9sZW4sIGxwU3RyMik7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5NV0KICoKICogQ2FsbGVkIGJ5IElDUTIwMDBiIGluc3RhbGwgdmlhIFNIRE9DVlc6CiAqIHN0cjE6ICJJbnRlcm5ldFNob3J0Y3V0IgogKiB4OiBzb21lIHVua25vd24gcG9pbnRlcgogKiBzdHIyOiAiaHR0cDovL2ZyZWUuYW9sLmNvbS90cnlhb2xmcmVlL2luZGV4LmFkcD8xMzkyNjkiCiAqIHN0cjM6ICJDOlxcV0lORE9XU1xcRGVza3RvcC5uZXcyXFxGcmVlIEFPTCAmIFVubGltaXRlZCBJbnRlcm5ldC51cmwiCiAqCiAqIEluIHNob3J0OiB0aGlzIG9uZSBtYXliZSBjcmVhdGVzIGEgZGVza3RvcCBsaW5rIDotKQogKi8KQk9PTCBXSU5BUEkgU0hTZXRJbmlTdHJpbmdXKExQV1NUUiBzdHIxLCBMUFZPSUQgeCwgTFBXU1RSIHN0cjIsIExQV1NUUiBzdHIzKQp7CiAgICBGSVhNRSgiKCclcycsICVwLCAnJXMnLCAnJXMnKSwgc3R1Yi5cbiIsIGRlYnVnc3RyX3coc3RyMSksIHgsIGRlYnVnc3RyX3coc3RyMiksIGRlYnVnc3RyX3coc3RyMykpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOTldCiAqCiAqIFNlZSBDT01DVEwzMl80MTcuCiAqLwpCT09MIFdJTkFQSSBFeHRUZXh0T3V0V3JhcFcoSERDIGhkYywgSU5UIHgsIElOVCB5LCBVSU5UIGZsYWdzLCBjb25zdCBSRUNUICpscHJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIHN0ciwgVUlOVCBjb3VudCwgY29uc3QgSU5UICpscER4KQp7CiAgICBHRVRfRlVOQyhwQ09NQ1RMMzJfNDE3LCBjb21jdGwzMiwgKExQQ1NUUik0MTcsIEZBTFNFKTsKICAgIHJldHVybiBwQ09NQ1RMMzJfNDE3KGhkYywgeCwgeSwgZmxhZ3MsIGxwcmVjdCwgc3RyLCBjb3VudCwgbHBEeCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMTNdCiAqCiAqIFNlZSBTSEdldEZpbGVJbmZvVy4KICovCkRXT1JEIFdJTkFQSSBTSEdldEZpbGVJbmZvV3JhcFcoTFBDV1NUUiBwYXRoLCBEV09SRCBkd0ZpbGVBdHRyaWJ1dGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgU0hGSUxFSU5GT1cgKnBzZmksIFVJTlQgc2l6ZW9mcHNmaSwgVUlOVCBmbGFncykKewogIEdFVF9GVU5DKHBTSEdldEZpbGVJbmZvVywgc2hlbGwzMiwgIlNIR2V0RmlsZUluZm9XIiwgMCk7CiAgcmV0dXJuIHBTSEdldEZpbGVJbmZvVyhwYXRoLCBkd0ZpbGVBdHRyaWJ1dGVzLCBwc2ZpLCBzaXplb2Zwc2ZpLCBmbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMThdCiAqCiAqIFNlZSBEcmFnUXVlcnlGaWxlVy4KICovClVJTlQgV0lOQVBJIERyYWdRdWVyeUZpbGVXcmFwVyhIRFJPUCBoRHJvcCwgVUlOVCBsRmlsZSwgTFBXU1RSIGxwc3pGaWxlLCBVSU5UIGxMZW5ndGgpCnsKICBHRVRfRlVOQyhwRHJhZ1F1ZXJ5RmlsZVcsIHNoZWxsMzIsICJEcmFnUXVlcnlGaWxlVyIsIDApOwogIHJldHVybiBwRHJhZ1F1ZXJ5RmlsZVcoaERyb3AsIGxGaWxlLCBscHN6RmlsZSwgbExlbmd0aCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzNdCiAqCiAqIFNlZSBTSEJyb3dzZUZvckZvbGRlclcuCiAqLwpMUElURU1JRExJU1QgV0lOQVBJIFNIQnJvd3NlRm9yRm9sZGVyV3JhcFcoTFBCUk9XU0VJTkZPVyBscEJpKQp7CiAgR0VUX0ZVTkMocFNIQnJvd3NlRm9yRm9sZGVyVywgc2hlbGwzMiwgIlNIQnJvd3NlRm9yRm9sZGVyVyIsIE5VTEwpOwogIHJldHVybiBwU0hCcm93c2VGb3JGb2xkZXJXKGxwQmkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM0XQogKgogKiBTZWUgU0hHZXRQYXRoRnJvbUlETGlzdFcuCiAqLwpCT09MIFdJTkFQSSBTSEdldFBhdGhGcm9tSURMaXN0V3JhcFcoTFBDSVRFTUlETElTVCBwaWRsLExQV1NUUiBwc3pQYXRoKQp7CiAgR0VUX0ZVTkMocFNIR2V0UGF0aEZyb21JRExpc3RXLCBzaGVsbDMyLCAiU0hHZXRQYXRoRnJvbUlETGlzdFciLCAwKTsKICByZXR1cm4gcFNIR2V0UGF0aEZyb21JRExpc3RXKHBpZGwsIHBzelBhdGgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM1XQogKgogKiBTZWUgU2hlbGxFeGVjdXRlRXhXLgogKi8KQk9PTCBXSU5BUEkgU2hlbGxFeGVjdXRlRXhXcmFwVyhMUFNIRUxMRVhFQ1VURUlORk9XIGxwRXhlY0luZm8pCnsKICBHRVRfRlVOQyhwU2hlbGxFeGVjdXRlRXhXLCBzaGVsbDMyLCAiU2hlbGxFeGVjdXRlRXhXIiwgRkFMU0UpOwogIHJldHVybiBwU2hlbGxFeGVjdXRlRXhXKGxwRXhlY0luZm8pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM2XQogKgogKiBTZWUgU0hGaWxlT3BlcmF0aW9uVy4KICovCkhJQ09OIFdJTkFQSSBTSEZpbGVPcGVyYXRpb25XcmFwVyhMUFNIRklMRU9QU1RSVUNUVyBscEZpbGVPcCkKewogIEdFVF9GVU5DKHBTSEZpbGVPcGVyYXRpb25XLCBzaGVsbDMyLCAiU0hGaWxlT3BlcmF0aW9uVyIsIDApOwogIHJldHVybiBwU0hGaWxlT3BlcmF0aW9uVyhscEZpbGVPcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzddCiAqCiAqIFNlZSBFeHRyYWN0SWNvbkV4Vy4KICovClVJTlQgV0lOQVBJIEV4dHJhY3RJY29uRXhXcmFwVyhMUENXU1RSIGxwc3pGaWxlLCBJTlQgbkljb25JbmRleCwgSElDT04gKnBoaWNvbkxhcmdlLAogICAgICAgICAgICAgICAgICAgICAgICAgSElDT04gKnBoaWNvblNtYWxsLCBVSU5UIG5JY29ucykKewogIEdFVF9GVU5DKHBFeHRyYWN0SWNvbkV4Vywgc2hlbGwzMiwgIkV4dHJhY3RJY29uRXhXIiwgMCk7CiAgcmV0dXJuIHBFeHRyYWN0SWNvbkV4VyhscHN6RmlsZSwgbkljb25JbmRleCwgcGhpY29uTGFyZ2UsIHBoaWNvblNtYWxsLCBuSWNvbnMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzQyXQogKgogKi8KTE9ORyBXSU5BUEkgU0hJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZSggUExPTkcgZGVzdCwgTE9ORyB4Y2hnLCBMT05HIGNvbXBhcmUpCnsKICAgICAgICByZXR1cm4gSW50ZXJsb2NrZWRDb21wYXJlRXhjaGFuZ2UoZGVzdCwgeGNoZywgY29tcGFyZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTBdCiAqCiAqIFNlZSBHZXRGaWxlVmVyc2lvbkluZm9TaXplVy4KICovCkRXT1JEIFdJTkFQSSBHZXRGaWxlVmVyc2lvbkluZm9TaXplV3JhcFcoCglMUFdTVFIgeCwKCUxQVk9JRCB5KQp7CiAgICAgICAgRFdPUkQgcmV0OwoKCUdFVF9GVU5DKHBHZXRGaWxlVmVyc2lvbkluZm9TaXplVywgdmVyc2lvbiwgIkdldEZpbGVWZXJzaW9uSW5mb1NpemVXIiwgMCk7CglyZXQgPSBwR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVcoeCwgeSk7CglyZXR1cm4gMHgyMDggKyByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTFdCiAqCiAqIFNlZSBHZXRGaWxlVmVyc2lvbkluZm9XLgogKi8KQk9PTCAgV0lOQVBJIEdldEZpbGVWZXJzaW9uSW5mb1dyYXBXKAoJTFBXU1RSIHcsICAgLyogW2luXSBwYXRoIHRvIGRsbCAqLwoJRFdPUkQgIHgsICAgLyogW2luXSBwYXJtIDIgdG8gR2V0RmlsZVZlcnNpb25JbmZvQSAqLwoJRFdPUkQgIHksICAgLyogW2luXSByZXR1cm4gdmFsdWUgZnJvbSBTSExXQVBJXzM1MCgpIC0gYXNzdW1lIGxlbmd0aCAqLwoJTFBWT0lEIHopICAgLyogW2luL291dF0gYnVmZmVyICgrMHgyMDggc2VudCB0byBHZXRGaWxlVmVyc2lvbkluZm9BKCkpICovCnsKICAgIEdFVF9GVU5DKHBHZXRGaWxlVmVyc2lvbkluZm9XLCB2ZXJzaW9uLCAiR2V0RmlsZVZlcnNpb25JbmZvVyIsIDApOwogICAgcmV0dXJuIHBHZXRGaWxlVmVyc2lvbkluZm9XKHcsIHgsIHktMHgyMDgsIChjaGFyKil6KzB4MjA4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1Ml0KICoKICogU2VlIFZlclF1ZXJ5VmFsdWVXLgogKi8KV09SRCBXSU5BUEkgVmVyUXVlcnlWYWx1ZVdyYXBXKAoJTFBWT0lEIHcsICAgLyogW2luXSBCdWZmZXIgZnJvbSBTSExXQVBJXzM1MSgpICovCglMUFdTVFIgeCwgICAvKiBbaW5dICAgVmFsdWUgdG8gcmV0cmlldmUgLSBjb252ZXJ0ZWQgYW5kIHBhc3NlZCB0byBWZXJRdWVyeVZhbHVlQSgpIGFzICMyICovCglMUFZPSUQgeSwgICAvKiBbb3V0XSAgVmVyIGJ1ZmZlciAtIHBhc3NlZCB0byBWZXJRdWVyeVZhbHVlQSBhcyAjMyAqLwoJVUlOVCogIHopICAgLyogW2luXSAgIFZlciBsZW5ndGggLSBwYXNzZWQgdG8gVmVyUXVlcnlWYWx1ZUEgYXMgIzQgKi8KewogICAgR0VUX0ZVTkMocFZlclF1ZXJ5VmFsdWVXLCB2ZXJzaW9uLCAiVmVyUXVlcnlWYWx1ZVciLCAwKTsKICAgIHJldHVybiBwVmVyUXVlcnlWYWx1ZVcoKGNoYXIqKXcrMHgyMDgsIHgsIHksIHopOwp9CgojZGVmaW5lIElzSWZhY2UodHlwZSkgU1VDQ0VFREVEKChoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEXyMjdHlwZSwgKHZvaWQqKikmbHBPYmopKSkKI2RlZmluZSBJU2hlbGxCcm93c2VyX0VuYWJsZU1vZGVsZXNzIElTaGVsbEJyb3dzZXJfRW5hYmxlTW9kZWxlc3NTQgojZGVmaW5lIEVuYWJsZU1vZGVsZXNzKHR5cGUpIHR5cGUjI19FbmFibGVNb2RlbGVzcygodHlwZSopbHBPYmosIGJNb2RlbGVzcykKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTVdCiAqCiAqIENoYW5nZSB0aGUgbW9kYWxpdHkgb2YgYSBzaGVsbCBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gbWFrZSBtb2RlbGVzcwogKiAgYk1vZGVsZXNzIFtJXSBUUlVFPU1ha2UgbW9kZWxlc3MsIEZBTFNFPU1ha2UgbW9kYWwKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gVGhlIG1vZGFsaXR5IGxwVW5rbm93biBpcyBjaGFuZ2VkLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlIGluZGljYXRpbmcgdGhlIGVycm9yLgogKgogKiBOT1RFUwogKiAgbHBVbmtub3duIG11c3Qgc3VwcG9ydCB0aGUgSU9sZUluUGxhY2VGcmFtZSBpbnRlcmZhY2UsIHRoZQogKiAgSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlIGludGVyZmFjZSwgdGhlIElTaGVsbEJyb3dzZXIgaW50ZXJmYWNlCiAqICBvciB0aGUgSURvY0hvc3RVSUhhbmRsZXIgaW50ZXJmYWNlLCBvciB0aGlzIGNhbGwgZmFpbHMuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9FbmFibGVNb2RlbGVzcyhJVW5rbm93biAqbHBVbmtub3duLCBCT09MIGJNb2RlbGVzcykKewogIElVbmtub3duICpscE9iajsKICBIUkVTVUxUIGhSZXQ7CgogIFRSQUNFKCIoJXAsJWQpXG4iLCBscFVua25vd24sIGJNb2RlbGVzcyk7CgogIGlmICghbHBVbmtub3duKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgaWYgKElzSWZhY2UoSU9sZUluUGxhY2VGcmFtZSkpCiAgICBFbmFibGVNb2RlbGVzcyhJT2xlSW5QbGFjZUZyYW1lKTsKICBlbHNlIGlmIChJc0lmYWNlKElTaGVsbEJyb3dzZXIpKQogICAgRW5hYmxlTW9kZWxlc3MoSVNoZWxsQnJvd3Nlcik7CiNpZiAwCiAgLyogRklYTUU6IFdpbmUgaGFzIG5vIGhlYWRlcnMgZm9yIHRoZXNlIG9iamVjdHMgeWV0ICovCiAgZWxzZSBpZiAoSXNJZmFjZShJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUpKQogICAgRW5hYmxlTW9kZWxlc3MoSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlKTsKICBlbHNlIGlmIChJc0lmYWNlKElEb2NIb3N0VUlIYW5kbGVyKSkKICAgIEVuYWJsZU1vZGVsZXNzKElEb2NIb3N0VUlIYW5kbGVyKTsKI2VuZGlmCiAgZWxzZQogICAgcmV0dXJuIGhSZXQ7CgogIElVbmtub3duX1JlbGVhc2UobHBPYmopOwogIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzU3XQogKgogKiBTZWUgU0hHZXROZXdMaW5rSW5mb1cuCiAqLwpCT09MIFdJTkFQSSBTSEdldE5ld0xpbmtJbmZvV3JhcFcoTFBDV1NUUiBwc3pMaW5rVG8sIExQQ1dTVFIgcHN6RGlyLCBMUFdTVFIgcHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCAqcGZNdXN0Q29weSwgVUlOVCB1RmxhZ3MpCnsKICBHRVRfRlVOQyhwU0hHZXROZXdMaW5rSW5mb1csIHNoZWxsMzIsICJTSEdldE5ld0xpbmtJbmZvVyIsIEZBTFNFKTsKICByZXR1cm4gcFNIR2V0TmV3TGlua0luZm9XKHBzekxpbmtUbywgcHN6RGlyLCBwc3pOYW1lLCBwZk11c3RDb3B5LCB1RmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzU4XQogKgogKiBTZWUgU0hEZWZFeHRyYWN0SWNvblcuCiAqLwpVSU5UIFdJTkFQSSBTSERlZkV4dHJhY3RJY29uV3JhcFcoTFBDV1NUUiBwc3pJY29uRmlsZSwgaW50IGlJbmRleCwgVUlOVCB1RmxhZ3MsIEhJQ09OKiBwaGljb25MYXJnZSwKICAgICAgICAgICAgICAgICAgICAgICAgIEhJQ09OKiBwaGljb25TbWFsbCwgVUlOVCBuSWNvblNpemUpCnsKICBHRVRfRlVOQyhwU0hEZWZFeHRyYWN0SWNvblcsIHNoZWxsMzIsICJTSERlZkV4dHJhY3RJY29uVyIsIDApOwogIHJldHVybiBwU0hEZWZFeHRyYWN0SWNvblcocHN6SWNvbkZpbGUsIGlJbmRleCwgdUZsYWdzLCBwaGljb25MYXJnZSwgcGhpY29uU21hbGwsIG5JY29uU2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNjNdCiAqCiAqIEdldCBhbmQgc2hvdyBhIGNvbnRleHQgbWVudSBmcm9tIGEgc2hlbGwgZm9sZGVyLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgICAgIFtJXSBXaW5kb3cgZGlzcGxheWluZyB0aGUgc2hlbGwgZm9sZGVyCiAqICBscEZvbGRlciAgICAgICBbSV0gSVNoZWxsRm9sZGVyIGludGVyZmFjZQogKiAgbHBBcGlkbCAgICAgICAgW0ldIElkIGZvciB0aGUgcGFydGljdWxhciBmb2xkZXIgZGVzaXJlZAogKiAgYkludm9rZURlZmF1bHQgW0ldIFdoZXRoZXIgdG8gaW52b2tlIHRoZSBkZWZhdWx0IG1lbnUgaXRlbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBJZiBiSW52b2tlRGVmYXVsdCBpcyBUUlVFLCB0aGUgZGVmYXVsdCBtZW51IGFjdGlvbiB3YXMKICogICAgICAgICAgIGV4ZWN1dGVkLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlIGluZGljYXRpbmcgdGhlIGVycm9yLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hJbnZva2VDb21tYW5kKEhXTkQgaFduZCwgSVNoZWxsRm9sZGVyKiBscEZvbGRlciwgTFBDSVRFTUlETElTVCBscEFwaWRsLCBCT09MIGJJbnZva2VEZWZhdWx0KQp7CiAgSUNvbnRleHRNZW51ICppQ29udGV4dDsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXAsJXAsJWQpXG4iLCBoV25kLCBscEZvbGRlciwgbHBBcGlkbCwgYkludm9rZURlZmF1bHQpOwoKICBpZiAoIWxwRm9sZGVyKQogICAgcmV0dXJuIGhSZXQ7CgogIC8qIEdldCB0aGUgY29udGV4dCBtZW51IGZyb20gdGhlIHNoZWxsIGZvbGRlciAqLwogIGhSZXQgPSBJU2hlbGxGb2xkZXJfR2V0VUlPYmplY3RPZihscEZvbGRlciwgaFduZCwgMSwgJmxwQXBpZGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZJSURfSUNvbnRleHRNZW51LCAwLCAodm9pZCoqKSZpQ29udGV4dCk7CiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICBITUVOVSBoTWVudTsKICAgIGlmICgoaE1lbnUgPSBDcmVhdGVQb3B1cE1lbnUoKSkpCiAgICB7CiAgICAgIEhSRVNVTFQgaFF1ZXJ5OwogICAgICBEV09SRCBkd0RlZmF1bHRJZCA9IDA7CgogICAgICAvKiBBZGQgdGhlIGNvbnRleHQgbWVudSBlbnRyaWVzIHRvIHRoZSBwb3B1cCAqLwogICAgICBoUXVlcnkgPSBJQ29udGV4dE1lbnVfUXVlcnlDb250ZXh0TWVudShpQ29udGV4dCwgaE1lbnUsIDAsIDEsIDB4N0ZGRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkludm9rZURlZmF1bHQgPyBDTUZfTk9STUFMIDogQ01GX0RFRkFVTFRPTkxZKTsKCiAgICAgIGlmIChTVUNDRUVERUQoaFF1ZXJ5KSkKICAgICAgewogICAgICAgIGlmIChiSW52b2tlRGVmYXVsdCAmJgogICAgICAgICAgICAoZHdEZWZhdWx0SWQgPSBHZXRNZW51RGVmYXVsdEl0ZW0oaE1lbnUsIDAsIDApKSAhPSAweEZGRkZGRkZGKQogICAgICAgIHsKICAgICAgICAgIENNSU5WT0tFQ09NTUFORElORk8gY21JY2k7CiAgICAgICAgICAvKiBJbnZva2UgdGhlIGRlZmF1bHQgaXRlbSAqLwogICAgICAgICAgbWVtc2V0KCZjbUljaSwwLHNpemVvZihjbUljaSkpOwogICAgICAgICAgY21JY2kuY2JTaXplID0gc2l6ZW9mKGNtSWNpKTsKICAgICAgICAgIGNtSWNpLmZNYXNrID0gQ01JQ19NQVNLX0FTWU5DT0s7CiAgICAgICAgICBjbUljaS5od25kID0gaFduZDsKICAgICAgICAgIGNtSWNpLmxwVmVyYiA9IE1BS0VJTlRSRVNPVVJDRUEoZHdEZWZhdWx0SWQpOwogICAgICAgICAgY21JY2kublNob3cgPSBTV19TQ1JPTExDSElMRFJFTjsKCiAgICAgICAgICBoUmV0ID0gSUNvbnRleHRNZW51X0ludm9rZUNvbW1hbmQoaUNvbnRleHQsICZjbUljaSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIERlc3Ryb3lNZW51KGhNZW51KTsKICAgIH0KICAgIElDb250ZXh0TWVudV9SZWxlYXNlKGlDb250ZXh0KTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNzBdCiAqCiAqIFNlZSBFeHRyYWN0SWNvblcuCiAqLwpISUNPTiBXSU5BUEkgRXh0cmFjdEljb25XcmFwVyhISU5TVEFOQ0UgaEluc3RhbmNlLCBMUENXU1RSIGxwc3pFeGVGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgbkljb25JbmRleCkKewogIEdFVF9GVU5DKHBFeHRyYWN0SWNvblcsIHNoZWxsMzIsICJFeHRyYWN0SWNvblciLCBOVUxMKTsKICByZXR1cm4gcEV4dHJhY3RJY29uVyhoSW5zdGFuY2UsIGxwc3pFeGVGaWxlTmFtZSwgbkljb25JbmRleCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNzZdCiAqLwpMQU5HSUQgV0lOQVBJIE1MR2V0VUlMYW5ndWFnZSgpCnsKICAgIEZJWE1FKCIoKSBzdHViXG4iKTsKICAgIC8qIEZJWE1FOiBUaGlzIHNob3VsZCBiZSBhIGZvcndhcmQgaW4gdGhlIC5zcGVjIGZpbGUgdG8gdGhlIHdpbjJrIGZ1bmN0aW9uCiAgICAgKiBrZXJuZWwzMi5HZXRVc2VyRGVmYXVsdFVJTGFuZ3VhZ2UsIGhvd2V2ZXIgdGhhdCBmdW5jdGlvbiBpc24ndCB0aGVyZSB5ZXQuCiAgICAgKi8KICAgIHJldHVybiBHZXRVc2VyRGVmYXVsdExhbmdJRCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzc3XQogKgogKiBMb2FkIGEgbGlicmFyeSBmcm9tIHRoZSBkaXJlY3Rvcnkgb2YgYSBwYXJ0aWN1bGFyIHByb2Nlc3MuCiAqCiAqIFBBUkFNUwogKiAgbmV3X21vZCAgIFtJXSBMaWJyYXJ5IG5hbWUKICogIGluc3RfaHduZCBbSV0gTW9kdWxlIHdob3NlIGRpcmVjdG9yeSBpcyB0byBiZSB1c2VkCiAqICBkd0ZsYWdzICAgW0ldIEZsYWdzIGNvbnRyb2xsaW5nIHRoZSBsb2FkCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgbW9kdWxlCiAqICBGYWlsdXJlOiBBIE5VTEwgaGFuZGxlLgogKi8KSE1PRFVMRSBXSU5BUEkgTUxMb2FkTGlicmFyeUEoTFBDU1RSIG5ld19tb2QsIEhNT0RVTEUgaW5zdF9od25kLCBEV09SRCBkd0ZsYWdzKQp7CiAgLyogRklYTUU6IE5hdGl2ZSBhcHBlYXJzIHRvIGRvIERQQV9DcmVhdGUgYW5kIGEgRFBBX0luc2VydFB0ciBmb3IKICAgKiAgICAgICAgZWFjaCBjYWxsIGhlcmUuCiAgICogRklYTUU6IE5hdGl2ZSBzaG93cyBjYWxscyB0bzoKICAgKiAgU0hSZWdHZXRVU1ZhbHVlIGZvciAiU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVybmF0aW9uYWwiCiAgICogICAgICAgICAgICAgICAgICAgICAgQ2hlY2tWZXJzaW9uCiAgICogIFJlZ09wZW5LZXlFeEEgZm9yICJIS0xNXFNvZnR3YXJlXE1pY3Jvc29mdFxJbnRlcm5ldCBFeHBsb3JlciIKICAgKiAgUmVnUXVlcnlWYWx1ZUV4QSBmb3IgIkxQS0luc3RhbGxlZCIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLQ1VcU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVybmF0aW9uYWwiCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJSZXNvdXJjZUxvY2FsZSIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLTE1cU29mdHdhcmVcTWljcm9zb2Z0XEFjdGl2ZSBTZXR1cFxJbnN0YWxsZWQgQ29tcG9uZW50c1x7Z3VpZH0iCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJMb2NhbGUiCiAgICogIFJlZ0Nsb3NlS2V5CiAgICogIGFuZCB0aGVuIHRlc3RzIHRoZSBMb2NhbGUgKCJlbiIgZm9yIG1lKS4KICAgKiAgICAgY29kZSBiZWxvdwogICAqICBhZnRlciB0aGUgY29kZSB0aGVuIGEgRFBBX0NyZWF0ZSAoZmlyc3QgdGltZSkgYW5kIERQQV9JbnNlcnRQdHIgYXJlIGRvbmUuCiAgICovCiAgICBDSEFSIG1vZF9wYXRoWzIqTUFYX1BBVEhdOwogICAgTFBTVFIgcHRyOwogICAgRFdPUkQgbGVuOwoKICAgIEZJWE1FKCIoJXMsJXAsMHglMDhseCkgc2VtaS1zdHViIVxuIiwgZGVidWdzdHJfYShuZXdfbW9kKSwgaW5zdF9od25kLCBkd0ZsYWdzKTsKICAgIGxlbiA9IEdldE1vZHVsZUZpbGVOYW1lQShpbnN0X2h3bmQsIG1vZF9wYXRoLCBzaXplb2YobW9kX3BhdGgpKTsKICAgIGlmICghbGVuIHx8IGxlbiA+PSBzaXplb2YobW9kX3BhdGgpKSByZXR1cm4gTlVMTDsKCiAgICBwdHIgPSBzdHJyY2hyKG1vZF9wYXRoLCAnXFwnKTsKICAgIGlmIChwdHIpIHsKCXN0cmNweShwdHIrMSwgbmV3X21vZCk7CglUUkFDRSgibG9hZGluZyAlc1xuIiwgZGVidWdzdHJfYShtb2RfcGF0aCkpOwoJcmV0dXJuIExvYWRMaWJyYXJ5QShtb2RfcGF0aCk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIE1MTG9hZExpYnJhcnlBLgogKi8KSE1PRFVMRSBXSU5BUEkgTUxMb2FkTGlicmFyeVcoTFBDV1NUUiBuZXdfbW9kLCBITU9EVUxFIGluc3RfaHduZCwgRFdPUkQgZHdGbGFncykKewogICAgV0NIQVIgbW9kX3BhdGhbMipNQVhfUEFUSF07CiAgICBMUFdTVFIgcHRyOwogICAgRFdPUkQgbGVuOwoKICAgIEZJWE1FKCIoJXMsJXAsMHglMDhseCkgc2VtaS1zdHViIVxuIiwgZGVidWdzdHJfdyhuZXdfbW9kKSwgaW5zdF9od25kLCBkd0ZsYWdzKTsKICAgIGxlbiA9IEdldE1vZHVsZUZpbGVOYW1lVyhpbnN0X2h3bmQsIG1vZF9wYXRoLCBzaXplb2YobW9kX3BhdGgpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoIWxlbiB8fCBsZW4gPj0gc2l6ZW9mKG1vZF9wYXRoKSAvIHNpemVvZihXQ0hBUikpIHJldHVybiBOVUxMOwoKICAgIHB0ciA9IHN0cnJjaHJXKG1vZF9wYXRoLCAnXFwnKTsKICAgIGlmIChwdHIpIHsKCXN0cmNweVcocHRyKzEsIG5ld19tb2QpOwoJVFJBQ0UoImxvYWRpbmcgJXNcbiIsIGRlYnVnc3RyX3cobW9kX3BhdGgpKTsKCXJldHVybiBMb2FkTGlicmFyeVcobW9kX3BhdGgpOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENvbG9yQWRqdXN0THVtYSAgICAgIFtTSExXQVBJLkBdCiAqCiAqIEFkanVzdCB0aGUgbHVtaW5vc2l0eSBvZiBhIGNvbG9yCiAqCiAqIFBBUkFNUwogKiAgY1JHQiAgICAgICAgIFtJXSBSR0IgdmFsdWUgdG8gY29udmVydAogKiAgZHdMdW1hICAgICAgIFtJXSBMdW1hIGFkanVzdG1lbnQKICogIGJVbmtub3duICAgICBbSV0gVW5rbm93bgogKgogKiBSRVRVUk5TCiAqICBUaGUgYWRqdXN0ZWQgUkdCIGNvbG9yLgogKi8KQ09MT1JSRUYgV0lOQVBJIENvbG9yQWRqdXN0THVtYShDT0xPUlJFRiBjUkdCLCBpbnQgZHdMdW1hLCBCT09MIGJVbmtub3duKQp7CiAgVFJBQ0UoIigweCU4bHgsJWQsJWQpXG4iLCBjUkdCLCBkd0x1bWEsIGJVbmtub3duKTsKCiAgaWYgKGR3THVtYSkKICB7CiAgICBXT1JEIHdILCB3TCwgd1M7CgogICAgQ29sb3JSR0JUb0hMUyhjUkdCLCAmd0gsICZ3TCwgJndTKTsKCiAgICBGSVhNRSgiSWdub3JpbmcgbHVtYSBhZGp1c3RtZW50XG4iKTsKCiAgICAvKiBGSVhNRTogVGhlIGFqZHVzdG1lbnQgaXMgbm90IGxpbmVhciAqLwoKICAgIGNSR0IgPSBDb2xvckhMU1RvUkdCKHdILCB3TCwgd1MpOwogIH0KICByZXR1cm4gY1JHQjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM4OV0KICoKICogU2VlIEdldFNhdmVGaWxlTmFtZVcuCiAqLwpCT09MIFdJTkFQSSBHZXRTYXZlRmlsZU5hbWVXcmFwVyhMUE9QRU5GSUxFTkFNRVcgb2ZuKQp7CiAgR0VUX0ZVTkMocEdldFNhdmVGaWxlTmFtZVcsIGNvbWRsZzMyLCAiR2V0U2F2ZUZpbGVOYW1lVyIsIEZBTFNFKTsKICByZXR1cm4gcEdldFNhdmVGaWxlTmFtZVcob2ZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM5MF0KICoKICogU2VlIFdOZXRSZXN0b3JlQ29ubmVjdGlvblcuCiAqLwpEV09SRCBXSU5BUEkgV05ldFJlc3RvcmVDb25uZWN0aW9uV3JhcFcoSFdORCBod25kT3duZXIsIExQV1NUUiBscHN6RGV2aWNlKQp7CiAgR0VUX0ZVTkMocFdOZXRSZXN0b3JlQ29ubmVjdGlvblcsIG1wciwgIldOZXRSZXN0b3JlQ29ubmVjdGlvblciLCAwKTsKICByZXR1cm4gcFdOZXRSZXN0b3JlQ29ubmVjdGlvblcoaHduZE93bmVyLCBscHN6RGV2aWNlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM5MV0KICoKICogU2VlIFdOZXRHZXRMYXN0RXJyb3JXLgogKi8KRFdPUkQgV0lOQVBJIFdOZXRHZXRMYXN0RXJyb3JXcmFwVyhMUERXT1JEIGxwRXJyb3IsIExQV1NUUiBscEVycm9yQnVmLCBEV09SRCBuRXJyb3JCdWZTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGxwTmFtZUJ1ZiwgRFdPUkQgbk5hbWVCdWZTaXplKQp7CiAgR0VUX0ZVTkMocFdOZXRHZXRMYXN0RXJyb3JXLCBtcHIsICJXTmV0R2V0TGFzdEVycm9yVyIsIDApOwogIHJldHVybiBwV05ldEdldExhc3RFcnJvclcobHBFcnJvciwgbHBFcnJvckJ1ZiwgbkVycm9yQnVmU2l6ZSwgbHBOYW1lQnVmLCBuTmFtZUJ1ZlNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDAxXQogKgogKiBTZWUgUGFnZVNldHVwRGxnVy4KICovCkJPT0wgV0lOQVBJIFBhZ2VTZXR1cERsZ1dyYXBXKExQUEFHRVNFVFVQRExHVyBwYWdlZGxnKQp7CiAgR0VUX0ZVTkMocFBhZ2VTZXR1cERsZ1csIGNvbWRsZzMyLCAiUGFnZVNldHVwRGxnVyIsIEZBTFNFKTsKICByZXR1cm4gcFBhZ2VTZXR1cERsZ1cocGFnZWRsZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDJdCiAqCiAqIFNlZSBQcmludERsZ1cuCiAqLwpCT09MIFdJTkFQSSBQcmludERsZ1dyYXBXKExQUFJJTlRETEdXIHByaW50ZGxnKQp7CiAgR0VUX0ZVTkMocFByaW50RGxnVywgY29tZGxnMzIsICJQcmludERsZ1ciLCBGQUxTRSk7CiAgcmV0dXJuIHBQcmludERsZ1cocHJpbnRkbGcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDAzXQogKgogKiBTZWUgR2V0T3BlbkZpbGVOYW1lVy4KICovCkJPT0wgV0lOQVBJIEdldE9wZW5GaWxlTmFtZVdyYXBXKExQT1BFTkZJTEVOQU1FVyBvZm4pCnsKICBHRVRfRlVOQyhwR2V0T3BlbkZpbGVOYW1lVywgY29tZGxnMzIsICJHZXRPcGVuRmlsZU5hbWVXIiwgRkFMU0UpOwogIHJldHVybiBwR2V0T3BlbkZpbGVOYW1lVyhvZm4pOwp9CgovKiBJTlRFUk5BTDogTWFwIGZyb20gSExTIGNvbG9yIHNwYWNlIHRvIFJHQiAqLwpzdGF0aWMgV09SRCBXSU5BUEkgQ29udmVydEh1ZShpbnQgd0h1ZSwgV09SRCB3TWlkMSwgV09SRCB3TWlkMikKewogIHdIdWUgPSB3SHVlID4gMjQwID8gd0h1ZSAtIDI0MCA6IHdIdWUgPCAwID8gd0h1ZSArIDI0MCA6IHdIdWU7CgogIGlmICh3SHVlID4gMTYwKQogICAgcmV0dXJuIHdNaWQxOwogIGVsc2UgaWYgKHdIdWUgPiAxMjApCiAgICB3SHVlID0gMTYwIC0gd0h1ZTsKICBlbHNlIGlmICh3SHVlID4gNDApCiAgICByZXR1cm4gd01pZDI7CgogIHJldHVybiAoKHdIdWUgKiAod01pZDIgLSB3TWlkMSkgKyAyMCkgLyA0MCkgKyB3TWlkMTsKfQoKLyogQ29udmVydCB0byBSR0IgYW5kIHNjYWxlIGludG8gUkdCIHJhbmdlICgwLi4yNTUpICovCiNkZWZpbmUgR0VUX1JHQihoKSAoQ29udmVydEh1ZShoLCB3TWlkMSwgd01pZDIpICogMjU1ICsgMTIwKSAvIDI0MAoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBDb2xvckhMU1RvUkdCCVtTSExXQVBJLkBdCiAqCiAqIENvbnZlcnQgZnJvbSBobHMgY29sb3Igc3BhY2UgaW50byBhbiByZ2IgQ09MT1JSRUYuCiAqCiAqIFBBUkFNUwogKiAgd0h1ZSAgICAgICAgW0ldIEh1ZSBhbW91bnQKICogIHdMdW1pbm9zaXR5IFtJXSBMdW1pbm9zaXR5IGFtb3VudAogKiAgd1NhdHVyYXRpb24gW0ldIFNhdHVyYXRpb24gYW1vdW50CiAqCiAqIFJFVFVSTlMKICogIEEgQ09MT1JSRUYgcmVwcmVzZW50aW5nIHRoZSBjb252ZXJ0ZWQgY29sb3IuCiAqCiAqIE5PVEVTCiAqICBJbnB1dCBobHMgdmFsdWVzIGFyZSBjb25zdHJhaW5lZCB0byB0aGUgcmFuZ2UgKDAuLjI0MCkuCiAqLwpDT0xPUlJFRiBXSU5BUEkgQ29sb3JITFNUb1JHQihXT1JEIHdIdWUsIFdPUkQgd0x1bWlub3NpdHksIFdPUkQgd1NhdHVyYXRpb24pCnsKICBXT1JEIHdSZWQ7CgogIGlmICh3U2F0dXJhdGlvbikKICB7CiAgICBXT1JEIHdHcmVlbiwgd0JsdWUsIHdNaWQxLCB3TWlkMjsKCiAgICBpZiAod0x1bWlub3NpdHkgPiAxMjApCiAgICAgIHdNaWQyID0gd1NhdHVyYXRpb24gKyB3THVtaW5vc2l0eSAtICh3U2F0dXJhdGlvbiAqIHdMdW1pbm9zaXR5ICsgMTIwKSAvIDI0MDsKICAgIGVsc2UKICAgICAgd01pZDIgPSAoKHdTYXR1cmF0aW9uICsgMjQwKSAqIHdMdW1pbm9zaXR5ICsgMTIwKSAvIDI0MDsKCiAgICB3TWlkMSA9IHdMdW1pbm9zaXR5ICogMiAtIHdNaWQyOwoKICAgIHdSZWQgICA9IEdFVF9SR0Iod0h1ZSArIDgwKTsKICAgIHdHcmVlbiA9IEdFVF9SR0Iod0h1ZSk7CiAgICB3Qmx1ZSAgPSBHRVRfUkdCKHdIdWUgLSA4MCk7CgogICAgcmV0dXJuIFJHQih3UmVkLCB3R3JlZW4sIHdCbHVlKTsKICB9CgogIHdSZWQgPSB3THVtaW5vc2l0eSAqIDI1NSAvIDI0MDsKICByZXR1cm4gUkdCKHdSZWQsIHdSZWQsIHdSZWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDEzXQogKgogKiBHZXQgdGhlIGN1cnJlbnQgZG9ja2luZyBzdGF0dXMgb2YgdGhlIHN5c3RlbS4KICoKICogUEFSQU1TCiAqICBkd0ZsYWdzIFtJXSBET0NLSU5GT18gZmxhZ3MgZnJvbSAid2luYmFzZS5oIiwgdW51c2VkCiAqCiAqIFJFVFVSTlMKICogIE9uZSBvZiBET0NLSU5GT19VTkRPQ0tFRCwgRE9DS0lORk9fVU5ET0NLRUQsIG9yIDAgaWYgdGhlIHN5c3RlbSBpcyBub3QKICogIGEgbm90ZWJvb2suCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRNYWNoaW5lSW5mbyhEV09SRCBkd0ZsYWdzKQp7CiAgSFdfUFJPRklMRV9JTkZPQSBod0luZm87CgogIFRSQUNFKCIoMHglMDhseClcbiIsIGR3RmxhZ3MpOwoKICBHZXRDdXJyZW50SHdQcm9maWxlQSgmaHdJbmZvKTsKICBzd2l0Y2ggKGh3SW5mby5kd0RvY2tJbmZvICYgKERPQ0tJTkZPX0RPQ0tFRHxET0NLSU5GT19VTkRPQ0tFRCkpCiAgewogIGNhc2UgRE9DS0lORk9fRE9DS0VEOgogIGNhc2UgRE9DS0lORk9fVU5ET0NLRUQ6CiAgICByZXR1cm4gaHdJbmZvLmR3RG9ja0luZm8gJiAoRE9DS0lORk9fRE9DS0VEfERPQ0tJTkZPX1VORE9DS0VEKTsKICBkZWZhdWx0OgogICAgcmV0dXJuIDA7CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDE4XQogKgogKiBGdW5jdGlvbiBzZWVtcyB0byBkbyBGcmVlTGlicmFyeSBwbHVzIG90aGVyIHRoaW5ncy4KICoKICogRklYTUUgbmF0aXZlIHNob3dzIHRoZSBmb2xsb3dpbmcgY2FsbHM6CiAqICAgUnRsRW50ZXJDcml0aWNhbFNlY3Rpb24KICogICBMb2NhbEZyZWUKICogICBHZXRQcm9jQWRkcmVzcyhDb21jdGwzMj8/LCAxNTBMKQogKiAgIERQQV9EZWxldGVQdHIKICogICBSdGxMZWF2ZUNyaXRpY2FsU2VjdGlvbgogKiAgZm9sbG93ZWQgYnkgdGhlIEZyZWVMaWJyYXJ5LgogKiAgVGhlIGFib3ZlIGNvZGUgbWF5IGJlIHJlbGF0ZWQgdG8gLjM3NyBhYm92ZS4KICovCkJPT0wgV0lOQVBJIE1MRnJlZUxpYnJhcnkoSE1PRFVMRSBoTW9kdWxlKQp7CglGSVhNRSgiKCVwKSBzZW1pLXN0dWJcbiIsIGhNb2R1bGUpOwoJcmV0dXJuIEZyZWVMaWJyYXJ5KGhNb2R1bGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDE5XQogKi8KQk9PTCBXSU5BUEkgU0hGbHVzaFNGQ2FjaGVXcmFwKHZvaWQpIHsKICBGSVhNRSgiOiBzdHViXG4iKTsKICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgW1NITFdBUEkuNDI5XQogKiBGSVhNRSBJIGhhdmUgbm8gaWRlYSB3aGF0IHRoaXMgZnVuY3Rpb24gZG9lcyBvciB3aGF0IGl0cyBhcmd1bWVudHMgYXJlLgogKi8KQk9PTCBXSU5BUEkgTUxJc01MSEluc3RhbmNlKEhJTlNUQU5DRSBoSW5zdCkKewogICAgICAgRklYTUUoIiglcCkgc3R1YlxuIiwgaEluc3QpOwogICAgICAgcmV0dXJuIEZBTFNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzMF0KICovCkRXT1JEIFdJTkFQSSBNTFNldE1MSEluc3RhbmNlKEhJTlNUQU5DRSBoSW5zdCwgSEFORExFIGhIZWFwKQp7CglGSVhNRSgiKCVwLCVwKSBzdHViXG4iLCBoSW5zdCwgaEhlYXApOwoJcmV0dXJuIEVfRkFJTDsgICAvKiBUaGlzIGlzIHdoYXQgaXMgdXNlZCBpZiBzaGx3YXBpIG5vdCBsb2FkZWQgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzMV0KICovCkRXT1JEIFdJTkFQSSBNTENsZWFyTUxISW5zdGFuY2UoRFdPUkQgeCkKewoJRklYTUUoIigweCUwOGx4KXN0dWJcbiIsIHgpOwoJcmV0dXJuIDB4YWJiYTEyNDc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MzZdCiAqCiAqIENvbnZlcnQgYW4gVW5pY29kZSBzdHJpbmcgQ0xTSUQgaW50byBhIENMU0lELgogKgogKiBQQVJBTVMKICogIGlkc3RyICAgICAgW0ldICAgc3RyaW5nIGNvbnRhaW5pbmcgYSBDTFNJRCBpbiB0ZXh0IGZvcm0KICogIGlkICAgICAgICAgW09dICAgQ0xTSUQgZXh0cmFjdGVkIGZyb20gdGhlIHN0cmluZwogKgogKiBSRVRVUk5TCiAqICBTX09LIG9uIHN1Y2Nlc3Mgb3IgRV9JTlZBTElEQVJHIG9uIGZhaWx1cmUKICoKICogTk9URVMKICogIFRoaXMgaXMgcmVhbGx5IENMU0lERnJvbVN0cmluZygpIHdoaWNoIGlzIGV4cG9ydGVkIGJ5IG9sZTMyLmRsbCwKICogIGhvd2V2ZXIgdGhlIG5hdGl2ZSBzaGx3YXBpLmRsbCBkb2VzICpub3QqIGltcG9ydCBvbGUzMi4gTm9yIGRvZXMKICogIG9sZTMyLmRsbCBpbXBvcnQgdGhpcyBvcmRpbmFsIGZyb20gc2hsd2FwaS4gVGhlcmVmb3JlIHdlIG11c3QgY29uY2x1ZGUKICogIHRoYXQgTVMgZHVwbGljYXRlZCB0aGUgY29kZSBmb3IgQ0xTSURGcm9tU3RyaW5nKCksIGFuZCB5ZXMgdGhleSBkaWQsIG9ubHkKICogIGl0IHJldHVybnMgYW4gRV9JTlZBTElEQVJHIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICogIFRoaXMgaXMgYSBkdXBsaWNhdGUgKHdpdGggY2hhbmdlcyBmb3IgVW5pY29kZSkgb2YgQ0xTSURGcm9tU3RyaW5nMTYoKQogKiAgaW4gImRsbHMvb2xlMzIvY29tcG9iai5jIi4KICovCkhSRVNVTFQgV0lOQVBJIENMU0lERnJvbVN0cmluZ1dyYXAoTFBDV1NUUiBpZHN0ciwgQ0xTSUQgKmlkKQp7CglMUENXU1RSIHMgPSBpZHN0cjsKCUJZVEUgKnA7CglJTlQgaTsKCVdDSEFSIHRhYmxlWzI1Nl07CgoJaWYgKCFzKSB7CgkgIG1lbXNldChpZCwgMCwgc2l6ZW9mKENMU0lEKSk7CgkgIHJldHVybiBTX09LOwoJfQoJZWxzZSB7ICAvKiB2YWxpZGF0ZSB0aGUgQ0xTSUQgc3RyaW5nICovCgoJICBpZiAoc3RybGVuVyhzKSAhPSAzOCkKCSAgICByZXR1cm4gRV9JTlZBTElEQVJHOwoKCSAgaWYgKChzWzBdIT1MJ3snKSB8fCAoc1s5XSE9TCctJykgfHwgKHNbMTRdIT1MJy0nKSB8fCAoc1sxOV0hPUwnLScpIHx8IChzWzI0XSE9TCctJykgfHwgKHNbMzddIT1MJ30nKSkKCSAgICByZXR1cm4gRV9JTlZBTElEQVJHOwoKCSAgZm9yIChpPTE7IGk8Mzc7IGkrKykKCSAgewoJICAgIGlmICgoaSA9PSA5KXx8KGkgPT0gMTQpfHwoaSA9PSAxOSl8fChpID09IDI0KSkKCSAgICAgIGNvbnRpbnVlOwoJICAgIGlmICghKCgoc1tpXSA+PSBMJzAnKSAmJiAoc1tpXSA8PSBMJzknKSkgIHx8CgkgICAgICAgICgoc1tpXSA+PSBMJ2EnKSAmJiAoc1tpXSA8PSBMJ2YnKSkgIHx8CgkgICAgICAgICgoc1tpXSA+PSBMJ0EnKSAmJiAoc1tpXSA8PSBMJ0YnKSkpCgkgICAgICAgKQoJICAgICAgcmV0dXJuIEVfSU5WQUxJREFSRzsKCSAgfQoJfQoKICAgIFRSQUNFKCIlcyAtPiAlcFxuIiwgZGVidWdzdHJfdyhzKSwgaWQpOwoKICAvKiBxdWljayBsb29rdXAgdGFibGUgKi8KICAgIG1lbXNldCh0YWJsZSwgMCwgMjU2KnNpemVvZihXQ0hBUikpOwoKICAgIGZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB7Cgl0YWJsZVsnMCcgKyBpXSA9IGk7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7Cgl0YWJsZVsnQScgKyBpXSA9IGkrMTA7Cgl0YWJsZVsnYScgKyBpXSA9IGkrMTA7CiAgICB9CgogICAgLyogaW4gZm9ybSB7WFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYfSAqLwoKICAgIHAgPSAoQllURSAqKSBpZDsKCiAgICBzKys7CS8qIHNraXAgbGVhZGluZyBicmFjZSAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHsKCXBbMyAtIGldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gNDsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gMjsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gMjsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgLyogdGhlc2UgYXJlIGp1c3Qgc2VxdWVudGlhbCBieXRlcyAqLwogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJKnArKyA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CglzICs9IDI7CiAgICB9CiAgICBzKys7CS8qIHNraXAgLSAqLwoKICAgIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKCSpwKysgPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwoJcyArPSAyOwogICAgfQoKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDM3XQogKgogKiBEZXRlcm1pbmUgaWYgdGhlIE9TIHN1cHBvcnRzIGEgZ2l2ZW4gZmVhdHVyZS4KICoKICogUEFSQU1TCiAqICBkd0ZlYXR1cmUgW0ldIEZlYXR1cmUgcmVxdWVzdGVkICh1bmRvY3VtZW50ZWQpCiAqCiAqIFJFVFVSTlMKICogIFRSVUUgIElmIHRoZSBmZWF0dXJlIGlzIGF2YWlsYWJsZS4KICogIEZBTFNFIElmIHRoZSBmZWF0dXJlIGlzIG5vdCBhdmFpbGFibGUuCiAqLwpCT09MIFdJTkFQSSBJc09TKERXT1JEIGZlYXR1cmUpCnsKICAgIE9TVkVSU0lPTklORk9BIG9zdmk7CiAgICBEV09SRCBwbGF0Zm9ybSwgbWFqb3J2LCBtaW5vcnY7CgogICAgb3N2aS5kd09TVmVyc2lvbkluZm9TaXplID0gc2l6ZW9mKE9TVkVSU0lPTklORk9BKTsKICAgIGlmKCFHZXRWZXJzaW9uRXhBKCZvc3ZpKSkgIHsKICAgICAgICBFUlIoIkdldFZlcnNpb25FeCBmYWlsZWQiKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbWFqb3J2ID0gb3N2aS5kd01ham9yVmVyc2lvbjsKICAgIG1pbm9ydiA9IG9zdmkuZHdNaW5vclZlcnNpb247CiAgICBwbGF0Zm9ybSA9IG9zdmkuZHdQbGF0Zm9ybUlkOwoKI2RlZmluZSBJU09TX1JFVFVSTih4KSBcCiAgICBUUkFDRSgiKDB4JWx4KSByZXQ9JWRcbiIsZmVhdHVyZSwoeCkpOyBcCiAgICByZXR1cm4gKHgpOwoKICAgIHN3aXRjaChmZWF0dXJlKSAgewogICAgY2FzZSBPU19XSU4zMlNPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMycwogICAgICAgICAgICAgICAgIHx8IHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTKQogICAgY2FzZSBPU19OVDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1dJTjk1T1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTKQogICAgY2FzZSBPU19OVDRPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA0KQogICAgY2FzZSBPU19XSU4yMDAwT1JHUkVBVEVSX0FMVDoKICAgIGNhc2UgT1NfV0lOMjAwME9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUpCiAgICBjYXNlIE9TX1dJTjk4T1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTICYmIG1pbm9ydiA+PSAxMCkKICAgIGNhc2UgT1NfV0lOOThfR09MRDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPT0gMTApCiAgICBjYXNlIE9TX1dJTjIwMDBQUk86CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA1KQogICAgY2FzZSBPU19XSU4yMDAwU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwQURWU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwREFUQUNFTlRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgKG1pbm9ydiA9PSAwIHx8IG1pbm9ydiA9PSAxKSkKICAgIGNhc2UgT1NfV0lOMjAwMFRFUk1JTkFMOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19FTUJFRERFRDoKICAgICAgICBGSVhNRSgiKE9TX0VNQkVEREVEKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfVEVSTUlOQUxDTElFTlQ6CiAgICAgICAgRklYTUUoIihPU19URVJNSU5BTENMSUVOVCkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX1RFUk1JTkFMUkVNT1RFQURNSU46CiAgICAgICAgRklYTUUoIihPU19URVJNSU5BTFJFTU9URUFETUlOKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfV0lOOTVfR09MRDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPT0gMCkKICAgIGNhc2UgT1NfTUVPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MgJiYgbWlub3J2ID49IDkwKQogICAgY2FzZSBPU19YUE9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUgJiYgbWlub3J2ID49IDEpCiAgICBjYXNlIE9TX0hPTUU6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA1ICYmIG1pbm9ydiA+PSAxKQogICAgY2FzZSBPU19QUk9GRVNTSU9OQUw6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKSAKICAgIGNhc2UgT1NfREFUQUNFTlRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX0FEVlNFUlZFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUpCiAgICBjYXNlIE9TX1NFUlZFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1RFUk1JTkFMU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfUEVSU09OQUxURVJNSU5BTFNFUlZFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWlub3J2ID49IDEgJiYgbWFqb3J2ID49IDUpCiAgICBjYXNlIE9TX0ZBU1RVU0VSU1dJVENISU5HOgogICAgICAgIEZJWE1FKCIoT1NfRkFTVFVTRVJTV0lUQ0hJTkcpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICBjYXNlIE9TX1dFTENPTUVMT0dPTlVJOgogICAgICAgIEZJWE1FKCIoT1NfV0VMQ09NRUxPR09OVUkpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19ET01BSU5NRU1CRVI6CiAgICAgICAgRklYTUUoIihPU19ET01BSU5NRU1CRVIpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICBjYXNlIE9TX0FOWVNFUlZFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1dPVzY0MzI6CiAgICAgICAgRklYTUUoIihPU19XT1c2NDMyKSBTaG91bGQgd2UgY2hlY2sgdGhpcz9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfV0VCU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfU01BTExCVVNJTkVTU1NFUlZFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1RBQkxFVFBDOgogICAgICAgIEZJWE1FKCIoT1NfVEFCTEVQQykgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX1NFUlZFUkFETUlOVUk6CiAgICAgICAgRklYTUUoIihPU19TRVJWRVJBRE1JTlVJKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfTUVESUFDRU5URVI6CiAgICAgICAgRklYTUUoIihPU19NRURJQUNFTlRFUikgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX0FQUExJQU5DRToKICAgICAgICBGSVhNRSgiKE9TX0FQUExJQU5DRSkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgojdW5kZWYgSVNPU19SRVRVUk4KCiAgICBXQVJOKCIoMHglbHgpIHVua25vd24gcGFyYW1ldGVyXG4iLGZlYXR1cmUpOwoKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBDb2xvclJHQlRvSExTCVtTSExXQVBJLkBdCiAqCiAqIENvbnZlcnQgYW4gcmdiIENPTE9SUkVGIGludG8gdGhlIGhscyBjb2xvciBzcGFjZS4KICoKICogUEFSQU1TCiAqICBjUkdCICAgICAgICAgW0ldIFNvdXJjZSByZ2IgdmFsdWUKICogIHB3SHVlICAgICAgICBbT10gRGVzdGluYXRpb24gZm9yIGNvbnZlcnRlZCBodWUKICogIHB3THVtaW5hbmNlICBbT10gRGVzdGluYXRpb24gZm9yIGNvbnZlcnRlZCBsdW1pbmFuY2UKICogIHB3U2F0dXJhdGlvbiBbT10gRGVzdGluYXRpb24gZm9yIGNvbnZlcnRlZCBzYXR1cmF0aW9uCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuIHB3SHVlLCBwd0x1bWluYW5jZSBhbmQgcHdTYXR1cmF0aW9uIGFyZSBzZXQgdG8gdGhlIGNvbnZlcnRlZAogKiAgdmFsdWVzLgogKgogKiBOT1RFUwogKiAgT3V0cHV0IEhMUyB2YWx1ZXMgYXJlIGNvbnN0cmFpbmVkIHRvIHRoZSByYW5nZSAoMC4uMjQwKS4KICogIEZvciBBY2hyb21hdGljIGNvbnZlcnNpb25zLCBIdWUgaXMgc2V0IHRvIDE2MC4KICovClZPSUQgV0lOQVBJIENvbG9yUkdCVG9ITFMoQ09MT1JSRUYgY1JHQiwgTFBXT1JEIHB3SHVlLAoJCQkgIExQV09SRCBwd0x1bWluYW5jZSwgTFBXT1JEIHB3U2F0dXJhdGlvbikKewogIGludCB3Uiwgd0csIHdCLCB3TWF4LCB3TWluLCB3SHVlLCB3THVtaW5vc2l0eSwgd1NhdHVyYXRpb247CgogIFRSQUNFKCIoJTA4bHgsJXAsJXAsJXApXG4iLCBjUkdCLCBwd0h1ZSwgcHdMdW1pbmFuY2UsIHB3U2F0dXJhdGlvbik7CgogIHdSID0gR2V0UlZhbHVlKGNSR0IpOwogIHdHID0gR2V0R1ZhbHVlKGNSR0IpOwogIHdCID0gR2V0QlZhbHVlKGNSR0IpOwoKICB3TWF4ID0gbWF4KHdSLCBtYXgod0csIHdCKSk7CiAgd01pbiA9IG1pbih3UiwgbWluKHdHLCB3QikpOwoKICAvKiBMdW1pbm9zaXR5ICovCiAgd0x1bWlub3NpdHkgPSAoKHdNYXggKyB3TWluKSAqIDI0MCArIDI1NSkgLyA1MTA7CgogIGlmICh3TWF4ID09IHdNaW4pCiAgewogICAgLyogQWNocm9tYXRpYyBjYXNlICovCiAgICB3U2F0dXJhdGlvbiA9IDA7CiAgICAvKiBIdWUgaXMgbm93IHVucmVwcmVzZW50YWJsZSwgYnV0IHRoaXMgaXMgd2hhdCBuYXRpdmUgcmV0dXJucy4uLiAqLwogICAgd0h1ZSA9IDE2MDsKICB9CiAgZWxzZQogIHsKICAgIC8qIENocm9tYXRpYyBjYXNlICovCiAgICBpbnQgd0RlbHRhID0gd01heCAtIHdNaW4sIHdSTm9ybSwgd0dOb3JtLCB3Qk5vcm07CgogICAgLyogU2F0dXJhdGlvbiAqLwogICAgaWYgKHdMdW1pbm9zaXR5IDw9IDEyMCkKICAgICAgd1NhdHVyYXRpb24gPSAoKHdNYXggKyB3TWluKS8yICsgd0RlbHRhICogMjQwKSAvICh3TWF4ICsgd01pbik7CiAgICBlbHNlCiAgICAgIHdTYXR1cmF0aW9uID0gKCg1MTAgLSB3TWF4IC0gd01pbikvMiArIHdEZWx0YSAqIDI0MCkgLyAoNTEwIC0gd01heCAtIHdNaW4pOwoKICAgIC8qIEh1ZSAqLwogICAgd1JOb3JtID0gKHdEZWx0YS8yICsgd01heCAqIDQwIC0gd1IgKiA0MCkgLyB3RGVsdGE7CiAgICB3R05vcm0gPSAod0RlbHRhLzIgKyB3TWF4ICogNDAgLSB3RyAqIDQwKSAvIHdEZWx0YTsKICAgIHdCTm9ybSA9ICh3RGVsdGEvMiArIHdNYXggKiA0MCAtIHdCICogNDApIC8gd0RlbHRhOwoKICAgIGlmICh3UiA9PSB3TWF4KQogICAgICB3SHVlID0gd0JOb3JtIC0gd0dOb3JtOwogICAgZWxzZSBpZiAod0cgPT0gd01heCkKICAgICAgd0h1ZSA9IDgwICsgd1JOb3JtIC0gd0JOb3JtOwogICAgZWxzZQogICAgICB3SHVlID0gMTYwICsgd0dOb3JtIC0gd1JOb3JtOwogICAgaWYgKHdIdWUgPCAwKQogICAgICB3SHVlICs9IDI0MDsKICAgIGVsc2UgaWYgKHdIdWUgPiAyNDApCiAgICAgIHdIdWUgLT0gMjQwOwogIH0KICBpZiAocHdIdWUpCiAgICAqcHdIdWUgPSB3SHVlOwogIGlmIChwd0x1bWluYW5jZSkKICAgICpwd0x1bWluYW5jZSA9IHdMdW1pbm9zaXR5OwogIGlmIChwd1NhdHVyYXRpb24pCiAgICAqcHdTYXR1cmF0aW9uID0gd1NhdHVyYXRpb247Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hDcmVhdGVTaGVsbFBhbGV0dGUJW1NITFdBUEkuQF0KICovCkhQQUxFVFRFIFdJTkFQSSBTSENyZWF0ZVNoZWxsUGFsZXR0ZShIREMgaGRjKQp7CglGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gQ3JlYXRlSGFsZnRvbmVQYWxldHRlKGhkYyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVNIR2V0SW52ZXJzZUNNQVAgKFNITFdBUEkuQCkKICoKICogR2V0IGFuIGludmVyc2UgY29sb3IgbWFwIHRhYmxlLgogKgogKiBQQVJBTVMKICogIGxwQ21hcCAgW09dIERlc3RpbmF0aW9uIGZvciBjb2xvciBtYXAKICogIGR3U2l6ZSAgW0ldIFNpemUgb2YgbWVtb3J5IHBvaW50ZWQgdG8gYnkgbHBDbWFwCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX1BPSU5URVIsICAgIElmIGxwQ21hcCBpcyBpbnZhbGlkLgogKiAgICAgICAgICAgRV9JTlZBTElEQVJHLCBJZiBkd0ZsYWdzIGlzIGludmFsaWQKICogICAgICAgICAgIEVfT1VUT0ZNRU1PUlksIElmIHRoZXJlIGlzIG5vIG1lbW9yeSBhdmFpbGFibGUKICoKICogTk9URVMKICogIGR3U2l6ZSBtYXkgb25seSBiZSBDTUFQX1BUUl9TSVpFICg0KSBvciBDTUFQX1NJWkUgKDgxOTIpLgogKiAgSWYgZHdTaXplID0gQ01BUF9QVFJfU0laRSwgKmxwQ21hcCBpcyBzZXQgdG8gdGhlIGFkZHJlc3Mgb2YgdGhpcyBETEwncwogKiAgaW50ZXJuYWwgQ01hcC4KICogIElmIGR3U2l6ZSA9IENNQVBfU0laRSwgbHBDbWFwIGlzIGZpbGxlZCB3aXRoIGEgY29weSBvZiB0aGUgZGF0YSBmcm9tCiAqICB0aGlzIERMTCdzIGludGVybmFsIENNYXAuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEdldEludmVyc2VDTUFQKExQRFdPUkQgZGVzdCwgRFdPUkQgZHdTaXplKQp7CiAgICBpZiAoZHdTaXplID09IDQpIHsKCUZJWE1FKCIgLSByZXR1cm5pbmcgYm9ndXMgYWRkcmVzcyBmb3IgU0hHZXRJbnZlcnNlQ01BUFxuIik7CgkqZGVzdCA9IChEV09SRCkweGFiYmExMjQ5OwoJcmV0dXJuIDA7CiAgICB9CiAgICBGSVhNRSgiKCVwLCAlI2x4KSBzdHViXG4iLCBkZXN0LCBkd1NpemUpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hJc0xvd01lbW9yeU1hY2hpbmUJW1NITFdBUEkuQF0KICoKICogRGV0ZXJtaW5lIGlmIHRoZSBjdXJyZW50IGNvbXB1dGVyIGhhcyBsb3cgbWVtb3J5LgogKgogKiBQQVJBTVMKICogIHggW0ldIEZJWE1FCiAqCiAqIFJFVFVSTlMKICogIFRSVUUgaWYgdGhlIHVzZXJzIG1hY2hpbmUgaGFzIDE2IE1lZ2FieXRlcyBvZiBtZW1vcnkgb3IgbGVzcywKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIFNISXNMb3dNZW1vcnlNYWNoaW5lIChEV09SRCB4KQp7CiAgRklYTUUoIigweCUwOGx4KSBzdHViXG4iLCB4KTsKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgR2V0TWVudVBvc0Zyb21JRAlbU0hMV0FQSS5AXQogKgogKiBSZXR1cm4gdGhlIHBvc2l0aW9uIG9mIGEgbWVudSBpdGVtIGZyb20gaXRzIElkLgogKgogKiBQQVJBTVMKICogICBoTWVudSBbSV0gTWVudSBjb250YWluaW5nIHRoZSBpdGVtCiAqICAgd0lEICAgW0ldIElkIG9mIHRoZSBtZW51IGl0ZW0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIGluZGV4IG9mIHRoZSBtZW51IGl0ZW0gaW4gaE1lbnUuCiAqICBGYWlsdXJlOiAtMSwgSWYgdGhlIGl0ZW0gaXMgbm90IGZvdW5kLgogKi8KSU5UIFdJTkFQSSBHZXRNZW51UG9zRnJvbUlEKEhNRU5VIGhNZW51LCBVSU5UIHdJRCkKewogTUVOVUlURU1JTkZPQSBtaTsKIElOVCBuQ291bnQgPSBHZXRNZW51SXRlbUNvdW50KGhNZW51KSwgbkl0ZXIgPSAwOwoKIHdoaWxlIChuSXRlciA8IG5Db3VudCkKIHsKICAgbWkud0lEID0gMDsKICAgaWYgKCFHZXRNZW51SXRlbUluZm9BKGhNZW51LCBuSXRlciwgVFJVRSwgJm1pKSAmJiBtaS53SUQgPT0gd0lEKQogICAgIHJldHVybiBuSXRlcjsKICAgbkl0ZXIrKzsKIH0KIHJldHVybiAtMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3OV0KICoKICogU2FtZSBhcyBTSExXQVBJLkdldE1lbnVQb3NGcm9tSUQKICovCkRXT1JEIFdJTkFQSSBTSE1lbnVJbmRleEZyb21JRChITUVOVSBoTWVudSwgVUlOVCB1SUQpCnsKICAgIHJldHVybiBHZXRNZW51UG9zRnJvbUlEKGhNZW51LCB1SUQpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQ0OF0KICovClZPSUQgV0lOQVBJIEZpeFNsYXNoZXNBbmRDb2xvblcoTFBXU1RSIGxwd3N0cikKewogICAgd2hpbGUgKCpscHdzdHIpCiAgICB7CiAgICAgICAgaWYgKCpscHdzdHIgPT0gJy8nKQogICAgICAgICAgICAqbHB3c3RyID0gJ1xcJzsKICAgICAgICBscHdzdHIrKzsKICAgIH0KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40NjFdCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRBcHBDb21wYXRGbGFncyhEV09SRCBVbmtub3duKQp7CiAgRklYTUUoInN0dWJcbiIpOwogIHJldHVybiAwOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjU0OV0KICovCkhSRVNVTFQgV0lOQVBJIFNIQ29DcmVhdGVJbnN0YW5jZUFDKFJFRkNMU0lEIHJjbHNpZCwgTFBVTktOT1dOIHBVbmtPdXRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdDbHNDb250ZXh0LCBSRUZJSUQgaWlkLCBMUFZPSUQgKnBwdikKewogICAgcmV0dXJuIENvQ3JlYXRlSW5zdGFuY2UocmNsc2lkLCBwVW5rT3V0ZXIsIGR3Q2xzQ29udGV4dCwgaWlkLCBwcHYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFNraXBKdW5jdGlvbglbU0hMV0FQSS5AXQogKgogKiBEZXRlcm1pbmUgaWYgYSBiaW5kIGNvbnRleHQgY2FuIGJlIGJvdW5kIHRvIGFuIG9iamVjdAogKgogKiBQQVJBTVMKICogIHBiYyAgICBbSV0gQmluZCBjb250ZXh0IHRvIGNoZWNrCiAqICBwY2xzaWQgW0ldIENMU0lEIG9mIG9iamVjdCB0byBiZSBib3VuZCB0bwogKgogKiBSRVRVUk5TCiAqICBUUlVFOiBJZiBpdCBpcyBzYWZlIHRvIGJpbmQKICogIEZBTFNFOiBJZiBwYmMgaXMgaW52YWxpZCBvciBiaW5kaW5nIHdvdWxkIG5vdCBiZSBzYWZlCiAqCiAqLwpCT09MIFdJTkFQSSBTSFNraXBKdW5jdGlvbihJQmluZEN0eCAqcGJjLCBjb25zdCBDTFNJRCAqcGNsc2lkKQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6U2tpcEJpbmRpbmdbXSA9IHsgJ1MnLCdrJywnaScsJ3AnLCcgJywKICAgICdCJywnaScsJ24nLCdkJywnaScsJ24nLCdnJywnICcsJ0MnLCdMJywnUycsJ0knLCdEJywnXDAnIH07CiAgQk9PTCBiUmV0ID0gRkFMU0U7CgogIGlmIChwYmMpCiAgewogICAgSVVua25vd24qIGxwVW5rOwoKICAgIGlmIChTVUNDRUVERUQoSUJpbmRDdHhfR2V0T2JqZWN0UGFyYW0ocGJjLCAoTFBPTEVTVFIpc3pTa2lwQmluZGluZywgJmxwVW5rKSkpCiAgICB7CiAgICAgIENMU0lEIGNsc2lkOwoKICAgICAgaWYgKFNVQ0NFRURFRChJVW5rbm93bl9HZXRDbGFzc0lEKGxwVW5rLCAmY2xzaWQpKSAmJgogICAgICAgICAgSXNFcXVhbEdVSUQocGNsc2lkLCAmY2xzaWQpKQogICAgICAgIGJSZXQgPSBUUlVFOwoKICAgICAgSVVua25vd25fUmVsZWFzZShscFVuayk7CiAgICB9CiAgfQogIHJldHVybiBiUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIR2V0U2hlbGxLZXkgKFNITFdBUEkuQCkKICovCkRXT1JEIFdJTkFQSSBTSEdldFNoZWxsS2V5KERXT1JEIGEsIERXT1JEIGIsIERXT1JEIGMpCnsKICAgIEZJWE1FKCIoJWx4LCAlbHgsICVseCk6IHN0dWJcbiIsIGEsIGIsIGMpOwogICAgcmV0dXJuIDB4NTA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU0hRdWV1ZVVzZXJXb3JrSXRlbSAoU0hMV0FQSS5AKQogKi8KSFJFU1VMVCBXSU5BUEkgU0hRdWV1ZVVzZXJXb3JrSXRlbShEV09SRCBhLCBEV09SRCBiLCBEV09SRCBjLCBEV09SRCBkLCBEV09SRCBlLCBEV09SRCBmLCBEV09SRCBnKQp7CiAgICBGSVhNRSgiKCVseCwgJWx4LCAlbHgsICVseCwgJWx4LCAlbHgsICVseCk6IHN0dWJcbiIsIGEsIGIsIGMsIGQsIGUsIGYsIGcpOwogICAgcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlJVW5rbm93bl9PbkZvY3VzQ2hhbmdlSVMgKFNITFdBUEkuQCkKICovCkRXT1JEIFdJTkFQSSBJVW5rbm93bl9PbkZvY3VzQ2hhbmdlSVMoSVVua25vd24gKiBwVW5rLCBJVW5rbm93biAqIHBGb2N1c09iamVjdCwgQk9PTCBiQ2hhbmdlKQp7CiAgICBGSVhNRSgiKCVwLCAlcCwgJXMpXG4iLCBwVW5rLCBwRm9jdXNPYmplY3QsIGJDaGFuZ2UgPyAiVFJVRSIgOiAiRkFMU0UiKTsKCi8qCiAgICBJSW5wdXRPYmplY3RTaXRlICogcElPUyA9IE5VTEw7CiAgICBpZiAoU1VDQ0VFREVEKElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKHBVbmssICZJSURfSUlucHV0T2JqZWN0U2l0ZSwgKHZvaWQgKiopJnBJT1MpKQogICAgICAgIElJbnB1dE9iamVjdFNpdGVfT25Gb2N1c0NoYW5nZUlTKHBJT1MsIHBGb2N1c09iamVjdCwgYkNoYW5nZSk7CiovCgogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU0hHZXRWYWx1ZVcgKFNITFdBUEkuQCkKICovCkhSRVNVTFQgV0lOQVBJIFNLR2V0VmFsdWVXKERXT1JEIGEsIExQV1NUUiBiLCBMUFdTVFIgYywgRFdPUkQgZCwgRFdPUkQgZSwgRFdPUkQgZikKewogICAgRklYTUUoIiglbHgsICVzLCAlcywgJWx4LCAlbHgsICVseCk6IHN0dWJcbiIsIGEsIGRlYnVnc3RyX3coYiksIGRlYnVnc3RyX3coYyksIGQsIGUsIGYpOwogICAgcmV0dXJuIEVfRkFJTDsKfQoKdHlwZWRlZiBIUkVTVUxUIChXSU5BUEkgKkRsbEdldFZlcnNpb25fZnVuYykoRExMVkVSU0lPTklORk8gKik7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgIEdldFVJVmVyc2lvbiAoU0hMV0FQSS40NTIpCiAqLwpEV09SRCBXSU5BUEkgR2V0VUlWZXJzaW9uKHZvaWQpCnsKICAgIHN0YXRpYyBEV09SRCB2ZXJzaW9uOwoKICAgIGlmICghdmVyc2lvbikKICAgIHsKICAgICAgICBEbGxHZXRWZXJzaW9uX2Z1bmMgcERsbEdldFZlcnNpb247CiAgICAgICAgSE1PRFVMRSBkbGwgPSBMb2FkTGlicmFyeUEoInNoZWxsMzIuZGxsIik7CiAgICAgICAgaWYgKCFkbGwpIHJldHVybiAwOwoKICAgICAgICBwRGxsR2V0VmVyc2lvbiA9IChEbGxHZXRWZXJzaW9uX2Z1bmMpR2V0UHJvY0FkZHJlc3MoZGxsLCAiRGxsR2V0VmVyc2lvbiIpOwogICAgICAgIGlmIChwRGxsR2V0VmVyc2lvbikKICAgICAgICB7CiAgICAgICAgICAgIERMTFZFUlNJT05JTkZPIGR2aTsKICAgICAgICAgICAgZHZpLmNiU2l6ZSA9IHNpemVvZihETExWRVJTSU9OSU5GTyk7CiAgICAgICAgICAgIGlmIChwRGxsR2V0VmVyc2lvbigmZHZpKSA9PSBTX09LKSB2ZXJzaW9uID0gZHZpLmR3TWFqb3JWZXJzaW9uOwogICAgICAgIH0KICAgICAgICBGcmVlTGlicmFyeSggZGxsICk7CiAgICAgICAgaWYgKCF2ZXJzaW9uKSB2ZXJzaW9uID0gMzsgIC8qIG9sZCBzaGVsbCBkbGxzIGRvbid0IGhhdmUgRGxsR2V0VmVyc2lvbiAqLwogICAgfQogICAgcmV0dXJuIHZlcnNpb247Cn0K