LyoKICogVGhlIHBhcmFtZXRlcnMgb2YgbWFueSBmdW5jdGlvbnMgY2hhbmdlcyBiZXR3ZWVuIGRpZmZlcmVudCBPUyB2ZXJzaW9ucwogKiAoTlQgdXNlcyBVbmljb2RlIHN0cmluZ3MsIDk1IHVzZXMgQVNDSUkgc3RyaW5ncykKICoKICogQ29weXJpZ2h0IDE5OTcgTWFyY3VzIE1laXNzbmVyCiAqICAgICAgICAgICAxOTk4IEr8cmdlbiBTY2htaWVkCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAic2hsZ3VpZC5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNoZWxsMzJfbWFpbi5oIgojaW5jbHVkZSAidW5kb2NzaGVsbC5oIgojaW5jbHVkZSAicGlkbC5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoc2hlbGwpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChwaWRsKTsKCi8qIEZJWE1FOiAhISEgbW92ZSBDUkVBVEVNUlVMSVNUIGFuZCBmbGFncyB0byBoZWFkZXIgZmlsZSAhISEgKi8KLyogICAgICAgICEhISBpdCBpcyBpbiBib3RoIGhlcmUgYW5kIGNvbWN0bDMydW5kb2MuYyAgICAgICEhISAqLwp0eXBlZGVmIHN0cnVjdCB0YWdDUkVBVEVNUlVMSVNUCnsKICAgIERXT1JEICBjYlNpemU7ICAgICAgICAvKiBzaXplIG9mIHN0cnVjdCAqLwogICAgRFdPUkQgIG5NYXhJdGVtczsgICAgIC8qIG1heCBuby4gb2YgaXRlbXMgaW4gbGlzdCAqLwogICAgRFdPUkQgIGR3RmxhZ3M7ICAgICAgIC8qIHNlZSBiZWxvdyAqLwogICAgSEtFWSAgIGhLZXk7ICAgICAgICAgIC8qIHJvb3QgcmVnLiBrZXkgdW5kZXIgd2hpY2ggbGlzdCBpcyBzYXZlZCAqLwogICAgTFBDU1RSIGxwc3pTdWJLZXk7ICAgIC8qIHJlZy4gc3Via2V5ICovCiAgICBQUk9DICAgbHBmbkNvbXBhcmU7ICAgLyogaXRlbSBjb21wYXJlIHByb2MgKi8KfSBDUkVBVEVNUlVMSVNUQSwgKkxQQ1JFQVRFTVJVTElTVEE7CgovKiBkd0ZsYWdzICovCiNkZWZpbmUgTVJVRl9TVFJJTkdfTElTVCAgMCAvKiBsaXN0IHdpbGwgY29udGFpbiBzdHJpbmdzICovCiNkZWZpbmUgTVJVRl9CSU5BUllfTElTVCAgMSAvKiBsaXN0IHdpbGwgY29udGFpbiBiaW5hcnkgZGF0YSAqLwojZGVmaW5lIE1SVUZfREVMQVlFRF9TQVZFIDIgLyogb25seSBzYXZlIGxpc3Qgb3JkZXIgdG8gcmVnLiBpcyBGcmVlTVJVTGlzdCAqLwoKZXh0ZXJuIEhBTkRMRSBXSU5BUEkgQ3JlYXRlTVJVTGlzdEEoTFBDUkVBVEVNUlVMSVNUQSBscGNtbCk7CmV4dGVybiBEV09SRCAgV0lOQVBJIEZyZWVNUlVMaXN0KEhBTkRMRSBoTVJVTGlzdCk7CmV4dGVybiBJTlQgICAgV0lOQVBJIEFkZE1SVURhdGEoSEFORExFIGhMaXN0LCBMUENWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhKTsKZXh0ZXJuIElOVCAgICBXSU5BUEkgRmluZE1SVURhdGEoSEFORExFIGhMaXN0LCBMUENWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhLCBMUElOVCBscFJlZ051bSk7CmV4dGVybiBJTlQgICAgV0lOQVBJIEVudW1NUlVMaXN0QShIQU5ETEUgaExpc3QsIElOVCBuSXRlbVBvcywgTFBWT0lEIGxwQnVmZmVyLCBEV09SRCBuQnVmZmVyU2l6ZSk7CgoKLyogR2V0IGEgZnVuY3Rpb24gcG9pbnRlciBmcm9tIGEgRExMIGhhbmRsZSAqLwojZGVmaW5lIEdFVF9GVU5DKGZ1bmMsIG1vZHVsZSwgbmFtZSwgZmFpbCkgXAogIGRvIHsgXAogICAgaWYgKCFmdW5jKSB7IFwKICAgICAgaWYgKCFTSEVMTDMyX2gjI21vZHVsZSAmJiAhKFNIRUxMMzJfaCMjbW9kdWxlID0gTG9hZExpYnJhcnlBKCNtb2R1bGUgIi5kbGwiKSkpIHJldHVybiBmYWlsOyBcCiAgICAgIGZ1bmMgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoU0hFTEwzMl9oIyNtb2R1bGUsIG5hbWUpOyBcCiAgICAgIGlmICghZnVuYykgcmV0dXJuIGZhaWw7IFwKICAgIH0gXAogIH0gd2hpbGUgKDApCgovKiBGdW5jdGlvbiBwb2ludGVycyBmb3IgR0VUX0ZVTkMgbWFjcm8gKi8Kc3RhdGljIEhNT0RVTEUgU0hFTEwzMl9oc2hsd2FwaT1OVUxMOwpzdGF0aWMgSEFORExFIChXSU5BUEkgKnBTSEFsbG9jU2hhcmVkKShMUENWT0lELERXT1JELERXT1JEKTsKc3RhdGljIExQVk9JRCAoV0lOQVBJICpwU0hMb2NrU2hhcmVkKShIQU5ETEUsRFdPUkQpOwpzdGF0aWMgQk9PTCAgIChXSU5BUEkgKnBTSFVubG9ja1NoYXJlZCkoTFBWT0lEKTsKc3RhdGljIEJPT0wgICAoV0lOQVBJICpwU0hGcmVlU2hhcmVkKShIQU5ETEUsRFdPUkQpOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFBhcnNlRmllbGRBCQkJCQlbaW50ZXJuYWxdCiAqCiAqIGNvcGllcyBhIGZpZWxkIGZyb20gYSAnLCcgZGVsaW1pdGVkIHN0cmluZwogKgogKiBmaXJzdCBmaWVsZCBpcyBuRmllbGQgPSAxCiAqLwpEV09SRCBXSU5BUEkgUGFyc2VGaWVsZEEoCglMUENTVFIgc3JjLAoJRFdPUkQgbkZpZWxkLAoJTFBTVFIgZHN0LAoJRFdPUkQgbGVuKQp7CglXQVJOKCIoJXMsMHglMDhseCwlcCwlbGQpIHNlbWktc3R1Yi5cbiIsZGVidWdzdHJfYShzcmMpLG5GaWVsZCxkc3QsbGVuKTsKCglpZiAoIXNyYyB8fCAhc3JjWzBdIHx8ICFkc3QgfHwgIWxlbikKCSAgcmV0dXJuIDA7CgoJLyogc2tpcCBuIGZpZWxkcyBkZWxpbWl0ZWQgYnkgJywnICovCgl3aGlsZSAobkZpZWxkID4gMSkKCXsKCSAgaWYgKCpzcmM9PSdcMCcpIHJldHVybiBGQUxTRTsKCSAgaWYgKCooc3JjKyspPT0nLCcpIG5GaWVsZC0tOwoJfQoKCS8qIGNvcHkgcGFydCB0aWxsIHRoZSBuZXh0ICcsJyB0byBkc3QgKi8KCXdoaWxlICggKnNyYyE9J1wwJyAmJiAqc3JjIT0nLCcgJiYgKGxlbi0tKT4wICkgKihkc3QrKyk9KihzcmMrKyk7CgoJLyogZmluYWxpemUgdGhlIHN0cmluZyAqLwoJKmRzdD0weDA7CgoJcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFBhcnNlRmllbGRXCQkJW2ludGVybmFsXQogKgogKiBjb3BpZXMgYSBmaWVsZCBmcm9tIGEgJywnIGRlbGltaXRlZCBzdHJpbmcKICoKICogZmlyc3QgZmllbGQgaXMgbkZpZWxkID0gMQogKi8KRFdPUkQgV0lOQVBJIFBhcnNlRmllbGRXKExQQ1dTVFIgc3JjLCBEV09SRCBuRmllbGQsIExQV1NUUiBkc3QsIERXT1JEIGxlbikKewoJV0FSTigiKCVzLDB4JTA4bHgsJXAsJWxkKSBzZW1pLXN0dWIuXG4iLCBkZWJ1Z3N0cl93KHNyYyksIG5GaWVsZCwgZHN0LCBsZW4pOwoKCWlmICghc3JjIHx8ICFzcmNbMF0gfHwgIWRzdCB8fCAhbGVuKQoJICByZXR1cm4gMDsKCgkvKiBza2lwIG4gZmllbGRzIGRlbGltaXRlZCBieSAnLCcgKi8KCXdoaWxlIChuRmllbGQgPiAxKQoJewoJICBpZiAoKnNyYyA9PSAweDApIHJldHVybiBGQUxTRTsKCSAgaWYgKCpzcmMrKyA9PSAnLCcpIG5GaWVsZC0tOwoJfQoKCS8qIGNvcHkgcGFydCB0aWxsIHRoZSBuZXh0ICcsJyB0byBkc3QgKi8KCXdoaWxlICggKnNyYyAhPSAweDAgJiYgKnNyYyAhPSAnLCcgJiYgKGxlbi0tKT4wICkgKihkc3QrKykgPSAqKHNyYysrKTsKCgkvKiBmaW5hbGl6ZSB0aGUgc3RyaW5nICovCgkqZHN0ID0gMHgwOwoKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQYXJzZUZpZWxkCQkJW1NIRUxMMzIuNThdCiAqLwpEV09SRCBXSU5BUEkgUGFyc2VGaWVsZEFXKExQQ1ZPSUQgc3JjLCBEV09SRCBuRmllbGQsIExQVk9JRCBkc3QsIERXT1JEIGxlbikKewoJaWYgKFNIRUxMX09zSXNVbmljb2RlKCkpCgkgIHJldHVybiBQYXJzZUZpZWxkVyhzcmMsIG5GaWVsZCwgZHN0LCBsZW4pOwoJcmV0dXJuIFBhcnNlRmllbGRBKHNyYywgbkZpZWxkLCBkc3QsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEdldEZpbGVOYW1lRnJvbUJyb3dzZQkJCVtTSEVMTDMyLjYzXQogKgogKi8KQk9PTCBXSU5BUEkgR2V0RmlsZU5hbWVGcm9tQnJvd3NlKAoJSFdORCBod25kT3duZXIsCglMUFNUUiBscHN0ckZpbGUsCglEV09SRCBuTWF4RmlsZSwKCUxQQ1NUUiBscHN0ckluaXRpYWxEaXIsCglMUENTVFIgbHBzdHJEZWZFeHQsCglMUENTVFIgbHBzdHJGaWx0ZXIsCglMUENTVFIgbHBzdHJUaXRsZSkKewogICAgSE1PRFVMRSBobW9kdWxlOwogICAgRkFSUFJPQyBwR2V0T3BlbkZpbGVOYW1lQTsKICAgIE9QRU5GSUxFTkFNRUEgb2ZuOwogICAgQk9PTCByZXQ7CgogICAgVFJBQ0UoIiVwLCAlcywgJWxkLCAlcywgJXMsICVzLCAlcylcbiIsCgkgIGh3bmRPd25lciwgbHBzdHJGaWxlLCBuTWF4RmlsZSwgbHBzdHJJbml0aWFsRGlyLCBscHN0ckRlZkV4dCwKCSAgbHBzdHJGaWx0ZXIsIGxwc3RyVGl0bGUpOwoKICAgIGhtb2R1bGUgPSBMb2FkTGlicmFyeUEoImNvbWRsZzMyLmRsbCIpOwogICAgaWYoIWhtb2R1bGUpIHJldHVybiBGQUxTRTsKICAgIHBHZXRPcGVuRmlsZU5hbWVBID0gR2V0UHJvY0FkZHJlc3MoaG1vZHVsZSwgIkdldE9wZW5GaWxlTmFtZUEiKTsKICAgIGlmKCFwR2V0T3BlbkZpbGVOYW1lQSkKICAgIHsKCUZyZWVMaWJyYXJ5KGhtb2R1bGUpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIG1lbXNldCgmb2ZuLCAwLCBzaXplb2Yob2ZuKSk7CgogICAgb2ZuLmxTdHJ1Y3RTaXplID0gc2l6ZW9mKG9mbik7CiAgICBvZm4uaHduZE93bmVyID0gaHduZE93bmVyOwogICAgb2ZuLmxwc3RyRmlsdGVyID0gbHBzdHJGaWx0ZXI7CiAgICBvZm4ubHBzdHJGaWxlID0gbHBzdHJGaWxlOwogICAgb2ZuLm5NYXhGaWxlID0gbk1heEZpbGU7CiAgICBvZm4ubHBzdHJJbml0aWFsRGlyID0gbHBzdHJJbml0aWFsRGlyOwogICAgb2ZuLmxwc3RyVGl0bGUgPSBscHN0clRpdGxlOwogICAgb2ZuLmxwc3RyRGVmRXh0ID0gbHBzdHJEZWZFeHQ7CiAgICBvZm4uRmxhZ3MgPSBPRk5fRVhQTE9SRVIgfCBPRk5fSElERVJFQURPTkxZIHwgT0ZOX0ZJTEVNVVNURVhJU1Q7CiAgICByZXQgPSBwR2V0T3BlbkZpbGVOYW1lQSgmb2ZuKTsKCiAgICBGcmVlTGlicmFyeShobW9kdWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIR2V0U2V0U2V0dGluZ3MJCQkJW1NIRUxMMzIuNjhdCiAqLwpWT0lEIFdJTkFQSSBTSEdldFNldFNldHRpbmdzKExQU0hFTExTVEFURSBscHNzLCBEV09SRCBkd01hc2ssIEJPT0wgYlNldCkKewogIGlmKGJTZXQpCiAgewogICAgRklYTUUoIiVwIDB4JTA4bHggVFJVRVxuIiwgbHBzcywgZHdNYXNrKTsKICB9CiAgZWxzZQogIHsKICAgIFNIR2V0U2V0dGluZ3MoKExQU0hFTExGTEFHU1RBVEUpbHBzcyxkd01hc2spOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hHZXRTZXR0aW5ncwkJCQlbU0hFTEwzMi5AXQogKgogKiBOT1RFUwogKiAgdGhlIHJlZ2lzdHJ5IHBhdGggYXJlIGZvciB3aW45OCAodGVzdGVkKQogKiAgYW5kIHBvc3NpYmx5IGFyZSB0aGUgc2FtZSBpbiBudDQwCiAqCiAqLwpWT0lEIFdJTkFQSSBTSEdldFNldHRpbmdzKExQU0hFTExGTEFHU1RBVEUgbHBzZnMsIERXT1JEIGR3TWFzaykKewoJSEtFWQloS2V5OwoJRFdPUkQJZHdEYXRhOwoJRFdPUkQJZHdEYXRhU2l6ZSA9IHNpemVvZiAoRFdPUkQpOwoKCVRSQUNFKCIoJXAgMHglMDhseClcbiIsbHBzZnMsZHdNYXNrKTsKCglpZiAoUmVnQ3JlYXRlS2V5RXhBKEhLRVlfQ1VSUkVOVF9VU0VSLCAiU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXEV4cGxvcmVyXFxBZHZhbmNlZCIsCgkJCQkgMCwgMCwgMCwgS0VZX0FMTF9BQ0NFU1MsIDAsICZoS2V5LCAwKSkKCSAgcmV0dXJuOwoKCWlmICggKFNTRl9TSE9XRVhURU5TSU9OUyAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIkhpZGVGaWxlRXh0IiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mU2hvd0V4dGVuc2lvbnMgID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICggKFNTRl9TSE9XSU5GT1RJUCAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIlNob3dJbmZvVGlwIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mU2hvd0luZm9UaXAgID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICggKFNTRl9ET05UUFJFVFRZUEFUSCAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIkRvbnRQcmV0dHlQYXRoIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mRG9udFByZXR0eVBhdGggID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICggKFNTRl9ISURFSUNPTlMgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJIaWRlSWNvbnMiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZIaWRlSWNvbnMgID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICggKFNTRl9NQVBORVREUlZCVVRUT04gJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJNYXBOZXREcnZCdG4iLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZNYXBOZXREcnZCdG4gID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICggKFNTRl9TSE9XQVRUUklCQ09MICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiU2hvd0F0dHJpYkNvbCIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+ZlNob3dBdHRyaWJDb2wgID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICgoKFNTRl9TSE9XQUxMT0JKRUNUUyB8IFNTRl9TSE9XU1lTRklMRVMpICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiSGlkZGVuIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgl7IGlmIChkd0RhdGEgPT0gMCkKCSAgeyBpZiAoU1NGX1NIT1dBTExPQkpFQ1RTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dBbGxPYmplY3RzICA9IDA7CgkgICAgaWYgKFNTRl9TSE9XU1lTRklMRVMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd1N5c0ZpbGVzICA9IDA7CgkgIH0KCSAgZWxzZSBpZiAoZHdEYXRhID09IDEpCgkgIHsgaWYgKFNTRl9TSE9XQUxMT0JKRUNUUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93QWxsT2JqZWN0cyAgPSAxOwoJICAgIGlmIChTU0ZfU0hPV1NZU0ZJTEVTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dTeXNGaWxlcyAgPSAwOwoJICB9CgkgIGVsc2UgaWYgKGR3RGF0YSA9PSAyKQoJICB7IGlmIChTU0ZfU0hPV0FMTE9CSkVDVFMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd0FsbE9iamVjdHMgID0gMDsKCSAgICBpZiAoU1NGX1NIT1dTWVNGSUxFUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93U3lzRmlsZXMgID0gMTsKCSAgfQoJfQoJUmVnQ2xvc2VLZXkgKGhLZXkpOwoKCVRSQUNFKCItLSAweCUwNHhcbiIsICooV09SRCopbHBzZnMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFNoZWxsRm9sZGVyVmlld19NZXNzYWdlCQkJW1NIRUxMMzIuNzNdCiAqCiAqIFNlbmQgYSBtZXNzYWdlIHRvIGFuIGV4cGxvcmVyIGNhYmluZXQgd2luZG93LgogKgogKiBQQVJBTVMKICogIGh3bmRDYWJpbmV0IFtJXSBUaGUgd2luZG93IGNvbnRhaW5pbmcgdGhlIHNoZWxsdmlldyB0byBjb21tdW5pY2F0ZSB3aXRoCiAqICBkd01lc3NhZ2UgICBbSV0gVGhlIFNGVk0gbWVzc2FnZSB0byBzZW5kCiAqICBkd1BhcmFtICAgICBbSV0gTWVzc2FnZSBwYXJhbWV0ZXIKICoKICogUkVUVVJOUwogKiAgZml4bWUuCiAqCiAqIE5PVEVTCiAqICBNZXNzYWdlIFNGVk1fUkVBUlJBTkdFID0gMQogKgogKiAgICBUaGlzIG1lc3NhZ2UgZ2V0cyBzZW50IHdoZW4gYSBjb2x1bW4gZ2V0cyBjbGlja2VkIHRvIGluc3RydWN0IHRoZQogKiAgICBzaGVsbCB2aWV3IHRvIHJlLXNvcnQgdGhlIGl0ZW0gbGlzdC4gZHdQYXJhbSBpZGVudGlmaWVzIHRoZSBjb2x1bW4KICogICAgdGhhdCB3YXMgY2xpY2tlZC4KICovCkxSRVNVTFQgV0lOQVBJIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UoCglIV05EIGh3bmRDYWJpbmV0LAoJVUlOVCB1TWVzc2FnZSwKCUxQQVJBTSBsUGFyYW0pCnsKCUZJWE1FKCIlcCAlMDh4ICUwOGx4IHN0dWJcbiIsaHduZENhYmluZXQsIHVNZXNzYWdlLCBsUGFyYW0pOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ2lzdGVyU2hlbGxIb29rCQkJCVtTSEVMTDMyLjE4MV0KICoKICogUmVnaXN0ZXIgYSBzaGVsbCBob29rLgogKgogKiBQQVJBTVMKICogICAgICBod25kICAgW0ldICBXaW5kb3cgaGFuZGxlCiAqICAgICAgZHdUeXBlIFtJXSAgVHlwZSBvZiBob29rLgogKgogKiBOT1RFUwogKiAgICAgRXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KQk9PTCBXSU5BUEkgUmVnaXN0ZXJTaGVsbEhvb2soCglIV05EIGhXbmQsCglEV09SRCBkd1R5cGUpCnsKCUZJWE1FKCIoJXAsMHglMDhseCk6c3R1Yi5cbiIsaFduZCwgZHdUeXBlKTsKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTaGVsbE1lc3NhZ2VCb3hXCQkJCVtTSEVMTDMyLjE4Ml0KICoKICogU2VlIFNoZWxsTWVzc2FnZUJveEEuCiAqLwppbnQgV0lOQVBJViBTaGVsbE1lc3NhZ2VCb3hXKAoJSElOU1RBTkNFIGhJbnN0YW5jZSwKCUhXTkQgaFduZCwKCUxQQ1dTVFIgbHBUZXh0LAoJTFBDV1NUUiBscENhcHRpb24sCglVSU5UIHVUeXBlLAoJLi4uKQp7CglXQ0hBUglzelRleHRbMTAwXSxzelRpdGxlWzEwMF07CglMUENXU1RSIHBzelRleHQgPSBzelRleHQsIHBzelRpdGxlID0gc3pUaXRsZSwgcHN6VGVtcDsKCXZhX2xpc3QgYXJnczsKCWludAlyZXQ7CgoJdmFfc3RhcnQoYXJncywgdVR5cGUpOwoJLyogd3ZzcHJpbnRmQShidWYsZm10LCBhcmdzKTsgKi8KCglUUkFDRSgiKCUwOGx4LCUwOGx4LCVwLCVwLCUwOHgpXG4iLAoJKERXT1JEKWhJbnN0YW5jZSwoRFdPUkQpaFduZCxscFRleHQsbHBDYXB0aW9uLHVUeXBlKTsKCglpZiAoIUhJV09SRChscENhcHRpb24pKQoJICBMb2FkU3RyaW5nVyhoSW5zdGFuY2UsIChEV09SRClscENhcHRpb24sIHN6VGl0bGUsIHNpemVvZihzelRpdGxlKS9zaXplb2Yoc3pUaXRsZVswXSkpOwoJZWxzZQoJICBwc3pUaXRsZSA9IGxwQ2FwdGlvbjsKCglpZiAoIUhJV09SRChscFRleHQpKQoJICBMb2FkU3RyaW5nVyhoSW5zdGFuY2UsIChEV09SRClscFRleHQsIHN6VGV4dCwgc2l6ZW9mKHN6VGV4dCkvc2l6ZW9mKHN6VGV4dFswXSkpOwoJZWxzZQoJICBwc3pUZXh0ID0gbHBUZXh0OwoKCUZvcm1hdE1lc3NhZ2VXKEZPUk1BVF9NRVNTQUdFX0FMTE9DQVRFX0JVRkZFUiB8IEZPUk1BVF9NRVNTQUdFX0ZST01fU1RSSU5HLAoJCSAgICAgICBwc3pUZXh0LCAwLCAwLCAoTFBXU1RSKSZwc3pUZW1wLCAwLCAmYXJncyk7CgoJdmFfZW5kKGFyZ3MpOwoKCXJldCA9IE1lc3NhZ2VCb3hXKGhXbmQscHN6VGVtcCxwc3pUaXRsZSx1VHlwZSk7CglMb2NhbEZyZWUoKEhMT0NBTClwc3pUZW1wKTsKCXJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsTWVzc2FnZUJveEEJCQkJW1NIRUxMMzIuMTgzXQogKgogKiBGb3JtYXQgYW5kIG91dHB1dCBhbiBlcnJvciBtZXNzYWdlLgogKgogKiBQQVJBTVMKICogIGhJbnN0YW5jZSBbSV0gSW5zdGFuY2UgaGFuZGxlIG9mIG1lc3NhZ2UgY3JlYXRvcgogKiAgaFduZCAgICAgIFtJXSBXaW5kb3cgaGFuZGxlIG9mIG1lc3NhZ2UgY3JlYXRvcgogKiAgbHBUZXh0ICAgIFtJXSBSZXNvdXJjZSBJZCBvZiB0aXRsZSBvciBMUFNUUgogKiAgbHBDYXB0aW9uIFtJXSBSZXNvdXJjZSBJZCBvZiB0aXRsZSBvciBMUFNUUgogKiAgdVR5cGUgICAgIFtJXSBUeXBlIG9mIGVycm9yIG1lc3NhZ2UKICoKICogUkVUVVJOUwogKiAgQSByZXR1cm4gdmFsdWUgZnJvbSBNZXNzYWdlQm94QSgpLgogKgogKiBOT1RFUwogKiAgICAgRXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KaW50IFdJTkFQSVYgU2hlbGxNZXNzYWdlQm94QSgKCUhJTlNUQU5DRSBoSW5zdGFuY2UsCglIV05EIGhXbmQsCglMUENTVFIgbHBUZXh0LAoJTFBDU1RSIGxwQ2FwdGlvbiwKCVVJTlQgdVR5cGUsCgkuLi4pCnsKCWNoYXIJc3pUZXh0WzEwMF0sc3pUaXRsZVsxMDBdOwoJTFBDU1RSICBwc3pUZXh0ID0gc3pUZXh0LCBwc3pUaXRsZSA9IHN6VGl0bGUsIHBzelRlbXA7Cgl2YV9saXN0IGFyZ3M7CglpbnQJcmV0OwoKCXZhX3N0YXJ0KGFyZ3MsIHVUeXBlKTsKCS8qIHd2c3ByaW50ZkEoYnVmLGZtdCwgYXJncyk7ICovCgoJVFJBQ0UoIiglMDhseCwlMDhseCwlcCwlcCwlMDh4KVxuIiwKCShEV09SRCloSW5zdGFuY2UsKERXT1JEKWhXbmQsbHBUZXh0LGxwQ2FwdGlvbix1VHlwZSk7CgoJaWYgKCFISVdPUkQobHBDYXB0aW9uKSkKCSAgTG9hZFN0cmluZ0EoaEluc3RhbmNlLCAoRFdPUkQpbHBDYXB0aW9uLCBzelRpdGxlLCBzaXplb2Yoc3pUaXRsZSkpOwoJZWxzZQoJICBwc3pUaXRsZSA9IGxwQ2FwdGlvbjsKCglpZiAoIUhJV09SRChscFRleHQpKQoJICBMb2FkU3RyaW5nQShoSW5zdGFuY2UsIChEV09SRClscFRleHQsIHN6VGV4dCwgc2l6ZW9mKHN6VGV4dCkpOwoJZWxzZQoJICBwc3pUZXh0ID0gbHBUZXh0OwoKCUZvcm1hdE1lc3NhZ2VBKEZPUk1BVF9NRVNTQUdFX0FMTE9DQVRFX0JVRkZFUiB8IEZPUk1BVF9NRVNTQUdFX0ZST01fU1RSSU5HLAoJCSAgICAgICBwc3pUZXh0LCAwLCAwLCAoTFBTVFIpJnBzelRlbXAsIDAsICZhcmdzKTsKCgl2YV9lbmQoYXJncyk7CgoJcmV0ID0gTWVzc2FnZUJveEEoaFduZCxwc3pUZW1wLHBzelRpdGxlLHVUeXBlKTsKCUxvY2FsRnJlZSgoSExPQ0FMKXBzelRlbXApOwoJcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZWdpc3RlckRyYWdEcm9wCQkJCVtTSEVMTDMyLjg2XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZWdpc3RlckRyYWdEcm9wKAoJSFdORCBoV25kLAoJTFBEUk9QVEFSR0VUIHBEcm9wVGFyZ2V0KQp7CglGSVhNRSgiKCVwLCVwKTpzdHViLlxuIiwgaFduZCwgcERyb3BUYXJnZXQpOwoJcmV0dXJuIFJlZ2lzdGVyRHJhZ0Ryb3AoaFduZCwgcERyb3BUYXJnZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJldm9rZURyYWdEcm9wCQkJCVtTSEVMTDMyLjg3XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZXZva2VEcmFnRHJvcChIV05EIGhXbmQpCnsKICAgIEZJWE1FKCIoJXApOnN0dWIuXG4iLGhXbmQpOwogICAgcmV0dXJuIFJldm9rZURyYWdEcm9wKGhXbmQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSERvRHJhZ0Ryb3AJCQkJCVtTSEVMTDMyLjg4XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KSFJFU1VMVCBXSU5BUEkgU0hEb0RyYWdEcm9wKAoJSFdORCBoV25kLAoJTFBEQVRBT0JKRUNUIGxwRGF0YU9iamVjdCwKCUxQRFJPUFNPVVJDRSBscERyb3BTb3VyY2UsCglEV09SRCBkd09LRWZmZWN0LAoJTFBEV09SRCBwZHdFZmZlY3QpCnsKICAgIEZJWE1FKCIoJXAgJXAgJXAgMHglMDhseCAlcCk6c3R1Yi5cbiIsCiAgICBoV25kLCBscERhdGFPYmplY3QsIGxwRHJvcFNvdXJjZSwgZHdPS0VmZmVjdCwgcGR3RWZmZWN0KTsKCXJldHVybiBEb0RyYWdEcm9wKGxwRGF0YU9iamVjdCwgbHBEcm9wU291cmNlLCBkd09LRWZmZWN0LCBwZHdFZmZlY3QpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBcnJhbmdlV2luZG93cwkJCQlbU0hFTEwzMi4xODRdCiAqCiAqLwpXT1JEIFdJTkFQSSBBcnJhbmdlV2luZG93cygKCUhXTkQgaHduZFBhcmVudCwKCURXT1JEIGR3UmVzZXJ2ZWQsCglMUENSRUNUIGxwUmVjdCwKCVdPUkQgY0tpZHMsCglDT05TVCBIV05EICogbHBLaWRzKQp7CiAgICBGSVhNRSgiKCVwIDB4JTA4bHggJXAgMHglMDR4ICVwKTpzdHViLlxuIiwKCSAgIGh3bmRQYXJlbnQsIGR3UmVzZXJ2ZWQsIGxwUmVjdCwgY0tpZHMsIGxwS2lkcyk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2lnbmFsRmlsZU9wZW4JCQkJW1NIRUxMMzIuMTAzXQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KRFdPUkQgV0lOQVBJClNpZ25hbEZpbGVPcGVuIChEV09SRCBkd1BhcmFtMSkKewogICAgRklYTUUoIigweCUwOGx4KTpzdHViLlxuIiwgZHdQYXJhbTEpOwoKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFERF9nZXRfcG9saWN5IC0gaGVscGVyIGZ1bmN0aW9uIGZvciBTSEFkZFRvUmVjZW50RG9jcwogKgogKiBQQVJBTUVURVJTCiAqICAgcG9saWN5ICAgIFtJTl0gIHBvbGljeSBuYW1lIChudWxsIHRlcm1lZCBzdHJpbmcpIHRvIGZpbmQKICogICB0eXBlICAgICAgW09VVF0gcHRyIHRvIERXT1JEIHRvIHJlY2VpdmUgdHlwZQogKiAgIGJ1ZmZlciAgICBbT1VUXSBwdHIgdG8gYXJlYSB0byBob2xkIGRhdGEgcmV0cmlldmVkCiAqICAgbGVuICAgICAgIFtJTi9PVVRdIHB0ciB0byBEV09SRCBob2xkaW5nIHNpemUgb2YgYnVmZmVyIGFuZCBnZXR0aW5nCiAqICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCBmaWxsZWQKICoKICogUkVUVVJOUwogKiAgIHJlc3VsdCBvZiB0aGUgU0hRdWVyeVZhbHVlRXggY2FsbAogKi8Kc3RhdGljIElOVCBTSEFERF9nZXRfcG9saWN5KExQU1RSIHBvbGljeSwgTFBEV09SRCB0eXBlLCBMUFZPSUQgYnVmZmVyLCBMUERXT1JEIGxlbikKewogICAgSEtFWSBQb2xpY3lfYmFzZWtleTsKICAgIElOVCByZXQ7CgogICAgLyogR2V0IHRoZSBrZXkgZm9yIHRoZSBwb2xpY2llcyBsb2NhdGlvbiBpbiB0aGUgcmVnaXN0cnkKICAgICAqLwogICAgaWYgKFJlZ09wZW5LZXlFeEEoSEtFWV9MT0NBTF9NQUNISU5FLAoJCSAgICAgICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50VmVyc2lvblxcUG9saWNpZXNcXEV4cGxvcmVyIiwKCQkgICAgICAwLCBLRVlfUkVBRCwgJlBvbGljeV9iYXNla2V5KSkgewoKCWlmIChSZWdPcGVuS2V5RXhBKEhLRVlfQ1VSUkVOVF9VU0VSLAoJCQkgICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50VmVyc2lvblxcUG9saWNpZXNcXEV4cGxvcmVyIiwKCQkJICAwLCBLRVlfUkVBRCwgJlBvbGljeV9iYXNla2V5KSkgewoJICAgIFRSQUNFKCJObyBFeHBsb3JlciBQb2xpY2llcyBsb2NhdGlvbiBleGlzdHMuIFBvbGljeSB3YW50ZWQ9JXNcbiIsCgkJICBwb2xpY3kpOwoJICAgICpsZW4gPSAwOwoJICAgIHJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKCX0KICAgIH0KCiAgICAvKiBSZXRyaWV2ZSB0aGUgZGF0YSBpZiBpdCBleGlzdHMKICAgICAqLwogICAgcmV0ID0gU0hRdWVyeVZhbHVlRXhBKFBvbGljeV9iYXNla2V5LCBwb2xpY3ksIDAsIHR5cGUsIGJ1ZmZlciwgbGVuKTsKICAgIFJlZ0Nsb3NlS2V5KFBvbGljeV9iYXNla2V5KTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFERF9jb21wYXJlX21ydSAtIGhlbHBlciBmdW5jdGlvbiBmb3IgU0hBZGRUb1JlY2VudERvY3MKICoKICogUEFSQU1FVEVSUwogKiAgIGRhdGExICAgICBbSU5dIGRhdGEgYmVpbmcgbG9va2VkIGZvcgogKiAgIGRhdGEyICAgICBbSU5dIGRhdGEgaW4gTVJVCiAqICAgY2JkYXRhICAgIFtJTl0gbGVuZ3RoIGZyb20gRmluZE1SVURhdGEgY2FsbCAobm90IHVzZWQpCiAqCiAqIFJFVFVSTlMKICogICBwb3NpdGlvbiB3aXRoaW4gTVJVIGxpc3QgdGhhdCBkYXRhIHdhcyBhZGRlZC4KICovCnN0YXRpYyBJTlQgQ0FMTEJBQ0sgU0hBRERfY29tcGFyZV9tcnUoTFBDVk9JRCBkYXRhMSwgTFBDVk9JRCBkYXRhMiwgRFdPUkQgY2JEYXRhKQp7CiAgICByZXR1cm4gbHN0cmNtcGlBKGRhdGExLCBkYXRhMik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQUREX2NyZWF0ZV9hZGRfbXJ1X2RhdGEgLSBoZWxwZXIgZnVuY3Rpb24gZm9yIFNIQWRkVG9SZWNlbnREb2NzCiAqCiAqIFBBUkFNRVRFUlMKICogICBtcnVoYW5kbGUgICAgW0lOXSBoYW5kbGUgZm9yIGNyZWF0ZWQgTVJVIGxpc3QKICogICBkb2NfbmFtZSAgICAgW0lOXSBudWxsIHRlcm1lZCBwdXJlIGRvYyBuYW1lCiAqICAgbmV3X2xua19uYW1lIFtJTl0gbnVsbCB0ZXJtZWQgcGF0aCBhbmQgZmlsZSBuYW1lIGZvciAubG5rIGZpbGUKICogICBidWZmZXIgICAgICAgW0lOL09VVF0gMjA0OCBieXRlIGFyZWEgdG8gY29uc3RydWN0IE1SVSBkYXRhCiAqICAgbGVuICAgICAgICAgIFtPVVRdIHB0ciB0byBpbnQgdG8gcmVjZWl2ZSBzcGFjZSB1c2VkIGluIGJ1ZmZlcgogKgogKiBSRVRVUk5TCiAqICAgcG9zaXRpb24gd2l0aGluIE1SVSBsaXN0IHRoYXQgZGF0YSB3YXMgYWRkZWQuCiAqLwpzdGF0aWMgSU5UIFNIQUREX2NyZWF0ZV9hZGRfbXJ1X2RhdGEoSEFORExFIG1ydWhhbmRsZSwgTFBTVFIgZG9jX25hbWUsIExQU1RSIG5ld19sbmtfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGJ1ZmZlciwgSU5UICpsZW4pCnsKICAgIExQU1RSIHB0cjsKICAgIElOVCB3bGVuOwoKICAgIC8qRklYTUU6IERvY3VtZW50OgogICAgICogIFJlY2VudERvY3MgTVJVIGRhdGEgc3RydWN0dXJlIHNlZW1zIHRvIGJlOgogICAgICogICAgKzBoICAgZG9jdW1lbnQgZmlsZSBuYW1lIHcvIHRlcm1pbmF0aW5nIDBoCiAgICAgKiAgICArbmggICBzaG9ydCBpbnQgdy8gc2l6ZSBvZiByZW1haW5pbmcKICAgICAqICAgICtuKzJoIDAyaCAzMGgsIG9yIDAxaCAzMGgsIG9yIDAwaCAzMGggIC0gIHVua25vd24KICAgICAqICAgICtuKzRoIDEwIGJ5dGVzIHplcm9zICAtICAgdW5rbm93bgogICAgICogICAgK24rZWggc2hvcnRjdXQgZmlsZSBuYW1lIHcvIHRlcm1pbmF0aW5nIDBoCiAgICAgKiAgICArbitlK25oIDMgemVybyBieXRlcyAgLSAgdW5rbm93bgogICAgICovCgogICAgLyogQ3JlYXRlIHRoZSBNUlUgZGF0YSBzdHJ1Y3R1cmUgZm9yICJSZWNlbnREb2NzIgoJICovCiAgICBwdHIgPSBidWZmZXI7CiAgICBsc3RyY3B5QShwdHIsIGRvY19uYW1lKTsKICAgIHB0ciArPSAobHN0cmxlbkEoYnVmZmVyKSArIDEpOwogICAgd2xlbj0gbHN0cmxlbkEobmV3X2xua19uYW1lKSArIDEgKyAxMjsKICAgICooKHNob3J0IGludCopcHRyKSA9IHdsZW47CiAgICBwdHIgKz0gMjsgICAvKiBzdGVwIHBhc3QgdGhlIGxlbmd0aCAqLwogICAgKihwdHIrKykgPSAweDMwOyAgLyogdW5rbm93biByZWFzb24gKi8KICAgICoocHRyKyspID0gMDsgICAgIC8qIHVua25vd24sIGJ1dCBjYW4gYmUgMHgwMCwgMHgwMSwgMHgwMiAqLwogICAgbWVtc2V0KHB0ciwgMCwgMTApOwogICAgcHRyICs9IDEwOwogICAgbHN0cmNweUEocHRyLCBuZXdfbG5rX25hbWUpOwogICAgcHRyICs9IChsc3RybGVuQShuZXdfbG5rX25hbWUpICsgMSk7CiAgICBtZW1zZXQocHRyLCAwLCAzKTsKICAgIHB0ciArPSAzOwogICAgKmxlbiA9IHB0ciAtIGJ1ZmZlcjsKCiAgICAvKiBBZGQgdGhlIG5ldyBlbnRyeSBpbnRvIHRoZSBNUlUgbGlzdAogICAgICovCiAgICByZXR1cm4gQWRkTVJVRGF0YShtcnVoYW5kbGUsIChMUENWT0lEKWJ1ZmZlciwgKmxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQWRkVG9SZWNlbnREb2NzCQkJCVtTSEVMTDMyLkBdCiAqCiAqIFBBUkFNRVRFUlMKICogICB1RmxhZ3MgIFtJTl0gU0hBUkRfUEFUSCBvciBTSEFSRF9QSURMCiAqICAgcHYgICAgICBbSU5dIHN0cmluZyBvciBwaWRsLCBOVUxMIGNsZWFycyB0aGUgbGlzdAogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgbmFtZQogKi8Kdm9pZCBXSU5BUEkgU0hBZGRUb1JlY2VudERvY3MgKFVJTlQgdUZsYWdzLExQQ1ZPSUQgcHYpCnsKLyogSWYgbGlzdCBpcyBhIHN0cmluZyBsaXN0IGxwZm5Db21wYXJlIGhhcyB0aGUgZm9sbG93aW5nIHByb3RvdHlwZQogKiBpbnQgQ0FMTEJBQ0sgTVJVQ29tcGFyZVN0cmluZyhMUENTVFIgczEsIExQQ1NUUiBzMikKICogZm9yIGJpbmFyeSBsaXN0cyB0aGUgcHJvdG90eXBlIGlzCiAqIGludCBDQUxMQkFDSyBNUlVDb21wYXJlQmluYXJ5KExQQ1ZPSUQgZGF0YTEsIExQQ1ZPSUQgZGF0YTIsIERXT1JEIGNiRGF0YSkKICogd2hlcmUgY2JEYXRhIGlzIHRoZSBuby4gb2YgYnl0ZXMgdG8gY29tcGFyZS4KICogTmVlZCB0byBjaGVjayB3aGF0IHJldHVybiB2YWx1ZSBtZWFucyBpZGVudGljYWwgLSAwPwogKi8KCgogICAgVUlOVCBvbGRlcnJvcm1vZGU7CiAgICBIS0VZIEhDVWJhc2VrZXk7CiAgICBDSEFSIGRvY19uYW1lW01BWF9QQVRIXTsKICAgIENIQVIgbGlua19kaXJbTUFYX1BBVEhdOwogICAgQ0hBUiBuZXdfbG5rX2ZpbGVwYXRoW01BWF9QQVRIXTsKICAgIENIQVIgbmV3X2xua19uYW1lW01BWF9QQVRIXTsKICAgIElNYWxsb2MgKnBwTTsKICAgIExQSVRFTUlETElTVCBwaWRsOwogICAgSFdORCBod25kID0gMDsgICAgICAgLyogRklYTUU6ICBnZXQgcmVhbCB3aW5kb3cgaGFuZGxlICovCiAgICBJTlQgcmV0OwogICAgRFdPUkQgZGF0YVs2NF0sIGRhdGFsZW4sIHR5cGU7CgogICAgLypGSVhNRTogRG9jdW1lbnQ6CiAgICAgKiAgUmVjZW50RG9jcyBNUlUgZGF0YSBzdHJ1Y3R1cmUgc2VlbXMgdG8gYmU6CiAgICAgKiAgICArMGggICBkb2N1bWVudCBmaWxlIG5hbWUgdy8gdGVybWluYXRpbmcgMGgKICAgICAqICAgICtuaCAgIHNob3J0IGludCB3LyBzaXplIG9mIHJlbWFpbmluZwogICAgICogICAgK24rMmggMDJoIDMwaCwgb3IgMDFoIDMwaCwgb3IgMDBoIDMwaCAgLSAgdW5rbm93bgogICAgICogICAgK24rNGggMTAgYnl0ZXMgemVyb3MgIC0gICB1bmtub3duCiAgICAgKiAgICArbitlaCBzaG9ydGN1dCBmaWxlIG5hbWUgdy8gdGVybWluYXRpbmcgMGgKICAgICAqICAgICtuK2UrbmggMyB6ZXJvIGJ5dGVzICAtICB1bmtub3duCiAgICAgKi8KCiAgICAvKiBTZWUgaWYgd2UgbmVlZCB0byBkbyBhbnl0aGluZy4KICAgICAqLwogICAgZGF0YWxlbiA9IDY0OwogICAgcmV0PVNIQUREX2dldF9wb2xpY3koICJOb1JlY2VudERvY3NIaXN0b3J5IiwgJnR5cGUsICZkYXRhLCAmZGF0YWxlbik7CiAgICBpZiAoKHJldCA+IDApICYmIChyZXQgIT0gRVJST1JfRklMRV9OT1RfRk9VTkQpKSB7CglFUlIoIkVycm9yICVkIGdldHRpbmcgcG9saWN5IFwiTm9SZWNlbnREb2NzSGlzdG9yeVwiXG4iLCByZXQpOwoJcmV0dXJuOwogICAgfQogICAgaWYgKHJldCA9PSBFUlJPUl9TVUNDRVNTKSB7CglpZiAoISggKHR5cGUgPT0gUkVHX0RXT1JEKSB8fAoJICAgICAgICgodHlwZSA9PSBSRUdfQklOQVJZKSAmJiAoZGF0YWxlbiA9PSA0KSkgKSkgewoJICAgIEVSUigiRXJyb3IgcG9saWN5IGRhdGEgZm9yIFwiTm9SZWNlbnREb2NzSGlzdG9yeVwiIG5vdCBmb3JtYXR0ZWQgY29ycmVjdGx5LCB0eXBlPSVsZCwgbGVuPSVsZFxuIiwKCQl0eXBlLCBkYXRhbGVuKTsKCSAgICByZXR1cm47Cgl9CgoJVFJBQ0UoInBvbGljeSB2YWx1ZSBmb3IgTm9SZWNlbnREb2NzSGlzdG9yeSA9ICUwOGx4XG4iLCBkYXRhWzBdKTsKCS8qIG5vdyB0ZXN0IHRoZSBhY3R1YWwgcG9saWN5IHZhbHVlICovCglpZiAoIGRhdGFbMF0gIT0gMCkKCSAgICByZXR1cm47CiAgICB9CgogICAgLyogT3BlbiBrZXkgdG8gd2hlcmUgdGhlIG5lY2Vzc2FyeSBpbmZvIGlzCiAgICAgKi8KICAgIC8qIEZJWE1FOiBUaGlzIHNob3VsZCBiZSBkb25lIGR1cmluZyBETEwgUFJPQ0VTU19BVFRBQ0ggKG9yIFRIUkVBRF9BVFRBQ0gpCiAgICAgKiAgICAgICAgYW5kIHRoZSBjbG9zZSBzaG91bGQgYmUgZG9uZSBkdXJpbmcgdGhlIF9ERVRBQ0guIFRoZSByZXN1bHRpbmcKICAgICAqICAgICAgICBrZXkgaXMgc3RvcmVkIGluIHRoZSBETEwgZ2xvYmFsIGRhdGEuCiAgICAgKi8KICAgIGlmIChSZWdDcmVhdGVLZXlFeEEoSEtFWV9DVVJSRU5UX1VTRVIsCgkJCSJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50VmVyc2lvblxcRXhwbG9yZXIiLAoJCQkwLCAwLCAwLCBLRVlfUkVBRCwgMCwgJkhDVWJhc2VrZXksIDApKSB7CglFUlIoIkZhaWxlZCB0byBjcmVhdGUgJ1NvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxFeHBsb3JlcidcbiIpOwoJcmV0dXJuOwogICAgfQoKICAgIC8qIEdldCBwYXRoIHRvIHVzZXIncyAiUmVjZW50IiBkaXJlY3RvcnkKICAgICAqLwogICAgaWYoU1VDQ0VFREVEKFNIR2V0TWFsbG9jKCZwcE0pKSkgewoJaWYgKFNVQ0NFRURFRChTSEdldFNwZWNpYWxGb2xkZXJMb2NhdGlvbihod25kLCBDU0lETF9SRUNFTlQsCgkJCQkJCSAmcGlkbCkpKSB7CgkgICAgU0hHZXRQYXRoRnJvbUlETGlzdEEocGlkbCwgbGlua19kaXIpOwoJICAgIElNYWxsb2NfRnJlZShwcE0sIHBpZGwpOwoJfQoJZWxzZSB7CgkgICAgLyogc2VyaW91cyBpc3N1ZXMgKi8KCSAgICBsaW5rX2RpclswXSA9IDA7CgkgICAgRVJSKCJzZXJpb3VzIGlzc3VlcyAxXG4iKTsKCX0KCUlNYWxsb2NfUmVsZWFzZShwcE0pOwogICAgfQogICAgZWxzZSB7CgkvKiBzZXJpb3VzIGlzc3VlcyAqLwoJbGlua19kaXJbMF0gPSAwOwoJRVJSKCJzZXJpb3VzIGlzc3VlcyAyXG4iKTsKICAgIH0KICAgIFRSQUNFKCJVc2VycyBSZWNlbnQgZGlyICVzXG4iLCBsaW5rX2Rpcik7CgogICAgLyogSWYgbm8gaW5wdXQsIHRoZW4gZ28gY2xlYXIgdGhlIGxpc3RzICovCiAgICBpZiAoIXB2KSB7CgkvKiBjbGVhciB1c2VyJ3MgUmVjZW50IGRpcgoJICovCgoJLyogRklYTUU6IGRlbGV0ZSBhbGwgZmlsZXMgaW4gImxpbmtfZGlyIgoJICoKCSAqIHdoaWxlKCBtb3JlIGZpbGVzICkgewoJICogICAgbHN0cmNweUEob2xkX2xua19uYW1lLCBsaW5rX2Rpcik7CgkgKiAgICBQYXRoQXBwZW5kQShvbGRfbG5rX25hbWUsIGZpbGVuYW0pOwoJICogICAgRGVsZXRlRmlsZUEob2xkX2xua19uYW1lKTsKCSAqIH0KCSAqLwoJRklYTUUoInNob3VsZCBkZWxldGUgYWxsIGZpbGVzIGluICVzXFwgXG4iLCBsaW5rX2Rpcik7CgoJLyogY2xlYXIgTVJVIGxpc3QKCSAqLwoJLyogTVMgQnVnID8/IHY0LjcyLjM2MTIuMTcwMCBvZiBzaGVsbDMyIGRvZXMgdGhlIGRlbGV0ZSBhZ2FpbnN0CgkgKiAgSEtFWV9MT0NBTF9NQUNISU5FIHZlcnNpb24gb2YgLi4uQ3VycmVudFZlcnNpb25cRXhwbG9yZXIKCSAqICBhbmQgbmF0dXJhbGx5IGl0IGZhaWxzIHcvIHJjPTIuIEl0IHNob3VsZCBkbyBpdCBhZ2FpbnN0CgkgKiAgSEtFWV9DVVJSRU5UX1VTRVIgd2hpY2ggaXMgd2hlcmUgaXQgaXMgc3RvcmVkLCBhbmQgd2hlcmUKCSAqICB0aGUgTVJVIHJvdXRpbmVzIGV4cGVjdCBpdCEhISEKCSAqLwoJUmVnRGVsZXRlS2V5QShIQ1ViYXNla2V5LCAiUmVjZW50RG9jcyIpOwoJUmVnQ2xvc2VLZXkoSENVYmFzZWtleSk7CglyZXR1cm47CiAgICB9CgogICAgLyogSGF2ZSBkYXRhIHRvIGFkZCwgdGhlIGpvYnMgdG8gYmUgZG9uZToKICAgICAqICAgMS4gQWRkIGRvY3VtZW50IHRvIE1SVSBsaXN0IGluIHJlZ2lzdHJ5ICJIS0NVXFNvZnR3YXJlXAogICAgICogICAgICBNaWNyb3NvZnRcV2luZG93c1xDdXJyZW50VmVyc2lvblxFeHBsb3JlclxSZWNlbnREb2NzIi4KICAgICAqICAgMi4gQWRkIHNob3J0Y3V0IHRvIGRvY3VtZW50IGluIHRoZSB1c2VyJ3MgUmVjZW50IGRpcmVjdG9yeQogICAgICogICAgICAoQ1NJRExfUkVDRU5UKS4KICAgICAqICAgMy4gQWRkIHNob3J0Y3V0IHRvIFN0YXJ0IG1lbnUncyBEb2N1bWVudHMgc3VibWVudS4KICAgICAqLwoKICAgIC8qIEdldCB0aGUgcHVyZSBkb2N1bWVudCBuYW1lIGZyb20gdGhlIGlucHV0CiAgICAgKi8KICAgIGlmICh1RmxhZ3MgJiBTSEFSRF9QSURMKSB7CglTSEdldFBhdGhGcm9tSURMaXN0QSgoTFBDSVRFTUlETElTVCkgcHYsIGRvY19uYW1lKTsKICAgIH0KICAgIGVsc2UgewoJbHN0cmNweUEoZG9jX25hbWUsIChMUENTVFIpIHB2KTsKICAgIH0KICAgIFRSQUNFKCJmdWxsIGRvY3VtZW50IG5hbWUgJXNcbiIsIGRvY19uYW1lKTsKICAgIFBhdGhTdHJpcFBhdGhBKGRvY19uYW1lKTsKICAgIFRSQUNFKCJzdHJpcHBlZCBkb2N1bWVudCBuYW1lICVzXG4iLCBkb2NfbmFtZSk7CgoKICAgIC8qICoqKiAgSk9CIDE6IFVwZGF0ZSByZWdpc3RyeSBmb3IgLi4uXEV4cGxvcmVyXFJlY2VudERvY3MgbGlzdCAgKioqICovCgogICAgeyAgLyogb24gaW5wdXQgbmVlZHM6CgkqICAgICAgZG9jX25hbWUgICAgLSAgcHVyZSBmaWxlLXNwZWMsIG5vIHBhdGgKCSogICAgICBsaW5rX2RpciAgICAtICBwYXRoIHRvIHRoZSB1c2VyJ3MgUmVjZW50IGRpcmVjdG9yeQoJKiAgICAgIEhDVWJhc2VrZXkgIC0gIGtleSBvZiAuLi5XaW5kb3dzXEN1cnJlbnRWZXJzaW9uXEV4cGxvcmVyIiBub2RlCgkqIGNyZWF0ZXM6CgkqICAgICAgbmV3X2xua19uYW1lLSAgcHVyZSBmaWxlLXNwZWMsIG5vIHBhdGggZm9yIG5ldyAubG5rIGZpbGUKCSogICAgICBuZXdfbG5rX2ZpbGVwYXRoCgkqICAgICAgICAgICAgICAgICAgLSAgcGF0aCBhbmQgZmlsZSBuYW1lIG9mIG5ldyAubG5rIGZpbGUKCSovCglDUkVBVEVNUlVMSVNUQSBteW1ydTsKCUhBTkRMRSBtcnVoYW5kbGU7CglJTlQgbGVuLCBwb3MsIGJ1ZnVzZWQsIGVycjsKCUlOVCBpOwoJRFdPUkQgYXR0cjsKCUNIQVIgYnVmZmVyWzIwNDhdOwoJQ0hBUiAqcHRyOwoJQ0hBUiBvbGRfbG5rX25hbWVbTUFYX1BBVEhdOwoJc2hvcnQgaW50IHNsZW47CgoJbXltcnUuY2JTaXplID0gc2l6ZW9mKENSRUFURU1SVUxJU1RBKTsKCW15bXJ1Lm5NYXhJdGVtcyA9IDE1OwoJbXltcnUuZHdGbGFncyA9IE1SVUZfQklOQVJZX0xJU1QgfCBNUlVGX0RFTEFZRURfU0FWRTsKCW15bXJ1LmhLZXkgPSBIQ1ViYXNla2V5OwoJbXltcnUubHBzelN1YktleSA9ICJSZWNlbnREb2NzIjsKCW15bXJ1LmxwZm5Db21wYXJlID0gJlNIQUREX2NvbXBhcmVfbXJ1OwoJbXJ1aGFuZGxlID0gQ3JlYXRlTVJVTGlzdEEoJm15bXJ1KTsKCWlmICghbXJ1aGFuZGxlKSB7CgkgICAgLyogTVJVIGZhaWxlZCAqLwoJICAgIEVSUigiTVJVIHByb2Nlc3NpbmcgZmFpbGVkLCBoYW5kbGUgemVyb1xuIik7CgkgICAgUmVnQ2xvc2VLZXkoSENVYmFzZWtleSk7CgkgICAgcmV0dXJuOwoJfQoJbGVuID0gbHN0cmxlbkEoZG9jX25hbWUpOwoJcG9zID0gRmluZE1SVURhdGEobXJ1aGFuZGxlLCBkb2NfbmFtZSwgbGVuLCAwKTsKCgkvKiBOb3cgZ2V0IHRoZSBNUlUgZW50cnkgdGhhdCB3aWxsIGJlIHJlcGxhY2VkCgkgKiBhbmQgZGVsZXRlIHRoZSAubG5rIGZpbGUgZm9yIGl0CgkgKi8KCWlmICgoYnVmdXNlZCA9IEVudW1NUlVMaXN0QShtcnVoYW5kbGUsIChwb3MgPT0gLTEpID8gMTQgOiBwb3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgMjA0OCkpICE9IC0xKSB7CgkgICAgcHRyID0gYnVmZmVyOwoJICAgIHB0ciArPSAobHN0cmxlbkEoYnVmZmVyKSArIDEpOwoJICAgIHNsZW4gPSAqKChzaG9ydCBpbnQqKXB0cik7CgkgICAgcHRyICs9IDI7ICAvKiBza2lwIHRoZSBsZW5ndGggYXJlYSAqLwoJICAgIGlmIChidWZ1c2VkID49IHNsZW4gKyAocHRyLWJ1ZmZlcikpIHsKCQkvKiBidWZmZXIgc2l6ZSBsb29rcyBnb29kICovCgkJcHRyICs9IDEyOyAvKiBnZXQgdG8gc3RyaW5nICovCgkJbGVuID0gYnVmdXNlZCAtIChwdHItYnVmZmVyKTsgIC8qIGdldCBsZW5ndGggb2YgYnVmIHJlbWFpbmluZyAqLwoJCWlmICgobHN0cmxlbkEocHRyKSA+IDApICYmIChsc3RybGVuQShwdHIpIDw9IGxlbi0xKSkgewoJCSAgICAvKiBhcHBlYXJzIHRvIGJlIGdvb2Qgc3RyaW5nICovCgkJICAgIGxzdHJjcHlBKG9sZF9sbmtfbmFtZSwgbGlua19kaXIpOwoJCSAgICBQYXRoQXBwZW5kQShvbGRfbG5rX25hbWUsIHB0cik7CgkJICAgIGlmICghRGVsZXRlRmlsZUEob2xkX2xua19uYW1lKSkgewoJCQlpZiAoKGF0dHIgPSBHZXRGaWxlQXR0cmlidXRlc0Eob2xkX2xua19uYW1lKSkgPT0gSU5WQUxJRF9GSUxFX0FUVFJJQlVURVMpIHsKCQkJICAgIGlmICgoZXJyID0gR2V0TGFzdEVycm9yKCkpICE9IEVSUk9SX0ZJTEVfTk9UX0ZPVU5EKSB7CgkJCQlFUlIoIkRlbGV0ZSBmb3IgJXMgZmFpbGVkLCBlcnI9JWQsIGF0dHI9JTA4bHhcbiIsCgkJCQkgICAgb2xkX2xua19uYW1lLCBlcnIsIGF0dHIpOwoJCQkgICAgfQoJCQkgICAgZWxzZSB7CgkJCQlUUkFDRSgib2xkIC5sbmsgZmlsZSAlcyBkaWQgbm90IGV4aXN0XG4iLAoJCQkJICAgICAgb2xkX2xua19uYW1lKTsKCQkJICAgIH0KCQkJfQoJCQllbHNlIHsKCQkJICAgIEVSUigiRGVsZXRlIGZvciAlcyBmYWlsZWQsIGF0dHI9JTA4bHhcbiIsCgkJCQlvbGRfbG5rX25hbWUsIGF0dHIpOwoJCQl9CgkJICAgIH0KCQkgICAgZWxzZSB7CgkJCVRSQUNFKCJkZWxldGVkIG9sZCAubG5rIGZpbGUgJXNcbiIsIG9sZF9sbmtfbmFtZSk7CgkJICAgIH0KCQl9CgkgICAgfQoJfQoKCS8qIENyZWF0ZSB1c2FibGUgLmxuayBmaWxlIG5hbWUgZm9yIHRoZSAiUmVjZW50IiBkaXJlY3RvcnkKCSAqLwoJd3NwcmludGZBKG5ld19sbmtfbmFtZSwgIiVzLmxuayIsIGRvY19uYW1lKTsKCWxzdHJjcHlBKG5ld19sbmtfZmlsZXBhdGgsIGxpbmtfZGlyKTsKCVBhdGhBcHBlbmRBKG5ld19sbmtfZmlsZXBhdGgsIG5ld19sbmtfbmFtZSk7CglpID0gMTsKCW9sZGVycm9ybW9kZSA9IFNldEVycm9yTW9kZShTRU1fRkFJTENSSVRJQ0FMRVJST1JTKTsKCXdoaWxlIChHZXRGaWxlQXR0cmlidXRlc0EobmV3X2xua19maWxlcGF0aCkgIT0gSU5WQUxJRF9GSUxFX0FUVFJJQlVURVMpIHsKCSAgICBpKys7CgkgICAgd3NwcmludGZBKG5ld19sbmtfbmFtZSwgIiVzICgldSkubG5rIiwgZG9jX25hbWUsIGkpOwoJICAgIGxzdHJjcHlBKG5ld19sbmtfZmlsZXBhdGgsIGxpbmtfZGlyKTsKCSAgICBQYXRoQXBwZW5kQShuZXdfbG5rX2ZpbGVwYXRoLCBuZXdfbG5rX25hbWUpOwoJfQoJU2V0RXJyb3JNb2RlKG9sZGVycm9ybW9kZSk7CglUUkFDRSgibmV3IHNob3J0Y3V0IHdpbGwgYmUgJXNcbiIsIG5ld19sbmtfZmlsZXBhdGgpOwoKCS8qIE5vdyBhZGQgdGhlIG5ldyBNUlUgZW50cnkgYW5kIGRhdGEKCSAqLwoJcG9zID0gU0hBRERfY3JlYXRlX2FkZF9tcnVfZGF0YShtcnVoYW5kbGUsIGRvY19uYW1lLCBuZXdfbG5rX25hbWUsCgkJCQkJYnVmZmVyLCAmbGVuKTsKCUZyZWVNUlVMaXN0KG1ydWhhbmRsZSk7CglUUkFDRSgiVXBkYXRlZCBNUlUgbGlzdCwgbmV3IGRvYyBpcyBwb3NpdGlvbiAlZFxuIiwgcG9zKTsKICAgIH0KCiAgICAvKiAqKiogIEpPQiAyOiBDcmVhdGUgc2hvcnRjdXQgaW4gdXNlcidzICJSZWNlbnQiIGRpcmVjdG9yeSAgKioqICovCgogICAgeyAgLyogb24gaW5wdXQgbmVlZHM6CgkqICAgICAgZG9jX25hbWUgICAgLSAgcHVyZSBmaWxlLXNwZWMsIG5vIHBhdGgKCSogICAgICBuZXdfbG5rX2ZpbGVwYXRoCgkqICAgICAgICAgICAgICAgICAgLSAgcGF0aCBhbmQgZmlsZSBuYW1lIG9mIG5ldyAubG5rIGZpbGUKIAkqICAgICAgdUZsYWdzW2luXSAgLSAgZmxhZ3Mgb24gY2FsbCB0byBTSEFkZFRvUmVjZW50RG9jcwoJKiAgICAgIHB2W2luXSAgICAgIC0gIGRvY3VtZW50IHBhdGgvcGlkbCBvbiBjYWxsIHRvIFNIQWRkVG9SZWNlbnREb2NzCgkqLwoJSVNoZWxsTGlua0EgKnBzbCA9IE5VTEw7CglJUGVyc2lzdEZpbGUgKnBQZiA9IE5VTEw7CglIUkVTVUxUIGhyZXM7CglDSEFSIGRlc2NbTUFYX1BBVEhdOwoJV0NIQVIgd2lkZWxpbmtbTUFYX1BBVEhdOwoKCUNvSW5pdGlhbGl6ZSgwKTsKCglocmVzID0gQ29DcmVhdGVJbnN0YW5jZSggJkNMU0lEX1NoZWxsTGluaywKCQkJCSBOVUxMLAoJCQkJIENMU0NUWF9JTlBST0NfU0VSVkVSLAoJCQkJICZJSURfSVNoZWxsTGlua0EsCgkJCQkgKExQVk9JRCApJnBzbCk7CglpZihTVUNDRUVERUQoaHJlcykpIHsKCgkgICAgaHJlcyA9IElTaGVsbExpbmtBX1F1ZXJ5SW50ZXJmYWNlKHBzbCwgJklJRF9JUGVyc2lzdEZpbGUsCgkJCQkJICAgICAoTFBWT0lEICopJnBQZik7CgkgICAgaWYoRkFJTEVEKGhyZXMpKSB7CgkJLyogYm9tYmVkICovCgkJRVJSKCJmYWlsZWQgUXVlcnlJbnRlcmZhY2UgZm9yIElQZXJzaXN0RmlsZSAlMDhseFxuIiwgaHJlcyk7CgkJZ290byBmYWlsOwoJICAgIH0KCgkgICAgLyogU2V0IHRoZSBkb2N1bWVudCBwYXRoIG9yIHBpZGwgKi8KCSAgICBpZiAodUZsYWdzICYgU0hBUkRfUElETCkgewoJCWhyZXMgPSBJU2hlbGxMaW5rQV9TZXRJRExpc3QocHNsLCAoTFBDSVRFTUlETElTVCkgcHYpOwoJICAgIH0gZWxzZSB7CgkJaHJlcyA9IElTaGVsbExpbmtBX1NldFBhdGgocHNsLCAoTFBDU1RSKSBwdik7CgkgICAgfQoJICAgIGlmKEZBSUxFRChocmVzKSkgewoJCS8qIGJvbWJlZCAqLwoJCUVSUigiZmFpbGVkIFNldHtJRExpc3R8UGF0aH0gJTA4bHhcbiIsIGhyZXMpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgoJICAgIGxzdHJjcHlBKGRlc2MsICJTaG9ydGN1dCB0byAiKTsKCSAgICBsc3RyY2F0QShkZXNjLCBkb2NfbmFtZSk7CgkgICAgaHJlcyA9IElTaGVsbExpbmtBX1NldERlc2NyaXB0aW9uKHBzbCwgZGVzYyk7CgkgICAgaWYoRkFJTEVEKGhyZXMpKSB7CgkJLyogYm9tYmVkICovCgkJRVJSKCJmYWlsZWQgU2V0RGVzY3JpcHRpb24gJTA4bHhcbiIsIGhyZXMpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgoJICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBuZXdfbG5rX2ZpbGVwYXRoLCAtMSwKCQkJCXdpZGVsaW5rLCBNQVhfUEFUSCk7CgkgICAgLyogY3JlYXRlIHRoZSBzaG9ydCBjdXQgKi8KCSAgICBocmVzID0gSVBlcnNpc3RGaWxlX1NhdmUocFBmLCB3aWRlbGluaywgVFJVRSk7CgkgICAgaWYoRkFJTEVEKGhyZXMpKSB7CgkJLyogYm9tYmVkICovCgkJRVJSKCJmYWlsZWQgSVBlcnNpc3RGaWxlOjpTYXZlICUwOGx4XG4iLCBocmVzKTsKCQlJUGVyc2lzdEZpbGVfUmVsZWFzZShwUGYpOwoJCUlTaGVsbExpbmtBX1JlbGVhc2UocHNsKTsKCQlnb3RvIGZhaWw7CgkgICAgfQoJICAgIGhyZXMgPSBJUGVyc2lzdEZpbGVfU2F2ZUNvbXBsZXRlZChwUGYsIHdpZGVsaW5rKTsKCSAgICBJUGVyc2lzdEZpbGVfUmVsZWFzZShwUGYpOwoJICAgIElTaGVsbExpbmtBX1JlbGVhc2UocHNsKTsKCSAgICBUUkFDRSgic2hvcnRjdXQgJXMgaGFzIGJlZW4gY3JlYXRlZCwgcmVzdWx0PSUwOGx4XG4iLAoJCSAgbmV3X2xua19maWxlcGF0aCwgaHJlcyk7Cgl9CgllbHNlIHsKCSAgICBFUlIoIkNvQ3JlYXRlSW5zdGFuY2UgZmFpbGVkLCBocmVzPSUwOGx4XG4iLCBocmVzKTsKCX0KICAgIH0KCiBmYWlsOgogICAgQ29VbmluaXRpYWxpemUoKTsKCiAgICAvKiBhbGwgZG9uZSAqLwogICAgUmVnQ2xvc2VLZXkoSENVYmFzZWtleSk7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ3JlYXRlU2hlbGxGb2xkZXJWaWV3RXgJCQlbU0hFTEwzMi4xNzRdCiAqCiAqIE5PVEVTCiAqICBzZWUgSVNoZWxsRm9sZGVyOjpDcmVhdGVWaWV3T2JqZWN0CiAqLwpIUkVTVUxUIFdJTkFQSSBTSENyZWF0ZVNoZWxsRm9sZGVyVmlld0V4KAoJTFBDU0ZWIHBzdmNiaSwgICAgLyogW2luXSBzaGVsbHRlbXBsYXRlIHN0cnVjdCAqLwoJSVNoZWxsVmlldyAqKnBwdikgLyogW291dF0gSVNoZWxsVmlldyBwb2ludGVyICovCnsKCUlTaGVsbFZpZXcgKiBwc2Y7CglIUkVTVUxUIGhSZXM7CgoJVFJBQ0UoInNmPSVwIHBpZGw9JXAgY2I9JXAgbW9kZT0weCUwOHggcGFybT0lcFxuIiwKCSAgcHN2Y2JpLT5wc2hmLCBwc3ZjYmktPnBpZGwsIHBzdmNiaS0+cGZuQ2FsbGJhY2ssCgkgIHBzdmNiaS0+ZnZtLCBwc3ZjYmktPnBzdk91dGVyKTsKCglwc2YgPSBJU2hlbGxWaWV3X0NvbnN0cnVjdG9yKHBzdmNiaS0+cHNoZik7CgoJaWYgKCFwc2YpCgkgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKCUlTaGVsbFZpZXdfQWRkUmVmKHBzZik7CgloUmVzID0gSVNoZWxsVmlld19RdWVyeUludGVyZmFjZShwc2YsICZJSURfSVNoZWxsVmlldywgKExQVk9JRCAqKXBwdik7CglJU2hlbGxWaWV3X1JlbGVhc2UocHNmKTsKCglyZXR1cm4gaFJlczsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgU0hXaW5IZWxwCQkJCQlbU0hFTEwzMi4xMjddCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFdpbkhlbHAgKERXT1JEIHYsIERXT1JEIHcsIERXT1JEIHgsIERXT1JEIHopCnsJRklYTUUoIjB4JTA4bHggMHglMDhseCAweCUwOGx4IDB4JTA4bHggc3R1YlxuIix2LHcseCx6KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBTSFJ1bkNvbnRyb2xQYW5lbCBbU0hFTEwzMi4xNjFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJ1bkNvbnRyb2xQYW5lbCAoRFdPUkQgeCwgRFdPUkQgeikKewlGSVhNRSgiMHglMDhseCAweCUwOGx4IHN0dWJcbiIseCx6KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgTFBVTktOT1dOIFNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlPTA7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2V0SW5zdGFuY2VFeHBsb3JlcgkJCVtTSEVMTDMyLjE3Nl0KICoKICogTk9URVMKICogIFNldHMgdGhlIGludGVyZmFjZQogKi8KSFJFU1VMVCBXSU5BUEkgU0hTZXRJbnN0YW5jZUV4cGxvcmVyIChMUFVOS05PV04gbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCVNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlID0gbHBVbmtub3duOwoJcmV0dXJuIChIUkVTVUxUKSBscFVua25vd247Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hHZXRJbnN0YW5jZUV4cGxvcmVyCQkJW1NIRUxMMzIuQF0KICoKICogTk9URVMKICogIGdldHMgdGhlIGludGVyZmFjZSBwb2ludGVyIG9mIHRoZSBleHBsb3JlciBhbmQgYSByZWZlcmVuY2UKICovCkhSRVNVTFQgV0lOQVBJIFNIR2V0SW5zdGFuY2VFeHBsb3JlciAoTFBVTktOT1dOICogbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCgkqbHBVbmtub3duID0gU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2U7CgoJaWYgKCFTSEVMTDMyX0lFeHBsb3JlckludGVyZmFjZSkKCSAgcmV0dXJuIEVfRkFJTDsKCglJVW5rbm93bl9BZGRSZWYoU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2UpOwoJcmV0dXJuIE5PRVJST1I7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGcmVlVW51c2VkTGlicmFyaWVzCQkJW1NIRUxMMzIuMTIzXQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgbmFtZQogKi8Kdm9pZCBXSU5BUEkgU0hGcmVlVW51c2VkTGlicmFyaWVzICh2b2lkKQp7CglGSVhNRSgic3R1YlxuIik7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX0F1dG9TY3JvbGwJCQkJW1NIRUxMMzIuMTI5XQogKgogKi8KQk9PTCBXSU5BUEkgREFEX0F1dG9TY3JvbGwoSFdORCBod25kLCBBVVRPX1NDUk9MTF9EQVRBICpzYW1wbGVzLCBMUFBPSU5UIHB0KQp7CiAgICBGSVhNRSgiaHduZCA9ICVwICVwICVwXG4iLGh3bmQsc2FtcGxlcyxwdCk7CiAgICByZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfRHJhZ0VudGVyCQkJCVtTSEVMTDMyLjEzMF0KICoKICovCkJPT0wgV0lOQVBJIERBRF9EcmFnRW50ZXIoSFdORCBod25kKQp7CiAgICBGSVhNRSgiaHduZCA9ICVwXG4iLGh3bmQpOwogICAgcmV0dXJuIEZBTFNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9EcmFnRW50ZXJFeAkJCQlbU0hFTEwzMi4xMzFdCiAqCiAqLwpCT09MIFdJTkFQSSBEQURfRHJhZ0VudGVyRXgoSFdORCBod25kLCBQT0lOVCBwKQp7CiAgICBGSVhNRSgiaHduZCA9ICVwICglbGQsJWxkKVxuIixod25kLHAueCxwLnkpOwogICAgcmV0dXJuIEZBTFNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9EcmFnTW92ZQkJCQlbU0hFTEwzMi4xMzRdCiAqCiAqLwpCT09MIFdJTkFQSSBEQURfRHJhZ01vdmUoUE9JTlQgcCkKewogICAgRklYTUUoIiglbGQsJWxkKVxuIixwLngscC55KTsKICAgIHJldHVybiBGQUxTRTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfRHJhZ0xlYXZlCQkJCVtTSEVMTDMyLjEzMl0KICoKICovCkJPT0wgV0lOQVBJIERBRF9EcmFnTGVhdmUoVk9JRCkKewogICAgRklYTUUoIlxuIik7CiAgICByZXR1cm4gRkFMU0U7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX1NldERyYWdJbWFnZQkJCQlbU0hFTEwzMi4xMzZdCiAqCiAqIE5PVEVTCiAqICBleHBvcnRlZCBieSBuYW1lCiAqLwpCT09MIFdJTkFQSSBEQURfU2V0RHJhZ0ltYWdlKAoJSElNQUdFTElTVCBoaW1sVHJhY2ssCglMUFBPSU5UIGxwcHQpCnsKCUZJWE1FKCIlcCAlcCBzdHViXG4iLGhpbWxUcmFjaywgbHBwdCk7CiAgcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX1Nob3dEcmFnSW1hZ2UJCQkJW1NIRUxMMzIuMTM3XQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgbmFtZQogKi8KQk9PTCBXSU5BUEkgREFEX1Nob3dEcmFnSW1hZ2UoQk9PTCBiU2hvdykKewoJRklYTUUoIjB4JTA4eCBzdHViXG4iLGJTaG93KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgY29uc3QgV0NIQVIgc3p3Q2FiTG9jYXRpb25bXSA9IHsKICAnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCiAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywKICAnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1xcJywKICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcXCcsCiAgJ0UnLCd4JywncCcsJ2wnLCdvJywncicsJ2UnLCdyJywnXFwnLAogICdDJywnYScsJ2InLCdpJywnbicsJ2UnLCd0JywnUycsJ3QnLCdhJywndCcsJ2UnLDAKfTsKCnN0YXRpYyBjb25zdCBXQ0hBUiBzendTZXR0aW5nc1tdID0geyAnUycsJ2UnLCd0JywndCcsJ2knLCduJywnZycsJ3MnLDAgfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlYWRDYWJpbmV0U3RhdGUJCQkJW1NIRUxMMzIuNjUxXSBOVCA0LjAKICoKICovCkJPT0wgV0lOQVBJIFJlYWRDYWJpbmV0U3RhdGUoQ0FCSU5FVFNUQVRFICpjcywgaW50IGxlbmd0aCkKewoJSEtFWSBoa2V5ID0gMDsKCURXT1JEIHR5cGUsIHI7CgoJVFJBQ0UoIiVwICVkIFxuIixjcyxsZW5ndGgpOwoKCWlmKCAoY3MgPT0gTlVMTCkgfHwgKGxlbmd0aCA8IChpbnQpc2l6ZW9mKCpjcykpICApCgkJcmV0dXJuIEZBTFNFOwoKCXIgPSBSZWdPcGVuS2V5VyggSEtFWV9DVVJSRU5UX1VTRVIsIHN6d0NhYkxvY2F0aW9uLCAmaGtleSApOwoJaWYoIHIgPT0gRVJST1JfU1VDQ0VTUyApCgl7CgkJdHlwZSA9IFJFR19CSU5BUlk7CgkJciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoIGhrZXksIHN6d1NldHRpbmdzLCAKCQkJTlVMTCwgJnR5cGUsIChMUEJZVEUpY3MsIChMUERXT1JEKSZsZW5ndGggKTsKCQlSZWdDbG9zZUtleSggaGtleSApOwoJCQkKCX0KCgkvKiBpZiB3ZSBjYW4ndCByZWFkIGZyb20gdGhlIHJlZ2lzdHJ5LCBjcmVhdGUgZGVmYXVsdCB2YWx1ZXMgKi8KCWlmICggKHIgIT0gRVJST1JfU1VDQ0VTUykgfHwgKGNzLT5jTGVuZ3RoIDwgc2l6ZW9mKCpjcykpIHx8CgkJKGNzLT5jTGVuZ3RoICE9IGxlbmd0aCkgKQoJewoJCUVSUigiSW5pdGlhbGl6aW5nIHNoZWxsIGNhYmluZXQgc2V0dGluZ3NcbiIpOwoJCW1lbXNldChjcywgMCwgc2l6ZW9mKCpjcykpOwoJCWNzLT5jTGVuZ3RoICAgICAgICAgID0gc2l6ZW9mKCpjcyk7CgkJY3MtPm5WZXJzaW9uICAgICAgICAgPSAyOwoJCWNzLT5mRnVsbFBhdGhUaXRsZSAgID0gRkFMU0U7CgkJY3MtPmZTYXZlTG9jYWxWaWV3ICAgPSBUUlVFOwoJCWNzLT5mTm90U2hlbGwgICAgICAgID0gRkFMU0U7CgkJY3MtPmZTaW1wbGVEZWZhdWx0ICAgPSBUUlVFOwoJCWNzLT5mRG9udFNob3dEZXNjQmFyID0gRkFMU0U7CgkJY3MtPmZOZXdXaW5kb3dNb2RlICAgPSBGQUxTRTsKCQljcy0+ZlNob3dDb21wQ29sb3IgICA9IEZBTFNFOwoJCWNzLT5mRG9udFByZXR0eU5hbWVzID0gRkFMU0U7CgkJY3MtPmZBZG1pbnNDcmVhdGVDb21tb25Hcm91cHMgPSBUUlVFOwoJCWNzLT5mTWVudUVudW1GaWx0ZXIgID0gOTY7Cgl9CgkKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBXcml0ZUNhYmluZXRTdGF0ZQkJCQlbU0hFTEwzMi42NTJdIE5UIDQuMAogKgogKi8KQk9PTCBXSU5BUEkgV3JpdGVDYWJpbmV0U3RhdGUoQ0FCSU5FVFNUQVRFICpjcykKewoJRFdPUkQgcjsKCUhLRVkgaGtleSA9IDA7CgoJVFJBQ0UoIiVwXG4iLGNzKTsKCglpZiggY3MgPT0gTlVMTCApCgkJcmV0dXJuIEZBTFNFOwoKCXIgPSBSZWdDcmVhdGVLZXlFeFcoIEhLRVlfQ1VSUkVOVF9VU0VSLCBzendDYWJMb2NhdGlvbiwgMCwKCQkgTlVMTCwgMCwgS0VZX0FMTF9BQ0NFU1MsIE5VTEwsICZoa2V5LCBOVUxMKTsKCWlmKCByID09IEVSUk9SX1NVQ0NFU1MgKQoJewoJCXIgPSBSZWdTZXRWYWx1ZUV4VyggaGtleSwgc3p3U2V0dGluZ3MsIDAsIAoJCQlSRUdfQklOQVJZLCAoTFBCWVRFKSBjcywgY3MtPmNMZW5ndGgpOwoKCQlSZWdDbG9zZUtleSggaGtleSApOwoJfQoKCXJldHVybiAocj09RVJST1JfU1VDQ0VTUyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEZpbGVJY29uSW5pdCAJCQkJW1NIRUxMMzIuNjYwXQogKgogKi8KQk9PTCBXSU5BUEkgRmlsZUljb25Jbml0KEJPT0wgYkZ1bGxJbml0KQp7CUZJWE1FKCIoJXMpXG4iLCBiRnVsbEluaXQgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElzVXNlckFkbWluCQkJCQlbU0hFTEwzMi42ODBdIE5UIDQuMAogKgogKi8KSFJFU1VMVCBXSU5BUEkgSXNVc2VyQWRtaW4odm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hBbGxvY1NoYXJlZAkJCQlbU0hFTEwzMi41MjBdCiAqCiAqIFNlZSBzaGx3YXBpLlNIQWxsb2NTaGFyZWQKICovCkhBTkRMRSBXSU5BUEkgU0hBbGxvY1NoYXJlZChMUFZPSUQgbHB2RGF0YSwgRFdPUkQgZHdTaXplLCBEV09SRCBkd1Byb2NJZCkKewogICAgR0VUX0ZVTkMocFNIQWxsb2NTaGFyZWQsIHNobHdhcGksIChjaGFyKik3LCBOVUxMKTsKICAgIHJldHVybiBwU0hBbGxvY1NoYXJlZChscHZEYXRhLCBkd1NpemUsIGR3UHJvY0lkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hMb2NrU2hhcmVkCQkJCQlbU0hFTEwzMi41MjFdCiAqCiAqIFNlZSBzaGx3YXBpLlNITG9ja1NoYXJlZAogKi8KTFBWT0lEIFdJTkFQSSBTSExvY2tTaGFyZWQoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3UHJvY0lkKQp7CiAgICBHRVRfRlVOQyhwU0hMb2NrU2hhcmVkLCBzaGx3YXBpLCAoY2hhciopOCwgTlVMTCk7CiAgICByZXR1cm4gcFNITG9ja1NoYXJlZChoU2hhcmVkLCBkd1Byb2NJZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIVW5sb2NrU2hhcmVkCQkJCVtTSEVMTDMyLjUyMl0KICoKICogU2VlIHNobHdhcGkuU0hVbmxvY2tTaGFyZWQKICovCkJPT0wgV0lOQVBJIFNIVW5sb2NrU2hhcmVkKExQVk9JRCBscFZpZXcpCnsKICAgIEdFVF9GVU5DKHBTSFVubG9ja1NoYXJlZCwgc2hsd2FwaSwgKGNoYXIqKTksIEZBTFNFKTsKICAgIHJldHVybiBwU0hVbmxvY2tTaGFyZWQobHBWaWV3KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGcmVlU2hhcmVkCQkJCQlbU0hFTEwzMi41MjNdCiAqCiAqIFNlZSBzaGx3YXBpLlNIRnJlZVNoYXJlZAogKi8KQk9PTCBXSU5BUEkgU0hGcmVlU2hhcmVkKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd1Byb2NJZCkKewogICAgR0VUX0ZVTkMocFNIRnJlZVNoYXJlZCwgc2hsd2FwaSwgKGNoYXIqKTEwLCBGQUxTRSk7CiAgICByZXR1cm4gcFNIRnJlZVNoYXJlZChoU2hhcmVkLCBkd1Byb2NJZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNldEFwcFN0YXJ0aW5nQ3Vyc29yCQkJCVtTSEVMTDMyLjk5XQogKi8KSFJFU1VMVCBXSU5BUEkgU2V0QXBwU3RhcnRpbmdDdXJzb3IoSFdORCB1LCBEV09SRCB2KQp7CUZJWE1FKCJod25kPSVwIDB4JTA0bHggc3R1YlxuIix1LHYgKTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNITG9hZE9MRQkJCQkJW1NIRUxMMzIuMTUxXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hMb2FkT0xFKExQQVJBTSBsUGFyYW0pCnsJRklYTUUoIjB4JTA0bHggc3R1YlxuIixsUGFyYW0pOwoJcmV0dXJuIFNfT0s7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRHJpdmVUeXBlCQkJCQlbU0hFTEwzMi42NF0KICoKICovCkhSRVNVTFQgV0lOQVBJIERyaXZlVHlwZShEV09SRCB1KQp7CUZJWE1FKCIweCUwNGx4IHN0dWJcbiIsdSk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFib3J0SW52b2tlQ29tbWFuZAkJCQlbU0hFTEwzMi4xOThdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEFib3J0SW52b2tlQ29tbWFuZCh2b2lkKQp7CUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiAxOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIT3V0T2ZNZW1vcnlNZXNzYWdlQm94CQkJW1NIRUxMMzIuMTI2XQogKgogKi8KaW50IFdJTkFQSSBTSE91dE9mTWVtb3J5TWVzc2FnZUJveCgKCUhXTkQgaHduZE93bmVyLAoJTFBDU1RSIGxwQ2FwdGlvbiwKCVVJTlQgdVR5cGUpCnsKCUZJWE1FKCIlcCAlcyAweCUwOHggc3R1YlxuIixod25kT3duZXIsIGxwQ2FwdGlvbiwgdVR5cGUpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGbHVzaENsaXBib2FyZAkJCQlbU0hFTEwzMi4xMjFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEZsdXNoQ2xpcGJvYXJkKHZvaWQpCnsJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIDE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIV2FpdEZvckZpbGVUb09wZW4JCQkJW1NIRUxMMzIuOTddCiAqCiAqLwpCT09MIFdJTkFQSSBTSFdhaXRGb3JGaWxlVG9PcGVuKAoJTFBDSVRFTUlETElTVCBwaWRsLAoJRFdPUkQgZHdGbGFncywKCURXT1JEIGR3VGltZW91dCkKewoJRklYTUUoIiVwIDB4JTA4bHggMHglMDhseCBzdHViXG4iLCBwaWRsLCBkd0ZsYWdzLCBkd1RpbWVvdXQpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJQAkJCQlbU0hFTEwzMi42NTRdCiAqCiAqIE5PVEVTOiBmaXJzdCBwYXJhbWV0ZXIgc2VlbXMgdG8gYmUgYSBwb2ludGVyIChzYW1lIGFzIHBhc3NlZCB0byBXcml0ZUNhYmluZXRTdGF0ZSkKICogc2Vjb25kIG9uZSBjb3VsZCBiZSBhIHNpemUgKDB4MGMpLiBUaGUgc2l6ZSBpcyB0aGUgc2FtZSBhcyB0aGUgc3RydWN0dXJlIHNhdmVkIHRvCiAqIEhDVVxTb2Z0d2FyZVxNaWNyb3NvZnRcV2luZG93c1xDdXJyZW50VmVyc2lvblxFeHBsb3JlclxDYWJpbmV0U3RhdGUKICogSSdtIChqcykgZ3Vlc3Npbmc6IHRoaXMgb25lIGlzIGp1c3QgUmVhZENhYmluZXRTdGF0ZSA7LSkKICovCkhSRVNVTFQgV0lOQVBJIHNoZWxsMzJfNjU0IChDQUJJTkVUU1RBVEUgKmNzLCBpbnQgbGVuZ3RoKQp7CglUUkFDRSgiJXAgJWRcbiIsY3MsbGVuZ3RoKTsKCXJldHVybiBSZWFkQ2FiaW5ldFN0YXRlKGNzLGxlbmd0aCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUkxCdWlsZExpc3RPZlBhdGhzCQkJW1NIRUxMMzIuMTQ2XQogKgogKiBOT1RFUwogKiAgIGJ1aWxkcyBhIERQQQogKi8KRFdPUkQgV0lOQVBJIFJMQnVpbGRMaXN0T2ZQYXRocyAodm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVNIVmFsaWRhdGVVTkMJCQkJW1NIRUxMMzIuMTczXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hWYWxpZGF0ZVVOQyAoRFdPUkQgeCwgRFdPUkQgeSwgRFdPUkQgeikKewoJRklYTUUoIjB4JTA4bHggMHglMDhseCAweCUwOGx4IHN0dWJcbiIseCx5LHopOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJRG9FbnZpcm9ubWVudFN1YnN0QQkJCVtTSEVMTDMyLkBdCiAqCiAqIFJlcGxhY2UgJUtFWVdPUkQlIGluIHRoZSBzdHIgd2l0aCB0aGUgdmFsdWUgb2YgdmFyaWFibGUgS0VZV09SRAogKiBmcm9tIGVudmlyb25tZW50LiBJZiBpdCBpcyBub3QgZm91bmQgdGhlICVLRVlXT1JEJSBpcyBsZWZ0CiAqIGludGFjdC4gSWYgdGhlIGJ1ZmZlciBpcyB0b28gc21hbGwsIHN0ciBpcyBub3QgbW9kaWZpZWQuCiAqCiAqIHBzelN0cmluZyAgIFtJXSAnXDAnIHRlcm1pbmF0ZWQgc3RyaW5nIHdpdGggJWtleXdvcmQlLgogKiAgICAgICAgICAgICBbT10gJ1wwJyB0ZXJtaW5hdGVkIHN0cmluZyB3aXRoICVrZXl3b3JkJSBzdWJzdGl0dXRlZC4KICogY2NoU3RyaW5nICAgW0ldIHNpemUgb2Ygc3RyLgogKgogKiBSZXR1cm4KICogICAgIGNjaFN0cmluZyBsZW5ndGggaW4gdGhlIEhJV09SRDsKICogICAgIFRSVUUgaW4gTE9XT1JEIGlmIHN1YnN0IHdhcyBzdWNjZXNzZnVsIGFuZCBGQUxTRSBpbiBvdGhlciBjYXNlCiAqLwpEV09SRCBXSU5BUEkgRG9FbnZpcm9ubWVudFN1YnN0QShMUFNUUiBwc3pTdHJpbmcsIFVJTlQgY2NoU3RyaW5nKQp7CiAgICBMUFNUUiBkc3Q7CiAgICBCT09MIHJlcyA9IEZBTFNFOwogICAgRklYTUUoIiglcywgJWQpIHN0dWJcbiIsIGRlYnVnc3RyX2EocHN6U3RyaW5nKSwgY2NoU3RyaW5nKTsKICAgIGlmIChwc3pTdHJpbmcgPT0gTlVMTCkgLyogUmVhbGx5IHJldHVybiAwPyAqLwogICAgICAgIHJldHVybiAwOwogICAgaWYgKChkc3QgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2NoU3RyaW5nICogc2l6ZW9mKENIQVIpKSkpCiAgICB7CiAgICAgICAgRFdPUkQgbnVtID0gRXhwYW5kRW52aXJvbm1lbnRTdHJpbmdzQShwc3pTdHJpbmcsIGRzdCwgY2NoU3RyaW5nKTsKICAgICAgICBpZiAobnVtICYmIG51bSA8IGNjaFN0cmluZykgLyogZGVzdCBidWZmZXIgaXMgdG9vIHNtYWxsICovCiAgICAgICAgewogICAgICAgICAgICByZXMgPSBUUlVFOwogICAgICAgICAgICBtZW1jcHkocHN6U3RyaW5nLCBkc3QsIG51bSk7CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzdCk7CiAgICB9CiAgICByZXR1cm4gTUFLRUxPTkcocmVzLGNjaFN0cmluZyk7IC8qIEFsd2F5cyBjY2hTdHJpbmc/ICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJRG9FbnZpcm9ubWVudFN1YnN0VwkJCVtTSEVMTDMyLkBdCiAqCiAqLwpEV09SRCBXSU5BUEkgRG9FbnZpcm9ubWVudFN1YnN0VyhMUFdTVFIgcHN6U3RyaW5nLCBVSU5UIGNjaFN0cmluZykKewoJRklYTUUoIiglcywgJWQpOiBzdHViXG4iLCBkZWJ1Z3N0cl93KHBzelN0cmluZyksIGNjaFN0cmluZyk7CglyZXR1cm4gTUFLRUxPTkcoRkFMU0UsY2NoU3RyaW5nKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglEb0Vudmlyb25tZW50U3Vic3QJCQlbU0hFTEwzMi41M10KICoKICovCkRXT1JEIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RBVyhMUFZPSUQgeCwgVUlOVCB5KQp7CiAgICBpZiAoU0hFTExfT3NJc1VuaWNvZGUoKSkKICAgICAgICByZXR1cm4gRG9FbnZpcm9ubWVudFN1YnN0Vyh4LCB5KTsKICAgIHJldHVybiBEb0Vudmlyb25tZW50U3Vic3RBKHgsIHkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtTSEVMTDMyLjI0M10KICoKICogV2luOTgrIGJ5LW9yZGluYWwgcm91dGluZS4gIEluIFdpbjk4IHRoaXMgcm91dGluZSByZXR1cm5zIHplcm8gYW5kCiAqIGRvZXMgbm90aGluZyBlbHNlLiAgUG9zc2libHkgdGhpcyBkb2VzIHNvbWV0aGluZyBpbiBOVCBvciBTSEVMTDMyIDUuMD8KICoKICovCgpCT09MIFdJTkFQSSBzaGVsbDMyXzI0MyhEV09SRCBhLCBEV09SRCBiKQp7CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NIRUxMMzIuNzE0XQogKi8KRFdPUkQgV0lOQVBJIFNIRUxMMzJfNzE0KExQVk9JRCB4KQp7CiAJRklYTUUoIiglcylzdHViXG4iLCBkZWJ1Z3N0cl93KHgpKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNIQWRkRnJvbVByb3BTaGVldEV4dEFycmF5CVtTSEVMTDMyLjE2N10KICovCkRXT1JEIFdJTkFQSSBTSEFkZEZyb21Qcm9wU2hlZXRFeHRBcnJheShEV09SRCBhLCBEV09SRCBiLCBEV09SRCBjKQp7CiAJRklYTUUoIiglMDhseCwlMDhseCwlMDhseClzdHViXG4iLCBhLCBiLCBjKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNIQ3JlYXRlUHJvcFNoZWV0RXh0QXJyYXkJW1NIRUxMMzIuMTY4XQogKi8KRFdPUkQgV0lOQVBJIFNIQ3JlYXRlUHJvcFNoZWV0RXh0QXJyYXkoRFdPUkQgYSwgTFBDU1RSIGIsIERXT1JEIGMpCnsKIAlGSVhNRSgiKCUwOGx4LCVzLCUwOGx4KXN0dWJcbiIsIGEsIGRlYnVnc3RyX2EoYiksIGMpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hSZXBsYWNlRnJvbVByb3BTaGVldEV4dEFycmF5CVtTSEVMTDMyLjE3MF0KICovCkRXT1JEIFdJTkFQSSBTSFJlcGxhY2VGcm9tUHJvcFNoZWV0RXh0QXJyYXkoRFdPUkQgYSwgRFdPUkQgYiwgRFdPUkQgYywgRFdPUkQgZCkKewogCUZJWE1FKCIoJTA4bHgsJTA4bHgsJTA4bHgsJTA4bHgpc3R1YlxuIiwgYSwgYiwgYywgZCk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSERlc3Ryb3lQcm9wU2hlZXRFeHRBcnJheQlbU0hFTEwzMi4xNjldCiAqLwpEV09SRCBXSU5BUEkgU0hEZXN0cm95UHJvcFNoZWV0RXh0QXJyYXkoRFdPUkQgYSkKewogCUZJWE1FKCIoJTA4bHgpc3R1YlxuIiwgYSk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBDSURMRGF0YV9DcmVhdGVGcm9tSURBcnJheQlbU0hFTEwzMi44M10KICoKICogIENyZWF0ZSBJRGF0YU9iamVjdCBmcm9tIFBJRExzPz8KICovCkhSRVNVTFQgV0lOQVBJIENJRExEYXRhX0NyZWF0ZUZyb21JREFycmF5KAoJTFBDSVRFTUlETElTVCBwaWRsRm9sZGVyLAoJRFdPUkQgY3BpZGxGaWxlcywKCUxQQ0lURU1JRExJU1QgKmxwcGlkbEZpbGVzLAoJTFBEQVRBT0JKRUNUICpwcGRhdGFPYmplY3QpCnsKICAgIFVJTlQgaTsKICAgIEhXTkQgaHduZCA9IDA7ICAgLypGSVhNRTogd2hvIHNob3VsZCBiZSBod25kIG9mIG93bmVyPyBzZXQgdG8gZGVza3RvcCAqLwoKICAgIFRSQUNFKCIoJXAsICVsZCwgJXAsICVwKVxuIiwgcGlkbEZvbGRlciwgY3BpZGxGaWxlcywgbHBwaWRsRmlsZXMsIHBwZGF0YU9iamVjdCk7CiAgICBpZiAoVFJBQ0VfT04ocGlkbCkpCiAgICB7CglwZHVtcCAocGlkbEZvbGRlcik7Cglmb3IgKGk9MDsgaTxjcGlkbEZpbGVzOyBpKyspIHBkdW1wIChscHBpZGxGaWxlc1tpXSk7CiAgICB9CiAgICAqcHBkYXRhT2JqZWN0ID0gSURhdGFPYmplY3RfQ29uc3RydWN0b3IoIGh3bmQsIHBpZGxGb2xkZXIsCgkJCQkJICAgICBscHBpZGxGaWxlcywgY3BpZGxGaWxlcyk7CiAgICBpZiAoKnBwZGF0YU9iamVjdCkgcmV0dXJuIFNfT0s7CiAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hDcmVhdGVTdGRFbnVtRm10RXRjCQkJW1NIRUxMMzIuNzRdCiAqCiAqIE5PVEVTCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSENyZWF0ZVN0ZEVudW1GbXRFdGMoCglEV09SRCBjRm9ybWF0cywKCWNvbnN0IEZPUk1BVEVUQyAqbHBGb3JtYXRzLAoJTFBFTlVNRk9STUFURVRDICpwcGVudW1Gb3JtYXRldGMpCnsKCUlFbnVtRk9STUFURVRDICpwZWY7CglIUkVTVUxUIGhSZXM7CglUUkFDRSgiY2Y9JWxkIGZlPSVwIHBlZj0lcFxuIiwgY0Zvcm1hdHMsIGxwRm9ybWF0cywgcHBlbnVtRm9ybWF0ZXRjKTsKCglwZWYgPSBJRW51bUZPUk1BVEVUQ19Db25zdHJ1Y3RvcihjRm9ybWF0cywgbHBGb3JtYXRzKTsKCWlmICghcGVmKQoJICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCglJRW51bUZPUk1BVEVUQ19BZGRSZWYocGVmKTsKCWhSZXMgPSBJRW51bUZPUk1BVEVUQ19RdWVyeUludGVyZmFjZShwZWYsICZJSURfSUVudW1GT1JNQVRFVEMsIChMUFZPSUQqKXBwZW51bUZvcm1hdGV0Yyk7CglJRW51bUZPUk1BVEVUQ19SZWxlYXNlKHBlZik7CgoJcmV0dXJuIGhSZXM7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU0hFTEwzMl8yNTYgKFNIRUxMMzIuMjU2KQogKi8KSFJFU1VMVCBXSU5BUEkgU0hFTEwzMl8yNTYoTFBEV09SRCBscGR3MCwgTFBEV09SRCBscGR3MSkKewogICAgSFJFU1VMVCByZXQgPSBTX09LOwoKICAgIEZJWE1FKCJzdHViICVwIDB4JTA4bHggJXBcbiIsIGxwZHcwLCBscGR3MCA/ICpscGR3MCA6IDAsIGxwZHcxKTsKCiAgICBpZiAoIWxwZHcwIHx8ICpscGR3MCAhPSAweDEwKQogICAgICAgIHJldCA9IEVfSU5WQUxJREFSRzsKICAgIGVsc2UKICAgIHsKICAgICAgICBMUFZPSUQgbHBkYXRhID0gMDsvKkxvY2FsQWxsb2MoTE1FTV9aRVJPSU5JVCwgMHg0RTQpOyovCgoJaWYgKCFscGRhdGEpCiAgICAgICAgICAgIHJldCA9IEVfT1VUT0ZNRU1PUlk7CgllbHNlCgl7CiAgICAgICAgICAgIC8qIEluaXRpYWxpemUgYW5kIHJldHVybiB1bmtub3duIGxwZGF0YSBzdHJ1Y3R1cmUgKi8KCX0KICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJU0hGaW5kRmlsZXMgKFNIRUxMMzIuOTApCiAqLwpCT09MIFdJTkFQSSBTSEZpbmRGaWxlcyggTFBDSVRFTUlETElTVCBwaWRsRm9sZGVyLCBMUENJVEVNSURMSVNUIHBpZGxTYXZlRmlsZSApCnsKICAgIEZJWE1FKCIlcCAlcFxuIiwgcGlkbEZvbGRlciwgcGlkbFNhdmVGaWxlICk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSFVwZGF0ZUltYWdlVyAoU0hFTEwzMi4xOTIpCiAqCiAqIE5vdGlmaWVzIHRoZSBzaGVsbCB0aGF0IGFuIGljb24gaW4gdGhlIHN5c3RlbSBpbWFnZSBsaXN0IGhhcyBiZWVuIGNoYW5nZWQuCiAqCiAqIFBBUkFNUwogKiAgcHN6SGFzaEl0ZW0gW0ldIFBhdGggdG8gZmlsZSB0aGF0IGNvbnRhaW5zIHRoZSBpY29uLgogKiAgaUluZGV4ICAgICAgW0ldIFplcm8tYmFzZWQgaW5kZXggb2YgdGhlIGljb24gaW4gdGhlIGZpbGUuCiAqICB1RmxhZ3MgICAgICBbSV0gRmxhZ3MgZGV0ZXJtaW5pbmcgdGhlIGljb24gYXR0cmlidXRlcy4gU2VlIG5vdGVzLgogKiAgaUltYWdlSW5kZXggW0ldIEluZGV4IG9mIHRoZSBpY29uIGluIHRoZSBzeXN0ZW0gaW1hZ2UgbGlzdC4KICoKICogTk9URVMKICogIHVGbGFncyBjYW4gYmUgb25lIG9yIG1vcmUgb2YgdGhlIGZvbGxvd2luZyBmbGFnczoKICogIEdJTF9OT1RGSUxFTkFNRSAtIHBzekhhc2hJdGVtIGlzIG5vdCBhIGZpbGUgbmFtZS4KICogIEdJTF9TSU1VTEFURURPQyAtIENyZWF0ZSBhIGRvY3VtZW50IGljb24gdXNpbmcgdGhlIHNwZWNpZmllZCBpY29uLgogKi8Kdm9pZCBXSU5BUEkgU0hVcGRhdGVJbWFnZVcoTFBDV1NUUiBwc3pIYXNoSXRlbSwgaW50IGlJbmRleCwgVUlOVCB1RmxhZ3MsIGludCBpSW1hZ2VJbmRleCkKewogICAgRklYTUUoIiVzLCAlZCwgMHgleCwgJWQgLSBzdHViXG4iLCBkZWJ1Z3N0cl93KHBzekhhc2hJdGVtKSwgaUluZGV4LCB1RmxhZ3MsIGlJbWFnZUluZGV4KTsKfQoKVk9JRCBXSU5BUEkgU0hVcGRhdGVJbWFnZUEoTFBDU1RSIHBzekhhc2hJdGVtLCBJTlQgaUluZGV4LCBVSU5UIHVGbGFncywgSU5UIGlJbWFnZUluZGV4KQp7CiAgICBGSVhNRSgiJXMsICVkLCAweCV4LCAlZCAtIHN0dWJcbiIsIGRlYnVnc3RyX2EocHN6SGFzaEl0ZW0pLCBpSW5kZXgsIHVGbGFncywgaUltYWdlSW5kZXgpOwp9CgpJTlQgV0lOQVBJIFNISGFuZGxlVXBkYXRlSW1hZ2UoTFBDSVRFTUlETElTVCBwaWRsRXh0cmEpCnsKICAgIEZJWE1FKCIlcCAtIHN0dWJcbiIsIHBpZGxFeHRyYSk7CgogICAgcmV0dXJuIC0xOwp9CgpCT09MIFdJTkFQSSBTSE9iamVjdFByb3BlcnRpZXMoSFdORCBod25kLCBEV09SRCBkd1R5cGUsIExQQ1dTVFIgc3pPYmplY3QsIExQQ1dTVFIgc3pQYWdlKQp7CiAgICBGSVhNRSgiJXAsIDB4JTA4bHgsICVzLCAlcyAtIHN0dWJcbiIsIGh3bmQsIGR3VHlwZSwgZGVidWdzdHJfdyhzek9iamVjdCksIGRlYnVnc3RyX3coc3pQYWdlKSk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCkJPT0wgV0lOQVBJIFNIR2V0TmV3TGlua0luZm9BKExQQ1NUUiBwc3pMaW5rVG8sIExQQ1NUUiBwc3pEaXIsIExQU1RSIHBzek5hbWUsIEJPT0wgKnBmTXVzdENvcHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgdUZsYWdzKQp7CiAgICBGSVhNRSgiJXMsICVzLCAlcCwgJXAsIDB4JTA4eCAtIHN0dWJcbiIsIGRlYnVnc3RyX2EocHN6TGlua1RvKSwgZGVidWdzdHJfYShwc3pEaXIpLAogICAgICAgICAgcHN6TmFtZSwgcGZNdXN0Q29weSwgdUZsYWdzKTsKCiAgICByZXR1cm4gRkFMU0U7Cn0KCkJPT0wgV0lOQVBJIFNIR2V0TmV3TGlua0luZm9XKExQQ1dTVFIgcHN6TGlua1RvLCBMUENXU1RSIHBzekRpciwgTFBXU1RSIHBzek5hbWUsIEJPT0wgKnBmTXVzdENvcHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgdUZsYWdzKQp7CiAgICBGSVhNRSgiJXMsICVzLCAlcCwgJXAsIDB4JTA4eCAtIHN0dWJcbiIsIGRlYnVnc3RyX3cocHN6TGlua1RvKSwgZGVidWdzdHJfdyhwc3pEaXIpLAogICAgICAgICAgcHN6TmFtZSwgcGZNdXN0Q29weSwgdUZsYWdzKTsKCiAgICByZXR1cm4gRkFMU0U7Cn0KCkhSRVNVTFQgV0lOQVBJIFNIU3RhcnROZXRDb25uZWN0aW9uRGlhbG9nKEhXTkQgaHduZCwgTFBDU1RSIHBzelJlbW90ZU5hbWUsIERXT1JEIGR3VHlwZSkKewogICAgRklYTUUoIiVwLCAlcywgMHglMDhseCAtIHN0dWJcbiIsIGh3bmQsIGRlYnVnc3RyX2EocHN6UmVtb3RlTmFtZSksIGR3VHlwZSk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIFNIRW1wdHlSZWN5Y2xlQmluQShIV05EIGh3bmQsIExQQ1NUUiBwc3pSb290UGF0aCwgRFdPUkQgZHdGbGFncykKewogICAgRklYTUUoIiVwLCAlcywgMHglMDhseCAtIHN0dWJcbiIsIGh3bmQsIGRlYnVnc3RyX2EocHN6Um9vdFBhdGgpLCBkd0ZsYWdzKTsKCiAgICByZXR1cm4gU19PSzsKfQoKSFJFU1VMVCBXSU5BUEkgU0hFbXB0eVJlY3ljbGVCaW5XKEhXTkQgaHduZCwgTFBDV1NUUiBwc3pSb290UGF0aCwgRFdPUkQgZHdGbGFncykKewogICAgRklYTUUoIiVwLCAlcywgMHglMDhseCAtIHN0dWJcbiIsIGh3bmQsIGRlYnVnc3RyX3cocHN6Um9vdFBhdGgpLCBkd0ZsYWdzKTsKCiAgICByZXR1cm4gU19PSzsKfQoKRFdPUkQgV0lOQVBJIFNIRm9ybWF0RHJpdmUoSFdORCBod25kLCBVSU5UIGRyaXZlLCBVSU5UIGZtdElELCBVSU5UIG9wdGlvbnMpCnsKICAgIEZJWE1FKCIlcCwgMHglMDh4LCAweCUwOHgsIDB4JTA4eCAtIHN0dWJcbiIsIGh3bmQsIGRyaXZlLCBmbXRJRCwgb3B0aW9ucyk7CgogICAgcmV0dXJuIFNIRk1UX05PRk9STUFUOwp9CgpIUkVTVUxUIFdJTkFQSSBTSFF1ZXJ5UmVjeWNsZUJpbkEoTFBDU1RSIHBzelJvb3RQYXRoLCBMUFNIUVVFUllSQklORk8gcFNIUXVlcnlSQkluZm8pCnsKICAgIEZJWE1FKCIlcywgJXAgLSBzdHViXG4iLCBkZWJ1Z3N0cl9hKHBzelJvb3RQYXRoKSwgcFNIUXVlcnlSQkluZm8pOwoKICAgIHBTSFF1ZXJ5UkJJbmZvLT5pNjRTaXplID0gMDsKICAgIHBTSFF1ZXJ5UkJJbmZvLT5pNjROdW1JdGVtcyA9IDA7CgogICAgcmV0dXJuIFNfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIFNIUXVlcnlSZWN5Y2xlQmluVyhMUENXU1RSIHBzelJvb3RQYXRoLCBMUFNIUVVFUllSQklORk8gcFNIUXVlcnlSQkluZm8pCnsKICAgIEZJWE1FKCIlcywgJXAgLSBzdHViXG4iLCBkZWJ1Z3N0cl93KHBzelJvb3RQYXRoKSwgcFNIUXVlcnlSQkluZm8pOwoKICAgIHBTSFF1ZXJ5UkJJbmZvLT5pNjRTaXplID0gMDsKICAgIHBTSFF1ZXJ5UkJJbmZvLT5pNjROdW1JdGVtcyA9IDA7CgogICAgcmV0dXJuIFNfT0s7Cn0K