# Operators

## :sum

Return the sum of a list of values:

``````{
":sum": [3, 5, 10]
}
``````

Is undefined if an element of the list is a string or an object.

## :product

Returns the product of a list of values:

``````{
":product": [12, 5]
}
``````

## :max

Returns the max of a list of values:

``````{
":max": [12, 5]
}
``````
``````{
":max": [
{ ":date": "2022-12-01" },
{ ":date": "2022-01-01" }
]
}
``````

Also works with date formats (check second tab).

## :min

Returns the min of a list of values:

``````{
":min": [12, 5]
}
``````
``````{
":min": [
{ ":date": "2022-12-01" },
{ ":date": "2022-01-01" }
]
}
``````

Also works with date formats (check second tab).

## :increasing

Returns true if the second value is higher than the first value provided in the list:

``````{
":increasing": [12, 5]
}
``````

# Logic

## :if :then :else

Evaluate expression in `:if`. Return `:then` if expression returns a trurthy value (eg: a string not empty is a truthy value), return `:else` otherwise.

``````{
":if": {},
":then": {},
":else": {}
}
``````

## :case :when

Evaluate a value and return the block associated with the value (in most language it corresponds to a switch):

``````{
":case": "{ data.my_key }",
":when": [
[
"val1",
{}
],
[
"val2",
{}
],
[
"val3",
{}
]
]
}
``````

## :defined

Returns `true` if the evaluated expression is defined (neither null nor undefined).

Example:

``````{
":defined": "{data.key}"
}
``````

## :cmp

Compare a value with an other value using a function.

The list of possible functions:

• `:eq` compares if the two elements are equal
• `:gt` compares if the first element is greater than the second one
• `:ge` compares if the first element is greater or equal to the second one
• `:lt` compares if the first element is lower than the second one
• `:le` compares if the first element is lower or equal to the second one
``````{
":cmp": "{data.my_var}",
":eq": 2 // could be "my_value"
}
``````

## :in

Evaluate if a value is present in a list:

``````{
":in": ["val1", ["val1", "val2"]]
}
``````

## :includes

Evaluate if a list contains a value:

``````{
":includes": [["val1", "val2"], "val1"]
}
``````

## :intersects

Evaluate of some elements from a list can be found in some elements from an other list:

``````{
":intersects": [["val1", "val2"], ["val1", "val3"]]
}
``````

## :not

Give the reverse boolean value of an expression:

``````{
":not": true
}
``````

## :true

Evaluate if an expression is true.

``````{
":true": "{data.my_var}"
}
``````

## :false

Evaluate if an expression is false.

``````{
":false": "{data.my_var}"
}
``````

## :every

Evaluate if all the expressions in the list return a truthy value

``````{
":every": [{":defined": "{data.my_var}"}, "{data.my_other_var}"]
}
``````

## :some

Evaluate if at least one of the expressions in the list return a truthy value

``````{
":some": [{":defined": "{data.my_var}"}, "{data.my_other_var}"]
}
``````

## :coalesce

Returns the first undefined value of an list:

``````{
":coalesce": [null, "{data.some_undefined_value}", "default value"]
}
``````

# List & loops

## :range

Return a list of integer from index_start to index_end:

``````{
":range": [index_start, index_end]
}
``````

`{":range": [4, 10]}` will return a value of `[4, 5, 6, 7, 8, 9]`.

## :array :fill

Create an array with a specified length and optionally fill it using an expression.

``````{
":array": 5,
":fill": {
"label": "Contact person {@position}",
"elements": []
}
}
``````

The following variables are accessible in the `:fill` context:

• `@first:` boolean, true if first item
• `@index`: current index, starting counting at 0
• `@position`: current position. Equals to index + 1
• `@last`: boolean, true if last item

## :map :to

Loop in a list and return an array evaluated for every element found.

``````{
":map": ["foo", "bar"],
":to": []
}
``````

It can also be:

``````{
"foo": {
":map": [
{"key1": "foo", "key2": "bar"},
{"key1": "ding", "key2": "dong"}
],
":to": [
"{@item.key1}"
]
}
``````

The following variables are accessible in the `:to` context:

• `@item`: the content of the current item
• `@first:` boolean, true if first item
• `@index`: current index, starting counting at 0
• `@position`: current position. Equals to index + 1
• `@last`: boolean, true if last item

# Objects

## :assign

Based on the list of objects provided, overwrite the keys of the current object with the later.

Example:

``````{
":assign": [
{
"key1": "foo",
"key2": "bar"
},
{
"key2": "foo2"
}
]
}
``````

Result:

``````{
"key1": "foo",
"key2": "foo2"
}
``````

## :object-entries

Transform an object into a list with the input evaluated in :`:as`. Optional argument :`:order-by`with value `key`or `value`.

Example:

``````{
"variables": [
{
"test_object": {
"gender": "female",
"given_name": "Olivia",
"family_name": "De Smet"
}
},
{
"test2": {
":object-entries": "{user}",
":as": {
"key": "{@value}",
"value": "{@key}"
}
},
"test": {
":object-entries": "{user}",
":as": "{@value}"
}
}
]
}
``````

Will return:

``````{
"test2": [
{
"key": "De Smet",
"value": "family_name"
},
{
"key": "female",
"value": "gender"
},
{
"key": "Olivia",
"value": "given_name"
}
],
"test": [
"De Smet",
"female",
"Olivia"
]
}
``````

What’s Next

in the next chapter we'll focus on the signature element.