diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Revision history for toml-parser
 
-## 0.1.0.0  -- YYYY-mm-dd
+## 1.0.0.0  -- 2023-06-29
 
-* First version. Released on an unsuspecting world.
+* Complete rewrite including 1.0.0 compliance and pretty-printing.
+
+## 0.1.0.0  -- 2017-05-04
+
+* First version.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2017 Eric Mertens
+Copyright (c) 2023 Eric Mertens
 
 Permission to use, copy, modify, and/or distribute this software for any purpose
 with or without fee is hereby granted, provided that the above copyright notice
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,129 @@
+# TOML Parser
+
+This package implements a validating parser for [TOML 1.0.0](https://toml.io/en/v1.0.0).
+
+This package uses an [alex](https://haskell-alex.readthedocs.io/en/latest/)-generated
+lexer and [happy](https://haskell-happy.readthedocs.io/en/latest/)-generated parser.
+
+It also provides a pair of classes for serializing into and out of TOML.
+
+## Package Structure
+
+```mermaid
+---
+title: Package Structure
+---
+stateDiagram-v2
+    classDef important font-weight:bold;
+
+    TOML:::important --> ApplicationTypes:::important : decode
+    ApplicationTypes --> TOML : encode
+    TOML --> [Token]: Toml.Lexer
+    [Token] --> [Expr]: Toml.Parser
+    [Expr] --> Table : Toml.Semantics
+    Table --> ApplicationTypes : Toml.FromTable
+    ApplicationTypes --> Table : Toml.ToTable
+    Table --> TOML : Toml.Pretty
+
+```
+
+The highest-level interface to this package is to define `FromTable` and `ToTable`
+instances for your application-specific datatypes. These can be used with `encode`
+and `decode` to convert to and from TOML.
+
+For low-level access to the TOML format, the lexer, parser, and validator are available
+for direct use. The diagram above shows how the different modules enable you to
+advance through the increasingly high-level TOML representations.
+
+## Example
+
+Consider this sample TOML text from the specification.
+
+```toml
+[[fruits]]
+name = "apple"
+
+[fruits.physical]  # subtable
+color = "red"
+shape = "round"
+
+[[fruits.varieties]]  # nested array of tables
+name = "red delicious"
+
+[[fruits.varieties]]
+name = "granny smith"
+
+
+[[fruits]]
+name = "banana"
+
+[[fruits.varieties]]
+name = "plantain"
+```
+
+Parsing using this package generates the following value
+
+```haskell
+>>> Right fruitToml = parse fruitStr
+>>> fruitToml
+Right (fromList [
+    ("fruits",Array [
+        Table (fromList [
+            ("name",String "apple"),
+            ("physical",Table (fromList [
+                ("color",String "red"),
+                ("shape",String "round")])),
+            ("varieties",Array [
+                Table (fromList [("name",String "red delicious")]),
+                Table (fromList [("name",String "granny smith")])])]),
+        Table (fromList [
+            ("name",String "banana"),
+            ("varieties",Array [
+                Table (fromList [("name",String "plantain")])])])])])
+```
+
+We can render this parsed value back to TOML text using `prettyToml fruitToml`.
+In this case the input was already sorted, so the generated text will happen
+to match almost exactly.
+
+Here's an example of defining datatypes and deserializers for the TOML above.
+
+```haskell
+newtype Fruits = Fruits [Fruit]
+    deriving (Eq, Show)
+
+data Fruit = Fruit String (Maybe Physical) [Variety]
+    deriving (Eq, Show)
+
+data Physical = Physical String String
+    deriving (Eq, Show)
+
+newtype Variety = Variety String
+    deriving (Eq, Show)
+
+instance FromTable Fruits where
+    fromTable = runParseTable (Fruits <$> reqKey "fruits")
+
+instance FromTable Fruit where
+    fromTable = runParseTable (Fruit <$> reqKey "name" <*> optKey "physical" <*> reqKey "varieties")
+
+instance FromTable Physical where
+    fromTable = runParseTable (Physical <$> reqKey "color" <*> reqKey "shape")
+
+instance FromTable Variety where
+    fromTable = runParseTable (Variety <$> reqKey "name")
+
+instance FromValue Fruits   where fromValue = defaultTableFromValue
+instance FromValue Fruit    where fromValue = defaultTableFromValue
+instance FromValue Physical where fromValue = defaultTableFromValue
+instance FromValue Variety  where fromValue = defaultTableFromValue
+```
+
+We can run this example on the original value to deserialize it into domain-specific datatypes.
+
+```haskell
+>>> decode fruitToml :: Either String Fruits
+Right (Fruits [
+    Fruit "apple" (Just (Physical "red" "round")) [Variety "red delicious", Variety "granny smith"],
+    Fruit "banana" Nothing [Variety "plantain"]])
+```
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/dist/build/TOML/Lexer.hs b/dist/build/TOML/Lexer.hs
deleted file mode 100644
--- a/dist/build/TOML/Lexer.hs
+++ /dev/null
@@ -1,1061 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-missing-signatures #-}
-{-# LANGUAGE CPP,MagicHash #-}
-{-# LINE 1 "src/TOML/Lexer.x" #-}
-
-{-# LANGUAGE Trustworthy #-}
-{-|
-Module      : TOML.Lexer
-Description : /Internal:/ Lexer for TOML generated by Alex
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
-
-Lexer for TOML generated by Alex. Errors are reported in the resulting
-token list with 'Error'. As much as possible this module only contains
-generated code. The rest of the implementation is in "LexerUtils".
--}
-module TOML.Lexer (scanTokens) where
-
-import           Data.Text (Text)
-import qualified Data.Text as Text
-
-import           TOML.LexerUtils
-import           TOML.Tokens
-import           TOML.Located
-
-
-#if __GLASGOW_HASKELL__ >= 603
-#include "ghcconfig.h"
-#elif defined(__GLASGOW_HASKELL__)
-#include "config.h"
-#endif
-#if __GLASGOW_HASKELL__ >= 503
-import Data.Array
-import Data.Array.Base (unsafeAt)
-#else
-import Array
-#endif
-#if __GLASGOW_HASKELL__ >= 503
-import GHC.Exts
-#else
-import GlaExts
-#endif
-alex_tab_size :: Int
-alex_tab_size = 8
-alex_base :: AlexAddr
-alex_base = AlexA# "\xf8\xff\xff\xff\xfc\xff\xff\xff\xf2\x00\x00\x00\xe8\x01\x00\x00\xde\x02\x00\x00\xe0\xff\xff\xff\xe1\xff\xff\xff\x5e\x03\x00\x00\xde\x03\x00\x00\x5e\x04\x00\x00\xde\x04\x00\x00\xd0\x00\x00\x00\xea\x00\x00\x00\xc3\x01\x00\x00\xdb\x01\x00\x00\xb9\x02\x00\x00\xdf\x02\x00\x00\xda\xff\xff\xff\x00\x00\x00\x00\x4f\x05\x00\x00\xf6\x02\x00\x00\x1f\x06\x00\x00\x07\x01\x00\x00\x11\x01\x00\x00\x21\x01\x00\x00\x00\x00\x00\x00\xf7\x05\x00\x00\x00\x00\x00\x00\x38\x06\x00\x00\x08\x07\x00\x00\x1f\x07\x00\x00\x2b\x01\x00\x00\x36\x01\x00\x00\xfa\x01\x00\x00\x15\x02\x00\x00\x00\x00\x00\x00\xc7\x06\x00\x00\xc7\x07\x00\x00\x87\x07\x00\x00\x00\x00\x00\x00\x0a\x00\x00\x00\x57\x08\x00\x00\x6e\x08\x00\x00\xf3\xff\xff\xff\xf4\xff\xff\xff\x0d\x00\x00\x00\x0f\x00\x00\x00\x20\x02\x00\x00\x2a\x02\x00\x00\x16\x03\x00\x00\x36\x06\x00\x00\x40\x06\x00\x00\x44\x07\x00\x00\x8e\x08\x00\x00\xa5\x08\x00\x00\xaf\x08\x00\x00\xb9\x08\x00\x00\xc3\x08\x00\x00\xfd\x08\x00\x00\xbd\x08\x00\x00\x00\x00\x00\x00\xf5\x01\x00\x00\xb3\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\x09\x00\x00\x86\x0a\x00\x00\xef\xff\xff\xff\xd4\x0a\x00\x00\x22\x0b\x00\x00\x6f\x0b\x00\x00\x94\x0b\x00\x00\x00\x00\x00\x00\xe2\x0b\x00\x00\x2d\x0c\x00\x00\x37\x0c\x00\x00\x67\x0c\x00\x00\xb5\x0c\x00\x00\x05\x0d\x00\x00\x55\x0d\x00\x00\x00\x00\x00\x00\xdc\x09\x00\x00\xe8\x09\x00\x00\xa3\x0d\x00\x00\xf1\x0d\x00\x00\x3f\x0e\x00\x00\x8d\x0e\x00\x00\xdb\x0e\x00\x00\x29\x0f\x00\x00\x77\x0f\x00\x00\xc5\x0f\x00\x00\x13\x10\x00\x00\x61\x10\x00\x00\xaf\x10\x00\x00\xfd\x10\x00\x00\x4b\x11\x00\x00\x99\x11\x00\x00\xe7\x11\x00\x00\x35\x12\x00\x00\x83\x12\x00\x00\xd3\x12\x00\x00\x21\x13\x00\x00\x6f\x13\x00\x00\xbd\x13\x00\x00\x0b\x14\x00\x00\x00\x00\x00\x00\x29\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\xf5\xff\xff\xff\xfe\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\x02\x00\x00\x7c\x14\x00\x00\xfa\xff\xff\xff\x00\x00\x00\x00\x05\x00\x00\x00\x18\x00\x00\x00"#
-
-alex_table :: AlexAddr
-alex_table = AlexA# "\x00\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x78\x00\x6f\x00\x74\x00\x87\x00\x17\x00\x17\x00\x17\x00\x17\x00\x17\x00\x17\x00\x17\x00\x17\x00\x17\x00\x17\x00\x82\x00\x75\x00\x71\x00\x70\x00\x3d\x00\x6e\x00\x73\x00\x3e\x00\x05\x00\x36\x00\x86\x00\x72\x00\x2c\x00\x06\x00\x78\x00\x39\x00\x43\x00\x6d\x00\x44\x00\x2b\x00\x46\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x00\x00\x6e\x00\x34\x00\x45\x00\x2e\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x41\x00\x34\x00\x42\x00\x00\x00\x60\x00\x83\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x5e\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x66\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x3f\x00\x70\x00\x40\x00\x00\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x25\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x26\x00\x08\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1c\x00\x0a\x00\x12\x00\x12\x00\x12\x00\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x78\x00\x00\x00\x00\x00\x87\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x00\x00\x00\x00\x84\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x0c\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x21\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x0d\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x1f\x00\x2f\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x25\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x26\x00\x08\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1c\x00\x0a\x00\x12\x00\x12\x00\x12\x00\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x00\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x3d\x00\x00\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x77\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x3d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x00\x00\x00\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x0e\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x31\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x0f\x00\x00\x00\x00\x00\x83\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x22\x00\x32\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x25\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x26\x00\x08\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1c\x00\x0a\x00\x12\x00\x12\x00\x12\x00\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x14\x00\x14\x00\x14\x00\x14\x00\x14\x00\x14\x00\x14\x00\x14\x00\x14\x00\x14\x00\x82\x00\x82\x00\x82\x00\x82\x00\x82\x00\x00\x00\x00\x00\x14\x00\x14\x00\x14\x00\x14\x00\x14\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x76\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x00\x00\x14\x00\x14\x00\x14\x00\x14\x00\x14\x00\x14\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x15\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x1d\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x25\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x26\x00\x08\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1c\x00\x0a\x00\x12\x00\x12\x00\x12\x00\x13\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x25\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x27\x00\x07\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x08\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1b\x00\x1c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x1e\x00\x24\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x26\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x29\x00\x37\x00\x00\x00\x37\x00\x00\x00\x00\x00\x4d\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x00\x00\x00\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x3b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x00\x00\x00\x00\x00\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x81\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x80\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4d\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x48\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x63\x00\x36\x00\x00\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x69\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x69\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x56\x00\x30\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3a\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3c\x00\x3b\x00\x07\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x23\x00\x24\x00\x09\x00\x19\x00\x19\x00\x19\x00\x1a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x60\x00\x36\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x69\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x69\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x63\x00\x36\x00\x00\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x49\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x69\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x69\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x36\x00\x00\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x69\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6c\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x69\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x36\x00\x00\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x4b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x4f\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x50\x00\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x34\x00\x00\x00\x60\x00\x00\x00\x35\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x11\x00\x00\x00\x11\x00\x00\x00\x00\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x53\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x11\x00\x00\x00\x11\x00\x33\x00\x00\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x54\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x55\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x61\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x51\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x52\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x59\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x5a\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x67\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x65\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x63\x00\x00\x00\x00\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x5f\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x62\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x64\x00\x64\x00\x64\x00\x64\x00\x64\x00\x64\x00\x64\x00\x64\x00\x64\x00\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x5c\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x5b\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x68\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x58\x00\x58\x00\x58\x00\x58\x00\x58\x00\x58\x00\x58\x00\x58\x00\x58\x00\x58\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x37\x00\x00\x00\x6b\x00\x00\x00\x00\x00\x4c\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x4c\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x4e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x47\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x4a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x00\x00\x00\x00\x00\x00\x00\x00\x60\x00\x00\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x60\x00\x82\x00\x00\x00\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x79\x00\x00\x00\x00\x00\x00\x00\x7c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7b\x00\x00\x00\x00\x00\x00\x00\x7d\x00\x00\x00\x7a\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
-
-alex_check :: AlexAddr
-alex_check = AlexA# "\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0a\x00\x27\x00\x27\x00\x0d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x0a\x00\x22\x00\x22\x00\x0a\x00\x20\x00\x0a\x00\x22\x00\x23\x00\x27\x00\x2e\x00\x22\x00\x27\x00\x22\x00\x27\x00\x0a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x22\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x0a\x00\x45\x00\x3d\x00\x0d\x00\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x65\x00\x5d\x00\xff\xff\x5f\x00\x5c\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x0a\x00\x7d\x00\xff\xff\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x0a\x00\xff\xff\xff\xff\x0d\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\xff\xff\x27\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x0a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x22\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\xff\xff\x5c\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x0a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\x20\x00\xff\xff\xff\xff\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x2b\x00\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x0a\x00\x2d\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xd7\x00\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xf7\x00\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x2d\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x5f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x65\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\x45\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x65\x00\xff\xff\x2d\x00\xff\xff\x5f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2b\x00\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2b\x00\xff\xff\x2d\x00\x2e\x00\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2b\x00\xff\xff\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x2d\x00\xff\xff\xff\xff\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x0a\x00\xff\xff\xff\xff\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x22\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x55\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5c\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x62\x00\xff\xff\xff\xff\xff\xff\x66\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x6e\x00\xff\xff\xff\xff\xff\xff\x72\x00\xff\xff\x74\x00\x75\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
-
-alex_deflt :: AlexAddr
-alex_deflt = AlexA# "\xff\xff\x85\x00\x85\x00\x85\x00\x85\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x1b\x00\x1b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x23\x00\x23\x00\x27\x00\x27\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3c\x00\x3c\x00\x85\x00\x85\x00\x85\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x3e\x00\x3e\x00\x3e\x00\xff\xff\x3e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
-
-alex_accept = listArray (0::Int,135) [AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccNone,AlexAccSkip,AlexAccSkip,AlexAcc 71,AlexAcc 70,AlexAcc 69,AlexAcc 68,AlexAcc 67,AlexAcc 66,AlexAcc 65,AlexAcc 64,AlexAcc 63,AlexAcc 62,AlexAcc 61,AlexAcc 60,AlexAcc 59,AlexAcc 58,AlexAcc 57,AlexAcc 56,AlexAcc 55,AlexAcc 54,AlexAcc 53,AlexAcc 52,AlexAcc 51,AlexAcc 50,AlexAcc 49,AlexAcc 48,AlexAcc 47,AlexAcc 46,AlexAcc 45,AlexAcc 44,AlexAcc 43,AlexAcc 42,AlexAcc 41,AlexAcc 40,AlexAcc 39,AlexAcc 38,AlexAcc 37,AlexAcc 36,AlexAcc 35,AlexAcc 34,AlexAcc 33,AlexAcc 32,AlexAcc 31,AlexAcc 30,AlexAcc 29,AlexAcc 28,AlexAcc 27,AlexAcc 26,AlexAcc 25,AlexAcc 24,AlexAcc 23,AlexAcc 22,AlexAcc 21,AlexAcc 20,AlexAcc 19,AlexAcc 18,AlexAcc 17,AlexAcc 16,AlexAcc 15,AlexAcc 14,AlexAcc 13,AlexAcc 12,AlexAcc 11,AlexAcc 10,AlexAcc 9,AlexAcc 8,AlexAcc 7,AlexAcc 6,AlexAcc 5,AlexAccSkip,AlexAcc 4,AlexAcc 3,AlexAcc 2,AlexAcc 1,AlexAcc 0]
-
-alex_actions = array (0::Int,72) [(71,alex_action_2),(70,alex_action_3),(69,alex_action_4),(68,alex_action_5),(67,alex_action_6),(66,alex_action_7),(65,alex_action_8),(64,alex_action_9),(63,alex_action_9),(62,alex_action_9),(61,alex_action_9),(60,alex_action_9),(59,alex_action_9),(58,alex_action_10),(57,alex_action_10),(56,alex_action_10),(55,alex_action_10),(54,alex_action_10),(53,alex_action_11),(52,alex_action_12),(51,alex_action_13),(50,alex_action_13),(49,alex_action_14),(48,alex_action_15),(47,alex_action_15),(46,alex_action_16),(45,alex_action_17),(44,alex_action_17),(43,alex_action_17),(42,alex_action_17),(41,alex_action_17),(40,alex_action_17),(39,alex_action_17),(38,alex_action_17),(37,alex_action_17),(36,alex_action_17),(35,alex_action_17),(34,alex_action_17),(33,alex_action_17),(32,alex_action_17),(31,alex_action_17),(30,alex_action_17),(29,alex_action_17),(28,alex_action_17),(27,alex_action_17),(26,alex_action_17),(25,alex_action_17),(24,alex_action_18),(23,alex_action_18),(22,alex_action_19),(21,alex_action_19),(20,alex_action_20),(19,alex_action_21),(18,alex_action_22),(17,alex_action_23),(16,alex_action_24),(15,alex_action_25),(14,alex_action_26),(13,alex_action_27),(12,alex_action_28),(11,alex_action_29),(10,alex_action_30),(9,alex_action_31),(8,alex_action_32),(7,alex_action_33),(6,alex_action_34),(5,alex_action_35),(4,alex_action_37),(3,alex_action_38),(2,alex_action_38),(1,alex_action_38),(0,alex_action_38)]
-
-{-# LINE 98 "src/TOML/Lexer.x" #-}
-
--- | Produce a token stream from an input file. The token
--- stream will always be terminated by an 'ErrorToken' or
--- 'EofToken'.
-scanTokens ::
-  Text            {- ^ Source text          -} ->
-  [Located Token] {- ^ Tokens with position -}
-scanTokens str = go (Located startPos str) InNormal
-  where
-  go inp st =
-    case alexScan inp (lexerModeInt st) of
-      AlexEOF                -> eofAction (locPosition inp) st
-      AlexError inp'         -> errorAction inp'
-      AlexSkip  inp' _       -> go inp' st
-      AlexToken inp' len act -> case act (fmap (Text.take len) inp) st of
-                                  (st', xs) -> xs ++ go inp' st'
-
-
-
-mldq,mlsq,sldq,slsq :: Int
-mldq = 1
-mlsq = 2
-sldq = 3
-slsq = 4
-alex_action_2 =  token_ LeftBraceToken         
-alex_action_3 =  token_ RightBraceToken        
-alex_action_4 =  token_ LeftBracketToken       
-alex_action_5 =  token_ RightBracketToken      
-alex_action_6 =  token_ CommaToken             
-alex_action_7 =  token_ PeriodToken            
-alex_action_8 =  token_ EqualToken             
-alex_action_9 =  token integer                 
-alex_action_10 =  token double                  
-alex_action_11 =  token_ TrueToken              
-alex_action_12 =  token_ FalseToken             
-alex_action_13 =  token localtime               
-alex_action_14 =  token zonedtime               
-alex_action_15 =  token timeofday               
-alex_action_16 =  token day                     
-alex_action_17 =  token bareKeyToken            
-alex_action_18 =  startString mlsq              
-alex_action_19 =  startString mldq              
-alex_action_20 =  startString slsq              
-alex_action_21 =  startString sldq              
-alex_action_22 =  endString                     
-alex_action_23 =  endString                     
-alex_action_24 =  endString                     
-alex_action_25 =  endString                     
-alex_action_26 =  emitChar                      
-alex_action_27 =  emitChar' '\b'                
-alex_action_28 =  emitChar' '\t'                
-alex_action_29 =  emitChar' '\n'                
-alex_action_30 =  emitChar' '\f'                
-alex_action_31 =  emitChar' '\r'                
-alex_action_32 =  emitChar' '"'                 
-alex_action_33 =  emitChar' '\\'                
-alex_action_34 =  emitUnicodeChar               
-alex_action_35 =  emitUnicodeChar               
-alex_action_37 =  token_ (ErrorToken BadEscape) 
-alex_action_38 =  emitChar                      
-{-# LINE 1 "templates/GenericTemplate.hs" #-}
-{-# LINE 1 "templates/GenericTemplate.hs" #-}
-{-# LINE 1 "<built-in>" #-}
-{-# LINE 18 "<built-in>" #-}
-{-# LINE 1 "/Users/emertens/Tools/ghc-8.0.2/lib/ghc-8.0.2/include/ghcversion.h" #-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{-# LINE 19 "<built-in>" #-}
-{-# LINE 1 "/var/folders/t0/04lb5h5n1sb6w_ghq4vgpgjw0000gn/T/ghc60047_0/ghc_2.h" #-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{-# LINE 20 "<built-in>" #-}
-{-# LINE 1 "templates/GenericTemplate.hs" #-}
--- -----------------------------------------------------------------------------
--- ALEX TEMPLATE
---
--- This code is in the PUBLIC DOMAIN; you may copy it freely and use
--- it for any purpose whatsoever.
-
--- -----------------------------------------------------------------------------
--- INTERNALS and main scanner engine
-
-
-{-# LINE 21 "templates/GenericTemplate.hs" #-}
-
-
-
-
-
--- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
-#if __GLASGOW_HASKELL__ > 706
-#define GTE(n,m) (tagToEnum# (n >=# m))
-#define EQ(n,m) (tagToEnum# (n ==# m))
-#else
-#define GTE(n,m) (n >=# m)
-#define EQ(n,m) (n ==# m)
-#endif
-
-{-# LINE 51 "templates/GenericTemplate.hs" #-}
-
-
-data AlexAddr = AlexA# Addr#
--- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
-#if __GLASGOW_HASKELL__ < 503
-uncheckedShiftL# = shiftL#
-#endif
-
-{-# INLINE alexIndexInt16OffAddr #-}
-alexIndexInt16OffAddr (AlexA# arr) off =
-#ifdef WORDS_BIGENDIAN
-  narrow16Int# i
-  where
-        i    = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)
-        high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
-        low  = int2Word# (ord# (indexCharOffAddr# arr off'))
-        off' = off *# 2#
-#else
-  indexInt16OffAddr# arr off
-#endif
-
-
-
-
-
-{-# INLINE alexIndexInt32OffAddr #-}
-alexIndexInt32OffAddr (AlexA# arr) off =
-#ifdef WORDS_BIGENDIAN
-  narrow32Int# i
-  where
-   i    = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#`
-                     (b2 `uncheckedShiftL#` 16#) `or#`
-                     (b1 `uncheckedShiftL#` 8#) `or#` b0)
-   b3   = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#)))
-   b2   = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#)))
-   b1   = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
-   b0   = int2Word# (ord# (indexCharOffAddr# arr off'))
-   off' = off *# 4#
-#else
-  indexInt32OffAddr# arr off
-#endif
-
-
-
-
-
-
-#if __GLASGOW_HASKELL__ < 503
-quickIndex arr i = arr ! i
-#else
--- GHC >= 503, unsafeAt is available from Data.Array.Base.
-quickIndex = unsafeAt
-#endif
-
-
-
-
--- -----------------------------------------------------------------------------
--- Main lexing routines
-
-data AlexReturn a
-  = AlexEOF
-  | AlexError  !AlexInput
-  | AlexSkip   !AlexInput !Int
-  | AlexToken  !AlexInput !Int a
-
--- alexScan :: AlexInput -> StartCode -> AlexReturn a
-alexScan input (I# (sc))
-  = alexScanUser undefined input (I# (sc))
-
-alexScanUser user input (I# (sc))
-  = case alex_scan_tkn user input 0# input sc AlexNone of
-  (AlexNone, input') ->
-    case alexGetByte input of
-      Nothing ->
-
-
-
-                                   AlexEOF
-      Just _ ->
-
-
-
-                                   AlexError input'
-
-  (AlexLastSkip input'' len, _) ->
-
-
-
-    AlexSkip input'' len
-
-  (AlexLastAcc k input''' len, _) ->
-
-
-
-    AlexToken input''' len (alex_actions ! k)
-
-
--- Push the input through the DFA, remembering the most recent accepting
--- state it encountered.
-
-alex_scan_tkn user orig_input len input s last_acc =
-  input `seq` -- strict in the input
-  let
-  new_acc = (check_accs (alex_accept `quickIndex` (I# (s))))
-  in
-  new_acc `seq`
-  case alexGetByte input of
-     Nothing -> (new_acc, input)
-     Just (c, new_input) ->
-
-
-
-      case fromIntegral c of { (I# (ord_c)) ->
-        let
-                base   = alexIndexInt32OffAddr alex_base s
-                offset = (base +# ord_c)
-                check  = alexIndexInt16OffAddr alex_check offset
-
-                new_s = if GTE(offset,0#) && EQ(check,ord_c)
-                          then alexIndexInt16OffAddr alex_table offset
-                          else alexIndexInt16OffAddr alex_deflt s
-        in
-        case new_s of
-            -1# -> (new_acc, input)
-                -- on an error, we want to keep the input *before* the
-                -- character that failed, not after.
-            _ -> alex_scan_tkn user orig_input (if c < 0x80 || c >= 0xC0 then (len +# 1#) else len)
-                                                -- note that the length is increased ONLY if this is the 1st byte in a char encoding)
-                        new_input new_s new_acc
-      }
-  where
-        check_accs (AlexAccNone) = last_acc
-        check_accs (AlexAcc a  ) = AlexLastAcc a input (I# (len))
-        check_accs (AlexAccSkip) = AlexLastSkip  input (I# (len))
-
-{-# LINE 198 "templates/GenericTemplate.hs" #-}
-
-data AlexLastAcc
-  = AlexNone
-  | AlexLastAcc !Int !AlexInput !Int
-  | AlexLastSkip     !AlexInput !Int
-
-data AlexAcc user
-  = AlexAccNone
-  | AlexAcc Int
-  | AlexAccSkip
-
diff --git a/dist/build/TOML/Parser.hs b/dist/build/TOML/Parser.hs
deleted file mode 100644
--- a/dist/build/TOML/Parser.hs
+++ /dev/null
@@ -1,1621 +0,0 @@
-{-# OPTIONS_GHC -w #-}
-{-# OPTIONS -fglasgow-exts -cpp #-}
-{-# LANGUAGE Trustworthy #-}
-{-|
-Module      : TOML.Parser
-Description : /Internal:/ Parser for TOML generated by Happy
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
-
-Parser for TOML generated by Happy.
-
--}
-module TOML.Parser (parseComponents) where
-
-import Data.Text (Text,pack)
-
-import TOML.Components
-import TOML.Errors
-import TOML.Located
-import TOML.Tokens
-import TOML.Value
-import qualified Data.Array as Happy_Data_Array
-import qualified GHC.Exts as Happy_GHC_Exts
-import Control.Applicative(Applicative(..))
-import Control.Monad (ap)
-
--- parser produced by Happy Version 1.19.5
-
-newtype HappyAbsSyn  = HappyAbsSyn HappyAny
-#if __GLASGOW_HASKELL__ >= 607
-type HappyAny = Happy_GHC_Exts.Any
-#else
-type HappyAny = forall a . a
-#endif
-happyIn4 :: ([Component]) -> (HappyAbsSyn )
-happyIn4 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn4 #-}
-happyOut4 :: (HappyAbsSyn ) -> ([Component])
-happyOut4 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut4 #-}
-happyIn5 :: ([Component]) -> (HappyAbsSyn )
-happyIn5 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn5 #-}
-happyOut5 :: (HappyAbsSyn ) -> ([Component])
-happyOut5 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut5 #-}
-happyIn6 :: ([(Text,Value)] -> Component) -> (HappyAbsSyn )
-happyIn6 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn6 #-}
-happyOut6 :: (HappyAbsSyn ) -> ([(Text,Value)] -> Component)
-happyOut6 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut6 #-}
-happyIn7 :: ([(Text,Value)]) -> (HappyAbsSyn )
-happyIn7 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn7 #-}
-happyOut7 :: (HappyAbsSyn ) -> ([(Text,Value)])
-happyOut7 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut7 #-}
-happyIn8 :: ([(Text,Value)]) -> (HappyAbsSyn )
-happyIn8 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn8 #-}
-happyOut8 :: (HappyAbsSyn ) -> ([(Text,Value)])
-happyOut8 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut8 #-}
-happyIn9 :: ([Text]) -> (HappyAbsSyn )
-happyIn9 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn9 #-}
-happyOut9 :: (HappyAbsSyn ) -> ([Text])
-happyOut9 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut9 #-}
-happyIn10 :: ([Text]) -> (HappyAbsSyn )
-happyIn10 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn10 #-}
-happyOut10 :: (HappyAbsSyn ) -> ([Text])
-happyOut10 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut10 #-}
-happyIn11 :: (Text) -> (HappyAbsSyn )
-happyIn11 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn11 #-}
-happyOut11 :: (HappyAbsSyn ) -> (Text)
-happyOut11 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut11 #-}
-happyIn12 :: (Value) -> (HappyAbsSyn )
-happyIn12 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn12 #-}
-happyOut12 :: (HappyAbsSyn ) -> (Value)
-happyOut12 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut12 #-}
-happyIn13 :: ([(Text,Value)]) -> (HappyAbsSyn )
-happyIn13 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn13 #-}
-happyOut13 :: (HappyAbsSyn ) -> ([(Text,Value)])
-happyOut13 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut13 #-}
-happyIn14 :: ([(Text,Value)]) -> (HappyAbsSyn )
-happyIn14 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn14 #-}
-happyOut14 :: (HappyAbsSyn ) -> ([(Text,Value)])
-happyOut14 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut14 #-}
-happyIn15 :: ([Value]) -> (HappyAbsSyn )
-happyIn15 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn15 #-}
-happyOut15 :: (HappyAbsSyn ) -> ([Value])
-happyOut15 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut15 #-}
-happyIn16 :: ([Value]) -> (HappyAbsSyn )
-happyIn16 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyIn16 #-}
-happyOut16 :: (HappyAbsSyn ) -> ([Value])
-happyOut16 x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOut16 #-}
-happyInTok :: (Located Token) -> (HappyAbsSyn )
-happyInTok x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyInTok #-}
-happyOutTok :: (HappyAbsSyn ) -> (Located Token)
-happyOutTok x = Happy_GHC_Exts.unsafeCoerce# x
-{-# INLINE happyOutTok #-}
-
-
-happyActOffsets :: HappyAddr
-happyActOffsets = HappyA# "\x00\x00\x00\x00\xfa\xff\x00\x00\x24\x00\x32\x00\x3b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x15\x00\x3a\x00\x00\x00\x24\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x35\x00\x03\x00\x38\x00\x00\x00\x0b\x00\x36\x00\x01\x00\x00\x00\x00\x00\x24\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x33\x00\x00\x00\x01\x00\x00\x00\x00\x00"#
-
-happyGotoOffsets :: HappyAddr
-happyGotoOffsets = HappyA# "\x17\x00\x30\x00\x3d\x00\x00\x00\x37\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x39\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x00\x00\x2d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00"#
-
-happyDefActions :: HappyAddr
-happyDefActions = HappyA# "\xf5\xff\x00\x00\x00\x00\xfd\xff\xf6\xff\x00\x00\x00\x00\xef\xff\xf0\xff\xee\xff\xed\xff\xec\xff\xf5\xff\x00\x00\xfe\xff\x00\x00\xf3\xff\xf2\xff\x00\x00\xfc\xff\x00\x00\xf4\xff\xe9\xff\xeb\xff\xea\xff\xe4\xff\xe3\xff\xda\xff\xde\xff\xe8\xff\xe5\xff\xe7\xff\xe6\xff\x00\x00\x00\x00\xf9\xff\xfb\xff\xf1\xff\xf8\xff\x00\x00\x00\x00\x00\x00\xdd\xff\xd7\xff\x00\x00\xd9\xff\xd8\xff\xdf\xff\xe1\xff\x00\x00\xe0\xff\xe2\xff\x00\x00\xf7\xff\xfa\xff\xdc\xff\x00\x00\xd6\xff\x00\x00\xdb\xff"#
-
-happyCheck :: HappyAddr
-happyCheck = HappyA# "\xff\xff\x07\x00\x01\x00\x00\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x07\x00\x09\x00\x00\x00\x12\x00\x0a\x00\x00\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x08\x00\x00\x00\x00\x00\x08\x00\x00\x00\x01\x00\x08\x00\x03\x00\x04\x00\x08\x00\x08\x00\x01\x00\x02\x00\x03\x00\x08\x00\x05\x00\x06\x00\x07\x00\x01\x00\x02\x00\x03\x00\x08\x00\x05\x00\x06\x00\x0b\x00\x0c\x00\x07\x00\x07\x00\x09\x00\x0a\x00\x01\x00\x08\x00\x03\x00\x04\x00\x08\x00\x05\x00\x06\x00\x07\x00\x05\x00\x06\x00\x07\x00\x03\x00\x04\x00\x07\x00\x02\x00\x0d\x00\x0b\x00\x0d\x00\x0b\x00\xff\xff\x13\x00\x0c\x00\xff\xff\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#
-
-happyTable :: HappyAddr
-happyTable = HappyA# "\x00\x00\x0e\x00\x17\x00\x33\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x38\x00\x1d\x00\x30\x00\x0f\x00\x34\x00\x36\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x31\x00\x27\x00\x24\x00\x37\x00\x05\x00\x02\x00\x3b\x00\x03\x00\x04\x00\x28\x00\x25\x00\x08\x00\x09\x00\x0a\x00\x37\x00\x0b\x00\x0c\x00\x13\x00\x08\x00\x09\x00\x0a\x00\x2b\x00\x0b\x00\x0c\x00\x2c\x00\x2d\x00\x28\x00\x25\x00\x29\x00\x2a\x00\x02\x00\x39\x00\x03\x00\x04\x00\x15\x00\x21\x00\x10\x00\x11\x00\x0f\x00\x10\x00\x11\x00\x13\x00\x04\x00\x06\x00\x0c\x00\x3b\x00\x2f\x00\x35\x00\x32\x00\x00\x00\xff\xff\x23\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#
-
-happyReduceArr = Happy_Data_Array.array (1, 41) [
-	(1 , happyReduce_1),
-	(2 , happyReduce_2),
-	(3 , happyReduce_3),
-	(4 , happyReduce_4),
-	(5 , happyReduce_5),
-	(6 , happyReduce_6),
-	(7 , happyReduce_7),
-	(8 , happyReduce_8),
-	(9 , happyReduce_9),
-	(10 , happyReduce_10),
-	(11 , happyReduce_11),
-	(12 , happyReduce_12),
-	(13 , happyReduce_13),
-	(14 , happyReduce_14),
-	(15 , happyReduce_15),
-	(16 , happyReduce_16),
-	(17 , happyReduce_17),
-	(18 , happyReduce_18),
-	(19 , happyReduce_19),
-	(20 , happyReduce_20),
-	(21 , happyReduce_21),
-	(22 , happyReduce_22),
-	(23 , happyReduce_23),
-	(24 , happyReduce_24),
-	(25 , happyReduce_25),
-	(26 , happyReduce_26),
-	(27 , happyReduce_27),
-	(28 , happyReduce_28),
-	(29 , happyReduce_29),
-	(30 , happyReduce_30),
-	(31 , happyReduce_31),
-	(32 , happyReduce_32),
-	(33 , happyReduce_33),
-	(34 , happyReduce_34),
-	(35 , happyReduce_35),
-	(36 , happyReduce_36),
-	(37 , happyReduce_37),
-	(38 , happyReduce_38),
-	(39 , happyReduce_39),
-	(40 , happyReduce_40),
-	(41 , happyReduce_41)
-	]
-
-happy_n_terms = 20 :: Int
-happy_n_nonterms = 13 :: Int
-
-happyReduce_1 = happySpecReduce_2  0# happyReduction_1
-happyReduction_1 happy_x_2
-	happy_x_1
-	 =  case happyOut5 happy_x_1 of { happy_var_1 -> 
-	happyIn4
-		 (reverse happy_var_1
-	)}
-
-happyReduce_2 = happySpecReduce_1  1# happyReduction_2
-happyReduction_2 happy_x_1
-	 =  case happyOut7 happy_x_1 of { happy_var_1 -> 
-	happyIn5
-		 ([InitialEntry happy_var_1]
-	)}
-
-happyReduce_3 = happySpecReduce_3  1# happyReduction_3
-happyReduction_3 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut5 happy_x_1 of { happy_var_1 -> 
-	case happyOut6 happy_x_2 of { happy_var_2 -> 
-	case happyOut7 happy_x_3 of { happy_var_3 -> 
-	happyIn5
-		 (happy_var_2 happy_var_3 : happy_var_1
-	)}}}
-
-happyReduce_4 = happySpecReduce_3  2# happyReduction_4
-happyReduction_4 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut9 happy_x_2 of { happy_var_2 -> 
-	happyIn6
-		 (TableEntry happy_var_2
-	)}
-
-happyReduce_5 = happyReduce 5# 2# happyReduction_5
-happyReduction_5 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut9 happy_x_3 of { happy_var_3 -> 
-	happyIn6
-		 (ArrayEntry happy_var_3
-	) `HappyStk` happyRest}
-
-happyReduce_6 = happyMonadReduce 3# 2# happyReduction_6
-happyReduction_6 (happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest) tk
-	 = happyThen (case happyOutTok happy_x_1 of { (happy_var_1@(Located _ LeftBracketToken)) -> 
-	( unterminated happy_var_1)}
-	) (\r -> happyReturn (happyIn6 r))
-
-happyReduce_7 = happyMonadReduce 4# 2# happyReduction_7
-happyReduction_7 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest) tk
-	 = happyThen (case happyOutTok happy_x_2 of { (happy_var_2@(Located _ LeftBracketToken)) -> 
-	( unterminated happy_var_2)}
-	) (\r -> happyReturn (happyIn6 r))
-
-happyReduce_8 = happyMonadReduce 5# 2# happyReduction_8
-happyReduction_8 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest) tk
-	 = happyThen (case happyOutTok happy_x_1 of { (happy_var_1@(Located _ LeftBracketToken)) -> 
-	( unterminated happy_var_1)}
-	) (\r -> happyReturn (happyIn6 r))
-
-happyReduce_9 = happySpecReduce_1  3# happyReduction_9
-happyReduction_9 happy_x_1
-	 =  case happyOut8 happy_x_1 of { happy_var_1 -> 
-	happyIn7
-		 (reverse happy_var_1
-	)}
-
-happyReduce_10 = happySpecReduce_0  4# happyReduction_10
-happyReduction_10  =  happyIn8
-		 ([]
-	)
-
-happyReduce_11 = happyReduce 4# 4# happyReduction_11
-happyReduction_11 (happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut8 happy_x_1 of { happy_var_1 -> 
-	case happyOut11 happy_x_2 of { happy_var_2 -> 
-	case happyOut12 happy_x_4 of { happy_var_4 -> 
-	happyIn8
-		 ((happy_var_2,happy_var_4):happy_var_1
-	) `HappyStk` happyRest}}}
-
-happyReduce_12 = happySpecReduce_1  5# happyReduction_12
-happyReduction_12 happy_x_1
-	 =  case happyOut10 happy_x_1 of { happy_var_1 -> 
-	happyIn9
-		 (reverse happy_var_1
-	)}
-
-happyReduce_13 = happySpecReduce_1  6# happyReduction_13
-happyReduction_13 happy_x_1
-	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
-	happyIn10
-		 ([happy_var_1]
-	)}
-
-happyReduce_14 = happySpecReduce_3  6# happyReduction_14
-happyReduction_14 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut10 happy_x_1 of { happy_var_1 -> 
-	case happyOut11 happy_x_3 of { happy_var_3 -> 
-	happyIn10
-		 (happy_var_3 : happy_var_1
-	)}}
-
-happyReduce_15 = happySpecReduce_1  7# happyReduction_15
-happyReduction_15 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (BareKeyToken happy_var_1)) -> 
-	happyIn11
-		 (happy_var_1
-	)}
-
-happyReduce_16 = happySpecReduce_1  7# happyReduction_16
-happyReduction_16 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (StringToken happy_var_1)) -> 
-	happyIn11
-		 (happy_var_1
-	)}
-
-happyReduce_17 = happySpecReduce_1  7# happyReduction_17
-happyReduction_17 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (IntegerToken happy_var_1)) -> 
-	happyIn11
-		 (pack (show happy_var_1)
-	)}
-
-happyReduce_18 = happySpecReduce_1  7# happyReduction_18
-happyReduction_18 happy_x_1
-	 =  happyIn11
-		 (pack "true"
-	)
-
-happyReduce_19 = happySpecReduce_1  7# happyReduction_19
-happyReduction_19 happy_x_1
-	 =  happyIn11
-		 (pack "false"
-	)
-
-happyReduce_20 = happySpecReduce_1  8# happyReduction_20
-happyReduction_20 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (IntegerToken happy_var_1)) -> 
-	happyIn12
-		 (Integer    happy_var_1
-	)}
-
-happyReduce_21 = happySpecReduce_1  8# happyReduction_21
-happyReduction_21 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (DoubleToken happy_var_1)) -> 
-	happyIn12
-		 (Double     happy_var_1
-	)}
-
-happyReduce_22 = happySpecReduce_1  8# happyReduction_22
-happyReduction_22 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (StringToken happy_var_1)) -> 
-	happyIn12
-		 (String     happy_var_1
-	)}
-
-happyReduce_23 = happySpecReduce_1  8# happyReduction_23
-happyReduction_23 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (ZonedTimeToken happy_var_1)) -> 
-	happyIn12
-		 (ZonedTimeV happy_var_1
-	)}
-
-happyReduce_24 = happySpecReduce_1  8# happyReduction_24
-happyReduction_24 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (TimeOfDayToken happy_var_1)) -> 
-	happyIn12
-		 (TimeOfDayV happy_var_1
-	)}
-
-happyReduce_25 = happySpecReduce_1  8# happyReduction_25
-happyReduction_25 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (DayToken       happy_var_1)) -> 
-	happyIn12
-		 (DayV       happy_var_1
-	)}
-
-happyReduce_26 = happySpecReduce_1  8# happyReduction_26
-happyReduction_26 happy_x_1
-	 =  case happyOutTok happy_x_1 of { (Located _ (LocalTimeToken happy_var_1)) -> 
-	happyIn12
-		 (LocalTimeV happy_var_1
-	)}
-
-happyReduce_27 = happySpecReduce_1  8# happyReduction_27
-happyReduction_27 happy_x_1
-	 =  happyIn12
-		 (Bool       True
-	)
-
-happyReduce_28 = happySpecReduce_1  8# happyReduction_28
-happyReduction_28 happy_x_1
-	 =  happyIn12
-		 (Bool       False
-	)
-
-happyReduce_29 = happySpecReduce_3  8# happyReduction_29
-happyReduction_29 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut13 happy_x_2 of { happy_var_2 -> 
-	happyIn12
-		 (Table      happy_var_2
-	)}
-
-happyReduce_30 = happySpecReduce_3  8# happyReduction_30
-happyReduction_30 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut15 happy_x_2 of { happy_var_2 -> 
-	happyIn12
-		 (List       happy_var_2
-	)}
-
-happyReduce_31 = happyMonadReduce 3# 8# happyReduction_31
-happyReduction_31 (happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest) tk
-	 = happyThen (case happyOutTok happy_x_1 of { (happy_var_1@(Located _ LeftBraceToken)) -> 
-	( unterminated happy_var_1)}
-	) (\r -> happyReturn (happyIn12 r))
-
-happyReduce_32 = happyMonadReduce 3# 8# happyReduction_32
-happyReduction_32 (happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest) tk
-	 = happyThen (case happyOutTok happy_x_1 of { (happy_var_1@(Located _ LeftBracketToken)) -> 
-	( unterminated happy_var_1)}
-	) (\r -> happyReturn (happyIn12 r))
-
-happyReduce_33 = happySpecReduce_0  9# happyReduction_33
-happyReduction_33  =  happyIn13
-		 ([]
-	)
-
-happyReduce_34 = happySpecReduce_1  9# happyReduction_34
-happyReduction_34 happy_x_1
-	 =  case happyOut14 happy_x_1 of { happy_var_1 -> 
-	happyIn13
-		 (reverse happy_var_1
-	)}
-
-happyReduce_35 = happySpecReduce_3  10# happyReduction_35
-happyReduction_35 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut11 happy_x_1 of { happy_var_1 -> 
-	case happyOut12 happy_x_3 of { happy_var_3 -> 
-	happyIn14
-		 ([(happy_var_1,happy_var_3)]
-	)}}
-
-happyReduce_36 = happyReduce 5# 10# happyReduction_36
-happyReduction_36 (happy_x_5 `HappyStk`
-	happy_x_4 `HappyStk`
-	happy_x_3 `HappyStk`
-	happy_x_2 `HappyStk`
-	happy_x_1 `HappyStk`
-	happyRest)
-	 = case happyOut14 happy_x_1 of { happy_var_1 -> 
-	case happyOut11 happy_x_3 of { happy_var_3 -> 
-	case happyOut12 happy_x_5 of { happy_var_5 -> 
-	happyIn14
-		 ((happy_var_3,happy_var_5):happy_var_1
-	) `HappyStk` happyRest}}}
-
-happyReduce_37 = happySpecReduce_0  11# happyReduction_37
-happyReduction_37  =  happyIn15
-		 ([]
-	)
-
-happyReduce_38 = happySpecReduce_1  11# happyReduction_38
-happyReduction_38 happy_x_1
-	 =  case happyOut16 happy_x_1 of { happy_var_1 -> 
-	happyIn15
-		 (reverse happy_var_1
-	)}
-
-happyReduce_39 = happySpecReduce_2  11# happyReduction_39
-happyReduction_39 happy_x_2
-	happy_x_1
-	 =  case happyOut16 happy_x_1 of { happy_var_1 -> 
-	happyIn15
-		 (reverse happy_var_1
-	)}
-
-happyReduce_40 = happySpecReduce_1  12# happyReduction_40
-happyReduction_40 happy_x_1
-	 =  case happyOut12 happy_x_1 of { happy_var_1 -> 
-	happyIn16
-		 ([happy_var_1]
-	)}
-
-happyReduce_41 = happySpecReduce_3  12# happyReduction_41
-happyReduction_41 happy_x_3
-	happy_x_2
-	happy_x_1
-	 =  case happyOut16 happy_x_1 of { happy_var_1 -> 
-	case happyOut12 happy_x_3 of { happy_var_3 -> 
-	happyIn16
-		 (happy_var_3 : happy_var_1
-	)}}
-
-happyNewToken action sts stk [] =
-	happyDoAction 19# notHappyAtAll action sts stk []
-
-happyNewToken action sts stk (tk:tks) =
-	let cont i = happyDoAction i tk action sts stk tks in
-	case tk of {
-	Located _ (StringToken happy_dollar_dollar) -> cont 1#;
-	Located _ (BareKeyToken happy_dollar_dollar) -> cont 2#;
-	Located _ (IntegerToken happy_dollar_dollar) -> cont 3#;
-	Located _ (DoubleToken happy_dollar_dollar) -> cont 4#;
-	Located _ TrueToken -> cont 5#;
-	Located _ FalseToken -> cont 6#;
-	happy_dollar_dollar@(Located _ LeftBracketToken) -> cont 7#;
-	Located _ RightBracketToken -> cont 8#;
-	happy_dollar_dollar@(Located _ LeftBraceToken) -> cont 9#;
-	Located _ RightBraceToken -> cont 10#;
-	Located _ CommaToken -> cont 11#;
-	Located _ PeriodToken -> cont 12#;
-	Located _ EqualToken -> cont 13#;
-	Located _ (ZonedTimeToken happy_dollar_dollar) -> cont 14#;
-	Located _ (LocalTimeToken happy_dollar_dollar) -> cont 15#;
-	Located _ (TimeOfDayToken happy_dollar_dollar) -> cont 16#;
-	Located _ (DayToken       happy_dollar_dollar) -> cont 17#;
-	Located _ EofToken -> cont 18#;
-	_ -> happyError' (tk:tks)
-	}
-
-happyError_ 19# tk tks = happyError' tks
-happyError_ _ tk tks = happyError' (tk:tks)
-
-happyThen :: () => Either TOMLError a -> (a -> Either TOMLError b) -> Either TOMLError b
-happyThen = (>>=)
-happyReturn :: () => a -> Either TOMLError a
-happyReturn = (return)
-happyThen1 m k tks = (>>=) m (\a -> k a tks)
-happyReturn1 :: () => a -> b -> Either TOMLError a
-happyReturn1 = \a tks -> (return) a
-happyError' :: () => [(Located Token)] -> Either TOMLError a
-happyError' = errorP
-
-components tks = happySomeParser where
-  happySomeParser = happyThen (happyParse 0# tks) (\x -> happyReturn (happyOut4 x))
-
-happySeq = happyDontSeq
-
-
--- | This operation is called by happy when no production matches the
--- current token list.
-errorP :: [Located Token] {- ^ nonempty remainig tokens -} -> Either TOMLError a
-errorP = Left . Unexpected . head
-
--- | Attempt to parse a layout annotated token stream or
--- the token that caused the parse to fail.
-parseComponents ::
-  [Located Token]              {- ^ layout annotated token stream -} ->
-  Either TOMLError [Component] {- ^ token at failure or result -}
-parseComponents = components
-
--- | Abort the parse with an error indicating that the given token was unmatched.
-unterminated :: Located Token -> Either TOMLError a
-unterminated = Left . Unterminated
-{-# LINE 1 "templates/GenericTemplate.hs" #-}
-{-# LINE 1 "templates/GenericTemplate.hs" #-}
-{-# LINE 1 "<built-in>" #-}
-{-# LINE 19 "<built-in>" #-}
-{-# LINE 1 "/Users/emertens/Tools/ghc-8.0.2/lib/ghc-8.0.2/include/ghcversion.h" #-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{-# LINE 20 "<built-in>" #-}
-{-# LINE 1 "/var/folders/t0/04lb5h5n1sb6w_ghq4vgpgjw0000gn/T/ghc59778_0/ghc_2.h" #-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{-# LINE 21 "<built-in>" #-}
-{-# LINE 1 "templates/GenericTemplate.hs" #-}
--- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp 
-
-
-{-# LINE 13 "templates/GenericTemplate.hs" #-}
-
-
-
-
-
--- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
-#if __GLASGOW_HASKELL__ > 706
-#define LT(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.<# m)) :: Bool)
-#define GTE(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.>=# m)) :: Bool)
-#define EQ(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.==# m)) :: Bool)
-#else
-#define LT(n,m) (n Happy_GHC_Exts.<# m)
-#define GTE(n,m) (n Happy_GHC_Exts.>=# m)
-#define EQ(n,m) (n Happy_GHC_Exts.==# m)
-#endif
-
-{-# LINE 46 "templates/GenericTemplate.hs" #-}
-
-
-data Happy_IntList = HappyCons Happy_GHC_Exts.Int# Happy_IntList
-
-
-
-
-
-
-{-# LINE 67 "templates/GenericTemplate.hs" #-}
-
-
-{-# LINE 77 "templates/GenericTemplate.hs" #-}
-
-
-
-
-
-
-
-
-
-
-infixr 9 `HappyStk`
-data HappyStk a = HappyStk a (HappyStk a)
-
------------------------------------------------------------------------------
--- starting the parse
-
-happyParse start_state = happyNewToken start_state notHappyAtAll notHappyAtAll
-
------------------------------------------------------------------------------
--- Accepting the parse
-
--- If the current token is 0#, it means we've just accepted a partial
--- parse (a %partial parser).  We must ignore the saved token on the top of
--- the stack in this case.
-happyAccept 0# tk st sts (_ `HappyStk` ans `HappyStk` _) =
-        happyReturn1 ans
-happyAccept j tk st sts (HappyStk ans _) = 
-        (happyTcHack j (happyTcHack st)) (happyReturn1 ans)
-
------------------------------------------------------------------------------
--- Arrays only: do the next action
-
-
-
-happyDoAction i tk st
-        = {- nothing -}
-          
-
-          case action of
-                0#           -> {- nothing -}
-                                     happyFail i tk st
-                -1#          -> {- nothing -}
-                                     happyAccept i tk st
-                n | LT(n,(0# :: Happy_GHC_Exts.Int#)) -> {- nothing -}
-                                                   
-                                                   (happyReduceArr Happy_Data_Array.! rule) i tk st
-                                                   where rule = (Happy_GHC_Exts.I# ((Happy_GHC_Exts.negateInt# ((n Happy_GHC_Exts.+# (1# :: Happy_GHC_Exts.Int#))))))
-                n                 -> {- nothing -}
-                                     
-
-                                     happyShift new_state i tk st
-                                     where new_state = (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#))
-   where off    = indexShortOffAddr happyActOffsets st
-         off_i  = (off Happy_GHC_Exts.+# i)
-         check  = if GTE(off_i,(0# :: Happy_GHC_Exts.Int#))
-                  then EQ(indexShortOffAddr happyCheck off_i, i)
-                  else False
-         action
-          | check     = indexShortOffAddr happyTable off_i
-          | otherwise = indexShortOffAddr happyDefActions st
-
-
-indexShortOffAddr (HappyA# arr) off =
-        Happy_GHC_Exts.narrow16Int# i
-  where
-        i = Happy_GHC_Exts.word2Int# (Happy_GHC_Exts.or# (Happy_GHC_Exts.uncheckedShiftL# high 8#) low)
-        high = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr (off' Happy_GHC_Exts.+# 1#)))
-        low  = Happy_GHC_Exts.int2Word# (Happy_GHC_Exts.ord# (Happy_GHC_Exts.indexCharOffAddr# arr off'))
-        off' = off Happy_GHC_Exts.*# 2#
-
-
-
-
-
-data HappyAddr = HappyA# Happy_GHC_Exts.Addr#
-
-
-
-
------------------------------------------------------------------------------
--- HappyState data type (not arrays)
-
-
-{-# LINE 170 "templates/GenericTemplate.hs" #-}
-
------------------------------------------------------------------------------
--- Shifting a token
-
-happyShift new_state 0# tk st sts stk@(x `HappyStk` _) =
-     let i = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in
---     trace "shifting the error token" $
-     happyDoAction i tk new_state (HappyCons (st) (sts)) (stk)
-
-happyShift new_state i tk st sts stk =
-     happyNewToken new_state (HappyCons (st) (sts)) ((happyInTok (tk))`HappyStk`stk)
-
--- happyReduce is specialised for the common cases.
-
-happySpecReduce_0 i fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happySpecReduce_0 nt fn j tk st@((action)) sts stk
-     = happyGoto nt j tk st (HappyCons (st) (sts)) (fn `HappyStk` stk)
-
-happySpecReduce_1 i fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happySpecReduce_1 nt fn j tk _ sts@((HappyCons (st@(action)) (_))) (v1`HappyStk`stk')
-     = let r = fn v1 in
-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
-
-happySpecReduce_2 i fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happySpecReduce_2 nt fn j tk _ (HappyCons (_) (sts@((HappyCons (st@(action)) (_))))) (v1`HappyStk`v2`HappyStk`stk')
-     = let r = fn v1 v2 in
-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
-
-happySpecReduce_3 i fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happySpecReduce_3 nt fn j tk _ (HappyCons (_) ((HappyCons (_) (sts@((HappyCons (st@(action)) (_))))))) (v1`HappyStk`v2`HappyStk`v3`HappyStk`stk')
-     = let r = fn v1 v2 v3 in
-       happySeq r (happyGoto nt j tk st sts (r `HappyStk` stk'))
-
-happyReduce k i fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happyReduce k nt fn j tk st sts stk
-     = case happyDrop (k Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) sts of
-         sts1@((HappyCons (st1@(action)) (_))) ->
-                let r = fn stk in  -- it doesn't hurt to always seq here...
-                happyDoSeq r (happyGoto nt j tk st1 sts1 r)
-
-happyMonadReduce k nt fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happyMonadReduce k nt fn j tk st sts stk =
-      case happyDrop k (HappyCons (st) (sts)) of
-        sts1@((HappyCons (st1@(action)) (_))) ->
-          let drop_stk = happyDropStk k stk in
-          happyThen1 (fn stk tk) (\r -> happyGoto nt j tk st1 sts1 (r `HappyStk` drop_stk))
-
-happyMonad2Reduce k nt fn 0# tk st sts stk
-     = happyFail 0# tk st sts stk
-happyMonad2Reduce k nt fn j tk st sts stk =
-      case happyDrop k (HappyCons (st) (sts)) of
-        sts1@((HappyCons (st1@(action)) (_))) ->
-         let drop_stk = happyDropStk k stk
-
-             off = indexShortOffAddr happyGotoOffsets st1
-             off_i = (off Happy_GHC_Exts.+# nt)
-             new_state = indexShortOffAddr happyTable off_i
-
-
-
-          in
-          happyThen1 (fn stk tk) (\r -> happyNewToken new_state sts1 (r `HappyStk` drop_stk))
-
-happyDrop 0# l = l
-happyDrop n (HappyCons (_) (t)) = happyDrop (n Happy_GHC_Exts.-# (1# :: Happy_GHC_Exts.Int#)) t
-
-happyDropStk 0# l = l
-happyDropStk n (x `HappyStk` xs) = happyDropStk (n Happy_GHC_Exts.-# (1#::Happy_GHC_Exts.Int#)) xs
-
------------------------------------------------------------------------------
--- Moving to a new state after a reduction
-
-
-happyGoto nt j tk st = 
-   {- nothing -}
-   happyDoAction j tk new_state
-   where off = indexShortOffAddr happyGotoOffsets st
-         off_i = (off Happy_GHC_Exts.+# nt)
-         new_state = indexShortOffAddr happyTable off_i
-
-
-
-
------------------------------------------------------------------------------
--- Error recovery (0# is the error token)
-
--- parse error if we are in recovery and we fail again
-happyFail 0# tk old_st _ stk@(x `HappyStk` _) =
-     let i = (case Happy_GHC_Exts.unsafeCoerce# x of { (Happy_GHC_Exts.I# (i)) -> i }) in
---      trace "failing" $ 
-        happyError_ i tk
-
-{-  We don't need state discarding for our restricted implementation of
-    "error".  In fact, it can cause some bogus parses, so I've disabled it
-    for now --SDM
-
--- discard a state
-happyFail  0# tk old_st (HappyCons ((action)) (sts)) 
-                                                (saved_tok `HappyStk` _ `HappyStk` stk) =
---      trace ("discarding state, depth " ++ show (length stk))  $
-        happyDoAction 0# tk action sts ((saved_tok`HappyStk`stk))
--}
-
--- Enter error recovery: generate an error token,
---                       save the old token and carry on.
-happyFail  i tk (action) sts stk =
---      trace "entering error recovery" $
-        happyDoAction 0# tk action sts ( (Happy_GHC_Exts.unsafeCoerce# (Happy_GHC_Exts.I# (i))) `HappyStk` stk)
-
--- Internal happy errors:
-
-notHappyAtAll :: a
-notHappyAtAll = error "Internal Happy error\n"
-
------------------------------------------------------------------------------
--- Hack to get the typechecker to accept our action functions
-
-
-happyTcHack :: Happy_GHC_Exts.Int# -> a -> a
-happyTcHack x y = y
-{-# INLINE happyTcHack #-}
-
-
------------------------------------------------------------------------------
--- Seq-ing.  If the --strict flag is given, then Happy emits 
---      happySeq = happyDoSeq
--- otherwise it emits
---      happySeq = happyDontSeq
-
-happyDoSeq, happyDontSeq :: a -> b -> b
-happyDoSeq   a b = a `seq` b
-happyDontSeq a b = b
-
------------------------------------------------------------------------------
--- Don't inline any functions from the template.  GHC has a nasty habit
--- of deciding to inline happyGoto everywhere, which increases the size of
--- the generated parser quite a bit.
-
-
-{-# NOINLINE happyDoAction #-}
-{-# NOINLINE happyTable #-}
-{-# NOINLINE happyCheck #-}
-{-# NOINLINE happyActOffsets #-}
-{-# NOINLINE happyGotoOffsets #-}
-{-# NOINLINE happyDefActions #-}
-
-{-# NOINLINE happyShift #-}
-{-# NOINLINE happySpecReduce_0 #-}
-{-# NOINLINE happySpecReduce_1 #-}
-{-# NOINLINE happySpecReduce_2 #-}
-{-# NOINLINE happySpecReduce_3 #-}
-{-# NOINLINE happyReduce #-}
-{-# NOINLINE happyMonadReduce #-}
-{-# NOINLINE happyGoto #-}
-{-# NOINLINE happyFail #-}
-
--- end of Happy Template.
-
diff --git a/src/TOML.hs b/src/TOML.hs
deleted file mode 100644
--- a/src/TOML.hs
+++ /dev/null
@@ -1,45 +0,0 @@
-{-# Language Safe #-}
-{-|
-Module      : TOML
-Description : Parser for the TOML configuration language
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
-
-Parser for the TOML file format: <https://github.com/toml-lang/toml>
--}
-module TOML
-  (
-  -- * Parsing
-    parseTOML
-
-  -- * Values
-  , Value(..)
-
-  -- * Error information
-  , TOMLError(..)
-  , LexerError(..)
-  , Located(..)
-  , Position(..)
-  , Token(..)
-  ) where
-
-import Control.Monad
-import Data.Text (Text)
-
-import TOML.Components
-import TOML.Errors
-import TOML.Lexer
-import TOML.Located
-import TOML.Parser
-import TOML.Tokens
-import TOML.Value
-
--- | Parse the given TOML file. Returns the top-level table as a list of
--- key-value pairs or returns an error.
-parseTOML :: Text -> Either TOMLError [(Text,Value)]
-parseTOML = mapLeft OverlappingKey . componentsToTable
-        <=< parseComponents . scanTokens
-  where
-    mapLeft f (Left  e) = Left (f e)
-    mapLeft _ (Right x) = Right x
diff --git a/src/TOML/Components.hs b/src/TOML/Components.hs
deleted file mode 100644
--- a/src/TOML/Components.hs
+++ /dev/null
@@ -1,122 +0,0 @@
-{-|
-Module      : TOML.Components
-Description : /Internal:/ Type and operations for raw top-level TOML elements
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
-
-This module provides an intermediate representation for TOML files.
-The parser produces a list of top-level table components, and this
-module gathers those together in the form of tables and lists of
-tables.
-
--}
-module TOML.Components where
-
-import           Control.Monad
-import           Data.Foldable
-import           Data.List
-import           Data.Maybe
-import           Data.Ord
-import           Data.Text (Text)
-import qualified Data.Text as Text
-
-import           TOML.Value
-
--- | Various top-level elements that can be returned by the TOML parser.
-data Component
-  = InitialEntry    [(Text,Value)] -- ^ key value pairs before any @[header]@
-  | TableEntry Path [(Text,Value)] -- ^ key value pairs after any @[header]@
-  | ArrayEntry Path [(Text,Value)] -- ^ key value pairs after any @[[header]]@
-  deriving (Read, Show)
-
--- | Non-empty list of table keys
-type Path = [Text]
-
-
--- | Merge a list of top-level components into a single
--- table, or throw an error with an ambiguous path.
-componentsToTable :: [Component] -> Either Path [(Text,Value)]
-componentsToTable = flattenTableList . collapseComponents
-
-
--- | Collapse the various components generated by the parser into a
--- single list of path-value pairs. This operations is particularly
--- responsible for gathering top-level array entries together.
-collapseComponents :: [Component] -> [(Path,Value)]
-collapseComponents [] = []
-collapseComponents (InitialEntry kvs : xs) =
-  [ ([k],v) | (k,v) <- kvs ] ++ collapseComponents xs
-collapseComponents (TableEntry k kvs : xs) =
-  (k, Table kvs) : collapseComponents xs
-collapseComponents xs@(ArrayEntry k _ : _) =
-  case splitArrays k xs of
-    (kvss, xs') -> (k, List (map Table kvss)) : collapseComponents xs'
-
-
--- | Extract all of the leading 'ArrayEntry' components that match
--- the given path.
-splitArrays :: Path -> [Component] -> ([[(Text,Value)]], [Component])
-splitArrays k1 (ArrayEntry k2 kvs : xs)
-  | k1 == k2 =
-     case splitArrays k1 xs of
-       (kvss, xs2) -> (kvs:kvss, xs2)
-splitArrays _ xs = ([],xs)
-
-
--- | Given a list of key-value pairs ordered by key, group the list
--- by equality on the head of the key-path list.
-factorHeads :: Eq k => [([k],v)] -> [(k,[([k],v)])]
-factorHeads xs = [ (h, [ (k, v) | (_:k,v) <- g ])
-                 | let eq (x,_) (y,_) = take 1 x == take 1 y
-                 , g@((h:_,_):_) <- groupBy eq xs
-                 ]
-
-
--- | Flatten a list of path-value pairs into a single table.
--- If in the course of flattening the pairs if the value at a
--- particular path is assigned twice, that path will be returned
--- instead.
-flattenTableList :: [(Path, Value)] -> Either Path [(Text, Value)]
-flattenTableList = go [] . order
-  where
-    go path xs = sequenceA [ flattenGroup path x ys | (x,ys) <- factorHeads xs ]
-
-    flattenGroup :: Path -> Text -> [(Path,Value)] -> Either Path (Text,Value)
-    flattenGroup path k (([],Table t):kvs) =
-      flattenGroup path k (mergeInlineTable t kvs)
-    flattenGroup path k (([],v):rest)
-      | null rest = (k,v) <$ validateInlineTables (k:path) v
-      | otherwise = Left (reverse (k:path))
-    flattenGroup path k kvs =
-      do kvs' <- go (k:path) kvs
-         return (k, Table kvs')
-
-
--- | Merge a table into the current list of path-value pairs. The
--- resulting list is sorted to make it appropriate for subsequent
--- grouping operations.
-mergeInlineTable :: [(Text,value)] -> [(Path,value)] -> [(Path,value)]
-mergeInlineTable t kvs = order ([([i],j) | (i,j) <- t] ++ kvs)
-
-
--- | Order a list of path-value pairs lexicographically by path.
-order :: [(Path,value)] -> [(Path,value)]
-order = sortBy (comparing fst)
-
-
--- | Throw an error with the problematic path if a duplicate is found.
-validateInlineTables :: Path -> Value -> Either Path ()
-validateInlineTables path (Table t) =
-  case findDuplicate (map fst t) of
-    Just k  -> Left (reverse (k:path))
-    Nothing -> traverse_ (\(k,v) -> validateInlineTables (k:path) v) t
-validateInlineTables path (List xs) =
-  zipWithM_ (\i x -> validateInlineTables (Text.pack (show i):path) x)
-        [0::Int ..] xs
-validateInlineTables _ _ = Right ()
-
-
--- | Find an entry that appears in the given list more than once.
-findDuplicate :: Ord a => [a] -> Maybe a
-findDuplicate = listToMaybe . map head . filter (not . null . tail) . group . sort
diff --git a/src/TOML/Errors.hs b/src/TOML/Errors.hs
deleted file mode 100644
--- a/src/TOML/Errors.hs
+++ /dev/null
@@ -1,67 +0,0 @@
-{-|
-Module      : TOML.Errors
-Description : /Internal:/ Errors that can occur while processing TOML
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
--}
-module TOML.Errors where
-
-import           Control.Exception
-import           Data.List
-import           Data.Text (Text)
-import qualified Data.Text as Text
-
-import           TOML.Tokens
-import           TOML.Located
-
--- | Errors that can occur while loading a TOML file.
-data TOMLError
-  = Unexpected   (Located Token) -- ^ unexpected token while parser
-  | Unterminated (Located Token) -- ^ unterminated token while parser
-  | OverlappingKey [Text]        -- ^ ambiguous table entry
-  deriving (Read, Show)
-
--- | 'displayException' provides human-readable error message
-instance Exception TOMLError where
-  displayException (Unexpected (Located pos token)) =
-    show (posLine pos) ++ ":" ++ show (posColumn pos) ++
-    ": unexpected " ++ showToken token
-  displayException (Unterminated (Located pos token)) =
-    show (posLine pos) ++ ":" ++ show (posColumn pos) ++
-    ": unterminated " ++ showToken token
-  displayException (OverlappingKey path) =
-    "multiple definitions of: " ++
-    intercalate "." (map Text.unpack path)
-
--- | Generates a human-readable description of a token.
-showToken :: Token -> String
-showToken t =
-  case t of
-    StringToken{}     -> "string literal"
-    BareKeyToken k    -> "table key ‘" ++ Text.unpack k ++ "’"
-    IntegerToken i    -> "integer " ++ show i
-    DoubleToken d     -> "float " ++ show d
-    ZonedTimeToken dt -> "offset date-time " ++ show dt
-    LocalTimeToken dt -> "local data-time " ++ show dt
-    DayToken       dt -> "local date " ++ show dt
-    TimeOfDayToken dt -> "local time " ++ show dt
-    CommaToken        -> "‘,’"
-    PeriodToken       -> "‘.’"
-    LeftBracketToken  -> "‘[’"
-    RightBracketToken -> "‘]’"
-    LeftBraceToken    -> "‘{’"
-    RightBraceToken   -> "‘}’"
-    EqualToken        -> "‘=’"
-    TrueToken         -> "‘true’"
-    FalseToken        -> "‘false’"
-    ErrorToken e      -> "lexical error: " ++ showLexerError e
-    EofToken          -> "end-of-file"
-
--- | Generates a human-readable description of a lexical error.
-showLexerError :: LexerError -> String
-showLexerError e =
-  case e of
-    UntermString -> "unterminated string literal"
-    BadEscape    -> "bad escape sequence"
-    NoMatch c    -> "unexpected ‘" ++ [c] ++ "’"
diff --git a/src/TOML/Lexer.x b/src/TOML/Lexer.x
deleted file mode 100644
--- a/src/TOML/Lexer.x
+++ /dev/null
@@ -1,115 +0,0 @@
-{
-{-# LANGUAGE Trustworthy #-}
-{-|
-Module      : TOML.Lexer
-Description : /Internal:/ Lexer for TOML generated by Alex
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
-
-Lexer for TOML generated by Alex. Errors are reported in the resulting
-token list with 'Error'. As much as possible this module only contains
-generated code. The rest of the implementation is in "LexerUtils".
--}
-module TOML.Lexer (scanTokens) where
-
-import           Data.Text (Text)
-import qualified Data.Text as Text
-
-import           TOML.LexerUtils
-import           TOML.Tokens
-import           TOML.Located
-
-}
-
-$asciialpha     = [A-Z a-z]
-$digit          = [0-9]
-$octdigit       = [0-7]
-$hexdigit       = [0-9a-fA-F]
-
-@decimal        = $digit+
-
-@barekey        = ($asciialpha | $digit | \_ | \-)+
-
-@newline        = \r? \n
-
-@fractpart      = $digit+ (\_ $digit+)*
-@integer        = [\-\+]? (0 | [1-9] $digit* (\_ $digit+)*)
-@double         = @integer (\. @fractpart)? ([eE] @integer)?
-
-
-@day            = @decimal \- $digit{2} \- $digit{2}
-@timeofday      = @decimal \: @decimal \: @decimal (\. @decimal)?
-@localtime      = @day T @timeofday
-@zonedtime      = @localtime ( [a-zA-Z] | [\+\-] $digit{2} \:? $digit{2} )
-
-
-toml :-
-
-<0> {
-$white+                 ;
-"#" .*                  ;
-
-"{"                     { token_ LeftBraceToken         }
-"}"                     { token_ RightBraceToken        }
-"["                     { token_ LeftBracketToken       }
-"]"                     { token_ RightBracketToken      }
-","                     { token_ CommaToken             }
-"."                     { token_ PeriodToken            }
-"="                     { token_ EqualToken             }
-@integer                { token integer                 }
-@double                 { token double                  }
-"true"                  { token_ TrueToken              }
-"false"                 { token_ FalseToken             }
-@localtime              { token localtime               }
-@zonedtime              { token zonedtime               }
-@timeofday              { token timeofday               }
-@day                    { token day                     }
-@barekey                { token bareKeyToken            }
-
-'''      @newline ?     { startString mlsq              }
-\" \" \" @newline ?     { startString mldq              }
-'                       { startString slsq              }
-\"                      { startString sldq              }
-} -- end of <0>
-
-<mlsq> '''              { endString                     }
-<mldq> \" \" \"         { endString                     }
-<slsq> '                { endString                     }
-<sldq> \"               { endString                     }
-
-<mlsq,mldq> @newline    { emitChar                      }
-<sldq,mldq> {
-\\ b                    { emitChar' '\b'                }
-\\ t                    { emitChar' '\t'                }
-\\ n                    { emitChar' '\n'                }
-\\ f                    { emitChar' '\f'                }
-\\ r                    { emitChar' '\r'                }
-\\ \"                   { emitChar' '"'                 }
-\\ \\                   { emitChar' '\\'                }
-\\ u $hexdigit{4}       { emitUnicodeChar               }
-\\ U $hexdigit{8}       { emitUnicodeChar               }
-\\ @newline $white *    ;
-\\                      { token_ (ErrorToken BadEscape) }
-}
-
-<sldq,slsq,mldq,mlsq> . { emitChar                      }
-
-{
--- | Produce a token stream from an input file. The token
--- stream will always be terminated by an 'ErrorToken' or
--- 'EofToken'.
-scanTokens ::
-  Text            {- ^ Source text          -} ->
-  [Located Token] {- ^ Tokens with position -}
-scanTokens str = go (Located startPos str) InNormal
-  where
-  go inp st =
-    case alexScan inp (lexerModeInt st) of
-      AlexEOF                -> eofAction (locPosition inp) st
-      AlexError inp'         -> errorAction inp'
-      AlexSkip  inp' _       -> go inp' st
-      AlexToken inp' len act -> case act (fmap (Text.take len) inp) st of
-                                  (st', xs) -> xs ++ go inp' st'
-
-}
diff --git a/src/TOML/LexerUtils.hs b/src/TOML/LexerUtils.hs
deleted file mode 100644
--- a/src/TOML/LexerUtils.hs
+++ /dev/null
@@ -1,236 +0,0 @@
-{-# LANGUAGE BangPatterns #-}
-{-|
-Module      : TOML.LexerUtils
-Description : /Internal:/ Lexer support operations for TOML
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
-
-This module is separate from the Lexer.x input to Alex
-to segregate the automatically generated code from the
-hand written code. The automatically generated code
-causes lots of warnings which mask the interesting warnings.
--}
-module TOML.LexerUtils
-  (
-  -- * Alex required definitions
-    AlexInput
-  , alexGetByte
-
-  -- * Lexer modes
-  , LexerMode(..)
-  , lexerModeInt
-
-  -- * Lexer actions
-  , Action
-  , token
-  , token_
-  , errorAction
-  , eofAction
-
-  -- * Token parsers
-  , integer
-  , double
-  , bareKeyToken
-
-  -- * String literal actions
-  , startString
-  , emitChar
-  , emitChar'
-  , emitUnicodeChar
-  , endString
-
-  -- * Date/time token parsers
-  , localtime
-  , zonedtime
-  , day
-  , timeofday
-  ) where
-
-import           Data.Char (isSpace, isControl, isAscii, ord, chr)
-import           Data.Text (Text)
-import qualified Data.Text as Text
-import qualified Data.Text.Read as Text
-import           Data.Time (ParseTime, parseTimeOrError, defaultTimeLocale, iso8601DateFormat)
-import           Data.Word (Word8)
-
-import           TOML.Tokens
-import           TOML.Located
-
-------------------------------------------------------------------------
--- Custom Alex wrapper - these functions are used by generated code
-------------------------------------------------------------------------
-
--- | The generated code expects the lexer input type to be named 'AlexInput'
-type AlexInput = Located Text
-
--- | Get the next characteristic byte from the input source.
-alexGetByte :: AlexInput -> Maybe (Word8,AlexInput)
-alexGetByte (Located p cs)
-  = do (c,cs') <- Text.uncons cs
-       let !b   = byteForChar c
-           !inp = Located (move p c) cs'
-       return (b, inp)
-
--- | The TOML format doesn't distinguish between any of the non-ASCII
--- characters. This function extracts the printable and whitespace
--- subset of Unicode and maps it to the ASCII value as used by Alex.
-byteForChar :: Char -> Word8
-byteForChar c
-  | isControl c && not (isSpace c) = 0
-  | isAscii c = fromIntegral (ord c)
-  | otherwise = 0
-
-------------------------------------------------------------------------
-
--- | Advance the position according to the kind of character lexed.
-move :: Position -> Char -> Position
-move (Position ix line column) c =
-  case c of
-    '\t' -> Position (ix + 1) line (((column + 7) `div` 8) * 8 + 1)
-    '\n' -> Position (ix + 1) (line + 1) 1
-    _    -> Position (ix + 1) line (column + 1)
-
-------------------------------------------------------------------------
--- Lexer Modes
-------------------------------------------------------------------------
-
--- | The lexer can be in a normal mode or can be lexing a string literal.
-data LexerMode
-  = InNormal
-  | InString !Int !Position String
-    -- ^ alex-mode, starting-position, reversed accumulated characters
-  deriving Show
-
-
--- | Compute the Alex state corresponding to a particular 'LexerMode'
-lexerModeInt :: LexerMode -> Int
-lexerModeInt InNormal{}           = 0
-lexerModeInt (InString mode _ _)  = mode
-
-
-------------------------------------------------------------------------
--- Lexer actions
-------------------------------------------------------------------------
-
--- | Type of actions used by lexer upon matching a rule
-type Action =
-  Located Text                 {- ^ located lexeme                     -} ->
-  LexerMode                    {- ^ lexer mode                         -} ->
-  (LexerMode, [Located Token]) {- ^ updated lexer mode, emitted tokens -}
-
-
--- | Helper function for building an 'Action' using the lexeme
-token :: (Text -> Token) {- ^ lexeme -> token -} -> Action
-token f match st = (st, [fmap f match])
-
--- | Helper function for building an 'Action' where the lexeme is unused.
-token_ :: Token -> Action
-token_ = token . const
-
--- | Action to perform upon end of file. Produce errors if EOF was unexpected.
-eofAction :: Position -> LexerMode -> [Located Token]
-eofAction eofPosn st =
-  case st of
-    InString _ posn _ -> [Located posn (ErrorToken UntermString)]
-    InNormal          -> [Located eofPosn EofToken]
-
--- | Action to perform when lexer gets stuck. Emits an error.
-errorAction :: AlexInput -> [Located Token]
-errorAction inp = [fmap (ErrorToken . NoMatch . Text.head) inp]
-
-------------------------------------------------------------------------
--- String literal mode actions
-------------------------------------------------------------------------
-
--- | Enter the string literal lexer
-startString :: Int -> Action
-startString mode lexeme _ = (InString mode (locPosition lexeme) [], [])
-
-
--- | Add current lexeme to the current string literal.
-emitChar :: Action
-emitChar _ InNormal = error "PANIC: emitChar used in normal mode"
-emitChar lexeme (InString mode pos acc) = (InString mode pos acc', [])
-  where
-    acc' = reverse (Text.unpack (locThing lexeme)) ++ acc
-
-
--- | Add literal character to the current string literal.
-emitChar' :: Char -> Action
-emitChar' c _ (InString mode pos acc) = (InString mode pos (c : acc), [])
-emitChar' _ _ _ = error "PANIC: emitChar' used in normal mode"
-
-
--- | Interpret the current lexeme as a unicode escape sequence and add
--- the resulting character to the current string literal.
-emitUnicodeChar :: Action
-emitUnicodeChar lexeme mode =
-  case Text.hexadecimal (Text.drop 2 (locThing lexeme)) of
-    Right (n, _)
-      | n < 0x110000 -> emitChar' (chr n) lexeme mode
-      | otherwise    -> (InNormal, [Located (locPosition lexeme) (ErrorToken BadEscape)])
-    _ -> error "PANIC: bad unicode unescape implementation"
-
-
--- | Successfully terminate the current mode and emit tokens as needed
-endString :: Action
-endString _ mode =
-  case mode of
-    InNormal -> error "PANIC: error in string literal lexer"
-    InString _ p input ->
-      let !str = Text.pack (reverse input)
-      in (InNormal, [Located p (StringToken str)])
-
-------------------------------------------------------------------------
--- Token builders
-------------------------------------------------------------------------
-
--- | Construct a 'Integer' token from a lexeme.
-integer :: Text {- ^ lexeme -} -> Token
-integer str = IntegerToken n
-  where
-  Right (n,_) = Text.signed Text.decimal (Text.filter (/= '_') str)
-
-
--- | Construct a 'Double' token from a lexeme.
-double :: Text {- ^ lexeme -} -> Token
-double str = DoubleToken n
-  where
-  Right (n,_) = Text.signed Text.double (Text.filter (/= '_') str)
-
-
--- | Construct a 'BareKeyToken' for the given lexeme. This operation
--- copies the lexeme into a fresh 'Text' value to ensure that a slice
--- of the original source file is kept.
-bareKeyToken :: Text {- ^ lexeme -} -> Token
-bareKeyToken txt = BareKeyToken $! Text.copy txt
-
-------------------------------------------------------------------------
--- Date and time token parsers
-------------------------------------------------------------------------
-
--- | Parse a date\/time lexeme to produce a 'Token'. As long as the
--- regular expressions in the "Lexer" module are correct, this parse
--- will never fail, so failure to parse throws an error.
-timeParser ::
-  ParseTime t =>
-  (t -> Token) {- ^ token function   -} ->
-  String       {- ^ time format      -} ->
-  Text         {- ^ lexeme           -} ->
-  Token        {- ^ date\/time token -}
-timeParser con fmt txt =
-  con (parseTimeOrError False defaultTimeLocale fmt (Text.unpack txt))
-
-
--- | Format string for parsing time of day: @hours:minutes:seconds.fractional@
-timeFormat :: String
-timeFormat = "%T%Q"
-
-
--- | Date and time lexeme parsers
-zonedtime, localtime, day, timeofday :: Text -> Token
-zonedtime = timeParser ZonedTimeToken (iso8601DateFormat (Just timeFormat)++"%Z")
-localtime = timeParser LocalTimeToken (iso8601DateFormat (Just timeFormat))
-day       = timeParser DayToken       (iso8601DateFormat Nothing)
-timeofday = timeParser TimeOfDayToken timeFormat
diff --git a/src/TOML/Located.hs b/src/TOML/Located.hs
deleted file mode 100644
--- a/src/TOML/Located.hs
+++ /dev/null
@@ -1,28 +0,0 @@
-{-# Language DeriveTraversable #-}
-{-|
-Module      : TOML.Located
-Description : /Internal:/ Wrapper for tracking text-file location of things
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
--}
-module TOML.Located where
-
--- | A position in a text file
-data Position = Position
-  { posIndex  :: {-# UNPACK #-} !Int -- ^ zero-based character index
-  , posLine   :: {-# UNPACK #-} !Int -- ^ one-based line number
-  , posColumn :: {-# UNPACK #-} !Int -- ^ one-based column number
-  }
-  deriving (Read, Show)
-
--- | A value annotated with its text file position
-data Located a = Located
-  { locPosition :: {-# UNPACK #-} !Position -- ^ position information
-  , locThing    :: !a                       -- ^ annotated value
-  }
-  deriving (Read, Show, Functor, Foldable, Traversable)
-
--- | The initial 'Position' for the start of a file
-startPos :: Position
-startPos = Position { posIndex = 0, posLine = 1, posColumn = 1 }
diff --git a/src/TOML/Parser.y b/src/TOML/Parser.y
deleted file mode 100644
--- a/src/TOML/Parser.y
+++ /dev/null
@@ -1,143 +0,0 @@
-{
-{-# LANGUAGE Trustworthy #-}
-{-|
-Module      : TOML.Parser
-Description : /Internal:/ Parser for TOML generated by Happy
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
-
-Parser for TOML generated by Happy.
-
--}
-module TOML.Parser (parseComponents) where
-
-import Data.Text (Text,pack)
-
-import TOML.Components
-import TOML.Errors
-import TOML.Located
-import TOML.Tokens
-import TOML.Value
-
-}
-
-%tokentype                      { Located Token                 }
-%token
-STRING                          { Located _ (StringToken $$)    }
-BAREKEY                         { Located _ (BareKeyToken $$)   }
-INTEGER                         { Located _ (IntegerToken $$)   }
-DOUBLE                          { Located _ (DoubleToken $$)    }
-'true'                          { Located _ TrueToken           }
-'false'                         { Located _ FalseToken          }
-'['                             { $$@(Located _ LeftBracketToken)}
-']'                             { Located _ RightBracketToken   }
-'{'                             { $$@(Located _ LeftBraceToken) }
-'}'                             { Located _ RightBraceToken     }
-','                             { Located _ CommaToken          }
-'.'                             { Located _ PeriodToken         }
-'='                             { Located _ EqualToken          }
-ZONEDTIME                       { Located _ (ZonedTimeToken $$) }
-LOCALTIME                       { Located _ (LocalTimeToken $$) }
-TIMEOFDAY                       { Located _ (TimeOfDayToken $$) }
-DAY                             { Located _ (DayToken       $$) }
-EOF                             { Located _ EofToken            }
-
-%monad { Either TOMLError }
-%error { errorP }
-
--- | Attempt to parse a layout annotated token stream or
--- the token that caused the parse to fail.
-%name components
-
-%%
-
-components ::                   { [Component]                   }
-  : componentsR EOF             { reverse $1                    }
-
-componentsR ::                  { [Component]                   }
-  : keyvalues                   { [InitialEntry $1]             }
-  | componentsR component keyvalues { $2 $3 : $1                }
-
-component ::                    { [(Text,Value)] -> Component   }
-  : '['     keys     ']'        { TableEntry $2                 }
-  | '[' '[' keys ']' ']'        { ArrayEntry $3                 }
-
-  | '['     keys     error      {% unterminated $1              }
-  | '[' '[' keys     error      {% unterminated $2              }
-  | '[' '[' keys ']' error      {% unterminated $1              }
-
-keyvalues ::                    { [(Text,Value)]                }
-  : keyvaluesR                  { reverse $1                    }
-
-keyvaluesR ::                   { [(Text,Value)]                }
-  :                             { []                            }
-  | keyvaluesR key '=' value    { ($2,$4):$1                    }
-
-keys ::                         { [Text]                        }
-  : keysR                       { reverse $1                    }
-
-keysR ::                        { [Text]                        }
-  : key                         { [$1]                          }
-  | keysR '.' key               { $3 : $1                       }
-
-key ::                          { Text                          }
-  : BAREKEY                     { $1                            }
-  | STRING                      { $1                            }
-  | INTEGER                     { pack (show $1)                }
-  | 'true'                      { pack "true"                   }
-  | 'false'                     { pack "false"                  }
-
-value ::                        { Value                         }
-  : INTEGER                     { Integer    $1                 }
-  | DOUBLE                      { Double     $1                 }
-  | STRING                      { String     $1                 }
-  | ZONEDTIME                   { ZonedTimeV $1                 }
-  | TIMEOFDAY                   { TimeOfDayV $1                 }
-  | DAY                         { DayV       $1                 }
-  | LOCALTIME                   { LocalTimeV $1                 }
-  | 'true'                      { Bool       True               }
-  | 'false'                     { Bool       False              }
-  | '{' inlinetable '}'         { Table      $2                 }
-  | '[' inlinearray ']'         { List       $2                 }
-
-  | '{' inlinetable error       {% unterminated $1              }
-  | '[' inlinearray error       {% unterminated $1              }
-
-inlinetable ::                  { [(Text,Value)]                }
-  :                             { []                            }
-  | inlinetableR                { reverse $1                    }
-
-inlinetableR ::                 { [(Text,Value)]                }
-  : key '=' value               { [($1,$3)]                     }
-  | inlinetableR ',' key '=' value
-                                { ($3,$5):$1                    }
-
-inlinearray ::                  { [Value]                       }
-  :                             { []                            }
-  | inlinearrayR                { reverse $1                    }
-  | inlinearrayR ','            { reverse $1                    }
-
-inlinearrayR ::                 { [Value]                       }
-  : value                       { [$1]                          }
-  | inlinearrayR ',' value      { $3 : $1                       }
-
-{
-
--- | This operation is called by happy when no production matches the
--- current token list.
-errorP :: [Located Token] {- ^ nonempty remainig tokens -} -> Either TOMLError a
-errorP = Left . Unexpected . head
-
--- | Attempt to parse a layout annotated token stream or
--- the token that caused the parse to fail.
-parseComponents ::
-  [Located Token]              {- ^ layout annotated token stream -} ->
-  Either TOMLError [Component] {- ^ token at failure or result -}
-parseComponents = components
-
--- | Abort the parse with an error indicating that the given token was unmatched.
-unterminated :: Located Token -> Either TOMLError a
-unterminated = Left . Unterminated
-
-}
diff --git a/src/TOML/Tokens.hs b/src/TOML/Tokens.hs
deleted file mode 100644
--- a/src/TOML/Tokens.hs
+++ /dev/null
@@ -1,49 +0,0 @@
-{-|
-Module      : TOML.Tokens
-Description : Internal: Token type and operations for TOML
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
-
-This module provides the token type used in the lexer and
-parser and provides the extra pass to insert layout tokens.
--}
-module TOML.Tokens
-  ( Token(..)
-  , LexerError(..)
-  ) where
-
-import Data.Text (Text)
-import Data.Time
-
-
--- | The token type used by "Config.Lexer" and "Config.Parser"
-data Token
-  = StringToken  Text        -- ^ string literal
-  | BareKeyToken Text        -- ^ bare table key
-  | IntegerToken Integer     -- ^ integer literal
-  | DoubleToken  Double      -- ^ floating   -point literal
-  | ZonedTimeToken ZonedTime -- ^ offset date-time
-  | LocalTimeToken LocalTime -- ^ local date-time
-  | TimeOfDayToken TimeOfDay -- ^ local time
-  | DayToken     Day         -- ^ local date
-  | CommaToken               -- ^ @,@
-  | PeriodToken              -- ^ @.@
-  | LeftBracketToken         -- ^ @[@
-  | RightBracketToken        -- ^ @[@
-  | LeftBraceToken           -- ^ @{@
-  | RightBraceToken          -- ^ @}@
-  | EqualToken               -- ^ @=@
-  | TrueToken                -- ^ @true@
-  | FalseToken               -- ^ @false@
-  | ErrorToken LexerError    -- ^ lexical error
-  | EofToken                 -- ^ end-of-file
-  deriving (Read, Show)
-
-
--- | Errors possible in the course of lexing
-data LexerError
-  = UntermString -- ^ unterminated string literal
-  | BadEscape    -- ^ invalid escape sequence
-  | NoMatch Char -- ^ no matching lexer rule
-  deriving (Read, Show)
diff --git a/src/TOML/Value.hs b/src/TOML/Value.hs
deleted file mode 100644
--- a/src/TOML/Value.hs
+++ /dev/null
@@ -1,27 +0,0 @@
-{-# OPTIONS_GHC -funbox-strict-fields #-}
-{-|
-Module      : TOML.Value
-Description : /Internal:/ Value type for TOML
-Copyright   : (c) Eric Mertens, 2017
-License     : ISC
-Maintainer  : emertens@gmail.com
--}
-
-module TOML.Value where
-
-import Data.Text (Text)
-import Data.Time (Day, LocalTime, TimeOfDay, ZonedTime)
-
--- | Values possible in a TOML file
-data Value
-  = Table      [(Text,Value)] -- ^ table, key-value pairs
-  | List       [Value]        -- ^ array
-  | Double     !Double        -- ^ floating-point literal
-  | Integer    !Integer       -- ^ integer literal
-  | String     !Text          -- ^ string literal
-  | Bool       Bool           -- ^ boolean literal
-  | ZonedTimeV !ZonedTime     -- ^ offset date-time
-  | LocalTimeV !LocalTime     -- ^ local date-time
-  | DayV       !Day           -- ^ local date
-  | TimeOfDayV !TimeOfDay     -- ^ local time
-  deriving (Read, Show)
diff --git a/src/Toml.hs b/src/Toml.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml.hs
@@ -0,0 +1,60 @@
+{-|
+Module      : Toml
+Description : TOML parser
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module parses TOML into semantically meaningful values.
+
+This parser implements TOML 1.0.0 <https://toml.io/en/v1.0.0>
+as carefully as possible.
+
+-}
+module Toml (
+
+    -- * types
+    Table,
+    Value(..),
+
+    -- * parsing
+    parse,
+
+    -- * printing
+    prettyToml,
+    DocClass(..),
+
+    -- * Serialization
+    decode,
+    encode,
+    Result(..),
+    ) where
+
+import Text.Printf (printf)
+import Toml.FromValue (FromTable (fromTable), runMatcher, Result(..))
+import Toml.Lexer (scanTokens, Token(TokError))
+import Toml.Located (Located(Located))
+import Toml.Parser (parseRawToml)
+import Toml.Position (Position(posColumn, posLine))
+import Toml.Pretty (TomlDoc, DocClass(..), prettyToken, prettyToml)
+import Toml.Semantics (semantics)
+import Toml.ToValue (ToTable (toTable))
+import Toml.Value (Table, Value(..))
+
+-- | Parse a TOML formatted 'String' or report an error message.
+parse :: String -> Either String Table
+parse str =
+    case parseRawToml (scanTokens str) of
+        Left (Located p (TokError e)) ->
+            Left (printf "%d:%d: lexical error: %s" (posLine p) (posColumn p) e)
+        Left (Located p t) ->
+            Left (printf "%d:%d: parse error: unexpected %s" (posLine p) (posColumn p) (prettyToken t))
+        Right exprs -> semantics exprs
+
+-- | Use the 'FromTable' instance to decode a value from a TOML string.
+decode :: FromTable a => String -> Result a
+decode = either Failure (runMatcher . fromTable) . parse
+
+-- | Use the 'ToTable' instance to encode a value to a TOML string.
+encode :: ToTable a => a -> TomlDoc
+encode = prettyToml . toTable
diff --git a/src/Toml/FromValue.hs b/src/Toml/FromValue.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/FromValue.hs
@@ -0,0 +1,222 @@
+{-|
+Module      : Toml.FromValue
+Description : Automation for converting TOML values to application values.
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+Use 'FromValue' to define a transformation from some 'Value' to an application
+domain type.
+
+Use 'FromTable' to define transformations specifically from 'Table'. These
+instances are interesting because all top-level TOML values are tables,
+so these are the types that work for top-level deserialization.
+
+Use 'ParseTable' to help build 'FromTable' instances. It will make it easy to
+track which table keys have been used and which are left over.
+
+Warnings can be emitted using 'warning' and 'warnTable' (depending on what)
+context you're in. These warnings can provide useful feedback about
+problematic decodings or keys that might be unused now but were perhaps
+meaningful in an old version of a configuration file.
+
+-}
+module Toml.FromValue (
+    -- * deserialization classes
+    FromValue(..),
+    FromTable(..),
+    defaultTableFromValue,
+
+    -- * matcher
+    Matcher,
+    runMatcher,
+    withScope,
+    warning,
+
+    -- * results
+    Result(..),
+
+    -- * table matching
+    ParseTable,
+    runParseTable,
+    optKey,
+    reqKey,
+    warnTable,
+
+    -- * table matching primitives
+    getTable,
+    setTable,
+    ) where
+
+import Control.Monad (zipWithM)
+import Control.Monad.Trans.Class (lift)
+import Control.Monad.Trans.State.Strict (StateT(..), evalStateT, put, get)
+import Data.Int (Int8, Int16, Int32, Int64)
+import Data.List (intercalate)
+import Data.Map (Map)
+import Data.Map qualified as Map
+import Data.String (IsString (fromString))
+import Data.Time (ZonedTime, LocalTime, Day, TimeOfDay)
+import Data.Word (Word8, Word16, Word32, Word64)
+import Numeric.Natural (Natural)
+import Toml.FromValue.Matcher (Matcher, Result(..), runMatcher, withScope, warning)
+import Toml.Pretty (prettySimpleKey, prettyValue)
+import Toml.Value (Value(..), Table)
+
+
+-- | Class for types that can be decoded from a TOML value.
+class FromValue a where
+    -- | Convert a 'Value' or report an error message
+    fromValue :: Value -> Matcher a
+
+    -- | Used to implement instance for '[]'. Most implementations rely on the default implementation.
+    listFromValue :: Value -> Matcher [a]
+    listFromValue (Array xs) = zipWithM (\i v -> withScope ("[" ++ show i ++ "]") (fromValue v)) [0::Int ..] xs
+    listFromValue v = typeError "array" v
+
+-- | Class for types that can be decoded from a TOML table.
+class FromValue a => FromTable a where
+    -- | Convert a 'Table' or report an error message
+    fromTable :: Table -> Matcher a
+
+instance (Ord k, IsString k, FromValue v) => FromTable (Map k v) where
+    fromTable t = Map.fromList <$> traverse f (Map.assocs t)
+        where
+            f (k,v) = (,) (fromString k) <$> withScope ('.':show (prettySimpleKey k)) (fromValue v)
+
+instance (Ord k, IsString k, FromValue v) => FromValue (Map k v) where
+    fromValue = defaultTableFromValue
+
+-- | Derive 'fromValue' implementation from 'fromTable'
+defaultTableFromValue :: FromTable a => Value -> Matcher a
+defaultTableFromValue (Table t) = fromTable t
+defaultTableFromValue v = typeError "table" v
+
+-- | Report a type error
+typeError :: String {- ^ expected type -} -> Value {- ^ actual value -} -> Matcher a
+typeError wanted got = fail ("Type error. wanted: " ++ wanted ++ " got: " ++ show (prettyValue got))
+
+instance FromValue Integer where
+    fromValue (Integer x) = pure x
+    fromValue v = typeError "integer" v
+
+instance FromValue Natural where
+    fromValue v =
+     do i <- fromValue v
+        if 0 <= i then
+            pure (fromInteger i)
+        else
+            fail "integer out of range for Natural"
+
+fromValueSized :: forall a. (Bounded a, Integral a) => String -> Value -> Matcher a
+fromValueSized name v =
+ do i <- fromValue v
+    if fromIntegral (minBound :: a) <= i && i <= fromIntegral (maxBound :: a) then
+        pure (fromInteger i)
+    else
+        fail ("integer out of range for " ++ name)
+
+instance FromValue Int    where fromValue = fromValueSized "Int"
+instance FromValue Int8   where fromValue = fromValueSized "Int8"
+instance FromValue Int16  where fromValue = fromValueSized "Int16"
+instance FromValue Int32  where fromValue = fromValueSized "Int32"
+instance FromValue Int64  where fromValue = fromValueSized "Int64"
+instance FromValue Word   where fromValue = fromValueSized "Word"
+instance FromValue Word8  where fromValue = fromValueSized "Word8"
+instance FromValue Word16 where fromValue = fromValueSized "Word16"
+instance FromValue Word32 where fromValue = fromValueSized "Word32"
+instance FromValue Word64 where fromValue = fromValueSized "Word64"
+
+instance FromValue Char where
+    fromValue (String [c]) = pure c
+    fromValue v = typeError "character" v
+
+    listFromValue (String xs) = pure xs
+    listFromValue v = typeError "string" v
+
+instance FromValue Double where
+    fromValue (Float x) = pure x
+    fromValue (Integer x) = pure (fromInteger x)
+    fromValue v = typeError "float" v
+
+instance FromValue Float where
+    fromValue (Float x) = pure (realToFrac x)
+    fromValue (Integer x) = pure (fromInteger x)
+    fromValue v = typeError "float" v
+
+instance FromValue Bool where
+    fromValue (Bool x) = pure x
+    fromValue v = typeError "boolean" v
+
+instance FromValue a => FromValue [a] where
+    fromValue = listFromValue
+
+instance FromValue Day where
+    fromValue (Day x) = pure x
+    fromValue v = typeError "local date" v
+
+instance FromValue TimeOfDay where
+    fromValue (TimeOfDay x) = pure x
+    fromValue v = typeError "local time" v
+
+instance FromValue ZonedTime where
+    fromValue (ZonedTime x) = pure x
+    fromValue v = typeError "offset date-time" v
+
+instance FromValue LocalTime where
+    fromValue (LocalTime x) = pure x
+    fromValue v = typeError "local date-time" v
+
+instance FromValue Value where
+    fromValue = pure
+
+-- | A 'Matcher' that tracks a current set of unmatched key-value
+-- pairs from a table.
+--
+-- Use 'optKey', 'reqKey', 'rej
+newtype ParseTable a = ParseTable (StateT Table Matcher a)
+    deriving (Functor, Applicative, Monad)
+
+instance MonadFail ParseTable where
+    fail = ParseTable . fail
+
+-- | Run a 'ParseTable' computation with a given starting 'Table'.
+-- Unused tables will generate a warning. To change this behavior
+-- 'getTable' and 'setTable' can be used to discard or generate
+-- error messages.
+runParseTable :: ParseTable a -> Table -> Matcher a
+runParseTable (ParseTable p) t =
+ do (x, t') <- runStateT p t
+    case Map.keys t' of
+        []  -> pure x
+        [k] -> x <$ warning ("Unexpected key: " ++ show (prettySimpleKey k))
+        ks  -> x <$ warning ("Unexpected keys: " ++ intercalate ", " (map (show . prettySimpleKey) ks))
+
+-- | Return the remaining portion of the table being matched.
+getTable :: ParseTable Table
+getTable = ParseTable get
+
+-- | Replace the remaining portion of the table being matched.
+setTable :: Table -> ParseTable ()
+setTable = ParseTable . put
+
+-- | Emit a warning at the current location.
+warnTable :: String -> ParseTable ()
+warnTable = ParseTable . lift . warning
+
+-- | Match a table entry by key if it exists or return 'Nothing' if not.
+optKey :: FromValue a => String -> ParseTable (Maybe a)
+optKey key = ParseTable $ StateT \t ->
+    case Map.lookup key t of
+        Nothing -> pure (Nothing, t)
+        Just v ->
+         do r <- withScope ('.' : show (prettySimpleKey key)) (fromValue v)
+            pure (Just r, Map.delete key t)
+
+-- | Match a table entry by key or report an error if missing.
+reqKey :: FromValue a => String -> ParseTable a
+reqKey key =
+ do mb <- optKey key
+    case mb of
+        Nothing -> fail ("Missing key: " ++ show (prettySimpleKey key))
+        Just v -> pure v
diff --git a/src/Toml/FromValue/Matcher.hs b/src/Toml/FromValue/Matcher.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/FromValue/Matcher.hs
@@ -0,0 +1,66 @@
+{-|
+Module      : Toml.FromValue.Matcher
+Description : A type for building results while tracking scopes
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+-}
+module Toml.FromValue.Matcher ( 
+    Matcher,
+    runMatcher,
+    withScope,
+    getScope,
+    warning,
+
+    Result(..),
+    ) where
+
+import Control.Applicative (Alternative(..))
+import Control.Monad (MonadPlus(..))
+import Control.Monad.Trans.Class (lift)
+import Control.Monad.Trans.Reader (asks, local, ReaderT(..))
+import Control.Monad.Trans.Writer.CPS (runWriterT, tell, WriterT)
+
+-- | Computations that result in a 'Result' and which track a list
+-- of nested contexts to assist in generating warnings and error
+-- messages.
+--
+-- Use 'withScope' to run a 'Matcher' in a new, nested scope.
+newtype Matcher a = Matcher (ReaderT [String] (WriterT (DList String) (Either String)) a)
+    deriving (Functor, Applicative, Monad)
+
+type DList a = [a] -> [a]
+
+-- | Computation outcome with error and warning messages.
+data Result a
+    = Failure String -- error message
+    | Success [String] a -- warnings and result
+    deriving (Read, Show, Eq, Ord)
+
+-- | Run a 'Matcher' with an empty scope.
+runMatcher :: Matcher a -> Result a
+runMatcher (Matcher m) =
+    case runWriterT (runReaderT m []) of
+        Left e -> Failure e
+        Right (x,w) -> Success (w []) x
+
+-- | Run a 'Matcher' with a locally extended scope.
+withScope :: String -> Matcher a -> Matcher a
+withScope ctx (Matcher m) = Matcher (local (ctx:) m)
+
+-- | Get the current list of scopes.
+getScope :: Matcher [String]
+getScope = Matcher (asks reverse)
+
+-- | Emit a warning mentioning the current scope.
+warning :: String -> Matcher ()
+warning w =
+ do loc <- getScope
+    Matcher (lift (tell ((w ++ " in top" ++ concat loc):)))
+
+-- | Fail with an error message annotated to the current location.
+instance MonadFail Matcher where
+    fail e =
+     do loc <- getScope
+        Matcher (lift (lift (Left (e ++ " in top" ++ concat loc))))
diff --git a/src/Toml/Lexer.x b/src/Toml/Lexer.x
new file mode 100644
--- /dev/null
+++ b/src/Toml/Lexer.x
@@ -0,0 +1,190 @@
+{
+{-|
+Module      : Toml.Lexer
+Description : TOML lexical analyzer
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module parses a TOML file into a lazy sequence
+of tokens. The lexer is aware of nested brackets and
+equals signs in order to handle TOML's context-sensitive
+lexing requirements. This context enables the lexer to
+distinguish between bare keys and various values like:
+floating-point literals, integer literals, and date literals.
+
+This module uses actions and lexical hooks defined in
+"LexerUtils".
+
+-}
+module Toml.Lexer (scanTokens, lexValue, Token(..)) where
+
+import Control.Monad.Trans.State.Strict (runState)
+import Toml.Lexer.Token
+import Toml.Lexer.Utils
+import Toml.Located
+import Toml.Position
+
+}
+$non_ascii        = \x1
+$wschar           = [\ \t]
+
+@ws               = $wschar*
+@newline          = \r? \n
+
+$bindig           = [0-1]
+$octdig           = [0-7]
+$digit            = [0-9]
+$hexdig           = [ $digit A-F a-f ]
+$basic_unescaped  = [ $wschar \x21 \x23-\x5B \x5D-\x7E $non_ascii ]
+$comment_start_symbol = \#
+
+@barekey = [0-9 A-Z a-z \- _]+
+
+@escape_seq_char  = [\x22 \x5C \x62 \x66 \x6E \x72 \x74] | "u" $hexdig{4}
+                  | "U0010" $hexdig{4}
+                  | "U000"  $hexdig{5}
+@escaped          = \\ @escape_seq_char
+@basic_char       = $basic_unescaped | @escaped
+
+@unsigned_dec_int = $digit | [1-9] ($digit | _ $digit)+
+@dec_int = [\-\+]? @unsigned_dec_int
+@zero_prefixable_int = $digit ($digit | _ $digit)*
+@hex_int = "0x" $hexdig ($hexdig | _ $hexdig)*
+@oct_int = "0o" $octdig ($octdig | _ $octdig)*
+@bin_int = "0b" $bindig ($bindig | _ $bindig)*
+
+@frac = "." @zero_prefixable_int
+@float_exp_part = [\+\-]? @zero_prefixable_int
+@special_float = [\+\-]? ("inf" | "nan")
+@exp = [Ee] @float_exp_part
+@float_int_part = @dec_int
+@float = @float_int_part ( @exp | @frac @exp? ) | @special_float
+
+$non_eol = [\x09 \x20-\x7E $non_ascii]
+@comment = $comment_start_symbol $non_eol*
+
+$literal_char = [ \x09 \x20-\x26 \x28-\x7E $non_ascii ]
+@basic_string = \" @basic_char* \"
+@literal_string = "'" $literal_char* "'"
+
+@ml_literal_string_delim = "'''"
+$mll_char = [\x09 \x20-\x26 \x28-\x7E]
+@mll_quotes = "'" "'"?
+@mll_content = $mll_char | @newline
+@ml_literal_body = @mll_content* (@mll_quotes @mll_content+)* @mll_quotes?
+@ml_literal_string = @ml_literal_string_delim @newline? @ml_literal_body @ml_literal_string_delim
+
+@ml_basic_string_delim = \" \" \"
+@mlb_quotes = \" \"?
+@mlb_escaped_nl = \\ @ws @newline ($wschar | @newline)*
+$mlb_unescaped = [$wschar \x21 \x23-\x5B \x5D-\x7E $non_ascii]
+@mlb_char = $mlb_unescaped | @escaped
+@mlb_content = @mlb_char | @newline | @mlb_escaped_nl
+@ml_basic_body = @mlb_content* (@mlb_quotes @mlb_content+)* @mlb_quotes?
+@ml_basic_string = @ml_basic_string_delim @newline? @ml_basic_body @ml_basic_string_delim
+
+@date_fullyear = $digit {4}
+@date_month = $digit {2}
+@date_mday = $digit {2}
+$time_delim = [Tt\ ]
+@time_hour = $digit {2}
+@time_minute = $digit {2}
+@time_second = $digit {2}
+@time_secfrac = "." $digit+
+@time_numoffset = [\+\-] @time_hour ":" @time_minute
+@time_offset = [Zz] | @time_numoffset
+
+@partial_time = @time_hour ":" @time_minute ":" @time_second @time_secfrac?
+@full_date = @date_fullyear "-" @date_month "-" @date_mday
+@full_time = @partial_time @time_offset
+
+@offset_date_time = @full_date $time_delim @full_time
+@local_date_time = @full_date $time_delim @partial_time
+@local_date = @full_date
+@local_time = @partial_time
+
+toml :-
+
+<val> {
+
+"["                 { enterList                         }
+"]"                 { exitList                          }
+"{"                 { enterTable                        }
+@dec_int            { value mkDecInteger                }
+@hex_int            { value mkHexInteger                }
+@oct_int            { value mkOctInteger                }
+@bin_int            { value mkBinInteger                }
+@float              { value mkFloat                     }
+"true"              { value_ TokTrue                    }
+"false"             { value_ TokFalse                   }
+
+@offset_date_time   { timeValue "offset date-time" offsetDateTimePatterns TokOffsetDateTime }
+@local_date         { timeValue "local date"       localDatePatterns      TokLocalDate      }
+@local_date_time    { timeValue "local date-time"  localDateTimePatterns  TokLocalDateTime  }
+@local_time         { timeValue "local time"       localTimePatterns      TokLocalTime      }
+
+}
+
+<0> {
+"[["                { token_ Tok2SquareO                }
+"]]"                { token_ Tok2SquareC                }
+}
+
+@newline            { token_ TokNewline                 }
+@comment;
+$wschar+;
+
+@basic_string       { value mkBasicString               }
+@literal_string     { value mkLiteralString             }
+
+@ml_literal_string  { value mkMlLiteralString           }
+@ml_basic_string    { value mkMlBasicString             }
+
+"}"                 { exitTable                         }
+"="                 { equals                            }
+"."                 { token_ TokPeriod                  }
+","                 { token_ TokComma                   }
+
+"["                 { token_ TokSquareO                 }
+"]"                 { token_ TokSquareC                 }
+"{"                 { token_ TokCurlyO                  }
+
+@barekey            { token  TokBareKey                 }
+
+{
+
+-- | Generate a lazy-list of tokens from the input string.
+-- The token stream is guaranteed to be terminated either with
+-- 'TokEOF' or 'TokError'.
+scanTokens :: String -> [Located Token]
+scanTokens str = scanTokens' [] Located { locPosition = startPos, locThing = str }
+
+scanTokens' :: [Context] -> AlexInput -> [Located Token]
+scanTokens' st str =
+  case alexScan str (stateInt st) of
+    AlexEOF          -> [TokEOF <$ str]
+    AlexError str'   -> [mkError <$> str']
+    AlexSkip  str' _ -> scanTokens' st str'
+    AlexToken str' n action ->
+      case runState (traverse (action . take n) str) st of
+        (t, st') -> t : scanTokens' st' str'
+
+stateInt :: [Context] -> Int
+stateInt (ValueContext : _) = val
+stateInt (ListContext  : _) = val
+stateInt _                  = 0
+
+-- | Lex a single token in a value context. This is mostly useful for testing.
+lexValue :: String -> Token
+lexValue str = lexValue_ Located { locPosition = startPos, locThing = str } 
+
+lexValue_ :: Located String -> Token
+lexValue_ str =
+  case alexScan str val of
+    AlexEOF              -> TokError "end of input"
+    AlexError{}          -> TokError "lexer error"
+    AlexSkip str' _      -> lexValue_ str'
+    AlexToken _ n action -> fst (runState (action (take n (locThing str))) [ValueContext])
+
+}
diff --git a/src/Toml/Lexer/Token.hs b/src/Toml/Lexer/Token.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/Lexer/Token.hs
@@ -0,0 +1,198 @@
+{-|
+Module      : Toml.Lexer.Token
+Description : Lexical tokens
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module provides the datatype for the lexical
+syntax of TOML files. These tokens will drive the
+parser in the "Parser" module.
+
+-}
+module Toml.Lexer.Token (
+    Token(..),
+    
+    mkBasicString,
+    mkLiteralString,
+    mkMlBasicString,
+    mkMlLiteralString,
+    
+    -- * integer literals
+    mkBinInteger,
+    mkDecInteger,
+    mkOctInteger,
+    mkHexInteger,
+
+    -- * float literals
+    mkFloat,
+
+    -- * date and time patterns
+    localDatePatterns,
+    localTimePatterns,
+    localDateTimePatterns,
+    offsetDateTimePatterns,
+
+    -- * errors
+    mkError,
+    ) where
+
+import Data.Char (chr, isSpace)
+import Data.Time (Day, LocalTime, TimeOfDay, ZonedTime)
+import Numeric (readBin, readHex, readOct)
+
+-- | Lexical token
+data Token
+    = TokTrue                       -- ^ @true@
+    | TokFalse                      -- ^ @false@
+    | TokComma                      -- ^ @','@
+    | TokEquals                     -- ^ @'='@
+    | TokNewline                    -- ^ @'\\n'@
+    | TokPeriod                     -- ^ @'.'@
+    | TokSquareO                    -- ^ @'['@
+    | TokSquareC                    -- ^ @']'@
+    | Tok2SquareO                   -- ^ @'[['@
+    | Tok2SquareC                   -- ^ @']]'@
+    | TokCurlyO                     -- ^ @'{'@
+    | TokCurlyC                     -- ^ @'}'@
+    | TokBareKey String             -- ^ bare key
+    | TokString String              -- ^ string literal
+    | TokMlString String            -- ^ multiline string literal
+    | TokInteger !Integer           -- ^ integer literal
+    | TokFloat !Double              -- ^ floating-point literal
+    | TokOffsetDateTime !ZonedTime  -- ^ date-time with timezone offset
+    | TokLocalDateTime !LocalTime   -- ^ local date-time
+    | TokLocalDate !Day             -- ^ local date
+    | TokLocalTime !TimeOfDay       -- ^ local time
+    | TokError String               -- ^ lexical error
+    | TokEOF                        -- ^ end of file
+    deriving (Read, Show)
+
+-- | Remove underscores from number literals
+scrub :: String -> String
+scrub = filter ('_' /=)
+
+-- | Construct a 'TokInteger' from a decimal integer literal lexeme.
+mkDecInteger :: String -> Token
+mkDecInteger ('+':xs) = TokInteger (read (scrub xs))
+mkDecInteger xs = TokInteger (read (scrub xs))
+
+-- | Construct a 'TokInteger' from a hexadecimal integer literal lexeme.
+mkHexInteger :: String -> Token
+mkHexInteger ('0':'x':xs) = TokInteger (fst (head (readHex (scrub xs))))
+mkHexInteger _ = error "processHex: bad input"
+
+-- | Construct a 'TokInteger' from a octal integer literal lexeme.
+mkOctInteger :: String -> Token
+mkOctInteger ('0':'o':xs) = TokInteger (fst (head (readOct (scrub xs))))
+mkOctInteger _ = error "processHex: bad input"
+
+-- | Construct a 'TokInteger' from a binary integer literal lexeme.
+mkBinInteger :: String -> Token
+mkBinInteger ('0':'b':xs) = TokInteger (fst (head (readBin (scrub xs))))
+mkBinInteger _ = error "processHex: bad input"
+
+-- | Construct a 'TokFloat' from a floating-point literal lexeme.
+mkFloat :: String -> Token
+mkFloat "nan"   = TokFloat (0/0)
+mkFloat "+nan"  = TokFloat (0/0)
+mkFloat "-nan"  = TokFloat (0/0)
+mkFloat "inf"   = TokFloat (1/0)
+mkFloat "+inf"  = TokFloat (1/0)
+mkFloat "-inf"  = TokFloat (-1/0)
+mkFloat ('+':x) = TokFloat (read (scrub x))
+mkFloat x       = TokFloat (read (scrub x))
+
+-- | Construct a 'TokString' from a literal string lexeme.
+mkLiteralString :: String -> Token
+mkLiteralString = TokString . tail . init
+
+-- | Construct a 'TokString' from a basic string lexeme.
+mkBasicString :: String -> Token
+mkBasicString "" = error "processBasic: missing initializer"
+mkBasicString (_:start) = enforceScalar TokString (go start)
+    where
+        go [] = error "processBasic: missing terminator"
+        go "\"" = ""
+        go ('\\':'"':xs) = '"' : go xs
+        go ('\\':'\\':xs) = '\\' : go xs
+        go ('\\':'b':xs) = '\b' : go xs
+        go ('\\':'f':xs) = '\f' : go xs
+        go ('\\':'n':xs) = '\n' : go xs
+        go ('\\':'r':xs) = '\r' : go xs
+        go ('\\':'t':xs) = '\t' : go xs
+        go ('\\':'u':a:b:c:d:xs) = chr (fst (head (readHex [a,b,c,d]))) : go xs
+        go ('\\':'U':a:b:c:d:e:f:g:h:xs) = chr (fst (head (readHex [a,b,c,d,e,f,g,h]))) : go xs
+        go (x:xs) = x : go xs
+
+-- | Construct a 'TokMlString' from a basic multi-line string lexeme.
+mkMlBasicString :: String -> Token
+mkMlBasicString str =
+    enforceScalar TokMlString
+    case str of
+        '"':'"':'"':'\r':'\n':start -> go start
+        '"':'"':'"':'\n':start -> go start
+        '"':'"':'"':start -> go start
+        _ -> error "processMlBasic: missing initializer"
+    where
+      go "\"\"\"" = ""
+      go ('\\':'"':xs) = '"' : go xs
+      go ('\\':'\\':xs) = '\\' : go xs
+      go ('\\':'b':xs) = '\b' : go xs
+      go ('\\':'f':xs) = '\f' : go xs
+      go ('\\':'n':xs) = '\n' : go xs
+      go ('\\':'r':xs) = '\r' : go xs
+      go ('\\':'t':xs) = '\t' : go xs
+      go ('\\':'u':a:b:c:d:xs) = chr (fst (head (readHex [a,b,c,d]))) : go xs
+      go ('\\':'U':a:b:c:d:e:f:g:h:xs) = chr (fst (head (readHex [a,b,c,d,e,f,g,h]))) : go xs
+      go ('\\':'\r':xs) = go (dropWhile isSpace xs)
+      go ('\\':'\n':xs) = go (dropWhile isSpace xs)
+      go ('\\':' ':xs)  = go (dropWhile isSpace xs)
+      go ('\\':'\t':xs) = go (dropWhile isSpace xs)
+      go (x:xs) = x : go xs
+      go [] = error "processMlBasic: missing terminator"
+
+-- | Construct a 'TokMlString' from a literal multi-line string lexeme.
+mkMlLiteralString :: String -> Token
+mkMlLiteralString str =
+    TokMlString
+    case str of
+        '\'':'\'':'\'':'\r':'\n':start -> go start
+        '\'':'\'':'\'':'\n':start -> go start
+        '\'':'\'':'\'':start -> go start
+        _ -> error "processMlLiteral: mising initializer"
+    where
+        go "'''" = ""
+        go (x:xs) = x : go xs
+        go "" = error "processMlLiteral: missing terminator"
+
+enforceScalar :: (String -> Token) -> String -> Token
+enforceScalar f str
+    | any isInvalid str = TokError "string literal controls non-scalar value"
+    | otherwise = f str
+    where
+        isInvalid x = '\xd800' <= x && x < '\xe000'
+
+-- | Make a 'TokError' from a lexical error message.
+mkError :: String -> Token
+mkError str = TokError ("Lexical error: " ++ show (head str))
+
+-- | Format strings for local date lexemes.
+localDatePatterns :: [String]
+localDatePatterns = ["%Y-%m-%d"]
+
+-- | Format strings for local time lexemes.
+localTimePatterns :: [String]
+localTimePatterns = ["%H:%M:%S%Q"]
+
+-- | Format strings for local datetime lexemes.
+localDateTimePatterns :: [String]
+localDateTimePatterns =
+    ["%Y-%m-%dT%H:%M:%S%Q",
+    "%Y-%m-%d %H:%M:%S%Q"]
+
+-- | Format strings for offset datetime lexemes.
+offsetDateTimePatterns :: [String]
+offsetDateTimePatterns =
+    ["%Y-%m-%dT%H:%M:%S%Q%Ez","%Y-%m-%dT%H:%M:%S%QZ",
+    "%Y-%m-%d %H:%M:%S%Q%Ez","%Y-%m-%d %H:%M:%S%QZ"]
diff --git a/src/Toml/Lexer/Utils.hs b/src/Toml/Lexer/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/Lexer/Utils.hs
@@ -0,0 +1,117 @@
+{-|
+Module      : Toml.Lexer.Utils
+Description : Wrapper and actions for generated lexer
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module provides a custom engine for the Alex generated
+lexer. This lexer drive provides nested states, unicode support,
+and file location tracking.
+
+-}
+module Toml.Lexer.Utils (
+    
+    -- * Types
+    M, Action,
+    Context(..),
+
+    -- * Actions
+    value,
+    value_,
+    token,
+    token_,
+    enterList,
+    exitList,
+    enterTable,
+    exitTable,
+    equals,
+    timeValue,
+
+    -- * Alex extension points
+    AlexInput,
+    alexGetByte,
+
+    ) where
+
+import Control.Monad.Trans.State.Strict (State, modify, state)
+import Data.Char (ord, isAscii)
+import Data.Foldable (asum)
+import Data.Time.Format (parseTimeM, defaultTimeLocale, ParseTime)
+
+import Toml.Located (Located(..))
+import Toml.Position (move)
+import Toml.Lexer.Token (Token(..))
+
+type M a = State [Context] a
+
+type Action = String -> M Token
+
+data Context
+  = ListContext  -- ^ processing an inline list, lex values
+  | TableContext -- ^ processing an inline table, don't lex values
+  | ValueContext -- ^ processing after an equals, lex one value
+  deriving Show
+
+pushContext :: Context -> M ()
+pushContext cxt = modify \st ->
+  case st of
+    ValueContext : st' -> cxt : st'
+    _                  -> cxt : st
+
+equals :: Action
+equals _ = TokEquals <$ pushContext ValueContext
+
+enterList :: Action
+enterList _ = TokSquareO <$ pushContext ListContext
+
+enterTable :: Action
+enterTable _ = TokCurlyO <$ pushContext TableContext
+
+exitTable :: Action
+exitTable _ = state \case
+  TableContext : st -> (TokCurlyC             , st)
+  st                -> (TokError "Unmatched }", st)
+
+exitList :: Action
+exitList _ = state \case
+  ListContext : st -> (TokSquareC            , st)
+  []               -> (TokSquareC            , [])
+  st               -> (TokError "Unmatched ]", st)
+
+token_ :: Token -> Action
+token_ t _ = pure t
+
+token :: (String -> Token) -> Action
+token f x = pure (f x)
+
+value_ :: Token -> Action
+value_ t _ = emitValue t
+
+value :: (String -> Token) -> Action
+value f x = emitValue (f x)
+
+emitValue :: a -> M a
+emitValue v = state \st ->
+  case st of
+    ValueContext:st' -> (v, st')
+    _                -> (v, st )
+
+timeValue :: ParseTime a => String -> [String] -> (a -> Token) -> Action
+timeValue description patterns constructor = value \str ->
+  case asum [parseTimeM False defaultTimeLocale pattern str | pattern <- patterns] of
+    Nothing -> TokError ("Malformed " ++ description)
+    Just t  -> constructor t
+
+type AlexInput = Located String
+
+alexGetByte :: AlexInput -> Maybe (Int, AlexInput)
+alexGetByte Located { locPosition = p, locThing = str } =
+  case str of
+    "" -> Nothing
+    x:xs
+      | x == '\1' -> Just (0,     rest)
+      | isAscii x -> Just (ord x, rest)
+      | otherwise -> Just (1,     rest)
+      where
+        rest = Located { locPosition = move x p, locThing = xs }
diff --git a/src/Toml/Located.hs b/src/Toml/Located.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/Located.hs
@@ -0,0 +1,23 @@
+{-|
+Module      : Toml.Located
+Description : Values annotated with positions
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module provides a simple tuple for tracking pairs of
+values and their file locations.
+
+-}
+module Toml.Located (
+    Located(..)
+    ) where
+
+import Toml.Position (Position)
+
+-- | A value annotated with its text file position
+data Located a = Located
+    { locPosition :: {-# UNPACK #-} !Position
+    , locThing    :: !a
+    }
+    deriving (Read, Show, Functor, Foldable, Traversable)
diff --git a/src/Toml/Parser.y b/src/Toml/Parser.y
new file mode 100644
--- /dev/null
+++ b/src/Toml/Parser.y
@@ -0,0 +1,138 @@
+{
+{-|
+Module      : Toml.Parser
+Description : Raw TOML expression parser
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module parses TOML tokens into a list of raw,
+uninterpreted sections and assignments.
+
+-}
+module Toml.Parser (
+  -- * types
+  Expr(..),
+  SectionKind(..),
+  Val(..),
+  Key,
+
+  -- * parser
+  parseRawToml,
+  ) where
+
+import Data.List.NonEmpty (NonEmpty)
+import Data.List.NonEmpty qualified as NonEmpty
+import Data.Time (Day, TimeOfDay, LocalTime, ZonedTime)
+
+import Toml.Located (Located(Located, locPosition, locThing))
+import Toml.Position (posLine)
+import Toml.Parser.Types
+import Toml.Lexer (Token(..))
+
+}
+
+%tokentype      { Located Token                     }
+%token
+'true'          { Located _ TokTrue                 }
+'false'         { Located _ TokFalse                }
+','             { Located _ TokComma                }
+'='             { Located _ TokEquals               }
+NEWLINE         { Located _ TokNewline              }
+'.'             { Located _ TokPeriod               }
+'['             { Located _ TokSquareO              }
+']'             { Located _ TokSquareC              }
+'[['            { Located _ Tok2SquareO             }
+']]'            { Located _ Tok2SquareC             }
+'{'             { Located _ TokCurlyO               }
+'}'             { Located _ TokCurlyC               }
+BAREKEY         { Located _ (TokBareKey        _ )  }
+STRING          { Located _ (TokString         _ )  }
+MLSTRING        { Located _ (TokMlString       $$)  }
+INTEGER         { Located _ (TokInteger        $$)  }
+FLOAT           { Located _ (TokFloat          $$)  }
+OFFSETDATETIME  { Located _ (TokOffsetDateTime $$)  }
+LOCALDATETIME   { Located _ (TokLocalDateTime  $$)  }
+LOCALDATE       { Located _ (TokLocalDate      $$)  }
+LOCALTIME       { Located _ (TokLocalTime      $$)  }
+EOF             { Located _ TokEOF                  }
+
+%monad          { Either (Located Token)            }
+%error          { errorP                            }
+
+%name parseRawToml toml
+
+%%
+
+toml ::                             { [Expr]    }
+  : sepBy1(expression, NEWLINE) EOF { concat $1 }
+
+expression ::       { [Expr]                  }
+  :                 { []                      }
+  | keyval          { [KeyValExpr (fst $1) (snd $1)] }
+  | '['  key ']'    { [TableExpr      $2    ] }
+  | '[[' key ']]'   { [ArrayTableExpr $2    ] }
+
+keyval ::           { (Key, Val)              }
+  : key '=' val     { ($1,$3)                 }
+
+key ::              { Key                     }
+  : sepBy1(simplekey, '.') { $1               }
+
+simplekey ::        { Located String          }
+  : BAREKEY         { fmap asString $1        }
+  | STRING          { fmap asString $1        }
+
+val ::              { Val                     }
+  : INTEGER         { ValInteger    $1        }
+  | FLOAT           { ValFloat      $1        }
+  | 'true'          { ValBool       True      }
+  | 'false'         { ValBool       False     }
+  | STRING          { ValString (asString (locThing $1)) }
+  | MLSTRING        { ValString     $1        }
+  | LOCALDATE       { ValDay        $1        }
+  | LOCALTIME       { ValTimeOfDay  $1        }
+  | OFFSETDATETIME  { ValZonedTime  $1        }
+  | LOCALDATETIME   { ValLocalTime  $1        }
+  | array           { ValArray      $1        }
+  | inlinetable     { ValTable      $1        }
+
+inlinetable ::                  { [(Key, Val)]      }
+  : '{' sepBy(keyval, ',') '}'  { $2                }
+
+array ::                                      { [Val]       }
+  : '[' newlines                          ']' { []          }
+  | '[' newlines arrayvalues              ']' { reverse $3  }
+  | '[' newlines arrayvalues ',' newlines ']' { reverse $3  }
+
+arrayvalues ::                            { [Val]       }
+  :                          val newlines { [$1]        }
+  | arrayvalues ',' newlines val newlines { $4 : $1     }
+
+newlines ::          {}
+  :                  {}
+  | newlines NEWLINE {}
+
+sepBy(p,q) ::         { [p]                   }
+  :                   { []                    }
+  | sepBy1(p,q)       { NonEmpty.toList $1    }
+
+sepBy1(p,q) ::        { NonEmpty p            }
+  : sepBy1_(p,q)      { NonEmpty.reverse $1   }
+
+sepBy1_(p,q) ::       { NonEmpty p            }
+  :                p  { NonEmpty.singleton $1 }
+  | sepBy1_(p,q) q p  { NonEmpty.cons $3 $1   }
+
+{
+
+errorP :: [Located Token] -> Either (Located Token) a
+errorP (t:_) = Left t
+errorP []    = error "Parser.errorP: unterminated token stream"
+
+asString :: Token -> String
+asString (TokString x) = x
+asString (TokBareKey x) = x
+asString _ = error "simpleKeyLexeme: panic"
+
+}
diff --git a/src/Toml/Parser/Types.hs b/src/Toml/Parser/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/Parser/Types.hs
@@ -0,0 +1,57 @@
+{-|
+Module      : Toml.Raw
+Description : Raw expressions from a parsed TOML file
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module provides a raw representation of TOML files as
+a list of table definitions and key-value assignments.
+
+These values use the raw dotted keys and have no detection
+for overlapping assignments.
+
+Further processing will happen in the "Semantics" module.
+
+-}
+module Toml.Parser.Types (
+    Key,
+    Expr(..),
+    Val(..),
+    SectionKind(..),
+    ) where
+
+import Data.List.NonEmpty (NonEmpty)
+import Data.Time (Day, LocalTime, TimeOfDay, ZonedTime)
+import Toml.Located (Located)
+
+-- | Non-empty sequence of dotted simple keys
+type Key = NonEmpty (Located String)
+
+-- | Headers and assignments corresponding to lines of a TOML file
+data Expr
+    = KeyValExpr     Key Val -- ^ key value assignment: @key = value@
+    | TableExpr      Key     -- ^ table: @[key]@
+    | ArrayTableExpr Key     -- ^ array of tables: @[[key]]@
+    deriving (Read, Show)
+
+-- | Unvalidated TOML values. Table are represented as a list of
+-- assignments rather than as resolved maps.
+data Val
+    = ValInteger   Integer
+    | ValFloat     Double
+    | ValArray     [Val]
+    | ValTable     [(Key, Val)]
+    | ValBool      Bool
+    | ValString    String
+    | ValTimeOfDay TimeOfDay
+    | ValZonedTime ZonedTime
+    | ValLocalTime LocalTime
+    | ValDay       Day
+    deriving (Read, Show)
+
+-- | Kinds of table headers.
+data SectionKind
+    = TableKind -- ^ [table]
+    | ArrayTableKind -- ^ [[array of tables]]
+    deriving (Read, Show, Eq)
diff --git a/src/Toml/Position.hs b/src/Toml/Position.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/Position.hs
@@ -0,0 +1,36 @@
+{-|
+Module      : Toml.Position
+Description : File position representation
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module provides the 'Position' type for tracking locations
+in files while doing lexing and parsing for providing more useful
+error messages.
+
+-}
+module Toml.Position (
+    Position(..),
+    startPos,
+    move,
+    ) where
+
+-- | A position in a text file
+data Position = Position
+    { posIndex, posLine, posColumn :: {-# UNPACK #-} !Int }
+    deriving (Read, Show, Ord, Eq)
+
+-- | The initial 'Position' for the start of a file
+startPos :: Position
+startPos = Position { posIndex = 0, posLine = 1, posColumn = 1 }
+
+-- | Adjust a file position given a single character handling
+-- newlines and tabs. All other characters are considered to fill
+-- exactly one column.
+move :: Char -> Position -> Position
+move x Position{ posIndex = i, posLine = l, posColumn = c} =
+    case x of
+        '\n' -> Position{ posIndex = i+1, posLine = l+1, posColumn = 1 }
+        '\t' -> Position{ posIndex = i+1, posLine = l, posColumn = (c + 7) `quot` 8 * 8 + 1 }
+        _    -> Position{ posIndex = i+1, posLine = l, posColumn = c+1 }
diff --git a/src/Toml/Pretty.hs b/src/Toml/Pretty.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/Pretty.hs
@@ -0,0 +1,204 @@
+{-# Language OverloadedStrings #-}
+{-|
+Module      : Toml.Pretty
+Description : Human-readable representations for error messages
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module provides human-readable renderers for types used
+in this package to assist error message production.
+
+-}
+module Toml.Pretty (
+    -- * Types
+    TomlDoc,
+    DocClass(..),
+
+    -- * semantic values
+    prettyToml,
+    prettyValue,
+
+    -- * syntactic components
+    prettyToken,
+    prettySectionKind,
+
+    -- * keys
+    prettySimpleKey,
+    prettyKey,
+    ) where
+
+import Data.Char (ord, isAsciiLower, isAsciiUpper, isDigit, isPrint)
+import Data.Foldable (fold)
+import Data.List (partition)
+import Data.List.NonEmpty (NonEmpty)
+import Data.List.NonEmpty qualified as NonEmpty
+import Data.Map qualified as Map
+import Data.String (fromString)
+import Data.Time (ZonedTime(zonedTimeZone), TimeZone (timeZoneMinutes))
+import Data.Time.Format (formatTime, defaultTimeLocale)
+import Prettyprinter
+import Text.Printf (printf)
+import Toml.Parser (SectionKind(..))
+import Toml.Lexer (Token(..))
+import Toml.Value (Value(..), Table)
+
+-- | Annotation used to enable styling pretty-printed TOML
+data DocClass
+    = TableClass  -- ^ top-level @[key]@ and @[[key]]@
+    | KeyClass    -- ^ dotted keys, left-hand side of assignments
+    | StringClass -- ^ string literals
+    | NumberClass -- ^ number literals
+    | DateClass   -- ^ date and time literals
+    | BoolClass   -- ^ boolean literals
+    deriving (Read, Show, Eq, Ord)
+
+-- | Pretty-printer document with TOML class attributes to aid
+-- in syntax-highlighting.
+type TomlDoc = Doc DocClass
+
+-- | Renders a dotted-key using quotes where necessary and annotated
+-- as a 'KeyClass'.
+prettyKey :: NonEmpty String -> TomlDoc
+prettyKey = annotate KeyClass . fold . NonEmpty.intersperse dot . fmap prettySimpleKey
+
+-- | Renders a simple-key using quotes where necessary.
+prettySimpleKey :: String -> Doc a
+prettySimpleKey str
+    | not (null str), all isBareKey str = fromString str
+    | otherwise                         = fromString (quoteString str)
+
+-- | Predicate for the character-class that is allowed in bare keys
+isBareKey :: Char -> Bool
+isBareKey x = isAsciiLower x || isAsciiUpper x || isDigit x || x == '-' || x == '_'
+
+-- | Quote a string using basic string literal syntax.
+quoteString :: String -> String
+quoteString = ('"':) . go
+    where
+        go = \case
+            ""        -> "\"" -- terminator
+            '"'  : xs -> '\\' : '"'  : go xs
+            '\\' : xs -> '\\' : '\\' : go xs
+            '\b' : xs -> '\\' : 'b'  : go xs
+            '\f' : xs -> '\\' : 'f'  : go xs
+            '\n' : xs -> '\\' : 'n'  : go xs
+            '\r' : xs -> '\\' : 'r'  : go xs
+            '\t' : xs -> '\\' : 't'  : go xs
+            x    : xs
+                | isPrint x     -> x : go xs
+                | x <= '\xffff' -> printf "\\u%04X%s" (ord x) (go xs)
+                | otherwise     -> printf "\\U%08X%s" (ord x) (go xs)
+
+-- | Pretty-print a section heading. The result is annotated as a 'TableClass'.
+prettySectionKind :: SectionKind -> NonEmpty String -> TomlDoc
+prettySectionKind TableKind      key =
+    annotate TableClass (unAnnotate (lbracket <> prettyKey key <> rbracket))
+prettySectionKind ArrayTableKind key =
+    annotate TableClass (unAnnotate (lbracket <> lbracket <> prettyKey key <> rbracket <> rbracket))
+
+-- | Render token for human-readable error messages.
+prettyToken :: Token -> String
+prettyToken = \case
+    TokComma            -> "','"
+    TokEquals           -> "'='"
+    TokPeriod           -> "'.'"
+    TokSquareO          -> "'['"
+    TokSquareC          -> "']'"
+    Tok2SquareO         -> "'[['"
+    Tok2SquareC         -> "']]'"
+    TokCurlyO           -> "'{'"
+    TokCurlyC           -> "'}'"
+    TokNewline          -> "newline"
+    TokBareKey        _ -> "bare key"
+    TokTrue             -> "true literal"
+    TokFalse            -> "false literal"
+    TokString         _ -> "string"
+    TokMlString       _ -> "multi-line string"
+    TokInteger        _ -> "integer"
+    TokFloat          _ -> "float"
+    TokOffsetDateTime _ -> "offset date-time"
+    TokLocalDateTime  _ -> "local date-time"
+    TokLocalDate      _ -> "local date"
+    TokLocalTime      _ -> "local time"
+    TokError          e -> "lexical error: " ++ e
+    TokEOF              -> "end-of-input"
+
+prettyAssignment :: String -> Value -> TomlDoc
+prettyAssignment = go . NonEmpty.singleton
+    where
+        go ks (Table (Map.assocs -> [(k,v)])) = go (NonEmpty.cons k ks) v
+        go ks v = prettyKey (NonEmpty.reverse ks) <+> equals <+> prettyValue v
+
+-- | Render a value suitable for assignment on the right-hand side
+-- of an equals sign. This value will always occupy a single line.
+prettyValue :: Value -> TomlDoc
+prettyValue = \case
+    Integer i       -> annotate NumberClass (pretty i)
+    Float   f
+        | isNaN f      -> annotate NumberClass "nan"
+        | isInfinite f -> annotate NumberClass (if f > 0 then "inf" else "-inf")
+        | otherwise    -> annotate NumberClass (pretty f)
+    Array a         -> align (list [prettyValue v | v <- a])
+    Table t         -> lbrace <> concatWith (surround ", ") [prettyAssignment k v | (k,v) <- Map.assocs t] <> rbrace
+    Bool True       -> annotate BoolClass "true"
+    Bool False      -> annotate BoolClass "false"
+    String str      -> annotate StringClass (fromString (quoteString str))
+    TimeOfDay tod   -> annotate DateClass (fromString (formatTime defaultTimeLocale "%H:%M:%S%Q" tod))
+    ZonedTime zt
+      | timeZoneMinutes (zonedTimeZone zt) == 0 ->
+                          annotate DateClass (fromString (formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S%QZ" zt))
+      | otherwise      -> annotate DateClass (fromString (formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S%Q%Ez" zt))
+    LocalTime lt    -> annotate DateClass (fromString (formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S%Q" lt))
+    Day d           -> annotate DateClass (fromString (formatTime defaultTimeLocale "%Y-%m-%d" d))
+
+isAlwaysSimple :: Value -> Bool
+isAlwaysSimple = \case
+    Integer   _ -> True
+    Float     _ -> True
+    Bool      _ -> True
+    String    _ -> True
+    TimeOfDay _ -> True
+    ZonedTime _ -> True
+    LocalTime _ -> True
+    Day       _ -> True
+    Table     x -> isSingularTable x
+    Array     x -> null x || not (all isTable x)
+
+isTable :: Value -> Bool
+isTable Table {} = True
+isTable _           = False
+
+isSingularTable :: Table -> Bool
+isSingularTable (Map.elems -> [Table v]) = isSingularTable v
+isSingularTable (Map.elems -> [v])       = isAlwaysSimple v
+isSingularTable _                        = False
+
+-- | Render a complete TOML document using top-level table
+-- and array of table sections where appropriate.
+prettyToml :: Table -> TomlDoc
+prettyToml = prettyToml_ TableKind []
+
+prettyToml_ :: SectionKind -> [String] -> Table -> TomlDoc
+prettyToml_ kind prefix t = vcat (topLines ++ subtables)
+    where
+        (simple, sections) = partition (isAlwaysSimple . snd) (Map.assocs t)
+
+        topLines = [fold topElts | let topElts = headers ++ assignments, not (null topElts)]
+
+        headers =
+            case NonEmpty.nonEmpty prefix of
+                Just key | not (null simple) || null sections || kind == ArrayTableKind ->
+                    [prettySectionKind kind key <> hardline]
+                _ -> []
+
+        assignments = [prettyAssignment k v <> hardline | (k,v) <- simple]
+
+        subtables = [prettySection (prefix `NonEmpty.prependList` pure k) v | (k,v) <- sections]
+
+prettySection :: NonEmpty String -> Value -> TomlDoc
+prettySection key (Table t) =
+    prettyToml_ TableKind (NonEmpty.toList key) t
+prettySection key (Array a) =
+    vcat [prettyToml_ ArrayTableKind (NonEmpty.toList key) t | Table t <- a]
+prettySection _ _ = error "prettySection applied to simple value"
diff --git a/src/Toml/Semantics.hs b/src/Toml/Semantics.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/Semantics.hs
@@ -0,0 +1,193 @@
+{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}
+{-# HLINT ignore "Use list literal" #-}
+{-|
+Module      : Toml.Sematics
+Description : Semantic interpretation of raw TOML expressions
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module extracts the nested Map representation of a TOML
+file. It detects invalid key assignments and resolves dotted
+key assignments.
+
+-}
+module Toml.Semantics (semantics) where
+
+import Control.Monad (foldM)
+import Data.List (sortOn)
+import Data.List.NonEmpty (NonEmpty((:|)))
+import Data.List.NonEmpty qualified as NonEmpty
+import Data.Map (Map)
+import Data.Map qualified as Map
+import Text.Printf (printf)
+import Toml.Located (locThing, Located, locPosition)
+import Toml.Parser (SectionKind(..), Key, Val(..), Expr(..))
+import Toml.Value (Table, Value(..))
+import Toml.Position (Position(..))
+import Toml.Pretty (prettySimpleKey)
+
+-- | Extract semantic value from sequence of raw TOML expressions
+-- or report an error string.
+semantics :: [Expr] -> Either String Table
+semantics exprs =
+ do let (topKVs, tables) = gather exprs
+    m1 <- assignKeyVals topKVs Map.empty
+    m2 <- foldM (\m (kind, key, kvs) ->
+        addSection kind kvs key m) m1 tables
+    pure (fmap frameToValue m2)
+
+-- | Line number, key, value
+type KeyVals = [(Key, Val)]
+
+-- | Arrange the expressions in a TOML file into the top-level key-value pairs
+-- and then all the key-value pairs for each subtable.
+gather :: [Expr] -> (KeyVals, [(SectionKind, Key, KeyVals)])
+gather = goTop []
+    where
+        goTop acc []                           = (reverse acc, [])
+        goTop acc (ArrayTableExpr key : exprs) = (reverse acc, goTable ArrayTableKind key [] exprs)
+        goTop acc (TableExpr      key : exprs) = (reverse acc, goTable TableKind      key [] exprs)
+        goTop acc (KeyValExpr     k v : exprs) = goTop ((k,v):acc) exprs
+
+        goTable kind key acc []                           = (kind, key, reverse acc) : []
+        goTable kind key acc (TableExpr      k   : exprs) = (kind, key, reverse acc) : goTable TableKind k [] exprs
+        goTable kind key acc (ArrayTableExpr k   : exprs) = (kind, key, reverse acc) : goTable ArrayTableKind k [] exprs
+        goTable kind key acc (KeyValExpr     k v : exprs) = goTable kind key ((k,v):acc) exprs
+
+-- | Frames help distinguish tables and arrays written in block and inline
+-- syntax. This allows us to enforce that inline tables and arrays can not
+-- be extended by block syntax.
+data Frame
+    = FrameTable FrameKind (Map String Frame)
+    | FrameArray (NonEmpty (Map String Frame)) -- stored in reverse order for easy "append"
+    | FrameValue Value
+    deriving Show
+
+data FrameKind
+    = Open   -- ^ table implicitly defined as supertable of [x.y.z]
+    | Dotted -- ^ table implicitly defined using dotted key assignment
+    | Closed -- ^ table closed to further extension
+    deriving Show
+
+frameToValue :: Frame -> Value
+frameToValue = \case
+    FrameTable _ t -> Table (frameToValue <$> t)
+    FrameArray a   -> Array (reverse (Table . fmap frameToValue <$> NonEmpty.toList a))
+    FrameValue v   -> v
+
+constructTable :: [(Key, Value)] -> Either String Table
+constructTable entries =
+    case findBadKey (map fst entries) of
+        Just bad -> invalidKey (NonEmpty.last bad) "is overlapped"
+        Nothing -> Right (Map.unionsWith merge [singleValue (locThing k) (locThing <$> ks) v | (k:|ks, v) <- entries])
+    where
+        merge (Table x) (Table y) = Table (Map.unionWith merge x y)
+        merge _ _ = error "constructFrame:merge: panic"
+
+        singleValue k []      v = Map.singleton k v
+        singleValue k (k1:ks) v = Map.singleton k (Table (singleValue k1 ks v))
+
+-- | Finds a key that overlaps with another in the same list
+findBadKey :: [Key] -> Maybe Key
+findBadKey = check . sortOn (fmap locThing)
+    where
+        check (x:y:_)
+          | NonEmpty.toList (fmap locThing x) `NonEmpty.isPrefixOf` fmap locThing y = Just x
+        check (_:xs) = check xs
+        check [] = Nothing
+
+addSection ::
+    SectionKind                      {- ^ section kind        -} ->
+    KeyVals                          {- ^ values to install   -} ->
+    Key                              {- ^ section key         -} ->
+    Map String Frame                 {- ^ local frame map     -} ->
+    Either String (Map String Frame) {- ^ error message or updated local frame map -}
+addSection kind kvs = walk
+    where
+        walk (k1 :| []) = flip Map.alterF (locThing k1) \case
+            -- defining a new table
+            Nothing ->
+                case kind of
+                    TableKind      -> go (FrameTable Closed) Map.empty
+                    ArrayTableKind -> go (FrameArray . NonEmpty.singleton) Map.empty
+
+            -- defining a super table of a previously defined subtable
+            Just (FrameTable Open t) ->
+                case kind of
+                    TableKind      -> go (FrameTable Closed) t
+                    ArrayTableKind -> invalidKey k1 "is already a table"
+
+            -- Add a new array element to an existing table array
+            Just (FrameArray a) ->
+                case kind of
+                    ArrayTableKind -> go (FrameArray . (`NonEmpty.cons` a)) Map.empty
+                    TableKind      -> invalidKey k1 "is already an array of tables"
+
+            -- failure cases
+            Just (FrameTable Closed _) -> invalidKey k1 "is a closed table"
+            Just (FrameTable Dotted _) -> error "addSection: dotted table left unclosed"
+            Just (FrameValue {})       -> invalidKey k1 "is assigned"
+            where
+                go g t = Just . g . closeDots <$> assignKeyVals kvs t
+
+        walk (k1 :| k2 : ks) = flip Map.alterF (locThing k1) \case
+            Nothing                     -> go (FrameTable Open     ) Map.empty
+            Just (FrameTable tk t)      -> go (FrameTable tk       ) t
+            Just (FrameArray (t :| ts)) -> go (FrameArray . (:| ts)) t
+            Just (FrameValue _)         -> invalidKey k1 "is assigned"
+            where
+                go g t = Just . g <$> walk (k2 :| ks) t
+
+-- | Close all of the tables that were implicitly defined with
+-- dotted prefixes.
+closeDots :: Map String Frame -> Map String Frame
+closeDots =
+    fmap \case
+        FrameTable Dotted t -> FrameTable Closed (closeDots t)
+        frame               -> frame
+
+assignKeyVals :: KeyVals -> Map String Frame -> Either String (Map String Frame)
+assignKeyVals kvs t = closeDots <$> foldM f t kvs
+    where
+        f m (k,v) = assign k v m
+
+-- | Assign a single dotted key in a frame.
+assign :: Key -> Val -> Map String Frame -> Either String (Map String Frame)
+
+assign (key :| []) val = flip Map.alterF (locThing key) \case
+    Nothing -> Just . FrameValue <$> valToValue val
+    Just{}  -> invalidKey key "is assigned"
+
+assign (key :| k1 : keys) val = flip Map.alterF (locThing key) \case
+    Nothing                    -> go Map.empty
+    Just (FrameTable Open   t) -> go t
+    Just (FrameTable Dotted t) -> go t
+    Just (FrameTable Closed _) -> invalidKey key "is closed"
+    Just (FrameArray        _) -> invalidKey key "is closed"
+    Just (FrameValue        _) -> invalidKey key "is assigned"
+    where
+        go t = Just . FrameTable Dotted <$> assign (k1 :| keys) val t
+
+-- | Convert 'Val' to 'Value' potentially raising an error if
+-- it has inline tables with key-conflicts.
+valToValue :: Val -> Either String Value
+valToValue = \case
+    ValInteger   x    -> Right (Integer   x)
+    ValFloat     x    -> Right (Float     x)
+    ValBool      x    -> Right (Bool      x)
+    ValString    x    -> Right (String    x)
+    ValTimeOfDay x    -> Right (TimeOfDay x)
+    ValZonedTime x    -> Right (ZonedTime x)
+    ValLocalTime x    -> Right (LocalTime x)
+    ValDay       x    -> Right (Day       x)
+    ValArray xs       -> Array <$> traverse valToValue xs
+    ValTable kvs      -> do entries <- (traverse . traverse) valToValue kvs
+                            Table <$> constructTable entries
+
+invalidKey :: Located String -> String -> Either String a
+invalidKey k msg = Left (printf "%d:%d: key error: %s %s"
+    (posLine (locPosition k))
+    (posColumn (locPosition k))
+    (show (prettySimpleKey (locThing k)))
+    msg)
diff --git a/src/Toml/ToValue.hs b/src/Toml/ToValue.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/ToValue.hs
@@ -0,0 +1,95 @@
+{-|
+Module      : Toml.ToValue
+Description : Automation for converting application values to TOML.
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+-}
+module Toml.ToValue (
+    ToValue(..),
+
+    -- * Table construction
+    ToTable(..),
+    defaultTableToValue,
+    table,
+    (.=),
+    ) where
+
+import Data.Int (Int8, Int16, Int32, Int64)
+import Data.Map qualified as Map
+import Data.Time (Day, TimeOfDay, LocalTime, ZonedTime)
+import Data.Word (Word8, Word16, Word32, Word64)
+import Numeric.Natural (Natural)
+import Toml.Value (Value(..), Table)
+
+-- | Build a 'Table' from a list of key-value pairs.
+--
+-- Use '.=' for a convenient way to build the pairs.
+table :: [(String, Value)] -> Value
+table = Table . Map.fromList
+
+-- | Convenience function for building key-value pairs while
+-- constructing a 'Table'.
+--
+-- @'table' [a '.=' b, c '.=' d]@
+(.=) :: ToValue a => String -> a -> (String, Value)
+k .= v = (k, toValue v)
+
+-- | Class for types that can be embedded into 'Value'
+class ToValue a where
+
+    -- | Embed a single thing into a TOML value.
+    toValue :: a -> Value
+
+    -- | Helper for converting a list of things into a value. This is typically
+    -- left to be defined by its default implementation and exists to help define
+    -- the encoding for TOML arrays.
+    toValueList :: [a] -> Value
+    toValueList = Array . map toValue
+
+-- | Class for things that can be embedded into a TOML table.
+--
+-- Implement this for things that embed into a 'Table' and then
+-- the 'ToValue' instance can be derived with 'defaultTableToValue'.
+class ToValue a => ToTable a where
+
+    -- | Convert a single value into a table
+    toTable :: a -> Table
+
+-- | Convenience function for building 'ToValue' instances.
+defaultTableToValue :: ToTable a => a -> Value
+defaultTableToValue = Table . toTable
+
+instance ToValue Value where
+    toValue = id
+
+-- | Single characters are encoded as singleton strings. Lists of characters
+-- are encoded as a single string value.
+instance ToValue Char where
+    toValue x = String [x]
+    toValueList = String
+
+-- | This instance defers to the list element's 'toValueList' implementation.
+instance ToValue a => ToValue [a] where
+    toValue = toValueList
+
+instance ToValue Double    where toValue = Float
+instance ToValue Float     where toValue = Float . realToFrac
+instance ToValue Bool      where toValue = Bool
+instance ToValue TimeOfDay where toValue = TimeOfDay
+instance ToValue LocalTime where toValue = LocalTime
+instance ToValue ZonedTime where toValue = ZonedTime
+instance ToValue Day       where toValue = Day
+instance ToValue Integer   where toValue = Integer
+instance ToValue Natural   where toValue = Integer . fromIntegral
+instance ToValue Int       where toValue = Integer . fromIntegral
+instance ToValue Int8      where toValue = Integer . fromIntegral
+instance ToValue Int16     where toValue = Integer . fromIntegral
+instance ToValue Int32     where toValue = Integer . fromIntegral
+instance ToValue Int64     where toValue = Integer . fromIntegral
+instance ToValue Word      where toValue = Integer . fromIntegral
+instance ToValue Word8     where toValue = Integer . fromIntegral
+instance ToValue Word16    where toValue = Integer . fromIntegral
+instance ToValue Word32    where toValue = Integer . fromIntegral
+instance ToValue Word64    where toValue = Integer . fromIntegral
diff --git a/src/Toml/Value.hs b/src/Toml/Value.hs
new file mode 100644
--- /dev/null
+++ b/src/Toml/Value.hs
@@ -0,0 +1,53 @@
+{-|
+Module      : Toml.Value
+Description : Semantic TOML values
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module provides the type for the semantics of a TOML file.
+All dotted keys are resolved in this representation. Each table
+is a Map with a single level of keys.
+
+-}
+module Toml.Value (
+    Value(..),
+    Table,
+    ) where
+
+import Data.Map (Map)
+import Data.Time (Day, LocalTime, TimeOfDay, ZonedTime(zonedTimeToLocalTime, zonedTimeZone), timeZoneMinutes)
+
+-- | Representation of a TOML key-value table.
+type Table = Map String Value
+
+-- | Semantic TOML value with all table assignments resolved.
+data Value
+    = Integer   Integer
+    | Float     Double
+    | Array     [Value]
+    | Table     Table
+    | Bool      Bool
+    | String    String
+    | TimeOfDay TimeOfDay
+    | ZonedTime ZonedTime
+    | LocalTime LocalTime
+    | Day       Day
+    deriving (Show, Read)
+
+instance Eq Value where
+    Integer   x == Integer   y = x == y
+    Float     x == Float     y = x == y
+    Array     x == Array     y = x == y
+    Table     x == Table     y = x == y
+    Bool      x == Bool      y = x == y
+    String    x == String    y = x == y
+    TimeOfDay x == TimeOfDay y = x == y
+    LocalTime x == LocalTime y = x == y
+    Day       x == Day       y = x == y
+    ZonedTime x == ZonedTime y = projectZT x == projectZT y
+    _           == _           = False
+
+-- Extract the relevant parts to build an Eq instance
+projectZT :: ZonedTime -> (LocalTime, Int)
+projectZT x = (zonedTimeToLocalTime x, timeZoneMinutes (zonedTimeZone x))
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,882 @@
+{-# Language QuasiQuotes #-}
+{-|
+Module      : Main
+Description : Unit tests
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+TOML parser and validator unit tests (primarily drawn from the
+specification document).
+
+-}
+module Main (main) where
+
+import Data.Either (isLeft)
+import Data.Map (Map)
+import Data.Map qualified as Map
+import Data.Time (Day, TimeOfDay, LocalTime, ZonedTime)
+import QuoteStr (quoteStr)
+import Test.Hspec (hspec, describe, it, shouldBe, shouldSatisfy, Spec)
+import Toml (Value(..), parse, decode, Result(Success), prettyToml, Table)
+import Toml.FromValue (FromValue(..), defaultTableFromValue, reqKey, optKey, runParseTable, ParseTable, FromTable (fromTable))
+import Toml.ToValue (table, (.=))
+
+main :: IO ()
+main = hspec do
+  describe "parse" do
+    describe "comment"
+     do it "ignores comments" $
+          parse [quoteStr|
+            # This is a full-line comment
+            key = "value"  # This is a comment at the end of a line
+            another = "# This is not a comment"|]
+          `shouldBe`
+          Right (Map.fromList [("another",String "# This is not a comment"),("key",String "value")])
+
+    describe "key/value pair"
+     do it "supports the most basic assignments" $
+          parse "key = \"value\"" `shouldBe` Right (Map.singleton "key" (String "value"))
+
+        it "requires a value after equals" $
+          parse "key = # INVALID" `shouldSatisfy` isLeft
+
+        it "requires newlines between assignments" $
+          parse "first = \"Tom\" last = \"Preston-Werner\" # INVALID" `shouldSatisfy` isLeft
+
+    describe "keys"
+     do it "allows bare keys" $
+          parse [quoteStr|
+            key = "value"
+            bare_key = "value"
+            bare-key = "value"
+            1234 = "value"|]
+          `shouldBe`
+          Right (Map.fromList [
+            "1234"     .= "value",
+            "bare-key" .= "value",
+            "bare_key" .= "value",
+            "key"      .= "value"])
+
+        it "allows quoted keys" $
+          parse [quoteStr|
+            "127.0.0.1" = "value"
+            "character encoding" = "value"
+            "ʎǝʞ" = "value"
+            'key2' = "value"
+            'quoted "value"' = "value"|]
+          `shouldBe`
+          Right (Map.fromList [
+            "127.0.0.1"          .= "value",
+            "character encoding" .= "value",
+            "key2"               .= "value",
+            "quoted \"value\""   .= "value",
+            "ʎǝʞ"                .= "value"])
+
+        it "allows dotted keys" $
+          parse [quoteStr|
+            name = "Orange"
+            physical.color = "orange"
+            physical.shape = "round"
+            site."google.com" = true|]
+          `shouldBe`
+          Right (Map.fromList [
+            "name"     .= "Orange",
+            "physical" .= table ["color" .= "orange", "shape" .= "round"],
+            "site"     .= table ["google.com" .= True]])
+
+        it "prevents duplicate keys" $
+          parse [quoteStr|
+            name = "Tom"
+            name = "Pradyun"|]
+          `shouldSatisfy` isLeft
+
+        it "prevents duplicate keys even between bare and quoted" $
+          parse [quoteStr|
+            spelling = "favorite"
+            "spelling" = "favourite"|]
+          `shouldSatisfy` isLeft
+
+        it "allows out of order definitions" $
+          parse [quoteStr|
+            apple.type = "fruit"
+            orange.type = "fruit"
+
+            apple.skin = "thin"
+            orange.skin = "thick"
+
+            apple.color = "red"
+            orange.color = "orange"|]
+          `shouldBe`
+          Right (Map.fromList [
+            "apple" .= table [
+                "color" .= "red",
+                "skin"  .= "thin",
+                "type"  .= "fruit"],
+            "orange" .= table [
+                "color" .= "orange",
+                "skin"  .= "thick",
+                "type"  .= "fruit"]])
+
+        it "allows numeric bare keys" $
+          parse "3.14159 = 'pi'" `shouldBe` Right (Map.singleton "3" (table [("14159", String "pi")]))
+
+        it "allows keys that look like other values" $
+          parse [quoteStr|
+            true = true
+            false = false
+            1900-01-01 = 1900-01-01
+            1_2 = 2_3|]
+          `shouldBe`
+          Right (Map.fromList [
+            "1900-01-01" .= (read "1900-01-01" :: Day),
+            "1_2"        .= (23::Int),
+            "false"      .= False,
+            "true"       .= True])
+
+    describe "string"
+     do it "parses escapes" $
+          parse [quoteStr|
+            str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."|]
+          `shouldBe`
+          Right (Map.singleton "str" (String "I'm a string. \"You can quote me\". Name\tJos\xe9\nLocation\tSF."))
+
+        it "strips the initial newline from multiline strings" $
+          parse [quoteStr|
+            str1 = """
+            Roses are red
+            Violets are blue"""|]
+          `shouldBe` Right (Map.singleton "str1" (String "Roses are red\nViolets are blue"))
+
+        it "strips whitespace with a trailing escape" $
+          parse [quoteStr|
+            # The following strings are byte-for-byte equivalent:
+            str1 = "The quick brown fox jumps over the lazy dog."
+
+            str2 = """
+            The quick brown \
+
+
+            fox jumps over \
+                the lazy dog."""
+
+            str3 = """\
+                The quick brown \
+                fox jumps over \
+                the lazy dog.\
+                """|]
+          `shouldBe`
+          Right (Map.fromList [
+            "str1" .= "The quick brown fox jumps over the lazy dog.",
+            "str2" .= "The quick brown fox jumps over the lazy dog.",
+            "str3" .= "The quick brown fox jumps over the lazy dog."])
+
+        it "allows quotes inside multiline quoted strings" $
+          parse [quoteStr|
+            str4 = """Here are two quotation marks: "". Simple enough."""
+            str5 = """Here are three quotation marks: ""\"."""
+            str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\"."""
+
+            # "This," she said, "is just a pointless statement."
+            str7 = """"This," she said, "is just a pointless statement.""""|]
+          `shouldBe`
+          Right (Map.fromList [
+            "str4" .= "Here are two quotation marks: \"\". Simple enough.",
+            "str5" .= "Here are three quotation marks: \"\"\".",
+            "str6" .= "Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".",
+            "str7" .= "\"This,\" she said, \"is just a pointless statement.\""])
+
+        it "disallows triple quotes inside a multiline string" $
+          parse [quoteStr|
+            str5 = """Here are three quotation marks: """."""  # INVALID|]
+          `shouldSatisfy` isLeft
+
+        it "ignores escapes in literal strings" $
+          parse [quoteStr|
+            # What you see is what you get.
+            winpath  = 'C:\Users\nodejs\templates'
+            winpath2 = '\\ServerX\admin$\system32\'
+            quoted   = 'Tom "Dubs" Preston-Werner'
+            regex    = '<\i\c*\s*>'|]
+          `shouldBe`
+          Right (Map.fromList [
+            "quoted"   .= "Tom \"Dubs\" Preston-Werner",
+            "regex"    .= "<\\i\\c*\\s*>",
+            "winpath"  .= "C:\\Users\\nodejs\\templates",
+            "winpath2" .= "\\\\ServerX\\admin$\\system32\\"])
+
+        it "handles multiline literal strings" $
+          parse [quoteStr|
+            regex2 = '''I [dw]on't need \d{2} apples'''
+            lines  = '''
+            The first newline is
+            trimmed in raw strings.
+            All other whitespace
+            is preserved.
+            '''|]
+          `shouldBe`
+          Right (Map.fromList [
+            "lines"  .= "The first newline is\ntrimmed in raw strings.\nAll other whitespace\nis preserved.\n",
+            "regex2" .= "I [dw]on't need \\d{2} apples"])
+
+        it "parses all the other escapes" $
+          parse [quoteStr|
+            x = "\\\b\f\r\U0010abcd"
+            y = """\\\b\f\r\u7bca\U0010abcd\n\r\t"""|]
+          `shouldBe`
+          Right (Map.fromList [
+            "x" .= "\\\b\f\r\x0010abcd",
+            "y" .= "\\\b\f\r\x7bca\x0010abcd\n\r\t"])
+
+        it "rejects out of range unicode escapes" $
+          parse [quoteStr|
+            x = "\U11111111"|]
+          `shouldSatisfy` isLeft
+
+    describe "integer"
+     do it "parses literals correctly" $
+          parse [quoteStr|
+            int1 = +99
+            int2 = 42
+            int3 = 0
+            int4 = -17
+            int5 = 1_000
+            int6 = 5_349_221
+            int7 = 53_49_221  # Indian number system grouping
+            int8 = 1_2_3_4_5  # VALID but discouraged
+            # hexadecimal with prefix `0x`
+            hex1 = 0xDEADBEEF
+            hex2 = 0xdeadbeef
+            hex3 = 0xdead_beef
+
+            # octal with prefix `0o`
+            oct1 = 0o01234567
+            oct2 = 0o755 # useful for Unix file permissions
+
+            # binary with prefix `0b`
+            bin1 = 0b11010110|]
+          `shouldBe` Right
+          (Map.fromList [
+              "bin1" .= Integer 214,
+              "hex1" .= Integer 0xDEADBEEF,
+              "hex2" .= Integer 0xDEADBEEF,
+              "hex3" .= Integer 0xDEADBEEF,
+              "int1" .= Integer 99,
+              "int2" .= Integer 42,
+              "int3" .= Integer 0,
+              "int4" .= Integer (-17),
+              "int5" .= Integer 1000,
+              "int6" .= Integer 5349221,
+              "int7" .= Integer 5349221,
+              "int8" .= Integer 12345,
+              "oct1" .= Integer 0o01234567,
+              "oct2" .= Integer 0o755])
+
+    describe "float"
+     do it "parses floats" $
+          parse [quoteStr|
+            # fractional
+            flt1 = +1.0
+            flt2 = 3.1415
+            flt3 = -0.01
+
+            # exponent
+            flt4 = 5e+22
+            flt5 = 1e06
+            flt6 = -2E-2
+
+            # both
+            flt7 = 6.626e-34
+            flt8 = 224_617.445_991_228
+            # infinity
+            sf1 = inf  # positive infinity
+            sf2 = +inf # positive infinity
+            sf3 = -inf # negative infinity|]
+          `shouldBe`
+          Right (Map.fromList [
+            "flt1" .= Float 1.0,
+            "flt2" .= Float 3.1415,
+            "flt3" .= Float (-1.0e-2),
+            "flt4" .= Float 4.9999999999999996e22,
+            "flt5" .= Float 1000000.0,
+            "flt6" .= Float (-2.0e-2),
+            "flt7" .= Float 6.626e-34,
+            "flt8" .= Float 224617.445991228,
+            "sf1"  .= Float (1/0),
+            "sf2"  .= Float (1/0),
+            "sf3"  .= Float (-1/0)])
+
+        it "parses nan correctly" $
+          let checkNaN (Float x) = isNaN x
+              checkNaN _         = False
+          in
+          parse [quoteStr|
+            # not a number
+            sf4 = nan  # actual sNaN/qNaN encoding is implementation-specific
+            sf5 = +nan # same as `nan`
+            sf6 = -nan # valid, actual encoding is implementation-specific|]
+          `shouldSatisfy` \case
+            Left{} -> False
+            Right x -> all checkNaN x
+
+    describe "boolean"
+     do it "parses boolean literals" $
+          parse [quoteStr|
+            bool1 = true
+            bool2 = false|]
+          `shouldBe`
+          Right (Map.fromList [
+            "bool1" .= True,
+            "bool2" .= False])
+
+    describe "offset date-time"
+     do it "parses offset date times" $
+          parse [quoteStr|
+            odt1 = 1979-05-27T07:32:00Z
+            odt2 = 1979-05-27T00:32:00-07:00
+            odt3 = 1979-05-27T00:32:00.999999-07:00
+            odt4 = 1979-05-27 07:32:00Z|]
+          `shouldBe`
+          Right (Map.fromList [
+            "odt1" .= ZonedTime (read "1979-05-27 07:32:00 +0000"),
+            "odt2" .= ZonedTime (read "1979-05-27 00:32:00 -0700"),
+            "odt3" .= ZonedTime (read "1979-05-27 00:32:00.999999 -0700"),
+            "odt4" .= ZonedTime (read "1979-05-27 07:32:00 +0000")])
+
+    describe "local date-time"
+     do it "parses local date-times" $
+          parse [quoteStr|
+            ldt1 = 1979-05-27T07:32:00
+            ldt2 = 1979-05-27T00:32:00.999999
+            ldt3 = 1979-05-28 00:32:00.999999|]
+          `shouldBe`
+          Right (Map.fromList [
+            "ldt1" .= LocalTime (read "1979-05-27 07:32:00"),
+            "ldt2" .= LocalTime (read "1979-05-27 00:32:00.999999"),
+            "ldt3" .= LocalTime (read "1979-05-28 00:32:00.999999")])
+
+    describe "local date"
+     do it "parses dates" $
+          parse [quoteStr|
+            ld1 = 1979-05-27|]
+          `shouldBe`
+          Right (Map.singleton "ld1" (Day (read "1979-05-27")))
+
+    describe "local time"
+     do it "parses times" $
+          parse [quoteStr|
+            lt1 = 07:32:00
+            lt2 = 00:32:00.999999|]
+          `shouldBe`
+          Right (Map.fromList [
+            "lt1" .= TimeOfDay (read "07:32:00"),
+            "lt2" .= TimeOfDay (read "00:32:00.999999")])
+
+    describe "array"
+     do it "parses array examples" $
+          parse [quoteStr|
+            integers = [ 1, 2, 3 ]
+            colors = [ "red", "yellow", "green" ]
+            nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
+            nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
+            string_array = [ "all", 'strings', """are the same""", '''type''' ]
+
+            # Mixed-type arrays are allowed
+            numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
+            contributors = [
+            "Foo Bar <foo@example.com>",
+            { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
+            ]|]
+            `shouldBe`
+            Right (Map.fromList [
+                "colors" .= ["red", "yellow", "green"],
+                "contributors" .= [
+                    String "Foo Bar <foo@example.com>",
+                    table [
+                        "email" .= "bazqux@example.com",
+                        "name" .= "Baz Qux",
+                        "url" .= "https://example.com/bazqux"]],
+                "integers" .= [1, 2, 3 :: Integer],
+                "nested_arrays_of_ints" .= [[1, 2], [3, 4, 5 :: Integer]],
+                "nested_mixed_array" .= [[Integer 1, Integer 2], [String "a", String "b", String "c"]],
+                "numbers" .= [Float 0.1, Float 0.2, Float 0.5, Integer 1, Integer 2, Integer 5],
+                "string_array" .= ["all", "strings", "are the same", "type"]])
+
+        it "handles newlines and comments" $
+          parse [quoteStr|
+            integers2 = [
+            1, 2, 3
+            ]
+
+            integers3 = [
+            1,
+            2, # this is ok
+            ]|]
+            `shouldBe`
+            Right (Map.fromList [
+                "integers2" .= [1, 2, 3 :: Int],
+                "integers3" .= [1, 2 :: Int]])
+
+        it "disambiguates double brackets from array tables" $
+          parse "x = [[1]]" `shouldBe` Right (Map.singleton "x" (Array [Array [Integer 1]]))
+
+    describe "table"
+     do it "allows empty tables" $
+          parse "[table]" `shouldBe` Right (Map.singleton "table" (table []))
+
+        it "parses simple tables" $
+          parse [quoteStr|
+            [table-1]
+            key1 = "some string"
+            key2 = 123
+
+            [table-2]
+            key1 = "another string"
+            key2 = 456|]
+          `shouldBe`
+          Right (Map.fromList [
+            "table-1" .= table [
+                "key1" .= "some string",
+                "key2" .= Integer 123],
+            "table-2" .= table [
+                "key1" .= "another string",
+                "key2" .= Integer 456]])
+
+        it "allows quoted keys" $
+          parse [quoteStr|
+            [dog."tater.man"]
+            type.name = "pug"|]
+          `shouldBe`
+          Right (Map.fromList [("dog", table [("tater.man", table [("type", table [("name",String "pug")])])])])
+
+        it "allows whitespace around keys" $
+          parse [quoteStr|
+            [a.b.c]            # this is best practice
+            [ d.e.f ]          # same as [d.e.f]
+            [ g .  h  . i ]    # same as [g.h.i]
+            [ j . "ʞ" . 'l' ]  # same as [j."ʞ".'l']|]
+          `shouldBe`
+          Right (Map.fromList [
+            "a" .= table ["b" .= table ["c" .= table []]],
+            "d" .= table ["e" .= table ["f" .= table []]],
+            "g" .= table ["h" .= table ["i" .= table []]],
+            "j" .= table ["ʞ" .= table ["l" .= table []]]])
+
+        it "allows supertables to be defined after subtables" $
+          parse [quoteStr|
+            # [x] you
+            # [x.y] don't
+            # [x.y.z] need these
+            [x.y.z.w] # for this to work
+
+            [x] # defining a super-table afterward is ok
+            q=1|]
+          `shouldBe`
+          Right (Map.fromList [
+            "x" .= table [
+                "q" .= Integer 1,
+                "y" .= table [
+                    "z" .= table [
+                        "w" .= table []]]]])
+
+        it "prevents using a [table] to open a table defined with dotted keys" $
+          parse [quoteStr|
+            [fruit]
+            apple.color = 'red'
+            apple.taste.sweet = true
+            [fruit.apple]|]
+          `shouldSatisfy` isLeft
+
+        it "can add subtables" $
+          parse [quoteStr|
+            [fruit]
+            apple.color = "red"
+            apple.taste.sweet = true
+            [fruit.apple.texture]  # you can add sub-tables
+            smooth = true|]
+          `shouldBe`
+          Right (Map.fromList [
+            "fruit" .= table [
+                "apple" .= table [
+                    "color" .= "red",
+                    "taste" .= table [
+                        "sweet" .= True],
+                        "texture" .= table [
+                            "smooth" .= True]]]])
+
+    describe "inline table"
+     do it "parses inline tables" $
+          parse [quoteStr|
+            name = { first = "Tom", last = "Preston-Werner" }
+            point = { x = 1, y = 2 }
+            animal = { type.name = "pug" }|]
+          `shouldBe`
+          Right (Map.fromList [
+            "animal" .= table ["type" .= table ["name" .= "pug"]],
+            "name"   .= table ["first" .= "Tom", "last" .= "Preston-Werner"],
+            "point"  .= table ["x" .= Integer 1, "y" .= Integer 2]])
+
+        it "prevents altering inline tables with dotted keys" $
+          parse [quoteStr|
+            [product]
+            type = { name = "Nail" }
+            type.edible = false  # INVALID|]
+          `shouldSatisfy` isLeft
+
+        it "prevents using inline tables to add keys to existing tables" $
+          parse [quoteStr|
+            [product]
+            type.name = "Nail"
+            type = { edible = false }  # INVALID|]
+          `shouldSatisfy` isLeft
+
+    describe "array of tables"
+     do it "supports array of tables syntax" $
+          decode [quoteStr|
+            [[products]]
+            name = "Hammer"
+            sku = 738594937
+
+            [[products]]  # empty table within the array
+
+            [[products]]
+            name = "Nail"
+            sku = 284758393
+
+            color = "gray"|]
+          `shouldBe`
+          Success mempty (Map.singleton "products" [
+            Map.fromList [
+              "name" .= "Hammer",
+              "sku"  .= Integer 738594937],
+            Map.empty,
+            Map.fromList [
+                "color" .= "gray",
+                "name"  .= "Nail",
+                "sku"   .= Integer 284758393]])
+
+        it "handles subtables under array of tables" $
+          parse [quoteStr|
+            [[fruits]]
+            name = "apple"
+
+            [fruits.physical]  # subtable
+            color = "red"
+            shape = "round"
+
+            [[fruits.varieties]]  # nested array of tables
+            name = "red delicious"
+
+            [[fruits.varieties]]
+            name = "granny smith"
+
+
+            [[fruits]]
+            name = "banana"
+
+            [[fruits.varieties]]
+            name = "plantain"|]
+          `shouldBe`
+          Right (Map.fromList [
+            "fruits" .= [
+                table [
+                    "name" .= "apple",
+                    "physical" .= table [
+                        "color" .= "red",
+                        "shape" .= "round"],
+                    "varieties" .= [
+                        table ["name" .= "red delicious"],
+                        table ["name" .= "granny smith"]]],
+                table [
+                    "name" .= "banana",
+                    "varieties" .= [
+                        table ["name" .= "plantain"]]]]])
+
+        it "prevents redefining a supertable with an array of tables" $
+          parse [quoteStr|
+            # INVALID TOML DOC
+            [fruit.physical]  # subtable, but to which parent element should it belong?
+            color = "red"
+            shape = "round"
+
+            [[fruit]]  # parser must throw an error upon discovering that "fruit" is
+                    # an array rather than a table
+            name = "apple"|]
+            `shouldSatisfy` isLeft
+
+        it "prevents redefining an inline array" $
+          parse [quoteStr|
+            # INVALID TOML DOC
+            fruits = []
+
+            [[fruits]] # Not allowed|]
+          `shouldSatisfy` isLeft
+
+    -- these cases are needed to complete coverage checking on Semantics module
+    describe "corner cases"
+     do it "stays open" $
+          parse [quoteStr|
+            [x.y.z]
+            [x]
+            [x.y]|]
+          `shouldBe`
+          parse "x.y.z={}"
+
+        it "stays closed" $
+          parse [quoteStr|
+            [x.y]
+            [x]
+            [x.y]|] `shouldSatisfy` isLeft
+
+        it "super tables of array tables preserve array tables" $
+          parse [quoteStr|
+            [[x.y]]
+            [x]
+            [[x.y]]|]
+          `shouldBe`
+          parse "x.y=[{},{}]"
+
+        it "super tables of array tables preserve array tables" $
+          parse [quoteStr|
+            [[x.y]]
+            [x]
+            [x.y.z]|]
+          `shouldBe`
+          parse "x.y=[{z={}}]"
+
+        it "detects conflicting inline keys" $
+          parse [quoteStr|
+            x = { y = 1, y.z = 2}|]
+          `shouldSatisfy` isLeft
+
+        it "handles merging dotted inline table keys" $
+          parse [quoteStr|
+            t = { a.x.y = 1, a.x.z = 2, a.q = 3}|]
+          `shouldBe`
+          Right (Map.fromList [
+            ("t", table [
+                ("a", table [
+                    ("q",Integer 3),
+                    ("x", table [
+                        ("y",Integer 1),
+                        ("z",Integer 2)])])])])
+
+        it "disallows overwriting assignments with tables" $
+          parse [quoteStr|
+            x = 1
+            [x.y]|]
+          `shouldSatisfy` isLeft
+
+        it "handles super super tables" $
+          parse [quoteStr|
+            [x.y.z]
+            [x.y]
+            [x]|]
+          `shouldBe`
+          parse "x.y.z={}"
+
+        it "You can dot into open supertables" $
+          parse [quoteStr|
+            [x.y.z]
+            [x]
+            y.q = 1|]
+          `shouldBe`
+          parse "x.y={z={},q=1}"
+
+        it "dotted tables close previously open tables" $
+          parse [quoteStr|
+            [x.y.z]
+            [x]
+            y.q = 1
+            [x.y]|]
+          `shouldSatisfy` isLeft
+
+        it "dotted tables can't assign through closed tables!" $
+          parse [quoteStr|
+            [x.y]
+            [x]
+            y.z.w = 1|]
+          `shouldSatisfy` isLeft
+
+        it "super tables can't add new subtables to array tables via dotted keys" $
+          parse [quoteStr|
+            [[x.y]]
+            [x]
+            y.z.a = 1
+            y.z.b = 2|]
+          `shouldSatisfy` isLeft
+
+        it "the previous example preserves closeness" $
+          parse [quoteStr|
+            [[x.y]]
+            [x]
+            y.z.a = 1
+            y.w = 2|]
+          `shouldSatisfy` isLeft
+
+        it "defining a supertable closes the supertable" $
+          parse [quoteStr|
+            [x.y]
+            [x]
+            [x]|]
+          `shouldSatisfy` isLeft
+
+        it "prevents redefining an array of tables" $
+          parse [quoteStr|
+            [[x.y]]
+            [x.y]|]
+          `shouldSatisfy` isLeft
+
+  describe "deserialization" deserializationTests
+  describe "pretty-printing" prettyTests
+
+tomlString :: Table -> String
+tomlString = show . prettyToml
+
+prettyTests :: Spec
+prettyTests =
+ do it "renders example 1" $
+      fmap tomlString (parse "x=1")
+        `shouldBe` Right [quoteStr|
+        x = 1|]
+
+    it "renders example 2" $
+      fmap tomlString (parse "x=1\ny=2")
+        `shouldBe` Right [quoteStr|
+        x = 1
+        y = 2|]
+
+    it "renders example lists" $
+      fmap tomlString (parse "x=[1,'two', [true]]")
+        `shouldBe` Right [quoteStr|
+        x = [1, "two", [true]]|]
+
+    it "renders empty tables" $
+      fmap tomlString (parse "x.y.z={}\nz.y.w=false")
+        `shouldBe` Right [quoteStr|
+        z.y.w = false
+
+        [x.y.z]|]
+
+    it "renders empty tables in array of tables" $
+      fmap tomlString (parse "ex=[{},{},{a=9}]")
+        `shouldBe` Right [quoteStr|
+        [[ex]]
+
+        [[ex]]
+
+        [[ex]]
+        a = 9|]
+
+    it "renders multiple tables" $
+      fmap tomlString (parse "a.x=1\nb.x=3\na.y=2\nb.y=4")
+        `shouldBe` Right [quoteStr|
+        [a]
+        x = 1
+        y = 2
+
+        [b]
+        x = 3
+        y = 4|]
+
+    it "renders escapes in strings" $
+      fmap tomlString (parse "a=\"\\b\\t\\r\\f\\\"\\u007f\\U0001000c\"")
+        `shouldBe` Right [quoteStr|
+        a = "\b\t\r\f\"\u007F\U0001000C"|]
+
+    it "renders floats" $
+      fmap tomlString (parse "a=0.0\nb=-0.1\nc=0.1\nd=3.141592653589793\ne=4e123")
+        `shouldBe` Right [quoteStr|
+        a = 0.0
+        b = -0.1
+        c = 0.1
+        d = 3.141592653589793
+        e = 4.0e123|]
+
+    it "renders special floats" $
+      fmap tomlString (parse "a=inf\nb=-inf\nc=nan")
+        `shouldBe` Right [quoteStr|
+        a = inf
+        b = -inf
+        c = nan|]
+
+    it "renders empty documents" $
+      fmap tomlString (parse "")
+        `shouldBe` Right ""
+
+    it "renders dates and time" $
+      fmap tomlString (parse [quoteStr|
+        a = 2020-05-07
+        b = 15:16:17.990
+        c = 2020-05-07T15:16:17.990
+        d = 2020-05-07T15:16:17.990Z
+        e = 2020-05-07T15:16:17-07:00
+        f = 2021-09-06T14:15:19+08:00|])
+        `shouldBe` Right [quoteStr|
+        a = 2020-05-07
+        b = 15:16:17.99
+        c = 2020-05-07T15:16:17.99
+        d = 2020-05-07T15:16:17.99Z
+        e = 2020-05-07T15:16:17-07:00
+        f = 2021-09-06T14:15:19+08:00|]
+
+    it "renders quoted keys" $
+      fmap tomlString (parse "''.'a b'.'\"' = 10")
+        `shouldBe` Right [quoteStr|
+        ""."a b"."\"" = 10|]
+
+newtype Fruits = Fruits [Fruit]
+    deriving (Eq, Show)
+
+data Fruit = Fruit String (Maybe Physical) [Variety]
+    deriving (Eq, Show)
+
+data Physical = Physical String String
+    deriving (Eq, Show)
+
+newtype Variety = Variety String
+    deriving (Eq, Show)
+
+instance FromTable Fruits where
+    fromTable = runParseTable (Fruits <$> reqKey "fruits")
+
+instance FromTable Fruit where
+    fromTable = runParseTable (Fruit <$> reqKey "name" <*> optKey "physical" <*> reqKey "varieties")
+
+instance FromTable Physical where
+    fromTable = runParseTable (Physical <$> reqKey "color" <*> reqKey "shape")
+
+instance FromTable Variety where
+    fromTable = runParseTable (Variety <$> reqKey "name")
+
+instance FromValue Fruits   where fromValue = defaultTableFromValue
+instance FromValue Fruit    where fromValue = defaultTableFromValue
+instance FromValue Physical where fromValue = defaultTableFromValue
+instance FromValue Variety  where fromValue = defaultTableFromValue
+
+deserializationTests :: Spec
+deserializationTests =
+     do it "handles fruit example" $
+          decode [quoteStr|
+              [[fruits]]
+              name = "apple"
+
+              [fruits.physical]  # subtable
+              color = "red"
+              shape = "round"
+
+              [[fruits.varieties]]  # nested array of tables
+              name = "red delicious"
+
+              [[fruits.varieties]]
+              name = "granny smith"
+
+              [[fruits]]
+              name = "banana"
+
+              [[fruits.varieties]]
+              name = "plantain"|]
+          `shouldBe`
+            Success mempty (Fruits [
+                Fruit "apple" (Just (Physical "red" "round")) [Variety "red delicious", Variety "granny smith"],
+                Fruit "banana" Nothing [Variety "plantain"]])
diff --git a/test/QuoteStr.hs b/test/QuoteStr.hs
new file mode 100644
--- /dev/null
+++ b/test/QuoteStr.hs
@@ -0,0 +1,36 @@
+{-|
+Module      : QuoteStr
+Description : Quasiquoter for multi-line string literals
+Copyright   : (c) Eric Mertens, 2023
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+This module makes it easy to write inline TOML for
+test cases without worrying about escaping newlines
+or quotation marks.
+
+-}
+module QuoteStr (quoteStr) where
+
+import Language.Haskell.TH ( Exp(LitE), ExpQ, Lit(StringL) )
+import Language.Haskell.TH.Quote ( QuasiQuoter(..) )
+import Data.List ( stripPrefix )
+
+quoteStr :: QuasiQuoter
+quoteStr = QuasiQuoter {
+    quoteDec = \_ -> fail "quoteStr doesn't support declarations",
+    quotePat = \_ -> fail "quoteStr doesn't support patterns",
+    quoteType = \_ -> fail "quoteStr doesn't support types",
+    quoteExp = processString
+  }
+
+processString :: String -> ExpQ
+processString ('\n':xs) =
+    let ws = takeWhile (' '==) xs
+        
+        cleanup "" = pure ""
+        cleanup x = case stripPrefix ws x of
+                      Nothing -> fail "bad prefix"
+                      Just x' -> pure x'
+    in LitE . StringL . unlines <$> traverse cleanup (lines xs)
+processString _ = fail "malformed string literal"
diff --git a/toml-parser.cabal b/toml-parser.cabal
--- a/toml-parser.cabal
+++ b/toml-parser.cabal
@@ -1,37 +1,81 @@
-name:                toml-parser
-version:             0.1.0.0
-synopsis:            Parser for the TOML configuration language
-description:         Parser for the TOML configuration language. TOML is specified
-                     by <https://github.com/toml-lang/toml>. This language is
-                     designed to be easy to understand and unambiguous.
-                     .
-                     This implementation uses Alex and Happy to generate an
-                     efficient lexer and parser. It aims to have minimal library
-                     dependencies.
-license:             ISC
-license-file:        LICENSE
-author:              Eric Mertens
-maintainer:          emertens@gmail.com
-copyright:           2017 Eric Mertens
-category:            Language
-build-type:          Simple
-extra-source-files:  ChangeLog.md
-cabal-version:       >=1.10
-homepage:            https://github.com/glguy/toml-parser
-bug-reports:         https://github.com/glguy/toml-parser/issues
+cabal-version:      3.0
+name:               toml-parser
+version:            1.0.0.0
+synopsis:           TOML 1.0.0 parser
+description:
+    TOML parser using generated lexers and parsers with
+    careful attention to the TOML 1.0.0 semantics for
+    defining tables.
+license:            ISC
+license-file:       LICENSE
+author:             Eric Mertens
+maintainer:         emertens@gmail.com
+copyright:          2023 Eric Mertens
+category:           Text
+build-type:         Simple
+tested-with:        GHC == 9.2.8, GHC == 9.4.5, GHC == 9.6.2
 
+extra-doc-files:
+    ChangeLog.md
+    README.md
+
 source-repository head
-  type: git
-  location: https://github.com/glguy/toml-parser.git
+    type: git
+    location: https://github.com/glguy/toml-parser
+    tag: main
 
+common extensions
+    default-language:   Haskell2010
+    default-extensions:
+        BlockArguments
+        DeriveTraversable
+        GeneralizedNewtypeDeriving
+        ImportQualifiedPost
+        LambdaCase
+        ScopedTypeVariables
+        ViewPatterns
+
 library
-  exposed-modules:     TOML
-  other-modules:       TOML.Tokens TOML.LexerUtils TOML.Lexer TOML.Errors
-                       TOML.Parser TOML.Components TOML.Value TOML.Located
-  build-depends:       base  >=4.9 && <4.11,
-                       array >=0.5 && <0.6,
-                       text  >=1.2 && <1.3,
-                       time  >=1.6 && <1.9
-  hs-source-dirs:      src
-  build-tools:         alex, happy
-  default-language:    Haskell2010
+    import:             extensions
+    hs-source-dirs:     src
+    default-language:   Haskell2010
+    exposed-modules:
+        Toml
+        Toml.FromValue
+        Toml.FromValue.Matcher
+        Toml.Lexer
+        Toml.Lexer.Token
+        Toml.Lexer.Utils
+        Toml.Located
+        Toml.Parser
+        Toml.Parser.Types
+        Toml.Position
+        Toml.Pretty
+        Toml.Semantics
+        Toml.ToValue
+        Toml.Value
+    build-depends:
+        array           ^>= 0.5,
+        base            ^>= 4.16 || ^>= 4.17 || ^>= 4.18,
+        containers      ^>= 0.5 || ^>= 0.6,
+        prettyprinter   ^>= 1.7,
+        time            ^>= 1.11 || ^>= 1.12,
+        transformers    ^>= 0.5 || ^>= 0.6,
+    build-tool-depends:
+        alex:alex       >= 3.2,
+        happy:happy     >= 1.19,
+
+test-suite unittests
+    import:             extensions
+    type:               exitcode-stdio-1.0
+    hs-source-dirs:     test
+    main-is:            Main.hs
+    build-depends:
+        base,
+        containers,
+        hspec           ^>= 2.11,
+        template-haskell ^>= 2.18 || ^>= 2.19 || ^>= 2.20,
+        time,
+        toml-parser,
+    other-modules:
+        QuoteStr
