HXQ 0.10.0 → 0.11.0
raw patch · 26 files changed
+1045/−602 lines, 26 filesdep −mtlPVP ok
version bump matches the API change (PVP)
Dependencies removed: mtl
API changes (from Hackage documentation)
+ Text.XML.HXQ.XQuery: XNull :: XTree
+ Text.XML.HXQ.XQuery: commit :: conn -> IO ()
+ Text.XML.HXQ.XQuery: rollback :: conn -> IO ()
- Text.XML.HXQ.XQuery: createIndex :: (IConnection conn) => conn -> String -> String -> IO ()
+ Text.XML.HXQ.XQuery: createIndex :: Connection -> String -> String -> IO ()
- Text.XML.HXQ.XQuery: genSchema :: (IConnection conn) => conn -> String -> String -> IO Table
+ Text.XML.HXQ.XQuery: genSchema :: Connection -> String -> String -> IO Table
- Text.XML.HXQ.XQuery: prepareSQL :: (IConnection conn) => conn -> String -> IO Statement
+ Text.XML.HXQ.XQuery: prepareSQL :: Connection -> String -> IO Statement
- Text.XML.HXQ.XQuery: printSchema :: (IConnection conn) => conn -> String -> IO ()
+ Text.XML.HXQ.XQuery: printSchema :: Connection -> String -> IO ()
- Text.XML.HXQ.XQuery: shred :: (IConnection conn) => conn -> String -> String -> IO ()
+ Text.XML.HXQ.XQuery: shred :: Connection -> String -> String -> IO ()
- Text.XML.HXQ.XQuery: xfileDB :: (IConnection conn) => String -> conn -> IO XSeq
+ Text.XML.HXQ.XQuery: xfileDB :: String -> Connection -> IO XSeq
- Text.XML.HXQ.XQuery: xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq
+ Text.XML.HXQ.XQuery: xqueryDB :: String -> Connection -> IO XSeq
Files
- HXQ.cabal +5/−6
- Main.hs +17/−8
- Makefile +4/−8
- Test1.hs +2/−1
- Test2.hs +1/−1
- TestDB.hs +1/−1
- TestDB2.hs +1/−1
- TestDBLP1.hs +9/−0
- TestDBLP2.hs +12/−0
- TestDBPL1.hs +0/−8
- TestDBPL2.hs +0/−12
- XQueryParser.y +19/−1
- db.html +60/−19
- index.html +8/−6
- src/Text/XML/HXQ/Compiler.hs +71/−27
- src/Text/XML/HXQ/Functions.hs +30/−27
- src/Text/XML/HXQ/Interpreter.hs +124/−96
- src/Text/XML/HXQ/Optimizer.hs +34/−25
- src/Text/XML/HXQ/Parser.hs +207/−157
- src/Text/XML/HXQ/XQuery.hs +3/−3
- src/Text/XML/HXQ/XTree.hs +19/−3
- src/mysql/Connect.hs +1/−1
- src/noDB/Text/XML/HXQ/OptionalDB.hs +25/−9
- src/sqlite/Connect.hs +1/−2
- src/withDB/Text/XML/HXQ/DB.hs +389/−178
- src/withDB/Text/XML/HXQ/OptionalDB.hs +2/−2
HXQ.cabal view
@@ -1,6 +1,6 @@ Cabal-Version: >= 1.2 Name: HXQ-Version: 0.10.0+Version: 0.11.0 Synopsis: A Compiler from XQuery to Haskell Description: HXQ is a fast and space-efficient compiler from XQuery (the standard@@ -30,8 +30,8 @@ Test2.hs TestDB.hs TestDB2.hs- TestDBPL1.hs- TestDBPL2.hs+ TestDBLP1.hs+ TestDBLP2.hs compile compile.bat data-files:@@ -54,7 +54,7 @@ src/hxml-0.2/00-README.txt Flag mysql- Description: provides database connectivity using HDBC and HDBC-odbc.+ Description: provides database connectivity using HDBC and MySql through HDBC-odbc. Default: False Flag sqlite@@ -68,7 +68,7 @@ Text.XML.HXQ.OptionalDB, HXML, DTD, LLParsing, TreeBuild, XMLParse, ETree, Misc, Tree, XMLScanner, AssocList, PrintXML, XML hs-source-dirs: . src src/hxml-0.2- Build-Depends: base, haskell98, array, template-haskell, mtl+ Build-Depends: base, haskell98, array, template-haskell if os(windows) hs-source-dirs: src/readline Other-Modules: System.Console.Readline@@ -90,7 +90,6 @@ Executable xquery Main-is: Main.hs hs-source-dirs: . src src/hxml-0.2- Build-Depends: base, haskell98, array, template-haskell, mtl if os(windows) hs-source-dirs: src/readline Other-Modules: System.Console.Readline
Main.hs view
@@ -6,18 +6,25 @@ - ---------------------------------------------------------------} +{-# OPTIONS -cpp #-} module Main where import System.Environment-import qualified Control.Exception+import qualified Control.Exception as C import Text.XML.HXQ.Functions(functions) import Text.XML.HXQ.Interpreter(evalInput,xqueryE) import Text.XML.HXQ.XQuery -version = "0.10.0"+#if __GLASGOW_HASKELL__ >= 609+type E = C.SomeException+#else+type E = C.Exception+#endif +version = "0.11.0" + parseEnv :: [String] -> [(String,String)] parseEnv [] = [("o","Temp.hs")] parseEnv ("-help":xs) = ("help",""):(parseEnv xs)@@ -30,7 +37,7 @@ parseEnv (file:xs) = ("r",file):(parseEnv xs) -noDBerror _ = error "Missing Database Connection"+noDBerror = error "Missing Database Connection; use -db in xquery" main = do senv <- getArgs@@ -64,6 +71,7 @@ Just file -> case lookup "db" env of Just filepath -> do db <- connect filepath result <- xfileDB file db+ commit db putXSeq result _ -> do query <- readFile file (result,_,_) <- xqueryE query [] [] noDBerror verbose@@ -75,13 +83,14 @@ case lookup "db" env of Just filepath -> do db <- connect filepath- evalInput (\s vs fs-> Control.Exception.catch- (do (result,nvs,nfs) <- xqueryE s vs fs (prepareSQL db) verbose+ evalInput (\s vs fs-> C.catch+ (do (result,nvs,nfs) <- xqueryE s vs fs db verbose putXSeq result+ commit db return (nvs,nfs))- (\e -> do putStrLn (show e); return (vs,fs))) [] []- _ -> evalInput (\s vs fs-> Control.Exception.catch+ (\e -> do putStrLn (show (e::E)); return (vs,fs))) [] []+ _ -> evalInput (\s vs fs-> C.catch (do (result,nvs,nfs) <- xqueryE s vs fs noDBerror verbose putXSeq result return (nvs,nfs))- (\e -> do putStrLn (show e); return (vs,fs))) [] []+ (\e -> do putStrLn (show (e::E)); return (vs,fs))) [] []
Makefile view
@@ -16,10 +16,6 @@ all: $(parser) Main.hs $(ghc) --make Main.hs -o xquery -# on-the-fly compiler: unstable; use xquery instead-hxqc: $(parser) HXQ-unstable.hs- $(ghc) -optl-s -no-recomp -package ghc --make HXQ-unstable.hs -o hxqc- # generate the XQuery parser using happy $(parser): XQueryParser.y happy -g -a -c -o $(parser) XQueryParser.y@@ -40,12 +36,12 @@ $(ghc) --make TestDB2.hs -o a.out ./a.out -dbpl1: $(parser) TestDBPL1.hs- $(ghc) --make TestDBPL1.hs -o a.out+dblp1: $(parser) TestDBLP1.hs+ $(ghc) --make TestDBLP1.hs -o a.out ./a.out +RTS -H200m -K100m -dbpl2: $(parser) TestDBPL2.hs- $(ghc) --make TestDBPL2.hs -o a.out+dblp2: $(parser) TestDBLP2.hs+ $(ghc) --make TestDBLP2.hs -o a.out ./a.out # run in the ghci interpreter and load HXQ
Test1.hs view
@@ -6,7 +6,8 @@ - ---------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-}+{-# LANGUAGE TemplateHaskell #-}+ module Main where
Test2.hs view
@@ -7,7 +7,7 @@ - ---------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-}+{-# LANGUAGE TemplateHaskell #-} module Main where
TestDB.hs view
@@ -8,7 +8,7 @@ - ---------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-}+{-# LANGUAGE TemplateHaskell #-} module Main where
TestDB2.hs view
@@ -7,7 +7,7 @@ - ---------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-}+{-# LANGUAGE TemplateHaskell #-} module Main where
+ TestDBLP1.hs view
@@ -0,0 +1,9 @@+module Main where++import Text.XML.HXQ.XQuery+++main = do db <- connect "hxq"+ -- Generate the relational schema for the DBPL database using hybrid inlining. Ignore HTML tags+ genSchema db "data/dblp.xml" "d" ["i","sub","sup","tt"]+ -- genSchema db "data/dblp.xml" "d" []
+ TestDBLP2.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE TemplateHaskell #-}++module Main where++import Text.XML.HXQ.XQuery+++main = do db <- connect "hxq"+ -- populate the DBPL database (it takes about 12 minutes)+ $(shredC "hxq" "data/dblp.xml" "d")+ -- create an index on author name+ createIndex db "d" "author"
− TestDBPL1.hs
@@ -1,8 +0,0 @@-module Main where--import Text.XML.HXQ.XQuery---main = do db <- connect "hxq"- -- generate the relational schema for the DBPL database using hybrid inlining- genSchema db "data/dblp.xml" "d"
− TestDBPL2.hs
@@ -1,12 +0,0 @@-{-# OPTIONS_GHC -fth #-}--module Main where--import Text.XML.HXQ.XQuery---main = do db <- connect "hxq"- -- populate the DBPL database (it takes about 12 minutes)- $(shredC "hxq" "data/dblp.xml" "d")- -- create an index on author name- createIndex db "d" "author"
XQueryParser.y view
@@ -89,6 +89,12 @@ '.' { DOT } ';' { SEMI } ':' { COLON }+ 'insert' { INSERT }+ 'delete' { DELETE }+ 'replace' { REPLACE }+ 'into' { INTO }+ 'from' { FROM}+ 'with' { WITH } 'Variable' { Variable $$ } 'XMLtext' { XMLtext $$ } 'Integer' { TInteger $$ }@@ -97,6 +103,7 @@ %nonassoc 'for' 'let' 'satisfies' 'return'+%nonassoc 'with' 'from' 'into' %nonassoc 'else' %left 'intersect' 'union' 'except' %right 'or'@@ -180,6 +187,9 @@ | string { $1 } | 'Integer' { Aint $1 } | 'Double' { Afloat $1 }+ | 'insert' expr 'into' expr { call "insert" [$2,Ast "destination" [$4]] }+ | 'delete' 'from' expr { call "delete" [$3] }+ | 'replace' expr 'with' expr { call "replace" [$2,$4] } expl :: { [ Ast ] } expl : expr { [$1] }@@ -388,7 +398,8 @@ | AND | OR | NOT | UNION | INTERSECT | EXCEPT | FOR | LET | IN | COMMA | ASSIGN | WHERE | ORDER | BY | ASCENDING | DESCENDING | ELEMENT | ATTRIBUTE | STAG | ETAG | SATISFIES | ATSIGN | SLASH | DECLARE | SEMI | COLON- | FUNCTION | VARIABLE |AT | DOT | DOTS | TokenEOF | PRE | POST | IS+ | FUNCTION | VARIABLE | AT | DOT | DOTS | TokenEOF | PRE | POST | IS+ | INSERT | INTO | DELETE | FROM | REPLACE | WITH | QName String | Variable String | XMLtext String | TInteger Int | TFloat Float | TString String | TError String deriving Eq@@ -418,6 +429,7 @@ (BY,"by"),(ASCENDING,"ascending"),(DESCENDING,"descending"),(ELEMENT,"element"), (ATTRIBUTE,"attribute"),(STAG,"</"),(ETAG,"/>"),(SATISFIES,"satisfies"),(ATSIGN,"@"), (SLASH,"/"),(DECLARE,"declare"),(FUNCTION,"function"),(VARIABLE,"variable"),+ (INSERT,"insert"),(INTO,"into"),(DELETE,"delete"),(FROM,"from"),(REPLACE,"replace"),(WITH,"with"), (AT,"at"),(DOTS,".."),(DOT,"."),(SEMI,";"),(COLON,":")] @@ -607,6 +619,12 @@ "gt" -> SGT "ge" -> SGE "is" -> IS+ "insert" -> INSERT+ "into" -> INTO+ "delete" -> DELETE+ "from" -> FROM+ "replace" -> REPLACE+ "with" -> WITH var -> QName var ) : lexer rest n }
db.html view
@@ -3,7 +3,7 @@ <body> <center> <h1>HXQ with Database Connectivity</h1>-<h3>Download <a href="/HXQ-0.10.0.tar.gz">HXQ-0.10.0.tar.gz</a></h3>+<h3>Download <a href="/HXQ-0.11.0.tar.gz">HXQ-0.11.0.tar.gz</a></h3> </center> <p> <h2>Installation Instructions (HXQ with database connectivity)</h2>@@ -40,6 +40,8 @@ <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-1.1.4">HDBC 1.1.4</a> (but not version 1.1.5) and the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-odbc">HDBC-odbc</a> driver.+(For ghc 6.10, you may have to change <tt>import Control.Exception</tt> to <tt>import Control.OldException</tt>+in Utils.hsc.) Then you do: <pre> runhaskell Setup.lhs configure -fmysql@@ -55,6 +57,8 @@ <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-1.1.4">HDBC 1.1.4</a> (but not version 1.1.5) and the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HDBC-sqlite3">HDBC-sqlite3</a> driver.+(For ghc 6.10, you may have to change <tt>import Control.Exception</tt> to <tt>import Control.OldException</tt>+in Utils.hsc and Statement.hsc.) Then you do: <pre> runhaskell Setup.lhs configure -fsqlite@@ -67,7 +71,7 @@ HXQ provides an interface to HDBC to query relational data inside an XQuery. For the HXQ compiler, the main function that allows database connectivity is: <pre>-$(xqdb query) :: (IConnection conn) => conn -> IO XSeq+$(xqdb query) :: Connection -> IO XSeq </pre> For example, if the database name is "hxq", then <pre>@@ -76,7 +80,7 @@ </pre> For the HXQ interpreter, the function is: <pre>-xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq+xqueryDB :: String -> Connection -> IO XSeq </pre> The <tt>xquery</tt> executable can also run XQueries that use a database by specifying the database name using the -db option, eg. <tt>xquery -db hxq</tt>.@@ -95,18 +99,20 @@ <p> <h2>Shredding</h2> <p>-To synthesize a relational schema <tt>schemaname</tt> to store an XML document located at <tt>pathname</tt>, use the following Haskell function:+To synthesize a relational schema <tt>schemaname</tt> to store an XML document+located at <tt>pathname</tt>, use the following Haskell function: <pre>-genSchema :: (IConnection conn) => conn -> String -> String -> IO ()-genSchema db pathname schemaname+genSchema :: Connection -> String -> String -> [String] -> IO ()+genSchema db pathname schemaname excludedtags </pre>-for a database <tt>db</tt>. HXQ will find a good-relational schema (using hybrid inlining) to store the XML data by+for a database <tt>db</tt>, where the excluded tags are HTML tags to be ignored (skipped)+when the XML data are document-centric+HXQ will find a good relational schema (using hybrid inlining) to store the XML data by scanning the document to extract its structural summary and then deriving a good relational schema from the summary. To actually store the data from the XML document into the relational schema, use the following Haskell function: <pre>-shred :: (IConnection conn) => conn -> String -> String -> IO ()+shred :: Connection -> String -> String -> IO () shred db pathname schemaname </pre> For example,@@ -115,7 +121,10 @@ genSchema db "data/cs.xml" "c" shred db "data/cs.xml" "c" </pre>-For large XML documents, you better use the compiled version of <tt>shred</tt>, <tt>$(shredC db pathname schemaname)</tt>.+For large XML documents, you better use the compiled version of <tt>shred</tt>:+<pre>+$(shredC dbname pathname schemaname)+</pre> <p> The Haskell function <pre>@@ -141,16 +150,48 @@ thus deriving an efficient execution. One example is <a href="TestDB2.hs">TestDB2.hs</a>. <p>-<h2>Example: Installing and Querying the DBPL Database</h2>+<h2>Updates</h2> <p>-First download and uncompress <tt>dbpl.xml.gz</tt> from <a href="http://dblp.uni-trier.de/xml/">DBLP</a>.-To install the DBPL database using MySQL, compile and execute first-<a href="TestDBPL1.hs">TestDBPL1.hs</a> and then-<a href="TestDBPL2.hs">TestDBPL2.hs</a>.-Then you may evaluete queries, such as <a href="data/q4.xq">data/q4.xq</a>, using the HXQ interpreter,-which takes about 4 seconds.-+The XQuery syntax has been extended with the following expressions in HXQ:+<pre>+ insert e1 into e2+ delete from e+ replace e2 with e1+</pre>+where <tt>e2</tt> and <tt>e</tt> are XQuery expressions that return XML elements extracted from shredded documents stored in the relational database.+That is, you can not update XML text files or constructed XML elements.+In addition, <tt>e2</tt> must return a singleton sequence (exactly one XML element) and+the returned XML sequence from <tt>e1</tt> must be compatible to the document structural summary at the point of the update.+These updates are evaluated using SQL updates+over the underlying relational database. The insert expression makes <tt>e1</tt> a new child of <tt>e2</tt> and returns <tt>e1</tt>.+The delete expression removes the element <tt>e</tt> from its parent and returns <tt>()</tt>.+The replace expression replaces <tt>e2</tt> with <tt>e1</tt> and returns <tt>e1</tt>.+These updates are not automatically committed; the programmer must commit them explicitly using the <tt>commit db</tt> function.+(The <tt>xquery</tt> program though commits at the end of each xquery automatically.) <p>+Examples of updates:+<pre>+replace publish('hxq','c')//gradstudent[name/lastname="Smith"]/gpa with 3.7+insert <zip>12345</zip> into publish('hxq','c')//gradstudent[name/lastname="Smith"]/address+for $e in publish('hxq','e')//employee return replace $e/salary with $e/salary*1.5+</pre>+<p>+<h2>Example: Installing and Querying the DBLP Database</h2>+<p>+First download and uncompress <tt>dblp.xml.gz</tt> from <a href="http://dblp.uni-trier.de/xml/">DBLP</a>.+To install the DBLP database using MySQL, compile and execute+<a href="TestDBLP1.hs">TestDBLP1.hs</a> first (using ghc options <tt>+RTS -H200m -K100m</tt>) and then+<a href="TestDBLP2.hs">TestDBLP2.hs</a>.+Then, you may evaluate queries, such as <a href="data/q4.xq">data/q4.xq</a>, using the HXQ interpreter,+<tt>xquery -db hxq data/q4.xq</tt>, which takes about 0.1 seconds.+<p>+<h2>Status</h2>+<p>+<ul>+<li> XML elements are not stored in document order. Thus, element indexing may return unpredictable results.+<li> HXQ does better job in stroring data-centric than document-centric XML data (especially those with mixed content).+</ul>+<p> <hr> <p>-<address>Last modified: 10/26/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>+<address>Last modified: 11/24/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
index.html view
@@ -3,7 +3,7 @@ <body> <center> <h1>HXQ: A Compiler from XQuery to Haskell</h1>-<h3>Download <a href="/HXQ-0.10.0.tar.gz">HXQ-0.10.0.tar.gz</a></h3>+<h3>Download <a href="/HXQ-0.11.0.tar.gz">HXQ-0.11.0.tar.gz</a></h3> </center> <p> <h2>Description</h2>@@ -29,7 +29,7 @@ (using 1150MB of heap space). (All results are taken on an Intel Core 2 Duo 2.2GHz 2GB running ghc-6.8.2 on Linux 2.6.23 kernel.) <p> Finally, HXQ can store XML documents in a relational database-(currently SQLite), by shredding XML into relational tuples, and by+(currently MySQL or SQLite), by shredding XML into relational tuples, and by translating XQueries over the shredded documents into optimized SQL queries. <p>@@ -46,7 +46,7 @@ if you want to modify the XQuery parser, you need to install the parser generator for Haskell, <a href="http://www.haskell.org/happy/">happy</a>. Then,-download <a href="/HXQ-0.10.0.tar.gz">HXQ version 0.10.0</a> and untar+download <a href="/HXQ-0.11.0.tar.gz">HXQ version 0.11.0</a> and untar it (using <tt>tar xfz</tt> on Linux or <a href="http://www.7-zip.org/">7z x</a> on Windows). Then, you do:@@ -55,8 +55,10 @@ runhaskell Setup.lhs build runhaskell Setup.lhs install </pre>-On Linux, the last command must be run as root. This will create the-executable <tt>xquery</tt>, which is the XQuery interpreter, and the+On linux, the last command must be run as root.+If you get an error during configuration that the readline package is missing, install+<a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/readline">readline</a> before HXQ.+HXQ consists of the executable <tt>xquery</tt>, which is the XQuery interpreter, and the HXQ library. To use the HXQ library in a Haskell program, simply <tt>import Text.XML.HXQ.XQuery</tt>. <p>@@ -161,4 +163,4 @@ <p> <hr> <p>-<address>Last modified: 10/25/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>+<address>Last modified: 10/27/08 by <a href="http://lambda.uta.edu/">Leonidas Fegaras</a></address>
src/Text/XML/HXQ/Compiler.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 02/15/08, last update: 10/20/08+- Creation: 02/15/08, last update: 11/14/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -14,19 +14,21 @@ --------------------------------------------------------------------------------------} -{-# OPTIONS_GHC -fth #-}+{-# LANGUAGE TemplateHaskell #-} + module Text.XML.HXQ.Compiler where import Control.Monad import Char(toLower) import List(sortBy)-import Language.Haskell.TH import XMLParse(parseDocument) import Text.XML.HXQ.Parser import Text.XML.HXQ.XTree import Text.XML.HXQ.Optimizer import Text.XML.HXQ.Functions+import Text.XML.HXQ.OptionalDB+import Language.Haskell.TH undef1 = [| error "Undefined XQuery context (.)" |]@@ -81,6 +83,11 @@ qName e = error ("Invalid QName: "++(show e)) +makeAttribute :: XSeq -> XSeq -> [(String,String)]+makeAttribute ac vc+ = if vc==[XNull] then [] else [(qName ac,showXS vc)]++ -- Each XPath predicate must calculate position() and last() from its input XSeq -- if last() is used, then the evaluation is blocking (need to store the whole input XSeq) compilePredicates :: [Ast] -> Q Exp -> Bool -> Q Exp@@ -127,6 +134,7 @@ in [| [ XFloat $x ] |] Astring s -> let x = litE (StringL s) in [| [ XText $x ] |]+ Ast "nonIO" [u] -> compile u context position last effective_axis Ast "context" [v,Astring dp,body] -> [| foldr (\x r -> $(compile body [| x |] position last dp)++r) [] $(compile v context position last effective_axis) |]@@ -140,13 +148,19 @@ Ast "step" (Avar "descendant_any":Ast "tags" tags:e:preds) -> let bc = compile e context position last effective_axis ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags)- in [| foldr (\x r -> $(compilePredicates preds [| descendant_any_with_tagged_children $ts x |] True)++r)- [] $bc |]+ in [| let v = $bc+ in if v==[XNull]+ then v+ else foldr (\x r -> $(compilePredicates preds [| descendant_any_with_tagged_children $ts x |] True)++r)+ [] v |] Ast "step" (Avar step:Astring tag:e:preds) -> let bc = compile e context position last effective_axis tc = litE (stringL tag)- in [| foldr (\x r -> $(compilePredicates preds [| $(findV step paths) $tc x |] True)++r)- [] $bc |]+ in [| let v = $bc+ in if v==[XNull]+ then v+ else foldr (\x r -> $(compilePredicates preds [| $(findV step paths) $tc x |] True)++r)+ [] v |] Ast "filter" (e:preds) -> compilePredicates preds (compile e context position last effective_axis) True Ast "predicate" [condition,body]@@ -155,6 +169,9 @@ else [] |] Ast "append" args -> [| appendText $(listE (map (\x -> compile x context position last effective_axis) args)) |]+ Ast "call" ((Avar f):_)+ | elem f ["insert","delete","replace"]+ -> error "Updates must be over XML data stored in databases" Ast "call" ((Avar f):args) -> callF f (map (\x -> compile x context position last effective_axis) args) Ast "construction" [Astring tag,id,parent,Ast "attributes" [],body]@@ -163,20 +180,20 @@ cid = compile id context position last effective_axis cparent = compile parent context position last effective_axis in [| let [XText vid] = $cid- [vparent] = $cparent- in [ XElem $ct [] (read vid) vparent $bc ] |]+ vparent = $cparent+ in [ XElem $ct [] (read vid) (if null vparent then parent_error else head vparent) $bc ] |] Ast "construction" [tag,id,parent,Ast "attributes" al,body] -> let alc = foldr (\(Ast "pair" [a,v]) r -> let ac = compile a context position last effective_axis vc = compile v context position last effective_axis- in [| (qName $ac,showXS $vc) : $r |]) [| [] |] al+ in [| (makeAttribute $ac $vc) ++ $r |]) [| [] |] al ct = compile tag context position last effective_axis bc = compile body context position last effective_axis cid = compile id context position last effective_axis cparent = compile parent context position last effective_axis in [| let [XText vid] = $cid- [vparent] = $cparent- in [ XElem (qName $ct) $alc (read vid) vparent $bc ] |]+ vparent = $cparent+ in [ XElem (qName $ct) $alc (read vid) (if null vparent then parent_error else head vparent) $bc ] |] Ast "let" [Avar var,source,body] -> do s <- compile source context position last effective_axis b <- compile body context position last effective_axis@@ -279,17 +296,20 @@ -> let bc = compileM e context position last effective_axis ts = listE (map (\(Avar tag) -> litE (stringL tag)) tags) in [| do vs <- $bc- foldr (\x r -> (liftM2 (++)) $(compilePredicatesM preds- [| descendant_any_with_tagged_children $ts x |] True) r)- (return []) vs |]+ if vs==[XNull]+ then return vs+ else foldr (\x r -> (liftM2 (++)) $(compilePredicatesM preds+ [| descendant_any_with_tagged_children $ts x |] True) r)+ (return []) vs |] Ast "step" (Avar step:Astring tag:e:preds) -> let bc = compileM e context position last effective_axis tc = litE (stringL tag) in [| do vs <- $bc- foldr (\x r -> (liftM2 (++)) $(compilePredicatesM preds- [| $(findV step paths) $tc x |] True) r)- (return []) vs |]-+ if vs==[XNull]+ then return vs+ else foldr (\x r -> (liftM2 (++)) $(compilePredicatesM preds+ [| $(findV step paths) $tc x |] True) r)+ (return []) vs |] Ast "filter" (e:preds) ->[| do vs <- $(compileM e context position last effective_axis) $(compilePredicatesM preds [| vs |] True) |]@@ -305,6 +325,25 @@ -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |]) [| return (appendText $(listE (map (\(n,_) -> varE n) binds))) |] binds+ Ast "call" [Avar "insert",e1,e2]+ -> let vc1 = compileM e1 context position last effective_axis+ vc2 = compileM e2 context position last effective_axis+ db = varE (mkName "_db")+ in [| do v1 <- $vc1+ v2 <- $vc2+ insertDB $db v1 v2 |]+ Ast "call" [Avar "delete",e]+ -> let vc = compileM e context position last effective_axis+ db = varE (mkName "_db")+ in [| do v <- $vc+ deleteDB $db v |]+ Ast "call" [Avar "replace",e1,e2]+ -> let vc1 = compileM e1 context position last effective_axis+ vc2 = compileM e2 context position last effective_axis+ db = varE (mkName "_db")+ in [| do v1 <- $vc1+ v2 <- $vc2+ replaceDB $db v1 v2 |] Ast "call" ((Avar f):args) -> let binds = zipWith (\i x -> (mkName ("x"++(show i)),x)) [1..(length args)] args in foldr (\(n,x) r -> [| $(compileM x context position last effective_axis) >>= $(lamE [varP n] r) |])@@ -316,14 +355,14 @@ cparent = compile parent context position last effective_axis in [| do b <- $bc let [XText vid] = $cid- [vparent] = $cparent- return [ XElem $ct [] (read vid) vparent b ] |]+ vparent = $cparent+ return [ XElem $ct [] (read vid) (if null vparent then parent_error else head vparent) b ] |] Ast "construction" [tag,id,parent,Ast "attributes" al,body] -> let alc = foldr (\(Ast "pair" [a,v]) r -> [| do ac <- $(compileM a context position last effective_axis) vc <- $(compileM v context position last effective_axis) s <- $r- return ((qName ac,showXS vc):s) |]) [| return [] |] al+ return ((makeAttribute ac vc)++s) |]) [| return [] |] al ct = compileM tag context position last effective_axis bc = compileM body context position last effective_axis cid = compile id context position last effective_axis@@ -332,8 +371,8 @@ c <- $ct b <- $bc let [XText vid] = $cid- [vparent] = $cparent- return [ XElem (qName c) a (read vid) vparent b ] |]+ vparent = $cparent+ return [ XElem (qName c) a (read vid) (if null vparent then parent_error else head vparent) b ] |] Ast "let" [Avar var,source,body] -> [| $(compileM source context position last effective_axis) >>= $(lamE [varP (mkName var)] (compileM body context position last effective_axis)) |]@@ -378,7 +417,9 @@ -- functions that need IO interaction (document reader, DB access, etc) ioSources :: [ String ]-ioSources = ["executeSQL","doc","fn:doc","sql","fn:sql","publish","fn:publish"]+ioSources+ = is ++ map (\x -> "fn:"++x) is+ where is = ["executeSQL","doc","sql","publish","insert","delete","replace"] -- steps that need the parent XTree link in evaluation (with a potential space leak)@@ -424,6 +465,7 @@ -- true if there is no need to lift to the IO monad noIO :: Ast -> Bool noIO (Ast nm _) | elem nm ioSources = False+noIO (Ast "call" (Avar nm:_)) | elem nm ioSources = False noIO (Ast n args) = all noIO args noIO _ = True @@ -433,6 +475,7 @@ = let (ast,_,_,ns) = pullIOSources query 0 False f x = case x of Ast nm _ | elem nm ["attributes","tags"] -> x+ Ast _ _ | noIO x -> Ast "nonIO" [x] _ -> case x of Ast "call" ((Avar nm):args)@@ -483,6 +526,7 @@ code = compileM ast undef1 undef2 undef3 "" rest = compileQueryM xs in foldl (\r (n,b,e) -> let d = lamE [varP (mkName n)] r+ bc = if b then [| True |] else [| False |] -- needed due to a bug in template haskell in case e of Avar m -> [| $d $(varE (mkName m)) |] Ast "prepareSQL" [Astring sql]@@ -491,7 +535,7 @@ $(litE (StringL sql))) >>= $d |] _ -> [| do let [XText f] = $(compileAst e) doc <- readFile f- $d [materialize b (parseDocument doc)] |])+ $d [materialize $bc (parseDocument doc)] |]) [| (liftM2 (++)) $code $rest |] ns compileQueryM [] = [| return [] |] @@ -509,6 +553,6 @@ -- | Run an XQuery that reads XML documents and queries databases.--- When evaluated, it returns (IConnection conn) => conn -> IO XSeq.+-- When evaluated, it returns @(IConnection conn) => conn -> IO XSeq@. xqdb :: String -> Q Exp xqdb query = lamE [varP (mkName "_db")] (compileQueryM (parse (scan query)))
src/Text/XML/HXQ/Functions.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 08/15/08, last update: 08/18/08+- Creation: 08/15/08, last update: 11/18/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -14,15 +14,17 @@ --------------------------------------------------------------------------------------} -{-# OPTIONS_GHC -fth -fbang-patterns #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE BangPatterns #-} + module Text.XML.HXQ.Functions where import Data.List(foldl') import Char(isDigit)-import Language.Haskell.TH import HXML(AttList) import Text.XML.HXQ.XTree+import Language.Haskell.TH {--------------- XPath Steps ---------------------------------------------------------}@@ -41,7 +43,7 @@ child_step tag x = case x of XElem _ _ _ _ bs- -> foldl' (\s b -> case b of+ -> foldr (\b s -> case b of XElem t _ _ _ _ | (t==tag || tag=="*") -> b:s _ -> s) [] bs _ -> []@@ -68,7 +70,7 @@ -- After examining 100 children it gives up: this avoids space leaks descendant_any_with_tagged_children :: [Tag] -> XTree -> XSeq descendant_any_with_tagged_children tags (x@(XElem t _ _ _ cs))- | all (\tag -> foldl' (\s b -> case b of+ | all (\tag -> foldr (\b s -> case b of (XElem k _ _ _ _) -> s || k == tag _ -> s) False cs100) tags = x:(concatMap (descendant_any_with_tagged_children tags) cs)@@ -82,18 +84,18 @@ attribute_step :: Tag -> XTree -> XSeq attribute_step attr x = case x of- XElem _ al _ _ _ -> foldl' (\s (a,v) -> if a==attr || attr=="*"- then (XText v):s- else s) [] al+ XElem _ al _ _ _ -> foldr (\(a,v) s -> if a==attr || attr=="*"+ then (XText v):s+ else s) [] al _ -> [] -- XPath step //@attr or //@* attribute_descendant_step :: Tag -> XTree -> XSeq attribute_descendant_step attr (x@(XElem _ al _ _ cs))- = foldl' (\s (a,v) -> if a==attr || attr=="*"- then (XText v):s- else s)+ = foldr (\(a,v) s -> if a==attr || attr=="*"+ then (XText v):s+ else s) (concatMap (attribute_descendant_step attr) cs) al attribute_descendant_step _ _ = [] @@ -237,9 +239,9 @@ text :: XSeq -> XSeq-text xs = foldl' (\r x -> case x of+text xs = foldr (\x r -> case x of XElem _ _ _ _ zs- -> (filter (\a -> case a of XText _ -> True; XInt _ -> True;+ -> (filter (\a -> case a of XText _ -> True; XInt _ -> True; XNull -> True; XFloat _ -> True; XBool _ -> True; _ -> False) zs)++r XText _ -> x:r XInt _ -> x:r@@ -265,7 +267,7 @@ toNum :: XSeq -> XSeq-toNum xs = foldl' (\r x -> case x of+toNum xs = foldr (\x r -> case x of XInt n -> x:r XFloat n -> x:r XText s -> case readNum s of@@ -432,16 +434,17 @@ -- make a function call callF :: Tag -> Function-callF fname args = case filter (\(n,_,_) -> n == fname || ("fn:"++n)==fname) functions of- (_,len,f):_ -> if (length args) == len- then f args- else error ("wrong number of arguments in function call: " ++ fname)- _ -> -- otherwise, it must be a Haskell function of type (XSeq,...,XSeq) -> XSeq- let itp = case args of- [] -> [t| () |]- [_] -> [t| XSeq |]- _ -> foldr (\_ r -> appT r [t| XSeq |]) (appT (tupleT (length args)) [t| XSeq |])- (tail args)- fn = sigE (varE (mkName fname))- (appT (appT arrowT itp) [t| XSeq |])- in appE fn (tupE args)+callF fname args+ = case filter (\(n,_,_) -> n == fname || ("fn:"++n)==fname) functions of+ (_,len,f):_ -> if (length args) == len+ then f args+ else error ("wrong number of arguments in function call: " ++ fname)+ _ -> -- otherwise, it must be a Haskell function of type (XSeq,...,XSeq) -> XSeq+ let itp = case args of+ [] -> [t| () |]+ [_] -> [t| XSeq |]+ _ -> foldr (\_ r -> appT r [t| XSeq |]) (appT (tupleT (length args)) [t| XSeq |])+ (tail args)+ fn = sigE (varE (mkName fname))+ (appT (appT arrowT itp) [t| XSeq |])+ in appE fn (tupE args)
src/Text/XML/HXQ/Interpreter.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 03/22/08, last update: 10/20/08+- Creation: 03/22/08, last update: 11/14/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -14,7 +14,8 @@ --------------------------------------------------------------------------------------} -{-# OPTIONS_GHC -fth -fglasgow-exts #-}+{-# OPTIONS_GHC -fglasgow-exts #-}+{-# LANGUAGE TemplateHaskell #-} module Text.XML.HXQ.Interpreter where@@ -104,12 +105,16 @@ -> eval (Ast "step" (Avar effective_axis:tag:Avar ".":preds)) context position last "" env fncs Ast "step" (Avar "descendant_any":Ast "tags" tags:e:preds) -> let ts = map (\(Avar tag) -> tag) tags- in foldr (\x r -> (applyPredicates preds (descendant_any_with_tagged_children ts x) True env fncs)++r)- [] (eval e context position last effective_axis env fncs)+ v = eval e context position last effective_axis env fncs+ in if v==[XNull]+ then v+ else foldr (\x r -> (applyPredicates preds (descendant_any_with_tagged_children ts x) True env fncs)++r) [] v Ast "step" (Avar step:Astring tag:e:preds) -> let step_fnc = findV step pathFunctions- in foldr (\x r -> (applyPredicates preds (step_fnc tag x) True env fncs)++r)- [] (eval e context position last effective_axis env fncs)+ v = eval e context position last effective_axis env fncs+ in if v==[XNull]+ then v+ else foldr (\x r -> (applyPredicates preds (step_fnc tag x) True env fncs)++r) [] v Ast "filter" (e:preds) -> applyPredicates preds (eval e context position last effective_axis env fncs) True env fncs Ast "predicate" [condition,body]@@ -118,32 +123,37 @@ else [] Ast "append" args -> appendText (map (\x -> eval x context position last effective_axis env fncs) args)+ Ast "call" ((Avar f):_)+ | elem f ["insert","delete","replace"]+ -> error "Updates must be over XML data stored in databases" Ast "call" ((Avar fname):args)- -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of- [(_,len,f)] -> if (length args) == len- then f (map (\x -> eval x context position last effective_axis env fncs) args)- else error ("Wrong number of arguments in system call: "++fname)- _ -> case filter (\(n,_,_) -> n == fname) fncs of- (_,params,body):_ -> if (length params) == (length args)- then eval body context undefv2 undefv3 ""- ((zipWith (\p a -> (p,eval a context position last effective_axis env fncs))- params args)++env) fncs- else error ("Wrong number of arguments in function call: "++fname)- _ -> error ("Undefined function: "++fname)+ -> let vs = map (\x -> eval x context position last effective_axis env fncs) args+ in case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of+ [(_,len,f)] -> if (length args) == len+ then f vs+ else error ("Wrong number of arguments in system call: "++fname)+ _ -> case filter (\(n,_,_) -> n == fname) fncs of+ (_,params,body):_+ -> if (length params) == (length args)+ then eval body context undefv2 undefv3 ""+ ((zipWith (\p v -> (p,v)) params vs)++env) fncs+ else error ("Wrong number of arguments in function call: "++fname)+ _ -> error ("Undefined function: "++fname) Ast "construction" [Astring tag,id,parent,Ast "attributes" [],body] -> let [XText vid] = eval id context position last effective_axis env fncs- [vparent] = eval parent context position last effective_axis env fncs- in [ XElem tag [] (read vid) vparent (eval body context position last effective_axis env fncs) ]+ vparent = eval parent context position last effective_axis env fncs+ in [ XElem tag [] (read vid) (if null vparent then parent_error else head vparent)+ (eval body context position last effective_axis env fncs) ] Ast "construction" [tag,id,parent,Ast "attributes" al,body]- -> let alc = map (\(Ast "pair" [a,v])+ -> let alc = concatMap (\(Ast "pair" [a,v]) -> let ac = eval a context position last effective_axis env fncs vc = eval v context position last effective_axis env fncs- in (qName ac,showXS vc)) al+ in if vc==[XNull] then [] else [(qName ac,showXS vc)]) al ct = eval tag context position last effective_axis env fncs bc = eval body context position last effective_axis env fncs [XText vid] = eval id context position last effective_axis env fncs- [vparent] = eval parent context position last effective_axis env fncs- in [ XElem (qName ct) alc (read vid) vparent bc ]+ vparent = eval parent context position last effective_axis env fncs+ in [ XElem (qName ct) alc (read vid) (if null vparent then parent_error else head vparent) bc ] Ast "let" [Avar var,source,body] -> eval body context position last effective_axis ((var,eval source context position last effective_axis env fncs):env) fncs@@ -178,38 +188,38 @@ -- The monadic applyPredicates that propagates IO state-applyPredicatesM :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> Statements -> IO XSeq-applyPredicatesM [] xs _ _ _ _ = return $! xs-applyPredicatesM ((Aint n):preds) xs _ env fncs stmts -- shortcut that improves laziness- = applyPredicatesM preds [xs !! (n-1)] True env fncs stmts-applyPredicatesM (pred:preds) xs True env fncs stmts -- top-k like+applyPredicatesM :: [Ast] -> XSeq -> Bool -> Environment -> Functions -> Connection -> Statements -> IO XSeq+applyPredicatesM [] xs _ _ _ _ _ = return $! xs+applyPredicatesM ((Aint n):preds) xs _ env fncs db stmts -- shortcut that improves laziness+ = applyPredicatesM preds [xs !! (n-1)] True env fncs db stmts+applyPredicatesM (pred:preds) xs True env fncs db stmts -- top-k like | maxPosition pathPosition pred > 0- = applyPredicatesM (pred:preds) (take (maxPosition pathPosition pred) xs) False env fncs stmts-applyPredicatesM (pred:preds) xs _ env fncs stmts+ = applyPredicatesM (pred:preds) (take (maxPosition pathPosition pred) xs) False env fncs db stmts+applyPredicatesM (pred:preds) xs _ env fncs db stmts | containsLast pred -- blocking: use only when last() is used in the predicate = do let last = length xs- vs <- foldir (\x i r -> do vs <- evalM pred x i last "" env fncs stmts+ vs <- foldir (\x i r -> do vs <- evalM pred x i last "" env fncs db stmts s <- r return $! (if case vs of [XInt k] -> k == i -- indexing b -> conditionTest b then x:s else s)) (return []) xs 1- applyPredicatesM preds vs True env fncs stmts-applyPredicatesM (pred:preds) xs _ env fncs stmts- = do vs <- foldir (\x i r -> do vs <- evalM pred x i undefv3 "" env fncs stmts+ applyPredicatesM preds vs True env fncs db stmts+applyPredicatesM (pred:preds) xs _ env fncs db stmts+ = do vs <- foldir (\x i r -> do vs <- evalM pred x i undefv3 "" env fncs db stmts s <- r return $! (if case vs of [XInt k] -> k == i -- indexing b -> conditionTest b then x:s else s)) (return []) xs 1- applyPredicatesM preds vs True env fncs stmts+ applyPredicatesM preds vs True env fncs db stmts -- The monadic XQuery interpreter; it is like eval but has plumbing to propagate IO state-evalM :: Ast -> XTree -> Int -> Int -> String -> Environment -> Functions -> Statements -> IO XSeq-evalM e context position last effective_axis env fncs stmts+evalM :: Ast -> XTree -> Int -> Int -> String -> Environment -> Functions -> Connection -> Statements -> IO XSeq+evalM e context position last effective_axis env fncs db stmts = case e of Avar "." -> return $! [ context ] Avar v -> return $! (findV v env)@@ -219,90 +229,108 @@ -- for non-IO XQuery, use the regular eval Ast "nonIO" [u] -> return $! (eval u context position last effective_axis env fncs) Ast "context" [v,Astring dp,body]- -> do vs <- evalM v context position last effective_axis env fncs stmts- foldr (\x r -> (liftM2 (++)) (evalM body x position last dp env fncs stmts) r)+ -> do vs <- evalM v context position last effective_axis env fncs db stmts+ foldr (\x r -> (liftM2 (++)) (evalM body x position last dp env fncs db stmts) r) (return []) vs Ast "call" [Avar "position"] -> return $! [XInt position] Ast "call" [Avar "last"] -> return $! [XInt last] Ast "step" (Avar "child":tag:Avar ".":preds) | effective_axis /= ""- -> evalM (Ast "step" (Avar effective_axis:tag:Avar ".":preds)) context position last "" env fncs stmts+ -> evalM (Ast "step" (Avar effective_axis:tag:Avar ".":preds)) context position last "" env fncs db stmts Ast "step" (Avar "descendant_any":Ast "tags" tags:e:preds)- -> do vs <- evalM e context position last effective_axis env fncs stmts+ -> do vs <- evalM e context position last effective_axis env fncs db stmts let ts = map (\(Avar tag) -> tag) tags- foldr (\x r -> (liftM2 (++)) (applyPredicatesM preds (descendant_any_with_tagged_children ts x) True env fncs stmts) r)- (return []) vs+ if vs==[XNull]+ then return vs+ else foldr (\x r -> (liftM2 (++)) (applyPredicatesM preds (descendant_any_with_tagged_children ts x)+ True env fncs db stmts) r)+ (return []) vs Ast "step" (Avar step:Astring tag:e:preds) -> let step_fnc = findV step pathFunctions- in do vs <- evalM e context position last effective_axis env fncs stmts- foldr (\x r -> (liftM2 (++)) (applyPredicatesM preds (step_fnc tag x) True env fncs stmts) r)- (return []) vs+ in do vs <- evalM e context position last effective_axis env fncs db stmts+ if vs==[XNull]+ then return vs+ else foldr (\x r -> (liftM2 (++)) (applyPredicatesM preds (step_fnc tag x)+ True env fncs db stmts) r)+ (return []) vs Ast "filter" (e:preds)- -> do vs <- evalM e context position last effective_axis env fncs stmts- applyPredicatesM preds vs True env fncs stmts+ -> do vs <- evalM e context position last effective_axis env fncs db stmts+ applyPredicatesM preds vs True env fncs db stmts Ast "predicate" [condition,body]- -> do eb <- evalM condition undefv1 undefv2 undefv3 "" env fncs stmts+ -> do eb <- evalM condition undefv1 undefv2 undefv3 "" env fncs db stmts if conditionTest eb- then evalM body context position last effective_axis env fncs stmts+ then evalM body context position last effective_axis env fncs db stmts else return [] Ast "executeSQL" [Avar var,args]- -> do as <- evalM args context position last effective_axis env fncs stmts+ -> do as <- evalM args context position last effective_axis env fncs db stmts executeSQL (findV var stmts) as+ Ast "append" args+ -> (liftM appendText) (mapM (\x -> evalM x context position last effective_axis env fncs db stmts) args) Ast "call" [Avar nm,c,t,e] -- this is the only lazy function | elem nm ["if","fn:if"]- -> do ce <- evalM c context position last effective_axis env fncs stmts- evalM (if conditionTest ce then t else e) context position last effective_axis env fncs stmts- Ast "append" args- -> (liftM appendText) (mapM (\x -> evalM x context position last effective_axis env fncs stmts) args)+ -> do ce <- evalM c context position last effective_axis env fncs db stmts+ evalM (if conditionTest ce then t else e) context position last effective_axis env fncs db stmts+ Ast "call" [Avar "insert",e1,e2]+ -> do v1 <- evalM e1 context position last effective_axis env fncs db stmts+ v2 <- evalM e2 context position last effective_axis env fncs db stmts+ insertDB db v1 v2+ Ast "call" [Avar "delete",e]+ -> do v <- evalM e context position last effective_axis env fncs db stmts+ deleteDB db v+ Ast "call" [Avar "replace",e1,e2]+ -> do v1 <- evalM e1 context position last effective_axis env fncs db stmts+ v2 <- evalM e2 context position last effective_axis env fncs db stmts+ replaceDB db v1 v2 Ast "call" ((Avar fname):args) -- Note: strict function application -> case filter (\(n,_,_) -> n == fname || ("fn:"++n) == fname) systemFunctions of [(_,len,f)] -> if (length args) == len- then (liftM f) (mapM (\x -> evalM x context position last effective_axis env fncs stmts) args)+ then do vs <- mapM (\x -> evalM x context position last effective_axis env fncs db stmts) args+ return $ f vs else error ("Wrong number of arguments in system call: "++fname) _ -> case filter (\(n,_,_) -> n == fname) fncs of (_,params,body):_ -> if (length params) == (length args)- then do vs <- mapM (\a -> evalM a context position last effective_axis env fncs stmts) args+ then do vs <- mapM (\a -> evalM a context position last effective_axis env fncs db stmts) args evalM body context undefv2 undefv3 ""- ((zipWith (\p a -> (p,a)) params vs)++env) fncs stmts+ ((zipWith (\p a -> (p,a)) params vs)++env) fncs db stmts else error ("Wrong number of arguments in function call: "++fname) _ -> error ("Undefined function: "++fname) Ast "construction" [Astring tag,id,parent,Ast "attributes" [],body]- -> do b <- evalM body context position last effective_axis env fncs stmts- [XText vid] <- evalM id context position last effective_axis env fncs stmts- [vparent] <- evalM parent context position last effective_axis env fncs stmts- return $! [ XElem tag [] (read vid) vparent b ]+ -> do b <- evalM body context position last effective_axis env fncs db stmts+ [XText vid] <- evalM id context position last effective_axis env fncs db stmts+ vparent <- evalM parent context position last effective_axis env fncs db stmts+ return $! [ XElem tag [] (read vid) (if null vparent then parent_error else head vparent) b ] Ast "construction" [tag,id,parent,Ast "attributes" al,body]- -> do alc <- mapM (\(Ast "pair" [a,v])- -> do ac <- evalM a context position last effective_axis env fncs stmts- vc <- evalM v context position last effective_axis env fncs stmts- return $! (qName ac,showXS vc)) al- ct <- evalM tag context position last effective_axis env fncs stmts- bc <- evalM body context position last effective_axis env fncs stmts- [XText vid] <- evalM id context position last effective_axis env fncs stmts- [vparent] <- evalM parent context position last effective_axis env fncs stmts- return $! [ XElem (qName ct) alc (read vid) vparent bc ]+ -> do alc <- foldM (\r (Ast "pair" [a,v])+ -> do ac <- evalM a context position last effective_axis env fncs db stmts+ vc <- evalM v context position last effective_axis env fncs db stmts+ if vc==[XNull] then return r else return $! (qName ac,showXS vc):r) [] al+ ct <- evalM tag context position last effective_axis env fncs db stmts+ bc <- evalM body context position last effective_axis env fncs db stmts+ [XText vid] <- evalM id context position last effective_axis env fncs db stmts+ vparent <- evalM parent context position last effective_axis env fncs db stmts+ return $! [ XElem (qName ct) alc (read vid) (if null vparent then parent_error else head vparent) bc ] Ast "let" [Avar var,source,body]- -> do s <- evalM source context position last effective_axis env fncs stmts- evalM body context position last effective_axis ((var,s):env) fncs stmts+ -> do s <- evalM source context position last effective_axis env fncs db stmts+ evalM body context position last effective_axis ((var,s):env) fncs db stmts Ast "for" [Avar var,Avar "$",source,body] -- a for-loop without an index- -> do vs <- evalM source context position last effective_axis env fncs stmts- foldr (\a r -> (liftM2 (++)) (evalM body a undefv2 undefv3 "" ((var,[a]):env) fncs stmts) r)+ -> do vs <- evalM source context position last effective_axis env fncs db stmts+ foldr (\a r -> (liftM2 (++)) (evalM body a undefv2 undefv3 "" ((var,[a]):env) fncs db stmts) r) (return []) vs Ast "for" [Avar var,Avar ivar,source,body] -- a for-loop with an index -> do let p = maxPosition (Avar ivar) body ns = if p > 0 -- there is a top-k like restriction then Ast "step" [source,Ast "call" [Avar "<=",pathPosition,Aint p]] else source - vs <- evalM ns context position last effective_axis env fncs stmts- foldir (\a i r -> (liftM2 (++)) (evalM body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs stmts) r)+ vs <- evalM ns context position last effective_axis env fncs db stmts+ foldir (\a i r -> (liftM2 (++)) (evalM body a i undefv3 "" ((var,[a]):(ivar,[XInt i]):env) fncs db stmts) r) (return []) vs 1 Ast "sortTuple" (exp:orderBys) -- prepare each FLWOR tuple for sorting- -> do vs <- evalM exp context position last effective_axis env fncs stmts- os <- mapM (\a -> evalM a context position last effective_axis env fncs stmts) orderBys+ -> do vs <- evalM exp context position last effective_axis env fncs db stmts+ os <- mapM (\a -> evalM a context position last effective_axis env fncs db stmts) orderBys return $! [ XElem "" [] 0 parent_error (foldl (\r a -> r++[XElem "" [] 0 parent_error (text a)]) [XElem "" [] 0 parent_error vs] os) ] Ast "sort" (exp:ordList) -- blocking- -> do vs <- evalM exp context position last effective_axis env fncs stmts+ -> do vs <- evalM exp context position last effective_axis env fncs db stmts let ce = map (\(XElem _ _ _ _ xs) -> map (\(XElem _ _ _ _ ys) -> ys) xs) vs ordering = foldr (\(Avar ord) r (x:xs) (y:ys) -> case compareXSeqs (ord == "ascending") x y of@@ -341,16 +369,16 @@ evalInput eval nvs nfs -evalQueryM :: [Ast] -> Environment -> Functions -> (String -> IO Statement) -> Bool -> IO (XSeq,Environment,Functions)-evalQueryM [] variables functions dbmapper verbose+evalQueryM :: [Ast] -> Environment -> Functions -> Connection -> Bool -> IO (XSeq,Environment,Functions)+evalQueryM [] variables functions db verbose = return $! ([],variables,functions)-evalQueryM (query:xs) variables functions dbmapper verbose+evalQueryM (query:xs) variables functions db verbose = case query of Ast "function" ((Avar f):b:args)- -> evalQueryM xs variables ((f,map (\(Avar v) -> v) args,optimize b):functions) dbmapper verbose+ -> evalQueryM xs variables ((f,map (\(Avar v) -> v) args,optimize b):functions) db verbose Ast "variable" [Avar v,u]- -> do uv <- evalM (optimize u) undefv1 undefv2 undefv3 "" variables functions []- evalQueryM xs ((v,uv):variables) functions dbmapper verbose+ -> do uv <- evalM (optimize u) undefv1 undefv2 undefv3 "" variables functions db []+ evalQueryM xs ((v,uv):variables) functions db verbose _ -> do let opt = optimize query (ast,ns) = liftIOSources opt if verbose@@ -373,23 +401,23 @@ stmts <- foldr (\(n,_,s) r -> case s of Ast "prepareSQL" [Astring sql] -> do stmts <- r- t <- dbmapper sql+ t <- prepareSQL db sql return $! ((n,t):stmts) _ -> r) (return []) ns- result <- evalM ast undefv1 undefv2 undefv3 "" (env++variables) functions stmts- (rest,renv,rfuns) <- evalQueryM xs variables functions dbmapper verbose+ result <- evalM ast undefv1 undefv2 undefv3 "" (env++variables) functions db stmts+ (rest,renv,rfuns) <- evalQueryM xs variables functions db verbose return $! (result++rest,renv,rfuns) -xqueryE :: String -> Environment -> Functions -> (String -> IO Statement) -> Bool -> IO (XSeq,Environment,Functions)-xqueryE query variables functions dbmapper verbose- = evalQueryM (parse (scan query)) variables functions dbmapper verbose+xqueryE :: String -> Environment -> Functions -> Connection -> Bool -> IO (XSeq,Environment,Functions)+xqueryE query variables functions db verbose+ = evalQueryM (parse (scan query)) variables functions db verbose -- | Evaluate the XQuery using the interpreter. xquery :: String -> IO XSeq-xquery query = do (u,_,_) <- xqueryE query [] [] (\sql -> error "No database connectivity") False+xquery query = do (u,_,_) <- xqueryE query [] [] (error "No database connectivity") False return $! u @@ -400,12 +428,12 @@ -- | Evaluate the XQuery with database connectivity using the interpreter.-xqueryDB :: (IConnection conn) => String -> conn -> IO XSeq-xqueryDB query db = do (u,_,_) <- xqueryE query [] [] (prepareSQL db) False+xqueryDB :: String -> Connection -> IO XSeq+xqueryDB query db = do (u,_,_) <- xqueryE query [] [] db False return $! u -- | Read an XQuery with database connectivity from a file and run it using the interpreter.-xfileDB :: (IConnection conn) => String -> conn -> IO XSeq+xfileDB :: String -> Connection -> IO XSeq xfileDB file db = do query <- readFile file xqueryDB query db
src/Text/XML/HXQ/Optimizer.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 05/01/08, last update: 10/25/08+- Creation: 05/01/08, last update: 11/23/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -23,7 +23,6 @@ import Text.XML.HXQ.Parser import Text.XML.HXQ.XTree import Text.XML.HXQ.OptionalDB-import Debug.Trace empty = Ast "call" [Avar "empty"]@@ -174,7 +173,7 @@ = case collect_attributes content of (nc,(Ast "pair" [Astring "_id",id]):(Ast "pair" [Astring "_parent",parent]):attrs) -> simplify (Ast "construction" [tag,id,parent,Ast "attributes" (as++attrs),nc])- (nc,attrs) -> simplify (Ast "construction" [tag,Astring "0",Aint 0,Ast "attributes" (as++attrs),nc])+ (nc,attrs) -> simplify (Ast "construction" [tag,Astring "0",Ast "call" [Avar "empty"],Ast "attributes" (as++attrs),nc]) -- if //* collect all children tagnames to use descendant_any simplify (Ast "for" [Avar var,i,Ast "step" (Avar "descendant-or-self":Astring "*":path:preds),body]) | not (null ((tagged_children var body))) || any (not . null . (tagged_children ".")) preds@@ -274,12 +273,12 @@ -> orAll (map (predToSQL tables) xs) Ast "call" [Avar "text",x] -> predToSQL tables x- Ast "call" [Avar cmp,Ast "for" [Avar v,i,Ast "call" [Avar "SQL",_,Ast "call" ((Avar "from"):t),pred],x],y]+ Ast "call" [Avar cmp,Ast "for" [Avar v,i,Ast "call" [Avar "SQL",_,Ast "call" ((Avar "tables"):t),pred],x],y] | any (\(f,_) -> f==cmp) sqlComparisson -> let ts = [ x | Avar x <- t ] (p,ps,ts') = predToSQL (tables++ts) (call "and" [Ast "call" [Avar cmp,x,y],pred]) in (p,ps,union ts' ts)- Ast "call" [Avar cmp,x,Ast "for" [Avar v,i,Ast "call" [Avar "SQL",_,Ast "call" ((Avar "from"):t),pred]],y]+ Ast "call" [Avar cmp,x,Ast "for" [Avar v,i,Ast "call" [Avar "SQL",_,Ast "call" ((Avar "tables"):t),pred]],y] | any (\(f,_) -> f==cmp) sqlComparisson -> let ts = [ x | Avar x <- t ] (p,ps,ts') = predToSQL (tables++ts) (call "and" [Ast "call" [Avar cmp,x,y],pred])@@ -346,9 +345,10 @@ then "select * from "++ts else "select "++cs++" from "++ts,[]) else let (p,args,nts) = predToSQL (tables++tnames) pred+ pp = if p=="" then "" else " where "++p in (if null cs- then "select * from "++combine (union tnames nts)++" where "++p- else "select "++cs++" from "++combine (union tnames nts)++" where "++p,args)+ then "select * from "++combine (union tnames nts)++pp+ else "select "++cs++" from "++combine (union tnames nts)++pp,args) findAttr :: String -> [Ast] -> Ast@@ -525,6 +525,8 @@ -- ((),x) -> x Ast "call" [Avar "concatenate",Ast "call" [Avar "empty"],x] -> norm x+ Ast "append" ((Ast "call" [Avar "empty"]):xs)+ -> norm (Ast "append" xs) Ast "call" [Avar "=",x,y] | x == empty && y == empty -> (true,True,count)@@ -614,48 +616,55 @@ -> norm (Ast "call" [Avar "concatenate",predicates (findAttr tag as) preds, Ast "step" (Avar "attribute_descendant":Astring tag:concatenateAll x:preds)]) -- SQL folding- Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],- Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],+ Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "tables"):f1),pred1],+ Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "tables"):f2),pred2], b]] | occurs v1 b == 0 -> norm (Ast "for" [Avar v2,Avar "$", Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):(s1++s2)),- Ast "call" ((Avar "from"):(f1++f2)),Ast "call" [Avar "and",pred1,pred2]],+ Ast "call" ((Avar "tables"):(f1++f2)),Ast "call" [Avar "and",pred1,pred2]], b])- Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "from"):tables),pred1],+ Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "tables"):tables),pred1], Ast "step" (Avar "self":Astring "*":x:pred2)] | splitSqlPredicate [ v | Avar v <- tables ] (andAll pred2) /= Nothing -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- tables ] (andAll pred2) in norm (Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),- Ast "call" ((Avar "from"):tables),Ast "call" [Avar "and",pred1,pred3]],+ Ast "call" ((Avar "tables"):tables),Ast "call" [Avar "and",pred1,pred3]], Ast "step" (Avar "self":Astring "*":x:pred4)])- Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],- Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],+ Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "tables"):f1),pred1],+ Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "tables"):f2),pred2], Ast "step" (Avar "self":Astring "*":b:predd)]] | occurs v1 b == 0 && splitSqlPredicate [ v | Avar v <- f1 ] (andAll predd) /= Nothing -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- f1 ] (andAll predd) in norm (Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),- Ast "call" ((Avar "from"):f1),Ast "call" [Avar "and",pred1,pred3]],+ Ast "call" ((Avar "tables"):f1),Ast "call" [Avar "and",pred1,pred3]], Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),- Ast "call" ((Avar "from"):f2),pred2],+ Ast "call" ((Avar "tables"):f2),pred2], Ast "step" (Avar "self":Astring"*":b:pred4)]])- Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "from"):tables),pred1],+ Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),Ast "call" ((Avar "tables"):tables),pred1], Ast "predicate" [pred2,x]] | splitSqlPredicate [ v | Avar v <- tables ] pred2 /= Nothing -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- tables ] pred2 in norm (Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s),- Ast "call" ((Avar "from"):tables),Ast "call" [Avar "and",pred1,pred3]],+ Ast "call" ((Avar "tables"):tables),Ast "call" [Avar "and",pred1,pred3]], Ast "step" (Avar "self":Astring"*":x:pred4)])- Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "from"):f1),pred1],- Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "from"):f2),pred2],+ Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),Ast "call" ((Avar "tables"):f1),pred1],+ Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),Ast "call" ((Avar "tables"):f2),pred2], Ast "predicate" [predd,b]]] | occurs v1 b == 0 && splitSqlPredicate [ v | Avar v <- f1 ] predd /= Nothing -> let Just(pred3,pred4) = splitSqlPredicate [ v | Avar v <- f1 ] predd in norm (Ast "for" [Avar v1,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s1),- Ast "call" ((Avar "from"):f1),Ast "call" [Avar "and",pred1,pred3]],+ Ast "call" ((Avar "tables"):f1),Ast "call" [Avar "and",pred1,pred3]], Ast "for" [Avar v2,Avar "$",Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):s2),- Ast "call" ((Avar "from"):f2),pred2],+ Ast "call" ((Avar "tables"):f2),pred2], Ast "step" (Avar "self":Astring"*":b:pred4)]])+-- ignore children from insertion destination+ Ast "destination" [Ast "for" [v,i,Ast "call" (Avar "SQL":sql),body]]+ -> norm (Ast "for" [v,i,Ast "call" (Avar "SQL":sql),Ast "destination" [body]])+ Ast "destination" [Ast "construction" [t,id,p,al,_]]+ -> norm (Ast "construction" [t,id,p,al,Ast "append" []])+ Ast "destination" [Ast f args]+ -> norm (Ast f args) -- default Ast n args -> let (r,b,c) = foldr (\a (r,b,c) -> let (x,s,i) = normalize a b c in (x:r,s,i))@@ -673,11 +682,11 @@ foldSQL e = case e of Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" [Avar "select"],- Ast "call" ((Avar "from"):tables),pred],body]+ Ast "call" ((Avar "tables"):tables),pred],body] | any (\(Avar x) -> x==v) tables -> foldSQL (Ast "for" [Avar v,Avar "$",Ast "call" [Avar "SQL",Ast "call" [Avar "select",Avar (v++".*")],- Ast "call" ((Avar "from"):tables),pred],body])- Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):cols),Ast "call" ((Avar "from"):tables),pred]+ Ast "call" ((Avar "tables"):tables),pred],body])+ Ast "call" [Avar "SQL",Ast "call" ((Avar "select"):cols),Ast "call" ((Avar "tables"):tables),pred] -> let (sql,args) = makeSQL [] tables pred cols in Ast "call" [Avar "sql",Astring sql,concatenateAll args] Ast n args -> Ast n (map foldSQL args)
src/Text/XML/HXQ/Parser.hs view
@@ -191,21 +191,21 @@ happyActOffsets :: HappyAddr-happyActOffsets = HappyA# "\x45\x00\x45\x00\x00\x00\xee\x02\x00\x00\xd7\x01\x98\x00\x00\x00\x00\x00\x3e\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\xc4\x02\xc4\x02\x8b\x00\x5d\x00\x8b\x00\x8b\x00\x8b\x00\x00\x00\xcb\x02\x8b\x00\xc3\x02\xc3\x02\x2f\x00\x2b\x00\xfb\xff\xc2\x02\xf4\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\xbe\x02\x00\x00\x17\x00\xc9\x02\xba\x02\xdd\xff\x00\x00\xea\x02\xb8\x02\x8b\x00\xb6\x02\xe3\x02\xb3\x02\x8b\x00\xbf\x02\xbd\x02\xf3\xff\xb4\x02\x00\x00\xa5\x02\x00\x00\x00\x00\xd7\x01\xad\x00\x6c\x00\x00\x00\x03\x01\x44\x00\xea\xff\x29\x00\x8b\x00\x00\x00\x88\x00\x00\x00\xb5\x02\x9b\x02\x9b\x02\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\x8b\x00\xff\xff\x4e\x00\x00\x00\x42\x02\x42\x02\x42\x02\x74\x02\x42\x02\x5b\x02\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x1f\x01\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x00\xf9\x00\xb1\x08\xd7\x01\xb0\x02\xad\x02\xcd\x02\xa2\x02\x00\x00\x73\x00\x8b\x00\x58\x00\x1f\x00\x91\x02\x00\x00\x00\x00\xac\x00\x8e\x02\x00\x00\x8b\x00\x9c\x00\x83\x02\x8b\x00\x8b\x00\x8b\x00\x00\x00\x8b\x00\x00\x00\xb1\x02\x89\x02\x8b\x00\x7d\x02\x7d\x02\x8b\x00\xbb\x01\xb2\x02\x8b\x00\x80\x02\x9e\x01\xa8\x02\x8b\x00\x29\x00\x00\x00\xf5\xff\x81\x02\xa4\x02\x68\x02\x00\x00\x0a\x00\x8b\x00\x00\x00\x00\x00\x71\x02\xa7\x00\x00\x00\x9c\x02\xa1\x00\x00\x00\x98\x02\xd7\x01\x72\x02\x76\x02\xd7\x01\x8a\x02\xfc\xff\xd7\x01\x26\x01\xd7\x01\xd7\x01\xed\xff\x00\x00\xfb\xff\xa6\x00\x00\x00\x47\x01\x00\x00\x00\x00\x7f\x02\x9e\x00\x00\x00\x8b\x00\x11\x02\x00\x00\x00\x00\x8b\x00\x8b\x00\x00\x00\xd7\x01\xdd\x00\x20\x02\x67\x02\x9d\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb\xff\x00\x00\x41\x02\x8b\x00\x07\x02\x8b\x00\x00\x00\xfc\xff\x8b\x00\x8b\x00\x8b\x00\x00\x00\x8b\x00\x00\x00\xd7\x01\x02\x00\x00\x00\x3a\x02\x8b\x00\x36\x02\xfd\x01\x70\x00\x11\x00\xd7\x01\xd7\x01\x00\x00\xd7\x01\x13\x02\xd7\x01\x33\x02\x00\x00\x33\x02\x00\x00\x00\x00\x8b\x00\x00\x00\x00\x00\x00\x00\xdd\x00\x33\x02\x8b\x00\x00\x00\x00\x00\x00\x00\x8b\x00\x81\x01\x00\x00\x64\x01\xd7\x01\x00\x00\x00\x00\x00\x00"#+happyActOffsets = HappyA# "\xe3\x00\xe3\x00\x00\x00\x33\x02\x00\x00\xc0\x02\x4d\x00\x00\x00\x00\x00\x57\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\xf2\x01\xf2\x01\x2f\x01\x97\x00\x2f\x01\x2f\x01\x2f\x01\x00\x00\x00\x02\x2f\x01\xf0\x01\xf0\x01\x16\x00\x0b\x00\x17\x00\xd9\x01\xee\x00\x00\x00\x2f\x01\xd3\x01\x2f\x01\x00\x00\x00\x00\x00\x00\x00\x00\xd7\xff\xcf\x01\x00\x00\x4b\x00\x70\x01\x2f\x01\x8c\x01\xde\x01\xce\x01\xe0\xff\x00\x00\x0b\x02\xbc\x01\x2f\x01\xb3\x01\xe9\x01\xb9\x01\x2f\x01\xc5\x01\xc4\x01\xec\xff\xc3\x01\x00\x00\x7d\x01\x00\x00\x00\x00\xc0\x02\x7c\x00\x55\x00\x00\x00\xec\x01\x42\x00\xef\xff\xfd\xff\x2f\x01\x00\x00\x08\x00\x00\x00\x86\x01\x6d\x01\x6d\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\x2f\x01\xff\xff\x36\x00\x00\x00\xac\x01\xac\x01\xac\x01\xf5\x02\xac\x01\xdc\x02\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\x00\x99\x00\xaf\x09\xc0\x02\x4d\x01\x42\x01\x6c\x01\x46\x01\x00\x00\xfc\xff\x2f\x01\x2d\x00\xfb\xff\x3d\x01\x00\x00\x00\x00\x78\x00\x3c\x01\x00\x00\x2f\x01\x24\x00\x28\x01\x2f\x01\x2f\x01\x2f\x01\x00\x00\x2f\x01\x00\x00\x58\x01\x36\x01\x2f\x01\x22\x01\x22\x01\x2f\x01\xa4\x02\x60\x01\x2f\x01\x2e\x01\x87\x02\x5a\x01\x2f\x01\xfd\xff\x00\x00\x2e\x00\x30\x01\x4e\x01\x2f\x01\xc0\x02\x2f\x01\x01\x01\x00\x00\xc0\x02\xc0\x02\x0f\x00\x2f\x01\x00\x00\x00\x00\x27\x01\x71\x00\x00\x00\x4b\x01\x70\x00\x00\x00\x4a\x01\xc0\x02\x1f\x01\x1e\x01\xc0\x02\x3e\x01\xfa\xff\xc0\x02\x0f\x02\xc0\x02\xc0\x02\xe5\xff\x00\x00\x17\x00\x31\x00\x00\x00\x30\x02\x00\x00\x00\x00\x37\x01\x67\x00\x00\x00\x2f\x01\x10\x01\x00\x00\x00\x00\x2f\x01\x2f\x01\x00\x00\xc0\x02\xc6\x01\x1c\x01\x24\x01\x66\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x40\x01\x2f\x01\xfb\x00\x2f\x01\x00\x00\xfa\xff\x2f\x01\x2f\x01\x2f\x01\x00\x00\x2f\x01\x00\x00\xc0\x02\x02\x00\x00\x00\x3b\x01\x2f\x01\x38\x01\xf8\x00\x60\x00\x5e\x00\xc0\x02\xc0\x02\x00\x00\xc0\x02\x17\x01\xc0\x02\x39\x01\x00\x00\x39\x01\x00\x00\x00\x00\x2f\x01\x00\x00\x00\x00\x00\x00\xc6\x01\x39\x01\x2f\x01\x00\x00\x00\x00\x00\x00\x2f\x01\x6a\x02\x00\x00\x4d\x02\xc0\x02\x00\x00\x00\x00\x00\x00"# happyGotoOffsets :: HappyAddr-happyGotoOffsets = HappyA# "\x00\x02\x34\x02\x00\x00\x00\x00\x00\x00\x00\x00\x35\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x02\x00\x00\xe0\x00\xdf\x00\xa4\x08\x90\x03\x77\x03\x8b\x08\x72\x08\x00\x00\x30\x02\x59\x08\xbc\x00\xd9\x00\x2c\x02\x29\x02\xd1\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\x02\x24\x02\x1c\x02\x00\x00\x0c\x02\x00\x00\x1b\x02\x40\x08\x00\x00\x00\x00\x12\x02\x27\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x5e\x03\x00\x00\x41\x01\x00\x00\x0b\x02\x6d\x00\x6e\x00\x0e\x08\xf5\x07\xdc\x07\xc3\x07\xaa\x07\x91\x07\x78\x07\x5f\x07\x46\x07\x2d\x07\x14\x07\xfb\x06\xe2\x06\xc9\x06\xb0\x06\x97\x06\x7e\x06\x65\x06\x4c\x06\x33\x06\x1a\x06\x01\x06\xe8\x05\xcf\x05\xb6\x05\x9d\x05\x84\x05\x6b\x05\x52\x05\x45\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x2c\x03\x0f\x02\x0a\x02\x08\x02\x00\x00\x00\x00\x00\x00\xca\x00\x00\x00\x39\x05\xb7\x02\xff\x01\x20\x05\x07\x05\xee\x04\x00\x00\xd5\x04\x00\x00\x00\x00\x04\x02\xbc\x04\x4f\x01\x09\x01\xa3\x04\x00\x00\x00\x00\x13\x03\x00\x00\x00\x00\x00\x00\xfa\x02\xf0\x00\x00\x00\xe3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x02\x8a\x04\x00\x00\x00\x00\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\x00\x9e\x02\x23\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\x02\xd5\x00\x00\x00\x00\x00\xc8\x02\x71\x04\x00\x00\x00\x00\xa4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\x00\x09\x02\x69\x00\x00\x00\x58\x04\x60\x00\x3f\x04\x00\x00\x71\x00\x26\x04\x0d\x04\xaf\x02\x00\x00\x96\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf4\x03\x00\x00\x28\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\xdb\x03\x00\x00\x00\x00\x00\x00\xf9\xff\x00\x00\xc2\x03\x00\x00\x00\x00\x00\x00\xa9\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyGotoOffsets = HappyA# "\xb4\x00\x4c\x01\x00\x00\x00\x00\x00\x00\x00\x00\x31\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x21\x01\x00\x00\xce\x00\xc4\x00\xa2\x09\x11\x04\xf8\x03\x89\x09\x70\x09\x00\x00\x35\x01\x57\x09\xb6\x00\xd5\x00\x34\x01\x33\x01\x07\x01\x00\x00\x00\x00\x00\x00\x3e\x09\x00\x00\x25\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x09\x00\x00\x32\x01\x25\x01\x00\x00\x15\x01\x00\x00\x20\x01\xf3\x08\x00\x00\x00\x00\x1d\x01\xda\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x01\xdf\x03\x00\x00\xe7\x00\x00\x00\x11\x01\x8d\x00\xcf\x00\xc1\x08\xa8\x08\x8f\x08\x76\x08\x5d\x08\x44\x08\x2b\x08\x12\x08\xf9\x07\xe0\x07\xc7\x07\xae\x07\x95\x07\x7c\x07\x63\x07\x4a\x07\x31\x07\x18\x07\xff\x06\xe6\x06\xcd\x06\xb4\x06\x9b\x06\x82\x06\x69\x06\x50\x06\x37\x06\x1e\x06\x05\x06\xc6\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x00\xad\x03\x16\x01\x12\x01\x0f\x01\x00\x00\x00\x00\x00\x00\xf3\x00\x00\x00\xec\x05\xe6\x00\x02\x01\xd3\x05\xba\x05\xa1\x05\x00\x00\x88\x05\x00\x00\x00\x00\xeb\x00\x6f\x05\xff\x00\xfa\x00\x56\x05\x00\x00\x00\x00\x94\x03\x00\x00\x00\x00\x00\x00\x7b\x03\xe4\x00\x00\x00\xe9\x00\x00\x00\x00\x00\x3d\x05\x00\x00\x24\x05\x00\x00\x00\x00\x00\x00\x00\x00\xec\x00\x0b\x05\x00\x00\x00\x00\xd2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x53\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8\x00\xdb\x00\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x62\x03\xdf\x00\x00\x00\x00\x00\x49\x03\xf2\x04\x00\x00\x00\x00\xaa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\x00\x85\x00\x68\x00\x00\x00\xd9\x04\x9f\x00\xc0\x04\x00\x00\x19\x00\xa7\x04\x8e\x04\x30\x03\x00\x00\x17\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x75\x04\x00\x00\x7e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x5c\x04\x00\x00\x00\x00\x00\x00\x6b\x00\x00\x00\x43\x04\x00\x00\x00\x00\x00\x00\x2a\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# happyDefActions :: HappyAddr-happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x8a\xff\x87\xff\xfa\xff\xbb\xff\xeb\xff\xec\xff\x00\x00\xcb\xff\xa0\xff\xed\xff\x8d\xff\x8c\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xff\x00\x00\x86\xff\xf2\xff\xca\xff\xc9\xff\x9f\xff\x00\x00\xfe\xff\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x8d\xff\x00\x00\x00\x00\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xff\x00\x00\xc6\xff\xcc\xff\xaa\xff\xcd\xff\xce\xff\xc8\xff\x00\x00\x00\x00\x84\xff\x00\x00\x00\x00\x00\x00\x99\xff\x00\x00\x9d\xff\x00\x00\xaf\xff\xb9\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\xff\xcf\xff\xd0\xff\xd1\xff\xd2\xff\xd3\xff\xd4\xff\xd5\xff\xd6\xff\xd7\xff\xd8\xff\xd9\xff\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe8\xff\xe9\xff\xea\xff\xbc\xff\xc3\xff\xc4\xff\x00\x00\x00\x00\xa5\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6\xff\xa7\xff\x00\x00\x97\xff\x95\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\xff\x00\x00\x9e\xff\x00\x00\xa9\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\xff\xf5\xff\x00\x00\x00\x00\x00\x00\xfc\xff\xfb\xff\x00\x00\x00\x00\x89\xff\x88\xff\x96\xff\x00\x00\xb2\xff\x00\x00\x00\x00\xb3\xff\x00\x00\xbe\xff\x00\x00\x00\x00\xc2\xff\x00\x00\x00\x00\xc7\xff\x00\x00\xef\xff\xf0\xff\x00\x00\x8d\xff\x00\x00\x00\x00\x8f\xff\x00\x00\x94\xff\x9c\xff\x00\x00\x00\x00\xa1\xff\x00\x00\x00\x00\xa2\xff\xa3\xff\x00\x00\x00\x00\x83\xff\xf1\xff\xb4\xff\xba\xff\x00\x00\x00\x00\xa8\xff\xb0\xff\x8e\xff\x8d\xff\x00\x00\x8d\xff\x93\xff\x00\x00\x00\x00\x00\x00\x9b\xff\x00\x00\x00\x00\x00\x00\x00\x00\xac\xff\x00\x00\xab\xff\xf9\xff\x00\x00\xf4\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xff\xc1\xff\x9a\xff\xee\xff\x00\x00\xc0\xff\x92\xff\x8d\xff\x91\xff\xa4\xff\xb1\xff\x00\x00\xb8\xff\xb6\xff\xb5\xff\xb4\xff\x90\xff\x00\x00\xae\xff\xad\xff\xf3\xff\x00\x00\x00\x00\xf7\xff\x00\x00\xbf\xff\xb7\xff\xf8\xff"#+happyDefActions = HappyA# "\x00\x00\x00\x00\x00\x00\x87\xff\x84\xff\xfa\xff\xb8\xff\xeb\xff\xec\xff\x00\x00\xcb\xff\x9d\xff\xed\xff\x8a\xff\x89\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xff\x00\x00\x83\xff\x00\x00\x00\x00\x00\x00\xf2\xff\xca\xff\xc9\xff\x9c\xff\x00\x00\xfe\xff\xfd\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\xff\x00\x00\x00\x00\x00\x00\xf6\xff\x00\x00\x00\x00\x00\x00\x00\x00\xc2\xff\x00\x00\xc3\xff\xcc\xff\xa7\xff\xcd\xff\xce\xff\xc5\xff\x00\x00\x00\x00\x81\xff\x00\x00\x00\x00\x00\x00\x96\xff\x00\x00\x9a\xff\x00\x00\xac\xff\xb6\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xcf\xff\xd0\xff\xd1\xff\xd2\xff\xd3\xff\xd4\xff\xd5\xff\xd6\xff\xd7\xff\xd8\xff\xd9\xff\xda\xff\xdb\xff\xdc\xff\xdd\xff\xde\xff\xdf\xff\xe0\xff\xe1\xff\xe2\xff\xe3\xff\xe4\xff\xe5\xff\xe6\xff\xe7\xff\xe8\xff\xe9\xff\xea\xff\xb9\xff\xc0\xff\xc1\xff\x00\x00\x00\x00\xa2\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3\xff\xa4\xff\x00\x00\x94\xff\x92\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\xff\x00\x00\x9b\xff\x00\x00\xa6\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xff\xf5\xff\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xff\x00\x00\xfc\xff\xfb\xff\xc6\xff\xc8\xff\x00\x00\x00\x00\x86\xff\x85\xff\x93\xff\x00\x00\xaf\xff\x00\x00\x00\x00\xb0\xff\x00\x00\xbb\xff\x00\x00\x00\x00\xbf\xff\x00\x00\x00\x00\xc4\xff\x00\x00\xef\xff\xf0\xff\x00\x00\x8a\xff\x00\x00\x00\x00\x8c\xff\x00\x00\x91\xff\x99\xff\x00\x00\x00\x00\x9e\xff\x00\x00\x00\x00\x9f\xff\xa0\xff\x00\x00\x00\x00\x80\xff\xf1\xff\xb1\xff\xb7\xff\x00\x00\x00\x00\xa5\xff\xad\xff\x8b\xff\x8a\xff\x00\x00\x8a\xff\x90\xff\x00\x00\x00\x00\x00\x00\x98\xff\x00\x00\x00\x00\x00\x00\x00\x00\xa9\xff\x00\x00\xa8\xff\xf9\xff\x00\x00\xf4\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xba\xff\xbe\xff\x97\xff\xee\xff\x00\x00\xbd\xff\x8f\xff\x8a\xff\x8e\xff\xa1\xff\xae\xff\x00\x00\xb5\xff\xb3\xff\xb2\xff\xb1\xff\x8d\xff\x00\x00\xab\xff\xaa\xff\xf3\xff\x00\x00\x00\x00\xf7\xff\x00\x00\xbc\xff\xb4\xff\xf8\xff"# happyCheck :: HappyAddr-happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x09\x00\x10\x00\x0d\x00\x0b\x00\x09\x00\x0a\x00\x0b\x00\x10\x00\x0a\x00\x0e\x00\x0f\x00\x10\x00\x0b\x00\x02\x00\x0f\x00\x10\x00\x0a\x00\x16\x00\x2c\x00\x3a\x00\x2b\x00\x02\x00\x03\x00\x04\x00\x18\x00\x0c\x00\x2b\x00\x42\x00\x09\x00\x37\x00\x0b\x00\x14\x00\x25\x00\x0e\x00\x0f\x00\x10\x00\x29\x00\x2a\x00\x0b\x00\x3e\x00\x04\x00\x16\x00\x2c\x00\x3a\x00\x07\x00\x3e\x00\x33\x00\x34\x00\x09\x00\x3a\x00\x0b\x00\x38\x00\x09\x00\x3a\x00\x0b\x00\x40\x00\x25\x00\x2c\x00\x43\x00\x40\x00\x29\x00\x2a\x00\x43\x00\x47\x00\x45\x00\x46\x00\x47\x00\x02\x00\x03\x00\x04\x00\x33\x00\x34\x00\x47\x00\x43\x00\x09\x00\x38\x00\x0b\x00\x3a\x00\x3b\x00\x0e\x00\x0f\x00\x10\x00\x18\x00\x40\x00\x0a\x00\x3a\x00\x43\x00\x16\x00\x45\x00\x46\x00\x47\x00\x02\x00\x03\x00\x04\x00\x39\x00\x0b\x00\x04\x00\x3a\x00\x09\x00\x0a\x00\x0b\x00\x3a\x00\x25\x00\x0e\x00\x0f\x00\x10\x00\x29\x00\x2a\x00\x2c\x00\x04\x00\x04\x00\x16\x00\x36\x00\x08\x00\x0a\x00\x09\x00\x33\x00\x34\x00\x2c\x00\x37\x00\x0c\x00\x38\x00\x0b\x00\x3a\x00\x3b\x00\x18\x00\x25\x00\x12\x00\x13\x00\x40\x00\x29\x00\x2a\x00\x43\x00\x16\x00\x45\x00\x46\x00\x47\x00\x02\x00\x03\x00\x04\x00\x33\x00\x34\x00\x3a\x00\x0b\x00\x09\x00\x38\x00\x0b\x00\x3a\x00\x2c\x00\x0e\x00\x0f\x00\x10\x00\x2c\x00\x40\x00\x16\x00\x18\x00\x43\x00\x16\x00\x45\x00\x46\x00\x47\x00\x09\x00\x33\x00\x34\x00\x35\x00\x0c\x00\x0c\x00\x41\x00\x10\x00\x0c\x00\x18\x00\x09\x00\x25\x00\x0d\x00\x48\x00\x0c\x00\x29\x00\x2a\x00\x10\x00\x44\x00\x0c\x00\x0c\x00\x47\x00\x33\x00\x34\x00\x35\x00\x33\x00\x34\x00\x04\x00\x29\x00\x2a\x00\x38\x00\x08\x00\x3a\x00\x2e\x00\x12\x00\x13\x00\x2c\x00\x2c\x00\x40\x00\x44\x00\x2c\x00\x43\x00\x47\x00\x45\x00\x46\x00\x47\x00\x2c\x00\x38\x00\x39\x00\x3a\x00\x02\x00\x2c\x00\x2c\x00\x17\x00\x3f\x00\x40\x00\x04\x00\x38\x00\x43\x00\x3a\x00\x17\x00\x09\x00\x04\x00\x04\x00\x02\x00\x40\x00\x08\x00\x08\x00\x43\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\x16\x00\x17\x00\x05\x00\x10\x00\x11\x00\x12\x00\x13\x00\x04\x00\x31\x00\x32\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\x06\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\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\x08\x00\x0f\x00\x10\x00\x11\x00\x04\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\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\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\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\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\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\x00\x00\x01\x00\x02\x00\x04\x00\x04\x00\x05\x00\x02\x00\x07\x00\x03\x00\x04\x00\x02\x00\x02\x00\x02\x00\x04\x00\x0e\x00\x0f\x00\x10\x00\x02\x00\x12\x00\x13\x00\x02\x00\x15\x00\x0b\x00\x16\x00\x17\x00\x19\x00\x1a\x00\x01\x00\x02\x00\x02\x00\x04\x00\x05\x00\x04\x00\x07\x00\x19\x00\x1a\x00\x18\x00\x02\x00\x02\x00\x04\x00\x0e\x00\x0f\x00\x10\x00\x02\x00\x12\x00\x13\x00\x02\x00\x15\x00\x3c\x00\x3d\x00\x02\x00\x19\x00\x1a\x00\x01\x00\x02\x00\x18\x00\x04\x00\x05\x00\x07\x00\x07\x00\x19\x00\x1a\x00\x2b\x00\x0a\x00\x43\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x0b\x00\x12\x00\x13\x00\x07\x00\x15\x00\x43\x00\x3a\x00\x2c\x00\x19\x00\x1a\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\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\x18\x00\x25\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\x18\x00\x02\x00\x25\x00\x04\x00\x05\x00\x06\x00\x07\x00\x14\x00\x2d\x00\x02\x00\x2b\x00\x04\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x0b\x00\x12\x00\x13\x00\x39\x00\x15\x00\x44\x00\x09\x00\x2d\x00\x19\x00\x1a\x00\x02\x00\x0a\x00\x04\x00\x05\x00\x06\x00\x07\x00\x19\x00\x1a\x00\x02\x00\x3a\x00\x04\x00\x0a\x00\x0e\x00\x0f\x00\x10\x00\x43\x00\x12\x00\x13\x00\x3a\x00\x15\x00\x14\x00\x43\x00\x39\x00\x19\x00\x1a\x00\x02\x00\x3a\x00\x04\x00\x05\x00\x01\x00\x07\x00\x19\x00\x1a\x00\x30\x00\x02\x00\x0c\x00\x04\x00\x0e\x00\x0f\x00\x10\x00\x2c\x00\x12\x00\x13\x00\x2c\x00\x15\x00\x43\x00\x3a\x00\x2c\x00\x19\x00\x1a\x00\x02\x00\x2f\x00\x04\x00\x05\x00\x06\x00\x07\x00\x2c\x00\x19\x00\x1a\x00\x2d\x00\x3a\x00\x0b\x00\x0e\x00\x0f\x00\x10\x00\x3a\x00\x12\x00\x13\x00\x0b\x00\x15\x00\x09\x00\x42\x00\xff\xff\x19\x00\x1a\x00\x02\x00\x43\x00\x04\x00\x05\x00\x06\x00\x07\x00\x44\x00\x3a\x00\x42\x00\x3a\x00\x43\x00\x43\x00\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#+happyCheck = HappyA# "\xff\xff\x02\x00\x03\x00\x04\x00\x07\x00\x0b\x00\x0b\x00\x0b\x00\x09\x00\x0a\x00\x0b\x00\x02\x00\x0a\x00\x0e\x00\x0f\x00\x10\x00\x2b\x00\x0b\x00\x16\x00\x0b\x00\x09\x00\x16\x00\x0b\x00\x2b\x00\x41\x00\x0a\x00\x3a\x00\x2c\x00\x18\x00\x14\x00\x16\x00\x09\x00\x09\x00\x0b\x00\x42\x00\x3e\x00\x25\x00\x4e\x00\x37\x00\x10\x00\x29\x00\x2a\x00\x3e\x00\x12\x00\x13\x00\x09\x00\x2c\x00\x33\x00\x34\x00\x35\x00\x33\x00\x34\x00\x10\x00\x3a\x00\x39\x00\x38\x00\x0b\x00\x3a\x00\x09\x00\x33\x00\x34\x00\x35\x00\x10\x00\x40\x00\x0a\x00\x10\x00\x43\x00\x44\x00\x45\x00\x3a\x00\x4a\x00\x4d\x00\x49\x00\x4d\x00\x4b\x00\x4c\x00\x4d\x00\x02\x00\x03\x00\x04\x00\x3a\x00\x3a\x00\x4a\x00\x4d\x00\x09\x00\x4d\x00\x0b\x00\x40\x00\x49\x00\x0e\x00\x0f\x00\x10\x00\x38\x00\x39\x00\x3a\x00\x0a\x00\x49\x00\x16\x00\x2c\x00\x3f\x00\x40\x00\x12\x00\x13\x00\x3a\x00\x3a\x00\x38\x00\x0c\x00\x3a\x00\x0c\x00\x49\x00\x2c\x00\x18\x00\x25\x00\x40\x00\x0c\x00\x0c\x00\x29\x00\x2a\x00\x29\x00\x2a\x00\x0d\x00\x37\x00\x49\x00\x2e\x00\x0c\x00\x0c\x00\x33\x00\x34\x00\x18\x00\x2c\x00\x04\x00\x38\x00\x0c\x00\x3a\x00\x3b\x00\x02\x00\x0c\x00\x04\x00\x2c\x00\x40\x00\x2c\x00\x36\x00\x43\x00\x44\x00\x45\x00\x04\x00\x2c\x00\x2c\x00\x49\x00\x08\x00\x4b\x00\x4c\x00\x4d\x00\x02\x00\x03\x00\x04\x00\x2c\x00\x2c\x00\x19\x00\x1a\x00\x09\x00\x0a\x00\x0b\x00\x04\x00\x2c\x00\x0e\x00\x0f\x00\x10\x00\x2c\x00\x10\x00\x11\x00\x12\x00\x13\x00\x16\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x00\x00\x01\x00\x02\x00\x0d\x00\x04\x00\x05\x00\x04\x00\x07\x00\x25\x00\x02\x00\x08\x00\x04\x00\x29\x00\x2a\x00\x0e\x00\x0f\x00\x10\x00\x18\x00\x12\x00\x13\x00\x04\x00\x15\x00\x33\x00\x34\x00\x08\x00\x19\x00\x1a\x00\x38\x00\x18\x00\x3a\x00\x04\x00\x04\x00\x19\x00\x1a\x00\x08\x00\x40\x00\x09\x00\x04\x00\x43\x00\x44\x00\x45\x00\x02\x00\x09\x00\x04\x00\x49\x00\x02\x00\x4b\x00\x4c\x00\x4d\x00\x02\x00\x03\x00\x04\x00\x02\x00\x17\x00\x04\x00\x02\x00\x09\x00\x02\x00\x0b\x00\x03\x00\x04\x00\x0e\x00\x0f\x00\x10\x00\x19\x00\x1a\x00\x0f\x00\x10\x00\x11\x00\x16\x00\x16\x00\x17\x00\x0f\x00\x10\x00\x04\x00\x19\x00\x1a\x00\x01\x00\x02\x00\x04\x00\x04\x00\x05\x00\x04\x00\x07\x00\x25\x00\x02\x00\x17\x00\x04\x00\x29\x00\x2a\x00\x0e\x00\x0f\x00\x10\x00\x02\x00\x12\x00\x13\x00\x02\x00\x15\x00\x33\x00\x34\x00\x02\x00\x19\x00\x1a\x00\x38\x00\x0b\x00\x3a\x00\x3b\x00\x02\x00\x19\x00\x1a\x00\x02\x00\x40\x00\x16\x00\x17\x00\x43\x00\x44\x00\x45\x00\x04\x00\x3c\x00\x3d\x00\x49\x00\x18\x00\x4b\x00\x4c\x00\x4d\x00\x02\x00\x03\x00\x04\x00\x02\x00\x02\x00\x02\x00\x02\x00\x09\x00\x18\x00\x0b\x00\x0a\x00\x18\x00\x0e\x00\x0f\x00\x10\x00\x07\x00\x49\x00\x2b\x00\x0b\x00\x49\x00\x16\x00\x0b\x00\x07\x00\x2c\x00\x2b\x00\x3a\x00\x4a\x00\x2d\x00\x01\x00\x02\x00\x18\x00\x04\x00\x05\x00\x14\x00\x07\x00\x25\x00\x0b\x00\x0b\x00\x09\x00\x29\x00\x2a\x00\x0e\x00\x0f\x00\x10\x00\x2d\x00\x12\x00\x13\x00\x39\x00\x15\x00\x33\x00\x34\x00\x0a\x00\x19\x00\x1a\x00\x38\x00\x3a\x00\x3a\x00\x0a\x00\x49\x00\x14\x00\x01\x00\x2c\x00\x40\x00\x3a\x00\x49\x00\x43\x00\x44\x00\x45\x00\x39\x00\x30\x00\x3a\x00\x49\x00\x2c\x00\x4b\x00\x4c\x00\x4d\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\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\x2f\x00\x49\x00\x3a\x00\x48\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\x46\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\x2c\x00\x2c\x00\x05\x00\x2d\x00\x3a\x00\x0b\x00\x42\x00\x3a\x00\x31\x00\x32\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\x06\x00\x0b\x00\x49\x00\x3a\x00\x4a\x00\x47\x00\x42\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\x08\x00\x49\x00\x3a\x00\x49\x00\x09\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\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\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\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\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\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\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\xff\xff\x25\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\xff\xff\x02\x00\x25\x00\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\x0c\x00\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\x06\x00\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\x00\x02\x00\xff\xff\x04\x00\x05\x00\xff\xff\x07\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x0e\x00\x0f\x00\x10\x00\xff\xff\x12\x00\x13\x00\xff\xff\x15\x00\xff\xff\xff\xff\xff\xff\x19\x00\x1a\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\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"# happyTable :: HappyAddr-happyTable = HappyA# "\x00\x00\x10\x00\x11\x00\x12\x00\x13\x00\xb8\x00\x15\x01\x14\x00\x13\x00\x6b\x00\x14\x00\x17\x00\xf8\x00\x15\x00\x16\x00\x17\x00\x45\x00\xa0\x00\xd3\x00\x09\x00\xf6\x00\x18\x00\x9a\x00\xaf\x00\xe8\x00\x10\x00\x11\x00\x12\x00\x0b\x01\x0e\x01\xa3\x00\xb0\x00\x13\x00\x9b\x00\x14\x00\xa1\x00\x19\x00\x15\x00\x16\x00\x17\x00\x1a\x00\x1b\x00\x30\x00\xe9\x00\x0f\x01\x18\x00\xf9\x00\x31\x00\x98\x00\xa4\x00\x1c\x00\x1d\x00\x2f\x00\x1f\x00\x30\x00\x1e\x00\x33\x00\x1f\x00\x34\x00\x21\x00\x19\x00\x9f\x00\x22\x00\x21\x00\x1a\x00\x1b\x00\x22\x00\x25\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x1c\x00\x1d\x00\x46\x00\x22\x00\x13\x00\x1e\x00\x14\x00\x1f\x00\x20\x00\x15\x00\x16\x00\x17\x00\x47\x00\x21\x00\xdb\x00\x31\x00\x22\x00\x18\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x99\x00\x34\x00\xff\x00\x31\x00\x13\x00\x40\x00\x14\x00\x31\x00\x19\x00\x15\x00\x16\x00\x17\x00\x1a\x00\x1b\x00\x9a\x00\x36\x00\x34\x00\x18\x00\x48\x00\x89\x00\x9e\x00\x88\x00\x1c\x00\x1d\x00\x9f\x00\x9c\x00\x0f\x01\x1e\x00\xd5\x00\x1f\x00\x20\x00\x01\x01\x19\x00\xfd\x00\x0b\x00\x21\x00\x1a\x00\x1b\x00\x22\x00\x18\x00\x23\x00\x24\x00\x25\x00\x10\x00\x11\x00\x12\x00\x1c\x00\x1d\x00\x31\x00\x8f\x00\x13\x00\x1e\x00\x14\x00\x1f\x00\x9f\x00\x15\x00\x16\x00\x17\x00\x9f\x00\x21\x00\x18\x00\x03\x01\x22\x00\x18\x00\x23\x00\x24\x00\x25\x00\x13\x00\x90\x00\x91\x00\xd6\x00\x05\x01\xe1\x00\x29\x00\x17\x00\xf0\x00\xe6\x00\x13\x00\x19\x00\x07\x01\xff\xff\xf2\x00\x1a\x00\x1b\x00\x17\x00\xd7\x00\xd1\x00\xa0\x00\xd8\x00\x90\x00\x91\x00\x92\x00\x1c\x00\x1d\x00\x36\x00\x4a\x00\x4b\x00\x1e\x00\x37\x00\x1f\x00\x4c\x00\xea\x00\x0b\x00\x9f\x00\x9f\x00\x21\x00\x93\x00\x9f\x00\x22\x00\x94\x00\x23\x00\x24\x00\x25\x00\x9f\x00\xcc\x00\xcd\x00\x1f\x00\xde\x00\x9f\x00\x9f\x00\xcf\x00\xce\x00\x21\x00\x34\x00\xe5\x00\x22\x00\x1f\x00\xcf\x00\x35\x00\x36\x00\x36\x00\xb6\x00\x21\x00\x41\x00\x42\x00\x22\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\xb8\x00\x96\x00\x9d\x00\x50\x00\x51\x00\x52\x00\x53\x00\xc0\x00\x09\x01\x0a\x01\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\xea\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\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\xe3\x00\x8c\x00\x09\x00\x8d\x00\xc1\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\x17\x01\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\x13\x01\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\xbc\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\xbf\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\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\x25\x00\x26\x00\x03\x00\xc9\x00\x04\x00\x05\x00\xc3\x00\x06\x00\xf3\x00\xf4\x00\xd1\x00\x03\x00\x2d\x00\x04\x00\x07\x00\x08\x00\x09\x00\x31\x00\x0a\x00\x0b\x00\xa7\x00\x0c\x00\x8a\x00\x95\x00\x96\x00\x0d\x00\x0e\x00\xb2\x00\x03\x00\xab\x00\x04\x00\x05\x00\xb0\x00\x06\x00\x02\x01\x0e\x00\xad\x00\x03\x00\xb1\x00\x04\x00\x07\x00\x08\x00\x09\x00\x2d\x00\x0a\x00\x0b\x00\x31\x00\x0c\x00\x2a\x00\x2b\x00\x39\x00\x0d\x00\x0e\x00\x02\x00\x03\x00\x43\x00\x04\x00\x05\x00\x98\x00\x06\x00\xe3\x00\x0e\x00\x0d\x01\x48\x00\x22\x00\x11\x01\x07\x00\x08\x00\x09\x00\xf7\x00\x0a\x00\x0b\x00\x98\x00\x0c\x00\x22\x00\x31\x00\x07\x01\x0d\x00\x0e\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\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\x06\x01\x65\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\xe2\x00\x03\x00\x00\x00\x04\x00\x3c\x00\xf9\x00\x06\x00\xec\x00\xee\x00\x03\x00\xed\x00\x04\x00\xef\x00\x07\x00\x08\x00\x09\x00\xf1\x00\x0a\x00\x0b\x00\x99\x00\x0c\x00\xb4\x00\xb5\x00\xb6\x00\x0d\x00\x0e\x00\x03\x00\xbb\x00\x04\x00\x3c\x00\xfa\x00\x06\x00\xe5\x00\x0e\x00\x03\x00\xaf\x00\x04\x00\xbe\x00\x07\x00\x08\x00\x09\x00\x22\x00\x0a\x00\x0b\x00\x31\x00\x0c\x00\xc5\x00\x22\x00\x99\x00\x0d\x00\x0e\x00\x03\x00\x31\x00\x04\x00\xdc\x00\xda\x00\x06\x00\xca\x00\x0e\x00\xd9\x00\x03\x00\xdd\x00\x04\x00\x07\x00\x08\x00\x09\x00\x9a\x00\x0a\x00\x0b\x00\xa5\x00\x0c\x00\x22\x00\x31\x00\x9a\x00\x0d\x00\x0e\x00\x03\x00\x8c\x00\x04\x00\x3c\x00\xdf\x00\x06\x00\xa5\x00\x2c\x00\x0e\x00\xa6\x00\x31\x00\xa9\x00\x07\x00\x08\x00\x09\x00\x31\x00\x0a\x00\x0b\x00\xad\x00\x0c\x00\x69\x00\xaa\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x22\x00\x04\x00\x3c\x00\xb9\x00\x06\x00\x28\x00\x31\x00\x2c\x00\x31\x00\x22\x00\x22\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\xbc\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\xd2\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\x69\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\x94\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\x3d\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3c\x00\x3e\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x13\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x14\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x0a\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x11\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xfb\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xfc\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xfe\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x00\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xdb\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xf2\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xbf\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xc2\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xc5\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xc6\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xc7\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xc8\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xce\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x6b\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x6c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x6d\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x6e\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x6f\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x70\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x71\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x72\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x73\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x74\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x75\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x76\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x77\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x78\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x79\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7a\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7b\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7d\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7e\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x80\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x81\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x82\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x83\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x84\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x85\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x86\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x87\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xa6\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xaa\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x38\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3a\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3b\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x40\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"#+happyTable = HappyA# "\x00\x00\x10\x00\x11\x00\x12\x00\x9e\x00\x14\x00\x36\x00\xe0\x00\x13\x00\x71\x00\x14\x00\xa6\x00\x03\x01\x15\x00\x16\x00\x17\x00\xf3\x00\x4b\x00\x18\x00\x95\x00\x35\x00\x18\x00\x36\x00\xa9\x00\x2c\x00\x01\x01\xb5\x00\xa0\x00\x16\x01\xa7\x00\x18\x00\x39\x00\x13\x00\x3a\x00\xb6\x00\xf4\x00\x19\x00\xff\xff\xa1\x00\x17\x00\x1a\x00\x1b\x00\xaa\x00\x08\x01\x0b\x00\x13\x00\x04\x01\x96\x00\x97\x00\xe1\x00\x1c\x00\x1d\x00\x17\x00\x37\x00\x9f\x00\x1e\x00\x3a\x00\x1f\x00\x13\x00\x96\x00\x97\x00\x98\x00\xc3\x00\x21\x00\xe6\x00\x17\x00\x22\x00\x23\x00\x24\x00\x37\x00\xe2\x00\x28\x00\x25\x00\xe3\x00\x26\x00\x27\x00\x28\x00\x10\x00\x11\x00\x12\x00\x37\x00\x1f\x00\x99\x00\x4c\x00\x13\x00\x9a\x00\x14\x00\x21\x00\x25\x00\x15\x00\x16\x00\x17\x00\xd7\x00\xd8\x00\x1f\x00\xa4\x00\x25\x00\x18\x00\xa5\x00\xd9\x00\x21\x00\xf5\x00\x0b\x00\x37\x00\x37\x00\xf0\x00\x19\x01\x1f\x00\x1a\x01\x25\x00\xa0\x00\x4d\x00\x19\x00\x21\x00\x10\x01\xec\x00\x1a\x00\x1b\x00\x50\x00\x51\x00\x20\x01\xa2\x00\x25\x00\x52\x00\xfb\x00\xfd\x00\x1c\x00\x1d\x00\x0c\x01\xa5\x00\x1a\x01\x1e\x00\xdc\x00\x1f\x00\x20\x00\x03\x00\xa6\x00\x04\x00\xa5\x00\x21\x00\xa5\x00\x4e\x00\x22\x00\x23\x00\x24\x00\x3c\x00\xa5\x00\xa5\x00\x25\x00\x8f\x00\x26\x00\x27\x00\x28\x00\x10\x00\x11\x00\x12\x00\xa5\x00\xa5\x00\x0d\x01\x0e\x00\x13\x00\x46\x00\x14\x00\x0a\x01\xa5\x00\x15\x00\x16\x00\x17\x00\xa5\x00\x56\x00\x57\x00\x58\x00\x59\x00\x18\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x28\x00\x29\x00\x03\x00\x12\x01\x04\x00\x05\x00\x3c\x00\x06\x00\x19\x00\x03\x00\x3d\x00\x04\x00\x1a\x00\x1b\x00\x07\x00\x08\x00\x09\x00\x0e\x01\x0a\x00\x0b\x00\x3c\x00\x0c\x00\x1c\x00\x1d\x00\x47\x00\x0d\x00\x0e\x00\x1e\x00\xf1\x00\x1f\x00\x3c\x00\x3a\x00\xee\x00\x0e\x00\x48\x00\x21\x00\x8e\x00\x3a\x00\x22\x00\x23\x00\x24\x00\x03\x00\x3b\x00\x04\x00\x25\x00\xe9\x00\x26\x00\x27\x00\x28\x00\x10\x00\x11\x00\x12\x00\x03\x00\xda\x00\x04\x00\xc1\x00\x13\x00\xce\x00\x14\x00\xfe\x00\xff\x00\x15\x00\x16\x00\x17\x00\xf0\x00\x0e\x00\x92\x00\x09\x00\x93\x00\x18\x00\xc3\x00\x9c\x00\xde\x00\x09\x00\xcb\x00\xd5\x00\x0e\x00\xbb\x00\x03\x00\xcc\x00\x04\x00\x05\x00\xd4\x00\x06\x00\x19\x00\x03\x00\xda\x00\x04\x00\x1a\x00\x1b\x00\x07\x00\x08\x00\x09\x00\xdc\x00\x0a\x00\x0b\x00\x33\x00\x0c\x00\x1c\x00\x1d\x00\x37\x00\x0d\x00\x0e\x00\x1e\x00\x90\x00\x1f\x00\x20\x00\xad\x00\x32\x00\x0e\x00\xb1\x00\x21\x00\x9b\x00\x9c\x00\x22\x00\x23\x00\x24\x00\xb6\x00\x30\x00\x31\x00\x25\x00\xb3\x00\x26\x00\x27\x00\x28\x00\x10\x00\x11\x00\x12\x00\xb7\x00\x33\x00\x37\x00\x3f\x00\x13\x00\x49\x00\x14\x00\x4e\x00\x11\x01\x15\x00\x16\x00\x17\x00\x9e\x00\x25\x00\x18\x01\x1c\x01\x25\x00\x18\x00\x02\x01\x9e\x00\x12\x01\xf8\x00\x37\x00\xbd\x00\xf9\x00\x02\x00\x03\x00\xed\x00\x04\x00\x05\x00\xf7\x00\x06\x00\x19\x00\xfa\x00\xfc\x00\xc0\x00\x1a\x00\x1b\x00\x07\x00\x08\x00\x09\x00\xc1\x00\x0a\x00\x0b\x00\x9f\x00\x0c\x00\x1c\x00\x1d\x00\xc6\x00\x0d\x00\x0e\x00\x1e\x00\xb5\x00\x1f\x00\xc9\x00\x25\x00\xd0\x00\xe5\x00\xa0\x00\x21\x00\x37\x00\x25\x00\x22\x00\x23\x00\x24\x00\x9f\x00\xe4\x00\x37\x00\x25\x00\xab\x00\x26\x00\x27\x00\x28\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\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\x92\x00\x25\x00\x37\x00\xbb\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\xb9\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\xa0\x00\xab\x00\xa3\x00\xac\x00\x37\x00\xaf\x00\xb0\x00\x37\x00\x14\x01\x15\x01\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\xf5\x00\xb3\x00\x25\x00\x37\x00\x2b\x00\x2e\x00\x32\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\xee\x00\x25\x00\x37\x00\x25\x00\x6f\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\x22\x01\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\x1e\x01\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\xc7\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\xca\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\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\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\x00\x00\x6b\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\x00\x00\x03\x00\x00\x00\x04\x00\x42\x00\x04\x01\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\x05\x01\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xe7\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\xea\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\xc4\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\xc7\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\xdd\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\x6f\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\x9a\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\x43\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x42\x00\x44\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x1e\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x1f\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x15\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x1c\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x06\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x07\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x09\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x0b\x01\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xe6\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xfd\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xbd\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xbe\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xca\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xcd\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xd0\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xd1\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xd2\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xd3\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xd9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x71\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x72\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x73\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x74\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x75\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x76\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x77\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x78\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x79\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7a\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7b\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7d\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7e\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x7f\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x80\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x81\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x82\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x83\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x84\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x85\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x86\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x87\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x88\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x89\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x8a\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x8b\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x8c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x8d\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xac\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xb0\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\xb9\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x2c\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x2e\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x3e\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x40\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x41\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\x00\x03\x00\x00\x00\x04\x00\x46\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00\x08\x00\x09\x00\x00\x00\x0a\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x0d\x00\x0e\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\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# -happyReduceArr = array (1, 125) [+happyReduceArr = array (1, 128) [ (1 , happyReduce_1), (2 , happyReduce_2), (3 , happyReduce_3),@@ -330,10 +330,13 @@ (122 , happyReduce_122), (123 , happyReduce_123), (124 , happyReduce_124),- (125 , happyReduce_125)+ (125 , happyReduce_125),+ (126 , happyReduce_126),+ (127 , happyReduce_127),+ (128 , happyReduce_128) ] -happy_n_terms = 73 :: Int+happy_n_terms = 79 :: Int happy_n_nonterms = 27 :: Int happyReduce_1 = happySpecReduce_1 0# happyReduction_1@@ -868,15 +871,48 @@ (Afloat happy_var_1 )} -happyReduce_55 = happySpecReduce_1 6# happyReduction_55-happyReduction_55 happy_x_1+happyReduce_55 = happyReduce 4# 5# happyReduction_55+happyReduction_55 (happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOut9 happy_x_2 of { happy_var_2 -> + case happyOut9 happy_x_4 of { happy_var_4 -> + happyIn9+ (call "insert" [happy_var_2,Ast "destination" [happy_var_4]]+ ) `HappyStk` happyRest}}++happyReduce_56 = happySpecReduce_3 5# happyReduction_56+happyReduction_56 happy_x_3+ happy_x_2+ happy_x_1+ = case happyOut9 happy_x_3 of { happy_var_3 -> + happyIn9+ (call "delete" [happy_var_3]+ )}++happyReduce_57 = happyReduce 4# 5# happyReduction_57+happyReduction_57 (happy_x_4 `HappyStk`+ happy_x_3 `HappyStk`+ happy_x_2 `HappyStk`+ happy_x_1 `HappyStk`+ happyRest)+ = case happyOut9 happy_x_2 of { happy_var_2 -> + case happyOut9 happy_x_4 of { happy_var_4 -> + happyIn9+ (call "replace" [happy_var_2,happy_var_4]+ ) `HappyStk` happyRest}}++happyReduce_58 = happySpecReduce_1 6# happyReduction_58+happyReduction_58 happy_x_1 = case happyOut9 happy_x_1 of { happy_var_1 -> happyIn10 ([happy_var_1] )} -happyReduce_56 = happySpecReduce_3 6# happyReduction_56-happyReduction_56 happy_x_3+happyReduce_59 = happySpecReduce_3 6# happyReduction_59+happyReduction_59 happy_x_3 happy_x_2 happy_x_1 = case happyOut10 happy_x_1 of { happy_var_1 -> @@ -885,24 +921,24 @@ (happy_var_1++[happy_var_3] )}} -happyReduce_57 = happySpecReduce_2 7# happyReduction_57-happyReduction_57 happy_x_2+happyReduce_60 = happySpecReduce_2 7# happyReduction_60+happyReduction_60 happy_x_2 happy_x_1 = case happyOut12 happy_x_2 of { happy_var_2 -> happyIn11 (happy_var_2 )} -happyReduce_58 = happySpecReduce_2 7# happyReduction_58-happyReduction_58 happy_x_2+happyReduce_61 = happySpecReduce_2 7# happyReduction_61+happyReduction_61 happy_x_2 happy_x_1 = case happyOut13 happy_x_2 of { happy_var_2 -> happyIn11 (happy_var_2 )} -happyReduce_59 = happySpecReduce_3 7# happyReduction_59-happyReduction_59 happy_x_3+happyReduce_62 = happySpecReduce_3 7# happyReduction_62+happyReduction_62 happy_x_3 happy_x_2 happy_x_1 = case happyOut11 happy_x_1 of { happy_var_1 -> @@ -911,8 +947,8 @@ (happy_var_1 . happy_var_3 )}} -happyReduce_60 = happySpecReduce_3 7# happyReduction_60-happyReduction_60 happy_x_3+happyReduce_63 = happySpecReduce_3 7# happyReduction_63+happyReduction_63 happy_x_3 happy_x_2 happy_x_1 = case happyOut11 happy_x_1 of { happy_var_1 -> @@ -921,8 +957,8 @@ (happy_var_1 . happy_var_3 )}} -happyReduce_61 = happySpecReduce_3 8# happyReduction_61-happyReduction_61 happy_x_3+happyReduce_64 = happySpecReduce_3 8# happyReduction_64+happyReduction_64 happy_x_3 happy_x_2 happy_x_1 = case happyOut8 happy_x_1 of { happy_var_1 -> @@ -931,8 +967,8 @@ (\x -> Ast "for" [happy_var_1,Avar "$",happy_var_3,x] )}} -happyReduce_62 = happyReduce 5# 8# happyReduction_62-happyReduction_62 (happy_x_5 `HappyStk`+happyReduce_65 = happyReduce 5# 8# happyReduction_65+happyReduction_65 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk`@@ -945,8 +981,8 @@ (\x -> Ast "for" [happy_var_1,happy_var_3,happy_var_5,x] ) `HappyStk` happyRest}}} -happyReduce_63 = happyReduce 5# 8# happyReduction_63-happyReduction_63 (happy_x_5 `HappyStk`+happyReduce_66 = happyReduce 5# 8# happyReduction_66+happyReduction_66 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk`@@ -959,8 +995,8 @@ (\x -> happy_var_1(Ast "for" [happy_var_3,Avar "$",happy_var_5,x]) ) `HappyStk` happyRest}}} -happyReduce_64 = happyReduce 7# 8# happyReduction_64-happyReduction_64 (happy_x_7 `HappyStk`+happyReduce_67 = happyReduce 7# 8# happyReduction_67+happyReduction_67 (happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk`@@ -976,8 +1012,8 @@ (\x -> happy_var_1(Ast "for" [happy_var_3,happy_var_5,happy_var_7,x]) ) `HappyStk` happyRest}}}} -happyReduce_65 = happySpecReduce_3 9# happyReduction_65-happyReduction_65 happy_x_3+happyReduce_68 = happySpecReduce_3 9# happyReduction_68+happyReduction_68 happy_x_3 happy_x_2 happy_x_1 = case happyOut8 happy_x_1 of { happy_var_1 -> @@ -986,8 +1022,8 @@ (\x -> Ast "let" [happy_var_1,happy_var_3,x] )}} -happyReduce_66 = happyReduce 5# 9# happyReduction_66-happyReduction_66 (happy_x_5 `HappyStk`+happyReduce_69 = happyReduce 5# 9# happyReduction_69+happyReduction_69 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk`@@ -1000,21 +1036,21 @@ (\x -> happy_var_1(Ast "let" [happy_var_3,happy_var_5,x]) ) `HappyStk` happyRest}}} -happyReduce_67 = happySpecReduce_2 10# happyReduction_67-happyReduction_67 happy_x_2+happyReduce_70 = happySpecReduce_2 10# happyReduction_70+happyReduction_70 happy_x_2 happy_x_1 = case happyOut9 happy_x_2 of { happy_var_2 -> happyIn14 (\x -> Ast "predicate" [happy_var_2,x] )} -happyReduce_68 = happySpecReduce_0 10# happyReduction_68-happyReduction_68 = happyIn14+happyReduce_71 = happySpecReduce_0 10# happyReduction_71+happyReduction_71 = happyIn14 (id ) -happyReduce_69 = happySpecReduce_3 11# happyReduction_69-happyReduction_69 happy_x_3+happyReduce_72 = happySpecReduce_3 11# happyReduction_72+happyReduction_72 happy_x_3 happy_x_2 happy_x_1 = case happyOut16 happy_x_3 of { happy_var_3 -> @@ -1023,13 +1059,13 @@ \x -> Ast "sort" (x:(snd happy_var_3))) )} -happyReduce_70 = happySpecReduce_0 11# happyReduction_70-happyReduction_70 = happyIn15+happyReduce_73 = happySpecReduce_0 11# happyReduction_73+happyReduction_73 = happyIn15 ((id,id) ) -happyReduce_71 = happySpecReduce_2 12# happyReduction_71-happyReduction_71 happy_x_2+happyReduce_74 = happySpecReduce_2 12# happyReduction_74+happyReduction_74 happy_x_2 happy_x_1 = case happyOut9 happy_x_1 of { happy_var_1 -> case happyOut17 happy_x_2 of { happy_var_2 -> @@ -1037,8 +1073,8 @@ (([happy_var_1],[happy_var_2]) )}} -happyReduce_72 = happyReduce 4# 12# happyReduction_72-happyReduction_72 (happy_x_4 `HappyStk`+happyReduce_75 = happyReduce 4# 12# happyReduction_75+happyReduction_75 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1050,25 +1086,25 @@ (((fst happy_var_1)++[happy_var_3],(snd happy_var_1)++[happy_var_4]) ) `HappyStk` happyRest}}} -happyReduce_73 = happySpecReduce_1 13# happyReduction_73-happyReduction_73 happy_x_1+happyReduce_76 = happySpecReduce_1 13# happyReduction_76+happyReduction_76 happy_x_1 = happyIn17 (Avar "ascending" ) -happyReduce_74 = happySpecReduce_1 13# happyReduction_74-happyReduction_74 happy_x_1+happyReduce_77 = happySpecReduce_1 13# happyReduction_77+happyReduction_77 happy_x_1 = happyIn17 (Avar "descending" ) -happyReduce_75 = happySpecReduce_0 13# happyReduction_75-happyReduction_75 = happyIn17+happyReduce_78 = happySpecReduce_0 13# happyReduction_78+happyReduction_78 = happyIn17 (Avar "ascending" ) -happyReduce_76 = happyReduce 4# 14# happyReduction_76-happyReduction_76 (happy_x_4 `HappyStk`+happyReduce_79 = happyReduce 4# 14# happyReduction_79+happyReduction_79 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1078,8 +1114,8 @@ (call "element" [Avar happy_var_3] ) `HappyStk` happyRest} -happyReduce_77 = happyReduce 4# 14# happyReduction_77-happyReduction_77 (happy_x_4 `HappyStk`+happyReduce_80 = happyReduce 4# 14# happyReduction_80+happyReduction_80 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1089,8 +1125,8 @@ (call "attribute" [Avar happy_var_3] ) `HappyStk` happyRest} -happyReduce_78 = happyReduce 6# 15# happyReduction_78-happyReduction_78 (happy_x_6 `HappyStk`+happyReduce_81 = happyReduce 6# 15# happyReduction_81+happyReduction_81 (happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk`@@ -1107,8 +1143,8 @@ ++(show (head happy_var_1))++" '"++happy_var_5++"'")] ) `HappyStk` happyRest}}} -happyReduce_79 = happyReduce 5# 15# happyReduction_79-happyReduction_79 (happy_x_5 `HappyStk`+happyReduce_82 = happyReduce 5# 15# happyReduction_82+happyReduction_82 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk`@@ -1123,16 +1159,16 @@ ++(show (head happy_var_1))++" '"++happy_var_4++"'")] ) `HappyStk` happyRest}} -happyReduce_80 = happySpecReduce_2 15# happyReduction_80-happyReduction_80 happy_x_2+happyReduce_83 = happySpecReduce_2 15# happyReduction_83+happyReduction_83 happy_x_2 happy_x_1 = case happyOut20 happy_x_1 of { happy_var_1 -> happyIn19 (Ast "element_construction" (happy_var_1++[Ast "append" []]) )} -happyReduce_81 = happyReduce 7# 15# happyReduction_81-happyReduction_81 (happy_x_7 `HappyStk`+happyReduce_84 = happyReduce 7# 15# happyReduction_84+happyReduction_84 (happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk`@@ -1146,8 +1182,8 @@ (Ast "element_construction" [happy_var_3,Ast "attributes" [],concatenateAll happy_var_6] ) `HappyStk` happyRest}} -happyReduce_82 = happyReduce 7# 15# happyReduction_82-happyReduction_82 (happy_x_7 `HappyStk`+happyReduce_85 = happyReduce 7# 15# happyReduction_85+happyReduction_85 (happy_x_7 `HappyStk` happy_x_6 `HappyStk` happy_x_5 `HappyStk` happy_x_4 `HappyStk`@@ -1161,8 +1197,8 @@ (Ast "attribute_construction" [happy_var_3,concatenateAll happy_var_6] ) `HappyStk` happyRest}} -happyReduce_83 = happyReduce 5# 15# happyReduction_83-happyReduction_83 (happy_x_5 `HappyStk`+happyReduce_86 = happyReduce 5# 15# happyReduction_86+happyReduction_86 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk`@@ -1174,8 +1210,8 @@ (Ast "element_construction" [Astring happy_var_2,Ast "attributes" [],concatenateAll happy_var_4] ) `HappyStk` happyRest}} -happyReduce_84 = happyReduce 5# 15# happyReduction_84-happyReduction_84 (happy_x_5 `HappyStk`+happyReduce_87 = happyReduce 5# 15# happyReduction_87+happyReduction_87 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk`@@ -1187,16 +1223,16 @@ (Ast "attribute_construction" [Astring happy_var_2,concatenateAll happy_var_4] ) `HappyStk` happyRest}} -happyReduce_85 = happySpecReduce_2 16# happyReduction_85-happyReduction_85 happy_x_2+happyReduce_88 = happySpecReduce_2 16# happyReduction_88+happyReduction_88 happy_x_2 happy_x_1 = case happyOut6 happy_x_2 of { happy_var_2 -> happyIn20 ([Astring happy_var_2,Ast "attributes" []] )} -happyReduce_86 = happySpecReduce_3 16# happyReduction_86-happyReduction_86 happy_x_3+happyReduce_89 = happySpecReduce_3 16# happyReduction_89+happyReduction_89 happy_x_3 happy_x_2 happy_x_1 = case happyOut6 happy_x_2 of { happy_var_2 -> @@ -1205,8 +1241,8 @@ ([Astring happy_var_2,Ast "attributes" happy_var_3] )}} -happyReduce_87 = happySpecReduce_3 17# happyReduction_87-happyReduction_87 happy_x_3+happyReduce_90 = happySpecReduce_3 17# happyReduction_90+happyReduction_90 happy_x_3 happy_x_2 happy_x_1 = case happyOut10 happy_x_2 of { happy_var_2 -> @@ -1214,29 +1250,29 @@ ([concatenateAll happy_var_2] )} -happyReduce_88 = happySpecReduce_1 17# happyReduction_88-happyReduction_88 happy_x_1+happyReduce_91 = happySpecReduce_1 17# happyReduction_91+happyReduction_91 happy_x_1 = case happyOutTok happy_x_1 of { (TString happy_var_1) -> happyIn21 ([Astring happy_var_1] )} -happyReduce_89 = happySpecReduce_1 17# happyReduction_89-happyReduction_89 happy_x_1+happyReduce_92 = happySpecReduce_1 17# happyReduction_92+happyReduction_92 happy_x_1 = case happyOutTok happy_x_1 of { (XMLtext happy_var_1) -> happyIn21 ([Astring happy_var_1] )} -happyReduce_90 = happySpecReduce_1 17# happyReduction_90-happyReduction_90 happy_x_1+happyReduce_93 = happySpecReduce_1 17# happyReduction_93+happyReduction_93 happy_x_1 = case happyOut19 happy_x_1 of { happy_var_1 -> happyIn21 ([happy_var_1] )} -happyReduce_91 = happyReduce 4# 17# happyReduction_91-happyReduction_91 (happy_x_4 `HappyStk`+happyReduce_94 = happyReduce 4# 17# happyReduction_94+happyReduction_94 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1247,8 +1283,8 @@ (happy_var_1++[concatenateAll happy_var_3] ) `HappyStk` happyRest}} -happyReduce_92 = happySpecReduce_2 17# happyReduction_92-happyReduction_92 happy_x_2+happyReduce_95 = happySpecReduce_2 17# happyReduction_95+happyReduction_95 happy_x_2 happy_x_1 = case happyOut21 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { (TString happy_var_2) -> @@ -1256,8 +1292,8 @@ (happy_var_1++[Astring happy_var_2] )}} -happyReduce_93 = happySpecReduce_2 17# happyReduction_93-happyReduction_93 happy_x_2+happyReduce_96 = happySpecReduce_2 17# happyReduction_96+happyReduction_96 happy_x_2 happy_x_1 = case happyOut21 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { (XMLtext happy_var_2) -> @@ -1265,8 +1301,8 @@ (happy_var_1++[Astring happy_var_2] )}} -happyReduce_94 = happySpecReduce_2 17# happyReduction_94-happyReduction_94 happy_x_2+happyReduce_97 = happySpecReduce_2 17# happyReduction_97+happyReduction_97 happy_x_2 happy_x_1 = case happyOut21 happy_x_1 of { happy_var_1 -> case happyOut19 happy_x_2 of { happy_var_2 -> @@ -1274,22 +1310,22 @@ (happy_var_1++[happy_var_2] )}} -happyReduce_95 = happySpecReduce_1 18# happyReduction_95-happyReduction_95 happy_x_1+happyReduce_98 = happySpecReduce_1 18# happyReduction_98+happyReduction_98 happy_x_1 = case happyOut23 happy_x_1 of { happy_var_1 -> happyIn22 (if length happy_var_1 == 1 then head happy_var_1 else Ast "append" happy_var_1 )} -happyReduce_96 = happySpecReduce_1 19# happyReduction_96-happyReduction_96 happy_x_1+happyReduce_99 = happySpecReduce_1 19# happyReduction_99+happyReduction_99 happy_x_1 = case happyOutTok happy_x_1 of { (TString happy_var_1) -> happyIn23 (if happy_var_1=="" then [] else [Astring happy_var_1] )} -happyReduce_97 = happySpecReduce_3 19# happyReduction_97-happyReduction_97 happy_x_3+happyReduce_100 = happySpecReduce_3 19# happyReduction_100+happyReduction_100 happy_x_3 happy_x_2 happy_x_1 = case happyOut10 happy_x_2 of { happy_var_2 -> @@ -1297,8 +1333,8 @@ ([concatenateAll happy_var_2] )} -happyReduce_98 = happySpecReduce_2 19# happyReduction_98-happyReduction_98 happy_x_2+happyReduce_101 = happySpecReduce_2 19# happyReduction_101+happyReduction_101 happy_x_2 happy_x_1 = case happyOut23 happy_x_1 of { happy_var_1 -> case happyOutTok happy_x_2 of { (TString happy_var_2) -> @@ -1306,8 +1342,8 @@ (if happy_var_2=="" then happy_var_1 else happy_var_1++[Astring happy_var_2] )}} -happyReduce_99 = happyReduce 4# 19# happyReduction_99-happyReduction_99 (happy_x_4 `HappyStk`+happyReduce_102 = happyReduce 4# 19# happyReduction_102+happyReduction_102 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1318,8 +1354,8 @@ (happy_var_1++[concatenateAll happy_var_3] ) `HappyStk` happyRest}} -happyReduce_100 = happySpecReduce_3 20# happyReduction_100-happyReduction_100 happy_x_3+happyReduce_103 = happySpecReduce_3 20# happyReduction_103+happyReduction_103 happy_x_3 happy_x_2 happy_x_1 = case happyOut6 happy_x_1 of { happy_var_1 -> @@ -1328,8 +1364,8 @@ ([Ast "pair" [Astring happy_var_1,happy_var_3]] )}} -happyReduce_101 = happyReduce 4# 20# happyReduction_101-happyReduction_101 (happy_x_4 `HappyStk`+happyReduce_104 = happyReduce 4# 20# happyReduction_104+happyReduction_104 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1341,8 +1377,8 @@ (happy_var_1++[Ast "pair" [Astring happy_var_2,happy_var_4]] ) `HappyStk` happyRest}}} -happyReduce_102 = happySpecReduce_2 21# happyReduction_102-happyReduction_102 happy_x_2+happyReduce_105 = happySpecReduce_2 21# happyReduction_105+happyReduction_105 happy_x_2 happy_x_1 = case happyOut29 happy_x_1 of { happy_var_1 -> case happyOut28 happy_x_2 of { happy_var_2 -> @@ -1350,8 +1386,8 @@ (happy_var_1 "child" (Avar ".") happy_var_2 )}} -happyReduce_103 = happySpecReduce_3 21# happyReduction_103-happyReduction_103 happy_x_3+happyReduce_106 = happySpecReduce_3 21# happyReduction_106+happyReduction_106 happy_x_3 happy_x_2 happy_x_1 = case happyOut29 happy_x_2 of { happy_var_2 -> @@ -1360,8 +1396,8 @@ (happy_var_2 "attribute" (Avar ".") happy_var_3 )}} -happyReduce_104 = happySpecReduce_3 21# happyReduction_104-happyReduction_104 happy_x_3+happyReduce_107 = happySpecReduce_3 21# happyReduction_107+happyReduction_107 happy_x_3 happy_x_2 happy_x_1 = case happyOut29 happy_x_1 of { happy_var_1 -> @@ -1371,8 +1407,8 @@ (happy_var_3 (happy_var_1 "child" (Avar ".") happy_var_2) )}}} -happyReduce_105 = happyReduce 4# 21# happyReduction_105-happyReduction_105 (happy_x_4 `HappyStk`+happyReduce_108 = happyReduce 4# 21# happyReduction_108+happyReduction_108 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1384,15 +1420,15 @@ (happy_var_4 (happy_var_2 "attribute" (Avar ".") happy_var_3) ) `HappyStk` happyRest}}} -happyReduce_106 = happySpecReduce_1 22# happyReduction_106-happyReduction_106 happy_x_1+happyReduce_109 = happySpecReduce_1 22# happyReduction_109+happyReduction_109 happy_x_1 = case happyOut27 happy_x_1 of { happy_var_1 -> happyIn26 (happy_var_1 )} -happyReduce_107 = happySpecReduce_2 22# happyReduction_107-happyReduction_107 happy_x_2+happyReduce_110 = happySpecReduce_2 22# happyReduction_110+happyReduction_110 happy_x_2 happy_x_1 = case happyOut26 happy_x_1 of { happy_var_1 -> case happyOut27 happy_x_2 of { happy_var_2 -> @@ -1400,8 +1436,8 @@ (happy_var_2 . happy_var_1 )}} -happyReduce_108 = happySpecReduce_3 23# happyReduction_108-happyReduction_108 happy_x_3+happyReduce_111 = happySpecReduce_3 23# happyReduction_111+happyReduction_111 happy_x_3 happy_x_2 happy_x_1 = case happyOut29 happy_x_2 of { happy_var_2 -> @@ -1410,8 +1446,8 @@ (\e -> happy_var_2 "child" e happy_var_3 )}} -happyReduce_109 = happyReduce 4# 23# happyReduction_109-happyReduction_109 (happy_x_4 `HappyStk`+happyReduce_112 = happyReduce 4# 23# happyReduction_112+happyReduction_112 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1422,8 +1458,8 @@ (\e -> happy_var_3 "attribute" e happy_var_4 ) `HappyStk` happyRest}} -happyReduce_110 = happyReduce 4# 23# happyReduction_110-happyReduction_110 (happy_x_4 `HappyStk`+happyReduce_113 = happyReduce 4# 23# happyReduction_113+happyReduction_113 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1434,8 +1470,8 @@ (\e -> happy_var_3 "descendant-or-self" e happy_var_4 ) `HappyStk` happyRest}} -happyReduce_111 = happyReduce 5# 23# happyReduction_111-happyReduction_111 (happy_x_5 `HappyStk`+happyReduce_114 = happyReduce 5# 23# happyReduction_114+happyReduction_114 (happy_x_5 `HappyStk` happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk`@@ -1447,15 +1483,15 @@ (\e -> happy_var_4 "attribute-descendant" e happy_var_5 ) `HappyStk` happyRest}} -happyReduce_112 = happySpecReduce_2 23# happyReduction_112-happyReduction_112 happy_x_2+happyReduce_115 = happySpecReduce_2 23# happyReduction_115+happyReduction_115 happy_x_2 happy_x_1 = happyIn27 (\e -> Ast "step" [Avar "parent",Astring "*",e] ) -happyReduce_113 = happyReduce 4# 24# happyReduction_113-happyReduction_113 (happy_x_4 `HappyStk`+happyReduce_116 = happyReduce 4# 24# happyReduction_116+happyReduction_116 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1466,13 +1502,13 @@ (happy_var_1 ++ [happy_var_3] ) `HappyStk` happyRest}} -happyReduce_114 = happySpecReduce_0 24# happyReduction_114-happyReduction_114 = happyIn28+happyReduce_117 = happySpecReduce_0 24# happyReduction_117+happyReduction_117 = happyIn28 ([] ) -happyReduce_115 = happySpecReduce_1 25# happyReduction_115-happyReduction_115 happy_x_1+happyReduce_118 = happySpecReduce_1 25# happyReduction_118+happyReduction_118 happy_x_1 = case happyOut30 happy_x_1 of { happy_var_1 -> happyIn29 (\t e ps -> if null ps@@ -1480,14 +1516,14 @@ else Ast "filter" (happy_var_1 t e:ps) )} -happyReduce_116 = happySpecReduce_1 25# happyReduction_116-happyReduction_116 happy_x_1+happyReduce_119 = happySpecReduce_1 25# happyReduction_119+happyReduction_119 happy_x_1 = happyIn29 (\t e ps -> Ast "step" ((Avar t):(Astring "*"):e:ps) ) -happyReduce_117 = happySpecReduce_1 25# happyReduction_117-happyReduction_117 happy_x_1+happyReduce_120 = happySpecReduce_1 25# happyReduction_120+happyReduction_120 happy_x_1 = case happyOut6 happy_x_1 of { happy_var_1 -> happyIn29 (\t e ps -> if elem happy_var_1 path_steps@@ -1495,8 +1531,8 @@ else Ast "step" ((Avar t):(Astring happy_var_1):e:ps) )} -happyReduce_118 = happyReduce 4# 25# happyReduction_118-happyReduction_118 (happy_x_4 `HappyStk`+happyReduce_121 = happyReduce 4# 25# happyReduction_121+happyReduction_121 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1511,8 +1547,8 @@ else parseError [TError ("Not a valid axis name: "++happy_var_1)] ) `HappyStk` happyRest}} -happyReduce_119 = happyReduce 4# 25# happyReduction_119-happyReduction_119 (happy_x_4 `HappyStk`+happyReduce_122 = happyReduce 4# 25# happyReduction_122+happyReduction_122 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1526,21 +1562,21 @@ else parseError [TError ("Not a valid axis name: "++happy_var_1)] ) `HappyStk` happyRest} -happyReduce_120 = happySpecReduce_1 26# happyReduction_120-happyReduction_120 happy_x_1+happyReduce_123 = happySpecReduce_1 26# happyReduction_123+happyReduction_123 happy_x_1 = case happyOut8 happy_x_1 of { happy_var_1 -> happyIn30 (\_ _ -> happy_var_1 )} -happyReduce_121 = happySpecReduce_1 26# happyReduction_121-happyReduction_121 happy_x_1+happyReduce_124 = happySpecReduce_1 26# happyReduction_124+happyReduction_124 happy_x_1 = happyIn30 (\_ e -> e ) -happyReduce_122 = happySpecReduce_3 26# happyReduction_122-happyReduction_122 happy_x_3+happyReduce_125 = happySpecReduce_3 26# happyReduction_125+happyReduction_125 happy_x_3 happy_x_2 happy_x_1 = case happyOut10 happy_x_2 of { happy_var_2 -> @@ -1550,15 +1586,15 @@ else Ast "context" [e,Astring t,concatenateAll happy_var_2] )} -happyReduce_123 = happySpecReduce_2 26# happyReduction_123-happyReduction_123 happy_x_2+happyReduce_126 = happySpecReduce_2 26# happyReduction_126+happyReduction_126 happy_x_2 happy_x_1 = happyIn30 (\_ _ -> call "empty" [] ) -happyReduce_124 = happyReduce 4# 26# happyReduction_124-happyReduction_124 (happy_x_4 `HappyStk`+happyReduce_127 = happyReduce 4# 26# happyReduction_127+happyReduction_127 (happy_x_4 `HappyStk` happy_x_3 `HappyStk` happy_x_2 `HappyStk` happy_x_1 `HappyStk`@@ -1571,8 +1607,8 @@ else Ast "context" [e,Astring t,call happy_var_1 happy_var_3] ) `HappyStk` happyRest}} -happyReduce_125 = happySpecReduce_3 26# happyReduction_125-happyReduction_125 happy_x_3+happyReduce_128 = happySpecReduce_3 26# happyReduction_128+happyReduction_128 happy_x_3 happy_x_2 happy_x_1 = case happyOut6 happy_x_1 of { happy_var_1 -> @@ -1581,7 +1617,7 @@ )} happyNewToken action sts stk [] =- happyDoAction 72# notHappyAtAll action sts stk []+ happyDoAction 78# notHappyAtAll action sts stk [] happyNewToken action sts stk (tk:tks) = let cont i = happyDoAction i tk action sts stk tks in@@ -1652,11 +1688,17 @@ DOT -> cont 64#; SEMI -> cont 65#; COLON -> cont 66#;- Variable happy_dollar_dollar -> cont 67#;- XMLtext happy_dollar_dollar -> cont 68#;- TInteger happy_dollar_dollar -> cont 69#;- TFloat happy_dollar_dollar -> cont 70#;- TString happy_dollar_dollar -> cont 71#;+ INSERT -> cont 67#;+ DELETE -> cont 68#;+ REPLACE -> cont 69#;+ INTO -> cont 70#;+ FROM -> cont 71#;+ WITH -> cont 72#;+ Variable happy_dollar_dollar -> cont 73#;+ XMLtext happy_dollar_dollar -> cont 74#;+ TInteger happy_dollar_dollar -> cont 75#;+ TFloat happy_dollar_dollar -> cont 76#;+ TString happy_dollar_dollar -> cont 77#; _ -> happyError' (tk:tks) } @@ -1753,7 +1795,8 @@ | AND | OR | NOT | UNION | INTERSECT | EXCEPT | FOR | LET | IN | COMMA | ASSIGN | WHERE | ORDER | BY | ASCENDING | DESCENDING | ELEMENT | ATTRIBUTE | STAG | ETAG | SATISFIES | ATSIGN | SLASH | DECLARE | SEMI | COLON- | FUNCTION | VARIABLE |AT | DOT | DOTS | TokenEOF | PRE | POST | IS+ | FUNCTION | VARIABLE | AT | DOT | DOTS | TokenEOF | PRE | POST | IS+ | INSERT | INTO | DELETE | FROM | REPLACE | WITH | QName String | Variable String | XMLtext String | TInteger Int | TFloat Float | TString String | TError String deriving Eq@@ -1783,6 +1826,7 @@ (BY,"by"),(ASCENDING,"ascending"),(DESCENDING,"descending"),(ELEMENT,"element"), (ATTRIBUTE,"attribute"),(STAG,"</"),(ETAG,"/>"),(SATISFIES,"satisfies"),(ATSIGN,"@"), (SLASH,"/"),(DECLARE,"declare"),(FUNCTION,"function"),(VARIABLE,"variable"),+ (INSERT,"insert"),(INTO,"into"),(DELETE,"delete"),(FROM,"from"),(REPLACE,"replace"),(WITH,"with"), (AT,"at"),(DOTS,".."),(DOT,"."),(SEMI,";"),(COLON,":")] @@ -1972,6 +2016,12 @@ "gt" -> SGT "ge" -> SGE "is" -> IS+ "insert" -> INSERT+ "into" -> INTO+ "delete" -> DELETE+ "from" -> FROM+ "replace" -> REPLACE+ "with" -> WITH var -> QName var ) : lexer rest n {-# LINE 1 "templates/GenericTemplate.hs" #-}
src/Text/XML/HXQ/XQuery.hs view
@@ -28,13 +28,13 @@ -- * The XQuery Interpreter xquery, xfile, -- * The XQuery Compiler with Database Connectivity- xqdb, connect, disconnect,+ xqdb, -- * The XQuery Interpreter with Database Connectivity xqueryDB, xfileDB, -- * Shredding and Publishing XML Documents Using a Relational Database genSchema, shred, shredC, printSchema, createIndex,- -- * Other functions- XMLEvent(..), prepareSQL, executeSQL+ -- * Other Functions+ XMLEvent(..), connect, disconnect, commit, rollback, prepareSQL, executeSQL ) where import HXML(AttList)
src/Text/XML/HXQ/XTree.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 05/01/08, last update: 10/24/08+- Creation: 05/01/08, last update: 11/14/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -20,6 +20,7 @@ module Text.XML.HXQ.XTree where import System.IO+import Char(isSpace) import XMLParse(XMLEvent(..)) import HXML(AttList) import Text.XML.HXQ.Parser(Ast(..))@@ -41,6 +42,7 @@ | XGERef Tag -- ^ general entity reference | XComment String -- ^ comment | XError String -- ^ error report+ | XNull -- ^ null value | XNoPad -- ^ marker for no padding in XSeq deriving Eq @@ -48,13 +50,26 @@ type XSeq = [XTree] +emptyElem :: XTree -> Bool+emptyElem e+ = case e of+ XElem _ al _ _ xs+ -> emptyAL al && all emptyElem xs+ XText text -> all isSpace text+ XNull -> True+ XNoPad -> True+ _ -> False+ where emptyAL = all (\(a,v) -> case (a,v) of (_,"") -> True; ('_':_,_) -> True; _ -> False)++ showAL :: AttList -> String-showAL = foldr (\(a,v) r -> " "++a++"=\""++v++"\""++r) []+showAL = foldr (\(a,v) r -> case (a,v) of (_,"") -> r; ('_':_,_) -> r; _ -> " "++a++"=\""++v++"\""++r) [] showXT :: XTree -> Bool -> String showXT e pad = case e of- XElem tag al _ _ [] -> "<"++tag++showAL al++"/>"+ XElem _ _ _ _ _ | emptyElem e -> ""+ XElem tag al _ _ xs | all emptyElem xs -> "<"++tag++showAL al++"/>" XElem tag al _ _ xs -> "<"++tag++showAL al++">"++showXS xs++"</"++tag++">" XText text -> p++text XInt n -> p++show n@@ -63,6 +78,7 @@ XComment s -> "<!--"++s++"-->" XPI n s -> "<?"++n++" "++s++">" XError s -> error s+ XNull -> "?" _ -> "" where p = if pad then " " else ""
src/mysql/Connect.hs view
@@ -14,7 +14,7 @@ --------------------------------------------------------------------------------------} -module Connect where+module Connect (Connection,connectionDriver,connect) where import Database.HDBC(handleSqlError) import Database.HDBC.ODBC
src/noDB/Text/XML/HXQ/OptionalDB.hs view
@@ -24,13 +24,9 @@ type Statement = String type Table = String -class IConnection conn- data Connection = Connection String -instance IConnection Connection - noDBerror = error "This version of HXQ does not provide database connectivity" @@ -42,7 +38,7 @@ executeSQL stmt args = noDBerror -prepareSQL :: (IConnection conn) => conn -> String -> IO Statement+prepareSQL :: Connection -> String -> IO Statement prepareSQL db sql = noDBerror @@ -55,18 +51,26 @@ disconnect db = noDBerror +commit :: conn -> IO ()+commit db = noDBerror+++rollback :: conn -> IO ()+rollback db = noDBerror++ -- | Print the relational schema of the XML document stored in the database under the given name-printSchema :: (IConnection conn) => conn -> String -> IO ()+printSchema :: Connection -> String -> IO () printSchema db name = noDBerror -- | Create a schema for an XML document into the database under the given name.-genSchema :: (IConnection conn) => conn -> String -> String -> IO Table+genSchema :: Connection -> String -> String -> IO Table genSchema db file name = noDBerror -- | Store an XML document into the database under the given name.-shred :: (IConnection conn) => conn -> String -> String -> IO ()+shred :: Connection -> String -> String -> IO () shred db file name = noDBerror @@ -76,5 +80,17 @@ -- | Create a secondary index on tagname for the shredded document under the given name..-createIndex :: (IConnection conn) => conn -> String -> String -> IO ()+createIndex :: Connection -> String -> String -> IO () createIndex db name tagname = noDBerror+++insertDB :: Connection -> XSeq -> XSeq -> IO XSeq+insertDB db from into = noDBerror+++deleteDB :: Connection -> XSeq -> IO XSeq+deleteDB db from = noDBerror+++replaceDB :: Connection -> XSeq -> XSeq -> IO XSeq+replaceDB db dest with = noDBerror
src/sqlite/Connect.hs view
@@ -14,8 +14,7 @@ --------------------------------------------------------------------------------------} -module Connect where-+module Connect (Connection,connectionDriver,connect) where import Database.HDBC.Sqlite3
src/withDB/Text/XML/HXQ/DB.hs view
@@ -4,7 +4,7 @@ - Programmer: Leonidas Fegaras - Email: fegaras@cse.uta.edu - Web: http://lambda.uta.edu/-- Creation: 05/12/08, last update: 10/25/08+- Creation: 05/12/08, last update: 11/23/08 - - Copyright (c) 2008 by Leonidas Fegaras, the University of Texas at Arlington. All rights reserved. - This material is provided as is, with absolutely no warranty expressed or implied.@@ -13,24 +13,24 @@ - --------------------------------------------------------------------------------------} --{-# OPTIONS_GHC -fth -funbox-strict-fields #-}+{-# LANGUAGE TemplateHaskell #-}+{-# OPTIONS_GHC -funbox-strict-fields #-} module Text.XML.HXQ.DB where import System.IO.Unsafe-import Char(isSpace,toLower)-import List(union,zip)+import Char(isSpace,isDigit,toLower)+import List(zip) import Data.List(foldl')-import Language.Haskell.TH import Database.HDBC import Text.XML.HXQ.XTree+import Text.XML.HXQ.Functions(child_step) import XMLParse(XMLEvent(..),parseDocument) import HXML(AttList) import Text.XML.HXQ.Parser import Connect-+import Language.Haskell.TH sql2xml :: SqlValue -> XTree@@ -49,7 +49,7 @@ SqlRational n -> XText (show n) SqlEpochTime n -> XText (show n) SqlTimeDiff n -> XText (show n)- SqlNull -> XText ""+ SqlNull -> XNull xml2sql :: XTree -> SqlValue@@ -60,10 +60,10 @@ XFloat n -> SqlString (show n) XBool n -> SqlBool n XElem n _ _ _ [x] -> xml2sql x- _ -> error ("Cannot convert "++show e++" into sql")+ _ -> error ("*** Cannot convert "++show e++" into sql") -perror = error "constructed elements have no parent"+perror = error "Constructed elements do not have a parent" executeSQL :: Statement -> XSeq -> IO XSeq@@ -71,15 +71,15 @@ = do n <- handleSqlError (execute stmt (map xml2sql args)) result <- handleSqlError (fetchAllRowsAL stmt) return (map (\x -> XElem "row" [] 0 perror (map (\(s,v) -> XElem (column s) [] 0 perror [sql2xml v]) x)) result)- where column s = if elem '.' s then tail(dropWhile (/= '.') s) else s+ where column s = if elem '.' s then tail (dropWhile (/= '.') s) else s -prepareSQL :: (IConnection conn) => conn -> String -> IO Statement+prepareSQL :: Connection -> String -> IO Statement prepareSQL db sql = handleSqlError (prepare db sql) {------------------------------------------------------------------------------------------ extract the structural summary and statistics from an XML file+-- Extract the structural summary and statistics from an XML file ----------------------------------------------------------------------------------------} @@ -105,24 +105,31 @@ in (c,t:s) -getSS :: [XMLEvent] -> Int -> [SSnode] -> [SSnode]-getSS ((EmptyEvent n atts):xs) count rs- = (getSS ((StartEvent n atts):(EndEvent n):xs) $! count) $! rs-getSS ((StartEvent n atts):xs) count ((SSnode m i j l b len ns):rs)+getSS :: [XMLEvent] -> Int -> [String] -> [SSnode] -> [SSnode]+getSS ((EmptyEvent n atts):xs) count ignored rs+ = ((getSS ((StartEvent n atts):(EndEvent n):xs) $! count) $! ignored) $! rs+getSS ((StartEvent n atts):xs) count ignored rs+ | elem n ignored+ = ((getSS xs $! count) $! ignored) $! rs+getSS ((EndEvent n):xs) count ignored rs+ | elem n ignored+ = ((getSS xs $! count) $! ignored) $! rs+getSS ((StartEvent n atts):xs) count ignored ((SSnode m i j l b len ns):rs) = let (c,SSnode m' i' j' l' b' len' ks,ts) = (insertSS n $! count) 0 $! ns (nc,as) = foldr (\(a,v) (i,s) -> ((insSS ('@':a) $! i) $! (length v)) $! s) (c,ks) atts r (SSnode m i j _ b len ts) = SSnode m i j 0 b len ts reset (SSnode m i j l b len ts) = SSnode m i j l b len (map r ts)- in (getSS xs $! nc) $! (reset (SSnode m' i' j' l' b' len' as):(SSnode m i j l b len ts):rs)-getSS ((EndEvent n):xs) count (t:(SSnode m i j l b len ns):rs)+ in ((getSS xs $! nc) $! ignored) $! (reset (SSnode m' i' j' l' b' len' as):(SSnode m i j l b len ts):rs)+getSS ((EndEvent n):xs) count ignored (t:(SSnode m i j l b len ns):rs) = let s (SSnode m i j l b len ts) = SSnode m i (max j l) 0 b len ts set (SSnode m i j l b len ts) = SSnode m i j l b len (map s ts)- in (getSS xs $! count) $! ((SSnode m i j l b len (set t:ns):rs))-getSS ((TextEvent t):xs) count ((SSnode m i j l _ len ns):rs)+ in ((getSS xs $! count) $! ignored) $! ((SSnode m i j l b len (set t:ns):rs))+getSS ((TextEvent t):xs) count ignored ((SSnode m i j l _ len ns):rs) | any (not . isSpace) t- = (getSS xs $! count) $! ((SSnode m i j l True (max len (length t)) ns):rs)-getSS (_:xs) count rs = (getSS xs $! count) $! rs-getSS [] _ rs = rs+ = ((getSS xs $! count) $! ignored) $! ((SSnode m i j l True (max len (length t)) ns):rs)+getSS (_:xs) count ignored rs+ = ((getSS xs $! count) $! ignored) $! rs+getSS [] _ _ rs = rs {---------------------------------------------------------------------------------------@@ -133,8 +140,8 @@ type Path = [Tag] -data Table = Table String Path Bool [Table]- | Column String Path Int+data Table = Table String Path Bool [Table] -- table-name relative-path mixed-content? components+ | Column String Path Int -- column-name relative-path max-byte-size deriving (Show,Read) @@ -149,44 +156,54 @@ schema :: SSnode -> String -> [String] -> [Table] schema (SSnode n i _ (-1) _ len ts) prefix path- = [ Table (prefix++show i) (pathCons n path) True+ = [ Table (prefix++"_"++show i) (pathCons n path) True ((reverse (concatMap (\t -> schema t prefix []) ts)) ++[ Column "value" [] len ]) ]-schema (SSnode n i j _ _ len []) prefix path- | j == 1 || head n == '@'- = [ Column (prefix++show i) (pathCons n path) len ]+schema (SSnode ('@':n) i j _ _ len []) prefix path+ = [ Column (prefix++"_"++show i) (pathCons ('@':n) path) len ]+schema (SSnode n i 1 _ _ len []) prefix path+ = [ Column (prefix++"_"++show i) (pathCons n path) len ] schema (SSnode n i 1 _ _ _ ts) prefix path- = concatMap (\t -> schema t prefix (pathCons n path)) ts-schema (SSnode n i _ _ b len ts) prefix path- = [ Table (prefix++show i) (pathCons n path) False+ = concatMap (\t -> schema t prefix (n:path)) ts+schema (t@(SSnode n i _ _ b len ts)) prefix path+ = [ Table (prefix++"_"++show i) (pathCons n path) False ((reverse (concatMap (\t -> schema t prefix []) ts))+ ++concatMap (getContent []) ts ++(if b && all (\(SSnode x _ _ _ _ _ _)-> head x == '@') ts then [ Column "value" [] len ] else [])) ]+ where getContent _ (SSnode _ _ _ (-1) _ _ ts) = []+ getContent ps (SSnode n i _ _ True len (_:_))+ = [Column (prefix++"_"++show i) (n:ps) len]+ getContent ps (SSnode n _ 1 _ _ _ ts)+ = concatMap (getContent (n:ps)) ts+ getContent _ _ = [] +-- if an element has both text content and subelements, then it must be mixed content; fixSS :: SSnode -> SSnode fixSS (SSnode n i j l True len ts) | any (\(SSnode x _ _ _ _ _ _)-> head x /= '@') ts- = SSnode n i j (-1) True len (filter (\(SSnode x _ _ _ _ _ _)-> head x == '@') ts)+ = SSnode n i j (-1) True len (map fixSS ts) fixSS (SSnode n i j l b len ts) = SSnode n i j l b len (map fixSS ts) -deriveSchema :: String -> String -> IO Table-deriveSchema file prefix+deriveSchema :: String -> String -> [String] -> IO Table+deriveSchema file prefix ignored = do doc <- readFile file let ts = parseDocument doc- [SSnode _ _ _ _ _ _ [t]] = getSS ts 0 [SSnode "root" 1 1 1 False 0 []]+ [SSnode _ _ _ _ _ _ [t]] = getSS ts 0 ignored [SSnode "root" 1 1 1 False 0 []] nt@(SSnode m i j l b len s) = fixSS t- return $! (Table prefix [] False (reverse (schema (SSnode m i 2 l b len s) prefix [])))+ -- putStrLn (show nt)+ return $! (head (schema (SSnode m i 2 l b len s) prefix [])) relationalSchema :: Table -> String -> [String] relationalSchema (Table n path b ts) parent- = ("create table "++n++" ( /* "++printPath path+ = ("\ncreate table "++n++" ( /* "++printPath path ++(if b then " (mixed content)" else "")++" */\n" ++n++"_id integer primary key not null"- ++(if parent /= "" then (",\n"++n++"_parent integer references "++parent++"("++parent++"_id)") else "")+ ++",\n"++n++"_parent integer"++(if parent /= "" then (" references "++parent++"("++parent++"_id)") else "") ++(concat [ ",\n"++m++" varchar("++show size++") /* "++printPath p++" */" | Column m p size <- ts ]) ++")\n") :[ s | t@(Table _ _ _ _) <- ts, s <- relationalSchema t n ]@@ -197,7 +214,7 @@ getTableNames _ = [] -initializeDB :: (IConnection conn) => conn -> IO ()+initializeDB :: Connection -> IO () initializeDB db = do tbs <- getTables db -- mySql always returns [] desc <- if null tbs && connectionDriver /= "sqlite"@@ -212,8 +229,8 @@ else return () -createSchema :: (IConnection conn) => conn -> String -> String -> IO Table-createSchema db file name+createSchema :: Connection -> String -> String -> [String] -> IO Table+createSchema db file name ignored = do initializeDB db stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?") _ <- handleSqlError (execute stmt [SqlString name])@@ -227,7 +244,7 @@ _ <- handleSqlError (run db "delete from HXQCatalog where name = ?" [SqlString name]) commit db else return ()- t <- deriveSchema file name+ t <- deriveSchema file name ignored let schema = relationalSchema t "" _ <- handleSqlError (run db "insert into HXQCatalog values (?,?,?,?,?)" [SqlString name, SqlInteger 0, SqlString file,@@ -237,7 +254,14 @@ return $! t -findSchema :: (IConnection conn) => conn -> String -> IO Table+-- | Create a schema for an XML document into the database under the given name.+-- The excluded tags are HTML tags to be ignored+genSchema :: Connection -> String -> String -> [String] -> IO Table+genSchema db file name excludedTags+ = createSchema db file (map toLower name) excludedTags+++findSchema :: Connection -> String -> IO Table findSchema db name = do initializeDB db stmt <- handleSqlError (prepare db "select summary from HXQCatalog where name = ?")@@ -246,11 +270,11 @@ if length result == 1 then let [[(_,SqlString s)]] = result in return $! ((read s)::Table)- else error ("Schema "++name++" doesn't exist")+ else error ("*** Schema "++name++" doesn't exist") -- | Print the relational schema of the XML document stored in the database under the given name-printSchema :: (IConnection conn) => conn -> String -> IO ()+printSchema :: Connection -> String -> IO () printSchema db name = do initializeDB db stmt <- handleSqlError (prepare db "select relational_schema from HXQCatalog where name = ?")@@ -259,7 +283,7 @@ if length result == 1 then let [[(_,SqlString s)]] = result in putStrLn s- else error ("Schema "++name++" doesn't exist")+ else error ("*** Schema "++name++" doesn't exist") {---------------------------------------------------------------------------------------@@ -268,10 +292,18 @@ findPath :: [Table] -> [String] -> Int -> Maybe (Int,Table)-findPath (t@(Table _ p _ s):ts) path _ | p == path = Just ((length s)-1,t)-findPath (t@(Column _ p _):ts) path n | p == path = Just (n,t)-findPath ((Table _ _ _ _):ts) path n = findPath ts path n-findPath (_:ts) path n = findPath ts path (n+1)+findPath (t@(Table _ p _ s):ts) path _+ | p == path+ = Just (length[ 1 | Column _ _ _ <- s]-1,t)+findPath (t@(Column _ p _):ts) path n+ | p == path+ = Just (n,t)+findPath ((Table _ _ _ s):ts) path n+ = let xs = findPath s path n+ xt = findPath ts path n+ in case xs of Nothing -> xt; _ -> xs+findPath (_:ts) path n+ = findPath ts path (n+1) findPath [] _ _ = Nothing @@ -280,21 +312,13 @@ = populate ((StartEvent tag atts):(EndEvent tag):xs) ts n ps populate (x@(StartEvent tag atts):xs) ((t@(Table n path _ s)):ts) _ (p:ps) = case findPath s (tag:p) 0 of- Just (n,nt@(Table m _ True as))- -> (-1,m):(popAtts atts as ++ showXTree xs 1 "")- where showXTree ((EmptyEvent tag atts):xs) i s- = showXTree xs i (s++"<"++tag++showAL atts++"/>")- showXTree ((StartEvent tag atts):xs) i s- = showXTree xs (i+1) (s++"<"++tag++showAL atts++">")- showXTree ((EndEvent tag):xs) i s- = if i==1 then (n,s):(-2,m):(populate xs (t:ts) n (p:ps))- else showXTree xs (i-1) (s++"</"++tag++">")- showXTree ((TextEvent text):xs) i s = showXTree xs i (s++text)- showXTree (_:xs) i s = showXTree xs i s Just (n,nt@(Table m _ _ as)) -> (-1,m):((popAtts atts as)++(populate xs (nt:t:ts) n ([]:p:ps))) Just (n,nt)- -> populate xs (nt:t:ts) n ((tag:p):ps)+ -> map (\(a,v) -> case findPath ts (('@':a):tag:p) 0 of+ Just (n,_) -> (n,v)+ Nothing -> error ("*** Unrecognized attribute: "++a)) atts+ ++ populate xs (nt:t:ts) n ((tag:p):ps) Nothing -> populate xs (t:ts) 0 ((tag:p):ps) where popAtts ((a,v):as) ks = let Just(m,_) = findPath ks ['@':a] 0@@ -314,11 +338,17 @@ populate [] ts n ps = [] -insert :: (IConnection conn) => conn -> [(Int,String)] -> Integer -> [(String,Int,Statement)] -> IO Integer-insert db xs id stmts = let (s,_,_,_) = m xs id 0 in s+insert :: [(Int,String)] -> Integer -> Integer -> [(String,Int,Statement)] -> IO (Integer,[(Int,String)])+insert xs id parent stmts = let (s,binds,rest,_) = m xs id parent+ in if null rest+ then do n <- s; return (n,binds)+ else do n <- s+ (m,mb) <- insert rest n parent stmts+ return (m,mb++binds) where m ((-1,m):xs) i p = let (s,el,xs',i') = ml xs (i+1) i in ((insertTuple m el i p) >> s,[],xs',i') m ((k,m):xs) i p = (return i,[(k,m)],xs,i)+ m [] i p = (return i,[],[],i) ml [] i p = (return i,[],[],i) ml ((-2,m):xs) i p = (return i,[],xs,i) ml xs i p = let (s,el,xs',i') = m xs i p@@ -329,42 +359,35 @@ = let (len,stmt) = foldr (\(a,l,s) r -> if m==a then (l,s) else r) (error "*** sql stmt not found") stmts tuple = map (\c -> find c e) [0..len] lift x = if x=="\NUL" then SqlNull else SqlString x- in do _ <- handleSqlError (execute stmt- (if i==id- then SqlInteger i:(map lift tuple)- else SqlInteger i:SqlInteger p:(map lift tuple)))+ in do -- putStrLn (m++show(show i:show p:tuple))+ _ <- handleSqlError (execute stmt (SqlInteger i:SqlInteger p:(map lift tuple))) return i --- | Create a schema for an XML document into the database under the given name.-genSchema :: (IConnection conn) => conn -> String -> String -> IO Table-genSchema db file name- = createSchema db file (map toLower name)+tableStmt db root (Table n _ _ ts)+ = do let len = length[ 1 | Column _ _ _ <- ts ]-1+ stmt <- handleSqlError (prepare db ("insert into "++n++" values (?,?"+ ++(concatMap (\_ -> ",?") [0..len])++")"))+ l <- mapM (tableStmt db root) ts+ return $! ((n,len,stmt):(concat l))+tableStmt _ _ _ = return [] -- | Store an XML document into the database under the given name.-shred :: (IConnection conn) => conn -> String -> String -> IO ()+shred :: Connection -> String -> String -> IO () shred db file name = do let prefix = map toLower name- t <- findSchema db prefix- --putStrLn (show t)- let tableStmt (Table n _ _ ts)- = do let len = length[ 1 | Column _ _ _ <- ts ]-1- stmt <- handleSqlError (prepare db ("insert into "++n++" values ("- ++(if n==prefix then "" else "?,")++"?"- ++(concatMap (\_ -> ",?") [0..len])++")"))- l <- mapM tableStmt ts- return $! ((n,len,stmt):(concat l))- tableStmt _ = return []- stmts <- tableStmt t+ t@(Table root _ _ _) <- findSchema db prefix+ stmts <- tableStmt db root t stmt1 <- prepare db "select next_id from HXQCatalog where name = ?" _ <- execute stmt1 [SqlString prefix] [[(_,SqlString ids)]] <- fetchAllRowsAL stmt1 doc <- readFile file- let id = read ids+ let id = (read ids)+1 ts = parseDocument doc- ic = (-1,prefix):(populate ts [t] 0 [[]] ++ [(-2,prefix)])- new_id <- insert db ic id stmts+ ic = populate ts [Table prefix [] True [t]] 0 [[]]+ -- putStrLn (show ic)+ (new_id,_) <- insert ic id 0 stmts stmt2 <- prepare db "update HXQCatalog set next_id = ? where name = ?" execute stmt2 [SqlInteger new_id,SqlString prefix] commit db@@ -372,13 +395,13 @@ -- | Create a secondary index on tagname for the shredded document under the given name..-createIndex :: (IConnection conn) => conn -> String -> String -> IO ()+createIndex :: Connection -> String -> String -> IO () createIndex db name tagname = do let prefix = map toLower name table <- findSchema db name let indexes = getIndexes "" table _ <- if null indexes- then error ("there is no tagname: "++tagname)+ then error ("*** Tthere is no tagname: "++tagname) else mapM (\(t,c) -> do -- putStrLn (t++" "++c) stmt <- handleSqlError (prepare db ("create index "++t++"_"++c++" on "++t++" ("++c++")")) handleSqlError (execute stmt [])) indexes@@ -396,7 +419,7 @@ {-# NOINLINE insertTuple #-}-insertTuple :: (IConnection conn) => conn -> Statement -> String -> Int+insertTuple :: Connection -> Statement -> String -> Int -> [Integer] -> [[(Int,String)]] -> [[(Int,String)]] insertTuple db stmt nm len (id:parent:_) (c:cs) = let find x xs = foldr (\(a,v) r -> if x==a then v else r) "\NUL" xs@@ -406,9 +429,7 @@ p = toInteger parent query = unsafePerformIO (do -- putStrLn (nm++show(show i:show p:tuple))- catchSql (do execute stmt (if id==0- then SqlInteger i:(map lift tuple)- else SqlInteger i:SqlInteger p:(map lift tuple))+ catchSql (do execute stmt (SqlInteger i:SqlInteger p:(map lift tuple)) return ()) (\ e -> putStrLn (show e++show cs)) if mod id 10000 == 9999@@ -418,15 +439,16 @@ in query `seq` cs -pushTuple :: (Int,String) -> [[(Int,String)]] -> [[(Int,String)]]-pushTuple a (x:xs) = (a:x):xs+pushColumn :: (Int,String) -> [[(Int,String)]] -> [[(Int,String)]]+pushColumn a (x:xs) = (a:x):xs pushAttributes :: [(String,String)] -> [(Int,String)] -> [[(Int,String)]] -> [[(Int,String)]] pushAttributes atts ps (x:xs) = ((map (\(a,v) -> findColumn a v ps) atts)++x):xs where findColumn name value ps- = foldr (\(i,a) r -> if a==name then (i,value) else r) (error ("column "++name++" not found")) ps+ = foldr (\(i,a) r -> if a==name then (i,value) else r)+ (error ("*** Column "++name++" not found")) ps dfa state stream values i ancs c@@ -442,63 +464,93 @@ shredC dbname file name = unsafePerformIO ( do let prefix = map toLower name+ rev (Table n path b ts) = Table n (reverse path) b (map rev ts)+ rev (Column tag path len) = Column tag (reverse path) len dbc <- connect dbname- table <- findSchema dbc prefix- let intE = litE . integerL . toInteger+ tbl <- findSchema dbc prefix+ let table = rev tbl+ intE = litE . integerL . toInteger intP = litP . integerL . toInteger- genCase table cols state pats c- = case table of- Column _ ['@':_] _- -> c state pats- Column nm path _- -> let col = findTag nm cols- in genPath (reverse path) state pats- (\m ps -> (match (tupP [intP m,infixP (conP (mkName "TextEvent") [dp]) (mkName ":") rp])- (normalB [| ($(intE m),pushTuple ($(intE col),$d) $cs,- $current,$ancestors,$r) |]) []):(c m ps))- Table nm path mixed ts- -> let cols = zip [2..] [ a | Column a _ _ <- ts ]- atts = [ (i,a) | (i,['@':a]) <- zip [2..] [ p | Column _ p _ <- ts ] ]- in genTuple (reverse path) nm atts state pats cols- (\m -> foldr (\t r _ ps -> genCase t cols m ps r) c ts m)+ pathHead (Table _ (tag:_:_) _ _) = Just tag+ pathHead (Column _ (tag:_:_) _) = Just tag+ pathHead _ = Nothing+ filter _ [] = ([],[])+ filter tag ((Table n (p:ps) b s):ts)+ | p == tag+ = let (s1,s2) = filter tag ts+ in ((Table n ps b s):s1,s2)+ filter tag ((Column n (p:ps) len):ts)+ | p == tag+ = let (s1,s2) = filter tag ts+ in ((Column n ps len):s1,s2)+ filter tag (t:ts)+ = let (s1,s2) = filter tag ts+ in (s1,t:s2) findTag tag = foldr (\(n,t) r -> if t==tag then n else r) (error "tag not found")- findState state tag = foldr (\(b,t,a) r -> if t==tag && b==state then a else r) (-1)- genTuple [] _ _ state pats _ c = c state pats- genTuple (p:path) nm atts state pats cols c- = let after = findState state p pats- in if after >= 0- then genPath path after pats c- else let next = (length pats)+2- ncs = [| [] : $cs |]- ae xs = if null atts- then [| $xs |]- else [| pushAttributes $al $(listE (map (\(i,a) -> tupE [intE i,litE (stringL a)]) atts)) $xs |]- in [match (tupP [intP state,infixP (conP (mkName "StartEvent") [litP (stringL p),alp]) (mkName ":") rp])+ getColumns nm ts = zip [2..] [ a | Column a _ _ <- ts ]+ getAttributes nm ts = [ (i,a) | (i,['@':a]) <- zip [2..] [ p | Column _ p _ <- ts ] ]+ genCodeL [] state avail _+ = (avail,[])+ genCodeL (x@(t:ts)) state avail cols+ = case pathHead t of+ Nothing+ -> let (i1,c1) = genCode t state avail cols+ (i2,c2) = genCodeL ts state i1 cols+ in (i2,c1++c2)+ Just tag -> let (s1,s2) = filter tag x+ (i1,c1) = genCodeL s1 avail (avail+1) cols+ (i2,c2) = if null s2 then (i1,[]) else genCodeL s2 state i1 cols+ atts = [ (findTag m cols,a) | Column m ['@':a] _ <- s1++s2 ]+ in (i2,skipTag tag state avail atts ++ c1 ++ c2)+ skipTag tag state avail atts+ = let next = avail+ ae xs = if null atts+ then [| $xs |]+ else [| pushAttributes $al $(listE (map (\(i,a) -> tupE [intE i,litE (stringL a)]) atts)) $xs |]+ in [ match (tupP [intP state,infixP (conP (mkName "StartEvent") [litP (stringL tag),alp]) (mkName ":") rp])+ (normalB [| ($(intE next),$(ae cs),$current,$ancestors,$r) |]) [],+ match (tupP [intP next,infixP (conP (mkName "EndEvent") [litP (stringL tag)]) (mkName ":") rp])+ (normalB [| ($(intE state),$cs,$current,$ancestors,$r) |]) [],+ match (tupP [intP state,infixP (conP (mkName "EmptyEvent") [litP (stringL tag),alp]) (mkName ":") rp])+ (normalB [| ($(intE state),$(ae cs),$current,$ancestors,$r) |]) []]+ genCode (Column "value" [] _) state avail cols+ = (avail,[ match (tupP [intP state,infixP (conP (mkName "TextEvent") [dp]) (mkName ":") rp])+ (normalB [| ($(intE state),pushColumn ($(intE (findTag "value" cols)),$d) $cs,+ $current,$ancestors,$r) |]) [] ])+ genCode (Column nm ['@':tag] _) state avail _+ = (avail,[])+ genCode (Column nm [] _) state avail cols+ = (avail,[ match (tupP [intP state,infixP (conP (mkName "TextEvent") [dp]) (mkName ":") rp])+ (normalB [| ($(intE state),pushColumn ($(intE (findTag nm cols)),$d) $cs,+ $current,$ancestors,$r) |]) [] ])+ genCode (Table nm [tag] mixed ts) state avail _+ = let next = avail+ ncs = [| [] : $cs |]+ cols = getColumns nm ts+ atts = getAttributes nm ts+ ae xs = if null atts+ then [| $xs |]+ else [| pushAttributes $al $(listE (map (\(i,a) -> tupE [intE i,litE (stringL a)]) atts)) $xs |]+ (i,c) = genCodeL ts next (avail+1) cols+ in (i,[ match (tupP [intP state,infixP (conP (mkName "StartEvent") [litP (stringL tag),alp]) (mkName ":") rp]) (normalB [| ($(intE next),$(ae ncs),$current+1,($current+1) : $ancestors,$r) |]) [],- match (tupP [intP next,infixP (conP (mkName "EndEvent") [litP (stringL p)]) (mkName ":") rp])+ match (tupP [intP next,infixP (conP (mkName "EndEvent") [litP (stringL tag)]) (mkName ":") rp]) (normalB [| ($(intE state),- insertTuple $db $(varE (mkName (nm++"_stmt"))) $(litE (stringL p))+ insertTuple $db $(varE (mkName (nm++"_stmt"))) $(litE (stringL nm)) $(intE ((length cols)+1)) $ancestors $cs, $current,tail $ancestors,$r) |]) [],- match (tupP [intP state,infixP (conP (mkName "EmptyEvent") [litP (stringL p),alp]) (mkName ":") rp])+ match (tupP [intP state,infixP (conP (mkName "EmptyEvent") [litP (stringL tag),alp]) (mkName ":") rp]) (normalB [| ($(intE state),- insertTuple $db $(varE (mkName (nm++"_stmt"))) $(litE (stringL p))+ insertTuple $db $(varE (mkName (nm++"_stmt"))) $(litE (stringL nm)) $(intE ((length cols)+1)) (($current+1) : $ancestors) $(ae ncs),- $current+1,$ancestors,$r) |]) []]- ++(genPath path next ((state,p,next):pats) c)- genPath [] state pats c = c state pats- genPath (p:path) state pats c- = let after = findState state p pats- in if after >= 0- then genPath path after pats c- else let next = (length pats)+2- in [match (tupP [intP state,infixP (conP (mkName "StartEvent") [litP (stringL p),alp]) (mkName ":") rp])- (normalB [| ($(intE next),$cs,$current,$ancestors,$r) |]) [],- match (tupP [intP next,infixP (conP (mkName "EndEvent") [litP (stringL p)]) (mkName ":") rp])- (normalB [| ($(intE state),$cs,$current,$ancestors,$r) |]) [],- match (tupP [intP state,infixP (conP (mkName "EmptyEvent") [litP (stringL p),alp]) (mkName ":") rp])- (normalB [| ($(intE state),$cs,$current,$ancestors,$r) |]) []]- ++(genPath path next ((state,p,next):pats) c)+ $current+1,$ancestors,$r) |]) [] ]+ ++ c)+ genCode (Column nm (tag:path) k) state avail cols+ = let (i,s) = genCode (Column nm path k) avail (avail+1) cols+ in (i,skipTag tag state avail []++s)+ genCode (Table nm (tag:path) mixed ts) state avail cols+ = let (i,s) = genCode (Table nm path mixed ts) avail (avail+1) cols+ in (i,skipTag tag state avail []++s) s = varE (mkName "s") r = varE (mkName "r") current = varE (mkName "i")@@ -512,26 +564,24 @@ rp = varP (mkName "r") dp = varP (mkName "d") alp = varP (mkName "al")+ (_,caseCode) = genCode table 1 2 [] code = lamE [sp,varP (mkName "i"),varP (mkName "ancs"),varP (mkName "cs")] (caseE (varE (mkName "s"))- ((genCase table [] 1 [] (\_ _ -> []))- ++[match (tupP [sp,infixP wildP (mkName ":") rp])- (normalB [| ($s,$cs,$current,$ancestors,$r) |]) [],- match wildP (normalB [| (0,[],1,[],[]) |]) []]))+ (caseCode++[match (tupP [sp,infixP wildP (mkName ":") rp])+ (normalB [| ($s,$cs,$current,$ancestors,$r) |]) [],+ match wildP (normalB [| (0,[],1,[],[]) |]) []])) tableStmt (Table n _ _ ts) = let len = length[ 1 | Column _ _ _ <- ts ]-1- ins = "insert into "++n++" values ("- ++(if n==prefix then "" else "?,")++"?"+ ins = "insert into "++n++" values (?,?" ++(concatMap (\_ -> ",?") [0..len])++")"- stmt = [| handleSqlError (prepare $db $(litE (stringL ins))) |]+ stmt = [| prepare $db $(litE (stringL ins)) |] in (n++"_stmt",stmt):concatMap tableStmt ts tableStmt _ = [] mseq a v b = infixE (Just a) (varE (mkName ">>=")) (Just (lamE [varP (mkName v)] b)) ret = foldr (\(n,s) r -> mseq s n r)- [| do execute $(varE (mkName (prefix++"_stmt"))) [SqlInteger $id]- return $! dfa 1 $(varE (mkName "doc")) [[]] $id [0] $code |]+ [| return $! dfa 1 $(varE (mkName "doc")) [[]] $id [0] $code |] (tableStmt table)- -- runQ ret >>= putStrLn.pprint+ -- runQ code >>= putStrLn.pprint return $! [| do d <- readFile $(litE (stringL file)) let doc = parseDocument d db <- connect $(litE (stringL dbname))@@ -553,33 +603,35 @@ -- construct an XQuery (in string form) that extracts a shredded XML document-publishTable :: Table -> Bool -> String-publishTable table needsParent- = "<root>{" ++ pubS (rev table) "()" id ++ "}</root>"- where rev (Table n path b ts) = Table n (reverse path) b (map rev ts)- rev (Column tag path len) = Column tag (reverse path) len- pubS (Table n [] _ ts) _ _- = "for $"++n++" in SQL(select(),from($"++n++"),true()) return " ++ pubLS ts n "()" id- pubS (Table n (p:_) _ ts) parent c- = c ("{for $"++n++" in SQL(select(),from($"++n++"),$"++n++"/"++n++"_parent eq $"- ++parent++"/"++parent++"_id) return "- ++"<"++p++">"- -- "{attribute {'_id'} {$"++n++"/"++n++"_id/text()}}"- -- ++",attribute {'_parent'} {"++(if needsParent then "$"++parent else "()")++"}}"- ++ pubLS ts n parent id ++ "</"++p++">}")+publishTable :: Table -> String -> Bool -> String+publishTable (table@(Table n _ _ _)) schema needsParent+ = "<root>{attribute {'_id'} {'0'},attribute {'_parent'} {()}"+ ++",attribute {'_table'} {'"++schema++" "++n++" "++n++"'}}"+ ++ pubS table "()" id ++ "</root>"+ where pubS (Table n (p:_) _ ts) parent c+ = c ("{for $"++n++" in SQL(select(),tables($"++n++"),"+ ++(if parent == "()"+ then "true()"+ else "$"++n++"/"++n++"_parent eq $"++parent++"/"++parent++"_id")+ ++") return <"++p++">"++header n n False++"}"++ pubLS ts n parent id ++ "</"++p++">}") pubS (Column tag (('@':p):_) _) parent c- = c ("attribute "++p++" {$"++parent++"/"++tag++"/text()}")+ = c ("{attribute "++p++" {$"++parent++"/"++tag++"/text()}}") pubS (Column tag (p:_) _) parent c- = c ("<"++p++">{$"++parent++"/"++tag++"/text()}</"++p++">")- pubS (Column "value" [] _) parent c- = c ("{$"++parent++"/value/text()}")+ = c ("<"++p++">"++header tag parent False++",$"++parent++"/"++tag++"/text()}</"++p++">")+ pubS (Column tag [] _) parent c+ = c ("{$"++parent++"/"++tag++"/text()}")+ header tag parent composite+ = "{attribute {'_id'} {$"++parent++"/"++parent++"_id/text()}"+ ++",attribute {'_parent'} {"++(if needsParent && parent /= "()/()_id" then "$"++parent else "()")++"}"+ ++",attribute {'_table'} {'"++schema++" "++parent++(if composite then " +" else " ")++tag++"'}" pubLS [] _ _ c = c "" pubLS (x@(t:ts)) n parent c = case head t of Nothing -> (pubS t n c)++(pubLS ts n parent c) Just tag -> let (s1,s2) = filter tag (reverse x)- in (mkE tag s1 c)++(if null s2 then "" else (","++pubLS s2 n parent id))- where mkE tag s c = "<"++tag++">"++pubLS s n parent c++"</"++tag++">"+ in (mkE tag s1 c)++(if null s2 then "" else pubLS s2 n parent id)+ where mkE tag s c+ = "<"++tag++">"++header tag n True++"}"++pubLS s n parent c++"</"++tag++">" head (Table _ (p:_:_) _ _) = Just p head (Column _ (p:_:_) _) = Just p head _ = Nothing@@ -604,11 +656,170 @@ = let query = unsafePerformIO (publishWrapper filepath name) [ast] = parse (scan query) in ast- where publishWrapper filepath name+ where rev (Table n path b ts) = Table n (reverse path) b (map rev ts)+ rev (Column tag path len) = Column tag (reverse path) len+ publishWrapper filepath name = do let prefix = map toLower name db <- connect filepath table <- findSchema db prefix -- putStrLn (show table)- let query = publishTable table needsParent+ let query = publishTable (rev table) prefix needsParent -- putStrLn query return $! query+++{----------------------------------------------------------------------------------------------------+-- Database updates+----------------------------------------------------------------------------------------------------}+++dbError :: Connection -> String -> IO a+dbError db msg = rollback db >> error ("*** "++msg)+++toStream :: XSeq -> [XMLEvent]+toStream ((XElem tag al _ _ ts):xs)+ = (StartEvent tag al):(toStream ts++((EndEvent tag):toStream xs))+toStream (x:xs) = (TextEvent (show x)):toStream xs+toStream [] = []+++insertChildren :: Connection -> String -> Table -> XSeq -> Int -> IO [(Int,String)]+insertChildren db schema table children parent+ = do stmts <- tableStmt db schema table+ stmt1 <- prepare db "select next_id from HXQCatalog where name = ?"+ execute stmt1 [SqlString schema]+ [[(_,SqlString ids)]] <- fetchAllRowsAL stmt1+ let id = (read ids)+1+ Table tag _ _ ts = table+ ic = populate (toStream children) [table,table] 0 [[],[]]+ (new_id,binds) <- insert ic id (toInteger parent) stmts+ stmt2 <- prepare db "update HXQCatalog set next_id = ? where name = ?"+ execute stmt2 [SqlInteger new_id,SqlString schema]+ return binds+++getDestinationTable :: Table -> String -> [Table]+getDestinationTable (x@(Table t _ _ ts)) tname+ | t == tname+ = [x]+getDestinationTable (Table t _ _ ts) tname+ = concatMap (\t -> getDestinationTable t tname) ts+getDestinationTable _ _ = []+++insertDB :: Connection -> XSeq -> XSeq -> IO XSeq+insertDB db from into+ = case into of+ [d@(XElem tag (("_table",tnm):_) id parent cs)]+ -> do let [schema,tableName,attrName] = words tnm+ table <- findSchema db schema+ let [dest@(Table _ _ _ tbs)] = getDestinationTable table tableName+ if attrName == tableName+ then insertChildren db schema dest from id+ else do mapM (\x -> case x of+ XElem t _ _ _ ts+ -> if head attrName == '+'+ then case [ z | z@(Table _ (tn:_) _ _) <- tbs, t==tn ] of+ [Table tx (tn:_) tb s]+ -> insertChildren db schema (Table tableName [] False [Table tx [tn] tb s]) from id+ _ -> case child_step t d of+ c@[XElem _ _ _ _ [XNull]]+ -> replaceDB db c ts >> return []+ [] -> dbError db ("You cannot insert this element at this position: "++show x)+ _ -> dbError db ("There is already an inserted element "+ ++"at this position; use replace instead: "++show x)+ else case child_step t d of+ c@[XElem _ _ _ _ [XNull]]+ -> replaceDB db c ts >> return []+ [] -> dbError db ("You cannot insert this element at this position: "++show x)+ _ -> dbError db ("There is already an inserted element "+ ++"at this position; use replace instead: "++show x)+ _ -> dbError db ("Incompatible insertion source: "++show x)+ ) from+ return []+ return from+ _ -> dbError db ("The insert destination must be a single persistent XML element: "++show into)+++removeTuples :: Connection -> String -> Table -> Integer -> IO ()+removeTuples db schema (Table n _ _ ts) parent+ = do stmt <- handleSqlError (prepare db ("select "++n++"_id from "++n++" where "++n++"_parent = ?"))+ handleSqlError (execute stmt [SqlInteger parent])+ result <- fetchAllRowsAL stmt+ case result of+ [[(_,SqlString ids)]]+ -> do let id = read ids+ handleSqlError (run db ("delete from "++n++" where "++n++"_id = ?") [SqlInteger id])+ mapM (\t -> removeTuples db schema t id) ts+ return ()+ _ -> return ()+removeTuples _ _ _ _ = return ()+++getColumns (XElem tag (("_table",tnm):_) id parent cs)+ = let [schema,tableName,attrName] = words tnm+ in if head attrName == '+'+ then concatMap getColumns cs+ else [attrName]+getColumns _ = []+++deleteDB :: Connection -> XSeq -> IO XSeq+deleteDB db (x@(XElem tag (("_table",tnm):_) id parent cs):xs)+ = do let [schema,tableName,attrName] = words tnm+ if tableName /= attrName+ then mapM (\c -> handleSqlError (run db ("update "++tableName++" set "++c+ ++" = NULL where "++tableName++"_id = ?")+ [SqlInteger (toInteger id)]))+ (getColumns x)+ else do table <- findSchema db schema+ let [Table n _ _ ts] = getDestinationTable table tableName+ handleSqlError (run db ("delete from "++n++" where "++n++"_id = ?")+ [SqlInteger (toInteger id)])+ mapM (\t -> removeTuples db schema t (toInteger id)) ts+ return [0]+ deleteDB db xs+deleteDB db (x:_) = dbError db ("You may only delete persistent XML elements: "++show x)+deleteDB _ [] = return []+++replaceDB :: Connection -> XSeq -> XSeq -> IO XSeq+replaceDB db dest with+ = case dest of+ [d@(XElem tag (("_table",tnm):_) id parent cs)]+ -> do let [schema,tableName,attrName] = words tnm+ update x = do handleSqlError (run db ("update "++tableName++" set "++attrName+ ++" = ? where "++tableName++"_id = ?")+ [SqlString (show x),SqlInteger (toInteger id)])+ return []+ table <- findSchema db schema+ if tableName == attrName+ then let [dest@(Table _ _ _ ts)] = getDestinationTable table tableName+ in do handleSqlError (run db ("delete from "++tableName++" where "++tableName++"_id = ?")+ [SqlInteger (toInteger id)])+ mapM (\t -> removeTuples db schema t (toInteger id)) ts+ insertChildren db schema dest with id+ return []+ else case with of+ [XElem t _ _ _ ts]+ -> if t == tag+ then mapM (\w -> case w of+ XNoPad -> return []+ XElem t' _ _ _ _ + -> case child_step t' d of+ [z] -> replaceDB db [z] [w]+ _ -> dbError db ("The replace destination element tagged '"+ ++tag++"' does not have a child tagged '"++t'++"'")+ _ -> if head attrName == '+'+ then dbError db ("The destination element tagged '"+ ++tag++"' can only be replaced with another element")+ else update w+ ) ts+ else dbError db ("The destination element tagged '"+ ++tag++"' cannot be replaced with an element tagged '"++t++"'")+ [x] | head attrName /= '+' -> update x+ [] -> return []+ _ -> dbError db ("The replace source must be a singleton value: "++show with)+ return with+ _ -> dbError db ("The replace destination must be a single persistent XML element: "++show dest)
src/withDB/Text/XML/HXQ/OptionalDB.hs view
@@ -15,8 +15,8 @@ module Text.XML.HXQ.OptionalDB- ( IConnection, Statement, publishXmlDoc, executeSQL, prepareSQL, connect, disconnect,- genSchema, shred, shredC, printSchema, createIndex+ ( IConnection, Statement, Connection, publishXmlDoc, executeSQL, prepareSQL, connect, disconnect, commit, rollback,+ genSchema, shred, shredC, printSchema, createIndex, insertDB, deleteDB, replaceDB ) where