# CURIA EU Court of Justice Judgment Scraper (`jungle_synthesizer/curia-eu-court-of-justice-judgment-scraper`) Actor

Scrapes CJEU case law from the official CURIA juris search — judgments, Advocate-General opinions, and orders with ECLI/CELEX identifiers, parties, subject matter, and full-text/PDF links.

- **URL**: https://apify.com/jungle\_synthesizer/curia-eu-court-of-justice-judgment-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Education, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## CURIA EU Court of Justice Judgment Scraper

The Court of Justice of the EU publishes thousands of judgments, AG opinions, and orders on [curia.europa.eu](https://curia.europa.eu) — but there's no bulk download, no public API, and the search UI returns one page at a time. This actor scrapes the official **CURIA juris** search interface and returns structured records with ECLI identifiers, CELEX numbers, parties, dates, document types, and links to full text and PDFs on EUR-Lex.

### Features

- **Case-number mode** — look up specific cases (e.g. `C-311/18`) and get every judgment, opinion, and order in the dossier
- **Broad-search mode** — filter by court, year, and document type to collect large batches across the dossier
- Returns ECLI and CELEX identifiers for unambiguous cross-referencing with EUR-Lex, EUR-Lex SPARQL, and other legal databases
- Direct links to full-text HTML and PDF versions of each document on EUR-Lex
- Handles the Angular SPA with fingerprint-matched Chrome requests — no CAPTCHAs, no manual intervention

### Use Cases

- **Legal research & LegalTech** — build annotated case law corpora, citation graphs, or case chronologies for briefs and analysis
- **Academic research** — systematic study of EU case law trends, subject-matter frequency, or AG opinion uptake rates
- **Compliance & regulatory monitoring** — track decisions in specific areas (data protection, competition, state aid) by year and court
- **Data journalism** — quantitative analysis of CJEU output, parties, and subject matter over time
- **RAG / AI legal assistants** — index CJEU judgments as structured chunks with reliable identifiers for retrieval

### How It Works

CURIA's search frontend is an Angular SPA hosted on `infocuria.curia.europa.eu`. When you enter a case number, the site redirects to a per-case affair page that expands the full document list inline. The actor uses a Playwright-based renderer with real Chrome fingerprinting (so the backend's headless-browser guard doesn't fire) and extracts case metadata and every document entry directly from the rendered DOM.

In broad-search mode, the actor loads the case listing filtered by court, year, and document type, returning one compact record per case row.

No proxy is required. The site does not use Cloudflare or any third-party bot-management service.

### Input

#### Case-number mode (recommended for targeted lookups)

```json
{
  "caseNumbers": ["C-311/18", "C-362/14"],
  "maxItems": 50
}
````

#### Broad-search mode (batch collection by filter)

```json
{
  "court": "C",
  "year": "2023",
  "documentType": "Judgment",
  "maxItems": 200
}
```

#### Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `caseNumbers` | array of strings | No | CJEU case numbers to look up (e.g. `C-311/18`, `T-125/22`). Leave empty to use the filter parameters below. |
| `court` | string | No | Filter by court. `C` = Court of Justice, `T` = General Court, `F` = Civil Service Tribunal (archived). Blank = all courts. |
| `year` | string | No | Filter to a specific year, e.g. `2023`. Used only when `caseNumbers` is empty. |
| `documentType` | string | No | Filter by document type: `Judgment`, `Opinion` (AG opinions), `Order`. Blank = all types. |
| `maxItems` | integer | Yes | Maximum number of records to return. Default: 100. |

**Tip:** `caseNumbers` and filter parameters can be combined. When `caseNumbers` is provided, the actor uses the direct per-case URL for each number and the `court` filter is applied as a URL hint; `year` and `documentType` are used for broad-search requests only.

### Output

Each item in the dataset represents one document (judgment, opinion, or order). In broad-search mode, each item represents one case row with only the case number and parties populated.

#### Output Fields

| Field | Description |
|-------|-------------|
| `caseNumber` | Case number, e.g. `C-311/18` |
| `ecli` | European Case Law Identifier, e.g. `ECLI:EU:C:2020:559` |
| `parties` | Applicant and defendant parties, e.g. `Facebook Ireland and Schrems` |
| `court` | Court name: `Court of Justice` or `General Court` |
| `documentType` | Document type: `Judgment`, `Opinion of AG`, `Order`, or `Abstract` |
| `dateOfDocument` | Date the document was issued (DD/MM/YYYY format as shown on CURIA) |
| `subjectMatter` | Subject matter / keywords from the case title (when available) |
| `judgmentTextUrl` | URL to the full HTML text on EUR-Lex |
| `judgmentPdfUrl` | URL to the PDF version on EUR-Lex |
| `celexNumber` | CELEX identifier, e.g. `62018CJ0311` — use this to look up the document in EUR-Lex APIs |
| `caseUrl` | URL to the case listing page on CURIA |
| `scrapedAt` | ISO-8601 timestamp of when the record was scraped |

#### Example Record

```json
{
  "caseNumber": "C-311/18",
  "ecli": "ECLI:EU:C:2020:559",
  "parties": "Facebook Ireland and Schrems",
  "court": "Court of Justice",
  "documentType": "Judgment",
  "dateOfDocument": "16/07/2020",
  "subjectMatter": "",
  "judgmentTextUrl": "https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:62018CJ0311",
  "judgmentPdfUrl": "https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:62018CJ0311",
  "celexNumber": "62018CJ0311",
  "caseUrl": "https://infocuria.curia.europa.eu/tabs/affair?publishedId=C-311%2F18",
  "scrapedAt": "2026-06-12T16:14:00.000Z"
}
```

### FAQ

**Does this cover all three CJEU courts?**
Yes — Court of Justice (C-series), General Court (T-series), and the archived Civil Service Tribunal (F-series). Use the `court` filter to narrow to one.

**What's the difference between the ECLI and CELEX number?**
ECLI (`ECLI:EU:C:2020:559`) is the pan-European case identifier used across legal databases. CELEX (`62018CJ0311`) is the EUR-Lex internal identifier used in that database's API and URLs. Both are returned when available.

**How far back does the data go?**
CURIA's juris search covers the full case law archive. The scraper does not impose a year floor. Use the `year` filter to target specific years.

**Are AG opinions included?**
Yes. Advocate-General opinions appear as separate document entries within a case dossier and are returned with `documentType: "Opinion of AG"`.

**What if a case has multiple documents (e.g. judgment + AG opinion + order)?**
Each document becomes a separate output record. A case like C-311/18 (Data Protection Commissioner v Facebook Ireland and Schrems II) has three document entries.

**Is there a pagination limit?**
Broad-search mode retrieves one page of the case list (up to ~20 rows). For systematic collection of large result sets, provide explicit `caseNumbers` lists or run multiple filtered batches by year.

**Can I get the full text of the judgment?**
The actor returns the EUR-Lex URL (`judgmentTextUrl`) and PDF URL (`judgmentPdfUrl`). It does not fetch or return the full document body — use the links to retrieve the text via EUR-Lex directly or with a separate HTTP request.

### Need More Features?

Open a GitHub issue or contact us at [orbtop.com](https://orbtop.com). Common extension requests: full-text PDF extraction, pagination across multiple result pages, bulk case-number input from a spreadsheet URL, and filtering by subject-matter keyword.

### Why Use This Actor?

CURIA's search is built for human browsers — there is no API, no sitemap, no bulk export. The Angular SPA requires JavaScript execution and browser fingerprint matching. This actor handles all of that and delivers clean structured output in one run. The ECLI and CELEX identifiers make it straightforward to join with EUR-Lex datasets, CrossRef citations, or your own legal research database.

# Actor input Schema

## `sp_intended_usage` (type: `string`):

Please describe how you plan to use the data extracted by this crawler.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

Provide your email address so we can get in touch with you.

## `caseNumbers` (type: `array`):

List of CJEU case numbers to look up (e.g. C-311/18, T-125/22). Leave empty to search broadly using the court/year/documentType filters.

## `court` (type: `string`):

Filter by court. C = Court of Justice, T = General Court, F = Civil Service Tribunal (archived).

## `year` (type: `string`):

Filter results to a specific year, e.g. 2023. Used only when caseNumbers is empty.

## `documentType` (type: `string`):

Filter by document type. Leave blank for all types.

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

Maximum number of records to return.

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "caseNumbers": [
    "C-311/18",
    "C-362/14"
  ],
  "court": "",
  "year": "",
  "documentType": "",
  "maxItems": 10
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "caseNumbers": [
        "C-311/18",
        "C-362/14"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/curia-eu-court-of-justice-judgment-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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "caseNumbers": [
        "C-311/18",
        "C-362/14",
    ],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/curia-eu-court-of-justice-judgment-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 '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "caseNumbers": [
    "C-311/18",
    "C-362/14"
  ],
  "maxItems": 10
}' |
apify call jungle_synthesizer/curia-eu-court-of-justice-judgment-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=jungle_synthesizer/curia-eu-court-of-justice-judgment-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "CURIA EU Court of Justice Judgment Scraper",
        "description": "Scrapes CJEU case law from the official CURIA juris search — judgments, Advocate-General opinions, and orders with ECLI/CELEX identifiers, parties, subject matter, and full-text/PDF links.",
        "version": "0.1",
        "x-build-id": "s8WiVdfUkVnp6aH7g"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/jungle_synthesizer~curia-eu-court-of-justice-judgment-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-jungle_synthesizer-curia-eu-court-of-justice-judgment-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/jungle_synthesizer~curia-eu-court-of-justice-judgment-scraper/runs": {
            "post": {
                "operationId": "runs-sync-jungle_synthesizer-curia-eu-court-of-justice-judgment-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/jungle_synthesizer~curia-eu-court-of-justice-judgment-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-jungle_synthesizer-curia-eu-court-of-justice-judgment-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",
                "required": [
                    "maxItems"
                ],
                "properties": {
                    "sp_intended_usage": {
                        "title": "What is the intended usage of this data?",
                        "minLength": 1,
                        "type": "string",
                        "description": "Please describe how you plan to use the data extracted by this crawler."
                    },
                    "sp_improvement_suggestions": {
                        "title": "How can we improve this crawler for you?",
                        "minLength": 1,
                        "type": "string",
                        "description": "Provide any feedback or suggestions for improvements."
                    },
                    "sp_contact": {
                        "title": "Contact Email",
                        "minLength": 1,
                        "type": "string",
                        "description": "Provide your email address so we can get in touch with you."
                    },
                    "caseNumbers": {
                        "title": "Case Numbers",
                        "type": "array",
                        "description": "List of CJEU case numbers to look up (e.g. C-311/18, T-125/22). Leave empty to search broadly using the court/year/documentType filters.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "court": {
                        "title": "Court",
                        "enum": [
                            "",
                            "C",
                            "T",
                            "F"
                        ],
                        "type": "string",
                        "description": "Filter by court. C = Court of Justice, T = General Court, F = Civil Service Tribunal (archived).",
                        "default": ""
                    },
                    "year": {
                        "title": "Year",
                        "type": "string",
                        "description": "Filter results to a specific year, e.g. 2023. Used only when caseNumbers is empty.",
                        "default": ""
                    },
                    "documentType": {
                        "title": "Document Type",
                        "enum": [
                            "",
                            "Judgment",
                            "Opinion",
                            "Order"
                        ],
                        "type": "string",
                        "description": "Filter by document type. Leave blank for all types.",
                        "default": ""
                    },
                    "maxItems": {
                        "title": "Max Items",
                        "type": "integer",
                        "description": "Maximum number of records to return.",
                        "default": 100
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
