diff --git a/src/content/docs/guides/collecting/index.mdx b/src/content/docs/guides/collecting/index.mdx
index 0d67c7596..20a9342c0 100644
--- a/src/content/docs/guides/collecting/index.mdx
+++ b/src/content/docs/guides/collecting/index.mdx
@@ -69,6 +69,17 @@ this = string(message).parse_json()
See the [message broker guide](/guides/collecting/read-from-message-brokers)
for broker-specific configurations.
+### Data stores
+
+Query external data stores such as MySQL and ClickHouse:
+
+```tql
+from_clickhouse sql="SELECT * FROM events WHERE severity >= 3", tls=false
+```
+
+See the [data store guide](/guides/collecting/read-from-data-stores) for table
+reads, SQL pushdown, metadata inspection, and live MySQL polling.
+
### Network data
Receive data over TCP or UDP sockets, or capture packets from network
@@ -98,5 +109,6 @@ connections.
- collecting/read-and-watch-files
- collecting/fetch-via-http-and-apis
- collecting/read-from-message-brokers
+- collecting/read-from-data-stores
- collecting/get-data-from-the-network
- routing/send-to-destinations
diff --git a/src/content/docs/guides/collecting/read-from-data-stores.mdx b/src/content/docs/guides/collecting/read-from-data-stores.mdx
new file mode 100644
index 000000000..65485ac5b
--- /dev/null
+++ b/src/content/docs/guides/collecting/read-from-data-stores.mdx
@@ -0,0 +1,146 @@
+---
+title: Read from data stores
+---
+
+This guide shows you how to read from external data stores with TQL. You'll learn how to read full tables, push filters into SQL, inspect metadata, and stream new rows from MySQL.
+
+Today, this guide focuses on from_mysql and from_clickhouse .
+As Tenzir adds more data store integrations, the same patterns will apply.
+
+## Read a full table
+
+Use `table=...` when you want to fetch all rows from a table.
+
+Read a ClickHouse table:
+
+```tql
+from_clickhouse table="security.events",
+ host="clickhouse.example.com",
+ password=secret("CLICKHOUSE_PASSWORD"),
+ tls=false
+```
+
+Or use a ClickHouse URI:
+
+```tql
+from_clickhouse uri="clickhouse://default:secret@clickhouse.example.com:9000/security",
+ table="events",
+ tls=false
+```
+
+Read a MySQL table:
+
+```tql
+from_mysql table="users",
+ host="mysql.example.com",
+ user="tenzir",
+ password=secret("MYSQL_PASSWORD"),
+ database="identity"
+```
+
+Use this mode when you want Tenzir to treat the table as the source of truth and
+apply filtering later in the pipeline.
+
+## Push filters and projections into SQL
+
+Use `sql=...` when the data store should do the filtering, sorting, or column
+selection before Tenzir receives the rows.
+
+Filter in ClickHouse:
+
+```tql
+from_clickhouse sql="SELECT time, host, severity, message FROM events WHERE severity >= 3 ORDER BY time DESC",
+ host="clickhouse.example.com",
+ password=secret("CLICKHOUSE_PASSWORD"),
+ tls=false
+```
+
+Filter in MySQL:
+
+```tql
+from_mysql sql="SELECT id, user, last_login FROM users WHERE active = 1 ORDER BY last_login DESC",
+ host="mysql.example.com",
+ user="tenzir",
+ password=secret("MYSQL_PASSWORD"),
+ database="identity"
+```
+
+This pattern reduces network traffic and lets you use the source system's query
+planner and indexes.
+
+## Inspect metadata
+
+Both operators can return metadata instead of table rows.
+
+List ClickHouse tables in a database:
+
+```tql
+from_clickhouse sql="SHOW TABLES FROM security",
+ host="clickhouse.example.com",
+ password=secret("CLICKHOUSE_PASSWORD"),
+ tls=false
+```
+
+Show the columns of a MySQL table:
+
+```tql
+from_mysql table="users",
+ show="columns",
+ host="mysql.example.com",
+ user="tenzir",
+ password=secret("MYSQL_PASSWORD"),
+ database="identity"
+```
+
+Use metadata queries when you want to discover available tables, inspect a
+schema, or validate assumptions before you run a larger pipeline. In
+ClickHouse, prefer regular SQL such as `SHOW`, `DESCRIBE`, or queries against
+system catalogs.
+
+## Poll for new rows from MySQL
+
+MySQL supports a live polling mode for tables with a monotonically increasing
+integer tracking column.
+
+```tql
+from_mysql table="audit_log",
+ live=true,
+ tracking_column="id",
+ host="mysql.example.com",
+ user="tenzir",
+ password=secret("MYSQL_PASSWORD"),
+ database="security"
+where severity == "high"
+```
+
+Use this mode when you want to turn a database table into a continuously polled
+event source.
+
+`from_clickhouse` does not currently provide a comparable live mode. It runs a
+query, emits the result, and then finishes.
+
+## Shape rows after reading
+
+Both operators produce structured events, so you can transform the result right
+away.
+
+```tql
+from_clickhouse sql="SELECT host, severity, message FROM events",
+ host="clickhouse.example.com",
+ password=secret("CLICKHOUSE_PASSWORD"),
+ tls=false
+where severity >= 3
+message = message.to_upper()
+```
+
+This lets you treat database rows like any other event stream in Tenzir.
+
+## See also
+
+- collecting/read-from-message-brokers
+- transformation/filter-and-select-data
+- routing/send-to-destinations
+- from_clickhouse
+- from_mysql
+- clickhouse
+- mysql
diff --git a/src/content/docs/guides/routing/send-to-destinations.mdx b/src/content/docs/guides/routing/send-to-destinations.mdx
index a2e5a7662..1a148c467 100644
--- a/src/content/docs/guides/routing/send-to-destinations.mdx
+++ b/src/content/docs/guides/routing/send-to-destinations.mdx
@@ -3,13 +3,14 @@ title: Send to destinations
---
This guide shows you how to send data to various destinations using TQL output
-operators. You'll learn about destination operators, file output patterns, and
-expression-based serialization.
+operators. You'll learn about message destinations, data stores, file output
+patterns, and expression-based serialization.
## Destination operators
-TQL provides `to_*` operators for sending events to various destinations. These
-operators accept expressions for flexible serialization.
+TQL provides `to_*` operators for sending events to various destinations.
+Message-oriented operators accept expressions for flexible serialization, while
+data store operators write structured rows directly.
### Message brokers
@@ -51,6 +52,34 @@ subscribe "security-events"
to_amazon_kinesis "security-events"
```
+### Data stores
+
+Send events to data stores like clickhouse and
+snowflake .
+
+Send structured events to ClickHouse:
+
+```tql
+subscribe "security-events"
+to_clickhouse table="alerts", primary=time, mode="create_append", tls=false
+```
+
+Write batches to Snowflake with bulk ingestion:
+
+```tql
+export
+to_snowflake \
+ account_identifier="org-account",
+ user_name="tenzir_user",
+ password=secret("SNOWFLAKE_PASSWORD"),
+ database="SECURITY",
+ schema="PUBLIC",
+ table="EVENTS"
+```
+
+These operators preserve event structure instead of requiring a `message`
+expression.
+
### Analytics platforms
Send data to platforms like [Splunk](/integrations/splunk),
@@ -76,8 +105,8 @@ to_opensearch "https://opensearch.example.com:9200",
### Cloud services
-Route events to cloud destinations like amazon/sqs
-and google/cloud-pubsub .
+Route events to cloud destinations like [Amazon SQS](/integrations/amazon/sqs)
+and [Google Cloud Pub/Sub](/integrations/google/cloud-pubsub).
Send to SQS:
@@ -90,7 +119,9 @@ Send to Pub/Sub:
```tql
subscribe "events"
-to_google_cloud_pubsub project_id="my-project", topic_id="events", message=this.print_ndjson()
+to_google_cloud_pubsub project_id="my-project",
+ topic_id="events",
+ message=this.print_json()
```
## File output
@@ -139,9 +170,10 @@ to_tcp "collector.example.com:12201" {
}
```
-## Expression-based serialization
+## Expression-based serialization for message destinations
-Destination operators use expressions for flexible message formatting:
+Message-oriented destination operators use expressions for flexible message
+formatting:
### Serialize the entire event
@@ -179,7 +211,7 @@ Route events to different destinations based on content:
to_kafka f"events.{event_type}"
```
-## See Also
+## See also
- fork
- to_kafka
@@ -190,5 +222,8 @@ to_kafka f"events.{event_type}"
- write_delimited
- write_ndjson
- print_ndjson
+- collecting/read-from-data-stores
- routing/load-balance-pipelines
- routing/split-and-merge-streams
+- to_clickhouse
+- to_snowflake
diff --git a/src/content/docs/integrations/clickhouse.excalidraw b/src/content/docs/integrations/clickhouse.excalidraw
new file mode 100644
index 000000000..d83483999
--- /dev/null
+++ b/src/content/docs/integrations/clickhouse.excalidraw
@@ -0,0 +1,2967 @@
+{
+ "type": "excalidraw",
+ "version": 2,
+ "source": "https://app.excalidraw.com",
+ "elements": [
+ {
+ "id": "8MN5I4hT3wVen_QUHAUnu",
+ "type": "rectangle",
+ "x": 1023.6306664679144,
+ "y": 476.4109026851011,
+ "width": 151.42450136036612,
+ "height": 143.23101048605469,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "Zy",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 239993862,
+ "version": 522,
+ "versionNonce": 296825663,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "Q90BHXvcB9LwBRiLiSjA9"
+ },
+ {
+ "id": "g_xmr_rAUoQx04wSxq2yQ",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1780756340496,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "Q90BHXvcB9LwBRiLiSjA9",
+ "type": "text",
+ "x": 1061.767916385158,
+ "y": 481.4109026851011,
+ "width": 75.1500015258789,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "Zz",
+ "roundness": null,
+ "seed": 1597739846,
+ "version": 502,
+ "versionNonce": 1309437506,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1776405904244,
+ "link": null,
+ "locked": false,
+ "text": "Database",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": "8MN5I4hT3wVen_QUHAUnu",
+ "originalText": "Database",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "type": "rectangle",
+ "version": 511,
+ "versionNonce": 925925210,
+ "index": "a0",
+ "isDeleted": true,
+ "id": "pxsLHRu0DqDRMIfSBq1IP",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 312.6865893307831,
+ "y": 326,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 438.62682133843384,
+ "height": 260,
+ "seed": 612159942,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "Y7J38UXbiwPtdxyo9fYNr",
+ "type": "rectangle",
+ "x": 392.6865893307831,
+ "y": 406,
+ "width": 280,
+ "height": 100,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "a1",
+ "roundness": null,
+ "seed": 1774889222,
+ "version": 25,
+ "versionNonce": 1906129734,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "lXsZ5Iq09sJ6hKvV8PUW9",
+ "type": "text",
+ "x": 497.211590856662,
+ "y": 411,
+ "width": 70.94999694824219,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "hachure",
+ "strokeWidth": 2,
+ "strokeStyle": "dashed",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "a2",
+ "roundness": null,
+ "seed": 1306236998,
+ "version": 25,
+ "versionNonce": 1851491354,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "text": "Pipeline",
+ "fontSize": 20,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": "Y7J38UXbiwPtdxyo9fYNr",
+ "originalText": "Pipeline",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "type": "rectangle",
+ "version": 489,
+ "versionNonce": 1512170118,
+ "index": "a3",
+ "isDeleted": true,
+ "id": "MS113qib66n_byZ-dYsHP",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "dotted",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 852.6865893307831,
+ "y": 326,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 438.62682133843384,
+ "height": 260,
+ "seed": 948739974,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "7tWVFQ1hznFjHbRX77A40",
+ "type": "rectangle",
+ "x": 932.6865893307831,
+ "y": 386,
+ "width": 300,
+ "height": 180,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "a4",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 236633798,
+ "version": 108,
+ "versionNonce": 994570458,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "2J7vPgwu8j0T0zofCOk6w",
+ "type": "text",
+ "x": 1045.1115885678437,
+ "y": 391,
+ "width": 75.1500015258789,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "a5",
+ "roundness": null,
+ "seed": 589493766,
+ "version": 90,
+ "versionNonce": 1913627078,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "text": "Database",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": "7tWVFQ1hznFjHbRX77A40",
+ "originalText": "Database",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "e_FOcnN9fF4M0BdfxaDrN",
+ "type": "rectangle",
+ "x": 972.6865893307831,
+ "y": 426,
+ "width": 220,
+ "height": 100,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "a6",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 815940934,
+ "version": 127,
+ "versionNonce": 831047066,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "rrcWQeq44H5YTrv0GY8Bx",
+ "type": "text",
+ "x": 1050.5949221554902,
+ "y": 431,
+ "width": 64.18333435058594,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "a7",
+ "roundness": null,
+ "seed": 1207282822,
+ "version": 114,
+ "versionNonce": 478378246,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "text": "Schemas",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": "e_FOcnN9fF4M0BdfxaDrN",
+ "originalText": "Schemas",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "type": "arrow",
+ "version": 1532,
+ "versionNonce": 2052129370,
+ "isDeleted": true,
+ "id": "ijxomphViqLxL8CKt_0IF",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 692.6865893307831,
+ "y": 466,
+ "strokeColor": "#e03131",
+ "backgroundColor": "#ffec99",
+ "width": 220,
+ "height": 0,
+ "seed": 1188703174,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "7tWVFQ1hznFjHbRX77A40",
+ "mode": "orbit",
+ "fixedPoint": [
+ 0.4444444444444442,
+ 0.4444444444444444
+ ]
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 220,
+ 0
+ ]
+ ],
+ "index": "a8"
+ },
+ {
+ "id": "yN4z2aruFERH55r0brpmx",
+ "type": "rectangle",
+ "x": 772.6865893307831,
+ "y": 446,
+ "width": 60,
+ "height": 40,
+ "angle": 0,
+ "strokeColor": "#e03131",
+ "backgroundColor": "#f8f9fa",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "a9",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 1265419014,
+ "version": 102,
+ "versionNonce": 1358587974,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "YP3kZRs98Jib89suc6x0T",
+ "type": "text",
+ "x": 779.9115897122529,
+ "y": 456,
+ "width": 45.54999923706055,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#e03131",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aA",
+ "roundness": null,
+ "seed": 673870406,
+ "version": 102,
+ "versionNonce": 544450330,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "text": "ADBC",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "yN4z2aruFERH55r0brpmx",
+ "originalText": "ADBC",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "LBHcAyLWAiRS1VWAnYrWL",
+ "type": "rectangle",
+ "x": 993.1573163962655,
+ "y": 457.10806858517185,
+ "width": 79.72278435602915,
+ "height": 56.34336263774654,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aB",
+ "roundness": null,
+ "seed": 1475361158,
+ "version": 658,
+ "versionNonce": 256995206,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "uhjj5mdyx378bMwZOmacA",
+ "type": "line",
+ "x": 993.5181039582695,
+ "y": 481.73451980525397,
+ "width": 78.67259902626967,
+ "height": 0,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aC",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1912281286,
+ "version": 235,
+ "versionNonce": 1550037978,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 78.67259902626967,
+ 0
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "wxTOD61F5OPXXBIDtpGxt",
+ "type": "line",
+ "x": 1009.2526237635235,
+ "y": 481.73451980525397,
+ "width": 0.12437256409457782,
+ "height": 31.7169114176644,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aD",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 501747718,
+ "version": 232,
+ "versionNonce": 1405456070,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.12437256409457782,
+ 31.7169114176644
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "AcUsH6RUS9OLVvg18AAKQ",
+ "type": "line",
+ "x": 1025.2422604774129,
+ "y": 482.05089551798244,
+ "width": 0.17604688976762406,
+ "height": 31.400535704935898,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aE",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 129244998,
+ "version": 240,
+ "versionNonce": 1614031002,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.17604688976762406,
+ 31.400535704935898
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "lSYkjHCVf2YIeF5v7QZjU",
+ "type": "line",
+ "x": 1041.4312823638481,
+ "y": 482.0360932873964,
+ "width": 0.42710638798645123,
+ "height": 31.415337935521947,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aF",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1404847750,
+ "version": 240,
+ "versionNonce": 183748102,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.42710638798645123,
+ 31.415337935521947
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "osejFYryyYUlSgz6iQVXc",
+ "type": "line",
+ "x": 1056.8729787460302,
+ "y": 481.95251889913084,
+ "width": 0.06915961804813092,
+ "height": 31.498912323787575,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aG",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 314410438,
+ "version": 240,
+ "versionNonce": 597165402,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0.06915961804813092,
+ 31.498912323787575
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "QJe234d_RzbV02CQo2Uzr",
+ "type": "text",
+ "x": 1012.4241827594619,
+ "y": 458.7444843651541,
+ "width": 42.39994812011719,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aH",
+ "roundness": null,
+ "seed": 903142662,
+ "version": 121,
+ "versionNonce": 98112838,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "text": "Table",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "Table",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "X6VRn41RLIDfBeVhxV29d",
+ "type": "rectangle",
+ "x": 1092.7584223962656,
+ "y": 456.8270985851718,
+ "width": 79.72278435602915,
+ "height": 56.34336263774654,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aI",
+ "roundness": null,
+ "seed": 41897030,
+ "version": 706,
+ "versionNonce": 803359258,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "5o6eLAhe7QDtwfTp0CkhY",
+ "type": "line",
+ "x": 1093.1192099582695,
+ "y": 481.45354980525394,
+ "width": 78.67259902626967,
+ "height": 0,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aJ",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 110744454,
+ "version": 283,
+ "versionNonce": 1842510982,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 78.67259902626967,
+ 0
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "gvZuZ0NqSRado6wU51goL",
+ "type": "line",
+ "x": 1108.8537297635235,
+ "y": 481.45354980525394,
+ "width": 0.12437256409457782,
+ "height": 31.7169114176644,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aK",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 207712966,
+ "version": 280,
+ "versionNonce": 1812330202,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.12437256409457782,
+ 31.7169114176644
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "yVzJb6tPtqkBULz3LqRQa",
+ "type": "line",
+ "x": 1124.843366477413,
+ "y": 481.7699255179824,
+ "width": 0.17604688976762406,
+ "height": 31.400535704935898,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aL",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 242428422,
+ "version": 288,
+ "versionNonce": 949812166,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.17604688976762406,
+ 31.400535704935898
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "9rbT0wMUwUK6Ga-xkfsT1",
+ "type": "line",
+ "x": 1141.0323883638482,
+ "y": 481.7551232873964,
+ "width": 0.42710638798645123,
+ "height": 31.415337935521947,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aM",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 734787910,
+ "version": 288,
+ "versionNonce": 1754663834,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.42710638798645123,
+ 31.415337935521947
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "jOEeTGeIkgds_XcW51U0P",
+ "type": "line",
+ "x": 1156.4740847460303,
+ "y": 481.6715488991308,
+ "width": 0.06915961804813092,
+ "height": 31.498912323787575,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aN",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 466149510,
+ "version": 288,
+ "versionNonce": 475370246,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0.06915961804813092,
+ 31.498912323787575
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "xEI-VKH-Qj0Aweqeg26JH",
+ "type": "text",
+ "x": 1112.025288759462,
+ "y": 458.4635143651542,
+ "width": 42.39994812011719,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aO",
+ "roundness": null,
+ "seed": 572972998,
+ "version": 169,
+ "versionNonce": 734365786,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "text": "Table",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "Table",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "type": "line",
+ "version": 1524,
+ "versionNonce": 58278470,
+ "isDeleted": true,
+ "id": "I-akP1h_MfsBs3WnlaqpY",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 498.58828246518095,
+ "y": 446.8875532984406,
+ "strokeColor": "#000000",
+ "backgroundColor": "#ced4da",
+ "width": 70.35754617365805,
+ "height": 35.178773086829025,
+ "seed": 50525958,
+ "groupIds": [
+ "Zm4VUaypghdAlHCLFMc64"
+ ],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 17.589386543414523,
+ 17.58938654341451
+ ],
+ [
+ 3.552713678800501e-15,
+ 35.178773086829025
+ ],
+ [
+ 52.768159630243545,
+ 35.17877308682902
+ ],
+ [
+ 70.35754617365805,
+ 17.589386543414538
+ ],
+ [
+ 52.76815963024356,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "index": "aP",
+ "polygon": false
+ },
+ {
+ "type": "line",
+ "version": 1676,
+ "versionNonce": 2103930138,
+ "isDeleted": true,
+ "id": "hTHCXGLox1-6KFItcVf6X",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 574.0022304422087,
+ "y": 447.09035574946415,
+ "strokeColor": "#1971c2",
+ "backgroundColor": "#ced4da",
+ "width": 70.3575461736581,
+ "height": 35.28193106911539,
+ "seed": 1994008134,
+ "groupIds": [
+ "Zm4VUaypghdAlHCLFMc64"
+ ],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 16.054749690096525,
+ 17.36392457284035
+ ],
+ [
+ -1.5346368533179948,
+ 34.953311116254866
+ ],
+ [
+ 68.8229093203401,
+ 34.95331111625485
+ ],
+ [
+ 68.58605202297224,
+ -0.3286199528605209
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "index": "aQ",
+ "polygon": false
+ },
+ {
+ "type": "line",
+ "version": 1710,
+ "versionNonce": 15010182,
+ "isDeleted": true,
+ "id": "StHUX5ckaob2vDhCP1NVO",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 423.06775260815704,
+ "y": 446.976207295103,
+ "strokeColor": "#000000",
+ "backgroundColor": "#ced4da",
+ "width": 70.35754617365805,
+ "height": 35.178773086829025,
+ "seed": 512322950,
+ "groupIds": [
+ "Zm4VUaypghdAlHCLFMc64"
+ ],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 3.552713678800501e-15,
+ 35.178773086829025
+ ],
+ [
+ 52.768159630243545,
+ 35.17877308682902
+ ],
+ [
+ 70.35754617365805,
+ 17.589386543414538
+ ],
+ [
+ 52.76815963024356,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "index": "aR",
+ "polygon": false
+ },
+ {
+ "id": "Y8Ntms1glDCjSG_0XGCL5",
+ "type": "image",
+ "x": 1008.3122995580559,
+ "y": 337.03124975000003,
+ "width": 148.7485795454546,
+ "height": 35.570312500000014,
+ "angle": 0,
+ "strokeColor": "transparent",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aS",
+ "roundness": null,
+ "seed": 2001587398,
+ "version": 268,
+ "versionNonce": 649625798,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097843325,
+ "link": null,
+ "locked": false,
+ "status": "error",
+ "fileId": "7bce60b8c15c30d4b3b4e7fa5fc02163346bfd973ce9a5d018fa64fdb8d35a4cd875428988936279276f795843fab791",
+ "scale": [
+ 1,
+ 1
+ ],
+ "crop": null
+ },
+ {
+ "id": "ZSdQbLPBJQ-3vi-SDkUnG",
+ "type": "image",
+ "x": 423.75250910769563,
+ "y": 337.03125,
+ "width": 217.8681609999999,
+ "height": 35.57031199999998,
+ "angle": 0,
+ "strokeColor": "transparent",
+ "backgroundColor": "#ffc9c9",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aT",
+ "roundness": null,
+ "seed": 1321485318,
+ "version": 237,
+ "versionNonce": 854505946,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097881189,
+ "link": null,
+ "locked": false,
+ "status": "saved",
+ "fileId": "e82434d4ac1cd6730a4ed376c59edff2e9c0022ad4ee9b38c806c3d7b63a8e86555f9d9c604e3478ba272e9154108d4a",
+ "scale": [
+ 1,
+ 1
+ ],
+ "crop": null
+ },
+ {
+ "type": "rectangle",
+ "version": 485,
+ "versionNonce": 1933751601,
+ "index": "aU",
+ "isDeleted": false,
+ "id": "MdBLs5DrRJv7pPr1ECBdP",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 860,
+ "y": 400.0000004254188,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 460.00000000000006,
+ "height": 259.99999957458124,
+ "seed": 1012386970,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [
+ {
+ "id": "g_xmr_rAUoQx04wSxq2yQ",
+ "type": "arrow"
+ },
+ {
+ "id": "tKM0pRpx3mTuxNwnoBONG",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1780756372702,
+ "link": null,
+ "locked": false
+ },
+ {
+ "type": "line",
+ "version": 1404,
+ "versionNonce": 427313986,
+ "isDeleted": false,
+ "id": "K1eRli9Ss4OCth8Rxisx0",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 580,
+ "y": 501.7969713603986,
+ "strokeColor": "#000000",
+ "backgroundColor": "#e9ecef",
+ "width": 160,
+ "height": 80,
+ "seed": 174911002,
+ "groupIds": [
+ "nS55pT0iEmYN13lrATL_r"
+ ],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1776405922494,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 40,
+ 39.67197250080198
+ ],
+ [
+ -1.4210854715202004e-14,
+ 80
+ ],
+ [
+ 160,
+ 80
+ ],
+ [
+ 160,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "index": "aW",
+ "polygon": false
+ },
+ {
+ "type": "image",
+ "version": 3811,
+ "versionNonce": 1217499906,
+ "index": "aX",
+ "isDeleted": false,
+ "id": "Ob5zHrhyWqtZkihkGCreM",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 646.1123898142422,
+ "y": 515.6199661898443,
+ "strokeColor": "transparent",
+ "backgroundColor": "#ffc9c9",
+ "width": 61.54214099463984,
+ "height": 50.681763172056336,
+ "seed": 1704729306,
+ "groupIds": [
+ "fCtmhUGKWexr3OXqoPqQN",
+ "nS55pT0iEmYN13lrATL_r"
+ ],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1776405922494,
+ "link": null,
+ "locked": false,
+ "status": "saved",
+ "fileId": "d1ee05fd41e4fad60a7372901fb1a4d206070a057f9b3a48768235e2c5775230a90d16ba6804ee1fbd79befd1ec8cbbf",
+ "scale": [
+ 1,
+ 1
+ ],
+ "crop": null
+ },
+ {
+ "id": "wiIzNpyZMDMVPVOdx3eVn",
+ "type": "rectangle",
+ "x": 1024.4167779398936,
+ "y": 485.22529758183066,
+ "width": 120,
+ "height": 80,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#f8f9fa",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "ED3zbSqQFl4xgPIcdlXCR"
+ ],
+ "frameId": null,
+ "index": "aY",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 331853722,
+ "version": 266,
+ "versionNonce": 64235034,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098217025,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "TXbEZ48uEoiWDzIqPH1M_",
+ "type": "text",
+ "x": 1061.9834454966563,
+ "y": 490.22529758183066,
+ "width": 44.86666488647461,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#f8f9fa",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "ED3zbSqQFl4xgPIcdlXCR"
+ ],
+ "frameId": null,
+ "index": "aZ",
+ "roundness": null,
+ "seed": 1227009114,
+ "version": 271,
+ "versionNonce": 1870422150,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098217025,
+ "link": null,
+ "locked": false,
+ "text": "Index",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": "wiIzNpyZMDMVPVOdx3eVn",
+ "originalText": "Index",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "C4Vg7NQrQ7CRH2oimHPhh",
+ "type": "text",
+ "x": 1063.897760976568,
+ "y": 517.8553174757881,
+ "width": 44,
+ "height": 25,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#f8f9fa",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "ED3zbSqQFl4xgPIcdlXCR"
+ ],
+ "frameId": null,
+ "index": "aa",
+ "roundness": null,
+ "seed": 998248730,
+ "version": 385,
+ "versionNonce": 492589786,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098217025,
+ "link": null,
+ "locked": false,
+ "text": "main",
+ "fontSize": 20,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "main",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "U43N5fGAQhuW1feXA8vj9",
+ "type": "image",
+ "x": 935.1033669398937,
+ "y": 395.5924855818307,
+ "width": 320,
+ "height": 61.935483870967744,
+ "angle": 0,
+ "strokeColor": "transparent",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "ab",
+ "roundness": null,
+ "seed": 1850924506,
+ "version": 172,
+ "versionNonce": 732740038,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097953019,
+ "link": null,
+ "locked": false,
+ "status": "saved",
+ "fileId": "427536ece8193bbdf039f2e7d8e9c52ddca850d9c1f5ab9cb392be289df6a930d6b9508e72a47654204b34fa73df0b84",
+ "scale": [
+ 1,
+ 1
+ ],
+ "crop": null
+ },
+ {
+ "id": "f0yXEXn5F8SJ5p_TyNUwb",
+ "type": "arrow",
+ "x": 1025.2986369398936,
+ "y": 525.2252975818308,
+ "width": 40,
+ "height": 0,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "ac",
+ "roundness": null,
+ "seed": 2125337242,
+ "version": 285,
+ "versionNonce": 862609350,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098217025,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -40,
+ 0
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "elbowed": false
+ },
+ {
+ "id": "7SvpfQ9JKp7TWxk_iPRuj",
+ "type": "ellipse",
+ "x": 963.4167779398937,
+ "y": 515.2252975818307,
+ "width": 20,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "ad",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1866772314,
+ "version": 219,
+ "versionNonce": 1455482778,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098217025,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "tYpVzQAJgHPTVmA_sLOkS",
+ "type": "text",
+ "x": 880.2823889115372,
+ "y": 551.1903207025754,
+ "width": 108.73332977294922,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "ae",
+ "roundness": null,
+ "seed": 1953084442,
+ "version": 246,
+ "versionNonce": 809152834,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1776407002754,
+ "link": null,
+ "locked": false,
+ "text": "clickhouse-cpp",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "clickhouse-cpp",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "KN1ayyvhKKjnePaEKeaIF",
+ "type": "image",
+ "x": 820.9327548851652,
+ "y": 144.86044771263136,
+ "width": 648,
+ "height": 198,
+ "angle": 0,
+ "strokeColor": "transparent",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "solid",
+ "roughness": 0,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "af",
+ "roundness": null,
+ "seed": 1748074566,
+ "version": 7,
+ "versionNonce": 611016410,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097970404,
+ "link": null,
+ "locked": false,
+ "status": "saved",
+ "fileId": "cf677ae2acf110ab1ada213681646441e0c13120f42e07e34dd682f16c145e211079120b235b660943d40ff50c8c0009",
+ "scale": [
+ 1,
+ 1
+ ],
+ "crop": null
+ },
+ {
+ "id": "xYtTaORtPfTaBfyVaE9Jh",
+ "type": "image",
+ "x": 735.7119039438548,
+ "y": 105.09331477743947,
+ "width": 648,
+ "height": 198,
+ "angle": 0,
+ "strokeColor": "transparent",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "solid",
+ "roughness": 0,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "ag",
+ "roundness": null,
+ "seed": 538466886,
+ "version": 7,
+ "versionNonce": 301543046,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741097998524,
+ "link": null,
+ "locked": false,
+ "status": "saved",
+ "fileId": "cf677ae2acf110ab1ada213681646441e0c13120f42e07e34dd682f16c145e211079120b235b660943d40ff50c8c0009",
+ "scale": [
+ 1,
+ 1
+ ],
+ "crop": null
+ },
+ {
+ "id": "NsxTI00fJ7Tk4JFzEOGL_",
+ "type": "image",
+ "x": 988.6590468390034,
+ "y": 400,
+ "width": 221.3677416168746,
+ "height": 67.5359211712499,
+ "angle": 0,
+ "strokeColor": "transparent",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "solid",
+ "roughness": 0,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "ah",
+ "roundness": null,
+ "seed": 135755354,
+ "version": 510,
+ "versionNonce": 1302936962,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1776405904244,
+ "link": null,
+ "locked": false,
+ "status": "saved",
+ "fileId": "74235aaa80d5377e7af618a88eaf3165fae35889019cba2a4a62571f5ce6a7f9ad2989f927cd6093f58b899f2e11d669",
+ "scale": [
+ 1,
+ 1
+ ],
+ "crop": null
+ },
+ {
+ "id": "vOB755ry3Yy5dgsquEXEw",
+ "type": "rectangle",
+ "x": 1008.2342083148578,
+ "y": 717.6959755193367,
+ "width": 220,
+ "height": 100,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "ak",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 842349190,
+ "version": 157,
+ "versionNonce": 1028906566,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098226665,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "CC4blV5bRJpXB76sprPmw",
+ "type": "text",
+ "x": 1086.1425411395649,
+ "y": 722.6959755193367,
+ "width": 64.18333435058594,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "al",
+ "roundness": null,
+ "seed": 502790598,
+ "version": 143,
+ "versionNonce": 1494520090,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098226665,
+ "link": null,
+ "locked": false,
+ "text": "Schemas",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "top",
+ "containerId": "vOB755ry3Yy5dgsquEXEw",
+ "originalText": "Schemas",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "NHNLon77B1UpJWm0TtITQ",
+ "type": "text",
+ "x": 1062.9663276537221,
+ "y": 759.4757254233818,
+ "width": 11.199999809265137,
+ "height": 35,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 4,
+ "strokeStyle": "solid",
+ "roughness": 0,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "amV",
+ "roundness": null,
+ "seed": 1291795610,
+ "version": 3,
+ "versionNonce": 1291828998,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098244079,
+ "link": null,
+ "locked": false,
+ "text": "",
+ "fontSize": 28,
+ "fontFamily": 5,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "grimbjvvQaXcX0fZ1QGkH",
+ "originalText": "",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "grimbjvvQaXcX0fZ1QGkH",
+ "type": "rectangle",
+ "x": 1059.430991911885,
+ "y": 522.742581081342,
+ "width": 79.72278435602915,
+ "height": 56.34336263774654,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "3KLhhHW84bohbevIB1Hzc"
+ ],
+ "frameId": null,
+ "index": "amd",
+ "roundness": null,
+ "seed": 1503711494,
+ "version": 766,
+ "versionNonce": 977033055,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "id": "g_xmr_rAUoQx04wSxq2yQ",
+ "type": "arrow"
+ },
+ {
+ "id": "tKM0pRpx3mTuxNwnoBONG",
+ "type": "arrow"
+ }
+ ],
+ "updated": 1780756361338,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "jDCSnbgRZUSNDrfjEd8Fc",
+ "type": "line",
+ "x": 1059.7917794738892,
+ "y": 547.369032301424,
+ "width": 78.67259902626967,
+ "height": 0,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "3KLhhHW84bohbevIB1Hzc"
+ ],
+ "frameId": null,
+ "index": "aml",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 816627782,
+ "version": 335,
+ "versionNonce": 108348674,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1776405904244,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 78.67259902626967,
+ 0
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "x1F877POVQOiJKca5RDRq",
+ "type": "line",
+ "x": 1075.5262992791431,
+ "y": 547.369032301424,
+ "width": 0.12437256409457782,
+ "height": 31.7169114176644,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "3KLhhHW84bohbevIB1Hzc"
+ ],
+ "frameId": null,
+ "index": "amt",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1996015494,
+ "version": 332,
+ "versionNonce": 122246338,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1776405904244,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.12437256409457782,
+ 31.7169114176644
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "okS3KPOvVBZwY3ofsj0Uc",
+ "type": "line",
+ "x": 1091.5159359930326,
+ "y": 547.6854080141526,
+ "width": 0.17604688976762406,
+ "height": 31.400535704935898,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "3KLhhHW84bohbevIB1Hzc"
+ ],
+ "frameId": null,
+ "index": "an",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 2093082310,
+ "version": 343,
+ "versionNonce": 981822594,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1776405904244,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.17604688976762406,
+ 31.400535704935898
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "ZJrOj4tP-Rs6DlBgjxBwu",
+ "type": "line",
+ "x": 1107.7049578794677,
+ "y": 547.6706057835664,
+ "width": 0.42710638798645123,
+ "height": 31.415337935521947,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "3KLhhHW84bohbevIB1Hzc"
+ ],
+ "frameId": null,
+ "index": "anV",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 44375558,
+ "version": 339,
+ "versionNonce": 635997250,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1776405904244,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.42710638798645123,
+ 31.415337935521947
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "vYTHyZXj8YpcxC4gKL6cW",
+ "type": "line",
+ "x": 1123.1466542616495,
+ "y": 547.5870313953009,
+ "width": 0.06915961804813092,
+ "height": 31.498912323787575,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "3KLhhHW84bohbevIB1Hzc"
+ ],
+ "frameId": null,
+ "index": "ao",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 765422918,
+ "version": 339,
+ "versionNonce": 1062319106,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1776405904244,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0.06915961804813092,
+ 31.498912323787575
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "AL2_d8YDszRMsO8BuMuM5",
+ "type": "text",
+ "x": 1078.6978582750817,
+ "y": 524.3789968613241,
+ "width": 42.39994812011719,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [
+ "3KLhhHW84bohbevIB1Hzc"
+ ],
+ "frameId": null,
+ "index": "ap",
+ "roundness": null,
+ "seed": 2064503942,
+ "version": 224,
+ "versionNonce": 1757406146,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1776405904244,
+ "link": null,
+ "locked": false,
+ "text": "Table",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "Table",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "type": "arrow",
+ "version": 1878,
+ "versionNonce": 1915132799,
+ "isDeleted": false,
+ "id": "g_xmr_rAUoQx04wSxq2yQ",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 749.604032,
+ "y": 541.340769268944,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffec99",
+ "width": 251.4939372499514,
+ "height": 0.2267816091880377,
+ "seed": 61286746,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1780756370090,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": {
+ "elementId": "MdBLs5DrRJv7pPr1ECBdP",
+ "mode": "inside",
+ "fixedPoint": [
+ 0.3067347157607638,
+ 0.5444905795551912
+ ]
+ },
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 251.4939372499514,
+ 0.2267816091880377
+ ]
+ ],
+ "index": "aq"
+ },
+ {
+ "id": "EjkVOqbp5FvWVeBdAETVV",
+ "type": "rectangle",
+ "x": 1128.3060413803403,
+ "y": 748.5230741045085,
+ "width": 79.72278435602915,
+ "height": 56.34336263774654,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "at",
+ "roundness": null,
+ "seed": 883774406,
+ "version": 701,
+ "versionNonce": 1153008838,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098228386,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "E-WgXxnOCbXfeYW0mfWG3",
+ "type": "line",
+ "x": 1128.6668289423444,
+ "y": 773.1495253245906,
+ "width": 78.67259902626967,
+ "height": 0,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "au",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1687874310,
+ "version": 278,
+ "versionNonce": 140182534,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098236529,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 78.67259902626967,
+ 0
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "xjWYRtXFibG7uLFMuFR8a",
+ "type": "line",
+ "x": 1144.4013487475984,
+ "y": 773.1495253245906,
+ "width": 0.12437256409457782,
+ "height": 31.7169114176644,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "av",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1230215750,
+ "version": 275,
+ "versionNonce": 30123866,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098236529,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.12437256409457782,
+ 31.7169114176644
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "4iUma5gpDHV3Ss8YN1ZnC",
+ "type": "line",
+ "x": 1160.3909854614876,
+ "y": 773.4659010373191,
+ "width": 0.17604688976762406,
+ "height": 31.400535704935898,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "aw",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1236558214,
+ "version": 283,
+ "versionNonce": 262705990,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098236529,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.17604688976762406,
+ 31.400535704935898
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "YTALf8QivrY8Y3ukdnM48",
+ "type": "line",
+ "x": 1176.580007347923,
+ "y": 773.4510988067331,
+ "width": 0.42710638798645123,
+ "height": 31.415337935521947,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "ax",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 1761231046,
+ "version": 283,
+ "versionNonce": 189901850,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098236529,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.42710638798645123,
+ 31.415337935521947
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "uw8IKhs5_yw6le7eBDmog",
+ "type": "line",
+ "x": 1192.021703730105,
+ "y": 773.3675244184675,
+ "width": 0.06915961804813092,
+ "height": 31.498912323787575,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "ay",
+ "roundness": {
+ "type": 2
+ },
+ "seed": 985806854,
+ "version": 283,
+ "versionNonce": 1291991686,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098236529,
+ "link": null,
+ "locked": false,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0.06915961804813092,
+ 31.498912323787575
+ ]
+ ],
+ "lastCommittedPoint": null,
+ "startBinding": null,
+ "endBinding": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "polygon": false
+ },
+ {
+ "id": "WfZ3V-cKbT8O4P8aYo7dF",
+ "type": "text",
+ "x": 1147.5729077435367,
+ "y": 750.1594898844909,
+ "width": 42.39994812011719,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "az",
+ "roundness": null,
+ "seed": 1460225862,
+ "version": 164,
+ "versionNonce": 1328099162,
+ "isDeleted": true,
+ "boundElements": [],
+ "updated": 1741098229156,
+ "link": null,
+ "locked": false,
+ "text": "Table",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "Table",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "type": "arrow",
+ "version": 565,
+ "versionNonce": 320025794,
+ "isDeleted": true,
+ "id": "pBotRGLBg9X5mnuVmfKnB",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1240,
+ "y": 299.590408778781,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "width": 205.2903283354567,
+ "height": 0,
+ "seed": 487225986,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1776405941366,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 205.2903283354567,
+ 0
+ ]
+ ],
+ "index": "b00",
+ "moveMidPointsWithElement": false
+ },
+ {
+ "type": "line",
+ "version": 1216,
+ "versionNonce": 1354649154,
+ "isDeleted": false,
+ "id": "F0orhRaHAqTuALLSnO9Xy",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1461.4896611218805,
+ "y": 501.1228355476312,
+ "strokeColor": "#000000",
+ "backgroundColor": "#e9ecef",
+ "width": 160,
+ "height": 80,
+ "seed": 1352391234,
+ "groupIds": [
+ "ue6SNJ8D0rwUulbQkKEMs"
+ ],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1776405935461,
+ "link": null,
+ "locked": false,
+ "startBinding": null,
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": null,
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -1.4896611218806584,
+ 80
+ ],
+ [
+ 118.51033887811936,
+ 79.99999999999999
+ ],
+ [
+ 158.51033887811934,
+ 40.000000000000014
+ ],
+ [
+ 118.51033887811934,
+ -7.105427357601002e-15
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "index": "b01",
+ "polygon": false
+ },
+ {
+ "type": "image",
+ "version": 3823,
+ "versionNonce": 1310668290,
+ "index": "b02",
+ "isDeleted": false,
+ "id": "u7uGFZKvYTJg3ZaveldwI",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1500.215355777485,
+ "y": 514.0164108401761,
+ "strokeColor": "transparent",
+ "backgroundColor": "#ffc9c9",
+ "width": 61.54214099463984,
+ "height": 50.681763172056336,
+ "seed": 309019138,
+ "groupIds": [
+ "DdDt_26QqNoMYFN5KrQht",
+ "ue6SNJ8D0rwUulbQkKEMs"
+ ],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1776405935461,
+ "link": null,
+ "locked": false,
+ "status": "saved",
+ "fileId": "d1ee05fd41e4fad60a7372901fb1a4d206070a057f9b3a48768235e2c5775230a90d16ba6804ee1fbd79befd1ec8cbbf",
+ "scale": [
+ 1,
+ 1
+ ],
+ "crop": null
+ },
+ {
+ "type": "arrow",
+ "version": 1564,
+ "versionNonce": 368428881,
+ "isDeleted": false,
+ "id": "tKM0pRpx3mTuxNwnoBONG",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "angle": 0,
+ "x": 1196.2651043929143,
+ "y": 541.9214336241902,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffec99",
+ "width": 243.73489560708572,
+ "height": 1.921433624190172,
+ "seed": 1924097822,
+ "groupIds": [],
+ "frameId": null,
+ "roundness": null,
+ "boundElements": [],
+ "updated": 1780756372702,
+ "link": null,
+ "locked": false,
+ "startBinding": {
+ "elementId": "MdBLs5DrRJv7pPr1ECBdP",
+ "mode": "inside",
+ "fixedPoint": [
+ 0.7310110965063353,
+ 0.5458516670422573
+ ]
+ },
+ "endBinding": null,
+ "lastCommittedPoint": null,
+ "startArrowhead": null,
+ "endArrowhead": "triangle",
+ "points": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 243.73489560708572,
+ -1.921433624190172
+ ]
+ ],
+ "index": "b03"
+ },
+ {
+ "id": "pxMAkKbSTRDYrKzd8E1cn",
+ "type": "text",
+ "x": 1200,
+ "y": 551.190321,
+ "width": 108.73332977294922,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#ffec99",
+ "fillStyle": "hachure",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b04",
+ "roundness": null,
+ "seed": 1604514014,
+ "version": 385,
+ "versionNonce": 436460290,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1776407000712,
+ "link": null,
+ "locked": false,
+ "text": "clickhouse-cpp",
+ "fontSize": 16,
+ "fontFamily": 5,
+ "textAlign": "left",
+ "verticalAlign": "top",
+ "containerId": null,
+ "originalText": "clickhouse-cpp",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "nEzwZ6XOe8KzswL0LroMB",
+ "type": "rectangle",
+ "x": 598.623046875,
+ "y": 575.7666015625,
+ "width": 138.3056640625,
+ "height": 34.1357421875,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b05",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 232567121,
+ "version": 342,
+ "versionNonce": 1024274513,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "zxelMnghO-HzobXyEJoVD"
+ }
+ ],
+ "updated": 1780756320381,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "zxelMnghO-HzobXyEJoVD",
+ "type": "text",
+ "x": 606.1758689880371,
+ "y": 582.83447265625,
+ "width": 123.20001983642578,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b06",
+ "roundness": null,
+ "seed": 1929338161,
+ "version": 336,
+ "versionNonce": 1238989119,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1780756320381,
+ "link": null,
+ "locked": false,
+ "text": "clickhouse-cpp",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "nEzwZ6XOe8KzswL0LroMB",
+ "originalText": "clickhouse-cpp",
+ "autoResize": true,
+ "lineHeight": 1.25
+ },
+ {
+ "id": "WgVhNBQVbSlVH8y_xFykq",
+ "type": "rectangle",
+ "x": 1452.22412109375,
+ "y": 576.77978515625,
+ "width": 138.3056640625,
+ "height": 34.1357421875,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "#e9ecef",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b07",
+ "roundness": {
+ "type": 3
+ },
+ "seed": 902815153,
+ "version": 399,
+ "versionNonce": 1585590737,
+ "isDeleted": false,
+ "boundElements": [
+ {
+ "type": "text",
+ "id": "WnHbmuBUHdYAa6Jmcn2I4"
+ }
+ ],
+ "updated": 1780756327060,
+ "link": null,
+ "locked": false
+ },
+ {
+ "id": "WnHbmuBUHdYAa6Jmcn2I4",
+ "type": "text",
+ "x": 1459.776943206787,
+ "y": 583.84765625,
+ "width": 123.20001983642578,
+ "height": 20,
+ "angle": 0,
+ "strokeColor": "#1e1e1e",
+ "backgroundColor": "transparent",
+ "fillStyle": "solid",
+ "strokeWidth": 1,
+ "strokeStyle": "solid",
+ "roughness": 1,
+ "opacity": 100,
+ "groupIds": [],
+ "frameId": null,
+ "index": "b08",
+ "roundness": null,
+ "seed": 273350545,
+ "version": 393,
+ "versionNonce": 1943916465,
+ "isDeleted": false,
+ "boundElements": [],
+ "updated": 1780756327060,
+ "link": null,
+ "locked": false,
+ "text": "clickhouse-cpp",
+ "fontSize": 16,
+ "fontFamily": 8,
+ "textAlign": "center",
+ "verticalAlign": "middle",
+ "containerId": "WgVhNBQVbSlVH8y_xFykq",
+ "originalText": "clickhouse-cpp",
+ "autoResize": true,
+ "lineHeight": 1.25
+ }
+ ],
+ "appState": {
+ "gridSize": 20,
+ "gridStep": 5,
+ "gridModeEnabled": false,
+ "viewBackgroundColor": "#ffffff",
+ "lockedMultiSelections": {}
+ },
+ "files": {
+ "d1ee05fd41e4fad60a7372901fb1a4d206070a057f9b3a48768235e2c5775230a90d16ba6804ee1fbd79befd1ec8cbbf": {
+ "mimeType": "image/svg+xml",
+ "id": "d1ee05fd41e4fad60a7372901fb1a4d206070a057f9b3a48768235e2c5775230a90d16ba6804ee1fbd79befd1ec8cbbf",
+ "dataURL": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI4NSIgaGVpZ2h0PSI3MCIgdmlld0JveD0iMCAwIDg1IDcwIiBmaWxsPSJub25lIj4KPHBhdGggZD0iTTI5LjQ1IDQ0LjQyTDQyLjc3IDEyLjkzQzQyLjgyNjkgMTIuODA1OCA0Mi44NTc4IDEyLjY3MTMgNDIuODYwNyAxMi41MzQ4QzQyLjg2MzYgMTIuMzk4MiA0Mi44Mzg2IDEyLjI2MjUgNDIuNzg3IDEyLjEzNkM0Mi43MzU1IDEyLjAwOTUgNDIuNjU4NiAxMS44OTQ5IDQyLjU2MTEgMTEuNzk5M0M0Mi40NjM1IDExLjcwMzcgNDIuMzQ3NSAxMS42MjkgNDIuMjIgMTEuNThDNDIuMDkyOCAxMS41Mjg2IDQxLjk1NzEgMTEuNTAxNSA0MS44MiAxMS41SDkuMjc5OTlDOS4wNzYzMiAxMS40OTU4IDguODc2MjEgMTEuNTUzOCA4LjcwNjQzIDExLjY2NjRDOC41MzY2NiAxMS43NzkgOC40MDUzMiAxMS45NDA3IDguMzI5OTkgMTIuMTNMMy4xMDk5OSAyNC42M0MzLjA1IDI0Ljc1NTggMy4wMTY5NSAyNC44OTI3IDMuMDEyOTggMjUuMDMyQzMuMDA5MDEgMjUuMTcxMyAzLjAzNDE5IDI1LjMwOTkgMy4wODY5MiAyNS40Mzg5QzMuMTM5NjUgMjUuNTY3OSAzLjIxODc1IDI1LjY4NDQgMy4zMTkxNiAyNS43ODExQzMuNDE5NTcgMjUuODc3NyAzLjUzOTA3IDI1Ljk1MjMgMy42Njk5OSAyNkMzLjc5MzMxIDI2LjA1MjUgMy45MjU5NCAyNi4wNzk3IDQuMDU5OTkgMjYuMDhIMTkuODJDMjAuMDg1MiAyNi4wOCAyMC4zMzk2IDI2LjE4NTQgMjAuNTI3MSAyNi4zNzI5QzIwLjcxNDYgMjYuNTYwNCAyMC44MiAyNi44MTQ4IDIwLjgyIDI3LjA4QzIwLjgxODUgMjcuMjE3MiAyMC43OTE0IDI3LjM1MjggMjAuNzQgMjcuNDhMNy41OTk5OSA1OS4wN0M3LjU0MzMyIDU5LjE5NDggNy41MTI5MiA1OS4zMjk5IDcuNTEwNjUgNTkuNDY2OUM3LjUwODM5IDU5LjYwNCA3LjUzNDMyIDU5Ljc0IDcuNTg2ODMgNTkuODY2NkM3LjYzOTM1IDU5Ljk5MzIgNy43MTczMiA2MC4xMDc3IDcuODE1OTIgNjAuMjAyOUM3LjkxNDUyIDYwLjI5OCA4LjAzMTYzIDYwLjM3MiA4LjE1OTk5IDYwLjQyQzguMjgzMzEgNjAuNDcyNSA4LjQxNTk0IDYwLjQ5OTcgOC41NDk5OSA2MC41SDQzQzQzLjIxMzIgNjAuNTE0MSA0My40MjUzIDYwLjQ1OTYgNDMuNjA1MiA2MC4zNDQ1QzQzLjc4NTIgNjAuMjI5MyA0My45MjM1IDYwLjA1OTUgNDQgNTkuODZMNDkuMjIgNDcuMjhDNDkuMjc2NyA0Ny4xNTUyIDQ5LjMwNzEgNDcuMDIwMSA0OS4zMDkzIDQ2Ljg4MzFDNDkuMzExNiA0Ni43NDYgNDkuMjg1NyA0Ni42MSA0OS4yMzMxIDQ2LjQ4MzRDNDkuMTgwNiA0Ni4zNTY4IDQ5LjEwMjcgNDYuMjQyNCA0OS4wMDQxIDQ2LjE0NzJDNDguOTA1NSA0Ni4wNTIgNDguNzg4MyA0NS45NzggNDguNjYgNDUuOTNDNDguNTM2NyA0NS44Nzc1IDQ4LjQwNCA0NS44NTAzIDQ4LjI3IDQ1Ljg1SDMwLjRDMzAuMTM0OCA0NS44NSAyOS44ODA0IDQ1Ljc0NDYgMjkuNjkyOSA0NS41NTcxQzI5LjUwNTMgNDUuMzY5NiAyOS40IDQ1LjExNTIgMjkuNCA0NC44NUMyOS4zODggNDQuNzA0OCAyOS40MDUgNDQuNTU4NiAyOS40NSA0NC40MloiIGZpbGw9IiMxMjEyMTIiLz4KPHBhdGggZD0iTTM3LjE3IDQxLjU4SDUwLjg4QzUxLjA4MzcgNDEuNTg0MyA1MS4yODM4IDQxLjUyNjIgNTEuNDUzNSA0MS40MTM2QzUxLjYyMzMgNDEuMzAxIDUxLjc1NDcgNDEuMTM5MyA1MS44MyA0MC45NUw1Ny44MyAyNi42OUM1Ny45MDUzIDI2LjUwMDcgNTguMDM2NyAyNi4zMzkgNTguMjA2NCAyNi4yMjY0QzU4LjM3NjIgMjYuMTEzOCA1OC41NzYzIDI2LjA1NTcgNTguNzggMjYuMDZINzYuNDFDNzYuNjIyIDI2LjA3NDkgNzYuODMzMiAyNi4wMjE4IDc3LjAxMyAyNS45MDg1Qzc3LjE5MjggMjUuNzk1MyA3Ny4zMzE5IDI1LjYyNzYgNzcuNDEgMjUuNDNMODIuNjMgMTIuOTNDODIuNjg1MiAxMi44MDA3IDgyLjcxMjYgMTIuNjYxMyA4Mi43MTAzIDEyLjUyMDdDODIuNzA3OSAxMi4zODAxIDgyLjY3NiAxMi4yNDE2IDgyLjYxNjYgMTIuMTE0M0M4Mi41NTcxIDExLjk4NjkgODIuNDcxNSAxMS44NzM0IDgyLjM2NTIgMTEuNzgxNEM4Mi4yNTkgMTEuNjg5MyA4Mi4xMzQ1IDExLjYyMDcgODIgMTEuNThDODEuODc2NyAxMS41Mjc1IDgxLjc0NCAxMS41MDAzIDgxLjYxIDExLjVINDguODJDNDguNjA4IDExLjQ4NTEgNDguMzk2OCAxMS41MzgyIDQ4LjIxNyAxMS42NTE1QzQ4LjAzNzEgMTEuNzY0NyA0Ny44OTgxIDExLjkzMjQgNDcuODIgMTIuMTNMMzYuMTcgNDAuMTNDMzYuMTEzMSA0MC4yNTQyIDM2LjA4MjIgNDAuMzg4NyAzNi4wNzkzIDQwLjUyNTJDMzYuMDc2MyA0MC42NjE4IDM2LjEwMTQgNDAuNzk3NSAzNi4xNTI5IDQwLjkyNEMzNi4yMDQ1IDQxLjA1MDUgMzYuMjgxNCA0MS4xNjUxIDM2LjM3ODkgNDEuMjYwN0MzNi40NzY0IDQxLjM1NjMgMzYuNTkyNSA0MS40MzEgMzYuNzIgNDEuNDhDMzYuODYxMiA0MS41NDQ3IDM3LjAxNDYgNDEuNTc4OCAzNy4xNyA0MS41OFoiIGZpbGw9IiMxMjEyMTIiLz4KPC9zdmc+",
+ "created": 1684733732697
+ },
+ "74235aaa80d5377e7af618a88eaf3165fae35889019cba2a4a62571f5ce6a7f9ad2989f927cd6093f58b899f2e11d669": {
+ "mimeType": "image/svg+xml",
+ "id": "74235aaa80d5377e7af618a88eaf3165fae35889019cba2a4a62571f5ce6a7f9ad2989f927cd6093f58b899f2e11d669",
+ "dataURL": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJMYXllcl8xIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA2NDkuMyAxOTguMyIgd2lkdGg9IjY0OS4zIiBoZWlnaHQ9IjE5OC4zIj4KICA8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMjkuMS4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogMi4xLjAgQnVpbGQgMTQyKSAgLS0+CiAgPGRlZnM+CiAgICA8c3R5bGU+CiAgICAgIC5zdDAgewogICAgICAgIGZpbGw6ICMxZTFlMWU7CiAgICAgIH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIDxnPgogICAgPHBhdGggY2xhc3M9InN0MCIgZD0iTTMyLjIsNDguOGMwLS43LjUtMS4yLDEuMi0xLjJoOWMuNywwLDEuMi41LDEuMiwxLjJ2MTAwLjdjMCwuNy0uNSwxLjItMS4yLDEuMmgtOWMtLjcsMC0xLjItLjUtMS4yLTEuMlY0OC44WiIvPgogICAgPHBhdGggY2xhc3M9InN0MCIgZD0iTTU1LjEsNDguOGMwLS43LjUtMS4yLDEuMi0xLjJoOWMuNywwLDEuMi41LDEuMiwxLjJ2MTAwLjdjMCwuNy0uNSwxLjItMS4yLDEuMmgtOWMtLjcsMC0xLjItLjUtMS4yLTEuMiwwLDAsMC0xMDAuNywwLTEwMC43WiIvPgogICAgPHBhdGggY2xhc3M9InN0MCIgZD0iTTc4LDQ4LjhjMC0uNy41LTEuMiwxLjItMS4yaDljLjcsMCwxLjIuNSwxLjIsMS4ydjEwMC43YzAsLjctLjUsMS4yLTEuMiwxLjJoLTljLS43LDAtMS4yLS41LTEuMi0xLjJWNDguOFoiLz4KICAgIDxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xMDAuOSw0OC44YzAtLjcuNS0xLjIsMS4yLTEuMmg5Yy43LDAsMS4yLjUsMS4yLDEuMnYxMDAuN2MwLC43LS41LDEuMi0xLjIsMS4yaC05Yy0uNywwLTEuMi0uNS0xLjItMS4yVjQ4LjhaIi8+CiAgICA8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTIzLjgsODguOWMwLS43LjUtMS4yLDEuMi0xLjJoOWMuNywwLDEuMi41LDEuMiwxLjJ2MjAuNWMwLC43LS41LDEuMi0xLjIsMS4yaC05Yy0uNywwLTEuMi0uNS0xLjItMS4ydi0yMC41WiIvPgogIDwvZz4KICA8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTk1LjIsNzUuN2MtMy4yLDAtNi4xLjYtOC43LDEuNy0yLjYsMS4xLTQuOCwyLjctNi42LDQuOS0xLjgsMi4yLTMuMSw0LjktNC4xLDgtLjksMy4xLTEuNCw2LjYtMS40LDEwLjVzLjgsOS42LDIuMywxMy40YzEuNSwzLjcsMy44LDYuNiw2LjksOC42LDMuMSwyLDYuOSwzLDExLjUsM3M1LjUtLjIsOC4xLS43LDUuMy0xLjMsOC0yLjF2OC41Yy0yLjYsMS01LjIsMS43LTcuOSwyLjEtMi43LjUtNS44LjctOS4zLjctNi43LDAtMTIuMi0xLjQtMTYuNy00LjEtNC40LTIuNy03LjctNi43LTkuOS0xMS43LTIuMi01LjEtMy4zLTExLTMuMy0xNy44cy43LTkuNSwyLTEzLjZjMS40LTQuMiwzLjQtNy43LDYtMTAuN3M1LjktNS4zLDkuNy02LjljMy45LTEuNiw4LjQtMi41LDEzLjUtMi41czYuNS40LDkuNywxLjEsNiwxLjYsOC42LDIuOWwtMy43LDguMmMtMi4xLTEtNC41LTEuOC03LTIuNi0yLjMtLjUtNC45LS45LTcuNy0uOVoiLz4KICA8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjMzLjksMTMzLjVoLTkuN1Y2My45aDkuN3Y2OS42WiIvPgogIDxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0yNTUuMiw4NC4xdjQ5LjRoLTkuN3YtNDkuNGg5LjdaTTI1MC41LDY1LjRjMS41LDAsMi43LjQsMy44LDEuM3MxLjYsMi4zLDEuNiw0LjMtLjUsMy40LTEuNiw0LjMtMi40LDEuMy0zLjgsMS4zLTIuOS0uNC00LTEuM2MtMS0uOS0xLjYtMi40LTEuNi00LjNzLjUtMy41LDEuNi00LjNjMS0uOSwyLjQtMS4zLDQtMS4zWiIvPgogIDxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0yODguNSwxMzQuNGMtNC41LDAtOC41LS45LTExLjktMi43cy02LjEtNC41LTgtOC4yYy0xLjktMy44LTIuOC04LjYtMi44LTE0LjRzMS0xMS4xLDMtMTQuOGMyLjEtMy44LDQuOS02LjYsOC4zLTguMywzLjUtMS44LDcuNi0yLjcsMTIuMS0yLjdzNS4zLjMsNy43LjljMi40LjUsNC41LDEuMiw2LDEuOWwtMi45LDcuOWMtMS43LS43LTMuNS0xLjMtNS41LTEuNy0xLjktLjUtMy43LS43LTUuNC0uNy0zLjEsMC01LjYuNy03LjYsMnMtMy40LDMuMi00LjQsNS45Yy0uOSwyLjYtMS40LDUuOC0xLjQsOS43cy41LDYuOSwxLjUsOS40YzEsMi42LDIuNCw0LjUsNC4zLDUuOSwyLDEuMyw0LjQsMS45LDcuMiwxLjlzNS4yLS4zLDcuMi0uOWMyLjEtLjYsNC0xLjQsNS45LTIuNHY4LjRjLTEuOCwxLTMuNywxLjgtNS44LDIuMy0xLjkuNC00LjUuNi03LjUuNloiLz4KICA8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMzIxLjIsMTA1LjdjLjctLjcsMjEuMS0yMS42LDIxLjEtMjEuNmgxMS4zbC0xOS45LDIxLjIsMjEuMiwyOC4yaC0xMS41bC0xNi4zLTIyLjEtNS43LDQuOHYxNy4zaC05LjZWNjMuOWg5LjZsLS4yLDQxLjhaIi8+CiAgPHBhdGggY2xhc3M9InN0MCIgZD0iTTQxNS4xLDEzMy41aC05Ljl2LTI5LjloLTMxLjJ2MjkuOWgtOS45di02NS40aDkuOXYyNy4xaDMxLjJ2LTI3LjFoOS45djY1LjRaIi8+CiAgPHBhdGggY2xhc3M9InN0MCIgZD0iTTQ3MC40LDEwOC44YzAsNC4xLS42LDcuNy0xLjYsMTAuOS0xLjEsMy4yLTIuNyw1LjktNC43LDguMXMtNC41LDMuOS03LjMsNWMtMi45LDEuMS02LjEsMS42LTkuNywxLjZzLTYuNC0uNS05LjItMS42Yy0yLjgtMS4yLTUuMy0yLjgtNy4zLTVzLTMuNi00LjktNC44LTguMWMtMS4yLTMuMi0xLjctNi44LTEuNy0xMXMuOS0xMCwyLjctMTMuOGMxLjktMy44LDQuNi02LjcsOC4xLTguNiwzLjUtMiw3LjctMywxMi41LTNzOC41LDEsMTEuOSwzYzMuNSwyLDYuMiw0LjgsOC4yLDguNiwxLjksMy43LDIuOSw4LjQsMi45LDEzLjlaTTQzNCwxMDguOGMwLDMuNy41LDYuOCwxLjQsOS41LjksMi42LDIuNCw0LjYsNC4zLDYsMiwxLjQsNC41LDIuMSw3LjUsMi4xczUuNi0uNyw3LjUtMi4xYzItMS40LDMuNC0zLjQsNC4zLTYsLjktMi43LDEuNC01LjksMS40LTkuNXMtLjUtNy0xLjUtOS41Yy0uOS0yLjYtMi40LTQuNS00LjMtNS45cy00LjQtMi4xLTcuNS0yLjFjLTQuNiwwLTcuOSwxLjUtMTAsNC42LTIuMSwzLTMuMSw3LjMtMy4xLDEyLjlaIi8+CiAgPHBhdGggY2xhc3M9InN0MCIgZD0iTTUyMi4xLDg0LjF2NDkuNGgtNy44bC0xLjMtNi41aC0uNWMtMSwxLjctMi40LDMuMS00LDQuMi0xLjYsMS4xLTMuNSwxLjktNS40LDIuNC0yLC41LTQsLjgtNiwuOC0zLjgsMC03LjEtLjYtOS44LTEuOC0yLjYtMS4zLTQuNi0zLjItNi01LjktMS4zLTIuNy0yLTYuMS0yLTEwLjN2LTMyLjNoOS44djMwLjljMCwzLjguOCw2LjcsMi40LDguNnM0LjIsMi44LDcuNiwyLjgsNi4xLS43LDguMS0yLDMuMy0zLjMsNC4xLTUuOWMuOS0yLjYsMS4zLTUuOCwxLjMtOS40di0yNWg5LjVaIi8+CiAgPHBhdGggY2xhc3M9InN0MCIgZD0iTTU2Ni41LDExOS42YzAsMy4yLS44LDYtMi40LDguMi0xLjYsMi4yLTMuOSwzLjktNi45LDUtMywxLjEtNi42LDEuNi0xMC44LDEuNnMtNi41LS4zLTktLjhjLTIuNC0uNS00LjctMS4yLTYuOC0yLjJ2LTguNWMyLjIsMSw0LjcsMiw3LjYsMi44LDIuOS44LDUuNywxLjIsOC40LDEuMnM2LjMtLjYsNy45LTEuN2MxLjYtMS4yLDIuNS0yLjcsMi41LTQuN3MtLjMtMi4xLS45LTIuOWMtLjYtLjktMS44LTEuOC0zLjUtMi43LTEuNy0xLTQuMS0yLjEtNy4zLTMuMy0zLjEtMS4zLTUuOC0yLjUtOC0zLjhzLTMuOS0yLjgtNS00LjVjLTEuMi0xLjgtMS43LTQtMS43LTYuOCwwLTQuMywxLjctNy41LDUuMS05LjgsMy41LTIuMyw4LjEtMy41LDEzLjctMy41czUuOC4zLDguNC45YzIuNy41LDUuMywxLjQsNy44LDIuNmwtMy4yLDcuNGMtMS40LS43LTIuOS0xLjItNC40LTEuNi0xLjUtLjUtMy0uOS00LjUtMS4yLTEuNS0uMy0zLS41LTQuNi0uNS0yLjksMC01LjIuNS02LjcsMS40cy0yLjMsMi4yLTIuMywzLjguMywyLjIsMSwzYy43LjksMiwxLjcsMy44LDIuNnM0LjIsMS45LDcuMiwzLjFjMy4xLDEuMiw1LjcsMi40LDcuOCwzLjYsMi4yLDEuMiwzLjgsMi43LDQuOSw0LjUsMS4zLDEuOCwxLjksNC4xLDEuOSw2LjhaIi8+CiAgPHBhdGggY2xhc3M9InN0MCIgZD0iTTU5Ni4yLDgzLjJjNC4zLDAsOC4xLjksMTEuMiwyLjcsMy4xLDEuOCw1LjUsNC4zLDcuMSw3LjcsMS43LDMuNCwyLjYsNy4zLDIuNiwxMS45djUuM2gtMzMuMmMwLDUuMSwxLjQsOC45LDMuOSwxMS42LDIuNiwyLjcsNi4xLDQsMTAuNyw0czYtLjMsOC40LS44YzIuNS0uNiw1LjEtMS41LDcuNy0yLjd2OC4xYy0yLjQsMS4xLTQuOSwxLjktNy41LDIuNS0yLjUuNS01LjUuOC05LC44cy05LS45LTEyLjYtMi44Yy0zLjctMS45LTYuNS00LjctOC42LTguNC0yLTMuOC0zLTguNC0zLTEzLjlzLjktMTAuMywyLjctMTQuMWMxLjktMy44LDQuNS02LjgsNy44LTguOCwzLjQtMiw3LjQtMy4xLDExLjgtMy4xWk01OTYuMiw5MC43Yy0zLjUsMC02LjMsMS4xLTguNCwzLjQtMi4xLDIuMy0zLjMsNS41LTMuNyw5LjZoMjMuM2MwLTIuNi0uNC00LjgtMS4yLTYuOHMtMi0zLjUtMy43LTQuNmMtMS42LTEtMy43LTEuNi02LjMtMS42WiIvPgo8L3N2Zz4=",
+ "created": 1741098070064,
+ "version": 2
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/content/docs/integrations/clickhouse.mdx b/src/content/docs/integrations/clickhouse.mdx
index 1fb2368b8..9e06d53dd 100644
--- a/src/content/docs/integrations/clickhouse.mdx
+++ b/src/content/docs/integrations/clickhouse.mdx
@@ -2,155 +2,239 @@
title: ClickHouse
---
-[ClickHouse](https://clickhouse.com/clickhouse) is an open-source analytical
-database. It lets you run real-time analytics with SQL queries.
-
-
-
-## How Tenzir Connects to ClickHouse
-
-Tenzir connects to ClickHouse over the network using the native ClickHouse TCP
-protocol using the official
-[clickhouse-cpp](https://github.com/ClickHouse/clickhouse-cpp) library. Tenzir
-communicates with ClickHouse via the host and port you specify in
-the to_clickhouse operator. This means:
-
-- **Network**: Tenzir and ClickHouse can run on the same machine (using
- `localhost`) or on different machines in the same network. You just need to
- make sure that Tenzir can reach the ClickHouse server.
-- **IPC**: There is no direct inter-process communication (IPC) mechanism; all
- communication uses ClickHouse's network protocol.
-- **Co-deployment**: For best performance and security, deploy Tenzir and
- ClickHouse in the same trusted network or use secure tunnels if needed.
-
-## Setting Up ClickHouse
+import { Steps } from "@astrojs/starlight/components";
-To get started with ClickHouse, follow the [official quick start
-guide](https://clickhouse.com/docs/getting-started/quick-start/oss):
+This page shows you how to use ClickHouse as an analytical store for Tenzir
+pipelines: write normalized security telemetry to ClickHouse with
+to_clickhouse and read tables or SQL query results back into Tenzir
+with from_clickhouse .
-### Native Binary
+[ClickHouse](https://clickhouse.com/clickhouse) is an open-source analytical
+database built for fast SQL over large event volumes. Tenzir sits in front of
+ClickHouse as a programmable security data pipeline: it collects telemetry,
+parses source formats, maps events to OCSF, enriches or reduces volume, and
+writes structured tables that analysts and detection systems can query.
-import { Steps } from "@astrojs/starlight/components";
+With from_clickhouse , ClickHouse can also feed later pipeline stages.
+Use this path to backfill historical events, export query results, materialize
+detection outputs, or route subsets to another tool without adding another
+ingestion path.
-
+
-1. Download the binary:
+## Choose an integration path
- ```sh
- curl https://clickhouse.com/ | sh
- ```
+Use the path that matches the role ClickHouse plays in your deployment:
-2. Start the server:
+| Goal | ClickHouse role | Tenzir building blocks |
+| :--- | :--- | :--- |
+| Build a security data lake | Destination for OCSF-normalized telemetry | ocsf::cast , to_clickhouse |
+| Keep a schema you manage in ClickHouse | Existing MergeTree table with explicit types, TTLs, projections, or materialized views | to_clickhouse with `mode="append"` |
+| Query retained telemetry | Source table or SQL query result | from_clickhouse |
+| Run lake-backed hunts or detections | SQL engine for filtering, grouping, and sorting large event sets | from_clickhouse , where , publish |
+| Export or fan out query results | Query result source for downstream tools or object storage | from_clickhouse , output operators such as to_s3 or to_http |
+| Inspect available tables and schemas | `SHOW`, `DESCRIBE`, or `system.*` metadata queries | from_clickhouse with `sql=...` |
- ```sh
- ./clickhouse server
- ```
+## Connect to ClickHouse
- This downloads the ClickHouse binary and starts the server. You can then
- connect to ClickHouse at `localhost:9000` (native protocol) or
- `localhost:8123` (HTTP interface).
+Tenzir connects to ClickHouse through the native ClickHouse TCP protocol using
+the official [clickhouse-cpp](https://github.com/ClickHouse/clickhouse-cpp)
+client library. The operators don't use ClickHouse's HTTP interface or a local
+IPC mechanism.
-3. (Optionally) Start CLI client:
+Use either a ClickHouse URI or explicit connection arguments:
- ```sh
- ./clickhouse client
- ```
+```tql
+from_clickhouse uri="clickhouse://default:secret@localhost:9000/security",
+ table="events",
+ tls=false
+```
- With this client, you can now run SQL queries on your ClickHouse server.
+You can also pass the connection details as separate arguments:
-
+```tql
+from_clickhouse table="security.events",
+ host="localhost",
+ port=9000,
+ user="default",
+ password=secret("CLICKHOUSE_PASSWORD"),
+ tls=false
+```
-### Docker
+Use the same connection arguments with to_clickhouse . If a URI selects
+a database and `table` is unqualified, Tenzir uses that database. In create
+modes, to_clickhouse also creates the selected database if it doesn't
+exist.
-
+## Set up ClickHouse
-1. Run Docker:
+::::tip[Start with ClickHouse Cloud]
+Use ClickHouse Cloud when you want ClickHouse managed separately from Tenzir
+but still reachable through the native protocol. Create a service with the
+[ClickHouse Cloud quick start](https://clickhouse.com/docs/getting-started/quick-start/cloud),
+copy the native endpoint, port, user, and database from the connection details,
+and keep TLS enabled.
- ```sh
- docker run -d --name clickhouse-server --ulimit nofile=262144:262144 \
- -p 9000:9000 -p 8123:8123 clickhouse/clickhouse-server
- ```
+Store the password in Tenzir's secret store and pass the Cloud connection
+details to either ClickHouse operator:
-
+```tql
+from_clickhouse table="security.events",
+ host="abc123.us-east-1.aws.clickhouse.cloud",
+ port=9440,
+ password=secret("CLICKHOUSE_PASSWORD")
+```
----
+The examples later use `tls=false` only because they assume a local
+self-managed ClickHouse server without TLS.
+::::
-You can now connect to ClickHouse at `localhost:9000` (native protocol) or
-`localhost:8123` (HTTP interface).
+If you need a local or self-managed ClickHouse deployment, start with the
+[ClickHouse OSS quick start](https://clickhouse.com/docs/getting-started/quick-start/oss).
+Tenzir connects to a self-managed server the same way, using the native host and
+port you configure in from_clickhouse and to_clickhouse .
## Examples
-These examples assume that the ClickHouse server is running on the same host as
-Tenzir and that it allows non-TLS connections (hence using `tls=false` in the
-pipelines).
+These examples assume that ClickHouse runs on the same host as Tenzir and
+allows non-TLS connections, which is why the pipelines use `tls=false`. For
+ClickHouse Cloud, use your service endpoint and credentials, and keep TLS
+enabled.
-You can find out more about how to configure TLS on the to_clickhouse
-documentation and the [Clickhouse SSL-TLS configuration
-guide](https://clickhouse.com/docs/guides/sre/configuring-ssl)
+### Land OCSF telemetry in ClickHouse
-### 1. Easy Mode: Automatic table creation
-
-Tenzir can automatically create tables in ClickHouse based on the incoming data
-schema. For example, to ingest OCSF network activity data:
+Use this path when ClickHouse is your security data lake. Tenzir can create
+tables from incoming events, and ocsf::cast keeps the ClickHouse schema
+stable by casting events to the selected OCSF class, encoding variant fields,
+and filling missing fields with typed nulls.
```tql
from_file "ocsf_network_activity.json"
ocsf::cast encode_variants=true, null_fill=true
-to_clickhouse table=f"ocsf.{class_name.replace(" ","_")}", primary=time, tls=false
+to_clickhouse table=f"ocsf.{class_name.replace(" ","_")}",
+ primary=time,
+ tls=false
```
When creating a table, the to_clickhouse operator uses the first event
-to determine the schema. You must take care that there are no untyped nulls in
-this event, as the operator cannot transmit those.
-
-In this example, we use the ocsf::cast operator, which will
-automatically align events with the correct OCSF schema, giving all fields the
-correct types and adding all fields that should be in `ocsf.Network_Activity`.
-This ensures that we create a complete table without missing or incorrectly
-typed columns.
+to determine the schema. Make sure the first event doesn't contain untyped nulls
+or empty records. ocsf::cast helps because it gives expected OCSF
+fields explicit types before the table is created.
-You can now query the data in ClickHouse, e.g.:
+After the data lands, query it directly in ClickHouse:
```sql
-SELECT median(traffic.bytes_in), median(traffic.bytes_out)
+SELECT
+ dst_endpoint.ip,
+ count() AS events,
+ median(traffic.bytes_in) AS median_bytes_in
FROM ocsf.Network_Activity
-GROUP BY *
+WHERE time > now() - INTERVAL 1 DAY
+GROUP BY dst_endpoint.ip
+ORDER BY events DESC
+LIMIT 20;
```
-### 2. Advanced: Explicit Table Creation
+### Append to a table you manage
-For more control, you can create the table in ClickHouse first. Use this
-approach when you know the full schema of your table, but not all events contain
-all fields and as such the operator would not create the correct table.
+Create the ClickHouse table first when you need explicit types, table engines,
+TTL policies, projections, materialized views, or partitioning that should stay
+under ClickHouse control.
1. Create the table in ClickHouse:
```sql
- CREATE TABLE my_table (
- id Int64,
- name String,
- mice_caught Nullable(Int64)
- ) ENGINE = MergeTree() ORDER BY id;
+ CREATE DATABASE IF NOT EXISTS security;
+
+ CREATE TABLE security.alerts (
+ time DateTime64(9),
+ rule_name String,
+ severity Int64,
+ src_ip Nullable(IPv6),
+ message String
+ ) ENGINE = MergeTree()
+ ORDER BY (time, rule_name);
```
2. Ingest data from Tenzir:
- ```csv title="my_file.csv"
- id,name,mice_caught
- 0,Jerry,
- 1,Tom,0
- ```
-
```tql
- from_file "my_file.csv"
- to_clickhouse table="my_table", mode="append", tls=false
+ from {
+ time: 2026-06-01T12:00:00Z,
+ rule_name: "failed-login-burst",
+ severity: 5,
+ src_ip: 10.0.1.12,
+ message: "More than 20 failed logons from one source in 5 minutes",
+ }
+ to_clickhouse table="security.alerts", mode="append", tls=false
```
- We use the explicit `mode="append"` to ensure that the table already exists.
-
- In this example _Jerry_, being a mouse, has no value for `mice_caught`. Since
- we created a table with the expected type, this is not an issue.
+ `mode="append"` makes the pipeline fail if the table doesn't already exist,
+ so ClickHouse remains the source of truth for the schema.
+
+### Read data from ClickHouse
+
+Use table mode when you want Tenzir to read a ClickHouse table as structured
+events. Filters after from_clickhouse can be pushed into ClickHouse in
+table mode, which reduces the amount of data transferred into the pipeline.
+
+```tql
+from_clickhouse table="ocsf.Network_Activity", tls=false
+where time > now() - 1d and severity_id >= 3
+publish "clickhouse-network-activity"
+```
+
+Use SQL mode when ClickHouse should project, aggregate, sort, or otherwise shape
+the result before Tenzir receives it:
+
+```tql
+from_clickhouse sql="SELECT time, host, severity, message FROM security.events WHERE severity >= 3 ORDER BY time DESC",
+ tls=false
+publish "clickhouse-findings"
+```
+
+### Inspect tables and schemas
+
+Use SQL mode for ClickHouse metadata queries:
+
+```tql
+from_clickhouse sql="SHOW TABLES FROM ocsf", tls=false
+```
+
+To inspect columns for a specific table, run `DESCRIBE TABLE`:
+
+```tql
+from_clickhouse sql="DESCRIBE TABLE ocsf.Network_Activity", tls=false
+```
+
+### Export query results
+
+Because from_clickhouse turns query results into regular Tenzir
+events, you can route them to any supported destination. For example, export a
+seven-day slice to S3 as Parquet:
+
+```tql
+from_clickhouse sql="SELECT * FROM ocsf.Network_Activity WHERE time >= now() - INTERVAL 7 DAY",
+ tls=false
+to_s3 "s3://security-exports/clickhouse/network_activity_{uuid}.parquet" {
+ write_parquet
+}
+```
+
+## See Also
+
+- from_clickhouse
+- ocsf::cast
+- publish
+- to_clickhouse
+- to_http
+- to_s3
+- where
+- write_parquet
+- collecting/read-from-data-stores
+- routing/send-to-destinations
+- secrets
diff --git a/src/content/docs/integrations/clickhouse.svg b/src/content/docs/integrations/clickhouse.svg
deleted file mode 100644
index e7c971d5e..000000000
--- a/src/content/docs/integrations/clickhouse.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-Database clickhouse-cpp Table
\ No newline at end of file
diff --git a/src/content/docs/integrations/mysql.mdx b/src/content/docs/integrations/mysql.mdx
index 2199bb694..5c6d65e80 100644
--- a/src/content/docs/integrations/mysql.mdx
+++ b/src/content/docs/integrations/mysql.mdx
@@ -47,4 +47,5 @@ from_mysql table="events", live=true, host="localhost", database="mydb"
## See Also
+- collecting/read-from-data-stores
- from_mysql
diff --git a/src/content/docs/reference/operators.mdx b/src/content/docs/reference/operators.mdx
index 1011b2052..4a544b1dc 100644
--- a/src/content/docs/reference/operators.mdx
+++ b/src/content/docs/reference/operators.mdx
@@ -375,6 +375,10 @@ operators:
description: 'Reads one or multiple files from Azure Blob Storage.'
example: 'from_azure_blob_storage "abfs://container/data/**.json"'
path: 'reference/operators/from_azure_blob_storage'
+ - name: 'from_clickhouse'
+ description: 'Reads rows or metadata from ClickHouse.'
+ example: 'from_clickhouse table="my_table"'
+ path: 'reference/operators/from_clickhouse'
- name: 'from_file'
description: 'Reads one or multiple files from a filesystem.'
example: 'from_file "s3://data/**.json"'
@@ -1534,6 +1538,14 @@ from_azure_blob_storage "abfs://container/data/**.json"
+
+
+```tql
+from_clickhouse table="my_table"
+```
+
+
+
```tql
diff --git a/src/content/docs/reference/operators/from_clickhouse.mdx b/src/content/docs/reference/operators/from_clickhouse.mdx
new file mode 100644
index 000000000..1aea24510
--- /dev/null
+++ b/src/content/docs/reference/operators/from_clickhouse.mdx
@@ -0,0 +1,177 @@
+---
+title: from_clickhouse
+category: Inputs/Events
+example: 'from_clickhouse table="my_table"'
+---
+
+import TLSOptions from '@partials/operators/TLSOptions.mdx';
+
+Fetches data from a ClickHouse server.
+
+```tql
+from_clickhouse [table=string, sql=string,
+ uri=string | (host=string, port=int, user=string, password=string),
+ tls=bool|record]
+```
+
+## Description
+
+The from_clickhouse operator issues a query to a ClickHouse server. You
+can either provide a `table` to read or an `sql` query.
+
+### `uri = string (optional)`
+
+A ClickHouse connection URI in the format:
+
+```text
+clickhouse://[user[:password]@]host[:port][/database]
+```
+
+When present, the URI supplies the connection endpoint and optionally the
+current database.
+
+Use `tls` separately to control TLS.
+
+Use either `uri` or the explicit connection arguments `host`, `port`, `user`,
+and `password`.
+
+### `table = string`
+
+The table to read from.
+
+You can qualify the table as `.`. If you omit the database,
+ClickHouse uses the current database selected by the URI or server defaults.
+
+Use this mode when you want to read a whole table and preserve named tuple
+fields from the table schema.
+
+Use exactly one of `table` or `sql`.
+
+### `sql = string`
+
+A custom SQL query to execute.
+
+Use this mode when you want ClickHouse to filter, project, sort, or cast data
+before Tenzir reads it.
+
+For metadata queries such as `SHOW TABLES`, `DESCRIBE TABLE`, or queries
+against `system.tables` and `system.columns`, use `sql`.
+
+Use exactly one of `table` or `sql`.
+
+### `host = string (optional)`
+
+The hostname for the ClickHouse server.
+
+Defaults to `"localhost"`.
+
+Mutually exclusive with `uri`.
+
+### `port = int (optional)`
+
+The port for the ClickHouse server.
+
+Defaults to `9000` without TLS and `9440` with TLS.
+
+Mutually exclusive with `uri`.
+
+### `user = string (optional)`
+
+The user to use for authentication.
+
+Defaults to `"default"`.
+
+Mutually exclusive with `uri`.
+
+### `password = string (optional)`
+
+The password for the given user.
+
+Defaults to `""`.
+
+Mutually exclusive with `uri`.
+
+
+
+## Types
+
+Tenzir maps ClickHouse types to Tenzir types as follows:
+
+| ClickHouse | Tenzir | Comment |
+| :------------------------------------------------ | :-------- | :--------------------------------------------- |
+| `Bool` | `bool` | |
+| `Int8`, `Int16`, `Int32`, `Int64` | `int64` | |
+| `UInt8`, `UInt16`, `UInt32`, `UInt64` | `uint64` | |
+| `Float32`, `Float64` | `double` | |
+| `String`, `FixedString(N)` | `string` | |
+| `UUID` | `string` | Emitted as canonical UUID text. |
+| `Enum8`, `Enum16` | `string` | Emitted as the enum label. |
+| `Decimal`, `Decimal32`, `Decimal64`, `Decimal128` | `string` | Emitted as decimal text to preserve precision. |
+| `Date`, `Date32`, `DateTime`, `DateTime64` | `time` | |
+| `IPv4`, `IPv6` | `ip` | |
+| `Tuple(...)` | `record` | |
+| `Array(T)` | `list` | |
+| `Array(UInt8)` | `blob` | |
+| `Nullable(T)` | `T` | Null values stay null. |
+
+`Map(...)` is not currently supported. Cast unsupported columns in `sql` or
+omit them from the query result.
+
+## Predicate Pushdown
+Tenzir has Predicate Pushdown, allowing `where` filters to be pushed up a pipeline
+and into the `from_clickhouse` operator. Where possible, `from_clickhouse` will
+also push this predicate into the query send to the ClickHouse server to reduce
+transfer and compute cost:
+
+```tql
+from_clickhouse table="db.table", host="localhost"
+where i > 42
+```
+is equivalent to
+```tql
+from_clickhouse sql="select * from db.table where i > 42", host="localhost"
+```
+
+Pushdown is only performed in `table` mode. When you provide an `sql` statement,
+you should consider filtering in the statement itself.
+
+## Examples
+
+### Read all rows from a table
+
+```tql
+from_clickhouse table="events", tls=false
+```
+
+### Use a connection URI
+
+```tql
+from_clickhouse uri="clickhouse://default:secret@clickhouse.example.com:9000/security",
+ table="events",
+ tls=false
+```
+
+### Run a filtered SQL query
+
+```tql
+from_clickhouse sql="SELECT * FROM events WHERE severity >= 3 ORDER BY time DESC",
+ tls=false
+```
+
+### List tables in the current database
+
+```tql
+from_clickhouse sql="SHOW TABLES", tls=false
+```
+
+### Show the columns for a table
+
+```tql
+from_clickhouse sql="DESCRIBE TABLE events", tls=false
+```
+
+## See Also
+
+- to_clickhouse
+- collecting/read-from-data-stores
+- clickhouse
diff --git a/src/content/docs/reference/operators/from_mysql.mdx b/src/content/docs/reference/operators/from_mysql.mdx
index cdfece6f3..86bfe6066 100644
--- a/src/content/docs/reference/operators/from_mysql.mdx
+++ b/src/content/docs/reference/operators/from_mysql.mdx
@@ -238,5 +238,6 @@ from_mysql table="events", live=true, tracking_column="event_id",
## See Also
+- collecting/read-from-data-stores
- to_clickhouse
- mysql
diff --git a/src/content/docs/reference/operators/to_clickhouse.mdx b/src/content/docs/reference/operators/to_clickhouse.mdx
index e36d44a23..6e2d66dd6 100644
--- a/src/content/docs/reference/operators/to_clickhouse.mdx
+++ b/src/content/docs/reference/operators/to_clickhouse.mdx
@@ -7,9 +7,9 @@ example: 'to_clickhouse table="my_table"'
Sends events to a ClickHouse table.
```tql
-to_clickhouse table=string, [host=string, port=int, user=string, password=string,
- mode=string, primary=field, database=string,
- tls=record]
+to_clickhouse table=string,
+ [uri=string | (host=string, port=int, user=string, password=string)],
+ [mode=string, primary=field, tls=bool|record]
```
## Description
@@ -21,8 +21,25 @@ The name of the table you want to write to.
This can be a dynamic expression, allowing you to automatically write to different
tables based on the data.
-The `.` notation can be used to also specify a table. If no ``,
-is provided, `"default"` will be used.
+The `.` notation can be used to also specify a table. If no ``
+is provided, Tenzir writes to the database selected by the URI, if any, or the server default.
+
+### `uri = string (optional)`
+
+A ClickHouse connection URI in the format:
+
+```text
+clickhouse://[user[:password]@]host[:port][/database]
+```
+
+When present, the URI supplies the connection endpoint and optionally the
+current database.
+
+If the URI includes `/database` and `table` is unqualified, Tenzir writes to
+that database. In `mode="create"` and `mode="create_append"`, Tenzir also
+creates the selected database if it does not exist yet.
+
+Use `tls` separately to control TLS.
### `host = string (optional)`
@@ -30,24 +47,32 @@ The hostname for the ClickHouse server.
Defaults to `"localhost"`.
+Mutually exclusive with `uri`.
+
### `port = int (optional)`
The port for the ClickHouse server.
Defaults to `9000` without TLS and `9440` with TLS.
+Mutually exclusive with `uri`.
+
### `user = string (optional)`
The user to use for authentication.
Defaults to `"default"`.
+Mutually exclusive with `uri`.
+
### `password = string (optional)`
The password for the given user.
Defaults to `""`.
+Mutually exclusive with `uri`.
+
### `mode = string (optional)`
- `"create"` Create a table and database. Fails the table already exists.
@@ -76,7 +101,7 @@ translation from Tenzir's types to ClickHouse:
| Tenzir | ClickHouse | Comment |
| :--------- | :----------------------------- | :---------------------------------------------------------------------------------------------------- |
-| `bool` | `UInt8` | |
+| `bool` | `Bool` | |
| `int64` | `Int64` | |
| `uint64` | `UInt64` | |
| `double` | `Float64` | |
@@ -153,6 +178,18 @@ from_file "my_file.csv"
to_clickhouse table="my_table", tls=false
```
+### Use a connection URI
+
+```tql
+from_file "my_file.csv"
+to_clickhouse uri="clickhouse://default:secret@clickhouse.example.com:9000/security",
+ table="alerts",
+ primary=time,
+ tls=false
+```
+
+This writes to `security.alerts`.
+
### Send OCSF data to ClickHouse
When sending OCSF data to ClickHouse, it is important to ensure that a consistent
@@ -179,7 +216,7 @@ This creates the following table:
┌─name─┬─type────────────────────┐
1. │ i │ Int64 │
2. │ d │ Nullable(Float64) │
-3. │ b │ Nullable(UInt8) │
+3. │ b │ Nullable(Bool) │
4. │ l │ Array(Nullable(Int64)) │
5. │ r │ Tuple( ↴│
│ │↳ s Nullable(String)) │
@@ -188,5 +225,7 @@ This creates the following table:
## See Also
+- from_clickhouse
- ocsf::cast
+- routing/send-to-destinations
- clickhouse
diff --git a/src/content/docs/reference/operators/to_snowflake.mdx b/src/content/docs/reference/operators/to_snowflake.mdx
index b3f5f9878..9622aaedf 100644
--- a/src/content/docs/reference/operators/to_snowflake.mdx
+++ b/src/content/docs/reference/operators/to_snowflake.mdx
@@ -96,4 +96,5 @@ to_snowflake \
## See Also
+- routing/send-to-destinations
- snowflake
diff --git a/src/sidebar.ts b/src/sidebar.ts
index d3d5398a4..e8adf8788 100644
--- a/src/sidebar.ts
+++ b/src/sidebar.ts
@@ -93,6 +93,7 @@ export const guides = [
"guides/collecting/read-and-watch-files",
"guides/collecting/fetch-via-http-and-apis",
"guides/collecting/read-from-message-brokers",
+ "guides/collecting/read-from-data-stores",
"guides/collecting/get-data-from-the-network",
],
},