# Aladin Scraper — Korean Bookstore Bestsellers (`kdatafactory/aladin-scraper`) Actor

Scrape live bestseller rankings from Aladin (알라딘), one of Korea's big-3 bookstores and its largest used-book market: rank, title, author, publisher, price (KRW), category, cover and URL as clean JSON. For used-book arbitrage, translation-rights scouting and publishing analytics.

- **URL**: https://apify.com/kdatafactory/aladin-scraper.md
- **Developed by:** [Seok June Park](https://apify.com/kdatafactory) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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/docs.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.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/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

## Aladin Scraper — Korean Bookstore Bestsellers 📖

Scrape live **bestseller rankings** from [Aladin (알라딘)](https://www.aladin.co.kr) — one of Korea's **big-3 bookstores** and the country's **largest used-book marketplace** — as clean, structured JSON. Get rank, title, author, publisher, new price (KRW), category, and cover image for every book on any bestseller list in one run.

Aladin is the go-to name in Korea for **used books (중고책)**: it runs both a huge online used marketplace and dozens of offline used-book stores. That makes its bestseller list uniquely useful for **used-book arbitrage** and second-hand pricing research — you get the titles with the highest resale demand, straight from the source.

> **Try it free.** Apify's free plan includes $5 of monthly platform credit — at **$2.00 / 1,000 results** that's roughly **2,500 books** from this actor, no credit card required. Set your input, click Start, and export JSON/CSV/Excel.

---

### What it does

This actor reads Aladin's own public bestseller pages (the same server-rendered pages any visitor sees), so results are fast and complete — no fragile full-page scraping, no headless browser, and **no API key required**. You can scrape:

- **The overall bestseller list** (종합), or
- **Any category list** — e.g. fiction (소설/시/희곡), business (경제경영), self-help (자기계발), humanities (인문학), essays (에세이), history (역사), and 20+ more.

Aladin publishes up to ~1,000 ranks per list, so you can pull a shallow Top-100 or a deep Top-1,000 snapshot.

> **Why Aladin?** Alongside Kyobo and Yes24, Aladin is one of Korea's big-3 bookstores — but it's the one that built its brand on the **used-book market**. Its bestseller list is a live demand signal for both new and second-hand books, which is exactly what resellers, publishers, and rights scouts want. This actor turns that list into a structured dataset you can filter, price-model, and pipe into your own tools.

---

### Input

| Field | Type | Description |
|-------|------|-------------|
| `mode` | string | What to scrape. Currently only `bestseller` (Aladin's bestseller ranking). Default `bestseller`. |
| `category` | string | Which bestseller list. A Korean category name (e.g. `종합`, `소설/시/희곡`, `경제경영`, `자기계발`, `인문학`, `에세이`, `역사`) **or** a raw Aladin category id (CID) — e.g. `0` = overall, `1` = fiction, `170` = business. Blank = `종합` (overall). |
| `maxItems` | integer | Max books to collect. Default `100`, max `1000`. |
| `proxyConfiguration` | object | Proxy settings (see below). Defaults to a direct connection. |

#### Input example

```json
{
  "mode": "bestseller",
  "category": "종합",
  "maxItems": 100
}
````

```json
{
  "mode": "bestseller",
  "category": "경제경영",
  "maxItems": 200
}
```

***

### Output

Each bestseller book is one dataset record. `price_krw` is the **new-book selling price** in Korean won (Aladin's discounted 판매가 — the price you actually pay for a new copy). `rank` is the book's position on the chosen bestseller list. `category` echoes the list you scraped.

```json
{
  "source": "aladin",
  "rank": 1,
  "item_id": "312732931",
  "title": "파쇄",
  "author": "구병모",
  "publisher": "위즈덤하우스",
  "price_krw": 11700,
  "used_price_krw": null,
  "category": "종합",
  "url": "https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=312732931",
  "image_url": "https://image.aladin.co.kr/product/31273/29/cover200/k592832565_1.jpg",
  "scraped_at": "2026-07-14T14:41:44+09:00"
}
```

A full 40-item sample from a real run is in [`samples/sample-output.json`](samples/sample-output.json).

| Field | Meaning |
|-------|---------|
| `source` | Always `"aladin"`. |
| `rank` | Position on the bestseller list (1 = top). |
| `item_id` | Aladin product `ItemId`. |
| `title` | Full book title. |
| `author` | Public author credit (지은이), as Aladin shows it. |
| `publisher` | Publisher name when shown, else `null` (best-effort — see limitations). |
| `price_krw` | New-book selling price in KRW (Aladin's discounted 판매가). |
| `used_price_krw` | Lowest used price **only if** the bestseller card shows one inline — in practice almost always `null` (see limitations). |
| `category` | The bestseller list scraped (e.g. `종합`, `경제경영`). |
| `url` | Product page URL. |
| `image_url` | Cover image URL. |
| `scraped_at` | ISO-8601 timestamp (KST, UTC+9). |

The critical fields — `rank`, `title`, `author`, and `price_krw` — populated on **40/40** records in the live test, along with `publisher`, `url`, `image_url`, and `category`. `used_price_krw` is best-effort and was `null` on all 40 (Aladin doesn't expose a used price on the bestseller card — see Known limitations).

***

### Use cases

- **Used-book arbitrage & resale** — Aladin is Korea's biggest used-book market, so its bestseller list is a live demand signal for the titles most worth sourcing second-hand. Track which books top the charts, then price and flip them.
- **Publishing & translation-rights scouting** — since **Han Kang won the 2024 Nobel Prize in Literature** (Korea's first), foreign publishers and agents are actively hunting Korean titles. A live bestseller feed by category is a fast way to spot what's selling and shortlist rights candidates.
- **Bestseller & trend tracking** — schedule daily/weekly snapshots to chart how ranks move over time, by category, and benchmark Aladin against other Korean bookstores.
- **AI agents & datasets** — feed structured Korean book data (rank, author, publisher, price, cover) into recommendation models, dashboards, or LLM agents.

***

### ❓ FAQ

**Is it legal to scrape this data?**
This actor collects only public, non-personal bestseller data — the same rankings any visitor sees on aladin.co.kr without logging in. Author names are the public book credits, not personal contact data. You are responsible for how you use the data; see the legality note below.

**What does it cost in practice?**
$2.00 per 1,000 results (launch pricing) + a few cents of platform usage. Example: a 100-result daily pull costs about **$0.20/day**. Apify's free $5 monthly credit covers **~2,500 results** (5 ÷ 2 × 1,000).

**Do I need an Aladin API key?**
No. Aladin offers an official OpenAPI (TTB) that needs a registered key, but this actor deliberately uses only the **public web pages**, so it works with zero configuration.

**Do I need to configure proxies?**
No — the default settings work out of the box. Aladin serves its bestseller pages without a bot wall, so the actor runs fine on a **direct connection**. For very heavy pulls you can optionally enable Apify Proxy — see the proxy note below.

**How fresh is the data?**
Every run scrapes the live Aladin bestseller list at run time. Schedule the actor for recurring snapshots (e.g. daily rank tracking).

**What is NOT included?**
Per-book used prices (they live on the individual product page, which this actor doesn't crawl — see limitations), reviews, and stock counts. `publisher` is best-effort. Titles, authors, and categories come as Korean strings.

***

### 🤖 Use with AI agents (MCP)

Call this Actor as a tool from Claude or any MCP-compatible AI agent — no glue code. Point your MCP client at Apify's server, scoped to this Actor:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=kdatafactory/aladin-scraper",
      "headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }
    }
  }
}
```

Your agent can then pull Korean bestseller book data on demand — no scraping code in your app. Grab a free token from [Apify → Integrations](https://console.apify.com/settings/integrations).

### 🇰🇷 More Korean data actors

This actor is part of a suite of Korean-platform scrapers by the same maintainer:

- **[yes24-bestseller-scraper](https://apify.com/kdatafactory/yes24-bestseller-scraper) — bestseller rankings from Yes24, another of Korea's big-3 bookstores.** Run it alongside this actor to compare bestseller lists across stores.
- **[ridibooks-scraper](https://apify.com/kdatafactory/ridibooks-scraper) — e-book bestsellers and rankings from RIDIBOOKS, Korea's leading e-book platform.**
- Browse all: [apify.com/kdatafactory](https://apify.com/kdatafactory)

***

### Rate limiting & legality

- The actor collects **only public, non-authenticated data**. It never logs in and never touches private endpoints.
- **No personal data** is collected — author names are public book credits, nothing more.
- Requests are rate-limited: one page at a time with a ≥ 500 ms delay between requests, to stay gentle on Aladin's servers.
- You are responsible for using the data in line with Aladin's terms of service and applicable law.

#### Known limitations (honesty note)

- **`used_price_krw` is best-effort and almost always `null`.** Aladin's bestseller cards do **not** show a used price inline — the used-copy price lives on each book's own product page. This actor deliberately does **not** crawl per-book pages just to fetch it (that would be slow and heavy), so this field is populated only in the rare case a card exposes a used price directly. It was `null` on 40/40 records in the live test. If you need per-book used prices, that would be a separate, heavier crawl.
- **`publisher` is best-effort.** It populated on 40/40 books in the live test, but Aladin's markup can vary, so it may be `null` for some listings. `rank`, `title`, `author`, and `price_krw` are the guaranteed-populated core fields.
- **`price_krw` is the new-book selling price** (Aladin's discounted 판매가), not the list price (정가) or any used price.
- **Titles, authors, publishers, and categories are Korean strings** — this actor does not translate them.
- **Only the `bestseller` mode is supported** today (overall + category bestseller lists). Search and per-book detail are out of scope.

***

*If this actor saves you time, a rating on the [Store page](https://apify.com/kdatafactory/aladin-scraper) helps a solo maintainer a lot. Found an issue? Open it in the Issues tab — I respond fast.*

# Actor input Schema

## `mode` (type: `string`):

What to scrape. Currently only Aladin's bestseller ranking is supported.

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

Which bestseller list to scrape. A Korean category name (e.g. '종합', '소설/시/희곡', '경제경영', '자기계발', '인문학', '에세이', '역사') or a raw Aladin category id (CID, e.g. 0 = overall, 1 = fiction, 170 = business). Blank = 종합 (overall bestseller).

## `maxItems` (type: `integer`):

Maximum number of bestseller books to collect. Aladin publishes up to ~1,000 ranks per list.

## `proxyConfiguration` (type: `object`):

Proxy settings. Aladin serves its bestseller pages without a bot wall, so the actor runs fine on a direct connection (default). If you ever see blocks at high volume, enable Apify Proxy here.

## Actor input object example

```json
{
  "mode": "bestseller",
  "category": "",
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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("kdatafactory/aladin-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("kdatafactory/aladin-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 kdatafactory/aladin-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Aladin Scraper — Korean Bookstore Bestsellers",
        "description": "Scrape live bestseller rankings from Aladin (알라딘), one of Korea's big-3 bookstores and its largest used-book market: rank, title, author, publisher, price (KRW), category, cover and URL as clean JSON. For used-book arbitrage, translation-rights scouting and publishing analytics.",
        "version": "0.1",
        "x-build-id": "YIjCwg5moUGrH0d0g"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/kdatafactory~aladin-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-kdatafactory-aladin-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/kdatafactory~aladin-scraper/runs": {
            "post": {
                "operationId": "runs-sync-kdatafactory-aladin-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/kdatafactory~aladin-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-kdatafactory-aladin-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": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "bestseller"
                        ],
                        "type": "string",
                        "description": "What to scrape. Currently only Aladin's bestseller ranking is supported.",
                        "default": "bestseller"
                    },
                    "category": {
                        "title": "Bestseller category",
                        "type": "string",
                        "description": "Which bestseller list to scrape. A Korean category name (e.g. '종합', '소설/시/희곡', '경제경영', '자기계발', '인문학', '에세이', '역사') or a raw Aladin category id (CID, e.g. 0 = overall, 1 = fiction, 170 = business). Blank = 종합 (overall bestseller).",
                        "default": ""
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Maximum number of bestseller books to collect. Aladin publishes up to ~1,000 ranks per list.",
                        "default": 100
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Proxy settings. Aladin serves its bestseller pages without a bot wall, so the actor runs fine on a direct connection (default). If you ever see blocks at high volume, enable Apify Proxy here.",
                        "default": {
                            "useApifyProxy": 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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
