diff --git a/Befunge.hs b/Befunge.hs
new file mode 100644
--- /dev/null
+++ b/Befunge.hs
@@ -0,0 +1,512 @@
+module Main 
+    where
+
+--- Copyright Brandon Simmons, 2010
+--- http://coder.bsimmons.name/blog/ 
+
+-- TODO:
+    -- performance improvements
+    -- consider switch over to IO Array or Vector?
+    -- catch errors in exec block
+    -- constrain grid to max proportions of array,
+    --    - expanding up to 80x25 when we have a 'p'
+    --   command outside the grid.
+    --    - Warn when we try to expand past 80x25, but
+    --   do expand.
+
+
+-- helpers:
+import System.Environment
+import Data.Char
+import Control.Arrow (first,second,(&&&),(|||))
+
+-- we need to be able to modify our array efficiently
+-- on 'p' calls. Using an IO Array would be easy here. For
+-- now we use basic unboxed immutable array. 
+import Data.Array.Unboxed
+
+-- we do a lot of work with IO in the State monad using StateT:
+   --- using 'mtl' library
+import Control.Monad.State.Strict
+   --- using 'transformers' library:  SLOWER THAN 'MTL'
+--import Control.Monad.Trans.State.Strict
+--import Control.Monad
+--import Control.Monad.IO.Class
+
+-- we need to be able to do randomness if we see '?':
+import System.Random
+
+-- error catching:
+import System.IO
+import System.IO.Error
+
+--------------------------------------------------------------------------------
+
+-- position of the "program counter":
+type Position = (Int,Int)
+
+-- directions as contintuations:
+type Direction = Position -> Position
+
+-- the source code is mapped onto a 2d array as Int ASCII values:
+type Code = UArray Position Int
+
+-- The stack stores integers, per the Funge-93 spec. When in "stringmode"
+-- we push the ASCII value of the characters we read: 
+type Stack = [ Int ]
+
+-- the state of our befunge program's execution. This is passed around
+-- and modified as IO actions are performed:
+data ProgramState = 
+    ES { -- state of the code and stack:
+         code :: Code,    
+         stack :: Stack,
+         -- state of program flow:
+         position :: Position, 
+         direction :: Direction,
+         haltBit :: Bool,
+         -- random generator:
+         randGen :: StdGen, 
+         -- should we announce messages and warnings?:
+         verbose :: Bool
+        } 
+
+-- the default initial state of a befunge computation:
+defaultState =  ES  { 
+         -- these are defaults:
+         haltBit    = False,
+         position   = (0,0), 
+         direction  = right,
+         stack      = [],
+         randGen    = mkStdGen 31337, 
+         verbose    = True,  
+         code       = array ((0,0),(0,0)) []  }
+
+
+
+-- we are using the State monad for our plumbing, but we need to be in 
+-- the IO monad, so we use the State monad transformer! This is our
+-- read-evaluate-print loop:
+type REPL a = StateT ProgramState IO a
+
+-- our command line paramaters:
+data Opts = Opts { quiet :: Bool,
+                   allow_oversize :: Bool,
+                   seed :: Maybe Int,
+                   srcFile :: FilePath  }
+
+-- by default we assume input is a correct funge-93 program:
+defaultOpts = Opts False False Nothing ""
+                           
+usage = "\n\tusage: " ++
+    "befunge-93 [--quiet] [--allow-oversize] [--seed INT] source.bf\n"
+
+
+--------------------------------------------------------------------------------
+                       --PROGRAM INITIALIZATION--
+--------------------------------------------------------------------------------
+
+main = do 
+    -- parse command line options, then build our initial state for our befunge
+    -- computation, catching any IO errors in the process:
+    --state_i <- try $ processOpts . parseArgs =<< getArgs
+    args <- getArgs
+    opts <- either parsingErrors return (parseArgs args)
+    state_i <- try $ processOpts opts
+    
+    -- it seems most programs expect input to be line-buffered: 
+    hSetBuffering stdin LineBuffering
+
+     -- if there are errors, then print them and exit...
+    either processingErrors
+           -- else supply our initial state to the State/IO magic monadic
+           -- machinery and begin executing our befunge program:
+           (evalStateT evalLoop)  state_i
+
+
+--------------------------------------------------------------------------------
+                           --EVALUATION LOOPS--
+--------------------------------------------------------------------------------
+
+evalLoop :: REPL ()
+evalLoop = do
+     -- extract the command at our position & execute it:
+    getCmd >>= execute
+     -- halt if @ command issued, else move and recurse:
+    halting <- gets haltBit
+    unless halting (move >> evalLoop) 
+       
+
+-- we push characters' ASCII values onto the stack until we hit " again:
+stringModeLoop :: REPL ()
+stringModeLoop = do 
+    c <- getCmd
+    unless (c == '"') $ do
+           push (ord c)
+           move
+           stringModeLoop
+    
+-- this is the code that does all the work: a function which takes a program
+-- state and does IO operations in the State/IO monads:
+execute :: Char -> REPL ()
+execute c = 
+    case c of
+    -- stack operations: --
+         '+' -> do (a,b) <- pop2
+                   push (a+b)
+
+         '-' -> do (a,b) <- pop2
+                   push (b-a)
+         
+         '*' -> do (a,b) <- pop2
+                   push (a*b)
+         
+         -- according to the befunge-98 spec, befunge-93 should ask the user
+         -- what the result of the division by zero should be. so elegant:
+         '/' -> do (a,b) <-pop2
+                   safeZero  b quot a  >>= push 
+         
+         '%' -> do (a,b) <- pop2
+                   safeZero  b rem a  >>= push  
+                
+         '!' -> do i <- pop
+                   if i == 0 
+                      then push 1
+                      else push 0
+
+         '`' -> do (a,b) <- pop2 
+                   if b>a
+                      then push 1
+                      else push 0
+
+         '$' -> do pop	
+                   return ()
+         
+         -- Pop value and output as an integer. funge-98 spec calls for
+         -- integer to be followed by a space, so we'll do that too:
+         '.' -> do i <- pop
+                   liftIO $ putStr $ show i ++" "
+         
+         -- Pop value and output as ASCII character
+         ',' -> do i <- pop
+                   liftIO $ putChar $ chr i
+
+         '\\' -> do (a,b) <- pop2
+                    push a
+                    push b
+         
+         ':' -> do a <- pop
+                   replicateM_ 2 (push a)
+         
+    -- program flow commands: --
+         ' ' -> return ()    
+
+         '>' -> setDirection right
+        
+         '<' -> setDirection left	
+       
+         '^' -> setDirection up
+      
+         'v' -> setDirection down
+         
+         '?' -> getRandomDirection >>= setDirection 
+     
+         -- hop over the next cell:
+         '#' -> move
+    
+         '@' -> halt
+         
+    -- stack and program flow: --
+         '"' -> move  >>  stringModeLoop
+                   
+         
+         '_' -> do a <- pop
+                   if a == 0
+                      then setDirection right
+                      else setDirection left
+         
+         '|' -> do a <- pop 	
+                   if a == 0
+                      then setDirection down
+                      else setDirection up
+         
+    -- IO operations: --
+         'p' -> do (y,x) <- pop2
+                   pop  >>= putCell (x,y) 
+                   
+         'g' -> do (y,x) <- pop2 	
+                   getCell (x,y) >>= push
+
+         '&' -> liftIO askInt >>= push
+         
+         '~' -> liftIO askChar >>= push
+
+         x -> if isDigit x 
+               then push (digitToInt x)
+                -- halt and complain if invalid command:
+               else do loc <- gets position
+                       halt
+                       maybeSay$ "unknown command '" ++ show x ++ 
+                                 "' in code path at " ++ show loc ++
+                                 ". Maybe you want a funge-98 interpreter?"
+    
+
+--------------------------------------------------------------------------------
+                             -- LOOP HELPERS --  
+--------------------------------------------------------------------------------
+
+    -- -- -- SPECIAL ARITHMETIC -- -- --
+
+safeZero :: Int -> (Int -> Int -> Int) -> Int -> REPL Int
+safeZero b func a =
+       if a /= 0
+          then return (b `func` a)
+          else do liftIO $ putStr 
+                     "\ndiv by zero; enter desired Int result: "
+                  liftIO askInt
+                  
+
+    -- -- -- STACK HELPERS -- -- --
+
+-- when empty stack, we are supposed to pop 0:
+pop :: REPL Int
+pop = do 
+    st <- gets stack                                    
+    if null st                                      
+       then return 0                                
+       else do modify $ \s-> s{stack = tail st}     
+               return (head st)                     
+
+pop2 :: REPL (Int,Int)
+pop2 = do a <- pop
+          b <- pop
+          return (a,b)
+
+push :: Int -> REPL ()
+push c = modify $ \s-> s{stack = c : stack s}
+    
+
+
+    -- -- -- MISC STATE HELPERS -- -- --
+
+-- the command character at our position:
+getCmd :: REPL Char    
+getCmd = do p <- gets position 
+            gets (chr . (! p) . code)    
+
+
+getCell :: Position -> REPL Int
+getCell xy = do
+    xy' <- wrap xy
+    unless (xy == xy') (maybeSay "warning: getCell out of bounds. wrapping.")
+    gets ((! xy') . code)
+
+
+-- modify our array by changing its value at position xy:
+putCell :: Position -> Int -> REPL ()
+putCell xy c = do
+    xy' <- wrap xy
+    unless (xy == xy') (maybeSay "warning: putCell out of bounds. wrapping.")
+    a <- gets code
+    modify $ \s-> s{code = a//[(xy',c)] }
+
+
+-- update state with new seed, returning a random direction:
+getRandomDirection :: REPL Direction
+getRandomDirection = do
+    (i,g) <- gets (randomR (0,3) . randGen)
+    modify $ \s-> s{randGen = g}
+    return ([up,down,left,right] !! i)
+
+
+    -- -- -- PROGRAM FLOW HELPERS -- -- --
+
+halt :: REPL ()
+halt = modify $ \s-> s{ haltBit = True }
+
+
+setDirection :: Direction -> REPL ()
+setDirection d = modify $ \s-> s{direction = d}
+       
+
+move :: REPL ()
+move = do
+    -- we need to know when we're out of bounds, so we can wrap:
+    (pos,mv) <- gets (position &&& direction)
+    pos' <- wrapSimple (mv pos)
+    modify $ \s-> s{position = pos'}
+
+
+-- if we exceed bounds, we wrap like a torus:
+wrap :: Position -> REPL Position
+wrap (pX,pY) = do
+    (bX,bY) <- gets (snd . bounds . code)
+    let x = pX `mod` (bX+1)
+        y = pY `mod` (bY+1)
+    return (x,y)
+
+--   DIFFICULT TO TELL IF THIS IS SIGNIFICANTLY FASTER THAN `wrap`:
+-- a more efficient wrapping function, for the program counter. Because
+-- the PC moves only one space at a time, we can use this in the 'move'
+-- function:
+wrapSimple :: Position -> REPL Position
+wrapSimple (pX,pY) = do
+    (bX,bY) <- gets (snd . bounds . code)
+    let x | pX < 0  = bX
+          | pX > bX = 0
+          | otherwise = pX
+        y | pY < 0  = bY
+          | pY > bY = 0
+          | otherwise = pY
+    return (x,y)
+
+
+
+-- we use continuations for the direction, because we never need to inspect
+-- our direction, thus a function is appropriate:
+down, up, left, right :: Direction
+down  = second (+1)
+right = first  (+1)
+left  = first  (subtract 1)
+up    = second (subtract 1)
+
+
+
+    -- -- -- IO HELPERS -- -- --
+
+askInt :: IO Int
+askInt = do n <- getLine 
+            if isInt n 
+               then return (read n)
+               else putStr "NOT AN INT. Try again: " >> askInt
+                    
+
+askChar :: IO Int
+askChar = getChar >>= return . ord    
+
+
+isInt :: String -> Bool
+isInt = all isDigit
+
+    -- -- -- ERROR AND DEBUGGING HELPERS -- -- --
+
+maybeSay :: String -> REPL ()
+maybeSay m = do
+    v <- gets verbose
+    when v (liftIO $ putStrLn m )
+
+
+
+--------------------------------------------------------------------------------
+                          -- MAIN IO HELPERS --
+--------------------------------------------------------------------------------
+
+
+    -- -- -- CLI ARGUMENTS PROCESSING -- -- -- 
+
+-- convert user-supplied options in our Opt container into
+-- an initial state, in the IO monad:
+processOpts :: Opts -> IO ProgramState
+processOpts os = do
+   let loud  = not $ quiet os        -- print warnings
+       bigOk = allow_oversize os     -- okay if grid is oversize
+   
+    -- build code grid from source file; we return the code array
+    -- and a Bool set to True if the input file was larger than the
+    -- standard 80x25:
+   hdl <- openFile (srcFile os) ReadMode
+    -- This should be compatible with UTF-8, and any symbols outside
+    -- the allowed Funge-93 charset will raise an error in `execute`:
+   hSetEncoding hdl latin1 
+   src <- hGetContents hdl
+   let (wasBig,arr) = buildGrid bigOk src
+    
+    -- initialize the RNG either from user-supplied seed, or
+    -- with the system generator:
+   rng <- maybe getStdGen (return . mkStdGen) (seed os)
+
+   when (loud && wasBig) $ putStrLn $
+        if bigOk
+           then "WARNING: using code area larger than 80x25."
+           else "WARNING: source was truncated to 80x25; " ++ 
+                "use --allow-oversize for source code of " ++   
+                "arbitrary dimensions."                         
+   
+   return$ defaultState{ code    = arr,
+                         randGen = rng,
+                         verbose = loud }
+
+
+-- we catch only errors of parsing the command line arguments here.
+-- btw this frankly seems easier than System.Console.GetOpts:
+parseArgs :: [String] -> Either IOError Opts
+parseArgs [] = Left$ userError$ "SOURCE FILE REQUIRED:"++ usage
+parseArgs as = parse as defaultOpts
+    where  -- the source code file:
+          parse [src] opts = Right$ opts{srcFile = src}
+           
+           -- simple optional flags:
+          parse ("--quiet":as) os = parse as os{quiet = True}
+          parse ("--allow-oversize":as) os = parse as os{allow_oversize = True}
+           
+           -- options with args:
+          parse ("--seed":s:as) os = 
+                if isInt s
+                   then parse as os{seed = Just$ read s}
+                   else Left$ userError$ "SEED MUST BE AN INTEGER:"++usage
+           
+           -- parse errors:
+          parse _ _ = Left$ userError $ "ERROR PARSING OPTIONS"++usage
+
+
+
+    -- -- -- INPUT PROCESSING -- -- --
+
+
+-- returns the array of source code, along with a Bool denoting whether
+-- the input source file exceeded 80x25 in any of it's dimensions:
+buildGrid :: Bool -> String -> (Bool,Code)
+buildGrid allowing_oversize str =
+    let ls = lines $ fixLineBreaks str
+         -- our array must be at least 80x25, but we will expand it if
+         -- the source seems to exceed those dimensions anywhere:
+        sxN = maximum $ 79 : map (subtract 1 . length) ls
+        syN = max 24 (length ls - 1)
+        (xN,yN) = if allowing_oversize
+                     then (sxN, syN)
+                     else (79,24)
+         -- we pad the array with spaces:
+        pad = repeat ' '
+        ls' = take (yN+1) (ls ++ repeat pad)
+         -- array is indexed from (0,0) in the upper left corner:
+        coords = [ (x,y) | y <- [0..yN], x <- [0..xN] ]
+        cells  = map ord $ concatMap (take (xN+1) . (++pad)) ls'
+         -- was the source input bigger than 80x25?:
+        big = sxN > 79 || syN > 24
+        arr = array ((0,0),(xN,yN)) (zip coords cells)
+     in (big, arr)
+
+
+
+--------------------------------------------------------------------------------
+                       -- ERROR AND FILE HANDLING --  
+--------------------------------------------------------------------------------
+
+-- convert all three line break types to newlines. This isn't required by
+-- the spec, but is useful:
+fixLineBreaks :: String -> String
+fixLineBreaks [] = []
+fixLineBreaks ('\r':'\n':xs) = '\n' : fixLineBreaks xs --win
+fixLineBreaks ('\r':xs)      = '\n' : fixLineBreaks xs --old mac
+fixLineBreaks (x:xs)         = x : fixLineBreaks xs
+
+-- minimal error handling. An error here seems to mean File Encoding
+-- issues:
+processingErrors :: IOError -> IO ()
+processingErrors e = do
+    print e
+    putStrLn "* Please report this bug to me so I can fix it *"
+
+-- raise the error retuned by the parsing function: parseArgs
+parsingErrors :: IOError -> IO a
+parsingErrors = ioError
diff --git a/Befunge93.cabal b/Befunge93.cabal
new file mode 100644
--- /dev/null
+++ b/Befunge93.cabal
@@ -0,0 +1,64 @@
+-- Befunge-93.cabal auto-generated by cabal init. For additional
+-- options, see
+-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
+-- The name of the package.
+Name:                Befunge93
+
+-- The package version. See the Haskell package versioning policy
+-- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
+-- standards guiding when and how versions should be incremented.
+Version:             0.1
+
+-- A short (one-line) description of the package.
+Synopsis:            An interpreter for the Befunge-93 Programming Language
+
+-- A longer description of the package.
+Description:         An interpreter for the '93 spec of the esoteric programming language Befunge
+
+-- URL for the project homepage or repository.
+Homepage:            http://coder.bsimmons.name/blog/2010/05/befunge-93-interpreter-on-hackage
+
+-- The license under which the package is released.
+License:             BSD3
+
+-- The file containing the license text.
+License-file:        LICENSE
+
+-- The package author(s).
+Author:              Brandon Simmons
+
+-- An email address to which users can send suggestions, bug reports,
+-- and patches.
+Maintainer:          brandon.m.simmons@gmail.com
+
+-- A copyright notice.
+-- Copyright:           
+
+-- Stability of the pakcage (experimental, provisional, stable...)
+Stability:           Experimental
+
+Category:            Compilers/Interpreters
+
+Build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or
+-- a README.
+Extra-source-files: README, Tests.hs, tests/phlamethrower/divtest.bf, tests/phlamethrower/compat.bf, tests/phlamethrower/README, tests/mycology/mycology.b98, tests/mycology/readme.txt, tests/mycology/license.txt
+
+-- Constraint on the version of Cabal needed to build this package.
+Cabal-version:       >=1.2
+
+
+Executable Befunge93
+  -- .hs or .lhs file containing the Main module.
+  Main-is:          Befunge.hs   
+  
+  -- Packages needed in order to build this package.
+  Build-depends:       base >= 2 && < 5, mtl < 2, array < 4, random < 2
+  
+  -- Modules not exported by this package.
+  -- Other-modules:       
+  
+  -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.
+  -- Build-tools:         
+  
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Brandon Simmons 2010
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Brandon Simmons nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README b/README
new file mode 100644
--- /dev/null
+++ b/README
@@ -0,0 +1,23 @@
+A Befunge Interpreter by jberryman
+--------------------------------
+
+The interpreter works on only Befunge-93 files, not the newer '98 version
+of the language. You can run the interpreter with:
+
+    $> Befunge93 [--quiet] [--allow-oversize] [--seed INT] source.bf
+
+Explanation of options:
+
+    --quiet     
+        Don't print any interpreter warnings or messages
+
+    --allow-oversize
+        Stretch the code area to fit the dimensions of the
+        file. A strict funge-93 interpreter should truncate
+        the file to 80x25 characters.
+
+    --seed
+        Provide your own random seed
+
+Please send me any bug reports, suggestions, etc. 
+    brandon.m.simmons@gmail.com
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+import Distribution.Simple
+main = defaultMain
diff --git a/Tests.hs b/Tests.hs
new file mode 100644
--- /dev/null
+++ b/Tests.hs
@@ -0,0 +1,61 @@
+module Main
+    where
+
+import System.Process
+import System.IO
+import System.Exit
+import Control.Monad
+
+main = do 
+      (_,testH1,_,_) <- runInteractiveCommand $
+             "runhaskell Befunge.hs tests/mycology/mycology.b98"
+      test1 <- hGetContents testH1
+      
+      (_,testH2,_,_) <- runInteractiveCommand $
+             "runhaskell Befunge.hs tests/phlamethrower/compat.bf"
+      test2 <- hGetContents testH2
+      
+      (_,testH3,_,_) <- runInteractiveCommand $
+             "runhaskell Befunge.hs tests/phlamethrower/divtest.bf"
+      test3 <- hGetContents testH3
+      
+      -- test output:
+      putStr test1
+      when (test1 /= goodTest1) exitFailure
+      putStr test2
+      when (test2 /= goodTest2) exitFailure
+      putStr test3
+      when (test3 /= goodTest3) exitFailure
+
+goodTest1 = unlines $
+    ["WARNING: source was truncated to 80x25; use --allow-oversize for source code of arbitrary dimensions.",
+    "0 1 2 3 4 5 6 7 ",
+    "GOOD: , works",
+    "GOOD: : duplicates",
+    "GOOD: empty stack pops zero",
+    "GOOD: 2-2 = 0",
+    "GOOD: | works",
+    "GOOD: 0! = 1",
+    "GOOD: 7! = 0",
+    "GOOD: 8*0 = 0",
+    "GOOD: # < jumps into <",
+    "GOOD: \\ swaps",
+    "GOOD: 01` = 0",
+    "GOOD: 10` = 1",
+    "GOOD: 900pg gets 9",
+    "GOOD: p modifies space",
+    "GOOD: wraparound works",
+    "UNDEF: edge # skips column 80",
+    "GOOD: Funge-93 spaces",
+    "The Befunge-93 version of the Mycology test suite is done.",
+    "Quitting..."]
+
+goodTest2 = unlines $
+    ["warning: getCell out of bounds. wrapping.",
+    "Get/put wraps",
+    "Cells are >8 bit",
+    "Edge jumps work",
+    "Negative remainders work",
+    "@ in stringmode works"]
+
+goodTest3 = ""
diff --git a/tests/mycology/license.txt b/tests/mycology/license.txt
new file mode 100644
--- /dev/null
+++ b/tests/mycology/license.txt
@@ -0,0 +1,24 @@
+Copyright (c) 2006-2008, Matti Niemenmaa
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+	* Neither the name of the project nor the names of its contributors may be
+	  used to endorse or promote products derived from this software without
+	  specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/tests/mycology/mycology.b98 b/tests/mycology/mycology.b98
new file mode 100644
Binary files /dev/null and b/tests/mycology/mycology.b98 differ
diff --git a/tests/mycology/readme.txt b/tests/mycology/readme.txt
new file mode 100644
--- /dev/null
+++ b/tests/mycology/readme.txt
@@ -0,0 +1,498 @@
+This is the Mycology Befunge-98 test suite, by Matti "Deewiant" Niemenmaa.
+
+To contact me, E-mail me. The address for Mycology-related things is
+matti.niemenmaa+mycology at the domain iki.fi.
+
+Mycology is licensed under the so-called 3-clause BSD license. See license.txt
+for the text of the license.
+
+Contents of this readme:
+	Changelog
+	Quick summary
+	More detailed info
+	Fingerprints
+	Notes on particular messages
+		"# across left edge"
+		"101-{}"
+		"4k #" and "2k ;;;5"
+		"2k6"
+
+Mycology changelog:
+-------------------
+
+	2009-04-04    - Made the u test not abort if the storage offset isn't (0,0).
+	              - Bugfix: u outputs the correct error message if it fails with
+	                a positive count.
+	2009-03-31    - Bugfix: some w were misaligned in the TOYS test.
+	2009-03-29    - Bugfix: 1y bits testing was really broken, really fixed it
+	                now.
+	2009-03-28    - Update: FILE's R really should reflect at EOF.
+	              - Update: removed the 'G to an infinite loop' test from STRN,
+	                        it makes sense that it does indeed loop forever.
+	              - Bugfix: it was always claimed that I/O was buffered.
+	              - Bugfix: 1y being greater than 15 was complained about:
+	                        should have been 31.
+	2008-11-15    - ) with a negative count wasn't actually tested, ( was used
+	                both times.
+	2008-10-17    - If o doesn't work, it is reported that i in binary mode will
+	                not be tested.
+	2008-09-21    - Fixed a misalignment in the fingerprint loading code.
+	2008-09-16    - MycoTRDS now expects ticks to start from zero, thus the
+	                expected value of G is one lower.
+	2008-09-15    - Fixed a misalignment in the u test with a negative argument.
+	2008-09-14    - Made the wraparound with non-cardinal delta test catch a
+	                common case.
+	2008-09-13    - Bugfix: test for k with negative argument was expecting
+	                incorrect k behaviour.
+	              - Bugfix: "GOOD: SGML spaces" was never output, who knows for
+	                how long that's been disabled.
+	              - Bugfix: IMAP check for non-ASCII now says it works when it
+	                works.
+	              - Update: IMAP check for non-ASCII is now GOOD when it works
+	                and BAD otherwise, per the latest spec.
+	              - Update: IMAP now checks mappings outside range 0-255.
+	              - Update: INDV now expects the logical order, reporting BAD
+	                otherwise.
+	2008-09-12    - Reduce stacking in HRTI test.
+	              - Corrected typo in a TOYS error message.
+	2008-09-10    - Made the check for wraparound with non-cardinal delta a bit
+	                stricter (instead of a delta of (12,0) it uses (13,2)).
+	2008-09-06    - Fixed a misspelled error message in mycouser.b98 for
+	                Befunge-93 interpreters.
+	              - Fixed a bug in 2k6 testing that led to an infinite loop.
+	2008-08-30    - Fixed the case where SCKE is included in SOCK.
+	2008-08-28    - SOCK and SCKE fixed: much code still assumed that A
+	                overwrites the original socket, and thus wrong sockets were
+	                being given to K and P.
+	2008-08-20    - Bugfix: results for the ;; concurrency test were off by one.
+	              - Test new A and O instructions in SUBR.
+	2008-08-19    - Bugfix: results for the concurrency tests 5kz and "a  b"
+	                were incorrect.
+	2008-08-14    - New fingerprint: DATE.
+	2008-08-13    - I had managed to get the way y should work as a pick
+	                instruction completely wrong. Thanks to Johannes Laire for
+	                noticing this and notifying me.
+	2008-08-11    - Removed PNTR (the same as INDV), it wasn't meant to exist
+	                any more.
+	2008-08-09    - The new addition to the FILE fingerprint, D, is now tested.
+	              - Using it, created .tmp files can now be removed from within
+	                Mycology.
+	2008-07-26    - Thanks to Arvid Norlander, Chris Pressey, and Mike Riley,
+	                none of k is UNDEF any longer, and some tests were changed
+	                to reflect the intended behaviour.
+	              - Expanded the null byte test.
+	              - Bugfix: in SOCK, the original socket should /not/ be
+	                destroyed: flipped a GOOD and BAD.
+	2008-07-19    - Now testing whether null bytes are handled correctly.
+	2008-05-02    - Bugfix: mycouser.b98 had a forgotten r in place of a (.
+	2008-03-30    - Bugfix: J test in SUBR was misaligned.
+	2008-03-29    - Bugfix: D failing in TOYS had no error message.
+	              - Bugfex: L and R in TOYS had incorrect error messages.
+	2008-03-15    - Bugfix: time output for hours <= 10 was incorrect.
+	2008-03-13    - Bugfix: a missing ; caused an incorrect error message.
+	2008-03-11    - i and o are now UNDEF if unavailable.
+	              - PERL is now tested with "5-1" instead of the palindromic
+	                "2+2". Thanks to Alex Smith for the input.
+	2008-02-02    - 1k # now considered UNDEF.
+	2008-01-09    - More typos or incorrect messages.
+	2007-12-02    - Corrected some typos.
+	2007-09-22    - Minor bugfixes.
+	2007-09-20    - Public release.
+	2007-07-26    - Creation of mycoterm.b98 and mycotrds.b98.
+	2007-06-17    - Creation of mycouser.b98.
+	2007-01-06    - Creation of mycorand.bf.
+	2006-12-31    - Creation of sanity.bf and mycology.b98.
+
+Quick summary of how to test your Befunge interpreter:
+-------------
+
+	- If, at any point, you get messages beginning with "BAD:", correct the
+	  issues before moving on to the next step.
+	- If your interpreter needs any command line switches for
+	  standard-conforming mode, use them.
+	- Run sanity.bf and make sure it outputs "0 1 2 3 4 5 6 7 8 9 ".
+	- Run mycology.b98, make sure it outputs "0 1 2 3 4 5 6 7 " and that there
+	  are no lines beginning with "BAD:" anywhere in the output.
+	- If your interpreter is Befunge-93 only, run mycorand.bf and examine the
+	  results.
+	- Run mycouser.b98: for complete testing, run it a few times and try giving
+	  it both valid and invalid input.
+	- If your interpreter should support one or both of the NCRS and TERM
+	  fingerprints, run mycoterm.b98.
+	- If your interpreter should support the TRDS fingerprint, run mycotrds.b98.
+
+More detailed info:
+-------------------
+
+Files with the .bf extension are valid Befunge-93 source code, while *.b98 are
+intended for Befunge-98 interpreters. mycology.b98 and mycouser.b98 are
+exceptions: they work in both standards - if the standards are implemented
+correctly.
+
+Note for Befunge-93: mycology.b98 is much bigger than the 80x25 allowed in
+Befunge-93. If your interpreter bails out on a file bigger than the maximum
+allowed, you can simply take the 80x25 square starting at the top left corner
+of mycology.b98 into a separate file and use that for testing.
+
+In order to test the absolute basics of the interpreter, feed it the file
+sanity.bf. This tests that the IP (instruction pointer) begins at the correct
+point in Funge-Space and moves in the correct direction. In addition, it makes
+sure the following instructions work:
+
+Decimal  ASCII  Instruction
+
+  32            Space
+  35       #    Trampoline
+  46       .    Output Decimal
+  48       0    Push Zero
+  49       1    Push One
+  50       2    Push Two
+  51       3    Push Three
+  52       4    Push Four
+  53       5    Push Five
+  54       6    Push Six
+  55       7    Push Seven
+  56       8    Push Eight
+  57       9    Push Niner
+  64       @    Stop
+
+The above are the absolute minimum which the interpreter must support. In
+addition, it should reflect upon encountering an instruction it does not
+recognize.
+
+sanity.bf will, if the interpreter supports all of the above, output the string
+"0 1 2 3 4 5 6 7 8 9 ". If it doesn't, anything might happen: sanity.bf does
+_not_ fail safe.
+
+Hereafter the actual testing in mycology.b98 can be conducted. The initial
+behaviour of the program is to output a code, using the Output Decimal
+instruction, after having successfully tested a certain instruction. These
+codes are as follows:
+
+Code  Decimal  ASCII  Instruction         Notes
+
+ 0      62       >    Go East
+ 1     118       v    Go South
+ 2      60       <    Go West
+ 3      94       ^    Go North
+ 4      36       $    Pop                 Explicitly testing whether popping an
+                                          empty stack works as it should is
+                                          done separately, later.
+
+ 5      34       "    Toggle Stringmode   If no reflection on the instruction
+                                          occurs, but the string's contents are
+                                          interpreted as instructions, a second
+                                          "4 " is output before exiting.
+
+ 6      95       _    East-West If        If the comparison is done incorrectly
+                                          (i.e. the wrong direction is taken)
+                                          an additional "5 " is output.
+
+ 7      43       +    Add
+
+For example, if the interpreter emits only "0 1 ", the Go East and Go South
+instructions were correctly interpreted, but a reflection occurred upon meeting
+Go West. A conforming interpreter should output every code in the listing once.
+
+These tests are very simple, due to the basic nature of the instructions
+involved. All that is tested is whether a reflection occurs or not. If
+mycology.b98 claims that an instruction which appears to work perfectly is
+failing, make sure that the above do what they should.
+
+Having tested the above, mycology.b98 tests the Output Character instruction
+and hence reverts to plain English output. If there is no output after code 7,
+the Output Character instruction does not function as it should.
+
+The output format changes to lines beginning with "BAD:" or "GOOD:", followed
+by a description of what the interpreter does wrong or correctly, respectively.
+Some, but not all, "BAD" lines are followed by a Stop instruction - these tend
+to be features which are deemed useful enough that they are used later in the
+program. (Or, possibly, features which may be used later, but aren't: it's hard
+to modify Befunge source code after it's first written, so there may be some
+cases where a Stop isn't necessary but is there anyway.) In some cases, a Stop
+was added to simplify the code: the Befunge-93 area is particularly snarly,
+since space is at a premium.
+
+Some lines begin with "UNDEF:". This means that the specification is either
+ambiguous or completely ignorant of an issue, and so different possibilities
+are acceptable. It is possible that some such undefined cases may result in
+"BAD:" if the interpreter does something completely unexpected, but there is no
+"GOOD:" equivalent, only "UNDEF:".
+
+Some comment lines not beginning with "BAD:", "GOOD:", or "UNDEF:" are also
+emitted occasionally, in order to clarify what is going on.
+
+Other notes on mycology.b98:
+
+	Befunge-93 detection relies on the interpreter using only the first 80
+	characters of lines, since Befunge-93 has a Funge-Space of 80x25 cells.
+
+	The checks are generally very simple. For instance, if the Subtract or
+	Multiply instructions empty the stack, they will be considered to work
+	properly: only a few checks are done, and they all check for zero.
+
+	Instructions are assumed to work if they pass one test (for the more
+	complicated instructions, more tests are needed, but every behaviour of the
+	instruction is still tested only once). If, for instance, an instruction
+	works the first 41 times and randomly fails every third time after that,
+	Mycology will probably not detect it, but will silently fail or, in the
+	worst case, pass.
+
+	Instructions are assumed to be at least somewhat sane: e.g. | should either
+	reflect or pop a cell and cause the IP to start moving north or south. Not
+	east or west, or to teleport to a random location in Funge- Space, or push
+	72 ampersands onto the stack. It is the tester's responsibility, not
+	Mycology's, to make sure that the interpreter doesn't go crazy and perform
+	malicious acts. You use Mycology at your own risk.
+
+See the end of this file for notes on particular messages.
+
+The following instructions are _not_ tested by mycology.b98 (those preceded by
+an asterisk are tested if the interpreter is detected as supporting
+Befunge-98):
+
+Decimal  ASCII  Instruction
+
+  37       %    *Remainder
+  38       &    Input Decimal
+  47       /    *Divide
+  61       =    Execute
+  63       ?    *Go Away
+ 126       ~    Input Character
+
+The division and input instructions are tested in mycouser.b98 because they all
+require user intervention (the division instructions only when dividing by
+zero, but I felt it would be better to not split the testing of an instruction
+into two files). Their correct behaviour is also very difficult to verify
+without a knowledgeable user.
+
+Go Away is tested separately in mycorand.bf because it takes too much space to
+fit in the Befunge-93 area of mycology.b98. If the Befunge-98 instruction Input
+File works, mycorand.bf is loaded using it and Go Away is thus tested in
+mycology.b98.
+
+Execute is completely untested, because to get a reliable result would require
+testing various commands and noting their behaviours on different platforms. An
+educated guess regarding the user's platform is in order, and overall it would
+be too complicated. It is simplest to test this manually, rather than to try to
+cater for all cases in a suite such as Mycology.
+
+Implementation notes regarding mycorand.bf:
+
+	Beware! If Go Away is unimplemented and thus reflects, an infinite loop
+	is entered!
+
+	The testing is very simple: it is only made sure that Go Away causes the
+	instruction pointer to go at least once in every cardinal direction,
+	though it is always encountered from the same direction.
+
+	The number of tries it took to successfully go in every direction is
+	output, so an interpreter's implementer can make sure the number
+	fluctuates somewhat. The order in which the directions were generated is
+	also output, so that it can be verified that the order isn't always the
+	same.
+
+Make sure that the interpreter successfully passes the Befunge-93 area of
+mycology.b98 before loading mycorand.bf or mycouser.bf!
+
+Regarding fingerprints
+----------------------
+
+mycology.b98 tests every fingerprint that I am aware of, apart from FNGR, SGNL,
+and WIND. It is completely up to the interpreter's writer(s) whether any should
+be supported: a completely specification-conforming interpreter does not need
+to support any fingerprint at all, as long as the ( "Load Semantics" and )
+"Unload Semantics" instructions perform correctly.
+
+FNGR is not tested because its specifications contradict the Befunge-98
+specifications. It contains operations for performing on a single fingerprint
+stack, but the specifications for Befunge-98 state that there should be a stack
+of semantics for each instruction in the range [A, Z]. RC/Funge-98, the (only,
+as far as I know) interpreter implementing FNGR, fails some of Mycology's tests
+due to this.
+
+SGNL is not tested simply because it is platform-specific. There is no
+technical obstacle to it, only my own convictions regarding platform-specific
+code. If anybody wishes to write code to test it, feel free to send it to me,
+it may be worthy of addition to Mycology.
+
+WIND is not tested because I do not wish to support it in my interpreter, and
+thus I didn't feel like writing tests for it. RC/Funge-98 is the only
+interpreter supporting it, and if I had discovered any bugs in it I would have
+had to delve into unfamiliar code to make it even possible to test the whole
+thing. I decided it was too much work and left it out. Once again, the addition
+of WIND to Mycology is perfectly fine, but I won't be the one to write the
+code.
+
+The list of fingerprints which are tested:
+
+	Official Cat's Eye Technologies fingerprints:
+
+		"HRTI"  0x48525449  High-Resolution Timer Interface
+		"MODE"  0x4d4f4445  Funge-98 Standard Modes
+		"MODU"  0x4d4f4455  Modulo Arithmetic Extension
+		"NULL"  0x4e554c4c  Funge-98 Null Fingerprint
+		"ORTH"  0x4f525448  Orthogonal Easement Library
+		"PERL"  0x5045524c  Generic Interface to the Perl Language
+		"REFC"  0x52454643  Referenced Cells Extension
+		"ROMA"  0x524f4d41  Funge-98 Roman Numerals
+		"TOYS"  0x544f5953  Funge-98 Standard Toys
+		"TURT"  0x54555254  Simple Turtle Graphics Library
+
+	RC/Funge-98 fingerprints:
+
+		In all cases, the documentation is considered the primary source of how
+		an instruction should behave. Precise semantics have been inferred from
+		the RC/Funge-98 source code where not properly documented.
+
+		For all fingerprints involving vectors, RC/Funge-98 doesn't, for some
+		reason, use the IP's storage offset. Thus, the tests assume the same
+		behaviour.
+
+		"BASE"  0x42415345  I/O for numbers in other bases
+		"CPLI"  0x43504c49  Complex Integer extension
+		"DIRF"  0x44495246  Directory functions extension
+		"EVAR"  0x45564152  Environment variables extension
+		"FILE"  0x46494c45  File I/O functions
+		"FIXP"  0x46495850  Some useful math functions
+		"FPDP"  0x46504450  Double precision floating point
+		"FPSP"  0x46505350  Single precision floating point
+		"FRTH"  0x46525448  Some common forth [sic] commands
+		"IIPC"  0x49495043  Inter IP [sic] communicaiton [sic] extension
+		"IMAP"  0x494d4150  Instruction remap extension
+		"INDV"  0x494e4456  Pointer functions
+		"PNTR"  0x504e5452  (an alias of "INDV")
+		"SOCK"  0x534f434b  tcp/ip [sic] socket extension
+		"STRN"  0x5354524e  String functions
+		"SUBR"  0x53554252  Subroutine extension
+		"TERM"  0x5445524d  Terminal control functions
+		"TIME"  0x54494d45  Time and Date functions
+		"TRDS"  0x54524453  IP travel in time and space
+
+	Jesse van Herk's extensions to RC/Funge-98:
+
+		"JSTR"  0x4a535452
+		"NCRS"  0x4e435253  Ncurses [sic] extension
+
+	GLFunge98 fingerprints:
+
+		"SCKE"  0x53434b45
+
+Notes on particular messages output by mycology.b98
+---------------------------------------------------
+
+"UNDEF: # across left edge..."
+..............................
+
+Here, the line and file cases are considered separately. This is because some
+interpreters consider the Funge-Space as a rectangle: see below, using 0 to
+mark empty cells which are outside Funge-Space.
+
+>    v000
+v    >  >
+@00000000
+
+Even though the file doesn't contain the three spaces at the end of the first
+line, or any of the spaces at the end of the third line, the program's
+representation of Funge-Space does, because Funge-Space is padded out to the
+width of the longest line in the file.
+
+Because jumping across the edge of Funge-Space isn't mentioned in the
+specification, one cannot be sure as to what should happen. If it is considered
+that Funge-Space is infinitely surrounded by spaces, jumping across the edge of
+space shouldn't skip over anything. On the other hand, # jumps over "the next
+Funge-Space cell in [the instruction pointer's] path", which might not include
+this void.
+
+However, it may be that an existing space cell which is not part of this void
+is skipped over. Thus, both jumping over the edge of the physical edge of the
+file, with only the void in between, and jumping over the edge of a line which
+is shorter, but may contain the spaces as the 0s in the above example, are
+tested. Most interpreters have different behaviour for the two.
+
+"BAD: 101-{} doesn't leave stack top as 0 and next as 1"
+........................................................
+
+This is something which may be tricky to get right. Let's examine what happens.
+On each following line, the instruction comes first, followed by the stack
+stack, with the contents of each stack in square brackets, starting at the
+bottom.
+
+1 [1]
+0 [1, 0]
+1 [1, 0, 1]
+- [1, -1]
+
+This part is trivial. What happens next, however, varies.
+
+One incorrect possibility:
+{ [1, 0, 0], []
+} [1]
+
+Here, { pushes abs(-1) zeroes onto the SOSS before a new stack is pushed. Since
+there was no SOSS at that time, the zero pushed doesn't appear.
+
+This is the behaviour of the Flaming Bofine Befunge Interpreter version
+2003.0326, amended with the 2003.0722 and 2003.0726 patches.
+
+Another:
+{ [1, 0, 0], [0]
+} [1]
+
+It seems that here, abs(-1) zeroes are being pushed on the TOSS instead of the
+SOSS.
+
+This is the behaviour of the RC/Funge-98 interpreter, version 1.07, as well as
+of the RC/Funge-98 interpreter modified by Jesse van Herk, version 1.05.
+
+What should happen:
+{ [1, 0, 0, 0], []
+} [1, 0]
+
+This is the behaviour of the Conforming Concurrent Befunge-98 Interpreter,
+version 1.00.
+
+Let's see what the spec has to say about the subject:
+
+	"The { 'Begin Block' instruction pops a cell it calls n, then pushes a new
+	stack on the top of the stack stack, transfers n elements from the SOSS to
+	the TOSS, then pushes the storage offset as a vector onto the SOSS..."
+
+	"If n is negative, |n| zeroes are pushed onto the SOSS."
+
+In other words, { should:
+
+	Pop the -1 from the stack.                      [1]
+	Push a new stack on the stack stack.            [1], []
+	Since -1 < 0, push |-1| = 1 zero onto the SOSS. [1, 0], []
+	Push the storage offset onto the SOSS.          [1, 0, 0, 0], []
+
+"BAD: 4k #..." and "BAD: 2k ;;;5..."
+....................................
+
+In Funge-98, spaces and semicolons are ethereal. The "next instruction"
+mentioned in the spec refers specifically to the next instruction the
+interpreter would execute if the k would not be there.
+
+Hence, k always executes its operand at the k, but reaches past all spaces and
+semicolons to find the operand. Hence 2k ;;;5 should execute the 5 twice at the
+k. (See the next section for the reason why it should be executed a third time
+afterward.)
+
+"BAD: 2k6..."
+.............
+
+The specification does not say that the operand should be skipped over after
+execution. The only special case is when the amount of times to execute is
+zero.
+
+This means that 2k6 should indeed first push 2 sixes at the k, and then a third
+when encountering the 6 itself.
+
+This also means that there is no way to execute an instruction only once: 1k6
+results in two sixes. (Another IP may certainly modify the 6 immediately after
+the k is executed, but that's a somewhat unlikely case and not exactly a good
+way to handle this limitation.)
+
+The spec is somewhat unclear on the entirety of k, but both of the above issues
+have been confirmed with Chris Pressey.
diff --git a/tests/phlamethrower/README b/tests/phlamethrower/README
new file mode 100644
--- /dev/null
+++ b/tests/phlamethrower/README
@@ -0,0 +1,3 @@
+Test files in this directory gratefully stolen from:
+
+    http://www.phlamethrower.co.uk/befunge/#files
diff --git a/tests/phlamethrower/compat.bf b/tests/phlamethrower/compat.bf
new file mode 100644
--- /dev/null
+++ b/tests/phlamethrower/compat.bf
@@ -0,0 +1,8 @@
+1-0g:"Z"-#v_$91+"sparw tup/teG">:#,_$               v                          Z
+          >:" "-#v_$91+"ecaps snruter teg BOO">:#,_$v
+v                >0" snruter teg BOO">:#,_$.91+,    >
+>8:+:*11p11g#v_91+"tib 8 dengis"01-11p11g!#v_"nu">" era slleC">:#,_v
+vv           >91+"tib 8>"                  >     ^                 >91+"krow " #
+ >        >"spmuj egdE">:#,_   91+"krow "04-3%1+#v_        >"sredniamer evitag"v
+>"ton od "^                                      >"ton od "^
+"eN">:#,_  91+"skrow edomgnirts ni @">:#,_@                                    >
diff --git a/tests/phlamethrower/divtest.bf b/tests/phlamethrower/divtest.bf
new file mode 100644
--- /dev/null
+++ b/tests/phlamethrower/divtest.bf
@@ -0,0 +1,6 @@
+0 91+ -01p>0 91+ -11p>01g11g:#v_                                               v
+
+
+>!#@_01p  ^                   >/02p01g11g%12p02g11g*12g+:22p01g-#v_            v
+^- +19 :+1g10$<                         v,+19.g22.g21.g20.g11.g10<
+11g1+: 91+ -!#^_11p  ^                  >                                      >
