// https://p...content-available-to-author-only...j.com/problems/FR_07_03/
#include <iostream>
#include <vector>
#include <string>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <map>
#include <stack>
#include <iterator>
using namespace std;
typedef vector< unsigned int > VI;
typedef long long LL;
#define FOR(c, from, to) for(int c = from; c <= (to); ++c)
#define FORD(c, from, to) for(int c = from; c >= (to); – –x)
#define REP(c, n) for(int c = 0; c < (n); ++c)
#define VAR(v, n) typeof(n) v = (n)
#define ALL(c) (c).begin(), (c).end()
#define SIZE(c) ((int)(c).size())
#define PB push_back
#define ST first
#define ND second
static char AsciiSpecialCharacters[ 32 ] = { '!' , '"' , '#' , '$' , '%' , '&' , '*' , '\' ' ,'(' , ')' ,'+' , ',' , '-' , '.' , '/' , ':' ,';' , '<' , '=' , '>' , '?' , '@' , '[' , '\\ ' , ']' , '^' , '_' , '`' , '{' , '}' , '|' , '~' } ;
void print_msg( string function, string msg) ;
bool is_login_and_password_are_correct( string & , string & ) ;
bool is_lenght_correct( string & , string & ) ;
bool is_login_contain_illegal_char( string & login) ;
bool is_password_meet_criteria( string & ) ;
void print_result( vector< string> & arr) ;
void print_accounts( map< string, string> & account) ;
bool is_account_exist( map< string,string> & account, string & ) ;
string change_to_lower_case( string & ) ;
void create_account( map< string, string> & account, string & login, string & password) ;
bool is_password_correct( map< string,string> & accounts, string & login, string & password) ;
// void remove_space(string & loginAndPassword, string * login, string * password);
int main( ) {
int attemps;
map< string, string> account;
string loginAndPassword;
string login;
string password;
vector< string> result;
string command;
while ( cin >> command >> attemps) {
if ( command == "register" ) {
for ( int i= 0 ; i< attemps; i++ ) {
cin >> login >> password;
if ( is_login_and_password_are_correct( login, password) ) {
if ( ! is_account_exist( account, login) ) {
create_account( account, login, password) ;
result.PB ( "Zarejestrowano" ) ;
} else
{
result.PB ( "Login zajety" ) ;
}
} else {
result.PB ( "Blad" ) ;
}
}
}
else if ( command == "login" ) {
for ( int i= 0 ; i< attemps; i++ ) {
cin >> login >> password;
if ( is_account_exist( account, login) ) {
if ( is_password_correct( account, login, password) ) {
result.PB ( "Zalogowano" ) ;
} else
{
result.PB ( "Zle haslo" ) ;
}
} else
{
result.PB ( "Konto nie istnieje" ) ;
}
}
}
}
print_result( result) ;
return 0 ;
}
void print_msg( string function, string msg) {
cout << function << " " << msg << "\n " ;
}
void print_result( vector< string> & arr) {
FOR( i, 0 , SIZE( arr) - 1 ) {
cout << arr[ i] << "\n " ;
}
}
void print_accounts( map< string, string> & account) {
cout << "\n " ;
for ( auto it : account) {
cout << it.first << " " << it.second << "\n " ;
}
}
bool is_lenght_correct( string & login, string & password) {
if ( login.length ( ) < 3 || login.length ( ) > 12 ) {
return false ;
}
if ( password.length ( ) < 5 || password.length ( ) > 15 ) {
return false ;
}
return true ;
}
bool is_login_contain_illegal_char( string & login) {
char character;
FOR( i, 0 , login.length ( ) - 1 ) {
character = login[ i] ;
FOR( j, 0 , 32 ) {
if ( character == AsciiSpecialCharacters[ j] ) {
cout << "IS_LOGIN_CONTAIN_ILLEGAL_CHAR: yes its " << character << endl;
return false ;
}
}
}
return true ;
}
/* these criteria is:
- number
- special character
- character in upper case
- character in lower case
*/
bool is_password_meet_criteria( string & password) {
bool numberOccurence = false ;
bool specialCharacterOccurence = false ;
bool upperCaseCharacterOccurence = false ;
bool lowerCaseCharacterOccurence = false ;
FOR( i, 0 , password.length ( ) ) {
if ( numberOccurence == false ) FOR( n, 48 , 57 ) {
if ( ( char ) ( n) == password[ i] ) {
numberOccurence = true ;
}
}
if ( specialCharacterOccurence == false ) FOR( j, 0 , 32 ) {
if ( AsciiSpecialCharacters[ j] == password[ i] ) {
specialCharacterOccurence = true ;
}
}
if ( upperCaseCharacterOccurence == false ) FOR( c, 65 , 90 ) {
if ( ( char ) ( c) == password[ i] ) {
upperCaseCharacterOccurence = true ;
}
}
if ( lowerCaseCharacterOccurence == false ) FOR( c, 97 , 122 ) {
if ( ( char ) ( c) == password[ i] ) {
lowerCaseCharacterOccurence = true ;
}
}
}
if ( ! ( numberOccurence && specialCharacterOccurence && upperCaseCharacterOccurence && lowerCaseCharacterOccurence) ) {
return false ;
}
return true ;
}
bool is_login_and_password_are_correct( string & login, string & password) {
if ( ! is_lenght_correct( login, password) ) {
print_msg( "IS_LENGHT_CORRECT: " , "too short or too long" ) ;
return false ;
}
if ( ! is_login_contain_illegal_char( login) ) {
return false ;
}
if ( ! is_password_meet_criteria( password) ) {
print_msg( "IS_PASSWORD_MEET_CRITERIA:" , "no" ) ;
return false ;
}
return true ;
}
string change_to_lower_case( string & text) {
string lower_text = text;
FOR( i, 0 , text.length ( ) ) {
lower_text[ i] = tolower ( lower_text[ i] ) ;
}
return lower_text;
}
void create_account( map< string, string> & account, string & login, string & password) {
string lowerCaseLogin = change_to_lower_case( login) ; // changing login to lower case because it doenst make an odds
account[ lowerCaseLogin] = password;
}
bool is_account_exist( map< string,string> & accounts, string & login) {
string lowerCaseLogin = change_to_lower_case( login) ;
for ( auto it : accounts) {
if ( ( it.first .compare ( lowerCaseLogin) ) == 0 ) {
return true ;
}
}
return false ;
}
bool is_password_correct( map< string,string> & accounts, string & login, string & password) {
string lowerCaseLogin = change_to_lower_case( login) ;
for ( auto it : accounts) {
if ( ( it.first .compare ( lowerCaseLogin) ) == 0 ) {
if ( ( it.second .compare ( password) ) == 0 ) {
return true ;
}
}
}
return false ;
}
// void remove_space(string & loginAndPassword, string * login, string * password){
// string word = "";
// int startPosition = 0;
// for (auto c : loginAndPassword) {
// cout << "REMOVE_SPACE: " << c << endl;
// if (c == ' ') {
// * login = word;
// word = "";
// break;
// }
// else{
// word = word + c;
// }
// startPosition++;
// }
// word = "";
// for(int i=startPosition; i<loginAndPassword.length(); i++){
// word = word + loginAndPassword[i]; // probably there is problem
// }
// * password = word;
// }
Ly8gaHR0cHM6Ly9wLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5qLmNvbS9wcm9ibGVtcy9GUl8wN18wMy8KCiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGNjdHlwZT4KI2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDxtYXA+CiNpbmNsdWRlIDxzdGFjaz4KI2luY2x1ZGUgPGl0ZXJhdG9yPgoKCnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0eXBlZGVmIHZlY3Rvcjx1bnNpZ25lZCBpbnQ+IFZJOwp0eXBlZGVmIGxvbmcgbG9uZyBMTDsKI2RlZmluZSBGT1IoYywgZnJvbSwgdG8pIGZvcihpbnQgYyA9IGZyb207IGMgPD0gKHRvKTsgKytjKQojZGVmaW5lIEZPUkQoYywgZnJvbSwgdG8pIGZvcihpbnQgYyA9IGZyb207IGMgPj0gKHRvKTsg4oCTIOKAk3gpCiNkZWZpbmUgUkVQKGMsIG4pIGZvcihpbnQgYyA9IDA7IGMgPCAobik7ICsrYykKI2RlZmluZSBWQVIodiwgbikgdHlwZW9mKG4pIHYgPSAobikKI2RlZmluZSBBTEwoYykgKGMpLmJlZ2luKCksIChjKS5lbmQoKQojZGVmaW5lIFNJWkUoYykgKChpbnQpKGMpLnNpemUoKSkKI2RlZmluZSBQQiBwdXNoX2JhY2sKI2RlZmluZSBTVCBmaXJzdAojZGVmaW5lIE5EIHNlY29uZAoKc3RhdGljIGNoYXIgQXNjaWlTcGVjaWFsQ2hhcmFjdGVyc1szMl0gPSB7JyEnLCAnIicsICcjJywgJyQnLCAnJScsICcmJywgJyonLCAnXCcnICwnKCcsICcpJywnKycgLCAnLCcsICctJywgJy4nLCAnLycsICc6JyAsJzsnLCAnPCcsICc9JywgJz4nLCAnPycsICdAJyAsICdbJywgJ1xcJywgJ10nLCAnXicsICdfJywgJ2AnLCAneycsICd9JywgJ3wnLCAnfid9OwoKdm9pZCBwcmludF9tc2coc3RyaW5nIGZ1bmN0aW9uLCAgc3RyaW5nIG1zZyk7CmJvb2wgaXNfbG9naW5fYW5kX3Bhc3N3b3JkX2FyZV9jb3JyZWN0KHN0cmluZyAmLCBzdHJpbmcgJik7CmJvb2wgaXNfbGVuZ2h0X2NvcnJlY3Qoc3RyaW5nICYsIHN0cmluZyAgJik7CmJvb2wgaXNfbG9naW5fY29udGFpbl9pbGxlZ2FsX2NoYXIoc3RyaW5nICYgbG9naW4pOwpib29sIGlzX3Bhc3N3b3JkX21lZXRfY3JpdGVyaWEoc3RyaW5nICYpOwp2b2lkIHByaW50X3Jlc3VsdCh2ZWN0b3I8c3RyaW5nPiAmIGFycik7CnZvaWQgcHJpbnRfYWNjb3VudHMobWFwPHN0cmluZywgc3RyaW5nPiAmIGFjY291bnQpOwpib29sIGlzX2FjY291bnRfZXhpc3QobWFwPHN0cmluZyxzdHJpbmc+ICYgYWNjb3VudCwgc3RyaW5nICYpOwpzdHJpbmcgY2hhbmdlX3RvX2xvd2VyX2Nhc2Uoc3RyaW5nICYpOwp2b2lkIGNyZWF0ZV9hY2NvdW50KG1hcDxzdHJpbmcsIHN0cmluZz4gJiBhY2NvdW50LCBzdHJpbmcgJiBsb2dpbiwgc3RyaW5nICYgcGFzc3dvcmQpOwpib29sIGlzX3Bhc3N3b3JkX2NvcnJlY3QobWFwPHN0cmluZyxzdHJpbmc+ICYgYWNjb3VudHMsIHN0cmluZyAmIGxvZ2luLCBzdHJpbmcgJiBwYXNzd29yZCk7Ci8vIHZvaWQgcmVtb3ZlX3NwYWNlKHN0cmluZyAmIGxvZ2luQW5kUGFzc3dvcmQsIHN0cmluZyAqIGxvZ2luLCBzdHJpbmcgKiBwYXNzd29yZCk7CgppbnQgbWFpbigpewoKICAgIGludCBhdHRlbXBzOwogICAgbWFwPHN0cmluZywgc3RyaW5nPiBhY2NvdW50OwogICAgc3RyaW5nIGxvZ2luQW5kUGFzc3dvcmQ7CgogICAgc3RyaW5nIGxvZ2luOwogICAgc3RyaW5nIHBhc3N3b3JkOwogICAgdmVjdG9yPHN0cmluZz4gcmVzdWx0OwogICAgc3RyaW5nIGNvbW1hbmQ7CiAgIAogICAgCiAgICB3aGlsZShjaW4gPj4gY29tbWFuZCA+PiBhdHRlbXBzKXsKICAgICAgICBpZihjb21tYW5kID09ICJyZWdpc3RlciIpewogICAgICAgICAgICBmb3IoaW50IGk9MDsgaTxhdHRlbXBzOyBpKyspewogICAgICAgICAgICAgICAgY2luID4+IGxvZ2luID4+IHBhc3N3b3JkOwogICAgICAgICAgICAgICAgaWYoaXNfbG9naW5fYW5kX3Bhc3N3b3JkX2FyZV9jb3JyZWN0KGxvZ2luLCBwYXNzd29yZCkpewogICAgICAgICAgICAgICAgICAgIGlmKCFpc19hY2NvdW50X2V4aXN0KGFjY291bnQsIGxvZ2luKSl7CiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZV9hY2NvdW50KGFjY291bnQsIGxvZ2luLCBwYXNzd29yZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdC5QQigiWmFyZWplc3Ryb3dhbm8iKTsKICAgICAgICAgICAgICAgICAgICB9ZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LlBCKCJMb2dpbiB6YWpldHkiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LlBCKCJCbGFkIik7CiAgICAgICAgICAgICAgICB9ICAKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGlmKGNvbW1hbmQgPT0gImxvZ2luIil7CiAgICAgICAgICAgIGZvcihpbnQgaT0wOyBpPGF0dGVtcHM7IGkrKyl7CiAgICAgICAgICAgICAgICBjaW4gPj4gbG9naW4gPj4gcGFzc3dvcmQ7CiAgICAgICAgICAgICAgICBpZihpc19hY2NvdW50X2V4aXN0KGFjY291bnQsIGxvZ2luKSl7CiAgICAgICAgICAgICAgICAgICAgaWYoaXNfcGFzc3dvcmRfY29ycmVjdChhY2NvdW50LCBsb2dpbiwgcGFzc3dvcmQpKXsKICAgICAgICAgICAgICAgICAgICByZXN1bHQuUEIoIlphbG9nb3dhbm8iKTsKICAgICAgICAgICAgICAgICAgICB9ZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LlBCKCJabGUgaGFzbG8iKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9ZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdC5QQigiS29udG8gbmllIGlzdG5pZWplIik7CiAgICAgICAgICAgICAgICB9ICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgoKICAgCgoKICAgIHByaW50X3Jlc3VsdChyZXN1bHQpOwoKCgogICAgcmV0dXJuIDA7Cn0Kdm9pZCBwcmludF9tc2coc3RyaW5nIGZ1bmN0aW9uLCAgc3RyaW5nIG1zZyl7CiAgICBjb3V0IDw8IGZ1bmN0aW9uIDw8ICIgIiA8PCBtc2cgPDwgIlxuIjsKfQoKdm9pZCBwcmludF9yZXN1bHQodmVjdG9yPHN0cmluZz4gJiBhcnIpewogICAgRk9SKGksIDAsIFNJWkUoYXJyKS0xKXsKICAgICAgICBjb3V0IDw8IGFycltpXSA8PCAiXG4iOwogICAgfQp9CnZvaWQgcHJpbnRfYWNjb3VudHMobWFwPHN0cmluZywgc3RyaW5nPiAmIGFjY291bnQpewogICAgY291dCA8PCAiXG4iOwogICAgZm9yKGF1dG8gaXQgOiBhY2NvdW50KXsKICAgICAgICBjb3V0IDw8IGl0LmZpcnN0IDw8ICIgIiA8PCBpdC5zZWNvbmQgPDwgIlxuIjsKICAgIH0KfQpib29sIGlzX2xlbmdodF9jb3JyZWN0KHN0cmluZyAmIGxvZ2luLCBzdHJpbmcgJiBwYXNzd29yZCl7CgogICAgaWYobG9naW4ubGVuZ3RoKCk8MyB8fCBsb2dpbi5sZW5ndGgoKT4xMil7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYocGFzc3dvcmQubGVuZ3RoKCk8NSB8fCBwYXNzd29yZC5sZW5ndGgoKT4xNSl7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgCgogICAgcmV0dXJuIHRydWU7Cn0KYm9vbCBpc19sb2dpbl9jb250YWluX2lsbGVnYWxfY2hhcihzdHJpbmcgJiBsb2dpbil7CiAgICAKICAgIGNoYXIgY2hhcmFjdGVyOwogICAgRk9SKGksIDAsIGxvZ2luLmxlbmd0aCgpLTEpewogICAgICAgIGNoYXJhY3RlciA9IGxvZ2luW2ldOwogICAgICAgIAogICAgICAgIEZPUihqLCAwLCAzMil7CiAgICAgICAgICAgIGlmKGNoYXJhY3RlciA9PSBBc2NpaVNwZWNpYWxDaGFyYWN0ZXJzW2pdKXsKICAgICAgICAgICAgICAgIGNvdXQgPDwgIklTX0xPR0lOX0NPTlRBSU5fSUxMRUdBTF9DSEFSOiB5ZXMgaXRzICIgPDwgY2hhcmFjdGVyIDw8IGVuZGw7IAogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSAgICAgCiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQovKiB0aGVzZSBjcml0ZXJpYSBpczoKLSBudW1iZXIKLSBzcGVjaWFsIGNoYXJhY3RlcgotIGNoYXJhY3RlciBpbiB1cHBlciBjYXNlCi0gY2hhcmFjdGVyIGluIGxvd2VyIGNhc2UKKi8KYm9vbCBpc19wYXNzd29yZF9tZWV0X2NyaXRlcmlhKHN0cmluZyAmIHBhc3N3b3JkKXsKICAgIGJvb2wgbnVtYmVyT2NjdXJlbmNlID0gZmFsc2U7CiAgICBib29sIHNwZWNpYWxDaGFyYWN0ZXJPY2N1cmVuY2UgPSBmYWxzZTsKICAgIGJvb2wgdXBwZXJDYXNlQ2hhcmFjdGVyT2NjdXJlbmNlID0gZmFsc2U7CiAgICBib29sIGxvd2VyQ2FzZUNoYXJhY3Rlck9jY3VyZW5jZSA9IGZhbHNlOwoKICAgIEZPUihpLCAwLCBwYXNzd29yZC5sZW5ndGgoKSl7CiAgICAgICAgaWYobnVtYmVyT2NjdXJlbmNlID09IGZhbHNlKSBGT1IobiwgNDgsIDU3KXsKICAgICAgICAgICAgaWYoKGNoYXIpKG4pID09IHBhc3N3b3JkW2ldKXsKICAgICAgICAgICAgICAgIG51bWJlck9jY3VyZW5jZSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYoc3BlY2lhbENoYXJhY3Rlck9jY3VyZW5jZSA9PSBmYWxzZSkgRk9SKGosIDAsIDMyKXsKICAgICAgICAgICAgaWYoQXNjaWlTcGVjaWFsQ2hhcmFjdGVyc1tqXSA9PSBwYXNzd29yZFtpXSl7CiAgICAgICAgICAgICAgICBzcGVjaWFsQ2hhcmFjdGVyT2NjdXJlbmNlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZih1cHBlckNhc2VDaGFyYWN0ZXJPY2N1cmVuY2UgPT0gZmFsc2UpIEZPUihjLCA2NSwgOTApewogICAgICAgICAgICBpZigoY2hhcikoYykgPT0gcGFzc3dvcmRbaV0pewogICAgICAgICAgICAgICAgdXBwZXJDYXNlQ2hhcmFjdGVyT2NjdXJlbmNlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZihsb3dlckNhc2VDaGFyYWN0ZXJPY2N1cmVuY2UgPT0gZmFsc2UpIEZPUihjLCA5NywgMTIyKXsKICAgICAgICAgICAgaWYoKGNoYXIpKGMpID09IHBhc3N3b3JkW2ldKXsKICAgICAgICAgICAgICAgIGxvd2VyQ2FzZUNoYXJhY3Rlck9jY3VyZW5jZSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBpZighKG51bWJlck9jY3VyZW5jZSAmJiBzcGVjaWFsQ2hhcmFjdGVyT2NjdXJlbmNlICYmIHVwcGVyQ2FzZUNoYXJhY3Rlck9jY3VyZW5jZSAmJiBsb3dlckNhc2VDaGFyYWN0ZXJPY2N1cmVuY2UpKXsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQpib29sIGlzX2xvZ2luX2FuZF9wYXNzd29yZF9hcmVfY29ycmVjdChzdHJpbmcgJiBsb2dpbiwgc3RyaW5nICYgcGFzc3dvcmQpewogICAgaWYoIWlzX2xlbmdodF9jb3JyZWN0KGxvZ2luLCBwYXNzd29yZCkpeyAgIAogICAgICAgIHByaW50X21zZygiSVNfTEVOR0hUX0NPUlJFQ1Q6ICIsICJ0b28gc2hvcnQgb3IgdG9vIGxvbmciKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZighaXNfbG9naW5fY29udGFpbl9pbGxlZ2FsX2NoYXIobG9naW4pKXsgICAgICAgCiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYoIWlzX3Bhc3N3b3JkX21lZXRfY3JpdGVyaWEocGFzc3dvcmQpKXsKICAgICAgICBwcmludF9tc2coIklTX1BBU1NXT1JEX01FRVRfQ1JJVEVSSUE6IiwgIm5vIik7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgcmV0dXJuIHRydWU7Cn0Kc3RyaW5nIGNoYW5nZV90b19sb3dlcl9jYXNlKHN0cmluZyAmIHRleHQpewoKICAgIHN0cmluZyBsb3dlcl90ZXh0ID0gdGV4dDsKCiAgICBGT1IoaSwgMCwgdGV4dC5sZW5ndGgoKSl7CiAgICAgICAgbG93ZXJfdGV4dFtpXSA9ICB0b2xvd2VyKGxvd2VyX3RleHRbaV0pOwogICAgfSAgCiAgICByZXR1cm4gbG93ZXJfdGV4dDsKfQp2b2lkIGNyZWF0ZV9hY2NvdW50KG1hcDxzdHJpbmcsIHN0cmluZz4gJiBhY2NvdW50LCBzdHJpbmcgJiBsb2dpbiwgc3RyaW5nICYgcGFzc3dvcmQpewogICAgCiAgICBzdHJpbmcgbG93ZXJDYXNlTG9naW4gPSBjaGFuZ2VfdG9fbG93ZXJfY2FzZShsb2dpbik7IC8vIGNoYW5naW5nIGxvZ2luIHRvIGxvd2VyIGNhc2UgYmVjYXVzZSBpdCBkb2Vuc3QgbWFrZSBhbiBvZGRzCiAgICBhY2NvdW50W2xvd2VyQ2FzZUxvZ2luXSA9IHBhc3N3b3JkOwogICAgCn0KYm9vbCBpc19hY2NvdW50X2V4aXN0KG1hcDxzdHJpbmcsc3RyaW5nPiAmIGFjY291bnRzLCBzdHJpbmcgJiBsb2dpbil7CiAgICBzdHJpbmcgbG93ZXJDYXNlTG9naW4gPSBjaGFuZ2VfdG9fbG93ZXJfY2FzZShsb2dpbik7CiAgICBmb3IoYXV0byBpdCA6IGFjY291bnRzKXsKICAgICAgICBpZigoaXQuZmlyc3QuY29tcGFyZShsb3dlckNhc2VMb2dpbikpPT0wKXsKICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9Cgpib29sIGlzX3Bhc3N3b3JkX2NvcnJlY3QobWFwPHN0cmluZyxzdHJpbmc+ICYgYWNjb3VudHMsIHN0cmluZyAmIGxvZ2luLCBzdHJpbmcgJiBwYXNzd29yZCl7CiAgICBzdHJpbmcgbG93ZXJDYXNlTG9naW4gPSBjaGFuZ2VfdG9fbG93ZXJfY2FzZShsb2dpbik7CiAgICBmb3IoYXV0byBpdCA6IGFjY291bnRzKXsKICAgICAgICBpZigoaXQuZmlyc3QuY29tcGFyZShsb3dlckNhc2VMb2dpbikpPT0wKXsKICAgICAgICAgICAgaWYoKGl0LnNlY29uZC5jb21wYXJlKHBhc3N3b3JkKSk9PTApewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn0KLy8gdm9pZCByZW1vdmVfc3BhY2Uoc3RyaW5nICYgbG9naW5BbmRQYXNzd29yZCwgc3RyaW5nICogbG9naW4sIHN0cmluZyAqIHBhc3N3b3JkKXsKLy8gICAgIHN0cmluZyB3b3JkID0gIiI7IAovLyAgICAgaW50IHN0YXJ0UG9zaXRpb24gPSAwOyAKLy8gICAgIGZvciAoYXV0byBjIDogbG9naW5BbmRQYXNzd29yZCkgeyAKLy8gICAgICAgICBjb3V0IDw8ICJSRU1PVkVfU1BBQ0U6ICIgPDwgYyA8PCBlbmRsOwovLyAgICAgICAgIGlmIChjID09ICcgJykgeyAKLy8gICAgICAgICAgICAgKiBsb2dpbiA9IHdvcmQ7Ci8vICAgICAgICAgICAgIHdvcmQgPSAiIjsgCi8vICAgICAgICAgICAgIGJyZWFrOwovLyAgICAgICAgIH0gCi8vICAgICAgICAgZWxzZXsgCi8vICAgICAgICAgICAgd29yZCA9IHdvcmQgKyBjOyAKLy8gICAgICAgICB9IAovLyAgICAgICAgIHN0YXJ0UG9zaXRpb24rKzsKLy8gICAgIH0gIAovLyAgICAgd29yZCA9ICIiOwovLyAgICAgZm9yKGludCBpPXN0YXJ0UG9zaXRpb247IGk8bG9naW5BbmRQYXNzd29yZC5sZW5ndGgoKTsgaSsrKXsKICAgICAgICAKLy8gICAgICAgICB3b3JkID0gd29yZCArIGxvZ2luQW5kUGFzc3dvcmRbaV07IC8vIHByb2JhYmx5IHRoZXJlIGlzIHByb2JsZW0KLy8gICAgIH0KLy8gICAgICogcGFzc3dvcmQgPSB3b3JkOwovLyB9IAoKICAgIAoK