LyoKICogU0hMV0FQSSBvcmRpbmFsIGZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NyBNYXJjdXMgTWVpc3NuZXIKICogICAgICAgICAgIDE5OTggSvxyZ2VuIFNjaG1pZWQKICogICAgICAgICAgIDIwMDEtMjAwMyBKb24gR3JpZmZpdGhzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNkZWZpbmUgQ09NX05PX1dJTkRPV1NfSAojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAiZG9jb2JqLmgiCiNpbmNsdWRlICJleGRpc3AuaCIKI2luY2x1ZGUgInNobGd1aWQuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAic2hsb2JqLmgiCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgInNobHdhcGkuaCIKCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChzaGVsbCk7CgovKiBHZXQgYSBmdW5jdGlvbiBwb2ludGVyIGZyb20gYSBETEwgaGFuZGxlICovCiNkZWZpbmUgR0VUX0ZVTkMoZnVuYywgbW9kdWxlLCBuYW1lLCBmYWlsKSBcCiAgZG8geyBcCiAgICBpZiAoIWZ1bmMpIHsgXAogICAgICBpZiAoIVNITFdBUElfaCMjbW9kdWxlICYmICEoU0hMV0FQSV9oIyNtb2R1bGUgPSBMb2FkTGlicmFyeUEoI21vZHVsZSAiLmRsbCIpKSkgcmV0dXJuIGZhaWw7IFwKICAgICAgZnVuYyA9IChmbiMjZnVuYylHZXRQcm9jQWRkcmVzcyhTSExXQVBJX2gjI21vZHVsZSwgbmFtZSk7IFwKICAgICAgaWYgKCFmdW5jKSByZXR1cm4gZmFpbDsgXAogICAgfSBcCiAgfSB3aGlsZSAoMCkKCi8qIERMTCBoYW5kbGVzIGZvciBsYXRlIGJvdW5kIGNhbGxzICovCmV4dGVybiBISU5TVEFOQ0Ugc2hsd2FwaV9oSW5zdGFuY2U7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaHNoZWxsMzI7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaHdpbm1tOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2hjb21kbGczMjsKZXh0ZXJuIEhNT0RVTEUgU0hMV0FQSV9oY29tY3RsMzI7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaG1wcjsKZXh0ZXJuIEhNT0RVTEUgU0hMV0FQSV9odXJsbW9uOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2h2ZXJzaW9uOwoKZXh0ZXJuIERXT1JEIFNITFdBUElfVGhyZWFkUmVmX2luZGV4OwoKLyogRnVuY3Rpb24gcG9pbnRlcnMgZm9yIEdFVF9GVU5DIG1hY3JvOyB0aGVzZSBuZWVkIHRvIGJlIGdsb2JhbCBiZWNhdXNlIG9mIGdjYyBidWcgKi8KdHlwZWRlZiBMUElURU1JRExJU1QgKFdJTkFQSSAqZm5wU0hCcm93c2VGb3JGb2xkZXJXKShMUEJST1dTRUlORk9XKTsKc3RhdGljICBmbnBTSEJyb3dzZUZvckZvbGRlclcgcFNIQnJvd3NlRm9yRm9sZGVyVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFBsYXlTb3VuZFcpKExQQ1dTVFIsIEhNT0RVTEUsIERXT1JEKTsKc3RhdGljICBmbnBQbGF5U291bmRXIHBQbGF5U291bmRXOwp0eXBlZGVmIERXT1JEICAgKFdJTkFQSSAqZm5wU0hHZXRGaWxlSW5mb1cpKExQQ1dTVFIsRFdPUkQsU0hGSUxFSU5GT1cqLFVJTlQsVUlOVCk7CnN0YXRpYyAgZm5wU0hHZXRGaWxlSW5mb1cgcFNIR2V0RmlsZUluZm9XOwp0eXBlZGVmIFVJTlQgICAgKFdJTkFQSSAqZm5wRHJhZ1F1ZXJ5RmlsZVcpKEhEUk9QLCBVSU5ULCBMUFdTVFIsIFVJTlQpOwpzdGF0aWMgIGZucERyYWdRdWVyeUZpbGVXIHBEcmFnUXVlcnlGaWxlVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFNIR2V0UGF0aEZyb21JRExpc3RXKShMUENJVEVNSURMSVNULCBMUFdTVFIpOwpzdGF0aWMgIGZucFNIR2V0UGF0aEZyb21JRExpc3RXIHBTSEdldFBhdGhGcm9tSURMaXN0VzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFNoZWxsRXhlY3V0ZUV4VykoTFBTSEVMTEVYRUNVVEVJTkZPVyk7CnN0YXRpYyAgZm5wU2hlbGxFeGVjdXRlRXhXIHBTaGVsbEV4ZWN1dGVFeFc7CnR5cGVkZWYgSElDT04gICAoV0lOQVBJICpmbnBTSEZpbGVPcGVyYXRpb25XKShMUFNIRklMRU9QU1RSVUNUVyk7CnN0YXRpYyAgZm5wU0hGaWxlT3BlcmF0aW9uVyBwU0hGaWxlT3BlcmF0aW9uVzsKdHlwZWRlZiBVSU5UICAgIChXSU5BUEkgKmZucEV4dHJhY3RJY29uRXhXKShMUENXU1RSLCBJTlQsSElDT04gKixISUNPTiAqLCBVSU5UKTsKc3RhdGljICBmbnBFeHRyYWN0SWNvbkV4VyBwRXh0cmFjdEljb25FeFc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBTSEdldE5ld0xpbmtJbmZvVykoTFBDV1NUUiwgTFBDV1NUUiwgTFBDV1NUUiwgQk9PTCosIFVJTlQpOwpzdGF0aWMgIGZucFNIR2V0TmV3TGlua0luZm9XIHBTSEdldE5ld0xpbmtJbmZvVzsKdHlwZWRlZiBIUkVTVUxUIChXSU5BUEkgKmZucFNIRGVmRXh0cmFjdEljb25XKShMUENXU1RSLCBpbnQsIFVJTlQsIEhJQ09OKiwgSElDT04qLCBVSU5UKTsKc3RhdGljICBmbnBTSERlZkV4dHJhY3RJY29uVyBwU0hEZWZFeHRyYWN0SWNvblc7CnR5cGVkZWYgSElDT04gICAoV0lOQVBJICpmbnBFeHRyYWN0SWNvblcpKEhJTlNUQU5DRSwgTFBDV1NUUiwgVUlOVCk7CnN0YXRpYyAgZm5wRXh0cmFjdEljb25XIHBFeHRyYWN0SWNvblc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBHZXRTYXZlRmlsZU5hbWVXKShMUE9QRU5GSUxFTkFNRVcpOwpzdGF0aWMgIGZucEdldFNhdmVGaWxlTmFtZVcgcEdldFNhdmVGaWxlTmFtZVc7CnR5cGVkZWYgRFdPUkQgICAoV0lOQVBJICpmbnBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XKShIV05ELCBMUFdTVFIpOwpzdGF0aWMgIGZucFdOZXRSZXN0b3JlQ29ubmVjdGlvblcgcFdOZXRSZXN0b3JlQ29ubmVjdGlvblc7CnR5cGVkZWYgRFdPUkQgICAoV0lOQVBJICpmbnBXTmV0R2V0TGFzdEVycm9yVykoTFBEV09SRCwgTFBXU1RSLCBEV09SRCwgTFBXU1RSLCBEV09SRCk7CnN0YXRpYyAgZm5wV05ldEdldExhc3RFcnJvclcgcFdOZXRHZXRMYXN0RXJyb3JXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wUGFnZVNldHVwRGxnVykoTFBQQUdFU0VUVVBETEdXKTsKc3RhdGljICBmbnBQYWdlU2V0dXBEbGdXIHBQYWdlU2V0dXBEbGdXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wUHJpbnREbGdXKShMUFBSSU5URExHVyk7CnN0YXRpYyAgZm5wUHJpbnREbGdXIHBQcmludERsZ1c7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBHZXRPcGVuRmlsZU5hbWVXKShMUE9QRU5GSUxFTkFNRVcpOwpzdGF0aWMgIGZucEdldE9wZW5GaWxlTmFtZVcgcEdldE9wZW5GaWxlTmFtZVc7CnR5cGVkZWYgRFdPUkQgICAoV0lOQVBJICpmbnBHZXRGaWxlVmVyc2lvbkluZm9TaXplVykoTFBDV1NUUixMUERXT1JEKTsKc3RhdGljICBmbnBHZXRGaWxlVmVyc2lvbkluZm9TaXplVyBwR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBHZXRGaWxlVmVyc2lvbkluZm9XKShMUENXU1RSLERXT1JELERXT1JELExQVk9JRCk7CnN0YXRpYyAgZm5wR2V0RmlsZVZlcnNpb25JbmZvVyBwR2V0RmlsZVZlcnNpb25JbmZvVzsKdHlwZWRlZiBXT1JEICAgIChXSU5BUEkgKmZucFZlclF1ZXJ5VmFsdWVXKShMUFZPSUQsTFBDV1NUUixMUFZPSUQqLFVJTlQqKTsKc3RhdGljICBmbnBWZXJRdWVyeVZhbHVlVyBwVmVyUXVlcnlWYWx1ZVc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBDT01DVEwzMl80MTcpKEhEQyxJTlQsSU5ULFVJTlQsY29uc3QgUkVDVCosTFBDV1NUUixVSU5ULGNvbnN0IElOVCopOwpzdGF0aWMgIGZucENPTUNUTDMyXzQxNyBwQ09NQ1RMMzJfNDE3Owp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqZm5wRGxsR2V0VmVyc2lvbikoRExMVkVSU0lPTklORk8qKTsKc3RhdGljICBmbnBEbGxHZXRWZXJzaW9uIHBEbGxHZXRWZXJzaW9uOwp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqZm5wQ3JlYXRlRm9ybWF0RW51bWVyYXRvcikoVUlOVCxGT1JNQVRFVEMqLElFbnVtRk9STUFURVRDKiopOwpzdGF0aWMgZm5wQ3JlYXRlRm9ybWF0RW51bWVyYXRvciBwQ3JlYXRlRm9ybWF0RW51bWVyYXRvcjsKdHlwZWRlZiBIUkVTVUxUIChXSU5BUEkgKmZucFJlZ2lzdGVyRm9ybWF0RW51bWVyYXRvcikoTFBCQyxJRW51bUZPUk1BVEVUQyosRFdPUkQpOwpzdGF0aWMgZm5wUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yIHBSZWdpc3RlckZvcm1hdEVudW1lcmF0b3I7CgpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVNlcnZpY2UoSVVua25vd24qLFJFRkdVSUQsUkVGSUlELExQVk9JRCopOwpIUkVTVUxUIFdJTkFQSSBTSEludm9rZUNvbW1hbmQoSFdORCxJU2hlbGxGb2xkZXIqLExQQ0lURU1JRExJU1QsQk9PTCk7CkhSRVNVTFQgV0lOQVBJIENMU0lERnJvbVN0cmluZ1dyYXAoTFBDV1NUUixDTFNJRCopOwpCT09MICAgIFdJTkFQSSBTSEFib3V0SW5mb1coTFBXU1RSLERXT1JEKTsKCi8qCiBOT1RFUzogTW9zdCBmdW5jdGlvbnMgZXhwb3J0ZWQgYnkgb3JkaW5hbCBzZWVtIHRvIGJlIHN1cGVyZmxvdXMuCiBUaGUgcmVhc29uIGZvciB0aGVzZSBmdW5jdGlvbnMgdG8gYmUgdGhlcmUgaXMgdG8gcHJvdmlkZSBhIHdyYXBwZXIKIGZvciB1bmljb2RlIGZ1bmN0aW9ucyB0byBwcm92aWRlIHRoZXNlIGZ1bmN0aW9ucyBvbiBzeXN0ZW1zIHdpdGhvdXQKIHVuaWNvZGUgZnVuY3Rpb25zIGVnLiB3aW45NS93aW45OC4gU2luY2Ugd2UgaGF2ZSBzdWNoIGZ1bmN0aW9ucyB3ZSBqdXN0CiBjYWxsIHRoZXNlLiBJZiBydW5uaW5nIFdpbmUgd2l0aCBuYXRpdmUgRExMcywgc29tZSBsYXRlIGJvdW5kIGNhbGxzIG1heQogZmFpbC4gSG93ZXZlciwgaXQgaXMgYmV0dGVyIHRvIGltcGxlbWVudCB0aGUgZnVuY3Rpb25zIGluIHRoZSBmb3J3YXJkIERMTAogYW5kIHJlY29tbWVuZCB0aGUgYnVpbHRpbiByYXRoZXIgdGhhbiByZWltcGxlbWVudGluZyB0aGUgY2FsbHMgaGVyZSEKKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNITFdBUElfRHVwU2hhcmVkSGFuZGxlCiAqCiAqIEludGVybmFsIGltcGxlbWV0YXRpb24gb2YgU0hMV0FQSV8xMS4KICovCnN0YXRpYwpIQU5ETEUgV0lOQVBJIFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd0RzdFByb2NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdTcmNQcm9jSWQsIERXT1JEIGR3QWNjZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd09wdGlvbnMpCnsKICBIQU5ETEUgaERzdCwgaFNyYzsKICBEV09SRCBkd015UHJvY0lkID0gR2V0Q3VycmVudFByb2Nlc3NJZCgpOwogIEhBTkRMRSBoUmV0ID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCUwOGx4LCUwOGx4KVxuIiwgaFNoYXJlZCwgZHdEc3RQcm9jSWQsIGR3U3JjUHJvY0lkLAogICAgICAgIGR3QWNjZXNzLCBkd09wdGlvbnMpOwoKICAvKiBHZXQgZGVzdCBwcm9jZXNzIGhhbmRsZSAqLwogIGlmIChkd0RzdFByb2NJZCA9PSBkd015UHJvY0lkKQogICAgaERzdCA9IEdldEN1cnJlbnRQcm9jZXNzKCk7CiAgZWxzZQogICAgaERzdCA9IE9wZW5Qcm9jZXNzKFBST0NFU1NfRFVQX0hBTkRMRSwgMCwgZHdEc3RQcm9jSWQpOwoKICBpZiAoaERzdCkKICB7CiAgICAvKiBHZXQgc3JjIHByb2Nlc3MgaGFuZGxlICovCiAgICBpZiAoZHdTcmNQcm9jSWQgPT0gZHdNeVByb2NJZCkKICAgICAgaFNyYyA9IEdldEN1cnJlbnRQcm9jZXNzKCk7CiAgICBlbHNlCiAgICAgIGhTcmMgPSBPcGVuUHJvY2VzcyhQUk9DRVNTX0RVUF9IQU5ETEUsIDAsIGR3U3JjUHJvY0lkKTsKCiAgICBpZiAoaFNyYykKICAgIHsKICAgICAgLyogTWFrZSBoYW5kbGUgYXZhaWxhYmxlIHRvIGRlc3QgcHJvY2VzcyAqLwogICAgICBpZiAoIUR1cGxpY2F0ZUhhbmRsZShoRHN0LCBoU2hhcmVkLCBoU3JjLCAmaFJldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdBY2Nlc3MsIDAsIGR3T3B0aW9ucyB8IERVUExJQ0FURV9TQU1FX0FDQ0VTUykpCiAgICAgICAgaFJldCA9IE5VTEw7CgogICAgICBpZiAoZHdTcmNQcm9jSWQgIT0gZHdNeVByb2NJZCkKICAgICAgICBDbG9zZUhhbmRsZShoU3JjKTsKICAgIH0KCiAgICBpZiAoZHdEc3RQcm9jSWQgIT0gZHdNeVByb2NJZCkKICAgICAgQ2xvc2VIYW5kbGUoaERzdCk7CiAgfQoKICBUUkFDRSgiUmV0dXJuaW5nIGhhbmRsZSAlcFxuIiwgaFJldCk7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjddCiAqCiAqIENyZWF0ZSBhIGJsb2NrIG9mIHNoYXJhYmxlIG1lbW9yeSBhbmQgaW5pdGlhbGlzZSBpdCB3aXRoIGRhdGEuCiAqCiAqIFBBUkFNUwogKiBscHZEYXRhICBbSV0gUG9pbnRlciB0byBkYXRhIHRvIHdyaXRlCiAqIGR3U2l6ZSAgIFtJXSBTaXplIG9mIGRhdGEKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGRhdGEKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBBIHNoYXJlZCBtZW1vcnkgaGFuZGxlCiAqIEZhaWx1cmU6IE5VTEwKICoKICogTk9URVMKICogT3JkaW5hbHMgNy0xMSBwcm92aWRlIGEgc2V0IG9mIGNhbGxzIHRvIGNyZWF0ZSBzaGFyZWQgbWVtb3J5IGJldHdlZW4gYQogKiBncm91cCBvZiBwcm9jZXNzZXMuIFRoZSBzaGFyZWQgbWVtb3J5IGlzIHRyZWF0ZWQgb3BhcXVlbHkgaW4gdGhhdCBpdHMgc2l6ZQogKiBpcyBub3QgZXhwb3NlZCB0byBjbGllbnRzIHdobyBtYXAgaXQuIFRoaXMgaXMgYWNjb21wbGlzaGVkIGJ5IHN0b3JpbmcKICogdGhlIHNpemUgb2YgdGhlIG1hcCBhcyB0aGUgZmlyc3QgRFdPUkQgb2YgbWFwcGVkIGRhdGEsIGFuZCB0aGVuIG9mZnNldHRpbmcKICogdGhlIHZpZXcgcG9pbnRlciByZXR1cm5lZCBieSB0aGlzIHNpemUuCiAqCiAqLwpIQU5ETEUgV0lOQVBJIFNIQWxsb2NTaGFyZWQoTFBDVk9JRCBscHZEYXRhLCBEV09SRCBkd1NpemUsIERXT1JEIGR3UHJvY0lkKQp7CiAgSEFORExFIGhNYXA7CiAgTFBWT0lEIHBNYXBwZWQ7CiAgSEFORExFIGhSZXQgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLCBscHZEYXRhLCBkd1NpemUsIGR3UHJvY0lkKTsKCiAgLyogQ3JlYXRlIGZpbGUgbWFwcGluZyBvZiB0aGUgY29ycmVjdCBsZW5ndGggKi8KICBoTWFwID0gQ3JlYXRlRmlsZU1hcHBpbmdBKElOVkFMSURfSEFORExFX1ZBTFVFLCBOVUxMLCBGSUxFX01BUF9SRUFELCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdTaXplICsgc2l6ZW9mKGR3U2l6ZSksIE5VTEwpOwogIGlmICghaE1hcCkKICAgIHJldHVybiBoUmV0OwoKICAvKiBHZXQgYSB2aWV3IGluIG91ciBwcm9jZXNzIGFkZHJlc3Mgc3BhY2UgKi8KICBwTWFwcGVkID0gTWFwVmlld09mRmlsZShoTWFwLCBGSUxFX01BUF9SRUFEIHwgRklMRV9NQVBfV1JJVEUsIDAsIDAsIDApOwoKICBpZiAocE1hcHBlZCkKICB7CiAgICAvKiBXcml0ZSBzaXplIG9mIGRhdGEsIGZvbGxvd2VkIGJ5IHRoZSBkYXRhLCB0byB0aGUgdmlldyAqLwogICAgKigoRFdPUkQqKXBNYXBwZWQpID0gZHdTaXplOwogICAgaWYgKGxwdkRhdGEpCiAgICAgIG1lbWNweSgoY2hhciAqKSBwTWFwcGVkICsgc2l6ZW9mKGR3U2l6ZSksIGxwdkRhdGEsIGR3U2l6ZSk7CgogICAgLyogUmVsZWFzZSB2aWV3LiBBbGwgZnVydGhlciB2aWV3cyBtYXBwZWQgd2lsbCBiZSBvcGFxdWUgKi8KICAgIFVubWFwVmlld09mRmlsZShwTWFwcGVkKTsKICAgIGhSZXQgPSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShoTWFwLCBkd1Byb2NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50UHJvY2Vzc0lkKCksIEZJTEVfTUFQX0FMTF9BQ0NFU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFVQTElDQVRFX1NBTUVfQUNDRVNTKTsKICB9CgogIENsb3NlSGFuZGxlKGhNYXApOwogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAIFtTSExXQVBJLjhdCiAqCiAqIEdldCBhIHBvaW50ZXIgdG8gYSBibG9jayBvZiBzaGFyZWQgbWVtb3J5IGZyb20gYSBzaGFyZWQgbWVtb3J5IGhhbmRsZS4KICoKICogUEFSQU1TCiAqIGhTaGFyZWQgIFtJXSBTaGFyZWQgbWVtb3J5IGhhbmRsZQogKiBkd1Byb2NJZCBbSV0gSUQgb2YgcHJvY2VzcyBvd25pbmcgaFNoYXJlZAogKgogKiBSRVRVUk5TCiAqIFN1Y2Nlc3M6IEEgcG9pbnRlciB0byB0aGUgc2hhcmVkIG1lbW9yeQogKiBGYWlsdXJlOiBOVUxMCiAqCiAqLwpQVk9JRCBXSU5BUEkgU0hMb2NrU2hhcmVkKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd1Byb2NJZCkKewogIEhBTkRMRSBoRHVwOwogIExQVk9JRCBwTWFwcGVkOwoKICBUUkFDRSgiKCVwICVsZClcbiIsIGhTaGFyZWQsIGR3UHJvY0lkKTsKCiAgLyogR2V0IGhhbmRsZSB0byBzaGFyZWQgbWVtb3J5IGZvciBjdXJyZW50IHByb2Nlc3MgKi8KICBoRHVwID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaFNoYXJlZCwgZHdQcm9jSWQsIEdldEN1cnJlbnRQcm9jZXNzSWQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9NQVBfQUxMX0FDQ0VTUywgMCk7CiAgLyogR2V0IFZpZXcgKi8KICBwTWFwcGVkID0gTWFwVmlld09mRmlsZShoRHVwLCBGSUxFX01BUF9SRUFEIHwgRklMRV9NQVBfV1JJVEUsIDAsIDAsIDApOwogIENsb3NlSGFuZGxlKGhEdXApOwoKICBpZiAocE1hcHBlZCkKICAgIHJldHVybiAoY2hhciAqKSBwTWFwcGVkICsgc2l6ZW9mKERXT1JEKTsgLyogSGlkZSBzaXplICovCiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuOV0KICoKICogUmVsZWFzZSBhIHBvaW50ZXIgdG8gYSBibG9jayBvZiBzaGFyZWQgbWVtb3J5LgogKgogKiBQQVJBTVMKICogbHBWaWV3IFtJXSBTaGFyZWQgbWVtb3J5IHBvaW50ZXIKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBUUlVFCiAqIEZhaWx1cmU6IEZBTFNFCiAqCiAqLwpCT09MIFdJTkFQSSBTSFVubG9ja1NoYXJlZChMUFZPSUQgbHBWaWV3KQp7CiAgVFJBQ0UoIiglcClcbiIsIGxwVmlldyk7CiAgcmV0dXJuIFVubWFwVmlld09mRmlsZSgoY2hhciAqKSBscFZpZXcgLSBzaXplb2YoRFdPUkQpKTsgLyogSW5jbHVkZSBzaXplICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuMTBdCiAqCiAqIERlc3Ryb3kgYSBibG9jayBvZiBzaGFyYWJsZSBtZW1vcnkuCiAqCiAqIFBBUkFNUwogKiBoU2hhcmVkICBbSV0gU2hhcmVkIG1lbW9yeSBoYW5kbGUKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGhTaGFyZWQKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBUUlVFCiAqIEZhaWx1cmU6IEZBTFNFCiAqCiAqLwpCT09MIFdJTkFQSSBTSEZyZWVTaGFyZWQoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3UHJvY0lkKQp7CiAgSEFORExFIGhDbG9zZTsKCiAgVFJBQ0UoIiglcCAlbGQpXG4iLCBoU2hhcmVkLCBkd1Byb2NJZCk7CgogIC8qIEdldCBhIGNvcHkgb2YgdGhlIGhhbmRsZSBmb3Igb3VyIHByb2Nlc3MsIGNsb3NpbmcgdGhlIHNvdXJjZSBoYW5kbGUgKi8KICBoQ2xvc2UgPSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShoU2hhcmVkLCBkd1Byb2NJZCwgR2V0Q3VycmVudFByb2Nlc3NJZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfTUFQX0FMTF9BQ0NFU1MsRFVQTElDQVRFX0NMT1NFX1NPVVJDRSk7CiAgLyogQ2xvc2UgbG9jYWwgY29weSAqLwogIHJldHVybiBDbG9zZUhhbmRsZShoQ2xvc2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgW1NITFdBUEkuMTFdCiAqCiAqIENvcHkgYSBzaGFyYWJsZSBtZW1vcnkgaGFuZGxlIGZyb20gb25lIHByb2Nlc3MgdG8gYW5vdGhlci4KICoKICogUEFSQU1TCiAqIGhTaGFyZWQgICAgIFtJXSBTaGFyZWQgbWVtb3J5IGhhbmRsZSB0byBkdXBsaWNhdGUKICogZHdEc3RQcm9jSWQgW0ldIElEIG9mIHRoZSBwcm9jZXNzIHdhbnRpbmcgdGhlIGR1cGxpY2F0ZWQgaGFuZGxlCiAqIGR3U3JjUHJvY0lkIFtJXSBJRCBvZiB0aGUgcHJvY2VzcyBvd25pbmcgaFNoYXJlZAogKiBkd0FjY2VzcyAgICBbSV0gRGVzaXJlZCBEdXBsaWNhdGVIYW5kbGUoKSBhY2Nlc3MKICogZHdPcHRpb25zICAgW0ldIERlc2lyZWQgRHVwbGljYXRlSGFuZGxlKCkgb3B0aW9ucwogKgogKiBSRVRVUk5TCiAqIFN1Y2Nlc3M6IEEgaGFuZGxlIHN1aXRhYmxlIGZvciB1c2UgYnkgdGhlIGR3RHN0UHJvY0lkIHByb2Nlc3MuCiAqIEZhaWx1cmU6IEEgTlVMTCBoYW5kbGUuCiAqCiAqLwpIQU5ETEUgV0lOQVBJIFNITWFwSGFuZGxlKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd0RzdFByb2NJZCwgRFdPUkQgZHdTcmNQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdBY2Nlc3MsIERXT1JEIGR3T3B0aW9ucykKewogIEhBTkRMRSBoUmV0OwoKICBoUmV0ID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaFNoYXJlZCwgZHdEc3RQcm9jSWQsIGR3U3JjUHJvY0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd0FjY2VzcywgZHdPcHRpb25zKTsKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjEzXQogKgogKiBDcmVhdGUgYW5kIHJlZ2lzdGVyIGEgY2xpcGJvYXJkIGVudW1lcmF0b3IgZm9yIGEgd2ViIGJyb3dzZXIuCiAqCiAqIFBBUkFNUwogKiAgbHBCQyAgICAgIFtJXSBCaW5kaW5nIGNvbnRleHQKICogIGxwVW5rbm93biBbSV0gQW4gb2JqZWN0IGV4cG9zaW5nIHRoZSBJV2ViQnJvd3NlckFwcCBpbnRlcmZhY2UKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogIFRoZSBlbnVtZXJhdG9yIGlzIHN0b3JlZCBhcyBhIHByb3BlcnR5IG9mIHRoZSB3ZWIgYnJvd3Nlci4gSWYgaXQgZG9lcyBub3QKICogIHlldCBleGlzdCwgaXQgaXMgY3JlYXRlZCBhbmQgc2V0IGJlZm9yZSBiZWluZyByZWdpc3RlcmVkLgogKi8KSFJFU1VMVCBXSU5BUEkgUmVnaXN0ZXJEZWZhdWx0QWNjZXB0SGVhZGVycyhMUEJDIGxwQkMsIElVbmtub3duICpscFVua25vd24pCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pQcm9wZXJ0eVtdID0geyAneycsJ0QnLCcwJywnRicsJ0MnLCdBJywnNCcsJzInLCcwJywKICAgICAgJy0nLCdEJywnMycsJ0YnLCc1JywnLScsJzEnLCcxJywnQycsJ0YnLCAnLScsJ0InLCcyJywnMScsJzEnLCctJywnMCcsCiAgICAgICcwJywnQScsJ0EnLCcwJywnMCcsJzQnLCdBJywnRScsJzgnLCczJywnNycsJ30nLCdcMCcgfTsKICBJRW51bUZPUk1BVEVUQyogcElFbnVtRm9ybWF0RXRjID0gTlVMTDsKICBWQVJJQU5UQVJHIHZhcjsKICBIUkVTVUxUIGhSZXQ7CiAgSVdlYkJyb3dzZXJBcHAqIHBCcm93c2VyID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwgJXApXG4iLCBscEJDLCBscFVua25vd24pOwoKICAvKiBHZXQgQW4gSVdlYkJyb3dzZXJBcHAgaW50ZXJmYWNlIGZyb20gIGxwVW5rbm93biAqLwogIGhSZXQgPSBJVW5rbm93bl9RdWVyeVNlcnZpY2UobHBVbmtub3duLCAmSUlEX0lXZWJCcm93c2VyQXBwLCAmSUlEX0lXZWJCcm93c2VyQXBwLCAoUFZPSUQpJnBCcm93c2VyKTsKICBpZiAoRkFJTEVEKGhSZXQpIHx8ICFwQnJvd3NlcikKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwoKICBWX1ZUKCZ2YXIpID0gVlRfRU1QVFk7CgogIC8qIFRoZSBwcm9wZXJ0eSB3ZSBnZXQgaXMgdGhlIGJyb3dzZXJzIGNsaXBib2FyZCBlbnVtZXJhdG9yICovCiAgaFJldCA9IElXZWJCcm93c2VyQXBwX0dldFByb3BlcnR5KHBCcm93c2VyLCAoQlNUUilzelByb3BlcnR5LCAmdmFyKTsKICBpZiAoRkFJTEVEKGhSZXQpKQogICAgcmV0dXJuIGhSZXQ7CgogIGlmIChWX1ZUKCZ2YXIpID09IFZUX0VNUFRZKQogIHsKICAgIC8qIEl0ZXJhdGUgdGhyb3VnaCBhY2NlcHRlZCBkb2N1bWVudHMgYW5kIFJlZ2lzdGVyQ2xpcEJvYXJkRm9ybWF0QSgpIHRoZW0gKi8KICAgIGNoYXIgc3pLZXlCdWZmWzEyOF0sIHN6VmFsdWVCdWZmWzEyOF07CiAgICBEV09SRCBkd0tleVNpemUsIGR3VmFsdWVTaXplLCBkd1JldCA9IDAsIGR3Q291bnQgPSAwLCBkd051bVZhbHVlcywgZHdUeXBlOwogICAgRk9STUFURVRDKiBmb3JtYXRMaXN0LCAqZm9ybWF0OwogICAgSEtFWSBoRG9jczsKCiAgICBUUkFDRSgiUmVnaXN0ZXJpbmcgZm9ybWF0cyBhbmQgY3JlYXRpbmcgSUVudW1GT1JNQVRFVEMgaW5zdGFuY2VcbiIpOwoKICAgIGlmICghUmVnT3BlbktleUEoSEtFWV9MT0NBTF9NQUNISU5FLCAiU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudCIKICAgICAgICAgICAgICAgICAgICAgIlZlcnNpb25cXEludGVybmV0IFNldHRpbmdzXFxBY2NlcHRlZCBEb2N1bWVudHMiLCAmaERvY3MpKQogICAgICByZXR1cm4gRV9GQUlMOwoKICAgIC8qIEdldCBjb3VudCBvZiB2YWx1ZXMgaW4ga2V5ICovCiAgICB3aGlsZSAoIWR3UmV0KQogICAgewogICAgICBkd0tleVNpemUgPSBzaXplb2Yoc3pLZXlCdWZmKTsKICAgICAgZHdSZXQgPSBSZWdFbnVtVmFsdWVBKGhEb2NzLGR3Q291bnQsc3pLZXlCdWZmLCZkd0tleVNpemUsMCwmZHdUeXBlLDAsMCk7CiAgICAgIGR3Q291bnQrKzsKICAgIH0KCiAgICBkd051bVZhbHVlcyA9IGR3Q291bnQ7CgogICAgLyogTm90ZTogZHdDb3VudCA9IG51bWJlciBvZiBpdGVtcyArIDE7IFRoZSBleHRyYSBpdGVtIGlzIHRoZSBlbmQgbm9kZSAqLwogICAgZm9ybWF0ID0gZm9ybWF0TGlzdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkd0NvdW50ICogc2l6ZW9mKEZPUk1BVEVUQykpOwogICAgaWYgKCFmb3JtYXRMaXN0KQogICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBpZiAoZHdOdW1WYWx1ZXMgPiAxKQogICAgewogICAgICBkd1JldCA9IDA7CiAgICAgIGR3Q291bnQgPSAwOwoKICAgICAgZHdOdW1WYWx1ZXMtLTsKCiAgICAgIC8qIFJlZ2lzdGVyIGNsaXBib2FyZCBmb3JtYXRzIGZvciB0aGUgdmFsdWVzIGFuZCBwb3B1bGF0ZSBmb3JtYXQgbGlzdCAqLwogICAgICB3aGlsZSghZHdSZXQgJiYgZHdDb3VudCA8IGR3TnVtVmFsdWVzKQogICAgICB7CiAgICAgICAgZHdLZXlTaXplID0gc2l6ZW9mKHN6S2V5QnVmZik7CiAgICAgICAgZHdWYWx1ZVNpemUgPSBzaXplb2Yoc3pWYWx1ZUJ1ZmYpOwogICAgICAgIGR3UmV0ID0gUmVnRW51bVZhbHVlQShoRG9jcywgZHdDb3VudCwgc3pLZXlCdWZmLCAmZHdLZXlTaXplLCAwLCAmZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUEJZVEUpc3pWYWx1ZUJ1ZmYsICZkd1ZhbHVlU2l6ZSk7CiAgICAgICAgaWYgKCFkd1JldCkKICAgICAgICAgIHJldHVybiBFX0ZBSUw7CgogICAgICAgIGZvcm1hdC0+Y2ZGb3JtYXQgPSBSZWdpc3RlckNsaXBib2FyZEZvcm1hdEEoc3pWYWx1ZUJ1ZmYpOwogICAgICAgIGZvcm1hdC0+cHRkID0gTlVMTDsKICAgICAgICBmb3JtYXQtPmR3QXNwZWN0ID0gMTsKICAgICAgICBmb3JtYXQtPmxpbmRleCA9IDQ7CiAgICAgICAgZm9ybWF0LT50eW1lZCA9IC0xOwoKICAgICAgICBmb3JtYXQrKzsKICAgICAgICBkd0NvdW50Kys7CiAgICAgIH0KICAgIH0KCiAgICAvKiBUZXJtaW5hdGUgdGhlIChtYXliZSBlbXB0eSkgbGlzdCwgbGFzdCBlbnRyeSBoYXMgYSBjZkZvcm1hdCBvZiAwICovCiAgICBmb3JtYXQtPmNmRm9ybWF0ID0gMDsKICAgIGZvcm1hdC0+cHRkID0gTlVMTDsKICAgIGZvcm1hdC0+ZHdBc3BlY3QgPSAxOwogICAgZm9ybWF0LT5saW5kZXggPSA0OwogICAgZm9ybWF0LT50eW1lZCA9IC0xOwoKICAgIC8qIENyZWF0ZSBhIGNsaXBib2FyZCBlbnVtZXJhdG9yICovCiAgICBHRVRfRlVOQyhwQ3JlYXRlRm9ybWF0RW51bWVyYXRvciwgdXJsbW9uLCAiQ3JlYXRlRm9ybWF0RW51bWVyYXRvciIsIEVfRkFJTCk7CiAgICBoUmV0ID0gcENyZWF0ZUZvcm1hdEVudW1lcmF0b3IoZHdOdW1WYWx1ZXMsIGZvcm1hdExpc3QsICZwSUVudW1Gb3JtYXRFdGMpOwoKICAgIGlmIChGQUlMRUQoaFJldCkgfHwgIXBJRW51bUZvcm1hdEV0YykKICAgICAgcmV0dXJuIGhSZXQ7CgogICAgLyogU2V0IG91ciBlbnVtZXJhdG9yIGFzIHRoZSBicm93c2VycyBwcm9wZXJ0eSAqLwogICAgVl9WVCgmdmFyKSA9IFZUX1VOS05PV047CiAgICBWX1VOS05PV04oJnZhcikgPSAoSVVua25vd24qKXBJRW51bUZvcm1hdEV0YzsKCiAgICBoUmV0ID0gSVdlYkJyb3dzZXJBcHBfUHV0UHJvcGVydHkocEJyb3dzZXIsIChCU1RSKXN6UHJvcGVydHksIHZhcik7CiAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgewogICAgICAgSUVudW1GT1JNQVRFVENfUmVsZWFzZShwSUVudW1Gb3JtYXRFdGMpOwogICAgICAgZ290byBSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzX0V4aXQ7CiAgICB9CiAgfQoKICBpZiAoVl9WVCgmdmFyKSA9PSBWVF9VTktOT1dOKQogIHsKICAgIC8qIE91ciB2YXJpYW50IGlzIGhvbGRpbmcgdGhlIGNsaXBib2FyZCBlbnVtZXJhdG9yICovCiAgICBJVW5rbm93biogcElVbmtub3duID0gVl9VTktOT1dOKCZ2YXIpOwogICAgSUVudW1GT1JNQVRFVEMqIHBDbG9uZSA9IE5VTEw7CgogICAgVFJBQ0UoIlJldHJpZXZlZCBJRW51bUZPUk1BVEVUQyBwcm9wZXJ0eVxuIik7CgogICAgLyogR2V0IGFuIElFbnVtRm9ybWF0RXRjIGludGVyZmFjZSBmcm9tIHRoZSB2YXJpYW50cyB2YWx1ZSAqLwogICAgcElFbnVtRm9ybWF0RXRjID0gTlVMTDsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShwSVVua25vd24sICZJSURfSUVudW1GT1JNQVRFVEMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFBWT0lEKSZwSUVudW1Gb3JtYXRFdGMpOwogICAgaWYgKCFoUmV0ICYmIHBJRW51bUZvcm1hdEV0YykKICAgIHsKICAgICAgLyogQ2xvbmUgYW5kIHJlZ2lzdGVyIHRoZSBlbnVtZXJhdG9yICovCiAgICAgIGhSZXQgPSBJRW51bUZPUk1BVEVUQ19DbG9uZShwSUVudW1Gb3JtYXRFdGMsICZwQ2xvbmUpOwogICAgICBpZiAoIWhSZXQgJiYgcENsb25lKQogICAgICB7CiAgICAgICAgR0VUX0ZVTkMocFJlZ2lzdGVyRm9ybWF0RW51bWVyYXRvciwgdXJsbW9uLCAiUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yIiwgRV9GQUlMKTsKICAgICAgICBwUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yKGxwQkMsIHBDbG9uZSwgMCk7CgogICAgICAgIElFbnVtRk9STUFURVRDX1JlbGVhc2UocENsb25lKTsKICAgICAgfQoKICAgICAgLyogUmVsZWFzZSB0aGUgSUVudW1Gb3JtYXRFdGMgaW50ZXJmYWNlICovCiAgICAgIElFbnVtRk9STUFURVRDX1JlbGVhc2UocElVbmtub3duKTsKICAgIH0KICAgIElVbmtub3duX1JlbGVhc2UoVl9VTktOT1dOKCZ2YXIpKTsKICB9CgpSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzX0V4aXQ6CiAgSVdlYkJyb3dzZXJBcHBfUmVsZWFzZShwQnJvd3Nlcik7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNV0KICoKICogR2V0IEV4cGxvcmVycyAiQWNjZXB0TGFuZ3VhZ2UiIHNldHRpbmcuCiAqCiAqIFBBUkFNUwogKiAgbGFuZ2J1ZiBbT10gRGVzdGluYXRpb24gZm9yIGxhbmd1YWdlIHN0cmluZwogKiAgYnVmbGVuICBbSV0gTGVuZ3RoIG9mIGxhbmdidWYKICogICAgICAgICAgWzBdIFN1Y2Nlc3M6IHVzZWQgbGVuZ3RoIG9mIGxhbmdidWYKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gICBsYW5nYnVmIGlzIHNldCB0byB0aGUgbGFuZ3VhZ2Ugc3RyaW5nIGZvdW5kLgogKiAgRmFpbHVyZTogRV9GQUlMLCBJZiBhbnkgYXJndW1lbnRzIGFyZSBpbnZhbGlkLCBlcnJvciBvY2N1cnJlZCwgb3IgRXhwbG9yZXIKICogICAgICAgICAgIGRvZXMgbm90IGNvbnRhaW4gdGhlIHNldHRpbmcuCiAqICAgICAgICAgICBFX0lOVkFMSURBUkcsIElmIHRoZSBidWZmZXIgaXMgbm90IGJpZyBlbm91Z2gKICovCkhSRVNVTFQgV0lOQVBJIEdldEFjY2VwdExhbmd1YWdlc1coIExQV1NUUiBsYW5nYnVmLCBMUERXT1JEIGJ1ZmxlbikKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6a2V5V1tdID0gewoJJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAoJJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywKCSdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsJyAnLCdFJywneCcsJ3AnLCdsJywnbycsJ3InLCdlJywncicsJ1xcJywKCSdJJywnbicsJ3QnLCdlJywncicsJ24nLCdhJywndCcsJ2knLCdvJywnbicsJ2EnLCdsJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB2YWx1ZVdbXSA9IHsKCSdBJywnYycsJ2MnLCdlJywncCcsJ3QnLCdMJywnYScsJ24nLCdnJywndScsJ2EnLCdnJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgZW51c1dbXSA9IHsnZScsJ24nLCctJywndScsJ3MnLDB9OwogICAgRFdPUkQgbXlzdHJsZW4sIG15dHlwZTsKICAgIEhLRVkgbXlrZXk7CiAgICBIUkVTVUxUIHJldHZhbDsKICAgIExDSUQgbXlsY2lkOwogICAgV0NIQVIgKm15c3RyOwoKICAgIGlmKCFsYW5nYnVmIHx8ICFidWZsZW4gfHwgISpidWZsZW4pCglyZXR1cm4gRV9GQUlMOwoKICAgIG15c3RybGVuID0gKCpidWZsZW4gPiAyMCkgPyAqYnVmbGVuIDogMjAgOwogICAgbXlzdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSAqIG15c3RybGVuKTsKICAgIFJlZ09wZW5LZXlXKEhLRVlfQ1VSUkVOVF9VU0VSLCBzemtleVcsICZteWtleSk7CiAgICBpZihSZWdRdWVyeVZhbHVlRXhXKG15a2V5LCB2YWx1ZVcsIDAsICZteXR5cGUsIChQQllURSlteXN0ciwgJm15c3RybGVuKSkgewogICAgICAgIC8qIERpZCBub3QgZmluZCB2YWx1ZSAqLwogICAgICAgIG15bGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwogICAgICAgIC8qIHNvbWVob3cgdGhlIG15bGNpZCB0cmFuc2xhdGVzIGludG8gImVuLXVzIgogICAgICAgICAqICB0aGlzIGlzIHNpbWlsYXIgdG8gIkxPQ0FMRV9TQUJCUkVWTEFOR05BTUUiCiAgICAgICAgICogIHdoaWNoIGNvdWxkIGJlIGdvdHRlbiB2aWEgR2V0TG9jYWxlSW5mby4KICAgICAgICAgKiAgVGhlIG9ubHkgcHJvYmxlbSBpcyBMT0NBTEVfU0FCQlJFVkxBTkdVQUdFIiBpcwogICAgICAgICAqICBhIDMgY2hhciBzdHJpbmcgKGZpcnN0IDIgYXJlIGNvdW50cnkgY29kZSBhbmQgdGhpcmQgaXMKICAgICAgICAgKiAgbGV0dGVyIGZvciAic3VibGFuZ3VhZ2UiLCB3aGljaCBkb2VzIG5vdCBjb21lIGNsb3NlIHRvCiAgICAgICAgICogICJlbi11cyIKICAgICAgICAgKi8KICAgICAgICBsc3RyY3B5VyhteXN0ciwgZW51c1cpOwogICAgICAgIG15c3RybGVuID0gbHN0cmxlblcobXlzdHIpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBoYW5kbGUgcmV0dXJuZWQgc3RyaW5nICovCiAgICAgICAgRklYTUUoIm1pc3NpbmcgY29kZVxuIik7CiAgICB9CiAgICBtZW1jcHkoIGxhbmdidWYsIG15c3RyLCBtaW4oKmJ1ZmxlbixzdHJsZW5XKG15c3RyKSsxKSpzaXplb2YoV0NIQVIpICk7CgogICAgaWYoKmJ1ZmxlbiA+IHN0cmxlblcobXlzdHIpKSB7CgkqYnVmbGVuID0gc3RybGVuVyhteXN0cik7CglyZXR2YWwgPSBTX09LOwogICAgfSBlbHNlIHsKCSpidWZsZW4gPSAwOwoJcmV0dmFsID0gRV9JTlZBTElEQVJHOwoJU2V0TGFzdEVycm9yKEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpOwogICAgfQogICAgUmVnQ2xvc2VLZXkobXlrZXkpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXlzdHIpOwogICAgcmV0dXJuIHJldHZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE0XQogKgogKiBBc2NpaSB2ZXJzaW9uIG9mIEdldEFjY2VwdExhbmd1YWdlc1cuCiAqLwpIUkVTVUxUIFdJTkFQSSBHZXRBY2NlcHRMYW5ndWFnZXNBKCBMUFNUUiBsYW5nYnVmLCBMUERXT1JEIGJ1ZmxlbikKewogICAgV0NIQVIgKmxhbmdidWZXOwogICAgRFdPUkQgYnVmbGVuVywgY29udmxlbjsKICAgIEhSRVNVTFQgcmV0dmFsOwoKICAgIGlmKCFsYW5nYnVmIHx8ICFidWZsZW4gfHwgISpidWZsZW4pIHJldHVybiBFX0ZBSUw7CgogICAgYnVmbGVuVyA9ICpidWZsZW47CiAgICBsYW5nYnVmVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpICogYnVmbGVuVyk7CiAgICByZXR2YWwgPSBHZXRBY2NlcHRMYW5ndWFnZXNXKGxhbmdidWZXLCAmYnVmbGVuVyk7CgogICAgLyogRklYTUU6IHRoaXMgaXMgd3JvbmcsIHRoZSBzdHJpbmcgbWF5IG5vdCBiZSBudWxsLXRlcm1pbmF0ZWQgKi8KICAgIGNvbnZsZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgbGFuZ2J1ZlcsIC0xLCBsYW5nYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmJ1ZmxlbiwgTlVMTCwgTlVMTCk7CiAgICAqYnVmbGVuID0gYnVmbGVuVyA/IGNvbnZsZW4gOiAwOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxhbmdidWZXKTsKICAgIHJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yM10KICoKICogQ29udmVydCBhIEdVSUQgdG8gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgZ3VpZCAgICAgW0ldIEdVSUQgdG8gY29udmVydAogKiAgbHBzekRlc3QgW09dIERlc3RpbmF0aW9uIGZvciBzdHJpbmcKICogIGNjaE1heCAgIFtJXSBMZW5ndGggb2Ygb3V0cHV0IGJ1ZmZlcgogKgogKiBSRVRVUk5TCiAqICBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgY3JlYXRlZC4KICovCklOVCBXSU5BUEkgU0hTdHJpbmdGcm9tR1VJREEoUkVGR1VJRCBndWlkLCBMUFNUUiBscHN6RGVzdCwgSU5UIGNjaE1heCkKewogIGNoYXIgeGd1aWRbNDBdOwogIElOVCBpTGVuOwoKICBUUkFDRSgiKCVzLCVwLCVkKVxuIiwgZGVidWdzdHJfZ3VpZChndWlkKSwgbHBzekRlc3QsIGNjaE1heCk7CgogIHNwcmludGYoeGd1aWQsICJ7JTA4bFgtJTA0WC0lMDRYLSUwMlglMDJYLSUwMlglMDJYJTAyWCUwMlglMDJYJTAyWH0iLAogICAgICAgICAgZ3VpZC0+RGF0YTEsIGd1aWQtPkRhdGEyLCBndWlkLT5EYXRhMywKICAgICAgICAgIGd1aWQtPkRhdGE0WzBdLCBndWlkLT5EYXRhNFsxXSwgZ3VpZC0+RGF0YTRbMl0sIGd1aWQtPkRhdGE0WzNdLAogICAgICAgICAgZ3VpZC0+RGF0YTRbNF0sIGd1aWQtPkRhdGE0WzVdLCBndWlkLT5EYXRhNFs2XSwgZ3VpZC0+RGF0YTRbN10pOwoKICBpTGVuID0gc3RybGVuKHhndWlkKSArIDE7CgogIGlmIChpTGVuID4gY2NoTWF4KQogICAgcmV0dXJuIDA7CiAgbWVtY3B5KGxwc3pEZXN0LCB4Z3VpZCwgaUxlbik7CiAgcmV0dXJuIGlMZW47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNF0KICoKICogQ29udmVydCBhIEdVSUQgdG8gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgZ3VpZCBbSV0gR1VJRCB0byBjb252ZXJ0CiAqICBzdHIgIFtPXSBEZXN0aW5hdGlvbiBmb3Igc3RyaW5nCiAqICBjbWF4IFtJXSBMZW5ndGggb2Ygb3V0cHV0IGJ1ZmZlcgogKgogKiBSRVRVUk5TCiAqICBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgY3JlYXRlZC4KICovCklOVCBXSU5BUEkgU0hTdHJpbmdGcm9tR1VJRFcoUkVGR1VJRCBndWlkLCBMUFdTVFIgbHBzekRlc3QsIElOVCBjY2hNYXgpCnsKICBXQ0hBUiB4Z3VpZFs0MF07CiAgSU5UIGlMZW47CiAgc3RhdGljIGNvbnN0IFdDSEFSIHdzekZvcm1hdFtdID0geyd7JywnJScsJzAnLCc4JywnbCcsJ1gnLCctJywnJScsJzAnLCc0JywnWCcsJy0nLCclJywnMCcsJzQnLCdYJywnLScsCiAgICAgICclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJy0nLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLAogICAgICAnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnfScsMH07CgogIFRSQUNFKCIoJXMsJXAsJWQpXG4iLCBkZWJ1Z3N0cl9ndWlkKGd1aWQpLCBscHN6RGVzdCwgY2NoTWF4KTsKCiAgc3ByaW50ZlcoeGd1aWQsIHdzekZvcm1hdCwgZ3VpZC0+RGF0YTEsIGd1aWQtPkRhdGEyLCBndWlkLT5EYXRhMywKICAgICAgICAgIGd1aWQtPkRhdGE0WzBdLCBndWlkLT5EYXRhNFsxXSwgZ3VpZC0+RGF0YTRbMl0sIGd1aWQtPkRhdGE0WzNdLAogICAgICAgICAgZ3VpZC0+RGF0YTRbNF0sIGd1aWQtPkRhdGE0WzVdLCBndWlkLT5EYXRhNFs2XSwgZ3VpZC0+RGF0YTRbN10pOwoKICBpTGVuID0gc3RybGVuVyh4Z3VpZCkgKyAxOwoKICBpZiAoaUxlbiA+IGNjaE1heCkKICAgIHJldHVybiAwOwogIG1lbWNweShscHN6RGVzdCwgeGd1aWQsIGlMZW4qc2l6ZW9mKFdDSEFSKSk7CiAgcmV0dXJuIGlMZW47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOV0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgYSBzcGFjZS4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIHNwYWNlLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyU3BhY2VXKFdDSEFSIHdjKQp7CiAgICBXT1JEIENoYXJUeXBlOwoKICAgIHJldHVybiBHZXRTdHJpbmdUeXBlVyhDVF9DVFlQRTEsICZ3YywgMSwgJkNoYXJUeXBlKSAmJiAoQ2hhclR5cGUgJiBDMV9TUEFDRSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMF0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgYSBibGFuay4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIGJsYW5rLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyQmxhbmtXKFdDSEFSIHdjKQp7CiAgICBXT1JEIENoYXJUeXBlOwoKICAgIHJldHVybiBHZXRTdHJpbmdUeXBlVyhDVF9DVFlQRTEsICZ3YywgMSwgJkNoYXJUeXBlKSAmJiAoQ2hhclR5cGUgJiBDMV9CTEFOSyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMV0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgcHVuY3R1YXRpb24uCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgcHVuY3R1YXRpb24sCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJQdW5jdFcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX1BVTkNUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMyXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGNvbnRyb2wgY2hhcmFjdGVyLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgY29udHJvbCBjaGFyYWN0ZXIsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJDbnRybFcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX0NOVFJMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGRpZ2l0LgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgZGlnaXQsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJEaWdpdFcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX0RJR0lUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM0XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGhleCBkaWdpdC4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIGhleCBkaWdpdCwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhclhEaWdpdFcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX1hESUdJVCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNV0KICoKICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGUzRXhXKExQV1NUUiBscHN6U3RyLCBEV09SRCBkd0xlbiwgTFBWT0lEIHAzKQp7CiAgICBGSVhNRSgiKCVzLDB4JTA4bHgsJXApOiBzdHViXG4iLCBkZWJ1Z3N0cl93KGxwc3pTdHIpLCBkd0xlbiwgcDMpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNl0KICoKICogSW5zZXJ0IGEgYml0bWFwIG1lbnUgaXRlbSBhdCB0aGUgYm90dG9tIG9mIGEgbWVudS4KICoKICogUEFSQU1TCiAqICBoTWVudSBbSV0gTWVudSB0byBpbnNlcnQgaW50bwogKiAgZmxhZ3MgW0ldIEZsYWdzIGZvciBpbnNlcnRpb24KICogIGlkICAgIFtJXSBNZW51IElEIG9mIHRoZSBpdGVtCiAqICBzdHIgICBbSV0gTWVudSB0ZXh0IGZvciB0aGUgaXRlbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLCAgdGhlIGl0ZW0gaXMgaW5zZXJ0ZWQgaW50byB0aGUgbWVudQogKiAgRmFpbHVyZTogRkFMU0UsIGlmIGFueSBwYXJhbWV0ZXIgaXMgaW52YWxpZAogKi8KQk9PTCBXSU5BUEkgQXBwZW5kTWVudVdyYXBXKEhNRU5VIGhNZW51LCBVSU5UIGZsYWdzLCBVSU5UIGlkLCBMUENXU1RSIHN0cikKewogICAgVFJBQ0UoIiglcCwweCUwOHgsMHglMDh4LCVzKVxuIixoTWVudSwgZmxhZ3MsIGlkLCBkZWJ1Z3N0cl93KHN0cikpOwogICAgcmV0dXJuIEluc2VydE1lbnVXKGhNZW51LCAtMSwgZmxhZ3MgfCBNRl9CSVRNQVAsIGlkLCBzdHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNzRdCiAqCiAqIEdldCB0aGUgdGV4dCBmcm9tIGEgZ2l2ZW4gZGlhbG9nIGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgW0ldIEhhbmRsZSBvZiBkaWFsb2cKICogIG5JdGVtICAgIFtJXSBJbmRleCBvZiBpdGVtCiAqICBscHNEZXN0ICBbT10gQnVmZmVyIGZvciByZWNlaXZpbmcgd2luZG93IHRleHQKICogIG5EZXN0TGVuIFtJXSBMZW5ndGggb2YgYnVmZmVyLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgbGVuZ3RoIG9mIHRoZSByZXR1cm5lZCB0ZXh0LgogKiAgRmFpbHVyZTogMC4KICovCklOVCBXSU5BUEkgR2V0RGxnSXRlbVRleHRXcmFwVyhIV05EIGhXbmQsIElOVCBuSXRlbSwgTFBXU1RSIGxwc0Rlc3QsSU5UIG5EZXN0TGVuKQp7CiAgSFdORCBoSXRlbSA9IEdldERsZ0l0ZW0oaFduZCwgbkl0ZW0pOwoKICBpZiAoaEl0ZW0pCiAgICByZXR1cm4gR2V0V2luZG93VGV4dFcoaEl0ZW0sIGxwc0Rlc3QsIG5EZXN0TGVuKTsKICBpZiAobkRlc3RMZW4pCiAgICAqbHBzRGVzdCA9IChXQ0hBUiknXDAnOwogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICBbU0hMV0FQSS4xMzhdCiAqCiAqIFNldCB0aGUgdGV4dCBvZiBhIGdpdmVuIGRpYWxvZyBpdGVtLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgIFtJXSBIYW5kbGUgb2YgZGlhbG9nCiAqICBpSXRlbSAgICBbSV0gSW5kZXggb2YgaXRlbQogKiAgbHBzelRleHQgW09dIFRleHQgdG8gc2V0CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuICBUaGUgdGV4dCBvZiB0aGUgZGlhbG9nIGlzIHNldCB0byBscHN6VGV4dC4KICogIEZhaWx1cmU6IEZBTFNFLCBPdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTZXREbGdJdGVtVGV4dFdyYXBXKEhXTkQgaFduZCwgSU5UIGlJdGVtLCBMUENXU1RSIGxwc3pUZXh0KQp7CiAgICBIV05EIGhXbmRJdGVtID0gR2V0RGxnSXRlbShoV25kLCBpSXRlbSk7CiAgICBpZiAoaFduZEl0ZW0pCiAgICAgICAgcmV0dXJuIFNldFdpbmRvd1RleHRXKGhXbmRJdGVtLCBscHN6VGV4dCk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTFdCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MgdXAgdG8gYSBnaXZlbiBsZW5ndGguCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKiAgbGVuICAgICBbSV0gTWF4aW11bSBsZW5ndGgKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5DQShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXAsIElOVCBsZW4pCnsKICAgIHJldHVybiBzdHJuY21wKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTJdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBOQ0EuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wTkNXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wLCBJTlQgbGVuKQp7CiAgICByZXR1cm4gc3RybmNtcFcobHBzelNyYywgbHBzekNtcCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1M10KICoKICogQ29tcGFyZSB0d28gQXNjaWkgc3RyaW5ncyB1cCB0byBhIGdpdmVuIGxlbmd0aCwgaWdub3JpbmcgY2FzZS4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTb3VyY2Ugc3RyaW5nCiAqICBscHN6Q21wIFtJXSBTdHJpbmcgdG8gY29tcGFyZSB0byBscHN6U3JjCiAqICBsZW4gICAgIFtJXSBNYXhpbXVtIGxlbmd0aAogKgogKiBSRVRVUk5TCiAqICBBIG51bWJlciBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICBscHN6U3JjIGlzIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxwc3pDbXAuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wTklDQShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXAsIERXT1JEIGxlbikKewogICAgcmV0dXJuIHN0cm5jYXNlY21wKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTRdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBOSUNBLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5JQ1coTFBDV1NUUiBscHN6U3JjLCBMUENXU1RSIGxwc3pDbXAsIERXT1JEIGxlbikKewogICAgcmV0dXJuIHN0cm5jbXBpVyhscHN6U3JjLCBscHN6Q21wLCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTU1XQogKgogKiBDb21wYXJlIHR3byBBc2NpaSBzdHJpbmdzLgogKgogKiBQQVJBTVMKICogIGxwc3pTcmMgW0ldIFNvdXJjZSBzdHJpbmcKICogIGxwc3pDbXAgW0ldIFN0cmluZyB0byBjb21wYXJlIHRvIGxwc3pTcmMKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcENBKExQQ1NUUiBscHN6U3JjLCBMUENTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNtcChscHN6U3JjLCBscHN6Q21wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1Nl0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFN0ckNtcENBLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcENXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gc3RyY21wVyhscHN6U3JjLCBscHN6Q21wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1N10KICoKICogQ29tcGFyZSB0d28gQXNjaWkgc3RyaW5ncywgaWdub3JpbmcgY2FzZS4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTb3VyY2Ugc3RyaW5nCiAqICBscHN6Q21wIFtJXSBTdHJpbmcgdG8gY29tcGFyZSB0byBscHN6U3JjCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBJQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gc3RyY2FzZWNtcChscHN6U3JjLCBscHN6Q21wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFN0ckNtcElDQS4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBJQ1coTFBDV1NUUiBscHN6U3JjLCBMUENXU1RSIGxwc3pDbXApCnsKICAgIHJldHVybiBzdHJjbXBpVyhscHN6U3JjLCBscHN6Q21wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2MF0KICoKICogR2V0IGFuIGlkZW50aWZpY2F0aW9uIHN0cmluZyBmb3IgdGhlIE9TIGFuZCBleHBsb3Jlci4KICoKICogUEFSQU1TCiAqICBscHN6RGVzdCAgW09dIERlc3RpbmF0aW9uIGZvciBJZCBzdHJpbmcKICogIGR3RGVzdExlbiBbSV0gTGVuZ3RoIG9mIGxwc3pEZXN0CiAqCiAqIFJFVFVSTlMKICogIFRSVUUsICBJZiB0aGUgc3RyaW5nIHdhcyBjcmVhdGVkIHN1Y2Nlc3NmdWxseQogKiAgRkFMU0UsIE90aGVyd2lzZQogKi8KQk9PTCBXSU5BUEkgU0hBYm91dEluZm9BKExQU1RSIGxwc3pEZXN0LCBEV09SRCBkd0Rlc3RMZW4pCnsKICBXQ0hBUiBidWZmWzIwODRdOwoKICBUUkFDRSgiKCVwLCVsZClcbiIsIGxwc3pEZXN0LCBkd0Rlc3RMZW4pOwoKICBpZiAobHBzekRlc3QgJiYgU0hBYm91dEluZm9XKGJ1ZmYsIGR3RGVzdExlbikpCiAgewogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGJ1ZmYsIC0xLCBscHN6RGVzdCwgZHdEZXN0TGVuLCBOVUxMLCBOVUxMKTsKICAgIHJldHVybiBUUlVFOwogIH0KICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjFdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSEFib3V0SW5mb0EuCiAqLwpCT09MIFdJTkFQSSBTSEFib3V0SW5mb1coTFBXU1RSIGxwc3pEZXN0LCBEV09SRCBkd0Rlc3RMZW4pCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pJRUtleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsCiAgICAnICcsJ0UnLCd4JywncCcsJ2wnLCdvJywncicsJ2UnLCdyJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6V2luTnRLZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJyAnLAogICAgJ04nLCdUJywnXFwnLCdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzeldpbktleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6UmVnS2V5W10gPSB7ICdTJywnTycsJ0YnLCdUJywnVycsJ0EnLCdSJywnRScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ0knLCduJywndCcsJ2UnLCdyJywnbicsJ2UnLCd0JywKICAgICcgJywnRScsJ3gnLCdwJywnbCcsJ28nLCdyJywnZScsJ3InLCdcXCcsCiAgICAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ2EnLCd0JywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6VmVyc2lvbltdID0geyAnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekN1c3RvbWl6ZWRbXSA9IHsgJ0MnLCd1JywncycsJ3QnLCdvJywnbScsJ2knLCd6JywnZScsJ2QnLAogICAgJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pPd25lcltdID0geyAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywnZScsJ3InLCdlJywnZCcsCiAgICAnTycsJ3cnLCduJywnZScsJ3InLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pPcmdbXSA9IHsgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ2UnLCdyJywnZScsJ2QnLAogICAgJ08nLCdyJywnZycsJ2EnLCduJywnaScsJ3onLCdhJywndCcsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelByb2R1Y3RbXSA9IHsgJ1AnLCdyJywnbycsJ2QnLCd1JywnYycsJ3QnLCdJJywnZCcsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelVwZGF0ZVtdID0geyAnSScsJ0UnLCdBJywnSycsCiAgICAnVScsJ3AnLCdkJywnYScsJ3QnLCdlJywnVScsJ3InLCdsJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6SGVscFtdID0geyAnSScsJ0UnLCdBJywnSycsCiAgICAnSCcsJ2UnLCdsJywncCcsJ1MnLCd0JywncicsJ2knLCduJywnZycsJ1wwJyB9OwogIFdDSEFSIGJ1ZmZbMjA4NF07CiAgSEtFWSBoUmVnOwogIERXT1JEIGR3VHlwZSwgZHdMZW47CgogIFRSQUNFKCIoJXAsJWxkKVxuIiwgbHBzekRlc3QsIGR3RGVzdExlbik7CgogIGlmICghbHBzekRlc3QpCiAgICByZXR1cm4gRkFMU0U7CgogICpscHN6RGVzdCA9ICdcMCc7CgogIC8qIFRyeSB0aGUgTlQga2V5IGZpcnN0LCBmb2xsb3dlZCBieSA5NS85OCBrZXkgKi8KICBpZiAoUmVnT3BlbktleUV4VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6V2luTnRLZXksIDAsIEtFWV9SRUFELCAmaFJlZykgJiYKICAgICAgUmVnT3BlbktleUV4VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6V2luS2V5LCAwLCBLRVlfUkVBRCwgJmhSZWcpKQogICAgcmV0dXJuIEZBTFNFOwoKICAvKiBPUyBWZXJzaW9uICovCiAgYnVmZlswXSA9ICdcMCc7CiAgZHdMZW4gPSAzMDsKICBpZiAoIVNIR2V0VmFsdWVXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pJRUtleSwgc3pWZXJzaW9uLCAmZHdUeXBlLCBidWZmLCAmZHdMZW4pKQogIHsKICAgIERXT1JEIGR3U3RyTGVuID0gc3RybGVuVyhidWZmKTsKICAgIGR3TGVuID0gMzAgLSBkd1N0ckxlbjsKICAgIFNIR2V0VmFsdWVXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pJRUtleSwKICAgICAgICAgICAgICAgIHN6Q3VzdG9taXplZCwgJmR3VHlwZSwgYnVmZitkd1N0ckxlbiwgJmR3TGVuKTsKICB9CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5SZWdpc3RlcmVkIE93bmVyICovCiAgYnVmZlswXSA9ICd+JzsKICBkd0xlbiA9IDI1NjsKICBpZiAoU0hHZXRWYWx1ZVcoaFJlZywgc3pPd25lciwgMCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5SZWdpc3RlcmVkIE9yZ2FuaXphdGlvbiAqLwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhoUmVnLCBzek9yZywgMCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIEZJWE1FOiBOb3Qgc3VyZSB3aGVyZSB0aGlzIG51bWJlciBjb21lcyBmcm9tICAqLwogIGJ1ZmZbMF0gPSAnfic7CiAgYnVmZlsxXSA9ICcwJzsKICBidWZmWzJdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflByb2R1Y3QgSWQgKi8KICBkd0xlbiA9IDI1NjsKICBpZiAoU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzelJlZ0tleSwgc3pQcm9kdWN0LCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogfklFIFVwZGF0ZSBVcmwgKi8KICBkd0xlbiA9IDIwNDg7CiAgaWYoU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeldpbktleSwgc3pVcGRhdGUsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+SUUgSGVscCBTdHJpbmcgKi8KICBkd0xlbiA9IDI1NjsKICBpZihTSEdldFZhbHVlVyhoUmVnLCBzekhlbHAsIDAsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICBSZWdDbG9zZUtleShoUmVnKTsKICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2M10KICoKICogQ2FsbCBJT2xlQ29tbWFuZFRhcmdldF9RdWVyeVN0YXR1cygpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gICAgIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbW1hbmRUYXJnZXQgaW50ZXJmYWNlCiAqICBwZ3VpZENtZEdyb3VwIFtJXSBHVUlEIGZvciB0aGUgY29tbWFuZCBncm91cAogKiAgY0NtZHMgICAgICAgICBbSV0KICogIHByZ0NtZHMgICAgICAgW09dIENvbW1hbmRzCiAqICBwQ21kVGV4dCAgICAgIFtPXSBDb21tYW5kIHRleHQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJT2xlQ29tbWFuZFRhcmdldC4KICogICAgICAgICAgIE90aGVyd2lzZSwgYW4gZXJyb3IgY29kZSBmcm9tIElPbGVDb21tYW5kVGFyZ2V0X1F1ZXJ5U3RhdHVzKCkuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVN0YXR1cyhJVW5rbm93biogbHBVbmtub3duLCBSRUZHVUlEIHBndWlkQ21kR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGNDbWRzLCBPTEVDTUQgKnByZ0NtZHMsIE9MRUNNRFRFWFQqIHBDbWRUZXh0KQp7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwLCVsZCwlcCwlcClcbiIsbHBVbmtub3duLCBwZ3VpZENtZEdyb3VwLCBjQ21kcywgcHJnQ21kcywgcENtZFRleHQpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIElPbGVDb21tYW5kVGFyZ2V0KiBscE9sZTsKCiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb21tYW5kVGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwT2xlKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwT2xlKQogICAgewogICAgICBoUmV0ID0gSU9sZUNvbW1hbmRUYXJnZXRfUXVlcnlTdGF0dXMobHBPbGUsIHBndWlkQ21kR3JvdXAsIGNDbWRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJnQ21kcywgcENtZFRleHQpOwogICAgICBJT2xlQ29tbWFuZFRhcmdldF9SZWxlYXNlKGxwT2xlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAkJW1NITFdBUEkuMTY0XQogKgogKiBDYWxsIElPbGVDb21tYW5kVGFyZ2V0X0V4ZWMoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duICAgICBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElPbGVDb21tYW5kVGFyZ2V0IGludGVyZmFjZQogKiAgcGd1aWRDbWRHcm91cCBbSV0gR1VJRCBmb3IgdGhlIGNvbW1hbmQgZ3JvdXAKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJT2xlQ29tbWFuZFRhcmdldC4KICogICAgICAgICAgIE90aGVyd2lzZSwgYW4gZXJyb3IgY29kZSBmcm9tIElPbGVDb21tYW5kVGFyZ2V0X0V4ZWMoKS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0V4ZWMoSVVua25vd24qIGxwVW5rbm93biwgUkVGR1VJRCBwZ3VpZENtZEdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBuQ21kSUQsIERXT1JEIG5DbWRleGVjb3B0LCBWQVJJQU5UKiBwdmFJbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFSSUFOVCogcHZhT3V0KQp7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwLCVsZCwlbGQsJXAsJXApXG4iLGxwVW5rbm93biwgcGd1aWRDbWRHcm91cCwgbkNtZElELAogICAgICAgIG5DbWRleGVjb3B0LCBwdmFJbiwgcHZhT3V0KTsKCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBJT2xlQ29tbWFuZFRhcmdldCogbHBPbGU7CgogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlQ29tbWFuZFRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscE9sZSk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwT2xlKQogICAgewogICAgICBoUmV0ID0gSU9sZUNvbW1hbmRUYXJnZXRfRXhlYyhscE9sZSwgcGd1aWRDbWRHcm91cCwgbkNtZElELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuQ21kZXhlY29wdCwgcHZhSW4sIHB2YU91dCk7CiAgICAgIElPbGVDb21tYW5kVGFyZ2V0X1JlbGVhc2UobHBPbGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2NV0KICoKICogUmV0cmlldmUsIG1vZGlmeSwgYW5kIHJlLXNldCBhIHZhbHVlIGZyb20gYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgIFtJXSBXaW5kb3cgdG8gZ2V0IHZhbHVlIGZyb20KICogIG9mZnNldCBbSV0gT2Zmc2V0IG9mIHZhbHVlCiAqICB3TWFzayAgW0ldIE1hc2sgZm9yIHVpRmxhZ3MKICogIHdGbGFncyBbSV0gQml0cyB0byBzZXQgaW4gd2luZG93IHZhbHVlCiAqCiAqIFJFVFVSTlMKICogIFRoZSBuZXcgdmFsdWUgYXMgaXQgd2FzIHNldCwgb3IgMCBpZiBhbnkgcGFyYW1ldGVyIGlzIGludmFsaWQuCiAqCiAqIE5PVEVTCiAqICBBbnkgYml0cyBzZXQgaW4gdWlNYXNrIGFyZSBjbGVhcmVkIGZyb20gdGhlIHZhbHVlLCB0aGVuIGFueSBiaXRzIHNldCBpbgogKiAgdWlGbGFncyBhcmUgc2V0IGluIHRoZSB2YWx1ZS4KICovCkxPTkcgV0lOQVBJIFNIU2V0V2luZG93Qml0cyhIV05EIGh3bmQsIElOVCBvZmZzZXQsIFVJTlQgd01hc2ssIFVJTlQgd0ZsYWdzKQp7CiAgTE9ORyByZXQgPSBHZXRXaW5kb3dMb25nQShod25kLCBvZmZzZXQpOwogIExPTkcgbmV3RmxhZ3MgPSAod0ZsYWdzICYgd01hc2spIHwgKHJldCAmIH53RmxhZ3MpOwoKICBpZiAobmV3RmxhZ3MgIT0gcmV0KQogICAgcmV0ID0gU2V0V2luZG93TG9uZ0EoaHduZCwgb2Zmc2V0LCBuZXdGbGFncyk7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2N10KICoKICogQ2hhbmdlIGEgd2luZG93J3MgcGFyZW50LgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgW0ldIFdpbmRvdyB0byBjaGFuZ2UgcGFyZW50IG9mCiAqICBoV25kUGFyZW50IFtJXSBOZXcgcGFyZW50IHdpbmRvdwogKgogKiBSRVRVUk5TCiAqICBUaGUgb2xkIHBhcmVudCBvZiBoV25kLgogKgogKiBOT1RFUwogKiAgSWYgaFduZFBhcmVudCBpcyBOVUxMIChkZXNrdG9wKSwgdGhlIHdpbmRvdyBzdHlsZSBpcyBjaGFuZ2VkIHRvIFdTX1BPUFVQLgogKiAgSWYgaFduZFBhcmVudCBpcyBOT1QgTlVMTCB0aGVuIHdlIHNldCB0aGUgV1NfQ0hJTEQgc3R5bGUuCiAqLwpIV05EIFdJTkFQSSBTSFNldFBhcmVudEh3bmQoSFdORCBoV25kLCBIV05EIGhXbmRQYXJlbnQpCnsKICBUUkFDRSgiJXAsICVwXG4iLCBoV25kLCBoV25kUGFyZW50KTsKCiAgaWYoR2V0UGFyZW50KGhXbmQpID09IGhXbmRQYXJlbnQpCiAgICByZXR1cm4gMDsKCiAgaWYoaFduZFBhcmVudCkKICAgIFNIU2V0V2luZG93Qml0cyhoV25kLCBHV0xfU1RZTEUsIFdTX0NISUxELCBXU19DSElMRCk7CiAgZWxzZQogICAgU0hTZXRXaW5kb3dCaXRzKGhXbmQsIEdXTF9TVFlMRSwgV1NfUE9QVVAsIFdTX1BPUFVQKTsKCiAgcmV0dXJuIFNldFBhcmVudChoV25kLCBoV25kUGFyZW50KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjE2OF0KICoKICogTG9jYXRlIGFuZCBhZHZpc2UgYSBjb25uZWN0aW9uIHBvaW50IGluIGFuIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rU2luayAgIFtJXSBTaW5rIGZvciB0aGUgY29ubmVjdGlvbiBwb2ludCBhZHZpc2UgY2FsbAogKiAgcmlpZCAgICAgICAgW0ldIFJFRklJRCBvZiBjb25uZWN0aW9uIHBvaW50IHRvIGFkdmlzZQogKiAgYkFkdmlzZU9ubHkgW0ldIFRSVUUgPSBBZHZpc2Ugb25seSwgRkFMU0UgPSBVbmFkdmlzZSBmaXJzdAogKiAgbHBVbmtub3duICAgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIGludGVyZmFjZQogKiAgbHBDb29raWUgICAgW09dIFBvaW50ZXIgdG8gY29ubmVjdGlvbiBwb2ludCBjb29raWUKICogIGxwcENQICAgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIElDb25uZWN0aW9uUG9pbnQgZm91bmQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gSWYgbHBwQ1AgaXMgbm9uLU5VTEwsIGl0IGlzIGZpbGxlZCB3aXRoIHRoZSBJQ29ubmVjdGlvblBvaW50CiAqICAgICAgICAgICB0aGF0IHdhcyBhZHZpc2VkLiBUaGUgY2FsbGVyIGlzIHJlc3BvbnNhYmxlIGZvciByZWxlYXNpbmcgaXQuCiAqICBGYWlsdXJlOiBFX0ZBSUwsIGlmIGFueSBhcmd1bWVudHMgYXJlIGludmFsaWQuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gaXNuJ3QgYW4gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwKICogICAgICAgICAgIE9yIGFuIEhSRVNVTFQgZXJyb3IgY29kZSBpZiBhbnkgY2FsbCBmYWlscy4KICovCkhSRVNVTFQgV0lOQVBJIENvbm5lY3RUb0Nvbm5lY3Rpb25Qb2ludChJVW5rbm93biogbHBVbmtTaW5rLCBSRUZJSUQgcmlpZCwgQk9PTCBiQWR2aXNlT25seSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24qIGxwVW5rbm93biwgTFBEV09SRCBscENvb2tpZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNvbm5lY3Rpb25Qb2ludCAqKmxwcENQKQp7CiAgSFJFU1VMVCBoUmV0OwogIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIqIGxwQ29udGFpbmVyOwogIElDb25uZWN0aW9uUG9pbnQgKmxwQ1A7CgogIGlmKCFscFVua25vd24gfHwgKGJBZHZpc2VPbmx5ICYmICFscFVua1NpbmspKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgaWYobHBwQ1ApCiAgICAqbHBwQ1AgPSBOVUxMOwoKICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lDb25uZWN0aW9uUG9pbnRDb250YWluZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwQ29udGFpbmVyKTsKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyX0ZpbmRDb25uZWN0aW9uUG9pbnQobHBDb250YWluZXIsIHJpaWQsICZscENQKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogICAgewogICAgICBpZighYkFkdmlzZU9ubHkpCiAgICAgICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfVW5hZHZpc2UobHBDUCwgKmxwQ29va2llKTsKICAgICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfQWR2aXNlKGxwQ1AsIGxwVW5rU2luaywgbHBDb29raWUpOwoKICAgICAgaWYgKEZBSUxFRChoUmV0KSkKICAgICAgICAqbHBDb29raWUgPSAwOwoKICAgICAgaWYgKGxwcENQICYmIFNVQ0NFRURFRChoUmV0KSkKICAgICAgICAqbHBwQ1AgPSBscENQOyAvKiBDYWxsZXIga2VlcHMgdGhlIGludGVyZmFjZSAqLwogICAgICBlbHNlCiAgICAgICAgSUNvbm5lY3Rpb25Qb2ludF9SZWxlYXNlKGxwQ1ApOyAvKiBSZWxlYXNlIGl0ICovCiAgICB9CgogICAgSVVua25vd25fUmVsZWFzZShscENvbnRhaW5lcik7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglACVtTSExXQVBJLjE2OV0KICoKICogUmVsZWFzZSBhbiBpbnRlcmZhY2UuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gcmVsZWFzZQogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KRFdPUkQgV0lOQVBJIElVbmtub3duX0F0b21pY1JlbGVhc2UoSVVua25vd24gKiogbHBVbmtub3duKQp7CiAgICBJVW5rbm93biAqdGVtcDsKCiAgICBUUkFDRSgiKCVwKVxuIixscFVua25vd24pOwoKICAgIGlmKCFscFVua25vd24gfHwgISooKExQRFdPUkQpbHBVbmtub3duKSkgcmV0dXJuIDA7CiAgICB0ZW1wID0gKmxwVW5rbm93bjsKICAgICpscFVua25vd24gPSBOVUxMOwoKICAgIFRSQUNFKCJkb2luZyBSZWxlYXNlXG4iKTsKCiAgICByZXR1cm4gSVVua25vd25fUmVsZWFzZSh0ZW1wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3MF0KICoKICogU2tpcCAnLy8nIGlmIHByZXNlbnQgaW4gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU3RyaW5nIHRvIGNoZWNrIGZvciAnLy8nCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBuZXh0IGNoYXJhY3RlciBhZnRlciB0aGUgJy8vJyBvciB0aGUgc3RyaW5nIGlmIG5vdCBwcmVzZW50CiAqICBGYWlsdXJlOiBOVUxMLCBpZiBscHN6U3RyIGlzIE5VTEwuCiAqLwpMUENTVFIgV0lOQVBJIFBhdGhTa2lwTGVhZGluZ1NsYXNoZXNBKExQQ1NUUiBscHN6U3JjKQp7CiAgaWYgKGxwc3pTcmMgJiYgbHBzelNyY1swXSA9PSAnLycgJiYgbHBzelNyY1sxXSA9PSAnLycpCiAgICBscHN6U3JjICs9IDI7CiAgcmV0dXJuIGxwc3pTcmM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAkJW1NITFdBUEkuMTcxXQogKgogKiBDaGVjayBpZiB0d28gaW50ZXJmYWNlcyBjb21lIGZyb20gdGhlIHNhbWUgb2JqZWN0LgogKgogKiBQQVJBTVMKICogICBscEludDEgW0ldIEludGVyZmFjZSB0byBjaGVjayBhZ2FpbnN0IGxwSW50Mi4KICogICBscEludDIgW0ldIEludGVyZmFjZSB0byBjaGVjayBhZ2FpbnN0IGxwSW50MS4KICoKICogUkVUVVJOUwogKiAgIFRSVUUsIElmIHRoZSBpbnRlcmZhY2VzIGNvbWUgZnJvbSB0aGUgc2FtZSBvYmplY3QuCiAqICAgRkFMU0UgT3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU0hJc1NhbWVPYmplY3QoSVVua25vd24qIGxwSW50MSwgSVVua25vd24qIGxwSW50MikKewogIExQVk9JRCBscFVua25vd24xLCBscFVua25vd24yOwoKICBUUkFDRSgiJXAgJXBcbiIsIGxwSW50MSwgbHBJbnQyKTsKCiAgaWYgKCFscEludDEgfHwgIWxwSW50MikKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKGxwSW50MSA9PSBscEludDIpCiAgICByZXR1cm4gVFJVRTsKCiAgaWYgKCFTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBJbnQxLCAmSUlEX0lVbmtub3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEICopJmxwVW5rbm93bjEpKSkKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKCFTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBJbnQyLCAmSUlEX0lVbmtub3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEICopJmxwVW5rbm93bjIpKSkKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKGxwVW5rbm93bjEgPT0gbHBVbmtub3duMikKICAgIHJldHVybiBUUlVFOwoKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzJdCiAqCiAqIEdldCB0aGUgd2luZG93IGhhbmRsZSBvZiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gZ2V0IHRoZSB3aW5kb3cgaGFuZGxlIG9mCiAqICBscGhXbmQgICAgW09dIERlc3RpbmF0aW9uIGZvciB3aW5kb3cgaGFuZGxlCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIGxwaFduZCBjb250YWlucyB0aGUgb2JqZWN0cyB3aW5kb3cgaGFuZGxlLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKgogKiBOT1RFUwogKiAgbHBVbmtub3duIGlzIGV4cGVjdGVkIHRvIHN1cHBvcnQgb25lIG9mIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlczoKICogIElPbGVXaW5kb3coKSwgSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlKCksIG9yIElTaGVsbFZpZXcoKS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0dldFdpbmRvdyhJVW5rbm93biAqbHBVbmtub3duLCBIV05EICpscGhXbmQpCnsKICAvKiBGSVhNRTogV2luZSBoYXMgbm8gaGVhZGVyIGZvciB0aGlzIG9iamVjdCAqLwogIHN0YXRpYyBjb25zdCBHVUlEIElJRF9JSW50ZXJuZXRTZWN1cml0eU1nclNpdGUgPSB7IDB4NzllYWM5ZWQsCiAgICAweGJhZjksIDB4MTFjZSwgeyAweDhjLCAweDgyLCAweDAwLCAweGFhLCAweDAwLCAweDRiLCAweGE5LCAweDBiIH19OwogIElVbmtub3duICpscE9sZTsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwaFduZCk7CgogIGlmICghbHBVbmtub3duKQogICAgcmV0dXJuIGhSZXQ7CgogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9sZVdpbmRvdywgKHZvaWQqKikmbHBPbGUpOwoKICBpZiAoRkFJTEVEKGhSZXQpKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sJklJRF9JU2hlbGxWaWV3LCAodm9pZCoqKSZscE9sZSk7CgogICAgaWYgKEZBSUxFRChoUmV0KSkKICAgIHsKICAgICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JSW50ZXJuZXRTZWN1cml0eU1nclNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBPbGUpOwogICAgfQogIH0KCiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICAvKiBMYXp5bmVzcyBoZXJlIC0gU2luY2UgR2V0V2luZG93KCkgaXMgdGhlIGZpcnN0IG1ldGhvZCBmb3IgdGhlIGFib3ZlIDMKICAgICAqIGludGVyZmFjZXMsIHdlIHVzZSB0aGUgc2FtZSBjYWxsIGZvciB0aGVtIGFsbC4KICAgICAqLwogICAgaFJldCA9IElPbGVXaW5kb3dfR2V0V2luZG93KChJT2xlV2luZG93KilscE9sZSwgbHBoV25kKTsKICAgIElVbmtub3duX1JlbGVhc2UobHBPbGUpOwogICAgaWYgKGxwaFduZCkKICAgICAgVFJBQ0UoIlJldHVybmluZyBIV05EPSVwXG4iLCAqbHBoV25kKTsKICB9CgogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTczXQogKgogKiBDYWxsIGEgbWV0aG9kIG9uIGFzIGFzIHlldCB1bmlkZW50aWZpZWQgb2JqZWN0LgogKgogKiBQQVJBTVMKICogIHBVbmsgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSB1bmlkZW50aWZpZWQgaW50ZXJmYWNlLAogKiAgYXJnICBbSV0gQXJndW1lbnQgZm9yIHRoZSBjYWxsIG9uIHRoZSBvYmplY3QuCiAqCiAqIFJFVFVSTlMKICogIFNfT0suCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9TZXRPd25lcihJVW5rbm93biAqcFVuaywgVUxPTkcgYXJnKQp7CiAgc3RhdGljIGNvbnN0IEdVSUQgZ3VpZF8xNzMgPSB7CiAgICAweDU4MzZmYjAwLCAweDgxODcsIDB4MTFjZiwgeyAweGExLDB4MmIsMHgwMCwweGFhLDB4MDAsMHg0YSwweGU4LDB4MzcgfQogIH07CiAgSU1hbGxvYyAqcFVuazI7CgogIFRSQUNFKCIoJXAsJWxkKVxuIiwgcFVuaywgYXJnKTsKCiAgLyogTm90ZTogYXJnIG1heSBub3QgYmUgYSBVTE9ORyBhbmQgcFVuazIgaXMgZm9yIHN1cmUgbm90IGFuIElNYWxsb2MgLQogICAqICAgICAgIFdlIHVzZSB0aGlzIGludGVyZmFjZSBhcyBpdHMgdnRhYmxlIGVudHJ5IGlzIGNvbXBhdGlibGUgd2l0aCB0aGUKICAgKiAgICAgICBvYmplY3QgaW4gcXVlc3Rpb24uCiAgICogRklYTUU6IEZpbmQgb3V0IHdoYXQgdGhpcyBvYmplY3QgaXMgYW5kIHdoZXJlIGl0IHNob3VsZCBiZSBkZWZpbmVkLgogICAqLwogIGlmIChwVW5rICYmCiAgICAgIFNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShwVW5rLCAmZ3VpZF8xNzMsICh2b2lkKiopJnBVbmsyKSkpCiAgewogICAgSU1hbGxvY19BbGxvYyhwVW5rMiwgYXJnKTsgLyogRmFrZWQgY2FsbCEhICovCiAgICBJTWFsbG9jX1JlbGVhc2UocFVuazIpOwogIH0KICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3NF0KICoKICogQ2FsbCBlaXRoZXIgSU9iamVjdFdpdGhTaXRlX1NldFNpdGUoKSBvciBJSW50ZXJuZXRTZWN1cml0eU1hbmFnZXJfU2V0U2VjdXJpdHlTaXRlKCkgb24KICogYW4gb2JqZWN0LgogKgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fU2V0U2l0ZSgKICAgICAgICBJVW5rbm93biAqb2JqLCAgICAgICAgLyogW2luXSAgIE9MRSBvYmplY3QgICAgICovCiAgICAgICAgSVVua25vd24gKnNpdGUpICAgICAgIC8qIFtpbl0gICBTaXRlIGludGVyZmFjZSAqLwp7CiAgICBIUkVTVUxUIGhyOwogICAgSU9iamVjdFdpdGhTaXRlICppb2Jqd2l0aHNpdGU7CiAgICBJSW50ZXJuZXRTZWN1cml0eU1hbmFnZXIgKmlzZWNtZ3I7CgogICAgaWYgKCFvYmopIHJldHVybiBFX0ZBSUw7CgogICAgaHIgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShvYmosICZJSURfSU9iamVjdFdpdGhTaXRlLCAoTFBWT0lEICopJmlvYmp3aXRoc2l0ZSk7CiAgICBUUkFDRSgiSUlEX0lPYmplY3RXaXRoU2l0ZSBRSSByZXQ9JTA4bHgsICVwXG4iLCBociwgaW9iandpdGhzaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaHIpKQogICAgewoJaHIgPSBJT2JqZWN0V2l0aFNpdGVfU2V0U2l0ZShpb2Jqd2l0aHNpdGUsIHNpdGUpOwoJVFJBQ0UoImRvbmUgSU9iamVjdFdpdGhTaXRlX1NldFNpdGUgcmV0PSUwOGx4XG4iLCBocik7CglJVW5rbm93bl9SZWxlYXNlKGlvYmp3aXRoc2l0ZSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglociA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKG9iaiwgJklJRF9JSW50ZXJuZXRTZWN1cml0eU1hbmFnZXIsIChMUFZPSUQgKikmaXNlY21ncik7CglUUkFDRSgiSUlEX0lJbnRlcm5ldFNlY3VyaXR5TWFuYWdlciBRSSByZXQ9JTA4bHgsICVwXG4iLCBociwgaXNlY21ncik7CglpZiAoRkFJTEVEKGhyKSkgcmV0dXJuIGhyOwoKCWhyID0gSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyX1NldFNlY3VyaXR5U2l0ZShpc2VjbWdyLCAoSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlICopc2l0ZSk7CglUUkFDRSgiZG9uZSBJSW50ZXJuZXRTZWN1cml0eU1hbmFnZXJfU2V0U2VjdXJpdHlTaXRlIHJldD0lMDhseFxuIiwgaHIpOwoJSVVua25vd25fUmVsZWFzZShpc2VjbWdyKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3NV0KICoKICogQ2FsbCBJUGVyc2lzdF9HZXRDbGFzc0lEKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElQZXJzaXN0IGludGVyZmFjZQogKiAgbHBDbGFzc0lkIFtPXSBEZXN0aW5hdGlvbiBmb3IgQ2xhc3MgSWQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gbHBDbGFzc0lkIGNvbnRhaW5zIHRoZSBDbGFzcyBJZCByZXF1ZXN0ZWQuCiAqICBGYWlsdXJlOiBFX0ZBSUwsIElmIGxwVW5rbm93biBpcyBOVUxMLAogKiAgICAgICAgICAgRV9OT0lOVEVSRkFDRSBJZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJUGVyc2lzdCwKICogICAgICAgICAgIE9yIGFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0dldENsYXNzSUQoSVVua25vd24gKmxwVW5rbm93biwgQ0xTSUQqIGxwQ2xhc3NJZCkKewogIElQZXJzaXN0KiBscFBlcnNpc3Q7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBkZWJ1Z3N0cl9ndWlkKGxwQ2xhc3NJZCkpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sJklJRF9JUGVyc2lzdCwodm9pZCoqKSZscFBlcnNpc3QpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICAgIHsKICAgICAgSVBlcnNpc3RfR2V0Q2xhc3NJRChscFBlcnNpc3QsIGxwQ2xhc3NJZCk7CiAgICAgIElQZXJzaXN0X1JlbGVhc2UobHBQZXJzaXN0KTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzZdCiAqCiAqIFJldHJpZXZlIGEgU2VydmljZSBJbnRlcmZhY2UgZnJvbSBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gZ2V0IGFuIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlIGZyb20KICogIHNpZCAgICAgICBbSV0gU2VydmljZSBJRCBmb3IgSVNlcnZpY2VQcm92aWRlcl9RdWVyeVNlcnZpY2UoKSBjYWxsCiAqICByaWlkICAgICAgW0ldIEZ1bmN0aW9uIHJlcXVlc3RlZCBmb3IgUXVlcnlTZXJ2aWNlIGNhbGwKICogIGxwcE91dCAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBzZXJ2aWNlIGludGVyZmFjZSBwb2ludGVyCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIGxwcE91dCBjb250YWlucyBhbiBvYmplY3QgcHJvdmlkaW5nIHRoZSByZXF1ZXN0ZWQgc2VydmljZQogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlCiAqCiAqIE5PVEVTCiAqICBscFVua25vd24gaXMgZXhwZWN0ZWQgdG8gc3VwcG9ydCB0aGUgSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVNlcnZpY2UoSVVua25vd24qIGxwVW5rbm93biwgUkVGR1VJRCBzaWQsIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKmxwcE91dCkKewogIElTZXJ2aWNlUHJvdmlkZXIqIHBTZXJ2aWNlID0gTlVMTDsKICBIUkVTVUxUIGhSZXQ7CgogIGlmICghbHBwT3V0KQogICAgcmV0dXJuIEVfRkFJTDsKCiAgKmxwcE91dCA9IE5VTEw7CgogIGlmICghbHBVbmtub3duKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgLyogR2V0IGFuIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlIGZyb20gdGhlIG9iamVjdCAqLwogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSVNlcnZpY2VQcm92aWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQVk9JRCopJnBTZXJ2aWNlKTsKCiAgaWYgKCFoUmV0ICYmIHBTZXJ2aWNlKQogIHsKICAgIFRSQUNFKCJRdWVyeUludGVyZmFjZSByZXR1cm5lZCAoSVNlcnZpY2VQcm92aWRlciopJXBcbiIsIHBTZXJ2aWNlKTsKCiAgICAvKiBHZXQgYSBTZXJ2aWNlIGludGVyZmFjZSBmcm9tIHRoZSBvYmplY3QgKi8KICAgIGhSZXQgPSBJU2VydmljZVByb3ZpZGVyX1F1ZXJ5U2VydmljZShwU2VydmljZSwgc2lkLCByaWlkLCBscHBPdXQpOwoKICAgIFRSQUNFKCIoSVNlcnZpY2VQcm92aWRlciopJXAgcmV0dXJuZWQgKElVbmtub3duKiklcFxuIiwgcFNlcnZpY2UsICpscHBPdXQpOwoKICAgIC8qIFJlbGVhc2UgdGhlIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlICovCiAgICBJVW5rbm93bl9SZWxlYXNlKHBTZXJ2aWNlKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzddCiAqCiAqIExvYWRzIGEgcG9wdXAgbWVudS4KICoKICogUEFSQU1TCiAqICBoSW5zdCAgW0ldIEluc3RhbmNlIGhhbmRsZQogKiAgc3pOYW1lIFtJXSBNZW51IG5hbWUKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgU0hMb2FkTWVudVBvcHVwKEhJTlNUQU5DRSBoSW5zdCwgTFBDV1NUUiBzek5hbWUpCnsKICBITUVOVSBoTWVudSwgaFN1Yk1lbnU7CgogIGlmICgoaE1lbnUgPSBMb2FkTWVudVcoaEluc3QsIHN6TmFtZSkpKQogIHsKICAgIGlmICgoaFN1Yk1lbnUgPSBHZXRTdWJNZW51KGhNZW51LCAwKSkpCiAgICAgIFJlbW92ZU1lbnUoaE1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwoKICAgIERlc3Ryb3lNZW51KGhNZW51KTsKICAgIHJldHVybiBUUlVFOwogIH0KICByZXR1cm4gRkFMU0U7Cn0KCnR5cGVkZWYgc3RydWN0IF9lbnVtV25kRGF0YQp7CiAgVUlOVCAgIHVpTXNnSWQ7CiAgV1BBUkFNIHdQYXJhbTsKICBMUEFSQU0gbFBhcmFtOwogIExSRVNVTFQgKFdJTkFQSSAqcGZuUG9zdCkoSFdORCxVSU5ULFdQQVJBTSxMUEFSQU0pOwp9IGVudW1XbmREYXRhOwoKLyogQ2FsbGJhY2sgZm9yIFNITFdBUElfMTc4ICovCnN0YXRpYyBCT09MIENBTExCQUNLIFNITFdBUElfRW51bUNoaWxkUHJvYyhIV05EIGhXbmQsIExQQVJBTSBsUGFyYW0pCnsKICBlbnVtV25kRGF0YSAqZGF0YSA9IChlbnVtV25kRGF0YSAqKWxQYXJhbTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGhXbmQsIGRhdGEpOwogIGRhdGEtPnBmblBvc3QoaFduZCwgZGF0YS0+dWlNc2dJZCwgZGF0YS0+d1BhcmFtLCBkYXRhLT5sUGFyYW0pOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xNzhdCiAqCiAqIFNlbmQgb3IgcG9zdCBhIG1lc3NhZ2UgdG8gZXZlcnkgY2hpbGQgb2YgYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICBbSV0gV2luZG93IHdob3NlIGNoaWxkcmVuIHdpbGwgZ2V0IHRoZSBtZXNzYWdlcwogKiAgdWlNc2dJZCBbSV0gTWVzc2FnZSBJZAogKiAgd1BhcmFtICBbSV0gV1BBUkFNIG9mIG1lc3NhZ2UKICogIGxQYXJhbSAgW0ldIExQQVJBTSBvZiBtZXNzYWdlCiAqICBiU2VuZCAgIFtJXSBUUlVFID0gVXNlIFNlbmRNZXNzYWdlQSgpLCBGQUxTRSA9IFVzZSBQb3N0TWVzc2FnZUEoKQogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKgogKiBOT1RFUwogKiAgVGhlIGFwcHJvcHJpYXRlIEFTQ0lJIG9yIFVuaWNvZGUgZnVuY3Rpb24gaXMgY2FsbGVkIGZvciB0aGUgd2luZG93LgogKi8Kdm9pZCBXSU5BUEkgU0hQcm9wYWdhdGVNZXNzYWdlKEhXTkQgaFduZCwgVUlOVCB1aU1zZ0lkLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtLCBCT09MIGJTZW5kKQp7CiAgZW51bVduZERhdGEgZGF0YTsKCiAgVFJBQ0UoIiglcCwldSwlZCwlbGQsJWQpXG4iLCBoV25kLCB1aU1zZ0lkLCB3UGFyYW0sIGxQYXJhbSwgYlNlbmQpOwoKICBpZihoV25kKQogIHsKICAgIGRhdGEudWlNc2dJZCA9IHVpTXNnSWQ7CiAgICBkYXRhLndQYXJhbSAgPSB3UGFyYW07CiAgICBkYXRhLmxQYXJhbSAgPSBsUGFyYW07CgogICAgaWYgKGJTZW5kKQogICAgICBkYXRhLnBmblBvc3QgPSBJc1dpbmRvd1VuaWNvZGUoaFduZCkgPyAodm9pZCopU2VuZE1lc3NhZ2VXIDogKHZvaWQqKVNlbmRNZXNzYWdlQTsKICAgIGVsc2UKICAgICAgZGF0YS5wZm5Qb3N0ID0gSXNXaW5kb3dVbmljb2RlKGhXbmQpID8gKHZvaWQqKVBvc3RNZXNzYWdlVyA6ICh2b2lkKilQb3N0TWVzc2FnZUE7CgogICAgRW51bUNoaWxkV2luZG93cyhoV25kLCBTSExXQVBJX0VudW1DaGlsZFByb2MsIChMUEFSQU0pJmRhdGEpOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4MF0KICoKICogUmVtb3ZlIGFsbCBzdWItbWVudXMgZnJvbSBhIG1lbnUuCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgW0ldIE1lbnUgdG8gcmVtb3ZlIHN1Yi1tZW51cyBmcm9tCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IDAuICBBbGwgc3ViLW1lbnVzIHVuZGVyIGhNZW51IGFyZSByZW1vdmVkCiAqICBGYWlsdXJlOiAtMSwgaWYgYW55IHBhcmFtZXRlciBpcyBpbnZhbGlkCiAqLwpEV09SRCBXSU5BUEkgU0hSZW1vdmVBbGxTdWJNZW51cyhITUVOVSBoTWVudSkKewogIGludCBpSXRlbUNvdW50ID0gR2V0TWVudUl0ZW1Db3VudChoTWVudSkgLSAxOwogIHdoaWxlIChpSXRlbUNvdW50ID49IDApCiAgewogICAgSE1FTlUgaFN1Yk1lbnUgPSBHZXRTdWJNZW51KGhNZW51LCBpSXRlbUNvdW50KTsKICAgIGlmIChoU3ViTWVudSkKICAgICAgUmVtb3ZlTWVudShoTWVudSwgaUl0ZW1Db3VudCwgTUZfQllQT1NJVElPTik7CiAgICBpSXRlbUNvdW50LS07CiAgfQogIHJldHVybiBpSXRlbUNvdW50Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTgxXQogKgogKiBFbmFibGUgb3IgZGlzYWJsZSBhIG1lbnUgaXRlbS4KICoKICogUEFSQU1TCiAqICBoTWVudSAgIFtJXSBNZW51IGhvbGRpbmcgbWVudSBpdGVtCiAqICB1SUQgICAgIFtJXSBJRCBvZiBtZW51IGl0ZW0gdG8gZW5hYmxlL2Rpc2FibGUKICogIGJFbmFibGUgW0ldIFdoZXRoZXIgdG8gZW5hYmxlIChUUlVFKSBvciBkaXNhYmxlIChGQUxTRSkgdGhlIGl0ZW0uCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXR1cm4gY29kZSBmcm9tIEVuYWJsZU1lbnVJdGVtLgogKi8KVUlOVCBXSU5BUEkgU0hFbmFibGVNZW51SXRlbShITUVOVSBoTWVudSwgVUlOVCB3SXRlbUlELCBCT09MIGJFbmFibGUpCnsKICByZXR1cm4gRW5hYmxlTWVudUl0ZW0oaE1lbnUsIHdJdGVtSUQsIGJFbmFibGUgPyBNRl9FTkFCTEVEIDogTUZfR1JBWUVEKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQAlbU0hMV0FQSS4xODJdCiAqCiAqIENoZWNrIG9yIHVuY2hlY2sgYSBtZW51IGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgIFtJXSBNZW51IGhvbGRpbmcgbWVudSBpdGVtCiAqICB1SUQgICAgW0ldIElEIG9mIG1lbnUgaXRlbSB0byBjaGVjay91bmNoZWNrCiAqICBiQ2hlY2sgW0ldIFdoZXRoZXIgdG8gY2hlY2sgKFRSVUUpIG9yIHVuY2hlY2sgKEZBTFNFKSB0aGUgaXRlbS4KICoKICogUkVUVVJOUwogKiAgVGhlIHJldHVybiBjb2RlIGZyb20gQ2hlY2tNZW51SXRlbS4KICovCkRXT1JEIFdJTkFQSSBTSENoZWNrTWVudUl0ZW0oSE1FTlUgaE1lbnUsIFVJTlQgdUlELCBCT09MIGJDaGVjaykKewogIHJldHVybiBDaGVja01lbnVJdGVtKGhNZW51LCB1SUQsIGJDaGVjayA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTgzXQogKgogKiBSZWdpc3RlciBhIHdpbmRvdyBjbGFzcyBpZiBpdCBpc24ndCBhbHJlYWR5LgogKgogKiBQQVJBTVMKICogIGxwV25kQ2xhc3MgW0ldIFdpbmRvdyBjbGFzcyB0byByZWdpc3RlcgogKgogKiBSRVRVUk5TCiAqICBUaGUgcmVzdWx0IG9mIHRoZSBSZWdpc3RlckNsYXNzQSBjYWxsLgogKi8KRFdPUkQgV0lOQVBJIFNIUmVnaXN0ZXJDbGFzc0EoV05EQ0xBU1NBICp3bmRjbGFzcykKewogIFdORENMQVNTQSB3Y2E7CiAgaWYgKEdldENsYXNzSW5mb0Eod25kY2xhc3MtPmhJbnN0YW5jZSwgd25kY2xhc3MtPmxwc3pDbGFzc05hbWUsICZ3Y2EpKQogICAgcmV0dXJuIFRSVUU7CiAgcmV0dXJuIChEV09SRClSZWdpc3RlckNsYXNzQSh3bmRjbGFzcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODZdCiAqLwpCT09MIFdJTkFQSSBTSFNpbXVsYXRlRHJvcChJRHJvcFRhcmdldCAqcERyb3AsIElEYXRhT2JqZWN0ICpwRGF0YU9iaiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZ3JmS2V5U3RhdGUsIFBQT0lOVEwgbHBQdCwgRFdPUkQqIHBkd0VmZmVjdCkKewogIERXT1JEIGR3RWZmZWN0ID0gRFJPUEVGRkVDVF9MSU5LIHwgRFJPUEVGRkVDVF9NT1ZFIHwgRFJPUEVGRkVDVF9DT1BZOwogIFBPSU5UTCBwdCA9IHsgMCwgMCB9OwoKICBpZiAoIWxwUHQpCiAgICBscFB0ID0gJnB0OwoKICBpZiAoIXBkd0VmZmVjdCkKICAgIHBkd0VmZmVjdCA9ICZkd0VmZmVjdDsKCiAgSURyb3BUYXJnZXRfRHJhZ0VudGVyKHBEcm9wLCBwRGF0YU9iaiwgZ3JmS2V5U3RhdGUsICpscFB0LCBwZHdFZmZlY3QpOwoKICBpZiAoKnBkd0VmZmVjdCkKICAgIHJldHVybiBJRHJvcFRhcmdldF9Ecm9wKHBEcm9wLCBwRGF0YU9iaiwgZ3JmS2V5U3RhdGUsICpscFB0LCBwZHdFZmZlY3QpOwoKICBJRHJvcFRhcmdldF9EcmFnTGVhdmUocERyb3ApOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTg3XQogKgogKiBDYWxsIElQZXJzaXN0UHJvcGVydHlCYWdfTG9hZCgpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJUGVyc2lzdFByb3BlcnR5QmFnIGludGVyZmFjZQogKiAgbHBQcm9wQmFnIFtPXSBEZXN0aW5hdGlvbiBmb3IgbG9hZGVkIElQcm9wZXJ0eUJhZwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0ZBSUwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpEV09SRCBXSU5BUEkgU0hMb2FkRnJvbVByb3BlcnR5QmFnKElVbmtub3duICpscFVua25vd24sIElQcm9wZXJ0eUJhZyogbHBQcm9wQmFnKQp7CiAgSVBlcnNpc3RQcm9wZXJ0eUJhZyogbHBQUEJhZzsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwUHJvcEJhZyk7CgogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JUGVyc2lzdFByb3BlcnR5QmFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwUFBCYWcpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscFBQQmFnKQogICAgewogICAgICBoUmV0ID0gSVBlcnNpc3RQcm9wZXJ0eUJhZ19Mb2FkKGxwUFBCYWcsIGxwUHJvcEJhZywgTlVMTCk7CiAgICAgIElQZXJzaXN0UHJvcGVydHlCYWdfUmVsZWFzZShscFBQQmFnKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjE4OF0KICoKICogQ2FsbCBJT2xlQ29udHJvbFNpdGVfVHJhbnNsYXRlQWNjZWxlcmF0b3IoKSAgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biAgIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbnRyb2xTaXRlIGludGVyZmFjZS4KICogIGxwTXNnICAgICAgIFtJXSBLZXkgbWVzc2FnZSB0byBiZSBwcm9jZXNzZWQuCiAqICBkd01vZGlmaWVycyBbSV0gRmxhZ3MgY29udGFpbmluZyB0aGUgc3RhdGUgb2YgdGhlIG1vZGlmaWVyIGtleXMuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUsIG9yIEVfSU5WQUxJREFSRyBpZiBscFVua25vd24gaXMgTlVMTC4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1RyYW5zbGF0ZUFjY2VsZXJhdG9yT0NTKElVbmtub3duICpscFVua25vd24sIExQTVNHIGxwTXNnLCBEV09SRCBkd01vZGlmaWVycykKewogIElPbGVDb250cm9sU2l0ZSogbHBDU2l0ZSA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwoKICBUUkFDRSgiKCVwLCVwLDB4JTA4bHgpXG4iLCBscFVua25vd24sIGxwTXNnLCBkd01vZGlmaWVycyk7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb250cm9sU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscENTaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBDU2l0ZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb250cm9sU2l0ZV9UcmFuc2xhdGVBY2NlbGVyYXRvcihscENTaXRlLCBscE1zZywgZHdNb2RpZmllcnMpOwogICAgICBJT2xlQ29udHJvbFNpdGVfUmVsZWFzZShscENTaXRlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xODldCiAqCiAqIENhbGwgSU9sZUNvbnRyb2xTaXRlX0dldEV4dGVuZGVkQ29udHJvbCgpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJT2xlQ29udHJvbFNpdGUgaW50ZXJmYWNlLgogKiAgbHBwRGlzcCAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgcmVzdWx0aW5nIElEaXNwYXRjaC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSwgb3IgRV9GQUlMIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKi8KRFdPUkQgV0lOQVBJIElVbmtub3duX09uRm9jdXNPQ1MoSVVua25vd24gKmxwVW5rbm93biwgSURpc3BhdGNoKiogbHBwRGlzcCkKewogIElPbGVDb250cm9sU2l0ZSogbHBDU2l0ZSA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBscHBEaXNwKTsKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9sZUNvbnRyb2xTaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwQ1NpdGUpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscENTaXRlKQogICAgewogICAgICBoUmV0ID0gSU9sZUNvbnRyb2xTaXRlX0dldEV4dGVuZGVkQ29udHJvbChscENTaXRlLCBscHBEaXNwKTsKICAgICAgSU9sZUNvbnRyb2xTaXRlX1JlbGVhc2UobHBDU2l0ZSk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgIFtTSExXQVBJLjE5MF0KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0hhbmRsZUlSZXN0cmljdChMUFVOS05PV04gbHBVbmtub3duLCBQVk9JRCBscEFyZzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQVk9JRCBscEFyZzIsIFBWT0lEIGxwQXJnMywgUFZPSUQgbHBBcmc0KQp7CiAgLyogRklYTUU6IHtEMTJGMjZCMi1EOTBBLTExRDAtODMwRC0wMEFBMDA1QjQzODN9IC0gV2hhdCBvYmplY3QgZG9lcyB0aGlzIHJlcHJlc2VudD8gKi8KICBzdGF0aWMgY29uc3QgRFdPUkQgc2VydmljZV9pZFtdID0geyAweGQxMmYyNmIyLCAweDExZDBkOTBhLCAweGFhMDAwZDgzLCAweDgzNDM1YjAwIH07CiAgLyogRklYTUU6IHtEMTJGMjZCMS1EOTBBLTExRDAtODMwRC0wMEFBMDA1QjQzODN9IC0gQWxzbyBVbmtub3duL3VuZG9jdW1lbnRlZCAqLwogIHN0YXRpYyBjb25zdCBEV09SRCBmdW5jdGlvbl9pZFtdID0geyAweGQxMmYyNmIxLCAweDExZDBkOTBhLCAweGFhMDAwZDgzLCAweDgzNDM1YjAwIH07CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwogIExQVU5LTk9XTiBscFVua0lubmVyID0gTlVMTDsgLyogRklYTUU6IFJlYWwgdHlwZSBpcyB1bmtub3duICovCgogIFRSQUNFKCIoJXAsJXAsJXAsJXAsJXApXG4iLCBscFVua25vd24sIGxwQXJnMSwgbHBBcmcyLCBscEFyZzMsIGxwQXJnNCk7CgogIGlmIChscFVua25vd24gJiYgbHBBcmc0KQogIHsKICAgICBoUmV0ID0gSVVua25vd25fUXVlcnlTZXJ2aWNlKGxwVW5rbm93biwgKFJFRkdVSUQpc2VydmljZV9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChSRUZHVUlEKWZ1bmN0aW9uX2lkLCAodm9pZCoqKSZscFVua0lubmVyKTsKCiAgICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscFVua0lubmVyKQogICAgIHsKICAgICAgIC8qIEZJWE1FOiBUaGUgdHlwZSBvZiBzZXJ2aWNlIG9iamVjdCByZXF1ZXN0ZWQgaXMgdW5rbm93biwgaG93ZXZlcgoJKiB0ZXN0aW5nIHNob3dzIHRoYXQgaXRzIGZpcnN0IG1ldGhvZCBpcyBjYWxsZWQgd2l0aCA0IHBhcmFtZXRlcnMuCgkqIEZha2UgdGhpcyBieSB1c2luZyBJUGFyc2VEaXNwbGF5TmFtZV9QYXJzZURpc3BsYXlOYW1lIHNpbmNlIHRoZQoJKiBzaWduYXR1cmUgYW5kIHBvc2l0aW9uIGluIHRoZSB2dGFibGUgbWF0Y2hlcyBvdXIgdW5rbm93biBvYmplY3QgdHlwZS4KCSovCiAgICAgICBoUmV0ID0gSVBhcnNlRGlzcGxheU5hbWVfUGFyc2VEaXNwbGF5TmFtZSgoTFBQQVJTRURJU1BMQVlOQU1FKWxwVW5rSW5uZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscEFyZzEsIGxwQXJnMiwgbHBBcmczLCBscEFyZzQpOwogICAgICAgSVVua25vd25fUmVsZWFzZShscFVua0lubmVyKTsKICAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgIFtTSExXQVBJLjE5Ml0KICoKICogR2V0IGEgc3ViLW1lbnUgZnJvbSBhIG1lbnUgaXRlbS4KICoKICogUEFSQU1TCiAqICBoTWVudSBbSV0gTWVudSB0byBnZXQgc3ViLW1lbnUgZnJvbQogKiAgdUlEICAgW0ldIElEIG9mIG1lbnUgaXRlbSBjb250YWluaW5nIHN1Yi1tZW51CiAqCiAqIFJFVFVSTlMKICogIFRoZSBzdWItbWVudSBvZiB0aGUgaXRlbSwgb3IgYSBOVUxMIGhhbmRsZSBpZiBhbnkgcGFyYW1ldGVycyBhcmUgaW52YWxpZC4KICovCkhNRU5VIFdJTkFQSSBTSEdldE1lbnVGcm9tSUQoSE1FTlUgaE1lbnUsIFVJTlQgdUlEKQp7CiAgTUVOVUlURU1JTkZPVyBtaTsKCiAgVFJBQ0UoIiglcCwldSlcbiIsIGhNZW51LCB1SUQpOwoKICBtaS5jYlNpemUgPSBzaXplb2YobWkpOwogIG1pLmZNYXNrID0gTUlJTV9TVUJNRU5VOwoKICBpZiAoIUdldE1lbnVJdGVtSW5mb1coaE1lbnUsIHVJRCwgRkFMU0UsICZtaSkpCiAgICByZXR1cm4gTlVMTDsKCiAgcmV0dXJuIG1pLmhTdWJNZW51Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTkzXQogKgogKiBHZXQgdGhlIGNvbG9yIGRlcHRoIG9mIHRoZSBwcmltYXJ5IGRpc3BsYXkuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGNvbG9yIGRlcHRoIG9mIHRoZSBwcmltYXJ5IGRpc3BsYXkuCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRDdXJDb2xvclJlcygpCnsKICAgIEhEQyBoZGM7CiAgICBEV09SRCByZXQ7CgogICAgVFJBQ0UoIigpXG4iKTsKCiAgICBoZGMgPSBHZXREQygwKTsKICAgIHJldCA9IEdldERldmljZUNhcHMoaGRjLCBCSVRTUElYRUwpICogR2V0RGV2aWNlQ2FwcyhoZGMsIFBMQU5FUyk7CiAgICBSZWxlYXNlREMoMCwgaGRjKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xOTRdCiAqCiAqIFdhaXQgZm9yIGEgbWVzc2FnZSB0byBhcnJpdmUsIHdpdGggYSB0aW1lb3V0LgogKgogKiBQQVJBTVMKICogIGhhbmQgICAgICBbSV0gSGFuZGxlIHRvIHF1ZXJ5CiAqICBkd1RpbWVvdXQgW0ldIFRpbWVvdXQgaW4gdGlja3Mgb3IgSU5GSU5JVEUgdG8gbmV2ZXIgdGltZW91dAogKgogKiBSRVRVUk5TCiAqICBTVEFUVVNfVElNRU9VVCBpZiBubyBtZXNzYWdlIGlzIHJlY2VpdmVkIGJlZm9yZSBkd1RpbWVvdXQgdGlja3MgcGFzc2VzLgogKiAgT3RoZXJ3aXNlIHJldHVybnMgdGhlIHZhbHVlIGZyb20gTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0c0V4IHdoZW4gYQogKiAgbWVzc2FnZSBpcyBhdmFpbGFibGUuCiAqLwpEV09SRCBXSU5BUEkgU0hXYWl0Rm9yU2VuZE1lc3NhZ2VUaHJlYWQoSEFORExFIGhhbmQsIERXT1JEIGR3VGltZW91dCkKewogIERXT1JEIGR3RW5kVGlja3MgPSBHZXRUaWNrQ291bnQoKSArIGR3VGltZW91dDsKICBEV09SRCBkd1JldDsKCiAgd2hpbGUgKChkd1JldCA9IE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHNFeCgxLCAmaGFuZCwgZHdUaW1lb3V0LCBRU19TRU5ETUVTU0FHRSwgMCkpID09IDEpCiAgewogICAgTVNHIG1zZzsKCiAgICBQZWVrTWVzc2FnZVcoJm1zZywgTlVMTCwgMCwgMCwgUE1fTk9SRU1PVkUpOwoKICAgIGlmIChkd1RpbWVvdXQgIT0gSU5GSU5JVEUpCiAgICB7CiAgICAgICAgaWYgKChpbnQpKGR3VGltZW91dCA9IGR3RW5kVGlja3MgLSBHZXRUaWNrQ291bnQoKSkgPD0gMCkKICAgICAgICAgICAgcmV0dXJuIFdBSVRfVElNRU9VVDsKICAgIH0KICB9CgogIHJldHVybiBkd1JldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjE5NV0KICoKICogRGV0ZXJtaW5lIGlmIGEgc2hlbGwgZm9sZGVyIGNhbiBiZSBleHBhbmRlZC4KICoKICogUEFSQU1TCiAqICBscEZvbGRlciBbSV0gUGFyZW50IGZvbGRlciBjb250YWluaW5nIHRoZSBvYmplY3QgdG8gdGVzdC4KICogIHBpZGwgICAgIFtJXSBJZCBvZiB0aGUgb2JqZWN0IHRvIHRlc3QuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0ssIGlmIHRoZSBvYmplY3QgaXMgZXhwYW5kYWJsZSwgU19GQUxTRSBvdGhlcndpc2UuCiAqICBGYWlsdXJlOiBFX0lOVkFMSURBUkcsIGlmIGFueSBhcmd1bWVudCBpcyBpbnZhbGlkLgogKgogKiBOT1RFUwogKiAgSWYgdGhlIG9iamVjdCB0byBiZSB0ZXN0ZWQgZG9lcyBub3QgZXhwb3NlIHRoZSBJUXVlcnlJbmZvKCkgaW50ZXJmYWNlIGl0CiAqICB3aWxsIG5vdCBiZSBpZGVudGlmaWVkIGFzIGFuIGV4cGFuZGFibGUgZm9sZGVyLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hJc0V4cGFuZGFibGVGb2xkZXIoTFBTSEVMTEZPTERFUiBscEZvbGRlciwgTFBDSVRFTUlETElTVCBwaWRsKQp7CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwogIElRdWVyeUluZm8gKmxwSW5mbzsKCiAgaWYgKGxwRm9sZGVyICYmIHBpZGwpCiAgewogICAgaFJldCA9IElTaGVsbEZvbGRlcl9HZXRVSU9iamVjdE9mKGxwRm9sZGVyLCBOVUxMLCAxLCAmcGlkbCwgJklJRF9JUXVlcnlJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsICh2b2lkKiopJmxwSW5mbyk7CiAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgICBoUmV0ID0gU19GQUxTRTsgLyogRG9lc24ndCBleHBvc2UgSVF1ZXJ5SW5mbyAqLwogICAgZWxzZQogICAgewogICAgICBEV09SRCBkd0ZsYWdzID0gMDsKCiAgICAgIC8qIE1TRE4gc3RhdGVzIG9mIElRdWVyeUluZm9fR2V0SW5mb0ZsYWdzKCkgdGhhdCAiVGhpcyBtZXRob2QgaXMgbm90CiAgICAgICAqIGN1cnJlbnRseSB1c2VkIi4gUmVhbGx5PyBZb3Ugd291bGRuJ3QgYmUgaG9sZGluZyBvdXQgb24gbWUgd291bGQgeW91PwogICAgICAgKi8KICAgICAgaFJldCA9IElRdWVyeUluZm9fR2V0SW5mb0ZsYWdzKGxwSW5mbywgJmR3RmxhZ3MpOwoKICAgICAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICAgICAgewogICAgICAgIC8qIDB4MiBpcyBhbiB1bmRvY3VtZW50ZWQgZmxhZyBhcHBhcmVudGx5IGluZGljYXRpbmcgZXhwYW5kYWJpbGl0eSAqLwogICAgICAgIGhSZXQgPSBkd0ZsYWdzICYgMHgyID8gU19PSyA6IFNfRkFMU0U7CiAgICAgIH0KCiAgICAgIElRdWVyeUluZm9fUmVsZWFzZShscEluZm8pOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjE5N10KICoKICogQmxhbmsgb3V0IGEgcmVnaW9uIG9mIHRleHQgYnkgZHJhd2luZyB0aGUgYmFja2dyb3VuZCBvbmx5LgogKgogKiBQQVJBTVMKICogIGhEQyAgIFtJXSBEZXZpY2UgY29udGV4dCB0byBkcmF3IGluCiAqICBwUmVjdCBbSV0gQXJlYSB0byBkcmF3IGluCiAqICBjUmVmICBbSV0gQ29sb3IgdG8gZHJhdyBpbgogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KRFdPUkQgV0lOQVBJIFNIRmlsbFJlY3RDbHIoSERDIGhEQywgTFBDUkVDVCBwUmVjdCwgQ09MT1JSRUYgY1JlZikKewogICAgQ09MT1JSRUYgY09sZENvbG9yID0gU2V0QmtDb2xvcihoREMsIGNSZWYpOwogICAgRXh0VGV4dE91dEEoaERDLCAwLCAwLCBFVE9fT1BBUVVFLCBwUmVjdCwgMCwgMCwgMCk7CiAgICBTZXRCa0NvbG9yKGhEQywgY09sZENvbG9yKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTk4XQogKgogKiBSZXR1cm4gdGhlIHZhbHVlIGFzb2NpYXRlZCB3aXRoIGEga2V5IGluIGEgbWFwLgogKgogKiBQQVJBTVMKICogIGxwS2V5cyAgIFtJXSBBIGxpc3Qgb2Yga2V5cyBvZiBsZW5ndGggaUxlbgogKiAgbHBWYWx1ZXMgW0ldIEEgbGlzdCBvZiB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGxwS2V5cywgb2YgbGVuZ3RoIGlMZW4KICogIGlMZW4gICAgIFtJXSBMZW5ndGggb2YgYm90aCBscEtleXMgYW5kIGxwVmFsdWVzCiAqICBpS2V5ICAgICBbSV0gVGhlIGtleSB2YWx1ZSB0byBsb29rIHVwIGluIGxwS2V5cwogKgogKiBSRVRVUk5TCiAqICBUaGUgdmFsdWUgaW4gbHBWYWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGlLZXksIG9yIC0xIGlmIGlLZXkgaXMgbm90CiAqICBmb3VuZCBpbiBscEtleXMuCiAqCiAqIE5PVEVTCiAqICAtIElmIHR3byBlbGVtZW50cyBpbiB0aGUgbWFwIHNoYXJlIHRoZSBzYW1lIGtleSwgdGhpcyBmdW5jdGlvbiByZXR1cm5zCiAqICAgIHRoZSB2YWx1ZSBjbG9zZXN0IHRvIHRoZSBzdGFydCBvZiB0aGUgbWFwCiAqICAtIFRoZSBuYXRpdmUgdmVyc2lvbiBvZiB0aGlzIGZ1bmN0aW9uIGNyYXNoZXMgaWYgbHBLZXlzIG9yIGxwVmFsdWVzIGlzIE5VTEwuCiAqLwppbnQgV0lOQVBJIFNIU2VhcmNoTWFwSW50KGNvbnN0IGludCAqbHBLZXlzLCBjb25zdCBpbnQgKmxwVmFsdWVzLCBpbnQgaUxlbiwgaW50IGlLZXkpCnsKICBpZiAobHBLZXlzICYmIGxwVmFsdWVzKQogIHsKICAgIGludCBpID0gMDsKCiAgICB3aGlsZSAoaSA8IGlMZW4pCiAgICB7CiAgICAgIGlmIChscEtleXNbaV0gPT0gaUtleSkKICAgICAgICByZXR1cm4gbHBWYWx1ZXNbaV07IC8qIEZvdW5kICovCiAgICAgIGkrKzsKICAgIH0KICB9CiAgcmV0dXJuIC0xOyAvKiBOb3QgZm91bmQgKi8KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xOTldCiAqCiAqIENvcHkgYW4gaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUEFSQU1TCiAqICAgbHBwRGVzdCAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29weQogKiAgIGxwVW5rbm93biBbSV0gU291cmNlIGZvciBjb3B5CiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpWT0lEIFdJTkFQSSBJVW5rbm93bl9TZXQoSVVua25vd24gKipscHBEZXN0LCBJVW5rbm93biAqbHBVbmtub3duKQp7CiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwcERlc3QsIGxwVW5rbm93bik7CgogIGlmIChscHBEZXN0KQogICAgSVVua25vd25fQXRvbWljUmVsZWFzZShscHBEZXN0KTsgLyogUmVsZWFzZSBleGlzdGluZyBpbnRlcmZhY2UgKi8KCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICAvKiBDb3B5ICovCiAgICBJVW5rbm93bl9BZGRSZWYobHBVbmtub3duKTsKICAgICpscHBEZXN0ID0gbHBVbmtub3duOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwMF0KICoKICovCkhSRVNVTFQgV0lOQVBJIE1heVFTRm9yd2FyZChJVW5rbm93biogbHBVbmtub3duLCBQVk9JRCBscFJlc2VydmVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGR1VJRCByaWlkQ21kR3JwLCBVTE9ORyBjQ21kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9MRUNNRCAqcHJnQ21kcywgT0xFQ01EVEVYVCogcENtZFRleHQpCnsKICBGSVhNRSgiKCVwLCVwLCVwLCVsZCwlcCwlcCkgLSBzdHViXG4iLAogICAgICAgIGxwVW5rbm93biwgbHBSZXNlcnZlZCwgcmlpZENtZEdycCwgY0NtZHMsIHByZ0NtZHMsIHBDbWRUZXh0KTsKCiAgLyogRklYTUU6IENhbGxzIElzUVNGb3J3YXJkICYgSVVua25vd25fUXVlcnlTdGF0dXMgKi8KICByZXR1cm4gRFJBR0RST1BfRV9OT1RSRUdJU1RFUkVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjAxXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgTWF5RXhlY0ZvcndhcmQoSVVua25vd24qIGxwVW5rbm93biwgSU5UIGlVbmssIFJFRkdVSUQgcGd1aWRDbWRHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgbkNtZElELCBEV09SRCBuQ21kZXhlY29wdCwgVkFSSUFOVCogcHZhSW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBUklBTlQqIHB2YU91dCkKewogIEZJWE1FKCIoJXAsJWQsJXAsJWxkLCVsZCwlcCwlcCkgLSBzdHViIVxuIiwgbHBVbmtub3duLCBpVW5rLCBwZ3VpZENtZEdyb3VwLAogICAgICAgIG5DbWRJRCwgbkNtZGV4ZWNvcHQsIHB2YUluLCBwdmFPdXQpOwogIHJldHVybiBEUkFHRFJPUF9FX05PVFJFR0lTVEVSRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDJdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBJc1FTRm9yd2FyZChSRUZHVUlEIHBndWlkQ21kR3JvdXAsVUxPTkcgY0NtZHMsIE9MRUNNRCAqcHJnQ21kcykKewogIEZJWE1FKCIoJXAsJWxkLCVwKSAtIHN0dWIhXG4iLCBwZ3VpZENtZEdyb3VwLCBjQ21kcywgcHJnQ21kcyk7CiAgcmV0dXJuIERSQUdEUk9QX0VfTk9UUkVHSVNURVJFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQAlbU0hMV0FQSS4yMDRdCiAqCiAqIERldGVybWluZSBpZiBhIHdpbmRvdyBpcyBub3QgYSBjaGlsZCBvZiBhbm90aGVyIHdpbmRvdy4KICoKICogUEFSQU1TCiAqIGhQYXJlbnQgW0ldIFN1c3BlY3RlZCBwYXJlbnQgd2luZG93CiAqIGhDaGlsZCAgW0ldIFN1c3BlY3RlZCBjaGlsZCB3aW5kb3cKICoKICogUkVUVVJOUwogKiBUUlVFOiAgSWYgaENoaWxkIGlzIGEgY2hpbGQgd2luZG93IG9mIGhQYXJlbnQKICogRkFMU0U6IElmIGhDaGlsZCBpcyBub3QgYSBjaGlsZCB3aW5kb3cgb2YgaFBhcmVudCwgb3IgdGhleSBhcmUgZXF1YWwKICovCkJPT0wgV0lOQVBJIFNISXNDaGlsZE9yU2VsZihIV05EIGhQYXJlbnQsIEhXTkQgaENoaWxkKQp7CiAgVFJBQ0UoIiglcCwlcClcbiIsIGhQYXJlbnQsIGhDaGlsZCk7CgogIGlmICghaFBhcmVudCB8fCAhaENoaWxkKQogICAgcmV0dXJuIFRSVUU7CiAgZWxzZSBpZihoUGFyZW50ID09IGhDaGlsZCkKICAgIHJldHVybiBGQUxTRTsKICByZXR1cm4gIUlzQ2hpbGQoaFBhcmVudCwgaENoaWxkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgRkRTQSBmdW5jdGlvbnMuICBNYW5hZ2UgYSBkeW5hbWljIGFycmF5IG9mIGZpeGVkIHNpemUgbWVtb3J5IGJsb2Nrcy4KICovCgp0eXBlZGVmIHN0cnVjdAp7CiAgICBEV09SRCBudW1faXRlbXM7ICAgICAgIC8qIE51bWJlciBvZiBlbGVtZW50cyBpbnNlcnRlZCAqLwogICAgdm9pZCAqbWVtOyAgICAgICAgICAgICAvKiBQdHIgdG8gYXJyYXkgKi8KICAgIERXT1JEIGJsb2Nrc19hbGxvY2VkOyAgLyogTnVtYmVyIG9mIGVsZW1lbnRzIGFsbG9jYXRlZCAqLwogICAgQllURSBpbmM7ICAgICAgICAgICAgICAvKiBOdW1iZXIgb2YgZWxlbWVudHMgdG8gZ3JvdyBieSB3aGVuIHdlIG5lZWQgdG8gZXhwYW5kICovCiAgICBCWVRFIGJsb2NrX3NpemU7ICAgICAgIC8qIFNpemUgaW4gYnl0ZXMgb2YgYW4gZWxlbWVudCAqLwogICAgQllURSBmbGFnczsgICAgICAgICAgICAvKiBGbGFncyAqLwp9IEZEU0FfaW5mbzsKCiNkZWZpbmUgRkRTQV9GTEFHX0lOVEVSTkFMX0FMTE9DIDB4MDEgLyogV2hlbiBzZXQgd2UgaGF2ZSBhbGxvY2F0ZWQgbWVtIGludGVybmFsbHkgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDhdCiAqCiAqIEluaXRpYWxpemUgYW4gRkRTQSBhcnJhcnkuIAogKi8KQk9PTCBXSU5BUEkgRkRTQV9Jbml0aWFsaXplKERXT1JEIGJsb2NrX3NpemUsIERXT1JEIGluYywgRkRTQV9pbmZvICppbmZvLCB2b2lkICptZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBpbml0X2Jsb2NrcykKewogICAgVFJBQ0UoIigweCUwOGx4IDB4JTA4bHggJXAgJXAgMHglMDhseClcbiIsIGJsb2NrX3NpemUsIGluYywgaW5mbywgbWVtLCBpbml0X2Jsb2Nrcyk7CgogICAgaWYoaW5jID09IDApCiAgICAgICAgaW5jID0gMTsKCiAgICBpZihtZW0pCiAgICAgICAgbWVtc2V0KG1lbSwgMCwgYmxvY2tfc2l6ZSAqIGluaXRfYmxvY2tzKTsKICAgIAogICAgaW5mby0+bnVtX2l0ZW1zID0gMDsKICAgIGluZm8tPmluYyA9IGluYzsKICAgIGluZm8tPm1lbSA9IG1lbTsKICAgIGluZm8tPmJsb2Nrc19hbGxvY2VkID0gaW5pdF9ibG9ja3M7CiAgICBpbmZvLT5ibG9ja19zaXplID0gYmxvY2tfc2l6ZTsKICAgIGluZm8tPmZsYWdzID0gMDsKCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwOV0KICoKICogRGVzdHJveSBhbiBGRFNBIGFycmF5CiAqLwpCT09MIFdJTkFQSSBGRFNBX0Rlc3Ryb3koRkRTQV9pbmZvICppbmZvKQp7CiAgICBUUkFDRSgiKCVwKVxuIiwgaW5mbyk7CgogICAgaWYoaW5mby0+ZmxhZ3MgJiBGRFNBX0ZMQUdfSU5URVJOQUxfQUxMT0MpCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaW5mby0+bWVtKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMTBdCiAqCiAqIEluc2VydCBlbGVtZW50IGludG8gYW4gRkRTQSBhcnJheQogKi8KRFdPUkQgV0lOQVBJIEZEU0FfSW5zZXJ0SXRlbShGRFNBX2luZm8gKmluZm8sIERXT1JEIHdoZXJlLCB2b2lkICpibG9jaykKewogICAgVFJBQ0UoIiglcCAweCUwOGx4ICVwKVxuIiwgaW5mbywgd2hlcmUsIGJsb2NrKTsKICAgIGlmKHdoZXJlID4gaW5mby0+bnVtX2l0ZW1zKQogICAgICAgIHdoZXJlID0gaW5mby0+bnVtX2l0ZW1zOwoKICAgIGlmKGluZm8tPm51bV9pdGVtcyA+PSBpbmZvLT5ibG9ja3NfYWxsb2NlZCkKICAgIHsKICAgICAgICBEV09SRCBzaXplID0gKGluZm8tPmJsb2Nrc19hbGxvY2VkICsgaW5mby0+aW5jKSAqIGluZm8tPmJsb2NrX3NpemU7CiAgICAgICAgaWYoaW5mby0+ZmxhZ3MgJiAweDEpCiAgICAgICAgICAgIGluZm8tPm1lbSA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGluZm8tPm1lbSwgc2l6ZSk7CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgdm9pZCAqb2xkX21lbSA9IGluZm8tPm1lbTsKICAgICAgICAgICAgaW5mby0+bWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemUpOwogICAgICAgICAgICBtZW1jcHkoaW5mby0+bWVtLCBvbGRfbWVtLCBpbmZvLT5ibG9ja3NfYWxsb2NlZCAqIGluZm8tPmJsb2NrX3NpemUpOwogICAgICAgIH0KICAgICAgICBpbmZvLT5ibG9ja3NfYWxsb2NlZCArPSBpbmZvLT5pbmM7CiAgICAgICAgaW5mby0+ZmxhZ3MgfD0gMHgxOwogICAgfQoKICAgIGlmKHdoZXJlIDwgaW5mby0+bnVtX2l0ZW1zKQogICAgewogICAgICAgIG1lbW1vdmUoKGNoYXIqKWluZm8tPm1lbSArICh3aGVyZSArIDEpICogaW5mby0+YmxvY2tfc2l6ZSwKICAgICAgICAgICAgICAgIChjaGFyKilpbmZvLT5tZW0gKyB3aGVyZSAqIGluZm8tPmJsb2NrX3NpemUsCiAgICAgICAgICAgICAgICAoaW5mby0+bnVtX2l0ZW1zIC0gd2hlcmUpICogaW5mby0+YmxvY2tfc2l6ZSk7CiAgICB9CiAgICBtZW1jcHkoKGNoYXIqKWluZm8tPm1lbSArIHdoZXJlICogaW5mby0+YmxvY2tfc2l6ZSwgYmxvY2ssIGluZm8tPmJsb2NrX3NpemUpOwoKICAgIGluZm8tPm51bV9pdGVtcysrOwogICAgcmV0dXJuIHdoZXJlOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjExXQogKgogKiBEZWxldGUgYW4gZWxlbWVudCBmcm9tIGFuIEZEU0EgYXJyYXkuCiAqLwpCT09MIFdJTkFQSSBGRFNBX0RlbGV0ZUl0ZW0oRkRTQV9pbmZvICppbmZvLCBEV09SRCB3aGVyZSkKewogICAgVFJBQ0UoIiglcCAweCUwOGx4KVxuIiwgaW5mbywgd2hlcmUpOwoKICAgIGlmKHdoZXJlID49IGluZm8tPm51bV9pdGVtcykKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYod2hlcmUgPCBpbmZvLT5udW1faXRlbXMgLSAxKQogICAgewogICAgICAgIG1lbW1vdmUoKGNoYXIqKWluZm8tPm1lbSArIHdoZXJlICogaW5mby0+YmxvY2tfc2l6ZSwKICAgICAgICAgICAgICAgIChjaGFyKilpbmZvLT5tZW0gKyAod2hlcmUgKyAxKSAqIGluZm8tPmJsb2NrX3NpemUsCiAgICAgICAgICAgICAgICAoaW5mby0+bnVtX2l0ZW1zIC0gd2hlcmUgLSAxKSAqIGluZm8tPmJsb2NrX3NpemUpOwogICAgfQogICAgbWVtc2V0KChjaGFyKilpbmZvLT5tZW0gKyAoaW5mby0+bnVtX2l0ZW1zIC0gMSkgKiBpbmZvLT5ibG9ja19zaXplLAogICAgICAgICAgIDAsIGluZm8tPmJsb2NrX3NpemUpOwogICAgaW5mby0+bnVtX2l0ZW1zLS07CiAgICByZXR1cm4gVFJVRTsKfQoKCnR5cGVkZWYgc3RydWN0IHsKICAgIFJFRklJRCAgIHJlZmlkOwogICAgRFdPUkQgICAgaW5keDsKfSBJRkFDRV9JTkRFWF9UQkw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjE5XQogKgogKiBDYWxsIElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKCkgb24gYSB0YWJsZSBvZiBvYmplY3RzLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9QT0lOVEVSIG9yIEVfTk9JTlRFUkZBQ0UuCiAqLwpIUkVTVUxUIFdJTkFQSSBRSVNlYXJjaCgKCUxQVk9JRCB3LCAgICAgICAgICAgLyogW2luXSAgIFRhYmxlIG9mIGludGVyZmFjZXMgKi8KCUlGQUNFX0lOREVYX1RCTCAqeCwgLyogW2luXSAgIEFycmF5IG9mIFJFRklJRHMgYW5kIGluZGV4ZXMgaW50byB0aGUgdGFibGUgKi8KCVJFRklJRCByaWlkLCAgICAgICAgLyogW2luXSAgIFJFRklJRCB0byBnZXQgaW50ZXJmYWNlIGZvciAqLwoJTFBWT0lEICpwcHYpICAgICAgICAgIC8qIFtvdXRdICBEZXN0aW5hdGlvbiBmb3IgaW50ZXJmYWNlIHBvaW50ZXIgKi8KewoJSFJFU1VMVCByZXQ7CglJVW5rbm93biAqYV92dGJsOwoJSUZBQ0VfSU5ERVhfVEJMICp4bW92ZTsKCglUUkFDRSgiKCVwICVwICVzICVwKVxuIiwgdyx4LGRlYnVnc3RyX2d1aWQocmlpZCkscHB2KTsKCWlmIChwcHYpIHsKCSAgICB4bW92ZSA9IHg7CgkgICAgd2hpbGUgKHhtb3ZlLT5yZWZpZCkgewoJCVRSQUNFKCJ0cnlpbmcgKGluZHggJWxkKSAlc1xuIiwgeG1vdmUtPmluZHgsIGRlYnVnc3RyX2d1aWQoeG1vdmUtPnJlZmlkKSk7CgkJaWYgKElzRXF1YWxJSUQocmlpZCwgeG1vdmUtPnJlZmlkKSkgewoJCSAgICBhX3Z0YmwgPSAoSVVua25vd24qKSh4bW92ZS0+aW5keCArIChMUEJZVEUpdyk7CgkJICAgIFRSQUNFKCJtYXRjaGVkLCByZXR1cm5pbmcgKCVwKVxuIiwgYV92dGJsKTsKCQkgICAgKnBwdiA9IChMUFZPSUQpYV92dGJsOwoJCSAgICBJVW5rbm93bl9BZGRSZWYoYV92dGJsKTsKCQkgICAgcmV0dXJuIFNfT0s7CgkJfQoJCXhtb3ZlKys7CgkgICAgfQoKCSAgICBpZiAoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSkgewoJCWFfdnRibCA9IChJVW5rbm93biopKHgtPmluZHggKyAoTFBCWVRFKXcpOwoJCVRSQUNFKCJyZXR1cm5pbmcgZmlyc3QgZm9yIElVbmtub3duICglcClcbiIsIGFfdnRibCk7CgkJKnBwdiA9IChMUFZPSUQpYV92dGJsOwoJCUlVbmtub3duX0FkZFJlZihhX3Z0YmwpOwoJCXJldHVybiBTX09LOwoJICAgIH0KCSAgICAqcHB2ID0gMDsKCSAgICByZXQgPSBFX05PSU5URVJGQUNFOwoJfSBlbHNlCgkgICAgcmV0ID0gRV9QT0lOVEVSOwoKCVRSQUNFKCItLSAweCUwOGx4XG4iLCByZXQpOwoJcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIyMV0KICoKICogUmVtb3ZlIHRoZSAiUHJvcERsZ0ZvbnQiIHByb3BlcnR5IGZyb20gYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCBbSV0gV2luZG93IHRvIHJlbW92ZSB0aGUgcHJvcGVydHkgZnJvbQogKgogKiBSRVRVUk5TCiAqICBBIGhhbmRsZSB0byB0aGUgcmVtb3ZlZCBwcm9wZXJ0eSwgb3IgTlVMTCBpZiBpdCBkaWQgbm90IGV4aXN0LgogKi8KSEFORExFIFdJTkFQSSBTSFJlbW92ZURlZmF1bHREaWFsb2dGb250KEhXTkQgaFduZCkKewogIEhBTkRMRSBoUHJvcDsKCiAgVFJBQ0UoIiglcClcbiIsIGhXbmQpOwoKICBoUHJvcCA9IEdldFByb3BBKGhXbmQsICJQcm9wRGxnRm9udCIpOwoKICBpZihoUHJvcCkKICB7CiAgICBEZWxldGVPYmplY3QoaFByb3ApOwogICAgaFByb3AgPSBSZW1vdmVQcm9wQShoV25kLCAiUHJvcERsZ0ZvbnQiKTsKICB9CiAgcmV0dXJuIGhQcm9wOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjM2XQogKgogKiBMb2FkIHRoZSBpbi1wcm9jZXNzIHNlcnZlciBvZiBhIGdpdmVuIEdVSUQuCiAqCiAqIFBBUkFNUwogKiAgcmVmaWlkIFtJXSBHVUlEIG9mIHRoZSBzZXJ2ZXIgdG8gbG9hZC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogQSBoYW5kbGUgdG8gdGhlIGxvYWRlZCBzZXJ2ZXIgZGxsLgogKiAgRmFpbHVyZTogQSBOVUxMIGhhbmRsZS4KICovCkhNT0RVTEUgV0lOQVBJIFNIUGluRGxsT2ZDTFNJRChSRUZJSUQgcmVmaWlkKQp7CiAgICBIS0VZIG5ld2tleTsKICAgIERXT1JEIHR5cGUsIGNvdW50OwogICAgQ0hBUiB2YWx1ZVtNQVhfUEFUSF0sIHN0cmluZ1tNQVhfUEFUSF07CgogICAgc3RyY3B5KHN0cmluZywgIkNMU0lEXFwiKTsKICAgIFNIU3RyaW5nRnJvbUdVSURBKHJlZmlpZCwgc3RyaW5nICsgNiwgc2l6ZW9mKHN0cmluZykvc2l6ZW9mKGNoYXIpIC0gNik7CiAgICBzdHJjYXQoc3RyaW5nLCAiXFxJblByb2NTZXJ2ZXIzMiIpOwoKICAgIGNvdW50ID0gTUFYX1BBVEg7CiAgICBSZWdPcGVuS2V5RXhBKEhLRVlfQ0xBU1NFU19ST09ULCBzdHJpbmcsIDAsIDEsICZuZXdrZXkpOwogICAgUmVnUXVlcnlWYWx1ZUV4QShuZXdrZXksIDAsIDAsICZ0eXBlLCAoUEJZVEUpdmFsdWUsICZjb3VudCk7CiAgICBSZWdDbG9zZUtleShuZXdrZXkpOwogICAgcmV0dXJuIExvYWRMaWJyYXJ5RXhBKHZhbHVlLCAwLCAwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzN10KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNITFdBUElfMTgzLgogKi8KRFdPUkQgV0lOQVBJIFNIUmVnaXN0ZXJDbGFzc1coV05EQ0xBU1NXICogbHBXbmRDbGFzcykKewoJV05EQ0xBU1NXIFduZENsYXNzOwoKCVRSQUNFKCIoJXAgJXMpXG4iLGxwV25kQ2xhc3MtPmhJbnN0YW5jZSwgZGVidWdzdHJfdyhscFduZENsYXNzLT5scHN6Q2xhc3NOYW1lKSk7CgoJaWYgKEdldENsYXNzSW5mb1cobHBXbmRDbGFzcy0+aEluc3RhbmNlLCBscFduZENsYXNzLT5scHN6Q2xhc3NOYW1lLCAmV25kQ2xhc3MpKQoJCXJldHVybiBUUlVFOwoJcmV0dXJuIFJlZ2lzdGVyQ2xhc3NXKGxwV25kQ2xhc3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjM4XQogKgogKiBVbnJlZ2lzdGVyIGEgbGlzdCBvZiBjbGFzc2VzLgogKgogKiBQQVJBTVMKICogIGhJbnN0ICAgICAgW0ldIEFwcGxpY2F0aW9uIGluc3RhbmNlIHRoYXQgcmVnaXN0ZXJlZCB0aGUgY2xhc3NlcwogKiAgbHBwQ2xhc3NlcyBbSV0gTGlzdCBvZiBjbGFzcyBuYW1lcwogKiAgaUNvdW50ICAgICBbSV0gTnVtYmVyIG9mIG5hbWVzIGluIGxwcENsYXNzZXMKICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICovCnZvaWQgV0lOQVBJIFNIVW5yZWdpc3RlckNsYXNzZXNBKEhJTlNUQU5DRSBoSW5zdCwgTFBDU1RSICpscHBDbGFzc2VzLCBJTlQgaUNvdW50KQp7CiAgV05EQ0xBU1NBIFduZENsYXNzOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgaEluc3QsIGxwcENsYXNzZXMsIGlDb3VudCk7CgogIHdoaWxlIChpQ291bnQgPiAwKQogIHsKICAgIGlmIChHZXRDbGFzc0luZm9BKGhJbnN0LCAqbHBwQ2xhc3NlcywgJlduZENsYXNzKSkKICAgICAgVW5yZWdpc3RlckNsYXNzQSgqbHBwQ2xhc3NlcywgaEluc3QpOwogICAgbHBwQ2xhc3NlcysrOwogICAgaUNvdW50LS07CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjM5XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hVbnJlZ2lzdGVyQ2xhc3Nlc0EuCiAqLwp2b2lkIFdJTkFQSSBTSFVucmVnaXN0ZXJDbGFzc2VzVyhISU5TVEFOQ0UgaEluc3QsIExQQ1dTVFIgKmxwcENsYXNzZXMsIElOVCBpQ291bnQpCnsKICBXTkRDTEFTU1cgV25kQ2xhc3M7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBoSW5zdCwgbHBwQ2xhc3NlcywgaUNvdW50KTsKCiAgd2hpbGUgKGlDb3VudCA+IDApCiAgewogICAgaWYgKEdldENsYXNzSW5mb1coaEluc3QsICpscHBDbGFzc2VzLCAmV25kQ2xhc3MpKQogICAgICBVbnJlZ2lzdGVyQ2xhc3NXKCpscHBDbGFzc2VzLCBoSW5zdCk7CiAgICBscHBDbGFzc2VzKys7CiAgICBpQ291bnQtLTsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNDBdCiAqCiAqIENhbGwgVGhlIGNvcnJlY3QgKEFzY2lpL1VuaWNvZGUpIGRlZmF1bHQgd2luZG93IHByb2NlZHVyZSBmb3IgYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgW0ldIFdpbmRvdyB0byBjYWxsIHRoZSBkZWZhdWx0IHByb2NlZHVyZSBmb3IKICogIHVNZXNzYWdlIFtJXSBNZXNzYWdlIElECiAqICB3UGFyYW0gICBbSV0gV1BBUkFNIG9mIG1lc3NhZ2UKICogIGxQYXJhbSAgIFtJXSBMUEFSQU0gb2YgbWVzc2FnZQogKgogKiBSRVRVUk5TCiAqICBUaGUgcmVzdWx0IG9mIGNhbGxpbmcgRGVmV2luZG93UHJvY0EoKSBvciBEZWZXaW5kb3dQcm9jVygpLgogKi8KTFJFU1VMVCBDQUxMQkFDSyBTSERlZldpbmRvd1Byb2MoSFdORCBoV25kLCBVSU5UIHVNZXNzYWdlLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CglpZiAoSXNXaW5kb3dVbmljb2RlKGhXbmQpKQoJCXJldHVybiBEZWZXaW5kb3dQcm9jVyhoV25kLCB1TWVzc2FnZSwgd1BhcmFtLCBsUGFyYW0pOwoJcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNZXNzYWdlLCB3UGFyYW0sIGxQYXJhbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICBbU0hMV0FQSS4yNTZdCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9HZXRTaXRlKExQVU5LTk9XTiBscFVua25vd24sIFJFRklJRCBpaWQsIFBWT0lEICpscHBTaXRlKQp7CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwogIExQT0JKRUNUV0lUSFNJVEUgbHBTaXRlID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIGxwVW5rbm93biwgZGVidWdzdHJfZ3VpZChpaWQpLCBscHBTaXRlKTsKCiAgaWYgKGxwVW5rbm93biAmJiBpaWQgJiYgbHBwU2l0ZSkKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPYmplY3RXaXRoU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscFNpdGUpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscFNpdGUpCiAgICB7CiAgICAgIGhSZXQgPSBJT2JqZWN0V2l0aFNpdGVfR2V0U2l0ZShscFNpdGUsIGlpZCwgbHBwU2l0ZSk7CiAgICAgIElPYmplY3RXaXRoU2l0ZV9SZWxlYXNlKGxwU2l0ZSk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjU3XQogKgogKiBDcmVhdGUgYSB3b3JrZXIgd2luZG93IHVzaW5nIENyZWF0ZVdpbmRvd0V4QSgpLgogKgogKiBQQVJBTVMKICogIHduZFByb2MgICAgW0ldIFdpbmRvdyBwcm9jZWR1cmUKICogIGhXbmRQYXJlbnQgW0ldIFBhcmVudCB3aW5kb3cKICogIGR3RXhTdHlsZSAgW0ldIEV4dHJhIHN0eWxlIGZsYWdzCiAqICBkd1N0eWxlICAgIFtJXSBTdHlsZSBmbGFncwogKiAgaE1lbnUgICAgICBbSV0gV2luZG93IG1lbnUKICogIHogICAgICAgICAgW0ldIFVua25vd24KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIHdpbmRvdyBoYW5kbGUgb2YgdGhlIG5ld2x5IGNyZWF0ZWQgd2luZG93LgogKiAgRmFpbHVyZTogMC4KICovCkhXTkQgV0lOQVBJIFNIQ3JlYXRlV29ya2VyV2luZG93QShMT05HIHduZFByb2MsIEhXTkQgaFduZFBhcmVudCwgRFdPUkQgZHdFeFN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1N0eWxlLCBITUVOVSBoTWVudSwgTE9ORyB6KQp7CiAgc3RhdGljIGNvbnN0IGNoYXIqIHN6Q2xhc3MgPSAiV29ya2VyQSI7CiAgV05EQ0xBU1NBIHdjOwogIEhXTkQgaFduZDsKCiAgVFJBQ0UoIigweCUwOGx4LCVwLDB4JTA4bHgsMHglMDhseCwlcCwweCUwOGx4KVxuIiwKICAgICAgICAgd25kUHJvYywgaFduZFBhcmVudCwgZHdFeFN0eWxlLCBkd1N0eWxlLCBoTWVudSwgeik7CgogIC8qIENyZWF0ZSBXaW5kb3cgY2xhc3MgKi8KICB3Yy5zdHlsZSAgICAgICAgID0gMDsKICB3Yy5scGZuV25kUHJvYyAgID0gRGVmV2luZG93UHJvY0E7CiAgd2MuY2JDbHNFeHRyYSAgICA9IDA7CiAgd2MuY2JXbmRFeHRyYSAgICA9IDQ7CiAgd2MuaEluc3RhbmNlICAgICA9IHNobHdhcGlfaEluc3RhbmNlOwogIHdjLmhJY29uICAgICAgICAgPSBOVUxMOwogIHdjLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yQShOVUxMLCAoTFBTVFIpSURDX0FSUk9XKTsKICB3Yy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSCkoQ09MT1JfQlRORkFDRSArIDEpOwogIHdjLmxwc3pNZW51TmFtZSAgPSBOVUxMOwogIHdjLmxwc3pDbGFzc05hbWUgPSBzekNsYXNzOwoKICBTSFJlZ2lzdGVyQ2xhc3NBKCZ3Yyk7IC8qIFJlZ2lzdGVyIGNsYXNzICovCgogIC8qIEZJWE1FOiBTZXQgZXh0cmEgYml0cyBpbiBkd0V4U3R5bGUgKi8KCiAgaFduZCA9IENyZWF0ZVdpbmRvd0V4QShkd0V4U3R5bGUsIHN6Q2xhc3MsIDAsIGR3U3R5bGUsIDAsIDAsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBoV25kUGFyZW50LCBoTWVudSwgc2hsd2FwaV9oSW5zdGFuY2UsIDApOwogIGlmIChoV25kKQogIHsKICAgIFNldFdpbmRvd0xvbmdQdHJXKGhXbmQsIERXTFBfTVNHUkVTVUxULCB6KTsKCiAgICBpZiAod25kUHJvYykKICAgICAgU2V0V2luZG93TG9uZ1B0ckEoaFduZCwgR1dMUF9XTkRQUk9DLCB3bmRQcm9jKTsKICB9CiAgcmV0dXJuIGhXbmQ7Cn0KCnR5cGVkZWYgc3RydWN0IHRhZ1BPTElDWURBVEEKewogIERXT1JEIHBvbGljeTsgICAgICAgIC8qIGZsYWdzIHZhbHVlIHBhc3NlZCB0byBTSFJlc3RyaWN0ZWQgKi8KICBMUENXU1RSIGFwcHN0cjsgICAgICAvKiBhcHBsaWNhdGlvbiBzdHIgc3VjaCBhcyAiRXhwbG9yZXIiICovCiAgTFBDV1NUUiBrZXlzdHI7ICAgICAgLyogbmFtZSBvZiB0aGUgYWN0dWFsIHJlZ2lzdHJ5IGtleSAvIHBvbGljeSAqLwp9IFBPTElDWURBVEEsICpMUFBPTElDWURBVEE7CgojZGVmaW5lIFNIRUxMX05PX1BPTElDWSAweGZmZmZmZmZmCgovKiBkZWZhdWx0IHNoZWxsIHBvbGljeSByZWdpc3RyeSBrZXkgKi8Kc3RhdGljIGNvbnN0IFdDSEFSIHN0clJlZ2lzdHJ5UG9saWN5V1tdID0geydTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywnTScsJ2knLCdjJywncicsJ28nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1xcJywnUCcsJ28nLCdsJywnaScsJ2MnLCdpJywnZScsJ3MnLDB9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgICAgICAgICAgICAgICAgICAgICAgICAgW1NITFdBUEkuMjcxXQogKgogKiBSZXRyaWV2ZSBhIHBvbGljeSB2YWx1ZSBmcm9tIHRoZSByZWdpc3RyeS4KICoKICogUEFSQU1TCiAqICBscFN1YktleSAgIFtJXSAgIHJlZ2lzdHJ5IGtleSBuYW1lCiAqICBscFN1Yk5hbWUgIFtJXSAgIHN1Ym5hbWUgb2YgcmVnaXN0cnkga2V5CiAqICBscFZhbHVlICAgIFtJXSAgIHZhbHVlIG5hbWUgb2YgcmVnaXN0cnkgdmFsdWUKICoKICogUkVUVVJOUwogKiAgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVnaXN0cnkga2V5IG9yIDAgaWYgbm90IGZvdW5kCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRSZXN0cmljdGlvbihMUENXU1RSIGxwU3ViS2V5LCBMUENXU1RSIGxwU3ViTmFtZSwgTFBDV1NUUiBscFZhbHVlKQp7CglEV09SRCByZXR2YWwsIGRhdHNpemUgPSBzaXplb2YocmV0dmFsKTsKCUhLRVkgaEtleTsKCglpZiAoIWxwU3ViS2V5KQoJICBscFN1YktleSA9IHN0clJlZ2lzdHJ5UG9saWN5VzsKCglyZXR2YWwgPSBSZWdPcGVuS2V5VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIGxwU3ViS2V5LCAmaEtleSk7CiAgICBpZiAocmV0dmFsICE9IEVSUk9SX1NVQ0NFU1MpCgkgIHJldHZhbCA9IFJlZ09wZW5LZXlXKEhLRVlfQ1VSUkVOVF9VU0VSLCBscFN1YktleSwgJmhLZXkpOwoJaWYgKHJldHZhbCAhPSBFUlJPUl9TVUNDRVNTKQoJICByZXR1cm4gMDsKCglTSEdldFZhbHVlVyhoS2V5LCBscFN1Yk5hbWUsIGxwVmFsdWUsIE5VTEwsIChMUEJZVEUpJnJldHZhbCwgJmRhdHNpemUpOwoJUmVnQ2xvc2VLZXkoaEtleSk7CglyZXR1cm4gcmV0dmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgICAgICAgICAgICAgICAgICAgICAgIFtTSExXQVBJLjI2Nl0KICoKICogSGVscGVyIGZ1bmN0aW9uIHRvIHJldHJpZXZlIHRoZSBwb3NzaWJseSBjYWNoZWQgdmFsdWUgZm9yIGEgc3BlY2lmaWMgcG9saWN5CiAqCiAqIFBBUkFNUwogKiAgcG9saWN5ICAgICBbSV0gICBUaGUgcG9saWN5IHRvIGxvb2sgZm9yCiAqICBpbml0aWFsICAgIFtJXSAgIE1haW4gcmVnaXN0cnkga2V5IHRvIG9wZW4sIGlmIE5VTEwgdXNlIGRlZmF1bHQKICogIHBvbFRhYmxlICAgW0ldICAgVGFibGUgb2Yga25vd24gcG9saWNpZXMsIDAgdGVybWluYXRlZAogKiAgcG9sQXJyICAgICBbSV0gICBDYWNoZSBhcnJheSBvZiBwb2xpY3kgdmFsdWVzCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXRyaWV2ZWQgcG9saWN5IHZhbHVlIG9yIDAgaWYgbm90IHN1Y2Nlc3NmdWwKICoKICogTk9URVMKICogIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBieSB0aGUgbmF0aXZlIFNIUmVzdHJpY3RlZCBmdW5jdGlvbiB0byBzZWFyY2ggZm9yIHRoZQogKiAgcG9saWN5IGFuZCBjYWNoZSBpdCBvbmNlIHJldHJpZXZlZC4gVGhlIGN1cnJlbnQgV2luZSBpbXBsZW1lbnRhdGlvbiB1c2VzIGEKICogIGRpZmZlcmVudCBQT0xJQ1lEQVRBIHN0cnVjdHVyZSBhbmQgaW1wbGVtZW50cyBhIHNpbWlsYXIgYWxnb3JpdGhtZSBhZGFwdGVkIHRvCiAqICB0aGF0IHN0cnVjdHVyZS4KICovCkRXT1JEIFdJTkFQSSBTSFJlc3RyaWN0aW9uTG9va3VwKAoJRFdPUkQgcG9saWN5LAoJTFBDV1NUUiBpbml0aWFsLAoJTFBQT0xJQ1lEQVRBIHBvbFRhYmxlLAoJTFBEV09SRCBwb2xBcnIpCnsKCVRSQUNFKCIoMHglMDhseCAlcyAlcCAlcClcbiIsIHBvbGljeSwgZGVidWdzdHJfdyhpbml0aWFsKSwgcG9sVGFibGUsIHBvbEFycik7CgoJaWYgKCFwb2xUYWJsZSB8fCAhcG9sQXJyKQoJICByZXR1cm4gMDsKCglmb3IgKDtwb2xUYWJsZS0+cG9saWN5OyBwb2xUYWJsZSsrLCBwb2xBcnIrKykKCXsKCSAgaWYgKHBvbGljeSA9PSBwb2xUYWJsZS0+cG9saWN5KQoJICB7CgkgICAgLyogd2UgaGF2ZSBhIGtub3duIHBvbGljeSAqLwoKCSAgICAvKiBjaGVjayBpZiB0aGlzIHBvbGljeSBoYXMgYmVlbiBjYWNoZWQgKi8KCQlpZiAoKnBvbEFyciA9PSBTSEVMTF9OT19QT0xJQ1kpCgkgICAgICAqcG9sQXJyID0gU0hHZXRSZXN0cmljdGlvbihpbml0aWFsLCBwb2xUYWJsZS0+YXBwc3RyLCBwb2xUYWJsZS0+a2V5c3RyKTsKCSAgICByZXR1cm4gKnBvbEFycjsKCSAgfQoJfQoJLyogd2UgZG9uJ3Qga25vdyB0aGlzIHBvbGljeSwgcmV0dXJuIDAgKi8KCVRSQUNFKCJ1bmtub3duIHBvbGljeTogKCUwOGx4KVxuIiwgcG9saWN5KTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjY3XQogKgogKiBHZXQgYW4gaW50ZXJmYWNlIGZyb20gYW4gb2JqZWN0LgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBwcHYgY29udGFpbnMgdGhlIHJlcXVlc3RlZCBpbnRlcmZhY2UuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUuCiAqCiAqIE5PVEVTCiAqICAgVGhpcyBRdWVyeUludGVyZmFjZSBhc2tzIHRoZSBpbm5lciBvYmplY3QgZm9yIGFuIGludGVyZmFjZS4gSW4gY2FzZQogKiAgIG9mIGFnZ3JlZ2F0aW9uIHRoaXMgcmVxdWVzdCB3b3VsZCBiZSBmb3J3YXJkZWQgYnkgdGhlIGlubmVyIHRvIHRoZQogKiAgIG91dGVyIG9iamVjdC4gVGhpcyBmdW5jdGlvbiBhc2tzIHRoZSBpbm5lciBvYmplY3QgZGlyZWN0bHkgZm9yIHRoZQogKiAgIGludGVyZmFjZSBjaXJjdW12ZW50aW5nIHRoZSBmb3J3YXJkaW5nIHRvIHRoZSBvdXRlciBvYmplY3QuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFdlYWtRdWVyeUludGVyZmFjZSgKCUlVbmtub3duICogcFVuaywgICAvKiBbaW5dIE91dGVyIG9iamVjdCAqLwoJSVVua25vd24gKiBwSW5uZXIsIC8qIFtpbl0gSW5uZXIgb2JqZWN0ICovCglJSUQgKiByaWlkLCAvKiBbaW5dIEludGVyZmFjZSBHVUlEIHRvIHF1ZXJ5IGZvciAqLwoJTFBWT0lEKiBwcHYpIC8qIFtvdXRdIERlc3RpbmF0aW9uIGZvciBxdWVyaWVkIGludGVyZmFjZSAqLwp7CglIUkVTVUxUIGhyZXQgPSBFX05PSU5URVJGQUNFOwoJVFJBQ0UoIihwVW5rPSVwIHBJbm5lcj0lcFxuXHRJSUQ6ICAlcyAlcClcbiIscFVuayxwSW5uZXIsZGVidWdzdHJfZ3VpZChyaWlkKSwgcHB2KTsKCgkqcHB2ID0gTlVMTDsKCWlmKHBVbmsgJiYgcElubmVyKSB7CgkgICAgaHJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKHBJbm5lciwgcmlpZCwgKExQVk9JRCopcHB2KTsKCSAgICBpZiAoU1VDQ0VFREVEKGhyZXQpKSBJVW5rbm93bl9SZWxlYXNlKHBVbmspOwoJfQoJVFJBQ0UoIi0tIDB4JTA4bHhcbiIsIGhyZXQpOwoJcmV0dXJuIGhyZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjhdCiAqCiAqIE1vdmUgYSByZWZlcmVuY2UgZnJvbSBvbmUgaW50ZXJmYWNlIHRvIGFub3RoZXIuCiAqCiAqIFBBUkFNUwogKiAgIGxwRGVzdCAgICAgW09dIERlc3RpbmF0aW9uIHRvIHJlY2VpdmUgdGhlIHJlZmVyZW5jZQogKiAgIGxwcFVua25vd24gW09dIFNvdXJjZSB0byBnaXZlIHVwIHRoZSByZWZlcmVuY2UgdG8gbHBEZXN0CiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpWT0lEIFdJTkFQSSBTSFdlYWtSZWxlYXNlSW50ZXJmYWNlKElVbmtub3duICpscERlc3QsIElVbmtub3duICoqbHBwVW5rbm93bikKewogIFRSQUNFKCIoJXAsJXApXG4iLCBscERlc3QsIGxwcFVua25vd24pOwoKICBpZiAoKmxwcFVua25vd24pCiAgewogICAgLyogQ29weSBSZWZlcmVuY2UqLwogICAgSVVua25vd25fQWRkUmVmKGxwRGVzdCk7CiAgICBJVW5rbm93bl9BdG9taWNSZWxlYXNlKGxwcFVua25vd24pOyAvKiBSZWxlYXNlIGV4aXN0aW5nIGludGVyZmFjZSAqLwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI2OV0KICoKICogQ29udmVydCBhbiBBU0NJSSBzdHJpbmcgb2YgYSBDTFNJRCBpbnRvIGEgQ0xTSUQuCiAqCiAqIFBBUkFNUwogKiAgaWRzdHIgW0ldIFN0cmluZyByZXByZXNlbnRpbmcgYSBDTFNJRCBpbiByZWdpc3RyeSBmb3JtYXQKICogIGlkICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIGNvbnZlcnRlZCBDTFNJRAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLiBpZCBjb250YWlucyB0aGUgY29udmVydGVkIENMU0lELgogKiAgRmFpbHVyZTogRkFMU0UuCiAqLwpCT09MIFdJTkFQSSBHVUlERnJvbVN0cmluZ0EoTFBDU1RSIGlkc3RyLCBDTFNJRCAqaWQpCnsKICBXQ0hBUiB3Q2xzaWRbNDBdOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBpZHN0ciwgLTEsIHdDbHNpZCwgc2l6ZW9mKHdDbHNpZCkvc2l6ZW9mKFdDSEFSKSk7CiAgcmV0dXJuIFNVQ0NFRURFRChDTFNJREZyb21TdHJpbmdXcmFwKHdDbHNpZCwgaWQpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3MF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIEdVSURGcm9tU3RyaW5nQS4KICovCkJPT0wgV0lOQVBJIEdVSURGcm9tU3RyaW5nVyhMUENXU1RSIGlkc3RyLCBDTFNJRCAqaWQpCnsKICByZXR1cm4gU1VDQ0VFREVEKENMU0lERnJvbVN0cmluZ1dyYXAoaWRzdHIsIGlkKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzZdCiAqCiAqIERldGVybWluZSBpZiB0aGUgYnJvd3NlciBpcyBpbnRlZ3JhdGVkIGludG8gdGhlIHNoZWxsLCBhbmQgc2V0IGEgcmVnaXN0cnkKICoga2V5IGFjY29yZGluZ2x5LgogKgogKiBQQVJBTVMKICogIE5vbmUuCiAqCiAqIFJFVFVSTlMKICogIDEsIElmIHRoZSBicm93c2VyIGlzIG5vdCBpbnRlZ3JhdGVkLgogKiAgMiwgSWYgdGhlIGJyb3dzZXIgaXMgaW50ZWdyYXRlZC4KICoKICogTk9URVMKICogIFRoZSBrZXkgIkhLTE1cU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVncmF0ZWRCcm93c2VyIiBpcwogKiAgZWl0aGVyIHNldCB0byBUUlVFLCBvciByZW1vdmVkIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSBicm93c2VyIGlzIGRlZW1lZAogKiAgdG8gYmUgaW50ZWdyYXRlZC4KICovCkRXT1JEIFdJTkFQSSBXaGljaFBsYXRmb3JtKCkKewogIHN0YXRpYyBMUENTVFIgc3pJbnRlZ3JhdGVkQnJvd3NlciA9ICJJbnRlZ3JhdGVkQnJvd3NlciI7CiAgc3RhdGljIERXT1JEIGR3U3RhdGUgPSAwOwogIEhLRVkgaEtleTsKICBEV09SRCBkd1JldCwgZHdEYXRhLCBkd1NpemU7CgogIGlmIChkd1N0YXRlKQogICAgcmV0dXJuIGR3U3RhdGU7CgogIC8qIElmIHNoZWxsMzIgZXhwb3J0cyBEbGxHZXRWZXJzaW9uKCksIHRoZSBicm93c2VyIGlzIGludGVncmF0ZWQgKi8KICBHRVRfRlVOQyhwRGxsR2V0VmVyc2lvbiwgc2hlbGwzMiwgIkRsbEdldFZlcnNpb24iLCAxKTsKICBkd1N0YXRlID0gcERsbEdldFZlcnNpb24gPyAyIDogMTsKCiAgLyogU2V0IG9yIGRlbGV0ZSB0aGUga2V5IGFjY29yZGluZ2x5ICovCiAgZHdSZXQgPSBSZWdPcGVuS2V5RXhBKEhLRVlfTE9DQUxfTUFDSElORSwKICAgICAgICAgICAgICAgICAgICAgICAgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXEludGVybmV0IEV4cGxvcmVyIiwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9BTExfQUNDRVNTLCAmaEtleSk7CiAgaWYgKCFkd1JldCkKICB7CiAgICBkd1JldCA9IFJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgc3pJbnRlZ3JhdGVkQnJvd3NlciwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSZkd0RhdGEsICZkd1NpemUpOwoKICAgIGlmICghZHdSZXQgJiYgZHdTdGF0ZSA9PSAxKQogICAgewogICAgICAvKiBWYWx1ZSBleGlzdHMgYnV0IGJyb3dzZXIgaXMgbm90IGludGVncmF0ZWQgKi8KICAgICAgUmVnRGVsZXRlVmFsdWVBKGhLZXksIHN6SW50ZWdyYXRlZEJyb3dzZXIpOwogICAgfQogICAgZWxzZSBpZiAoZHdSZXQgJiYgZHdTdGF0ZSA9PSAyKQogICAgewogICAgICAvKiBCcm93c2VyIGlzIGludGVncmF0ZWQgYnV0IHZhbHVlIGRvZXMgbm90IGV4aXN0ICovCiAgICAgIGR3RGF0YSA9IFRSVUU7CiAgICAgIFJlZ1NldFZhbHVlRXhBKGhLZXksIHN6SW50ZWdyYXRlZEJyb3dzZXIsIDAsIFJFR19EV09SRCwKICAgICAgICAgICAgICAgICAgICAgKExQQllURSkmZHdEYXRhLCBzaXplb2YoZHdEYXRhKSk7CiAgICB9CiAgICBSZWdDbG9zZUtleShoS2V5KTsKICB9CiAgcmV0dXJuIGR3U3RhdGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzhdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSENyZWF0ZVdvcmtlcldpbmRvd0EuCiAqLwpIV05EIFdJTkFQSSBTSENyZWF0ZVdvcmtlcldpbmRvd1coTE9ORyB3bmRQcm9jLCBIV05EIGhXbmRQYXJlbnQsIERXT1JEIGR3RXhTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdTdHlsZSwgSE1FTlUgaE1lbnUsIExPTkcgeikKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekNsYXNzW10gPSB7ICdXJywgJ28nLCAncicsICdrJywgJ2UnLCAncicsICdXJywgJ1wwJyB9OwogIFdORENMQVNTVyB3YzsKICBIV05EIGhXbmQ7CgogIFRSQUNFKCIoMHglMDhseCwlcCwweCUwOGx4LDB4JTA4bHgsJXAsMHglMDhseClcbiIsCiAgICAgICAgIHduZFByb2MsIGhXbmRQYXJlbnQsIGR3RXhTdHlsZSwgZHdTdHlsZSwgaE1lbnUsIHopOwoKICAvKiBJZiBvdXIgT1MgaXMgbmF0aXZlbHkgQVNDSUksIHVzZSB0aGUgQVNDSUkgdmVyc2lvbiAqLwogIGlmICghKEdldFZlcnNpb24oKSAmIDB4ODAwMDAwMDApKSAgLyogTlQgKi8KICAgIHJldHVybiBTSENyZWF0ZVdvcmtlcldpbmRvd0Eod25kUHJvYywgaFduZFBhcmVudCwgZHdFeFN0eWxlLCBkd1N0eWxlLCBoTWVudSwgeik7CgogIC8qIENyZWF0ZSBXaW5kb3cgY2xhc3MgKi8KICB3Yy5zdHlsZSAgICAgICAgID0gMDsKICB3Yy5scGZuV25kUHJvYyAgID0gRGVmV2luZG93UHJvY1c7CiAgd2MuY2JDbHNFeHRyYSAgICA9IDA7CiAgd2MuY2JXbmRFeHRyYSAgICA9IDQ7CiAgd2MuaEluc3RhbmNlICAgICA9IHNobHdhcGlfaEluc3RhbmNlOwogIHdjLmhJY29uICAgICAgICAgPSBOVUxMOwogIHdjLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yVyhOVUxMLCAoTFBXU1RSKUlEQ19BUlJPVyk7CiAgd2MuaGJyQmFja2dyb3VuZCA9IChIQlJVU0gpKENPTE9SX0JUTkZBQ0UgKyAxKTsKICB3Yy5scHN6TWVudU5hbWUgID0gTlVMTDsKICB3Yy5scHN6Q2xhc3NOYW1lID0gc3pDbGFzczsKCiAgU0hSZWdpc3RlckNsYXNzVygmd2MpOyAvKiBSZWdpc3RlciBjbGFzcyAqLwoKICAvKiBGSVhNRTogU2V0IGV4dHJhIGJpdHMgaW4gZHdFeFN0eWxlICovCgogIGhXbmQgPSBDcmVhdGVXaW5kb3dFeFcoZHdFeFN0eWxlLCBzekNsYXNzLCAwLCBkd1N0eWxlLCAwLCAwLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgaFduZFBhcmVudCwgaE1lbnUsIHNobHdhcGlfaEluc3RhbmNlLCAwKTsKICBpZiAoaFduZCkKICB7CiAgICBTZXRXaW5kb3dMb25nUHRyVyhoV25kLCBEV0xQX01TR1JFU1VMVCwgeik7CgogICAgaWYgKHduZFByb2MpCiAgICAgIFNldFdpbmRvd0xvbmdQdHJXKGhXbmQsIEdXTFBfV05EUFJPQywgd25kUHJvYyk7CiAgfQogIHJldHVybiBoV25kOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjc5XQogKgogKiBHZXQgYW5kIHNob3cgYSBjb250ZXh0IG1lbnUgZnJvbSBhIHNoZWxsIGZvbGRlci4KICoKICogUEFSQU1TCiAqICBoV25kICAgICAgICAgICBbSV0gV2luZG93IGRpc3BsYXlpbmcgdGhlIHNoZWxsIGZvbGRlcgogKiAgbHBGb2xkZXIgICAgICAgW0ldIElTaGVsbEZvbGRlciBpbnRlcmZhY2UKICogIGxwQXBpZGwgICAgICAgIFtJXSBJZCBmb3IgdGhlIHBhcnRpY3VsYXIgZm9sZGVyIGRlc2lyZWQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSBpbmRpY2F0aW5nIHRoZSBlcnJvci4KICovCkhSRVNVTFQgV0lOQVBJIFNISW52b2tlRGVmYXVsdENvbW1hbmQoSFdORCBoV25kLCBJU2hlbGxGb2xkZXIqIGxwRm9sZGVyLCBMUENJVEVNSURMSVNUIGxwQXBpZGwpCnsKICByZXR1cm4gU0hJbnZva2VDb21tYW5kKGhXbmQsIGxwRm9sZGVyLCBscEFwaWRsLCBGQUxTRSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODFdCiAqCiAqIF9TSFBhY2tEaXNwUGFyYW1zVgogKi8KSFJFU1VMVCBXSU5BUEkgU0hQYWNrRGlzcFBhcmFtc1YoTFBWT0lEIHcsIExQVk9JRCB4LCBMUFZPSUQgeSwgTFBWT0lEIHopCnsKCUZJWE1FKCIlcCAlcCAlcCAlcFxuIix3LHgseSx6KTsKCXJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICBbU0hMV0FQSS4yODJdCiAqCiAqIFRoaXMgZnVuY3Rpb24gc2VlbXMgdG8gYmUgYSBmb3J3YXJkIHRvIFNIUGFja0Rpc3BQYXJhbXNWICh3aGF0ZXZlciBUSEFUCiAqIGZ1bmN0aW9uIGRvZXMuLi4pLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hQYWNrRGlzcFBhcmFtcyhMUFZPSUQgdywgTFBWT0lEIHgsIExQVk9JRCB5LCBMUFZPSUQgeikKewogIEZJWE1FKCIlcCAlcCAlcCAlcFxuIiwgdywgeCwgeSwgeik7CiAgcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4NF0KICoKICogX0lDb25uZWN0aW9uUG9pbnRfU2ltcGxlSW52b2tlCiAqLwpEV09SRCBXSU5BUEkgSUNvbm5lY3Rpb25Qb2ludF9TaW1wbGVJbnZva2UoCglMUFZPSUQgeCwKCUxQVk9JRCB5LAoJTFBWT0lEIHopCnsKICAgICAgICBGSVhNRSgiKCVwICVwICVwKSBzdHViXG4iLHgseSx6KTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg1XQogKgogKiBOb3RpZnkgYW4gSUNvbm5lY3Rpb25Qb2ludCBvYmplY3Qgb2YgY2hhbmdlcy4KICoKICogUEFSQU1TCiAqICBscENQICAgW0ldIE9iamVjdCB0byBub3RpZnkKICogIGRpc3BJRCBbSV0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfTk9JTlRFUkZBQ0UsIGlmIGxwQ1AgaXMgTlVMTCBvciBkb2VzIG5vdCBzdXBwb3J0IHRoZQogKiAgICAgICAgICAgSUNvbm5lY3Rpb25Qb2ludCBpbnRlcmZhY2UuCiAqLwpIUkVTVUxUIFdJTkFQSSBJQ29ubmVjdGlvblBvaW50X09uQ2hhbmdlZChJQ29ubmVjdGlvblBvaW50KiBscENQLCBESVNQSUQgZGlzcElEKQp7CiAgSUVudW1Db25uZWN0aW9ucyAqbHBFbnVtOwogIEhSRVNVTFQgaFJldCA9IEVfTk9JTlRFUkZBQ0U7CgogIFRSQUNFKCIoJXAsMHglOGxYKVxuIiwgbHBDUCwgZGlzcElEKTsKCiAgLyogR2V0IGFuIGVudW1lcmF0b3IgZm9yIHRoZSBjb25uZWN0aW9ucyAqLwogIGlmIChscENQKQogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfRW51bUNvbm5lY3Rpb25zKGxwQ1AsICZscEVudW0pOwoKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIElQcm9wZXJ0eU5vdGlmeVNpbmsgKmxwU2luazsKICAgIENPTk5FQ1REQVRBIGNvbm5EYXRhOwogICAgVUxPTkcgdWxGZXRjaGVkOwoKICAgIC8qIENhbGwgT25DaGFuZ2VkKCkgZm9yIGV2ZXJ5IG5vdGlmeSBzaW5rIGluIHRoZSBjb25uZWN0aW9uIHBvaW50ICovCiAgICB3aGlsZSAoSUVudW1Db25uZWN0aW9uc19OZXh0KGxwRW51bSwgMSwgJmNvbm5EYXRhLCAmdWxGZXRjaGVkKSA9PSBTX09LKQogICAgewogICAgICBpZiAoU1VDQ0VFREVEKElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGNvbm5EYXRhLnBVbmssICZJSURfSVByb3BlcnR5Tm90aWZ5U2luaywgKHZvaWQqKikmbHBTaW5rKSkgJiYKICAgICAgICAgIGxwU2luaykKICAgICAgewogICAgICAgIElQcm9wZXJ0eU5vdGlmeVNpbmtfT25DaGFuZ2VkKGxwU2luaywgZGlzcElEKTsKICAgICAgICBJUHJvcGVydHlOb3RpZnlTaW5rX1JlbGVhc2UobHBTaW5rKTsKICAgICAgfQogICAgICBJVW5rbm93bl9SZWxlYXNlKGNvbm5EYXRhLnBVbmspOwogICAgfQoKICAgIElFbnVtQ29ubmVjdGlvbnNfUmVsZWFzZShscEVudW0pOwogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4N10KICoKICogTm90aWZ5IGFuIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgb2JqZWN0IG9mIGNoYW5nZXMuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gbm90aWZ5CiAqICBkaXNwSUQgICAgW0ldCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gaXMgTlVMTCBvciBkb2VzIG5vdCBzdXBwb3J0IHRoZQogKiAgICAgICAgICAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciBpbnRlcmZhY2UuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9DUENvbnRhaW5lck9uQ2hhbmdlZChJVW5rbm93biAqbHBVbmtub3duLCBESVNQSUQgZGlzcElEKQp7CiAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciogbHBDUEMgPSBOVUxMOwogIEhSRVNVTFQgaFJldCA9IEVfTk9JTlRFUkZBQ0U7CgogIFRSQUNFKCIoJXAsMHglOGxYKVxuIiwgbHBVbmtub3duLCBkaXNwSUQpOwoKICBpZiAobHBVbmtub3duKQogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JQ29ubmVjdGlvblBvaW50Q29udGFpbmVyLCAodm9pZCoqKSZscENQQyk7CgogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgSUNvbm5lY3Rpb25Qb2ludCogbHBDUDsKCiAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lcl9GaW5kQ29ubmVjdGlvblBvaW50KGxwQ1BDLCAmSUlEX0lQcm9wZXJ0eU5vdGlmeVNpbmssICZscENQKTsKICAgIElDb25uZWN0aW9uUG9pbnRDb250YWluZXJfUmVsZWFzZShscENQQyk7CgogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfT25DaGFuZ2VkKGxwQ1AsIGRpc3BJRCk7CiAgICBJQ29ubmVjdGlvblBvaW50X1JlbGVhc2UobHBDUCk7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg5XQogKgogKiBTZWUgUGxheVNvdW5kVy4KICovCkJPT0wgV0lOQVBJIFBsYXlTb3VuZFdyYXBXKExQQ1dTVFIgcHN6U291bmQsIEhNT0RVTEUgaG1vZCwgRFdPUkQgZmR3U291bmQpCnsKICBHRVRfRlVOQyhwUGxheVNvdW5kVywgd2lubW0sICJQbGF5U291bmRXIiwgRkFMU0UpOwogIHJldHVybiBwUGxheVNvdW5kVyhwc3pTb3VuZCwgaG1vZCwgZmR3U291bmQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjk0XQogKi8KQk9PTCBXSU5BUEkgU0hHZXRJbmlTdHJpbmdXKExQU1RSIHN0cjEsIExQU1RSIHN0cjIsIExQU1RSIHBTdHIsIERXT1JEIHNvbWVfbGVuLCAgTFBDU1RSIGxwU3RyMikKewogICAgLyoKICAgICAqIHN0cjE6CQkiSSIJIkkiCXB1c2hsIGVzcCsweDIwCiAgICAgKiBzdHIyOgkJIlUiCSJJIglwdXNobCAweDc3YzkzODEwCiAgICAgKiAoaXMgIkkiIGFuZCAiVSIgImludGVnZXIiIGFuZCAidW5zaWduZWQiID8/KQogICAgICoKICAgICAqIHBTdHI6CQkiIgkiIglwdXNobCBlYXgKICAgICAqIHNvbWVfbGVuOgkweDgyNAkweDEwNAlwdXNobCAweDgyNAogICAgICogbHBTdHIyOgkJIiVsIgkiJWwiCXB1c2hsIGVzcCsweGMKICAgICAqCiAgICAgKiBzaGx3YXBpLiBTdHJDcHlOVyhscFN0cjIsIGlycmVsZXZhbnRfdmFyLCAweDEwNCk7CiAgICAgKiBMb2NhbEFsbG9jKDB4MDAsIHNvbWVfbGVuKSAtPiBpcnJlbGV2YW50X3ZhcgogICAgICogTG9jYWxBbGxvYygweDQwLCBpcnJlbGV2YW50X2xlbikgLT4gcFN0cgogICAgICogc2hsd2FwaS4yOTQoc3RyMSwgc3RyMiwgcFN0ciwgc29tZV9sZW4sIGxwU3RyMik7CiAgICAgKiBzaGx3YXBpLlBhdGhSZW1vdmVCbGFua3NXKHBTdHIpOwogICAgICovCiAgICBGSVhNRSgiKCclcycsICclcycsICclcycsICUwOGx4LCAnJXMnKTogc3R1YiFcbiIsIHN0cjEsIHN0cjIsIHBTdHIsIHNvbWVfbGVuLCBscFN0cjIpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOTVdCiAqCiAqIENhbGxlZCBieSBJQ1EyMDAwYiBpbnN0YWxsIHZpYSBTSERPQ1ZXOgogKiBzdHIxOiAiSW50ZXJuZXRTaG9ydGN1dCIKICogeDogc29tZSB1bmtub3duIHBvaW50ZXIKICogc3RyMjogImh0dHA6Ly9mcmVlLmFvbC5jb20vdHJ5YW9sZnJlZS9pbmRleC5hZHA/MTM5MjY5IgogKiBzdHIzOiAiQzpcXFdJTkRPV1NcXERlc2t0b3AubmV3MlxcRnJlZSBBT0wgJiBVbmxpbWl0ZWQgSW50ZXJuZXQudXJsIgogKgogKiBJbiBzaG9ydDogdGhpcyBvbmUgbWF5YmUgY3JlYXRlcyBhIGRlc2t0b3AgbGluayA6LSkKICovCkJPT0wgV0lOQVBJIFNIU2V0SW5pU3RyaW5nVyhMUFdTVFIgc3RyMSwgTFBWT0lEIHgsIExQV1NUUiBzdHIyLCBMUFdTVFIgc3RyMykKewogICAgRklYTUUoIignJXMnLCAlcCwgJyVzJywgJyVzJyksIHN0dWIuXG4iLCBkZWJ1Z3N0cl93KHN0cjEpLCB4LCBkZWJ1Z3N0cl93KHN0cjIpLCBkZWJ1Z3N0cl93KHN0cjMpKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjk5XQogKgogKiBTZWUgQ09NQ1RMMzJfNDE3LgogKi8KQk9PTCBXSU5BUEkgRXh0VGV4dE91dFdyYXBXKEhEQyBoZGMsIElOVCB4LCBJTlQgeSwgVUlOVCBmbGFncywgY29uc3QgUkVDVCAqbHByZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiBzdHIsIFVJTlQgY291bnQsIGNvbnN0IElOVCAqbHBEeCkKewogICAgR0VUX0ZVTkMocENPTUNUTDMyXzQxNywgY29tY3RsMzIsIChMUENTVFIpNDE3LCBGQUxTRSk7CiAgICByZXR1cm4gcENPTUNUTDMyXzQxNyhoZGMsIHgsIHksIGZsYWdzLCBscHJlY3QsIHN0ciwgY291bnQsIGxwRHgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzEzXQogKgogKiBTZWUgU0hHZXRGaWxlSW5mb1cuCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRGaWxlSW5mb1dyYXBXKExQQ1dTVFIgcGF0aCwgRFdPUkQgZHdGaWxlQXR0cmlidXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgIFNIRklMRUlORk9XICpwc2ZpLCBVSU5UIHNpemVvZnBzZmksIFVJTlQgZmxhZ3MpCnsKICBHRVRfRlVOQyhwU0hHZXRGaWxlSW5mb1csIHNoZWxsMzIsICJTSEdldEZpbGVJbmZvVyIsIDApOwogIHJldHVybiBwU0hHZXRGaWxlSW5mb1cocGF0aCwgZHdGaWxlQXR0cmlidXRlcywgcHNmaSwgc2l6ZW9mcHNmaSwgZmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzE4XQogKgogKiBTZWUgRHJhZ1F1ZXJ5RmlsZVcuCiAqLwpVSU5UIFdJTkFQSSBEcmFnUXVlcnlGaWxlV3JhcFcoSERST1AgaERyb3AsIFVJTlQgbEZpbGUsIExQV1NUUiBscHN6RmlsZSwgVUlOVCBsTGVuZ3RoKQp7CiAgR0VUX0ZVTkMocERyYWdRdWVyeUZpbGVXLCBzaGVsbDMyLCAiRHJhZ1F1ZXJ5RmlsZVciLCAwKTsKICByZXR1cm4gcERyYWdRdWVyeUZpbGVXKGhEcm9wLCBsRmlsZSwgbHBzekZpbGUsIGxMZW5ndGgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzMzXQogKgogKiBTZWUgU0hCcm93c2VGb3JGb2xkZXJXLgogKi8KTFBJVEVNSURMSVNUIFdJTkFQSSBTSEJyb3dzZUZvckZvbGRlcldyYXBXKExQQlJPV1NFSU5GT1cgbHBCaSkKewogIEdFVF9GVU5DKHBTSEJyb3dzZUZvckZvbGRlclcsIHNoZWxsMzIsICJTSEJyb3dzZUZvckZvbGRlclciLCBOVUxMKTsKICByZXR1cm4gcFNIQnJvd3NlRm9yRm9sZGVyVyhscEJpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzNF0KICoKICogU2VlIFNIR2V0UGF0aEZyb21JRExpc3RXLgogKi8KQk9PTCBXSU5BUEkgU0hHZXRQYXRoRnJvbUlETGlzdFdyYXBXKExQQ0lURU1JRExJU1QgcGlkbCxMUFdTVFIgcHN6UGF0aCkKewogIEdFVF9GVU5DKHBTSEdldFBhdGhGcm9tSURMaXN0Vywgc2hlbGwzMiwgIlNIR2V0UGF0aEZyb21JRExpc3RXIiwgMCk7CiAgcmV0dXJuIHBTSEdldFBhdGhGcm9tSURMaXN0VyhwaWRsLCBwc3pQYXRoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzNV0KICoKICogU2VlIFNoZWxsRXhlY3V0ZUV4Vy4KICovCkJPT0wgV0lOQVBJIFNoZWxsRXhlY3V0ZUV4V3JhcFcoTFBTSEVMTEVYRUNVVEVJTkZPVyBscEV4ZWNJbmZvKQp7CiAgR0VUX0ZVTkMocFNoZWxsRXhlY3V0ZUV4Vywgc2hlbGwzMiwgIlNoZWxsRXhlY3V0ZUV4VyIsIEZBTFNFKTsKICByZXR1cm4gcFNoZWxsRXhlY3V0ZUV4VyhscEV4ZWNJbmZvKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzNl0KICoKICogU2VlIFNIRmlsZU9wZXJhdGlvblcuCiAqLwpISUNPTiBXSU5BUEkgU0hGaWxlT3BlcmF0aW9uV3JhcFcoTFBTSEZJTEVPUFNUUlVDVFcgbHBGaWxlT3ApCnsKICBHRVRfRlVOQyhwU0hGaWxlT3BlcmF0aW9uVywgc2hlbGwzMiwgIlNIRmlsZU9wZXJhdGlvblciLCAwKTsKICByZXR1cm4gcFNIRmlsZU9wZXJhdGlvblcobHBGaWxlT3ApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM3XQogKgogKiBTZWUgRXh0cmFjdEljb25FeFcuCiAqLwpVSU5UIFdJTkFQSSBFeHRyYWN0SWNvbkV4V3JhcFcoTFBDV1NUUiBscHN6RmlsZSwgSU5UIG5JY29uSW5kZXgsIEhJQ09OICpwaGljb25MYXJnZSwKICAgICAgICAgICAgICAgICAgICAgICAgIEhJQ09OICpwaGljb25TbWFsbCwgVUlOVCBuSWNvbnMpCnsKICBHRVRfRlVOQyhwRXh0cmFjdEljb25FeFcsIHNoZWxsMzIsICJFeHRyYWN0SWNvbkV4VyIsIDApOwogIHJldHVybiBwRXh0cmFjdEljb25FeFcobHBzekZpbGUsIG5JY29uSW5kZXgsIHBoaWNvbkxhcmdlLCBwaGljb25TbWFsbCwgbkljb25zKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM0Ml0KICoKICovCkxPTkcgV0lOQVBJIFNISW50ZXJsb2NrZWRDb21wYXJlRXhjaGFuZ2UoIFBMT05HIGRlc3QsIExPTkcgeGNoZywgTE9ORyBjb21wYXJlKQp7CiAgICAgICAgcmV0dXJuIEludGVybG9ja2VkQ29tcGFyZUV4Y2hhbmdlKGRlc3QsIHhjaGcsIGNvbXBhcmUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzUwXQogKgogKiBTZWUgR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVcuCiAqLwpEV09SRCBXSU5BUEkgR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVdyYXBXKAoJTFBXU1RSIHgsCglMUFZPSUQgeSkKewogICAgICAgIERXT1JEIHJldDsKCglHRVRfRlVOQyhwR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVcsIHZlcnNpb24sICJHZXRGaWxlVmVyc2lvbkluZm9TaXplVyIsIDApOwoJcmV0ID0gcEdldEZpbGVWZXJzaW9uSW5mb1NpemVXKHgsIHkpOwoJcmV0dXJuIDB4MjA4ICsgcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzUxXQogKgogKiBTZWUgR2V0RmlsZVZlcnNpb25JbmZvVy4KICovCkJPT0wgIFdJTkFQSSBHZXRGaWxlVmVyc2lvbkluZm9XcmFwVygKCUxQV1NUUiB3LCAgIC8qIFtpbl0gcGF0aCB0byBkbGwgKi8KCURXT1JEICB4LCAgIC8qIFtpbl0gcGFybSAyIHRvIEdldEZpbGVWZXJzaW9uSW5mb0EgKi8KCURXT1JEICB5LCAgIC8qIFtpbl0gcmV0dXJuIHZhbHVlIGZyb20gU0hMV0FQSV8zNTAoKSAtIGFzc3VtZSBsZW5ndGggKi8KCUxQVk9JRCB6KSAgIC8qIFtpbi9vdXRdIGJ1ZmZlciAoKzB4MjA4IHNlbnQgdG8gR2V0RmlsZVZlcnNpb25JbmZvQSgpKSAqLwp7CiAgICBHRVRfRlVOQyhwR2V0RmlsZVZlcnNpb25JbmZvVywgdmVyc2lvbiwgIkdldEZpbGVWZXJzaW9uSW5mb1ciLCAwKTsKICAgIHJldHVybiBwR2V0RmlsZVZlcnNpb25JbmZvVyh3LCB4LCB5LTB4MjA4LCAoY2hhciopeisweDIwOCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTJdCiAqCiAqIFNlZSBWZXJRdWVyeVZhbHVlVy4KICovCldPUkQgV0lOQVBJIFZlclF1ZXJ5VmFsdWVXcmFwVygKCUxQVk9JRCB3LCAgIC8qIFtpbl0gQnVmZmVyIGZyb20gU0hMV0FQSV8zNTEoKSAqLwoJTFBXU1RSIHgsICAgLyogW2luXSAgIFZhbHVlIHRvIHJldHJpZXZlIC0gY29udmVydGVkIGFuZCBwYXNzZWQgdG8gVmVyUXVlcnlWYWx1ZUEoKSBhcyAjMiAqLwoJTFBWT0lEIHksICAgLyogW291dF0gIFZlciBidWZmZXIgLSBwYXNzZWQgdG8gVmVyUXVlcnlWYWx1ZUEgYXMgIzMgKi8KCVVJTlQqICB6KSAgIC8qIFtpbl0gICBWZXIgbGVuZ3RoIC0gcGFzc2VkIHRvIFZlclF1ZXJ5VmFsdWVBIGFzICM0ICovCnsKICAgIEdFVF9GVU5DKHBWZXJRdWVyeVZhbHVlVywgdmVyc2lvbiwgIlZlclF1ZXJ5VmFsdWVXIiwgMCk7CiAgICByZXR1cm4gcFZlclF1ZXJ5VmFsdWVXKChjaGFyKil3KzB4MjA4LCB4LCB5LCB6KTsKfQoKI2RlZmluZSBJc0lmYWNlKHR5cGUpIFNVQ0NFRURFRCgoaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF8jI3R5cGUsICh2b2lkKiopJmxwT2JqKSkpCiNkZWZpbmUgSVNoZWxsQnJvd3Nlcl9FbmFibGVNb2RlbGVzcyBJU2hlbGxCcm93c2VyX0VuYWJsZU1vZGVsZXNzU0IKI2RlZmluZSBFbmFibGVNb2RlbGVzcyh0eXBlKSB0eXBlIyNfRW5hYmxlTW9kZWxlc3MoKHR5cGUqKWxwT2JqLCBiTW9kZWxlc3MpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzU1XQogKgogKiBDaGFuZ2UgdGhlIG1vZGFsaXR5IG9mIGEgc2hlbGwgb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIG1ha2UgbW9kZWxlc3MKICogIGJNb2RlbGVzcyBbSV0gVFJVRT1NYWtlIG1vZGVsZXNzLCBGQUxTRT1NYWtlIG1vZGFsCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIFRoZSBtb2RhbGl0eSBscFVua25vd24gaXMgY2hhbmdlZC4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSBpbmRpY2F0aW5nIHRoZSBlcnJvci4KICoKICogTk9URVMKICogIGxwVW5rbm93biBtdXN0IHN1cHBvcnQgdGhlIElPbGVJblBsYWNlRnJhbWUgaW50ZXJmYWNlLCB0aGUKICogIElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSBpbnRlcmZhY2UsIHRoZSBJU2hlbGxCcm93c2VyIGludGVyZmFjZQogKiAgdGhlIElEb2NIb3N0VUlIYW5kbGVyIGludGVyZmFjZSwgb3IgdGhlIElPbGVJblBsYWNlQWN0aXZlT2JqZWN0IGludGVyZmFjZSwKICogIG9yIHRoaXMgY2FsbCB3aWxsIGZhaWwuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9FbmFibGVNb2RlbGVzcyhJVW5rbm93biAqbHBVbmtub3duLCBCT09MIGJNb2RlbGVzcykKewogIElVbmtub3duICpscE9iajsKICBIUkVTVUxUIGhSZXQ7CgogIFRSQUNFKCIoJXAsJWQpXG4iLCBscFVua25vd24sIGJNb2RlbGVzcyk7CgogIGlmICghbHBVbmtub3duKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgaWYgKElzSWZhY2UoSU9sZUluUGxhY2VBY3RpdmVPYmplY3QpKQogICAgRW5hYmxlTW9kZWxlc3MoSU9sZUluUGxhY2VBY3RpdmVPYmplY3QpOwogIGVsc2UgaWYgKElzSWZhY2UoSU9sZUluUGxhY2VGcmFtZSkpCiAgICBFbmFibGVNb2RlbGVzcyhJT2xlSW5QbGFjZUZyYW1lKTsKICBlbHNlIGlmIChJc0lmYWNlKElTaGVsbEJyb3dzZXIpKQogICAgRW5hYmxlTW9kZWxlc3MoSVNoZWxsQnJvd3Nlcik7CiNpZiAwCiAgLyogRklYTUU6IFdpbmUgaGFzIG5vIGhlYWRlcnMgZm9yIHRoZXNlIG9iamVjdHMgeWV0ICovCiAgZWxzZSBpZiAoSXNJZmFjZShJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUpKQogICAgRW5hYmxlTW9kZWxlc3MoSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlKTsKICBlbHNlIGlmIChJc0lmYWNlKElEb2NIb3N0VUlIYW5kbGVyKSkKICAgIEVuYWJsZU1vZGVsZXNzKElEb2NIb3N0VUlIYW5kbGVyKTsKI2VuZGlmCiAgZWxzZQogICAgcmV0dXJuIGhSZXQ7CgogIElVbmtub3duX1JlbGVhc2UobHBPYmopOwogIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzU3XQogKgogKiBTZWUgU0hHZXROZXdMaW5rSW5mb1cuCiAqLwpCT09MIFdJTkFQSSBTSEdldE5ld0xpbmtJbmZvV3JhcFcoTFBDV1NUUiBwc3pMaW5rVG8sIExQQ1dTVFIgcHN6RGlyLCBMUFdTVFIgcHN6TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCAqcGZNdXN0Q29weSwgVUlOVCB1RmxhZ3MpCnsKICBHRVRfRlVOQyhwU0hHZXROZXdMaW5rSW5mb1csIHNoZWxsMzIsICJTSEdldE5ld0xpbmtJbmZvVyIsIEZBTFNFKTsKICByZXR1cm4gcFNIR2V0TmV3TGlua0luZm9XKHBzekxpbmtUbywgcHN6RGlyLCBwc3pOYW1lLCBwZk11c3RDb3B5LCB1RmxhZ3MpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzU4XQogKgogKiBTZWUgU0hEZWZFeHRyYWN0SWNvblcuCiAqLwpVSU5UIFdJTkFQSSBTSERlZkV4dHJhY3RJY29uV3JhcFcoTFBDV1NUUiBwc3pJY29uRmlsZSwgaW50IGlJbmRleCwgVUlOVCB1RmxhZ3MsIEhJQ09OKiBwaGljb25MYXJnZSwKICAgICAgICAgICAgICAgICAgICAgICAgIEhJQ09OKiBwaGljb25TbWFsbCwgVUlOVCBuSWNvblNpemUpCnsKICBHRVRfRlVOQyhwU0hEZWZFeHRyYWN0SWNvblcsIHNoZWxsMzIsICJTSERlZkV4dHJhY3RJY29uVyIsIDApOwogIHJldHVybiBwU0hEZWZFeHRyYWN0SWNvblcocHN6SWNvbkZpbGUsIGlJbmRleCwgdUZsYWdzLCBwaGljb25MYXJnZSwgcGhpY29uU21hbGwsIG5JY29uU2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNjNdCiAqCiAqIEdldCBhbmQgc2hvdyBhIGNvbnRleHQgbWVudSBmcm9tIGEgc2hlbGwgZm9sZGVyLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgICAgIFtJXSBXaW5kb3cgZGlzcGxheWluZyB0aGUgc2hlbGwgZm9sZGVyCiAqICBscEZvbGRlciAgICAgICBbSV0gSVNoZWxsRm9sZGVyIGludGVyZmFjZQogKiAgbHBBcGlkbCAgICAgICAgW0ldIElkIGZvciB0aGUgcGFydGljdWxhciBmb2xkZXIgZGVzaXJlZAogKiAgYkludm9rZURlZmF1bHQgW0ldIFdoZXRoZXIgdG8gaW52b2tlIHRoZSBkZWZhdWx0IG1lbnUgaXRlbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBJZiBiSW52b2tlRGVmYXVsdCBpcyBUUlVFLCB0aGUgZGVmYXVsdCBtZW51IGFjdGlvbiB3YXMKICogICAgICAgICAgIGV4ZWN1dGVkLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlIGluZGljYXRpbmcgdGhlIGVycm9yLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hJbnZva2VDb21tYW5kKEhXTkQgaFduZCwgSVNoZWxsRm9sZGVyKiBscEZvbGRlciwgTFBDSVRFTUlETElTVCBscEFwaWRsLCBCT09MIGJJbnZva2VEZWZhdWx0KQp7CiAgSUNvbnRleHRNZW51ICppQ29udGV4dDsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXAsJXAsJWQpXG4iLCBoV25kLCBscEZvbGRlciwgbHBBcGlkbCwgYkludm9rZURlZmF1bHQpOwoKICBpZiAoIWxwRm9sZGVyKQogICAgcmV0dXJuIGhSZXQ7CgogIC8qIEdldCB0aGUgY29udGV4dCBtZW51IGZyb20gdGhlIHNoZWxsIGZvbGRlciAqLwogIGhSZXQgPSBJU2hlbGxGb2xkZXJfR2V0VUlPYmplY3RPZihscEZvbGRlciwgaFduZCwgMSwgJmxwQXBpZGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZJSURfSUNvbnRleHRNZW51LCAwLCAodm9pZCoqKSZpQ29udGV4dCk7CiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICBITUVOVSBoTWVudTsKICAgIGlmICgoaE1lbnUgPSBDcmVhdGVQb3B1cE1lbnUoKSkpCiAgICB7CiAgICAgIEhSRVNVTFQgaFF1ZXJ5OwogICAgICBEV09SRCBkd0RlZmF1bHRJZCA9IDA7CgogICAgICAvKiBBZGQgdGhlIGNvbnRleHQgbWVudSBlbnRyaWVzIHRvIHRoZSBwb3B1cCAqLwogICAgICBoUXVlcnkgPSBJQ29udGV4dE1lbnVfUXVlcnlDb250ZXh0TWVudShpQ29udGV4dCwgaE1lbnUsIDAsIDEsIDB4N0ZGRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYkludm9rZURlZmF1bHQgPyBDTUZfTk9STUFMIDogQ01GX0RFRkFVTFRPTkxZKTsKCiAgICAgIGlmIChTVUNDRUVERUQoaFF1ZXJ5KSkKICAgICAgewogICAgICAgIGlmIChiSW52b2tlRGVmYXVsdCAmJgogICAgICAgICAgICAoZHdEZWZhdWx0SWQgPSBHZXRNZW51RGVmYXVsdEl0ZW0oaE1lbnUsIDAsIDApKSAhPSAweEZGRkZGRkZGKQogICAgICAgIHsKICAgICAgICAgIENNSU5WT0tFQ09NTUFORElORk8gY21JY2k7CiAgICAgICAgICAvKiBJbnZva2UgdGhlIGRlZmF1bHQgaXRlbSAqLwogICAgICAgICAgbWVtc2V0KCZjbUljaSwwLHNpemVvZihjbUljaSkpOwogICAgICAgICAgY21JY2kuY2JTaXplID0gc2l6ZW9mKGNtSWNpKTsKICAgICAgICAgIGNtSWNpLmZNYXNrID0gQ01JQ19NQVNLX0FTWU5DT0s7CiAgICAgICAgICBjbUljaS5od25kID0gaFduZDsKICAgICAgICAgIGNtSWNpLmxwVmVyYiA9IE1BS0VJTlRSRVNPVVJDRUEoZHdEZWZhdWx0SWQpOwogICAgICAgICAgY21JY2kublNob3cgPSBTV19TQ1JPTExDSElMRFJFTjsKCiAgICAgICAgICBoUmV0ID0gSUNvbnRleHRNZW51X0ludm9rZUNvbW1hbmQoaUNvbnRleHQsICZjbUljaSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIERlc3Ryb3lNZW51KGhNZW51KTsKICAgIH0KICAgIElDb250ZXh0TWVudV9SZWxlYXNlKGlDb250ZXh0KTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNzBdCiAqCiAqIFNlZSBFeHRyYWN0SWNvblcuCiAqLwpISUNPTiBXSU5BUEkgRXh0cmFjdEljb25XcmFwVyhISU5TVEFOQ0UgaEluc3RhbmNlLCBMUENXU1RSIGxwc3pFeGVGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgbkljb25JbmRleCkKewogIEdFVF9GVU5DKHBFeHRyYWN0SWNvblcsIHNoZWxsMzIsICJFeHRyYWN0SWNvblciLCBOVUxMKTsKICByZXR1cm4gcEV4dHJhY3RJY29uVyhoSW5zdGFuY2UsIGxwc3pFeGVGaWxlTmFtZSwgbkljb25JbmRleCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNzZdCiAqLwpMQU5HSUQgV0lOQVBJIE1MR2V0VUlMYW5ndWFnZSgpCnsKICAgIEZJWE1FKCIoKSBzdHViXG4iKTsKICAgIC8qIEZJWE1FOiBUaGlzIHNob3VsZCBiZSBhIGZvcndhcmQgaW4gdGhlIC5zcGVjIGZpbGUgdG8gdGhlIHdpbjJrIGZ1bmN0aW9uCiAgICAgKiBrZXJuZWwzMi5HZXRVc2VyRGVmYXVsdFVJTGFuZ3VhZ2UsIGhvd2V2ZXIgdGhhdCBmdW5jdGlvbiBpc24ndCB0aGVyZSB5ZXQuCiAgICAgKi8KICAgIHJldHVybiBHZXRVc2VyRGVmYXVsdExhbmdJRCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzc3XQogKgogKiBMb2FkIGEgbGlicmFyeSBmcm9tIHRoZSBkaXJlY3Rvcnkgb2YgYSBwYXJ0aWN1bGFyIHByb2Nlc3MuCiAqCiAqIFBBUkFNUwogKiAgbmV3X21vZCAgIFtJXSBMaWJyYXJ5IG5hbWUKICogIGluc3RfaHduZCBbSV0gTW9kdWxlIHdob3NlIGRpcmVjdG9yeSBpcyB0byBiZSB1c2VkCiAqICBkd0ZsYWdzICAgW0ldIEZsYWdzIGNvbnRyb2xsaW5nIHRoZSBsb2FkCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgbW9kdWxlCiAqICBGYWlsdXJlOiBBIE5VTEwgaGFuZGxlLgogKi8KSE1PRFVMRSBXSU5BUEkgTUxMb2FkTGlicmFyeUEoTFBDU1RSIG5ld19tb2QsIEhNT0RVTEUgaW5zdF9od25kLCBEV09SRCBkd0ZsYWdzKQp7CiAgLyogRklYTUU6IE5hdGl2ZSBhcHBlYXJzIHRvIGRvIERQQV9DcmVhdGUgYW5kIGEgRFBBX0luc2VydFB0ciBmb3IKICAgKiAgICAgICAgZWFjaCBjYWxsIGhlcmUuCiAgICogRklYTUU6IE5hdGl2ZSBzaG93cyBjYWxscyB0bzoKICAgKiAgU0hSZWdHZXRVU1ZhbHVlIGZvciAiU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVybmF0aW9uYWwiCiAgICogICAgICAgICAgICAgICAgICAgICAgQ2hlY2tWZXJzaW9uCiAgICogIFJlZ09wZW5LZXlFeEEgZm9yICJIS0xNXFNvZnR3YXJlXE1pY3Jvc29mdFxJbnRlcm5ldCBFeHBsb3JlciIKICAgKiAgUmVnUXVlcnlWYWx1ZUV4QSBmb3IgIkxQS0luc3RhbGxlZCIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLQ1VcU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVybmF0aW9uYWwiCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJSZXNvdXJjZUxvY2FsZSIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLTE1cU29mdHdhcmVcTWljcm9zb2Z0XEFjdGl2ZSBTZXR1cFxJbnN0YWxsZWQgQ29tcG9uZW50c1x7Z3VpZH0iCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJMb2NhbGUiCiAgICogIFJlZ0Nsb3NlS2V5CiAgICogIGFuZCB0aGVuIHRlc3RzIHRoZSBMb2NhbGUgKCJlbiIgZm9yIG1lKS4KICAgKiAgICAgY29kZSBiZWxvdwogICAqICBhZnRlciB0aGUgY29kZSB0aGVuIGEgRFBBX0NyZWF0ZSAoZmlyc3QgdGltZSkgYW5kIERQQV9JbnNlcnRQdHIgYXJlIGRvbmUuCiAgICovCiAgICBDSEFSIG1vZF9wYXRoWzIqTUFYX1BBVEhdOwogICAgTFBTVFIgcHRyOwogICAgRFdPUkQgbGVuOwoKICAgIEZJWE1FKCIoJXMsJXAsMHglMDhseCkgc2VtaS1zdHViIVxuIiwgZGVidWdzdHJfYShuZXdfbW9kKSwgaW5zdF9od25kLCBkd0ZsYWdzKTsKICAgIGxlbiA9IEdldE1vZHVsZUZpbGVOYW1lQShpbnN0X2h3bmQsIG1vZF9wYXRoLCBzaXplb2YobW9kX3BhdGgpKTsKICAgIGlmICghbGVuIHx8IGxlbiA+PSBzaXplb2YobW9kX3BhdGgpKSByZXR1cm4gTlVMTDsKCiAgICBwdHIgPSBzdHJyY2hyKG1vZF9wYXRoLCAnXFwnKTsKICAgIGlmIChwdHIpIHsKCXN0cmNweShwdHIrMSwgbmV3X21vZCk7CglUUkFDRSgibG9hZGluZyAlc1xuIiwgZGVidWdzdHJfYShtb2RfcGF0aCkpOwoJcmV0dXJuIExvYWRMaWJyYXJ5QShtb2RfcGF0aCk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIE1MTG9hZExpYnJhcnlBLgogKi8KSE1PRFVMRSBXSU5BUEkgTUxMb2FkTGlicmFyeVcoTFBDV1NUUiBuZXdfbW9kLCBITU9EVUxFIGluc3RfaHduZCwgRFdPUkQgZHdGbGFncykKewogICAgV0NIQVIgbW9kX3BhdGhbMipNQVhfUEFUSF07CiAgICBMUFdTVFIgcHRyOwogICAgRFdPUkQgbGVuOwoKICAgIEZJWE1FKCIoJXMsJXAsMHglMDhseCkgc2VtaS1zdHViIVxuIiwgZGVidWdzdHJfdyhuZXdfbW9kKSwgaW5zdF9od25kLCBkd0ZsYWdzKTsKICAgIGxlbiA9IEdldE1vZHVsZUZpbGVOYW1lVyhpbnN0X2h3bmQsIG1vZF9wYXRoLCBzaXplb2YobW9kX3BhdGgpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoIWxlbiB8fCBsZW4gPj0gc2l6ZW9mKG1vZF9wYXRoKSAvIHNpemVvZihXQ0hBUikpIHJldHVybiBOVUxMOwoKICAgIHB0ciA9IHN0cnJjaHJXKG1vZF9wYXRoLCAnXFwnKTsKICAgIGlmIChwdHIpIHsKCXN0cmNweVcocHRyKzEsIG5ld19tb2QpOwoJVFJBQ0UoImxvYWRpbmcgJXNcbiIsIGRlYnVnc3RyX3cobW9kX3BhdGgpKTsKCXJldHVybiBMb2FkTGlicmFyeVcobW9kX3BhdGgpOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENvbG9yQWRqdXN0THVtYSAgICAgIFtTSExXQVBJLkBdCiAqCiAqIEFkanVzdCB0aGUgbHVtaW5vc2l0eSBvZiBhIGNvbG9yCiAqCiAqIFBBUkFNUwogKiAgY1JHQiAgICAgICAgIFtJXSBSR0IgdmFsdWUgdG8gY29udmVydAogKiAgZHdMdW1hICAgICAgIFtJXSBMdW1hIGFkanVzdG1lbnQKICogIGJVbmtub3duICAgICBbSV0gVW5rbm93bgogKgogKiBSRVRVUk5TCiAqICBUaGUgYWRqdXN0ZWQgUkdCIGNvbG9yLgogKi8KQ09MT1JSRUYgV0lOQVBJIENvbG9yQWRqdXN0THVtYShDT0xPUlJFRiBjUkdCLCBpbnQgZHdMdW1hLCBCT09MIGJVbmtub3duKQp7CiAgVFJBQ0UoIigweCU4bHgsJWQsJWQpXG4iLCBjUkdCLCBkd0x1bWEsIGJVbmtub3duKTsKCiAgaWYgKGR3THVtYSkKICB7CiAgICBXT1JEIHdILCB3TCwgd1M7CgogICAgQ29sb3JSR0JUb0hMUyhjUkdCLCAmd0gsICZ3TCwgJndTKTsKCiAgICBGSVhNRSgiSWdub3JpbmcgbHVtYSBhZGp1c3RtZW50XG4iKTsKCiAgICAvKiBGSVhNRTogVGhlIGFqZHVzdG1lbnQgaXMgbm90IGxpbmVhciAqLwoKICAgIGNSR0IgPSBDb2xvckhMU1RvUkdCKHdILCB3TCwgd1MpOwogIH0KICByZXR1cm4gY1JHQjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM4OV0KICoKICogU2VlIEdldFNhdmVGaWxlTmFtZVcuCiAqLwpCT09MIFdJTkFQSSBHZXRTYXZlRmlsZU5hbWVXcmFwVyhMUE9QRU5GSUxFTkFNRVcgb2ZuKQp7CiAgR0VUX0ZVTkMocEdldFNhdmVGaWxlTmFtZVcsIGNvbWRsZzMyLCAiR2V0U2F2ZUZpbGVOYW1lVyIsIEZBTFNFKTsKICByZXR1cm4gcEdldFNhdmVGaWxlTmFtZVcob2ZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM5MF0KICoKICogU2VlIFdOZXRSZXN0b3JlQ29ubmVjdGlvblcuCiAqLwpEV09SRCBXSU5BUEkgV05ldFJlc3RvcmVDb25uZWN0aW9uV3JhcFcoSFdORCBod25kT3duZXIsIExQV1NUUiBscHN6RGV2aWNlKQp7CiAgR0VUX0ZVTkMocFdOZXRSZXN0b3JlQ29ubmVjdGlvblcsIG1wciwgIldOZXRSZXN0b3JlQ29ubmVjdGlvblciLCAwKTsKICByZXR1cm4gcFdOZXRSZXN0b3JlQ29ubmVjdGlvblcoaHduZE93bmVyLCBscHN6RGV2aWNlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM5MV0KICoKICogU2VlIFdOZXRHZXRMYXN0RXJyb3JXLgogKi8KRFdPUkQgV0lOQVBJIFdOZXRHZXRMYXN0RXJyb3JXcmFwVyhMUERXT1JEIGxwRXJyb3IsIExQV1NUUiBscEVycm9yQnVmLCBEV09SRCBuRXJyb3JCdWZTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGxwTmFtZUJ1ZiwgRFdPUkQgbk5hbWVCdWZTaXplKQp7CiAgR0VUX0ZVTkMocFdOZXRHZXRMYXN0RXJyb3JXLCBtcHIsICJXTmV0R2V0TGFzdEVycm9yVyIsIDApOwogIHJldHVybiBwV05ldEdldExhc3RFcnJvclcobHBFcnJvciwgbHBFcnJvckJ1ZiwgbkVycm9yQnVmU2l6ZSwgbHBOYW1lQnVmLCBuTmFtZUJ1ZlNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDAxXQogKgogKiBTZWUgUGFnZVNldHVwRGxnVy4KICovCkJPT0wgV0lOQVBJIFBhZ2VTZXR1cERsZ1dyYXBXKExQUEFHRVNFVFVQRExHVyBwYWdlZGxnKQp7CiAgR0VUX0ZVTkMocFBhZ2VTZXR1cERsZ1csIGNvbWRsZzMyLCAiUGFnZVNldHVwRGxnVyIsIEZBTFNFKTsKICByZXR1cm4gcFBhZ2VTZXR1cERsZ1cocGFnZWRsZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDJdCiAqCiAqIFNlZSBQcmludERsZ1cuCiAqLwpCT09MIFdJTkFQSSBQcmludERsZ1dyYXBXKExQUFJJTlRETEdXIHByaW50ZGxnKQp7CiAgR0VUX0ZVTkMocFByaW50RGxnVywgY29tZGxnMzIsICJQcmludERsZ1ciLCBGQUxTRSk7CiAgcmV0dXJuIHBQcmludERsZ1cocHJpbnRkbGcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDAzXQogKgogKiBTZWUgR2V0T3BlbkZpbGVOYW1lVy4KICovCkJPT0wgV0lOQVBJIEdldE9wZW5GaWxlTmFtZVdyYXBXKExQT1BFTkZJTEVOQU1FVyBvZm4pCnsKICBHRVRfRlVOQyhwR2V0T3BlbkZpbGVOYW1lVywgY29tZGxnMzIsICJHZXRPcGVuRmlsZU5hbWVXIiwgRkFMU0UpOwogIHJldHVybiBwR2V0T3BlbkZpbGVOYW1lVyhvZm4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDA0XQogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fRW51bU9iamVjdHMoTFBTSEVMTEZPTERFUiBscEZvbGRlciwgSFdORCBod25kLCBTSENPTlRGIGZsYWdzLCBJRW51bUlETGlzdCAqKnBwZW51bSkKewogICAgSVBlcnNpc3QgKnBlcnNpc3Q7CiAgICBIUkVTVUxUIGhyOwoKICAgIGhyID0gSVNoZWxsRm9sZGVyX1F1ZXJ5SW50ZXJmYWNlKGxwRm9sZGVyLCAmSUlEX0lQZXJzaXN0LCAoTFBWT0lEKSZwZXJzaXN0KTsKICAgIGlmKFNVQ0NFRURFRChocikpCiAgICB7CiAgICAgICAgQ0xTSUQgY2xzaWQ7CiAgICAgICAgaHIgPSBJUGVyc2lzdF9HZXRDbGFzc0lEKHBlcnNpc3QsICZjbHNpZCk7CiAgICAgICAgaWYoU1VDQ0VFREVEKGhyKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmKElzRXF1YWxDTFNJRCgmY2xzaWQsICZDTFNJRF9TaGVsbEZTRm9sZGVyKSkKICAgICAgICAgICAgICAgIGhyID0gSVNoZWxsRm9sZGVyX0VudW1PYmplY3RzKGxwRm9sZGVyLCBod25kLCBmbGFncywgcHBlbnVtKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgaHIgPSBFX0ZBSUw7CiAgICAgICAgfQogICAgICAgIElQZXJzaXN0X1JlbGVhc2UocGVyc2lzdCk7CiAgICB9CiAgICByZXR1cm4gaHI7Cn0KCi8qIElOVEVSTkFMOiBNYXAgZnJvbSBITFMgY29sb3Igc3BhY2UgdG8gUkdCICovCnN0YXRpYyBXT1JEIFdJTkFQSSBDb252ZXJ0SHVlKGludCB3SHVlLCBXT1JEIHdNaWQxLCBXT1JEIHdNaWQyKQp7CiAgd0h1ZSA9IHdIdWUgPiAyNDAgPyB3SHVlIC0gMjQwIDogd0h1ZSA8IDAgPyB3SHVlICsgMjQwIDogd0h1ZTsKCiAgaWYgKHdIdWUgPiAxNjApCiAgICByZXR1cm4gd01pZDE7CiAgZWxzZSBpZiAod0h1ZSA+IDEyMCkKICAgIHdIdWUgPSAxNjAgLSB3SHVlOwogIGVsc2UgaWYgKHdIdWUgPiA0MCkKICAgIHJldHVybiB3TWlkMjsKCiAgcmV0dXJuICgod0h1ZSAqICh3TWlkMiAtIHdNaWQxKSArIDIwKSAvIDQwKSArIHdNaWQxOwp9CgovKiBDb252ZXJ0IHRvIFJHQiBhbmQgc2NhbGUgaW50byBSR0IgcmFuZ2UgKDAuLjI1NSkgKi8KI2RlZmluZSBHRVRfUkdCKGgpIChDb252ZXJ0SHVlKGgsIHdNaWQxLCB3TWlkMikgKiAyNTUgKyAxMjApIC8gMjQwCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIENvbG9ySExTVG9SR0IJW1NITFdBUEkuQF0KICoKICogQ29udmVydCBmcm9tIGhscyBjb2xvciBzcGFjZSBpbnRvIGFuIHJnYiBDT0xPUlJFRi4KICoKICogUEFSQU1TCiAqICB3SHVlICAgICAgICBbSV0gSHVlIGFtb3VudAogKiAgd0x1bWlub3NpdHkgW0ldIEx1bWlub3NpdHkgYW1vdW50CiAqICB3U2F0dXJhdGlvbiBbSV0gU2F0dXJhdGlvbiBhbW91bnQKICoKICogUkVUVVJOUwogKiAgQSBDT0xPUlJFRiByZXByZXNlbnRpbmcgdGhlIGNvbnZlcnRlZCBjb2xvci4KICoKICogTk9URVMKICogIElucHV0IGhscyB2YWx1ZXMgYXJlIGNvbnN0cmFpbmVkIHRvIHRoZSByYW5nZSAoMC4uMjQwKS4KICovCkNPTE9SUkVGIFdJTkFQSSBDb2xvckhMU1RvUkdCKFdPUkQgd0h1ZSwgV09SRCB3THVtaW5vc2l0eSwgV09SRCB3U2F0dXJhdGlvbikKewogIFdPUkQgd1JlZDsKCiAgaWYgKHdTYXR1cmF0aW9uKQogIHsKICAgIFdPUkQgd0dyZWVuLCB3Qmx1ZSwgd01pZDEsIHdNaWQyOwoKICAgIGlmICh3THVtaW5vc2l0eSA+IDEyMCkKICAgICAgd01pZDIgPSB3U2F0dXJhdGlvbiArIHdMdW1pbm9zaXR5IC0gKHdTYXR1cmF0aW9uICogd0x1bWlub3NpdHkgKyAxMjApIC8gMjQwOwogICAgZWxzZQogICAgICB3TWlkMiA9ICgod1NhdHVyYXRpb24gKyAyNDApICogd0x1bWlub3NpdHkgKyAxMjApIC8gMjQwOwoKICAgIHdNaWQxID0gd0x1bWlub3NpdHkgKiAyIC0gd01pZDI7CgogICAgd1JlZCAgID0gR0VUX1JHQih3SHVlICsgODApOwogICAgd0dyZWVuID0gR0VUX1JHQih3SHVlKTsKICAgIHdCbHVlICA9IEdFVF9SR0Iod0h1ZSAtIDgwKTsKCiAgICByZXR1cm4gUkdCKHdSZWQsIHdHcmVlbiwgd0JsdWUpOwogIH0KCiAgd1JlZCA9IHdMdW1pbm9zaXR5ICogMjU1IC8gMjQwOwogIHJldHVybiBSR0Iod1JlZCwgd1JlZCwgd1JlZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MTNdCiAqCiAqIEdldCB0aGUgY3VycmVudCBkb2NraW5nIHN0YXR1cyBvZiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIGR3RmxhZ3MgW0ldIERPQ0tJTkZPXyBmbGFncyBmcm9tICJ3aW5iYXNlLmgiLCB1bnVzZWQKICoKICogUkVUVVJOUwogKiAgT25lIG9mIERPQ0tJTkZPX1VORE9DS0VELCBET0NLSU5GT19VTkRPQ0tFRCwgb3IgMCBpZiB0aGUgc3lzdGVtIGlzIG5vdAogKiAgYSBub3RlYm9vay4KICovCkRXT1JEIFdJTkFQSSBTSEdldE1hY2hpbmVJbmZvKERXT1JEIGR3RmxhZ3MpCnsKICBIV19QUk9GSUxFX0lORk9BIGh3SW5mbzsKCiAgVFJBQ0UoIigweCUwOGx4KVxuIiwgZHdGbGFncyk7CgogIEdldEN1cnJlbnRId1Byb2ZpbGVBKCZod0luZm8pOwogIHN3aXRjaCAoaHdJbmZvLmR3RG9ja0luZm8gJiAoRE9DS0lORk9fRE9DS0VEfERPQ0tJTkZPX1VORE9DS0VEKSkKICB7CiAgY2FzZSBET0NLSU5GT19ET0NLRUQ6CiAgY2FzZSBET0NLSU5GT19VTkRPQ0tFRDoKICAgIHJldHVybiBod0luZm8uZHdEb2NrSW5mbyAmIChET0NLSU5GT19ET0NLRUR8RE9DS0lORk9fVU5ET0NLRUQpOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gMDsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MThdCiAqCiAqIEZ1bmN0aW9uIHNlZW1zIHRvIGRvIEZyZWVMaWJyYXJ5IHBsdXMgb3RoZXIgdGhpbmdzLgogKgogKiBGSVhNRSBuYXRpdmUgc2hvd3MgdGhlIGZvbGxvd2luZyBjYWxsczoKICogICBSdGxFbnRlckNyaXRpY2FsU2VjdGlvbgogKiAgIExvY2FsRnJlZQogKiAgIEdldFByb2NBZGRyZXNzKENvbWN0bDMyPz8sIDE1MEwpCiAqICAgRFBBX0RlbGV0ZVB0cgogKiAgIFJ0bExlYXZlQ3JpdGljYWxTZWN0aW9uCiAqICBmb2xsb3dlZCBieSB0aGUgRnJlZUxpYnJhcnkuCiAqICBUaGUgYWJvdmUgY29kZSBtYXkgYmUgcmVsYXRlZCB0byAuMzc3IGFib3ZlLgogKi8KQk9PTCBXSU5BUEkgTUxGcmVlTGlicmFyeShITU9EVUxFIGhNb2R1bGUpCnsKCUZJWE1FKCIoJXApIHNlbWktc3R1YlxuIiwgaE1vZHVsZSk7CglyZXR1cm4gRnJlZUxpYnJhcnkoaE1vZHVsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MTldCiAqLwpCT09MIFdJTkFQSSBTSEZsdXNoU0ZDYWNoZVdyYXAodm9pZCkgewogIEZJWE1FKCI6IHN0dWJcbiIpOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDI1XQogKi8KQk9PTCBXSU5BUEkgRGVsZXRlTWVudVdyYXAoSE1FTlUgaG1lbnUsIFVJTlQgcG9zLCBVSU5UIGZsYWdzKQp7CiAgICAvKiBGSVhNRTogVGhpcyBzaG91bGQgZG8gbW9yZSB0aGFuIHNpbXBseSBjYWxsIERlbGV0ZU1lbnUgKi8KICAgIEZJWE1FKCIlcCAlMDh4ICUwOHgpOiBzZW1pLXN0dWJcbiIsIGhtZW51LCBwb3MsIGZsYWdzKTsKICAgIHJldHVybiBEZWxldGVNZW51KGhtZW51LCBwb3MsIGZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgW1NITFdBUEkuNDI5XQogKiBGSVhNRSBJIGhhdmUgbm8gaWRlYSB3aGF0IHRoaXMgZnVuY3Rpb24gZG9lcyBvciB3aGF0IGl0cyBhcmd1bWVudHMgYXJlLgogKi8KQk9PTCBXSU5BUEkgTUxJc01MSEluc3RhbmNlKEhJTlNUQU5DRSBoSW5zdCkKewogICAgICAgRklYTUUoIiglcCkgc3R1YlxuIiwgaEluc3QpOwogICAgICAgcmV0dXJuIEZBTFNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzMF0KICovCkRXT1JEIFdJTkFQSSBNTFNldE1MSEluc3RhbmNlKEhJTlNUQU5DRSBoSW5zdCwgSEFORExFIGhIZWFwKQp7CglGSVhNRSgiKCVwLCVwKSBzdHViXG4iLCBoSW5zdCwgaEhlYXApOwoJcmV0dXJuIEVfRkFJTDsgICAvKiBUaGlzIGlzIHdoYXQgaXMgdXNlZCBpZiBzaGx3YXBpIG5vdCBsb2FkZWQgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzMV0KICovCkRXT1JEIFdJTkFQSSBNTENsZWFyTUxISW5zdGFuY2UoRFdPUkQgeCkKewoJRklYTUUoIigweCUwOGx4KXN0dWJcbiIsIHgpOwoJcmV0dXJuIDB4YWJiYTEyNDc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MzZdCiAqCiAqIENvbnZlcnQgYW4gVW5pY29kZSBzdHJpbmcgQ0xTSUQgaW50byBhIENMU0lELgogKgogKiBQQVJBTVMKICogIGlkc3RyICAgICAgW0ldICAgc3RyaW5nIGNvbnRhaW5pbmcgYSBDTFNJRCBpbiB0ZXh0IGZvcm0KICogIGlkICAgICAgICAgW09dICAgQ0xTSUQgZXh0cmFjdGVkIGZyb20gdGhlIHN0cmluZwogKgogKiBSRVRVUk5TCiAqICBTX09LIG9uIHN1Y2Nlc3Mgb3IgRV9JTlZBTElEQVJHIG9uIGZhaWx1cmUKICoKICogTk9URVMKICogIFRoaXMgaXMgcmVhbGx5IENMU0lERnJvbVN0cmluZygpIHdoaWNoIGlzIGV4cG9ydGVkIGJ5IG9sZTMyLmRsbCwKICogIGhvd2V2ZXIgdGhlIG5hdGl2ZSBzaGx3YXBpLmRsbCBkb2VzICpub3QqIGltcG9ydCBvbGUzMi4gTm9yIGRvZXMKICogIG9sZTMyLmRsbCBpbXBvcnQgdGhpcyBvcmRpbmFsIGZyb20gc2hsd2FwaS4gVGhlcmVmb3JlIHdlIG11c3QgY29uY2x1ZGUKICogIHRoYXQgTVMgZHVwbGljYXRlZCB0aGUgY29kZSBmb3IgQ0xTSURGcm9tU3RyaW5nKCksIGFuZCB5ZXMgdGhleSBkaWQsIG9ubHkKICogIGl0IHJldHVybnMgYW4gRV9JTlZBTElEQVJHIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICogIFRoaXMgaXMgYSBkdXBsaWNhdGUgKHdpdGggY2hhbmdlcyBmb3IgVW5pY29kZSkgb2YgQ0xTSURGcm9tU3RyaW5nMTYoKQogKiAgaW4gImRsbHMvb2xlMzIvY29tcG9iai5jIi4KICovCkhSRVNVTFQgV0lOQVBJIENMU0lERnJvbVN0cmluZ1dyYXAoTFBDV1NUUiBpZHN0ciwgQ0xTSUQgKmlkKQp7CglMUENXU1RSIHMgPSBpZHN0cjsKCUJZVEUgKnA7CglJTlQgaTsKCVdDSEFSIHRhYmxlWzI1Nl07CgoJaWYgKCFzKSB7CgkgIG1lbXNldChpZCwgMCwgc2l6ZW9mKENMU0lEKSk7CgkgIHJldHVybiBTX09LOwoJfQoJZWxzZSB7ICAvKiB2YWxpZGF0ZSB0aGUgQ0xTSUQgc3RyaW5nICovCgoJICBpZiAoc3RybGVuVyhzKSAhPSAzOCkKCSAgICByZXR1cm4gRV9JTlZBTElEQVJHOwoKCSAgaWYgKChzWzBdIT1MJ3snKSB8fCAoc1s5XSE9TCctJykgfHwgKHNbMTRdIT1MJy0nKSB8fCAoc1sxOV0hPUwnLScpIHx8IChzWzI0XSE9TCctJykgfHwgKHNbMzddIT1MJ30nKSkKCSAgICByZXR1cm4gRV9JTlZBTElEQVJHOwoKCSAgZm9yIChpPTE7IGk8Mzc7IGkrKykKCSAgewoJICAgIGlmICgoaSA9PSA5KXx8KGkgPT0gMTQpfHwoaSA9PSAxOSl8fChpID09IDI0KSkKCSAgICAgIGNvbnRpbnVlOwoJICAgIGlmICghKCgoc1tpXSA+PSBMJzAnKSAmJiAoc1tpXSA8PSBMJzknKSkgIHx8CgkgICAgICAgICgoc1tpXSA+PSBMJ2EnKSAmJiAoc1tpXSA8PSBMJ2YnKSkgIHx8CgkgICAgICAgICgoc1tpXSA+PSBMJ0EnKSAmJiAoc1tpXSA8PSBMJ0YnKSkpCgkgICAgICAgKQoJICAgICAgcmV0dXJuIEVfSU5WQUxJREFSRzsKCSAgfQoJfQoKICAgIFRSQUNFKCIlcyAtPiAlcFxuIiwgZGVidWdzdHJfdyhzKSwgaWQpOwoKICAvKiBxdWljayBsb29rdXAgdGFibGUgKi8KICAgIG1lbXNldCh0YWJsZSwgMCwgMjU2KnNpemVvZihXQ0hBUikpOwoKICAgIGZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB7Cgl0YWJsZVsnMCcgKyBpXSA9IGk7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7Cgl0YWJsZVsnQScgKyBpXSA9IGkrMTA7Cgl0YWJsZVsnYScgKyBpXSA9IGkrMTA7CiAgICB9CgogICAgLyogaW4gZm9ybSB7WFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYfSAqLwoKICAgIHAgPSAoQllURSAqKSBpZDsKCiAgICBzKys7CS8qIHNraXAgbGVhZGluZyBicmFjZSAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHsKCXBbMyAtIGldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gNDsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gMjsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gMjsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgLyogdGhlc2UgYXJlIGp1c3Qgc2VxdWVudGlhbCBieXRlcyAqLwogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJKnArKyA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CglzICs9IDI7CiAgICB9CiAgICBzKys7CS8qIHNraXAgLSAqLwoKICAgIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKCSpwKysgPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwoJcyArPSAyOwogICAgfQoKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDM3XQogKgogKiBEZXRlcm1pbmUgaWYgdGhlIE9TIHN1cHBvcnRzIGEgZ2l2ZW4gZmVhdHVyZS4KICoKICogUEFSQU1TCiAqICBkd0ZlYXR1cmUgW0ldIEZlYXR1cmUgcmVxdWVzdGVkICh1bmRvY3VtZW50ZWQpCiAqCiAqIFJFVFVSTlMKICogIFRSVUUgIElmIHRoZSBmZWF0dXJlIGlzIGF2YWlsYWJsZS4KICogIEZBTFNFIElmIHRoZSBmZWF0dXJlIGlzIG5vdCBhdmFpbGFibGUuCiAqLwpCT09MIFdJTkFQSSBJc09TKERXT1JEIGZlYXR1cmUpCnsKICAgIE9TVkVSU0lPTklORk9BIG9zdmk7CiAgICBEV09SRCBwbGF0Zm9ybSwgbWFqb3J2LCBtaW5vcnY7CgogICAgb3N2aS5kd09TVmVyc2lvbkluZm9TaXplID0gc2l6ZW9mKE9TVkVSU0lPTklORk9BKTsKICAgIGlmKCFHZXRWZXJzaW9uRXhBKCZvc3ZpKSkgIHsKICAgICAgICBFUlIoIkdldFZlcnNpb25FeCBmYWlsZWQiKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbWFqb3J2ID0gb3N2aS5kd01ham9yVmVyc2lvbjsKICAgIG1pbm9ydiA9IG9zdmkuZHdNaW5vclZlcnNpb247CiAgICBwbGF0Zm9ybSA9IG9zdmkuZHdQbGF0Zm9ybUlkOwoKI2RlZmluZSBJU09TX1JFVFVSTih4KSBcCiAgICBUUkFDRSgiKDB4JWx4KSByZXQ9JWRcbiIsZmVhdHVyZSwoeCkpOyBcCiAgICByZXR1cm4gKHgpOwoKICAgIHN3aXRjaChmZWF0dXJlKSAgewogICAgY2FzZSBPU19XSU4zMlNPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMycwogICAgICAgICAgICAgICAgIHx8IHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTKQogICAgY2FzZSBPU19OVDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1dJTjk1T1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTKQogICAgY2FzZSBPU19OVDRPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA0KQogICAgY2FzZSBPU19XSU4yMDAwT1JHUkVBVEVSX0FMVDoKICAgIGNhc2UgT1NfV0lOMjAwME9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUpCiAgICBjYXNlIE9TX1dJTjk4T1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTICYmIG1pbm9ydiA+PSAxMCkKICAgIGNhc2UgT1NfV0lOOThfR09MRDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPT0gMTApCiAgICBjYXNlIE9TX1dJTjIwMDBQUk86CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA1KQogICAgY2FzZSBPU19XSU4yMDAwU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwQURWU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwREFUQUNFTlRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgKG1pbm9ydiA9PSAwIHx8IG1pbm9ydiA9PSAxKSkKICAgIGNhc2UgT1NfV0lOMjAwMFRFUk1JTkFMOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19FTUJFRERFRDoKICAgICAgICBGSVhNRSgiKE9TX0VNQkVEREVEKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfVEVSTUlOQUxDTElFTlQ6CiAgICAgICAgRklYTUUoIihPU19URVJNSU5BTENMSUVOVCkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX1RFUk1JTkFMUkVNT1RFQURNSU46CiAgICAgICAgRklYTUUoIihPU19URVJNSU5BTFJFTU9URUFETUlOKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfV0lOOTVfR09MRDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPT0gMCkKICAgIGNhc2UgT1NfTUVPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MgJiYgbWlub3J2ID49IDkwKQogICAgY2FzZSBPU19YUE9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUgJiYgbWlub3J2ID49IDEpCiAgICBjYXNlIE9TX0hPTUU6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA1ICYmIG1pbm9ydiA+PSAxKQogICAgY2FzZSBPU19QUk9GRVNTSU9OQUw6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19EQVRBQ0VOVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfQURWU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfVEVSTUlOQUxTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19QRVJTT05BTFRFUk1JTkFMU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtaW5vcnYgPj0gMSAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfRkFTVFVTRVJTV0lUQ0hJTkc6CiAgICAgICAgRklYTUUoIihPU19GQVNUVVNFUlNXSVRDSElORykgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGNhc2UgT1NfV0VMQ09NRUxPR09OVUk6CiAgICAgICAgRklYTUUoIihPU19XRUxDT01FTE9HT05VSSkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX0RPTUFJTk1FTUJFUjoKICAgICAgICBGSVhNRSgiKE9TX0RPTUFJTk1FTUJFUikgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGNhc2UgT1NfQU5ZU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfV09XNjQzMjoKICAgICAgICBGSVhNRSgiKE9TX1dPVzY0MzIpIFNob3VsZCB3ZSBjaGVjayB0aGlzP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19XRUJTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19TTUFMTEJVU0lORVNTU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfVEFCTEVUUEM6CiAgICAgICAgRklYTUUoIihPU19UQUJMRVBDKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfU0VSVkVSQURNSU5VSToKICAgICAgICBGSVhNRSgiKE9TX1NFUlZFUkFETUlOVUkpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19NRURJQUNFTlRFUjoKICAgICAgICBGSVhNRSgiKE9TX01FRElBQ0VOVEVSKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfQVBQTElBTkNFOgogICAgICAgIEZJWE1FKCIoT1NfQVBQTElBTkNFKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiN1bmRlZiBJU09TX1JFVFVSTgoKICAgIFdBUk4oIigweCVseCkgdW5rbm93biBwYXJhbWV0ZXJcbiIsZmVhdHVyZSk7CgogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS40MzldCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExvYWRSZWdVSVN0cmluZ1coSEtFWSBoa2V5LCBMUENXU1RSIHZhbHVlLCBMUFdTVFIgYnVmLCBEV09SRCBzaXplKQp7CiAgICBEV09SRCB0eXBlLCBzeiA9IHNpemU7CgogICAgaWYoUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCB2YWx1ZSwgTlVMTCwgJnR5cGUsIChMUEJZVEUpYnVmLCAmc3opICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIEVfRkFJTDsKCiAgICByZXR1cm4gU0hMb2FkSW5kaXJlY3RTdHJpbmcoYnVmLCBidWYsIHNpemUsIE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS40NzhdCiAqCiAqIENhbGwgSUlucHV0T2JqZWN0X1RyYW5zbGF0ZUFjY2VsZXJhdG9ySU8oKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSUlucHV0T2JqZWN0IGludGVyZmFjZS4KICogIGxwTXNnICAgICBbSV0gS2V5IG1lc3NhZ2UgdG8gYmUgcHJvY2Vzc2VkLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0lOVkFMSURBUkcgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9UcmFuc2xhdGVBY2NlbGVyYXRvcklPKElVbmtub3duICpscFVua25vd24sIExQTVNHIGxwTXNnKQp7CiAgSUlucHV0T2JqZWN0KiBscElucHV0ID0gTlVMTDsKICBIUkVTVUxUIGhSZXQgPSBFX0lOVkFMSURBUkc7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwTXNnKTsKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUlucHV0T2JqZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwSW5wdXQpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscElucHV0KQogICAgewogICAgICBoUmV0ID0gSUlucHV0T2JqZWN0X1RyYW5zbGF0ZUFjY2VsZXJhdG9ySU8obHBJbnB1dCwgbHBNc2cpOwogICAgICBJSW5wdXRPYmplY3RfUmVsZWFzZShscElucHV0KTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjQ4MV0KICoKICogQ2FsbCBJSW5wdXRPYmplY3RfSGFzRm9jdXNJTygpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJSW5wdXRPYmplY3QgaW50ZXJmYWNlLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLCBpZiBscFVua25vd24gaXMgYW4gSUlucHV0T2JqZWN0IG9iamVjdCBhbmQgaGFzIHRoZSBmb2N1cywKICogICAgICAgICAgIG9yIFNfRkFMU0Ugb3RoZXJ3aXNlLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0lOVkFMSURBUkcgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9IYXNGb2N1c0lPKElVbmtub3duICpscFVua25vd24pCnsKICBJSW5wdXRPYmplY3QqIGxwSW5wdXQgPSBOVUxMOwogIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKCiAgVFJBQ0UoIiglcClcbiIsIGxwVW5rbm93bik7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lJbnB1dE9iamVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscElucHV0KTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBJbnB1dCkKICAgIHsKICAgICAgaFJldCA9IElJbnB1dE9iamVjdF9IYXNGb2N1c0lPKGxwSW5wdXQpOwogICAgICBJSW5wdXRPYmplY3RfUmVsZWFzZShscElucHV0KTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQ29sb3JSR0JUb0hMUwlbU0hMV0FQSS5AXQogKgogKiBDb252ZXJ0IGFuIHJnYiBDT0xPUlJFRiBpbnRvIHRoZSBobHMgY29sb3Igc3BhY2UuCiAqCiAqIFBBUkFNUwogKiAgY1JHQiAgICAgICAgIFtJXSBTb3VyY2UgcmdiIHZhbHVlCiAqICBwd0h1ZSAgICAgICAgW09dIERlc3RpbmF0aW9uIGZvciBjb252ZXJ0ZWQgaHVlCiAqICBwd0x1bWluYW5jZSAgW09dIERlc3RpbmF0aW9uIGZvciBjb252ZXJ0ZWQgbHVtaW5hbmNlCiAqICBwd1NhdHVyYXRpb24gW09dIERlc3RpbmF0aW9uIGZvciBjb252ZXJ0ZWQgc2F0dXJhdGlvbgogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLiBwd0h1ZSwgcHdMdW1pbmFuY2UgYW5kIHB3U2F0dXJhdGlvbiBhcmUgc2V0IHRvIHRoZSBjb252ZXJ0ZWQKICogIHZhbHVlcy4KICoKICogTk9URVMKICogIE91dHB1dCBITFMgdmFsdWVzIGFyZSBjb25zdHJhaW5lZCB0byB0aGUgcmFuZ2UgKDAuLjI0MCkuCiAqICBGb3IgQWNocm9tYXRpYyBjb252ZXJzaW9ucywgSHVlIGlzIHNldCB0byAxNjAuCiAqLwpWT0lEIFdJTkFQSSBDb2xvclJHQlRvSExTKENPTE9SUkVGIGNSR0IsIExQV09SRCBwd0h1ZSwKCQkJICBMUFdPUkQgcHdMdW1pbmFuY2UsIExQV09SRCBwd1NhdHVyYXRpb24pCnsKICBpbnQgd1IsIHdHLCB3Qiwgd01heCwgd01pbiwgd0h1ZSwgd0x1bWlub3NpdHksIHdTYXR1cmF0aW9uOwoKICBUUkFDRSgiKCUwOGx4LCVwLCVwLCVwKVxuIiwgY1JHQiwgcHdIdWUsIHB3THVtaW5hbmNlLCBwd1NhdHVyYXRpb24pOwoKICB3UiA9IEdldFJWYWx1ZShjUkdCKTsKICB3RyA9IEdldEdWYWx1ZShjUkdCKTsKICB3QiA9IEdldEJWYWx1ZShjUkdCKTsKCiAgd01heCA9IG1heCh3UiwgbWF4KHdHLCB3QikpOwogIHdNaW4gPSBtaW4od1IsIG1pbih3Rywgd0IpKTsKCiAgLyogTHVtaW5vc2l0eSAqLwogIHdMdW1pbm9zaXR5ID0gKCh3TWF4ICsgd01pbikgKiAyNDAgKyAyNTUpIC8gNTEwOwoKICBpZiAod01heCA9PSB3TWluKQogIHsKICAgIC8qIEFjaHJvbWF0aWMgY2FzZSAqLwogICAgd1NhdHVyYXRpb24gPSAwOwogICAgLyogSHVlIGlzIG5vdyB1bnJlcHJlc2VudGFibGUsIGJ1dCB0aGlzIGlzIHdoYXQgbmF0aXZlIHJldHVybnMuLi4gKi8KICAgIHdIdWUgPSAxNjA7CiAgfQogIGVsc2UKICB7CiAgICAvKiBDaHJvbWF0aWMgY2FzZSAqLwogICAgaW50IHdEZWx0YSA9IHdNYXggLSB3TWluLCB3Uk5vcm0sIHdHTm9ybSwgd0JOb3JtOwoKICAgIC8qIFNhdHVyYXRpb24gKi8KICAgIGlmICh3THVtaW5vc2l0eSA8PSAxMjApCiAgICAgIHdTYXR1cmF0aW9uID0gKCh3TWF4ICsgd01pbikvMiArIHdEZWx0YSAqIDI0MCkgLyAod01heCArIHdNaW4pOwogICAgZWxzZQogICAgICB3U2F0dXJhdGlvbiA9ICgoNTEwIC0gd01heCAtIHdNaW4pLzIgKyB3RGVsdGEgKiAyNDApIC8gKDUxMCAtIHdNYXggLSB3TWluKTsKCiAgICAvKiBIdWUgKi8KICAgIHdSTm9ybSA9ICh3RGVsdGEvMiArIHdNYXggKiA0MCAtIHdSICogNDApIC8gd0RlbHRhOwogICAgd0dOb3JtID0gKHdEZWx0YS8yICsgd01heCAqIDQwIC0gd0cgKiA0MCkgLyB3RGVsdGE7CiAgICB3Qk5vcm0gPSAod0RlbHRhLzIgKyB3TWF4ICogNDAgLSB3QiAqIDQwKSAvIHdEZWx0YTsKCiAgICBpZiAod1IgPT0gd01heCkKICAgICAgd0h1ZSA9IHdCTm9ybSAtIHdHTm9ybTsKICAgIGVsc2UgaWYgKHdHID09IHdNYXgpCiAgICAgIHdIdWUgPSA4MCArIHdSTm9ybSAtIHdCTm9ybTsKICAgIGVsc2UKICAgICAgd0h1ZSA9IDE2MCArIHdHTm9ybSAtIHdSTm9ybTsKICAgIGlmICh3SHVlIDwgMCkKICAgICAgd0h1ZSArPSAyNDA7CiAgICBlbHNlIGlmICh3SHVlID4gMjQwKQogICAgICB3SHVlIC09IDI0MDsKICB9CiAgaWYgKHB3SHVlKQogICAgKnB3SHVlID0gd0h1ZTsKICBpZiAocHdMdW1pbmFuY2UpCiAgICAqcHdMdW1pbmFuY2UgPSB3THVtaW5vc2l0eTsKICBpZiAocHdTYXR1cmF0aW9uKQogICAgKnB3U2F0dXJhdGlvbiA9IHdTYXR1cmF0aW9uOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNIQ3JlYXRlU2hlbGxQYWxldHRlCVtTSExXQVBJLkBdCiAqLwpIUEFMRVRURSBXSU5BUEkgU0hDcmVhdGVTaGVsbFBhbGV0dGUoSERDIGhkYykKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIENyZWF0ZUhhbGZ0b25lUGFsZXR0ZShoZGMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglTSEdldEludmVyc2VDTUFQIChTSExXQVBJLkApCiAqCiAqIEdldCBhbiBpbnZlcnNlIGNvbG9yIG1hcCB0YWJsZS4KICoKICogUEFSQU1TCiAqICBscENtYXAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29sb3IgbWFwCiAqICBkd1NpemUgIFtJXSBTaXplIG9mIG1lbW9yeSBwb2ludGVkIHRvIGJ5IGxwQ21hcAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9QT0lOVEVSLCAgICBJZiBscENtYXAgaXMgaW52YWxpZC4KICogICAgICAgICAgIEVfSU5WQUxJREFSRywgSWYgZHdGbGFncyBpcyBpbnZhbGlkCiAqICAgICAgICAgICBFX09VVE9GTUVNT1JZLCBJZiB0aGVyZSBpcyBubyBtZW1vcnkgYXZhaWxhYmxlCiAqCiAqIE5PVEVTCiAqICBkd1NpemUgbWF5IG9ubHkgYmUgQ01BUF9QVFJfU0laRSAoNCkgb3IgQ01BUF9TSVpFICg4MTkyKS4KICogIElmIGR3U2l6ZSA9IENNQVBfUFRSX1NJWkUsICpscENtYXAgaXMgc2V0IHRvIHRoZSBhZGRyZXNzIG9mIHRoaXMgRExMJ3MKICogIGludGVybmFsIENNYXAuCiAqICBJZiBkd1NpemUgPSBDTUFQX1NJWkUsIGxwQ21hcCBpcyBmaWxsZWQgd2l0aCBhIGNvcHkgb2YgdGhlIGRhdGEgZnJvbQogKiAgdGhpcyBETEwncyBpbnRlcm5hbCBDTWFwLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hHZXRJbnZlcnNlQ01BUChMUERXT1JEIGRlc3QsIERXT1JEIGR3U2l6ZSkKewogICAgaWYgKGR3U2l6ZSA9PSA0KSB7CglGSVhNRSgiIC0gcmV0dXJuaW5nIGJvZ3VzIGFkZHJlc3MgZm9yIFNIR2V0SW52ZXJzZUNNQVBcbiIpOwoJKmRlc3QgPSAoRFdPUkQpMHhhYmJhMTI0OTsKCXJldHVybiAwOwogICAgfQogICAgRklYTUUoIiglcCwgJSNseCkgc3R1YlxuIiwgZGVzdCwgZHdTaXplKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNISXNMb3dNZW1vcnlNYWNoaW5lCVtTSExXQVBJLkBdCiAqCiAqIERldGVybWluZSBpZiB0aGUgY3VycmVudCBjb21wdXRlciBoYXMgbG93IG1lbW9yeS4KICoKICogUEFSQU1TCiAqICB4IFtJXSBGSVhNRQogKgogKiBSRVRVUk5TCiAqICBUUlVFIGlmIHRoZSB1c2VycyBtYWNoaW5lIGhhcyAxNiBNZWdhYnl0ZXMgb2YgbWVtb3J5IG9yIGxlc3MsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTSElzTG93TWVtb3J5TWFjaGluZSAoRFdPUkQgeCkKewogIEZJWE1FKCIoMHglMDhseCkgc3R1YlxuIiwgeCk7CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEdldE1lbnVQb3NGcm9tSUQJW1NITFdBUEkuQF0KICoKICogUmV0dXJuIHRoZSBwb3NpdGlvbiBvZiBhIG1lbnUgaXRlbSBmcm9tIGl0cyBJZC4KICoKICogUEFSQU1TCiAqICAgaE1lbnUgW0ldIE1lbnUgY29udGFpbmluZyB0aGUgaXRlbQogKiAgIHdJRCAgIFtJXSBJZCBvZiB0aGUgbWVudSBpdGVtCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBpbmRleCBvZiB0aGUgbWVudSBpdGVtIGluIGhNZW51LgogKiAgRmFpbHVyZTogLTEsIElmIHRoZSBpdGVtIGlzIG5vdCBmb3VuZC4KICovCklOVCBXSU5BUEkgR2V0TWVudVBvc0Zyb21JRChITUVOVSBoTWVudSwgVUlOVCB3SUQpCnsKIE1FTlVJVEVNSU5GT1cgbWk7CiBJTlQgbkNvdW50ID0gR2V0TWVudUl0ZW1Db3VudChoTWVudSksIG5JdGVyID0gMDsKCiB3aGlsZSAobkl0ZXIgPCBuQ291bnQpCiB7CiAgIG1pLmNiU2l6ZSA9IHNpemVvZihtaSk7CiAgIG1pLmZNYXNrID0gTUlJTV9JRDsKICAgaWYgKEdldE1lbnVJdGVtSW5mb1coaE1lbnUsIG5JdGVyLCBUUlVFLCAmbWkpICYmIG1pLndJRCA9PSB3SUQpCiAgICAgcmV0dXJuIG5JdGVyOwogICBuSXRlcisrOwogfQogcmV0dXJuIC0xOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTc5XQogKgogKiBTYW1lIGFzIFNITFdBUEkuR2V0TWVudVBvc0Zyb21JRAogKi8KRFdPUkQgV0lOQVBJIFNITWVudUluZGV4RnJvbUlEKEhNRU5VIGhNZW51LCBVSU5UIHVJRCkKewogICAgcmV0dXJuIEdldE1lbnVQb3NGcm9tSUQoaE1lbnUsIHVJRCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDQ4XQogKi8KVk9JRCBXSU5BUEkgRml4U2xhc2hlc0FuZENvbG9uVyhMUFdTVFIgbHB3c3RyKQp7CiAgICB3aGlsZSAoKmxwd3N0cikKICAgIHsKICAgICAgICBpZiAoKmxwd3N0ciA9PSAnLycpCiAgICAgICAgICAgICpscHdzdHIgPSAnXFwnOwogICAgICAgIGxwd3N0cisrOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQ2MV0KICovCkRXT1JEIFdJTkFQSSBTSEdldEFwcENvbXBhdEZsYWdzKERXT1JEIGR3VW5rbm93bikKewogIEZJWE1FKCIoMHglMDhseCkgc3R1YlxuIiwgZHdVbmtub3duKTsKICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS41NDldCiAqLwpIUkVTVUxUIFdJTkFQSSBTSENvQ3JlYXRlSW5zdGFuY2VBQyhSRUZDTFNJRCByY2xzaWQsIExQVU5LTk9XTiBwVW5rT3V0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3Q2xzQ29udGV4dCwgUkVGSUlEIGlpZCwgTFBWT0lEICpwcHYpCnsKICAgIHJldHVybiBDb0NyZWF0ZUluc3RhbmNlKHJjbHNpZCwgcFVua091dGVyLCBkd0Nsc0NvbnRleHQsIGlpZCwgcHB2KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hTa2lwSnVuY3Rpb24JW1NITFdBUEkuQF0KICoKICogRGV0ZXJtaW5lIGlmIGEgYmluZCBjb250ZXh0IGNhbiBiZSBib3VuZCB0byBhbiBvYmplY3QKICoKICogUEFSQU1TCiAqICBwYmMgICAgW0ldIEJpbmQgY29udGV4dCB0byBjaGVjawogKiAgcGNsc2lkIFtJXSBDTFNJRCBvZiBvYmplY3QgdG8gYmUgYm91bmQgdG8KICoKICogUkVUVVJOUwogKiAgVFJVRTogSWYgaXQgaXMgc2FmZSB0byBiaW5kCiAqICBGQUxTRTogSWYgcGJjIGlzIGludmFsaWQgb3IgYmluZGluZyB3b3VsZCBub3QgYmUgc2FmZQogKgogKi8KQk9PTCBXSU5BUEkgU0hTa2lwSnVuY3Rpb24oSUJpbmRDdHggKnBiYywgY29uc3QgQ0xTSUQgKnBjbHNpZCkKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelNraXBCaW5kaW5nW10gPSB7ICdTJywnaycsJ2knLCdwJywnICcsCiAgICAnQicsJ2knLCduJywnZCcsJ2knLCduJywnZycsJyAnLCdDJywnTCcsJ1MnLCdJJywnRCcsJ1wwJyB9OwogIEJPT0wgYlJldCA9IEZBTFNFOwoKICBpZiAocGJjKQogIHsKICAgIElVbmtub3duKiBscFVuazsKCiAgICBpZiAoU1VDQ0VFREVEKElCaW5kQ3R4X0dldE9iamVjdFBhcmFtKHBiYywgKExQT0xFU1RSKXN6U2tpcEJpbmRpbmcsICZscFVuaykpKQogICAgewogICAgICBDTFNJRCBjbHNpZDsKCiAgICAgIGlmIChTVUNDRUVERUQoSVVua25vd25fR2V0Q2xhc3NJRChscFVuaywgJmNsc2lkKSkgJiYKICAgICAgICAgIElzRXF1YWxHVUlEKHBjbHNpZCwgJmNsc2lkKSkKICAgICAgICBiUmV0ID0gVFJVRTsKCiAgICAgIElVbmtub3duX1JlbGVhc2UobHBVbmspOwogICAgfQogIH0KICByZXR1cm4gYlJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEdldFNoZWxsS2V5IChTSExXQVBJLkApCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRTaGVsbEtleShEV09SRCBhLCBEV09SRCBiLCBEV09SRCBjKQp7CiAgICBGSVhNRSgiKCVseCwgJWx4LCAlbHgpOiBzdHViXG4iLCBhLCBiLCBjKTsKICAgIHJldHVybiAweDUwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIUXVldWVVc2VyV29ya0l0ZW0gKFNITFdBUEkuQCkKICovCkhSRVNVTFQgV0lOQVBJIFNIUXVldWVVc2VyV29ya0l0ZW0oRFdPUkQgYSwgRFdPUkQgYiwgRFdPUkQgYywgRFdPUkQgZCwgRFdPUkQgZSwgRFdPUkQgZiwgRFdPUkQgZykKewogICAgRklYTUUoIiglbHgsICVseCwgJWx4LCAlbHgsICVseCwgJWx4LCAlbHgpOiBzdHViXG4iLCBhLCBiLCBjLCBkLCBlLCBmLCBnKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSVVua25vd25fT25Gb2N1c0NoYW5nZUlTIChTSExXQVBJLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9PbkZvY3VzQ2hhbmdlSVMoTFBVTktOT1dOIGxwVW5rbm93biwgTFBVTktOT1dOIHBGb2N1c09iamVjdCwgQk9PTCBiRm9jdXMpCnsKICAgIElJbnB1dE9iamVjdFNpdGUgKnBJT1MgPSBOVUxMOwogICAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwoKICAgIFRSQUNFKCIoJXAsICVwLCAlcylcbiIsIGxwVW5rbm93biwgcEZvY3VzT2JqZWN0LCBiRm9jdXMgPyAiVFJVRSIgOiAiRkFMU0UiKTsKCiAgICBpZiAobHBVbmtub3duKQogICAgewogICAgICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUlucHV0T2JqZWN0U2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKiopJnBJT1MpOwogICAgICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgcElPUykKICAgICAgICB7CiAgICAgICAgICAgIGhSZXQgPSBJSW5wdXRPYmplY3RTaXRlX09uRm9jdXNDaGFuZ2VJUyhwSU9TLCBwRm9jdXNPYmplY3QsIGJGb2N1cyk7CiAgICAgICAgICAgIElJbnB1dE9iamVjdFNpdGVfUmVsZWFzZShwSU9TKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEdldFZhbHVlVyAoU0hMV0FQSS5AKQogKi8KSFJFU1VMVCBXSU5BUEkgU0tHZXRWYWx1ZVcoRFdPUkQgYSwgTFBXU1RSIGIsIExQV1NUUiBjLCBEV09SRCBkLCBEV09SRCBlLCBEV09SRCBmKQp7CiAgICBGSVhNRSgiKCVseCwgJXMsICVzLCAlbHgsICVseCwgJWx4KTogc3R1YlxuIiwgYSwgZGVidWdzdHJfdyhiKSwgZGVidWdzdHJfdyhjKSwgZCwgZSwgZik7CiAgICByZXR1cm4gRV9GQUlMOwp9Cgp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqRGxsR2V0VmVyc2lvbl9mdW5jKShETExWRVJTSU9OSU5GTyAqKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgR2V0VUlWZXJzaW9uIChTSExXQVBJLjQ1MikKICovCkRXT1JEIFdJTkFQSSBHZXRVSVZlcnNpb24odm9pZCkKewogICAgc3RhdGljIERXT1JEIHZlcnNpb247CgogICAgaWYgKCF2ZXJzaW9uKQogICAgewogICAgICAgIERsbEdldFZlcnNpb25fZnVuYyBwRGxsR2V0VmVyc2lvbjsKICAgICAgICBITU9EVUxFIGRsbCA9IExvYWRMaWJyYXJ5QSgic2hlbGwzMi5kbGwiKTsKICAgICAgICBpZiAoIWRsbCkgcmV0dXJuIDA7CgogICAgICAgIHBEbGxHZXRWZXJzaW9uID0gKERsbEdldFZlcnNpb25fZnVuYylHZXRQcm9jQWRkcmVzcyhkbGwsICJEbGxHZXRWZXJzaW9uIik7CiAgICAgICAgaWYgKHBEbGxHZXRWZXJzaW9uKQogICAgICAgIHsKICAgICAgICAgICAgRExMVkVSU0lPTklORk8gZHZpOwogICAgICAgICAgICBkdmkuY2JTaXplID0gc2l6ZW9mKERMTFZFUlNJT05JTkZPKTsKICAgICAgICAgICAgaWYgKHBEbGxHZXRWZXJzaW9uKCZkdmkpID09IFNfT0spIHZlcnNpb24gPSBkdmkuZHdNYWpvclZlcnNpb247CiAgICAgICAgfQogICAgICAgIEZyZWVMaWJyYXJ5KCBkbGwgKTsKICAgICAgICBpZiAoIXZlcnNpb24pIHZlcnNpb24gPSAzOyAgLyogb2xkIHNoZWxsIGRsbHMgZG9uJ3QgaGF2ZSBEbGxHZXRWZXJzaW9uICovCiAgICB9CiAgICByZXR1cm4gdmVyc2lvbjsKfQo=