LyoKICogVGhlIHBhcmFtZXRlcnMgb2YgbWFueSBmdW5jdGlvbnMgY2hhbmdlcyBiZXR3ZWVuIGRpZmZlcmVudCBPUyB2ZXJzaW9ucwogKiAoTlQgdXNlcyBVbmljb2RlIHN0cmluZ3MsIDk1IHVzZXMgQVNDSUkgc3RyaW5ncykKICoKICogQ29weXJpZ2h0IDE5OTcgTWFyY3VzIE1laXNzbmVyCiAqICAgICAgICAgICAxOTk4IEr8cmdlbiBTY2htaWVkCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAiaGVhcC5oIgoKI2luY2x1ZGUgIndpbmUvb2JqX2Jhc2UuaCIKI2luY2x1ZGUgInNoZWxsYXBpLmgiCiNpbmNsdWRlICJzaGxndWlkLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNoZWxsMzJfbWFpbi5oIgojaW5jbHVkZSAidW5kb2NzaGVsbC5oIgojaW5jbHVkZSAicGlkbC5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoc2hlbGwpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChwaWRsKTsKCi8qIEZJWE1FOiAhISEgbW92ZSBDUkVBVEVNUlVMSVNUIGFuZCBmbGFncyB0byBoZWFkZXIgZmlsZSAhISEgKi8KLyogICAgICAgICEhISBpdCBpcyBpbiBib3RoIGhlcmUgYW5kIGNvbWN0bDMydW5kb2MuYyAgICAgICEhISAqLwp0eXBlZGVmIHN0cnVjdCB0YWdDUkVBVEVNUlVMSVNUCnsKICAgIERXT1JEICBjYlNpemU7ICAgICAgICAvKiBzaXplIG9mIHN0cnVjdCAqLwogICAgRFdPUkQgIG5NYXhJdGVtczsgICAgIC8qIG1heCBuby4gb2YgaXRlbXMgaW4gbGlzdCAqLwogICAgRFdPUkQgIGR3RmxhZ3M7ICAgICAgIC8qIHNlZSBiZWxvdyAqLwogICAgSEtFWSAgIGhLZXk7ICAgICAgICAgIC8qIHJvb3QgcmVnLiBrZXkgdW5kZXIgd2hpY2ggbGlzdCBpcyBzYXZlZCAqLwogICAgTFBDU1RSIGxwc3pTdWJLZXk7ICAgIC8qIHJlZy4gc3Via2V5ICovCiAgICBQUk9DICAgbHBmbkNvbXBhcmU7ICAgLyogaXRlbSBjb21wYXJlIHByb2MgKi8KfSBDUkVBVEVNUlVMSVNUQSwgKkxQQ1JFQVRFTVJVTElTVEE7CgovKiBkd0ZsYWdzICovCiNkZWZpbmUgTVJVRl9TVFJJTkdfTElTVCAgMCAvKiBsaXN0IHdpbGwgY29udGFpbiBzdHJpbmdzICovCiNkZWZpbmUgTVJVRl9CSU5BUllfTElTVCAgMSAvKiBsaXN0IHdpbGwgY29udGFpbiBiaW5hcnkgZGF0YSAqLwojZGVmaW5lIE1SVUZfREVMQVlFRF9TQVZFIDIgLyogb25seSBzYXZlIGxpc3Qgb3JkZXIgdG8gcmVnLiBpcyBGcmVlTVJVTGlzdCAqLwoKZXh0ZXJuIEhBTkRMRSBXSU5BUEkgQ3JlYXRlTVJVTGlzdEEoTFBDUkVBVEVNUlVMSVNUQSBscGNtbCk7CmV4dGVybiBEV09SRCAgV0lOQVBJIEZyZWVNUlVMaXN0KEhBTkRMRSBoTVJVTGlzdCk7CmV4dGVybiBJTlQgICAgV0lOQVBJIEFkZE1SVURhdGEoSEFORExFIGhMaXN0LCBMUENWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhKTsKZXh0ZXJuIElOVCAgICBXSU5BUEkgRmluZE1SVURhdGEoSEFORExFIGhMaXN0LCBMUENWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhLCBMUElOVCBscFJlZ051bSk7CmV4dGVybiBJTlQgICAgV0lOQVBJIEVudW1NUlVMaXN0QShIQU5ETEUgaExpc3QsIElOVCBuSXRlbVBvcywgTFBWT0lEIGxwQnVmZmVyLCBEV09SRCBuQnVmZmVyU2l6ZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQYXJzZUZpZWxkQQkJCQkJW2ludGVybmFsXQogKgogKiBjb3BpZXMgYSBmaWVsZCBmcm9tIGEgJywnIGRlbGltaXRlZCBzdHJpbmcKICoKICogZmlyc3QgZmllbGQgaXMgbkZpZWxkID0gMQogKi8KRFdPUkQgV0lOQVBJIFBhcnNlRmllbGRBKAoJTFBDU1RSIHNyYywKCURXT1JEIG5GaWVsZCwKCUxQU1RSIGRzdCwKCURXT1JEIGxlbikKewoJV0FSTigiKCVzLDB4JTA4bHgsJXAsJWxkKSBzZW1pLXN0dWIuXG4iLGRlYnVnc3RyX2Eoc3JjKSxuRmllbGQsZHN0LGxlbik7CgoJaWYgKCFzcmMgfHwgIXNyY1swXSB8fCAhZHN0IHx8ICFsZW4pCgkgIHJldHVybiAwOwoKCS8qIHNraXAgbiBmaWVsZHMgZGVsaW1pdGVkIGJ5ICcsJyAqLwoJd2hpbGUgKG5GaWVsZCA+IDEpCgl7CgkgIGlmICgqc3JjPT0nXDAnKSByZXR1cm4gRkFMU0U7CgkgIGlmICgqKHNyYysrKT09JywnKSBuRmllbGQtLTsKCX0KCgkvKiBjb3B5IHBhcnQgdGlsbCB0aGUgbmV4dCAnLCcgdG8gZHN0ICovCgl3aGlsZSAoICpzcmMhPSdcMCcgJiYgKnNyYyE9JywnICYmIChsZW4tLSk+MCApICooZHN0KyspPSooc3JjKyspOwoKCS8qIGZpbmFsaXplIHRoZSBzdHJpbmcgKi8KCSpkc3Q9MHgwOwoKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQYXJzZUZpZWxkVwkJCVtpbnRlcm5hbF0KICoKICogY29waWVzIGEgZmllbGQgZnJvbSBhICcsJyBkZWxpbWl0ZWQgc3RyaW5nCiAqCiAqIGZpcnN0IGZpZWxkIGlzIG5GaWVsZCA9IDEKICovCkRXT1JEIFdJTkFQSSBQYXJzZUZpZWxkVyhMUENXU1RSIHNyYywgRFdPUkQgbkZpZWxkLCBMUFdTVFIgZHN0LCBEV09SRCBsZW4pCnsKCUZJWE1FKCIoJXMsMHglMDhseCwlcCwlbGQpIHN0dWJcbiIsCgkgIGRlYnVnc3RyX3coc3JjKSwgbkZpZWxkLCBkc3QsIGxlbik7CglyZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFBhcnNlRmllbGQJCQlbU0hFTEwzMi41OF0KICovCkRXT1JEIFdJTkFQSSBQYXJzZUZpZWxkQVcoTFBDVk9JRCBzcmMsIERXT1JEIG5GaWVsZCwgTFBWT0lEIGRzdCwgRFdPUkQgbGVuKQp7CglpZiAoU0hFTExfT3NJc1VuaWNvZGUoKSkKCSAgcmV0dXJuIFBhcnNlRmllbGRXKHNyYywgbkZpZWxkLCBkc3QsIGxlbik7CglyZXR1cm4gUGFyc2VGaWVsZEEoc3JjLCBuRmllbGQsIGRzdCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogR2V0RmlsZU5hbWVGcm9tQnJvd3NlCQkJW1NIRUxMMzIuNjNdCiAqCiAqLwpCT09MIFdJTkFQSSBHZXRGaWxlTmFtZUZyb21Ccm93c2UoCglIV05EIGh3bmRPd25lciwKCUxQU1RSIGxwc3RyRmlsZSwKCURXT1JEIG5NYXhGaWxlLAoJTFBDU1RSIGxwc3RySW5pdGlhbERpciwKCUxQQ1NUUiBscHN0ckRlZkV4dCwKCUxQQ1NUUiBscHN0ckZpbHRlciwKCUxQQ1NUUiBscHN0clRpdGxlKQp7CiAgICBITU9EVUxFIGhtb2R1bGU7CiAgICBGQVJQUk9DIHBHZXRPcGVuRmlsZU5hbWVBOwogICAgT1BFTkZJTEVOQU1FQSBvZm47CiAgICBCT09MIHJldDsKCiAgICBUUkFDRSgiJTA0eCwgJXMsICVsZCwgJXMsICVzLCAlcywgJXMpXG4iLAoJICBod25kT3duZXIsIGxwc3RyRmlsZSwgbk1heEZpbGUsIGxwc3RySW5pdGlhbERpciwgbHBzdHJEZWZFeHQsCgkgIGxwc3RyRmlsdGVyLCBscHN0clRpdGxlKTsKCiAgICBobW9kdWxlID0gTG9hZExpYnJhcnlBKCJjb21kbGczMi5kbGwiKTsKICAgIGlmKCFobW9kdWxlKSByZXR1cm4gRkFMU0U7CiAgICBwR2V0T3BlbkZpbGVOYW1lQSA9IEdldFByb2NBZGRyZXNzKGhtb2R1bGUsICJHZXRPcGVuRmlsZU5hbWVBIik7CiAgICBpZighcEdldE9wZW5GaWxlTmFtZUEpCiAgICB7CglGcmVlTGlicmFyeShobW9kdWxlKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBtZW1zZXQoJm9mbiwgMCwgc2l6ZW9mKG9mbikpOwoKICAgIG9mbi5sU3RydWN0U2l6ZSA9IHNpemVvZihvZm4pOwogICAgb2ZuLmh3bmRPd25lciA9IGh3bmRPd25lcjsKICAgIG9mbi5scHN0ckZpbHRlciA9IGxwc3RyRmlsdGVyOwogICAgb2ZuLmxwc3RyRmlsZSA9IGxwc3RyRmlsZTsKICAgIG9mbi5uTWF4RmlsZSA9IG5NYXhGaWxlOwogICAgb2ZuLmxwc3RySW5pdGlhbERpciA9IGxwc3RySW5pdGlhbERpcjsKICAgIG9mbi5scHN0clRpdGxlID0gbHBzdHJUaXRsZTsKICAgIG9mbi5scHN0ckRlZkV4dCA9IGxwc3RyRGVmRXh0OwogICAgb2ZuLkZsYWdzID0gT0ZOX0VYUExPUkVSIHwgT0ZOX0hJREVSRUFET05MWSB8IE9GTl9GSUxFTVVTVEVYSVNUOwogICAgcmV0ID0gcEdldE9wZW5GaWxlTmFtZUEoJm9mbik7CgogICAgRnJlZUxpYnJhcnkoaG1vZHVsZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEdldFNldFNldHRpbmdzCQkJCVtTSEVMTDMyLjY4XQogKi8KVk9JRCBXSU5BUEkgU0hHZXRTZXRTZXR0aW5ncyhEV09SRCB4LCBEV09SRCB5LCBEV09SRCB6KQp7CglGSVhNRSgiMHglMDhseCAweCUwOGx4IDB4JTA4bHhcbiIsIHgsIHksIHopOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEdldFNldHRpbmdzCQkJCVtTSEVMTDMyLkBdCiAqCiAqIE5PVEVTCiAqICB0aGUgcmVnaXN0cnkgcGF0aCBhcmUgZm9yIHdpbjk4ICh0ZXN0ZWQpCiAqICBhbmQgcG9zc2libHkgYXJlIHRoZSBzYW1lIGluIG50NDAKICoKICovClZPSUQgV0lOQVBJIFNIR2V0U2V0dGluZ3MoTFBTSEVMTEZMQUdTVEFURSBscHNmcywgRFdPUkQgZHdNYXNrKQp7CglIS0VZCWhLZXk7CglEV09SRAlkd0RhdGE7CglEV09SRAlkd0RhdGFTaXplID0gc2l6ZW9mIChEV09SRCk7CgoJVFJBQ0UoIiglcCAweCUwOGx4KVxuIixscHNmcyxkd01hc2spOwoKCWlmIChSZWdDcmVhdGVLZXlFeEEoSEtFWV9DVVJSRU5UX1VTRVIsICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50VmVyc2lvblxcRXhwbG9yZXJcXEFkdmFuY2VkIiwKCQkJCSAwLCAwLCAwLCBLRVlfQUxMX0FDQ0VTUywgMCwgJmhLZXksIDApKQoJICByZXR1cm47CgoJaWYgKCAoU1NGX1NIT1dFWFRFTlNJT05TICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiSGlkZUZpbGVFeHQiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93RXh0ZW5zaW9ucyAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX1NIT1dJTkZPVElQICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiU2hvd0luZm9UaXAiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93SW5mb1RpcCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX0RPTlRQUkVUVFlQQVRIICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiRG9udFByZXR0eVBhdGgiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZEb250UHJldHR5UGF0aCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX0hJREVJQ09OUyAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIkhpZGVJY29ucyIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+ZkhpZGVJY29ucyAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX01BUE5FVERSVkJVVFRPTiAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIk1hcE5ldERydkJ0biIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+Zk1hcE5ldERydkJ0biAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX1NIT1dBVFRSSUJDT0wgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJTaG93QXR0cmliQ29sIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mU2hvd0F0dHJpYkNvbCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCgoU1NGX1NIT1dBTExPQkpFQ1RTIHwgU1NGX1NIT1dTWVNGSUxFUykgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJIaWRkZW4iLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCXsgaWYgKGR3RGF0YSA9PSAwKQoJICB7IGlmIChTU0ZfU0hPV0FMTE9CSkVDVFMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd0FsbE9iamVjdHMgID0gMDsKCSAgICBpZiAoU1NGX1NIT1dTWVNGSUxFUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93U3lzRmlsZXMgID0gMDsKCSAgfQoJICBlbHNlIGlmIChkd0RhdGEgPT0gMSkKCSAgeyBpZiAoU1NGX1NIT1dBTExPQkpFQ1RTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dBbGxPYmplY3RzICA9IDE7CgkgICAgaWYgKFNTRl9TSE9XU1lTRklMRVMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd1N5c0ZpbGVzICA9IDA7CgkgIH0KCSAgZWxzZSBpZiAoZHdEYXRhID09IDIpCgkgIHsgaWYgKFNTRl9TSE9XQUxMT0JKRUNUUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93QWxsT2JqZWN0cyAgPSAwOwoJICAgIGlmIChTU0ZfU0hPV1NZU0ZJTEVTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dTeXNGaWxlcyAgPSAxOwoJICB9Cgl9CglSZWdDbG9zZUtleSAoaEtleSk7CgoJVFJBQ0UoIi0tIDB4JTA0eFxuIiwgKihXT1JEKilscHNmcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UJCQlbU0hFTEwzMi43M10KICoKICogUEFSQU1FVEVSUwogKiAgaHduZENhYmluZXQgZGVmaW5lcyB0aGUgZXhwbG9yZXIgY2FiaW5ldCB3aW5kb3cgdGhhdCBjb250YWlucyB0aGUKICogICAgICAgICAgICAgIHNoZWxsdmlldyB5b3UgbmVlZCB0byBjb21tdW5pY2F0ZSB3aXRoCiAqICB1TXNnICAgICAgICBpZGVudGlmeWluZyB0aGUgU0ZWTSBlbnVtIHRvIHBlcmZvcm0KICogIGxQYXJhbQogKgogKiBOT1RFUwogKiAgTWVzc2FnZSBTRlZNX1JFQVJSQU5HRSA9IDEKICogICAgVGhpcyBtZXNzYWdlIGdldHMgc2VudCB3aGVuIGEgY29sdW1uIGdldHMgY2xpY2tlZCB0byBpbnN0cnVjdCB0aGUKICogICAgc2hlbGwgdmlldyB0byByZS1zb3J0IHRoZSBpdGVtIGxpc3QuIGxQYXJhbSBpZGVudGlmaWVzIHRoZSBjb2x1bW4KICogICAgdGhhdCB3YXMgY2xpY2tlZC4KICovCmludCBXSU5BUEkgU0hTaGVsbEZvbGRlclZpZXdfTWVzc2FnZSgKCUhXTkQgaHduZENhYmluZXQsCglEV09SRCBkd01lc3NhZ2UsCglEV09SRCBkd1BhcmFtKQp7CglGSVhNRSgiJTA0eCAlMDhseCAlMDhseCBzdHViXG4iLGh3bmRDYWJpbmV0LCBkd01lc3NhZ2UsIGR3UGFyYW0pOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ2lzdGVyU2hlbGxIb29rCQkJCVtTSEVMTDMyLjE4MV0KICoKICogUEFSQU1TCiAqICAgICAgaHduZCBbSV0gIHdpbmRvdyBoYW5kbGUKICogICAgICB5ICAgIFtJXSAgZmxhZyA/Pz8/CiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpCT09MIFdJTkFQSSBSZWdpc3RlclNoZWxsSG9vaygKCUhXTkQgaFduZCwKCURXT1JEIGR3VHlwZSkKewoJRklYTUUoIigweCUwOHgsMHglMDhseCk6c3R1Yi5cbiIsaFduZCwgZHdUeXBlKTsKCXJldHVybiBUUlVFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsTWVzc2FnZUJveFcJCQkJW1NIRUxMMzIuMTgyXQogKgogKiBGb3JtYXQgYW5kIG91dHB1dCBlcnJvcm1lc3NhZ2UuCiAqCiAqIGlkVGV4dAlyZXNvdXJjZSBJRCBvZiB0aXRsZSBvciBMUFNUUgogKiBpZFRpdGxlCXJlc291cmNlIElEIG9mIHRpdGxlIG9yIExQU1RSCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwppbnQgV0lOQVBJViBTaGVsbE1lc3NhZ2VCb3hXKAoJSElOU1RBTkNFIGhJbnN0YW5jZSwKCUhXTkQgaFduZCwKCUxQQ1dTVFIgbHBUZXh0LAoJTFBDV1NUUiBscENhcHRpb24sCglVSU5UIHVUeXBlLAoJLi4uKQp7CglXQ0hBUglzelRleHRbMTAwXSxzelRpdGxlWzEwMF07CglMUENXU1RSIHBzelRleHQgPSBzelRleHQsIHBzelRpdGxlID0gc3pUaXRsZSwgcHN6VGVtcDsKCXZhX2xpc3QgYXJnczsKCWludAlyZXQ7CgoJdmFfc3RhcnQoYXJncywgdVR5cGUpOwoJLyogd3ZzcHJpbnRmQShidWYsZm10LCBhcmdzKTsgKi8KCglUUkFDRSgiKCUwOGx4LCUwOGx4LCVwLCVwLCUwOHgpXG4iLAoJKERXT1JEKWhJbnN0YW5jZSwoRFdPUkQpaFduZCxscFRleHQsbHBDYXB0aW9uLHVUeXBlKTsKCglpZiAoIUhJV09SRChscENhcHRpb24pKQoJICBMb2FkU3RyaW5nVyhoSW5zdGFuY2UsIChEV09SRClscENhcHRpb24sIHN6VGl0bGUsIHNpemVvZihzelRpdGxlKS9zaXplb2Yoc3pUaXRsZVswXSkpOwoJZWxzZQoJICBwc3pUaXRsZSA9IGxwQ2FwdGlvbjsKCglpZiAoIUhJV09SRChscFRleHQpKQoJICBMb2FkU3RyaW5nVyhoSW5zdGFuY2UsIChEV09SRClscFRleHQsIHN6VGV4dCwgc2l6ZW9mKHN6VGV4dCkvc2l6ZW9mKHN6VGV4dFswXSkpOwoJZWxzZQoJICBwc3pUZXh0ID0gbHBUZXh0OwoKCUZvcm1hdE1lc3NhZ2VXKEZPUk1BVF9NRVNTQUdFX0FMTE9DQVRFX0JVRkZFUiB8IEZPUk1BVF9NRVNTQUdFX0ZST01fU1RSSU5HLAoJCSAgICAgICBwc3pUZXh0LCAwLCAwLCAoTFBXU1RSKSZwc3pUZW1wLCAwLCAmYXJncyk7CgoJdmFfZW5kKGFyZ3MpOwoKCXJldCA9IE1lc3NhZ2VCb3hXKGhXbmQscHN6VGVtcCxwc3pUaXRsZSx1VHlwZSk7CglMb2NhbEZyZWUoKEhMT0NBTClwc3pUZW1wKTsKCXJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsTWVzc2FnZUJveEEJCQkJW1NIRUxMMzIuMTgzXQogKi8KaW50IFdJTkFQSVYgU2hlbGxNZXNzYWdlQm94QSgKCUhJTlNUQU5DRSBoSW5zdGFuY2UsCglIV05EIGhXbmQsCglMUENTVFIgbHBUZXh0LAoJTFBDU1RSIGxwQ2FwdGlvbiwKCVVJTlQgdVR5cGUsCgkuLi4pCnsKCWNoYXIJc3pUZXh0WzEwMF0sc3pUaXRsZVsxMDBdOwoJTFBDU1RSICBwc3pUZXh0ID0gc3pUZXh0LCBwc3pUaXRsZSA9IHN6VGl0bGUsIHBzelRlbXA7Cgl2YV9saXN0IGFyZ3M7CglpbnQJcmV0OwoKCXZhX3N0YXJ0KGFyZ3MsIHVUeXBlKTsKCS8qIHd2c3ByaW50ZkEoYnVmLGZtdCwgYXJncyk7ICovCgoJVFJBQ0UoIiglMDhseCwlMDhseCwlcCwlcCwlMDh4KVxuIiwKCShEV09SRCloSW5zdGFuY2UsKERXT1JEKWhXbmQsbHBUZXh0LGxwQ2FwdGlvbix1VHlwZSk7CgoJaWYgKCFISVdPUkQobHBDYXB0aW9uKSkKCSAgTG9hZFN0cmluZ0EoaEluc3RhbmNlLCAoRFdPUkQpbHBDYXB0aW9uLCBzelRpdGxlLCBzaXplb2Yoc3pUaXRsZSkpOwoJZWxzZQoJICBwc3pUaXRsZSA9IGxwQ2FwdGlvbjsKCglpZiAoIUhJV09SRChscFRleHQpKQoJICBMb2FkU3RyaW5nQShoSW5zdGFuY2UsIChEV09SRClscFRleHQsIHN6VGV4dCwgc2l6ZW9mKHN6VGV4dCkpOwoJZWxzZQoJICBwc3pUZXh0ID0gbHBUZXh0OwoKCUZvcm1hdE1lc3NhZ2VBKEZPUk1BVF9NRVNTQUdFX0FMTE9DQVRFX0JVRkZFUiB8IEZPUk1BVF9NRVNTQUdFX0ZST01fU1RSSU5HLAoJCSAgICAgICBwc3pUZXh0LCAwLCAwLCAoTFBTVFIpJnBzelRlbXAsIDAsICZhcmdzKTsKCgl2YV9lbmQoYXJncyk7CgoJcmV0ID0gTWVzc2FnZUJveEEoaFduZCxwc3pUZW1wLHBzelRpdGxlLHVUeXBlKTsKCUxvY2FsRnJlZSgoSExPQ0FMKXBzelRlbXApOwoJcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZWdpc3RlckRyYWdEcm9wCQkJCVtTSEVMTDMyLjg2XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZWdpc3RlckRyYWdEcm9wKAoJSFdORCBoV25kLAoJTFBEUk9QVEFSR0VUIHBEcm9wVGFyZ2V0KQp7CglGSVhNRSgiKDB4JTA4eCwlcCk6c3R1Yi5cbiIsIGhXbmQsIHBEcm9wVGFyZ2V0KTsKCWlmIChHZXRTaGVsbE9sZSgpKSByZXR1cm4gcFJlZ2lzdGVyRHJhZ0Ryb3AoaFduZCwgcERyb3BUYXJnZXQpOwogICAgICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJldm9rZURyYWdEcm9wCQkJCVtTSEVMTDMyLjg3XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZXZva2VEcmFnRHJvcChIV05EIGhXbmQpCnsKICAgIEZJWE1FKCIoMHglMDh4KTpzdHViLlxuIixoV25kKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSERvRHJhZ0Ryb3AJCQkJCVtTSEVMTDMyLjg4XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KSFJFU1VMVCBXSU5BUEkgU0hEb0RyYWdEcm9wKAoJSFdORCBoV25kLAoJTFBEQVRBT0JKRUNUIGxwRGF0YU9iamVjdCwKCUxQRFJPUFNPVVJDRSBscERyb3BTb3VyY2UsCglEV09SRCBkd09LRWZmZWN0LAoJTFBEV09SRCBwZHdFZmZlY3QpCnsKICAgIEZJWE1FKCIoMHglMDR4ICVwICVwIDB4JTA4bHggJXApOnN0dWIuXG4iLAogICAgaFduZCwgbHBEYXRhT2JqZWN0LCBscERyb3BTb3VyY2UsIGR3T0tFZmZlY3QsIHBkd0VmZmVjdCk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQXJyYW5nZVdpbmRvd3MJCQkJW1NIRUxMMzIuMTg0XQogKgogKi8KV09SRCBXSU5BUEkgQXJyYW5nZVdpbmRvd3MoCglIV05EIGh3bmRQYXJlbnQsCglEV09SRCBkd1Jlc2VydmVkLAoJTFBDUkVDVCBscFJlY3QsCglXT1JEIGNLaWRzLAoJQ09OU1QgSFdORCAqIGxwS2lkcykKewogICAgRklYTUUoIigweCUwOHggMHglMDhseCAlcCAweCUwNHggJXApOnN0dWIuXG4iLAoJICAgaHduZFBhcmVudCwgZHdSZXNlcnZlZCwgbHBSZWN0LCBjS2lkcywgbHBLaWRzKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTaWduYWxGaWxlT3BlbgkJCQlbU0hFTEwzMi4xMDNdCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqLwpEV09SRCBXSU5BUEkKU2lnbmFsRmlsZU9wZW4gKERXT1JEIGR3UGFyYW0xKQp7CiAgICBGSVhNRSgiKDB4JTA4bHgpOnN0dWIuXG4iLCBkd1BhcmFtMSk7CgogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQUREX2dldF9wb2xpY3kgLSBoZWxwZXIgZnVuY3Rpb24gZm9yIFNIQWRkVG9SZWNlbnREb2NzCiAqCiAqIFBBUkFNRVRFUlMKICogICBwb2xpY3kgICAgW0lOXSAgcG9saWN5IG5hbWUgKG51bGwgdGVybWVkIHN0cmluZykgdG8gZmluZAogKiAgIHR5cGUgICAgICBbT1VUXSBwdHIgdG8gRFdPUkQgdG8gcmVjZWl2ZSB0eXBlCiAqICAgYnVmZmVyICAgIFtPVVRdIHB0ciB0byBhcmVhIHRvIGhvbGQgZGF0YSByZXRyaWV2ZWQKICogICBsZW4gICAgICAgW0lOL09VVF0gcHRyIHRvIERXT1JEIGhvbGRpbmcgc2l6ZSBvZiBidWZmZXIgYW5kIGdldHRpbmcKICogICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoIGZpbGxlZAogKgogKiBSRVRVUk5TCiAqICAgcmVzdWx0IG9mIHRoZSBTSFF1ZXJ5VmFsdWVFeCBjYWxsCiAqLwpzdGF0aWMgSU5UIFNIQUREX2dldF9wb2xpY3koTFBTVFIgcG9saWN5LCBMUERXT1JEIHR5cGUsIExQVk9JRCBidWZmZXIsIExQRFdPUkQgbGVuKQp7CiAgICBIS0VZIFBvbGljeV9iYXNla2V5OwogICAgSU5UIHJldDsKCiAgICAvKiBHZXQgdGhlIGtleSBmb3IgdGhlIHBvbGljaWVzIGxvY2F0aW9uIGluIHRoZSByZWdpc3RyeQogICAgICovCiAgICBpZiAoUmVnT3BlbktleUV4QShIS0VZX0xPQ0FMX01BQ0hJTkUsCgkJICAgICAgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxQb2xpY2llc1xcRXhwbG9yZXIiLAoJCSAgICAgIDAsIEtFWV9SRUFELCAmUG9saWN5X2Jhc2VrZXkpKSB7CgoJaWYgKFJlZ09wZW5LZXlFeEEoSEtFWV9DVVJSRU5UX1VTRVIsCgkJCSAgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxQb2xpY2llc1xcRXhwbG9yZXIiLAoJCQkgIDAsIEtFWV9SRUFELCAmUG9saWN5X2Jhc2VrZXkpKSB7CgkgICAgVFJBQ0UoIk5vIEV4cGxvcmVyIFBvbGljaWVzIGxvY2F0aW9uIGV4aXN0cy4gUG9saWN5IHdhbnRlZD0lc1xuIiwKCQkgIHBvbGljeSk7CgkgICAgKmxlbiA9IDA7CgkgICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwoJfQogICAgfQoKICAgIC8qIFJldHJpZXZlIHRoZSBkYXRhIGlmIGl0IGV4aXN0cwogICAgICovCiAgICByZXQgPSBTSFF1ZXJ5VmFsdWVFeEEoUG9saWN5X2Jhc2VrZXksIHBvbGljeSwgMCwgdHlwZSwgYnVmZmVyLCBsZW4pOwogICAgUmVnQ2xvc2VLZXkoUG9saWN5X2Jhc2VrZXkpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQUREX2NvbXBhcmVfbXJ1IC0gaGVscGVyIGZ1bmN0aW9uIGZvciBTSEFkZFRvUmVjZW50RG9jcwogKgogKiBQQVJBTUVURVJTCiAqICAgZGF0YTEgICAgIFtJTl0gZGF0YSBiZWluZyBsb29rZWQgZm9yCiAqICAgZGF0YTIgICAgIFtJTl0gZGF0YSBpbiBNUlUKICogICBjYmRhdGEgICAgW0lOXSBsZW5ndGggZnJvbSBGaW5kTVJVRGF0YSBjYWxsIChub3QgdXNlZCkKICoKICogUkVUVVJOUwogKiAgIHBvc2l0aW9uIHdpdGhpbiBNUlUgbGlzdCB0aGF0IGRhdGEgd2FzIGFkZGVkLgogKi8Kc3RhdGljIElOVCBDQUxMQkFDSyBTSEFERF9jb21wYXJlX21ydShMUENWT0lEIGRhdGExLCBMUENWT0lEIGRhdGEyLCBEV09SRCBjYkRhdGEpCnsKICAgIHJldHVybiBsc3RyY21waUEoZGF0YTEsIGRhdGEyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBRERfY3JlYXRlX2FkZF9tcnVfZGF0YSAtIGhlbHBlciBmdW5jdGlvbiBmb3IgU0hBZGRUb1JlY2VudERvY3MKICoKICogUEFSQU1FVEVSUwogKiAgIG1ydWhhbmRsZSAgICBbSU5dIGhhbmRsZSBmb3IgY3JlYXRlZCBNUlUgbGlzdAogKiAgIGRvY19uYW1lICAgICBbSU5dIG51bGwgdGVybWVkIHB1cmUgZG9jIG5hbWUKICogICBuZXdfbG5rX25hbWUgW0lOXSBudWxsIHRlcm1lZCBwYXRoIGFuZCBmaWxlIG5hbWUgZm9yIC5sbmsgZmlsZQogKiAgIGJ1ZmZlciAgICAgICBbSU4vT1VUXSAyMDQ4IGJ5dGUgYXJlYSB0byBjb25zdHVyY3QgTVJVIGRhdGEKICogICBsZW4gICAgICAgICAgW09VVF0gcHRyIHRvIGludCB0byByZWNlaXZlIHNwYWNlIHVzZWQgaW4gYnVmZmVyCiAqCiAqIFJFVFVSTlMKICogICBwb3NpdGlvbiB3aXRoaW4gTVJVIGxpc3QgdGhhdCBkYXRhIHdhcyBhZGRlZC4KICovCnN0YXRpYyBJTlQgU0hBRERfY3JlYXRlX2FkZF9tcnVfZGF0YShIQU5ETEUgbXJ1aGFuZGxlLCBMUFNUUiBkb2NfbmFtZSwgTFBTVFIgbmV3X2xua19uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgYnVmZmVyLCBJTlQgKmxlbikKewogICAgTFBTVFIgcHRyOwogICAgSU5UIHdsZW47CgogICAgLypGSVhNRTogRG9jdW1lbnQ6CiAgICAgKiAgUmVjZW50RG9jcyBNUlUgZGF0YSBzdHJ1Y3R1cmUgc2VlbXMgdG8gYmU6CiAgICAgKiAgICArMGggICBkb2N1bWVudCBmaWxlIG5hbWUgdy8gdGVybWluYXRpbmcgMGgKICAgICAqICAgICtuaCAgIHNob3J0IGludCB3LyBzaXplIG9mIHJlbWFpbmluZwogICAgICogICAgK24rMmggMDJoIDMwaCwgb3IgMDFoIDMwaCwgb3IgMDBoIDMwaCAgLSAgdW5rbm93bgogICAgICogICAgK24rNGggMTAgYnl0ZXMgemVyb3MgIC0gICB1bmtub3duCiAgICAgKiAgICArbitlaCBzaG9ydGN1dCBmaWxlIG5hbWUgdy8gdGVybWluYXRpbmcgMGgKICAgICAqICAgICtuK2UrbmggMyB6ZXJvIGJ5dGVzICAtICB1bmtub3duCiAgICAgKi8KCiAgICAvKiBDcmVhdGUgdGhlIE1SVSBkYXRhIHN0cnVjdHVyZSBmb3IgIlJlY2VudERvY3MiCgkgKi8KICAgIHB0ciA9IGJ1ZmZlcjsKICAgIGxzdHJjcHlBKHB0ciwgZG9jX25hbWUpOwogICAgcHRyICs9IChsc3RybGVuQShidWZmZXIpICsgMSk7CiAgICB3bGVuPSBsc3RybGVuQShuZXdfbG5rX25hbWUpICsgMSArIDEyOwogICAgKigoc2hvcnQgaW50KilwdHIpID0gd2xlbjsKICAgIHB0ciArPSAyOyAgIC8qIHN0ZXAgcGFzdCB0aGUgbGVuZ3RoICovCiAgICAqKHB0cisrKSA9IDB4MzA7ICAvKiB1bmtub3duIHJlYXNvbiAqLwogICAgKihwdHIrKykgPSAwOyAgICAgLyogdW5rbm93biwgYnV0IGNhbiBiZSAweDAwLCAweDAxLCAweDAyICovCiAgICBtZW1zZXQocHRyLCAwLCAxMCk7CiAgICBwdHIgKz0gMTA7CiAgICBsc3RyY3B5QShwdHIsIG5ld19sbmtfbmFtZSk7CiAgICBwdHIgKz0gKGxzdHJsZW5BKG5ld19sbmtfbmFtZSkgKyAxKTsKICAgIG1lbXNldChwdHIsIDAsIDMpOwogICAgcHRyICs9IDM7CiAgICAqbGVuID0gcHRyIC0gYnVmZmVyOwoKICAgIC8qIEFkZCB0aGUgbmV3IGVudHJ5IGludG8gdGhlIE1SVSBsaXN0CiAgICAgKi8KICAgIHJldHVybiBBZGRNUlVEYXRhKG1ydWhhbmRsZSwgKExQQ1ZPSUQpYnVmZmVyLCAqbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBZGRUb1JlY2VudERvY3MJCQkJW1NIRUxMMzIuQF0KICoKICogUEFSQU1FVEVSUwogKiAgIHVGbGFncyAgW0lOXSBTSEFSRF9QQVRIIG9yIFNIQVJEX1BJREwKICogICBwdiAgICAgIFtJTl0gc3RyaW5nIG9yIHBpZGwsIE5VTEwgY2xlYXJzIHRoZSBsaXN0CiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBuYW1lCiAqCiAqIEZJWE1FOiA/PyBNU0ROIHNob3dzIHRoaXMgYXMgYSBWT0lECiAqLwpEV09SRCBXSU5BUEkgU0hBZGRUb1JlY2VudERvY3MgKFVJTlQgdUZsYWdzLExQQ1ZPSUQgcHYpCnsKLyogSWYgbGlzdCBpcyBhIHN0cmluZyBsaXN0IGxwZm5Db21wYXJlIGhhcyB0aGUgZm9sbG93aW5nIHByb3RvdHlwZQogKiBpbnQgQ0FMTEJBQ0sgTVJVQ29tcGFyZVN0cmluZyhMUENTVFIgczEsIExQQ1NUUiBzMikKICogZm9yIGJpbmFyeSBsaXN0cyB0aGUgcHJvdG90eXBlIGlzCiAqIGludCBDQUxMQkFDSyBNUlVDb21wYXJlQmluYXJ5KExQQ1ZPSUQgZGF0YTEsIExQQ1ZPSUQgZGF0YTIsIERXT1JEIGNiRGF0YSkKICogd2hlcmUgY2JEYXRhIGlzIHRoZSBuby4gb2YgYnl0ZXMgdG8gY29tcGFyZS4KICogTmVlZCB0byBjaGVjayB3aGF0IHJldHVybiB2YWx1ZSBtZWFucyBpZGVudGljYWwgLSAwPwogKi8KCgogICAgVUlOVCBvbGRlcnJvcm1vZGU7CiAgICBIS0VZIEhDVWJhc2VrZXk7CiAgICBDSEFSIGRvY19uYW1lW01BWF9QQVRIXTsKICAgIENIQVIgbGlua19kaXJbTUFYX1BBVEhdOwogICAgQ0hBUiBuZXdfbG5rX2ZpbGVwYXRoW01BWF9QQVRIXTsKICAgIENIQVIgbmV3X2xua19uYW1lW01BWF9QQVRIXTsKICAgIElNYWxsb2MgKnBwTTsKICAgIExQSVRFTUlETElTVCBwaWRsOwogICAgSFdORCBod25kID0gMDsgICAgICAgLyogRklYTUU6ICBnZXQgcmVhbCB3aW5kb3cgaGFuZGxlICovCiAgICBJTlQgcmV0OwogICAgRFdPUkQgZGF0YVs2NF0sIGRhdGFsZW4sIHR5cGU7CgogICAgLypGSVhNRTogRG9jdW1lbnQ6CiAgICAgKiAgUmVjZW50RG9jcyBNUlUgZGF0YSBzdHJ1Y3R1cmUgc2VlbXMgdG8gYmU6CiAgICAgKiAgICArMGggICBkb2N1bWVudCBmaWxlIG5hbWUgdy8gdGVybWluYXRpbmcgMGgKICAgICAqICAgICtuaCAgIHNob3J0IGludCB3LyBzaXplIG9mIHJlbWFpbmluZwogICAgICogICAgK24rMmggMDJoIDMwaCwgb3IgMDFoIDMwaCwgb3IgMDBoIDMwaCAgLSAgdW5rbm93bgogICAgICogICAgK24rNGggMTAgYnl0ZXMgemVyb3MgIC0gICB1bmtub3duCiAgICAgKiAgICArbitlaCBzaG9ydGN1dCBmaWxlIG5hbWUgdy8gdGVybWluYXRpbmcgMGgKICAgICAqICAgICtuK2UrbmggMyB6ZXJvIGJ5dGVzICAtICB1bmtub3duCiAgICAgKi8KCiAgICAvKiBTZWUgaWYgd2UgbmVlZCB0byBkbyBhbnl0aGluZy4KICAgICAqLwogICAgZGF0YWxlbiA9IDY0OwogICAgcmV0PVNIQUREX2dldF9wb2xpY3koICJOb1JlY2VudERvY3NIaXN0b3J5IiwgJnR5cGUsICZkYXRhLCAmZGF0YWxlbik7CiAgICBpZiAoKHJldCA+IDApICYmIChyZXQgIT0gRVJST1JfRklMRV9OT1RfRk9VTkQpKSB7CglFUlIoIkVycm9yICVkIGdldHRpbmcgcG9saWN5IFwiTm9SZWNlbnREb2NzSGlzdG9yeVwiXG4iLCByZXQpOwoJcmV0dXJuIDA7CiAgICB9CiAgICBpZiAocmV0ID09IEVSUk9SX1NVQ0NFU1MpIHsKCWlmICghKCAodHlwZSA9PSBSRUdfRFdPUkQpIHx8CgkgICAgICAgKCh0eXBlID09IFJFR19CSU5BUlkpICYmIChkYXRhbGVuID09IDQpKSApKSB7CgkgICAgRVJSKCJFcnJvciBwb2xpY3kgZGF0YSBmb3IgXCJOb1JlY2VudERvY3NIaXN0b3J5XCIgbm90IGZvcm1hdGVkIGNvcnJlY3RseSwgdHlwZT0lbGQsIGxlbj0lbGRcbiIsCgkJdHlwZSwgZGF0YWxlbik7CgkgICAgcmV0dXJuIDA7Cgl9CgoJVFJBQ0UoInBvbGljeSB2YWx1ZSBmb3IgTm9SZWNlbnREb2NzSGlzdG9yeSA9ICUwOGx4XG4iLCBkYXRhWzBdKTsKCS8qIG5vdyB0ZXN0IHRoZSBhY3R1YWwgcG9saWN5IHZhbHVlICovCglpZiAoIGRhdGFbMF0gIT0gMCkKCSAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKiBPcGVuIGtleSB0byB3aGVyZSB0aGUgbmVjZXNzYXJ5IGluZm8gaXMKICAgICAqLwogICAgLyogRklYTUU6IFRoaXMgc2hvdWxkIGJlIGRvbmUgZHVyaW5nIERMTCBQUk9DRVNTX0FUVEFDSCAob3IgVEhSRUFEX0FUVEFDSCkKICAgICAqICAgICAgICBhbmQgdGhlIGNsb3NlIHNob3VsZCBiZSBkb25lIGR1cmluZyB0aGUgX0RFVEFDSC4gVGhlIHJlc3VsdGluZwogICAgICogICAgICAgIGtleSBpcyBzdG9yZWQgaW4gdGhlIERMTCBnbG9iYWwgZGF0YS4KICAgICAqLwogICAgaWYgKFJlZ0NyZWF0ZUtleUV4QShIS0VZX0NVUlJFTlRfVVNFUiwKCQkJIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxFeHBsb3JlciIsCgkJCTAsIDAsIDAsIEtFWV9SRUFELCAwLCAmSENVYmFzZWtleSwgMCkpIHsKCUVSUigiRmFpbGVkIHRvIGNyZWF0ZSAnU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXEV4cGxvcmVyJ1xuIik7CglyZXR1cm4gMDsKICAgIH0KCiAgICAvKiBHZXQgcGF0aCB0byB1c2VyJ3MgIlJlY2VudCIgZGlyZWN0b3J5CiAgICAgKi8KICAgIGlmKFNVQ0NFRURFRChTSEdldE1hbGxvYygmcHBNKSkpIHsKCWlmIChTVUNDRUVERUQoU0hHZXRTcGVjaWFsRm9sZGVyTG9jYXRpb24oaHduZCwgQ1NJRExfUkVDRU5ULAoJCQkJCQkgJnBpZGwpKSkgewoJICAgIFNIR2V0UGF0aEZyb21JRExpc3RBKHBpZGwsIGxpbmtfZGlyKTsKCSAgICBJTWFsbG9jX0ZyZWUocHBNLCBwaWRsKTsKCX0KCWVsc2UgewoJICAgIC8qIHNlcmlvdXMgaXNzdWVzICovCgkgICAgbGlua19kaXJbMF0gPSAwOwoJICAgIEVSUigic2VyaW91cyBpc3N1ZXMgMVxuIik7Cgl9CglJTWFsbG9jX1JlbGVhc2UocHBNKTsKICAgIH0KICAgIGVsc2UgewoJLyogc2VyaW91cyBpc3N1ZXMgKi8KCWxpbmtfZGlyWzBdID0gMDsKCUVSUigic2VyaW91cyBpc3N1ZXMgMlxuIik7CiAgICB9CiAgICBUUkFDRSgiVXNlcnMgUmVjZW50IGRpciAlc1xuIiwgbGlua19kaXIpOwoKICAgIC8qIElmIG5vIGlucHV0LCB0aGVuIGdvIGNsZWFyIHRoZSBsaXN0cyAqLwogICAgaWYgKCFwdikgewoJLyogY2xlYXIgdXNlcidzIFJlY2VudCBkaXIKCSAqLwoKCS8qIEZJWE1FOiBkZWxldGUgYWxsIGZpbGVzIGluICJsaW5rX2RpciIKCSAqCgkgKiB3aGlsZSggbW9yZSBmaWxlcyApIHsKCSAqICAgIGxzdHJjcHlBKG9sZF9sbmtfbmFtZSwgbGlua19kaXIpOwoJICogICAgUGF0aEFwcGVuZEEob2xkX2xua19uYW1lLCBmaWxlbmFtKTsKCSAqICAgIERlbGV0ZUZpbGVBKG9sZF9sbmtfbmFtZSk7CgkgKiB9CgkgKi8KCUZJWE1FKCJzaG91bGQgZGVsZXRlIGFsbCBmaWxlcyBpbiAlc1xcIFxuIiwgbGlua19kaXIpOwoKCS8qIGNsZWFyIE1SVSBsaXN0CgkgKi8KCS8qIE1TIEJ1ZyA/PyB2NC43Mi4zNjEyLjE3MDAgb2Ygc2hlbGwzMiBkb2VzIHRoZSBkZWxldGUgYWdhaW5zdAoJICogIEhLRVlfTE9DQUxfTUFDSElORSB2ZXJzaW9uIG9mIC4uLkN1cnJlbnRWZXJzaW9uXEV4cGxvcmVyCgkgKiAgYW5kIG5hdHVyYWxseSBpdCBmYWlscyB3LyByYz0yLiBJdCBzaG91bGQgZG8gaXQgYWdhaW5zdAoJICogIEhLRVlfQ1VSUkVOVF9VU0VSIHdoaWNoIGlzIHdoZXJlIGl0IGlzIHN0b3JlZCwgYW5kIHdoZXJlCgkgKiAgdGhlIE1SVSByb3V0aW5lcyBleHBlY3QgaXQhISEhCgkgKi8KCVJlZ0RlbGV0ZUtleUEoSENVYmFzZWtleSwgIlJlY2VudERvY3MiKTsKCVJlZ0Nsb3NlS2V5KEhDVWJhc2VrZXkpOwoJcmV0dXJuIDA7CiAgICB9CgogICAgLyogSGF2ZSBkYXRhIHRvIGFkZCwgdGhlIGpvYnMgdG8gYmUgZG9uZToKICAgICAqICAgMS4gQWRkIGRvY3VtZW50IHRvIE1SVSBsaXN0IGluIHJlZ2lzdHJ5ICJIS0NVXFNvZnR3YXJlXAogICAgICogICAgICBNaWNyb3NvZnRcV2luZG93c1xDdXJyZW50VmVyc2lvblxFeHBsb3JlclxSZWNlbnREb2NzIi4KICAgICAqICAgMi4gQWRkIHNob3J0Y3V0IHRvIGRvY3VtZW50IGluIHRoZSB1c2VyJ3MgUmVjZW50IGRpcmVjdG9yeQogICAgICogICAgICAoQ1NJRExfUkVDRU5UKS4KICAgICAqICAgMy4gQWRkIHNob3J0Y3V0IHRvIFN0YXJ0IG1lbnUncyBEb2N1bWVudHMgc3VibWVudS4KICAgICAqLwoKICAgIC8qIEdldCB0aGUgcHVyZSBkb2N1bWVudCBuYW1lIGZyb20gdGhlIGlucHV0CiAgICAgKi8KICAgIGlmICh1RmxhZ3MgJiBTSEFSRF9QSURMKSB7CglTSEdldFBhdGhGcm9tSURMaXN0QSgoTFBDSVRFTUlETElTVCkgcHYsIGRvY19uYW1lKTsKICAgIH0KICAgIGVsc2UgewoJbHN0cmNweUEoZG9jX25hbWUsIChMUFNUUikgcHYpOwogICAgfQogICAgVFJBQ0UoImZ1bGwgZG9jdW1lbnQgbmFtZSAlc1xuIiwgZG9jX25hbWUpOwogICAgUGF0aFN0cmlwUGF0aEEoZG9jX25hbWUpOwogICAgVFJBQ0UoInN0cmlwcGVkIGRvY3VtZW50IG5hbWUgJXNcbiIsIGRvY19uYW1lKTsKCgogICAgLyogKioqICBKT0IgMTogVXBkYXRlIHJlZ2lzdHJ5IGZvciAuLi5cRXhwbG9yZXJcUmVjZW50RG9jcyBsaXN0ICAqKiogKi8KCiAgICB7ICAvKiBvbiBpbnB1dCBuZWVkczoKCSogICAgICBkb2NfbmFtZSAgICAtICBwdXJlIGZpbGUtc3BlYywgbm8gcGF0aAoJKiAgICAgIGxpbmtfZGlyICAgIC0gIHBhdGggdG8gdGhlIHVzZXIncyBSZWNlbnQgZGlyZWN0b3J5CgkqICAgICAgSENVYmFzZWtleSAgLSAga2V5IG9mIC4uLldpbmRvd3NcQ3VycmVudFZlcnNpb25cRXhwbG9yZXIiIG5vZGUKCSogY3JlYXRlczoKCSogICAgICBuZXdfbG5rX25hbWUtICBwdXJlIGZpbGUtc3BlYywgbm8gcGF0aCBmb3IgbmV3IC5sbmsgZmlsZQoJKiAgICAgIG5ld19sbmtfZmlsZXBhdGgKCSogICAgICAgICAgICAgICAgICAtICBwYXRoIGFuZCBmaWxlIG5hbWUgb2YgbmV3IC5sbmsgZmlsZQoJKi8KCUNSRUFURU1SVUxJU1RBIG15bXJ1OwoJSEFORExFIG1ydWhhbmRsZTsKCUlOVCBsZW4sIHBvcywgYnVmdXNlZCwgZXJyOwoJSU5UIGk7CglEV09SRCBhdHRyOwoJQ0hBUiBidWZmZXJbMjA0OF07CglDSEFSICpwdHI7CglDSEFSIG9sZF9sbmtfbmFtZVtNQVhfUEFUSF07CglzaG9ydCBpbnQgc2xlbjsKCglteW1ydS5jYlNpemUgPSBzaXplb2YoQ1JFQVRFTVJVTElTVEEpOwoJbXltcnUubk1heEl0ZW1zID0gMTU7CglteW1ydS5kd0ZsYWdzID0gTVJVRl9CSU5BUllfTElTVCB8IE1SVUZfREVMQVlFRF9TQVZFOwoJbXltcnUuaEtleSA9IEhDVWJhc2VrZXk7CglteW1ydS5scHN6U3ViS2V5ID0gIlJlY2VudERvY3MiOwoJbXltcnUubHBmbkNvbXBhcmUgPSAmU0hBRERfY29tcGFyZV9tcnU7CgltcnVoYW5kbGUgPSBDcmVhdGVNUlVMaXN0QSgmbXltcnUpOwoJaWYgKCFtcnVoYW5kbGUpIHsKCSAgICAvKiBNUlUgZmFpbGVkICovCgkgICAgRVJSKCJNUlUgcHJvY2Vzc2luZyBmYWlsZWQsIGhhbmRsZSB6ZXJvXG4iKTsKCSAgICBSZWdDbG9zZUtleShIQ1ViYXNla2V5KTsKCSAgICByZXR1cm4gMDsKCX0KCWxlbiA9IGxzdHJsZW5BKGRvY19uYW1lKTsKCXBvcyA9IEZpbmRNUlVEYXRhKG1ydWhhbmRsZSwgZG9jX25hbWUsIGxlbiwgMCk7CgoJLyogTm93IGdldCB0aGUgTVJVIGVudHJ5IHRoYXQgd2lsbCBiZSByZXBsYWNlZAoJICogYW5kIGRlbGV0ZSB0aGUgLmxuayBmaWxlIGZvciBpdAoJICovCglpZiAoKGJ1ZnVzZWQgPSBFbnVtTVJVTGlzdEEobXJ1aGFuZGxlLCAocG9zID09IC0xKSA/IDE0IDogcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIsIDIwNDgpKSAhPSAtMSkgewoJICAgIHB0ciA9IGJ1ZmZlcjsKCSAgICBwdHIgKz0gKGxzdHJsZW5BKGJ1ZmZlcikgKyAxKTsKCSAgICBzbGVuID0gKigoc2hvcnQgaW50KilwdHIpOwoJICAgIHB0ciArPSAyOyAgLyogc2tpcCB0aGUgbGVuZ3RoIGFyZWEgKi8KCSAgICBpZiAoYnVmdXNlZCA+PSBzbGVuICsgKHB0ci1idWZmZXIpKSB7CgkJLyogYnVmZmVyIHNpemUgbG9va3MgZ29vZCAqLwoJCXB0ciArPSAxMjsgLyogZ2V0IHRvIHN0cmluZyAqLwoJCWxlbiA9IGJ1ZnVzZWQgLSAocHRyLWJ1ZmZlcik7ICAvKiBnZXQgbGVuZ3RoIG9mIGJ1ZiByZW1haW5pbmcgKi8KCQlpZiAoKGxzdHJsZW5BKHB0cikgPiAwKSAmJiAobHN0cmxlbkEocHRyKSA8PSBsZW4tMSkpIHsKCQkgICAgLyogYXBwZWFycyB0byBiZSBnb29kIHN0cmluZyAqLwoJCSAgICBsc3RyY3B5QShvbGRfbG5rX25hbWUsIGxpbmtfZGlyKTsKCQkgICAgUGF0aEFwcGVuZEEob2xkX2xua19uYW1lLCBwdHIpOwoJCSAgICBpZiAoIURlbGV0ZUZpbGVBKG9sZF9sbmtfbmFtZSkpIHsKCQkJaWYgKChhdHRyID0gR2V0RmlsZUF0dHJpYnV0ZXNBKG9sZF9sbmtfbmFtZSkpID09IC0xKSB7CgkJCSAgICBpZiAoKGVyciA9IEdldExhc3RFcnJvcigpKSAhPSBFUlJPUl9GSUxFX05PVF9GT1VORCkgewoJCQkJRVJSKCJEZWxldGUgZm9yICVzIGZhaWxlZCwgZXJyPSVkLCBhdHRyPSUwOGx4XG4iLAoJCQkJICAgIG9sZF9sbmtfbmFtZSwgZXJyLCBhdHRyKTsKCQkJICAgIH0KCQkJICAgIGVsc2UgewoJCQkJVFJBQ0UoIm9sZCAubG5rIGZpbGUgJXMgZGlkIG5vdCBleGlzdFxuIiwKCQkJCSAgICAgIG9sZF9sbmtfbmFtZSk7CgkJCSAgICB9CgkJCX0KCQkJZWxzZSB7CgkJCSAgICBFUlIoIkRlbGV0ZSBmb3IgJXMgZmFpbGVkLCBhdHRyPSUwOGx4XG4iLAoJCQkJb2xkX2xua19uYW1lLCBhdHRyKTsKCQkJfQoJCSAgICB9CgkJICAgIGVsc2UgewoJCQlUUkFDRSgiZGVsZXRlZCBvbGQgLmxuayBmaWxlICVzXG4iLCBvbGRfbG5rX25hbWUpOwoJCSAgICB9CgkJfQoJICAgIH0KCX0KCgkvKiBDcmVhdGUgdXNhYmxlIC5sbmsgZmlsZSBuYW1lIGZvciB0aGUgIlJlY2VudCIgZGlyZWN0b3J5CgkgKi8KCXdzcHJpbnRmQShuZXdfbG5rX25hbWUsICIlcy5sbmsiLCBkb2NfbmFtZSk7Cglsc3RyY3B5QShuZXdfbG5rX2ZpbGVwYXRoLCBsaW5rX2Rpcik7CglQYXRoQXBwZW5kQShuZXdfbG5rX2ZpbGVwYXRoLCBuZXdfbG5rX25hbWUpOwoJaSA9IDE7CglvbGRlcnJvcm1vZGUgPSBTZXRFcnJvck1vZGUoU0VNX0ZBSUxDUklUSUNBTEVSUk9SUyk7Cgl3aGlsZSAoR2V0RmlsZUF0dHJpYnV0ZXNBKG5ld19sbmtfZmlsZXBhdGgpICE9IC0xKSB7CgkgICAgaSsrOwoJICAgIHdzcHJpbnRmQShuZXdfbG5rX25hbWUsICIlcyAoJXUpLmxuayIsIGRvY19uYW1lLCBpKTsKCSAgICBsc3RyY3B5QShuZXdfbG5rX2ZpbGVwYXRoLCBsaW5rX2Rpcik7CgkgICAgUGF0aEFwcGVuZEEobmV3X2xua19maWxlcGF0aCwgbmV3X2xua19uYW1lKTsKCX0KCVNldEVycm9yTW9kZShvbGRlcnJvcm1vZGUpOwoJVFJBQ0UoIm5ldyBzaG9ydGN1dCB3aWxsIGJlICVzXG4iLCBuZXdfbG5rX2ZpbGVwYXRoKTsKCgkvKiBOb3cgYWRkIHRoZSBuZXcgTVJVIGVudHJ5IGFuZCBkYXRhCgkgKi8KCXBvcyA9IFNIQUREX2NyZWF0ZV9hZGRfbXJ1X2RhdGEobXJ1aGFuZGxlLCBkb2NfbmFtZSwgbmV3X2xua19uYW1lLAoJCQkJCWJ1ZmZlciwgJmxlbik7CglGcmVlTVJVTGlzdChtcnVoYW5kbGUpOwoJVFJBQ0UoIlVwZGF0ZWQgTVJVIGxpc3QsIG5ldyBkb2MgaXMgcG9zaXRpb24gJWRcbiIsIHBvcyk7CiAgICB9CgogICAgLyogKioqICBKT0IgMjogQ3JlYXRlIHNob3J0Y3V0IGluIHVzZXIncyAiUmVjZW50IiBkaXJlY3RvcnkgICoqKiAqLwoKICAgIHsgIC8qIG9uIGlucHV0IG5lZWRzOgoJKiAgICAgIGRvY19uYW1lICAgIC0gIHB1cmUgZmlsZS1zcGVjLCBubyBwYXRoCgkqICAgICAgbmV3X2xua19maWxlcGF0aAoJKiAgICAgICAgICAgICAgICAgIC0gIHBhdGggYW5kIGZpbGUgbmFtZSBvZiBuZXcgLmxuayBmaWxlCiAJKiAgICAgIHVGbGFnc1tpbl0gIC0gIGZsYWdzIG9uIGNhbGwgdG8gU0hBZGRUb1JlY2VudERvY3MKCSogICAgICBwdltpbl0gICAgICAtICBkb2N1bWVudCBwYXRoL3BpZGwgb24gY2FsbCB0byBTSEFkZFRvUmVjZW50RG9jcwoJKi8KCUlTaGVsbExpbmtBICpwc2wgPSBOVUxMOwoJSVBlcnNpc3RGaWxlICpwUGYgPSBOVUxMOwoJSFJFU1VMVCBocmVzOwoJQ0hBUiBkZXNjW01BWF9QQVRIXTsKCVdDSEFSIHdpZGVsaW5rW01BWF9QQVRIXTsKCglDb0luaXRpYWxpemUoMCk7CgoJaHJlcyA9IENvQ3JlYXRlSW5zdGFuY2UoICZDTFNJRF9TaGVsbExpbmssCgkJCQkgTlVMTCwKCQkJCSBDTFNDVFhfSU5QUk9DX1NFUlZFUiwKCQkJCSAmSUlEX0lTaGVsbExpbmtBLAoJCQkJIChMUFZPSUQgKSZwc2wpOwoJaWYoU1VDQ0VFREVEKGhyZXMpKSB7CgoJICAgIGhyZXMgPSBJU2hlbGxMaW5rQV9RdWVyeUludGVyZmFjZShwc2wsICZJSURfSVBlcnNpc3RGaWxlLAoJCQkJCSAgICAgKExQVk9JRCAqKSZwUGYpOwoJICAgIGlmKEZBSUxFRChocmVzKSkgewoJCS8qIGJvbWJlZCAqLwoJCUVSUigiZmFpbGVkIFF1ZXJ5SW50ZXJmYWNlIGZvciBJUGVyc2lzdEZpbGUgJTA4bHhcbiIsIGhyZXMpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgoJICAgIC8qIFNldCB0aGUgZG9jdW1lbnQgcGF0aCBvciBwaWRsICovCgkgICAgaWYgKHVGbGFncyAmIFNIQVJEX1BJREwpIHsKCQlocmVzID0gSVNoZWxsTGlua0FfU2V0SURMaXN0KHBzbCwgKExQQ0lURU1JRExJU1QpIHB2KTsKCSAgICB9IGVsc2UgewoJCWhyZXMgPSBJU2hlbGxMaW5rQV9TZXRQYXRoKHBzbCwgKExQQ1NUUikgcHYpOwoJICAgIH0KCSAgICBpZihGQUlMRUQoaHJlcykpIHsKCQkvKiBib21iZWQgKi8KCQlFUlIoImZhaWxlZCBTZXR7SURMaXN0fFBhdGh9ICUwOGx4XG4iLCBocmVzKTsKCQlnb3RvIGZhaWw7CgkgICAgfQoKCSAgICBsc3RyY3B5QShkZXNjLCAiU2hvcnRjdXQgdG8gIik7CgkgICAgbHN0cmNhdEEoZGVzYywgZG9jX25hbWUpOwoJICAgIGhyZXMgPSBJU2hlbGxMaW5rQV9TZXREZXNjcmlwdGlvbihwc2wsIGRlc2MpOwoJICAgIGlmKEZBSUxFRChocmVzKSkgewoJCS8qIGJvbWJlZCAqLwoJCUVSUigiZmFpbGVkIFNldERlc2NyaXB0aW9uICUwOGx4XG4iLCBocmVzKTsKCQlnb3RvIGZhaWw7CgkgICAgfQoKCSAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgbmV3X2xua19maWxlcGF0aCwgLTEsCgkJCQl3aWRlbGluaywgTUFYX1BBVEgpOwoJICAgIC8qIGNyZWF0ZSB0aGUgc2hvcnQgY3V0ICovCgkgICAgaHJlcyA9IElQZXJzaXN0RmlsZV9TYXZlKHBQZiwgd2lkZWxpbmssIFRSVUUpOwoJICAgIGlmKEZBSUxFRChocmVzKSkgewoJCS8qIGJvbWJlZCAqLwoJCUVSUigiZmFpbGVkIElQZXJzaXN0RmlsZTo6U2F2ZSAlMDhseFxuIiwgaHJlcyk7CgkJSVBlcnNpc3RGaWxlX1JlbGVhc2UocFBmKTsKCQlJU2hlbGxMaW5rQV9SZWxlYXNlKHBzbCk7CgkJZ290byBmYWlsOwoJICAgIH0KCSAgICBocmVzID0gSVBlcnNpc3RGaWxlX1NhdmVDb21wbGV0ZWQocFBmLCB3aWRlbGluayk7CgkgICAgSVBlcnNpc3RGaWxlX1JlbGVhc2UocFBmKTsKCSAgICBJU2hlbGxMaW5rQV9SZWxlYXNlKHBzbCk7CgkgICAgVFJBQ0UoInNob3J0Y3V0ICVzIGhhcyBiZWVuIGNyZWF0ZWQsIHJlc3VsdD0lMDhseFxuIiwKCQkgIG5ld19sbmtfZmlsZXBhdGgsIGhyZXMpOwoJfQoJZWxzZSB7CgkgICAgRVJSKCJDb0NyZWF0ZUluc3RhbmNlIGZhaWxlZCwgaHJlcz0lMDhseFxuIiwgaHJlcyk7Cgl9CiAgICB9CgogZmFpbDoKICAgIENvVW5pbml0aWFsaXplKCk7CgogICAgLyogYWxsIGRvbmUgKi8KICAgIFJlZ0Nsb3NlS2V5KEhDVWJhc2VrZXkpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ3JlYXRlU2hlbGxGb2xkZXJWaWV3RXgJCQlbU0hFTEwzMi4xNzRdCiAqCiAqIE5PVEVTCiAqICBzZWUgSVNoZWxsRm9sZGVyOjpDcmVhdGVWaWV3T2JqZWN0CiAqLwpIUkVTVUxUIFdJTkFQSSBTSENyZWF0ZVNoZWxsRm9sZGVyVmlld0V4KAoJTFBDU0hFTExGT0xERVJWSUVXSU5GTyBwc3ZjYmksIC8qIFtpbl0gc2hlbGx0ZW1wbGF0ZSBzdHJ1Y3QgKi8KCUxQU0hFTExWSUVXKiBwcHYpICAgICAgICAgICAgICAvKiBbb3V0XSBJU2hlbGxWaWV3IHBvaW50ZXIgKi8KewoJSVNoZWxsVmlldyAqIHBzZjsKCUhSRVNVTFQgaFJlczsKCglUUkFDRSgic2Y9JXAgcGlkbD0lcCBjYj0lcCBtb2RlPTB4JTA4eCBwYXJtPTB4JTA4bHhcbiIsCgkgIHBzdmNiaS0+cHNoZiwgcHN2Y2JpLT5waWRsRm9sZGVyLCBwc3ZjYmktPmxwZm5DYWxsYmFjaywKCSAgcHN2Y2JpLT51Vmlld01vZGUsIHBzdmNiaS0+ZHdVc2VyKTsKCglwc2YgPSBJU2hlbGxWaWV3X0NvbnN0cnVjdG9yKHBzdmNiaS0+cHNoZik7CgoJaWYgKCFwc2YpCgkgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKCUlTaGVsbFZpZXdfQWRkUmVmKHBzZik7CgloUmVzID0gSVNoZWxsVmlld19RdWVyeUludGVyZmFjZShwc2YsICZJSURfSVNoZWxsVmlldywgKExQVk9JRCAqKXBwdik7CglJU2hlbGxWaWV3X1JlbGVhc2UocHNmKTsKCglyZXR1cm4gaFJlczsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgU0hXaW5IZWxwCQkJCQlbU0hFTEwzMi4xMjddCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFdpbkhlbHAgKERXT1JEIHYsIERXT1JEIHcsIERXT1JEIHgsIERXT1JEIHopCnsJRklYTUUoIjB4JTA4bHggMHglMDhseCAweCUwOGx4IDB4JTA4bHggc3R1YlxuIix2LHcseCx6KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBTSFJ1bkNvbnRyb2xQYW5lbCBbU0hFTEwzMi4xNjFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJ1bkNvbnRyb2xQYW5lbCAoRFdPUkQgeCwgRFdPUkQgeikKewlGSVhNRSgiMHglMDhseCAweCUwOGx4IHN0dWJcbiIseCx6KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgTFBVTktOT1dOIFNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlPTA7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2V0SW5zdGFuY2VFeHBsb3JlcgkJCVtTSEVMTDMyLjE3Nl0KICoKICogTk9URVMKICogIFNldHMgdGhlIGludGVyZmFjZQogKi8KSFJFU1VMVCBXSU5BUEkgU0hTZXRJbnN0YW5jZUV4cGxvcmVyIChMUFVOS05PV04gbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCVNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlID0gbHBVbmtub3duOwoJcmV0dXJuIChIUkVTVUxUKSBscFVua25vd247Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hHZXRJbnN0YW5jZUV4cGxvcmVyCQkJW1NIRUxMMzIuQF0KICoKICogTk9URVMKICogIGdldHMgdGhlIGludGVyZmFjZSBwb2ludGVyIG9mIHRoZSBleHBsb3JlciBhbmQgYSByZWZlcmVuY2UKICovCkhSRVNVTFQgV0lOQVBJIFNIR2V0SW5zdGFuY2VFeHBsb3JlciAoTFBVTktOT1dOICogbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCgkqbHBVbmtub3duID0gU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2U7CgoJaWYgKCFTSEVMTDMyX0lFeHBsb3JlckludGVyZmFjZSkKCSAgcmV0dXJuIEVfRkFJTDsKCglJVW5rbm93bl9BZGRSZWYoU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2UpOwoJcmV0dXJuIE5PRVJST1I7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGcmVlVW51c2VkTGlicmFyaWVzCQkJW1NIRUxMMzIuMTIzXQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgbmFtZQogKi8Kdm9pZCBXSU5BUEkgU0hGcmVlVW51c2VkTGlicmFyaWVzICh2b2lkKQp7CglGSVhNRSgic3R1YlxuIik7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX0F1dG9TY3JvbGwJCQkJW1NIRUxMMzIuMTI5XQogKgogKi8KRFdPUkQgV0lOQVBJIERBRF9BdXRvU2Nyb2xsKEhXTkQgaHduZCwgTFBTQ1JPTExTQU1QTEVTIHNhbXBsZXMsIExQUE9JTlQgcHQpCnsKICAgIEZJWE1FKCJod25kID0gJTA0eCAlcCAlcFxuIixod25kLHNhbXBsZXMscHQpOwogICAgcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX0RyYWdFbnRlcgkJCQlbU0hFTEwzMi4xMzBdCiAqCiAqLwpCT09MIFdJTkFQSSBEQURfRHJhZ0VudGVyKEhXTkQgaHduZCkKewogICAgRklYTUUoImh3bmQgPSAlMDR4XG4iLGh3bmQpOwogICAgcmV0dXJuIEZBTFNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9EcmFnRW50ZXJFeAkJCQlbU0hFTEwzMi4xMzFdCiAqCiAqLwpCT09MIFdJTkFQSSBEQURfRHJhZ0VudGVyRXgoSFdORCBod25kLCBQT0lOVCBwKQp7CiAgICBGSVhNRSgiaHduZCA9ICUwNHggKCVsZCwlbGQpXG4iLGh3bmQscC54LHAueSk7CiAgICByZXR1cm4gRkFMU0U7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX0RyYWdNb3ZlCQkJCVtTSEVMTDMyLjEzNF0KICoKICovCkJPT0wgV0lOQVBJIERBRF9EcmFnTW92ZShQT0lOVCBwKQp7CiAgICBGSVhNRSgiKCVsZCwlbGQpXG4iLHAueCxwLnkpOwogICAgcmV0dXJuIEZBTFNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9EcmFnTGVhdmUJCQkJW1NIRUxMMzIuMTMyXQogKgogKi8KQk9PTCBXSU5BUEkgREFEX0RyYWdMZWF2ZShWT0lEKQp7CiAgICBGSVhNRSgiXG4iKTsKICAgIHJldHVybiBGQUxTRTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfU2V0RHJhZ0ltYWdlCQkJCVtTSEVMTDMyLjEzNl0KICoKICogTk9URVMKICogIGV4cG9ydGVkIGJ5IG5hbWUKICovCkJPT0wgV0lOQVBJIERBRF9TZXREcmFnSW1hZ2UoCglISU1BR0VMSVNUIGhpbWxUcmFjaywKCUxQUE9JTlQgbHBwdCkKewoJRklYTUUoIiVwICVwIHN0dWJcbiIsaGltbFRyYWNrLCBscHB0KTsKICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfU2hvd0RyYWdJbWFnZQkJCQlbU0hFTEwzMi4xMzddCiAqCiAqIE5PVEVTCiAqICBleHBvcnRlZCBieSBuYW1lCiAqLwpCT09MIFdJTkFQSSBEQURfU2hvd0RyYWdJbWFnZShCT09MIGJTaG93KQp7CglGSVhNRSgiMHglMDh4IHN0dWJcbiIsYlNob3cpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVhZENhYmluZXRTdGF0ZQkJCQlbU0hFTEwzMi42NTFdIE5UIDQuMAogKgogKi8KSFJFU1VMVCBXSU5BUEkgUmVhZENhYmluZXRTdGF0ZShEV09SRCB1LCBEV09SRCB2KQp7CUZJWE1FKCIweCUwNGx4IDB4JTA0bHggc3R1YlxuIix1LHYpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogV3JpdGVDYWJpbmV0U3RhdGUJCQkJW1NIRUxMMzIuNjUyXSBOVCA0LjAKICoKICovCkhSRVNVTFQgV0lOQVBJIFdyaXRlQ2FiaW5ldFN0YXRlKERXT1JEIHUpCnsJRklYTUUoIjB4JTA0bHggc3R1YlxuIix1KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEZpbGVJY29uSW5pdCAJCQkJW1NIRUxMMzIuNjYwXQogKgogKi8KQk9PTCBXSU5BUEkgRmlsZUljb25Jbml0KEJPT0wgYkZ1bGxJbml0KQp7CUZJWE1FKCIoJXMpXG4iLCBiRnVsbEluaXQgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElzVXNlckFkbWluCQkJCQlbU0hFTEwzMi42ODBdIE5UIDQuMAogKgogKi8KSFJFU1VMVCBXSU5BUEkgSXNVc2VyQWRtaW4odm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBbGxvY1NoYXJlZAkJCQlbU0hFTEwzMi41MjBdCiAqCiAqIE5PVEVTCiAqICBwYXJhbWV0ZXIxIGlzIHJldHVybiB2YWx1ZSBmcm9tIEhlYXBBbGxvYwogKiAgcGFyYW1ldGVyMiBpcyBlcXVhbCB0byB0aGUgc2l6ZSBhbGxvY2F0ZWQgd2l0aCBIZWFwQWxsb2MKICogIHBhcmFtZXRlcjMgaXMgcmV0dXJuIHZhbHVlIGZyb20gR2V0Q3VycmVudFByb2Nlc3NJZAogKgogKiAgdGhlIHJldHVybiB2YWx1ZSBpcyBwb3N0ZWQgYXMgbFBhcmFtIHdpdGggMHg0MDIgKFdNX1VTRVIrMikgdG8gc29tZXdoZXJlCiAqICBXTV9VU0VSKzIgY291bGQgYmUgdGhlIHVuZG9jdW1lbnRlZCBDV01fU0VUUEFUSAogKiAgdGhlIGFsbG9jYXRlZCBtZW1vcnkgY29udGFpbnMgYSBwaWRsCiAqLwpIR0xPQkFMIFdJTkFQSSBTSEFsbG9jU2hhcmVkKExQVk9JRCBwc3JjLCBEV09SRCBzaXplLCBEV09SRCBwcm9jSUQpCnsJSEdMT0JBTCBobWVtOwoJTFBWT0lEIHBtZW07CgoJVFJBQ0UoInB0cj0lcCBzaXplPTB4JTA0bHggcHJvY0lEPTB4JTA0bHhcbiIscHNyYyxzaXplLHByb2NJRCk7CglobWVtID0gR2xvYmFsQWxsb2MoR01FTV9GSVhFRCwgc2l6ZSk7CglpZiAoIWhtZW0pCgkgIHJldHVybiAwOwoKCXBtZW0gPSAgR2xvYmFsTG9jayAoaG1lbSk7CgoJaWYgKCEgcG1lbSkKCSAgcmV0dXJuIDA7CgoJbWVtY3B5IChwbWVtLCBwc3JjLCBzaXplKTsKCUdsb2JhbFVubG9jayhobWVtKTsKCXJldHVybiBobWVtOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNITG9ja1NoYXJlZAkJCQkJW1NIRUxMMzIuNTIxXQogKgogKiBOT1RFUwogKiAgcGFyYW1ldGVyMSBpcyByZXR1cm4gdmFsdWUgZnJvbSBTSEFsbG9jU2hhcmVkCiAqICBwYXJhbWV0ZXIyIGlzIHJldHVybiB2YWx1ZSBmcm9tIEdldEN1cnJlbnRQcm9jZXNzSWQKICogIHRoZSByZWNlaXZlciBvZiAoV01fVVNFUisyKSB0cmllcyB0byBsb2NrIHRoZSBIQU5ETEUgKD8pCiAqICB0aGUgcmV0dXJuIHZhbHVlIHNlZW1zIHRvIGJlIGEgbWVtb3J5IGFkZHJlc3MKICovCkxQVk9JRCBXSU5BUEkgU0hMb2NrU2hhcmVkKEhBTkRMRSBobWVtLCBEV09SRCBwcm9jSUQpCnsJVFJBQ0UoImhhbmRsZT0weCUwNHggcHJvY0lEPTB4JTA0bHhcbiIsaG1lbSxwcm9jSUQpOwoJcmV0dXJuIEdsb2JhbExvY2soaG1lbSk7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hVbmxvY2tTaGFyZWQJCQkJW1NIRUxMMzIuNTIyXQogKgogKiBOT1RFUwogKiAgcGFyYW1ldGVyMSBpcyByZXR1cm4gdmFsdWUgZnJvbSBTSExvY2tTaGFyZWQKICovCkJPT0wgV0lOQVBJIFNIVW5sb2NrU2hhcmVkKExQVk9JRCBwdikKewoJVFJBQ0UoIiVwXG4iLHB2KTsKCXJldHVybiBHbG9iYWxVbmxvY2soKEhBTkRMRSlwdik7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGcmVlU2hhcmVkCQkJCQlbU0hFTEwzMi41MjNdCiAqCiAqIE5PVEVTCiAqICBwYXJhbWV0ZXIxIGlzIHJldHVybiB2YWx1ZSBmcm9tIFNIQWxsb2NTaGFyZWQKICogIHBhcmFtZXRlcjIgaXMgcmV0dXJuIHZhbHVlIGZyb20gR2V0Q3VycmVudFByb2Nlc3NJZAogKi8KQk9PTCBXSU5BUEkgU0hGcmVlU2hhcmVkKAoJSEFORExFIGhNZW0sCglEV09SRCBwaWQpCnsKCVRSQUNFKCJoYW5kbGU9MHglMDR4IDB4JTA0bHhcbiIsaE1lbSxwaWQpOwoJcmV0dXJuIEdsb2JhbEZyZWUoaE1lbSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNldEFwcFN0YXJ0aW5nQ3Vyc29yCQkJCVtTSEVMTDMyLjk5XQogKi8KSFJFU1VMVCBXSU5BUEkgU2V0QXBwU3RhcnRpbmdDdXJzb3IoSFdORCB1LCBEV09SRCB2KQp7CUZJWE1FKCJod25kPTB4JTA0eCAweCUwNGx4IHN0dWJcbiIsdSx2ICk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSExvYWRPTEUJCQkJCVtTSEVMTDMyLjE1MV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNITG9hZE9MRShEV09SRCB1KQp7CUZJWE1FKCIweCUwNGx4IHN0dWJcbiIsdSk7CglyZXR1cm4gU19PSzsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEcml2ZVR5cGUJCQkJCVtTSEVMTDMyLjY0XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgRHJpdmVUeXBlKERXT1JEIHUpCnsJRklYTUUoIjB4JTA0bHggc3R1YlxuIix1KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQWJvcnRJbnZva2VDb21tYW5kCQkJCVtTSEVMTDMyLjE5OF0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIQWJvcnRJbnZva2VDb21tYW5kKHZvaWQpCnsJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIDE7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hPdXRPZk1lbW9yeU1lc3NhZ2VCb3gJCQlbU0hFTEwzMi4xMjZdCiAqCiAqLwppbnQgV0lOQVBJIFNIT3V0T2ZNZW1vcnlNZXNzYWdlQm94KAoJSFdORCBod25kT3duZXIsCglMUENTVFIgbHBDYXB0aW9uLAoJVUlOVCB1VHlwZSkKewoJRklYTUUoIjB4JTA0eCAlcyAweCUwOHggc3R1YlxuIixod25kT3duZXIsIGxwQ2FwdGlvbiwgdVR5cGUpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGbHVzaENsaXBib2FyZAkJCQlbU0hFTEwzMi4xMjFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEZsdXNoQ2xpcGJvYXJkKHZvaWQpCnsJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIDE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIV2FpdEZvckZpbGVUb09wZW4JCQkJW1NIRUxMMzIuOTddCiAqCiAqLwpCT09MIFdJTkFQSSBTSFdhaXRGb3JGaWxlVG9PcGVuKAoJTFBDSVRFTUlETElTVCBwaWRsLAoJRFdPUkQgZHdGbGFncywKCURXT1JEIGR3VGltZW91dCkKewoJRklYTUUoIiVwIDB4JTA4bHggMHglMDhseCBzdHViXG4iLCBwaWRsLCBkd0ZsYWdzLCBkd1RpbWVvdXQpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJQAkJCQlbU0hFTEwzMi42NTRdCiAqCiAqIE5PVEVTOiBmaXJzdCBwYXJhbWV0ZXIgc2VlbXMgdG8gYmUgYSBwb2ludGVyIChzYW1lIGFzIHBhc3NlZCB0byBXcml0ZUNhYmluZXRTdGF0ZSkKICogc2Vjb25kIG9uZSBjb3VsZCBiZSBhIHNpemUgKDB4MGMpLiBUaGUgc2l6ZSBpcyB0aGUgc2FtZSBhcyB0aGUgc3RydWN0dXJlIHNhdmVkIHRvCiAqIEhDVVxTb2Z0d2FyZVxNaWNyb3NvZnRcV2luZG93c1xDdXJyZW50VmVyc2lvblxFeHBsb3JlclxDYWJpbmV0U3RhdGUKICogSSdtIChqcykgZ3Vlc3Npbmc6IHRoaXMgb25lIGlzIGp1c3QgUmVhZENhYmluZXRTdGF0ZSA7LSkKICovCkhSRVNVTFQgV0lOQVBJIHNoZWxsMzJfNjU0IChEV09SRCB4LCBEV09SRCB5KQp7CUZJWE1FKCIweCUwOGx4IDB4JTA4bHggc3R1YlxuIix4LHkpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUkxCdWlsZExpc3RPZlBhdGhzCQkJW1NIRUxMMzIuMTQ2XQogKgogKiBOT1RFUwogKiAgIGJ1aWxkcyBhIERQQQogKi8KRFdPUkQgV0lOQVBJIFJMQnVpbGRMaXN0T2ZQYXRocyAodm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVNIVmFsaWRhdGVVTkMJCQkJW1NIRUxMMzIuMTczXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hWYWxpZGF0ZVVOQyAoRFdPUkQgeCwgRFdPUkQgeSwgRFdPUkQgeikKewoJRklYTUUoIjB4JTA4bHggMHglMDhseCAweCUwOGx4IHN0dWJcbiIseCx5LHopOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJRG9FbnZpcm9ubWVudFN1YnN0QQkJCVtTSEVMTDMyLkBdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RBKExQU1RSIHgsIExQU1RSIHkpCnsKCUZJWE1FKCIoJXMsICVzKSBzdHViXG4iLCBkZWJ1Z3N0cl9hKHgpLCBkZWJ1Z3N0cl9hKHkpKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCURvRW52aXJvbm1lbnRTdWJzdFcJCQlbU0hFTEwzMi5AXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgRG9FbnZpcm9ubWVudFN1YnN0VyhMUFdTVFIgeCwgTFBXU1RSIHkpCnsKCUZJWE1FKCIoJXMsICVzKTogc3R1YlxuIiwgZGVidWdzdHJfdyh4KSwgZGVidWdzdHJfdyh5KSk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglEb0Vudmlyb25tZW50U3Vic3QJCQlbU0hFTEwzMi41M10KICoKICovCkhSRVNVTFQgV0lOQVBJIERvRW52aXJvbm1lbnRTdWJzdEFXKExQVk9JRCB4LCBMUFZPSUQgeSkKewoJaWYgKFNIRUxMX09zSXNVbmljb2RlKCkpCgkgIHJldHVybiBEb0Vudmlyb25tZW50U3Vic3RXKHgsIHkpOwoJcmV0dXJuIERvRW52aXJvbm1lbnRTdWJzdEEoeCwgeSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1NIRUxMMzIuMjQzXQogKgogKiBXaW45OCsgYnktb3JkaW5hbCByb3V0aW5lLiAgSW4gV2luOTggdGhpcyByb3V0aW5lIHJldHVybnMgemVybyBhbmQKICogZG9lcyBub3RoaW5nIGVsc2UuICBQb3NzaWJseSB0aGlzIGRvZXMgc29tZXRoaW5nIGluIE5UIG9yIFNIRUxMMzIgNS4wPwogKgogKi8KCkJPT0wgV0lOQVBJIHNoZWxsMzJfMjQzKERXT1JEIGEsIERXT1JEIGIpCnsKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hFTEwzMi43MTRdCiAqLwpEV09SRCBXSU5BUEkgU0hFTEwzMl83MTQoTFBWT0lEIHgpCnsKIAlGSVhNRSgiKCVzKXN0dWJcbiIsIGRlYnVnc3RyX3coeCkpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hBZGRGcm9tUHJvcFNoZWV0RXh0QXJyYXkJW1NIRUxMMzIuMTY3XQogKi8KRFdPUkQgV0lOQVBJIFNIQWRkRnJvbVByb3BTaGVldEV4dEFycmF5KERXT1JEIGEsIERXT1JEIGIsIERXT1JEIGMpCnsKIAlGSVhNRSgiKCUwOGx4LCUwOGx4LCUwOGx4KXN0dWJcbiIsIGEsIGIsIGMpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hDcmVhdGVQcm9wU2hlZXRFeHRBcnJheQlbU0hFTEwzMi4xNjhdCiAqLwpEV09SRCBXSU5BUEkgU0hDcmVhdGVQcm9wU2hlZXRFeHRBcnJheShEV09SRCBhLCBMUENTVFIgYiwgRFdPUkQgYykKewogCUZJWE1FKCIoJTA4bHgsJXMsJTA4bHgpc3R1YlxuIiwgYSwgZGVidWdzdHJfYShiKSwgYyk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSFJlcGxhY2VGcm9tUHJvcFNoZWV0RXh0QXJyYXkJW1NIRUxMMzIuMTcwXQogKi8KRFdPUkQgV0lOQVBJIFNIUmVwbGFjZUZyb21Qcm9wU2hlZXRFeHRBcnJheShEV09SRCBhLCBEV09SRCBiLCBEV09SRCBjLCBEV09SRCBkKQp7CiAJRklYTUUoIiglMDhseCwlMDhseCwlMDhseCwlMDhseClzdHViXG4iLCBhLCBiLCBjLCBkKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNIRGVzdHJveVByb3BTaGVldEV4dEFycmF5CVtTSEVMTDMyLjE2OV0KICovCkRXT1JEIFdJTkFQSSBTSERlc3Ryb3lQcm9wU2hlZXRFeHRBcnJheShEV09SRCBhKQp7CiAJRklYTUUoIiglMDhseClzdHViXG4iLCBhKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIENJRExEYXRhX0NyZWF0ZUZyb21JREFycmF5CVtTSEVMTDMyLjgzXQogKgogKiAgQ3JlYXRlIElEYXRhT2JqZWN0IGZyb20gUElETHM/PwogKi8KSFJFU1VMVCBXSU5BUEkgQ0lETERhdGFfQ3JlYXRlRnJvbUlEQXJyYXkoCglMUENJVEVNSURMSVNUIHBpZGxGb2xkZXIsCglEV09SRCBjcGlkbEZpbGVzLAoJTFBDSVRFTUlETElTVCAqbHBwaWRsRmlsZXMsCglMUERBVEFPQkpFQ1QgKnBwZGF0YU9iamVjdCkKewogICAgSU5UIGk7CiAgICBIV05EIGh3bmQgPSAwOyAgIC8qRklYTUU6IHdobyBzaG91bGQgYmUgaHduZCBvZiBvd25lcj8gc2V0IHRvIGRlc2t0b3AgKi8KCiAgICBUUkFDRSgiKCVwLCAlbGQsICVwLCAlcClcbiIsIHBpZGxGb2xkZXIsIGNwaWRsRmlsZXMsIGxwcGlkbEZpbGVzLCBwcGRhdGFPYmplY3QpOwogICAgaWYgKFRSQUNFX09OKHBpZGwpKQogICAgewoJcGR1bXAgKHBpZGxGb2xkZXIpOwoJZm9yIChpPTA7IGk8Y3BpZGxGaWxlczsgaSsrKSBwZHVtcCAobHBwaWRsRmlsZXNbaV0pOwogICAgfQogICAgKnBwZGF0YU9iamVjdCA9IElEYXRhT2JqZWN0X0NvbnN0cnVjdG9yKCBod25kLCBwaWRsRm9sZGVyLAoJCQkJCSAgICAgbHBwaWRsRmlsZXMsIGNwaWRsRmlsZXMpOwogICAgaWYgKCpwcGRhdGFPYmplY3QpIHJldHVybiBTX09LOwogICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ3JlYXRlU3RkRW51bUZtdEV0YwkJCVtTSEVMTDMyLjc0XQogKgogKiBOT1RFUwogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hDcmVhdGVTdGRFbnVtRm10RXRjKAoJRFdPUkQgY0Zvcm1hdHMsCgljb25zdCBGT1JNQVRFVEMgKmxwRm9ybWF0cywKCUxQRU5VTUZPUk1BVEVUQyAqcHBlbnVtRm9ybWF0ZXRjKQp7CglJRW51bUZPUk1BVEVUQyAqcGVmOwoJSFJFU1VMVCBoUmVzOwoJVFJBQ0UoImNmPSVsZCBmZT0lcCBwZWY9JXBcbiIsIGNGb3JtYXRzLCBscEZvcm1hdHMsIHBwZW51bUZvcm1hdGV0Yyk7CgoJcGVmID0gSUVudW1GT1JNQVRFVENfQ29uc3RydWN0b3IoY0Zvcm1hdHMsIGxwRm9ybWF0cyk7CglpZiAoIXBlZikKCSAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgoJSUVudW1GT1JNQVRFVENfQWRkUmVmKHBlZik7CgloUmVzID0gSUVudW1GT1JNQVRFVENfUXVlcnlJbnRlcmZhY2UocGVmLCAmSUlEX0lFbnVtRk9STUFURVRDLCAoTFBWT0lEKilwcGVudW1Gb3JtYXRldGMpOwoJSUVudW1GT1JNQVRFVENfUmVsZWFzZShwZWYpOwoKCXJldHVybiBoUmVzOwp9Cg==