# Vancouver Property Signal Monitor (`stevennguyen/vancouver-property-signal-monitor`) Actor

Monitor Vancouver Open Data for rental standards issues, building permits, and assessment signals with address enrichment and aggregated property-level lead scoring.

- **URL**: https://apify.com/stevennguyen/vancouver-property-signal-monitor.md
- **Developed by:** [Steven Nguyen](https://apify.com/stevennguyen) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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

## Vancouver Property Signal Monitor

Monitor City of Vancouver Open Data for property, rental, and redevelopment signals. The Actor turns public rental standards issues, recent building permits, and property assessment records into lead-scored, CRM-ready property records.

This is not a foreclosure or tax-delinquency scraper. Vancouver's public data is better for property intelligence, rental standards monitoring, redevelopment scouting, and contractor/vendor lead generation.

By default, the Actor emits **one aggregated lead per normalized property address**. It joins matching rental standards issues, building permits, and assessment signals into a stronger property-level lead with `signal_types`, `signal_count`, `source_records`, and combined `lead_reasons`. Use `outputMode: "raw"` for one record per source row, or `outputMode: "both"` to emit aggregate leads plus raw source records.

Address enrichment is enabled by default. The Actor takes high-scoring seed addresses and queries the other Vancouver datasets by address, so a rental-standards lead can intentionally pick up matching permit and assessment records instead of relying on unrelated top-N source queries to overlap by chance.

### Sources

| Source | Dataset | What it contributes |
|---|---|---|
| Rental standards | `rental-standards-current-issues` | Active rental buildings with outstanding standards issues, issue counts, units, operator, source detail URL. |
| Building permits | `issued-building-permits` | Recent issued permits, project value, type of work, project description, applicant, contractor, neighbourhood. |
| Property assessment | `property-tax-report` | Land/improvement value, year built, zoning, PID/folio, assessment year. Useful for land-heavy redevelopment signals. |

### Example: rental + permit signals

```json
{
  "signals": ["rental_standards", "building_permits"],
  "neighbourhoods": "Downtown, West End, Mount Pleasant",
  "minOutstandingIssues": 1,
  "minProjectValue": 50000,
  "sinceDays": 30,
  "outputMode": "aggregated",
  "enableAddressEnrichment": true,
  "maxEnrichmentAddresses": 20,
  "enrichmentLimit": 5,
  "onlyChanges": true,
  "compareWithPreviousRun": true,
  "stateStoreName": "vancouver-property-signal-monitor-state",
  "stateKey": "vancouver-core-property-signals"
}
````

### Example: redevelopment scouting

```json
{
  "signals": ["tax_assessment", "building_permits"],
  "minLandValue": 1500000,
  "minProjectValue": 250000,
  "permitKeywords": "demolition, new building, multiplex, change of use",
  "sinceDays": 60,
  "maxItemsPerSource": 100
}
```

### Output fields

Each dataset item includes normalized fields where available:

- `change_type`: `new`, `updated`, `unchanged`, or `missing_from_current_run`
- `signal_score`: 0-100 lead score
- `signal_type`: `aggregated_property`, `rental_standards`, `building_permit`, or `tax_assessment`
- `signal_types`: source signal types joined into an aggregate lead
- `signal_count`: number of source records joined into an aggregate lead
- `property_address`
- `neighbourhood`
- `lead_reasons`
- `recommended_buyer`
- `business_operator`
- `total_outstanding_issues`
- `total_units`
- `project_value`
- `permit_number`
- `issue_date`
- `type_of_work`
- `permit_category`
- `applicant`
- `contractor`
- `pid`, `folio`
- `land_value`, `improvement_value`, `year_built`, `zoning_district`
- `source_url`
- `source_urls`
- `source_records`: compact source-record references for aggregate leads
- `raw`

The run summary is written to key-value store key `OUTPUT`.

### Change detection

When `compareWithPreviousRun` is enabled, this Actor stores fingerprints in a named key-value store (`stateStoreName`) under `stateKey`. Later runs mark records as new, updated, unchanged, or missing. Keep both values stable for scheduled monitors and use different keys for different watchlist/filter sets.

### Caveats

- City source schemas can change.
- Vancouver Open Data does not expose the same foreclosure/tax-delinquency signals available in many US counties.
- Owner names are generally not available in these datasets.
- Treat this as lead intelligence and research, not legal/financial advice. Verify source URLs before acting on high-stakes decisions.

# Actor input Schema

## `signals` (type: `array`):

Public-data signal groups to monitor.

## `neighbourhoods` (type: `string`):

Optional comma-separated Vancouver local areas, e.g. Downtown, West End, Mount Pleasant.

## `searchTerms` (type: `string`):

Optional comma-separated terms matched against all public fields.

## `permitKeywords` (type: `string`):

Comma-separated terms for building permit filtering/scoring.

## `minOutstandingIssues` (type: `integer`):

Minimum outstanding rental standards issues.

## `minProjectValue` (type: `integer`):

Minimum building permit project value in CAD.

## `minLandValue` (type: `integer`):

Minimum current land value for tax assessment signal records.

## `sinceDays` (type: `integer`):

Only fetch issued permits since this many days ago.

## `reportYear` (type: `string`):

Report year for property-tax assessment records, e.g. 2026.

## `maxItemsPerSource` (type: `integer`):

Maximum records to request per source. Vancouver Open Data caps individual requests, so this Actor keeps the MVP intentionally small.

## `outputMode` (type: `string`):

aggregated emits one joined record per address. raw emits one record per source item. both emits aggregate records plus source records.

## `enableAddressEnrichment` (type: `boolean`):

For high-scoring seed addresses, query other Vancouver datasets by address to intentionally create multi-signal leads.

## `maxEnrichmentAddresses` (type: `integer`):

Maximum number of highest-scoring addresses to enrich across other sources.

## `enrichmentLimit` (type: `integer`):

Maximum matching records fetched from each enrichment source for each seed address.

## `onlyChanges` (type: `boolean`):

Skip unchanged records when compareWithPreviousRun is enabled.

## `emitUnchanged` (type: `boolean`):

Emit unchanged records too. Useful for first-run exports and debugging.

## `compareWithPreviousRun` (type: `boolean`):

Persist fingerprints and mark records as new, updated, unchanged, or missing\_from\_current\_run.

## `stateStoreName` (type: `string`):

Named key-value store used to persist monitor state across Apify runs. Keep stable for scheduled monitors.

## `stateKey` (type: `string`):

Key-value store key used to persist monitor state. Use a different key for each watchlist/filter set.

## Actor input object example

```json
{
  "signals": [
    "rental_standards",
    "building_permits"
  ],
  "permitKeywords": "demolition, new building, multiplex, renovation, addition, alteration, change of use",
  "minOutstandingIssues": 1,
  "minProjectValue": 50000,
  "minLandValue": 1000000,
  "sinceDays": 30,
  "maxItemsPerSource": 100,
  "outputMode": "aggregated",
  "enableAddressEnrichment": true,
  "maxEnrichmentAddresses": 20,
  "enrichmentLimit": 5,
  "onlyChanges": true,
  "emitUnchanged": false,
  "compareWithPreviousRun": true,
  "stateStoreName": "vancouver-property-signal-monitor-state",
  "stateKey": "vancouver-property-signal-monitor-state"
}
```

# Actor output Schema

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

Lead-scored property signal records emitted by this run.

## `summary` (type: `string`):

JSON summary with source/signal/change counts and filters used.

# 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 = {
    "signals": [
        "rental_standards",
        "building_permits"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("stevennguyen/vancouver-property-signal-monitor").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 = { "signals": [
        "rental_standards",
        "building_permits",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("stevennguyen/vancouver-property-signal-monitor").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 '{
  "signals": [
    "rental_standards",
    "building_permits"
  ]
}' |
apify call stevennguyen/vancouver-property-signal-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=stevennguyen/vancouver-property-signal-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Vancouver Property Signal Monitor",
        "description": "Monitor Vancouver Open Data for rental standards issues, building permits, and assessment signals with address enrichment and aggregated property-level lead scoring.",
        "version": "0.4",
        "x-build-id": "3TYAUrKWjdarhN98p"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/stevennguyen~vancouver-property-signal-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-stevennguyen-vancouver-property-signal-monitor",
                "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/stevennguyen~vancouver-property-signal-monitor/runs": {
            "post": {
                "operationId": "runs-sync-stevennguyen-vancouver-property-signal-monitor",
                "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/stevennguyen~vancouver-property-signal-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-stevennguyen-vancouver-property-signal-monitor",
                "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": {
                    "signals": {
                        "title": "Signals",
                        "type": "array",
                        "description": "Public-data signal groups to monitor.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "rental_standards",
                                "building_permits",
                                "tax_assessment"
                            ],
                            "enumTitles": [
                                "Rental standards issues",
                                "Issued building permits",
                                "Property tax assessment signals"
                            ]
                        },
                        "default": [
                            "rental_standards",
                            "building_permits"
                        ]
                    },
                    "neighbourhoods": {
                        "title": "Neighbourhoods",
                        "type": "string",
                        "description": "Optional comma-separated Vancouver local areas, e.g. Downtown, West End, Mount Pleasant."
                    },
                    "searchTerms": {
                        "title": "Search terms",
                        "type": "string",
                        "description": "Optional comma-separated terms matched against all public fields."
                    },
                    "permitKeywords": {
                        "title": "Permit keywords",
                        "type": "string",
                        "description": "Comma-separated terms for building permit filtering/scoring.",
                        "default": "demolition, new building, multiplex, renovation, addition, alteration, change of use"
                    },
                    "minOutstandingIssues": {
                        "title": "Minimum rental issues",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum outstanding rental standards issues.",
                        "default": 1
                    },
                    "minProjectValue": {
                        "title": "Minimum permit project value",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum building permit project value in CAD.",
                        "default": 50000
                    },
                    "minLandValue": {
                        "title": "Minimum land value",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Minimum current land value for tax assessment signal records.",
                        "default": 1000000
                    },
                    "sinceDays": {
                        "title": "Permit lookback days",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Only fetch issued permits since this many days ago.",
                        "default": 30
                    },
                    "reportYear": {
                        "title": "Property tax report year",
                        "type": "string",
                        "description": "Report year for property-tax assessment records, e.g. 2026."
                    },
                    "maxItemsPerSource": {
                        "title": "Max items per source",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum records to request per source. Vancouver Open Data caps individual requests, so this Actor keeps the MVP intentionally small.",
                        "default": 100
                    },
                    "outputMode": {
                        "title": "Output mode",
                        "enum": [
                            "aggregated",
                            "raw",
                            "both"
                        ],
                        "type": "string",
                        "description": "aggregated emits one joined record per address. raw emits one record per source item. both emits aggregate records plus source records.",
                        "default": "aggregated"
                    },
                    "enableAddressEnrichment": {
                        "title": "Enable address enrichment",
                        "type": "boolean",
                        "description": "For high-scoring seed addresses, query other Vancouver datasets by address to intentionally create multi-signal leads.",
                        "default": true
                    },
                    "maxEnrichmentAddresses": {
                        "title": "Max enrichment addresses",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum number of highest-scoring addresses to enrich across other sources.",
                        "default": 20
                    },
                    "enrichmentLimit": {
                        "title": "Enrichment records per address/source",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "Maximum matching records fetched from each enrichment source for each seed address.",
                        "default": 5
                    },
                    "onlyChanges": {
                        "title": "Only emit changes",
                        "type": "boolean",
                        "description": "Skip unchanged records when compareWithPreviousRun is enabled.",
                        "default": true
                    },
                    "emitUnchanged": {
                        "title": "Emit unchanged records",
                        "type": "boolean",
                        "description": "Emit unchanged records too. Useful for first-run exports and debugging.",
                        "default": false
                    },
                    "compareWithPreviousRun": {
                        "title": "Compare with previous run",
                        "type": "boolean",
                        "description": "Persist fingerprints and mark records as new, updated, unchanged, or missing_from_current_run.",
                        "default": true
                    },
                    "stateStoreName": {
                        "title": "State store name",
                        "type": "string",
                        "description": "Named key-value store used to persist monitor state across Apify runs. Keep stable for scheduled monitors.",
                        "default": "vancouver-property-signal-monitor-state"
                    },
                    "stateKey": {
                        "title": "State key",
                        "type": "string",
                        "description": "Key-value store key used to persist monitor state. Use a different key for each watchlist/filter set.",
                        "default": "vancouver-property-signal-monitor-state"
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
