PD9waHAgIGlmICghZGVmaW5lZCgnQkFTRVBBVEgnKSkgZXhpdCgnTm8gZGlyZWN0IHNjcmlwdCBhY2Nlc3MgYWxsb3dlZCcpOwovKioKICogQ29kZSBJZ25pdGVyCiAqCiAqIEFuIG9wZW4gc291cmNlIGFwcGxpY2F0aW9uIGRldmVsb3BtZW50IGZyYW1ld29yayBmb3IgUEhQIDQuMy4yIG9yIG5ld2VyCiAqCiAqIEBwYWNrYWdlCQlDb2RlSWduaXRlcgogKiBAYXV0aG9yCQlSaWNrIEVsbGlzCiAqIEBjb3B5cmlnaHQJQ29weXJpZ2h0IChjKSAyMDA2LCBwTWFjaGluZSwgSW5jLgogKiBAbGljZW5zZQkJaHR0cDovL3d3dy5jb2RlaWduaXRvci5jb20vdXNlcl9ndWlkZS9saWNlbnNlLmh0bWwgCiAqIEBsaW5rCQlodHRwOi8vd3d3LmNvZGVpZ25pdGVyLmNvbQogKiBAc2luY2UJCVZlcnNpb24gMS4wCiAqIEBmaWxlc291cmNlCiAqLwogCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCiAqIElucHV0IENsYXNzCiAqIAogKiBQcmUtcHJvY2Vzc2VzIGdsb2JhbCBpbnB1dCBkYXRhIGZvciBzZWN1cml0eQogKgogKiBAcGFja2FnZQkJQ29kZUlnbml0ZXIKICogQHN1YnBhY2thZ2UJTGlicmFyaWVzCiAqIEBjYXRlZ29yeQlJbnB1dAogKiBAYXV0aG9yCQlSaWNrIEVsbGlzCiAqIEBsaW5rCQlodHRwOi8vd3d3LmNvZGVpZ25pdGVyLmNvbS91c2VyX2d1aWRlL2xpYnJhcmllcy9pbnB1dC5odG1sCiAqLwpjbGFzcyBDSV9JbnB1dCB7Cgl2YXIgJHVzZV94c3NfY2xlYW4JCT0gRkFMU0U7Cgl2YXIgJGlwX2FkZHJlc3MJCQk9IEZBTFNFOwoJdmFyICR1c2VyX2FnZW50CQkJPSBGQUxTRTsKCXZhciAkYWxsb3dfZ2V0X2FycmF5CT0gRkFMU0U7CgkKCS8qKgoJICogQ29uc3RydWN0b3IKCSAqCgkgKiBTZXRzIHdoZXRoZXIgdG8gZ2xvYmFsbHkgZW5hYmxlIHRoZSBYU1MgcHJvY2Vzc2luZwoJICogYW5kIHdoZXRoZXIgdG8gYWxsb3cgdGhlICRfR0VUIGFycmF5CgkgKgoJICogQGFjY2VzcwlwdWJsaWMKCSAqLwkKCWZ1bmN0aW9uIENJX0lucHV0KCkKCXsJCgkJbG9nX21lc3NhZ2UoJ2RlYnVnJywgIklucHV0IENsYXNzIEluaXRpYWxpemVkIik7CgkKCQkkQ0ZHID0mIF9sb2FkX2NsYXNzKCdDb25maWcnKTsKCQkkdGhpcy0+dXNlX3hzc19jbGVhbgk9ICgkQ0ZHLT5pdGVtKCdnbG9iYWxfeHNzX2ZpbHRlcmluZycpID09PSBUUlVFKSA/IFRSVUUgOiBGQUxTRTsKCQkkdGhpcy0+YWxsb3dfZ2V0X2FycmF5CT0gKCRDRkctPml0ZW0oJ2VuYWJsZV9xdWVyeV9zdHJpbmdzJykgPT09IFRSVUUpID8gVFJVRSA6IEZBTFNFOwkJCgkJJHRoaXMtPl9zYW5pdGl6ZV9nbG9iYWxzKCk7Cgl9CgkKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkKCS8qKgoJICogU2FuaXRpemUgR2xvYmFscwoJICoKCSAqIFRoaXMgZnVuY3Rpb24gZG9lcyB0aGUgZm9sb3dpbmc6CgkgKgoJICogVW5zZXRzICRfR0VUIGRhdGEgKGlmIHF1ZXJ5IHN0cmluZ3MgYXJlIG5vdCBlbmFibGVkKQoJICoKCSAqIFVuc2V0cyBhbGwgZ2xvYmFscyBpZiByZWdpc3Rlcl9nbG9iYWxzIGlzIGVuYWJsZWQKCSAqCgkgKiBTdGFuZGFyZGl6ZXMgbmV3bGluZSBjaGFyYWN0ZXJzIHRvIFxuCgkgKgoJICogQGFjY2Vzcwlwcml2YXRlCgkgKiBAcmV0dXJuCXZvaWQKCSAqLwoJZnVuY3Rpb24gX3Nhbml0aXplX2dsb2JhbHMoKQoJewoJCS8vIFVuc2V0IGdsb2JhbHMuIFRoaXMgaXMgZWZmZWN0aXZlbHkgdGhlIHNhbWUgYXMgcmVnaXN0ZXJfZ2xvYmFscyA9IG9mZgoJCWZvcmVhY2ggKGFycmF5KCRfR0VULCAkX1BPU1QsICRfQ09PS0lFKSBhcyAkZ2xvYmFsKQoJCXsKCQkJaWYgKCAhIGlzX2FycmF5KCRnbG9iYWwpKQoJCQl7CgkJCQl1bnNldCgkJGdsb2JhbCk7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlmb3JlYWNoICgkZ2xvYmFsIGFzICRrZXkgPT4gJHZhbCkKCQkJCXsKCQkJCQl1bnNldCgkJGtleSk7CgkJCQl9CQoJCQl9CgkJfQoKCQkvLyBJcyAkX0dFVCBkYXRhIGFsbG93ZWQ/IElmIG5vdCB3ZSdsbCBzZXQgdGhlICRfR0VUIHRvIGFuIGVtcHR5IGFycmF5CgkJaWYgKCR0aGlzLT5hbGxvd19nZXRfYXJyYXkgPT0gRkFMU0UpCgkJewoJCQkkX0dFVCA9IGFycmF5KCk7CgkJfQoJCQoJCS8vIENsZWFuICRfUE9TVCBEYXRhCgkJaWYgKGlzX2FycmF5KCRfUE9TVCkgQU5EIGNvdW50KCRfUE9TVCkgPiAwKQoJCXsKCQkJZm9yZWFjaCgkX1BPU1QgYXMgJGtleSA9PiAkdmFsKQoJCQl7CQkJCQoJCQkJJF9QT1NUWyR0aGlzLT5fY2xlYW5faW5wdXRfa2V5cygka2V5KV0gPSAkdGhpcy0+X2NsZWFuX2lucHV0X2RhdGEoJHZhbCk7CgkJCX0JCQkKCQl9CgkKCQkvLyBDbGVhbiAkX0NPT0tJRSBEYXRhCgkJaWYgKGlzX2FycmF5KCRfQ09PS0lFKSBBTkQgY291bnQoJF9DT09LSUUpID4gMCkKCQl7CgkJCWZvcmVhY2goJF9DT09LSUUgYXMgJGtleSA9PiAkdmFsKQoJCQl7CQkJICAKCQkJCSRfQ09PS0lFWyR0aGlzLT5fY2xlYW5faW5wdXRfa2V5cygka2V5KV0gPSAkdGhpcy0+X2NsZWFuX2lucHV0X2RhdGEoJHZhbCk7CgkJCX0JCgkJfQoJCQoJCWxvZ19tZXNzYWdlKCdkZWJ1ZycsICJHbG9iYWwgUE9TVCBhbmQgQ09PS0lFIGRhdGEgc2FuaXRpemVkIik7Cgl9CQoJCgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKioKCSAqIENsZWFuIEludHB1dCBEYXRhCgkgKgoJICogVGhpcyBpcyBhIGhlbHBlciBmdW5jdGlvbi4gSXQgZXNjYXBlcyBkYXRhIGFuZCAKCSAqIHN0YW5kYXJkaXplcyBuZXdsaW5lIGNoYXJhY3RlcnMgdG8gXG4KCSAqCgkgKiBAYWNjZXNzCXByaXZhdGUKCSAqIEBwYXJhbQlzdHJpbmcKCSAqIEByZXR1cm4Jc3RyaW5nCgkgKi8JCglmdW5jdGlvbiBfY2xlYW5faW5wdXRfZGF0YSgkc3RyKQoJewoJCWlmIChpc19hcnJheSgkc3RyKSkKCQl7CgkJCSRuZXdfYXJyYXkgPSBhcnJheSgpOwoJCQlmb3JlYWNoICgkc3RyIGFzICRrZXkgPT4gJHZhbCkKCQkJewoJCQkJJG5ld19hcnJheVskdGhpcy0+X2NsZWFuX2lucHV0X2tleXMoJGtleSldID0gJHRoaXMtPl9jbGVhbl9pbnB1dF9kYXRhKCR2YWwpOwoJCQl9CgkJCXJldHVybiAkbmV3X2FycmF5OwoJCX0KCQkKCQlpZiAoJHRoaXMtPnVzZV94c3NfY2xlYW4gPT09IFRSVUUpCgkJewoJCQkkc3RyID0gJHRoaXMtPnhzc19jbGVhbigkc3RyKTsKCQl9CgkJCgkJLy8gU3RhbmRhcmRpemUgbmV3bGluZXMKCQlyZXR1cm4gcHJlZ19yZXBsYWNlKCIvXDAxNVwwMTJ8XDAxNXxcMDEyLyIsICJcbiIsICRzdHIpOwoJfQoJCgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKioKCSAqIENsZWFuIEtleXMKCSAqCgkgKiBUaGlzIGlzIGEgaGVscGVyIGZ1bmN0aW9uLiBUbyBwcmV2ZW50IG1hbGljaW91cyB1c2VycyAKCSAqIGZyb20gdHJ5aW5nIHRvIGV4cGxvaXQga2V5cyB3ZSBtYWtlIHN1cmUgdGhhdCBrZXlzIGFyZSAKCSAqIG9ubHkgbmFtZWQgd2l0aCBhbHBoYS1udW1lcmljIHRleHQgYW5kIGEgZmV3IG90aGVyIGl0ZW1zLgoJICoKCSAqIEBhY2Nlc3MJcHJpdmF0ZQoJICogQHBhcmFtCXN0cmluZwoJICogQHJldHVybglzdHJpbmcKCSAqLwoJZnVuY3Rpb24gX2NsZWFuX2lucHV0X2tleXMoJHN0cikKCXsJCgkJIGlmICggISBwcmVnX21hdGNoKCIvXlthLXowLTk6X1wvLV0rJC9pIiwgJHN0cikpCgkJIHsgCgkJCWV4aXQoJ0Rpc2FsbG93ZWQgS2V5IENoYXJhY3RlcnM6ICcuJHN0cik7CgkJIH0KCQoJCWlmICggISBnZXRfbWFnaWNfcXVvdGVzX2dwYygpKQoJCXsKCQkgICByZXR1cm4gYWRkc2xhc2hlcygkc3RyKTsKCQl9CgkJCgkJcmV0dXJuICRzdHI7Cgl9CgkKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkKCS8qKgoJICogRmV0Y2ggYW4gaXRlbSBmcm9tIHRoZSBQT1NUIGFycmF5CgkgKgoJICogQGFjY2VzcwlwdWJsaWMKCSAqIEBwYXJhbQlzdHJpbmcKCSAqIEBwYXJhbQlib29sCgkgKiBAcmV0dXJuCXN0cmluZwoJICovCglmdW5jdGlvbiBwb3N0KCRpbmRleCA9ICcnLCAkeHNzX2NsZWFuID0gRkFMU0UpCgl7CQkKCQlpZiAoICEgaXNzZXQoJF9QT1NUWyRpbmRleF0pKQoJCXsKCQkJcmV0dXJuIEZBTFNFOwoJCX0KCgkJaWYgKCR4c3NfY2xlYW4gPT09IFRSVUUpCgkJewoJCQlpZiAoaXNfYXJyYXkoJF9QT1NUWyRpbmRleF0pKQoJCQl7CgkJCQlmb3JlYWNoKCRfUE9TVFskaW5kZXhdIGFzICRrZXkgPT4gJHZhbCkKCQkJCXsJCQkJCQoJCQkJCSRfUE9TVFskaW5kZXhdWyRrZXldID0gJHRoaXMtPnhzc19jbGVhbigkdmFsKTsKCQkJCX0KCQkJfQoJCQllbHNlCgkJCXsKCQkJCXJldHVybiAkdGhpcy0+eHNzX2NsZWFuKCRfUE9TVFskaW5kZXhdKTsKCQkJfQoJCX0KCgkJcmV0dXJuICRfUE9TVFskaW5kZXhdOwoJfQoJCgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKioKCSAqIEZldGNoIGFuIGl0ZW0gZnJvbSB0aGUgQ09PS0lFIGFycmF5CgkgKgoJICogQGFjY2VzcwlwdWJsaWMKCSAqIEBwYXJhbQlzdHJpbmcKCSAqIEBwYXJhbQlib29sCgkgKiBAcmV0dXJuCXN0cmluZwoJICovCglmdW5jdGlvbiBjb29raWUoJGluZGV4ID0gJycsICR4c3NfY2xlYW4gPSBGQUxTRSkKCXsKCQlpZiAoICEgaXNzZXQoJF9DT09LSUVbJGluZGV4XSkpCgkJewoJCQlyZXR1cm4gRkFMU0U7CgkJfQoKCQlpZiAoJHhzc19jbGVhbiA9PT0gVFJVRSkKCQl7CgkJCWlmIChpc19hcnJheSgkX0NPT0tJRVskaW5kZXhdKSkKCQkJewoJCQkJJGNvb2tpZSA9IGFycmF5KCk7CgkJCQlmb3JlYWNoKCRfQ09PS0lFWyRpbmRleF0gYXMgJGtleSA9PiAkdmFsKQoJCQkJewoJCQkJCSRjb29raWVbJGtleV0gPSAkdGhpcy0+eHNzX2NsZWFuKCR2YWwpOwoJCQkJfQoJCQoJCQkJcmV0dXJuICRjb29raWU7CgkJCX0KCQkJZWxzZQoJCQl7CgkJCQlyZXR1cm4gJHRoaXMtPnhzc19jbGVhbigkX0NPT0tJRVskaW5kZXhdKTsKCQkJfQoJCX0KCQllbHNlCgkJewoJCQlyZXR1cm4gJF9DT09LSUVbJGluZGV4XTsKCQl9Cgl9CgoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQoJLyoqCgkgKiBGZXRjaCBhbiBpdGVtIGZyb20gdGhlIFNFUlZFUiBhcnJheQoJICoKCSAqIEBhY2Nlc3MJcHVibGljCgkgKiBAcGFyYW0Jc3RyaW5nCgkgKiBAcGFyYW0JYm9vbAoJICogQHJldHVybglzdHJpbmcKCSAqLwoJZnVuY3Rpb24gc2VydmVyKCRpbmRleCA9ICcnLCAkeHNzX2NsZWFuID0gRkFMU0UpCgl7CQkKCQlpZiAoICEgaXNzZXQoJF9TRVJWRVJbJGluZGV4XSkpCgkJewoJCQlyZXR1cm4gRkFMU0U7CgkJfQoKCQlpZiAoJHhzc19jbGVhbiA9PT0gVFJVRSkKCQl7CgkJCXJldHVybiAkdGhpcy0+eHNzX2NsZWFuKCRfU0VSVkVSWyRpbmRleF0pOwoJCX0KCQkKCQlyZXR1cm4gJF9TRVJWRVJbJGluZGV4XTsKCX0KCQoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCQoJLyoqCgkgKiBGZXRjaCB0aGUgSVAgQWRkcmVzcwoJICoKCSAqIEBhY2Nlc3MJcHVibGljCgkgKiBAcmV0dXJuCXN0cmluZwoJICovCglmdW5jdGlvbiBpcF9hZGRyZXNzKCkKCXsKCQlpZiAoJHRoaXMtPmlwX2FkZHJlc3MgIT09IEZBTFNFKQoJCXsKCQkJcmV0dXJuICR0aGlzLT5pcF9hZGRyZXNzOwoJCX0KCQkKCQlpZiAoJHRoaXMtPnNlcnZlcignUkVNT1RFX0FERFInKSBBTkQgJHRoaXMtPnNlcnZlcignSFRUUF9DTElFTlRfSVAnKSkKCQl7CgkJCSAkdGhpcy0+aXBfYWRkcmVzcyA9ICRfU0VSVkVSWydIVFRQX0NMSUVOVF9JUCddOwoJCX0KCQllbHNlaWYgKCR0aGlzLT5zZXJ2ZXIoJ1JFTU9URV9BRERSJykpCgkJewoJCQkgJHRoaXMtPmlwX2FkZHJlc3MgPSAkX1NFUlZFUlsnUkVNT1RFX0FERFInXTsKCQl9CgkJZWxzZWlmICgkdGhpcy0+c2VydmVyKCdIVFRQX0NMSUVOVF9JUCcpKQoJCXsKCQkJICR0aGlzLT5pcF9hZGRyZXNzID0gJF9TRVJWRVJbJ0hUVFBfQ0xJRU5UX0lQJ107CgkJfQoJCWVsc2VpZiAoJHRoaXMtPnNlcnZlcignSFRUUF9YX0ZPUldBUkRFRF9GT1InKSkKCQl7CgkJCSAkdGhpcy0+aXBfYWRkcmVzcyA9ICRfU0VSVkVSWydIVFRQX1hfRk9SV0FSREVEX0ZPUiddOwoJCX0KCQkKCQlpZiAoJHRoaXMtPmlwX2FkZHJlc3MgPT09IEZBTFNFKQoJCXsKCQkJcmV0dXJuICR0aGlzLT5pcF9hZGRyZXNzID0gJzAuMC4wLjAnOwoJCX0KCQkKCQlpZiAoc3Ryc3RyKCR0aGlzLT5pcF9hZGRyZXNzLCAnLCcpKQoJCXsKCQkJJHggPSBleHBsb2RlKCcsJywgJHRoaXMtPmlwX2FkZHJlc3MpOwoJCQkkdGhpcy0+aXBfYWRkcmVzcyA9IGVuZCgkeCk7CgkJfQoJCQoJCWlmICggISAkdGhpcy0+dmFsaWRfaXAoJHRoaXMtPmlwX2FkZHJlc3MpKQoJCXsKCQkJJHRoaXMtPmlwX2FkZHJlc3MgPSAnMC4wLjAuMCc7CgkJfQoJCQkJCgkJcmV0dXJuICR0aGlzLT5pcF9hZGRyZXNzOwoJfQoJCgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKioKCSAqIFZhbGlkYXRlIElQIEFkZHJlc3MKCSAqCgkgKiBAYWNjZXNzCXB1YmxpYwoJICogQHBhcmFtCXN0cmluZwoJICogQHJldHVybglzdHJpbmcKCSAqLwoJZnVuY3Rpb24gdmFsaWRfaXAoJGlwKQoJewoJCXJldHVybiAoICEgcHJlZ19tYXRjaCggIi9eWzAtOV17MSwzfVwuWzAtOV17MSwzfVwuWzAtOV17MSwzfVwuWzAtOV17MSwzfSQvIiwgJGlwKSkgPyBGQUxTRSA6IFRSVUU7Cgl9CgkKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkKCS8qKgoJICogVXNlciBBZ2VudAoJICoKCSAqIEBhY2Nlc3MJcHVibGljCgkgKiBAcmV0dXJuCXN0cmluZwoJICovCglmdW5jdGlvbiB1c2VyX2FnZW50KCkKCXsKCQlpZiAoJHRoaXMtPnVzZXJfYWdlbnQgIT09IEZBTFNFKQoJCXsKCQkJcmV0dXJuICR0aGlzLT51c2VyX2FnZW50OwoJCX0KCQoJCSR0aGlzLT51c2VyX2FnZW50ID0gKCAhIGlzc2V0KCRfU0VSVkVSWydIVFRQX1VTRVJfQUdFTlQnXSkpID8gRkFMU0UgOiAkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ107CgkJCgkJcmV0dXJuICR0aGlzLT51c2VyX2FnZW50OwoJfQoJCgkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJCgkvKioKCSAqIFhTUyBDbGVhbgoJICoKCSAqIFNhbml0aXplcyBkYXRhIHNvIHRoYXQgQ3Jvc3MgU2l0ZSBTY3JpcHRpbmcgSGFja3MgY2FuIGJlCgkgKiBwcmV2ZW50ZWQuyiBUaGlzIGZ1bmN0aW9uIGRvZXMgYSBmYWlyIGFtb3VudCBvZiB3b3JrIGJ1dAoJICogaXQgaXMgZXh0cmVtZWx5IHRob3JvdWdoLCBkZXNpZ25lZCB0byBwcmV2ZW50IGV2ZW4gdGhlCgkgKiBtb3N0IG9ic2N1cmUgWFNTIGF0dGVtcHRzLsogTm90aGluZyBpcyBldmVyIDEwMCUgZm9vbHByb29mLAoJICogb2YgY291cnNlLCBidXQgSSBoYXZlbid0IGJlZW4gYWJsZSB0byBnZXQgYW55dGhpbmcgcGFzc2VkCgkgKiB0aGUgZmlsdGVyLgoJICoKCSAqIE5vdGU6IFRoaXMgZnVuY3Rpb24gc2hvdWxkIG9ubHkgYmUgdXNlZCB0byBkZWFsIHdpdGggZGF0YQoJICogdXBvbiBzdWJtaXNzaW9uLsogSXQncyBub3Qgc29tZXRoaW5nIHRoYXQgc2hvdWxkCgkgKiBiZSB1c2VkIGZvciBnZW5lcmFsIHJ1bnRpbWUgcHJvY2Vzc2luZy4KCSAqCgkgKiBUaGlzIGZ1bmN0aW9uIHdhcyBiYXNlZCBpbiBwYXJ0IG9uIHNvbWUgY29kZSBhbmQgaWRlYXMgSQoJICogZ290IGZyb20gQml0Zmx1eDogaHR0cDovL2Jsb2cuYml0Zmx1eC5jaC93aWtpL1hTU19QcmV2ZW50aW9uCgkgKgoJICogVG8gaGVscCBkZXZlbG9wIHRoaXMgc2NyaXB0IEkgdXNlZCB0aGlzIGdyZWF0IGxpc3Qgb2YKCSAqIHZ1bG5lcmFiaWxpdGllcyBhbG9uZyB3aXRoIGEgZmV3IG90aGVyIGhhY2tzIEkndmUgCgkgKiBoYXJ2ZXN0ZWQgZnJvbSBleGFtaW5pbmcgdnVsbmVyYWJpbGl0aWVzIGluIG90aGVyIHByb2dyYW1zOgoJICogaHR0cDovL2hhLmNrZXJzLm9yZy94c3MuaHRtbAoJICoKCSAqIEBhY2Nlc3MJcHVibGljCgkgKiBAcGFyYW0Jc3RyaW5nCgkgKiBAcmV0dXJuCXN0cmluZwoJICovCglmdW5jdGlvbiB4c3NfY2xlYW4oJHN0ciwgJGNoYXJzZXQgPSAnSVNPLTg4NTktMScpCgl7CQoJCS8qCgkJICogUmVtb3ZlIE51bGwgQ2hhcmFjdGVycwoJCSAqCgkJICogVGhpcyBwcmV2ZW50cyBzYW5kd2ljaGluZyBudWxsIGNoYXJhY3RlcnMKCQkgKiBiZXR3ZWVuIGFzY2lpIGNoYXJhY3RlcnMsIGxpa2UgSmF2YVwwc2NyaXB0LgoJCSAqCgkJICovCgkJJHN0ciA9IHByZWdfcmVwbGFjZSgnL1wwKy8nLCAnJywgJHN0cik7CgkJJHN0ciA9IHByZWdfcmVwbGFjZSgnLyhcXFxcMCkrLycsICcnLCAkc3RyKTsKCgkJLyoKCQkgKiBWYWxpZGF0ZSBzdGFuZGFyZCBjaGFyYWN0ZXIgZW50aXRlcwoJCSAqCgkJICogQWRkIGEgc2VtaWNvbG9uIGlmIG1pc3NpbmcuICBXZSBkbyB0aGlzIHRvIGVuYWJsZQoJCSAqIHRoZSBjb252ZXJzaW9uIG9mIGVudGl0aWVzIHRvIEFTQ0lJIGxhdGVyLgoJCSAqCgkJICovCgkJJHN0ciA9IHByZWdfcmVwbGFjZSgnIygmXCMqXHcrKVtceDAwLVx4MjBdKzsjdScsIlxcMTsiLCRzdHIpOwoJCQoJCS8qCgkJICogVmFsaWRhdGUgVVRGMTYgdHdvIGJ5dGUgZW5jb2RlaW5nICh4MDApIAoJCSAqCgkJICogSnVzdCBhcyBhYm92ZSwgYWRkcyBhIHNlbWljb2xvbiBpZiBtaXNzaW5nLgoJCSAqCgkJICovCgkJJHN0ciA9IHByZWdfcmVwbGFjZSgnIygmXCN4KikoWzAtOUEtRl0rKTsqI2l1JywiXFwxXFwyOyIsJHN0cik7CgoJCS8qCgkJICogVVJMIERlY29kZQoJCSAqCgkJICogSnVzdCBpbiBjYXNlIHN0dWZmIGxpa2UgdGhpcyBpcyBzdWJtaXR0ZWQ6CgkJICoKCQkgKiA8YSBocmVmPSJodHRwOi8vJTc3JTc3JTc3JTJFJTY3JTZGJTZGJTY3JTZDJTY1JTJFJTYzJTZGJTZEIj5Hb29nbGU8L2E+CgkJICoKCQkgKiBOb3RlOiBOb3JtYWxseSB1cmxkZWNvZGUoKSB3b3VsZCBiZSBlYXNpZXIgYnV0IGl0IHJlbW92ZXMgcGx1cyBzaWducwoJCSAqCgkJICovCQoJCSRzdHIgPSBwcmVnX3JlcGxhY2UoIi8ldTAoW2EtejAtOV17M30pL2kiLCAiJiN4XFwxOyIsICRzdHIpOwoJCSRzdHIgPSBwcmVnX3JlcGxhY2UoIi8lKFthLXowLTldezJ9KS9pIiwgIiYjeFxcMTsiLCAkc3RyKTsJCQoJCQkJCgkJLyoKCQkgKiBDb252ZXJ0IGNoYXJhY3RlciBlbnRpdGllcyB0byBBU0NJSSAKCQkgKgoJCSAqIFRoaXMgcGVybWl0cyBvdXIgdGVzdHMgYmVsb3cgdG8gd29yayByZWxpYWJseS4KCQkgKiBXZSBvbmx5IGNvbnZlcnQgZW50aXRpZXMgdGhhdCBhcmUgd2l0aGluIHRhZ3Mgc2luY2UKCQkgKiB0aGVzZSBhcmUgdGhlIG9uZXMgdGhhdCB3aWxsIHBvc2Ugc2VjdXJpdHkgcHJvYmxlbXMuCgkJICoKCQkgKi8KCQkgCgkJaWYgKHByZWdfbWF0Y2hfYWxsKCIvPCguKz8pPi9zaSIsICRzdHIsICRtYXRjaGVzKSkKCQl7CQkKCQkJZm9yICgkaSA9IDA7ICRpIDwgY291bnQoJG1hdGNoZXNbJzAnXSk7ICRpKyspCgkJCXsKCQkJCSRzdHIgPSBzdHJfcmVwbGFjZSgkbWF0Y2hlc1snMSddWyRpXSwgCgkJCQkJCQkJCSR0aGlzLT5faHRtbF9lbnRpdHlfZGVjb2RlKCRtYXRjaGVzWycxJ11bJGldLCAkY2hhcnNldCksIAoJCQkJCQkJCQkkc3RyKTsKCQkJfQoJCX0KCQoJCS8qCgkJICogQ29udmVydCBhbGwgdGFicyB0byBzcGFjZXMKCQkgKgoJCSAqIFRoaXMgcHJldmVudHMgc3RyaW5ncyBsaWtlIHRoaXM6IGphCXZhc2NyaXB0CgkJICogTm90ZTogd2UgZGVhbCB3aXRoIHNwYWNlcyBiZXR3ZWVuIGNoYXJhY3RlcnMgbGF0ZXIuCgkJICoKCQkgKi8JCQoJCSRzdHIgPSBwcmVnX3JlcGxhY2UoIiNcdCsjIiwgIiAiLCAkc3RyKTsKCQoJCS8qCgkJICogTWFrZXMgUEhQIHRhZ3Mgc2FmZQoJCSAqCgkJICogIE5vdGU6IFhNTCB0YWdzIGFyZSBpbmFkdmVydGVudGx5IHJlcGxhY2VkIHRvbzoKCQkgKgoJCSAqCTw/eG1sCgkJICoKCQkgKiBCdXQgaXQgZG9lc24ndCBzZWVtIHRvIHBvc2UgYSBwcm9ibGVtLgoJCSAqCgkJICovCQkKCQkkc3RyID0gc3RyX3JlcGxhY2UoYXJyYXkoJzw/cGhwJywgJzw/UEhQJywgJzw/JywgJz8+JyksICBhcnJheSgnJmx0Oz9waHAnLCAnJmx0Oz9QSFAnLCAnJmx0Oz8nLCAnPyZndDsnKSwgJHN0cik7CgkKCQkvKgoJCSAqIENvbXBhY3QgYW55IGV4cGxvZGVkIHdvcmRzCgkJICoKCQkgKiBUaGlzIGNvcnJlY3RzIHdvcmRzIGxpa2U6ICBqIGEgdiBhIHMgYyByIGkgcCB0CgkJICogVGhlc2Ugd29yZHMgYXJlIGNvbXBhY3RlZCBiYWNrIHRvIHRoZWlyIGNvcnJlY3Qgc3RhdGUuCgkJICoKCQkgKi8JCQoJCSR3b3JkcyA9IGFycmF5KCdqYXZhc2NyaXB0JywgJ3Zic2NyaXB0JywgJ3NjcmlwdCcsICdhcHBsZXQnLCAnYWxlcnQnLCAnZG9jdW1lbnQnLCAnd3JpdGUnLCAnY29va2llJywgJ3dpbmRvdycpOwoJCWZvcmVhY2ggKCR3b3JkcyBhcyAkd29yZCkKCQl7CgkJCSR0ZW1wID0gJyc7CgkJCWZvciAoJGkgPSAwOyAkaSA8IHN0cmxlbigkd29yZCk7ICRpKyspCgkJCXsKCQkJCSR0ZW1wIC49IHN1YnN0cigkd29yZCwgJGksIDEpLiJccyoiOwoJCQl9CgkJCQoJCQkkdGVtcCA9IHN1YnN0cigkdGVtcCwgMCwgLTMpOwoJCQkkc3RyID0gcHJlZ19yZXBsYWNlKCcjJy4kdGVtcC4nI3MnLCAkd29yZCwgJHN0cik7CgkJCSRzdHIgPSBwcmVnX3JlcGxhY2UoJyMnLnVjZmlyc3QoJHRlbXApLicjcycsIHVjZmlyc3QoJHdvcmQpLCAkc3RyKTsKCQl9CgkKCQkvKgoJCSAqIFJlbW92ZSBkaXNhbGxvd2VkIEphdmFzY3JpcHQgaW4gbGlua3Mgb3IgaW1nIHRhZ3MKCQkgKi8JCQoJCSAkc3RyID0gcHJlZ19yZXBsYWNlKCIjPGEuKz9ocmVmPS4qPyhhbGVydFwofGFsZXJ0JlwjNDA7fGphdmFzY3JpcHRcOnx3aW5kb3dcLnxkb2N1bWVudFwufFwuY29va2llfDxzY3JpcHR8PHhzcykuKj9cPi4qPzwvYT4jc2kiLCAiIiwgJHN0cik7CgkJICRzdHIgPSBwcmVnX3JlcGxhY2UoIiM8aW1nLis/c3JjPS4qPyhhbGVydFwofGFsZXJ0JlwjNDA7fGphdmFzY3JpcHRcOnx3aW5kb3dcLnxkb2N1bWVudFwufFwuY29va2llfDxzY3JpcHR8PHhzcykuKj9cPiNzaSIsICIiLCAkc3RyKTsKCQkgJHN0ciA9IHByZWdfcmVwbGFjZSgiIzwoc2NyaXB0fHhzcykuKj9cPiNzaSIsICIiLCAkc3RyKTsKCgkJLyoKCQkgKiBSZW1vdmUgSmF2YVNjcmlwdCBFdmVudCBIYW5kbGVycwoJCSAqCgkJICogTm90ZTogVGhpcyBjb2RlIGlzIGEgbGl0dGxlIGJsdW50LiAgSXQgcmVtb3ZlcwoJCSAqIHRoZSBldmVudCBoYW5kbGVyIGFuZCBhbnl0aGluZyB1cCB0byB0aGUgY2xvc2luZyA+LCAKCQkgKiBidXQgaXQncyB1bmxrZWx5IHRvIGJlIGEgcHJvYmxlbS4KCQkgKgoJCSAqLwkJCgkJICRzdHIgPSBwcmVnX3JlcGxhY2UoJyMoPFtePl0rLio/KShvbmJsdXJ8b25jaGFuZ2V8b25jbGlja3xvbmZvY3VzfG9ubG9hZHxvbm1vdXNlb3Zlcnxvbm1vdXNldXB8b25tb3VzZWRvd258b25zZWxlY3R8b25zdWJtaXR8b251bmxvYWR8b25rZXlwcmVzc3xvbmtleWRvd258b25rZXl1cHxvbnJlc2l6ZSlbXj5dKj4jaVUnLCJcXDE+Iiwkc3RyKTsKCQoJCS8qCgkJICogU2FuaXRpemUgbmF1Z2h0eSBIVE1MIGVsZW1lbnRzCgkJICoKCQkgKiBJZiBhIHRhZyBjb250YWluaW5nIGFueSBvZiB0aGUgd29yZHMgaW4gdGhlIGxpc3QgCgkJICogYmVsb3cgaXMgZm91bmQsIHRoZSB0YWcgZ2V0cyBjb252ZXJ0ZWQgdG8gZW50aXRpZXMuCgkJICoKCQkgKiBTbyB0aGlzOiA8Ymxpbms+CgkJICogQmVjb21lczogJmx0O2JsaW5rJmd0OwoJCSAqCgkJICovCQkKCQkkc3RyID0gcHJlZ19yZXBsYWNlKCcjPCgvKlxzKikoYWxlcnR8YXBwbGV0fGJhc2Vmb250fGJhc2V8YmVoYXZpb3J8Ymdzb3VuZHxibGlua3xib2R5fGVtYmVkfGV4cHJlc3Npb258Zm9ybXxmcmFtZXNldHxmcmFtZXxoZWFkfGh0bWx8aWxheWVyfGlmcmFtZXxpbnB1dHxsYXllcnxsaW5rfG1ldGF8b2JqZWN0fHBsYWludGV4dHxzdHlsZXxzY3JpcHR8dGV4dGFyZWF8dGl0bGV8eG1sfHhzcykoW14+XSopPiNpcycsICImbHQ7XFwxXFwyXFwzJmd0OyIsICRzdHIpOwoJCQoJCS8qCgkJICogU2FuaXRpemUgbmF1Z2h0eSBzY3JpcHRpbmcgZWxlbWVudHMKCQkgKgoJCSAqIFNpbWlsYXIgdG8gYWJvdmUsIG9ubHkgaW5zdGVhZCBvZiBsb29raW5nIGZvcgoJCSAqIHRhZ3MgaXQgbG9va3MgZm9yIFBIUCBhbmQgSmF2YVNjcmlwdCBjb21tYW5kcwoJCSAqIHRoYXQgYXJlIGRpc2FsbG93ZWQuICBSYXRoZXIgdGhhbiByZW1vdmluZyB0aGUKCQkgKiBjb2RlLCBpdCBzaW1wbHkgY29udmVydHMgdGhlIHBhcmVudGhlc2lzIHRvIGVudGl0aWVzCgkJICogcmVuZGVyaW5nIHRoZSBjb2RlIHVuZXhlY3V0YWJsZS4KCQkgKgoJCSAqIEZvciBleGFtcGxlOglldmFsKCdzb21lIGNvZGUnKQoJCSAqIEJlY29tZXM6CQlldmFsJiM0MDsnc29tZSBjb2RlJyYjNDE7CgkJICoKCQkgKi8KCQkkc3RyID0gcHJlZ19yZXBsYWNlKCcjKGFsZXJ0fGNtZHxwYXNzdGhydXxldmFsfGV4ZWN8c3lzdGVtfGZvcGVufGZzb2Nrb3BlbnxmaWxlfGZpbGVfZ2V0X2NvbnRlbnRzfHJlYWRmaWxlfHVubGluaykoXHMqKVwoKC4qPylcKSNzaScsICJcXDFcXDImIzQwO1xcMyYjNDE7IiwgJHN0cik7CgkJCQkJCQoJCS8qCgkJICogRmluYWwgY2xlYW4gdXAKCQkgKgoJCSAqIFRoaXMgYWRkcyBhIGJpdCBvZiBleHRyYSBwcmVjYXV0aW9uIGluIGNhc2UKCQkgKiBzb21ldGhpbmcgZ290IHRocm91Z2ggdGhlIGFib3ZlIGZpbHRlcnMKCQkgKgoJCSAqLwkKCQkkYmFkID0gYXJyYXkoCgkJCQkJCSdkb2N1bWVudC5jb29raWUnCT0+ICcnLAoJCQkJCQknZG9jdW1lbnQud3JpdGUnCT0+ICcnLAoJCQkJCQknd2luZG93LmxvY2F0aW9uJwk9PiAnJywKCQkJCQkJImphdmFzY3JpcHRccyo6Igk9PiAnJywKCQkJCQkJIlJlZGlyZWN0XHMrMzAyIgk9PiAnJywKCQkJCQkJJzwhLS0nCQkJCT0+ICcmbHQ7IS0tJywKCQkJCQkJJy0tPicJCQkJPT4gJy0tJmd0OycKCQkJCQkpOwoJCgkJZm9yZWFjaCAoJGJhZCBhcyAka2V5ID0+ICR2YWwpCgkJewoJCQkkc3RyID0gcHJlZ19yZXBsYWNlKCIjIi4ka2V5LiIjaSIsICR2YWwsICRzdHIpOyAgIAoJCX0KCQkKCQkJCQkJCgkJbG9nX21lc3NhZ2UoJ2RlYnVnJywgIlhTUyBGaWx0ZXJpbmcgY29tcGxldGVkIik7CgkJcmV0dXJuICRzdHI7Cgl9CgoJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgkvKioKCSAqIEhUTUwgRW50aXRpZXMgRGVjb2RlCgkgKgoJICogVGhpcyBmdW5jdGlvbiBpcyBhIHJlcGxhY2VtZW50IGZvciBodG1sX2VudGl0eV9kZWNvZGUoKQoJICoKCSAqIEluIHNvbWUgdmVyc2lvbnMgb2YgUEhQIHRoZSBuYXRpdmUgZnVuY3Rpb24gZG9lcyBub3Qgd29yawoJICogd2hlbiBVVEYtOCBpcyB0aGUgc3BlY2lmaWVkIGNoYXJhY3RlciBzZXQsIHNvIHRoaXMgZ2l2ZXMgdXMKCSAqIGEgd29yay1hcm91bmQuICBNb3JlIGluZm8gaGVyZToKCSAqIGh0dHA6Ly9idWdzLnBocC5uZXQvYnVnLnBocD9pZD0yNTY3MAoJICoKCSAqIEBhY2Nlc3MJcHJpdmF0ZQoJICogQHBhcmFtCXN0cmluZwoJICogQHBhcmFtCXN0cmluZwoJICogQHJldHVybglzdHJpbmcKCSAqLwoJLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoJLyogIFJlcGxhY2VtZW50IGZvciBodG1sX2VudGl0eV9kZWNvZGUoKQoJLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgkKCS8qCglOT1RFOiBodG1sX2VudGl0eV9kZWNvZGUoKSBoYXMgYSBidWcgaW4gc29tZSBQSFAgdmVyc2lvbnMgd2hlbiBVVEYtOCBpcyB0aGUgCgljaGFyYWN0ZXIgc2V0LCBhbmQgdGhlIFBIUCBkZXZlbG9wZXJzIHNhaWQgdGhleSB3ZXJlIG5vdCBiYWNrIHBvcnRpbmcgdGhlCglmaXggdG8gdmVyc2lvbnMgb3RoZXIgdGhhbiBQSFAgNS54LgoJKi8KCWZ1bmN0aW9uIF9odG1sX2VudGl0eV9kZWNvZGUoJHN0ciwgJGNoYXJzZXQ9J0lTTy04ODU5LTEnKSAKCXsKCQlpZiAoc3RyaXN0cigkc3RyLCAnJicpID09PSBGQUxTRSkgcmV0dXJuICRzdHI7CgkKCQkvLyBUaGUgcmVhc29uIHdlIGFyZSBub3QgdXNpbmcgaHRtbF9lbnRpdHlfZGVjb2RlKCkgYnkgaXRzZWxmIGlzIGJlY2F1c2UKCQkvLyB3aGlsZSBpdCBpcyBub3QgdGVjaG5pY2FsbHkgY29ycmVjdCB0byBsZWF2ZSBvdXQgdGhlIHNlbWljb2xvbgoJCS8vIGF0IHRoZSBlbmQgb2YgYW4gZW50aXR5IG1vc3QgYnJvd3NlcnMgd2lsbCBzdGlsbCBpbnRlcnByZXQgdGhlIGVudGl0eQoJCS8vIGNvcnJlY3RseS4gIGh0bWxfZW50aXR5X2RlY29kZSgpIGRvZXMgbm90IGNvbnZlcnQgZW50aXRpZXMgd2l0aG91dAoJCS8vIHNlbWljb2xvbnMsIHNvIHdlIGFyZSBsZWZ0IHdpdGggb3VyIG93biBsaXR0bGUgc29sdXRpb24gaGVyZS4gQnVtbWVyLgoJCgkJaWYgKGZ1bmN0aW9uX2V4aXN0cygnaHRtbF9lbnRpdHlfZGVjb2RlJykgJiYgKHN0cnRvbG93ZXIoJGNoYXJzZXQpICE9ICd1dGYtOCcgT1IgdmVyc2lvbl9jb21wYXJlKHBocHZlcnNpb24oKSwgJzUuMC4wJywgJz49JykpKQoJCXsKCQkJJHN0ciA9IGh0bWxfZW50aXR5X2RlY29kZSgkc3RyLCBFTlRfQ09NUEFULCAkY2hhcnNldCk7CgkJCSRzdHIgPSBwcmVnX3JlcGxhY2UoJ34mI3goWzAtOWEtZl17Miw1fSl+ZWknLCAnY2hyKGhleGRlYygiXFwxIikpJywgJHN0cik7CgkJCXJldHVybiBwcmVnX3JlcGxhY2UoJ34mIyhbMC05XXsyLDR9KX5lJywgJ2NocihcXDEpJywgJHN0cik7CgkJfQoJCQoJCS8vIE51bWVyaWMgRW50aXRpZXMKCQkkc3RyID0gcHJlZ19yZXBsYWNlKCd+JiN4KFswLTlhLWZdezIsNX0pO3swLDF9fmVpJywgJ2NocihoZXhkZWMoIlxcMSIpKScsICRzdHIpOwoJCSRzdHIgPSBwcmVnX3JlcGxhY2UoJ34mIyhbMC05XXsyLDR9KTt7MCwxfX5lJywgJ2NocihcXDEpJywgJHN0cik7CgkKCQkvLyBMaXRlcmFsIEVudGl0aWVzIC0gU2xpZ2h0bHkgc2xvdyBzbyB3ZSBkbyBhbm90aGVyIGNoZWNrCgkJaWYgKHN0cmlzdHIoJHN0ciwgJyYnKSA9PT0gRkFMU0UpCgkJewoJCQkkc3RyID0gc3RydHIoJHN0ciwgYXJyYXlfZmxpcChnZXRfaHRtbF90cmFuc2xhdGlvbl90YWJsZShIVE1MX0VOVElUSUVTKSkpOwoJCX0KCQkKCQlyZXR1cm4gJHN0cjsKCX0KCn0KLy8gRU5EIElucHV0IGNsYXNzCj8+