I have a C++ library for generating passwords. The library is implemented using the Abstract Factory and Command patterns. Please write a main() function that will define a console user interface and allow this library to be used to generate passwords for the user. Here is code of library:

#include <string>
#include <vector>
#include <random>
#include <stdexcept>

class PasswordOptions {
public:
    virtual bool useLowercase() const = 0;
    virtual bool useUppercase() const = 0;
    virtual bool useDigits() const = 0;
    virtual bool useSpecialChars() const = 0;
    virtual size_t getPasswordLength() const = 0;
};

class PasswordFactory {
public:
    virtual std::string generatePassword() const = 0;
};

class BasePasswordOptions : public PasswordOptions {
private:
    bool includeLowercase;
    bool includeUppercase;
    bool includeDigits;
    bool includeSpecialChars;
    size_t length;

public:
    BasePasswordOptions(bool lower, bool upper, bool digits, bool special, size_t len)
        : includeLowercase(lower),
          includeUppercase(upper),
          includeDigits(digits),
          includeSpecialChars(special),
          length(len) {}

    bool useLowercase() const override { return includeLowercase; }
    bool useUppercase() const override { return includeUppercase; }
    bool useDigits() const override { return includeDigits; }
    bool useSpecialChars() const override { return includeSpecialChars; }
    size_t getPasswordLength() const override { return length; }
};

class ConcretePasswordFactory : public PasswordFactory {
private:
    PasswordOptions const &options;

    char randomChar(const std::string &category) const {
        static std::mt19937 rng(std::random_device{}());
        std::uniform_int_distribution<> dist(0, category.length() - 1);
        return category[dist(rng)];
    }

public:
    ConcretePasswordFactory(const PasswordOptions &opts) : options(opts) {}

    std::string generatePassword() const override {
        std::string allowedChars;
        if (options.useLowercase()) allowedChars += "abcdefghijklmnopqrstuvwxyz";
        if (options.useUppercase()) allowedChars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        if (options.useDigits()) allowedChars += "0123456789";
        if (options.useSpecialChars()) allowedChars += "!@#$%^&*()_-+=<>?";

        if (allowedChars.empty()) throw std::runtime_error("No characters are allowed for password generation");
        
        std::string password;
        for (size_t i = 0; i < options.getPasswordLength(); ++i) {
            password += randomChar(allowedChars);
        }
        return password;
    }
};

class ICommand {
public:
    virtual void execute() = 0;
};

class PasswordGeneratorCommand : public ICommand {
private:
    const PasswordFactory &factory;
    size_t numberOfPasswords;
    std::vector<std::string> &passwords;

public:
    PasswordGeneratorCommand(const PasswordFactory &f, size_t numPasswords, std::vector<std::string> &p)
        : factory(f), numberOfPasswords(numPasswords), passwords(p) {}

    void execute() override {
        try {
            for (size_t i = 0; i < numberOfPasswords; ++i) {
                passwords.push_back(factory.generatePassword());
            }
        } catch (const std::exception &e) {
            throw;
        }
    }
};

class PasswordStrengthChecker {
public:
    static bool isPasswordStrong(const std::string &password) {
        size_t score = 0;
        for (char ch : password) {
            if (std::islower(ch)) score += 1;
            else if (std::isupper(ch)) score += 2;
            else if (std::isdigit(ch)) score += 3;
            else score += 5;
        }
        return score > 10;
    }
};