diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Revision history for reani
+
+## 0.1.0.0 -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/reanimate.cabal b/reanimate.cabal
new file mode 100644
--- /dev/null
+++ b/reanimate.cabal
@@ -0,0 +1,79 @@
+-- Initial reani.cabal generated by cabal init.  For further documentation,
+--  see http://haskell.org/cabal/users-guide/
+
+name:                reanimate
+version:             0.1.0.0
+-- synopsis:
+-- description:
+license:             PublicDomain
+author:              David Himmelstrup
+maintainer:          lemmih@gmail.com
+category:            Graphics
+synopsis:            Animation library based on SVGs.
+homepage:            https://github.com/Lemmih/reanimate
+build-type:          Simple
+extra-source-files:  ChangeLog.md
+cabal-version:       >=1.10
+
+description:
+  Animation library based on SVGs. Can import (and manipulate) SVGs from
+  LaTeX and diagrams. Exports gifs, mp4s, and more. Ships with a webbased
+  viewer and auto-reloader.
+
+
+data-files:           viewer/build/*.js
+                      viewer/build/*.html
+                      viewer/build/static/js/2.772a56e7.chunk.js
+                      viewer/build/static/js/main.db22f45d.chunk.js
+                      viewer/build/static/js/runtime~main.9eb600ee.js
+                      viewer/build/static/css/main.6efe09fd.chunk.css
+
+Source-Repository head
+    Type:      git
+    Location:  git://github.com/lemmih/reanimate.git
+
+library
+  hs-source-dirs:     src
+  default-language:   Haskell2010
+  default-extensions: PackageImports
+  exposed-modules:    Reanimate.Monad
+                      Reanimate.Render
+                      Reanimate.Examples
+                      Reanimate.Combinators
+                      Reanimate.LaTeX
+                      Reanimate.Svg
+                      Reanimate.Diagrams
+                      Reanimate.Transform
+                      Reanimate.Driver
+                      Reanimate.Misc
+  other-modules:      Reanimate.Svg.NamedColors
+                      Reanimate.Cache
+                      Paths_reanimate
+  build-depends:       base >=4.10 && <4.13,
+                       time, text, unix, filepath, process, directory,
+                       containers, reanimate-svg >= 0.7.0.0, xml, bytestring, lens, linear, mtl, matrix,
+                       JuicyPixels, attoparsec, parallel, diagrams, diagrams-svg,
+                       diagrams-core, diagrams-lib, diagrams-contrib,
+                       svg-builder, matrices, cubicbezier, palette, hinotify, websockets,
+                       hashable
+
+Flag gtk-viewer
+  Description: Enable gtk-based viewer
+  Default:     False
+
+Flag server
+  Description: Enable rendering server
+  Default:     False
+
+executable reanimate-server
+  if flag(server)
+    buildable:        True
+  else
+    buildable:        False
+  default-language:   Haskell2010
+  hs-source-dirs:     server, src
+  main-is:            Main.hs
+  other-modules:      Reanimate.Misc
+                      Cache
+  build-depends:      base >=4.10 && <4.13, text, websockets, process, filepath, directory,
+                      containers, hashable, time
diff --git a/server/Cache.hs b/server/Cache.hs
new file mode 100644
--- /dev/null
+++ b/server/Cache.hs
@@ -0,0 +1,30 @@
+module Cache (lookupCache, insertCache) where
+
+import Control.Concurrent
+import Control.Exception
+import qualified Data.IntMap as M
+import System.Directory
+import System.FilePath
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
+import Data.Text (Text)
+import Data.Hashable
+
+valueFilePath :: Text -> IO FilePath
+valueFilePath key = do
+  tmp <- getTemporaryDirectory
+  return $ tmp </> "reanimate" ++ show (hash key) <.> "svgs"
+
+
+insertCache :: Text -> [Text] -> IO ()
+insertCache key value = do
+  cacheFile <- valueFilePath key
+  T.writeFile cacheFile (T.unlines value)
+
+lookupCache :: Text -> IO (Maybe [Text])
+lookupCache key = do
+    cacheFile <- valueFilePath key
+    do svgs <- T.lines <$> T.readFile cacheFile
+       evaluate (svgs)
+       return (Just svgs)
+     `catch` \SomeException{} -> return Nothing
diff --git a/server/Main.hs b/server/Main.hs
new file mode 100644
--- /dev/null
+++ b/server/Main.hs
@@ -0,0 +1,117 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Main where
+
+import Control.Concurrent
+import Control.Exception
+import Control.Monad
+import Data.Monoid
+import Data.Time
+import Network.WebSockets
+import Control.Monad.Fix
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
+import qualified Data.Map as Map
+
+import Cache
+import Reanimate.Misc
+
+main :: IO ()
+main = do
+  runServerWith "127.0.0.1" 9161 opts $ \pending -> do
+  conn <- acceptRequest pending
+  thread <- newEmptyMVar
+  forkPingThread conn 30
+  forever $ do
+    msg <- receiveData conn :: IO T.Text
+    stopWorker conn thread
+    putMVar thread =<< forkIO (generateResponse conn msg >> tryTakeMVar thread >> return ())
+  where
+    opts = defaultConnectionOptions
+      { connectionCompressionOptions = PermessageDeflateCompression defaultPermessageDeflate }
+
+stopWorker conn mvar = do
+  mbTid <- tryTakeMVar mvar
+  case mbTid of
+    Nothing -> return ()
+    Just tid -> do
+      putStrLn "Interrupt"
+      killThread tid
+      sendTextData conn $ T.pack $ "Error" ++ "Reset"
+
+generateResponse conn msg = do
+  mbCached <- lookupCache msg
+  case mbCached of
+    Just svgs -> do
+      putStrLn "Returning cached svg."
+      sendTextDatas conn (T.pack "Success!" : svgs)
+      sendTextData conn (T.pack "Done")
+    Nothing ->
+      withTempFile ".exe" $ \tmpExecutable ->
+      withTempFile ".hs" $ \tmpSource ->
+      withTempDir $ \tmpDir -> do
+        T.writeFile tmpSource $ T.unlines
+          ["{-# LANGUAGE Arrows, OverloadedStrings, CPP #-}"
+          ,"module Main where"
+          ,"import Reanimate.Monad"
+          ,"import           Reanimate.Combinators"
+          ,"import           Reanimate.LaTeX"
+          ,"import           Codec.Picture.Types"
+          ,"import           Reanimate.Svg"
+          ,"import           Reanimate.Render"
+          ,"import           Data.Monoid"
+          ,"import           Graphics.Svg as S"
+          ,"main = renderSvgs animation " <> T.pack (show tmpDir)
+          ,"#line 1 \"animation.hs\""
+          ] <> msg
+        putStrLn $ "Compiling program:\n" ++ T.unpack msg
+        sendTextData conn (T.pack "Compiling")
+        ret <- timeIt "compile" $
+                runCmd_ "stack" $ ["ghc", "--"] ++ ghcOptions ++ [tmpSource, "-o", tmpExecutable]
+        case ret of
+          Left err -> do
+            sendTextData conn $ T.pack $ "Error" ++ unlines (drop 3 (lines err))
+          Right{} -> do
+            queue <- newChan
+            tid <- forkIO $ forever $ sendTextData conn =<< readChan queue
+            sendTextData conn (T.pack "Rendering")
+            flip onException (killThread tid) $
+              timeIt "render" $ withTimeout queue conn 60 $ do
+              getFrame <- runCmdLazy tmpExecutable ["+RTS", "-N", "-M50M", "-RTS"]
+              flip fix [] $ \loop acc -> do
+                frame <- getFrame
+                case frame of
+                  Left "" -> do
+                    writeChan queue (T.pack "Done")
+                    insertCache msg (reverse acc)
+                  Left err -> do
+                    _ <- getChanContents queue
+                    writeChan queue $ T.pack $ "Error" ++ err
+                  Right frame -> do
+                    writeChan queue frame
+                    loop (frame : acc)
+
+ghcOptions :: [String]
+ghcOptions = ["-rtsopts", "--make", "-threaded", "-O"]
+
+withTimeout queue conn t action = do
+  finished <- newEmptyMVar
+  worker <- forkIO (action >> putMVar finished ())
+  timer <- forkIO $ do
+    threadDelay (10^6 * t)
+    putMVar finished ()
+    putStrLn "Timeout"
+    killThread worker
+    _ <- getChanContents queue
+    writeChan queue $ T.pack $ "Error" ++ "Timeout"
+
+  takeMVar finished `onException` do
+    killThread worker
+    killThread timer
+
+timeIt :: String -> IO a -> IO a
+timeIt label fn = do
+  t1 <- getCurrentTime
+  a <- fn
+  t2 <- getCurrentTime
+  putStrLn $ label ++ ": " ++ show (diffUTCTime t2 t1)
+  return a
diff --git a/src/Reanimate/Cache.hs b/src/Reanimate/Cache.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Cache.hs
@@ -0,0 +1,81 @@
+module Reanimate.Cache
+  ( cacheMem
+  , cacheDisk
+  , cacheDiskSvg
+  , cacheDiskLines
+  ) where
+
+import           Control.Exception
+import           Data.Hashable
+import           Data.IORef
+import           Data.Map           (Map)
+import qualified Data.Map           as Map
+import           Data.Text          (Text)
+import qualified Data.Text          as T
+import qualified Data.Text.Encoding as T
+import qualified Data.Text.IO       as T
+import           Graphics.SvgTree   (Tree (..), parseSvgFile, unparse)
+import           Reanimate.Monad    (renderTree)
+import           Reanimate.Svg      (unbox)
+import Text.XML.Light ( Content(..), parseXML )
+import           System.Directory
+import           System.FilePath
+import           System.IO.Unsafe
+
+-- Memory cache and disk cache
+
+cacheDisk :: (T.Text -> Maybe a) -> (a -> T.Text) -> (Text -> IO a) -> (Text -> IO a)
+cacheDisk parse render gen key = do
+    root <- getXdgDirectory XdgCache "reanimate"
+    createDirectoryIfMissing True root
+    let path = root </> show (hash key)
+    hit <- doesFileExist path
+    if hit
+      then do
+        inp <- T.readFile path
+        case parse inp of
+          Nothing -> do
+            let tmp = path <.> "tmp"
+            new <- gen key
+            T.writeFile tmp (render new)
+            renameFile tmp path
+            return new
+          Just val -> pure val
+      else do
+        let tmp = path <.> "tmp"
+        new <- gen key
+        T.writeFile tmp (render new)
+        renameFile tmp path
+        return new
+
+cacheDiskSvg :: (Text -> IO Tree) -> (Text -> IO Tree)
+cacheDiskSvg = cacheDisk parse render
+  where
+    parse txt = case parseXML txt of
+      [Elem t] -> Just (unparse t)
+      _   -> Nothing
+    render = T.pack . renderTree
+
+cacheDiskLines :: (Text -> IO [Text]) -> (Text -> IO [Text])
+cacheDiskLines = cacheDisk parse render
+  where
+    parse = Just . T.lines
+    render = T.unlines
+
+
+{-# NOINLINE cache #-}
+cache :: IORef (Map Text Tree)
+cache = unsafePerformIO (newIORef Map.empty)
+
+cacheMem :: (Text -> IO Tree) -> (Text -> IO Tree)
+cacheMem gen key = do
+  store <- readIORef cache
+  case Map.lookup key store of
+    Just svg -> return svg
+    Nothing -> do
+      svg <- gen key
+      case svg of
+        -- None usually indicates that latex or another tool was misconfigured. In this case,
+        -- don't store the result.
+        None -> pure None
+        _ -> atomicModifyIORef cache (\store -> (Map.insert key svg store, svg))
diff --git a/src/Reanimate/Combinators.hs b/src/Reanimate/Combinators.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Combinators.hs
@@ -0,0 +1,40 @@
+{-# LANGUAGE Arrows            #-}
+{-# LANGUAGE OverloadedStrings #-}
+module Reanimate.Combinators where
+
+import           Control.Arrow
+import           Data.Fixed      (mod')
+import           Data.Monoid     ((<>))
+import           Data.Text       (Text, pack)
+import qualified Data.Text       as T
+
+-- import           Reanimate.Arrow
+
+type Path = [(Double, Double)]
+
+approxFnData :: Int -> (Double -> (Double, Double)) -> Path
+approxFnData steps fn =
+  fn 0 : [ fn (fromIntegral n/fromIntegral steps) | n <- [0..steps] ]
+
+morphPath :: Path -> Path -> Double -> Path
+morphPath src dst idx = zipWith worker src dst
+  where
+    worker (x1, y1) (x2, y2) =
+      (x1 + (x2-x1)*idx
+      ,y1 + (y2-y1)*idx)
+
+-- signalSigmoid :: Double -> Double -> Double -> Ani Double
+-- signalSigmoid steepness from to = proc () -> do
+--   s <- signal 0 1 -< ()
+--   let s' = (s-0.5)*steepness
+--   let sigmoid = exp s' / (exp s'+1)
+--       ret = (from + (to-from)*sigmoid)
+--   returnA -< ret
+--
+-- signalSCurve :: Double -> Double -> Double -> Ani Double
+-- signalSCurve steepness from to = proc () -> do
+--   s <- signal 0 1 -< ()
+--   let s' = if s < 0.5
+--               then 0.5 * (2*s)**steepness
+--               else 1-0.5 * (2 - 2*s)**steepness
+--   returnA -< from + (to-from)*s'
diff --git a/src/Reanimate/Diagrams.hs b/src/Reanimate/Diagrams.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Diagrams.hs
@@ -0,0 +1,35 @@
+{-# LANGUAGE FlexibleContexts          #-}
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE OverloadedStrings         #-}
+{-# LANGUAGE PackageImports            #-}
+{-# LANGUAGE TypeFamilies              #-}
+module Reanimate.Diagrams
+  ( renderDiagram
+  , SvgDiagram
+  ) where
+
+import qualified Data.ByteString.Lazy  as BL
+import qualified Diagrams.Backend.SVG  as D
+import qualified Diagrams.Core.Compile as D
+import qualified Diagrams.Core.Types   as D
+import qualified Diagrams.Size         as D
+import           Graphics.SvgTree      (Document (..), Tree (..), defaultSvg,
+                                        elements, loadSvgFile, parseSvgFile,
+                                        xmlOfDocument)
+import qualified Graphics.Svg.Core as Svg
+import           Linear.V2
+import           Reanimate.Svg         (unbox)
+
+import           Diagrams.Prelude
+import qualified Diagrams.Prelude      as D
+
+renderDiagram :: SvgDiagram -> Tree
+renderDiagram d =
+    case parseSvgFile "" (BL.toStrict $ Svg.renderBS (renderDia D.SVG opts d)) of
+      Nothing  -> error "Malformed svg"
+      Just svg -> unbox svg
+  where
+    -- opts = SVGOptions (mkSizeSpec (V2 Nothing Nothing)) Nothing "" [] False
+    opts = D.SVGOptions absolute Nothing "" [] False
+
+type SvgDiagram = D.Diagram D.SVG
diff --git a/src/Reanimate/Driver.hs b/src/Reanimate/Driver.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Driver.hs
@@ -0,0 +1,80 @@
+module Reanimate.Driver ( reanimate ) where
+
+import           Control.Concurrent (MVar, forkIO, killThread, modifyMVar_,
+                                     newEmptyMVar, putMVar)
+import           Control.Monad.Fix  (fix)
+import qualified Data.Text          as T
+import           Network.WebSockets
+import           System.Directory   (findFile, listDirectory)
+import           System.Environment (getArgs, getProgName)
+import           System.INotify     (EventVariety (..), addWatch, withINotify)
+import           System.IO          (BufferMode (..), hPutStrLn, hSetBuffering,
+                                     stderr, stdin)
+
+import           Reanimate.Misc     (runCmdLazy, runCmd, runCmd_, withTempDir, withTempFile)
+import           Reanimate.Monad    (Animation)
+import           Reanimate.Render   (renderSvgs)
+
+import Paths_reanimate
+
+opts = defaultConnectionOptions
+  { connectionCompressionOptions = PermessageDeflateCompression defaultPermessageDeflate }
+
+reanimate :: Animation -> IO ()
+reanimate animation = do
+  args <- getArgs
+  hSetBuffering stdin NoBuffering
+  case args of
+    ["once"] -> renderSvgs animation
+    _ -> withTempDir $ \tmpDir -> do
+      url <- getDataFileName "viewer/build/index.html"
+      runCmd "xdg-open" [url]
+      runServerWith "127.0.0.1" 9161 opts $ \pending -> do
+        putStrLn "Server pending."
+        prog <- getProgName
+        lst <- listDirectory "."
+        mbSelf <- findFile ("." : lst) prog
+        blocker <- newEmptyMVar :: IO (MVar ())
+        case mbSelf of
+          Nothing -> do
+            hPutStrLn stderr "Failed to find own source code."
+          Just self -> withINotify $ \notify -> do
+            conn <- acceptRequest pending
+            slave <- newEmptyMVar
+            let handler = modifyMVar_ slave $ \tid -> do
+                  sendTextData conn (T.pack "Compiling")
+                  putStrLn "Kill and respawn."
+                  killThread tid
+                  tid <- forkIO $ withTempFile ".exe" $ \tmpExecutable -> do
+                    ret <- runCmd_ "stack" $ ["ghc", "--"] ++ ghcOptions tmpDir ++ [self, "-o", tmpExecutable]
+                    case ret of
+                      Left err ->
+                        sendTextData conn $ T.pack $ "Error" ++ unlines (drop 3 (lines err))
+                      Right{} -> do
+                        getFrame <- runCmdLazy tmpExecutable ["once", "+RTS", "-N", "-M200M", "-RTS"]
+                        flip fix [] $ \loop acc -> do
+                          frame <- getFrame
+                          case frame of
+                            Left "" -> do
+                              sendTextData conn (T.pack "Done")
+                              -- insertCache msg (reverse acc)
+                            Left err -> do
+                              -- _ <- getChanContents queue
+                              sendTextData conn $ T.pack $ "Error" ++ err
+                            Right frame -> do
+                              sendTextData conn frame
+                              loop (frame : acc)
+                  return tid
+            putStrLn "Found self. Listening."
+            addWatch notify [Modify] self (const handler)
+            putMVar slave =<< forkIO (return ())
+            let loop = do
+                  fps <- receiveData conn :: IO T.Text
+                  handler
+                  loop
+            loop
+
+ghcOptions :: FilePath -> [String]
+ghcOptions tmpDir =
+    ["-rtsopts", "--make", "-threaded", "-O2"] ++
+    ["-odir", tmpDir, "-hidir", tmpDir]
diff --git a/src/Reanimate/Examples.hs b/src/Reanimate/Examples.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Examples.hs
@@ -0,0 +1,807 @@
+{-# LANGUAGE Arrows                #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE OverloadedStrings     #-}
+{-# LANGUAGE PackageImports        #-}
+{-# LANGUAGE ParallelListComp      #-}
+{-# LANGUAGE PartialTypeSignatures #-}
+{-# LANGUAGE TypeFamilies          #-}
+module Reanimate.Examples where
+
+import           Codec.Picture.Types
+import           Control.Lens                  ()
+import           Control.Monad
+import qualified Data.Map                      as M
+import           Data.Text                     (Text, pack)
+import           Graphics.SvgTree              as S
+import           Linear.V2
+import           Numeric
+import           Text.Printf
+
+import           Reanimate.Combinators
+import           Reanimate.Diagrams
+import           Reanimate.LaTeX
+import           Reanimate.Monad
+import           Reanimate.Svg
+
+import qualified Data.Colour.Palette.BrewerSet as D
+import qualified Diagrams.Backend.SVG          as D
+import           Diagrams.Prelude              hiding (Animation, boundingBox,
+                                                center, circle, duration,
+                                                fontSize, rotate, scale,
+                                                translate)
+import qualified Diagrams.Prelude              as D
+import qualified Diagrams.TwoD.Path.LSystem    as D
+
+import           Debug.Trace
+
+{-
+sinewave :: Ani ()
+sinewave = proc () -> do
+    duration 10 -< ()
+    emit -< toHtml $ mkBackground "black"
+    idx <- signalOscillate 0 1 -< ()
+    emit -< do
+      defs_ $ clipPath_ [id_ "clip"] $ toHtml $
+        mkRect (Num 0, Num (-height)) (Num $ idx*width) (Num 320)
+      toHtml $ translate margin height $ withStrokeColor "white" $
+        withClipPathRef (Ref "clip") $ mkPathText $ renderPathText $ approxFnData 1000 wave
+      toHtml $ withStrokeColor "white" $
+        mkLine (Num margin, Num 10) (Num margin, Num 170)
+      toHtml $ withStrokeColor "white" $
+        mkLine (Num margin, Num height) (Num (margin+width), Num height)
+    let (circX, circY) = wave idx
+    emit -< g_ [transform_ $ Lucid.translate margin height] $
+      circle_ [num_ cx_ circX, num_ cy_ circY, r_ "3", fill_ "red"]
+  where
+    freq = 3; margin = 30; width = 260; height = 90
+    wave idx = (idx*width, sin (idx*pi*2*freq) * 50)
+
+morph_wave :: Ani ()
+morph_wave = proc () -> do
+    duration 5 -< ()
+    morph <- signalOscillate 0 1 -< ()
+    emit -< toHtml $ mkBackground "black"
+    emit -< toHtml $ withStrokeColor "white" $ mkGroup
+      [ translate 30 50  $ mkPathText $ renderPathText wave1
+      , translate 30 130 $ mkPathText $ renderPathText wave2
+      , translate 30 90  $ mkPathText $ renderPathText $ morphPath wave1 wave2 morph
+      , mkLine (Num 30, Num 10) (Num 30, Num 170)
+      , mkLine (Num 30, Num 90) (Num 290, Num 90) ]
+  where
+    freq = 3; width = 260
+    wave1 = approxFnData 1000 $ \idx -> (idx*width, sin (idx*pi*2*freq) * 20)
+    wave2 = approxFnData 1000 $ \idx -> (idx*width, sin (idx*pi*2*(freq*3)) * 20)
+
+morph_wave_circle :: Ani ()
+morph_wave_circle = proc t -> do
+    duration 5 -< ()
+    idx <- signalOscillate 0 1 -< ()
+    emit -< toHtml $ withStrokeColor "white" $ mkGroup
+      [ mkBackground "black"
+      , translate 30 90 $ mkPathText $ renderPathText $ morphPath circle wave1 idx
+      , mkLine (Num 30, Num 10) (Num 30, Num 170)
+      , mkLine (Num 30, Num 90) (Num 290, Num 90) ]
+  where
+    freq = 5; width = 260; radius = 50
+    wave1 = approxFnData 1000 $ \idx -> (idx*width, sin (idx*pi*2*freq) * 20)
+    circle = approxFnData 1000 $ \idx ->
+      (cos (idx*pi*2+pi/2)*radius + width/2, sin (idx*pi*2+pi/2)*radius)
+
+progressMeters :: Ani ()
+progressMeters = proc () -> do
+  emit -< rect_ [width_ "100%", height_ "100%", fill_ "black"]
+  annotate' (adjustSpeed 1.0 progressMeter) -< g_ [transform_ $ Lucid.translate 40 20]
+  annotate' (adjustSpeed 2.0 progressMeter) -< g_ [transform_ $ Lucid.translate 140 20]
+  annotate' (adjustSpeed 0.5 progressMeter) -< g_ [transform_ $ Lucid.translate 240 20]
+
+  emit -< do
+    text_ [x_ "55", y_ "150", font_size_ "20"
+          , text_anchor_ "middle"
+          , fill_ "white"] "1x"
+    text_ [x_ "155", y_ "150", font_size_ "20"
+          , text_anchor_ "middle"
+          , fill_ "white"] "2x"
+    text_ [x_ "255", y_ "150", font_size_ "20"
+          , text_anchor_ "middle"
+          , fill_ "white"] "0.5x"
+
+progressMeter :: Ani ()
+progressMeter = loop $ proc () -> do
+  duration 5 -< ()
+  h <- signal 0 100 -< ()
+  emit -< rect_ [ width_ "30", height_ "100", stroke_ "white", stroke_width_ "2", fill_opacity_ "0" ]
+  emit -< rect_ [ width_ "30", num_ height_ h, stroke_ "white", fill_ "white" ]
+  returnA -< ()
+
+highlight :: Ani ()
+highlight = proc () -> do
+    emit -< rect_ [width_ "100%", height_ "100%", fill_ "black"]
+    emit -< do
+      path_ (commonAttrs "white" ++ [d_ $ renderPathText rect1])
+      path_ (commonAttrs "white" ++ [d_ $ renderPathText rect2])
+
+      path_ (commonAttrs "white" ++ [d_ $ renderPathText rect3])
+      path_ (commonAttrs "lightblue" ++ [d_ $ renderPathText rect4])
+      path_ (commonAttrs "yellow" ++ [d_ $ renderPathText rect5])
+      path_ (commonAttrs "red" ++ [d_ $ renderPathText rect6])
+
+    follow
+      [ mkTransition highlight1 highlight2
+      , mkTransition highlight2 highlight3
+      , mkTransition highlight3 highlight4
+      , mkTransition highlight4 highlight5
+      , mkTransition highlight5 highlight6
+      , mkTransition highlight6 highlight1
+      ] -< ()
+
+  where
+    mkTransition from to = pauseAtEnd 1 $ proc () -> do
+      duration 1 -< ()
+      s <- signalSCurve 2 0 1 -< ()
+      let trans = morphPath from to s
+      emit -<
+        path_ (highlightAttrs "green" ++ [d_ $ renderPathText trans <> "Z"])
+    mkRect x y width height =
+      [ (x,y), (x+width, y), (x+width, y+height), (x,y+height) ]
+    rect1 = mkRect margin margin w h
+    rect2 = mkRect (320-margin-w*2) margin (w*2) h
+    rect3 = mkRect margin (180-margin-h) w h
+    rect4 = mkRect (320/3) (180-margin-h) w h
+    rect5 = mkRect (320/3*2-w) (180-margin-h) w h
+    rect6 = mkRect (320-margin-w) (180-margin-h) w h
+    highlight1 = mkRect (margin-b) (margin-b) (w+2*b) (h+2*b)
+    highlight2 = mkRect (320-margin-w*2-b) (margin-b) (w*2+2*b) (h+2*b)
+    highlight3 = mkRect (320-margin-w-b) (180-margin-h-b) (w+2*b) (h+2*b)
+    highlight4 = mkRect (320/3*2-w-b) (180-margin-h-b) (320/3+2*b) (h+2*b)
+    highlight5 = mkRect (320/3-b) (180-margin-h-b) (320/3+2*b) (h+2*b)
+    highlight6 = mkRect (margin-b) (180-margin-h-b) (320/3+2*b) (h+2*b)
+    b = 7
+    margin = 30
+    w = 30
+    h = 30
+    commonAttrs c = [stroke_width_ "2", stroke_ c, fill_ c]
+    highlightAttrs c = [stroke_width_ "2", stroke_ c, fill_opacity_ "0"]
+
+clip_rect :: Ani ()
+clip_rect = proc () -> do
+  emit -< toHtml $ mkBackground "black"
+  annotate' $ follow
+    [ sim
+      [ sim [ paintStatic prev | prev <- [max 0 (n-4) .. n-1] ]
+      , sim [ runAni "black" i | i <- [n-4], i>=0 ]
+      , runAni "white" n ]
+    | n <- [0..15]
+    ] -< g_ [transform_ $ Lucid.translate (320/2) (180/2)]
+  where
+    paintStatic nth = proc () ->
+      emit -< toHtml $ withStrokeColor "white" $
+        square (20+nth*10)
+    runAni color nth = circle_clip $ proc () -> do
+      duration 1 -< ()
+      emit -< toHtml $ withStrokeColor color $
+        square (20+nth*10)
+    square side = center $ withFillOpacity 0 $ withStrokeWidth (Num 2) $
+      mkRect (Num 0, Num 0) (Num side) (Num side)
+
+circle_clip :: Ani () -> Ani ()
+circle_clip sub = proc () -> do
+    arc <- signal (pi*2) 0 -< ()
+    let startX = pack$show$sin 0 * 1000
+        startY = pack$show$cos 0 * 1000
+        xPos = pack$show$sin arc * 1000
+        yPos = pack$show$cos arc * 1000
+        long = if arc < pi then "1" else "0"
+    emit -< clipPath_ [id_ $ uniqName] $
+      path_ [ d_ $ "M "<>startX<>" "<>startY<>" A 1000 1000 0 "<>long<>" 1 "
+                  <>xPos<> " "<>yPos<>" L 0 0 Z"]
+    annotate' sub -<
+      g_ [clip_path_ $ "url(#"<>uniqName<>")"]
+  where
+    uniqName = "clip" -- XXX: Not very unique?
+
+
+scaling :: Ani ()
+scaling = adjustSpeed 2 $ syncAll
+  [ proc () ->
+    annotate' animation -< g_ [transform_ $ Lucid.translate x y <> " " <> Lucid.scale 0.5 0.5]
+  | x <- [0,160]
+  , y <- [0,90]
+  | animation <- [sinewave, morph_wave, highlight, progressMeters]]
+
+
+label :: String -> Ani ()
+label str = proc () -> do
+  emit -< text_ [x_ "0", y_ "16", font_size_ "16"
+        , fill_ "white"] (toHtml str)
+
+valentine :: Ani ()
+valentine = proc () -> do
+    follow
+     [ all_red
+     , sim [ background
+           , follow [backgroundDelay, sim [delay 6.4 (fallingLove 0.09)
+                                          ,delay 4.9 (fallingLove 0.12)
+                                          ,delay 4.5 (fallingLove 0.88)
+                                          ,delay 0.3 (fallingLove 0.43)
+                                          ,delay 5.3 (fallingLove 0.93)
+                                          ,delay 0.1 (fallingLove 0.80)
+                                          ,delay 1.1 (fallingLove 0.39)
+                                          ,delay 2.3 (fallingLove 0.21)
+                                          ,delay 2.9 (fallingLove 0.77)
+                                          ,delay 3.4 (fallingLove 0.46)
+                                          ,delay 6.2 (fallingLove 0.19)
+                                          ,delay 5.9 (fallingLove 0.53)
+                                          ,delay 3.2 (fallingLove 0.14)
+                                          ,delay 7.7 (fallingLove 0.99) ]]
+           , follow [heart_ani, heart_disappear]
+           , follow [backgroundDelay, message "", message ""
+                    , message "", message "爱", message ""
+                    , message "", message ""]]
+     ] -<()
+  where
+    all_red = proc () -> do
+      duration 1 -< ()
+      emit -< rect_ [width_ "100%", height_ "100%", fill_ "red"]
+    background = freezeAtEnd $ proc () -> do
+      duration 2 -< ()
+      n <- signal 0 0xFF -< ()
+      let color = "#FF" ++ hex n ++ hex n
+      emit -< rect_ [width_ "100%", height_ "100%", fill_ $ pack color]
+    backgroundDelay = freezeAtEnd $ proc () -> do
+      duration (animationDuration background-1) -< ()
+      returnA -< ()
+    heart_ani = repeatAni 10 $ proc () -> do
+      duration 1 -< ()
+      n <- signalOscillateSCurve 2 0.9 1.1 -< ()
+      annotate' drawHeart -< g_ [transform_ $ Lucid.translate 160 110] . g_ [transform_ $ Lucid.scale n n <> " "]
+    heart_disappear = proc () -> do
+      duration 3 -< ()
+      n  <- signal 0.9 10 -< ()
+      annotate' drawHeart -< g_ [transform_ $ Lucid.translate 160 110] . g_ [transform_ $ Lucid.scale n n <> " "]
+    white = loop $ proc () -> do
+      duration 1 -< ()
+      emit -< rect_ [width_ "100%", height_ "100%", fill_ "#FFFFFF"]
+    fallingLove xPos = proc () -> do
+      duration 2 -< ()
+      n <- signal 0 1 -< ()
+      o <- signalOscillate (-1) 1 -< ()
+      emit -<
+        g_ [transform_ $ Lucid.translate (xPos*360) (210*n)] $
+          g_ [transform_ $ Lucid.rotate (45*o)] $
+            text_ [font_size_ "18"
+                  ,text_anchor_ "middle"
+                  ,fill_ "red"] "爱"
+    message txt = proc () -> do
+      duration 1 -< ()
+      o <- signalOscillate 0 1 -< ()
+      n <- signalOscillateSCurve 2 0.9 1.1 -< ()
+      emit -<
+        g_ [transform_ $ Lucid.translate 160 110, num_ opacity_ o] $
+        g_ [transform_ $ Lucid.scale n n ] $
+          text_ [x_ "0", y_ "-12", font_size_ "24"
+                    , text_anchor_ "middle"
+                    , fill_ "white"] txt
+
+    drawHeart = proc () -> do
+      emit -<
+        g_ [transform_ $ Lucid.translate (-170) (-260)] $
+          g_ [transform_ $ Lucid.rotateAround 225 150 121 <> " " <> Lucid.scale 0.4 0.4] $
+            path_ ([stroke_ "red", fill_"red", d_ dat])
+    dat = "M0 200 v-200 h200      a100,100 90 0,1 0,200     a100,100 90 0,1 -200,0     z"
+    hex n = if n < 0x10 then "0" ++ showHex (round n) ""
+            else showHex (round n) ""
+
+frequencies :: Ani ()
+frequencies = proc () -> do
+    emit -< rect_ [width_ "100%", height_ "100%", fill_ "black"]
+    n <- signal 0 2 -< ()
+    follow -- [drawUpWave
+      [ drawLine
+      , drawFirstWave
+      , drawSecondWave
+      , drawUpWave
+      ] -< n
+  where
+    freqs = [11, 5, 17]; margin = 30; width = 260; height = 90
+    drawLine = freezeAtEnd $ proc _ -> do
+      label "drawLine" -< ()
+      duration 1 -< ()
+      n <- signal margin (width+margin) -< ()
+      emit -< do
+        line_ [ num_ x1_ margin, num_ y1_ height
+              , num_ x2_ n,      num_ y2_ height
+              , stroke_ "white"]
+        circle_ [num_ cx_ n, num_ cy_ height, r_ "3", fill_ "red"]
+    drawFirstWave = freezeAtEnd $ proc move -> do
+      label "drawFirstWave" -< ()
+      duration 3 -< ()
+      n <- signal 0 1 -< ()
+      emit -< do
+        g_ [transform_ $ Lucid.translate margin height] $ renderPath $ morphPath line1 (wave1 move) n
+        let circleY = sum [ sin ((1+move)*pi*2*freq) * 20 | freq <- freqs ]
+        circle_ [num_ cx_ (width+margin), num_ cy_ (height+circleY*n), num_ r_ 3, fill_ "red"]
+    drawSecondWave = freezeAtEnd $ proc move -> do
+      label "drawSecondWave" -< ()
+      duration 3 -< ()
+      emit -< do
+        g_ [transform_ $ Lucid.translate margin height] $ renderPath $ wave1 move
+        let circleY = sum [ sin ((1+move)*pi*2*freq) * 20 | freq <- freqs ]
+        circle_ [num_ cx_ (width+margin), num_ cy_ (height+circleY), num_ r_ 3, fill_ "red"]
+    drawUpWave = freezeAtEnd $ proc move -> do
+      label "drawUpWave" -< ()
+      duration 2 -< ()
+      n <- signal 0 1 -< ()
+      emit -< do
+        g_ [transform_ $ Lucid.scale 1 (1-0.5*n)] $ do
+          g_ [transform_ $ Lucid.translate margin height] $ renderPath $ wave1 move
+          let circleY = sum [ sin ((1+move)*pi*2*freq) * 20 | freq <- freqs ]
+          circle_ [num_ cx_ (width+margin), num_ cy_ (height+circleY), num_ r_ 3, fill_ "red"]
+    line1 = approxFnData 1000 $ \idx ->
+      (idx*width, 0)
+    wave1 n = approxFnData 1000 $ \idx ->
+      (idx*width, sum [ sin ((idx+n)*pi*2*freq) * 20 | freq <- freqs ])
+
+
+latex_basic :: Ani ()
+latex_basic = proc () -> do
+  duration 2 -< ()
+  s <- signalOscillate 0 1 -< ()
+  emit -< toHtml $ mkGroup
+    [ mkBackground "black"
+    , translate (320/2) (180/2) $ mkGroup
+      [ withStrokeColor "white" $ withFillOpacity 0 $ withStrokeWidth (Num 0.1) text
+      , withFillColor "white" $ withFillOpacity s text] ]
+  where
+    text = scale 4 $ center $ latexAlign
+      "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"
+
+bezier :: Ani ()
+bezier = adjustSpeed 0.4 $ proc () -> do
+  emit -< rect_ [width_ "100%", height_ "100%", fill_ "black"]
+  follow
+    [ orderN [pointA, pointB]
+    , morph [pointA, pointA, pointB] [pointA, pointC, pointB]
+    , orderN [pointA, pointC, pointB]
+    , morph [pointA, pointC, pointB, pointB] [pointA, pointC, pointD, pointB]
+    , orderN [pointA, pointC, pointD, pointB]
+    , morph [pointA, pointC, pointD, pointB] [pointA, pointA, pointB, pointB]] -< ()
+  where
+    pointA = (70,130); pointB = (270,120); pointC = (30,30); pointD = (250,50)
+
+    morph old new = proc () -> do
+      duration 0.5 -< ()
+      s <- signal 0 1 -< ()
+      let new' = map (\(a,b) -> between a b s) (zip old new)
+      emit -< forM_ (zip new' (tail new')) $ \(a,b) -> do
+        renderPath $
+          approxFnData 100 $ \idx ->
+            between a b idx
+      emit -< mapM_ secondaryCircleAt new'
+      emit -< primaryCircleAt (head new')
+    orderN lst = proc () -> do
+      duration 2 -< ()
+      s <- signalOscillate 0 1 -< ()
+      emit -< primaryCircleAt =<< orderN' (map const lst) s <* mapM_ secondaryCircleAt lst
+    orderN' [a] s = do
+      renderPath $ take (round $ 100*s) $ approxFnData 100 $ \idx -> a idx
+      return (a s)
+    orderN' lst s = do
+      forM_ (zip lst (tail lst)) $ \(a,b) -> renderPath $
+          approxFnData 100 $ \idx ->
+            between (a s) (b s) idx
+      let middlePoints = map (\(a,b) -> \idx -> between (a idx) (b idx) idx) (zip lst (tail lst))
+      orderN' middlePoints s <* mapM_ secondaryCircleAt (map ($s) middlePoints)
+
+    secondaryCircleAt (x,y) = circle_ [num_ cx_ x, num_ cy_ y, num_ r_ 3, fill_ "green"]
+    primaryCircleAt (x,y) = circle_ [num_ cx_ x, num_ cy_ y, num_ r_ 3, fill_ "red"]
+    between a b _ | a==b = a
+    between (x1, y1) (x2, y2) idx =
+      ( x1 + idx * (x2 - x1)
+      , y1 + idx * (x2-x1) * (y2 - y1) / (x2 - x1))
+
+pathSquare :: Ani ()
+pathSquare = proc () -> do
+    duration 2 -< ()
+    s <- signalOscillate 0 1 -< ()
+    emit -< rect_ [width_ "100%", height_ "100%", fill_ "black"]
+    emit -< g_ [stroke_ "white"] $ toHtml (square s)
+  where
+    square s = S.PathTree (myPath s)
+    myPath s = S.defaultSvg
+      & S.pathDefinition .~ interpolatePathCommands s myPathCmds
+    myPathCmds =
+      [ S.MoveTo S.OriginAbsolute [V2 100 100]
+      , S.LineTo S.OriginAbsolute [V2 200 150]
+      , S.LineTo S.OriginRelative [V2 (-10) (-100)]
+      , S.EndPath
+      ]
+
+latex_draw :: Ani ()
+latex_draw = pauseAtEnd 1 $ proc () -> do
+  emit -< toHtml $ mkBackground "black"
+  drawText `andThen` fillText -< ()
+  where
+    msg = "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"
+    glyphs = center $ latexAlign msg
+    placement = translate (320/2) (180/2) . scale 5
+    fillText = proc () -> do
+      duration 1 -< ()
+      s <- signal 0 1 -< ()
+      emit -< toHtml $ placement $
+          withFillColor "white" $ withFillOpacity s $
+            glyphs
+    drawText = proc () -> do
+      duration 2 -< ()
+      s <- signal 0 1 -< ()
+      emit -< toHtml $ placement $
+        withStrokeColor "white" $ withFillOpacity 0 $ withStrokeWidth (Num 0.1) $
+          partialSvg s glyphs
+
+
+bbox :: Ani ()
+bbox = proc () -> do
+  emit -< toHtml $ mkBackground "black"
+  duration 5 -< ()
+  annotate' bbox1 -< g_ [transform_ $ Lucid.translate (320/2-50) (180/2)]
+  annotate' bbox2 -< g_ [transform_ $ Lucid.translate (320/2+50) (180/2)]
+
+bbox1 :: Ani ()
+bbox1 = proc () -> do
+  s <- signal 0 1 -< ()
+  emit -< do
+    toHtml $ mkBoundingBox $ rotate (360*s) svg
+    toHtml $ withFillColor "white" $ rotate (360*s) svg
+  where
+    svg = scale 3 $ center $ latexAlign "\\sum_{k=1}^\\infty"
+
+bbox2 :: Ani ()
+bbox2 = proc () -> do
+  s <- signalOscillate 0 1 -< ()
+  emit -< do
+    toHtml $ mkBoundingBox $ partialSvg s heartShape
+    toHtml $ withStrokeColor "white" $ withFillOpacity 0 $ partialSvg s heartShape
+
+mkBoundingBox :: Tree -> Tree
+mkBoundingBox svg = withStrokeColor "red" $ withFillOpacity 0 $
+    mkRect (S.Num x, S.Num y) (S.Num w) (S.Num h)
+  where
+    (x, y, w, h) = boundingBox svg
+
+heartShape =
+    center $ rotateAroundCenter 225 $ mkPathString
+      "M0.0,40.0 v-40.0 h40.0\
+      \a20.0 20.0 90.0 0 1 0.0,40.0\
+      \a20.0 20.0 90.0 0 1 -40.0,0.0 Z"
+
+latex_color :: Ani ()
+latex_color = proc () -> do
+    duration 0.1 -< ()
+    emit -< toHtml $ mkBackground "black"
+    emit -< toHtml $ translate (320/2) (180/2) $ withStrokeWidth (Num 0.2) $
+      withStrokeColor "white" $
+      withSubglyphs [0] (withFillColor "blue") $
+      withSubglyphs [1] (withFillColor "yellow") $
+      withSubglyphs [2] (withFillColor "green") $
+      withSubglyphs [3] (withFillColor "red") $
+      withSubglyphs [4] (withFillColor "darkslategrey") $
+      svg
+  where
+    svg = scale 10 $ center $ latex "\\LaTeX"
+-}
+
+
+latex_draw :: Animation
+latex_draw =
+    bg `sim` (autoReverse $ drawText `andThen` fillText)
+  where
+    bg = mkAnimation 0 $ emit (mkBackground "black")
+    msg = "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"
+    glyphs = center $ latexAlign msg
+    fillText = mkAnimation 1 $ do
+      s <- signal 0 1
+      emit $ scale 5 $ withFillColor "white" $ withFillOpacity s glyphs
+    drawText = mkAnimation 2 $ do
+      s <- signal 0 1
+      emit $ scale 5 $
+        withStrokeColor "white" $ withFillOpacity 0 $ withStrokeWidth (Num 0.1) $
+          partialSvg s glyphs
+
+morph_wave :: Animation
+morph_wave = autoReverse $ mkAnimation 2.5 $ do
+    morph <- signal 0 1
+    emit $ mkBackground "black"
+    emit $ withStrokeColor "white" $ translate (-320/2) (-180/2) $ mkGroup
+      [ translate 30 50  $ mkLinePath wave1
+      , translate 30 130 $ mkLinePath wave2
+      , translate 30 90  $ mkLinePath $ morphPath wave1 wave2 morph
+      , mkLine (Num 30, Num 10) (Num 30, Num 170)
+      , mkLine (Num 30, Num 90) (Num 290, Num 90) ]
+  where
+    freq = 3; width = 260
+    wave1 = approxFnData 100 $ \idx -> (idx*width, sin (idx*pi*2*freq) * 20)
+    wave2 = approxFnData 100 $ \idx -> (idx*width, sin (idx*pi*2*(freq*3)) * 20)
+
+morph_wave_circle :: Animation
+morph_wave_circle = autoReverse $ mkAnimation 2.5 $ do
+    idx <- signal 0 1
+    emit $ mkBackground "black"
+    emit $ withStrokeColor "white" $ translate (-320/2) (-180/2) $ mkGroup
+      [ translate 30 90 $ mkLinePath $ morphPath circle wave1 idx
+      , mkLine (Num 30, Num 10) (Num 30, Num 170)
+      , mkLine (Num 30, Num 90) (Num 290, Num 90) ]
+  where
+    freq = 5; width = 260; radius = 50
+    wave1 = approxFnData 100 $ \idx -> (idx*width, sin (idx*pi*2*freq) * 20)
+    circle = approxFnData 100 $ \idx ->
+      (cos (idx*pi*2+pi/2)*radius + width/2, sin (idx*pi*2+pi/2)*radius)
+
+progressMeters :: Animation
+progressMeters =
+    bg `sim` labels `sim`
+    mapA (translate (-100) 0)  (adjustSpeed 1.0 progressMeter) `simLoop`
+    mapA (translate 0 0) (adjustSpeed 2.0 progressMeter) `simLoop`
+    mapA (translate 100 0) (adjustSpeed 0.5 progressMeter)
+  where
+    bg = mkAnimation 0 $ emit $ mkBackground "black"
+    labels = mkAnimation 0 $ emit $ translate 0 70 $ withFillColor "white" $ mkGroup
+      [ translate (-100) 0 $ scale 2 $ center $ latex "1x"
+      , translate 0 0      $ scale 2 $ center $ latex "2x"
+      , translate 100 0    $ scale 2 $ center $ latex "0.5x"
+      ]
+
+progressMeter :: Animation
+progressMeter = mkAnimation 3 $ do
+  h <- signal 0 100
+  emit $ center $ mkGroup
+    [ withStrokeColor "white" $ withStrokeWidth (Num 2) $ withFillOpacity 0 $
+        mkRect (Num 0, Num 0) (Num 30) (Num 100)
+    , withFillColor "white" $
+        mkRect (Num 0, Num 0) (Num 30) (Num h) ]
+
+
+bbox :: Animation
+bbox = bg `sim`
+    mapA (translate (-50) 0) bbox1 `sim`
+    mapA (translate 50 0) bbox2
+  where
+    bg = mkAnimation 0 $ emit $ mkBackground "black"
+
+bbox1 :: Animation
+bbox1 = mkAnimation 5 $ do
+    s <- signal 0 1
+    emit $ mkGroup
+      [ mkBoundingBox $ rotate (360*s) svg
+      , withFillColor "white" $ rotate (360*s) svg ]
+  where
+    svg = scale 3 $ center $ latexAlign "\\sum_{k=1}^\\infty"
+
+bbox2 :: Animation
+bbox2 = autoReverse $ mkAnimation 2.5 $ do
+  s <- signal 0 1
+  emit $ mkGroup
+    [ mkBoundingBox $ partialSvg s heartShape
+    , withStrokeColor "white" $ withFillOpacity 0 $ partialSvg s heartShape ]
+
+mkBoundingBox :: Tree -> Tree
+mkBoundingBox svg = withStrokeColor "red" $ withFillOpacity 0 $
+    mkRect (S.Num x, S.Num y) (S.Num w) (S.Num h)
+  where
+    (x, y, w, h) = boundingBox svg
+
+heartShape =
+    center $ rotateAroundCenter 225 $ mkPathString
+      "M0.0,40.0 v-40.0 h40.0\
+      \a20.0 20.0 90.0 0 1 0.0,40.0\
+      \a20.0 20.0 90.0 0 1 -40.0,0.0 Z"
+
+latex_color :: Animation
+latex_color = mkAnimation 1 $ do
+    emit $ mkBackground "black"
+    emit $ withStrokeWidth (Num 0.2) $
+      withStrokeColor "white" $
+      withSubglyphs [0] (withFillColor "blue") $
+      withSubglyphs [1] (withFillColor "yellow") $
+      withSubglyphs [2] (withFillColor "green") $
+      withSubglyphs [3] (withFillColor "red") $
+      withSubglyphs [4] (withFillColor "darkslategrey") $
+      svg
+  where
+    svg = scale 10 $ center $ latex "\\LaTeX"
+
+latex_basic :: Animation
+latex_basic = autoReverse $ mkAnimation 2 $ do
+    s <- signal 0 1
+    emit $ mkGroup
+      [ mkBackground "black"
+      , withStrokeColor "white" $ withFillOpacity 0 $ withStrokeWidth (Num 0.1) text
+      , withFillColor "white" $ withFillOpacity s text ]
+  where
+    text = scale 4 $ center $ latexAlign
+      "\\sum_{k=1}^\\infty {1 \\over k^2} = {\\pi^2 \\over 6}"
+
+valentine :: Animation
+valentine =
+    all_red `before`
+    ( background `sim`
+      (backgroundDelay `before`
+       foldr1 sim [ pause p `before` fallingLove x | (p, x) <- falling ]
+      ) `sim`
+      (heart_ani `before` heart_disappear) `sim`
+      (pause 5 `before` message ai)
+    )
+  where
+    falling = [(6.4, 0.09), (4.9, 0.12), (4.5, 0.88), (0.3, 0.43), (5.3, 0.93)
+              ,(0.1, 0.80), (1.1, 0.39), (2.3, 0.21), (2.9, 0.77), (3.4, 0.46)
+              ,(6.2, 0.19), (5.9, 0.53), (3.2, 0.14), (7.7, 0.99) ]
+    ai = center $ xelatex "爱"
+    all_red = mkAnimation 1 $ emit $ mkBackground "red"
+    background = mkAnimation 2 $ do
+      n <- round <$> signal 0 0xFF
+      emit $ mkBackgroundPixel $ PixelRGBA8 0xFF n n 0xFF
+    backgroundDelay = pause (duration background-1)
+    heart_ani = repeatAnimation 10 $ mkAnimation 1 $ do
+      n <- oscillate $ signalSCurve 2 0.9 1.1
+      mapF (scale n) $ drawHeart
+    heart_disappear = mkAnimation 3 $ do
+      n  <- signal 0.9 10
+      mapF (scale n) drawHeart
+    fallingLove xPos = mkAnimation 2 $ do
+      n <- signal (-100) 100
+      o <- oscillate $ signal (-1) 1
+      emit $ scale 2 $ withFillColor "red" $
+        translate ((xPos*2-1)*60) n $ rotate (45*o) ai
+    message txt = mkAnimation 1 $ do
+      o <- oscillate $ signal 0 1
+      n <- oscillate $ signalSCurve 2 0.9 1.1
+      emit $ scale n $ scale 2 $ withFillColor "white" $ withFillOpacity o txt
+    drawHeart = emit $ withFillColor "red" $ heartShape
+
+
+diaSize :: Animation
+diaSize = mkAnimation 0.1 $ do
+    emit $ mkBackground "white"
+    emit $ translate (-320/2) (-180/2) dSvg
+  where
+    dSvg = renderDiagram $ withEnvelope (D.rect 320 180 :: SvgDiagram) $
+      D.scale 3 $
+      D.translate (V2 0 (-30)) $
+      D.rotate (90 @@ deg) $
+      D.lwO 0.1 $ D.strokePath (D.getTurtlePath (D.tree3 4))
+
+wavyTree :: Animation
+wavyTree = mkAnimation 1 $ do
+    s <- oscillate $ signal 1 2
+    emit $ mkBackground "white"
+    emit $ translate (-320/2) (-180/2) (dSvg s)
+  where
+    dSvg s = renderDiagram $ withEnvelope (D.rect 320 180 :: SvgDiagram) $
+      D.scale 3 $
+      D.translate (V2 0 (-30)) $
+      D.rotate (90 @@ deg) $
+      D.lwO 0.1 $ D.strokePath (D.getTurtlePath (tree s))
+    gens = 4
+    tree s =
+      D.lSystem gens (s/16 @@ turn) (D.symbols "F") rules
+    rules = M.fromList [D.rule 'F' "FF-[->F+F+>F]+[+>F->F->F]"]
+
+tangentAndNormal :: Animation
+tangentAndNormal = mkAnimation 5 $ do
+    s <- oscillate $ signalSCurve 2 0 1
+    emit $ mkBackground "white"
+    emit $ translate (-320/2) (-180/2) $ renderDiagram $
+      withEnvelope (D.rect 320 180 :: SvgDiagram) $
+      D.scale 50 $ D.translate (V2 (-2) (-0.75)) $ dia s
+  where
+    dia param =
+        frame 0.5 $
+        strokeLocTrail spline
+        <> mconcat
+          [ tangentLine
+          , baselineText "tangent" # D.translate tangentVector
+          , normalLine
+          , topLeftText "normal" # D.translate (-normalVector)
+          , rightAngleSquare
+          ] # moveTo pt # D.fontSize large
+      where
+        pts = map p2 [(0,0), (1,1), (2,1), (3,0), (3.5,0)]
+
+        spline :: Located (Trail V2 Double)
+        spline = cubicSpline False pts
+
+        pt = atParam spline param
+        tangentVector ::  V2 Double
+        tangentVector = D.normalize $ tangentAtParam spline param
+        normalVector = D.normalize $ normalAtParam spline param
+
+        symmetricLine :: V2 Double -> SvgDiagram
+        symmetricLine v = fromOffsets [2 *^ v] # D.center
+        tangentLine :: SvgDiagram
+        tangentLine = symmetricLine tangentVector
+        normalLine = symmetricLine normalVector
+
+        rightAngleSquare :: SvgDiagram
+        rightAngleSquare = square 0.1 # alignBL # D.rotate (signedAngleBetween tangentVector unitX)
+
+
+drawSunflower :: Animation
+drawSunflower = mkAnimation 10 $ do
+    n <- signal 1 500
+    rot <- signal 0 45
+    emit $ mkBackground "black"
+    emit $ rotate rot $ translate (-320/2) (-180/2)
+      (dSvg $ round n)
+  where
+    cached = [ dSvg n | n <- [0..]]
+    dSvg n = renderDiagram $ withEnvelope (D.rect 320 180 :: SvgDiagram) $
+      D.scale 5 $ sunflower n
+
+    mkCoords :: [P2 Double]
+    mkCoords =[coord (fromIntegral i) | i <- [1..]]
+      where
+        coord m = p2 $ fromPolar (sqrt m) (2.4 * m)
+        fromPolar r theta = (r * cos theta, r * sin theta)
+
+    floret :: Double -> SvgDiagram
+    floret r = D.circle 0.6 # lw none # fc (colors !! n)
+      where
+        n = floor (1.4 * sqrt r) `mod` 10
+        colors = black : (reverse $ D.brewerSet D.YlOrBr 9)
+
+    sunflower :: Int ->  SvgDiagram
+    sunflower n = frame 4 $ position $ take n $ zip mkCoords florets
+      where
+        florets = [ floret (sqrt (fromIntegral i)) | i <- [1 ..]]
+
+mkFilter :: String -> [FilterElement] -> Filter
+mkFilter ident fe = defaultSvg & filterChildren .~ fe & attrId .~ Just ident
+
+gooEffect :: Animation
+gooEffect = mkAnimation 5 $ do
+  s <- oscillate $ signal 0 3
+  emit $ mkBackground "black"
+  emit $ FilterTree $ mkFilter "blur"
+    [FEGaussianBlur $ defaultSvg
+      & gaussianBlurStdDeviationX .~ Num dev
+      & filterResult .~ Just "blur"
+    ] & filterWidth .~ pure (Percent 3)
+      & filterX .~ pure (Percent (-1))
+      & filterHeight .~ pure (Percent 3)
+      & filterY .~ pure (Percent (-1))
+  emit $ FilterTree $ mkFilter "goo"
+    [FEGaussianBlur $ defaultSvg
+      & gaussianBlurStdDeviationX .~ Num dev
+      & filterResult .~ Just "blur"
+    ,FEColorMatrix $ defaultSvg
+      & colorMatrixType .~ Matrix
+      & colorMatrixValues .~ "1 0 0 0 0 \
+                             \0 1 0 0 0 \
+                             \0 0 1 0 0 \
+                             \0 0 0 " ++ show (sharpness*2) ++ " -" ++ show sharpness
+      & filterResult .~ pure "goo"
+    ,FEComposite $ defaultSvg
+      & compositeIn .~ pure SourceGraphic
+      & compositeIn2 .~ pure (SourceRef "goo")
+      & compositeOperator .~ CompositeAtop
+    ] & filterWidth .~ pure (Percent 3)
+      & filterX .~ pure (Percent (-1))
+      & filterHeight .~ pure (Percent 3)
+      & filterY .~ pure (Percent (-1))
+  emit $ translate 0 (-radius*2) $ withFillColor "red" $ mkGroup
+    [ translate (s*(-radius)) 0 circ
+    , translate (s*radius) 0 circ
+    ]
+  emit $ withFillColor "red" $ mkGroup
+    [ translate (s*(-radius)) 0 circ
+    , translate (s*radius) 0 circ
+    ]
+    & filterRef .~ pure (Ref "blur")
+  emit $ translate 0 (radius*2) $ withFillColor "red" $ set filterRef (pure $ Ref "goo")
+    $ mkGroup [ translate (s*(-radius)) 0 circ
+              , translate (s*radius) 0 circ ]
+  where
+    sharpness = 60
+    dev = 10
+    radius = 30
+    circ = CircleTree $ defaultSvg
+      & circleCenter .~ (Num 0, Num 0)
+      & circleRadius .~ Num radius
diff --git a/src/Reanimate/LaTeX.hs b/src/Reanimate/LaTeX.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/LaTeX.hs
@@ -0,0 +1,112 @@
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+module Reanimate.LaTeX (latex,xelatex,latexAlign) where
+
+import           Control.Exception     (SomeException, handle)
+import qualified Data.ByteString       as B
+import           Data.IORef
+import           Data.Map              (Map)
+import qualified Data.Map              as Map
+import Data.Monoid
+import           Reanimate.Cache
+import           Reanimate.Misc
+import           Reanimate.Svg
+import           System.FilePath       (replaceExtension, takeFileName, (</>))
+import           System.IO.Unsafe      (unsafePerformIO)
+
+import           Control.Lens          (over, set, (%~), (&), (.~), (^.))
+import           Data.Text             (Text)
+import qualified Data.Text             as T
+import qualified Data.Text.IO             as T
+import           Graphics.SvgTree      (Document (..), Tree (..), defaultSvg,
+                                        elements, loadSvgFile, parseSvgFile,
+                                        xmlOfDocument)
+import           Text.XML.Light        (elContent)
+import           Text.XML.Light.Output (ppcContent, ppcElement, prettyConfigPP)
+
+latex :: T.Text -> Tree
+latex tex = (unsafePerformIO . (cacheMem . cacheDiskSvg) latexToSVG)
+  ("% plain latex\n" <> tex)
+
+xelatex :: Text -> Tree
+xelatex tex = (unsafePerformIO . (cacheMem . cacheDiskSvg) latexToSVG)
+  ("% xelatex\n" <> tex)
+
+latexAlign :: Text -> Tree
+latexAlign tex = latex $ T.unlines ["\\begin{align*}", tex, "\\end{align*}"]
+
+
+latexToSVG :: Text -> IO Tree
+latexToSVG tex = handle (\(e::SomeException) -> return (failedSvg tex)) $ do
+  latex <- requireExecutable "latex"
+  dvisvgm <- requireExecutable "dvisvgm"
+  withTempDir $ \tmp_dir -> withTempFile "tex" $ \tex_file -> withTempFile "svg" $ \svg_file -> do
+    let dvi_file = tmp_dir </> replaceExtension (takeFileName tex_file) "dvi"
+    writeFile tex_file tex_document
+    appendFile tex_file tex_prologue
+    T.appendFile tex_file tex
+    appendFile tex_file tex_epilogue
+    runCmd latex ["-interaction=batchmode", "-halt-on-error", "-output-directory="++tmp_dir, tex_file]
+    runCmd dvisvgm [ dvi_file
+                   , "--exact"    -- better bboxes.
+                   -- , "--bbox=1,1" -- increase bbox size.
+                   , "--no-fonts" -- use glyphs instead of fonts.
+                   ,"--verbosity=0", "-o",svg_file]
+    svg_data <- B.readFile svg_file
+    case parseSvgFile svg_file svg_data of
+      Nothing  -> error "Malformed svg"
+      Just svg -> return $ unbox $ replaceUses svg
+
+xelatexToSVG :: Text -> IO Tree
+xelatexToSVG tex = handle (\(e::SomeException) -> return (failedSvg tex)) $ do
+  latex <- requireExecutable "xelatex"
+  dvisvgm <- requireExecutable "dvisvgm"
+  withTempDir $ \tmp_dir -> withTempFile "tex" $ \tex_file -> withTempFile "svg" $ \svg_file -> do
+    let dvi_file = tmp_dir </> replaceExtension (takeFileName tex_file) "xdv"
+    writeFile tex_file tex_document
+    appendFile tex_file tex_xelatex
+    appendFile tex_file tex_prologue
+    T.appendFile tex_file tex
+    appendFile tex_file tex_epilogue
+    runCmd latex ["-no-pdf", "-interaction=batchmode", "-halt-on-error", "-output-directory="++tmp_dir, tex_file]
+    runCmd dvisvgm [ dvi_file
+                   , "--exact"    -- better bboxes.
+                   -- , "--bbox=1,1" -- increase bbox size.
+                   , "--no-fonts" -- use glyphs instead of fonts.
+                   ,"--verbosity=0", "-o",svg_file]
+    svg_data <- B.readFile svg_file
+    case parseSvgFile svg_file svg_data of
+      Nothing  -> error "Malformed svg"
+      Just svg -> return $ unbox $ replaceUses svg
+
+failedSvg :: Text -> Tree
+failedSvg tex = defaultSvg
+  -- text_ [ font_size_ "20"
+  --       , fill_ "white"] (toHtml $ "bad latex: "++tex)
+
+tex_document = "\\documentclass[preview]{standalone}\n"
+tex_xelatex =
+  "\\usepackage[UTF8]{ctex}\n"
+tex_prologue =
+  "\\usepackage[english]{babel}\n\
+  \\\usepackage{amsmath}\n\
+  \\\usepackage{amssymb}\n\
+  \\\usepackage{dsfont}\n\
+  \\\usepackage{setspace}\n\
+  \\\usepackage{relsize}\n\
+  \\\usepackage{textcomp}\n\
+  \\\usepackage{mathrsfs}\n\
+  \\\usepackage{calligra}\n\
+  \\\usepackage{wasysym}\n\
+  \\\usepackage{ragged2e}\n\
+  \\\usepackage{physics}\n\
+  \\\usepackage{xcolor}\n\
+  \\\usepackage{textcomp}\n\
+  \\\usepackage{xfrac}\n\
+  \\\usepackage{microtype}\n\
+  \\\linespread{1}\n\
+  \\\begin{document}\n"
+
+tex_epilogue =
+  "\n\
+  \\\end{document}"
diff --git a/src/Reanimate/Misc.hs b/src/Reanimate/Misc.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Misc.hs
@@ -0,0 +1,83 @@
+module Reanimate.Misc
+  ( requireExecutable
+  , runCmd
+  , runCmd_
+  , runCmdLazy
+  , withTempDir
+  , withTempFile
+  ) where
+
+import           Control.Exception (evaluate, finally, throwIO)
+import qualified Data.Text         as T
+import qualified Data.Text.IO      as T
+import           System.Directory  (createDirectory, findExecutable,
+                                    getTemporaryDirectory,
+                                    removeDirectoryRecursive, removeFile)
+import           System.Exit       (ExitCode (..))
+import           System.FilePath   ((<.>), (</>))
+import           System.IO         (hClose, openTempFile, hGetContents, hIsEOF)
+import           System.Process    (readProcessWithExitCode,
+                                    runInteractiveProcess, showCommandForUser,
+                                    waitForProcess)
+
+requireExecutable :: String -> IO FilePath
+requireExecutable exec = do
+  mbPath <- findExecutable exec
+  case mbPath of
+    Nothing   -> error $ "Couldn't find executable: " ++ exec
+    Just path -> return path
+
+runCmd :: FilePath -> [String] -> IO ()
+runCmd exec args = do
+  _ <- runCmd_ exec args
+  return ()
+
+runCmd_ :: FilePath -> [String] -> IO (Either String String)
+runCmd_ exec args = do
+  (ret, stdout, stderr) <- readProcessWithExitCode exec args ""
+  evaluate (length stdout + length stderr)
+  case ret of
+    ExitSuccess -> return (Right stdout)
+    ExitFailure err -> do
+      return $ Left $
+        "Failed to run: " ++ showCommandForUser exec args ++ "\n" ++
+        "Error code: " ++ show err ++ "\n" ++
+        "stderr: " ++ stderr
+
+runCmdLazy :: FilePath -> [String] -> IO (IO (Either String T.Text))
+runCmdLazy exec args = do
+  (inp, out, err, pid) <- runInteractiveProcess exec args Nothing Nothing
+  hClose inp
+  return $ do
+    eof <- hIsEOF out
+    if eof
+      then do
+        stderr <- hGetContents err
+        evaluate (length stderr)
+        ret <- waitForProcess pid
+        case ret of
+          ExitSuccess -> return (Left "")
+          ExitFailure err -> do
+            return $ Left $
+              "Failed to run: " ++ showCommandForUser exec args ++ "\n" ++
+              "Error code: " ++ show err ++ "\n" ++
+              "stderr: " ++ stderr
+      else do
+        line <- T.hGetLine out
+        return (Right line)
+
+withTempDir :: (FilePath -> IO a) -> IO a
+withTempDir action = do
+  dir <- getTemporaryDirectory
+  (path, handle) <- openTempFile dir "reanimate-XXXXXX"
+  hClose handle
+  removeFile path
+  createDirectory (dir </> path)
+  action (dir </> path) `finally` removeDirectoryRecursive (dir </> path)
+
+withTempFile :: String -> (FilePath -> IO a) -> IO a
+withTempFile ext action = do
+  dir <- getTemporaryDirectory
+  (path, handle) <- openTempFile dir ("reanimate-XXXXXX" <.> ext)
+  hClose handle
+  action path `finally` removeFile path
diff --git a/src/Reanimate/Monad.hs b/src/Reanimate/Monad.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Monad.hs
@@ -0,0 +1,150 @@
+module Reanimate.Monad where
+
+import           Control.Arrow         ()
+import qualified Control.Category      as C
+import           Control.Monad.State
+import           Data.Fixed
+import           Data.Fixed            (mod')
+import qualified Data.Map              as M
+import           Data.Monoid           ((<>))
+import           Data.Text             (Text, pack)
+import           Graphics.SvgTree      (Document (..), Number (..), Text (..),
+                                        TextSpan (..), TextSpanContent (..),
+                                        Tree, Tree (..), xmlOfDocument, xmlOfTree)
+import           Reanimate.Svg
+import           Text.XML.Light        (elContent)
+import           Text.XML.Light.Output
+
+import           Reanimate.Combinators (approxFnData, morphPath)
+
+type Duration = Double
+type Time = Double
+
+data Frame a = Frame {unFrame :: Duration -> Time -> State ([Tree] -> [Tree]) a}
+
+instance Functor Frame where
+  fmap fn f = Frame $ \d t -> fmap fn (unFrame f d t)
+
+instance Applicative Frame where
+  pure a = Frame $ \_ _ -> pure a
+  fn <*> fa = Frame $ \d t -> do
+    fn <- unFrame fn d t
+    a <- unFrame fa d t
+    pure (fn a)
+
+instance Monad Frame where
+  return a = Frame $ \_ _ -> pure a
+  f >>= g = Frame $ \d t -> do
+    a <- unFrame f d t
+    unFrame (g a) d t
+
+-- End behavior:
+--   Freeze at last frame
+--   Loop
+--   Disappear
+data Animation = Animation Duration (Frame ())
+
+mkAnimation :: Duration -> Frame () -> Animation
+mkAnimation = Animation
+
+duration :: Animation -> Duration
+duration (Animation d _) = d
+
+emit :: Tree -> Frame ()
+emit svg = Frame $ \_ _ -> modify (.(svg:))
+
+before :: Animation -> Animation -> Animation
+before (Animation d1 (Frame f1)) (Animation d2 (Frame f2)) =
+  Animation (d1+d2) (Frame $ \_ t -> if t < d1 then f1 d1 t else f2 d2 (t-d1))
+
+-- Play two animation concurrently. Shortest animation freezes on last frame.
+sim :: Animation -> Animation -> Animation
+sim (Animation d1 (Frame f1)) (Animation d2 (Frame f2)) =
+  Animation (max d1 d2) $ Frame $ \d t -> do
+    f1 d1 (min d1 t)
+    f2 d2 (min d2 t)
+
+-- Play two animation concurrently. Shortest animation loops.
+simLoop :: Animation -> Animation -> Animation
+simLoop (Animation d1 (Frame f1)) (Animation d2 (Frame f2)) =
+  Animation (max d1 d2) $ Frame $ \d t -> do
+    f1 d1 (t `mod'` d1)
+    f2 d2 (t `mod'` d2)
+
+-- Play two animation concurrently. Animations disappear after playing once.
+simDrop :: Animation -> Animation -> Animation
+simDrop (Animation d1 (Frame f1)) (Animation d2 (Frame f2)) =
+  Animation (max d1 d2) $ Frame $ \d t -> do
+    when (t < d1) (f1 d1 t)
+    when (t < d2) (f2 d2 t)
+
+pause :: Double -> Animation
+pause d = Animation d (pure ())
+
+andThen :: Animation -> Animation -> Animation
+andThen a b = a `sim` (pause (duration a) `before` b)
+
+signal :: Double -> Double -> Frame Double
+signal from to = Frame $ \d t -> pure $
+  from + (to-from)*(t/d)
+
+signalSCurve :: Double -> Double -> Double -> Frame Double
+signalSCurve steepness from to = do
+  s <- signal 0 1
+  let s' = if s < 0.5
+              then 0.5 * (2*s)**steepness
+              else 1-0.5 * (2 - 2*s)**steepness
+  pure $ from + (to-from)*s'
+
+frameAt :: Double -> Animation -> Tree
+frameAt t (Animation d (Frame f)) = mkGroup $ execState (f d (min d t)) id []
+
+renderTree :: Tree -> String
+renderTree t = maybe "" ppElement $ xmlOfTree t
+
+renderSvg :: Maybe Number -> Maybe Number -> Tree -> String
+renderSvg w h t = ppElement $ xmlOfDocument doc
+  where
+    width = 320
+    height = width / (16/9)
+    doc = Document
+      { _viewBox = Just (-width/2, -height/2, width, height)
+      , _width = w
+      , _height = h
+      , _elements = [t]
+      , _definitions = M.empty
+      , _description = ""
+      , _documentLocation = ""
+      }
+
+mapA :: (Tree -> Tree) -> Animation -> Animation
+mapA fn (Animation d f) = Animation d (mapF fn f)
+
+mapF :: (Tree -> Tree) -> Frame a -> Frame a
+mapF fn frame = Frame $ \d t -> do
+  case runState (unFrame frame d t) id of
+    (a, children) -> modify (. (fn (mkGroup (children [])):)) >> pure a
+
+pauseAtEnd :: Double -> Animation -> Animation
+pauseAtEnd p a = a `andThen` pause p
+
+adjustSpeed :: Double -> Animation -> Animation
+adjustSpeed factor (Animation d fn) =
+  Animation (d/factor) $ Frame $ \_dur t -> unFrame fn d (t*factor)
+
+reverseAnimation :: Animation -> Animation
+reverseAnimation (Animation d fn) = Animation d $ Frame $ \_dur t ->
+  unFrame fn d (d-t)
+
+autoReverse :: Animation -> Animation
+autoReverse a = a `before` reverseAnimation a
+
+oscillate :: Frame a -> Frame a
+oscillate f = Frame $ \d t -> do
+  if t < d/2
+    then unFrame f d (t*2)
+    else unFrame f d (d*2-t*2)
+
+repeatAnimation :: Double -> Animation -> Animation
+repeatAnimation n (Animation d f) = Animation (d*n) $ Frame $ \_ t ->
+  unFrame f d (t `mod'` d)
diff --git a/src/Reanimate/Render.hs b/src/Reanimate/Render.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Render.hs
@@ -0,0 +1,105 @@
+module Reanimate.Render
+  ( render
+  , renderSvgs
+  ) where
+
+import           Control.Monad               (forM_)
+import           Control.Parallel.Strategies
+import qualified Data.ByteString.Lazy.Char8  as BS
+import qualified Data.Text                   as T
+import qualified Data.Text.IO                as T
+import           Graphics.SvgTree            (Number (..))
+import           Reanimate.Diagrams
+import           Reanimate.Examples
+import           Reanimate.Misc
+import           Reanimate.Monad
+import           System.Directory            (renameFile)
+import           System.FilePath             (takeExtension, takeFileName,
+                                              (</>))
+import           Text.Printf                 (printf)
+
+renderSvgs :: Animation ->  IO ()
+renderSvgs ani = do
+    let renderedFrames = map (T.concat . T.lines . T.pack . nthFrame) frames
+    mapM_ T.putStrLn (renderedFrames `using` parBuffer 16 rdeepseq)
+  where
+    frames = [0..frameCount-1]
+    rate = 60
+    nthFrame nth = renderSvg Nothing Nothing $ frameAt (recip (fromIntegral rate) * fromIntegral nth) ani
+    frameCount = round (duration ani * fromIntegral rate) :: Int
+    nameTemplate :: String
+    nameTemplate = "render-%05d.svg"
+
+
+data Format = RenderMp4 | RenderGif | RenderWebm | RenderBlank
+
+formatFPS :: Format -> Int
+formatFPS RenderMp4   = 60
+formatFPS RenderGif   = 25
+formatFPS RenderWebm  = 30
+formatFPS RenderBlank = 60
+
+render :: Animation -> FilePath -> IO ()
+render ani target =
+  case takeExtension target of
+    ".mp4"  -> renderFormat RenderMp4 ani target
+    ".gif"  -> renderFormat RenderGif ani target
+    ".webm" -> renderFormat RenderWebm ani target
+    ""      -> renderFormat RenderBlank ani target
+    ext     -> error $ "Unknown media format: " ++ show ext
+
+renderFormat :: Format -> Animation -> FilePath -> IO ()
+renderFormat format ani target = do
+  putStrLn $ "Starting render of animation: " ++ show (round (duration ani)) ++ "s"
+  ffmpeg <- requireExecutable "ffmpeg"
+  generateFrames ani 640 fps $ \template ->
+    withTempFile "txt" $ \progress -> writeFile progress "" >>
+    case format of
+      RenderMp4 ->
+        runCmd ffmpeg ["-r", show fps, "-i", template, "-y"
+                      , "-c:v", "libx264", "-vf", "fps="++show fps
+                      , "-progress", progress
+                      , "-pix_fmt", "yuv420p", target]
+      RenderGif -> withTempFile "png" $ \palette -> do
+        runCmd ffmpeg ["-i", template, "-y"
+                      ,"-vf", "fps="++show fps++",scale=320:-1:flags=lanczos,palettegen"
+                      ,"-t", show (duration ani)
+                      , palette ]
+        runCmd ffmpeg ["-i", template, "-y"
+                      ,"-i", palette
+                      ,"-progress", progress
+                      ,"-filter_complex"
+                      ,"fps="++show fps++",scale=320:-1:flags=lanczos[x];[x][1:v]paletteuse"
+                      ,"-t", show (duration ani)
+                      , target]
+      RenderWebm ->
+        runCmd ffmpeg ["-r", show fps, "-i", template, "-y"
+                      ,"-progress", progress
+                      , "-c:v", "libvpx-vp9", "-vf", "fps="++show fps
+                      , target]
+      RenderBlank -> return ()
+  where
+    fps = formatFPS format
+
+---------------------------------------------------------------------------------
+-- Helpers
+-- XXX: Move to a different module and unify with helpers from LaTeX.
+
+-- XXX: Use threads
+generateFrames ani width_ rate action = withTempDir $ \tmp -> do
+    let frameName nth = tmp </> printf nameTemplate nth
+        rendered = [ renderSvg width height $ nthFrame n | n <- frames]
+                    `using` parBuffer 16 rdeepseq
+    forM_ (zip [0::Int ..] rendered) $ \(n, frame) -> do
+      writeFile (frameName n) frame
+      putStr $ "\r" ++ show (n+1) ++ "/" ++ show frameCount
+    putStrLn "\n"
+    action (tmp </> nameTemplate)
+  where
+    width = Just $ Num width_
+    height = Just $ Num (width_*(9/16))
+    frames = [0..frameCount-1]
+    nthFrame nth = frameAt (recip (fromIntegral rate) * fromIntegral nth) ani
+    frameCount = round (duration ani * fromIntegral rate) :: Int
+    nameTemplate :: String
+    nameTemplate = "render-%05d.svg"
diff --git a/src/Reanimate/Svg.hs b/src/Reanimate/Svg.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Svg.hs
@@ -0,0 +1,496 @@
+module Reanimate.Svg where
+
+import           Codec.Picture               (PixelRGBA8 (..))
+import           Codec.Picture.Types
+import           Control.Arrow
+import           Control.Lens                (over, set, (%~), (&), (.~), (^.))
+import           Control.Monad.Fix
+import           Control.Monad.State
+import           Data.Attoparsec.Text        (parseOnly)
+import           Data.List
+import qualified Data.Map                    as Map
+import           Data.Maybe
+import qualified Data.Text                   as T
+import qualified Geom2D.CubicBezier          as Bezier
+import           Graphics.SvgTree
+import           Graphics.SvgTree.PathParser
+import           Linear.Metric
+import           Linear.V2
+import           Linear.Vector
+import           Reanimate.Svg.NamedColors
+import qualified Reanimate.Transform         as Transform
+
+import           Debug.Trace
+
+defaultDPI :: Dpi
+defaultDPI = 96
+
+replaceUses :: Document -> Document
+replaceUses doc = doc & elements %~ map (mapTree replace)
+                      & definitions .~ Map.empty
+  where
+    replace (UseTree _ Just{}) = error "replaceUses: subtree in use?"
+    replace (UseTree use Nothing) =
+      case Map.lookup (use^.useName) idMap of
+        Nothing -> error $ "Unknown id: " ++ (use^.useName)
+        Just tree ->
+          GroupTree $
+          defaultSvg & groupChildren .~ [tree]
+                     & transform .~ Just [baseToTransformation (use^.useBase)]
+    replace x = x
+    baseToTransformation (x,y) =
+      case (toUserUnit defaultDPI x, toUserUnit defaultDPI y) of
+        (Num a, Num b) -> Translate a b
+        _              -> TransformUnknown
+    docTree = GroupTree $ set groupChildren (doc^.elements) defaultSvg
+    idMap = foldTree updMap Map.empty docTree `Map.union`
+            (doc^.definitions)
+    updMap m tree =
+      case tree^.attrId of
+        Nothing  -> m
+        Just tid -> Map.insert tid tree m
+    elementToTree (ElementGeometry t) = Just t
+    elementToTree _                   = Nothing
+
+docIds :: Document -> [String]
+docIds doc = Map.keys idMap ++ Map.keys (doc^.definitions)
+  where
+    docTree = GroupTree $ set groupChildren (doc^.elements) defaultSvg
+    idMap = foldTree updMap Map.empty docTree
+    updMap m tree =
+      case tree^.attrId of
+        Nothing  -> m
+        Just tid -> Map.insert tid tree m
+
+
+-- Transform out viewbox. defs and CSS rules are discarded.
+unbox :: Document -> Tree
+unbox doc@Document{_viewBox = Just (minx, minw, _width, _height)} =
+  GroupTree $ defaultSvg
+          & groupChildren .~ doc^.elements
+          & transform .~ Just [Translate (-minx) (-minw)]
+unbox doc =
+  GroupTree $ defaultSvg
+    & groupChildren .~ doc^.elements
+
+type CmdM a = State RPoint a
+
+data LineCommand
+  = LineMove RPoint
+  | LineDraw RPoint
+  | LineBezier [RPoint]
+  deriving (Show)
+
+lineToPath :: [LineCommand] -> [PathCommand]
+lineToPath = map worker
+  where
+    worker (LineMove p)         = MoveTo OriginAbsolute [p]
+    worker (LineDraw p)         = LineTo OriginAbsolute [p]
+    worker (LineBezier [a,b,c]) = CurveTo OriginAbsolute [(a,b,c)]
+    worker (LineBezier [a,b])   = QuadraticBezier OriginAbsolute [(a,b)]
+
+partialLine :: Double -> [LineCommand] -> [LineCommand]
+partialLine alpha cmds = evalState (worker 0 cmds) zero
+  where
+    worker d [] = pure []
+    worker d (cmd:xs) = do
+      from <- get
+      len <- lineLength cmd
+      let frac = (targetLen-d) / len
+      if len == 0 || frac > 1
+        then (cmd:) <$> worker (d+len) xs
+        else pure [adjustLineLength frac from cmd]
+    totalLen = evalState (sum <$> mapM lineLength cmds) zero
+    targetLen = totalLen * alpha
+
+adjustLineLength :: Double -> RPoint -> LineCommand -> LineCommand
+adjustLineLength alpha from cmd =
+  case cmd of
+    LineBezier points -> LineBezier $ drop 1 $ partial_bezier_points (from:points) 0 alpha
+    LineMove p -> LineMove p
+    LineDraw t -> LineDraw (lerp alpha t from)
+
+lineLength :: LineCommand -> CmdM Double
+lineLength cmd =
+  case cmd of
+    LineMove to       -> pure 0 <* put to
+    LineDraw to       -> gets (distance to) <* put to
+    LineBezier points -> gets (distance (last points)) <* put (last points)
+
+toLineCommands :: [PathCommand] -> [LineCommand]
+toLineCommands ps = evalState (worker zero Nothing ps) zero
+  where
+    worker startPos mbPrevControlPt [] = pure []
+    worker startPos mbPrevControlPt (cmd:cmds) = do
+      lcmds <- toLineCommand startPos mbPrevControlPt cmd
+      let startPos' =
+            case lcmds of
+              [LineMove pos] -> pos
+              _              -> startPos
+      (lcmds++) <$> worker startPos' (cmdToControlPoint $ last lcmds) cmds
+
+cmdToControlPoint (LineBezier points) = Just (last (init points))
+cmdToControlPoint _                   = Nothing
+
+toLineCommand :: RPoint -> Maybe RPoint -> PathCommand -> CmdM [LineCommand]
+toLineCommand startPos mbPrevControlPt cmd = do
+  case cmd of
+    MoveTo OriginAbsolute []  -> pure []
+    MoveTo OriginAbsolute lst -> put (last lst) *> gets (pure.LineMove)
+    MoveTo OriginRelative lst -> modify (+ sum lst) *> gets (pure.LineMove)
+    LineTo OriginAbsolute lst -> forM lst (\to -> put to *> pure (LineDraw to))
+    LineTo OriginRelative lst -> forM lst (\to -> modify (+to) *> gets LineDraw)
+    HorizontalTo OriginAbsolute lst ->
+      forM lst $ \x -> modify (_x .~ x) *> gets LineDraw
+    HorizontalTo OriginRelative lst ->
+      forM lst $ \x -> modify (_x %~ (+x)) *> gets LineDraw
+    VerticalTo OriginAbsolute lst ->
+      forM lst $ \y -> modify (_y .~ y) *> gets LineDraw
+    VerticalTo OriginRelative lst ->
+      forM lst $ \y -> modify (_y %~ (+y)) *> gets LineDraw
+    CurveTo OriginAbsolute quads -> do
+      forM quads $ \(a,b,c) -> put c *> pure (LineBezier [a,b,c])
+    CurveTo OriginRelative quads -> do
+      forM quads $ \(a,b,c) -> do
+        from <- get <* modify (+c)
+        pure $ LineBezier $ map (+from) [a,b,c]
+    SmoothCurveTo o lst -> mfix $ \result -> do
+      let ctrl = mbPrevControlPt : map cmdToControlPoint result
+      forM (zip lst ctrl) $ \((c2,to), mbControl) -> do
+        from <- get <* adjustPosition o to
+        let c1 = maybe (makeAbsolute o from c2) (mirrorPoint from) mbControl
+        pure $ LineBezier [c1,makeAbsolute o from c2,makeAbsolute o from to]
+    QuadraticBezier OriginAbsolute pairs -> do
+      forM pairs $ \(a,b) -> put b *> pure (LineBezier [a,b])
+    QuadraticBezier OriginRelative pairs -> do
+      forM pairs $ \(a,b) -> do
+        from <- get <* modify (+b)
+        pure $ LineBezier $ map (+from) [a,b]
+    SmoothQuadraticBezierCurveTo o lst -> mfix $ \result -> do
+      let ctrl = mbPrevControlPt : map cmdToControlPoint result
+      forM (zip lst ctrl) $ \(to, mbControl) -> do
+        from <- get <* adjustPosition o to
+        let c1 = maybe from (mirrorPoint from) mbControl
+        pure $ LineBezier [c1,makeAbsolute o from to]
+    EllipticalArc o points -> concat <$>
+      (forM points $ \(rotX, rotY, angle, largeArc, sweepFlag, to) -> do
+        from <- get <* adjustPosition o to
+        return $ convertSvgArc from rotX rotY angle largeArc sweepFlag (makeAbsolute o from to))
+    EndPath -> put startPos *> pure [LineDraw startPos]
+  where
+    mirrorPoint c p = c*2-p
+    adjustPosition OriginRelative p = modify (+p)
+    adjustPosition OriginAbsolute p = put p
+    makeAbsolute OriginAbsolute from p = p
+    makeAbsolute OriginRelative from p = from+p
+
+
+calculateVectorAngle :: Double -> Double -> Double -> Double -> Double
+calculateVectorAngle ux uy vx vy
+    | tb >= ta
+        = tb - ta
+    | otherwise
+        = pi * 2 - (ta - tb)
+    where
+        ta = atan2 uy ux
+        tb = atan2 vy vx
+
+-- ported from: https://github.com/vvvv/SVG/blob/master/Source/Paths/SvgArcSegment.cs
+convertSvgArc :: RPoint -> Coord -> Coord -> Coord -> Bool -> Bool -> RPoint -> [LineCommand]
+convertSvgArc (V2 x0 y0) radiusX radiusY angle largeArcFlag sweepFlag (V2 x y)
+    | x0 == x && y0 == y
+        = []
+    | radiusX == 0.0 && radiusY == 0.0
+        = [LineDraw (V2 x y)]
+    | otherwise
+        = calcSegments x0 y0 theta1' segments'
+    where
+        sinPhi = sin (angle * pi/180)
+        cosPhi = cos (angle * pi/180)
+
+        x1dash = cosPhi * (x0 - x) / 2.0 + sinPhi * (y0 - y) / 2.0
+        y1dash = -sinPhi * (x0 - x) / 2.0 + cosPhi * (y0 - y) / 2.0
+
+        numerator = radiusX * radiusX * radiusY * radiusY - radiusX * radiusX * y1dash * y1dash - radiusY * radiusY * x1dash * x1dash
+
+        s = sqrt(1.0 - numerator / (radiusX * radiusX * radiusY * radiusY))
+        rx   = if (numerator < 0.0) then (radiusX * s) else radiusX
+        ry   = if (numerator < 0.0) then (radiusY * s) else radiusY
+        root = if (numerator < 0.0)
+                then (0.0)
+                else ((if ((largeArcFlag && sweepFlag) || (not largeArcFlag && not sweepFlag)) then (-1.0) else 1.0) *
+                        sqrt(numerator / (radiusX * radiusX * y1dash * y1dash + radiusY * radiusY * x1dash * x1dash)))
+
+        cxdash = root * rx * y1dash / ry
+        cydash = -root * ry * x1dash / rx
+
+        cx = cosPhi * cxdash - sinPhi * cydash + (x0 + x) / 2.0
+        cy = sinPhi * cxdash + cosPhi * cydash + (y0 + y) / 2.0
+
+        theta1'  = calculateVectorAngle 1.0 0.0 ((x1dash - cxdash) / rx) ((y1dash - cydash) / ry)
+        dtheta' = calculateVectorAngle ((x1dash - cxdash) / rx) ((y1dash - cydash) / ry) ((-x1dash - cxdash) / rx) ((-y1dash - cydash) / ry)
+        dtheta  = if (not sweepFlag && dtheta' > 0)
+                    then  (dtheta' - 2 * pi)
+                    else  (if (sweepFlag && dtheta' < 0) then (dtheta' + 2 * pi) else dtheta')
+
+        segments' = ceiling (abs (dtheta / (pi / 2.0)))
+        delta = dtheta / fromInteger segments'
+        t = 8.0 / 3.0 * sin(delta / 4.0) * sin(delta / 4.0) / sin(delta / 2.0)
+
+        calcSegments startX startY theta1 segments
+            | segments == 0
+                = []
+            | otherwise
+                = LineBezier [ V2 (startX + dx1) (startY + dy1)
+                             , V2 (endpointX + dxe) (endpointY + dye)
+                             , V2 endpointX endpointY ] : calcSegments endpointX endpointY theta2 (segments - 1)
+            where
+                cosTheta1 = cos theta1
+                sinTheta1 = sin theta1
+                theta2 = theta1 + delta
+                cosTheta2 = cos theta2
+                sinTheta2 = sin theta2
+
+                endpointX = cosPhi * rx * cosTheta2 - sinPhi * ry * sinTheta2 + cx
+                endpointY = sinPhi * rx * cosTheta2 + cosPhi * ry * sinTheta2 + cy
+
+                dx1 = t * (-cosPhi * rx * sinTheta1 - sinPhi * ry * cosTheta1)
+                dy1 = t * (-sinPhi * rx * sinTheta1 + cosPhi * ry * cosTheta1)
+
+                dxe = t * (cosPhi * rx * sinTheta2 + sinPhi * ry * cosTheta2)
+                dye = t * (sinPhi * rx * sinTheta2 - cosPhi * ry * cosTheta2)
+
+
+-- Algorithm taken from manim. It's magic.
+bezier :: [RPoint] -> Double -> RPoint
+bezier points t = sum
+    [ point ^* (((1-t)**(fromIntegral $ n-k)) * (t**fromIntegral k) * fromIntegral (choose n k))
+    | (k, point) <- zip [0..] points ]
+  where
+    n = length points -1
+    choose n k = product [n,n-1 .. n-k+1] `div` product [1..k]
+
+partial_bezier_points :: [RPoint] -> Double -> Double -> [RPoint]
+partial_bezier_points points a b
+  | isNaN end_prop || isInfinite end_prop = replicate (length points) (last points)
+  | otherwise = [ bezier (take (i+1) a_to_1) end_prop | i <- [0..length points-1] ]
+  where
+    a_to_1 = [ bezier (drop i points) a | i <- [0..length points-1] ]
+    end_prop = (b-a) / (1-a)
+
+
+
+interpolatePathCommands :: Double -> [PathCommand] -> [PathCommand]
+interpolatePathCommands alpha = lineToPath . partialLine alpha . toLineCommands
+
+partialSvg :: Double -> Tree -> Tree
+partialSvg alpha = mapTree worker
+  where
+    worker (PathTree path) =
+      PathTree $ path & pathDefinition %~ lineToPath . partialLine alpha . toLineCommands
+    worker t = t
+
+-- (x,y,w,h)
+boundingBox :: Tree -> (Double, Double, Double, Double)
+boundingBox t =
+    case svgBoundingPoints t of
+      [] -> (0,0,0,0)
+      (V2 x y:rest) ->
+        let (minx, miny, maxx, maxy) = foldl' worker (x, y, x, y) rest
+        in (minx, miny, maxx-minx, maxy-miny)
+  where
+    worker (minx, miny, maxx, maxy) (V2 x y) =
+      (min minx x, min miny y, max maxx x, max maxy y)
+
+linePoints :: [LineCommand] -> [RPoint]
+linePoints = worker zero
+  where
+    worker from [] = []
+    worker from (x:xs) =
+      case x of
+        LineMove to     -> worker to xs
+        LineDraw to     -> from:to:worker to xs
+        LineBezier ctrl -> -- approximation
+          [ last (partial_bezier_points (from:ctrl) 0 (recip chunks*i)) | i <- [0..chunks]] ++
+          worker (last ctrl) xs
+    chunks = 10
+
+svgBoundingPoints :: Tree -> [RPoint]
+svgBoundingPoints t = map (Transform.transformPoint m) $
+    case t of
+      None            -> []
+      UseTree{}       -> []
+      GroupTree g     -> concatMap svgBoundingPoints (g^.groupChildren)
+      SymbolTree (Symbol g) -> concatMap svgBoundingPoints (g^.groupChildren)
+      FilterTree{}    -> []
+      DefinitionTree{} -> []
+      PathTree p      -> linePoints $ toLineCommands (p^.pathDefinition)
+      CircleTree{}    -> error "CircleTree"
+      PolyLineTree{}  -> error "PolyLineTree"
+      EllipseTree{}   -> error "EllipseTree"
+      LineTree{}      -> error "LineTree"
+      RectangleTree rect ->
+        case mapTuple (toUserUnit defaultDPI) (rect^.rectUpperLeftCorner) of
+          (Num x, Num y) -> [V2 x y] ++
+            case mapTuple (fmap $ toUserUnit defaultDPI) (rect^.rectWidth, rect^.rectHeight) of
+              (Just (Num w), Just (Num h)) -> [V2 (x+w) (y+h)]
+              _              -> []
+          _ -> []
+      TextTree{}      -> []
+      ImageTree{}     -> []
+      MeshGradientTree{} -> []
+  where
+    m = Transform.mkMatrix (t^.transform)
+    mapTuple f = f *** f
+
+withTransformations :: [Transformation] -> Tree -> Tree
+withTransformations transformations t =
+  mkGroup [t] & transform .~ Just transformations
+
+translate :: Double -> Double -> Tree -> Tree
+translate x y = withTransformations [Translate x y]
+
+rotate :: Double -> Tree -> Tree
+rotate a = withTransformations [Rotate a Nothing]
+
+rotateAround :: Double -> RPoint -> Tree -> Tree
+rotateAround a (V2 x y) = withTransformations [Rotate a (Just (x,y))]
+
+rotateAroundCenter :: Double -> Tree -> Tree
+rotateAroundCenter a t =
+    rotateAround a (V2 (x+w/h) (y+h/2)) t
+  where
+    (x,y,w,h) = boundingBox t
+
+scale :: Double -> Tree -> Tree
+scale a = withTransformations [Scale a Nothing]
+
+scaleXY :: Double -> Double -> Tree -> Tree
+scaleXY x y = withTransformations [Scale x (Just y)]
+
+-- scalePoints :: Double -> Tree -> Tree
+-- scalePoints a = scalePointsXY a a
+--
+-- scalePointsXY :: Double -> Double -> Tree -> Tree
+-- scalePointsXY x y = mapTree worker
+--   where
+--     worker t =
+--       case t of
+--         None            -> t
+--         UseTree{}       -> t
+--         GroupTree{}     -> t
+--         SymbolTree{}    -> t
+--         PathTree p      -> PathTree $ p
+--           & pathDefinition %~ lineToPath . map scaleCmd . toLineCommands
+--         CircleTree{}    -> error "scalePointsXY CircleTree"
+--         PolyLineTree{}  -> error "scalePointsXY PolyLineTree"
+--         EllipseTree{}   -> error "scalePointsXY EllipseTree"
+--         LineTree{}      -> error "scalePointsXY LineTree"
+--         RectangleTree rect -> RectangleTree $ rect
+--           & rectUpperLeftCorner %~ (mapNumber (*x) *** mapNumber (*y))
+--           & rectWidth %~ mapNumber (*x)
+--           & rectHeight %~ mapNumber (*y)
+--         TextTree{}      -> t
+--         ImageTree{}     -> t
+--         MeshGradientTree{} -> t
+--     scaleCmd (LineMove to) = LineMove (to * V2 x y)
+--     scaleCmd (LineDraw to) = LineDraw (to * V2 x y)
+--     scaleCmd (LineBezier points) = LineBezier (map (*V2 x y) points)
+
+center :: Tree -> Tree
+center t = translate (-x-w/2) (-y-h/2) t
+  where
+    (x, y, w, h) = boundingBox t
+
+mkColor :: String -> Texture
+mkColor name =
+  case Map.lookup name svgNamedColors of
+    Nothing -> ColorRef (PixelRGBA8 240 248 255 255)
+    Just c  -> ColorRef c
+
+withStrokeColor :: String -> Tree -> Tree
+withStrokeColor color = strokeColor .~ pure (mkColor color)
+
+withFillColor :: String -> Tree -> Tree
+withFillColor color = fillColor .~ pure (mkColor color)
+
+withFillColorPixel :: PixelRGBA8 -> Tree -> Tree
+withFillColorPixel color = fillColor .~ pure (ColorRef color)
+
+withFillOpacity :: Double -> Tree -> Tree
+withFillOpacity opacity = fillOpacity .~ Just (realToFrac opacity)
+
+withStrokeWidth :: Number -> Tree -> Tree
+withStrokeWidth width = strokeWidth .~ pure width
+
+withClipPathRef :: ElementRef -> Tree -> Tree
+withClipPathRef ref = clipPathRef .~ pure ref
+
+mkRect :: Point -> Number -> Number -> Tree
+mkRect corner width height = RectangleTree $ defaultSvg
+  & rectUpperLeftCorner .~ corner
+  & rectWidth .~ Just width
+  & rectHeight .~ Just height
+
+mkBoundingRect :: Tree -> Double -> Tree
+mkBoundingRect src margin =
+    mkRect (Num $ x-margin, Num $ y-margin) (Num $ w+margin*2) (Num $ h+margin*2)
+  where
+    (x, y, w, h) = boundingBox src
+
+mkLine :: Point -> Point -> Tree
+mkLine point1 point2 = LineTree $ defaultSvg
+  & linePoint1 .~ point1
+  & linePoint2 .~ point2
+
+mkGroup :: [Tree] -> Tree
+mkGroup forest = GroupTree $ defaultSvg
+  & groupChildren .~ forest
+
+mkPathString :: String -> Tree
+mkPathString = mkPathText . T.pack
+
+mkPathText :: T.Text -> Tree
+mkPathText str =
+  case parseOnly pathParser str of
+    Left err   -> error err
+    Right cmds -> PathTree $ defaultSvg & pathDefinition .~ cmds
+
+mkLinePath :: [(Double, Double)] -> Tree
+mkLinePath [] = mkGroup []
+mkLinePath ((startX, startY):rest) =
+    PathTree $ defaultSvg & pathDefinition .~ cmds
+  where
+    cmds = [ MoveTo OriginAbsolute [V2 startX startY]
+           , LineTo OriginAbsolute [ V2 x y | (x, y) <- rest ] ]
+
+mkBackground :: String -> Tree
+mkBackground color = withFillColor color $ mkRect (Num $ -320/2, Num $ -180/2) (Percent 1) (Percent 1)
+
+mkBackgroundPixel :: PixelRGBA8 -> Tree
+mkBackgroundPixel pixel =
+    withFillColorPixel pixel $ mkRect (Num $ -320/2, Num $ -180/2) (Percent 1) (Percent 1)
+
+withSubglyphs :: [Int] -> (Tree -> Tree) -> Tree -> Tree
+withSubglyphs target fn t = evalState (worker t) 0
+  where
+    worker :: Tree -> State Int Tree
+    worker t =
+      case t of
+        GroupTree g -> do
+          cs <- mapM worker (g ^. groupChildren)
+          return $ GroupTree $ g & groupChildren .~ cs
+        PathTree{} -> handleGlyph t
+        CircleTree{} -> handleGlyph t
+        PolyLineTree{} -> handleGlyph t
+        PolygonTree{} -> handleGlyph t
+        EllipseTree{} -> handleGlyph t
+        LineTree{} -> handleGlyph t
+        RectangleTree{} -> handleGlyph t
+        _ -> return t
+    handleGlyph :: Tree -> State Int Tree
+    handleGlyph t = do
+      n <- get <* modify (+1)
+      if n `elem` target
+        then return $ fn t
+        else return t
diff --git a/src/Reanimate/Svg/NamedColors.hs b/src/Reanimate/Svg/NamedColors.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Svg/NamedColors.hs
@@ -0,0 +1,157 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Reanimate.Svg.NamedColors( svgNamedColors ) where
+
+import qualified Data.Map as M
+import Codec.Picture( PixelRGBA8( .. ) )
+import Data.Text( Text )
+
+svgNamedColors :: M.Map String PixelRGBA8
+svgNamedColors = M.fromList
+  [ ("aliceblue"           , PixelRGBA8 240 248 255 255)
+  , ("antiquewhite"        , PixelRGBA8 250 235 215 255)
+  , ("aqua"                , PixelRGBA8   0 255 255 255)
+  , ("aquamarine"          , PixelRGBA8 127 255 212 255)
+  , ("azure"               , PixelRGBA8 240 255 255 255)
+  , ("beige"               , PixelRGBA8 245 245 220 255)
+  , ("bisque"              , PixelRGBA8 255 228 196 255)
+  , ("black"               , PixelRGBA8   0   0   0 255)
+  , ("blanchedalmond"      , PixelRGBA8 255 235 205 255)
+  , ("blue"                , PixelRGBA8   0   0 255 255)
+  , ("blueviolet"          , PixelRGBA8 138  43 226 255)
+  , ("brown"               , PixelRGBA8 165  42  42 255)
+  , ("burlywood"           , PixelRGBA8 222 184 135 255)
+  , ("cadetblue"           , PixelRGBA8  95 158 160 255)
+  , ("chartreuse"          , PixelRGBA8 127 255   0 255)
+  , ("chocolate"           , PixelRGBA8 210 105  30 255)
+  , ("coral"               , PixelRGBA8 255 127  80 255)
+  , ("cornflowerblue"      , PixelRGBA8 100 149 237 255)
+  , ("cornsilk"            , PixelRGBA8 255 248 220 255)
+  , ("crimson"             , PixelRGBA8 220  20  60 255)
+  , ("cyan"                , PixelRGBA8   0 255 255 255)
+  , ("darkblue"            , PixelRGBA8   0   0 139 255)
+  , ("darkcyan"            , PixelRGBA8   0 139 139 255)
+  , ("darkgoldenrod"       , PixelRGBA8 184 134  11 255)
+  , ("darkgray"            , PixelRGBA8 169 169 169 255)
+  , ("darkgreen"           , PixelRGBA8   0 100   0 255)
+  , ("darkgrey"            , PixelRGBA8 169 169 169 255)
+  , ("darkkhaki"           , PixelRGBA8 189 183 107 255)
+  , ("darkmagenta"         , PixelRGBA8 139   0 139 255)
+  , ("darkolivegreen"      , PixelRGBA8  85 107  47 255)
+  , ("darkorange"          , PixelRGBA8 255 140   0 255)
+  , ("darkorchid"          , PixelRGBA8 153  50 204 255)
+  , ("darkred"             , PixelRGBA8 139   0   0 255)
+  , ("darksalmon"          , PixelRGBA8 233 150 122 255)
+  , ("darkseagreen"        , PixelRGBA8 143 188 143 255)
+  , ("darkslateblue"       , PixelRGBA8  72  61 139 255)
+  , ("darkslategray"       , PixelRGBA8  47  79  79 255)
+  , ("darkslategrey"       , PixelRGBA8  47  79  79 255)
+  , ("darkturquoise"       , PixelRGBA8   0 206 209 255)
+  , ("darkviolet"          , PixelRGBA8 148   0 211 255)
+  , ("deeppink"            , PixelRGBA8 255  20 147 255)
+  , ("deepskyblue"         , PixelRGBA8   0 191 255 255)
+  , ("dimgray"             , PixelRGBA8 105 105 105 255)
+  , ("dimgrey"             , PixelRGBA8 105 105 105 255)
+  , ("dodgerblue"          , PixelRGBA8  30 144 255 255)
+  , ("firebrick"           , PixelRGBA8 178  34  34 255)
+  , ("floralwhite"         , PixelRGBA8 255 250 240 255)
+  , ("forestgreen"         , PixelRGBA8  34 139  34 255)
+  , ("fuchsia"             , PixelRGBA8 255   0 255 255)
+  , ("gainsboro"           , PixelRGBA8 220 220 220 255)
+  , ("ghostwhite"          , PixelRGBA8 248 248 255 255)
+  , ("gold"                , PixelRGBA8 255 215   0 255)
+  , ("goldenrod"           , PixelRGBA8 218 165  32 255)
+  , ("gray"                , PixelRGBA8 128 128 128 255)
+  , ("grey"                , PixelRGBA8 128 128 128 255)
+  , ("green"               , PixelRGBA8   0 128   0 255)
+  , ("greenyellow"         , PixelRGBA8 173 255  47 255)
+  , ("honeydew"            , PixelRGBA8 240 255 240 255)
+  , ("hotpink"             , PixelRGBA8 255 105 180 255)
+  , ("indianred"           , PixelRGBA8 205  92  92 255)
+  , ("indigo"              , PixelRGBA8  75   0 130 255)
+  , ("ivory"               , PixelRGBA8 255 255 240 255)
+  , ("khaki"               , PixelRGBA8 240 230 140 255)
+  , ("lavender"            , PixelRGBA8 230 230 250 255)
+  , ("lavenderblush"       , PixelRGBA8 255 240 245 255)
+  , ("lawngreen"           , PixelRGBA8 124 252   0 255)
+  , ("lemonchiffon"        , PixelRGBA8 255 250 205 255)
+  , ("lightblue"           , PixelRGBA8 173 216 230 255)
+  , ("lightcoral"          , PixelRGBA8 240 128 128 255)
+  , ("lightcyan"           , PixelRGBA8 224 255 255 255)
+  , ("lightgoldenrodyellow", PixelRGBA8 250 250 210 255)
+  , ("lightgray"           , PixelRGBA8 211 211 211 255)
+  , ("lightgreen"          , PixelRGBA8 144 238 144 255)
+  , ("lightgrey"           , PixelRGBA8 211 211 211 255)
+  , ("lightpink"           , PixelRGBA8 255 182 193 255)
+  , ("lightsalmon"         , PixelRGBA8 255 160 122 255)
+  , ("lightseagreen"       , PixelRGBA8  32 178 170 255)
+  , ("lightskyblue"        , PixelRGBA8 135 206 250 255)
+  , ("lightslategray"      , PixelRGBA8 119 136 153 255)
+  , ("lightslategrey"      , PixelRGBA8 119 136 153 255)
+  , ("lightsteelblue"      , PixelRGBA8 176 196 222 255)
+  , ("lightyellow"         , PixelRGBA8 255 255 224 255)
+  , ("lime"                , PixelRGBA8   0 255   0 255)
+  , ("limegreen"           , PixelRGBA8  50 205  50 255)
+  , ("linen"               , PixelRGBA8 250 240 230 255)
+  , ("magenta"             , PixelRGBA8 255   0 255 255)
+  , ("maroon"              , PixelRGBA8 128   0   0 255)
+  , ("mediumaquamarine"    , PixelRGBA8 102 205 170 255)
+  , ("mediumblue"          , PixelRGBA8   0   0 205 255)
+  , ("mediumorchid"        , PixelRGBA8 186  85 211 255)
+  , ("mediumpurple"        , PixelRGBA8 147 112 219 255)
+  , ("mediumseagreen"      , PixelRGBA8  60 179 113 255)
+  , ("mediumslateblue"     , PixelRGBA8 123 104 238 255)
+  , ("mediumspringgreen"   , PixelRGBA8   0 250 154 255)
+  , ("mediumturquoise"     , PixelRGBA8  72 209 204 255)
+  , ("mediumvioletred"     , PixelRGBA8 199  21 133 255)
+  , ("midnightblue"        , PixelRGBA8  25  25 112 255)
+  , ("mintcream"           , PixelRGBA8 245 255 250 255)
+  , ("mistyrose"           , PixelRGBA8 255 228 225 255)
+  , ("moccasin"            , PixelRGBA8 255 228 181 255)
+  , ("navajowhite"         , PixelRGBA8 255 222 173 255)
+  , ("navy"                , PixelRGBA8   0   0 128 255)
+  , ("oldlace"             , PixelRGBA8 253 245 230 255)
+  , ("olive"               , PixelRGBA8 128 128   0 255)
+  , ("olivedrab"           , PixelRGBA8 107 142  35 255)
+  , ("orange"              , PixelRGBA8 255 165   0 255)
+  , ("orangered"           , PixelRGBA8 255  69   0 255)
+  , ("orchid"              , PixelRGBA8 218 112 214 255)
+  , ("palegoldenrod"       , PixelRGBA8 238 232 170 255)
+  , ("palegreen"           , PixelRGBA8 152 251 152 255)
+  , ("paleturquoise"       , PixelRGBA8 175 238 238 255)
+  , ("palevioletred"       , PixelRGBA8 219 112 147 255)
+  , ("papayawhip"          , PixelRGBA8 255 239 213 255)
+  , ("peachpuff"           , PixelRGBA8 255 218 185 255)
+  , ("peru"                , PixelRGBA8 205 133  63 255)
+  , ("pink"                , PixelRGBA8 255 192 203 255)
+  , ("plum"                , PixelRGBA8 221 160 221 255)
+  , ("powderblue"          , PixelRGBA8 176 224 230 255)
+  , ("purple"              , PixelRGBA8 128   0 128 255)
+  , ("red"                 , PixelRGBA8 255   0   0 255)
+  , ("rosybrown"           , PixelRGBA8 188 143 143 255)
+  , ("royalblue"           , PixelRGBA8  65 105 225 255)
+  , ("saddlebrown"         , PixelRGBA8 139  69  19 255)
+  , ("salmon"              , PixelRGBA8 250 128 114 255)
+  , ("sandybrown"          , PixelRGBA8 244 164  96 255)
+  , ("seagreen"            , PixelRGBA8  46 139  87 255)
+  , ("seashell"            , PixelRGBA8 255 245 238 255)
+  , ("sienna"              , PixelRGBA8 160  82  45 255)
+  , ("silver"              , PixelRGBA8 192 192 192 255)
+  , ("skyblue"             , PixelRGBA8 135 206 235 255)
+  , ("slateblue"           , PixelRGBA8 106  90 205 255)
+  , ("slategray"           , PixelRGBA8 112 128 144 255)
+  , ("slategrey"           , PixelRGBA8 112 128 144 255)
+  , ("snow"                , PixelRGBA8 255 250 250 255)
+  , ("springgreen"         , PixelRGBA8   0 255 127 255)
+  , ("steelblue"           , PixelRGBA8  70 130 180 255)
+  , ("tan"                 , PixelRGBA8 210 180 140 255)
+  , ("teal"                , PixelRGBA8   0 128 128 255)
+  , ("thistle"             , PixelRGBA8 216 191 216 255)
+  , ("tomato"              , PixelRGBA8 255  99  71 255)
+  , ("turquoise"           , PixelRGBA8  64 224 208 255)
+  , ("violet"              , PixelRGBA8 238 130 238 255)
+  , ("wheat"               , PixelRGBA8 245 222 179 255)
+  , ("white"               , PixelRGBA8 255 255 255 255)
+  , ("whitesmoke"          , PixelRGBA8 245 245 245 255)
+  , ("yellow"              , PixelRGBA8 255 255   0 255)
+  , ("yellowgreen"         , PixelRGBA8 154 205  50 255)
+  ]
diff --git a/src/Reanimate/Transform.hs b/src/Reanimate/Transform.hs
new file mode 100644
--- /dev/null
+++ b/src/Reanimate/Transform.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE PackageImports #-}
+module Reanimate.Transform
+  ( identity
+  , transformPoint
+  , mkMatrix
+  ) where
+
+-- XXX: Use Linear.Matrix instead of Data.Matrix to drop the 'matrix' dependency.
+import           Data.List
+import           "matrix" Data.Matrix (Matrix)
+import qualified "matrix" Data.Matrix as M
+import           Data.Maybe
+import           Graphics.SvgTree
+import           Linear.V2
+
+type TMatrix = Matrix Coord
+
+identity :: TMatrix
+identity = M.identity 3
+
+fromList :: [Coord] -> TMatrix
+fromList [a,b,c,d,e,f] = M.fromList 3 3 [a,c,e,b,d,f,0,0,1]
+fromList _             = error "Reanimate.Transform.fromList: bad input"
+
+transformPoint :: TMatrix -> RPoint -> RPoint
+transformPoint m (V2 x y) = V2 (a*x +c*y + e) (b*x + d*y +f)
+  where
+    (a:c:e:b:d:f:_) = M.toList m
+
+mkMatrix :: Maybe [Transformation] -> TMatrix
+mkMatrix Nothing   = identity
+mkMatrix (Just ts) = foldl' (*) identity (map transformationMatrix ts)
+
+transformationMatrix :: Transformation -> TMatrix
+transformationMatrix transformation =
+  case transformation of
+    TransformMatrix a b c d e f -> fromList [a,b,c,d,e,f]
+    Translate x y               -> translate x y
+    Scale sx mbSy               -> fromList [sx,0,0,fromMaybe sx mbSy,0,0]
+    Rotate a Nothing            -> rotate a
+    Rotate a (Just (x,y))       -> translate x y * rotate a * translate (-x) (-y)
+    SkewX a                     -> fromList [1,0,tan (a*pi/180),1,0,0]
+    SkewY a                     -> fromList [1,tan (a*pi/180),0,1,0,0]
+    TransformUnknown            -> identity
+  where
+    translate x y = fromList [1,0,0,1,x,y]
+    rotate a = fromList [cos r,sin r,-sin r,cos r,0,0]
+      where r = a * pi / 180
diff --git a/viewer/build/index.html b/viewer/build/index.html
new file mode 100644
--- /dev/null
+++ b/viewer/build/index.html
@@ -0,0 +1,1 @@
+<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="./manifest.json"/><title>Reanimate Playground</title><link href="./static/css/main.6efe09fd.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(l){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],f=0,i=[];f<n.length;f++)t=n[f],p[t]&&i.push(p[t][0]),p[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(l[r]=o[r]);for(s&&s(e);i.length;)i.shift()();return c.push.apply(c,u||[]),a()}function a(){for(var e,r=0;r<c.length;r++){for(var t=c[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==p[u]&&(n=!1)}n&&(c.splice(r--,1),e=f(f.s=t[0]))}return e}var t={},p={1:0},c=[];function f(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return l[e].call(r.exports,r,r.exports,f),r.l=!0,r.exports}f.m=l,f.c=t,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(r,e){if(1&e&&(r=f(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)f.d(t,n,function(e){return r[e]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="./";var r=window.webpackJsonp=window.webpackJsonp||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;a()}([])</script><script src="./static/js/2.772a56e7.chunk.js"></script><script src="./static/js/main.db22f45d.chunk.js"></script></body></html>
diff --git a/viewer/build/service-worker.js b/viewer/build/service-worker.js
new file mode 100644
--- /dev/null
+++ b/viewer/build/service-worker.js
@@ -0,0 +1,34 @@
+/**
+ * Welcome to your Workbox-powered service worker!
+ *
+ * You'll need to register this file in your web app and you should
+ * disable HTTP caching for this file too.
+ * See https://goo.gl/nhQhGp
+ *
+ * The rest of the code is auto-generated. Please don't update this file
+ * directly; instead, make changes to your Workbox build configuration
+ * and re-run your build process.
+ * See https://goo.gl/2aRDsh
+ */
+
+importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.3/workbox-sw.js");
+
+importScripts(
+  "./precache-manifest.15b8d497ab10704d87b84878b92d08cf.js"
+);
+
+workbox.clientsClaim();
+
+/**
+ * The workboxSW.precacheAndRoute() method efficiently caches and responds to
+ * requests for URLs in the manifest.
+ * See https://goo.gl/S9QRab
+ */
+self.__precacheManifest = [].concat(self.__precacheManifest || []);
+workbox.precaching.suppressWarnings();
+workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
+
+workbox.routing.registerNavigationRoute("./index.html", {
+  
+  blacklist: [/^\/_/,/\/[^\/]+\.[^\/]+$/],
+});
diff --git a/viewer/build/static/css/main.6efe09fd.chunk.css b/viewer/build/static/css/main.6efe09fd.chunk.css
new file mode 100644
--- /dev/null
+++ b/viewer/build/static/css/main.6efe09fd.chunk.css
@@ -0,0 +1,2 @@
+body{margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}.App{height:100vh;background-color:#282c34;color:#fff;display:grid;grid-template-columns:1fr;grid-template-rows:auto;grid-auto-flow:column;-webkit-align-items:center;align-items:center;overflow:hidden}.controls{text-align:center}.controls svg{padding-left:5px;padding-right:5px}.viewer{position:static}.viewer svg{max-width:100vw;max-height:100vh;margin-top:auto;margin-bottom:auto}div.messages{position:fixed;top:0;width:100%;background:#282c34}div.messages pre{margin:0}.home{color:#fff;text-align:center;float:right;margin-right:2em}
+/*# sourceMappingURL=main.6efe09fd.chunk.css.map */
diff --git a/viewer/build/static/js/2.772a56e7.chunk.js b/viewer/build/static/js/2.772a56e7.chunk.js
new file mode 100644
--- /dev/null
+++ b/viewer/build/static/js/2.772a56e7.chunk.js
@@ -0,0 +1,2 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[2],[function(e,t,n){"use strict";e.exports=n(11)},function(e,t,n){"use strict";function r(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}n.d(t,"a",function(){return r})},function(e,t,n){"use strict";function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{},l=Object.keys(n);"function"===typeof Object.getOwnPropertySymbols&&(l=l.concat(Object.getOwnPropertySymbols(n).filter(function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),l.forEach(function(t){r(e,t,n[t])})}return e}n.d(t,"a",function(){return l})},function(e,t,n){"use strict";var r=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map(function(e){return t[e]}).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach(function(e){r[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(l){return!1}}()?Object.assign:function(e,t){for(var n,o,a=function(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),u=1;u<arguments.length;u++){for(var c in n=Object(arguments[u]))l.call(n,c)&&(a[c]=n[c]);if(r){o=r(n);for(var s=0;s<o.length;s++)i.call(n,o[s])&&(a[o[s]]=n[o[s]])}}return a}},function(e,t,n){"use strict";!function e(){if("undefined"!==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(12)},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}n.d(t,"a",function(){return r})},function(e,t,n){"use strict";function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function l(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),e}n.d(t,"a",function(){return l})},function(e,t,n){"use strict";function r(e){return(r=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}n.d(t,"a",function(){return r})},function(e,t,n){"use strict";function r(e,t){return(r=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function l(e,t){if("function"!==typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&r(e,t)}n.d(t,"a",function(){return l})},function(e,t,n){"use strict";function r(e){return(r="function"===typeof Symbol&&"symbol"===typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function l(e){return(l="function"===typeof Symbol&&"symbol"===r(Symbol.iterator)?function(e){return r(e)}:function(e){return e&&"function"===typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":r(e)})(e)}var i=n(1);function o(e,t){return!t||"object"!==l(t)&&"function"!==typeof t?Object(i.a)(e):t}n.d(t,"a",function(){return o})},,function(e,t,n){"use strict";var r=n(3),l="function"===typeof Symbol&&Symbol.for,i=l?Symbol.for("react.element"):60103,o=l?Symbol.for("react.portal"):60106,a=l?Symbol.for("react.fragment"):60107,u=l?Symbol.for("react.strict_mode"):60108,c=l?Symbol.for("react.profiler"):60114,s=l?Symbol.for("react.provider"):60109,f=l?Symbol.for("react.context"):60110,d=l?Symbol.for("react.concurrent_mode"):60111,p=l?Symbol.for("react.forward_ref"):60112,m=l?Symbol.for("react.suspense"):60113,h=l?Symbol.for("react.memo"):60115,y=l?Symbol.for("react.lazy"):60116,v="function"===typeof Symbol&&Symbol.iterator;function g(e){for(var t=arguments.length-1,n="https://reactjs.org/docs/error-decoder.html?invariant="+e,r=0;r<t;r++)n+="&args[]="+encodeURIComponent(arguments[r+1]);!function(e,t,n,r,l,i,o,a){if(!e){if(e=void 0,void 0===t)e=Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,l,i,o,a],c=0;(e=Error(t.replace(/%s/g,function(){return u[c++]}))).name="Invariant Violation"}throw e.framesToPop=1,e}}(!1,"Minified React error #"+e+"; visit %s for the full message or use the non-minified dev environment for full errors and additional helpful warnings. ",n)}var b={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},k={};function w(e,t,n){this.props=e,this.context=t,this.refs=k,this.updater=n||b}function x(){}function T(e,t,n){this.props=e,this.context=t,this.refs=k,this.updater=n||b}w.prototype.isReactComponent={},w.prototype.setState=function(e,t){"object"!==typeof e&&"function"!==typeof e&&null!=e&&g("85"),this.updater.enqueueSetState(this,e,t,"setState")},w.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},x.prototype=w.prototype;var S=T.prototype=new x;S.constructor=T,r(S,w.prototype),S.isPureReactComponent=!0;var _={current:null},E={current:null},C=Object.prototype.hasOwnProperty,P={key:!0,ref:!0,__self:!0,__source:!0};function N(e,t,n){var r=void 0,l={},o=null,a=null;if(null!=t)for(r in void 0!==t.ref&&(a=t.ref),void 0!==t.key&&(o=""+t.key),t)C.call(t,r)&&!P.hasOwnProperty(r)&&(l[r]=t[r]);var u=arguments.length-2;if(1===u)l.children=n;else if(1<u){for(var c=Array(u),s=0;s<u;s++)c[s]=arguments[s+2];l.children=c}if(e&&e.defaultProps)for(r in u=e.defaultProps)void 0===l[r]&&(l[r]=u[r]);return{$$typeof:i,type:e,key:o,ref:a,props:l,_owner:E.current}}function O(e){return"object"===typeof e&&null!==e&&e.$$typeof===i}var z=/\/+/g,R=[];function M(e,t,n,r){if(R.length){var l=R.pop();return l.result=e,l.keyPrefix=t,l.func=n,l.context=r,l.count=0,l}return{result:e,keyPrefix:t,func:n,context:r,count:0}}function I(e){e.result=null,e.keyPrefix=null,e.func=null,e.context=null,e.count=0,10>R.length&&R.push(e)}function U(e,t,n){return null==e?0:function e(t,n,r,l){var a=typeof t;"undefined"!==a&&"boolean"!==a||(t=null);var u=!1;if(null===t)u=!0;else switch(a){case"string":case"number":u=!0;break;case"object":switch(t.$$typeof){case i:case o:u=!0}}if(u)return r(l,t,""===n?"."+D(t,0):n),1;if(u=0,n=""===n?".":n+":",Array.isArray(t))for(var c=0;c<t.length;c++){var s=n+D(a=t[c],c);u+=e(a,s,r,l)}else if(s=null===t||"object"!==typeof t?null:"function"===typeof(s=v&&t[v]||t["@@iterator"])?s:null,"function"===typeof s)for(t=s.call(t),c=0;!(a=t.next()).done;)u+=e(a=a.value,s=n+D(a,c++),r,l);else"object"===a&&g("31","[object Object]"===(r=""+t)?"object with keys {"+Object.keys(t).join(", ")+"}":r,"");return u}(e,"",t,n)}function D(e,t){return"object"===typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+(""+e).replace(/[=:]/g,function(e){return t[e]})}(e.key):t.toString(36)}function F(e,t){e.func.call(e.context,t,e.count++)}function L(e,t,n){var r=e.result,l=e.keyPrefix;e=e.func.call(e.context,t,e.count++),Array.isArray(e)?A(e,r,n,function(e){return e}):null!=e&&(O(e)&&(e=function(e,t){return{$$typeof:i,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(e,l+(!e.key||t&&t.key===e.key?"":(""+e.key).replace(z,"$&/")+"/")+n)),r.push(e))}function A(e,t,n,r,l){var i="";null!=n&&(i=(""+n).replace(z,"$&/")+"/"),U(e,L,t=M(t,i,r,l)),I(t)}function j(){var e=_.current;return null===e&&g("307"),e}var W={Children:{map:function(e,t,n){if(null==e)return e;var r=[];return A(e,r,null,t,n),r},forEach:function(e,t,n){if(null==e)return e;U(e,F,t=M(null,null,t,n)),I(t)},count:function(e){return U(e,function(){return null},null)},toArray:function(e){var t=[];return A(e,t,null,function(e){return e}),t},only:function(e){return O(e)||g("143"),e}},createRef:function(){return{current:null}},Component:w,PureComponent:T,createContext:function(e,t){return void 0===t&&(t=null),(e={$$typeof:f,_calculateChangedBits:t,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:s,_context:e},e.Consumer=e},forwardRef:function(e){return{$$typeof:p,render:e}},lazy:function(e){return{$$typeof:y,_ctor:e,_status:-1,_result:null}},memo:function(e,t){return{$$typeof:h,type:e,compare:void 0===t?null:t}},useCallback:function(e,t){return j().useCallback(e,t)},useContext:function(e,t){return j().useContext(e,t)},useEffect:function(e,t){return j().useEffect(e,t)},useImperativeHandle:function(e,t,n){return j().useImperativeHandle(e,t,n)},useDebugValue:function(){},useLayoutEffect:function(e,t){return j().useLayoutEffect(e,t)},useMemo:function(e,t){return j().useMemo(e,t)},useReducer:function(e,t,n){return j().useReducer(e,t,n)},useRef:function(e){return j().useRef(e)},useState:function(e){return j().useState(e)},Fragment:a,StrictMode:u,Suspense:m,createElement:N,cloneElement:function(e,t,n){(null===e||void 0===e)&&g("267",e);var l=void 0,o=r({},e.props),a=e.key,u=e.ref,c=e._owner;if(null!=t){void 0!==t.ref&&(u=t.ref,c=E.current),void 0!==t.key&&(a=""+t.key);var s=void 0;for(l in e.type&&e.type.defaultProps&&(s=e.type.defaultProps),t)C.call(t,l)&&!P.hasOwnProperty(l)&&(o[l]=void 0===t[l]&&void 0!==s?s[l]:t[l])}if(1===(l=arguments.length-2))o.children=n;else if(1<l){s=Array(l);for(var f=0;f<l;f++)s[f]=arguments[f+2];o.children=s}return{$$typeof:i,type:e.type,key:a,ref:u,props:o,_owner:c}},createFactory:function(e){var t=N.bind(null,e);return t.type=e,t},isValidElement:O,version:"16.8.2",unstable_ConcurrentMode:d,unstable_Profiler:c,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{ReactCurrentDispatcher:_,ReactCurrentOwner:E,assign:r}},V={default:W},B=V&&W||V;e.exports=B.default||B},function(e,t,n){"use strict";var r=n(0),l=n(3),i=n(13);function o(e){for(var t=arguments.length-1,n="https://reactjs.org/docs/error-decoder.html?invariant="+e,r=0;r<t;r++)n+="&args[]="+encodeURIComponent(arguments[r+1]);!function(e,t,n,r,l,i,o,a){if(!e){if(e=void 0,void 0===t)e=Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,l,i,o,a],c=0;(e=Error(t.replace(/%s/g,function(){return u[c++]}))).name="Invariant Violation"}throw e.framesToPop=1,e}}(!1,"Minified React error #"+e+"; visit %s for the full message or use the non-minified dev environment for full errors and additional helpful warnings. ",n)}r||o("227");var a=!1,u=null,c=!1,s=null,f={onError:function(e){a=!0,u=e}};function d(e,t,n,r,l,i,o,c,s){a=!1,u=null,function(e,t,n,r,l,i,o,a,u){var c=Array.prototype.slice.call(arguments,3);try{t.apply(n,c)}catch(s){this.onError(s)}}.apply(f,arguments)}var p=null,m={};function h(){if(p)for(var e in m){var t=m[e],n=p.indexOf(e);if(-1<n||o("96",e),!v[n])for(var r in t.extractEvents||o("97",e),v[n]=t,n=t.eventTypes){var l=void 0,i=n[r],a=t,u=r;g.hasOwnProperty(u)&&o("99",u),g[u]=i;var c=i.phasedRegistrationNames;if(c){for(l in c)c.hasOwnProperty(l)&&y(c[l],a,u);l=!0}else i.registrationName?(y(i.registrationName,a,u),l=!0):l=!1;l||o("98",r,e)}}}function y(e,t,n){b[e]&&o("100",e),b[e]=t,k[e]=t.eventTypes[n].dependencies}var v=[],g={},b={},k={},w=null,x=null,T=null;function S(e,t,n){var r=e.type||"unknown-event";e.currentTarget=T(n),function(e,t,n,r,l,i,f,p,m){if(d.apply(this,arguments),a){if(a){var h=u;a=!1,u=null}else o("198"),h=void 0;c||(c=!0,s=h)}}(r,t,void 0,e),e.currentTarget=null}function _(e,t){return null==t&&o("30"),null==e?t:Array.isArray(e)?Array.isArray(t)?(e.push.apply(e,t),e):(e.push(t),e):Array.isArray(t)?[e].concat(t):[e,t]}function E(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)}var C=null;function P(e){if(e){var t=e._dispatchListeners,n=e._dispatchInstances;if(Array.isArray(t))for(var r=0;r<t.length&&!e.isPropagationStopped();r++)S(e,t[r],n[r]);else t&&S(e,t,n);e._dispatchListeners=null,e._dispatchInstances=null,e.isPersistent()||e.constructor.release(e)}}var N={injectEventPluginOrder:function(e){p&&o("101"),p=Array.prototype.slice.call(e),h()},injectEventPluginsByName:function(e){var t,n=!1;for(t in e)if(e.hasOwnProperty(t)){var r=e[t];m.hasOwnProperty(t)&&m[t]===r||(m[t]&&o("102",t),m[t]=r,n=!0)}n&&h()}};function O(e,t){var n=e.stateNode;if(!n)return null;var r=w(n);if(!r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}return e?null:(n&&"function"!==typeof n&&o("231",t,typeof n),n)}function z(e){if(null!==e&&(C=_(C,e)),e=C,C=null,e&&(E(e,P),C&&o("95"),c))throw e=s,c=!1,s=null,e}var R=Math.random().toString(36).slice(2),M="__reactInternalInstance$"+R,I="__reactEventHandlers$"+R;function U(e){if(e[M])return e[M];for(;!e[M];){if(!e.parentNode)return null;e=e.parentNode}return 5===(e=e[M]).tag||6===e.tag?e:null}function D(e){return!(e=e[M])||5!==e.tag&&6!==e.tag?null:e}function F(e){if(5===e.tag||6===e.tag)return e.stateNode;o("33")}function L(e){return e[I]||null}function A(e){do{e=e.return}while(e&&5!==e.tag);return e||null}function j(e,t,n){(t=O(e,n.dispatchConfig.phasedRegistrationNames[t]))&&(n._dispatchListeners=_(n._dispatchListeners,t),n._dispatchInstances=_(n._dispatchInstances,e))}function W(e){if(e&&e.dispatchConfig.phasedRegistrationNames){for(var t=e._targetInst,n=[];t;)n.push(t),t=A(t);for(t=n.length;0<t--;)j(n[t],"captured",e);for(t=0;t<n.length;t++)j(n[t],"bubbled",e)}}function V(e,t,n){e&&n&&n.dispatchConfig.registrationName&&(t=O(e,n.dispatchConfig.registrationName))&&(n._dispatchListeners=_(n._dispatchListeners,t),n._dispatchInstances=_(n._dispatchInstances,e))}function B(e){e&&e.dispatchConfig.registrationName&&V(e._targetInst,null,e)}function H(e){E(e,W)}var $=!("undefined"===typeof window||!window.document||!window.document.createElement);function Q(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var K={animationend:Q("Animation","AnimationEnd"),animationiteration:Q("Animation","AnimationIteration"),animationstart:Q("Animation","AnimationStart"),transitionend:Q("Transition","TransitionEnd")},q={},Y={};function X(e){if(q[e])return q[e];if(!K[e])return e;var t,n=K[e];for(t in n)if(n.hasOwnProperty(t)&&t in Y)return q[e]=n[t];return e}$&&(Y=document.createElement("div").style,"AnimationEvent"in window||(delete K.animationend.animation,delete K.animationiteration.animation,delete K.animationstart.animation),"TransitionEvent"in window||delete K.transitionend.transition);var G=X("animationend"),J=X("animationiteration"),Z=X("animationstart"),ee=X("transitionend"),te="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),ne=null,re=null,le=null;function ie(){if(le)return le;var e,t,n=re,r=n.length,l="value"in ne?ne.value:ne.textContent,i=l.length;for(e=0;e<r&&n[e]===l[e];e++);var o=r-e;for(t=1;t<=o&&n[r-t]===l[i-t];t++);return le=l.slice(e,1<t?1-t:void 0)}function oe(){return!0}function ae(){return!1}function ue(e,t,n,r){for(var l in this.dispatchConfig=e,this._targetInst=t,this.nativeEvent=n,e=this.constructor.Interface)e.hasOwnProperty(l)&&((t=e[l])?this[l]=t(n):"target"===l?this.target=r:this[l]=n[l]);return this.isDefaultPrevented=(null!=n.defaultPrevented?n.defaultPrevented:!1===n.returnValue)?oe:ae,this.isPropagationStopped=ae,this}function ce(e,t,n,r){if(this.eventPool.length){var l=this.eventPool.pop();return this.call(l,e,t,n,r),l}return new this(e,t,n,r)}function se(e){e instanceof this||o("279"),e.destructor(),10>this.eventPool.length&&this.eventPool.push(e)}function fe(e){e.eventPool=[],e.getPooled=ce,e.release=se}l(ue.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!==typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=oe)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!==typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=oe)},persist:function(){this.isPersistent=oe},isPersistent:ae,destructor:function(){var e,t=this.constructor.Interface;for(e in t)this[e]=null;this.nativeEvent=this._targetInst=this.dispatchConfig=null,this.isPropagationStopped=this.isDefaultPrevented=ae,this._dispatchInstances=this._dispatchListeners=null}}),ue.Interface={type:null,target:null,currentTarget:function(){return null},eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null},ue.extend=function(e){function t(){}function n(){return r.apply(this,arguments)}var r=this;t.prototype=r.prototype;var i=new t;return l(i,n.prototype),n.prototype=i,n.prototype.constructor=n,n.Interface=l({},r.Interface,e),n.extend=r.extend,fe(n),n},fe(ue);var de=ue.extend({data:null}),pe=ue.extend({data:null}),me=[9,13,27,32],he=$&&"CompositionEvent"in window,ye=null;$&&"documentMode"in document&&(ye=document.documentMode);var ve=$&&"TextEvent"in window&&!ye,ge=$&&(!he||ye&&8<ye&&11>=ye),be=String.fromCharCode(32),ke={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["compositionend","keypress","textInput","paste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"blur compositionend keydown keypress keyup mousedown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:"blur compositionstart keydown keypress keyup mousedown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"blur compositionupdate keydown keypress keyup mousedown".split(" ")}},we=!1;function xe(e,t){switch(e){case"keyup":return-1!==me.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"blur":return!0;default:return!1}}function Te(e){return"object"===typeof(e=e.detail)&&"data"in e?e.data:null}var Se=!1;var _e={eventTypes:ke,extractEvents:function(e,t,n,r){var l=void 0,i=void 0;if(he)e:{switch(e){case"compositionstart":l=ke.compositionStart;break e;case"compositionend":l=ke.compositionEnd;break e;case"compositionupdate":l=ke.compositionUpdate;break e}l=void 0}else Se?xe(e,n)&&(l=ke.compositionEnd):"keydown"===e&&229===n.keyCode&&(l=ke.compositionStart);return l?(ge&&"ko"!==n.locale&&(Se||l!==ke.compositionStart?l===ke.compositionEnd&&Se&&(i=ie()):(re="value"in(ne=r)?ne.value:ne.textContent,Se=!0)),l=de.getPooled(l,t,n,r),i?l.data=i:null!==(i=Te(n))&&(l.data=i),H(l),i=l):i=null,(e=ve?function(e,t){switch(e){case"compositionend":return Te(t);case"keypress":return 32!==t.which?null:(we=!0,be);case"textInput":return(e=t.data)===be&&we?null:e;default:return null}}(e,n):function(e,t){if(Se)return"compositionend"===e||!he&&xe(e,t)?(e=ie(),le=re=ne=null,Se=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return ge&&"ko"!==t.locale?null:t.data;default:return null}}(e,n))?((t=pe.getPooled(ke.beforeInput,t,n,r)).data=e,H(t)):t=null,null===i?t:null===t?i:[i,t]}},Ee=null,Ce=null,Pe=null;function Ne(e){if(e=x(e)){"function"!==typeof Ee&&o("280");var t=w(e.stateNode);Ee(e.stateNode,e.type,t)}}function Oe(e){Ce?Pe?Pe.push(e):Pe=[e]:Ce=e}function ze(){if(Ce){var e=Ce,t=Pe;if(Pe=Ce=null,Ne(e),t)for(e=0;e<t.length;e++)Ne(t[e])}}function Re(e,t){return e(t)}function Me(e,t,n){return e(t,n)}function Ie(){}var Ue=!1;function De(e,t){if(Ue)return e(t);Ue=!0;try{return Re(e,t)}finally{Ue=!1,(null!==Ce||null!==Pe)&&(Ie(),ze())}}var Fe={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Le(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Fe[e.type]:"textarea"===t}function Ae(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}function je(e){if(!$)return!1;var t=(e="on"+e)in document;return t||((t=document.createElement("div")).setAttribute(e,"return;"),t="function"===typeof t[e]),t}function We(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function Ve(e){e._valueTracker||(e._valueTracker=function(e){var t=We(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&"undefined"!==typeof n&&"function"===typeof n.get&&"function"===typeof n.set){var l=n.get,i=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return l.call(this)},set:function(e){r=""+e,i.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function Be(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=We(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}var He=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;He.hasOwnProperty("ReactCurrentDispatcher")||(He.ReactCurrentDispatcher={current:null});var $e=/^(.*)[\\\/]/,Qe="function"===typeof Symbol&&Symbol.for,Ke=Qe?Symbol.for("react.element"):60103,qe=Qe?Symbol.for("react.portal"):60106,Ye=Qe?Symbol.for("react.fragment"):60107,Xe=Qe?Symbol.for("react.strict_mode"):60108,Ge=Qe?Symbol.for("react.profiler"):60114,Je=Qe?Symbol.for("react.provider"):60109,Ze=Qe?Symbol.for("react.context"):60110,et=Qe?Symbol.for("react.concurrent_mode"):60111,tt=Qe?Symbol.for("react.forward_ref"):60112,nt=Qe?Symbol.for("react.suspense"):60113,rt=Qe?Symbol.for("react.memo"):60115,lt=Qe?Symbol.for("react.lazy"):60116,it="function"===typeof Symbol&&Symbol.iterator;function ot(e){return null===e||"object"!==typeof e?null:"function"===typeof(e=it&&e[it]||e["@@iterator"])?e:null}function at(e){if(null==e)return null;if("function"===typeof e)return e.displayName||e.name||null;if("string"===typeof e)return e;switch(e){case et:return"ConcurrentMode";case Ye:return"Fragment";case qe:return"Portal";case Ge:return"Profiler";case Xe:return"StrictMode";case nt:return"Suspense"}if("object"===typeof e)switch(e.$$typeof){case Ze:return"Context.Consumer";case Je:return"Context.Provider";case tt:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case rt:return at(e.type);case lt:if(e=1===e._status?e._result:null)return at(e)}return null}function ut(e){var t="";do{e:switch(e.tag){case 3:case 4:case 6:case 7:case 10:case 9:var n="";break e;default:var r=e._debugOwner,l=e._debugSource,i=at(e.type);n=null,r&&(n=at(r.type)),r=i,i="",l?i=" (at "+l.fileName.replace($e,"")+":"+l.lineNumber+")":n&&(i=" (created by "+n+")"),n="\n    in "+(r||"Unknown")+i}t+=n,e=e.return}while(e);return t}var ct=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,st=Object.prototype.hasOwnProperty,ft={},dt={};function pt(e,t,n,r,l){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=l,this.mustUseProperty=n,this.propertyName=e,this.type=t}var mt={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){mt[e]=new pt(e,0,!1,e,null)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];mt[t]=new pt(t,1,!1,e[1],null)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){mt[e]=new pt(e,2,!1,e.toLowerCase(),null)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){mt[e]=new pt(e,2,!1,e,null)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){mt[e]=new pt(e,3,!1,e.toLowerCase(),null)}),["checked","multiple","muted","selected"].forEach(function(e){mt[e]=new pt(e,3,!0,e,null)}),["capture","download"].forEach(function(e){mt[e]=new pt(e,4,!1,e,null)}),["cols","rows","size","span"].forEach(function(e){mt[e]=new pt(e,6,!1,e,null)}),["rowSpan","start"].forEach(function(e){mt[e]=new pt(e,5,!1,e.toLowerCase(),null)});var ht=/[\-:]([a-z])/g;function yt(e){return e[1].toUpperCase()}function vt(e,t,n,r){var l=mt.hasOwnProperty(t)?mt[t]:null;(null!==l?0===l.type:!r&&(2<t.length&&("o"===t[0]||"O"===t[0])&&("n"===t[1]||"N"===t[1])))||(function(e,t,n,r){if(null===t||"undefined"===typeof t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,l,r)&&(n=null),r||null===l?function(e){return!!st.call(dt,e)||!st.call(ft,e)&&(ct.test(e)?dt[e]=!0:(ft[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):l.mustUseProperty?e[l.propertyName]=null===n?3!==l.type&&"":n:(t=l.attributeName,r=l.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(l=l.type)||4===l&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}function gt(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function bt(e,t){var n=t.checked;return l({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function kt(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=gt(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function wt(e,t){null!=(t=t.checked)&&vt(e,"checked",t,!1)}function xt(e,t){wt(e,t);var n=gt(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?St(e,t.type,n):t.hasOwnProperty("defaultValue")&&St(e,t.type,gt(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function Tt(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!e.defaultChecked,e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function St(e,t,n){"number"===t&&e.ownerDocument.activeElement===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(ht,yt);mt[t]=new pt(t,1,!1,e,null)}),"xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(ht,yt);mt[t]=new pt(t,1,!1,e,"http://www.w3.org/1999/xlink")}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(ht,yt);mt[t]=new pt(t,1,!1,e,"http://www.w3.org/XML/1998/namespace")}),["tabIndex","crossOrigin"].forEach(function(e){mt[e]=new pt(e,1,!1,e.toLowerCase(),null)});var _t={change:{phasedRegistrationNames:{bubbled:"onChange",captured:"onChangeCapture"},dependencies:"blur change click focus input keydown keyup selectionchange".split(" ")}};function Et(e,t,n){return(e=ue.getPooled(_t.change,e,t,n)).type="change",Oe(n),H(e),e}var Ct=null,Pt=null;function Nt(e){z(e)}function Ot(e){if(Be(F(e)))return e}function zt(e,t){if("change"===e)return t}var Rt=!1;function Mt(){Ct&&(Ct.detachEvent("onpropertychange",It),Pt=Ct=null)}function It(e){"value"===e.propertyName&&Ot(Pt)&&De(Nt,e=Et(Pt,e,Ae(e)))}function Ut(e,t,n){"focus"===e?(Mt(),Pt=n,(Ct=t).attachEvent("onpropertychange",It)):"blur"===e&&Mt()}function Dt(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Ot(Pt)}function Ft(e,t){if("click"===e)return Ot(t)}function Lt(e,t){if("input"===e||"change"===e)return Ot(t)}$&&(Rt=je("input")&&(!document.documentMode||9<document.documentMode));var At={eventTypes:_t,_isInputEventSupported:Rt,extractEvents:function(e,t,n,r){var l=t?F(t):window,i=void 0,o=void 0,a=l.nodeName&&l.nodeName.toLowerCase();if("select"===a||"input"===a&&"file"===l.type?i=zt:Le(l)?Rt?i=Lt:(i=Dt,o=Ut):(a=l.nodeName)&&"input"===a.toLowerCase()&&("checkbox"===l.type||"radio"===l.type)&&(i=Ft),i&&(i=i(e,t)))return Et(i,n,r);o&&o(e,l,t),"blur"===e&&(e=l._wrapperState)&&e.controlled&&"number"===l.type&&St(l,"number",l.value)}},jt=ue.extend({view:null,detail:null}),Wt={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Vt(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=Wt[e])&&!!t[e]}function Bt(){return Vt}var Ht=0,$t=0,Qt=!1,Kt=!1,qt=jt.extend({screenX:null,screenY:null,clientX:null,clientY:null,pageX:null,pageY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:Bt,button:null,buttons:null,relatedTarget:function(e){return e.relatedTarget||(e.fromElement===e.srcElement?e.toElement:e.fromElement)},movementX:function(e){if("movementX"in e)return e.movementX;var t=Ht;return Ht=e.screenX,Qt?"mousemove"===e.type?e.screenX-t:0:(Qt=!0,0)},movementY:function(e){if("movementY"in e)return e.movementY;var t=$t;return $t=e.screenY,Kt?"mousemove"===e.type?e.screenY-t:0:(Kt=!0,0)}}),Yt=qt.extend({pointerId:null,width:null,height:null,pressure:null,tangentialPressure:null,tiltX:null,tiltY:null,twist:null,pointerType:null,isPrimary:null}),Xt={mouseEnter:{registrationName:"onMouseEnter",dependencies:["mouseout","mouseover"]},mouseLeave:{registrationName:"onMouseLeave",dependencies:["mouseout","mouseover"]},pointerEnter:{registrationName:"onPointerEnter",dependencies:["pointerout","pointerover"]},pointerLeave:{registrationName:"onPointerLeave",dependencies:["pointerout","pointerover"]}},Gt={eventTypes:Xt,extractEvents:function(e,t,n,r){var l="mouseover"===e||"pointerover"===e,i="mouseout"===e||"pointerout"===e;if(l&&(n.relatedTarget||n.fromElement)||!i&&!l)return null;if(l=r.window===r?r:(l=r.ownerDocument)?l.defaultView||l.parentWindow:window,i?(i=t,t=(t=n.relatedTarget||n.toElement)?U(t):null):i=null,i===t)return null;var o=void 0,a=void 0,u=void 0,c=void 0;"mouseout"===e||"mouseover"===e?(o=qt,a=Xt.mouseLeave,u=Xt.mouseEnter,c="mouse"):"pointerout"!==e&&"pointerover"!==e||(o=Yt,a=Xt.pointerLeave,u=Xt.pointerEnter,c="pointer");var s=null==i?l:F(i);if(l=null==t?l:F(t),(e=o.getPooled(a,i,n,r)).type=c+"leave",e.target=s,e.relatedTarget=l,(n=o.getPooled(u,t,n,r)).type=c+"enter",n.target=l,n.relatedTarget=s,r=t,i&&r)e:{for(l=r,c=0,o=t=i;o;o=A(o))c++;for(o=0,u=l;u;u=A(u))o++;for(;0<c-o;)t=A(t),c--;for(;0<o-c;)l=A(l),o--;for(;c--;){if(t===l||t===l.alternate)break e;t=A(t),l=A(l)}t=null}else t=null;for(l=t,t=[];i&&i!==l&&(null===(c=i.alternate)||c!==l);)t.push(i),i=A(i);for(i=[];r&&r!==l&&(null===(c=r.alternate)||c!==l);)i.push(r),r=A(r);for(r=0;r<t.length;r++)V(t[r],"bubbled",e);for(r=i.length;0<r--;)V(i[r],"captured",n);return[e,n]}};function Jt(e,t){return e===t&&(0!==e||1/e===1/t)||e!==e&&t!==t}var Zt=Object.prototype.hasOwnProperty;function en(e,t){if(Jt(e,t))return!0;if("object"!==typeof e||null===e||"object"!==typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++)if(!Zt.call(t,n[r])||!Jt(e[n[r]],t[n[r]]))return!1;return!0}function tn(e){var t=e;if(e.alternate)for(;t.return;)t=t.return;else{if(0!==(2&t.effectTag))return 1;for(;t.return;)if(0!==(2&(t=t.return).effectTag))return 1}return 3===t.tag?2:3}function nn(e){2!==tn(e)&&o("188")}function rn(e){if(!(e=function(e){var t=e.alternate;if(!t)return 3===(t=tn(e))&&o("188"),1===t?null:e;for(var n=e,r=t;;){var l=n.return,i=l?l.alternate:null;if(!l||!i)break;if(l.child===i.child){for(var a=l.child;a;){if(a===n)return nn(l),e;if(a===r)return nn(l),t;a=a.sibling}o("188")}if(n.return!==r.return)n=l,r=i;else{a=!1;for(var u=l.child;u;){if(u===n){a=!0,n=l,r=i;break}if(u===r){a=!0,r=l,n=i;break}u=u.sibling}if(!a){for(u=i.child;u;){if(u===n){a=!0,n=i,r=l;break}if(u===r){a=!0,r=i,n=l;break}u=u.sibling}a||o("189")}}n.alternate!==r&&o("190")}return 3!==n.tag&&o("188"),n.stateNode.current===n?e:t}(e)))return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}var ln=ue.extend({animationName:null,elapsedTime:null,pseudoElement:null}),on=ue.extend({clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),an=jt.extend({relatedTarget:null});function un(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}var cn={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},sn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},fn=jt.extend({key:function(e){if(e.key){var t=cn[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=un(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?sn[e.keyCode]||"Unidentified":""},location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:Bt,charCode:function(e){return"keypress"===e.type?un(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?un(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),dn=qt.extend({dataTransfer:null}),pn=jt.extend({touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:Bt}),mn=ue.extend({propertyName:null,elapsedTime:null,pseudoElement:null}),hn=qt.extend({deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:null,deltaMode:null}),yn=[["abort","abort"],[G,"animationEnd"],[J,"animationIteration"],[Z,"animationStart"],["canplay","canPlay"],["canplaythrough","canPlayThrough"],["drag","drag"],["dragenter","dragEnter"],["dragexit","dragExit"],["dragleave","dragLeave"],["dragover","dragOver"],["durationchange","durationChange"],["emptied","emptied"],["encrypted","encrypted"],["ended","ended"],["error","error"],["gotpointercapture","gotPointerCapture"],["load","load"],["loadeddata","loadedData"],["loadedmetadata","loadedMetadata"],["loadstart","loadStart"],["lostpointercapture","lostPointerCapture"],["mousemove","mouseMove"],["mouseout","mouseOut"],["mouseover","mouseOver"],["playing","playing"],["pointermove","pointerMove"],["pointerout","pointerOut"],["pointerover","pointerOver"],["progress","progress"],["scroll","scroll"],["seeking","seeking"],["stalled","stalled"],["suspend","suspend"],["timeupdate","timeUpdate"],["toggle","toggle"],["touchmove","touchMove"],[ee,"transitionEnd"],["waiting","waiting"],["wheel","wheel"]],vn={},gn={};function bn(e,t){var n=e[0],r="on"+((e=e[1])[0].toUpperCase()+e.slice(1));t={phasedRegistrationNames:{bubbled:r,captured:r+"Capture"},dependencies:[n],isInteractive:t},vn[e]=t,gn[n]=t}[["blur","blur"],["cancel","cancel"],["click","click"],["close","close"],["contextmenu","contextMenu"],["copy","copy"],["cut","cut"],["auxclick","auxClick"],["dblclick","doubleClick"],["dragend","dragEnd"],["dragstart","dragStart"],["drop","drop"],["focus","focus"],["input","input"],["invalid","invalid"],["keydown","keyDown"],["keypress","keyPress"],["keyup","keyUp"],["mousedown","mouseDown"],["mouseup","mouseUp"],["paste","paste"],["pause","pause"],["play","play"],["pointercancel","pointerCancel"],["pointerdown","pointerDown"],["pointerup","pointerUp"],["ratechange","rateChange"],["reset","reset"],["seeked","seeked"],["submit","submit"],["touchcancel","touchCancel"],["touchend","touchEnd"],["touchstart","touchStart"],["volumechange","volumeChange"]].forEach(function(e){bn(e,!0)}),yn.forEach(function(e){bn(e,!1)});var kn={eventTypes:vn,isInteractiveTopLevelEventType:function(e){return void 0!==(e=gn[e])&&!0===e.isInteractive},extractEvents:function(e,t,n,r){var l=gn[e];if(!l)return null;switch(e){case"keypress":if(0===un(n))return null;case"keydown":case"keyup":e=fn;break;case"blur":case"focus":e=an;break;case"click":if(2===n.button)return null;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":e=qt;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":e=dn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":e=pn;break;case G:case J:case Z:e=ln;break;case ee:e=mn;break;case"scroll":e=jt;break;case"wheel":e=hn;break;case"copy":case"cut":case"paste":e=on;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":e=Yt;break;default:e=ue}return H(t=e.getPooled(l,t,n,r)),t}},wn=kn.isInteractiveTopLevelEventType,xn=[];function Tn(e){var t=e.targetInst,n=t;do{if(!n){e.ancestors.push(n);break}var r;for(r=n;r.return;)r=r.return;if(!(r=3!==r.tag?null:r.stateNode.containerInfo))break;e.ancestors.push(n),n=U(r)}while(n);for(n=0;n<e.ancestors.length;n++){t=e.ancestors[n];var l=Ae(e.nativeEvent);r=e.topLevelType;for(var i=e.nativeEvent,o=null,a=0;a<v.length;a++){var u=v[a];u&&(u=u.extractEvents(r,t,i,l))&&(o=_(o,u))}z(o)}}var Sn=!0;function _n(e,t){if(!t)return null;var n=(wn(e)?Cn:Pn).bind(null,e);t.addEventListener(e,n,!1)}function En(e,t){if(!t)return null;var n=(wn(e)?Cn:Pn).bind(null,e);t.addEventListener(e,n,!0)}function Cn(e,t){Me(Pn,e,t)}function Pn(e,t){if(Sn){var n=Ae(t);if(null===(n=U(n))||"number"!==typeof n.tag||2===tn(n)||(n=null),xn.length){var r=xn.pop();r.topLevelType=e,r.nativeEvent=t,r.targetInst=n,e=r}else e={topLevelType:e,nativeEvent:t,targetInst:n,ancestors:[]};try{De(Tn,e)}finally{e.topLevelType=null,e.nativeEvent=null,e.targetInst=null,e.ancestors.length=0,10>xn.length&&xn.push(e)}}}var Nn={},On=0,zn="_reactListenersID"+(""+Math.random()).slice(2);function Rn(e){return Object.prototype.hasOwnProperty.call(e,zn)||(e[zn]=On++,Nn[e[zn]]={}),Nn[e[zn]]}function Mn(e){if("undefined"===typeof(e=e||("undefined"!==typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function In(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function Un(e,t){var n,r=In(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=In(r)}}function Dn(){for(var e=window,t=Mn();t instanceof e.HTMLIFrameElement;){try{e=t.contentDocument.defaultView}catch(n){break}t=Mn(e.document)}return t}function Fn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function Ln(e){var t=Dn(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&function e(t,n){return!(!t||!n)&&(t===n||(!t||3!==t.nodeType)&&(n&&3===n.nodeType?e(t,n.parentNode):"contains"in t?t.contains(n):!!t.compareDocumentPosition&&!!(16&t.compareDocumentPosition(n))))}(n.ownerDocument.documentElement,n)){if(null!==r&&Fn(n))if(t=r.start,void 0===(e=r.end)&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if((e=(t=n.ownerDocument||document)&&t.defaultView||window).getSelection){e=e.getSelection();var l=n.textContent.length,i=Math.min(r.start,l);r=void 0===r.end?i:Math.min(r.end,l),!e.extend&&i>r&&(l=r,r=i,i=l),l=Un(n,i);var o=Un(n,r);l&&o&&(1!==e.rangeCount||e.anchorNode!==l.node||e.anchorOffset!==l.offset||e.focusNode!==o.node||e.focusOffset!==o.offset)&&((t=t.createRange()).setStart(l.node,l.offset),e.removeAllRanges(),i>r?(e.addRange(t),e.extend(o.node,o.offset)):(t.setEnd(o.node,o.offset),e.addRange(t)))}for(t=[],e=n;e=e.parentNode;)1===e.nodeType&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for("function"===typeof n.focus&&n.focus(),n=0;n<t.length;n++)(e=t[n]).element.scrollLeft=e.left,e.element.scrollTop=e.top}}var An=$&&"documentMode"in document&&11>=document.documentMode,jn={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},dependencies:"blur contextmenu dragend focus keydown keyup mousedown mouseup selectionchange".split(" ")}},Wn=null,Vn=null,Bn=null,Hn=!1;function $n(e,t){var n=t.window===t?t.document:9===t.nodeType?t:t.ownerDocument;return Hn||null==Wn||Wn!==Mn(n)?null:("selectionStart"in(n=Wn)&&Fn(n)?n={start:n.selectionStart,end:n.selectionEnd}:n={anchorNode:(n=(n.ownerDocument&&n.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:n.anchorOffset,focusNode:n.focusNode,focusOffset:n.focusOffset},Bn&&en(Bn,n)?null:(Bn=n,(e=ue.getPooled(jn.select,Vn,e,t)).type="select",e.target=Wn,H(e),e))}var Qn={eventTypes:jn,extractEvents:function(e,t,n,r){var l,i=r.window===r?r.document:9===r.nodeType?r:r.ownerDocument;if(!(l=!i)){e:{i=Rn(i),l=k.onSelect;for(var o=0;o<l.length;o++){var a=l[o];if(!i.hasOwnProperty(a)||!i[a]){i=!1;break e}}i=!0}l=!i}if(l)return null;switch(i=t?F(t):window,e){case"focus":(Le(i)||"true"===i.contentEditable)&&(Wn=i,Vn=t,Bn=null);break;case"blur":Bn=Vn=Wn=null;break;case"mousedown":Hn=!0;break;case"contextmenu":case"mouseup":case"dragend":return Hn=!1,$n(n,r);case"selectionchange":if(An)break;case"keydown":case"keyup":return $n(n,r)}return null}};function Kn(e,t){return e=l({children:void 0},t),(t=function(e){var t="";return r.Children.forEach(e,function(e){null!=e&&(t+=e)}),t}(t.children))&&(e.children=t),e}function qn(e,t,n,r){if(e=e.options,t){t={};for(var l=0;l<n.length;l++)t["$"+n[l]]=!0;for(n=0;n<e.length;n++)l=t.hasOwnProperty("$"+e[n].value),e[n].selected!==l&&(e[n].selected=l),l&&r&&(e[n].defaultSelected=!0)}else{for(n=""+gt(n),t=null,l=0;l<e.length;l++){if(e[l].value===n)return e[l].selected=!0,void(r&&(e[l].defaultSelected=!0));null!==t||e[l].disabled||(t=e[l])}null!==t&&(t.selected=!0)}}function Yn(e,t){return null!=t.dangerouslySetInnerHTML&&o("91"),l({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function Xn(e,t){var n=t.value;null==n&&(n=t.defaultValue,null!=(t=t.children)&&(null!=n&&o("92"),Array.isArray(t)&&(1>=t.length||o("93"),t=t[0]),n=t),null==n&&(n="")),e._wrapperState={initialValue:gt(n)}}function Gn(e,t){var n=gt(t.value),r=gt(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function Jn(e){var t=e.textContent;t===e._wrapperState.initialValue&&(e.value=t)}N.injectEventPluginOrder("ResponderEventPlugin SimpleEventPlugin EnterLeaveEventPlugin ChangeEventPlugin SelectEventPlugin BeforeInputEventPlugin".split(" ")),w=L,x=D,T=F,N.injectEventPluginsByName({SimpleEventPlugin:kn,EnterLeaveEventPlugin:Gt,ChangeEventPlugin:At,SelectEventPlugin:Qn,BeforeInputEventPlugin:_e});var Zn={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"};function er(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function tr(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?er(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var nr,rr=void 0,lr=(nr=function(e,t){if(e.namespaceURI!==Zn.svg||"innerHTML"in e)e.innerHTML=t;else{for((rr=rr||document.createElement("div")).innerHTML="<svg>"+t+"</svg>",t=rr.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!==typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction(function(){return nr(e,t)})}:nr);function ir(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var or={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ar=["Webkit","ms","Moz","O"];function ur(e,t,n){return null==t||"boolean"===typeof t||""===t?"":n||"number"!==typeof t||0===t||or.hasOwnProperty(e)&&or[e]?(""+t).trim():t+"px"}function cr(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),l=ur(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,l):e[n]=l}}Object.keys(or).forEach(function(e){ar.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),or[t]=or[e]})});var sr=l({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function fr(e,t){t&&(sr[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML)&&o("137",e,""),null!=t.dangerouslySetInnerHTML&&(null!=t.children&&o("60"),"object"===typeof t.dangerouslySetInnerHTML&&"__html"in t.dangerouslySetInnerHTML||o("61")),null!=t.style&&"object"!==typeof t.style&&o("62",""))}function dr(e,t){if(-1===e.indexOf("-"))return"string"===typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function pr(e,t){var n=Rn(e=9===e.nodeType||11===e.nodeType?e:e.ownerDocument);t=k[t];for(var r=0;r<t.length;r++){var l=t[r];if(!n.hasOwnProperty(l)||!n[l]){switch(l){case"scroll":En("scroll",e);break;case"focus":case"blur":En("focus",e),En("blur",e),n.blur=!0,n.focus=!0;break;case"cancel":case"close":je(l)&&En(l,e);break;case"invalid":case"submit":case"reset":break;default:-1===te.indexOf(l)&&_n(l,e)}n[l]=!0}}}function mr(){}var hr=null,yr=null;function vr(e,t){switch(e){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function gr(e,t){return"textarea"===e||"option"===e||"noscript"===e||"string"===typeof t.children||"number"===typeof t.children||"object"===typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var br="function"===typeof setTimeout?setTimeout:void 0,kr="function"===typeof clearTimeout?clearTimeout:void 0,wr=i.unstable_scheduleCallback,xr=i.unstable_cancelCallback;function Tr(e){for(e=e.nextSibling;e&&1!==e.nodeType&&3!==e.nodeType;)e=e.nextSibling;return e}function Sr(e){for(e=e.firstChild;e&&1!==e.nodeType&&3!==e.nodeType;)e=e.nextSibling;return e}new Set;var _r=[],Er=-1;function Cr(e){0>Er||(e.current=_r[Er],_r[Er]=null,Er--)}function Pr(e,t){_r[++Er]=e.current,e.current=t}var Nr={},Or={current:Nr},zr={current:!1},Rr=Nr;function Mr(e,t){var n=e.type.contextTypes;if(!n)return Nr;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var l,i={};for(l in n)i[l]=t[l];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=i),i}function Ir(e){return null!==(e=e.childContextTypes)&&void 0!==e}function Ur(e){Cr(zr),Cr(Or)}function Dr(e){Cr(zr),Cr(Or)}function Fr(e,t,n){Or.current!==Nr&&o("168"),Pr(Or,t),Pr(zr,n)}function Lr(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!==typeof r.getChildContext)return n;for(var i in r=r.getChildContext())i in e||o("108",at(t)||"Unknown",i);return l({},n,r)}function Ar(e){var t=e.stateNode;return t=t&&t.__reactInternalMemoizedMergedChildContext||Nr,Rr=Or.current,Pr(Or,t),Pr(zr,zr.current),!0}function jr(e,t,n){var r=e.stateNode;r||o("169"),n?(t=Lr(e,t,Rr),r.__reactInternalMemoizedMergedChildContext=t,Cr(zr),Cr(Or),Pr(Or,t)):Cr(zr),Pr(zr,n)}var Wr=null,Vr=null;function Br(e){return function(t){try{return e(t)}catch(n){}}}function Hr(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.contextDependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.effectTag=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childExpirationTime=this.expirationTime=0,this.alternate=null}function $r(e,t,n,r){return new Hr(e,t,n,r)}function Qr(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Kr(e,t){var n=e.alternate;return null===n?((n=$r(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.effectTag=0,n.nextEffect=null,n.firstEffect=null,n.lastEffect=null),n.childExpirationTime=e.childExpirationTime,n.expirationTime=e.expirationTime,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,n.contextDependencies=e.contextDependencies,n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function qr(e,t,n,r,l,i){var a=2;if(r=e,"function"===typeof e)Qr(e)&&(a=1);else if("string"===typeof e)a=5;else e:switch(e){case Ye:return Yr(n.children,l,i,t);case et:return Xr(n,3|l,i,t);case Xe:return Xr(n,2|l,i,t);case Ge:return(e=$r(12,n,t,4|l)).elementType=Ge,e.type=Ge,e.expirationTime=i,e;case nt:return(e=$r(13,n,t,l)).elementType=nt,e.type=nt,e.expirationTime=i,e;default:if("object"===typeof e&&null!==e)switch(e.$$typeof){case Je:a=10;break e;case Ze:a=9;break e;case tt:a=11;break e;case rt:a=14;break e;case lt:a=16,r=null;break e}o("130",null==e?e:typeof e,"")}return(t=$r(a,n,t,l)).elementType=e,t.type=r,t.expirationTime=i,t}function Yr(e,t,n,r){return(e=$r(7,e,r,t)).expirationTime=n,e}function Xr(e,t,n,r){return e=$r(8,e,r,t),t=0===(1&t)?Xe:et,e.elementType=t,e.type=t,e.expirationTime=n,e}function Gr(e,t,n){return(e=$r(6,e,null,t)).expirationTime=n,e}function Jr(e,t,n){return(t=$r(4,null!==e.children?e.children:[],e.key,t)).expirationTime=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Zr(e,t){e.didError=!1;var n=e.earliestPendingTime;0===n?e.earliestPendingTime=e.latestPendingTime=t:n<t?e.earliestPendingTime=t:e.latestPendingTime>t&&(e.latestPendingTime=t),nl(t,e)}function el(e,t){e.didError=!1,e.latestPingedTime>=t&&(e.latestPingedTime=0);var n=e.earliestPendingTime,r=e.latestPendingTime;n===t?e.earliestPendingTime=r===t?e.latestPendingTime=0:r:r===t&&(e.latestPendingTime=n),n=e.earliestSuspendedTime,r=e.latestSuspendedTime,0===n?e.earliestSuspendedTime=e.latestSuspendedTime=t:n<t?e.earliestSuspendedTime=t:r>t&&(e.latestSuspendedTime=t),nl(t,e)}function tl(e,t){var n=e.earliestPendingTime;return n>t&&(t=n),(e=e.earliestSuspendedTime)>t&&(t=e),t}function nl(e,t){var n=t.earliestSuspendedTime,r=t.latestSuspendedTime,l=t.earliestPendingTime,i=t.latestPingedTime;0===(l=0!==l?l:i)&&(0===e||r<e)&&(l=r),0!==(e=l)&&n>e&&(e=n),t.nextExpirationTimeToWorkOn=l,t.expirationTime=e}function rl(e,t){if(e&&e.defaultProps)for(var n in t=l({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}var ll=(new r.Component).refs;function il(e,t,n,r){n=null===(n=n(r,t=e.memoizedState))||void 0===n?t:l({},t,n),e.memoizedState=n,null!==(r=e.updateQueue)&&0===e.expirationTime&&(r.baseState=n)}var ol={isMounted:function(e){return!!(e=e._reactInternalFiber)&&2===tn(e)},enqueueSetState:function(e,t,n){e=e._reactInternalFiber;var r=xa(),l=Yi(r=Yo(r,e));l.payload=t,void 0!==n&&null!==n&&(l.callback=n),Bo(),Gi(e,l),Jo(e,r)},enqueueReplaceState:function(e,t,n){e=e._reactInternalFiber;var r=xa(),l=Yi(r=Yo(r,e));l.tag=Bi,l.payload=t,void 0!==n&&null!==n&&(l.callback=n),Bo(),Gi(e,l),Jo(e,r)},enqueueForceUpdate:function(e,t){e=e._reactInternalFiber;var n=xa(),r=Yi(n=Yo(n,e));r.tag=Hi,void 0!==t&&null!==t&&(r.callback=t),Bo(),Gi(e,r),Jo(e,n)}};function al(e,t,n,r,l,i,o){return"function"===typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,i,o):!t.prototype||!t.prototype.isPureReactComponent||(!en(n,r)||!en(l,i))}function ul(e,t,n){var r=!1,l=Nr,i=t.contextType;return"object"===typeof i&&null!==i?i=Wi(i):(l=Ir(t)?Rr:Or.current,i=(r=null!==(r=t.contextTypes)&&void 0!==r)?Mr(e,l):Nr),t=new t(n,i),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=ol,e.stateNode=t,t._reactInternalFiber=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=l,e.__reactInternalMemoizedMaskedChildContext=i),t}function cl(e,t,n,r){e=t.state,"function"===typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"===typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&ol.enqueueReplaceState(t,t.state,null)}function sl(e,t,n,r){var l=e.stateNode;l.props=n,l.state=e.memoizedState,l.refs=ll;var i=t.contextType;"object"===typeof i&&null!==i?l.context=Wi(i):(i=Ir(t)?Rr:Or.current,l.context=Mr(e,i)),null!==(i=e.updateQueue)&&(to(e,i,n,l,r),l.state=e.memoizedState),"function"===typeof(i=t.getDerivedStateFromProps)&&(il(e,t,i,n),l.state=e.memoizedState),"function"===typeof t.getDerivedStateFromProps||"function"===typeof l.getSnapshotBeforeUpdate||"function"!==typeof l.UNSAFE_componentWillMount&&"function"!==typeof l.componentWillMount||(t=l.state,"function"===typeof l.componentWillMount&&l.componentWillMount(),"function"===typeof l.UNSAFE_componentWillMount&&l.UNSAFE_componentWillMount(),t!==l.state&&ol.enqueueReplaceState(l,l.state,null),null!==(i=e.updateQueue)&&(to(e,i,n,l,r),l.state=e.memoizedState)),"function"===typeof l.componentDidMount&&(e.effectTag|=4)}var fl=Array.isArray;function dl(e,t,n){if(null!==(e=n.ref)&&"function"!==typeof e&&"object"!==typeof e){if(n._owner){n=n._owner;var r=void 0;n&&(1!==n.tag&&o("309"),r=n.stateNode),r||o("147",e);var l=""+e;return null!==t&&null!==t.ref&&"function"===typeof t.ref&&t.ref._stringRef===l?t.ref:((t=function(e){var t=r.refs;t===ll&&(t=r.refs={}),null===e?delete t[l]:t[l]=e})._stringRef=l,t)}"string"!==typeof e&&o("284"),n._owner||o("290",e)}return e}function pl(e,t){"textarea"!==e.type&&o("31","[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t,"")}function ml(e){function t(t,n){if(e){var r=t.lastEffect;null!==r?(r.nextEffect=n,t.lastEffect=n):t.firstEffect=t.lastEffect=n,n.nextEffect=null,n.effectTag=8}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function l(e,t,n){return(e=Kr(e,t)).index=0,e.sibling=null,e}function i(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.effectTag=2,n):r:(t.effectTag=2,n):n}function a(t){return e&&null===t.alternate&&(t.effectTag=2),t}function u(e,t,n,r){return null===t||6!==t.tag?((t=Gr(n,e.mode,r)).return=e,t):((t=l(t,n)).return=e,t)}function c(e,t,n,r){return null!==t&&t.elementType===n.type?((r=l(t,n.props)).ref=dl(e,t,n),r.return=e,r):((r=qr(n.type,n.key,n.props,null,e.mode,r)).ref=dl(e,t,n),r.return=e,r)}function s(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Jr(n,e.mode,r)).return=e,t):((t=l(t,n.children||[])).return=e,t)}function f(e,t,n,r,i){return null===t||7!==t.tag?((t=Yr(n,e.mode,r,i)).return=e,t):((t=l(t,n)).return=e,t)}function d(e,t,n){if("string"===typeof t||"number"===typeof t)return(t=Gr(""+t,e.mode,n)).return=e,t;if("object"===typeof t&&null!==t){switch(t.$$typeof){case Ke:return(n=qr(t.type,t.key,t.props,null,e.mode,n)).ref=dl(e,null,t),n.return=e,n;case qe:return(t=Jr(t,e.mode,n)).return=e,t}if(fl(t)||ot(t))return(t=Yr(t,e.mode,n,null)).return=e,t;pl(e,t)}return null}function p(e,t,n,r){var l=null!==t?t.key:null;if("string"===typeof n||"number"===typeof n)return null!==l?null:u(e,t,""+n,r);if("object"===typeof n&&null!==n){switch(n.$$typeof){case Ke:return n.key===l?n.type===Ye?f(e,t,n.props.children,r,l):c(e,t,n,r):null;case qe:return n.key===l?s(e,t,n,r):null}if(fl(n)||ot(n))return null!==l?null:f(e,t,n,r,null);pl(e,n)}return null}function m(e,t,n,r,l){if("string"===typeof r||"number"===typeof r)return u(t,e=e.get(n)||null,""+r,l);if("object"===typeof r&&null!==r){switch(r.$$typeof){case Ke:return e=e.get(null===r.key?n:r.key)||null,r.type===Ye?f(t,e,r.props.children,l,r.key):c(t,e,r,l);case qe:return s(t,e=e.get(null===r.key?n:r.key)||null,r,l)}if(fl(r)||ot(r))return f(t,e=e.get(n)||null,r,l,null);pl(t,r)}return null}function h(l,o,a,u){for(var c=null,s=null,f=o,h=o=0,y=null;null!==f&&h<a.length;h++){f.index>h?(y=f,f=null):y=f.sibling;var v=p(l,f,a[h],u);if(null===v){null===f&&(f=y);break}e&&f&&null===v.alternate&&t(l,f),o=i(v,o,h),null===s?c=v:s.sibling=v,s=v,f=y}if(h===a.length)return n(l,f),c;if(null===f){for(;h<a.length;h++)(f=d(l,a[h],u))&&(o=i(f,o,h),null===s?c=f:s.sibling=f,s=f);return c}for(f=r(l,f);h<a.length;h++)(y=m(f,l,h,a[h],u))&&(e&&null!==y.alternate&&f.delete(null===y.key?h:y.key),o=i(y,o,h),null===s?c=y:s.sibling=y,s=y);return e&&f.forEach(function(e){return t(l,e)}),c}function y(l,a,u,c){var s=ot(u);"function"!==typeof s&&o("150"),null==(u=s.call(u))&&o("151");for(var f=s=null,h=a,y=a=0,v=null,g=u.next();null!==h&&!g.done;y++,g=u.next()){h.index>y?(v=h,h=null):v=h.sibling;var b=p(l,h,g.value,c);if(null===b){h||(h=v);break}e&&h&&null===b.alternate&&t(l,h),a=i(b,a,y),null===f?s=b:f.sibling=b,f=b,h=v}if(g.done)return n(l,h),s;if(null===h){for(;!g.done;y++,g=u.next())null!==(g=d(l,g.value,c))&&(a=i(g,a,y),null===f?s=g:f.sibling=g,f=g);return s}for(h=r(l,h);!g.done;y++,g=u.next())null!==(g=m(h,l,y,g.value,c))&&(e&&null!==g.alternate&&h.delete(null===g.key?y:g.key),a=i(g,a,y),null===f?s=g:f.sibling=g,f=g);return e&&h.forEach(function(e){return t(l,e)}),s}return function(e,r,i,u){var c="object"===typeof i&&null!==i&&i.type===Ye&&null===i.key;c&&(i=i.props.children);var s="object"===typeof i&&null!==i;if(s)switch(i.$$typeof){case Ke:e:{for(s=i.key,c=r;null!==c;){if(c.key===s){if(7===c.tag?i.type===Ye:c.elementType===i.type){n(e,c.sibling),(r=l(c,i.type===Ye?i.props.children:i.props)).ref=dl(e,c,i),r.return=e,e=r;break e}n(e,c);break}t(e,c),c=c.sibling}i.type===Ye?((r=Yr(i.props.children,e.mode,u,i.key)).return=e,e=r):((u=qr(i.type,i.key,i.props,null,e.mode,u)).ref=dl(e,r,i),u.return=e,e=u)}return a(e);case qe:e:{for(c=i.key;null!==r;){if(r.key===c){if(4===r.tag&&r.stateNode.containerInfo===i.containerInfo&&r.stateNode.implementation===i.implementation){n(e,r.sibling),(r=l(r,i.children||[])).return=e,e=r;break e}n(e,r);break}t(e,r),r=r.sibling}(r=Jr(i,e.mode,u)).return=e,e=r}return a(e)}if("string"===typeof i||"number"===typeof i)return i=""+i,null!==r&&6===r.tag?(n(e,r.sibling),(r=l(r,i)).return=e,e=r):(n(e,r),(r=Gr(i,e.mode,u)).return=e,e=r),a(e);if(fl(i))return h(e,r,i,u);if(ot(i))return y(e,r,i,u);if(s&&pl(e,i),"undefined"===typeof i&&!c)switch(e.tag){case 1:case 0:o("152",(u=e.type).displayName||u.name||"Component")}return n(e,r)}}var hl=ml(!0),yl=ml(!1),vl={},gl={current:vl},bl={current:vl},kl={current:vl};function wl(e){return e===vl&&o("174"),e}function xl(e,t){Pr(kl,t),Pr(bl,e),Pr(gl,vl);var n=t.nodeType;switch(n){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:tr(null,"");break;default:t=tr(t=(n=8===n?t.parentNode:t).namespaceURI||null,n=n.tagName)}Cr(gl),Pr(gl,t)}function Tl(e){Cr(gl),Cr(bl),Cr(kl)}function Sl(e){wl(kl.current);var t=wl(gl.current),n=tr(t,e.type);t!==n&&(Pr(bl,e),Pr(gl,n))}function _l(e){bl.current===e&&(Cr(gl),Cr(bl))}var El=0,Cl=2,Pl=4,Nl=8,Ol=16,zl=32,Rl=64,Ml=128,Il=He.ReactCurrentDispatcher,Ul=0,Dl=null,Fl=null,Ll=null,Al=null,jl=null,Wl=null,Vl=0,Bl=null,Hl=0,$l=!1,Ql=null,Kl=0;function ql(){o("307")}function Yl(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!Jt(e[n],t[n]))return!1;return!0}function Xl(e,t,n,r,l,i){if(Ul=i,Dl=t,Ll=null!==e?e.memoizedState:null,Il.current=null===Ll?ci:si,t=n(r,l),$l){do{$l=!1,Kl+=1,Ll=null!==e?e.memoizedState:null,Wl=Al,Bl=jl=Fl=null,Il.current=si,t=n(r,l)}while($l);Ql=null,Kl=0}return Il.current=ui,(e=Dl).memoizedState=Al,e.expirationTime=Vl,e.updateQueue=Bl,e.effectTag|=Hl,e=null!==Fl&&null!==Fl.next,Ul=0,Wl=jl=Al=Ll=Fl=Dl=null,Vl=0,Bl=null,Hl=0,e&&o("300"),t}function Gl(){Il.current=ui,Ul=0,Wl=jl=Al=Ll=Fl=Dl=null,Vl=0,Bl=null,Hl=0,$l=!1,Ql=null,Kl=0}function Jl(){var e={memoizedState:null,baseState:null,queue:null,baseUpdate:null,next:null};return null===jl?Al=jl=e:jl=jl.next=e,jl}function Zl(){if(null!==Wl)Wl=(jl=Wl).next,Ll=null!==(Fl=Ll)?Fl.next:null;else{null===Ll&&o("310");var e={memoizedState:(Fl=Ll).memoizedState,baseState:Fl.baseState,queue:Fl.queue,baseUpdate:Fl.baseUpdate,next:null};jl=null===jl?Al=e:jl.next=e,Ll=Fl.next}return jl}function ei(e,t){return"function"===typeof t?t(e):t}function ti(e){var t=Zl(),n=t.queue;if(null===n&&o("311"),0<Kl){var r=n.dispatch;if(null!==Ql){var l=Ql.get(n);if(void 0!==l){Ql.delete(n);var i=t.memoizedState;do{i=e(i,l.action),l=l.next}while(null!==l);return Jt(i,t.memoizedState)||(wi=!0),t.memoizedState=i,t.baseUpdate===n.last&&(t.baseState=i),[i,r]}}return[t.memoizedState,r]}r=n.last;var a=t.baseUpdate;if(i=t.baseState,null!==a?(null!==r&&(r.next=null),r=a.next):r=null!==r?r.next:null,null!==r){var u=l=null,c=r,s=!1;do{var f=c.expirationTime;f<Ul?(s||(s=!0,u=a,l=i),f>Vl&&(Vl=f)):i=c.eagerReducer===e?c.eagerState:e(i,c.action),a=c,c=c.next}while(null!==c&&c!==r);s||(u=a,l=i),Jt(i,t.memoizedState)||(wi=!0),t.memoizedState=i,t.baseUpdate=u,t.baseState=l,n.eagerReducer=e,n.eagerState=i}return[t.memoizedState,n.dispatch]}function ni(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===Bl?(Bl={lastEffect:null}).lastEffect=e.next=e:null===(t=Bl.lastEffect)?Bl.lastEffect=e.next=e:(n=t.next,t.next=e,e.next=n,Bl.lastEffect=e),e}function ri(e,t,n,r){var l=Jl();Hl|=e,l.memoizedState=ni(t,n,void 0,void 0===r?null:r)}function li(e,t,n,r){var l=Zl();r=void 0===r?null:r;var i=void 0;if(null!==Fl){var o=Fl.memoizedState;if(i=o.destroy,null!==r&&Yl(r,o.deps))return void ni(El,n,i,r)}Hl|=e,l.memoizedState=ni(t,n,i,r)}function ii(e,t){return"function"===typeof t?(e=e(),t(e),function(){t(null)}):null!==t&&void 0!==t?(e=e(),t.current=e,function(){t.current=null}):void 0}function oi(){}function ai(e,t,n){25>Kl||o("301");var r=e.alternate;if(e===Dl||null!==r&&r===Dl)if($l=!0,e={expirationTime:Ul,action:n,eagerReducer:null,eagerState:null,next:null},null===Ql&&(Ql=new Map),void 0===(n=Ql.get(t)))Ql.set(t,e);else{for(t=n;null!==t.next;)t=t.next;t.next=e}else{Bo();var l=xa(),i={expirationTime:l=Yo(l,e),action:n,eagerReducer:null,eagerState:null,next:null},a=t.last;if(null===a)i.next=i;else{var u=a.next;null!==u&&(i.next=u),a.next=i}if(t.last=i,0===e.expirationTime&&(null===r||0===r.expirationTime)&&null!==(r=t.eagerReducer))try{var c=t.eagerState,s=r(c,n);if(i.eagerReducer=r,i.eagerState=s,Jt(s,c))return}catch(f){}Jo(e,l)}}var ui={readContext:Wi,useCallback:ql,useContext:ql,useEffect:ql,useImperativeHandle:ql,useLayoutEffect:ql,useMemo:ql,useReducer:ql,useRef:ql,useState:ql,useDebugValue:ql},ci={readContext:Wi,useCallback:function(e,t){return Jl().memoizedState=[e,void 0===t?null:t],e},useContext:Wi,useEffect:function(e,t){return ri(516,Ml|Rl,e,t)},useImperativeHandle:function(e,t,n){return n=null!==n&&void 0!==n?n.concat([e]):null,ri(4,Pl|zl,ii.bind(null,t,e),n)},useLayoutEffect:function(e,t){return ri(4,Pl|zl,e,t)},useMemo:function(e,t){var n=Jl();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=Jl();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e=(e=r.queue={last:null,dispatch:null,eagerReducer:e,eagerState:t}).dispatch=ai.bind(null,Dl,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},Jl().memoizedState=e},useState:function(e){var t=Jl();return"function"===typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={last:null,dispatch:null,eagerReducer:ei,eagerState:e}).dispatch=ai.bind(null,Dl,e),[t.memoizedState,e]},useDebugValue:oi},si={readContext:Wi,useCallback:function(e,t){var n=Zl();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&Yl(t,r[1])?r[0]:(n.memoizedState=[e,t],e)},useContext:Wi,useEffect:function(e,t){return li(516,Ml|Rl,e,t)},useImperativeHandle:function(e,t,n){return n=null!==n&&void 0!==n?n.concat([e]):null,li(4,Pl|zl,ii.bind(null,t,e),n)},useLayoutEffect:function(e,t){return li(4,Pl|zl,e,t)},useMemo:function(e,t){var n=Zl();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&Yl(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)},useReducer:ti,useRef:function(){return Zl().memoizedState},useState:function(e){return ti(ei)},useDebugValue:oi},fi=null,di=null,pi=!1;function mi(e,t){var n=$r(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.effectTag=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function hi(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,!0);case 13:default:return!1}}function yi(e){if(pi){var t=di;if(t){var n=t;if(!hi(e,t)){if(!(t=Tr(n))||!hi(e,t))return e.effectTag|=2,pi=!1,void(fi=e);mi(fi,n)}fi=e,di=Sr(t)}else e.effectTag|=2,pi=!1,fi=e}}function vi(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&18!==e.tag;)e=e.return;fi=e}function gi(e){if(e!==fi)return!1;if(!pi)return vi(e),pi=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!gr(t,e.memoizedProps))for(t=di;t;)mi(e,t),t=Tr(t);return vi(e),di=fi?Tr(e.stateNode):null,!0}function bi(){di=fi=null,pi=!1}var ki=He.ReactCurrentOwner,wi=!1;function xi(e,t,n,r){t.child=null===e?yl(t,null,n,r):hl(t,e.child,n,r)}function Ti(e,t,n,r,l){n=n.render;var i=t.ref;return ji(t,l),r=Xl(e,t,n,r,i,l),null===e||wi?(t.effectTag|=1,xi(e,t,r,l),t.child):(t.updateQueue=e.updateQueue,t.effectTag&=-517,e.expirationTime<=l&&(e.expirationTime=0),Ri(e,t,l))}function Si(e,t,n,r,l,i){if(null===e){var o=n.type;return"function"!==typeof o||Qr(o)||void 0!==o.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=qr(n.type,null,r,null,t.mode,i)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=o,_i(e,t,o,r,l,i))}return o=e.child,l<i&&(l=o.memoizedProps,(n=null!==(n=n.compare)?n:en)(l,r)&&e.ref===t.ref)?Ri(e,t,i):(t.effectTag|=1,(e=Kr(o,r)).ref=t.ref,e.return=t,t.child=e)}function _i(e,t,n,r,l,i){return null!==e&&en(e.memoizedProps,r)&&e.ref===t.ref&&(wi=!1,l<i)?Ri(e,t,i):Ci(e,t,n,r,i)}function Ei(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.effectTag|=128)}function Ci(e,t,n,r,l){var i=Ir(n)?Rr:Or.current;return i=Mr(t,i),ji(t,l),n=Xl(e,t,n,r,i,l),null===e||wi?(t.effectTag|=1,xi(e,t,n,l),t.child):(t.updateQueue=e.updateQueue,t.effectTag&=-517,e.expirationTime<=l&&(e.expirationTime=0),Ri(e,t,l))}function Pi(e,t,n,r,l){if(Ir(n)){var i=!0;Ar(t)}else i=!1;if(ji(t,l),null===t.stateNode)null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),ul(t,n,r),sl(t,n,r,l),r=!0;else if(null===e){var o=t.stateNode,a=t.memoizedProps;o.props=a;var u=o.context,c=n.contextType;"object"===typeof c&&null!==c?c=Wi(c):c=Mr(t,c=Ir(n)?Rr:Or.current);var s=n.getDerivedStateFromProps,f="function"===typeof s||"function"===typeof o.getSnapshotBeforeUpdate;f||"function"!==typeof o.UNSAFE_componentWillReceiveProps&&"function"!==typeof o.componentWillReceiveProps||(a!==r||u!==c)&&cl(t,o,r,c),Qi=!1;var d=t.memoizedState;u=o.state=d;var p=t.updateQueue;null!==p&&(to(t,p,r,o,l),u=t.memoizedState),a!==r||d!==u||zr.current||Qi?("function"===typeof s&&(il(t,n,s,r),u=t.memoizedState),(a=Qi||al(t,n,a,r,d,u,c))?(f||"function"!==typeof o.UNSAFE_componentWillMount&&"function"!==typeof o.componentWillMount||("function"===typeof o.componentWillMount&&o.componentWillMount(),"function"===typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount()),"function"===typeof o.componentDidMount&&(t.effectTag|=4)):("function"===typeof o.componentDidMount&&(t.effectTag|=4),t.memoizedProps=r,t.memoizedState=u),o.props=r,o.state=u,o.context=c,r=a):("function"===typeof o.componentDidMount&&(t.effectTag|=4),r=!1)}else o=t.stateNode,a=t.memoizedProps,o.props=t.type===t.elementType?a:rl(t.type,a),u=o.context,"object"===typeof(c=n.contextType)&&null!==c?c=Wi(c):c=Mr(t,c=Ir(n)?Rr:Or.current),(f="function"===typeof(s=n.getDerivedStateFromProps)||"function"===typeof o.getSnapshotBeforeUpdate)||"function"!==typeof o.UNSAFE_componentWillReceiveProps&&"function"!==typeof o.componentWillReceiveProps||(a!==r||u!==c)&&cl(t,o,r,c),Qi=!1,u=t.memoizedState,d=o.state=u,null!==(p=t.updateQueue)&&(to(t,p,r,o,l),d=t.memoizedState),a!==r||u!==d||zr.current||Qi?("function"===typeof s&&(il(t,n,s,r),d=t.memoizedState),(s=Qi||al(t,n,a,r,u,d,c))?(f||"function"!==typeof o.UNSAFE_componentWillUpdate&&"function"!==typeof o.componentWillUpdate||("function"===typeof o.componentWillUpdate&&o.componentWillUpdate(r,d,c),"function"===typeof o.UNSAFE_componentWillUpdate&&o.UNSAFE_componentWillUpdate(r,d,c)),"function"===typeof o.componentDidUpdate&&(t.effectTag|=4),"function"===typeof o.getSnapshotBeforeUpdate&&(t.effectTag|=256)):("function"!==typeof o.componentDidUpdate||a===e.memoizedProps&&u===e.memoizedState||(t.effectTag|=4),"function"!==typeof o.getSnapshotBeforeUpdate||a===e.memoizedProps&&u===e.memoizedState||(t.effectTag|=256),t.memoizedProps=r,t.memoizedState=d),o.props=r,o.state=d,o.context=c,r=s):("function"!==typeof o.componentDidUpdate||a===e.memoizedProps&&u===e.memoizedState||(t.effectTag|=4),"function"!==typeof o.getSnapshotBeforeUpdate||a===e.memoizedProps&&u===e.memoizedState||(t.effectTag|=256),r=!1);return Ni(e,t,n,r,i,l)}function Ni(e,t,n,r,l,i){Ei(e,t);var o=0!==(64&t.effectTag);if(!r&&!o)return l&&jr(t,n,!1),Ri(e,t,i);r=t.stateNode,ki.current=t;var a=o&&"function"!==typeof n.getDerivedStateFromError?null:r.render();return t.effectTag|=1,null!==e&&o?(t.child=hl(t,e.child,null,i),t.child=hl(t,null,a,i)):xi(e,t,a,i),t.memoizedState=r.state,l&&jr(t,n,!0),t.child}function Oi(e){var t=e.stateNode;t.pendingContext?Fr(0,t.pendingContext,t.pendingContext!==t.context):t.context&&Fr(0,t.context,!1),xl(e,t.containerInfo)}function zi(e,t,n){var r=t.mode,l=t.pendingProps,i=t.memoizedState;if(0===(64&t.effectTag)){i=null;var o=!1}else i={timedOutAt:null!==i?i.timedOutAt:0},o=!0,t.effectTag&=-65;if(null===e)if(o){var a=l.fallback;e=Yr(null,r,0,null),0===(1&t.mode)&&(e.child=null!==t.memoizedState?t.child.child:t.child),r=Yr(a,r,n,null),e.sibling=r,(n=e).return=r.return=t}else n=r=yl(t,null,l.children,n);else null!==e.memoizedState?(a=(r=e.child).sibling,o?(n=l.fallback,l=Kr(r,r.pendingProps),0===(1&t.mode)&&((o=null!==t.memoizedState?t.child.child:t.child)!==r.child&&(l.child=o)),r=l.sibling=Kr(a,n,a.expirationTime),n=l,l.childExpirationTime=0,n.return=r.return=t):n=r=hl(t,r.child,l.children,n)):(a=e.child,o?(o=l.fallback,(l=Yr(null,r,0,null)).child=a,0===(1&t.mode)&&(l.child=null!==t.memoizedState?t.child.child:t.child),(r=l.sibling=Yr(o,r,n,null)).effectTag|=2,n=l,l.childExpirationTime=0,n.return=r.return=t):r=n=hl(t,a,l.children,n)),t.stateNode=e.stateNode;return t.memoizedState=i,t.child=n,r}function Ri(e,t,n){if(null!==e&&(t.contextDependencies=e.contextDependencies),t.childExpirationTime<n)return null;if(null!==e&&t.child!==e.child&&o("153"),null!==t.child){for(n=Kr(e=t.child,e.pendingProps,e.expirationTime),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Kr(e,e.pendingProps,e.expirationTime)).return=t;n.sibling=null}return t.child}function Mi(e,t,n){var r=t.expirationTime;if(null!==e){if(e.memoizedProps!==t.pendingProps||zr.current)wi=!0;else if(r<n){switch(wi=!1,t.tag){case 3:Oi(t),bi();break;case 5:Sl(t);break;case 1:Ir(t.type)&&Ar(t);break;case 4:xl(t,t.stateNode.containerInfo);break;case 10:Li(t,t.memoizedProps.value);break;case 13:if(null!==t.memoizedState)return 0!==(r=t.child.childExpirationTime)&&r>=n?zi(e,t,n):null!==(t=Ri(e,t,n))?t.sibling:null}return Ri(e,t,n)}}else wi=!1;switch(t.expirationTime=0,t.tag){case 2:r=t.elementType,null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),e=t.pendingProps;var l=Mr(t,Or.current);if(ji(t,n),l=Xl(null,t,r,e,l,n),t.effectTag|=1,"object"===typeof l&&null!==l&&"function"===typeof l.render&&void 0===l.$$typeof){if(t.tag=1,Gl(),Ir(r)){var i=!0;Ar(t)}else i=!1;t.memoizedState=null!==l.state&&void 0!==l.state?l.state:null;var a=r.getDerivedStateFromProps;"function"===typeof a&&il(t,r,a,e),l.updater=ol,t.stateNode=l,l._reactInternalFiber=t,sl(t,r,e,n),t=Ni(null,t,r,!0,i,n)}else t.tag=0,xi(null,t,l,n),t=t.child;return t;case 16:switch(l=t.elementType,null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),i=t.pendingProps,e=function(e){var t=e._result;switch(e._status){case 1:return t;case 2:case 0:throw t;default:switch(e._status=0,(t=(t=e._ctor)()).then(function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)},function(t){0===e._status&&(e._status=2,e._result=t)}),e._status){case 1:return e._result;case 2:throw e._result}throw e._result=t,t}}(l),t.type=e,l=t.tag=function(e){if("function"===typeof e)return Qr(e)?1:0;if(void 0!==e&&null!==e){if((e=e.$$typeof)===tt)return 11;if(e===rt)return 14}return 2}(e),i=rl(e,i),a=void 0,l){case 0:a=Ci(null,t,e,i,n);break;case 1:a=Pi(null,t,e,i,n);break;case 11:a=Ti(null,t,e,i,n);break;case 14:a=Si(null,t,e,rl(e.type,i),r,n);break;default:o("306",e,"")}return a;case 0:return r=t.type,l=t.pendingProps,Ci(e,t,r,l=t.elementType===r?l:rl(r,l),n);case 1:return r=t.type,l=t.pendingProps,Pi(e,t,r,l=t.elementType===r?l:rl(r,l),n);case 3:return Oi(t),null===(r=t.updateQueue)&&o("282"),l=null!==(l=t.memoizedState)?l.element:null,to(t,r,t.pendingProps,null,n),(r=t.memoizedState.element)===l?(bi(),t=Ri(e,t,n)):(l=t.stateNode,(l=(null===e||null===e.child)&&l.hydrate)&&(di=Sr(t.stateNode.containerInfo),fi=t,l=pi=!0),l?(t.effectTag|=2,t.child=yl(t,null,r,n)):(xi(e,t,r,n),bi()),t=t.child),t;case 5:return Sl(t),null===e&&yi(t),r=t.type,l=t.pendingProps,i=null!==e?e.memoizedProps:null,a=l.children,gr(r,l)?a=null:null!==i&&gr(r,i)&&(t.effectTag|=16),Ei(e,t),1!==n&&1&t.mode&&l.hidden?(t.expirationTime=t.childExpirationTime=1,t=null):(xi(e,t,a,n),t=t.child),t;case 6:return null===e&&yi(t),null;case 13:return zi(e,t,n);case 4:return xl(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=hl(t,null,r,n):xi(e,t,r,n),t.child;case 11:return r=t.type,l=t.pendingProps,Ti(e,t,r,l=t.elementType===r?l:rl(r,l),n);case 7:return xi(e,t,t.pendingProps,n),t.child;case 8:case 12:return xi(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,l=t.pendingProps,a=t.memoizedProps,Li(t,i=l.value),null!==a){var u=a.value;if(0===(i=Jt(u,i)?0:0|("function"===typeof r._calculateChangedBits?r._calculateChangedBits(u,i):1073741823))){if(a.children===l.children&&!zr.current){t=Ri(e,t,n);break e}}else for(null!==(u=t.child)&&(u.return=t);null!==u;){var c=u.contextDependencies;if(null!==c){a=u.child;for(var s=c.first;null!==s;){if(s.context===r&&0!==(s.observedBits&i)){1===u.tag&&((s=Yi(n)).tag=Hi,Gi(u,s)),u.expirationTime<n&&(u.expirationTime=n),null!==(s=u.alternate)&&s.expirationTime<n&&(s.expirationTime=n),s=n;for(var f=u.return;null!==f;){var d=f.alternate;if(f.childExpirationTime<s)f.childExpirationTime=s,null!==d&&d.childExpirationTime<s&&(d.childExpirationTime=s);else{if(!(null!==d&&d.childExpirationTime<s))break;d.childExpirationTime=s}f=f.return}c.expirationTime<n&&(c.expirationTime=n);break}s=s.next}}else a=10===u.tag&&u.type===t.type?null:u.child;if(null!==a)a.return=u;else for(a=u;null!==a;){if(a===t){a=null;break}if(null!==(u=a.sibling)){u.return=a.return,a=u;break}a=a.return}u=a}}xi(e,t,l.children,n),t=t.child}return t;case 9:return l=t.type,r=(i=t.pendingProps).children,ji(t,n),r=r(l=Wi(l,i.unstable_observedBits)),t.effectTag|=1,xi(e,t,r,n),t.child;case 14:return i=rl(l=t.type,t.pendingProps),Si(e,t,l,i=rl(l.type,i),r,n);case 15:return _i(e,t,t.type,t.pendingProps,r,n);case 17:return r=t.type,l=t.pendingProps,l=t.elementType===r?l:rl(r,l),null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),t.tag=1,Ir(r)?(e=!0,Ar(t)):e=!1,ji(t,n),ul(t,r,l),sl(t,r,l,n),Ni(null,t,r,!0,e,n)}o("156")}var Ii={current:null},Ui=null,Di=null,Fi=null;function Li(e,t){var n=e.type._context;Pr(Ii,n._currentValue),n._currentValue=t}function Ai(e){var t=Ii.current;Cr(Ii),e.type._context._currentValue=t}function ji(e,t){Ui=e,Fi=Di=null;var n=e.contextDependencies;null!==n&&n.expirationTime>=t&&(wi=!0),e.contextDependencies=null}function Wi(e,t){return Fi!==e&&!1!==t&&0!==t&&("number"===typeof t&&1073741823!==t||(Fi=e,t=1073741823),t={context:e,observedBits:t,next:null},null===Di?(null===Ui&&o("308"),Di=t,Ui.contextDependencies={first:t,expirationTime:0}):Di=Di.next=t),e._currentValue}var Vi=0,Bi=1,Hi=2,$i=3,Qi=!1;function Ki(e){return{baseState:e,firstUpdate:null,lastUpdate:null,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function qi(e){return{baseState:e.baseState,firstUpdate:e.firstUpdate,lastUpdate:e.lastUpdate,firstCapturedUpdate:null,lastCapturedUpdate:null,firstEffect:null,lastEffect:null,firstCapturedEffect:null,lastCapturedEffect:null}}function Yi(e){return{expirationTime:e,tag:Vi,payload:null,callback:null,next:null,nextEffect:null}}function Xi(e,t){null===e.lastUpdate?e.firstUpdate=e.lastUpdate=t:(e.lastUpdate.next=t,e.lastUpdate=t)}function Gi(e,t){var n=e.alternate;if(null===n){var r=e.updateQueue,l=null;null===r&&(r=e.updateQueue=Ki(e.memoizedState))}else r=e.updateQueue,l=n.updateQueue,null===r?null===l?(r=e.updateQueue=Ki(e.memoizedState),l=n.updateQueue=Ki(n.memoizedState)):r=e.updateQueue=qi(l):null===l&&(l=n.updateQueue=qi(r));null===l||r===l?Xi(r,t):null===r.lastUpdate||null===l.lastUpdate?(Xi(r,t),Xi(l,t)):(Xi(r,t),l.lastUpdate=t)}function Ji(e,t){var n=e.updateQueue;null===(n=null===n?e.updateQueue=Ki(e.memoizedState):Zi(e,n)).lastCapturedUpdate?n.firstCapturedUpdate=n.lastCapturedUpdate=t:(n.lastCapturedUpdate.next=t,n.lastCapturedUpdate=t)}function Zi(e,t){var n=e.alternate;return null!==n&&t===n.updateQueue&&(t=e.updateQueue=qi(t)),t}function eo(e,t,n,r,i,o){switch(n.tag){case Bi:return"function"===typeof(e=n.payload)?e.call(o,r,i):e;case $i:e.effectTag=-2049&e.effectTag|64;case Vi:if(null===(i="function"===typeof(e=n.payload)?e.call(o,r,i):e)||void 0===i)break;return l({},r,i);case Hi:Qi=!0}return r}function to(e,t,n,r,l){Qi=!1;for(var i=(t=Zi(e,t)).baseState,o=null,a=0,u=t.firstUpdate,c=i;null!==u;){var s=u.expirationTime;s<l?(null===o&&(o=u,i=c),a<s&&(a=s)):(c=eo(e,0,u,c,n,r),null!==u.callback&&(e.effectTag|=32,u.nextEffect=null,null===t.lastEffect?t.firstEffect=t.lastEffect=u:(t.lastEffect.nextEffect=u,t.lastEffect=u))),u=u.next}for(s=null,u=t.firstCapturedUpdate;null!==u;){var f=u.expirationTime;f<l?(null===s&&(s=u,null===o&&(i=c)),a<f&&(a=f)):(c=eo(e,0,u,c,n,r),null!==u.callback&&(e.effectTag|=32,u.nextEffect=null,null===t.lastCapturedEffect?t.firstCapturedEffect=t.lastCapturedEffect=u:(t.lastCapturedEffect.nextEffect=u,t.lastCapturedEffect=u))),u=u.next}null===o&&(t.lastUpdate=null),null===s?t.lastCapturedUpdate=null:e.effectTag|=32,null===o&&null===s&&(i=c),t.baseState=i,t.firstUpdate=o,t.firstCapturedUpdate=s,e.expirationTime=a,e.memoizedState=c}function no(e,t,n){null!==t.firstCapturedUpdate&&(null!==t.lastUpdate&&(t.lastUpdate.next=t.firstCapturedUpdate,t.lastUpdate=t.lastCapturedUpdate),t.firstCapturedUpdate=t.lastCapturedUpdate=null),ro(t.firstEffect,n),t.firstEffect=t.lastEffect=null,ro(t.firstCapturedEffect,n),t.firstCapturedEffect=t.lastCapturedEffect=null}function ro(e,t){for(;null!==e;){var n=e.callback;if(null!==n){e.callback=null;var r=t;"function"!==typeof n&&o("191",n),n.call(r)}e=e.nextEffect}}function lo(e,t){return{value:e,source:t,stack:ut(t)}}function io(e){e.effectTag|=4}var oo=void 0,ao=void 0,uo=void 0,co=void 0;oo=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},ao=function(){},uo=function(e,t,n,r,i){var o=e.memoizedProps;if(o!==r){var a=t.stateNode;switch(wl(gl.current),e=null,n){case"input":o=bt(a,o),r=bt(a,r),e=[];break;case"option":o=Kn(a,o),r=Kn(a,r),e=[];break;case"select":o=l({},o,{value:void 0}),r=l({},r,{value:void 0}),e=[];break;case"textarea":o=Yn(a,o),r=Yn(a,r),e=[];break;default:"function"!==typeof o.onClick&&"function"===typeof r.onClick&&(a.onclick=mr)}fr(n,r),a=n=void 0;var u=null;for(n in o)if(!r.hasOwnProperty(n)&&o.hasOwnProperty(n)&&null!=o[n])if("style"===n){var c=o[n];for(a in c)c.hasOwnProperty(a)&&(u||(u={}),u[a]="")}else"dangerouslySetInnerHTML"!==n&&"children"!==n&&"suppressContentEditableWarning"!==n&&"suppressHydrationWarning"!==n&&"autoFocus"!==n&&(b.hasOwnProperty(n)?e||(e=[]):(e=e||[]).push(n,null));for(n in r){var s=r[n];if(c=null!=o?o[n]:void 0,r.hasOwnProperty(n)&&s!==c&&(null!=s||null!=c))if("style"===n)if(c){for(a in c)!c.hasOwnProperty(a)||s&&s.hasOwnProperty(a)||(u||(u={}),u[a]="");for(a in s)s.hasOwnProperty(a)&&c[a]!==s[a]&&(u||(u={}),u[a]=s[a])}else u||(e||(e=[]),e.push(n,u)),u=s;else"dangerouslySetInnerHTML"===n?(s=s?s.__html:void 0,c=c?c.__html:void 0,null!=s&&c!==s&&(e=e||[]).push(n,""+s)):"children"===n?c===s||"string"!==typeof s&&"number"!==typeof s||(e=e||[]).push(n,""+s):"suppressContentEditableWarning"!==n&&"suppressHydrationWarning"!==n&&(b.hasOwnProperty(n)?(null!=s&&pr(i,n),e||c===s||(e=[])):(e=e||[]).push(n,s))}u&&(e=e||[]).push("style",u),i=e,(t.updateQueue=i)&&io(t)}},co=function(e,t,n,r){n!==r&&io(t)};var so="function"===typeof WeakSet?WeakSet:Set;function fo(e,t){var n=t.source,r=t.stack;null===r&&null!==n&&(r=ut(n)),null!==n&&at(n.type),t=t.value,null!==e&&1===e.tag&&at(e.type);try{console.error(t)}catch(l){setTimeout(function(){throw l})}}function po(e){var t=e.ref;if(null!==t)if("function"===typeof t)try{t(null)}catch(n){qo(e,n)}else t.current=null}function mo(e,t,n){if(null!==(n=null!==(n=n.updateQueue)?n.lastEffect:null)){var r=n=n.next;do{if((r.tag&e)!==El){var l=r.destroy;r.destroy=void 0,void 0!==l&&l()}(r.tag&t)!==El&&(l=r.create,r.destroy=l()),r=r.next}while(r!==n)}}function ho(e){switch("function"===typeof Vr&&Vr(e),e.tag){case 0:case 11:case 14:case 15:var t=e.updateQueue;if(null!==t&&null!==(t=t.lastEffect)){var n=t=t.next;do{var r=n.destroy;if(void 0!==r){var l=e;try{r()}catch(i){qo(l,i)}}n=n.next}while(n!==t)}break;case 1:if(po(e),"function"===typeof(t=e.stateNode).componentWillUnmount)try{t.props=e.memoizedProps,t.state=e.memoizedState,t.componentWillUnmount()}catch(i){qo(e,i)}break;case 5:po(e);break;case 4:go(e)}}function yo(e){return 5===e.tag||3===e.tag||4===e.tag}function vo(e){e:{for(var t=e.return;null!==t;){if(yo(t)){var n=t;break e}t=t.return}o("160"),n=void 0}var r=t=void 0;switch(n.tag){case 5:t=n.stateNode,r=!1;break;case 3:case 4:t=n.stateNode.containerInfo,r=!0;break;default:o("161")}16&n.effectTag&&(ir(t,""),n.effectTag&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||yo(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag&&18!==n.tag;){if(2&n.effectTag)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.effectTag)){n=n.stateNode;break e}}for(var l=e;;){if(5===l.tag||6===l.tag)if(n)if(r){var i=t,a=l.stateNode,u=n;8===i.nodeType?i.parentNode.insertBefore(a,u):i.insertBefore(a,u)}else t.insertBefore(l.stateNode,n);else r?(a=t,u=l.stateNode,8===a.nodeType?(i=a.parentNode).insertBefore(u,a):(i=a).appendChild(u),null!==(a=a._reactRootContainer)&&void 0!==a||null!==i.onclick||(i.onclick=mr)):t.appendChild(l.stateNode);else if(4!==l.tag&&null!==l.child){l.child.return=l,l=l.child;continue}if(l===e)break;for(;null===l.sibling;){if(null===l.return||l.return===e)return;l=l.return}l.sibling.return=l.return,l=l.sibling}}function go(e){for(var t=e,n=!1,r=void 0,l=void 0;;){if(!n){n=t.return;e:for(;;){switch(null===n&&o("160"),n.tag){case 5:r=n.stateNode,l=!1;break e;case 3:case 4:r=n.stateNode.containerInfo,l=!0;break e}n=n.return}n=!0}if(5===t.tag||6===t.tag){e:for(var i=t,a=i;;)if(ho(a),null!==a.child&&4!==a.tag)a.child.return=a,a=a.child;else{if(a===i)break;for(;null===a.sibling;){if(null===a.return||a.return===i)break e;a=a.return}a.sibling.return=a.return,a=a.sibling}l?(i=r,a=t.stateNode,8===i.nodeType?i.parentNode.removeChild(a):i.removeChild(a)):r.removeChild(t.stateNode)}else if(4===t.tag){if(null!==t.child){r=t.stateNode.containerInfo,l=!0,t.child.return=t,t=t.child;continue}}else if(ho(t),null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return;4===(t=t.return).tag&&(n=!1)}t.sibling.return=t.return,t=t.sibling}}function bo(e,t){switch(t.tag){case 0:case 11:case 14:case 15:mo(Pl,Nl,t);break;case 1:break;case 5:var n=t.stateNode;if(null!=n){var r=t.memoizedProps;e=null!==e?e.memoizedProps:r;var l=t.type,i=t.updateQueue;t.updateQueue=null,null!==i&&function(e,t,n,r,l){e[I]=l,"input"===n&&"radio"===l.type&&null!=l.name&&wt(e,l),dr(n,r),r=dr(n,l);for(var i=0;i<t.length;i+=2){var o=t[i],a=t[i+1];"style"===o?cr(e,a):"dangerouslySetInnerHTML"===o?lr(e,a):"children"===o?ir(e,a):vt(e,o,a,r)}switch(n){case"input":xt(e,l);break;case"textarea":Gn(e,l);break;case"select":t=e._wrapperState.wasMultiple,e._wrapperState.wasMultiple=!!l.multiple,null!=(n=l.value)?qn(e,!!l.multiple,n,!1):t!==!!l.multiple&&(null!=l.defaultValue?qn(e,!!l.multiple,l.defaultValue,!0):qn(e,!!l.multiple,l.multiple?[]:"",!1))}}(n,i,l,e,r)}break;case 6:null===t.stateNode&&o("162"),t.stateNode.nodeValue=t.memoizedProps;break;case 3:case 12:break;case 13:if(n=t.memoizedState,r=void 0,e=t,null===n?r=!1:(r=!0,e=t.child,0===n.timedOutAt&&(n.timedOutAt=xa())),null!==e&&function(e,t){for(var n=e;;){if(5===n.tag){var r=n.stateNode;if(t)r.style.display="none";else{r=n.stateNode;var l=n.memoizedProps.style;l=void 0!==l&&null!==l&&l.hasOwnProperty("display")?l.display:null,r.style.display=ur("display",l)}}else if(6===n.tag)n.stateNode.nodeValue=t?"":n.memoizedProps;else{if(13===n.tag&&null!==n.memoizedState){(r=n.child.sibling).return=n,n=r;continue}if(null!==n.child){n.child.return=n,n=n.child;continue}}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return;n=n.return}n.sibling.return=n.return,n=n.sibling}}(e,r),null!==(n=t.updateQueue)){t.updateQueue=null;var a=t.stateNode;null===a&&(a=t.stateNode=new so),n.forEach(function(e){var n=function(e,t){var n=e.stateNode;null!==n&&n.delete(t),t=Yo(t=xa(),e),null!==(e=Go(e,t))&&(Zr(e,t),0!==(t=e.expirationTime)&&Ta(e,t))}.bind(null,t,e);a.has(e)||(a.add(e),e.then(n,n))})}break;case 17:break;default:o("163")}}var ko="function"===typeof WeakMap?WeakMap:Map;function wo(e,t,n){(n=Yi(n)).tag=$i,n.payload={element:null};var r=t.value;return n.callback=function(){Ra(r),fo(e,t)},n}function xo(e,t,n){(n=Yi(n)).tag=$i;var r=e.type.getDerivedStateFromError;if("function"===typeof r){var l=t.value;n.payload=function(){return r(l)}}var i=e.stateNode;return null!==i&&"function"===typeof i.componentDidCatch&&(n.callback=function(){"function"!==typeof r&&(null===Lo?Lo=new Set([this]):Lo.add(this));var n=t.value,l=t.stack;fo(e,t),this.componentDidCatch(n,{componentStack:null!==l?l:""})}),n}function To(e){switch(e.tag){case 1:Ir(e.type)&&Ur();var t=e.effectTag;return 2048&t?(e.effectTag=-2049&t|64,e):null;case 3:return Tl(),Dr(),0!==(64&(t=e.effectTag))&&o("285"),e.effectTag=-2049&t|64,e;case 5:return _l(e),null;case 13:return 2048&(t=e.effectTag)?(e.effectTag=-2049&t|64,e):null;case 18:return null;case 4:return Tl(),null;case 10:return Ai(e),null;default:return null}}var So=He.ReactCurrentDispatcher,_o=He.ReactCurrentOwner,Eo=1073741822,Co=!1,Po=null,No=null,Oo=0,zo=-1,Ro=!1,Mo=null,Io=!1,Uo=null,Do=null,Fo=null,Lo=null;function Ao(){if(null!==Po)for(var e=Po.return;null!==e;){var t=e;switch(t.tag){case 1:var n=t.type.childContextTypes;null!==n&&void 0!==n&&Ur();break;case 3:Tl(),Dr();break;case 5:_l(t);break;case 4:Tl();break;case 10:Ai(t)}e=e.return}No=null,Oo=0,zo=-1,Ro=!1,Po=null}function jo(){for(;null!==Mo;){var e=Mo.effectTag;if(16&e&&ir(Mo.stateNode,""),128&e){var t=Mo.alternate;null!==t&&(null!==(t=t.ref)&&("function"===typeof t?t(null):t.current=null))}switch(14&e){case 2:vo(Mo),Mo.effectTag&=-3;break;case 6:vo(Mo),Mo.effectTag&=-3,bo(Mo.alternate,Mo);break;case 4:bo(Mo.alternate,Mo);break;case 8:go(e=Mo),e.return=null,e.child=null,e.memoizedState=null,e.updateQueue=null,null!==(e=e.alternate)&&(e.return=null,e.child=null,e.memoizedState=null,e.updateQueue=null)}Mo=Mo.nextEffect}}function Wo(){for(;null!==Mo;){if(256&Mo.effectTag)e:{var e=Mo.alternate,t=Mo;switch(t.tag){case 0:case 11:case 15:mo(Cl,El,t);break e;case 1:if(256&t.effectTag&&null!==e){var n=e.memoizedProps,r=e.memoizedState;t=(e=t.stateNode).getSnapshotBeforeUpdate(t.elementType===t.type?n:rl(t.type,n),r),e.__reactInternalSnapshotBeforeUpdate=t}break e;case 3:case 5:case 6:case 4:case 17:break e;default:o("163")}}Mo=Mo.nextEffect}}function Vo(e,t){for(;null!==Mo;){var n=Mo.effectTag;if(36&n){var r=Mo.alternate,l=Mo,i=t;switch(l.tag){case 0:case 11:case 15:mo(Ol,zl,l);break;case 1:var a=l.stateNode;if(4&l.effectTag)if(null===r)a.componentDidMount();else{var u=l.elementType===l.type?r.memoizedProps:rl(l.type,r.memoizedProps);a.componentDidUpdate(u,r.memoizedState,a.__reactInternalSnapshotBeforeUpdate)}null!==(r=l.updateQueue)&&no(0,r,a);break;case 3:if(null!==(r=l.updateQueue)){if(a=null,null!==l.child)switch(l.child.tag){case 5:a=l.child.stateNode;break;case 1:a=l.child.stateNode}no(0,r,a)}break;case 5:i=l.stateNode,null===r&&4&l.effectTag&&vr(l.type,l.memoizedProps)&&i.focus();break;case 6:case 4:case 12:case 13:case 17:break;default:o("163")}}128&n&&(null!==(l=Mo.ref)&&(i=Mo.stateNode,"function"===typeof l?l(i):l.current=i)),512&n&&(Uo=e),Mo=Mo.nextEffect}}function Bo(){null!==Do&&xr(Do),null!==Fo&&Fo()}function Ho(e,t){Io=Co=!0,e.current===t&&o("177");var n=e.pendingCommitExpirationTime;0===n&&o("261"),e.pendingCommitExpirationTime=0;var r=t.expirationTime,l=t.childExpirationTime;for(function(e,t){if(e.didError=!1,0===t)e.earliestPendingTime=0,e.latestPendingTime=0,e.earliestSuspendedTime=0,e.latestSuspendedTime=0,e.latestPingedTime=0;else{t<e.latestPingedTime&&(e.latestPingedTime=0);var n=e.latestPendingTime;0!==n&&(n>t?e.earliestPendingTime=e.latestPendingTime=0:e.earliestPendingTime>t&&(e.earliestPendingTime=e.latestPendingTime)),0===(n=e.earliestSuspendedTime)?Zr(e,t):t<e.latestSuspendedTime?(e.earliestSuspendedTime=0,e.latestSuspendedTime=0,e.latestPingedTime=0,Zr(e,t)):t>n&&Zr(e,t)}nl(0,e)}(e,l>r?l:r),_o.current=null,r=void 0,1<t.effectTag?null!==t.lastEffect?(t.lastEffect.nextEffect=t,r=t.firstEffect):r=t:r=t.firstEffect,hr=Sn,yr=function(){var e=Dn();if(Fn(e)){if("selectionStart"in e)var t={start:e.selectionStart,end:e.selectionEnd};else e:{var n=(t=(t=e.ownerDocument)&&t.defaultView||window).getSelection&&t.getSelection();if(n&&0!==n.rangeCount){t=n.anchorNode;var r=n.anchorOffset,l=n.focusNode;n=n.focusOffset;try{t.nodeType,l.nodeType}catch(p){t=null;break e}var i=0,o=-1,a=-1,u=0,c=0,s=e,f=null;t:for(;;){for(var d;s!==t||0!==r&&3!==s.nodeType||(o=i+r),s!==l||0!==n&&3!==s.nodeType||(a=i+n),3===s.nodeType&&(i+=s.nodeValue.length),null!==(d=s.firstChild);)f=s,s=d;for(;;){if(s===e)break t;if(f===t&&++u===r&&(o=i),f===l&&++c===n&&(a=i),null!==(d=s.nextSibling))break;f=(s=f).parentNode}s=d}t=-1===o||-1===a?null:{start:o,end:a}}else t=null}t=t||{start:0,end:0}}else t=null;return{focusedElem:e,selectionRange:t}}(),Sn=!1,Mo=r;null!==Mo;){l=!1;var a=void 0;try{Wo()}catch(c){l=!0,a=c}l&&(null===Mo&&o("178"),qo(Mo,a),null!==Mo&&(Mo=Mo.nextEffect))}for(Mo=r;null!==Mo;){l=!1,a=void 0;try{jo()}catch(c){l=!0,a=c}l&&(null===Mo&&o("178"),qo(Mo,a),null!==Mo&&(Mo=Mo.nextEffect))}for(Ln(yr),yr=null,Sn=!!hr,hr=null,e.current=t,Mo=r;null!==Mo;){l=!1,a=void 0;try{Vo(e,n)}catch(c){l=!0,a=c}l&&(null===Mo&&o("178"),qo(Mo,a),null!==Mo&&(Mo=Mo.nextEffect))}if(null!==r&&null!==Uo){var u=function(e,t){Fo=Do=Uo=null;var n=la;la=!0;do{if(512&t.effectTag){var r=!1,l=void 0;try{var i=t;mo(Ml,El,i),mo(El,Rl,i)}catch(u){r=!0,l=u}r&&qo(t,l)}t=t.nextEffect}while(null!==t);la=n,0!==(n=e.expirationTime)&&Ta(e,n),sa||la||Pa(1073741823,!1)}.bind(null,e,r);Do=i.unstable_runWithPriority(i.unstable_NormalPriority,function(){return wr(u)}),Fo=u}Co=Io=!1,"function"===typeof Wr&&Wr(t.stateNode),n=t.expirationTime,0===(t=(t=t.childExpirationTime)>n?t:n)&&(Lo=null),function(e,t){e.expirationTime=t,e.finishedWork=null}(e,t)}function $o(e){for(;;){var t=e.alternate,n=e.return,r=e.sibling;if(0===(1024&e.effectTag)){Po=e;e:{var i=t,a=Oo,u=(t=e).pendingProps;switch(t.tag){case 2:case 16:break;case 15:case 0:break;case 1:Ir(t.type)&&Ur();break;case 3:Tl(),Dr(),(u=t.stateNode).pendingContext&&(u.context=u.pendingContext,u.pendingContext=null),null!==i&&null!==i.child||(gi(t),t.effectTag&=-3),ao(t);break;case 5:_l(t);var c=wl(kl.current);if(a=t.type,null!==i&&null!=t.stateNode)uo(i,t,a,u,c),i.ref!==t.ref&&(t.effectTag|=128);else if(u){var s=wl(gl.current);if(gi(t)){i=(u=t).stateNode;var f=u.type,d=u.memoizedProps,p=c;switch(i[M]=u,i[I]=d,a=void 0,c=f){case"iframe":case"object":_n("load",i);break;case"video":case"audio":for(f=0;f<te.length;f++)_n(te[f],i);break;case"source":_n("error",i);break;case"img":case"image":case"link":_n("error",i),_n("load",i);break;case"form":_n("reset",i),_n("submit",i);break;case"details":_n("toggle",i);break;case"input":kt(i,d),_n("invalid",i),pr(p,"onChange");break;case"select":i._wrapperState={wasMultiple:!!d.multiple},_n("invalid",i),pr(p,"onChange");break;case"textarea":Xn(i,d),_n("invalid",i),pr(p,"onChange")}for(a in fr(c,d),f=null,d)d.hasOwnProperty(a)&&(s=d[a],"children"===a?"string"===typeof s?i.textContent!==s&&(f=["children",s]):"number"===typeof s&&i.textContent!==""+s&&(f=["children",""+s]):b.hasOwnProperty(a)&&null!=s&&pr(p,a));switch(c){case"input":Ve(i),Tt(i,d,!0);break;case"textarea":Ve(i),Jn(i);break;case"select":case"option":break;default:"function"===typeof d.onClick&&(i.onclick=mr)}a=f,u.updateQueue=a,(u=null!==a)&&io(t)}else{d=t,i=a,p=u,f=9===c.nodeType?c:c.ownerDocument,s===Zn.html&&(s=er(i)),s===Zn.html?"script"===i?((i=f.createElement("div")).innerHTML="<script><\/script>",f=i.removeChild(i.firstChild)):"string"===typeof p.is?f=f.createElement(i,{is:p.is}):(f=f.createElement(i),"select"===i&&p.multiple&&(f.multiple=!0)):f=f.createElementNS(s,i),(i=f)[M]=d,i[I]=u,oo(i,t,!1,!1),p=i;var m=c,h=dr(f=a,d=u);switch(f){case"iframe":case"object":_n("load",p),c=d;break;case"video":case"audio":for(c=0;c<te.length;c++)_n(te[c],p);c=d;break;case"source":_n("error",p),c=d;break;case"img":case"image":case"link":_n("error",p),_n("load",p),c=d;break;case"form":_n("reset",p),_n("submit",p),c=d;break;case"details":_n("toggle",p),c=d;break;case"input":kt(p,d),c=bt(p,d),_n("invalid",p),pr(m,"onChange");break;case"option":c=Kn(p,d);break;case"select":p._wrapperState={wasMultiple:!!d.multiple},c=l({},d,{value:void 0}),_n("invalid",p),pr(m,"onChange");break;case"textarea":Xn(p,d),c=Yn(p,d),_n("invalid",p),pr(m,"onChange");break;default:c=d}fr(f,c),s=void 0;var y=f,v=p,g=c;for(s in g)if(g.hasOwnProperty(s)){var k=g[s];"style"===s?cr(v,k):"dangerouslySetInnerHTML"===s?null!=(k=k?k.__html:void 0)&&lr(v,k):"children"===s?"string"===typeof k?("textarea"!==y||""!==k)&&ir(v,k):"number"===typeof k&&ir(v,""+k):"suppressContentEditableWarning"!==s&&"suppressHydrationWarning"!==s&&"autoFocus"!==s&&(b.hasOwnProperty(s)?null!=k&&pr(m,s):null!=k&&vt(v,s,k,h))}switch(f){case"input":Ve(p),Tt(p,d,!1);break;case"textarea":Ve(p),Jn(p);break;case"option":null!=d.value&&p.setAttribute("value",""+gt(d.value));break;case"select":(c=p).multiple=!!d.multiple,null!=(p=d.value)?qn(c,!!d.multiple,p,!1):null!=d.defaultValue&&qn(c,!!d.multiple,d.defaultValue,!0);break;default:"function"===typeof c.onClick&&(p.onclick=mr)}(u=vr(a,u))&&io(t),t.stateNode=i}null!==t.ref&&(t.effectTag|=128)}else null===t.stateNode&&o("166");break;case 6:i&&null!=t.stateNode?co(i,t,i.memoizedProps,u):("string"!==typeof u&&(null===t.stateNode&&o("166")),i=wl(kl.current),wl(gl.current),gi(t)?(a=(u=t).stateNode,i=u.memoizedProps,a[M]=u,(u=a.nodeValue!==i)&&io(t)):(a=t,(u=(9===i.nodeType?i:i.ownerDocument).createTextNode(u))[M]=t,a.stateNode=u));break;case 11:break;case 13:if(u=t.memoizedState,0!==(64&t.effectTag)){t.expirationTime=a,Po=t;break e}u=null!==u,a=null!==i&&null!==i.memoizedState,null!==i&&!u&&a&&(null!==(i=i.child.sibling)&&(null!==(c=t.firstEffect)?(t.firstEffect=i,i.nextEffect=c):(t.firstEffect=t.lastEffect=i,i.nextEffect=null),i.effectTag=8)),(u||a)&&(t.effectTag|=4);break;case 7:case 8:case 12:break;case 4:Tl(),ao(t);break;case 10:Ai(t);break;case 9:case 14:break;case 17:Ir(t.type)&&Ur();break;case 18:break;default:o("156")}Po=null}if(t=e,1===Oo||1!==t.childExpirationTime){for(u=0,a=t.child;null!==a;)(i=a.expirationTime)>u&&(u=i),(c=a.childExpirationTime)>u&&(u=c),a=a.sibling;t.childExpirationTime=u}if(null!==Po)return Po;null!==n&&0===(1024&n.effectTag)&&(null===n.firstEffect&&(n.firstEffect=e.firstEffect),null!==e.lastEffect&&(null!==n.lastEffect&&(n.lastEffect.nextEffect=e.firstEffect),n.lastEffect=e.lastEffect),1<e.effectTag&&(null!==n.lastEffect?n.lastEffect.nextEffect=e:n.firstEffect=e,n.lastEffect=e))}else{if(null!==(e=To(e)))return e.effectTag&=1023,e;null!==n&&(n.firstEffect=n.lastEffect=null,n.effectTag|=1024)}if(null!==r)return r;if(null===n)break;e=n}return null}function Qo(e){var t=Mi(e.alternate,e,Oo);return e.memoizedProps=e.pendingProps,null===t&&(t=$o(e)),_o.current=null,t}function Ko(e,t){Co&&o("243"),Bo(),Co=!0;var n=So.current;So.current=ui;var r=e.nextExpirationTimeToWorkOn;r===Oo&&e===No&&null!==Po||(Ao(),Oo=r,Po=Kr((No=e).current,null),e.pendingCommitExpirationTime=0);for(var l=!1;;){try{if(t)for(;null!==Po&&!Ea();)Po=Qo(Po);else for(;null!==Po;)Po=Qo(Po)}catch(v){if(Fi=Di=Ui=null,Gl(),null===Po)l=!0,Ra(v);else{null===Po&&o("271");var i=Po,a=i.return;if(null!==a){e:{var u=e,c=a,s=i,f=v;if(a=Oo,s.effectTag|=1024,s.firstEffect=s.lastEffect=null,null!==f&&"object"===typeof f&&"function"===typeof f.then){var d=f;f=c;var p=-1,m=-1;do{if(13===f.tag){var h=f.alternate;if(null!==h&&null!==(h=h.memoizedState)){m=10*(1073741822-h.timedOutAt);break}"number"===typeof(h=f.pendingProps.maxDuration)&&(0>=h?p=0:(-1===p||h<p)&&(p=h))}f=f.return}while(null!==f);f=c;do{if((h=13===f.tag)&&(h=void 0!==f.memoizedProps.fallback&&null===f.memoizedState),h){if(null===(c=f.updateQueue)?((c=new Set).add(d),f.updateQueue=c):c.add(d),0===(1&f.mode)){f.effectTag|=64,s.effectTag&=-1957,1===s.tag&&(null===s.alternate?s.tag=17:((a=Yi(1073741823)).tag=Hi,Gi(s,a))),s.expirationTime=1073741823;break e}c=a;var y=(s=u).pingCache;null===y?(y=s.pingCache=new ko,h=new Set,y.set(d,h)):void 0===(h=y.get(d))&&(h=new Set,y.set(d,h)),h.has(c)||(h.add(c),s=Xo.bind(null,s,d,c),d.then(s,s)),-1===p?u=1073741823:(-1===m&&(m=10*(1073741822-tl(u,a))-5e3),u=m+p),0<=u&&zo<u&&(zo=u),f.effectTag|=2048,f.expirationTime=a;break e}f=f.return}while(null!==f);f=Error((at(s.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display."+ut(s))}Ro=!0,f=lo(f,s),u=c;do{switch(u.tag){case 3:u.effectTag|=2048,u.expirationTime=a,Ji(u,a=wo(u,f,a));break e;case 1:if(p=f,m=u.type,s=u.stateNode,0===(64&u.effectTag)&&("function"===typeof m.getDerivedStateFromError||null!==s&&"function"===typeof s.componentDidCatch&&(null===Lo||!Lo.has(s)))){u.effectTag|=2048,u.expirationTime=a,Ji(u,a=xo(u,p,a));break e}}u=u.return}while(null!==u)}Po=$o(i);continue}l=!0,Ra(v)}}break}if(Co=!1,So.current=n,Fi=Di=Ui=null,Gl(),l)No=null,e.finishedWork=null;else if(null!==Po)e.finishedWork=null;else{if(null===(n=e.current.alternate)&&o("281"),No=null,Ro){if(l=e.latestPendingTime,i=e.latestSuspendedTime,a=e.latestPingedTime,0!==l&&l<r||0!==i&&i<r||0!==a&&a<r)return el(e,r),void wa(e,n,r,e.expirationTime,-1);if(!e.didError&&t)return e.didError=!0,r=e.nextExpirationTimeToWorkOn=r,t=e.expirationTime=1073741823,void wa(e,n,r,t,-1)}t&&-1!==zo?(el(e,r),(t=10*(1073741822-tl(e,r)))<zo&&(zo=t),t=10*(1073741822-xa()),t=zo-t,wa(e,n,r,e.expirationTime,0>t?0:t)):(e.pendingCommitExpirationTime=r,e.finishedWork=n)}}function qo(e,t){for(var n=e.return;null!==n;){switch(n.tag){case 1:var r=n.stateNode;if("function"===typeof n.type.getDerivedStateFromError||"function"===typeof r.componentDidCatch&&(null===Lo||!Lo.has(r)))return Gi(n,e=xo(n,e=lo(t,e),1073741823)),void Jo(n,1073741823);break;case 3:return Gi(n,e=wo(n,e=lo(t,e),1073741823)),void Jo(n,1073741823)}n=n.return}3===e.tag&&(Gi(e,n=wo(e,n=lo(t,e),1073741823)),Jo(e,1073741823))}function Yo(e,t){var n=i.unstable_getCurrentPriorityLevel(),r=void 0;if(0===(1&t.mode))r=1073741823;else if(Co&&!Io)r=Oo;else{switch(n){case i.unstable_ImmediatePriority:r=1073741823;break;case i.unstable_UserBlockingPriority:r=1073741822-10*(1+((1073741822-e+15)/10|0));break;case i.unstable_NormalPriority:r=1073741822-25*(1+((1073741822-e+500)/25|0));break;case i.unstable_LowPriority:case i.unstable_IdlePriority:r=1;break;default:o("313")}null!==No&&r===Oo&&--r}return n===i.unstable_UserBlockingPriority&&(0===aa||r<aa)&&(aa=r),r}function Xo(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),null!==No&&Oo===n?No=null:(t=e.earliestSuspendedTime,r=e.latestSuspendedTime,0!==t&&n<=t&&n>=r&&(e.didError=!1,(0===(t=e.latestPingedTime)||t>n)&&(e.latestPingedTime=n),nl(n,e),0!==(n=e.expirationTime)&&Ta(e,n)))}function Go(e,t){e.expirationTime<t&&(e.expirationTime=t);var n=e.alternate;null!==n&&n.expirationTime<t&&(n.expirationTime=t);var r=e.return,l=null;if(null===r&&3===e.tag)l=e.stateNode;else for(;null!==r;){if(n=r.alternate,r.childExpirationTime<t&&(r.childExpirationTime=t),null!==n&&n.childExpirationTime<t&&(n.childExpirationTime=t),null===r.return&&3===r.tag){l=r.stateNode;break}r=r.return}return l}function Jo(e,t){null!==(e=Go(e,t))&&(!Co&&0!==Oo&&t>Oo&&Ao(),Zr(e,t),Co&&!Io&&No===e||Ta(e,e.expirationTime),va>ya&&(va=0,o("185")))}function Zo(e,t,n,r,l){return i.unstable_runWithPriority(i.unstable_ImmediatePriority,function(){return e(t,n,r,l)})}var ea=null,ta=null,na=0,ra=void 0,la=!1,ia=null,oa=0,aa=0,ua=!1,ca=null,sa=!1,fa=!1,da=null,pa=i.unstable_now(),ma=1073741822-(pa/10|0),ha=ma,ya=50,va=0,ga=null;function ba(){ma=1073741822-((i.unstable_now()-pa)/10|0)}function ka(e,t){if(0!==na){if(t<na)return;null!==ra&&i.unstable_cancelCallback(ra)}na=t,e=i.unstable_now()-pa,ra=i.unstable_scheduleCallback(Ca,{timeout:10*(1073741822-t)-e})}function wa(e,t,n,r,l){e.expirationTime=r,0!==l||Ea()?0<l&&(e.timeoutHandle=br(function(e,t,n){e.pendingCommitExpirationTime=n,e.finishedWork=t,ba(),ha=ma,Na(e,n)}.bind(null,e,t,n),l)):(e.pendingCommitExpirationTime=n,e.finishedWork=t)}function xa(){return la?ha:(Sa(),0!==oa&&1!==oa||(ba(),ha=ma),ha)}function Ta(e,t){null===e.nextScheduledRoot?(e.expirationTime=t,null===ta?(ea=ta=e,e.nextScheduledRoot=e):(ta=ta.nextScheduledRoot=e).nextScheduledRoot=ea):t>e.expirationTime&&(e.expirationTime=t),la||(sa?fa&&(ia=e,oa=1073741823,Oa(e,1073741823,!1)):1073741823===t?Pa(1073741823,!1):ka(e,t))}function Sa(){var e=0,t=null;if(null!==ta)for(var n=ta,r=ea;null!==r;){var l=r.expirationTime;if(0===l){if((null===n||null===ta)&&o("244"),r===r.nextScheduledRoot){ea=ta=r.nextScheduledRoot=null;break}if(r===ea)ea=l=r.nextScheduledRoot,ta.nextScheduledRoot=l,r.nextScheduledRoot=null;else{if(r===ta){(ta=n).nextScheduledRoot=ea,r.nextScheduledRoot=null;break}n.nextScheduledRoot=r.nextScheduledRoot,r.nextScheduledRoot=null}r=n.nextScheduledRoot}else{if(l>e&&(e=l,t=r),r===ta)break;if(1073741823===e)break;n=r,r=r.nextScheduledRoot}}ia=t,oa=e}var _a=!1;function Ea(){return!!_a||!!i.unstable_shouldYield()&&(_a=!0)}function Ca(){try{if(!Ea()&&null!==ea){ba();var e=ea;do{var t=e.expirationTime;0!==t&&ma<=t&&(e.nextExpirationTimeToWorkOn=ma),e=e.nextScheduledRoot}while(e!==ea)}Pa(0,!0)}finally{_a=!1}}function Pa(e,t){if(Sa(),t)for(ba(),ha=ma;null!==ia&&0!==oa&&e<=oa&&!(_a&&ma>oa);)Oa(ia,oa,ma>oa),Sa(),ba(),ha=ma;else for(;null!==ia&&0!==oa&&e<=oa;)Oa(ia,oa,!1),Sa();if(t&&(na=0,ra=null),0!==oa&&ka(ia,oa),va=0,ga=null,null!==da)for(e=da,da=null,t=0;t<e.length;t++){var n=e[t];try{n._onComplete()}catch(r){ua||(ua=!0,ca=r)}}if(ua)throw e=ca,ca=null,ua=!1,e}function Na(e,t){la&&o("253"),ia=e,oa=t,Oa(e,t,!1),Pa(1073741823,!1)}function Oa(e,t,n){if(la&&o("245"),la=!0,n){var r=e.finishedWork;null!==r?za(e,r,t):(e.finishedWork=null,-1!==(r=e.timeoutHandle)&&(e.timeoutHandle=-1,kr(r)),Ko(e,n),null!==(r=e.finishedWork)&&(Ea()?e.finishedWork=r:za(e,r,t)))}else null!==(r=e.finishedWork)?za(e,r,t):(e.finishedWork=null,-1!==(r=e.timeoutHandle)&&(e.timeoutHandle=-1,kr(r)),Ko(e,n),null!==(r=e.finishedWork)&&za(e,r,t));la=!1}function za(e,t,n){var r=e.firstBatch;if(null!==r&&r._expirationTime>=n&&(null===da?da=[r]:da.push(r),r._defer))return e.finishedWork=t,void(e.expirationTime=0);e.finishedWork=null,e===ga?va++:(ga=e,va=0),i.unstable_runWithPriority(i.unstable_ImmediatePriority,function(){Ho(e,t)})}function Ra(e){null===ia&&o("246"),ia.expirationTime=0,ua||(ua=!0,ca=e)}function Ma(e,t){var n=sa;sa=!0;try{return e(t)}finally{(sa=n)||la||Pa(1073741823,!1)}}function Ia(e,t){if(sa&&!fa){fa=!0;try{return e(t)}finally{fa=!1}}return e(t)}function Ua(e,t,n){sa||la||0===aa||(Pa(aa,!1),aa=0);var r=sa;sa=!0;try{return i.unstable_runWithPriority(i.unstable_UserBlockingPriority,function(){return e(t,n)})}finally{(sa=r)||la||Pa(1073741823,!1)}}function Da(e,t,n,r,l){var i=t.current;e:if(n){t:{2===tn(n=n._reactInternalFiber)&&1===n.tag||o("170");var a=n;do{switch(a.tag){case 3:a=a.stateNode.context;break t;case 1:if(Ir(a.type)){a=a.stateNode.__reactInternalMemoizedMergedChildContext;break t}}a=a.return}while(null!==a);o("171"),a=void 0}if(1===n.tag){var u=n.type;if(Ir(u)){n=Lr(n,u,a);break e}}n=a}else n=Nr;return null===t.context?t.context=n:t.pendingContext=n,t=l,(l=Yi(r)).payload={element:e},null!==(t=void 0===t?null:t)&&(l.callback=t),Bo(),Gi(i,l),Jo(i,r),r}function Fa(e,t,n,r){var l=t.current;return Da(e,t,n,l=Yo(xa(),l),r)}function La(e){if(!(e=e.current).child)return null;switch(e.child.tag){case 5:default:return e.child.stateNode}}function Aa(e){var t=1073741822-25*(1+((1073741822-xa()+500)/25|0));t>=Eo&&(t=Eo-1),this._expirationTime=Eo=t,this._root=e,this._callbacks=this._next=null,this._hasChildren=this._didComplete=!1,this._children=null,this._defer=!0}function ja(){this._callbacks=null,this._didCommit=!1,this._onCommit=this._onCommit.bind(this)}function Wa(e,t,n){e={current:t=$r(3,null,null,t?3:0),containerInfo:e,pendingChildren:null,pingCache:null,earliestPendingTime:0,latestPendingTime:0,earliestSuspendedTime:0,latestSuspendedTime:0,latestPingedTime:0,didError:!1,pendingCommitExpirationTime:0,finishedWork:null,timeoutHandle:-1,context:null,pendingContext:null,hydrate:n,nextExpirationTimeToWorkOn:0,expirationTime:0,firstBatch:null,nextScheduledRoot:null},this._internalRoot=t.stateNode=e}function Va(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Ba(e,t,n,r,l){var i=n._reactRootContainer;if(i){if("function"===typeof l){var o=l;l=function(){var e=La(i._internalRoot);o.call(e)}}null!=e?i.legacy_renderSubtreeIntoContainer(e,t,l):i.render(t,l)}else{if(i=n._reactRootContainer=function(e,t){if(t||(t=!(!(t=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var n;n=e.lastChild;)e.removeChild(n);return new Wa(e,!1,t)}(n,r),"function"===typeof l){var a=l;l=function(){var e=La(i._internalRoot);a.call(e)}}Ia(function(){null!=e?i.legacy_renderSubtreeIntoContainer(e,t,l):i.render(t,l)})}return La(i._internalRoot)}function Ha(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;return Va(t)||o("200"),function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:qe,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)}Ee=function(e,t,n){switch(t){case"input":if(xt(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var l=L(r);l||o("90"),Be(r),xt(r,l)}}}break;case"textarea":Gn(e,n);break;case"select":null!=(t=n.value)&&qn(e,!!n.multiple,t,!1)}},Aa.prototype.render=function(e){this._defer||o("250"),this._hasChildren=!0,this._children=e;var t=this._root._internalRoot,n=this._expirationTime,r=new ja;return Da(e,t,null,n,r._onCommit),r},Aa.prototype.then=function(e){if(this._didComplete)e();else{var t=this._callbacks;null===t&&(t=this._callbacks=[]),t.push(e)}},Aa.prototype.commit=function(){var e=this._root._internalRoot,t=e.firstBatch;if(this._defer&&null!==t||o("251"),this._hasChildren){var n=this._expirationTime;if(t!==this){this._hasChildren&&(n=this._expirationTime=t._expirationTime,this.render(this._children));for(var r=null,l=t;l!==this;)r=l,l=l._next;null===r&&o("251"),r._next=l._next,this._next=t,e.firstBatch=this}this._defer=!1,Na(e,n),t=this._next,this._next=null,null!==(t=e.firstBatch=t)&&t._hasChildren&&t.render(t._children)}else this._next=null,this._defer=!1},Aa.prototype._onComplete=function(){if(!this._didComplete){this._didComplete=!0;var e=this._callbacks;if(null!==e)for(var t=0;t<e.length;t++)(0,e[t])()}},ja.prototype.then=function(e){if(this._didCommit)e();else{var t=this._callbacks;null===t&&(t=this._callbacks=[]),t.push(e)}},ja.prototype._onCommit=function(){if(!this._didCommit){this._didCommit=!0;var e=this._callbacks;if(null!==e)for(var t=0;t<e.length;t++){var n=e[t];"function"!==typeof n&&o("191",n),n()}}},Wa.prototype.render=function(e,t){var n=this._internalRoot,r=new ja;return null!==(t=void 0===t?null:t)&&r.then(t),Fa(e,n,null,r._onCommit),r},Wa.prototype.unmount=function(e){var t=this._internalRoot,n=new ja;return null!==(e=void 0===e?null:e)&&n.then(e),Fa(null,t,null,n._onCommit),n},Wa.prototype.legacy_renderSubtreeIntoContainer=function(e,t,n){var r=this._internalRoot,l=new ja;return null!==(n=void 0===n?null:n)&&l.then(n),Fa(t,r,e,l._onCommit),l},Wa.prototype.createBatch=function(){var e=new Aa(this),t=e._expirationTime,n=this._internalRoot,r=n.firstBatch;if(null===r)n.firstBatch=e,e._next=null;else{for(n=null;null!==r&&r._expirationTime>=t;)n=r,r=r._next;e._next=r,null!==n&&(n._next=e)}return e},Re=Ma,Me=Ua,Ie=function(){la||0===aa||(Pa(aa,!1),aa=0)};var $a={createPortal:Ha,findDOMNode:function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternalFiber;return void 0===t&&("function"===typeof e.render?o("188"):o("268",Object.keys(e))),e=null===(e=rn(t))?null:e.stateNode},hydrate:function(e,t,n){return Va(t)||o("200"),Ba(null,e,t,!0,n)},render:function(e,t,n){return Va(t)||o("200"),Ba(null,e,t,!1,n)},unstable_renderSubtreeIntoContainer:function(e,t,n,r){return Va(n)||o("200"),(null==e||void 0===e._reactInternalFiber)&&o("38"),Ba(e,t,n,!1,r)},unmountComponentAtNode:function(e){return Va(e)||o("40"),!!e._reactRootContainer&&(Ia(function(){Ba(null,null,e,!1,function(){e._reactRootContainer=null})}),!0)},unstable_createPortal:function(){return Ha.apply(void 0,arguments)},unstable_batchedUpdates:Ma,unstable_interactiveUpdates:Ua,flushSync:function(e,t){la&&o("187");var n=sa;sa=!0;try{return Zo(e,t)}finally{sa=n,Pa(1073741823,!1)}},unstable_createRoot:function(e,t){return Va(e)||o("299","unstable_createRoot"),new Wa(e,!0,null!=t&&!0===t.hydrate)},unstable_flushControlled:function(e){var t=sa;sa=!0;try{Zo(e)}finally{(sa=t)||la||Pa(1073741823,!1)}},__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{Events:[D,F,L,N.injectEventPluginsByName,g,H,function(e){E(e,B)},Oe,ze,Pn,z]}};!function(e){var t=e.findFiberByHostInstance;(function(e){if("undefined"===typeof __REACT_DEVTOOLS_GLOBAL_HOOK__)return!1;var t=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(t.isDisabled||!t.supportsFiber)return!0;try{var n=t.inject(e);Wr=Br(function(e){return t.onCommitFiberRoot(n,e)}),Vr=Br(function(e){return t.onCommitFiberUnmount(n,e)})}catch(r){}})(l({},e,{overrideProps:null,currentDispatcherRef:He.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=rn(e))?null:e.stateNode},findFiberByHostInstance:function(e){return t?t(e):null}}))}({findFiberByHostInstance:U,bundleType:0,version:"16.8.2",rendererPackageName:"react-dom"});var Qa={default:$a},Ka=Qa&&$a||Qa;e.exports=Ka.default||Ka},function(e,t,n){"use strict";e.exports=n(14)},function(e,t,n){"use strict";(function(e){Object.defineProperty(t,"__esModule",{value:!0});var n=null,r=!1,l=3,i=-1,o=-1,a=!1,u=!1;function c(){if(!a){var e=n.expirationTime;u?T():u=!0,x(d,e)}}function s(){var e=n,t=n.next;if(n===t)n=null;else{var r=n.previous;n=r.next=t,t.previous=r}e.next=e.previous=null,r=e.callback,t=e.expirationTime,e=e.priorityLevel;var i=l,a=o;l=e,o=t;try{var u=r()}finally{l=i,o=a}if("function"===typeof u)if(u={callback:u,priorityLevel:e,expirationTime:t,next:null,previous:null},null===n)n=u.next=u.previous=u;else{r=null,e=n;do{if(e.expirationTime>=t){r=e;break}e=e.next}while(e!==n);null===r?r=n:r===n&&(n=u,c()),(t=r.previous).next=r.previous=u,u.next=r,u.previous=t}}function f(){if(-1===i&&null!==n&&1===n.priorityLevel){a=!0;try{do{s()}while(null!==n&&1===n.priorityLevel)}finally{a=!1,null!==n?c():u=!1}}}function d(e){a=!0;var l=r;r=e;try{if(e)for(;null!==n;){var i=t.unstable_now();if(!(n.expirationTime<=i))break;do{s()}while(null!==n&&n.expirationTime<=i)}else if(null!==n)do{s()}while(null!==n&&!S())}finally{a=!1,r=l,null!==n?c():u=!1,f()}}var p,m,h=Date,y="function"===typeof setTimeout?setTimeout:void 0,v="function"===typeof clearTimeout?clearTimeout:void 0,g="function"===typeof requestAnimationFrame?requestAnimationFrame:void 0,b="function"===typeof cancelAnimationFrame?cancelAnimationFrame:void 0;function k(e){p=g(function(t){v(m),e(t)}),m=y(function(){b(p),e(t.unstable_now())},100)}if("object"===typeof performance&&"function"===typeof performance.now){var w=performance;t.unstable_now=function(){return w.now()}}else t.unstable_now=function(){return h.now()};var x,T,S,_=null;if("undefined"!==typeof window?_=window:"undefined"!==typeof e&&(_=e),_&&_._schedMock){var E=_._schedMock;x=E[0],T=E[1],S=E[2],t.unstable_now=E[3]}else if("undefined"===typeof window||"function"!==typeof MessageChannel){var C=null,P=function(e){if(null!==C)try{C(e)}finally{C=null}};x=function(e){null!==C?setTimeout(x,0,e):(C=e,setTimeout(P,0,!1))},T=function(){C=null},S=function(){return!1}}else{"undefined"!==typeof console&&("function"!==typeof g&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"),"function"!==typeof b&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://fb.me/react-polyfills"));var N=null,O=!1,z=-1,R=!1,M=!1,I=0,U=33,D=33;S=function(){return I<=t.unstable_now()};var F=new MessageChannel,L=F.port2;F.port1.onmessage=function(){O=!1;var e=N,n=z;N=null,z=-1;var r=t.unstable_now(),l=!1;if(0>=I-r){if(!(-1!==n&&n<=r))return R||(R=!0,k(A)),N=e,void(z=n);l=!0}if(null!==e){M=!0;try{e(l)}finally{M=!1}}};var A=function e(t){if(null!==N){k(e);var n=t-I+D;n<D&&U<D?(8>n&&(n=8),D=n<U?U:n):U=n,I=t+D,O||(O=!0,L.postMessage(void 0))}else R=!1};x=function(e,t){N=e,z=t,M||0>t?L.postMessage(void 0):R||(R=!0,k(A))},T=function(){N=null,O=!1,z=-1}}t.unstable_ImmediatePriority=1,t.unstable_UserBlockingPriority=2,t.unstable_NormalPriority=3,t.unstable_IdlePriority=5,t.unstable_LowPriority=4,t.unstable_runWithPriority=function(e,n){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var r=l,o=i;l=e,i=t.unstable_now();try{return n()}finally{l=r,i=o,f()}},t.unstable_next=function(e){switch(l){case 1:case 2:case 3:var n=3;break;default:n=l}var r=l,o=i;l=n,i=t.unstable_now();try{return e()}finally{l=r,i=o,f()}},t.unstable_scheduleCallback=function(e,r){var o=-1!==i?i:t.unstable_now();if("object"===typeof r&&null!==r&&"number"===typeof r.timeout)r=o+r.timeout;else switch(l){case 1:r=o+-1;break;case 2:r=o+250;break;case 5:r=o+1073741823;break;case 4:r=o+1e4;break;default:r=o+5e3}if(e={callback:e,priorityLevel:l,expirationTime:r,next:null,previous:null},null===n)n=e.next=e.previous=e,c();else{o=null;var a=n;do{if(a.expirationTime>r){o=a;break}a=a.next}while(a!==n);null===o?o=n:o===n&&(n=e,c()),(r=o.previous).next=o.previous=e,e.next=o,e.previous=r}return e},t.unstable_cancelCallback=function(e){var t=e.next;if(null!==t){if(t===e)n=null;else{e===n&&(n=t);var r=e.previous;r.next=t,t.previous=r}e.next=e.previous=null}},t.unstable_wrapCallback=function(e){var n=l;return function(){var r=l,o=i;l=n,i=t.unstable_now();try{return e.apply(this,arguments)}finally{l=r,i=o,f()}}},t.unstable_getCurrentPriorityLevel=function(){return l},t.unstable_shouldYield=function(){return!r&&(null!==n&&n.expirationTime<o||S())},t.unstable_continueExecution=function(){null!==n&&c()},t.unstable_pauseExecution=function(){},t.unstable_getFirstCallbackNode=function(){return n}}).call(this,n(15))},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(r){"object"===typeof window&&(n=window)}e.exports=n}]]);
+//# sourceMappingURL=2.772a56e7.chunk.js.map
diff --git a/viewer/build/static/js/main.db22f45d.chunk.js b/viewer/build/static/js/main.db22f45d.chunk.js
new file mode 100644
--- /dev/null
+++ b/viewer/build/static/js/main.db22f45d.chunk.js
@@ -0,0 +1,2 @@
+(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{10:function(e,n,t){e.exports=t(18)},16:function(e,n,t){},17:function(e,n,t){},18:function(e,n,t){"use strict";t.r(n);var s=t(0),a=t.n(s),o=t(4),r=t.n(o),i=(t(16),t(2)),c=t(5),l=t(6),m=t(9),g=t(7),u=t(1),d=t(8),v=(t(17),function(e){function n(e){var t;Object(c.a)(this,n),(t=Object(m.a)(this,Object(g.a)(n).call(this,e))).connect=function(){var e=new WebSocket("ws://localhost:9161");e.onopen=function(n){t.setState(function(e){return Object(i.a)({},e,{message:"Connected."})}),e.send("60")},e.onclose=function(e){t.setState(function(e){return Object(i.a)({},e,{message:"Disconnected."})}),setTimeout(t.connect,1e3)},e.onmessage=function(e){if("Success!"===e.data)console.log("Success");else if("Compiling"===e.data)t.setState({message:"Compiling..."});else if("Rendering"===e.data)t.setState({message:"Rendering..."}),t.nFrames_new=0,t.svgs_new=[];else if("Done"===e.data)t.setState({message:""}),console.log("Done"),t.nFrames=t.nFrames_new,t.svgs=t.svgs_new,t.nFrames_new=0,t.svgs_new=[],t.start=Date.now();else if(e.data.startsWith("Error"))console.log("Error"),t.setState({message:e.data.substring(5)});else{t.setState({message:"Rendering: ".concat(t.nFrames_new)}),t.nFrames_new++;var n=document.createElement("div");n.innerHTML=e.data,t.svgs_new.push(n)}},t.setState(function(n){return Object(i.a)({},n,{socket:e,message:"Connecting..."})})},t.onLoad=function(e){setTimeout(function(){e.resize()},0)},t.state={},setTimeout(t.connect,0),t.nFrames_new=0,t.svgs_new=[],t.nFrames=0,t.svgs=[],t.start=Date.now();var s=Object(u.a)(t);return requestAnimationFrame(function e(){var n=Date.now(),a=s.nFrames,o=Math.round((n-t.start)/1e3*60)%a;if(s.svgs_new.length){for(;s.svg.firstChild;)s.svg.removeChild(s.svg.firstChild);s.svg.appendChild(s.svgs_new[s.svgs_new.length-1])}else if(a){for(;s.svg.firstChild;)s.svg.removeChild(s.svg.firstChild);s.svg.appendChild(s.svgs[o])}else s.svg.innerText="";requestAnimationFrame(e)}),t}return Object(d.a)(n,e),Object(l.a)(n,[{key:"render",value:function(){var e=this,n=this.state.message;return a.a.createElement("div",{className:"App"},a.a.createElement("div",{className:"viewer"},a.a.createElement("div",{ref:function(n){return e.svg=n}}),a.a.createElement("div",{className:"messages"},a.a.createElement("pre",null,n))))}}]),n}(s.Component));Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));r.a.render(a.a.createElement(v,null),document.getElementById("root")),"serviceWorker"in navigator&&navigator.serviceWorker.ready.then(function(e){e.unregister()})}},[[10,1,2]]]);
+//# sourceMappingURL=main.db22f45d.chunk.js.map
diff --git a/viewer/build/static/js/runtime~main.9eb600ee.js b/viewer/build/static/js/runtime~main.9eb600ee.js
new file mode 100644
--- /dev/null
+++ b/viewer/build/static/js/runtime~main.9eb600ee.js
@@ -0,0 +1,2 @@
+!function(e){function r(r){for(var n,f,i=r[0],l=r[1],a=r[2],c=0,s=[];c<i.length;c++)f=i[c],o[f]&&s.push(o[f][0]),o[f]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,a||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var l=t[i];0!==o[l]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="./";var i=window.webpackJsonp=window.webpackJsonp||[],l=i.push.bind(i);i.push=r,i=i.slice();for(var a=0;a<i.length;a++)r(i[a]);var p=l;t()}([]);
+//# sourceMappingURL=runtime~main.9eb600ee.js.map
