LyoKICogVGhlIHBhcmFtZXRlcnMgb2YgbWFueSBmdW5jdGlvbnMgY2hhbmdlcyBiZXR3ZWVuIGRpZmZlcmVudCBPUyB2ZXJzaW9ucwogKiAoTlQgdXNlcyBVbmljb2RlIHN0cmluZ3MsIDk1IHVzZXMgQVNDSUkgc3RyaW5ncykKICoKICogQ29weXJpZ2h0IDE5OTcgTWFyY3VzIE1laXNzbmVyCiAqICAgICAgICAgICAxOTk4IEr8cmdlbiBTY2htaWVkCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5ubHMuaCIKCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAic2hsZ3VpZC5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNoZWxsMzJfbWFpbi5oIgojaW5jbHVkZSAidW5kb2NzaGVsbC5oIgojaW5jbHVkZSAicGlkbC5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoc2hlbGwpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChwaWRsKTsKCi8qIEZJWE1FOiAhISEgbW92ZSBDUkVBVEVNUlVMSVNUIGFuZCBmbGFncyB0byBoZWFkZXIgZmlsZSAhISEgKi8KLyogICAgICAgICEhISBpdCBpcyBpbiBib3RoIGhlcmUgYW5kIGNvbWN0bDMydW5kb2MuYyAgICAgICEhISAqLwp0eXBlZGVmIHN0cnVjdCB0YWdDUkVBVEVNUlVMSVNUCnsKICAgIERXT1JEICBjYlNpemU7ICAgICAgICAvKiBzaXplIG9mIHN0cnVjdCAqLwogICAgRFdPUkQgIG5NYXhJdGVtczsgICAgIC8qIG1heCBuby4gb2YgaXRlbXMgaW4gbGlzdCAqLwogICAgRFdPUkQgIGR3RmxhZ3M7ICAgICAgIC8qIHNlZSBiZWxvdyAqLwogICAgSEtFWSAgIGhLZXk7ICAgICAgICAgIC8qIHJvb3QgcmVnLiBrZXkgdW5kZXIgd2hpY2ggbGlzdCBpcyBzYXZlZCAqLwogICAgTFBDU1RSIGxwc3pTdWJLZXk7ICAgIC8qIHJlZy4gc3Via2V5ICovCiAgICBQUk9DICAgbHBmbkNvbXBhcmU7ICAgLyogaXRlbSBjb21wYXJlIHByb2MgKi8KfSBDUkVBVEVNUlVMSVNUQSwgKkxQQ1JFQVRFTVJVTElTVEE7CgovKiBkd0ZsYWdzICovCiNkZWZpbmUgTVJVRl9TVFJJTkdfTElTVCAgMCAvKiBsaXN0IHdpbGwgY29udGFpbiBzdHJpbmdzICovCiNkZWZpbmUgTVJVRl9CSU5BUllfTElTVCAgMSAvKiBsaXN0IHdpbGwgY29udGFpbiBiaW5hcnkgZGF0YSAqLwojZGVmaW5lIE1SVUZfREVMQVlFRF9TQVZFIDIgLyogb25seSBzYXZlIGxpc3Qgb3JkZXIgdG8gcmVnLiBpcyBGcmVlTVJVTGlzdCAqLwoKZXh0ZXJuIEhBTkRMRSBXSU5BUEkgQ3JlYXRlTVJVTGlzdEEoTFBDUkVBVEVNUlVMSVNUQSBscGNtbCk7CmV4dGVybiBEV09SRCAgV0lOQVBJIEZyZWVNUlVMaXN0KEhBTkRMRSBoTVJVTGlzdCk7CmV4dGVybiBJTlQgICAgV0lOQVBJIEFkZE1SVURhdGEoSEFORExFIGhMaXN0LCBMUENWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhKTsKZXh0ZXJuIElOVCAgICBXSU5BUEkgRmluZE1SVURhdGEoSEFORExFIGhMaXN0LCBMUENWT0lEIGxwRGF0YSwgRFdPUkQgY2JEYXRhLCBMUElOVCBscFJlZ051bSk7CmV4dGVybiBJTlQgICAgV0lOQVBJIEVudW1NUlVMaXN0QShIQU5ETEUgaExpc3QsIElOVCBuSXRlbVBvcywgTFBWT0lEIGxwQnVmZmVyLCBEV09SRCBuQnVmZmVyU2l6ZSk7CgoKLyogR2V0IGEgZnVuY3Rpb24gcG9pbnRlciBmcm9tIGEgRExMIGhhbmRsZSAqLwojZGVmaW5lIEdFVF9GVU5DKGZ1bmMsIG1vZHVsZSwgbmFtZSwgZmFpbCkgXAogIGRvIHsgXAogICAgaWYgKCFmdW5jKSB7IFwKICAgICAgaWYgKCFTSEVMTDMyX2gjI21vZHVsZSAmJiAhKFNIRUxMMzJfaCMjbW9kdWxlID0gTG9hZExpYnJhcnlBKCNtb2R1bGUgIi5kbGwiKSkpIHJldHVybiBmYWlsOyBcCiAgICAgIGZ1bmMgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoU0hFTEwzMl9oIyNtb2R1bGUsIG5hbWUpOyBcCiAgICAgIGlmICghZnVuYykgcmV0dXJuIGZhaWw7IFwKICAgIH0gXAogIH0gd2hpbGUgKDApCgovKiBGdW5jdGlvbiBwb2ludGVycyBmb3IgR0VUX0ZVTkMgbWFjcm8gKi8Kc3RhdGljIEhNT0RVTEUgU0hFTEwzMl9oc2hsd2FwaT1OVUxMOwpzdGF0aWMgSEFORExFIChXSU5BUEkgKnBTSEFsbG9jU2hhcmVkKShMUENWT0lELERXT1JELERXT1JEKTsKc3RhdGljIExQVk9JRCAoV0lOQVBJICpwU0hMb2NrU2hhcmVkKShIQU5ETEUsRFdPUkQpOwpzdGF0aWMgQk9PTCAgIChXSU5BUEkgKnBTSFVubG9ja1NoYXJlZCkoTFBWT0lEKTsKc3RhdGljIEJPT0wgICAoV0lOQVBJICpwU0hGcmVlU2hhcmVkKShIQU5ETEUsRFdPUkQpOwoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFBhcnNlRmllbGRBCQkJCQlbaW50ZXJuYWxdCiAqCiAqIGNvcGllcyBhIGZpZWxkIGZyb20gYSAnLCcgZGVsaW1pdGVkIHN0cmluZwogKgogKiBmaXJzdCBmaWVsZCBpcyBuRmllbGQgPSAxCiAqLwpEV09SRCBXSU5BUEkgUGFyc2VGaWVsZEEoCglMUENTVFIgc3JjLAoJRFdPUkQgbkZpZWxkLAoJTFBTVFIgZHN0LAoJRFdPUkQgbGVuKQp7CglXQVJOKCIoJXMsMHglMDhseCwlcCwlbGQpIHNlbWktc3R1Yi5cbiIsZGVidWdzdHJfYShzcmMpLG5GaWVsZCxkc3QsbGVuKTsKCglpZiAoIXNyYyB8fCAhc3JjWzBdIHx8ICFkc3QgfHwgIWxlbikKCSAgcmV0dXJuIDA7CgoJLyogc2tpcCBuIGZpZWxkcyBkZWxpbWl0ZWQgYnkgJywnICovCgl3aGlsZSAobkZpZWxkID4gMSkKCXsKCSAgaWYgKCpzcmM9PSdcMCcpIHJldHVybiBGQUxTRTsKCSAgaWYgKCooc3JjKyspPT0nLCcpIG5GaWVsZC0tOwoJfQoKCS8qIGNvcHkgcGFydCB0aWxsIHRoZSBuZXh0ICcsJyB0byBkc3QgKi8KCXdoaWxlICggKnNyYyE9J1wwJyAmJiAqc3JjIT0nLCcgJiYgKGxlbi0tKT4wICkgKihkc3QrKyk9KihzcmMrKyk7CgoJLyogZmluYWxpemUgdGhlIHN0cmluZyAqLwoJKmRzdD0weDA7CgoJcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFBhcnNlRmllbGRXCQkJW2ludGVybmFsXQogKgogKiBjb3BpZXMgYSBmaWVsZCBmcm9tIGEgJywnIGRlbGltaXRlZCBzdHJpbmcKICoKICogZmlyc3QgZmllbGQgaXMgbkZpZWxkID0gMQogKi8KRFdPUkQgV0lOQVBJIFBhcnNlRmllbGRXKExQQ1dTVFIgc3JjLCBEV09SRCBuRmllbGQsIExQV1NUUiBkc3QsIERXT1JEIGxlbikKewoJV0FSTigiKCVzLDB4JTA4bHgsJXAsJWxkKSBzZW1pLXN0dWIuXG4iLCBkZWJ1Z3N0cl93KHNyYyksIG5GaWVsZCwgZHN0LCBsZW4pOwoKCWlmICghc3JjIHx8ICFzcmNbMF0gfHwgIWRzdCB8fCAhbGVuKQoJICByZXR1cm4gMDsKCgkvKiBza2lwIG4gZmllbGRzIGRlbGltaXRlZCBieSAnLCcgKi8KCXdoaWxlIChuRmllbGQgPiAxKQoJewoJICBpZiAoKnNyYyA9PSAweDApIHJldHVybiBGQUxTRTsKCSAgaWYgKCpzcmMrKyA9PSAnLCcpIG5GaWVsZC0tOwoJfQoKCS8qIGNvcHkgcGFydCB0aWxsIHRoZSBuZXh0ICcsJyB0byBkc3QgKi8KCXdoaWxlICggKnNyYyAhPSAweDAgJiYgKnNyYyAhPSAnLCcgJiYgKGxlbi0tKT4wICkgKihkc3QrKykgPSAqKHNyYysrKTsKCgkvKiBmaW5hbGl6ZSB0aGUgc3RyaW5nICovCgkqZHN0ID0gMHgwOwoKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQYXJzZUZpZWxkCQkJW1NIRUxMMzIuNThdCiAqLwpEV09SRCBXSU5BUEkgUGFyc2VGaWVsZEFXKExQQ1ZPSUQgc3JjLCBEV09SRCBuRmllbGQsIExQVk9JRCBkc3QsIERXT1JEIGxlbikKewoJaWYgKFNIRUxMX09zSXNVbmljb2RlKCkpCgkgIHJldHVybiBQYXJzZUZpZWxkVyhzcmMsIG5GaWVsZCwgZHN0LCBsZW4pOwoJcmV0dXJuIFBhcnNlRmllbGRBKHNyYywgbkZpZWxkLCBkc3QsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEdldEZpbGVOYW1lRnJvbUJyb3dzZQkJCVtTSEVMTDMyLjYzXQogKgogKi8KQk9PTCBXSU5BUEkgR2V0RmlsZU5hbWVGcm9tQnJvd3NlKAoJSFdORCBod25kT3duZXIsCglMUFNUUiBscHN0ckZpbGUsCglEV09SRCBuTWF4RmlsZSwKCUxQQ1NUUiBscHN0ckluaXRpYWxEaXIsCglMUENTVFIgbHBzdHJEZWZFeHQsCglMUENTVFIgbHBzdHJGaWx0ZXIsCglMUENTVFIgbHBzdHJUaXRsZSkKewogICAgSE1PRFVMRSBobW9kdWxlOwogICAgRkFSUFJPQyBwR2V0T3BlbkZpbGVOYW1lQTsKICAgIE9QRU5GSUxFTkFNRUEgb2ZuOwogICAgQk9PTCByZXQ7CgogICAgVFJBQ0UoIiVwLCAlcywgJWxkLCAlcywgJXMsICVzLCAlcylcbiIsCgkgIGh3bmRPd25lciwgbHBzdHJGaWxlLCBuTWF4RmlsZSwgbHBzdHJJbml0aWFsRGlyLCBscHN0ckRlZkV4dCwKCSAgbHBzdHJGaWx0ZXIsIGxwc3RyVGl0bGUpOwoKICAgIGhtb2R1bGUgPSBMb2FkTGlicmFyeUEoImNvbWRsZzMyLmRsbCIpOwogICAgaWYoIWhtb2R1bGUpIHJldHVybiBGQUxTRTsKICAgIHBHZXRPcGVuRmlsZU5hbWVBID0gR2V0UHJvY0FkZHJlc3MoaG1vZHVsZSwgIkdldE9wZW5GaWxlTmFtZUEiKTsKICAgIGlmKCFwR2V0T3BlbkZpbGVOYW1lQSkKICAgIHsKCUZyZWVMaWJyYXJ5KGhtb2R1bGUpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIG1lbXNldCgmb2ZuLCAwLCBzaXplb2Yob2ZuKSk7CgogICAgb2ZuLmxTdHJ1Y3RTaXplID0gc2l6ZW9mKG9mbik7CiAgICBvZm4uaHduZE93bmVyID0gaHduZE93bmVyOwogICAgb2ZuLmxwc3RyRmlsdGVyID0gbHBzdHJGaWx0ZXI7CiAgICBvZm4ubHBzdHJGaWxlID0gbHBzdHJGaWxlOwogICAgb2ZuLm5NYXhGaWxlID0gbk1heEZpbGU7CiAgICBvZm4ubHBzdHJJbml0aWFsRGlyID0gbHBzdHJJbml0aWFsRGlyOwogICAgb2ZuLmxwc3RyVGl0bGUgPSBscHN0clRpdGxlOwogICAgb2ZuLmxwc3RyRGVmRXh0ID0gbHBzdHJEZWZFeHQ7CiAgICBvZm4uRmxhZ3MgPSBPRk5fRVhQTE9SRVIgfCBPRk5fSElERVJFQURPTkxZIHwgT0ZOX0ZJTEVNVVNURVhJU1Q7CiAgICByZXQgPSBwR2V0T3BlbkZpbGVOYW1lQSgmb2ZuKTsKCiAgICBGcmVlTGlicmFyeShobW9kdWxlKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIR2V0U2V0U2V0dGluZ3MJCQkJW1NIRUxMMzIuNjhdCiAqLwpWT0lEIFdJTkFQSSBTSEdldFNldFNldHRpbmdzKExQU0hFTExTVEFURSBscHNzLCBEV09SRCBkd01hc2ssIEJPT0wgYlNldCkKewogIGlmKGJTZXQpCiAgewogICAgRklYTUUoIiVwIDB4JTA4bHggVFJVRVxuIiwgbHBzcywgZHdNYXNrKTsKICB9CiAgZWxzZQogIHsKICAgIFNIR2V0U2V0dGluZ3MoKExQU0hFTExGTEFHU1RBVEUpbHBzcyxkd01hc2spOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hHZXRTZXR0aW5ncwkJCQlbU0hFTEwzMi5AXQogKgogKiBOT1RFUwogKiAgdGhlIHJlZ2lzdHJ5IHBhdGggYXJlIGZvciB3aW45OCAodGVzdGVkKQogKiAgYW5kIHBvc3NpYmx5IGFyZSB0aGUgc2FtZSBpbiBudDQwCiAqCiAqLwpWT0lEIFdJTkFQSSBTSEdldFNldHRpbmdzKExQU0hFTExGTEFHU1RBVEUgbHBzZnMsIERXT1JEIGR3TWFzaykKewoJSEtFWQloS2V5OwoJRFdPUkQJZHdEYXRhOwoJRFdPUkQJZHdEYXRhU2l6ZSA9IHNpemVvZiAoRFdPUkQpOwoKCVRSQUNFKCIoJXAgMHglMDhseClcbiIsbHBzZnMsZHdNYXNrKTsKCglpZiAoUmVnQ3JlYXRlS2V5RXhBKEhLRVlfQ1VSUkVOVF9VU0VSLCAiU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXEV4cGxvcmVyXFxBZHZhbmNlZCIsCgkJCQkgMCwgMCwgMCwgS0VZX0FMTF9BQ0NFU1MsIDAsICZoS2V5LCAwKSkKCSAgcmV0dXJuOwoKCWlmICggKFNTRl9TSE9XRVhURU5TSU9OUyAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIkhpZGVGaWxlRXh0IiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mU2hvd0V4dGVuc2lvbnMgID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICggKFNTRl9TSE9XSU5GT1RJUCAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIlNob3dJbmZvVGlwIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mU2hvd0luZm9UaXAgID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICggKFNTRl9ET05UUFJFVFRZUEFUSCAmIGR3TWFzaykgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoaEtleSwgIkRvbnRQcmV0dHlQYXRoIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgkgIGxwc2ZzLT5mRG9udFByZXR0eVBhdGggID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICggKFNTRl9ISURFSUNPTlMgJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJIaWRlSWNvbnMiLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZIaWRlSWNvbnMgID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICggKFNTRl9NQVBORVREUlZCVVRUT04gJiBkd01hc2spICYmICFSZWdRdWVyeVZhbHVlRXhBKGhLZXksICJNYXBOZXREcnZCdG4iLCAwLCAwLCAoTFBCWVRFKSZkd0RhdGEsICZkd0RhdGFTaXplKSkKCSAgbHBzZnMtPmZNYXBOZXREcnZCdG4gID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICggKFNTRl9TSE9XQVRUUklCQ09MICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiU2hvd0F0dHJpYkNvbCIsIDAsIDAsIChMUEJZVEUpJmR3RGF0YSwgJmR3RGF0YVNpemUpKQoJICBscHNmcy0+ZlNob3dBdHRyaWJDb2wgID0gKChkd0RhdGEgPT0gMCkgPyAgMCA6IDEpOwoKCWlmICgoKFNTRl9TSE9XQUxMT0JKRUNUUyB8IFNTRl9TSE9XU1lTRklMRVMpICYgZHdNYXNrKSAmJiAhUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCAiSGlkZGVuIiwgMCwgMCwgKExQQllURSkmZHdEYXRhLCAmZHdEYXRhU2l6ZSkpCgl7IGlmIChkd0RhdGEgPT0gMCkKCSAgeyBpZiAoU1NGX1NIT1dBTExPQkpFQ1RTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dBbGxPYmplY3RzICA9IDA7CgkgICAgaWYgKFNTRl9TSE9XU1lTRklMRVMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd1N5c0ZpbGVzICA9IDA7CgkgIH0KCSAgZWxzZSBpZiAoZHdEYXRhID09IDEpCgkgIHsgaWYgKFNTRl9TSE9XQUxMT0JKRUNUUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93QWxsT2JqZWN0cyAgPSAxOwoJICAgIGlmIChTU0ZfU0hPV1NZU0ZJTEVTICYgZHdNYXNrKQlscHNmcy0+ZlNob3dTeXNGaWxlcyAgPSAwOwoJICB9CgkgIGVsc2UgaWYgKGR3RGF0YSA9PSAyKQoJICB7IGlmIChTU0ZfU0hPV0FMTE9CSkVDVFMgJiBkd01hc2spCWxwc2ZzLT5mU2hvd0FsbE9iamVjdHMgID0gMDsKCSAgICBpZiAoU1NGX1NIT1dTWVNGSUxFUyAmIGR3TWFzaykJbHBzZnMtPmZTaG93U3lzRmlsZXMgID0gMTsKCSAgfQoJfQoJUmVnQ2xvc2VLZXkgKGhLZXkpOwoKCVRSQUNFKCItLSAweCUwNHhcbiIsICooV09SRCopbHBzZnMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFNoZWxsRm9sZGVyVmlld19NZXNzYWdlCQkJW1NIRUxMMzIuNzNdCiAqCiAqIFNlbmQgYSBtZXNzYWdlIHRvIGFuIGV4cGxvcmVyIGNhYmluZXQgd2luZG93LgogKgogKiBQQVJBTVMKICogIGh3bmRDYWJpbmV0IFtJXSBUaGUgd2luZG93IGNvbnRhaW5pbmcgdGhlIHNoZWxsdmlldyB0byBjb21tdW5pY2F0ZSB3aXRoCiAqICBkd01lc3NhZ2UgICBbSV0gVGhlIFNGVk0gbWVzc2FnZSB0byBzZW5kCiAqICBkd1BhcmFtICAgICBbSV0gTWVzc2FnZSBwYXJhbWV0ZXIKICoKICogUkVUVVJOUwogKiAgZml4bWUuCiAqCiAqIE5PVEVTCiAqICBNZXNzYWdlIFNGVk1fUkVBUlJBTkdFID0gMQogKgogKiAgICBUaGlzIG1lc3NhZ2UgZ2V0cyBzZW50IHdoZW4gYSBjb2x1bW4gZ2V0cyBjbGlja2VkIHRvIGluc3RydWN0IHRoZQogKiAgICBzaGVsbCB2aWV3IHRvIHJlLXNvcnQgdGhlIGl0ZW0gbGlzdC4gZHdQYXJhbSBpZGVudGlmaWVzIHRoZSBjb2x1bW4KICogICAgdGhhdCB3YXMgY2xpY2tlZC4KICovCkxSRVNVTFQgV0lOQVBJIFNIU2hlbGxGb2xkZXJWaWV3X01lc3NhZ2UoCglIV05EIGh3bmRDYWJpbmV0LAoJVUlOVCB1TWVzc2FnZSwKCUxQQVJBTSBsUGFyYW0pCnsKCUZJWE1FKCIlcCAlMDh4ICUwOGx4IHN0dWJcbiIsaHduZENhYmluZXQsIHVNZXNzYWdlLCBsUGFyYW0pOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlZ2lzdGVyU2hlbGxIb29rCQkJCVtTSEVMTDMyLjE4MV0KICoKICogUmVnaXN0ZXIgYSBzaGVsbCBob29rLgogKgogKiBQQVJBTVMKICogICAgICBod25kICAgW0ldICBXaW5kb3cgaGFuZGxlCiAqICAgICAgZHdUeXBlIFtJXSAgVHlwZSBvZiBob29rLgogKgogKiBOT1RFUwogKiAgICAgRXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KQk9PTCBXSU5BUEkgUmVnaXN0ZXJTaGVsbEhvb2soCglIV05EIGhXbmQsCglEV09SRCBkd1R5cGUpCnsKCUZJWE1FKCIoJXAsMHglMDhseCk6c3R1Yi5cbiIsaFduZCwgZHdUeXBlKTsKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTaGVsbE1lc3NhZ2VCb3hXCQkJCVtTSEVMTDMyLjE4Ml0KICoKICogU2VlIFNoZWxsTWVzc2FnZUJveEEuCiAqLwppbnQgV0lOQVBJViBTaGVsbE1lc3NhZ2VCb3hXKAoJSElOU1RBTkNFIGhJbnN0YW5jZSwKCUhXTkQgaFduZCwKCUxQQ1dTVFIgbHBUZXh0LAoJTFBDV1NUUiBscENhcHRpb24sCglVSU5UIHVUeXBlLAoJLi4uKQp7CglXQ0hBUglzelRleHRbMTAwXSxzelRpdGxlWzEwMF07CglMUENXU1RSIHBzelRleHQgPSBzelRleHQsIHBzelRpdGxlID0gc3pUaXRsZSwgcHN6VGVtcDsKCXZhX2xpc3QgYXJnczsKCWludAlyZXQ7CgoJdmFfc3RhcnQoYXJncywgdVR5cGUpOwoJLyogd3ZzcHJpbnRmQShidWYsZm10LCBhcmdzKTsgKi8KCglUUkFDRSgiKCVwLCVwLCVwLCVwLCUwOHgpXG4iLAoJICAgIGhJbnN0YW5jZSxoV25kLGxwVGV4dCxscENhcHRpb24sdVR5cGUpOwoKCWlmIChJU19JTlRSRVNPVVJDRShscENhcHRpb24pKQoJICBMb2FkU3RyaW5nVyhoSW5zdGFuY2UsIExPV09SRChscENhcHRpb24pLCBzelRpdGxlLCBzaXplb2Yoc3pUaXRsZSkvc2l6ZW9mKHN6VGl0bGVbMF0pKTsKCWVsc2UKCSAgcHN6VGl0bGUgPSBscENhcHRpb247CgoJaWYgKElTX0lOVFJFU09VUkNFKGxwVGV4dCkpCgkgIExvYWRTdHJpbmdXKGhJbnN0YW5jZSwgTE9XT1JEKGxwVGV4dCksIHN6VGV4dCwgc2l6ZW9mKHN6VGV4dCkvc2l6ZW9mKHN6VGV4dFswXSkpOwoJZWxzZQoJICBwc3pUZXh0ID0gbHBUZXh0OwoKCUZvcm1hdE1lc3NhZ2VXKEZPUk1BVF9NRVNTQUdFX0FMTE9DQVRFX0JVRkZFUiB8IEZPUk1BVF9NRVNTQUdFX0ZST01fU1RSSU5HLAoJCSAgICAgICBwc3pUZXh0LCAwLCAwLCAoTFBXU1RSKSZwc3pUZW1wLCAwLCAmYXJncyk7CgoJdmFfZW5kKGFyZ3MpOwoKCXJldCA9IE1lc3NhZ2VCb3hXKGhXbmQscHN6VGVtcCxwc3pUaXRsZSx1VHlwZSk7CglMb2NhbEZyZWUoKEhMT0NBTClwc3pUZW1wKTsKCXJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNoZWxsTWVzc2FnZUJveEEJCQkJW1NIRUxMMzIuMTgzXQogKgogKiBGb3JtYXQgYW5kIG91dHB1dCBhbiBlcnJvciBtZXNzYWdlLgogKgogKiBQQVJBTVMKICogIGhJbnN0YW5jZSBbSV0gSW5zdGFuY2UgaGFuZGxlIG9mIG1lc3NhZ2UgY3JlYXRvcgogKiAgaFduZCAgICAgIFtJXSBXaW5kb3cgaGFuZGxlIG9mIG1lc3NhZ2UgY3JlYXRvcgogKiAgbHBUZXh0ICAgIFtJXSBSZXNvdXJjZSBJZCBvZiB0aXRsZSBvciBMUFNUUgogKiAgbHBDYXB0aW9uIFtJXSBSZXNvdXJjZSBJZCBvZiB0aXRsZSBvciBMUFNUUgogKiAgdVR5cGUgICAgIFtJXSBUeXBlIG9mIGVycm9yIG1lc3NhZ2UKICoKICogUkVUVVJOUwogKiAgQSByZXR1cm4gdmFsdWUgZnJvbSBNZXNzYWdlQm94QSgpLgogKgogKiBOT1RFUwogKiAgICAgRXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KaW50IFdJTkFQSVYgU2hlbGxNZXNzYWdlQm94QSgKCUhJTlNUQU5DRSBoSW5zdGFuY2UsCglIV05EIGhXbmQsCglMUENTVFIgbHBUZXh0LAoJTFBDU1RSIGxwQ2FwdGlvbiwKCVVJTlQgdVR5cGUsCgkuLi4pCnsKCWNoYXIJc3pUZXh0WzEwMF0sc3pUaXRsZVsxMDBdOwoJTFBDU1RSICBwc3pUZXh0ID0gc3pUZXh0LCBwc3pUaXRsZSA9IHN6VGl0bGUsIHBzelRlbXA7Cgl2YV9saXN0IGFyZ3M7CglpbnQJcmV0OwoKCXZhX3N0YXJ0KGFyZ3MsIHVUeXBlKTsKCS8qIHd2c3ByaW50ZkEoYnVmLGZtdCwgYXJncyk7ICovCgoJVFJBQ0UoIiglcCwlcCwlcCwlcCwlMDh4KVxuIiwKCSAgICBoSW5zdGFuY2UsaFduZCxscFRleHQsbHBDYXB0aW9uLHVUeXBlKTsKCglpZiAoSVNfSU5UUkVTT1VSQ0UobHBDYXB0aW9uKSkKCSAgTG9hZFN0cmluZ0EoaEluc3RhbmNlLCBMT1dPUkQobHBDYXB0aW9uKSwgc3pUaXRsZSwgc2l6ZW9mKHN6VGl0bGUpKTsKCWVsc2UKCSAgcHN6VGl0bGUgPSBscENhcHRpb247CgoJaWYgKElTX0lOVFJFU09VUkNFKGxwVGV4dCkpCgkgIExvYWRTdHJpbmdBKGhJbnN0YW5jZSwgTE9XT1JEKGxwVGV4dCksIHN6VGV4dCwgc2l6ZW9mKHN6VGV4dCkpOwoJZWxzZQoJICBwc3pUZXh0ID0gbHBUZXh0OwoKCUZvcm1hdE1lc3NhZ2VBKEZPUk1BVF9NRVNTQUdFX0FMTE9DQVRFX0JVRkZFUiB8IEZPUk1BVF9NRVNTQUdFX0ZST01fU1RSSU5HLAoJCSAgICAgICBwc3pUZXh0LCAwLCAwLCAoTFBTVFIpJnBzelRlbXAsIDAsICZhcmdzKTsKCgl2YV9lbmQoYXJncyk7CgoJcmV0ID0gTWVzc2FnZUJveEEoaFduZCxwc3pUZW1wLHBzelRpdGxlLHVUeXBlKTsKCUxvY2FsRnJlZSgoSExPQ0FMKXBzelRlbXApOwoJcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hSZWdpc3RlckRyYWdEcm9wCQkJCVtTSEVMTDMyLjg2XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZWdpc3RlckRyYWdEcm9wKAoJSFdORCBoV25kLAoJTFBEUk9QVEFSR0VUIHBEcm9wVGFyZ2V0KQp7CglGSVhNRSgiKCVwLCVwKTpzdHViLlxuIiwgaFduZCwgcERyb3BUYXJnZXQpOwoJcmV0dXJuIFJlZ2lzdGVyRHJhZ0Ryb3AoaFduZCwgcERyb3BUYXJnZXQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSFJldm9rZURyYWdEcm9wCQkJCVtTSEVMTDMyLjg3XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KSFJFU1VMVCBXSU5BUEkgU0hSZXZva2VEcmFnRHJvcChIV05EIGhXbmQpCnsKICAgIEZJWE1FKCIoJXApOnN0dWIuXG4iLGhXbmQpOwogICAgcmV0dXJuIFJldm9rZURyYWdEcm9wKGhXbmQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSERvRHJhZ0Ryb3AJCQkJCVtTSEVMTDMyLjg4XQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KSFJFU1VMVCBXSU5BUEkgU0hEb0RyYWdEcm9wKAoJSFdORCBoV25kLAoJTFBEQVRBT0JKRUNUIGxwRGF0YU9iamVjdCwKCUxQRFJPUFNPVVJDRSBscERyb3BTb3VyY2UsCglEV09SRCBkd09LRWZmZWN0LAoJTFBEV09SRCBwZHdFZmZlY3QpCnsKICAgIEZJWE1FKCIoJXAgJXAgJXAgMHglMDhseCAlcCk6c3R1Yi5cbiIsCiAgICBoV25kLCBscERhdGFPYmplY3QsIGxwRHJvcFNvdXJjZSwgZHdPS0VmZmVjdCwgcGR3RWZmZWN0KTsKCXJldHVybiBEb0RyYWdEcm9wKGxwRGF0YU9iamVjdCwgbHBEcm9wU291cmNlLCBkd09LRWZmZWN0LCBwZHdFZmZlY3QpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBcnJhbmdlV2luZG93cwkJCQlbU0hFTEwzMi4xODRdCiAqCiAqLwpXT1JEIFdJTkFQSSBBcnJhbmdlV2luZG93cygKCUhXTkQgaHduZFBhcmVudCwKCURXT1JEIGR3UmVzZXJ2ZWQsCglMUENSRUNUIGxwUmVjdCwKCVdPUkQgY0tpZHMsCglDT05TVCBIV05EICogbHBLaWRzKQp7CiAgICBGSVhNRSgiKCVwIDB4JTA4bHggJXAgMHglMDR4ICVwKTpzdHViLlxuIiwKCSAgIGh3bmRQYXJlbnQsIGR3UmVzZXJ2ZWQsIGxwUmVjdCwgY0tpZHMsIGxwS2lkcyk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2lnbmFsRmlsZU9wZW4JCQkJW1NIRUxMMzIuMTAzXQogKgogKiBOT1RFUwogKiAgICAgZXhwb3J0ZWQgYnkgb3JkaW5hbAogKi8KRFdPUkQgV0lOQVBJClNpZ25hbEZpbGVPcGVuIChEV09SRCBkd1BhcmFtMSkKewogICAgRklYTUUoIigweCUwOGx4KTpzdHViLlxuIiwgZHdQYXJhbTEpOwoKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFERF9nZXRfcG9saWN5IC0gaGVscGVyIGZ1bmN0aW9uIGZvciBTSEFkZFRvUmVjZW50RG9jcwogKgogKiBQQVJBTUVURVJTCiAqICAgcG9saWN5ICAgIFtJTl0gIHBvbGljeSBuYW1lIChudWxsIHRlcm1lZCBzdHJpbmcpIHRvIGZpbmQKICogICB0eXBlICAgICAgW09VVF0gcHRyIHRvIERXT1JEIHRvIHJlY2VpdmUgdHlwZQogKiAgIGJ1ZmZlciAgICBbT1VUXSBwdHIgdG8gYXJlYSB0byBob2xkIGRhdGEgcmV0cmlldmVkCiAqICAgbGVuICAgICAgIFtJTi9PVVRdIHB0ciB0byBEV09SRCBob2xkaW5nIHNpemUgb2YgYnVmZmVyIGFuZCBnZXR0aW5nCiAqICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCBmaWxsZWQKICoKICogUkVUVVJOUwogKiAgIHJlc3VsdCBvZiB0aGUgU0hRdWVyeVZhbHVlRXggY2FsbAogKi8Kc3RhdGljIElOVCBTSEFERF9nZXRfcG9saWN5KExQU1RSIHBvbGljeSwgTFBEV09SRCB0eXBlLCBMUFZPSUQgYnVmZmVyLCBMUERXT1JEIGxlbikKewogICAgSEtFWSBQb2xpY3lfYmFzZWtleTsKICAgIElOVCByZXQ7CgogICAgLyogR2V0IHRoZSBrZXkgZm9yIHRoZSBwb2xpY2llcyBsb2NhdGlvbiBpbiB0aGUgcmVnaXN0cnkKICAgICAqLwogICAgaWYgKFJlZ09wZW5LZXlFeEEoSEtFWV9MT0NBTF9NQUNISU5FLAoJCSAgICAgICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50VmVyc2lvblxcUG9saWNpZXNcXEV4cGxvcmVyIiwKCQkgICAgICAwLCBLRVlfUkVBRCwgJlBvbGljeV9iYXNla2V5KSkgewoKCWlmIChSZWdPcGVuS2V5RXhBKEhLRVlfQ1VSUkVOVF9VU0VSLAoJCQkgICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50VmVyc2lvblxcUG9saWNpZXNcXEV4cGxvcmVyIiwKCQkJICAwLCBLRVlfUkVBRCwgJlBvbGljeV9iYXNla2V5KSkgewoJICAgIFRSQUNFKCJObyBFeHBsb3JlciBQb2xpY2llcyBsb2NhdGlvbiBleGlzdHMuIFBvbGljeSB3YW50ZWQ9JXNcbiIsCgkJICBwb2xpY3kpOwoJICAgICpsZW4gPSAwOwoJICAgIHJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKCX0KICAgIH0KCiAgICAvKiBSZXRyaWV2ZSB0aGUgZGF0YSBpZiBpdCBleGlzdHMKICAgICAqLwogICAgcmV0ID0gU0hRdWVyeVZhbHVlRXhBKFBvbGljeV9iYXNla2V5LCBwb2xpY3ksIDAsIHR5cGUsIGJ1ZmZlciwgbGVuKTsKICAgIFJlZ0Nsb3NlS2V5KFBvbGljeV9iYXNla2V5KTsKICAgIHJldHVybiByZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFERF9jb21wYXJlX21ydSAtIGhlbHBlciBmdW5jdGlvbiBmb3IgU0hBZGRUb1JlY2VudERvY3MKICoKICogUEFSQU1FVEVSUwogKiAgIGRhdGExICAgICBbSU5dIGRhdGEgYmVpbmcgbG9va2VkIGZvcgogKiAgIGRhdGEyICAgICBbSU5dIGRhdGEgaW4gTVJVCiAqICAgY2JkYXRhICAgIFtJTl0gbGVuZ3RoIGZyb20gRmluZE1SVURhdGEgY2FsbCAobm90IHVzZWQpCiAqCiAqIFJFVFVSTlMKICogICBwb3NpdGlvbiB3aXRoaW4gTVJVIGxpc3QgdGhhdCBkYXRhIHdhcyBhZGRlZC4KICovCnN0YXRpYyBJTlQgQ0FMTEJBQ0sgU0hBRERfY29tcGFyZV9tcnUoTFBDVk9JRCBkYXRhMSwgTFBDVk9JRCBkYXRhMiwgRFdPUkQgY2JEYXRhKQp7CiAgICByZXR1cm4gbHN0cmNtcGlBKGRhdGExLCBkYXRhMik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQUREX2NyZWF0ZV9hZGRfbXJ1X2RhdGEgLSBoZWxwZXIgZnVuY3Rpb24gZm9yIFNIQWRkVG9SZWNlbnREb2NzCiAqCiAqIFBBUkFNRVRFUlMKICogICBtcnVoYW5kbGUgICAgW0lOXSBoYW5kbGUgZm9yIGNyZWF0ZWQgTVJVIGxpc3QKICogICBkb2NfbmFtZSAgICAgW0lOXSBudWxsIHRlcm1lZCBwdXJlIGRvYyBuYW1lCiAqICAgbmV3X2xua19uYW1lIFtJTl0gbnVsbCB0ZXJtZWQgcGF0aCBhbmQgZmlsZSBuYW1lIGZvciAubG5rIGZpbGUKICogICBidWZmZXIgICAgICAgW0lOL09VVF0gMjA0OCBieXRlIGFyZWEgdG8gY29uc3RydWN0IE1SVSBkYXRhCiAqICAgbGVuICAgICAgICAgIFtPVVRdIHB0ciB0byBpbnQgdG8gcmVjZWl2ZSBzcGFjZSB1c2VkIGluIGJ1ZmZlcgogKgogKiBSRVRVUk5TCiAqICAgcG9zaXRpb24gd2l0aGluIE1SVSBsaXN0IHRoYXQgZGF0YSB3YXMgYWRkZWQuCiAqLwpzdGF0aWMgSU5UIFNIQUREX2NyZWF0ZV9hZGRfbXJ1X2RhdGEoSEFORExFIG1ydWhhbmRsZSwgTFBTVFIgZG9jX25hbWUsIExQU1RSIG5ld19sbmtfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQU1RSIGJ1ZmZlciwgSU5UICpsZW4pCnsKICAgIExQU1RSIHB0cjsKICAgIElOVCB3bGVuOwoKICAgIC8qRklYTUU6IERvY3VtZW50OgogICAgICogIFJlY2VudERvY3MgTVJVIGRhdGEgc3RydWN0dXJlIHNlZW1zIHRvIGJlOgogICAgICogICAgKzBoICAgZG9jdW1lbnQgZmlsZSBuYW1lIHcvIHRlcm1pbmF0aW5nIDBoCiAgICAgKiAgICArbmggICBzaG9ydCBpbnQgdy8gc2l6ZSBvZiByZW1haW5pbmcKICAgICAqICAgICtuKzJoIDAyaCAzMGgsIG9yIDAxaCAzMGgsIG9yIDAwaCAzMGggIC0gIHVua25vd24KICAgICAqICAgICtuKzRoIDEwIGJ5dGVzIHplcm9zICAtICAgdW5rbm93bgogICAgICogICAgK24rZWggc2hvcnRjdXQgZmlsZSBuYW1lIHcvIHRlcm1pbmF0aW5nIDBoCiAgICAgKiAgICArbitlK25oIDMgemVybyBieXRlcyAgLSAgdW5rbm93bgogICAgICovCgogICAgLyogQ3JlYXRlIHRoZSBNUlUgZGF0YSBzdHJ1Y3R1cmUgZm9yICJSZWNlbnREb2NzIgoJICovCiAgICBwdHIgPSBidWZmZXI7CiAgICBsc3RyY3B5QShwdHIsIGRvY19uYW1lKTsKICAgIHB0ciArPSAobHN0cmxlbkEoYnVmZmVyKSArIDEpOwogICAgd2xlbj0gbHN0cmxlbkEobmV3X2xua19uYW1lKSArIDEgKyAxMjsKICAgICooKHNob3J0IGludCopcHRyKSA9IHdsZW47CiAgICBwdHIgKz0gMjsgICAvKiBzdGVwIHBhc3QgdGhlIGxlbmd0aCAqLwogICAgKihwdHIrKykgPSAweDMwOyAgLyogdW5rbm93biByZWFzb24gKi8KICAgICoocHRyKyspID0gMDsgICAgIC8qIHVua25vd24sIGJ1dCBjYW4gYmUgMHgwMCwgMHgwMSwgMHgwMiAqLwogICAgbWVtc2V0KHB0ciwgMCwgMTApOwogICAgcHRyICs9IDEwOwogICAgbHN0cmNweUEocHRyLCBuZXdfbG5rX25hbWUpOwogICAgcHRyICs9IChsc3RybGVuQShuZXdfbG5rX25hbWUpICsgMSk7CiAgICBtZW1zZXQocHRyLCAwLCAzKTsKICAgIHB0ciArPSAzOwogICAgKmxlbiA9IHB0ciAtIGJ1ZmZlcjsKCiAgICAvKiBBZGQgdGhlIG5ldyBlbnRyeSBpbnRvIHRoZSBNUlUgbGlzdAogICAgICovCiAgICByZXR1cm4gQWRkTVJVRGF0YShtcnVoYW5kbGUsIChMUENWT0lEKWJ1ZmZlciwgKmxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQWRkVG9SZWNlbnREb2NzCQkJCVtTSEVMTDMyLkBdCiAqCiAqIE1vZGlmeSAoYWRkL2NsZWFyKSBTaGVsbCdzIGxpc3Qgb2YgcmVjZW50bHkgdXNlZCBkb2N1bWVudHMuCiAqCiAqIFBBUkFNRVRFUlMKICogICB1RmxhZ3MgIFtJTl0gU0hBUkRfUEFUSEEsIFNIQVJEX1BBVEhXIG9yIFNIQVJEX1BJREwKICogICBwdiAgICAgIFtJTl0gc3RyaW5nIG9yIHBpZGwsIE5VTEwgY2xlYXJzIHRoZSBsaXN0CiAqCiAqIE5PVEVTCiAqICAgICBleHBvcnRlZCBieSBuYW1lCiAqCiAqIEZJWE1FCiAqICBjb252ZXJ0IHRvIHVuaWNvZGUKICovCnZvaWQgV0lOQVBJIFNIQWRkVG9SZWNlbnREb2NzIChVSU5UIHVGbGFncyxMUENWT0lEIHB2KQp7Ci8qIElmIGxpc3QgaXMgYSBzdHJpbmcgbGlzdCBscGZuQ29tcGFyZSBoYXMgdGhlIGZvbGxvd2luZyBwcm90b3R5cGUKICogaW50IENBTExCQUNLIE1SVUNvbXBhcmVTdHJpbmcoTFBDU1RSIHMxLCBMUENTVFIgczIpCiAqIGZvciBiaW5hcnkgbGlzdHMgdGhlIHByb3RvdHlwZSBpcwogKiBpbnQgQ0FMTEJBQ0sgTVJVQ29tcGFyZUJpbmFyeShMUENWT0lEIGRhdGExLCBMUENWT0lEIGRhdGEyLCBEV09SRCBjYkRhdGEpCiAqIHdoZXJlIGNiRGF0YSBpcyB0aGUgbm8uIG9mIGJ5dGVzIHRvIGNvbXBhcmUuCiAqIE5lZWQgdG8gY2hlY2sgd2hhdCByZXR1cm4gdmFsdWUgbWVhbnMgaWRlbnRpY2FsIC0gMD8KICovCgoKICAgIFVJTlQgb2xkZXJyb3Jtb2RlOwogICAgSEtFWSBIQ1ViYXNla2V5OwogICAgQ0hBUiBkb2NfbmFtZVtNQVhfUEFUSF07CiAgICBDSEFSIGxpbmtfZGlyW01BWF9QQVRIXTsKICAgIENIQVIgbmV3X2xua19maWxlcGF0aFtNQVhfUEFUSF07CiAgICBDSEFSIG5ld19sbmtfbmFtZVtNQVhfUEFUSF07CiAgICBJTWFsbG9jICpwcE07CiAgICBMUElURU1JRExJU1QgcGlkbDsKICAgIEhXTkQgaHduZCA9IDA7ICAgICAgIC8qIEZJWE1FOiAgZ2V0IHJlYWwgd2luZG93IGhhbmRsZSAqLwogICAgSU5UIHJldDsKICAgIERXT1JEIGRhdGFbNjRdLCBkYXRhbGVuLCB0eXBlOwoKICAgIFRSQUNFKCIlMDR4ICVwXG4iLCB1RmxhZ3MsIHB2KTsKCiAgICAvKkZJWE1FOiBEb2N1bWVudDoKICAgICAqICBSZWNlbnREb2NzIE1SVSBkYXRhIHN0cnVjdHVyZSBzZWVtcyB0byBiZToKICAgICAqICAgICswaCAgIGRvY3VtZW50IGZpbGUgbmFtZSB3LyB0ZXJtaW5hdGluZyAwaAogICAgICogICAgK25oICAgc2hvcnQgaW50IHcvIHNpemUgb2YgcmVtYWluaW5nCiAgICAgKiAgICArbisyaCAwMmggMzBoLCBvciAwMWggMzBoLCBvciAwMGggMzBoICAtICB1bmtub3duCiAgICAgKiAgICArbis0aCAxMCBieXRlcyB6ZXJvcyAgLSAgIHVua25vd24KICAgICAqICAgICtuK2VoIHNob3J0Y3V0IGZpbGUgbmFtZSB3LyB0ZXJtaW5hdGluZyAwaAogICAgICogICAgK24rZStuaCAzIHplcm8gYnl0ZXMgIC0gIHVua25vd24KICAgICAqLwoKICAgIC8qIFNlZSBpZiB3ZSBuZWVkIHRvIGRvIGFueXRoaW5nLgogICAgICovCiAgICBkYXRhbGVuID0gNjQ7CiAgICByZXQ9U0hBRERfZ2V0X3BvbGljeSggIk5vUmVjZW50RG9jc0hpc3RvcnkiLCAmdHlwZSwgJmRhdGEsICZkYXRhbGVuKTsKICAgIGlmICgocmV0ID4gMCkgJiYgKHJldCAhPSBFUlJPUl9GSUxFX05PVF9GT1VORCkpIHsKCUVSUigiRXJyb3IgJWQgZ2V0dGluZyBwb2xpY3kgXCJOb1JlY2VudERvY3NIaXN0b3J5XCJcbiIsIHJldCk7CglyZXR1cm47CiAgICB9CiAgICBpZiAocmV0ID09IEVSUk9SX1NVQ0NFU1MpIHsKCWlmICghKCAodHlwZSA9PSBSRUdfRFdPUkQpIHx8CgkgICAgICAgKCh0eXBlID09IFJFR19CSU5BUlkpICYmIChkYXRhbGVuID09IDQpKSApKSB7CgkgICAgRVJSKCJFcnJvciBwb2xpY3kgZGF0YSBmb3IgXCJOb1JlY2VudERvY3NIaXN0b3J5XCIgbm90IGZvcm1hdHRlZCBjb3JyZWN0bHksIHR5cGU9JWxkLCBsZW49JWxkXG4iLAoJCXR5cGUsIGRhdGFsZW4pOwoJICAgIHJldHVybjsKCX0KCglUUkFDRSgicG9saWN5IHZhbHVlIGZvciBOb1JlY2VudERvY3NIaXN0b3J5ID0gJTA4bHhcbiIsIGRhdGFbMF0pOwoJLyogbm93IHRlc3QgdGhlIGFjdHVhbCBwb2xpY3kgdmFsdWUgKi8KCWlmICggZGF0YVswXSAhPSAwKQoJICAgIHJldHVybjsKICAgIH0KCiAgICAvKiBPcGVuIGtleSB0byB3aGVyZSB0aGUgbmVjZXNzYXJ5IGluZm8gaXMKICAgICAqLwogICAgLyogRklYTUU6IFRoaXMgc2hvdWxkIGJlIGRvbmUgZHVyaW5nIERMTCBQUk9DRVNTX0FUVEFDSCAob3IgVEhSRUFEX0FUVEFDSCkKICAgICAqICAgICAgICBhbmQgdGhlIGNsb3NlIHNob3VsZCBiZSBkb25lIGR1cmluZyB0aGUgX0RFVEFDSC4gVGhlIHJlc3VsdGluZwogICAgICogICAgICAgIGtleSBpcyBzdG9yZWQgaW4gdGhlIERMTCBnbG9iYWwgZGF0YS4KICAgICAqLwogICAgaWYgKFJlZ0NyZWF0ZUtleUV4QShIS0VZX0NVUlJFTlRfVVNFUiwKCQkJIlNvZnR3YXJlXFxNaWNyb3NvZnRcXFdpbmRvd3NcXEN1cnJlbnRWZXJzaW9uXFxFeHBsb3JlciIsCgkJCTAsIDAsIDAsIEtFWV9SRUFELCAwLCAmSENVYmFzZWtleSwgMCkpIHsKCUVSUigiRmFpbGVkIHRvIGNyZWF0ZSAnU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudFZlcnNpb25cXEV4cGxvcmVyJ1xuIik7CglyZXR1cm47CiAgICB9CgogICAgLyogR2V0IHBhdGggdG8gdXNlcidzICJSZWNlbnQiIGRpcmVjdG9yeQogICAgICovCiAgICBpZihTVUNDRUVERUQoU0hHZXRNYWxsb2MoJnBwTSkpKSB7CglpZiAoU1VDQ0VFREVEKFNIR2V0U3BlY2lhbEZvbGRlckxvY2F0aW9uKGh3bmQsIENTSURMX1JFQ0VOVCwKCQkJCQkJICZwaWRsKSkpIHsKCSAgICBTSEdldFBhdGhGcm9tSURMaXN0QShwaWRsLCBsaW5rX2Rpcik7CgkgICAgSU1hbGxvY19GcmVlKHBwTSwgcGlkbCk7Cgl9CgllbHNlIHsKCSAgICAvKiBzZXJpb3VzIGlzc3VlcyAqLwoJICAgIGxpbmtfZGlyWzBdID0gMDsKCSAgICBFUlIoInNlcmlvdXMgaXNzdWVzIDFcbiIpOwoJfQoJSU1hbGxvY19SZWxlYXNlKHBwTSk7CiAgICB9CiAgICBlbHNlIHsKCS8qIHNlcmlvdXMgaXNzdWVzICovCglsaW5rX2RpclswXSA9IDA7CglFUlIoInNlcmlvdXMgaXNzdWVzIDJcbiIpOwogICAgfQogICAgVFJBQ0UoIlVzZXJzIFJlY2VudCBkaXIgJXNcbiIsIGxpbmtfZGlyKTsKCiAgICAvKiBJZiBubyBpbnB1dCwgdGhlbiBnbyBjbGVhciB0aGUgbGlzdHMgKi8KICAgIGlmICghcHYpIHsKCS8qIGNsZWFyIHVzZXIncyBSZWNlbnQgZGlyCgkgKi8KCgkvKiBGSVhNRTogZGVsZXRlIGFsbCBmaWxlcyBpbiAibGlua19kaXIiCgkgKgoJICogd2hpbGUoIG1vcmUgZmlsZXMgKSB7CgkgKiAgICBsc3RyY3B5QShvbGRfbG5rX25hbWUsIGxpbmtfZGlyKTsKCSAqICAgIFBhdGhBcHBlbmRBKG9sZF9sbmtfbmFtZSwgZmlsZW5hbSk7CgkgKiAgICBEZWxldGVGaWxlQShvbGRfbG5rX25hbWUpOwoJICogfQoJICovCglGSVhNRSgic2hvdWxkIGRlbGV0ZSBhbGwgZmlsZXMgaW4gJXNcXFxuIiwgbGlua19kaXIpOwoKCS8qIGNsZWFyIE1SVSBsaXN0CgkgKi8KCS8qIE1TIEJ1ZyA/PyB2NC43Mi4zNjEyLjE3MDAgb2Ygc2hlbGwzMiBkb2VzIHRoZSBkZWxldGUgYWdhaW5zdAoJICogIEhLRVlfTE9DQUxfTUFDSElORSB2ZXJzaW9uIG9mIC4uLkN1cnJlbnRWZXJzaW9uXEV4cGxvcmVyCgkgKiAgYW5kIG5hdHVyYWxseSBpdCBmYWlscyB3LyByYz0yLiBJdCBzaG91bGQgZG8gaXQgYWdhaW5zdAoJICogIEhLRVlfQ1VSUkVOVF9VU0VSIHdoaWNoIGlzIHdoZXJlIGl0IGlzIHN0b3JlZCwgYW5kIHdoZXJlCgkgKiAgdGhlIE1SVSByb3V0aW5lcyBleHBlY3QgaXQhISEhCgkgKi8KCVJlZ0RlbGV0ZUtleUEoSENVYmFzZWtleSwgIlJlY2VudERvY3MiKTsKCVJlZ0Nsb3NlS2V5KEhDVWJhc2VrZXkpOwoJcmV0dXJuOwogICAgfQoKICAgIC8qIEhhdmUgZGF0YSB0byBhZGQsIHRoZSBqb2JzIHRvIGJlIGRvbmU6CiAgICAgKiAgIDEuIEFkZCBkb2N1bWVudCB0byBNUlUgbGlzdCBpbiByZWdpc3RyeSAiSEtDVVxTb2Z0d2FyZVwKICAgICAqICAgICAgTWljcm9zb2Z0XFdpbmRvd3NcQ3VycmVudFZlcnNpb25cRXhwbG9yZXJcUmVjZW50RG9jcyIuCiAgICAgKiAgIDIuIEFkZCBzaG9ydGN1dCB0byBkb2N1bWVudCBpbiB0aGUgdXNlcidzIFJlY2VudCBkaXJlY3RvcnkKICAgICAqICAgICAgKENTSURMX1JFQ0VOVCkuCiAgICAgKiAgIDMuIEFkZCBzaG9ydGN1dCB0byBTdGFydCBtZW51J3MgRG9jdW1lbnRzIHN1Ym1lbnUuCiAgICAgKi8KCiAgICAvKiBHZXQgdGhlIHB1cmUgZG9jdW1lbnQgbmFtZSBmcm9tIHRoZSBpbnB1dAogICAgICovCiAgICBzd2l0Y2ggKHVGbGFncykKICAgIHsKICAgIGNhc2UgU0hBUkRfUElETDoKCVNIR2V0UGF0aEZyb21JRExpc3RBKChMUENJVEVNSURMSVNUKSBwdiwgZG9jX25hbWUpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgU0hBUkRfUEFUSEE6CiAgICAgICAgbHN0cmNweW5BKGRvY19uYW1lLCAoTFBDU1RSKXB2LCBNQVhfUEFUSCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTSEFSRF9QQVRIVzoKICAgICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgKExQQ1dTVFIpcHYsIC0xLCBkb2NfbmFtZSwgTUFYX1BBVEgsIE5VTEwsIE5VTEwpOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGZsYWdzOiAldVxuIiwgdUZsYWdzKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgVFJBQ0UoImZ1bGwgZG9jdW1lbnQgbmFtZSAlc1xuIiwgZGVidWdzdHJfYShkb2NfbmFtZSkpOwogICAgUGF0aFN0cmlwUGF0aEEoZG9jX25hbWUpOwogICAgVFJBQ0UoInN0cmlwcGVkIGRvY3VtZW50IG5hbWUgJXNcbiIsIGRlYnVnc3RyX2EoZG9jX25hbWUpKTsKCgogICAgLyogKioqICBKT0IgMTogVXBkYXRlIHJlZ2lzdHJ5IGZvciAuLi5cRXhwbG9yZXJcUmVjZW50RG9jcyBsaXN0ICAqKiogKi8KCiAgICB7ICAvKiBvbiBpbnB1dCBuZWVkczoKCSogICAgICBkb2NfbmFtZSAgICAtICBwdXJlIGZpbGUtc3BlYywgbm8gcGF0aAoJKiAgICAgIGxpbmtfZGlyICAgIC0gIHBhdGggdG8gdGhlIHVzZXIncyBSZWNlbnQgZGlyZWN0b3J5CgkqICAgICAgSENVYmFzZWtleSAgLSAga2V5IG9mIC4uLldpbmRvd3NcQ3VycmVudFZlcnNpb25cRXhwbG9yZXIiIG5vZGUKCSogY3JlYXRlczoKCSogICAgICBuZXdfbG5rX25hbWUtICBwdXJlIGZpbGUtc3BlYywgbm8gcGF0aCBmb3IgbmV3IC5sbmsgZmlsZQoJKiAgICAgIG5ld19sbmtfZmlsZXBhdGgKCSogICAgICAgICAgICAgICAgICAtICBwYXRoIGFuZCBmaWxlIG5hbWUgb2YgbmV3IC5sbmsgZmlsZQoJKi8KCUNSRUFURU1SVUxJU1RBIG15bXJ1OwoJSEFORExFIG1ydWhhbmRsZTsKCUlOVCBsZW4sIHBvcywgYnVmdXNlZCwgZXJyOwoJSU5UIGk7CglEV09SRCBhdHRyOwoJQ0hBUiBidWZmZXJbMjA0OF07CglDSEFSICpwdHI7CglDSEFSIG9sZF9sbmtfbmFtZVtNQVhfUEFUSF07CglzaG9ydCBpbnQgc2xlbjsKCglteW1ydS5jYlNpemUgPSBzaXplb2YoQ1JFQVRFTVJVTElTVEEpOwoJbXltcnUubk1heEl0ZW1zID0gMTU7CglteW1ydS5kd0ZsYWdzID0gTVJVRl9CSU5BUllfTElTVCB8IE1SVUZfREVMQVlFRF9TQVZFOwoJbXltcnUuaEtleSA9IEhDVWJhc2VrZXk7CglteW1ydS5scHN6U3ViS2V5ID0gIlJlY2VudERvY3MiOwoJbXltcnUubHBmbkNvbXBhcmUgPSAmU0hBRERfY29tcGFyZV9tcnU7CgltcnVoYW5kbGUgPSBDcmVhdGVNUlVMaXN0QSgmbXltcnUpOwoJaWYgKCFtcnVoYW5kbGUpIHsKCSAgICAvKiBNUlUgZmFpbGVkICovCgkgICAgRVJSKCJNUlUgcHJvY2Vzc2luZyBmYWlsZWQsIGhhbmRsZSB6ZXJvXG4iKTsKCSAgICBSZWdDbG9zZUtleShIQ1ViYXNla2V5KTsKCSAgICByZXR1cm47Cgl9CglsZW4gPSBsc3RybGVuQShkb2NfbmFtZSk7Cglwb3MgPSBGaW5kTVJVRGF0YShtcnVoYW5kbGUsIGRvY19uYW1lLCBsZW4sIDApOwoKCS8qIE5vdyBnZXQgdGhlIE1SVSBlbnRyeSB0aGF0IHdpbGwgYmUgcmVwbGFjZWQKCSAqIGFuZCBkZWxldGUgdGhlIC5sbmsgZmlsZSBmb3IgaXQKCSAqLwoJaWYgKChidWZ1c2VkID0gRW51bU1SVUxpc3RBKG1ydWhhbmRsZSwgKHBvcyA9PSAtMSkgPyAxNCA6IHBvcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmZmVyLCAyMDQ4KSkgIT0gLTEpIHsKCSAgICBwdHIgPSBidWZmZXI7CgkgICAgcHRyICs9IChsc3RybGVuQShidWZmZXIpICsgMSk7CgkgICAgc2xlbiA9ICooKHNob3J0IGludCopcHRyKTsKCSAgICBwdHIgKz0gMjsgIC8qIHNraXAgdGhlIGxlbmd0aCBhcmVhICovCgkgICAgaWYgKGJ1ZnVzZWQgPj0gc2xlbiArIChwdHItYnVmZmVyKSkgewoJCS8qIGJ1ZmZlciBzaXplIGxvb2tzIGdvb2QgKi8KCQlwdHIgKz0gMTI7IC8qIGdldCB0byBzdHJpbmcgKi8KCQlsZW4gPSBidWZ1c2VkIC0gKHB0ci1idWZmZXIpOyAgLyogZ2V0IGxlbmd0aCBvZiBidWYgcmVtYWluaW5nICovCgkJaWYgKChsc3RybGVuQShwdHIpID4gMCkgJiYgKGxzdHJsZW5BKHB0cikgPD0gbGVuLTEpKSB7CgkJICAgIC8qIGFwcGVhcnMgdG8gYmUgZ29vZCBzdHJpbmcgKi8KCQkgICAgbHN0cmNweUEob2xkX2xua19uYW1lLCBsaW5rX2Rpcik7CgkJICAgIFBhdGhBcHBlbmRBKG9sZF9sbmtfbmFtZSwgcHRyKTsKCQkgICAgaWYgKCFEZWxldGVGaWxlQShvbGRfbG5rX25hbWUpKSB7CgkJCWlmICgoYXR0ciA9IEdldEZpbGVBdHRyaWJ1dGVzQShvbGRfbG5rX25hbWUpKSA9PSBJTlZBTElEX0ZJTEVfQVRUUklCVVRFUykgewoJCQkgICAgaWYgKChlcnIgPSBHZXRMYXN0RXJyb3IoKSkgIT0gRVJST1JfRklMRV9OT1RfRk9VTkQpIHsKCQkJCUVSUigiRGVsZXRlIGZvciAlcyBmYWlsZWQsIGVycj0lZCwgYXR0cj0lMDhseFxuIiwKCQkJCSAgICBvbGRfbG5rX25hbWUsIGVyciwgYXR0cik7CgkJCSAgICB9CgkJCSAgICBlbHNlIHsKCQkJCVRSQUNFKCJvbGQgLmxuayBmaWxlICVzIGRpZCBub3QgZXhpc3RcbiIsCgkJCQkgICAgICBvbGRfbG5rX25hbWUpOwoJCQkgICAgfQoJCQl9CgkJCWVsc2UgewoJCQkgICAgRVJSKCJEZWxldGUgZm9yICVzIGZhaWxlZCwgYXR0cj0lMDhseFxuIiwKCQkJCW9sZF9sbmtfbmFtZSwgYXR0cik7CgkJCX0KCQkgICAgfQoJCSAgICBlbHNlIHsKCQkJVFJBQ0UoImRlbGV0ZWQgb2xkIC5sbmsgZmlsZSAlc1xuIiwgb2xkX2xua19uYW1lKTsKCQkgICAgfQoJCX0KCSAgICB9Cgl9CgoJLyogQ3JlYXRlIHVzYWJsZSAubG5rIGZpbGUgbmFtZSBmb3IgdGhlICJSZWNlbnQiIGRpcmVjdG9yeQoJICovCgl3c3ByaW50ZkEobmV3X2xua19uYW1lLCAiJXMubG5rIiwgZG9jX25hbWUpOwoJbHN0cmNweUEobmV3X2xua19maWxlcGF0aCwgbGlua19kaXIpOwoJUGF0aEFwcGVuZEEobmV3X2xua19maWxlcGF0aCwgbmV3X2xua19uYW1lKTsKCWkgPSAxOwoJb2xkZXJyb3Jtb2RlID0gU2V0RXJyb3JNb2RlKFNFTV9GQUlMQ1JJVElDQUxFUlJPUlMpOwoJd2hpbGUgKEdldEZpbGVBdHRyaWJ1dGVzQShuZXdfbG5rX2ZpbGVwYXRoKSAhPSBJTlZBTElEX0ZJTEVfQVRUUklCVVRFUykgewoJICAgIGkrKzsKCSAgICB3c3ByaW50ZkEobmV3X2xua19uYW1lLCAiJXMgKCV1KS5sbmsiLCBkb2NfbmFtZSwgaSk7CgkgICAgbHN0cmNweUEobmV3X2xua19maWxlcGF0aCwgbGlua19kaXIpOwoJICAgIFBhdGhBcHBlbmRBKG5ld19sbmtfZmlsZXBhdGgsIG5ld19sbmtfbmFtZSk7Cgl9CglTZXRFcnJvck1vZGUob2xkZXJyb3Jtb2RlKTsKCVRSQUNFKCJuZXcgc2hvcnRjdXQgd2lsbCBiZSAlc1xuIiwgbmV3X2xua19maWxlcGF0aCk7CgoJLyogTm93IGFkZCB0aGUgbmV3IE1SVSBlbnRyeSBhbmQgZGF0YQoJICovCglwb3MgPSBTSEFERF9jcmVhdGVfYWRkX21ydV9kYXRhKG1ydWhhbmRsZSwgZG9jX25hbWUsIG5ld19sbmtfbmFtZSwKCQkJCQlidWZmZXIsICZsZW4pOwoJRnJlZU1SVUxpc3QobXJ1aGFuZGxlKTsKCVRSQUNFKCJVcGRhdGVkIE1SVSBsaXN0LCBuZXcgZG9jIGlzIHBvc2l0aW9uICVkXG4iLCBwb3MpOwogICAgfQoKICAgIC8qICoqKiAgSk9CIDI6IENyZWF0ZSBzaG9ydGN1dCBpbiB1c2VyJ3MgIlJlY2VudCIgZGlyZWN0b3J5ICAqKiogKi8KCiAgICB7ICAvKiBvbiBpbnB1dCBuZWVkczoKCSogICAgICBkb2NfbmFtZSAgICAtICBwdXJlIGZpbGUtc3BlYywgbm8gcGF0aAoJKiAgICAgIG5ld19sbmtfZmlsZXBhdGgKCSogICAgICAgICAgICAgICAgICAtICBwYXRoIGFuZCBmaWxlIG5hbWUgb2YgbmV3IC5sbmsgZmlsZQogCSogICAgICB1RmxhZ3NbaW5dICAtICBmbGFncyBvbiBjYWxsIHRvIFNIQWRkVG9SZWNlbnREb2NzCgkqICAgICAgcHZbaW5dICAgICAgLSAgZG9jdW1lbnQgcGF0aC9waWRsIG9uIGNhbGwgdG8gU0hBZGRUb1JlY2VudERvY3MKCSovCglJU2hlbGxMaW5rQSAqcHNsID0gTlVMTDsKCUlQZXJzaXN0RmlsZSAqcFBmID0gTlVMTDsKCUhSRVNVTFQgaHJlczsKCUNIQVIgZGVzY1tNQVhfUEFUSF07CglXQ0hBUiB3aWRlbGlua1tNQVhfUEFUSF07CgoJQ29Jbml0aWFsaXplKDApOwoKCWhyZXMgPSBDb0NyZWF0ZUluc3RhbmNlKCAmQ0xTSURfU2hlbGxMaW5rLAoJCQkJIE5VTEwsCgkJCQkgQ0xTQ1RYX0lOUFJPQ19TRVJWRVIsCgkJCQkgJklJRF9JU2hlbGxMaW5rQSwKCQkJCSAoTFBWT0lEICkmcHNsKTsKCWlmKFNVQ0NFRURFRChocmVzKSkgewoKCSAgICBocmVzID0gSVNoZWxsTGlua0FfUXVlcnlJbnRlcmZhY2UocHNsLCAmSUlEX0lQZXJzaXN0RmlsZSwKCQkJCQkgICAgIChMUFZPSUQgKikmcFBmKTsKCSAgICBpZihGQUlMRUQoaHJlcykpIHsKCQkvKiBib21iZWQgKi8KCQlFUlIoImZhaWxlZCBRdWVyeUludGVyZmFjZSBmb3IgSVBlcnNpc3RGaWxlICUwOGx4XG4iLCBocmVzKTsKCQlnb3RvIGZhaWw7CgkgICAgfQoKCSAgICAvKiBTZXQgdGhlIGRvY3VtZW50IHBhdGggb3IgcGlkbCAqLwoJICAgIGlmICh1RmxhZ3MgPT0gU0hBUkRfUElETCkgewoJCWhyZXMgPSBJU2hlbGxMaW5rQV9TZXRJRExpc3QocHNsLCAoTFBDSVRFTUlETElTVCkgcHYpOwoJICAgIH0gZWxzZSB7CgkJaHJlcyA9IElTaGVsbExpbmtBX1NldFBhdGgocHNsLCAoTFBDU1RSKSBwdik7CgkgICAgfQoJICAgIGlmKEZBSUxFRChocmVzKSkgewoJCS8qIGJvbWJlZCAqLwoJCUVSUigiZmFpbGVkIFNldHtJRExpc3R8UGF0aH0gJTA4bHhcbiIsIGhyZXMpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgoJICAgIGxzdHJjcHlBKGRlc2MsICJTaG9ydGN1dCB0byAiKTsKCSAgICBsc3RyY2F0QShkZXNjLCBkb2NfbmFtZSk7CgkgICAgaHJlcyA9IElTaGVsbExpbmtBX1NldERlc2NyaXB0aW9uKHBzbCwgZGVzYyk7CgkgICAgaWYoRkFJTEVEKGhyZXMpKSB7CgkJLyogYm9tYmVkICovCgkJRVJSKCJmYWlsZWQgU2V0RGVzY3JpcHRpb24gJTA4bHhcbiIsIGhyZXMpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgoJICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBuZXdfbG5rX2ZpbGVwYXRoLCAtMSwKCQkJCXdpZGVsaW5rLCBNQVhfUEFUSCk7CgkgICAgLyogY3JlYXRlIHRoZSBzaG9ydCBjdXQgKi8KCSAgICBocmVzID0gSVBlcnNpc3RGaWxlX1NhdmUocFBmLCB3aWRlbGluaywgVFJVRSk7CgkgICAgaWYoRkFJTEVEKGhyZXMpKSB7CgkJLyogYm9tYmVkICovCgkJRVJSKCJmYWlsZWQgSVBlcnNpc3RGaWxlOjpTYXZlICUwOGx4XG4iLCBocmVzKTsKCQlJUGVyc2lzdEZpbGVfUmVsZWFzZShwUGYpOwoJCUlTaGVsbExpbmtBX1JlbGVhc2UocHNsKTsKCQlnb3RvIGZhaWw7CgkgICAgfQoJICAgIGhyZXMgPSBJUGVyc2lzdEZpbGVfU2F2ZUNvbXBsZXRlZChwUGYsIHdpZGVsaW5rKTsKCSAgICBJUGVyc2lzdEZpbGVfUmVsZWFzZShwUGYpOwoJICAgIElTaGVsbExpbmtBX1JlbGVhc2UocHNsKTsKCSAgICBUUkFDRSgic2hvcnRjdXQgJXMgaGFzIGJlZW4gY3JlYXRlZCwgcmVzdWx0PSUwOGx4XG4iLAoJCSAgbmV3X2xua19maWxlcGF0aCwgaHJlcyk7Cgl9CgllbHNlIHsKCSAgICBFUlIoIkNvQ3JlYXRlSW5zdGFuY2UgZmFpbGVkLCBocmVzPSUwOGx4XG4iLCBocmVzKTsKCX0KICAgIH0KCiBmYWlsOgogICAgQ29VbmluaXRpYWxpemUoKTsKCiAgICAvKiBhbGwgZG9uZSAqLwogICAgUmVnQ2xvc2VLZXkoSENVYmFzZWtleSk7CiAgICByZXR1cm47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIQ3JlYXRlU2hlbGxGb2xkZXJWaWV3RXgJCQlbU0hFTEwzMi4xNzRdCiAqCiAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgZGVmYXVsdCBTaGVsbCBmb2xkZXIgdmlldyBvYmplY3QuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0sKICogIEZhaWx1cmU6IGVycm9yIHZhbHVlCiAqCiAqIE5PVEVTCiAqICBzZWUgSVNoZWxsRm9sZGVyOjpDcmVhdGVWaWV3T2JqZWN0CiAqLwpIUkVTVUxUIFdJTkFQSSBTSENyZWF0ZVNoZWxsRm9sZGVyVmlld0V4KAoJTFBDU0ZWIHBzdmNiaSwgICAgLyogW2luXSBzaGVsbHRlbXBsYXRlIHN0cnVjdCAqLwoJSVNoZWxsVmlldyAqKnBwdikgLyogW291dF0gSVNoZWxsVmlldyBwb2ludGVyICovCnsKCUlTaGVsbFZpZXcgKiBwc2Y7CglIUkVTVUxUIGhSZXM7CgoJVFJBQ0UoInNmPSVwIHBpZGw9JXAgY2I9JXAgbW9kZT0weCUwOHggcGFybT0lcFxuIiwKCSAgcHN2Y2JpLT5wc2hmLCBwc3ZjYmktPnBpZGwsIHBzdmNiaS0+cGZuQ2FsbGJhY2ssCgkgIHBzdmNiaS0+ZnZtLCBwc3ZjYmktPnBzdk91dGVyKTsKCglwc2YgPSBJU2hlbGxWaWV3X0NvbnN0cnVjdG9yKHBzdmNiaS0+cHNoZik7CgoJaWYgKCFwc2YpCgkgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKCUlTaGVsbFZpZXdfQWRkUmVmKHBzZik7CgloUmVzID0gSVNoZWxsVmlld19RdWVyeUludGVyZmFjZShwc2YsICZJSURfSVNoZWxsVmlldywgKExQVk9JRCAqKXBwdik7CglJU2hlbGxWaWV3X1JlbGVhc2UocHNmKTsKCglyZXR1cm4gaFJlczsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgU0hXaW5IZWxwCQkJCQlbU0hFTEwzMi4xMjddCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFdpbkhlbHAgKERXT1JEIHYsIERXT1JEIHcsIERXT1JEIHgsIERXT1JEIHopCnsJRklYTUUoIjB4JTA4bHggMHglMDhseCAweCUwOGx4IDB4JTA4bHggc3R1YlxuIix2LHcseCx6KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBTSFJ1bkNvbnRyb2xQYW5lbCBbU0hFTEwzMi4xNjFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFJ1bkNvbnRyb2xQYW5lbCAoRFdPUkQgeCwgRFdPUkQgeikKewlGSVhNRSgiMHglMDhseCAweCUwOGx4IHN0dWJcbiIseCx6KTsKCXJldHVybiAwOwp9CgpzdGF0aWMgTFBVTktOT1dOIFNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlPTA7Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIU2V0SW5zdGFuY2VFeHBsb3JlcgkJCVtTSEVMTDMyLjE3Nl0KICoKICogTk9URVMKICogIFNldHMgdGhlIGludGVyZmFjZQogKi8KVk9JRCBXSU5BUEkgU0hTZXRJbnN0YW5jZUV4cGxvcmVyIChMUFVOS05PV04gbHBVbmtub3duKQp7CVRSQUNFKCIlcFxuIiwgbHBVbmtub3duKTsKCVNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlID0gbHBVbmtub3duOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIR2V0SW5zdGFuY2VFeHBsb3JlcgkJCVtTSEVMTDMyLkBdCiAqCiAqIE5PVEVTCiAqICBnZXRzIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBvZiB0aGUgZXhwbG9yZXIgYW5kIGEgcmVmZXJlbmNlCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEdldEluc3RhbmNlRXhwbG9yZXIgKExQVU5LTk9XTiAqIGxwVW5rbm93bikKewlUUkFDRSgiJXBcbiIsIGxwVW5rbm93bik7CgoJKmxwVW5rbm93biA9IFNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlOwoKCWlmICghU0hFTEwzMl9JRXhwbG9yZXJJbnRlcmZhY2UpCgkgIHJldHVybiBFX0ZBSUw7CgoJSVVua25vd25fQWRkUmVmKFNIRUxMMzJfSUV4cGxvcmVySW50ZXJmYWNlKTsKCXJldHVybiBOT0VSUk9SOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIRnJlZVVudXNlZExpYnJhcmllcwkJCVtTSEVMTDMyLjEyM10KICoKICogTk9URVMKICogIGV4cG9ydGVkIGJ5IG5hbWUKICovCnZvaWQgV0lOQVBJIFNIRnJlZVVudXNlZExpYnJhcmllcyAodm9pZCkKewoJRklYTUUoInN0dWJcbiIpOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9BdXRvU2Nyb2xsCQkJCVtTSEVMTDMyLjEyOV0KICoKICovCkJPT0wgV0lOQVBJIERBRF9BdXRvU2Nyb2xsKEhXTkQgaHduZCwgQVVUT19TQ1JPTExfREFUQSAqc2FtcGxlcywgTFBQT0lOVCBwdCkKewogICAgRklYTUUoImh3bmQgPSAlcCAlcCAlcFxuIixod25kLHNhbXBsZXMscHQpOwogICAgcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX0RyYWdFbnRlcgkJCQlbU0hFTEwzMi4xMzBdCiAqCiAqLwpCT09MIFdJTkFQSSBEQURfRHJhZ0VudGVyKEhXTkQgaHduZCkKewogICAgRklYTUUoImh3bmQgPSAlcFxuIixod25kKTsKICAgIHJldHVybiBGQUxTRTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfRHJhZ0VudGVyRXgJCQkJW1NIRUxMMzIuMTMxXQogKgogKi8KQk9PTCBXSU5BUEkgREFEX0RyYWdFbnRlckV4KEhXTkQgaHduZCwgUE9JTlQgcCkKewogICAgRklYTUUoImh3bmQgPSAlcCAoJWxkLCVsZClcbiIsaHduZCxwLngscC55KTsKICAgIHJldHVybiBGQUxTRTsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEQURfRHJhZ01vdmUJCQkJW1NIRUxMMzIuMTM0XQogKgogKi8KQk9PTCBXSU5BUEkgREFEX0RyYWdNb3ZlKFBPSU5UIHApCnsKICAgIEZJWE1FKCIoJWxkLCVsZClcbiIscC54LHAueSk7CiAgICByZXR1cm4gRkFMU0U7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogREFEX0RyYWdMZWF2ZQkJCQlbU0hFTEwzMi4xMzJdCiAqCiAqLwpCT09MIFdJTkFQSSBEQURfRHJhZ0xlYXZlKFZPSUQpCnsKICAgIEZJWE1FKCJcbiIpOwogICAgcmV0dXJuIEZBTFNFOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9TZXREcmFnSW1hZ2UJCQkJW1NIRUxMMzIuMTM2XQogKgogKiBOT1RFUwogKiAgZXhwb3J0ZWQgYnkgbmFtZQogKi8KQk9PTCBXSU5BUEkgREFEX1NldERyYWdJbWFnZSgKCUhJTUFHRUxJU1QgaGltbFRyYWNrLAoJTFBQT0lOVCBscHB0KQp7CglGSVhNRSgiJXAgJXAgc3R1YlxuIixoaW1sVHJhY2ssIGxwcHQpOwogIHJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERBRF9TaG93RHJhZ0ltYWdlCQkJCVtTSEVMTDMyLjEzN10KICoKICogTk9URVMKICogIGV4cG9ydGVkIGJ5IG5hbWUKICovCkJPT0wgV0lOQVBJIERBRF9TaG93RHJhZ0ltYWdlKEJPT0wgYlNob3cpCnsKCUZJWE1FKCIweCUwOHggc3R1YlxuIixiU2hvdyk7CglyZXR1cm4gMDsKfQoKc3RhdGljIGNvbnN0IFdDSEFSIHN6d0NhYkxvY2F0aW9uW10gPSB7CiAgJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAogICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsCiAgJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCdcXCcsCiAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXFwnLAogICdFJywneCcsJ3AnLCdsJywnbycsJ3InLCdlJywncicsJ1xcJywKICAnQycsJ2EnLCdiJywnaScsJ24nLCdlJywndCcsJ1MnLCd0JywnYScsJ3QnLCdlJywwCn07CgpzdGF0aWMgY29uc3QgV0NIQVIgc3p3U2V0dGluZ3NbXSA9IHsgJ1MnLCdlJywndCcsJ3QnLCdpJywnbicsJ2cnLCdzJywwIH07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBSZWFkQ2FiaW5ldFN0YXRlCQkJCVtTSEVMTDMyLjY1MV0gTlQgNC4wCiAqCiAqLwpCT09MIFdJTkFQSSBSZWFkQ2FiaW5ldFN0YXRlKENBQklORVRTVEFURSAqY3MsIGludCBsZW5ndGgpCnsKCUhLRVkgaGtleSA9IDA7CglEV09SRCB0eXBlLCByOwoKCVRSQUNFKCIlcCAlZFxuIiwgY3MsIGxlbmd0aCk7CgoJaWYoIChjcyA9PSBOVUxMKSB8fCAobGVuZ3RoIDwgKGludClzaXplb2YoKmNzKSkgICkKCQlyZXR1cm4gRkFMU0U7CgoJciA9IFJlZ09wZW5LZXlXKCBIS0VZX0NVUlJFTlRfVVNFUiwgc3p3Q2FiTG9jYXRpb24sICZoa2V5ICk7CglpZiggciA9PSBFUlJPUl9TVUNDRVNTICkKCXsKCQl0eXBlID0gUkVHX0JJTkFSWTsKCQlyID0gUmVnUXVlcnlWYWx1ZUV4VyggaGtleSwgc3p3U2V0dGluZ3MsIAoJCQlOVUxMLCAmdHlwZSwgKExQQllURSljcywgKExQRFdPUkQpJmxlbmd0aCApOwoJCVJlZ0Nsb3NlS2V5KCBoa2V5ICk7CgkJCQoJfQoKCS8qIGlmIHdlIGNhbid0IHJlYWQgZnJvbSB0aGUgcmVnaXN0cnksIGNyZWF0ZSBkZWZhdWx0IHZhbHVlcyAqLwoJaWYgKCAociAhPSBFUlJPUl9TVUNDRVNTKSB8fCAoY3MtPmNMZW5ndGggPCBzaXplb2YoKmNzKSkgfHwKCQkoY3MtPmNMZW5ndGggIT0gbGVuZ3RoKSApCgl7CgkJRVJSKCJJbml0aWFsaXppbmcgc2hlbGwgY2FiaW5ldCBzZXR0aW5nc1xuIik7CgkJbWVtc2V0KGNzLCAwLCBzaXplb2YoKmNzKSk7CgkJY3MtPmNMZW5ndGggICAgICAgICAgPSBzaXplb2YoKmNzKTsKCQljcy0+blZlcnNpb24gICAgICAgICA9IDI7CgkJY3MtPmZGdWxsUGF0aFRpdGxlICAgPSBGQUxTRTsKCQljcy0+ZlNhdmVMb2NhbFZpZXcgICA9IFRSVUU7CgkJY3MtPmZOb3RTaGVsbCAgICAgICAgPSBGQUxTRTsKCQljcy0+ZlNpbXBsZURlZmF1bHQgICA9IFRSVUU7CgkJY3MtPmZEb250U2hvd0Rlc2NCYXIgPSBGQUxTRTsKCQljcy0+Zk5ld1dpbmRvd01vZGUgICA9IEZBTFNFOwoJCWNzLT5mU2hvd0NvbXBDb2xvciAgID0gRkFMU0U7CgkJY3MtPmZEb250UHJldHR5TmFtZXMgPSBGQUxTRTsKCQljcy0+ZkFkbWluc0NyZWF0ZUNvbW1vbkdyb3VwcyA9IFRSVUU7CgkJY3MtPmZNZW51RW51bUZpbHRlciAgPSA5NjsKCX0KCQoJcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFdyaXRlQ2FiaW5ldFN0YXRlCQkJCVtTSEVMTDMyLjY1Ml0gTlQgNC4wCiAqCiAqLwpCT09MIFdJTkFQSSBXcml0ZUNhYmluZXRTdGF0ZShDQUJJTkVUU1RBVEUgKmNzKQp7CglEV09SRCByOwoJSEtFWSBoa2V5ID0gMDsKCglUUkFDRSgiJXBcbiIsY3MpOwoKCWlmKCBjcyA9PSBOVUxMICkKCQlyZXR1cm4gRkFMU0U7CgoJciA9IFJlZ0NyZWF0ZUtleUV4VyggSEtFWV9DVVJSRU5UX1VTRVIsIHN6d0NhYkxvY2F0aW9uLCAwLAoJCSBOVUxMLCAwLCBLRVlfQUxMX0FDQ0VTUywgTlVMTCwgJmhrZXksIE5VTEwpOwoJaWYoIHIgPT0gRVJST1JfU1VDQ0VTUyApCgl7CgkJciA9IFJlZ1NldFZhbHVlRXhXKCBoa2V5LCBzendTZXR0aW5ncywgMCwgCgkJCVJFR19CSU5BUlksIChMUEJZVEUpIGNzLCBjcy0+Y0xlbmd0aCk7CgoJCVJlZ0Nsb3NlS2V5KCBoa2V5ICk7Cgl9CgoJcmV0dXJuIChyPT1FUlJPUl9TVUNDRVNTKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRmlsZUljb25Jbml0IAkJCQlbU0hFTEwzMi42NjBdCiAqCiAqLwpCT09MIFdJTkFQSSBGaWxlSWNvbkluaXQoQk9PTCBiRnVsbEluaXQpCnsJRklYTUUoIiglcylcbiIsIGJGdWxsSW5pdCA/ICJ0cnVlIiA6ICJmYWxzZSIpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSXNVc2VyQWRtaW4JCQkJCVtTSEVMTDMyLjY4MF0gTlQgNC4wCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBJc1VzZXJBZG1pbih2b2lkKQp7CUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFsbG9jU2hhcmVkCQkJCVtTSEVMTDMyLjUyMF0KICoKICogU2VlIHNobHdhcGkuU0hBbGxvY1NoYXJlZAogKi8KSEFORExFIFdJTkFQSSBTSEFsbG9jU2hhcmVkKExQVk9JRCBscHZEYXRhLCBEV09SRCBkd1NpemUsIERXT1JEIGR3UHJvY0lkKQp7CiAgICBHRVRfRlVOQyhwU0hBbGxvY1NoYXJlZCwgc2hsd2FwaSwgKGNoYXIqKTcsIE5VTEwpOwogICAgcmV0dXJuIHBTSEFsbG9jU2hhcmVkKGxwdkRhdGEsIGR3U2l6ZSwgZHdQcm9jSWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSExvY2tTaGFyZWQJCQkJCVtTSEVMTDMyLjUyMV0KICoKICogU2VlIHNobHdhcGkuU0hMb2NrU2hhcmVkCiAqLwpMUFZPSUQgV0lOQVBJIFNITG9ja1NoYXJlZChIQU5ETEUgaFNoYXJlZCwgRFdPUkQgZHdQcm9jSWQpCnsKICAgIEdFVF9GVU5DKHBTSExvY2tTaGFyZWQsIHNobHdhcGksIChjaGFyKik4LCBOVUxMKTsKICAgIHJldHVybiBwU0hMb2NrU2hhcmVkKGhTaGFyZWQsIGR3UHJvY0lkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hVbmxvY2tTaGFyZWQJCQkJW1NIRUxMMzIuNTIyXQogKgogKiBTZWUgc2hsd2FwaS5TSFVubG9ja1NoYXJlZAogKi8KQk9PTCBXSU5BUEkgU0hVbmxvY2tTaGFyZWQoTFBWT0lEIGxwVmlldykKewogICAgR0VUX0ZVTkMocFNIVW5sb2NrU2hhcmVkLCBzaGx3YXBpLCAoY2hhciopOSwgRkFMU0UpOwogICAgcmV0dXJuIHBTSFVubG9ja1NoYXJlZChscFZpZXcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEZyZWVTaGFyZWQJCQkJCVtTSEVMTDMyLjUyM10KICoKICogU2VlIHNobHdhcGkuU0hGcmVlU2hhcmVkCiAqLwpCT09MIFdJTkFQSSBTSEZyZWVTaGFyZWQoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3UHJvY0lkKQp7CiAgICBHRVRfRlVOQyhwU0hGcmVlU2hhcmVkLCBzaGx3YXBpLCAoY2hhciopMTAsIEZBTFNFKTsKICAgIHJldHVybiBwU0hGcmVlU2hhcmVkKGhTaGFyZWQsIGR3UHJvY0lkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2V0QXBwU3RhcnRpbmdDdXJzb3IJCQkJW1NIRUxMMzIuOTldCiAqLwpIUkVTVUxUIFdJTkFQSSBTZXRBcHBTdGFydGluZ0N1cnNvcihIV05EIHUsIERXT1JEIHYpCnsJRklYTUUoImh3bmQ9JXAgMHglMDRseCBzdHViXG4iLHUsdiApOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hMb2FkT0xFCQkJCQlbU0hFTEwzMi4xNTFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExvYWRPTEUoTFBBUkFNIGxQYXJhbSkKewlGSVhNRSgiMHglMDRseCBzdHViXG4iLGxQYXJhbSk7CglyZXR1cm4gU19PSzsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEcml2ZVR5cGUJCQkJCVtTSEVMTDMyLjY0XQogKgogKi8KSFJFU1VMVCBXSU5BUEkgRHJpdmVUeXBlKERXT1JEIHUpCnsJRklYTUUoIjB4JTA0bHggc3R1YlxuIix1KTsKCXJldHVybiAwOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEludmFsaWRhdGVEcml2ZVR5cGUJCQlbU0hFTEwzMi42NV0KICoKICovCmludCBXSU5BUEkgSW52YWxpZGF0ZURyaXZlVHlwZShpbnQgdSkKewlGSVhNRSgiMHglMDh4IHN0dWJcbiIsdSk7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSEFib3J0SW52b2tlQ29tbWFuZAkJCQlbU0hFTEwzMi4xOThdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEFib3J0SW52b2tlQ29tbWFuZCh2b2lkKQp7CUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiAxOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIT3V0T2ZNZW1vcnlNZXNzYWdlQm94CQkJW1NIRUxMMzIuMTI2XQogKgogKi8KaW50IFdJTkFQSSBTSE91dE9mTWVtb3J5TWVzc2FnZUJveCgKCUhXTkQgaHduZE93bmVyLAoJTFBDU1RSIGxwQ2FwdGlvbiwKCVVJTlQgdVR5cGUpCnsKCUZJWE1FKCIlcCAlcyAweCUwOHggc3R1YlxuIixod25kT3duZXIsIGxwQ2FwdGlvbiwgdVR5cGUpOwoJcmV0dXJuIDA7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hGbHVzaENsaXBib2FyZAkJCQlbU0hFTEwzMi4xMjFdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEZsdXNoQ2xpcGJvYXJkKHZvaWQpCnsJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIDE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNIV2FpdEZvckZpbGVUb09wZW4JCQkJW1NIRUxMMzIuOTddCiAqCiAqLwpCT09MIFdJTkFQSSBTSFdhaXRGb3JGaWxlVG9PcGVuKAoJTFBDSVRFTUlETElTVCBwaWRsLAoJRFdPUkQgZHdGbGFncywKCURXT1JEIGR3VGltZW91dCkKewoJRklYTUUoIiVwIDB4JTA4bHggMHglMDhseCBzdHViXG4iLCBwaWRsLCBkd0ZsYWdzLCBkd1RpbWVvdXQpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJQAkJCQlbU0hFTEwzMi42NTRdCiAqCiAqIE5PVEVTCiAqICBmaXJzdCBwYXJhbWV0ZXIgc2VlbXMgdG8gYmUgYSBwb2ludGVyIChzYW1lIGFzIHBhc3NlZCB0byBXcml0ZUNhYmluZXRTdGF0ZSkKICogIHNlY29uZCBvbmUgY291bGQgYmUgYSBzaXplICgweDBjKS4gVGhlIHNpemUgaXMgdGhlIHNhbWUgYXMgdGhlIHN0cnVjdHVyZSBzYXZlZCB0bwogKiAgSENVXFNvZnR3YXJlXE1pY3Jvc29mdFxXaW5kb3dzXEN1cnJlbnRWZXJzaW9uXEV4cGxvcmVyXENhYmluZXRTdGF0ZQogKiAgSSdtIChqcykgZ3Vlc3Npbmc6IHRoaXMgb25lIGlzIGp1c3QgUmVhZENhYmluZXRTdGF0ZSA7LSkKICovCkhSRVNVTFQgV0lOQVBJIHNoZWxsMzJfNjU0IChDQUJJTkVUU1RBVEUgKmNzLCBpbnQgbGVuZ3RoKQp7CglUUkFDRSgiJXAgJWRcbiIsY3MsbGVuZ3RoKTsKCXJldHVybiBSZWFkQ2FiaW5ldFN0YXRlKGNzLGxlbmd0aCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUkxCdWlsZExpc3RPZlBhdGhzCQkJW1NIRUxMMzIuMTQ2XQogKgogKiBOT1RFUwogKiAgIGJ1aWxkcyBhIERQQQogKi8KRFdPUkQgV0lOQVBJIFJMQnVpbGRMaXN0T2ZQYXRocyAodm9pZCkKewlGSVhNRSgic3R1YlxuIik7CglyZXR1cm4gMDsKfQovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCVNIVmFsaWRhdGVVTkMJCQkJW1NIRUxMMzIuMTczXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgU0hWYWxpZGF0ZVVOQyAoRFdPUkQgeCwgRFdPUkQgeSwgRFdPUkQgeikKewoJRklYTUUoIjB4JTA4bHggMHglMDhseCAweCUwOGx4IHN0dWJcbiIseCx5LHopOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJRG9FbnZpcm9ubWVudFN1YnN0QQkJCVtTSEVMTDMyLkBdCiAqCiAqIFJlcGxhY2UgJUtFWVdPUkQlIGluIHRoZSBzdHIgd2l0aCB0aGUgdmFsdWUgb2YgdmFyaWFibGUgS0VZV09SRAogKiBmcm9tIGVudmlyb25tZW50LiBJZiBpdCBpcyBub3QgZm91bmQgdGhlICVLRVlXT1JEJSBpcyBsZWZ0CiAqIGludGFjdC4gSWYgdGhlIGJ1ZmZlciBpcyB0b28gc21hbGwsIHN0ciBpcyBub3QgbW9kaWZpZWQuCiAqCiAqIFBBUkFNUwogKiAgcHN6U3RyaW5nICBbSV0gJ1wwJyB0ZXJtaW5hdGVkIHN0cmluZyB3aXRoICVrZXl3b3JkJS4KICogICAgICAgICAgICAgW09dICdcMCcgdGVybWluYXRlZCBzdHJpbmcgd2l0aCAla2V5d29yZCUgc3Vic3RpdHV0ZWQuCiAqICBjY2hTdHJpbmcgIFtJXSBzaXplIG9mIHN0ci4KICoKICogUkVUVVJOUwogKiAgICAgY2NoU3RyaW5nIGxlbmd0aCBpbiB0aGUgSElXT1JEOwogKiAgICAgVFJVRSBpbiBMT1dPUkQgaWYgc3Vic3Qgd2FzIHN1Y2Nlc3NmdWwgYW5kIEZBTFNFIGluIG90aGVyIGNhc2UKICovCkRXT1JEIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RBKExQU1RSIHBzelN0cmluZywgVUlOVCBjY2hTdHJpbmcpCnsKICAgIExQU1RSIGRzdDsKICAgIEJPT0wgcmVzID0gRkFMU0U7CiAgICBGSVhNRSgiKCVzLCAlZCkgc3R1YlxuIiwgZGVidWdzdHJfYShwc3pTdHJpbmcpLCBjY2hTdHJpbmcpOwogICAgaWYgKHBzelN0cmluZyA9PSBOVUxMKSAvKiBSZWFsbHkgcmV0dXJuIDA/ICovCiAgICAgICAgcmV0dXJuIDA7CiAgICBpZiAoKGRzdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjY2hTdHJpbmcgKiBzaXplb2YoQ0hBUikpKSkKICAgIHsKICAgICAgICBEV09SRCBudW0gPSBFeHBhbmRFbnZpcm9ubWVudFN0cmluZ3NBKHBzelN0cmluZywgZHN0LCBjY2hTdHJpbmcpOwogICAgICAgIGlmIChudW0gJiYgbnVtIDwgY2NoU3RyaW5nKSAvKiBkZXN0IGJ1ZmZlciBpcyB0b28gc21hbGwgKi8KICAgICAgICB7CiAgICAgICAgICAgIHJlcyA9IFRSVUU7CiAgICAgICAgICAgIG1lbWNweShwc3pTdHJpbmcsIGRzdCwgbnVtKTsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0KTsKICAgIH0KICAgIHJldHVybiBNQUtFTE9ORyhyZXMsY2NoU3RyaW5nKTsgLyogQWx3YXlzIGNjaFN0cmluZz8gKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglEb0Vudmlyb25tZW50U3Vic3RXCQkJW1NIRUxMMzIuQF0KICoKICogU2VlIERvRW52aXJvbm1lbnRTdWJzdEEuICAKICovCkRXT1JEIFdJTkFQSSBEb0Vudmlyb25tZW50U3Vic3RXKExQV1NUUiBwc3pTdHJpbmcsIFVJTlQgY2NoU3RyaW5nKQp7CglGSVhNRSgiKCVzLCAlZCk6IHN0dWJcbiIsIGRlYnVnc3RyX3cocHN6U3RyaW5nKSwgY2NoU3RyaW5nKTsKCXJldHVybiBNQUtFTE9ORyhGQUxTRSxjY2hTdHJpbmcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCURvRW52aXJvbm1lbnRTdWJzdAkJCVtTSEVMTDMyLjUzXQogKgogKiBTZWUgRG9FbnZpcm9ubWVudFN1YnN0QS4gIAogKi8KRFdPUkQgV0lOQVBJIERvRW52aXJvbm1lbnRTdWJzdEFXKExQVk9JRCB4LCBVSU5UIHkpCnsKICAgIGlmIChTSEVMTF9Pc0lzVW5pY29kZSgpKQogICAgICAgIHJldHVybiBEb0Vudmlyb25tZW50U3Vic3RXKHgsIHkpOwogICAgcmV0dXJuIERvRW52aXJvbm1lbnRTdWJzdEEoeCwgeSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1NIRUxMMzIuMjQzXQogKgogKiBXaW45OCsgYnktb3JkaW5hbCByb3V0aW5lLiAgSW4gV2luOTggdGhpcyByb3V0aW5lIHJldHVybnMgemVybyBhbmQKICogZG9lcyBub3RoaW5nIGVsc2UuICBQb3NzaWJseSB0aGlzIGRvZXMgc29tZXRoaW5nIGluIE5UIG9yIFNIRUxMMzIgNS4wPwogKgogKi8KCkJPT0wgV0lOQVBJIHNoZWxsMzJfMjQzKERXT1JEIGEsIERXT1JEIGIpCnsKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hFTEwzMi43MTRdCiAqLwpEV09SRCBXSU5BUEkgU0hFTEwzMl83MTQoTFBWT0lEIHgpCnsKIAlGSVhNRSgiKCVzKXN0dWJcbiIsIGRlYnVnc3RyX3coeCkpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hBZGRGcm9tUHJvcFNoZWV0RXh0QXJyYXkJW1NIRUxMMzIuMTY3XQogKi8KRFdPUkQgV0lOQVBJIFNIQWRkRnJvbVByb3BTaGVldEV4dEFycmF5KERXT1JEIGEsIERXT1JEIGIsIERXT1JEIGMpCnsKIAlGSVhNRSgiKCUwOGx4LCUwOGx4LCUwOGx4KXN0dWJcbiIsIGEsIGIsIGMpOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgU0hDcmVhdGVQcm9wU2hlZXRFeHRBcnJheQlbU0hFTEwzMi4xNjhdCiAqLwpEV09SRCBXSU5BUEkgU0hDcmVhdGVQcm9wU2hlZXRFeHRBcnJheShEV09SRCBhLCBMUENTVFIgYiwgRFdPUkQgYykKewogCUZJWE1FKCIoJTA4bHgsJXMsJTA4bHgpc3R1YlxuIiwgYSwgZGVidWdzdHJfYShiKSwgYyk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSFJlcGxhY2VGcm9tUHJvcFNoZWV0RXh0QXJyYXkJW1NIRUxMMzIuMTcwXQogKi8KRFdPUkQgV0lOQVBJIFNIUmVwbGFjZUZyb21Qcm9wU2hlZXRFeHRBcnJheShEV09SRCBhLCBEV09SRCBiLCBEV09SRCBjLCBEV09SRCBkKQp7CiAJRklYTUUoIiglMDhseCwlMDhseCwlMDhseCwlMDhseClzdHViXG4iLCBhLCBiLCBjLCBkKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNIRGVzdHJveVByb3BTaGVldEV4dEFycmF5CVtTSEVMTDMyLjE2OV0KICovCkRXT1JEIFdJTkFQSSBTSERlc3Ryb3lQcm9wU2hlZXRFeHRBcnJheShEV09SRCBhKQp7CiAJRklYTUUoIiglMDhseClzdHViXG4iLCBhKTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIENJRExEYXRhX0NyZWF0ZUZyb21JREFycmF5CVtTSEVMTDMyLjgzXQogKgogKiAgQ3JlYXRlIElEYXRhT2JqZWN0IGZyb20gUElETHM/PwogKi8KSFJFU1VMVCBXSU5BUEkgQ0lETERhdGFfQ3JlYXRlRnJvbUlEQXJyYXkoCglMUENJVEVNSURMSVNUIHBpZGxGb2xkZXIsCglEV09SRCBjcGlkbEZpbGVzLAoJTFBDSVRFTUlETElTVCAqbHBwaWRsRmlsZXMsCglMUERBVEFPQkpFQ1QgKnBwZGF0YU9iamVjdCkKewogICAgVUlOVCBpOwogICAgSFdORCBod25kID0gMDsgICAvKkZJWE1FOiB3aG8gc2hvdWxkIGJlIGh3bmQgb2Ygb3duZXI/IHNldCB0byBkZXNrdG9wICovCgogICAgVFJBQ0UoIiglcCwgJWxkLCAlcCwgJXApXG4iLCBwaWRsRm9sZGVyLCBjcGlkbEZpbGVzLCBscHBpZGxGaWxlcywgcHBkYXRhT2JqZWN0KTsKICAgIGlmIChUUkFDRV9PTihwaWRsKSkKICAgIHsKCXBkdW1wIChwaWRsRm9sZGVyKTsKCWZvciAoaT0wOyBpPGNwaWRsRmlsZXM7IGkrKykgcGR1bXAgKGxwcGlkbEZpbGVzW2ldKTsKICAgIH0KICAgICpwcGRhdGFPYmplY3QgPSBJRGF0YU9iamVjdF9Db25zdHJ1Y3RvciggaHduZCwgcGlkbEZvbGRlciwKCQkJCQkgICAgIGxwcGlkbEZpbGVzLCBjcGlkbEZpbGVzKTsKICAgIGlmICgqcHBkYXRhT2JqZWN0KSByZXR1cm4gU19PSzsKICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTSENyZWF0ZVN0ZEVudW1GbXRFdGMJCQlbU0hFTEwzMi43NF0KICoKICogTk9URVMKICoKICovCkhSRVNVTFQgV0lOQVBJIFNIQ3JlYXRlU3RkRW51bUZtdEV0YygKCURXT1JEIGNGb3JtYXRzLAoJY29uc3QgRk9STUFURVRDICpscEZvcm1hdHMsCglMUEVOVU1GT1JNQVRFVEMgKnBwZW51bUZvcm1hdGV0YykKewoJSUVudW1GT1JNQVRFVEMgKnBlZjsKCUhSRVNVTFQgaFJlczsKCVRSQUNFKCJjZj0lbGQgZmU9JXAgcGVmPSVwXG4iLCBjRm9ybWF0cywgbHBGb3JtYXRzLCBwcGVudW1Gb3JtYXRldGMpOwoKCXBlZiA9IElFbnVtRk9STUFURVRDX0NvbnN0cnVjdG9yKGNGb3JtYXRzLCBscEZvcm1hdHMpOwoJaWYgKCFwZWYpCgkgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKCUlFbnVtRk9STUFURVRDX0FkZFJlZihwZWYpOwoJaFJlcyA9IElFbnVtRk9STUFURVRDX1F1ZXJ5SW50ZXJmYWNlKHBlZiwgJklJRF9JRW51bUZPUk1BVEVUQywgKExQVk9JRCopcHBlbnVtRm9ybWF0ZXRjKTsKCUlFbnVtRk9STUFURVRDX1JlbGVhc2UocGVmKTsKCglyZXR1cm4gaFJlczsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEVMTDMyXzI1NiAoU0hFTEwzMi4yNTYpCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEVMTDMyXzI1NihMUERXT1JEIGxwZHcwLCBMUERXT1JEIGxwZHcxKQp7CiAgICBIUkVTVUxUIHJldCA9IFNfT0s7CgogICAgRklYTUUoInN0dWIgJXAgMHglMDhseCAlcFxuIiwgbHBkdzAsIGxwZHcwID8gKmxwZHcwIDogMCwgbHBkdzEpOwoKICAgIGlmICghbHBkdzAgfHwgKmxwZHcwICE9IDB4MTApCiAgICAgICAgcmV0ID0gRV9JTlZBTElEQVJHOwogICAgZWxzZQogICAgewogICAgICAgIExQVk9JRCBscGRhdGEgPSAwOy8qTG9jYWxBbGxvYyhMTUVNX1pFUk9JTklULCAweDRFNCk7Ki8KCglpZiAoIWxwZGF0YSkKICAgICAgICAgICAgcmV0ID0gRV9PVVRPRk1FTU9SWTsKCWVsc2UKCXsKICAgICAgICAgICAgLyogSW5pdGlhbGl6ZSBhbmQgcmV0dXJuIHVua25vd24gbHBkYXRhIHN0cnVjdHVyZSAqLwoJfQogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEZpbmRGaWxlcyAoU0hFTEwzMi45MCkKICovCkJPT0wgV0lOQVBJIFNIRmluZEZpbGVzKCBMUENJVEVNSURMSVNUIHBpZGxGb2xkZXIsIExQQ0lURU1JRExJU1QgcGlkbFNhdmVGaWxlICkKewogICAgRklYTUUoIiVwICVwXG4iLCBwaWRsRm9sZGVyLCBwaWRsU2F2ZUZpbGUgKTsKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIVXBkYXRlSW1hZ2VXIChTSEVMTDMyLjE5MikKICoKICogTm90aWZpZXMgdGhlIHNoZWxsIHRoYXQgYW4gaWNvbiBpbiB0aGUgc3lzdGVtIGltYWdlIGxpc3QgaGFzIGJlZW4gY2hhbmdlZC4KICoKICogUEFSQU1TCiAqICBwc3pIYXNoSXRlbSBbSV0gUGF0aCB0byBmaWxlIHRoYXQgY29udGFpbnMgdGhlIGljb24uCiAqICBpSW5kZXggICAgICBbSV0gWmVyby1iYXNlZCBpbmRleCBvZiB0aGUgaWNvbiBpbiB0aGUgZmlsZS4KICogIHVGbGFncyAgICAgIFtJXSBGbGFncyBkZXRlcm1pbmluZyB0aGUgaWNvbiBhdHRyaWJ1dGVzLiBTZWUgbm90ZXMuCiAqICBpSW1hZ2VJbmRleCBbSV0gSW5kZXggb2YgdGhlIGljb24gaW4gdGhlIHN5c3RlbSBpbWFnZSBsaXN0LgogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nCiAqCiAqIE5PVEVTCiAqICB1RmxhZ3MgY2FuIGJlIG9uZSBvciBtb3JlIG9mIHRoZSBmb2xsb3dpbmcgZmxhZ3M6CiAqICBHSUxfTk9URklMRU5BTUUgLSBwc3pIYXNoSXRlbSBpcyBub3QgYSBmaWxlIG5hbWUuCiAqICBHSUxfU0lNVUxBVEVET0MgLSBDcmVhdGUgYSBkb2N1bWVudCBpY29uIHVzaW5nIHRoZSBzcGVjaWZpZWQgaWNvbi4KICovCnZvaWQgV0lOQVBJIFNIVXBkYXRlSW1hZ2VXKExQQ1dTVFIgcHN6SGFzaEl0ZW0sIGludCBpSW5kZXgsIFVJTlQgdUZsYWdzLCBpbnQgaUltYWdlSW5kZXgpCnsKICAgIEZJWE1FKCIlcywgJWQsIDB4JXgsICVkIC0gc3R1YlxuIiwgZGVidWdzdHJfdyhwc3pIYXNoSXRlbSksIGlJbmRleCwgdUZsYWdzLCBpSW1hZ2VJbmRleCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSFVwZGF0ZUltYWdlQSAoU0hFTEwzMi4xOTEpCiAqCiAqIFNlZSBTSFVwZGF0ZUltYWdlVy4KICovClZPSUQgV0lOQVBJIFNIVXBkYXRlSW1hZ2VBKExQQ1NUUiBwc3pIYXNoSXRlbSwgSU5UIGlJbmRleCwgVUlOVCB1RmxhZ3MsIElOVCBpSW1hZ2VJbmRleCkKewogICAgRklYTUUoIiVzLCAlZCwgMHgleCwgJWQgLSBzdHViXG4iLCBkZWJ1Z3N0cl9hKHBzekhhc2hJdGVtKSwgaUluZGV4LCB1RmxhZ3MsIGlJbWFnZUluZGV4KTsKfQoKSU5UIFdJTkFQSSBTSEhhbmRsZVVwZGF0ZUltYWdlKExQQ0lURU1JRExJU1QgcGlkbEV4dHJhKQp7CiAgICBGSVhNRSgiJXAgLSBzdHViXG4iLCBwaWRsRXh0cmEpOwoKICAgIHJldHVybiAtMTsKfQoKQk9PTCBXSU5BUEkgU0hPYmplY3RQcm9wZXJ0aWVzKEhXTkQgaHduZCwgRFdPUkQgZHdUeXBlLCBMUENXU1RSIHN6T2JqZWN0LCBMUENXU1RSIHN6UGFnZSkKewogICAgRklYTUUoIiVwLCAweCUwOGx4LCAlcywgJXMgLSBzdHViXG4iLCBod25kLCBkd1R5cGUsIGRlYnVnc3RyX3coc3pPYmplY3QpLCBkZWJ1Z3N0cl93KHN6UGFnZSkpOwoKICAgIHJldHVybiBUUlVFOwp9CgpCT09MIFdJTkFQSSBTSEdldE5ld0xpbmtJbmZvQShMUENTVFIgcHN6TGlua1RvLCBMUENTVFIgcHN6RGlyLCBMUFNUUiBwc3pOYW1lLCBCT09MICpwZk11c3RDb3B5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIHVGbGFncykKewogICAgRklYTUUoIiVzLCAlcywgJXAsICVwLCAweCUwOHggLSBzdHViXG4iLCBkZWJ1Z3N0cl9hKHBzekxpbmtUbyksIGRlYnVnc3RyX2EocHN6RGlyKSwKICAgICAgICAgIHBzek5hbWUsIHBmTXVzdENvcHksIHVGbGFncyk7CgogICAgcmV0dXJuIEZBTFNFOwp9CgpCT09MIFdJTkFQSSBTSEdldE5ld0xpbmtJbmZvVyhMUENXU1RSIHBzekxpbmtUbywgTFBDV1NUUiBwc3pEaXIsIExQV1NUUiBwc3pOYW1lLCBCT09MICpwZk11c3RDb3B5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIHVGbGFncykKewogICAgRklYTUUoIiVzLCAlcywgJXAsICVwLCAweCUwOHggLSBzdHViXG4iLCBkZWJ1Z3N0cl93KHBzekxpbmtUbyksIGRlYnVnc3RyX3cocHN6RGlyKSwKICAgICAgICAgIHBzek5hbWUsIHBmTXVzdENvcHksIHVGbGFncyk7CgogICAgcmV0dXJuIEZBTFNFOwp9CgpIUkVTVUxUIFdJTkFQSSBTSFN0YXJ0TmV0Q29ubmVjdGlvbkRpYWxvZyhIV05EIGh3bmQsIExQQ1NUUiBwc3pSZW1vdGVOYW1lLCBEV09SRCBkd1R5cGUpCnsKICAgIEZJWE1FKCIlcCwgJXMsIDB4JTA4bHggLSBzdHViXG4iLCBod25kLCBkZWJ1Z3N0cl9hKHBzelJlbW90ZU5hbWUpLCBkd1R5cGUpOwoKICAgIHJldHVybiBTX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBTSEVtcHR5UmVjeWNsZUJpbkEoSFdORCBod25kLCBMUENTVFIgcHN6Um9vdFBhdGgsIERXT1JEIGR3RmxhZ3MpCnsKICAgIEZJWE1FKCIlcCwgJXMsIDB4JTA4bHggLSBzdHViXG4iLCBod25kLCBkZWJ1Z3N0cl9hKHBzelJvb3RQYXRoKSwgZHdGbGFncyk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIFNIRW1wdHlSZWN5Y2xlQmluVyhIV05EIGh3bmQsIExQQ1dTVFIgcHN6Um9vdFBhdGgsIERXT1JEIGR3RmxhZ3MpCnsKICAgIEZJWE1FKCIlcCwgJXMsIDB4JTA4bHggLSBzdHViXG4iLCBod25kLCBkZWJ1Z3N0cl93KHBzelJvb3RQYXRoKSwgZHdGbGFncyk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCkRXT1JEIFdJTkFQSSBTSEZvcm1hdERyaXZlKEhXTkQgaHduZCwgVUlOVCBkcml2ZSwgVUlOVCBmbXRJRCwgVUlOVCBvcHRpb25zKQp7CiAgICBGSVhNRSgiJXAsIDB4JTA4eCwgMHglMDh4LCAweCUwOHggLSBzdHViXG4iLCBod25kLCBkcml2ZSwgZm10SUQsIG9wdGlvbnMpOwoKICAgIHJldHVybiBTSEZNVF9OT0ZPUk1BVDsKfQoKSFJFU1VMVCBXSU5BUEkgU0hRdWVyeVJlY3ljbGVCaW5BKExQQ1NUUiBwc3pSb290UGF0aCwgTFBTSFFVRVJZUkJJTkZPIHBTSFF1ZXJ5UkJJbmZvKQp7CiAgICBGSVhNRSgiJXMsICVwIC0gc3R1YlxuIiwgZGVidWdzdHJfYShwc3pSb290UGF0aCksIHBTSFF1ZXJ5UkJJbmZvKTsKCiAgICBwU0hRdWVyeVJCSW5mby0+aTY0U2l6ZSA9IDA7CiAgICBwU0hRdWVyeVJCSW5mby0+aTY0TnVtSXRlbXMgPSAwOwoKICAgIHJldHVybiBTX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBTSFF1ZXJ5UmVjeWNsZUJpblcoTFBDV1NUUiBwc3pSb290UGF0aCwgTFBTSFFVRVJZUkJJTkZPIHBTSFF1ZXJ5UkJJbmZvKQp7CiAgICBGSVhNRSgiJXMsICVwIC0gc3R1YlxuIiwgZGVidWdzdHJfdyhwc3pSb290UGF0aCksIHBTSFF1ZXJ5UkJJbmZvKTsKCiAgICBwU0hRdWVyeVJCSW5mby0+aTY0U2l6ZSA9IDA7CiAgICBwU0hRdWVyeVJCSW5mby0+aTY0TnVtSXRlbXMgPSAwOwoKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgU0hTZXRMb2NhbGl6ZWROYW1lIChTSEVMTDMyLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFNldExvY2FsaXplZE5hbWUoTFBXU1RSIHBzelBhdGgsIExQQ1dTVFIgcHN6UmVzTW9kdWxlLCBpbnQgaWRzUmVzKQp7CiAgICBGSVhNRSgiJXAsICVzLCAlZCAtIHN0dWJcbiIsIHBzelBhdGgsIGRlYnVnc3RyX3cocHN6UmVzTW9kdWxlKSwgaWRzUmVzKTsKCiAgICByZXR1cm4gU19PSzsKfQo=