Dokploy

OpenPanel

An open-source web and product analytics platform that combines the power of Mixpanel with the ease of Plausible and one of the best Google Analytics replacements.

OpenPanel logo

Configuration

x-common: &x-common
  NODE_ENV: production
  SELF_HOSTED: "true"
  API_URL: ${API_URL}
  DASHBOARD_URL: ${DASHBOARD_URL}
  DATABASE_URL: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@op-db:5432/${POSTGRES_DB}?schema=public
  DATABASE_URL_DIRECT: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@op-db:5432/${POSTGRES_DB}?schema=public
  REDIS_URL: redis://default:${REDIS_PASSWORD}@op-kv:6379
  CLICKHOUSE_URL: http://op-ch:8123/openpanel

services:
  op-db:
    image: postgres:14-alpine
    restart: always
    volumes:
      - op-db-data:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}']
      interval: 10s
      timeout: 5s
      retries: 5
    environment:
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}

  op-kv:
    image: redis:7.2.5-alpine
    restart: always
    volumes:
      - op-kv-data:/data
    command: redis-server --requirepass ${REDIS_PASSWORD} --maxmemory-policy noeviction
    healthcheck:
      test: ['CMD', 'redis-cli', '-a', '${REDIS_PASSWORD}', 'ping']
      interval: 10s
      timeout: 5s
      retries: 5

  op-ch:
    image: clickhouse/clickhouse-server:25.10.2.65
    restart: always
    volumes:
      - op-ch-data:/var/lib/clickhouse
      - op-ch-logs:/var/log/clickhouse-server
      - ../files/clickhouse_config:/etc/clickhouse-server/config.d
      - ../files/clickhouse_users:/etc/clickhouse-server/users.d
      - ../files/clickhouse_init:/docker-entrypoint-initdb.d
    environment:
      - CLICKHOUSE_SKIP_USER_SETUP=1
    healthcheck:
      test: ['CMD-SHELL', 'clickhouse-client --query "SELECT 1" -d openpanel']
      interval: 10s
      timeout: 5s
      retries: 5

  op-api:
    image: lindesvard/openpanel-api:2.2.1
    restart: always
    command: >
      sh -c "
        echo 'Waiting for PostgreSQL to be ready...'
        while ! nc -z op-db 5432; do
          sleep 1
        done
        echo 'PostgreSQL is ready'

        echo 'Waiting for ClickHouse to be ready...'
        while ! nc -z op-ch 8123; do
          sleep 1
        done
        echo 'ClickHouse is ready'

        echo 'Running migrations...'

        CI=true pnpm -r run migrate:deploy

        pnpm start
      "
    environment:
      COOKIE_SECRET: ${COOKIE_SECRET}
      ALLOW_REGISTRATION: ${ALLOW_REGISTRATION}
      ALLOW_INVITATION: ${ALLOW_INVITATION}
      EMAIL_SENDER: ${EMAIL_SENDER}
      RESEND_API_KEY: ${RESEND_API_KEY}
      <<: *x-common
    healthcheck:
      test: ['CMD-SHELL', 'curl -f http://localhost:3000/healthcheck || exit 1']
      interval: 10s
      timeout: 5s
      retries: 5
    depends_on:
      op-db:
        condition: service_healthy
      op-ch:
        condition: service_healthy
      op-kv:
        condition: service_healthy

  op-dashboard:
    image: lindesvard/openpanel-dashboard:2.2.1
    restart: always
    depends_on:
      op-api:
        condition: service_healthy
    environment:
      <<: *x-common
    healthcheck:
      test: ['CMD-SHELL', 'curl -f http://localhost:3000/api/healthcheck || exit 1']
      interval: 10s
      timeout: 5s
      retries: 5

  op-worker:
    image: lindesvard/openpanel-worker:2.2.1
    restart: always
    depends_on:
      op-api:
        condition: service_healthy
    environment:
      <<: *x-common
    healthcheck:
      test: ['CMD-SHELL', 'curl -f http://localhost:3000/healthcheck || exit 1']
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  op-db-data:
  op-kv-data:
  op-ch-data:
  op-ch-logs:
[variables]
main_domain = "${domain}"
db_password = "${password:32}"
cookie_secret = "${base64:32}"
redis_password = "${password:32}"

[config]
# ClickHouse config files - mounted as directories
[[config.mounts]]
filePath = "./clickhouse_config/op-config.xml"
content = """
<clickhouse>
    <logger>
        <level>warning</level>
        <console>true</console>
    </logger>
    <keep_alive_timeout>10</keep_alive_timeout>
    <!-- Stop all the unnecessary logging -->
    <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"/>
    <listen_host>0.0.0.0</listen_host>
    <interserver_listen_host>0.0.0.0</interserver_listen_host>
    <interserver_http_host>op-ch</interserver_http_host>
    <!-- Disable cgroup memory observer -->
    <cgroups_memory_usage_observer_wait_time>0</cgroups_memory_usage_observer_wait_time>
    <!-- Not used anymore, but kept for backwards compatibility -->
    <macros>
        <shard>1</shard>
        <replica>replica1</replica>
        <cluster>openpanel_cluster</cluster>
    </macros>
</clickhouse>
"""

[[config.mounts]]
filePath = "./clickhouse_users/op-user-config.xml"
content = """
<clickhouse>
    <profiles>
        <default>
            <log_queries>0</log_queries>
            <log_query_threads>0</log_query_threads>
        </default>
    </profiles>
</clickhouse>
"""

[[config.mounts]]
filePath = "./clickhouse_init/1_init-db.sql"
content = """
CREATE DATABASE IF NOT EXISTS openpanel;
"""

[[config.domains]]
serviceName = "op-dashboard"
port = 3000
host = "${main_domain}"

[[config.domains]]
serviceName = "op-api"
port = 3000
host = "${main_domain}"
path = "/api"
stripPath = true

[config.env]
DASHBOARD_URL = "http://${main_domain}"
API_URL = "http://${main_domain}/api"

# Database configuration
POSTGRES_DB = "openpanel"
POSTGRES_USER = "openpanel"
POSTGRES_PASSWORD = "${db_password}"
REDIS_PASSWORD = "${redis_password}"

# Security
COOKIE_SECRET = "${cookie_secret}"

# Registration settings
ALLOW_REGISTRATION = "true"
ALLOW_INVITATION = "true"

# Email configuration (optional - configure for email notifications)
EMAIL_SENDER = ""
RESEND_API_KEY = ""

Base64

To import this template in Dokploy: create a Compose service → AdvancedBase64 import and paste the content below:

ewogICJjb21wb3NlIjogIngtY29tbW9uOiAmeC1jb21tb25cbiAgTk9ERV9FTlY6IHByb2R1Y3Rpb25cbiAgU0VMRl9IT1NURUQ6IFwidHJ1ZVwiXG4gIEFQSV9VUkw6ICR7QVBJX1VSTH1cbiAgREFTSEJPQVJEX1VSTDogJHtEQVNIQk9BUkRfVVJMfVxuICBEQVRBQkFTRV9VUkw6IHBvc3RncmVzOi8vJHtQT1NUR1JFU19VU0VSfToke1BPU1RHUkVTX1BBU1NXT1JEfUBvcC1kYjo1NDMyLyR7UE9TVEdSRVNfREJ9P3NjaGVtYT1wdWJsaWNcbiAgREFUQUJBU0VfVVJMX0RJUkVDVDogcG9zdGdyZXM6Ly8ke1BPU1RHUkVTX1VTRVJ9OiR7UE9TVEdSRVNfUEFTU1dPUkR9QG9wLWRiOjU0MzIvJHtQT1NUR1JFU19EQn0/c2NoZW1hPXB1YmxpY1xuICBSRURJU19VUkw6IHJlZGlzOi8vZGVmYXVsdDoke1JFRElTX1BBU1NXT1JEfUBvcC1rdjo2Mzc5XG4gIENMSUNLSE9VU0VfVVJMOiBodHRwOi8vb3AtY2g6ODEyMy9vcGVucGFuZWxcblxuc2VydmljZXM6XG4gIG9wLWRiOlxuICAgIGltYWdlOiBwb3N0Z3JlczoxNC1hbHBpbmVcbiAgICByZXN0YXJ0OiBhbHdheXNcbiAgICB2b2x1bWVzOlxuICAgICAgLSBvcC1kYi1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YVxuICAgIGhlYWx0aGNoZWNrOlxuICAgICAgdGVzdDogWydDTUQtU0hFTEwnLCAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nXVxuICAgICAgaW50ZXJ2YWw6IDEwc1xuICAgICAgdGltZW91dDogNXNcbiAgICAgIHJldHJpZXM6IDVcbiAgICBlbnZpcm9ubWVudDpcbiAgICAgIC0gUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQn1cbiAgICAgIC0gUE9TVEdSRVNfVVNFUj0ke1BPU1RHUkVTX1VTRVJ9XG4gICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSR7UE9TVEdSRVNfUEFTU1dPUkR9XG5cbiAgb3Ata3Y6XG4gICAgaW1hZ2U6IHJlZGlzOjcuMi41LWFscGluZVxuICAgIHJlc3RhcnQ6IGFsd2F5c1xuICAgIHZvbHVtZXM6XG4gICAgICAtIG9wLWt2LWRhdGE6L2RhdGFcbiAgICBjb21tYW5kOiByZWRpcy1zZXJ2ZXIgLS1yZXF1aXJlcGFzcyAke1JFRElTX1BBU1NXT1JEfSAtLW1heG1lbW9yeS1wb2xpY3kgbm9ldmljdGlvblxuICAgIGhlYWx0aGNoZWNrOlxuICAgICAgdGVzdDogWydDTUQnLCAncmVkaXMtY2xpJywgJy1hJywgJyR7UkVESVNfUEFTU1dPUkR9JywgJ3BpbmcnXVxuICAgICAgaW50ZXJ2YWw6IDEwc1xuICAgICAgdGltZW91dDogNXNcbiAgICAgIHJldHJpZXM6IDVcblxuICBvcC1jaDpcbiAgICBpbWFnZTogY2xpY2tob3VzZS9jbGlja2hvdXNlLXNlcnZlcjoyNS4xMC4yLjY1XG4gICAgcmVzdGFydDogYWx3YXlzXG4gICAgdm9sdW1lczpcbiAgICAgIC0gb3AtY2gtZGF0YTovdmFyL2xpYi9jbGlja2hvdXNlXG4gICAgICAtIG9wLWNoLWxvZ3M6L3Zhci9sb2cvY2xpY2tob3VzZS1zZXJ2ZXJcbiAgICAgIC0gLi4vZmlsZXMvY2xpY2tob3VzZV9jb25maWc6L2V0Yy9jbGlja2hvdXNlLXNlcnZlci9jb25maWcuZFxuICAgICAgLSAuLi9maWxlcy9jbGlja2hvdXNlX3VzZXJzOi9ldGMvY2xpY2tob3VzZS1zZXJ2ZXIvdXNlcnMuZFxuICAgICAgLSAuLi9maWxlcy9jbGlja2hvdXNlX2luaXQ6L2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kXG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICAtIENMSUNLSE9VU0VfU0tJUF9VU0VSX1NFVFVQPTFcbiAgICBoZWFsdGhjaGVjazpcbiAgICAgIHRlc3Q6IFsnQ01ELVNIRUxMJywgJ2NsaWNraG91c2UtY2xpZW50IC0tcXVlcnkgXCJTRUxFQ1QgMVwiIC1kIG9wZW5wYW5lbCddXG4gICAgICBpbnRlcnZhbDogMTBzXG4gICAgICB0aW1lb3V0OiA1c1xuICAgICAgcmV0cmllczogNVxuXG4gIG9wLWFwaTpcbiAgICBpbWFnZTogbGluZGVzdmFyZC9vcGVucGFuZWwtYXBpOjIuMi4xXG4gICAgcmVzdGFydDogYWx3YXlzXG4gICAgY29tbWFuZDogPlxuICAgICAgc2ggLWMgXCJcbiAgICAgICAgZWNobyAnV2FpdGluZyBmb3IgUG9zdGdyZVNRTCB0byBiZSByZWFkeS4uLidcbiAgICAgICAgd2hpbGUgISBuYyAteiBvcC1kYiA1NDMyOyBkb1xuICAgICAgICAgIHNsZWVwIDFcbiAgICAgICAgZG9uZVxuICAgICAgICBlY2hvICdQb3N0Z3JlU1FMIGlzIHJlYWR5J1xuXG4gICAgICAgIGVjaG8gJ1dhaXRpbmcgZm9yIENsaWNrSG91c2UgdG8gYmUgcmVhZHkuLi4nXG4gICAgICAgIHdoaWxlICEgbmMgLXogb3AtY2ggODEyMzsgZG9cbiAgICAgICAgICBzbGVlcCAxXG4gICAgICAgIGRvbmVcbiAgICAgICAgZWNobyAnQ2xpY2tIb3VzZSBpcyByZWFkeSdcblxuICAgICAgICBlY2hvICdSdW5uaW5nIG1pZ3JhdGlvbnMuLi4nXG5cbiAgICAgICAgQ0k9dHJ1ZSBwbnBtIC1yIHJ1biBtaWdyYXRlOmRlcGxveVxuXG4gICAgICAgIHBucG0gc3RhcnRcbiAgICAgIFwiXG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICBDT09LSUVfU0VDUkVUOiAke0NPT0tJRV9TRUNSRVR9XG4gICAgICBBTExPV19SRUdJU1RSQVRJT046ICR7QUxMT1dfUkVHSVNUUkFUSU9OfVxuICAgICAgQUxMT1dfSU5WSVRBVElPTjogJHtBTExPV19JTlZJVEFUSU9OfVxuICAgICAgRU1BSUxfU0VOREVSOiAke0VNQUlMX1NFTkRFUn1cbiAgICAgIFJFU0VORF9BUElfS0VZOiAke1JFU0VORF9BUElfS0VZfVxuICAgICAgPDw6ICp4LWNvbW1vblxuICAgIGhlYWx0aGNoZWNrOlxuICAgICAgdGVzdDogWydDTUQtU0hFTEwnLCAnY3VybCAtZiBodHRwOi8vbG9jYWxob3N0OjMwMDAvaGVhbHRoY2hlY2sgfHwgZXhpdCAxJ11cbiAgICAgIGludGVydmFsOiAxMHNcbiAgICAgIHRpbWVvdXQ6IDVzXG4gICAgICByZXRyaWVzOiA1XG4gICAgZGVwZW5kc19vbjpcbiAgICAgIG9wLWRiOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeVxuICAgICAgb3AtY2g6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5XG4gICAgICBvcC1rdjpcbiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHlcblxuICBvcC1kYXNoYm9hcmQ6XG4gICAgaW1hZ2U6IGxpbmRlc3ZhcmQvb3BlbnBhbmVsLWRhc2hib2FyZDoyLjIuMVxuICAgIHJlc3RhcnQ6IGFsd2F5c1xuICAgIGRlcGVuZHNfb246XG4gICAgICBvcC1hcGk6XG4gICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5XG4gICAgZW52aXJvbm1lbnQ6XG4gICAgICA8PDogKngtY29tbW9uXG4gICAgaGVhbHRoY2hlY2s6XG4gICAgICB0ZXN0OiBbJ0NNRC1TSEVMTCcsICdjdXJsIC1mIGh0dHA6Ly9sb2NhbGhvc3Q6MzAwMC9hcGkvaGVhbHRoY2hlY2sgfHwgZXhpdCAxJ11cbiAgICAgIGludGVydmFsOiAxMHNcbiAgICAgIHRpbWVvdXQ6IDVzXG4gICAgICByZXRyaWVzOiA1XG5cbiAgb3Atd29ya2VyOlxuICAgIGltYWdlOiBsaW5kZXN2YXJkL29wZW5wYW5lbC13b3JrZXI6Mi4yLjFcbiAgICByZXN0YXJ0OiBhbHdheXNcbiAgICBkZXBlbmRzX29uOlxuICAgICAgb3AtYXBpOlxuICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeVxuICAgIGVudmlyb25tZW50OlxuICAgICAgPDw6ICp4LWNvbW1vblxuICAgIGhlYWx0aGNoZWNrOlxuICAgICAgdGVzdDogWydDTUQtU0hFTEwnLCAnY3VybCAtZiBodHRwOi8vbG9jYWxob3N0OjMwMDAvaGVhbHRoY2hlY2sgfHwgZXhpdCAxJ11cbiAgICAgIGludGVydmFsOiAxMHNcbiAgICAgIHRpbWVvdXQ6IDVzXG4gICAgICByZXRyaWVzOiA1XG5cbnZvbHVtZXM6XG4gIG9wLWRiLWRhdGE6XG4gIG9wLWt2LWRhdGE6XG4gIG9wLWNoLWRhdGE6XG4gIG9wLWNoLWxvZ3M6XG4iLAogICJjb25maWciOiAiW3ZhcmlhYmxlc11cbm1haW5fZG9tYWluID0gXCIke2RvbWFpbn1cIlxuZGJfcGFzc3dvcmQgPSBcIiR7cGFzc3dvcmQ6MzJ9XCJcbmNvb2tpZV9zZWNyZXQgPSBcIiR7YmFzZTY0OjMyfVwiXG5yZWRpc19wYXNzd29yZCA9IFwiJHtwYXNzd29yZDozMn1cIlxuXG5bY29uZmlnXVxuIyBDbGlja0hvdXNlIGNvbmZpZyBmaWxlcyAtIG1vdW50ZWQgYXMgZGlyZWN0b3JpZXNcbltbY29uZmlnLm1vdW50c11dXG5maWxlUGF0aCA9IFwiLi9jbGlja2hvdXNlX2NvbmZpZy9vcC1jb25maWcueG1sXCJcbmNvbnRlbnQgPSBcIlwiXCJcbjxjbGlja2hvdXNlPlxuICAgIDxsb2dnZXI+XG4gICAgICAgIDxsZXZlbD53YXJuaW5nPC9sZXZlbD5cbiAgICAgICAgPGNvbnNvbGU+dHJ1ZTwvY29uc29sZT5cbiAgICA8L2xvZ2dlcj5cbiAgICA8a2VlcF9hbGl2ZV90aW1lb3V0PjEwPC9rZWVwX2FsaXZlX3RpbWVvdXQ+XG4gICAgPCEtLSBTdG9wIGFsbCB0aGUgdW5uZWNlc3NhcnkgbG9nZ2luZyAtLT5cbiAgICA8cXVlcnlfdGhyZWFkX2xvZyByZW1vdmU9XCJyZW1vdmVcIi8+XG4gICAgPHF1ZXJ5X2xvZyByZW1vdmU9XCJyZW1vdmVcIi8+XG4gICAgPHRleHRfbG9nIHJlbW92ZT1cInJlbW92ZVwiLz5cbiAgICA8dHJhY2VfbG9nIHJlbW92ZT1cInJlbW92ZVwiLz5cbiAgICA8bWV0cmljX2xvZyByZW1vdmU9XCJyZW1vdmVcIi8+XG4gICAgPGFzeW5jaHJvbm91c19tZXRyaWNfbG9nIHJlbW92ZT1cInJlbW92ZVwiLz5cbiAgICA8c2Vzc2lvbl9sb2cgcmVtb3ZlPVwicmVtb3ZlXCIvPlxuICAgIDxwYXJ0X2xvZyByZW1vdmU9XCJyZW1vdmVcIi8+XG4gICAgPGxpc3Rlbl9ob3N0PjAuMC4wLjA8L2xpc3Rlbl9ob3N0PlxuICAgIDxpbnRlcnNlcnZlcl9saXN0ZW5faG9zdD4wLjAuMC4wPC9pbnRlcnNlcnZlcl9saXN0ZW5faG9zdD5cbiAgICA8aW50ZXJzZXJ2ZXJfaHR0cF9ob3N0Pm9wLWNoPC9pbnRlcnNlcnZlcl9odHRwX2hvc3Q+XG4gICAgPCEtLSBEaXNhYmxlIGNncm91cCBtZW1vcnkgb2JzZXJ2ZXIgLS0+XG4gICAgPGNncm91cHNfbWVtb3J5X3VzYWdlX29ic2VydmVyX3dhaXRfdGltZT4wPC9jZ3JvdXBzX21lbW9yeV91c2FnZV9vYnNlcnZlcl93YWl0X3RpbWU+XG4gICAgPCEtLSBOb3QgdXNlZCBhbnltb3JlLCBidXQga2VwdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgLS0+XG4gICAgPG1hY3Jvcz5cbiAgICAgICAgPHNoYXJkPjE8L3NoYXJkPlxuICAgICAgICA8cmVwbGljYT5yZXBsaWNhMTwvcmVwbGljYT5cbiAgICAgICAgPGNsdXN0ZXI+b3BlbnBhbmVsX2NsdXN0ZXI8L2NsdXN0ZXI+XG4gICAgPC9tYWNyb3M+XG48L2NsaWNraG91c2U+XG5cIlwiXCJcblxuW1tjb25maWcubW91bnRzXV1cbmZpbGVQYXRoID0gXCIuL2NsaWNraG91c2VfdXNlcnMvb3AtdXNlci1jb25maWcueG1sXCJcbmNvbnRlbnQgPSBcIlwiXCJcbjxjbGlja2hvdXNlPlxuICAgIDxwcm9maWxlcz5cbiAgICAgICAgPGRlZmF1bHQ+XG4gICAgICAgICAgICA8bG9nX3F1ZXJpZXM+MDwvbG9nX3F1ZXJpZXM+XG4gICAgICAgICAgICA8bG9nX3F1ZXJ5X3RocmVhZHM+MDwvbG9nX3F1ZXJ5X3RocmVhZHM+XG4gICAgICAgIDwvZGVmYXVsdD5cbiAgICA8L3Byb2ZpbGVzPlxuPC9jbGlja2hvdXNlPlxuXCJcIlwiXG5cbltbY29uZmlnLm1vdW50c11dXG5maWxlUGF0aCA9IFwiLi9jbGlja2hvdXNlX2luaXQvMV9pbml0LWRiLnNxbFwiXG5jb250ZW50ID0gXCJcIlwiXG5DUkVBVEUgREFUQUJBU0UgSUYgTk9UIEVYSVNUUyBvcGVucGFuZWw7XG5cIlwiXCJcblxuW1tjb25maWcuZG9tYWluc11dXG5zZXJ2aWNlTmFtZSA9IFwib3AtZGFzaGJvYXJkXCJcbnBvcnQgPSAzMDAwXG5ob3N0ID0gXCIke21haW5fZG9tYWlufVwiXG5cbltbY29uZmlnLmRvbWFpbnNdXVxuc2VydmljZU5hbWUgPSBcIm9wLWFwaVwiXG5wb3J0ID0gMzAwMFxuaG9zdCA9IFwiJHttYWluX2RvbWFpbn1cIlxucGF0aCA9IFwiL2FwaVwiXG5zdHJpcFBhdGggPSB0cnVlXG5cbltjb25maWcuZW52XVxuREFTSEJPQVJEX1VSTCA9IFwiaHR0cDovLyR7bWFpbl9kb21haW59XCJcbkFQSV9VUkwgPSBcImh0dHA6Ly8ke21haW5fZG9tYWlufS9hcGlcIlxuXG4jIERhdGFiYXNlIGNvbmZpZ3VyYXRpb25cblBPU1RHUkVTX0RCID0gXCJvcGVucGFuZWxcIlxuUE9TVEdSRVNfVVNFUiA9IFwib3BlbnBhbmVsXCJcblBPU1RHUkVTX1BBU1NXT1JEID0gXCIke2RiX3Bhc3N3b3JkfVwiXG5SRURJU19QQVNTV09SRCA9IFwiJHtyZWRpc19wYXNzd29yZH1cIlxuXG4jIFNlY3VyaXR5XG5DT09LSUVfU0VDUkVUID0gXCIke2Nvb2tpZV9zZWNyZXR9XCJcblxuIyBSZWdpc3RyYXRpb24gc2V0dGluZ3NcbkFMTE9XX1JFR0lTVFJBVElPTiA9IFwidHJ1ZVwiXG5BTExPV19JTlZJVEFUSU9OID0gXCJ0cnVlXCJcblxuIyBFbWFpbCBjb25maWd1cmF0aW9uIChvcHRpb25hbCAtIGNvbmZpZ3VyZSBmb3IgZW1haWwgbm90aWZpY2F0aW9ucylcbkVNQUlMX1NFTkRFUiA9IFwiXCJcblJFU0VORF9BUElfS0VZID0gXCJcIlxuIgp9

Tags

analytics


Version: 2.2.1

On this page