Skip to main content
Skip table of contents

Use Case: Updating Virtual Products with Additional Artwork

When we create virtual products using the createVirtualProductsFromArtwork GraphQL mutation, we are applying artwork to the first print area (usually the front), but what if we wanted to also populate other print areas such as the back or neck label? This article will describe how you can make a single subsequent API call to achieve this and update other aspects of the product as well.

We will first use the createVirtualProductsFromArtwork GraphQL mutation, providing it with a single blank product and a single artwork object. The API will return details of a new virtual product created in the platform.

This could easily be 10 blank products and 10 artwork objects, returning 100 new virtual products but for the purposes of this example and to keep things easy to understand, we will just create 1 virtual product.

We will then use the response data to update the following parts of the new virtual product:

  • Add artwork to the Back print area.

  • Add artwork to the Neck Label print area.

  • Change the name of the product.

  • Change the retail SKU of the product.

  • Disable specific colour options on the product.

  • Set the default colour option.

Authentication

The GraphQL API uses oauth authentication.  A request for an oauth token is made to the oauth endpoint, which returns an access token.  This token can then be used in requests made to the GraphQL API endpoint.

To make a request for a token, you will require an oauth user to be set up in the KornitX platform. The user will require specific access and permissions depending on the API request. The permissions required for this request can be found in the “Oauth User Requirements” section below.

If you don’t have an oauth user set up, please contact the support team, who will be happy to help. The support team will set up the oauth user in the KornitX platform for you and supply you with the oauth user client ID and client secret.  These credentials can then be used to obtain a token from the oauth token endpoint. 

Oauth Token Endpoint - https://oauth.kornitx.net/token

The oauth token can be obtained by making a POST to the above endpoint.  The request type for the oauth token is x-www-form-urlencoded and must include the following form keys and values.

Key

Value

client_id

The client ID of the oauth user provided by the support team.

client_secret

The client secret of the oauth user provided by the support team.

grant_type

client_credentials

scope

products.customisable.create products.customisable.edit

Example Response

JSON
{"token_type":"Bearer","expires_in":3600,"access_token":"..."}

Oauth User Requirements

To make the createVirtualProductsFromArtwork request to the GraphQL API, the oauth user must have:

  • Read access to the categories that the products listed in the baseProducts variable, are assigned to.

  • Write access to the target category specified in the categoryId variable.

  • The products.customisable.create user permission enabled.

The Create Virtual Products from Artwork GraphQL Mutation

Now we have the access token, we can now make the createVirtualProductsFromArtwork request.

We will be making a POST request to the https://cpp.custom-gateway.net/v2/product-manager/products-graphql endpoint.

The request will have 2 headers listed below.

Content-Type: “application/json” 

Authorization: “Bearer [OAUTH_ACCESS_TOKEN]“

[OAUTH_ACCESS_TOKEN] should be replaced by the access token that was returned when we made the token request to the https://oauth.kornitx.net/token endpoint.

Mutation

In this example, we will be including 1 base product ID and 1 artwork object, which will create a single virtual product and return the following information about that product.

  • Product ID

  • Name

  • Retail SKU

  • Various snapshots

  • The aspect options of the blank product that the new virtual product was created using (giving us the information we need to disable various colours later on).

  • The print areas (known as surface areas) of the blank product that the new virtual product was created using (giving us the information we need to add artwork to the back and neck label print areas later on).

However, the GraphQL API call can return numerous other pieces of information about the product, details of which, can be found in the schema here - https://developers-v2.custom-gateway.net/graphql/product.doc.html

Example Mutation

GRAPHQL
mutation (
  $baseProducts: [ID]!
  $categoryId: ID!
  $artwork: [CreateVirtualProductsFromArtworkArtwork]!
) {
  createVirtualProductsFromArtwork(
    baseProducts: $baseProducts
    categoryId: $categoryId
    artwork: $artwork
  ) {
    id
    name
    retail_sku
    base_product {
        aspect_options(count: 1000) {
	        items {
	            aspect_id
	            aspect_name
	            id
	            name
                is_enabled
	        }
	    }
	    surface_areas {
	        items {
	            id
	            name
	        }
	    }
    }
    
    snapshots {
        thumbnail
        extra_small
        small
        medium
        large
        extra_large
        super_large
    }
    base_product_id
  }
}

Variables

The mutation contains references to 3 variables - $baseProducts, $categoryId and $artwork. Descriptions of these variables can be found in the table below.

Variable Descriptions

Variable

Type

Description

baseProducts

[ID]!

A collection of base product IDs.

categoryId

ID!

The ID of the target product category into which the new virtual products will be created.

artwork

CreateVirtualProductsFromArtworkArtwork

A collection of artwork objects.

Each artwork object has a:

  • design name

  • preview URL (used in live preview smartlinks)

  • full size URL (using for artwork generation)

Example Variables

JSON
{
   "baseProducts":[
      8843396
   ],
   "categoryId":20097,
   "artwork":[
      {
         "design_name":"Army Print",
         "urls":[
            {
               "preview":"https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/0f34/6511/9dcb/d926/624b/7b12/e625/413b/e254/1bcb/b445/7369/16d6/1ca4/3441/4195-original.jpg",
               "original":"https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/0f34/6511/9dcb/d926/624b/7b12/e625/413b/e254/1bcb/b445/7369/16d6/1ca4/3441/4195-original.jpg"
            }
         ]
      }
   ]
}

Response

A successful request will return the details of the virtual products that were created. For the example we have been working with, the response data can be viewed below.

Example Response

JSON
{
    "data": {
        "createVirtualProductsFromArtwork": [
            {
                "id": 14700144,
                "name": "Army Print - Gildan Valueweight T-Shirt",
                "retail_sku": "Gd01test-14700144",
                "base_product": {
                    "aspect_options": {
                        "items": [
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514439,
                                "name": "Black",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514440,
                                "name": "Red",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514441,
                                "name": "Navy",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514442,
                                "name": "Sport Grey",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514443,
                                "name": "Daisy",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514444,
                                "name": "Maroon",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514445,
                                "name": "Forest Green",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514446,
                                "name": "Royal Blue",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514447,
                                "name": "Light Blue",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514448,
                                "name": "Irish Green",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785850,
                                "aspect_name": "Front",
                                "id": 2514449,
                                "name": "White",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514450,
                                "name": "Black",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514451,
                                "name": "Red",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514452,
                                "name": "Navy",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514453,
                                "name": "Sport Grey",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514454,
                                "name": "Irish Green",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514455,
                                "name": "Daisy",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514456,
                                "name": "Maroon",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514457,
                                "name": "Forest Green",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514458,
                                "name": "Royal Blue",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514459,
                                "name": "Light Blue",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785851,
                                "aspect_name": "Back",
                                "id": 2514460,
                                "name": "White",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514461,
                                "name": "White",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514462,
                                "name": "Black",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514463,
                                "name": "Red",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514464,
                                "name": "Sport Grey",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514465,
                                "name": "Navy",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514466,
                                "name": "Irish Green",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514467,
                                "name": "Daisy",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514468,
                                "name": "Forest Green",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514469,
                                "name": "Royal Blue",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514470,
                                "name": "Light Blue",
                                "is_enabled": true
                            },
                            {
                                "aspect_id": 1785852,
                                "aspect_name": "Neck Label",
                                "id": 2514471,
                                "name": "Maroon",
                                "is_enabled": true
                            }
                        ]
                    },
                    "surface_areas": {
                        "items": [
                            {
                                "id": 4606942,
                                "name": "Front",
                                "artworks": {
                                    "items": []
                                }
                            },
                            {
                                "id": 4606943,
                                "name": "Back",
                                "artworks": {
                                    "items": []
                                }
                            },
                            {
                                "id": 4606944,
                                "name": "Neck Label",
                                "artworks": {
                                    "items": []
                                }
                            },
                            {
                                "id": 4637180,
                                "name": "Front (Paid)",
                                "artworks": {
                                    "items": []
                                }
                            },
                            {
                                "id": 4637181,
                                "name": "Back (Paid)",
                                "artworks": {
                                    "items": []
                                }
                            }
                        ]
                    }
                },
                "snapshots": {
                    "extra_small": "https://s3-eu-west-1.amazonaws.com/generated-assets-gateway3d-com/product/7F17D091A45AAFF/snapshot/extra-small.jpg",
                    "small": "https://s3-eu-west-1.amazonaws.com/generated-assets-gateway3d-com/product/7F17D091A45AAFF/snapshot/small.jpg",
                    "medium": "https://s3-eu-west-1.amazonaws.com/generated-assets-gateway3d-com/product/7F17D091A45AAFF/snapshot/medium.jpg",
                    "large": "https://s3-eu-west-1.amazonaws.com/generated-assets-gateway3d-com/product/7F17D091A45AAFF/snapshot/large.jpg",
                    "extra_large": "https://s3-eu-west-1.amazonaws.com/generated-assets-gateway3d-com/product/7F17D091A45AAFF/snapshot/extra-large.jpg",
                    "super_large": "https://s3-eu-west-1.amazonaws.com/generated-assets-gateway3d-com/product/7F17D091A45AAFF/snapshot/super-large.jpg"
                },
                "base_product_id": 8843396
            }
        ]
    }
}

Updating the New Virtual Product

Now that we have created the virtual product, we can go ahead and update it using the data returned in the previous call. We will make a single call to the GraphQL API but the payload will contain 5 separate mutations.

We can use the same access token as we did for the createVirtualProductsFromArtwork GraphQL mutation, as we included the products.customisable.edit permission in the scope when we requested the OAuth token. We should however, use the https://graphql.kornitx.net endpoint when making this request.

  • A mutation to add artwork to the Back print area.

GRAPHQL
backArtwork: updateProductSurfaceAreaArtwork(
        productId: $productId,
        surfaceAreaId: $surfaceAreaBackId,
        artworks: $backArtworks
	    )
	    {
	        id
	        surface_id
	        fullsize_url
	        preview_url
            type
            is_required_for_virtuals
	    }
  • A mutation to add artwork to the Neck Label print area.

GRAPHQL
neckArtwork: updateProductSurfaceAreaArtwork(
        productId: $productId,
        surfaceAreaId: $surfaceAreaNeckId,
        artworks: $neckArtworks
	    )
	    {
	        id
	        surface_id
	        fullsize_url
	        preview_url
            type
            is_required_for_virtuals
	    }

As we are making 2 updateProductSurfaceAreaArtwork mutations, the API requires us to provide aliases so that there aren’t any conflicts in terms of the data returned in the response. We are using the aliases backArtwork and neckArtwork .

  • A mutation to update the product name and retail SKU.

GRAPHQL
updateProducts(products: $products) {
            id
            name
            retail_sku
        }
  • A mutation to disable 2 specific colour options on the virtual product.

GRAPHQL
updateProductVirtualAspectOptions(productId: $productId, options: $aspectOptions) {
			id
			option_id
			is_enabled
		}
  • A mutation to set the default colour option.

GRAPHQL
updateProductVirtualAspects(productId: $productId, aspects: $aspects) {
			id
			aspect_id
			default_option_id
		}

When combined together, the full GraphQL request will look like this.

GRAPHQL
mutation(
$productId: ID!,
$surfaceAreaBackId: ID!,
$surfaceAreaNeckId: ID!,
$backArtworks: [ProductSurfaceAreaArtworkInput]!,
$neckArtworks: [ProductSurfaceAreaArtworkInput]!,
$products: [ProductInput]!,
$aspectOptions: [ProductVirtualAspectOptionInput]!
$aspects: [ProductVirtualAspectInput]!
)
{
	core {
		backArtwork: updateProductSurfaceAreaArtwork(
        productId: $productId,
        surfaceAreaId: $surfaceAreaBackId,
        artworks: $backArtworks
	    )
	    {
	        id
	        surface_id
	        fullsize_url
	        preview_url
            type
            is_required_for_virtuals
	    }

        neckArtwork: updateProductSurfaceAreaArtwork(
        productId: $productId,
        surfaceAreaId: $surfaceAreaNeckId,
        artworks: $neckArtworks
	    )
	    {
	        id
	        surface_id
	        fullsize_url
	        preview_url
            type
            is_required_for_virtuals
	    }

        updateProducts(products: $products) {
            id
            name
            retail_sku
        }

        updateProductVirtualAspectOptions(productId: $productId, options: $aspectOptions) {
			id
			option_id
			is_enabled
		}

        updateProductVirtualAspects(productId: $productId, aspects: $aspects) {
			id
			aspect_id
			default_option_id
		}
	}
}

Variables

The values of the following variables will either be taken from the response data from the previous createVirtualProductsFromArtwork mutation or values that you should supply like the artwork URLs for the Back and Neck Label print areas.

Variable Descriptions

Variable

Type

Description

productId

ID!

The ID of the virtual product to be updated. This can be found in the response data of the previous mutation.

surfaceAreaBackId

ID!

The ID of the back print area. This can be found in the response data of the previous mutation.

surfaceAreaBackId

ID!

The ID of the neck label print area. This can be found in the response data of the previous mutation.

backArtworks

[ProductSurfaceAreaArtworkInput]!

A collection of product surface area artwork input objects.

Each artwork object has a:

  • fullsize_url The full sized artwork URL.

  • preview_url The artwork preview URL.

  • type The type of artwork being uploaded. We will supply “raster” as the value.

  • is_required_for_virtuals We will supply a value of true here.

neckArtworks

[ProductSurfaceAreaArtworkInput]!

A collection of product surface area artwork input objects.

Each artwork object has a:

  • fullsize_url The full sized artwork URL.

  • preview_url The artwork preview URL.

  • type The type of artwork being uploaded. We will supply “raster” as the value.

  • is_required_for_virtuals We will supply a value of true here.

products

[ProductInput]!

A collection of product input objects.

The product input object has the fields:

  • id The virtual product ID.

  • name The new name for the product.

  • retail_sku The new retail SKU for the product.

aspectOptions

[ProductVirtualAspectOptionInput]!

A collection of product virtual aspect option input objects.

Each artwork object has the fields:

  • id We will supply a null value here.

  • option_id The ID of the aspect option we want to update. These can be found in the response data of the previous mutation.

  • is_enabled We will supply a value of false here to disable the aspect option.

When disabling aspect options, it’s important that we disable each colour option on all aspects. In our example we are disabling Light Blue and Irish Green and there are 3 aspects, Front, Back and Neck Label.

We should therefore send a total of 6 aspect option input objects. These will consist of:

  • Front Light Blue

  • Back Light Blue

  • Neck Light Blue

  • Front Irish Green

  • Back Irish Green

  • Neck Irish Green

The IDs of each of these can be found in the response data of the previous mutation.

aspects

[ProductVirtualAspectInput]!

A collection of product virtual aspect input objects.

  • id We will supply a null value here.

  • aspect_id The ID of the aspect we want to update. These can be found in the response data of the previous mutation.

  • default_option_id The ID of the aspect option we want to set as the default colour. These can be found in the response data of the previous mutation.

It’s important that we include an object for each aspect. In this case, there will be 3 objects, one each for the Front, Back and Neck Label aspects.

It’s also important that each aspect option we set as default, is related to the same colour. In our example, we will be setting Red as the default colour, so each of the aspect option IDs we send in the request, will be related to the Red aspect option.

Example Variables

JSON
{
  "productId": 14700144,
  "surfaceAreaBackId": 4606943,
  "surfaceAreaNeckId": 4606944,
  "backArtworks": [
    {
      "fullsize_url": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/52d8/2cf7/b89d/8fc2/b969/bdb3/aea9/b9bb/0d32/a14c/0c2d/9f88/0d3b/c435/300b/305b-original.jpg",
      "preview_url": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/52d8/2cf7/b89d/8fc2/b969/bdb3/aea9/b9bb/0d32/a14c/0c2d/9f88/0d3b/c435/300b/305b-original.jpg",
      "type": "raster",
      "is_required_for_virtuals": true
    }
  ],
  "neckArtworks": [
    {
      "fullsize_url": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/9b46/78c2/01f6/43f9/0866/21f7/08f0/2304/9ad8/d16e/4ed6/81f1/1a01/1029/72e1/84bc-original.png",
      "preview_url": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/9b46/78c2/01f6/43f9/0866/21f7/08f0/2304/9ad8/d16e/4ed6/81f1/1a01/1029/72e1/84bc-original.png",
      "type": "raster",
      "is_required_for_virtuals": true
    }
  ],
  "products": [
    {
        "id": 14700144,
        "name": "New Product Name",
        "retail_sku": "PS_SKU_12345"
    }
  ],
  "aspectOptions": [
    {
        "id": null,
        "option_id": 2514447,
        "is_enabled": false
    },
    {
        "id": null,
        "option_id": 2514448,
        "is_enabled": false
    },
    {
        "id": null,
        "option_id": 2514459,
        "is_enabled": false
    },
    {
        "id": null,
        "option_id": 2514454,
        "is_enabled": false
    },
    {
        "id": null,
        "option_id": 2514466,
        "is_enabled": false
    },
    {
        "id": null,
        "option_id": 2514470,
        "is_enabled": false
    }
  ],
  "aspects": [
    {
      "id": null,
      "aspect_id": 1785850,
      "default_option_id": 2514440
    },
    {
      "id": null,
      "aspect_id": 1785851,
      "default_option_id": 2514451
    },
    {
      "id": null,
      "aspect_id": 1785852,
      "default_option_id": 2514463
    }
  ]
}

Response

A successful request will return the details of the virtual products that were updated. For the example we have been working with, the response data can be viewed below.

Example Response

JSON
{
    "data": {
        "core": {
            "backArtwork": [
                {
                    "id": 5140064,
                    "surface_id": 4606943,
                    "fullsize_url": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/52d8/2cf7/b89d/8fc2/b969/bdb3/aea9/b9bb/0d32/a14c/0c2d/9f88/0d3b/c435/300b/305b-original.jpg",
                    "preview_url": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/52d8/2cf7/b89d/8fc2/b969/bdb3/aea9/b9bb/0d32/a14c/0c2d/9f88/0d3b/c435/300b/305b-original.jpg",
                    "type": "raster",
                    "is_required_for_virtuals": true
                }
            ],
            "neckArtwork": [
                {
                    "id": 5140065,
                    "surface_id": 4606944,
                    "fullsize_url": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/9b46/78c2/01f6/43f9/0866/21f7/08f0/2304/9ad8/d16e/4ed6/81f1/1a01/1029/72e1/84bc-original.png",
                    "preview_url": "https://s3-eu-west-1.amazonaws.com/user-images-gateway3d-com/user-images/9b46/78c2/01f6/43f9/0866/21f7/08f0/2304/9ad8/d16e/4ed6/81f1/1a01/1029/72e1/84bc-original.png",
                    "type": "raster",
                    "is_required_for_virtuals": true
                }
            ],
            "updateProducts": [
                {
                    "id": 14702553,
                    "name": "New Product Name",
                    "retail_sku": "PS_SKU_12345"
                }
            ],
            "updateProductVirtualAspectOptions": [
                {
                    "id": 1485949,
                    "option_id": 2514447,
                    "is_enabled": false
                },
                {
                    "id": 1485950,
                    "option_id": 2514448,
                    "is_enabled": false
                },
                {
                    "id": 1485951,
                    "option_id": 2514459,
                    "is_enabled": false
                },
                {
                    "id": 1485952,
                    "option_id": 2514454,
                    "is_enabled": false
                },
                {
                    "id": 1485953,
                    "option_id": 2514466,
                    "is_enabled": false
                },
                {
                    "id": 1485954,
                    "option_id": 2514470,
                    "is_enabled": false
                }
            ],
            "updateProductVirtualAspects": [
                {
                    "id": 175470,
                    "aspect_id": 1785850,
                    "default_option_id": "2514440"
                },
                {
                    "id": 175471,
                    "aspect_id": 1785851,
                    "default_option_id": "2514451"
                },
                {
                    "id": 175472,
                    "aspect_id": 1785852,
                    "default_option_id": "2514463"
                }
            ]
        }
    }
}
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.