This is liza.info, produced by makeinfo version 6.3 from liza.texi. This manual is for the Liza Data Collection Framework, version 7.4.9. Copyright © 2014, 2017, 2018 R-T Specialty, LLC. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”. _ This manual contains inline notes for developers of Liza.(1) For an index of notes, see *note Developer Notes Index::._  File: liza.info, Node: Top, Next: Design, Up: (dir) Main **** * Menu: * Design and Architecture:Design. Design and structure of framework * Assertions:: * Bucket:: * Client:: * Data API:: * Predicate System:: * Program:: * Server:: * Validation:: * Hacking:: Information for developers of Liza * License:: Document License * Concept Index:: * Developer Notes Index:: Index of pertenant notes for developers of Liza. This manual is for the Liza Data Collection Framework, version 7.4.9. Copyright © 2014, 2017, 2018 R-T Specialty, LLC. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”. ---------- Footnotes ---------- (1) To disable for user documentation, pass ‘--disable-devnotes’ to ‘configure’.  File: liza.info, Node: Design, Next: Assertions, Prev: Top, Up: Top 1 Design & Architecture *********************** Liza is fundamentally a data collection framework—a fancy form for collecting, validating, and lightly processing user data. The main components of the system are: *Assertions* Basic validations against bucket data, producing errors and manipulating control flow. Invokes triggers to manipulate the UI and document. Assertions are compiled from Program sources. *Note Assertions::. *Bucket* The key/value store into which all document data are stored. Supports staging and rollback of data, processing deltas, and provides hooks that drive the rest of the system. *Note Bucket::. *Client* Basic logic for navigating between steps, prompting for user actions, display help text and basic document data, communicate with server, etc. *Note Client::. *Data API* Declarative abstraction for accessing and processing remote data (e.g. a RESTful service). *Note Data API::. *Developer Dialog* Renders information about the system for debugging the client. Can monitor the bucket, assertions, classification results, and provides other useful features. *Predicate System* Processes classification data from external classifiers to determine applicability of specific questions. These data are used to determine what assertions are performed, what questions and groups display, and more. *Note Predicate System::. *Program* Internal representation of the Program with delegation of events to the assertion system. Contains compiled representation of all steps, groups, questions, assertions, metadata, and others. *Note Program::. *Program UI* Rendering of elements specific to Programs, such as steps, groups, and questions. This is the equivalent of an HTML form. Directly monitors the bucket to perform UI updates. *Note Program UI::. *Program XML* The source code for a Program, in XML format. *Note Program XML::. *Server* Provides REST API for serving Programs; saving data; revalidating, filtering, and recalculating data; and other types of processing. Code is shared with the client, ensuring identical behavior for appropriate behaviors. *Note Server::. *Type Validation* Validates and formats bucket values for specific field (question) types. For example, a date field must be in a recognized date format, and will be normalized for display. *Note Validation::. More information about each can be found in their respective chapter/section.  File: liza.info, Node: Assertions, Next: Bucket, Prev: Design, Up: Top 2 Assertions ************ This system has maintenance concerns. (1) _There isn’t much here yet. Maybe you can help?_ ---------- Footnotes ---------- (1) Assertions are compiled from the Program XML (*note Program XML::). Rather than using a library, it compiles a mess of largely duplicate code inline. This system needs to be _replaced_, not modified. A replacement can either be in the form of a library (removing most if not all code generation from the Program XML compiler), or possibly compile into classifications and use the classification system. _The latter option is preferred, and would be more powerful with less maintenance._  File: liza.info, Node: Bucket, Next: Client, Prev: Assertions, Up: Top 3 Bucket ******** _There isn’t much here yet. Maybe you can help?_ * Menu: * Value Assignment:Bucket Assignment. Writing data to the Bucket. * Bucket Diff:: Representing bucket changes. * Calculated Values:: Dynamic data derived from other values. * Metabucket:: Bucket holding document metadata  File: liza.info, Node: Bucket Assignment, Next: Bucket Diff, Up: Bucket 3.1 Bucket Value Assignment =========================== _There isn’t much here yet. Maybe you can help?_  File: liza.info, Node: Bucket Diff, Next: Calculated Values, Prev: Bucket Assignment, Up: Bucket 3.2 Bucket Diff =============== Changes to the bucket are represented by an array with certain conventions: 1. A change to some index k is represented by the same index k in the diff. 2. A value of ‘undefined’ indicates that the respective index has not changed. Holes in the array (indexes not assigned any value) are treated in the same manner as ‘undefined’. 3. A ‘null’ in the last index of the vector marks a truncation point; it is used to delete one or more indexes. The vector will be truncated at that point. Any preceding ‘null’ values are treated as if they were ‘undefined’.(1) Diffs are only tracked at the vector (array of scalars) level—if there is a change to a nested structure assigned to an index, that index of the outer vector will be tracked as modified. It will, however, recursively compare nested changes to determine if a modification _has taken place_.(2) Examples appear in *note Figure 3.1: f:diff-ex. Original Diff Interpretation ---------------------------------------------------------------------------- ‘["foo", "bar"]’ ‘["baz", "quux"]’ Index 0 changed to ‘baz’. Index 1 changed to ‘quux’. ‘["foo", "bar"]’ ‘[undefined, Index 0 did not change. "quux"]’ Index 1 changed to ‘quux’. ‘["foo", "bar"]’ ‘[, "quux"]’ Index 0 did not change. Index 1 changed to ‘quux’. ‘["foo", "bar"]’ ‘["baz", null]’ Index 0 changed to ‘baz’. Index 1 was removed. ‘["foo", "bar", ‘[undefined, null]’ Index 0 was not changed. "baz"]’ Index 1 was removed. Index 2 was removed. ‘["foo", "bar", ‘[null, undefined, Index 0 was not changed. "baz"]’ null]’ Index 1 was not changed. Index 2 was removed. ‘["foo", "bar", ‘[null, null, null]’ Index 0 was not changed. "baz"]’ Index 1 was not changed. Index 2 was removed. Figure 3.1: Bucket diff examples. Diffs are generated by ‘StagingBucket’ (https://gitlab.com/lovullo/liza/tree/master/src/bucket/StagingBucket.js). ‘null’ truncation is understood both by ‘StagingBucket’ and by ‘QuoteDataBucket’ (https://gitlab.com/lovullo/liza/tree/master/src/bucket/QuoteDataBucket.js). A diff is applied to the underlying bucket by invoking ‘StagingBucket#commit’. ---------- Footnotes ---------- (1) The reason for this seemingly redundant (and inconvenient) choice is that JSON encodes ‘undefined’ values as ‘null’. Consequently, when serializing a diff, ‘undefined’s are lost. To address this, any ‘null’ that is not in the tail position is treated as ‘undefined’. We cannot truncate at the first null, because ‘[null,null,null]’ may actually represent ‘[undefined,undefined,null]’. (2) See ‘StagingBucket’ (https://gitlab.com/lovullo/liza/tree/master/src/bucket/StagingBucket.js) method ‘#_parseChanges’.  File: liza.info, Node: Calculated Values, Next: Metabucket, Prev: Bucket Diff, Up: Bucket 3.3 Calculated Values ===================== _There isn’t much here yet. Maybe you can help?_  File: liza.info, Node: Metabucket, Prev: Calculated Values, Up: Bucket 3.4 Metabucket ============== The “metabucket” is a bucket-like key/value store separate from the data bucket.(1) It should be used to save data that should be accessible only to the server, but never the client. Data must still be formatted as a vector, but unlike the data Bucket, vector values are sometimes structured data instead of strings. A standard still needs to be devised to provide guidance for when storing structured data is appropriate, rather than a vector of strings. The client has no means by which to access the metabucket. Custom fields can be populated by server-side DataAPIs (*note Server-Side Data API Calls::). Any fields prefixed with the string ‘liza_’ are reserved and are populated automatically by the Server. They are shown in *note Table 3.1: t:liza-meta. ‘liza_timestamp_initial_rated’ A Unix timestamp representing the first time a document was acted upon by a rating service. This value is set once and is never updated or cleared. Table 3.1: Metabucket fields populated automatically by the Server ---------- Footnotes ---------- (1) It is stored in the ‘meta’ field on the Mongo document.  File: liza.info, Node: Client, Next: Data API, Prev: Bucket, Up: Top 4 Client ******** This system has maintenance concerns. (1) _There isn’t much here yet. Maybe you can help?_ * Menu: * Error Handling:: * Saving to Server:: Posting bucket diff to the Server. ---------- Footnotes ---------- (1) The client is largely managed by a single class, ‘Client’ (https://gitlab.com/lovullo/liza/tree/master/src/client/Client.js), which has grown out of control. ‘Client’ mediates essentially the entire system. Code is to be extracted out of this class as it is touched. The other system mammoth is ‘Ui’ (*note Program UI::).  File: liza.info, Node: Error Handling, Next: Saving to Server, Up: Client 4.1 Error Handling ================== This system has maintenance concerns. (1) There are three layers of error checking:(2) 1. Required field checking—whether all required questions have been answered. 2. Type Validation—verify that questions contain valid data according to their declared type. *note Validation::. 3. Assertions—arbitrary checks on data. *note Assertions::. Required fields fail serially—the system will notify the user of the required field, and direct him/her to it (usually through scrolling). A field is marked as “fixed” according to the rules in *note Managing Error State::. * Menu: * Managing Error State:: Determining when failures should be marked as “fixed” ---------- Footnotes ---------- (1) The complexity of this system and integration into legacy layers has caused maintenance trouble in the past. Each of the error checking layers need to be integrated to reduce complexity. (2) Primarily for legacy reasons. They are being consolodated as the system is touched.  File: liza.info, Node: Managing Error State, Up: Error Handling 4.1.1 Managing Error State -------------------------- Each failure caused by assertions is associated with a “failure stack”. The stack represents the trail of assertions that have run, containing the ids of all values asserted against. When any field or classification changes that is represented on the failure stack, the failure for the failed field associated with that failure stack is cleared. *Example:* If an assertion for some question FOO first checked the value of bucket field BAR, and within its failure checked the value C:PREDICATE, the failure stack would contain both of those ids. If either BAR or the PREDICATE classification changed, the question FOO would have its error cleared. Error state is managed by ‘ValidStateMonitor’ (https://gitlab.com/lovullo/liza/tree/master/src/validate/ValidStateMonitor.js).  File: liza.info, Node: Saving to Server, Prev: Error Handling, Up: Client 4.2 Saving to Server ==================== _There isn’t much here yet. Maybe you can help?_ To save changes, the client posts only the bucket diff (*note Bucket Diff::) to the Server (*note Server::). Because JSON serialization encodes ‘undefined’ values as ‘null’ (as noted in *note Bucket Diff::), and only the null in the tail position marks the truncation point, the Client first truncates the array to include only the first ‘null’.(1) An example is shown in *note Figure 4.1: f:client-diff. // given (two unchanged, three removed) [ undefined, undefined, null, null, null ] // encodes into JSON as (bad; represents four unchanged, one removed) [ null, null, null, null, null ] // Client truncates to (two unchanged, >=2 removed) [ null, null, null ] Figure 4.1: Client diff truncation This conversion is handled by ‘XhttpQuoteTransport’ (https://gitlab.com/lovullo/liza/tree/master/src/client/transport/XhttpQuoteTransport.js). Examples can be found in the respective test case ‘XhttpQuoteTransport’ (https://gitlab.com/lovullo/liza/tree/master/test/client/transport/XhttpQuoteTransport.js). ---------- Footnotes ---------- (1) The server would otherwise remove only the last index, even if multiple indexes were removed.  File: liza.info, Node: Data API, Next: Predicate System, Prev: Client, Up: Top 5 Data API ********** This system has maintenance concerns. (1) _There isn’t much here yet. Maybe you can help?_ The “Data API” is a declarative abstraction for accessing and processing remote data (e.g. a RESTful service). The name stems from how it is used—to declare an remote API’s inputs and outputs. This system is generally used indirectly through the *note Program XML: Program XML.(2) All interaction with this system should be had through the ‘DataApiManager’ (https://gitlab.com/lovullo/liza/tree/master/src/dapi/DataApiManager.js). The ‘DataApiManager’ (https://gitlab.com/lovullo/liza/tree/master/src/dapi/DataApiManager.js) manages the entire operation—from triggering the initial request, to performing mapping, to populating bucket data. It takes only a ‘DataApiFactory’ (https://gitlab.com/lovullo/liza/tree/master/src/dapi/DataApiFactory.js) and Data API definitions. Definitions have the following schema:(3) { "type": "string", "source": "string", "method": "string", "params": { ["string(name)"]: { "name": "string(name)", "default": { "type": "string", "value": "string" }, ... }, }, "retvals": [ "string", ... ], "static": [ { ["string(param)"]: "string", ... }, ... ], "static_nonempty": boolean, "static_multiple": boolean } Each of the above fields are defined by: ‘type’ Any type supported by ‘DataApiFactory’ (https://gitlab.com/lovullo/liza/tree/master/src/dapi/DataApiFactory.js) (e.g. ‘rest’). ‘source’ Type-specific source of data. For e.g. ‘rest’, this is a URI. ‘method’ Type-specific method for interacting with the API. For e.g. ‘rest’, this is an HTTP method. ‘params’ Key-value mapping of input parameter names (as received by ‘source’) to their default values. These inputs must be populated by the caller at the time of the request. ‘retvals’ Array of fields returned by the data source. ‘static’ Static values to prepend to the returned data. This is often used for adding “please select” text, for example. ‘static_nonempty’ Whether statics should be added when there is return data; Otherwise, they will be added only if the response yields no results. ‘static_multiple’ Whether statics should be added only if multiple data are returned. For example, a “please select” is only useful if there is more than one option for the user to select from. When ‘true’, this has the convenient side-effect of auto-selecting the only result. An example definition appears in *note Figure 5.1: f:dapi-ex. { "type": "rest", "source": "/foo/city", "method": "post", "params": { "getVal": { "name": "getVal", "default": { "type": "string", "value": "getCityOptions" } }, "zipcode": { "name": "zipcode", "default": { "type": "ref", "value": "" } } }, "retvals": [ "city", "id", "state", "county", "country" ], "static": [ { "city": "(Please Select)", "id": "", "state": "", "county": "", "country": "" } ], "static_nonempty": false, "static_multiple": true }, Figure 5.1: Example Data API definition ---------- Footnotes ---------- (1) This is a complex system with too much logic lying in ‘DataApiManager’ (https://gitlab.com/lovullo/liza/tree/master/src/dapi/DataApiManager.js) (having been extracted from its old home in ‘Program’ (https://gitlab.com/lovullo/liza/tree/master/src/program/Program.js) ). (2) See ‘Data API’ in the Liza Program UI Compiler manual. (3) There are poor design decisions that will likely persist indefinitely because of integration with other systems, so future extensions may be messy (especially in the case of ‘retvals’).  File: liza.info, Node: Predicate System, Next: Program, Prev: Data API, Up: Top 6 Predicate System ****************** This system has maintenance concerns. (1) For a practical application of these concepts, see its use in the Program XML (*note Specifying Predicates::). The “predicate system” determines the “applicability” of certain objects (like questions and assertions) by associating them with predicates. The domain of discourse (variables which may be quantified) is listed in *note Table 6.1: t:predicate-dod. What it means for some object to be applicable depends on the context. Type Prefix Description --------------------------------------------------------------------------- Classifications _None_ Results of applying an external “classifier” to the bucket (*note Bucket::). Bucket Truth ‘q:’ Whether the given name in the bucket Predicate (*note Bucket::) is non-empty and non-zero. The prefix ‘q:’ refers to its most common use case—questions (*note Program UI: Program UI.). Table 6.1: Predicate system domain of discourse This system is limited to existential quantification over the domain of discourse. For other quantifiers and higher-order logic, defer to one of the systems that contributes to the domain of discourse, like the classifier.(2) Predicates are usually specified in the Program XML (*note Specifying Predicates::) and compiled into the program (*note Program::). ---------- Footnotes ---------- (1) New programs (using the old incarnation of TAME) use the classifier embedded into the rater by TAME. Old ones, however, still use the “Global Classifier”. This system isn’t as well tested as TAME’s—which needs to work properly for the sake of calculating premium—and has suffered from a number of bugs in the past. The solution is to migrate all programs to TAME and remove that old code. (2) This is usually TAME. The Program XML also supports inline classifications with TAME’s syntax (*note Specifying Predicates::).  File: liza.info, Node: Program, Next: Server, Prev: Predicate System, Up: Top 7 Program ********* This system has maintenance concerns. (1) The “Program” is a declarative representation of an entire system. It is the highest level of abstraction from a data perspective. The user observes and interacts with a Program using the *note Program UI: Program UI. Programs contain a lot of metadata that is not in a convenience human-readable (or modifiable) format, some of which are redundant. Programs are ideally compiled from a *note Program XML: Program XML. document. * Menu: * Program UI:: * Program XML:: * Document Metadata:: Document-level data that cannot be modified by the client. ---------- Footnotes ---------- (1) The ‘Program’ class was one of the first prototypes created, and has evolved poorly with the rest of the system. It is the base class for all compiled programs, and it glues together too many other systems with a terrible API and little to no encapsulation. With that said, it is one of the least touched classes (thus its state); developers rarely have the need to touch ‘Program’.  File: liza.info, Node: Program UI, Next: Program XML, Up: Program 7.1 Program UI ============== This system has maintenance concerns. (1) The “Program UI” renders a *note Program:: as a form. At the highest level, steps are rendered in a tab-like manner, above the main form content. A step contains groups, which in turn contain elements such as questions. Groups are delimited in some manner defined by their style (*note Group Styles::). Questions are rendered as form fields. Any time the respective *note Bucket:: field is changed, the form field is updated to reflect those changes, after having first been formatted with the appropriate validator (*note Formatting Values::). When a question is changed by the user, the value is expected to be propagated to the Bucket (*note Bucket Assignment::). Navigation between steps can be done via the “Navigation Bar” above the step content, or using “Go Back” and “Continue” buttons at the foot of the step content. A “Sidebar” is rendered adjacent to the step content. It displays the name of the Program, as well as configurable metadata (usually through the ‘sidebar’ node of the *note Program XML: Program XML.). It also displays question help text (also configured through the XML) and any error messages (*note Error Handling::). * Menu: * Group Styles:: Different ways of displaying groups of questions to the user. * DOM Abstraction :: Representing and efficiently manipulating the DOM. ---------- Footnotes ---------- (1) The ‘Ui’ class, in addition to ‘Client’ (https://gitlab.com/lovullo/liza/tree/master/src/client/Client) (*note Client::), represent the two monoliths of the system. This mediates all UI-related tasks, and still has far too many concerns with far too many dependencies. Code is to be extracted out of this class as it is touched.  File: liza.info, Node: Group Styles, Next: DOM Abstraction, Up: Program UI 7.1.1 Group Styles ------------------ _Portions of this system need refactoring.(1)_ Groups support a number of “group styles” that determine how they are delimited from other groups (*note Defining Groups::); how the elements they contain are rendered and laid out; and how multiple indexes are displayed, added, and removed. A list of available styles is detailed in *note Table 7.1: t:group-styles. Name Description Multi-Index?Add/Remove Index? ---------------------------------------------------------------------------- ‘default’ Groups are unstyled by default—they render N N elements as flat fields like a traditional form. Only the first index of elements is rendered. ‘accordion’ Styled as a ‘stacked’ group with a header Y N that toggles the body associated with that index. When collapsed, only the header is visible for that index. The default styling indicates the collapsed status using an arrow in the header. ‘collapsetable’Renders element label in the leftmost column Y Add like ‘sidetable’. Indexes are groups of rows delimited by headings, which collapse the respective group of rows when clicked. ‘sidetable’ Renders elements as rows with label in the Y Add leftmost column rather than the top row. Each index is rendered as a column. ‘stacked’ Groups respective indexes of elements such Y N that one set of indexes appears atop of another set, much like separate groups are placed. ‘tabbedblock’Each group is rendered as a block, with each Y N index rendered as a tab to the right of it. Clicking a tab toggles the body content to the associated index. Elements are rendered within the box. ‘tabbed’ Like ‘default’, but each index has a tab at Y Y the top of the group. Clicking a tab toggles the body content to the associated index. ‘table’ A vanilla table with elements as columns, Y Y their labels across the top row. Each index is rendered in its own row. Table 7.1: Group styles and index support ---------- Footnotes ---------- (1) Some group styles still use jQuery; they should be modified to use modern formatters and Liza DOM abstractions (see ‘src/ui/field’ (https://gitlab.com/lovullo/liza/tree/master/src/ui/field) and ‘src/ui/styler’ (https://gitlab.com/lovullo/liza/tree/master/src/ui/styler)).  File: liza.info, Node: DOM Abstraction, Prev: Group Styles, Up: Program UI 7.1.2 DOM Abstraction --------------------- _jQuery is still used throughout parts of the framework and is a performance bottleneck—it needs to be fully removed and replaced with this DOM abstraction.(1)_ Liza was conceived long before frameworks like React existed. The implementation originally used Dojo because of its broad widget set, but it was later dropped because of extreme performance issues, especially on the browsers of the day (Liza had to support Internet Explorer 6!); at one point, certain steps took over a minute to load for the most unfortunate of users. jQuery was then used for various parts of the UI and for ease of DOM manipulation, because of the lack of good and universal DOM APIs back then. It too became a bottleneck. Using DOM APIs is now easy with modern browsers. Liza’s DOM abstraction contains a couple of components: • “DOM Fields” represent a field on the DOM. Each field has a name and an index associated with the DOM node. Nodes are cached in memory after first access and queue requests during lookups to prevent stampeding. Provides basic DOM operations, including styling, containing row, and parent/sibling selecting. See ‘’ (https://gitlab.com/lovullo/liza/tree/master/src/ui/field). • “DOM Context” is a slice of the DOM used for restricting queries. It can attach and detach sections of the DOM, and be further split into a context hierarchy. The ‘DomContext’ (https://gitlab.com/lovullo/liza/tree/master/src/src/ui/context/DomContext.js) provides field querying (see ‘DomField’ (https://gitlab.com/lovullo/liza/tree/master/src/src/ui/field/DomField.js)) and caching. See ‘src/ui/context’ (https://gitlab.com/lovullo/liza/tree/master/src/ui/context). It is important to always use these abstractions for any portions of the DOM under control of this abstraction; otherwise, assumptions used for caching may result in unintended behavior. Using DOM contexts, DOM operations can be restricted to small windows (for example, groups or tabs), further reducing the impact of DOM queries. The “root context” is represented by ‘RootDomContext’ (https://gitlab.com/lovullo/liza/tree/master/src/src/ui/context/RootDomContext.js)—sub-contexts can be obtained by invoking ‘#slice’ on any context, which creates a new context from a subset of the parent. Detaching a parent will detach all child contexts. Contexts can be manipulated in memory before being re-attached. Detach a context from the DOM with ‘#detach’, and attach with ‘#attach’. A context is aware of its parent and will re-attach itself to the DOM in the correct place. A child context always attaches to the parent, and so will not be rendered until the parent attaches. Always detach from the DOM before performing extensive manipulations; this prevents the need for expensive re-painting until manipulation is done, at which point the context can be re-attached. * Menu: * Field Styling:: Styling ‘DomField’ (https://gitlab.com/lovullo/liza/tree/master/src/src/ui/field/DomField.js). ---------- Footnotes ---------- (1) See ‘src/ui/ElementStyler’ (https://gitlab.com/lovullo/liza/tree/master/src/ui/ElementStyler).  File: liza.info, Node: Field Styling, Up: DOM Abstraction 7.1.2.1 Field Styling ..................... _There isn’t much here yet. Maybe you can help?_ ‘DomField’ (https://gitlab.com/lovullo/liza/tree/master/src/src/ui/field/DomField.js) is styled using field stylers (see ‘src/ui/styler’ (https://gitlab.com/lovullo/liza/tree/master/src/ui/styler)). The two most notable stylers are ‘’ (https://gitlab.com/lovullo/liza/tree/master/src/src/ui/field/ErrorFieldStyler/.js) and ‘’ (https://gitlab.com/lovullo/liza/tree/master/src/src/ui/field/NaFieldStyler/.js), which style fields in error and hide fields that are no applicable respectively.  File: liza.info, Node: Program XML, Next: Document Metadata, Prev: Program UI, Up: Program 7.2 Program XML =============== _There isn’t much here yet. Maybe you can help?_ * Menu: * Defining Groups:: Grouping questions and other entities. * Specifying Predicates:: Predicating display of entities.  File: liza.info, Node: Defining Groups, Next: Specifying Predicates, Up: Program XML 7.2.1 Defining Groups --------------------- A “group” organizes and relates entities. If given a ‘@title’, a header will be displayed above the group with that title. A group may optionally be given a unique identifier ‘@id’, which is useful for debugging and scripting; any such identifier should be ‘snake_case’. Figure 7.1: Defining a simple group with a title Groups can be independently styled in a number of different ways to provide different data representations (*note Group Styles::). Style is optional—the ‘default’ group displays only the first index of each entity. Further styling can be done using CSS using ‘@class’. All questions within a group share the same number of indexes; this is accomplished by monitoring the “group leader”. By default, the leader is the first indexable entity in the group (question, answer, or display); this can be overridden with the ‘@indexedBy’ attribute. This attribute is only practically meaningful if the chosen group style supports indexes (*note Group Styles::). Figure 7.2: Overriding group leader using ‘@indexedBy’ Some group styles allow the user to add indexes; set ‘@locked’ to ‘true’ to suppress this feature. 7.2.1.1 Linking Groups ...................... Data collection for similar entities may span multiple steps or groups; for example, one group may allow the user to define their risk locations, and a future group may ask for additional information for each of those locations. To have all entities within each of those groups share index length, they may be linked. A “group link” is an arbitrary name given to a set of groups. Each group that wants to be part of the same link must set ‘@link’ to the same string. The name of the link does not matter—it is _not_ a reference to a group ‘@id’. Figure 7.3: Linking groups using ‘@link’ In *note Figure 7.3: f:group-link, each question in LOCATION and UNDERWRITING will have the same number of indexes—any time a new index is added to LOCATION, UNDERWRITING questions too will gain another index and vice versa. There is no limit to the number of groups that can share the same link. Linked groups are implemented such that the union of all fields in each of the groups of a given link are assigned to each of the individual groups. When the leader of any group changes, a new index is initialized for each group field, which (in the case of linked groups) is comprised of all fields in the link.  File: liza.info, Node: Specifying Predicates, Prev: Defining Groups, Up: Program XML 7.2.2 Specifying Predicates --------------------------- Object predicates (*note Predicate System::) are specified using the ‘@when’ attribute of certain nodes. It must contain a string of references understood by the system (see domain of discourse, *note Predicate System::), all of which much match for the predicate to be true. Figure 7.4: Using the ‘@when’ attribute In *note Figure 7.4: f:pred-when. above, question ‘vacant_desc’ will be applicable when _all_ of the values of ‘vacant’, ‘property’, and ‘q:describe’ are true.(1) Within the context of the Program XML, this concretely means that the classifications ‘vacant’ and ‘property’ are true, and that the question ‘describe’ is answered “yes”. It reads as a sentence: “‘vacant_desc’” is applicable when we should “describe a vacant property”. ---------- Footnotes ---------- (1) *Note Predicate System:: for what “true” means for a particular variable in the domain of discourse.  File: liza.info, Node: Document Metadata, Prev: Program XML, Up: Program 7.3 Document Metadata ===================== “Document metadata” are metadata that describe certain aspects of the document; they are stored adjacent to the bucket in ‘meta’ on the document root.(1) They should be used in place of a bucket field any time the client has no business knowing about the data. The ‘meta’ record is called the “Metabucket”. Metadata in the Metabucket should _not_ be directly populated by external systems—Data API integration should be used instead (see below). Metadata can be populated using any Data API (*note Data API: Data API.)—return data populate the Metabucket in the same way that they populate the Bucket. Definitions are stored in ‘meta.fields’, as shown in *note Figure 7.5: f:meta-fields. "fields":{ ["string(name)": { "desc": "string", "dapi": { "name": "string", "map": { "string(dest field)": "string(source field)" } } } } Figure 7.5: Format of ‘meta.fields’. Further, a key-value mapping of all bucket fields that—when modified, need to result in a metadata API call—are stored in the ‘mapis’ object; this is shown in *note Figure 7.6: f:mapis. "mapis":{ ["string(field name)"]: [ "string(dapi name)", ... ] } Figure 7.6: Format of ‘mapis’. ---------- Footnotes ---------- (1) Terminology note: “document” and “quote” are the same thing; the latter is transitioning to the former for generality.  File: liza.info, Node: Server, Next: Validation, Prev: Program, Up: Top 8 Liza Server ************* This system has maintenance concerns. (1) _There isn’t much here yet. Maybe you can help?_ The “server”(2) is a RESTful service that serves as the HTTP server. It is designed to run under Node.js, motivated by the benefits of sharing code with the Client (*note Client::). The daemon is handled by the abstract ‘Daemon’ (https://gitlab.com/lovullo/liza/tree/master/src/server/daemon/Daemon.js) monolith, which requires that a concrete ‘#getEncryptionService’ method be defined by a subtype or trait. An example script to start the server is shown in *note Figure 8.1: f:server-start. For local development, or to avoid use of any encryption service, use ‘DevDaemon’ (https://gitlab.com/lovullo/liza/tree/master/src/server/daemon/DevDaemon.js), which uses a dummy encryption service. To start the server, invoke ‘bin/server’ (https://gitlab.com/lovullo/liza/tree/master/bin/server). You may also invoke ‘bin/server.js’ (https://gitlab.com/lovullo/liza/tree/master/bin/server.js) directly using Node.js, but the use of ‘’ (https://gitlab.com/lovullo/liza/tree/master/bin/server) is recommended, as it uses the Node.js executable determined at configure-time, along with any command-line options required for Liza Server to function correctly. Additional options can be provided to Node.js using the NODE_FLAGS environment variable, which will be _appended_ to the configure-time flags. This environment variable is _not_ escaped or quoted, so be mindful of word expansion. $ bin/server -c path/to/config.json # providing additional options to node $ NODE_FLAGS=--debug bin/server -c path/to/config.json Figure 8.1: Starting the Liza Server The HTTP server is managed by ‘http_server’ (https://gitlab.com/lovullo/liza/tree/master/src/server/daemon/http_server.js). * Menu: * Configuration:Server Configuration. Server configuration. * Requests:: Handling HTTP requests. * Posting Data:: Handling step saves and other posts. * Server-Side Data API Calls:: Accessing external resources on the server. * Encryption Service:: Managing sensitive data. ---------- Footnotes ---------- (1) The ‘Daemon’ (https://gitlab.com/lovullo/liza/tree/master/src/server/daemon/Daemon.js) monolith and ‘Server’ (https://gitlab.com/lovullo/liza/tree/master/src/server/Server.js), among other things, need refactoring. Quote initialization code should be moved into ‘ProgramInit’ (https://gitlab.com/lovullo/liza/tree/master/src/server/ProgramInit.js). (2) Which may also be referenced as “quote server” in certain legacy contexts, referring to Liza’s origin as an insurance rating system.  File: liza.info, Node: Server Configuration, Next: Requests, Up: Server 8.1 Configuration ================= _There isn’t much here yet. Maybe you can help?_ Liza is migrating to actual configuration file in place of environment variables. If no configuration is explicitly specified, it uses ‘conf/vanilla-server.json’ (https://gitlab.com/lovullo/liza/tree/master/conf/vanilla-server.json). Configuration loading is handled by ‘ConfLoader’ (https://gitlab.com/lovullo/liza/tree/master/src/conf/ConfLoader.js). The configuration store ‘ConfStore’ (https://gitlab.com/lovullo/liza/tree/master/src/conf/ConfStore.js) is asyncrhonous, so loading configuration from any external system is supported.(1) ---------- Footnotes ---------- (1) Provided that you write the code to load from that system, that is.  File: liza.info, Node: Requests, Next: Posting Data, Prev: Server Configuration, Up: Server 8.2 HTTP Requests ================= _There isn’t much here yet. Maybe you can help?_ Each HTTP request produces a ‘UserRequest’ (https://gitlab.com/lovullo/liza/tree/master/src/server/request/UserRequest.js) associated with a ‘UserSession’ (https://gitlab.com/lovullo/liza/tree/master/src/server/request/UserSession.js). Sessions are tightly coupled with PHP(1); an existing PHP session is expected, as identified by the ‘PHPSESSID’ cookie. Sessions are shared via Memcache (see ‘ResilientMemcache’ (https://gitlab.com/lovullo/liza/tree/master/src/server/cache/ResilientMemcache.js)).(2) If a session is not found (or is invalid), an HTTP ‘500’ status code is returned and the HTTP request is aborted. Requests are subject to a 120 second timeout, after which the request will be served an HTTP ‘408’ status code. Note that this _does not stop background processing_—this timeout exists to prevent the user from hanging indefinitely. If a process intends to perform background processing for any length of time (longer than a few seconds), it should complete the request as quickly as possible and use some other mechanism to report back progress (e.g. polling). The ‘UserRequest’ (https://gitlab.com/lovullo/liza/tree/master/src/server/request/UserRequest.js) exposes raw request data with minor processing. *Path (‘#getUri’)* The path component of the URI. The method name is unfortunate. *Query data (‘#getGetData’)* Query string processed into a key/value object. Despite the name, this is also populated if non-GET requests contain query strings. *POST data (‘#getPostData’)* POST data processed into an object as if it were a query string (just as ‘#getGetData’). Since this requires data that is streamed asynchronously, this method takes a callback that waits for all data to become available; if the data are already available, it is immediately invoked with the processed POST data. *Cookies (‘#getCookies’)* Cookies parsed into a key/value object. *Remote address (‘#getRemoteAddr’)* IP address of the origin of the request. If the server is behind a proxy that sets the ‘X-Forwarded-For’ header, it is used instead. *Host address (‘#getHostAddr’)* Hostname of the server. If the server is behind a proxy that sets the ‘X-Forwarded-Host’ header, it is used instead. *Origin (‘#getOrigin’)* Origin of request. Only available if at lease one of the ‘Origin’ or ‘Referer’ headers are set. This is useful mainly for determining the protocol and host while behind a proxy. *User agent (‘#getUserAgent’)* The user agent string of the request. *Session ID (‘#getSessionId’)* The user’s unique session id (‘PHPSESSID’). *Session ID name (‘#getSessionIdName’)* The name of the cookie from which the session ID originated (hard-coded to ‘PHPSESSID’). _TODO: Document return format and writing response data._ ---------- Footnotes ---------- (1) They don’t have to be—refactoring is needed. (2) Via a memcache session handler (https://secure.php.net/manual/en/memcached.sessions.php).  File: liza.info, Node: Posting Data, Next: Server-Side Data API Calls, Prev: Requests, Up: Server 8.3 Posting Data ================ A diff of the bucket data (*note Bucket Diff::) is posted to the server on step save. This operation is performed asynchronously—the client need not wait for the step to save before the next can be requested. Since validations are shared between the server and the client (*note Validation::), saving should only fail in exception situations. Should a failure occur, the server will instruct the client to kick the user back to the previous step (“kickback”). A step cannot be saved if it is locked; such attempts will result in an error. To prevent a user from skipping steps, the client may post only one step past the last step that has successfully saved; otherwise, the user is kicked back to the last step that was saved. Once those basic checks have passed, the document is updated: 1. The diff is first “sanitized” to strip out unknown fields, internal fields posted by non-internal users, and to filter fields on permitted characters; 2. The sanitized diff is then applied to the existing bucket on the document; 3. Calculated values marked for storage (*note Calculated Values::) are re-calculated on the server (the values posted by the client have already been discarded by the first step in this list); 4. Server-side Data API calls (*note Data API::) are triggered using the diff as input data and an empty bucket for response storage (*note Server-Side Data API Calls::); 5. The last premium calculation date is cleared (indicating that premiums are no longer valid);(1) 6. Data marked as sensitive is encrypted and the ciphertext written to the bucket in place of the plaintext (*note Encryption Service::); 7. The current step is incremented and the “top visited step” is set to the larger of the incremented step or the existing top visited step id; and then 8. The new document state and bucket data are written to the database. ---------- Footnotes ---------- (1) This concept is tightly coupled with insurance; it should be factored out at some point.  File: liza.info, Node: Server-Side Data API Calls, Next: Encryption Service, Prev: Posting Data, Up: Server 8.4 Server-Side Data API Calls ============================== This system has maintenance concerns. (1) Server-side Data API calls (*note Data API::) are triggered on step save (*note Posting Data::) and are handled much like they are on the client. Such calls are made automatically only for document metadata. Results of sever-side calls are _not_ written to the bucket and are therefore useful for data that the client should not be permitted to modify; it also allows data to be kept secret from the client.(2) Data API results on the client can be mapped back to multiple bucket values; the server, however, has serious concerns with how data are propagated for data integrity and security reasons. Further, document metadata can be structured, unlike the Bucket which has a rigid matrix format (*note Bucket::). Therefore, the entire response is mapped into the parent field; defined return values are used only for filtering. When a DataAPI request is made, it supercedes any previous requests that may still be pending for that same index. ---------- Footnotes ---------- (1) This makes use of ‘DapiMetaSource’ (https://gitlab.com/lovullo/liza/tree/master/src/server/meta/DapiMetaSource.js) to encapsulate the horrible API of ‘DataApiManager’ (https://gitlab.com/lovullo/liza/tree/master/src/dapi/DataApiManager.js); the latter needs cleanup to remove the former. (2) All bucket data is served to the client, with the exception of internal fields if the user is non-internal.  File: liza.info, Node: Encryption Service, Prev: Server-Side Data API Calls, Up: Server 8.5 Encryption Service ====================== _There isn’t much here yet. Maybe you can help?_  File: liza.info, Node: Validation, Next: Hacking, Prev: Server, Up: Top 9 Validation ************ _There isn’t much here yet. Maybe you can help?_ * Menu: * Formatting Values::  File: liza.info, Node: Formatting Values, Up: Validation 9.1 Formatting Values ===================== _There isn’t much here yet. Maybe you can help?_  File: liza.info, Node: Hacking, Next: License, Prev: Validation, Up: Top 10 Hacking Liza *************** _There isn’t much here yet. Maybe you can help?_ This chapter provides general information and guidance for [prospective] developers of Liza. For writing classes; interfaces; and traits, developers should familiarize themselves with GNU ease.js (https://www.gnu.org/software/easejs). For writing unit tests, developers should be familiarize themselves with Mocha (https://mochajs.org/) and Chai (http://www.chaijs.com/). For more information on the libraries used by Liza, see *note Libraries::. Most source files have a general structure that must be followed. For example, all such files must have a copyright header and must be named after the class they define or system under test. For more information, *note Source Files::. Generally speaking, developers should be familiar with vanilla ECMAScript; DOM APIs; and have a basic understanding of Node.js for well-rounded Liza development. Writing this manual requires basic understanding of Texinfo. References for these topics and others are provided in *note Developer Resources::. * Menu: * Source Files:: Conventions for project files * Libraries:: The few libraries used by Liza * Developer Resources:: Where to look for more information * TypeScript Migration:: Information on migrating to TypeScript  File: liza.info, Node: Source Files, Next: Libraries, Up: Hacking 10.1 Source Files ================= _There isn’t much here yet. Maybe you can help?_ This section describes conventions for organizing files, both in directory structure and in content. * Menu: * Copyright Header:: Important header at the top of all source files * ECMAScript Strict Mode:Strict Mode. Always indicate strict mode  File: liza.info, Node: Copyright Header, Next: Strict Mode, Up: Source Files 10.1.1 Copyright Header ----------------------- Every source file should begin with a copyright header including the appropriate years and license information. This ensures that this information is always available even if the file becomes separated from the source distribution (e.g. is distributed independently). Further, it is necessary to indicate that the source file is distributed under the GNU General Public License version 3 _or later_—that “or later” clause does not exist as part of the license itself, and so the mere presence of the license in ‘COPYING’ is insufficient. The copyright headers vary slightly between JavaScript and Texinfo source files, represented in *note Figure 10.1: f:cheader-js. and *note Figure 10.2: f:cheader-texi. respectively. /** * DESCRIPTION OF FILE * * Copyright (C) 2017, 2018 R-T Specialty, LLC. * * This file is part of the Liza Data Collection Framework * * Liza is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ Figure 10.1: Example copyright header for JavaScript files @c This document is part of the Liza Data Collection Framework manual. @c Copyright (C) 2018 R-T Specialty, LLC. @c @c Permission is granted to copy, distribute and/or modify this document @c under the terms of the GNU Free Documentation License, Version 1.3 @c or any later version published by the Free Software Foundation; @c with no Invariant Sections, no Front-Cover Texts, and no Back-Cover @c Texts. A copy of the license is included in the section entitled ``GNU @c Free Documentation License''. Figure 10.2: Example copyright header for JavaScript files For more information, see “How to Apply These Terms to Your New Programs” under the GNU General Public License version 3 (https://www.gnu.org/licenses/gpl.html).  File: liza.info, Node: Strict Mode, Prev: Copyright Header, Up: Source Files 10.1.2 ECMAScript Strict Mode ----------------------------- ECMAScript 5’s Strict Mode (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) throws errors in more situations that may lead to buggy code, allows for better optimization of ECMAScript code during runtime, and prohibits syntax that conflicts with future ECMAScript versions. It also enables certain features, like using ‘let’ inside blocks. It should always be enabled going forward as shown in *note Figure 10.3: f:strict-mode. The statement should immediately follow the copyright header (*note Copyright Header::), before any other code. // Copyright header 'use strict'; // ... Figure 10.3: Enabling strict mode  File: liza.info, Node: Libraries, Next: Developer Resources, Prev: Source Files, Up: Hacking 10.2 Libraries Used =================== Liza does not use many libraries. The primary reason for this was that few libraries useful to Liza existed during its initial development—Node.js and its community was still very young. With that said, care should be taken to ensure that libraries are added only after a careful analysis of its costs and benefits, as they add volatility to the whole system and may also introduce security vulnerabilities outside of our control. They further introduce maintenance obligations for keeping up with newer versions of those libraries and addressing backwards-compatibility concerns. 10.2.1 System Libraries ----------------------- Liza was originally developed using JavaScript (first ECMAScript 3, and then ECMAScript 5). JavaScript does not natively support the classical object-oriented model familiar to users of more traditional classical object-oriented languages like Java, C++, C#, and PHP. Liza is built using GNU ease.js (https://www.gnu.org/software/easejs), which provides those familiar features. The primary language used by developers in the office that created Liza is PHP, which motivated the creation of ease.js to ease the burden of entry. Consequently, Liza is written in a classical object-oriented style rather than using prototypes. The ‘class’ keyword introduced in ECMAScript is largely syntatic sugar around the prototype model and does not address the primary concerns of ease.js, nor does it provide traits. _The project is now migrating toward TypeScript_, so new code should not use ease.js unless required and an effort should be made to move existing code away from ease.js. For more information on this migration, see *Note TypeScript Migration::. 10.2.2 Testing Libraries ------------------------ Mocha (https://mochajs.org/) is used as the test runner for JavaScript unit tests. Chai (http://www.chaijs.com/) is the assertion library. This differs from PHP development where a single system (PHPUnit) encompasses both of these needs. Chai offers a few different styles of assertions (“should”, “expect”, and “assert”); Liza uses “expect” (http://www.chaijs.com/guide/styles/#expect). _A library to aid in mocking TypeScript classes needs to be researched._ 10.2.3 UI Libraries ------------------- jQuery was used in the past, but has been largely purged from the system (and continues to be removed) due to strong performance issues. Further, now that browser APIs have stabalized and Liza no longer needs to support as far back as Internet Explorer 6, the standard DOM APIs are more than sufficient. Liza instead provides its own UI and DOM abstractions (‘src/ui’ (https://gitlab.com/lovullo/liza/tree/master/src/ui)) that have been optimized for Liza’s needs. There are modern frameworks that may overlap with the type of UI operations that Liza performs, as well as certain DOM optimizations that it performs; however, it is unlikely that such frameworks (e.g. React, Angular, Meteor) will ever be integrated, as the cost of doing so exceeds the marginal benefit.  File: liza.info, Node: Developer Resources, Next: TypeScript Migration, Prev: Libraries, Up: Hacking 10.3 Developer Resources ======================== MDN (https://developer.mozilla.org/en-US/docs/Web)(1) is an essential resource for web development in general, especially for JavaScript/ECMAScript and the various Web APIs. It contains resources for all levels, including for those unfamiliar with JavaScript (https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps). All developers should familiarize themselves with the resources available on MDN so that they understand what type of information is readily accessible for future reference. An overview of TypeScript can be found in its Handbook (https://www.typescriptlang.org/docs/handbook/basic-types.html). The language borrows concepts from a number of others, so many concepts may be familiar to you. TypeScript uses structural typing (duck typing). In Liza, we also choose to implement nominal typing using “branding” (‘src/types/misc.d.ts’ (https://gitlab.com/lovullo/liza/tree/master/src/types/misc.d.ts)). A language specification (https://github.com/microsoft/TypeScript/blob/master/doc/spec.md) is also available. The Server (*note Server::) uses Node.js. Although it’s largely abstracted away, there may be times where you need to touch on it, in which case the Node.js documentation (https://nodejs.org/en/docs/) will be helpful. However, it is important to note the version of Node.js that Liza is currently using, as it may be woefully out of date and require looking at older versions of the documentation. This manual is written using Texinfo (https://www.gnu.org/software/texinfo/), which is the documentation format of the GNU operating system. The format is structured and well-suited for software documentation with output in a variety of formats. Looking at the source code of this manual will be helpful—it provides the general structure and numerous macros that are specific to Liza. Data are persisted using MongoDB (https://www.mongodb.com/). Database operations in Liza are abstracted away, but it’s helpful to understand how to query the database directly to understand how the system works and composes its data, and for the purposes of debugging. For information on specific libraries used by Liza, *note Libraries::. ---------- Footnotes ---------- (1) Formerly the “Mozilla Developer Network”; see ”The Future of MDN: A Focus on Web Docs” (https://blog.mozilla.org/opendesign/future-mdn-focus-web-docs/) for the history of the rename.  File: liza.info, Node: TypeScript Migration, Prev: Developer Resources, Up: Hacking 10.4 TypeScript Migration ========================= _There isn’t much here yet. Maybe you can help?_ This section contains notes regarding a migration to TypeScript. It is intended to serve as a guide—it is not prescriptive. 10.4.1 Migrating Away From GNU ease.js -------------------------------------- Liza was originally written in GNU ease.js (https://www.gnu.org/software/easejs). TypeScript now provides many features that ease.js was written to address, though not all (most notably traits). Since ease.js was designed with JavaScript interoperability in mind, and TypeScript generates prototypes from classes, TypeScript classes serve as drop-in replacements under most circumstances. However, subtypes must be migrated at the same time as their parents, otherwise type checking in TypeScript cannot properly be performed. If this is a concern, type assertions (https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-type-assertions) can potentially be used to coerce types during a transition period in conjunction with ease.js’ ‘Class.isA’ (https://www.gnu.org/software/easejs/manual/easejs.html#Type-Checks-and-Polymorphism). Often times you will need to reference a class or interface as a dependency before it has been migrated away from ease.js. To do this, create a corresponding ‘.d.ts’ file in the same directory as the dependency. For example, if a class ‘Foo’ is contained in ‘Foo.js’, create a sibling ‘Foo.d.ts’ file. For more information, see Declaration Files (https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html) in the TypeScript handbook. ease.js implements stackable Scala-like traits. Traits are _not_ provided by TypeScript. Traits will therefore have to be refactored into, for example, decorators or strategies. 10.4.2 Structural Typing ------------------------ TypeScript implements structural typing (https://en.wikipedia.org/wiki/Structural_typing), also called duck typing. This means that any two types sharing the same “shape” are compatible with one-another. For classes, this can be mitigated by defining private members, which then ensures that compatible types are indeed subtypes. Interfaces can be used in either the traditional OOP sense, or as a means to define the shape of some arbitrary object. Since interfaces do not define implementation details, the distinction isn’t important—it does not matter if we receive an instance of an object implementing an interface, or some object arbitrary that just happens to adhere to it. In other instances where we want to distinguish between two values with otherwise compatible APIs, Nominal Typing below. 10.4.3 Nominal Typing --------------------- It is sometimes desirable to distinguish between two otherwise compatible types. Consider, for example, a user id and a Unix timestamp. Both are of type ‘number’, but it’s desirable to ensure that one is not used where another is expected. TypeScript doesn’t directly support nominal typing (https://en.wikipedia.org/wiki/Nominal_typing), where compatibility of data types are determined by name. Liza uses a convention called “branding”, abstracted behind a ‘NominalType’ generic (defined in ‘src/types/misc.d.ts’ (https://gitlab.com/lovullo/liza/tree/master/src/types/misc.d.ts)). type UnixTimestamp = NominalType; type Milliseconds = NominalType; function timeElapsed( start: UnixTimestamp, end: UnixTimestamp ): Milliseconds { return end - start; } const start = 1571325570000; const end = 1571514320000; // this is okay const elapsed = timeElapsed( start, end ); // this is not, since elapsed is of type Milliseconds timeElapsed( start, elapsed ); Figure 10.4: Example of nominal typing Consider the example in *note Figure 10.4: f:nom-type. Both ‘UnixTimestamp’ and ‘Milliseconds’ are a ‘number’ type, but they have been defined in such a way that their names are part of the type definition. Not only does the compiler prevent bugs caused from mixing data, but nominal types also help to make the code self-documenting. If you want to have self-documenting types _without_ employing nominal typing, use type aliases. There are no prescriptive rules for whether a type should be defined nominally. In some cases, it’s useful to use nominal types after having validated data, so that the compiler can enforce that assumption from that point forward. This can be done using type assertions (https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-guards-and-type-assertions). type PositiveInteger = NominalType; const isPositiveInteger = ( n: number ): n is PositiveInteger => n > 0; const lookupIndex( arr: T[], i: PositiveInteger ): T => arr[ i ]; // untrusted input from the user const user_input = readSomeValue(); if ( isPositiveInteger( user_input ) ) { // user_input is now of type PositiveInteger return lookupIndex( data, user_input ); } Figure 10.5: Validating nominal types In *note Figure 10.5: f:nom-assert. above, we only assume something to be a ‘PositiveInteger’ after having checked its value. After that point, we can use TypeScript’s type system to ensure at compile time that we are only using positive integers in certain contexts. _Never cast values (e.g. using ‘user_input’) when type predicates are provided, since that undermines type safety._  File: liza.info, Node: License, Next: Concept Index, Prev: Hacking, Up: Top Appendix A GNU Free Documentation License ***************************************** Version 1.3, 3 November 2008 Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 0. PREAMBLE The purpose of this License is to make a manual, textbook, or other functional and useful document “free” in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference. 1. APPLICABILITY AND DEFINITIONS This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”. Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only. The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text. The “publisher” means any person or entity that distributes copies of the Document to the public. A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License. 2. VERBATIM COPYING You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies. 3. COPYING IN QUANTITY If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. 4. MODIFICATIONS You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement. C. State on the Title page the name of the publisher of the Modified Version, as the publisher. D. Preserve all the copyright notices of the Document. E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice. H. Include an unaltered copy of this License. I. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. K. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. M. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version. N. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section. O. Preserve any Warranty Disclaimers. If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles. You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. 5. COMBINING DOCUMENTS You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements.” 6. COLLECTIONS OF DOCUMENTS You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. 7. AGGREGATION WITH INDEPENDENT WORKS A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate. 8. TRANSLATION Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title. 9. TERMINATION You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License. However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it. 10. FUTURE REVISIONS OF THIS LICENSE The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See . Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document. 11. RELICENSING “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable works thus published on the MMC site. “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization. “Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document. An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008. The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing. ADDENDUM: How to use this License for your documents ==================================================== To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page: Copyright (C) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with...Texts.” line with this: with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.  File: liza.info, Node: Concept Index, Next: Developer Notes Index, Prev: License, Up: Top Concept Index ************* [index] * Menu: * Applicability: Predicate System. (line 12) * Assertions: Design. (line 11) * Bucket: Design. (line 17) * Bucket diff: Bucket Diff. (line 6) * Bucket Diff: Saving to Server. (line 8) * Bucket diff <1>: Posting Data. (line 6) * Bucket Truncation: Saving to Server. (line 8) * Bucket, Updating: Program UI. (line 15) * Calculated values, server-side: Posting Data. (line 32) * Classifier: Predicate System. (line 12) * Client: Design. (line 22) * Configuration: Server Configuration. (line 8) * Data API: Design. (line 27) * Data API <1>: Server-Side Data API Calls. (line 8) * Data sanitization: Posting Data. (line 25) * Database: Developer Resources. (line 42) * Developer Dialog: Design. (line 31) * Document metadata: Server-Side Data API Calls. (line 8) * Documentation: Developer Resources. (line 33) * Dojo, History: DOM Abstraction. (line 6) * DOM: DOM Abstraction. (line 6) * DOM, Context: DOM Abstraction. (line 22) * DOM, Field: DOM Abstraction. (line 22) * Domain of discourse, Predicate: Predicate System. (line 12) * Encryption: Posting Data. (line 43) * Encryption Service: Server. (line 20) * Error: Error Handling. (line 8) * Error Stack: Managing Error State. (line 6) * Error, Fixed: Error Handling. (line 16) * Error, Required: Error Handling. (line 16) * Failure: Error Handling. (line 8) * Failure Stack: Managing Error State. (line 6) * Field, Fixed: Error Handling. (line 16) * Field, Required: Error Handling. (line 16) * Field, Styling: Field Styling. (line 6) * Fixed, Error: Error Handling. (line 16) * Group: Program UI. (line 10) * Group <1>: Defining Groups. (line 6) * Group, Indexes: Defining Groups. (line 24) * Group, Leader: Defining Groups. (line 24) * Group, Linking: Defining Groups. (line 44) * Group, Locking: Defining Groups. (line 38) * Group, Styling: Group Styles. (line 8) * Group, Styling <1>: Defining Groups. (line 19) * HTTP Server: Server. (line 46) * Initial rated date: Metabucket. (line 24) * jQuery: DOM Abstraction. (line 6) * Long-running requests: Requests. (line 25) * Memcache: Requests. (line 8) * Metabucket: Metabucket. (line 6) * Navigation Bar: Program UI. (line 22) * PHPSESSID: Requests. (line 8) * Post: Posting Data. (line 6) * Predicate: Design. (line 36) * Predicate <1>: Predicate System. (line 12) * Predicate <2>: Specifying Predicates. (line 6) * Premium calculation date: Posting Data. (line 40) * Program: Design. (line 42) * Program <1>: Program. (line 8) * Program, User Interface: Design. (line 48) * Program, User Interface <1>: Program UI. (line 8) * Program, XML: Design. (line 53) * Program, XML <1>: Program. (line 13) * Question: Program UI. (line 15) * Question <1>: Formatting Values. (line 6) * Question, Value Formatting: Program UI. (line 15) * Question, Value Formatting <1>: Formatting Values. (line 6) * Quote Server: Server. (line 67) * Request timeout: Requests. (line 19) * Required Field: Error Handling. (line 16) * Saving: Saving to Server. (line 8) * Serialization: Saving to Server. (line 8) * Server: Design. (line 56) * Server <1>: Server. (line 10) * Session: Requests. (line 8) * Sidebar: Program UI. (line 27) * Step: Program UI. (line 10) * Step save: Posting Data. (line 6) * Timeout: Requests. (line 19) * TODO, Missing Docs: Assertions. (line 8) * TODO, Missing Docs <1>: Bucket. (line 6) * TODO, Missing Docs <2>: Bucket Assignment. (line 6) * TODO, Missing Docs <3>: Calculated Values. (line 6) * TODO, Missing Docs <4>: Client. (line 8) * TODO, Missing Docs <5>: Saving to Server. (line 6) * TODO, Missing Docs <6>: Data API. (line 8) * TODO, Missing Docs <7>: Field Styling. (line 6) * TODO, Missing Docs <8>: Program XML. (line 6) * TODO, Missing Docs <9>: Server. (line 8) * TODO, Missing Docs <10>: Server Configuration. (line 6) * TODO, Missing Docs <11>: Requests. (line 6) * TODO, Missing Docs <12>: Encryption Service. (line 6) * TODO, Missing Docs <13>: Validation. (line 6) * TODO, Missing Docs <14>: Formatting Values. (line 6) * TODO, Missing Docs <15>: Hacking. (line 6) * TODO, Missing Docs <16>: Source Files. (line 6) * TODO, Missing Docs <17>: TypeScript Migration. (line 6) * Top visited step: Posting Data. (line 46) * Type Validation: Design. (line 62) * User Interface, Button Navigation: Program UI. (line 22) * User Interface, Navigation Bar: Program UI. (line 22) * User Interface, Program: Design. (line 48) * User Interface, Program <1>: Program UI. (line 8) * Validation, Type: Design. (line 62)  File: liza.info, Node: Developer Notes Index, Prev: Concept Index, Up: Top Developer Notes Index ********************* [index] * Menu: * Chai: Hacking. (line 11) * Chai <1>: Libraries. (line 45) * Copyright Header: Hacking. (line 18) * Copyright Header <1>: Copyright Header. (line 6) * GNU ease.js: Hacking. (line 11) * GNU ease.js <1>: Libraries. (line 19) * GNU General Public License version 3: Copyright Header. (line 6) * GNU General Public License version 3, Or Later: Copyright Header. (line 6) * jQuery: Libraries. (line 60) * Libraries: Hacking. (line 11) * Libraries <1>: Libraries. (line 6) * License: Copyright Header. (line 6) * Maintenance Concern: Assertions. (line 6) * Maintenance Concern <1>: Client. (line 6) * Maintenance Concern <2>: Error Handling. (line 6) * Maintenance Concern <3>: Data API. (line 6) * Maintenance Concern <4>: Predicate System. (line 6) * Maintenance Concern <5>: Program. (line 6) * Maintenance Concern <6>: Program UI. (line 6) * Maintenance Concern <7>: Server. (line 6) * Maintenance Concern <8>: Server-Side Data API Calls. (line 6) * MDN: Developer Resources. (line 6) * Missing Docs: Assertions. (line 8) * Missing Docs <1>: Bucket. (line 6) * Missing Docs <2>: Bucket Assignment. (line 6) * Missing Docs <3>: Calculated Values. (line 6) * Missing Docs <4>: Client. (line 8) * Missing Docs <5>: Saving to Server. (line 6) * Missing Docs <6>: Data API. (line 8) * Missing Docs <7>: Field Styling. (line 6) * Missing Docs <8>: Program XML. (line 6) * Missing Docs <9>: Server. (line 8) * Missing Docs <10>: Server Configuration. (line 6) * Missing Docs <11>: Requests. (line 6) * Missing Docs <12>: Encryption Service. (line 6) * Missing Docs <13>: Validation. (line 6) * Missing Docs <14>: Formatting Values. (line 6) * Missing Docs <15>: Hacking. (line 6) * Missing Docs <16>: Source Files. (line 6) * Missing Docs <17>: TypeScript Migration. (line 6) * Mocha: Hacking. (line 11) * Mocha <1>: Libraries. (line 45) * MongoDB: Developer Resources. (line 42) * Node.js: Developer Resources. (line 26) * Refactor: Group Styles. (line 6) * Resources, Developer: Developer Resources. (line 6) * Source File Naming: Hacking. (line 18) * Source Files: Hacking. (line 18) * Source Files <1>: Source Files. (line 8) * Strict Mode, ECMAScript: Strict Mode. (line 6) * Texinfo, GNU: Developer Resources. (line 33) * TypeScript: Libraries. (line 37) * TypeScript <1>: Developer Resources. (line 15) * TypeScript <2>: TypeScript Migration. (line 6) * Typing, Duck: TypeScript Migration. (line 46) * Typing, Nominal: TypeScript Migration. (line 66) * Typing, Structural: TypeScript Migration. (line 46)  Tag Table: Node: Top725 Ref: Top-Footnote-11763 Node: Design1856 Node: Assertions4538 Ref: Assertions-Footnote-14779 Node: Bucket5281 Node: Bucket Assignment5727 Node: Bucket Diff5915 Ref: f:diff-ex7023 Ref: Bucket Diff-Footnote-19159 Ref: Bucket Diff-Footnote-29583 Node: Calculated Values9718 Node: Metabucket9913 Ref: t:liza-meta10809 Ref: Metabucket-Footnote-111113 Node: Client11181 Ref: Client-Footnote-111498 Node: Error Handling11846 Ref: Error Handling-Footnote-112712 Ref: Error Handling-Footnote-212908 Node: Managing Error State13001 Node: Saving to Server13918 Ref: f:client-diff14516 Ref: Saving to Server-Footnote-115211 Node: Data API15313 Ref: f:dapi-ex18170 Ref: Data API-Footnote-119044 Ref: Data API-Footnote-219330 Ref: Data API-Footnote-319397 Node: Predicate System19595 Ref: t:predicate-dod20217 Ref: Predicate System-Footnote-121297 Ref: Predicate System-Footnote-221717 Node: Program21854 Ref: Program-Footnote-122628 Node: Program UI23032 Ref: Program UI-Footnote-124600 Node: Group Styles24947 Ref: t:group-styles25441 Ref: Group Styles-Footnote-127720 Node: DOM Abstraction28008 Ref: DOM Abstraction-Footnote-131287 Node: Field Styling31394 Node: Program XML32065 Node: Defining Groups32383 Ref: f:group32809 Ref: f:group-leader33680 Ref: f:group-link34644 Node: Specifying Predicates35635 Ref: f:pred-when36065 Ref: Specifying Predicates-Footnote-136980 Node: Document Metadata37093 Ref: f:meta-fields37947 Ref: f:mapis38429 Ref: Document Metadata-Footnote-138584 Node: Server38719 Ref: f:server-start40352 Ref: Server-Footnote-141063 Ref: Server-Footnote-241433 Node: Server Configuration41580 Ref: Server Configuration-Footnote-142346 Node: Requests42422 Ref: Requests-Footnote-145614 Ref: Requests-Footnote-245674 Node: Posting Data45772 Ref: Posting Data-Footnote-147912 Node: Server-Side Data API Calls48009 Ref: Server-Side Data API Calls-Footnote-149226 Ref: Server-Side Data API Calls-Footnote-249530 Node: Encryption Service49646 Node: Validation49840 Node: Formatting Values50031 Node: Hacking50191 Node: Source Files51612 Node: Copyright Header52082 Ref: f:cheader-js52955 Ref: f:cheader-texi53913 Node: Strict Mode54714 Ref: f:strict-mode55441 Node: Libraries55535 Node: Developer Resources58748 Ref: Developer Resources-Footnote-161153 Node: TypeScript Migration61352 Ref: f:nom-type64834 Ref: f:nom-assert66171 Node: License67045 Node: Concept Index92374 Node: Developer Notes Index100316  End Tag Table  Local Variables: coding: utf-8 End: