Rybbit
Open-source and privacy-friendly alternative to Google Analytics that is 10x more intuitive
Configuration
# https://www.rybbit.io/docs/self-hosting-advanced
# NOTE: there are two sample HTTP traefik domain entries created:
# - rybbit_backend (port 3001, path /api),
# - rybbit_client (port 3002, path /)
#
# You should treat these as placeholders - Rybbit only supports HTTPS.
#
# You should also update the `BASE_URL` environment variable when
# updating the domain entries with your custom domain.
services:
rybbit_clickhouse:
image: clickhouse/clickhouse-server:25.5
volumes:
- clickhouse_data:/var/lib/clickhouse
- ../files/clickhouse_config:/etc/clickhouse-server/config.d
environment:
- CLICKHOUSE_DB=${CLICKHOUSE_DB}
- CLICKHOUSE_USER=${CLICKHOUSE_USER}
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD}
healthcheck:
test:
[
"CMD",
"wget",
"--no-verbose",
"--tries=1",
"--spider",
"http://localhost:8123/ping",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
restart: unless-stopped
rybbit_postgres:
image: postgres:17.5
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
rybbit_redis:
image: redis:7-alpine
volumes:
- redis_data:/data
# Backs session tracking and the BullMQ queues. noeviction is required by
# BullMQ (evicting job keys corrupts queues); AOF (everysec) keeps queues
# durable across restarts.
command:
- redis-server
- --requirepass
- ${REDIS_PASSWORD}
- --appendonly
- "yes"
- --appendfsync
- everysec
- --maxmemory-policy
- noeviction
healthcheck:
test:
[
"CMD",
"redis-cli",
"-a",
"${REDIS_PASSWORD}",
"--no-auth-warning",
"ping",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 5s
restart: unless-stopped
rybbit_backend:
image: ghcr.io/rybbit-io/rybbit-backend:v2.7.0
environment:
- NODE_ENV=production
- CLICKHOUSE_HOST=http://rybbit_clickhouse:8123
- CLICKHOUSE_DB=${CLICKHOUSE_DB}
- CLICKHOUSE_USER=${CLICKHOUSE_USER}
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD}
- POSTGRES_HOST=rybbit_postgres
- POSTGRES_PORT=5432
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- REDIS_HOST=rybbit_redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD}
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
- BASE_URL=${BASE_URL}
- DISABLE_SIGNUP=${DISABLE_SIGNUP}
- DISABLE_TELEMETRY=${DISABLE_TELEMETRY}
depends_on:
rybbit_clickhouse:
condition: service_healthy
rybbit_postgres:
condition: service_started
rybbit_redis:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:3001/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
restart: unless-stopped
rybbit_client:
image: ghcr.io/rybbit-io/rybbit-client:v2.7.0
environment:
- NODE_ENV=production
- NEXT_PUBLIC_BACKEND_URL=${BASE_URL}
- NEXT_PUBLIC_DISABLE_SIGNUP=${DISABLE_SIGNUP}
depends_on:
- rybbit_backend
restart: unless-stopped
volumes:
clickhouse_data:
postgres_data:
redis_data:[variables]
main_domain = "${domain}"
better_auth_secret = "${base64:32}"
clickhouse_password = "${password:32}"
postgres_password = "${password:32}"
redis_password = "${password:32}"
[[config.domains]]
serviceName = "rybbit_backend"
port = 3001
host = "${main_domain}"
path = "/api"
[[config.domains]]
serviceName = "rybbit_client"
port = 3002
host = "${main_domain}"
[config.env]
BASE_URL = "http://${main_domain}"
BETTER_AUTH_SECRET = "${better_auth_secret}"
DISABLE_SIGNUP = "false"
DISABLE_TELEMETRY = "false"
CLICKHOUSE_DB = "analytics"
CLICKHOUSE_USER = "default"
CLICKHOUSE_PASSWORD = "${clickhouse_password}"
POSTGRES_DB = "analytics"
POSTGRES_USER = "frog"
POSTGRES_PASSWORD = "${postgres_password}"
REDIS_PASSWORD = "${redis_password}"
[[config.mounts]]
filePath = "./clickhouse_config/enable_json.xml"
content = """
<clickhouse>
<settings>
<enable_json_type>1</enable_json_type>
</settings>
</clickhouse>
"""
[[config.mounts]]
filePath = "./clickhouse_config/logging_rules.xml"
content = """
<clickhouse>
<logger>
<level>warning</level>
<console>true</console>
</logger>
<query_thread_log remove="remove"/>
<query_log remove="remove"/>
<text_log remove="remove"/>
<trace_log remove="remove"/>
<metric_log remove="remove"/>
<asynchronous_metric_log remove="remove"/>
<session_log remove="remove"/>
<part_log remove="remove"/>
<latency_log remove="remove"/>
<processors_profile_log remove="remove"/>
</clickhouse>
"""
[[config.mounts]]
filePath = "./clickhouse_config/network.xml"
content = """
<clickhouse>
<listen_host>0.0.0.0</listen_host>
</clickhouse>
"""
[[config.mounts]]
filePath = "./clickhouse_config/user_logging.xml"
content = """
<clickhouse>
<profiles>
<default>
<log_queries>0</log_queries>
<log_query_threads>0</log_query_threads>
<log_processors_profiles>0</log_processors_profiles>
</default>
</profiles>
</clickhouse>
"""Base64
To import this template in Dokploy: create a Compose service → Advanced → Base64 import and paste the content below:
ewogICJjb21wb3NlIjogIiMgaHR0cHM6Ly93d3cucnliYml0LmlvL2RvY3Mvc2VsZi1ob3N0aW5nLWFkdmFuY2VkXG5cbiMgTk9URTogdGhlcmUgYXJlIHR3byBzYW1wbGUgSFRUUCB0cmFlZmlrIGRvbWFpbiBlbnRyaWVzIGNyZWF0ZWQ6XG4jIC0gcnliYml0X2JhY2tlbmQgKHBvcnQgMzAwMSwgcGF0aCAvYXBpKSxcbiMgLSByeWJiaXRfY2xpZW50IChwb3J0IDMwMDIsIHBhdGggLylcbiNcbiMgWW91IHNob3VsZCB0cmVhdCB0aGVzZSBhcyBwbGFjZWhvbGRlcnMgLSBSeWJiaXQgb25seSBzdXBwb3J0cyBIVFRQUy5cbiNcbiMgWW91IHNob3VsZCBhbHNvIHVwZGF0ZSB0aGUgYEJBU0VfVVJMYCBlbnZpcm9ubWVudCB2YXJpYWJsZSB3aGVuXG4jIHVwZGF0aW5nIHRoZSBkb21haW4gZW50cmllcyB3aXRoIHlvdXIgY3VzdG9tIGRvbWFpbi5cblxuc2VydmljZXM6XG4gIHJ5YmJpdF9jbGlja2hvdXNlOlxuICAgIGltYWdlOiBjbGlja2hvdXNlL2NsaWNraG91c2Utc2VydmVyOjI1LjVcbiAgICB2b2x1bWVzOlxuICAgICAgLSBjbGlja2hvdXNlX2RhdGE6L3Zhci9saWIvY2xpY2tob3VzZVxuICAgICAgLSAuLi9maWxlcy9jbGlja2hvdXNlX2NvbmZpZzovZXRjL2NsaWNraG91c2Utc2VydmVyL2NvbmZpZy5kXG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICAtIENMSUNLSE9VU0VfREI9JHtDTElDS0hPVVNFX0RCfVxuICAgICAgLSBDTElDS0hPVVNFX1VTRVI9JHtDTElDS0hPVVNFX1VTRVJ9XG4gICAgICAtIENMSUNLSE9VU0VfUEFTU1dPUkQ9JHtDTElDS0hPVVNFX1BBU1NXT1JEfVxuICAgIGhlYWx0aGNoZWNrOlxuICAgICAgdGVzdDpcbiAgICAgICAgW1xuICAgICAgICAgIFwiQ01EXCIsXG4gICAgICAgICAgXCJ3Z2V0XCIsXG4gICAgICAgICAgXCItLW5vLXZlcmJvc2VcIixcbiAgICAgICAgICBcIi0tdHJpZXM9MVwiLFxuICAgICAgICAgIFwiLS1zcGlkZXJcIixcbiAgICAgICAgICBcImh0dHA6Ly9sb2NhbGhvc3Q6ODEyMy9waW5nXCIsXG4gICAgICAgIF1cbiAgICAgIGludGVydmFsOiAzMHNcbiAgICAgIHRpbWVvdXQ6IDEwc1xuICAgICAgcmV0cmllczogM1xuICAgICAgc3RhcnRfcGVyaW9kOiAxMHNcbiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZFxuXG4gIHJ5YmJpdF9wb3N0Z3JlczpcbiAgICBpbWFnZTogcG9zdGdyZXM6MTcuNVxuICAgIGVudmlyb25tZW50OlxuICAgICAgLSBQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCfVxuICAgICAgLSBQT1NUR1JFU19VU0VSPSR7UE9TVEdSRVNfVVNFUn1cbiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JHtQT1NUR1JFU19QQVNTV09SRH1cbiAgICB2b2x1bWVzOlxuICAgICAgLSBwb3N0Z3Jlc19kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YVxuICAgIGhlYWx0aGNoZWNrOlxuICAgICAgdGVzdDogW1wiQ01ELVNIRUxMXCIsIFwicGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn1cIl1cbiAgICAgIGludGVydmFsOiAzMHNcbiAgICAgIHRpbWVvdXQ6IDEwc1xuICAgICAgcmV0cmllczogM1xuICAgIHJlc3RhcnQ6IHVubGVzcy1zdG9wcGVkXG5cbiAgcnliYml0X3JlZGlzOlxuICAgIGltYWdlOiByZWRpczo3LWFscGluZVxuICAgIHZvbHVtZXM6XG4gICAgICAtIHJlZGlzX2RhdGE6L2RhdGFcbiAgICAjIEJhY2tzIHNlc3Npb24gdHJhY2tpbmcgYW5kIHRoZSBCdWxsTVEgcXVldWVzLiBub2V2aWN0aW9uIGlzIHJlcXVpcmVkIGJ5XG4gICAgIyBCdWxsTVEgKGV2aWN0aW5nIGpvYiBrZXlzIGNvcnJ1cHRzIHF1ZXVlcyk7IEFPRiAoZXZlcnlzZWMpIGtlZXBzIHF1ZXVlc1xuICAgICMgZHVyYWJsZSBhY3Jvc3MgcmVzdGFydHMuXG4gICAgY29tbWFuZDpcbiAgICAgIC0gcmVkaXMtc2VydmVyXG4gICAgICAtIC0tcmVxdWlyZXBhc3NcbiAgICAgIC0gJHtSRURJU19QQVNTV09SRH1cbiAgICAgIC0gLS1hcHBlbmRvbmx5XG4gICAgICAtIFwieWVzXCJcbiAgICAgIC0gLS1hcHBlbmRmc3luY1xuICAgICAgLSBldmVyeXNlY1xuICAgICAgLSAtLW1heG1lbW9yeS1wb2xpY3lcbiAgICAgIC0gbm9ldmljdGlvblxuICAgIGhlYWx0aGNoZWNrOlxuICAgICAgdGVzdDpcbiAgICAgICAgW1xuICAgICAgICAgIFwiQ01EXCIsXG4gICAgICAgICAgXCJyZWRpcy1jbGlcIixcbiAgICAgICAgICBcIi1hXCIsXG4gICAgICAgICAgXCIke1JFRElTX1BBU1NXT1JEfVwiLFxuICAgICAgICAgIFwiLS1uby1hdXRoLXdhcm5pbmdcIixcbiAgICAgICAgICBcInBpbmdcIixcbiAgICAgICAgXVxuICAgICAgaW50ZXJ2YWw6IDMwc1xuICAgICAgdGltZW91dDogMTBzXG4gICAgICByZXRyaWVzOiAzXG4gICAgICBzdGFydF9wZXJpb2Q6IDVzXG4gICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWRcblxuICByeWJiaXRfYmFja2VuZDpcbiAgICBpbWFnZTogZ2hjci5pby9yeWJiaXQtaW8vcnliYml0LWJhY2tlbmQ6djIuNy4wXG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICAtIE5PREVfRU5WPXByb2R1Y3Rpb25cbiAgICAgIC0gQ0xJQ0tIT1VTRV9IT1NUPWh0dHA6Ly9yeWJiaXRfY2xpY2tob3VzZTo4MTIzXG4gICAgICAtIENMSUNLSE9VU0VfREI9JHtDTElDS0hPVVNFX0RCfVxuICAgICAgLSBDTElDS0hPVVNFX1VTRVI9JHtDTElDS0hPVVNFX1VTRVJ9XG4gICAgICAtIENMSUNLSE9VU0VfUEFTU1dPUkQ9JHtDTElDS0hPVVNFX1BBU1NXT1JEfVxuICAgICAgLSBQT1NUR1JFU19IT1NUPXJ5YmJpdF9wb3N0Z3Jlc1xuICAgICAgLSBQT1NUR1JFU19QT1JUPTU0MzJcbiAgICAgIC0gUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQn1cbiAgICAgIC0gUE9TVEdSRVNfVVNFUj0ke1BPU1RHUkVTX1VTRVJ9XG4gICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSR7UE9TVEdSRVNfUEFTU1dPUkR9XG4gICAgICAtIFJFRElTX0hPU1Q9cnliYml0X3JlZGlzXG4gICAgICAtIFJFRElTX1BPUlQ9NjM3OVxuICAgICAgLSBSRURJU19QQVNTV09SRD0ke1JFRElTX1BBU1NXT1JEfVxuICAgICAgLSBCRVRURVJfQVVUSF9TRUNSRVQ9JHtCRVRURVJfQVVUSF9TRUNSRVR9XG4gICAgICAtIEJBU0VfVVJMPSR7QkFTRV9VUkx9XG4gICAgICAtIERJU0FCTEVfU0lHTlVQPSR7RElTQUJMRV9TSUdOVVB9XG4gICAgICAtIERJU0FCTEVfVEVMRU1FVFJZPSR7RElTQUJMRV9URUxFTUVUUll9XG4gICAgZGVwZW5kc19vbjpcbiAgICAgIHJ5YmJpdF9jbGlja2hvdXNlOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeVxuICAgICAgcnliYml0X3Bvc3RncmVzOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2Vfc3RhcnRlZFxuICAgICAgcnliYml0X3JlZGlzOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeVxuICAgIGhlYWx0aGNoZWNrOlxuICAgICAgdGVzdDogW1wiQ01EXCIsIFwid2dldFwiLCBcIi0tbm8tdmVyYm9zZVwiLCBcIi0tdHJpZXM9MVwiLCBcIi0tc3BpZGVyXCIsIFwiaHR0cDovLzEyNy4wLjAuMTozMDAxL2FwaS9oZWFsdGhcIl1cbiAgICAgIGludGVydmFsOiAzMHNcbiAgICAgIHRpbWVvdXQ6IDEwc1xuICAgICAgcmV0cmllczogM1xuICAgICAgc3RhcnRfcGVyaW9kOiAxMHNcbiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZFxuXG4gIHJ5YmJpdF9jbGllbnQ6XG4gICAgaW1hZ2U6IGdoY3IuaW8vcnliYml0LWlvL3J5YmJpdC1jbGllbnQ6djIuNy4wXG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICAtIE5PREVfRU5WPXByb2R1Y3Rpb25cbiAgICAgIC0gTkVYVF9QVUJMSUNfQkFDS0VORF9VUkw9JHtCQVNFX1VSTH1cbiAgICAgIC0gTkVYVF9QVUJMSUNfRElTQUJMRV9TSUdOVVA9JHtESVNBQkxFX1NJR05VUH1cbiAgICBkZXBlbmRzX29uOlxuICAgICAgLSByeWJiaXRfYmFja2VuZFxuICAgIHJlc3RhcnQ6IHVubGVzcy1zdG9wcGVkXG5cbnZvbHVtZXM6XG4gIGNsaWNraG91c2VfZGF0YTpcbiAgcG9zdGdyZXNfZGF0YTpcbiAgcmVkaXNfZGF0YTpcbiIsCiAgImNvbmZpZyI6ICJbdmFyaWFibGVzXVxubWFpbl9kb21haW4gPSBcIiR7ZG9tYWlufVwiXG5iZXR0ZXJfYXV0aF9zZWNyZXQgPSBcIiR7YmFzZTY0OjMyfVwiXG5jbGlja2hvdXNlX3Bhc3N3b3JkID0gXCIke3Bhc3N3b3JkOjMyfVwiXG5wb3N0Z3Jlc19wYXNzd29yZCA9IFwiJHtwYXNzd29yZDozMn1cIlxucmVkaXNfcGFzc3dvcmQgPSBcIiR7cGFzc3dvcmQ6MzJ9XCJcblxuW1tjb25maWcuZG9tYWluc11dXG5zZXJ2aWNlTmFtZSA9IFwicnliYml0X2JhY2tlbmRcIlxucG9ydCA9IDMwMDFcbmhvc3QgPSBcIiR7bWFpbl9kb21haW59XCJcbnBhdGggPSBcIi9hcGlcIlxuXG5bW2NvbmZpZy5kb21haW5zXV1cbnNlcnZpY2VOYW1lID0gXCJyeWJiaXRfY2xpZW50XCJcbnBvcnQgPSAzMDAyXG5ob3N0ID0gXCIke21haW5fZG9tYWlufVwiXG5cbltjb25maWcuZW52XVxuQkFTRV9VUkwgPSBcImh0dHA6Ly8ke21haW5fZG9tYWlufVwiXG5CRVRURVJfQVVUSF9TRUNSRVQgPSBcIiR7YmV0dGVyX2F1dGhfc2VjcmV0fVwiXG5ESVNBQkxFX1NJR05VUCA9IFwiZmFsc2VcIlxuRElTQUJMRV9URUxFTUVUUlkgPSBcImZhbHNlXCJcbkNMSUNLSE9VU0VfREIgPSBcImFuYWx5dGljc1wiXG5DTElDS0hPVVNFX1VTRVIgPSBcImRlZmF1bHRcIlxuQ0xJQ0tIT1VTRV9QQVNTV09SRCA9IFwiJHtjbGlja2hvdXNlX3Bhc3N3b3JkfVwiXG5QT1NUR1JFU19EQiA9IFwiYW5hbHl0aWNzXCJcblBPU1RHUkVTX1VTRVIgPSBcImZyb2dcIlxuUE9TVEdSRVNfUEFTU1dPUkQgPSBcIiR7cG9zdGdyZXNfcGFzc3dvcmR9XCJcblJFRElTX1BBU1NXT1JEID0gXCIke3JlZGlzX3Bhc3N3b3JkfVwiXG5cbltbY29uZmlnLm1vdW50c11dXG5maWxlUGF0aCA9IFwiLi9jbGlja2hvdXNlX2NvbmZpZy9lbmFibGVfanNvbi54bWxcIlxuY29udGVudCA9IFwiXCJcIlxuPGNsaWNraG91c2U+XG4gICAgPHNldHRpbmdzPlxuICAgICAgICA8ZW5hYmxlX2pzb25fdHlwZT4xPC9lbmFibGVfanNvbl90eXBlPlxuICAgIDwvc2V0dGluZ3M+XG48L2NsaWNraG91c2U+XG5cIlwiXCJcblxuW1tjb25maWcubW91bnRzXV1cbmZpbGVQYXRoID0gXCIuL2NsaWNraG91c2VfY29uZmlnL2xvZ2dpbmdfcnVsZXMueG1sXCJcbmNvbnRlbnQgPSBcIlwiXCJcbjxjbGlja2hvdXNlPlxuICAgIDxsb2dnZXI+XG4gICAgICAgIDxsZXZlbD53YXJuaW5nPC9sZXZlbD5cbiAgICAgICAgPGNvbnNvbGU+dHJ1ZTwvY29uc29sZT5cbiAgICA8L2xvZ2dlcj5cbiAgICA8cXVlcnlfdGhyZWFkX2xvZyByZW1vdmU9XCJyZW1vdmVcIi8+XG4gICAgPHF1ZXJ5X2xvZyByZW1vdmU9XCJyZW1vdmVcIi8+XG4gICAgPHRleHRfbG9nIHJlbW92ZT1cInJlbW92ZVwiLz5cbiAgICA8dHJhY2VfbG9nIHJlbW92ZT1cInJlbW92ZVwiLz5cbiAgICA8bWV0cmljX2xvZyByZW1vdmU9XCJyZW1vdmVcIi8+XG4gICAgPGFzeW5jaHJvbm91c19tZXRyaWNfbG9nIHJlbW92ZT1cInJlbW92ZVwiLz5cbiAgICA8c2Vzc2lvbl9sb2cgcmVtb3ZlPVwicmVtb3ZlXCIvPlxuICAgIDxwYXJ0X2xvZyByZW1vdmU9XCJyZW1vdmVcIi8+XG4gICAgPGxhdGVuY3lfbG9nIHJlbW92ZT1cInJlbW92ZVwiLz5cbiAgICA8cHJvY2Vzc29yc19wcm9maWxlX2xvZyByZW1vdmU9XCJyZW1vdmVcIi8+XG48L2NsaWNraG91c2U+XG5cIlwiXCJcblxuW1tjb25maWcubW91bnRzXV1cbmZpbGVQYXRoID0gXCIuL2NsaWNraG91c2VfY29uZmlnL25ldHdvcmsueG1sXCJcbmNvbnRlbnQgPSBcIlwiXCJcbjxjbGlja2hvdXNlPlxuICAgIDxsaXN0ZW5faG9zdD4wLjAuMC4wPC9saXN0ZW5faG9zdD5cbjwvY2xpY2tob3VzZT5cblwiXCJcIlxuXG5bW2NvbmZpZy5tb3VudHNdXVxuZmlsZVBhdGggPSBcIi4vY2xpY2tob3VzZV9jb25maWcvdXNlcl9sb2dnaW5nLnhtbFwiXG5jb250ZW50ID0gXCJcIlwiXG48Y2xpY2tob3VzZT5cbiAgICA8cHJvZmlsZXM+XG4gICAgICAgIDxkZWZhdWx0PlxuICAgICAgICAgICAgPGxvZ19xdWVyaWVzPjA8L2xvZ19xdWVyaWVzPlxuICAgICAgICAgICAgPGxvZ19xdWVyeV90aHJlYWRzPjA8L2xvZ19xdWVyeV90aHJlYWRzPlxuICAgICAgICAgICAgPGxvZ19wcm9jZXNzb3JzX3Byb2ZpbGVzPjA8L2xvZ19wcm9jZXNzb3JzX3Byb2ZpbGVzPlxuICAgICAgICA8L2RlZmF1bHQ+XG4gICAgPC9wcm9maWxlcz5cbjwvY2xpY2tob3VzZT5cblwiXCJcIlxuIgp9Links
Tags
analytics
Version: v2.7.0