h3      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                     NoneM         None+23468:MAdministrator name URL of jquery URL of jqueryCSS URL of jqueryUI URL of the nicEdit editor #UList of (wfname, workflow) pairs, to be scheduled depending on the message's pwfname (A ( identifies a '0 that handle messages. The scheduler composes a ( with every A message that arrives and sends the message to the appropriate '. 4The anonymous user. The path of the root flow. 6ESet the flow to be executed when the URL has no path. The home page. 9By default it is "noscript". Although it is changed by  runNavigation to it's own flow name. 7@Send a complete response. send :: Token -> HttpData -> IO() 9TSend a response fragment, useful for streaming. The last packet must be sent trough 7. @^Executes a simple request-response computation that receive the params and return a response. It is used with B  There is a higher level version  wstateless in  MFLow.Forms AExecutes a monadic computation that are send and receive messages, but does not store it's state in permanent storage. The process once stopped, will restart anew BFAdd a list of flows to be scheduled. Each entry in the list is a pair  (path, flow) C"Return the list of the scheduler. FThe scheduler creates a ( with every u message that arrives and sends the message to the appropriate flow, then waits for the response and returns it. ,This is the core of the application server.  MFLow.Wai and  MFlow.Hack use it GThe handler of the error log. HSets an authentication method, that includes the registration and validation calls. Both return Nothing if successful. Otherwise they return a text message explaining the failure.  Return the key name of an user Register an user/password. K&Register a user with the auth method. MRead a config variable from the config file "mflow.config". If it is not set, use the second parameter and add it to the configuration list so next time the administrator can change it in the configuration file. %Set an user-defined config variable. NSet the Administrator user and password. It must be defined in Main, before any configuration parameter is read and before the execution of any flow. P#Set the 404 "not found" response. The parameter is as follows: (Bool Either if the user is Administrator or not -> String The error string -> HttpData) The response. See  code for an example RuWrites a XML tag in a ByteString. It is the most basic form of formatting. For more sophisticated formatting , use MFlow.Forms.XHtml or MFlow.Forms.HSP. S bhtml ats v= btag "html" ats v T bbody ats v= btag "body" ats v VSet the path of the files in the web server. The links to the files are relative to it. The files are cached (memoized) according with the  Data.TCache policies in the program space. This avoid the blocking of the efficient GHC threads by frequent IO calls. This enhances the performance in the context of heavy concurrency. It uses  *. The caching and uncaching follows the  criteria  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYI !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYI'"$&% !()*+,-./01#=<;>?789:E6BCDA@45GPQRSTUKNOIHLMV23FWYXJb !"#$&%'( )*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYNone +2346:BM-[a server procedure \!a string with a valid JavaScript ] a String with a CSS description ^a CSS file URL _>Script URL and the list of scripts to be executed when loaded hMinimal interface for defining the basic form and link elements. The core of MFlow is agnostic about the rendering package used. Every formatting (either HTML or not) used with MFlow must have an 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.  View v m a( is a widget (formlet) with formatting v running the monad m (usually #) and which return a value of type a It has ,  and   instances. &Things to know about these instances: KIf the View expression does not validate, ask will present the page again. Alternative instance7: Both alternatives are executed. The rest is as usual Monad Instance: YThe rendering of each statement is added to the previous. If you want to avoid this, use  The execution is stopped when the statement has a formlet-widget that does not validate and return an invalid response (So it will present the page again if no other widget in the expression validates). ]The monadic code is executed from the beginning each time the page is presented or refreshed use pageFlowJ if your page has more than one monadic computation with dynamic behavior use pageFlow2 to identify each subflow branch of a conditional  For example:  pageFlow "myid" $ do r <- formlet1 liftIO $ ioaction1 r s <- formlet2 liftIO $ ioaction2 s case s of True -> pageFlow "idtrue" $ do .... False -> paeFlow "idfalse" $ do ... ...  Here if formlet2 do not validate,  ioaction2 is not executed. But if formLet1; validates and the page is refreshed two times (because formlet2 has failed, see above),then  ioaction1 is executed two times. use  . if you want to avoid repeated IO executions. the FlowM monad executes the page navigation. It perform Backtracking when necessary to synchronize when the user press the back button or when the user enter an arbitrary URL. The instruction pointer is moved to the right position within the procedure to handle the request. aHowever this is transparent to the programmer, who codify in the style of a console application. LUse this instead of return to return from a computation with ask statements This way when the user press the back button, the computation will execute back, to the returned code, according with the user navigation. It is a callback in the view monad. The callback rendering substitutes the widget rendering when the latter is validated, without affecting the rendering of other widgets. This allow the simultaneous execution of different behaviors in different widgets in the same page. The inspiration is the callback primitive in the Seaside Web Framework that allows similar functionality (See  http://www.seaside.st) $This is the visible difference with waction callbacks, which execute a a flow in the FlowM monad that takes complete control of the navigation, while wactions are executed within the same page. @Execute the widget in a monad and return the result in another. ?Join two widgets in the same page the resulting widget, when askded with it, return a 2 tuple of their validation results if both return Noting, the widget return Nothing (invalid). it has a low infix priority: infixr 2 Br <- ask widget1 <+> widget2 case r of (Just x, Nothing) -> .. ?Join two widgets in the same page the resulting widget, when askded with it, return a 2 tuple of their validation results if both return Noting, the widget return Nothing (invalid). it has a low infix priority: infixr 2 Br <- ask widget1 <+> widget2 case r of (Just x, Nothing) -> .. The first elem result (even if it is not validated) is discarded, and the second is returned . This contrast with the applicative operator  O which fails the whole validation if the validation of the first elem fails. BThe first element is displayed however, as happens in the case of   . Here w's are widgets and r's are returned values  (w1 <* w2) will return Just r1! only if w1 and w2 are validated  (w1 <** w2) will return Just r1 even if w2 is not validated it has a low infix priority: infixr 1 The second elem result (even if it is not validated) is discarded, and the first is returned . This contrast with the applicative operator   which fails the whole validation if the validation of the second elem fails. The second element is displayed however, as in the case of  . see the  examples it has a low infix priority: infixr 1 True if the flow is going back (as a result of the back button pressed in the web browser). Usually this check is nos necessary unless conditional code make it necessary  menu= do mop <- getGoStraighTo case mop of Just goop -> goop Nothing -> do r <- ask option1 <|> option2 case r of op1 -> setGoStraighTo (Just goop1) >> goop1 op2 -> setGoStraighTo (Just goop2) >> goop2This pseudocode below would execute the ask of the menu once. But the user will never have the possibility to see the menu again. To let him choose other option, the code has to be change to  7menu= do mop <- getGoStraighTo back <- e case (mop,back) of (Just goop,False) -> goop _ -> do r <- ask option1 <|> option2 case r of op1 -> setGoStraighTo (Just goop1) >> goop1 op2 -> setGoStraighTo (Just goop2) >> goop2However this is very specialized. Normally the back button detection is not necessary. In a persistent flow (with step) even this default entry option would be completely automatic, since the process would restart at the last page visited. 0Will prevent the Suprack beyond the point where  is located. If the user press the back button beyond that point, the flow parameter is executed, usually it is an ask statement with a message. If the flow is not going back, it does nothing. It is a cut in Supracking [It is useful when an undoable transaction has been commited. For example, after a payment. IThis example show a message when the user go back and press again to pay  ask $ wlink () << b << "press here to pay 100000 $ " payIt preventGoingBack . ask $ b << "You paid 10000 $ one time" ++> wlink () << b << " Please press here to complete the proccess" ask $ wlink () << b << "OK, press here to go to the menu or press the back button to verify that you can not pay again" where payIt= liftIO $ print "paying" executes the first computation when going forward and the second computation when backtracking. Depending on how the second computation finishes, the flow will resume forward or backward. less powerful version of : The second computation simply undo the effect of the first one, and the flow continues backward ever. It can be used as a rollback mechanism in the context of long running transactions. 5Set user-defined data in the context of the session. yThe data is indexed by type in a map. So the user can insert-retrieve different kinds of data in the session context. This example define  addHistory and  getHistory2 to maintain a Html log in the session of a Flow: newtype History = History ( Html) deriving Typeable setHistory html= setSessionData $ History html getHistory= getSessionData `onNothing` return (History mempty) >>= \(History h) -> return h addHistory html= do html' <- getHistory setHistory $ html' `mappend` html :Get the session data of the desired type if there is any. hgetSessionData specialized for the View monad. if Nothing, the monadic computation does not continue. Return the session identifier 2Return the user language. Now it is fixed to "en" Set the header-footer that will enclose the widgets. It must be provided in the same formatting than them, although with normalization to ByteStrings any formatting can be used 2This header uses XML trough Haskell Server Pages ( &http://hackage.haskell.org/package/hsp)  XsetHeader $ c -> <html> <head> <title> my title </title> <meta name= "Keywords" content= "sci-fi" />) </head> <body style= "margin-left:5%;margin-right:5%"> <% c %> </body> </html> This header uses  Text.XHtml  setHeader $ c -> thehtml << (header << (thetitle% << title +++ meta ! [name6 "Keywords",content "sci-fi"])) +++ body ! [style& "margin-left:5%;margin-right:5%"] c /This header uses both. It uses byteString tags setHeader $ c -> S [] $ R# "head" [] $ (i (thetitle << title) append i  meta$name= "Keywords" content= "sci-fi" /) append T2 [("style", "margin-left:5%;margin-right:5%")] c Return the current header 0Add another header embedded in the previous one Set an HTTP cookie Set an HTTP Response header Set 1) the timeout of the flow execution since the last user interaction. Once passed, the flow executes from the beginning. 2) In persistent flows it set the session state timeout for the flow, that is persistent. If the flow is not persistent, it has no effect. OAs the other state primitives, it can be run in the Flow and in the View monad A2 flows restart anew. persistent flows (that use  a) restart at the last saved execution point, unless the session time has expired for the user. Cached widgets operate with widgets in the Identity monad, but they may perform IO using the execute instance of the monad m, which is usually the IO monad. execute basically "sanctifies" the use of unsafePerformIO for a transient purpose such is caching. This is defined in Data.TCache.Memoization>. The programmer can create his own instance for his monad. With  it is possible to cache the rendering of a widget as a ByteString (maintaining type safety) , permanently or for a certain time. this is very useful for complex widgets that present information. Specially it they must access to databases.  import MFlow.Wai.Blaze.Html.All import Some.Time.Library addMessageFlows [(noscript, time)] main= run 80 waiMessageFlow time=do ask $ cachedWidget "time" 5 $ wlink () b << "the time is " ++ show (execute giveTheTime) ++ " click here" time this pseudocode would update the time every 5 seconds. The execution of the IO computation giveTheTime must be executed inside the cached widget to avoid unnecesary IO executions. >NOTE: the rendering of cached widgets are shared by all users A shorter name for  Unlike 7, which cache the rendering but not the user response, wfreeze cache also the user response. This is useful for pseudo-widgets which just show information while the controls are in other non freezed widgets. A freezed widget ever return the first user response It is faster than 0. It is not restricted to the Identity monad. =NOTE: the content of freezed widgets are shared by all users Execute the Flow, in the  FlowM view m# monad. It is used as parameter of hackMessageFlow waiMessageFlow or B OThe flow is executed in a loop. When the flow is finished, it is started again zmain= do addMessageFlows [("noscript",transient $ runFlow mainf)] forkIO . run 80 $ waiMessageFlow adminLoop Run a persistent flow inside the current flow. It is identified by the procedure and the string identifier. Unlike the normal flows, that run within infinite loops, runFlowIn executes once. In subsequent executions, the flow will get the intermediate responses from the log and will return the result without asking again. This is useful for asking once, storing in the log and subsequently retrieving user defined configurations by means of persistent flows with web formularies. To unlift a FlowM computation. useful for executing the configuration generated by runFLowIn outside of the web flow (FlowM) monad Run a transient Flow from the IO monad. runNav :: String -> FlowM Html IO () -> IO () runNav ident f= exec1 ident $ runFlowOnce (transientNav f) undefined Clears the environment 1clear the request paramenters and the rest path. Stores the result of the flow in a persistent log. When restarted, it get the result from the log and it does not execute it again. When no results are in the log, the computation is executed. It is equivalent to  but in the FlowM monad. To execute transient flows as if they were persistent, it can be used instead of step, but it does log nothing. Thus, it is faster and convenient when no session state must be stored beyond the lifespan of the server process. 3transient $ runFlow f === runFlow $ transientNav f Rreturn the value of a post or get param in the form ?param=value&param2=value2... VRequirements are JavaScripts, Stylesheets or server processes (or any instance of the b[ class) that are included in the Web page or in the server when a widget specifies this. requires is the procedure to be called with the list of requirements. Various widgets in the page can require the same element, MFlow will install it once. OInsert a form tag if the widget has form input fields. If not, it does nothing QGenerate a new string. Useful for creating tag identifiers and other attributes. BIf the page is refreshed, the identifiers generated are the same. 9Get the next identifier that will be created by genNewId Z[\]^_`abcdefghijklmnopqrstuvwxyz{|}~name value path 1Max-Age in seconds. Nothing for a session cookie name value path 1Max-Age in seconds. Nothing for a session cookie name value path 1Max-Age in seconds. Nothing for a session cookie name value /The key of the cached object for the retrieval 8Timeout of the caching. Zero means the whole server run )The cached widget, in the Identity monad The cached result /The key of the cached object for the retrieval /Timeout of the caching. Zero means sessionwide )The cached widget, in the Identity monad The cached result /The key of the cached object for the retrieval /Timeout of the caching. Zero means sessionwide The cached widget The cached result       !"#$%&'Z[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'&%$#"! ~}|{zyxhijklmnopqrstuvwdgfebc`a Z_^]\[    Z_^]\[`abcdgfehijklmnopqrstuvwxyz{|}~      !"#$%&' None+3("To delete all previous directives )Add no-cache to the  Cache-Control< header directive. It deletes all expires and put max-age=0 /It means that the widget need not to be cached *Add  no-cache: string( to the Cache-Control header directive ^It deletes the header string (sensible cookies for example) from the data stored in the cache +Add no-store to the  Cache-Control header directive. It deletes expires and put  max-age: 0 4Stronger kind of noCache. Not even store temporally ,Add  expires: datestring to the  Cache-Control header directive. it deletes max-age+ Currently it takes the last one if many (The page will be cached until this date -Add  max-age: seconds to the  Cache-ControlH header directive. if there are more than one, it chooses the lower one @The page will be stored in the cache for that amount of seconds .Add private to the  Cache-Control header directive. it delete public if any PIt means that the page that holds the widget must not be shared by other users. /Add public to the  Cache-Control header directive. BMeans that the cache can share the page content with other users. 0Add sMaxAge seconds to the  Cache-Control0 header directive. if many, chooses the minimum YSpecify the time to hold the page for intermediate caches: for example proxies and CDNs. 1Add  noTransform to the  Cache-Control header directive. MTell CDNs that the content should not be transformed to save space and so on  add mustRevalidate to the  Cache-Control header directive. 5The cache must verify that the page has not changed. 2Add proxyRevalidate to the  Cache-Control header directive. >The same than mustRevalidate, for shared caches (proxies etc) 3Add etag string to the header directives. MIt is a resource identifier for the page that substitutes the URL identifier 4Add vary string to the header directives. Usually the page add this identifier to the URL string, that is the default identifier So the same page with different etags will be cached and server separately 5NReturn the composition of the current directives. Used by the page internally !()*+,-./01 2345()*+,-./012345(5)*+,-./01234 ()*+,-./01 2345None+23468:=JKM96AValidates a form or widget result against a validating procedure getOdd= getInt Nothing 6Q (x -> return $ if mod x 2==0 then Nothing else Just "only odd numbers, please")7rActions are callbacks that are executed when a widget is validated. A action may be a complete flow in the flowM monad. It takes complete control of the navigation while it is executed. At the end it return the result to the caller and display the original calling page. It is useful when the widget is inside widget containers that may treat it as a black box. GIt returns a result that can be significant or, else, be ignored with  and G. An action may or may not initiate his own dialog with the user via f 8Wchange the rendering and the return value of a page. This is superseded by page flows. 91Display a text box and return a non empty String :hDisplay a text box and return an Integer (if the value entered is not an Integer, fails the validation) ;_Display a text box and return a Int (if the value entered is not an Int, fails the validation) <Display a password box =lImplement a radio button that perform a submit when pressed. the parameter is the name of the radio group >HImplement a radio button the parameter is the name of the radio group ?:encloses a set of Radio boxes. Return the option selected @cDisplay a text box and return the value entered if it is readable( Otherwise, fail the validation) AbRead the checkboxes dynamically created by JavaScript within the view parameter see for example selectAutocomplete in MFlow.Forms.Widgets E4Display a multiline text box and return its content FDisplay a dropdown box with the two values (second (true) and third parameter(false)) . With the value of the first parameter selected. GzDisplay a dropdown box with the options in the first parameter is optionally selected . It returns the selected option. H<Set the option for getSelect. Options are concatenated with  IESet the selected option for getSelect. Options are concatenated with  J0upload a file to a temporary file in the server "The user can move, rename it etc. K*Enclose Widgets within some formatting. view7 is intended to be instantiated to a particular format  NOTE: It has a infix priority : infixr 5 less than the one of ++> and <++ of the operators, so use parentheses when appropriate, unless the we want to enclose all the widgets in the right side. Most of the type errors in the DSL are due to the low priority of this operator. FThis is a widget, which is a table with some links. it returns an Int  import MFlow.Forms.Blaze.Html tableLinks :: View Html Int table ! At.style "border:1;width:20%;margin-left:auto;margin-right:auto" <<< caption << text "choose an item" ++> thead << tr << ( th << b << text "item" <> th << b << text "times chosen") ++> (tbody <<< tr ! rowspan "2" << td << linkHome ++> (tr <<< td <<< wlink IPhone (b << text "iphone") <++ td << ( b << text (fromString $ show ( cart V.! 0))) <|> tr <<< td <<< wlink IPod (b << text "ipad") <++ td << ( b << text (fromString $ show ( cart V.! 1))) <|> tr <<< td <<< wlink IPad (b << text "ipod") <++ td << ( b << text (fromString $ show ( cart V.! 2)))) ) L#Append formatting code to a widget   getString "hi" L H1 << "hi there"It has a infix priority: infixr 6 higher than K and most other operators. M$Prepend formatting code to a widget  bold << "enter name" M 9  It has a infix priority: infixr 6 higher than K and most other operators N.Add attributes to the topmost tag of a widget It has a fixity infix 8 O:Is an example of login/register validation form needed by Y5. In this case the form field appears in a single line. it shows, in sequence, entries for the username, password, a button for logging, a entry to repeat password necessary for registering and a button for registering. The user can build its own user login/validation forms by modifying this example  userFormLine= (User <$> getString (Just "enter user") <*> getPassword <+> submitButton "login") <+> fromStr " password again" +> getPassword <* submitButton "register" P>Example of user/password form (no validation) to be used with Y QYEmpty widget that does not validate. May be used as "empty boxes" inside larger widgets. It returns a non valid value. Rca synonym of noWidget that can be used in a monadic expression in the View monad does not continue S(Render a Show-able value and return it TERender raw view formatting. It is useful for displaying information. V&If the user is logged or is anonymous W#return the result if going forward ^If the process is backtracking, it does not validate, in order to continue the backtracking Xforces backtracking if the widget validates, because a previous page handle this widget response . This is useful for recurrent cached widgets or qs that are present in multiple pages. For example in the case of menus or common options. The active elements of this widget must be cached with no timeout. YNIt creates a widget for user login/registering. If a user name is specified in the first parameter, it is forced to login/password as this specific user. If this user was already logged, the widget return the user without asking. If the user press the register button, the new user-password is registered and the user logged. Z@Uses 4 different keys to encrypt the 4 parts of a MFlow cookie. [/Uses a single key to encrypt the MFlow cookie. \change the user 0It is supposed that the user has been validated !!logout. The user is reset to the 4 user b8If not logged, perform login. otherwise return the user +getUserSimple= getUser Nothing userFormLinecVery basic user authentication. The user is stored in a cookie. it looks for the cookie. If no cookie, it ask to the user for a Ked user-password combination. The user-password combination is only asked if the user has not logged already otherwise, the stored username is returned. )getUser mu form= ask $ userWidget mu formdAuthentication against Ked users. to be used with 6 e-for compatibility with the same procedure in $. This is the non testing version  askt v w= ask w hide one or the other gA synonym of ask. pMaybe more appropriate for pages with long interactions with the user while the result has little importance. hCreates a stateless flow (see @S) whose behavior is defined as a widget. It is a higher level form of the latter iWrap a widget with form element within a form-action element. Usually this is not necessary since this wrapping is done automatically by the View; monad, unless there are more than one form in the page. lInstall the server code and return the client code for an AJAX interaction. It is very lightweight, It does no t need jQuery. LThis example increases the value of a text box each time the box is clicked  ask $ do let elemval= "document.getElementById('text1').value" ajaxc <- ajax $ \n -> return $ elemval <> "='" <> B.pack(show(read n +1)) <> "'" b << text "click the box" ++> getInt (Just 0) <! [("id","text1"),("onclick", ajaxc elemval)] mSend the JavaScript expression, generated by the procedure parameter as a ByteString, execute it in the browser and the result is returned back The ajaxSend6 invocation must be inside a ajax procedure or else a No ajax session set error will be produced nLike ajaxSend but the result is ignored pCreates a link to a the next step within the flow. A link can be composed with other widget elements. It can not be broken by its own definition. It points to the page that created it. q"Creates an absolute link. While a p path depend on the page where it is located and ever points to the code of the page that had it inserted, an absLink point to the first page in the flow that inserted it. It is useful for creating a backtracking point in combination with X   page $ absLink "here" << p << "here link" page $ p << "second page" ++> wlink () << p << "click here" page $ p << "third page" ++> retry (absLink "here" << p << "will go back") page $ p << "fourth page" ++> wlink () << p << "will not reach here" After navigating to the third page, when clicking in the link, will backtrack to the first, and will validate the first link as if the click where done in the first page. Then the second page would be displayed. qIn monadic widgets, it also backtrack to the statement where the absLink is located without the need of retry:   page $ do absLink "here" << p << "here link" p << "second statement" ++> wlink () << p << "click here" p << "third statement" ++> (absLink "here" << p << "will present the first statement alone") p << "fourth statement" ++> wlink () << p << "will not reach here" +absLink x = wcached (show x) 0 . wlink x rWhen some user interface return some response to the server, but it is not produced by a form or a link, but for example by an script,  returning% convert this code into a widget. EAt runtime the parameter is read from the environment and validated. . The parameter is the visualization code, that accept a serialization function that generate the server invocation string, used by the visualization to return the value by means of an script, usually. sOConcat a list of widgets of the same type, return a the first validated result t6from a list of widgets, it return the validated ones. uSlike manyOf, but does not validate if one or more of the widgets does not validate wSIntersperse a widget in a list of widgets. the results is a 2-tuple of both types. it has a infix priority infixr 5 xPut a widget before and after other. Useful for navigation links in a page that appears at toAdd and at the bottom of a page. yFlatten a binary tree of tuples of Maybe results produced by the <+> operator into a single tuple with the same elements in the same order. This is useful for easing matching. For example:  ; res <- ask $ wlink1 <+> wlink2 wform <+> wlink3 <+> wlink4res has type:  GMaybe (Maybe (Maybe (Maybe (Maybe a,Maybe b),Maybe c),Maybe d),Maybe e)but  flatten res has type: . (Maybe a, Maybe b, Maybe c, Maybe d, Maybe e)zPrepares the state for a page flow. It add a prefix to every form element or link identifier for the formlets and also keep the state of the links clicked and form input entered within the widget. If the computation within the widget has branches if caseK etc, each branch must have its pageFlow with a distinct identifier. See  Vhttp://haskell-web.blogspot.com.es/2013/06/the-promising-land-of-monadic-formlets.html {3send raw bytestring data to the client. usable for example  do setHttpHeader  Content-Type; "text//plain" maxAge 36000 rawSend longdata i"#$%&'()*+,-./06789:;<=>?@ABCD1EFGHI2J/( original file, file type, temporal uploaded) KLMNOPQRSTUVWXYZ[34567\]^8_`a!bcdefg9:hijkluser defined procedure, executed in the server.Receives the value of the JavaScript expression and must return another JavaScript expression that will be executed in the web browser returns a function that accept a JavaScript expression and return a JavaScript event handler expression that invokes the ajax server procedure ;mnopqrstuvwxyz{<=>?@ABCHKNORSTZ[\]^_`ahijklmnopqrstuvw6789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{hijklmnopqrstuvwKHdVNObcOP_`aYZ[\]^fgehz9;:DEFGHI<?>=oCA@kjBpqJristuTSU6QR78wxvKMLNRST{yWXlmn`aZ_^]\[d"#$%&'()*+,-./06789:;<=>?@ABCD1EFGHI2JKLMNOPQRSTUVWXYZ[34567\]^8_`a!bcdefg9:hijkl;mnopqrstuvwxyz{<=>?@ABCKLMNwxNone24|Used to insert html elements within a tag with the appropriate infix priority for the other operators used in MFlow. Also it can be used for adding markup to widgets with this signature such are p ad H |}||}|}|NoneM~0A small console interpreter with some commands:  sync3Synchronize the cache with persistent storage (see D) flushFlush the cache endSynchronize and exit abortExit. Do not synchronize won exception, for example Control-c, it sync and exits. It must be used as the last statement of the main procedure. Uexecute the process and wait for its finalization. then it synchronizes the cache 7Install the admin flow in the list of flows handled by HackMessageFlow^ this gives access to an administrator page. It is necessary to create an admin user with N. =The administration page is reached with the path "adminserv" E~FGHIJK~~ E~FGHIJKNoneGet the next segment of the REST path. if there is no one or if the data does not match with the type expected, then it return invalid. Therefore a monadic sequence in the View monad will not continue Check that the next rest segment has a certain value. It return invalid otherwise. therefore a monadic sequence in the View monad will not continue 4Get a parameter from a GET or POST key-value input. L1append to the output the result of an expression 1append to the output the result of an expression 9error message when a applicative expression do not match LL None *+234:MPresent a user form if not logged in. Otherwise, the user name and a logout link is presented. The parameters and the behavior are the same as Y". Only the display is different ?Display a logout link if the user is logged. Nothing otherwise dIf not logged, it present a page flow which asks for the user name, then the password if not logged 9If logged, it present the user name and a link to logout Pnormally to be used with autoRefresh and pageFlow when used with other widgets. WReturn the list of edited widgets (added by the active widgets) for a given identifier nDeletes the list of edited widgets for a certain identifier and with the type of the witness widget parameter Return the JavaScript to be executed on the browser to prepend a widget to the location identified by the selector (the bytestring parameter), The selector must have the form of a jQuery expression . It stores the added widgets in the edited list, that is accessed with  5The resulting string can be executed in the browser. lx will return the code to execute the complete ajax roundtrip. This code returned by ajax must be in an event handler. RThis example will insert a widget in the div when the element with identifier  clickelemw is clicked. when the form is submitted, the widget values are returned and the list of edited widgets are deleted.  id1<- genNewId let sel= "$('#" <> fromString id1 <> "')" callAjax <- ajax . const $ prependWidget sel wn let installevents= "$(document).ready(function(){\ \$('#clickelem').click(function(){"++callAjax "''"++"});})" requires [JScriptFile jqueryScript [installevents] ] ws <- getEdited sel r <- (div <<< manyOf ws) <! [("id",id1)] delEdited sel ws' return r Like + but append the widget instead of prepend. Like M but set the entire content of the selector instead of prepending an element Inside a tag, it add and delete widgets of the same type. When the form is submitted or a wlink is pressed, this widget return the list of validated widgets. the event for adding a new widget is attached , as a click event to the element of the page with the identifier  wEditListAdd that the user will choose. PThis example add or delete editable text boxes, with two initial boxes with hi,  how are you as values. Tt uses blaze-html: f r <- ask $ addLink ++> br ++> (El.div `wEditList` getString1 $ ["hi", "how are you"]) "addid" <++ br <** submitButton "send" ask $ p << (show r ++ " returned") ++> wlink () (p << text " back to menu") mainmenu where addLink = a ! At.id "addid" ! href "#" $ text "add" delBox = input ! type_ "checkbox" ! checked "" ! onclick "this.parentNode.parentNode.removeChild(this.parentNode)" getString1 mx= El.div <<< delBox ++> getString mx <++ br dPresent the JQuery auto-completion list, from a procedure defined by the programmer, to a text box. @Produces a text box. It gives a auto-completion list to the textbox. When return is pressed in the textbox, the box content is used to create a widget of a kind defined by the user, which will be situated above of the textbox. When submitted, the result is the content of the created widgets (the validated ones).  is an specialization of this widget, where the widget parameter is fixed, with a checkbox that delete the element when unselected . This fixed widget is as such (using generic FormElem class tags): gftag "div" <<< ftag "input" mempty `attrs` [("type","checkbox") ,("checked","") ,("onclick","this.parentNode.parentNode.removeChild(this.parentNode)")] ++> ftag "span" (fromStr $ fromJust x ) ++> whidden( fromJust x) A specialization of wutocompleteEdit which make appear each chosen option with a checkbox that deletes the element when unchecked. The result, when submitted, is the list of selected elements. UCreates a rich text editor around a text field or a text area widget. This code:  page $ p "Insert the text" ++> htmlEdit ["bold","italic"] "" (getMultilineText "" <! [("rows","3"),("cols","80")]) <++ br <** submitButton "enter" qCreates a rich text area with bold and italic buttons. The buttons are the ones added in the nicEdit editor. A widget that display the content of an html, But if the user has edition privileges, it permits to edit it in place. So the editor could see the final appearance of what he writes. When the user click the save, the content is saved and identified by the key. Then, from now on, all the users will see the saved content instead of the code content. +The content is saved in a file by default (texts; in this versions), but there is a configurable version ( tFieldGenu). The content of the element and the formatting is cached in memory, so the display is, theoretically, very fast. Ka text field. Read the cached field value and present it without edition. 6A multilanguage version of tFieldEd. For a field with keyA it add a suffix with the two characters of the language used. "A multilanguage version of tField Permits to iterate the presentation of data and//or input fields and widgets within a web page that does not change. The placeholders are created with dField. Both are widget modifiers: The latter gets a widget and create a placeholder in the page that is updated via ajax. The content of the update is the rendering of the widget at each iteration. The former gets a wider widget which contains dField elements and permit the iteration. Whenever a link or a form within the witerate widget is activated, the result is the placeholders filled with the new html content. This content can be data, a input field, a link or a widget. No navigation happens. This permits even faster updates than autoRefresh. since the latter refresh the whole widget and it does not permits modifications of the layout at runtime. When edTemplate or template is used on top of witerate, the result is editable at runtime, and the span placeholders generated, that are updated via ajax can be relocated within the layout of the template. Additionally, contrary to some javascript frameworks, the pages generated with this mechanism are searchable by web crawlers. ,Present a widget via AJAX if it is within a  context. In the first iteration it present the widget surrounded by a placeholder. subsequent iterations will send just the javascript code necessary for the refreshing of the placeholder. permits the edition of the rendering of a widget at run time. Once saved, the new rendering becomes the new rendering of the widget for all the users. You must keep the active elements of the template vthe first parameter is the user that has permissions for edition. the second is a key that identifies the template. =Does the same than template but without the edition facility present the JQuery datePicker calendar to choose a date. The second parameter is the configuration. Use "()" by default. See  http://jqueryui.com/datepicker/ present a jQuery dialog with a widget. When a button is pressed it return the result. The first parameter is the configuration. To make it modal, use "({modal: true})" see  http://jqueryui.com/dialog/% for the available configurations. cThe enclosed widget will be wrapped within a form tag if the user do not encloses it using wform.f Capture the form or link submissions and send them via jQuery AJAX. The response is the new presentation of the widget, that is updated. No new page is generated but the functionality is equivalent. Only the activated widget rendering is updated in the client, so a widget with autoRefresh can be used in heavyweight pages. If AJAX/JavaScript are not available, the widget is refreshed normally, via a new page. MautoRefresh encloses the widget in a form tag if it includes form elements. EIf there are more than one autoRefresh, they must be enclosed within z elements <In some cases, it is necessary that a link or form inside a  or M! block should not be autorefreshed, since it produces side effects in the rest of the page that affect to the rendering of the whole. If you like to refresh the whole page, simply add noAutoRefresh attribute to the widget to force the refresh of the whole page when it is activated. 4That behavior is common at the last sentence of the  block.  This is a cascade menu example.  O r <- page $ autoRefresh $ ul <<< do li <<< wlink OptionA << "option A" ul <<< li <<< (wlink OptionA1 << "Option A1" <! noAutoRefresh) <|> li <<< (wlink OptionA2 << "Option A2" <! noAutoRefresh) <|>... maybe other content case r of OptionA1 -> pageA1 OptionA2 -> pageA2 when option A is clicked, the two sub-options appear with autorefresh. Only the two lines are returned by the server using AJAX. but when Option A1-2 is pressed we want to present other pages, so we add the noAutorefresh attribute. 9NOTE: the noAutoRefresh attribute should be added to the  a/ or  form/ tags. does the same than C but append the result of each request to the bottom of the widget  all the comments and remarks of  apply here does the same than J but prepend the result of each request before the current widget content  all the comments and remarks of  apply here jcontinuously execute a widget and update the content. The update method specify how the update is done.  means a substitution of content. The second parameter is the delay for the next retry in case of disconnection, in milliseconds. LIt can be used to show data updates in the server. The widget is executed in a different process than the one of the rest of the page. Updates in the session context are not seen by the push widget. It has his own context. To communicate with the widget, use DBRef's or TVar and the STM semantics for waiting updates using X. Widgets in a push can have links and forms, but since they are asynchronous, they can not return inputs. but they can modify the server state. push ever return an invalid response to the calling widget, so it never triggers the advance of the navigation. 1This example is a counter increased each second:  pushIncrease= do tv <- liftIO $ newTVarIO 0 page $ push 0 Html $ do n <- atomic $ readTVar tv atomic $ writeTVar tv $ n + 1 liftIO $ threadDelay 1000000 b << (show n) ++> noWidget <This other simulates a console output that echoes what is entered in a text box below. It has two widgets: a push output in append mode and a text box input. The communication uses a TVar. The push widget wait for updates in the TVar. because the second widget uses autoRefresh, all happens in the same page. LIt is recommended to add a timeout to the push widget, like in the example: @ pushSample= do tv <- liftIO $ newTVarIO $ Just "init" page $ push Append 1000 (disp tv) <** input tv where disp tv= do setTimeouts 100 0 line <- tget tv p << line ++> noWidget input tv= autoRefresh $ do line <- getString Nothing <** submitButton "Enter" tput tv line tput tv x = atomic $ writeTVar tv ( Just x) !> "WRITE" tget tv= atomic $ do mr <- readTVar tv case mr of Nothing -> retry Just r -> do writeTVar tv Nothing return r fshow the jQuery spinner widget. the first parameter is the configuration . Use "()" by default. See  http://jqueryui.com/spinner takes as argument a widget and delay the load until it is visible. The rendering to be shown during the load is the specified in the first parameter. The resulting lazy widget behaves programatically in the same way. wIt can lazily load recursively. It means that if the loaded widget has a lazy statement, it will be honored as well. mBecause a widget can contain arbitrary HTML, images or javascript, lazy can be used to lazy load anything. To load a image: 1lazy temprendering $ wraw ( img ! href imageurl) or 6lazy temprendering $ img ! href imageurl ++> noWidget BNOPQRSTUVWXYZ[\ identifier witness ]^jQuery selector widget to prepend Estring returned with the jQuery string to be executed in the browser The holder tag :the contained widget, initialized by a value of its type The initial list of values. NThe id of the button or link that will create a new list element when clicked Initial value NAuto-completion procedure: will receive a prefix and return a list of strings the initial text of the box Lthe auto-completion procedure: receives a prefix, return a list of options. Bthe widget to add, initialized with the string entered in the box initial set of values resulting widget _`abcdMefgh'':NOPQRSTUVWXYZ[\]^_`abcdMefghNone+24:Mijklmnopqrstuvijklmnop ilkjmnopqrstuv None +2346wxyz{|}W  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYwxyz{|} NoneRun a persistent flow. It uses ~ to get the port The first parameter is the first element in the URL path. It also set the home page The port is read from the first parameter passed to the executable. If no parameter, it is read from the PORT environment variable. if this does not exist, the port 80 is used. sExactly the same as runNavigation, but with TLS added. Expects certificate.pem and key.pem in project directory. ~D       !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ahijklmnopqrstuvw()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|~~ None234F:Run a list of flows with a number of simultaneous threads Inject substitutes an expression by other. It may be used to override ask interaction with the user. It should bee used infix for greater readability:  +ask something `inject` const some other sThe parameter passed is the test number if the flow has not been executed by runTest, inject return the original JA simulated ask that generate simulated user input of the type expected. tIt forces the web page rendering, since it is monadic and can contain side effects and load effects to be tested. it is a substitute of  from  MFlow.Forms for testing purposes. $Instead of generating a result like X, the result is given as the first parameter so it does not need a Generate instance. vIt forces the web page rendering, since it is monadic so it can contain side effects and load effects to be tested. 9verify a property. if not true, throw the error message. It is intended to be used in a infix notation, on the right of the code, in order to separate the code assertions from the application code and make clearly visible them as a form of documentation. Separated from it:  JliftIO $ print (x :: Int) `verify` (return $ x > 10, "x < = 10") YThe expression is monadic to allow for complex verifications that may involve IO actions a pure version of verifyM              !"#$%&'()*++,-../0123456789:9;<<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                q   e n o      !"#$%&'()*+,-./00112233456789:;<=>?@ABCDE FGHIJKLMN O P P Q Q R S S T U V W X Y Z [ \ ] ^ _ ` a b c d e f ghhijklmnopqrst u v w x y z { |} ~                  %                        !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcbdbefegeheiejekelemeneoepeqereseZeteuevewexeyeze{e|e}e~eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee    C       MFlow-0.4.5.13 MFlow.Forms MFlow.CookiesMFlowMFlow.Forms.InternalsMFlow.Forms.CacheMFlow.Forms.Blaze.HtmlMFlow.Forms.AdminMFlow.Forms.WebApiMFlow.Forms.Widgets MFlow.WaiMFlow.Wai.Blaze.Html.AllMFlow.Forms.Test Data.TCache MemoizationControl.WorkflowstepMFLow.Forms.TestasktMFlow.Wai.ResponsebaseControl.Applicative<*> Data.Functor<$><|><*CookieParanoidCookieEncryptedCookieUnEncryptedCookieCookieT contentHtml cookieuser getCookies cookieHeaders decryptCookieparanoidEncryptCookieparanoidDecryptCookie encryptCookieAttribs PasswdStrUserStrUseruserName upasswordAuth uregister uvalidate ProcessablepwfnamepwfPathpuserpind getParamsParamsProcListHttpDataErrorFlowTokentwfnametusertindtpathtenvtblocktsendqtrecqaddTokenToListdeleteTokenInList anonymousnoScript setNoScriptsend sendFlush sendFragmentsendEndFragmentreceive flushResponseflushRec receiveReqreceiveReqTimeout stateless transientaddMessageFlowsgetMessageFlowsdelMessageFlowsendToMF msgSchedulerhlog setAuthMethod getAuthMethodeUser userRegisterconfig getConfig setAdminUser getAdminNamesetNotFoundResponsegetNotFoundResponsebtagbhtmlbbodyaddAttrs setFilesPath serveFilenewFlow mimeTableWebRequirement ServerProcJScriptCSSCSSFile JScriptFile RequirementsinstallRequirements Requirement ParamResult Validated NotValidatedNoParam FormInput toByteString toHttpDatafromStrfromStrNoEncodeftaginredflinkflink1finput ftextareafselectfoptionfoption1 formActionattrsOnClickCheckedValueTypeNameVoid MFlowState mfSequencemfCachednewAskinSyncmfSomeNotValidatesmfLangmfEnvneedForm mfFileUploadmfToken mfkillTime mfSessionTime mfCookies mfHttpHeadersmfHeadermfDebugmfRequirementsmfInstalledScriptsmfDatamfAjax mfSeqCachenotSyncInActionmfPath mfPagePathmfPrefix mfPageFlow linkMatched mfAutorefreshmfTracemfClearNeedFormNoElemsHasElemsHasFormLangViewrunViewFormElmFlowMMWStateFlowMrunFlowM SupervisesupBack superviseSuprunSupFailBackGoBackNoBack BackPoint!> iCanFailBack repeatPlease noFailBack fromFailBack toFailBackbreturnliftSup wcallback changeMonadmix<+>**>valid<** goingBackpreventGoingBack onBacktrack compensate mFlowState0setSessionDatadelSessionDatagetSessionDatagetSData getSessionIdgetLanggetTokengetEnv stdHeader setHeader getHeader addHeader setCookiesetParanoidCookiesetEncryptedCookiesetEncryptedCookie' setHttpHeader setTimeouts getWFNamegetCurrentUser normalize cachedWidgetwcachedwfreezerunFlow inRecovery runFlowOnce runFlowOnce1 startState runFlowOnce2runFlowOnceReturn runFlowIn runFlowConfclearEnv clearEnv' transientNav valToMaybe isValidated fromValidated getParam1 getRestParamgetKeyValueParam readParamrequiresunfoldinstallAllRequirements loadjsfile loadScript loadCallback loadcssfileloadcssinstallWebRequirementsstrRequirementstrRequirement' ajaxScript formPrefix insertForm controlForms currentPathgenNewId getNextId$fRequirementsWebRequirement $fShow(,)$fOrd(,)$fEq(,)$fShowRequirement$fSerialize(,) $fMonadIOView$fMonadStateMFlowStateView$fMonadTransFlowM$fMonadTransView $fMonoidView $fMonadView$fAlternativeView$fApplicativeView $fFunctorView$fFunctorFormElm$fMonadLocView$fMonadLocFlowM$fSuperviseMFlowStateStateT$fSerializeFormElm$fMonadStatesSup$fMonadTransSup $fFunctorSup $fMonadIOSup$fAlternativeSup$fApplicativeSup $fMonadSup$fSerializeFailBack$fAlternativeFailBack$fApplicativeFailBack$fFunctorFailBackresetCachePolicynoCachenoCache'noStoreexpiresmaxAgeprivatepublicsMaxAge noTransformproxyRevalidateetagvarysetCachePolicyvalidatewactionwmodify getString getIntegergetInt getPasswordsetRadioActivesetRadiogetRadio setCheckBox genCheckBoxeswhidden getCheckBoxes getTextBoxgetMultilineTextgetBool getSelect setOptionsetSelectedOption fileUpload<<<<++++>:>|*>|+|flattenpageFlowrawSend<<$fFormInputMarkupM adminLoopwait addAdminWFrestprestwparamdisp UpdateMethodHtmlPrependAppend tfieldKeyuserFormOrName maybeLogoutwlogin getEdited delEdited setEdited prependWidget appendWidget setWidget wEditList wautocompletewautocompleteEditwautocompleteList writetField readtFieldhtmlEdittFieldEdtFieldmFieldEdmFieldwiteratedField edTemplatetemplate datePickerwdialog autoRefresh noAutoRefresh appendUpdate prependUpdatepush getSpinnerlazywaiMessageFlow runNavigationrunSecureNavigationrunSecureNavigation'GenerategeneraterunTestrunTest1injectverify showCookie showCookie' showMaxAge splitCookiesreadEnv urlEncodedextrasafe hexadecimaldecryptCookie' encryptMaybe decryptMaybe decryptFM cookieToTupledecryptAndToTuplecadmin cjqueryScript cjqueryCSS cjqueryUI cnicEditUrl noScriptRef keyUserNametCacheRegister setConfigdefNotFoundResponse TCache-0.12.0Data.TCache.Defs setPersistNFlowConfig0ConfigConfig1RespEndFragmFragmReq iorefqmapfromReq delMsgHistory _messageFlows recFromMF showError errorMessagelinelogError logFileName _authMethoderror1 userPrefixtCacheRegister'tCacheValidatechange readConfigreadOld keyConfigrconfnotFoundResponse rfilesPathrflow$fSerializableNFlow$fIndexableNFlow$fSerializableConfig$fIndexableConfig$fSerializableUser$fIndexableUser$fProcessableReq$fProcessableToken$fMonoidHttpData$fSerializableToken $fReadToken $fShowToken$fIndexableTokenghc-prim GHC.TypesIO Applicative AlternativeGHC.BaseMonadData.TCache.Memoization cachedByKey*>Workflow-0.8.3mustRevalidate CacheElemVaryETagProxyRevalidateMustRevalidateNoCache' NoTransformSMaxAgeMaxAgeExpiresNoStoreNoCachePublicPrivatesetcompile onNothing Data.MaybeNothinglogout'Tuple6Tuple5Tuple4Tuple3Tuple2Flattendoflat AjaxSessionIdMFOption CheckBoxesRadiogetParam setOption1 userWidget'login1paranoidLogin1encryptedLogin1login1'login' nextMessageisparaminstallServerControl$fFormInputByteString$fFlattenMaybe(,,,,,)$fFlattenMaybe(,,,,)$fFlattenMaybe(,,,)$fFlattenMaybe(,,)$fFlattenMaybe(,)$fMonoidCheckBoxes syncCache ssyncCache adminLoop1 adminMFlowerrorsusers showFormList optionsUserdispvupdate IteratedIdTField tfieldContentMedit jqueryScript jqueryCSSjqueryUI nicEditUrlfocushintsize getEdited1 addEdited modifyWidgetinstallEditField ajaxSendText autoEvalLink autoEvalFormsetIdnoid timeoutscriptrefresh$fSerializableTField$fIndexableTFieldTRespTRespRTRempty ToResponse toResponsemkParamsmkparam$fToResponseHttpData$fToResponse[]$fToResponseByteString$fToResponseResponse$fToResponseTResp $fMonoidTResptoAppflow tvresourcesstatCookieNameputStateCookiegetStateCookie$fProcessableRequestgetPortWpure safeIOToSTM setConditions defaultCheckclearSyncCacheatomicallySync syncWriteclearSyncCacheProcdeleteResourcesdeleteResource getResources getResource withResources withResourcewithSTMResourcesflushAll invalidateKeyflushKey flushDBRefdelDBRefnewDBRefgetDBRef keyObjDBRef writeDBRef readDBRefs readDBRefnumElemsnewCachesetCacheCache Synchronous cacheSizecheck frecuency Asyncronous SyncManualSyncModeData.TCache.Triggers addTriggerDBRefData.TCache.IResource resources delResources delResourcewriteResources writeResource readResourcereadResourcesByKeyreadResourceByKey keyResource IResourceRetrytoReturntoDeletetoAdd Resources GHC.Conc.SyncSTM unsafeIOToSTM atomically<$somemany<**>optionalliftA3liftA2liftAemptygetConstConst unwrapMonad WrapMonad WrappedMonad unwrapArrow WrapArrow WrappedArrow getZipListZipListblaze-markup-0.7.0.2Text.Blaze.Internal!AttributeValue AttributeTagMarkup dataAttributecustomAttributetextpreEscapedTextlazyTextpreEscapedLazyTextstringpreEscapedStringunsafeByteStringunsafeLazyByteString textCommentlazyTextComment stringCommentunsafeByteStringCommentunsafeLazyByteStringCommenttextTag stringTag textValuepreEscapedTextValue lazyTextValuepreEscapedLazyTextValue stringValuepreEscapedStringValueunsafeByteStringValueunsafeLazyByteStringValue!?contents Text.BlazeToValuetoValuepreEscapedToValueToMarkuptoMarkuppreEscapedToMarkupblaze-html-0.8.1.0Text.Blaze.Html5wbrvideovarultracktrtitletimetheadthtfoottextareatdtbodytablesupsummarysubstylestrongspansourcesmallselectsectionscriptsamprubyrtrpqprogresspreparampoutputoptionoptgroupolobjectnoscriptnavmetermetamenuitemmenumarkmainlinklilegendlabelkeygenkbdinsinputimgiframeihtmlhrhgroupheaderheadh6h5h4h3h2h1formfooterfigure figcaptionfieldsetembedemdtdldivdfndetailsdeldddatalistcommandcolgroupcolcodecitecaptioncanvasbuttonbrbody blockquotebdobaudioasidearticleareaaddressabbra docTypeHtmldocTypeText.Blaze.HtmlpreEscapedToHtmltoHtmlText.Blaze.Html5.Attributesxmlnswrapwidthvalueusemaptype_targettabindexsubjectstartsrcdocsrc spellchecksizesshapeselectedseamlessscopedscopesandboxrowspanrowsreversedrequiredrelreadonly radiogrouppubdatepreload placeholderpingpatternoptimumopen onwaitingonvolumechangeonunloadonundo ontimeupdate onsuspendonsubmit onstorage onstalledonselect onseekingonseekedonscrollonresizeonredoonreadystatechange onratechange onpropstate onprogress onplayingonplayonpause onpageshow onpagehideononline onmousewheel onmouseup onmouseover onmouseout onmousemove onmousedown onmessage onloadstartonloadedmetadata onloadeddataonloadonkeyup onkeydown oninvalidoninput onhaschange onforminput onformchangeonfocusonerroronended onemptiedondurationchangeondrop ondragstart ondragover ondragleave ondragenter ondragendondrag ondblclick oncontextmenuonclickonchangeoncanplaythrough oncanplayonblur onbeforeprintonbeforeonload novalidatenamemultipleminmethodmedia maxlengthmaxmanifestlowlooplistlangkeytypeitemtype itemscopeitempropitemismapidicon httpEquivhreflanghrefhighhiddenheightheaders formtargetformnovalidate formmethod formenctype formactionforenctype draggabledisableddirdeferdatetimedata_coordscontrols contextmenucontenteditablecontentcolspancolsclass_checkedcharset challengeautoplay autofocus autocompleteasyncaltaction accesskey acceptCharsetaccepttransformers-0.4.3.0Control.Monad.IO.ClassMonadIOliftIOverifyM testNumber getTestNumber $fGeneratea $fGenerate(,)$fGenerate(,)0$fGenerateInteger $fGenerateInt $fGenerate[]$fGenerateMaybe