PD9waHAgIGlmICghZGVmaW5lZCgnQkFTRVBBVEgnKSkgZXhpdCgnTm8gZGlyZWN0IHNjcmlwdCBhY2Nlc3MgYWxsb3dlZCcpOwovKioKICogQ29kZSBJZ25pdGVyCiAqCiAqIEFuIG9wZW4gc291cmNlIGFwcGxpY2F0aW9uIGRldmVsb3BtZW50IGZyYW1ld29yayBmb3IgUEhQIDQuMy4yIG9yIG5ld2VyCiAqCiAqIEBwYWNrYWdlCQlDb2RlSWduaXRlcgogKiBAYXV0aG9yCQlSaWNrIEVsbGlzCiAqIEBjb3B5cmlnaHQJQ29weXJpZ2h0IChjKSAyMDA2LCBwTWFjaGluZSwgSW5jLgogKiBAbGljZW5zZQkJaHR0cDovL3d3dy5jb2RlaWduaXRvci5jb20vdXNlcl9ndWlkZS9saWNlbnNlLmh0bWwgCiAqIEBsaW5rCQlodHRwOi8vd3d3LmNvZGVpZ25pdGVyLmNvbQogKiBAc2luY2UJCVZlcnNpb24gMS4wCiAqIEBmaWxlc291cmNlCiAqLwogCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIElucHV0IENsYXNzCiAqIAogKiBQcmUtcHJvY2Vzc2VzIGdsb2JhbCBpbnB1dCBkYXRhIGZvciBzZWN1cml0eQogKgogKiBAcGFja2FnZQkJQ29kZUlnbml0ZXIKICogQHN1YnBhY2thZ2UJTGlicmFyaWVzCiAqIEBjYXRlZ29yeQlJbnB1dAogKiBAYXV0aG9yCQlSaWNrIEVsbGlzCiAqIEBsaW5rCQlodHRwOi8vd3d3LmNvZGVpZ25pdGVyLmNvbS91c2VyX2d1aWRlL2xpYnJhcmllcy9pbnB1dC5odG1sCiAqLwpjbGFzcyBDSV9JbnB1dCB7Cgl2YXIgJHVzZV94c3NfY2xlYW4JCT0gRkFMU0U7Cgl2YXIgJGlwX2FkZHJlc3MJCQk9IEZBTFNFOwoJdmFyICR1c2VyX2FnZW50CQkJPSBGQUxTRTsKCXZhciAkYWxsb3dfZ2V0X2FycmF5CT0gRkFMU0U7CgkKCS8qKgoJICogQ29uc3RydWN0b3IKCSAqCgkgKiBTZXRzIHdoZXRoZXIgdG8gZ2xvYmFsbHkgZW5hYmxlIHRoZSBYU1MgcHJvY2Vzc2luZwoJICogYW5kIHdoZXRoZXIgdG8gYWxsb3cgdGhlICRfR0VUIGFycmF5CgkgKgoJICogQGFjY2VzcwlwdWJsaWMKCSAqLwkKCWZ1bmN0aW9uIENJX0lucHV0KCkKCXsJCgkJbG9nX21lc3NhZ2UoJ2RlYnVnJywgIklucHV0IENsYXNzIEluaXRpYWxpemVkIik7CgkKCQkkQ0ZHID0mIGxvYWRfY2xhc3MoJ0NvbmZpZycpOwoJCSR0aGlzLT51c2VfeHNzX2NsZWFuCT0gKCRDRkctPml0ZW0oJ2dsb2JhbF94c3NfZmlsdGVyaW5nJykgPT09IFRSVUUpID8gVFJVRSA6IEZBTFNFOwoJCSR0aGlzLT5hbGxvd19nZXRfYXJyYXkJPSAoJENGRy0+aXRlbSgnZW5hYmxlX3F1ZXJ5X3N0cmluZ3MnKSA9PT0gVFJVRSkgPyBUUlVFIDogRkFMU0U7CQkKCQkkdGhpcy0+X3Nhbml0aXplX2dsb2JhbHMoKTsKCX0KCQoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQoJLyoqCgkgKiBTYW5pdGl6ZSBHbG9iYWxzCgkgKgoJICogVGhpcyBmdW5jdGlvbiBkb2VzIHRoZSBmb2xvd2luZzoKCSAqCgkgKiBVbnNldHMgJF9HRVQgZGF0YSAoaWYgcXVlcnkgc3RyaW5ncyBhcmUgbm90IGVuYWJsZWQpCgkgKgoJICogVW5zZXRzIGFsbCBnbG9iYWxzIGlmIHJlZ2lzdGVyX2dsb2JhbHMgaXMgZW5hYmxlZAoJICoKCSAqIFN0YW5kYXJkaXplcyBuZXdsaW5lIGNoYXJhY3RlcnMgdG8gXG4KCSAqCgkgKiBAYWNjZXNzCXByaXZhdGUKCSAqIEByZXR1cm4Jdm9pZAoJICovCglmdW5jdGlvbiBfc2FuaXRpemVfZ2xvYmFscygpCgl7CgkJLy8gVW5zZXQgZ2xvYmFscy4gVGhpcyBpcyBlZmZlY3RpdmVseSB0aGUgc2FtZSBhcyByZWdpc3Rlcl9nbG9iYWxzID0gb2ZmCgkJZm9yZWFjaCAoYXJyYXkoJF9HRVQsICRfUE9TVCwgJF9DT09LSUUpIGFzICRnbG9iYWwpCgkJewoJCQlpZiAoICEgaXNfYXJyYXkoJGdsb2JhbCkpCgkJCXsKCQkJCXVuc2V0KCQkZ2xvYmFsKTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCWZvcmVhY2ggKCRnbG9iYWwgYXMgJGtleSA9PiAkdmFsKQoJCQkJewoJCQkJCXVuc2V0KCQka2V5KTsKCQkJCX0JCgkJCX0KCQl9CgoJCS8vIElzICRfR0VUIGRhdGEgYWxsb3dlZD8gSWYgbm90IHdlJ2xsIHNldCB0aGUgJF9HRVQgdG8gYW4gZW1wdHkgYXJyYXkKCQlpZiAoJHRoaXMtPmFsbG93X2dldF9hcnJheSA9PSBGQUxTRSkKCQl7CgkJCSRfR0VUID0gYXJyYXkoKTsKCQl9CgkJCgkJLy8gQ2xlYW4gJF9QT1NUIERhdGEKCQlpZiAoaXNfYXJyYXkoJF9QT1NUKSBBTkQgY291bnQoJF9QT1NUKSA+IDApCgkJewoJCQlmb3JlYWNoKCRfUE9TVCBhcyAka2V5ID0+ICR2YWwpCgkJCXsJCQkJCgkJCQkkX1BPU1RbJHRoaXMtPl9jbGVhbl9pbnB1dF9rZXlzKCRrZXkpXSA9ICR0aGlzLT5fY2xlYW5faW5wdXRfZGF0YSgkdmFsKTsKCQkJfQkJCQoJCX0KCQoJCS8vIENsZWFuICRfQ09PS0lFIERhdGEKCQlpZiAoaXNfYXJyYXkoJF9DT09LSUUpIEFORCBjb3VudCgkX0NPT0tJRSkgPiAwKQoJCXsKCQkJZm9yZWFjaCgkX0NPT0tJRSBhcyAka2V5ID0+ICR2YWwpCgkJCXsJCQkgIAoJCQkJJF9DT09LSUVbJHRoaXMtPl9jbGVhbl9pbnB1dF9rZXlzKCRrZXkpXSA9ICR0aGlzLT5fY2xlYW5faW5wdXRfZGF0YSgkdmFsKTsKCQkJfQkKCQl9CgkJCgkJbG9nX21lc3NhZ2UoJ2RlYnVnJywgIkdsb2JhbCBQT1NUIGFuZCBDT09LSUUgZGF0YSBzYW5pdGl6ZWQiKTsKCX0JCgkKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkKCS8qKgoJICogQ2xlYW4gSW50cHV0IERhdGEKCSAqCgkgKiBUaGlzIGlzIGEgaGVscGVyIGZ1bmN0aW9uLiBJdCBlc2NhcGVzIGRhdGEgYW5kIAoJICogc3RhbmRhcmRpemVzIG5ld2xpbmUgY2hhcmFjdGVycyB0byBcbgoJICoKCSAqIEBhY2Nlc3MJcHJpdmF0ZQoJICogQHBhcmFtCXN0cmluZwoJICogQHJldHVybglzdHJpbmcKCSAqLwkKCWZ1bmN0aW9uIF9jbGVhbl9pbnB1dF9kYXRhKCRzdHIpCgl7CgkJaWYgKGlzX2FycmF5KCRzdHIpKQoJCXsKCQkJJG5ld19hcnJheSA9IGFycmF5KCk7CgkJCWZvcmVhY2ggKCRzdHIgYXMgJGtleSA9PiAkdmFsKQoJCQl7CgkJCQkkbmV3X2FycmF5WyR0aGlzLT5fY2xlYW5faW5wdXRfa2V5cygka2V5KV0gPSAkdGhpcy0+X2NsZWFuX2lucHV0X2RhdGEoJHZhbCk7CgkJCX0KCQkJcmV0dXJuICRuZXdfYXJyYXk7CgkJfQoJCQoJCWlmICgkdGhpcy0+dXNlX3hzc19jbGVhbiA9PT0gVFJVRSkKCQl7CgkJCSRzdHIgPSAkdGhpcy0+eHNzX2NsZWFuKCRzdHIpOwoJCX0KCQkKCQkvLyBTdGFuZGFyZGl6ZSBuZXdsaW5lcwoJCXJldHVybiBwcmVnX3JlcGxhY2UoIi9cMDE1XDAxMnxcMDE1fFwwMTIvIiwgIlxuIiwgJHN0cik7Cgl9CgkKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkKCS8qKgoJICogQ2xlYW4gS2V5cwoJICoKCSAqIFRoaXMgaXMgYSBoZWxwZXIgZnVuY3Rpb24uIFRvIHByZXZlbnQgbWFsaWNpb3VzIHVzZXJzIAoJICogZnJvbSB0cnlpbmcgdG8gZXhwbG9pdCBrZXlzIHdlIG1ha2Ugc3VyZSB0aGF0IGtleXMgYXJlIAoJICogb25seSBuYW1lZCB3aXRoIGFscGhhLW51bWVyaWMgdGV4dCBhbmQgYSBmZXcgb3RoZXIgaXRlbXMuCgkgKgoJICogQGFjY2Vzcwlwcml2YXRlCgkgKiBAcGFyYW0Jc3RyaW5nCgkgKiBAcmV0dXJuCXN0cmluZwoJICovCglmdW5jdGlvbiBfY2xlYW5faW5wdXRfa2V5cygkc3RyKQoJewkKCQkgaWYgKCAhIHByZWdfbWF0Y2goIi9eW2EtejAtOTpfXC8tXSskL2kiLCAkc3RyKSkKCQkgeyAKCQkJZXhpdCgnRGlzYWxsb3dlZCBLZXkgQ2hhcmFjdGVyczogJy4kc3RyKTsKCQkgfQoJCgkJaWYgKCAhIGdldF9tYWdpY19xdW90ZXNfZ3BjKCkpCgkJewoJCSAgIHJldHVybiBhZGRzbGFzaGVzKCRzdHIpOwoJCX0KCQkKCQlyZXR1cm4gJHN0cjsKCX0KCQoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQoJLyoqCgkgKiBGZXRjaCBhbiBpdGVtIGZyb20gdGhlIFBPU1QgYXJyYXkKCSAqCgkgKiBAYWNjZXNzCXB1YmxpYwoJICogQHBhcmFtCXN0cmluZwoJICogQHBhcmFtCWJvb2wKCSAqIEByZXR1cm4Jc3RyaW5nCgkgKi8KCWZ1bmN0aW9uIHBvc3QoJGluZGV4ID0gJycsICR4c3NfY2xlYW4gPSBGQUxTRSkKCXsJCQoJCWlmICggISBpc3NldCgkX1BPU1RbJGluZGV4XSkpCgkJewoJCQlyZXR1cm4gRkFMU0U7CgkJfQoKCQlpZiAoJHhzc19jbGVhbiA9PT0gVFJVRSkKCQl7CgkJCWlmIChpc19hcnJheSgkX1BPU1RbJGluZGV4XSkpCgkJCXsKCQkJCWZvcmVhY2goJF9QT1NUWyRpbmRleF0gYXMgJGtleSA9PiAkdmFsKQoJCQkJewkJCQkJCgkJCQkJJF9QT1NUWyRpbmRleF1bJGtleV0gPSAkdGhpcy0+eHNzX2NsZWFuKCR2YWwpOwoJCQkJfQoJCQl9CgkJCWVsc2UKCQkJewoJCQkJcmV0dXJuICR0aGlzLT54c3NfY2xlYW4oJF9QT1NUWyRpbmRleF0pOwoJCQl9CgkJfQoKCQlyZXR1cm4gJF9QT1NUWyRpbmRleF07Cgl9CgkKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkKCS8qKgoJICogRmV0Y2ggYW4gaXRlbSBmcm9tIHRoZSBDT09LSUUgYXJyYXkKCSAqCgkgKiBAYWNjZXNzCXB1YmxpYwoJICogQHBhcmFtCXN0cmluZwoJICogQHBhcmFtCWJvb2wKCSAqIEByZXR1cm4Jc3RyaW5nCgkgKi8KCWZ1bmN0aW9uIGNvb2tpZSgkaW5kZXggPSAnJywgJHhzc19jbGVhbiA9IEZBTFNFKQoJewoJCWlmICggISBpc3NldCgkX0NPT0tJRVskaW5kZXhdKSkKCQl7CgkJCXJldHVybiBGQUxTRTsKCQl9CgoJCWlmICgkeHNzX2NsZWFuID09PSBUUlVFKQoJCXsKCQkJaWYgKGlzX2FycmF5KCRfQ09PS0lFWyRpbmRleF0pKQoJCQl7CgkJCQkkY29va2llID0gYXJyYXkoKTsKCQkJCWZvcmVhY2goJF9DT09LSUVbJGluZGV4XSBhcyAka2V5ID0+ICR2YWwpCgkJCQl7CgkJCQkJJGNvb2tpZVska2V5XSA9ICR0aGlzLT54c3NfY2xlYW4oJHZhbCk7CgkJCQl9CgkJCgkJCQlyZXR1cm4gJGNvb2tpZTsKCQkJfQoJCQllbHNlCgkJCXsKCQkJCXJldHVybiAkdGhpcy0+eHNzX2NsZWFuKCRfQ09PS0lFWyRpbmRleF0pOwoJCQl9CgkJfQoJCWVsc2UKCQl7CgkJCXJldHVybiAkX0NPT0tJRVskaW5kZXhdOwoJCX0KCX0KCgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKioKCSAqIEZldGNoIGFuIGl0ZW0gZnJvbSB0aGUgU0VSVkVSIGFycmF5CgkgKgoJICogQGFjY2VzcwlwdWJsaWMKCSAqIEBwYXJhbQlzdHJpbmcKCSAqIEBwYXJhbQlib29sCgkgKiBAcmV0dXJuCXN0cmluZwoJICovCglmdW5jdGlvbiBzZXJ2ZXIoJGluZGV4ID0gJycsICR4c3NfY2xlYW4gPSBGQUxTRSkKCXsJCQoJCWlmICggISBpc3NldCgkX1NFUlZFUlskaW5kZXhdKSkKCQl7CgkJCXJldHVybiBGQUxTRTsKCQl9CgoJCWlmICgkeHNzX2NsZWFuID09PSBUUlVFKQoJCXsKCQkJcmV0dXJuICR0aGlzLT54c3NfY2xlYW4oJF9TRVJWRVJbJGluZGV4XSk7CgkJfQoJCQoJCXJldHVybiAkX1NFUlZFUlskaW5kZXhdOwoJfQoJCgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKioKCSAqIEZldGNoIHRoZSBJUCBBZGRyZXNzCgkgKgoJICogQGFjY2VzcwlwdWJsaWMKCSAqIEByZXR1cm4Jc3RyaW5nCgkgKi8KCWZ1bmN0aW9uIGlwX2FkZHJlc3MoKQoJewoJCWlmICgkdGhpcy0+aXBfYWRkcmVzcyAhPT0gRkFMU0UpCgkJewoJCQlyZXR1cm4gJHRoaXMtPmlwX2FkZHJlc3M7CgkJfQoJCQoJCWlmICgkdGhpcy0+c2VydmVyKCdSRU1PVEVfQUREUicpIEFORCAkdGhpcy0+c2VydmVyKCdIVFRQX0NMSUVOVF9JUCcpKQoJCXsKCQkJICR0aGlzLT5pcF9hZGRyZXNzID0gJF9TRVJWRVJbJ0hUVFBfQ0xJRU5UX0lQJ107CgkJfQoJCWVsc2VpZiAoJHRoaXMtPnNlcnZlcignUkVNT1RFX0FERFInKSkKCQl7CgkJCSAkdGhpcy0+aXBfYWRkcmVzcyA9ICRfU0VSVkVSWydSRU1PVEVfQUREUiddOwoJCX0KCQllbHNlaWYgKCR0aGlzLT5zZXJ2ZXIoJ0hUVFBfQ0xJRU5UX0lQJykpCgkJewoJCQkgJHRoaXMtPmlwX2FkZHJlc3MgPSAkX1NFUlZFUlsnSFRUUF9DTElFTlRfSVAnXTsKCQl9CgkJZWxzZWlmICgkdGhpcy0+c2VydmVyKCdIVFRQX1hfRk9SV0FSREVEX0ZPUicpKQoJCXsKCQkJICR0aGlzLT5pcF9hZGRyZXNzID0gJF9TRVJWRVJbJ0hUVFBfWF9GT1JXQVJERURfRk9SJ107CgkJfQoJCQoJCWlmICgkdGhpcy0+aXBfYWRkcmVzcyA9PT0gRkFMU0UpCgkJewoJCQkkdGhpcy0+aXBfYWRkcmVzcyA9ICcwLjAuMC4wJzsKCQkJcmV0dXJuICR0aGlzLT5pcF9hZGRyZXNzOwoJCX0KCQkKCQlpZiAoc3Ryc3RyKCR0aGlzLT5pcF9hZGRyZXNzLCAnLCcpKQoJCXsKCQkJJHggPSBleHBsb2RlKCcsJywgJHRoaXMtPmlwX2FkZHJlc3MpOwoJCQkkdGhpcy0+aXBfYWRkcmVzcyA9IGVuZCgkeCk7CgkJfQoJCQoJCWlmICggISAkdGhpcy0+dmFsaWRfaXAoJHRoaXMtPmlwX2FkZHJlc3MpKQoJCXsKCQkJJHRoaXMtPmlwX2FkZHJlc3MgPSAnMC4wLjAuMCc7CgkJfQoJCQkJCgkJcmV0dXJuICR0aGlzLT5pcF9hZGRyZXNzOwoJfQoJCgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKioKCSAqIFZhbGlkYXRlIElQIEFkZHJlc3MKCSAqCgkgKiBAYWNjZXNzCXB1YmxpYwoJICogQHBhcmFtCXN0cmluZwoJICogQHJldHVybglzdHJpbmcKCSAqLwoJZnVuY3Rpb24gdmFsaWRfaXAoJGlwKQoJewoJCXJldHVybiAoICEgcHJlZ19tYXRjaCggIi9eWzAtOV17MSwzfVwuWzAtOV17MSwzfVwuWzAtOV17MSwzfVwuWzAtOV17MSwzfSQvIiwgJGlwKSkgPyBGQUxTRSA6IFRSVUU7Cgl9CgkKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkKCS8qKgoJICogVXNlciBBZ2VudAoJICoKCSAqIEBhY2Nlc3MJcHVibGljCgkgKiBAcmV0dXJuCXN0cmluZwoJICovCglmdW5jdGlvbiB1c2VyX2FnZW50KCkKCXsKCQlpZiAoJHRoaXMtPnVzZXJfYWdlbnQgIT09IEZBTFNFKQoJCXsKCQkJcmV0dXJuICR0aGlzLT51c2VyX2FnZW50OwoJCX0KCQoJCSR0aGlzLT51c2VyX2FnZW50ID0gKCAhIGlzc2V0KCRfU0VSVkVSWydIVFRQX1VTRVJfQUdFTlQnXSkpID8gRkFMU0UgOiAkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ107CgkJCgkJcmV0dXJuICR0aGlzLT51c2VyX2FnZW50OwoJfQoJCgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKioKCSAqIFhTUyBDbGVhbgoJICoKCSAqIFNhbml0aXplcyBkYXRhIHNvIHRoYXQgQ3Jvc3MgU2l0ZSBTY3JpcHRpbmcgSGFja3MgY2FuIGJlCgkgKiBwcmV2ZW50ZWQuyiBUaGlzIGZ1bmN0aW9uIGRvZXMgYSBmYWlyIGFtb3VudCBvZiB3b3JrIGJ1dAoJICogaXQgaXMgZXh0cmVtZWx5IHRob3JvdWdoLCBkZXNpZ25lZCB0byBwcmV2ZW50IGV2ZW4gdGhlCgkgKiBtb3N0IG9ic2N1cmUgWFNTIGF0dGVtcHRzLsogTm90aGluZyBpcyBldmVyIDEwMCUgZm9vbHByb29mLAoJICogb2YgY291cnNlLCBidXQgSSBoYXZlbid0IGJlZW4gYWJsZSB0byBnZXQgYW55dGhpbmcgcGFzc2VkCgkgKiB0aGUgZmlsdGVyLgoJICoKCSAqIE5vdGU6IFRoaXMgZnVuY3Rpb24gc2hvdWxkIG9ubHkgYmUgdXNlZCB0byBkZWFsIHdpdGggZGF0YQoJICogdXBvbiBzdWJtaXNzaW9uLsogSXQncyBub3Qgc29tZXRoaW5nIHRoYXQgc2hvdWxkCgkgKiBiZSB1c2VkIGZvciBnZW5lcmFsIHJ1bnRpbWUgcHJvY2Vzc2luZy4KCSAqCgkgKiBUaGlzIGZ1bmN0aW9uIHdhcyBiYXNlZCBpbiBwYXJ0IG9uIHNvbWUgY29kZSBhbmQgaWRlYXMgSQoJICogZ290IGZyb20gQml0Zmx1eDogaHR0cDovL2Jsb2cuYml0Zmx1eC5jaC93aWtpL1hTU19QcmV2ZW50aW9uCgkgKgoJICogVG8gaGVscCBkZXZlbG9wIHRoaXMgc2NyaXB0IEkgdXNlZCB0aGlzIGdyZWF0IGxpc3Qgb2YKCSAqIHZ1bG5lcmFiaWxpdGllcyBhbG9uZyB3aXRoIGEgZmV3IG90aGVyIGhhY2tzIEkndmUgCgkgKiBoYXJ2ZXN0ZWQgZnJvbSBleGFtaW5pbmcgdnVsbmVyYWJpbGl0aWVzIGluIG90aGVyIHByb2dyYW1zOgoJICogaHR0cDovL2hhLmNrZXJzLm9yZy94c3MuaHRtbAoJICoKCSAqIEBhY2Nlc3MJcHVibGljCgkgKiBAcGFyYW0Jc3RyaW5nCgkgKiBAcmV0dXJuCXN0cmluZwoJICovCglmdW5jdGlvbiB4c3NfY2xlYW4oJHN0ciwgJGNoYXJzZXQgPSAnSVNPLTg4NTktMScpCgl7CQoJCS8qCgkJICogUmVtb3ZlIE51bGwgQ2hhcmFjdGVycwoJCSAqCgkJICogVGhpcyBwcmV2ZW50cyBzYW5kd2ljaGluZyBudWxsIGNoYXJhY3RlcnMKCQkgKiBiZXR3ZWVuIGFzY2lpIGNoYXJhY3RlcnMsIGxpa2UgSmF2YVwwc2NyaXB0LgoJCSAqCgkJICovCgkJJHN0ciA9IHByZWdfcmVwbGFjZSgnL1wwKy8nLCAnJywgJHN0cik7CgkJJHN0ciA9IHByZWdfcmVwbGFjZSgnLyhcXFxcMCkrLycsICcnLCAkc3RyKTsKCgkJLyoKCQkgKiBWYWxpZGF0ZSBzdGFuZGFyZCBjaGFyYWN0ZXIgZW50aXRlcwoJCSAqCgkJICogQWRkIGEgc2VtaWNvbG9uIGlmIG1pc3NpbmcuICBXZSBkbyB0aGlzIHRvIGVuYWJsZQoJCSAqIHRoZSBjb252ZXJzaW9uIG9mIGVudGl0aWVzIHRvIEFTQ0lJIGxhdGVyLgoJCSAqCgkJICovCgkJJHN0ciA9IHByZWdfcmVwbGFjZSgnIygmXCMqXHcrKVtceDAwLVx4MjBdKzsjdScsIlxcMTsiLCRzdHIpOwoJCQoJCS8qCgkJICogVmFsaWRhdGUgVVRGMTYgdHdvIGJ5dGUgZW5jb2RlaW5nICh4MDApIAoJCSAqCgkJICogSnVzdCBhcyBhYm92ZSwgYWRkcyBhIHNlbWljb2xvbiBpZiBtaXNzaW5nLgoJCSAqCgkJICovCgkJJHN0ciA9IHByZWdfcmVwbGFjZSgnIygmXCN4KikoWzAtOUEtRl0rKTsqI2l1JywiXFwxXFwyOyIsJHN0cik7CgoJCS8qCgkJICogVVJMIERlY29kZQoJCSAqCgkJICogSnVzdCBpbiBjYXNlIHN0dWZmIGxpa2UgdGhpcyBpcyBzdWJtaXR0ZWQ6CgkJICoKCQkgKiA8YSBocmVmPSJodHRwOi8vJTc3JTc3JTc3JTJFJTY3JTZGJTZGJTY3JTZDJTY1JTJFJTYzJTZGJTZEIj5Hb29nbGU8L2E+CgkJICoKCQkgKiBOb3RlOiBOb3JtYWxseSB1cmxkZWNvZGUoKSB3b3VsZCBiZSBlYXNpZXIgYnV0IGl0IHJlbW92ZXMgcGx1cyBzaWducwoJCSAqCgkJICovCQoJCSRzdHIgPSBwcmVnX3JlcGxhY2UoIi8ldTAoW2EtejAtOV17M30pL2kiLCAiJiN4XFwxOyIsICRzdHIpOwoJCSRzdHIgPSBwcmVnX3JlcGxhY2UoIi8lKFthLXowLTldezJ9KS9pIiwgIiYjeFxcMTsiLCAkc3RyKTsJCQoJCQkJCgkJLyoKCQkgKiBDb252ZXJ0IGNoYXJhY3RlciBlbnRpdGllcyB0byBBU0NJSSAKCQkgKgoJCSAqIFRoaXMgcGVybWl0cyBvdXIgdGVzdHMgYmVsb3cgdG8gd29yayByZWxpYWJseS4KCQkgKiBXZSBvbmx5IGNvbnZlcnQgZW50aXRpZXMgdGhhdCBhcmUgd2l0aGluIHRhZ3Mgc2luY2UKCQkgKiB0aGVzZSBhcmUgdGhlIG9uZXMgdGhhdCB3aWxsIHBvc2Ugc2VjdXJpdHkgcHJvYmxlbXMuCgkJICoKCQkgKi8KCQkgCgkJaWYgKHByZWdfbWF0Y2hfYWxsKCIvPCguKz8pPi9zaSIsICRzdHIsICRtYXRjaGVzKSkKCQl7CQkKCQkJZm9yICgkaSA9IDA7ICRpIDwgY291bnQoJG1hdGNoZXNbJzAnXSk7ICRpKyspCgkJCXsKCQkJCSRzdHIgPSBzdHJfcmVwbGFjZSgkbWF0Y2hlc1snMSddWyRpXSwgCgkJCQkJCQkJCSR0aGlzLT5faHRtbF9lbnRpdHlfZGVjb2RlKCRtYXRjaGVzWycxJ11bJGldLCAkY2hhcnNldCksIAoJCQkJCQkJCQkkc3RyKTsKCQkJfQoJCX0KCQoJCS8qCgkJICogQ29udmVydCBhbGwgdGFicyB0byBzcGFjZXMKCQkgKgoJCSAqIFRoaXMgcHJldmVudHMgc3RyaW5ncyBsaWtlIHRoaXM6IGphCXZhc2NyaXB0CgkJICogTm90ZTogd2UgZGVhbCB3aXRoIHNwYWNlcyBiZXR3ZWVuIGNoYXJhY3RlcnMgbGF0ZXIuCgkJICoKCQkgKi8JCQoJCSRzdHIgPSBwcmVnX3JlcGxhY2UoIiNcdCsjIiwgIiAiLCAkc3RyKTsKCQoJCS8qCgkJICogTWFrZXMgUEhQIHRhZ3Mgc2FmZQoJCSAqCgkJICogIE5vdGU6IFhNTCB0YWdzIGFyZSBpbmFkdmVydGVudGx5IHJlcGxhY2VkIHRvbzoKCQkgKgoJCSAqCTw/eG1sCgkJICoKCQkgKiBCdXQgaXQgZG9lc24ndCBzZWVtIHRvIHBvc2UgYSBwcm9ibGVtLgoJCSAqCgkJICovCQkKCQkkc3RyID0gc3RyX3JlcGxhY2UoYXJyYXkoJzw/cGhwJywgJzw/UEhQJywgJzw/JywgJz8+JyksICBhcnJheSgnJmx0Oz9waHAnLCAnJmx0Oz9QSFAnLCAnJmx0Oz8nLCAnPyZndDsnKSwgJHN0cik7CgkKCQkvKgoJCSAqIENvbXBhY3QgYW55IGV4cGxvZGVkIHdvcmRzCgkJICoKCQkgKiBUaGlzIGNvcnJlY3RzIHdvcmRzIGxpa2U6ICBqIGEgdiBhIHMgYyByIGkgcCB0CgkJICogVGhlc2Ugd29yZHMgYXJlIGNvbXBhY3RlZCBiYWNrIHRvIHRoZWlyIGNvcnJlY3Qgc3RhdGUuCgkJICoKCQkgKi8JCQoJCSR3b3JkcyA9IGFycmF5KCdqYXZhc2NyaXB0JywgJ3Zic2NyaXB0JywgJ3NjcmlwdCcsICdhcHBsZXQnLCAnYWxlcnQnLCAnZG9jdW1lbnQnLCAnd3JpdGUnLCAnY29va2llJywgJ3dpbmRvdycpOwoJCWZvcmVhY2ggKCR3b3JkcyBhcyAkd29yZCkKCQl7CgkJCSR0ZW1wID0gJyc7CgkJCWZvciAoJGkgPSAwOyAkaSA8IHN0cmxlbigkd29yZCk7ICRpKyspCgkJCXsKCQkJCSR0ZW1wIC49IHN1YnN0cigkd29yZCwgJGksIDEpLiJccyoiOwoJCQl9CgkJCQoJCQkkdGVtcCA9IHN1YnN0cigkdGVtcCwgMCwgLTMpOwoJCQkkc3RyID0gcHJlZ19yZXBsYWNlKCcjJy4kdGVtcC4nI3MnLCAkd29yZCwgJHN0cik7CgkJCSRzdHIgPSBwcmVnX3JlcGxhY2UoJyMnLnVjZmlyc3QoJHRlbXApLicjcycsIHVjZmlyc3QoJHdvcmQpLCAkc3RyKTsKCQl9CgkKCQkvKgoJCSAqIFJlbW92ZSBkaXNhbGxvd2VkIEphdmFzY3JpcHQgaW4gbGlua3Mgb3IgaW1nIHRhZ3MKCQkgKi8JCQoJCSAkc3RyID0gcHJlZ19yZXBsYWNlKCIjPGEuKz9ocmVmPS4qPyhhbGVydFwofGFsZXJ0JlwjNDA7fGphdmFzY3JpcHRcOnx3aW5kb3dcLnxkb2N1bWVudFwufFwuY29va2llfDxzY3JpcHR8PHhzcykuKj9cPi4qPzwvYT4jc2kiLCAiIiwgJHN0cik7CgkJICRzdHIgPSBwcmVnX3JlcGxhY2UoIiM8aW1nLis/c3JjPS4qPyhhbGVydFwofGFsZXJ0JlwjNDA7fGphdmFzY3JpcHRcOnx3aW5kb3dcLnxkb2N1bWVudFwufFwuY29va2llfDxzY3JpcHR8PHhzcykuKj9cPiNzaSIsICIiLCAkc3RyKTsKCQkgJHN0ciA9IHByZWdfcmVwbGFjZSgiIzwoc2NyaXB0fHhzcykuKj9cPiNzaSIsICIiLCAkc3RyKTsKCgkJLyoKCQkgKiBSZW1vdmUgSmF2YVNjcmlwdCBFdmVudCBIYW5kbGVycwoJCSAqCgkJICogTm90ZTogVGhpcyBjb2RlIGlzIGEgbGl0dGxlIGJsdW50LiAgSXQgcmVtb3ZlcwoJCSAqIHRoZSBldmVudCBoYW5kbGVyIGFuZCBhbnl0aGluZyB1cCB0byB0aGUgY2xvc2luZyA+LCAKCQkgKiBidXQgaXQncyB1bmxrZWx5IHRvIGJlIGEgcHJvYmxlbS4KCQkgKgoJCSAqLwkJCgkJICRzdHIgPSBwcmVnX3JlcGxhY2UoJyMoPFtePl0rLio/KShvbmJsdXJ8b25jaGFuZ2V8b25jbGlja3xvbmZvY3VzfG9ubG9hZHxvbm1vdXNlb3Zlcnxvbm1vdXNldXB8b25tb3VzZWRvd258b25zZWxlY3R8b25zdWJtaXR8b251bmxvYWR8b25rZXlwcmVzc3xvbmtleWRvd258b25rZXl1cHxvbnJlc2l6ZSlbXj5dKj4jaVUnLCJcXDE+Iiwkc3RyKTsKCQoJCS8qCgkJICogU2FuaXRpemUgbmF1Z2h0eSBIVE1MIGVsZW1lbnRzCgkJICoKCQkgKiBJZiBhIHRhZyBjb250YWluaW5nIGFueSBvZiB0aGUgd29yZHMgaW4gdGhlIGxpc3QgCgkJICogYmVsb3cgaXMgZm91bmQsIHRoZSB0YWcgZ2V0cyBjb252ZXJ0ZWQgdG8gZW50aXRpZXMuCgkJICoKCQkgKiBTbyB0aGlzOiA8Ymxpbms+CgkJICogQmVjb21lczogJmx0O2JsaW5rJmd0OwoJCSAqCgkJICovCQkKCQkkc3RyID0gcHJlZ19yZXBsYWNlKCcjPCgvKlxzKikoYWxlcnR8YXBwbGV0fGJhc2Vmb250fGJhc2V8YmVoYXZpb3J8Ymdzb3VuZHxibGlua3xib2R5fGVtYmVkfGV4cHJlc3Npb258Zm9ybXxmcmFtZXNldHxmcmFtZXxoZWFkfGh0bWx8aWxheWVyfGlmcmFtZXxpbnB1dHxsYXllcnxsaW5rfG1ldGF8b2JqZWN0fHBsYWludGV4dHxzdHlsZXxzY3JpcHR8dGV4dGFyZWF8dGl0bGV8eG1sfHhzcykoW14+XSopPiNpcycsICImbHQ7XFwxXFwyXFwzJmd0OyIsICRzdHIpOwoJCQoJCS8qCgkJICogU2FuaXRpemUgbmF1Z2h0eSBzY3JpcHRpbmcgZWxlbWVudHMKCQkgKgoJCSAqIFNpbWlsYXIgdG8gYWJvdmUsIG9ubHkgaW5zdGVhZCBvZiBsb29raW5nIGZvcgoJCSAqIHRhZ3MgaXQgbG9va3MgZm9yIFBIUCBhbmQgSmF2YVNjcmlwdCBjb21tYW5kcwoJCSAqIHRoYXQgYXJlIGRpc2FsbG93ZWQuICBSYXRoZXIgdGhhbiByZW1vdmluZyB0aGUKCQkgKiBjb2RlLCBpdCBzaW1wbHkgY29udmVydHMgdGhlIHBhcmVudGhlc2lzIHRvIGVudGl0aWVzCgkJICogcmVuZGVyaW5nIHRoZSBjb2RlIHVuZXhlY3V0YWJsZS4KCQkgKgoJCSAqIEZvciBleGFtcGxlOglldmFsKCdzb21lIGNvZGUnKQoJCSAqIEJlY29tZXM6CQlldmFsJiM0MDsnc29tZSBjb2RlJyYjNDE7CgkJICoKCQkgKi8KCQkkc3RyID0gcHJlZ19yZXBsYWNlKCcjKGFsZXJ0fGNtZHxwYXNzdGhydXxldmFsfGV4ZWN8c3lzdGVtfGZvcGVufGZzb2Nrb3BlbnxmaWxlfGZpbGVfZ2V0X2NvbnRlbnRzfHJlYWRmaWxlfHVubGluaykoXHMqKVwoKC4qPylcKSNzaScsICJcXDFcXDImIzQwO1xcMyYjNDE7IiwgJHN0cik7CgkJCQkJCQoJCS8qCgkJICogRmluYWwgY2xlYW4gdXAKCQkgKgoJCSAqIFRoaXMgYWRkcyBhIGJpdCBvZiBleHRyYSBwcmVjYXV0aW9uIGluIGNhc2UKCQkgKiBzb21ldGhpbmcgZ290IHRocm91Z2ggdGhlIGFib3ZlIGZpbHRlcnMKCQkgKgoJCSAqLwkKCQkkYmFkID0gYXJyYXkoCgkJCQkJCSdkb2N1bWVudC5jb29raWUnCT0+ICcnLAoJCQkJCQknZG9jdW1lbnQud3JpdGUnCT0+ICcnLAoJCQkJCQknd2luZG93LmxvY2F0aW9uJwk9PiAnJywKCQkJCQkJImphdmFzY3JpcHRccyo6Igk9PiAnJywKCQkJCQkJIlJlZGlyZWN0XHMrMzAyIgk9PiAnJywKCQkJCQkJJzwhLS0nCQkJCT0+ICcmbHQ7IS0tJywKCQkJCQkJJy0tPicJCQkJPT4gJy0tJmd0OycKCQkJCQkpOwoJCgkJZm9yZWFjaCAoJGJhZCBhcyAka2V5ID0+ICR2YWwpCgkJewoJCQkkc3RyID0gcHJlZ19yZXBsYWNlKCIjIi4ka2V5LiIjaSIsICR2YWwsICRzdHIpOyAgIAoJCX0KCQkKCQkJCQkJCgkJbG9nX21lc3NhZ2UoJ2RlYnVnJywgIlhTUyBGaWx0ZXJpbmcgY29tcGxldGVkIik7CgkJcmV0dXJuICRzdHI7Cgl9CgoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgkvKioKCSAqIEhUTUwgRW50aXRpZXMgRGVjb2RlCgkgKgoJICogVGhpcyBmdW5jdGlvbiBpcyBhIHJlcGxhY2VtZW50IGZvciBodG1sX2VudGl0eV9kZWNvZGUoKQoJICoKCSAqIEluIHNvbWUgdmVyc2lvbnMgb2YgUEhQIHRoZSBuYXRpdmUgZnVuY3Rpb24gZG9lcyBub3Qgd29yawoJICogd2hlbiBVVEYtOCBpcyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBzZXQsIHNvIHRoaXMgZ2l2ZXMgdXMKCSAqIGEgd29yay1hcm91bmQuICBNb3JlIGluZm8gaGVyZToKCSAqIGh0dHA6Ly9idWdzLnBocC5uZXQvYnVnLnBocD9pZD0yNTY3MAoJICoKCSAqIEBhY2Nlc3MJcHJpdmF0ZQoJICogQHBhcmFtCXN0cmluZwoJICogQHBhcmFtCXN0cmluZwoJICogQHJldHVybglzdHJpbmcKCSAqLwoJLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJLyogIFJlcGxhY2VtZW50IGZvciBodG1sX2VudGl0eV9kZWNvZGUoKQoJLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgkKCS8qCglOT1RFOiBodG1sX2VudGl0eV9kZWNvZGUoKSBoYXMgYSBidWcgaW4gc29tZSBQSFAgdmVyc2lvbnMgd2hlbiBVVEYtOCBpcyB0aGUgCgljaGFyYWN0ZXIgc2V0LCBhbmQgdGhlIFBIUCBkZXZlbG9wZXJzIHNhaWQgdGhleSB3ZXJlIG5vdCBiYWNrIHBvcnRpbmcgdGhlCglmaXggdG8gdmVyc2lvbnMgb3RoZXIgdGhhbiBQSFAgNS54LgoJKi8KCWZ1bmN0aW9uIF9odG1sX2VudGl0eV9kZWNvZGUoJHN0ciwgJGNoYXJzZXQ9J0lTTy04ODU5LTEnKSAKCXsKCQlpZiAoc3RyaXN0cigkc3RyLCAnJicpID09PSBGQUxTRSkgcmV0dXJuICRzdHI7CgkKCQkvLyBUaGUgcmVhc29uIHdlIGFyZSBub3QgdXNpbmcgaHRtbF9lbnRpdHlfZGVjb2RlKCkgYnkgaXRzZWxmIGlzIGJlY2F1c2UKCQkvLyB3aGlsZSBpdCBpcyBub3QgdGVjaG5pY2FsbHkgY29ycmVjdCB0byBsZWF2ZSBvdXQgdGhlIHNlbWljb2xvbgoJCS8vIGF0IHRoZSBlbmQgb2YgYW4gZW50aXR5IG1vc3QgYnJvd3NlcnMgd2lsbCBzdGlsbCBpbnRlcnByZXQgdGhlIGVudGl0eQoJCS8vIGNvcnJlY3RseS4gIGh0bWxfZW50aXR5X2RlY29kZSgpIGRvZXMgbm90IGNvbnZlcnQgZW50aXRpZXMgd2l0aG91dAoJCS8vIHNlbWljb2xvbnMsIHNvIHdlIGFyZSBsZWZ0IHdpdGggb3VyIG93biBsaXR0bGUgc29sdXRpb24gaGVyZS4gQnVtbWVyLgoJCgkJaWYgKGZ1bmN0aW9uX2V4aXN0cygnaHRtbF9lbnRpdHlfZGVjb2RlJykgJiYgKHN0cnRvbG93ZXIoJGNoYXJzZXQpICE9ICd1dGYtOCcgT1IgdmVyc2lvbl9jb21wYXJlKHBocHZlcnNpb24oKSwgJzUuMC4wJywgJz49JykpKQoJCXsKCQkJJHN0ciA9IGh0bWxfZW50aXR5X2RlY29kZSgkc3RyLCBFTlRfQ09NUEFULCAkY2hhcnNldCk7CgkJCSRzdHIgPSBwcmVnX3JlcGxhY2UoJ34mI3goWzAtOWEtZl17Miw1fSl+ZWknLCAnY2hyKGhleGRlYygiXFwxIikpJywgJHN0cik7CgkJCXJldHVybiBwcmVnX3JlcGxhY2UoJ34mIyhbMC05XXsyLDR9KX5lJywgJ2NocihcXDEpJywgJHN0cik7CgkJfQoJCQoJCS8vIE51bWVyaWMgRW50aXRpZXMKCQkkc3RyID0gcHJlZ19yZXBsYWNlKCd+JiN4KFswLTlhLWZdezIsNX0pO3swLDF9fmVpJywgJ2NocihoZXhkZWMoIlxcMSIpKScsICRzdHIpOwoJCSRzdHIgPSBwcmVnX3JlcGxhY2UoJ34mIyhbMC05XXsyLDR9KTt7MCwxfX5lJywgJ2NocihcXDEpJywgJHN0cik7CgkKCQkvLyBMaXRlcmFsIEVudGl0aWVzIC0gU2xpZ2h0bHkgc2xvdyBzbyB3ZSBkbyBhbm90aGVyIGNoZWNrCgkJaWYgKHN0cmlzdHIoJHN0ciwgJyYnKSA9PT0gRkFMU0UpCgkJewoJCQkkc3RyID0gc3RydHIoJHN0ciwgYXJyYXlfZmxpcChnZXRfaHRtbF90cmFuc2xhdGlvbl90YWJsZShIVE1MX0VOVElUSUVTKSkpOwoJCX0KCQkKCQlyZXR1cm4gJHN0cjsKCX0KCn0KLy8gRU5EIElucHV0IGNsYXNzCj8+