From efdf13403db69753490b09a16d2b477a57114962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20Thei=C3=9Fen?= Date: Thu, 11 Jul 2024 15:03:22 +0200 Subject: [PATCH] Rebuild --- .../odata-url-conventions.html | 72 +++++++++---------- .../odata-url-conventions.md | 72 +++++++++---------- 2 files changed, 72 insertions(+), 72 deletions(-) diff --git a/docs/odata-url-conventions/odata-url-conventions.html b/docs/odata-url-conventions/odata-url-conventions.html index a68881cb..2640d2eb 100644 --- a/docs/odata-url-conventions/odata-url-conventions.html +++ b/docs/odata-url-conventions/odata-url-conventions.html @@ -1876,7 +1876,7 @@
OData-JSON, section 6. Non-transient entities can alternatively be represented through their resource path.

-

Example 107: determine the price of an adhoc-defined product

+

Example 108: determine the price of an adhoc-defined product

http://host/service/Price(Product=@p)?@p={"Color":"red"}
@@ -1894,15 +1894,15 @@
5.1.1.14.4 $it

Note: property names and property paths in $filter expressions nested within $expand are evaluated in the context of the declared type of the expanded navigation property, so property names and property paths for the current instance of the collection identified by the resource path MUST be prefixed with $it/.

The $it literal can also be used as a path prefix to invoke a bound function overload on the current instance within an expression. Function names without a path prefix refer to an unbound function overload.

-

Example 108: email addresses ending with .com assuming EmailAddresses is a collection of strings

+

Example 109: email addresses ending with .com assuming EmailAddresses is a collection of strings

http://host/service/Customers(1)/EmailAddresses?$filter=endswith($it,'.com')
-

Example 109: customers along with their orders that shipped to the same city as the customer’s address. The nested filter expression is evaluated in the context of Orders; $it allows referring to values in the outer context of Customers. Note: the nested filter condition could equivalently be expressed as $it/Address/City eq $this/ShipTo/City.

+

Example 110: customers along with their orders that shipped to the same city as the customer’s address. The nested filter expression is evaluated in the context of Orders; $it allows referring to values in the outer context of Customers. Note: the nested filter condition could equivalently be expressed as $it/Address/City eq $this/ShipTo/City.

http://host/service/Customers?$expand=Orders($filter=$it/Address/City eq ShipTo/City)
-

Example 110: products with at least 10 positive reviews. Model.PositiveReviews is a function bound to Model.Product returning a collection of reviews.

+

Example 111: products with at least 10 positive reviews. Model.PositiveReviews is a function bound to Model.Product returning a collection of reviews.

http://host/service/Products?$filter=$it/Model.PositiveReviews()/$count ge 10
@@ -1911,16 +1911,16 @@
5.1.1.14.5 $root

The $root literal can be used in expressions to refer to resources of the same service.

-

Example 111: all employees with the same last name as employee A1235

+

Example 112: all employees with the same last name as employee A1235

http://host/service/Employees?$filter=LastName eq $root/Employees('A1245')/LastName
-

Example 112: products ordered by a set of customers, where the set of customers is passed as a JSON array containing the resource paths from $root to each customer

+

Example 113: products ordered by a set of customers, where the set of customers is passed as a JSON array containing the resource paths from $root to each customer

http://host/service/ProductsOrderedBy(Customers=@c)
   ?@c=[$root/Customers('ALFKI'),$root/Customers('BLAUS')]
-

Example 113: function call returning the average rating of a given employee by their peers (employees in department D1)

+

Example 114: function call returning the average rating of a given employee by their peers (employees in department D1)

http://host/service/Employees('A1245')/self.AvgRating(RatedBy=@peers)
   ?@peers=$root/Employees/$filter(Department eq 'D1')
@@ -1930,7 +1930,7 @@
5.1.1.14.6 $this

The $this literal can be used in $filter and $orderby expressions nested within $expand and $select for collection-valued properties and navigation properties. It refers to the current instance of the collection.

-

Example 114: select only email addresses ending with .com

+

Example 115: select only email addresses ending with .com

http://host/service/Customers?$select=EmailAddresses($filter=endswith($this,'.com'))
@@ -1943,7 +1943,7 @@

-

Example 115: similar behavior whether HeadquarterAddress is a nullable complex type or a nullable navigation property

+

Example 116: similar behavior whether HeadquarterAddress is a nullable complex type or a nullable navigation property

Companies(1)/HeadquarterAddress/Street

To access properties of derived types, the property name MUST be prefixed with the qualified name of the derived type on which the property is defined, followed by a forward slash (/), see addressing derived types. If the current instance is not of the specified derived type, the path expression returns null.

@@ -1957,11 +1957,11 @@

path expression leading to the annotated resource or property.

If an annotation is not applied to the resource or property, then its value, and the values of its components, are treated as null.

-

Example 116: Return Products that have prices in Euro

+

Example 117: Return Products that have prices in Euro

http://host/service/Products?$filter=Price/@Measures.Currency eq 'EUR'
-

Example 117: Return Employees that have any error messages in the Core.Messages annotation

+

Example 118: Return Employees that have any error messages in the Core.Messages annotation

http://host/service/Employees?$filter=@Core.Messages/any(m:m/severity eq 'error')

Services MAY additionally support the use of the unqualified term name by defining one or more default namespaces through the Core.DefaultNamespace annotation term defined in OData-VocCore. For more information on default namespaces, see Default Namespaces in OData-Protocol. This short notation however uses the same name pattern as parameter aliases. If a query option is specified as a parameter alias, then any occurrence of the parameter alias name in an expression MUST evaluate to the parameter alias value and MUST NOT evaluate to the annotation value of an identical unqualified term name.

@@ -2160,65 +2160,65 @@

-

Example 118: expand a navigation property of an entity type

+

Example 119: expand a navigation property of an entity type

http://host/service/Products?$expand=Category
-

Example 119: expand a navigation property of a complex type

+

Example 120: expand a navigation property of a complex type

http://host/service/Customers?$expand=Addresses/Country

A path MUST NOT appear in more than one expand item.

Query options can be applied to an expanded navigation property by appending a semicolon-separated list of query options, enclosed in parentheses, to the navigation property name. Allowed system query options are $compute, $select, $expand, and $levels for all navigation properties, plus $filter, $orderby, $skip, $top, $count, and $search for collection-valued navigation properties.

-

Example 120: all categories and for each category all related products with a discontinued date equal to null

+

Example 121: all categories and for each category all related products with a discontinued date equal to null

http://host/service/Categories?$expand=Products($filter=DiscontinuedDate eq null)

The $count segment can be appended to a navigation property name or type-cast segment following a navigation property name to return just the count of the related entities. The $filter and $search system query options can be used to limit the number of related entities included in the count.

-

Example 121: all categories and for each category the number of all related products

+

Example 122: all categories and for each category the number of all related products

http://host/service/Categories?$expand=Products/$count
-

Example 122: all categories and for each category the number of all related blue products

+

Example 123: all categories and for each category the number of all related blue products

http://host/service/Categories?$expand=Products/$count($search=blue)

To retrieve entity references instead of the related entities, append /$ref to the navigation property name or type-cast segment following a navigation property name. The system query options $filter, $search, $skip, $top, and $count can be used to limit the number of expanded entity references.

-

Example 123: all categories and for each category the references of all related products

+

Example 124: all categories and for each category the references of all related products

http://host/service/Categories?$expand=Products/$ref
-

Example 124: all categories and for each category the references of all related products of the derived type Sales.PremierProduct

+

Example 125: all categories and for each category the references of all related products of the derived type Sales.PremierProduct

http://host/service/Categories?$expand=Products/Sales.PremierProduct/$ref
-

Example 125: all categories and for each category the references of all related premier products with a current promotion equal to null

+

Example 126: all categories and for each category the references of all related premier products with a current promotion equal to null

http://host/service/Categories
   ?$expand=Products/Sales.PremierProduct/$ref($filter=CurrentPromotion eq null)

Cyclic navigation properties (whose target type is identical or can be cast to its source type) can be recursively expanded using the special $levels option. The value of the $levels option is either a positive integer to specify the number of levels to expand, or the literal string max to specify the maximum expansion level supported by that service. A $levels option with a value of 1 specifies a single expand with no recursion.

-

Example 126: all employees with their manager, manager’s manager, and manager’s manager’s manager

+

Example 127: all employees with their manager, manager’s manager, and manager’s manager’s manager

http://host/service/Employees?$expand=ReportsTo($levels=3)

It is also possible to expand all declared and dynamic navigation properties using a star (*). To retrieve references to all related entities use */$ref, and to expand all related entities with a certain distance use the star operator with the $levels option. The star operator can be combined with explicitly named navigation properties, which take precedence over the star operator.

The star operator does not implicitly include stream properties.

-

Example 127: expand Supplier and include references for all other related entities

+

Example 128: expand Supplier and include references for all other related entities

http://host/service/Categories?$expand=*/$ref,Supplier
-

Example 128: expand all related entities and their related entities

+

Example 129: expand all related entities and their related entities

http://host/service/Categories?$expand=*($levels=2)

Specifying a stream property includes the media stream inline according to the specified format.

-

Example 129: include Employee’s Photo stream property along with other properties of the customer

+

Example 130: include Employee’s Photo stream property along with other properties of the customer

http://host/service/Employees?$expand=Photo

Specifying $value for a media entity includes the media entity’s stream value inline according to the specified format.

-

Example 130: Include the Product’s media stream along with other properties of the product

+

Example 131: Include the Product’s media stream along with other properties of the product

http://host/service/Products?$expand=$value
@@ -2244,12 +2244,12 @@

-

Example 131: rating and release date of all products

+

Example 132: rating and release date of all products

http://host/service/Products?$select=Rating,ReleaseDate

It is also possible to request all declared and dynamic structural properties using a star (*).

-

Example 132: all structural properties of all products

+

Example 133: all structural properties of all products

http://host/service/Products?$select=*

If the select item is not defined for the type of the resource, and that type supports dynamic properties or instance annotations, then the property is treated as null for all instances on which it is not defined.

@@ -2257,21 +2257,21 @@

$expand.

If the select item is a navigation property, then the corresponding navigation link is represented in the response. If the navigation property also appears in an $expand query option, then it is additionally represented as inline content. This inline content can itself be restricted with a nested $select query option, see section 5.1.2.

-

Example 133: name and description of all products, plus name of expanded category

+

Example 134: name and description of all products, plus name of expanded category

http://host/service/Products?$select=Name,Description
   &$expand=Category($select=Name)

The select item MUST be prefixed with a qualified structured type name in order to select a property defined on a type derived from the type of the resource segment.

A select item that is a complex type or collection of complex type can be followed by a forward slash, an optional type-cast segment, and the name of a property of the complex type (and so on for nested complex types).

-

Example 134: the AccountRepresentative property of any supplier that is of the derived type Namespace.PreferredSupplier, together with the Street property of the complex property Address, and the Location property of the derived complex type Namespace.AddressWithLocation

+

Example 135: the AccountRepresentative property of any supplier that is of the derived type Namespace.PreferredSupplier, together with the Street property of the complex property Address, and the Location property of the derived complex type Namespace.AddressWithLocation

http://host/service/Suppliers
   ?$select=Namespace.PreferredSupplier/AccountRepresentative,
            Address/Street,Address/Namespace.AddressWithLocation/Location

Query options can be applied to a select item that is a path to a single complex value or a collection of primitive or complex values by appending a semicolon-separated list of query options, enclosed in parentheses, to the select item. The allowed system query options depend on the type of the resource identified by the select item, see section System Query Options, with the exception of $expand. The same property MUST NOT have select options specified in more than one place in a request and MUST NOT be specified in more than one expand.

-

Example 135: select up to five addresses whose City starts with an H, sorted, and with the Country expanded

+

Example 136: select up to five addresses whose City starts with an H, sorted, and with the Country expanded

http://host/service/Customers
   ?$select=Addresses($filter=startswith(City,'H');$top=5;
                      $orderby=Country/Name,City,Street)
@@ -2283,7 +2283,7 @@ 

-

Example 136: the ID property, the ActionName action defined in Model and all actions and functions defined in the Model2 for each product if those actions and functions can be bound to that product

+

Example 137: the ID property, the ActionName action defined in Model and all actions and functions defined in the Model2 for each product if those actions and functions can be bound to that product

http://host/service/Products?$select=ID,Model.ActionName,Model2.*

When multiple select item exist in a $select clause, then the total set of properties, open properties, navigation properties, actions and functions to be returned is equal to the union of the set of those identified by each select item.

@@ -2315,7 +2315,7 @@

The OData-ABNF compute syntax rule defines the formal grammar of the $compute query option.

Computed properties SHOULD be included as dynamic properties in the result and MUST be included if $select is specified with the computed property name, or star (*).

-

Example 138: compute total price for order items

+

Example 139: compute total price for order items

http://host/service/Orders(10)/Items
   ?$select=Product/Description,Total
   &$filter=Total gt 100
@@ -2378,7 +2378,7 @@ 

OData-ABNF.

Custom query options MUST NOT begin with a $ or @ character.

-

Example 139: service-specific custom query option debug-mode

+

Example 140: service-specific custom query option debug-mode

http://host/service/Products?debug-mode=true
@@ -2389,15 +2389,15 @@

OData-ABNF.

The semantics of parameter aliases are covered in OData-Protocol. The OData-ABNF rule aliasAndValue defines the formal grammar for passing parameter alias values as query options.

-

Example 140:

+

Example 141:

http://host/service/Movies?$filter=contains(@word,Title)&@word='Black'
-

Example 141:

+

Example 142:

http://host/service/Movies?$filter=Title eq @title&@title='Wizard of Oz'
-

Example 142: JSON array of strings as parameter alias value — note that [, ], and " need to be percent-encoded in real URLs, the clear-text representation used here is just for readability

+

Example 143: JSON array of strings as parameter alias value — note that [, ], and " need to be percent-encoded in real URLs, the clear-text representation used here is just for readability

http://host/service/Products/Model.WithIngredients(Ingredients=@i)
   ?@i=["Carrots","Ginger","Oranges"]
diff --git a/docs/odata-url-conventions/odata-url-conventions.md b/docs/odata-url-conventions/odata-url-conventions.md index 25b3de55..5a2a0e87 100644 --- a/docs/odata-url-conventions/odata-url-conventions.md +++ b/docs/odata-url-conventions/odata-url-conventions.md @@ -3200,7 +3200,7 @@ Entities are represented as structured literals as described in [OData-JSON, sec Non-transient entities can alternatively be represented through their [resource path](#ResourcePath). ::: example -Example 107: determine the price of an adhoc-defined product +Example 108: determine the price of an adhoc-defined product ``` http://host/service/Price(Product=@p)?@p={"Color":"red"} ``` @@ -3245,7 +3245,7 @@ function overload on the current instance within an expression. Function names without a path prefix refer to an unbound function overload. ::: example -Example 108: email addresses ending with `.com` assuming +Example 109: email addresses ending with `.com` assuming `EmailAddresses` is a collection of strings ``` http://host/service/Customers(1)/EmailAddresses?$filter=endswith($it,'.com') @@ -3253,7 +3253,7 @@ http://host/service/Customers(1)/EmailAddresses?$filter=endswith($it,'.com') ::: ::: example -Example 109: customers along with their orders that shipped to the same +Example 110: customers along with their orders that shipped to the same city as the customer's address. The nested filter expression is evaluated in the context of Orders; `$it` allows referring to values in the outer context of Customers. @@ -3264,7 +3264,7 @@ http://host/service/Customers?$expand=Orders($filter=$it/Address/City eq ShipTo/ ::: ::: example -Example 110: products with at least 10 positive reviews. +Example 111: products with at least 10 positive reviews. `Model.PositiveReviews` is a function bound to `Model.Product` returning a collection of reviews. ``` @@ -3278,14 +3278,14 @@ The `$root` literal can be used in expressions to refer to resources of the same service. ::: example -Example 111: all employees with the same last name as employee `A1235` +Example 112: all employees with the same last name as employee `A1235` ``` http://host/service/Employees?$filter=LastName eq $root/Employees('A1245')/LastName ``` ::: ::: example -Example 112: products ordered by a set of customers, where the set of +Example 113: products ordered by a set of customers, where the set of customers is passed as a JSON array containing the resource paths from `$root` to each customer ``` @@ -3295,7 +3295,7 @@ http://host/service/ProductsOrderedBy(Customers=@c) ::: ::: example -Example 113: function call returning the average rating of a given employee by their peers (employees in department D1) +Example 114: function call returning the average rating of a given employee by their peers (employees in department D1) ``` http://host/service/Employees('A1245')/self.AvgRating(RatedBy=@peers) ?@peers=$root/Employees/$filter(Department eq 'D1') @@ -3312,7 +3312,7 @@ and navigation properties. It refers to the current instance of the collection. ::: example -Example 114: select only email addresses ending with `.com` +Example 115: select only email addresses ending with `.com` ``` http://host/service/Customers?$select=EmailAddresses($filter=endswith($this,'.com')) ``` @@ -3339,7 +3339,7 @@ target cardinality 0..1), its value, and the values of its components, are treated as `null`. ::: example -Example 115: similar behavior whether `HeadquarterAddress` is a nullable +Example 116: similar behavior whether `HeadquarterAddress` is a nullable complex type or a nullable navigation property ``` Companies(1)/HeadquarterAddress/Street @@ -3380,14 +3380,14 @@ If an annotation is not applied to the resource or property, then its value, and the values of its components, are treated as `null`. ::: example -Example 116: Return Products that have prices in Euro +Example 117: Return Products that have prices in Euro ``` http://host/service/Products?$filter=Price/@Measures.Currency eq 'EUR' ``` ::: ::: example -Example 117: Return Employees that have any error messages in the +Example 118: Return Employees that have any error messages in the [`Core.Messages`](https://github.com/oasis-tcs/odata-vocabularies/blob/main/vocabularies/Org.OData.Core.V1.md#Messages) annotation ``` @@ -3522,14 +3522,14 @@ segment does not specify a declared property, then the expanded property appears only for those instances on which it has a value. ::: example -Example 118: expand a navigation property of an entity type +Example 119: expand a navigation property of an entity type ``` http://host/service/Products?$expand=Category ``` ::: ::: example -Example 119: expand a navigation property of a complex type +Example 120: expand a navigation property of a complex type ``` http://host/service/Customers?$expand=Addresses/Country ``` @@ -3553,7 +3553,7 @@ Allowed system query options are for collection-valued navigation properties. ::: example -Example 120: all categories and for each category all related products +Example 121: all categories and for each category all related products with a discontinued date equal to `null` ``` http://host/service/Categories?$expand=Products($filter=DiscontinuedDate eq null) @@ -3567,7 +3567,7 @@ property name to return just the count of the related entities. The number of related entities included in the count. ::: example -Example 121: all categories and for each category the number of all +Example 122: all categories and for each category the number of all related products ``` http://host/service/Categories?$expand=Products/$count @@ -3575,7 +3575,7 @@ http://host/service/Categories?$expand=Products/$count ::: ::: example -Example 122: all categories and for each category the number of all +Example 123: all categories and for each category the number of all related blue products ``` http://host/service/Categories?$expand=Products/$count($search=blue) @@ -3592,7 +3592,7 @@ The system query options [`$filter`](#SystemQueryOptionfilter), expanded entity references. ::: example -Example 123: all categories and for each category the references of all +Example 124: all categories and for each category the references of all related products ``` http://host/service/Categories?$expand=Products/$ref @@ -3600,7 +3600,7 @@ http://host/service/Categories?$expand=Products/$ref ::: ::: example -Example 124: all categories and for each category the references of all +Example 125: all categories and for each category the references of all related products of the derived type `Sales.PremierProduct` ``` http://host/service/Categories?$expand=Products/Sales.PremierProduct/$ref @@ -3608,7 +3608,7 @@ http://host/service/Categories?$expand=Products/Sales.PremierProduct/$ref ::: ::: example -Example 125: all categories and for each category the references of all +Example 126: all categories and for each category the references of all related premier products with a current promotion equal to `null` ``` http://host/service/Categories @@ -3625,7 +3625,7 @@ A `$levels` option with a value of 1 specifies a single expand with no recursion. ::: example -Example 126: all employees with their manager, manager's manager, and +Example 127: all employees with their manager, manager's manager, and manager's manager's manager ``` http://host/service/Employees?$expand=ReportsTo($levels=3) @@ -3642,7 +3642,7 @@ which take precedence over the star operator. The star operator does not implicitly include stream properties. ::: example -Example 127: expand `Supplier` and include references for all other +Example 128: expand `Supplier` and include references for all other related entities ``` http://host/service/Categories?$expand=*/$ref,Supplier @@ -3650,7 +3650,7 @@ http://host/service/Categories?$expand=*/$ref,Supplier ::: ::: example -Example 128: expand all related entities and their related entities +Example 129: expand all related entities and their related entities ``` http://host/service/Categories?$expand=*($levels=2) ``` @@ -3660,7 +3660,7 @@ Specifying a stream property includes the media stream inline according to the specified format. ::: example -Example 129: include Employee's `Photo` stream property along with other +Example 130: include Employee's `Photo` stream property along with other properties of the customer ``` http://host/service/Employees?$expand=Photo @@ -3671,7 +3671,7 @@ Specifying `$value` for a media entity includes the media entity's stream value inline according to the specified format. ::: example -Example 130: Include the Product's media stream along with other +Example 131: Include the Product's media stream along with other properties of the product ``` http://host/service/Products?$expand=$value @@ -3730,7 +3730,7 @@ The simplest form of a select item explicitly requests a property defined on the type of the resources identified by the resource path section of the URL. ::: example -Example 131: rating and release date of all products +Example 132: rating and release date of all products ``` http://host/service/Products?$select=Rating,ReleaseDate ``` @@ -3740,7 +3740,7 @@ It is also possible to request all declared and dynamic structural properties using a star (`*`). ::: example -Example 132: all structural properties of all products +Example 133: all structural properties of all products ``` http://host/service/Products?$select=* ``` @@ -3768,7 +3768,7 @@ inline content can itself be restricted with a nested `$select` query option, see [section 5.1.2](#SystemQueryOptionfilter). ::: example -Example 133: name and description of all products, plus name of expanded +Example 134: name and description of all products, plus name of expanded category ``` http://host/service/Products?$select=Name,Description @@ -3785,7 +3785,7 @@ be followed by a forward slash, an optional [type-cast segment](#AddressingDeriv complex type (and so on for nested complex types). ::: example -Example 134: the `AccountRepresentative` property of any supplier that +Example 135: the `AccountRepresentative` property of any supplier that is of the derived type `Namespace.PreferredSupplier`, together with the `Street` property of the complex property `Address`, and the Location property of the derived complex type `Namespace.AddressWithLocation` @@ -3807,7 +3807,7 @@ select options specified in more than one place in a request and MUST NOT be specified in more than one expand. ::: example -Example 135: select up to five addresses whose `City` starts with an +Example 136: select up to five addresses whose `City` starts with an `H`, sorted, and with the `Country` expanded ``` http://host/service/Customers @@ -3844,7 +3844,7 @@ qualified name and that operation cannot be bound to the entities requested, the service MUST ignore the select item. ::: example -Example 136: the `ID` property, the `ActionName` action defined in +Example 137: the `ID` property, the `ActionName` action defined in `Model` and all actions and functions defined in the `Model2` for each product if those actions and functions can be bound to that product ``` @@ -3910,7 +3910,7 @@ The [OData-ABNF](#ODataABNF) `search` syntax rule defines the formal grammar of the `$search` query option. ::: example -Example 137: all products that are blue or green. It is up to the +Example 138: all products that are blue or green. It is up to the service to decide what makes a product blue or green. ``` http://host/service/Products?$search=blue OR green @@ -4005,7 +4005,7 @@ result and MUST be included if `$select` is specified with the computed property name, or star (`*`). ::: example -Example 138: compute total price for order items +Example 139: compute total price for order items ``` http://host/service/Orders(10)/Items ?$select=Product/Description,Total @@ -4049,7 +4049,7 @@ custom query option is any query option of the form shown by the rule Custom query options MUST NOT begin with a `$` or `@` character. ::: example -Example 139: service-specific custom query option `debug-mode` +Example 140: service-specific custom query option `debug-mode` ``` http://host/service/Products?debug-mode=true ``` @@ -4071,21 +4071,21 @@ The semantics of parameter aliases are covered in values as query options. ::: example -Example 140: +Example 141: ``` http://host/service/Movies?$filter=contains(@word,Title)&@word='Black' ``` ::: ::: example -Example 141: +Example 142: ``` http://host/service/Movies?$filter=Title eq @title&@title='Wizard of Oz' ``` ::: ::: example -Example 142: JSON array of strings as parameter alias value --- note that +Example 143: JSON array of strings as parameter alias value --- note that `[`, `]`, and `"` need to be percent-encoded in real URLs, the clear-text representation used here is just for readability ```