DISL 0.5 schema
The JSON Schema of DISL 0.5 (disl.schema.json) has 181 definitions. They are grouped here by the layers of Appendix A.2, each with its own description above its JSON. The file itself is published unchanged at /adp/disl/schema/0.2/disl.schema.json, the address of its $id, for validators and editors.
Common
A simple identifier: a letter or underscore followed by letters, digits or underscores. A specification uses it for type, attribute, parameter, port and function names, and for alias and map keys, so that every such name is also a valid CEL identifier. Identifiers are case-sensitive, and two in the same namespace may not differ only in case. See section 2.2.
{
"type": "string",
"pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
}A qualified identifier: one or more dot-separated segments, each a letter or underscore followed by letters, digits, underscores or hyphens. A specification uses it for language ids, theme tokens such as color.surface, names brought in through an import alias such as std.cylinder, and plugin names. Like every identifier it is case-sensitive. See section 2.2.
{
"type": "string",
"pattern": "^[A-Za-z_][A-Za-z0-9_-]*(\\.[A-Za-z_][A-Za-z0-9_-]*)*$"
}A reference to a node type or relation type by its identifier, optionally prefixed with an import alias as in bpmn.Task. A specification uses it wherever a type is named, for example in inheritance, viewpoints, forms, constraints and hooks. A type reference always includes all subtypes of the named type, and a reference to an undefined name is a specification error. See section 2.7.
{
"$ref": "#/$defs/QualifiedId"
}One type reference or a non-empty list of them, accepted where the schema allows several types in place of one. A specification uses it for a node or relation type's extends property and for the types a form, constraint, hook or operation applies to. As with a single reference, each named type includes all its subtypes. See section 2.7.
{
"anyOf": [
{
"$ref": "#/$defs/TypeRef"
},
{
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
},
"minItems": 1
}
]
}A semantic version string following SemVer 2.0.0: major, minor and patch numbers, optionally followed by a pre-release and a build part. A specification uses it for its language version, which DID definitions record and which drives migrations. A change that can invalidate or change the meaning of existing definitions is a major change; optional additions are minor; documentation, visual and toolbox-only changes are patch changes. See section 2.9.
{
"type": "string",
"pattern": "^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z.-]+)?(\\+[0-9A-Za-z.-]+)?$"
}Any human-facing string in a specification, such as a label, message, description or placeholder. It is either a plain string or an object mapping BCP 47 language tags to strings, which should include the language's default locale. Runtimes pick the best match for the user's locale and fall back to the default locale, then to the first entry. cel is not a language tag (DISL 0.2): an object with a cel property is CEL, accepted where a Message is. See section 2.3.
{
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"propertyNames": {
"pattern": "^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$",
"not": {
"const": "cel"
}
},
"additionalProperties": {
"type": "string"
},
"minProperties": 1
}
]
}The documentation that almost any object in a specification can carry in its doc property, so that a runtime can explain elements, fields, tools and rules to users. It is either a LocalizedText, which is shorthand for a summary, or an object with a one-sentence summary, a longer CommonMark description, a rationale, examples, seeAlso links, tags, an audience, since, deprecated, image and helpUrl. See section 2.4.
{
"anyOf": [
{
"$ref": "#/$defs/LocalizedText"
},
{
"type": "object",
"properties": {
"summary": {
"$ref": "#/$defs/LocalizedText"
},
"description": {
"$ref": "#/$defs/LocalizedText"
},
"rationale": {
"$ref": "#/$defs/LocalizedText"
},
"examples": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"$ref": "#/$defs/LocalizedText"
},
"description": {
"$ref": "#/$defs/LocalizedText"
},
"value": true
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"seeAlso": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"$ref": "#/$defs/LocalizedText"
},
"href": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"href"
],
"patternProperties": {
"^x-": true
}
}
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"audience": {
"type": "array",
"items": {
"enum": [
"user",
"author",
"developer"
]
}
},
"since": {
"type": "string"
},
"deprecated": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "object",
"properties": {
"since": {
"type": "string"
},
"message": {
"$ref": "#/$defs/LocalizedText"
},
"replacedBy": {
"type": "string"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
},
"image": {
"type": "string"
},
"helpUrl": {
"type": "string"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
}The source text of a CEL expression, as a non-empty string. It is the building block of every dynamic value in a specification: the cel property of expressions, computed values and functions. The expression is type-checked in the context where it appears and evaluated under a cost limit. See section 2.5.
{
"type": "string",
"minLength": 1
}A property that always contains CEL, used for rules, conditions and other positions where a literal would make no sense. It is written either as a bare string of CEL or as an object with a cel property plus an optional resultType and doc. When resultType is present, validators check that the expression's static type is assignable to it. See section 2.5.
{
"anyOf": [
{
"$ref": "#/$defs/CelSource"
},
{
"type": "object",
"properties": {
"cel": {
"$ref": "#/$defs/CelSource"
},
"resultType": {
"type": "string"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"cel"
],
"patternProperties": {
"^x-": true
}
}
]
}The object form of a computed value: an object with a cel property holding the CEL source, plus an optional resultType and doc. A specification uses it in bindable positions, where a bare string would be a literal, and wherever human-facing text must contain computed values, such as constraint messages and tooltips. See section 2.5.
{
"type": "object",
"properties": {
"cel": {
"$ref": "#/$defs/CelSource"
},
"resultType": {
"type": "string"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"cel"
],
"patternProperties": {
"^x-": true
}
}A binding of a value to an attribute of the current element, written as an object with an attribute property holding a dotted path into structs such as address.city. Where the property is user-editable, such as a label or a placement coordinate, the binding is two-way and edits write back to the attribute. An optional offset, such as P1D, adds a constant in domain units in placement. See section 2.5.
{
"type": "object",
"properties": {
"attribute": {
"type": "string"
},
"offset": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"attribute"
],
"patternProperties": {
"^x-": true
}
}A reference to a theme token, written as an object whose token property holds the token's qualified name, for example color.surface. It is one of the dynamic forms a bindable value accepts, and it is resolved for the current theme mode, so colors and other visual values can follow light and dark themes. See section 2.5.
{
"type": "object",
"properties": {
"token": {
"$ref": "#/$defs/QualifiedId"
}
},
"additionalProperties": false,
"required": [
"token"
],
"patternProperties": {
"^x-": true
}
}A reference to a parameter of the enclosing shape, marker or template, written as an object whose param property holds the parameter's simple name. It is one of the dynamic forms a bindable value accepts, letting a reusable definition take values supplied where it is used. See section 2.5.
{
"type": "object",
"properties": {
"param": {
"$ref": "#/$defs/SimpleId"
}
},
"additionalProperties": false,
"required": [
"param"
],
"patternProperties": {
"^x-": true
}
}The four non-literal forms a bindable value accepts: a CEL computation, an attribute binding, a theme token reference or a shape, marker or template parameter reference. It is combined with a literal type to make the bindable string, number and boolean definitions. Because literals may be strings, CEL in a bindable position must always use the object form with a cel property. See section 2.5.
{
"anyOf": [
{
"$ref": "#/$defs/CelValue"
},
{
"$ref": "#/$defs/AttrBinding"
},
{
"$ref": "#/$defs/TokenRef"
},
{
"$ref": "#/$defs/ParamRef"
}
]
}A bindable string: a literal string or one of the dynamic forms, namely a CEL computation, an attribute binding, a theme token or a parameter reference. A bare string here is always a literal, never CEL, so a computed string must be written in the object form with a cel property. See section 2.5.
{
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/Dynamic"
}
]
}A bindable number: a literal number or one of the dynamic forms, namely a CEL computation, an attribute binding, a theme token or a parameter reference. It lets numeric visual and layout properties follow the model, the theme or the parameters of the enclosing shape, marker or template. See section 2.5.
{
"anyOf": [
{
"type": "number"
},
{
"$ref": "#/$defs/Dynamic"
}
]
}A bindable boolean: a literal true or false, or one of the dynamic forms, namely a CEL computation, an attribute binding, a theme token or a parameter reference. A specification uses it for switches such as visible, collapsed, readOnly, selectable, deletable and connectable, so they can depend on the element's state. See section 2.5.
{
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/$defs/Dynamic"
}
]
}A geometry expression: a single coordinate or dimension in shape paths, handle positions and part bounds. It is a number in canvas units, a percentage string such as 50% of the relevant dimension, or any other string, which is CEL returning a double or an int. The short string form is used because geometry is so dense with expressions. See section 2.5.
{
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
}A canvas length, used for sizes such as the width of a form item. It is either a number in canvas units, the unit of the coordinate system's numeric axis and px by default, or a string with an explicit unit: px, pt, mm, cm, in, em or %. Percentages refer to the containing box's corresponding dimension, and em to the current font size. See section 2.6.
{
"anyOf": [
{
"type": "number"
},
{
"type": "string",
"pattern": "^-?\\d+(\\.\\d+)?(px|pt|mm|cm|in|em|%)$"
}
]
}A color, written as a CSS Color Level 4 string. Accepted forms include hex such as #1D9E75 or #1D9E75CC, rgb, hsl and oklch functions, named colors, transparent, and currentColor, which is the resolved text color of the element. See section 2.6.
{
"type": "string"
}A width and height pair, written as a two-item array of numbers. A specification uses it for default, minimum, maximum and fixed node sizes, shape and icon sizes, port sizes and page sizes. Either item may be null where a dimension is left open, for example unbounded in one dimension when used as a size limit. See section 2.6.
{
"type": "array",
"items": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
]
},
"minItems": 2,
"maxItems": 2
}Spacing on the four sides of a box, used for padding and page margins. It is a single number for all sides, a two-item array of vertical and horizontal, or a four-item array of top, right, bottom and left. See section 2.6.
{
"anyOf": [
{
"type": "number"
},
{
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
},
{
"type": "array",
"items": {
"type": "number"
},
"minItems": 4,
"maxItems": 4
}
]
}A position given by an x and a y value. It is written as a two-item array for numeric axes, or as an object with x and y properties when axis values are timestamps or categories. DID's schema reuses this definition for positions in stored diagrams. See section 2.6.
{
"anyOf": [
{
"type": "array",
"items": true,
"minItems": 2,
"maxItems": 2
},
{
"type": "object",
"properties": {
"x": true,
"y": true
},
"additionalProperties": false,
"required": [
"x",
"y"
],
"patternProperties": {
"^x-": true
}
}
]
}A rectangular area given by x, y, w and h, each a geometry expression: a number, a percentage of the relevant dimension or a CEL string. A specification uses it for a custom shape's text area, the bounds of shape parts, a container's content area and drop zones, an embedded form's region and the canvas bounds. See section 6.8.
{
"type": "object",
"properties": {
"x": {
"$ref": "#/$defs/GeomExpr"
},
"y": {
"$ref": "#/$defs/GeomExpr"
},
"w": {
"$ref": "#/$defs/GeomExpr"
},
"h": {
"$ref": "#/$defs/GeomExpr"
}
},
"additionalProperties": false,
"required": [
"x",
"y",
"w",
"h"
],
"patternProperties": {
"^x-": true
}
}A pair of integer bounds, min and max, either of which may be null for unbounded, with an optional doc. A specification uses it for counts: the number of instances of a node type allowed per diagram, per-type child counts in containment, and the number of connections a port accepts. A node type's multiplicity is enforced as a built-in constraint. See section 4.6.
{
"type": "object",
"properties": {
"min": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"max": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A use of a declared plugin, written as an object whose plugin property names the plugin and whose optional args carry its arguments. A specification uses it where a built-in choice can be replaced by a plugin, for example an edge's routing. The named plugin must be declared in the specification's plugins, and the arguments are validated against that declaration. See section 13.1.
{
"type": "object",
"properties": {
"plugin": {
"$ref": "#/$defs/QualifiedId"
},
"args": {
"type": "object"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"plugin"
],
"patternProperties": {
"^x-": true
}
}A delegation to a declared plugin, written as an object whose name property names the plugin and whose optional args carry its arguments. A specification uses it in the plugin property of custom shapes, tools, context tools, form items, operations and migration steps. As with every plugin use, the plugin must be declared and the arguments are validated against its declaration. See section 13.1.
{
"type": "object",
"properties": {
"name": {
"$ref": "#/$defs/QualifiedId"
},
"args": {
"type": "object"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"name"
],
"patternProperties": {
"^x-": true
}
}A modifier key: Alt, Shift, Ctrl, Meta, or none for no key. A specification uses it for snapping's bypassModifier, the key that temporarily disables snapping while held, which defaults to Alt. See section 5.9.
{
"enum": [
"Alt",
"Shift",
"Ctrl",
"Meta",
"none"
]
}Top level
The root of a DISL document: one specification of a diagram type, written by a tool engineer. It carries the targeted DISL version and the language's identity, the eight layers from metamodel to persistence, and imports, functions, viewpoints, plugins and doc. Only the version key, language and metamodel are required; every other layer has a documented default. The deprecated dedl key is read in place of disl but never written. See section 3.1.
{
"type": "object",
"properties": {
"$schema": {
"type": "string"
},
"disl": {
"type": "string",
"pattern": "^\\d+\\.\\d+$",
"description": "The DISL version the specification targets, as major.minor: 0.1, 0.2, 0.3, 0.4 or 0.5. A 0.5 runtime reads 0.1, 0.2, 0.3 and 0.4 specifications with their meaning. See DISL 0.5, section 2.9."
},
"dedl": {
"type": "string",
"pattern": "^\\d+\\.\\d+$",
"deprecated": true,
"description": "Deprecated alias of \"disl\": read, never written (DISL specification, deprecated aliases)."
},
"language": {
"$ref": "#/$defs/Language"
},
"imports": {
"type": "array",
"items": {
"$ref": "#/$defs/Import"
}
},
"functions": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Function"
}
},
"metamodel": {
"$ref": "#/$defs/Metamodel"
},
"coordinates": {
"$ref": "#/$defs/Coordinates"
},
"notation": {
"$ref": "#/$defs/Notation"
},
"toolbox": {
"$ref": "#/$defs/Toolbox"
},
"forms": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Form"
}
},
"constraints": {
"$ref": "#/$defs/Constraints"
},
"behavior": {
"$ref": "#/$defs/Behavior"
},
"layout": {
"$ref": "#/$defs/Layout"
},
"persistence": {
"$ref": "#/$defs/Persistence"
},
"viewpoints": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Viewpoint"
}
},
"plugins": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/QualifiedId"
},
"additionalProperties": {
"$ref": "#/$defs/Plugin"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"language",
"metamodel"
],
"oneOf": [
{
"required": [
"disl"
]
},
{
"required": [
"dedl"
]
}
],
"patternProperties": {
"^x-": true
}
}The identity of the diagram type a specification defines, in its language property. Its required id is a globally unique qualified identifier, reverse-DNS style recommended, recorded in every DID definition, and its required version is a SemVer that drives migrations. It also holds the label, default locale (en by default) and locales, authors, license, homepage, icon, file extension, limits such as the CEL cost limit, required conformance and features, and profiles. See section 3.2.
{
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/QualifiedId"
},
"version": {
"$ref": "#/$defs/SemVer"
},
"origin": {
"type": "string",
"pattern": "^[a-z0-9-]+/[a-z0-9-]+$",
"description": "The specification's origin as <vendor>/<type>, such as w3c/rdf, which FBL's registration refers to; replaces x-adp-origin. See DISL 0.2, section 3.2."
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"defaultLocale": {
"type": "string"
},
"locales": {
"type": "array",
"items": {
"type": "string"
}
},
"authors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string"
},
"url": {
"type": "string"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"license": {
"type": "string"
},
"homepage": {
"type": "string"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"fileExtension": {
"type": "string"
},
"limits": {
"type": "object",
"properties": {
"celCost": {
"type": "integer"
},
"maxElements": {
"type": "integer"
},
"maxDocumentBytes": {
"type": "integer"
},
"budgets": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Budget"
},
"description": "Hard budgets by id, each cutting what is drawn and withholding edits while exceeded; independent of the soft maxElements. See DISL 0.2, section 3.2.1."
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"requires": {
"type": "object",
"properties": {
"conformance": {
"enum": [
"core",
"standard",
"full"
]
},
"features": {
"type": "array",
"items": {
"type": "string"
}
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"profiles": {
"type": "array",
"items": {
"type": "string"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"id",
"version"
],
"patternProperties": {
"^x-": true
}
}A reuse of another specification or library in a specification's imports list. Its from property locates the imported specification and its as property gives the alias under which imported names are referenced, as alias.Name. Optional properties set an acceptable version range, an integrity hash that runtimes verify when present, and which layers to include, all of them by default. Import cycles are a specification error. See section 3.3.
{
"type": "object",
"properties": {
"from": {
"type": "string"
},
"as": {
"$ref": "#/$defs/SimpleId"
},
"version": {
"type": "string"
},
"integrity": {
"type": "string"
},
"include": {
"type": "array",
"items": {
"enum": [
"metamodel",
"notation",
"forms",
"functions",
"constraints",
"toolbox"
]
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"from",
"as"
],
"patternProperties": {
"^x-": true
}
}A reusable, documented CEL function declared in a specification's functions map and called by its name, for example displayName(self). It has positional params, each with a name and a CEL or metamodel type, a returns type, and a cel body. The body sees only its parameters, plus diagram and env when listed in uses. A function may call functions declared before it, but recursion is a specification error unless the function declares recursion (DISL 0.2), which bounds its self-recursion. See section 3.4.
{
"type": "object",
"properties": {
"params": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"$ref": "#/$defs/SimpleId"
},
"type": {
"type": "string"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"name",
"type"
],
"patternProperties": {
"^x-": true
}
}
},
"returns": {
"type": "string"
},
"cel": {
"$ref": "#/$defs/CelSource"
},
"uses": {
"type": "array",
"items": {
"enum": [
"diagram",
"env"
]
}
},
"recursion": {
"description": "Lets the function call itself, bounded by maxDepth; indirect recursion stays a specification error. See DISL 0.2, section 3.4.",
"type": "object",
"properties": {
"maxDepth": {
"type": "integer",
"minimum": 1,
"description": "The deepest nesting of calls of this function within one top-level call. See DISL 0.2, section 3.4."
},
"atMaxDepth": {
"description": "Returned, over the same parameters, by a call nested deeper than maxDepth instead of evaluating the body. See DISL 0.2, section 3.4.",
"$ref": "#/$defs/CelSource"
}
},
"additionalProperties": false,
"required": [
"maxDepth",
"atMaxDepth"
],
"patternProperties": {
"^x-": true
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"params",
"returns",
"cel"
],
"patternProperties": {
"^x-": true
}
}One diagram kind over a language's model, declared in a specification's viewpoints map, for example a structure diagram and a timeline of the same project. It selects which types appear through include and exclude, the coordinate system, layout, toolbox groups and canvas, and can override notation for nodes, edges and styles. One viewpoint should be marked default for new diagrams; without any, a single implicit viewpoint named main shows everything. See section 3.5.
{
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/LocalizedText"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"coordinateSystem": {
"$ref": "#/$defs/SimpleId"
},
"include": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
}
},
"exclude": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
}
},
"members": {
"description": "Whether an element whose type passes include and exclude is drawn in views of this viewpoint, a bool in the element context (wildcards through matchesGlob); defaults to true. A relation is drawn only when both ends are. See DISL 0.2, section 3.5.",
"$ref": "#/$defs/Expression"
},
"toolbox": {
"type": "array",
"items": {
"type": "string"
}
},
"layout": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/LayoutConfig"
}
]
},
"notation": {
"type": "object",
"properties": {
"nodes": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/QualifiedId"
},
"additionalProperties": {
"$ref": "#/$defs/NodeNotation"
}
},
"edges": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/QualifiedId"
},
"additionalProperties": {
"$ref": "#/$defs/EdgeNotation"
}
},
"styles": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Style"
}
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"canvas": {
"$ref": "#/$defs/Canvas"
},
"variantOf": {
"description": "Makes this viewpoint an alternative presentation of the named one, offered as a toggle on its views rather than as a view kind; switching is viewer state, and a DID view never names a variant. See DISL 0.2, section 3.5.",
"$ref": "#/$defs/SimpleId"
},
"toggle": {
"description": "The switch that turns this variant on and off. See DISL 0.2, section 3.5.",
"type": "object",
"properties": {
"label": {
"description": "The switch's label; defaults to this viewpoint's label. See DISL 0.2, section 3.5.",
"$ref": "#/$defs/Message"
},
"icon": {
"$ref": "#/$defs/IconRef",
"description": "The switch's icon. See DISL 0.2, section 3.5."
},
"position": {
"description": "Where the switch sits, outside the drawing surface. See DISL 0.2, section 3.5.",
"$ref": "#/$defs/Position"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"default": {
"type": "boolean"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}The declaration of an extension a specification relies on, in its plugins map, for what the declarative core cannot express. It states the accepted versions, the extension points it provides, whether it is required, fallbacks for when it is absent, typed arguments that every use is validated against, where to obtain it, and any CEL functions it adds. A runtime without a required plugin refuses to open such diagrams for editing. In DISL 0.2 its CEL functions are called by bare name, may name their parameters, and declare uses, deterministic and a fallback for when the plugin is absent. See section 13.1.
{
"type": "object",
"properties": {
"version": {
"type": "string"
},
"provides": {
"type": "array",
"items": {
"enum": [
"shape",
"marker",
"lineEffect",
"routing",
"layout",
"snap",
"widget",
"action",
"celFunctions",
"import",
"export",
"persistenceFormat",
"collaboration"
]
}
},
"required": {
"type": "boolean"
},
"fallback": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"args": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Attribute"
}
},
"source": {
"type": "object"
},
"celFunctions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"$ref": "#/$defs/SimpleId"
},
"params": {
"description": "The parameter types in order: a CEL type string (0.1), or {name, type, doc}, which names the parameter for fallback. See DISL 0.2, section 13.1.",
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"properties": {
"name": {
"$ref": "#/$defs/SimpleId",
"description": "The parameter's name, bound in fallback. See DISL 0.2, section 13.1."
},
"type": {
"type": "string",
"description": "The parameter's CEL type. See DISL 0.2, section 13.1."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"name",
"type"
],
"patternProperties": {
"^x-": true
}
}
]
}
},
"returns": {
"type": "string"
},
"cost": {
"type": "integer"
},
"uses": {
"type": "array",
"items": {
"enum": [
"diagram",
"env"
]
},
"description": "What the implementation may read besides its arguments, as for user functions: a read-only view of the working state (diagram) and env. See DISL 0.2, section 13.1."
},
"deterministic": {
"type": "boolean",
"description": "Whether the result depends only on the arguments and what uses names; false forbids calls in the deterministic contexts of 12.5. Defaults to true. See DISL 0.2, section 13.1."
},
"fallback": {
"description": "Evaluated over the named parameters in place of the call when the plugin is absent; without it the call is an evaluation error and std.pluginMissing is reported once per plugin. See DISL 0.2, section 13.1.",
"$ref": "#/$defs/CelSource"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"name",
"returns"
],
"patternProperties": {
"^x-": true
}
}
},
"plans": {
"description": "For a persistenceFormat plugin: the model changes its plan operation accepts (FBL 0.2, section 11.2); a change it does not declare is sent as the changes it does. Default add, set and remove. See DISL 0.3, section 13.1.",
"type": "array",
"items": {
"enum": [
"add",
"set",
"remove",
"move",
"retype"
]
},
"uniqueItems": true
},
"add": {
"description": "For a persistenceFormat plugin: how it plans a add. position true means it honours a position, inserting there or refusing (FBL 0.2, section 11.2). See DISL 0.3, section 13.1.",
"type": "object",
"properties": {
"position": {
"type": "boolean"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"move": {
"description": "For a persistenceFormat plugin: how it plans a move. position true means it honours a position, inserting there or refusing (FBL 0.2, section 11.2). See DISL 0.3, section 13.1.",
"type": "object",
"properties": {
"position": {
"type": "boolean"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}1 · Metamodel
The metamodel is Layer 1 of a specification: the abstract syntax of a diagram type, saying which kinds of elements exist, their attributes, how they nest, connect and which ports they expose, and nothing about appearance. It holds the attributes of the diagram root, named data types, enumerations, node types (everything drawn as a node) and relation types (everything drawn as an edge), each keyed by a simple identifier. See section 4.1.
{
"type": "object",
"properties": {
"diagram": {
"type": "object",
"properties": {
"attributes": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Attribute"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"dataTypes": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/DataType"
}
},
"enums": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Enum"
}
},
"types": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/NodeType"
}
},
"relations": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/RelationType"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}An attribute describes one named value on a node, relation, port, struct field or the diagram itself. Its required type names a primitive, enumeration, data type, or node or relation type, which makes it a reference. Other properties give a default and make it required, a list (many), read-only, derived, transient, unique within a scope, part of the natural key or secret, and add primitive facets such as min or pattern. DISL 0.2 adds read-only reasons, absent and empty texts, outOfRange, fixed, samePrecisionAs, written precision and transient viewer. See section 4.3.
{
"type": "object",
"properties": {
"type": {
"$ref": "#/$defs/QualifiedId"
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"required": {
"type": "boolean"
},
"default": true,
"many": {
"type": "boolean"
},
"minItems": {
"type": "integer"
},
"maxItems": {
"type": "integer"
},
"uniqueItems": {
"type": "boolean"
},
"readOnly": {
"type": "boolean"
},
"fixed": {
"description": "A constant the attribute always has: read-only, never persisted, and allowed as narrowing in a subtype; exclusive with derived and default. See DISL 0.2, section 4.3."
},
"derived": {
"$ref": "#/$defs/Expression"
},
"transient": {
"description": "true: editable and not persisted (0.1). viewer: held per viewer, starting at default whenever a viewer opens the view, never persisted or on undo, settable in read-only mode, and not readable from deterministic contexts. See DISL 0.2, section 4.3.",
"anyOf": [
{
"type": "boolean"
},
{
"const": "viewer"
}
]
},
"unique": {
"enum": [
"diagram",
"parent",
"type"
]
},
"key": {
"type": "boolean"
},
"secret": {
"type": "boolean"
},
"facets": {
"type": "object"
},
"group": {
"type": "string"
},
"order": {
"type": "integer"
},
"min": {
"description": "The lower bound; in DISL 0.2 it may also be {cel}, evaluated in the element context. See DISL 0.2, section 4.3."
},
"max": {
"description": "The upper bound; in DISL 0.2 it may also be {cel}, evaluated in the element context. See DISL 0.2, section 4.3."
},
"exclusiveMin": {
"type": "number"
},
"exclusiveMax": {
"type": "number"
},
"step": true,
"precision": {
"type": "integer"
},
"unit": {
"type": "string"
},
"minLength": {
"type": "integer"
},
"maxLength": {
"type": "integer"
},
"pattern": {
"type": "string"
},
"format": {
"type": "string"
},
"markup": {
"enum": [
"plain",
"markdown"
]
},
"timezone": {
"type": "string"
},
"writtenPrecision": {
"enum": [
"preserve",
"date",
"minute",
"second",
"millisecond"
],
"description": "For datetime: the precision values are written in; preserve keeps, per stored value, the precision it was read with (date-only or the finest written field). Absent, values are written as in 0.1. See DISL 0.2, section 4.2."
},
"newPrecision": {
"enum": [
"date",
"minute",
"second",
"millisecond"
],
"description": "For datetime: the precision of values the tool creates; defaults to second. See DISL 0.2, section 4.2."
},
"calendar": {
"type": "boolean"
},
"palette": {
"type": "array",
"items": {
"type": "string"
}
},
"alpha": {
"type": "boolean"
},
"schemes": {
"type": "array",
"items": {
"type": "string"
}
},
"paths": {
"type": "boolean",
"description": "uri: a value may also be a path, absolute or relative to the folder of the file it is stored in; schemes then restricts URIs only. Defaults to false. See DISL 0.4, section 4.2."
},
"context": {
"type": "string"
},
"resultType": {
"type": "string"
},
"schema": {
"type": "object"
},
"mediaTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"maxBytes": {
"type": "integer"
},
"samePrecisionAs": {
"description": "The attribute of the same element whose values must be written with the same precision as this one's; a mismatch is reported by std.mixedPrecision. See DISL 0.2, section 4.3.",
"$ref": "#/$defs/SimpleId"
},
"readOnlyReasons": {
"description": "Why the attribute is read-only, in priority order; the first that applies is shown with the field and given as the refusal of any write. Element context. See DISL 0.2, section 4.3.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"absentText": {
"description": "Shown for the attribute when the element has no stored value and no default. See DISL 0.2, section 4.3.",
"$ref": "#/$defs/Message"
},
"emptyText": {
"description": "Shown for the attribute when its stored value is empty (\"\", [] or {}). See DISL 0.2, section 4.3.",
"$ref": "#/$defs/Message"
},
"outOfRange": {
"description": "Whether a value past min or max is clamped or refused, per kind of edit. See DISL 0.2, section 4.3.",
"$ref": "#/$defs/OutOfRange"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"type"
],
"patternProperties": {
"^x-": true
}
}A data type is a named value type declared in the metamodel, either a constrained primitive or a struct. A constrained primitive names its base primitive and adds that primitive's facets, such as a range, pattern or unit; a struct lists its fields as attributes, which may themselves be structs, lists or references. Its display property says how a value is summarised in labels and list cells. See section 4.4.
{
"type": "object",
"properties": {
"base": {
"enum": [
"string",
"text",
"int",
"number",
"bool",
"date",
"datetime",
"time",
"duration",
"color",
"uri",
"expression",
"json",
"binary"
]
},
"fields": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Attribute"
}
},
"display": {
"$ref": "#/$defs/BString"
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"min": true,
"max": true,
"exclusiveMin": {
"type": "number"
},
"exclusiveMax": {
"type": "number"
},
"step": true,
"precision": {
"type": "integer"
},
"unit": {
"type": "string"
},
"minLength": {
"type": "integer"
},
"maxLength": {
"type": "integer"
},
"pattern": {
"type": "string"
},
"format": {
"type": "string"
},
"markup": {
"enum": [
"plain",
"markdown"
]
},
"timezone": {
"type": "string"
},
"calendar": {
"type": "boolean"
},
"palette": {
"type": "array",
"items": {
"type": "string"
}
},
"alpha": {
"type": "boolean"
},
"schemes": {
"type": "array",
"items": {
"type": "string"
}
},
"context": {
"type": "string"
},
"resultType": {
"type": "string"
},
"schema": {
"type": "object"
},
"mediaTypes": {
"type": "array",
"items": {
"type": "string"
}
},
"maxBytes": {
"type": "integer"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}An enumeration is a named, closed set of values declared in the metamodel and usable as an attribute type. Its values map is required; the value ids are simple identifiers, they are what is stored, and the map order is the display order. Setting ordered makes the values comparable, and extensible lets users enter values that are not listed. See section 4.5.
{
"type": "object",
"properties": {
"values": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/EnumValue"
}
},
"ordered": {
"type": "boolean"
},
"extensible": {
"type": "boolean"
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"values"
],
"patternProperties": {
"^x-": true
}
}An enum value is one entry of an enumeration, keyed by the simple identifier that is stored. It may carry a display label, documentation, a color and an icon, which are hints a notation may use, and a deprecated flag or object. See section 4.5.
{
"type": "object",
"properties": {
"value": {
"type": "string",
"minLength": 1,
"description": "The member's stored form in a DID definition and the default spelling a format binding maps it to, such as run-job; CEL keeps using the key. Unique within the enumeration; defaults to the key. See DISL 0.2, section 4.5."
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"color": {
"description": "A colour hint for notations and legends: a Color, or a TokenRef resolved in the current theme mode. See DISL 0.3, sections 4.5 and 6.13.",
"anyOf": [
{
"$ref": "#/$defs/Color"
},
{
"$ref": "#/$defs/TokenRef"
}
]
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"deprecated": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "object"
}
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A node type describes a kind of element drawn as a node, including containers, lanes and annotations; the metamodel's types map declares them. It carries its own attributes, ports and containment rules (children), may be abstract and may extend other node types, inheriting their attributes, ports, containment and tags. Multiplicity limits the instances per diagram, viewOnly marks elements with no model meaning, and labelAttribute names the attribute used as the element's name. See section 4.6.
{
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/LocalizedText"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"abstract": {
"type": "boolean"
},
"extends": {
"$ref": "#/$defs/TypeRefs"
},
"attributes": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Attribute"
}
},
"bounds": {
"description": "Bounds of a node or relation type that involve several of its attributes at once. See DISL 0.3, section 4.3.",
"type": "object",
"properties": {
"neighbour": {
"$ref": "#/$defs/NeighbourBounds"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"ports": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/PortType"
}
},
"children": {
"$ref": "#/$defs/Containment"
},
"multiplicity": {
"$ref": "#/$defs/MinMax"
},
"derived": {
"description": "Makes the type's elements derived: computed from the model, never stored, instantiated by a user or put on undo. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/DerivedNode"
},
"viewOnly": {
"type": "boolean"
},
"labelAttribute": {
"$ref": "#/$defs/SimpleId"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}Containment is the children property of a node type and says which nodes may be nested inside it; a contained node has exactly one parent and is deleted with it unless behavior says otherwise. It lists the allowed child types, count bounds overall and per type (null meaning unbounded), whether child order is meaningful, and named slots for nodes with several distinct regions. A node type without children cannot contain other nodes. See section 4.8.
{
"type": "object",
"properties": {
"allowed": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
}
},
"min": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"max": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"perType": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/MinMax"
}
},
"ordered": {
"type": "boolean"
},
"acrossViews": {
"type": "boolean"
},
"slots": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"type": "object",
"properties": {
"allowed": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
}
},
"min": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"max": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A port type declares a named connection point on a node type, such as a pin or an input or output handle. Direction restricts edge direction (in, out or inout, the default), multiplicity sets how many instances each node has (one fixed port by default), dynamic lets users add and remove instances, and accepts lists the relation types that may attach. Each port instance can carry its own attributes and is persisted with its owner. See section 4.10.
{
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/LocalizedText"
},
"direction": {
"enum": [
"in",
"out",
"inout"
]
},
"multiplicity": {
"$ref": "#/$defs/MinMax"
},
"dynamic": {
"type": "boolean"
},
"maxConnections": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"accepts": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
}
},
"attributes": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Attribute"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A relation type describes a kind of connection drawn as an edge, declared in the metamodel's relations map. Its source and target say which elements may be connected; directed defaults to true, self-loops are disallowed and parallel relations allowed by default, and acyclic forbids cycles. Like node types it may be abstract, extend other relation types and carry attributes; it may also connect relations, be derived by an expression or be view-only. See section 4.9.
{
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/LocalizedText"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"abstract": {
"type": "boolean"
},
"extends": {
"$ref": "#/$defs/TypeRefs"
},
"source": {
"$ref": "#/$defs/RelationEnd"
},
"target": {
"$ref": "#/$defs/RelationEnd"
},
"directed": {
"type": "boolean"
},
"allowSelfLoops": {
"type": "boolean"
},
"allowParallel": {
"type": "boolean"
},
"acyclic": {
"type": "boolean"
},
"attributes": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Attribute"
}
},
"bounds": {
"description": "Bounds of a node or relation type that involve several of its attributes at once. See DISL 0.3, section 4.3.",
"type": "object",
"properties": {
"neighbour": {
"$ref": "#/$defs/NeighbourBounds"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"connectsRelations": {
"type": "boolean"
},
"derived": {
"description": "Makes the type's relations derived: the 0.1 Expression returning a list of maps with source and target (and optionally id, sources, owner and attribute values), or a DerivedRelation. See DISL 0.2, section 4.9.",
"anyOf": [
{
"$ref": "#/$defs/Expression"
},
{
"$ref": "#/$defs/DerivedRelation"
}
]
},
"viewOnly": {
"type": "boolean"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A relation end states what may sit at the source or target of a relation type. It is a single type reference, a non-empty list of them, or an object adding excluded subtypes, the port types the end must attach to, bounds on how many relations of this type an element may have at this end, and a role name for CEL and labels. Attribute-dependent connectivity is written as a connect constraint instead. See section 4.9.
{
"anyOf": [
{
"$ref": "#/$defs/TypeRef"
},
{
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
},
"minItems": 1
},
{
"type": "object",
"properties": {
"types": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
}
},
"exclude": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
}
},
"ports": {
"type": "array",
"items": {
"type": "string"
}
},
"min": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"max": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
]
},
"role": {
"type": "string"
},
"optional": {
"type": "boolean",
"description": "On the target end only: a relation of this type may have no target, drawn as its edge notation's stub; self.target is then null and std.endpoints does not report it. Defaults to false. See DISL 0.2, section 4.9."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
}2 · Coordinates
The coordinates object is Layer 2 of a specification: it declares named axes, named coordinate systems and reusable snap profiles, and names the default system used by viewpoints that do not name one. Axes may also be written inline inside systems. When it is absent, the diagram type gets a single cartesian system named canvas with two linear pixel axes, y pointing down, unbounded, grid hidden and snapping off. See section 5.2.
{
"type": "object",
"properties": {
"axes": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Axis"
}
},
"systems": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/CoordinateSystem"
}
},
"snapProfiles": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Snapping"
}
},
"default": {
"$ref": "#/$defs/SimpleId"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}An axis maps domain values such as numbers, timestamps or categories to canvas distance along one direction. Its required kind is linear or log for numbers, time for dates and timestamps, ordinal for discrete bands such as lanes, or angular for polar systems. Common properties set a label, domain bounds, origin, reversal, automatic expansion and a ruler; each kind adds its own, such as unit and scale, time zone and calendar, or the band categories. See section 5.3.
{
"type": "object",
"properties": {
"kind": {
"enum": [
"linear",
"log",
"time",
"ordinal",
"angular"
]
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"min": true,
"max": true,
"reversed": {
"type": "boolean"
},
"origin": true,
"outOfRange": {
"description": "Whether a value past the axis bounds is clamped or refused, per kind of edit. See DISL 0.2, section 5.3.",
"$ref": "#/$defs/OutOfRange"
},
"ranges": {
"type": "array",
"items": {
"$ref": "#/$defs/AxisRange"
},
"description": "Named ranges drawn as bands. See DISL 0.2, section 5.3."
},
"endLabels": {
"description": "Labels at the ends of the axis, by domain end. See DISL 0.2, section 5.3.",
"type": "object",
"properties": {
"min": {
"$ref": "#/$defs/Message",
"description": "The label at the minimum end. See DISL 0.2, section 5.3."
},
"max": {
"$ref": "#/$defs/Message",
"description": "The label at the maximum end. See DISL 0.2, section 5.3."
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"ruler": {
"$ref": "#/$defs/Ruler"
},
"expand": {
"enum": [
"none",
"auto"
]
},
"unit": {
"type": "string"
},
"scale": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"unit": {
"description": "The unit: a time unit, or {attribute} bound to a diagram attribute whose enum values are unit names, so that changing it rescales the axis. See DISL 0.2, section 5.5.",
"anyOf": [
{
"$ref": "#/$defs/TimeUnit"
},
{
"$ref": "#/$defs/AttrBinding"
}
]
},
"size": {
"type": "number"
}
},
"additionalProperties": false,
"required": [
"unit",
"size"
],
"patternProperties": {
"^x-": true
}
}
]
},
"precision": {
"type": "integer"
},
"base": {
"type": "number"
},
"format": {
"type": "string"
},
"valueType": {
"enum": [
"date",
"datetime",
"epoch-ms",
"epoch-s",
"yearMonth"
],
"description": "How time values are stored: date, datetime, epoch-ms, epoch-s, or yearMonth (DISL 0.2), whose domain is the month index of signed astronomical ±YYYY-MM values; timezone, calendar and collapse do not apply to it and units finer than month are rejected. See DISL 0.2, section 5.5."
},
"timezone": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/Dynamic"
}
]
},
"calendar": {
"$ref": "#/$defs/Calendar"
},
"collapse": {
"enum": [
"none",
"non-working"
]
},
"zoomLevels": {
"type": "array",
"items": {
"$ref": "#/$defs/ZoomLevel"
}
},
"today": {
"type": "object",
"properties": {
"visible": {
"type": "boolean"
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"label": {
"$ref": "#/$defs/LocalizedText"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"categories": {
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/Category"
}
},
{
"$ref": "#/$defs/CelValue"
},
{
"type": "object",
"properties": {
"nodes": {
"$ref": "#/$defs/TypeRef"
},
"orderBy": {
"$ref": "#/$defs/Expression"
},
"label": {
"$ref": "#/$defs/Expression"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"nodes"
],
"patternProperties": {
"^x-": true
}
}
]
},
"bandSize": {
"anyOf": [
{
"type": "number"
},
{
"const": "auto"
}
]
},
"minBandSize": {
"type": "number"
},
"maxBandSize": {
"type": "number"
},
"bandSizes": {
"$ref": "#/$defs/AttrBinding"
},
"padding": {
"type": "number"
},
"gap": {
"type": "number"
},
"reorderable": {
"type": "boolean"
},
"allowUnassigned": {
"type": "boolean"
},
"header": {
"type": "object",
"properties": {
"size": {
"type": "number"
},
"label": {
"$ref": "#/$defs/BString"
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"side": {
"enum": [
"left",
"right",
"top",
"bottom"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"start": {
"type": "number"
},
"direction": {
"enum": [
"clockwise",
"counterclockwise"
]
},
"wrap": {
"type": "boolean"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"kind"
],
"patternProperties": {
"^x-": true
}
}An axis reference is how a coordinate system names one of its axes, in its x, y, angle and radius properties. It is either the name of an axis declared in the coordinates object's axes map, or an axis written inline. See section 5.7.
{
"anyOf": [
{
"$ref": "#/$defs/SimpleId"
},
{
"$ref": "#/$defs/Axis"
}
]
}A calendar defines working time for a time axis, used for shading non-working time, collapsing it, and working-time snapping. Working days are ISO weekday numbers (Monday to Friday by default), working hours are start and end pairs per day (the whole day by default), and holidays are listed dates or bound to a diagram attribute; exceptions describe special days. Its id is the name CEL time functions use to refer to it. See section 5.5.
{
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"workingDays": {
"type": "array",
"items": {
"type": "integer",
"minimum": 1,
"maximum": 7
}
},
"workingHours": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 2,
"maxItems": 2
}
},
"holidays": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"$ref": "#/$defs/Dynamic"
}
]
},
"exceptions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"date": {
"type": "string"
},
"workingHours": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 2,
"maxItems": 2
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"date"
],
"patternProperties": {
"^x-": true
}
}
},
"firstDayOfWeek": {
"type": "integer",
"minimum": 1,
"maximum": 7
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A category is one band of an ordinal axis, such as a lane, a row or a Kanban column, when the bands are given as a static list. Its id is required and is what positions on the axis refer to; it may also carry a label, documentation, a color and a size. See section 5.6.
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"color": {
"type": "string"
},
"size": {
"type": "number"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"id"
],
"patternProperties": {
"^x-": true
}
}A ruler configures the ruler or header shown for an axis, set on the axis or on one of its zoom levels. It sets visibility, position (top, bottom, left or right) and size, and levels, a list of header rows for multi-level time scales, each with its unit, format and zoom range. Formats are Unicode LDML date or number patterns, and nonWorkingStyle styles the shading of non-working time. See section 5.13.
{
"type": "object",
"properties": {
"visible": {
"type": "boolean"
},
"position": {
"enum": [
"top",
"bottom",
"left",
"right"
]
},
"size": {
"type": "number"
},
"levels": {
"type": "array",
"items": {
"type": "object",
"properties": {
"unit": {
"$ref": "#/$defs/TimeUnit"
},
"format": {
"type": "string"
},
"minZoom": {
"type": "number"
},
"maxZoom": {
"type": "number"
},
"minSpacingPx": {
"type": "number",
"minimum": 0,
"description": "Show this level only while adjacent labels are at least this far apart on screen. See DISL 0.2, section 5.13."
},
"step": {
"type": "integer",
"minimum": 1,
"description": "Multiples of unit; defaults to 1. See DISL 0.2, section 5.13."
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"ticks": {
"description": "A single adaptive row, in place of levels. See DISL 0.2, section 5.13.",
"$ref": "#/$defs/RulerTicks"
},
"boundaryFormats": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/TimeUnit"
},
"additionalProperties": {
"type": "string"
},
"description": "A tick that falls exactly on the start of a listed unit uses that unit's format; the largest such unit wins. See DISL 0.2, section 5.13."
},
"attach": {
"enum": [
"view",
"canvas"
],
"description": "view (the default) keeps the ruler at its edge of the pane whatever is scrolled; canvas scrolls it with the drawing. See DISL 0.2, section 5.13."
},
"minUnit": {
"description": "No level or tick step shorter than this unit is shown: a TimeUnit, or an attribute binding to one, such as the diagram's unit. See DISL 0.3, section 5.13.",
"anyOf": [
{
"$ref": "#/$defs/TimeUnit"
},
{
"$ref": "#/$defs/AttrBinding"
}
]
},
"format": {
"type": "string"
},
"nonWorkingStyle": {
"$ref": "#/$defs/StyleRef"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"not": {
"required": [
"levels",
"ticks"
]
}
}A zoom level is a preset on a time axis, such as days, weeks or months, that changes the axis scale and its header together. It carries a label, a scale giving a time unit and the canvas distance one unit occupies at zoom 1, and the ruler to show at that level. See section 5.5.
{
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/LocalizedText"
},
"scale": {
"type": "object",
"properties": {
"unit": {
"$ref": "#/$defs/TimeUnit"
},
"size": {
"type": "number"
}
},
"additionalProperties": false,
"required": [
"unit",
"size"
],
"patternProperties": {
"^x-": true
}
},
"ruler": {
"$ref": "#/$defs/Ruler"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A coordinate system combines two axes into a placement frame: x and y for a cartesian system, angle and radius for a polar one, with kind required. It sets orientation (y-down by default), a polar center, bounds, and whether the canvas is infinite, which it is unless bounds are set. It also carries the grid display, default snapping and guides, and nested maps container node types to systems local to those containers, whose children are positioned relative to them. See section 5.7.
{
"type": "object",
"properties": {
"kind": {
"enum": [
"cartesian",
"polar"
]
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"x": {
"$ref": "#/$defs/AxisRef"
},
"y": {
"$ref": "#/$defs/AxisRef"
},
"angle": {
"$ref": "#/$defs/AxisRef"
},
"radius": {
"$ref": "#/$defs/AxisRef"
},
"center": {
"$ref": "#/$defs/Size"
},
"orientation": {
"enum": [
"y-down",
"y-up"
]
},
"bounds": {
"type": "object",
"properties": {
"x": {
"type": "array",
"items": true,
"minItems": 2,
"maxItems": 2
},
"y": {
"type": "array",
"items": true,
"minItems": 2,
"maxItems": 2
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"infinite": {
"type": "boolean"
},
"grid": {
"$ref": "#/$defs/GridDisplay"
},
"snapping": {
"$ref": "#/$defs/SnappingRef"
},
"guides": {
"$ref": "#/$defs/Guides"
},
"nested": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/SimpleId"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"kind"
],
"patternProperties": {
"^x-": true
}
}Grid display configures the visible grid of a coordinate system, which is separate from snapping but defaults to mirroring it. It sets visibility (hidden by default), style (lines by default, or dots, crosses or none), spacing, which on time axes may be a calendar unit, how often a line is major, minor and major colors, and the zoom below which minor lines hide. Ordinal bands can be striped and non-working time filled. See section 5.13.
{
"type": "object",
"properties": {
"visible": {
"type": "boolean"
},
"style": {
"enum": [
"lines",
"dots",
"crosses",
"none"
]
},
"spacing": {
"anyOf": [
{
"type": "number"
},
{
"type": "object",
"properties": {
"x": true,
"y": true
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
{
"type": "object",
"properties": {
"unit": {
"$ref": "#/$defs/TimeUnit"
},
"step": {
"type": "integer"
}
},
"additionalProperties": false,
"required": [
"unit"
],
"patternProperties": {
"^x-": true
}
}
]
},
"majorEvery": {
"anyOf": [
{
"type": "integer"
},
{
"type": "object",
"properties": {
"x": {
"type": "integer"
},
"y": {
"type": "integer"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
},
"minorColor": {
"$ref": "#/$defs/Paint"
},
"majorColor": {
"$ref": "#/$defs/Paint"
},
"minZoomForMinor": {
"type": "number"
},
"bands": {
"type": "object",
"properties": {
"alternate": {
"type": "boolean"
},
"fill": {
"type": "array",
"items": {
"$ref": "#/$defs/Paint"
}
},
"separator": {
"$ref": "#/$defs/Stroke"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"nonWorking": {
"$ref": "#/$defs/Style"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}Guides configure the alignment aids of a coordinate system while dragging. Smart guides to the edges and centers of nearby elements and equal-spacing distribution guides are on by default; user guides, dragged out of rulers and stored in view data, are off by default. A style may be given for the guide lines. See section 5.12.
{
"type": "object",
"properties": {
"smart": {
"type": "boolean"
},
"distribution": {
"type": "boolean"
},
"user": {
"type": "boolean"
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}Placement tells the runtime where each coordinate of a node comes from; it is declared in the node notation, so one model type can be placed differently per viewpoint. It names the coordinate system and gives a placement source for each axis's position and for its opposite edge or extent (x2 excludes width, y2 excludes height), plus the anchor. It also controls moving and resizing per axis, stacking within a band, and clamping to the parent. See section 5.8.
{
"type": "object",
"properties": {
"system": {
"$ref": "#/$defs/SimpleId"
},
"x": {
"$ref": "#/$defs/PlacementSource"
},
"y": {
"$ref": "#/$defs/PlacementSource"
},
"x2": {
"$ref": "#/$defs/PlacementSource"
},
"y2": {
"$ref": "#/$defs/PlacementSource"
},
"width": {
"$ref": "#/$defs/PlacementSource"
},
"height": {
"$ref": "#/$defs/PlacementSource"
},
"angle": {
"$ref": "#/$defs/PlacementSource"
},
"radius": {
"$ref": "#/$defs/PlacementSource"
},
"anchor": {
"$ref": "#/$defs/Anchor"
},
"movable": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "object",
"properties": {
"x": {
"type": "boolean"
},
"y": {
"type": "boolean"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
},
"resizable": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "object",
"properties": {
"x": {
"type": "boolean"
},
"y": {
"type": "boolean"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
},
"stack": {
"type": "object",
"properties": {
"mode": {
"enum": [
"overlap",
"stack",
"pack"
]
},
"order": {
"$ref": "#/$defs/Expression"
},
"rowSize": {
"type": "number"
},
"growBand": {
"type": "boolean"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"clampToParent": {
"type": "boolean"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"not": {
"anyOf": [
{
"required": [
"x2",
"width"
]
},
{
"required": [
"y2",
"height"
]
}
]
}
}A placement source says where one coordinate of a placement comes from. The string free, or omitting it, stores the value in view data; an attribute binding reads and writes a model attribute, optionally with a constant offset; a CEL expression computes a read-only value, and write actions let a move update the model from it; layout true leaves it to the layout algorithm. A bound attribute's type must suit the axis. See section 5.8.
{
"anyOf": [
{
"const": "free"
},
{
"$ref": "#/$defs/AttrBinding"
},
{
"type": "object",
"properties": {
"cel": {
"$ref": "#/$defs/CelSource"
},
"write": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"cel"
],
"patternProperties": {
"^x-": true
}
},
{
"type": "object",
"properties": {
"layout": {
"const": true
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"layout"
],
"patternProperties": {
"^x-": true
}
}
]
}An anchor says which point of a node a placement position refers to. It is one of the named points top-left (the default), top, top-right, left, center, right, bottom-left, bottom or bottom-right, or a pair of fractions of the node's width and height. Point-like elements on time axes, such as milestones, typically use center. See section 5.8.
{
"anyOf": [
{
"enum": [
"top-left",
"top",
"top-right",
"left",
"center",
"right",
"bottom-left",
"bottom",
"bottom-right"
]
},
{
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
}
]
}Snapping restricts positions and sizes to discrete values, defined per axis in the axis's own units; it is declared in a snap profile, on a coordinate system, a viewpoint canvas, a node or edge notation, or a placement, and the most specific declaration wins per property and per axis. It holds a snap rule per axis (or both), rules for sizes, rotation, bendpoints and labels, the mode (always or magnetic), which targets participate, the tolerance, and the bypass key. See section 5.9.
{
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"userToggle": {
"type": "boolean"
},
"mode": {
"enum": [
"always",
"magnetic"
]
},
"x": {
"$ref": "#/$defs/SnapRule"
},
"y": {
"$ref": "#/$defs/SnapRule"
},
"both": {
"$ref": "#/$defs/SnapRule"
},
"angle": {
"$ref": "#/$defs/SnapRule"
},
"radius": {
"$ref": "#/$defs/SnapRule"
},
"size": {
"$ref": "#/$defs/AxisRules"
},
"reference": {
"enum": [
"anchor",
"bounds",
"center",
"edges"
]
},
"rotation": {
"type": "object",
"properties": {
"step": {
"type": "number"
},
"tolerance": {
"type": "number"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"bendpoints": {
"anyOf": [
{
"enum": [
"inherit",
"none"
]
},
{
"$ref": "#/$defs/AxisRules"
}
]
},
"labels": {
"anyOf": [
{
"const": "none"
},
{
"type": "object",
"properties": {
"positions": {
"type": "array",
"items": true
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
},
"targets": {
"type": "array",
"items": {
"enum": [
"rule",
"objects",
"guides",
"ports",
"parent"
]
}
},
"toleranceScreenPx": {
"type": "number"
},
"bypassModifier": {
"$ref": "#/$defs/Modifier"
},
"feedback": {
"type": "object",
"properties": {
"showGhost": {
"type": "boolean"
},
"showValue": {
"type": "boolean"
},
"highlightBand": {
"type": "boolean"
},
"style": {
"$ref": "#/$defs/StyleRef"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"applyToProgrammatic": {
"type": "boolean"
},
"byGesture": {
"description": "Snapping per gesture, each entry more specific than its level. See DISL 0.2, section 5.9.",
"type": "object",
"properties": {
"move": {
"description": "Snapping for moves, merged over the enclosing snapping per property and per axis. See DISL 0.2, section 5.9.",
"$ref": "#/$defs/Snapping"
},
"resize": {
"description": "Snapping for resizes, merged over the enclosing snapping per property and per axis. See DISL 0.2, section 5.9.",
"$ref": "#/$defs/Snapping"
},
"drop": {
"description": "Snapping for toolbox drops, create-at-pointer and context-menu add here, merged over the enclosing snapping per property and per axis. See DISL 0.2, section 5.9.",
"$ref": "#/$defs/Snapping"
},
"paste": {
"description": "Snapping for pastes, merged over the enclosing snapping per property and per axis. See DISL 0.2, section 5.9.",
"$ref": "#/$defs/Snapping"
},
"handle": {
"description": "Snapping for handle drags, merged over the enclosing snapping per property and per axis. See DISL 0.2, section 5.9.",
"$ref": "#/$defs/Snapping"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A snapping reference is how a coordinate system, a viewpoint canvas or a node or edge notation states its snapping. It is either a string naming a snap profile declared in the coordinates object, or a snapping object written inline. See section 5.9.
{
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/Snapping"
}
]
}A snap rule states how values along one axis, or one extent, are snapped. It is a string, either none for continuous values or the name of a profile, or a rule object with exactly one rule key. In the examples, inherit-x and inherit-y copy the other axis's rule. See section 5.10.
{
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/SnapRuleObject"
}
]
}A snap rule object is the object form of a snap rule and holds exactly one rule key: grid, values, calendar (time units), ticks (visible axis ticks), bands (ordinal bands), divisions (equal parts), ratio (aspect ratios), cel (a custom function), byZoom (zoom-dependent rules) or plugin. Common properties beside the key clamp the result with min and max, set the rounding direction (nearest by default) and override the mode. See section 5.10.
{
"type": "object",
"properties": {
"grid": {
"type": "object",
"properties": {
"spacing": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
}
]
},
"offset": true,
"subdivisions": {
"type": "integer"
},
"subdivideAtZoom": {
"type": "number"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"spacing"
],
"patternProperties": {
"^x-": true
}
},
"values": {
"anyOf": [
{
"type": "array",
"items": true
},
{
"$ref": "#/$defs/CelValue"
}
]
},
"calendar": {
"type": "object",
"properties": {
"unit": {
"description": "The unit: a time unit, or {attribute} bound to a diagram attribute whose enum values are unit names. See DISL 0.2, section 5.10.",
"anyOf": [
{
"$ref": "#/$defs/TimeUnit"
},
{
"$ref": "#/$defs/AttrBinding"
}
]
},
"step": {
"type": "integer"
},
"align": {
"enum": [
"start",
"end",
"nearest"
]
},
"workingTime": {
"type": "boolean"
},
"calendar": {
"type": "string"
},
"at": {
"type": "string"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"unit"
],
"patternProperties": {
"^x-": true
}
},
"ticks": {
"type": "object",
"properties": {
"level": {
"enum": [
"major",
"minor"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"bands": {
"type": "object",
"properties": {
"align": {
"enum": [
"start",
"center",
"end",
"keep-offset"
]
},
"offsetGrid": {
"type": "number"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"divisions": {
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"of": {
"enum": [
"parent",
"canvas",
"axis"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"count"
],
"patternProperties": {
"^x-": true
}
},
"ratio": {
"type": "object",
"properties": {
"ratios": {
"type": "array",
"items": {
"type": "number"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"ratios"
],
"patternProperties": {
"^x-": true
}
},
"cel": {
"$ref": "#/$defs/CelSource"
},
"byZoom": {
"type": "array",
"items": {
"type": "object",
"properties": {
"maxZoom": {
"type": "number"
},
"rule": {
"$ref": "#/$defs/SnapRule"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"rule"
],
"patternProperties": {
"^x-": true
}
},
"minItems": 1
},
"plugin": {
"$ref": "#/$defs/QualifiedId"
},
"args": {
"type": "object"
},
"min": true,
"max": true,
"direction": {
"enum": [
"nearest",
"floor",
"ceil"
]
},
"ties": {
"enum": [
"away-from-zero",
"toward-zero",
"up",
"down",
"even"
],
"description": "How a value exactly halfway rounds when direction is nearest: away-from-zero (the default, as CEL math.round), toward-zero, up, down or even. See DISL 0.2, section 5.10."
},
"mode": {
"enum": [
"always",
"magnetic"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"oneOf": [
{
"required": [
"grid"
]
},
{
"required": [
"values"
]
},
{
"required": [
"calendar"
]
},
{
"required": [
"ticks"
]
},
{
"required": [
"bands"
]
},
{
"required": [
"divisions"
]
},
{
"required": [
"ratio"
]
},
{
"required": [
"cel"
]
},
{
"required": [
"byZoom"
]
},
{
"required": [
"plugin"
]
}
]
}Axis rules group snap rules by axis, with x, y and both, where both applies one rule to x and y. A snapping object uses them for sizes, the rules for extents such as width and height, and for edge bendpoints when these are not simply inherited or switched off. See section 5.9.
{
"type": "object",
"properties": {
"x": {
"$ref": "#/$defs/SnapRule"
},
"y": {
"$ref": "#/$defs/SnapRule"
},
"both": {
"$ref": "#/$defs/SnapRule"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}3 · Notation
The notation layer of a specification: the concrete syntax that says how every node, edge, port and label of the diagram type looks. It holds the theme and fonts, named styles, custom shapes, markers and icons, the notations per node type, edge type and port, the canvas, and defaults for nodes and edges. A visual property resolves from per-element overrides, states, conditions and variants down through styles, supertypes and these defaults to the built-in default. See section 6.1.
{
"type": "object",
"properties": {
"theme": {
"$ref": "#/$defs/Theme"
},
"fonts": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"src": {
"type": "array",
"items": {
"type": "string"
}
},
"weights": {
"type": "array",
"items": {
"type": "integer"
}
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"textMetric": {
"description": "How text is measured for geometry. See DISL 0.2, section 6.5.",
"$ref": "#/$defs/TextMetric"
},
"styles": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Style"
}
},
"shapes": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/ShapeDef"
}
},
"markers": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/MarkerDef"
}
},
"icons": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/IconDef"
}
},
"nodes": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/QualifiedId"
},
"additionalProperties": {
"$ref": "#/$defs/NodeNotation"
}
},
"edges": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/QualifiedId"
},
"additionalProperties": {
"$ref": "#/$defs/EdgeNotation"
}
},
"ports": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/PortNotation"
}
},
"canvas": {
"$ref": "#/$defs/Canvas"
},
"defaults": {
"type": "object",
"properties": {
"node": {
"$ref": "#/$defs/NodeNotation"
},
"edge": {
"$ref": "#/$defs/EdgeNotation"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}The theme of a specification's notation: semantic tokens that give colors, fonts and sizes names, so one specification renders well in any mode or brand palette. Its tokens property holds the base values and its modes property overrides them per mode; light, dark and high-contrast are recognised by runtimes. It can also set the initial mode, follow the system preference and extend an imported theme. Tokens are referenced from any bindable position. See section 6.2.
{
"type": "object",
"properties": {
"tokens": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/QualifiedId"
}
},
"modes": {
"type": "object",
"additionalProperties": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/QualifiedId"
}
}
},
"defaultMode": {
"type": "string"
},
"followSystem": {
"type": "boolean"
},
"extends": {
"type": "string"
},
"contrast": {
"type": "array",
"items": {
"$ref": "#/$defs/ContrastRequirement"
},
"description": "Contrast requirements checked by specification validators. See DISL 0.2, section 6.2."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}What fills an area or colors a stroke, used by fills, stroke colors, font colors, halos and shadows. It is a color string such as a hex value, transparent or currentColor; the string none for no paint, which unlike transparent is not hit-testable; a token, CEL or attribute reference; or an object for a linear or radial gradient, a pattern or an image. See section 6.3.
{
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/Dynamic"
},
{
"$ref": "#/$defs/Gradient"
},
{
"$ref": "#/$defs/Pattern"
},
{
"$ref": "#/$defs/ImagePaint"
}
]
}A paint that blends colors, either linear along an angle or radial from a center with a radius. Its type property chooses linear or radial, and its stops list at least two colors, each at an offset given as a fraction from 0 to 1. Stop colors are bindable, so a gradient can follow theme tokens. See section 6.3.
{
"type": "object",
"properties": {
"type": {
"enum": [
"linear",
"radial"
]
},
"angle": {
"type": "number"
},
"center": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
},
"radius": {
"type": "number"
},
"stops": {
"type": "array",
"items": {
"type": "object",
"properties": {
"offset": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"color": {
"$ref": "#/$defs/BString"
}
},
"additionalProperties": false,
"required": [
"offset",
"color"
],
"patternProperties": {
"^x-": true
}
},
"minItems": 2
}
},
"additionalProperties": false,
"required": [
"type",
"stops"
],
"patternProperties": {
"^x-": true
}
}A paint that fills an area with a repeating built-in pattern: hatch, cross-hatch, dots, grid, vertical, horizontal, zigzag, checker or bricks. Its color, background, spacing, angle and line width can be set. Patterns are recommended as a secondary visual cue wherever color alone distinguishes categories, for accessibility. See section 6.3.
{
"type": "object",
"properties": {
"type": {
"const": "pattern"
},
"pattern": {
"enum": [
"hatch",
"cross-hatch",
"dots",
"grid",
"vertical",
"horizontal",
"zigzag",
"checker",
"bricks"
]
},
"color": {
"$ref": "#/$defs/BString"
},
"background": {
"$ref": "#/$defs/BString"
},
"spacing": {
"type": "number"
},
"angle": {
"type": "number"
},
"width": {
"type": "number"
}
},
"additionalProperties": false,
"required": [
"type",
"pattern"
],
"patternProperties": {
"^x-": true
}
}A paint that fills an area with an image, named by its src property, which is bindable. Its fit property says how the image covers the area (tile, cover, contain or stretch), and its opacity property makes it translucent. See section 6.3.
{
"type": "object",
"properties": {
"type": {
"const": "image"
},
"src": {
"$ref": "#/$defs/BString"
},
"fit": {
"enum": [
"tile",
"cover",
"contain",
"stretch"
]
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"additionalProperties": false,
"required": [
"type",
"src"
],
"patternProperties": {
"^x-": true
}
}How an outline or line is drawn, used alike for node outlines, edge lines, separators, grid lines and marker outlines. It sets color, width (default 1), opacity, dash style (default solid), caps, joins and alignment on closed outlines. Beyond that it can draw a double line, a wider casing underneath, a geometric line effect, animated flow along the path that respects reduced-motion preferences, or a hand-drawn sketch. See section 6.4.
{
"type": "object",
"properties": {
"color": {
"$ref": "#/$defs/Paint"
},
"width": {
"$ref": "#/$defs/BNumber"
},
"minWidthScreenPx": {
"type": "number"
},
"opacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"dash": {
"$ref": "#/$defs/DashStyle"
},
"dashOffset": {
"type": "number"
},
"dashScale": {
"enum": [
"absolute",
"width"
]
},
"cap": {
"enum": [
"butt",
"round",
"square"
]
},
"join": {
"enum": [
"miter",
"round",
"bevel"
]
},
"miterLimit": {
"type": "number"
},
"align": {
"enum": [
"center",
"inside",
"outside"
]
},
"double": {
"type": "object",
"properties": {
"gap": {
"type": "number"
},
"innerColor": {
"$ref": "#/$defs/Paint"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"casing": {
"type": "object",
"properties": {
"color": {
"$ref": "#/$defs/Paint"
},
"width": {
"type": "number"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"effect": {
"$ref": "#/$defs/LineEffect"
},
"flow": {
"type": "object",
"properties": {
"speed": {
"type": "number"
},
"direction": {
"enum": [
"forward",
"backward"
]
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"sketch": {
"type": "object",
"properties": {
"roughness": {
"type": "number"
},
"bowing": {
"type": "number"
},
"seed": true
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}The dash pattern of a stroke: one of the named presets solid, dashed, long-dash, short-dash, dotted, dash-dot and dash-dot-dot, or an explicit array of alternating dash and gap lengths. By default, dash lengths are multiples of the stroke width rather than canvas units, as set by the stroke's dashScale property. The default is solid. See section 6.4.
{
"anyOf": [
{
"enum": [
"solid",
"dashed",
"long-dash",
"short-dash",
"dotted",
"dash-dot",
"dash-dot-dot"
]
},
{
"type": "array",
"items": {
"type": "number"
},
"minItems": 1
},
{
"$ref": "#/$defs/Dynamic"
}
]
}A geometric effect that modifies the shape of a line or outline, set on a stroke. Its type property picks a wave, zigzag, loops (a coil), ticks along one or both sides, repeated small arrowheads, a parallel offset, or a plugin effect, each with its own parameters such as amplitude and wavelength. Effects apply before dashes, so a dashed wave is possible, and never change the hit-test geometry. See section 6.4.
{
"type": "object",
"properties": {
"type": {
"enum": [
"wave",
"zigzag",
"loops",
"ticks",
"arrows",
"offset",
"plugin"
]
},
"amplitude": {
"type": "number"
},
"wavelength": {
"type": "number"
},
"radius": {
"type": "number"
},
"spacing": {
"type": "number"
},
"length": {
"type": "number"
},
"side": {
"enum": [
"left",
"right",
"both"
]
},
"marker": {
"$ref": "#/$defs/MarkerRef"
},
"distance": {
"type": "number"
},
"name": {
"type": "string"
},
"args": {
"type": "object"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"type"
],
"patternProperties": {
"^x-": true
}
}How text is set, used as a style's default font for an element's labels. It covers family (a font stack, default the body font token), size in canvas units (default 14), weight (default 400), style, color, line height (default 1.3 times the size), letter spacing, decoration, case transform and variant. A minimum on-screen size hides small text when zoomed out, and a halo outlines glyphs for legibility over lines and fills. See section 6.5.
{
"type": "object",
"properties": {
"family": {
"$ref": "#/$defs/BString"
},
"size": {
"$ref": "#/$defs/BNumber"
},
"minSizeScreenPx": {
"type": "number"
},
"weight": {
"anyOf": [
{
"type": "integer"
},
{
"enum": [
"normal",
"bold"
]
}
]
},
"style": {
"enum": [
"normal",
"italic"
]
},
"color": {
"$ref": "#/$defs/Paint"
},
"lineHeight": {
"type": "number"
},
"letterSpacing": {
"type": "number"
},
"decoration": {
"enum": [
"none",
"underline",
"line-through",
"overline"
]
},
"transform": {
"enum": [
"none",
"uppercase",
"lowercase",
"capitalize"
]
},
"variant": {
"enum": [
"normal",
"small-caps",
"tabular-nums"
]
},
"halo": {
"type": "object",
"properties": {
"color": {
"$ref": "#/$defs/Paint"
},
"width": {
"type": "number"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A bundle of visual properties, declared by name in the notation's styles or written inline wherever a style is accepted. It sets fill, stroke, opacity, corner radius, shadow, font, text alignment, padding, cursor, filter, blend mode and visibility. Its extends property inherits from one or more other styles, merged left to right before the style's own properties, and properties merge per key when styles combine. See section 6.6.
{
"type": "object",
"properties": {
"extends": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
},
"fill": {
"$ref": "#/$defs/Paint"
},
"fillOpacity": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"stroke": {
"$ref": "#/$defs/Stroke"
},
"opacity": {
"anyOf": [
{
"type": "number",
"minimum": 0,
"maximum": 1
},
{
"$ref": "#/$defs/Dynamic"
}
]
},
"cornerRadius": {
"anyOf": [
{
"$ref": "#/$defs/BNumber"
},
{
"type": "array",
"items": {
"type": "number"
},
"minItems": 4,
"maxItems": 4
}
]
},
"shadow": {
"anyOf": [
{
"const": "none"
},
{
"type": "object",
"properties": {
"dx": {
"type": "number"
},
"dy": {
"type": "number"
},
"blur": {
"type": "number"
},
"color": {
"$ref": "#/$defs/Paint"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
},
"font": {
"$ref": "#/$defs/Font"
},
"textAlign": {
"enum": [
"left",
"center",
"right",
"justify"
]
},
"verticalAlign": {
"enum": [
"top",
"middle",
"bottom"
]
},
"padding": {
"$ref": "#/$defs/Insets"
},
"cursor": {
"type": "string"
},
"filter": {
"enum": [
"none",
"grayscale",
"blur"
]
},
"blend": {
"type": "string"
},
"visible": {
"$ref": "#/$defs/BBool"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A reference to a style wherever a specification applies one: either a string naming a style declared in the notation's styles, or a style object written inline. It is used by interaction states, conditional styles, parts of composite shapes, handles and many other visual properties. See section 6.6.
{
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/Style"
}
]
}One style reference or a list of them, used for the base style of node and edge notations and their variants. Each entry is either the name of a style declared in the notation's styles or an inline style object. See section 6.9.
{
"anyOf": [
{
"$ref": "#/$defs/StyleRef"
},
{
"type": "array",
"items": {
"$ref": "#/$defs/StyleRef"
}
}
]
}The styles a node, edge or port notation applies while an interaction state is active, as a map from state to style reference. The states are hover, selected, focused, dragging, highlighted, dropTarget, dropReject, invalid, warning, disabled and editing. A state style merges per key over the resolved style and outranks conditions and variants; runtimes supply sensible defaults for hover, selection, drop feedback and problems when the specification declares none. See section 6.6.
{
"type": "object",
"properties": {
"hover": {
"$ref": "#/$defs/StyleRef"
},
"selected": {
"$ref": "#/$defs/StyleRef"
},
"focused": {
"$ref": "#/$defs/StyleRef"
},
"dragging": {
"$ref": "#/$defs/StyleRef"
},
"highlighted": {
"$ref": "#/$defs/StyleRef"
},
"dropTarget": {
"$ref": "#/$defs/StyleRef"
},
"dropReject": {
"$ref": "#/$defs/StyleRef"
},
"invalid": {
"$ref": "#/$defs/StyleRef"
},
"warning": {
"$ref": "#/$defs/StyleRef"
},
"disabled": {
"$ref": "#/$defs/StyleRef"
},
"editing": {
"$ref": "#/$defs/StyleRef"
},
"filteredOut": {
"description": "Applied to an element a canvas filter with effect dim does not keep. See DISL 0.2, section 6.6.",
"$ref": "#/$defs/StyleRef"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A list of conditional styles on a notation, each applied while its when expression holds. Each entry pairs a CEL expression with a style reference, a named style or an inline one, and may carry documentation. When several are true they apply in declaration order, later ones winning, and they rank below interaction states and above variants when a visual property is resolved. See section 6.6.
{
"type": "array",
"items": {
"type": "object",
"properties": {
"when": {
"$ref": "#/$defs/Expression"
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"when",
"style"
],
"patternProperties": {
"^x-": true
}
}
}An icon declared in the notation's icons for use by tools, nodes, badges and labels. It is given as inline SVG, which is sanitised, as a path (optionally drawn as a stroke), as an image source with a size, or as a glyph from an icon font. Icons are monochrome by default and take the current color so they follow the theme; its colored property keeps their own colors. See section 6.14.
{
"type": "object",
"properties": {
"svg": {
"type": "string"
},
"path": {
"$ref": "#/$defs/PathDef"
},
"stroke": {
"type": "boolean"
},
"src": {
"type": "string"
},
"size": {
"$ref": "#/$defs/Size"
},
"font": {
"type": "string"
},
"glyph": {
"type": "string"
},
"colored": {
"type": "boolean"
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A reference to an icon: either a string naming one, such as an icon declared in the notation's icons or a library icon like std.database or tabler:database, or an icon definition written inline. DISL 0.2 adds {icon, flip}, an icon mirrored horizontally, vertically or both. See section 6.14.
{
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/IconDef"
},
{
"type": "object",
"properties": {
"icon": {
"$ref": "#/$defs/IconRef",
"description": "The icon to mirror. See DISL 0.2, section 6.14."
},
"flip": {
"anyOf": [
{
"enum": [
"none",
"horizontal",
"vertical",
"both"
]
},
{
"$ref": "#/$defs/Dynamic"
}
],
"description": "none, horizontal, vertical or both; bindable. See DISL 0.2, section 6.14."
}
},
"additionalProperties": false,
"required": [
"icon"
],
"patternProperties": {
"^x-": true
}
}
]
}A reference to the shape of a node body or of a part: either a string naming a built-in primitive such as ellipse, or an object. The object is either a shape instance, which names a shape and gives its parameters, or a custom shape definition written inline. When a node notation gives none, the body shape is rect. See section 6.7.
{
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/ShapeInstance"
},
{
"$ref": "#/$defs/ShapeDef"
}
]
}A use of a named shape with its parameters, one of the forms of a shape reference. Its type property names the shape, for example roundedRect or polygon, and its params property supplies parameter values, each of which is bindable, so a parameter can follow a token, attribute or CEL expression. Parameters left out take the shape's defaults. See section 6.7.
{
"type": "object",
"properties": {
"type": {
"type": "string"
},
"params": {
"type": "object",
"additionalProperties": true
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"type"
],
"patternProperties": {
"^x-": true
}
}A custom shape a specification declares in the notation's shapes when no built-in primitive fits, from a static SVG path to a fully parameterised shape whose geometry is computed with CEL. Exactly one of path, parts, svg or plugin gives its geometry. It can also declare parameters, handles that edit them, the outline used for anchoring and hit testing, the label's text area, a default size, an aspect ratio and a scaling mode. See section 6.8.
{
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/LocalizedText"
},
"params": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/ShapeParam"
}
},
"path": {
"$ref": "#/$defs/PathDef"
},
"parts": {
"type": "array",
"items": {
"$ref": "#/$defs/ShapePart"
},
"minItems": 1
},
"svg": {
"type": "string"
},
"plugin": {
"$ref": "#/$defs/PluginCall"
},
"outline": {
"anyOf": [
{
"enum": [
"path",
"bounds",
"ellipse"
]
},
{
"$ref": "#/$defs/PathDef"
}
]
},
"textArea": {
"$ref": "#/$defs/Box"
},
"handles": {
"type": "array",
"items": {
"$ref": "#/$defs/Handle"
}
},
"defaultSize": {
"$ref": "#/$defs/Size"
},
"aspectRatio": {
"type": "number"
},
"scaling": {
"$ref": "#/$defs/ScaleMode"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"oneOf": [
{
"required": [
"path"
]
},
{
"required": [
"parts"
]
},
{
"required": [
"svg"
]
},
{
"required": [
"plugin"
]
}
]
}A parameter of a custom shape, such as the fold of a note, which its geometry expressions read as p followed by the parameter name. Its type property is required, and it can have a default, which may be a CEL expression depending on width and height, bounds, enum values and a unit that guides forms and handles. Its persist property says whether user-adjusted values are stored per element in view data, which is the default. See section 6.8.
{
"type": "object",
"properties": {
"type": {
"enum": [
"number",
"int",
"bool",
"enum",
"color",
"string"
]
},
"default": true,
"min": {
"$ref": "#/$defs/GeomExpr"
},
"max": {
"$ref": "#/$defs/GeomExpr"
},
"values": {
"type": "array",
"items": {
"type": "string"
}
},
"unit": {
"enum": [
"length",
"fraction",
"angle",
"count"
]
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"persist": {
"enum": [
"view",
"none"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"type"
],
"patternProperties": {
"^x-": true
}
}The geometry of a custom shape, an icon or a shape outline, given as a path. It is either an SVG path string in a declared viewBox, scaled into the bounds, or a list of segments whose coordinates are geometry expressions evaluated against the node's width, height and parameters. A path can hold several sub-paths and a fill rule, nonzero by default or evenodd. See section 6.8.
{
"type": "object",
"properties": {
"viewBox": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 4,
"maxItems": 4
},
"d": {
"type": "string"
},
"segments": {
"type": "array",
"items": {
"$ref": "#/$defs/PathSegment"
},
"minItems": 1
},
"fillRule": {
"enum": [
"nonzero",
"evenodd"
]
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"oneOf": [
{
"required": [
"d"
]
},
{
"required": [
"segments"
]
}
]
}One step of a segment-based path. Its op property picks move, line, horizontal or vertical line, quadratic or cubic Bezier, elliptical arc with SVG semantics, a rounded rectangle or ellipse sub-path, or close, and the coordinate fields each op needs are geometry expressions. A segment can carry a when expression to include it only conditionally, so a shape's topology can depend on its parameters. See section 6.8.
{
"type": "object",
"properties": {
"op": {
"enum": [
"M",
"L",
"H",
"V",
"Q",
"C",
"A",
"R",
"E",
"Z"
]
},
"x": {
"$ref": "#/$defs/GeomExpr"
},
"y": {
"$ref": "#/$defs/GeomExpr"
},
"cx": {
"$ref": "#/$defs/GeomExpr"
},
"cy": {
"$ref": "#/$defs/GeomExpr"
},
"c1x": {
"$ref": "#/$defs/GeomExpr"
},
"c1y": {
"$ref": "#/$defs/GeomExpr"
},
"c2x": {
"$ref": "#/$defs/GeomExpr"
},
"c2y": {
"$ref": "#/$defs/GeomExpr"
},
"rx": {
"$ref": "#/$defs/GeomExpr"
},
"ry": {
"$ref": "#/$defs/GeomExpr"
},
"rotation": {
"$ref": "#/$defs/GeomExpr"
},
"w": {
"$ref": "#/$defs/GeomExpr"
},
"h": {
"$ref": "#/$defs/GeomExpr"
},
"r": {
"$ref": "#/$defs/GeomExpr"
},
"largeArc": {
"type": "boolean"
},
"sweep": {
"type": "boolean"
},
"when": {
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"required": [
"op"
],
"patternProperties": {
"^x-": true
}
}One part of a composite custom shape, itself a built-in or custom shape with its own box and style. Its box gives its bounds in shape coordinates, its style merges over the node style, and its id lets styles and states address the part. A part can be rotated, included only when an expression holds, contribute to the connection outline, or be excluded from hit testing. See section 6.8.
{
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"shape": {
"$ref": "#/$defs/ShapeRef"
},
"box": {
"$ref": "#/$defs/Box"
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"rotate": {
"$ref": "#/$defs/GeomExpr"
},
"when": {
"$ref": "#/$defs/Expression"
},
"outline": {
"type": "boolean"
},
"hit": {
"type": "boolean"
},
"tooltip": {
"description": "Hover text over this part, shown in place of the node's tooltip; a Message in the element context plus p, the shape's parameter values. See DISL 0.3, section 6.8.",
"$ref": "#/$defs/Message"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"shape"
],
"patternProperties": {
"^x-": true
}
}An interactive handle on a custom shape that lets a user fine-tune one of its parameters by dragging on the canvas. It names the parameter it edits, gives its position as geometry expressions, the axis it moves along, and an inverse expression that computes the new value from the pointer position. A two-parameter handle also edits a second parameter, and snapping, appearance and a tooltip can be set. See section 6.8.
{
"type": "object",
"properties": {
"param": {
"$ref": "#/$defs/SimpleId"
},
"x": {
"$ref": "#/$defs/GeomExpr"
},
"y": {
"$ref": "#/$defs/GeomExpr"
},
"axis": {
"enum": [
"x",
"y",
"both",
"radial"
]
},
"value": {
"$ref": "#/$defs/Expression"
},
"yParam": {
"$ref": "#/$defs/SimpleId"
},
"yValue": {
"$ref": "#/$defs/Expression"
},
"snap": {
"$ref": "#/$defs/SnapRule"
},
"cursor": {
"type": "string"
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"label": {
"description": "The tooltip while hovering or dragging, in the handle context, where p holds the parameter values under the pointer while dragging. See DISL 0.2, section 6.8.",
"$ref": "#/$defs/Message"
},
"visible": {
"description": "Whether the handle is offered, in the element context plus env. See DISL 0.2, section 6.8.",
"$ref": "#/$defs/Expression"
},
"write": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
},
"description": "For a parameter bound with {cel}: actions run with value (and yValue) bound to the new, snapped value, as one change transaction, in the handleWrite context. A handle on an {attribute}-bound parameter writes that attribute. See DISL 0.2, section 6.8."
},
"refusals": {
"description": "Refusals per gesture on the handle. See DISL 0.2, section 6.8.",
"type": "object",
"properties": {
"move": {
"description": "Shown when the user tries to drag the handle while it does not apply. See DISL 0.2, section 6.8.",
"$ref": "#/$defs/Reason"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"param",
"x",
"y"
],
"patternProperties": {
"^x-": true
}
}How the static geometry of a custom shape, its viewBox paths or inline SVG, is fitted into the node's bounds; a custom shape sets it through its scaling property. It is one of stretch (the default), uniform (keep the aspect ratio, centered) or none (one to one at the top-left), or an object whose nineSlice lists top, right, bottom and left insets so the corners keep their size and only the middle stretches. See section 6.8.
{
"anyOf": [
{
"enum": [
"stretch",
"uniform",
"none"
]
},
{
"type": "object",
"properties": {
"nineSlice": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 4,
"maxItems": 4
}
},
"additionalProperties": false,
"required": [
"nineSlice"
],
"patternProperties": {
"^x-": true
}
}
]
}Where a label, icon, badge or legend sits relative to a node, port or the canvas. It is either a named slot (center, top, bottom, left, right or a corner such as top-left), the same slots prefixed with outside- to place the item beyond the outline, or plain outside; or an object giving an anchor as fractions of the bounds, an optional offset in canvas units and an align of start, center or end. See section 6.9.
{
"anyOf": [
{
"enum": [
"center",
"top",
"bottom",
"left",
"right",
"top-left",
"top-right",
"bottom-left",
"bottom-right",
"outside-top",
"outside-bottom",
"outside-left",
"outside-right",
"outside-top-left",
"outside-top-right",
"outside-bottom-left",
"outside-bottom-right",
"outside"
]
},
{
"type": "object",
"properties": {
"anchor": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
},
"offset": {
"description": "The offset [dx, dy] from the anchor, or bound: {attribute} (a dragged label then writes the attribute) or {cel}. See DISL 0.2, section 6.12.",
"anyOf": [
{
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
},
{
"$ref": "#/$defs/AttrBinding"
},
{
"$ref": "#/$defs/CelValue"
}
]
},
"align": {
"enum": [
"start",
"center",
"end"
]
}
},
"additionalProperties": false,
"required": [
"anchor"
],
"patternProperties": {
"^x-": true
}
}
]
}A piece of text drawn on a node, edge, port, compartment header or the canvas; the same object is used everywhere. Its text is a bindable string, and binding it to an attribute makes it editable inline by default; format, wrap, maxWidth, overflow and background control rendering, and parse can split edited text into several attributes. Node labels use position, while edge labels add at, side, offset, distance and orientation to place themselves along the path. See section 6.12.
{
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"text": {
"$ref": "#/$defs/BString"
},
"format": {
"enum": [
"plain",
"markdown",
"rich"
]
},
"placeholder": {
"$ref": "#/$defs/LocalizedText"
},
"editable": {
"anyOf": [
{
"const": false
},
{
"enum": [
"inline",
"multiline",
"form"
]
}
]
},
"parse": {
"type": "object",
"properties": {
"cel": {
"$ref": "#/$defs/CelSource"
},
"write": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"accepts": {
"description": "Whether the entered text, value, is accepted; when it is not, the edit is refused with refusal. Form context. See DISL 0.3, section 6.12.",
"$ref": "#/$defs/Expression"
},
"refusal": {
"description": "Shown when accepts is false. Form context. See DISL 0.3, section 6.12.",
"$ref": "#/$defs/Message"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"write"
],
"patternProperties": {
"^x-": true
}
},
"editText": {
"description": "The text an inline editor starts with in place of the label's text: a Message in the element context, or an attribute binding, which also receives the committed text when the label has no parse. See DISL 0.3, section 6.12.",
"anyOf": [
{
"$ref": "#/$defs/Message"
},
{
"$ref": "#/$defs/AttrBinding"
}
]
},
"position": {
"$ref": "#/$defs/Position"
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"background": {
"type": "object",
"properties": {
"fill": {
"$ref": "#/$defs/Paint"
},
"stroke": {
"$ref": "#/$defs/Stroke"
},
"padding": {
"$ref": "#/$defs/Insets"
},
"cornerRadius": {
"type": "number"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"maxWidth": {
"anyOf": [
{
"type": "number"
},
{
"const": "parent"
}
]
},
"wrap": {
"enum": [
"none",
"word",
"char"
]
},
"maxLines": {
"type": "integer"
},
"overflow": {
"enum": [
"visible",
"clip",
"ellipsis",
"shrink"
]
},
"rotation": {
"anyOf": [
{
"type": "number"
},
{
"const": "vertical"
}
]
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"visible": {
"$ref": "#/$defs/BBool"
},
"draggable": {
"type": "boolean"
},
"link": {
"$ref": "#/$defs/BString"
},
"tooltip": {
"$ref": "#/$defs/Message"
},
"layer": {
"const": "top"
},
"at": {
"anyOf": [
{
"enum": [
"start",
"middle",
"end"
]
},
{
"type": "number",
"minimum": 0,
"maximum": 1
}
]
},
"offset": {
"type": "number"
},
"side": {
"enum": [
"above",
"below",
"left",
"right",
"on"
]
},
"distance": {
"type": "number"
},
"orientation": {
"enum": [
"horizontal",
"follow",
"upright"
]
},
"avoidMarkers": {
"type": "boolean"
},
"keepOnSegment": {
"type": "boolean"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"text"
],
"patternProperties": {
"^x-": true
}
}A stacked region inside a node that lists items, such as the attributes and operations of a class or the columns of a table; a node notation holds them in its compartments list. Its required id names it and its required items gives the source: a many-valued attribute, the node's children of given types in a slot, or a CEL list. Per-item text, icon and style render each item, and layout, overflow, collapsing and editable options control arrangement and in-place editing. See section 6.9.
{
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"title": {
"$ref": "#/$defs/LocalizedText"
},
"items": {
"anyOf": [
{
"$ref": "#/$defs/AttrBinding"
},
{
"$ref": "#/$defs/CelValue"
},
{
"type": "object",
"properties": {
"children": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
}
},
"slot": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"children"
],
"patternProperties": {
"^x-": true
}
}
]
},
"itemText": {
"$ref": "#/$defs/BString"
},
"itemIcon": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/Dynamic"
}
]
},
"itemStyle": {
"$ref": "#/$defs/StyleRef"
},
"itemConditions": {
"$ref": "#/$defs/Conditions"
},
"itemLink": {
"description": "A link per item, in the compartmentItem context: where it is a non-empty string, a link symbol at the end of the item's line opens it with the open action. See DISL 0.4, section 6.9.",
"$ref": "#/$defs/BString"
},
"itemOrder": {
"description": "The order items are listed in, computed when drawing: by the value of by per item (compartmentItem context), ascending by default; items whose value is null come last, and ties keep the source order. See DISL 0.4, section 6.9.",
"type": "object",
"properties": {
"by": {
"$ref": "#/$defs/Expression"
},
"direction": {
"enum": [
"ascending",
"descending"
]
}
},
"additionalProperties": false,
"required": [
"by"
],
"patternProperties": {
"^x-": true
}
},
"groupBy": {
"description": "Lists the items under one collapsible heading per value of an enum attribute of the items. See DISL 0.4, section 6.9.",
"$ref": "#/$defs/GroupBy"
},
"layout": {
"enum": [
"vertical",
"horizontal",
"grid",
"wrap"
]
},
"separator": {
"anyOf": [
{
"const": "none"
},
{
"$ref": "#/$defs/Stroke"
}
]
},
"size": {
"anyOf": [
{
"const": "auto"
},
{
"type": "number"
},
{
"type": "object",
"properties": {
"min": {
"type": "number"
},
"max": {
"type": "number"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
},
"overflow": {
"enum": [
"grow",
"clip",
"scroll",
"ellipsis"
]
},
"maxItems": {
"type": "integer"
},
"collapsible": {
"type": "boolean"
},
"collapsed": {
"description": "The default collapse state of the compartment; a stored state wins, and is stored only while it differs from this default. See DISL 0.4, section 6.9.",
"$ref": "#/$defs/BBool"
},
"emptyText": {
"$ref": "#/$defs/LocalizedText"
},
"editable": {
"type": "object",
"properties": {
"add": {
"type": "boolean"
},
"remove": {
"type": "boolean"
},
"reorder": {
"type": "boolean"
},
"inline": {
"type": "boolean"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"visible": {
"$ref": "#/$defs/BBool"
},
"padding": {
"$ref": "#/$defs/Insets"
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"id",
"items"
],
"patternProperties": {
"^x-": true
}
}The icon a node notation draws inside or beside the node, set through its icon property. The icon itself is required and may be a fixed icon reference or bound to model data; position places it, size gives its size, color tints it and visible can hide it conditionally. Variants commonly swap it, for example to show a different symbol on a gateway depending on its kind. See section 6.9.
{
"type": "object",
"properties": {
"icon": {
"anyOf": [
{
"$ref": "#/$defs/IconRef"
},
{
"$ref": "#/$defs/Dynamic"
}
]
},
"position": {
"$ref": "#/$defs/Position"
},
"size": {
"type": "number"
},
"color": {
"$ref": "#/$defs/Paint"
},
"flip": {
"anyOf": [
{
"enum": [
"none",
"horizontal",
"vertical",
"both"
]
},
{
"$ref": "#/$defs/Dynamic"
}
],
"description": "Mirrors the icon: none (the default), horizontal, vertical or both; bindable. Hit testing is unchanged. See DISL 0.2, section 6.9."
},
"visible": {
"$ref": "#/$defs/BBool"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"icon"
],
"patternProperties": {
"^x-": true
}
}A small indicator drawn at a corner or edge of a node, such as a problem counter, a lock, a stereotype glyph or a progress ring; a node notation lists them in badges. Only its id is required; position and offset place it, shape, text, icon, style and size draw it, visible can hide it conditionally, and tooltip and onClick, which names an operation, make it informative and interactive. See section 6.9.
{
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"pack": {
"type": "boolean",
"description": "Whether the badge takes the next slot of the node's badgeLayout while it is visible, ignoring position and offset; defaults to false. See DISL 0.2, section 6.9."
},
"position": {
"$ref": "#/$defs/Position"
},
"offset": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
},
"shape": {
"$ref": "#/$defs/ShapeRef"
},
"text": {
"$ref": "#/$defs/BString"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"flip": {
"anyOf": [
{
"enum": [
"none",
"horizontal",
"vertical",
"both"
]
},
{
"$ref": "#/$defs/Dynamic"
}
],
"description": "Mirrors the badge's icon: none (the default), horizontal, vertical or both; bindable. See DISL 0.2, section 6.9."
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"size": {
"type": "number"
},
"visible": {
"$ref": "#/$defs/BBool"
},
"tooltip": {
"$ref": "#/$defs/Message"
},
"onClick": {
"type": "string"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"id"
],
"patternProperties": {
"^x-": true
}
}How the ports of a node type are drawn and placed, keyed by port name in a node notation's ports map. shape defaults to an 8 by 8 rectangle; side picks the side of the node (auto chooses by direction, in on the left and out on the right), position is a fraction along it or distribute (the default) to space all instances evenly, and inset moves the port inside or outside the outline. movable, label and order add dragging, a label and a sort key. See section 6.9.
{
"type": "object",
"properties": {
"shape": {
"$ref": "#/$defs/ShapeRef"
},
"size": {
"$ref": "#/$defs/Size"
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"states": {
"$ref": "#/$defs/States"
},
"side": {
"anyOf": [
{
"enum": [
"top",
"right",
"bottom",
"left",
"auto"
]
},
{
"$ref": "#/$defs/Dynamic"
}
]
},
"position": {
"anyOf": [
{
"type": "number",
"minimum": 0,
"maximum": 1
},
{
"const": "distribute"
},
{
"$ref": "#/$defs/Dynamic"
}
]
},
"inset": {
"type": "number"
},
"movable": {
"type": "boolean"
},
"label": {
"$ref": "#/$defs/Label"
},
"order": {
"$ref": "#/$defs/Expression"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}Where edges attach to a node when they do not use a port, set through a node notation's anchors property. Its mode is outline (the default, where the line towards the center crosses the outline), center, fixed (only at the listed points, given as fractions of the bounds), sides (the midpoint of the nearest side, for orthogonal diagrams) or port. gap leaves space between outline and edge end, and spread distributes several edges arriving on one side. See section 6.9.
{
"type": "object",
"properties": {
"mode": {
"enum": [
"outline",
"center",
"fixed",
"sides",
"port"
]
},
"gap": {
"type": "number"
},
"spread": {
"type": "boolean"
},
"sides": {
"type": "array",
"items": {
"enum": [
"top",
"right",
"bottom",
"left"
]
},
"minItems": 1,
"uniqueItems": true,
"description": "The sides edges may attach to; defaults to all four. With mode sides the midpoint of the nearest allowed side is used; with outline the intersection is kept on the allowed sides; fixed ignores it. See DISL 0.2, section 6.9."
},
"points": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"x": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"y": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"additionalProperties": false,
"required": [
"x",
"y"
],
"patternProperties": {
"^x-": true
}
}
},
"drawnFrom": {
"description": "point (the default) draws an edge's end at its anchor; outline uses the anchor only to decide which side of the element the edge belongs to, and draws the end where the line towards the other end crosses the outline. See DISL 0.3, section 6.9.",
"enum": [
"point",
"outline"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}How a node whose type has children lays out, frames and clips them, set through a node notation's container property. layout is free, stack, grid, flow, lanes (bands, as for pools with lanes) or layout: followed by the name of a layout algorithm, with direction, gap, padding and columns refining it. header adds a title band, contentArea and clip bound the children, and autoGrow, collapsible, dropZones and highlightOnDrop govern editing. See section 6.9.
{
"type": "object",
"properties": {
"layout": {
"anyOf": [
{
"enum": [
"free",
"stack",
"grid",
"flow",
"lanes"
]
},
{
"type": "string",
"pattern": "^layout:"
}
]
},
"nesting": {
"enum": [
"inside",
"none"
],
"description": "inside (the default, 0.1) draws children inside the parent; none draws them outside it, so containment is shown by edges or layout, the parent does not grow to enclose them and moving it does not move them. See DISL 0.2, section 6.9."
},
"direction": {
"enum": [
"vertical",
"horizontal"
]
},
"gap": {
"type": "number"
},
"padding": {
"$ref": "#/$defs/Insets"
},
"columns": {
"type": "integer"
},
"header": {
"type": "object",
"properties": {
"size": {
"type": "number"
},
"side": {
"enum": [
"top",
"left",
"right",
"bottom"
]
},
"label": {
"$ref": "#/$defs/Label"
},
"style": {
"$ref": "#/$defs/StyleRef"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"contentArea": {
"$ref": "#/$defs/Box"
},
"clip": {
"type": "boolean"
},
"autoGrow": {
"type": "boolean"
},
"collapsible": {
"type": "boolean"
},
"dropZones": {
"type": "array",
"items": {
"type": "object",
"properties": {
"slot": {
"type": "string"
},
"box": {
"$ref": "#/$defs/Box"
},
"style": {
"$ref": "#/$defs/StyleRef"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"highlightOnDrop": {
"type": "boolean"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}The size and resize behaviour of a node type, set through a node notation's size property. default is the size on creation, min and max are limits, and fixed is shorthand for all three equal and not resizable. resizable (default true, or only horizontal or vertical), aspectRatio (a number or keep) and autoSize (fitting content, or grow, which never shrinks below the user's size) shape resizing, while width and height can bind the size to data. See section 6.9.
{
"type": "object",
"properties": {
"default": {
"$ref": "#/$defs/Size"
},
"min": {
"$ref": "#/$defs/Size"
},
"max": {
"$ref": "#/$defs/Size"
},
"fixed": {
"$ref": "#/$defs/Size"
},
"resizable": {
"anyOf": [
{
"type": "boolean"
},
{
"enum": [
"horizontal",
"vertical"
]
}
]
},
"aspectRatio": {
"anyOf": [
{
"type": "number"
},
{
"const": "keep"
}
]
},
"autoSize": {
"enum": [
"none",
"fitContent",
"fitWidth",
"fitHeight",
"grow"
]
},
"width": {
"$ref": "#/$defs/BNumber"
},
"height": {
"$ref": "#/$defs/BNumber"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}Live form widgets drawn inside a node set through a node notation's form property. form, which is required, names a form or gives one inline, and region is the area inside the node, by default the shape's text area. interaction says when widgets accept input (default onSelect), minZoom and fallback decide what shows when zoomed out, and autoSize lets the node grow to fit. See section 7.6.
{
"type": "object",
"properties": {
"form": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/Form"
}
]
},
"region": {
"$ref": "#/$defs/Box"
},
"interaction": {
"enum": [
"always",
"onSelect",
"onDoubleClick",
"readOnly"
]
},
"minZoom": {
"type": "number"
},
"fallback": {
"enum": [
"labels",
"none",
"summary"
]
},
"autoSize": {
"type": "boolean"
},
"style": {
"$ref": "#/$defs/StyleRef"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"form"
],
"patternProperties": {
"^x-": true
}
}One level-of-detail rule for semantic zoom, listed in a node notation's lod property. Its required maxZoom is the zoom level at or below which the rule applies; hide lists notation properties or label ids to leave out, labels reduces labels to primary or none, shape substitutes a simpler shape, and render set to box draws a plain filled rectangle for performance. See section 6.9.
{
"type": "object",
"properties": {
"maxZoom": {
"type": "number"
},
"hide": {
"type": "array",
"items": {
"type": "string"
}
},
"labels": {
"enum": [
"all",
"primary",
"none"
]
},
"shape": {
"$ref": "#/$defs/ShapeRef"
},
"render": {
"enum": [
"full",
"box"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"maxZoom"
],
"patternProperties": {
"^x-": true
}
}How one node type is drawn and behaves on the canvas, keyed by type name in the notation layer's nodes map. It combines the body shape (default rect) and styles, size and placement, labels (by default one centered label bound to the type's label attribute), compartments, an embedded form, icon, badges, ports, anchors and container layout. variants and lod switch parts of it by model state or zoom, and further properties set states, conditions, layer, tooltip, interaction permissions and double-click behaviour. See section 6.9.
{
"type": "object",
"properties": {
"shape": {
"$ref": "#/$defs/ShapeRef"
},
"style": {
"$ref": "#/$defs/StyleRefs"
},
"partStyles": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/StyleRef"
}
},
"size": {
"$ref": "#/$defs/SizeSpec"
},
"placement": {
"$ref": "#/$defs/Placement"
},
"snapping": {
"$ref": "#/$defs/SnappingRef"
},
"rotation": {
"type": "object",
"properties": {
"allowed": {
"type": "boolean"
},
"default": {
"type": "number"
},
"step": {
"type": "number"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"labels": {
"type": "array",
"items": {
"$ref": "#/$defs/Label"
}
},
"compartments": {
"type": "array",
"items": {
"$ref": "#/$defs/Compartment"
}
},
"form": {
"$ref": "#/$defs/EmbeddedForm"
},
"icon": {
"$ref": "#/$defs/NodeIcon"
},
"badges": {
"type": "array",
"items": {
"$ref": "#/$defs/Badge"
}
},
"badgeLayout": {
"description": "The slots packed badges take. See DISL 0.2, section 6.9.",
"$ref": "#/$defs/BadgeLayout"
},
"ports": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/PortNotation"
}
},
"anchors": {
"$ref": "#/$defs/AnchorSpec"
},
"container": {
"$ref": "#/$defs/ContainerSpec"
},
"variants": {
"type": "array",
"items": {
"$ref": "#/$defs/NodeVariant"
}
},
"lod": {
"type": "array",
"items": {
"$ref": "#/$defs/LodRule"
}
},
"states": {
"$ref": "#/$defs/States"
},
"conditions": {
"$ref": "#/$defs/Conditions"
},
"tooltip": {
"$ref": "#/$defs/Message"
},
"layer": {
"anyOf": [
{
"enum": [
"background",
"default",
"foreground"
]
},
{
"type": "integer"
}
]
},
"selectable": {
"$ref": "#/$defs/BBool"
},
"deletable": {
"$ref": "#/$defs/BBool"
},
"copyable": {
"$ref": "#/$defs/BBool"
},
"connectable": {
"$ref": "#/$defs/BBool"
},
"hitPaddingScreenPx": {
"type": "number"
},
"doubleClick": {
"type": "string"
},
"drillDown": {
"type": "object",
"properties": {
"viewpoint": {
"type": "string"
},
"filter": {
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"accessibility": {
"type": "object",
"properties": {
"role": {
"type": "string"
},
"name": {
"$ref": "#/$defs/BString"
},
"description": {
"$ref": "#/$defs/BString"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"refusals": {
"description": "The sentences shown when a gesture on an element of this kind is switched off, per gesture. See DISL 0.2, section 6.9.",
"$ref": "#/$defs/GestureRefusals"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A conditional alternative to parts of a node notation, such as a collapsed sub-process or a gateway symbol that depends on its kind, listed in the notation's variants property. Its when expression decides whether it applies, and it may carry any node notation property except placement. Every matching variant is applied in order over the base notation. See section 6.9.
{
"type": "object",
"properties": {
"when": {
"$ref": "#/$defs/Expression"
},
"shape": {
"$ref": "#/$defs/ShapeRef"
},
"style": {
"$ref": "#/$defs/StyleRefs"
},
"partStyles": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/StyleRef"
}
},
"size": {
"$ref": "#/$defs/SizeSpec"
},
"snapping": {
"$ref": "#/$defs/SnappingRef"
},
"rotation": {
"type": "object",
"properties": {
"allowed": {
"type": "boolean"
},
"default": {
"type": "number"
},
"step": {
"type": "number"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"labels": {
"type": "array",
"items": {
"$ref": "#/$defs/Label"
}
},
"compartments": {
"type": "array",
"items": {
"$ref": "#/$defs/Compartment"
}
},
"form": {
"$ref": "#/$defs/EmbeddedForm"
},
"icon": {
"$ref": "#/$defs/NodeIcon"
},
"badges": {
"type": "array",
"items": {
"$ref": "#/$defs/Badge"
}
},
"badgeLayout": {
"description": "The slots packed badges take. See DISL 0.2, section 6.9.",
"$ref": "#/$defs/BadgeLayout"
},
"ports": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/PortNotation"
}
},
"anchors": {
"$ref": "#/$defs/AnchorSpec"
},
"container": {
"$ref": "#/$defs/ContainerSpec"
},
"lod": {
"type": "array",
"items": {
"$ref": "#/$defs/LodRule"
}
},
"states": {
"$ref": "#/$defs/States"
},
"conditions": {
"$ref": "#/$defs/Conditions"
},
"tooltip": {
"$ref": "#/$defs/Message"
},
"layer": {
"anyOf": [
{
"enum": [
"background",
"default",
"foreground"
]
},
{
"type": "integer"
}
]
},
"selectable": {
"$ref": "#/$defs/BBool"
},
"deletable": {
"$ref": "#/$defs/BBool"
},
"copyable": {
"$ref": "#/$defs/BBool"
},
"connectable": {
"$ref": "#/$defs/BBool"
},
"hitPaddingScreenPx": {
"type": "number"
},
"doubleClick": {
"type": "string"
},
"drillDown": {
"type": "object",
"properties": {
"viewpoint": {
"type": "string"
},
"filter": {
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"accessibility": {
"type": "object",
"properties": {
"role": {
"type": "string"
},
"name": {
"$ref": "#/$defs/BString"
},
"description": {
"$ref": "#/$defs/BString"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"refusals": {
"description": "The sentences shown when a gesture on an element of this kind is switched off, per gesture. See DISL 0.2, section 6.9.",
"$ref": "#/$defs/GestureRefusals"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"when"
],
"patternProperties": {
"^x-": true
}
}A custom marker a specification declares in the notation layer's markers map, or inline where a marker is referenced. Its geometry is a path or a set of composite parts in marker coordinates, with x pointing along the path towards the end and the tip at the reference point ref, which defaults to 0,0. size gives the nominal size, orient defaults to auto with source markers reversed automatically, and fill, stroke and shorten control drawing. See section 6.11.
{
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/LocalizedText"
},
"path": {
"$ref": "#/$defs/PathDef"
},
"parts": {
"type": "array",
"items": {
"$ref": "#/$defs/ShapePart"
}
},
"ref": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
},
"size": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2
},
"params": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/ShapeParam"
}
},
"orient": {
"anyOf": [
{
"enum": [
"auto",
"auto-start-reverse"
]
},
{
"type": "number"
}
]
},
"fill": {
"$ref": "#/$defs/Paint"
},
"stroke": {
"$ref": "#/$defs/Stroke"
},
"shorten": {
"$ref": "#/$defs/GeomExpr"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"anyOf": [
{
"required": [
"path"
]
},
{
"required": [
"parts"
]
}
]
}A marker reference that names a marker and adjusts it, used wherever a marker is expected. type is required and names a built-in or custom marker, and params sets marker parameters such as length, width, angle, fill or inset. With type stack it composes several markers, listed in markers, from the edge end inward with the given spacing, for example a bar followed by a crow's foot. See section 6.11.
{
"type": "object",
"properties": {
"type": {
"type": "string"
},
"params": {
"type": "object"
},
"markers": {
"type": "array",
"items": {
"$ref": "#/$defs/MarkerRef"
}
},
"spacing": {
"type": "number"
}
},
"additionalProperties": false,
"required": [
"type"
],
"patternProperties": {
"^x-": true
}
}A reference to the decoration drawn at an edge end or along an edge, used by an edge notation's source and target markers and by mid markers. It is a string naming a built-in or custom marker (none draws nothing), a marker instance with type and parameters or a stack, an inline marker declaration, or a CEL expression that returns a marker name from model data. See section 6.11.
{
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/MarkerInstance"
},
{
"$ref": "#/$defs/MarkerDef"
},
{
"$ref": "#/$defs/CelValue"
}
]
}A decoration drawn along an edge's path rather than at its ends, listed in an edge notation's midMarkers. marker, which is required, is the decoration; at places it at start, middle (the default), end or a fraction of the path length, and repeat instead repeats it every spacing canvas units within an optional from and to range. orient sets its rotation relative to the path tangent and visible can hide it conditionally. See section 6.10.
{
"type": "object",
"properties": {
"marker": {
"$ref": "#/$defs/MarkerRef"
},
"at": {
"anyOf": [
{
"enum": [
"start",
"middle",
"end"
]
},
{
"type": "number",
"minimum": 0,
"maximum": 1
}
]
},
"repeat": {
"type": "object",
"properties": {
"spacing": {
"type": "number"
},
"from": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"to": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"additionalProperties": false,
"required": [
"spacing"
],
"patternProperties": {
"^x-": true
}
},
"orient": {
"anyOf": [
{
"enum": [
"auto",
"auto-reverse"
]
},
{
"type": "number"
}
]
},
"visible": {
"$ref": "#/$defs/BBool"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"marker"
],
"patternProperties": {
"^x-": true
}
}How an edge's line is routed between its ends, set by a line spec's routing property. It is one of straight (the default), polyline, orthogonal, rounded, curved, bezier, spline, arc, tree, metro (octilinear) or layout (taken from the layout algorithm), or an object that hands routing to a plugin. See section 6.10.
{
"anyOf": [
{
"enum": [
"straight",
"polyline",
"orthogonal",
"rounded",
"curved",
"bezier",
"spline",
"arc",
"tree",
"metro",
"layout"
]
},
{
"$ref": "#/$defs/PluginUse"
}
]
}The stroke, routing and geometry of an edge's line, set by an edge notation's line property. stroke takes everything a stroke can express, routing picks the routing algorithm, and cornerRadius and curvature shape corners and curves. avoidNodes and avoidPadding route around other nodes, bendpoints and segments govern user editing, minSegmentLength keeps markers off corners, and startDirection and endDirection set how the line leaves and enters its nodes. See section 6.10.
{
"type": "object",
"properties": {
"stroke": {
"$ref": "#/$defs/Stroke"
},
"routing": {
"$ref": "#/$defs/Routing"
},
"cornerRadius": {
"type": "number"
},
"curvature": {
"type": "number"
},
"avoidNodes": {
"type": "boolean"
},
"avoidPadding": {
"type": "number"
},
"bendpoints": {
"type": "object",
"properties": {
"editable": {
"type": "boolean"
},
"max": {
"type": "integer"
},
"addOnDrag": {
"type": "boolean"
},
"removeOnStraighten": {
"type": "boolean"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"segments": {
"type": "object",
"properties": {
"editable": {
"type": "boolean"
},
"keepOrthogonal": {
"type": "boolean"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"minSegmentLength": {
"type": "number"
},
"startDirection": {
"enum": [
"auto",
"up",
"down",
"left",
"right",
"normal"
]
},
"endDirection": {
"enum": [
"auto",
"up",
"down",
"left",
"right",
"normal"
]
},
"bezier": {
"description": "The control points of a bezier route. See DISL 0.2, section 6.10.",
"$ref": "#/$defs/BezierSpec"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}How one end of an edge attaches to its node, set for the source or target in an edge notation's anchoring property; it overrides the node's anchor spec for this edge type. mode is outline, center, port, fixed or sides as for anchors, points lists fixed anchor points as fractions of the bounds, and gap leaves space between the node outline and the marker. See section 6.10.
{
"type": "object",
"properties": {
"mode": {
"enum": [
"outline",
"center",
"port",
"fixed",
"sides",
"part"
],
"description": "How the end attaches; part (DISL 0.2) attaches it at a point on a side of a named shape part, given by part, side and at. See DISL 0.2, section 6.10."
},
"gap": {
"type": "number"
},
"sides": {
"type": "array",
"items": {
"enum": [
"top",
"right",
"bottom",
"left"
]
},
"minItems": 1,
"uniqueItems": true,
"description": "The sides of the end node this end may attach to; defaults to all four. See DISL 0.2, section 6.10."
},
"points": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"x": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"y": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"additionalProperties": false,
"required": [
"x",
"y"
],
"patternProperties": {
"^x-": true
}
}
},
"part": {
"description": "With mode part: the id of a shape part of the end node's shape, usually bound to an attribute. See DISL 0.2, section 6.10.",
"$ref": "#/$defs/BString"
},
"side": {
"anyOf": [
{
"enum": [
"top",
"right",
"bottom",
"left"
]
},
{
"$ref": "#/$defs/Dynamic"
}
],
"description": "With mode part: the side of the part's box; bindable. See DISL 0.2, section 6.10."
},
"at": {
"description": "With mode part: the position along that side from its start (left or top), a fraction from 0 to 1; bindable. See DISL 0.2, section 6.10.",
"$ref": "#/$defs/BNumber"
},
"movable": {
"type": "boolean",
"description": "Whether the user may drag the end along the node's parts and sides, writing the bound attributes; defaults to true when part, side and at are all attribute bindings. See DISL 0.2, section 6.10."
},
"default": {
"description": "The values written when a connect gesture does not determine them. See DISL 0.2, section 6.10.",
"type": "object",
"properties": {
"part": {
"$ref": "#/$defs/BString",
"description": "The shape part written by default. See DISL 0.2, section 6.10."
},
"side": {
"anyOf": [
{
"enum": [
"top",
"right",
"bottom",
"left"
]
},
{
"$ref": "#/$defs/Dynamic"
}
],
"description": "The side written by default. See DISL 0.2, section 6.10."
},
"at": {
"$ref": "#/$defs/BNumber",
"description": "The position along the side written by default. See DISL 0.2, section 6.10."
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}How one relation type, or a reference attribute drawn as an edge, is rendered; the notation layer's edges map holds one per name. line sets stroke and routing, source and target markers decorate the ends (by default none at the source and a filled arrow at the target for directed relations), and midMarkers and labels decorate the path. Further properties control anchoring, self loops, parallel edges, jumps at crossings, layer, states, conditions, variants and reconnecting. See section 6.10.
{
"type": "object",
"properties": {
"line": {
"$ref": "#/$defs/LineSpec"
},
"style": {
"$ref": "#/$defs/StyleRefs"
},
"sourceMarker": {
"$ref": "#/$defs/MarkerRef"
},
"targetMarker": {
"$ref": "#/$defs/MarkerRef"
},
"midMarkers": {
"type": "array",
"items": {
"$ref": "#/$defs/MidMarker"
}
},
"stub": {
"description": "How a relation of this type without a target is drawn. See DISL 0.2, section 6.10.",
"$ref": "#/$defs/Stub"
},
"labels": {
"type": "array",
"items": {
"$ref": "#/$defs/Label"
}
},
"anchoring": {
"type": "object",
"properties": {
"source": {
"$ref": "#/$defs/EndAnchor"
},
"target": {
"$ref": "#/$defs/EndAnchor"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"selfLoop": {
"type": "object",
"properties": {
"shape": {
"enum": [
"arc",
"rect",
"circle"
]
},
"size": {
"type": "number"
},
"side": {
"enum": [
"top",
"right",
"bottom",
"left",
"auto"
]
},
"spread": {
"type": "number"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"parallel": {
"type": "object",
"properties": {
"spread": {
"type": "number"
},
"mode": {
"enum": [
"offset",
"curve",
"bundle"
]
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"jumps": {
"type": "object",
"properties": {
"style": {
"enum": [
"none",
"arc",
"gap",
"square",
"sharp"
]
},
"size": {
"type": "number"
},
"over": {
"enum": [
"later",
"horizontal",
"all"
]
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"snapping": {
"$ref": "#/$defs/SnappingRef"
},
"hitWidthScreenPx": {
"type": "number"
},
"layer": {
"anyOf": [
{
"enum": [
"belowNodes",
"aboveNodes"
]
},
{
"type": "integer"
}
]
},
"states": {
"$ref": "#/$defs/States"
},
"conditions": {
"$ref": "#/$defs/Conditions"
},
"variants": {
"type": "array",
"items": {
"$ref": "#/$defs/EdgeVariant"
}
},
"tooltip": {
"$ref": "#/$defs/Message"
},
"selectable": {
"$ref": "#/$defs/BBool"
},
"deletable": {
"$ref": "#/$defs/BBool"
},
"reconnectable": {
"$ref": "#/$defs/BBool"
},
"accessibility": {
"type": "object",
"properties": {
"role": {
"type": "string"
},
"name": {
"$ref": "#/$defs/BString"
},
"description": {
"$ref": "#/$defs/BString"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"refusals": {
"description": "The sentences shown when a gesture on an element of this kind is switched off, per gesture. See DISL 0.2, section 6.10.",
"$ref": "#/$defs/GestureRefusals"
},
"connect": {
"description": "How connect gestures of this relation type start and which end the dragged-from node becomes. See DISL 0.2, section 6.10.",
"$ref": "#/$defs/ConnectGesture"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A conditional alternative to parts of an edge notation, listed in its variants property. Its when expression decides whether it applies, and it may carry the edge notation's properties, such as a different line, markers or labels. Variants work as they do for nodes, applied over the base notation when they match. See section 6.10.
{
"type": "object",
"properties": {
"when": {
"$ref": "#/$defs/Expression"
},
"line": {
"$ref": "#/$defs/LineSpec"
},
"style": {
"$ref": "#/$defs/StyleRefs"
},
"sourceMarker": {
"$ref": "#/$defs/MarkerRef"
},
"targetMarker": {
"$ref": "#/$defs/MarkerRef"
},
"midMarkers": {
"type": "array",
"items": {
"$ref": "#/$defs/MidMarker"
}
},
"stub": {
"description": "How a relation of this type without a target is drawn. See DISL 0.2, section 6.10.",
"$ref": "#/$defs/Stub"
},
"labels": {
"type": "array",
"items": {
"$ref": "#/$defs/Label"
}
},
"anchoring": {
"type": "object",
"properties": {
"source": {
"$ref": "#/$defs/EndAnchor"
},
"target": {
"$ref": "#/$defs/EndAnchor"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"selfLoop": {
"type": "object",
"properties": {
"shape": {
"enum": [
"arc",
"rect",
"circle"
]
},
"size": {
"type": "number"
},
"side": {
"enum": [
"top",
"right",
"bottom",
"left",
"auto"
]
},
"spread": {
"type": "number"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"parallel": {
"type": "object",
"properties": {
"spread": {
"type": "number"
},
"mode": {
"enum": [
"offset",
"curve",
"bundle"
]
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"jumps": {
"type": "object",
"properties": {
"style": {
"enum": [
"none",
"arc",
"gap",
"square",
"sharp"
]
},
"size": {
"type": "number"
},
"over": {
"enum": [
"later",
"horizontal",
"all"
]
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"snapping": {
"$ref": "#/$defs/SnappingRef"
},
"hitWidthScreenPx": {
"type": "number"
},
"layer": {
"anyOf": [
{
"enum": [
"belowNodes",
"aboveNodes"
]
},
{
"type": "integer"
}
]
},
"states": {
"$ref": "#/$defs/States"
},
"conditions": {
"$ref": "#/$defs/Conditions"
},
"tooltip": {
"$ref": "#/$defs/Message"
},
"selectable": {
"$ref": "#/$defs/BBool"
},
"deletable": {
"$ref": "#/$defs/BBool"
},
"reconnectable": {
"$ref": "#/$defs/BBool"
},
"accessibility": {
"type": "object",
"properties": {
"role": {
"type": "string"
},
"name": {
"$ref": "#/$defs/BString"
},
"description": {
"$ref": "#/$defs/BString"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"refusals": {
"description": "The sentences shown when a gesture on an element of this kind is switched off, per gesture. See DISL 0.2, section 6.10.",
"$ref": "#/$defs/GestureRefusals"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"when"
],
"patternProperties": {
"^x-": true
}
}The drawing surface's configuration, set by the notation layer's canvas property or by a viewpoint's own canvas. It gives the background paint (by default the canvas colour token), an optional paged layout for printing, fixed bounds, zoom limits and presets, a watermark label drawn under everything, an auto-generated legend, a minimap and the look of the selection outline and resize handles. DISL 0.2 adds the chrome outside the drawing surface: title, header, notices, filters, the empty message, stretching, an initial fit and a legend computed from what is drawn. See section 6.13.
{
"type": "object",
"properties": {
"background": {
"$ref": "#/$defs/Paint"
},
"page": {
"type": "object",
"properties": {
"size": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/Size"
}
]
},
"orientation": {
"enum": [
"portrait",
"landscape"
]
},
"margins": {
"$ref": "#/$defs/Insets"
},
"showBreaks": {
"type": "boolean"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"bounds": {
"$ref": "#/$defs/Box"
},
"zoom": {
"type": "object",
"properties": {
"min": {
"type": "number"
},
"max": {
"type": "number"
},
"default": {
"type": "number"
},
"steps": {
"type": "array",
"items": {
"type": "number"
}
},
"initial": {
"anyOf": [
{
"type": "number"
},
{
"const": "fit"
}
],
"description": "The zoom a viewer starts with: a number, or fit, which fits zoom and pan once per viewer and view and never refits on model changes; defaults to default. See DISL 0.2, section 6.13."
},
"fitPadding": {
"type": "number",
"minimum": 0,
"description": "The space kept on each side when fitting, as a fraction of the content extent; defaults to 0.05. See DISL 0.2, section 6.13."
},
"fitWhen": {
"enum": [
"open",
"firstContent"
],
"description": "Fit when the view opens, or the first time it has content (the default). See DISL 0.2, section 6.13."
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"watermark": {
"$ref": "#/$defs/Label"
},
"legend": {
"type": "object",
"properties": {
"visible": {
"type": "boolean"
},
"position": {
"$ref": "#/$defs/Position"
},
"entries": {
"type": "array",
"items": {
"type": "string"
}
},
"title": {
"description": "The legend's heading. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/Message"
},
"from": {
"enum": [
"declared",
"drawn"
],
"description": "declared (the default, 0.1) shows every entry; drawn shows an entry only while an element in diagram.drawn matches it. See DISL 0.2, section 6.13."
},
"computed": {
"description": "Entries computed from the drawn elements. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/LegendComputed"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"minimap": {
"type": "boolean"
},
"selection": {
"type": "object",
"properties": {
"style": {
"$ref": "#/$defs/StyleRef"
},
"handles": {
"$ref": "#/$defs/StyleRef"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"title": {
"description": "The title drawn above the drawing surface, outside it, with self bound to the diagram; never zoomed, panned or selected. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/Label"
},
"header": {
"description": "A band of rows between the title and the drawing surface. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/ChromeBand"
},
"notices": {
"type": "array",
"items": {
"$ref": "#/$defs/Notice"
},
"description": "Status notices outside the drawing surface. See DISL 0.2, section 6.13."
},
"filters": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Filter"
},
"description": "User filters by id, whose values are viewer state. See DISL 0.2, section 6.13.1."
},
"empty": {
"description": "The message shown on an empty canvas. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/EmptyMessage"
},
"fit": {
"enum": [
"none",
"stretch"
],
"description": "none (the default) or stretch: scale x and y independently so that bounds, which must be set, fills the pane minus margin; node sizes, strokes and fonts are not stretched. See DISL 0.2, section 6.13."
},
"margin": {
"description": "The space kept around the stretched bounds; defaults to 0. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/Insets"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}4 · Toolbox and forms
The palette from which users create elements, declared in a specification's toolbox property. It holds ordered tool groups, a library of tools that groups may reference by id, context tools and context menus, templates and starter templates, plus presentation settings such as layout (default list), searchable (default true) and which generic tools are offered (select and pan by default). If the toolbox is absent, the runtime generates one creation tool per concrete node and relation type. See section 7.1.
{
"type": "object",
"properties": {
"groups": {
"type": "array",
"items": {
"$ref": "#/$defs/ToolGroup"
}
},
"tools": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Tool"
}
},
"layout": {
"enum": [
"list",
"grid",
"icons",
"compact"
]
},
"position": {
"enum": [
"left",
"right",
"top",
"floating"
]
},
"searchable": {
"type": "boolean"
},
"showRecent": {
"type": "integer"
},
"generic": {
"type": "object",
"properties": {
"select": {
"type": "boolean"
},
"pan": {
"type": "boolean"
},
"lasso": {
"type": "boolean"
},
"text": {
"type": "boolean"
},
"note": {
"type": "boolean"
},
"image": {
"type": "boolean"
},
"freehand": {
"type": "boolean"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"contextTools": {
"type": "array",
"items": {
"$ref": "#/$defs/ContextToolSet"
}
},
"contextMenus": {
"type": "array",
"items": {
"$ref": "#/$defs/ContextToolSet"
}
},
"templates": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Template"
}
},
"starters": {
"type": "array",
"items": {
"type": "string"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A named group of tools in the toolbox palette, used in the toolbox groups list. It has a required id, a label and icon, and lists its tools either inline or by the id of a tool in the toolbox library; nested groups give sub-groups. It can start collapsed, be limited to certain viewpoints, and be shown or hidden by a visible expression evaluated in the diagram context. See section 7.1.
{
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"collapsed": {
"type": "boolean"
},
"visible": {
"$ref": "#/$defs/Expression"
},
"viewpoints": {
"type": "array",
"items": {
"type": "string"
}
},
"tools": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/Tool"
}
]
}
},
"groups": {
"type": "array",
"items": {
"$ref": "#/$defs/ToolGroup"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"id"
],
"patternProperties": {
"^x-": true
}
}One entry in the toolbox, used in tool groups and the toolbox library. Its kind says what it does: create a node or edge (the default, inferred from the type it creates), insert a template, run an operation, a generic tool such as select or pan, or a plugin. Further properties set initial attribute values and size, the interaction mode, a shortcut, whether it stays active, and what happens after creation (by default label editing). DISL 0.2 adds a drop table (mode drop), unavailable reasons, and a CreateEnd for the ends a create-edge tool creates. See section 7.2.
{
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"kind": {
"enum": [
"create-node",
"create-edge",
"template",
"operation",
"select",
"pan",
"lasso",
"text",
"note",
"image",
"freehand",
"plugin"
]
},
"label": {
"description": "The palette text, a Message in the element context with self bound to the diagram; defaults to the created type's label. See DISL 0.2, section 7.2.",
"$ref": "#/$defs/Message"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"creates": {
"$ref": "#/$defs/TypeRef"
},
"initial": {
"type": "object"
},
"size": {
"$ref": "#/$defs/Size"
},
"variantOf": {
"type": "string"
},
"mode": {
"enum": [
"click",
"drag",
"stamp",
"click-click",
"chain",
"auto",
"drop"
]
},
"sticky": {
"type": "boolean"
},
"shortcut": {
"type": "string"
},
"enabled": {
"$ref": "#/$defs/Expression"
},
"visible": {
"$ref": "#/$defs/Expression"
},
"unavailable": {
"description": "Why the tool cannot be used now, in priority order, in the element context with self bound to the diagram; while one applies the tool is shown disabled with that reason and refused. A tool of kind operation also inherits its operation's reasons. See DISL 0.2, section 7.2.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"preview": {
"type": "object",
"properties": {
"style": {
"$ref": "#/$defs/StyleRef"
},
"shape": {
"$ref": "#/$defs/ShapeRef"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"after": {
"enum": [
"select",
"editLabel",
"openForm",
"none"
]
},
"template": {
"type": "string"
},
"operation": {
"type": "string"
},
"plugin": {
"$ref": "#/$defs/PluginCall"
},
"drop": {
"description": "What a drop (or click) of this tool does, depending on the element under the drop point. See DISL 0.2, section 7.2.",
"$ref": "#/$defs/DropSpec"
},
"createSource": {
"description": "The node created as the source when a connect gesture ends on empty canvas: a type (0.1) or a CreateEnd. See DISL 0.2, section 7.2.",
"anyOf": [
{
"$ref": "#/$defs/TypeRef"
},
{
"$ref": "#/$defs/CreateEnd"
}
]
},
"createTarget": {
"description": "The node created as the target when a connect gesture ends on empty canvas: a type (0.1), a CreateEnd, or ask. See DISL 0.2, section 7.2.",
"anyOf": [
{
"$ref": "#/$defs/TypeRef"
},
{
"$ref": "#/$defs/CreateEnd"
},
{
"const": "ask"
}
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"id"
],
"patternProperties": {
"^x-": true
}
}A set of context tools shown next to a selected element, declared in the toolbox under contextTools, or under contextMenus for right-click menus. Its for property names the element types it applies to and when adds a condition in the element context; placement chooses around, toolbar, menu or radial presentation. For context menus the runtime adds standard entries such as cut, copy and paste unless standardEntries is false. See section 7.3.
{
"type": "object",
"properties": {
"for": {
"description": "The element types the set applies to; the keyword diagram opens it on empty canvas (entries see position), and connection on a pending connection (entries see source, target, sourceAnchor and position). See DISL 0.2, section 7.3.",
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/$defs/TypeRef"
},
{
"enum": [
"diagram",
"connection"
]
}
]
}
},
"when": {
"$ref": "#/$defs/Expression"
},
"placement": {
"enum": [
"around",
"toolbar",
"menu",
"radial"
]
},
"tools": {
"type": "array",
"items": {
"$ref": "#/$defs/ContextTool"
}
},
"standardEntries": {
"type": "boolean"
},
"runSingle": {
"type": "boolean",
"description": "When exactly one entry is available, run it without showing the menu; defaults to false. See DISL 0.2, section 7.3."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"tools"
],
"patternProperties": {
"^x-": true
}
}One item of a context tool set, shown beside the selected element as the fastest way to grow a diagram. Its required kind is one of create-connected (a new node linked through the relation type in via, outgoing or incoming), connect, create-child (in a slot), operation, delete, duplicate, editLabel, openForm or plugin. Every kind accepts a label, icon, shortcut, enabled condition and position relative to the element. DISL 0.2 adds moveUp and moveDown, visible and unavailable, a picker of existing elements (target pick), and one entry per list item (forEach); DISL 0.3 adds the menu group an entry is shown in (group); DISL 0.4 adds the standard entries pin, unpin and unpinAll. See section 7.3.
{
"type": "object",
"properties": {
"kind": {
"enum": [
"create-connected",
"connect",
"create-child",
"operation",
"delete",
"duplicate",
"editLabel",
"openForm",
"plugin",
"moveUp",
"moveDown",
"pin",
"unpin",
"unpinAll"
]
},
"creates": {
"$ref": "#/$defs/TypeRef"
},
"via": {
"$ref": "#/$defs/TypeRef"
},
"direction": {
"enum": [
"outgoing",
"incoming"
]
},
"slot": {
"type": "string"
},
"operation": {
"type": "string"
},
"plugin": {
"$ref": "#/$defs/PluginCall"
},
"label": {
"description": "The entry's label, a Message evaluated for the element it is shown on (and item and index inside forEach) each time it is presented. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Message"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"shortcut": {
"type": "string"
},
"enabled": {
"$ref": "#/$defs/Expression"
},
"visible": {
"description": "Whether the entry is offered at all; an entry that is not visible is not shown, while an unavailable one is shown disabled. Element context. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Expression"
},
"unavailable": {
"description": "Reasons that, while one applies, show the entry disabled with that reason and refuse it; an entry that runs an operation also inherits the operation's. Element context. See DISL 0.2, section 7.3.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"position": {
"$ref": "#/$defs/Position"
},
"target": {
"enum": [
"drag",
"pick",
"either"
],
"description": "How the other end of a connect or create-connected entry is chosen: drag (the default and the 0.1 behaviour), pick from a list of candidates, or either. See DISL 0.2, section 7.3."
},
"candidates": {
"description": "The elements a picker offers, a list in the element context; defaults to every element the relation's ends and prevent-constraints admit. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Expression"
},
"candidateLabel": {
"description": "The text of each picker row, with item bound; defaults to item.label(). See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Message"
},
"pickerTitle": {
"description": "The picker's title; defaults to the entry's label. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Message"
},
"emptyText": {
"description": "Shown when there are no candidates, as the reason the entry is unavailable. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Message"
},
"forEach": {
"description": "A list; the entry is produced once per item, in list order, with item (or the as name) and index bound in its label, visible, enabled, unavailable, args and icon. An empty list produces no entry. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Expression"
},
"as": {
"description": "The name item is bound as inside forEach; defaults to item. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/SimpleId"
},
"args": {
"description": "Values of the invoked operation's parameters, from parameter name to Expression; when they give every required parameter, no parameter dialog opens. See DISL 0.2, section 7.3.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
},
"submenu": {
"description": "Groups the entries generated by forEach under one submenu with this label. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Message"
},
"group": {
"description": "The menu group the entry is shown in: consecutive entries of one set with an equal group, or with none, form one group, decided by the entries as declared; a runtime shows the groups in order and sets them apart. The name is not shown. See DISL 0.3, section 7.3.",
"$ref": "#/$defs/SimpleId"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"kind"
],
"patternProperties": {
"^x-": true
}
}A reusable pre-built fragment, such as a pattern or starter structure, declared by name in the toolbox templates map. Its required fragment lists nodes and relations that refer to each other by local ref names rather than ids; attribute values are expressions evaluated with the template parameters, declared in params, available as p. Templates are placed with a template tool, dragged from a gallery, or offered as starters for a new diagram. See section 7.4.
{
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/LocalizedText"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"params": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Attribute"
}
},
"fragment": {
"type": "object",
"properties": {
"nodes": {
"type": "array",
"items": {
"$ref": "#/$defs/FragmentNode"
}
},
"relations": {
"type": "array",
"items": {
"$ref": "#/$defs/FragmentRelation"
}
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"preview": {
"type": "string"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"fragment"
],
"patternProperties": {
"^x-": true
}
}A node to be created when a template is inserted, listed in the template fragment nodes. It needs a local ref name, used by other fragment entries in place of an id, and a type; attribute values are expressions evaluated with the template parameters as p. Its at position is relative to the insertion point, in the coordinate system of the target container, with durations relative to the drop time on time axes. See section 7.4.
{
"type": "object",
"properties": {
"ref": {
"$ref": "#/$defs/SimpleId"
},
"type": {
"$ref": "#/$defs/TypeRef"
},
"attributes": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
},
"parent": {
"type": "string"
},
"slot": {
"type": "string"
},
"at": true,
"size": true
},
"additionalProperties": false,
"required": [
"ref",
"type"
],
"patternProperties": {
"^x-": true
}
}A relation to be created when a template is inserted, listed in the template fragment relations. It has a required type and a source and target that name nodes of the same fragment by their local ref names. Its attribute values are expressions, evaluated with the template parameters available as p. See section 7.4.
{
"type": "object",
"properties": {
"ref": {
"$ref": "#/$defs/SimpleId"
},
"type": {
"$ref": "#/$defs/TypeRef"
},
"source": {
"type": "string"
},
"target": {
"type": "string"
},
"attributes": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
}
},
"additionalProperties": false,
"required": [
"type",
"source",
"target"
],
"patternProperties": {
"^x-": true
}
}A declarative description of editable fields for one or more element types, or for the diagram root, declared by id in the specification's forms. Its usage says where it appears: property inspector (the default), creation dialog, embedded in nodes, popover or bulk editing. It lays out an ordered list of form items and says when edits commit, by default immediately for inspectors and explicitly for create dialogs. Types without a form get a generated one. See section 7.5.
{
"type": "object",
"properties": {
"for": {
"anyOf": [
{
"$ref": "#/$defs/TypeRefs"
},
{
"const": "diagram"
}
]
},
"usage": {
"type": "array",
"items": {
"enum": [
"inspector",
"create",
"embedded",
"popover",
"bulk"
]
}
},
"layout": {
"anyOf": [
{
"enum": [
"vertical",
"horizontal"
]
},
{
"type": "object",
"properties": {
"columns": {
"type": "integer"
},
"labelPosition": {
"enum": [
"top",
"left",
"inline",
"none"
]
},
"density": {
"enum": [
"comfortable",
"compact"
]
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
},
"items": {
"type": "array",
"items": {
"$ref": "#/$defs/FormItem"
}
},
"commit": {
"enum": [
"immediate",
"onBlur",
"explicit"
]
},
"label": {
"description": "The title of the form or dialog, a Message in the form context with self bound to the target. See DISL 0.2, section 7.5.",
"$ref": "#/$defs/Message"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"submitLabel": {
"description": "The label of the dialog's confirming button. See DISL 0.2, section 7.5.",
"$ref": "#/$defs/Message"
},
"cancelLabel": {
"description": "The label of the dialog's cancelling button. See DISL 0.2, section 7.5.",
"$ref": "#/$defs/Message"
},
"danger": {
"type": "boolean",
"description": "Whether the confirming button is styled as destructive; defaults to false. See DISL 0.2, section 7.5."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"items"
],
"patternProperties": {
"^x-": true
}
}One item in a form: either a field that edits an attribute, or a container or other item chosen by its kind. A field names its attribute path and optionally a widget (defaulting by attribute type), label, placeholder, options, field-local validation and actions run on change. Other kinds are section, row, tabs, group, static text, divider, a computed read-only value, a button running an operation or actions, a findings list (problems is its deprecated alias) and plugin. See section 7.5.
{
"type": "object",
"properties": {
"kind": {
"enum": [
"field",
"section",
"row",
"tabs",
"group",
"text",
"divider",
"computed",
"button",
"type",
"findings",
"problems",
"plugin"
],
"description": "What the item is. findings lists the findings on the form's target; problems is its deprecated alias (section 18), read and never written. type (DISL 0.3) shows and changes the element's type through behavior.retype, its choices options as given, the element's own type among them. See DISL 0.3, section 7.5."
},
"id": {
"description": "The row id of a field, computed item or type item, by which a host addresses the row; without it the row id is the attribute, else the label as evaluated. It changes nothing the row shows, edits or refuses. See DISL 0.3, section 7.5.",
"$ref": "#/$defs/SimpleId"
},
"attribute": {
"type": "string"
},
"widget": {
"enum": [
"text",
"textarea",
"markdown",
"code",
"number",
"slider",
"spinner",
"rating",
"checkbox",
"switch",
"select",
"combobox",
"radio",
"segmented",
"multiselect",
"tags",
"date",
"datetime",
"time",
"duration",
"daterange",
"color",
"icon",
"reference",
"references",
"list",
"table",
"struct",
"file",
"image",
"link",
"progress",
"readonly",
"plugin"
]
},
"label": {
"description": "The item's label, a Message evaluated in the form context for the edited element. See DISL 0.2, section 7.5.",
"$ref": "#/$defs/Message"
},
"placeholder": {
"description": "The hint shown in an empty input, a Message evaluated in the form context. See DISL 0.2, section 7.5.",
"$ref": "#/$defs/Message"
},
"visible": {
"$ref": "#/$defs/Expression"
},
"enabled": {
"$ref": "#/$defs/Expression"
},
"required": {
"type": "boolean"
},
"validate": {
"type": "array",
"items": {
"$ref": "#/$defs/FieldValidation"
}
},
"options": {
"anyOf": [
{
"type": "array",
"items": true
},
{
"$ref": "#/$defs/CelValue"
},
{
"type": "object",
"properties": {
"enum": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"enum"
],
"patternProperties": {
"^x-": true
}
}
]
},
"widgetOptions": {
"type": "object"
},
"colSpan": {
"type": "integer"
},
"width": {
"$ref": "#/$defs/Length"
},
"prefix": {
"$ref": "#/$defs/LocalizedText"
},
"suffix": {
"$ref": "#/$defs/LocalizedText"
},
"unit": {
"$ref": "#/$defs/LocalizedText"
},
"format": {
"type": "string"
},
"rows": {
"type": "integer"
},
"display": {
"description": "The text an attribute item shows for its value, in place of the widget's rendering of it; a Message in the form context. See DISL 0.3, section 7.5.",
"$ref": "#/$defs/Message"
},
"parse": {
"description": "Makes an attribute or computed item editable as text: what it accepts, what it writes and how it refuses. See DISL 0.3, section 7.5.",
"$ref": "#/$defs/FieldParse"
},
"optionLabel": {
"description": "For a type item: the label of a choice, with item bound to the type. See DISL 0.3, section 7.5.",
"$ref": "#/$defs/Expression"
},
"refusals": {
"description": "For a type item: the reasons a value outside the choices is refused, the first that applies shown; self and newValue (the chosen type) are bound. See DISL 0.3, section 7.5.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"readOnly": {
"$ref": "#/$defs/BBool"
},
"onChange": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"title": {
"description": "The title of a section, group or tab, a Message evaluated in the form context. See DISL 0.2, section 7.5.",
"$ref": "#/$defs/Message"
},
"collapsible": {
"type": "boolean"
},
"collapsed": {
"type": "boolean"
},
"items": {
"type": "array",
"items": {
"$ref": "#/$defs/FormItem"
}
},
"tabs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"title": {
"$ref": "#/$defs/LocalizedText"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"items": {
"type": "array",
"items": {
"$ref": "#/$defs/FormItem"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"items"
],
"patternProperties": {
"^x-": true
}
}
},
"text": {
"$ref": "#/$defs/LocalizedText"
},
"value": {
"$ref": "#/$defs/BString"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"operation": {
"type": "string"
},
"actions": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"confirm": {
"description": "The confirmation asked before this runs: a Message (the 0.1 form, which asks every time) or a Confirmation. See DISL 0.2, section 9.5.",
"anyOf": [
{
"$ref": "#/$defs/Message"
},
{
"$ref": "#/$defs/Confirmation"
}
]
},
"readOnlyReasons": {
"description": "Why the field is read-only, in priority order, before the attribute's reasons and the edit gate. Form context. See DISL 0.2, section 7.5.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"absentText": {
"description": "Shown in the field when the attribute is absent; overrides the attribute's. See DISL 0.2, section 7.5.",
"$ref": "#/$defs/Message"
},
"emptyText": {
"description": "Shown in the field when the attribute's value is empty; overrides the attribute's. See DISL 0.2, section 7.5.",
"$ref": "#/$defs/Message"
},
"showAbsent": {
"type": "boolean",
"description": "Whether the row is shown while the value is absent; defaults to true. See DISL 0.2, section 7.5."
},
"initial": {
"description": "The value the field is pre-filled with when a dialog opens, evaluated once in the form context (the create context for a create form), with position when invoked at a point. See DISL 0.2, section 7.5.",
"$ref": "#/$defs/Expression"
},
"unavailable": {
"description": "For a button: reasons that, while one applies, show the button disabled with that reason and refuse it. See DISL 0.2, section 7.5.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"plugin": {
"$ref": "#/$defs/PluginCall"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"anyOf": [
{
"required": [
"attribute"
]
},
{
"required": [
"kind"
]
}
]
}A field-local validation rule attached to a form field in its validate list. Its rule is an expression over the entered value, and its message is shown immediately when the rule fails, with a severity of error, warning or info. It gives quick feedback in the form but does not replace the specification's constraints. See section 7.5.
{
"type": "object",
"properties": {
"rule": {
"$ref": "#/$defs/Expression"
},
"message": {
"$ref": "#/$defs/Message"
},
"severity": {
"enum": [
"error",
"warning",
"info"
]
},
"timing": {
"enum": [
"input",
"commit"
],
"description": "When the rule is checked: input, as the value is entered (the default and the 0.1 behaviour), or commit, when the dialog is submitted. See DISL 0.2, section 7.5."
}
},
"additionalProperties": false,
"required": [
"rule",
"message"
],
"patternProperties": {
"^x-": true
}
}5 · Constraints
The container for a specification's validity rules, declared in its constraints property. It holds the ordered list of constraint rules, named groups that users can enable, disable or re-rate as a unit, default severity and timing for rules, settings that tune the built-in constraints and, in DISL 0.3, the order of the codes findings are listed in. Its blockSaveOn setting defaults to never, so diagrams with problems are still saved and remain loadable. See section 8.1.
{
"type": "object",
"properties": {
"rules": {
"type": "array",
"items": {
"$ref": "#/$defs/Constraint"
}
},
"groups": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/LocalizedText"
},
"enabledByDefault": {
"type": "boolean"
},
"severityOverride": {
"enum": [
"error",
"warning",
"info",
"hint"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"defaults": {
"type": "object",
"properties": {
"severity": {
"enum": [
"error",
"warning",
"info",
"hint"
]
},
"timing": {
"type": "array",
"items": {
"enum": [
"live",
"save",
"explicit",
"export"
]
}
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"blockSaveOn": {
"enum": [
"never",
"error"
]
},
"builtIn": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/BuiltInSetting"
}
},
"order": {
"description": "The codes in the order findings are listed: by the position of a finding's code here, unlisted codes last; then the reader's findings in reading order; then by the line of the finding's element, a group of duplicates by its first member. Without it, or empty, findings keep the order of section 8.6. See DISL 0.3, sections 8.1 and 8.6.",
"type": "array",
"items": {
"$ref": "#/$defs/QualifiedId"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A single validity rule, written in CEL and listed in the constraints rules. Its required id and rule give the condition that has to hold; kind is invariant by default or a gesture kind (connect, containment, create, delete, placement, change) checked before a user action. Scope says which elements it is evaluated for (default the diagram), severity defaults to error, and enforcement either reports findings or prevents the change. DISL 0.2 adds code, forEach (one finding per item), location, subject and over (model or view); rule is required unless forEach is given. It can offer quick fixes. See section 8.2.
{
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"code": {
"description": "The code findings of this rule report to users and tools, such as databricks.duplicate-task-key; it replaces x-adp-ruleId and rule ids kept in label or tags. Suppressions stay keyed by id. See DISL 0.2, section 8.2.",
"$ref": "#/$defs/QualifiedId"
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"kind": {
"enum": [
"invariant",
"connect",
"containment",
"create",
"delete",
"placement",
"change",
"reorder"
]
},
"scope": {
"anyOf": [
{
"enum": [
"diagram",
"node",
"relation",
"port",
"*"
]
},
{
"$ref": "#/$defs/TypeRefs"
}
]
},
"over": {
"enum": [
"model",
"view"
],
"description": "What one evaluation covers: model (the default and the 0.1 meaning) evaluates once per model however many views are open; view evaluates once per view, with view bound, and each finding carries that view's id. See DISL 0.2, section 8.2."
},
"forEach": {
"description": "A list evaluated once per scope element; the rule is then evaluated per item, with item and index bound, and yields one finding per item for which when holds and rule does not, in list order. rule then defaults to false (every item is a finding), and enforcement must be report. See DISL 0.2, section 8.2.",
"$ref": "#/$defs/Expression"
},
"when": {
"$ref": "#/$defs/Expression"
},
"rule": {
"$ref": "#/$defs/Expression"
},
"severity": {
"anyOf": [
{
"enum": [
"error",
"warning",
"info",
"hint"
]
},
{
"$ref": "#/$defs/CelValue"
}
]
},
"message": {
"$ref": "#/$defs/Message"
},
"target": {
"$ref": "#/$defs/Expression"
},
"attribute": {
"type": "string"
},
"location": {
"description": "The SourceLocation map (or null) of the finding, when it is not the target element's location() or is more precise. See DISL 0.2, section 8.2.",
"$ref": "#/$defs/Expression"
},
"subject": {
"description": "A string naming the undrawn thing the finding is about, such as a triple or a key path. See DISL 0.2, section 8.2.",
"$ref": "#/$defs/Expression"
},
"timing": {
"type": "array",
"items": {
"enum": [
"live",
"save",
"explicit",
"export"
]
}
},
"enforcement": {
"enum": [
"report",
"prevent",
"prevent-and-report"
]
},
"fixes": {
"type": "array",
"items": {
"$ref": "#/$defs/QuickFix"
}
},
"suppressible": {
"type": "boolean"
},
"enabled": {
"type": "boolean"
},
"group": {
"$ref": "#/$defs/SimpleId"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"cost": {
"enum": [
"cheap",
"expensive"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"id"
],
"patternProperties": {
"^x-": true
},
"anyOf": [
{
"required": [
"rule"
]
},
{
"required": [
"forEach"
]
}
],
"if": {
"required": [
"forEach"
]
},
"then": {
"properties": {
"enforcement": {
"const": "report"
}
}
}
}A suggested correction offered with a problem reported by a constraint, listed in its fixes. It has a label and either actions, executed as one transaction with self bound to the problem's element, or the id of a declared operation to run. A when condition decides whether it is offered; preferred marks the fix used by fix all and the keyboard shortcut, and applyToAll lets it fix every problem of that constraint at once. See section 8.5.
{
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/Message"
},
"when": {
"$ref": "#/$defs/Expression"
},
"actions": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"operation": {
"type": "string"
},
"preferred": {
"type": "boolean"
},
"applyToAll": {
"type": "boolean"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"label"
],
"patternProperties": {
"^x-": true
}
}6 · Behavior
What happens in response to user actions beyond direct manipulation, declared in a specification's behavior property. It holds hooks that react to events, named operations, per-type deletion policies, and clipboard, retyping and undo settings. Its maxHookDepth bounds the number of hook executions in one transaction (default 100), so hooks that trigger further hooks cannot run away. DISL 0.2 adds named reasons, the diagram-wide edit gate and standard messages. See section 9.1.
{
"type": "object",
"properties": {
"placements": {
"description": "Named parent placements, referred to by a drop's or a create action's place. See DISL 0.3, section 9.1.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/ParentPlacement"
}
},
"hooks": {
"type": "array",
"items": {
"$ref": "#/$defs/Hook"
}
},
"operations": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Operation"
}
},
"deletion": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/DeletionPolicy"
}
},
"clipboard": {
"type": "object",
"properties": {
"relations": {
"enum": [
"internal",
"all",
"none"
]
},
"ids": {
"const": "regenerate"
},
"names": {
"enum": [
"keep",
"suffix"
]
},
"offset": true,
"crossDocument": {
"type": "boolean"
},
"formats": {
"type": "array",
"items": {
"type": "string"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"retype": {
"type": "object",
"additionalProperties": {
"type": "object",
"properties": {
"to": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
}
},
"attributeMapping": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
},
"when": {
"description": "Whether the element may become a target type: self is the element and target the candidate type; default true. See DISL 0.3, section 9.5.",
"$ref": "#/$defs/Expression"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"undo": {
"type": "object",
"properties": {
"mergeWindowMs": {
"type": "integer"
},
"maxSteps": {
"type": "integer"
},
"persistHistory": {
"type": "boolean"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"maxHookDepth": {
"type": "integer"
},
"reasons": {
"description": "Named reasons, declared once and referred to as {reason: id} from any Reason list. See DISL 0.2, section 9.1.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/NamedReason"
}
},
"editGate": {
"description": "Diagram-wide reasons that, while one applies, withhold every model-changing gesture, tool, operation and form field, with the first applicable reason as the sentence; gestures that write only view data are not withheld. Element context with self bound to the diagram. See DISL 0.2, section 9.1.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"messages": {
"description": "Standard sentences the runtime otherwise words itself, by id: std.notApplicable (operation context plus operationId), std.readOnly (element context on the diagram), std.atStart and std.atEnd. See DISL 0.2, section 9.1.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/QualifiedId"
},
"additionalProperties": {
"$ref": "#/$defs/Message"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A reaction to an editing event, listed in the behavior hooks. Its required id, on and actions say which events it responds to (such as create, change, connect, move, load or save) and the actions to run in order, optionally limited to element types, changed attributes and a when condition. After hooks, the default, run after the change in the same undoable transaction; before hooks run before constraints and may abort. Hooks do not run for remote changes. See section 9.2.
{
"type": "object",
"properties": {
"id": {
"$ref": "#/$defs/SimpleId"
},
"on": {
"anyOf": [
{
"enum": [
"create",
"delete",
"change",
"connect",
"disconnect",
"reconnect",
"reparent",
"move",
"resize",
"paste",
"duplicate",
"retype",
"load",
"save",
"viewpointOpen"
]
},
{
"type": "array",
"items": {
"enum": [
"create",
"delete",
"change",
"connect",
"disconnect",
"reconnect",
"reparent",
"move",
"resize",
"paste",
"duplicate",
"retype",
"load",
"save",
"viewpointOpen"
]
},
"minItems": 1
}
]
},
"for": {
"$ref": "#/$defs/TypeRefs"
},
"attribute": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
},
"when": {
"$ref": "#/$defs/Expression"
},
"actions": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"phase": {
"enum": [
"before",
"after"
]
},
"order": {
"type": "integer"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"id",
"on",
"actions"
],
"patternProperties": {
"^x-": true
}
}A named, documented command, declared by id in the behavior operations and invoked from tools, context tools, form buttons, quick fixes, shortcuts or menus. Its for property says what it applies to: element types (bound as self), the selection or the diagram. Parameters produce a generated dialog, or a custom form, and are available as p. Its actions run as one transaction, or a plugin implements it; an enabled expression and a confirmation question are optional. See section 9.3.
{
"type": "object",
"properties": {
"label": {
"description": "The operation's label, a Message evaluated in the operation context without p each time the operation is presented. See DISL 0.2, section 9.3.",
"$ref": "#/$defs/Message"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"shortcut": {
"type": "string"
},
"for": {
"anyOf": [
{
"$ref": "#/$defs/TypeRefs"
},
{
"enum": [
"selection",
"diagram"
]
}
]
},
"params": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Attribute"
}
},
"paramsForm": {
"type": "string"
},
"enabled": {
"$ref": "#/$defs/Expression"
},
"unavailable": {
"description": "Reasons that, while one applies, make every entry that runs the operation unavailable with that reason. Operation context without p. See DISL 0.2, section 9.3.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"confirm": {
"description": "The confirmation asked before this runs: a Message (the 0.1 form, which asks every time) or a Confirmation. See DISL 0.2, section 9.5.",
"anyOf": [
{
"$ref": "#/$defs/Message"
},
{
"$ref": "#/$defs/Confirmation"
}
]
},
"actions": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"plugin": {
"$ref": "#/$defs/PluginCall"
},
"simulate": {
"description": "A simulated run, played outside any transaction and never on undo; exclusive with actions and plugin. See DISL 0.2, section 9.6.",
"$ref": "#/$defs/Simulation"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}One declarative step from a small, closed set, used in hooks, operations, quick fixes, form buttons and field change handlers. Each action is an object with one leading key such as set, unset, create, connect, delete, move, resize, retype, reparent, let, if, forEach, select, reveal, highlight, open, editLabel, openForm, notify, layout, abort, call or plugin. All values are expressions, and every action may carry a when condition that skips it unless true. See section 9.4.
{
"type": "object",
"properties": {
"set": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
},
"unset": {
"type": "array",
"items": {
"type": "string"
}
},
"target": {
"$ref": "#/$defs/Expression"
},
"create": {
"type": "object",
"properties": {
"type": {
"$ref": "#/$defs/Expression"
},
"attributes": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
},
"parent": {
"$ref": "#/$defs/Expression"
},
"slot": {
"$ref": "#/$defs/Expression"
},
"at": {
"$ref": "#/$defs/Expression"
},
"size": {
"$ref": "#/$defs/Expression"
},
"after": {
"description": "A sibling element: the new or reparented element is placed directly after it in its parent's child order; the parent's children must be ordered. At most one of after and before. See DISL 0.2, section 9.4.",
"$ref": "#/$defs/Expression"
},
"before": {
"description": "A sibling element: the new or reparented element is placed directly before it in its parent's child order. See DISL 0.2, section 9.4.",
"$ref": "#/$defs/Expression"
},
"place": {
"description": "A parent placement of behavior.placements that chooses the parent and index; exclusive with parent, after and before. See DISL 0.3, section 9.4.",
"$ref": "#/$defs/SimpleId"
}
},
"additionalProperties": false,
"required": [
"type"
],
"patternProperties": {
"^x-": true
},
"allOf": [
{
"if": {
"required": [
"place"
]
},
"then": {
"not": {
"anyOf": [
{
"required": [
"parent"
]
},
{
"required": [
"after"
]
},
{
"required": [
"before"
]
}
]
}
}
}
]
},
"connect": {
"type": "object",
"properties": {
"type": {
"$ref": "#/$defs/Expression"
},
"source": {
"$ref": "#/$defs/Expression"
},
"target": {
"$ref": "#/$defs/Expression"
},
"attributes": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
}
},
"additionalProperties": false,
"required": [
"type",
"source",
"target"
],
"patternProperties": {
"^x-": true
}
},
"as": {
"$ref": "#/$defs/SimpleId"
},
"delete": {
"$ref": "#/$defs/Expression"
},
"move": {
"type": "object",
"properties": {
"target": {
"$ref": "#/$defs/Expression"
},
"x": {
"$ref": "#/$defs/Expression"
},
"y": {
"$ref": "#/$defs/Expression"
},
"parent": {
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"resize": {
"type": "object",
"properties": {
"target": {
"$ref": "#/$defs/Expression"
},
"width": {
"$ref": "#/$defs/Expression"
},
"height": {
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"retype": {
"type": "object",
"properties": {
"to": {
"$ref": "#/$defs/Expression"
},
"target": {
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"required": [
"to"
],
"patternProperties": {
"^x-": true
}
},
"reparent": {
"type": "object",
"properties": {
"target": {
"$ref": "#/$defs/Expression"
},
"parent": {
"$ref": "#/$defs/Expression"
},
"slot": {
"$ref": "#/$defs/Expression"
},
"after": {
"description": "A sibling element: the new or reparented element is placed directly after it in its parent's child order; the parent's children must be ordered. At most one of after and before. See DISL 0.2, section 9.4.",
"$ref": "#/$defs/Expression"
},
"before": {
"description": "A sibling element: the new or reparented element is placed directly before it in its parent's child order. See DISL 0.2, section 9.4.",
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"required": [
"parent"
],
"patternProperties": {
"^x-": true
}
},
"reorder": {
"description": "Changes only the order of an element among its siblings, as one step; refused by reorder gesture constraints. Give one of by, after and before. See DISL 0.2, section 9.4.",
"type": "object",
"properties": {
"target": {
"description": "The element to move among its siblings; defaults to self. See DISL 0.2, section 9.4.",
"$ref": "#/$defs/Expression"
},
"by": {
"description": "A signed number of positions; -1 moves it up (earlier). See DISL 0.2, section 9.4.",
"$ref": "#/$defs/Expression"
},
"after": {
"description": "A sibling to place it directly after. See DISL 0.2, section 9.4.",
"$ref": "#/$defs/Expression"
},
"before": {
"description": "A sibling to place it directly before. See DISL 0.2, section 9.4.",
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"let": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
},
"if": {
"$ref": "#/$defs/Expression"
},
"then": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"else": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"forEach": {
"$ref": "#/$defs/Expression"
},
"do": {
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"view": {
"description": "Changes view data of target (default self). Viewer state is never persisted, never on undo and allowed in read-only mode; DISL 0.4: a change to a stored kind (pinned, groups, a kept filter) is an edit, written and undone with its operation. An operation whose actions are all view, select, reveal and highlight actions on viewer state is offered in read-only mode and creates no undo step. See DISL 0.4, section 9.4.",
"type": "object",
"properties": {
"collapsed": {
"description": "The viewer's new collapsed state of target. See DISL 0.2, section 9.4.",
"$ref": "#/$defs/Expression"
},
"filters": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Expression"
},
"description": "New values of the viewer's canvas filters, by filter id. See DISL 0.2, section 9.4."
},
"viewpoint": {
"description": "The viewpoint, or variant, the viewer switches to. See DISL 0.2, section 9.4.",
"$ref": "#/$defs/Expression"
},
"pinned": {
"description": "Whether target is pinned: true pins it at its current position, false removes the pin and its stored position. See DISL 0.4, sections 7.3 and 9.4.",
"$ref": "#/$defs/Expression"
},
"groups": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"$ref": "#/$defs/Expression"
},
"description": "New collapse states of target's compartment groups, by group key; a state equal to the group's default removes the stored state. See DISL 0.4, sections 6.9 and 9.4."
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"open": {
"description": "Opens a link: an http or https URI in the platform's browser without access to the runtime, a path through the host's reveal (or shown with an offer to copy when the host cannot reveal it); anything else is refused. Changes no model, view data or history. See DISL 0.4, section 9.4.",
"$ref": "#/$defs/Expression"
},
"select": {
"$ref": "#/$defs/Expression"
},
"reveal": {
"$ref": "#/$defs/Expression"
},
"highlight": {
"$ref": "#/$defs/Expression"
},
"durationMs": {
"type": "integer"
},
"editLabel": {
"type": "object",
"properties": {
"target": {
"$ref": "#/$defs/Expression"
},
"label": {
"type": "string"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"openForm": {
"type": "object",
"properties": {
"target": {
"$ref": "#/$defs/Expression"
},
"form": {
"type": "string"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"notify": {
"type": "object",
"properties": {
"message": {
"$ref": "#/$defs/Expression"
},
"severity": {
"enum": [
"info",
"success",
"warning",
"error"
]
}
},
"additionalProperties": false,
"required": [
"message"
],
"patternProperties": {
"^x-": true
}
},
"layout": {
"type": "object",
"properties": {
"scope": {
"$ref": "#/$defs/Expression"
},
"algorithm": {
"type": "string"
},
"refusals": {
"description": "Refusals of a layout action: nothingDrawn while the scope holds nothing the algorithm can place (for rows, no element with a drawable extent), unchanged when the layout would change nothing. See DISL 0.3, section 9.4.",
"type": "object",
"properties": {
"nothingDrawn": {
"$ref": "#/$defs/Message"
},
"unchanged": {
"$ref": "#/$defs/Message"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"abort": {
"type": "object",
"properties": {
"message": {
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"call": {
"$ref": "#/$defs/SimpleId"
},
"args": {
"type": "object",
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
},
"plugin": {
"$ref": "#/$defs/QualifiedId"
},
"when": {
"$ref": "#/$defs/Expression"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"minProperties": 1
}The rules for deleting an element of one type, declared per type in the behavior deletion map. Children says what happens to contained elements (delete by default, reparent to the deleted node's parent, or forbid); relations covers attached edges (delete by default, forbid, or reconnect incoming to outgoing edges of the same type); references covers reference attributes pointing at it (unset by default, delete the referencing elements, or forbid). A confirm text asks before deleting. See section 9.5.
{
"type": "object",
"properties": {
"children": {
"enum": [
"delete",
"reparent",
"forbid"
]
},
"relations": {
"enum": [
"delete",
"forbid",
"reconnect"
]
},
"references": {
"enum": [
"unset",
"delete-referencing",
"forbid"
]
},
"confirm": {
"description": "The confirmation asked before this runs: a Message (the 0.1 form, which asks every time) or a Confirmation. See DISL 0.2, section 9.5.",
"anyOf": [
{
"$ref": "#/$defs/Message"
},
{
"$ref": "#/$defs/Confirmation"
}
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}7 · Layout
The automatic layout settings of a specification, declared in its layout property. It names layout configurations under algorithms, chooses the default one used by the Arrange command, sets layouts inside containers of a type, and says when layout runs automatically (manual by default) and which user positions survive it (pinned elements by default). Layout never changes coordinates bound to attributes, such as a task's start date. See section 10.
{
"type": "object",
"properties": {
"algorithms": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/LayoutConfig"
}
},
"default": {
"type": "string"
},
"containers": {
"type": "object",
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"$ref": "#/$defs/LayoutConfig"
}
]
}
},
"trigger": {
"enum": [
"manual",
"onCreate",
"onChange",
"onLoadIfMissing",
"always"
]
},
"respect": {
"enum": [
"none",
"pinned",
"all"
]
},
"incremental": {
"type": "boolean"
},
"animate": {
"anyOf": [
{
"const": false
},
{
"type": "object",
"properties": {
"durationMs": {
"type": "integer"
},
"easing": {
"type": "string"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}One named layout configuration, used in the layout algorithms map and for containers. Its required algorithm names the layout, such as layered, tree, force, lanes, an ELK algorithm or a plugin; DISL names algorithms but does not define them. Further settings give the main flow direction, spacing in canvas units, edge routing, whether user bendpoints are replaced, pass-through algorithm options, the default scope and whether notes take part. See section 10.
{
"type": "object",
"properties": {
"algorithm": {
"type": "string",
"description": "The algorithm: a name DISL lists (10), of which rowPacked, rows and tidyTree are standard and defined in 10.1 to 10.3 and force with tiers has the properties of 10.4, elk:<id> or plugin:<name>. See DISL 0.4, section 10."
},
"direction": {
"enum": [
"right",
"down",
"left",
"up"
]
},
"spacing": {
"type": "object",
"properties": {
"node": {
"type": "number"
},
"layer": {
"type": "number"
},
"edge": {
"type": "number"
},
"component": {
"type": "number"
},
"port": {
"type": "number"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"edgeRouting": {
"$ref": "#/$defs/Routing"
},
"overrideRouting": {
"type": "boolean"
},
"options": {
"type": "object"
},
"scope": {
"enum": [
"all",
"selection",
"component"
]
},
"includeViewOnly": {
"type": "boolean"
},
"rowPacked": {
"description": "The options of the standard rowPacked algorithm; only with algorithm rowPacked. See DISL 0.3, section 10.",
"$ref": "#/$defs/RowPacked"
},
"rows": {
"description": "The options of the standard rows algorithm; only with algorithm rows. See DISL 0.3, section 10.",
"$ref": "#/$defs/RowsLayout"
},
"tidyTree": {
"description": "The options of the standard tidyTree algorithm; only with algorithm tidyTree. See DISL 0.3, section 10.",
"$ref": "#/$defs/TidyTree"
},
"force": {
"description": "The options of force: tiers of node types from the centre outwards and the least gap between nodes; only with algorithm force. See DISL 0.4, section 10.4.",
"$ref": "#/$defs/ForceLayout"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"algorithm"
],
"patternProperties": {
"^x-": true
},
"allOf": [
{
"if": {
"required": [
"rowPacked"
]
},
"then": {
"properties": {
"algorithm": {
"const": "rowPacked"
}
}
}
},
{
"if": {
"required": [
"rows"
]
},
"then": {
"properties": {
"algorithm": {
"const": "rows"
}
}
}
},
{
"if": {
"required": [
"tidyTree"
]
},
"then": {
"properties": {
"algorithm": {
"const": "tidyTree"
}
}
}
},
{
"if": {
"required": [
"force"
]
},
"then": {
"properties": {
"algorithm": {
"const": "force"
}
}
}
}
]
}8 · Persistence
How the diagrams users draw are stored as DID definitions, declared in a specification's persistence property. It chooses the serialization format (json by default), encoding and file split, how ids are generated, how records and keys are ordered, number precision and timestamps, which view data and style overrides are kept, metadata, how the specification is referenced, migrations, collaboration, and import and export conversions. The aim is byte-identical output from any two conforming runtimes. DISL 0.2 moves ids to IdStrategy and adds viewer state to view. With format fbl the model is instead a body in another tool's format, read and written through an FBL binding (FBL, the Format Binding Language), and the DID writer settings are not given. See sections 11.1 and 11.2.
{
"type": "object",
"properties": {
"format": {
"anyOf": [
{
"enum": [
"json",
"yaml",
"jsonl",
"cbor",
"fbl"
]
},
{
"type": "string",
"pattern": "^plugin:"
}
]
},
"binding": {
"description": "The FBL binding that reads and writes the model when format is fbl: a URI reference to an FBL document followed by '#' and the binding's name, or an inline FBL Binding. See section 11.2.",
"anyOf": [
{
"type": "string",
"format": "uri-reference"
},
{
"$ref": "https://etalii.net/adp/fbl/schema/0.1/fbl.schema.json#/$defs/Binding"
}
]
},
"typeMap": {
"description": "Only with format fbl: the binding's types mapped onto the metamodel, keyed by the binding's type name; without it, the binding's types and attributes are the metamodel's. See DISL 0.3, section 11.2.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/QualifiedId"
},
"additionalProperties": {
"$ref": "#/$defs/TypeMapEntry"
}
},
"encoding": {
"const": "utf-8"
},
"indent": {
"anyOf": [
{
"type": "integer"
},
{
"const": "tab"
}
]
},
"newline": {
"enum": [
"lf",
"crlf"
]
},
"finalNewline": {
"type": "boolean"
},
"compression": {
"enum": [
"none",
"gzip",
"zip-bundle"
]
},
"mediaType": {
"type": "string"
},
"files": {
"type": "object",
"properties": {
"mode": {
"enum": [
"single",
"split",
"per-element",
"bundle"
]
},
"model": {
"type": "string"
},
"view": {
"type": "string"
},
"index": {
"type": "string"
},
"assets": {
"type": "object",
"properties": {
"mode": {
"enum": [
"inline",
"external",
"bundle"
]
},
"dir": {
"type": "string"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"lock": {
"type": "boolean"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"ids": {
"$ref": "#/$defs/IdStrategy"
},
"references": {
"enum": [
"id",
"path",
"qualified-name"
]
},
"ordering": {
"type": "object",
"properties": {
"elements": {
"enum": [
"creation",
"id",
"type-then-id",
"tree",
"cel"
]
},
"orderBy": {
"$ref": "#/$defs/Expression"
},
"keys": {
"enum": [
"canonical",
"alphabetical"
]
},
"layout": {
"enum": [
"flat",
"nested"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"omitDefaults": {
"type": "boolean"
},
"precision": {
"type": "object",
"properties": {
"canvas": {
"type": "integer"
},
"numbers": {
"type": "integer"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"timestamps": {
"type": "object",
"properties": {
"format": {
"enum": [
"rfc3339",
"epoch-ms"
]
},
"timezone": {
"enum": [
"utc",
"preserve"
]
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"canonical": {
"type": "boolean"
},
"view": {
"type": "object",
"properties": {
"store": {
"type": "array",
"items": {
"$ref": "#/$defs/ViewKind"
}
},
"styleOverrides": {
"anyOf": [
{
"enum": [
"none",
"all"
]
},
{
"type": "array",
"items": {
"type": "string"
}
}
]
},
"viewer": {
"type": "array",
"items": {
"$ref": "#/$defs/ViewKind"
},
"description": "View-data kinds held per viewer: never persisted, never on undo, changeable in read-only mode, not shared with other viewers and not readable from deterministic contexts. See DISL 0.2, section 11.6."
},
"initial": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"description": "The value each viewer kind starts with when a viewer first opens a view, from kind to a literal or {cel} in the element context; collapsed without one starts false. See DISL 0.2, section 11.6."
},
"revealExpands": {
"type": "boolean",
"description": "Whether revealing or selecting an element inside a collapsed container expands its collapsed ancestors; defaults to true. See DISL 0.2, section 11.6."
},
"bind": {
"description": "Only with format fbl: binds stored kinds of view data (pinned, groups, filters) onto entries of the body rather than the registration. Each kind names the binding type whose entries hold it and which of its attributes hold the element, the position, the group and its state, or the filters' values. See DISL 0.4, section 11.6.",
"type": "object",
"properties": {
"pinned": {
"$ref": "#/$defs/ViewBind"
},
"groups": {
"$ref": "#/$defs/ViewBind"
},
"filters": {
"$ref": "#/$defs/ViewBind"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"metadata": {
"type": "array",
"items": {
"enum": [
"languageVersion",
"createdAt",
"modifiedAt",
"generator",
"authors",
"title",
"checksum"
]
}
},
"definition": {
"type": "object",
"properties": {
"embed": {
"enum": [
"none",
"reference",
"inline"
]
},
"uri": {
"type": "string"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"migrations": {
"type": "array",
"items": {
"$ref": "#/$defs/Migration"
}
},
"collaboration": {
"type": "object",
"properties": {
"mode": {
"enum": [
"none",
"lock",
"ot",
"crdt"
]
},
"engine": {
"anyOf": [
{
"enum": [
"yjs",
"automerge"
]
},
{
"type": "string",
"pattern": "^plugin:"
}
]
},
"granularity": {
"enum": [
"element",
"attribute"
]
},
"text": {
"enum": [
"replace",
"merge"
]
},
"ordering": {
"const": "fractional-index"
},
"presence": {
"type": "boolean"
},
"conflicts": {
"enum": [
"last-writer-wins",
"report"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"export": {
"type": "array",
"items": {
"type": "object",
"properties": {
"format": {
"type": "string"
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"options": {
"type": "object"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"format"
],
"patternProperties": {
"^x-": true
}
}
},
"import": {
"type": "array",
"items": {
"type": "object",
"properties": {
"format": {
"type": "string"
},
"label": {
"$ref": "#/$defs/LocalizedText"
},
"options": {
"type": "object"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"format"
],
"patternProperties": {
"^x-": true
}
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"allOf": [
{
"if": {
"properties": {
"format": {
"const": "fbl"
}
},
"required": [
"format"
]
},
"then": {
"required": [
"binding"
],
"not": {
"anyOf": [
{
"required": [
"files"
]
},
{
"required": [
"encoding"
]
},
{
"required": [
"indent"
]
},
{
"required": [
"newline"
]
},
{
"required": [
"finalNewline"
]
},
{
"required": [
"compression"
]
},
{
"required": [
"mediaType"
]
},
{
"required": [
"ordering"
]
},
{
"required": [
"omitDefaults"
]
},
{
"required": [
"precision"
]
},
{
"required": [
"timestamps"
]
},
{
"required": [
"canonical"
]
},
{
"required": [
"metadata"
]
},
{
"required": [
"definition"
]
}
]
}
},
"else": {
"not": {
"anyOf": [
{
"required": [
"binding"
]
},
{
"required": [
"typeMap"
]
}
]
}
}
}
]
}An upgrade from older language versions, listed in the persistence migrations. Its from property is a version range, to is the version it produces, and steps is a non-empty ordered list of migration steps. Migrations run on load, before validation, in version order; a failing migration aborts loading, and the original file is not modified until the user saves. See section 11.9.
{
"type": "object",
"properties": {
"from": {
"type": "string"
},
"to": {
"$ref": "#/$defs/SemVer"
},
"steps": {
"type": "array",
"items": {
"$ref": "#/$defs/MigrationStep"
},
"minItems": 1
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"from",
"to",
"steps"
],
"patternProperties": {
"^x-": true
}
}One step of a migration, written as an object with a single step key and an optional doc. Steps rename, delete or retype types, rename, delete, set or convert attributes, transform a whole attributes map, convert stored view coordinates, rename ports and slots, or call a plugin. Expressions run in the migration context, which sees raw records as maps rather than typed elements, because the old definition does not conform to the new metamodel. See section 11.9.
{
"type": "object",
"properties": {
"renameType": {
"type": "object",
"properties": {
"from": {
"type": "string"
},
"to": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"from",
"to"
],
"patternProperties": {
"^x-": true
}
},
"renameAttribute": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"from": {
"type": "string"
},
"to": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"type",
"from",
"to"
],
"patternProperties": {
"^x-": true
}
},
"deleteType": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"mode": {
"enum": [
"delete",
"keep-as-unknown"
]
}
},
"additionalProperties": false,
"required": [
"type"
],
"patternProperties": {
"^x-": true
}
},
"deleteAttribute": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"attribute": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"type",
"attribute"
],
"patternProperties": {
"^x-": true
}
},
"setAttribute": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"attribute": {
"type": "string"
},
"value": {
"$ref": "#/$defs/Expression"
},
"when": {
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"required": [
"type",
"attribute",
"value"
],
"patternProperties": {
"^x-": true
}
},
"convertAttribute": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"attribute": {
"type": "string"
},
"cel": {
"$ref": "#/$defs/CelSource"
}
},
"additionalProperties": false,
"required": [
"type",
"attribute",
"cel"
],
"patternProperties": {
"^x-": true
}
},
"transform": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"cel": {
"$ref": "#/$defs/CelSource"
}
},
"additionalProperties": false,
"required": [
"type",
"cel"
],
"patternProperties": {
"^x-": true
}
},
"retype": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"to": {
"type": "string"
},
"when": {
"$ref": "#/$defs/Expression"
}
},
"additionalProperties": false,
"required": [
"type",
"to"
],
"patternProperties": {
"^x-": true
}
},
"convertView": {
"type": "object",
"properties": {
"system": {
"type": "string"
},
"x": {
"$ref": "#/$defs/CelSource"
},
"y": {
"$ref": "#/$defs/CelSource"
},
"w": {
"$ref": "#/$defs/CelSource"
},
"h": {
"$ref": "#/$defs/CelSource"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"renamePort": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"from": {
"type": "string"
},
"to": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"type",
"from",
"to"
],
"patternProperties": {
"^x-": true
}
},
"renameSlot": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"from": {
"type": "string"
},
"to": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"type",
"from",
"to"
],
"patternProperties": {
"^x-": true
}
},
"plugin": {
"$ref": "#/$defs/PluginCall"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"minProperties": 1,
"maxProperties": 2
}Documents
Not listed in Appendix A.2
Any user-facing text that may be computed: a LocalizedText, or the object form of a computed value ({cel}) returning a string or a map of language tags to strings. Every user-facing text position of DISL 0.2 (labels, messages, placeholders, titles, confirmations, refusals and reasons) accepts it. In a Message position an object with a cel property is always CEL, never a locale map, and a CEL Message that fails to evaluate falls back to the position's default text. See DISL 0.2, section 2.3.
{
"anyOf": [
{
"$ref": "#/$defs/LocalizedText"
},
{
"$ref": "#/$defs/CelValue"
}
]
}Why a gesture is refused, a field is read-only or an entry is unavailable. It is a Message, which always applies; an object with a when condition and a message, which applies while when holds (always when absent); or a reference {reason: id} to a named reason in behavior.reasons, which applies while that reason's when holds. Reasons are used in ordered lists, of which the first that applies is the one shown. See DISL 0.2, section 2.3.
{
"anyOf": [
{
"$ref": "#/$defs/Message"
},
{
"type": "object",
"properties": {
"when": {
"description": "The condition under which this reason applies, in the context of the position that holds it; absent means always. See DISL 0.2, section 2.3.",
"$ref": "#/$defs/Expression"
},
"message": {
"description": "The sentence shown while this reason applies. See DISL 0.2, section 2.3.",
"$ref": "#/$defs/Message"
},
"id": {
"description": "An optional name for this reason, for diagnostics and documentation. See DISL 0.2, section 2.3.",
"$ref": "#/$defs/SimpleId"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"message"
],
"patternProperties": {
"^x-": true
}
},
{
"type": "object",
"properties": {
"reason": {
"description": "The id of a named reason declared in behavior.reasons; a reference to an undeclared reason is a specification error. See DISL 0.2, section 9.1.",
"$ref": "#/$defs/SimpleId"
}
},
"additionalProperties": false,
"required": [
"reason"
],
"patternProperties": {
"^x-": true
}
}
]
}A reason declared once by id in behavior.reasons and referred to as {reason: id} from any Reason list, so that one sentence is written once and shown the same wherever it applies. It has a when condition and a message. See DISL 0.2, section 9.1.
{
"type": "object",
"properties": {
"when": {
"description": "The condition under which the reason applies, in the context of the position that refers to it; absent means always. See DISL 0.2, section 9.1.",
"$ref": "#/$defs/Expression"
},
"message": {
"description": "The sentence shown wherever the reason applies. See DISL 0.2, section 9.1.",
"$ref": "#/$defs/Message"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"message"
],
"patternProperties": {
"^x-": true
}
}What a hard budget withholds while it is exceeded, and the reason shown for it on every refused gesture, read-only row and unavailable entry. See DISL 0.2, section 3.2.1.
{
"type": "object",
"properties": {
"edits": {
"enum": [
"model",
"all",
"none"
],
"description": "What is refused while the budget is exceeded: model (the default) every change to the model, all also stored view data such as positions, none nothing. See DISL 0.2, section 3.2.1."
},
"reason": {
"description": "The refusal and read-only reason shown for every withheld edit; defaults to the runtime's sentence. See DISL 0.2, section 3.2.1.",
"$ref": "#/$defs/Reason"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}One hard budget, in language.limits.budgets keyed by id: what it measures, its maximum, the truncation order and units, and the notice, withheld edits and finding while it is exceeded. Budgets apply after viewer filters, deterministically, and never remove model data; CEL reads their state with budget(id). maxElements stays a soft limit. See DISL 0.2, section 3.2.1.
{
"type": "object",
"properties": {
"measure": {
"description": "What is counted: {count: [types]}, the drawn candidates of those node and relation types after viewer filters, or {cel}, an int in the budget context for a measure that is not a count of drawn elements. See DISL 0.2, section 3.2.1.",
"anyOf": [
{
"type": "object",
"properties": {
"count": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
},
"minItems": 1,
"description": "The node and relation types whose drawn candidates are counted. See DISL 0.2, section 3.2.1."
}
},
"additionalProperties": false,
"required": [
"count"
],
"patternProperties": {
"^x-": true
}
},
{
"$ref": "#/$defs/CelValue"
}
]
},
"max": {
"type": "integer",
"minimum": 0,
"description": "The limit. See DISL 0.2, section 3.2.1."
},
"truncate": {
"type": "boolean",
"description": "Whether the budget cuts what is drawn; defaults to true for count and false for cel. A non-truncating budget only gates edits and notices. See DISL 0.2, section 3.2.1."
},
"order": {
"description": "The sort key of each candidate, ascending, in the budget context (self, index); may return a list for lexicographic keys. Defaults to persistence order. See DISL 0.2, section 3.2.1.",
"$ref": "#/$defs/Expression"
},
"unit": {
"description": "A group key: the elements of one unit are kept or cut together, and the first unit that does not fit ends the cut. Defaults to each element on its own. See DISL 0.2, section 3.2.1.",
"$ref": "#/$defs/Expression"
},
"notice": {
"description": "The built-in notice budget:<id> shown while the budget truncates: true (the default), false, or its text, severity and position. See DISL 0.2, section 3.2.1.",
"anyOf": [
{
"type": "boolean"
},
{
"type": "object",
"properties": {
"text": {
"$ref": "#/$defs/Message",
"description": "The notice's text; defaults to a sentence naming shown and total. See DISL 0.2, section 3.2.1."
},
"severity": {
"enum": [
"info",
"warning",
"error"
],
"description": "Styles the notice; defaults to info. See DISL 0.2, section 3.2.1."
},
"position": {
"enum": [
"top",
"bottom",
"top-left",
"top-right",
"bottom-left",
"bottom-right"
],
"description": "Where the notice sits; defaults to top. See DISL 0.2, section 3.2.1."
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}
]
},
"withhold": {
"description": "What is refused while the budget is exceeded, with its reason. See DISL 0.2, section 3.2.1.",
"$ref": "#/$defs/BudgetWithhold"
},
"finding": {
"description": "A diagram-level finding reported while the budget is exceeded. See DISL 0.2, section 3.2.1.",
"type": "object",
"properties": {
"severity": {
"enum": [
"error",
"warning",
"info",
"hint"
],
"description": "The finding's severity; defaults to info. See DISL 0.2, section 3.2.1."
},
"message": {
"$ref": "#/$defs/Message",
"description": "The finding's message. See DISL 0.2, section 3.2.1."
}
},
"additionalProperties": false,
"required": [
"message"
],
"patternProperties": {
"^x-": true
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"measure",
"max"
],
"patternProperties": {
"^x-": true
}
}What happens to a value past an attribute's min or max, or an axis's bounds: whether a drag is clamped or refused, whether a typed value is refused or clamped, and the refusal message. The defaults refuse both, as in 0.1. See DISL 0.2, sections 4.3 and 5.3.
{
"type": "object",
"properties": {
"drag": {
"enum": [
"clamp",
"refuse"
],
"description": "A gesture that would put the value past the bound: clamp stops it at the bound (after snapping, the bound wins), refuse refuses it (the default). See DISL 0.2, section 4.3."
},
"typed": {
"enum": [
"refuse",
"clamp"
],
"description": "A value entered in a form or a label, or pasted, past the bound: refuse (the default) or clamp. See DISL 0.2, section 4.3."
},
"message": {
"description": "The refusal, in the gesture:change context plus min and max; defaults to the std.facets or std.axisBounds sentence. See DISL 0.2, section 4.3.",
"$ref": "#/$defs/Message"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}Ordered attributes of one element kept a minimum gap apart and inside two other attributes, in a node or relation type's bounds.neighbour: after any transaction that changes one of them, the runtime clamps the present values in order, as part of that transaction. See DISL 0.3, section 4.3.
{
"type": "object",
"properties": {
"attributes": {
"description": "The ordered attributes kept apart, in their order. See DISL 0.3, section 4.3.",
"type": "array",
"items": {
"$ref": "#/$defs/SimpleId"
},
"minItems": 1,
"uniqueItems": true
},
"between": {
"description": "The two attributes every value of attributes lies between, the lower first. See DISL 0.3, section 4.3.",
"type": "array",
"items": {
"$ref": "#/$defs/SimpleId"
},
"minItems": 2,
"maxItems": 2
},
"gap": {
"description": "The least distance between two neighbouring anchors, in the attributes' units (months for yearMonth); a number or {cel} in the element context. See DISL 0.3, section 4.3.",
"anyOf": [
{
"type": "number",
"minimum": 0
},
{
"$ref": "#/$defs/CelValue"
}
]
},
"inner": {
"description": "How many of attributes, from the first, take part as anchors; the others are only clamped inside between. An int or {cel} in the element context; default all of them. See DISL 0.3, section 4.3.",
"anyOf": [
{
"type": "integer",
"minimum": 0
},
{
"$ref": "#/$defs/CelValue"
}
]
},
"absent": {
"description": "An absent attribute among the anchors: spread takes its evenly spread position between its present neighbours as an anchor; ignore (the default) leaves it out. See DISL 0.3, section 4.3.",
"enum": [
"spread",
"ignore"
]
},
"on": {
"description": "The edits after which the clamp runs: change (a typed or programmatic set), handle (a shape handle drag) and create; default all three. See DISL 0.3, section 4.3.",
"type": "array",
"items": {
"enum": [
"change",
"handle",
"create"
]
},
"minItems": 1,
"uniqueItems": true
},
"pinned": {
"description": "edited clamps the attribute the transaction set first and the others around it; none (the default) clamps them in order. See DISL 0.3, section 4.3.",
"enum": [
"edited",
"none"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"attributes",
"between",
"gap"
],
"patternProperties": {
"^x-": true
}
}The derived object of a node type, whose elements are computed from the model rather than stored: from gives the items, key groups them, id, attributes, parent and slot are computed per group in the deriveItem context (item, group, index), sources records the provenance, and reason and edits say what happens to gestures on them. Derived elements are computed on load and in every transaction, in declaration order, and are never written, instantiated or put on undo. See DISL 0.2, section 4.11.
{
"type": "object",
"properties": {
"from": {
"description": "The items, a list in the derive context; one element per item, or per distinct key. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Expression"
},
"key": {
"description": "Items with equal keys (CEL equality; a string, number, bool or list of those) yield one element, with group bound to all of them; by default every item is its own element. deriveItem context. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Expression"
},
"id": {
"description": "The element's id, a string in the deriveItem context; it must be unique among all elements. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Expression"
},
"attributes": {
"description": "The values of the type's attributes, from attribute name to an Expression in the deriveItem context; an attribute not listed has its default. See DISL 0.2, section 4.11.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
},
"parent": {
"description": "Computed containment: the parent element, stored or derived earlier, allowed by its type's children; defaults to null (top level). See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Expression"
},
"slot": {
"description": "The slot in the parent (4.8). See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Expression"
},
"sources": {
"description": "The provenance, a list of elements; defaults to group when the items are elements, else []. Read in CEL as self.sources. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Expression"
},
"reason": {
"description": "Why a gesture on a derived element is refused when edits does not map it; defaults to the runtime's sentence. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Reason"
},
"edits": {
"description": "Gestures carried out by an operation on the sources instead of being refused, from gesture (delete, reparent, move, connect, rename or attribute:<name>) to operation id; the operation receives the derived element as self. See DISL 0.2, section 4.11.",
"type": "object",
"propertyNames": {
"pattern": "^(delete|reparent|move|connect|rename|attribute:[A-Za-z_][A-Za-z0-9_]*)$"
},
"additionalProperties": {
"$ref": "#/$defs/SimpleId"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"from",
"id"
],
"patternProperties": {
"^x-": true
}
}The object form of a relation type's derived property: the members of a derived node type except parent and slot, plus the source, target and owner of each derived relation. The 0.1 expression form keeps its meaning. See DISL 0.2, sections 4.9 and 4.11.
{
"type": "object",
"properties": {
"from": {
"description": "The items, a list in the derive context; one element per item, or per distinct key. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Expression"
},
"key": {
"description": "Items with equal keys (CEL equality; a string, number, bool or list of those) yield one element, with group bound to all of them; by default every item is its own element. deriveItem context. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Expression"
},
"id": {
"description": "The element's id, a string in the deriveItem context; it must be unique among all elements. Defaults to <Type>:<source.id>-><target.id>, with #2, #3 and so on appended to repeats. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Expression"
},
"attributes": {
"description": "The values of the type's attributes, from attribute name to an Expression in the deriveItem context; an attribute not listed has its default. See DISL 0.2, section 4.11.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
},
"source": {
"description": "The source element, which must satisfy the relation type's source; an item whose ends do not is dropped and reported by std.derivedEnds. See DISL 0.2, section 4.9.",
"$ref": "#/$defs/Expression"
},
"target": {
"description": "The target element, which must satisfy the relation type's target. See DISL 0.2, section 4.9.",
"$ref": "#/$defs/Expression"
},
"owner": {
"description": "The element the relation belongs to: it is drawn in the owner's layer and hidden with it. Defaults to the nearest common ancestor of its ends, or the diagram. See DISL 0.2, section 4.9.",
"$ref": "#/$defs/Expression"
},
"sources": {
"description": "The provenance, a list of elements; defaults to group when the items are elements, else []. Read in CEL as self.sources. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Expression"
},
"reason": {
"description": "Why a gesture on a derived element is refused when edits does not map it; defaults to the runtime's sentence. See DISL 0.2, section 4.11.",
"$ref": "#/$defs/Reason"
},
"edits": {
"description": "Gestures carried out by an operation on the sources instead of being refused, from gesture (delete, reparent, move, connect, rename or attribute:<name>) to operation id; the operation receives the derived element as self. See DISL 0.2, section 4.11.",
"type": "object",
"propertyNames": {
"pattern": "^(delete|reparent|move|connect|rename|attribute:[A-Za-z_][A-Za-z0-9_]*)$"
},
"additionalProperties": {
"$ref": "#/$defs/SimpleId"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"from",
"source",
"target"
],
"patternProperties": {
"^x-": true
}
}A calendar unit of time, accepted wherever a unit is: axis scales, zoom levels, ruler levels and ticks, calendar snap rules, grid spacing and the CEL unit functions. DISL 0.2 adds decade, century and millennium, whose boundaries are years divisible by 10, 100 and 1000 in astronomical numbering. See DISL 0.2, section 5.5.
{
"enum": [
"millisecond",
"second",
"minute",
"hour",
"day",
"week",
"month",
"quarter",
"year",
"decade",
"century",
"millennium"
]
}A single adaptive row of ruler ticks: of the listed steps, the finest whose labels are at least minSpacingPx apart is used. Ticks fall on round boundaries of their unit. See DISL 0.2, section 5.13.
{
"type": "object",
"properties": {
"minSpacingPx": {
"type": "number",
"minimum": 0,
"description": "The least distance between labels; the finest step that keeps it is used. See DISL 0.2, section 5.13."
},
"steps": {
"type": "array",
"minItems": 1,
"description": "The candidate steps, finest first. See DISL 0.2, section 5.13.",
"items": {
"type": "object",
"properties": {
"unit": {
"$ref": "#/$defs/TimeUnit",
"description": "The step's unit. See DISL 0.2, section 5.13."
},
"step": {
"type": "integer",
"minimum": 1,
"description": "Multiples of unit; defaults to 1. See DISL 0.2, section 5.13."
},
"format": {
"type": "string",
"description": "The label format (LDML). See DISL 0.2, section 5.13."
}
},
"additionalProperties": false,
"required": [
"unit"
],
"patternProperties": {
"^x-": true
}
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"steps"
],
"patternProperties": {
"^x-": true
}
}A named range of a linear axis, possibly of unequal size, drawn as a band with the grid under the elements and optionally separated by a line; not an element. CEL axisRange(axis, value) returns the id of the range holding a value. See DISL 0.2, section 5.3.
{
"type": "object",
"properties": {
"id": {
"description": "The range's id, returned by axisRange(). See DISL 0.2, section 5.3.",
"$ref": "#/$defs/SimpleId"
},
"label": {
"$ref": "#/$defs/Message",
"description": "The range's label. See DISL 0.2, section 5.3."
},
"from": {
"description": "The range's start, a domain value. See DISL 0.2, section 5.3."
},
"to": {
"description": "The range's end, a domain value. See DISL 0.2, section 5.3."
},
"fill": {
"$ref": "#/$defs/Paint",
"description": "The band's fill. See DISL 0.2, section 5.3."
},
"style": {
"$ref": "#/$defs/StyleRef",
"description": "The band's style. See DISL 0.2, section 5.3."
},
"separator": {
"description": "The line drawn at the range's start. See DISL 0.2, section 5.3.",
"$ref": "#/$defs/Stroke"
},
"labelPosition": {
"enum": [
"start",
"center",
"end"
],
"description": "Where the label sits along the range; defaults to center. See DISL 0.2, section 5.3."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"id",
"from",
"to"
],
"patternProperties": {
"^x-": true
}
}A contrast the theme must keep between a foreground token and one or more background tokens, in every mode; a specification validator reports a pair below minRatio as a specification warning. Runtimes are unaffected. See DISL 0.2, section 6.2.
{
"type": "object",
"properties": {
"foreground": {
"description": "The token of the foreground colour. See DISL 0.2, section 6.2.",
"$ref": "#/$defs/QualifiedId"
},
"background": {
"anyOf": [
{
"$ref": "#/$defs/QualifiedId"
},
{
"type": "array",
"items": {
"$ref": "#/$defs/QualifiedId"
},
"minItems": 1
}
],
"description": "The token, or tokens, of the background colours. See DISL 0.2, section 6.2."
},
"minRatio": {
"type": "number",
"minimum": 1,
"description": "The least WCAG 2.x contrast ratio in every theme mode; 4.5 is recommended for text. See DISL 0.2, section 6.2."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"foreground",
"background",
"minRatio"
],
"patternProperties": {
"^x-": true
}
}Items of a compartment listed under one heading per value of an enumeration attribute, in the enumeration's declared order, each with a count and a collapse default per value; empty groups are left out unless empty is show. The group key is the value's stored form. See DISL 0.4, section 6.9.
{
"type": "object",
"properties": {
"attribute": {
"description": "An attribute of every item type whose type is an enumeration.",
"$ref": "#/$defs/SimpleId"
},
"collapsed": {
"description": "Whether each group starts collapsed, by the enum value's key; a value not listed starts expanded.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"type": "boolean"
}
},
"count": {
"description": "Whether a heading shows how many items it holds; defaults to true.",
"type": "boolean"
},
"empty": {
"description": "Whether a group with no item has a heading: hide (the default) or show.",
"enum": [
"hide",
"show"
]
},
"title": {
"description": "The heading's text, in the compartmentItem context with item bound to the value's key; defaults to the value's label.",
"$ref": "#/$defs/Message"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"attribute"
],
"patternProperties": {
"^x-": true
}
}The slots packed badges take: visible badges with pack take consecutive slots in declaration order, from start and offset, in direction, spacing apart. See DISL 0.2, section 6.9.
{
"type": "object",
"properties": {
"start": {
"description": "Where the first slot is. See DISL 0.2, section 6.9.",
"$ref": "#/$defs/Position"
},
"offset": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 2,
"maxItems": 2,
"description": "The first slot's offset [dx, dy] from start. See DISL 0.2, section 6.9."
},
"direction": {
"enum": [
"left",
"right",
"up",
"down"
],
"description": "The direction later slots run in. See DISL 0.2, section 6.9."
},
"spacing": {
"type": "number",
"description": "The distance between slots. See DISL 0.2, section 6.9."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}The control points of a bezier-routed edge: their reach along the start and end directions and what happens when the target lies behind the source. See DISL 0.2, section 6.10.
{
"type": "object",
"properties": {
"reach": {
"anyOf": [
{
"type": "number",
"minimum": 0
},
{
"const": "auto"
}
],
"description": "How far the control points lie from each end along the start and end directions, in canvas units; auto is half the horizontal distance, at least 30. See DISL 0.2, section 6.10."
},
"backward": {
"enum": [
"direct",
"loop"
],
"description": "When the end lies behind the start: direct doubles back; loop grows the reach so the curve leaves forward and re-enters from behind. See DISL 0.2, section 6.10."
},
"maxReach": {
"type": "number",
"minimum": 0,
"description": "The largest reach loop may grow to. See DISL 0.2, section 6.10."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}How a relation without a target (target.optional) is drawn: a short line out of its source, with its style and label. The stub is the relation: selecting it selects the relation. See DISL 0.2, section 6.10.
{
"type": "object",
"properties": {
"length": {
"type": "number",
"minimum": 0,
"description": "The stub's length in canvas units. See DISL 0.2, section 6.10."
},
"side": {
"enum": [
"right",
"left",
"top",
"bottom",
"auto"
],
"description": "The side of the source the stub leaves from. See DISL 0.2, section 6.10."
},
"style": {
"$ref": "#/$defs/StyleRef",
"description": "The stub's style. See DISL 0.2, section 6.10."
},
"label": {
"description": "A label drawn along the stub. See DISL 0.2, section 6.10.",
"$ref": "#/$defs/Label"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}The refusals a node or edge notation declares per gesture it switches off (move, resize, reparent, delete, connect, reconnect, copy, editLabel), so that an attempted gesture on an element of that kind is answered with a sentence rather than silence. Each is an ordered list of Reasons, in the element context. See DISL 0.2, sections 6.9 and 6.10.
{
"type": "object",
"properties": {
"move": {
"description": "The refusal shown when a user attempts moving an element of this kind that the notation or placement does not allow: an ordered list of Reasons, of which the first that applies is shown. See DISL 0.2, section 6.9.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"resize": {
"description": "The refusal shown when a user attempts resizing an element of this kind that the notation or placement does not allow: an ordered list of Reasons, of which the first that applies is shown. See DISL 0.2, section 6.9.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"reparent": {
"description": "The refusal shown when a user attempts moving into another container an element of this kind that the notation or placement does not allow: an ordered list of Reasons, of which the first that applies is shown. See DISL 0.2, section 6.9.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"delete": {
"description": "The refusal shown when a user attempts deleting an element of this kind that the notation or placement does not allow: an ordered list of Reasons, of which the first that applies is shown. See DISL 0.2, section 6.9.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"connect": {
"description": "The refusal shown when a user attempts connecting an element of this kind that the notation or placement does not allow: an ordered list of Reasons, of which the first that applies is shown. See DISL 0.2, section 6.9.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"reconnect": {
"description": "The refusal shown when a user attempts reconnecting an end of an element of this kind that the notation or placement does not allow: an ordered list of Reasons, of which the first that applies is shown. See DISL 0.2, section 6.9.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"copy": {
"description": "The refusal shown when a user attempts copying an element of this kind that the notation or placement does not allow: an ordered list of Reasons, of which the first that applies is shown. See DISL 0.2, section 6.9.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"editLabel": {
"description": "The refusal shown when a user attempts editing the label of an element of this kind that the notation or placement does not allow: an ordered list of Reasons, of which the first that applies is shown. See DISL 0.2, section 6.9.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}How a connect gesture of one relation type starts, in an edge notation's connect: which anchors start it and which end the dragged-from node becomes, so that the anchor used chooses the direction, and the tool whose settings apply. See DISL 0.2, section 6.10.
{
"type": "object",
"properties": {
"from": {
"description": "The anchors (AnchorSpec point ids) from which a connect gesture of this relation type starts, each mapped to the end the node dragged from becomes; absent means every anchor, as source (0.1). An anchor not listed does not start one. See DISL 0.2, section 6.10.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"enum": [
"source",
"target"
]
}
},
"tool": {
"description": "The library tool whose mode, initial, createSource and createTarget apply to a gesture started from an anchor. See DISL 0.2, section 6.10.",
"$ref": "#/$defs/SimpleId"
},
"pointer": {
"description": "The pointer button, modifiers and start area of the gesture; absent means the primary button from an anchor, as in 0.2. See DISL 0.3, section 6.10.",
"$ref": "#/$defs/GesturePointer"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}The pointer binding of a connect gesture: the button and modifier keys that start it, and whether it starts from an anchor or anywhere on the node's body. See DISL 0.3, section 6.10.
{
"type": "object",
"properties": {
"button": {
"description": "The pointer button that starts the gesture; default primary. See DISL 0.3, section 6.10.",
"enum": [
"primary",
"secondary",
"middle"
]
},
"start": {
"description": "anchor (the default): the gesture starts from an anchor or port; body: from anywhere on the node's body. See DISL 0.3, section 6.10.",
"enum": [
"anchor",
"body"
]
},
"modifiers": {
"description": "Keys that must be held for the gesture to start, spelled as Modifier is. See DISL 0.3, section 6.10.",
"type": "array",
"items": {
"enum": [
"Alt",
"Shift",
"Ctrl",
"Meta"
]
},
"uniqueItems": true
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A band of text rows drawn between the canvas title and the drawing surface, outside it: not an element, not selectable, draggable or deletable, and not part of layout; the surface's origin is below it. See DISL 0.2, section 6.13.
{
"type": "object",
"properties": {
"rows": {
"type": "array",
"items": {
"$ref": "#/$defs/Label"
},
"description": "The rows, labels with self bound to the diagram. See DISL 0.2, section 6.13."
},
"style": {
"$ref": "#/$defs/StyleRef",
"description": "The band's style. See DISL 0.2, section 6.13."
},
"visible": {
"$ref": "#/$defs/BBool",
"description": "Whether the band is shown; defaults to true. See DISL 0.2, section 6.13."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A status notice drawn outside the drawing surface, such as a truncation banner, with its text, severity, position, visibility and buttons. A notice is not an element; notices stack in declaration order per position. Each truncating budget contributes a built-in notice budget:<id>, and a parse failure the built-in unavailable. See DISL 0.2, section 6.13.Shown as written in the source.
{
"type": "object",
"properties": {
"id": {
"description": "The notice's id: a simple identifier, or budget:<id> naming a declared budget. A declared notice with the id of a built-in one (budget:<id> or unavailable) replaces it, and is shown only while the built-in one would be. See DISL 0.2, section 6.13.",
"anyOf": [
{
"$ref": "#/$defs/SimpleId"
},
{
"type": "string",
"pattern": "^budget:[A-Za-z_][A-Za-z0-9_]*$"
}
]
},
"text": {
"description": "The notice's text, in the chrome context. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/Message"
},
"severity": {
"enum": [
"info",
"warning",
"error"
],
"description": "Styles the notice; defaults to info. See DISL 0.2, section 6.13."
},
"position": {
"enum": [
"top",
"bottom",
"top-left",
"top-right",
"bottom-left",
"bottom-right"
],
"description": "Where the notice sits, anchored to the surface outside the drawing; defaults to top. See DISL 0.2, section 6.13."
},
"visible": {
"description": "Whether the notice is shown, in the chrome context; defaults to true. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/BBool"
},
"actions": {
"type": "array",
"description": "Buttons, each running an operation. See DISL 0.2, section 6.13.",
"items": {
"type": "object",
"properties": {
"label": {
"$ref": "#/$defs/Message",
"description": "The button's label. See DISL 0.2, section 6.13."
},
"operation": {
"$ref": "#/$defs/SimpleId",
"description": "The operation the button runs. See DISL 0.2, section 6.13."
},
"args": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Expression"
},
"description": "Values of the operation's parameters, in the chrome context. See DISL 0.2, section 6.13."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"label",
"operation"
],
"patternProperties": {
"^x-": true
}
}
},
"dismissible": {
"type": "boolean",
"description": "Whether the viewer may close it; the dismissal is viewer state. Defaults to false. See DISL 0.2, section 6.13."
},
"style": {
"$ref": "#/$defs/StyleRef",
"description": "The notice's style. See DISL 0.2, section 6.13."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"id",
"text"
],
"patternProperties": {
"^x-": true
}
}A user filter on the canvas, in canvas.filters: a control whose value is viewer state and a keep condition deciding which elements of the types it applies to stay drawn. Filtering never changes the model, findings or undo. See DISL 0.2, section 6.13.1.
{
"type": "object",
"properties": {
"label": {
"description": "Shown on the control; defaults to the id. See DISL 0.2, section 6.13.1.",
"$ref": "#/$defs/Message"
},
"control": {
"enum": [
"chips",
"switch",
"select",
"search"
],
"description": "The control: chips (a list of chosen values), switch (a bool), select (one of options) or search (free text). See DISL 0.2, section 6.13.1."
},
"appliesTo": {
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
},
"description": "The types the filter can hide; others always stay. Defaults to every node type. See DISL 0.2, section 6.13.1."
},
"options": {
"description": "The values offered by chips and select, a list in the filter context without self. See DISL 0.2, section 6.13.1.",
"$ref": "#/$defs/CelValue"
},
"default": {
"description": "The value a viewer starts with, a literal or {cel}; defaults to [], false or an empty string by control. See DISL 0.2, section 6.13.1."
},
"match": {
"description": "For chips: whether an element must match any or all chosen values, and whether the viewer may switch; defaults to any, switchable. See DISL 0.2, section 6.13.1.",
"type": "object",
"properties": {
"default": {
"enum": [
"any",
"all"
],
"description": "Whether an element must match any (the default) or all chosen values. See DISL 0.2, section 6.13.1."
},
"userToggle": {
"type": "boolean",
"description": "Whether the viewer may switch between any and all; defaults to true. See DISL 0.2, section 6.13.1."
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"keep": {
"description": "True when self stays drawn, in the filter context (self, value, match, diagram, env). See DISL 0.2, section 6.13.1.",
"$ref": "#/$defs/Expression"
},
"effect": {
"enum": [
"hide",
"dim"
],
"description": "hide (the default) leaves filtered-out elements undrawn, with their relations; dim applies the filteredOut state. See DISL 0.2, section 6.13.1."
},
"position": {
"description": "Where the control sits, outside the drawing surface. See DISL 0.2, section 6.13.1.",
"$ref": "#/$defs/Position"
},
"persist": {
"type": "boolean",
"description": "The value is view data of the kind filters, stored with the diagram and the same for every viewer, rather than viewer state; changing it is an edit. filters must then be in view.store. Defaults to false. See DISL 0.4, section 6.13.1."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"control",
"keep"
],
"patternProperties": {
"^x-": true
}
}The message drawn centred on an empty canvas, outside the drawing; the toolbox and empty-canvas gestures stay available. See DISL 0.2, section 6.13.
{
"type": "object",
"properties": {
"text": {
"description": "The message, in the chrome context. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/Message"
},
"when": {
"description": "When the message is shown; defaults to the view drawing no element after viewpoint membership and derived elements. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/Expression"
},
"style": {
"$ref": "#/$defs/StyleRef",
"description": "The message's style. See DISL 0.2, section 6.13."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"text"
],
"patternProperties": {
"^x-": true
}
}Legend entries computed per drawn element: one entry per distinct key, with its label and swatch taken from the first element of the group. See DISL 0.2, section 6.13.
{
"type": "object",
"properties": {
"key": {
"description": "Groups drawn elements into one entry, in the legend context. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/Expression"
},
"label": {
"description": "The entry's text, evaluated on the first element of each group. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/Message"
},
"swatch": {
"description": "The entry's swatch, evaluated on the first element of each group. See DISL 0.2, section 6.13.",
"type": "object",
"properties": {
"shape": {
"$ref": "#/$defs/ShapeRef",
"description": "The swatch's shape. See DISL 0.2, section 6.13."
},
"fill": {
"$ref": "#/$defs/Paint",
"description": "The swatch's fill. See DISL 0.2, section 6.13."
},
"stroke": {
"$ref": "#/$defs/Paint",
"description": "The swatch's outline colour. See DISL 0.2, section 6.13."
},
"icon": {
"$ref": "#/$defs/IconRef",
"description": "The swatch's icon. See DISL 0.2, section 6.13."
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"order": {
"description": "The sort key of the entries; defaults to first appearance in persistence order. See DISL 0.2, section 6.13.",
"$ref": "#/$defs/Expression"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"key"
],
"patternProperties": {
"^x-": true
}
}How text is measured at layout time: host, the host's font metrics (the default, 0.1), or an average advance per counted character. CEL textWidth and textHeight use it, and so every layout input computed with them, so that every runtime and headless layout computes the same layout; drawing measures with the real font. See DISL 0.3, section 6.5.
{
"anyOf": [
{
"const": "host"
},
{
"type": "object",
"properties": {
"kind": {
"const": "average",
"description": "average: every character advances by the same fraction of the font size. See DISL 0.2, section 6.5."
},
"advance": {
"type": "number",
"exclusiveMinimum": 0,
"description": "The width of one character, as a fraction of the font size. See DISL 0.2, section 6.5."
},
"count": {
"enum": [
"utf16",
"codepoint",
"grapheme"
],
"description": "What a character is. See DISL 0.2, section 6.5."
},
"lineHeight": {
"type": "number",
"exclusiveMinimum": 0,
"description": "The line height, as a multiple of the font size. See DISL 0.2, section 6.5."
}
},
"additionalProperties": false,
"required": [
"kind",
"advance"
],
"patternProperties": {
"^x-": true
}
}
]
}The node a create-edge tool creates when a connect gesture is released on empty canvas, in createSource or createTarget: its type, initial attribute values and size. Creating the end, the relation, their hooks and snapping is one transaction and one undo step. See DISL 0.2, section 7.2.
{
"type": "object",
"properties": {
"type": {
"description": "The node type created for the missing end. See DISL 0.2, section 7.2.",
"$ref": "#/$defs/TypeRef"
},
"initial": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"description": "Initial attribute values, literals or {cel} in the create context, where position is the release point, parent the container under it and other the existing end. See DISL 0.2, section 7.2."
},
"size": {
"description": "The created node's size. See DISL 0.2, section 7.2.",
"$ref": "#/$defs/Size"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"type"
],
"patternProperties": {
"^x-": true
}
}A tool's drop table (mode drop): a list of drop targets tried in order against the element under the drop point, and what a drop that none matches does. A tool without drop behaves as in 0.1. See DISL 0.2, section 7.2.
{
"type": "object",
"properties": {
"targets": {
"type": "array",
"items": {
"$ref": "#/$defs/DropTarget"
},
"description": "Tried in order against the element under the drop point; the first whose on matches runs as one transaction. See DISL 0.2, section 7.2."
},
"elsewhere": {
"enum": [
"create",
"ignore",
"refuse",
"menu"
],
"description": "What a drop that no target matches does: create the tool's own type at the drop point (the default), ignore it, refuse it with refusal, or open the diagram context menu at the drop point. See DISL 0.2, section 7.2."
},
"refusal": {
"description": "The refusal shown for elsewhere: refuse; context diagram, env, dropTarget and position. See DISL 0.2, section 7.2.",
"$ref": "#/$defs/Reason"
},
"place": {
"description": "A parent placement of behavior.placements that chooses where a drop creates the tool's element; with it, targets and elsewhere are not consulted. See DISL 0.3, section 7.2.",
"$ref": "#/$defs/SimpleId"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A parent placement in behavior.placements: chooses the parent of a new element by geometry among candidates, and its index among that parent's children. Evaluated in the parentPlacement context. See DISL 0.3, section 9.1.
{
"type": "object",
"properties": {
"candidates": {
"description": "The elements that may become the parent, a list of Element. See DISL 0.3, section 9.1.",
"$ref": "#/$defs/Expression"
},
"as": {
"description": "The name each candidate is bound to in rank; default candidate. See DISL 0.3, section 9.1.",
"$ref": "#/$defs/SimpleId"
},
"rank": {
"description": "A number per candidate; the lowest wins, the first in model order on a tie. See DISL 0.3, section 9.1.",
"$ref": "#/$defs/Expression"
},
"index": {
"description": "The new element's index among the chosen parent's children, with parent bound; clamped to their number; default after the last. See DISL 0.3, section 9.1.",
"$ref": "#/$defs/Expression"
},
"whenEmpty": {
"description": "With no candidate: root creates the element at the top level when the diagram has no top-level element candidates could return; refuse (the default) refuses with refusal. See DISL 0.3, section 9.1.",
"enum": [
"root",
"refuse"
]
},
"refusal": {
"description": "The refusal when no parent is chosen. See DISL 0.3, section 9.1.",
"$ref": "#/$defs/Reason"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"candidates",
"rank"
],
"patternProperties": {
"^x-": true
}
}One entry of a tool's drop table: a context tool of any kind plus on, the types of element under the drop point (or canvas) it applies to. Its self is the drop target, the diagram for canvas, and position is the drop point. See DISL 0.2, section 7.2.
{
"type": "object",
"properties": {
"on": {
"description": "What the entry applies to: node types under the drop point (with their subtypes) and/or the keyword canvas for empty canvas. See DISL 0.2, section 7.2.",
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/$defs/TypeRef"
},
{
"const": "canvas"
}
]
},
"minItems": 1
},
"kind": {
"enum": [
"create-connected",
"connect",
"create-child",
"operation",
"delete",
"duplicate",
"editLabel",
"openForm",
"plugin",
"moveUp",
"moveDown"
]
},
"creates": {
"$ref": "#/$defs/TypeRef"
},
"via": {
"$ref": "#/$defs/TypeRef"
},
"direction": {
"enum": [
"outgoing",
"incoming"
]
},
"slot": {
"type": "string"
},
"operation": {
"type": "string"
},
"plugin": {
"$ref": "#/$defs/PluginCall"
},
"label": {
"description": "The entry's label, a Message evaluated for the element it is shown on (and item and index inside forEach) each time it is presented. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Message"
},
"icon": {
"$ref": "#/$defs/IconRef"
},
"shortcut": {
"type": "string"
},
"enabled": {
"$ref": "#/$defs/Expression"
},
"visible": {
"description": "Whether the entry is offered at all; an entry that is not visible is not shown, while an unavailable one is shown disabled. Element context. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Expression"
},
"unavailable": {
"description": "Reasons that, while one applies, show the entry disabled with that reason and refuse it; an entry that runs an operation also inherits the operation's. Element context. See DISL 0.2, section 7.3.",
"type": "array",
"items": {
"$ref": "#/$defs/Reason"
}
},
"position": {
"$ref": "#/$defs/Position"
},
"target": {
"enum": [
"drag",
"pick",
"either"
],
"description": "How the other end of a connect or create-connected entry is chosen: drag (the default and the 0.1 behaviour), pick from a list of candidates, or either. See DISL 0.2, section 7.3."
},
"candidates": {
"description": "The elements a picker offers, a list in the element context; defaults to every element the relation's ends and prevent-constraints admit. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Expression"
},
"candidateLabel": {
"description": "The text of each picker row, with item bound; defaults to item.label(). See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Message"
},
"pickerTitle": {
"description": "The picker's title; defaults to the entry's label. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Message"
},
"emptyText": {
"description": "Shown when there are no candidates, as the reason the entry is unavailable. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Message"
},
"forEach": {
"description": "A list; the entry is produced once per item, in list order, with item (or the as name) and index bound in its label, visible, enabled, unavailable, args and icon. An empty list produces no entry. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Expression"
},
"as": {
"description": "The name item is bound as inside forEach; defaults to item. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/SimpleId"
},
"args": {
"description": "Values of the invoked operation's parameters, from parameter name to Expression; when they give every required parameter, no parameter dialog opens. See DISL 0.2, section 7.3.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"$ref": "#/$defs/Expression"
}
},
"submenu": {
"description": "Groups the entries generated by forEach under one submenu with this label. See DISL 0.2, section 7.3.",
"$ref": "#/$defs/Message"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"on",
"kind"
],
"patternProperties": {
"^x-": true
}
}How a form item accepts typed text: accepts decides whether the text is taken, write turns it into attribute values as one transaction, and refusal is shown otherwise. value is bound to the entered text. Form context. See DISL 0.3, section 7.5.
{
"type": "object",
"properties": {
"accepts": {
"description": "Whether the entered text, value, is accepted. See DISL 0.3, section 7.5.",
"$ref": "#/$defs/Expression"
},
"write": {
"description": "Run as one transaction when the text is accepted. See DISL 0.3, section 7.5.",
"type": "array",
"items": {
"$ref": "#/$defs/Action"
}
},
"refusal": {
"description": "Shown when accepts is false. See DISL 0.3, section 7.5.",
"$ref": "#/$defs/Message"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"accepts",
"write",
"refusal"
],
"patternProperties": {
"^x-": true
}
}The settings of one built-in constraint, in constraints.builtIn keyed by its id such as std.references: its severity, whether it is enabled, the code its findings report, the message of its findings, which may be computed from detail, and the refusal it shows when it refuses a gesture, which may be computed from violation, and (DISL 0.3) whether a group of duplicates is reported once. See DISL 0.3, section 8.1.
{
"type": "object",
"properties": {
"severity": {
"enum": [
"error",
"warning",
"info",
"hint"
],
"description": "Re-rates the built-in. See DISL 0.2, section 8.1."
},
"enabled": {
"type": "boolean",
"description": "Switches the built-in off; defaults to true. See DISL 0.2, section 8.1."
},
"code": {
"description": "The code findings of this built-in report, such as timeline.dangling-connection; or {cel} evaluated per finding in the constraint context plus detail, returning such a code. See DISL 0.3, section 8.1.",
"anyOf": [
{
"$ref": "#/$defs/QualifiedId"
},
{
"$ref": "#/$defs/CelValue"
}
]
},
"message": {
"description": "The message of this built-in's findings, in place of the runtime's, in the constraint context plus detail (the keys each built-in lists in 8.7). See DISL 0.2, section 8.1.",
"$ref": "#/$defs/Message"
},
"refusal": {
"description": "The refusal this built-in shows when it refuses a gesture, in place of the runtime's, in that gesture's context plus violation (the keys 8.4 lists per built-in). Without it a refusal is worded by the runtime, never taken from message. See DISL 0.2, section 8.4.",
"$ref": "#/$defs/Message"
},
"oncePerGroup": {
"enum": [
"second",
"last"
],
"description": "Reports a group of duplicates once, at its second or its last member, rather than at every member after the first: the holders of one id for std.duplicateId, a repeat that allowParallel false forbids for std.endpoints. No effect on any other built-in or case. See DISL 0.3, section 8.1."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}A place in a file of the model, which findings and the reader's element locations carry: file, relative to the diagram's subject as FBL defines it and separated by /, and optionally a line, a column and a length. line and column are 1-based; column and length count Unicode code points; column requires line and length requires column. Without a line the location is the whole file. See DISL 0.2, section 8.6.
{
"type": "object",
"properties": {
"file": {
"type": "string",
"minLength": 1,
"description": "The file, relative to the diagram's subject, with / separators. See DISL 0.2, section 8.6."
},
"line": {
"type": "integer",
"minimum": 1,
"description": "The 1-based line. See DISL 0.2, section 8.6."
},
"column": {
"type": "integer",
"minimum": 1,
"description": "The 1-based column, counted in Unicode code points. See DISL 0.2, section 8.6."
},
"length": {
"type": "integer",
"minimum": 0,
"description": "The length of the located text, in Unicode code points. See DISL 0.2, section 8.6."
}
},
"additionalProperties": false,
"required": [
"file"
],
"dependentRequired": {
"column": [
"line"
],
"length": [
"column"
]
},
"patternProperties": {
"^x-": true
}
}One finding as a headless validator writes it, an item of ValidatorOutput. A finding (DISL 0.1 called it a problem) is the result of a rule or of the reader; this JSON form keeps the 0.1 keys constraintId (the finding's constraint), severity, message, elementId, attribute and pointer, and adds code, elementIds (the finding's target), location, subject and view. See DISL 0.2, section 8.6.
{
"type": "object",
"properties": {
"constraintId": {
"description": "The id of the rule that raised the finding: a declared constraint's id or a built-in id such as std.unparseable. Suppressions are keyed by it. See DISL 0.2, section 8.6.",
"$ref": "#/$defs/QualifiedId"
},
"code": {
"description": "The code the rule reports to users and tools, when it declares one, such as databricks.duplicate-task-key. See DISL 0.2, section 8.6.",
"$ref": "#/$defs/QualifiedId"
},
"severity": {
"enum": [
"error",
"warning",
"info",
"hint"
],
"description": "The finding's severity. See DISL 0.2, section 8.6."
},
"message": {
"type": "string",
"description": "The message, evaluated and localized. See DISL 0.2, section 8.6."
},
"elementId": {
"type": "string",
"description": "The 0.1 key: the id of the first element the finding is about; equal to the first of elementIds when either is present. See DISL 0.2, section 8.6."
},
"elementIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "The ids of every element the finding is about, in order. See DISL 0.2, section 8.6."
},
"attribute": {
"type": "string",
"description": "The attribute the finding is about. See DISL 0.2, section 8.6."
},
"location": {
"description": "Where in the model's files the finding is. See DISL 0.2, section 8.6.",
"$ref": "#/$defs/SourceLocation"
},
"subject": {
"type": "string",
"description": "A display string naming something that is not drawn, such as a triple or a key path; never resolved as an id. See DISL 0.2, section 8.6."
},
"view": {
"type": "string",
"description": "The id of the view a finding of an over: view rule belongs to. See DISL 0.2, section 8.6."
},
"pointer": {
"type": "string",
"description": "The JSON Pointer of the record of a DID definition the finding is about; absent when location names a file that is not a DID definition. See DISL 0.2, section 8.6."
}
},
"additionalProperties": false,
"required": [
"constraintId",
"severity",
"message"
],
"patternProperties": {
"^x-": true
}
}What a headless validator writes: a JSON array of findings in the normative order of findings. The object form, with the same array under findings and an optional $schema, lets a stored example name this schema. See DISL 0.2, section 8.6.
{
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/$defs/Finding"
}
},
{
"type": "object",
"properties": {
"$schema": {
"type": "string",
"description": "The schema the stored output names. See DISL 0.2, section 8.6."
},
"findings": {
"type": "array",
"items": {
"$ref": "#/$defs/Finding"
},
"description": "The findings, in the normative order of findings. See DISL 0.2, section 8.6."
}
},
"additionalProperties": false,
"required": [
"findings"
],
"patternProperties": {
"^x-": true
}
}
]
}A simulated run played over time, the third body of an operation beside actions and plugin: each step computes every taking-part element's state from the previous step's. It runs outside any transaction; its writes never enter undo, mark the document modified, persist, fire hooks or reach constraints, and any committed change ends the run. See DISL 0.2, section 9.6.
{
"type": "object",
"properties": {
"for": {
"description": "The element types that take part. See DISL 0.2, section 9.6.",
"$ref": "#/$defs/TypeRefs"
},
"state": {
"description": "A transient (or viewer) attribute declared on each of those types: the only thing a simulation writes. See DISL 0.2, section 9.6.",
"$ref": "#/$defs/SimpleId"
},
"initial": {
"description": "Each element's state at step 0, in the simulation context. See DISL 0.2, section 9.6.",
"$ref": "#/$defs/Expression"
},
"next": {
"description": "Each element's state at the next step, evaluated against the previous step's states (simultaneous update), in the simulation context (self, state, step, p, diagram, env). See DISL 0.2, section 9.6.",
"$ref": "#/$defs/Expression"
},
"until": {
"description": "Evaluated after each step; the run finishes when it is true. See DISL 0.2, section 9.6.",
"$ref": "#/$defs/Expression"
},
"stepMs": {
"type": "integer",
"minimum": 0,
"description": "The time between steps in milliseconds; defaults to 700. See DISL 0.2, section 9.6."
},
"maxSteps": {
"type": "integer",
"minimum": 1,
"description": "A hard stop; defaults to 1000. See DISL 0.2, section 9.6."
},
"notice": {
"description": "The status notice shown while the simulation runs and after it finishes; dismissing it ends the run and clears the states. See DISL 0.2, section 9.6.",
"type": "object",
"properties": {
"running": {
"description": "The notice shown while the run plays. See DISL 0.2, section 9.6.",
"$ref": "#/$defs/Message"
},
"finished": {
"description": "The notice shown after it finishes. See DISL 0.2, section 9.6.",
"$ref": "#/$defs/Message"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"for",
"state",
"initial",
"next",
"until"
],
"patternProperties": {
"^x-": true
}
}A confirmation asked before a deletion, an operation or a button runs, in the object form of confirm. It holds the question, a title, the labels of both buttons, whether the confirming one is dangerous, and when to ask: only while when holds and, if count is given, count >= threshold. A plain Message in confirm is a Confirmation with only a message, which asks every time as in 0.1. See DISL 0.2, section 9.5.
{
"type": "object",
"properties": {
"message": {
"description": "The question asked; it may use count. See DISL 0.2, section 9.5.",
"$ref": "#/$defs/Message"
},
"title": {
"description": "The dialog title; defaults to the operation's label, or Delete for a deletion. See DISL 0.2, section 9.5.",
"$ref": "#/$defs/Message"
},
"confirmLabel": {
"description": "The label of the confirming button; defaults to the runtime's own. See DISL 0.2, section 9.5.",
"$ref": "#/$defs/Message"
},
"cancelLabel": {
"description": "The label of the cancelling button; defaults to the runtime's own. See DISL 0.2, section 9.5.",
"$ref": "#/$defs/Message"
},
"danger": {
"type": "boolean",
"description": "Whether the confirming button is styled as destructive; defaults to true for a deletion and false otherwise. See DISL 0.2, section 9.5."
},
"when": {
"description": "Ask only while this holds; absent means always. See DISL 0.2, section 9.5.",
"$ref": "#/$defs/Expression"
},
"count": {
"description": "An integer the confirmation is about, bound as count in its texts, such as the number of nodes under a branch. See DISL 0.2, section 9.5.",
"$ref": "#/$defs/Expression"
},
"threshold": {
"type": "integer",
"minimum": 0,
"description": "Ask only when count >= threshold; defaults to 0, so a confirmation asks every time unless raised. Ignored without count. See DISL 0.2, section 9.5."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"message"
],
"patternProperties": {
"^x-": true
}
}The options of the rowPacked algorithm: elements keep their rows and are packed along the main axis in order, gap apart, with connected targets after their sources. See DISL 0.3, section 10.1.
{
"type": "object",
"properties": {
"keepRows": {
"description": "States that rows are kept; rowPacked never changes an element's row. See DISL 0.3, section 10.1.",
"const": true
},
"order": {
"description": "The order within a row: start, by the element's start along the packed axis as its base placement gives it; document, model order. See DISL 0.3, section 10.1.",
"enum": [
"start",
"document"
]
},
"gap": {
"description": "The least distance between two elements on a row, in canvas units. See DISL 0.3, section 10.1.",
"type": "number",
"minimum": 0
},
"followConnections": {
"description": "A relation type whose targets start no earlier than the targetAfter point of their source. See DISL 0.3, section 10.1.",
"$ref": "#/$defs/TypeRef"
},
"targetAfter": {
"description": "The point of a source a target starts after; default sourceEnd. See DISL 0.3, section 10.1.",
"enum": [
"sourceStart",
"sourceMiddle",
"sourceEnd"
]
},
"rowsCovered": {
"description": "The number of rows an element covers from its own row, in the element context; default 1. See DISL 0.3, section 10.1.",
"$ref": "#/$defs/Expression"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"order",
"gap"
],
"patternProperties": {
"^x-": true
}
}The options of the rows algorithm: assigns rows only, writing the attributes in writes; the fewest rows the extents allow when every extent covers one row, and a row covered by a taller extent is never swapped. See DISL 0.3, section 10.2.
{
"type": "object",
"properties": {
"writes": {
"description": "The attributes the algorithm writes, the row first; it changes nothing else. See DISL 0.3, section 10.2.",
"type": "array",
"items": {
"$ref": "#/$defs/SimpleId"
},
"minItems": 1,
"uniqueItems": true
},
"extent": {
"description": "Per type, the extent an element occupies on its row: from and to along the main axis, and the rows it covers from its own row down. In the layoutExtent context; an element whose extent does not evaluate does not take part. See DISL 0.3, section 10.2.",
"type": "object",
"propertyNames": {
"$ref": "#/$defs/TypeRef"
},
"additionalProperties": {
"description": "The extent of one type's elements. See DISL 0.3, section 10.2.",
"type": "object",
"properties": {
"from": {
"$ref": "#/$defs/GeomExpr"
},
"to": {
"$ref": "#/$defs/GeomExpr"
},
"rows": {
"$ref": "#/$defs/GeomExpr"
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"from",
"to"
],
"patternProperties": {
"^x-": true
}
}
},
"clearance": {
"description": "The least distance between two extents on one row, in canvas units; default 0. See DISL 0.3, section 10.2.",
"type": "number",
"minimum": 0
},
"affinity": {
"description": "A relation type that draws linked elements to nearby rows. See DISL 0.3, section 10.2.",
"$ref": "#/$defs/TypeRef"
},
"ties": {
"description": "Between two equally near free rows, lower takes the smaller row number (the default), upper the larger. See DISL 0.3, section 10.2.",
"enum": [
"lower",
"upper"
]
},
"swapPasses": {
"description": "The most passes of neighbouring-row swaps; default 0. See DISL 0.3, section 10.2.",
"type": "integer",
"minimum": 0
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"writes",
"extent"
],
"patternProperties": {
"^x-": true
}
}The options of the tidyTree algorithm: a tidy tree in model order, with optional stored rows and drag behaviour. See DISL 0.3, section 10.3.
{
"type": "object",
"properties": {
"order": {
"description": "children: each element's children in their model order. See DISL 0.3, section 10.3.",
"enum": [
"children"
]
},
"parentAlign": {
"description": "A parent centred over its first and last child (firstLastCentre, the default) or over its children's extent (childrenCentre). See DISL 0.3, section 10.3.",
"enum": [
"firstLastCentre",
"childrenCentre"
]
},
"origin": {
"description": "leftmostAtZero (the default) shifts the layout so its leftmost node is at 0; rootAtZero puts the first root's position at 0. See DISL 0.3, section 10.3.",
"enum": [
"leftmostAtZero",
"rootAtZero"
]
},
"rows": {
"description": "Stored main-axis positions shared by siblings. See DISL 0.3, section 10.3.",
"type": "object",
"properties": {
"stored": {
"description": "none (the default): every position is computed; y: the top-level elements, and all children of one parent, share one stored main-axis position. See DISL 0.3, section 10.3.",
"enum": [
"none",
"y"
]
},
"minGap": {
"description": "The least gap between a parent's far edge on the main axis and the near edge of its children's row, in canvas units. See DISL 0.3, section 10.3.",
"type": "number",
"minimum": 0
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"drag": {
"description": "What dragging an element does. See DISL 0.3, section 10.3.",
"type": "object",
"properties": {
"carry": {
"description": "subtree: everything beneath moves with the dragged element; node: it moves alone. See DISL 0.3, section 10.3.",
"enum": [
"subtree",
"node"
]
},
"across": {
"description": "reorder: dropped past a sibling's centre, the element is reordered among its siblings in the model. See DISL 0.3, section 10.3.",
"enum": [
"reorder",
"none"
]
},
"down": {
"description": "row: the dropped main-axis position is stored for the row and everything beneath it. See DISL 0.3, section 10.3.",
"enum": [
"row",
"none"
]
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}The options of the force layout: tiers lists node types from the centre outwards, each entry one ring (a list puts several types on one ring), and gap is the least distance between the bounds of any two nodes. Its result keeps tiers in order, has no overlap, leaves pinned nodes where they are, is the same for the same input, moves little on a live change and is never written. See DISL 0.4, section 10.4.
{
"type": "object",
"properties": {
"tiers": {
"type": "array",
"items": {
"anyOf": [
{
"$ref": "#/$defs/TypeRef"
},
{
"type": "array",
"items": {
"$ref": "#/$defs/TypeRef"
},
"minItems": 1
}
]
},
"minItems": 1
},
"gap": {
"type": "number",
"minimum": 0
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
}
}How elements get their ids, in persistence.ids: the default strategy for every type (the 0.1 properties strategy, prefix, expression, stable and pattern, plus encoding, ephemeral, reason and suffix), per-type rules in types, what happens to missing ids on reading, and how ids are compared. Nodes, relations and views share one id space; of elements sharing an id the first in reading order keeps it. See DISL 0.2, section 11.5.
{
"type": "object",
"properties": {
"strategy": {
"enum": [
"uuid-v4",
"uuid-v7",
"ulid",
"nanoid",
"sequential",
"natural",
"cel",
"derived"
],
"description": "How ids are made: the 0.1 generation strategies, or derived, whose id is the value of expression evaluated in the identity context and recomputed after reading and at the end of every transaction. See DISL 0.2, section 11.5."
},
"encoding": {
"enum": [
"hex",
"base64url",
"base36"
],
"description": "The text form of uuid-v4 and uuid-v7 ids: hex (the 0.1 form, the default), base64url (22 characters) or base36 (25 characters); ids stay opaque strings. See DISL 0.2, section 11.5."
},
"prefix": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": {
"type": "string"
}
}
],
"description": "Prepended to generated ids, one string, or at the top level a map from type to string (0.1); not applied to cel or derived results. See DISL 0.2, section 11.5."
},
"expression": {
"description": "The id, a string: required for cel (evaluated once, on creation, in the create context) and for derived (in the identity context). See DISL 0.2, section 11.5.",
"$ref": "#/$defs/Expression"
},
"stable": {
"type": "boolean",
"description": "Ids never change once assigned, even if natural keys change. Defaults to true. Has no effect on derived ids, which always follow their expression. See DISL 0.2, section 11.5."
},
"ephemeral": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/$defs/Expression"
}
],
"description": "Whether the id identifies the element within one reading of the model only: a boolean, or an Expression evaluated in the identity context. An ephemeral element is never stored as view data, a style override, a suppression or a reference. Defaults to false. See DISL 0.2, section 11.5."
},
"reason": {
"description": "The refusal shown when a gesture would store an ephemeral id, in the element context with self bound to the ephemeral element; defaults to the runtime's sentence. See DISL 0.2, section 11.5.",
"$ref": "#/$defs/Reason"
},
"pattern": {
"type": "string",
"description": "The allowed id syntax; defaults to ^[A-Za-z0-9_.:#-]{1,128}$. See DISL 0.2, section 11.5."
},
"suffix": {
"type": "string",
"description": "How a generated cel or natural id is made unique: {n} is replaced by the smallest integer n >= 2 that makes it unique. Defaults to -{n}. See DISL 0.2, section 11.5."
},
"types": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/QualifiedId"
},
"additionalProperties": {
"$ref": "#/$defs/IdRule"
},
"description": "Per-type id rules, keyed by type reference; each overrides the default for that type and its subtypes that have no rule of their own. See DISL 0.2, section 11.5."
},
"missing": {
"enum": [
"assign",
"ephemeral"
],
"description": "What a runtime does with an element read without a usable id: assign gives it a new id, written with the next save (the default); ephemeral treats it as ephemeral. See DISL 0.2, section 11.5."
},
"compare": {
"enum": [
"exact",
"ignore-case"
],
"description": "How ids are compared for lookups, references, duplicate detection and view keys: exact (the default) or ignore-case, by Unicode default case folding, keeping the first spelling read. See DISL 0.2, section 11.5."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"if": {
"required": [
"strategy"
],
"properties": {
"strategy": {
"enum": [
"cel",
"derived"
]
}
}
},
"then": {
"required": [
"expression"
]
}
}The id rule of one type in persistence.ids.types, overriding the default for that type and its subtypes (the nearest rule in the type's linearisation wins). It holds a strategy, including derived, whose expression runs in the identity context; the encoding of generated UUIDs; ephemeral, for ids that do not survive a re-reading, with the reason given when a gesture would store one; and prefix, stable, pattern and suffix as for the default. See DISL 0.2, section 11.5.
{
"type": "object",
"properties": {
"strategy": {
"enum": [
"uuid-v4",
"uuid-v7",
"ulid",
"nanoid",
"sequential",
"natural",
"cel",
"derived"
],
"description": "How ids are made: the 0.1 generation strategies, or derived, whose id is the value of expression evaluated in the identity context and recomputed after reading and at the end of every transaction. See DISL 0.2, section 11.5."
},
"encoding": {
"enum": [
"hex",
"base64url",
"base36"
],
"description": "The text form of uuid-v4 and uuid-v7 ids: hex (the 0.1 form, the default), base64url (22 characters) or base36 (25 characters); ids stay opaque strings. See DISL 0.2, section 11.5."
},
"prefix": {
"type": "string",
"description": "Prepended to ids generated for this type; not applied to cel or derived results. See DISL 0.2, section 11.5."
},
"expression": {
"description": "The id, a string: required for cel (evaluated once, on creation, in the create context) and for derived (in the identity context). See DISL 0.2, section 11.5.",
"$ref": "#/$defs/Expression"
},
"stable": {
"type": "boolean",
"description": "Ids never change once assigned, even if natural keys change. Defaults to true. Has no effect on derived ids, which always follow their expression. See DISL 0.2, section 11.5."
},
"ephemeral": {
"anyOf": [
{
"type": "boolean"
},
{
"$ref": "#/$defs/Expression"
}
],
"description": "Whether the id identifies the element within one reading of the model only: a boolean, or an Expression evaluated in the identity context. An ephemeral element is never stored as view data, a style override, a suppression or a reference. Defaults to false. See DISL 0.2, section 11.5."
},
"reason": {
"description": "The refusal shown when a gesture would store an ephemeral id, in the element context with self bound to the ephemeral element; defaults to the runtime's sentence. See DISL 0.2, section 11.5.",
"$ref": "#/$defs/Reason"
},
"pattern": {
"type": "string",
"description": "The allowed id syntax; defaults to ^[A-Za-z0-9_.:#-]{1,128}$. See DISL 0.2, section 11.5."
},
"suffix": {
"type": "string",
"description": "How a generated cel or natural id is made unique: {n} is replaced by the smallest integer n >= 2 that makes it unique. Defaults to -{n}. See DISL 0.2, section 11.5."
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"patternProperties": {
"^x-": true
},
"if": {
"required": [
"strategy"
],
"properties": {
"strategy": {
"enum": [
"cel",
"derived"
]
}
}
},
"then": {
"required": [
"expression"
]
}
}How one type of an FBL binding maps onto the metamodel, in persistence.typeMap. See DISL 0.3, section 11.2.
{
"type": "object",
"properties": {
"as": {
"description": "What the binding's entries of this type become: diagram (their attributes are the diagram's), header or unreadable (kept out of the model; unreadable ones reported by std.unreadableEntry), or a metamodel type. See DISL 0.3, section 11.2.",
"anyOf": [
{
"enum": [
"diagram",
"header",
"unreadable"
]
},
{
"$ref": "#/$defs/TypeRef"
}
]
},
"attributes": {
"description": "The binding's attribute names mapped to metamodel attributes; source and target make a reference attribute an end of a relation, id the element's id, and null leaves the attribute out of the model. Unlisted attributes keep their names. See DISL 0.3, section 11.2.",
"type": "object",
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
}
},
"hostAttributes": {
"description": "Attributes the binding reads and writes that are not attributes of the model. See DISL 0.3, section 11.2.",
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"as"
],
"patternProperties": {
"^x-": true
}
}Where one kind of view data is kept in a format binding's body: the binding type whose entries hold it, and the binding attributes that hold the element the entry is about (a reference by id), the position (x, y) of a pinned element, the group key and collapsed state of a group, or each kept filter's value. Entries of a bound type are not elements of the model. See DISL 0.4, section 11.6.
{
"type": "object",
"properties": {
"type": {
"type": "string"
},
"element": {
"type": "string"
},
"x": {
"type": "string"
},
"y": {
"type": "string"
},
"group": {
"type": "string"
},
"collapsed": {
"type": "string"
},
"values": {
"type": "object",
"propertyNames": {
"$ref": "#/$defs/SimpleId"
},
"additionalProperties": {
"type": "string"
}
},
"doc": {
"$ref": "#/$defs/Doc"
}
},
"additionalProperties": false,
"required": [
"type"
],
"patternProperties": {
"^x-": true
}
}A kind of view data: the 0.1 kinds a view may store (bounds, waypoints, anchors, labelOffsets, collapsed, zIndex, rotation, params, ports, viewport, guides, pinned, settings), groups (DISL 0.4: the collapse states of compartment groups), and the viewer kinds selection, filters and viewpoint; filters may be stored too when a filter has persist (DISL 0.4). persistence.view lists the kinds a view stores and the kinds each viewer holds; a kind may not be in both. See DISL 0.4, section 11.6.
{
"enum": [
"bounds",
"waypoints",
"anchors",
"labelOffsets",
"collapsed",
"zIndex",
"rotation",
"params",
"ports",
"viewport",
"guides",
"pinned",
"settings",
"groups",
"selection",
"filters",
"viewpoint"
]
}