# Path: cardinal/decorators.py
# def command(triggers):
#     if isinstance(triggers, str):
#         triggers = [triggers]
# 
#     if not isinstance(triggers, list):
#         raise TypeError("Command must be a trigger string or list of triggers")
# 
#     def wrap(f):
#         f.commands = triggers
#         return f
# 
#     return wrap
# 
# def help(lines):
#     # For backwards compatibility
#     if isinstance(lines, str):
#         lines = [lines]
# 
#     if not isinstance(lines, list):
#         raise TypeError("Help must be a help string or list of help strings")
# 
#     def wrap(f):
#         # Create help list or prepend to it
#         if not hasattr(f, 'help'):
#             f.help = lines
#         else:
#             f.help = lines + f.help
# 
#         return f
# 
#     return wrap
# 
# def event(triggers):
#     if isinstance(triggers, str):
#         triggers = [triggers]
# 
#     if not isinstance(triggers, list):
#         raise TypeError("Event must be a trigger string or list of triggers")
# 
#     def wrap(f):
#         f.events = triggers
#         return f
# 
#     return wrap
# 
# Path: cardinal/util.py
# def is_action(message):
#     """Checks if a message is a /me message."""
#     return message.startswith("\x01ACTION")
# 
# def parse_action(nick, message):
#     """Parses a /me message like an IRC client might.
# 
#     e.g. "/me dances." -> "* Cardinal dances."
#     """
#     if not is_action(message):
#         raise ValueError("This message is not an ACTION message")
# 
#     message = message[len("\x01ACTION "):]
#     if message and message[-1] == "\x01":
#         message = message[:-1]
# 
#     return "* {}{}".format(
#         nick,
#         " " + message if message else "",
#     )
# 
# def strip_formatting(line):
#     """Removes mIRC control code formatting"""
#     return re.sub(r"(?:\x03\d\d?,\d\d?|\x03\d\d?|[\x01-\x1f])", "", line)


from datetime import datetime, timezone
from cardinal.decorators import command, help, event
from cardinal.util import (
    is_action,
    parse_action,
    strip_formatting,
)


PRIVMSG = 'PRIVMSG'  # [channel, message]
NOTICE = 'NOTICE'  # [channel, message]
NICK = 'NICK'  # [new_nick]
MODE = 'MODE'  # [channel, mode]
TOPIC = 'TOPIC'  # [channel, topic]
JOIN = 'JOIN'  # [channel]
PART = 'PART'  # [channel, message]
QUIT = 'QUIT'  # [message]

EPOCH = datetime.utcfromtimestamp(0)


class SeenPlugin:
    def __init__(self, cardinal, config):

# Path: cardinal/decorators.py
# def command(triggers):
#     if isinstance(triggers, str):
#         triggers = [triggers]
# 
#     if not isinstance(triggers, list):
#         raise TypeError("Command must be a trigger string or list of triggers")
# 
#     def wrap(f):
#         f.commands = triggers
#         return f
# 
#     return wrap
# 
# def help(lines):
#     # For backwards compatibility
#     if isinstance(lines, str):
#         lines = [lines]
# 
#     if not isinstance(lines, list):
#         raise TypeError("Help must be a help string or list of help strings")
# 
#     def wrap(f):
#         # Create help list or prepend to it
#         if not hasattr(f, 'help'):
#             f.help = lines
#         else:
#             f.help = lines + f.help
# 
#         return f
# 
#     return wrap
# 
# def event(triggers):
#     if isinstance(triggers, str):
#         triggers = [triggers]
# 
#     if not isinstance(triggers, list):
#         raise TypeError("Event must be a trigger string or list of triggers")
# 
#     def wrap(f):
#         f.events = triggers
#         return f
# 
#     return wrap
# 
# Path: cardinal/util.py
# def is_action(message):
#     """Checks if a message is a /me message."""
#     return message.startswith("\x01ACTION")
# 
# def parse_action(nick, message):
#     """Parses a /me message like an IRC client might.
# 
#     e.g. "/me dances." -> "* Cardinal dances."
#     """
#     if not is_action(message):
#         raise ValueError("This message is not an ACTION message")
# 
#     message = message[len("\x01ACTION "):]
#     if message and message[-1] == "\x01":
#         message = message[:-1]
# 
#     return "* {}{}".format(
#         nick,
#         " " + message if message else "",
#     )
# 
# def strip_formatting(line):
#     """Removes mIRC control code formatting"""
#     return re.sub(r"(?:\x03\d\d?,\d\d?|\x03\d\d?|[\x01-\x1f])", "", line)


# Path: plugins/seen/plugin.py
from datetime import datetime, timezone
from cardinal.decorators import command, help, event
from cardinal.util import (
    is_action,
    parse_action,
    strip_formatting,
)



PRIVMSG = 'PRIVMSG'  # [channel, message]
NOTICE = 'NOTICE'  # [channel, message]
NICK = 'NICK'  # [new_nick]
MODE = 'MODE'  # [channel, mode]
TOPIC = 'TOPIC'  # [channel, topic]
JOIN = 'JOIN'  # [channel]
PART = 'PART'  # [channel, message]
QUIT = 'QUIT'  # [message]

EPOCH = datetime.utcfromtimestamp(0)


class SeenPlugin:
    def __init__(self, cardinal, config):

        if config is None: