packages feed

glirc 2.0 → 2.1

raw patch · 18 files changed

+1171/−1434 lines, 18 filesdep +memorydep +vector

Dependencies added: memory, vector

Files

ChangeLog.md view
@@ -1,5 +1,13 @@ # Revision history for glirc2 +## 2.1++* Add red highlighting for own nick+* Synchronize reply codes with Freenode+* Add textual interpretation of reply codes+* Add SASL support+* Add `/channelinfo` command+ ## 2.0  * First version of glirc rewrite
README.md view
@@ -21,6 +21,7 @@ * Run commands upon connection * Ban lists don't obstruct chat messages * Ban list and user list are searchable+* CERTFP and SASL authentication  TLS ===@@ -100,6 +101,8 @@ * `username` - text - username * `realname` - text - realname / GECOS * `password` - text - server password+* `sasl-username` - text - SASL username+* `sasl-password` - text - SASL password * `tls` - yes/no - use TLS to connect * `tls-insecure` - yes/no - disable certificate validation * `tls-client-cert` - text - path to TLS client certificate@@ -109,6 +112,8 @@ * `socks-port` - number - port number of SOCKS proxy to connect through * `server-certificates` - list of text - list of CA certificates to use when validating certificates * `chanserv-channels` - list of text - list of channels with chanserv op permission+* `flood-penalty` - number - cost in seconds per message+* `flood-threshold` - number - threshold of seconds for burst   Commands@@ -140,6 +145,7 @@ * `/part` - Part from current channel * `/users` - Show channel user list * `/masks <mode>` - Show channel bans(b), quiets(q), exempts(e), or invex(I)+* `/channelinfo` - Show channel topic, creation, url  Filters 
glirc.cabal view
@@ -1,5 +1,5 @@ name:                glirc-version:             2.0+version:             2.1 synopsis:            Console IRC client description:         Console IRC client license:             ISC@@ -30,6 +30,7 @@                        Client.EventLoop                        Client.IdentifierColors                        Client.Image+                       Client.Image.ChannelInfo                        Client.Image.MaskList                        Client.Image.Message                        Client.Image.UserList@@ -69,6 +70,7 @@                        unordered-containers >=0.2.7  && <0.3,                        hashable             >=1.2.4  && <1.3,                        network              >=2.6.2  && <2.7,+                       vector               >=0.11   && <0.12,                        tls                  >=1.3.8  && <1.4,                        split                >=0.2    && <0.3,                        profunctors          >=5.2    && <5.3,@@ -79,6 +81,7 @@                        data-default-class   >=0.1.2  && <0.2,                        stm                  >=2.4    && <2.5,                        directory            >=1.2.6  && <1.3,+                       memory               >=0.13   && <0.14,                        filepath             >=1.4.1  && <1.5    ghc-options:         -threaded -rtsopts
src/Client/ChannelState.hs view
@@ -16,9 +16,10 @@ module Client.ChannelState   (   -- * Channel state type-    ChannelState+    ChannelState(..)   , chanTopic   , chanTopicProvenance+  , chanUrl   , chanUsers   , chanModes   , chanLists@@ -56,6 +57,8 @@         -- ^ topic text   , _chanTopicProvenance :: !(Maybe TopicProvenance)         -- ^ author and timestamp for topic+  , _chanUrl :: !(Maybe Text)+        -- ^ channel URL   , _chanUsers :: !(HashMap Identifier String)         -- ^ user list and sigils   , _chanModes :: !(Map Char Text)@@ -80,6 +83,7 @@ newChannel :: ChannelState newChannel = ChannelState   { _chanTopic = Text.empty+  , _chanUrl = Nothing   , _chanTopicProvenance = Nothing   , _chanUsers = HashMap.empty   , _chanModes = Map.empty
src/Client/Commands.hs view
@@ -141,6 +141,7 @@   , ("part"      , ChannelCommand cmdPart   simpleChannelTab)    , ("users"     , ChannelCommand cmdUsers  noChannelTab)+  , ("channelinfo", ChannelCommand cmdChannelInfo noChannelTab)   , ("masks"     , ChannelCommand cmdMasks  noChannelTab)   ] @@ -359,6 +360,12 @@ cmdUsers _ _ _ st _ = commandContinue                     $ changeSubfocus FocusUsers                     $ consumeInput st++cmdChannelInfo :: NetworkName -> ConnectionState -> Identifier -> ClientState -> String -> IO CommandResult+cmdChannelInfo _ _ _ st _+  = commandContinue+  $ changeSubfocus FocusInfo+  $ consumeInput st  cmdMasks :: NetworkName -> ConnectionState -> Identifier -> ClientState -> String -> IO CommandResult cmdMasks _ cs _ st rest =
src/Client/Configuration.hs view
@@ -133,6 +133,8 @@        _ssSocksPort      <- fieldReq' ssSocksPort     (sectionOptNum "socks-port")        _ssServerCerts    <- fieldReq' ssServerCerts   (sectionOptStrings "server-certificates")        _ssChanservChannels <- fieldReq' ssChanservChannels (sectionOptIdentifiers "chanserv-channels")+       _ssFloodPenalty   <- fieldReq' ssFloodPenalty   (sectionOptNum "flood-penalty")+       _ssFloodThreshold <- fieldReq' ssFloodThreshold (sectionOptNum "flood-threshold")        return ServerSettings{..}   where     field    l key = field'    l (sectionOpt key)
src/Client/ConnectionState.hs view
@@ -19,7 +19,7 @@ module Client.ConnectionState   (   -- * Connection state type-    ConnectionState+    ConnectionState(..)   , csNick   , csChannels   , csSocket@@ -85,7 +85,7 @@ import           LensUtils  data ConnectionState = ConnectionState-  { _csNetworkId    :: NetworkId+  { _csNetworkId    :: !NetworkId   , _csChannels     :: !(HashMap Identifier ChannelState)   , _csSocket       :: !NetworkConnection   , _csModeTypes    :: !ModeTypes@@ -233,8 +233,11 @@          $ forgetUser' nick          $ overChannel chan (partChannel nick) cs     Reply RPL_WELCOME (me:_) -> doWelcome msgWhen (mkId me) cs+    Reply RPL_SASLSUCCESS _ -> ([ircCapEnd], cs)+    Reply RPL_SASLFAIL _ -> ([ircCapEnd], cs)     Reply code args        -> noReply (doRpl code msgWhen args cs)     Cap cmd params         -> doCap cmd params cs+    Authenticate param     -> doAuthenticate param cs     Mode who target (modes:params)  -> doMode msgWhen who target modes params cs     Topic user chan topic  -> noReply (doTopic msgWhen user chan topic cs)     _                      -> noReply cs@@ -271,7 +274,7 @@       Just $! posixSecondsToUTCTime (fromInteger i)     _ -> Nothing -doRpl :: Int -> ZonedTime -> [Text] -> ConnectionState -> ConnectionState+doRpl :: ReplyCode -> ZonedTime -> [Text] -> ConnectionState -> ConnectionState doRpl cmd msgWhen args =   case cmd of @@ -301,6 +304,12 @@           overChannel (mkId chan) (set chanCreation (Just when))         _ -> id +    RPL_CHANNEL_URL ->+      case args of+        _me:chan:urlTxt:_ ->+          overChannel (mkId chan) (set chanUrl (Just urlTxt))+        _ -> id+     RPL_ISUPPORT -> isupport args      RPL_NAMREPLY ->@@ -350,7 +359,7 @@                      cs         _ -> id -    RPL_INVITELIST ->+    RPL_INVEXLIST ->       case args of         _me:_tgt:mask:who:whenTxt:_ | Just when <- parseTimeParam whenTxt ->           over csTransaction $ \t ->@@ -358,7 +367,7 @@             in BanTransaction ((mask,(who,when)):xs)         _ -> id -    RPL_ENDOFINVITELIST ->+    RPL_ENDOFINVEXLIST ->       case args of         _me:tgt:_ -> \cs ->            set csTransaction NoTransaction@@ -408,15 +417,15 @@ -- | These replies are interpreted by the client and should only be shown -- in the detailed view. Any reply interpreted by 'doRpl' should be -- listed here.-squelchReply :: Int -> Bool+squelchReply :: ReplyCode -> Bool squelchReply rpl =   case rpl of     RPL_NAMREPLY        -> True     RPL_ENDOFNAMES      -> True     RPL_BANLIST         -> True     RPL_ENDOFBANLIST    -> True-    RPL_INVITELIST      -> True-    RPL_ENDOFINVITELIST -> True+    RPL_INVEXLIST       -> True+    RPL_ENDOFINVEXLIST  -> True     RPL_EXCEPTLIST      -> True     RPL_ENDOFEXCEPTLIST -> True     RPL_QUIETLIST       -> True@@ -425,6 +434,7 @@     RPL_TOPIC           -> True     RPL_TOPICWHOTIME    -> True     RPL_CREATIONTIME    -> True+    RPL_CHANNEL_URL     -> True     RPL_NOTOPIC         -> True     RPL_WHOREPLY        -> True     RPL_ENDOFWHO        -> True@@ -512,9 +522,23 @@       | otherwise         = mode:modes     applyOne modes (False, mode, _) = delete mode modes -supportedCaps :: [Text]-supportedCaps = ["multi-prefix", "znc.in/server-time-iso"]+supportedCaps :: ConnectionState -> [Text]+supportedCaps cs = sasl ++ ["multi-prefix", "znc.in/server-time-iso"]+  where+    ss = view csSettings cs+    sasl = ["sasl" | has ssSaslUsername ss+                   , has ssSaslPassword ss ] +doAuthenticate :: Text -> ConnectionState -> ([RawIrcMsg], ConnectionState)+doAuthenticate "+" cs+  | Just user <- view ssSaslUsername ss+  , Just pass <- view ssSaslPassword ss+  = ([ircAuthenticate (encodePlainAuthentication user pass)], cs)+  where+    ss = view csSettings cs++doAuthenticate _ cs = ([ircCapEnd], cs)+ doCap :: CapCmd -> [Text] -> ConnectionState -> ([RawIrcMsg], ConnectionState) doCap cmd args cs =   case (cmd,args) of@@ -523,12 +547,15 @@       | otherwise -> ([ircCapReq reqCaps], cs)       where         caps = Text.words capsTxt-        reqCaps = intersect supportedCaps caps+        reqCaps = intersect (supportedCaps cs) caps -    (CapAck,_) -> ([ircCapEnd], cs)-    (CapNak,_) -> ([ircCapEnd], cs)+    (CapAck,[capsTxt])+      | "sasl" `elem` caps ->+          ([ircAuthenticate plainAuthenticationMode], cs)+      where+        caps = Text.words capsTxt -    _ -> noReply cs+    _ -> ([ircCapEnd], cs)   initialMessages :: ConnectionState -> [RawIrcMsg]
src/Client/Image.hs view
@@ -14,6 +14,7 @@ import           Client.ChannelState import           Client.ConnectionState import qualified Client.EditBox as Edit+import           Client.Image.ChannelInfo import           Client.Image.MaskList import           Client.Image.Message import           Client.Image.UserList@@ -56,6 +57,8 @@ messagePaneImages :: ClientState -> [Image] messagePaneImages !st =   case (view clientFocus st, view clientSubfocus st) of+    (ChannelFocus network channel, FocusInfo) ->+      channelInfoImages network channel st     (ChannelFocus network channel, FocusUsers)       | view clientDetailView st -> userInfoImages network channel st       | otherwise                -> userListImages network channel st@@ -223,6 +226,7 @@     subfocusName =       case view clientSubfocus st of         FocusMessages -> Nothing+        FocusInfo     -> Just $ string (withForeColor defAttr green) "info"         FocusUsers    -> Just $ string (withForeColor defAttr green) "users"         FocusMasks m  -> Just $ horizCat           [ string (withForeColor defAttr green) "masks"
+ src/Client/Image/ChannelInfo.hs view
@@ -0,0 +1,75 @@+{-# Language OverloadedStrings #-}+{-# Language BangPatterns #-}++{-|+Module      : Client.Image.ChannelInfo+Description : Channel information renderer+Copyright   : (c) Eric Mertens, 2016+License     : ISC+Maintainer  : emertens@gmail.com++This module implements a renderer for the window that shows+channel metadata.++-}+module Client.Image.ChannelInfo+  ( channelInfoImages+  ) where++import           Client.ChannelState+import           Client.ConnectionState+import           Client.Image.Message+import           Client.MircFormatting+import           Client.State+import           Control.Lens+import qualified Data.HashMap.Strict as HashMap+import           Data.List+import           Data.Ord+import           Data.Time+import           Graphics.Vty.Image+import           Irc.Identifier++-- | Render the lines used in a channel mask list+channelInfoImages :: NetworkName -> Identifier -> ClientState -> [Image]+channelInfoImages network channelId st++  | Just cs      <- preview (clientConnection network) st+  , Just channel <- preview (csChannels . ix channelId) cs+  = channelInfoImages' channel cs++  | otherwise = [text' (withForeColor defAttr red) "No channel information"]++channelInfoImages' :: ChannelState -> ConnectionState -> [Image]+channelInfoImages' !channel !cs+    = topicLine+    : provenanceLines+   ++ creationLines+   ++ urlLines++  where+    label = text' (withForeColor defAttr green)++    topicLine = label "Topic: " <|> parseIrcText (view chanTopic channel)++    myNick = view csNick cs++    utcTimeImage = string defAttr . formatTime defaultTimeLocale "%F %T"++    provenanceLines =+        case view chanTopicProvenance channel of+          Nothing -> []+          Just !prov ->+            [ label "Topic set by: " <|> coloredUserInfo DetailedRender [myNick] (view topicAuthor prov)+            , label "Topic set on: " <|> utcTimeImage (view topicTime prov)+            ]++    creationLines =+        case view chanCreation channel of+          Nothing   -> []+          Just time -> [label "Created on: " <|> utcTimeImage time]++    urlLines =+        case view chanUrl channel of+          Nothing -> []+          Just url -> [ label "Channel URL: " <|> parseIrcText url ]+
src/Client/Image/Message.hs view
@@ -27,6 +27,7 @@ import           Control.Lens import           Data.Time import           Graphics.Vty.Image+import           Irc.Codes import           Irc.Identifier import           Irc.Message import           Irc.RawIrcMsg@@ -42,6 +43,7 @@   { rendStatusMsg  :: [Char] -- ^ restricted message sigils   , rendUserSigils :: [Char] -- ^ sender sigils   , rendNicks      :: [Identifier] -- ^ nicknames to highlight+  , rendMyNicks    :: [Identifier] -- ^ nicknames to highlight in red   }  -- | Default 'MessageRenderParams' with no sigils or nicknames specified@@ -50,6 +52,7 @@   { rendStatusMsg = ""   , rendUserSigils = ""   , rendNicks = []+  , rendMyNicks = []   }  -- | Construct a message given the time the message was received and its@@ -60,7 +63,7 @@ msgImage when params body = horizCat   [ timeImage when   , statusMsgImage (rendStatusMsg params)-  , bodyImage NormalRender (rendUserSigils params) (rendNicks params) body+  , bodyImage NormalRender (rendUserSigils params) (rendMyNicks params) (rendNicks params) body   ]  -- | Construct a message given the time the message was received and its@@ -69,7 +72,7 @@ detailedMsgImage when params body = horizCat   [ datetimeImage when   , statusMsgImage (rendStatusMsg params)-  , bodyImage DetailedRender (rendUserSigils params) (rendNicks params) body+  , bodyImage DetailedRender (rendUserSigils params) (rendMyNicks params) (rendNicks params) body   ]  -- | Render the sigils for a restricted message.@@ -87,11 +90,12 @@ bodyImage ::   RenderMode ->   [Char] {- ^ sigils -} ->+  [Identifier] {- ^ my nicknames -} ->   [Identifier] {- ^ nicknames to highlight -} ->   MessageBody -> Image-bodyImage rm modes nicks body =+bodyImage rm modes myNicks nicks body =   case body of-    IrcBody irc  -> ircLineImage rm modes nicks irc+    IrcBody irc  -> ircLineImage rm modes myNicks nicks irc     ErrorBody ex -> string defAttr ("Exception: " ++ show ex)     ExitBody     -> string defAttr "Thread finished" @@ -129,9 +133,10 @@ ircLineImage ::   RenderMode ->   [Char]       {- ^ sigils (e.g. \@+) -} ->+  [Identifier] {- ^ my nicknames to highlight -} ->   [Identifier] {- ^ nicknames to highlight -} ->   IrcMsg -> Image-ircLineImage rm sigils nicks body =+ircLineImage rm sigils myNicks nicks body =   let detail img =         case rm of           NormalRender -> emptyImage@@ -141,24 +146,24 @@     Nick old new ->       detail (string quietAttr "nick ") <|>       string (withForeColor defAttr cyan) sigils <|>-      coloredUserInfo rm old <|>+      coloredUserInfo rm myNicks old <|>       string defAttr " became " <|>-      coloredIdentifier new+      coloredIdentifier myNicks new      Join nick _chan ->       string quietAttr "join " <|>-      coloredUserInfo rm nick+      coloredUserInfo rm myNicks nick      Part nick _chan mbreason ->       string quietAttr "part " <|>-      coloredUserInfo rm nick <|>+      coloredUserInfo rm myNicks nick <|>       foldMap (\reason -> string quietAttr " (" <|>                           parseIrcText reason <|>                           string quietAttr ")") mbreason      Quit nick mbreason ->       string quietAttr "quit "   <|>-      coloredUserInfo rm nick   <|>+      coloredUserInfo rm myNicks nick   <|>       foldMap (\reason -> string quietAttr " (" <|>                           parseIrcText reason <|>                           string quietAttr ")") mbreason@@ -166,90 +171,119 @@     Kick kicker _channel kickee reason ->       detail (string quietAttr "kick ") <|>       string (withForeColor defAttr cyan) sigils <|>-      coloredUserInfo rm kicker <|>+      coloredUserInfo rm myNicks kicker <|>       string defAttr " kicked " <|>-      coloredIdentifier kickee <|>+      coloredIdentifier myNicks kickee <|>       string defAttr ": " <|>       parseIrcText reason      Topic src _dst txt ->-      coloredUserInfo rm src <|>+      coloredUserInfo rm myNicks src <|>       string defAttr " changed topic to " <|>       parseIrcText txt      Notice src _dst txt ->       detail (string quietAttr "note ") <|>       string (withForeColor defAttr cyan) sigils <|>-      coloredUserInfo rm src <|>+      coloredUserInfo rm myNicks src <|>       string (withForeColor defAttr red) ": " <|>-      parseIrcTextWithNicks nicks txt+      parseIrcTextWithNicks myNicks nicks txt      Privmsg src _dst txt ->       detail (string quietAttr "chat ") <|>       string (withForeColor defAttr cyan) sigils <|>-      coloredUserInfo rm src <|>+      coloredUserInfo rm myNicks src <|>       string defAttr ": " <|>-      parseIrcTextWithNicks nicks txt+      parseIrcTextWithNicks myNicks nicks txt      Action src _dst txt ->       detail (string quietAttr "chat ") <|>       string (withForeColor defAttr blue) "* " <|>       string (withForeColor defAttr cyan) sigils <|>-      coloredUserInfo rm src <|>+      coloredUserInfo rm myNicks src <|>       string defAttr " " <|>-      parseIrcTextWithNicks nicks txt+      parseIrcTextWithNicks myNicks nicks txt      Ping params ->-      string defAttr "PING" <|>-      horizCat [char (withForeColor defAttr blue) '·' <|>-                 parseIrcText p | p <- params]+      string defAttr "PING " <|> separatedParams params      Pong params ->-      string defAttr "PONG" <|>-      horizCat [char (withForeColor defAttr blue) '·' <|>-                 parseIrcText p | p <- params]+      string defAttr "PONG " <|> separatedParams params      Error reason ->       string (withForeColor defAttr red) "ERROR " <|>       parseIrcText reason      Reply code params ->-      string defAttr (show code) <|>-      horizCat [char (withForeColor defAttr blue) '·' <|>-                parseIrcText p | p <- params]+      renderReplyCode rm code <|>+      char defAttr ' ' <|>+      separatedParams (dropFst params)+      where+        dropFst = case rm of+                    DetailedRender -> id+                    NormalRender   -> drop 1      UnknownMsg irc ->-      maybe emptyImage (\ui -> coloredUserInfo rm ui <|> char defAttr ' ')+      maybe emptyImage (\ui -> coloredUserInfo rm myNicks ui <|> char defAttr ' ')         (view msgPrefix irc) <|>       text' defAttr (view msgCommand irc) <|>-      horizCat [char (withForeColor defAttr blue) '·' <|>-                parseIrcText p | p <- view msgParams irc]+      char defAttr ' ' <|>+      separatedParams (view msgParams irc)      Cap cmd args ->       string defAttr (show cmd) <|>-      horizCat [char (withForeColor defAttr blue) '·' <|>-                text' defAttr a | a <- args]+      char defAttr ' ' <|>+      separatedParams args +    Authenticate{} -> string defAttr "AUTHENTICATE ***"+     Mode nick _chan params ->       detail (string quietAttr "mode ") <|>       string (withForeColor defAttr cyan) sigils <|>-      coloredUserInfo rm nick <|>+      coloredUserInfo rm myNicks nick <|>       string defAttr " set mode: " <|>-      horizCat (intersperse (char (withForeColor defAttr blue) '·')-                            (text' defAttr <$> params))+      separatedParams params +separatorImage :: Image+separatorImage = char (withForeColor defAttr blue) '·'++separatedParams :: [Text] -> Image+separatedParams = horizCat . intersperse separatorImage . map parseIrcText++renderReplyCode :: RenderMode -> ReplyCode -> Image+renderReplyCode rm code@(ReplyCode w) =+  case rm of+    DetailedRender -> string attr (show w)+    NormalRender   -> text' attr (Text.toLower (replyCodeText info)) <|>+                      char defAttr ':'+  where+    info = replyCodeInfo code++    color = case replyCodeType info of+              ClientServerReply -> magenta+              CommandReply      -> green+              ErrorReply        -> red+              UnknownReply      -> yellow++    attr = withForeColor defAttr color++ -- | Render a nickname in its hash-based color.-coloredIdentifier :: Identifier -> Image-coloredIdentifier ident =-  text' (withForeColor defAttr (identifierColor ident)) (idText ident)+coloredIdentifier :: [Identifier] {- ^ my nicknames -} -> Identifier -> Image+coloredIdentifier myNicks ident =+  text' (withForeColor defAttr color) (idText ident)+  where+    color+      | ident `elem` myNicks = red+      | otherwise            = identifierColor ident  -- | Render an a full user. In normal mode only the nickname will be rendered. -- If detailed mode the full user info including the username and hostname parts -- will be rendered. The nickname will be colored.-coloredUserInfo :: RenderMode -> UserInfo -> Image-coloredUserInfo NormalRender ui = coloredIdentifier (userNick ui)-coloredUserInfo DetailedRender ui = horizCat-  [ coloredIdentifier (userNick ui)+coloredUserInfo :: RenderMode -> [Identifier] -> UserInfo -> Image+coloredUserInfo NormalRender myNicks ui = coloredIdentifier myNicks (userNick ui)+coloredUserInfo DetailedRender myNicks ui = horizCat+  [ coloredIdentifier myNicks (userNick ui)   , foldMap (\user -> char defAttr '!' <|> text' quietAttr user) (userName ui)   , foldMap (\host -> char defAttr '@' <|> text' quietAttr host) (userHost ui)   ]@@ -263,20 +297,26 @@ -- control characters in it then the text will be rendered according to -- the formatting codes. Otherwise the nicknames in the message are -- highlighted.-parseIrcTextWithNicks :: [Identifier] -> Text -> Image-parseIrcTextWithNicks nicks txt+parseIrcTextWithNicks ::+  [Identifier] {- ^ my nicks -} ->+  [Identifier] {- ^ other nicks -} ->+  Text -> Image+parseIrcTextWithNicks myNicks nicks txt   | Text.any isControl txt = parseIrcText txt-  | otherwise              = highlightNicks nicks txt+  | otherwise              = highlightNicks myNicks nicks txt  -- | Given a list of nicknames and a chat message, this will generate -- an image where all of the occurrences of those nicknames are colored.-highlightNicks :: [Identifier] -> Text -> Image-highlightNicks nicks txt = horizCat (highlight1 <$> txtParts)+highlightNicks ::+  [Identifier] {- ^ my nicks -} ->+  [Identifier] {- ^ other nicks -} ->+  Text -> Image+highlightNicks myNicks nicks txt = horizCat (highlight1 <$> txtParts)   where     nickSet = HashSet.fromList nicks     txtParts = nickSplit txt     highlight1 part-      | HashSet.member partId nickSet = coloredIdentifier partId+      | HashSet.member partId nickSet = coloredIdentifier myNicks partId       | otherwise                     = text' defAttr part       where         partId = mkId part
src/Client/Image/UserList.hs view
@@ -1,3 +1,4 @@+{-# Language OverloadedStrings #-} {-| Module      : Client.Image.UserList Description : Line renderers for channel user list view@@ -28,13 +29,18 @@   Identifier  {- ^ Focused channel name -} ->   ClientState -> [Image] userListImages network channel st =-    [horizCat (intersperse gap (map renderUser usersList))]+    [countImage, horizCat (intersperse gap (map renderUser usersList))]   where+    countImage = text' (withForeColor defAttr green) "Users: " <|>+                 string defAttr (show (HashMap.size usersHashMap))+     matcher = clientMatcher st +    myNicks = toListOf (clientConnection network . csNick) st+     renderUser (ident, sigils) =       string (withForeColor defAttr cyan) sigils <|>-      coloredIdentifier ident+      coloredIdentifier myNicks ident      gap = char defAttr ' ' @@ -58,9 +64,11 @@   where     matcher = clientMatcher st +    myNicks = toListOf (clientConnection network . csNick) st+     renderEntry (info, sigils) =       string (withForeColor defAttr cyan) sigils <|>-      coloredUserInfo DetailedRender info+      coloredUserInfo DetailedRender myNicks info      matcher' (info,sigils) =       matcher (Text.pack sigils `Text.append` renderUserInfo info)
src/Client/NetworkConnection.hs view
@@ -35,6 +35,7 @@ import           Control.Concurrent.STM import           Control.Concurrent.Async import           Control.Exception+import           Control.Lens import           Control.Monad import           Data.ByteString (ByteString) import qualified Data.ByteString as B@@ -126,7 +127,9 @@   TQueue ByteString ->   IO () startConnection network cxt settings onInput outQueue =-  do rate <- newRateLimitDefault+  do rate <- newRateLimit+               (view ssFloodPenalty settings)+               (view ssFloodThreshold settings)      withConnection cxt settings $ \h ->        withAsync (sendLoop h outQueue rate)      $ \sender ->        withAsync (receiveLoop network h onInput) $ \receiver ->
src/Client/ServerSettings.hs view
@@ -34,6 +34,8 @@   , ssSocksPort   , ssServerCerts   , ssChanservChannels+  , ssFloodPenalty+  , ssFloodThreshold    -- * Load function   , loadDefaultServerSettings@@ -50,24 +52,26 @@ import Network.Socket (HostName, PortNumber)  data ServerSettings = ServerSettings-  { _ssNick          :: !Text -- ^ connection nickname-  , _ssUser          :: !Text -- ^ connection username-  , _ssReal          :: !Text -- ^ connection realname / GECOS-  , _ssUserInfo      :: !Text -- ^ CTCP userinfo-  , _ssPassword      :: !(Maybe Text) -- ^ server password-  , _ssSaslUsername  :: !(Maybe Text) -- ^ SASL username-  , _ssSaslPassword  :: !(Maybe Text) -- ^ SASL password-  , _ssHostName      :: !HostName -- ^ server hostname-  , _ssPort          :: !(Maybe PortNumber) -- ^ server port-  , _ssTls           :: !Bool -- ^ use TLS to connect-  , _ssTlsInsecure   :: !Bool -- ^ disable certificate checking-  , _ssTlsClientCert :: !(Maybe FilePath) -- ^ path to client TLS certificate-  , _ssTlsClientKey  :: !(Maybe FilePath) -- ^ path to client TLS key-  , _ssConnectCmds   :: ![Text] -- ^ raw IRC messages to transmit upon successful connection-  , _ssSocksHost     :: !(Maybe HostName) -- ^ hostname of SOCKS proxy-  , _ssSocksPort     :: !PortNumber -- ^ port of SOCKS proxy-  , _ssServerCerts   :: ![FilePath] -- ^ additional CA certificates for validating server+  { _ssNick             :: !Text -- ^ connection nickname+  , _ssUser             :: !Text -- ^ connection username+  , _ssReal             :: !Text -- ^ connection realname / GECOS+  , _ssUserInfo         :: !Text -- ^ CTCP userinfo+  , _ssPassword         :: !(Maybe Text) -- ^ server password+  , _ssSaslUsername     :: !(Maybe Text) -- ^ SASL username+  , _ssSaslPassword     :: !(Maybe Text) -- ^ SASL password+  , _ssHostName         :: !HostName -- ^ server hostname+  , _ssPort             :: !(Maybe PortNumber) -- ^ server port+  , _ssTls              :: !Bool -- ^ use TLS to connect+  , _ssTlsInsecure      :: !Bool -- ^ disable certificate checking+  , _ssTlsClientCert    :: !(Maybe FilePath) -- ^ path to client TLS certificate+  , _ssTlsClientKey     :: !(Maybe FilePath) -- ^ path to client TLS key+  , _ssConnectCmds      :: ![Text] -- ^ raw IRC messages to transmit upon successful connection+  , _ssSocksHost        :: !(Maybe HostName) -- ^ hostname of SOCKS proxy+  , _ssSocksPort        :: !PortNumber -- ^ port of SOCKS proxy+  , _ssServerCerts      :: ![FilePath] -- ^ additional CA certificates for validating server   , _ssChanservChannels :: ![Identifier] -- ^ Channels with chanserv permissions+  , _ssFloodPenalty     :: !Int -- ^ Flood limiter penalty (seconds)+  , _ssFloodThreshold   :: !Int -- ^ Flood limited threshold (seconds)   }   deriving Show @@ -100,4 +104,6 @@        , _ssSocksPort     = 1080        , _ssServerCerts   = []        , _ssChanservChannels = []+       , _ssFloodPenalty     = 2 -- RFC 1459 defaults+       , _ssFloodThreshold   = 10        }
src/Client/State.hs view
@@ -83,7 +83,6 @@ import           Data.Text (Text) import qualified Data.Text as Text import qualified Data.Text.ICU as ICU-import           Data.Time import           Graphics.Vty import           Irc.Identifier import           Irc.Message@@ -106,6 +105,7 @@  data ClientSubfocus   = FocusMessages+  | FocusInfo   | FocusUsers   | FocusMasks !Char   deriving Eq@@ -201,10 +201,12 @@   where     focus = ChannelFocus network channel'     wl = toWindowLine rendParams msg+    myNicks = toListOf (clientConnection network . csNick) st     rendParams = MessageRendererParams       { rendStatusMsg  = statusModes       , rendUserSigils = computeMsgLineModes network channel' msg st       , rendNicks      = channelUserList network channel' st+      , rendMyNicks    = myNicks       }      -- on failure returns mempty/""@@ -242,7 +244,7 @@                           | otherwise   -> WLNormal         Error{}         -> WLImportant         Reply cmd _ ->-          case replyType cmd of+          case replyCodeType (replyCodeInfo cmd) of             ErrorReply -> WLImportant             _          -> WLNormal         _               -> WLBoring
src/Irc/Codes.hs view
@@ -1,1337 +1,854 @@-{-# Language PatternSynonyms #-}--{-|-Module      : Irc.Codes-Description : Helpers for interpreting IRC reply codes-Copyright   : (c) Eric Mertens, 2016-License     : ISC-Maintainer  : emertens@gmail.com--This module defines support for working with IRC's numeric reply-codes. Pattern synonyms are provided for each of the possible IRC reply codes.--Reply code information was extracted from https://www.alien.net.au/irc/irc2numerics.html---}--module Irc.Codes where---- | Categories for reply codes-data ReplyType-  = ClientServerReply -- ^ 0-99 Messages between client and server-  | CommandReply      -- ^ 200-399 Responses to commands-  | ErrorReply        -- ^ 200-399 Errors-  | CustomReply       -- ^ Uncategorized---- | Categorize replies according to the ranges provided in RFC 2812-replyType :: Int {- reply code -} -> ReplyType-replyType x-  | 000 <= x, x < 100 = ClientServerReply-  | 200 <= x, x < 400 = CommandReply-  | 400 <= x, x < 600 = ErrorReply-  | otherwise         = CustomReply--pattern RPL_WELCOME                 :: Int-pattern RPL_WELCOME                 = 001--pattern RPL_YOURHOST                :: Int-pattern RPL_YOURHOST                = 002--pattern RPL_CREATED                 :: Int-pattern RPL_CREATED                 = 003--pattern RPL_MYINFO                  :: Int-pattern RPL_MYINFO                  = 004--pattern RPL_ISUPPORT                :: Int-pattern RPL_ISUPPORT                = 005--pattern RPL_SNOMASK                 :: Int-pattern RPL_SNOMASK                 = 008--pattern RPL_STATMEMTOT              :: Int-pattern RPL_STATMEMTOT              = 009--pattern RPL_BOUNCE                  :: Int-pattern RPL_BOUNCE                  = 010--pattern RPL_STATMEM                 :: Int-pattern RPL_STATMEM                 = 010--pattern RPL_YOURCOOKIE              :: Int-pattern RPL_YOURCOOKIE              = 014--pattern RPL_YOURID                  :: Int-pattern RPL_YOURID                  = 042--pattern RPL_SAVENICK                :: Int-pattern RPL_SAVENICK                = 043--pattern RPL_ATTEMPTINGJUNC          :: Int-pattern RPL_ATTEMPTINGJUNC          = 050--pattern RPL_ATTEMPTINGREROUTE       :: Int-pattern RPL_ATTEMPTINGREROUTE       = 051--pattern RPL_TRACELINK               :: Int-pattern RPL_TRACELINK               = 200--pattern RPL_TRACECONNECTING         :: Int-pattern RPL_TRACECONNECTING         = 201--pattern RPL_TRACEHANDSHAKE          :: Int-pattern RPL_TRACEHANDSHAKE          = 202--pattern RPL_TRACEUNKNOWN            :: Int-pattern RPL_TRACEUNKNOWN            = 203--pattern RPL_TRACEOPERATOR           :: Int-pattern RPL_TRACEOPERATOR           = 204--pattern RPL_TRACEUSER               :: Int-pattern RPL_TRACEUSER               = 205--pattern RPL_TRACESERVER             :: Int-pattern RPL_TRACESERVER             = 206--pattern RPL_TRACESERVICE            :: Int-pattern RPL_TRACESERVICE            = 207--pattern RPL_TRACENEWTYPE            :: Int-pattern RPL_TRACENEWTYPE            = 208--pattern RPL_TRACECLASS              :: Int-pattern RPL_TRACECLASS              = 209--pattern RPL_TRACERECONNECT          :: Int-pattern RPL_TRACERECONNECT          = 210--pattern RPL_STATS                   :: Int-pattern RPL_STATS                   = 210--pattern RPL_STATSLINKINFO           :: Int-pattern RPL_STATSLINKINFO           = 211--pattern RPL_STATSCOMMANDS           :: Int-pattern RPL_STATSCOMMANDS           = 212--pattern RPL_STATSCLINE              :: Int-pattern RPL_STATSCLINE              = 213--pattern RPL_STATSILINE              :: Int-pattern RPL_STATSILINE              = 215--pattern RPL_STATSKLINE              :: Int-pattern RPL_STATSKLINE              = 216--pattern RPL_STATSYLINE              :: Int-pattern RPL_STATSYLINE              = 218--pattern RPL_ENDOFSTATS              :: Int-pattern RPL_ENDOFSTATS              = 219--pattern RPL_UMODEIS                 :: Int-pattern RPL_UMODEIS                 = 221--pattern RPL_SQLINE_NICK             :: Int-pattern RPL_SQLINE_NICK             = 222--pattern RPL_STATSDLINE              :: Int-pattern RPL_STATSDLINE              = 225--pattern RPL_STATSZLINE              :: Int-pattern RPL_STATSZLINE              = 225--pattern RPL_STATSCOUNT              :: Int-pattern RPL_STATSCOUNT              = 226--pattern RPL_SERVICEINFO             :: Int-pattern RPL_SERVICEINFO             = 231--pattern RPL_ENDOFSERVICES           :: Int-pattern RPL_ENDOFSERVICES           = 232--pattern RPL_SERVICE                 :: Int-pattern RPL_SERVICE                 = 233--pattern RPL_SERVLIST                :: Int-pattern RPL_SERVLIST                = 234--pattern RPL_SERVLISTEND             :: Int-pattern RPL_SERVLISTEND             = 235--pattern RPL_STATSVERBOSE            :: Int-pattern RPL_STATSVERBOSE            = 236--pattern RPL_STATSIAUTH              :: Int-pattern RPL_STATSIAUTH              = 239--pattern RPL_STATSLLINE              :: Int-pattern RPL_STATSLLINE              = 241--pattern RPL_STATSUPTIME             :: Int-pattern RPL_STATSUPTIME             = 242--pattern RPL_STATSOLINE              :: Int-pattern RPL_STATSOLINE              = 243--pattern RPL_STATSHLINE              :: Int-pattern RPL_STATSHLINE              = 244--pattern RPL_STATSSLINE              :: Int-pattern RPL_STATSSLINE              = 245--pattern RPL_STATSPING               :: Int-pattern RPL_STATSPING               = 246--pattern RPL_STATSDEFINE             :: Int-pattern RPL_STATSDEFINE             = 248--pattern RPL_STATSDEBUG              :: Int-pattern RPL_STATSDEBUG              = 249--pattern RPL_STATSCONN               :: Int-pattern RPL_STATSCONN               = 250--pattern RPL_LUSERCLIENT             :: Int-pattern RPL_LUSERCLIENT             = 251--pattern RPL_LUSEROP                 :: Int-pattern RPL_LUSEROP                 = 252--pattern RPL_LUSERUNKNOWN            :: Int-pattern RPL_LUSERUNKNOWN            = 253--pattern RPL_LUSERCHANNELS           :: Int-pattern RPL_LUSERCHANNELS           = 254--pattern RPL_LUSERME                 :: Int-pattern RPL_LUSERME                 = 255--pattern RPL_ADMINME                 :: Int-pattern RPL_ADMINME                 = 256--pattern RPL_ADMINLOC1               :: Int-pattern RPL_ADMINLOC1               = 257--pattern RPL_ADMINLOC2               :: Int-pattern RPL_ADMINLOC2               = 258--pattern RPL_ADMINEMAIL              :: Int-pattern RPL_ADMINEMAIL              = 259--pattern RPL_TRACELOG                :: Int-pattern RPL_TRACELOG                = 261--pattern RPL_TRACEPING               :: Int-pattern RPL_TRACEPING               = 262--pattern RPL_TRACEEND                :: Int-pattern RPL_TRACEEND                = 262--pattern RPL_TRYAGAIN                :: Int-pattern RPL_TRYAGAIN                = 263--pattern RPL_LOCALUSERS              :: Int-pattern RPL_LOCALUSERS              = 265--pattern RPL_GLOBALUSERS             :: Int-pattern RPL_GLOBALUSERS             = 266--pattern RPL_START_NETSTAT           :: Int-pattern RPL_START_NETSTAT           = 267--pattern RPL_NETSTAT                 :: Int-pattern RPL_NETSTAT                 = 268--pattern RPL_END_NETSTAT             :: Int-pattern RPL_END_NETSTAT             = 269--pattern RPL_PRIVS                   :: Int-pattern RPL_PRIVS                   = 270--pattern RPL_SILELIST                :: Int-pattern RPL_SILELIST                = 271--pattern RPL_ENDOFSILELIST           :: Int-pattern RPL_ENDOFSILELIST           = 272--pattern RPL_NOTIFY                  :: Int-pattern RPL_NOTIFY                  = 273--pattern RPL_ENDNOTIFY               :: Int-pattern RPL_ENDNOTIFY               = 274--pattern RPL_STATSDELTA              :: Int-pattern RPL_STATSDELTA              = 274--pattern RPL_VCHANEXIST              :: Int-pattern RPL_VCHANEXIST              = 276--pattern RPL_VCHANLIST               :: Int-pattern RPL_VCHANLIST               = 277--pattern RPL_VCHANHELP               :: Int-pattern RPL_VCHANHELP               = 278--pattern RPL_GLIST                   :: Int-pattern RPL_GLIST                   = 280--pattern RPL_ENDOFGLIST              :: Int-pattern RPL_ENDOFGLIST              = 281--pattern RPL_ACCEPTLIST              :: Int-pattern RPL_ACCEPTLIST              = 281--pattern RPL_ENDOFACCEPT             :: Int-pattern RPL_ENDOFACCEPT             = 282--pattern RPL_JUPELIST                :: Int-pattern RPL_JUPELIST                = 282--pattern RPL_ENDOFJUPELIST           :: Int-pattern RPL_ENDOFJUPELIST           = 283--pattern RPL_FEATURE                 :: Int-pattern RPL_FEATURE                 = 284--pattern RPL_GLIST_HASH              :: Int-pattern RPL_GLIST_HASH              = 285--pattern RPL_CHANINFO_HANDLE         :: Int-pattern RPL_CHANINFO_HANDLE         = 285--pattern RPL_NEWHOSTIS               :: Int-pattern RPL_NEWHOSTIS               = 285--pattern RPL_CHANINFO_USERS          :: Int-pattern RPL_CHANINFO_USERS          = 286--pattern RPL_CHKHEAD                 :: Int-pattern RPL_CHKHEAD                 = 286--pattern RPL_CHANINFO_CHOPS          :: Int-pattern RPL_CHANINFO_CHOPS          = 287--pattern RPL_CHANUSER                :: Int-pattern RPL_CHANUSER                = 287--pattern RPL_CHANINFO_VOICES         :: Int-pattern RPL_CHANINFO_VOICES         = 288--pattern RPL_PATCHHEAD               :: Int-pattern RPL_PATCHHEAD               = 288--pattern RPL_CHANINFO_AWAY           :: Int-pattern RPL_CHANINFO_AWAY           = 289--pattern RPL_PATCHCON                :: Int-pattern RPL_PATCHCON                = 289--pattern RPL_CHANINFO_OPERS          :: Int-pattern RPL_CHANINFO_OPERS          = 290--pattern RPL_HELPHDR                 :: Int-pattern RPL_HELPHDR                 = 290--pattern RPL_DATASTR                 :: Int-pattern RPL_DATASTR                 = 290--pattern RPL_CHANINFO_BANNED         :: Int-pattern RPL_CHANINFO_BANNED         = 291--pattern RPL_HELPOP                  :: Int-pattern RPL_HELPOP                  = 291--pattern RPL_ENDOFCHECK              :: Int-pattern RPL_ENDOFCHECK              = 291--pattern RPL_CHANINFO_BANS           :: Int-pattern RPL_CHANINFO_BANS           = 292--pattern RPL_HELPTLR                 :: Int-pattern RPL_HELPTLR                 = 292--pattern RPL_CHANINFO_INVITE         :: Int-pattern RPL_CHANINFO_INVITE         = 293--pattern RPL_HELPHLP                 :: Int-pattern RPL_HELPHLP                 = 293--pattern RPL_CHANINFO_INVITES        :: Int-pattern RPL_CHANINFO_INVITES        = 294--pattern RPL_HELPFWD                 :: Int-pattern RPL_HELPFWD                 = 294--pattern RPL_CHANINFO_KICK           :: Int-pattern RPL_CHANINFO_KICK           = 295--pattern RPL_HELPIGN                 :: Int-pattern RPL_HELPIGN                 = 295--pattern RPL_CHANINFO_KICKS          :: Int-pattern RPL_CHANINFO_KICKS          = 296--pattern RPL_END_CHANINFO            :: Int-pattern RPL_END_CHANINFO            = 299--pattern RPL_NONE                    :: Int-pattern RPL_NONE                    = 300--pattern RPL_AWAY                    :: Int-pattern RPL_AWAY                    = 301--pattern RPL_USERHOST                :: Int-pattern RPL_USERHOST                = 302--pattern RPL_ISON                    :: Int-pattern RPL_ISON                    = 303--pattern RPL_TEXT                    :: Int-pattern RPL_TEXT                    = 304--pattern RPL_UNAWAY                  :: Int-pattern RPL_UNAWAY                  = 305--pattern RPL_NOWAWAY                 :: Int-pattern RPL_NOWAWAY                 = 306--pattern RPL_WHOISREGNICK            :: Int-pattern RPL_WHOISREGNICK            = 307--pattern RPL_SUSERHOST               :: Int-pattern RPL_SUSERHOST               = 307--pattern RPL_NOTIFYACTION            :: Int-pattern RPL_NOTIFYACTION            = 308--pattern RPL_WHOISADMIN              :: Int-pattern RPL_WHOISADMIN              = 308--pattern RPL_NICKTRACE               :: Int-pattern RPL_NICKTRACE               = 309--pattern RPL_WHOISSADMIN             :: Int-pattern RPL_WHOISSADMIN             = 309--pattern RPL_WHOISHELPER             :: Int-pattern RPL_WHOISHELPER             = 309--pattern RPL_WHOISSVCMSG             :: Int-pattern RPL_WHOISSVCMSG             = 310--pattern RPL_WHOISHELPOP             :: Int-pattern RPL_WHOISHELPOP             = 310--pattern RPL_WHOISSERVICE            :: Int-pattern RPL_WHOISSERVICE            = 310--pattern RPL_WHOISUSER               :: Int-pattern RPL_WHOISUSER               = 311--pattern RPL_WHOISSERVER             :: Int-pattern RPL_WHOISSERVER             = 312--pattern RPL_WHOISOPERATOR           :: Int-pattern RPL_WHOISOPERATOR           = 313--pattern RPL_WHOWASUSER              :: Int-pattern RPL_WHOWASUSER              = 314--pattern RPL_ENDOFWHO                :: Int-pattern RPL_ENDOFWHO                = 315--pattern RPL_WHOISCHANOP             :: Int-pattern RPL_WHOISCHANOP             = 316--pattern RPL_WHOISIDLE               :: Int-pattern RPL_WHOISIDLE               = 317--pattern RPL_ENDOFWHOIS              :: Int-pattern RPL_ENDOFWHOIS              = 318--pattern RPL_WHOISCHANNELS           :: Int-pattern RPL_WHOISCHANNELS           = 319--pattern RPL_WHOISVIRT               :: Int-pattern RPL_WHOISVIRT               = 320--pattern RPL_WHOIS_HIDDEN            :: Int-pattern RPL_WHOIS_HIDDEN            = 320--pattern RPL_WHOISSPECIAL            :: Int-pattern RPL_WHOISSPECIAL            = 320--pattern RPL_LISTSTART               :: Int-pattern RPL_LISTSTART               = 321--pattern RPL_LIST                    :: Int-pattern RPL_LIST                    = 322--pattern RPL_LISTEND                 :: Int-pattern RPL_LISTEND                 = 323--pattern RPL_CHANNELMODEIS           :: Int-pattern RPL_CHANNELMODEIS           = 324--pattern RPL_UNIQOPIS                :: Int-pattern RPL_UNIQOPIS                = 325--pattern RPL_CHANNELPASSIS           :: Int-pattern RPL_CHANNELPASSIS           = 325--pattern RPL_NOCHANPASS              :: Int-pattern RPL_NOCHANPASS              = 326--pattern RPL_CHPASSUNKNOWN           :: Int-pattern RPL_CHPASSUNKNOWN           = 327--pattern RPL_CHANNEL_URL             :: Int-pattern RPL_CHANNEL_URL             = 328--pattern RPL_CREATIONTIME            :: Int-pattern RPL_CREATIONTIME            = 329--pattern RPL_WHOWAS_TIME             :: Int-pattern RPL_WHOWAS_TIME             = 330--pattern RPL_WHOISACCOUNT            :: Int-pattern RPL_WHOISACCOUNT            = 330--pattern RPL_NOTOPIC                 :: Int-pattern RPL_NOTOPIC                 = 331--pattern RPL_TOPIC                   :: Int-pattern RPL_TOPIC                   = 332--pattern RPL_TOPICWHOTIME            :: Int-pattern RPL_TOPICWHOTIME            = 333--pattern RPL_LISTUSAGE               :: Int-pattern RPL_LISTUSAGE               = 334--pattern RPL_COMMANDSYNTAX           :: Int-pattern RPL_COMMANDSYNTAX           = 334--pattern RPL_LISTSYNTAX              :: Int-pattern RPL_LISTSYNTAX              = 334--pattern RPL_CHANPASSOK              :: Int-pattern RPL_CHANPASSOK              = 338--pattern RPL_WHOISACTUALLY           :: Int-pattern RPL_WHOISACTUALLY           = 338--pattern RPL_BADCHANPASS             :: Int-pattern RPL_BADCHANPASS             = 339--pattern RPL_INVITING                :: Int-pattern RPL_INVITING                = 341--pattern RPL_SUMMONING               :: Int-pattern RPL_SUMMONING               = 342--pattern RPL_INVITED                 :: Int-pattern RPL_INVITED                 = 345--pattern RPL_INVITELIST              :: Int-pattern RPL_INVITELIST              = 346--pattern RPL_ENDOFINVITELIST         :: Int-pattern RPL_ENDOFINVITELIST         = 347--pattern RPL_EXCEPTLIST              :: Int-pattern RPL_EXCEPTLIST              = 348--pattern RPL_ENDOFEXCEPTLIST         :: Int-pattern RPL_ENDOFEXCEPTLIST         = 349--pattern RPL_VERSION                 :: Int-pattern RPL_VERSION                 = 351--pattern RPL_WHOREPLY                :: Int-pattern RPL_WHOREPLY                = 352--pattern RPL_NAMREPLY                :: Int-pattern RPL_NAMREPLY                = 353--pattern RPL_WHOSPCRPL               :: Int-pattern RPL_WHOSPCRPL               = 354--pattern RPL_NAMREPLY_               :: Int-pattern RPL_NAMREPLY_               = 355--pattern RPL_KILLDONE                :: Int-pattern RPL_KILLDONE                = 361--pattern RPL_CLOSING                 :: Int-pattern RPL_CLOSING                 = 362--pattern RPL_CLOSEEND                :: Int-pattern RPL_CLOSEEND                = 363--pattern RPL_LINKS                   :: Int-pattern RPL_LINKS                   = 364--pattern RPL_ENDOFLINKS              :: Int-pattern RPL_ENDOFLINKS              = 365--pattern RPL_ENDOFNAMES              :: Int-pattern RPL_ENDOFNAMES              = 366--pattern RPL_BANLIST                 :: Int-pattern RPL_BANLIST                 = 367--pattern RPL_ENDOFBANLIST            :: Int-pattern RPL_ENDOFBANLIST            = 368--pattern RPL_ENDOFWHOWAS             :: Int-pattern RPL_ENDOFWHOWAS             = 369--pattern RPL_INFO                    :: Int-pattern RPL_INFO                    = 371--pattern RPL_MOTD                    :: Int-pattern RPL_MOTD                    = 372--pattern RPL_INFOSTART               :: Int-pattern RPL_INFOSTART               = 373--pattern RPL_ENDOFINFO               :: Int-pattern RPL_ENDOFINFO               = 374--pattern RPL_MOTDSTART               :: Int-pattern RPL_MOTDSTART               = 375--pattern RPL_ENDOFMOTD               :: Int-pattern RPL_ENDOFMOTD               = 376--pattern RPL_KICKEXPIRED             :: Int-pattern RPL_KICKEXPIRED             = 377--pattern RPL_SPAM                    :: Int-pattern RPL_SPAM                    = 377--pattern RPL_BANEXPIRED              :: Int-pattern RPL_BANEXPIRED              = 378--pattern RPL_WHOISHOST               :: Int-pattern RPL_WHOISHOST               = 378--pattern RPL_KICKLINKED              :: Int-pattern RPL_KICKLINKED              = 379--pattern RPL_BANLINKED               :: Int-pattern RPL_BANLINKED               = 380--pattern RPL_YOURHELPER              :: Int-pattern RPL_YOURHELPER              = 380--pattern RPL_YOUREOPER               :: Int-pattern RPL_YOUREOPER               = 381--pattern RPL_REHASHING               :: Int-pattern RPL_REHASHING               = 382--pattern RPL_YOURESERVICE            :: Int-pattern RPL_YOURESERVICE            = 383--pattern RPL_MYPORTIS                :: Int-pattern RPL_MYPORTIS                = 384--pattern RPL_NOTOPERANYMORE          :: Int-pattern RPL_NOTOPERANYMORE          = 385--pattern RPL_QLIST                   :: Int-pattern RPL_QLIST                   = 386--pattern RPL_IRCOPS                  :: Int-pattern RPL_IRCOPS                  = 386--pattern RPL_ENDOFQLIST              :: Int-pattern RPL_ENDOFQLIST              = 387--pattern RPL_ENDOFIRCOPS             :: Int-pattern RPL_ENDOFIRCOPS             = 387--pattern RPL_TIME                    :: Int-pattern RPL_TIME                    = 391--pattern RPL_USERSSTART              :: Int-pattern RPL_USERSSTART              = 392--pattern RPL_USERS                   :: Int-pattern RPL_USERS                   = 393--pattern RPL_ENDOFUSERS              :: Int-pattern RPL_ENDOFUSERS              = 394--pattern RPL_NOUSERS                 :: Int-pattern RPL_NOUSERS                 = 395--pattern RPL_HOSTHIDDEN              :: Int-pattern RPL_HOSTHIDDEN              = 396--pattern ERR_UNKNOWNERROR            :: Int-pattern ERR_UNKNOWNERROR            = 400--pattern ERR_NOSUCHNICK              :: Int-pattern ERR_NOSUCHNICK              = 401--pattern ERR_NOSUCHSERVER            :: Int-pattern ERR_NOSUCHSERVER            = 402--pattern ERR_NOSUCHCHANNEL           :: Int-pattern ERR_NOSUCHCHANNEL           = 403--pattern ERR_CANNOTSENDTOCHAN        :: Int-pattern ERR_CANNOTSENDTOCHAN        = 404--pattern ERR_TOOMANYCHANNELS         :: Int-pattern ERR_TOOMANYCHANNELS         = 405--pattern ERR_WASNOSUCHNICK           :: Int-pattern ERR_WASNOSUCHNICK           = 406--pattern ERR_TOOMANYTARGETS          :: Int-pattern ERR_TOOMANYTARGETS          = 407--pattern ERR_NOSUCHSERVICE           :: Int-pattern ERR_NOSUCHSERVICE           = 408--pattern ERR_NOCOLORSONCHAN          :: Int-pattern ERR_NOCOLORSONCHAN          = 408--pattern ERR_NOORIGIN                :: Int-pattern ERR_NOORIGIN                = 409--pattern ERR_NORECIPIENT             :: Int-pattern ERR_NORECIPIENT             = 411--pattern ERR_NOTEXTTOSEND            :: Int-pattern ERR_NOTEXTTOSEND            = 412--pattern ERR_NOTOPLEVEL              :: Int-pattern ERR_NOTOPLEVEL              = 413--pattern ERR_WILDTOPLEVEL            :: Int-pattern ERR_WILDTOPLEVEL            = 414--pattern ERR_BADMASK                 :: Int-pattern ERR_BADMASK                 = 415--pattern ERR_TOOMANYMATCHES          :: Int-pattern ERR_TOOMANYMATCHES          = 416--pattern ERR_QUERYTOOLONG            :: Int-pattern ERR_QUERYTOOLONG            = 416--pattern ERR_LENGTHTRUNCATED         :: Int-pattern ERR_LENGTHTRUNCATED         = 419--pattern ERR_UNKNOWNCOMMAND          :: Int-pattern ERR_UNKNOWNCOMMAND          = 421--pattern ERR_NOMOTD                  :: Int-pattern ERR_NOMOTD                  = 422--pattern ERR_NOADMININFO             :: Int-pattern ERR_NOADMININFO             = 423--pattern ERR_FILEERROR               :: Int-pattern ERR_FILEERROR               = 424--pattern ERR_NOOPERMOTD              :: Int-pattern ERR_NOOPERMOTD              = 425--pattern ERR_TOOMANYAWAY             :: Int-pattern ERR_TOOMANYAWAY             = 429--pattern ERR_EVENTNICKCHANGE         :: Int-pattern ERR_EVENTNICKCHANGE         = 430--pattern ERR_NONICKNAMEGIVEN         :: Int-pattern ERR_NONICKNAMEGIVEN         = 431--pattern ERR_ERRONEUSNICKNAME        :: Int-pattern ERR_ERRONEUSNICKNAME        = 432--pattern ERR_NICKNAMEINUSE           :: Int-pattern ERR_NICKNAMEINUSE           = 433--pattern ERR_SERVICENAMEINUSE        :: Int-pattern ERR_SERVICENAMEINUSE        = 434--pattern ERR_NORULES                 :: Int-pattern ERR_NORULES                 = 434--pattern ERR_SERVICECONFUSED         :: Int-pattern ERR_SERVICECONFUSED         = 435--pattern ERR_BANONCHAN               :: Int-pattern ERR_BANONCHAN               = 435--pattern ERR_NICKCOLLISION           :: Int-pattern ERR_NICKCOLLISION           = 436--pattern ERR_UNAVAILRESOURCE         :: Int-pattern ERR_UNAVAILRESOURCE         = 437--pattern ERR_BANNICKCHANGE           :: Int-pattern ERR_BANNICKCHANGE           = 437--pattern ERR_NICKTOOFAST             :: Int-pattern ERR_NICKTOOFAST             = 438--pattern ERR_DEAD                    :: Int-pattern ERR_DEAD                    = 438--pattern ERR_TARGETTOOFAST           :: Int-pattern ERR_TARGETTOOFAST           = 439--pattern ERR_SERVICESDOWN            :: Int-pattern ERR_SERVICESDOWN            = 440--pattern ERR_USERNOTINCHANNEL        :: Int-pattern ERR_USERNOTINCHANNEL        = 441--pattern ERR_NOTONCHANNEL            :: Int-pattern ERR_NOTONCHANNEL            = 442--pattern ERR_USERONCHANNEL           :: Int-pattern ERR_USERONCHANNEL           = 443--pattern ERR_NOLOGIN                 :: Int-pattern ERR_NOLOGIN                 = 444--pattern ERR_SUMMONDISABLED          :: Int-pattern ERR_SUMMONDISABLED          = 445--pattern ERR_USERSDISABLED           :: Int-pattern ERR_USERSDISABLED           = 446--pattern ERR_NONICKCHANGE            :: Int-pattern ERR_NONICKCHANGE            = 447--pattern ERR_NOTIMPLEMENTED          :: Int-pattern ERR_NOTIMPLEMENTED          = 449--pattern ERR_NOTREGISTERED           :: Int-pattern ERR_NOTREGISTERED           = 451--pattern ERR_IDCOLLISION             :: Int-pattern ERR_IDCOLLISION             = 452--pattern ERR_NICKLOST                :: Int-pattern ERR_NICKLOST                = 453--pattern ERR_HOSTILENAME             :: Int-pattern ERR_HOSTILENAME             = 455--pattern ERR_ACCEPTFULL              :: Int-pattern ERR_ACCEPTFULL              = 456--pattern ERR_ACCEPTEXIST             :: Int-pattern ERR_ACCEPTEXIST             = 457--pattern ERR_ACCEPTNOT               :: Int-pattern ERR_ACCEPTNOT               = 458--pattern ERR_NOHIDING                :: Int-pattern ERR_NOHIDING                = 459--pattern ERR_NOTFORHALFOPS           :: Int-pattern ERR_NOTFORHALFOPS           = 460--pattern ERR_NEEDMOREPARAMS          :: Int-pattern ERR_NEEDMOREPARAMS          = 461--pattern ERR_ALREADYREGISTERED       :: Int-pattern ERR_ALREADYREGISTERED       = 462--pattern ERR_NOPERMFORHOST           :: Int-pattern ERR_NOPERMFORHOST           = 463--pattern ERR_PASSWDMISMATCH          :: Int-pattern ERR_PASSWDMISMATCH          = 464--pattern ERR_YOUREBANNEDCREEP        :: Int-pattern ERR_YOUREBANNEDCREEP        = 465--pattern ERR_YOUWILLBEBANNED         :: Int-pattern ERR_YOUWILLBEBANNED         = 466--pattern ERR_KEYSET                  :: Int-pattern ERR_KEYSET                  = 467--pattern ERR_INVALIDUSERNAME         :: Int-pattern ERR_INVALIDUSERNAME         = 468--pattern ERR_ONLYSERVERSCANCHANGE    :: Int-pattern ERR_ONLYSERVERSCANCHANGE    = 468--pattern ERR_LINKSET                 :: Int-pattern ERR_LINKSET                 = 469--pattern ERR_LINKCHANNEL             :: Int-pattern ERR_LINKCHANNEL             = 470--pattern ERR_KICKEDFROMCHAN          :: Int-pattern ERR_KICKEDFROMCHAN          = 470--pattern ERR_CHANNELISFULL           :: Int-pattern ERR_CHANNELISFULL           = 471--pattern ERR_UNKNOWNMODE             :: Int-pattern ERR_UNKNOWNMODE             = 472--pattern ERR_INVITEONLYCHAN          :: Int-pattern ERR_INVITEONLYCHAN          = 473--pattern ERR_BANNEDFROMCHAN          :: Int-pattern ERR_BANNEDFROMCHAN          = 474--pattern ERR_BADCHANNELKEY           :: Int-pattern ERR_BADCHANNELKEY           = 475--pattern ERR_BADCHANMASK             :: Int-pattern ERR_BADCHANMASK             = 476--pattern ERR_NOCHANMODES             :: Int-pattern ERR_NOCHANMODES             = 477--pattern ERR_NEEDREGGEDNICK          :: Int-pattern ERR_NEEDREGGEDNICK          = 477--pattern ERR_BANLISTFULL             :: Int-pattern ERR_BANLISTFULL             = 478--pattern ERR_BADCHANNAME             :: Int-pattern ERR_BADCHANNAME             = 479--pattern ERR_LINKFAIL                :: Int-pattern ERR_LINKFAIL                = 479--pattern ERR_NOULINE                 :: Int-pattern ERR_NOULINE                 = 480--pattern ERR_CANNOTKNOCK             :: Int-pattern ERR_CANNOTKNOCK             = 480--pattern ERR_NOPRIVILEGES            :: Int-pattern ERR_NOPRIVILEGES            = 481--pattern ERR_CHANOPRIVSNEEDED        :: Int-pattern ERR_CHANOPRIVSNEEDED        = 482--pattern ERR_CANTKILLSERVER          :: Int-pattern ERR_CANTKILLSERVER          = 483--pattern ERR_RESTRICTED              :: Int-pattern ERR_RESTRICTED              = 484--pattern ERR_ISCHANSERVICE           :: Int-pattern ERR_ISCHANSERVICE           = 484--pattern ERR_DESYNC                  :: Int-pattern ERR_DESYNC                  = 484--pattern ERR_ATTACKDENY              :: Int-pattern ERR_ATTACKDENY              = 484--pattern ERR_UNIQOPRIVSNEEDED        :: Int-pattern ERR_UNIQOPRIVSNEEDED        = 485--pattern ERR_KILLDENY                :: Int-pattern ERR_KILLDENY                = 485--pattern ERR_CANTKICKADMIN           :: Int-pattern ERR_CANTKICKADMIN           = 485--pattern ERR_ISREALSERVICE           :: Int-pattern ERR_ISREALSERVICE           = 485--pattern ERR_NONONREG                :: Int-pattern ERR_NONONREG                = 486--pattern ERR_HTMDISABLED             :: Int-pattern ERR_HTMDISABLED             = 486--pattern ERR_ACCOUNTONLY             :: Int-pattern ERR_ACCOUNTONLY             = 486--pattern ERR_CHANTOORECENT           :: Int-pattern ERR_CHANTOORECENT           = 487--pattern ERR_MSGSERVICES             :: Int-pattern ERR_MSGSERVICES             = 487--pattern ERR_TSLESSCHAN              :: Int-pattern ERR_TSLESSCHAN              = 488--pattern ERR_VOICENEEDED             :: Int-pattern ERR_VOICENEEDED             = 489--pattern ERR_SECUREONLYCHAN          :: Int-pattern ERR_SECUREONLYCHAN          = 489--pattern ERR_NOOPERHOST              :: Int-pattern ERR_NOOPERHOST              = 491--pattern ERR_NOSERVICEHOST           :: Int-pattern ERR_NOSERVICEHOST           = 492--pattern ERR_NOFEATURE               :: Int-pattern ERR_NOFEATURE               = 493--pattern ERR_BADFEATURE              :: Int-pattern ERR_BADFEATURE              = 494--pattern ERR_BADLOGTYPE              :: Int-pattern ERR_BADLOGTYPE              = 495--pattern ERR_BADLOGSYS               :: Int-pattern ERR_BADLOGSYS               = 496--pattern ERR_BADLOGVALUE             :: Int-pattern ERR_BADLOGVALUE             = 497--pattern ERR_ISOPERLCHAN             :: Int-pattern ERR_ISOPERLCHAN             = 498--pattern ERR_CHANOWNPRIVNEEDED       :: Int-pattern ERR_CHANOWNPRIVNEEDED       = 499--pattern ERR_UMODEUNKNOWNFLAG        :: Int-pattern ERR_UMODEUNKNOWNFLAG        = 501--pattern ERR_USERSDONTMATCH          :: Int-pattern ERR_USERSDONTMATCH          = 502--pattern ERR_GHOSTEDCLIENT           :: Int-pattern ERR_GHOSTEDCLIENT           = 503--pattern ERR_VWORLDWARN              :: Int-pattern ERR_VWORLDWARN              = 503--pattern ERR_USERNOTONSERV           :: Int-pattern ERR_USERNOTONSERV           = 504--pattern ERR_SILELISTFULL            :: Int-pattern ERR_SILELISTFULL            = 511--pattern ERR_TOOMANYWATCH            :: Int-pattern ERR_TOOMANYWATCH            = 512--pattern ERR_BADPING                 :: Int-pattern ERR_BADPING                 = 513--pattern ERR_INVALID_ERROR           :: Int-pattern ERR_INVALID_ERROR           = 514--pattern ERR_TOOMANYDCC              :: Int-pattern ERR_TOOMANYDCC              = 514--pattern ERR_BADEXPIRE               :: Int-pattern ERR_BADEXPIRE               = 515--pattern ERR_DONTCHEAT               :: Int-pattern ERR_DONTCHEAT               = 516--pattern ERR_DISABLED                :: Int-pattern ERR_DISABLED                = 517--pattern ERR_NOINVITE                :: Int-pattern ERR_NOINVITE                = 518--pattern ERR_LONGMASK                :: Int-pattern ERR_LONGMASK                = 518--pattern ERR_ADMONLY                 :: Int-pattern ERR_ADMONLY                 = 519--pattern ERR_TOOMANYUSERS            :: Int-pattern ERR_TOOMANYUSERS            = 519--pattern ERR_OPERONLY                :: Int-pattern ERR_OPERONLY                = 520--pattern ERR_MASKTOOWIDE             :: Int-pattern ERR_MASKTOOWIDE             = 520--pattern ERR_WHOTRUNC                :: Int-pattern ERR_WHOTRUNC                = 520--pattern ERR_LISTSYNTAX              :: Int-pattern ERR_LISTSYNTAX              = 521--pattern ERR_WHOSYNTAX               :: Int-pattern ERR_WHOSYNTAX               = 522--pattern ERR_WHOLIMEXCEED            :: Int-pattern ERR_WHOLIMEXCEED            = 523--pattern ERR_QUARANTINED             :: Int-pattern ERR_QUARANTINED             = 524--pattern ERR_OPERSPVERIFY            :: Int-pattern ERR_OPERSPVERIFY            = 524--pattern ERR_REMOTEPFX               :: Int-pattern ERR_REMOTEPFX               = 525--pattern ERR_PFXUNROUTABLE           :: Int-pattern ERR_PFXUNROUTABLE           = 526--pattern ERR_BADHOSTMASK             :: Int-pattern ERR_BADHOSTMASK             = 550--pattern ERR_HOSTUNAVAIL             :: Int-pattern ERR_HOSTUNAVAIL             = 551--pattern ERR_USINGSLINE              :: Int-pattern ERR_USINGSLINE              = 552--pattern ERR_STATSSLINE              :: Int-pattern ERR_STATSSLINE              = 553--pattern RPL_LOGON                   :: Int-pattern RPL_LOGON                   = 600--pattern RPL_LOGOFF                  :: Int-pattern RPL_LOGOFF                  = 601--pattern RPL_WATCHOFF                :: Int-pattern RPL_WATCHOFF                = 602--pattern RPL_WATCHSTAT               :: Int-pattern RPL_WATCHSTAT               = 603--pattern RPL_NOWON                   :: Int-pattern RPL_NOWON                   = 604--pattern RPL_NOWOFF                  :: Int-pattern RPL_NOWOFF                  = 605--pattern RPL_WATCHLIST               :: Int-pattern RPL_WATCHLIST               = 606--pattern RPL_ENDOFWATCHLIST          :: Int-pattern RPL_ENDOFWATCHLIST          = 607--pattern RPL_WATCHCLEAR              :: Int-pattern RPL_WATCHCLEAR              = 608--pattern RPL_ISOPER                  :: Int-pattern RPL_ISOPER                  = 610--pattern RPL_ISLOCOP                 :: Int-pattern RPL_ISLOCOP                 = 611--pattern RPL_ISNOTOPER               :: Int-pattern RPL_ISNOTOPER               = 612--pattern RPL_ENDOFISOPER             :: Int-pattern RPL_ENDOFISOPER             = 613--pattern RPL_DCCSTATUS               :: Int-pattern RPL_DCCSTATUS               = 617--pattern RPL_DCCLIST                 :: Int-pattern RPL_DCCLIST                 = 618--pattern RPL_ENDOFDCCLIST            :: Int-pattern RPL_ENDOFDCCLIST            = 619--pattern RPL_WHOWASHOST              :: Int-pattern RPL_WHOWASHOST              = 619--pattern RPL_DCCINFO                 :: Int-pattern RPL_DCCINFO                 = 620--pattern RPL_RULES                   :: Int-pattern RPL_RULES                   = 621--pattern RPL_ENDOFO                  :: Int-pattern RPL_ENDOFO                  = 626--pattern RPL_SETTINGS                :: Int-pattern RPL_SETTINGS                = 630--pattern RPL_ENDOFSETTINGS           :: Int-pattern RPL_ENDOFSETTINGS           = 631--pattern RPL_DUMPING                 :: Int-pattern RPL_DUMPING                 = 640--pattern RPL_DUMPRPL                 :: Int-pattern RPL_DUMPRPL                 = 641--pattern RPL_EODUMP                  :: Int-pattern RPL_EODUMP                  = 642--pattern RPL_TRACEROUTE_HOP          :: Int-pattern RPL_TRACEROUTE_HOP          = 660--pattern RPL_TRACEROUTE_START        :: Int-pattern RPL_TRACEROUTE_START        = 661--pattern RPL_MODECHANGEWARN          :: Int-pattern RPL_MODECHANGEWARN          = 662--pattern RPL_CHANREDIR               :: Int-pattern RPL_CHANREDIR               = 663--pattern RPL_SERVMODEIS              :: Int-pattern RPL_SERVMODEIS              = 664--pattern RPL_OTHERUMODEIS            :: Int-pattern RPL_OTHERUMODEIS            = 665--pattern RPL_ENDOF_GENERIC           :: Int-pattern RPL_ENDOF_GENERIC           = 666--pattern RPL_WHOWASDETAILS           :: Int-pattern RPL_WHOWASDETAILS           = 670--pattern RPL_WHOISSECURE             :: Int-pattern RPL_WHOISSECURE             = 671--pattern RPL_UNKNOWNMODES            :: Int-pattern RPL_UNKNOWNMODES            = 672--pattern RPL_CANNOTSETMODES          :: Int-pattern RPL_CANNOTSETMODES          = 673--pattern RPL_LUSERSTAFF              :: Int-pattern RPL_LUSERSTAFF              = 678--pattern RPL_TIMEONSERVERIS          :: Int-pattern RPL_TIMEONSERVERIS          = 679--pattern RPL_NETWORKS                :: Int-pattern RPL_NETWORKS                = 682--pattern RPL_YOURLANGUAGEIS          :: Int-pattern RPL_YOURLANGUAGEIS          = 687--pattern RPL_LANGUAGE                :: Int-pattern RPL_LANGUAGE                = 688--pattern RPL_WHOISSTAFF              :: Int-pattern RPL_WHOISSTAFF              = 689--pattern RPL_WHOISLANGUAGE           :: Int-pattern RPL_WHOISLANGUAGE           = 690--pattern RPL_ENDOFMODLIST            :: Int-pattern RPL_ENDOFMODLIST            = 703--pattern RPL_HELPSTART               :: Int-pattern RPL_HELPSTART               = 704--pattern RPL_HELPTXT                 :: Int-pattern RPL_HELPTXT                 = 705--pattern RPL_ENDOFHELP               :: Int-pattern RPL_ENDOFHELP               = 706--pattern RPL_ETRACEFULL              :: Int-pattern RPL_ETRACEFULL              = 708--pattern RPL_ETRACE                  :: Int-pattern RPL_ETRACE                  = 709--pattern RPL_KNOCK                   :: Int-pattern RPL_KNOCK                   = 710--pattern RPL_KNOCKDLVR               :: Int-pattern RPL_KNOCKDLVR               = 711--pattern ERR_TOOMANYKNOCK            :: Int-pattern ERR_TOOMANYKNOCK            = 712--pattern ERR_CHANOPEN                :: Int-pattern ERR_CHANOPEN                = 713--pattern ERR_KNOCKONCHAN             :: Int-pattern ERR_KNOCKONCHAN             = 714--pattern ERR_KNOCKDISABLED           :: Int-pattern ERR_KNOCKDISABLED           = 715--pattern RPL_TARGUMODEG              :: Int-pattern RPL_TARGUMODEG              = 716--pattern RPL_TARGNOTIFY              :: Int-pattern RPL_TARGNOTIFY              = 717--pattern RPL_UMODEGMSG               :: Int-pattern RPL_UMODEGMSG               = 718--pattern RPL_ENDOFOMOTD              :: Int-pattern RPL_ENDOFOMOTD              = 722--pattern ERR_NOPRIVS                 :: Int-pattern ERR_NOPRIVS                 = 723--pattern RPL_TESTMARK                :: Int-pattern RPL_TESTMARK                = 724--pattern RPL_TESTLINE                :: Int-pattern RPL_TESTLINE                = 725--pattern RPL_NOTESTLINE              :: Int-pattern RPL_NOTESTLINE              = 726--pattern RPL_QUIETLIST               :: Int-pattern RPL_QUIETLIST               = 728--pattern RPL_ENDOFQUIETLIST          :: Int-pattern RPL_ENDOFQUIETLIST          = 729--pattern RPL_XINFO                   :: Int-pattern RPL_XINFO                   = 771--pattern RPL_XINFOSTART              :: Int-pattern RPL_XINFOSTART              = 773--pattern RPL_XINFOEND                :: Int-pattern RPL_XINFOEND                = 774--pattern ERR_CANNOTDOCOMMAND         :: Int-pattern ERR_CANNOTDOCOMMAND         = 972--pattern ERR_CANNOTCHANGEUMODE       :: Int-pattern ERR_CANNOTCHANGEUMODE       = 973--pattern ERR_CANNOTCHANGECHANMODE    :: Int-pattern ERR_CANNOTCHANGECHANMODE    = 974--pattern ERR_CANNOTCHANGESERVERMODE  :: Int-pattern ERR_CANNOTCHANGESERVERMODE  = 975--pattern ERR_CANNOTSENDTONICK        :: Int-pattern ERR_CANNOTSENDTONICK        = 976--pattern ERR_UNKNOWNSERVERMODE       :: Int-pattern ERR_UNKNOWNSERVERMODE       = 977--pattern ERR_SERVERMODELOCK          :: Int-pattern ERR_SERVERMODELOCK          = 979--pattern ERR_BADCHARENCODING         :: Int-pattern ERR_BADCHARENCODING         = 980--pattern ERR_TOOMANYLANGUAGES        :: Int-pattern ERR_TOOMANYLANGUAGES        = 981--pattern ERR_NOLANGUAGE              :: Int-pattern ERR_NOLANGUAGE              = 982--pattern ERR_TEXTTOOSHORT            :: Int-pattern ERR_TEXTTOOSHORT            = 983--pattern ERR_NUMERIC_ERR             :: Int-pattern ERR_NUMERIC_ERR             = 999+{-# Language PatternSynonyms, OverloadedStrings #-}+{-# OPTIONS_GHC -Wno-missing-pattern-synonym-signatures #-}++{-|+Module      : Irc.Codes+Description : Helpers for interpreting IRC reply codes+Copyright   : (c) Eric Mertens, 2016+License     : ISC+Maintainer  : emertens@gmail.com++This module defines support for working with IRC's numeric reply+codes. Pattern synonyms are provided for each of the possible IRC reply codes.++Reply code information was extracted from https://www.alien.net.au/irc/irc2numerics.html++-}++module Irc.Codes where++import           Data.Vector (Vector)+import qualified Data.Vector as Vector+import           Data.Text (Text)+import qualified Data.Text as Text++-- | Type of numeric reply codes+newtype ReplyCode = ReplyCode Word++instance Show ReplyCode where+  showsPrec p (ReplyCode x) = showsPrec p x++-- | Categories for reply codes+data ReplyType+  = ClientServerReply -- ^ 0-99 Messages between client and server+  | CommandReply      -- ^ 200-399 Responses to commands+  | ErrorReply        -- ^ 200-399 Errors+  | UnknownReply      -- ^ Uncategorized++pattern RPL_WELCOME                 = ReplyCode 001+pattern RPL_YOURHOST                = ReplyCode 002+pattern RPL_CREATED                 = ReplyCode 003+pattern RPL_MYINFO                  = ReplyCode 004+pattern RPL_ISUPPORT                = ReplyCode 005+pattern RPL_SNOMASK                 = ReplyCode 008+pattern RPL_STATMEMTOT              = ReplyCode 009+pattern RPL_REDIR                   = ReplyCode 010+pattern RPL_YOURCOOKIE              = ReplyCode 014+pattern RPL_MAP                     = ReplyCode 015+pattern RPL_MAPEND                  = ReplyCode 017+pattern RPL_YOURID                  = ReplyCode 042+pattern RPL_SAVENICK                = ReplyCode 043+pattern RPL_ATTEMPTINGJUNC          = ReplyCode 050+pattern RPL_ATTEMPTINGREROUTE       = ReplyCode 051+pattern RPL_TRACELINK               = ReplyCode 200+pattern RPL_TRACECONNECTING         = ReplyCode 201+pattern RPL_TRACEHANDSHAKE          = ReplyCode 202+pattern RPL_TRACEUNKNOWN            = ReplyCode 203+pattern RPL_TRACEOPERATOR           = ReplyCode 204+pattern RPL_TRACEUSER               = ReplyCode 205+pattern RPL_TRACESERVER             = ReplyCode 206+pattern RPL_TRACESERVICE            = ReplyCode 207+pattern RPL_TRACENEWTYPE            = ReplyCode 208+pattern RPL_TRACECLASS              = ReplyCode 209+pattern RPL_TRACERECONNECT          = ReplyCode 210+pattern RPL_STATS                   = ReplyCode 210+pattern RPL_STATSLINKINFO           = ReplyCode 211+pattern RPL_STATSCOMMANDS           = ReplyCode 212+pattern RPL_STATSCLINE              = ReplyCode 213+pattern RPL_STATSNLINE              = ReplyCode 214+pattern RPL_STATSILINE              = ReplyCode 215+pattern RPL_STATSKLINE              = ReplyCode 216+pattern RPL_STATSQLINE              = ReplyCode 217+pattern RPL_STATSYLINE              = ReplyCode 218+pattern RPL_ENDOFSTATS              = ReplyCode 219+pattern RPL_STATSPLINE              = ReplyCode 220+pattern RPL_UMODEIS                 = ReplyCode 221+pattern RPL_SQLINE_NICK             = ReplyCode 222+pattern RPL_STATSDLINE              = ReplyCode 225+pattern RPL_STATSZLINE              = ReplyCode 225+pattern RPL_STATSCOUNT              = ReplyCode 226+pattern RPL_SERVICEINFO             = ReplyCode 231+pattern RPL_ENDOFSERVICES           = ReplyCode 232+pattern RPL_SERVICE                 = ReplyCode 233+pattern RPL_SERVLIST                = ReplyCode 234+pattern RPL_SERVLISTEND             = ReplyCode 235+pattern RPL_STATSVERBOSE            = ReplyCode 236+pattern RPL_STATSIAUTH              = ReplyCode 239+pattern RPL_STATSLLINE              = ReplyCode 241+pattern RPL_STATSUPTIME             = ReplyCode 242+pattern RPL_STATSOLINE              = ReplyCode 243+pattern RPL_STATSHLINE              = ReplyCode 244+pattern RPL_STATSSLINE              = ReplyCode 245+pattern RPL_STATSPING               = ReplyCode 246+pattern RPL_STATSXLINE              = ReplyCode 247+pattern RPL_STATSULINE              = ReplyCode 248+pattern RPL_STATSDEBUG              = ReplyCode 249+pattern RPL_STATSCONN               = ReplyCode 250+pattern RPL_LUSERCLIENT             = ReplyCode 251+pattern RPL_LUSEROP                 = ReplyCode 252+pattern RPL_LUSERUNKNOWN            = ReplyCode 253+pattern RPL_LUSERCHANNELS           = ReplyCode 254+pattern RPL_LUSERME                 = ReplyCode 255+pattern RPL_ADMINME                 = ReplyCode 256+pattern RPL_ADMINLOC1               = ReplyCode 257+pattern RPL_ADMINLOC2               = ReplyCode 258+pattern RPL_ADMINEMAIL              = ReplyCode 259+pattern RPL_TRACELOG                = ReplyCode 261+pattern RPL_ENDOFTRACE              = ReplyCode 262+pattern RPL_LOAD2HI                 = ReplyCode 263+pattern RPL_LOCALUSERS              = ReplyCode 265+pattern RPL_GLOBALUSERS             = ReplyCode 266+pattern RPL_START_NETSTAT           = ReplyCode 267+pattern RPL_NETSTAT                 = ReplyCode 268+pattern RPL_END_NETSTAT             = ReplyCode 269+pattern RPL_PRIVS                   = ReplyCode 270+pattern RPL_SILELIST                = ReplyCode 271+pattern RPL_ENDOFSILELIST           = ReplyCode 272+pattern RPL_NOTIFY                  = ReplyCode 273+pattern RPL_ENDNOTIFY               = ReplyCode 274+pattern RPL_STATSDELTA              = ReplyCode 274+pattern RPL_WHOISCERTFP             = ReplyCode 276+pattern RPL_VCHANLIST               = ReplyCode 277+pattern RPL_VCHANHELP               = ReplyCode 278+pattern RPL_GLIST                   = ReplyCode 280+pattern RPL_ACCEPTLIST              = ReplyCode 281+pattern RPL_ENDOFACCEPT             = ReplyCode 282+pattern RPL_ENDOFJUPELIST           = ReplyCode 283+pattern RPL_FEATURE                 = ReplyCode 284+pattern RPL_DATASTR                 = ReplyCode 290+pattern RPL_END_CHANINFO            = ReplyCode 299+pattern RPL_NONE                    = ReplyCode 300+pattern RPL_AWAY                    = ReplyCode 301+pattern RPL_USERHOST                = ReplyCode 302+pattern RPL_ISON                    = ReplyCode 303+pattern RPL_TEXT                    = ReplyCode 304+pattern RPL_UNAWAY                  = ReplyCode 305+pattern RPL_NOWAWAY                 = ReplyCode 306+pattern RPL_WHOISREGNICK            = ReplyCode 307+pattern RPL_SUSERHOST               = ReplyCode 307+pattern RPL_NOTIFYACTION            = ReplyCode 308+pattern RPL_WHOISADMIN              = ReplyCode 308+pattern RPL_NICKTRACE               = ReplyCode 309+pattern RPL_WHOISSADMIN             = ReplyCode 309+pattern RPL_WHOISHELPER             = ReplyCode 309+pattern RPL_WHOISUSER               = ReplyCode 311+pattern RPL_WHOISSERVER             = ReplyCode 312+pattern RPL_WHOISOPERATOR           = ReplyCode 313+pattern RPL_WHOWASUSER              = ReplyCode 314+pattern RPL_ENDOFWHO                = ReplyCode 315+pattern RPL_WHOISCHANOP             = ReplyCode 316+pattern RPL_WHOISIDLE               = ReplyCode 317+pattern RPL_ENDOFWHOIS              = ReplyCode 318+pattern RPL_WHOISCHANNELS           = ReplyCode 319+pattern RPL_WHOISSPECIAL            = ReplyCode 320+pattern RPL_LISTSTART               = ReplyCode 321+pattern RPL_LIST                    = ReplyCode 322+pattern RPL_LISTEND                 = ReplyCode 323+pattern RPL_CHANNELMODEIS           = ReplyCode 324+pattern RPL_CHANNELMLOCKIS          = ReplyCode 325+pattern RPL_NOCHANPASS              = ReplyCode 326+pattern RPL_CHPASSUNKNOWN           = ReplyCode 327+pattern RPL_CHANNEL_URL             = ReplyCode 328+pattern RPL_CREATIONTIME            = ReplyCode 329+pattern RPL_WHOWAS_TIME             = ReplyCode 330+pattern RPL_WHOISACCOUNT            = ReplyCode 330+pattern RPL_NOTOPIC                 = ReplyCode 331+pattern RPL_TOPIC                   = ReplyCode 332+pattern RPL_TOPICWHOTIME            = ReplyCode 333+pattern RPL_LISTUSAGE               = ReplyCode 334+pattern RPL_COMMANDSYNTAX           = ReplyCode 334+pattern RPL_LISTSYNTAX              = ReplyCode 334+pattern RPL_WHOISACTUALLY           = ReplyCode 338+pattern RPL_BADCHANPASS             = ReplyCode 339+pattern RPL_INVITING                = ReplyCode 341+pattern RPL_SUMMONING               = ReplyCode 342+pattern RPL_INVITED                 = ReplyCode 345+pattern RPL_INVEXLIST               = ReplyCode 346+pattern RPL_ENDOFINVEXLIST          = ReplyCode 347+pattern RPL_EXCEPTLIST              = ReplyCode 348+pattern RPL_ENDOFEXCEPTLIST         = ReplyCode 349+pattern RPL_VERSION                 = ReplyCode 351+pattern RPL_WHOREPLY                = ReplyCode 352+pattern RPL_NAMREPLY                = ReplyCode 353+pattern RPL_WHOSPCRPL               = ReplyCode 354+pattern RPL_NAMREPLY_               = ReplyCode 355+pattern RPL_WHOWASREAL              = ReplyCode 360+pattern RPL_KILLDONE                = ReplyCode 361+pattern RPL_CLOSING                 = ReplyCode 362+pattern RPL_CLOSEEND                = ReplyCode 363+pattern RPL_LINKS                   = ReplyCode 364+pattern RPL_ENDOFLINKS              = ReplyCode 365+pattern RPL_ENDOFNAMES              = ReplyCode 366+pattern RPL_BANLIST                 = ReplyCode 367+pattern RPL_ENDOFBANLIST            = ReplyCode 368+pattern RPL_ENDOFWHOWAS             = ReplyCode 369+pattern RPL_INFO                    = ReplyCode 371+pattern RPL_MOTD                    = ReplyCode 372+pattern RPL_INFOSTART               = ReplyCode 373+pattern RPL_ENDOFINFO               = ReplyCode 374+pattern RPL_MOTDSTART               = ReplyCode 375+pattern RPL_ENDOFMOTD               = ReplyCode 376+pattern RPL_WHOISHOST               = ReplyCode 378+pattern RPL_KICKLINKED              = ReplyCode 379+pattern RPL_YOUREOPER               = ReplyCode 381+pattern RPL_REHASHING               = ReplyCode 382+pattern RPL_YOURESERVICE            = ReplyCode 383+pattern RPL_MYPORTIS                = ReplyCode 384+pattern RPL_NOTOPERANYMORE          = ReplyCode 385+pattern RPL_RSACHALLENGE            = ReplyCode 386+pattern RPL_TIME                    = ReplyCode 391+pattern RPL_USERSSTART              = ReplyCode 392+pattern RPL_USERS                   = ReplyCode 393+pattern RPL_ENDOFUSERS              = ReplyCode 394+pattern RPL_NOUSERS                 = ReplyCode 395+pattern RPL_HOSTHIDDEN              = ReplyCode 396+pattern ERR_UNKNOWNERROR            = ReplyCode 400+pattern ERR_NOSUCHNICK              = ReplyCode 401+pattern ERR_NOSUCHSERVER            = ReplyCode 402+pattern ERR_NOSUCHCHANNEL           = ReplyCode 403+pattern ERR_CANNOTSENDTOCHAN        = ReplyCode 404+pattern ERR_TOOMANYCHANNELS         = ReplyCode 405+pattern ERR_WASNOSUCHNICK           = ReplyCode 406+pattern ERR_TOOMANYTARGETS          = ReplyCode 407+pattern ERR_NOORIGIN                = ReplyCode 409+pattern ERR_NORECIPIENT             = ReplyCode 411+pattern ERR_NOTEXTTOSEND            = ReplyCode 412+pattern ERR_NOTOPLEVEL              = ReplyCode 413+pattern ERR_WILDTOPLEVEL            = ReplyCode 414+pattern ERR_BADMASK                 = ReplyCode 415+pattern ERR_TOOMANYMATCHES          = ReplyCode 416+pattern ERR_LENGTHTRUNCATED         = ReplyCode 419+pattern ERR_UNKNOWNCOMMAND          = ReplyCode 421+pattern ERR_NOMOTD                  = ReplyCode 422+pattern ERR_NOADMININFO             = ReplyCode 423+pattern ERR_FILEERROR               = ReplyCode 424+pattern ERR_NOOPERMOTD              = ReplyCode 425+pattern ERR_TOOMANYAWAY             = ReplyCode 429+pattern ERR_EVENTNICKCHANGE         = ReplyCode 430+pattern ERR_NONICKNAMEGIVEN         = ReplyCode 431+pattern ERR_ERRONEUSNICKNAME        = ReplyCode 432+pattern ERR_NICKNAMEINUSE           = ReplyCode 433+pattern ERR_SERVICENAMEINUSE        = ReplyCode 434+pattern ERR_NORULES                 = ReplyCode 434+pattern ERR_BANNICKCHANGE           = ReplyCode 435+pattern ERR_NICKCOLLISION           = ReplyCode 436+pattern ERR_UNAVAILRESOURCE         = ReplyCode 437+pattern ERR_NICKTOOFAST             = ReplyCode 438+pattern ERR_TARGETTOOFAST           = ReplyCode 439+pattern ERR_SERVICESDOWN            = ReplyCode 440+pattern ERR_USERNOTINCHANNEL        = ReplyCode 441+pattern ERR_NOTONCHANNEL            = ReplyCode 442+pattern ERR_USERONCHANNEL           = ReplyCode 443+pattern ERR_NOLOGIN                 = ReplyCode 444+pattern ERR_SUMMONDISABLED          = ReplyCode 445+pattern ERR_USERSDISABLED           = ReplyCode 446+pattern ERR_NONICKCHANGE            = ReplyCode 447+pattern ERR_NOTIMPLEMENTED          = ReplyCode 449+pattern ERR_NOTREGISTERED           = ReplyCode 451+pattern ERR_IDCOLLISION             = ReplyCode 452+pattern ERR_NICKLOST                = ReplyCode 453+pattern ERR_HOSTILENAME             = ReplyCode 455+pattern ERR_ACCEPTFULL              = ReplyCode 456+pattern ERR_ACCEPTEXIST             = ReplyCode 457+pattern ERR_ACCEPTNOT               = ReplyCode 458+pattern ERR_NOHIDING                = ReplyCode 459+pattern ERR_NOTFORHALFOPS           = ReplyCode 460+pattern ERR_NEEDMOREPARAMS          = ReplyCode 461+pattern ERR_ALREADYREGISTERED       = ReplyCode 462+pattern ERR_NOPERMFORHOST           = ReplyCode 463+pattern ERR_PASSWDMISMATCH          = ReplyCode 464+pattern ERR_YOUREBANNEDCREEP        = ReplyCode 465+pattern ERR_YOUWILLBEBANNED         = ReplyCode 466+pattern ERR_KEYSET                  = ReplyCode 467+pattern ERR_INVALIDUSERNAME         = ReplyCode 468+pattern ERR_ONLYSERVERSCANCHANGE    = ReplyCode 468+pattern ERR_LINKSET                 = ReplyCode 469+pattern ERR_LINKCHANNEL             = ReplyCode 470+pattern ERR_CHANNELISFULL           = ReplyCode 471+pattern ERR_UNKNOWNMODE             = ReplyCode 472+pattern ERR_INVITEONLYCHAN          = ReplyCode 473+pattern ERR_BANNEDFROMCHAN          = ReplyCode 474+pattern ERR_BADCHANNELKEY           = ReplyCode 475+pattern ERR_BADCHANMASK             = ReplyCode 476+pattern ERR_NEEDREGGEDNICK          = ReplyCode 477+pattern ERR_BANLISTFULL             = ReplyCode 478+pattern ERR_BADCHANNAME             = ReplyCode 479+pattern ERR_THROTTLE                = ReplyCode 480+pattern ERR_NOPRIVILEGES            = ReplyCode 481+pattern ERR_CHANOPRIVSNEEDED        = ReplyCode 482+pattern ERR_CANTKILLSERVER          = ReplyCode 483+pattern ERR_ISCHANSERVICE           = ReplyCode 484+pattern ERR_BANNEDNICK              = ReplyCode 485+pattern ERR_NONONREG                = ReplyCode 486+pattern ERR_TSLESSCHAN              = ReplyCode 488+pattern ERR_VOICENEEDED             = ReplyCode 489+pattern ERR_NOOPERHOST              = ReplyCode 491+pattern ERR_NOSERVICEHOST           = ReplyCode 492+pattern ERR_NOFEATURE               = ReplyCode 493+pattern ERR_OWNMODE                 = ReplyCode 494+pattern ERR_BADLOGTYPE              = ReplyCode 495+pattern ERR_BADLOGSYS               = ReplyCode 496+pattern ERR_BADLOGVALUE             = ReplyCode 497+pattern ERR_ISOPERLCHAN             = ReplyCode 498+pattern ERR_CHANOWNPRIVNEEDED       = ReplyCode 499+pattern ERR_UMODEUNKNOWNFLAG        = ReplyCode 501+pattern ERR_USERSDONTMATCH          = ReplyCode 502+pattern ERR_GHOSTEDCLIENT           = ReplyCode 503+pattern ERR_USERNOTONSERV           = ReplyCode 504+pattern ERR_SILELISTFULL            = ReplyCode 511+pattern ERR_TOOMANYWATCH            = ReplyCode 512+pattern ERR_WRONGPONG               = ReplyCode 513+pattern ERR_BADEXPIRE               = ReplyCode 515+pattern ERR_DONTCHEAT               = ReplyCode 516+pattern ERR_DISABLED                = ReplyCode 517+pattern ERR_NOINVITE                = ReplyCode 518+pattern ERR_LONGMASK                = ReplyCode 518+pattern ERR_ADMONLY                 = ReplyCode 519+pattern ERR_TOOMANYUSERS            = ReplyCode 519+pattern ERR_OPERONLY                = ReplyCode 520+pattern ERR_MASKTOOWIDE             = ReplyCode 520+pattern ERR_WHOTRUNC                = ReplyCode 520+pattern ERR_LISTSYNTAX              = ReplyCode 521+pattern ERR_WHOSYNTAX               = ReplyCode 522+pattern ERR_WHOLIMEXCEED            = ReplyCode 523+pattern ERR_HELPNOTFOUND            = ReplyCode 524+pattern ERR_REMOTEPFX               = ReplyCode 525+pattern ERR_PFXUNROUTABLE           = ReplyCode 526+pattern ERR_BADHOSTMASK             = ReplyCode 550+pattern ERR_HOSTUNAVAIL             = ReplyCode 551+pattern ERR_USINGSLINE              = ReplyCode 552+pattern ERR_STATSSLINE              = ReplyCode 553+pattern RPL_LOGON                   = ReplyCode 600+pattern RPL_LOGOFF                  = ReplyCode 601+pattern RPL_WATCHOFF                = ReplyCode 602+pattern RPL_WATCHSTAT               = ReplyCode 603+pattern RPL_NOWON                   = ReplyCode 604+pattern RPL_NOWOFF                  = ReplyCode 605+pattern RPL_WATCHLIST               = ReplyCode 606+pattern RPL_ENDOFWATCHLIST          = ReplyCode 607+pattern RPL_WATCHCLEAR              = ReplyCode 608+pattern RPL_ISOPER                  = ReplyCode 610+pattern RPL_ISLOCOP                 = ReplyCode 611+pattern RPL_ISNOTOPER               = ReplyCode 612+pattern RPL_ENDOFISOPER             = ReplyCode 613+pattern RPL_DCCSTATUS               = ReplyCode 617+pattern RPL_DCCLIST                 = ReplyCode 618+pattern RPL_ENDOFDCCLIST            = ReplyCode 619+pattern RPL_WHOWASHOST              = ReplyCode 619+pattern RPL_DCCINFO                 = ReplyCode 620+pattern RPL_RULES                   = ReplyCode 621+pattern RPL_ENDOFO                  = ReplyCode 626+pattern RPL_SETTINGS                = ReplyCode 630+pattern RPL_ENDOFSETTINGS           = ReplyCode 631+pattern RPL_DUMPING                 = ReplyCode 640+pattern RPL_DUMPRPL                 = ReplyCode 641+pattern RPL_EODUMP                  = ReplyCode 642+pattern RPL_TRACEROUTE_HOP          = ReplyCode 660+pattern RPL_TRACEROUTE_START        = ReplyCode 661+pattern RPL_MODECHANGEWARN          = ReplyCode 662+pattern RPL_CHANREDIR               = ReplyCode 663+pattern RPL_SERVMODEIS              = ReplyCode 664+pattern RPL_OTHERUMODEIS            = ReplyCode 665+pattern RPL_ENDOF_GENERIC           = ReplyCode 666+pattern RPL_WHOWASDETAILS           = ReplyCode 670+pattern RPL_WHOISSECURE             = ReplyCode 671+pattern RPL_UNKNOWNMODES            = ReplyCode 672+pattern RPL_CANNOTSETMODES          = ReplyCode 673+pattern RPL_LUSERSTAFF              = ReplyCode 678+pattern RPL_TIMEONSERVERIS          = ReplyCode 679+pattern RPL_NETWORKS                = ReplyCode 682+pattern RPL_YOURLANGUAGEIS          = ReplyCode 687+pattern RPL_LANGUAGE                = ReplyCode 688+pattern RPL_WHOISSTAFF              = ReplyCode 689+pattern RPL_WHOISLANGUAGE           = ReplyCode 690+pattern RPL_MODLIST                 = ReplyCode 702+pattern RPL_ENDOFMODLIST            = ReplyCode 703+pattern RPL_HELPSTART               = ReplyCode 704+pattern RPL_HELPTXT                 = ReplyCode 705+pattern RPL_ENDOFHELP               = ReplyCode 706+pattern ERR_TARGCHANGE              = ReplyCode 707+pattern RPL_ETRACEFULL              = ReplyCode 708+pattern RPL_ETRACE                  = ReplyCode 709+pattern RPL_KNOCK                   = ReplyCode 710+pattern RPL_KNOCKDLVR               = ReplyCode 711+pattern ERR_TOOMANYKNOCK            = ReplyCode 712+pattern ERR_CHANOPEN                = ReplyCode 713+pattern ERR_KNOCKONCHAN             = ReplyCode 714+pattern ERR_KNOCKDISABLED           = ReplyCode 715+pattern RPL_TARGUMODEG              = ReplyCode 716+pattern RPL_TARGNOTIFY              = ReplyCode 717+pattern RPL_UMODEGMSG               = ReplyCode 718+pattern RPL_OMOTDSTART              = ReplyCode 720+pattern RPL_OMOTD                   = ReplyCode 721+pattern RPL_ENDOFOMOTD              = ReplyCode 722+pattern ERR_NOPRIVS                 = ReplyCode 723+pattern RPL_TESTMASK                = ReplyCode 724+pattern RPL_TESTLINE                = ReplyCode 725+pattern RPL_NOTESTLINE              = ReplyCode 726+pattern RPL_QUIETLIST               = ReplyCode 728+pattern RPL_ENDOFQUIETLIST          = ReplyCode 729+pattern RPL_MONONLINE               = ReplyCode 730+pattern RPL_MONOFFLINE              = ReplyCode 731+pattern RPL_MONLIST                 = ReplyCode 732+pattern RPL_ENDOFMONLIST            = ReplyCode 733+pattern ERR_MONLISTFULL             = ReplyCode 734+pattern RPL_RSACHALLENGE2           = ReplyCode 740+pattern RPL_ENDOFRSACHALLENGE2      = ReplyCode 741+pattern ERR_MLOCKRESTRICTED         = ReplyCode 742+pattern RPL_SCANMATCHED             = ReplyCode 750+pattern RPL_SCANUMODES              = ReplyCode 751+pattern RPL_XINFO                   = ReplyCode 771+pattern RPL_XINFOSTART              = ReplyCode 773+pattern RPL_XINFOEND                = ReplyCode 774+pattern RPL_LOGGEDIN                = ReplyCode 900+pattern RPL_LOGGEDOUT               = ReplyCode 901+pattern RPL_NICKLOCKED              = ReplyCode 902+pattern RPL_SASLSUCCESS             = ReplyCode 903+pattern RPL_SASLFAIL                = ReplyCode 904+pattern RPL_SASLTOOLONG             = ReplyCode 905+pattern RPL_SASLABORTED             = ReplyCode 906+pattern RPL_SASLALREADY             = ReplyCode 907+pattern RPL_SASLMECHS               = ReplyCode 908+pattern ERR_CANNOTDOCOMMAND         = ReplyCode 972+pattern ERR_CANNOTCHANGEUMODE       = ReplyCode 973+pattern ERR_CANNOTCHANGECHANMODE    = ReplyCode 974+pattern ERR_CANNOTCHANGESERVERMODE  = ReplyCode 975+pattern ERR_CANNOTSENDTONICK        = ReplyCode 976+pattern ERR_UNKNOWNSERVERMODE       = ReplyCode 977+pattern ERR_SERVERMODELOCK          = ReplyCode 979+pattern ERR_BADCHARENCODING         = ReplyCode 980+pattern ERR_TOOMANYLANGUAGES        = ReplyCode 981+pattern ERR_NOLANGUAGE              = ReplyCode 982+pattern ERR_TEXTTOOSHORT            = ReplyCode 983+pattern ERR_NUMERIC_ERR             = ReplyCode 999++data ReplyCodeInfo = ReplyCodeInfo+  { replyCodeType :: !ReplyType+  , replyCodeText :: !Text+  }++replyCodeInfo :: ReplyCode -> ReplyCodeInfo+replyCodeInfo (ReplyCode w) =+  case replyCodeInfoTable Vector.!? i of+    Nothing -> defaultReplyCodeInfo i+    Just info -> info+  where+    i = fromIntegral w++defaultReplyCodeInfo :: Int -> ReplyCodeInfo+defaultReplyCodeInfo = ReplyCodeInfo UnknownReply . Text.pack . show++replyCodeInfoTable :: Vector ReplyCodeInfo+replyCodeInfoTable+  = Vector.accumulate+      (\_def new -> new)+      (Vector.generate 1000 defaultReplyCodeInfo)+  $ fmap (\(ReplyCode code,info) -> (fromIntegral code, info))+  $ Vector.fromList+  [ (RPL_WELCOME               , ReplyCodeInfo ClientServerReply "WELCOME")+  , (RPL_YOURHOST              , ReplyCodeInfo ClientServerReply "YOURHOST")+  , (RPL_CREATED               , ReplyCodeInfo ClientServerReply "CREATED")+  , (RPL_MYINFO                , ReplyCodeInfo ClientServerReply "MYINFO")+  , (RPL_ISUPPORT              , ReplyCodeInfo ClientServerReply "ISUPPORT")+  , (RPL_SNOMASK               , ReplyCodeInfo ClientServerReply "SNOMASK")+  , (RPL_STATMEMTOT            , ReplyCodeInfo ClientServerReply "STATMEMTOT")+  , (RPL_REDIR                 , ReplyCodeInfo ClientServerReply "REDIR")+  , (RPL_YOURCOOKIE            , ReplyCodeInfo ClientServerReply "YOURCOOKIE")+  , (RPL_MAP                   , ReplyCodeInfo ClientServerReply "MAP")+  , (RPL_MAPEND                , ReplyCodeInfo ClientServerReply "MAPEND")+  , (RPL_YOURID                , ReplyCodeInfo ClientServerReply "YOURID")+  , (RPL_SAVENICK              , ReplyCodeInfo ClientServerReply "SAVENICK")+  , (RPL_ATTEMPTINGJUNC        , ReplyCodeInfo ClientServerReply "ATTEMPTINGJUNC")+  , (RPL_ATTEMPTINGREROUTE     , ReplyCodeInfo ClientServerReply "ATTEMPTINGREROUTE")+  , (RPL_TRACELINK             , ReplyCodeInfo CommandReply "TRACELINK")+  , (RPL_TRACECONNECTING       , ReplyCodeInfo CommandReply "TRACECONNECTING")+  , (RPL_TRACEHANDSHAKE        , ReplyCodeInfo CommandReply "TRACEHANDSHAKE")+  , (RPL_TRACEUNKNOWN          , ReplyCodeInfo CommandReply "TRACEUNKNOWN")+  , (RPL_TRACEOPERATOR         , ReplyCodeInfo CommandReply "TRACEOPERATOR")+  , (RPL_TRACEUSER             , ReplyCodeInfo CommandReply "TRACEUSER")+  , (RPL_TRACESERVER           , ReplyCodeInfo CommandReply "TRACESERVER")+  , (RPL_TRACESERVICE          , ReplyCodeInfo CommandReply "TRACESERVICE")+  , (RPL_TRACENEWTYPE          , ReplyCodeInfo CommandReply "TRACENEWTYPE")+  , (RPL_TRACECLASS            , ReplyCodeInfo CommandReply "TRACECLASS")+  , (RPL_TRACERECONNECT        , ReplyCodeInfo CommandReply "TRACERECONNECT")+  , (RPL_STATS                 , ReplyCodeInfo CommandReply "STATS")+  , (RPL_STATSLINKINFO         , ReplyCodeInfo CommandReply "STATSLINKINFO")+  , (RPL_STATSCOMMANDS         , ReplyCodeInfo CommandReply "STATSCOMMANDS")+  , (RPL_STATSCLINE            , ReplyCodeInfo CommandReply "STATSCLINE")+  , (RPL_STATSNLINE            , ReplyCodeInfo CommandReply "STATSNLINE")+  , (RPL_STATSILINE            , ReplyCodeInfo CommandReply "STATSILINE")+  , (RPL_STATSKLINE            , ReplyCodeInfo CommandReply "STATSKLINE")+  , (RPL_STATSQLINE            , ReplyCodeInfo CommandReply "STATSQLINE")+  , (RPL_STATSYLINE            , ReplyCodeInfo CommandReply "STATSYLINE")+  , (RPL_ENDOFSTATS            , ReplyCodeInfo CommandReply "ENDOFSTATS")+  , (RPL_STATSPLINE            , ReplyCodeInfo CommandReply "STATSPLINE")+  , (RPL_UMODEIS               , ReplyCodeInfo CommandReply "UMODEIS")+  , (RPL_SQLINE_NICK           , ReplyCodeInfo CommandReply "SQLINE_NICK")+  , (RPL_STATSDLINE            , ReplyCodeInfo CommandReply "STATSDLINE")+  , (RPL_STATSZLINE            , ReplyCodeInfo CommandReply "STATSZLINE")+  , (RPL_STATSCOUNT            , ReplyCodeInfo CommandReply "STATSCOUNT")+  , (RPL_SERVICEINFO           , ReplyCodeInfo CommandReply "SERVICEINFO")+  , (RPL_ENDOFSERVICES         , ReplyCodeInfo CommandReply "ENDOFSERVICES")+  , (RPL_SERVICE               , ReplyCodeInfo CommandReply "SERVICE")+  , (RPL_SERVLIST              , ReplyCodeInfo CommandReply "SERVLIST")+  , (RPL_SERVLISTEND           , ReplyCodeInfo CommandReply "SERVLISTEND")+  , (RPL_STATSVERBOSE          , ReplyCodeInfo CommandReply "STATSVERBOSE")+  , (RPL_STATSIAUTH            , ReplyCodeInfo CommandReply "STATSIAUTH")+  , (RPL_STATSLLINE            , ReplyCodeInfo CommandReply "STATSLLINE")+  , (RPL_STATSUPTIME           , ReplyCodeInfo CommandReply "STATSUPTIME")+  , (RPL_STATSOLINE            , ReplyCodeInfo CommandReply "STATSOLINE")+  , (RPL_STATSHLINE            , ReplyCodeInfo CommandReply "STATSHLINE")+  , (RPL_STATSSLINE            , ReplyCodeInfo CommandReply "STATSSLINE")+  , (RPL_STATSPING             , ReplyCodeInfo CommandReply "STATSPING")+  , (RPL_STATSXLINE            , ReplyCodeInfo CommandReply "STATSXLINE")+  , (RPL_STATSULINE            , ReplyCodeInfo CommandReply "STATSULINE")+  , (RPL_STATSDEBUG            , ReplyCodeInfo CommandReply "STATSDEBUG")+  , (RPL_STATSCONN             , ReplyCodeInfo CommandReply "STATSCONN")+  , (RPL_LUSERCLIENT           , ReplyCodeInfo CommandReply "LUSERCLIENT")+  , (RPL_LUSEROP               , ReplyCodeInfo CommandReply "LUSEROP")+  , (RPL_LUSERUNKNOWN          , ReplyCodeInfo CommandReply "LUSERUNKNOWN")+  , (RPL_LUSERCHANNELS         , ReplyCodeInfo CommandReply "LUSERCHANNELS")+  , (RPL_LUSERME               , ReplyCodeInfo CommandReply "LUSERME")+  , (RPL_ADMINME               , ReplyCodeInfo CommandReply "ADMINME")+  , (RPL_ADMINLOC1             , ReplyCodeInfo CommandReply "ADMINLOC1")+  , (RPL_ADMINLOC2             , ReplyCodeInfo CommandReply "ADMINLOC2")+  , (RPL_ADMINEMAIL            , ReplyCodeInfo CommandReply "ADMINEMAIL")+  , (RPL_TRACELOG              , ReplyCodeInfo CommandReply "TRACELOG")+  , (RPL_ENDOFTRACE            , ReplyCodeInfo CommandReply "ENDOFTRACE")+  , (RPL_LOAD2HI               , ReplyCodeInfo CommandReply "LOAD2HI")+  , (RPL_LOCALUSERS            , ReplyCodeInfo CommandReply "LOCALUSERS")+  , (RPL_GLOBALUSERS           , ReplyCodeInfo CommandReply "GLOBALUSERS")+  , (RPL_START_NETSTAT         , ReplyCodeInfo CommandReply "START_NETSTAT")+  , (RPL_NETSTAT               , ReplyCodeInfo CommandReply "NETSTAT")+  , (RPL_END_NETSTAT           , ReplyCodeInfo CommandReply "END_NETSTAT")+  , (RPL_PRIVS                 , ReplyCodeInfo CommandReply "PRIVS")+  , (RPL_SILELIST              , ReplyCodeInfo CommandReply "SILELIST")+  , (RPL_ENDOFSILELIST         , ReplyCodeInfo CommandReply "ENDOFSILELIST")+  , (RPL_NOTIFY                , ReplyCodeInfo CommandReply "NOTIFY")+  , (RPL_ENDNOTIFY             , ReplyCodeInfo CommandReply "ENDNOTIFY")+  , (RPL_STATSDELTA            , ReplyCodeInfo CommandReply "STATSDELTA")+  , (RPL_WHOISCERTFP           , ReplyCodeInfo CommandReply "WHOISCERTFP")+  , (RPL_VCHANLIST             , ReplyCodeInfo CommandReply "VCHANLIST")+  , (RPL_VCHANHELP             , ReplyCodeInfo CommandReply "VCHANHELP")+  , (RPL_GLIST                 , ReplyCodeInfo CommandReply "GLIST")+  , (RPL_ACCEPTLIST            , ReplyCodeInfo CommandReply "ACCEPTLIST")+  , (RPL_ENDOFACCEPT           , ReplyCodeInfo CommandReply "ENDOFACCEPT")+  , (RPL_ENDOFJUPELIST         , ReplyCodeInfo CommandReply "ENDOFJUPELIST")+  , (RPL_FEATURE               , ReplyCodeInfo CommandReply "FEATURE")+  , (RPL_DATASTR               , ReplyCodeInfo CommandReply "DATASTR")+  , (RPL_END_CHANINFO          , ReplyCodeInfo CommandReply "END_CHANINFO")+  , (RPL_NONE                  , ReplyCodeInfo CommandReply "NONE")+  , (RPL_AWAY                  , ReplyCodeInfo CommandReply "AWAY")+  , (RPL_USERHOST              , ReplyCodeInfo CommandReply "USERHOST")+  , (RPL_ISON                  , ReplyCodeInfo CommandReply "ISON")+  , (RPL_TEXT                  , ReplyCodeInfo CommandReply "TEXT")+  , (RPL_UNAWAY                , ReplyCodeInfo CommandReply "UNAWAY")+  , (RPL_NOWAWAY               , ReplyCodeInfo CommandReply "NOWAWAY")+  , (RPL_WHOISREGNICK          , ReplyCodeInfo CommandReply "WHOISREGNICK")+  , (RPL_SUSERHOST             , ReplyCodeInfo CommandReply "SUSERHOST")+  , (RPL_NOTIFYACTION          , ReplyCodeInfo CommandReply "NOTIFYACTION")+  , (RPL_WHOISADMIN            , ReplyCodeInfo CommandReply "WHOISADMIN")+  , (RPL_NICKTRACE             , ReplyCodeInfo CommandReply "NICKTRACE")+  , (RPL_WHOISSADMIN           , ReplyCodeInfo CommandReply "WHOISSADMIN")+  , (RPL_WHOISHELPER           , ReplyCodeInfo CommandReply "WHOISHELPER")+  , (RPL_WHOISUSER             , ReplyCodeInfo CommandReply "WHOISUSER")+  , (RPL_WHOISSERVER           , ReplyCodeInfo CommandReply "WHOISSERVER")+  , (RPL_WHOISOPERATOR         , ReplyCodeInfo CommandReply "WHOISOPERATOR")+  , (RPL_WHOWASUSER            , ReplyCodeInfo CommandReply "WHOWASUSER")+  , (RPL_ENDOFWHO              , ReplyCodeInfo CommandReply "ENDOFWHO")+  , (RPL_WHOISCHANOP           , ReplyCodeInfo CommandReply "WHOISCHANOP")+  , (RPL_WHOISIDLE             , ReplyCodeInfo CommandReply "WHOISIDLE")+  , (RPL_ENDOFWHOIS            , ReplyCodeInfo CommandReply "ENDOFWHOIS")+  , (RPL_WHOISCHANNELS         , ReplyCodeInfo CommandReply "WHOISCHANNELS")+  , (RPL_WHOISSPECIAL          , ReplyCodeInfo CommandReply "WHOISSPECIAL")+  , (RPL_LISTSTART             , ReplyCodeInfo CommandReply "LISTSTART")+  , (RPL_LIST                  , ReplyCodeInfo CommandReply "LIST")+  , (RPL_LISTEND               , ReplyCodeInfo CommandReply "LISTEND")+  , (RPL_CHANNELMODEIS         , ReplyCodeInfo CommandReply "CHANNELMODEIS")+  , (RPL_CHANNELMLOCKIS        , ReplyCodeInfo CommandReply "CHANNELMLOCKIS")+  , (RPL_NOCHANPASS            , ReplyCodeInfo CommandReply "NOCHANPASS")+  , (RPL_CHPASSUNKNOWN         , ReplyCodeInfo CommandReply "CHPASSUNKNOWN")+  , (RPL_CHANNEL_URL           , ReplyCodeInfo CommandReply "CHANNEL_URL")+  , (RPL_CREATIONTIME          , ReplyCodeInfo CommandReply "CREATIONTIME")+  , (RPL_WHOWAS_TIME           , ReplyCodeInfo CommandReply "WHOWAS_TIME")+  , (RPL_WHOISACCOUNT          , ReplyCodeInfo CommandReply "WHOISACCOUNT")+  , (RPL_NOTOPIC               , ReplyCodeInfo CommandReply "NOTOPIC")+  , (RPL_TOPIC                 , ReplyCodeInfo CommandReply "TOPIC")+  , (RPL_TOPICWHOTIME          , ReplyCodeInfo CommandReply "TOPICWHOTIME")+  , (RPL_LISTUSAGE             , ReplyCodeInfo CommandReply "LISTUSAGE")+  , (RPL_COMMANDSYNTAX         , ReplyCodeInfo CommandReply "COMMANDSYNTAX")+  , (RPL_LISTSYNTAX            , ReplyCodeInfo CommandReply "LISTSYNTAX")+  , (RPL_WHOISACTUALLY         , ReplyCodeInfo CommandReply "WHOISACTUALLY")+  , (RPL_BADCHANPASS           , ReplyCodeInfo CommandReply "BADCHANPASS")+  , (RPL_INVITING              , ReplyCodeInfo CommandReply "INVITING")+  , (RPL_SUMMONING             , ReplyCodeInfo CommandReply "SUMMONING")+  , (RPL_INVITED               , ReplyCodeInfo CommandReply "INVITED")+  , (RPL_INVEXLIST             , ReplyCodeInfo CommandReply "INVEXLIST")+  , (RPL_ENDOFINVEXLIST        , ReplyCodeInfo CommandReply "ENDOFINVEXLIST")+  , (RPL_EXCEPTLIST            , ReplyCodeInfo CommandReply "EXCEPTLIST")+  , (RPL_ENDOFEXCEPTLIST       , ReplyCodeInfo CommandReply "ENDOFEXCEPTLIST")+  , (RPL_VERSION               , ReplyCodeInfo CommandReply "VERSION")+  , (RPL_WHOREPLY              , ReplyCodeInfo CommandReply "WHOREPLY")+  , (RPL_NAMREPLY              , ReplyCodeInfo CommandReply "NAMREPLY")+  , (RPL_WHOSPCRPL             , ReplyCodeInfo CommandReply "WHOSPCRPL")+  , (RPL_NAMREPLY_             , ReplyCodeInfo CommandReply "NAMREPLY_")+  , (RPL_WHOWASREAL            , ReplyCodeInfo CommandReply "WHOWASREAL")+  , (RPL_KILLDONE              , ReplyCodeInfo CommandReply "KILLDONE")+  , (RPL_CLOSING               , ReplyCodeInfo CommandReply "CLOSING")+  , (RPL_CLOSEEND              , ReplyCodeInfo CommandReply "CLOSEEND")+  , (RPL_LINKS                 , ReplyCodeInfo CommandReply "LINKS")+  , (RPL_ENDOFLINKS            , ReplyCodeInfo CommandReply "ENDOFLINKS")+  , (RPL_ENDOFNAMES            , ReplyCodeInfo CommandReply "ENDOFNAMES")+  , (RPL_BANLIST               , ReplyCodeInfo CommandReply "BANLIST")+  , (RPL_ENDOFBANLIST          , ReplyCodeInfo CommandReply "ENDOFBANLIST")+  , (RPL_ENDOFWHOWAS           , ReplyCodeInfo CommandReply "ENDOFWHOWAS")+  , (RPL_INFO                  , ReplyCodeInfo CommandReply "INFO")+  , (RPL_MOTD                  , ReplyCodeInfo CommandReply "MOTD")+  , (RPL_INFOSTART             , ReplyCodeInfo CommandReply "INFOSTART")+  , (RPL_ENDOFINFO             , ReplyCodeInfo CommandReply "ENDOFINFO")+  , (RPL_MOTDSTART             , ReplyCodeInfo CommandReply "MOTDSTART")+  , (RPL_ENDOFMOTD             , ReplyCodeInfo CommandReply "ENDOFMOTD")+  , (RPL_WHOISHOST             , ReplyCodeInfo CommandReply "WHOISHOST")+  , (RPL_KICKLINKED            , ReplyCodeInfo CommandReply "KICKLINKED")+  , (RPL_YOUREOPER             , ReplyCodeInfo CommandReply "YOUREOPER")+  , (RPL_REHASHING             , ReplyCodeInfo CommandReply "REHASHING")+  , (RPL_YOURESERVICE          , ReplyCodeInfo CommandReply "YOURESERVICE")+  , (RPL_MYPORTIS              , ReplyCodeInfo CommandReply "MYPORTIS")+  , (RPL_NOTOPERANYMORE        , ReplyCodeInfo CommandReply "NOTOPERANYMORE")+  , (RPL_RSACHALLENGE          , ReplyCodeInfo CommandReply "RSACHALLENGE")+  , (RPL_TIME                  , ReplyCodeInfo CommandReply "TIME")+  , (RPL_USERSSTART            , ReplyCodeInfo CommandReply "USERSSTART")+  , (RPL_USERS                 , ReplyCodeInfo CommandReply "USERS")+  , (RPL_ENDOFUSERS            , ReplyCodeInfo CommandReply "ENDOFUSERS")+  , (RPL_NOUSERS               , ReplyCodeInfo CommandReply "NOUSERS")+  , (RPL_HOSTHIDDEN            , ReplyCodeInfo CommandReply "HOSTHIDDEN")+  , (ERR_UNKNOWNERROR          , ReplyCodeInfo ErrorReply "UNKNOWNERROR")+  , (ERR_NOSUCHNICK            , ReplyCodeInfo ErrorReply "NOSUCHNICK")+  , (ERR_NOSUCHSERVER          , ReplyCodeInfo ErrorReply "NOSUCHSERVER")+  , (ERR_NOSUCHCHANNEL         , ReplyCodeInfo ErrorReply "NOSUCHCHANNEL")+  , (ERR_CANNOTSENDTOCHAN      , ReplyCodeInfo ErrorReply "CANNOTSENDTOCHAN")+  , (ERR_TOOMANYCHANNELS       , ReplyCodeInfo ErrorReply "TOOMANYCHANNELS")+  , (ERR_WASNOSUCHNICK         , ReplyCodeInfo ErrorReply "WASNOSUCHNICK")+  , (ERR_TOOMANYTARGETS        , ReplyCodeInfo ErrorReply "TOOMANYTARGETS")+  , (ERR_NOORIGIN              , ReplyCodeInfo ErrorReply "NOORIGIN")+  , (ERR_NORECIPIENT           , ReplyCodeInfo ErrorReply "NORECIPIENT")+  , (ERR_NOTEXTTOSEND          , ReplyCodeInfo ErrorReply "NOTEXTTOSEND")+  , (ERR_NOTOPLEVEL            , ReplyCodeInfo ErrorReply "NOTOPLEVEL")+  , (ERR_WILDTOPLEVEL          , ReplyCodeInfo ErrorReply "WILDTOPLEVEL")+  , (ERR_BADMASK               , ReplyCodeInfo ErrorReply "BADMASK")+  , (ERR_TOOMANYMATCHES        , ReplyCodeInfo ErrorReply "TOOMANYMATCHES")+  , (ERR_LENGTHTRUNCATED       , ReplyCodeInfo ErrorReply "LENGTHTRUNCATED")+  , (ERR_UNKNOWNCOMMAND        , ReplyCodeInfo ErrorReply "UNKNOWNCOMMAND")+  , (ERR_NOMOTD                , ReplyCodeInfo ErrorReply "NOMOTD")+  , (ERR_NOADMININFO           , ReplyCodeInfo ErrorReply "NOADMININFO")+  , (ERR_FILEERROR             , ReplyCodeInfo ErrorReply "FILEERROR")+  , (ERR_NOOPERMOTD            , ReplyCodeInfo ErrorReply "NOOPERMOTD")+  , (ERR_TOOMANYAWAY           , ReplyCodeInfo ErrorReply "TOOMANYAWAY")+  , (ERR_EVENTNICKCHANGE       , ReplyCodeInfo ErrorReply "EVENTNICKCHANGE")+  , (ERR_NONICKNAMEGIVEN       , ReplyCodeInfo ErrorReply "NONICKNAMEGIVEN")+  , (ERR_ERRONEUSNICKNAME      , ReplyCodeInfo ErrorReply "ERRONEUSNICKNAME")+  , (ERR_NICKNAMEINUSE         , ReplyCodeInfo ErrorReply "NICKNAMEINUSE")+  , (ERR_SERVICENAMEINUSE      , ReplyCodeInfo ErrorReply "SERVICENAMEINUSE")+  , (ERR_NORULES               , ReplyCodeInfo ErrorReply "NORULES")+  , (ERR_BANNICKCHANGE         , ReplyCodeInfo ErrorReply "BANNICKCHANGE")+  , (ERR_NICKCOLLISION         , ReplyCodeInfo ErrorReply "NICKCOLLISION")+  , (ERR_UNAVAILRESOURCE       , ReplyCodeInfo ErrorReply "UNAVAILRESOURCE")+  , (ERR_NICKTOOFAST           , ReplyCodeInfo ErrorReply "NICKTOOFAST")+  , (ERR_TARGETTOOFAST         , ReplyCodeInfo ErrorReply "TARGETTOOFAST")+  , (ERR_SERVICESDOWN          , ReplyCodeInfo ErrorReply "SERVICESDOWN")+  , (ERR_USERNOTINCHANNEL      , ReplyCodeInfo ErrorReply "USERNOTINCHANNEL")+  , (ERR_NOTONCHANNEL          , ReplyCodeInfo ErrorReply "NOTONCHANNEL")+  , (ERR_USERONCHANNEL         , ReplyCodeInfo ErrorReply "USERONCHANNEL")+  , (ERR_NOLOGIN               , ReplyCodeInfo ErrorReply "NOLOGIN")+  , (ERR_SUMMONDISABLED        , ReplyCodeInfo ErrorReply "SUMMONDISABLED")+  , (ERR_USERSDISABLED         , ReplyCodeInfo ErrorReply "USERSDISABLED")+  , (ERR_NONICKCHANGE          , ReplyCodeInfo ErrorReply "NONICKCHANGE")+  , (ERR_NOTIMPLEMENTED        , ReplyCodeInfo ErrorReply "NOTIMPLEMENTED")+  , (ERR_NOTREGISTERED         , ReplyCodeInfo ErrorReply "NOTREGISTERED")+  , (ERR_IDCOLLISION           , ReplyCodeInfo ErrorReply "IDCOLLISION")+  , (ERR_NICKLOST              , ReplyCodeInfo ErrorReply "NICKLOST")+  , (ERR_HOSTILENAME           , ReplyCodeInfo ErrorReply "HOSTILENAME")+  , (ERR_ACCEPTFULL            , ReplyCodeInfo ErrorReply "ACCEPTFULL")+  , (ERR_ACCEPTEXIST           , ReplyCodeInfo ErrorReply "ACCEPTEXIST")+  , (ERR_ACCEPTNOT             , ReplyCodeInfo ErrorReply "ACCEPTNOT")+  , (ERR_NOHIDING              , ReplyCodeInfo ErrorReply "NOHIDING")+  , (ERR_NOTFORHALFOPS         , ReplyCodeInfo ErrorReply "NOTFORHALFOPS")+  , (ERR_NEEDMOREPARAMS        , ReplyCodeInfo ErrorReply "NEEDMOREPARAMS")+  , (ERR_ALREADYREGISTERED     , ReplyCodeInfo ErrorReply "ALREADYREGISTERED")+  , (ERR_NOPERMFORHOST         , ReplyCodeInfo ErrorReply "NOPERMFORHOST")+  , (ERR_PASSWDMISMATCH        , ReplyCodeInfo ErrorReply "PASSWDMISMATCH")+  , (ERR_YOUREBANNEDCREEP      , ReplyCodeInfo ErrorReply "YOUREBANNEDCREEP")+  , (ERR_YOUWILLBEBANNED       , ReplyCodeInfo ErrorReply "YOUWILLBEBANNED")+  , (ERR_KEYSET                , ReplyCodeInfo ErrorReply "KEYSET")+  , (ERR_INVALIDUSERNAME       , ReplyCodeInfo ErrorReply "INVALIDUSERNAME")+  , (ERR_ONLYSERVERSCANCHANGE  , ReplyCodeInfo ErrorReply "ONLYSERVERSCANCHANGE")+  , (ERR_LINKSET               , ReplyCodeInfo ErrorReply "LINKSET")+  , (ERR_LINKCHANNEL           , ReplyCodeInfo ErrorReply "LINKCHANNEL")+  , (ERR_CHANNELISFULL         , ReplyCodeInfo ErrorReply "CHANNELISFULL")+  , (ERR_UNKNOWNMODE           , ReplyCodeInfo ErrorReply "UNKNOWNMODE")+  , (ERR_INVITEONLYCHAN        , ReplyCodeInfo ErrorReply "INVITEONLYCHAN")+  , (ERR_BANNEDFROMCHAN        , ReplyCodeInfo ErrorReply "BANNEDFROMCHAN")+  , (ERR_BADCHANNELKEY         , ReplyCodeInfo ErrorReply "BADCHANNELKEY")+  , (ERR_BADCHANMASK           , ReplyCodeInfo ErrorReply "BADCHANMASK")+  , (ERR_NEEDREGGEDNICK        , ReplyCodeInfo ErrorReply "NEEDREGGEDNICK")+  , (ERR_BANLISTFULL           , ReplyCodeInfo ErrorReply "BANLISTFULL")+  , (ERR_BADCHANNAME           , ReplyCodeInfo ErrorReply "BADCHANNAME")+  , (ERR_THROTTLE              , ReplyCodeInfo ErrorReply "THROTTLE")+  , (ERR_NOPRIVILEGES          , ReplyCodeInfo ErrorReply "NOPRIVILEGES")+  , (ERR_CHANOPRIVSNEEDED      , ReplyCodeInfo ErrorReply "CHANOPRIVSNEEDED")+  , (ERR_CANTKILLSERVER        , ReplyCodeInfo ErrorReply "CANTKILLSERVER")+  , (ERR_ISCHANSERVICE         , ReplyCodeInfo ErrorReply "ISCHANSERVICE")+  , (ERR_BANNEDNICK            , ReplyCodeInfo ErrorReply "BANNEDNICK")+  , (ERR_NONONREG              , ReplyCodeInfo ErrorReply "NONONREG")+  , (ERR_TSLESSCHAN            , ReplyCodeInfo ErrorReply "TSLESSCHAN")+  , (ERR_VOICENEEDED           , ReplyCodeInfo ErrorReply "VOICENEEDED")+  , (ERR_NOOPERHOST            , ReplyCodeInfo ErrorReply "NOOPERHOST")+  , (ERR_NOSERVICEHOST         , ReplyCodeInfo ErrorReply "NOSERVICEHOST")+  , (ERR_NOFEATURE             , ReplyCodeInfo ErrorReply "NOFEATURE")+  , (ERR_OWNMODE               , ReplyCodeInfo ErrorReply "OWNMODE")+  , (ERR_BADLOGTYPE            , ReplyCodeInfo ErrorReply "BADLOGTYPE")+  , (ERR_BADLOGSYS             , ReplyCodeInfo ErrorReply "BADLOGSYS")+  , (ERR_BADLOGVALUE           , ReplyCodeInfo ErrorReply "BADLOGVALUE")+  , (ERR_ISOPERLCHAN           , ReplyCodeInfo ErrorReply "ISOPERLCHAN")+  , (ERR_CHANOWNPRIVNEEDED     , ReplyCodeInfo ErrorReply "CHANOWNPRIVNEEDED")+  , (ERR_UMODEUNKNOWNFLAG      , ReplyCodeInfo ErrorReply "UMODEUNKNOWNFLAG")+  , (ERR_USERSDONTMATCH        , ReplyCodeInfo ErrorReply "USERSDONTMATCH")+  , (ERR_GHOSTEDCLIENT         , ReplyCodeInfo ErrorReply "GHOSTEDCLIENT")+  , (ERR_USERNOTONSERV         , ReplyCodeInfo ErrorReply "USERNOTONSERV")+  , (ERR_SILELISTFULL          , ReplyCodeInfo ErrorReply "SILELISTFULL")+  , (ERR_TOOMANYWATCH          , ReplyCodeInfo ErrorReply "TOOMANYWATCH")+  , (ERR_WRONGPONG             , ReplyCodeInfo ErrorReply "WRONGPONG")+  , (ERR_BADEXPIRE             , ReplyCodeInfo ErrorReply "BADEXPIRE")+  , (ERR_DONTCHEAT             , ReplyCodeInfo ErrorReply "DONTCHEAT")+  , (ERR_DISABLED              , ReplyCodeInfo ErrorReply "DISABLED")+  , (ERR_NOINVITE              , ReplyCodeInfo ErrorReply "NOINVITE")+  , (ERR_LONGMASK              , ReplyCodeInfo ErrorReply "LONGMASK")+  , (ERR_ADMONLY               , ReplyCodeInfo ErrorReply "ADMONLY")+  , (ERR_TOOMANYUSERS          , ReplyCodeInfo ErrorReply "TOOMANYUSERS")+  , (ERR_OPERONLY              , ReplyCodeInfo ErrorReply "OPERONLY")+  , (ERR_MASKTOOWIDE           , ReplyCodeInfo ErrorReply "MASKTOOWIDE")+  , (ERR_WHOTRUNC              , ReplyCodeInfo ErrorReply "WHOTRUNC")+  , (ERR_LISTSYNTAX            , ReplyCodeInfo ErrorReply "LISTSYNTAX")+  , (ERR_WHOSYNTAX             , ReplyCodeInfo ErrorReply "WHOSYNTAX")+  , (ERR_WHOLIMEXCEED          , ReplyCodeInfo ErrorReply "WHOLIMEXCEED")+  , (ERR_HELPNOTFOUND          , ReplyCodeInfo ErrorReply "HELPNOTFOUND")+  , (ERR_REMOTEPFX             , ReplyCodeInfo ErrorReply "REMOTEPFX")+  , (ERR_PFXUNROUTABLE         , ReplyCodeInfo ErrorReply "PFXUNROUTABLE")+  , (ERR_BADHOSTMASK           , ReplyCodeInfo ErrorReply "BADHOSTMASK")+  , (ERR_HOSTUNAVAIL           , ReplyCodeInfo ErrorReply "HOSTUNAVAIL")+  , (ERR_USINGSLINE            , ReplyCodeInfo ErrorReply "USINGSLINE")+  , (ERR_STATSSLINE            , ReplyCodeInfo ErrorReply "STATSSLINE")+  , (RPL_LOGON                 , ReplyCodeInfo CommandReply "LOGON")+  , (RPL_LOGOFF                , ReplyCodeInfo CommandReply "LOGOFF")+  , (RPL_WATCHOFF              , ReplyCodeInfo CommandReply "WATCHOFF")+  , (RPL_WATCHSTAT             , ReplyCodeInfo CommandReply "WATCHSTAT")+  , (RPL_NOWON                 , ReplyCodeInfo CommandReply "NOWON")+  , (RPL_NOWOFF                , ReplyCodeInfo CommandReply "NOWOFF")+  , (RPL_WATCHLIST             , ReplyCodeInfo CommandReply "WATCHLIST")+  , (RPL_ENDOFWATCHLIST        , ReplyCodeInfo CommandReply "ENDOFWATCHLIST")+  , (RPL_WATCHCLEAR            , ReplyCodeInfo CommandReply "WATCHCLEAR")+  , (RPL_ISOPER                , ReplyCodeInfo CommandReply "ISOPER")+  , (RPL_ISLOCOP               , ReplyCodeInfo CommandReply "ISLOCOP")+  , (RPL_ISNOTOPER             , ReplyCodeInfo CommandReply "ISNOTOPER")+  , (RPL_ENDOFISOPER           , ReplyCodeInfo CommandReply "ENDOFISOPER")+  , (RPL_DCCSTATUS             , ReplyCodeInfo CommandReply "DCCSTATUS")+  , (RPL_DCCLIST               , ReplyCodeInfo CommandReply "DCCLIST")+  , (RPL_ENDOFDCCLIST          , ReplyCodeInfo CommandReply "ENDOFDCCLIST")+  , (RPL_WHOWASHOST            , ReplyCodeInfo CommandReply "WHOWASHOST")+  , (RPL_DCCINFO               , ReplyCodeInfo CommandReply "DCCINFO")+  , (RPL_RULES                 , ReplyCodeInfo CommandReply "RULES")+  , (RPL_ENDOFO                , ReplyCodeInfo CommandReply "ENDOFO")+  , (RPL_SETTINGS              , ReplyCodeInfo CommandReply "SETTINGS")+  , (RPL_ENDOFSETTINGS         , ReplyCodeInfo CommandReply "ENDOFSETTINGS")+  , (RPL_DUMPING               , ReplyCodeInfo CommandReply "DUMPING")+  , (RPL_DUMPRPL               , ReplyCodeInfo CommandReply "DUMPRPL")+  , (RPL_EODUMP                , ReplyCodeInfo CommandReply "EODUMP")+  , (RPL_TRACEROUTE_HOP        , ReplyCodeInfo CommandReply "TRACEROUTE_HOP")+  , (RPL_TRACEROUTE_START      , ReplyCodeInfo CommandReply "TRACEROUTE_START")+  , (RPL_MODECHANGEWARN        , ReplyCodeInfo CommandReply "MODECHANGEWARN")+  , (RPL_CHANREDIR             , ReplyCodeInfo CommandReply "CHANREDIR")+  , (RPL_SERVMODEIS            , ReplyCodeInfo CommandReply "SERVMODEIS")+  , (RPL_OTHERUMODEIS          , ReplyCodeInfo CommandReply "OTHERUMODEIS")+  , (RPL_ENDOF_GENERIC         , ReplyCodeInfo CommandReply "ENDOF_GENERIC")+  , (RPL_WHOWASDETAILS         , ReplyCodeInfo CommandReply "WHOWASDETAILS")+  , (RPL_WHOISSECURE           , ReplyCodeInfo CommandReply "WHOISSECURE")+  , (RPL_UNKNOWNMODES          , ReplyCodeInfo CommandReply "UNKNOWNMODES")+  , (RPL_CANNOTSETMODES        , ReplyCodeInfo CommandReply "CANNOTSETMODES")+  , (RPL_LUSERSTAFF            , ReplyCodeInfo CommandReply "LUSERSTAFF")+  , (RPL_TIMEONSERVERIS        , ReplyCodeInfo CommandReply "TIMEONSERVERIS")+  , (RPL_NETWORKS              , ReplyCodeInfo CommandReply "NETWORKS")+  , (RPL_YOURLANGUAGEIS        , ReplyCodeInfo CommandReply "YOURLANGUAGEIS")+  , (RPL_LANGUAGE              , ReplyCodeInfo CommandReply "LANGUAGE")+  , (RPL_WHOISSTAFF            , ReplyCodeInfo CommandReply "WHOISSTAFF")+  , (RPL_WHOISLANGUAGE         , ReplyCodeInfo CommandReply "WHOISLANGUAGE")+  , (RPL_MODLIST               , ReplyCodeInfo CommandReply "MODLIST")+  , (RPL_ENDOFMODLIST          , ReplyCodeInfo CommandReply "ENDOFMODLIST")+  , (RPL_HELPSTART             , ReplyCodeInfo CommandReply "HELPSTART")+  , (RPL_HELPTXT               , ReplyCodeInfo CommandReply "HELPTXT")+  , (RPL_ENDOFHELP             , ReplyCodeInfo CommandReply "ENDOFHELP")+  , (ERR_TARGCHANGE            , ReplyCodeInfo ErrorReply "TARGCHANGE")+  , (RPL_ETRACEFULL            , ReplyCodeInfo CommandReply "ETRACEFULL")+  , (RPL_ETRACE                , ReplyCodeInfo CommandReply "ETRACE")+  , (RPL_KNOCK                 , ReplyCodeInfo CommandReply "KNOCK")+  , (RPL_KNOCKDLVR             , ReplyCodeInfo CommandReply "KNOCKDLVR")+  , (ERR_TOOMANYKNOCK          , ReplyCodeInfo ErrorReply "TOOMANYKNOCK")+  , (ERR_CHANOPEN              , ReplyCodeInfo ErrorReply "CHANOPEN")+  , (ERR_KNOCKONCHAN           , ReplyCodeInfo ErrorReply "KNOCKONCHAN")+  , (ERR_KNOCKDISABLED         , ReplyCodeInfo ErrorReply "KNOCKDISABLED")+  , (RPL_TARGUMODEG            , ReplyCodeInfo CommandReply "TARGUMODEG")+  , (RPL_TARGNOTIFY            , ReplyCodeInfo CommandReply "TARGNOTIFY")+  , (RPL_UMODEGMSG             , ReplyCodeInfo CommandReply "UMODEGMSG")+  , (RPL_OMOTDSTART            , ReplyCodeInfo CommandReply "OMOTDSTART")+  , (RPL_OMOTD                 , ReplyCodeInfo CommandReply "OMOTD")+  , (RPL_ENDOFOMOTD            , ReplyCodeInfo CommandReply "ENDOFOMOTD")+  , (ERR_NOPRIVS               , ReplyCodeInfo ErrorReply "NOPRIVS")+  , (RPL_TESTMASK              , ReplyCodeInfo CommandReply "TESTMASK")+  , (RPL_TESTLINE              , ReplyCodeInfo CommandReply "TESTLINE")+  , (RPL_NOTESTLINE            , ReplyCodeInfo CommandReply "NOTESTLINE")+  , (RPL_QUIETLIST             , ReplyCodeInfo CommandReply "QUIETLIST")+  , (RPL_ENDOFQUIETLIST        , ReplyCodeInfo CommandReply "ENDOFQUIETLIST")+  , (RPL_MONONLINE             , ReplyCodeInfo CommandReply "MONONLINE")+  , (RPL_MONOFFLINE            , ReplyCodeInfo CommandReply "MONOFFLINE")+  , (RPL_MONLIST               , ReplyCodeInfo CommandReply "MONLIST")+  , (RPL_ENDOFMONLIST          , ReplyCodeInfo CommandReply "ENDOFMONLIST")+  , (ERR_MONLISTFULL           , ReplyCodeInfo ErrorReply "MONLISTFULL")+  , (RPL_RSACHALLENGE2         , ReplyCodeInfo CommandReply "RSACHALLENGE2")+  , (RPL_ENDOFRSACHALLENGE2    , ReplyCodeInfo CommandReply "ENDOFRSACHALLENGE2")+  , (ERR_MLOCKRESTRICTED       , ReplyCodeInfo ErrorReply "MLOCKRESTRICTED")+  , (RPL_SCANMATCHED           , ReplyCodeInfo CommandReply "SCANMATCHED")+  , (RPL_SCANUMODES            , ReplyCodeInfo CommandReply "SCANUMODES")+  , (RPL_XINFO                 , ReplyCodeInfo CommandReply "XINFO")+  , (RPL_XINFOSTART            , ReplyCodeInfo CommandReply "XINFOSTART")+  , (RPL_XINFOEND              , ReplyCodeInfo CommandReply "XINFOEND")+  , (RPL_LOGGEDIN              , ReplyCodeInfo CommandReply "LOGGEDIN")+  , (RPL_LOGGEDOUT             , ReplyCodeInfo CommandReply "LOGGEDOUT")+  , (RPL_NICKLOCKED            , ReplyCodeInfo CommandReply "NICKLOCKED")+  , (RPL_SASLSUCCESS           , ReplyCodeInfo CommandReply "SASLSUCCESS")+  , (RPL_SASLFAIL              , ReplyCodeInfo CommandReply "SASLFAIL")+  , (RPL_SASLTOOLONG           , ReplyCodeInfo CommandReply "SASLTOOLONG")+  , (RPL_SASLABORTED           , ReplyCodeInfo CommandReply "SASLABORTED")+  , (RPL_SASLALREADY           , ReplyCodeInfo CommandReply "SASLALREADY")+  , (RPL_SASLMECHS             , ReplyCodeInfo CommandReply "SASLMECHS")+  , (ERR_CANNOTDOCOMMAND       , ReplyCodeInfo ErrorReply "CANNOTDOCOMMAND")+  , (ERR_CANNOTCHANGEUMODE     , ReplyCodeInfo ErrorReply "CANNOTCHANGEUMODE")+  , (ERR_CANNOTCHANGECHANMODE  , ReplyCodeInfo ErrorReply "CANNOTCHANGECHANMODE")+  , (ERR_CANNOTCHANGESERVERMODE, ReplyCodeInfo ErrorReply "CANNOTCHANGESERVERMODE")+  , (ERR_CANNOTSENDTONICK      , ReplyCodeInfo ErrorReply "CANNOTSENDTONICK")+  , (ERR_UNKNOWNSERVERMODE     , ReplyCodeInfo ErrorReply "UNKNOWNSERVERMODE")+  , (ERR_SERVERMODELOCK        , ReplyCodeInfo ErrorReply "SERVERMODELOCK")+  , (ERR_BADCHARENCODING       , ReplyCodeInfo ErrorReply "BADCHARENCODING")+  , (ERR_TOOMANYLANGUAGES      , ReplyCodeInfo ErrorReply "TOOMANYLANGUAGES")+  , (ERR_NOLANGUAGE            , ReplyCodeInfo ErrorReply "NOLANGUAGE")+  , (ERR_TEXTTOOSHORT          , ReplyCodeInfo ErrorReply "TEXTTOOSHORT")+  , (ERR_NUMERIC_ERR           , ReplyCodeInfo ErrorReply "NUMERIC_ERR")+  ]
src/Irc/Commands.hs view
@@ -28,12 +28,19 @@   , ircWho   , ircWhois   , ircWhowas++  -- * SASL support+  , ircAuthenticate+  , plainAuthenticationMode+  , encodePlainAuthentication   ) where  import           Irc.RawIrcMsg import           Irc.Identifier import           Data.Text (Text) import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text+import qualified Data.ByteArray.Encoding as Enc  -- | PRIVMSG command ircPrivmsg ::@@ -167,3 +174,19 @@ -- | CAP LS command ircCapLs :: RawIrcMsg ircCapLs = rawIrcMsg "CAP" ["LS"]++ircAuthenticate :: Text -> RawIrcMsg+ircAuthenticate msg = rawIrcMsg "AUTHENTICATE" [msg]++plainAuthenticationMode :: Text+plainAuthenticationMode = "PLAIN"++encodePlainAuthentication ::+  Text {- ^ username -} ->+  Text {- ^ password -} ->+  Text+encodePlainAuthentication user pass+  = Text.decodeUtf8+  $ Enc.convertToBase Enc.Base64+  $ Text.encodeUtf8+  $ Text.intercalate "\0" [user,user,pass]
src/Irc/Message.hs view
@@ -39,10 +39,11 @@ import           Irc.Identifier import           Irc.RawIrcMsg import           Irc.UserInfo+import           Irc.Codes  data IrcMsg   = UnknownMsg RawIrcMsg-  | Reply Int [Text]+  | Reply ReplyCode [Text]   | Nick UserInfo Identifier   | Join UserInfo Identifier   | Part UserInfo Identifier (Maybe Text)@@ -53,6 +54,7 @@   | Action UserInfo Identifier Text -- ^ source target txt   | Notice UserInfo Identifier Text -- ^ source target txt   | Mode UserInfo Identifier [Text] -- ^ source target txt+  | Authenticate Text   | Cap CapCmd [Text]   | Ping [Text]   | Pong [Text]@@ -81,11 +83,14 @@ cookIrcMsg msg =   case view msgCommand msg of     cmd | Right (n,"") <- decimal cmd ->-        Reply n (view msgParams msg)+        Reply (ReplyCode n) (view msgParams msg)     "CAP" | _target:cmdTxt:rest <- view msgParams msg           , Just cmd <- cookCapCmd cmdTxt ->            Cap cmd rest +    "AUTHENTICATE" | x:_ <- view msgParams msg ->+        Authenticate x+     "PING" -> Ping (view msgParams msg)     "PONG" -> Pong (view msgParams msg) @@ -161,6 +166,7 @@                       | otherwise -> TargetWindow tgt     Notice  src tgt _ | tgt == me -> TargetWindow (userNick src)                       | otherwise -> TargetWindow tgt+    Authenticate{}                -> TargetHidden     Ping{}                        -> TargetHidden     Pong{}                        -> TargetHidden     Error{}                       -> TargetNetwork@@ -183,6 +189,7 @@     Action x _ _  -> Just x     Notice x _ _  -> Just x     Mode x _ _    -> Just x+    Authenticate{}-> Nothing     Ping{}        -> Nothing     Pong{}        -> Nothing     Error{}       -> Nothing@@ -194,7 +201,7 @@ ircMsgText msg =   case msg of     UnknownMsg raw -> Text.unwords (view msgCommand raw : view msgParams raw)-    Reply n xs     -> Text.unwords (Text.pack (show n) : xs)+    Reply (ReplyCode n) xs -> Text.unwords (Text.pack (show n) : xs)     Nick x y       -> Text.unwords [renderUserInfo x, idText y]     Join x _       -> renderUserInfo x     Part x _ mb    -> Text.unwords (renderUserInfo x : maybeToList mb)@@ -209,6 +216,7 @@     Pong xs        -> Text.unwords xs     Cap _ xs       -> Text.unwords xs     Error t        -> t+    Authenticate{} -> ""  -- nickname   =  ( letter / special ) *8( letter / digit / special / "-" ) -- letter     =  %x41-5A / %x61-7A       ; A-Z / a-z
src/Irc/RateLimit.hs view
@@ -18,7 +18,6 @@ module Irc.RateLimit   ( RateLimit   , newRateLimit-  , newRateLimitDefault   , tickRateLimit   ) where @@ -33,11 +32,6 @@   , rateThreshold :: !Int            -- ^ seconds   , ratePenalty   :: !Int            -- ^ seconds   }---- | Construct a new rate limit with the RFC 2813 specified--- 2 second penalty and 10 second threshold-newRateLimitDefault :: IO RateLimit-newRateLimitDefault = newRateLimit 2 12  -- | Construct a new rate limit with the given penalty and threshold. newRateLimit ::