LyoKICogVGhlIHBhcmFtZXRlcnMgb2YgbWFueSBmdW5jdGlvbnMgY2hhbmdlcyBiZXR3ZWVuIGRpZmZlcmVudCBPUyB2ZXJzaW9ucwogKiAoTlQgdXNlcyBVbmljb2RlIHN0cmluZ3MsIDk1IHVzZXMgQVNDSUkgc3RyaW5ncykKICoKICogQ29weXJpZ2h0IDE5OTcgTWFyY3VzIE1laXNzbmVyCiAqICAgICAgICAgICAxOTk4IEr8cmdlbiBTY2htaWVkCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAic2hsZ3VpZC5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNoZWxsMzJfbWFpbi5oIgojaW5jbHVkZSAidW5kb2NzaGVsbC5oIgojaW5jbHVkZSAicGlkbC5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoc2hlbGwpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChwaWRsKTsKCi8qIEZJWE1FOiAhISEgbW92ZSBDUkVBVEVNUlVMSVNUIGFuZCBmbGFncyB0byBoZWFkZXIgZmlsZSAhISEgKi8KLyogICAgICAgICEhISBpdCBpcyBpbiBib3RoIGhlcmUgYW5kIGNvbWN0bDMydW5kb2MuYyAgICAgICEhISAqLwp0eXBlZGVmIHN0cnVjdCB0YWdDUkVBVEVNUlVMSVNUCnsKICAgIERXT1JEICBjYlNpemU7ICAgICAgICAvKiBzaXplIG9mIHN0cnVjdCAqLwogICAgRFdPUkQgIG5NYXhJdGVtczsgICAgIC8qIG1heCBuby4gb2YgaXRlbXMgaW4gbGlzdCAqLwogICAgRFdPUkQgIGR3RmxhZ3M7ICAgICAgIC8qIHNlZSBiZWxvdyAqLwogICAgSEtFWSAgIGhLZXk7ICAgICAgICAgIC8qIHJvb3QgcmVnLiBrZXkgdW5kZXIgd2hpY2ggbGlzdCBpcyBzYXZlZCAqLwogICAgTFBDU1RSIGxwc3pTdWJLZXk7ICAgIC8qIHJlZy4gc3Via2V5ICovCiAgICBQUk9DICAgbHBmbkNvbXBhcmU7ICAgLyogaXRlbSBjb21wYXJlIHByb2MgKi8KfSBDUkVBVEVNUlVMSVNUQSwgKkxQQ1JFQVRFTVJVTElTVEE7CgovKiBkd0ZsYWdzICovCiNkZWZpbmUgTVJVRl9TVFJJTkdfTElTVCAgMCAvKiBsaXN0IHdpbGwgY29udGFpbiBzdHJpbmdzICovCiNkZWZpbmUgTVJVRl9CSU5BUllfTElTVCAgMSAvKiBsaXN0IHdpbGwgY29udGFpbiBiaW5hcnkgZGF0YSAqLwojZGVmaW5lIE1SVUZfREVMQVlFRF9TQVZFIDIgLyogb25seSBzYXZlIGxpc3Qgb3JkZXIgdG8gcmVnLiBpcyBGcmVlTVJVTGlzdCAqLwoKZXh0ZXJuIEhBTkRMRSBXSU5BUEkgQ3JlYXRlTVJVTGlzdEEoTFBDUkVBVEVNUlVMSVNUQSBscGNtbCk7CmV4dGVybiBEV09SRCAgV0lOQVBJIEZyZWVNUlVMaXN0KEhBTkRMRSBoTVJVTGlzdCk7CmV4dGVybiBJTlQgICAgV0lOQVBJIEFkZE1SVURhdGEoSEFORExFIGhMaXN0LCBMUENWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhKTsKZXh0ZXJuIElOVCAgICBXSU5BUEkgRmluZE1SVURhdGEoSEFORExFIGhMaXN0LCBMUENWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhLCBMUElOVCBscFJlZ051bSk7CmV4dGVybiBJTlQgICAgV0lOQVBJIEVudW1NUlVMaXN0QShIQU5ETEUgaExpc3QsIElOVCBuSXRlbVBvcywgTFBWT0lEIGxwQnVmZmVyLCBEV09SRCBuQnVmZmVyU2l6ZSk7CgoKLyogR2V0IGEgZnVuY3Rpb24gcG9pbnRlciBmcm9tIGEgRExMIGhhbmRsZSAqLwojZGVmaW5lIEdFVF9GVU5DKGZ1bmMsIG1vZHVsZSwgbmFtZSwgZmFpbCkgXAogIGRvIHsgXAogICAgaWYgKCFmdW5jKSB7IFwKICAgICAgaWYgKCFTSEVMTDMyX2gjI21vZHVsZSAmJiAhKFNIRUxMMzJfaCMjbW9kdWxlID0gTG9hZExpYnJhcnlBKCNtb2R1bGUgIi5kbGwiKSkpIHJldHVybiBmYWlsOyBcCiAgICAgIGZ1bmMgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoU0hFTEwzMl9oIyNtb2R1bGUsIG5hbWUpOyBcCiAgICAgIGlmICghZnVuYykgcmV0dXJuIGZhaWw7IFwKICAgIH0gXAogIH0gd2hpbGUgKDApCgovKiBGdW5jdGlvbiBwb2ludGVycyBmb3IgR0VUX0ZVTkMgbWFjcm8gKi8Kc3RhdGljIEhNT0RVTEUgU0hFTEwzMl9oc2hsd2FwaT1OVUxMOwpzdGF0aWMgSEFORExFIChXSU5BUEkgKnBTSEFsbG9jU2hhcmVkKShMUENWT0lELERXT1JELERXT1JEKTsKc3RhdGljIExQVk9JRCAoV0lOQVBJICpwU0hMb2NrU2hhcmVkKShIQU5ETEUsRFdPUkQpOwpzdGF0aWMgQk9PTCAgIChXSU5BUEkgKnBTSFVubG9ja1NoYXJlZCkoTFBWT0lEKTsKc3RhdGljIEJPT0wgICAoV0lOQVBJICpwU0hGcmVlU2hhcmVkKShIQU5ETEUsRFdPUkQpOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFBhcnNlRmllbGRBCQkJCQlbaW50ZXJuYWxdCiAqCiAqIGNvcGllcyBhIGZpZWxkIGZyb20gYSAnLCcgZGVsaW1pdGVkIHN0cmluZwogKgogKiBmaXJzdCBmaWVsZCBpcyBuRmllbGQgPSAxCiAqLwpEV09SRCBXSU5BUEkgUGFyc2VGaWVsZEEoCglMUENTVFIgc3JjLAoJRFdPUkQgbkZpZWxkLAoJTFBTVFIgZHN0LAoJRFdPUkQgbGVuKQp7CglXQVJOKCIoJXMsMHglMDh4LCVwLCVkKSBzZW1pLXN0dWIuXG4iLGRlYnVnc3RyX2Eoc3JjKSxuRmllbGQsZHN0LGxlbik7CgoJaWYgKCFzcmMgfHwgIXNyY1swXSB8fCAhZHN0IHx8ICFsZW4pCgkgIHJldHVybiAwOwoKCS8qIHNraXAgbiBmaWVsZHMgZGVsaW1pdGVkIGJ5ICcsJyAqLwoJd2hpbGUgKG5GaWVsZCA+IDEpCgl7CgkgIGlmICgqc3JjPT0nXDAnKSByZXR1cm4gRkFMU0U7CgkgIGlmICgqKHNyYysrKT09JywnKSBuRmllbGQtLTsKCX0KCgkvKiBjb3B5IHBhcnQgdGlsbCB0aGUgbmV4dCAnLCcgdG8gZHN0ICovCgl3aGlsZSAoICpzcmMhPSdcMCcgJiYgKnNyYyE9JywnICYmIChsZW4tLSk+MCApICooZHN0KyspPSooc3JjKyspOwoKCS8qIGZpbmFsaXplIHRoZSBzdHJpbmcgKi8KCSpkc3Q9MHgwOwoKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQYXJzZUZpZWxkVwkJCVtpbnRlcm5hbF0KICoKICogY29waWVzIGEgZmllbGQgZnJvbSBhICcsJyBkZWxpbWl0ZWQgc3RyaW5nCiAqCiAqIGZpcnN0IGZpZWxkIGlzIG5GaWVsZCA9IDEKICovCkRXT1JEIFdJTkFQSSBQYXJzZUZpZWxkVyhMUENXU1RSIHNyYywgRFdPUkQgbkZpZWxkLCBMUFdTVFIgZHN0LCBEV09SRCBsZW4pCnsKCVdBUk4oIiglcywweCUwOHgsJXAsJWQpIHNlbWktc3R1Yi5cbiIsIGRlYnVnc3RyX3coc3JjKSwgbkZpZWxkLCBkc3QsIGxlbik7CgoJaWYgKCFzcmMgfHwgIXNyY1swXSB8fCAhZHN0IHx8ICFsZW4pCgkgIHJldHVybiAwOwoKCS8qIHNraXAgbiBmaWVsZHMgZGVsaW1pdGVkIGJ5ICcsJyAqLwoJd2hpbGUgKG5GaWVsZCA+IDEpCgl7CgkgIGlmICgqc3JjID09IDB4MCkgcmV0dXJuIEZBTFNFOwoJICBpZiAoKnNyYysrID09ICcsJykgbkZpZWxkLS07Cgl9CgoJLyogY29weSBwYXJ0IHRpbGwgdGhlIG5leHQgJywnIHRvIGRzdCAqLwoJd2hpbGUgKCAqc3JjICE9IDB4MCAmJiAqc3JjICE9ICcsJyAmJiAobGVuLS0pPjAgKSAqKGRzdCsrKSA9ICooc3JjKyspOwoKCS8qIGZpbmFsaXplIHRoZSBzdHJpbmcgKi8KCSpkc3QgPSAweDA7CgoJcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFBhcnNlRmllbGQJCQlbU0hFTEwzMi41OF0KICovCkRXT1JEIFdJTkFQSSBQYXJzZUZpZWxkQVcoTFBDVk9JRCBzcmMsIERXT1JEIG5GaWVsZCwgTFBWT0lEIGRzdCwgRFdPUkQgbGVuKQp7CglpZiAoU0hFTExfT3NJc1VuaWNvZGUoKSkKCSAgcmV0dXJuIFBhcnNlRmllbGRXKHNyYywgbkZpZWxkLCBkc3QsIGxlbik7CglyZXR1cm4gUGFyc2VGaWVsZEEoc3JjLCBuRmllbGQsIGRzdCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogR2V0RmlsZU5hbWVGcm9tQnJvd3NlCQkJW1NIRUxMMzIuNjNdCiAqCiAqLwpCT09MIFdJTkFQSSBHZXRGaWxlTmFtZUZyb21Ccm93c2UoCglIV05EIGh3bmRPd25lciwKCUxQU1RSIGxwc3RyRmlsZSwKCURXT1JEIG5NYXhGaWxlLAoJTFBDU1RSIGxwc3RySW5pdGlhbERpciwKCUxQQ1NUUiBscHN0ckRlZkV4dCwKCUxQQ1NUUiBscHN0ckZpbHRlciwKCUxQQ1NUUiBscHN0clRpdGxlKQp7CiAgICBITU9EVUxFIGhtb2R1bGU7CiAgICBGQVJQUk9DIHBHZXRPcGVuRmlsZU5hbWVBOwogICAgT1BFTkZJTEVOQU1FQSBvZm47CiAgICBCT09MIHJldDsKCiAgICBUUkFDRSgiJXAsICVzLCAlZCwgJXMsICVzLCAlcywgJXMpXG4iLAoJICBod25kT3duZXIsIGxwc3RyRmlsZSwgbk1heEZpbGUsIGxwc3RySW5pdGlhbERpciwgbHBzdHJEZWZFeHQsCgkgIGxwc3RyRmlsdGVyLCBscHN0clRpdGxlKTsKCiAgICBobW9kdWxlID0gTG9hZExpYnJhcnlBKCJjb21kbGczMi5kbGwiKTsKICAgIGlmKCFobW9kdWxlKSByZXR1cm4gRkFMU0U7CiAgICBwR2V0T3BlbkZpbGVOYW1lQSA9IEdldFByb2NBZGRyZXNzKGhtb2R1bGUsICJHZXRPcGVuRmlsZU5hbWVBIik7CiAgICBpZighcEdldE9wZW5GaWxlTmFtZUEpCiAgICB7CglGcmVlTGlicmFyeShobW9kdWxlKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBtZW1zZXQoJm9mbiwgMCwgc2l6ZW9mKG9mbikpOwoKICAgIG9mbi5sU3RydWN0U2l6ZSA9IHNpemVvZihvZm4pOwogICAgb2ZuLmh3bmRPd25lciA9IGh3bmRPd25lcjsKICAgIG9mbi5scHN0ckZpbHRlciA9IGxwc3RyRmlsdGVyOwogICAgb2ZuLmxwc3RyRmlsZSA9IGxwc3RyRmlsZTsKICAgIG9mbi5uTWF4RmlsZSA9IG5NYXhGaWxlOwogICAgb2ZuLmxwc3RySW5pdGlhbERpciA9IGxwc3RySW5pdGlhbERpcjsKICAgIG9mbi5scHN0clRpdGxlID0gbHBzdHJUaXRsZTsKICAgIG9mbi5scHN0ckRlZkV4dCA9IGxwc3RyRGVmRXh0OwogICAgb2ZuLkZsYWdzID0gT0ZOX0VYUExPUkVSIHwgT0ZOX0hJREVSRUFET05MWSB8IE9GTl9GSUxFTVVTVEVYSVNUOwogICAgcmV0ID0gcEdldE9wZW5GaWxlTmFtZUEoJm9mbik7CgogICAgRnJlZUxpYnJhcnkoaG1vZHVsZSk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEdldFNldFNldHRpbmdzCQkJCVtTSEVMTDMyLjY4XQogKi8KVk9JRCBXSU5BUEkgU0hHZXRTZXRTZXR0aW5ncyhMUFNIRUxMU1RBVEUgbHBzcywgRFdPUkQgZHdNYXNrLCBCT09MIGJTZXQpCnsKICBpZihiU2V0KQogIHsKICAgIEZJWE1FKCIlcCAweCUwOHggVFJVRVxuIiwgbHBzcywgZHdNYXNrKTsKICB9CiAgZWxzZQogIHsKICAgIFNIR2V0U2V0dGluZ3MoKExQU0hFTExGTEFHU1RBVEUpbHBzcyxkd01hc2spOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hHZXRTZXR0aW5ncwkJCQlbU0hFTEwzMi5AXQogKgogKiBOT1RFUwogKiAgdGhlIHJlZ2lzdHJ5IHBhdGggYXJlIGZvciB3aW45OCAodGVzdGVkKQogKiAgYW5kIHBvc3NpYmx5IGFyZSB0aGUgc2FtZSBpbiBudDQwCiAqCiAqLwpWT0lEIFdJTkFQSSBTSEdldFNldHRpbmdzKExQU0hFTExGTEFHU1RBVEUgbHBzZnMsIERXT1JEIGR3TWFzaykKewoJSEtFWQloS2V5OwoJRFdPUkQJZHdEYXRhOwoJRFdPUkQJZHdEYXRhU2l6ZSA9IHNpemVvZiAoRFdPUkQpOwoKCVRSQUNFKCIoJXAgMHglMDh4KVxuIixscHNmcyxkd01hc2spOwoKCWlmIChSZWdDcmVhdGVLZXlFeEEoSEtFWV9DVVJSRU5UX1VTRVIsICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50VmVyc2lvblxcRXhwbG9yZXJcXEFkdmFuY2VkIiwKCQkJCSAwLCAwLCAwLCBLRVlfQUxMX0FDQ0VTUywgMCwgJmhLZXksIDApKQoJICByZXR1cm47CgoJaWYgKCAoU1NGX1NIT1dFWFRFTlNJT05TICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiSGlkZUZpbGVFeHQiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93RXh0ZW5zaW9ucyAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX1NIT1dJTkZPVElQICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiU2hvd0luZm9UaXAiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZTaG93SW5mb1RpcCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX0RPTlRQUkVUVFlQQVRIICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiRG9udFByZXR0eVBhdGgiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZEb250UHJldHR5UGF0aCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX0hJREVJQ09OUyAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIkhpZGVJY29ucyIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+ZkhpZGVJY29ucyAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX01BUE5FVERSVkJVVFRPTiAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIk1hcE5ldERydkJ0biIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+Zk1hcE5ldERydkJ0biAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCAoU1NGX1NIT1dBVFRSSUJDT0wgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJTaG93QXR0cmliQ29sIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mU2hvd0F0dHJpYkNvbCAgPSAoKGR3RGF0YSA9PSAwKSA/ICAwIDogMSk7CgoJaWYgKCgoU1NGX1NIT1dBTExPQkpFQ1RTIHwgU1NGX1NIT1dTWVNGSUxFUykgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJIaWRkZW4iLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCXsgaWYgKGR3RGF0YSA9PSAwKQoJICB7IGlmIChTU0ZfU0hPV0FMTE9CSkVDVFMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd0FsbE9iamVjdHMgID0gMDsKCSAgICBpZiAoU1NGX1NIT1dTWVNGSUxFUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93U3lzRmlsZXMgID0gMDsKCSAgfQoJICBlbHNlIGlmIChkd0RhdGEgPT0gMSkKCSAgeyBpZiAoU1NGX1NIT1dBTExPQkpFQ1RTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dBbGxPYmplY3RzICA9IDE7CgkgICAgaWYgKFNTRl9TSE9XU1lTRklMRVMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd1N5c0ZpbGVzICA9IDA7CgkgIH0KCSAgZWxzZSBpZiAoZHdEYXRhID09IDIpCgkgIHsgaWYgKFNTRl9TSE9XQUxMT0JKRUNUUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93QWxsT2JqZWN0cyAgPSAwOwoJICAgIGlmIChTU0ZfU0hPV1NZU0ZJTEVTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dTeXNGaWxlcyAgPSAxOwoJICB9Cgl9CglSZWdDbG9zZUtleSAoaEtleSk7CgoJVFJBQ0UoIi0tIDB4JTA0eFxuIiwgKihXT1JEKilscHNmcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UJCQlbU0hFTEwzMi43M10KICoKICogU2VuZCBhIG1lc3NhZ2UgdG8gYW4gZXhwbG9yZXIgY2FiaW5ldCB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaHduZENhYmluZXQgW0ldIFRoZSB3aW5kb3cgY29udGFpbmluZyB0aGUgc2hlbGx2aWV3IHRvIGNvbW11bmljYXRlIHdpdGgKICogIGR3TWVzc2FnZSAgIFtJXSBUaGUgU0ZWTSBtZXNzYWdlIHRvIHNlbmQKICogIGR3UGFyYW0gICAgIFtJXSBNZXNzYWdlIHBhcmFtZXRlcgogKgogKiBSRVRVUk5TCiAqICBmaXhtZS4KICoKICogTk9URVMKICogIE1lc3NhZ2UgU0ZWTV9SRUFSUkFOR0UgPSAxCiAqCiAqICAgIFRoaXMgbWVzc2FnZSBnZXRzIHNlbnQgd2hlbiBhIGNvbHVtbiBnZXRzIGNsaWNrZWQgdG8gaW5zdHJ1Y3QgdGhlCiAqICAgIHNoZWxsIHZpZXcgdG8gcmUtc29ydCB0aGUgaXRlbSBsaXN0LiBkd1BhcmFtIGlkZW50aWZpZXMgdGhlIGNvbHVtbgogKiAgICB0aGF0IHdhcyBjbGlja2VkLgogKi8KTFJFU1VMVCBXSU5BUEkgU0hTaGVsbEZvbGRlclZpZXdfTWVzc2FnZSgKCUhXTkQgaHduZENhYmluZXQsCglVSU5UIHVNZXNzYWdlLAoJTFBBUkFNIGxQYXJhbSkKewoJRklYTUUoIiVwICUwOHggJTA4bHggc3R1YlxuIixod25kQ2FiaW5ldCwgdU1lc3NhZ2UsIGxQYXJhbSk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVnaXN0ZXJTaGVsbEhvb2sJCQkJW1NIRUxMMzIuMTgxXQogKgogKiBSZWdpc3RlciBhIHNoZWxsIGhvb2suCiAqCiAqIFBBUkFNUwogKiAgICAgIGh3bmQgICBbSV0gIFdpbmRvdyBoYW5kbGUKICogICAgICBkd1R5cGUgW0ldICBUeXBlIG9mIGhvb2suCiAqCiAqIE5PVEVTCiAqICAgICBFeHBvcnRlZCBieSBvcmRpbmFsCiAqLwpCT09MIFdJTkFQSSBSZWdpc3RlclNoZWxsSG9vaygKCUhXTkQgaFduZCwKCURXT1JEIGR3VHlwZSkKewoJRklYTUUoIiglcCwweCUwOHgpOnN0dWIuXG4iLGhXbmQsIGR3VHlwZSk7CglyZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2hlbGxNZXNzYWdlQm94VwkJCQlbU0hFTEwzMi4xODJdCiAqCiAqIFNlZSBTaGVsbE1lc3NhZ2VCb3hBLgogKgogKiBOT1RFOgogKiBzaGx3YXBpLlNoZWxsTWVzc2FnZUJveFdyYXBXIGlzIGEgZHVwbGljYXRlIG9mIHNoZWxsMzIuU2hlbGxNZXNzYWdlQm94VwogKiBiZWNhdXNlIHdlIGNhbid0IGZvcndhcmQgdG8gaXQgaW4gdGhlIC5zcGVjIGZpbGUgc2luY2UgaXQncyBleHBvcnRlZCBieQogKiBvcmRpbmFsLiBJZiB5b3UgY2hhbmdlIHRoZSBpbXBsZW1lbnRhdGlvbiBoZXJlIHBsZWFzZSB1cGRhdGUgdGhlIGNvZGUgaW4KICogc2hsd2FwaSBhcyB3ZWxsLgogKi8KaW50IFdJTkFQSVYgU2hlbGxNZXNzYWdlQm94VygKCUhJTlNUQU5DRSBoSW5zdGFuY2UsCglIV05EIGhXbmQsCglMUENXU1RSIGxwVGV4dCwKCUxQQ1dTVFIgbHBDYXB0aW9uLAoJVUlOVCB1VHlwZSwKCS4uLikKewoJV0NIQVIJc3pUZXh0WzEwMF0sc3pUaXRsZVsxMDBdOwoJTFBDV1NUUiBwc3pUZXh0ID0gc3pUZXh0LCBwc3pUaXRsZSA9IHN6VGl0bGU7CglMUFdTVFIgIHBzelRlbXA7Cgl2YV9saXN0IGFyZ3M7CglpbnQJcmV0OwoKCXZhX3N0YXJ0KGFyZ3MsIHVUeXBlKTsKCS8qIHd2c3ByaW50ZkEoYnVmLGZtdCwgYXJncyk7ICovCgoJVFJBQ0UoIiglcCwlcCwlcCwlcCwlMDh4KVxuIiwKCSAgICBoSW5zdGFuY2UsaFduZCxscFRleHQsbHBDYXB0aW9uLHVUeXBlKTsKCglpZiAoSVNfSU5UUkVTT1VSQ0UobHBDYXB0aW9uKSkKCSAgTG9hZFN0cmluZ1coaEluc3RhbmNlLCBMT1dPUkQobHBDYXB0aW9uKSwgc3pUaXRsZSwgc2l6ZW9mKHN6VGl0bGUpL3NpemVvZihzelRpdGxlWzBdKSk7CgllbHNlCgkgIHBzelRpdGxlID0gbHBDYXB0aW9uOwoKCWlmIChJU19JTlRSRVNPVVJDRShscFRleHQpKQoJICBMb2FkU3RyaW5nVyhoSW5zdGFuY2UsIExPV09SRChscFRleHQpLCBzelRleHQsIHNpemVvZihzelRleHQpL3NpemVvZihzelRleHRbMF0pKTsKCWVsc2UKCSAgcHN6VGV4dCA9IGxwVGV4dDsKCglGb3JtYXRNZXNzYWdlVyhGT1JNQVRfTUVTU0FHRV9BTExPQ0FURV9CVUZGRVIgfCBGT1JNQVRfTUVTU0FHRV9GUk9NX1NUUklORywKCQkgICAgICAgcHN6VGV4dCwgMCwgMCwgKExQV1NUUikmcHN6VGVtcCwgMCwgJmFyZ3MpOwoKCXZhX2VuZChhcmdzKTsKCglyZXQgPSBNZXNzYWdlQm94VyhoV25kLHBzelRlbXAscHN6VGl0bGUsdVR5cGUpOwoJTG9jYWxGcmVlKChITE9DQUwpcHN6VGVtcCk7CglyZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTaGVsbE1lc3NhZ2VCb3hBCQkJCVtTSEVMTDMyLjE4M10KICoKICogRm9ybWF0IGFuZCBvdXRwdXQgYW4gZXJyb3IgbWVzc2FnZS4KICoKICogUEFSQU1TCiAqICBoSW5zdGFuY2UgW0ldIEluc3RhbmNlIGhhbmRsZSBvZiBtZXNzYWdlIGNyZWF0b3IKICogIGhXbmQgICAgICBbSV0gV2luZG93IGhhbmRsZSBvZiBtZXNzYWdlIGNyZWF0b3IKICogIGxwVGV4dCAgICBbSV0gUmVzb3VyY2UgSWQgb2YgdGl0bGUgb3IgTFBTVFIKICogIGxwQ2FwdGlvbiBbSV0gUmVzb3VyY2UgSWQgb2YgdGl0bGUgb3IgTFBTVFIKICogIHVUeXBlICAgICBbSV0gVHlwZSBvZiBlcnJvciBtZXNzYWdlCiAqCiAqIFJFVFVSTlMKICogIEEgcmV0dXJuIHZhbHVlIGZyb20gTWVzc2FnZUJveEEoKS4KICoKICogTk9URVMKICogICAgIEV4cG9ydGVkIGJ5IG9yZGluYWwKICovCmludCBXSU5BUElWIFNoZWxsTWVzc2FnZUJveEEoCglISU5TVEFOQ0UgaEluc3RhbmNlLAoJSFdORCBoV25kLAoJTFBDU1RSIGxwVGV4dCwKCUxQQ1NUUiBscENhcHRpb24sCglVSU5UIHVUeXBlLAoJLi4uKQp7CgljaGFyCXN6VGV4dFsxMDBdLHN6VGl0bGVbMTAwXTsKCUxQQ1NUUiAgcHN6VGV4dCA9IHN6VGV4dCwgcHN6VGl0bGUgPSBzelRpdGxlOwoJTFBTVFIgICBwc3pUZW1wOwoJdmFfbGlzdCBhcmdzOwoJaW50CXJldDsKCgl2YV9zdGFydChhcmdzLCB1VHlwZSk7CgkvKiB3dnNwcmludGZBKGJ1ZixmbXQsIGFyZ3MpOyAqLwoKCVRSQUNFKCIoJXAsJXAsJXAsJXAsJTA4eClcbiIsCgkgICAgaEluc3RhbmNlLGhXbmQsbHBUZXh0LGxwQ2FwdGlvbix1VHlwZSk7CgoJaWYgKElTX0lOVFJFU09VUkNFKGxwQ2FwdGlvbikpCgkgIExvYWRTdHJpbmdBKGhJbnN0YW5jZSwgTE9XT1JEKGxwQ2FwdGlvbiksIHN6VGl0bGUsIHNpemVvZihzelRpdGxlKSk7CgllbHNlCgkgIHBzelRpdGxlID0gbHBDYXB0aW9uOwoKCWlmIChJU19JTlRSRVNPVVJDRShscFRleHQpKQoJICBMb2FkU3RyaW5nQShoSW5zdGFuY2UsIExPV09SRChscFRleHQpLCBzelRleHQsIHNpemVvZihzelRleHQpKTsKCWVsc2UKCSAgcHN6VGV4dCA9IGxwVGV4dDsKCglGb3JtYXRNZXNzYWdlQShGT1JNQVRfTUVTU0FHRV9BTExPQ0FURV9CVUZGRVIgfCBGT1JNQVRfTUVTU0FHRV9GUk9NX1NUUklORywKCQkgICAgICAgcHN6VGV4dCwgMCwgMCwgKExQU1RSKSZwc3pUZW1wLCAwLCAmYXJncyk7CgoJdmFfZW5kKGFyZ3MpOwoKCXJldCA9IE1lc3NhZ2VCb3hBKGhXbmQscHN6VGVtcCxwc3pUaXRsZSx1VHlwZSk7CglMb2NhbEZyZWUoKEhMT0NBTClwc3pUZW1wKTsKCXJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIUmVnaXN0ZXJEcmFnRHJvcAkJCQlbU0hFTEwzMi44Nl0KICoKICogUHJvYmFibHkgZXF1aXZhbGVudCB0byBSZWdpc3RlckRyYWdEcm9wIGJ1dCB1bmRlciBXaW5kb3dzIDl4IGl0IGNvdWxkIHVzZSB0aGUKICogc2hlbGwzMiBidWlsdC1pbiAibWluaS1DT00iIHdpdGhvdXQgdGhlIG5lZWQgdG8gbG9hZCBvbGUzMi5kbGwgLSBzZWUgU0hMb2FkT0xFCiAqIGZvciBkZXRhaWxzCiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBvcmRpbmFsCiAqCiAqIFNFRSBBTFNPCiAqICAgICBSZWdpc3RlckRyYWdEcm9wLCBTSExvYWRPTEUKICovCkhSRVNVTFQgV0lOQVBJIFNIUmVnaXN0ZXJEcmFnRHJvcCgKCUhXTkQgaFduZCwKCUxQRFJPUFRBUkdFVCBwRHJvcFRhcmdldCkKewoJRklYTUUoIiglcCwlcCk6c3R1Yi5cbiIsIGhXbmQsIHBEcm9wVGFyZ2V0KTsKCXJldHVybiBSZWdpc3RlckRyYWdEcm9wKGhXbmQsIHBEcm9wVGFyZ2V0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZXZva2VEcmFnRHJvcAkJCQlbU0hFTEwzMi44N10KICoKICogUHJvYmFibHkgZXF1aXZhbGVudCB0byBSZXZva2VEcmFnRHJvcCBidXQgdW5kZXIgV2luZG93cyA5eCBpdCBjb3VsZCB1c2UgdGhlCiAqIHNoZWxsMzIgYnVpbHQtaW4gIm1pbmktQ09NIiB3aXRob3V0IHRoZSBuZWVkIHRvIGxvYWQgb2xlMzIuZGxsIC0gc2VlIFNITG9hZE9MRQogKiBmb3IgZGV0YWlscwogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKgogKiBTRUUgQUxTTwogKiAgICAgUmV2b2tlRHJhZ0Ryb3AsIFNITG9hZE9MRQogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZXZva2VEcmFnRHJvcChIV05EIGhXbmQpCnsKICAgIEZJWE1FKCIoJXApOnN0dWIuXG4iLGhXbmQpOwogICAgcmV0dXJuIFJldm9rZURyYWdEcm9wKGhXbmQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSERvRHJhZ0Ryb3AJCQkJCVtTSEVMTDMyLjg4XQogKgogKiBQcm9iYWJseSBlcXVpdmFsZW50IHRvIERvRHJhZ0Ryb3AgYnV0IHVuZGVyIFdpbmRvd3MgOXggaXQgY291bGQgdXNlIHRoZQogKiBzaGVsbDMyIGJ1aWx0LWluICJtaW5pLUNPTSIgd2l0aG91dCB0aGUgbmVlZCB0byBsb2FkIG9sZTMyLmRsbCAtIHNlZSBTSExvYWRPTEUKICogZm9yIGRldGFpbHMKICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICoKICogU0VFIEFMU08KICogICAgIERvRHJhZ0Ryb3AsIFNITG9hZE9MRQogKi8KSFJFU1VMVCBXSU5BUEkgU0hEb0RyYWdEcm9wKAoJSFdORCBoV25kLAoJTFBEQVRBT0JKRUNUIGxwRGF0YU9iamVjdCwKCUxQRFJPUFNPVVJDRSBscERyb3BTb3VyY2UsCglEV09SRCBkd09LRWZmZWN0LAoJTFBEV09SRCBwZHdFZmZlY3QpCnsKICAgIEZJWE1FKCIoJXAgJXAgJXAgMHglMDh4ICVwKTpzdHViLlxuIiwKICAgIGhXbmQsIGxwRGF0YU9iamVjdCwgbHBEcm9wU291cmNlLCBkd09LRWZmZWN0LCBwZHdFZmZlY3QpOwoJcmV0dXJuIERvRHJhZ0Ryb3AobHBEYXRhT2JqZWN0LCBscERyb3BTb3VyY2UsIGR3T0tFZmZlY3QsIHBkd0VmZmVjdCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFycmFuZ2VXaW5kb3dzCQkJCVtTSEVMTDMyLjE4NF0KICoKICovCldPUkQgV0lOQVBJIEFycmFuZ2VXaW5kb3dzKAoJSFdORCBod25kUGFyZW50LAoJRFdPUkQgZHdSZXNlcnZlZCwKCUxQQ1JFQ1QgbHBSZWN0LAoJV09SRCBjS2lkcywKCUNPTlNUIEhXTkQgKiBscEtpZHMpCnsKICAgIEZJWE1FKCIoJXAgMHglMDh4ICVwIDB4JTA0eCAlcCk6c3R1Yi5cbiIsCgkgICBod25kUGFyZW50LCBkd1Jlc2VydmVkLCBscFJlY3QsIGNLaWRzLCBscEtpZHMpOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNpZ25hbEZpbGVPcGVuCQkJCVtTSEVMTDMyLjEwM10KICoKICogTk9URVMKICogICAgIGV4cG9ydGVkIGJ5IG9yZGluYWwKICovCkRXT1JEIFdJTkFQSQpTaWduYWxGaWxlT3BlbiAoRFdPUkQgZHdQYXJhbTEpCnsKICAgIEZJWE1FKCIoMHglMDh4KTpzdHViLlxuIiwgZHdQYXJhbTEpOwoKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFERF9nZXRfcG9saWN5IC0gaGVscGVyIGZ1bmN0aW9uIGZvciBTSEFkZFRvUmVjZW50RG9jcwogKgogKiBQQVJBTUVURVJTCiAqICAgcG9saWN5ICAgIFtJTl0gIHBvbGljeSBuYW1lIChudWxsIHRlcm1lZCBzdHJpbmcpIHRvIGZpbmQKICogICB0eXBlICAgICAgW09VVF0gcHRyIHRvIERXT1JEIHRvIHJlY2VpdmUgdHlwZQogKiAgIGJ1ZmZlciAgICBbT1VUXSBwdHIgdG8gYXJlYSB0byBob2xkIGRhdGEgcmV0cmlldmVkCiAqICAgbGVuICAgICAgIFtJTi9PVVRdIHB0ciB0byBEV09SRCBob2xkaW5nIHNpemUgb2YgYnVmZmVyIGFuZCBnZXR0aW5nCiAqICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCBmaWxsZWQKICoKICogUkVUVVJOUwogKiAgIHJlc3VsdCBvZiB0aGUgU0hRdWVyeVZhbHVlRXggY2FsbAogKi8Kc3RhdGljIElOVCBTSEFERF9nZXRfcG9saWN5KExQQ1NUUiBwb2xpY3ksIExQRFdPUkQgdHlwZSwgTFBWT0lEIGJ1ZmZlciwgTFBEV09SRCBsZW4pCnsKICAgIEhLRVkgUG9saWN5X2Jhc2VrZXk7CiAgICBJTlQgcmV0OwoKICAgIC8qIEdldCB0aGUga2V5IGZvciB0aGUgcG9saWNpZXMgbG9jYXRpb24gaW4gdGhlIHJlZ2lzdHJ5CiAgICAgKi8KICAgIGlmIChSZWdPcGVuS2V5RXhBKEhLRVlfTE9DQUxfTUFDSElORSwKCQkgICAgICAiU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXFBvbGljaWVzXFxFeHBsb3JlciIsCgkJICAgICAgMCwgS0VZX1JFQUQsICZQb2xpY3lfYmFzZWtleSkpIHsKCglpZiAoUmVnT3BlbktleUV4QShIS0VZX0NVUlJFTlRfVVNFUiwKCQkJICAiU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXFBvbGljaWVzXFxFeHBsb3JlciIsCgkJCSAgMCwgS0VZX1JFQUQsICZQb2xpY3lfYmFzZWtleSkpIHsKCSAgICBUUkFDRSgiTm8gRXhwbG9yZXIgUG9saWNpZXMgbG9jYXRpb24gZXhpc3RzLiBQb2xpY3kgd2FudGVkPSVzXG4iLAoJCSAgcG9saWN5KTsKCSAgICAqbGVuID0gMDsKCSAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7Cgl9CiAgICB9CgogICAgLyogUmV0cmlldmUgdGhlIGRhdGEgaWYgaXQgZXhpc3RzCiAgICAgKi8KICAgIHJldCA9IFNIUXVlcnlWYWx1ZUV4QShQb2xpY3lfYmFzZWtleSwgcG9saWN5LCAwLCB0eXBlLCBidWZmZXIsIGxlbik7CiAgICBSZWdDbG9zZUtleShQb2xpY3lfYmFzZWtleSk7CiAgICByZXR1cm4gcmV0Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBRERfY29tcGFyZV9tcnUgLSBoZWxwZXIgZnVuY3Rpb24gZm9yIFNIQWRkVG9SZWNlbnREb2NzCiAqCiAqIFBBUkFNRVRFUlMKICogICBkYXRhMSAgICAgW0lOXSBkYXRhIGJlaW5nIGxvb2tlZCBmb3IKICogICBkYXRhMiAgICAgW0lOXSBkYXRhIGluIE1SVQogKiAgIGNiZGF0YSAgICBbSU5dIGxlbmd0aCBmcm9tIEZpbmRNUlVEYXRhIGNhbGwgKG5vdCB1c2VkKQogKgogKiBSRVRVUk5TCiAqICAgcG9zaXRpb24gd2l0aGluIE1SVSBsaXN0IHRoYXQgZGF0YSB3YXMgYWRkZWQuCiAqLwpzdGF0aWMgSU5UIENBTExCQUNLIFNIQUREX2NvbXBhcmVfbXJ1KExQQ1ZPSUQgZGF0YTEsIExQQ1ZPSUQgZGF0YTIsIERXT1JEIGNiRGF0YSkKewogICAgcmV0dXJuIGxzdHJjbXBpQShkYXRhMSwgZGF0YTIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFERF9jcmVhdGVfYWRkX21ydV9kYXRhIC0gaGVscGVyIGZ1bmN0aW9uIGZvciBTSEFkZFRvUmVjZW50RG9jcwogKgogKiBQQVJBTUVURVJTCiAqICAgbXJ1aGFuZGxlICAgIFtJTl0gaGFuZGxlIGZvciBjcmVhdGVkIE1SVSBsaXN0CiAqICAgZG9jX25hbWUgICAgIFtJTl0gbnVsbCB0ZXJtZWQgcHVyZSBkb2MgbmFtZQogKiAgIG5ld19sbmtfbmFtZSBbSU5dIG51bGwgdGVybWVkIHBhdGggYW5kIGZpbGUgbmFtZSBmb3IgLmxuayBmaWxlCiAqICAgYnVmZmVyICAgICAgIFtJTi9PVVRdIDIwNDggYnl0ZSBhcmVhIHRvIGNvbnN0cnVjdCBNUlUgZGF0YQogKiAgIGxlbiAgICAgICAgICBbT1VUXSBwdHIgdG8gaW50IHRvIHJlY2VpdmUgc3BhY2UgdXNlZCBpbiBidWZmZXIKICoKICogUkVUVVJOUwogKiAgIHBvc2l0aW9uIHdpdGhpbiBNUlUgbGlzdCB0aGF0IGRhdGEgd2FzIGFkZGVkLgogKi8Kc3RhdGljIElOVCBTSEFERF9jcmVhdGVfYWRkX21ydV9kYXRhKEhBTkRMRSBtcnVoYW5kbGUsIExQQ1NUUiBkb2NfbmFtZSwgTFBDU1RSIG5ld19sbmtfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGJ1ZmZlciwgSU5UICpsZW4pCnsKICAgIExQU1RSIHB0cjsKICAgIElOVCB3bGVuOwoKICAgIC8qRklYTUU6IERvY3VtZW50OgogICAgICogIFJlY2VudERvY3MgTVJVIGRhdGEgc3RydWN0dXJlIHNlZW1zIHRvIGJlOgogICAgICogICAgKzBoICAgZG9jdW1lbnQgZmlsZSBuYW1lIHcvIHRlcm1pbmF0aW5nIDBoCiAgICAgKiAgICArbmggICBzaG9ydCBpbnQgdy8gc2l6ZSBvZiByZW1haW5pbmcKICAgICAqICAgICtuKzJoIDAyaCAzMGgsIG9yIDAxaCAzMGgsIG9yIDAwaCAzMGggIC0gIHVua25vd24KICAgICAqICAgICtuKzRoIDEwIGJ5dGVzIHplcm9zICAtICAgdW5rbm93bgogICAgICogICAgK24rZWggc2hvcnRjdXQgZmlsZSBuYW1lIHcvIHRlcm1pbmF0aW5nIDBoCiAgICAgKiAgICArbitlK25oIDMgemVybyBieXRlcyAgLSAgdW5rbm93bgogICAgICovCgogICAgLyogQ3JlYXRlIHRoZSBNUlUgZGF0YSBzdHJ1Y3R1cmUgZm9yICJSZWNlbnREb2NzIgoJICovCiAgICBwdHIgPSBidWZmZXI7CiAgICBsc3RyY3B5QShwdHIsIGRvY19uYW1lKTsKICAgIHB0ciArPSAobHN0cmxlbkEoYnVmZmVyKSArIDEpOwogICAgd2xlbj0gbHN0cmxlbkEobmV3X2xua19uYW1lKSArIDEgKyAxMjsKICAgICooKHNob3J0IGludCopcHRyKSA9IHdsZW47CiAgICBwdHIgKz0gMjsgICAvKiBzdGVwIHBhc3QgdGhlIGxlbmd0aCAqLwogICAgKihwdHIrKykgPSAweDMwOyAgLyogdW5rbm93biByZWFzb24gKi8KICAgICoocHRyKyspID0gMDsgICAgIC8qIHVua25vd24sIGJ1dCBjYW4gYmUgMHgwMCwgMHgwMSwgMHgwMiAqLwogICAgbWVtc2V0KHB0ciwgMCwgMTApOwogICAgcHRyICs9IDEwOwogICAgbHN0cmNweUEocHRyLCBuZXdfbG5rX25hbWUpOwogICAgcHRyICs9IChsc3RybGVuQShuZXdfbG5rX25hbWUpICsgMSk7CiAgICBtZW1zZXQocHRyLCAwLCAzKTsKICAgIHB0ciArPSAzOwogICAgKmxlbiA9IHB0ciAtIGJ1ZmZlcjsKCiAgICAvKiBBZGQgdGhlIG5ldyBlbnRyeSBpbnRvIHRoZSBNUlUgbGlzdAogICAgICovCiAgICByZXR1cm4gQWRkTVJVRGF0YShtcnVoYW5kbGUsIChMUENWT0lEKWJ1ZmZlciwgKmxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQWRkVG9SZWNlbnREb2NzCQkJCVtTSEVMTDMyLkBdCiAqCiAqIE1vZGlmeSAoYWRkL2NsZWFyKSBTaGVsbCdzIGxpc3Qgb2YgcmVjZW50bHkgdXNlZCBkb2N1bWVudHMuCiAqCiAqIFBBUkFNRVRFUlMKICogICB1RmxhZ3MgIFtJTl0gU0hBUkRfUEFUSEEsIFNIQVJEX1BBVEhXIG9yIFNIQVJEX1BJREwKICogICBwdiAgICAgIFtJTl0gc3RyaW5nIG9yIHBpZGwsIE5VTEwgY2xlYXJzIHRoZSBsaXN0CiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBuYW1lCiAqCiAqIEZJWE1FCiAqICBjb252ZXJ0IHRvIHVuaWNvZGUKICovCnZvaWQgV0lOQVBJIFNIQWRkVG9SZWNlbnREb2NzIChVSU5UIHVGbGFncyxMUENWT0lEIHB2KQp7Ci8qIElmIGxpc3QgaXMgYSBzdHJpbmcgbGlzdCBscGZuQ29tcGFyZSBoYXMgdGhlIGZvbGxvd2luZyBwcm90b3R5cGUKICogaW50IENBTExCQUNLIE1SVUNvbXBhcmVTdHJpbmcoTFBDU1RSIHMxLCBMUENTVFIgczIpCiAqIGZvciBiaW5hcnkgbGlzdHMgdGhlIHByb3RvdHlwZSBpcwogKiBpbnQgQ0FMTEJBQ0sgTVJVQ29tcGFyZUJpbmFyeShMUENWT0lEIGRhdGExLCBMUENWT0lEIGRhdGEyLCBEV09SRCBjYkRhdGEpCiAqIHdoZXJlIGNiRGF0YSBpcyB0aGUgbm8uIG9mIGJ5dGVzIHRvIGNvbXBhcmUuCiAqIE5lZWQgdG8gY2hlY2sgd2hhdCByZXR1cm4gdmFsdWUgbWVhbnMgaWRlbnRpY2FsIC0gMD8KICovCgoKICAgIFVJTlQgb2xkZXJyb3Jtb2RlOwogICAgSEtFWSBIQ1ViYXNla2V5OwogICAgQ0hBUiBkb2NfbmFtZVtNQVhfUEFUSF07CiAgICBDSEFSIGxpbmtfZGlyW01BWF9QQVRIXTsKICAgIENIQVIgbmV3X2xua19maWxlcGF0aFtNQVhfUEFUSF07CiAgICBDSEFSIG5ld19sbmtfbmFtZVtNQVhfUEFUSF07CiAgICBJTWFsbG9jICpwcE07CiAgICBMUElURU1JRExJU1QgcGlkbDsKICAgIEhXTkQgaHduZCA9IDA7ICAgICAgIC8qIEZJWE1FOiAgZ2V0IHJlYWwgd2luZG93IGhhbmRsZSAqLwogICAgSU5UIHJldDsKICAgIERXT1JEIGRhdGFbNjRdLCBkYXRhbGVuLCB0eXBlOwoKICAgIFRSQUNFKCIlMDR4ICVwXG4iLCB1RmxhZ3MsIHB2KTsKCiAgICAvKkZJWE1FOiBEb2N1bWVudDoKICAgICAqICBSZWNlbnREb2NzIE1SVSBkYXRhIHN0cnVjdHVyZSBzZWVtcyB0byBiZToKICAgICAqICAgICswaCAgIGRvY3VtZW50IGZpbGUgbmFtZSB3LyB0ZXJtaW5hdGluZyAwaAogICAgICogICAgK25oICAgc2hvcnQgaW50IHcvIHNpemUgb2YgcmVtYWluaW5nCiAgICAgKiAgICArbisyaCAwMmggMzBoLCBvciAwMWggMzBoLCBvciAwMGggMzBoICAtICB1bmtub3duCiAgICAgKiAgICArbis0aCAxMCBieXRlcyB6ZXJvcyAgLSAgIHVua25vd24KICAgICAqICAgICtuK2VoIHNob3J0Y3V0IGZpbGUgbmFtZSB3LyB0ZXJtaW5hdGluZyAwaAogICAgICogICAgK24rZStuaCAzIHplcm8gYnl0ZXMgIC0gIHVua25vd24KICAgICAqLwoKICAgIC8qIFNlZSBpZiB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nLgogICAgICovCiAgICBkYXRhbGVuID0gNjQ7CiAgICByZXQ9U0hBRERfZ2V0X3BvbGljeSggIk5vUmVjZW50RG9jc0hpc3RvcnkiLCAmdHlwZSwgJmRhdGEsICZkYXRhbGVuKTsKICAgIGlmICgocmV0ID4gMCkgJiYgKHJldCAhPSBFUlJPUl9GSUxFX05PVF9GT1VORCkpIHsKCUVSUigiRXJyb3IgJWQgZ2V0dGluZyBwb2xpY3kgXCJOb1JlY2VudERvY3NIaXN0b3J5XCJcbiIsIHJldCk7CglyZXR1cm47CiAgICB9CiAgICBpZiAocmV0ID09IEVSUk9SX1NVQ0NFU1MpIHsKCWlmICghKCAodHlwZSA9PSBSRUdfRFdPUkQpIHx8CgkgICAgICAgKCh0eXBlID09IFJFR19CSU5BUlkpICYmIChkYXRhbGVuID09IDQpKSApKSB7CgkgICAgRVJSKCJFcnJvciBwb2xpY3kgZGF0YSBmb3IgXCJOb1JlY2VudERvY3NIaXN0b3J5XCIgbm90IGZvcm1hdHRlZCBjb3JyZWN0bHksIHR5cGU9JWQsIGxlbj0lZFxuIiwKCQl0eXBlLCBkYXRhbGVuKTsKCSAgICByZXR1cm47Cgl9CgoJVFJBQ0UoInBvbGljeSB2YWx1ZSBmb3IgTm9SZWNlbnREb2NzSGlzdG9yeSA9ICUwOHhcbiIsIGRhdGFbMF0pOwoJLyogbm93IHRlc3QgdGhlIGFjdHVhbCBwb2xpY3kgdmFsdWUgKi8KCWlmICggZGF0YVswXSAhPSAwKQoJICAgIHJldHVybjsKICAgIH0KCiAgICAvKiBPcGVuIGtleSB0byB3aGVyZSB0aGUgbmVjZXNzYXJ5IGluZm8gaXMKICAgICAqLwogICAgLyogRklYTUU6IFRoaXMgc2hvdWxkIGJlIGRvbmUgZHVyaW5nIERMTCBQUk9DRVNTX0FUVEFDSCAob3IgVEhSRUFEX0FUVEFDSCkKICAgICAqICAgICAgICBhbmQgdGhlIGNsb3NlIHNob3VsZCBiZSBkb25lIGR1cmluZyB0aGUgX0RFVEFDSC4gVGhlIHJlc3VsdGluZwogICAgICogICAgICAgIGtleSBpcyBzdG9yZWQgaW4gdGhlIERMTCBnbG9iYWwgZGF0YS4KICAgICAqLwogICAgaWYgKFJlZ0NyZWF0ZUtleUV4QShIS0VZX0NVUlJFTlRfVVNFUiwKCQkJIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxFeHBsb3JlciIsCgkJCTAsIDAsIDAsIEtFWV9SRUFELCAwLCAmSENVYmFzZWtleSwgMCkpIHsKCUVSUigiRmFpbGVkIHRvIGNyZWF0ZSAnU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXEV4cGxvcmVyJ1xuIik7CglyZXR1cm47CiAgICB9CgogICAgLyogR2V0IHBhdGggdG8gdXNlcidzICJSZWNlbnQiIGRpcmVjdG9yeQogICAgICovCiAgICBpZihTVUNDRUVERUQoU0hHZXRNYWxsb2MoJnBwTSkpKSB7CglpZiAoU1VDQ0VFREVEKFNIR2V0U3BlY2lhbEZvbGRlckxvY2F0aW9uKGh3bmQsIENTSURMX1JFQ0VOVCwKCQkJCQkJICZwaWRsKSkpIHsKCSAgICBTSEdldFBhdGhGcm9tSURMaXN0QShwaWRsLCBsaW5rX2Rpcik7CgkgICAgSU1hbGxvY19GcmVlKHBwTSwgcGlkbCk7Cgl9CgllbHNlIHsKCSAgICAvKiBzZXJpb3VzIGlzc3VlcyAqLwoJICAgIGxpbmtfZGlyWzBdID0gMDsKCSAgICBFUlIoInNlcmlvdXMgaXNzdWVzIDFcbiIpOwoJfQoJSU1hbGxvY19SZWxlYXNlKHBwTSk7CiAgICB9CiAgICBlbHNlIHsKCS8qIHNlcmlvdXMgaXNzdWVzICovCglsaW5rX2RpclswXSA9IDA7CglFUlIoInNlcmlvdXMgaXNzdWVzIDJcbiIpOwogICAgfQogICAgVFJBQ0UoIlVzZXJzIFJlY2VudCBkaXIgJXNcbiIsIGxpbmtfZGlyKTsKCiAgICAvKiBJZiBubyBpbnB1dCwgdGhlbiBnbyBjbGVhciB0aGUgbGlzdHMgKi8KICAgIGlmICghcHYpIHsKCS8qIGNsZWFyIHVzZXIncyBSZWNlbnQgZGlyCgkgKi8KCgkvKiBGSVhNRTogZGVsZXRlIGFsbCBmaWxlcyBpbiAibGlua19kaXIiCgkgKgoJICogd2hpbGUoIG1vcmUgZmlsZXMgKSB7CgkgKiAgICBsc3RyY3B5QShvbGRfbG5rX25hbWUsIGxpbmtfZGlyKTsKCSAqICAgIFBhdGhBcHBlbmRBKG9sZF9sbmtfbmFtZSwgZmlsZW5hbSk7CgkgKiAgICBEZWxldGVGaWxlQShvbGRfbG5rX25hbWUpOwoJICogfQoJICovCglGSVhNRSgic2hvdWxkIGRlbGV0ZSBhbGwgZmlsZXMgaW4gJXNcXFxuIiwgbGlua19kaXIpOwoKCS8qIGNsZWFyIE1SVSBsaXN0CgkgKi8KCS8qIE1TIEJ1ZyA/PyB2NC43Mi4zNjEyLjE3MDAgb2Ygc2hlbGwzMiBkb2VzIHRoZSBkZWxldGUgYWdhaW5zdAoJICogIEhLRVlfTE9DQUxfTUFDSElORSB2ZXJzaW9uIG9mIC4uLkN1cnJlbnRWZXJzaW9uXEV4cGxvcmVyCgkgKiAgYW5kIG5hdHVyYWxseSBpdCBmYWlscyB3LyByYz0yLiBJdCBzaG91bGQgZG8gaXQgYWdhaW5zdAoJICogIEhLRVlfQ1VSUkVOVF9VU0VSIHdoaWNoIGlzIHdoZXJlIGl0IGlzIHN0b3JlZCwgYW5kIHdoZXJlCgkgKiAgdGhlIE1SVSByb3V0aW5lcyBleHBlY3QgaXQhISEhCgkgKi8KCVJlZ0RlbGV0ZUtleUEoSENVYmFzZWtleSwgIlJlY2VudERvY3MiKTsKCVJlZ0Nsb3NlS2V5KEhDVWJhc2VrZXkpOwoJcmV0dXJuOwogICAgfQoKICAgIC8qIEhhdmUgZGF0YSB0byBhZGQsIHRoZSBqb2JzIHRvIGJlIGRvbmU6CiAgICAgKiAgIDEuIEFkZCBkb2N1bWVudCB0byBNUlUgbGlzdCBpbiByZWdpc3RyeSAiSEtDVVxTb2Z0d2FyZVwKICAgICAqICAgICAgTWljcm9zb2Z0XFdpbmRvd3NcQ3VycmVudFZlcnNpb25cRXhwbG9yZXJcUmVjZW50RG9jcyIuCiAgICAgKiAgIDIuIEFkZCBzaG9ydGN1dCB0byBkb2N1bWVudCBpbiB0aGUgdXNlcidzIFJlY2VudCBkaXJlY3RvcnkKICAgICAqICAgICAgKENTSURMX1JFQ0VOVCkuCiAgICAgKiAgIDMuIEFkZCBzaG9ydGN1dCB0byBTdGFydCBtZW51J3MgRG9jdW1lbnRzIHN1Ym1lbnUuCiAgICAgKi8KCiAgICAvKiBHZXQgdGhlIHB1cmUgZG9jdW1lbnQgbmFtZSBmcm9tIHRoZSBpbnB1dAogICAgICovCiAgICBzd2l0Y2ggKHVGbGFncykKICAgIHsKICAgIGNhc2UgU0hBUkRfUElETDoKCVNIR2V0UGF0aEZyb21JRExpc3RBKChMUENJVEVNSURMSVNUKSBwdiwgZG9jX25hbWUpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgU0hBUkRfUEFUSEE6CiAgICAgICAgbHN0cmNweW5BKGRvY19uYW1lLCAoTFBDU1RSKXB2LCBNQVhfUEFUSCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTSEFSRF9QQVRIVzoKICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgKExQQ1dTVFIpcHYsIC0xLCBkb2NfbmFtZSwgTUFYX1BBVEgsIE5VTEwsIE5VTEwpOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGZsYWdzOiAldVxuIiwgdUZsYWdzKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgVFJBQ0UoImZ1bGwgZG9jdW1lbnQgbmFtZSAlc1xuIiwgZGVidWdzdHJfYShkb2NfbmFtZSkpOwogICAgUGF0aFN0cmlwUGF0aEEoZG9jX25hbWUpOwogICAgVFJBQ0UoInN0cmlwcGVkIGRvY3VtZW50IG5hbWUgJXNcbiIsIGRlYnVnc3RyX2EoZG9jX25hbWUpKTsKCgogICAgLyogKioqICBKT0IgMTogVXBkYXRlIHJlZ2lzdHJ5IGZvciAuLi5cRXhwbG9yZXJcUmVjZW50RG9jcyBsaXN0ICAqKiogKi8KCiAgICB7ICAvKiBvbiBpbnB1dCBuZWVkczoKCSogICAgICBkb2NfbmFtZSAgICAtICBwdXJlIGZpbGUtc3BlYywgbm8gcGF0aAoJKiAgICAgIGxpbmtfZGlyICAgIC0gIHBhdGggdG8gdGhlIHVzZXIncyBSZWNlbnQgZGlyZWN0b3J5CgkqICAgICAgSENVYmFzZWtleSAgLSAga2V5IG9mIC4uLldpbmRvd3NcQ3VycmVudFZlcnNpb25cRXhwbG9yZXIiIG5vZGUKCSogY3JlYXRlczoKCSogICAgICBuZXdfbG5rX25hbWUtICBwdXJlIGZpbGUtc3BlYywgbm8gcGF0aCBmb3IgbmV3IC5sbmsgZmlsZQoJKiAgICAgIG5ld19sbmtfZmlsZXBhdGgKCSogICAgICAgICAgICAgICAgICAtICBwYXRoIGFuZCBmaWxlIG5hbWUgb2YgbmV3IC5sbmsgZmlsZQoJKi8KCUNSRUFURU1SVUxJU1RBIG15bXJ1OwoJSEFORExFIG1ydWhhbmRsZTsKCUlOVCBsZW4sIHBvcywgYnVmdXNlZCwgZXJyOwoJSU5UIGk7CglEV09SRCBhdHRyOwoJQ0hBUiBidWZmZXJbMjA0OF07CglDSEFSICpwdHI7CglDSEFSIG9sZF9sbmtfbmFtZVtNQVhfUEFUSF07CglzaG9ydCBpbnQgc2xlbjsKCglteW1ydS5jYlNpemUgPSBzaXplb2YoQ1JFQVRFTVJVTElTVEEpOwoJbXltcnUubk1heEl0ZW1zID0gMTU7CglteW1ydS5kd0ZsYWdzID0gTVJVRl9CSU5BUllfTElTVCB8IE1SVUZfREVMQVlFRF9TQVZFOwoJbXltcnUuaEtleSA9IEhDVWJhc2VrZXk7CglteW1ydS5scHN6U3ViS2V5ID0gIlJlY2VudERvY3MiOwoJbXltcnUubHBmbkNvbXBhcmUgPSAoUFJPQylTSEFERF9jb21wYXJlX21ydTsKCW1ydWhhbmRsZSA9IENyZWF0ZU1SVUxpc3RBKCZteW1ydSk7CglpZiAoIW1ydWhhbmRsZSkgewoJICAgIC8qIE1SVSBmYWlsZWQgKi8KCSAgICBFUlIoIk1SVSBwcm9jZXNzaW5nIGZhaWxlZCwgaGFuZGxlIHplcm9cbiIpOwoJICAgIFJlZ0Nsb3NlS2V5KEhDVWJhc2VrZXkpOwoJICAgIHJldHVybjsKCX0KCWxlbiA9IGxzdHJsZW5BKGRvY19uYW1lKTsKCXBvcyA9IEZpbmRNUlVEYXRhKG1ydWhhbmRsZSwgZG9jX25hbWUsIGxlbiwgMCk7CgoJLyogTm93IGdldCB0aGUgTVJVIGVudHJ5IHRoYXQgd2lsbCBiZSByZXBsYWNlZAoJICogYW5kIGRlbGV0ZSB0aGUgLmxuayBmaWxlIGZvciBpdAoJICovCglpZiAoKGJ1ZnVzZWQgPSBFbnVtTVJVTGlzdEEobXJ1aGFuZGxlLCAocG9zID09IC0xKSA/IDE0IDogcG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZmZXIsIDIwNDgpKSAhPSAtMSkgewoJICAgIHB0ciA9IGJ1ZmZlcjsKCSAgICBwdHIgKz0gKGxzdHJsZW5BKGJ1ZmZlcikgKyAxKTsKCSAgICBzbGVuID0gKigoc2hvcnQgaW50KilwdHIpOwoJICAgIHB0ciArPSAyOyAgLyogc2tpcCB0aGUgbGVuZ3RoIGFyZWEgKi8KCSAgICBpZiAoYnVmdXNlZCA+PSBzbGVuICsgKHB0ci1idWZmZXIpKSB7CgkJLyogYnVmZmVyIHNpemUgbG9va3MgZ29vZCAqLwoJCXB0ciArPSAxMjsgLyogZ2V0IHRvIHN0cmluZyAqLwoJCWxlbiA9IGJ1ZnVzZWQgLSAocHRyLWJ1ZmZlcik7ICAvKiBnZXQgbGVuZ3RoIG9mIGJ1ZiByZW1haW5pbmcgKi8KCQlpZiAoKGxzdHJsZW5BKHB0cikgPiAwKSAmJiAobHN0cmxlbkEocHRyKSA8PSBsZW4tMSkpIHsKCQkgICAgLyogYXBwZWFycyB0byBiZSBnb29kIHN0cmluZyAqLwoJCSAgICBsc3RyY3B5QShvbGRfbG5rX25hbWUsIGxpbmtfZGlyKTsKCQkgICAgUGF0aEFwcGVuZEEob2xkX2xua19uYW1lLCBwdHIpOwoJCSAgICBpZiAoIURlbGV0ZUZpbGVBKG9sZF9sbmtfbmFtZSkpIHsKCQkJaWYgKChhdHRyID0gR2V0RmlsZUF0dHJpYnV0ZXNBKG9sZF9sbmtfbmFtZSkpID09IElOVkFMSURfRklMRV9BVFRSSUJVVEVTKSB7CgkJCSAgICBpZiAoKGVyciA9IEdldExhc3RFcnJvcigpKSAhPSBFUlJPUl9GSUxFX05PVF9GT1VORCkgewoJCQkJRVJSKCJEZWxldGUgZm9yICVzIGZhaWxlZCwgZXJyPSVkLCBhdHRyPSUwOHhcbiIsCgkJCQkgICAgb2xkX2xua19uYW1lLCBlcnIsIGF0dHIpOwoJCQkgICAgfQoJCQkgICAgZWxzZSB7CgkJCQlUUkFDRSgib2xkIC5sbmsgZmlsZSAlcyBkaWQgbm90IGV4aXN0XG4iLAoJCQkJICAgICAgb2xkX2xua19uYW1lKTsKCQkJICAgIH0KCQkJfQoJCQllbHNlIHsKCQkJICAgIEVSUigiRGVsZXRlIGZvciAlcyBmYWlsZWQsIGF0dHI9JTA4eFxuIiwKCQkJCW9sZF9sbmtfbmFtZSwgYXR0cik7CgkJCX0KCQkgICAgfQoJCSAgICBlbHNlIHsKCQkJVFJBQ0UoImRlbGV0ZWQgb2xkIC5sbmsgZmlsZSAlc1xuIiwgb2xkX2xua19uYW1lKTsKCQkgICAgfQoJCX0KCSAgICB9Cgl9CgoJLyogQ3JlYXRlIHVzYWJsZSAubG5rIGZpbGUgbmFtZSBmb3IgdGhlICJSZWNlbnQiIGRpcmVjdG9yeQoJICovCgl3c3ByaW50ZkEobmV3X2xua19uYW1lLCAiJXMubG5rIiwgZG9jX25hbWUpOwoJbHN0cmNweUEobmV3X2xua19maWxlcGF0aCwgbGlua19kaXIpOwoJUGF0aEFwcGVuZEEobmV3X2xua19maWxlcGF0aCwgbmV3X2xua19uYW1lKTsKCWkgPSAxOwoJb2xkZXJyb3Jtb2RlID0gU2V0RXJyb3JNb2RlKFNFTV9GQUlMQ1JJVElDQUxFUlJPUlMpOwoJd2hpbGUgKEdldEZpbGVBdHRyaWJ1dGVzQShuZXdfbG5rX2ZpbGVwYXRoKSAhPSBJTlZBTElEX0ZJTEVfQVRUUklCVVRFUykgewoJICAgIGkrKzsKCSAgICB3c3ByaW50ZkEobmV3X2xua19uYW1lLCAiJXMgKCV1KS5sbmsiLCBkb2NfbmFtZSwgaSk7CgkgICAgbHN0cmNweUEobmV3X2xua19maWxlcGF0aCwgbGlua19kaXIpOwoJICAgIFBhdGhBcHBlbmRBKG5ld19sbmtfZmlsZXBhdGgsIG5ld19sbmtfbmFtZSk7Cgl9CglTZXRFcnJvck1vZGUob2xkZXJyb3Jtb2RlKTsKCVRSQUNFKCJuZXcgc2hvcnRjdXQgd2lsbCBiZSAlc1xuIiwgbmV3X2xua19maWxlcGF0aCk7CgoJLyogTm93IGFkZCB0aGUgbmV3IE1SVSBlbnRyeSBhbmQgZGF0YQoJICovCglwb3MgPSBTSEFERF9jcmVhdGVfYWRkX21ydV9kYXRhKG1ydWhhbmRsZSwgZG9jX25hbWUsIG5ld19sbmtfbmFtZSwKCQkJCQlidWZmZXIsICZsZW4pOwoJRnJlZU1SVUxpc3QobXJ1aGFuZGxlKTsKCVRSQUNFKCJVcGRhdGVkIE1SVSBsaXN0LCBuZXcgZG9jIGlzIHBvc2l0aW9uICVkXG4iLCBwb3MpOwogICAgfQoKICAgIC8qICoqKiAgSk9CIDI6IENyZWF0ZSBzaG9ydGN1dCBpbiB1c2VyJ3MgIlJlY2VudCIgZGlyZWN0b3J5ICAqKiogKi8KCiAgICB7ICAvKiBvbiBpbnB1dCBuZWVkczoKCSogICAgICBkb2NfbmFtZSAgICAtICBwdXJlIGZpbGUtc3BlYywgbm8gcGF0aAoJKiAgICAgIG5ld19sbmtfZmlsZXBhdGgKCSogICAgICAgICAgICAgICAgICAtICBwYXRoIGFuZCBmaWxlIG5hbWUgb2YgbmV3IC5sbmsgZmlsZQogCSogICAgICB1RmxhZ3NbaW5dICAtICBmbGFncyBvbiBjYWxsIHRvIFNIQWRkVG9SZWNlbnREb2NzCgkqICAgICAgcHZbaW5dICAgICAgLSAgZG9jdW1lbnQgcGF0aC9waWRsIG9uIGNhbGwgdG8gU0hBZGRUb1JlY2VudERvY3MKCSovCglJU2hlbGxMaW5rQSAqcHNsID0gTlVMTDsKCUlQZXJzaXN0RmlsZSAqcFBmID0gTlVMTDsKCUhSRVNVTFQgaHJlczsKCUNIQVIgZGVzY1tNQVhfUEFUSF07CglXQ0hBUiB3aWRlbGlua1tNQVhfUEFUSF07CgoJQ29Jbml0aWFsaXplKDApOwoKCWhyZXMgPSBDb0NyZWF0ZUluc3RhbmNlKCAmQ0xTSURfU2hlbGxMaW5rLAoJCQkJIE5VTEwsCgkJCQkgQ0xTQ1RYX0lOUFJPQ19TRVJWRVIsCgkJCQkgJklJRF9JU2hlbGxMaW5rQSwKCQkJCSAoTFBWT0lEICkmcHNsKTsKCWlmKFNVQ0NFRURFRChocmVzKSkgewoKCSAgICBocmVzID0gSVNoZWxsTGlua0FfUXVlcnlJbnRlcmZhY2UocHNsLCAmSUlEX0lQZXJzaXN0RmlsZSwKCQkJCQkgICAgIChMUFZPSUQgKikmcFBmKTsKCSAgICBpZihGQUlMRUQoaHJlcykpIHsKCQkvKiBib21iZWQgKi8KCQlFUlIoImZhaWxlZCBRdWVyeUludGVyZmFjZSBmb3IgSVBlcnNpc3RGaWxlICUwOHhcbiIsIGhyZXMpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgoJICAgIC8qIFNldCB0aGUgZG9jdW1lbnQgcGF0aCBvciBwaWRsICovCgkgICAgaWYgKHVGbGFncyA9PSBTSEFSRF9QSURMKSB7CgkJaHJlcyA9IElTaGVsbExpbmtBX1NldElETGlzdChwc2wsIChMUENJVEVNSURMSVNUKSBwdik7CgkgICAgfSBlbHNlIHsKCQlocmVzID0gSVNoZWxsTGlua0FfU2V0UGF0aChwc2wsIChMUENTVFIpIHB2KTsKCSAgICB9CgkgICAgaWYoRkFJTEVEKGhyZXMpKSB7CgkJLyogYm9tYmVkICovCgkJRVJSKCJmYWlsZWQgU2V0e0lETGlzdHxQYXRofSAlMDh4XG4iLCBocmVzKTsKCQlnb3RvIGZhaWw7CgkgICAgfQoKCSAgICBsc3RyY3B5QShkZXNjLCAiU2hvcnRjdXQgdG8gIik7CgkgICAgbHN0cmNhdEEoZGVzYywgZG9jX25hbWUpOwoJICAgIGhyZXMgPSBJU2hlbGxMaW5rQV9TZXREZXNjcmlwdGlvbihwc2wsIGRlc2MpOwoJICAgIGlmKEZBSUxFRChocmVzKSkgewoJCS8qIGJvbWJlZCAqLwoJCUVSUigiZmFpbGVkIFNldERlc2NyaXB0aW9uICUwOHhcbiIsIGhyZXMpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgoJICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBuZXdfbG5rX2ZpbGVwYXRoLCAtMSwKCQkJCXdpZGVsaW5rLCBNQVhfUEFUSCk7CgkgICAgLyogY3JlYXRlIHRoZSBzaG9ydCBjdXQgKi8KCSAgICBocmVzID0gSVBlcnNpc3RGaWxlX1NhdmUocFBmLCB3aWRlbGluaywgVFJVRSk7CgkgICAgaWYoRkFJTEVEKGhyZXMpKSB7CgkJLyogYm9tYmVkICovCgkJRVJSKCJmYWlsZWQgSVBlcnNpc3RGaWxlOjpTYXZlICUwOHhcbiIsIGhyZXMpOwoJCUlQZXJzaXN0RmlsZV9SZWxlYXNlKHBQZik7CgkJSVNoZWxsTGlua0FfUmVsZWFzZShwc2wpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgkgICAgaHJlcyA9IElQZXJzaXN0RmlsZV9TYXZlQ29tcGxldGVkKHBQZiwgd2lkZWxpbmspOwoJICAgIElQZXJzaXN0RmlsZV9SZWxlYXNlKHBQZik7CgkgICAgSVNoZWxsTGlua0FfUmVsZWFzZShwc2wpOwoJICAgIFRSQUNFKCJzaG9ydGN1dCAlcyBoYXMgYmVlbiBjcmVhdGVkLCByZXN1bHQ9JTA4eFxuIiwKCQkgIG5ld19sbmtfZmlsZXBhdGgsIGhyZXMpOwoJfQoJZWxzZSB7CgkgICAgRVJSKCJDb0NyZWF0ZUluc3RhbmNlIGZhaWxlZCwgaHJlcz0lMDh4XG4iLCBocmVzKTsKCX0KICAgIH0KCiBmYWlsOgogICAgQ29VbmluaXRpYWxpemUoKTsKCiAgICAvKiBhbGwgZG9uZSAqLwogICAgUmVnQ2xvc2VLZXkoSENVYmFzZWtleSk7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ3JlYXRlU2hlbGxGb2xkZXJWaWV3RXgJCQlbU0hFTEwzMi4xNzRdCiAqCiAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgZGVmYXVsdCBTaGVsbCBmb2xkZXIgdmlldyBvYmplY3QuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0sKICogIEZhaWx1cmU6IGVycm9yIHZhbHVlCiAqCiAqIE5PVEVTCiAqICBzZWUgSVNoZWxsRm9sZGVyOjpDcmVhdGVWaWV3T2JqZWN0CiAqLwpIUkVTVUxUIFdJTkFQSSBTSENyZWF0ZVNoZWxsRm9sZGVyVmlld0V4KAoJTFBDU0ZWIHBzdmNiaSwgICAgLyogW2luXSBzaGVsbHRlbXBsYXRlIHN0cnVjdCAqLwoJSVNoZWxsVmlldyAqKnBwdikgLyogW291dF0gSVNoZWxsVmlldyBwb2ludGVyICovCnsKCUlTaGVsbFZpZXcgKiBwc2Y7CglIUkVTVUxUIGhSZXM7CgoJVFJBQ0UoInNmPSVwIHBpZGw9JXAgY2I9JXAgbW9kZT0weCUwOHggcGFybT0lcFxuIiwKCSAgcHN2Y2JpLT5wc2hmLCBwc3ZjYmktPnBpZGwsIHBzdmNiaS0+cGZuQ2FsbGJhY2ssCgkgIHBzdmNiaS0+ZnZtLCBwc3ZjYmktPnBzdk91dGVyKTsKCglwc2YgPSBJU2hlbGxWaWV3X0NvbnN0cnVjdG9yKHBzdmNiaS0+cHNoZik7CgoJaWYgKCFwc2YpCgkgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKCUlTaGVsbFZpZXdfQWRkUmVmKHBzZik7CgloUmVzID0gSVNoZWxsVmlld19RdWVyeUludGVyZmFjZShwc2YsICZJSURfSVNoZWxsVmlldywgKExQVk9JRCAqKXBwdik7CglJU2hlbGxWaWV3X1JlbGVhc2UocHNmKTsKCglyZXR1cm4gaFJlczsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgU0hXaW5IZWxwCQkJCQlbU0hFTEwzMi4xMjddCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFdpbkhlbHAgKERXT1JEIHYsIERXT1JEIHcsIERXT1JEIHgsIERXT1JEIHopCnsJRklYTUUoIjB4JTA4eCAweCUwOHggMHglMDh4IDB4JTA4eCBzdHViXG4iLHYsdyx4LHopOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIFNIUnVuQ29udHJvbFBhbmVsIFtTSEVMTDMyLjE2MV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIUnVuQ29udHJvbFBhbmVsIChEV09SRCB4LCBEV09SRCB6KQp7CUZJWE1FKCIweCUwOHggMHglMDh4IHN0dWJcbiIseCx6KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgTFBVTktOT1dOIFNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlPTA7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2V0SW5zdGFuY2VFeHBsb3JlcgkJCVtTSEVMTDMyLjE3Nl0KICoKICogTk9URVMKICogIFNldHMgdGhlIGludGVyZmFjZQogKi8KVk9JRCBXSU5BUEkgU0hTZXRJbnN0YW5jZUV4cGxvcmVyIChMUFVOS05PV04gbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCVNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlID0gbHBVbmtub3duOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIR2V0SW5zdGFuY2VFeHBsb3JlcgkJCVtTSEVMTDMyLkBdCiAqCiAqIE5PVEVTCiAqICBnZXRzIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBvZiB0aGUgZXhwbG9yZXIgYW5kIGEgcmVmZXJlbmNlCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEdldEluc3RhbmNlRXhwbG9yZXIgKElVbmtub3duICoqbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCgkqbHBVbmtub3duID0gU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2U7CgoJaWYgKCFTSEVMTDMyX0lFeHBsb3JlckludGVyZmFjZSkKCSAgcmV0dXJuIEVfRkFJTDsKCglJVW5rbm93bl9BZGRSZWYoU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2UpOwoJcmV0dXJuIE5PRVJST1I7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGcmVlVW51c2VkTGlicmFyaWVzCQkJW1NIRUxMMzIuMTIzXQogKgogKiBQcm9iYWJseSBlcXVpdmFsZW50IHRvIENvRnJlZVVudXNlZExpYnJhcmllcyBidXQgdW5kZXIgV2luZG93cyA5eCBpdCBjb3VsZCB1c2UKICogdGhlIHNoZWxsMzIgYnVpbHQtaW4gIm1pbmktQ09NIiB3aXRob3V0IHRoZSBuZWVkIHRvIGxvYWQgb2xlMzIuZGxsIC0gc2VlIFNITG9hZE9MRQogKiBmb3IgZGV0YWlscwogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKgogKiBTRUUgQUxTTwogKiAgICAgQ29GcmVlVW51c2VkTGlicmFyaWVzLCBTSExvYWRPTEUKICovCnZvaWQgV0lOQVBJIFNIRnJlZVVudXNlZExpYnJhcmllcyAodm9pZCkKewoJRklYTUUoInN0dWJcbiIpOwoJQ29GcmVlVW51c2VkTGlicmFyaWVzKCk7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX0F1dG9TY3JvbGwJCQkJW1NIRUxMMzIuMTI5XQogKgogKi8KQk9PTCBXSU5BUEkgREFEX0F1dG9TY3JvbGwoSFdORCBod25kLCBBVVRPX1NDUk9MTF9EQVRBICpzYW1wbGVzLCBMUFBPSU5UIHB0KQp7CiAgICBGSVhNRSgiaHduZCA9ICVwICVwICVwXG4iLGh3bmQsc2FtcGxlcyxwdCk7CiAgICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfRHJhZ0VudGVyCQkJCVtTSEVMTDMyLjEzMF0KICoKICovCkJPT0wgV0lOQVBJIERBRF9EcmFnRW50ZXIoSFdORCBod25kKQp7CiAgICBGSVhNRSgiaHduZCA9ICVwXG4iLGh3bmQpOwogICAgcmV0dXJuIEZBTFNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9EcmFnRW50ZXJFeAkJCQlbU0hFTEwzMi4xMzFdCiAqCiAqLwpCT09MIFdJTkFQSSBEQURfRHJhZ0VudGVyRXgoSFdORCBod25kLCBQT0lOVCBwKQp7CiAgICBGSVhNRSgiaHduZCA9ICVwICglZCwlZClcbiIsaHduZCxwLngscC55KTsKICAgIHJldHVybiBGQUxTRTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfRHJhZ01vdmUJCQkJW1NIRUxMMzIuMTM0XQogKgogKi8KQk9PTCBXSU5BUEkgREFEX0RyYWdNb3ZlKFBPSU5UIHApCnsKICAgIEZJWE1FKCIoJWQsJWQpXG4iLHAueCxwLnkpOwogICAgcmV0dXJuIEZBTFNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9EcmFnTGVhdmUJCQkJW1NIRUxMMzIuMTMyXQogKgogKi8KQk9PTCBXSU5BUEkgREFEX0RyYWdMZWF2ZShWT0lEKQp7CiAgICBGSVhNRSgiXG4iKTsKICAgIHJldHVybiBGQUxTRTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfU2V0RHJhZ0ltYWdlCQkJCVtTSEVMTDMyLjEzNl0KICoKICogTk9URVMKICogIGV4cG9ydGVkIGJ5IG5hbWUKICovCkJPT0wgV0lOQVBJIERBRF9TZXREcmFnSW1hZ2UoCglISU1BR0VMSVNUIGhpbWxUcmFjaywKCUxQUE9JTlQgbHBwdCkKewoJRklYTUUoIiVwICVwIHN0dWJcbiIsaGltbFRyYWNrLCBscHB0KTsKICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfU2hvd0RyYWdJbWFnZQkJCQlbU0hFTEwzMi4xMzddCiAqCiAqIE5PVEVTCiAqICBleHBvcnRlZCBieSBuYW1lCiAqLwpCT09MIFdJTkFQSSBEQURfU2hvd0RyYWdJbWFnZShCT09MIGJTaG93KQp7CglGSVhNRSgiMHglMDh4IHN0dWJcbiIsYlNob3cpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBjb25zdCBXQ0hBUiBzendDYWJMb2NhdGlvbltdID0gewogICdTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywKICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLAogICdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1xcJywKICAnRScsJ3gnLCdwJywnbCcsJ28nLCdyJywnZScsJ3InLCdcXCcsCiAgJ0MnLCdhJywnYicsJ2knLCduJywnZScsJ3QnLCdTJywndCcsJ2EnLCd0JywnZScsMAp9OwoKc3RhdGljIGNvbnN0IFdDSEFSIHN6d1NldHRpbmdzW10gPSB7ICdTJywnZScsJ3QnLCd0JywnaScsJ24nLCdnJywncycsMCB9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVhZENhYmluZXRTdGF0ZQkJCQlbU0hFTEwzMi42NTFdIE5UIDQuMAogKgogKi8KQk9PTCBXSU5BUEkgUmVhZENhYmluZXRTdGF0ZShDQUJJTkVUU1RBVEUgKmNzLCBpbnQgbGVuZ3RoKQp7CglIS0VZIGhrZXkgPSAwOwoJRFdPUkQgdHlwZSwgcjsKCglUUkFDRSgiJXAgJWRcbiIsIGNzLCBsZW5ndGgpOwoKCWlmKCAoY3MgPT0gTlVMTCkgfHwgKGxlbmd0aCA8IChpbnQpc2l6ZW9mKCpjcykpICApCgkJcmV0dXJuIEZBTFNFOwoKCXIgPSBSZWdPcGVuS2V5VyggSEtFWV9DVVJSRU5UX1VTRVIsIHN6d0NhYkxvY2F0aW9uLCAmaGtleSApOwoJaWYoIHIgPT0gRVJST1JfU1VDQ0VTUyApCgl7CgkJdHlwZSA9IFJFR19CSU5BUlk7CgkJciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoIGhrZXksIHN6d1NldHRpbmdzLCAKCQkJTlVMTCwgJnR5cGUsIChMUEJZVEUpY3MsIChMUERXT1JEKSZsZW5ndGggKTsKCQlSZWdDbG9zZUtleSggaGtleSApOwoJCQkKCX0KCgkvKiBpZiB3ZSBjYW4ndCByZWFkIGZyb20gdGhlIHJlZ2lzdHJ5LCBjcmVhdGUgZGVmYXVsdCB2YWx1ZXMgKi8KCWlmICggKHIgIT0gRVJST1JfU1VDQ0VTUykgfHwgKGNzLT5jTGVuZ3RoIDwgc2l6ZW9mKCpjcykpIHx8CgkJKGNzLT5jTGVuZ3RoICE9IGxlbmd0aCkgKQoJewoJCUVSUigiSW5pdGlhbGl6aW5nIHNoZWxsIGNhYmluZXQgc2V0dGluZ3NcbiIpOwoJCW1lbXNldChjcywgMCwgc2l6ZW9mKCpjcykpOwoJCWNzLT5jTGVuZ3RoICAgICAgICAgID0gc2l6ZW9mKCpjcyk7CgkJY3MtPm5WZXJzaW9uICAgICAgICAgPSAyOwoJCWNzLT5mRnVsbFBhdGhUaXRsZSAgID0gRkFMU0U7CgkJY3MtPmZTYXZlTG9jYWxWaWV3ICAgPSBUUlVFOwoJCWNzLT5mTm90U2hlbGwgICAgICAgID0gRkFMU0U7CgkJY3MtPmZTaW1wbGVEZWZhdWx0ICAgPSBUUlVFOwoJCWNzLT5mRG9udFNob3dEZXNjQmFyID0gRkFMU0U7CgkJY3MtPmZOZXdXaW5kb3dNb2RlICAgPSBGQUxTRTsKCQljcy0+ZlNob3dDb21wQ29sb3IgICA9IEZBTFNFOwoJCWNzLT5mRG9udFByZXR0eU5hbWVzID0gRkFMU0U7CgkJY3MtPmZBZG1pbnNDcmVhdGVDb21tb25Hcm91cHMgPSBUUlVFOwoJCWNzLT5mTWVudUVudW1GaWx0ZXIgID0gOTY7Cgl9CgkKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBXcml0ZUNhYmluZXRTdGF0ZQkJCQlbU0hFTEwzMi42NTJdIE5UIDQuMAogKgogKi8KQk9PTCBXSU5BUEkgV3JpdGVDYWJpbmV0U3RhdGUoQ0FCSU5FVFNUQVRFICpjcykKewoJRFdPUkQgcjsKCUhLRVkgaGtleSA9IDA7CgoJVFJBQ0UoIiVwXG4iLGNzKTsKCglpZiggY3MgPT0gTlVMTCApCgkJcmV0dXJuIEZBTFNFOwoKCXIgPSBSZWdDcmVhdGVLZXlFeFcoIEhLRVlfQ1VSUkVOVF9VU0VSLCBzendDYWJMb2NhdGlvbiwgMCwKCQkgTlVMTCwgMCwgS0VZX0FMTF9BQ0NFU1MsIE5VTEwsICZoa2V5LCBOVUxMKTsKCWlmKCByID09IEVSUk9SX1NVQ0NFU1MgKQoJewoJCXIgPSBSZWdTZXRWYWx1ZUV4VyggaGtleSwgc3p3U2V0dGluZ3MsIDAsIAoJCQlSRUdfQklOQVJZLCAoTFBCWVRFKSBjcywgY3MtPmNMZW5ndGgpOwoKCQlSZWdDbG9zZUtleSggaGtleSApOwoJfQoKCXJldHVybiAocj09RVJST1JfU1VDQ0VTUyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEZpbGVJY29uSW5pdCAJCQkJW1NIRUxMMzIuNjYwXQogKgogKi8KQk9PTCBXSU5BUEkgRmlsZUljb25Jbml0KEJPT0wgYkZ1bGxJbml0KQp7CUZJWE1FKCIoJXMpXG4iLCBiRnVsbEluaXQgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElzVXNlckFkbWluCQkJCQlbU0hFTEwzMi42ODBdIE5UIDQuMAogKgogKi8KSFJFU1VMVCBXSU5BUEkgSXNVc2VyQWRtaW4odm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBbGxvY1NoYXJlZAkJCQlbU0hFTEwzMi41MjBdCiAqCiAqIFNlZSBzaGx3YXBpLlNIQWxsb2NTaGFyZWQKICovCkhBTkRMRSBXSU5BUEkgU0hBbGxvY1NoYXJlZChMUFZPSUQgbHB2RGF0YSwgRFdPUkQgZHdTaXplLCBEV09SRCBkd1Byb2NJZCkKewogICAgR0VUX0ZVTkMocFNIQWxsb2NTaGFyZWQsIHNobHdhcGksIChjaGFyKik3LCBOVUxMKTsKICAgIHJldHVybiBwU0hBbGxvY1NoYXJlZChscHZEYXRhLCBkd1NpemUsIGR3UHJvY0lkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hMb2NrU2hhcmVkCQkJCQlbU0hFTEwzMi41MjFdCiAqCiAqIFNlZSBzaGx3YXBpLlNITG9ja1NoYXJlZAogKi8KTFBWT0lEIFdJTkFQSSBTSExvY2tTaGFyZWQoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3UHJvY0lkKQp7CiAgICBHRVRfRlVOQyhwU0hMb2NrU2hhcmVkLCBzaGx3YXBpLCAoY2hhciopOCwgTlVMTCk7CiAgICByZXR1cm4gcFNITG9ja1NoYXJlZChoU2hhcmVkLCBkd1Byb2NJZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIVW5sb2NrU2hhcmVkCQkJCVtTSEVMTDMyLjUyMl0KICoKICogU2VlIHNobHdhcGkuU0hVbmxvY2tTaGFyZWQKICovCkJPT0wgV0lOQVBJIFNIVW5sb2NrU2hhcmVkKExQVk9JRCBscFZpZXcpCnsKICAgIEdFVF9GVU5DKHBTSFVubG9ja1NoYXJlZCwgc2hsd2FwaSwgKGNoYXIqKTksIEZBTFNFKTsKICAgIHJldHVybiBwU0hVbmxvY2tTaGFyZWQobHBWaWV3KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGcmVlU2hhcmVkCQkJCQlbU0hFTEwzMi41MjNdCiAqCiAqIFNlZSBzaGx3YXBpLlNIRnJlZVNoYXJlZAogKi8KQk9PTCBXSU5BUEkgU0hGcmVlU2hhcmVkKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd1Byb2NJZCkKewogICAgR0VUX0ZVTkMocFNIRnJlZVNoYXJlZCwgc2hsd2FwaSwgKGNoYXIqKTEwLCBGQUxTRSk7CiAgICByZXR1cm4gcFNIRnJlZVNoYXJlZChoU2hhcmVkLCBkd1Byb2NJZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNldEFwcFN0YXJ0aW5nQ3Vyc29yCQkJCVtTSEVMTDMyLjk5XQogKi8KSFJFU1VMVCBXSU5BUEkgU2V0QXBwU3RhcnRpbmdDdXJzb3IoSFdORCB1LCBEV09SRCB2KQp7CUZJWE1FKCJod25kPSVwIDB4JTA0eCBzdHViXG4iLHUsdiApOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNITG9hZE9MRQkJCQkJW1NIRUxMMzIuMTUxXQogKgogKiBUbyByZWR1Y2UgdGhlIG1lbW9yeSB1c2FnZSBvZiBXaW5kb3dzIDk1LCBpdHMgc2hlbGwzMiBjb250YWluZWQgYW4KICogaW50ZXJuYWwgaW1wbGVtZW50YXRpb24gb2YgYSBwYXJ0IG9mIENPTSAoc2VlIGUuZy4gU0hHZXRNYWxsb2MsIFNIQ29DcmVhdGVJbnN0YW5jZSwKICogU0hSZWdpc3RlckRyYWdEcm9wIGV0Yy4pIHRoYXQgYWxsb3dlZCB0byB1c2UgaW4tcHJvY2VzcyBTVEEgb2JqZWN0cyB3aXRob3V0CiAqIHRoZSBuZWVkIHRvIGxvYWQgT0xFMzIuRExMLiBJZiBPTEUzMi5ETEwgd2FzIGFscmVhZHkgbG9hZGVkLCB0aGUgU0gqIGZ1bmN0aW9uCiAqIHdvdWxkIGp1c3QgY2FsbCB0aGUgQ28qIGZ1bmN0aW9ucy4KICoKICogVGhlIFNITG9hZE9MRSB3YXMgY2FsbGVkIHdoZW4gT0xFMzIuRExMIHdhcyBiZWluZyBsb2FkZWQgdG8gdHJhbnNmZXIgYWxsIHRoZQogKiBpbmZvcm1hdGlvbiBmcm9tIHRoZSBzaGVsbDMyICJtaW5pLUNPTSIgdG8gb2xlMzIuZGxsLgogKgogKiBTZWUgaHR0cDovL2Jsb2dzLm1zZG4uY29tL29sZG5ld3RoaW5nL2FyY2hpdmUvMjAwNC8wNy8wNS8xNzMyMjYuYXNweCBmb3IgYQogKiBkZXRhaWxlZCBkZXNjcmlwdGlvbi4KICoKICogVW5kZXIgd2luZSBvbGUzMi5kbGwgaXMgYWx3YXlzIGxvYWRlZCBhcyBpdCBpcyBpbXBvcnRlZCBieSBzaGx3YXBpLmRsbCB3aGljaCBpcwogKiBpbXBvcnRlZCBieSBzaGVsbDMyIGFuZCBubyAibWluaS1DT00iIGlzIHVzZWQgKGV4Y2VwdCBmb3IgdGhlICJMb2FkV2l0aG91dENPTSIKICogaGFjayBpbiBTSENvQ3JlYXRlSW5zdGFuY2UpCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExvYWRPTEUoTFBBUkFNIGxQYXJhbSkKewlGSVhNRSgiMHglMDhseCBzdHViXG4iLGxQYXJhbSk7CglyZXR1cm4gU19PSzsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEcml2ZVR5cGUJCQkJCVtTSEVMTDMyLjY0XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgRHJpdmVUeXBlKERXT1JEIHUpCnsJRklYTUUoIjB4JTA0eCBzdHViXG4iLHUpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSW52YWxpZGF0ZURyaXZlVHlwZQkJCVtTSEVMTDMyLjY1XQogKgogKi8KaW50IFdJTkFQSSBJbnZhbGlkYXRlRHJpdmVUeXBlKGludCB1KQp7CUZJWE1FKCIweCUwOHggc3R1YlxuIix1KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQWJvcnRJbnZva2VDb21tYW5kCQkJCVtTSEVMTDMyLjE5OF0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIQWJvcnRJbnZva2VDb21tYW5kKHZvaWQpCnsJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIDE7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hPdXRPZk1lbW9yeU1lc3NhZ2VCb3gJCQlbU0hFTEwzMi4xMjZdCiAqCiAqLwppbnQgV0lOQVBJIFNIT3V0T2ZNZW1vcnlNZXNzYWdlQm94KAoJSFdORCBod25kT3duZXIsCglMUENTVFIgbHBDYXB0aW9uLAoJVUlOVCB1VHlwZSkKewoJRklYTUUoIiVwICVzIDB4JTA4eCBzdHViXG4iLGh3bmRPd25lciwgbHBDYXB0aW9uLCB1VHlwZSk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZsdXNoQ2xpcGJvYXJkCQkJCVtTSEVMTDMyLjEyMV0KICoKICovCkhSRVNVTFQgV0lOQVBJIFNIRmx1c2hDbGlwYm9hcmQodm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gMTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hXYWl0Rm9yRmlsZVRvT3BlbgkJCQlbU0hFTEwzMi45N10KICoKICovCkJPT0wgV0lOQVBJIFNIV2FpdEZvckZpbGVUb09wZW4oCglMUENJVEVNSURMSVNUIHBpZGwsCglEV09SRCBkd0ZsYWdzLAoJRFdPUkQgZHdUaW1lb3V0KQp7CglGSVhNRSgiJXAgMHglMDh4IDB4JTA4eCBzdHViXG4iLCBwaWRsLCBkd0ZsYWdzLCBkd1RpbWVvdXQpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJQAkJCQlbU0hFTEwzMi42NTRdCiAqCiAqIE5PVEVTCiAqICBmaXJzdCBwYXJhbWV0ZXIgc2VlbXMgdG8gYmUgYSBwb2ludGVyIChzYW1lIGFzIHBhc3NlZCB0byBXcml0ZUNhYmluZXRTdGF0ZSkKICogIHNlY29uZCBvbmUgY291bGQgYmUgYSBzaXplICgweDBjKS4gVGhlIHNpemUgaXMgdGhlIHNhbWUgYXMgdGhlIHN0cnVjdHVyZSBzYXZlZCB0bwogKiAgSENVXFNvZnR3YXJlXE1pY3Jvc29mdFxXaW5kb3dzXEN1cnJlbnRWZXJzaW9uXEV4cGxvcmVyXENhYmluZXRTdGF0ZQogKiAgSSdtIChqcykgZ3Vlc3Npbmc6IHRoaXMgb25lIGlzIGp1c3QgUmVhZENhYmluZXRTdGF0ZSA7LSkKICovCkhSRVNVTFQgV0lOQVBJIHNoZWxsMzJfNjU0IChDQUJJTkVUU1RBVEUgKmNzLCBpbnQgbGVuZ3RoKQp7CglUUkFDRSgiJXAgJWRcbiIsY3MsbGVuZ3RoKTsKCXJldHVybiBSZWFkQ2FiaW5ldFN0YXRlKGNzLGxlbmd0aCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUkxCdWlsZExpc3RPZlBhdGhzCQkJW1NIRUxMMzIuMTQ2XQogKgogKiBOT1RFUwogKiAgIGJ1aWxkcyBhIERQQQogKi8KRFdPUkQgV0lOQVBJIFJMQnVpbGRMaXN0T2ZQYXRocyAodm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVNIVmFsaWRhdGVVTkMJCQkJW1NIRUxMMzIuMTczXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hWYWxpZGF0ZVVOQyAoRFdPUkQgeCwgRFdPUkQgeSwgRFdPUkQgeikKewoJRklYTUUoIjB4JTA4eCAweCUwOHggMHglMDh4IHN0dWJcbiIseCx5LHopOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJRG9FbnZpcm9ubWVudFN1YnN0QQkJCVtTSEVMTDMyLkBdCiAqCiAqIFJlcGxhY2UgJUtFWVdPUkQlIGluIHRoZSBzdHIgd2l0aCB0aGUgdmFsdWUgb2YgdmFyaWFibGUgS0VZV09SRAogKiBmcm9tIGVudmlyb25tZW50LiBJZiBpdCBpcyBub3QgZm91bmQgdGhlICVLRVlXT1JEJSBpcyBsZWZ0CiAqIGludGFjdC4gSWYgdGhlIGJ1ZmZlciBpcyB0b28gc21hbGwsIHN0ciBpcyBub3QgbW9kaWZpZWQuCiAqCiAqIFBBUkFNUwogKiAgcHN6U3RyaW5nICBbSV0gJ1wwJyB0ZXJtaW5hdGVkIHN0cmluZyB3aXRoICVrZXl3b3JkJS4KICogICAgICAgICAgICAgW09dICdcMCcgdGVybWluYXRlZCBzdHJpbmcgd2l0aCAla2V5d29yZCUgc3Vic3RpdHV0ZWQuCiAqICBjY2hTdHJpbmcgIFtJXSBzaXplIG9mIHN0ci4KICoKICogUkVUVVJOUwogKiAgICAgY2NoU3RyaW5nIGxlbmd0aCBpbiB0aGUgSElXT1JEOwogKiAgICAgVFJVRSBpbiBMT1dPUkQgaWYgc3Vic3Qgd2FzIHN1Y2Nlc3NmdWwgYW5kIEZBTFNFIGluIG90aGVyIGNhc2UKICovCkRXT1JEIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RBKExQU1RSIHBzelN0cmluZywgVUlOVCBjY2hTdHJpbmcpCnsKICAgIExQU1RSIGRzdDsKICAgIEJPT0wgcmVzID0gRkFMU0U7CiAgICBGSVhNRSgiKCVzLCAlZCkgc3R1YlxuIiwgZGVidWdzdHJfYShwc3pTdHJpbmcpLCBjY2hTdHJpbmcpOwogICAgaWYgKHBzelN0cmluZyA9PSBOVUxMKSAvKiBSZWFsbHkgcmV0dXJuIDA/ICovCiAgICAgICAgcmV0dXJuIDA7CiAgICBpZiAoKGRzdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjY2hTdHJpbmcgKiBzaXplb2YoQ0hBUikpKSkKICAgIHsKICAgICAgICBEV09SRCBudW0gPSBFeHBhbmRFbnZpcm9ubWVudFN0cmluZ3NBKHBzelN0cmluZywgZHN0LCBjY2hTdHJpbmcpOwogICAgICAgIGlmIChudW0gJiYgbnVtIDwgY2NoU3RyaW5nKSAvKiBkZXN0IGJ1ZmZlciBpcyB0b28gc21hbGwgKi8KICAgICAgICB7CiAgICAgICAgICAgIHJlcyA9IFRSVUU7CiAgICAgICAgICAgIG1lbWNweShwc3pTdHJpbmcsIGRzdCwgbnVtKTsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0KTsKICAgIH0KICAgIHJldHVybiBNQUtFTE9ORyhyZXMsY2NoU3RyaW5nKTsgLyogQWx3YXlzIGNjaFN0cmluZz8gKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglEb0Vudmlyb25tZW50U3Vic3RXCQkJW1NIRUxMMzIuQF0KICoKICogU2VlIERvRW52aXJvbm1lbnRTdWJzdEEuICAKICovCkRXT1JEIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RXKExQV1NUUiBwc3pTdHJpbmcsIFVJTlQgY2NoU3RyaW5nKQp7CglGSVhNRSgiKCVzLCAlZCk6IHN0dWJcbiIsIGRlYnVnc3RyX3cocHN6U3RyaW5nKSwgY2NoU3RyaW5nKTsKCXJldHVybiBNQUtFTE9ORyhGQUxTRSxjY2hTdHJpbmcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCURvRW52aXJvbm1lbnRTdWJzdAkJCVtTSEVMTDMyLjUzXQogKgogKiBTZWUgRG9FbnZpcm9ubWVudFN1YnN0QS4gIAogKi8KRFdPUkQgV0lOQVBJIERvRW52aXJvbm1lbnRTdWJzdEFXKExQVk9JRCB4LCBVSU5UIHkpCnsKICAgIGlmIChTSEVMTF9Pc0lzVW5pY29kZSgpKQogICAgICAgIHJldHVybiBEb0Vudmlyb25tZW50U3Vic3RXKHgsIHkpOwogICAgcmV0dXJuIERvRW52aXJvbm1lbnRTdWJzdEEoeCwgeSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1NIRUxMMzIuMjQzXQogKgogKiBXaW45OCsgYnktb3JkaW5hbCByb3V0aW5lLiAgSW4gV2luOTggdGhpcyByb3V0aW5lIHJldHVybnMgemVybyBhbmQKICogZG9lcyBub3RoaW5nIGVsc2UuICBQb3NzaWJseSB0aGlzIGRvZXMgc29tZXRoaW5nIGluIE5UIG9yIFNIRUxMMzIgNS4wPwogKgogKi8KCkJPT0wgV0lOQVBJIHNoZWxsMzJfMjQzKERXT1JEIGEsIERXT1JEIGIpCnsKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hFTEwzMi43MTRdCiAqLwpEV09SRCBXSU5BUEkgU0hFTEwzMl83MTQoTFBWT0lEIHgpCnsKIAlGSVhNRSgiKCVzKXN0dWJcbiIsIGRlYnVnc3RyX3coeCkpOwoJcmV0dXJuIDA7Cn0KCnR5cGVkZWYgc3RydWN0IF9QU1hBCnsKICAgIFVJTlQgdWlDb3VudDsKICAgIFVJTlQgdWlBbGxvY2F0ZWQ7CiAgICBJU2hlbGxQcm9wU2hlZXRFeHQgKnBzcHN4WzFdOwp9IFBTWEEsICpQUFNYQTsKCnR5cGVkZWYgc3RydWN0IF9QU1hBX0NBTEwKewogICAgTFBGTkFERFBST1BTSEVFVFBBR0UgbHBmbkFkZFJlcGxhY2VXaXRoOwogICAgTFBBUkFNIGxQYXJhbTsKICAgIEJPT0wgYkNhbGxlZDsKICAgIEJPT0wgYk11bHRpcGxlOwogICAgVUlOVCB1aUNvdW50Owp9IFBTWEFfQ0FMTCwgKlBQU1hBX0NBTEw7CgpzdGF0aWMgQk9PTCBDQUxMQkFDSyBQc3hhQ2FsbChIUFJPUFNIRUVUUEFHRSBocGFnZSwgTFBBUkFNIGxQYXJhbSkKewogICAgUFBTWEFfQ0FMTCBDYWxsID0gKFBQU1hBX0NBTEwpbFBhcmFtOwoKICAgIGlmIChDYWxsICE9IE5VTEwpCiAgICB7CiAgICAgICAgaWYgKChDYWxsLT5iTXVsdGlwbGUgfHwgIUNhbGwtPmJDYWxsZWQpICYmCiAgICAgICAgICAgIENhbGwtPmxwZm5BZGRSZXBsYWNlV2l0aChocGFnZSwgQ2FsbC0+bFBhcmFtKSkKICAgICAgICB7CiAgICAgICAgICAgIENhbGwtPmJDYWxsZWQgPSBUUlVFOwogICAgICAgICAgICBDYWxsLT51aUNvdW50Kys7CiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hBZGRGcm9tUHJvcFNoZWV0RXh0QXJyYXkJW1NIRUxMMzIuMTY3XQogKi8KVUlOVCBXSU5BUEkgU0hBZGRGcm9tUHJvcFNoZWV0RXh0QXJyYXkoSFBTWEEgaHBzeGEsIExQRk5BRERQUk9QU0hFRVRQQUdFIGxwZm5BZGRQYWdlLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBQU1hBX0NBTEwgQ2FsbDsKICAgIFVJTlQgaTsKICAgIFBQU1hBIHBzeGEgPSAoUFBTWEEpaHBzeGE7CgogICAgVFJBQ0UoIiglcCwlcCwlMDhseClcbiIsIGhwc3hhLCBscGZuQWRkUGFnZSwgbFBhcmFtKTsKCiAgICBpZiAocHN4YSkKICAgIHsKICAgICAgICBaZXJvTWVtb3J5KCZDYWxsLCBzaXplb2YoQ2FsbCkpOwogICAgICAgIENhbGwubHBmbkFkZFJlcGxhY2VXaXRoID0gbHBmbkFkZFBhZ2U7CiAgICAgICAgQ2FsbC5sUGFyYW0gPSBsUGFyYW07CiAgICAgICAgQ2FsbC5iTXVsdGlwbGUgPSBUUlVFOwoKICAgICAgICAvKiBDYWxsIHRoZSBBZGRQYWdlIG1ldGhvZCBvZiBhbGwgcmVnaXN0ZXJlZCBJU2hlbGxQcm9wU2hlZXRFeHQgaW50ZXJmYWNlcyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgIT0gcHN4YS0+dWlDb3VudDsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgcHN4YS0+cHNwc3hbaV0tPmxwVnRibC0+QWRkUGFnZXMocHN4YS0+cHNwc3hbaV0sIFBzeGFDYWxsLCAoTFBBUkFNKSZDYWxsKTsKICAgICAgICB9CgogICAgICAgIHJldHVybiBDYWxsLnVpQ291bnQ7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hDcmVhdGVQcm9wU2hlZXRFeHRBcnJheQlbU0hFTEwzMi4xNjhdCiAqLwpIUFNYQSBXSU5BUEkgU0hDcmVhdGVQcm9wU2hlZXRFeHRBcnJheShIS0VZIGhLZXksIExQQ1dTVFIgcHN6U3ViS2V5LCBVSU5UIG1heF9pZmFjZSkKewogICAgcmV0dXJuIFNIQ3JlYXRlUHJvcFNoZWV0RXh0QXJyYXlFeChoS2V5LCBwc3pTdWJLZXksIG1heF9pZmFjZSwgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hDcmVhdGVQcm9wU2hlZXRFeHRBcnJheUV4CVtTSEVMTDMyLjE5NF0KICovCkhQU1hBIFdJTkFQSSBTSENyZWF0ZVByb3BTaGVldEV4dEFycmF5RXgoSEtFWSBoS2V5LCBMUENXU1RSIHBzelN1YktleSwgVUlOVCBtYXhfaWZhY2UsIElEYXRhT2JqZWN0ICpwRGF0YU9iaikKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6UHJvcFNoZWV0U3ViS2V5W10gPSB7J3MnLCdoJywnZScsJ2wnLCdsJywnZScsJ3gnLCdcXCcsJ1AnLCdyJywnbycsJ3AnLCdlJywncicsJ3QnLCd5JywnUycsJ2gnLCdlJywnZScsJ3QnLCdIJywnYScsJ24nLCdkJywnbCcsJ2UnLCdyJywncycsMH07CiAgICBXQ0hBUiBzekhhbmRsZXJbNjRdOwogICAgRFdPUkQgZHdIYW5kbGVyTGVuOwogICAgV0NIQVIgc3pDbHNpZEhhbmRsZXJbMzldOwogICAgRFdPUkQgZHdDbHNpZFNpemU7CiAgICBDTFNJRCBjbHNpZDsKICAgIExPTkcgbFJldDsKICAgIERXT1JEIGR3SW5kZXg7CiAgICBJU2hlbGxFeHRJbml0ICpwc3hpOwogICAgSVNoZWxsUHJvcFNoZWV0RXh0ICpwc3BzeDsKICAgIEhLRVkgaGtCYXNlLCBoa1Byb3BTaGVldEhhbmRsZXJzOwogICAgUFBTWEEgcHN4YSA9IE5VTEw7CgogICAgVFJBQ0UoIiglcCwlcywldSlcbiIsIGhLZXksIGRlYnVnc3RyX3cocHN6U3ViS2V5KSwgbWF4X2lmYWNlKTsKCiAgICBpZiAobWF4X2lmYWNlID09IDApCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgLyogT3BlbiB0aGUgcmVnaXN0cnkga2V5ICovCiAgICBsUmV0ID0gUmVnT3BlbktleVcoaEtleSwgcHN6U3ViS2V5LCAmaGtCYXNlKTsKICAgIGlmIChsUmV0ICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgbFJldCA9IFJlZ09wZW5LZXlFeFcoaGtCYXNlLCBzelByb3BTaGVldFN1YktleSwgMCwgS0VZX0VOVU1FUkFURV9TVUJfS0VZUywgJmhrUHJvcFNoZWV0SGFuZGxlcnMpOwogICAgUmVnQ2xvc2VLZXkoaGtCYXNlKTsKICAgIGlmIChsUmV0ID09IEVSUk9SX1NVQ0NFU1MpCiAgICB7CiAgICAgICAgLyogQ3JlYXRlIGFuZCBpbml0aWFsaXplIHRoZSBQcm9wZXJ0eSBTaGVldCBFeHRlbnNpb25zIEFycmF5ICovCiAgICAgICAgcHN4YSA9IChQUFNYQSlMb2NhbEFsbG9jKExNRU1fRklYRUQsIEZJRUxEX09GRlNFVChQU1hBLCBwc3BzeFttYXhfaWZhY2VdKSk7CiAgICAgICAgaWYgKHBzeGEpCiAgICAgICAgewogICAgICAgICAgICBaZXJvTWVtb3J5KHBzeGEsIEZJRUxEX09GRlNFVChQU1hBLCBwc3BzeFttYXhfaWZhY2VdKSk7CiAgICAgICAgICAgIHBzeGEtPnVpQWxsb2NhdGVkID0gbWF4X2lmYWNlOwoKICAgICAgICAgICAgLyogRW51bWVyYXRlIGFsbCBzdWJrZXlzIGFuZCBhdHRlbXB0IHRvIGxvYWQgdGhlIHNoZWxsIGV4dGVuc2lvbnMgKi8KICAgICAgICAgICAgZHdJbmRleCA9IDA7CiAgICAgICAgICAgIGRvCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGR3SGFuZGxlckxlbiA9IHNpemVvZihzekhhbmRsZXIpIC8gc2l6ZW9mKHN6SGFuZGxlclswXSk7CiAgICAgICAgICAgICAgICBsUmV0ID0gUmVnRW51bUtleUV4Vyhoa1Byb3BTaGVldEhhbmRsZXJzLCBkd0luZGV4KyssIHN6SGFuZGxlciwgJmR3SGFuZGxlckxlbiwgTlVMTCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgICAgICBpZiAobFJldCAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChsUmV0ID09IEVSUk9SX01PUkVfREFUQSkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CgogICAgICAgICAgICAgICAgICAgIGlmIChsUmV0ID09IEVSUk9SX05PX01PUkVfSVRFTVMpCiAgICAgICAgICAgICAgICAgICAgICAgIGxSZXQgPSBFUlJPUl9TVUNDRVNTOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGR3Q2xzaWRTaXplID0gc2l6ZW9mKHN6Q2xzaWRIYW5kbGVyKTsKICAgICAgICAgICAgICAgIGlmIChTSEdldFZhbHVlVyhoa1Byb3BTaGVldEhhbmRsZXJzLCBzekhhbmRsZXIsIE5VTEwsIE5VTEwsIHN6Q2xzaWRIYW5kbGVyLCAmZHdDbHNpZFNpemUpID09IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogRm9yY2UgYSBOVUxMLXRlcm1pbmF0aW9uIGFuZCBjb252ZXJ0IHRoZSBzdHJpbmcgKi8KICAgICAgICAgICAgICAgICAgICBzekNsc2lkSGFuZGxlclsoc2l6ZW9mKHN6Q2xzaWRIYW5kbGVyKSAvIHNpemVvZihzekNsc2lkSGFuZGxlclswXSkpIC0gMV0gPSAwOwogICAgICAgICAgICAgICAgICAgIGlmIChTVUNDRUVERUQoU0hDTFNJREZyb21TdHJpbmdXKHN6Q2xzaWRIYW5kbGVyLCAmY2xzaWQpKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEF0dGVtcHQgdG8gZ2V0IGFuIElTaGVsbFByb3BTaGVldEV4dCBhbmQgYW4gSVNoZWxsRXh0SW5pdCBpbnN0YW5jZS4KICAgICAgICAgICAgICAgICAgICAgICAgICAgT25seSBpZiBib3RoIGludGVyZmFjZXMgYXJlIHN1cHBvcnRlZCBpdCdzIGEgcmVhbCBzaGVsbCBleHRlbnNpb24uCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoZW4gY2FsbCBJU2hlbGxFeHRJbml0J3MgSW5pdGlhbGl6ZSBtZXRob2QuICovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChTVUNDRUVERUQoQ29DcmVhdGVJbnN0YW5jZSgmY2xzaWQsIE5VTEwsIENMU0NUWF9JTlBST0NfU0VSVkVSLyogfCBDTFNDVFhfTk9fQ09ERV9ET1dOTE9BRCAqLywgJklJRF9JU2hlbGxQcm9wU2hlZXRFeHQsIChMUFZPSUQgKikmcHNwc3gpKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFNVQ0NFRURFRChwc3BzeC0+bHBWdGJsLT5RdWVyeUludGVyZmFjZShwc3BzeCwgJklJRF9JU2hlbGxFeHRJbml0LCAoUFZPSUQgKikmcHN4aSkpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChTVUNDRUVERUQocHN4aS0+bHBWdGJsLT5Jbml0aWFsaXplKHBzeGksIE5VTEwsIHBEYXRhT2JqLCBoS2V5KSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBBZGQgdGhlIElTaGVsbFByb3BTaGVldEV4dCBpbnN0YW5jZSB0byB0aGUgYXJyYXkgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHN4YS0+cHNwc3hbcHN4YS0+dWlDb3VudCsrXSA9IHBzcHN4OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3hpLT5scFZ0YmwtPlJlbGVhc2UocHN4aSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzcHN4LT5scFZ0YmwtPlJlbGVhc2UocHNwc3gpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc3BzeC0+bHBWdGJsLT5SZWxlYXNlKHBzcHN4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgIH0gd2hpbGUgKHBzeGEtPnVpQ291bnQgIT0gcHN4YS0+dWlBbGxvY2F0ZWQpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIGxSZXQgPSBFUlJPUl9OT1RfRU5PVUdIX01FTU9SWTsKCiAgICAgICAgUmVnQ2xvc2VLZXkoaGtQcm9wU2hlZXRIYW5kbGVycyk7CiAgICB9CgogICAgaWYgKGxSZXQgIT0gRVJST1JfU1VDQ0VTUyAmJiBwc3hhKQogICAgewogICAgICAgIFNIRGVzdHJveVByb3BTaGVldEV4dEFycmF5KChIUFNYQSlwc3hhKTsKICAgICAgICBwc3hhID0gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gKEhQU1hBKXBzeGE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hSZXBsYWNlRnJvbVByb3BTaGVldEV4dEFycmF5CVtTSEVMTDMyLjE3MF0KICovClVJTlQgV0lOQVBJIFNIUmVwbGFjZUZyb21Qcm9wU2hlZXRFeHRBcnJheShIUFNYQSBocHN4YSwgVUlOVCB1UGFnZUlELCBMUEZOQUREUFJPUFNIRUVUUEFHRSBscGZuUmVwbGFjZVdpdGgsIExQQVJBTSBsUGFyYW0pCnsKICAgIFBTWEFfQ0FMTCBDYWxsOwogICAgVUlOVCBpOwogICAgUFBTWEEgcHN4YSA9IChQUFNYQSlocHN4YTsKCiAgICBUUkFDRSgiKCVwLCV1LCVwLCUwOGx4KVxuIiwgaHBzeGEsIHVQYWdlSUQsIGxwZm5SZXBsYWNlV2l0aCwgbFBhcmFtKTsKCiAgICBpZiAocHN4YSkKICAgIHsKICAgICAgICBaZXJvTWVtb3J5KCZDYWxsLCBzaXplb2YoQ2FsbCkpOwogICAgICAgIENhbGwubHBmbkFkZFJlcGxhY2VXaXRoID0gbHBmblJlcGxhY2VXaXRoOwogICAgICAgIENhbGwubFBhcmFtID0gbFBhcmFtOwoKICAgICAgICAvKiBDYWxsIHRoZSBSZXBsYWNlUGFnZSBtZXRob2Qgb2YgYWxsIHJlZ2lzdGVyZWQgSVNoZWxsUHJvcFNoZWV0RXh0IGludGVyZmFjZXMuCiAgICAgICAgICAgRWFjaCBzaGVsbCBleHRlbnNpb24gaXMgb25seSBhbGxvd2VkIHRvIGNhbGwgdGhlIGNhbGxiYWNrIG9uY2UgZHVyaW5nIHRoZSBjYWxsYmFjay4gKi8KICAgICAgICBmb3IgKGkgPSAwOyBpICE9IHBzeGEtPnVpQ291bnQ7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIENhbGwuYkNhbGxlZCA9IEZBTFNFOwogICAgICAgICAgICBwc3hhLT5wc3BzeFtpXS0+bHBWdGJsLT5SZXBsYWNlUGFnZShwc3hhLT5wc3BzeFtpXSwgdVBhZ2VJRCwgUHN4YUNhbGwsIChMUEFSQU0pJkNhbGwpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIENhbGwudWlDb3VudDsKICAgIH0KCiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSERlc3Ryb3lQcm9wU2hlZXRFeHRBcnJheQlbU0hFTEwzMi4xNjldCiAqLwp2b2lkIFdJTkFQSSBTSERlc3Ryb3lQcm9wU2hlZXRFeHRBcnJheShIUFNYQSBocHN4YSkKewogICAgVUlOVCBpOwogICAgUFBTWEEgcHN4YSA9IChQUFNYQSlocHN4YTsKCiAgICBUUkFDRSgiKCVwKVxuIiwgaHBzeGEpOwoKICAgIGlmIChwc3hhKQogICAgewogICAgICAgIGZvciAoaSA9IDA7IGkgIT0gcHN4YS0+dWlDb3VudDsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgcHN4YS0+cHNwc3hbaV0tPmxwVnRibC0+UmVsZWFzZShwc3hhLT5wc3BzeFtpXSk7CiAgICAgICAgfQoKICAgICAgICBMb2NhbEZyZWUoKEhMT0NBTClwc3hhKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBDSURMRGF0YV9DcmVhdGVGcm9tSURBcnJheQlbU0hFTEwzMi44M10KICoKICogIENyZWF0ZSBJRGF0YU9iamVjdCBmcm9tIFBJRExzPz8KICovCkhSRVNVTFQgV0lOQVBJIENJRExEYXRhX0NyZWF0ZUZyb21JREFycmF5KAoJTFBDSVRFTUlETElTVCBwaWRsRm9sZGVyLAoJRFdPUkQgY3BpZGxGaWxlcywKCUxQQ0lURU1JRExJU1QgKmxwcGlkbEZpbGVzLAoJTFBEQVRBT0JKRUNUICpwcGRhdGFPYmplY3QpCnsKICAgIFVJTlQgaTsKICAgIEhXTkQgaHduZCA9IDA7ICAgLypGSVhNRTogd2hvIHNob3VsZCBiZSBod25kIG9mIG93bmVyPyBzZXQgdG8gZGVza3RvcCAqLwoKICAgIFRSQUNFKCIoJXAsICVkLCAlcCwgJXApXG4iLCBwaWRsRm9sZGVyLCBjcGlkbEZpbGVzLCBscHBpZGxGaWxlcywgcHBkYXRhT2JqZWN0KTsKICAgIGlmIChUUkFDRV9PTihwaWRsKSkKICAgIHsKCXBkdW1wIChwaWRsRm9sZGVyKTsKCWZvciAoaT0wOyBpPGNwaWRsRmlsZXM7IGkrKykgcGR1bXAgKGxwcGlkbEZpbGVzW2ldKTsKICAgIH0KICAgICpwcGRhdGFPYmplY3QgPSBJRGF0YU9iamVjdF9Db25zdHJ1Y3RvciggaHduZCwgcGlkbEZvbGRlciwKCQkJCQkgICAgIGxwcGlkbEZpbGVzLCBjcGlkbEZpbGVzKTsKICAgIGlmICgqcHBkYXRhT2JqZWN0KSByZXR1cm4gU19PSzsKICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENyZWF0ZVN0ZEVudW1GbXRFdGMJCQlbU0hFTEwzMi43NF0KICoKICogTk9URVMKICoKICovCkhSRVNVTFQgV0lOQVBJIFNIQ3JlYXRlU3RkRW51bUZtdEV0YygKCURXT1JEIGNGb3JtYXRzLAoJY29uc3QgRk9STUFURVRDICpscEZvcm1hdHMsCglMUEVOVU1GT1JNQVRFVEMgKnBwZW51bUZvcm1hdGV0YykKewoJSUVudW1GT1JNQVRFVEMgKnBlZjsKCUhSRVNVTFQgaFJlczsKCVRSQUNFKCJjZj0lZCBmZT0lcCBwZWY9JXBcbiIsIGNGb3JtYXRzLCBscEZvcm1hdHMsIHBwZW51bUZvcm1hdGV0Yyk7CgoJcGVmID0gSUVudW1GT1JNQVRFVENfQ29uc3RydWN0b3IoY0Zvcm1hdHMsIGxwRm9ybWF0cyk7CglpZiAoIXBlZikKCSAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgoJSUVudW1GT1JNQVRFVENfQWRkUmVmKHBlZik7CgloUmVzID0gSUVudW1GT1JNQVRFVENfUXVlcnlJbnRlcmZhY2UocGVmLCAmSUlEX0lFbnVtRk9STUFURVRDLCAoTFBWT0lEKilwcGVudW1Gb3JtYXRldGMpOwoJSUVudW1GT1JNQVRFVENfUmVsZWFzZShwZWYpOwoKCXJldHVybiBoUmVzOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIRUxMMzJfMjU2IChTSEVMTDMyLjI1NikKICovCkhSRVNVTFQgV0lOQVBJIFNIRUxMMzJfMjU2KExQRFdPUkQgbHBkdzAsIExQRFdPUkQgbHBkdzEpCnsKICAgIEhSRVNVTFQgcmV0ID0gU19PSzsKCiAgICBGSVhNRSgic3R1YiAlcCAweCUwOHggJXBcbiIsIGxwZHcwLCBscGR3MCA/ICpscGR3MCA6IDAsIGxwZHcxKTsKCiAgICBpZiAoIWxwZHcwIHx8ICpscGR3MCAhPSAweDEwKQogICAgICAgIHJldCA9IEVfSU5WQUxJREFSRzsKICAgIGVsc2UKICAgIHsKICAgICAgICBMUFZPSUQgbHBkYXRhID0gMDsvKkxvY2FsQWxsb2MoTE1FTV9aRVJPSU5JVCwgMHg0RTQpOyovCgoJaWYgKCFscGRhdGEpCiAgICAgICAgICAgIHJldCA9IEVfT1VUT0ZNRU1PUlk7CgllbHNlCgl7CiAgICAgICAgICAgIC8qIEluaXRpYWxpemUgYW5kIHJldHVybiB1bmtub3duIGxwZGF0YSBzdHJ1Y3R1cmUgKi8KCX0KICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU0hGaW5kRmlsZXMgKFNIRUxMMzIuOTApCiAqLwpCT09MIFdJTkFQSSBTSEZpbmRGaWxlcyggTFBDSVRFTUlETElTVCBwaWRsRm9sZGVyLCBMUENJVEVNSURMSVNUIHBpZGxTYXZlRmlsZSApCnsKICAgIEZJWE1FKCIlcCAlcFxuIiwgcGlkbEZvbGRlciwgcGlkbFNhdmVGaWxlICk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSFVwZGF0ZUltYWdlVyAoU0hFTEwzMi4xOTIpCiAqCiAqIE5vdGlmaWVzIHRoZSBzaGVsbCB0aGF0IGFuIGljb24gaW4gdGhlIHN5c3RlbSBpbWFnZSBsaXN0IGhhcyBiZWVuIGNoYW5nZWQuCiAqCiAqIFBBUkFNUwogKiAgcHN6SGFzaEl0ZW0gW0ldIFBhdGggdG8gZmlsZSB0aGF0IGNvbnRhaW5zIHRoZSBpY29uLgogKiAgaUluZGV4ICAgICAgW0ldIFplcm8tYmFzZWQgaW5kZXggb2YgdGhlIGljb24gaW4gdGhlIGZpbGUuCiAqICB1RmxhZ3MgICAgICBbSV0gRmxhZ3MgZGV0ZXJtaW5pbmcgdGhlIGljb24gYXR0cmlidXRlcy4gU2VlIG5vdGVzLgogKiAgaUltYWdlSW5kZXggW0ldIEluZGV4IG9mIHRoZSBpY29uIGluIHRoZSBzeXN0ZW0gaW1hZ2UgbGlzdC4KICoKICogUkVUVVJOUwogKiAgTm90aGluZwogKgogKiBOT1RFUwogKiAgdUZsYWdzIGNhbiBiZSBvbmUgb3IgbW9yZSBvZiB0aGUgZm9sbG93aW5nIGZsYWdzOgogKiAgR0lMX05PVEZJTEVOQU1FIC0gcHN6SGFzaEl0ZW0gaXMgbm90IGEgZmlsZSBuYW1lLgogKiAgR0lMX1NJTVVMQVRFRE9DIC0gQ3JlYXRlIGEgZG9jdW1lbnQgaWNvbiB1c2luZyB0aGUgc3BlY2lmaWVkIGljb24uCiAqLwp2b2lkIFdJTkFQSSBTSFVwZGF0ZUltYWdlVyhMUENXU1RSIHBzekhhc2hJdGVtLCBpbnQgaUluZGV4LCBVSU5UIHVGbGFncywgaW50IGlJbWFnZUluZGV4KQp7CiAgICBGSVhNRSgiJXMsICVkLCAweCV4LCAlZCAtIHN0dWJcbiIsIGRlYnVnc3RyX3cocHN6SGFzaEl0ZW0pLCBpSW5kZXgsIHVGbGFncywgaUltYWdlSW5kZXgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU0hVcGRhdGVJbWFnZUEgKFNIRUxMMzIuMTkxKQogKgogKiBTZWUgU0hVcGRhdGVJbWFnZVcuCiAqLwpWT0lEIFdJTkFQSSBTSFVwZGF0ZUltYWdlQShMUENTVFIgcHN6SGFzaEl0ZW0sIElOVCBpSW5kZXgsIFVJTlQgdUZsYWdzLCBJTlQgaUltYWdlSW5kZXgpCnsKICAgIEZJWE1FKCIlcywgJWQsIDB4JXgsICVkIC0gc3R1YlxuIiwgZGVidWdzdHJfYShwc3pIYXNoSXRlbSksIGlJbmRleCwgdUZsYWdzLCBpSW1hZ2VJbmRleCk7Cn0KCklOVCBXSU5BUEkgU0hIYW5kbGVVcGRhdGVJbWFnZShMUENJVEVNSURMSVNUIHBpZGxFeHRyYSkKewogICAgRklYTUUoIiVwIC0gc3R1YlxuIiwgcGlkbEV4dHJhKTsKCiAgICByZXR1cm4gLTE7Cn0KCkJPT0wgV0lOQVBJIFNIT2JqZWN0UHJvcGVydGllcyhIV05EIGh3bmQsIERXT1JEIGR3VHlwZSwgTFBDV1NUUiBzek9iamVjdCwgTFBDV1NUUiBzelBhZ2UpCnsKICAgIEZJWE1FKCIlcCwgMHglMDh4LCAlcywgJXMgLSBzdHViXG4iLCBod25kLCBkd1R5cGUsIGRlYnVnc3RyX3coc3pPYmplY3QpLCBkZWJ1Z3N0cl93KHN6UGFnZSkpOwoKICAgIHJldHVybiBUUlVFOwp9CgpCT09MIFdJTkFQSSBTSEdldE5ld0xpbmtJbmZvQShMUENTVFIgcHN6TGlua1RvLCBMUENTVFIgcHN6RGlyLCBMUFNUUiBwc3pOYW1lLCBCT09MICpwZk11c3RDb3B5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIHVGbGFncykKewogICAgRklYTUUoIiVzLCAlcywgJXAsICVwLCAweCUwOHggLSBzdHViXG4iLCBkZWJ1Z3N0cl9hKHBzekxpbmtUbyksIGRlYnVnc3RyX2EocHN6RGlyKSwKICAgICAgICAgIHBzek5hbWUsIHBmTXVzdENvcHksIHVGbGFncyk7CgogICAgcmV0dXJuIEZBTFNFOwp9CgpCT09MIFdJTkFQSSBTSEdldE5ld0xpbmtJbmZvVyhMUENXU1RSIHBzekxpbmtUbywgTFBDV1NUUiBwc3pEaXIsIExQV1NUUiBwc3pOYW1lLCBCT09MICpwZk11c3RDb3B5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIHVGbGFncykKewogICAgRklYTUUoIiVzLCAlcywgJXAsICVwLCAweCUwOHggLSBzdHViXG4iLCBkZWJ1Z3N0cl93KHBzekxpbmtUbyksIGRlYnVnc3RyX3cocHN6RGlyKSwKICAgICAgICAgIHBzek5hbWUsIHBmTXVzdENvcHksIHVGbGFncyk7CgogICAgcmV0dXJuIEZBTFNFOwp9CgpIUkVTVUxUIFdJTkFQSSBTSFN0YXJ0TmV0Q29ubmVjdGlvbkRpYWxvZyhIV05EIGh3bmQsIExQQ1NUUiBwc3pSZW1vdGVOYW1lLCBEV09SRCBkd1R5cGUpCnsKICAgIEZJWE1FKCIlcCwgJXMsIDB4JTA4eCAtIHN0dWJcbiIsIGh3bmQsIGRlYnVnc3RyX2EocHN6UmVtb3RlTmFtZSksIGR3VHlwZSk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIFNIRW1wdHlSZWN5Y2xlQmluQShIV05EIGh3bmQsIExQQ1NUUiBwc3pSb290UGF0aCwgRFdPUkQgZHdGbGFncykKewogICAgRklYTUUoIiVwLCAlcywgMHglMDh4IC0gc3R1YlxuIiwgaHduZCwgZGVidWdzdHJfYShwc3pSb290UGF0aCksIGR3RmxhZ3MpOwoKICAgIHJldHVybiBTX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBTSEVtcHR5UmVjeWNsZUJpblcoSFdORCBod25kLCBMUENXU1RSIHBzelJvb3RQYXRoLCBEV09SRCBkd0ZsYWdzKQp7CiAgICBGSVhNRSgiJXAsICVzLCAweCUwOHggLSBzdHViXG4iLCBod25kLCBkZWJ1Z3N0cl93KHBzelJvb3RQYXRoKSwgZHdGbGFncyk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCkRXT1JEIFdJTkFQSSBTSEZvcm1hdERyaXZlKEhXTkQgaHduZCwgVUlOVCBkcml2ZSwgVUlOVCBmbXRJRCwgVUlOVCBvcHRpb25zKQp7CiAgICBGSVhNRSgiJXAsIDB4JTA4eCwgMHglMDh4LCAweCUwOHggLSBzdHViXG4iLCBod25kLCBkcml2ZSwgZm10SUQsIG9wdGlvbnMpOwoKICAgIHJldHVybiBTSEZNVF9OT0ZPUk1BVDsKfQoKSFJFU1VMVCBXSU5BUEkgU0hRdWVyeVJlY3ljbGVCaW5BKExQQ1NUUiBwc3pSb290UGF0aCwgTFBTSFFVRVJZUkJJTkZPIHBTSFF1ZXJ5UkJJbmZvKQp7CiAgICBGSVhNRSgiJXMsICVwIC0gc3R1YlxuIiwgZGVidWdzdHJfYShwc3pSb290UGF0aCksIHBTSFF1ZXJ5UkJJbmZvKTsKCiAgICBwU0hRdWVyeVJCSW5mby0+aTY0U2l6ZSA9IDA7CiAgICBwU0hRdWVyeVJCSW5mby0+aTY0TnVtSXRlbXMgPSAwOwoKICAgIHJldHVybiBTX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBTSFF1ZXJ5UmVjeWNsZUJpblcoTFBDV1NUUiBwc3pSb290UGF0aCwgTFBTSFFVRVJZUkJJTkZPIHBTSFF1ZXJ5UkJJbmZvKQp7CiAgICBGSVhNRSgiJXMsICVwIC0gc3R1YlxuIiwgZGVidWdzdHJfdyhwc3pSb290UGF0aCksIHBTSFF1ZXJ5UkJJbmZvKTsKCiAgICBwU0hRdWVyeVJCSW5mby0+aTY0U2l6ZSA9IDA7CiAgICBwU0hRdWVyeVJCSW5mby0+aTY0TnVtSXRlbXMgPSAwOwoKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgU0hTZXRMb2NhbGl6ZWROYW1lIChTSEVMTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFNldExvY2FsaXplZE5hbWUoTFBXU1RSIHBzelBhdGgsIExQQ1dTVFIgcHN6UmVzTW9kdWxlLCBpbnQgaWRzUmVzKQp7CiAgICBGSVhNRSgiJXAsICVzLCAlZCAtIHN0dWJcbiIsIHBzelBhdGgsIGRlYnVnc3RyX3cocHN6UmVzTW9kdWxlKSwgaWRzUmVzKTsKCiAgICByZXR1cm4gU19PSzsKfQo=