<commit_before>STAP (Simple Task-Actor Protocol)
version 7.10


    Message Type        Regular Expression                                  Functionality
    ** task -> user **  <<container>>                                       update current display container with values in <<container>>
    ** task -> user **  null                                                clear the display container
    ** task -> user **  {<<taskOption>>(,<<taskOption>>)*}                  optional task commands/properties
    ** user -> task **  [<<ums>>,<<id>>,<<value>>]                          user-side action (e.g. button-click, textbox edit); second field corresponds to the <<id>> of the item that is manipulated by user; <<id>> doesn't exist, <<itemNum>> is sent; <<value>> must be of a type consistent with this item (e.g. for boolean items value must be a boolean)
    ** user -> task **  [<<ums>>,<<id>>,<<userEvent>>]                      user-side event (e.g. load/unload, captured key or mouse event); second field corresponds to the <<id>> of the item that is manipulated by user; <<id>> doesn't exist, <<itemNum>> is sent

    Label Name          Regular Expression                                  Functionality
    <<container>>       [<<item>>(,<<item>>)*]                              array of item updates
    <<item>>            <<value>>|{<<property>>(,<<property>>)*}            an item may be declared by value or a set of properties
    <<property>>        "v":<<value>>                                       set item value; ["hello world"] is just shorthand for [{"v":"hello world"}]
    <<property>>        "id":<<id>>                                         item unique id or order number within the current container; if item specified by id doesn't exist, it is appended to the container; root-level display container has no id
    <<id>>              <<text>>                                            unique item key; <<id>> text is displayed as item title text (unless "title" optional property is specified, see below); e.g. [{"id":"Name","v":"Bob"},{"id":"Age","v":77}] adds two key:value pairs to the UI -- Name:Bob and Age:77, and [{"id":"Age","v":78}] would change the value for Age from 77 to 78
    <<id>>              <<uint>>                                            item order number within the current container; item numbering in a container begins at 0, thus {"id":0} is the first item in a given container; if <<uint>> is greater or equal to current number of items in the container, corresponding value is appended as the last item in the container
    <<value>>           <<text>>|<<number>>|<<boolean>>|<<container>>       item value may be text, number, boolean (signifying buttons/options), or an array of items
    <<value>>           null                                                value of null removes item from container; e.g., [{"id":0,"v":null}] will remove the first item from the display
    <<ums>>             <<uint>>                                            time in milliseconds since the initiation of user software (e.g. onload event)
    <<text>>            ** see JSON string specification, e.g. http://json.org **
    <<number>>          ** see JSON number specification, e.g. http://json.org **
    <<uint>>            ** integer >= 0 **
    <<boolean>>         (true)|(false)

everything above is core-STAP; all user-side sw must be able to handle the format specified above for simple text+button tasks

==

everything below specifies optional directives that enable more featureful user-interface interactions

    <<taskOption>>      "require":{<<required>>(,<<required>>)*}            should be sent once before task begins; specify which options and option values are required for correctly interpreting current task; if any of the <<required>> items are not implemented yet in the user software, the suggested behavior is to disconnect from task after a polite [<<ums>>,0,{"error":"sorry, <<required>> is not yet implemented on this side"}]
    <<taskOption>>      "error":<<text>>                                    error message to be dumped into user-side error stream
    <<taskOption>>      "template":<<url>>|<<js>>                           likely sent once before task begins (may be ignored by computational agents); custom visualization template for STAP messages (e.g. CSS or JS text or url); Template command may be called multiple times to load multiple parts of a template
    <<taskOption>>      "agent":[<<userInfo>>(,<<userInfo>>)*]              likely sent once before task begins; request information about user-side software; the polite thing for user-side software to do would be to reply to "client" <<taskOption>> with as much information as possible, but task-side code should not be dependent on this; participant replies to this request as such: [<<ums>>,0,{"clientinfo":<<json>>}]; e.g. a response to {"clientinfo":["ip","url","screen","userAgent"]} may be [<<ums>>,0,{"clientinfo":{"ip":"172.16.58.3","url":"http://localhost:8080/stap.html","screen":{"availWidth":1524,"availHeight":900,"width":1600,"height":900,"colorDepth":24,"pixelDepth":24,"availLeft":0,"availTop":0,"orientation":{"angle":0}},"userAgent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"}}]
    <<taskOption>>      "task":{"(win)|(loss)|(end)":<<conds>>}             likely sent once before task begins; win, loss, and neutral task-end conditions; suggested user-sw behavior for human participants is to convert <<conds>> into natural language and display as "Instructions"
    <<taskOption>>      "task":{"(good)|(bad)":<<conds>>}                   likely sent once before task begins; goal values (what to seek, what to avoid); suggested user-sw behavior for human participants is to convert <<conds>> into natural language and display as "Instructions"
    <<conds>>           [<<cond>>|<<condAnd>>(,<<cond>>|<<condAnd>>)*]      <<conds>> list is True if any of the items in it are True
    <<condAnd>>         [<<cond>>(,<<cond>>)*]                              <<condAnd>> list is True if ALL of the items in it are True
    <<cond>>            [<<id>>(,"<|>|(<=)|(>=)|(!=)")?,<<number>>|<<text>>]
    <<userInfo>>        "ip"                                                request client ip address
    <<userInfo>>        "userAgent"                                         request information about user-side software (e.g. webbrowser type/version, AI architecture type/version)
    <<userInfo>>        "url"                                               request client url (relevant when user-side software runs in a webbrowser)
    <<userInfo>>        "screen"                                            find out total user screen size (for human participants this would be different from <<eventType>> 13, which only sends back current <<container>> size)
    <<userEvent>>       {(<<userInfo>>:<<json>>)}                           response to "Agent" <<taskOption>>; e.g. a response to {"Agent":["ip","url","screen","userAgent"]} may be a series of messages, such as [<<ums>>,0,{"ip":"172.16.58.3"}] [<<ums>>,0,{"url":"http://localhost:8080/stap.html"}] [<<ums>>,0,{"screen":{"availWidth":1524,"availHeight":900,"width":1600,"height":900,"colorDepth":24,"pixelDepth":24,"availLeft":0,"availTop":0,"orientation":{"angle":0}}}] [<<ums>>,0,{"userAgent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"}]
    <<userEvent>>       {"error":<<text>>}                                  user->task messages that contain this directive are dumped into task-side error stream
    <<userEvent>>       [0]                                                 load event to indicate that user-side sw is ready
    <<json>>            ** see full JSON specification, e.g. http://json.org **
    <<url>>             ** legal url **
    <<js>>              ** legal javascript **
    <<html>>            ** legal text/html **


everything above is core-STAP; although task-options can be ignored in many cases, user-side sw must still expect them as potentially incoming messages, and be willing to quit if it cannot handle any of the items specified via the "require" task option

==

everything below can be negotiated via the "require" <<taskOption>>; if task requires options that user sw cannot handle, user software can disconnect

- if a <<property>> is specified for a container (or a container-type, such as table or popup), and it is not applicable to containers, this <<property>> is inherited by all decendent elements; e.g. [{"id":"my container","v":[1,2,{"id":"more","v":[3,4]}],"rnd":1}] signifies that all numeric values in the container "my container", including those in the "more" container, are rounded to 1 (integers)

    Label Name          Regular Expression                                  Functionality
    <<required>>        "options":[<<optionName>>(,<<optionName>>)*]        specify options necessary for this task; e.g., {"required":{"options":["r","rot"]}}
    <<required>>        <<optionName>>:[<<optionVal>>(,<<optionVal>>)*]     specify option values necessary for this task; e.g., {"required":{"select":[1,2,"n"],"type":["table","path"]}}
    <<required>>        "e":[<<eventType>>(,<<eventType>>)*]                specify event types necessary for this task; e.g., {"required":{"e":[40,44]}}
    <<required>>        "colors":<<uint>>                                   specify how many different preset colors are necessary for this task; <<uint>> must be greater than 1 (presets 0 and 1 are default background and text colors); e.g., {"required":{"colors":3}} signifies that the task will require 2 different colors in addition to the background and text colors
    <<required>>        "sizeUnits":["<<sizeUnit>>"(,"<<sizeUnit>>")*]      specify size-units necessary for this task; e.g., {"required":{"sizeUnits":["%","E","vh","vw"]}}
    <<required>>        "emphases":{<<emp>>:<<uint>>(,<<emp>>:<<uint>>)*}   specify emphasis types necessary for this task; e.g., {"required":{"emphases":{"emp":3,"emp2":3}}} signifies that two emphases types are required (emp and emp2), each with three levels of strength
    <<emp>>             ** text string starting with "emp"; e.g. "emp2" **
    <<optionName>>      ** the part to the left of the colon in the <<property>> or <<taskOption>> expression; e.g. "S", "eB", "bg" **
    <<optionVal>>       ** the part to the right of the colon in the <<property>> or <<taskOption>> expression **

    <<taskOption>>      <<property>>                                        optional properties for top-level container

    <<property>>        <<optionName>>:null                                 remove/reset property (i.e. clear or reset to default behavior)
    <<property>>        <<command>>                                         commands that alter how other properties are changed; <<command>> property values are not permanent; e.g. [{"id":"x","T":10,"bg":"blue"}] signifies that the background of "x" should be changed to blue over the course of 10seconds, after which the value of "bg" (background) remains "blue", but the value "T" (time of animation) resets to null, because "T" is an <<command>> option
    <<property>>        <<option>>                                          generic options
    <<property>>        <<inputOption>>                                     user-input options (specify whether item value is editable, and what the behavior is upon edits)
    <<property>>        <<boolOption>>                                      boolean item options
    <<property>>        <<numOption>>                                       number item options
    <<property>>        <<txtOption>>                                       text item options
    <<property>>        <<aniOption>>                                       animation options

    <<command>>         "$":<<id>>|<<tag>>                                  select items; apply current updates to all of the items that match by <<id>>, or <<tag>>; search is recursive, not just in current container
    <<command>>         "$":{<<property>>(,<<property>>)*}                  select items; apply current updates to all of the items that match by where all <<property>> values match; search is recursive, not just in current container; selection by "type" property is allowed for items with both explicit and derived types; e.g., {"$":{"type":0},"v":0} would set all numeric values to 0's, {"$":{"v":1},"v":0} would set all 1's to 0's, {"$":"x","bg":"red"} would find all items where id is "x" or one of the tags (specified via "#") is "x" and set their background colors to "red", [{"id":"my container","v":[{"$":{"type":[]},"bg":"blue"}]}] will set backgrounds of all containers inside of "my container" to blue
    <<command>>         "$":true                                            select ALL items (recursively); apply current updates to all items in current container and all their descendents; e.g. {"$":true,"emp":1} sets emphasis to 1 for every single item in display
    <<command>>         "$":false                                           select all items in current container (NOT recursively); apply current updates to all items in current container; e.g. [{"id":"x","v":[{"$":false,"emp":1}]}] sets emphasis to 1 for every item in container "x"
    <<command>>         "O":1                                               Onedit/onsubedit trigger for current update (i.e. pretend as if there was a user-side input); useful for playback, demo, instructions; e.g. task->user messages [{"id":"press me","v":false,"onedit":null}] [{"id":"press me","v":true,"O":1}] would add a button, one that would disappear once clicked, and then force-click the button, causing it to disappear
    <<command>>         "P":<<itemNum>>|<<id>>                              Push (i.e. insert) current item before item specified by <<itemNum>> or <<id>> in current container; e.g. ["a","b","c"] followed by [{"v":"x","P":1}] is equivalent to ["a","x","b","c"]
    <<command>>         "Q":<<number>>|<<text>>                             Queue identifier for current update; useful for queued (delayed or animated) updates triggered via S, T, or U commands; e.g. the following two task->user messages -- [{"id":"candles","v":0},{"id":"candles","v":1,"Q":"t1","U":10000,"R":1},{"id":"candles","v":2,"Q":"t2","U":20000,"R":1}] and [{"Q":"t1":,"U":null}] -- would result in a key:value pair "candles":0 being added to display, and timers set up to change the value of "candles" to 1 at 10sec, then to 2 at 20sec into the task, then the 10sec timer is removed, but the 20sec timer for the same item remains, and user sw ends up sending the following message back 20s into the task -- [20000,"t2",[1]]
    <<command>>         "R":1|2|3                                           Receipt request for current update; 1 indicates a receipt is required when property change(s) begin -- user->task message: [<<ums>>,<<id>>,[1]]; 2 indicates a receipt is required when property change(s) end, after animation (if the property changes are not animated, "R":2 flag is ignored) -- user->task message: [<<ums>>,<<id>>,[1]]; "R":3 indicates that receipts [1] and [2] are both requested; e.g. {"bg":"blue","U":5000,"S":5,"R":3,"Q":"aniblue"} indicates that the background should take 5 seconds to become blue, starting at user-time 5000 (i.e. 5s into the task), and reciept events should be sent to task at beginning and end of animation with "aniblue" as the id -- this will result in the following messages sent back to task software: [5000,"aniblue",[1]] and [10000,"aniblue",[2]]
    <<command>>         "S":<<number>>|null                                 Seconds to make current update (i.e. animation); <<number>> is the number of seconds over which current update takes place; null clears current animation(s)
    <<command>>         "T":<<number>>|null                                 Timeout (i.e. delay) for current update (exclusive with "U" command); <<number>> is the number of seconds to delay; null clears previous delays (initiated via "T" or "U" directive); e.g. {"v":null,"T":2} will clear the screen after a 2 seconds; [{"id":"text","v":"hello"},{"id":"text","v":null,"W":2}}] would add "text":"hello" to screen, and then remove it 2 seconds later
    <<command>>         "U":<<ums>>|null                                    User-time for current update (exclusive with "T" command); used to delay the processing of the current update until user time has reached specified <<ums>>; null clears previous delay(s) (initiated via "T" or "U" directive)

    <<property>>        "type":<<itemType>>                                 the value specified for this item 
    <<itemType>>        "popup"                                             this item is a popup -- a special <<container>> that pops up over other items of the parent container, partially obscuring their view, and preventing them from being edited
    <<itemType>>        "table"                                             this item is a table -- a special <<container>> that contains others <<container>> items, each of which will be a row in a table; e.g. [{"id":"personnel","v":[["name","age","gender"],["john",39,"m"],["mary",28,"f"]],"type":"table","head":1}] will add a "personnel" table with a header row and two records (john, mary)
    <<itemType>>        "pie"                                               this item is a pie -- a special <<container>> whose items are displayed as slices in a pie
    <<itemType>>        "path"                                              this item is a line/path -- its value is an array of numbers where each pair of numbers to signify line points, or <<text>> to signify SVG path string; e.g. [{"id":"my graph","v":[150,0,75,200,225,200],"type":"path","w":300,"h":300}] or [{"id":"my graph","v":"M150 0 75 200 225 200 Z","type":"path","w":300,"h":300}] would each draw the same triangle in a 300x300 container
    <<itemType>>        "html"                                              this item is html body -- its a special <<text>> item that includes html tags; e.g. {"type":"html","v":"<b>this text is bold</b>"}; this should only be employed for displaying documents, not functional UI components, and with the assumption that many machine agents will ignore the tags inside html
    <<property>>        <<tableOption>>                                     table item options
    <<property>>        <<pieOption>>                                       pie item options
    <<property>>        <<pathOption>>                                      path item options; these options should be used only when needed for the task to function correctly, never merely for visual appeal (visual appeal specifications are loaded via templates, using <<taskOption>> "template":<<url>>)

    <<option>>          "title":<<text>>                                    visible title (replaces item id as the visible title)
    <<option>>          "#":[<<text>>(,<<text>>)*]                          add tags to current item (useful for "$" selection command)
    <<option>>          <<emp>>:<<uint>>                                    emphasize item in some way (make it bold or highlight); <<emp>> is an emphasis type declared via "required" directive, <<uint>> is a number signifying emphasis strength, where 0 is nonexistent, 1 is weakest, 2 is stronger, etc. (strongest emphasis level is specified via required directive)
    <<option>>          "bg":<<cssBackground>>                              background
    <<option>>          "c":<<color>>                                       text/stroke color
    <<option>>          "opc":<<number>>                                    opacity; <<number>> must be between 0 (seethrough) and 1 (solid); 1 is default
    <<option>>          "fnt":<<cssFont>>                                   text font
    <<option>>          "scroll":0|1|2|3                                    vertical scrolling; 0 - scrolling isn't allowed, 1 (default) - scrolling allowed when possible, 2 - scrolling isn't allowed, but container automatically scrolls to the bottom to reveal newly added content, 3 - scrolling is allowed, and container automatically scrolls to the bottom to reveal newly added content
    <<option>>          "scrollH":0|1|2|3                                   horizontal scrolling; 0 - scrolling isn't allowed, 1 (default) - scrolling allowed when possible, 2 - scrolling isn't allowed, but container automatically scrolls to the right to reveal newly added content, 3 - scrolling is allowed, and container automatically scrolls to the right to reveal newly added content
    <<option>>          "w":<<number>>|"<<number>><<sizeUnit>>"             width of the item
    <<option>>          "h":<<number>>|"<<number>><<sizeUnit>>"             height of the item
    <<option>>          "x":<<number>>|"<<number>><<sizeUnit>>"             horizontal position of left-top corner of the item
    <<option>>          "y":<<number>>|"<<number>><<sizeUnit>>"             vertical position of left-top corner of the item
    <<option>>          "z":<<number>>                                      z-index (stack order) of the item; an item with greater stack order is always in front of an item with a lower stack order
    <<option>>          "r":<<number>>                                      rounded corner radius (ex: create a blue circle w/ radius=10 -> [{"w":20,"h":20,"r":10,"bg":"blue"}])
    <<option>>          "rot":<<number>>                                    rotation
    <<option>>          "bd":<<cssBorder>>                                  border style
    <<option>>          "bdc":<<color>>                                     border color
    <<option>>          "bdw":<<number>>                                    border width
    <<option>>          "pad":<<cssPadding>>                                padding

    <<inputOption>>     "patronym":<<uint>>                                 <<uint>> indicates the number of patronyms (i.e. parent container names) to include in ** user -> task ** messages; e.g. [{"id":"personnel","v":[["name","age","gender"],["john",39,"m",false],["mary",28,"f",false]],"type":"table","head":1,"patronym":1}] will create a "personnel" table with a header and two records, each record having an unnamed button -- when the button corresponding to "john" row is clicked, user->task message will be [<<ums>>,[3,1],true], where [3,1] correspond to the button id and button's parent id (i.e. cell and row numbers), respectively; when the button corresponding to "mary" row is clicked, user->task message will be [<<ums>>,[3,2],true]; if the "patronym" option for this table was set to 2, clicking the buttons corresponding to "john" and "mary" rows would send [<<ums>>,[3,1,"personnel"],true] and  [<<ums>>,[3,2,"personnel"],true] user->task messages, respectively
    <<inputOption>>     "onedit":<<item>>                                   how to change editable item after user changes its value; use "onedit":{} to reset a control to do nothing after a user-directed change; e.g. [{"id":"say something:","v":"","eT":1,"onedit":""}] will create a textbox where user can type something, but as soon as they hit Enter, the text will disappear; [{"id":"btn1","v":false,"onedit":{"eB":0}}] creates a button, btn1, that becomes disabled once clicked; [{"id":"btn1","v":false,"onedit":null}] creates a button, btn1, that gets removed once clicked
    <<inputOption>>     "onsubedit":<<item>>                                how to change container after one of its descendant items receives user input; e.g. [{"id":"choose","v":[{"id":"choice 1","v":false},{"id":"choice 2","v":false},{"id":"choice 3","v":false}],"select":1,"onsubedit":{"eB:0"}}] creates a set of three choices, which all become disabled once any one of them gets clicked
    <<inputOption>>     "eB":0|1                                            editable Boolean flag; 0 makes boolean items (buttons) disabled; 1 (default) enables them
    <<inputOption>>     "eN":0|1                                            editable Number flag; eN:0 (default) is standard, non-editable numeric field; eN:1 is a numeric input
    <<inputOption>>     "eT":0|1|2|3|4                                      editable Text flag; eT:0 (default) is standard, non-editable text; non-zero value turns text items into text inputs; eT:1 signifies a standard single-line input field, where user-entered value is sent to task software whenever the field loses focus (on blur or enter); eT:2 is a multi-line text area that allows carriage returns, and sends user-entered value on blur; eT:3 signifies a single-line input field where the value is sent to task software on every input; eT:4 signifies a multi-line text area where the value is sent to task software on every input
    <<inputOption>>     "e":[<<eventType>>(,<<eventType>>)*]                event capture; capture item events like key presses and mouse movements; event types required for task must be pre-specified via the "require" <<taskOption>>
    <<inputOption>>     "esu":"<<sizeUnit>>"                                size unit for x/y/w/h specs in user->task messages for captured events

    <<boolOption>>      "select":-1|0|1|2                                   selection behavior for boolean items: -1 (default) means that each item is selected (true) on click, and considered deselected immediately (i.e. clickable buttons); 0 means that each item is selected (true) on mousedown, and deselected (false) on mouseup (i.e. hold-down buttons); 1 means that an item stays selected (true) when clicked, until it is clicked again to deselect (false), or until another item is selected within the current container (i.e. radio buttons or select); 2 means that each item is selected (true) when clicked and deselected (false) when clicked again (i.e. checkboxes or multiple-select)
    <<boolOption>>      "select":"n"                                        selection behavior for boolean items: "n" is a hybrid between 1 and 0 -- only one item in container can be selected at a time, but the selection/deselection does not happen on click, but rather on mousedown/hover/mouseup  (e.g. a set of navigation buttons) -- each item is selected (true) either on mousedown or on mousehover while another boolean item in this container is selected, and an item is deselected (false) either on mouseup or when mouse hovers over some other boolean item in this container

    <<numOption>>       "rnd":<<number>>                                    round to the nearest <<number>>; e.g. [{"id":"x","v":57.1,"rnd":.01}] should be interpreted as x=57.10, [{"id":"x","v":57.1,"rnd":5}] should be interpreted as x=55
    <<numOption>>       "min":<<number>>                                    minimum displayable value
    <<numOption>>       "max":<<number>>                                    maximum displayable value
    <<numOption>>       "unit":<<text>>                                     exclusive with "time" option; unit for the number (e.g. "$", "%", "m/sec", "kg", "€ million", "$ k")
    <<numOption>>       "time":"(<<timeField>>)+"                           exclusive with "unit" option; indicates that the value for this item is the total number of seconds since 1970/01/01 00:00; e.g. [{"id":"when","v":1483963200,"time":"YMDhm"}] is a way to specify date/time 2017/01/09 12:00; [{"v":543.21,"time":"ms."}] is a way to specify 9:03.210 (9min, 3sec, 210ms)

    <<txtOption>>       "chmax":<<number>>                                  max number of characters in <<text>>
    <<txtOption>>       "mask":{<<regex>>:<<text>>(,<<regex>>:<<text>>)*}   replace <<regex>> with <<text>> throughout the string (global replace); e.g. [{"v":"","eT":1,"mask":{".","*"}}] would add a text input field where each character would be masked by "*" (like in password fields)

    <<aniOption>>       "ease":(0|1|2|3|4|"back"|"elastic"|"bounce")        easing option for animation; default is 0 (linear); see http://greensock.com/ease-visualizer to visualize ease options
    <<aniOption>>       "easeout":(1|-1|0)                                  ease direction; 1 is out, -1 is in, 0 is in-and-out; default is 1; see http://greensock.com/ease-visualizer to visualize ease options

    <<tableOption>>     "head":0|1                                          if this value is 1, first row of a table is treated as the header row (default value is 0)

    <<pieOption>>       "bounda":[<<number>>(,<<number>>)*]                 bounding angles of the pie in clockwise order, 0 degrees is up; e.g., [{"id":"navigation","v":[{"id":"E","v":false},{"id":"S","v":false},{"id":"W","v":false},{"id":"N","v":false}],"type":"pie","bounda":[45,135,225,315]}] creates a 4-button east-south-west-north pie

    <<pathOption>>      "f":(<<color>>|"none")                              similar to SVG fill
    <<pathOption>>      "thk":<<number>>                                    similar to SVG stroke-width
    <<pathOption>>      "end1|2":"(arrow)|(circle)|(square)"                similar to SVG marker-start/marker-end
    <<pathOption>>      "cap":"(square)|(round)|()"                         similar to SVG stroke-linecap
    <<pathOption>>      "dash":<<strokeDash>>                               similar to SVG stroke-dasharray

    <<userEvent>>       [<<eventType>>(,<<value>>)*]                        captured UI events specified via the "e" option, see <<eventType>> descriptions below for more detail
    <<eventType>>       -1                                                  stap UI exit event (similar to html5 onbeforeunload); user->task message on this event would be: [<<ums>>,0,[1]]
    <<eventType>>       0                                                   stap UI ready event (similar to html5 onload); user->task message on this event would be: [<<ums>>,0,[0]]
    <<eventType>>       1                                                   stap change-start event; this is the event sent back when property updates that include "R":1 (or "R":3) flag begin
    <<eventType>>       2                                                   stap change-end event; this is the event sent back after an animation that included "R":2 (or "R":3) flag is complete
    <<eventType>>       10                                                  item focus event; user->task message on this event would be: [<<ums>>,<<id>>,[10]]<commit_msg>STAP v7.11<commit_after>STAP (Simple Task-Actor Protocol)
version 7.11


    Message Type        Regular Expression                                  Functionality
    ** task -> user **  <<container>>                                       update current display container
    ** task -> user **  null                                                clear the display container
    ** task -> user **  {<<taskOption>>(,<<taskOption>>)*}                  optional task commands/properties
    ** user -> task **  [<<ums>>,<<id>>,<<value>>]                          user-side action (e.g. button-click, textbox edit); second field corresponds to the <<id>> of the item that is manipulated by user; <<value>> must be of a type consistent with this item (e.g. for boolean items value must be a boolean)
    ** user -> task **  [<<ums>>,<<id>>,<<userEvent>>]                      user-side event (e.g. load/unload, captured key or mouse event); second field corresponds to the <<id>> of the item that is manipulated by user

    Label Name          Regular Expression                                  Functionality
    <<container>>       [<<item>>(,<<item>>)*]                              array of item updates/declarations for current container
    <<item>>            <<value>>|{<<property>>(,<<property>>)*}            an item may be declared by value or a set of properties
    <<property>>        "v":<<value>>                                       set item value; i.e., ["hello world"] is just shorthand for [{"v":"hello world"}]
    <<property>>        "id":<<id>>                                         update the item with the specified <<id>> within the current container; if item specified by id doesn't exist, it is appended to the container; root-level display container has no id
    <<property>>        "id":[<<id>>(,<<id>>)*]                             update the item specified by the <<id>> array, where the first <<id>> identifies the item within current container, with the following <<id>>'s specifying its child, that child's child, etc.; e.g. {"id":[2,3],"v":null} would delete the fourth item inside the third container
    <<id>>              <<text>>                                            unique item key; <<id>> text is displayed as item title text (unless "title" optional property is specified, see below); e.g. [{"id":"Name","v":"Bob"},{"id":"Age","v":77}] adds two key:value pairs to the UI -- Name:Bob and Age:77, and [{"id":"Age","v":78}] would change the value for Age from 77 to 78
    <<id>>              <<uint>>                                            item order number within the current container; item numbering in a container begins at 0, thus {"id":0} is the first item in a given container; if <<uint>> is greater or equal to current number of items in the container, corresponding value is appended as the last item in the container
    <<value>>           <<text>>|<<number>>|<<boolean>>|<<container>>       item value may be text, number, boolean (signifying buttons/options), or an array of item updates for a child container
    <<value>>           null                                                value of null removes item from container; e.g., [{"id":0,"v":null}] will remove the first item from the display
    <<ums>>             <<uint>>                                            time in milliseconds since the initiation of user software (e.g. onload event)
    <<text>>            ** see JSON string specification, e.g. http://json.org **
    <<number>>          ** see JSON number specification, e.g. http://json.org **
    <<uint>>            ** integer >= 0 **
    <<boolean>>         (true)|(false)

everything above is core-STAP; all user-side sw must be able to handle the format specified above for simple text+button tasks

==

everything below specifies optional directives that enable more featureful user-interface interactions

    <<taskOption>>      "require":{<<required>>(,<<required>>)*}            should be sent once before task begins; specify which options and option values are required for correctly interpreting current task; if any of the <<required>> items are not implemented yet in the user software, the suggested behavior is to disconnect from task after a polite [<<ums>>,0,{"error":"sorry, <<required>> is not yet implemented on this side"}]
    <<taskOption>>      "error":<<text>>                                    error message to be dumped into user-side error stream
    <<taskOption>>      "template":<<url>>|<<js>>                           likely sent once before task begins (may be ignored by computational agents); custom visualization template for STAP messages (e.g. CSS or JS text or url); Template command may be called multiple times to load multiple parts of a template
    <<taskOption>>      "agent":[<<userInfo>>(,<<userInfo>>)*]              likely sent once before task begins; request information about user-side software; the polite thing for user-side software to do would be to reply to "client" <<taskOption>> with as much information as possible, but task-side code should not be dependent on this; participant replies to this request as such: [<<ums>>,0,{"clientinfo":<<json>>}]; e.g. a response to {"clientinfo":["ip","url","screen","userAgent"]} may be [<<ums>>,0,{"clientinfo":{"ip":"172.16.58.3","url":"http://localhost:8080/stap.html","screen":{"availWidth":1524,"availHeight":900,"width":1600,"height":900,"colorDepth":24,"pixelDepth":24,"availLeft":0,"availTop":0,"orientation":{"angle":0}},"userAgent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"}}]
    <<taskOption>>      "task":{"(win)|(loss)|(end)":<<conds>>}             likely sent once before task begins; win, loss, and neutral task-end conditions; suggested user-sw behavior for human participants is to convert <<conds>> into natural language and display as "Instructions"
    <<taskOption>>      "task":{"(good)|(bad)":<<conds>>}                   likely sent once before task begins; goal values (what to seek, what to avoid); suggested user-sw behavior for human participants is to convert <<conds>> into natural language and display as "Instructions"
    <<conds>>           [<<cond>>|<<condAnd>>(,<<cond>>|<<condAnd>>)*]      <<conds>> list is True if any of the items in it are True
    <<condAnd>>         [<<cond>>(,<<cond>>)*]                              <<condAnd>> list is True if ALL of the items in it are True
    <<cond>>            [<<id>>(,"<|>|(<=)|(>=)|(!=)")?,<<number>>|<<text>>]
    <<userInfo>>        "ip"                                                request client ip address
    <<userInfo>>        "userAgent"                                         request information about user-side software (e.g. webbrowser type/version, AI architecture type/version)
    <<userInfo>>        "url"                                               request client url (relevant when user-side software runs in a webbrowser)
    <<userInfo>>        "screen"                                            find out total user screen size (for human participants this would be different from <<eventType>> 13, which only sends back current <<container>> size)
    <<userEvent>>       {(<<userInfo>>:<<json>>)}                           response to "Agent" <<taskOption>>; e.g. a response to {"Agent":["ip","url","screen","userAgent"]} may be a series of messages, such as [<<ums>>,0,{"ip":"172.16.58.3"}] [<<ums>>,0,{"url":"http://localhost:8080/stap.html"}] [<<ums>>,0,{"screen":{"availWidth":1524,"availHeight":900,"width":1600,"height":900,"colorDepth":24,"pixelDepth":24,"availLeft":0,"availTop":0,"orientation":{"angle":0}}}] [<<ums>>,0,{"userAgent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"}]
    <<userEvent>>       {"error":<<text>>}                                  user->task messages that contain this directive are dumped into task-side error stream
    <<userEvent>>       [0]                                                 load event to indicate that user-side sw is ready
    <<json>>            ** see full JSON specification, e.g. http://json.org **
    <<url>>             ** legal url **
    <<js>>              ** legal javascript **
    <<html>>            ** legal text/html **


everything above is core-STAP; although task-options can be ignored in many cases, user-side sw must still expect them as potentially incoming messages, and be willing to quit if it cannot handle any of the items specified via the "require" task option

==

everything below can be negotiated via the "require" <<taskOption>>; if task requires options that user sw cannot handle, user software can disconnect

- if a <<property>> is specified for a container (or a container-type, such as table or popup), and it is not applicable to containers, this <<property>> is inherited by all decendent elements; e.g. [{"id":"my container","v":[1,2,{"id":"more","v":[3,4]}],"rnd":1}] signifies that all numeric values in the container "my container", including those in the "more" container, are rounded to 1 (integers)

    Label Name          Regular Expression                                  Functionality
    <<required>>        "options":[<<optionName>>(,<<optionName>>)*]        specify options necessary for this task; e.g., {"required":{"options":["r","rot"]}}
    <<required>>        <<optionName>>:[<<optionVal>>(,<<optionVal>>)*]     specify option values necessary for this task; e.g., {"required":{"select":[1,2,"n"],"type":["table","path"]}}
    <<required>>        "e":[<<eventType>>(,<<eventType>>)*]                specify event types necessary for this task; e.g., {"required":{"e":[40,44]}}
    <<required>>        "path":[<<curveType>>(,<<curveType>>)*]             specify path curve options necessary for this task; e.g., {"required":{"path":["S","C"]}}
    <<required>>        "colors":<<uint>>                                   specify how many different preset colors are necessary for this task; <<uint>> must be greater than 1 (presets 0 and 1 are default background and text colors); e.g., {"required":{"colors":3}} signifies that the task will require 2 different colors in addition to the background and text colors
    <<required>>        "sizeUnits":["<<sizeUnit>>"(,"<<sizeUnit>>")*]      specify size-units necessary for this task; e.g., {"required":{"sizeUnits":["%","E","vh","vw"]}}
    <<required>>        "emphases":{<<emp>>:<<uint>>(,<<emp>>:<<uint>>)*}   specify emphasis types necessary for this task; e.g., {"required":{"emphases":{"emp":3,"emp2":3}}} signifies that two emphases types are required (emp and emp2), each with three levels of strength
    <<emp>>             ** text string starting with "emp"; e.g. "emp2" **
    <<curveType>>       ** the string on the leftmost part of <<pathTo>> expression; i.e., character C, S, Q, T, or A **
    <<optionName>>      ** the part to the left of the colon in the <<property>> or <<taskOption>> expression; e.g. "S", "eB", "bg" **
    <<optionVal>>       ** the part to the right of the colon in the <<property>> or <<taskOption>> expression **

    <<taskOption>>      <<property>>                                        optional properties for top-level container

    <<property>>        <<optionName>>:null                                 remove/reset property (i.e. clear or reset to default behavior)
    <<property>>        <<command>>                                         commands that alter how other properties are changed; <<command>> property values are not permanent; e.g. [{"id":"x","T":10,"bg":"blue"}] signifies that the background of "x" should be changed to blue over the course of 10seconds, after which the value of "bg" (background) remains "blue", but the value "T" (time of animation) resets to null, because "T" is an <<command>> option
    <<property>>        <<option>>                                          generic options
    <<property>>        <<inputOption>>                                     user-input options (specify whether item value is editable, and what the behavior is upon edits)
    <<property>>        <<boolOption>>                                      boolean item options
    <<property>>        <<numOption>>                                       number item options
    <<property>>        <<txtOption>>                                       text item options
    <<property>>        <<aniOption>>                                       animation options

    <<command>>         "$":<<searchTerm>>                                  select items; apply current updates to all of the items that match <<searchTerm>>; e.g. [{"id":"x","v":"hello"},{"id":"z","v":[{"id":"y","v":[{"id":"x","v":"goodbye"}]}]}] followed by {"$":["y","x"],"bg":"red"} would turn the background of "x"-"hello" and "x"-"goodbye" id-value pairs red
    <<command>>         "$":[<<searchTerm>>(,<<searchTerm>>)*]              multiple selects; apply current updates to all of the items that match any one <<searchTerm>>
    <<command>>         "O":1                                               Onedit/onsubedit trigger for current update (i.e. pretend as if there was a user-side input); useful for playback, demo, instructions; e.g. task->user messages [{"id":"press me","v":false,"onedit":null}] [{"id":"press me","v":true,"O":1}] would add a button, one that would disappear once clicked, and then force-click the button, causing it to disappear
    <<command>>         "P":<<id>>                                          Push (i.e. insert) current item before item specified by <<id>> in current container; e.g. ["a","b","c"] followed by [{"v":"x","P":1}] is equivalent to ["a","x","b","c"]
    <<command>>         "P":[<<uint>>,<<uint>>]                             Push with replace; insert current item in place of range specified by [<<uint>>,<<uint>>] (i.e. insert and remove all items between the two integers, including the first and disincluding the last, in current container); e.g. ["a","b","c"] followed by [{"v":"x","P":[1,2]}] is equivalent to ["a","x","c"]
    <<command>>         "Q":<<number>>|<<text>>                             Queue identifier for current update; useful for queued (delayed or animated) updates triggered via S, T, or U commands; e.g. the following two task->user messages -- [{"id":"candles","v":0},{"id":"candles","v":1,"Q":"t1","U":10000,"R":1},{"id":"candles","v":2,"Q":"t2","U":20000,"R":1}] and [{"Q":"t1":,"U":null}] -- would result in a key:value pair "candles":0 being added to display, and timers set up to change the value of "candles" to 1 at 10sec, then to 2 at 20sec into the task, then the 10sec timer is removed, but the 20sec timer for the same item remains, and user sw ends up sending the following message back 20s into the task -- [20000,"t2",[1]]
    <<command>>         "R":1|2|3                                           Receipt request for current update; 1 indicates a receipt is required when property change(s) begin -- user->task message: [<<ums>>,<<id>>,[1]]; 2 indicates a receipt is required when property change(s) end, after animation (if the property changes are not animated, "R":2 flag is ignored) -- user->task message: [<<ums>>,<<id>>,[1]]; "R":3 indicates that receipts [1] and [2] are both requested; e.g. {"bg":"blue","U":5000,"S":5,"R":3,"Q":"aniblue"} indicates that the background should take 5 seconds to become blue, starting at user-time 5000 (i.e. 5s into the task), and reciept events should be sent to task at beginning and end of animation with "aniblue" as the id -- this will result in the following messages sent back to task software: [5000,"aniblue",[1]] and [10000,"aniblue",[2]]
    <<command>>         "S":<<number>>|null                                 Seconds to make current update (i.e. animation); <<number>> is the number of seconds over which current update takes place; null clears current animation(s)
    <<command>>         "T":<<number>>|null                                 Timeout (i.e. delay) for current update (exclusive with "U" command); <<number>> is the number of seconds to delay; null clears previous delays (initiated via "T" or "U" directive); e.g. {"v":null,"T":2} will clear the screen after a 2 seconds timout; [{"id":"text","v":"hello"},{"id":"text","v":null,"W":2}}] would add "text":"hello" to screen, and then remove it 2 seconds later
    <<command>>         "U":<<ums>>|null                                    User-time for current update (exclusive with "T" command); used to delay the processing of the current update until user time has reached specified <<ums>>; null clears previous delay(s) (initiated via "T" or "U" directive)

    <<searchTerm>>      <<id>>|<<tag>>                                      match by <<id>> or <<tag>>; search is recursive, not just in current container; empty-string matches items where id isn't specified (e.g., {"$":"","bg":"red"} sets background of all items without an id to red); e.g., {"$":"x","bg":"red"} would find all items where id is "x" or one of the tags (specified via "#") is "x" and set their background colors to "red"
    <<searchTerm>>      {<<searchProp>>(,<<searchProp>>)*}                  match by property values; if no <<searchProp>> is specified, all items are selected (e.g., {"$":{},"c":"red"} sets color of all text of all items to "red")
    <<searchProp>>      "recur":0                                           recursive search flag; property searches are recursive by default, add "recur":0 to search only current container, not child containers; e.g., {"$":{"recur":0},"c":"red"} sets color of all text of all items in current container to "red"
    <<searchProp>>      <<property>>                                        match by property values; all <<property>> values must match; selection by "type" property is allowed for items with both explicit and derived types (e.g., {"$":{"type":0},"v":0} would set all numeric values to 0's); selection by "#" property searches for whether the specified hashtag exists (e.g.; {"$":{"#":"xx"},"c":"red"} finds all elements where one of the hashtags is "xx" and sets text color to red); e.g., {"$":{"v":1},"v":0} would set all 1's to 0's, [{"id":"my container","v":[{"$":{"type":[]},"bg":"blue"}]}] will set backgrounds of all containers inside of "my container" to blue

    <<property>>        "type":<<itemType>>                                 the value specified for this item 
    <<itemType>>        "popup"                                             this item is a popup -- a special <<container>> that pops up over other items of the parent container, partially obscuring their view, and preventing them from being edited
    <<itemType>>        "table"                                             this item is a table -- a special <<container>> that contains others <<container>> items, each of which will be a row in a table; e.g. [{"id":"personnel","v":[["name","age","gender"],["john",39,"m"],["mary",28,"f"]],"type":"table","head":1}] will add a "personnel" table with a header row and two records (john, mary)
    <<itemType>>        "pie"                                               this item is a pie -- a special <<container>> whose items are displayed as slices in a pie
    <<itemType>>        "path"                                              this item is a line/path -- a special <<container>> whose first item is a starting <<point>>, and each next item is a <<pathTo>>, which specifies a <<point>> where a line/curve is to be drawn to (and, if it's a curve, how it should curve); e.g., {type:'path',v:[[0,100],["S",50,50,100,100],[0,0]]} would add a path to display where the path starts in the lower-left corner of the container, curves up and back down to the lower-right corner, and then shoots diagonally straight to the top-left corner
    <<itemType>>        "html"                                              this item is html body -- its a special <<text>> item that includes html tags; e.g. {"type":"html","v":"<b>this text is bold</b>"}; this should only be employed for displaying documents, not functional UI components, and with the assumption that many machine agents will ignore the tags inside html
    <<itemType>>        "data"                                              this item is a data frame -- a special <<container>> whose items are related data series (each data series is a <<container>> with values); "data" item types may be displayed in different ways depending on client software and template used (e.g. chart and/or table, 2d/3d, interactive plots, animation, a "download CSV" link, etc)
    <<property>>        <<tableOption>>                                     table item options
    <<property>>        <<pieOption>>                                       pie item options
    <<property>>        <<pathOption>>                                      path item options; these options should be used only when needed for the task to function correctly, never merely for visual appeal (visual appeal specifications are loaded via templates, using <<taskOption>> "template":<<url>>)

    <<option>>          "title":<<text>>                                    visible title (replaces item id as the visible title)
    <<option>>          "#":[<<text>>(,<<text>>)*]                          add tags to current item (useful for "$" selection command)
    <<option>>          <<emp>>:<<uint>>                                    emphasize item in some way (make it bold or highlight); <<emp>> is an emphasis type declared via "required" directive, <<uint>> is a number signifying emphasis strength, where 0 is nonexistent, 1 is weakest, 2 is stronger, etc. (strongest emphasis level is specified via required directive)
    <<option>>          "bg":<<cssBackground>>                              background
    <<option>>          "c":<<color>>                                       text/stroke color
    <<option>>          "opc":<<number>>                                    opacity; <<number>> must be between 0 (seethrough) and 1 (solid); 1 is default
    <<option>>          "fnt":<<cssFont>>                                   text font
    <<option>>          "scroll":0|1|2|3                                    vertical scrolling; 0 - scrolling isn't allowed, 1 (default) - scrolling allowed when possible, 2 - scrolling isn't allowed, but container automatically scrolls to the bottom to reveal newly added content, 3 - scrolling is allowed, and container automatically scrolls to the bottom to reveal newly added content
    <<option>>          "scrollH":0|1|2|3                                   horizontal scrolling; 0 - scrolling isn't allowed, 1 (default) - scrolling allowed when possible, 2 - scrolling isn't allowed, but container automatically scrolls to the right to reveal newly added content, 3 - scrolling is allowed, and container automatically scrolls to the right to reveal newly added content
    <<option>>          "w":<<number>>|"<<number>><<sizeUnit>>"             width of the item
    <<option>>          "h":<<number>>|"<<number>><<sizeUnit>>"             height of the item
    <<option>>          "x":<<number>>|"<<number>><<sizeUnit>>"             horizontal position of left-top corner of the item
    <<option>>          "y":<<number>>|"<<number>><<sizeUnit>>"             vertical position of left-top corner of the item
    <<option>>          "z":<<number>>                                      z-index (stack order) of the item; an item with greater stack order is always in front of an item with a lower stack order
    <<option>>          "r":<<number>>                                      rounded corner radius (ex: create a blue circle w/ radius=10 -> [{"w":20,"h":20,"r":10,"bg":"blue"}])
    <<option>>          "rot":<<number>>                                    rotation
    <<option>>          "bd":<<cssBorder>>                                  border style
    <<option>>          "bdc":<<color>>                                     border color
    <<option>>          "bdw":<<number>>                                    border width
    <<option>>          "pad":<<cssPadding>>                                padding

    <<inputOption>>     "patronym":<<uint>>                                 <<uint>> indicates the number of patronyms (i.e. parent container names) to include in ** user -> task ** messages; names of parents always preceed names of children; e.g. [{"id":"personnel","v":[["name","age","gender"],["john",39,"m",false],["mary",28,"f",false]],"type":"table","head":1,"patronym":1}] will create a "personnel" table with a header and two records, each record having an unnamed button -- when the button corresponding to "john" row is clicked, user->task message will be [<<ums>>,[1,3],true], where [1,3] correspond to the button's parent id and the button's id, respectively (i.e. row and cell numbers in the case of a table); when the button corresponding to "mary" row is clicked, user->task message will be [<<ums>>,[2,3],true]; if the "patronym" option for this table was set to 2, clicking the buttons corresponding to "john" and "mary" rows would send [<<ums>>,["personnel",1,3],true] and  [<<ums>>,["personnel",2,3],true] user->task messages, respectively
    <<inputOption>>     "onedit":<<item>>                                   how to change editable item after user changes its value; use "onedit":{} to reset a control to do nothing after a user-directed change; e.g. [{"id":"say something:","v":"","eT":1,"onedit":""}] will create a textbox where user can type something, but as soon as they hit Enter, the text will disappear; [{"id":"btn1","v":false,"onedit":{"eB":0}}] creates a button, btn1, that becomes disabled once clicked; [{"id":"btn1","v":false,"onedit":null}] creates a button, btn1, that gets removed once clicked
    <<inputOption>>     "onsubedit":<<item>>                                how to change container after one of its descendant items receives user input; e.g. [{"id":"choose","v":[{"id":"choice 1","v":false},{"id":"choice 2","v":false},{"id":"choice 3","v":false}],"select":1,"onsubedit":{"eB:0"}}] creates a set of three choices, which all become disabled once any one of them gets clicked
    <<inputOption>>     "eB":0|1                                            editable Boolean flag; 0 makes boolean items (e.g. buttons) disabled; 1 (default) enables them
    <<inputOption>>     "eN":0|1                                            editable Number flag; eN:0 (default) is standard, non-editable numeric field; eN:1 is a numeric input
    <<inputOption>>     "eT":0|1|2|3|4                                      editable Text flag; eT:0 (default) is standard, non-editable text; non-zero value turns text items into text inputs; eT:1 signifies a standard single-line input field, where user-entered value is sent to task software whenever the field loses focus (on blur or enter); eT:2 is a multi-line text area that allows carriage returns, and sends user-entered value on blur; eT:3 signifies a single-line input field where the value is sent to task software on every input; eT:4 signifies a multi-line text area where the value is sent to task software on every input
    <<inputOption>>     "e":[<<eventType>>(,<<eventType>>)*]                event capture; capture item events like key presses and mouse movements; event types required for task must be pre-specified via the "require" <<taskOption>>
    <<inputOption>>     "esu":"<<sizeUnit>>"                                size unit for x/y/w/h specs in user->task messages for captured events

    <<boolOption>>      "select":-1|0|1|2                                   selection behavior for boolean items: -1 (default) means that each item is selected (true) on click, and considered deselected immediately (i.e. clickable buttons); 0 means that each item is selected (true) on mousedown, and deselected (false) on mouseup (i.e. hold-down buttons); 1 means that an item stays selected (true) when clicked, until it is clicked again to deselect (false), or until another item is selected within the current container (i.e. radio buttons or select); 2 means that each item is selected (true) when clicked and deselected (false) when clicked again (i.e. checkboxes or multiple-select)
    <<boolOption>>      "select":"n"                                        selection behavior for boolean items: "n" is a hybrid between 1 and 0 -- only one item in container can be selected at a time, but the selection/deselection does not happen on click, but rather on mousedown/hover/mouseup  (e.g. a set of navigation buttons) -- each item is selected (true) either on mousedown or on mousehover while another boolean item in this container is selected, and an item is deselected (false) either on mouseup or when mouse hovers over some other boolean item in this container

    <<numOption>>       "rnd":<<number>>                                    round to the nearest <<number>>; e.g. [{"id":"x","v":57.1,"rnd":.01}] should be interpreted as x=57.10, [{"id":"x","v":57.1,"rnd":5}] should be interpreted as x=55
    <<numOption>>       "min":<<number>>                                    minimum displayable value
    <<numOption>>       "max":<<number>>                                    maximum displayable value
    <<numOption>>       "unit":<<text>>                                     exclusive with "time" option; unit for the number (e.g. "$", "%", "m/sec", "kg", "€ million", "$ k")
    <<numOption>>       "time":"(<<timeField>>)+"                           exclusive with "unit" option; indicates that the value for this item is the total number of seconds since 1970/01/01 00:00; e.g. [{"id":"when","v":1483963200,"time":"YMDhm"}] is a way to specify date/time 2017/01/09 12:00; [{"v":543.21,"time":"ms."}] is a way to specify 9:03.210 (9min, 3sec, 210ms)

    <<txtOption>>       "chmax":<<number>>                                  max number of characters in <<text>>
    <<txtOption>>       "mask":{<<regex>>:<<text>>(,<<regex>>:<<text>>)*}   replace <<regex>> with <<text>> throughout the string (global replace); e.g. [{"v":"","eT":1,"mask":{".","*"}}] would add a text input field where each character would be masked by "*" (like in password fields)

    <<aniOption>>       "ease":(0|1|2|3|4|"back"|"elastic"|"bounce")        easing option for animation; default is 0 (linear); see http://greensock.com/ease-visualizer to visualize ease options
    <<aniOption>>       "easeout":(1|-1|0)                                  ease direction; 1 is out, -1 is in, 0 is in-and-out; default is 1; see http://greensock.com/ease-visualizer to visualize ease options

    <<tableOption>>     "head":0|1                                          if this value is 1, first row of a table is treated as the header row (default value is 0)

    <<pieOption>>       "bounda":[<<number>>(,<<number>>)*]                 bounding angles of the pie in clockwise order, 0 degrees is up; e.g., [{"id":"navigation","v":[{"id":"E","v":false},{"id":"S","v":false},{"id":"W","v":false},{"id":"N","v":false}],"type":"pie","bounda":[45,135,225,315]}] creates a 4-button east-south-west-north pie

    <<point>>           <<number>>,<<number>>
    <<pathTo>>          [<<point>>]
    <<pathTo>>          ["C",<<point>>,<<point>>,<<point>>]
    <<pathTo>>          ["S",<<point>>,<<point>>]
    <<pathTo>>          ["Q",<<point>>,<<point>>]
    <<pathTo>>          ["T",<<point>>]
    <<pathTo>>          ["A",<<point>>,<<number>>,0|1,0|1,<<point>>]
    <<pathOption>>      "f":(<<color>>|"none")                              similar to SVG fill
    <<pathOption>>      "thk":<<number>>                                    similar to SVG stroke-width
    <<pathOption>>      "end1|2":"(arrow)|(circle)|(square)"                similar to SVG marker-start/marker-end
    <<pathOption>>      "cap":"(square)|(round)|()"                         similar to SVG stroke-linecap
    <<pathOption>>      "dash":<<strokeDash>>                               similar to SVG stroke-dasharray

    <<userEvent>>       [<<eventType>>(,<<value>>)*]                        captured UI events specified via the "e" option, see <<eventType>> descriptions below for more detail
    <<eventType>>       -1                                                  stap UI exit event (similar to html5 onbeforeunload); user->task message on this event would be: [<<ums>>,0,[1]]
    <<eventType>>       0                                                   stap UI ready event (similar to html5 onload); user->task message on this event would be: [<<ums>>,0,[0]]
    <<eventType>>       1                                                   stap change-start event; this is the event sent back when property updates that include "R":1 (or "R":3) flag begin
    <<eventType>>       2                                                   stap change-end event; this is the event sent back after an animation that included "R":2 (or "R":3) flag is complete
    <<eventType>>       10                                                  item focus event; user->task message on this event would be: [<<ums>>,<<id>>,[10]]
{'fraction_non_alphanumeric': 0.14196514017665238, 'fraction_numerical': 0.015876751227624292, 'mean_word_length': 2.4780378676269983, 'pattern_counts': {'":': 563, '<': 1431, '<?xml version=': 0, '>': 1471, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 233, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '690531', 'n_tokens_mistral': 16863, 'n_tokens_neox': 15824, 'n_words': 6661}