# Dotti Australia Product Scraper (`dromb/dotti-au-product-scraper`) Actor

Scrape product data, categories, and detailed item information from Dotti Australia for price monitoring, product research, market research, availability tracking, and competitive analysis.

- **URL**: https://apify.com/dromb/dotti-au-product-scraper.md
- **Developed by:** [Dmitriy Gyrbu](https://apify.com/dromb) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.30 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Dotti Australia Product Scraper

This Apify Actor allows you to scrape product data, categories, and detailed item information from Dotti Australia for price monitoring, product research, market research, availability tracking, and competitive analysis.

### Features

- **Product Search**: Search for products using keywords and sort options.
- **Category Scraping**: List products within a specific category.
- **Detailed Item Info**: Get full specifications, pricing, and availability for a single product.
- **Category Tree**: Explore the Dotti category hierarchy.
- **Search Filters**: Discover available filters and sort options for a category.
- **Multi-Method HTTP Fallback**: Automatically tries multiple HTTP clients (httpx, cloudscraper, tls_client, curl_cffi) for maximum success rate.
- **Proxy Support**: Integrated Apify proxy support with country filtering.
- **Retry Logic**: Automatic retry with exponential backoff for blocked requests.
- **Standardized Infrastructure**: Built on shared apify-wave1 runtime for consistency across actors.

### Operation Guide

#### 1. Product Search
Provide a `Search Query` (e.g., "dress") to get a list of matching products. You can refine results using `Sort`.

#### 2. Category Scraping
Provide a `URL` (e.g., `https://dotti.jgl.com.au/shop/do-womens-new-all`) or `Category ID` to fetch all products in that category.

#### 3. Item Details
Provide a `URL`, `Slug`, or `Item ID` to get exhaustive details for a single item.

#### 4. Category List
Use the `categories` operation to get a list of all categories from the homepage. Use `Refresh Categories` to force reload.

#### 5. Search Filters
Provide a `Category URL` to discover available filters and sort options for that category.

### Examples

You can copy and paste these JSON inputs into the Apify Actor's "JSON" editor for quick testing.

#### Search for "Dress"
Returns a list of dress products sorted by relevance.
```json
{
  "operation": "search",
  "query": "dress",
  "limit": 10,
  "sort": "recommended"
}
````

#### Search for Jeans with Price Sort

Returns jeans products sorted by price.

```json
{
  "operation": "search",
  "query": "jeans",
  "sort": "price_asc",
  "limit": 20
}
```

#### Fetch Category Products

Gets products from a specific category.

```json
{
  "operation": "category",
  "url": "https://dotti.jgl.com.au/shop/do-womens-new-all",
  "limit": 20,
  "sort": "new"
}
```

#### Fetch Specific Product Details

Gets full specifications for a product using its URL.

```json
{
  "operation": "item",
  "url": "https://dotti.jgl.com.au/shop/do-womens-new-all/do-womens-dress-12345"
}
```

#### List All Categories

Returns the main category structure of the site.

```json
{
  "operation": "categories",
  "limit": 100
}
```

#### Get Category Filters

Returns available filters for a category.

```json
{
  "operation": "search_filters",
  "categoryUrl": "/shop/do-womens-new-all"
}
```

### Input Fields

| Field | Required | Description | Example |
|---|---|---|---|
| `operation` | **Required** | Operation to perform: `search`, `category`, `item`, `categories`, or `search_filters` | `search` |
| `query` | Optional | Text search query | `dress` |
| `url` | Optional | Full category or product URL | `https://dotti.jgl.com.au/shop/do-womens-new-all` |
| `slug` | Optional | Product slug | `do-womens-dress-12345` |
| `categoryId` | Optional | Category ID | `461559` |
| `itemId` | Optional | Item ID or SKU | `12345` |
| `parentId` | Optional | Parent category ID | `461558` |
| `categoryUrl` | Optional | Category URL for filters | `/shop/do-womens-new-all` |
| `limit` | Optional | Max items to return | `48` |
| `page` | Optional | Page number | `1` |
| `sort` | Optional | Sort order (`recommended`, `new`, `price_asc`, `price_desc`) | `price_asc` |
| `details` | Optional | Include richer normalized fields | `false` |
| `refresh` | Optional | Refresh category cache from homepage | `false` |
| `proxy` | Optional | Proxy mode (`direct`, `apify`, `custom`, `auto`) | `auto` |
| `customProxyUrl` | Optional | Custom proxy URL | `http://proxy.example.com:8080` |
| `proxyCountry` | Optional | Proxy country code | `AU` |

### Output Fields

Each product item includes:

- `id`: Product ID.
- `slug`: Product slug.
- `name`: Product name.
- `brand`: Brand name.
- `price`: Current price.
- `discount_price`: Discounted price.
- `currency`: Currency (AUD).
- `source_url`: URL to product page.
- `image`: Main product image.
- `images`: List of all product images.
- `in_stock`: Stock availability boolean.
- `stock_status`: Stock status text.
- `description`: Full product description.
- `short_description`: Short product description.
- `attributes`: Detailed specifications (color, size, features, etc.).
- `breadcrumbs`: Category hierarchy.
- `variants`: Product variants with size/color options.
- `price_info`: Price information array.

### Proxy & Bot Protection

Dotti uses light bot protection. Direct mode usually works, but for high-volume scraping or if you encounter blocks, use:

- **Auto**: Automatically handles proxy selection (recommended).
- **Direct**: Bypasses proxy (usually sufficient).
- **Custom**: Uses a provided custom proxy URL.
- **Apify**: Uses Apify's proxy infrastructure.

The actor includes automatic retry logic with exponential backoff for blocked requests (403, 429, 502, 503) and invalid JSON responses.

### Pricing

- **Actor Start**: $0.005 per run
- **Dataset Item**: $0.0004 per item

Free/trial users are limited to 10 result requests per day.

### Limitations

- This scraper is unofficial and not affiliated with Dotti.
- Dotti may change their API or HTML structure without notice.
- Some products may have incomplete data depending on source availability.
- Category URLs may change over time; use the categories endpoint to discover current URLs.
- High-volume scraping may trigger rate limiting or blocking.

### Disclaimer

This scraper is unofficial and not affiliated with Dotti. Users are responsible for complying with Dotti's terms of service and applicable laws.

# Actor input Schema

## `operation` (type: `string`):

Operation to perform: search, category, item, categories, or search\_filters.

## `query` (type: `string`):

Free-text query (e.g., 'dress' or 'jeans') for searching products.

## `url` (type: `string`):

Full category or product URL for category or item operations.

## `slug` (type: `string`):

Product slug (e.g., 'do-womens-new-all') for item operation.

## `categoryId` (type: `string`):

Category ID (e.g., '461559') for category operation.

## `itemId` (type: `string`):

Item ID or SKU for fetching a single item's details.

## `parentId` (type: `string`):

Parent category ID for category operation.

## `categoryUrl` (type: `string`):

Category URL to fetch filters from (e.g., '/shop/do-womens-new-all').

## `limit` (type: `integer`):

Maximum number of items/categories to return.

## `page` (type: `integer`):

Page number for pagination.

## `sort` (type: `string`):

Sort order: recommended, new, price\_asc, price\_desc.

## `details` (type: `boolean`):

When true, return richer normalized fields where available.

## `refresh` (type: `boolean`):

Refresh category cache from homepage when listing categories.

## `proxy` (type: `string`):

Proxy configuration: 'direct', 'apify', 'custom', or 'auto'.

## `customProxyUrl` (type: `string`):

URL for custom proxy if 'custom' is selected.

## `proxyCountry` (type: `string`):

Country for the proxy (e.g., 'AU').

## `includeRaw` (type: `boolean`):

Include the raw source payload in the output.

## `disableFreeTrialGuard` (type: `boolean`):

Disable the free/trial usage limit guard (for testing).

## Actor input object example

```json
{
  "operation": "search",
  "limit": 48,
  "page": 1,
  "sort": "recommended",
  "details": false,
  "refresh": false,
  "proxy": "auto",
  "proxyCountry": "AU",
  "includeRaw": false,
  "disableFreeTrialGuard": false
}
```

# Actor output Schema

## `id` (type: `string`):

Product ID

## `slug` (type: `string`):

Product slug

## `name` (type: `string`):

Product name

## `brand` (type: `string`):

Brand name

## `source_url` (type: `string`):

URL to product page

## `category` (type: `string`):

Product category

## `breadcrumbs` (type: `string`):

Category hierarchy

## `price` (type: `string`):

Current price

## `discount_price` (type: `string`):

Discounted price

## `currency` (type: `string`):

Currency

## `price_info` (type: `string`):

Price information array

## `in_stock` (type: `string`):

Availability status

## `stock_status` (type: `string`):

Stock status text

## `description` (type: `string`):

Full product description

## `short_description` (type: `string`):

Short product description

## `image` (type: `string`):

Main product image

## `images` (type: `string`):

List of product images

## `variants` (type: `string`):

Product variants

## `attributes` (type: `string`):

Detailed specifications

## `multi_buy` (type: `string`):

Multi-buy promotion

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("dromb/dotti-au-product-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("dromb/dotti-au-product-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call dromb/dotti-au-product-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=dromb/dotti-au-product-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Dotti Australia Product Scraper",
        "description": "Scrape product data, categories, and detailed item information from Dotti Australia for price monitoring, product research, market research, availability tracking, and competitive analysis.",
        "version": "1.0",
        "x-build-id": "J1mO0rHQKoopwYZKk"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/dromb~dotti-au-product-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-dromb-dotti-au-product-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/dromb~dotti-au-product-scraper/runs": {
            "post": {
                "operationId": "runs-sync-dromb-dotti-au-product-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/dromb~dotti-au-product-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-dromb-dotti-au-product-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "operation": {
                        "title": "Operation",
                        "enum": [
                            "search",
                            "category",
                            "item",
                            "categories",
                            "search_filters"
                        ],
                        "type": "string",
                        "description": "Operation to perform: search, category, item, categories, or search_filters.",
                        "default": "search"
                    },
                    "query": {
                        "title": "Search Query",
                        "type": "string",
                        "description": "Free-text query (e.g., 'dress' or 'jeans') for searching products."
                    },
                    "url": {
                        "title": "URL",
                        "type": "string",
                        "description": "Full category or product URL for category or item operations."
                    },
                    "slug": {
                        "title": "Product Slug",
                        "type": "string",
                        "description": "Product slug (e.g., 'do-womens-new-all') for item operation."
                    },
                    "categoryId": {
                        "title": "Category ID",
                        "type": "string",
                        "description": "Category ID (e.g., '461559') for category operation."
                    },
                    "itemId": {
                        "title": "Item ID",
                        "type": "string",
                        "description": "Item ID or SKU for fetching a single item's details."
                    },
                    "parentId": {
                        "title": "Parent Category ID",
                        "type": "string",
                        "description": "Parent category ID for category operation."
                    },
                    "categoryUrl": {
                        "title": "Category URL for Filters",
                        "type": "string",
                        "description": "Category URL to fetch filters from (e.g., '/shop/do-womens-new-all')."
                    },
                    "limit": {
                        "title": "Limit",
                        "type": "integer",
                        "description": "Maximum number of items/categories to return.",
                        "default": 48
                    },
                    "page": {
                        "title": "Page",
                        "type": "integer",
                        "description": "Page number for pagination.",
                        "default": 1
                    },
                    "sort": {
                        "title": "Sort",
                        "enum": [
                            "recommended",
                            "new",
                            "price_asc",
                            "price_desc"
                        ],
                        "type": "string",
                        "description": "Sort order: recommended, new, price_asc, price_desc.",
                        "default": "recommended"
                    },
                    "details": {
                        "title": "Include Details",
                        "type": "boolean",
                        "description": "When true, return richer normalized fields where available.",
                        "default": false
                    },
                    "refresh": {
                        "title": "Refresh Categories",
                        "type": "boolean",
                        "description": "Refresh category cache from homepage when listing categories.",
                        "default": false
                    },
                    "proxy": {
                        "title": "Proxy Configuration",
                        "enum": [
                            "direct",
                            "apify",
                            "custom",
                            "auto"
                        ],
                        "type": "string",
                        "description": "Proxy configuration: 'direct', 'apify', 'custom', or 'auto'.",
                        "default": "auto"
                    },
                    "customProxyUrl": {
                        "title": "Custom Proxy URL",
                        "type": "string",
                        "description": "URL for custom proxy if 'custom' is selected."
                    },
                    "proxyCountry": {
                        "title": "Proxy Country",
                        "type": "string",
                        "description": "Country for the proxy (e.g., 'AU').",
                        "default": "AU"
                    },
                    "includeRaw": {
                        "title": "Include Raw Payload",
                        "type": "boolean",
                        "description": "Include the raw source payload in the output.",
                        "default": false
                    },
                    "disableFreeTrialGuard": {
                        "title": "Disable Free Trial Guard",
                        "type": "boolean",
                        "description": "Disable the free/trial usage limit guard (for testing).",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
