packages feed

axiom 0.4.6 → 0.4.7

raw patch · 4 files changed

+483/−302 lines, 4 filesdep ~transientdep ~transient-universePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: transient, transient-universe

API changes (from Hackage documentation)

- GHCJS.HPlay.View: attrs :: FormInput view => view -> Attribs -> view
- GHCJS.HPlay.View: class (Monoid view, Typeable view) => FormInput view where flink1 verb = flink verb (fromStr verb) foption1 val msel = foption val (fromStr val) msel
- GHCJS.HPlay.View: data CheckBoxes a
- GHCJS.HPlay.View: finput :: FormInput view => Name -> Type -> Value -> Checked -> OnClick1 -> view
- GHCJS.HPlay.View: flink :: FormInput view => JSString -> view -> view
- GHCJS.HPlay.View: flink1 :: FormInput view => JSString -> view
- GHCJS.HPlay.View: foption :: FormInput view => JSString -> view -> Bool -> view
- GHCJS.HPlay.View: foption1 :: FormInput view => JSString -> Bool -> view
- GHCJS.HPlay.View: formAction :: FormInput view => JSString -> JSString -> view -> view
- GHCJS.HPlay.View: fromStr :: FormInput view => JSString -> view
- GHCJS.HPlay.View: fromStrNoEncode :: FormInput view => String -> view
- GHCJS.HPlay.View: fselect :: FormInput view => JSString -> view -> view
- GHCJS.HPlay.View: ftag :: FormInput view => JSString -> view -> view
- GHCJS.HPlay.View: ftextarea :: FormInput view => JSString -> JSString -> view
- GHCJS.HPlay.View: inred :: FormInput view => view -> view
- GHCJS.HPlay.View: instance GHC.Base.Monoid a => GHC.Base.Monoid (GHCJS.HPlay.View.Radio a)
- GHCJS.HPlay.View: instance GHC.Classes.Eq GHCJS.HPlay.View.AlternativeBranch
- GHCJS.HPlay.View: instance GHC.Show.Show GHCJS.HPlay.View.AlternativeBranch
- GHCJS.HPlay.View: instance GHC.Show.Show GHCJS.HPlay.View.IDNUM
- GHCJS.HPlay.View: instance GHC.Show.Show GHCJS.HPlay.View.NeedForm
- GHCJS.HPlay.View: instance GHC.Show.Show a => GHC.Show.Show (GHCJS.HPlay.View.CheckBoxes a)
- GHCJS.HPlay.View: instance GHCJS.HPlay.View.FormInput Internal.Perch.Perch
+ GHCJS.HPlay.View: Radio :: a -> Radio a
+ GHCJS.HPlay.View: RadioId :: JSString -> RadioId
+ GHCJS.HPlay.View: data RadioId
+ GHCJS.HPlay.View: newtype CheckBoxes a
+ GHCJS.HPlay.View: newtype Radio a
+ GHCJS.HPlay.View: pack :: () => a
+ GHCJS.HPlay.View: type JSString = String
+ GHCJS.HPlay.View: unpack :: () => a
- GHCJS.HPlay.Cell: calc :: Widget ()
+ GHCJS.HPlay.Cell: calc :: Cloud ()
- GHCJS.HPlay.Cell: gcell :: JSString -> Widget Double
+ GHCJS.HPlay.Cell: gcell :: JSString -> Cloud Double
- GHCJS.HPlay.Cell: get :: Cell a -> TransIO a
+ GHCJS.HPlay.Cell: get :: () => Cell a -> TransIO a
- GHCJS.HPlay.Cell: mkscell :: JSString -> Maybe Double -> Expr Double -> Widget Double
+ GHCJS.HPlay.Cell: mkscell :: JSString -> Expr Double -> Cloud (Cell Double)
- GHCJS.HPlay.View: (<!) :: Widget a -> Attribs -> Widget a
+ GHCJS.HPlay.View: (<!) :: () => Widget a -> [(PropId, JSString)] -> Widget a
- GHCJS.HPlay.View: alert :: JSString -> IO ()
+ GHCJS.HPlay.View: alert :: (Show a, MonadIO m) => a -> m ()
- GHCJS.HPlay.View: edit :: Cloud a -> Cloud a
+ GHCJS.HPlay.View: edit :: () => Cloud a -> Cloud a
- GHCJS.HPlay.View: getRadio :: Monoid a => [Widget (Radio a)] -> Widget a
+ GHCJS.HPlay.View: getRadio :: [Widget (Radio a)] -> Widget a
- GHCJS.HPlay.View: runCont :: EventF -> StateIO (Maybe a)
+ GHCJS.HPlay.View: runCont :: () => EventF -> StateIO Maybe a
- GHCJS.HPlay.View: setRadio :: (Typeable a, Eq a, Show a) => a -> Widget (Radio a)
+ GHCJS.HPlay.View: setRadio :: (Typeable a, Eq a, Show a, Read a) => Bool -> a -> Widget (Radio a)
- GHCJS.HPlay.View: setRadioActive :: (Typeable a, Eq a, Show a) => a -> Widget (Radio a)
+ GHCJS.HPlay.View: setRadioActive :: (Typeable a, Eq a, Show a, Read a) => Bool -> a -> Widget (Radio a)
- GHCJS.HPlay.View: staticNav :: TransIO b -> TransIO b
+ GHCJS.HPlay.View: staticNav :: () => TransIO b -> TransIO b

Files

README.md view
@@ -1,14 +1,14 @@ ![Axiom logo](axiom.png)
 ==========
-[![Hackage](https://img.shields.io/hackage/v/ghcjs-hplay.svg)](http://hackage.haskell.org/package/ghcjs-hplay)
-[![Stackage LTS](http://stackage.org/package/ghcjs-hplay/badge/lts)](http://stackage.org/lts/package/ghcjs-hplay)
-[![Stackage Nightly](http://stackage.org/package/ghcjs-hplay/badge/nightly)](http://stackage.org/nightly/package/ghcjs-hplay)
+[![Hackage](https://img.shields.io/hackage/v/axiom.svg)](http://hackage.haskell.org/package/axiom)
+[![Stackage LTS](http://stackage.org/package/axiom/badge/lts)](http://stackage.org/lts/package/axiom)
+[![Stackage Nightly](http://stackage.org/package/axiom/badge/nightly)](http://stackage.org/nightly/package/axiom)
 [![Build Status](https://travis-ci.org/transient-haskell/axiom.png?branch=master)](https://travis-ci.org/transient-haskell/axiom)
 
 
 For some examples, see the [transient-examples](https://github.com/transient-haskell/transient-examples) repository: [distributedApps.hs](https://github.com/transient-haskell/transient-examples/blob/master/distributedApps.hs) and      [webapp.hs](https://github.com/transient-haskell/transient-examples/blob/master/webapp.hs)
 
-The source code can be executed in the commmand line if you have docker installed.
+The source code of these applications can be executed in the commmand line if you have docker installed.
 
 [![Gitter](https://badges.gitter.im/theam/haskell-do.svg)](https://gitter.im/Transient-Transient-Universe-HPlay/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link)
 
@@ -26,7 +26,7 @@ ============
 The JS program compiled with GHCJS is sent to the browser, then it opens a websockets connection. Then  the most useful primitive is `atRemote` wich execute his argument in the server and return the result back to the client  (or viceversa, see below). The communication transport the variables necessary for executing the computation remotely. There is no explicit serialization neither communication. All is done implicitly.
 
-`atRemote` can be executed inside itself, so a computation can jump from server to client and back. So a browser can be controlled by the server or the other way aroud. But the execution starts in the browser. There is very little data to transport to execute remotely.  In the other side, streaming  and reactivity in both directions is included with no additional considerations with `atRemote` and other primitives. Isn't awesome?
+`atRemote` can be executed inside itself, so a computation can jump from server to client and back. So a browser can be controlled by the server or the other way aroud. But the execution starts in the browser. Only the variable values already computed are transported to execute remotely.  In the other side, streaming  and reactivity in both directions is included since `atRemote` and other primitives are reactive (see the [transient tutorial](https://github.com/transient-haskell/transient/wiki/Transient-tutorial)).
 
 In the other side, there is an experimental template editor to generate static HTML templates. The server can execute a rest route and bring the corresponding page template and the JS code to the browser, so web crawlers can find something to read.
 Also in Axiom everithing compose algebraically with standard applicative, alternative and monoidal operators, and  also monadically:  
@@ -35,13 +35,156 @@ 
 Events do not bubble up to the top like in the case of React. An event within a widget produce a monadic response that executes widgets down trough the monad without affecting the surrounding rendering not affected by the event. That is why Axiom does not need a Virtual DOM, and the logic of the application and the execution flow match, so it produces a clean and understandable code. look at the TODO app (it is client-side only)
 
-tryplayg.herokuapp.com/try/todo.hs/edit
+http://tryplayg.herokuapp.com/try/todo.hs/edit
 
 Axiom also implement widgets that works as spreadsheet cells, with formulas depending on other cells. These formulas can be executed in the server, so they have full access to databases, mumber crunching, map-reduce etc. This functionality need some testing.
 
+How to install & run fast
+=========================
+use `initNode` to initalize the application. Example below.
+   
+
+If you have docker
+------------------
+You can use a docker image that has GHC, GHCJS and Transient installed. First you should create this executable shell with this content and save it to an executable location:
+```
+$ cat execthirdline.sh
+command=`sed -n '3p' ${1} | sed 's/-- //'`
+eval $command $1 $2 $3
+```
+Then add this to the head of your main source file:
+
+```csh
+#!/usr/bin/env ./execthirdline.sh
+-- compile an Axiom program with ghcjs and execute it with runghc
+-- set -e && port=`echo ${3} | awk -F/ '{print $(3)}'` && docker run -it -p ${port}:${port} -v $(pwd):/work agocorona/transient:24-03-2017  bash -c "cd work && mkdir -p ./static && ghcjs ${1} -o static/out && runghc ${1} ${2} ${3}"
+```
+
+That header compiles the program with GHCJS and write the javascript code generated to the "static" folder and then executes the server program in interpreted mode with `runghc`. This is useful for rapid development, since you can modify the code and re-execute it very fast.
+
+To fully compile and execute the program, you can susbstitute `runghc` by `ghc` and execute the binary. The header would look like:
+
+```csh
+#!/usr/bin/env ./execthirdline.sh
+-- compile an Axiom program with ghcjs and with ghc, then execute the program
+-- set -e && port=`echo ${3} | awk -F/ '{print $(3)}'` && docker run -it -p ${port}:${port} -v $(pwd):/work agocorona/transient:24-03-2017  bash -c "cd work && mkdir -p ./static && ghcjs ${1} -o static/out && ghc ${1}  -o program && chmod 777 program && ./program ${2} ${3}"
+```
+That header, besides executing the application, it would also create a "program"  executable in your host machine  (as well as an "static" folder with files needed for the client-side application. You can execute it natively in a linux distro in the way it will be described below.
+
+More complicated projects can be compiled and executed using `cabal` and `stack`. You can modify the header accordingly.
+
+For example, this is a program that is directly executable with docker
+
+```haskell
+#!/usr/bin/env ./execthirdline.sh
+-- compile it with ghcjs and  execute it with runghc
+-- set -e && port=`echo ${3} | awk -F/ '{print $(3)}'` && docker run -it -p ${port}:${port} -v $(pwd):/work agocorona/transient:24-03-2017  bash -c "cd work && mkdir -p ./static && ghcjs ${1} -o static/out && runghc ${1}  ${2} ${3}"
+
+import Prelude hiding (div, id, span)
+import Transient.Base
+import GHCJS.HPlay.View
+import Transient.Move
+import Transient.Indeterminism
+import Data.IORef
+import Control.Concurrent (threadDelay)
+import Control.Monad.IO.Class
+import Data.Monoid
+
+main= keep . initNode . onBrowser $ do 
+    local . render $  wlink () (h1 "hello fibonacci numbers")
+    
+    r <-  atRemote $ do
+                r <- local . threads 1 . choose $ take 10 fibs
+                localIO $ print r
+                localIO $ threadDelay 1000000
+                return r
+    
+    local . render . rawHtml $ (h2 r)
+    where
+    fibs = 0 : 1 : zipWith (+) fibs (tail fibs) :: [Int]  -- fibonacci numb. definition
+```
+
+To execute the program:
+```
+> chmod 777 YourSource.hs
+> ./YourSource.hs -p start/<host>/<port>
+```
+
+where <host> <port>  are defined by you. for example `./YourSource.hs -p start/localhost/8080`
+
+The program will be accessed from outside docker as a web application. Read the documentation of Docker for your platform about how to invoke it.
+
+If you want to run it in a host Linux machine, you can generate the browser code and the executable from docker in the way described above. Then in in the host you can execute it:
+
+```
+> ./program - p start/localhost/8080
+```
+
+If you want to install Axiom in your host machine:
+--------------------------------------------------
+
+You need to install [stack](https://docs.haskellstack.org/en/stable/README/) and [ghcjs](https://github.com/ghcjs/ghcjs). The latter is not an easy task.
+
+Then install Axiom in stack/ghc:
+
+```
+> stack install axiom
+```
+
+This should install ghc and compile everithing.
+
+Alternatively, you can install [Haskell platform](https://www.haskell.org/platform/) and:
+
+```
+> cabal install axiom
+```
+
+In any case you need to install Axiom in GHCJS too:
+
+```
+> cabal install axiom --ghcjs
+```
+
+How to compile and run a program
+================================
+```
+> mkdir  static 
+> ghcjs yourProgram.hs -o static/out
+> ghc yourProgram.hs
+
+> yourProgram -p start/yourhost/yourport
+
+```
+
+How to run Distributed applications
+========================
+
+If your program use `inputNodes` to connect N server nodes, you must use additional parameters in the command line:
+
+in a computer or docker instance:
+```
+> yourProgram -p start/host1/port1
+```
+In the same or another computer or docker instance:
+```
+> yourProgram -p start/host2/port2/add/host1/port1/y
+```
+in the same or another computer or docker instance:
+```
+> yourProgram -p start/host3/port3/add/host1/port1/y
+```
+
+Be sure that the `host:port` ip addresses are reachable from all the machines.
+
+This connect all the server nodes among them. 
+
+The web browser can point to any host:port of them. You must have the static folder (wich contains the generated javascript files) as well as the executable in all the locations.
+
+See [distrbutedApps](https://github.com/transient-haskell/transient-examples/blob/master/distributedApps.hs) that contain examples of distributed web applications.
+
 Plans:
 ======
 
-Axiom is in the process of becoming a Server-side as well as Client-side library for creating Web application. The last release support page templates for the creation of server-side content.
+Axiom web nodes are client side applications. So dHTML rendering happens on the browser. It is intended to implement server side rendering as well as multipage navigation. The last release support page navigation and page templates for the creation of server-side content.
 
-In the future it will manage routes in the server side besides client side, and will generate dinamic HTML content in the server as well as in the client.
+
axiom.cabal view
@@ -1,6 +1,6 @@ name: axiom
 
-version: 0.4.6
+version: 0.4.7
 cabal-version: >=1.10
 build-type: Simple
 
@@ -14,8 +14,6 @@ synopsis: Web EDSL for running in browsers and server nodes using transient
 description: Client-and Server-side Haskell framework that compiles to javascript with the GHCJS compiler and run over Transient.  See homepage
 category: Web
-cabal-version: >=1.10
-build-type: Simple
 stability: experimental
 
 data-dir: ""
@@ -23,14 +21,14 @@ 
 source-repository head
     type: git
-    location: http://github.com/agocorona/ghcjs-hplay
+    location: http://github.com/agocorona/axiom
 
 library
      build-depends: base               > 4.0  && <6.0
                   , transformers       -any
                   , containers         -any
-                  , transient          >= 0.5.9.2
-                  , transient-universe >= 0.4.6.1
+                  , transient          >= 0.6.0.1
+                  , transient-universe >= 0.5.0.0
 
                   , mtl                -any
                   , ghcjs-perch        >= 0.3.3
src/GHCJS/HPlay/Cell.hs view
@@ -14,23 +14,26 @@ {-# LANGUAGE TypeSynonymInstances, FlexibleInstances, OverloadedStrings, CPP, ScopedTypeVariables #-}
 module GHCJS.HPlay.Cell(Cell(..),boxCell,bcell,(.=),get,mkscell,scell, gcell, calc)  where
 import Transient.Internals
+import Transient.Move --hiding (JSString)
 import GHCJS.HPlay.View
 import Data.Typeable
 import Unsafe.Coerce
 import qualified Data.Map as M hiding ((!))
 
-import Control.Monad.IO.Class
+import Control.Monad.State hiding (get)
 import Control.Monad
+import Data.Monoid
 import Data.List
 import Control.Exception
-
+import Data.IORef
+import System.IO.Unsafe
 #ifdef ghcjs_HOST_OS
 
 import Data.JSString hiding (empty)
 
 #else
 
-type JSString = String
+-- type JSString = String
 
 #endif
 
@@ -73,8 +76,10 @@ typeIO :: (ElemID -> IO (Maybe a)) -> a
 typeIO = undefined
 
+typestring :: TypeRep
 typestring= typeOf (undefined :: String)
 
+show1 :: (Show a, Typeable a) => a -> String
 show1 x= if typeOf x== typestring
         then unsafeCoerce x
         else show x
@@ -127,66 +132,71 @@ -- | within a `mkscell` formula, `gcell` get the the value of another cell using his name.
 --
 -- see http://tryplayg.herokuapp.com/try/spreadsheet.hs/edit
-gcell ::   JSString -> Widget Double
-gcell n= Widget $ do
-  Vars vars <- getSData <|> return(Vars M.empty ) -- liftIO $ readIORef rvars
+gcell ::   JSString -> Cloud Double
+gcell n= loggedc $ do
+  -- onAll $ do
+  --    cutExceptions
+  --    reportBack
+  vars <- getCloudState rvars <|> return M.empty  -- liftIO $ readIORef rvars
+  localIO  $ print ("gcell", n)
   case M.lookup n vars of
-    Just exp -> do inc n  exp;  exp
+    Just exp -> do  inc ;  exp  !> "executing exp"
     Nothing -> error $ "cell not found: " ++ show n
   where
-  inc n exp=  do
-     Tries tries maxtries<- getSData <|> do
-                                      Exprs exprs <- getSData
-                                      return . Tries 0 $ 3 * (M.size $  exprs)
+  inc  =  do
+     Tries tries maxtries <- getCloudState rtries <|> error "no tries" --do
+                                      -- Exprs exprs <- getCloudState
+                                      -- return . Tries 0 $ 3 * (M.size $  exprs)
+     localIO $ print tries
      if tries <= maxtries
-       then  setData $ Tries (tries+1) maxtries
-       else  back Loop
+       then  localIO $  writeIORef rtries $ Tries (tries+1) maxtries
+       else  local $ do
+         -- liftIO $ print "back"
+         back Loop
 
 data Loop= Loop deriving (Show,Typeable)
 
 instance Exception Loop
 
 -- a parameter is a function of all of the rest
-type Expr a = TransIO a
+type Expr a = Cloud a
 
 data Tries= Tries Int Int deriving Typeable
---rtries= unsafePerformIO $ newIORef $ (0::Int)
+rtries= unsafePerformIO $ newIORef $ Tries 0 0
 --maxtries=  3 * (M.size $ unsafePerformIO $ readIORef rexprs)
 
-newtype Exprs= Exprs (M.Map JSString (Expr Double))
---rexprs :: IORef (M.Map JSString (Expr Double))
---rexprs= unsafePerformIO $ newIORef M.empty      -- initial expressions
+-- newtype Exprs= Exprs (M.Map JSString (Expr Double))
+rexprs :: IORef (M.Map JSString (Expr Double))
+rexprs= unsafePerformIO $ newIORef M.empty      -- initial expressions
 
-newtype Vars= Vars (M.Map JSString (Expr Double))
---rvars :: IORef (M.Map JSString (Expr Double))
---rvars= unsafePerformIO $ newIORef M.empty       -- expressions actually used for each cell.
+-- newtype Vars= Vars (M.Map JSString (Expr Double))
+rvars :: IORef (M.Map JSString (Expr Double))
+rvars= unsafePerformIO $ newIORef M.empty       -- expressions actually used for each cell.
                                                 -- initially, A mix of reexprs and rmodified
                                                 -- and also contains the result of calculation
 
-newtype Modified= Modified (M.Map JSString (Expr Double)) deriving Typeable
---rmodified :: IORef (M.Map JSString (Expr Double))
---rmodified= unsafePerformIO $ newIORef M.empty    -- cells modified by the user or by the loop detection mechanism
+-- newtype Modified= Modified (M.Map JSString (Expr Double)) deriving Typeable
+rmodified :: IORef (M.Map JSString ( Double))
+rmodified= unsafePerformIO $ newIORef M.empty    -- cells modified by the user or by the loop detection mechanism
 
 
 -- | make a spreadsheet cell. a spreadsheet cell is an input-output box that takes input values from
 -- the user, has an expression associated and display the result value after executing `calc`
 --
 -- see http://tryplayg.herokuapp.com/try/spreadsheet.hs/edit
-mkscell :: JSString -> Maybe Double -> Expr Double -> Widget Double
-mkscell name val expr= mk (scell name expr) val
+mkscell :: JSString -> Expr Double -> Cloud (Cell Double)
+mkscell  name  expr= do
+  exprs <- onAll $ liftIO (readIORef rexprs) <|> return ( M.empty) -- readIORef rexprs
+  onAll $ liftIO $ writeIORef  rexprs $ M.insert name expr exprs
+  return $ scell name expr
 
---both mx= local $ runCloud mx   <** runCloud ( atRemote (clustered $ mx >> empty :: Cloud()))
 
 
 scell :: JSString -> Expr Double -> Cell Double
 scell id  expr= Cell{ mk= \mv -> Widget $  do
-                           Exprs exprs <- getSData <|> return (Exprs M.empty) -- readIORef rexprs
-                           setData . Exprs $ M.insert id expr exprs
-
-                           r <- norender $ getParam (Just id) "text"  mv `fire` OnKeyUp
-
-                           Modified mod <-  getSData <|>  return(Modified M.empty)
-                           setData . Modified  $ M.insert  id (return  r)  mod
+                           r <- norender $ getParam (Just id) "text"  mv `fire` OnChange
+                           mod <-  liftIO (readIORef rmodified) <|> return( M.empty)
+                           liftIO $ writeIORef rmodified $ M.insert id  r mod
                            return r
 
                     , setter= \x -> withElem id $ \e -> setProp e "value" (toJSString $ show1 x)
@@ -197,66 +207,97 @@ 
 
 
+
 -- | executes the spreadsheet adjusting the vaules of the cells created with `mkscell` and solving loops
 --
 -- see http://tryplayg.herokuapp.com/try/spreadsheet.hs/edit
-calc :: Widget ()
-calc= Widget $  do
-  st <- getCont
-  return() `onBack` (\(e::Loop) -> do removeVar st e; forward Loop )
+calc :: Cloud ()
+calc=  do
+  mod <- localIO $ readIORef rmodified
+  onAll $ liftIO $ print ("LENGTH MOD", M.size mod)
+  onAll $ liftIO $ print "setCloudState modified"
+  setCloudState rmodified mod
+  exprs <- getCloudState rexprs
+  onAll $ liftIO $ print "setCloudState exprs"
+  setCloudState rexprs exprs
+  onAll $ liftIO $ print "setCloudState rvars"
 
-  Modified nvs <- getSData  <|> error "no modified" -- liftIO $ readIORef rmodified
+  setCloudState rvars  M.empty
 
-  when (not $ M.null nvs) $ do
-            values <-  calc1
-            mapM_ (\(n,v) -> boxCell n .= v)  values
+  onAll $ return() `onBack` (\(e::Loop) -> runCloud'  $ do localIO $ print "REMOVEVAR"; removeVar  e; local (forward Loop) )
+  exprs <- getCloudState rexprs <|> error "no exprs"
+  onAll $ liftIO $ print "setCloudState rtries"
 
---  liftIO $ writeIORef rmodified M.empty
+  setCloudState rtries $ Tries 0 $ 3 * (M.size $  exprs)
+  nvs <- getCloudState rmodified <|> error "no modified" -- liftIO $ readIORef rmodified
 
+  onAll $ liftIO $ print ("LENGTH NVS", M.size nvs)
+  when (not $ M.null nvs) $ calc1
+            --values <-  calc1
+            --localIO $ print "NEW CALC"
+            --local $ mapM_ (\(n,v) -> boxCell n .= v)  values
+  onAll $ liftIO $ print "setCloudState modified"
+  setCloudState rmodified M.empty
+
   where
-  run' st x=  runTransState st x >> return ()
 
 
-  calc1  :: TransIO [(JSString,Double)]
+  --calc1  :: Expr [(JSString,Double)]
   calc1= do
-    setData $ Tries 0 -- liftIO $ writeIORef rtries 0
-    Exprs cells    <- getSData <|> error "no exprs" -- liftIO $ readIORef rexprs
-    Modified nvs   <- getSData <|> error "mo modified2" -- liftIO $ readIORef rmodified
-    setData . Vars $ M.union nvs cells
-    solve
+      return () !> "CALC1"
+      cells    <- getCloudState rexprs <|> error "no exprs" -- liftIO $ readIORef rexprs
+      nvs      <- getCloudState rmodified <|> error "no modified2" -- liftIO $ readIORef rmodified
+      onAll $ liftIO $ print "setCloudState vars"
 
---solve  :: M.Map JSString (Widget a) -> Widget (M.Map JSString a)
-solve :: TransIO [(JSString,Double)]
-solve = do
-     Vars vars <- getSData <|> error "no vars" --  liftIO $ readIORef rvars
-     mapM (solve1 vars) $ M.toList vars
-     where
+      setCloudState rvars $ M.union (M.map return nvs) cells
 
+      solve
+
+  --solve :: Expr [(JSString,Double)]
+  solve =  do
+     vars <- getCloudState rvars <|> error "no vars" --  liftIO $ readIORef rvars
+     onAll $ liftIO $ print $ ("LENGHT VARS", M.size vars)
+     mapM_ (solve1 vars) $ M.toList vars
+     where
      solve1 vars (k,f)= do
+        localIO $ print ("solve1",k)
         x <- f
-        setData . Vars $ M.insert k (return x) vars
-        return (k,x) :: TransIO (JSString,Double)
+        localIO $ print ("setcloudstate var",k,x)
+        local $ boxCell k .= x
+        setCloudState rvars $ M.insert k (return x) vars
+        return () -- (k,x) :: Expr (JSString,Double)
 
 
+setCloudState r v=  allNodes $  writeIORef r v
+getCloudState r= onAll . liftIO $ readIORef r
 
---  removeVar :: EventF -> SomeException -> IO () -- [(JSString,Double)]
-removeVar st  = \(e:: Loop) ->  do -- runCloud $ both $ localIO $ do
-    Modified nvs <- getSData <|>  error "no modified 3"-- readIORef rmodified
-    Exprs exprs  <- getSData <|>  error " no Exprs2" --readIORef rexprs
+--  removeVar ::SomeException -> IO () -- [(JSString,Double)]
+removeVar = \(e:: Loop) -> do
+  nvs <- getCloudState rmodified <|>  error "no modified 3"-- readIORef rmodified
+  -- mapM (\n -> snd n >>= \v ->  localIO $ print (fst n,v)) $ M.toList nvs
+  exprs  <- getCloudState rexprs <|>  error " no Exprs2" --readIORef rexprs
 
-    case  M.keys exprs \\ M.keys nvs of
-      [] -> error "non solvable circularity in cell dependencies"
-      (name:_) -> do
-         mv <- liftIO $ getID name
+  case  M.keys exprs \\ M.keys nvs of
+    [] -> error "non solvable circularity in cell dependencies"
+    (name:_) -> do
+      localIO $ print ("removeVar",name)
 
-         case mv of
-            Nothing -> return ()
-            Just v  -> do
-                setData . Modified  $ M.insert name ( return v) nvs
-                return ()   -- !> ("using",v)
-                norender calc -- runTransState st (norender calc)
-                return ()
+      mv <- localIO $ getID name
 
+      case mv of
+          Nothing -> return ()
+          Just v  -> do
+              onAll $ liftIO $ print "setCloudState modified"
+              setCloudState  rmodified  $ M.insert name v nvs
+              return ()
+
+allNodes :: IO () -> Cloud ()
+allNodes mx= loggedc $ (localIO mx)  <> (atRemote $ (localIO $ print "UPDATE" >> mx))
+
+--atBrowser mx= if isBrowserInstance then mx else atRemote mx
+
+--atServer mx= if not isBrowserInstance then mx else atRemote mx
+  
   -- http://blog.sigfpe.com/2006/11/from-l-theorem-to-spreadsheet.html
   -- loeb ::  Functor f => f (t -> a) -> f a
   --  loeb x = fmap (\a ->  a (loeb  x)) x
src/GHCJS/HPlay/View.hs view
@@ -80,7 +80,6 @@   , pass
   -- * Low-level and Internals
   , ElemID
-  , FormInput(..)
   , getNextId
   , genNewId
   , continuePerch
@@ -97,10 +96,12 @@   , getValue
   -- * Re-exported
   , module Control.Applicative
-  , module GHCJS.Perch
+  , module GHCJS.Perch  
   -- remove
   ,CheckBoxes(..)
   ,edit
+  ,JSString,pack, unpack
+  ,RadioId(..), Radio(..)
 
 )  where
 
@@ -110,7 +111,7 @@ import           Transient.Move.Utils
 import qualified Prelude(id,span,div)
 #ifndef ghcjs_HOST_OS
-import           Transient.Move(ParseContext(..))
+import           Transient.Parse hiding(parseString)
 import           Data.Char(isSpace)
 import           System.Directory
 import           System.IO.Error
@@ -120,7 +121,7 @@ #endif
 
 import           Control.Monad.State
-import qualified Data.Map                as M
+-- import qualified Data.Map                as M
 
 import           Control.Applicative
 import           Control.Concurrent
@@ -147,10 +148,12 @@ import           GHCJS.Types
 import           Transient.Move          hiding (pack)
 
-import           Data.JSString           as JS hiding (empty, center,span, strip,foldr,head,tail)
+import qualified Data.JSString           as JS hiding (empty, center,span, strip,foldr,head)
+import           Data.JSString (pack,unpack,toLower)
 #else
+import           Data.List as JS         hiding (span)
 import           GHCJS.Perch             hiding (JSVal, JsEvent (..), eventName, option,head, map)
-import           Transient.Move          hiding (JSString, pack)
+import           Transient.Move          
 #endif
 
 #ifndef ghcjs_HOST_OS
@@ -195,16 +198,17 @@ getName = undefined
 #endif
 
-elemBySeq :: (MonadState EventF m,MonadIO m)  => JSString -> m (Maybe Elem)
+elemBySeq :: (MonadState EventF m, MonadIO m) => JSString -> m (Maybe Elem)
 #ifdef ghcjs_HOST_OS
-elemBySeq id=  do
-   IdLine _ id1 <- getData `onNothing` error ("not found: " ++ show id) --  return (IdLine "none")
-   return  ()                                                    !> ("elemBySeq",id1, id)
-   liftIO $ do
-      re <- elemBySeqDOM  id1 $ JS.takeWhile (/='p') id
-      fromJSVal re
+elemBySeq id = do
+    IdLine _ id1 <- getData `onNothing` error ("not found: " ++ show id) --  return (IdLine "none")
+    return  ()                                                    !> ("elemBySeq",id1, id)
+    liftIO $ do
+        let id2= JS.takeWhile (/='p') id
+        re <- elemBySeqDOM id1 id2
+        fromJSVal re
 #else
-elemBySeq _= return Nothing
+elemBySeq _ = return Nothing
 #endif
 
 #ifdef ghcjs_HOST_OS
@@ -232,7 +236,7 @@      Nothing -> error ("withElem: not found"++ fromJSString id)
      Just e -> f e
 
-data NeedForm= HasForm | HasElems  | NoElems deriving Show
+--data NeedForm= HasForm | HasElems  | NoElems deriving Show
 
 
 type ElemID= JSString
@@ -241,49 +245,40 @@ instance   Functor Widget where
   fmap f mx=   Widget. Transient $ fmap (fmap f) . runTrans $ norender mx
 
---instance Alternative Widget where
---   empty= Widget empty
---   (Widget x) <|> (Widget y)=  Widget $ Transient $ do
---            rx <- runTrans x
---            ry <- runTrans y
---            return $ rx <|> ry
 
 
 instance Applicative Widget where
   pure= return
 
-  Widget (Transient x) <*> Widget (Transient y) = Widget .Transient  $ do
-          mn <- getData
-          mrepeat <-getData
-
-          when (isJust mn && mrepeat == Just ExecEvent) $ do
-            let IDNUM n = fromJust mn in modify $  \s -> s{mfSequence=  n}
-                                                                           -- !> ("SET IDMUN", n)
-            delData $ IDNUM 0
-          mx <- x
-          my <- y
-          return $ mx <*> my
+  Widget (Transient x) <*> Widget (Transient y) = Widget . Transient $ do
+        getData `onNothing` do 
+            cont <- get
+            let al= Alternative cont
+            setData $ Alternative cont
+            return al
+        mx <- x
+        my <- y
+        return $ mx <*> my
 
 
 
 instance Monoid a => Monoid (Widget a) where
   mempty= return mempty
-  mappend x y= (<>) <$> x <*> y
+  mappend x y= do 
+     (<>) <$> x  <*> y
 
 instance AdditionalOperators Widget where
 
-    Widget (Transient x) <** Widget (Transient y)=
-          Widget . Transient $ do
-                 mn <- getData
-                 mrepeat <-getData
-                 liftIO $ print ("IDNUM",mn)
-                 when (isJust mn && mrepeat == Just ExecEvent) $ do
-                    let IDNUM n = fromJust mn in modify $  \s -> s{mfSequence=  n}
---                                                                                 !> ("SET IDMUN", n)
-                    delData $ IDNUM 0
-                 mx <- x
-                 y
-                 return mx
+    Widget (Transient x) <** Widget (Transient y)= Widget . Transient $ do
+                getData `onNothing` do 
+                  cont <- get
+                  let al= Alternative cont
+                  setData $ Alternative cont
+                  return al
+                 
+                mx <- x
+                y
+                return mx
 
     (<***) x y= Widget $  norender x <*** norender y
 
@@ -335,22 +330,22 @@ -- instance of this class.
 -- See "MFlow.Forms.Blaze.Html for the instance for blaze-html" "MFlow.Forms.XHtml" for the instance
 -- for @Text.XHtml@ and MFlow.Forms.HSP for the instance for Haskell Server Pages.
-class (Monoid view,Typeable view)   => FormInput view where
-    fromStr :: JSString -> view
-    fromStrNoEncode :: String -> view
-    ftag :: JSString -> view  -> view
-    inred   :: view -> view
-    flink ::  JSString -> view -> view
-    flink1:: JSString -> view
-    flink1 verb = flink verb (fromStr verb)
-    finput :: Name -> Type -> Value -> Checked -> OnClick1 -> view
-    ftextarea :: JSString -> JSString -> view
-    fselect :: JSString -> view -> view
-    foption :: JSString -> view -> Bool -> view
-    foption1 :: JSString -> Bool -> view
-    foption1   val msel= foption val (fromStr val) msel
-    formAction  :: JSString -> JSString -> view -> view
-    attrs :: view -> Attribs -> view
+-- class (Monoid view,Typeable view)   => FormInput view where
+--     fromStr :: JSString -> view
+--     fromStrNoEncode :: String -> view
+--     ftag :: JSString -> view  -> view
+--     inred   :: view -> view
+--     flink ::  JSString -> view -> view
+--     flink1:: JSString -> view
+--     flink1 verb = flink verb (fromStr verb)
+--     finput :: Name -> Type -> Value -> Checked -> OnClick1 -> view
+--     ftextarea :: JSString -> JSString -> view
+--     fselect :: JSString -> view -> view
+--     foption :: JSString -> view -> Bool -> view
+--     foption1 :: JSString -> Bool -> view
+--     foption1   val msel= foption val (fromStr val) msel
+--     formAction  :: JSString -> JSString -> view -> view
+--     attrs :: view -> Attribs -> view
 
 type Attribs= [(JSString, JSString)]
 
@@ -368,17 +363,18 @@ fromValidated (NotValidated s err)= error $ "fromValidated: NotValidated "++ s
 
 getParam1 :: ( Typeable a, Read a, Show a)
-          => JSString ->  StateIO (ParamResult Perch a)
-getParam1 par = do
+          => Bool -> JSString ->  StateIO (ParamResult Perch a)
+getParam1 exact  par = do
    isTemplate <- liftIO $ readIORef execTemplate
    if isTemplate then return NoParam else do
-       me <- elemBySeq par !> par
---                                                !> ("looking for " ++ show par)
+      
+       me <- if exact then elemById par else elemBySeq par
+                                                !> ("looking for " ++ show par)
        case me of
          Nothing -> return  NoParam
          Just e ->  do
-           v <- getValue e                       -- !!> ("exist" ++ show par)
-           readParam v                           -- !!> ("getParam for "++ show v)
+            v <- getValue e                       -- !!> ("exist" ++ show par)
+            readParam v                           -- !!> ("getParam for "++ show v)
 
 
 type Params= Attribs
@@ -397,14 +393,18 @@ 
  maybeRead str= do
    let typeofx = typeOf x
-   if typeofx == typeOf  ( undefined :: String)   then
+   if typeofx == typeOf  ( undefined :: String)     then
            return . Validated $ unsafeCoerce str            -- !!> ("maybread string " ++ str)
-    else case reads $ str  of          --            -- !!> ("read " ++ str) of
+   else if typeofx == typeOf(undefined :: JSString) then
+           return . Validated $ unsafeCoerce $ pack  str
+   else case reads $ str  of          --            -- !!> ("read " ++ str) of
               [(x,"")] ->  return $ Validated x            -- !!> ("readsprec" ++ show x)
               _ -> do
-                   let err= inred . fromStr $ toJSString $ "can't read \"" ++ str ++ "\" as type " ++  show (typeOf x)
+                   let err= inred $ "can't read \"" ++ str ++ "\" as type " ++  show (typeOf x)
                    return $ NotValidated str err
 
+
+
 -- | Validates a form or widget result against a validating procedure
 --
 -- @getOdd= getInt Nothing `validate` (\x -> return $ if mod x 2==0 then  Nothing else Just "only odd numbers, please")@
@@ -420,7 +420,7 @@           me <- val x
           case me of
              Just str -> do
-                  liftIO $ withElem idn $ build $ clear >> inred  str
+                  liftIO $ withElem idn $ build $ clear >> (inred  str)
                   return Nothing
              Nothing  -> do
                   liftIO $ withElem idn $ build clear
@@ -439,7 +439,6 @@ #ifdef ghcjs_HOST_OS
 genNewId ::  (MonadState EventF m, MonadIO m) => m  JSString
 genNewId=  do
---      Prefix pre <-  getData `onNothing` return (Prefix "")
       r <- liftIO $ atomicModifyIORef rprefix (\n -> (n+1,n))
       n <- genId
       let nid= toJSString $  ('n':show n) ++ ('p':show r)
@@ -502,69 +501,56 @@ inputPassword ::   Widget String
 inputPassword= getPassword
 
-newtype Radio a= Radio a deriving Monoid
-
+newtype Radio a= Radio a
 
+data RadioId= RadioId JSString deriving Typeable
 
 -- | Implement a radio button
--- the parameter is the name of the radio group
-setRadio :: (Typeable a, Eq a, Show a) =>
-            a ->  Widget  (Radio a)
-setRadio v = Widget $ Transient $ do
-  RadioId n <- getData `onNothing` error "setRadio out of getRadio"
+setRadio :: (Typeable a, Eq a, Show a,Read a) =>
+            Bool -> a ->  Widget  (Radio a)
+setRadio ch v = Widget $ Transient $ do
+  RadioId name <- getData `onNothing` error "setRadio out of getRadio"
   id <- genNewId
-  st <- get
---  setData HasElems       -- only for MFlow
-  me <- elemBySeq id
+  me <- elemBySeq id  
   checked <-  case me  of
-       Nothing -> return ""
-       Just e  -> liftIO $ getProp e "checked"
-  let strs= if  checked=="true" then Just v else Nothing
---  let mn= if null strs then False else True
-      ret= fmap  Radio  strs
-      str = if typeOf v == typeOf(undefined :: String)
+      Nothing -> return ""
+      Just e  -> liftIO $ getProp e "checked"
+  
+  let str = if typeOf v == typeOf(undefined :: String)
                    then unsafeCoerce v else show v
-
   addSData
-      ( finput id "radio" (toJSString str) ( isJust strs ) Nothing `attrs` [("name",n)] :: Perch)
+      ( finput id "radio" (toJSString str)  ch Nothing `attrs` [("name",name)] :: Perch)
+  
+  if  checked == "true" !> ("val",v) then Just . Radio . read1 . unpack <$> liftIO (getProp (fromJust me) "value") else return Nothing
+  where 
+  read1 x=r 
+    where
+    r= if typeOf r== typeOf (undefined :: String) then unsafeCoerce x 
+          else read x 
 
-  return ret
+setRadioActive :: (Typeable a, Eq a, Show a,Read a) =>
+                   Bool -> a -> Widget (Radio a)
+setRadioActive ch rs = setRadio ch rs `raiseEvent` OnClick
 
-setRadioActive :: (Typeable a, Eq a, Show a) =>
-                    a -> Widget (Radio a)
-setRadioActive rs = setRadio rs `raiseEvent` OnClick
 
-data RadioId= RadioId JSString deriving Typeable
-
 -- | encloses a set of Radio boxes. Return the option selected
 getRadio
-  :: Monoid a => [Widget (Radio a)] -> Widget a
-getRadio ws = Widget $ Transient $ do
-   id <- genNewId
-   setData $ RadioId id
-   fs <- mapM runView  ws
-   let mx = mconcat fs
-   delData $ RadioId id
-   return $ fmap (\(Radio r) -> r) mx
+   ::  [Widget (Radio a)] -> Widget a
+getRadio ws =  do
+  id <- genNewId
+  setData $ RadioId id
+  Radio x <- foldr (<|>) empty ws <*** delData (RadioId id)
+  return x
 
 
-data CheckBoxes a= CheckBoxes [a] deriving Show
-
-instance Monoid (CheckBoxes a) where
-  mappend (CheckBoxes xs) (CheckBoxes ys)= CheckBoxes $ xs ++ ys
-  mempty= CheckBoxes []
-
+newtype CheckBoxes a= CheckBoxes [a] deriving Monoid
 
--- | Display a text box and return the value entered if it is readable( Otherwise, fail the validation)
+-- | present a checkbox
 setCheckBox :: (Typeable a , Show a) =>
                 Bool -> a -> Widget  (CheckBoxes a)
 setCheckBox checked' v= Widget . Transient $ do
   n  <- genNewId
-  st <- get
---  setData HasElems
   me <- elemBySeq n
-
-
   let showv= toJSString (if typeOf v == typeOf (undefined :: String)
                              then unsafeCoerce v
                              else show v)
@@ -577,27 +563,26 @@             checked <- liftIO $ getProp e "checked"
             return . Just . CheckBoxes $ if  checked=="true"  then [v] else []
 
-
+-- Read the checkboxes
 getCheckBoxes ::  Show a => Widget  (CheckBoxes a) ->  Widget  [a]
-getCheckBoxes w = Widget $ Transient $ do
-   mrs <- runView w
-   case mrs of
-     Nothing -> return Nothing
-     Just(CheckBoxes rs ) ->   return $ Just rs
+getCheckBoxes w =  do
+  CheckBoxes rs <-  w
+  return rs
+ 
 
 whidden :: (Read a, Show a, Typeable a) => a -> Widget a
 whidden x= res where
  res= Widget . Transient $ do
-      n <- genNewId
-      let showx= case cast x of
-                  Just x' -> x'
-                  Nothing -> show x
-      r <- getParam1 n  `asTypeOf` typef res
-      addSData (finput n "hidden" (toJSString showx) False Nothing :: Perch)
-      return (valToMaybe r)
-      where
-      typef :: Widget a -> StateIO (ParamResult Perch a)
-      typef = undefined
+    n <- genNewId
+    let showx= case cast x of
+                Just x' -> x'
+                Nothing -> show x
+    r <- getParam1 False n  `asTypeOf` typef res
+    addSData (finput n "hidden" (toJSString showx) False Nothing :: Perch)
+    return (valToMaybe r)
+    where
+    typef :: Widget a -> StateIO (ParamResult Perch a)
+    typef = undefined
 
 
 
@@ -628,9 +613,9 @@               else if typeOf v== typeOf (undefined :: JSString) then unsafeCoerce v
               else toJSString $ show v             -- !!> "show"
 
-    setData HasElems
-    r <- getParam1 tolook
-
+    -- setData HasElems
+    r <- getParam1 (isJust look) tolook
+    
     case r of
        Validated x        -> do addSData (finput tolook type1 (nvalue $ Just x) False Nothing :: Perch) ; return $ Just x            -- !!> "validated"
        NotValidated s err -> do addSData (finput tolook type1  (toJSString s) False Nothing <> err :: Perch); return Nothing
@@ -645,7 +630,7 @@ getMultilineText nvalue =  res where
  res= Widget. Transient $ do
     tolook <- genNewId   !>  "GETMULTI"
-    r <- getParam1 tolook  `asTypeOf` typef res
+    r <- getParam1 False tolook  `asTypeOf` typef res
     case r of
        Validated x        -> do addSData (ftextarea tolook  $ toJSString x :: Perch); return $ Just x     !> "VALIDATED"
        NotValidated s err -> do addSData (ftextarea tolook   (toJSString s) :: Perch); return  Nothing    !> "NOTVALIDATED"
@@ -677,7 +662,7 @@     tolook <- genNewId
     -- st <- get
 --    setData HasElems
-    r <- getParam1 tolook `asTypeOf` typef res
+    r <- getParam1 False tolook `asTypeOf` typef res
 --    setData $ fmap MFOption $ valToMaybe r
     runView $ fselect tolook <<< opts
 --
@@ -799,10 +784,11 @@ staticNav  x= do
   Path paths <-  getState <|> return (Path  [])
   x <*** setState (Path paths)
+  
 
 -- | template link. Besides the wlink behaviour, it loads the page from the server if there is any
 --
--- the page many have been saved with `edit`
+-- the page may have been saved with `edit`
 tlink :: (Show a,  Typeable a) => a -> Perch -> Widget a
 tlink x v= Widget  $
 
@@ -897,7 +883,6 @@          else do
 --            setData ExecTemplate     !> "SET EXECTEMPLATE 2"
 --            liftIO $ writeIORef execTemplate True
-            liftIO $ print (pathelem, segment)
             if unpack pathelem /= segment then  empty else do
                    liftIO $ writeIORef rReadIndexPath $ l + 1
                    asynchronous
@@ -960,28 +945,28 @@ 
     where
     isSeparator c=  c == '>'
-    dropSpaces= parse $ \str ->((),BS.dropWhile isSpace str)
+    --dropSpaces= parse $ \str ->((),BS.dropWhile isSpace str)
 
 
-tTakeWhile :: (Char -> Bool) -> TransIO BS.ByteString
-tTakeWhile cond= parse (span' cond)
-  where
-  span' cond s=
-     let (h,t) = BS.span cond s
-         c= BS.head t
-     in (BS.snoc h c,BS.drop 1 t)
+-- tTakeWhile :: (Char -> Bool) -> TransIO BS.ByteString
+-- tTakeWhile cond= parse (span' cond)
+--   where
+--   span' cond s=
+--      let (h,t) = BS.span cond s
+--          c= BS.head t
+--      in (BS.snoc h c,BS.drop 1 t)
 
 
-parse ::  (BS.ByteString -> (b, BS.ByteString)) -> TransIO b
-parse split= do
-    ParseContext readit str <- getSData
-                                <|> error "parse: ParseContext not found"
-                                :: TransIO (ParseContext BS.ByteString)
+-- parse ::  (BS.ByteString -> (b, BS.ByteString)) -> TransIO b
+-- parse split= do
+--     ParseContext readit str <- getSData
+--                                 <|> error "parse: ParseContext not found"
+--                                 :: TransIO (ParseContext BS.ByteString)
 
-    if BS.null str then empty else do
-       let (ret,str3) = split str
-       setData $ ParseContext readit  str3
-       return ret
+--     if BS.null str then empty else do
+--        let (ret,str3) = split str
+--        setData $ ParseContext readit  str3
+--        return ret
 
 
 
@@ -1061,7 +1046,7 @@       rest <- getData `onNothing` return mempty
       delData rest
       mx <- runView widget
-      fs <- getData `onNothing` return mempty
+      fs <- getData `onNothing` return (mempty :: Perch)
       setData  $ rest <> (fs `attrs` attribs :: Perch)
       return mx
 
@@ -1112,41 +1097,42 @@ 
 
 -------------------------
-instance   FormInput Perch  where
-    fromStr = toElem
-    fromStrNoEncode  = toElem
-    ftag n v =  nelem n `child` v
+fromStr = toElem
+--     fromStrNoEncode  = toElem
+ftag n v =  nelem n `child` v
 
-    attrs tag  [] = tag
-    attrs tag (nv:attribs) = attrs (attr tag nv) attribs
+attrs tag  [] = tag
+attrs tag (nv:attribs) = attrs (attr tag nv) attribs
 
-    inred msg=  ftag "b" msg `attrs` [("style","color:red")]
+inred msg=  ftag "b" msg `attrs` [("style","color:red")]
 
-    finput n t v f c=
+finput n t v f c=
        let
-        tag= ftag "input" mempty `attrs` [("type",  t), ("id",  n), ("value",  v)]
-        tag1= if f then tag `attrs` [("checked", "")] else tag
-       in case c of Just s -> tag1 `attrs` [("onclick", s)] ; _ -> tag1
+        tag= input ! atr "type" t ! id   n ! atr "value"   v
+        tag1= if f then tag ! atr "checked" "" else tag
+       in case c of Just s -> tag1 ! atr "onclick" s; _ -> tag1
 
-    ftextarea nam text=
-        ftag "textarea" mempty `attrs` [("id",  nam)] `child` text
 
+ftextarea nam text=
+         textarea ! id  nam $ text
 
-    fselect nam list = ftag "select" mempty `attrs` [("id", nam)] `child` list
-    foption  name v msel=
-      let tag=  ftag "option" mempty `attrs` [("value", name)]  `child`  v
-      in if msel then tag `attrs` [("selected", "")] else tag
 
+fselect nam list = select ! id nam $ list
 
-    formAction action method1 form = ftag "form" mempty `attrs` [("acceptCharset", "UTF-8")
-                                                         ,( "action", action)
-                                                         ,("method",  method1)]
-                                                         `child` form
+foption  name v msel=
+      let tag=  nelem "option" ! atr "value" name  `child`  v
+      in if msel then tag ! atr "selected" "" else tag
 
 
-    flink  v str = ftag "a" mempty `attrs` [("href",  v)] `child` str
+--     formAction action method1 form = ftag "form" mempty `attrs` [("acceptCharset", "UTF-8")
+--                                                          ,( "action", action)
+--                                                          ,("method",  method1)]
+--                                                          `child` form
 
 
+--     flink  v str = ftag "a" mempty `attrs` [("href",  v)] `child` str
+
+
 ---------------------------
 data EvData =  NoData | Click Int (Int, Int) | Mouse (Int, Int) | MouseOut | Key Int deriving (Show,Eq,Typeable)
 
@@ -1369,7 +1355,7 @@ 
 -- first identifier for an applicative widget expression
 -- needed for applictives in the widget monad that are executed differently than in the TransIO monad
-newtype IDNUM = IDNUM Int deriving Show
+-- newtype IDNUM = IDNUM Int deriving Show
 
 data Event= forall ev.IsEvent ev => Event ev
 
@@ -1399,7 +1385,7 @@ raiseEvent ::  IsEvent event  => Widget a -> event -> Widget a
 #ifdef ghcjs_HOST_OS
 raiseEvent w event = Widget . Transient $ do
-       cont <- get                                             -- !> "raise"
+       Alternative cont <- getData  `onNothing` (Alternative <$> get)
        let iohandler :: EventData -> IO ()
            iohandler eventdata =do
                 runStateT (setData eventdata >> runCont' cont) cont  --  !> "runCont INIT"
@@ -1408,17 +1394,19 @@        id <- genNewId
        let id'= JS.takeWhile (/='p') id
        addEventList id' event iohandler
-
-       me <- elemBySeq id'                                          --  !> ("adding event to",  id')
-       case me of
+       template <-liftIO $ readIORef execTemplate 
+       if not template then runView $ addEvent  id event iohandler <<< w  
+       else do
+          me <- elemBySeq id'                                          --  !> ("adding event to",  id')
+          case me of
 
-         Nothing -> runView $ addEvent  id event iohandler <<< w      -- !> "do not exist, creating elem"
-         Just e -> do
-           mr <- getData                                              -- !> "exist adding event to current element"
-           when (mr /= Just ExecEvent) $ liftIO (buildHandler e event iohandler)
-           r <- runView w
-           delData noHtml
-           return r
+            Nothing -> runView $ addEvent  id event iohandler <<< w      !> "do not exist, creating elem"
+            Just e -> do
+              mr <- getData                                              !> "exist adding event to current element"
+              when (mr /= Just ExecEvent) $ liftIO (buildHandler e event iohandler)
+              r <- runView w
+              delData noHtml
+              return r
 
    where
    -- to restore event handlers when a new template is loaded
@@ -1433,9 +1421,8 @@ 
 
    runCont' cont= do
---     mn <- getData
---     when (isJust mn) $ let IDNUM n = fromJust mn in modify $  \s -> s{mfSequence=  n}
      setData ExecEvent                              --  !> "REPEAT: SET EXECEVENT"
+
      liftIO $ writeIORef execTemplate False
      mr <- runClosure cont
      return ()
@@ -1484,6 +1471,7 @@         wraw v `wake` event
         e@(EventData typ _) <- getEventData
         guard (eventName event== typ)
+
         return e
 
 
@@ -1528,7 +1516,7 @@   runWidget  w body
 
 
-data AlternativeBranch= Alternative deriving (Typeable, Eq, Show)
+newtype AlternativeBranch= Alternative EventF deriving Typeable
 
 -- | executes the computation and  add the effect of "hanging" the generated rendering from the one generated by the
 -- previous `render` sentence, or from the body of the document, if there isn't any. If an event happens within
@@ -1555,7 +1543,7 @@        ma <- getData
        mw <- getData 
        
-       id1 <- if (ma == Just Alternative || mw == Just WasParallel) !> (ma,mw)
+       id1 <- if (isJust (ma :: Maybe AlternativeBranch) || mw == Just WasParallel )   !> (mw)
                then do
                  id3 <- do
                      id3 <- genNewId !> "ALTERNATIVE"
@@ -1568,19 +1556,19 @@                             me <- liftIO $   elemById id1' >>= \x ->
                                               case x of
                                                  Nothing -> return Nothing
-                                                 Just x -> nextSibling x
+                                                 Just x  -> nextSibling x
                             case me of
                               Nothing -> return id3 -- should not happen
-                              Just e -> attribute e "id" >>= return . fromJust
+                              Just e  -> attribute e "id" >>= return . fromJust
 
-                 setData (IdLine level id3)                             -- !> ("setDataAL1",id3)
-                 delData Alternative                                    -- !> ("alternative, creating", id3)
+                 setData (IdLine level id3)                              !> ("setDataAL1",id3)
+                 delData $ Alternative  undefined                                   !> ("alternative, creating", id3)
                  return id3
                else setData idline1 >> return id1'
 
        id2 <-  genNewId
        n <- gets mfSequence
-       setData $ IDNUM n
+      --  setData $ IDNUM n
 
 
 
@@ -1590,7 +1578,7 @@ 
         (Transient $ do
 
-           meid2 <- elemBySeq id2                                   -- !> ("checking",id1,id2)
+           meid2 <- elemBySeq id2                                    !> ("checking",id1,id2)
 
            case meid2 of
             Nothing -> return ()
@@ -1599,7 +1587,7 @@                id2' <- attribute eid2 "id" >>= return . fromJust
 --               let n= read (tail $ JS.unpack  $ JS.dropWhile (/= 'p') id2') + 1
 --               liftIO $ writeIORef rprefix n   !>  ("N",n)
-               (setData (IdLine (level +1) id2'))                   -- !>  ("set IdLine",id2')
+               (setData (IdLine (level +1) id2'))                    !>  ("set IdLine",id2')
 
            execmode <- getData
 
@@ -1607,7 +1595,7 @@              Just ExecEvent -> do
                 -- an event has happened. Clean previous rendering
                 when (isJust meid2) $ liftIO $ do
-                        deleteSiblings $ fromJust meid2                 -- !> "EVENT"
+                        deleteSiblings $ fromJust meid2                  !> "EVENT"
                         clearChildren $ fromJust meid2
                 delData ExecEvent
 
@@ -1616,7 +1604,7 @@ 
              _ -> do
 
-                 return ()                                               -- !> ("EXECTEMPLATE", isTemplate)
+                 return ()                                                !> ("EXECTEMPLATE", isTemplate)
                  if isTemplate then delData noHtml  else do
                      render <- getData `onNothing` (return  noHtml)      -- !> "TEMPLATE"
 
@@ -1627,13 +1615,15 @@                      delData render
            return $ Just ())
        if(isJust r)
-         then  delData Alternative >> setData (IdLine (level +1) id2 )    -- !> ("setDataAl",id2)
-         else  setData Alternative  !> "SETDATA ALTERNATIVE"
+         then  delData (Alternative undefined) >> setData (IdLine (level +1) id2 )    -- !> ("setDataAl",id2)
+         else do 
+               cont <- get
+               setData (Alternative cont)  !> "SETDATA ALTERNATIVE"
        return r
 
 
 #else
-render (Widget x)= x
+render (Widget x)= empty
 #endif
 
 
@@ -1661,11 +1651,19 @@ -- be appended, prepended to the previous content or it can erase the previous content depending on the
 -- update method.
 at ::  JSString -> UpdateMethod -> Widget a -> Widget  a
-at id method w= setAt id method <<< w
-
+at id method w= setAt id method <<< do
+  original@(IdLine level i) <- Widget $ getState <|> error "IdLine not defined"
+  setState $ IdLine level  $ JS.tail id -- "n0p0"
+  w  `with` setState original
+  where
+  with    (Widget (Transient x)) (Widget (Transient y))=
+    Widget . Transient $ do
+           mx <- x
+           y
+           return mx
 
 setAt :: JSString -> UpdateMethod -> Perch  -> Perch
-setAt id method render  = liftIO $ case method of
+setAt id method render  = liftIO $   case method of
      Insert -> do
              forElems_ id $ clear >> render
              return ()
@@ -1705,9 +1703,10 @@ 
 foreign import javascript unsafe  "$1[$2] = $3" setProp :: Elem -> JSString -> JSString -> IO ()
 
-foreign import javascript unsafe  "alert($1)" alert ::  JSString -> IO ()
-
+foreign import javascript unsafe  "alert($1)" js_alert ::  JSString -> IO ()
 
+alert ::  (Show a,MonadIO m) => a -> m ()
+alert= liftIO . js_alert . pack . show 
 
 foreign import javascript unsafe  "document.getElementById($1)" elemByIdDOM
       :: JSString -> IO JSVal
@@ -1725,11 +1724,11 @@ #else
 unpack= undefined
 getProp :: Elem -> JSString -> IO JSString
-getProp = undefined
+getProp = error "getProp: undefined in server"
 setProp :: Elem -> JSString -> JSString -> IO ()
-setProp = undefined
-alert ::  JSString -> IO ()
-alert= undefined
+setProp = error "setProp: undefined in server"
+alert ::  (Show a,MonadIO m) => a -> m ()
+alert= liftIO . print
 data Callback a= Callback a
 data ContinueAsync=ContinueAsync
 syncCallback1= undefined