orchid (empty) → 0.0.6
raw patch · 62 files changed
+9115/−0 lines, 62 filesdep +QuickCheckdep +basedep +bytestringsetup-changedbinary-added
Dependencies added: QuickCheck, base, bytestring, containers, directory, encoding, hscolour, mtl, nano-md5, parsec, process, salvia, stm, time, unix, utf8-string, xml
Files
- LICENSE +28/−0
- Setup.lhs +6/−0
- orchid.cabal +93/−0
- src/Misc/Commons.hs +195/−0
- src/Network/Orchid/Backend/CachingBackend.hs +40/−0
- src/Network/Orchid/Backend/DarcsBackend.hs +165/−0
- src/Network/Orchid/Core/Backend.hs +31/−0
- src/Network/Orchid/Core/Format.hs +20/−0
- src/Network/Orchid/Core/Handler.hs +107/−0
- src/Network/Orchid/Core/Liaison.hs +108/−0
- src/Network/Orchid/Format/Haskell.hs +16/−0
- src/Network/Orchid/Format/History.hs +19/−0
- src/Network/Orchid/Format/Html.hs +17/−0
- src/Network/Orchid/Format/Latex.hs +15/−0
- src/Network/Orchid/Format/Pdf.hs +29/−0
- src/Network/Orchid/Format/Plain.hs +12/−0
- src/Network/Orchid/Format/Xml.hs +17/−0
- src/Network/Orchid/FormatRegister.hs +28/−0
- src/Network/Orchid/Wiki.hs +8/−0
- src/Text/Document/Core/Processing.hs +37/−0
- src/Text/Document/Core/Type.hs +1941/−0
- src/Text/Document/Document.hs +23/−0
- src/Text/Document/Parser/Wiki.hs +209/−0
- src/Text/Document/Parser/WikiHelper.hs +85/−0
- src/Text/Document/Plugin.hs +133/−0
- src/Text/Document/Plugin/Formula.hs +109/−0
- src/Text/Document/Plugin/HsColour.hs +64/−0
- src/Text/Document/Plugin/TOC.hs +37/−0
- src/Text/Document/PluginRegister.hs +16/−0
- src/Text/Xhtml/Xhtml.hs +67/−0
- src/Text/Xml/Xml.hs +375/−0
- viewer/favicon.gif binary
- viewer/img/loading.gif binary
- viewer/img/shadow00.png binary
- viewer/img/shadow01.png binary
- viewer/img/shadow02.png binary
- viewer/img/shadow03.png binary
- viewer/img/shadow04.png binary
- viewer/img/shadow10.png binary
- viewer/img/shadow14.png binary
- viewer/img/shadow20.png binary
- viewer/img/shadow24.png binary
- viewer/img/shadow30.png binary
- viewer/img/shadow34.png binary
- viewer/img/shadow40.png binary
- viewer/img/shadow41.png binary
- viewer/img/shadow42.png binary
- viewer/img/shadow43.png binary
- viewer/img/shadow44.png binary
- viewer/img/stripes.png binary
- viewer/img/uu.png binary
- viewer/js/app.js +501/−0
- viewer/js/jquery-1.2.6.js +3585/−0
- viewer/js/jquery.history.js +156/−0
- viewer/js/ui.js +134/−0
- viewer/js/utils.js +20/−0
- viewer/show.html +143/−0
- viewer/style/main.css +15/−0
- viewer/style/page.css +56/−0
- viewer/style/plugins.css +68/−0
- viewer/style/ui.ccss +226/−0
- viewer/style/viewer.css +161/−0
@@ -0,0 +1,28 @@+Copyright (c) Sebastiaan Visser 2008++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+2. Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.+
@@ -0,0 +1,6 @@+#! /usr/bin/env runhaskell++>import Distribution.Simple++>main = defaultMain+
@@ -0,0 +1,93 @@+Name: orchid+Version: 0.0.6+Description: Haskell Wiki Library+Synopsis: Haskell Wiki Library+Category: Network, Web+License: BSD3+License-file: LICENSE+Author: Sebastiaan Visser+Maintainer: sfvisser@cs.uu.nl+Build-Type: Simple+Build-Depends: base,+ bytestring,+ salvia == 0.0.4,+ xml,+ containers,+ QuickCheck,+ parsec <= 2.1.0.1,+ time,+ mtl ==1.1.0.2,+ stm,+ process,+ unix,+ nano-md5,+ hscolour,+ encoding,+ utf8-string,+ directory++GHC-Options: -fglasgow-exts -threaded+Extensions: CPP+HS-Source-Dirs: src+Other-modules: Paths_orchid,+ Misc.Commons+Exposed-modules: Text.Document.Document,+ Text.Document.Core.Type,+ Text.Document.Core.Processing,+ Text.Document.Parser.Wiki,+ Text.Document.Parser.WikiHelper,+ Text.Document.Plugin.Formula,+ Text.Document.Plugin.HsColour,+ Text.Document.Plugin.TOC,+ Text.Document.Plugin,+ Text.Document.PluginRegister,+ Text.Xhtml.Xhtml,+ Text.Xml.Xml,+ Network.Orchid.Backend.CachingBackend,+ Network.Orchid.Backend.DarcsBackend,+ Network.Orchid.Core.Backend,+ Network.Orchid.Core.Format,+ Network.Orchid.Core.Handler,+ Network.Orchid.Core.Liaison,+ Network.Orchid.Format.Haskell,+ Network.Orchid.Format.History,+ Network.Orchid.Format.Html,+ Network.Orchid.Format.Latex,+ Network.Orchid.Format.Pdf,+ Network.Orchid.Format.Plain,+ Network.Orchid.Format.Xml,+ Network.Orchid.FormatRegister,+ Network.Orchid.Wiki+Data-Files: viewer/favicon.gif+ viewer/img/shadow00.png+ viewer/img/shadow01.png+ viewer/img/shadow02.png+ viewer/img/shadow03.png+ viewer/img/shadow04.png+ viewer/img/shadow10.png+ viewer/img/shadow14.png+ viewer/img/shadow20.png+ viewer/img/shadow24.png+ viewer/img/shadow30.png+ viewer/img/shadow34.png+ viewer/img/shadow40.png+ viewer/img/shadow41.png+ viewer/img/shadow42.png+ viewer/img/shadow43.png+ viewer/img/shadow44.png+ viewer/img/stripes.png+ viewer/img/uu.png+ viewer/img/loading.gif+ viewer/js/app.js+ viewer/js/jquery-1.2.6.js+ viewer/js/jquery.history.js+ viewer/js/ui.js+ viewer/js/utils.js+ viewer/show.html+ viewer/style/main.css+ viewer/style/page.css+ viewer/style/plugins.css+ viewer/style/ui.ccss+ viewer/style/viewer.css++
@@ -0,0 +1,195 @@+{-# LANGUAGE TypeSynonymInstances #-}++module Misc.Commons where++import Control.Applicative +import Control.Concurrent+import Control.Concurrent.STM+import Control.Monad (liftM, liftM2, ap, mzero, mplus)+import Control.Monad.Identity+import Data.Char+import Data.Time.Clock+import Data.Time.LocalTime+import Test.QuickCheck+import Text.ParserCombinators.Parsec hiding (many, optional, (<|>))+import Text.ParserCombinators.Parsec.Pos (updatePosChar)+import Text.Printf (printf)+import Data.List (partition, tails, inits, isPrefixOf)+import qualified Data.Map as Map++-------[ common utilities ]----------------------------------------------------++infixl 8 .$+(.$) :: (a -> b) -> a -> b+(.$) a b = a b++dup a = (a, a)+branch f g a = (f a, g a)+swap (a, b) = (b, a)++bool a b c = if c then a else b++-- Test eithers.+left (Left _) = True+left _ = False+right (Right _) = True+right _ = False++partitionEither :: [Either a b] -> ([a], [b])+partitionEither xs =+ let (a, b) = partition left xs in+ (map (\(Left x) -> x) a,+ map (\(Right x) -> x) b)++safeRead :: Read a => String -> Maybe a+safeRead s = case reads s of+ [(x, "")] -> Just x+ _ -> Nothing++intRead :: String -> Maybe Int+intRead = safeRead++-- Conversions.++boolM = bool (Just ()) Nothing++eitherToMaybe :: Either a b -> Maybe b+eitherToMaybe = either (const Nothing) Just++listToMaybe :: [a] -> Maybe [a]+listToMaybe [] = Nothing+listToMaybe xs = Just xs++-------[ list utilities ]------------------------------------------------------++safeList :: ([a] -> b) -> [a] -> Maybe b+safeList _ [] = Nothing+safeList f xs = Just $ f xs++safeHead = safeList head+safeLast = safeList last++withReverse f = reverse . f . reverse++trimWith f = withReverse (dropWhile f) . dropWhile f++snoc a b = a ++ [b]++split :: Eq a => a -> [a] -> [[a]]+split c = splitWith (==c)++splitWith :: (a -> Bool) -> [a] -> [[a]]+splitWith f xs =+ case span (not . f) (dropWhile f xs) of+ ([], []) -> []+ (a, []) -> [a]+ (a, b) -> a : splitWith f b++splitsWith :: Eq a => [a] -> [a] -> Maybe ([a], [a])+splitsWith n h = + fmap (fmap (drop (length n)))+ . safeHead+ . filter (isPrefixOf n . snd)+ . uncurry zip+ . fmap2 inits tails+ $ dup h++-------[ map utilities ]-------------------------------------------------------++(<->) a b c = Map.insert a b c++(<--) a b = Map.insert a b Map.empty++-------[ text manipulation ]---------------------------------------------------++normalCase (x:xs) = toUpper x : map toLower xs+upperCase = map toUpper+lowerCase = map toLower++-- Trim all heading and trailing whitespace.+trim = trimWith (`elem` " \t\n\r")++-- ShowS functions.++ss = showString+intersperseS c [] = id+intersperseS c [s] = s+intersperseS c xs = foldl1 (\a -> ((a.c).)) xs+concatS = foldl (.) id+concatMapS f = concatS . map f+unlinesS = concatMapS (. ss "\n")+eolS = ss "\n"+++-------[ second arity functor ]------------------------------------------------++class Functor2 f where+ fmap2 :: (a -> c) -> (b -> d) -> f a b -> f c d++instance Functor2 (,) where+ fmap2 f g (a, b) = (f a, g b)++instance Functor2 Either where+ fmap2 f _ (Left a) = Left (f a)+ fmap2 _ g (Right b) = Right (g b)++-------[ monadic expressions ]-------------------------------------------------++ifM :: Monad m => m Bool -> (a -> a) -> a -> m a+ifM t f g = t >>= (\b -> return $ if b then f g else g)++-- Thread a value through monadic expression.+constM c = (>> return c)++-------[ parsec extensions ]---------------------------------------------------++-- Helper function to quickly apply a parser.+(@@) p b = either (const Nothing) Just $ parse (p <* eof) "" b+(@!) p b = parse (p <* eof) "" b++-- Apply a parser for a minimum of `n' times.+pMin n p = (++) <$> count n p <*> many p++-- Apply a parser for a maximum of `n' times.+pMax n p | n <= 0 = return []+ | otherwise = option [] $ liftM2 (:) p (pMax (n-1) p)++-- Apply a parser for a minimum of `n' and a maximum of 'm' times.+pRange n m p = liftM2 (++) (count n p) (pMax (m-n) p)++-- Option parser with maybe result.+pMaybe :: GenParser tok st a -> GenParser tok st (Maybe a)+pMaybe = option Nothing . liftM Just++-------[ testing ]-------------------------------------------------------------++-- We will abuse QuickCheck for unit testing purposes.+unitCheck :: (Testable a) => a -> IO ()+unitCheck = quickCheck++testAll xs = mapM_ (\(s,a) -> printf "%-50s: " s >> a) xs++-------[ time utils ]----------------------------------------------------------++later howlong = do+ zone <- getCurrentTimeZone+ time <- liftM (addUTCTime $ fromInteger howlong) getCurrentTime+ return $ utcToLocalTime zone time++now = later 0++-------[ concurrency utils ]---------------------------------------------------++atomModTVar :: (a -> a) -> TVar a -> IO a+atomModTVar f v = atomically $ do+ t <- readTVar v+ writeTVar v (f t)+ return (f t)++atomReadTVar :: TVar a -> IO a+atomReadTVar = atomically . readTVar++atomWithTVar :: (a -> b) -> TVar a -> IO b+atomWithTVar f v = atomically+ $ liftM f (readTVar v)+
@@ -0,0 +1,40 @@+module Network.Orchid.Backend.CachingBackend (cachingBackend) where++#if (__GLASGOW_HASKELL__ < 609)+import Control.Exception hiding (IOException)+#else+import Control.Exception+#endif++import System.Posix.Files+import System.Directory+import qualified System.IO.UTF8 as U++import Network.Orchid.Core.Backend++#if (__GLASGOW_HASKELL__ < 609)+type IOException = Exception+#endif++cachingBackend :: FilePath -> Backend -> Backend+cachingBackend cache backend = Backend {+ store = store backend+ , delete = delete backend+ , retrieve = cachedRetrieve cache backend+ , history = history backend+ }++-------- backend procedures ---------------------------------------------------++cachedRetrieve :: FilePath -> Backend -> FilePath -> Revision -> IO (Maybe String)+cachedRetrieve cache backend file rev = do+ hit <- (try $ U.readFile $ concat [cache, file, "?", name rev]) :: IO (Either IOException String)+ case hit of+ -- Cache hit, use this one.+ Right doc -> return $ Just doc+ -- No cache hit, forward to backend and store in cache dir.+ Left e -> do+ doc <- retrieve backend file rev+-- maybe (return ()) (U.writeFile $ concat [cache, file, "?", name rev]) doc+ return doc+
@@ -0,0 +1,165 @@+module Network.Orchid.Backend.DarcsBackend (darcsBackend) where++import Control.Applicative hiding (empty)+import Text.ParserCombinators.Parsec hiding (many, optional, (<|>), try)+import System.Directory (removeFile)+import System.Process (runInteractiveProcess, waitForProcess, runProcess)+import System.Exit+import qualified System.IO.UTF8 as U++#if (__GLASGOW_HASKELL__ < 609)+import Control.Exception hiding (IOException)+#else+import Control.Exception+#endif++import Misc.Commons (splitsWith, eitherToMaybe, trim)+import Network.Protocol.Uri ((/+), normalize)+import Network.Orchid.Core.Backend++#if (__GLASGOW_HASKELL__ < 609)+type IOException = Exception+#endif++type DarcsRepository = FilePath++{-+Create a Darcs wiki backend bound to the specified repository location. The+temp directory specfied will be used to store intermediate results from+patching old revisions. This directory can easily be shared with the cache+directory for the `CachingBackend' module.+-}++darcsBackend :: FilePath -> FilePath -> Backend+darcsBackend repo temp = Backend {+ store = darcsStore repo+ , delete = darcsDelete repo+ , retrieve = darcsRetrieve repo temp+ , history = darcsHistory repo+ }++-------- store a documents in a new darcs patch -------------------------------++darcsStore :: DarcsRepository -> FilePath -> Revision -> String -> IO ()+darcsStore repo file cha@(Revision _ author name) doc = do++ -- Write the new document to the source file.+ U.writeFile (repo /+ file) doc++ -- Add file to repository.+ runProcess "darcs" ["add", "--case-ok", file]+ (Just repo) Nothing Nothing Nothing Nothing+ >>= waitForProcess++ -- Record the changes for this file.+ runProcess "darcs" [+ "record", file+ , "--all"+ , "--patch-name=" ++ name+ , "--author=" ++ author+ ] (Just repo) Nothing Nothing Nothing Nothing+ >>= waitForProcess++ return ()++-------- delete a document from the darcs repo --------------------------------++darcsDelete :: DarcsRepository -> FilePath -> Revision -> IO ()+darcsDelete repo file cha@(Revision _ author name) = do++ -- Write the new document to the source file.+ removeFile (repo /+ file)++ -- Record the changes for this file.+ runProcess "darcs" [+ "record", file+ , "--all"+ , "--patch-name=" ++ name+ , "--author=" ++ author+ ] (Just repo) Nothing Nothing Nothing Nothing+ >>= waitForProcess++ -- TODO: cache removal.++ return ()++-------------------------------------------------------------------------------++darcsRetrieve :: DarcsRepository -> FilePath -> FilePath -> Revision -> IO (Maybe String)+darcsRetrieve repo temp file rev =+ case name rev of+ "" -> eitherToMaybe <$> (try (U.readFile (repo /+ file)) :: IO (Either IOException String))+ n -> retrieveDiff file repo temp n++retrieveDiff :: FilePath -> FilePath -> FilePath -> String -> IO (Maybe String)+retrieveDiff file repo temp name = do++ -- Load the diff from darcs.+ (inp, out, err, pid) <-+ runInteractiveProcess "darcs" [+ "diff", file+ , "--unified"+ , "--store-in-memory"+ , "--to-patch=^" ++ (escapePatch name) ++ "$"+ ]+ (Just repo) Nothing ++ -- Pipe the diff from darcs straight to patch.+ let prev = temp ++ file ++ "?" ++ name+ pid' <- runProcess "patch" [+ "--unified"+ , "--output=" ++ prev+ ]+ (Just repo) Nothing+ (Just out) Nothing Nothing++ -- Wait for both processes in pipe to terminate.+ exit' <- waitForProcess pid'+ exit <- waitForProcess pid++ -- Return just the document or nothing on failure.+ case exit of+ ExitSuccess -> Just <$> U.readFile (repo /+ prev)+ -- TODO: just to damn ugly.+ ExitFailure _ -> removeFile (repo /+ prev) >> return Nothing++-- Escape special characters in text that will end up in an XML document.+escapePatch :: String -> String+escapePatch [] = []+escapePatch ('(':xs) = "\\(" ++ escapePatch xs+escapePatch (')':xs) = "\\)" ++ escapePatch xs+escapePatch ('+':xs) = "\\+" ++ escapePatch xs+escapePatch ('.':xs) = "\\." ++ escapePatch xs+escapePatch (x:xs) = x : escapePatch xs++-------- request and parse modification history -------------------------------++darcsHistory :: DarcsRepository -> FilePath -> IO (Maybe History)+darcsHistory repo file = do+ (inp, out, err, pid) <-+ runInteractiveProcess "darcs" ["changes", file] (Just repo) Nothing+ s <- pHistory <$> U.hGetContents out+ waitForProcess pid+ return s++pHistory :: String -> Maybe History+pHistory h = splitsWith "\n\n" h >>= pRevisions . snd++pRevisions :: String -> Maybe History+pRevisions his = do+ case splitsWith "\n\n" his of+ Nothing -> fmap pure $ pRevision his+ Just (c, cs) -> do+ c' <- pRevision c+ cs' <- pRevisions cs+ return (c' : cs')++pRevision :: String -> Maybe Revision+pRevision revision = do+ let tmplt = length "Sun Aug 10 19:20:52 CEST 2008"+ (inf, body) <- splitsWith "\n" revision+ let date = take tmplt inf+ author = trim (drop tmplt inf)+ name = dropWhile (flip elem " *") $ head $ lines body+ return $ Revision date author name+
@@ -0,0 +1,31 @@+module Network.Orchid.Core.Backend where++import Data.List (intercalate)++type Author = String+type Date = String++data Revision =+ Revision {+ date :: Date+ , author :: Author+ , name :: String+ }++instance Show Revision where+ show (Revision d a n) = intercalate "\n" [sd, sa, sn]+ where+ sd = if null d then "<no date>" else d+ sa = if null a then "<no author>" else a+ sn = if null n then "<no revision name>" else n++type History = [Revision]++data Backend =+ Backend {+ store :: FilePath -> Revision -> String -> IO ()+ , retrieve :: FilePath -> Revision -> IO (Maybe String)+ , delete :: FilePath -> Revision -> IO ()+ , history :: FilePath -> IO (Maybe History)+ }+
@@ -0,0 +1,20 @@+module Network.Orchid.Core.Format where++import Data.ByteString.Lazy (ByteString)++import Network.Protocol.Uri (URI)+import Network.Orchid.Core.Backend++-- Formats produce proper UTF-8 text or binary docs. (TODO: ascii for tex?)+data Output =+ TextOutput String+ | BinaryOutput ByteString++-- Wiki format description data type.+data WikiFormat =+ WikiFormat {+ extension :: String+ , mime :: String+ , handler :: Backend -> FilePath -> URI -> String -> IO Output+ }+
@@ -0,0 +1,107 @@+module Network.Orchid.Core.Handler (+ hRepository+ , hViewer+ , hWiki+ , hWikiCustomViewer+ ) where++import Control.Monad.State (lift, gets)+import Control.Concurrent.STM++import Network.Salvia.Advanced.ExtendedFileSystem (hExtendedFileSystem)+import Network.Salvia.Handlers.Directory (hDirectory)+import Network.Salvia.Handlers.Error (hError)+import Network.Salvia.Handlers.File (hFileResource)+import Network.Salvia.Handlers.File (hUri)+import Network.Salvia.Handlers.FileSystem (hFileSystem, hFileTypeDispatcher)+import Network.Salvia.Handlers.Login+import Network.Salvia.Handlers.Login (UserDatabase, TUserSession)+import Network.Salvia.Handlers.MethodRouter (hPOST, hMethodRouter)+import Network.Salvia.Handlers.PathRouter (hPrefix, hPath, hPathRouter)+import Network.Salvia.Handlers.Rewrite (hWithoutDir)+import Network.Salvia.Httpd (Handler, request)+import Network.Protocol.Http (Method (..), Status (..))+import Network.Protocol.Uri ((/+), URI(..))+import Misc.Commons ((.$))+import Network.Orchid.Backend.CachingBackend (cachingBackend)+import Network.Orchid.Backend.DarcsBackend (darcsBackend)+import Network.Orchid.Core.Backend (Backend)+import Network.Orchid.Core.Format (extension)+import Network.Orchid.Core.Liaison (hWikiStore, hWikiDelete, hWikiRetrieve)+import Network.Orchid.FormatRegister (wikiFormats)++import Paths_orchid++-------- main entry point -----------------------------------------------------++backend :: FilePath -> Backend+backend dataDir =+ cachingBackend (dataDir /+ "_cache/")+ $ darcsBackend dataDir "_cache/"++hRepository :: Show a => FilePath -> FilePath -> UserDatabase b -> TUserSession a -> Handler ()+hRepository dataDir workDir userdb session =+ hPrefix "/_" + .$ hFileSystem (dataDir /+ "_")+ $ hFileTypeDispatcher dataDir+ hDirectory+ $ hWithoutDir dataDir+ $ hWikiREST workDir userdb session+ $ backend dataDir++hViewer :: FilePath -> Handler ()+hViewer dir = do+ hPath "/"+ .$ hFileResource (dir /+ "show.html")+ $ hExtendedFileSystem dir++hWiki :: Show a => FilePath -> FilePath -> TUserDatabase FilePath -> TUserSession a -> Handler ()+hWiki dataDir workDir userdb session = do+ viewerDir <- lift $ getDataFileName "viewer"+ hWikiCustomViewer viewerDir dataDir workDir userdb session++hWikiCustomViewer :: Show a+ => FilePath -> FilePath -> FilePath+ -> TUserDatabase FilePath -> TUserSession a -> Handler ()+hWikiCustomViewer viewerDir dataDir workDir tuserdb session = do+ userdb <- lift . atomically $ readTVar tuserdb+ hPrefix "/data"+ .$ hRepository dataDir workDir userdb session+ $ authHandlers tuserdb session+ $ hViewer viewerDir++authHandlers :: Show a => TUserDatabase FilePath -> TUserSession a -> Handler () -> Handler ()+authHandlers tuserdb session handler = do+ userdb <- lift . atomically $ readTVar tuserdb+ hPathRouter [+ ("/loginfo", hAuthorized userdb "loginfo" (const $ hLoginfo session) session)+ , ("/login", hPOST $ hLogin userdb session)+ , ("/logout", hPOST $ hLogout session)+ , ("/signup", hAuthorized userdb "signup" (const $ hPOST $ hSignup tuserdb ["loginfo", "show", "edit", "create"]) session)+ ] handler++-------- REST interface -------------------------------------------------------++-- The wiki module will act as a REST interface by using the MethodRouter+-- handler to dispatch on the HTTP request method.++hWikiREST :: Show a => FilePath -> UserDatabase b -> TUserSession a -> Backend -> Handler ()+hWikiREST workDir userdb session backend =+ hUri $ \uri ->+ previewHandlers backend workDir uri+ $ actionHandlers backend workDir uri userdb session+ $ hError BadRequest++actionHandlers :: Show a => Backend -> FilePath -> URI -> UserDatabase b -> TUserSession a -> Handler () -> Handler ()+actionHandlers backend workDir uri userdb session =+ hMethodRouter [+ (GET, hAuthorized userdb "show" (const $ hWikiRetrieve backend workDir False uri) session)+ , (PUT, hAuthorized userdb "edit" (flip (hWikiStore backend) uri) session)+ , (DELETE, hAuthorized userdb "delete" (flip (hWikiDelete backend) uri) session)+ ]++previewHandlers :: Backend -> FilePath -> URI -> Handler () -> Handler ()+previewHandlers backend workDir uri = hPathRouter (+ map (\ext -> ("/preview." ++ ext, hWikiRetrieve backend workDir True uri))+ $ map extension wikiFormats) +
@@ -0,0 +1,108 @@+module Network.Orchid.Core.Liaison (+ hWikiRetrieve+ , hWikiDelete+ , hWikiStore+ ) where++import Control.Applicative ((<$>))+import Control.Monad.State (gets, lift)+import Data.Encoding (encodeLazy)+import Data.Encoding.UTF8 (UTF8 (..))+import Data.List (find)+import qualified Data.ByteString.Lazy as B++import Network.Salvia.Handlers.Error (safeIO, hError, hCustomError)+import Network.Salvia.Handlers.File ()+import Network.Salvia.Handlers.Login (username, User)+import Network.Salvia.Handlers.MethodRouter ()+import Network.Salvia.Handlers.PathRouter ()+import Network.Salvia.Httpd (UriHandler, sendBs, request, modResponse, contentsUtf8)+import Network.Protocol.Http+import Network.Orchid.Core.Backend (Backend (..), Revision (..))+import Network.Orchid.Core.Format (WikiFormat (..), Output (..))+import Network.Orchid.FormatRegister+import qualified Network.Protocol.Uri as U++-- TODO: should history be here instead of format dir?++-------- showing wiki documents -----------------------------------------------++{- |+Dependent on the `b' flag we either bounce the PUTted contents back in the+requested format, or we open the source version of the requested resource and+print this back in the requested format.+-}++hWikiRetrieve :: Backend -> FilePath -> Bool -> UriHandler ()+hWikiRetrieve backend workDir b u = do++ -- Fetch revision identifier from URI query string.+ rev <- Revision "" "" . U.query . uri <$> gets request++ -- Compute the source file and format handler.+ let src = U.relative $ U.setExtension Nothing u+ ext = maybe "txt" id $ U.extension u+ fmt = maybe defaultFormat id $ find ((ext==) . extension) wikiFormats++ -- The body might be retrieved from our backend or from the request itself.+ body <- if b+ then contentsUtf8+ else lift (retrieve backend (U.path src) rev)++ -- Format the body using the selected wiki handler or return an error when+ -- the body could not be retrieved.+ case body of+ Nothing -> hError NotFound+ Just s -> do+ b <- lift $ (handler fmt) backend workDir src s+ (body, enc) <- return $ case b of+ TextOutput s -> (encodeLazy UTF8 s, Just utf8)+ BinaryOutput bs -> (bs, Nothing)++ modResponse+ $ setStatus OK+ . setContentType (mime fmt) enc+ . setContentLength (B.length body)+ sendBs body++-------- deleting wiki documents ----------------------------------------------++-- TODO:generalize deletion/storage++hWikiDelete :: Backend -> Maybe User -> UriHandler ()+hWikiDelete backend user u = do++ -- Fetch revision identifier from URI query string.+ revname <- gets (U.query . uri . request)+ let rev = Revision "" (maybe "guest" username user) revname+ let src = U.setExtension Nothing u++ safeIO+ (delete backend (U.path $ U.relative src) rev)+ (const $ return ())++-------- storing wiki documents -----------------------------------------------++hWikiStore :: Backend -> Maybe User -> UriHandler ()+hWikiStore backend user u = do++ -- Fetch revision identifier from URI query string.+ revname <- gets (U.query . uri . request)+ let rev = Revision "" (maybe "guest" username user) revname++ let src = U.setExtension Nothing u++ -- Check history to prevent duplicate revision name.+ p <- maybe [] (filter (\(Revision d a n) -> n == revname))+ <$> lift (history backend (U.path $ U.relative src))++ case p of+ x:xs -> hCustomError BadRequest "existing revision name"+ [] -> do+ c <- contentsUtf8+ case c of+ Nothing -> modResponse $ setStatus BadRequest+ Just c' -> safeIO+ (store backend (U.path $ U.relative src) rev c')+ (const $ return ())+
@@ -0,0 +1,16 @@+module Network.Orchid.Format.Haskell (fHaskell) where++import Text.Document.Document+import Network.Orchid.Core.Backend+import Network.Orchid.Core.Format+import Network.Protocol.Uri++fHaskell = WikiFormat "hs" "text/plain" haskell++haskell :: Backend -> FilePath -> URI -> String -> IO Output+haskell backend _ _ src = return + $ TextOutput+ $ either show show+ $ fromWiki src++
@@ -0,0 +1,19 @@+module Network.Orchid.Format.History (fHistory) where++import Control.Monad (liftM)+import Data.List (intercalate)++import Text.Document.Document+import Network.Orchid.Core.Backend+import Network.Orchid.Core.Format+import qualified Network.Protocol.Uri as U++fHistory = WikiFormat "his" "text/plain" history'++history' :: Backend -> FilePath -> U.URI -> String -> IO Output+history' backend _ f _ = do+ liftM+ (TextOutput . maybe "no history" (intercalate "\n\n" . map show))+ (history backend $ U.path $ U.relative f)++
@@ -0,0 +1,17 @@+module Network.Orchid.Format.Html (fHtml) where++import Control.Monad (liftM)++import Text.Document.Document+import Network.Orchid.Core.Backend+import Network.Orchid.Core.Format+import Network.Protocol.Uri++fHtml = WikiFormat "html" "text/html" html++html :: Backend -> FilePath -> URI -> String -> IO Output+html _ work _ src = do+ case fromWiki src of+ Left err -> return $ TextOutput (show err)+ Right doc -> liftM (TextOutput . show) (processToXHTML work doc)+
@@ -0,0 +1,15 @@+module Network.Orchid.Format.Latex (fLatex) where++import Text.Document.Document+import Network.Orchid.Core.Backend+import Network.Orchid.Core.Format+import Network.Protocol.Uri++fLatex = WikiFormat "tex" "text/plain" latex++latex :: Backend -> FilePath -> URI -> String -> IO Output+latex _ _ _ src = return + $ TextOutput+ $ either show toLaTeX+ $ fromWiki src+
@@ -0,0 +1,29 @@+module Network.Orchid.Format.Pdf (fPdf) where++import Control.Monad (liftM)+import Data.ByteString.Lazy hiding (writeFile)+import Prelude hiding (readFile)+import System.Process (waitForProcess, runProcess)++import Text.Document.Document+import Network.Protocol.Uri+import Network.Orchid.Core.Backend+import Network.Orchid.Core.Format++fPdf = WikiFormat "pdf" "application/pdf" pdf++-- TODO: write to _cache dir, not /tmp+pdf :: Backend -> FilePath -> URI -> String -> IO Output+pdf _ _ _ src = do+ writeFile "/tmp/tex-to-pdf.tex"+ $ either show toLaTeX+ $ fromWiki src+ runProcess "pdflatex" ["-interaction=batchmode", "/tmp/tex-to-pdf.tex"]+ (Just "/tmp") Nothing Nothing Nothing Nothing+ >>= waitForProcess+ liftM BinaryOutput $ readFile "/tmp/tex-to-pdf.pdf"++{- runProcess "latexmk" [+ "-pdf", "-silent", "-f", "-g"+ ] (Just "/tmp") Nothing Nothing Nothing Nothing+ >>= waitForProcess-}
@@ -0,0 +1,12 @@+module Network.Orchid.Format.Plain (fPlain) where++import Text.Document.Document+import Network.Orchid.Core.Backend+import Network.Orchid.Core.Format+import Network.Protocol.Uri++fPlain = WikiFormat "txt" "text/plain" plain++plain :: Backend -> FilePath -> URI -> String -> IO Output+plain _ _ _ = return . TextOutput+
@@ -0,0 +1,17 @@+module Network.Orchid.Format.Xml (fXml) where++import Text.XML.Light.Output++import Text.Document.Document+import Network.Orchid.Core.Backend+import Network.Orchid.Core.Format+import Network.Protocol.Uri++fXml = WikiFormat "xml" "text/xml" xml++xml :: Backend -> FilePath -> URI -> String -> IO Output+xml _ _ _ src = return+ $ TextOutput+ $ either show (ppContent . toXML)+ $ fromWiki src+
@@ -0,0 +1,28 @@+module Network.Orchid.FormatRegister (+ wikiFormats+ , defaultFormat+ ) where++import Network.Orchid.Core.Format (WikiFormat)+import Network.Orchid.Format.Html (fHtml)+import Network.Orchid.Format.Xml (fXml)+import Network.Orchid.Format.Haskell (fHaskell)+import Network.Orchid.Format.History (fHistory)+import Network.Orchid.Format.Latex (fLatex)+import Network.Orchid.Format.Pdf (fPdf)+import Network.Orchid.Format.Plain (fPlain)++wikiFormats :: [WikiFormat]+wikiFormats = [+ fPdf+ , fXml+ , fHtml+ , fPlain+ , fLatex+ , fHaskell+ , fHistory+ ] ++defaultFormat :: WikiFormat+defaultFormat = fPlain+
@@ -0,0 +1,8 @@+module Network.Orchid.Wiki (+ hRepository+ , hViewer+ , hWiki+ ) where++import Network.Orchid.Core.Handler+
@@ -0,0 +1,37 @@+module Text.Document.Core.Processing where++import Text.XML.Light (Content)++import Text.Document.Core.Type+import Text.Document.Plugin+import Text.Document.PluginRegister+import Text.Xml.Xml++-- Todo: it feels logical to put the result of side-effects back into the+-- printers. But we do not want to be too ambitious.++processDocument :: Format -> (Syn_Document -> a) -> FilePath -> Document -> IO a+processDocument fmt printer work doc = do++ -- Compute the desired semantics from the document.+ let sem = wrappedSemDocument doc+ io f = f work doc sem+ nop = return ()+ procs = processors_Syn_Document sem++ -- Perform the side-effects that plug-ins may require.+ mapM_ (maybe nop io . flip processor fmt) procs++ -- Contruct the pure result from the document semantics.+ return (printer sem)++-- Wrong place?+processToXHTML :: FilePath -> Document -> IO Node+processToXHTML = processDocument XHTML xhtml_Syn_Document++processToLaTeX :: FilePath -> Document -> IO ShowS+processToLaTeX = processDocument LaTeX latex_Syn_Document++processToXML :: FilePath -> Document -> IO Content+processToXML = processDocument XML xml_Syn_Document+
@@ -0,0 +1,1941 @@+++-- UUAGC 0.9.7 (src/Text/Document/Core/Type.ag)+module Text.Document.Core.Type where++import Prelude hiding (span, div)+import Data.List (intercalate)+import qualified Text.XML.Light as XL++import Text.Document.Plugin+import Text.Xhtml.Xhtml+import Text.Xml.Xml+import Misc.Commons (fmap2, intersperseS, concatMapS, unlinesS, concatS, eolS, ss)+import qualified Text.Xhtml.Xhtml as H++data LinkType = Internal | External | Reference+ deriving (Eq, Show)+++++document = Document_Document +section = Structure_Section +blocks = Block_Blocks +paragraph = Block_Paragraph +enum = Block_Enum+list = Block_List+mapping = Block_Mapping+verbatim = Block_Verbatim+comment = Block_Comment+anchor_ = Block_Anchor+caption = Block_Caption+plugin = Block_Plugin++lines = Inline_Lines +image = Inline_Image +text = Inline_Text +emph = Inline_Emph +strong = Inline_Strong +fixed = Inline_Fixed+link = Inline_Link +footnote = Inline_Footnote +quote = Inline_Quote ++(Inline_Text a) <++> (Inline_Text b) = Inline_Text (a ++ b)++-- Wrapper functions for semantic domains.+wrappedSemDocument doc = flip (wrap_Document . sem_Document) (Inh_Document doc) doc+++++toXHTML :: Document -> Node+toXHTML = xhtml_Syn_Document . wrappedSemDocument++xhtmlDocument t s anns ab b =+ body $ nodeset (+ classDiv "header" (nodeset ([+ h1 t+ , withClass "sub" h1 s+-- , classDiv "author" (nodeset [maybe empty id (lookup "author" anns)])+-- , classDiv "enmail" (nodeset [maybe empty id (lookup "email" anns)])+ ] ++ map (\(a, b) -> classDiv ("annotation " ++ a) (nodeset [b])) anns)+ ) : xhtmlAbstract ab : b)++-- Create the HTML block containing the document abstract.+xhtmlAbstract ab+ | ab == empty = empty+ | otherwise =+ classDiv "abstract"+ $ nodeset [h2 $ H.text "Abstract", ab]++xhtmlSection _ _ False _ b = div $ nodeset b+xhtmlSection lvl s True t b = div $ nodeset (hdr : b)+ where+ title = nodeset [span $ H.text number, t]+ hdr = header (lvl+2) title+ number = (intercalate "." $ map show $ reverse s) ++ " "++xhtmlCleanList xs = if null items then [] else [ul $ items]+ where items = filter significant xs++xhtmlLink kind = withClass (show kind)++linkAnchor Reference ref = anchor ('#':ref)+linkAnchor Internal ref = anchor (ref ++ ".html")+linkAnchor _ ref = anchor ref++xhtmlFromOutput (OutputPlain s) = H.text s+xhtmlFromOutput (OutputXML n) = n++xhtmlPlugin pp doc = maybe err (\a -> xhtmlFromOutput $ a doc) $ printer pp XHTML+ where+ err = classSpan "format-error"+ $ H.text ("No XHTML pretty printer for plugin: " ++ printerName pp)++++toXML :: Document -> XL.Content+toXML = xml_Syn_Document . wrappedSemDocument++-- todo: type signatures++xmlElem name childs =+ XL.Elem $ XL.Element (XL.QName name Nothing Nothing) [] childs Nothing++xmlText text = XL.Text (XL.CData XL.CDataText text Nothing)++xmlFromOutput (OutputXMLLight s) = s++xmlPlugin pp doc = maybe err (\a -> xmlFromOutput $ a doc) $ printer pp XML+ where+ err = xmlText ("No XML pretty printer for plugin: " ++ printerName pp)++-- Very `rough' function to strip the outer element off.+xmlStrip :: XL.Content -> XL.Content+xmlStrip (XL.Elem (XL.Element _ _ (c:_) _)) = c+++++toLaTeX :: Document -> String+toLaTeX = ($"") . latex_Syn_Document . wrappedSemDocument++-- Escape special characters in text that will end up in an LaTeX document.+escapeTex :: String -> String+escapeTex [] = []+escapeTex ('\\':xs) = "\\\\" ++ escapeTex xs+escapeTex (x:xs) = x : escapeTex xs++-- Shortcut functions for common tex constructs.++ifEmpty s t e = if not (null (s "")) then t else e+ifEmptyId s t = ifEmpty s t id++texBlock n c = ss "\\begin{" . ss n . ss "}\n" . c . ss "\\end{" . ss n . ss "}\n"+texLine n c = ss "\\" . ss n . ss "{\n" . c . ss "}\n"+texSingle n = ss "\\" . ss n . ss "\n"+texStart n = ss "\\" . ss n . ss "\n"+texStartP n b p = ss "\\" . ss n . ifEmptyId b (ss "[" . b . ss "]") . ss "{" . p . ss "}\n"+texSurround n p = ss "\\" . ss n . ss "{" . p . ss "}"++-- Shortcut functions specifc latex constructs.++texDocument t s a b =+ texArticle+ . texTitle (t . ss "\\\\" . s)+ . texBlock "document"+ (texMaketitle . texAbstract a . b)++texArticle = texStartP "documentclass" id (ss "article")+ . texStartP "usepackage" id (ss "amssymb,amsmath,bm,color")+ . texStartP "usepackage" (ss "utf8") (ss "inputenc")+ . texStartP "usepackage" id (ss "hyperref")+texTitle = texStartP "title" id+texMaketitle = texSingle "maketitle"+texAbstract = texBlock "abstract"+texVerbatim = texBlock "verbatim"+texSection n = texStartP (concat (replicate n "sub") ++ "section") id+texItemize = texBlock "itemize"+texEnumerate = texBlock "enumerate"+texItem = texStart "item"+texEmph = texSurround "emph"+texStrong = texSurround "textbf"+texFixed = texSurround "texttt"+texLink a b = texSurround "url" (ss a) +texFootnote = texSurround "footnote"+texMapping (x, y) = texSurround "item" x . eolS . y . eolS++-- Plugin handler.++texPluginErr n = ss ("ERROR: unable to pretty print plugin: " ++ n) . eolS . eolS++texFromOutput _ (OutputPlain s) = ss s+texFromOutput n _ = (texPluginErr n)++texPlugin pp doc =+ let n = printerName pp in+ maybe (texPluginErr n) (\a -> texFromOutput n $ a doc) (printer pp LaTeX)++makeTexSection ist title level body =+ (if ist then texSection (level - 1) title else id)+ . intersperseS (eolS . eolS) body++++documentToXhtmlTOC :: Document -> NodeSet+documentToXhtmlTOC = xhtmlTOC_Syn_Document . wrappedSemDocument+-- Annotation --------------------------------------------------+{-+ visit 0:+ synthesized attributes:+ xhtml : (String, Node)+ xml : XL.Content+ alternatives:+ alternative Tuple:+ child x1 : {String}+ child x2 : Inline +-}+type Annotation = ( (String),(Inline))+-- cata+sem_Annotation :: Annotation ->+ T_Annotation +sem_Annotation ( x1,x2) =+ (sem_Annotation_Tuple x1 (sem_Inline x2 ) )+-- semantic domain+type T_Annotation = ( ((String, Node)),(XL.Content))+data Inh_Annotation = Inh_Annotation {}+data Syn_Annotation = Syn_Annotation {xhtml_Syn_Annotation :: (String, Node),xml_Syn_Annotation :: XL.Content}+wrap_Annotation :: T_Annotation ->+ Inh_Annotation ->+ Syn_Annotation +wrap_Annotation sem (Inh_Annotation ) =+ (let ( _lhsOxhtml,_lhsOxml) =+ (sem )+ in (Syn_Annotation _lhsOxhtml _lhsOxml ))+sem_Annotation_Tuple :: String ->+ T_Inline ->+ T_Annotation +sem_Annotation_Tuple x1_ x2_ =+ (let _lhsOxhtml :: ((String, Node))+ _lhsOxml :: (XL.Content)+ _x2Ilatex :: ShowS+ _x2Ixhtml :: Node+ _x2Ixml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 76, column 16)+ _lhsOxhtml =+ (x1_, _x2Ixhtml)+ -- "src/Text/Document/Printer/Xml.ag"(line 57, column 16)+ _lhsOxml =+ xmlElem "annotation" [+ xmlElem "key" [xmlText x1_]+ , xmlElem "value" [_x2Ixml]+ ]+ ( _x2Ilatex,_x2Ixhtml,_x2Ixml) =+ (x2_ )+ in ( _lhsOxhtml,_lhsOxml))+-- Annotations -------------------------------------------------+{-+ visit 0:+ synthesized attributes:+ xhtml : [(String, Node)]+ xml : [XL.Content]+ alternatives:+ alternative Cons:+ child hd : Annotation + child tl : Annotations + alternative Nil:+-}+type Annotations = [(Annotation)]+-- cata+sem_Annotations :: Annotations ->+ T_Annotations +sem_Annotations list =+ (Prelude.foldr sem_Annotations_Cons sem_Annotations_Nil (Prelude.map sem_Annotation list) )+-- semantic domain+type T_Annotations = ( ([(String, Node)]),([XL.Content]))+data Inh_Annotations = Inh_Annotations {}+data Syn_Annotations = Syn_Annotations {xhtml_Syn_Annotations :: [(String, Node)],xml_Syn_Annotations :: [XL.Content]}+wrap_Annotations :: T_Annotations ->+ Inh_Annotations ->+ Syn_Annotations +wrap_Annotations sem (Inh_Annotations ) =+ (let ( _lhsOxhtml,_lhsOxml) =+ (sem )+ in (Syn_Annotations _lhsOxhtml _lhsOxml ))+sem_Annotations_Cons :: T_Annotation ->+ T_Annotations ->+ T_Annotations +sem_Annotations_Cons hd_ tl_ =+ (let _lhsOxhtml :: ([(String, Node)])+ _lhsOxml :: ([XL.Content])+ _hdIxhtml :: ((String, Node))+ _hdIxml :: (XL.Content)+ _tlIxhtml :: ([(String, Node)])+ _tlIxml :: ([XL.Content])+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 59, column 39)+ _lhsOxhtml =+ _hdIxhtml : _tlIxhtml+ -- use rule "src/Text/Document/Printer/Xml.ag"(line 45, column 13)+ _lhsOxml =+ _hdIxml : _tlIxml+ ( _hdIxhtml,_hdIxml) =+ (hd_ )+ ( _tlIxhtml,_tlIxml) =+ (tl_ )+ in ( _lhsOxhtml,_lhsOxml))+sem_Annotations_Nil :: T_Annotations +sem_Annotations_Nil =+ (let _lhsOxhtml :: ([(String, Node)])+ _lhsOxml :: ([XL.Content])+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 59, column 39)+ _lhsOxhtml =+ []+ -- use rule "src/Text/Document/Printer/Xml.ag"(line 45, column 13)+ _lhsOxml =+ []+ in ( _lhsOxhtml,_lhsOxml))+-- Block -------------------------------------------------------+{-+ visit 0:+ inherited attribute:+ sem : Document + synthesized attributes:+ latex : ShowS+ processors : [Processor Document Syn_Document]+ xhtml : Node+ xml : XL.Content+ alternatives:+ alternative Anchor:+ child name : {String}+ child contents : Block + alternative Blocks:+ child blocks : Blocks + alternative Caption:+ child caption : Inline + child contents : Block + alternative Comment:+ child comment : {String}+ alternative Enum:+ child items : Blocks + alternative List:+ child items : Blocks + alternative Mapping:+ child pairs : Pairs + alternative Paragraph:+ child paragraph : Inline + alternative Plugin:+ child plugin : {( PrettyPrinter Document+ , Processor Document Syn_Document)}+ alternative Verbatim:+ child verbatim : Block +-}+data Block = Block_Anchor (String) (Block) + | Block_Blocks (Blocks) + | Block_Caption (Inline) (Block) + | Block_Comment (String) + | Block_Enum (Blocks) + | Block_List (Blocks) + | Block_Mapping (Pairs) + | Block_Paragraph (Inline) + | Block_Plugin (( PrettyPrinter Document+ , Processor Document Syn_Document)) + | Block_Verbatim (Block) + deriving ( Eq,Show)+-- cata+sem_Block :: Block ->+ T_Block +sem_Block (Block_Anchor _name _contents ) =+ (sem_Block_Anchor _name (sem_Block _contents ) )+sem_Block (Block_Blocks _blocks ) =+ (sem_Block_Blocks (sem_Blocks _blocks ) )+sem_Block (Block_Caption _caption _contents ) =+ (sem_Block_Caption (sem_Inline _caption ) (sem_Block _contents ) )+sem_Block (Block_Comment _comment ) =+ (sem_Block_Comment _comment )+sem_Block (Block_Enum _items ) =+ (sem_Block_Enum (sem_Blocks _items ) )+sem_Block (Block_List _items ) =+ (sem_Block_List (sem_Blocks _items ) )+sem_Block (Block_Mapping _pairs ) =+ (sem_Block_Mapping (sem_Pairs _pairs ) )+sem_Block (Block_Paragraph _paragraph ) =+ (sem_Block_Paragraph (sem_Inline _paragraph ) )+sem_Block (Block_Plugin _plugin ) =+ (sem_Block_Plugin _plugin )+sem_Block (Block_Verbatim _verbatim ) =+ (sem_Block_Verbatim (sem_Block _verbatim ) )+-- semantic domain+type T_Block = Document ->+ ( ShowS,([Processor Document Syn_Document]),Node,(XL.Content))+data Inh_Block = Inh_Block {sem_Inh_Block :: Document}+data Syn_Block = Syn_Block {latex_Syn_Block :: ShowS,processors_Syn_Block :: [Processor Document Syn_Document],xhtml_Syn_Block :: Node,xml_Syn_Block :: XL.Content}+wrap_Block :: T_Block ->+ Inh_Block ->+ Syn_Block +wrap_Block sem (Inh_Block _lhsIsem ) =+ (let ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml) =+ (sem _lhsIsem )+ in (Syn_Block _lhsOlatex _lhsOprocessors _lhsOxhtml _lhsOxml ))+sem_Block_Anchor :: String ->+ T_Block ->+ T_Block +sem_Block_Anchor name_ contents_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _contentsOsem :: Document+ _contentsIlatex :: ShowS+ _contentsIprocessors :: ([Processor Document Syn_Document])+ _contentsIxhtml :: Node+ _contentsIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 89, column 16)+ _lhsOxhtml =+ nameDiv name_ _contentsIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 87, column 16)+ _lhsOxml =+ xmlElem "anchor" [xmlText name_, _contentsIxml]+ -- "src/Text/Document/Printer/Latex.ag"(line 108, column 16)+ _lhsOlatex =+ ss "-- todo Anchor --"+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _contentsIprocessors+ -- copy rule (down)+ _contentsOsem =+ _lhsIsem+ ( _contentsIlatex,_contentsIprocessors,_contentsIxhtml,_contentsIxml) =+ (contents_ _contentsOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_Block_Blocks :: T_Blocks ->+ T_Block +sem_Block_Blocks blocks_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _blocksOsem :: Document+ _blocksIlatex :: ([ShowS])+ _blocksIprocessors :: ([Processor Document Syn_Document])+ _blocksIxhtml :: NodeSet+ _blocksIxml :: ([XL.Content])+ -- "src/Text/Document/Printer/Xhtml.ag"(line 82, column 16)+ _lhsOxhtml =+ nodeset _blocksIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 80, column 16)+ _lhsOxml =+ xmlElem "blocks" _blocksIxml+ -- "src/Text/Document/Printer/Latex.ag"(line 102, column 16)+ _lhsOlatex =+ intersperseS (eolS . eolS) _blocksIlatex+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _blocksIprocessors+ -- copy rule (down)+ _blocksOsem =+ _lhsIsem+ ( _blocksIlatex,_blocksIprocessors,_blocksIxhtml,_blocksIxml) =+ (blocks_ _blocksOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_Block_Caption :: T_Inline ->+ T_Block ->+ T_Block +sem_Block_Caption caption_ contents_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _contentsOsem :: Document+ _captionIlatex :: ShowS+ _captionIxhtml :: Node+ _captionIxml :: (XL.Content)+ _contentsIlatex :: ShowS+ _contentsIprocessors :: ([Processor Document Syn_Document])+ _contentsIxhtml :: Node+ _contentsIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 90, column 16)+ _lhsOxhtml =+ classDiv "caption" $ nodeset [(classDiv "caption-label" _captionIxhtml), _contentsIxhtml]+ -- "src/Text/Document/Printer/Xml.ag"(line 88, column 16)+ _lhsOxml =+ xmlElem "caption" [_captionIxml, _contentsIxml]+ -- "src/Text/Document/Printer/Latex.ag"(line 109, column 16)+ _lhsOlatex =+ ss "-- todo Caption --"+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _contentsIprocessors+ -- copy rule (down)+ _contentsOsem =+ _lhsIsem+ ( _captionIlatex,_captionIxhtml,_captionIxml) =+ (caption_ )+ ( _contentsIlatex,_contentsIprocessors,_contentsIxhtml,_contentsIxml) =+ (contents_ _contentsOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_Block_Comment :: String ->+ T_Block +sem_Block_Comment comment_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ -- "src/Text/Document/Printer/Xhtml.ag"(line 88, column 16)+ _lhsOxhtml =+ H.text comment_+ -- "src/Text/Document/Printer/Xml.ag"(line 86, column 16)+ _lhsOxml =+ xmlElem "comment" [xmlText comment_]+ -- "src/Text/Document/Printer/Latex.ag"(line 110, column 16)+ _lhsOlatex =+ ss comment_+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ []+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_Block_Enum :: T_Blocks ->+ T_Block +sem_Block_Enum items_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _itemsOsem :: Document+ _itemsIlatex :: ([ShowS])+ _itemsIprocessors :: ([Processor Document Syn_Document])+ _itemsIxhtml :: NodeSet+ _itemsIxml :: ([XL.Content])+ -- "src/Text/Document/Printer/Xhtml.ag"(line 84, column 16)+ _lhsOxhtml =+ ol _itemsIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 82, column 16)+ _lhsOxml =+ xmlElem "enum" (map (xmlElem "item" . (:[])) _itemsIxml)+ -- "src/Text/Document/Printer/Latex.ag"(line 104, column 16)+ _lhsOlatex =+ texEnumerate $ concatMapS (texItem.) _itemsIlatex+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _itemsIprocessors+ -- copy rule (down)+ _itemsOsem =+ _lhsIsem+ ( _itemsIlatex,_itemsIprocessors,_itemsIxhtml,_itemsIxml) =+ (items_ _itemsOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_Block_List :: T_Blocks ->+ T_Block +sem_Block_List items_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _itemsOsem :: Document+ _itemsIlatex :: ([ShowS])+ _itemsIprocessors :: ([Processor Document Syn_Document])+ _itemsIxhtml :: NodeSet+ _itemsIxml :: ([XL.Content])+ -- "src/Text/Document/Printer/Xhtml.ag"(line 85, column 16)+ _lhsOxhtml =+ ul _itemsIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 83, column 16)+ _lhsOxml =+ xmlElem "list" (map (xmlElem "item" . (:[])) _itemsIxml)+ -- "src/Text/Document/Printer/Latex.ag"(line 105, column 16)+ _lhsOlatex =+ texItemize $ concatMapS (texItem.) _itemsIlatex+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _itemsIprocessors+ -- copy rule (down)+ _itemsOsem =+ _lhsIsem+ ( _itemsIlatex,_itemsIprocessors,_itemsIxhtml,_itemsIxml) =+ (items_ _itemsOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_Block_Mapping :: T_Pairs ->+ T_Block +sem_Block_Mapping pairs_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _pairsOsem :: Document+ _pairsIlatex :: ([(ShowS, ShowS)])+ _pairsIxhtml :: ([(Node, Node)])+ _pairsIxml :: ([XL.Content])+ -- "src/Text/Document/Printer/Xhtml.ag"(line 86, column 16)+ _lhsOxhtml =+ dl _pairsIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 84, column 16)+ _lhsOxml =+ xmlElem "mapping" _pairsIxml+ -- "src/Text/Document/Printer/Latex.ag"(line 106, column 16)+ _lhsOlatex =+ texItemize $ concatMapS texMapping _pairsIlatex+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ []+ -- copy rule (down)+ _pairsOsem =+ _lhsIsem+ ( _pairsIlatex,_pairsIxhtml,_pairsIxml) =+ (pairs_ _pairsOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_Block_Paragraph :: T_Inline ->+ T_Block +sem_Block_Paragraph paragraph_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _paragraphIlatex :: ShowS+ _paragraphIxhtml :: Node+ _paragraphIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 83, column 16)+ _lhsOxhtml =+ par _paragraphIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 81, column 16)+ _lhsOxml =+ xmlElem "paragraph" [_paragraphIxml]+ -- "src/Text/Document/Printer/Latex.ag"(line 103, column 16)+ _lhsOlatex =+ _paragraphIlatex+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ []+ ( _paragraphIlatex,_paragraphIxhtml,_paragraphIxml) =+ (paragraph_ )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_Block_Plugin :: (( PrettyPrinter Document+ , Processor Document Syn_Document)) ->+ T_Block +sem_Block_Plugin plugin_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ -- "src/Text/Document/Printer/Xhtml.ag"(line 91, column 16)+ _lhsOxhtml =+ xhtmlPlugin (fst plugin_) _lhsIsem+ -- "src/Text/Document/Printer/Xml.ag"(line 89, column 16)+ _lhsOxml =+ xmlElem "plugin" [xmlPlugin (fst plugin_) _lhsIsem]+ -- "src/Text/Document/Printer/Latex.ag"(line 111, column 16)+ _lhsOlatex =+ texPlugin (fst plugin_) _lhsIsem+ -- "src/Text/Document/Core/Processing.ag"(line 11, column 20)+ _lhsOprocessors =+ [snd plugin_]+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_Block_Verbatim :: T_Block ->+ T_Block +sem_Block_Verbatim verbatim_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _verbatimOsem :: Document+ _verbatimIlatex :: ShowS+ _verbatimIprocessors :: ([Processor Document Syn_Document])+ _verbatimIxhtml :: Node+ _verbatimIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 87, column 16)+ _lhsOxhtml =+ pre _verbatimIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 85, column 16)+ _lhsOxml =+ xmlElem "verbatim" [_verbatimIxml]+ -- "src/Text/Document/Printer/Latex.ag"(line 107, column 16)+ _lhsOlatex =+ ss "-- todo Verbatim --"+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _verbatimIprocessors+ -- copy rule (down)+ _verbatimOsem =+ _lhsIsem+ ( _verbatimIlatex,_verbatimIprocessors,_verbatimIxhtml,_verbatimIxml) =+ (verbatim_ _verbatimOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+-- Blocks ------------------------------------------------------+{-+ visit 0:+ inherited attribute:+ sem : Document + synthesized attributes:+ latex : [ShowS]+ processors : [Processor Document Syn_Document]+ xhtml : NodeSet+ xml : [XL.Content]+ alternatives:+ alternative Cons:+ child hd : Block + child tl : Blocks + alternative Nil:+-}+type Blocks = [(Block)]+-- cata+sem_Blocks :: Blocks ->+ T_Blocks +sem_Blocks list =+ (Prelude.foldr sem_Blocks_Cons sem_Blocks_Nil (Prelude.map sem_Block list) )+-- semantic domain+type T_Blocks = Document ->+ ( ([ShowS]),([Processor Document Syn_Document]),NodeSet,([XL.Content]))+data Inh_Blocks = Inh_Blocks {sem_Inh_Blocks :: Document}+data Syn_Blocks = Syn_Blocks {latex_Syn_Blocks :: [ShowS],processors_Syn_Blocks :: [Processor Document Syn_Document],xhtml_Syn_Blocks :: NodeSet,xml_Syn_Blocks :: [XL.Content]}+wrap_Blocks :: T_Blocks ->+ Inh_Blocks ->+ Syn_Blocks +wrap_Blocks sem (Inh_Blocks _lhsIsem ) =+ (let ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml) =+ (sem _lhsIsem )+ in (Syn_Blocks _lhsOlatex _lhsOprocessors _lhsOxhtml _lhsOxml ))+sem_Blocks_Cons :: T_Block ->+ T_Blocks ->+ T_Blocks +sem_Blocks_Cons hd_ tl_ =+ (\ _lhsIsem ->+ (let _lhsOlatex :: ([ShowS])+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _lhsOxhtml :: NodeSet+ _lhsOxml :: ([XL.Content])+ _hdOsem :: Document+ _tlOsem :: Document+ _hdIlatex :: ShowS+ _hdIprocessors :: ([Processor Document Syn_Document])+ _hdIxhtml :: Node+ _hdIxml :: (XL.Content)+ _tlIlatex :: ([ShowS])+ _tlIprocessors :: ([Processor Document Syn_Document])+ _tlIxhtml :: NodeSet+ _tlIxml :: ([XL.Content])+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 75, column 39)+ _lhsOlatex =+ _hdIlatex : _tlIlatex+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _hdIprocessors ++ _tlIprocessors+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 58, column 39)+ _lhsOxhtml =+ _hdIxhtml : _tlIxhtml+ -- use rule "src/Text/Document/Printer/Xml.ag"(line 45, column 13)+ _lhsOxml =+ _hdIxml : _tlIxml+ -- copy rule (down)+ _hdOsem =+ _lhsIsem+ -- copy rule (down)+ _tlOsem =+ _lhsIsem+ ( _hdIlatex,_hdIprocessors,_hdIxhtml,_hdIxml) =+ (hd_ _hdOsem )+ ( _tlIlatex,_tlIprocessors,_tlIxhtml,_tlIxml) =+ (tl_ _tlOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_Blocks_Nil :: T_Blocks +sem_Blocks_Nil =+ (\ _lhsIsem ->+ (let _lhsOlatex :: ([ShowS])+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _lhsOxhtml :: NodeSet+ _lhsOxml :: ([XL.Content])+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 75, column 39)+ _lhsOlatex =+ []+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ []+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 58, column 39)+ _lhsOxhtml =+ []+ -- use rule "src/Text/Document/Printer/Xml.ag"(line 45, column 13)+ _lhsOxml =+ []+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+-- Document ----------------------------------------------------+{-+ visit 0:+ inherited attribute:+ sem : Document + synthesized attributes:+ latex : ShowS+ processors : [Processor Document Syn_Document]+ xhtml : Node+ xhtmlTOC : NodeSet+ xml : XL.Content+ alternatives:+ alternative Document:+ child title : Title + child subtitle : Title + child annotations : Annotations + child abstract : MaybeBlock + child body : SectionContents +-}+data Document = Document_Document (Title) (Title) (Annotations) (MaybeBlock) (SectionContents) + deriving ( Eq,Show)+-- cata+sem_Document :: Document ->+ T_Document +sem_Document (Document_Document _title _subtitle _annotations _abstract _body ) =+ (sem_Document_Document (sem_Title _title ) (sem_Title _subtitle ) (sem_Annotations _annotations ) (sem_MaybeBlock _abstract ) (sem_SectionContents _body ) )+-- semantic domain+type T_Document = Document ->+ ( ShowS,([Processor Document Syn_Document]),Node,NodeSet,(XL.Content))+data Inh_Document = Inh_Document {sem_Inh_Document :: Document}+data Syn_Document = Syn_Document {latex_Syn_Document :: ShowS,processors_Syn_Document :: [Processor Document Syn_Document],xhtml_Syn_Document :: Node,xhtmlTOC_Syn_Document :: NodeSet,xml_Syn_Document :: XL.Content}+wrap_Document :: T_Document ->+ Inh_Document ->+ Syn_Document +wrap_Document sem (Inh_Document _lhsIsem ) =+ (let ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxhtmlTOC,_lhsOxml) =+ (sem _lhsIsem )+ in (Syn_Document _lhsOlatex _lhsOprocessors _lhsOxhtml _lhsOxhtmlTOC _lhsOxml ))+sem_Document_Document :: T_Title ->+ T_Title ->+ T_Annotations ->+ T_MaybeBlock ->+ T_SectionContents ->+ T_Document +sem_Document_Document title_ subtitle_ annotations_ abstract_ body_ =+ (\ _lhsIsem ->+ (let _bodyOlevel :: Int+ _bodyOsection :: ([Int])+ _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOxhtmlTOC :: NodeSet+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _abstractOsem :: Document+ _bodyOsem :: Document+ _titleIisTitle :: Bool+ _titleIlatex :: ShowS+ _titleIxhtml :: Node+ _titleIxml :: ([XL.Content])+ _subtitleIisTitle :: Bool+ _subtitleIlatex :: ShowS+ _subtitleIxhtml :: Node+ _subtitleIxml :: ([XL.Content])+ _annotationsIxhtml :: ([(String, Node)])+ _annotationsIxml :: ([XL.Content])+ _abstractIlatex :: ShowS+ _abstractIprocessors :: ([Processor Document Syn_Document])+ _abstractIxhtml :: Node+ _abstractIxml :: ([XL.Content])+ _bodyIlatex :: ([ShowS])+ _bodyIprocessors :: ([Processor Document Syn_Document])+ _bodyIsection :: ([Int])+ _bodyIxhtml :: NodeSet+ _bodyIxhtmlTOC :: NodeSet+ _bodyIxml :: ([XL.Content])+ -- "src/Text/Document/Core/Structure.ag"(line 10, column 15)+ _bodyOlevel =+ 1+ -- "src/Text/Document/Core/Structure.ag"(line 33, column 14)+ _bodyOsection =+ [1]+ -- "src/Text/Document/Printer/Xhtml.ag"(line 65, column 16)+ _lhsOxhtml =+ xhtmlDocument+ _titleIxhtml+ _subtitleIxhtml+ _annotationsIxhtml+ _abstractIxhtml+ _bodyIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 48, column 16)+ _lhsOxml =+ xmlElem "document" [+ xmlElem "title" (map xmlStrip _titleIxml)+ , xmlElem "subtitle" (map xmlStrip _subtitleIxml)+ , xmlElem "annotations" _annotationsIxml+ , xmlElem "abstract" _abstractIxml+ , xmlElem "body" _bodyIxml+ ]+ -- "src/Text/Document/Printer/Latex.ag"(line 82, column 16)+ _lhsOlatex =+ texDocument+ _titleIlatex+ _subtitleIlatex+ _abstractIlatex+ (unlinesS _bodyIlatex)+ -- "src/Text/Document/Plugin/TOC.ag"(line 12, column 14)+ _lhsOxhtmlTOC =+ xhtmlCleanList _bodyIxhtmlTOC+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _abstractIprocessors ++ _bodyIprocessors+ -- copy rule (down)+ _abstractOsem =+ _lhsIsem+ -- copy rule (down)+ _bodyOsem =+ _lhsIsem+ ( _titleIisTitle,_titleIlatex,_titleIxhtml,_titleIxml) =+ (title_ )+ ( _subtitleIisTitle,_subtitleIlatex,_subtitleIxhtml,_subtitleIxml) =+ (subtitle_ )+ ( _annotationsIxhtml,_annotationsIxml) =+ (annotations_ )+ ( _abstractIlatex,_abstractIprocessors,_abstractIxhtml,_abstractIxml) =+ (abstract_ _abstractOsem )+ ( _bodyIlatex,_bodyIprocessors,_bodyIsection,_bodyIxhtml,_bodyIxhtmlTOC,_bodyIxml) =+ (body_ _bodyOlevel _bodyOsection _bodyOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxhtmlTOC,_lhsOxml)))+-- EitherStructureBlock ----------------------------------------+{-+ visit 0:+ inherited attributes:+ level : Int+ sem : Document + chained attribute:+ section : [Int]+ synthesized attributes:+ latex : ShowS+ processors : [Processor Document Syn_Document]+ xhtml : Node+ xhtmlTOC : NodeSet+ xml : XL.Content+ alternatives:+ alternative Left:+ child left : Structure + alternative Right:+ child right : Block +-}+type EitherStructureBlock = (Either (Structure) (Block))+-- cata+sem_EitherStructureBlock :: EitherStructureBlock ->+ T_EitherStructureBlock +sem_EitherStructureBlock (Prelude.Left x ) =+ (sem_EitherStructureBlock_Left (sem_Structure x ) )+sem_EitherStructureBlock (Prelude.Right x ) =+ (sem_EitherStructureBlock_Right (sem_Block x ) )+-- semantic domain+type T_EitherStructureBlock = Int ->+ ([Int]) ->+ Document ->+ ( ShowS,([Processor Document Syn_Document]),([Int]),Node,NodeSet,(XL.Content))+data Inh_EitherStructureBlock = Inh_EitherStructureBlock {level_Inh_EitherStructureBlock :: Int,section_Inh_EitherStructureBlock :: [Int],sem_Inh_EitherStructureBlock :: Document}+data Syn_EitherStructureBlock = Syn_EitherStructureBlock {latex_Syn_EitherStructureBlock :: ShowS,processors_Syn_EitherStructureBlock :: [Processor Document Syn_Document],section_Syn_EitherStructureBlock :: [Int],xhtml_Syn_EitherStructureBlock :: Node,xhtmlTOC_Syn_EitherStructureBlock :: NodeSet,xml_Syn_EitherStructureBlock :: XL.Content}+wrap_EitherStructureBlock :: T_EitherStructureBlock ->+ Inh_EitherStructureBlock ->+ Syn_EitherStructureBlock +wrap_EitherStructureBlock sem (Inh_EitherStructureBlock _lhsIlevel _lhsIsection _lhsIsem ) =+ (let ( _lhsOlatex,_lhsOprocessors,_lhsOsection,_lhsOxhtml,_lhsOxhtmlTOC,_lhsOxml) =+ (sem _lhsIlevel _lhsIsection _lhsIsem )+ in (Syn_EitherStructureBlock _lhsOlatex _lhsOprocessors _lhsOsection _lhsOxhtml _lhsOxhtmlTOC _lhsOxml ))+sem_EitherStructureBlock_Left :: T_Structure ->+ T_EitherStructureBlock +sem_EitherStructureBlock_Left left_ =+ (\ _lhsIlevel+ _lhsIsection+ _lhsIsem ->+ (let _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _lhsOxhtml :: Node+ _lhsOxhtmlTOC :: NodeSet+ _lhsOsection :: ([Int])+ _lhsOxml :: (XL.Content)+ _leftOlevel :: Int+ _leftOsection :: ([Int])+ _leftOsem :: Document+ _leftIlatex :: ShowS+ _leftIprocessors :: ([Processor Document Syn_Document])+ _leftIsection :: ([Int])+ _leftIxhtml :: Node+ _leftIxhtmlTOC :: NodeSet+ _leftIxml :: (XL.Content)+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 73, column 39)+ _lhsOlatex =+ _leftIlatex+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _leftIprocessors+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 56, column 39)+ _lhsOxhtml =+ _leftIxhtml+ -- use rule "src/Text/Document/Plugin/TOC.ag"(line 8, column 52)+ _lhsOxhtmlTOC =+ _leftIxhtmlTOC+ -- copy rule (up)+ _lhsOsection =+ _leftIsection+ -- copy rule (up)+ _lhsOxml =+ _leftIxml+ -- copy rule (down)+ _leftOlevel =+ _lhsIlevel+ -- copy rule (down)+ _leftOsection =+ _lhsIsection+ -- copy rule (down)+ _leftOsem =+ _lhsIsem+ ( _leftIlatex,_leftIprocessors,_leftIsection,_leftIxhtml,_leftIxhtmlTOC,_leftIxml) =+ (left_ _leftOlevel _leftOsection _leftOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOsection,_lhsOxhtml,_lhsOxhtmlTOC,_lhsOxml)))+sem_EitherStructureBlock_Right :: T_Block ->+ T_EitherStructureBlock +sem_EitherStructureBlock_Right right_ =+ (\ _lhsIlevel+ _lhsIsection+ _lhsIsem ->+ (let _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _lhsOxhtml :: Node+ _lhsOxhtmlTOC :: NodeSet+ _lhsOsection :: ([Int])+ _lhsOxml :: (XL.Content)+ _rightOsem :: Document+ _rightIlatex :: ShowS+ _rightIprocessors :: ([Processor Document Syn_Document])+ _rightIxhtml :: Node+ _rightIxml :: (XL.Content)+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 73, column 39)+ _lhsOlatex =+ _rightIlatex+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _rightIprocessors+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 56, column 39)+ _lhsOxhtml =+ _rightIxhtml+ -- use rule "src/Text/Document/Plugin/TOC.ag"(line 8, column 52)+ _lhsOxhtmlTOC =+ []+ -- copy rule (chain)+ _lhsOsection =+ _lhsIsection+ -- copy rule (up)+ _lhsOxml =+ _rightIxml+ -- copy rule (down)+ _rightOsem =+ _lhsIsem+ ( _rightIlatex,_rightIprocessors,_rightIxhtml,_rightIxml) =+ (right_ _rightOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOsection,_lhsOxhtml,_lhsOxhtmlTOC,_lhsOxml)))+-- Inline ------------------------------------------------------+{-+ visit 0:+ synthesized attributes:+ latex : ShowS+ xhtml : Node+ xml : XL.Content+ alternatives:+ alternative Emph:+ child emph : Inline + alternative Fixed:+ child fixed : Inline + alternative Footnote:+ child note : Inline + alternative Image:+ child source : {String}+ child description : {String}+ alternative Lines:+ child lines : Inlines + alternative Link:+ child ref : {String}+ child kind : {LinkType}+ child description : Inline + alternative Quote:+ child quote : Inline + alternative Strong:+ child strong : Inline + alternative Text:+ child text : {String}+-}+data Inline = Inline_Emph (Inline) + | Inline_Fixed (Inline) + | Inline_Footnote (Inline) + | Inline_Image (String) (String) + | Inline_Lines (Inlines) + | Inline_Link (String) (LinkType) (Inline) + | Inline_Quote (Inline) + | Inline_Strong (Inline) + | Inline_Text (String) + deriving ( Eq,Show)+-- cata+sem_Inline :: Inline ->+ T_Inline +sem_Inline (Inline_Emph _emph ) =+ (sem_Inline_Emph (sem_Inline _emph ) )+sem_Inline (Inline_Fixed _fixed ) =+ (sem_Inline_Fixed (sem_Inline _fixed ) )+sem_Inline (Inline_Footnote _note ) =+ (sem_Inline_Footnote (sem_Inline _note ) )+sem_Inline (Inline_Image _source _description ) =+ (sem_Inline_Image _source _description )+sem_Inline (Inline_Lines _lines ) =+ (sem_Inline_Lines (sem_Inlines _lines ) )+sem_Inline (Inline_Link _ref _kind _description ) =+ (sem_Inline_Link _ref _kind (sem_Inline _description ) )+sem_Inline (Inline_Quote _quote ) =+ (sem_Inline_Quote (sem_Inline _quote ) )+sem_Inline (Inline_Strong _strong ) =+ (sem_Inline_Strong (sem_Inline _strong ) )+sem_Inline (Inline_Text _text ) =+ (sem_Inline_Text _text )+-- semantic domain+type T_Inline = ( ShowS,Node,(XL.Content))+data Inh_Inline = Inh_Inline {}+data Syn_Inline = Syn_Inline {latex_Syn_Inline :: ShowS,xhtml_Syn_Inline :: Node,xml_Syn_Inline :: XL.Content}+wrap_Inline :: T_Inline ->+ Inh_Inline ->+ Syn_Inline +wrap_Inline sem (Inh_Inline ) =+ (let ( _lhsOlatex,_lhsOxhtml,_lhsOxml) =+ (sem )+ in (Syn_Inline _lhsOlatex _lhsOxhtml _lhsOxml ))+sem_Inline_Emph :: T_Inline ->+ T_Inline +sem_Inline_Emph emph_ =+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _emphIlatex :: ShowS+ _emphIxhtml :: Node+ _emphIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 97, column 16)+ _lhsOxhtml =+ H.emph _emphIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 98, column 16)+ _lhsOxml =+ xmlElem "emph" [_emphIxml]+ -- "src/Text/Document/Printer/Latex.ag"(line 117, column 16)+ _lhsOlatex =+ texEmph _emphIlatex+ ( _emphIlatex,_emphIxhtml,_emphIxml) =+ (emph_ )+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+sem_Inline_Fixed :: T_Inline ->+ T_Inline +sem_Inline_Fixed fixed_ =+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _fixedIlatex :: ShowS+ _fixedIxhtml :: Node+ _fixedIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 99, column 16)+ _lhsOxhtml =+ tt _fixedIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 100, column 16)+ _lhsOxml =+ xmlElem "fixed" [_fixedIxml]+ -- "src/Text/Document/Printer/Latex.ag"(line 119, column 16)+ _lhsOlatex =+ texFixed _fixedIlatex+ ( _fixedIlatex,_fixedIxhtml,_fixedIxml) =+ (fixed_ )+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+sem_Inline_Footnote :: T_Inline ->+ T_Inline +sem_Inline_Footnote note_ =+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _noteIlatex :: ShowS+ _noteIxhtml :: Node+ _noteIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 101, column 16)+ _lhsOxhtml =+ classSpan "footnote" _noteIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 106, column 16)+ _lhsOxml =+ xmlElem "footnote" [_noteIxml]+ -- "src/Text/Document/Printer/Latex.ag"(line 123, column 16)+ _lhsOlatex =+ texFootnote _noteIlatex+ ( _noteIlatex,_noteIxhtml,_noteIxml) =+ (note_ )+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+sem_Inline_Image :: String ->+ String ->+ T_Inline +sem_Inline_Image source_ description_ =+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ -- "src/Text/Document/Printer/Xhtml.ag"(line 95, column 16)+ _lhsOxhtml =+ img source_ description_+ -- "src/Text/Document/Printer/Xml.ag"(line 93, column 16)+ _lhsOxml =+ xmlElem "image" [+ xmlElem "source" [xmlText source_]+ , xmlElem "description" [xmlText description_]+ ]+ -- "src/Text/Document/Printer/Latex.ag"(line 115, column 16)+ _lhsOlatex =+ ss "todo"+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+sem_Inline_Lines :: T_Inlines ->+ T_Inline +sem_Inline_Lines lines_ =+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _linesIlatex :: ([ShowS])+ _linesIxhtml :: NodeSet+ _linesIxml :: ([XL.Content])+ -- "src/Text/Document/Printer/Xhtml.ag"(line 94, column 16)+ _lhsOxhtml =+ nodeset _linesIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 92, column 16)+ _lhsOxml =+ xmlElem "lines" _linesIxml+ -- "src/Text/Document/Printer/Latex.ag"(line 114, column 16)+ _lhsOlatex =+ concatS _linesIlatex+ ( _linesIlatex,_linesIxhtml,_linesIxml) =+ (lines_ )+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+sem_Inline_Link :: String ->+ LinkType ->+ T_Inline ->+ T_Inline +sem_Inline_Link ref_ kind_ description_ =+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _descriptionIlatex :: ShowS+ _descriptionIxhtml :: Node+ _descriptionIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 100, column 16)+ _lhsOxhtml =+ xhtmlLink kind_ (linkAnchor kind_ ref_) _descriptionIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 101, column 16)+ _lhsOxml =+ xmlElem "link" [+ xmlElem "ref" [xmlText ref_]+ , xmlElem "kind" [xmlText (show kind_)]+ , xmlElem "description" [_descriptionIxml]+ ]+ -- "src/Text/Document/Printer/Latex.ag"(line 120, column 16)+ _lhsOlatex =+ if kind_ == External+ then texLink ref_ _descriptionIlatex+ else ss "-- todo non-External Links --"+ ( _descriptionIlatex,_descriptionIxhtml,_descriptionIxml) =+ (description_ )+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+sem_Inline_Quote :: T_Inline ->+ T_Inline +sem_Inline_Quote quote_ =+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _quoteIlatex :: ShowS+ _quoteIxhtml :: Node+ _quoteIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 102, column 16)+ _lhsOxhtml =+ cite _quoteIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 107, column 16)+ _lhsOxml =+ xmlElem "quote" [_quoteIxml]+ -- "src/Text/Document/Printer/Latex.ag"(line 124, column 16)+ _lhsOlatex =+ ss "-- todo Quote --"+ ( _quoteIlatex,_quoteIxhtml,_quoteIxml) =+ (quote_ )+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+sem_Inline_Strong :: T_Inline ->+ T_Inline +sem_Inline_Strong strong_ =+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _strongIlatex :: ShowS+ _strongIxhtml :: Node+ _strongIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 98, column 16)+ _lhsOxhtml =+ H.strong _strongIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 99, column 16)+ _lhsOxml =+ xmlElem "strong" [_strongIxml]+ -- "src/Text/Document/Printer/Latex.ag"(line 118, column 16)+ _lhsOlatex =+ texStrong _strongIlatex+ ( _strongIlatex,_strongIxhtml,_strongIxml) =+ (strong_ )+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+sem_Inline_Text :: String ->+ T_Inline +sem_Inline_Text text_ =+ (let _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ -- "src/Text/Document/Printer/Xhtml.ag"(line 96, column 16)+ _lhsOxhtml =+ H.text text_+ -- "src/Text/Document/Printer/Xml.ag"(line 97, column 16)+ _lhsOxml =+ xmlText text_+ -- "src/Text/Document/Printer/Latex.ag"(line 116, column 16)+ _lhsOlatex =+ ss (escapeTex text_)+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+-- Inlines -----------------------------------------------------+{-+ visit 0:+ synthesized attributes:+ latex : [ShowS]+ xhtml : NodeSet+ xml : [XL.Content]+ alternatives:+ alternative Cons:+ child hd : Inline + child tl : Inlines + alternative Nil:+-}+type Inlines = [(Inline)]+-- cata+sem_Inlines :: Inlines ->+ T_Inlines +sem_Inlines list =+ (Prelude.foldr sem_Inlines_Cons sem_Inlines_Nil (Prelude.map sem_Inline list) )+-- semantic domain+type T_Inlines = ( ([ShowS]),NodeSet,([XL.Content]))+data Inh_Inlines = Inh_Inlines {}+data Syn_Inlines = Syn_Inlines {latex_Syn_Inlines :: [ShowS],xhtml_Syn_Inlines :: NodeSet,xml_Syn_Inlines :: [XL.Content]}+wrap_Inlines :: T_Inlines ->+ Inh_Inlines ->+ Syn_Inlines +wrap_Inlines sem (Inh_Inlines ) =+ (let ( _lhsOlatex,_lhsOxhtml,_lhsOxml) =+ (sem )+ in (Syn_Inlines _lhsOlatex _lhsOxhtml _lhsOxml ))+sem_Inlines_Cons :: T_Inline ->+ T_Inlines ->+ T_Inlines +sem_Inlines_Cons hd_ tl_ =+ (let _lhsOlatex :: ([ShowS])+ _lhsOxhtml :: NodeSet+ _lhsOxml :: ([XL.Content])+ _hdIlatex :: ShowS+ _hdIxhtml :: Node+ _hdIxml :: (XL.Content)+ _tlIlatex :: ([ShowS])+ _tlIxhtml :: NodeSet+ _tlIxml :: ([XL.Content])+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 75, column 39)+ _lhsOlatex =+ _hdIlatex : _tlIlatex+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 58, column 39)+ _lhsOxhtml =+ _hdIxhtml : _tlIxhtml+ -- use rule "src/Text/Document/Printer/Xml.ag"(line 45, column 13)+ _lhsOxml =+ _hdIxml : _tlIxml+ ( _hdIlatex,_hdIxhtml,_hdIxml) =+ (hd_ )+ ( _tlIlatex,_tlIxhtml,_tlIxml) =+ (tl_ )+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+sem_Inlines_Nil :: T_Inlines +sem_Inlines_Nil =+ (let _lhsOlatex :: ([ShowS])+ _lhsOxhtml :: NodeSet+ _lhsOxml :: ([XL.Content])+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 75, column 39)+ _lhsOlatex =+ []+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 58, column 39)+ _lhsOxhtml =+ []+ -- use rule "src/Text/Document/Printer/Xml.ag"(line 45, column 13)+ _lhsOxml =+ []+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml))+-- MaybeBlock --------------------------------------------------+{-+ visit 0:+ inherited attribute:+ sem : Document + synthesized attributes:+ latex : ShowS+ processors : [Processor Document Syn_Document]+ xhtml : Node+ xml : [XL.Content]+ alternatives:+ alternative Just:+ child just : Block + alternative Nothing:+-}+type MaybeBlock = (Maybe (Block))+-- cata+sem_MaybeBlock :: MaybeBlock ->+ T_MaybeBlock +sem_MaybeBlock (Prelude.Just x ) =+ (sem_MaybeBlock_Just (sem_Block x ) )+sem_MaybeBlock Prelude.Nothing =+ sem_MaybeBlock_Nothing+-- semantic domain+type T_MaybeBlock = Document ->+ ( ShowS,([Processor Document Syn_Document]),Node,([XL.Content]))+data Inh_MaybeBlock = Inh_MaybeBlock {sem_Inh_MaybeBlock :: Document}+data Syn_MaybeBlock = Syn_MaybeBlock {latex_Syn_MaybeBlock :: ShowS,processors_Syn_MaybeBlock :: [Processor Document Syn_Document],xhtml_Syn_MaybeBlock :: Node,xml_Syn_MaybeBlock :: [XL.Content]}+wrap_MaybeBlock :: T_MaybeBlock ->+ Inh_MaybeBlock ->+ Syn_MaybeBlock +wrap_MaybeBlock sem (Inh_MaybeBlock _lhsIsem ) =+ (let ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml) =+ (sem _lhsIsem )+ in (Syn_MaybeBlock _lhsOlatex _lhsOprocessors _lhsOxhtml _lhsOxml ))+sem_MaybeBlock_Just :: T_Block ->+ T_MaybeBlock +sem_MaybeBlock_Just just_ =+ (\ _lhsIsem ->+ (let _lhsOxml :: ([XL.Content])+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _lhsOxhtml :: Node+ _justOsem :: Document+ _justIlatex :: ShowS+ _justIprocessors :: ([Processor Document Syn_Document])+ _justIxhtml :: Node+ _justIxml :: (XL.Content)+ -- "src/Text/Document/Printer/Xml.ag"(line 68, column 16)+ _lhsOxml =+ [xmlElem "maybeblock" [_justIxml]]+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 73, column 39)+ _lhsOlatex =+ _justIlatex+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _justIprocessors+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 56, column 39)+ _lhsOxhtml =+ _justIxhtml+ -- copy rule (down)+ _justOsem =+ _lhsIsem+ ( _justIlatex,_justIprocessors,_justIxhtml,_justIxml) =+ (just_ _justOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+sem_MaybeBlock_Nothing :: T_MaybeBlock +sem_MaybeBlock_Nothing =+ (\ _lhsIsem ->+ (let _lhsOxml :: ([XL.Content])+ _lhsOlatex :: ShowS+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _lhsOxhtml :: Node+ -- "src/Text/Document/Printer/Xml.ag"(line 67, column 16)+ _lhsOxml =+ []+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 73, column 39)+ _lhsOlatex =+ id+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ []+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 56, column 39)+ _lhsOxhtml =+ empty+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+-- Pair --------------------------------------------------------+{-+ visit 0:+ inherited attribute:+ sem : Document + synthesized attributes:+ latex : (ShowS, ShowS)+ processors : [Processor Document Syn_Document]+ xhtml : (Node, Node)+ xml : XL.Content+ alternatives:+ alternative Tuple:+ child x1 : Block + child x2 : Block +-}+type Pair = ( (Block),(Block))+-- cata+sem_Pair :: Pair ->+ T_Pair +sem_Pair ( x1,x2) =+ (sem_Pair_Tuple (sem_Block x1 ) (sem_Block x2 ) )+-- semantic domain+type T_Pair = Document ->+ ( ((ShowS, ShowS)),([Processor Document Syn_Document]),((Node, Node)),(XL.Content))+data Inh_Pair = Inh_Pair {sem_Inh_Pair :: Document}+data Syn_Pair = Syn_Pair {latex_Syn_Pair :: (ShowS, ShowS),processors_Syn_Pair :: [Processor Document Syn_Document],xhtml_Syn_Pair :: (Node, Node),xml_Syn_Pair :: XL.Content}+wrap_Pair :: T_Pair ->+ Inh_Pair ->+ Syn_Pair +wrap_Pair sem (Inh_Pair _lhsIsem ) =+ (let ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml) =+ (sem _lhsIsem )+ in (Syn_Pair _lhsOlatex _lhsOprocessors _lhsOxhtml _lhsOxml ))+sem_Pair_Tuple :: T_Block ->+ T_Block ->+ T_Pair +sem_Pair_Tuple x1_ x2_ =+ (\ _lhsIsem ->+ (let _lhsOxhtml :: ((Node, Node))+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ((ShowS, ShowS))+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _x1Osem :: Document+ _x2Osem :: Document+ _x1Ilatex :: ShowS+ _x1Iprocessors :: ([Processor Document Syn_Document])+ _x1Ixhtml :: Node+ _x1Ixml :: (XL.Content)+ _x2Ilatex :: ShowS+ _x2Iprocessors :: ([Processor Document Syn_Document])+ _x2Ixhtml :: Node+ _x2Ixml :: (XL.Content)+ -- "src/Text/Document/Printer/Xhtml.ag"(line 79, column 16)+ _lhsOxhtml =+ (_x1Ixhtml, _x2Ixhtml)+ -- "src/Text/Document/Printer/Xml.ag"(line 77, column 16)+ _lhsOxml =+ xmlElem "pair" [_x1Ixml, _x2Ixml]+ -- "src/Text/Document/Printer/Latex.ag"(line 99, column 16)+ _lhsOlatex =+ (_x1Ilatex, _x2Ilatex)+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _x1Iprocessors ++ _x2Iprocessors+ -- copy rule (down)+ _x1Osem =+ _lhsIsem+ -- copy rule (down)+ _x2Osem =+ _lhsIsem+ ( _x1Ilatex,_x1Iprocessors,_x1Ixhtml,_x1Ixml) =+ (x1_ _x1Osem )+ ( _x2Ilatex,_x2Iprocessors,_x2Ixhtml,_x2Ixml) =+ (x2_ _x2Osem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOxhtml,_lhsOxml)))+-- Pairs -------------------------------------------------------+{-+ visit 0:+ inherited attribute:+ sem : Document + synthesized attributes:+ latex : [(ShowS, ShowS)]+ xhtml : [(Node, Node)]+ xml : [XL.Content]+ alternatives:+ alternative Cons:+ child hd : Pair + child tl : Pairs + alternative Nil:+-}+type Pairs = [(Pair)]+-- cata+sem_Pairs :: Pairs ->+ T_Pairs +sem_Pairs list =+ (Prelude.foldr sem_Pairs_Cons sem_Pairs_Nil (Prelude.map sem_Pair list) )+-- semantic domain+type T_Pairs = Document ->+ ( ([(ShowS, ShowS)]),([(Node, Node)]),([XL.Content]))+data Inh_Pairs = Inh_Pairs {sem_Inh_Pairs :: Document}+data Syn_Pairs = Syn_Pairs {latex_Syn_Pairs :: [(ShowS, ShowS)],xhtml_Syn_Pairs :: [(Node, Node)],xml_Syn_Pairs :: [XL.Content]}+wrap_Pairs :: T_Pairs ->+ Inh_Pairs ->+ Syn_Pairs +wrap_Pairs sem (Inh_Pairs _lhsIsem ) =+ (let ( _lhsOlatex,_lhsOxhtml,_lhsOxml) =+ (sem _lhsIsem )+ in (Syn_Pairs _lhsOlatex _lhsOxhtml _lhsOxml ))+sem_Pairs_Cons :: T_Pair ->+ T_Pairs ->+ T_Pairs +sem_Pairs_Cons hd_ tl_ =+ (\ _lhsIsem ->+ (let _lhsOlatex :: ([(ShowS, ShowS)])+ _lhsOxhtml :: ([(Node, Node)])+ _lhsOxml :: ([XL.Content])+ _hdOsem :: Document+ _tlOsem :: Document+ _hdIlatex :: ((ShowS, ShowS))+ _hdIprocessors :: ([Processor Document Syn_Document])+ _hdIxhtml :: ((Node, Node))+ _hdIxml :: (XL.Content)+ _tlIlatex :: ([(ShowS, ShowS)])+ _tlIxhtml :: ([(Node, Node)])+ _tlIxml :: ([XL.Content])+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 78, column 39)+ _lhsOlatex =+ _hdIlatex : _tlIlatex+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 61, column 39)+ _lhsOxhtml =+ _hdIxhtml : _tlIxhtml+ -- use rule "src/Text/Document/Printer/Xml.ag"(line 45, column 13)+ _lhsOxml =+ _hdIxml : _tlIxml+ -- copy rule (down)+ _hdOsem =+ _lhsIsem+ -- copy rule (down)+ _tlOsem =+ _lhsIsem+ ( _hdIlatex,_hdIprocessors,_hdIxhtml,_hdIxml) =+ (hd_ _hdOsem )+ ( _tlIlatex,_tlIxhtml,_tlIxml) =+ (tl_ _tlOsem )+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml)))+sem_Pairs_Nil :: T_Pairs +sem_Pairs_Nil =+ (\ _lhsIsem ->+ (let _lhsOlatex :: ([(ShowS, ShowS)])+ _lhsOxhtml :: ([(Node, Node)])+ _lhsOxml :: ([XL.Content])+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 78, column 39)+ _lhsOlatex =+ []+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 61, column 39)+ _lhsOxhtml =+ []+ -- use rule "src/Text/Document/Printer/Xml.ag"(line 45, column 13)+ _lhsOxml =+ []+ in ( _lhsOlatex,_lhsOxhtml,_lhsOxml)))+-- SectionContents ---------------------------------------------+{-+ visit 0:+ inherited attributes:+ level : Int+ sem : Document + chained attribute:+ section : [Int]+ synthesized attributes:+ latex : [ShowS]+ processors : [Processor Document Syn_Document]+ xhtml : NodeSet+ xhtmlTOC : NodeSet+ xml : [XL.Content]+ alternatives:+ alternative Cons:+ child hd : EitherStructureBlock + child tl : SectionContents + alternative Nil:+-}+type SectionContents = [(EitherStructureBlock)]+-- cata+sem_SectionContents :: SectionContents ->+ T_SectionContents +sem_SectionContents list =+ (Prelude.foldr sem_SectionContents_Cons sem_SectionContents_Nil (Prelude.map sem_EitherStructureBlock list) )+-- semantic domain+type T_SectionContents = Int ->+ ([Int]) ->+ Document ->+ ( ([ShowS]),([Processor Document Syn_Document]),([Int]),NodeSet,NodeSet,([XL.Content]))+data Inh_SectionContents = Inh_SectionContents {level_Inh_SectionContents :: Int,section_Inh_SectionContents :: [Int],sem_Inh_SectionContents :: Document}+data Syn_SectionContents = Syn_SectionContents {latex_Syn_SectionContents :: [ShowS],processors_Syn_SectionContents :: [Processor Document Syn_Document],section_Syn_SectionContents :: [Int],xhtml_Syn_SectionContents :: NodeSet,xhtmlTOC_Syn_SectionContents :: NodeSet,xml_Syn_SectionContents :: [XL.Content]}+wrap_SectionContents :: T_SectionContents ->+ Inh_SectionContents ->+ Syn_SectionContents +wrap_SectionContents sem (Inh_SectionContents _lhsIlevel _lhsIsection _lhsIsem ) =+ (let ( _lhsOlatex,_lhsOprocessors,_lhsOsection,_lhsOxhtml,_lhsOxhtmlTOC,_lhsOxml) =+ (sem _lhsIlevel _lhsIsection _lhsIsem )+ in (Syn_SectionContents _lhsOlatex _lhsOprocessors _lhsOsection _lhsOxhtml _lhsOxhtmlTOC _lhsOxml ))+sem_SectionContents_Cons :: T_EitherStructureBlock ->+ T_SectionContents ->+ T_SectionContents +sem_SectionContents_Cons hd_ tl_ =+ (\ _lhsIlevel+ _lhsIsection+ _lhsIsem ->+ (let _lhsOxhtmlTOC :: NodeSet+ _lhsOlatex :: ([ShowS])+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _lhsOxhtml :: NodeSet+ _lhsOxml :: ([XL.Content])+ _lhsOsection :: ([Int])+ _hdOlevel :: Int+ _hdOsection :: ([Int])+ _hdOsem :: Document+ _tlOlevel :: Int+ _tlOsection :: ([Int])+ _tlOsem :: Document+ _hdIlatex :: ShowS+ _hdIprocessors :: ([Processor Document Syn_Document])+ _hdIsection :: ([Int])+ _hdIxhtml :: Node+ _hdIxhtmlTOC :: NodeSet+ _hdIxml :: (XL.Content)+ _tlIlatex :: ([ShowS])+ _tlIprocessors :: ([Processor Document Syn_Document])+ _tlIsection :: ([Int])+ _tlIxhtml :: NodeSet+ _tlIxhtmlTOC :: NodeSet+ _tlIxml :: ([XL.Content])+ -- "src/Text/Document/Plugin/TOC.ag"(line 23, column 10)+ _lhsOxhtmlTOC =+ _hdIxhtmlTOC ++ _tlIxhtmlTOC+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 75, column 39)+ _lhsOlatex =+ _hdIlatex : _tlIlatex+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _hdIprocessors ++ _tlIprocessors+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 58, column 39)+ _lhsOxhtml =+ _hdIxhtml : _tlIxhtml+ -- use rule "src/Text/Document/Printer/Xml.ag"(line 45, column 13)+ _lhsOxml =+ _hdIxml : _tlIxml+ -- copy rule (up)+ _lhsOsection =+ _tlIsection+ -- copy rule (down)+ _hdOlevel =+ _lhsIlevel+ -- copy rule (down)+ _hdOsection =+ _lhsIsection+ -- copy rule (down)+ _hdOsem =+ _lhsIsem+ -- copy rule (down)+ _tlOlevel =+ _lhsIlevel+ -- copy rule (chain)+ _tlOsection =+ _hdIsection+ -- copy rule (down)+ _tlOsem =+ _lhsIsem+ ( _hdIlatex,_hdIprocessors,_hdIsection,_hdIxhtml,_hdIxhtmlTOC,_hdIxml) =+ (hd_ _hdOlevel _hdOsection _hdOsem )+ ( _tlIlatex,_tlIprocessors,_tlIsection,_tlIxhtml,_tlIxhtmlTOC,_tlIxml) =+ (tl_ _tlOlevel _tlOsection _tlOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOsection,_lhsOxhtml,_lhsOxhtmlTOC,_lhsOxml)))+sem_SectionContents_Nil :: T_SectionContents +sem_SectionContents_Nil =+ (\ _lhsIlevel+ _lhsIsection+ _lhsIsem ->+ (let _lhsOlatex :: ([ShowS])+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _lhsOxhtml :: NodeSet+ _lhsOxhtmlTOC :: NodeSet+ _lhsOxml :: ([XL.Content])+ _lhsOsection :: ([Int])+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 75, column 39)+ _lhsOlatex =+ []+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ []+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 58, column 39)+ _lhsOxhtml =+ []+ -- use rule "src/Text/Document/Plugin/TOC.ag"(line 9, column 52)+ _lhsOxhtmlTOC =+ []+ -- use rule "src/Text/Document/Printer/Xml.ag"(line 45, column 13)+ _lhsOxml =+ []+ -- copy rule (chain)+ _lhsOsection =+ _lhsIsection+ in ( _lhsOlatex,_lhsOprocessors,_lhsOsection,_lhsOxhtml,_lhsOxhtmlTOC,_lhsOxml)))+-- Structure ---------------------------------------------------+{-+ visit 0:+ inherited attributes:+ level : Int+ sem : Document + chained attribute:+ section : [Int]+ synthesized attributes:+ latex : ShowS+ processors : [Processor Document Syn_Document]+ xhtml : Node+ xhtmlTOC : NodeSet+ xml : XL.Content+ alternatives:+ alternative Section:+ child title : Title + child contents : SectionContents +-}+data Structure = Structure_Section (Title) (SectionContents) + deriving ( Eq,Show)+-- cata+sem_Structure :: Structure ->+ T_Structure +sem_Structure (Structure_Section _title _contents ) =+ (sem_Structure_Section (sem_Title _title ) (sem_SectionContents _contents ) )+-- semantic domain+type T_Structure = Int ->+ ([Int]) ->+ Document ->+ ( ShowS,([Processor Document Syn_Document]),([Int]),Node,NodeSet,(XL.Content))+data Inh_Structure = Inh_Structure {level_Inh_Structure :: Int,section_Inh_Structure :: [Int],sem_Inh_Structure :: Document}+data Syn_Structure = Syn_Structure {latex_Syn_Structure :: ShowS,processors_Syn_Structure :: [Processor Document Syn_Document],section_Syn_Structure :: [Int],xhtml_Syn_Structure :: Node,xhtmlTOC_Syn_Structure :: NodeSet,xml_Syn_Structure :: XL.Content}+wrap_Structure :: T_Structure ->+ Inh_Structure ->+ Syn_Structure +wrap_Structure sem (Inh_Structure _lhsIlevel _lhsIsection _lhsIsem ) =+ (let ( _lhsOlatex,_lhsOprocessors,_lhsOsection,_lhsOxhtml,_lhsOxhtmlTOC,_lhsOxml) =+ (sem _lhsIlevel _lhsIsection _lhsIsem )+ in (Syn_Structure _lhsOlatex _lhsOprocessors _lhsOsection _lhsOxhtml _lhsOxhtmlTOC _lhsOxml ))+sem_Structure_Section :: T_Title ->+ T_SectionContents ->+ T_Structure +sem_Structure_Section title_ contents_ =+ (\ _lhsIlevel+ _lhsIsection+ _lhsIsem ->+ (let _contentsOlevel :: Int+ _contentsOsection :: ([Int])+ _lhsOsection :: ([Int])+ _lhsOxhtml :: Node+ _lhsOxml :: (XL.Content)+ _lhsOlatex :: ShowS+ _lhsOxhtmlTOC :: NodeSet+ _lhsOprocessors :: ([Processor Document Syn_Document])+ _contentsOsem :: Document+ _titleIisTitle :: Bool+ _titleIlatex :: ShowS+ _titleIxhtml :: Node+ _titleIxml :: ([XL.Content])+ _contentsIlatex :: ([ShowS])+ _contentsIprocessors :: ([Processor Document Syn_Document])+ _contentsIsection :: ([Int])+ _contentsIxhtml :: NodeSet+ _contentsIxhtmlTOC :: NodeSet+ _contentsIxml :: ([XL.Content])+ -- "src/Text/Document/Core/Structure.ag"(line 13, column 14)+ _contentsOlevel =+ _lhsIlevel + 1+ -- "src/Text/Document/Core/Structure.ag"(line 37, column 13)+ _contentsOsection =+ 1 : _lhsIsection+ -- "src/Text/Document/Core/Structure.ag"(line 38, column 13)+ _lhsOsection =+ let _:x:xs = _contentsIsection in+ (if _titleIisTitle then (+1) else id)+ x : xs+ -- "src/Text/Document/Printer/Xhtml.ag"(line 73, column 16)+ _lhsOxhtml =+ xhtmlSection _lhsIlevel _lhsIsection _titleIisTitle _titleIxhtml _contentsIxhtml+ -- "src/Text/Document/Printer/Xml.ag"(line 71, column 16)+ _lhsOxml =+ xmlElem "section" (+ _titleIxml +++ _contentsIxml+ )+ -- "src/Text/Document/Printer/Latex.ag"(line 89, column 16)+ _lhsOlatex =+ makeTexSection+ _titleIisTitle+ _titleIlatex+ _lhsIlevel+ _contentsIlatex+ -- "src/Text/Document/Plugin/TOC.ag"(line 15, column 13)+ _lhsOxhtmlTOC =+ let title = H.emph _titleIxhtml+ num = span $ H.text $ intercalate "." $ map show $ reverse $ _lhsIsection+ item = nodeset [title, num]+ f = if _titleIisTitle then (item :) else id in+ [nodeset $ f $ xhtmlCleanList _contentsIxhtmlTOC]+ -- use rule "src/Text/Document/Core/Processing.ag"(line 9, column 20)+ _lhsOprocessors =+ _contentsIprocessors+ -- copy rule (down)+ _contentsOsem =+ _lhsIsem+ ( _titleIisTitle,_titleIlatex,_titleIxhtml,_titleIxml) =+ (title_ )+ ( _contentsIlatex,_contentsIprocessors,_contentsIsection,_contentsIxhtml,_contentsIxhtmlTOC,_contentsIxml) =+ (contents_ _contentsOlevel _contentsOsection _contentsOsem )+ in ( _lhsOlatex,_lhsOprocessors,_lhsOsection,_lhsOxhtml,_lhsOxhtmlTOC,_lhsOxml)))+-- Title -------------------------------------------------------+{-+ visit 0:+ synthesized attributes:+ isTitle : Bool+ latex : ShowS+ xhtml : Node+ xml : [XL.Content]+ alternatives:+ alternative Just:+ child just : Inline + alternative Nothing:+-}+type Title = (Maybe (Inline))+-- cata+sem_Title :: Title ->+ T_Title +sem_Title (Prelude.Just x ) =+ (sem_Title_Just (sem_Inline x ) )+sem_Title Prelude.Nothing =+ sem_Title_Nothing+-- semantic domain+type T_Title = ( Bool,ShowS,Node,([XL.Content]))+data Inh_Title = Inh_Title {}+data Syn_Title = Syn_Title {isTitle_Syn_Title :: Bool,latex_Syn_Title :: ShowS,xhtml_Syn_Title :: Node,xml_Syn_Title :: [XL.Content]}+wrap_Title :: T_Title ->+ Inh_Title ->+ Syn_Title +wrap_Title sem (Inh_Title ) =+ (let ( _lhsOisTitle,_lhsOlatex,_lhsOxhtml,_lhsOxml) =+ (sem )+ in (Syn_Title _lhsOisTitle _lhsOlatex _lhsOxhtml _lhsOxml ))+sem_Title_Just :: T_Inline ->+ T_Title +sem_Title_Just just_ =+ (let _lhsOisTitle :: Bool+ _lhsOxml :: ([XL.Content])+ _lhsOlatex :: ShowS+ _lhsOxhtml :: Node+ _justIlatex :: ShowS+ _justIxhtml :: Node+ _justIxml :: (XL.Content)+ -- "src/Text/Document/Core/Structure.ag"(line 20, column 13)+ _lhsOisTitle =+ True+ -- "src/Text/Document/Printer/Xml.ag"(line 64, column 16)+ _lhsOxml =+ [xmlElem "title" [_justIxml]]+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 73, column 39)+ _lhsOlatex =+ _justIlatex+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 56, column 39)+ _lhsOxhtml =+ _justIxhtml+ ( _justIlatex,_justIxhtml,_justIxml) =+ (just_ )+ in ( _lhsOisTitle,_lhsOlatex,_lhsOxhtml,_lhsOxml))+sem_Title_Nothing :: T_Title +sem_Title_Nothing =+ (let _lhsOisTitle :: Bool+ _lhsOxml :: ([XL.Content])+ _lhsOlatex :: ShowS+ _lhsOxhtml :: Node+ -- "src/Text/Document/Core/Structure.ag"(line 21, column 13)+ _lhsOisTitle =+ False+ -- "src/Text/Document/Printer/Xml.ag"(line 63, column 16)+ _lhsOxml =+ []+ -- use rule "src/Text/Document/Printer/Latex.ag"(line 73, column 39)+ _lhsOlatex =+ id+ -- use rule "src/Text/Document/Printer/Xhtml.ag"(line 56, column 39)+ _lhsOxhtml =+ empty+ in ( _lhsOisTitle,_lhsOlatex,_lhsOxhtml,_lhsOxml))
@@ -0,0 +1,23 @@+module Text.Document.Document (++ -- Parsers.+ fromWiki++ -- Pure printers.+ , toLaTeX+ , toXML+ , toXHTML++ -- IO Printers.+ , processToXHTML+ , processToLaTeX+ , processToXML++ ) where++import Control.Monad++import Text.Document.Core.Type+import Text.Document.Core.Processing+import Text.Document.Parser.Wiki+
@@ -0,0 +1,209 @@+module Text.Document.Parser.Wiki where++import Control.Applicative+import Data.List (intercalate)+import Data.Maybe (isNothing, catMaybes)+import Prelude hiding (lines)+import Text.ParserCombinators.Parsec hiding (many, optional, (<|>))++import Text.Document.Core.Type+import Text.Document.Plugin+import Text.Document.PluginRegister+import Text.Document.Parser.WikiHelper+import Network.Protocol.Uri+import Misc.Commons++-------[ document parsers ]----------------------------------------------------++pDocTitle = string "###" *> (text <$> pNonEmptyLine) <* many pEmptyLineEol+pDocSubtitle = string "####" *> (text <$> pNonEmptyLine) <* many pEmptyLineEol+pAbstract = string "**!" *> many pEmptyLineEol *> (snd <$> pParagraph 0)+pAnnotate = char '@' *> ((,) <$> pString <*> (snd <$> pInline 0))++pDocument = document + <$> pMaybe pDocTitle+ <*> pMaybe pDocSubtitle+ <*> many (try pAnnotate)+ <*> pMaybe (try pAbstract)+ <*> (maybe [] snd <$> pMaybe (pSections 0 False))++parseDocumentFile file = do+ f <- readFile file+ return $ (pDocument @! f)++fromWiki :: String -> Either ParseError Document+fromWiki t = parse pDocument "" (t ++ "\n")++-------[ inline parsers ]------------------------------------------------------++-- TODO: refactor + generalize++-- Several links types.+pWebLink = (\a -> link (show a) External (text $ show a)) <$> pAbsoluteURI++pReference = (\a f -> link a Reference (parseInline (f a)))+ <$> (string "[#" *> many (noneOf "|]")) <*> href <* char ']'+ where href = option id (const <$> (char '|' *> many (noneOf "]")))++pInternalLink = (\a f -> link (f a) Internal (text a)) <$> (char '[' *> many (noneOf "|]")) <*> href <* char ']'+ where href = option id (const <$> (char '|' *> many (noneOf "]")))++pImage = (\a f -> image a (f a)) <$> (char '{' *> many (noneOf "|}")) <*> href <* char '}'+ where href = option id (const <$> (char '|' *> many (noneOf "}")))++-----++pAbbreviations =+ choice+ $ map (\(a, b) -> text b <$ string a) [+ (">>", "»")+ , ("<<", "«")+ , ("...", "…")+ , ("--", "―")+ ]++pCustoms =+ try pWebLink+ <|> try pReference+ <|> try pInternalLink+ <|> try pImage+ <|> try pAbbreviations++inlineTbl = [+ ("*", "*", strong)+ , ("__", "__", footnote)+ , ("_", "_", emph)+ , ("==", "==", quote)+ , ("=", "=", fixed)+ , ("\0", "\0", id)+ ]++-- tricky helper. explain+pFragmentText sym = lines <$> f <$> many (Left <$> pCustoms <|> Right <$> noneOf sym)+ where + f [] = []+ f (Left l:xs) = l : f xs+ f xs = text (map (\(Right x) -> x) a) : f b+ where (a, b) = span right xs++pFragment (s, e, sem) = (sem . lines) <$> (begin *> frags)+ where+ begin = try (string s)+ end = try (string e)+ sym = head s : map (\(_, b, _) -> head b) inlineTbl+ normal = pFragmentText sym+ more = (\a b c -> (text [a] <++> b) : c) <$> oneOf sym <*> normal <*> frags+ sub = (:) <$> pLines <*> frags+ frags = normal <**> option pure (pure <$ end <|> (flip(:)) <$> sub <|> (flip(:)) <$> more)++pLines = choice $ map pFragment inlineTbl++parseInline :: String -> Inline+parseInline xs =+ either (text . show) id+ $ parse pLines "" ('\0' : xs ++ "\0")++pInline :: Level -> GenParser Char st (Int, Inline)+pInline n = fmap2 id (parseInline . trimText) <$> pText n++-------[ structural parsers ]--------------------------------------------------++type Level = Int++pSections :: Level -> Bool -> GenParser Char () (Level, SectionContents)+pSections n forceTitle = do++ -- Based on the `forceTitle' flag we parse or try to parse a title.+ (n', title) <-+ (if forceTitle+ then id+ else option (n, Nothing))+ (try $ pTitle n)++ -- Try to parse another section on level deeper OR another section on the+ -- same level, this section MUST have a title of its own (otherwise it is not+ -- a new section) OR a new block level element.+ items <- some $ choice [+ (Left . snd) <$> pSections (n' + 1) (isNothing title)+ , (Right . snd) <$> pSections n' True+ , (Left . (:[]). Right . snd) <$> pBlock n'+ ]++ let -- Separate all sub-sections from block elements that are ours+ (sub, next) = partitionEither items++ -- Make this section.+ this = section title (concat sub)++ return (n', (Left this) : concat next)++pTitle n = (,)+ <$> (pIndent' n <* string "***")+ <*> (Just . snd <$> pInline 0)++-------[ block parsers ]-------------------------------------------------------++-- Try to parse a single block level element.++-- TODO: These try's should probably be on item indicator level.++pBlock n =+ try (pPlugin n)+ <|> try (pAnchor n)+ <|> try (pCaption n)+ <|> try (pMapping n)+ <|> try (pUnorderedList n)+ <|> try (pOrderedList n)+ <|> (pParagraph n)++{-+Collect all plugins from the global plugin register that claim can parser+Wiki fragments.+-}++pluginParsers = catMaybes $ map (\p -> transformer p Wiki) pluginRegister++pPlugin n = (,) n+ <$> plugin <$> choice (map (\a -> try $ a $ Just (ContextWiki n)) pluginParsers)+ <* many pEmptyLineEol++pAnchor n = do+ n' <- pIndent' n+ string "#anchor "+ l <- pNonEmptyLine+ (_, b) <- pBlock n'+ return $ (n', anchor_ l b)++pCaption n = do+ n' <- pIndent' n+ string "#caption "+ (_, i) <- pInline 0+ (_, b) <- pBlock n'+ return $ (n', caption i b)++pParagraph n = fmap2 id paragraph <$> pInline n++-- List parsers.++pMapping = pList mapping (pMapItem "--" "->")+pUnorderedList = pList list (pListItem "-")+pOrderedList = pList enum (pListItem "+")++pList sem item n = do+ (n', x) <- item n+ xs <- map snd <$> many (try $ item n')+ return (n', sem (x:xs))++pListItem c n = do+ n' <- pIndent' n+ i <- string c+ *> ((\a b -> blocks (a : b))+ <$> (snd <$> pBlock 0)+ <*> (map snd <$> many (pBlock (n'+1))))+ return (n', i)++pMapItem c0 c1 n = do+ (n', a) <- pListItem c0 n+ (_, b) <- pListItem c1 n+ return (n', (a, b))+
@@ -0,0 +1,85 @@+module Text.Document.Parser.WikiHelper where++import Control.Applicative+import Data.List (intercalate)+import Text.ParserCombinators.Parsec hiding (many, optional, (<|>))++import Network.Protocol.Uri+import Misc.Commons++-------[ helpers ]-------------------------------------------------------------++{-+Helper function that trims all empty lines from the top and bottom of a text+fragment and removes trailing whitespace and the biggest square block of+heading whitespace.+-}++trimCode txt = + let+ mi = minimum $ map (length . takeWhile ws) ne+ ne = filter (not . em) ls+ em = all ws+ ws = (`elem` "\t ")+ ls = lines txt+ tl = withReverse (dropWhile ws)+ in intercalate "\n"+ $ trimWith em+ $ map (drop mi)+ $ map tl ls++trimText txt = + let+ ws = (`elem` "\t ")+ tl = withReverse (dropWhile ws)+ in intercalate "\n"+ $ trimWith (all ws)+ $ map trim+ $ lines txt++-------[ parsers ]-------------------------------------------------------------++eols = "\r\n"+ws = "\t "+wss = ws ++ eols++-- Parse end of line, \r\n or \n.+pEol = snoc <$> option "" (string "\r") <*> char '\n'++-- Parse a chunk of whitespace, no line endings.+pSpace = many $ oneOf ws++-- Try to parse at least level n indentation.+pIndent n = do+ h <- try (many pEmptyLineEol)+ i <- try (pMin n (oneOf ws))+ return (length i, concat h ++ i) -- (\a -> (length a, a)) <$> ++pIndent' n = fst <$> pIndent n++-- Parse an empty line including the line ending.+pEmptyLineEol = try ((++) <$> many (oneOf ws) <*> pEol)++-- Parse a non empty line excluding the EOL character. +pNonEmptyLine = (++) <$> many (oneOf ws) <*> ((:) <$> noneOf wss <*> many (noneOf eols))++-- Parse a non empty line including the line ending.+pNonEmptyLineEol = (++) <$> pNonEmptyLine <*> (pEol <|> ("" <$ eof))++-- A string identifier not containing any whitespace.+pString = many $ noneOf wss++-- Parse a block of text terminated by an empty line.+-- todo: include ident space and reuse this function in pLevel.++pText :: Int -> GenParser Char st (Int, String)+pText n = do+ h <- many pEmptyLineEol+ (m, i) <- pIndent n+ b <- many1 (try pNonEmptyLineEol)+ f <- many pEmptyLineEol+ return (m, concat (h ++ (i:b) ++ f))++-- Parse a block of text terminated by an empty line.+pLevel n = concat . map snd <$> many (pText n)+
@@ -0,0 +1,133 @@+module Text.Document.Plugin where++import Control.Monad (liftM)+import Control.Applicative ((<$>))+import Text.ParserCombinators.Parsec (GenParser)+import qualified Text.XML.Light as XL++import Text.Xml.Xml (Node)+import Misc.Commons (branch, fmap2)++{-+List of formats currently supported for both the parser and the pretty printer+side. Plugins for every format plugins might support parsing or printing.+-}++data Format =+ Wiki+ | XML+ | XHTML+ | LaTeX+ | ADT+ deriving (Eq, Show)++{-+Instead of only allowing text pretty printing for plugins a more flexible+Output type is used. This type should allow plugins to be more precise in their+output domain. E.g. XML/Xhtml pretty printer can simply out XML nodes and do+not have to worry about conversion to strings.+-}++data Output = + OutputPlain String+ | OutputXML Node -- Do not use internal nodes.+ | OutputXMLLight XL.Content++data Context = ContextWiki Int+ deriving (Eq, Show)++{-+A plugin contains an identifying name and a transformation function. This+transformation function is indexed by a format identifier and might deliver a+parser for that format. The parse result is a pretty printer function indexed+by a format identifier as well, Given this format the function might deliver a+pretty printed string in that format. Due to these two `Maybe' types the plugin+may support any of the possible combinations of parsing and pretty printing for+arbitrary types.++Because the pretty printer will eventually end up in the document tree, it has+the plugin name included. This way the plugins can easily be identified,+compared or used for error reporting.++Non-pure function can make use of the processor computation that receives a+filepath they can use as a working directory. A bit clumsy, but that's the+burden of purity.+-}++type Parser doc = Format -> Maybe (Maybe Context -> GenParser Char () doc)++data PrettyPrinter doc =+ Printer {+ printerName :: String+ , printer :: Format -> Maybe (doc -> Output)+ }++data Processor doc sem =+ Processor {+ processorName :: String+ , processor :: Format -> Maybe (FilePath -> doc -> sem -> IO ())+ }++type Transformer doc sem = Parser (PrettyPrinter doc, Processor doc sem)++data Plugin doc sem =+ Plugin {+ pluginName :: String+ , transformer :: Transformer doc sem+ }++{-+Plugins are only showable and comparable using there (hopefully) uniquely+identifying name.+-}++instance Eq (PrettyPrinter doc) where+ a == b = printerName a == printerName b++instance Eq (Processor doc sem) where+ a == b = processorName a == processorName b++{-+When a plugin support a pretty printer for the ADT format that produces a plain+string as output, this printer will be used as the show instance for this+plugin.+-}++instance Show (Processor doc sem) where+ show = processorName++instance Show (PrettyPrinter doc) where+ show = printerName++instance Eq (Plugin doc sem) where+ a == b = pluginName a == pluginName b++instance Show (Plugin doc sem) where+ show = pluginName++-------- plugin helper functions ----------------------------------------------++{-+Create a plugin transformer function from both a mapping from format+identifiers to general parsers and a mapping from format identifiers to pretty+printers. The pretty printers should take the result of the parsers.+-}++-- FIX:++makePlugin :: + String+ -> [(Format, Maybe Context -> GenParser Char () int)]+ -> [(Format, int -> doc -> Output)]+ -> [(Format, int -> FilePath -> doc -> sem -> IO ())]+ -> Plugin doc sem++makePlugin name ps pps ios = Plugin name $ \fmt -> do+ fmtParser <- lookup fmt ps+ let printer int fmt' = lookup fmt' pps >>= return . ($int)+ let processor int fmt' = lookup fmt' ios >>= return . ($int)+ return (\a -> + fmap2 (Printer name) (Processor name)+ <$> branch printer processor+ <$> fmtParser a)+
@@ -0,0 +1,109 @@+module Text.Document.Plugin.Formula (formulaPlugin) where++import Control.Applicative++#if (__GLASGOW_HASKELL__ < 609)+import Control.Exception hiding (IOException)+#else+import Control.Exception+#endif++import Control.Monad (when)+import Data.Char (ord)+import Data.Digest.OpenSSL.MD5 (md5sum)+import Data.ByteString (pack)+import Data.List (intercalate)+import System.IO+import System.IO.Unsafe+import System.Posix.Files (getFileStatus, isRegularFile)+import System.Process (runInteractiveProcess, waitForProcess, runProcess)+import Text.ParserCombinators.Parsec hiding (many, optional, (<|>), try)++import Network.Protocol.Uri ((/+))+import Text.Document.Parser.WikiHelper+import Text.Document.Core.Type+import Text.Document.Plugin+import Misc.Commons (trim)+import qualified Text.Xhtml.Xhtml as H+import qualified Text.Xml.Xml as X++#if (__GLASGOW_HASKELL__ < 609)+type IOException = Exception+#endif++-------- hscolour plugin ------------------------------------------------------++formulaPlugin :: Plugin Document Syn_Document+formulaPlugin = makePlugin "formula"+ [(Wiki, pFormula)]+ [(XHTML, ppXHTML), (LaTeX, ppCodeLaTeX), (ADT, ppADT)]+ [(XHTML, ioXHTML)]++-------- parsers --------------------------------------------------------------++pFormula (Just (ContextWiki n)) = do+ (m, i) <- pIndent n+ (string "@@" <* many (oneOf ws) <* string "formula")+ *> many pEmptyLineEol+ *> (trimCode+ <$> pLevel (m + 1))++-------- pretty printers ------------------------------------------------------++ppXHTML formula doc = OutputXML+ $ X.attribute "class" "formula"+ $ H.img ("_images" /+ generateFileName formula) "formula"++generateFileName :: String -> String+generateFileName formula = md5sum (pack $ map (fromIntegral . ord) formula) ++ ".png"++-------- processors -----------------------------------------------------------++ioXHTML :: String -> FilePath -> Document -> Syn_Document -> IO ()+ioXHTML formula workDir doc sem = do++ let image = generateFileName formula++ exist <- try (isRegularFile <$> getFileStatus (workDir /+ image)) :: IO (Either IOException Bool)+ case exist of+ Right True -> return ()+ Left _ -> do++ -- Save formula pulled through template as tex file.+ writeFile ("/tmp/tex-formula-" ++ image++ ".tex") (texTemplate formula)++ -- Create DVI file from tex.+ runProcess "latex" [+ "-interaction=nonstopmode"+ , "/tmp/tex-formula-" ++ image ++ ".tex"+ ] (Just "/tmp") Nothing Nothing Nothing Nothing+ >>= waitForProcess++ -- Convert DVI file to PNG image.+ runProcess "dvipng" [+ "-q", "-T", "tight", "-bg", "Transparent"+ , "-D", "180", "/tmp/tex-formula-" ++ image ++ ".dvi"+ , "-o", workDir /+ "_images" /+ image+ ] Nothing Nothing Nothing Nothing Nothing+ >>= waitForProcess+ return ()++ppCodeLaTeX s doc = OutputPlain s++ppADT s doc = OutputPlain $ show s++texTemplate :: String -> String+texTemplate s = concat [header, s, footer]+ where+ header = intercalate "\n" [+ "\\documentclass[fleqn]{article}"+ , "\\usepackage{amssymb,amsmath,bm,color}"+ , "\\usepackage[utf8]{inputenc}"+ , "\\begin{document}"+ , "\\thispagestyle{empty}"+ , "\\mathindent0cm"+ , "\\parindent0cm"+ , ""+ ]+ footer = "\n\\end{document}"+
@@ -0,0 +1,64 @@+module Text.Document.Plugin.HsColour (hscolourPlugin) where++import Control.Applicative+import Text.ParserCombinators.Parsec hiding (many, optional, (<|>))+import qualified Language.Haskell.HsColour.Colourise as C+import qualified Language.Haskell.HsColour.ColourHighlight as H+import qualified Language.Haskell.HsColour.CSS as HscCSS+import qualified Language.Haskell.HsColour.LaTeX as HscTeX++import Text.Document.Parser.WikiHelper+import Text.Document.Core.Type+import Text.Document.Plugin+import qualified Text.Xhtml.Xhtml as H+import qualified Text.Xml.Xml as X++-------- hscolour plugin ------------------------------------------------------++hscolourPlugin :: Plugin Document Syn_Document+hscolourPlugin = makePlugin "hscolour" + [(Wiki, pWiki)]+ [(XHTML, ppXHTML), (LaTeX, ppLaTeX), (ADT, ppADT)]+ []++-------- parsers --------------------------------------------------------------++pWiki (Just (ContextWiki n)) = do+ (m, i) <- pIndent n+ (string "@@" <* many (oneOf ws) <* string "haskell")+ *> many pEmptyLineEol+ *> (trimCode+ <$> pLevel (m + 1))++-------- pretty printers ------------------------------------------------------++ppXHTML s doc = OutputXML $ X.snippet $ HscCSS.hscolour False True "" s++ppLaTeX s doc = OutputPlain+ $ "\\begin{verbatim}\n" ++ s ++ "\n\\end{verbatim}\n"++{-+ppLaTeX s = OutputPlain+ $ HscTeX.hscolour texColourPrefs True s++texColourPrefs = C.ColourPrefs {+ C.keyword = [H.Normal]+ , C.keyglyph = [H.Normal]+ , C.layout = [H.Normal]+ , C.comment = [H.Normal]+ , C.conid = [H.Normal]+ , C.varid = [H.Normal]+ , C.conop = [H.Normal]+ , C.varop = [H.Normal]+ , C.string = [H.Normal]+ , C.char = [H.Normal]+ , C.number = [H.Normal]+ , C.cpp = [H.Normal]+ , C.selection = [H.Normal]+ , C.variantselection = [H.Normal]+ , C.definition = [H.Normal]+ }+-}++ppADT s doc = OutputPlain $ show doc+
@@ -0,0 +1,37 @@+module Text.Document.Plugin.TOC (tocPlugin) where++import Control.Applicative+import Text.ParserCombinators.Parsec hiding (many, optional, (<|>))++import Text.Document.Core.Type+import Text.Document.Plugin+import Text.Document.Parser.WikiHelper+import qualified Text.Xhtml.Xhtml as H+import qualified Text.Xml.Xml as X++-------- table of contents plugin ---------------------------------------------++tocPlugin :: Plugin Document Syn_Document+tocPlugin = makePlugin "toc"+ [(Wiki, pTOC)]+ [(XHTML, ppXHTML), (LaTeX, ppCodeLaTeX), (ADT, ppADT)]+ []++-------- parser(s) ------------------------------------------------------------++pTOC (Just (ContextWiki n)) = do+ (m, i) <- pIndent n+ (string "@@" <* many (oneOf ws) <* string "toc") *> many pEmptyLineEol++-------- pretty printer(s) ----------------------------------------------------++ppXHTML _ doc = OutputXML+ $ H.classDiv "toc"+ $ X.nodeset+ $ (H.h2 $ H.text "Contents")+ : documentToXhtmlTOC doc++ppCodeLaTeX s doc = OutputPlain "\\pagebreak\n\\tableofcontents\n\\pagebreak\n"++ppADT _ doc = OutputPlain "ERROR"+
@@ -0,0 +1,16 @@+module Text.Document.PluginRegister (pluginRegister) where++import Text.Document.Plugin+import Text.Document.Core.Type++import Text.Document.Plugin.HsColour+import Text.Document.Plugin.Formula+import Text.Document.Plugin.TOC++pluginRegister :: [Plugin Document Syn_Document]+pluginRegister = [+ formulaPlugin+ , hscolourPlugin+ , tocPlugin+ ]+
@@ -0,0 +1,67 @@+module Text.Xhtml.Xhtml where++import Prelude hiding (head, div, span)++import Text.Xml.Xml hiding (text)+import qualified Text.Xml.Xml++-------[ XHTML shortcuts ]-----------------------------------------------------++-- Document structure elements.++document t b = html $ nodeset [head (title t), body b]++html = doc . element "html"+head = element "head"+title = element "title" . text+body = element "body"++-- Title elements.++h1 = element "h1"+h2 = element "h2"+h3 = element "h3"+h4 = element "h4"+h5 = element "h5"+h6 = element "h5"+header i = element ("h" ++ show i)++-- Block level elements.++div = element "div"+pre = element "pre"+par = element "p"+input = element "input"+ul = element "ul" . nodeset . map (element "li")+ol = element "ol" . nodeset . map (element "li")+dlterm = element "dt"+dldef = element "df"+dl = element "dl" . nodeset . concat . map (\(k, v) -> [element "dt" k, element "dd" v])++-- Inline elements.++text = Text.Xml.Xml.text+span = element "span"+img s a = attribute "src" s $ attribute "alt" a $ element "img" $ text ""+anchor h = attribute "href" h . element "a"+link h = anchor h . text+emph = element "em"+strong = element "strong"+tt = element "tt"+dfn = element "dfn"+code = element "code"+cite = element "cite"+hr = element "hr" $ nodeset []++-- Shortcuts for custom elements using classes.++withClass c e = attribute "class" c . e++classDiv = flip withClass div +classSpan = flip withClass span++withName n e = attribute "name" n . e++nameDiv = flip withName div+nameSpan = flip withName span+
@@ -0,0 +1,375 @@+++-- UUAGC 0.9.7 (src/Text/Xml/Xml.ag)+module Text.Xml.Xml where++import Misc.Commons (ss)++type Namespace = String+type Comment = String+type Text = String+type NodePair = (Node, Node)+type NodeMap = [NodePair]+++doc = Node_Doc+text = Node_Text+comment = Node_Comment+nodeset = Node_NodeSet+snippet = Node_Snippet+empty = Node_Empty++elementNS ns e = Node_Element ns e []+element = elementNS ""++attributeNS ns k v (Node_Element n' e a s) = Node_Element n' e ((Attribute_Attribute ns k v):a) s+attribute = attributeNS ""++-- Determine whether an XML node has significant data.+significant (Node_NodeSet []) = False+significant (Node_Text "") = False+significant (Node_Comment "") = False+significant (Node_Empty ) = False+significant _ = True++++ -- todo: use utils.+ppNodeset [] _ = id+ppNodeset [n] mixed = n+ppNodeset ns mixed = c . foldl1 (\a -> ((a.c).)) ns . c+ where c = if mixed then id else ss "\n"++ppNs "" = ss ""+ppNs ns = ss (ns ++ ":")++-- Escape special characters in text that will end up in an XML document.+escape :: String -> String+escape [] = []+escape ('<':xs) = "<" ++ escape xs+escape ('>':xs) = ">" ++ escape xs+escape ('&':xs) = "&" ++ escape xs+escape ('"':xs) = """ ++ escape xs+escape (x:xs) = x : escape xs++++wrappedSemNode = flip (wrap_Node . sem_Node) Inh_Node++instance Show Node where+ show = xmlToString++xmlToString :: Node -> String+xmlToString = ($"") . pp_Syn_Node . wrappedSemNode+-- Attribute ---------------------------------------------------+{-+ visit 0:+ synthesized attribute:+ pp : ShowS+ alternatives:+ alternative Attribute:+ child namespace : {Namespace}+ child key : {String}+ child value : {String}+-}+data Attribute = Attribute_Attribute (Namespace) (String) (String) + deriving ( Eq)+-- cata+sem_Attribute :: Attribute ->+ T_Attribute +sem_Attribute (Attribute_Attribute _namespace _key _value ) =+ (sem_Attribute_Attribute _namespace _key _value )+-- semantic domain+type T_Attribute = ( ShowS)+data Inh_Attribute = Inh_Attribute {}+data Syn_Attribute = Syn_Attribute {pp_Syn_Attribute :: ShowS}+wrap_Attribute :: T_Attribute ->+ Inh_Attribute ->+ Syn_Attribute +wrap_Attribute sem (Inh_Attribute ) =+ (let ( _lhsOpp) =+ (sem )+ in (Syn_Attribute _lhsOpp ))+sem_Attribute_Attribute :: Namespace ->+ String ->+ String ->+ T_Attribute +sem_Attribute_Attribute namespace_ key_ value_ =+ (let _lhsOpp :: ShowS+ -- "src/Text/Xml/Xml.ag"(line 105, column 15)+ _lhsOpp =+ ppNs namespace_ . ss key_ . ss "=\"" . ss (escape value_) . ss "\""+ in ( _lhsOpp))+-- Attributes --------------------------------------------------+{-+ visit 0:+ synthesized attribute:+ pp : ShowS+ alternatives:+ alternative Cons:+ child hd : Attribute + child tl : Attributes + alternative Nil:+-}+type Attributes = [(Attribute)]+-- cata+sem_Attributes :: Attributes ->+ T_Attributes +sem_Attributes list =+ (Prelude.foldr sem_Attributes_Cons sem_Attributes_Nil (Prelude.map sem_Attribute list) )+-- semantic domain+type T_Attributes = ( ShowS)+data Inh_Attributes = Inh_Attributes {}+data Syn_Attributes = Syn_Attributes {pp_Syn_Attributes :: ShowS}+wrap_Attributes :: T_Attributes ->+ Inh_Attributes ->+ Syn_Attributes +wrap_Attributes sem (Inh_Attributes ) =+ (let ( _lhsOpp) =+ (sem )+ in (Syn_Attributes _lhsOpp ))+sem_Attributes_Cons :: T_Attribute ->+ T_Attributes ->+ T_Attributes +sem_Attributes_Cons hd_ tl_ =+ (let _lhsOpp :: ShowS+ _hdIpp :: ShowS+ _tlIpp :: ShowS+ -- "src/Text/Xml/Xml.ag"(line 108, column 15)+ _lhsOpp =+ ss " " . _hdIpp . _tlIpp+ ( _hdIpp) =+ (hd_ )+ ( _tlIpp) =+ (tl_ )+ in ( _lhsOpp))+sem_Attributes_Nil :: T_Attributes +sem_Attributes_Nil =+ (let _lhsOpp :: ShowS+ -- use rule "src/Text/Xml/Xml.ag"(line 93, column 41)+ _lhsOpp =+ id+ in ( _lhsOpp))+-- Node --------------------------------------------------------+{-+ visit 0:+ synthesized attributes:+ mixed : Bool+ pp : ShowS+ alternatives:+ alternative Comment:+ child comment : {Comment}+ alternative Doc:+ child root : Node + alternative Element:+ child namespace : {Namespace}+ child name : {String}+ child attributes : Attributes + child childNodes : Node + alternative Empty:+ alternative NodeSet:+ child nodes : NodeSet + alternative Snippet:+ child snippet : {String}+ alternative Text:+ child text : {Text}+-}+data Node = Node_Comment (Comment) + | Node_Doc (Node) + | Node_Element (Namespace) (String) (Attributes) (Node) + | Node_Empty + | Node_NodeSet (NodeSet) + | Node_Snippet (String) + | Node_Text (Text) + deriving ( Eq)+-- cata+sem_Node :: Node ->+ T_Node +sem_Node (Node_Comment _comment ) =+ (sem_Node_Comment _comment )+sem_Node (Node_Doc _root ) =+ (sem_Node_Doc (sem_Node _root ) )+sem_Node (Node_Element _namespace _name _attributes _childNodes ) =+ (sem_Node_Element _namespace _name (sem_Attributes _attributes ) (sem_Node _childNodes ) )+sem_Node (Node_Empty ) =+ (sem_Node_Empty )+sem_Node (Node_NodeSet _nodes ) =+ (sem_Node_NodeSet (sem_NodeSet _nodes ) )+sem_Node (Node_Snippet _snippet ) =+ (sem_Node_Snippet _snippet )+sem_Node (Node_Text _text ) =+ (sem_Node_Text _text )+-- semantic domain+type T_Node = ( Bool,ShowS)+data Inh_Node = Inh_Node {}+data Syn_Node = Syn_Node {mixed_Syn_Node :: Bool,pp_Syn_Node :: ShowS}+wrap_Node :: T_Node ->+ Inh_Node ->+ Syn_Node +wrap_Node sem (Inh_Node ) =+ (let ( _lhsOmixed,_lhsOpp) =+ (sem )+ in (Syn_Node _lhsOmixed _lhsOpp ))+sem_Node_Comment :: Comment ->+ T_Node +sem_Node_Comment comment_ =+ (let _lhsOpp :: ShowS+ _lhsOmixed :: Bool+ -- "src/Text/Xml/Xml.ag"(line 102, column 15)+ _lhsOpp =+ ss "<!-- " . ss (escape comment_) . ss " -->"+ -- use rule "src/Text/Xml/Xml.ag"(line 64, column 31)+ _lhsOmixed =+ False+ in ( _lhsOmixed,_lhsOpp))+sem_Node_Doc :: T_Node ->+ T_Node +sem_Node_Doc root_ =+ (let _lhsOmixed :: Bool+ _lhsOpp :: ShowS+ _rootImixed :: Bool+ _rootIpp :: ShowS+ -- use rule "src/Text/Xml/Xml.ag"(line 64, column 31)+ _lhsOmixed =+ _rootImixed+ -- use rule "src/Text/Xml/Xml.ag"(line 93, column 41)+ _lhsOpp =+ _rootIpp+ ( _rootImixed,_rootIpp) =+ (root_ )+ in ( _lhsOmixed,_lhsOpp))+sem_Node_Element :: Namespace ->+ String ->+ T_Attributes ->+ T_Node ->+ T_Node +sem_Node_Element namespace_ name_ attributes_ childNodes_ =+ (let _lhsOmixed :: Bool+ _lhsOpp :: ShowS+ _attributesIpp :: ShowS+ _childNodesImixed :: Bool+ _childNodesIpp :: ShowS+ -- "src/Text/Xml/Xml.ag"(line 68, column 13)+ _lhsOmixed =+ False+ -- "src/Text/Xml/Xml.ag"(line 98, column 15)+ _lhsOpp =+ ss "<" . ppNs namespace_ . ss name_ . _attributesIpp . ss ">" .+ _childNodesIpp . ss "</" . ss name_ . ss ">"+ ( _attributesIpp) =+ (attributes_ )+ ( _childNodesImixed,_childNodesIpp) =+ (childNodes_ )+ in ( _lhsOmixed,_lhsOpp))+sem_Node_Empty :: T_Node +sem_Node_Empty =+ (let _lhsOmixed :: Bool+ _lhsOpp :: ShowS+ -- use rule "src/Text/Xml/Xml.ag"(line 64, column 31)+ _lhsOmixed =+ False+ -- use rule "src/Text/Xml/Xml.ag"(line 93, column 41)+ _lhsOpp =+ id+ in ( _lhsOmixed,_lhsOpp))+sem_Node_NodeSet :: T_NodeSet ->+ T_Node +sem_Node_NodeSet nodes_ =+ (let _lhsOpp :: ShowS+ _lhsOmixed :: Bool+ _nodesImixed :: Bool+ _nodesIpp :: ([ShowS])+ -- "src/Text/Xml/Xml.ag"(line 97, column 15)+ _lhsOpp =+ ppNodeset _nodesIpp _nodesImixed+ -- use rule "src/Text/Xml/Xml.ag"(line 64, column 31)+ _lhsOmixed =+ _nodesImixed+ ( _nodesImixed,_nodesIpp) =+ (nodes_ )+ in ( _lhsOmixed,_lhsOpp))+sem_Node_Snippet :: String ->+ T_Node +sem_Node_Snippet snippet_ =+ (let _lhsOpp :: ShowS+ _lhsOmixed :: Bool+ -- "src/Text/Xml/Xml.ag"(line 101, column 15)+ _lhsOpp =+ ss snippet_+ -- use rule "src/Text/Xml/Xml.ag"(line 64, column 31)+ _lhsOmixed =+ False+ in ( _lhsOmixed,_lhsOpp))+sem_Node_Text :: Text ->+ T_Node +sem_Node_Text text_ =+ (let _lhsOmixed :: Bool+ _lhsOpp :: ShowS+ -- "src/Text/Xml/Xml.ag"(line 67, column 13)+ _lhsOmixed =+ True+ -- "src/Text/Xml/Xml.ag"(line 100, column 15)+ _lhsOpp =+ ss (escape text_)+ in ( _lhsOmixed,_lhsOpp))+-- NodeSet -----------------------------------------------------+{-+ visit 0:+ synthesized attributes:+ mixed : Bool+ pp : [ShowS]+ alternatives:+ alternative Cons:+ child hd : Node + child tl : NodeSet + alternative Nil:+-}+type NodeSet = [(Node)]+-- cata+sem_NodeSet :: NodeSet ->+ T_NodeSet +sem_NodeSet list =+ (Prelude.foldr sem_NodeSet_Cons sem_NodeSet_Nil (Prelude.map sem_Node list) )+-- semantic domain+type T_NodeSet = ( Bool,([ShowS]))+data Inh_NodeSet = Inh_NodeSet {}+data Syn_NodeSet = Syn_NodeSet {mixed_Syn_NodeSet :: Bool,pp_Syn_NodeSet :: [ShowS]}+wrap_NodeSet :: T_NodeSet ->+ Inh_NodeSet ->+ Syn_NodeSet +wrap_NodeSet sem (Inh_NodeSet ) =+ (let ( _lhsOmixed,_lhsOpp) =+ (sem )+ in (Syn_NodeSet _lhsOmixed _lhsOpp ))+sem_NodeSet_Cons :: T_Node ->+ T_NodeSet ->+ T_NodeSet +sem_NodeSet_Cons hd_ tl_ =+ (let _lhsOmixed :: Bool+ _lhsOpp :: ([ShowS])+ _hdImixed :: Bool+ _hdIpp :: ShowS+ _tlImixed :: Bool+ _tlIpp :: ([ShowS])+ -- use rule "src/Text/Xml/Xml.ag"(line 64, column 31)+ _lhsOmixed =+ _hdImixed || _tlImixed+ -- use rule "src/Text/Xml/Xml.ag"(line 94, column 41)+ _lhsOpp =+ _hdIpp : _tlIpp+ ( _hdImixed,_hdIpp) =+ (hd_ )+ ( _tlImixed,_tlIpp) =+ (tl_ )+ in ( _lhsOmixed,_lhsOpp))+sem_NodeSet_Nil :: T_NodeSet +sem_NodeSet_Nil =+ (let _lhsOmixed :: Bool+ _lhsOpp :: ([ShowS])+ -- use rule "src/Text/Xml/Xml.ag"(line 64, column 31)+ _lhsOmixed =+ False+ -- use rule "src/Text/Xml/Xml.ag"(line 94, column 41)+ _lhsOpp =+ []+ in ( _lhsOmixed,_lhsOpp))
binary file changed (absent → 356 bytes)
binary file changed (absent → 673 bytes)
binary file changed (absent → 3369 bytes)
binary file changed (absent → 3531 bytes)
binary file changed (absent → 3066 bytes)
binary file changed (absent → 3602 bytes)
binary file changed (absent → 3612 bytes)
binary file changed (absent → 3598 bytes)
binary file changed (absent → 3723 bytes)
binary file changed (absent → 2938 bytes)
binary file changed (absent → 2942 bytes)
binary file changed (absent → 3584 bytes)
binary file changed (absent → 3707 bytes)
binary file changed (absent → 3380 bytes)
binary file changed (absent → 3500 bytes)
binary file changed (absent → 3068 bytes)
binary file changed (absent → 3579 bytes)
binary file changed (absent → 3513 bytes)
binary file changed (absent → 2831 bytes)
binary file changed (absent → 7955 bytes)
@@ -0,0 +1,501 @@+/* ------------------------------------------------------------------------- */++$(document).ready( + function start ()+ {+ setupLoadingIcon()+ installCollapsers()+ installOptions()+ installSmartFields()+ installHandlers()+ index()+ setupBrowserHistory()+ updateAuth()+ }+)++function index ()+{+ // When no document is requested using the resource hash, open the index+ // document by default.+ if (!document.location.hash)+ document.location.hash = 'Index'+}++function setupBrowserHistory ()+{+ // History changes are reflected using the parseURI/update functions.+ $.history.init(+ function historyChange (hash)+ {+ parseURI()+ update()+ }+ )+}++function setupLoadingIcon ()+{+ $("#loading").ajaxStart(+ function ()+ {+ $(this).show();+ }+ );+ $("#loading").ajaxStop(+ function ()+ {+ $(this).hide();+ }+ ); +}++function installHandlers ()+{+ $('#history-btn').click(showHistory)+ $('#edit-btn').click(showEditor)+ $('#login-btn').click(login)+ $('#logout-btn').click(logout)+ $('#create-account-btn').click(signup)+ $('#save-btn').click(save)+ $('#preview-btn').click(preview)+ $('#delete-btn').click(_delete)+}++/* ------------------------------------------------------------------------- */++// Current application state.++Wiki = {++ // Static information.+ prefix : 'data/'+ , previewURI : 'data/preview'+ , loginURI : 'login'+ , logoutURI : 'logout'+ , loginfoURI : 'loginfo'+ , signupURI : 'signup'+ , viewerURI : '#'++ // State information.+ , title : ''+ , ext : 'html'+ , rev : ''+ , anchor : ''++ , prevTitle : ''+ , prevExt : ''+ , prevRev : ''+ , prevAnchor : ''++ , author : ''+ , user : ''+}++function parseURI ()+{+ var hash = window.location.hash+ var parse = hash.match(/^#([^?#]*)\??([^#]*)#?(.*)/)++ var ext = parse[1].match(/\.([^.]*)$/)+ var tit = parse[1].match(/(.*)\.([^.]*)$/)++ Wiki.prevTitle = Wiki.title+ Wiki.prevExt = Wiki.ext+ Wiki.prevRev = Wiki.rev+ Wiki.prevAnchor = Wiki.anchor++ Wiki.title = tit ? tit[1] : parse[1]+ Wiki.ext = ext ? ext[1] : 'html'+ Wiki.rev = parse[2]+ Wiki.anchor = parse[3]+}++function update ()+{+ var t = 0++ // Only refresh when one of these change.+ if (Wiki.title != Wiki.prevTitle ||+ Wiki.ext != Wiki.prevExt ||+ Wiki.rev != Wiki.prevRev) {++ // Update information bar.+ $('#document').html(Wiki.title)+ $('#revision').html(Wiki.rev || '<i>head revision</i>')+ $('#user').html(Wiki.user)++ show()+ showHistory()+ updateAuth()++ // Anchor focus delay when refreshing.+ t = 1000+ }++ if (Wiki.anchor)+ setTimeout(+ function ()+ {+ followAnchor(Wiki.anchor)+ }, t+ )+}++function makeURI (prefix, title, ext, rev, anchor)+{+ var p = prefix === undefined ? Wiki.prefix : prefix+ var t = title === undefined ? Wiki.title : title+ var e = ext === undefined ? Wiki.ext : ext+ var r = rev === undefined ? Wiki.rev : rev+ var a = anchor === undefined ? Wiki.anchor : anchor+ return p + t+ + (e ? '.' + e : '')+ + (r ? '?' + r : '')+ + (a ? '#' + a : '')+}++function makeURIExt (ext)+{+ return makeURI(undefined, undefined, ext)+}++/* ---- showing documents -------------------------------------------------- */++function viewerHTML (txt)+{+ if (Wiki.ext == 'html') {+ $('#plain-viewer').hide()+ $('#plain-viewer').html('')+ $('#rich-viewer').show()+ $('#rich-viewer').html(txt)+ } else {+ $('#rich-viewer').hide()+ $('#rich-viewer').html('')+ $('#plain-viewer').show()+ $('#plain-viewer').html(txt)+ }+}++function setExternalLinks ()+{+ $('#txt-btn'). attr('href', makeURI(Wiki.viewerURI, undefined, 'txt'))+ $('#html-btn'). attr('href', makeURI(Wiki.viewerURI, undefined, 'html'))+ $('#latex-btn'). attr('href', makeURI(Wiki.viewerURI, undefined, 'tex'))+ $('#adt-btn'). attr('href', makeURI(Wiki.viewerURI, undefined, 'hs'))+ $('#pdf-btn'). attr('href', makeURIExt('pdf'))+ $('#print-btn'). attr('href', makeURIExt('html'))+ $('#src-btn'). attr('href', makeURIExt('txt'))+}++function show ()+{+ $.get(+ makeURIExt(Wiki.ext)+ , ''++ // Showing existing document:+ , function (res)+ {+ viewerHTML(res)+ $('#history-btn').removeClass('disabled')+ processLinks()+ processImages()+ setExternalLinks()+ }+ , ''++ // `Showing' non-existing document:+ , function ()+ {+ viewerHTML('new document, click <strong>edit</strong> to start editing')+ $('#history-btn').addClass('disabled')+ showEditor() //todo+ }+ )+}++function processLinks ()+{+ $(".Internal").each(+ function ()+ {+ var href = this.getAttribute('href')+ if (!href.match(/:/))+ this.setAttribute('href', '#' + href)+ }+ )++ $(".Reference").each(+ function ()+ {+ $(this).attr('href', makeURI(Wiki.viewerURI, undefined, undefined, undefined, $(this).attr('href').substring(1)))+ }+ )+}++function processImages ()+{+ $("img").each(+ function ()+ {+ var src = this.getAttribute('src')+ this.setAttribute('src', src.replace(/^_/, 'data/_'))+ }+ )+}++function followAnchor (ref)+{+ var target = $('*[name=' + ref + ']')[0]+ target.scrollIntoView()++ setTimeout(+ function ()+ {+ focusElement(target)+ }, 0)+}++function focusElement (target)+{+ var div = document.createElement('div')+ document.body.appendChild(div)+ var bcr = target.getBoundingClientRect()+ div.style.left = bcr.left+ div.style.top = bcr.top+ div.style.width = target.clientWidth+ div.style.height = target.clientHeight+ $(div).addClass('find')+ $(div).fadeOut('slow')+}++/* ---- authentication bar ------------------------------------------------- */++function login ()+{+ if ($('#login-btn').hasClass('disabled'))+ return;++ $.post(+ Wiki.loginURI+ , { username : $('#username').val()+ , password : $('#password').val()+ } + , function ()+ {+ $('#login-status').removeClass('error')+ $('#login-status').html('login successful')+ panelClose($('#auth-btn'), $('#auth'))+ updateAuth()+ }+ , ''+ , function (e)+ {+ $('#login-status').addClass('error')+ $('#login-status').html('login failed: <span>' + e.responseText + '</span>')+ }+ )+}++function logout ()+{+ if ($('#logout-btn').hasClass('disabled'))+ return;++ $.post(+ Wiki.logoutURI+ , function ()+ {+ $('#login-status').removeClass('error')+ $('#login-status').html('logout successful')+ $('#auth').fadeOut()+ updateAuth()+ }+ )+}++function updateAuth ()+{+ $.get(+ Wiki.loginfoURI+ , ''+ , function (res)+ {+ var m = res.match(/username=(.*?\n)/)+ Wiki.user = (m && m[1]) || ''+ $('#user').html(Wiki.user)+ var bla = $('#user-ui').val(Wiki.user)+ fieldUpdate.call(bla)+ }+ , ''+ , function (res)+ {+ Wiki.user = ''+ $('#user').html('<i>not logged in</i>')+ fieldUpdate.call($('#user-ui').val(''))+ }+ )+}++function signup ()+{+ if ($('#signup-btn').hasClass('disabled'))+ return;++ $.post(+ Wiki.signupURI+ , { username : $('#su-username').val()+ , password : $('#su-password').val()+ } + , function ()+ {+ $('#signup-status').removeClass('error')+ $('#signup-status').html('signup successful')+ panelClose($('#signup-btn'), $('#signup'))+ }+ , ''+ , function (e)+ {+ $('#signup-status').addClass('error')+ $('#signup-status').html('signup failed: <span>' + e.responseText + '</span>')+ }+ )+}++/* ---- document history --------------------------------------------------- */++function showHistory (title)+{+ // Refuse history updates when panel is closed.+ if (!$('#history').hasClass('open'))+ return++ $.get(makeURIExt('his'), '',+ function (res)+ {+ $('#history').html(historyTable(res))+ }+ )+}++function historyTable (res)+{+ function row (c, i)+ {+ var lines = c.split('\n')+ , modified = lines.shift()+ , author = lines.shift()+ , name = lines.shift()++ // Side note.+ var klass =+ name == Wiki.rev ||+ (i == 0 && !Wiki.rev) + ? 'class="current" ' : ''++ return [+ , '<tr $klass>'+ , '<td>$modified</td>'+ , '<td>$author</td>'+ , '<td><a href="' + makeURI(Wiki.viewerURI, undefined, undefined, i == 0 ? '' : name) + '">$name</a></td>'+ , '</tr>'+ ].join('').interpolate({+ 'klass' : klass+ , 'modified' : modified+ , 'author' : author+ , 'name' : name+ })+ }++ function col (c)+ {+ return '<td>' + c + '</td>'+ }++ return '' + + '<table cellpadding="0" cellspacing="0"><tr>' ++ '<th id="modified">modified</th>' ++ '<th id="author">author</th>' ++ '<th id="changename">change</th>' ++ '</tr>' ++ res.asHTML().split("\n\n").map(row).join('')+ + '</tbody></table>'+}++/* ---- document editor ---------------------------------------------------- */++function showEditor (title)+{+ $.get(makeURIExt('txt'), '',++ // Editing an existing document:+ function (res)+ {+ $('#editField').val(res)+ },+ '',++ // `Editing' a new document:+ function (res)+ {+ $('#editField').val('<new document>')+ }+ )+}++function save (title)+{+ if (!Wiki.user)+ return;++ $.put(+ makeURI(undefined, undefined, 'txt', $('#change.full').val())+ , $('#editField').val()+ , function ()+ {+ $('#edit-status').removeClass('error')+ $('#edit-status').html('save successful')+ panelClose($('#edit-btn'), $('#editor'))+ show()+ showHistory()+ }+ , ''+ , function (e)+ {+ $('#edit-status').addClass('error')+ $('#edit-status').html('save failed: <span>' + e.responseText + '</span>')+ }+ )+}++function preview ()+{+ $.put(+ Wiki.previewURI + '.' + Wiki.ext+ , $('#editField').val()+ , function (res)+ {+ viewerHTML(res)+ processLinks()+ processImages()+ $('#edit-status').removeClass('error')+ $('#edit-status').html('preview successful')+ }+ )+}++function _delete ()+{+ $._delete(+ makeURI(undefined, undefined, '', $('#change.full').val())+ , ''+ , function (res)+ {+ $('#edit-status').removeClass('error')+ $('#edit-status').html('delete successful')+ // todo: close edit & history.+ }+ )+}+
@@ -0,0 +1,3585 @@+(function(){+/*+ * jQuery 1.2.6 - New Wave Javascript+ *+ * Copyright (c) 2008 John Resig (jquery.com)+ * Dual licensed under the MIT (MIT-LICENSE.txt)+ * and GPL (GPL-LICENSE.txt) licenses.+ *+ * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $+ * $Rev: 5685 $+ */++// Map over jQuery in case of overwrite+var _jQuery = window.jQuery,+// Map over the $ in case of overwrite+ _$ = window.$;++var jQuery = window.jQuery = window.$ = function( selector, context ) {+ // The jQuery object is actually just the init constructor 'enhanced'+ return new jQuery.fn.init( selector, context );+};++// A simple way to check for HTML strings or ID strings+// (both of which we optimize for)+var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,++// Is it a simple selector+ isSimple = /^.[^:#\[\.]*$/,++// Will speed up references to undefined, and allows munging its name.+ undefined;++jQuery.fn = jQuery.prototype = {+ init: function( selector, context ) {+ // Make sure that a selection was provided+ selector = selector || document;++ // Handle $(DOMElement)+ if ( selector.nodeType ) {+ this[0] = selector;+ this.length = 1;+ return this;+ }+ // Handle HTML strings+ if ( typeof selector == "string" ) {+ // Are we dealing with HTML string or an ID?+ var match = quickExpr.exec( selector );++ // Verify a match, and that no context was specified for #id+ if ( match && (match[1] || !context) ) {++ // HANDLE: $(html) -> $(array)+ if ( match[1] )+ selector = jQuery.clean( [ match[1] ], context );++ // HANDLE: $("#id")+ else {+ var elem = document.getElementById( match[3] );++ // Make sure an element was located+ if ( elem ){+ // Handle the case where IE and Opera return items+ // by name instead of ID+ if ( elem.id != match[3] )+ return jQuery().find( selector );++ // Otherwise, we inject the element directly into the jQuery object+ return jQuery( elem );+ }+ selector = [];+ }++ // HANDLE: $(expr, [context])+ // (which is just equivalent to: $(content).find(expr)+ } else+ return jQuery( context ).find( selector );++ // HANDLE: $(function)+ // Shortcut for document ready+ } else if ( jQuery.isFunction( selector ) )+ return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );++ return this.setArray(jQuery.makeArray(selector));+ },++ // The current version of jQuery being used+ jquery: "1.2.6",++ // The number of elements contained in the matched element set+ size: function() {+ return this.length;+ },++ // The number of elements contained in the matched element set+ length: 0,++ // Get the Nth element in the matched element set OR+ // Get the whole matched element set as a clean array+ get: function( num ) {+ return num == undefined ?++ // Return a 'clean' array+ jQuery.makeArray( this ) :++ // Return just the object+ this[ num ];+ },++ // Take an array of elements and push it onto the stack+ // (returning the new matched element set)+ pushStack: function( elems ) {+ // Build a new jQuery matched element set+ var ret = jQuery( elems );++ // Add the old object onto the stack (as a reference)+ ret.prevObject = this;++ // Return the newly-formed element set+ return ret;+ },++ // Force the current matched set of elements to become+ // the specified array of elements (destroying the stack in the process)+ // You should use pushStack() in order to do this, but maintain the stack+ setArray: function( elems ) {+ // Resetting the length to 0, then using the native Array push+ // is a super-fast way to populate an object with array-like properties+ this.length = 0;+ Array.prototype.push.apply( this, elems );++ return this;+ },++ // Execute a callback for every element in the matched set.+ // (You can seed the arguments with an array of args, but this is+ // only used internally.)+ each: function( callback, args ) {+ return jQuery.each( this, callback, args );+ },++ // Determine the position of an element within+ // the matched set of elements+ index: function( elem ) {+ var ret = -1;++ // Locate the position of the desired element+ return jQuery.inArray(+ // If it receives a jQuery object, the first element is used+ elem && elem.jquery ? elem[0] : elem+ , this );+ },++ attr: function( name, value, type ) {+ var options = name;++ // Look for the case where we're accessing a style value+ if ( name.constructor == String )+ if ( value === undefined )+ return this[0] && jQuery[ type || "attr" ]( this[0], name );++ else {+ options = {};+ options[ name ] = value;+ }++ // Check to see if we're setting style values+ return this.each(function(i){+ // Set all the styles+ for ( name in options )+ jQuery.attr(+ type ?+ this.style :+ this,+ name, jQuery.prop( this, options[ name ], type, i, name )+ );+ });+ },++ css: function( key, value ) {+ // ignore negative width and height values+ if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )+ value = undefined;+ return this.attr( key, value, "curCSS" );+ },++ text: function( text ) {+ if ( typeof text != "object" && text != null )+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );++ var ret = "";++ jQuery.each( text || this, function(){+ jQuery.each( this.childNodes, function(){+ if ( this.nodeType != 8 )+ ret += this.nodeType != 1 ?+ this.nodeValue :+ jQuery.fn.text( [ this ] );+ });+ });++ return ret;+ },++ wrapAll: function( html ) {+ if ( this[0] )+ // The elements to wrap the target around+ jQuery( html, this[0].ownerDocument )+ .clone()+ .insertBefore( this[0] )+ .map(function(){+ var elem = this;++ while ( elem.firstChild )+ elem = elem.firstChild;++ return elem;+ })+ .append(this);++ return this;+ },++ wrapInner: function( html ) {+ return this.each(function(){+ jQuery( this ).contents().wrapAll( html );+ });+ },++ wrap: function( html ) {+ return this.each(function(){+ jQuery( this ).wrapAll( html );+ });+ },++ append: function() {+ return this.domManip(arguments, true, false, function(elem){+ if (this.nodeType == 1)+ this.appendChild( elem );+ });+ },++ prepend: function() {+ return this.domManip(arguments, true, true, function(elem){+ if (this.nodeType == 1)+ this.insertBefore( elem, this.firstChild );+ });+ },++ before: function() {+ return this.domManip(arguments, false, false, function(elem){+ this.parentNode.insertBefore( elem, this );+ });+ },++ after: function() {+ return this.domManip(arguments, false, true, function(elem){+ this.parentNode.insertBefore( elem, this.nextSibling );+ });+ },++ end: function() {+ return this.prevObject || jQuery( [] );+ },++ find: function( selector ) {+ var elems = jQuery.map(this, function(elem){+ return jQuery.find( selector, elem );+ });++ return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ?+ jQuery.unique( elems ) :+ elems );+ },++ clone: function( events ) {+ // Do the clone+ var ret = this.map(function(){+ if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {+ // IE copies events bound via attachEvent when+ // using cloneNode. Calling detachEvent on the+ // clone will also remove the events from the orignal+ // In order to get around this, we use innerHTML.+ // Unfortunately, this means some modifications to+ // attributes in IE that are actually only stored+ // as properties will not be copied (such as the+ // the name attribute on an input).+ var clone = this.cloneNode(true),+ container = document.createElement("div");+ container.appendChild(clone);+ return jQuery.clean([container.innerHTML])[0];+ } else+ return this.cloneNode(true);+ });++ // Need to set the expando to null on the cloned set if it exists+ // removeData doesn't work here, IE removes it from the original as well+ // this is primarily for IE but the data expando shouldn't be copied over in any browser+ var clone = ret.find("*").andSelf().each(function(){+ if ( this[ expando ] != undefined )+ this[ expando ] = null;+ });++ // Copy the events from the original to the clone+ if ( events === true )+ this.find("*").andSelf().each(function(i){+ if (this.nodeType == 3)+ return;+ var events = jQuery.data( this, "events" );++ for ( var type in events )+ for ( var handler in events[ type ] )+ jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );+ });++ // Return the cloned set+ return ret;+ },++ filter: function( selector ) {+ return this.pushStack(+ jQuery.isFunction( selector ) &&+ jQuery.grep(this, function(elem, i){+ return selector.call( elem, i );+ }) ||++ jQuery.multiFilter( selector, this ) );+ },++ not: function( selector ) {+ if ( selector.constructor == String )+ // test special case where just one selector is passed in+ if ( isSimple.test( selector ) )+ return this.pushStack( jQuery.multiFilter( selector, this, true ) );+ else+ selector = jQuery.multiFilter( selector, this );++ var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;+ return this.filter(function() {+ return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;+ });+ },++ add: function( selector ) {+ return this.pushStack( jQuery.unique( jQuery.merge(+ this.get(),+ typeof selector == 'string' ?+ jQuery( selector ) :+ jQuery.makeArray( selector )+ )));+ },++ is: function( selector ) {+ return !!selector && jQuery.multiFilter( selector, this ).length > 0;+ },++ hasClass: function( selector ) {+ return this.is( "." + selector );+ },++ val: function( value ) {+ if ( value == undefined ) {++ if ( this.length ) {+ var elem = this[0];++ // We need to handle select boxes special+ if ( jQuery.nodeName( elem, "select" ) ) {+ var index = elem.selectedIndex,+ values = [],+ options = elem.options,+ one = elem.type == "select-one";++ // Nothing was selected+ if ( index < 0 )+ return null;++ // Loop through all the selected options+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {+ var option = options[ i ];++ if ( option.selected ) {+ // Get the specifc value for the option+ value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;++ // We don't need an array for one selects+ if ( one )+ return value;++ // Multi-Selects return an array+ values.push( value );+ }+ }++ return values;++ // Everything else, we just grab the value+ } else+ return (this[0].value || "").replace(/\r/g, "");++ }++ return undefined;+ }++ if( value.constructor == Number )+ value += '';++ return this.each(function(){+ if ( this.nodeType != 1 )+ return;++ if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )+ this.checked = (jQuery.inArray(this.value, value) >= 0 ||+ jQuery.inArray(this.name, value) >= 0);++ else if ( jQuery.nodeName( this, "select" ) ) {+ var values = jQuery.makeArray(value);++ jQuery( "option", this ).each(function(){+ this.selected = (jQuery.inArray( this.value, values ) >= 0 ||+ jQuery.inArray( this.text, values ) >= 0);+ });++ if ( !values.length )+ this.selectedIndex = -1;++ } else+ this.value = value;+ });+ },++ html: function( value ) {+ return value == undefined ?+ (this[0] ?+ this[0].innerHTML :+ null) :+ this.empty().append( value );+ },++ replaceWith: function( value ) {+ return this.after( value ).remove();+ },++ eq: function( i ) {+ return this.slice( i, i + 1 );+ },++ slice: function() {+ return this.pushStack( Array.prototype.slice.apply( this, arguments ) );+ },++ map: function( callback ) {+ return this.pushStack( jQuery.map(this, function(elem, i){+ return callback.call( elem, i, elem );+ }));+ },++ andSelf: function() {+ return this.add( this.prevObject );+ },++ data: function( key, value ){+ var parts = key.split(".");+ parts[1] = parts[1] ? "." + parts[1] : "";++ if ( value === undefined ) {+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);++ if ( data === undefined && this.length )+ data = jQuery.data( this[0], key );++ return data === undefined && parts[1] ?+ this.data( parts[0] ) :+ data;+ } else+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){+ jQuery.data( this, key, value );+ });+ },++ removeData: function( key ){+ return this.each(function(){+ jQuery.removeData( this, key );+ });+ },++ domManip: function( args, table, reverse, callback ) {+ var clone = this.length > 1, elems;++ return this.each(function(){+ if ( !elems ) {+ elems = jQuery.clean( args, this.ownerDocument );++ if ( reverse )+ elems.reverse();+ }++ var obj = this;++ if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )+ obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );++ var scripts = jQuery( [] );++ jQuery.each(elems, function(){+ var elem = clone ?+ jQuery( this ).clone( true )[0] :+ this;++ // execute all scripts after the elements have been injected+ if ( jQuery.nodeName( elem, "script" ) )+ scripts = scripts.add( elem );+ else {+ // Remove any inner scripts for later evaluation+ if ( elem.nodeType == 1 )+ scripts = scripts.add( jQuery( "script", elem ).remove() );++ // Inject the elements into the document+ callback.call( obj, elem );+ }+ });++ scripts.each( evalScript );+ });+ }+};++// Give the init function the jQuery prototype for later instantiation+jQuery.fn.init.prototype = jQuery.fn;++function evalScript( i, elem ) {+ if ( elem.src )+ jQuery.ajax({+ url: elem.src,+ async: false,+ dataType: "script"+ });++ else+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );++ if ( elem.parentNode )+ elem.parentNode.removeChild( elem );+}++function now(){+ return +new Date;+}++jQuery.extend = jQuery.fn.extend = function() {+ // copy reference to target object+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;++ // Handle a deep copy situation+ if ( target.constructor == Boolean ) {+ deep = target;+ target = arguments[1] || {};+ // skip the boolean and the target+ i = 2;+ }++ // Handle case when target is a string or something (possible in deep copy)+ if ( typeof target != "object" && typeof target != "function" )+ target = {};++ // extend jQuery itself if only one argument is passed+ if ( length == i ) {+ target = this;+ --i;+ }++ for ( ; i < length; i++ )+ // Only deal with non-null/undefined values+ if ( (options = arguments[ i ]) != null )+ // Extend the base object+ for ( var name in options ) {+ var src = target[ name ], copy = options[ name ];++ // Prevent never-ending loop+ if ( target === copy )+ continue;++ // Recurse if we're merging object values+ if ( deep && copy && typeof copy == "object" && !copy.nodeType )+ target[ name ] = jQuery.extend( deep, + // Never move original objects, clone them+ src || ( copy.length != null ? [ ] : { } )+ , copy );++ // Don't bring in undefined values+ else if ( copy !== undefined )+ target[ name ] = copy;++ }++ // Return the modified object+ return target;+};++var expando = "jQuery" + now(), uuid = 0, windowData = {},+ // exclude the following css properties to add px+ exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,+ // cache defaultView+ defaultView = document.defaultView || {};++jQuery.extend({+ noConflict: function( deep ) {+ window.$ = _$;++ if ( deep )+ window.jQuery = _jQuery;++ return jQuery;+ },++ // See test/unit/core.js for details concerning this function.+ isFunction: function( fn ) {+ return !!fn && typeof fn != "string" && !fn.nodeName &&+ fn.constructor != Array && /^[\s[]?function/.test( fn + "" );+ },++ // check if an element is in a (or is an) XML document+ isXMLDoc: function( elem ) {+ return elem.documentElement && !elem.body ||+ elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;+ },++ // Evalulates a script in a global context+ globalEval: function( data ) {+ data = jQuery.trim( data );++ if ( data ) {+ // Inspired by code by Andrea Giammarchi+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html+ var head = document.getElementsByTagName("head")[0] || document.documentElement,+ script = document.createElement("script");++ script.type = "text/javascript";+ if ( jQuery.browser.msie )+ script.text = data;+ else+ script.appendChild( document.createTextNode( data ) );++ // Use insertBefore instead of appendChild to circumvent an IE6 bug.+ // This arises when a base node is used (#2709).+ head.insertBefore( script, head.firstChild );+ head.removeChild( script );+ }+ },++ nodeName: function( elem, name ) {+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();+ },++ cache: {},++ data: function( elem, name, data ) {+ elem = elem == window ?+ windowData :+ elem;++ var id = elem[ expando ];++ // Compute a unique ID for the element+ if ( !id )+ id = elem[ expando ] = ++uuid;++ // Only generate the data cache if we're+ // trying to access or manipulate it+ if ( name && !jQuery.cache[ id ] )+ jQuery.cache[ id ] = {};++ // Prevent overriding the named cache with undefined values+ if ( data !== undefined )+ jQuery.cache[ id ][ name ] = data;++ // Return the named cache data, or the ID for the element+ return name ?+ jQuery.cache[ id ][ name ] :+ id;+ },++ removeData: function( elem, name ) {+ elem = elem == window ?+ windowData :+ elem;++ var id = elem[ expando ];++ // If we want to remove a specific section of the element's data+ if ( name ) {+ if ( jQuery.cache[ id ] ) {+ // Remove the section of cache data+ delete jQuery.cache[ id ][ name ];++ // If we've removed all the data, remove the element's cache+ name = "";++ for ( name in jQuery.cache[ id ] )+ break;++ if ( !name )+ jQuery.removeData( elem );+ }++ // Otherwise, we want to remove all of the element's data+ } else {+ // Clean up the element expando+ try {+ delete elem[ expando ];+ } catch(e){+ // IE has trouble directly removing the expando+ // but it's ok with using removeAttribute+ if ( elem.removeAttribute )+ elem.removeAttribute( expando );+ }++ // Completely remove the data cache+ delete jQuery.cache[ id ];+ }+ },++ // args is for internal usage only+ each: function( object, callback, args ) {+ var name, i = 0, length = object.length;++ if ( args ) {+ if ( length == undefined ) {+ for ( name in object )+ if ( callback.apply( object[ name ], args ) === false )+ break;+ } else+ for ( ; i < length; )+ if ( callback.apply( object[ i++ ], args ) === false )+ break;++ // A special, fast, case for the most common use of each+ } else {+ if ( length == undefined ) {+ for ( name in object )+ if ( callback.call( object[ name ], name, object[ name ] ) === false )+ break;+ } else+ for ( var value = object[0];+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}+ }++ return object;+ },++ prop: function( elem, value, type, i, name ) {+ // Handle executable functions+ if ( jQuery.isFunction( value ) )+ value = value.call( elem, i );++ // Handle passing in a number to a CSS property+ return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?+ value + "px" :+ value;+ },++ className: {+ // internal only, use addClass("class")+ add: function( elem, classNames ) {+ jQuery.each((classNames || "").split(/\s+/), function(i, className){+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )+ elem.className += (elem.className ? " " : "") + className;+ });+ },++ // internal only, use removeClass("class")+ remove: function( elem, classNames ) {+ if (elem.nodeType == 1)+ elem.className = classNames != undefined ?+ jQuery.grep(elem.className.split(/\s+/), function(className){+ return !jQuery.className.has( classNames, className );+ }).join(" ") :+ "";+ },++ // internal only, use hasClass("class")+ has: function( elem, className ) {+ return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;+ }+ },++ // A method for quickly swapping in/out CSS properties to get correct calculations+ swap: function( elem, options, callback ) {+ var old = {};+ // Remember the old values, and insert the new ones+ for ( var name in options ) {+ old[ name ] = elem.style[ name ];+ elem.style[ name ] = options[ name ];+ }++ callback.call( elem );++ // Revert the old values+ for ( var name in options )+ elem.style[ name ] = old[ name ];+ },++ css: function( elem, name, force ) {+ if ( name == "width" || name == "height" ) {+ var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];++ function getWH() {+ val = name == "width" ? elem.offsetWidth : elem.offsetHeight;+ var padding = 0, border = 0;+ jQuery.each( which, function() {+ padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;+ border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;+ });+ val -= Math.round(padding + border);+ }++ if ( jQuery(elem).is(":visible") )+ getWH();+ else+ jQuery.swap( elem, props, getWH );++ return Math.max(0, val);+ }++ return jQuery.curCSS( elem, name, force );+ },++ curCSS: function( elem, name, force ) {+ var ret, style = elem.style;++ // A helper method for determining if an element's values are broken+ function color( elem ) {+ if ( !jQuery.browser.safari )+ return false;++ // defaultView is cached+ var ret = defaultView.getComputedStyle( elem, null );+ return !ret || ret.getPropertyValue("color") == "";+ }++ // We need to handle opacity special in IE+ if ( name == "opacity" && jQuery.browser.msie ) {+ ret = jQuery.attr( style, "opacity" );++ return ret == "" ?+ "1" :+ ret;+ }+ // Opera sometimes will give the wrong display answer, this fixes it, see #2037+ if ( jQuery.browser.opera && name == "display" ) {+ var save = style.outline;+ style.outline = "0 solid black";+ style.outline = save;+ }++ // Make sure we're using the right name for getting the float value+ if ( name.match( /float/i ) )+ name = styleFloat;++ if ( !force && style && style[ name ] )+ ret = style[ name ];++ else if ( defaultView.getComputedStyle ) {++ // Only "float" is needed here+ if ( name.match( /float/i ) )+ name = "float";++ name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();++ var computedStyle = defaultView.getComputedStyle( elem, null );++ if ( computedStyle && !color( elem ) )+ ret = computedStyle.getPropertyValue( name );++ // If the element isn't reporting its values properly in Safari+ // then some display: none elements are involved+ else {+ var swap = [], stack = [], a = elem, i = 0;++ // Locate all of the parent display: none elements+ for ( ; a && color(a); a = a.parentNode )+ stack.unshift(a);++ // Go through and make them visible, but in reverse+ // (It would be better if we knew the exact display type that they had)+ for ( ; i < stack.length; i++ )+ if ( color( stack[ i ] ) ) {+ swap[ i ] = stack[ i ].style.display;+ stack[ i ].style.display = "block";+ }++ // Since we flip the display style, we have to handle that+ // one special, otherwise get the value+ ret = name == "display" && swap[ stack.length - 1 ] != null ?+ "none" :+ ( computedStyle && computedStyle.getPropertyValue( name ) ) || "";++ // Finally, revert the display styles back+ for ( i = 0; i < swap.length; i++ )+ if ( swap[ i ] != null )+ stack[ i ].style.display = swap[ i ];+ }++ // We should always get a number back from opacity+ if ( name == "opacity" && ret == "" )+ ret = "1";++ } else if ( elem.currentStyle ) {+ var camelCase = name.replace(/\-(\w)/g, function(all, letter){+ return letter.toUpperCase();+ });++ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];++ // From the awesome hack by Dean Edwards+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291++ // If we're not dealing with a regular pixel number+ // but a number that has a weird ending, we need to convert it to pixels+ if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {+ // Remember the original values+ var left = style.left, rsLeft = elem.runtimeStyle.left;++ // Put in the new values to get a computed value out+ elem.runtimeStyle.left = elem.currentStyle.left;+ style.left = ret || 0;+ ret = style.pixelLeft + "px";++ // Revert the changed values+ style.left = left;+ elem.runtimeStyle.left = rsLeft;+ }+ }++ return ret;+ },++ clean: function( elems, context ) {+ var ret = [];+ context = context || document;+ // !context.createElement fails in IE with an error but returns typeof 'object'+ if (typeof context.createElement == 'undefined')+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;++ jQuery.each(elems, function(i, elem){+ if ( !elem )+ return;++ if ( elem.constructor == Number )+ elem += '';++ // Convert html string into DOM nodes+ if ( typeof elem == "string" ) {+ // Fix "XHTML"-style tags in all browsers+ elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?+ all :+ front + "></" + tag + ">";+ });++ // Trim whitespace, otherwise indexOf won't work as expected+ var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");++ var wrap =+ // option or optgroup+ !tags.indexOf("<opt") &&+ [ 1, "<select multiple='multiple'>", "</select>" ] ||++ !tags.indexOf("<leg") &&+ [ 1, "<fieldset>", "</fieldset>" ] ||++ tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&+ [ 1, "<table>", "</table>" ] ||++ !tags.indexOf("<tr") &&+ [ 2, "<table><tbody>", "</tbody></table>" ] ||++ // <thead> matched above+ (!tags.indexOf("<td") || !tags.indexOf("<th")) &&+ [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||++ !tags.indexOf("<col") &&+ [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||++ // IE can't serialize <link> and <script> tags normally+ jQuery.browser.msie &&+ [ 1, "div<div>", "</div>" ] ||++ [ 0, "", "" ];++ // Go to html and back, then peel off extra wrappers+ div.innerHTML = wrap[1] + elem + wrap[2];++ // Move to the right depth+ while ( wrap[0]-- )+ div = div.lastChild;++ // Remove IE's autoinserted <tbody> from table fragments+ if ( jQuery.browser.msie ) {++ // String was a <table>, *may* have spurious <tbody>+ var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?+ div.firstChild && div.firstChild.childNodes :++ // String was a bare <thead> or <tfoot>+ wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?+ div.childNodes :+ [];++ for ( var j = tbody.length - 1; j >= 0 ; --j )+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )+ tbody[ j ].parentNode.removeChild( tbody[ j ] );++ // IE completely kills leading whitespace when innerHTML is used+ if ( /^\s/.test( elem ) )+ div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );++ }++ elem = jQuery.makeArray( div.childNodes );+ }++ if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )+ return;++ if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )+ ret.push( elem );++ else+ ret = jQuery.merge( ret, elem );++ });++ return ret;+ },++ attr: function( elem, name, value ) {+ // don't set attributes on text and comment nodes+ if (!elem || elem.nodeType == 3 || elem.nodeType == 8)+ return undefined;++ var notxml = !jQuery.isXMLDoc( elem ),+ // Whether we are setting (or getting)+ set = value !== undefined,+ msie = jQuery.browser.msie;++ // Try to normalize/fix the name+ name = notxml && jQuery.props[ name ] || name;++ // Only do all the following if this is a node (faster for style)+ // IE elem.getAttribute passes even for style+ if ( elem.tagName ) {++ // These attributes require special treatment+ var special = /href|src|style/.test( name );++ // Safari mis-reports the default selected property of a hidden option+ // Accessing the parent's selectedIndex property fixes it+ if ( name == "selected" && jQuery.browser.safari )+ elem.parentNode.selectedIndex;++ // If applicable, access the attribute via the DOM 0 way+ if ( name in elem && notxml && !special ) {+ if ( set ){+ // We can't allow the type property to be changed (since it causes problems in IE)+ if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )+ throw "type property can't be changed";++ elem[ name ] = value;+ }++ // browsers index elements by id/name on forms, give priority to attributes.+ if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )+ return elem.getAttributeNode( name ).nodeValue;++ return elem[ name ];+ }++ if ( msie && notxml && name == "style" )+ return jQuery.attr( elem.style, "cssText", value );++ if ( set )+ // convert the value to a string (all browsers do this but IE) see #1070+ elem.setAttribute( name, "" + value );++ var attr = msie && notxml && special+ // Some attributes require a special call on IE+ ? elem.getAttribute( name, 2 )+ : elem.getAttribute( name );++ // Non-existent attributes return null, we normalize to undefined+ return attr === null ? undefined : attr;+ }++ // elem is actually elem.style ... set the style++ // IE uses filters for opacity+ if ( msie && name == "opacity" ) {+ if ( set ) {+ // IE has trouble with opacity if it does not have layout+ // Force it by setting the zoom level+ elem.zoom = 1;++ // Set the alpha filter to set the opacity+ elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) ++ (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");+ }++ return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':+ "";+ }++ name = name.replace(/-([a-z])/ig, function(all, letter){+ return letter.toUpperCase();+ });++ if ( set )+ elem[ name ] = value;++ return elem[ name ];+ },++ trim: function( text ) {+ return (text || "").replace( /^\s+|\s+$/g, "" );+ },++ makeArray: function( array ) {+ var ret = [];++ if( array != null ){+ var i = array.length;+ //the window, strings and functions also have 'length'+ if( i == null || array.split || array.setInterval || array.call )+ ret[0] = array;+ else+ while( i )+ ret[--i] = array[i];+ }++ return ret;+ },++ inArray: function( elem, array ) {+ for ( var i = 0, length = array.length; i < length; i++ )+ // Use === because on IE, window == document+ if ( array[ i ] === elem )+ return i;++ return -1;+ },++ merge: function( first, second ) {+ // We have to loop this way because IE & Opera overwrite the length+ // expando of getElementsByTagName+ var i = 0, elem, pos = first.length;+ // Also, we need to make sure that the correct elements are being returned+ // (IE returns comment nodes in a '*' query)+ if ( jQuery.browser.msie ) {+ while ( elem = second[ i++ ] )+ if ( elem.nodeType != 8 )+ first[ pos++ ] = elem;++ } else+ while ( elem = second[ i++ ] )+ first[ pos++ ] = elem;++ return first;+ },++ unique: function( array ) {+ var ret = [], done = {};++ try {++ for ( var i = 0, length = array.length; i < length; i++ ) {+ var id = jQuery.data( array[ i ] );++ if ( !done[ id ] ) {+ done[ id ] = true;+ ret.push( array[ i ] );+ }+ }++ } catch( e ) {+ ret = array;+ }++ return ret;+ },++ grep: function( elems, callback, inv ) {+ var ret = [];++ // Go through the array, only saving the items+ // that pass the validator function+ for ( var i = 0, length = elems.length; i < length; i++ )+ if ( !inv != !callback( elems[ i ], i ) )+ ret.push( elems[ i ] );++ return ret;+ },++ map: function( elems, callback ) {+ var ret = [];++ // Go through the array, translating each of the items to their+ // new value (or values).+ for ( var i = 0, length = elems.length; i < length; i++ ) {+ var value = callback( elems[ i ], i );++ if ( value != null )+ ret[ ret.length ] = value;+ }++ return ret.concat.apply( [], ret );+ }+});++var userAgent = navigator.userAgent.toLowerCase();++// Figure out what browser is being used+jQuery.browser = {+ version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],+ safari: /webkit/.test( userAgent ),+ opera: /opera/.test( userAgent ),+ msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),+ mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )+};++var styleFloat = jQuery.browser.msie ?+ "styleFloat" :+ "cssFloat";++jQuery.extend({+ // Check to see if the W3C box model is being used+ boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",++ props: {+ "for": "htmlFor",+ "class": "className",+ "float": styleFloat,+ cssFloat: styleFloat,+ styleFloat: styleFloat,+ readonly: "readOnly",+ maxlength: "maxLength",+ cellspacing: "cellSpacing"+ }+});++jQuery.each({+ parent: function(elem){return elem.parentNode;},+ parents: function(elem){return jQuery.dir(elem,"parentNode");},+ next: function(elem){return jQuery.nth(elem,2,"nextSibling");},+ prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},+ nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},+ prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},+ siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},+ children: function(elem){return jQuery.sibling(elem.firstChild);},+ contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}+}, function(name, fn){+ jQuery.fn[ name ] = function( selector ) {+ var ret = jQuery.map( this, fn );++ if ( selector && typeof selector == "string" )+ ret = jQuery.multiFilter( selector, ret );++ return this.pushStack( jQuery.unique( ret ) );+ };+});++jQuery.each({+ appendTo: "append",+ prependTo: "prepend",+ insertBefore: "before",+ insertAfter: "after",+ replaceAll: "replaceWith"+}, function(name, original){+ jQuery.fn[ name ] = function() {+ var args = arguments;++ return this.each(function(){+ for ( var i = 0, length = args.length; i < length; i++ )+ jQuery( args[ i ] )[ original ]( this );+ });+ };+});++jQuery.each({+ removeAttr: function( name ) {+ jQuery.attr( this, name, "" );+ if (this.nodeType == 1)+ this.removeAttribute( name );+ },++ addClass: function( classNames ) {+ jQuery.className.add( this, classNames );+ },++ removeClass: function( classNames ) {+ jQuery.className.remove( this, classNames );+ },++ toggleClass: function( classNames ) {+ jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );+ },++ remove: function( selector ) {+ if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {+ // Prevent memory leaks+ jQuery( "*", this ).add(this).each(function(){+ jQuery.event.remove(this);+ jQuery.removeData(this);+ });+ if (this.parentNode)+ this.parentNode.removeChild( this );+ }+ },++ empty: function() {+ // Remove element nodes and prevent memory leaks+ jQuery( ">*", this ).remove();++ // Remove any remaining nodes+ while ( this.firstChild )+ this.removeChild( this.firstChild );+ }+}, function(name, fn){+ jQuery.fn[ name ] = function(){+ return this.each( fn, arguments );+ };+});++jQuery.each([ "Height", "Width" ], function(i, name){+ var type = name.toLowerCase();++ jQuery.fn[ type ] = function( size ) {+ // Get window width or height+ return this[0] == window ?+ // Opera reports document.body.client[Width/Height] properly in both quirks and standards+ jQuery.browser.opera && document.body[ "client" + name ] ||++ // Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)+ jQuery.browser.safari && window[ "inner" + name ] ||++ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode+ document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :++ // Get document width or height+ this[0] == document ?+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater+ Math.max(+ Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),+ Math.max(document.body["offset" + name], document.documentElement["offset" + name])+ ) :++ // Get or set width or height on the element+ size == undefined ?+ // Get width or height on the element+ (this.length ? jQuery.css( this[0], type ) : null) :++ // Set the width or height on the element (default to pixels if value is unitless)+ this.css( type, size.constructor == String ? size : size + "px" );+ };+});++// Helper function used by the dimensions and offset modules+function num(elem, prop) {+ return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;+}var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?+ "(?:[\\w*_-]|\\\\.)" :+ "(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",+ quickChild = new RegExp("^>\\s*(" + chars + "+)"),+ quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),+ quickClass = new RegExp("^([#.]?)(" + chars + "*)");++jQuery.extend({+ expr: {+ "": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},+ "#": function(a,i,m){return a.getAttribute("id")==m[2];},+ ":": {+ // Position Checks+ lt: function(a,i,m){return i<m[3]-0;},+ gt: function(a,i,m){return i>m[3]-0;},+ nth: function(a,i,m){return m[3]-0==i;},+ eq: function(a,i,m){return m[3]-0==i;},+ first: function(a,i){return i==0;},+ last: function(a,i,m,r){return i==r.length-1;},+ even: function(a,i){return i%2==0;},+ odd: function(a,i){return i%2;},++ // Child Checks+ "first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},+ "last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},+ "only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},++ // Parent Checks+ parent: function(a){return a.firstChild;},+ empty: function(a){return !a.firstChild;},++ // Text Check+ contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},++ // Visibility+ visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},+ hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},++ // Form attributes+ enabled: function(a){return !a.disabled;},+ disabled: function(a){return a.disabled;},+ checked: function(a){return a.checked;},+ selected: function(a){return a.selected||jQuery.attr(a,"selected");},++ // Form elements+ text: function(a){return "text"==a.type;},+ radio: function(a){return "radio"==a.type;},+ checkbox: function(a){return "checkbox"==a.type;},+ file: function(a){return "file"==a.type;},+ password: function(a){return "password"==a.type;},+ submit: function(a){return "submit"==a.type;},+ image: function(a){return "image"==a.type;},+ reset: function(a){return "reset"==a.type;},+ button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},+ input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},++ // :has()+ has: function(a,i,m){return jQuery.find(m[3],a).length;},++ // :header+ header: function(a){return /h\d/i.test(a.nodeName);},++ // :animated+ animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}+ }+ },++ // The regular expressions that power the parsing engine+ parse: [+ // Match: [@value='test'], [@foo]+ /^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,++ // Match: :contains('foo')+ /^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,++ // Match: :even, :last-child, #id, .class+ new RegExp("^([:.#]*)(" + chars + "+)")+ ],++ multiFilter: function( expr, elems, not ) {+ var old, cur = [];++ while ( expr && expr != old ) {+ old = expr;+ var f = jQuery.filter( expr, elems, not );+ expr = f.t.replace(/^\s*,\s*/, "" );+ cur = not ? elems = f.r : jQuery.merge( cur, f.r );+ }++ return cur;+ },++ find: function( t, context ) {+ // Quickly handle non-string expressions+ if ( typeof t != "string" )+ return [ t ];++ // check to make sure context is a DOM element or a document+ if ( context && context.nodeType != 1 && context.nodeType != 9)+ return [ ];++ // Set the correct context (if none is provided)+ context = context || document;++ // Initialize the search+ var ret = [context], done = [], last, nodeName;++ // Continue while a selector expression exists, and while+ // we're no longer looping upon ourselves+ while ( t && last != t ) {+ var r = [];+ last = t;++ t = jQuery.trim(t);++ var foundToken = false,++ // An attempt at speeding up child selectors that+ // point to a specific element tag+ re = quickChild,++ m = re.exec(t);++ if ( m ) {+ nodeName = m[1].toUpperCase();++ // Perform our own iteration and filter+ for ( var i = 0; ret[i]; i++ )+ for ( var c = ret[i].firstChild; c; c = c.nextSibling )+ if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )+ r.push( c );++ ret = r;+ t = t.replace( re, "" );+ if ( t.indexOf(" ") == 0 ) continue;+ foundToken = true;+ } else {+ re = /^([>+~])\s*(\w*)/i;++ if ( (m = re.exec(t)) != null ) {+ r = [];++ var merge = {};+ nodeName = m[2].toUpperCase();+ m = m[1];++ for ( var j = 0, rl = ret.length; j < rl; j++ ) {+ var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;+ for ( ; n; n = n.nextSibling )+ if ( n.nodeType == 1 ) {+ var id = jQuery.data(n);++ if ( m == "~" && merge[id] ) break;++ if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {+ if ( m == "~" ) merge[id] = true;+ r.push( n );+ }++ if ( m == "+" ) break;+ }+ }++ ret = r;++ // And remove the token+ t = jQuery.trim( t.replace( re, "" ) );+ foundToken = true;+ }+ }++ // See if there's still an expression, and that we haven't already+ // matched a token+ if ( t && !foundToken ) {+ // Handle multiple expressions+ if ( !t.indexOf(",") ) {+ // Clean the result set+ if ( context == ret[0] ) ret.shift();++ // Merge the result sets+ done = jQuery.merge( done, ret );++ // Reset the context+ r = ret = [context];++ // Touch up the selector string+ t = " " + t.substr(1,t.length);++ } else {+ // Optimize for the case nodeName#idName+ var re2 = quickID;+ var m = re2.exec(t);++ // Re-organize the results, so that they're consistent+ if ( m ) {+ m = [ 0, m[2], m[3], m[1] ];++ } else {+ // Otherwise, do a traditional filter check for+ // ID, class, and element selectors+ re2 = quickClass;+ m = re2.exec(t);+ }++ m[2] = m[2].replace(/\\/g, "");++ var elem = ret[ret.length-1];++ // Try to do a global search by ID, where we can+ if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {+ // Optimization for HTML document case+ var oid = elem.getElementById(m[2]);++ // Do a quick check for the existence of the actual ID attribute+ // to avoid selecting by the name attribute in IE+ // also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form+ if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )+ oid = jQuery('[@id="'+m[2]+'"]', elem)[0];++ // Do a quick check for node name (where applicable) so+ // that div#foo searches will be really fast+ ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];+ } else {+ // We need to find all descendant elements+ for ( var i = 0; ret[i]; i++ ) {+ // Grab the tag name being searched for+ var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];++ // Handle IE7 being really dumb about <object>s+ if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )+ tag = "param";++ r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));+ }++ // It's faster to filter by class and be done with it+ if ( m[1] == "." )+ r = jQuery.classFilter( r, m[2] );++ // Same with ID filtering+ if ( m[1] == "#" ) {+ var tmp = [];++ // Try to find the element with the ID+ for ( var i = 0; r[i]; i++ )+ if ( r[i].getAttribute("id") == m[2] ) {+ tmp = [ r[i] ];+ break;+ }++ r = tmp;+ }++ ret = r;+ }++ t = t.replace( re2, "" );+ }++ }++ // If a selector string still exists+ if ( t ) {+ // Attempt to filter it+ var val = jQuery.filter(t,r);+ ret = r = val.r;+ t = jQuery.trim(val.t);+ }+ }++ // An error occurred with the selector;+ // just return an empty set instead+ if ( t )+ ret = [];++ // Remove the root context+ if ( ret && context == ret[0] )+ ret.shift();++ // And combine the results+ done = jQuery.merge( done, ret );++ return done;+ },++ classFilter: function(r,m,not){+ m = " " + m + " ";+ var tmp = [];+ for ( var i = 0; r[i]; i++ ) {+ var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;+ if ( !not && pass || not && !pass )+ tmp.push( r[i] );+ }+ return tmp;+ },++ filter: function(t,r,not) {+ var last;++ // Look for common filter expressions+ while ( t && t != last ) {+ last = t;++ var p = jQuery.parse, m;++ for ( var i = 0; p[i]; i++ ) {+ m = p[i].exec( t );++ if ( m ) {+ // Remove what we just matched+ t = t.substring( m[0].length );++ m[2] = m[2].replace(/\\/g, "");+ break;+ }+ }++ if ( !m )+ break;++ // :not() is a special case that can be optimized by+ // keeping it out of the expression list+ if ( m[1] == ":" && m[2] == "not" )+ // optimize if only one selector found (most common case)+ r = isSimple.test( m[3] ) ?+ jQuery.filter(m[3], r, true).r :+ jQuery( r ).not( m[3] );++ // We can get a big speed boost by filtering by class here+ else if ( m[1] == "." )+ r = jQuery.classFilter(r, m[2], not);++ else if ( m[1] == "[" ) {+ var tmp = [], type = m[3];++ for ( var i = 0, rl = r.length; i < rl; i++ ) {+ var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];++ if ( z == null || /href|src|selected/.test(m[2]) )+ z = jQuery.attr(a,m[2]) || '';++ if ( (type == "" && !!z ||+ type == "=" && z == m[5] ||+ type == "!=" && z != m[5] ||+ type == "^=" && z && !z.indexOf(m[5]) ||+ type == "$=" && z.substr(z.length - m[5].length) == m[5] ||+ (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )+ tmp.push( a );+ }++ r = tmp;++ // We can get a speed boost by handling nth-child here+ } else if ( m[1] == ":" && m[2] == "nth-child" ) {+ var merge = {}, tmp = [],+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'+ test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(+ m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||+ !/\D/.test(m[3]) && "0n+" + m[3] || m[3]),+ // calculate the numbers (first)n+(last) including if they are negative+ first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;++ // loop through all the elements left in the jQuery object+ for ( var i = 0, rl = r.length; i < rl; i++ ) {+ var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);++ if ( !merge[id] ) {+ var c = 1;++ for ( var n = parentNode.firstChild; n; n = n.nextSibling )+ if ( n.nodeType == 1 )+ n.nodeIndex = c++;++ merge[id] = true;+ }++ var add = false;++ if ( first == 0 ) {+ if ( node.nodeIndex == last )+ add = true;+ } else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )+ add = true;++ if ( add ^ not )+ tmp.push( node );+ }++ r = tmp;++ // Otherwise, find the expression to execute+ } else {+ var fn = jQuery.expr[ m[1] ];+ if ( typeof fn == "object" )+ fn = fn[ m[2] ];++ if ( typeof fn == "string" )+ fn = eval("false||function(a,i){return " + fn + ";}");++ // Execute it against the current filter+ r = jQuery.grep( r, function(elem, i){+ return fn(elem, i, m, r);+ }, not );+ }+ }++ // Return an array of filtered elements (r)+ // and the modified expression string (t)+ return { r: r, t: t };+ },++ dir: function( elem, dir ){+ var matched = [],+ cur = elem[dir];+ while ( cur && cur != document ) {+ if ( cur.nodeType == 1 )+ matched.push( cur );+ cur = cur[dir];+ }+ return matched;+ },++ nth: function(cur,result,dir,elem){+ result = result || 1;+ var num = 0;++ for ( ; cur; cur = cur[dir] )+ if ( cur.nodeType == 1 && ++num == result )+ break;++ return cur;+ },++ sibling: function( n, elem ) {+ var r = [];++ for ( ; n; n = n.nextSibling ) {+ if ( n.nodeType == 1 && n != elem )+ r.push( n );+ }++ return r;+ }+});+/*+ * A number of helper functions used for managing events.+ * Many of the ideas behind this code orignated from+ * Dean Edwards' addEvent library.+ */+jQuery.event = {++ // Bind an event to an element+ // Original by Dean Edwards+ add: function(elem, types, handler, data) {+ if ( elem.nodeType == 3 || elem.nodeType == 8 )+ return;++ // For whatever reason, IE has trouble passing the window object+ // around, causing it to be cloned in the process+ if ( jQuery.browser.msie && elem.setInterval )+ elem = window;++ // Make sure that the function being executed has a unique ID+ if ( !handler.guid )+ handler.guid = this.guid++;++ // if data is passed, bind to handler+ if( data != undefined ) {+ // Create temporary function pointer to original handler+ var fn = handler;++ // Create unique handler function, wrapped around original handler+ handler = this.proxy( fn, function() {+ // Pass arguments and context to original handler+ return fn.apply(this, arguments);+ });++ // Store data in unique handler+ handler.data = data;+ }++ // Init the element's event structure+ var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),+ handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){+ // Handle the second event of a trigger and when+ // an event is called after a page has unloaded+ if ( typeof jQuery != "undefined" && !jQuery.event.triggered )+ return jQuery.event.handle.apply(arguments.callee.elem, arguments);+ });+ // Add elem as a property of the handle function+ // This is to prevent a memory leak with non-native+ // event in IE.+ handle.elem = elem;++ // Handle multiple events separated by a space+ // jQuery(...).bind("mouseover mouseout", fn);+ jQuery.each(types.split(/\s+/), function(index, type) {+ // Namespaced event handlers+ var parts = type.split(".");+ type = parts[0];+ handler.type = parts[1];++ // Get the current list of functions bound to this event+ var handlers = events[type];++ // Init the event handler queue+ if (!handlers) {+ handlers = events[type] = {};++ // Check for a special event handler+ // Only use addEventListener/attachEvent if the special+ // events handler returns false+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {+ // Bind the global event handler to the element+ if (elem.addEventListener)+ elem.addEventListener(type, handle, false);+ else if (elem.attachEvent)+ elem.attachEvent("on" + type, handle);+ }+ }++ // Add the function to the element's handler list+ handlers[handler.guid] = handler;++ // Keep track of which events have been used, for global triggering+ jQuery.event.global[type] = true;+ });++ // Nullify elem to prevent memory leaks in IE+ elem = null;+ },++ guid: 1,+ global: {},++ // Detach an event or set of events from an element+ remove: function(elem, types, handler) {+ // don't do events on text and comment nodes+ if ( elem.nodeType == 3 || elem.nodeType == 8 )+ return;++ var events = jQuery.data(elem, "events"), ret, index;++ if ( events ) {+ // Unbind all events for the element+ if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )+ for ( var type in events )+ this.remove( elem, type + (types || "") );+ else {+ // types is actually an event object here+ if ( types.type ) {+ handler = types.handler;+ types = types.type;+ }++ // Handle multiple events seperated by a space+ // jQuery(...).unbind("mouseover mouseout", fn);+ jQuery.each(types.split(/\s+/), function(index, type){+ // Namespaced event handlers+ var parts = type.split(".");+ type = parts[0];++ if ( events[type] ) {+ // remove the given handler for the given type+ if ( handler )+ delete events[type][handler.guid];++ // remove all handlers for the given type+ else+ for ( handler in events[type] )+ // Handle the removal of namespaced events+ if ( !parts[1] || events[type][handler].type == parts[1] )+ delete events[type][handler];++ // remove generic event handler if no more handlers exist+ for ( ret in events[type] ) break;+ if ( !ret ) {+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {+ if (elem.removeEventListener)+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);+ else if (elem.detachEvent)+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));+ }+ ret = null;+ delete events[type];+ }+ }+ });+ }++ // Remove the expando if it's no longer used+ for ( ret in events ) break;+ if ( !ret ) {+ var handle = jQuery.data( elem, "handle" );+ if ( handle ) handle.elem = null;+ jQuery.removeData( elem, "events" );+ jQuery.removeData( elem, "handle" );+ }+ }+ },++ trigger: function(type, data, elem, donative, extra) {+ // Clone the incoming data, if any+ data = jQuery.makeArray(data);++ if ( type.indexOf("!") >= 0 ) {+ type = type.slice(0, -1);+ var exclusive = true;+ }++ // Handle a global trigger+ if ( !elem ) {+ // Only trigger if we've ever bound an event for it+ if ( this.global[type] )+ jQuery("*").add([window, document]).trigger(type, data);++ // Handle triggering a single element+ } else {+ // don't do events on text and comment nodes+ if ( elem.nodeType == 3 || elem.nodeType == 8 )+ return undefined;++ var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),+ // Check to see if we need to provide a fake event, or not+ event = !data[0] || !data[0].preventDefault;++ // Pass along a fake event+ if ( event ) {+ data.unshift({+ type: type,+ target: elem,+ preventDefault: function(){},+ stopPropagation: function(){},+ timeStamp: now()+ });+ data[0][expando] = true; // no need to fix fake event+ }++ // Enforce the right trigger type+ data[0].type = type;+ if ( exclusive )+ data[0].exclusive = true;++ // Trigger the event, it is assumed that "handle" is a function+ var handle = jQuery.data(elem, "handle");+ if ( handle )+ val = handle.apply( elem, data );++ // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)+ if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )+ val = false;++ // Extra functions don't get the custom event object+ if ( event )+ data.shift();++ // Handle triggering of extra function+ if ( extra && jQuery.isFunction( extra ) ) {+ // call the extra function and tack the current return value on the end for possible inspection+ ret = extra.apply( elem, val == null ? data : data.concat( val ) );+ // if anything is returned, give it precedence and have it overwrite the previous value+ if (ret !== undefined)+ val = ret;+ }++ // Trigger the native events (except for clicks on links)+ if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {+ this.triggered = true;+ try {+ elem[ type ]();+ // prevent IE from throwing an error for some hidden elements+ } catch (e) {}+ }++ this.triggered = false;+ }++ return val;+ },++ handle: function(event) {+ // returned undefined or false+ var val, ret, namespace, all, handlers;++ event = arguments[0] = jQuery.event.fix( event || window.event );++ // Namespaced event handlers+ namespace = event.type.split(".");+ event.type = namespace[0];+ namespace = namespace[1];+ // Cache this now, all = true means, any handler+ all = !namespace && !event.exclusive;++ handlers = ( jQuery.data(this, "events") || {} )[event.type];++ for ( var j in handlers ) {+ var handler = handlers[j];++ // Filter the functions by class+ if ( all || handler.type == namespace ) {+ // Pass in a reference to the handler function itself+ // So that we can later remove it+ event.handler = handler;+ event.data = handler.data;++ ret = handler.apply( this, arguments );++ if ( val !== false )+ val = ret;++ if ( ret === false ) {+ event.preventDefault();+ event.stopPropagation();+ }+ }+ }++ return val;+ },++ fix: function(event) {+ if ( event[expando] == true )+ return event;++ // store a copy of the original event object+ // and "clone" to set read-only properties+ var originalEvent = event;+ event = { originalEvent: originalEvent };+ var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");+ for ( var i=props.length; i; i-- )+ event[ props[i] ] = originalEvent[ props[i] ];++ // Mark it as fixed+ event[expando] = true;++ // add preventDefault and stopPropagation since+ // they will not work on the clone+ event.preventDefault = function() {+ // if preventDefault exists run it on the original event+ if (originalEvent.preventDefault)+ originalEvent.preventDefault();+ // otherwise set the returnValue property of the original event to false (IE)+ originalEvent.returnValue = false;+ };+ event.stopPropagation = function() {+ // if stopPropagation exists run it on the original event+ if (originalEvent.stopPropagation)+ originalEvent.stopPropagation();+ // otherwise set the cancelBubble property of the original event to true (IE)+ originalEvent.cancelBubble = true;+ };++ // Fix timeStamp+ event.timeStamp = event.timeStamp || now();++ // Fix target property, if necessary+ if ( !event.target )+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either++ // check if target is a textnode (safari)+ if ( event.target.nodeType == 3 )+ event.target = event.target.parentNode;++ // Add relatedTarget, if necessary+ if ( !event.relatedTarget && event.fromElement )+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;++ // Calculate pageX/Y if missing and clientX/Y available+ if ( event.pageX == null && event.clientX != null ) {+ var doc = document.documentElement, body = document.body;+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);+ }++ // Add which for key events+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )+ event.which = event.charCode || event.keyCode;++ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)+ if ( !event.metaKey && event.ctrlKey )+ event.metaKey = event.ctrlKey;++ // Add which for click: 1 == left; 2 == middle; 3 == right+ // Note: button is not normalized, so don't use it+ if ( !event.which && event.button )+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));++ return event;+ },++ proxy: function( fn, proxy ){+ // Set the guid of unique handler to the same of original handler, so it can be removed+ proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;+ // So proxy can be declared as an argument+ return proxy;+ },++ special: {+ ready: {+ setup: function() {+ // Make sure the ready event is setup+ bindReady();+ return;+ },++ teardown: function() { return; }+ },++ mouseenter: {+ setup: function() {+ if ( jQuery.browser.msie ) return false;+ jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);+ return true;+ },++ teardown: function() {+ if ( jQuery.browser.msie ) return false;+ jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);+ return true;+ },++ handler: function(event) {+ // If we actually just moused on to a sub-element, ignore it+ if ( withinElement(event, this) ) return true;+ // Execute the right handlers by setting the event type to mouseenter+ event.type = "mouseenter";+ return jQuery.event.handle.apply(this, arguments);+ }+ },++ mouseleave: {+ setup: function() {+ if ( jQuery.browser.msie ) return false;+ jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);+ return true;+ },++ teardown: function() {+ if ( jQuery.browser.msie ) return false;+ jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);+ return true;+ },++ handler: function(event) {+ // If we actually just moused on to a sub-element, ignore it+ if ( withinElement(event, this) ) return true;+ // Execute the right handlers by setting the event type to mouseleave+ event.type = "mouseleave";+ return jQuery.event.handle.apply(this, arguments);+ }+ }+ }+};++jQuery.fn.extend({+ bind: function( type, data, fn ) {+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){+ jQuery.event.add( this, type, fn || data, fn && data );+ });+ },++ one: function( type, data, fn ) {+ var one = jQuery.event.proxy( fn || data, function(event) {+ jQuery(this).unbind(event, one);+ return (fn || data).apply( this, arguments );+ });+ return this.each(function(){+ jQuery.event.add( this, type, one, fn && data);+ });+ },++ unbind: function( type, fn ) {+ return this.each(function(){+ jQuery.event.remove( this, type, fn );+ });+ },++ trigger: function( type, data, fn ) {+ return this.each(function(){+ jQuery.event.trigger( type, data, this, true, fn );+ });+ },++ triggerHandler: function( type, data, fn ) {+ return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );+ },++ toggle: function( fn ) {+ // Save reference to arguments for access in closure+ var args = arguments, i = 1;++ // link all the functions, so any of them can unbind this click handler+ while( i < args.length )+ jQuery.event.proxy( fn, args[i++] );++ return this.click( jQuery.event.proxy( fn, function(event) {+ // Figure out which function to execute+ this.lastToggle = ( this.lastToggle || 0 ) % i;++ // Make sure that clicks stop+ event.preventDefault();++ // and execute the function+ return args[ this.lastToggle++ ].apply( this, arguments ) || false;+ }));+ },++ hover: function(fnOver, fnOut) {+ return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);+ },++ ready: function(fn) {+ // Attach the listeners+ bindReady();++ // If the DOM is already ready+ if ( jQuery.isReady )+ // Execute the function immediately+ fn.call( document, jQuery );++ // Otherwise, remember the function for later+ else+ // Add the function to the wait list+ jQuery.readyList.push( function() { return fn.call(this, jQuery); } );++ return this;+ }+});++jQuery.extend({+ isReady: false,+ readyList: [],+ // Handle when the DOM is ready+ ready: function() {+ // Make sure that the DOM is not already loaded+ if ( !jQuery.isReady ) {+ // Remember that the DOM is ready+ jQuery.isReady = true;++ // If there are functions bound, to execute+ if ( jQuery.readyList ) {+ // Execute all of them+ jQuery.each( jQuery.readyList, function(){+ this.call( document );+ });++ // Reset the list of functions+ jQuery.readyList = null;+ }++ // Trigger any bound ready events+ jQuery(document).triggerHandler("ready");+ }+ }+});++var readyBound = false;++function bindReady(){+ if ( readyBound ) return;+ readyBound = true;++ // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event+ if ( document.addEventListener && !jQuery.browser.opera)+ // Use the handy event callback+ document.addEventListener( "DOMContentLoaded", jQuery.ready, false );++ // If IE is used and is not in a frame+ // Continually check to see if the document is ready+ if ( jQuery.browser.msie && window == top ) (function(){+ if (jQuery.isReady) return;+ try {+ // If IE is used, use the trick by Diego Perini+ // http://javascript.nwbox.com/IEContentLoaded/+ document.documentElement.doScroll("left");+ } catch( error ) {+ setTimeout( arguments.callee, 0 );+ return;+ }+ // and execute any waiting functions+ jQuery.ready();+ })();++ if ( jQuery.browser.opera )+ document.addEventListener( "DOMContentLoaded", function () {+ if (jQuery.isReady) return;+ for (var i = 0; i < document.styleSheets.length; i++)+ if (document.styleSheets[i].disabled) {+ setTimeout( arguments.callee, 0 );+ return;+ }+ // and execute any waiting functions+ jQuery.ready();+ }, false);++ if ( jQuery.browser.safari ) {+ var numStyles;+ (function(){+ if (jQuery.isReady) return;+ if ( document.readyState != "loaded" && document.readyState != "complete" ) {+ setTimeout( arguments.callee, 0 );+ return;+ }+ if ( numStyles === undefined )+ numStyles = jQuery("style, link[rel=stylesheet]").length;+ if ( document.styleSheets.length != numStyles ) {+ setTimeout( arguments.callee, 0 );+ return;+ }+ // and execute any waiting functions+ jQuery.ready();+ })();+ }++ // A fallback to window.onload, that will always work+ jQuery.event.add( window, "load", jQuery.ready );+}++jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," ++ "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," ++ "submit,keydown,keypress,keyup,error").split(","), function(i, name){++ // Handle event binding+ jQuery.fn[name] = function(fn){+ return fn ? this.bind(name, fn) : this.trigger(name);+ };+});++// Checks if an event happened on an element within another element+// Used in jQuery.event.special.mouseenter and mouseleave handlers+var withinElement = function(event, elem) {+ // Check if mouse(over|out) are still within the same parent element+ var parent = event.relatedTarget;+ // Traverse up the tree+ while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }+ // Return true if we actually just moused on to a sub-element+ return parent == elem;+};++// Prevent memory leaks in IE+// And prevent errors on refresh with events like mouseover in other browsers+// Window isn't included so as not to unbind existing unload events+jQuery(window).bind("unload", function() {+ jQuery("*").add(document).unbind();+});+jQuery.fn.extend({+ // Keep a copy of the old load+ _load: jQuery.fn.load,++ load: function( url, params, callback ) {+ if ( typeof url != 'string' )+ return this._load( url );++ var off = url.indexOf(" ");+ if ( off >= 0 ) {+ var selector = url.slice(off, url.length);+ url = url.slice(0, off);+ }++ callback = callback || function(){};++ // Default to a GET request+ var type = "GET";++ // If the second parameter was provided+ if ( params )+ // If it's a function+ if ( jQuery.isFunction( params ) ) {+ // We assume that it's the callback+ callback = params;+ params = null;++ // Otherwise, build a param string+ } else {+ params = jQuery.param( params );+ type = "POST";+ }++ var self = this;++ // Request the remote document+ jQuery.ajax({+ url: url,+ type: type,+ dataType: "html",+ data: params,+ complete: function(res, status){+ // If successful, inject the HTML into all the matched elements+ if ( status == "success" || status == "notmodified" )+ // See if a selector was specified+ self.html( selector ?+ // Create a dummy div to hold the results+ jQuery("<div/>")+ // inject the contents of the document in, removing the scripts+ // to avoid any 'Permission Denied' errors in IE+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))++ // Locate the specified elements+ .find(selector) :++ // If not, just inject the full result+ res.responseText );++ self.each( callback, [res.responseText, status, res] );+ }+ });+ return this;+ },++ serialize: function() {+ return jQuery.param(this.serializeArray());+ },+ serializeArray: function() {+ return this.map(function(){+ return jQuery.nodeName(this, "form") ?+ jQuery.makeArray(this.elements) : this;+ })+ .filter(function(){+ return this.name && !this.disabled &&+ (this.checked || /select|textarea/i.test(this.nodeName) ||+ /text|hidden|password/i.test(this.type));+ })+ .map(function(i, elem){+ var val = jQuery(this).val();+ return val == null ? null :+ val.constructor == Array ?+ jQuery.map( val, function(val, i){+ return {name: elem.name, value: val};+ }) :+ {name: elem.name, value: val};+ }).get();+ }+});++// Attach a bunch of functions for handling common AJAX events+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){+ jQuery.fn[o] = function(f){+ return this.bind(o, f);+ };+});++var jsc = now();++jQuery.extend({+ get: function( url, data, callback, type, error ) {+ // shift arguments if data argument was ommited+ if ( jQuery.isFunction( data ) ) {+ callback = data;+ data = null;+ }++ return jQuery.ajax({+ type: "GET",+ url: url,+ data: data,+ error: error,+ success: callback,+ dataType: type+ });+ },++ put: function( url, data, callback, type, error ) {+ // shift arguments if data argument was ommited+ if ( jQuery.isFunction( data ) ) {+ callback = data;+ data = null;+ }++ return jQuery.ajax({+ type: "PUT",+ url: url,+ data: data,+ success: callback,+ error: error,+ dataType: type+ });+ },++ _delete: function( url, data, callback, type, error ) {+ // shift arguments if data argument was ommited+ if ( jQuery.isFunction( data ) ) {+ callback = data;+ data = null;+ }++ return jQuery.ajax({+ type: "DELETE",+ url: url,+ data: data,+ success: callback,+ error: error,+ dataType: type+ });+ },++ getScript: function( url, callback ) {+ return jQuery.get(url, null, callback, "script");+ },++ getJSON: function( url, data, callback ) {+ return jQuery.get(url, data, callback, "json");+ },++ post: function( url, data, callback, type, error ) {+ if ( jQuery.isFunction( data ) ) {+ callback = data;+ data = {};+ }++ return jQuery.ajax({+ type: "POST",+ url: url,+ data: data,+ success: callback,+ error: error,+ dataType: type+ });+ },++ ajaxSetup: function( settings ) {+ jQuery.extend( jQuery.ajaxSettings, settings );+ },++ ajaxSettings: {+ url: location.href,+ global: true,+ type: "GET",+ timeout: 0,+ contentType: "application/x-www-form-urlencoded",+ processData: true,+ async: true,+ data: null,+ username: null,+ password: null,+ accepts: {+ xml: "application/xml, text/xml",+ html: "text/html",+ script: "text/javascript, application/javascript",+ json: "application/json, text/javascript",+ text: "text/plain",+ _default: "*/*"+ }+ },++ // Last-Modified header cache for next request+ lastModified: {},++ ajax: function( s ) {+ // Extend the settings, but re-extend 's' so that it can be+ // checked again later (in the test suite, specifically)+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));++ var jsonp, jsre = /=\?(&|$)/g, status, data,+ type = s.type.toUpperCase();++ // convert data if not already a string+ if ( s.data && s.processData && typeof s.data != "string" )+ s.data = jQuery.param(s.data);++ // Handle JSONP Parameter Callbacks+ if ( s.dataType == "jsonp" ) {+ if ( type == "GET" ) {+ if ( !s.url.match(jsre) )+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";+ } else if ( !s.data || !s.data.match(jsre) )+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";+ s.dataType = "json";+ }++ // Build temporary JSONP function+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {+ jsonp = "jsonp" + jsc++;++ // Replace the =? sequence both in the query string and the data+ if ( s.data )+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");++ // We need to make sure+ // that a JSONP style response is executed properly+ s.dataType = "script";++ // Handle JSONP-style loading+ window[ jsonp ] = function(tmp){+ data = tmp;+ success();+ complete();+ // Garbage collect+ window[ jsonp ] = undefined;+ try{ delete window[ jsonp ]; } catch(e){}+ if ( head )+ head.removeChild( script );+ };+ }++ if ( s.dataType == "script" && s.cache == null )+ s.cache = false;++ if ( s.cache === false && type == "GET" ) {+ var ts = now();+ // try replacing _= if it is there+ var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");+ // if nothing was replaced, add timestamp to the end+ s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");+ }++ // If data is available, append data to url for get requests+ if ( s.data && type == "GET" ) {+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;++ // IE likes to send both get and post data, prevent this+ s.data = null;+ }++ // Watch for a new set of requests+ if ( s.global && ! jQuery.active++ )+ jQuery.event.trigger( "ajaxStart" );++ // Matches an absolute URL, and saves the domain+ var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;++ // If we're requesting a remote document+ // and trying to load JSON or Script with a GET+ if ( s.dataType == "script" && type == "GET"+ && remote.test(s.url) && remote.exec(s.url)[1] != location.host ){+ var head = document.getElementsByTagName("head")[0];+ var script = document.createElement("script");+ script.src = s.url;+ if (s.scriptCharset)+ script.charset = s.scriptCharset;++ // Handle Script loading+ if ( !jsonp ) {+ var done = false;++ // Attach handlers for all browsers+ script.onload = script.onreadystatechange = function(){+ if ( !done && (!this.readyState ||+ this.readyState == "loaded" || this.readyState == "complete") ) {+ done = true;+ success();+ complete();+ head.removeChild( script );+ }+ };+ }++ head.appendChild(script);++ // We handle everything using the script element injection+ return undefined;+ }++ var requestDone = false;++ // Create the request object; Microsoft failed to properly+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available+ var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();++ // Open the socket+ // Passing null username, generates a login popup on Opera (#2865)+ if( s.username )+ xhr.open(type, s.url, s.async, s.username, s.password);+ else+ xhr.open(type, s.url, s.async);++ // Need an extra try/catch for cross domain requests in Firefox 3+ try {+ // Set the correct header, if data is being sent+ if ( s.data )+ xhr.setRequestHeader("Content-Type", s.contentType);++ // Set the If-Modified-Since header, if ifModified mode.+ if ( s.ifModified )+ xhr.setRequestHeader("If-Modified-Since",+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );++ // Set header so the called script knows that it's an XMLHttpRequest+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");++ // Set the Accepts header for the server, depending on the dataType+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?+ s.accepts[ s.dataType ] + ", */*" :+ s.accepts._default );+ } catch(e){}++ // Allow custom headers/mimetypes+ if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {+ // cleanup active request counter+ s.global && jQuery.active--;+ // close opended socket+ xhr.abort();+ return false;+ }++ if ( s.global )+ jQuery.event.trigger("ajaxSend", [xhr, s]);++ // Wait for a response to come back+ var onreadystatechange = function(isTimeout){+ // The transfer is complete and the data is available, or the request timed out+ if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {+ requestDone = true;++ // clear poll interval+ if (ival) {+ clearInterval(ival);+ ival = null;+ }++ status = isTimeout == "timeout" && "timeout" ||+ !jQuery.httpSuccess( xhr ) && "error" ||+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||+ "success";++ if ( status == "success" ) {+ // Watch for, and catch, XML document parse errors+ try {+ // process the data (runs the xml through httpData regardless of callback)+ data = jQuery.httpData( xhr, s.dataType, s.dataFilter );+ } catch(e) {+ status = "parsererror";+ }+ }++ // Make sure that the request was successful or notmodified+ if ( status == "success" ) {+ // Cache Last-Modified header, if ifModified mode.+ var modRes;+ try {+ modRes = xhr.getResponseHeader("Last-Modified");+ } catch(e) {} // swallow exception thrown by FF if header is not available++ if ( s.ifModified && modRes )+ jQuery.lastModified[s.url] = modRes;++ // JSONP handles its own success callback+ if ( !jsonp )+ success();+ } else+ jQuery.handleError(s, xhr, status);++ // Fire the complete handlers+ complete();++ // Stop memory leaks+ if ( s.async )+ xhr = null;+ }+ };++ if ( s.async ) {+ // don't attach the handler to the request, just poll it instead+ var ival = setInterval(onreadystatechange, 13);++ // Timeout checker+ if ( s.timeout > 0 )+ setTimeout(function(){+ // Check to see if the request is still happening+ if ( xhr ) {+ // Cancel the request+ xhr.abort();++ if( !requestDone )+ onreadystatechange( "timeout" );+ }+ }, s.timeout);+ }++ // Send the data+ try {+ xhr.send(s.data);+ } catch(e) {+ jQuery.handleError(s, xhr, null, e);+ }++ // firefox 1.5 doesn't fire statechange for sync requests+ if ( !s.async )+ onreadystatechange();++ function success(){+ // If a local callback was specified, fire it and pass it the data+ if ( s.success )+ s.success( data, status );++ // Fire the global callback+ if ( s.global )+ jQuery.event.trigger( "ajaxSuccess", [xhr, s] );+ }++ function complete(){+ // Process result+ if ( s.complete )+ s.complete(xhr, status);++ // The request was completed+ if ( s.global )+ jQuery.event.trigger( "ajaxComplete", [xhr, s] );++ // Handle the global AJAX counter+ if ( s.global && ! --jQuery.active )+ jQuery.event.trigger( "ajaxStop" );+ }++ // return XMLHttpRequest to allow aborting the request etc.+ return xhr;+ },++ handleError: function( s, xhr, status, e ) {+ // If a local callback was specified, fire it+ if ( s.error ) s.error( xhr, status, e );++ // Fire the global callback+ if ( s.global )+ jQuery.event.trigger( "ajaxError", [xhr, s, e] );+ },++ // Counter for holding the number of active queries+ active: 0,++ // Determines if an XMLHttpRequest was successful or not+ httpSuccess: function( xhr ) {+ try {+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450+ return !xhr.status && location.protocol == "file:" ||+ ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||+ jQuery.browser.safari && xhr.status == undefined;+ } catch(e){}+ return false;+ },++ // Determines if an XMLHttpRequest returns NotModified+ httpNotModified: function( xhr, url ) {+ try {+ var xhrRes = xhr.getResponseHeader("Last-Modified");++ // Firefox always returns 200. check Last-Modified date+ return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||+ jQuery.browser.safari && xhr.status == undefined;+ } catch(e){}+ return false;+ },++ httpData: function( xhr, type, filter ) {+ var ct = xhr.getResponseHeader("content-type"),+ xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,+ data = xml ? xhr.responseXML : xhr.responseText;++ if ( xml && data.documentElement.tagName == "parsererror" )+ throw "parsererror";+ + // Allow a pre-filtering function to sanitize the response+ if( filter )+ data = filter( data, type );++ // If the type is "script", eval it in global context+ if ( type == "script" )+ jQuery.globalEval( data );++ // Get the JavaScript object, if JSON is used.+ if ( type == "json" )+ data = eval("(" + data + ")");++ return data;+ },++ // Serialize an array of form elements or a set of+ // key/values into a query string+ param: function( a ) {+ var s = [];++ // If an array was passed in, assume that it is an array+ // of form elements+ if ( a.constructor == Array || a.jquery )+ // Serialize the form elements+ jQuery.each( a, function(){+ s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );+ });++ // Otherwise, assume that it's an object of key/value pairs+ else+ // Serialize the key/values+ for ( var j in a )+ // If the value is an array then the key names need to be repeated+ if ( a[j] && a[j].constructor == Array )+ jQuery.each( a[j], function(){+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );+ });+ else+ s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );++ // Return the resulting serialization+ return s.join("&").replace(/%20/g, "+");+ }++});+jQuery.fn.extend({+ show: function(speed,callback){+ return speed ?+ this.animate({+ height: "show", width: "show", opacity: "show"+ }, speed, callback) :++ this.filter(":hidden").each(function(){+ this.style.display = this.oldblock || "";+ if ( jQuery.css(this,"display") == "none" ) {+ var elem = jQuery("<" + this.tagName + " />").appendTo("body");+ this.style.display = elem.css("display");+ // handle an edge condition where css is - div { display:none; } or similar+ if (this.style.display == "none")+ this.style.display = "block";+ elem.remove();+ }+ }).end();+ },++ hide: function(speed,callback){+ return speed ?+ this.animate({+ height: "hide", width: "hide", opacity: "hide"+ }, speed, callback) :++ this.filter(":visible").each(function(){+ this.oldblock = this.oldblock || jQuery.css(this,"display");+ this.style.display = "none";+ }).end();+ },++ // Save the old toggle function+ _toggle: jQuery.fn.toggle,++ toggle: function( fn, fn2 ){+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?+ this._toggle.apply( this, arguments ) :+ fn ?+ this.animate({+ height: "toggle", width: "toggle", opacity: "toggle"+ }, fn, fn2) :+ this.each(function(){+ jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();+ });+ },++ slideDown: function(speed,callback){+ return this.animate({height: "show"}, speed, callback);+ },++ slideUp: function(speed,callback){+ return this.animate({height: "hide"}, speed, callback);+ },++ slideToggle: function(speed, callback){+ return this.animate({height: "toggle"}, speed, callback);+ },++ fadeIn: function(speed, callback){+ return this.animate({opacity: "show"}, speed, callback);+ },++ fadeOut: function(speed, callback){+ return this.animate({opacity: "hide"}, speed, callback);+ },++ fadeTo: function(speed,to,callback){+ return this.animate({opacity: to}, speed, callback);+ },++ animate: function( prop, speed, easing, callback ) {+ var optall = jQuery.speed(speed, easing, callback);++ return this[ optall.queue === false ? "each" : "queue" ](function(){+ if ( this.nodeType != 1)+ return false;++ var opt = jQuery.extend({}, optall), p,+ hidden = jQuery(this).is(":hidden"), self = this;++ for ( p in prop ) {+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )+ return opt.complete.call(this);++ if ( p == "height" || p == "width" ) {+ // Store display property+ opt.display = jQuery.css(this, "display");++ // Make sure that nothing sneaks out+ opt.overflow = this.style.overflow;+ }+ }++ if ( opt.overflow != null )+ this.style.overflow = "hidden";++ opt.curAnim = jQuery.extend({}, prop);++ jQuery.each( prop, function(name, val){+ var e = new jQuery.fx( self, opt, name );++ if ( /toggle|show|hide/.test(val) )+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );+ else {+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),+ start = e.cur(true) || 0;++ if ( parts ) {+ var end = parseFloat(parts[2]),+ unit = parts[3] || "px";++ // We need to compute starting value+ if ( unit != "px" ) {+ self.style[ name ] = (end || 1) + unit;+ start = ((end || 1) / e.cur(true)) * start;+ self.style[ name ] = start + unit;+ }++ // If a +=/-= token was provided, we're doing a relative animation+ if ( parts[1] )+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;++ e.custom( start, end, unit );+ } else+ e.custom( start, val, "" );+ }+ });++ // For JS strict compliance+ return true;+ });+ },++ queue: function(type, fn){+ if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {+ fn = type;+ type = "fx";+ }++ if ( !type || (typeof type == "string" && !fn) )+ return queue( this[0], type );++ return this.each(function(){+ if ( fn.constructor == Array )+ queue(this, type, fn);+ else {+ queue(this, type).push( fn );++ if ( queue(this, type).length == 1 )+ fn.call(this);+ }+ });+ },++ stop: function(clearQueue, gotoEnd){+ var timers = jQuery.timers;++ if (clearQueue)+ this.queue([]);++ this.each(function(){+ // go in reverse order so anything added to the queue during the loop is ignored+ for ( var i = timers.length - 1; i >= 0; i-- )+ if ( timers[i].elem == this ) {+ if (gotoEnd)+ // force the next step to be the last+ timers[i](true);+ timers.splice(i, 1);+ }+ });++ // start the next in the queue if the last step wasn't forced+ if (!gotoEnd)+ this.dequeue();++ return this;+ }++});++var queue = function( elem, type, array ) {+ if ( elem ){++ type = type || "fx";++ var q = jQuery.data( elem, type + "queue" );++ if ( !q || array )+ q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );++ }+ return q;+};++jQuery.fn.dequeue = function(type){+ type = type || "fx";++ return this.each(function(){+ var q = queue(this, type);++ q.shift();++ if ( q.length )+ q[0].call( this );+ });+};++jQuery.extend({++ speed: function(speed, easing, fn) {+ var opt = speed && speed.constructor == Object ? speed : {+ complete: fn || !fn && easing ||+ jQuery.isFunction( speed ) && speed,+ duration: speed,+ easing: fn && easing || easing && easing.constructor != Function && easing+ };++ opt.duration = (opt.duration && opt.duration.constructor == Number ?+ opt.duration :+ jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;++ // Queueing+ opt.old = opt.complete;+ opt.complete = function(){+ if ( opt.queue !== false )+ jQuery(this).dequeue();+ if ( jQuery.isFunction( opt.old ) )+ opt.old.call( this );+ };++ return opt;+ },++ easing: {+ linear: function( p, n, firstNum, diff ) {+ return firstNum + diff * p;+ },+ swing: function( p, n, firstNum, diff ) {+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;+ }+ },++ timers: [],+ timerId: null,++ fx: function( elem, options, prop ){+ this.options = options;+ this.elem = elem;+ this.prop = prop;++ if ( !options.orig )+ options.orig = {};+ }++});++jQuery.fx.prototype = {++ // Simple function for setting a style value+ update: function(){+ if ( this.options.step )+ this.options.step.call( this.elem, this.now, this );++ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );++ // Set display property to block for height/width animations+ if ( this.prop == "height" || this.prop == "width" )+ this.elem.style.display = "block";+ },++ // Get the current size+ cur: function(force){+ if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )+ return this.elem[ this.prop ];++ var r = parseFloat(jQuery.css(this.elem, this.prop, force));+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;+ },++ // Start an animation from one number to another+ custom: function(from, to, unit){+ this.startTime = now();+ this.start = from;+ this.end = to;+ this.unit = unit || this.unit || "px";+ this.now = this.start;+ this.pos = this.state = 0;+ this.update();++ var self = this;+ function t(gotoEnd){+ return self.step(gotoEnd);+ }++ t.elem = this.elem;++ jQuery.timers.push(t);++ if ( jQuery.timerId == null ) {+ jQuery.timerId = setInterval(function(){+ var timers = jQuery.timers;++ for ( var i = 0; i < timers.length; i++ )+ if ( !timers[i]() )+ timers.splice(i--, 1);++ if ( !timers.length ) {+ clearInterval( jQuery.timerId );+ jQuery.timerId = null;+ }+ }, 13);+ }+ },++ // Simple 'show' function+ show: function(){+ // Remember where we started, so that we can go back to it later+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );+ this.options.show = true;++ // Begin the animation+ this.custom(0, this.cur());++ // Make sure that we start at a small width/height to avoid any+ // flash of content+ if ( this.prop == "width" || this.prop == "height" )+ this.elem.style[this.prop] = "1px";++ // Start by showing the element+ jQuery(this.elem).show();+ },++ // Simple 'hide' function+ hide: function(){+ // Remember where we started, so that we can go back to it later+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );+ this.options.hide = true;++ // Begin the animation+ this.custom(this.cur(), 0);+ },++ // Each step of an animation+ step: function(gotoEnd){+ var t = now();++ if ( gotoEnd || t > this.options.duration + this.startTime ) {+ this.now = this.end;+ this.pos = this.state = 1;+ this.update();++ this.options.curAnim[ this.prop ] = true;++ var done = true;+ for ( var i in this.options.curAnim )+ if ( this.options.curAnim[i] !== true )+ done = false;++ if ( done ) {+ if ( this.options.display != null ) {+ // Reset the overflow+ this.elem.style.overflow = this.options.overflow;++ // Reset the display+ this.elem.style.display = this.options.display;+ if ( jQuery.css(this.elem, "display") == "none" )+ this.elem.style.display = "block";+ }++ // Hide the element if the "hide" operation was done+ if ( this.options.hide )+ this.elem.style.display = "none";++ // Reset the properties, if the item has been hidden or shown+ if ( this.options.hide || this.options.show )+ for ( var p in this.options.curAnim )+ jQuery.attr(this.elem.style, p, this.options.orig[p]);+ }++ if ( done )+ // Execute the complete function+ this.options.complete.call( this.elem );++ return false;+ } else {+ var n = t - this.startTime;+ this.state = n / this.options.duration;++ // Perform the easing function, defaults to swing+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);+ this.now = this.start + ((this.end - this.start) * this.pos);++ // Perform the next step of the animation+ this.update();+ }++ return true;+ }++};++jQuery.extend( jQuery.fx, {+ speeds:{+ slow: 600,+ fast: 200,+ // Default speed+ def: 400+ },+ step: {+ scrollLeft: function(fx){+ fx.elem.scrollLeft = fx.now;+ },++ scrollTop: function(fx){+ fx.elem.scrollTop = fx.now;+ },++ opacity: function(fx){+ jQuery.attr(fx.elem.style, "opacity", fx.now);+ },++ _default: function(fx){+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;+ }+ }+});+// The Offset Method+// Originally By Brandon Aaron, part of the Dimension Plugin+// http://jquery.com/plugins/project/dimensions+jQuery.fn.offset = function() {+ var left = 0, top = 0, elem = this[0], results;++ if ( elem ) with ( jQuery.browser ) {+ var parent = elem.parentNode,+ offsetChild = elem,+ offsetParent = elem.offsetParent,+ doc = elem.ownerDocument,+ safari2 = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),+ css = jQuery.curCSS,+ fixed = css(elem, "position") == "fixed";++ // Use getBoundingClientRect if available+ if ( elem.getBoundingClientRect ) {+ var box = elem.getBoundingClientRect();++ // Add the document scroll offsets+ add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),+ box.top + Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));++ // IE adds the HTML element's border, by default it is medium which is 2px+ // IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }+ // IE 7 standards mode, the border is always 2px+ // This border/offset is typically represented by the clientLeft and clientTop properties+ // However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS+ // Therefore this method will be off by 2px in IE while in quirksmode+ add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );++ // Otherwise loop through the offsetParents and parentNodes+ } else {++ // Initial element offsets+ add( elem.offsetLeft, elem.offsetTop );++ // Get parent offsets+ while ( offsetParent ) {+ // Add offsetParent offsets+ add( offsetParent.offsetLeft, offsetParent.offsetTop );++ // Mozilla and Safari > 2 does not include the border on offset parents+ // However Mozilla adds the border for table or table cells+ if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )+ border( offsetParent );++ // Add the document scroll offsets if position is fixed on any offsetParent+ if ( !fixed && css(offsetParent, "position") == "fixed" )+ fixed = true;++ // Set offsetChild to previous offsetParent unless it is the body element+ offsetChild = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;+ // Get next offsetParent+ offsetParent = offsetParent.offsetParent;+ }++ // Get parent scroll offsets+ while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {+ // Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug+ if ( !/^inline|table.*$/i.test(css(parent, "display")) )+ // Subtract parent scroll offsets+ add( -parent.scrollLeft, -parent.scrollTop );++ // Mozilla does not add the border for a parent that has overflow != visible+ if ( mozilla && css(parent, "overflow") != "visible" )+ border( parent );++ // Get next parent+ parent = parent.parentNode;+ }++ // Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild+ // Mozilla doubles body offsets with a non-absolutely positioned offsetChild+ if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||+ (mozilla && css(offsetChild, "position") != "absolute") )+ add( -doc.body.offsetLeft, -doc.body.offsetTop );++ // Add the document scroll offsets if position is fixed+ if ( fixed )+ add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),+ Math.max(doc.documentElement.scrollTop, doc.body.scrollTop));+ }++ // Return an object with top and left properties+ results = { top: top, left: left };+ }++ function border(elem) {+ add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );+ }++ function add(l, t) {+ left += parseInt(l, 10) || 0;+ top += parseInt(t, 10) || 0;+ }++ return results;+};+++jQuery.fn.extend({+ position: function() {+ var left = 0, top = 0, results;++ if ( this[0] ) {+ // Get *real* offsetParent+ var offsetParent = this.offsetParent(),++ // Get correct offsets+ offset = this.offset(),+ parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();++ // Subtract element margins+ // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0+ offset.top -= num( this, 'marginTop' );+ offset.left -= num( this, 'marginLeft' );++ // Add offsetParent borders+ parentOffset.top += num( offsetParent, 'borderTopWidth' );+ parentOffset.left += num( offsetParent, 'borderLeftWidth' );++ // Subtract the two offsets+ results = {+ top: offset.top - parentOffset.top,+ left: offset.left - parentOffset.left+ };+ }++ return results;+ },++ offsetParent: function() {+ var offsetParent = this[0].offsetParent;+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )+ offsetParent = offsetParent.offsetParent;+ return jQuery(offsetParent);+ }+});+++// Create scrollLeft and scrollTop methods+jQuery.each( ['Left', 'Top'], function(i, name) {+ var method = 'scroll' + name;+ + jQuery.fn[ method ] = function(val) {+ if (!this[0]) return;++ return val != undefined ?++ // Set the scroll offset+ this.each(function() {+ this == window || this == document ?+ window.scrollTo(+ !i ? val : jQuery(window).scrollLeft(),+ i ? val : jQuery(window).scrollTop()+ ) :+ this[ method ] = val;+ }) :++ // Return the scroll offset+ this[0] == window || this[0] == document ?+ self[ i ? 'pageYOffset' : 'pageXOffset' ] ||+ jQuery.boxModel && document.documentElement[ method ] ||+ document.body[ method ] :+ this[0][ method ];+ };+});+// Create innerHeight, innerWidth, outerHeight and outerWidth methods+jQuery.each([ "Height", "Width" ], function(i, name){++ var tl = i ? "Left" : "Top", // top or left+ br = i ? "Right" : "Bottom"; // bottom or right++ // innerHeight and innerWidth+ jQuery.fn["inner" + name] = function(){+ return this[ name.toLowerCase() ]() ++ num(this, "padding" + tl) ++ num(this, "padding" + br);+ };++ // outerHeight and outerWidth+ jQuery.fn["outer" + name] = function(margin) {+ return this["inner" + name]() ++ num(this, "border" + tl + "Width") ++ num(this, "border" + br + "Width") ++ (margin ?+ num(this, "margin" + tl) + num(this, "margin" + br) : 0);+ };++});})();
@@ -0,0 +1,156 @@+/* + * jQuery history plugin + * + * Copyright (c) 2006 Taku Sano (Mikage Sawatari) + * Licensed under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + * Modified by Lincoln Cooper to add Safari support and only call the callback once during initialization + * for msie when no initial hash supplied. + * API rewrite by Lauris Bukðis-Haberkorns + */ + +(function($) { + +function History() +{ + this._curHash = ''; + this._callback = function(hash){}; +}; + +$.extend(History.prototype, { + + init: function(callback) { + this._callback = callback; + this._curHash = location.hash; + + if($.browser.msie) { + // To stop the callback firing twice during initilization if no hash present + if (this._curHash == '') { + this._curHash = '#'; + } + + // add hidden iframe for IE + $("body").prepend('<iframe id="jQuery_history" style="display: none;"></iframe>'); + var iframe = $("#jQuery_history")[0].contentWindow.document; + iframe.open(); + iframe.close(); + iframe.location.hash = this._curHash; + } + else if ($.browser.safari) { + // etablish back/forward stacks + this._historyBackStack = []; + this._historyBackStack.length = history.length; + this._historyForwardStack = []; + this._isFirst = true; + this._dontCheck = false; + } + this._callback(this._curHash.replace(/^#/, '')); + setInterval(this._check, 100); + }, + + add: function(hash) { + // This makes the looping function do something + this._historyBackStack.push(hash); + + this._historyForwardStack.length = 0; // clear forwardStack (true click occured) + this._isFirst = true; + }, + + _check: function() { + if($.browser.msie) { + // On IE, check for location.hash of iframe + var ihistory = $("#jQuery_history")[0]; + var iframe = ihistory.contentDocument || ihistory.contentWindow.document; + var current_hash = iframe.location.hash; + if(current_hash != $.history._curHash) { + + location.hash = current_hash; + $.history._curHash = current_hash; + $.history._callback(current_hash.replace(/^#/, '')); + + } + } else if ($.browser.safari) { + if (!$.history._dontCheck) { + var historyDelta = history.length - $.history._historyBackStack.length; + + if (historyDelta) { // back or forward button has been pushed + $.history._isFirst = false; + if (historyDelta < 0) { // back button has been pushed + // move items to forward stack + for (var i = 0; i < Math.abs(historyDelta); i++) $.history._historyForwardStack.unshift($.history._historyBackStack.pop()); + } else { // forward button has been pushed + // move items to back stack + for (var i = 0; i < historyDelta; i++) $.history._historyBackStack.push($.history._historyForwardStack.shift()); + } + var cachedHash = $.history._historyBackStack[$.history._historyBackStack.length - 1]; + if (cachedHash != undefined) { + $.history._curHash = location.hash; + $.history._callback(cachedHash); + } + } else if ($.history._historyBackStack[$.history._historyBackStack.length - 1] == undefined && !$.history._isFirst) { + // back button has been pushed to beginning and URL already pointed to hash (e.g. a bookmark) + // document.URL doesn't change in Safari + if (document.URL.indexOf('#') >= 0) { + $.history._callback(document.URL.split('#')[1]); + } else { + $.history._callback(''); + } + $.history._isFirst = true; + } + } + } else { + // otherwise, check for location.hash + var current_hash = location.hash; + if(current_hash != $.history._curHash) { + $.history._curHash = current_hash; + $.history._callback(current_hash.replace(/^#/, '')); + } + } + }, + + load: function(hash) { + var newhash; + + if ($.browser.safari) { + newhash = hash; + } else { + newhash = '#' + hash; + location.hash = newhash; + } + this._curHash = newhash; + + if ($.browser.msie) { + var ihistory = $("#jQuery_history")[0]; // TODO: need contentDocument? + var iframe = ihistory.contentWindow.document; + iframe.open(); + iframe.close(); + iframe.location.hash = newhash; + this._callback(hash); + } + else if ($.browser.safari) { + this._dontCheck = true; + // Manually keep track of the history values for Safari + this.add(hash); + + // Wait a while before allowing checking so that Safari has time to update the "history" object + // correctly (otherwise the check loop would detect a false change in hash). + var fn = function() {$.history._dontCheck = false;}; + window.setTimeout(fn, 200); + this._callback(hash); + // N.B. "location.hash=" must be the last line of code for Safari as execution stops afterwards. + // By explicitly using the "location.hash" command (instead of using a variable set to "location.hash") the + // URL in the browser and the "history" object are both updated correctly. + location.hash = newhash; + } + else { + this._callback(hash); + } + } +}); + +$(document).ready(function() { + $.history = new History(); // singleton instance +}); + +})(jQuery);
@@ -0,0 +1,134 @@+/* ------------------------------------------------------------------------- */++function installCollapsers ()+{+ $('.collapser').click(togglePanel)+}++function togglePanel (show)+{+ var button = $(this)+ var panel = $(button.attr('target'))++ if (button.hasClass('open') && show !== true)+ panelClose(button, panel)+ else if (show !== false)+ panelOpen(button, panel)+}++function panelClose (button, panel)+{+ panel.fadeOut()+ button.removeClass('open')+ panel.removeClass('open')+}++function panelOpen (button, panel)+{+ panel.addClass('open')+ button.addClass('open')+ panel.fadeIn()+}++function showPanel ()+{+ togglePanel.call(this, true)+}++function hidePanel ()+{+ togglePanel.call(this, false)+}++/* ------------------------------------------------------------------------- */++function installOptions()+{+ $('.option').click(setOpted)+}++function setOpted ()+{+ var button = $(this)+ var all = $(this.parentNode).children()++ all.removeClass('opted')+ button.addClass('opted')+}++/* ------------------------------------------------------------------------- */++function installSmartFields ()+{+ $('input')+ .focus(fieldFocus)+ .blur(fieldBlur)+ .change(fieldUpdate)+ .keyup(fieldUpdate)+ .map(fieldUpateTarget)+}++function fieldFocus ()+{+ var input = $(this)++ // Empty the field when it has no user content.+ if (!input.hasClass('full'))+ input.val('')+}++function fieldUpdate ()+{+ var input = $(this)++ input.val()+ ? input.addClass('full')+ : input.removeClass('full')++ fieldUpateTarget.call(input)+}++function fieldBlur ()+{+ // Restore description text when still/again empty.+ var input = $(this)+ if (!input.val())+ input.val(input.attr('name'))+}++function fieldUpateTarget ()+{+ var target = $(this).attr('target')+ var others = $('input')++ if (!target)+ return+ var targets = target.split(/,\s*/)+ if (!targets.length)+ return++ // For all separate targets.+ for (var t = 0; t < targets.length; t++) {++ // Get all non-full inputs with same target.+ var empty = others.filter(+ function (a)+ {+ var elem = $(others[a])+ return elem.attr('target').match(targets[t])+ && !elem.hasClass('full')+ }+ )++ // Set enabled/disabled of target based amount of non-full inputs.+ if (empty.length)+ $(targets[t]).addClass('disabled')+ else+ $(targets[t]).removeClass('disabled')+ }++ return true;+}++/* ------------------------------------------------------------------------- */+
@@ -0,0 +1,20 @@+String.prototype.interpolate =+ function interpolate(vars) + {+ return this.replace(/\$([0-9a-z-A-Z_]+)/g,+ function (m, id)+ { + return (typeof vars[id] === "undefined") ? m : vars[id]+ }+ )+ }++String.prototype.asHTML =+ function asHTML () + {+ return this+ .replace(/\&/g, '&')+ .replace(/</g, '<')+ .replace(/>/g, '>')+ }+
@@ -0,0 +1,143 @@+<html>++<head>++ <link rel="stylesheet" type="text/css" href="style/main.css"></link>+ <link rel="stylesheet" type="text/css" href="style/page.css"></link>+ <link rel="stylesheet" type="text/css" href="style/ui.css"></link>+ <link rel="stylesheet" type="text/css" href="style/viewer.css"></link>+ <link rel="stylesheet" type="text/css" href="style/plugins.css"></link>++ <script type="text/javascript" src="js/jquery-1.2.6.js"></script>+ <script type="text/javascript" src="js/jquery.history.js"></script>+ <script type="text/javascript" src="js/utils.js"></script>+ <script type="text/javascript" src="js/ui.js"></script>+ <script type="text/javascript" src="js/app.js"></script>++</head>++<body>++ <table cellpadding="0" cellspacing="0" class="page">+ <tbody>+ <tr>+ <td class="col0 row0"></td>+ <td class="col1 row0"></td>+ <td class="col2 row0"> </td>+ <td class="col3 row0"></td>+ <td class="col4 row0"></td>+ </tr>+ <tr>+ <td class="col0 row1"></td>+ <td colspan="3" rowspan="3" id="main">++<!-- ====================================================================== -->++ <div id="ui">++ <!-- info section -->+ <div id="info">+ document: <span id="document"></span>+ revision: <span id="revision"></span>+ <!-- author: <span id="author"></span> -->+ user: <span id="user"></span>+ </div>++ <!-- toolbar section -->+ <div id="toolbar">+ <a id="auth-btn" class="collapser" target="#auth">login</a>+ <a id="signup-btn" class="collapser" target="#signup">signup</a>+ <a id="format-btn" class="collapser" target="#format">format</a>+ <a id="history-btn" class="collapser" target="#history">history</a>+ <a id="edit-btn" class="collapser" target="#editor">edit</a>+ </div>++ <!-- auth section -->+ <div id="auth">+ <input id="user-ui" target="#logout-btn, #save-btn, #delete-btn" type="text"></input>+ <input name="username" target="#login-btn" id="username" type="text" value="username"></input>+ <input name="password" target="#login-btn" id="password" type="password" value="password"></input>+ <a id="login-btn">login</a>+ <a id="logout-btn">logout</a>+ <div id="login-status" class="status"> </div>+ </div>++ <!-- signup section -->+ <div id="signup">+ <input name="username" id="su-username" target="#create-account-btn" type="text" value="username"></input>+ <input name="password" id="su-password" target="#create-account-btn" type="password" value="password"></input>+ <a id="create-account-btn">create account</a>+ <div id="signup-status" class="status"> </div>+ </div>++ <!-- format section -->+ <div id="format">+ <span>view format:+ <a id="txt-btn" class="option">txt</a>+ <a id="html-btn" class="option opted">html</a>+ <a id="latex-btn" class="option">latex</a>+ <a id="adt-btn" class="option">adt</a>+ </span>+ <span>open as:+ <a id="pdf-btn" >pdf</a>+ <a id="print-btn">print</a>+ <a id="src-btn" >source</a>+ </span>+ </div>++ <!-- history section -->+ <div id="history"></div>++ <!-- editor section -->+ <div id="editor">+ <textarea id="editField" cols="40"></textarea>+ <input id="change" name="change description"+ type="text" target="#save-btn, #delete-btn" value="change description"></input>+ <a id="save-btn">save</a>+ <a id="preview-btn">preview</a>+ <a id="delete-btn">delete</a>+ <div id="edit-status" class="status"> </div>+ </div>++ </div>++<!-- ====================================================================== -->++ <div id="viewer">++ <a id="full-btn" class="collapser open" target="#ui">toggle toolbar</a>+ <img id="loading" src="img/loading.gif"></img>++ <!-- viewer section -->+ <div id="rich-viewer"></div>+ <pre id="plain-viewer"></pre>++ </div>++<!-- ====================================================================== -->++ </td>+ <td class="col4 row1"></td>+ </tr>+ <tr>+ <td class="col0 row2"> </td>+ <td class="col4 row2"></td>+ </tr>+ <tr>+ <td class="col0 row3"></td>+ <td class="col4 row3"></td>+ </tr>+ <tr>+ <td class="col0 row4"></td>+ <td class="col1 row4"></td>+ <td class="col2 row4"></td>+ <td class="col3 row4"></td>+ <td class="col4 row4"></td>+ </tr>+ </tbody>+ </table>++</body>++</html>+
@@ -0,0 +1,15 @@+body {+ background-color : #666;+ background-image : url('../img/stripes.png');+ padding-top : 4em;+ overflow-y : scroll;+}++#logo {+ position : absolute;+ z-index : 10;+ top : 1em;+ left : 58em;+ display : none;+}+
@@ -0,0 +1,56 @@+.page {+ margin : -3.0em auto 2em auto;+}++.page .col0,+.page .col4 {+ width : 80px;+}++.page .row0.col1,+.page .row0.col3,+.page .row4.col1,+.page .row4.col3 {+ width : 160px;+}++.page .row1.col0,+.page .row1.col0,+.page .row3.col4,+.page .row3.col4 {+ height : 160px;+}++.page .row0,+.page .row4 {+ height : 80px;+}++.page .row0.col0 { background : url('../img/shadow00.png') }+.page .row0.col1 { background : url('../img/shadow01.png') }+.page .row0.col2 { background : url('../img/shadow02.png') }+.page .row0.col3 { background : url('../img/shadow03.png') }+.page .row0.col4 { background : url('../img/shadow04.png') }++.page .row1.col0 { background : url('../img/shadow10.png') }+.page .row1.col4 { background : url('../img/shadow14.png') }+.page .row2.col0 { background : url('../img/shadow20.png') }+.page .row2.col4 { background : url('../img/shadow24.png') }+.page .row3.col0 { background : url('../img/shadow30.png') }+.page .row3.col4 { background : url('../img/shadow34.png') }++.page .row4.col0 { background : url('../img/shadow40.png') }+.page .row4.col1 { background : url('../img/shadow41.png') }+.page .row4.col2 { background : url('../img/shadow42.png') }+.page .row4.col3 { background : url('../img/shadow43.png') }+.page .row4.col4 { background : url('../img/shadow44.png') }++/* page background */++#main {+ width : 54em;+ border : solid 8px #fff;+ opacity : 0.7;+ background : #ddd;+}+
@@ -0,0 +1,68 @@+/* ---- hscolour ----------------------------------------------------------- */++#rich-viewer pre {+ background : #fff;+ padding : 2em;+ border-top : solid 2px #aaa;+ border-bottom : solid 2px #aaa;+ margin-bottom : 1em;+}++.varop,+.keyglyph {+ color : #960;+}++.definition {+ color : #005;+ font-weight : bold;+}++.varid {+ color : #444;+}++.keyword {+ font-weight : bold;+}++.comment {+ color : #44f;+}++.conid {+ color : #000;+}++.num {+ color : #00a;+}++.str {+ color : #a00;+}++/* ---- latex formula ------------------------------------------------------ */++#rich-viewer img.formula {+ float : none;+}++/* ---- table of contents -------------------------------------------------- */++#rich-viewer .toc {+ border-top : solid 2px #fff;+ border-bottom : solid 2px #fff;+ margin : 3em;+ padding : 1.4em;+}++#rich-viewer .toc h2 {+ padding-bottom : 1em;+}++#rich-viewer .toc span {+ amargin-top : -10;+ afloat : right;+}+
@@ -0,0 +1,226 @@+//{ for syntax highlighting css-like in vim++panelBg = #d6d6d6+uiFont = "Helvetica Neue", Helvetica, Arial, sans-serif++link = #b47+linkHover = #305+linkDisabled = #999++collapserClosed = #999+collapserOpened = #305++opter = #999+optedBg = #fff+optionBgHover = #ddd++#ui:++ & > div:+ background : $panelBg url('../img/shadow42.png') repeat-x 0 (-30px)+ padding : 0.8em+ border-bottom : solid 2px #fff++ *:+ font-family : $uiFont++.find:+ border : solid 8px #a47+ position : fixed++#format, #auth, #signup, #history, #editor:+ display : none++#ui:++ a:+ margin-right : 0.6em+ margin-bottom : 0.4em+ padding : 0.4em++ color : $link+ font-size : 1.0em+ text-decoration : none++ cursor : pointer++ &:hover:+ color : $linkHover++ &.disabled:+ color : $linkDisabled+ cursor : default++ &.collapser:+ &:before:+ color : $collapserClosed+ content : '▸ '+ &.open:before:+ color : $collapserOpened+ content : '▾ '++ &.option:+ &.opted:+ background : $optedBg+ cursor : default+ &:before:+ color : #305+ content : '+ '+ &:hover:+ background : $optedBg+ &:before:+ color : $opter+ content : '+ '+ &:hover:+ background : $optionBgHover++ input:+ background : #fff url('../img/shadow02.png') repeat-x 0 -20px+ padding : 0.2em+ border : none+ color : #555+ font->+ style : italic+ size : 0.9em+ &:focus:+ background : #fff url('../img/shadow02.png') repeat-x 0 -15px+ color : #a47+ font-style : normal+ &.full:+ color : #a47+ font-style : normal++ textarea:+ background : #bbb url('../img/shadow24.png') repeat-y (-30px) 0+ width : 100%+ min-height : 320px+ border : none+ margin-bottom : 1.8em+ font->+ family : 'Courier', Fixed+ size : 0.8em+ line-height : 1.3em++ .status:+ padding : 0.2em+ color : #080+ font-size : 1.0em+ text-align : right+ margin-top : -1.65em++ &.error:+ color : #800++ span:+ font-size : 0.8em+ font-weight : normal++ #history:+ background : #ccc+ padding : 1em+ border-bottom : solid 2px #fff+ display : none++ table:+ width : 100%+ padding : 0.5em+ font-size : 0.7em+ line-height : 1.3em++ td, th:+ padding : 0.4em+ padding-left : 2em+ vertical-align : top+ font-size : 1.1em++ .current td:+ background : #fff++ td:+ background : #eee+ text-align : left+ border-top : solid 1px #ccc+ & + td:+ background : #eee url('../img/shadow24.png') repeat-y (-40px) 0+ padding-left : 2em++ th:+ background : #ddd+ text-align : left+ border-bottom : solid 1px #bbb++ #author:+ width : 200px++ #modified:+ width : 220px++ a:+ color : #b47+ text-decoration : none+ cursor : pointer+ &:hover:+ color : #305++ #info:+ font-size : 0.8em+ color : #005+ font-style : italic+ span:+ color : #305+ font-style : normal+ font-weight : bold+ padding-right : 1em+ i:+ color : #888+ font-weight : normal++ #auth:+ input:+ width : 14em+ #user-ui:+ display : none+ #username:+ &, #password:+ margin-right : 1em++ #signup:+ input:+ width : 14em+ #su-username:+ &, #su-password:+ margin-right : 1em++ #editor #change:+ margin-bottom : 1em+ width : 100%+ display : block++ #format:+ span:+ color : #305+ font-size : 1.0em+ margin-right : 2em+ a.option:+ margin->+ left : 0.4em+ right : 0++#full-btn:+ margin->+ top : 1em+ left : 1em+ float : left+ color : #222+ opacity : 0.5+ font-size : 0.8em+ font-family : $uiFont+ text-decoration : none+ cursor : pointer++#loading:+ margin->+ top : 0.8em+ right : 1em+ float : right+
@@ -0,0 +1,161 @@+#plain-viewer {+ padding : 3em;+ padding-top : 6em;+ background : #fff url('../img/shadow42.png') repeat-x 0 -25px;+ white-space : pre-wrap;+ font-family : 'Courier';+ font-size : 0.8em;+ line-height : 1.3em;+ margin : 0;+}++/* --------------------------------- */++#rich-viewer {+ padding : 3em;+ padding-top : 6em;+ min-height : 120px;+ background : #eee url('../img/shadow42.png') repeat-x 0 -15px;+}++/* All headers. */++#rich-viewer h1,+#rich-viewer h2,+#rich-viewer h3,+#rich-viewer h4,+#rich-viewer h5,+#rich-viewer h6 {+ bborder : dotted 1px blue;+ font-weight : normal;+ font-family : 'Georgia';+ color : #005;+}++/* --------------------------------- */++/*+ * Document header consisting out of a possible title, subtitle and meta+ * information like author name and location.+ */++#rich-viewer .header {+ margin-bottom : 4em;+}++#rich-viewer h1 {+ font-size : 2.2em;+ font-style : italic;+ text-align : center;+}++#rich-viewer h1.sub {+ font-size : 1.4em;+ margin-bottom : 2em;+}++#rich-viewer .annotation {+ font-style : italic;+ text-align : center;+}++#rich-viewer .author { font-size : 1.3em; }+#rich-viewer .email { font-size : 1.1em; }++#rich-viewer .abstract {+ font-size : 0.9em;+ width : 75%;+ margin-left : 6em;+ margin-bottom : 4em;+}++#rich-viewer .abstract h2 {+ text-align : center;+ padding-bottom : 1em;+}++#rich-viewer .caption-label {+ font-size : 0.85em;+ text-align : center;+ padding-bottom : 0.6em;+}++/* --------------------------------- */++/* Sections. */++#rich-viewer div {+ bborder : dotted 1px red;+}++#rich-viewer h3 span,+#rich-viewer h4 span,+#rich-viewer h5 span,+#rich-viewer h6 span {+ color : #305;+ margin : 0;+ margin-right : 0.6em;+}++/* First level section title. */++#rich-viewer h3 {+ font-size : 1.4em;+ dpadding-top : 1em;+ margin-bottom : 1em;+ border-bottom : solid 2px #eee;+}++/* Second level section title. */++#rich-viewer h4 {+ font-size : 1.2em;+ padding-top : 0.5em;+ margin-bottom : 0.5em;+ border-bottom : solid 1px #eee;+}++/* Third level section title. */++#rich-viewer h5 {+ font-size : 1.0em;+ padding-top : 0.3em;+ margin-bottom : 0.3em;+ border-bottom : solid 1px #eee;+}++/* --------------------------------- */++#rich-viewer p {+ bborder : dotted 1px blue;+ font-family : 'Georgia';+ font-size : 0.9em;+ line-height : 1.3em;+}++#rich-viewer img {+ float : right;+ clear : both;+ margin : 1em;+}++#rich-viewer ul,+#rich-viewer ol {+ padding-left : 2em;+}++#rich-viewer li {+ sborder : solid 1px red;+}++#rich-viewer a {+ color : #a47;+ cursor : pointer;+ text-decoration : none;+}++#rich-viewer a:hover {+ background-color : white;+ color : #b47;+}+