#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
class user {
protected :
string name, username, password, phone_number, email_address, role;
public :
user( string name, string username, string password, string phone_number, string email_address, string role)
: name( name) , username( username) , password( password) , phone_number( phone_number) , email_address( email_address) , role( role) { }
virtual void login( ) {
cout << "Logging in as " << role << endl;
}
void logout( ) {
cout << "Logging out...\n " ;
}
void change_password( string new_password) {
password = new_password;
cout << "Password changed successfully.\n " ;
}
} ;
class book {
private :
string title, author, genre;
int number_of_copies;
public :
book( string title, string author, string genre, int number_of_copies)
: title( title) , author( author) , genre( genre) , number_of_copies( number_of_copies) { }
bool is_available( ) {
return number_of_copies > 0 ;
}
void checkout( ) {
if ( is_available( ) ) {
number_of_copies-- ;
cout << "Checked out: " << title << endl;
} else {
cout << "No copies available for checkout.\n " ;
}
}
void check_in( ) {
number_of_copies++ ;
cout << "Checked in: " << title << endl;
}
string get_title( ) const {
return title;
}
} ;
class magazine {
private :
string title, publisher, publication_date;
bool available;
public :
magazine( string title, string publisher, string publication_date, bool available)
: title( title) , publisher( publisher) , publication_date( publication_date) , available( available) { }
bool is_available( ) {
return available;
}
void checkout( ) {
if ( is_available( ) ) {
available = false ;
cout << "Checked out: " << title << endl;
} else {
cout << "Magazine not available for checkout.\n " ;
}
}
void check_in( ) {
available = true ;
cout << "Checked in: " << title << endl;
}
string get_title( ) const {
return title;
}
} ;
class patron : public user {
private :
string library_card_number, address;
public :
patron( string name, string username, string password, string phone_number, string email_address, string library_card_number, string address)
: user( name, username, password, phone_number, email_address, "Patron" ) , library_card_number( library_card_number) , address( address) { }
void search_and_checkout_book( vector< book> & books, string title) {
for ( auto & b : books) {
if ( b.get_title ( ) == title) {
b.checkout ( ) ;
return ;
}
}
cout << "Book not available.\n " ;
}
void search_and_checkout_magazine( vector< magazine> & magazines, string title) {
for ( auto & m : magazines) {
if ( m.get_title ( ) == title) {
m.checkout ( ) ;
return ;
}
}
cout << "Magazine not available.\n " ;
}
} ;
class librarian : public user {
private :
string employee_id, department;
public :
librarian( string name, string username, string password, string phone_number, string email_address, string employee_id, string department)
: user( name, username, password, phone_number, email_address, "Librarian" ) , employee_id( employee_id) , department( department) { }
void add_book( vector< book> & books, string title, string author, string genre, int number_of_copies) {
books.emplace_back ( title, author, genre, number_of_copies) ;
cout << "Book added: " << title << endl;
}
void delete_book( vector< book> & books, string title) {
auto it = find_if( books.begin ( ) , books.end ( ) , [ & title] ( const book& b) { return b.get_title ( ) == title; } ) ;
if ( it ! = books.end ( ) ) {
books.erase ( it) ;
cout << "Book deleted: " << title << endl;
} else {
cout << "Book not found.\n " ;
}
}
void add_magazine( vector< magazine> & magazines, string title, string publisher, string publication_date, bool available) {
magazines.emplace_back ( title, publisher, publication_date, available) ;
cout << "Magazine added: " << title << endl;
}
void delete_magazine( vector< magazine> & magazines, string title) {
auto it = find_if( magazines.begin ( ) , magazines.end ( ) , [ & title] ( const magazine& m) { return m.get_title ( ) == title; } ) ;
if ( it ! = magazines.end ( ) ) {
magazines.erase ( it) ;
cout << "Magazine deleted: " << title << endl;
} else {
cout << "Magazine not found.\n " ;
}
}
} ;
int main( ) {
vector< book> books;
vector< magazine> magazines;
string name, username, password, phone_number, email_address, role;
cout << "Enter your name: " ;
getline( cin , name) ;
cout << "Enter your username: " ;
getline( cin , username) ;
cout << "Enter your password: " ;
getline( cin , password) ;
cout << "Enter your phone number: " ;
getline( cin , phone_number) ;
cout << "Enter your email address: " ;
getline( cin , email_address) ;
cout << "Enter your role (Patron or Librarian): " ;
getline( cin , role) ;
if ( role == "Patron" ) {
string library_card_number, address;
cout << "Enter your library card number: " ;
getline( cin , library_card_number) ;
cout << "Enter your address: " ;
getline( cin , address) ;
patron user( name, username, password, phone_number, email_address, library_card_number, address) ;
string search_title;
cout << "Enter the title of the book or magazine you're looking for: " ;
getline( cin , search_title) ;
user.search_and_checkout_book ( books, search_title) ;
user.search_and_checkout_magazine ( magazines, search_title) ;
} else if ( role == "Librarian" ) {
string employee_id, department;
cout << "Enter your employee ID: " ;
getline( cin , employee_id) ;
cout << "Enter your department: " ;
getline( cin , department) ;
librarian user( name, username, password, phone_number, email_address, employee_id, department) ;
int choice;
while ( true ) {
cout << "Choose an option:\n 1. Add Book\n 2. Delete Book\n 3. Add Magazine\n 4. Delete Magazine\n 5. Exit\n " ;
cin >> choice;
cin .ignore ( ) ;
if ( choice == 1 ) {
string title, author, genre;
int copies;
cout << "Enter book title: " ;
getline( cin , title) ;
cout << "Enter book author: " ;
getline( cin , author) ;
cout << "Enter book genre: " ;
getline( cin , genre) ;
cout << "Enter number of copies: " ;
cin >> copies;
cin .ignore ( ) ;
user.add_book ( books, title, author, genre, copies) ;
} else if ( choice == 2 ) {
string title;
cout << "Enter book title to delete: " ;
getline( cin , title) ;
user.delete_book ( books, title) ;
} else if ( choice == 3 ) {
string title, publisher, publication_date;
bool available;
cout << "Enter magazine title: " ;
getline( cin , title) ;
cout << "Enter publisher: " ;
getline( cin , publisher) ;
cout << "Enter publication date: " ;
getline( cin , publication_date) ;
cout << "Is it available (1 for Yes, 0 for No): " ;
cin >> available;
cin .ignore ( ) ;
user.add_magazine ( magazines, title, publisher, publication_date, available) ;
} else if ( choice == 4 ) {
string title;
cout << "Enter magazine title to delete: " ;
getline( cin , title) ;
user.delete_magazine ( magazines, title) ;
} else if ( choice == 5 ) {
break ;
} else {
cout << "Invalid choice. Try again.\n " ;
}
}
} else {
cout << "Invalid role! Please enter either 'Patron' or 'Librarian'.\n " ;
}
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmNsYXNzIHVzZXIgewpwcm90ZWN0ZWQ6CiAgICBzdHJpbmcgbmFtZSwgdXNlcm5hbWUsIHBhc3N3b3JkLCBwaG9uZV9udW1iZXIsIGVtYWlsX2FkZHJlc3MsIHJvbGU7CgpwdWJsaWM6CiAgICB1c2VyKHN0cmluZyBuYW1lLCBzdHJpbmcgdXNlcm5hbWUsIHN0cmluZyBwYXNzd29yZCwgc3RyaW5nIHBob25lX251bWJlciwgc3RyaW5nIGVtYWlsX2FkZHJlc3MsIHN0cmluZyByb2xlKQogICAgICAgIDogbmFtZShuYW1lKSwgdXNlcm5hbWUodXNlcm5hbWUpLCBwYXNzd29yZChwYXNzd29yZCksIHBob25lX251bWJlcihwaG9uZV9udW1iZXIpLCBlbWFpbF9hZGRyZXNzKGVtYWlsX2FkZHJlc3MpLCByb2xlKHJvbGUpIHt9CgogICAgdmlydHVhbCB2b2lkIGxvZ2luKCkgewogICAgICAgIGNvdXQgPDwgIkxvZ2dpbmcgaW4gYXMgIiA8PCByb2xlIDw8IGVuZGw7CiAgICB9CgogICAgdm9pZCBsb2dvdXQoKSB7CiAgICAgICAgY291dCA8PCAiTG9nZ2luZyBvdXQuLi5cbiI7CiAgICB9CgogICAgdm9pZCBjaGFuZ2VfcGFzc3dvcmQoc3RyaW5nIG5ld19wYXNzd29yZCkgewogICAgICAgIHBhc3N3b3JkID0gbmV3X3Bhc3N3b3JkOwogICAgICAgIGNvdXQgPDwgIlBhc3N3b3JkIGNoYW5nZWQgc3VjY2Vzc2Z1bGx5LlxuIjsKICAgIH0KfTsKCmNsYXNzIGJvb2sgewpwcml2YXRlOgogICAgc3RyaW5nIHRpdGxlLCBhdXRob3IsIGdlbnJlOwogICAgaW50IG51bWJlcl9vZl9jb3BpZXM7CgpwdWJsaWM6CiAgICBib29rKHN0cmluZyB0aXRsZSwgc3RyaW5nIGF1dGhvciwgc3RyaW5nIGdlbnJlLCBpbnQgbnVtYmVyX29mX2NvcGllcykKICAgICAgICA6IHRpdGxlKHRpdGxlKSwgYXV0aG9yKGF1dGhvciksIGdlbnJlKGdlbnJlKSwgbnVtYmVyX29mX2NvcGllcyhudW1iZXJfb2ZfY29waWVzKSB7fQoKICAgIGJvb2wgaXNfYXZhaWxhYmxlKCkgewogICAgICAgIHJldHVybiBudW1iZXJfb2ZfY29waWVzID4gMDsKICAgIH0KCiAgICB2b2lkIGNoZWNrb3V0KCkgewogICAgICAgIGlmIChpc19hdmFpbGFibGUoKSkgewogICAgICAgICAgICBudW1iZXJfb2ZfY29waWVzLS07CiAgICAgICAgICAgIGNvdXQgPDwgIkNoZWNrZWQgb3V0OiAiIDw8IHRpdGxlIDw8IGVuZGw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY291dCA8PCAiTm8gY29waWVzIGF2YWlsYWJsZSBmb3IgY2hlY2tvdXQuXG4iOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGNoZWNrX2luKCkgewogICAgICAgIG51bWJlcl9vZl9jb3BpZXMrKzsKICAgICAgICBjb3V0IDw8ICJDaGVja2VkIGluOiAiIDw8IHRpdGxlIDw8IGVuZGw7CiAgICB9CgogICAgc3RyaW5nIGdldF90aXRsZSgpIGNvbnN0IHsKICAgICAgICByZXR1cm4gdGl0bGU7CiAgICB9Cn07CgpjbGFzcyBtYWdhemluZSB7CnByaXZhdGU6CiAgICBzdHJpbmcgdGl0bGUsIHB1Ymxpc2hlciwgcHVibGljYXRpb25fZGF0ZTsKICAgIGJvb2wgYXZhaWxhYmxlOwoKcHVibGljOgogICAgbWFnYXppbmUoc3RyaW5nIHRpdGxlLCBzdHJpbmcgcHVibGlzaGVyLCBzdHJpbmcgcHVibGljYXRpb25fZGF0ZSwgYm9vbCBhdmFpbGFibGUpCiAgICAgICAgOiB0aXRsZSh0aXRsZSksIHB1Ymxpc2hlcihwdWJsaXNoZXIpLCBwdWJsaWNhdGlvbl9kYXRlKHB1YmxpY2F0aW9uX2RhdGUpLCBhdmFpbGFibGUoYXZhaWxhYmxlKSB7fQoKICAgIGJvb2wgaXNfYXZhaWxhYmxlKCkgewogICAgICAgIHJldHVybiBhdmFpbGFibGU7CiAgICB9CgogICAgdm9pZCBjaGVja291dCgpIHsKICAgICAgICBpZiAoaXNfYXZhaWxhYmxlKCkpIHsKICAgICAgICAgICAgYXZhaWxhYmxlID0gZmFsc2U7CiAgICAgICAgICAgIGNvdXQgPDwgIkNoZWNrZWQgb3V0OiAiIDw8IHRpdGxlIDw8IGVuZGw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY291dCA8PCAiTWFnYXppbmUgbm90IGF2YWlsYWJsZSBmb3IgY2hlY2tvdXQuXG4iOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGNoZWNrX2luKCkgewogICAgICAgIGF2YWlsYWJsZSA9IHRydWU7CiAgICAgICAgY291dCA8PCAiQ2hlY2tlZCBpbjogIiA8PCB0aXRsZSA8PCBlbmRsOwogICAgfQoKICAgIHN0cmluZyBnZXRfdGl0bGUoKSBjb25zdCB7CiAgICAgICAgcmV0dXJuIHRpdGxlOwogICAgfQp9OwoKY2xhc3MgcGF0cm9uIDogcHVibGljIHVzZXIgewpwcml2YXRlOgogICAgc3RyaW5nIGxpYnJhcnlfY2FyZF9udW1iZXIsIGFkZHJlc3M7CgpwdWJsaWM6CiAgICBwYXRyb24oc3RyaW5nIG5hbWUsIHN0cmluZyB1c2VybmFtZSwgc3RyaW5nIHBhc3N3b3JkLCBzdHJpbmcgcGhvbmVfbnVtYmVyLCBzdHJpbmcgZW1haWxfYWRkcmVzcywgc3RyaW5nIGxpYnJhcnlfY2FyZF9udW1iZXIsIHN0cmluZyBhZGRyZXNzKQogICAgICAgIDogdXNlcihuYW1lLCB1c2VybmFtZSwgcGFzc3dvcmQsIHBob25lX251bWJlciwgZW1haWxfYWRkcmVzcywgIlBhdHJvbiIpLCBsaWJyYXJ5X2NhcmRfbnVtYmVyKGxpYnJhcnlfY2FyZF9udW1iZXIpLCBhZGRyZXNzKGFkZHJlc3MpIHt9CgogICAgdm9pZCBzZWFyY2hfYW5kX2NoZWNrb3V0X2Jvb2sodmVjdG9yPGJvb2s+JiBib29rcywgc3RyaW5nIHRpdGxlKSB7CiAgICAgICAgZm9yIChhdXRvJiBiIDogYm9va3MpIHsKICAgICAgICAgICAgaWYgKGIuZ2V0X3RpdGxlKCkgPT0gdGl0bGUpIHsKICAgICAgICAgICAgICAgIGIuY2hlY2tvdXQoKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjb3V0IDw8ICJCb29rIG5vdCBhdmFpbGFibGUuXG4iOwogICAgfQoKICAgIHZvaWQgc2VhcmNoX2FuZF9jaGVja291dF9tYWdhemluZSh2ZWN0b3I8bWFnYXppbmU+JiBtYWdhemluZXMsIHN0cmluZyB0aXRsZSkgewogICAgICAgIGZvciAoYXV0byYgbSA6IG1hZ2F6aW5lcykgewogICAgICAgICAgICBpZiAobS5nZXRfdGl0bGUoKSA9PSB0aXRsZSkgewogICAgICAgICAgICAgICAgbS5jaGVja291dCgpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvdXQgPDwgIk1hZ2F6aW5lIG5vdCBhdmFpbGFibGUuXG4iOwogICAgfQp9OwoKY2xhc3MgbGlicmFyaWFuIDogcHVibGljIHVzZXIgewpwcml2YXRlOgogICAgc3RyaW5nIGVtcGxveWVlX2lkLCBkZXBhcnRtZW50OwoKcHVibGljOgogICAgbGlicmFyaWFuKHN0cmluZyBuYW1lLCBzdHJpbmcgdXNlcm5hbWUsIHN0cmluZyBwYXNzd29yZCwgc3RyaW5nIHBob25lX251bWJlciwgc3RyaW5nIGVtYWlsX2FkZHJlc3MsIHN0cmluZyBlbXBsb3llZV9pZCwgc3RyaW5nIGRlcGFydG1lbnQpCiAgICAgICAgOiB1c2VyKG5hbWUsIHVzZXJuYW1lLCBwYXNzd29yZCwgcGhvbmVfbnVtYmVyLCBlbWFpbF9hZGRyZXNzLCAiTGlicmFyaWFuIiksIGVtcGxveWVlX2lkKGVtcGxveWVlX2lkKSwgZGVwYXJ0bWVudChkZXBhcnRtZW50KSB7fQoKICAgIHZvaWQgYWRkX2Jvb2sodmVjdG9yPGJvb2s+JiBib29rcywgc3RyaW5nIHRpdGxlLCBzdHJpbmcgYXV0aG9yLCBzdHJpbmcgZ2VucmUsIGludCBudW1iZXJfb2ZfY29waWVzKSB7CiAgICAgICAgYm9va3MuZW1wbGFjZV9iYWNrKHRpdGxlLCBhdXRob3IsIGdlbnJlLCBudW1iZXJfb2ZfY29waWVzKTsKICAgICAgICBjb3V0IDw8ICJCb29rIGFkZGVkOiAiIDw8IHRpdGxlIDw8IGVuZGw7CiAgICB9CgogICAgdm9pZCBkZWxldGVfYm9vayh2ZWN0b3I8Ym9vaz4mIGJvb2tzLCBzdHJpbmcgdGl0bGUpIHsKICAgICAgICBhdXRvIGl0ID0gZmluZF9pZihib29rcy5iZWdpbigpLCBib29rcy5lbmQoKSwgWyZ0aXRsZV0oY29uc3QgYm9vayYgYikgeyByZXR1cm4gYi5nZXRfdGl0bGUoKSA9PSB0aXRsZTsgfSk7CiAgICAgICAgaWYgKGl0ICE9IGJvb2tzLmVuZCgpKSB7CiAgICAgICAgICAgIGJvb2tzLmVyYXNlKGl0KTsKICAgICAgICAgICAgY291dCA8PCAiQm9vayBkZWxldGVkOiAiIDw8IHRpdGxlIDw8IGVuZGw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY291dCA8PCAiQm9vayBub3QgZm91bmQuXG4iOwogICAgICAgIH0KICAgIH0KCiAgICB2b2lkIGFkZF9tYWdhemluZSh2ZWN0b3I8bWFnYXppbmU+JiBtYWdhemluZXMsIHN0cmluZyB0aXRsZSwgc3RyaW5nIHB1Ymxpc2hlciwgc3RyaW5nIHB1YmxpY2F0aW9uX2RhdGUsIGJvb2wgYXZhaWxhYmxlKSB7CiAgICAgICAgbWFnYXppbmVzLmVtcGxhY2VfYmFjayh0aXRsZSwgcHVibGlzaGVyLCBwdWJsaWNhdGlvbl9kYXRlLCBhdmFpbGFibGUpOwogICAgICAgIGNvdXQgPDwgIk1hZ2F6aW5lIGFkZGVkOiAiIDw8IHRpdGxlIDw8IGVuZGw7CiAgICB9CgogICAgdm9pZCBkZWxldGVfbWFnYXppbmUodmVjdG9yPG1hZ2F6aW5lPiYgbWFnYXppbmVzLCBzdHJpbmcgdGl0bGUpIHsKICAgICAgICBhdXRvIGl0ID0gZmluZF9pZihtYWdhemluZXMuYmVnaW4oKSwgbWFnYXppbmVzLmVuZCgpLCBbJnRpdGxlXShjb25zdCBtYWdhemluZSYgbSkgeyByZXR1cm4gbS5nZXRfdGl0bGUoKSA9PSB0aXRsZTsgfSk7CiAgICAgICAgaWYgKGl0ICE9IG1hZ2F6aW5lcy5lbmQoKSkgewogICAgICAgICAgICBtYWdhemluZXMuZXJhc2UoaXQpOwogICAgICAgICAgICBjb3V0IDw8ICJNYWdhemluZSBkZWxldGVkOiAiIDw8IHRpdGxlIDw8IGVuZGw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY291dCA8PCAiTWFnYXppbmUgbm90IGZvdW5kLlxuIjsKICAgICAgICB9CiAgICB9Cn07CgppbnQgbWFpbigpIHsKICAgIHZlY3Rvcjxib29rPiBib29rczsKICAgIHZlY3RvcjxtYWdhemluZT4gbWFnYXppbmVzOwoKICAgIHN0cmluZyBuYW1lLCB1c2VybmFtZSwgcGFzc3dvcmQsIHBob25lX251bWJlciwgZW1haWxfYWRkcmVzcywgcm9sZTsKICAgIGNvdXQgPDwgIkVudGVyIHlvdXIgbmFtZTogIjsKICAgIGdldGxpbmUoY2luLCBuYW1lKTsKICAgIGNvdXQgPDwgIkVudGVyIHlvdXIgdXNlcm5hbWU6ICI7CiAgICBnZXRsaW5lKGNpbiwgdXNlcm5hbWUpOwogICAgY291dCA8PCAiRW50ZXIgeW91ciBwYXNzd29yZDogIjsKICAgIGdldGxpbmUoY2luLCBwYXNzd29yZCk7CiAgICBjb3V0IDw8ICJFbnRlciB5b3VyIHBob25lIG51bWJlcjogIjsKICAgIGdldGxpbmUoY2luLCBwaG9uZV9udW1iZXIpOwogICAgY291dCA8PCAiRW50ZXIgeW91ciBlbWFpbCBhZGRyZXNzOiAiOwogICAgZ2V0bGluZShjaW4sIGVtYWlsX2FkZHJlc3MpOwogICAgY291dCA8PCAiRW50ZXIgeW91ciByb2xlIChQYXRyb24gb3IgTGlicmFyaWFuKTogIjsKICAgIGdldGxpbmUoY2luLCByb2xlKTsKCiAgICBpZiAocm9sZSA9PSAiUGF0cm9uIikgewogICAgICAgIHN0cmluZyBsaWJyYXJ5X2NhcmRfbnVtYmVyLCBhZGRyZXNzOwogICAgICAgIGNvdXQgPDwgIkVudGVyIHlvdXIgbGlicmFyeSBjYXJkIG51bWJlcjogIjsKICAgICAgICBnZXRsaW5lKGNpbiwgbGlicmFyeV9jYXJkX251bWJlcik7CiAgICAgICAgY291dCA8PCAiRW50ZXIgeW91ciBhZGRyZXNzOiAiOwogICAgICAgIGdldGxpbmUoY2luLCBhZGRyZXNzKTsKCiAgICAgICAgcGF0cm9uIHVzZXIobmFtZSwgdXNlcm5hbWUsIHBhc3N3b3JkLCBwaG9uZV9udW1iZXIsIGVtYWlsX2FkZHJlc3MsIGxpYnJhcnlfY2FyZF9udW1iZXIsIGFkZHJlc3MpOwoKICAgICAgICBzdHJpbmcgc2VhcmNoX3RpdGxlOwogICAgICAgIGNvdXQgPDwgIkVudGVyIHRoZSB0aXRsZSBvZiB0aGUgYm9vayBvciBtYWdhemluZSB5b3UncmUgbG9va2luZyBmb3I6ICI7CiAgICAgICAgZ2V0bGluZShjaW4sIHNlYXJjaF90aXRsZSk7CgogICAgICAgIHVzZXIuc2VhcmNoX2FuZF9jaGVja291dF9ib29rKGJvb2tzLCBzZWFyY2hfdGl0bGUpOwogICAgICAgIHVzZXIuc2VhcmNoX2FuZF9jaGVja291dF9tYWdhemluZShtYWdhemluZXMsIHNlYXJjaF90aXRsZSk7CgogICAgfSBlbHNlIGlmIChyb2xlID09ICJMaWJyYXJpYW4iKSB7CiAgICAgICAgc3RyaW5nIGVtcGxveWVlX2lkLCBkZXBhcnRtZW50OwogICAgICAgIGNvdXQgPDwgIkVudGVyIHlvdXIgZW1wbG95ZWUgSUQ6ICI7CiAgICAgICAgZ2V0bGluZShjaW4sIGVtcGxveWVlX2lkKTsKICAgICAgICBjb3V0IDw8ICJFbnRlciB5b3VyIGRlcGFydG1lbnQ6ICI7CiAgICAgICAgZ2V0bGluZShjaW4sIGRlcGFydG1lbnQpOwoKICAgICAgICBsaWJyYXJpYW4gdXNlcihuYW1lLCB1c2VybmFtZSwgcGFzc3dvcmQsIHBob25lX251bWJlciwgZW1haWxfYWRkcmVzcywgZW1wbG95ZWVfaWQsIGRlcGFydG1lbnQpOwoKICAgICAgICBpbnQgY2hvaWNlOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIGNvdXQgPDwgIkNob29zZSBhbiBvcHRpb246XG4xLiBBZGQgQm9va1xuMi4gRGVsZXRlIEJvb2tcbjMuIEFkZCBNYWdhemluZVxuNC4gRGVsZXRlIE1hZ2F6aW5lXG41LiBFeGl0XG4iOwogICAgICAgICAgICBjaW4gPj4gY2hvaWNlOwogICAgICAgICAgICBjaW4uaWdub3JlKCk7CgogICAgICAgICAgICBpZiAoY2hvaWNlID09IDEpIHsKICAgICAgICAgICAgICAgIHN0cmluZyB0aXRsZSwgYXV0aG9yLCBnZW5yZTsKICAgICAgICAgICAgICAgIGludCBjb3BpZXM7CiAgICAgICAgICAgICAgICBjb3V0IDw8ICJFbnRlciBib29rIHRpdGxlOiAiOwogICAgICAgICAgICAgICAgZ2V0bGluZShjaW4sIHRpdGxlKTsKICAgICAgICAgICAgICAgIGNvdXQgPDwgIkVudGVyIGJvb2sgYXV0aG9yOiAiOwogICAgICAgICAgICAgICAgZ2V0bGluZShjaW4sIGF1dGhvcik7CiAgICAgICAgICAgICAgICBjb3V0IDw8ICJFbnRlciBib29rIGdlbnJlOiAiOwogICAgICAgICAgICAgICAgZ2V0bGluZShjaW4sIGdlbnJlKTsKICAgICAgICAgICAgICAgIGNvdXQgPDwgIkVudGVyIG51bWJlciBvZiBjb3BpZXM6ICI7CiAgICAgICAgICAgICAgICBjaW4gPj4gY29waWVzOwogICAgICAgICAgICAgICAgY2luLmlnbm9yZSgpOwogICAgICAgICAgICAgICAgdXNlci5hZGRfYm9vayhib29rcywgdGl0bGUsIGF1dGhvciwgZ2VucmUsIGNvcGllcyk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hvaWNlID09IDIpIHsKICAgICAgICAgICAgICAgIHN0cmluZyB0aXRsZTsKICAgICAgICAgICAgICAgIGNvdXQgPDwgIkVudGVyIGJvb2sgdGl0bGUgdG8gZGVsZXRlOiAiOwogICAgICAgICAgICAgICAgZ2V0bGluZShjaW4sIHRpdGxlKTsKICAgICAgICAgICAgICAgIHVzZXIuZGVsZXRlX2Jvb2soYm9va3MsIHRpdGxlKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChjaG9pY2UgPT0gMykgewogICAgICAgICAgICAgICAgc3RyaW5nIHRpdGxlLCBwdWJsaXNoZXIsIHB1YmxpY2F0aW9uX2RhdGU7CiAgICAgICAgICAgICAgICBib29sIGF2YWlsYWJsZTsKICAgICAgICAgICAgICAgIGNvdXQgPDwgIkVudGVyIG1hZ2F6aW5lIHRpdGxlOiAiOwogICAgICAgICAgICAgICAgZ2V0bGluZShjaW4sIHRpdGxlKTsKICAgICAgICAgICAgICAgIGNvdXQgPDwgIkVudGVyIHB1Ymxpc2hlcjogIjsKICAgICAgICAgICAgICAgIGdldGxpbmUoY2luLCBwdWJsaXNoZXIpOwogICAgICAgICAgICAgICAgY291dCA8PCAiRW50ZXIgcHVibGljYXRpb24gZGF0ZTogIjsKICAgICAgICAgICAgICAgIGdldGxpbmUoY2luLCBwdWJsaWNhdGlvbl9kYXRlKTsKICAgICAgICAgICAgICAgIGNvdXQgPDwgIklzIGl0IGF2YWlsYWJsZSAoMSBmb3IgWWVzLCAwIGZvciBObyk6ICI7CiAgICAgICAgICAgICAgICBjaW4gPj4gYXZhaWxhYmxlOwogICAgICAgICAgICAgICAgY2luLmlnbm9yZSgpOwogICAgICAgICAgICAgICAgdXNlci5hZGRfbWFnYXppbmUobWFnYXppbmVzLCB0aXRsZSwgcHVibGlzaGVyLCBwdWJsaWNhdGlvbl9kYXRlLCBhdmFpbGFibGUpOwogICAgICAgICAgICB9IGVsc2UgaWYgKGNob2ljZSA9PSA0KSB7CiAgICAgICAgICAgICAgICBzdHJpbmcgdGl0bGU7CiAgICAgICAgICAgICAgICBjb3V0IDw8ICJFbnRlciBtYWdhemluZSB0aXRsZSB0byBkZWxldGU6ICI7CiAgICAgICAgICAgICAgICBnZXRsaW5lKGNpbiwgdGl0bGUpOwogICAgICAgICAgICAgICAgdXNlci5kZWxldGVfbWFnYXppbmUobWFnYXppbmVzLCB0aXRsZSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoY2hvaWNlID09IDUpIHsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY291dCA8PCAiSW52YWxpZCBjaG9pY2UuIFRyeSBhZ2Fpbi5cbiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGNvdXQgPDwgIkludmFsaWQgcm9sZSEgUGxlYXNlIGVudGVyIGVpdGhlciAnUGF0cm9uJyBvciAnTGlicmFyaWFuJy5cbiI7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0K