From 7caf70941381ffe6320875c7c9d147eb08254a37 Mon Sep 17 00:00:00 2001 From: Jere Salonen Date: Tue, 23 Apr 2024 19:59:16 +0200 Subject: [PATCH 001/500] feat: Add EdgeDB edgedb.svg includes EdgeDB logo and add edgedb.yaml the configuration for edgedb and postgres services. Commit includes setting environment variables, volumes, health checks, and ports. --- public/svgs/edgedb.svg | 3 +++ templates/compose/edgedb.yaml | 43 +++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 public/svgs/edgedb.svg create mode 100644 templates/compose/edgedb.yaml diff --git a/public/svgs/edgedb.svg b/public/svgs/edgedb.svg new file mode 100644 index 000000000..a906f7f7e --- /dev/null +++ b/public/svgs/edgedb.svg @@ -0,0 +1,3 @@ + + + diff --git a/templates/compose/edgedb.yaml b/templates/compose/edgedb.yaml new file mode 100644 index 000000000..62c6e8000 --- /dev/null +++ b/templates/compose/edgedb.yaml @@ -0,0 +1,43 @@ +# documentation: https://www.edgedb.com +# slogan: An open-source database designed as a spiritual successor to SQL and the relational paradigm. Powered by the Postgres query engine under the hood. +# tags: db database sql +# logo: svgs/edgedb.svg + +services: + edgedb: + image: edgedb/edgedb + environment: + - EDGEDB_SERVER_ADMIN_UI=${EDGEDB_SERVER_ADMIN_UI:-enabled} + - EDGEDB_SERVER_BACKEND_DSN=postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB + - EDGEDB_SERVER_SECURITY=strict + - EDGEDB_SERVER_PASSWORD=$SERVICE_EDGEDB_SERVER_PASSWORD + - EDGEDB_SERVER_TLS_CERT_MODE=generate_self_signed + # - EDGEDB_SERVER_TLS_CERT_FILE= # Ideally Coolify should generate its own certificates + # - EDGEDB_SERVER_TLS_KEY_FILE= # -- || -- + - POSTGRES_DB=${POSTGRES_DB:-edgedb} + + depends_on: + postgresql: + condition: service_healthy + volumes: + - "./dbschema:/dbschema" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:5656/server/status/alive"] + interval: 5s + timeout: 20s + retries: 10 + ports: + - "5656:5656" + postgresql: + image: postgres:16-alpine + volumes: + - postgresql-data:/var/lib/postgresql/data + environment: + - POSTGRES_USER=$SERVICE_USER_POSTGRES + - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES + - POSTGRES_DB=${POSTGRES_DB:-edgedb} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 \ No newline at end of file From 03d347f082b86a4b8c980186884bc83b415d5c7e Mon Sep 17 00:00:00 2001 From: Jere Salonen Date: Tue, 23 Apr 2024 20:08:08 +0200 Subject: [PATCH 002/500] fix: Add port metadata and Coolify magic to generate the domain --- templates/compose/edgedb.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/compose/edgedb.yaml b/templates/compose/edgedb.yaml index 62c6e8000..a4e127fa5 100644 --- a/templates/compose/edgedb.yaml +++ b/templates/compose/edgedb.yaml @@ -2,11 +2,13 @@ # slogan: An open-source database designed as a spiritual successor to SQL and the relational paradigm. Powered by the Postgres query engine under the hood. # tags: db database sql # logo: svgs/edgedb.svg +# port: 5656 services: edgedb: image: edgedb/edgedb environment: + - SERVICE_FQDN_EDGEDB - EDGEDB_SERVER_ADMIN_UI=${EDGEDB_SERVER_ADMIN_UI:-enabled} - EDGEDB_SERVER_BACKEND_DSN=postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB - EDGEDB_SERVER_SECURITY=strict From 0ac6180479fea22ee9ea740a7c0a540950971df5 Mon Sep 17 00:00:00 2001 From: Luan Estradioto Date: Mon, 3 Jun 2024 17:58:44 -0300 Subject: [PATCH 003/500] feat: add jitsi template --- public/svgs/jitsi.svg | 8 +++ templates/compose/jitsi.env | 8 +++ templates/compose/jitsi.yaml | 120 +++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 public/svgs/jitsi.svg create mode 100644 templates/compose/jitsi.env create mode 100644 templates/compose/jitsi.yaml diff --git a/public/svgs/jitsi.svg b/public/svgs/jitsi.svg new file mode 100644 index 000000000..6257659ee --- /dev/null +++ b/public/svgs/jitsi.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/templates/compose/jitsi.env b/templates/compose/jitsi.env new file mode 100644 index 000000000..46816cb73 --- /dev/null +++ b/templates/compose/jitsi.env @@ -0,0 +1,8 @@ +JITSI_IMAGE_VERSION=unstable +JIBRI_RECORDER_PASSWORD=$SERVICE_PASSWORD_JITSI +JIBRI_XMPP_PASSWORD=$SERVICE_PASSWORD_JITSI +JICOFO_AUTH_PASSWORD=$SERVICE_PASSWORD_JITSI +JIGASI_XMPP_PASSWORD=$SERVICE_PASSWORD_JITSI +JVB_AUTH_PASSWORD=$SERVICE_PASSWORD_JITSI +PUBLIC_URL= +TZ=UTC \ No newline at end of file diff --git a/templates/compose/jitsi.yaml b/templates/compose/jitsi.yaml new file mode 100644 index 000000000..34155701a --- /dev/null +++ b/templates/compose/jitsi.yaml @@ -0,0 +1,120 @@ +# documentation: https://jitsi.github.io/handbook/docs/intro +# slogan: World's easiest way to add meetings to your apps +# env_file: jitsi.env +# logo: svgs/jitsi.svg +# tags: video, conferencing, meetings, communication, open-source + +services: + jitsi-web: + image: "jitsi/web:${JITSI_IMAGE_VERSION}" + container_name: jitsi-web + restart: unless-stopped + ports: + - "8001:80" + - "8443:443" + volumes: + - ~/.jitsi-meet-cfg/web:/config:Z + - ~/.jitsi-meet-cfg/web/crontabs:/var/spool/cron/crontabs:Z + - ~/.jitsi-meet-cfg/transcripts:/usr/share/jitsi-meet/transcripts:Z + environment: + - SERVICE_FQDN_JITSI + - PUBLIC_URL=$SERVICE_FQDN_JITSI + - TZ + networks: + meet.jitsi: + aliases: + - meet.jitsi + depends_on: + - jvb + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost"] + interval: 2s + timeout: 10s + retries: 15 + + prosody: + image: "jitsi/prosody:${JITSI_IMAGE_VERSION}" + expose: + - '5222' + - '5347' + - '5280' + container_name: jitsi-xmpp + restart: unless-stopped + volumes: + - ~/.jitsi-meet-cfg/prosody/config:/config:Z + - ~/.jitsi-meet-cfg/prosody/prosody-plugins-custom:/prosody-plugins-custom:Z + environment: + - JICOFO_AUTH_PASSWORD + - JVB_AUTH_PASSWORD + - PUBLIC_URL=$SERVICE_FQDN_JITSI + - TZ + networks: + meet.jitsi: + aliases: + - xmpp.meet.jitsi + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:5280/http-bind"] + interval: 2s + timeout: 10s + retries: 15 + + jicofo: + image: "jitsi/jicofo:${JITSI_IMAGE_VERSION}" + container_name: jitsi-jicofo + restart: unless-stopped + volumes: + - ~/.jitsi-meet-cfg/jicofo:/config:Z + environment: + - XMPP_SERVER=prosody + - JICOFO_AUTH_PASSWORD + - TZ + - JICOFO_ENABLE_HEALTH_CHECKS=1 + depends_on: + - prosody + networks: + meet.jitsi: + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8888/about/health"] + interval: 2s + timeout: 10s + retries: 15 + + jvb: + image: "jitsi/jvb:${JITSI_IMAGE_VERSION}" + container_name: jitsi-jvb + restart: unless-stopped + expose: + - '10000:10000/udp' + - '8080:8080' + - '10000' + volumes: + - ~/.jitsi-meet-cfg/jvb:/config:Z + environment: + - JVB_ADVERTISE_IPS + - JVB_AUTH_PASSWORD + - PUBLIC_URL=$SERVICE_FQDN_JITSI + - TZ + - XMPP_SERVER=prosody + depends_on: + - prosody + networks: + meet.jitsi: + labels: + - "traefik.enable=true" + - "traefik.udp.routers.my-udp-router.entrypoints=video" + - "traefik.udp.routers.my-udp-router.service=my-udp-service" + - "traefik.udp.services.my-udp-service.loadbalancer.server.port=10000" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/about/health"] + interval: 2s + timeout: 10s + retries: 15 + +networks: + meet.jitsi: + +volumes: + jitsi-web: + jitsi-xmpp: + jitsi-jicofo: + jitsi-jvb: \ No newline at end of file From 53abea63f7a4ec5854ad3e9bdf96a8966bbc7386 Mon Sep 17 00:00:00 2001 From: Matt <63170914+matas0@users.noreply.github.com> Date: Tue, 13 Aug 2024 23:35:46 +0400 Subject: [PATCH 004/500] feat: Dify template --- templates/compose/dify.yaml | 645 ++++++++++++++++++++++++++++++++++++ 1 file changed, 645 insertions(+) create mode 100644 templates/compose/dify.yaml diff --git a/templates/compose/dify.yaml b/templates/compose/dify.yaml new file mode 100644 index 000000000..350f93198 --- /dev/null +++ b/templates/compose/dify.yaml @@ -0,0 +1,645 @@ +# documentation: https://docs.dify.ai +# slogan: Dify is an open-source LLM app development platform. Dify's intuitive interface combines AI workflow, RAG pipeline, agent capabilities, model management, observability features and more, letting you quickly go from prototype to production. +# tags: ai, weaviate, openai, gpt, llm, lmops, dify, redis, postgres, qdrant, RAG, agent +# logo: svgs/dify.png +# port: 80 + + +x-shared-env: &shared-api-worker-env + LOG_LEVEL: ${LOG_LEVEL:-INFO} + DEBUG: ${DEBUG:-false} + FLASK_DEBUG: ${FLASK_DEBUG:-false} + CONSOLE_WEB_URL: ${CONSOLE_WEB_URL:-} + CONSOLE_API_URL: ${CONSOLE_API_URL:-} + SERVICE_API_URL: ${SERVICE_API_URL} + APP_WEB_URL: ${APP_WEB_URL:-} + CHECK_UPDATE_URL: ${CHECK_UPDATE_URL:-https://updates.dify.ai} + OPENAI_API_BASE: ${OPENAI_API_BASE:-https://api.openai.com/v1} + FILES_URL: ${FILES_URL:-} + FILES_ACCESS_TIMEOUT: ${FILES_ACCESS_TIMEOUT:-300} + APP_MAX_ACTIVE_REQUESTS: ${APP_MAX_ACTIVE_REQUESTS:-0} + MIGRATION_ENABLED: ${MIGRATION_ENABLED:-true} + DEPLOY_ENV: ${DEPLOY_ENV:-PRODUCTION} + DIFY_BIND_ADDRESS: ${DIFY_BIND_ADDRESS:-0.0.0.0} + DIFY_PORT: ${DIFY_PORT:-5001} + SERVER_WORKER_AMOUNT: ${SERVER_WORKER_AMOUNT:-} + SERVER_WORKER_CLASS: ${SERVER_WORKER_CLASS:-} + CELERY_WORKER_CLASS: ${CELERY_WORKER_CLASS:-} + GUNICORN_TIMEOUT: ${GUNICORN_TIMEOUT:-360} + CELERY_WORKER_AMOUNT: ${CELERY_WORKER_AMOUNT:-} + CELERY_AUTO_SCALE: ${CELERY_AUTO_SCALE:-false} + CELERY_MAX_WORKERS: ${CELERY_MAX_WORKERS:-} + CELERY_MIN_WORKERS: ${CELERY_MIN_WORKERS:-} + API_TOOL_DEFAULT_CONNECT_TIMEOUT: ${API_TOOL_DEFAULT_CONNECT_TIMEOUT:-10} + API_TOOL_DEFAULT_READ_TIMEOUT: ${API_TOOL_DEFAULT_READ_TIMEOUT:-60} + DB_USERNAME: ${DB_USERNAME:-postgres} + DB_PASSWORD: ${DB_PASSWORD:-difyai123456} + DB_HOST: ${DB_HOST:-db} + DB_PORT: ${DB_PORT:-5432} + DB_DATABASE: ${DB_DATABASE:-dify} + SQLALCHEMY_POOL_SIZE: ${SQLALCHEMY_POOL_SIZE:-30} + SQLALCHEMY_POOL_RECYCLE: ${SQLALCHEMY_POOL_RECYCLE:-3600} + SQLALCHEMY_ECHO: ${SQLALCHEMY_ECHO:-false} + POSTGRES_MAX_CONNECTIONS: ${POSTGRES_MAX_CONNECTIONS:-100} + POSTGRES_SHARED_BUFFERS: ${POSTGRES_SHARED_BUFFERS:-128MB} + POSTGRES_WORK_MEM: ${POSTGRES_WORK_MEM:-4MB} + POSTGRES_MAINTENANCE_WORK_MEM: ${POSTGRES_MAINTENANCE_WORK_MEM:-64MB} + POSTGRES_EFFECTIVE_CACHE_SIZE: ${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB} + REDIS_HOST: ${REDIS_HOST:-redis} + REDIS_PORT: ${REDIS_PORT:-6379} + REDIS_USERNAME: ${REDIS_USERNAME:-} + REDIS_PASSWORD: $SERVICE_PASSWORD_REDIS + REDIS_USE_SSL: ${REDIS_USE_SSL:-false} + REDIS_DB: 0 + CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://:$SERVICE_PASSWORD_REDIS@redis:6379/1} + BROKER_USE_SSL: ${BROKER_USE_SSL:-false} + WEB_API_CORS_ALLOW_ORIGINS: ${WEB_API_CORS_ALLOW_ORIGINS:-*} + CONSOLE_CORS_ALLOW_ORIGINS: ${CONSOLE_CORS_ALLOW_ORIGINS:-*} + STORAGE_TYPE: ${STORAGE_TYPE:-local} + STORAGE_LOCAL_PATH: storage + S3_USE_AWS_MANAGED_IAM: ${S3_USE_AWS_MANAGED_IAM:-false} + S3_ENDPOINT: ${S3_ENDPOINT:-} + S3_BUCKET_NAME: ${S3_BUCKET_NAME:-} + S3_ACCESS_KEY: ${S3_ACCESS_KEY:-} + S3_SECRET_KEY: ${S3_SECRET_KEY:-} + S3_REGION: ${S3_REGION:-us-east-1} + AZURE_BLOB_ACCOUNT_NAME: ${AZURE_BLOB_ACCOUNT_NAME:-} + AZURE_BLOB_ACCOUNT_KEY: ${AZURE_BLOB_ACCOUNT_KEY:-} + AZURE_BLOB_CONTAINER_NAME: ${AZURE_BLOB_CONTAINER_NAME:-} + AZURE_BLOB_ACCOUNT_URL: ${AZURE_BLOB_ACCOUNT_URL:-} + GOOGLE_STORAGE_BUCKET_NAME: ${GOOGLE_STORAGE_BUCKET_NAME:-} + GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64: ${GOOGLE_STORAGE_SERVICE_ACCOUNT_JSON_BASE64:-} + ALIYUN_OSS_BUCKET_NAME: ${ALIYUN_OSS_BUCKET_NAME:-} + ALIYUN_OSS_ACCESS_KEY: ${ALIYUN_OSS_ACCESS_KEY:-} + ALIYUN_OSS_SECRET_KEY: ${ALIYUN_OSS_SECRET_KEY:-} + ALIYUN_OSS_ENDPOINT: ${ALIYUN_OSS_ENDPOINT:-} + ALIYUN_OSS_REGION: ${ALIYUN_OSS_REGION:-} + ALIYUN_OSS_AUTH_VERSION: ${ALIYUN_OSS_AUTH_VERSION:-v4} + TENCENT_COS_BUCKET_NAME: ${TENCENT_COS_BUCKET_NAME:-} + TENCENT_COS_SECRET_KEY: ${TENCENT_COS_SECRET_KEY:-} + TENCENT_COS_SECRET_ID: ${TENCENT_COS_SECRET_ID:-} + TENCENT_COS_REGION: ${TENCENT_COS_REGION:-} + TENCENT_COS_SCHEME: ${TENCENT_COS_SCHEME:-} + OCI_ENDPOINT: ${OCI_ENDPOINT:-} + OCI_BUCKET_NAME: ${OCI_BUCKET_NAME:-} + OCI_ACCESS_KEY: ${OCI_ACCESS_KEY:-} + OCI_SECRET_KEY: ${OCI_SECRET_KEY:-} + OCI_REGION: ${OCI_REGION:-} + VECTOR_STORE: ${VECTOR_STORE:-weaviate} + WEAVIATE_ENDPOINT: ${WEAVIATE_ENDPOINT:-http://weaviate:8080} + WEAVIATE_API_KEY: $SERVICE_PASSWORD_WEAVIATE + RELYT_HOST: ${RELYT_HOST:-db} + RELYT_PORT: ${RELYT_PORT:-5432} + RELYT_USER: $SERVICE_USER_RELYT + RELYT_PASSWORD: $SERVICE_PASSWORD_RELYT + RELYT_DATABASE: ${RELYT_DATABASE:-postgres} + TIDB_VECTOR_HOST: ${TIDB_VECTOR_HOST:-tidb} + TIDB_VECTOR_PORT: ${TIDB_VECTOR_PORT:-4000} + TIDB_VECTOR_USER: $SERVICE_USER_TIDB + TIDB_VECTOR_PASSWORD: $SERVICE_PASSWORD_TIDB + TIDB_VECTOR_DATABASE: ${TIDB_VECTOR_DATABASE:-dify} + # AnalyticDB configuration + ANALYTICDB_KEY_ID: ${ANALYTICDB_KEY_ID:-} + ANALYTICDB_KEY_SECRET: ${ANALYTICDB_KEY_SECRET:-} + ANALYTICDB_REGION_ID: ${ANALYTICDB_REGION_ID:-} + ANALYTICDB_INSTANCE_ID: ${ANALYTICDB_INSTANCE_ID:-} + ANALYTICDB_ACCOUNT: ${ANALYTICDB_ACCOUNT:-} + ANALYTICDB_PASSWORD: ${ANALYTICDB_PASSWORD:-} + ANALYTICDB_NAMESPACE: ${ANALYTICDB_NAMESPACE:-dify} + ANALYTICDB_NAMESPACE_PASSWORD: ${ANALYTICDB_NAMESPACE_PASSWORD:-} + TENCENT_VECTOR_DB_URL: ${TENCENT_VECTOR_DB_URL:-http://127.0.0.1} + TENCENT_VECTOR_DB_API_KEY: ${TENCENT_VECTOR_DB_API_KEY:-dify} + TENCENT_VECTOR_DB_TIMEOUT: ${TENCENT_VECTOR_DB_TIMEOUT:-30} + TENCENT_VECTOR_DB_USERNAME: ${TENCENT_VECTOR_DB_USERNAME:-dify} + TENCENT_VECTOR_DB_DATABASE: ${TENCENT_VECTOR_DB_DATABASE:-dify} + TENCENT_VECTOR_DB_SHARD: ${TENCENT_VECTOR_DB_SHARD:-1} + TENCENT_VECTOR_DB_REPLICAS: ${TENCENT_VECTOR_DB_REPLICAS:-2} + UPLOAD_FILE_SIZE_LIMIT: ${UPLOAD_FILE_SIZE_LIMIT:-15} + UPLOAD_FILE_BATCH_LIMIT: ${UPLOAD_FILE_BATCH_LIMIT:-5} + ETL_TYPE: ${ETL_TYPE:-dify} + MULTIMODAL_SEND_IMAGE_FORMAT: ${MULTIMODAL_SEND_IMAGE_FORMAT:-base64} + UPLOAD_IMAGE_FILE_SIZE_LIMIT: ${UPLOAD_IMAGE_FILE_SIZE_LIMIT:-10} + SENTRY_DSN: ${API_SENTRY_DSN:-} + SENTRY_TRACES_SAMPLE_RATE: ${API_SENTRY_TRACES_SAMPLE_RATE:-1.0} + SENTRY_PROFILES_SAMPLE_RATE: ${API_SENTRY_PROFILES_SAMPLE_RATE:-1.0} + NOTION_INTEGRATION_TYPE: ${NOTION_INTEGRATION_TYPE:-public} + NOTION_CLIENT_SECRET: ${NOTION_CLIENT_SECRET:-} + NOTION_CLIENT_ID: ${NOTION_CLIENT_ID:-} + NOTION_INTERNAL_SECRET: ${NOTION_INTERNAL_SECRET:-} + MAIL_TYPE: ${MAIL_TYPE:-resend} + MAIL_DEFAULT_SEND_FROM: ${MAIL_DEFAULT_SEND_FROM:-} + SMTP_SERVER: ${SMTP_SERVER:-} + SMTP_PORT: ${SMTP_PORT:-465} + SMTP_USERNAME: ${SMTP_USERNAME:-} + SMTP_PASSWORD: ${SMTP_PASSWORD:-} + SMTP_USE_TLS: ${SMTP_USE_TLS:-true} + SMTP_OPPORTUNISTIC_TLS: ${SMTP_OPPORTUNISTIC_TLS:-false} + RESEND_API_KEY: ${RESEND_API_KEY:-your-resend-api-key} + RESEND_API_URL: https://api.resend.com + INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-1000} + INVITE_EXPIRY_HOURS: ${INVITE_EXPIRY_HOURS:-72} + RESET_PASSWORD_TOKEN_EXPIRY_HOURS: ${RESET_PASSWORD_TOKEN_EXPIRY_HOURS:-24} + CODE_EXECUTION_ENDPOINT: ${CODE_EXECUTION_ENDPOINT:-http://sandbox:8194} + CODE_EXECUTION_API_KEY: ${SANDBOX_API_KEY:-dify-sandbox} + CODE_MAX_NUMBER: ${CODE_MAX_NUMBER:-9223372036854775807} + CODE_MIN_NUMBER: ${CODE_MIN_NUMBER:--9223372036854775808} + CODE_MAX_STRING_LENGTH: ${CODE_MAX_STRING_LENGTH:-80000} + TEMPLATE_TRANSFORM_MAX_LENGTH: ${TEMPLATE_TRANSFORM_MAX_LENGTH:-80000} + CODE_MAX_STRING_ARRAY_LENGTH: ${CODE_MAX_STRING_ARRAY_LENGTH:-30} + CODE_MAX_OBJECT_ARRAY_LENGTH: ${CODE_MAX_OBJECT_ARRAY_LENGTH:-30} + CODE_MAX_NUMBER_ARRAY_LENGTH: ${CODE_MAX_NUMBER_ARRAY_LENGTH:-1000} + SSRF_PROXY_HTTP_URL: ${SSRF_PROXY_HTTP_URL:-http://ssrf_proxy:3128} + SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128} + +services: + # API service + api: + image: langgenius/dify-api:0.6.16 + restart: always + environment: + SECRET_KEY: $SERVICE_PASSWORD_64_SECRETKEY + INIT_PASSWORD: $SERVICE_USER_INITPASSWORD + # Use the shared environment variables. + <<: *shared-api-worker-env + # Startup mode, 'api' starts the API server. + MODE: api + depends_on: + - db + - redis + volumes: + # Mount the storage directory to the container, for storing user files. + - './volumes/app/storage:/app/api/storage' + networks: + - ssrf_proxy_network + - default + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:5001/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # worker service + # The Celery worker for processing the queue. + worker: + image: langgenius/dify-api:0.6.16 + restart: always + environment: + # Use the shared environment variables. + <<: *shared-api-worker-env + # Startup mode, 'worker' starts the Celery worker for processing the queue. + MODE: worker + depends_on: + - db + - redis + volumes: + # Mount the storage directory to the container, for storing user files. + - './volumes/app/storage:/app/api/storage' + networks: + - ssrf_proxy_network + - default + healthcheck: + test: ["CMD-SHELL", "celery -A app.celery_app inspect ping -d celery@$HOSTNAME"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # Frontend web application. + web: + image: langgenius/dify-web:0.6.16 + restart: always + environment: + CONSOLE_API_URL: ${CONSOLE_API_URL:-} + APP_API_URL: ${APP_API_URL:-} + SENTRY_DSN: ${WEB_SENTRY_DSN:-} + NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0} + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # The postgres database. + db: + image: postgres:15-alpine + restart: always + environment: + PGUSER: ${PGUSER:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456} + POSTGRES_DB: ${POSTGRES_DB:-dify} + PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata} + command: > + postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}' + -c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}' + -c 'work_mem=${POSTGRES_WORK_MEM:-4MB}' + -c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}' + -c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}' + volumes: + - './volumes/db/data:/var/lib/postgresql/data' + healthcheck: + test: [ "CMD", "pg_isready" ] + interval: 1s + timeout: 3s + retries: 30 + + # The redis cache. + redis: + image: redis:6-alpine + restart: always + volumes: + # Mount the redis data directory to the container. + - './volumes/redis/data:/data' + # Set the redis password when startup redis server. + command: redis-server --requirepass $SERVICE_PASSWORD_REDIS + healthcheck: + test: [ "CMD", "redis-cli", "-a", "$SERVICE_PASSWORD_REDIS", "ping" ] + + # The DifySandbox + sandbox: + image: langgenius/dify-sandbox:0.2.1 + restart: always + environment: + # The DifySandbox configurations + # Make sure you are changing this key for your deployment with a strong key. + # You can generate a strong key using `openssl rand -base64 42`. + API_KEY: ${SANDBOX_API_KEY:-dify-sandbox} + GIN_MODE: ${SANDBOX_GIN_MODE:-release} + WORKER_TIMEOUT: ${SANDBOX_WORKER_TIMEOUT:-15} + ENABLE_NETWORK: ${SANDBOX_ENABLE_NETWORK:-true} + HTTP_PROXY: ${SANDBOX_HTTP_PROXY:-http://ssrf_proxy:3128} + HTTPS_PROXY: ${SANDBOX_HTTPS_PROXY:-http://ssrf_proxy:3128} + SANDBOX_PORT: ${SANDBOX_PORT:-8194} + volumes: + - './volumes/sandbox/dependencies:/dependencies' + networks: + - ssrf_proxy_network + - default + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8194/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # ssrf_proxy server + # for more information, please refer to + # https://docs.dify.ai/learn-more/faq/self-host-faq#id-18.-why-is-ssrf_proxy-needed + ssrf_proxy: + image: ubuntu/squid:latest + restart: always + volumes: + - type: bind + source: ./ssrf_proxy/squid.conf.template + target: /etc/squid/squid.conf.template + read_only: true + content: | + acl localnet src 0.0.0.1-0.255.255.255 # RFC 1122 "this" network (LAN) + acl localnet src 10.0.0.0/8 # RFC 1918 local private network (LAN) + acl localnet src 100.64.0.0/10 # RFC 6598 shared address space (CGN) + acl localnet src 169.254.0.0/16 # RFC 3927 link-local (directly plugged) machines + acl localnet src 172.16.0.0/12 # RFC 1918 local private network (LAN) + acl localnet src 192.168.0.0/16 # RFC 1918 local private network (LAN) + acl localnet src fc00::/7 # RFC 4193 local private network range + acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines + acl SSL_ports port 443 + acl Safe_ports port 80 # http + acl Safe_ports port 21 # ftp + acl Safe_ports port 443 # https + acl Safe_ports port 70 # gopher + acl Safe_ports port 210 # wais + acl Safe_ports port 1025-65535 # unregistered ports + acl Safe_ports port 280 # http-mgmt + acl Safe_ports port 488 # gss-http + acl Safe_ports port 591 # filemaker + acl Safe_ports port 777 # multiling http + acl CONNECT method CONNECT + http_access deny !Safe_ports + http_access deny CONNECT !SSL_ports + http_access allow localhost manager + http_access deny manager + http_access allow localhost + include /etc/squid/conf.d/*.conf + http_access deny all + + ################################## Proxy Server ################################ + http_port 3128 + coredump_dir ${COREDUMP_DIR} + refresh_pattern ^ftp: 1440 20% 10080 + refresh_pattern ^gopher: 1440 0% 1440 + refresh_pattern -i (/cgi-bin/|\?) 0 0% 0 + refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims + refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims + refresh_pattern \/InRelease$ 0 0% 0 refresh-ims + refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims + refresh_pattern . 0 20% 4320 + + + # cache_dir ufs /var/spool/squid 100 16 256 + # upstream proxy, set to your own upstream proxy IP to avoid SSRF attacks + # cache_peer 172.1.1.1 parent 3128 0 no-query no-digest no-netdb-exchange default + + ################################## Reverse Proxy To Sandbox ################################ + http_port 3129 accel vhost + cache_peer ${SANDBOX_HOST} parent ${SANDBOX_PORT} 0 no-query originserver + acl src_all src all + http_access allow src_all + - type: bind + source: ./ssrf_proxy/docker-entrypoint.sh + target: /docker-entrypoint.sh + read_only: true + content: | + #!/bin/bash + + # Modified based on Squid OCI image entrypoint + + # This entrypoint aims to forward the squid logs to stdout to assist users of + # common container related tooling (e.g., kubernetes, docker-compose, etc) to + # access the service logs. + + # Moreover, it invokes the squid binary, leaving all the desired parameters to + # be provided by the "command" passed to the spawned container. If no command + # is provided by the user, the default behavior (as per the CMD statement in + # the Dockerfile) will be to use Ubuntu's default configuration [1] and run + # squid with the "-NYC" options to mimic the behavior of the Ubuntu provided + # systemd unit. + + # [1] The default configuration is changed in the Dockerfile to allow local + # network connections. See the Dockerfile for further information. + + echo "[ENTRYPOINT] re-create snakeoil self-signed certificate removed in the build process" + if [ ! -f /etc/ssl/private/ssl-cert-snakeoil.key ]; then + /usr/sbin/make-ssl-cert generate-default-snakeoil --force-overwrite > /dev/null 2>&1 + fi + + tail -F /var/log/squid/access.log 2>/dev/null & + tail -F /var/log/squid/error.log 2>/dev/null & + tail -F /var/log/squid/store.log 2>/dev/null & + tail -F /var/log/squid/cache.log 2>/dev/null & + + # Replace environment variables in the template and output to the squid.conf + echo "[ENTRYPOINT] replacing environment variables in the template" + awk '{ + while(match($0, /\${[A-Za-z_][A-Za-z_0-9]*}/)) { + var = substr($0, RSTART+2, RLENGTH-3) + val = ENVIRON[var] + $0 = substr($0, 1, RSTART-1) val substr($0, RSTART+RLENGTH) + } + print + }' /etc/squid/squid.conf.template > /etc/squid/squid.conf + + /usr/sbin/squid -Nz + echo "[ENTRYPOINT] starting squid" + /usr/sbin/squid -f /etc/squid/squid.conf -NYC 1 + - ssrf_proxy_var_log_squid:/var/log/squid + - ssrf_proxy_var_spool_squid:/var/spool/squid + entrypoint: ["/bin/sh", "/docker-entrypoint.sh"] + environment: + # pls clearly modify the squid env vars to fit your network environment. + HTTP_PORT: ${SSRF_HTTP_PORT:-3128} + COREDUMP_DIR: ${SSRF_COREDUMP_DIR:-/var/spool/squid} + REVERSE_PROXY_PORT: ${SSRF_REVERSE_PROXY_PORT:-8194} + SANDBOX_HOST: ${SSRF_SANDBOX_HOST:-sandbox} + SANDBOX_PORT: ${SANDBOX_PORT:-8194} + networks: + - ssrf_proxy_network + - default + healthcheck: + test: ["CMD", "squid", "-k", "check"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + # The nginx reverse proxy. + # used for reverse proxying the API service and Web service. + nginx: + image: nginx:latest + restart: always + volumes: + - type: bind + source: ./nginx/nginx.conf.template + target: /etc/nginx/nginx.conf.template + read_only: true + content: | + # Please do not directly edit this file. Instead, modify the .env variables related to NGINX configuration. + + user nginx; + worker_processes ${NGINX_WORKER_PROCESSES}; + + error_log /var/log/nginx/error.log notice; + pid /var/run/nginx.pid; + + + events { + worker_connections 1024; + } + + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout ${NGINX_KEEPALIVE_TIMEOUT}; + + #gzip on; + client_max_body_size ${NGINX_CLIENT_MAX_BODY_SIZE}; + + include /etc/nginx/conf.d/*.conf; + } + - type: bind + source: ./nginx/proxy.conf.template + target: /etc/nginx/proxy.conf.template + read_only: true + content: | + # Please do not directly edit this file. Instead, modify the .env variables related to NGINX configuration. + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + proxy_set_header Connection ""; + proxy_buffering off; + proxy_read_timeout ${NGINX_PROXY_READ_TIMEOUT}; + proxy_send_timeout ${NGINX_PROXY_SEND_TIMEOUT}; + - type: bind + source: ./nginx/https.conf.template + target: /etc/nginx/https.conf.template + read_only: true + content: | + # Please do not directly edit this file. Instead, modify the .env variables related to NGINX configuration. + + listen ${NGINX_SSL_PORT} ssl; + ssl_certificate ${SSL_CERTIFICATE_PATH}; + ssl_certificate_key ${SSL_CERTIFICATE_KEY_PATH}; + ssl_protocols ${NGINX_SSL_PROTOCOLS}; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + - type: bind + source: ./nginx/docker-entrypoint.sh + target: /docker-entrypoint-mount.sh + read_only: true + content: | + #!/bin/bash + + if [ "${NGINX_HTTPS_ENABLED}" = "true" ]; then + # Check if the certificate and key files for the specified domain exist + if [ -n "${CERTBOT_DOMAIN}" ] && \ + [ -f "/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_FILENAME}" ] && \ + [ -f "/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_KEY_FILENAME}" ]; then + SSL_CERTIFICATE_PATH="/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_FILENAME}" + SSL_CERTIFICATE_KEY_PATH="/etc/letsencrypt/live/${CERTBOT_DOMAIN}/${NGINX_SSL_CERT_KEY_FILENAME}" + else + SSL_CERTIFICATE_PATH="/etc/ssl/${NGINX_SSL_CERT_FILENAME}" + SSL_CERTIFICATE_KEY_PATH="/etc/ssl/${NGINX_SSL_CERT_KEY_FILENAME}" + fi + export SSL_CERTIFICATE_PATH + export SSL_CERTIFICATE_KEY_PATH + + # set the HTTPS_CONFIG environment variable to the content of the https.conf.template + HTTPS_CONFIG=$(envsubst < /etc/nginx/https.conf.template) + export HTTPS_CONFIG + # Substitute the HTTPS_CONFIG in the default.conf.template with content from https.conf.template + envsubst '${HTTPS_CONFIG}' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf + fi + + if [ "${NGINX_ENABLE_CERTBOT_CHALLENGE}" = "true" ]; then + ACME_CHALLENGE_LOCATION='location /.well-known/acme-challenge/ { root /var/www/html; }' + else + ACME_CHALLENGE_LOCATION='' + fi + export ACME_CHALLENGE_LOCATION + + env_vars=$(printenv | cut -d= -f1 | sed 's/^/$/g' | paste -sd, -) + + envsubst "$env_vars" < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf + envsubst "$env_vars" < /etc/nginx/proxy.conf.template > /etc/nginx/proxy.conf + + envsubst < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf + + # Start Nginx using the default entrypoint + exec nginx -g 'daemon off;' + - type: bind + source: ./nginx/default.conf.template + target: /etc/nginx/conf.d/default.conf.template + read_only: true + content: | + # Please do not directly edit this file. Instead, modify the .env variables related to NGINX configuration. + + server { + listen ${NGINX_PORT}; + server_name ${NGINX_SERVER_NAME}; + + location /console/api { + proxy_pass http://api:5001; + include proxy.conf; + } + + location /api { + proxy_pass http://api:5001; + include proxy.conf; + } + + location /v1 { + proxy_pass http://api:5001; + include proxy.conf; + } + + location /files { + proxy_pass http://api:5001; + include proxy.conf; + } + + location / { + proxy_pass http://web:3000; + include proxy.conf; + } + + # placeholder for acme challenge location + ${ACME_CHALLENGE_LOCATION} + + # placeholder for https config defined in https.conf.template + ${HTTPS_CONFIG} + } + - './nginx/ssl:/etc/ssl' + - './volumes/certbot/conf/live:/etc/letsencrypt/live' + - './volumes/certbot/conf:/etc/letsencrypt' + - './volumes/certbot/www:/var/www/html' + entrypoint: [ "sh", "-c", "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ] + environment: + NGINX_SERVER_NAME: $SERVICE_FQDN_NGINX + NGINX_HTTPS_ENABLED: ${NGINX_HTTPS_ENABLED:-false} + NGINX_SSL_PORT: ${NGINX_SSL_PORT:-443} + NGINX_PORT: ${NGINX_PORT:-80} + # You're required to add your own SSL certificates/keys to the `./nginx/ssl` directory + # and modify the env vars below in .env if HTTPS_ENABLED is true. + NGINX_SSL_CERT_FILENAME: ${NGINX_SSL_CERT_FILENAME:-dify.crt} + NGINX_SSL_CERT_KEY_FILENAME: ${NGINX_SSL_CERT_KEY_FILENAME:-dify.key} + NGINX_SSL_PROTOCOLS: ${NGINX_SSL_PROTOCOLS:-TLSv1.1 TLSv1.2 TLSv1.3} + NGINX_WORKER_PROCESSES: ${NGINX_WORKER_PROCESSES:-auto} + NGINX_CLIENT_MAX_BODY_SIZE: ${NGINX_CLIENT_MAX_BODY_SIZE:-15M} + NGINX_KEEPALIVE_TIMEOUT: ${NGINX_KEEPALIVE_TIMEOUT:-65} + NGINX_PROXY_READ_TIMEOUT: ${NGINX_PROXY_READ_TIMEOUT:-3600s} + NGINX_PROXY_SEND_TIMEOUT: ${NGINX_PROXY_SEND_TIMEOUT:-3600s} + NGINX_ENABLE_CERTBOT_CHALLENGE: ${NGINX_ENABLE_CERTBOT_CHALLENGE:-false} + CERTBOT_DOMAIN: ${CERTBOT_DOMAIN:-} + depends_on: + - api + - web + healthcheck: + test: ["CMD", "nginx", "-t"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + + + # The Weaviate vector store. + weaviate: + image: semitechnologies/weaviate:1.19.0 + profiles: + - '' + - weaviate + restart: always + volumes: + # Mount the Weaviate data directory to the con tainer. + - ./volumes/weaviate:/var/lib/weaviate + environment: + # The Weaviate configurations + # You can refer to the [Weaviate](https://weaviate.io/developers/weaviate/config-refs/env-vars) documentation for more information. + PERSISTENCE_DATA_PATH: ${WEAVIATE_PERSISTENCE_DATA_PATH:-/var/lib/weaviate} + QUERY_DEFAULTS_LIMIT: ${WEAVIATE_QUERY_DEFAULTS_LIMIT:-25} + AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: ${WEAVIATE_AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED:-false} + DEFAULT_VECTORIZER_MODULE: ${WEAVIATE_DEFAULT_VECTORIZER_MODULE:-none} + CLUSTER_HOSTNAME: ${WEAVIATE_CLUSTER_HOSTNAME:-node1} + AUTHENTICATION_APIKEY_ENABLED: ${WEAVIATE_AUTHENTICATION_APIKEY_ENABLED:-true} + AUTHENTICATION_APIKEY_ALLOWED_KEYS: $SERVICE_PASSWORD_WEAVIATE + AUTHENTICATION_APIKEY_USERS: $SERVICE_USER_WEAVIATE + AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true} + AUTHORIZATION_ADMINLIST_USERS: $SERVICE_USER_WEAVIATE + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/v1/.well-known/live"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + +networks: + # create a network between sandbox, api and ssrf_proxy, and can not access outside. + ssrf_proxy_network: + driver: bridge + internal: true + +volumes: + ssrf_proxy_var_log_squid: + ssrf_proxy_var_spool_squid: From b8cf64dd2a13c580359189f117da15de024cdf87 Mon Sep 17 00:00:00 2001 From: Matt <63170914+OhThatMatt@users.noreply.github.com> Date: Wed, 14 Aug 2024 22:39:10 +0400 Subject: [PATCH 005/500] Dify template improvements --- templates/compose/dify.yaml | 48 ++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/templates/compose/dify.yaml b/templates/compose/dify.yaml index 350f93198..95690b226 100644 --- a/templates/compose/dify.yaml +++ b/templates/compose/dify.yaml @@ -11,7 +11,7 @@ x-shared-env: &shared-api-worker-env FLASK_DEBUG: ${FLASK_DEBUG:-false} CONSOLE_WEB_URL: ${CONSOLE_WEB_URL:-} CONSOLE_API_URL: ${CONSOLE_API_URL:-} - SERVICE_API_URL: ${SERVICE_API_URL} + SERVICE_API_URL: APP_WEB_URL: ${APP_WEB_URL:-} CHECK_UPDATE_URL: ${CHECK_UPDATE_URL:-https://updates.dify.ai} OPENAI_API_BASE: ${OPENAI_API_BASE:-https://api.openai.com/v1} @@ -32,11 +32,11 @@ x-shared-env: &shared-api-worker-env CELERY_MIN_WORKERS: ${CELERY_MIN_WORKERS:-} API_TOOL_DEFAULT_CONNECT_TIMEOUT: ${API_TOOL_DEFAULT_CONNECT_TIMEOUT:-10} API_TOOL_DEFAULT_READ_TIMEOUT: ${API_TOOL_DEFAULT_READ_TIMEOUT:-60} - DB_USERNAME: ${DB_USERNAME:-postgres} - DB_PASSWORD: ${DB_PASSWORD:-difyai123456} + DB_USERNAME: $SERVICE_USER_POSTGRES + DB_PASSWORD: $SERVICE_PASSWORD_POSTGRES DB_HOST: ${DB_HOST:-db} DB_PORT: ${DB_PORT:-5432} - DB_DATABASE: ${DB_DATABASE:-dify} + DB_DATABASE: dify SQLALCHEMY_POOL_SIZE: ${SQLALCHEMY_POOL_SIZE:-30} SQLALCHEMY_POOL_RECYCLE: ${SQLALCHEMY_POOL_RECYCLE:-3600} SQLALCHEMY_ECHO: ${SQLALCHEMY_ECHO:-false} @@ -51,7 +51,7 @@ x-shared-env: &shared-api-worker-env REDIS_PASSWORD: $SERVICE_PASSWORD_REDIS REDIS_USE_SSL: ${REDIS_USE_SSL:-false} REDIS_DB: 0 - CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://:$SERVICE_PASSWORD_REDIS@redis:6379/1} + CELERY_BROKER_URL: redis://:$SERVICE_PASSWORD_REDIS@redis:6379/1 BROKER_USE_SSL: ${BROKER_USE_SSL:-false} WEB_API_CORS_ALLOW_ORIGINS: ${WEB_API_CORS_ALLOW_ORIGINS:-*} CONSOLE_CORS_ALLOW_ORIGINS: ${CONSOLE_CORS_ALLOW_ORIGINS:-*} @@ -154,7 +154,7 @@ x-shared-env: &shared-api-worker-env services: # API service api: - image: langgenius/dify-api:0.6.16 + image: langgenius/dify-api:latest restart: always environment: SECRET_KEY: $SERVICE_PASSWORD_64_SECRETKEY @@ -182,7 +182,7 @@ services: # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:0.6.16 + image: langgenius/dify-api:latest restart: always environment: # Use the shared environment variables. @@ -199,7 +199,7 @@ services: - ssrf_proxy_network - default healthcheck: - test: ["CMD-SHELL", "celery -A app.celery_app inspect ping -d celery@$HOSTNAME"] + test: ["CMD-SHELL", "celery inspect ping"] interval: 30s timeout: 10s retries: 3 @@ -207,7 +207,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:0.6.16 + image: langgenius/dify-web:latest restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} @@ -215,7 +215,7 @@ services: SENTRY_DSN: ${WEB_SENTRY_DSN:-} NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0} healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000"] + test: ["CMD", "wget", "--spider", "-q", "http://web:3000"] interval: 30s timeout: 10s retries: 3 @@ -226,10 +226,10 @@ services: image: postgres:15-alpine restart: always environment: - PGUSER: ${PGUSER:-postgres} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-difyai123456} - POSTGRES_DB: ${POSTGRES_DB:-dify} - PGDATA: ${PGDATA:-/var/lib/postgresql/data/pgdata} + POSTGRES_USER: $SERVICE_USER_POSTGRES + POSTGRES_PASSWORD: $SERVICE_PASSWORD_POSTGRES + POSTGRES_DB: dify + PGDATA: /var/lib/postgresql/data/pgdata command: > postgres -c 'max_connections=${POSTGRES_MAX_CONNECTIONS:-100}' -c 'shared_buffers=${POSTGRES_SHARED_BUFFERS:-128MB}' @@ -239,10 +239,10 @@ services: volumes: - './volumes/db/data:/var/lib/postgresql/data' healthcheck: - test: [ "CMD", "pg_isready" ] - interval: 1s - timeout: 3s - retries: 30 + test: ["CMD", "pg_isready", "-U", "$SERVICE_USER_POSTGRES", "-d", "dify"] + interval: 10s + timeout: 5s + retries: 5 # The redis cache. redis: @@ -252,13 +252,13 @@ services: # Mount the redis data directory to the container. - './volumes/redis/data:/data' # Set the redis password when startup redis server. - command: redis-server --requirepass $SERVICE_PASSWORD_REDIS + command: redis-server --requirepass "$SERVICE_PASSWORD_REDIS" healthcheck: test: [ "CMD", "redis-cli", "-a", "$SERVICE_PASSWORD_REDIS", "ping" ] # The DifySandbox sandbox: - image: langgenius/dify-sandbox:0.2.1 + image: langgenius/dify-sandbox:latest restart: always environment: # The DifySandbox configurations @@ -276,12 +276,6 @@ services: networks: - ssrf_proxy_network - default - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8194/health"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s # ssrf_proxy server # for more information, please refer to @@ -628,7 +622,7 @@ services: AUTHORIZATION_ADMINLIST_ENABLED: ${WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED:-true} AUTHORIZATION_ADMINLIST_USERS: $SERVICE_USER_WEAVIATE healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8080/v1/.well-known/live"] + test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/v1/.well-known/live"] interval: 30s timeout: 10s retries: 3 From 6faf80fd797f0e395598dd2781c63d7f7d754834 Mon Sep 17 00:00:00 2001 From: Matt <63170914+matas0@users.noreply.github.com> Date: Wed, 14 Aug 2024 22:55:11 +0400 Subject: [PATCH 006/500] Added dify logo --- public/svgs/dify.png | Bin 0 -> 7324 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 public/svgs/dify.png diff --git a/public/svgs/dify.png b/public/svgs/dify.png new file mode 100644 index 0000000000000000000000000000000000000000..326acf789cfbacfbe2a749fa99cebabbf998eb7d GIT binary patch literal 7324 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 literal 0 HcmV?d00001 From ae5e720b473f536c43a7faeeb0a876fd1644a24b Mon Sep 17 00:00:00 2001 From: christiankolbow Date: Sat, 17 Aug 2024 16:39:05 +0200 Subject: [PATCH 007/500] feat: add zipline template --- templates/compose/zipline.yaml | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 templates/compose/zipline.yaml diff --git a/templates/compose/zipline.yaml b/templates/compose/zipline.yaml new file mode 100644 index 000000000..0064c69c5 --- /dev/null +++ b/templates/compose/zipline.yaml @@ -0,0 +1,41 @@ +# documentation: https://github.com/diced/zipline +# slogan: A ShareX/file upload server that is easy to use, packed with features, and with an easy setup! +# tags: zipline,file-sharing,upload,sharing +# port: 3000 +services: + zipline: + image: ghcr.io/diced/zipline + restart: unless-stopped + environment: + - SERVICE_FQDN_ZIPLINE_3000 + - CORE_RETURN_HTTPS=false + - CORE_SECRET=${SERVICE_PASSWORD_64_ZIPLINE} + - CORE_DATABASE_URL=postgres://${SERVICE_USER_DATABASE}:${SERVICE_PASSWORD_64_DATABASE}@postgres/${POSTGRESQL_DATABASE:-zipline} + - CORE_LOGGER=true + volumes: + - zipline-uploads:/zipline/uploads + - zipline-public:/zipline/public + depends_on: + postgres: + condition: service_healthy + healthcheck: + test: + ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000/auth/login"] + interval: 5s + timeout: 20s + retries: 10 + postgres: + image: postgres:16-alpine + volumes: + - postgresql-data:/var/lib/postgresql/data + environment: + - POSTGRES_USER=${SERVICE_USER_DATABASE} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_64_DATABASE} + - POSTGRES_DB=${POSTGRESQL_DATABASE:-zipline} + healthcheck: + test: + - CMD-SHELL + - pg_isready -U $${SERVICE_USER_DATABASE} -d $${POSTGRESQL_DATABASE} + interval: 5s + timeout: 20s + retries: 10 From e77e807cdd830b71e0d6885b417c0ab14ef7de0f Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 15:54:16 +0200 Subject: [PATCH 008/500] Add UI --- .../project/database/redis/general.blade.php | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/resources/views/livewire/project/database/redis/general.blade.php b/resources/views/livewire/project/database/redis/general.blade.php index ceb12a802..35ee90583 100644 --- a/resources/views/livewire/project/database/redis/general.blade.php +++ b/resources/views/livewire/project/database/redis/general.blade.php @@ -9,48 +9,41 @@
- + +
+
+ +

Network

- +
- + @if ($db_url_public) - + @endif

Proxy

- + Proxy Logs - + - Proxy Logs + Proxy Logs
- +

Advanced

- +
+ From a2ba67ea34f33cad2bfeacf928ead01fa9a90baf Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:19:36 +0200 Subject: [PATCH 009/500] Add redis username --- app/Actions/Database/StartRedis.php | 16 +++++++++++- .../Project/Database/Redis/General.php | 25 ++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php index f10afef5e..b3f240942 100644 --- a/app/Actions/Database/StartRedis.php +++ b/app/Actions/Database/StartRedis.php @@ -166,6 +166,14 @@ class StartRedis $environment_variables->push("$env->key=$env->real_value"); } + $redis_version = $this->get_redis_version(); + + if (version_compare($redis_version, '6.0', '>=')) { + if ($environment_variables->filter(fn ($env) => str($env)->contains('REDIS_USERNAME'))->isEmpty()) { + $environment_variables->push("REDIS_USERNAME={$this->database->redis_username}"); + } + } + if ($environment_variables->filter(fn ($env) => str($env)->contains('REDIS_PASSWORD'))->isEmpty()) { $environment_variables->push("REDIS_PASSWORD={$this->database->redis_password}"); } @@ -173,6 +181,12 @@ class StartRedis return $environment_variables->all(); } + private function get_redis_version() + { + $image_parts = explode(':', $this->database->image); + return $image_parts[1] ?? '0.0'; + } + private function add_custom_redis() { if (is_null($this->database->redis_conf) || empty($this->database->redis_conf)) { @@ -184,4 +198,4 @@ class StartRedis instant_scp($path, "{$this->configuration_dir}/{$filename}", $this->database->destination->server); Storage::disk('local')->delete("tmp/redis.conf_{$this->database->uuid}"); } -} +} \ No newline at end of file diff --git a/app/Livewire/Project/Database/Redis/General.php b/app/Livewire/Project/Database/Redis/General.php index a7ce0161a..6acd1095f 100644 --- a/app/Livewire/Project/Database/Redis/General.php +++ b/app/Livewire/Project/Database/Redis/General.php @@ -25,6 +25,7 @@ class General extends Component 'database.name' => 'required', 'database.description' => 'nullable', 'database.redis_conf' => 'nullable', + 'database.redis_username' => 'required', 'database.redis_password' => 'required', 'database.image' => 'required', 'database.ports_mappings' => 'nullable', @@ -37,6 +38,7 @@ class General extends Component 'database.name' => 'Name', 'database.description' => 'Description', 'database.redis_conf' => 'Redis Configuration', + 'database.redis_username' => 'Redis Username', 'database.redis_password' => 'Redis Password', 'database.image' => 'Image', 'database.ports_mappings' => 'Port Mapping', @@ -73,16 +75,33 @@ class General extends Component { try { $this->validate(); - if ($this->database->redis_conf === '') { - $this->database->redis_conf = null; + + $redis_version = $this->get_redis_version(); + + if (version_compare($redis_version, '6.0', '>=')) { + if ($this->database->isDirty('redis_username')) { + $this->database->redis_username = $this->database->redis_username; + } } + + if ($this->database->isDirty('redis_password')) { + $this->database->redis_password = $this->database->redis_password; + } + $this->database->save(); + $this->dispatch('success', 'Database updated.'); } catch (Exception $e) { return handleError($e, $this); } } + private function get_redis_version() + { + $image_parts = explode(':', $this->database->image); + return $image_parts[1] ?? '0.0'; + } + public function instantSave() { try { @@ -123,4 +142,4 @@ class General extends Component { return view('livewire.project.database.redis.general'); } -} +} \ No newline at end of file From 388f8c4e9533bdaa5f21398bde0119dded3095e5 Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:20:03 +0200 Subject: [PATCH 010/500] Security fix redis password and username logic --- app/Models/StandaloneRedis.php | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index 8a202ea9e..b08825bd4 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -16,6 +16,14 @@ class StandaloneRedis extends BaseModel protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status']; + protected $casts = [ + 'redis_password' => 'encrypted', + ]; + + protected $attributes = [ + 'redis_username' => 'redis', + ]; + protected static function booted() { static::created(function ($database) { @@ -205,7 +213,11 @@ class StandaloneRedis extends BaseModel protected function internalDbUrl(): Attribute { return new Attribute( - get: fn () => "redis://:{$this->redis_password}@{$this->uuid}:6379/0", + get: function () { + $redis_version = $this->get_redis_version(); + $username_part = version_compare($redis_version, '6.0', '>=') ? "{$this->redis_username}:" : ""; + return "redis://{$username_part}{$this->redis_password}@{$this->uuid}:6379/0"; + } ); } @@ -214,14 +226,21 @@ class StandaloneRedis extends BaseModel return new Attribute( get: function () { if ($this->is_public && $this->public_port) { - return "redis://:{$this->redis_password}@{$this->destination->server->getIp}:{$this->public_port}/0"; + $redis_version = $this->get_redis_version(); + $username_part = version_compare($redis_version, '6.0', '>=') ? "{$this->redis_username}:" : ""; + return "redis://{$username_part}{$this->redis_password}@{$this->destination->server->getIp}:{$this->public_port}/0"; } - return null; } ); } + private function get_redis_version() + { + $image_parts = explode(':', $this->image); + return $image_parts[1] ?? '0.0'; + } + public function environment() { return $this->belongsTo(Environment::class); @@ -285,4 +304,4 @@ class StandaloneRedis extends BaseModel return $parsedCollection->toArray(); } } -} +} \ No newline at end of file From ae7e5487791c08a0f0a40ad5554af81050346876 Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:20:15 +0200 Subject: [PATCH 011/500] DB migration for redis username --- ...dis_username_to_standalone_redis_table.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 database/migrations/2024_08_21_165435_add_redis_username_to_standalone_redis_table.php diff --git a/database/migrations/2024_08_21_165435_add_redis_username_to_standalone_redis_table.php b/database/migrations/2024_08_21_165435_add_redis_username_to_standalone_redis_table.php new file mode 100644 index 000000000..397c6a68f --- /dev/null +++ b/database/migrations/2024_08_21_165435_add_redis_username_to_standalone_redis_table.php @@ -0,0 +1,22 @@ +string('redis_username')->default('redis')->after('description'); + }); + } + + public function down(): void + { + Schema::table('standalone_redis', function (Blueprint $table) { + $table->dropColumn('redis_username'); + }); + } +}; From 68060ef37dbe94c675925ad01b09ed05fbaab5ac Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:20:28 +0200 Subject: [PATCH 012/500] typo in redis seeder --- database/seeders/StandaloneRedisSeeder.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/database/seeders/StandaloneRedisSeeder.php b/database/seeders/StandaloneRedisSeeder.php index e7bf3373e..7c64b17a2 100644 --- a/database/seeders/StandaloneRedisSeeder.php +++ b/database/seeders/StandaloneRedisSeeder.php @@ -11,8 +11,9 @@ class StandaloneRedisSeeder extends Seeder public function run(): void { StandaloneRedis::create([ - 'name' => 'Local PostgreSQL', - 'description' => 'Local PostgreSQL for testing', + 'name' => 'Local Redis', + 'description' => 'Local Redis for testing', + 'redis_username' => 'redis', 'redis_password' => 'redis', 'environment_id' => 1, 'destination_id' => 0, From 462acda233507c19acd541f9b3d6a2893e2a7a8a Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Wed, 21 Aug 2024 19:20:46 +0200 Subject: [PATCH 013/500] Feat: add UI for redis password and username --- .../livewire/project/database/redis/general.blade.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/resources/views/livewire/project/database/redis/general.blade.php b/resources/views/livewire/project/database/redis/general.blade.php index 35ee90583..e062a4bcd 100644 --- a/resources/views/livewire/project/database/redis/general.blade.php +++ b/resources/views/livewire/project/database/redis/general.blade.php @@ -12,8 +12,13 @@
- - + @php + $redis_version = explode(':', $database->image)[1] ?? '0.0'; + @endphp + @if (version_compare($redis_version, '6.0', '>=')) + + @endif +

Network

@@ -46,4 +51,4 @@
- + \ No newline at end of file From 3d7a467abf936f50167cf06445c4b61d008c2ae3 Mon Sep 17 00:00:00 2001 From: ayntk-ai <122374094+ayntk-ai@users.noreply.github.com> Date: Fri, 23 Aug 2024 19:00:18 +0200 Subject: [PATCH 014/500] WIP WIP --- app/Actions/Database/StartRedis.php | 56 +++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php index b3f240942..6d1548357 100644 --- a/app/Actions/Database/StartRedis.php +++ b/app/Actions/Database/StartRedis.php @@ -20,10 +20,42 @@ class StartRedis public function handle(StandaloneRedis $database) { $this->database = $database; + //$this->configuration_dir = database_configuration_dir().'/'.$this->database->uuid; + + //$this->add_custom_redis(); + + // $startCommand = "redis-server"; + // $additionalArgs = []; + + // if (!is_null($this->database->redis_conf) && !empty($this->database->redis_conf)) { + // ray("Using custom Redis configuration"); + // $additionalArgs[] = "{$this->configuration_dir}/redis.conf"; + + // // Check if the custom config contains a requirepass directive + // $configContent = file_get_contents("{$this->configuration_dir}/redis.conf"); + // if (strpos($configContent, 'requirepass') === false) { + // $additionalArgs[] = "--requirepass {$this->database->redis_password}"; + // ray("No requirepass in custom config, adding it as an argument"); + // } else { + // ray("requirepass found in custom config"); + // } + // } else { + // $additionalArgs[] = "--requirepass {$this->database->redis_password}"; + // $additionalArgs[] = "--appendonly yes"; + // ray("No custom config, using default arguments"); + // } + + // if (!empty($additionalArgs)) { + // $startCommand .= " " . implode(" ", $additionalArgs); + // } + + // ray("Final start command: " . $startCommand); $startCommand = "redis-server --requirepass {$this->database->redis_password} --appendonly yes"; + $container_name = $this->database->uuid; + $this->configuration_dir = database_configuration_dir().'/'.$container_name; $this->commands = [ @@ -31,12 +63,14 @@ class StartRedis "mkdir -p $this->configuration_dir", ]; + $persistent_storages = $this->generate_local_persistent_volumes(); $persistent_file_volumes = $this->database->fileStorages()->get(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $environment_variables = $this->generate_environment_variables(); $this->add_custom_redis(); + $docker_compose = [ 'services' => [ $container_name => [ @@ -113,6 +147,7 @@ class StartRedis 'read_only' => true, ]; $docker_compose['services'][$container_name]['command'] = "redis-server /usr/local/etc/redis/redis.conf --requirepass {$this->database->redis_password} --appendonly yes"; + } $docker_compose = Yaml::dump($docker_compose, 10); $docker_compose_base64 = base64_encode($docker_compose); @@ -178,13 +213,20 @@ class StartRedis $environment_variables->push("REDIS_PASSWORD={$this->database->redis_password}"); } - return $environment_variables->all(); - } + ray('Initial environment variables:', $environment_variables->toArray()); - private function get_redis_version() - { - $image_parts = explode(':', $this->database->image); - return $image_parts[1] ?? '0.0'; + // Overwrite with UI-set environment variables + $ui_variables = $this->database->environment_variables()->get();//this is working + ray('UI-set environment variables:', $ui_variables->toArray()); + + foreach ($ui_variables as $ui_variable) { //the overwrite is not working it is set wrong + $environment_variables = $environment_variables->reject(fn ($env) => str($env)->startsWith("{$ui_variable->key}=")); + $environment_variables->push("{$ui_variable->key}={$ui_variable->real_value}"); + } + + ray('Final environment variables:', $environment_variables->toArray()); + + return $environment_variables->all(); } private function add_custom_redis() @@ -194,7 +236,7 @@ class StartRedis } $filename = 'redis.conf'; Storage::disk('local')->put("tmp/redis.conf_{$this->database->uuid}", $this->database->redis_conf); - $path = Storage::path("tmp/redis.conf_{$this->database->uuid}"); + $path = Storage::path("tmp/redis.conf_{$this->database->uuid}"); instant_scp($path, "{$this->configuration_dir}/{$filename}", $this->database->destination->server); Storage::disk('local')->delete("tmp/redis.conf_{$this->database->uuid}"); } From cddd4b59f90dbeee57039e15cbdd1aa0fea57be0 Mon Sep 17 00:00:00 2001 From: ALsJourney <63744576+ALsJourney@users.noreply.github.com> Date: Fri, 6 Sep 2024 14:16:40 +0200 Subject: [PATCH 015/500] Added a basic login test and also added 2 small variables to dev .env file Small test just to see if you wish to continue this way of me writing tests in this shape and form. you can run them locally with php artisan dusk:chrome-driver --detect, run it with ./vendor/laravel/dusk/bin/chromedriver-mac-arm --port=9515 then run tests with php artisan dusk --- .env.development.example | 2 ++ config/testing.php | 6 ++++++ tests/Browser/ExampleTest.php | 20 -------------------- tests/Browser/LoginTest.php | 30 ++++++++++++++++++++++++++++++ tests/DuskTestCase.php | 5 ++++- 5 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 config/testing.php delete mode 100644 tests/Browser/ExampleTest.php create mode 100644 tests/Browser/LoginTest.php diff --git a/.env.development.example b/.env.development.example index f9bcd361a..0f9e4c72e 100644 --- a/.env.development.example +++ b/.env.development.example @@ -13,6 +13,8 @@ TELESCOPE_ENABLED=false # Selenium Driver URL for Dusk DUSK_DRIVER_URL=http://selenium:4444 +DUSK_EMAIL=test@example.com +DUSK_PASSWORD=password # PostgreSQL Database Configuration DB_DATABASE=coolify diff --git a/config/testing.php b/config/testing.php new file mode 100644 index 000000000..41b8eadf0 --- /dev/null +++ b/config/testing.php @@ -0,0 +1,6 @@ + env('DUSK_TEST_EMAIL', 'test@example.com'), + 'dusk_test_password' => env('DUSK_TEST_PASSWORD', 'password'), +]; diff --git a/tests/Browser/ExampleTest.php b/tests/Browser/ExampleTest.php deleted file mode 100644 index 15dc8f5f1..000000000 --- a/tests/Browser/ExampleTest.php +++ /dev/null @@ -1,20 +0,0 @@ -browse(function (Browser $browser) { - $browser->visit('/') - ->assertSee('Laravel'); - }); - } -} diff --git a/tests/Browser/LoginTest.php b/tests/Browser/LoginTest.php new file mode 100644 index 000000000..ffa83d09b --- /dev/null +++ b/tests/Browser/LoginTest.php @@ -0,0 +1,30 @@ +browse(function (Browser $browser) use ($password, $email) { + $browser->visit('/login') + ->type('email', $email) + ->type('password', $password) + ->press('Login') + ->assertPathIs('/'); + }); + } +} diff --git a/tests/DuskTestCase.php b/tests/DuskTestCase.php index 8628871a1..d909d1c21 100644 --- a/tests/DuskTestCase.php +++ b/tests/DuskTestCase.php @@ -67,6 +67,9 @@ abstract class DuskTestCase extends BaseTestCase protected function baseUrl() { - return rtrim(config('app.url'), '/'); + $app_url = config('app.url'); + $port = config('app.port'); + + return $app_url.':'.$port; } } From 38d4e4a035a050e9038a12ea04b016a399568f6d Mon Sep 17 00:00:00 2001 From: ALsJourney <63744576+ALsJourney@users.noreply.github.com> Date: Sun, 8 Sep 2024 21:41:56 +0200 Subject: [PATCH 016/500] Added a HowTo Markdown on how to run tests --- tests/How_To_Use_Dusk.md | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 tests/How_To_Use_Dusk.md diff --git a/tests/How_To_Use_Dusk.md b/tests/How_To_Use_Dusk.md new file mode 100644 index 000000000..fc10bff8c --- /dev/null +++ b/tests/How_To_Use_Dusk.md @@ -0,0 +1,53 @@ +# How to use Laravel Dusk in local development + +## Pre-requisites + +- Google Chrome installed on your machine (for the Chrome driver) +- everything else is already set up in the project + + +## Running Dusk in local development + +In order to use Laravel Dusk in local development, you need to run these commands: + +```bash +docker exec -it coolify php artisan dusk:chrome-driver --detect +``` + +The chrome driver will be installed under `./vendor/laravel/dusk/bin/chromedriver-linux`. + +Then you need to run the chrome-driver by hand. You can find the driver in the following path: +```bash +docker exec -it coolify ./vendor/laravel/dusk/bin/chromedriver-linux --port=9515 +``` + +### Running the tests on Apple Silicon + +If you are using an Apple Silicon machine, you need to install the Chrome driver locally on your machine with the following command: + +```bash +php artisan dusk:chrome-driver --detect +# then run it with the following command +./vendor/laravel/dusk/bin/chromedriver-mac-arm --port=9515 130 ↵ +``` + +### Running the tests + +Finally, you can run the tests with the following command: +```bash +docker exec -it coolify php artisan dusk +``` + +That's it. You should see the tests running in the terminal. +For proof, you can check the screenshot in the `tests/Browser/screenshots` folder. + +``` + + PASS Tests\Browser\LoginTest + ✓ login 3.63s + + Tests: 1 passed (1 assertions) + Duration: 3.79s + + +``` \ No newline at end of file From df134a4f67c7b65c919eb6b105b57924ce12708e Mon Sep 17 00:00:00 2001 From: mufeng Date: Fri, 20 Sep 2024 11:02:20 +0800 Subject: [PATCH 017/500] Add template for HeyForm --- public/svgs/heyform.svg | 5 ++++ templates/compose/heyform.yaml | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 public/svgs/heyform.svg create mode 100644 templates/compose/heyform.yaml diff --git a/public/svgs/heyform.svg b/public/svgs/heyform.svg new file mode 100644 index 000000000..ff29ca654 --- /dev/null +++ b/public/svgs/heyform.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/templates/compose/heyform.yaml b/templates/compose/heyform.yaml new file mode 100644 index 000000000..732eb2544 --- /dev/null +++ b/templates/compose/heyform.yaml @@ -0,0 +1,48 @@ +# documentation: https://docs.heyform.net/open-source/self-hosting +# slogan: Allows anyone to create engaging conversational forms for surveys, questionnaires, quizzes, and polls. No coding skills required. +# tags: form, builder, forms, survey, quiz, open source, self-hosted, docker +# logo: svgs/heyform.svg +# port: 9513 + +networks: + keydb: null + mongo: null + +services: + heyform: + image: 'heyform/community-edition:latest' + restart: always + volumes: + - 'assets:/app/static/upload' + depends_on: + - mongo + - keydb + ports: + - '9513:8000' + environment: + - SERVICE_FQDN_HEYFORM_9513 + - 'APP_HOMEPAGE_URL=${SERVICE_FQDN_HEYFORM_9513}' + - 'SESSION_KEY=${SERVICE_BASE64_64}' + - 'FORM_ENCRYPTION_KEY=${SERVICE_BASE64_64}' + - "MONGO_URI='mongodb://mongo:27017/heyform'" + - REDIS_HOST=keydb + - REDIS_PORT=6379 + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/health"] + interval: 2s + timeout: 10s + retries: 15 + + mongo: + image: 'percona/percona-server-mongodb:4.4' + restart: always + volumes: + - 'mongo:/data/db' + + keydb: + image: 'eqalpha/keydb:latest' + restart: always + command: 'keydb-server --appendonly yes' + volumes: + - 'keydb:/data' + From 1ae145bf13de253107537b3b0018e9b433b95418 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 26 Sep 2024 19:49:33 +0200 Subject: [PATCH 018/500] Revert "typo in redis seeder" This reverts commit 68060ef37dbe94c675925ad01b09ed05fbaab5ac. --- database/seeders/StandaloneRedisSeeder.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/database/seeders/StandaloneRedisSeeder.php b/database/seeders/StandaloneRedisSeeder.php index 7c64b17a2..e7bf3373e 100644 --- a/database/seeders/StandaloneRedisSeeder.php +++ b/database/seeders/StandaloneRedisSeeder.php @@ -11,9 +11,8 @@ class StandaloneRedisSeeder extends Seeder public function run(): void { StandaloneRedis::create([ - 'name' => 'Local Redis', - 'description' => 'Local Redis for testing', - 'redis_username' => 'redis', + 'name' => 'Local PostgreSQL', + 'description' => 'Local PostgreSQL for testing', 'redis_password' => 'redis', 'environment_id' => 1, 'destination_id' => 0, From e5b798964dce9489d0391b7337f850789801e658 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 26 Sep 2024 20:01:35 +0200 Subject: [PATCH 019/500] Update StartRedis.php --- app/Actions/Database/StartRedis.php | 74 ++++------------------------- 1 file changed, 9 insertions(+), 65 deletions(-) diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php index 6d1548357..eeddab924 100644 --- a/app/Actions/Database/StartRedis.php +++ b/app/Actions/Database/StartRedis.php @@ -20,42 +20,10 @@ class StartRedis public function handle(StandaloneRedis $database) { $this->database = $database; - //$this->configuration_dir = database_configuration_dir().'/'.$this->database->uuid; - - //$this->add_custom_redis(); - - // $startCommand = "redis-server"; - // $additionalArgs = []; - - // if (!is_null($this->database->redis_conf) && !empty($this->database->redis_conf)) { - // ray("Using custom Redis configuration"); - // $additionalArgs[] = "{$this->configuration_dir}/redis.conf"; - - // // Check if the custom config contains a requirepass directive - // $configContent = file_get_contents("{$this->configuration_dir}/redis.conf"); - // if (strpos($configContent, 'requirepass') === false) { - // $additionalArgs[] = "--requirepass {$this->database->redis_password}"; - // ray("No requirepass in custom config, adding it as an argument"); - // } else { - // ray("requirepass found in custom config"); - // } - // } else { - // $additionalArgs[] = "--requirepass {$this->database->redis_password}"; - // $additionalArgs[] = "--appendonly yes"; - // ray("No custom config, using default arguments"); - // } - - // if (!empty($additionalArgs)) { - // $startCommand .= " " . implode(" ", $additionalArgs); - // } - - // ray("Final start command: " . $startCommand); $startCommand = "redis-server --requirepass {$this->database->redis_password} --appendonly yes"; - $container_name = $this->database->uuid; - $this->configuration_dir = database_configuration_dir().'/'.$container_name; $this->commands = [ @@ -63,14 +31,12 @@ class StartRedis "mkdir -p $this->configuration_dir", ]; - $persistent_storages = $this->generate_local_persistent_volumes(); $persistent_file_volumes = $this->database->fileStorages()->get(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $environment_variables = $this->generate_environment_variables(); $this->add_custom_redis(); - $docker_compose = [ 'services' => [ $container_name => [ @@ -116,14 +82,7 @@ class StartRedis data_set($docker_compose, "services.{$container_name}.cpuset", $this->database->limits_cpuset); } if ($this->database->destination->server->isLogDrainEnabled() && $this->database->isLogDrainEnabled()) { - $docker_compose['services'][$container_name]['logging'] = [ - 'driver' => 'fluentd', - 'options' => [ - 'fluentd-address' => 'tcp://127.0.0.1:24224', - 'fluentd-async' => 'true', - 'fluentd-sub-second-precision' => 'true', - ], - ]; + $docker_compose['services'][$container_name]['logging'] = generate_fluentd_configuration(); } if (count($this->database->ports_mappings_array) > 0) { $docker_compose['services'][$container_name]['ports'] = $this->database->ports_mappings_array; @@ -147,8 +106,12 @@ class StartRedis 'read_only' => true, ]; $docker_compose['services'][$container_name]['command'] = "redis-server /usr/local/etc/redis/redis.conf --requirepass {$this->database->redis_password} --appendonly yes"; - } + + // Add custom docker run options + $docker_run_options = convert_docker_run_to_compose($this->database->custom_docker_run_options); + $docker_compose = generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network); + $docker_compose = Yaml::dump($docker_compose, 10); $docker_compose_base64 = base64_encode($docker_compose); $this->commands[] = "echo '{$docker_compose_base64}' | base64 -d | tee $this->configuration_dir/docker-compose.yml > /dev/null"; @@ -201,30 +164,11 @@ class StartRedis $environment_variables->push("$env->key=$env->real_value"); } - $redis_version = $this->get_redis_version(); - - if (version_compare($redis_version, '6.0', '>=')) { - if ($environment_variables->filter(fn ($env) => str($env)->contains('REDIS_USERNAME'))->isEmpty()) { - $environment_variables->push("REDIS_USERNAME={$this->database->redis_username}"); - } - } - if ($environment_variables->filter(fn ($env) => str($env)->contains('REDIS_PASSWORD'))->isEmpty()) { $environment_variables->push("REDIS_PASSWORD={$this->database->redis_password}"); } - ray('Initial environment variables:', $environment_variables->toArray()); - - // Overwrite with UI-set environment variables - $ui_variables = $this->database->environment_variables()->get();//this is working - ray('UI-set environment variables:', $ui_variables->toArray()); - - foreach ($ui_variables as $ui_variable) { //the overwrite is not working it is set wrong - $environment_variables = $environment_variables->reject(fn ($env) => str($env)->startsWith("{$ui_variable->key}=")); - $environment_variables->push("{$ui_variable->key}={$ui_variable->real_value}"); - } - - ray('Final environment variables:', $environment_variables->toArray()); + add_coolify_default_environment_variables($this->database, $environment_variables, $environment_variables); return $environment_variables->all(); } @@ -236,8 +180,8 @@ class StartRedis } $filename = 'redis.conf'; Storage::disk('local')->put("tmp/redis.conf_{$this->database->uuid}", $this->database->redis_conf); - $path = Storage::path("tmp/redis.conf_{$this->database->uuid}"); + $path = Storage::path("tmp/redis.conf_{$this->database->uuid}"); instant_scp($path, "{$this->configuration_dir}/{$filename}", $this->database->destination->server); Storage::disk('local')->delete("tmp/redis.conf_{$this->database->uuid}"); } -} \ No newline at end of file +} From a2bca3d5b82913638831301ab25699a52259d21c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Nov=C3=A1k?= Date: Mon, 30 Sep 2024 00:43:35 +0200 Subject: [PATCH 020/500] added embedded Discord messages logic --- app/Dto/Notification/DiscordMessage.php | 70 +++++++++++++++++++ app/Jobs/SendMessageToDiscordJob.php | 8 +-- app/Notifications/Channels/DiscordChannel.php | 2 +- app/Notifications/Test.php | 13 ++-- 4 files changed, 83 insertions(+), 10 deletions(-) create mode 100644 app/Dto/Notification/DiscordMessage.php diff --git a/app/Dto/Notification/DiscordMessage.php b/app/Dto/Notification/DiscordMessage.php new file mode 100644 index 000000000..88feda7e3 --- /dev/null +++ b/app/Dto/Notification/DiscordMessage.php @@ -0,0 +1,70 @@ +fields[] = [ + 'name' => $name, + 'value' => $value, + ]; + + return $this; + } + + public function toPayload(): array + { + $payload = [ + 'embeds' => [ + [ + 'title' => $this->title, + 'description' => $this->description, + 'color' => $this->color, + 'fields' => $this->addTimestampToFields($this->fields), + ], + ], + ]; + + if ($this->isCritical) { + $payload['content'] = '@here'; + } + + return $payload; + } + + private function addTimestampToFields(array $fields): array + { + $fields[] = [ + 'name' => 'Time', + 'value' => 'timestamp.':R>', + ]; + + return $fields; + } +} diff --git a/app/Jobs/SendMessageToDiscordJob.php b/app/Jobs/SendMessageToDiscordJob.php index f38cf823c..8b238a36d 100644 --- a/app/Jobs/SendMessageToDiscordJob.php +++ b/app/Jobs/SendMessageToDiscordJob.php @@ -2,6 +2,7 @@ namespace App\Jobs; +use App\Dto\Notification\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; @@ -29,7 +30,7 @@ class SendMessageToDiscordJob implements ShouldBeEncrypted, ShouldQueue public int $maxExceptions = 5; public function __construct( - public string $text, + public DiscordMessage $message, public string $webhookUrl ) {} @@ -38,9 +39,6 @@ class SendMessageToDiscordJob implements ShouldBeEncrypted, ShouldQueue */ public function handle(): void { - $payload = [ - 'content' => $this->text, - ]; - Http::post($this->webhookUrl, $payload); + Http::post($this->webhookUrl, $this->message->toPayload()); } } diff --git a/app/Notifications/Channels/DiscordChannel.php b/app/Notifications/Channels/DiscordChannel.php index f1706f138..3a33d8902 100644 --- a/app/Notifications/Channels/DiscordChannel.php +++ b/app/Notifications/Channels/DiscordChannel.php @@ -12,7 +12,7 @@ class DiscordChannel */ public function send(SendsDiscord $notifiable, Notification $notification): void { - $message = $notification->toDiscord($notifiable); + $message = $notification->toDiscord(); $webhookUrl = $notifiable->routeNotificationForDiscord(); if (! $webhookUrl) { return; diff --git a/app/Notifications/Test.php b/app/Notifications/Test.php index 3b46a9a24..f3bb1e3f6 100644 --- a/app/Notifications/Test.php +++ b/app/Notifications/Test.php @@ -2,6 +2,7 @@ namespace App\Notifications; +use App\Dto\Notification\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -29,11 +30,15 @@ class Test extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - $message = 'Coolify: This is a test Discord notification from Coolify.'; - $message .= "\n\n"; - $message .= '[Go to your dashboard]('.base_url().')'; + $message = new DiscordMessage( + title: 'Coolify: This is a test Discord notification from Coolify.', + description: 'This is a test Discord notification from Coolify.', + color: DiscordMessage::successColor(), + ); + + $message->addField('Link', '[Go to your dashboard]('.base_url().')'); return $message; } From 9e2f0fb894dead9bf6da22398cbb4525f942ed35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Nov=C3=A1k?= Date: Mon, 30 Sep 2024 10:06:50 +0200 Subject: [PATCH 021/500] updated namespace for DiscordMessage --- app/Jobs/SendMessageToDiscordJob.php | 2 +- app/{Dto/Notification => Notifications/Dto}/DiscordMessage.php | 2 +- app/Notifications/Test.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename app/{Dto/Notification => Notifications/Dto}/DiscordMessage.php (97%) diff --git a/app/Jobs/SendMessageToDiscordJob.php b/app/Jobs/SendMessageToDiscordJob.php index 8b238a36d..5b406f50f 100644 --- a/app/Jobs/SendMessageToDiscordJob.php +++ b/app/Jobs/SendMessageToDiscordJob.php @@ -2,7 +2,7 @@ namespace App\Jobs; -use App\Dto\Notification\DiscordMessage; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; diff --git a/app/Dto/Notification/DiscordMessage.php b/app/Notifications/Dto/DiscordMessage.php similarity index 97% rename from app/Dto/Notification/DiscordMessage.php rename to app/Notifications/Dto/DiscordMessage.php index 88feda7e3..39c4be718 100644 --- a/app/Dto/Notification/DiscordMessage.php +++ b/app/Notifications/Dto/DiscordMessage.php @@ -1,6 +1,6 @@ Date: Tue, 1 Oct 2024 21:38:12 +0200 Subject: [PATCH 022/500] updated DiscordMessages for Server notifications --- app/Notifications/Server/DockerCleanup.php | 11 +++++++---- app/Notifications/Server/ForceDisabled.php | 11 +++++++++-- app/Notifications/Server/ForceEnabled.php | 11 +++++++---- app/Notifications/Server/HighDiskUsage.php | 13 +++++++++++-- app/Notifications/Server/Revived.php | 11 +++++++---- app/Notifications/Server/Unreachable.php | 11 +++++++++-- 6 files changed, 50 insertions(+), 18 deletions(-) diff --git a/app/Notifications/Server/DockerCleanup.php b/app/Notifications/Server/DockerCleanup.php index 682ed7a1a..68d35b15e 100644 --- a/app/Notifications/Server/DockerCleanup.php +++ b/app/Notifications/Server/DockerCleanup.php @@ -5,6 +5,7 @@ namespace App\Notifications\Server; use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\TelegramChannel; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Notification; @@ -49,11 +50,13 @@ class DockerCleanup extends Notification implements ShouldQueue // return $mail; // } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - $message = "Coolify: Server '{$this->server->name}' cleanup job done!\n\n{$this->message}"; - - return $message; + return new DiscordMessage( + title: "Coolify: Server '{$this->server->name}' cleanup job done!", + description: $this->message, + color: DiscordMessage::successColor(), + ); } public function toTelegram(): array diff --git a/app/Notifications/Server/ForceDisabled.php b/app/Notifications/Server/ForceDisabled.php index 6377f2f15..a02228dc3 100644 --- a/app/Notifications/Server/ForceDisabled.php +++ b/app/Notifications/Server/ForceDisabled.php @@ -6,6 +6,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\TelegramChannel; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -50,9 +51,15 @@ class ForceDisabled extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - $message = "Coolify: Server ({$this->server->name}) disabled because it is not paid!\n All automations and integrations are stopped.\nPlease update your subscription to enable the server again [here](https://app.coolify.io/subscriptions)."; + $message = new DiscordMessage( + title: "Coolify: Server ({$this->server->name}) disabled because it is not paid!", + description: 'All automations and integrations are stopped.', + color: DiscordMessage::errorColor(), + ); + + $message->addField('Link', 'Please update your subscription to enable the server again [here](https://app.coolify.io/subscriptions).'); return $message; } diff --git a/app/Notifications/Server/ForceEnabled.php b/app/Notifications/Server/ForceEnabled.php index 83594d643..c5c3e42b3 100644 --- a/app/Notifications/Server/ForceEnabled.php +++ b/app/Notifications/Server/ForceEnabled.php @@ -6,6 +6,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\TelegramChannel; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -50,11 +51,13 @@ class ForceEnabled extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - $message = "Coolify: Server ({$this->server->name}) enabled again!"; - - return $message; + return new DiscordMessage( + title: "Coolify: Server '{$this->server->name}' enabled again!", + description: 'All automations and integrations are started.', + color: DiscordMessage::successColor(), + ); } public function toTelegram(): array diff --git a/app/Notifications/Server/HighDiskUsage.php b/app/Notifications/Server/HighDiskUsage.php index 34cb22091..c91b8c266 100644 --- a/app/Notifications/Server/HighDiskUsage.php +++ b/app/Notifications/Server/HighDiskUsage.php @@ -6,6 +6,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\TelegramChannel; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -52,9 +53,17 @@ class HighDiskUsage extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - $message = "Coolify: Server '{$this->server->name}' high disk usage detected!\nDisk usage: {$this->disk_usage}%. Threshold: {$this->docker_cleanup_threshold}%.\nPlease cleanup your disk to prevent data-loss.\nHere are some tips: https://coolify.io/docs/knowledge-base/server/automated-cleanup."; + $message = new DiscordMessage( + title: "Coolify: Server '{$this->server->name}' high disk usage detected!", + description: 'Please cleanup your disk to prevent data-loss.', + color: DiscordMessage::errorColor(), + ); + + $message->addField('Disk usage', "{$this->disk_usage}%"); + $message->addField('Threshold', "{$this->docker_cleanup_threshold}%"); + $message->addField('Link', 'Here are some tips: https://coolify.io/docs/knowledge-base/server/automated-cleanup.'); return $message; } diff --git a/app/Notifications/Server/Revived.php b/app/Notifications/Server/Revived.php index 3f2b3b696..c3a3f389a 100644 --- a/app/Notifications/Server/Revived.php +++ b/app/Notifications/Server/Revived.php @@ -8,6 +8,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\TelegramChannel; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -72,11 +73,13 @@ class Revived extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - $message = "Coolify: Server '{$this->server->name}' revived. All automations & integrations are turned on again!"; - - return $message; + return new DiscordMessage( + title: "Coolify: Server '{$this->server->name}' revived.", + description: 'All automations & integrations are turned on again!', + color: DiscordMessage::successColor(), + ); } public function toTelegram(): array diff --git a/app/Notifications/Server/Unreachable.php b/app/Notifications/Server/Unreachable.php index 2fb83559a..7e56123e4 100644 --- a/app/Notifications/Server/Unreachable.php +++ b/app/Notifications/Server/Unreachable.php @@ -6,6 +6,7 @@ use App\Models\Server; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\EmailChannel; use App\Notifications\Channels\TelegramChannel; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -63,9 +64,15 @@ class Unreachable extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - $message = "Coolify: Your server '{$this->server->name}' is unreachable. All automations & integrations are turned off! Please check your server! IMPORTANT: We automatically try to revive your server and turn on all automations & integrations."; + $message = new DiscordMessage( + title: "Coolify: Your server '{$this->server->name}' is unreachable.", + description: 'All automations & integrations are turned off! Please check your server!', + color: DiscordMessage::errorColor(), + ); + + $message->addField('IMPORTANT', 'We automatically try to revive your server and turn on all automations & integrations.'); return $message; } From cb5dc13bf1260594c80b913bc44de449f6bdd9e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Nov=C3=A1k?= Date: Tue, 1 Oct 2024 21:42:13 +0200 Subject: [PATCH 023/500] updated DiscordMessages for Internal&ScheduledTask notifications --- app/Notifications/Dto/DiscordMessage.php | 5 +++++ app/Notifications/Internal/GeneralNotification.php | 9 +++++++-- app/Notifications/ScheduledTask/TaskFailed.php | 13 +++++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app/Notifications/Dto/DiscordMessage.php b/app/Notifications/Dto/DiscordMessage.php index 39c4be718..0d0028f56 100644 --- a/app/Notifications/Dto/DiscordMessage.php +++ b/app/Notifications/Dto/DiscordMessage.php @@ -28,6 +28,11 @@ class DiscordMessage return hexdec('ff705f'); } + public static function infoColor(): int + { + return hexdec('4f545c'); + } + public function addField(string $name, string $value): self { $this->fields[] = [ diff --git a/app/Notifications/Internal/GeneralNotification.php b/app/Notifications/Internal/GeneralNotification.php index 1d4d648c8..48e7d8340 100644 --- a/app/Notifications/Internal/GeneralNotification.php +++ b/app/Notifications/Internal/GeneralNotification.php @@ -4,6 +4,7 @@ namespace App\Notifications\Internal; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\TelegramChannel; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Notification; @@ -32,9 +33,13 @@ class GeneralNotification extends Notification implements ShouldQueue return $channels; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - return $this->message; + return new DiscordMessage( + title: 'Coolify: General Notification', + description: $this->message, + color: DiscordMessage::infoColor(), + ); } public function toTelegram(): array diff --git a/app/Notifications/ScheduledTask/TaskFailed.php b/app/Notifications/ScheduledTask/TaskFailed.php index 479cc1aa1..aac665fb6 100644 --- a/app/Notifications/ScheduledTask/TaskFailed.php +++ b/app/Notifications/ScheduledTask/TaskFailed.php @@ -3,6 +3,7 @@ namespace App\Notifications\ScheduledTask; use App\Models\ScheduledTask; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -46,9 +47,17 @@ class TaskFailed extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - return "Coolify: Scheduled task ({$this->task->name}, [link]({$this->url})) failed with output: {$this->output}"; + $message = new DiscordMessage( + title: "Coolify: Scheduled task ({$this->task->name}) failed.", + description: "Output: {$this->output}", + color: DiscordMessage::errorColor(), + ); + + $message->addField('Link', '[Open task in Coolify]('.$this->url.')'); + + return $message; } public function toTelegram(): array From 53a6e97ca37069347132a65c591d71aac6198bec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Nov=C3=A1k?= Date: Tue, 1 Oct 2024 21:46:56 +0200 Subject: [PATCH 024/500] updated DiscordMessages for Database notifications --- app/Notifications/Database/BackupFailed.php | 15 +++++++++++++-- app/Notifications/Database/BackupSuccess.php | 13 +++++++++++-- app/Notifications/Database/DailyBackup.php | 9 +++++++-- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/app/Notifications/Database/BackupFailed.php b/app/Notifications/Database/BackupFailed.php index 77024c05b..ef6128c5f 100644 --- a/app/Notifications/Database/BackupFailed.php +++ b/app/Notifications/Database/BackupFailed.php @@ -3,6 +3,7 @@ namespace App\Notifications\Database; use App\Models\ScheduledDatabaseBackup; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -45,9 +46,19 @@ class BackupFailed extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - return "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was FAILED.\n\nReason:\n{$this->output}"; + $message = new DiscordMessage( + title: "Coolify: Database backup for {$this->name} (db:{$this->database_name}) has FAILED.", + description: 'Please check the output below for more information.', + color: DiscordMessage::errorColor(), + isCritical: true, + ); + + $message->addField('Frequency', $this->frequency); + $message->addField('Output', $this->output); + + return $message; } public function toTelegram(): array diff --git a/app/Notifications/Database/BackupSuccess.php b/app/Notifications/Database/BackupSuccess.php index f8dc6eb56..fa9eb616c 100644 --- a/app/Notifications/Database/BackupSuccess.php +++ b/app/Notifications/Database/BackupSuccess.php @@ -3,6 +3,7 @@ namespace App\Notifications\Database; use App\Models\ScheduledDatabaseBackup; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -44,9 +45,17 @@ class BackupSuccess extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - return "Coolify: Database backup for {$this->name} (db:{$this->database_name}) with frequency of {$this->frequency} was successful."; + $message = new DiscordMessage( + title: "Coolify: Database backup for {$this->name} (db:{$this->database_name}) was successful.", + description: 'Please check the output below for more information.', + color: DiscordMessage::successColor(), + ); + + $message->addField('Frequency', $this->frequency); + + return $message; } public function toTelegram(): array diff --git a/app/Notifications/Database/DailyBackup.php b/app/Notifications/Database/DailyBackup.php index a51ac6283..b53a56903 100644 --- a/app/Notifications/Database/DailyBackup.php +++ b/app/Notifications/Database/DailyBackup.php @@ -4,6 +4,7 @@ namespace App\Notifications\Database; use App\Notifications\Channels\DiscordChannel; use App\Notifications\Channels\TelegramChannel; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Channels\MailChannel; @@ -34,9 +35,13 @@ class DailyBackup extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - return 'Coolify: Daily backup statuses'; + return new DiscordMessage( + title: 'Coolify: Daily backup statuses', + description: 'Nothing to report.', + color: DiscordMessage::infoColor(), + ); // todo: is this necessary notification? what is the purpose of this notification? } public function toTelegram(): array From aac491da251edb953f112a9ea53b2420be3398e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Nov=C3=A1k?= Date: Tue, 1 Oct 2024 21:48:14 +0200 Subject: [PATCH 025/500] updated DiscordMessages for Container notifications --- app/Notifications/Container/ContainerRestarted.php | 9 +++++++-- app/Notifications/Container/ContainerStopped.php | 11 +++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/Notifications/Container/ContainerRestarted.php b/app/Notifications/Container/ContainerRestarted.php index 23f6de264..49c2cecf0 100644 --- a/app/Notifications/Container/ContainerRestarted.php +++ b/app/Notifications/Container/ContainerRestarted.php @@ -3,6 +3,7 @@ namespace App\Notifications\Container; use App\Models\Server; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -34,9 +35,13 @@ class ContainerRestarted extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - $message = "Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}"; + $message = new DiscordMessage( + title: "Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}", + description: 'Please check the output below for more information.', + color: DiscordMessage::infoColor(), + ); return $message; } diff --git a/app/Notifications/Container/ContainerStopped.php b/app/Notifications/Container/ContainerStopped.php index bcf5e67a5..d8ed2316b 100644 --- a/app/Notifications/Container/ContainerStopped.php +++ b/app/Notifications/Container/ContainerStopped.php @@ -3,6 +3,7 @@ namespace App\Notifications\Container; use App\Models\Server; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -34,11 +35,13 @@ class ContainerStopped extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - $message = "Coolify: A resource ($this->name) has been stopped unexpectedly on {$this->server->name}"; - - return $message; + return new DiscordMessage( + title: "Coolify: A resource ($this->name) has been stopped unexpectedly on {$this->server->name}", + description: 'Please check the output below for more information.', + color: DiscordMessage::errorColor(), + ); } public function toTelegram(): array From 3b4759f349912b2d5c6cf5434fb0f3b7b28cd1cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Nov=C3=A1k?= Date: Tue, 1 Oct 2024 22:07:24 +0200 Subject: [PATCH 026/500] updated DiscordMessages for Application notifications --- .../Application/DeploymentFailed.php | 23 +++++++++++---- .../Application/DeploymentSuccess.php | 29 ++++++++++++------- .../Application/StatusChanged.php | 13 ++++++--- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/app/Notifications/Application/DeploymentFailed.php b/app/Notifications/Application/DeploymentFailed.php index 1809da368..b255cc667 100644 --- a/app/Notifications/Application/DeploymentFailed.php +++ b/app/Notifications/Application/DeploymentFailed.php @@ -4,6 +4,7 @@ namespace App\Notifications\Application; use App\Models\Application; use App\Models\ApplicationPreview; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -72,14 +73,26 @@ class DeploymentFailed extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { if ($this->preview) { - $message = 'Coolify: Pull request #'.$this->preview->pull_request_id.' of '.$this->application_name.' ('.$this->preview->fqdn.') deployment failed: '; - $message .= '[View Deployment Logs]('.$this->deployment_url.')'; + $message = new DiscordMessage( + title: 'Coolify: Deployment failed of pull request #'.$this->preview->pull_request_id.' of '.$this->application_name, + description: 'Check in the link below', + color: DiscordMessage::errorColor(), + isCritical: true, + ); + + $message->addField('Deployment Logs', '[Here]('.$this->deployment_url.')'); } else { - $message = 'Coolify: Deployment failed of '.$this->application_name.' ('.$this->fqdn.'): '; - $message .= '[View Deployment Logs]('.$this->deployment_url.')'; + $message = new DiscordMessage( + title: 'Coolify: Deployment failed of '.$this->application_name, + description: 'Check in the link below', + color: DiscordMessage::errorColor(), + isCritical: true, + ); + + $message->addField('Deployment Logs', '[Here]('.$this->deployment_url.')'); } return $message; diff --git a/app/Notifications/Application/DeploymentSuccess.php b/app/Notifications/Application/DeploymentSuccess.php index 5085065c2..96ec2ce82 100644 --- a/app/Notifications/Application/DeploymentSuccess.php +++ b/app/Notifications/Application/DeploymentSuccess.php @@ -4,6 +4,7 @@ namespace App\Notifications\Application; use App\Models\Application; use App\Models\ApplicationPreview; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -78,24 +79,32 @@ class DeploymentSuccess extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { if ($this->preview) { - $message = 'Coolify: New PR'.$this->preview->pull_request_id.' version successfully deployed of '.$this->application_name.' + $message = new DiscordMessage( + title: "Coolify: New PR{$this->preview->pull_request_id} version successfully deployed of {$this->application_name}", + description: 'Check in the links below.', + color: DiscordMessage::successColor(), + ); -'; if ($this->preview->fqdn) { - $message .= '[Open Application]('.$this->preview->fqdn.') | '; + $message->addField('Open Application', '[Here]('.$this->preview->fqdn.')'); } - $message .= '[Deployment logs]('.$this->deployment_url.')'; - } else { - $message = 'Coolify: New version successfully deployed of '.$this->application_name.' -'; + $message->addField('Deployment logs', '[Here]('.$this->deployment_url.')'); + } else { + $message = new DiscordMessage( + title: "Coolify: New version successfully deployed of {$this->application_name}", + description: 'Check in the links below.', + color: DiscordMessage::successColor(), + ); + if ($this->fqdn) { - $message .= '[Open Application]('.$this->fqdn.') | '; + $message->addField('Open Application', '[Here]('.$this->fqdn.')'); } - $message .= '[Deployment logs]('.$this->deployment_url.')'; + + $message->addField('Deployment logs', '[Here]('.$this->deployment_url.')'); } return $message; diff --git a/app/Notifications/Application/StatusChanged.php b/app/Notifications/Application/StatusChanged.php index 53ed8a589..abc93a3a4 100644 --- a/app/Notifications/Application/StatusChanged.php +++ b/app/Notifications/Application/StatusChanged.php @@ -3,6 +3,7 @@ namespace App\Notifications\Application; use App\Models\Application; +use App\Notifications\Dto\DiscordMessage; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; @@ -55,12 +56,16 @@ class StatusChanged extends Notification implements ShouldQueue return $mail; } - public function toDiscord(): string + public function toDiscord(): DiscordMessage { - $message = 'Coolify: '.$this->resource_name.' has been stopped. + $message = new DiscordMessage( + title: "Coolify: {$this->resource_name} has been stopped", + description: 'Check the application in Coolify', + color: DiscordMessage::errorColor(), + isCritical: true, + ); -'; - $message .= '[Open Application in Coolify]('.$this->resource_url.')'; + $message->addField('Link', '[Open Application in Coolify]('.$this->resource_url.')'); return $message; } From 67b17e871fe75e04a872da0f06c79ecb6df0aa39 Mon Sep 17 00:00:00 2001 From: Eric Dahl Date: Thu, 3 Oct 2024 13:26:27 -0400 Subject: [PATCH 027/500] adding mindsDB --- public/svgs/mindsdb.svg | 12 ++++++++++++ templates/compose/mindsdb.yaml | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 public/svgs/mindsdb.svg create mode 100644 templates/compose/mindsdb.yaml diff --git a/public/svgs/mindsdb.svg b/public/svgs/mindsdb.svg new file mode 100644 index 000000000..53799dd1c --- /dev/null +++ b/public/svgs/mindsdb.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/templates/compose/mindsdb.yaml b/templates/compose/mindsdb.yaml new file mode 100644 index 000000000..44bae7719 --- /dev/null +++ b/templates/compose/mindsdb.yaml @@ -0,0 +1,35 @@ +# documentation: https://docs.mindsdb.com/what-is-mindsdb +# slogan: MindsDB is the platform for building AI from enterprise data, enabling smarter organizations. +# tags: mysql, postgresdb, machine-learning, ai +# logo: svgs/mindsdb.png +# port: 47334 + +services: + mindsdb: + image: mindsdb/mindsdb + restart: always + environment: + - SERVICE_FQDN_MINDSDB_47334 + - MINDSDB_DOCKER_ENV=true + - MINDSDB_STORAGE_DIR=/mindsdb/var + - FLASK_DEBUG=1 # This will make sure http requests are logged regardless of log level + - OPENAI_API_KEY=$OPENAI_API_KEY + - LANGFUSE_HOST=$LANGFUSE_HOST + - LANGFUSE_PUBLIC_KEY=$LANGFUSE_PUBLIC_KEY + - LANGFUSE_SECRET_KEY=$LANGFUSE_SECRET_KEY + - LANGFUSE_RELEASE="local" + # - LANGFUSE_DEBUG="True" + - LANGFUSE_TIMEOUT="10" + - LANGFUSE_SAMPLE_RATE="1.0" + ports: + - 47335:47335 + - 47336:47336 + volumes: + - type: bind + source: . + target: /mindsdb + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:47334/api/util/ping"] + interval: 30s + timeout: 4s + retries: 100 From 8e50a98e1b55c31778fb02eb20415e6d11b273a0 Mon Sep 17 00:00:00 2001 From: Daniel Alves Date: Thu, 3 Oct 2024 16:10:22 -0300 Subject: [PATCH 028/500] feat: add coder service tamplate and logo --- public/svgs/coder.svg | 8 ++++++ templates/compose/coder.yaml | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 public/svgs/coder.svg create mode 100644 templates/compose/coder.yaml diff --git a/public/svgs/coder.svg b/public/svgs/coder.svg new file mode 100644 index 000000000..45b7f795c --- /dev/null +++ b/public/svgs/coder.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/templates/compose/coder.yaml b/templates/compose/coder.yaml new file mode 100644 index 000000000..9d9696f5c --- /dev/null +++ b/templates/compose/coder.yaml @@ -0,0 +1,50 @@ +# documentation: https://coder.com/docs +# slogan: Coder is an open-source platform for creating and managing cloud development environments on your infrastructure, with the tools and IDEs your developers already love. +# tags: coder,development,environment,self-hosted,postgres +# logo: svgs/coder.svg +# port: 7080 + +version: "3.9" +services: + coder: + image: "ghcr.io/coder/coder:${CODER_VERSION:-latest}" + environment: + - "SERVICE_FQDN_CODER=${SERVICE_FQDN_CODER}" + - "CODER_PG_CONNECTION_URL=postgresql://${POSTGRES_USER:-username}:${POSTGRES_PASSWORD:-password}@database/${POSTGRES_DB:-coder}?sslmode=disable" + - "CODER_HTTP_ADDRESS=0.0.0.0:7080" + - "CODER_ACCESS_URL=${SERVICE_FQDN_CODER}" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + ports: + - "7080:7080" + depends_on: + database: + condition: service_healthy + healthcheck: + test: + - CMD + - wget + - "-q" + - "--spider" + - "http://localhost:7080" + interval: 5s + timeout: 20s + retries: 10 + database: + image: "postgres:16.4-alpine" + restart: unless-stopped + environment: + POSTGRES_USER: "${POSTGRES_USER:-username}" + POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:-password}" + POSTGRES_DB: "${POSTGRES_DB:-coder}" + volumes: + - "coder_data:/var/lib/postgresql/data" + healthcheck: + test: + - CMD-SHELL + - "pg_isready -U ${POSTGRES_USER:-username} -d ${POSTGRES_DB:-coder}" + interval: 5s + timeout: 5s + retries: 5 +volumes: + coder_data: null From b4593ec1d225ffe15a471687d35df2fbac678dd3 Mon Sep 17 00:00:00 2001 From: "Alexander G." Date: Fri, 4 Oct 2024 12:42:42 +0300 Subject: [PATCH 029/500] Update trigger.yaml --- templates/compose/trigger.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/trigger.yaml b/templates/compose/trigger.yaml index 6181a6925..2e8e9f9a7 100644 --- a/templates/compose/trigger.yaml +++ b/templates/compose/trigger.yaml @@ -6,7 +6,7 @@ services: trigger: - image: ghcr.io/triggerdotdev/trigger.dev:latest + image: ghcr.io/triggerdotdev/trigger.dev:main environment: - SERVICE_FQDN_TRIGGER_3000 - LOGIN_ORIGIN=$SERVICE_FQDN_TRIGGER From ab8b36266bed9182eaa867eaf41ddc51a3e90056 Mon Sep 17 00:00:00 2001 From: "Alexander G." Date: Fri, 4 Oct 2024 12:44:19 +0300 Subject: [PATCH 030/500] Update trigger-with-external-database.yaml --- templates/compose/trigger-with-external-database.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/trigger-with-external-database.yaml b/templates/compose/trigger-with-external-database.yaml index dcd3e2b97..00702452b 100644 --- a/templates/compose/trigger-with-external-database.yaml +++ b/templates/compose/trigger-with-external-database.yaml @@ -6,7 +6,7 @@ services: trigger: - image: ghcr.io/triggerdotdev/trigger.dev:latest + image: ghcr.io/triggerdotdev/trigger.dev:main environment: - SERVICE_FQDN_TRIGGER_3000 - LOGIN_ORIGIN=$SERVICE_FQDN_TRIGGER From 6f998f11577159cca92b0270d510d9e8479a4ea4 Mon Sep 17 00:00:00 2001 From: Alex Renoki Date: Sat, 5 Oct 2024 06:15:48 +0300 Subject: [PATCH 031/500] Added zep --- public/svgs/zep.png | Bin 0 -> 10841 bytes templates/compose/zep.yaml | 194 +++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 public/svgs/zep.png create mode 100644 templates/compose/zep.yaml diff --git a/public/svgs/zep.png b/public/svgs/zep.png new file mode 100644 index 0000000000000000000000000000000000000000..7d51b32dc078ed968b0483bbee646de5bbf7354f GIT binary patch literal 10841 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 /dev/tcp/127.0.0.1/5557' || exit 1" + interval: 10s + timeout: 5s + retries: 5 + start_period: 45s + zep: + image: ghcr.io/getzep/zep:latest + restart: always + depends_on: + postgres: + condition: service_healthy + nlp: + condition: service_healthy + environment: + - SERVICE_FQDN_ZEP_8000 + - ZEP_STORE_POSTGRES_DSN=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/postgres?sslmode=disable + - ZEP_NLP_SERVER_URL=http://nlp:5557 + - ZEP_EXTRACTORS_DOCUMENTS_EMBEDDINGS_SERVICE=${EXTRACTORS_DOCUMENTS_EMBEDDINGS_SERVICE:-openai} + - ZEP_EXTRACTORS_DOCUMENTS_EMBEDDINGS_DIMENSIONS=${EXTRACTORS_DOCUMENTS_EMBEDDINGS_DIMENSIONS:-1536} + - ZEP_EXTRACTORS_MESSAGES_EMBEDDINGS_SERVICE=${EXTRACTORS_MESSAGES_EMBEDDINGS_SERVICE:-openai} + - ZEP_EXTRACTORS_MESSAGES_EMBEDDINGS_DIMENSIONS=${EXTRACTORS_MESSAGES_EMBEDDINGS_DIMENSIONS:-1536} + - ZEP_EXTRACTORS_MESSAGES_SUMMARIZER_EMBEDDINGS_SERVICE=${EXTRACTORS_MESSAGES_SUMMARIZER_EMBEDDINGS_SERVICE:-openai} + - ZEP_EXTRACTORS_MESSAGES_SUMMARIZER_EMBEDDINGS_DIMENSIONS=${EXTRACTORS_MESSAGES_SUMMARIZER_EMBEDDINGS_DIMENSIONS:-1536} + - ZEP_OPENAI_API_KEY=${OPENAI_API_KEY} + - ZEP_AUTH_SECRET=${SERVICE_PASSWORD_AUTHSECRET} + - ZEP_SERVER_WEB_ENABLED=${ZEP_SERVER_WEB_ENABLED:-false} + volumes: + - type: bind + source: ./config.yaml + target: /app/config.yaml + content: | + llm: + # openai or anthropic + service: "openai" + # OpenAI: gpt-3.5-turbo, gpt-4, gpt-3.5-turbo-1106, gpt-3.5-turbo-16k, gpt-4-32k, gpt-4o-mini, gpt-4o-mini-2024-07-18; Anthropic: claude-instant-1 or claude-2 + model: "gpt-4o-mini" + ## OpenAI-specific settings + # Only used for Azure OpenAI API + azure_openai_endpoint: + # for Azure OpenAI API deployment, the model may be deployed with custom deployment names + # set the deployment names if you encounter in logs HTTP 404 errors: + # "The API deployment for this resource does not exist." + azure_openai: + # llm.model name is used as deployment name as reasonable default if not set + # assuming base model is deployed with deployment name matching model name + # llm_deployment: "gpt-4o-mini-customname" + # embeddings deployment is required when Zep is configured to use OpenAI embeddings + # embedding_deployment: "text-embedding-ada-002-customname" + # Use only with an alternate OpenAI-compatible API endpoint + llm_deployment: + embedding_deployment: + openai_endpoint: + openai_org_id: + nlp: + server_url: "http://localhost:5557" + memory: + message_window: 12 + extractors: + documents: + embeddings: + enabled: true + chunk_size: 1000 + dimensions: 384 + service: "local" + # dimensions: 1536 + # service: "openai" + messages: + summarizer: + enabled: true + entities: + enabled: true + embeddings: + enabled: true + dimensions: 384 + service: "local" + entities: + enabled: true + intent: + enabled: true + embeddings: + enabled: true + dimensions: 384 + service: "local" + # dimensions: 1536 + # service: "openai" + store: + type: "postgres" + postgres: + dsn: "postgres://postgres:postgres@localhost:5432/?sslmode=disable" + server: + # Specify the host to listen on. Defaults to 0.0.0.0 + host: 0.0.0.0 + port: 8000 + # Is the Web UI enabled? + # Warning: The Web UI is not secured by authentication and should not be enabled if + # Zep is exposed to the public internet. + web_enabled: true + # The maximum size of a request body, in bytes. Defaults to 5MB. + max_request_size: 5242880 + auth: + # Set to true to enable authentication + required: true + # Do not use this secret in production. The ZEP_AUTH_SECRET environment variable should be + # set to a cryptographically secure secret. See the Zep docs for details. + secret: "do-not-use-this-secret-in-production" + data: + # PurgeEvery is the period between hard deletes, in minutes. + # If set to 0 or undefined, hard deletes will not be performed. + purge_every: 60 + log: + level: "info" + opentelemetry: + enabled: false + # Custom Prompts Configuration + # Allows customization of extractor prompts. + custom_prompts: + summarizer_prompts: + # Anthropic Guidelines: + # - Use XML-style tags like as element identifiers. + # - Include {{.PrevSummary}} and {{.MessagesJoined}} as template variables. + # - Clearly explain model instructions, e.g., "Review content inside tags". + # - Provide a clear example within the prompt. + # + # Example format: + # anthropic: | + # + # + # + # + # {{.PrevSummary}} + # {{.MessagesJoined}} + # Response without preamble. + # + # If left empty, the default Anthropic summary prompt from zep/pkg/extractors/prompts.go will be used. + anthropic: | + + # OpenAI summarizer prompt configuration. + # Guidelines: + # - Include {{.PrevSummary}} and {{.MessagesJoined}} as template variables. + # - Provide a clear example within the prompt. + # + # Example format: + # openai: | + # + # Example: + # + # Current summary: {{.PrevSummary}} + # New lines of conversation: {{.MessagesJoined}} + # New summary:` + # + # If left empty, the default OpenAI summary prompt from zep/pkg/extractors/prompts.go will be used. + openai: | + healthcheck: + test: "timeout 10s bash -c ':> /dev/tcp/127.0.0.1/8000' || exit 1" + interval: 5s + timeout: 10s + retries: 3 + start_period: 40s From b84cecfd3f757d792017892c793f4bee017a22af Mon Sep 17 00:00:00 2001 From: Alex Renoki Date: Sat, 5 Oct 2024 10:21:14 +0300 Subject: [PATCH 032/500] Added missing services. --- templates/compose/trigger.yaml | 44 ++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/templates/compose/trigger.yaml b/templates/compose/trigger.yaml index 2e8e9f9a7..1064ef789 100644 --- a/templates/compose/trigger.yaml +++ b/templates/compose/trigger.yaml @@ -11,15 +11,23 @@ services: - SERVICE_FQDN_TRIGGER_3000 - LOGIN_ORIGIN=$SERVICE_FQDN_TRIGGER - APP_ORIGIN=$SERVICE_FQDN_TRIGGER + - ELECTRIC_ORIGIN=http://electric:3000 - MAGIC_LINK_SECRET=$SERVICE_PASSWORD_64_MAGIC - ENCRYPTION_KEY=$SERVICE_PASSWORD_64_ENCRYPTION - SESSION_SECRET=$SERVICE_PASSWORD_64_SESSION + - PROVIDER_SECRET=$SERVICE_PASSWORD_64_PROVIDER + - COORDINATOR_SECRET=$SERVICE_PASSWORD_64_COORDINATOR - POSTGRES_USER=$SERVICE_USER_POSTGRES - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES - POSTGRES_DB=${POSTGRES_DB:-trigger} - POSTGRES_HOST=postgres - DATABASE_URL=postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB - DIRECT_URL=postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB + - REDIS_HOST=redis + - REDIS_PORT=6379 + - REDIS_TLS_DISABLED=true + - V3_ENABLED=${V3_ENABLED:-true} + - REMIX_APP_PORT=${REMIX_APP_PORT:-3000} - RUNTIME_PLATFORM=docker-compose - NODE_ENV=production - AUTH_GITHUB_CLIENT_ID=${AUTH_GITHUB_CLIENT_ID} @@ -30,10 +38,43 @@ services: depends_on: postgresql: condition: service_healthy + redis: + condition: service_healthy + electric: + condition: service_healthy healthcheck: - test: ["NONE"] + test: + - CMD-SHELL + - pwd + electric: + image: electricsql/electric + restart: always + environment: + DATABASE_URL: postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB + depends_on: + postgresql: + condition: service_healthy + healthcheck: + test: + - CMD-SHELL + - pwd + redis: + image: "redis:7" + environment: + - ALLOW_EMPTY_PASSWORD=yes + restart: always + healthcheck: + test: + - CMD-SHELL + - "redis-cli -h localhost -p 6379 ping" + interval: 5s + timeout: 5s + retries: 3 + volumes: + - redis-data:/data postgresql: image: postgres:16-alpine + restart: always volumes: - postgresql-data:/var/lib/postgresql/data environment: @@ -45,4 +86,3 @@ services: interval: 5s timeout: 20s retries: 10 - From 0ce030d863d1a7eac00b7e9049a49e8cadbcf119 Mon Sep 17 00:00:00 2001 From: "Alexander G." Date: Mon, 7 Oct 2024 11:25:37 +0300 Subject: [PATCH 033/500] Update zep.yaml --- templates/compose/zep.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/templates/compose/zep.yaml b/templates/compose/zep.yaml index d11110f4a..becaf94f0 100644 --- a/templates/compose/zep.yaml +++ b/templates/compose/zep.yaml @@ -4,8 +4,6 @@ # logo: svgs/zep.png # port: 8000 -version: "3" - volumes: pg_data: From 7f64873209de4a2c869e3479358d090b4013192f Mon Sep 17 00:00:00 2001 From: Darren Sisson Date: Mon, 7 Oct 2024 16:54:35 +0100 Subject: [PATCH 034/500] update supabase and add supavisor --- templates/compose/supabase.yaml | 108 +++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 9 deletions(-) diff --git a/templates/compose/supabase.yaml b/templates/compose/supabase.yaml index 5eb707d93..1776c2119 100644 --- a/templates/compose/supabase.yaml +++ b/templates/compose/supabase.yaml @@ -14,7 +14,7 @@ services: supabase-analytics: condition: service_healthy environment: - - SERVICE_FQDN_SUPABASEKONG + - SERVICE_FQDN_SUPABASEKONG_8000 - JWT_SECRET=${SERVICE_PASSWORD_JWT} - KONG_DATABASE=off - KONG_DECLARATIVE_CONFIG=/home/kong/kong.yml @@ -278,7 +278,7 @@ services: config: hide_credentials: true supabase-studio: - image: supabase/studio:20240729-ce42139 + image: supabase/studio:20240923-2e3e90c healthcheck: test: [ @@ -301,7 +301,7 @@ services: - DEFAULT_ORGANIZATION_NAME=${STUDIO_DEFAULT_ORGANIZATION:-Default Organization} - DEFAULT_PROJECT_NAME=${STUDIO_DEFAULT_PROJECT:-Default Project} - - SUPABASE_URL=${SERVICE_FQDN_SUPABASEKONG} + - 'SUPABASE_URL=http://supabase-kong:8000' - SUPABASE_PUBLIC_URL=${SERVICE_FQDN_SUPABASEKONG} - SUPABASE_ANON_KEY=${SERVICE_SUPABASEANON_KEY} - SUPABASE_SERVICE_KEY=${SERVICE_SUPABASESERVICE_KEY} @@ -309,6 +309,7 @@ services: - LOGFLARE_API_KEY=${SERVICE_PASSWORD_LOGFLARE} - LOGFLARE_URL=http://supabase-analytics:4000 + - 'SUPABASE_PUBLIC_API=${SERVICE_FQDN_SUPABASEKONG}' - NEXT_PUBLIC_ENABLE_LOGS=true # Comment to use Big Query backend for analytics - NEXT_ANALYTICS_BACKEND_PROVIDER=postgres @@ -351,6 +352,14 @@ services: create schema if not exists _realtime; alter schema _realtime owner to :pguser; + - type: bind + source: ./volumes/db/supavisor.sql + target: /docker-entrypoint-initdb.d/init-scripts/99-supavisor.sql + content: | + \set pguser `echo "supabase_admin"` + + create schema if not exists _supavisor; + alter schema _supavisor owner to :pguser; - type: bind source: ./volumes/db/webhooks.sql target: /docker-entrypoint-initdb.d/init-scripts/98-webhooks.sql @@ -905,7 +914,7 @@ services: restart: unless-stopped environment: - PGRST_DB_URI=postgres://authenticator:${SERVICE_PASSWORD_POSTGRES}@${POSTGRES_HOSTNAME:-supabase-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres} - - PGRST_DB_SCHEMAS=${PGRST_DB_SCHEMAS:-public} + - 'PGRST_DB_SCHEMAS=${PGRST_DB_SCHEMAS:-public,storage,graphql_public}' - PGRST_DB_ANON_ROLE=anon - PGRST_JWT_SECRET=${SERVICE_PASSWORD_JWT} - PGRST_DB_USE_LEGACY_GUCS=false @@ -914,7 +923,7 @@ services: command: "postgrest" exclude_from_hc: true supabase-auth: - image: supabase/gotrue:v2.151.0 + image: supabase/gotrue:v2.158.1 depends_on: supabase-db: # Disable this if you are using an external Postgres database @@ -992,7 +1001,7 @@ services: # GOTRUE_HOOK_PASSWORD_VERIFICATION_ATTEMPT_ENABLED="true" # GOTRUE_HOOK_PASSWORD_VERIFICATION_ATTEMPT_URI="pg-functions://postgres/public/password_verification_attempt" - + # Uncomment to enable common OAuth Variables #- 'GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=${GOTRUE_EXTERNAL_GITHUB_CLIENT_ID}' #- 'GOTRUE_EXTERNAL_GITHUB_ENABLED=${GOTRUE_EXTERNAL_GITHUB_ENABLED}' @@ -1005,7 +1014,7 @@ services: realtime-dev: # This container name looks inconsistent but is correct because realtime constructs tenant id by parsing the subdomain - image: supabase/realtime:v2.30.23 + image: supabase/realtime:v2.30.34 container_name: realtime-dev.supabase-realtime depends_on: supabase-db: @@ -1085,7 +1094,7 @@ services: exit 0 supabase-storage: - image: supabase/storage-api:v1.0.6 + image: supabase/storage-api:v1.10.1 depends_on: supabase-db: # Disable this if you are using an external Postgres database @@ -1185,7 +1194,7 @@ services: - PG_META_DB_PASSWORD=${SERVICE_PASSWORD_POSTGRES} supabase-edge-functions: - image: supabase/edge-runtime:v1.53.3 + image: supabase/edge-runtime:v1.58.3 depends_on: supabase-analytics: condition: service_healthy @@ -1327,3 +1336,84 @@ services: - start - --main-service - /home/deno/functions/main + + supabase-supavisor: + image: 'supabase/supavisor:1.1.56' + healthcheck: + test: + - CMD + - curl + - "-sSfL" + - "-o" + - /dev/null + - "http://127.0.0.1:4000/api/health" + timeout: 5s + interval: 5s + retries: 10 + restart: unless-stopped + depends_on: + supabase-db: + condition: service_healthy + environment: + - PORT=4000 + - PROXY_PORT_SESSION=5432 + - PROXY_PORT_TRANSACTION=6543 + - 'POSTGRES_PORT=${POSTGRES_PORT:-5432}' + - 'POSTGRES_HOSTNAME=${POSTGRES_HOSTNAME:-supabase-db}' + - 'POSTGRES_DB=${POSTGRES_DB:-postgres}' + - 'POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}' + - 'DATABASE_URL=ecto://supabase_admin:${SERVICE_PASSWORD_POSTGRES}@${POSTGRES_HOSTNAME:-supabase-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres}' + - CLUSTER_POSTGRES=true + - 'SECRET_KEY_BASE=${SERVICE_PASSWORD_SUPAVISORSECRET}' + - 'VAULT_ENC_KEY=${SERVICE_PASSWORD_VAULTENC}' + - 'API_JWT_SECRET=${SERVICE_PASSWORD_JWT}' + - 'METRICS_JWT_SECRET=${SERVICE_PASSWORD_JWT}' + - REGION=local + - 'ERL_AFLAGS=-proto_dist inet_tcp' + volumes: + - type: bind + source: ./volumes/supavisor/entrypoint.sh + target: /home/entrypoint.sh + content: | + #!/bin/bash + + /app/bin/supavisor eval ' + {:ok, _} = Application.ensure_all_started(:supavisor) + {:ok, version} = + case Supavisor.Repo.query!("select version()") do + %{rows: [[ver]]} -> Supavisor.Helpers.parse_pg_version(ver) + _ -> nil + end + params = %{ + "external_id" => "dev_tenant", + "db_host" => System.get_env("POSTGRES_HOSTNAME"), + "db_port" => System.get_env("POSTGRES_PORT") |> String.to_integer(), + "db_database" => System.get_env("POSTGRES_DB"), + "require_user" => false, + "auth_query" => "SELECT rolname, rolpassword FROM pg_authid WHERE rolname=$1", + "default_max_clients" => 100, + "default_pool_size" => 20, + "enforce_ssl" => false, + "default_parameter_status" => %{"server_version" => version}, + "users" => [%{ + "db_user" => "postgres", + "db_password" => System.get_env("POSTGRES_PASSWORD"), + "mode_type" => "transaction", + "pool_size" => 20, + "is_manager" => true + }] + } + + tenant = Supavisor.Tenants.get_tenant_by_external_id(params["external_id"]) + + if tenant do + {:ok, _} = Supavisor.Tenants.update_tenant(tenant, params) + else + {:ok, _} = Supavisor.Tenants.create_tenant(params) + end + ' + + command: + - sh + - "-c" + - "chmod +x /home/entrypoint.sh && /app/bin/migrate && /home/entrypoint.sh && /app/bin/server" From f559a1d9b33d8b4b4e5b530524b9f561869d7ec0 Mon Sep 17 00:00:00 2001 From: Darren Sisson Date: Tue, 8 Oct 2024 13:47:27 +0100 Subject: [PATCH 035/500] add missing live service to plane template --- templates/compose/plane.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/templates/compose/plane.yaml b/templates/compose/plane.yaml index d3ff15617..69c9bef58 100644 --- a/templates/compose/plane.yaml +++ b/templates/compose/plane.yaml @@ -97,6 +97,19 @@ services: timeout: 10s retries: 15 + live: + <<: *app-env + image: makeplane/plane-live:stable + command: node live/dist/server.js live + depends_on: + - api + - web + healthcheck: + test: ["CMD", "echo", "hey whats up"] + interval: 2s + timeout: 10s + retries: 15 + api: <<: *app-env image: makeplane/plane-backend:stable From 8dfba32c307e005c993559e351db651212c7627c Mon Sep 17 00:00:00 2001 From: Darren Sisson Date: Tue, 8 Oct 2024 14:02:55 +0100 Subject: [PATCH 036/500] add rabbitmq to plane template --- templates/compose/plane.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/templates/compose/plane.yaml b/templates/compose/plane.yaml index 69c9bef58..a561909b6 100644 --- a/templates/compose/plane.yaml +++ b/templates/compose/plane.yaml @@ -23,6 +23,15 @@ x-app-env: &app-env - REDIS_HOST=plane-redis - REDIS_PORT=6379 - REDIS_URL=${REDIS_URL:-redis://plane-redis:6379/} + + # RabbitMQ Settings + - RABBITMQ_HOST=plane-mq + - RABBITMQ_PORT=${RABBITMQ_PORT:-5672} + - RABBITMQ_DEFAULT_USER=${SERVICE_USER_RABBITMQ:-plane} + - RABBITMQ_DEFAULT_PASS=${SERVICE_PASSWORD_RABBITMQ:-plane} + - RABBITMQ_DEFAULT_VHOST=${RABBITMQ_VHOST:-plane} + - RABBITMQ_VHOST=${RABBITMQ_VHOST:-plane} + - 'AMQP_URL=amqp://${SERVICE_USER_RABBITMQ}:${SERVICE_PASSWORD_RABBITMQ}@$plane-mq:${RABBITMQ_PORT}/plane' # Application secret - SECRET_KEY=$SERVICE_PASSWORD_64_SECRETKEY # DATA STORE SETTINGS @@ -191,6 +200,18 @@ services: timeout: 20s retries: 10 + plane-mq: + <<: *app-env + image: rabbitmq:3.13.6-management-alpine + restart: always + volumes: + - rabbitmq_data:/var/lib/rabbitmq + healthcheck: + test: rabbitmq-diagnostics -q ping + interval: 30s + timeout: 30s + retries: 3 + plane-minio: <<: *app-env image: minio/minio:latest From 97ce097c1f4ff9dddd4da5f0e76a9f6c15c3346f Mon Sep 17 00:00:00 2001 From: Darren Sisson Date: Tue, 8 Oct 2024 14:16:55 +0100 Subject: [PATCH 037/500] fix plane template --- templates/compose/plane.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/templates/compose/plane.yaml b/templates/compose/plane.yaml index a561909b6..754cc32ac 100644 --- a/templates/compose/plane.yaml +++ b/templates/compose/plane.yaml @@ -46,9 +46,7 @@ x-app-env: &app-env - BUCKET_NAME=${BUCKET_NAME:-uploads} - FILE_SIZE_LIMIT=${FILE_SIZE_LIMIT:-5242880} # Admin and Space URLs - - ADMIN_BASE_URL=${ADMIN_BASE_URL} - - SPACE_BASE_URL=${SPACE_BASE_URL} - - APP_BASE_URL=${SERVICE_FQDN_PLANE} + - API_BASE_URL=${API_BASE_URL:-http://api:8000} services: proxy: @@ -179,7 +177,7 @@ services: plane-db: <<: *app-env - image: postgres:15.5-alpine + image: postgres:15.7-alpine command: postgres -c 'max_connections=1000' volumes: - pgdata:/var/lib/postgresql/data From 68447ea326b513c0b72700fdded986210d8f5b4e Mon Sep 17 00:00:00 2001 From: Darren Sisson Date: Tue, 8 Oct 2024 14:41:24 +0100 Subject: [PATCH 038/500] fix plane template error in url --- templates/compose/plane.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/compose/plane.yaml b/templates/compose/plane.yaml index 754cc32ac..fc62cb122 100644 --- a/templates/compose/plane.yaml +++ b/templates/compose/plane.yaml @@ -31,7 +31,7 @@ x-app-env: &app-env - RABBITMQ_DEFAULT_PASS=${SERVICE_PASSWORD_RABBITMQ:-plane} - RABBITMQ_DEFAULT_VHOST=${RABBITMQ_VHOST:-plane} - RABBITMQ_VHOST=${RABBITMQ_VHOST:-plane} - - 'AMQP_URL=amqp://${SERVICE_USER_RABBITMQ}:${SERVICE_PASSWORD_RABBITMQ}@$plane-mq:${RABBITMQ_PORT}/plane' + - 'AMQP_URL=amqp://${SERVICE_USER_RABBITMQ}:${SERVICE_PASSWORD_RABBITMQ}@plane-mq:${RABBITMQ_PORT}/plane' # Application secret - SECRET_KEY=$SERVICE_PASSWORD_64_SECRETKEY # DATA STORE SETTINGS @@ -45,7 +45,7 @@ x-app-env: &app-env - MINIO_ROOT_PASSWORD=$SERVICE_PASSWORD_MINIO - BUCKET_NAME=${BUCKET_NAME:-uploads} - FILE_SIZE_LIMIT=${FILE_SIZE_LIMIT:-5242880} - # Admin and Space URLs + # Live server env - API_BASE_URL=${API_BASE_URL:-http://api:8000} services: From 83bcf981c255d63548ea7269bdd3c86af4a431c7 Mon Sep 17 00:00:00 2001 From: Luan Estradioto Date: Wed, 9 Oct 2024 00:14:27 -0300 Subject: [PATCH 039/500] fix autocompletes --- .../views/components/modal-confirmation.blade.php | 12 ++++++++---- .../views/livewire/notifications/telegram.blade.php | 7 ++++--- resources/views/livewire/settings-email.blade.php | 3 ++- resources/views/livewire/settings-oauth.blade.php | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/resources/views/components/modal-confirmation.blade.php b/resources/views/components/modal-confirmation.blade.php index fde75ab24..adcae3eca 100644 --- a/resources/views/components/modal-confirmation.blade.php +++ b/resources/views/components/modal-confirmation.blade.php @@ -268,13 +268,17 @@

Please enter your password to confirm this destructive action.

- -
- + + +

@error('password') diff --git a/resources/views/livewire/notifications/telegram.blade.php b/resources/views/livewire/notifications/telegram.blade.php index 3f57ff471..0b9d5a874 100644 --- a/resources/views/livewire/notifications/telegram.blade.php +++ b/resources/views/livewire/notifications/telegram.blade.php @@ -20,11 +20,12 @@
- + id="team.telegram_chat_id" label="Chat ID" />
@if (data_get($team, 'telegram_enabled'))

Subscribe to events

diff --git a/resources/views/livewire/settings-email.blade.php b/resources/views/livewire/settings-email.blade.php index 37d395cd8..0e99c9586 100644 --- a/resources/views/livewire/settings-email.blade.php +++ b/resources/views/livewire/settings-email.blade.php @@ -36,7 +36,8 @@
- +
diff --git a/resources/views/livewire/settings-oauth.blade.php b/resources/views/livewire/settings-oauth.blade.php index 9a94d3c2b..eefd10c7c 100644 --- a/resources/views/livewire/settings-oauth.blade.php +++ b/resources/views/livewire/settings-oauth.blade.php @@ -25,7 +25,7 @@ + type="password" label="Client Secret" autocomplete="new-password" /> @if ($oauth_setting->provider == 'azure') From e6c249ffea070441cb8ea4c6e0adbd2cf2980602 Mon Sep 17 00:00:00 2001 From: Luan Estradioto Date: Wed, 9 Oct 2024 01:20:13 -0300 Subject: [PATCH 040/500] add to resend too --- resources/views/livewire/settings-email.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/settings-email.blade.php b/resources/views/livewire/settings-email.blade.php index 0e99c9586..c36e98808 100644 --- a/resources/views/livewire/settings-email.blade.php +++ b/resources/views/livewire/settings-email.blade.php @@ -58,7 +58,7 @@
+ label="Host" autocomplete="new-password" />
From b1e91252f3ccb640c1d2cd29edc23454775e70db Mon Sep 17 00:00:00 2001 From: Alex Renoki Date: Wed, 9 Oct 2024 12:54:19 +0300 Subject: [PATCH 041/500] Updated trigger service --- templates/compose/trigger.yaml | 122 ++++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 32 deletions(-) diff --git a/templates/compose/trigger.yaml b/templates/compose/trigger.yaml index 1064ef789..e33459535 100644 --- a/templates/compose/trigger.yaml +++ b/templates/compose/trigger.yaml @@ -4,37 +4,56 @@ # logo: svgs/trigger.png # port: 3000 +x-common-env: &common-env + PORT: 3030 + REMIX_APP_PORT: 3000 + NODE_ENV: production + RUNTIME_PLATFORM: docker-compose + V3_ENABLED: true + INTERNAL_OTEL_TRACE_DISABLED: 1 + INTERNAL_OTEL_TRACE_LOGGING_ENABLED: 0 + POSTGRES_USER: $SERVICE_USER_POSTGRES + POSTGRES_PASSWORD: $SERVICE_PASSWORD_POSTGRES + POSTGRES_DB: ${POSTGRES_DB:-trigger} + MAGIC_LINK_SECRET: $SERVICE_PASSWORD_64_MAGIC + SESSION_SECRET: $SERVICE_PASSWORD_64_SESSION + ENCRYPTION_KEY: $SERVICE_PASSWORD_64_ENCRYPTION + PROVIDER_SECRET: $SERVICE_PASSWORD_64_PROVIDER + COORDINATOR_SECRET: $SERVICE_PASSWORD_64_COORDINATOR + DATABASE_HOST: postgresql + DATABASE_URL: postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB + DIRECT_URL: postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB + REDIS_HOST: redis + REDIS_PORT: 6379 + REDIS_TLS_DISABLED: true + COORDINATOR_HOST: 127.0.0.1 + COORDINATOR_PORT: 9020 + WHITELISTED_EMAILS: "" + ADMIN_EMAILS: "" + DEFAULT_ORG_EXECUTION_CONCURRENCY_LIMIT: 300 + DEFAULT_ENV_EXECUTION_CONCURRENCY_LIMIT: 100 + DEPLOY_REGISTRY_HOST: docker.io + DEPLOY_REGISTRY_NAMESPACE: trigger + REGISTRY_HOST: ${DEPLOY_REGISTRY_HOST} + REGISTRY_NAMESPACE: ${DEPLOY_REGISTRY_NAMESPACE} + AUTH_GITHUB_CLIENT_ID: ${AUTH_GITHUB_CLIENT_ID} + AUTH_GITHUB_CLIENT_SECRET: ${AUTH_GITHUB_CLIENT_SECRET} + RESEND_API_KEY: ${RESEND_API_KEY} + FROM_EMAIL: ${FROM_EMAIL} + REPLY_TO_EMAIL: ${REPLY_TO_EMAIL} + LOGIN_ORIGIN: $SERVICE_FQDN_TRIGGER_3000 + APP_ORIGIN: $SERVICE_FQDN_TRIGGER_3000 + DEV_OTEL_EXPORTER_OTLP_ENDPOINT: $SERVICE_FQDN_TRIGGER_3000/otel + OTEL_EXPORTER_OTLP_ENDPOINT: "http://trigger:3040/otel" + ELECTRIC_ORIGIN: http://electric:3000 + services: trigger: - image: ghcr.io/triggerdotdev/trigger.dev:main + image: ghcr.io/triggerdotdev/trigger.dev:v3 + restart: always environment: - - SERVICE_FQDN_TRIGGER_3000 - - LOGIN_ORIGIN=$SERVICE_FQDN_TRIGGER - - APP_ORIGIN=$SERVICE_FQDN_TRIGGER - - ELECTRIC_ORIGIN=http://electric:3000 - - MAGIC_LINK_SECRET=$SERVICE_PASSWORD_64_MAGIC - - ENCRYPTION_KEY=$SERVICE_PASSWORD_64_ENCRYPTION - - SESSION_SECRET=$SERVICE_PASSWORD_64_SESSION - - PROVIDER_SECRET=$SERVICE_PASSWORD_64_PROVIDER - - COORDINATOR_SECRET=$SERVICE_PASSWORD_64_COORDINATOR - - POSTGRES_USER=$SERVICE_USER_POSTGRES - - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES - - POSTGRES_DB=${POSTGRES_DB:-trigger} - - POSTGRES_HOST=postgres - - DATABASE_URL=postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB - - DIRECT_URL=postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB - - REDIS_HOST=redis - - REDIS_PORT=6379 - - REDIS_TLS_DISABLED=true - - V3_ENABLED=${V3_ENABLED:-true} - - REMIX_APP_PORT=${REMIX_APP_PORT:-3000} - - RUNTIME_PLATFORM=docker-compose - - NODE_ENV=production - - AUTH_GITHUB_CLIENT_ID=${AUTH_GITHUB_CLIENT_ID} - - AUTH_GITHUB_CLIENT_SECRET=${AUTH_GITHUB_CLIENT_SECRET} - - RESEND_API_KEY=${RESEND_API_KEY} - - FROM_EMAIL=${FROM_EMAIL} - - REPLY_TO_EMAIL=${REPLY_TO_EMAIL} + SERVICE_FQDN_TRIGGER_3000: "" + <<: *common-env depends_on: postgresql: condition: service_healthy @@ -50,7 +69,7 @@ services: image: electricsql/electric restart: always environment: - DATABASE_URL: postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB + <<: *common-env depends_on: postgresql: condition: service_healthy @@ -78,11 +97,50 @@ services: volumes: - postgresql-data:/var/lib/postgresql/data environment: - - POSTGRES_USER=$SERVICE_USER_POSTGRES - - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES - - POSTGRES_DB=${POSTGRES_DB:-trigger} + <<: *common-env + command: + - -c + - wal_level=logical healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 20s retries: 10 + docker-provider: + image: ghcr.io/triggerdotdev/provider/docker:v3 + restart: always + volumes: + - /var/run/docker.sock:/var/run/docker.sock + user: root + depends_on: + trigger: + condition: service_healthy + environment: + <<: *common-env + PLATFORM_HOST: trigger + PLATFORM_WS_PORT: 3030 + SECURE_CONNECTION: "false" + PLATFORM_SECRET: $PROVIDER_SECRET + coordinator: + image: ghcr.io/triggerdotdev/coordinator:v3 + restart: always + volumes: + - /var/run/docker.sock:/var/run/docker.sock + user: root + depends_on: + trigger: + condition: service_healthy + environment: + <<: *common-env + PLATFORM_HOST: trigger + PLATFORM_WS_PORT: 3030 + SECURE_CONNECTION: "false" + PLATFORM_SECRET: $COORDINATOR_SECRET + healthcheck: + test: + - CMD-SHELL + - pwd + +volumes: + postgresql-data: + redis-data: From 1b0f67a0839f2619ed82f7b0633239c75093d449 Mon Sep 17 00:00:00 2001 From: Darren Sisson Date: Wed, 9 Oct 2024 13:03:47 +0100 Subject: [PATCH 042/500] update supabase template to match current version --- templates/compose/supabase.yaml | 61 ++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/templates/compose/supabase.yaml b/templates/compose/supabase.yaml index 1776c2119..8f3d0a667 100644 --- a/templates/compose/supabase.yaml +++ b/templates/compose/supabase.yaml @@ -353,11 +353,18 @@ services: create schema if not exists _realtime; alter schema _realtime owner to :pguser; - type: bind - source: ./volumes/db/supavisor.sql - target: /docker-entrypoint-initdb.d/init-scripts/99-supavisor.sql + source: ./volumes/db/_supabase.sql + target: /docker-entrypoint-initdb.d/migrations/97-_supabase.sql + content: | + \set pguser `echo "$POSTGRES_USER"` + + CREATE DATABASE _supabase WITH OWNER :pguser; + - type: bind + source: ./volumes/db/pooler.sql + target: /docker-entrypoint-initdb.d/migrations/99-pooler.sql content: | \set pguser `echo "supabase_admin"` - + \c _supabase create schema if not exists _supavisor; alter schema _supavisor owner to :pguser; - type: bind @@ -600,7 +607,7 @@ services: target: /docker-entrypoint-initdb.d/migrations/99-logs.sql content: | \set pguser `echo "supabase_admin"` - + \c _supabase create schema if not exists _analytics; alter schema _analytics owner to :pguser; # Use named volume to persist pgsodium decryption key between restarts @@ -625,7 +632,7 @@ services: environment: - LOGFLARE_NODE_HOST=127.0.0.1 - DB_USERNAME=supabase_admin - - DB_DATABASE=${POSTGRES_DB:-postgres} + - DB_DATABASE=_supabase - DB_HOSTNAME=${POSTGRES_HOSTNAME:-supabase-db} - DB_PORT=${POSTGRES_PORT:-5432} - DB_PASSWORD=${SERVICE_PASSWORD_POSTGRES} @@ -637,7 +644,7 @@ services: - LOGFLARE_MIN_CLUSTER_SIZE=1 # Comment variables to use Big Query backend for analytics - - POSTGRES_BACKEND_URL=postgresql://supabase_admin:${SERVICE_PASSWORD_POSTGRES}@${POSTGRES_HOSTNAME:-supabase-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres} + - POSTGRES_BACKEND_URL=postgresql://supabase_admin:${SERVICE_PASSWORD_POSTGRES}@${POSTGRES_HOSTNAME:-supabase-db}:${POSTGRES_PORT:-5432}/_supabase - POSTGRES_BACKEND_SCHEMA=_analytics - LOGFLARE_FEATURE_FLAG_OVERRIDE=multibackend=true @@ -1354,15 +1361,19 @@ services: depends_on: supabase-db: condition: service_healthy + supabase-analytics: + condition: service_healthy environment: + - POOLER_TENANT_ID=dev_tenant + - POOLER_POOL_MODE=transaction + - POOLER_DEFAULT_POOL_SIZE=${POOLER_DEFAULT_POOL_SIZE:-20} + - POOLER_MAX_CLIENT_CONN=${POOLER_MAX_CLIENT_CONN:-100} - PORT=4000 - - PROXY_PORT_SESSION=5432 - - PROXY_PORT_TRANSACTION=6543 - 'POSTGRES_PORT=${POSTGRES_PORT:-5432}' - 'POSTGRES_HOSTNAME=${POSTGRES_HOSTNAME:-supabase-db}' - 'POSTGRES_DB=${POSTGRES_DB:-postgres}' - 'POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}' - - 'DATABASE_URL=ecto://supabase_admin:${SERVICE_PASSWORD_POSTGRES}@${POSTGRES_HOSTNAME:-supabase-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres}' + - 'DATABASE_URL=ecto://supabase_admin:${SERVICE_PASSWORD_POSTGRES}@${POSTGRES_HOSTNAME:-supabase-db}:${POSTGRES_PORT:-5432}/_supabase' - CLUSTER_POSTGRES=true - 'SECRET_KEY_BASE=${SERVICE_PASSWORD_SUPAVISORSECRET}' - 'VAULT_ENC_KEY=${SERVICE_PASSWORD_VAULTENC}' @@ -1370,14 +1381,15 @@ services: - 'METRICS_JWT_SECRET=${SERVICE_PASSWORD_JWT}' - REGION=local - 'ERL_AFLAGS=-proto_dist inet_tcp' + command: + - /bin/sh + - "-c" + - '/app/bin/migrate && /app/bin/supavisor eval "$$(cat /etc/pooler/pooler.exs)" && /app/bin/server' volumes: - type: bind - source: ./volumes/supavisor/entrypoint.sh - target: /home/entrypoint.sh + source: ./volumes/pooler/pooler.exs + target: /etc/pooler/pooler.exs content: | - #!/bin/bash - - /app/bin/supavisor eval ' {:ok, _} = Application.ensure_all_started(:supavisor) {:ok, version} = case Supavisor.Repo.query!("select version()") do @@ -1385,21 +1397,20 @@ services: _ -> nil end params = %{ - "external_id" => "dev_tenant", + "external_id" => System.get_env("POOLER_TENANT_ID"), "db_host" => System.get_env("POSTGRES_HOSTNAME"), "db_port" => System.get_env("POSTGRES_PORT") |> String.to_integer(), "db_database" => System.get_env("POSTGRES_DB"), "require_user" => false, - "auth_query" => "SELECT rolname, rolpassword FROM pg_authid WHERE rolname=$1", - "default_max_clients" => 100, - "default_pool_size" => 20, - "enforce_ssl" => false, + "auth_query" => "SELECT * FROM pgbouncer.get_auth($1)", + "default_max_clients" => System.get_env("POOLER_MAX_CLIENT_CONN"), + "default_pool_size" => System.get_env("POOLER_DEFAULT_POOL_SIZE"), "default_parameter_status" => %{"server_version" => version}, "users" => [%{ - "db_user" => "postgres", + "db_user" => "pgbouncer", "db_password" => System.get_env("POSTGRES_PASSWORD"), - "mode_type" => "transaction", - "pool_size" => 20, + "mode_type" => System.get_env("POOLER_POOL_MODE"), + "pool_size" => System.get_env("POOLER_DEFAULT_POOL_SIZE"), "is_manager" => true }] } @@ -1411,9 +1422,3 @@ services: else {:ok, _} = Supavisor.Tenants.create_tenant(params) end - ' - - command: - - sh - - "-c" - - "chmod +x /home/entrypoint.sh && /app/bin/migrate && /home/entrypoint.sh && /app/bin/server" From a094eceb624b024ef46efd1e98a6769003555c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Smitka?= Date: Wed, 9 Oct 2024 18:34:17 +0200 Subject: [PATCH 043/500] Expose port 443/udp with Caddy proxy --- bootstrap/helpers/proxy.php | 1 + 1 file changed, 1 insertion(+) diff --git a/bootstrap/helpers/proxy.php b/bootstrap/helpers/proxy.php index 5d1ad5390..9fa93e2e9 100644 --- a/bootstrap/helpers/proxy.php +++ b/bootstrap/helpers/proxy.php @@ -239,6 +239,7 @@ function generate_default_proxy_configuration(Server $server) 'ports' => [ '80:80', '443:443', + '443:443/udp', ], 'labels' => [ 'coolify.managed=true', From f95f44f4ccee167a1cfa491d6e5824ab44dd9955 Mon Sep 17 00:00:00 2001 From: MarioCake Date: Wed, 9 Oct 2024 23:45:57 +0200 Subject: [PATCH 044/500] Add settings button to projects page. --- app/Livewire/Project/Index.php | 6 +++++- resources/views/livewire/project/index.blade.php | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/Livewire/Project/Index.php b/app/Livewire/Project/Index.php index 0e4f15a5c..9ba082a8c 100644 --- a/app/Livewire/Project/Index.php +++ b/app/Livewire/Project/Index.php @@ -18,7 +18,11 @@ class Index extends Component public function mount() { $this->private_keys = PrivateKey::ownedByCurrentTeam()->get(); - $this->projects = Project::ownedByCurrentTeam()->get(); + $this->projects = Project::ownedByCurrentTeam()->get()->map(function ($project) { + $project->route = route('project.edit', ['project_uuid' => $project->uuid]); + + return $project; + }); $this->servers = Server::ownedByCurrentTeam()->count(); } diff --git a/resources/views/livewire/project/index.blade.php b/resources/views/livewire/project/index.blade.php index 10719456e..bebe15258 100644 --- a/resources/views/livewire/project/index.blade.php +++ b/resources/views/livewire/project/index.blade.php @@ -24,6 +24,12 @@
+
From 62e67eff8931bd0c136235831f3e77218e786980 Mon Sep 17 00:00:00 2001 From: MarioCake Date: Wed, 9 Oct 2024 23:49:54 +0200 Subject: [PATCH 045/500] Remove click handler for settings div. --- resources/views/livewire/project/index.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/project/index.blade.php b/resources/views/livewire/project/index.blade.php index bebe15258..d53535582 100644 --- a/resources/views/livewire/project/index.blade.php +++ b/resources/views/livewire/project/index.blade.php @@ -24,7 +24,7 @@
-
+
Settings From 0155af211653270247149447e99e9b87b926d760 Mon Sep 17 00:00:00 2001 From: loudar Date: Thu, 10 Oct 2024 01:01:11 +0200 Subject: [PATCH 046/500] limit randomly generated github app name length --- app/Livewire/Source/Github/Create.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Livewire/Source/Github/Create.php b/app/Livewire/Source/Github/Create.php index f85e8646e..103c5c9fb 100644 --- a/app/Livewire/Source/Github/Create.php +++ b/app/Livewire/Source/Github/Create.php @@ -23,7 +23,7 @@ class Create extends Component public function mount() { - $this->name = generate_random_name(); + $this->name = substr(generate_random_name(), 0, 34); // GitHub Apps names can only be 34 characters long } public function createGitHubApp() From 2a419639171aca244ac4bf73bea5b34a9b608911 Mon Sep 17 00:00:00 2001 From: Adrian Barrio Date: Thu, 10 Oct 2024 09:44:40 +0200 Subject: [PATCH 047/500] feat: add Transmission template --- public/svgs/transmission.svg | 1 + templates/compose/transmission.yaml | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 public/svgs/transmission.svg create mode 100644 templates/compose/transmission.yaml diff --git a/public/svgs/transmission.svg b/public/svgs/transmission.svg new file mode 100644 index 000000000..9a11f77f4 --- /dev/null +++ b/public/svgs/transmission.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/compose/transmission.yaml b/templates/compose/transmission.yaml new file mode 100644 index 000000000..3a0d05c32 --- /dev/null +++ b/templates/compose/transmission.yaml @@ -0,0 +1,13 @@ +services: + transmission: + image: "lscr.io/linuxserver/transmission:latest" + environment: + - SERVICE_FQDN_transmission_9091 + - PUID=1000 + - PGID=1000 + - USER=${SERVICE_USER_ADMIN} + - PASS=${SERVICE_PASSWORD_ADMIN} + volumes: + - "config:/config" + - "downloads:/downloads" + - "watch:/watch" From 76d631d7ba7699d07ec53168a0c12718f842d2ed Mon Sep 17 00:00:00 2001 From: MarioCake Date: Thu, 10 Oct 2024 09:45:13 +0200 Subject: [PATCH 048/500] Rename route attribute to settingsRoute attribute. --- app/Livewire/Project/Index.php | 2 +- resources/views/livewire/project/index.blade.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Livewire/Project/Index.php b/app/Livewire/Project/Index.php index 9ba082a8c..f8eb838be 100644 --- a/app/Livewire/Project/Index.php +++ b/app/Livewire/Project/Index.php @@ -19,7 +19,7 @@ class Index extends Component { $this->private_keys = PrivateKey::ownedByCurrentTeam()->get(); $this->projects = Project::ownedByCurrentTeam()->get()->map(function ($project) { - $project->route = route('project.edit', ['project_uuid' => $project->uuid]); + $project->settingsRoute = route('project.edit', ['project_uuid' => $project->uuid]); return $project; }); diff --git a/resources/views/livewire/project/index.blade.php b/resources/views/livewire/project/index.blade.php index d53535582..cb8e1bbed 100644 --- a/resources/views/livewire/project/index.blade.php +++ b/resources/views/livewire/project/index.blade.php @@ -26,7 +26,7 @@
From 44d0b9918b8f523f985e9140b23fe61c56795d29 Mon Sep 17 00:00:00 2001 From: Adrian Barrio Date: Thu, 10 Oct 2024 10:44:00 +0200 Subject: [PATCH 049/500] feat: add transmission healhcheck --- templates/compose/transmission.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/templates/compose/transmission.yaml b/templates/compose/transmission.yaml index 3a0d05c32..76f8bad47 100644 --- a/templates/compose/transmission.yaml +++ b/templates/compose/transmission.yaml @@ -11,3 +11,15 @@ services: - "config:/config" - "downloads:/downloads" - "watch:/watch" + healthcheck: + test: [ + "CMD", + "curl", + "-sSfL", + "-u", + "${SERVICE_USER_ADMIN}:${SERVICE_PASSWORD_ADMIN}", + "http://localhost:9091/" + ] + interval: 30s + timeout: 10s + retries: 3 \ No newline at end of file From 8d23331a2088500ab57b9d480b3569f9734fc49d Mon Sep 17 00:00:00 2001 From: Adrian Barrio Date: Thu, 10 Oct 2024 10:44:44 +0200 Subject: [PATCH 050/500] chore: add transmission template desc --- templates/compose/transmission.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/templates/compose/transmission.yaml b/templates/compose/transmission.yaml index 76f8bad47..7e2719f1d 100644 --- a/templates/compose/transmission.yaml +++ b/templates/compose/transmission.yaml @@ -1,3 +1,9 @@ +# documentation: https://transmissionbt.com/help/ +# slogan: Fast, easy, and free BitTorrent client. +# tags: bittorrent, torrent, peer-to-peer +# logo: svgs/transmission.svg +# port: 9091 + services: transmission: image: "lscr.io/linuxserver/transmission:latest" From d6986726afb6b70cabcc8c63ee0b9a16db980fe2 Mon Sep 17 00:00:00 2001 From: Adrian Barrio Date: Thu, 10 Oct 2024 10:45:29 +0200 Subject: [PATCH 051/500] chore: update transmission docs link --- templates/compose/transmission.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/transmission.yaml b/templates/compose/transmission.yaml index 7e2719f1d..c28951388 100644 --- a/templates/compose/transmission.yaml +++ b/templates/compose/transmission.yaml @@ -1,4 +1,4 @@ -# documentation: https://transmissionbt.com/help/ +# documentation: https://docs.linuxserver.io/images/docker-transmission/ # slogan: Fast, easy, and free BitTorrent client. # tags: bittorrent, torrent, peer-to-peer # logo: svgs/transmission.svg From 222d5f88befe850b8383a01f0e6e094364f6d94c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 10 Oct 2024 13:48:32 +0200 Subject: [PATCH 052/500] Revert "Revert "Feat: New services part 3"" --- config/sentry.php | 1 - config/version.php | 1 - public/svgs/affine.svg | 88 +++++++++++++++++ public/svgs/cloudbeaver.svg | 7 ++ public/svgs/cryptgeon.png | Bin 0 -> 77470 bytes public/svgs/flowise.png | Bin 0 -> 7230 bytes public/svgs/freshrss.png | Bin 0 -> 14801 bytes public/svgs/homebox.svg | 11 +++ public/svgs/immich.svg | 66 +++++++++++++ public/svgs/kimai.svg | 67 +++++++++++++ public/svgs/libretranslate.svg | 1 + public/svgs/ntfy.svg | 1 + public/svgs/owncloud.svg | 84 ++++++++++++++++ public/svgs/qbittorrent.svg | 16 +++ public/svgs/traccar.png | Bin 0 -> 22009 bytes public/svgs/unsend.svg | 13 +++ public/svgs/vvveb.svg | 1 + templates/compose/affine.yaml | 75 +++++++++++++++ templates/compose/cloudbeaver.yaml | 18 ++++ templates/compose/cryptgeon.yaml | 41 ++++++++ templates/compose/flowise-with-databases.yaml | 91 ++++++++++++++++++ templates/compose/flowise.yaml | 35 +++++++ templates/compose/freshrss-with-mariadb.yaml | 41 ++++++++ templates/compose/freshrss-with-mysql.yaml | 41 ++++++++ .../compose/freshrss-with-postgresql.yaml | 41 ++++++++ templates/compose/freshrss.yaml | 20 ++++ templates/compose/glitchtip.yaml | 25 +++-- templates/compose/homebox.yaml | 21 ++++ templates/compose/immich.yaml | 76 +++++++++++++++ templates/compose/kimai.yaml | 44 +++++++++ templates/compose/libretranslate.yaml | 19 ++++ templates/compose/nextcloud-with-mariadb.yaml | 61 ++++++++++++ templates/compose/nextcloud-with-mysql.yaml | 61 ++++++++++++ .../compose/nextcloud-with-postgres.yaml | 60 ++++++++++++ templates/compose/nextcloud.yaml | 5 +- templates/compose/ntfy.yaml | 46 +++++++++ templates/compose/owncloud.yaml | 73 ++++++++++++++ templates/compose/plausible.yaml | 4 +- templates/compose/qbittorrent.yaml | 48 +++++++++ templates/compose/traccar.yaml | 50 ++++++++++ templates/compose/unsend.yaml | 60 ++++++++++++ templates/compose/vvveb-with-mariadb.yaml | 41 ++++++++ templates/compose/vvveb-with-mysql.yaml | 41 ++++++++ templates/compose/vvveb.yaml | 18 ++++ versions.json | 5 +- 45 files changed, 1502 insertions(+), 16 deletions(-) create mode 100644 public/svgs/affine.svg create mode 100644 public/svgs/cloudbeaver.svg create mode 100644 public/svgs/cryptgeon.png create mode 100644 public/svgs/flowise.png create mode 100644 public/svgs/freshrss.png create mode 100644 public/svgs/homebox.svg create mode 100644 public/svgs/immich.svg create mode 100644 public/svgs/kimai.svg create mode 100644 public/svgs/libretranslate.svg create mode 100644 public/svgs/ntfy.svg create mode 100644 public/svgs/owncloud.svg create mode 100644 public/svgs/qbittorrent.svg create mode 100644 public/svgs/traccar.png create mode 100644 public/svgs/unsend.svg create mode 100644 public/svgs/vvveb.svg create mode 100644 templates/compose/affine.yaml create mode 100644 templates/compose/cloudbeaver.yaml create mode 100644 templates/compose/cryptgeon.yaml create mode 100644 templates/compose/flowise-with-databases.yaml create mode 100644 templates/compose/flowise.yaml create mode 100644 templates/compose/freshrss-with-mariadb.yaml create mode 100644 templates/compose/freshrss-with-mysql.yaml create mode 100644 templates/compose/freshrss-with-postgresql.yaml create mode 100644 templates/compose/freshrss.yaml create mode 100644 templates/compose/homebox.yaml create mode 100644 templates/compose/immich.yaml create mode 100644 templates/compose/kimai.yaml create mode 100644 templates/compose/libretranslate.yaml create mode 100644 templates/compose/nextcloud-with-mariadb.yaml create mode 100644 templates/compose/nextcloud-with-mysql.yaml create mode 100644 templates/compose/nextcloud-with-postgres.yaml create mode 100644 templates/compose/ntfy.yaml create mode 100644 templates/compose/owncloud.yaml create mode 100644 templates/compose/qbittorrent.yaml create mode 100644 templates/compose/traccar.yaml create mode 100644 templates/compose/unsend.yaml create mode 100644 templates/compose/vvveb-with-mariadb.yaml create mode 100644 templates/compose/vvveb-with-mysql.yaml create mode 100644 templates/compose/vvveb.yaml diff --git a/config/sentry.php b/config/sentry.php index b7e230e71..2fed52ef0 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -8,7 +8,6 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) 'release' => '4.0.0-beta.358', - // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index a89343eb9..82b1479af 100644 --- a/config/version.php +++ b/config/version.php @@ -1,4 +1,3 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/svgs/cloudbeaver.svg b/public/svgs/cloudbeaver.svg new file mode 100644 index 000000000..4a7634766 --- /dev/null +++ b/public/svgs/cloudbeaver.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/public/svgs/cryptgeon.png b/public/svgs/cryptgeon.png new file mode 100644 index 0000000000000000000000000000000000000000..be121cfd082f63e4599a0a5ad11577a0d959c0a1 GIT binary patch literal 77470 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 Y4s7b#`uKB?akabW?e0se+#YuP|4}xp9RL6T literal 0 HcmV?d00001 diff --git a/public/svgs/flowise.png b/public/svgs/flowise.png new file mode 100644 index 0000000000000000000000000000000000000000..6b0be0d2a7f4fbffb3f9eea9f938f8c3460c0b7a GIT binary patch literal 7230 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 VHBCY=|9rtaTI%|0wW_b9{|7Qx<|P0C literal 0 HcmV?d00001 diff --git a/public/svgs/freshrss.png b/public/svgs/freshrss.png new file mode 100644 index 0000000000000000000000000000000000000000..d1a75118f93d05313314f65764102669bafc4566 GIT binary patch literal 14801 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 + + + + + + + + + + diff --git a/public/svgs/immich.svg b/public/svgs/immich.svg new file mode 100644 index 000000000..9d844a772 --- /dev/null +++ b/public/svgs/immich.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/public/svgs/kimai.svg b/public/svgs/kimai.svg new file mode 100644 index 000000000..35b146972 --- /dev/null +++ b/public/svgs/kimai.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/svgs/libretranslate.svg b/public/svgs/libretranslate.svg new file mode 100644 index 000000000..103d47d60 --- /dev/null +++ b/public/svgs/libretranslate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/svgs/ntfy.svg b/public/svgs/ntfy.svg new file mode 100644 index 000000000..9e5b5136f --- /dev/null +++ b/public/svgs/ntfy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/svgs/owncloud.svg b/public/svgs/owncloud.svg new file mode 100644 index 000000000..83631e3f5 --- /dev/null +++ b/public/svgs/owncloud.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/svgs/qbittorrent.svg b/public/svgs/qbittorrent.svg new file mode 100644 index 000000000..69d8cf62a --- /dev/null +++ b/public/svgs/qbittorrent.svg @@ -0,0 +1,16 @@ + + + qbittorrent-new-light + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/svgs/traccar.png b/public/svgs/traccar.png new file mode 100644 index 0000000000000000000000000000000000000000..c747aea05407bc78019b28dbb5cec82ac73f872c GIT binary patch literal 22009 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 F{{m9gF)#oC literal 0 HcmV?d00001 diff --git a/public/svgs/unsend.svg b/public/svgs/unsend.svg new file mode 100644 index 000000000..f5ff6fabc --- /dev/null +++ b/public/svgs/unsend.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/svgs/vvveb.svg b/public/svgs/vvveb.svg new file mode 100644 index 000000000..2b66b3087 --- /dev/null +++ b/public/svgs/vvveb.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/compose/affine.yaml b/templates/compose/affine.yaml new file mode 100644 index 000000000..97be09cdb --- /dev/null +++ b/templates/compose/affine.yaml @@ -0,0 +1,75 @@ +# documentation: https://docs.affine.pro/docs/self-host-affine +# slogan: Affine is an open-source, all-in-one workspace and OS for knowledge management, a Notion/Miro alternative. +# tags: knowledge-management,notion,miro,workspace +# logo: svgs/affine.svg +# port: 3010 + +services: + affine: + image: ghcr.io/toeverything/affine-graphql:stable + command: + - sh + - '-c' + - 'node ./scripts/self-host-predeploy && node ./dist/index.js' + depends_on: + redis: + condition: service_healthy + postgres: + condition: service_healthy + volumes: + - affine-config:/root/.affine/config + - affine-storage:/root/.affine/storage + logging: + driver: json-file + options: + max-size: 1000m + environment: + - SERVICE_FQDN_AFFINE_3010 + - NODE_OPTIONS=--import=./scripts/register.js + - AFFINE_CONFIG_PATH=/root/.affine/config + - REDIS_SERVER_HOST=redis + - DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-affine} + - NODE_ENV=production + - AFFINE_SERVER_HOST=$SERVICE_FQDN_AFFINE + - AFFINE_SERVER_EXTERNAL_URL=$SERVICE_FQDN_AFFINE + - MAILER_HOST=${MAILER_HOST} + - MAILER_PORT=${MAILER_PORT} + - MAILER_USER=${MAILER_USER} + - MAILER_PASSWORD=${MAILER_PASSWORD} + - MAILER_SENDER=${MAILER_SENDER} + healthcheck: + test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/3010' || exit 1"] + interval: 5s + timeout: 20s + retries: 3 + + redis: + image: redis + volumes: + - affine-redis-data:/data + healthcheck: + test: + - CMD + - redis-cli + - '--raw' + - incr + - ping + interval: 10s + timeout: 5s + retries: 5 + postgres: + image: postgres:16 + volumes: + - affine-postgres-data:/var/lib/postgresql/data + healthcheck: + test: + - CMD-SHELL + - 'pg_isready -U affine' + interval: 10s + timeout: 5s + retries: 5 + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-affine} + - PGDATA=/var/lib/postgresql/data/pgdata diff --git a/templates/compose/cloudbeaver.yaml b/templates/compose/cloudbeaver.yaml new file mode 100644 index 000000000..a21b00453 --- /dev/null +++ b/templates/compose/cloudbeaver.yaml @@ -0,0 +1,18 @@ +# documentation: https://dbeaver.com/docs/cloudbeaver/ +# slogan: CloudBeaver is a lightweight web application designed for comprehensive data management. +# tags: dbeaver, data management, data, database, mysql, postgres, sqlite, sql, mongodb +# logo: svgs/cloudbeaver.svg +# port: 8978 + +services: + cloudbeaver: + image: dbeaver/cloudbeaver:24 + volumes: + - cloudbeaver-data:/opt/cloudbeaver/workspace + environment: + - SERVICE_FQDN_CLOUDBEAVER_8978 + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:8978/"] + interval: 5s + timeout: 20s + retries: 10 diff --git a/templates/compose/cryptgeon.yaml b/templates/compose/cryptgeon.yaml new file mode 100644 index 000000000..942b1601c --- /dev/null +++ b/templates/compose/cryptgeon.yaml @@ -0,0 +1,41 @@ +# documentation: https://github.com/cupcakearmy/cryptgeon +# slogan: Secure note / file sharing service inspired by PrivNote. +# tags: cryptgeon, secure, note, sharing, privnote, file, sharing +# logo: svgs/cryptgeon.png +# port: 8000 + +services: + app: + image: cupcakearmy/cryptgeon:latest + environment: + - SERVICE_FQDN_CRYPTGEON_8000 + - SIZE_LIMIT=${SIZE_LIMIT:-4 MiB} + - MAX_VIEWS=${MAX_VIEWS:-100} + - MAX_EXPIRATION=${MAX_EXPIRATION:-360} + - ALLOW_ADVANCED=${ALLOW_ADVANCED:-true} + - ALLOW_FILES=${ALLOW_FILES:-true} + depends_on: + redis: + condition: service_healthy + healthcheck: + test: + - CMD + - curl + - "--fail" + - "http://127.0.0.1:8000/api/live/" + interval: 1m + timeout: 3s + retries: 2 + start_period: 5s + + redis: + image: redis:7-alpine + command: "redis-server --maxmemory 200mb --maxmemory-policy allkeys-lru" + healthcheck: + test: + - CMD + - redis-cli + - PING + interval: 5s + timeout: 10s + retries: 2 diff --git a/templates/compose/flowise-with-databases.yaml b/templates/compose/flowise-with-databases.yaml new file mode 100644 index 000000000..d78079b62 --- /dev/null +++ b/templates/compose/flowise-with-databases.yaml @@ -0,0 +1,91 @@ +# documentation: https://docs.flowiseai.com/ +# slogan: Flowise is an open source low-code tool for developers to build customized LLM orchestration flows & AI agents. Also deploys Redis, Postgres and other services. +# tags: lowcode, nocode, ai, llm, openai, anthropic, machine-learning, rag, agents, chatbot, api, team, bot, flows +# logo: svgs/flowise.png +# port: 3001 + +volumes: + flowise_data: + pg_record_manager_data: + redis_cache_data: + qdrant_data: + +services: + flowise: + image: flowiseai/flowise + restart: always + depends_on: + pg_record_manager: + condition: service_healthy + redis_cache: + condition: service_healthy + qdrant: + condition: service_healthy + environment: + - SERVICE_FQDN_FLOWISE_3001 + - DEBUG=false + - DISABLE_FLOWISE_TELEMETRY=true + - PORT=3001 + - DATABASE_PATH=/root/.flowise + - APIKEY_PATH=/root/.flowise + - SECRETKEY_PATH=/root/.flowise + - LOG_PATH=/root/.flowise/logs + - BLOB_STORAGE_PATH=/root/.flowise/storage + - FLOWISE_USERNAME=${SERVICE_USER_FLOWISE} + - FLOWISE_PASSWORD=${SERVICE_PASSWORD_FLOWISE} + volumes: + - flowise_data:/root/.flowise + healthcheck: + test: + - CMD-SHELL + - wget + - --no-verbose + - --tries=1 + - --spider + - http://localhost:3001 + interval: 5s + timeout: 5s + retries: 3 + pg_record_manager: + image: "postgres:16" + restart: always + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-record_manager} + volumes: + - pg_record_manager_data:/var/lib/postgresql/data + healthcheck: + test: + - CMD-SHELL + - "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}" + interval: 5s + timeout: 5s + retries: 3 + redis_cache: + image: "redis:7" + restart: always + volumes: + - redis_cache_data:/data + healthcheck: + test: + - CMD-SHELL + - "redis-cli -h localhost -p 6379 ping" + interval: 5s + timeout: 5s + retries: 3 + qdrant: + image: "qdrant/qdrant:latest" + restart: always + environment: + - SERVICE_FQDN_QDRANT_6333 + - QDRANT__SERVICE__API_KEY=${SERVICE_PASSWORD_QDRANTAPIKEY} + volumes: + - "qdrant_data:/qdrant/storage" + healthcheck: + test: + - CMD-SHELL + - bash -c ':> /dev/tcp/127.0.0.1/6333' || exit 1 + interval: 5s + timeout: 5s + retries: 3 diff --git a/templates/compose/flowise.yaml b/templates/compose/flowise.yaml new file mode 100644 index 000000000..dc5095e1e --- /dev/null +++ b/templates/compose/flowise.yaml @@ -0,0 +1,35 @@ +# documentation: https://docs.flowiseai.com/ +# slogan: Flowise is an open source low-code tool for developers to build customized LLM orchestration flows & AI agents. +# tags: lowcode, nocode, ai, llm, openai, anthropic, machine-learning, rag, agents, chatbot, api, team, bot, flows +# logo: svgs/flowise.png +# port: 3001 + +services: + flowise: + image: flowiseai/flowise + restart: always + environment: + - SERVICE_FQDN_FLOWISE_3001 + - DEBUG=false + - DISABLE_FLOWISE_TELEMETRY=true + - PORT=3001 + - DATABASE_PATH=/root/.flowise + - APIKEY_PATH=/root/.flowise + - SECRETKEY_PATH=/root/.flowise + - LOG_PATH=/root/.flowise/logs + - BLOB_STORAGE_PATH=/root/.flowise/storage + - FLOWISE_USERNAME=${SERVICE_USER_FLOWISE} + - FLOWISE_PASSWORD=${SERVICE_PASSWORD_FLOWISE} + volumes: + - flowise_data:/root/.flowise + healthcheck: + test: + - CMD-SHELL + - wget + - --no-verbose + - --tries=1 + - --spide + - http://localhost:3001 + interval: 5s + timeout: 5s + retries: 3 diff --git a/templates/compose/freshrss-with-mariadb.yaml b/templates/compose/freshrss-with-mariadb.yaml new file mode 100644 index 000000000..fe066ffb6 --- /dev/null +++ b/templates/compose/freshrss-with-mariadb.yaml @@ -0,0 +1,41 @@ +# documentation: https://freshrss.org/index.html +# slogan: A free, self-hostable feed aggregator. +# tags: rss, feed +# logo: svgs/freshrss.png +# port: 80 + +services: + freshrss: + image: freshrss/freshrss:latest + environment: + - SERVICE_FQDN_FRESHRSS_80 + - CRON_MIN=${CRON_MIN:-1,31} + - MARIADB_DB=${MARIADB_DATABASE:-freshrss} + - MARIADB_USER=${SERVICE_USER_MARIADB} + - MARIADB_PASSWORD=${SERVICE_PASSWORD_MARIADB} + volumes: + - freshrss-data:/var/www/FreshRSS/data + - freshrss-extensions:/var/www/FreshRSS/extensions + depends_on: + freshrss-db: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/80' || exit 1"] + interval: 5s + timeout: 20s + retries: 3 + + freshrss-db: + image: mariadb:11 + volumes: + - mariadb-data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=$SERVICE_PASSWORD_ROOT + - MYSQL_DATABASE=${MARIADB_DATABASE:-freshrss} + - MYSQL_USER=${SERVICE_USER_MARIADB} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MARIADB} + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + interval: 5s + timeout: 20s + retries: 10 diff --git a/templates/compose/freshrss-with-mysql.yaml b/templates/compose/freshrss-with-mysql.yaml new file mode 100644 index 000000000..ca3726a12 --- /dev/null +++ b/templates/compose/freshrss-with-mysql.yaml @@ -0,0 +1,41 @@ +# documentation: https://freshrss.org/index.html +# slogan: A free, self-hostable feed aggregator. +# tags: rss, feed +# logo: svgs/freshrss.png +# port: 80 + +services: + freshrss: + image: freshrss/freshrss:latest + environment: + - SERVICE_FQDN_FRESHRSS_80 + - CRON_MIN=${CRON_MIN:-1,31} + - MYSQL_DB=${MYSQL_DATABASE:-freshrss} + - MYSQL_USER=${SERVICE_USER_MYSQL} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL} + volumes: + - freshrss-data:/var/www/FreshRSS/data + - freshrss-extensions:/var/www/FreshRSS/extensions + depends_on: + freshrss-db: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/80' || exit 1"] + interval: 5s + timeout: 20s + retries: 3 + + freshrss-db: + image: mysql:8 + volumes: + - mysql-data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=$SERVICE_PASSWORD_ROOT + - MYSQL_DATABASE=${MYSQL_DATABASE:-freshrss} + - MYSQL_USER=$SERVICE_USER_MYSQL + - MYSQL_PASSWORD=$SERVICE_PASSWORD_MYSQL + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"] + interval: 5s + timeout: 20s + retries: 10 diff --git a/templates/compose/freshrss-with-postgresql.yaml b/templates/compose/freshrss-with-postgresql.yaml new file mode 100644 index 000000000..8928dfd56 --- /dev/null +++ b/templates/compose/freshrss-with-postgresql.yaml @@ -0,0 +1,41 @@ +# documentation: https://freshrss.org/index.html +# slogan: A free, self-hostable feed aggregator. +# tags: rss, feed +# logo: svgs/freshrss.png +# port: 80 + +services: + freshrss: + image: freshrss/freshrss:latest + environment: + - SERVICE_FQDN_FRESHRSS_80 + - CRON_MIN=${CRON_MIN:-1,31} + - POSTGRES_DB=${POSTGRESQL_DATABASE:-freshrss} + - POSTGRES_USER=${SERVICE_USER_POSTGRESQL} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL} + - POSTGRES_HOST=postgresql + volumes: + - freshrss-data:/var/www/FreshRSS/data + - freshrss-extensions:/var/www/FreshRSS/extensions + depends_on: + freshrss-db: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/80' || exit 1"] + interval: 5s + timeout: 20s + retries: 3 + + freshrss-db: + image: postgres:16 + volumes: + - freshrss-postgresql-data:/var/lib/postgresql/data + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRESQL} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL} + - POSTGRES_DB=${POSTGRESQL_DATABASE:-freshrss} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 diff --git a/templates/compose/freshrss.yaml b/templates/compose/freshrss.yaml new file mode 100644 index 000000000..c481b96d4 --- /dev/null +++ b/templates/compose/freshrss.yaml @@ -0,0 +1,20 @@ +# documentation: https://freshrss.org/index.html +# slogan: A free, self-hostable feed aggregator. +# tags: rss, feed +# logo: svgs/freshrss.png +# port: 80 + +services: + freshrss: + image: freshrss/freshrss:latest + environment: + - SERVICE_FQDN_FRESHRSS_80 + - CRON_MIN=${CRON_MIN:-1,31} + volumes: + - freshrss-data:/var/www/FreshRSS/data + - freshrss-extensions:/var/www/FreshRSS/extensions + healthcheck: + test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/80' || exit 1"] + interval: 5s + timeout: 20s + retries: 3 diff --git a/templates/compose/glitchtip.yaml b/templates/compose/glitchtip.yaml index a8e4848b0..2f0b0100c 100644 --- a/templates/compose/glitchtip.yaml +++ b/templates/compose/glitchtip.yaml @@ -12,12 +12,13 @@ services: - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL} - POSTGRES_DB=${POSTGRESQL_DATABASE:-glitchtip} volumes: - - pg-data:/var/lib/postgresql/data + - glitchtip-postgres-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 20s retries: 10 + redis: image: redis healthcheck: @@ -25,11 +26,14 @@ services: interval: 5s timeout: 20s retries: 10 + web: image: glitchtip/glitchtip depends_on: - - postgres - - redis + postgres: + condition: service_healthy + redis: + condition: service_healthy environment: - SERVICE_FQDN_GLITCHTIP_8080 - DATABASE_URL=postgres://$SERVICE_USER_POSTGRESQL:$SERVICE_PASSWORD_POSTGRESQL@postgres:5432/${POSTGRESQL_DATABASE:-glitchtip} @@ -46,14 +50,16 @@ services: interval: 5s timeout: 20s retries: 10 + worker: image: glitchtip/glitchtip command: ./bin/run-celery-with-beat.sh depends_on: - - postgres - - redis + postgres: + condition: service_healthy + redis: + condition: service_healthy environment: - - SERVICE_FQDN_GLITCHTIP - DATABASE_URL=postgres://$SERVICE_USER_POSTGRESQL:$SERVICE_PASSWORD_POSTGRESQL@postgres:5432/${POSTGRESQL_DATABASE:-glitchtip} - SECRET_KEY=$SERVICE_BASE64_64_ENCRYPTION - EMAIL_URL=${EMAIL_URL:-consolemail://} @@ -68,12 +74,15 @@ services: interval: 5s timeout: 20s retries: 10 + migrate: image: glitchtip/glitchtip restart: "no" depends_on: - - postgres - - redis + postgres: + condition: service_healthy + redis: + condition: service_healthy command: "./manage.py migrate" environment: - DATABASE_URL=postgres://$SERVICE_USER_POSTGRESQL:$SERVICE_PASSWORD_POSTGRESQL@postgres:5432/${POSTGRESQL_DATABASE:-glitchtip} diff --git a/templates/compose/homebox.yaml b/templates/compose/homebox.yaml new file mode 100644 index 000000000..f7c09ed31 --- /dev/null +++ b/templates/compose/homebox.yaml @@ -0,0 +1,21 @@ +# documentation: https://github.com/hay-kot/homebox +# slogan: Homebox is a self-hosted file management solution. +# tags: homebox,file-management,self-hosted +# logo: svgs/homebox.svg +# port: 7745 + +services: + homebox: + image: ghcr.io/hay-kot/homebox:latest + environment: + - SERVICE_FQDN_HOMEBOX_7745 + - HBOX_LOG_LEVEL=${HBOX_LOG_LEVEL:-info} + - HBOX_LOG_FORMAT=${HBOX_LOG_FORMAT:-text} + - HBOX_WEB_MAX_UPLOAD_SIZE=${HBOX_WEB_MAX_UPLOAD_SIZE:-10} + volumes: + - homebox-data:/data/ + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:7745"] + interval: 5s + timeout: 20s + retries: 10 diff --git a/templates/compose/immich.yaml b/templates/compose/immich.yaml new file mode 100644 index 000000000..b3525cc58 --- /dev/null +++ b/templates/compose/immich.yaml @@ -0,0 +1,76 @@ +# documentation: https://immich.app/docs/overview/introduction +# slogan: Self-hosted photo and video management solution. +# tags: photo,video,management,server,cloud,storage,sharing,metadata,face,recognition +# logo: svgs/immich.svg +# port: 2283 + +services: + immich: + image: ghcr.io/immich-app/immich-server:release + # extends: + # file: hwaccel.transcoding.yml + # service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding + volumes: + - immich-uploads:/usr/src/app/upload + - /etc/localtime:/etc/localtime:ro + environment: + - SERVICE_FQDN_IMMICH_3001 + - UPLOAD_LOCATION=./library + - DB_DATA_LOCATION=./postgres + - DB_PASSWORD=$SERVICE_PASSWORD_POSTGRES + - DB_USERNAME=$SERVICE_USER_POSTGRES + - DB_DATABASE_NAME=${DB_DATABASE_NAME:-immich} + - TZ=${TZ:-Etc/UTC} + depends_on: + redis: + condition: service_healthy + database: + condition: service_healthy + healthcheck: + disable: false + + immich-machine-learning: + container_name: immich_machine_learning + # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag. + # Example tag: ${IMMICH_VERSION:-release}-cuda + image: ghcr.io/immich-app/immich-machine-learning:release + # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration + # file: hwaccel.ml.yml + # service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable + volumes: + - immich-model-cache:/cache + environment: + - UPLOAD_LOCATION=./library + - DB_DATA_LOCATION=./postgres + - DB_PASSWORD=$SERVICE_PASSWORD_POSTGRES + - DB_USERNAME=$SERVICE_USER_POSTGRES + - DB_DATABASE_NAME=${DB_DATABASE_NAME:-immich} + - TZ=${TZ:-Etc/UTC} + healthcheck: + disable: false + + redis: + image: redis:7.4-alpine + healthcheck: + test: + - CMD + - redis-cli + - PING + interval: 5s + timeout: 10s + retries: 20 + + database: + image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 + environment: + POSTGRES_PASSWORD: ${SERVICE_PASSWORD_POSTGRES} + POSTGRES_USER: ${SERVICE_USER_POSTGRES} + POSTGRES_DB: ${DB_DATABASE_NAME:-immich} + POSTGRES_INITDB_ARGS: '--data-checksums' + volumes: + - immich-postgres-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 diff --git a/templates/compose/kimai.yaml b/templates/compose/kimai.yaml new file mode 100644 index 000000000..ba73ba980 --- /dev/null +++ b/templates/compose/kimai.yaml @@ -0,0 +1,44 @@ +# documentation: https://www.kimai.org/ +# slogan: Open source time-tracking app. +# tags: time-tracking, open-source +# logo: svgs/kimai.svg +# port: 8001 + +services: + mysql: + image: mysql:8 + volumes: + - kimai-mysql-data:/var/lib/mysql + environment: + - MYSQL_DATABASE=${MYSQL_DATABASE:-kimai} + - MYSQL_USER=${SERVICE_USER_MYSQL} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL} + - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_ROOT} + command: --default-storage-engine innodb + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"] + interval: 5s + timeout: 20s + retries: 10 + kimai: + image: kimai/kimai2:apache-latest + container_name: kimai + depends_on: + mysql: + condition: service_healthy + volumes: + - kimai-data:/opt/kimai/var/data + environment: + - SERVICE_FQDN_KIMAI_8001 + - APP_SECRET=${SERVICE_PASSWORD_APPSECRET} + - MAILER_FROM=${MAILER_FROM:-kimai@example.com} + - MAILER_URL=${MAILER_URL:-null://null} + - ADMINMAIL=${ADMINMAIL:-admin@kimai.local} + - ADMINPASS=${SERVICE_PASSWORD_ADMINPASS} + - DATABASE_URL=mysql://${SERVICE_USER_MYSQL}:${SERVICE_PASSWORD_MYSQL}@mysql/${MYSQL_DATABASE}?charset=utf8mb4&serverVersion=8.3.0 + - TRUSTED_HOSTS=localhost + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1:8001"] + interval: 2s + timeout: 10s + retries: 15 diff --git a/templates/compose/libretranslate.yaml b/templates/compose/libretranslate.yaml new file mode 100644 index 000000000..69b9e4466 --- /dev/null +++ b/templates/compose/libretranslate.yaml @@ -0,0 +1,19 @@ +# documentation: https://libretranslate.com/docs/ +# slogan: Free and open-source machine translation API, entirely self-hosted. +# tags: translate, api +# logo: svgs/libretranslate.svg +# port: 5000 + +services: + libretranslate: + image: "libretranslate/libretranslate:latest" + environment: + - SERVICE_FQDN_LIBRETRANSLATE_5000 + - LT_SSL=true + - LT_UPDATE_MODELS=true + - LT_LOAD_ONLY=en,es,fr,de,ja + volumes: + - api-keys:/app/db + - models:/home/libretranslate/.local + healthcheck: + test: ["CMD-SHELL", "./venv/bin/python scripts/healthcheck.py"] diff --git a/templates/compose/nextcloud-with-mariadb.yaml b/templates/compose/nextcloud-with-mariadb.yaml new file mode 100644 index 000000000..5cab4f0bb --- /dev/null +++ b/templates/compose/nextcloud-with-mariadb.yaml @@ -0,0 +1,61 @@ +# documentation: https://docs.nextcloud.com +# slogan: NextCloud is a self-hosted, open-source platform that provides file storage, collaboration, and communication tools for seamless data management. +# tags: cloud, collaboration, communication, filestorage, data +# logo: svgs/nextcloud.svg +# port: 80 + +services: + nextcloud: + image: lscr.io/linuxserver/nextcloud:latest + environment: + - SERVICE_FQDN_NEXTCLOUD_80 + - PUID=1000 + - PGID=1000 + - TZ=${TZ:-Europe/Paris} + - MYSQL_DATABASE=${MARIADB_DATABASE:-nextcloud} + - MYSQL_USER=${SERVICE_USER_MARIADB} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MARIADB} + - MYSQL_HOST=nextcloud-db + - REDIS_HOST=redis + - REDIS_PORT=6379 + volumes: + - nextcloud-config:/config + - nextcloud-data:/data + depends_on: + nextcloud-db: + condition: service_healthy + redis: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1:80"] + interval: 2s + timeout: 10s + retries: 15 + + nextcloud-db: + image: mariadb:11 + volumes: + - nextcloud-mariadb-data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_ROOT} + - MYSQL_DATABASE=${MARIADB_DATABASE:-nextcloud} + - MYSQL_USER=${SERVICE_USER_MARIADB} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MARIADB} + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + interval: 5s + timeout: 20s + retries: 10 + + redis: + image: "redis:7.4-alpine" + volumes: + - "nextcloud-redis-data:/data" + healthcheck: + test: + - CMD + - redis-cli + - PING + interval: 5s + timeout: 10s + retries: 20 diff --git a/templates/compose/nextcloud-with-mysql.yaml b/templates/compose/nextcloud-with-mysql.yaml new file mode 100644 index 000000000..f8f6b972f --- /dev/null +++ b/templates/compose/nextcloud-with-mysql.yaml @@ -0,0 +1,61 @@ +# documentation: https://docs.nextcloud.com +# slogan: NextCloud is a self-hosted, open-source platform that provides file storage, collaboration, and communication tools for seamless data management. +# tags: cloud, collaboration, communication, filestorage, data +# logo: svgs/nextcloud.svg +# port: 80 + +services: + nextcloud: + image: lscr.io/linuxserver/nextcloud:latest + environment: + - SERVICE_FQDN_NEXTCLOUD_80 + - PUID=1000 + - PGID=1000 + - TZ=${TZ:-Europe/Paris} + - MYSQL_DATABASE=${MYSQL_DATABASE:-nextcloud} + - MYSQL_USER=${SERVICE_USER_MYSQL} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL} + - MYSQL_HOST=nextcloud-db + - REDIS_HOST=redis + - REDIS_PORT=6379 + volumes: + - nextcloud-config:/config + - nextcloud-data:/data + depends_on: + nextcloud-db: + condition: service_healthy + redis: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1:80"] + interval: 2s + timeout: 10s + retries: 15 + + nextcloud-db: + image: mysql:8.4.2 + volumes: + - nextcloud-mysql-data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_ROOT} + - MYSQL_DATABASE=${MYSQL_DATABASE:-nextcloud} + - MYSQL_USER=${SERVICE_USER_MYSQL} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL} + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"] + interval: 5s + timeout: 20s + retries: 10 + + redis: + image: "redis:7.4-alpine" + volumes: + - "nextcloud-redis-data:/data" + healthcheck: + test: + - CMD + - redis-cli + - PING + interval: 5s + timeout: 10s + retries: 20 diff --git a/templates/compose/nextcloud-with-postgres.yaml b/templates/compose/nextcloud-with-postgres.yaml new file mode 100644 index 000000000..503fb4b82 --- /dev/null +++ b/templates/compose/nextcloud-with-postgres.yaml @@ -0,0 +1,60 @@ +# documentation: https://docs.nextcloud.com +# slogan: NextCloud is a self-hosted, open-source platform that provides file storage, collaboration, and communication tools for seamless data management. +# tags: cloud, collaboration, communication, filestorage, data +# logo: svgs/nextcloud.svg +# port: 80 + +services: + nextcloud: + image: lscr.io/linuxserver/nextcloud:latest + environment: + - SERVICE_FQDN_NEXTCLOUD_80 + - PUID=1000 + - PGID=1000 + - TZ=${TZ:-Europe/Paris} + - POSTGRES_DB=${POSTGRES_DB:-nextcloud} + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_HOST=nextcloud-db + - REDIS_HOST=redis + - REDIS_PORT=6379 + volumes: + - nextcloud-config:/config + - nextcloud-data:/data + depends_on: + nextcloud-db: + condition: service_healthy + redis: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1:80"] + interval: 2s + timeout: 10s + retries: 15 + + nextcloud-db: + image: postgres:16-alpine + volumes: + - nextcloud-postgresql-data:/var/lib/postgresql/data + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-nextcloud} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 + + redis: + image: "redis:7.4-alpine" + volumes: + - "nextcloud-redis-data:/data" + healthcheck: + test: + - CMD + - redis-cli + - PING + interval: 5s + timeout: 10s + retries: 20 diff --git a/templates/compose/nextcloud.yaml b/templates/compose/nextcloud.yaml index 33858ee15..d0b2c2a59 100644 --- a/templates/compose/nextcloud.yaml +++ b/templates/compose/nextcloud.yaml @@ -2,15 +2,16 @@ # slogan: NextCloud is a self-hosted, open-source platform that provides file storage, collaboration, and communication tools for seamless data management. # tags: cloud, collaboration, communication, filestorage, data # logo: svgs/nextcloud.svg +# port: 80 services: nextcloud: image: lscr.io/linuxserver/nextcloud:latest environment: - - SERVICE_FQDN_NEXTCLOUD + - SERVICE_FQDN_NEXTCLOUD_80 - PUID=1000 - PGID=1000 - - TZ=Europe/Madrid + - TZ=${TZ:-Europe/Madrid} volumes: - nextcloud-config:/config - nextcloud-data:/data diff --git a/templates/compose/ntfy.yaml b/templates/compose/ntfy.yaml new file mode 100644 index 000000000..47b66a124 --- /dev/null +++ b/templates/compose/ntfy.yaml @@ -0,0 +1,46 @@ +# documentation: https://docs.ntfy.sh/ +# slogan: ntfy is a simple HTTP-based pub-sub notification service. It allows you to send notifications to your phone or desktop via scripts from any computer, and/or using a REST API. +# tags: ntfy, notification, push notification, pub-sub, notify +# logo: svgs/ntfy.svg +# port: 80 + +services: + ntfy: + image: binwiederhier/ntfy + command: + - serve + environment: + - SERVICE_FQDN_NTFY_80 + - NTFY_BASE_URL=${SERVICE_FQDN_NTFY} + - TZ=${TZ:-UTC} + - NTFY_CACHE_FILE=/var/cache/ntfy/cache.db + - NTFY_AUTH_FILE=/var/lib/ntfy/auth.db + - NTFY_UPSTREAM_BASE_URL=${UPSTREAM_BASE_URL:-https://ntfy.sh} + - NTFY_ENABLE_SIGNUP=${NTFY_ENABLE_SIGNUP:-true} + - NTFY_ENABLE_LOGIN=${NTFY_ENABLE_LOGIN:-true} + - NTFY_CACHE_DURATION=${NTFY_CACHE_DURATION:-24h} + - NTFY_ATTACHMENT_TOTAL_SIZE_LIMIT=${NTFY_ATTACHMENT_TOTAL_SIZE_LIMIT:-1G} + - NTFY_ATTACHMENT_FILE_SIZE_LIMIT=${NTFY_ATTACHMENT_FILE_SIZE_LIMIT:-10M} + - NTFY_ATTACHMENT_EXPIRY_DURATION=${NTFY_ATTACHMENT_EXPIRY_DURATION:-24h} + - NTFY_SMTP_SENDER_ADDR=${NTFY_SMTP_SENDER_ADDR:-smtp.your-domain.de} + - NTFY_SMTP_SENDER_USER=${NTFY_SMTP_SENDER_USER:-no-reply@de} + - NTFY_SMTP_SENDER_PASS=${NTFY_SMTP_SENDER_PASS:-password} + - NTFY_SMTP_SENDER_FROM=${NTFY_SMTP_SENDER_FROM:-no-reply@de} + - NTFY_KEEPALIVE_INTERVAL=${NTFY_KEEPALIVE_INTERVAL:-5m} + - NTFY_MANAGER_INTERVAL=${NTFY_MANAGER_INTERVAL:-5m} + - NTFY_VISITOR_MESSAGE_DAILY_LIMIT=${NTFY_VISITOR_MESSAGE_DAILY_LIMIT:-100} + - NTFY_VISITOR_ATTACHMENT_DAILY_BANDWIDTH_LIMIT=${NTFY_VISITOR_ATTACHMENT_DAILY_BANDWIDTH_LIMIT:-1G} + - NTFY_UPSTREAM_ACCESS_TOKEN=${UPSTREAM_ACCESS_TOKEN} + - NTFY_AUTH_DEFAULT_ACCESS=${NTFY_AUTH_DEFAULT_ACCESS:-read-write} + - NTFY_WEB_PUSH_PUBLIC_KEY=${NTFY_WEB_PUSH_PUBLIC_KEY} + - NTFY_WEB_PUSH_PRIVATE_KEY=${NTFY_WEB_PUSH_PRIVATE_KEY} + - NTFY_WEB_PUSH_EMAIL_ADDRESS=${NTFY_WEB_PUSH_EMAIL_ADDRESS} + volumes: + - ntfy-cache:/var/cache/ntfy + - ntfy-db:/var/lib/ntfy/ + healthcheck: + test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:80/v1/health -O - | grep -Eo '\"healthy\"\\s*:\\s*true' || exit 1"] + interval: 60s + timeout: 10s + retries: 3 + start_period: 40s diff --git a/templates/compose/owncloud.yaml b/templates/compose/owncloud.yaml new file mode 100644 index 000000000..6c29ddbe7 --- /dev/null +++ b/templates/compose/owncloud.yaml @@ -0,0 +1,73 @@ +# ignore: true +# documentation: https://owncloud.com/docs +# slogan: OwnCloud with Open Web UI integrates file management with a powerful, user-friendly interface. +# tags: owncloud,file-management,open-web-ui,integration,cloud +# logo: svgs/owncloud.svg +# port: 8080 + +services: + owncloud: + image: owncloud/server:latest + depends_on: + mariadb: + condition: service_healthy + redis: + condition: service_healthy + environment: + - SERVICE_FQDN_OWNCLOUD_8080 + - OWNCLOUD_DOMAIN=${SERVICE_FQDN_OWNCLOUD} + - OWNCLOUD_TRUSTED_DOMAINS=${SERVICE_FQDN_OWNCLOUD} # This is a comma separated list of domains that are trusted by the server (No Protocol) + - OWNCLOUD_DB_TYPE=mysql + - OWNCLOUD_DB_HOST=mariadb + - OWNCLOUD_DB_NAME=${DB_NAME:-owncloud} + - OWNCLOUD_DB_USERNAME=${SERVICE_USER_MARIADB} + - OWNCLOUD_DB_PASSWORD=${SERVICE_PASSWORD_MARIADB} + - OWNCLOUD_ADMIN_USERNAME=${SERVICE_USER_OWNCLOUD} + - OWNCLOUD_ADMIN_PASSWORD=${SERVICE_PASSWORD_OWNCLOUD} + - OWNCLOUD_MYSQL_UTF8MB4=${MYSQL_UTF8MB4:-true} + - OWNCLOUD_REDIS_ENABLED=${REDIS_ENABLED:-true} + - OWNCLOUD_REDIS_HOST=redis + healthcheck: + test: + - CMD + - /usr/bin/healthcheck + interval: 30s + timeout: 10s + retries: 5 + volumes: + - owncloud-data:/mnt/data + + mariadb: + image: mariadb:latest + environment: + - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MARIADBROOT} + - MYSQL_USER=${SERVICE_USER_MARIADB} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MARIADB} + - MYSQL_DATABASE=${DB_NAME:-owncloud} + - TZ=auto + command: + - "--character-set-server=utf8mb4" + - "--collation-server=utf8mb4_bin" + - "--max-allowed-packet=128M" + - "--innodb-log-file-size=64M" + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + interval: 5s + timeout: 20s + retries: 10 + volumes: + - owncloud-mysql-data:/var/lib/mysql + + redis: + image: redis:6 + command: + - "--databases" + - "1" + healthcheck: + test: + - CMD + - redis-cli + - ping + interval: 10s + timeout: 5s + retries: 5 diff --git a/templates/compose/plausible.yaml b/templates/compose/plausible.yaml index 7db12cb00..e02e92d38 100644 --- a/templates/compose/plausible.yaml +++ b/templates/compose/plausible.yaml @@ -6,7 +6,7 @@ services: plausible: - image: "ghcr.io/plausible/community-edition:v2.1" + image: "ghcr.io/plausible/community-edition:v2.1.4" command: 'sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run"' environment: - SERVICE_FQDN_PLAUSIBLE @@ -22,7 +22,7 @@ services: image: bytemark/smtp plausible_db: - image: "postgres:14-alpine" + image: "postgres:16-alpine" volumes: - "db-data:/var/lib/postgresql/data" environment: diff --git a/templates/compose/qbittorrent.yaml b/templates/compose/qbittorrent.yaml new file mode 100644 index 000000000..f7a4ad878 --- /dev/null +++ b/templates/compose/qbittorrent.yaml @@ -0,0 +1,48 @@ +# documentation: https://docs.linuxserver.io/images/docker-qbittorrent/ +# slogan: The qBittorrent project aims to provide an open-source software alternative to μTorrent. +# tags: torrent, streaming, webui +# logo: svgs/qbittorrent.svg +# port: 8080 + +services: + qbit: + image: "lscr.io/linuxserver/qbittorrent:latest" + environment: + - WEBUI_PORT=${WEBUI_PORT:-8080} + - PUID=1000 + - PGID=1000 + volumes: + - qbittorrent-config:/config + - qbittorrent-downloads:/downloads + - qbittorrent-torrents:/torrents + healthcheck: + test: + - CMD + - wget + - "-q" + - "--spider" + - "http://127.0.0.1:8080/" + interval: 5s + timeout: 20s + retries: 10 + + vuetorrent-backend: + image: "ghcr.io/vuetorrent/vuetorrent-backend:latest" + environment: + - SERVICE_FQDN_QBITORRENT_8080 + - PORT=${WEBUI_PORT:-8080} + - QBIT_BASE=${SERVICE_FQDN_QBITORRENT} + - RELEASE_TYPE=${RELEASE_TYPE:-stable} + - UPDATE_VT_CRON=${UPDATE_VT_CRON:-"0 * * * *"} + volumes: + - vuetorrent-config:/config + healthcheck: + test: + - CMD + - wget + - "-q" + - "--spider" + - "http://127.0.0.1:8080/" + interval: 5s + timeout: 20s + retries: 10 diff --git a/templates/compose/traccar.yaml b/templates/compose/traccar.yaml new file mode 100644 index 000000000..5aa0887fe --- /dev/null +++ b/templates/compose/traccar.yaml @@ -0,0 +1,50 @@ +# documentation: https://www.traccar.org/documentation/ +# slogan: Traccar is a free and open source modern GPS tracking system. +# tags: traccar,gps,tracking,open,source +# logo: svgs/traccar.png +# port: 8082 + +services: + traccar: + image: traccar/traccar:latest + environment: + - SERVICE_FQDN_TRACCAR_8082 + - SERVICE_FQDN_TRACCARAPI_5159 + - CONFIG_USE_ENVIRONMENT_VARIABLES=${CONFIG_USE_ENVIRONMENT_VARIABLES:-true} + - DATABASE_USER=${SERVICE_USER_POSTGRES} + - DATABASE_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + volumes: + - type: bind + source: ./srv/traccar/conf/traccar.xml + target: /opt/traccar/conf/traccar.xml + content: | + + + + ./conf/default.xml + org.postgresql.Driver + jdbc:postgresql://postgres:5432/traccar + + depends_on: + postgres: + condition: service_healthy + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8082/ping"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 15s + + postgres: + image: postgres:16-alpine + environment: + - POSTGRES_USER=$SERVICE_USER_POSTGRES + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRESQL_DATABASE:-traccar} + volumes: + - traccar-postgresql-data:/var/lib/postgresql/data/ + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 diff --git a/templates/compose/unsend.yaml b/templates/compose/unsend.yaml new file mode 100644 index 000000000..6929e5dc1 --- /dev/null +++ b/templates/compose/unsend.yaml @@ -0,0 +1,60 @@ +# documentation: https://docs.unsend.dev/get-started/self-hosting +# slogan: Unsend is an open-source alternative to Resend, Sendgrid, Mailgun and Postmark etc. +# tags: resend, mailer, marketing emails, transaction emails, self-hosting, postmark +# logo: svgs/unsend.svg +# port: 3000 + +services: + postgres: + image: postgres:16 + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${SERVICE_DB_POSTGRES:-unsend} + healthcheck: + test: ["CMD", "pg_isready", "-U", "${SERVICE_USER_POSTGRES}"] + interval: 10s + timeout: 5s + retries: 5 + volumes: + - unsend-postgres-data:/var/lib/postgresql/data + + redis: + image: redis:7 + volumes: + - unsend-redis-data:/data + command: ["redis-server", "--maxmemory-policy", "noeviction"] + healthcheck: + test: + - CMD + - redis-cli + - PING + interval: 5s + timeout: 10s + retries: 20 + + unsend: + image: unsend/unsend:latest + environment: + - SERVICE_FQDN_UNSEND_3000 + - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${SERVICE_DB_POSTGRES:-unsend} + - NEXTAUTH_URL=${SERVICE_FQDN_UNSEND} + - NEXTAUTH_SECRET=${SERVICE_BASE64_64_NEXTAUTHSECRET} + - AWS_ACCESS_KEY=${SERVICE_AWS_ACCESS_KEY} + - AWS_SECRET_KEY=${SERVICE_AWS_SECRET_KEY} + - AWS_DEFAULT_REGION=${SERVICE_AWS_DEFAULT_REGION} + - GITHUB_ID=${SERVICE_GITHUB_ID:-1234567890} + - GITHUB_SECRET=${SERVICE_GITHUB_SECRET:-abcde1234567890} + - REDIS_URL=redis://redis:6379 + - NEXT_PUBLIC_IS_CLOUD=${NEXT_PUBLIC_IS_CLOUD:-false} + - API_RATE_LIMIT=${SERVICE_API_RATE_LIMIT:-1} + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"] + interval: 2s + timeout: 10s + retries: 15 diff --git a/templates/compose/vvveb-with-mariadb.yaml b/templates/compose/vvveb-with-mariadb.yaml new file mode 100644 index 000000000..a20c70a46 --- /dev/null +++ b/templates/compose/vvveb-with-mariadb.yaml @@ -0,0 +1,41 @@ +# documentation: https://docs.vvveb.com +# slogan: Powerful and easy to use cms to build websites, blogs or ecommerce stores. +# tags: cms, blog, content, management, ecommerce, page-builder, nocode, mysql, sqlite, pgsql +# logo: svgs/vvveb.svg +# port: 80 + +services: + vvveb: + image: vvveb/vvvebcms:latest + volumes: + - vvveb-data:/var/www/html + environment: + - SERVICE_FQDN_VVVEB_80 + - DB_ENGINE=mysqli + - DB_HOST=mariadb + - DB_USER=${SERVICE_USER_VVVEB} + - DB_PASSWORD=${SERVICE_PASSWORD_VVVEB} + - DB_NAME=${MARIADB_DATABASE:-vvveb} + depends_on: + mariadb: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1"] + interval: 2s + timeout: 10s + retries: 10 + + mariadb: + image: mariadb:11 + volumes: + - vvveb-mariadb-data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_ROOT} + - MYSQL_DATABASE=${MARIADB_DATABASE:-vvveb} + - MYSQL_USER=${SERVICE_USER_VVVEB} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_VVVEB} + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + interval: 5s + timeout: 20s + retries: 10 diff --git a/templates/compose/vvveb-with-mysql.yaml b/templates/compose/vvveb-with-mysql.yaml new file mode 100644 index 000000000..64b4b264a --- /dev/null +++ b/templates/compose/vvveb-with-mysql.yaml @@ -0,0 +1,41 @@ +# documentation: https://docs.vvveb.com +# slogan: Powerful and easy to use cms to build websites, blogs or ecommerce stores. +# tags: cms, blog, content, management, ecommerce, page-builder, nocode, mysql, sqlite, pgsql +# logo: svgs/vvveb.svg +# port: 80 + +services: + vvveb: + image: vvveb/vvvebcms:latest + volumes: + - vvveb-data:/var/www/html + environment: + - SERVICE_FQDN_VVVEB_80 + - DB_ENGINE=mysqli + - DB_HOST=mysql + - DB_USER=${SERVICE_USER_VVVEB} + - DB_PASSWORD=${SERVICE_PASSWORD_VVVEB} + - DB_NAME=${MYSQL_DATABASE:-vvveb} + depends_on: + mysql: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1"] + interval: 2s + timeout: 10s + retries: 10 + + mysql: + image: mysql:8.4.2 + volumes: + - vvveb-mysql-data:/var/lib/mysql + environment: + - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_ROOT} + - MYSQL_DATABASE=${MYSQL_DATABASE:-vvveb} + - MYSQL_USER=${SERVICE_USER_VVVEB} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_VVVEB} + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"] + interval: 5s + timeout: 20s + retries: 10 diff --git a/templates/compose/vvveb.yaml b/templates/compose/vvveb.yaml new file mode 100644 index 000000000..11b71a7e9 --- /dev/null +++ b/templates/compose/vvveb.yaml @@ -0,0 +1,18 @@ +# documentation: https://docs.vvveb.com +# slogan: Powerful and easy to use cms to build websites, blogs or ecommerce stores. +# tags: cms, blog, content, management, ecommerce, page-builder, nocode, mysql, sqlite, pgsql +# logo: svgs/vvveb.svg +# port: 80 + +services: + vvveb: + image: vvveb/vvvebcms:latest + volumes: + - vvveb-data:/var/www/html + environment: + - SERVICE_FQDN_VVVEB_80 + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1"] + interval: 2s + timeout: 10s + retries: 10 diff --git a/versions.json b/versions.json index 4dbe7eb70..8efe02c0a 100644 --- a/versions.json +++ b/versions.json @@ -1,10 +1,11 @@ { "coolify": { "v4": { - "version": "4.0.0-beta.358" + "version": "4.0.0-beta.357" }, "nightly": { - "version": "4.0.0-beta.359" + "version": "4.0.0-beta.358" + }, "helper": { "version": "1.0.2" From 0499afb94f2f79dafdcaed0617b3a27b9b4b09cf Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 14:04:36 +0200 Subject: [PATCH 053/500] fix owncloud --- templates/compose/owncloud.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/templates/compose/owncloud.yaml b/templates/compose/owncloud.yaml index 6c29ddbe7..8d65f6c60 100644 --- a/templates/compose/owncloud.yaml +++ b/templates/compose/owncloud.yaml @@ -1,4 +1,3 @@ -# ignore: true # documentation: https://owncloud.com/docs # slogan: OwnCloud with Open Web UI integrates file management with a powerful, user-friendly interface. # tags: owncloud,file-management,open-web-ui,integration,cloud @@ -16,7 +15,7 @@ services: environment: - SERVICE_FQDN_OWNCLOUD_8080 - OWNCLOUD_DOMAIN=${SERVICE_FQDN_OWNCLOUD} - - OWNCLOUD_TRUSTED_DOMAINS=${SERVICE_FQDN_OWNCLOUD} # This is a comma separated list of domains that are trusted by the server (No Protocol) + - OWNCLOUD_TRUSTED_DOMAINS=${SERVICE_URL_OWNCLOUD} - OWNCLOUD_DB_TYPE=mysql - OWNCLOUD_DB_HOST=mariadb - OWNCLOUD_DB_NAME=${DB_NAME:-owncloud} From 84f17013b3a858dcce48c620e35d69d83a104522 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 14:05:57 +0200 Subject: [PATCH 054/500] fix: libretranslate --- templates/compose/libretranslate.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/templates/compose/libretranslate.yaml b/templates/compose/libretranslate.yaml index 69b9e4466..6b387b63f 100644 --- a/templates/compose/libretranslate.yaml +++ b/templates/compose/libretranslate.yaml @@ -9,11 +9,11 @@ services: image: "libretranslate/libretranslate:latest" environment: - SERVICE_FQDN_LIBRETRANSLATE_5000 - - LT_SSL=true - - LT_UPDATE_MODELS=true - - LT_LOAD_ONLY=en,es,fr,de,ja + - LT_SSL=${LT_SSL:-true} + - LT_UPDATE_MODELS=${LT_UPDATE_MODELS:-true} + - LT_LOAD_ONLY=${LT_LOAD_ONLY:-en,es,fr,de,ja} volumes: - - api-keys:/app/db - - models:/home/libretranslate/.local + - libretranslate-api-keys:/app/db + - libretranslate-models:/home/libretranslate/.local healthcheck: test: ["CMD-SHELL", "./venv/bin/python scripts/healthcheck.py"] From 67ee82f41979984985e37efaadb797c64ddb419d Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 14:16:59 +0200 Subject: [PATCH 055/500] disable cryptgeon --- templates/compose/cryptgeon.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/compose/cryptgeon.yaml b/templates/compose/cryptgeon.yaml index 942b1601c..79b864c52 100644 --- a/templates/compose/cryptgeon.yaml +++ b/templates/compose/cryptgeon.yaml @@ -1,3 +1,4 @@ +# ignore: true # documentation: https://github.com/cupcakearmy/cryptgeon # slogan: Secure note / file sharing service inspired by PrivNote. # tags: cryptgeon, secure, note, sharing, privnote, file, sharing From df46b3a791fd2434976e28c49e3803f9b856a5c7 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 14:20:32 +0200 Subject: [PATCH 056/500] fix transmission service --- templates/compose/transmission.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/compose/transmission.yaml b/templates/compose/transmission.yaml index c28951388..1e5da78ea 100644 --- a/templates/compose/transmission.yaml +++ b/templates/compose/transmission.yaml @@ -6,17 +6,17 @@ services: transmission: - image: "lscr.io/linuxserver/transmission:latest" + image: lscr.io/linuxserver/transmission:latest environment: - - SERVICE_FQDN_transmission_9091 + - SERVICE_FQDN_TRANSMISSION_9091 - PUID=1000 - PGID=1000 - USER=${SERVICE_USER_ADMIN} - PASS=${SERVICE_PASSWORD_ADMIN} volumes: - - "config:/config" - - "downloads:/downloads" - - "watch:/watch" + - transmission-config:/config + - transmission-downloads:/downloads + - transmission-watch:/watch healthcheck: test: [ "CMD", @@ -28,4 +28,4 @@ services: ] interval: 30s timeout: 10s - retries: 3 \ No newline at end of file + retries: 3 From e69bf86c6b0bebf77b13b00988ac1e0784705683 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 14:37:29 +0200 Subject: [PATCH 057/500] fix flowise --- templates/compose/flowise-with-databases.yaml | 56 ++++++++----------- templates/compose/flowise.yaml | 19 ++----- 2 files changed, 28 insertions(+), 47 deletions(-) diff --git a/templates/compose/flowise-with-databases.yaml b/templates/compose/flowise-with-databases.yaml index d78079b62..f2e26839e 100644 --- a/templates/compose/flowise-with-databases.yaml +++ b/templates/compose/flowise-with-databases.yaml @@ -4,28 +4,21 @@ # logo: svgs/flowise.png # port: 3001 -volumes: - flowise_data: - pg_record_manager_data: - redis_cache_data: - qdrant_data: - services: flowise: - image: flowiseai/flowise - restart: always + image: flowiseai/flowise:latest depends_on: - pg_record_manager: + pg-record-manager: condition: service_healthy - redis_cache: + redis-cache: condition: service_healthy qdrant: condition: service_healthy environment: - SERVICE_FQDN_FLOWISE_3001 - - DEBUG=false - - DISABLE_FLOWISE_TELEMETRY=true - - PORT=3001 + - DEBUG=${DEBUG:-false} + - DISABLE_FLOWISE_TELEMETRY=${DISABLE_FLOWISE_TELEMETRY:-true} + - PORT=${PORT:-3001} - DATABASE_PATH=/root/.flowise - APIKEY_PATH=/root/.flowise - SECRETKEY_PATH=/root/.flowise @@ -34,39 +27,34 @@ services: - FLOWISE_USERNAME=${SERVICE_USER_FLOWISE} - FLOWISE_PASSWORD=${SERVICE_PASSWORD_FLOWISE} volumes: - - flowise_data:/root/.flowise + - flowise-data:/root/.flowise healthcheck: - test: - - CMD-SHELL - - wget - - --no-verbose - - --tries=1 - - --spider - - http://localhost:3001 + test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3001 || exit 1"] interval: 5s timeout: 5s retries: 3 - pg_record_manager: - image: "postgres:16" - restart: always + + pg-record-manager: + image: postgres:16 environment: - POSTGRES_USER=${SERVICE_USER_POSTGRES} - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} - - POSTGRES_DB=${POSTGRES_DB:-record_manager} + - POSTGRES_DB=${POSTGRES_DB:-pg-record-manager} volumes: - - pg_record_manager_data:/var/lib/postgresql/data + - pg-record-manager-data:/var/lib/postgresql/data healthcheck: test: - CMD-SHELL - "pg_isready -h localhost -U $${POSTGRES_USER} -d $${POSTGRES_DB}" interval: 5s timeout: 5s - retries: 3 - redis_cache: - image: "redis:7" - restart: always + retries: 10 + start_period: 20s + + redis-cache: + image: redis:7 volumes: - - redis_cache_data:/data + - flowise-redis-cache-data:/data healthcheck: test: - CMD-SHELL @@ -74,14 +62,14 @@ services: interval: 5s timeout: 5s retries: 3 + qdrant: - image: "qdrant/qdrant:latest" - restart: always + image: qdrant/qdrant:latest environment: - SERVICE_FQDN_QDRANT_6333 - QDRANT__SERVICE__API_KEY=${SERVICE_PASSWORD_QDRANTAPIKEY} volumes: - - "qdrant_data:/qdrant/storage" + - flowise-qdrant-data:/qdrant/storage healthcheck: test: - CMD-SHELL diff --git a/templates/compose/flowise.yaml b/templates/compose/flowise.yaml index dc5095e1e..796d0cc4e 100644 --- a/templates/compose/flowise.yaml +++ b/templates/compose/flowise.yaml @@ -6,13 +6,12 @@ services: flowise: - image: flowiseai/flowise - restart: always + image: flowiseai/flowise:latest environment: - SERVICE_FQDN_FLOWISE_3001 - - DEBUG=false - - DISABLE_FLOWISE_TELEMETRY=true - - PORT=3001 + - DEBUG=${DEBUG:-false} + - DISABLE_FLOWISE_TELEMETRY=${DISABLE_FLOWISE_TELEMETRY:-true} + - PORT=${PORT:-3001} - DATABASE_PATH=/root/.flowise - APIKEY_PATH=/root/.flowise - SECRETKEY_PATH=/root/.flowise @@ -21,15 +20,9 @@ services: - FLOWISE_USERNAME=${SERVICE_USER_FLOWISE} - FLOWISE_PASSWORD=${SERVICE_PASSWORD_FLOWISE} volumes: - - flowise_data:/root/.flowise + - flowise-data:/root/.flowise healthcheck: - test: - - CMD-SHELL - - wget - - --no-verbose - - --tries=1 - - --spide - - http://localhost:3001 + test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3001 || exit 1"] interval: 5s timeout: 5s retries: 3 From ed58f842a35c04cb7b5b4425a29306e60551d003 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:05:55 +0200 Subject: [PATCH 058/500] fix heyform --- templates/compose/heyform.yaml | 64 +++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/templates/compose/heyform.yaml b/templates/compose/heyform.yaml index 732eb2544..a92f14109 100644 --- a/templates/compose/heyform.yaml +++ b/templates/compose/heyform.yaml @@ -2,47 +2,53 @@ # slogan: Allows anyone to create engaging conversational forms for surveys, questionnaires, quizzes, and polls. No coding skills required. # tags: form, builder, forms, survey, quiz, open source, self-hosted, docker # logo: svgs/heyform.svg -# port: 9513 - -networks: - keydb: null - mongo: null +# port: 8000 services: heyform: - image: 'heyform/community-edition:latest' - restart: always + image: heyform/community-edition:latest volumes: - - 'assets:/app/static/upload' + - heyform-assets:/app/static/upload depends_on: - - mongo - - keydb - ports: - - '9513:8000' + mongo: + condition: service_healthy + keydb: + condition: service_healthy environment: - - SERVICE_FQDN_HEYFORM_9513 - - 'APP_HOMEPAGE_URL=${SERVICE_FQDN_HEYFORM_9513}' - - 'SESSION_KEY=${SERVICE_BASE64_64}' - - 'FORM_ENCRYPTION_KEY=${SERVICE_BASE64_64}' - - "MONGO_URI='mongodb://mongo:27017/heyform'" + - SERVICE_FQDN_HEYFORM_8000 + - APP_HOMEPAGE_URL=${SERVICE_FQDN_HEYFORM} + - SESSION_KEY=${SERVICE_BASE64_64_SESSION} + - FORM_ENCRYPTION_KEY=${SERVICE_BASE64_64_FORM} + - MONGO_URI=mongodb://mongo:27017/heyform - REDIS_HOST=keydb - REDIS_PORT=6379 healthcheck: - test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/health"] - interval: 2s - timeout: 10s - retries: 15 + test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8000 || exit 1"] + interval: 5s + timeout: 5s + retries: 3 mongo: - image: 'percona/percona-server-mongodb:4.4' - restart: always + image: percona/percona-server-mongodb:latest volumes: - - 'mongo:/data/db' + - heyform-mongo-data:/data/db + healthcheck: + test: ["CMD-SHELL", "echo 'ok' > /dev/null 2>&1"] + interval: 5s + timeout: 5s + retries: 10 + start_period: 5s keydb: - image: 'eqalpha/keydb:latest' - restart: always - command: 'keydb-server --appendonly yes' + image: eqalpha/keydb:latest + command: keydb-server --appendonly yes + environment: + - KEYDB_PASSWORD=${SERVICE_PASSWORD_KEYDB} volumes: - - 'keydb:/data' - + - heyform-keydb-data:/data + healthcheck: + test: ["CMD-SHELL", "keydb-cli", "--pass", "${SERVICE_PASSWORD_KEYDB}", "ping"] + interval: 5s + timeout: 5s + retries: 10 + start_period: 5s From edcad90a5ae17871d76fa7958b4e4db08c9aa9f4 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 17:22:08 +0200 Subject: [PATCH 059/500] fix zipline service --- public/svgs/zipline.png | Bin 0 -> 27499 bytes templates/compose/zipline.yaml | 25 +++++++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) create mode 100644 public/svgs/zipline.png diff --git a/public/svgs/zipline.png b/public/svgs/zipline.png new file mode 100644 index 0000000000000000000000000000000000000000..2b8f6972d5edcf5bd61db6ebae6aac342150472b GIT binary patch literal 27499 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˕|s{@L$t4Dq}u7x`k^_Bp!g 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 literal 0 HcmV?d00001 diff --git a/templates/compose/zipline.yaml b/templates/compose/zipline.yaml index 0064c69c5..c5efc4058 100644 --- a/templates/compose/zipline.yaml +++ b/templates/compose/zipline.yaml @@ -1,17 +1,19 @@ # documentation: https://github.com/diced/zipline # slogan: A ShareX/file upload server that is easy to use, packed with features, and with an easy setup! # tags: zipline,file-sharing,upload,sharing +# logo: svgs/zipline.png # port: 3000 + services: zipline: - image: ghcr.io/diced/zipline - restart: unless-stopped + image: ghcr.io/diced/zipline:latest environment: - SERVICE_FQDN_ZIPLINE_3000 - - CORE_RETURN_HTTPS=false + - CORE_RETURN_HTTPS=${CORE_RETURN_HTTPS:-false} - CORE_SECRET=${SERVICE_PASSWORD_64_ZIPLINE} - - CORE_DATABASE_URL=postgres://${SERVICE_USER_DATABASE}:${SERVICE_PASSWORD_64_DATABASE}@postgres/${POSTGRESQL_DATABASE:-zipline} - - CORE_LOGGER=true + - CORE_DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres/${POSTGRES_DB:-zipline-db} + - CORE_LOGGER=${CORE_LOGGER:-true} + # Default credentials are "administrator" and "password" volumes: - zipline-uploads:/zipline/uploads - zipline-public:/zipline/public @@ -24,18 +26,17 @@ services: interval: 5s timeout: 20s retries: 10 + postgres: image: postgres:16-alpine volumes: - - postgresql-data:/var/lib/postgresql/data + - zipline-postgres-data:/var/lib/postgresql/data environment: - - POSTGRES_USER=${SERVICE_USER_DATABASE} - - POSTGRES_PASSWORD=${SERVICE_PASSWORD_64_DATABASE} - - POSTGRES_DB=${POSTGRESQL_DATABASE:-zipline} + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-zipline-db} healthcheck: - test: - - CMD-SHELL - - pg_isready -U $${SERVICE_USER_DATABASE} -d $${POSTGRESQL_DATABASE} + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 20s retries: 10 From 5c3fffe1a6bbb61ca9e1a8391d084a5f915b82b8 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:13:48 +0200 Subject: [PATCH 060/500] fix supabase --- templates/compose/supabase.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/templates/compose/supabase.yaml b/templates/compose/supabase.yaml index 8f3d0a667..588405289 100644 --- a/templates/compose/supabase.yaml +++ b/templates/compose/supabase.yaml @@ -331,7 +331,6 @@ services: - config_file=/etc/postgresql/postgresql.conf - -c - log_min_messages=fatal - restart: unless-stopped environment: - POSTGRES_HOST=/var/run/postgresql - PGPORT=${POSTGRES_PORT:-5432} @@ -620,7 +619,6 @@ services: timeout: 5s interval: 5s retries: 10 - restart: unless-stopped depends_on: supabase-db: condition: service_healthy @@ -918,7 +916,6 @@ services: condition: service_healthy supabase-analytics: condition: service_healthy - restart: unless-stopped environment: - PGRST_DB_URI=postgres://authenticator:${SERVICE_PASSWORD_POSTGRES}@${POSTGRES_HOSTNAME:-supabase-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-postgres} - 'PGRST_DB_SCHEMAS=${PGRST_DB_SCHEMAS:-public,storage,graphql_public}' @@ -1357,7 +1354,6 @@ services: timeout: 5s interval: 5s retries: 10 - restart: unless-stopped depends_on: supabase-db: condition: service_healthy From 5e11f159e0a78a72d3706aeebb6d6e3337223ff2 Mon Sep 17 00:00:00 2001 From: Lucas Michot Date: Thu, 10 Oct 2024 18:32:24 +0200 Subject: [PATCH 061/500] Remove some useless variable assignments. --- app/Livewire/Boarding/Index.php | 2 -- app/Livewire/Server/Form.php | 7 ------- app/Models/Application.php | 4 ++-- bootstrap/helpers/docker.php | 12 ++++++------ 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/app/Livewire/Boarding/Index.php b/app/Livewire/Boarding/Index.php index 52d4674ee..b7dd8656d 100644 --- a/app/Livewire/Boarding/Index.php +++ b/app/Livewire/Boarding/Index.php @@ -73,8 +73,6 @@ class Index extends Component } $this->privateKeyName = generate_random_name(); $this->remoteServerName = generate_random_name(); - $this->remoteServerPort = $this->remoteServerPort; - $this->remoteServerUser = $this->remoteServerUser; if (isDev()) { $this->privateKey = '-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php index c4f25c79d..30c96eaee 100644 --- a/app/Livewire/Server/Form.php +++ b/app/Livewire/Server/Form.php @@ -95,8 +95,6 @@ class Form extends Component $this->server = $server; $this->timezones = collect(timezone_identifiers_list())->sort()->values()->toArray(); $this->wildcard_domain = $this->server->settings->wildcard_domain; - $this->server->settings->docker_cleanup_threshold = $this->server->settings->docker_cleanup_threshold; - $this->server->settings->docker_cleanup_frequency = $this->server->settings->docker_cleanup_frequency; $this->server->settings->delete_unused_volumes = $server->settings->delete_unused_volumes; $this->server->settings->delete_unused_networks = $server->settings->delete_unused_networks; } @@ -236,11 +234,6 @@ class Form extends Component } refresh_server_connection($this->server->privateKey); $this->server->settings->wildcard_domain = $this->wildcard_domain; - if ($this->server->settings->force_docker_cleanup) { - $this->server->settings->docker_cleanup_frequency = $this->server->settings->docker_cleanup_frequency; - } else { - $this->server->settings->docker_cleanup_threshold = $this->server->settings->docker_cleanup_threshold; - } $currentTimezone = $this->server->settings->getOriginal('server_timezone'); $newTimezone = $this->server->settings->server_timezone; if ($currentTimezone !== $newTimezone || $currentTimezone === '') { diff --git a/app/Models/Application.php b/app/Models/Application.php index 07aeb4c5b..b20f65201 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -1459,9 +1459,9 @@ class Application extends BaseModel return $config; } - public function setConfig($config) { - $config = $config; + public function setConfig($config) + { $validator = Validator::make(['config' => $config], [ 'config' => 'required|json', ]); diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index 397bce029..5b45f666f 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -279,7 +279,6 @@ function fqdnLabelsForCaddy(string $network, string $uuid, Collection $domains, $labels->push("caddy_ingress_network={$network}"); } foreach ($domains as $loop => $domain) { - $loop = $loop; $url = Url::fromString($domain); $host = $url->getHost(); $path = $url->getPath(); @@ -335,10 +334,11 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ if (preg_match('/coolify\.traefik\.middlewares=(.*)/', $item, $matches)) { return explode(',', $matches[1]); } + return null; })->flatten() - ->filter() - ->unique(); + ->filter() + ->unique(); } foreach ($domains as $loop => $domain) { try { @@ -388,7 +388,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ if ($path !== '/') { // Middleware handling $middlewares = collect([]); - if ($is_stripprefix_enabled && !str($image)->contains('ghost')) { + if ($is_stripprefix_enabled && ! str($image)->contains('ghost')) { $labels->push("traefik.http.middlewares.{$https_label}-stripprefix.stripprefix.prefixes={$path}"); $middlewares->push("{$https_label}-stripprefix"); } @@ -402,7 +402,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ $labels = $labels->merge($redirect_to_non_www); $middlewares->push($to_non_www_name); } - if ($redirect_direction === 'www' && !str($host)->startsWith('www.')) { + if ($redirect_direction === 'www' && ! str($host)->startsWith('www.')) { $labels = $labels->merge($redirect_to_www); $middlewares->push($to_www_name); } @@ -417,7 +417,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ $middlewares = collect([]); if ($is_gzip_enabled) { $middlewares->push('gzip'); - } + } if (str($image)->contains('ghost')) { $middlewares->push('redir-ghost'); } From 10d429e43e05d4e93c97d35d21ac80eb2db94cca Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 19:20:04 +0200 Subject: [PATCH 062/500] Feat: Add peppermint --- templates/compose/peppermint.yaml | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 templates/compose/peppermint.yaml diff --git a/templates/compose/peppermint.yaml b/templates/compose/peppermint.yaml new file mode 100644 index 000000000..75b5fd5b0 --- /dev/null +++ b/templates/compose/peppermint.yaml @@ -0,0 +1,40 @@ +# documentation: https://docs.peppermint.sh/ +# slogan: Open source helpdesk solution designed to enhance the user experience for teams currently utilizing costly software alternatives +# tags: helpdesk, open-source, peppermint, postgres +# logo: svgs/peppermint.png +# port: 3000 + +services: + postgres: + image: postgres:16-alpine + volumes: + - peppermint-postgresql-data:/var/lib/postgresql/data + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-peppermint-db} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 + + peppermint: + image: pepperlabs/peppermint:latest + depends_on: + postgres: + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"] + interval: 2s + timeout: 10s + retries: 15 + environment: + - SERVICE_FQDN_PEPPERMINT_3000 + - SERVICE_FQDN_PEPPERMINTAPI_5003 + - DB_USERNAME=${SERVICE_USER_POSTGRES} + - DB_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - DB_HOST=postgres + - DB_NAME=${POSTGRES_DB:-peppermint-db} + - SECRET=${SERVICE_PASSWORD_PEPPERMINT} + - API_URL=SERVICE_FQDN_PEPPERMINT_5003 From 62ac6cdc351d9f5b01fc1bdf0ba561b128fce469 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 19:46:42 +0200 Subject: [PATCH 063/500] Add peppermint logo --- public/svgs/peppermint.png | Bin 0 -> 20389 bytes templates/compose/peppermint.yaml | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 public/svgs/peppermint.png diff --git a/public/svgs/peppermint.png b/public/svgs/peppermint.png new file mode 100644 index 0000000000000000000000000000000000000000..38db83de0ccc0201151526f1daa31ea43e0923be GIT binary patch literal 20389 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 Date: Thu, 10 Oct 2024 19:18:35 +0100 Subject: [PATCH 064/500] Added mosquitto --- public/svgs/mosquitto.png | Bin 0 -> 16118 bytes templates/compose/mosquitto.yaml | 47 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 public/svgs/mosquitto.png create mode 100644 templates/compose/mosquitto.yaml diff --git a/public/svgs/mosquitto.png b/public/svgs/mosquitto.png new file mode 100644 index 0000000000000000000000000000000000000000..eb287a7cdd7e2d0a0bbacbd375f6ae6b065df280 GIT binary patch literal 16118 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

p!*Z_;7&1;8)3J~i4?v1 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 /mosquitto/config/mosquitto.conf && + echo ''listener 8883'' >> /mosquitto/config/mosquitto.conf && + echo ''listener 9001'' >> /mosquitto/config/mosquitto.conf && + echo ''cafile /certs/ca.crt'' >> /mosquitto/config/mosquitto.conf && + echo ''certfile /certs/server.crt'' >> /mosquitto/config/mosquitto.conf && + echo ''keyfile /certs/server.key'' >> /mosquitto/config/mosquitto.conf && + echo ''require_certificate ''$REQUIRE_CERTIFICATE >> /mosquitto/config/mosquitto.conf && + echo ''allow_anonymous ''$ALLOW_ANONYMOUS >> /mosquitto/config/mosquitto.conf && + echo ''password_file /mosquitto/config/passwords'' >> /mosquitto/config/mosquitto.conf && + touch /mosquitto/config/passwords && + mosquitto_passwd -b -c /mosquitto/config/passwords $USERNAME $PASSWORD && + chmod 0700 /mosquitto/config/passwords && + chown mosquitto:mosquitto /mosquitto/config/passwords && + chmod 0700 /certs/* && + chown mosquitto:mosquitto /certs/* && + exec mosquitto -c /mosquitto/config/mosquitto.conf + "' + labels: + - traefik.enable=true + - traefik.tcp.routers.mqtt.entrypoints=mqtt + - traefik.tcp.routers.mqtts.entrypoints=mqtts From 3c51c889ccffe5229dd266c4f91249ba67e7ee96 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:48:36 +0200 Subject: [PATCH 065/500] fix plunk --- templates/compose/plunk.yaml | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/templates/compose/plunk.yaml b/templates/compose/plunk.yaml index cc1616c42..5e808017f 100644 --- a/templates/compose/plunk.yaml +++ b/templates/compose/plunk.yaml @@ -4,10 +4,9 @@ # logo: svgs/plunk.svg # port: 3000 -version: '3' services: plunk: - image: driaug/plunk + image: driaug/plunk:latest depends_on: postgresql: condition: service_healthy @@ -16,8 +15,8 @@ services: environment: - SERVICE_FQDN_PLUNK_3000 - REDIS_URL=redis://redis:6379 - - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql/plunk?schema=public - - JWT_SECRET=${SERVICE_PASSWORD_JWT_SECRET} + - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql/plunk-db?schema=public + - JWT_SECRET=${SERVICE_PASSWORD_JWTSECRET} - AWS_REGION=${AWS_REGION} - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} @@ -25,30 +24,32 @@ services: - NEXT_PUBLIC_API_URI=${SERVICE_FQDN_PLUNK}/api - APP_URI=${SERVICE_FQDN_PLUNK} - API_URI=${SERVICE_FQDN_PLUNK}/api - - DISABLE_SIGNUPS=False + - DISABLE_SIGNUPS=${DISABLE_SIGNUPS:-False} entrypoint: [ "/app/entry.sh" ] healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000"] interval: 2s timeout: 10s retries: 15 + postgresql: image: postgres:16-alpine environment: - - POSTGRES_USER=$SERVICE_USER_POSTGRES - - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES - - POSTGRES_DB=${POSTGRES_DB:-plunk} + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-plunk-db} volumes: - - postgresql-data:/var/lib/postgresql/data + - plunk-postgresql-data:/var/lib/postgresql/data healthcheck: - test: [ "CMD-SHELL", "pg_isready -U postgres -d postgres" ] + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s - timeout: 10s - retries: 20 + timeout: 20s + retries: 10 + redis: - image: "redis:7.4-alpine" + image: redis:7.4-alpine volumes: - - "redis-data:/data" + - plunk-redis-data:/data healthcheck: test: - CMD From 9fc2aa806bf51b703458460edb3739f2de88b3ae Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 22:55:39 +0200 Subject: [PATCH 066/500] enable cryptgeon --- templates/compose/cryptgeon.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/compose/cryptgeon.yaml b/templates/compose/cryptgeon.yaml index 79b864c52..942b1601c 100644 --- a/templates/compose/cryptgeon.yaml +++ b/templates/compose/cryptgeon.yaml @@ -1,4 +1,3 @@ -# ignore: true # documentation: https://github.com/cupcakearmy/cryptgeon # slogan: Secure note / file sharing service inspired by PrivNote. # tags: cryptgeon, secure, note, sharing, privnote, file, sharing From 91c6fa3ff958bf7994132e90b57f2a1e56093f34 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 23:06:01 +0200 Subject: [PATCH 067/500] typo --- templates/compose/peppermint.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/peppermint.yaml b/templates/compose/peppermint.yaml index cd4eb436b..c079ee48b 100644 --- a/templates/compose/peppermint.yaml +++ b/templates/compose/peppermint.yaml @@ -31,7 +31,7 @@ services: retries: 15 environment: - SERVICE_FQDN_PEPPERMINT_3000 - - SERVICE_FQDN_PEPPERMINTAPI_5003 + - SERVICE_FQDN_PEPPERMINT_5003 - DB_USERNAME=${SERVICE_USER_POSTGRES} - DB_PASSWORD=${SERVICE_PASSWORD_POSTGRES} - DB_HOST=postgres From 2d157243208d22e7ddb19ed8dcebc9b9a84e8199 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:05:21 +0200 Subject: [PATCH 068/500] fix unsend --- templates/compose/unsend.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/templates/compose/unsend.yaml b/templates/compose/unsend.yaml index 6929e5dc1..f838c8632 100644 --- a/templates/compose/unsend.yaml +++ b/templates/compose/unsend.yaml @@ -12,10 +12,10 @@ services: - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} - POSTGRES_DB=${SERVICE_DB_POSTGRES:-unsend} healthcheck: - test: ["CMD", "pg_isready", "-U", "${SERVICE_USER_POSTGRES}"] - interval: 10s - timeout: 5s - retries: 5 + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 volumes: - unsend-postgres-data:/var/lib/postgresql/data @@ -43,8 +43,8 @@ services: - AWS_ACCESS_KEY=${SERVICE_AWS_ACCESS_KEY} - AWS_SECRET_KEY=${SERVICE_AWS_SECRET_KEY} - AWS_DEFAULT_REGION=${SERVICE_AWS_DEFAULT_REGION} - - GITHUB_ID=${SERVICE_GITHUB_ID:-1234567890} - - GITHUB_SECRET=${SERVICE_GITHUB_SECRET:-abcde1234567890} + - GITHUB_ID=${SERVICE_GITHUB_ID} + - GITHUB_SECRET=${SERVICE_GITHUB_SECRET} - REDIS_URL=redis://redis:6379 - NEXT_PUBLIC_IS_CLOUD=${NEXT_PUBLIC_IS_CLOUD:-false} - API_RATE_LIMIT=${SERVICE_API_RATE_LIMIT:-1} @@ -54,7 +54,7 @@ services: redis: condition: service_healthy healthcheck: - test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"] - interval: 2s - timeout: 10s - retries: 15 + test: [ "CMD-SHELL", "wget -qO- http://127.0.0.1:3000 || exit 1" ] + interval: 5s + retries: 10 + timeout: 2s From ccc231011080c063735cb3ae3a529382082f3894 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:16:48 +0200 Subject: [PATCH 069/500] fix dify --- templates/compose/dify.yaml | 52 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/templates/compose/dify.yaml b/templates/compose/dify.yaml index 95690b226..a801426c1 100644 --- a/templates/compose/dify.yaml +++ b/templates/compose/dify.yaml @@ -2,8 +2,7 @@ # slogan: Dify is an open-source LLM app development platform. Dify's intuitive interface combines AI workflow, RAG pipeline, agent capabilities, model management, observability features and more, letting you quickly go from prototype to production. # tags: ai, weaviate, openai, gpt, llm, lmops, dify, redis, postgres, qdrant, RAG, agent # logo: svgs/dify.png -# port: 80 - +# port: 3000 x-shared-env: &shared-api-worker-env LOG_LEVEL: ${LOG_LEVEL:-INFO} @@ -152,10 +151,8 @@ x-shared-env: &shared-api-worker-env SSRF_PROXY_HTTPS_URL: ${SSRF_PROXY_HTTPS_URL:-http://ssrf_proxy:3128} services: - # API service api: image: langgenius/dify-api:latest - restart: always environment: SECRET_KEY: $SERVICE_PASSWORD_64_SECRETKEY INIT_PASSWORD: $SERVICE_USER_INITPASSWORD @@ -164,11 +161,13 @@ services: # Startup mode, 'api' starts the API server. MODE: api depends_on: - - db - - redis + db: + condition: service_healthy + redis: + condition: service_healthy volumes: # Mount the storage directory to the container, for storing user files. - - './volumes/app/storage:/app/api/storage' + - dify-storage:/app/api/storage networks: - ssrf_proxy_network - default @@ -183,18 +182,19 @@ services: # The Celery worker for processing the queue. worker: image: langgenius/dify-api:latest - restart: always environment: # Use the shared environment variables. <<: *shared-api-worker-env # Startup mode, 'worker' starts the Celery worker for processing the queue. MODE: worker depends_on: - - db - - redis + db: + condition: service_healthy + redis: + condition: service_healthy volumes: # Mount the storage directory to the container, for storing user files. - - './volumes/app/storage:/app/api/storage' + - dify-storage:/app/api/storage networks: - ssrf_proxy_network - default @@ -208,12 +208,12 @@ services: # Frontend web application. web: image: langgenius/dify-web:latest - restart: always environment: - CONSOLE_API_URL: ${CONSOLE_API_URL:-} - APP_API_URL: ${APP_API_URL:-} - SENTRY_DSN: ${WEB_SENTRY_DSN:-} - NEXT_TELEMETRY_DISABLED: ${NEXT_TELEMETRY_DISABLED:-0} + - SERVICE_FQDN_WEB_3000 + - CONSOLE_API_URL=${SERVICE_FQDN_WEB} + - APP_API_URL=${SERVICE_FQDN_API} + - SENTRY_DSN=${WEB_SENTRY_DSN:-} + - NEXT_TELEMETRY_DISABLED=${NEXT_TELEMETRY_DISABLED:-0} healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://web:3000"] interval: 30s @@ -224,7 +224,6 @@ services: # The postgres database. db: image: postgres:15-alpine - restart: always environment: POSTGRES_USER: $SERVICE_USER_POSTGRES POSTGRES_PASSWORD: $SERVICE_PASSWORD_POSTGRES @@ -237,7 +236,7 @@ services: -c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}' -c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}' volumes: - - './volumes/db/data:/var/lib/postgresql/data' + - dify-db-data:/var/lib/postgresql/data healthcheck: test: ["CMD", "pg_isready", "-U", "$SERVICE_USER_POSTGRES", "-d", "dify"] interval: 10s @@ -247,10 +246,10 @@ services: # The redis cache. redis: image: redis:6-alpine - restart: always + environment: + REDIS_PASSWORD: $SERVICE_PASSWORD_REDIS volumes: - # Mount the redis data directory to the container. - - './volumes/redis/data:/data' + - dify-redis-data:/data # Set the redis password when startup redis server. command: redis-server --requirepass "$SERVICE_PASSWORD_REDIS" healthcheck: @@ -276,13 +275,17 @@ services: networks: - ssrf_proxy_network - default + healthcheck: + test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/8194' || exit 1"] + interval: 5s + timeout: 20s + retries: 3 # ssrf_proxy server # for more information, please refer to # https://docs.dify.ai/learn-more/faq/self-host-faq#id-18.-why-is-ssrf_proxy-needed ssrf_proxy: image: ubuntu/squid:latest - restart: always volumes: - type: bind source: ./ssrf_proxy/squid.conf.template @@ -410,7 +413,6 @@ services: # used for reverse proxying the API service and Web service. nginx: image: nginx:latest - restart: always volumes: - type: bind source: ./nginx/nginx.conf.template @@ -604,10 +606,8 @@ services: profiles: - '' - weaviate - restart: always volumes: - # Mount the Weaviate data directory to the con tainer. - - ./volumes/weaviate:/var/lib/weaviate + - dify-weaviate-data:/var/lib/weaviate environment: # The Weaviate configurations # You can refer to the [Weaviate](https://weaviate.io/developers/weaviate/config-refs/env-vars) documentation for more information. From 0e844a0865e00a6a177466af5d789897429c1e0a Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:26:55 +0200 Subject: [PATCH 070/500] Update zep.yaml --- templates/compose/zep.yaml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/templates/compose/zep.yaml b/templates/compose/zep.yaml index becaf94f0..75e7558aa 100644 --- a/templates/compose/zep.yaml +++ b/templates/compose/zep.yaml @@ -4,13 +4,9 @@ # logo: svgs/zep.png # port: 8000 -volumes: - pg_data: - services: postgres: image: ghcr.io/getzep/postgres:postgres-15 - restart: always shm_size: 128mb environment: - POSTGRES_USER=${SERVICE_USER_POSTGRES} @@ -26,8 +22,8 @@ services: retries: 5 nlp: image: ghcr.io/getzep/zep-nlp-server:0.4 - restart: always environment: + - SERVICE_FQDN_NLP_5557 - ZEP_OPENAI_API_KEY=${OPENAI_API_KEY} - ZEP_AUTH_SECRET=${SERVICE_PASSWORD_AUTHSECRET} - ZEP_SERVER_WEB_ENABLED=${ZEP_SERVER_WEB_ENABLED:-false} @@ -39,7 +35,6 @@ services: start_period: 45s zep: image: ghcr.io/getzep/zep:latest - restart: always depends_on: postgres: condition: service_healthy From 06114f06cabca5e19bbae3b162dc497461b97d28 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:27:06 +0200 Subject: [PATCH 071/500] Update service-templates.json --- templates/service-templates.json | 503 ++++++++++++++++++++++++++++++- 1 file changed, 496 insertions(+), 7 deletions(-) diff --git a/templates/service-templates.json b/templates/service-templates.json index 3522d6bd1..eeca12af4 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -13,6 +13,20 @@ "minversion": "0.0.0", "port": "80" }, + "affine": { + "documentation": "https://docs.affine.pro/docs/self-host-affine?utm_source=coolify.io", + "slogan": "Affine is an open-source, all-in-one workspace and OS for knowledge management, a Notion/Miro alternative.", + "compose": "c2VydmljZXM6CiAgYWZmaW5lOgogICAgaW1hZ2U6ICdnaGNyLmlvL3RvZXZlcnl0aGluZy9hZmZpbmUtZ3JhcGhxbDpzdGFibGUnCiAgICBjb21tYW5kOgogICAgICAtIHNoCiAgICAgIC0gJy1jJwogICAgICAtICdub2RlIC4vc2NyaXB0cy9zZWxmLWhvc3QtcHJlZGVwbG95ICYmIG5vZGUgLi9kaXN0L2luZGV4LmpzJwogICAgZGVwZW5kc19vbjoKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2FmZmluZS1jb25maWc6L3Jvb3QvLmFmZmluZS9jb25maWcnCiAgICAgIC0gJ2FmZmluZS1zdG9yYWdlOi9yb290Ly5hZmZpbmUvc3RvcmFnZScKICAgIGxvZ2dpbmc6CiAgICAgIGRyaXZlcjoganNvbi1maWxlCiAgICAgIG9wdGlvbnM6CiAgICAgICAgbWF4LXNpemU6IDEwMDBtCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQUZGSU5FXzMwMTAKICAgICAgLSBOT0RFX09QVElPTlM9LS1pbXBvcnQ9Li9zY3JpcHRzL3JlZ2lzdGVyLmpzCiAgICAgIC0gQUZGSU5FX0NPTkZJR19QQVRIPS9yb290Ly5hZmZpbmUvY29uZmlnCiAgICAgIC0gUkVESVNfU0VSVkVSX0hPU1Q9cmVkaXMKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AcG9zdGdyZXM6NTQzMi8ke1BPU1RHUkVTX0RCOi1hZmZpbmV9JwogICAgICAtIE5PREVfRU5WPXByb2R1Y3Rpb24KICAgICAgLSBBRkZJTkVfU0VSVkVSX0hPU1Q9JFNFUlZJQ0VfRlFETl9BRkZJTkUKICAgICAgLSBBRkZJTkVfU0VSVkVSX0VYVEVSTkFMX1VSTD0kU0VSVklDRV9GUUROX0FGRklORQogICAgICAtICdNQUlMRVJfSE9TVD0ke01BSUxFUl9IT1NUfScKICAgICAgLSAnTUFJTEVSX1BPUlQ9JHtNQUlMRVJfUE9SVH0nCiAgICAgIC0gJ01BSUxFUl9VU0VSPSR7TUFJTEVSX1VTRVJ9JwogICAgICAtICdNQUlMRVJfUEFTU1dPUkQ9JHtNQUlMRVJfUEFTU1dPUkR9JwogICAgICAtICdNQUlMRVJfU0VOREVSPSR7TUFJTEVSX1NFTkRFUn0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gImJhc2ggLWMgJzo+IC9kZXYvdGNwLzEyNy4wLjAuMS8zMDEwJyB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMwogIHJlZGlzOgogICAgaW1hZ2U6IHJlZGlzCiAgICB2b2x1bWVzOgogICAgICAtICdhZmZpbmUtcmVkaXMtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtICctLXJhdycKICAgICAgICAtIGluY3IKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2JwogICAgdm9sdW1lczoKICAgICAgLSAnYWZmaW5lLXBvc3RncmVzLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VIGFmZmluZScKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LWFmZmluZX0nCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YS9wZ2RhdGEK", + "tags": [ + "knowledge-management", + "notion", + "miro", + "workspace" + ], + "logo": "svgs/affine.svg", + "minversion": "0.0.0", + "port": "3010" + }, "anythingllm": { "documentation": "https://docs.anythingllm.com/installation-docker/overview?utm_source=coolify.io", "slogan": "AnythingLLM is the easiest to use, all-in-one AI application that can do RAG, AI Agents, and much more with no code or infrastructure headaches.", @@ -321,6 +335,25 @@ "logo": "svgs/classicpress.svg", "minversion": "0.0.0" }, + "cloudbeaver": { + "documentation": "https://dbeaver.com/docs/cloudbeaver/?utm_source=coolify.io", + "slogan": "CloudBeaver is a lightweight web application designed for comprehensive data management.", + "compose": "c2VydmljZXM6CiAgY2xvdWRiZWF2ZXI6CiAgICBpbWFnZTogJ2RiZWF2ZXIvY2xvdWRiZWF2ZXI6MjQnCiAgICB2b2x1bWVzOgogICAgICAtICdjbG91ZGJlYXZlci1kYXRhOi9vcHQvY2xvdWRiZWF2ZXIvd29ya3NwYWNlJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0NMT1VEQkVBVkVSXzg5NzgKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLXEnCiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo4OTc4LycKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=", + "tags": [ + "dbeaver", + "data management", + "data", + "database", + "mysql", + "postgres", + "sqlite", + "sql", + "mongodb" + ], + "logo": "svgs/cloudbeaver.svg", + "minversion": "0.0.0", + "port": "8978" + }, "cloudflared": { "documentation": "https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/?utm_source=coolify.io", "slogan": "Client for Cloudflare Tunnel, a daemon that exposes private services through the Cloudflare edge.", @@ -343,6 +376,23 @@ "minversion": "0.0.0", "port": "8443" }, + "cryptgeon": { + "documentation": "https://github.com/cupcakearmy/cryptgeon?utm_source=coolify.io", + "slogan": "Secure note / file sharing service inspired by PrivNote.", + "compose": "c2VydmljZXM6CiAgYXBwOgogICAgaW1hZ2U6ICdjdXBjYWtlYXJteS9jcnlwdGdlb246bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0NSWVBUR0VPTl84MDAwCiAgICAgIC0gJ1NJWkVfTElNSVQ9JHtTSVpFX0xJTUlUOi00IE1pQn0nCiAgICAgIC0gJ01BWF9WSUVXUz0ke01BWF9WSUVXUzotMTAwfScKICAgICAgLSAnTUFYX0VYUElSQVRJT049JHtNQVhfRVhQSVJBVElPTjotMzYwfScKICAgICAgLSAnQUxMT1dfQURWQU5DRUQ9JHtBTExPV19BRFZBTkNFRDotdHJ1ZX0nCiAgICAgIC0gJ0FMTE9XX0ZJTEVTPSR7QUxMT1dfRklMRVM6LXRydWV9JwogICAgZGVwZW5kc19vbjoKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLS1mYWlsJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6ODAwMC9hcGkvbGl2ZS8nCiAgICAgIGludGVydmFsOiAxbQogICAgICB0aW1lb3V0OiAzcwogICAgICByZXRyaWVzOiAyCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMKICByZWRpczoKICAgIGltYWdlOiAncmVkaXM6Ny1hbHBpbmUnCiAgICBjb21tYW5kOiAncmVkaXMtc2VydmVyIC0tbWF4bWVtb3J5IDIwMG1iIC0tbWF4bWVtb3J5LXBvbGljeSBhbGxrZXlzLWxydScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIFBJTkcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAyCg==", + "tags": [ + "cryptgeon", + "secure", + "note", + "sharing", + "privnote", + "file", + "sharing" + ], + "logo": "svgs/cryptgeon.png", + "minversion": "0.0.0", + "port": "8000" + }, "dashboard": { "documentation": "https://github.com/phntxx/dashboard?tab=readme-ov-file#dashboard?utm_source=coolify.io", "slogan": "A dashboard, inspired by SUI.", @@ -357,6 +407,28 @@ "minversion": "0.0.0", "port": "8080" }, + "dify": { + "documentation": "https://docs.dify.ai?utm_source=coolify.io", + "slogan": "Dify is an open-source LLM app development platform. Dify's intuitive interface combines AI workflow, RAG pipeline, agent capabilities, model management, observability features and more, letting you quickly go from prototype to production.", + "compose": "eC1zaGFyZWQtZW52OgogIExPR19MRVZFTDogJyR7TE9HX0xFVkVMOi1JTkZPfScKICBERUJVRzogJyR7REVCVUc6LWZhbHNlfScKICBGTEFTS19ERUJVRzogJyR7RkxBU0tfREVCVUc6LWZhbHNlfScKICBDT05TT0xFX1dFQl9VUkw6ICcke0NPTlNPTEVfV0VCX1VSTDotfScKICBDT05TT0xFX0FQSV9VUkw6ICcke0NPTlNPTEVfQVBJX1VSTDotfScKICBTRVJWSUNFX0FQSV9VUkw6IG51bGwKICBBUFBfV0VCX1VSTDogJyR7QVBQX1dFQl9VUkw6LX0nCiAgQ0hFQ0tfVVBEQVRFX1VSTDogJyR7Q0hFQ0tfVVBEQVRFX1VSTDotaHR0cHM6Ly91cGRhdGVzLmRpZnkuYWl9JwogIE9QRU5BSV9BUElfQkFTRTogJyR7T1BFTkFJX0FQSV9CQVNFOi1odHRwczovL2FwaS5vcGVuYWkuY29tL3YxfScKICBGSUxFU19VUkw6ICcke0ZJTEVTX1VSTDotfScKICBGSUxFU19BQ0NFU1NfVElNRU9VVDogJyR7RklMRVNfQUNDRVNTX1RJTUVPVVQ6LTMwMH0nCiAgQVBQX01BWF9BQ1RJVkVfUkVRVUVTVFM6ICcke0FQUF9NQVhfQUNUSVZFX1JFUVVFU1RTOi0wfScKICBNSUdSQVRJT05fRU5BQkxFRDogJyR7TUlHUkFUSU9OX0VOQUJMRUQ6LXRydWV9JwogIERFUExPWV9FTlY6ICcke0RFUExPWV9FTlY6LVBST0RVQ1RJT059JwogIERJRllfQklORF9BRERSRVNTOiAnJHtESUZZX0JJTkRfQUREUkVTUzotMC4wLjAuMH0nCiAgRElGWV9QT1JUOiAnJHtESUZZX1BPUlQ6LTUwMDF9JwogIFNFUlZFUl9XT1JLRVJfQU1PVU5UOiAnJHtTRVJWRVJfV09SS0VSX0FNT1VOVDotfScKICBTRVJWRVJfV09SS0VSX0NMQVNTOiAnJHtTRVJWRVJfV09SS0VSX0NMQVNTOi19JwogIENFTEVSWV9XT1JLRVJfQ0xBU1M6ICcke0NFTEVSWV9XT1JLRVJfQ0xBU1M6LX0nCiAgR1VOSUNPUk5fVElNRU9VVDogJyR7R1VOSUNPUk5fVElNRU9VVDotMzYwfScKICBDRUxFUllfV09SS0VSX0FNT1VOVDogJyR7Q0VMRVJZX1dPUktFUl9BTU9VTlQ6LX0nCiAgQ0VMRVJZX0FVVE9fU0NBTEU6ICcke0NFTEVSWV9BVVRPX1NDQUxFOi1mYWxzZX0nCiAgQ0VMRVJZX01BWF9XT1JLRVJTOiAnJHtDRUxFUllfTUFYX1dPUktFUlM6LX0nCiAgQ0VMRVJZX01JTl9XT1JLRVJTOiAnJHtDRUxFUllfTUlOX1dPUktFUlM6LX0nCiAgQVBJX1RPT0xfREVGQVVMVF9DT05ORUNUX1RJTUVPVVQ6ICcke0FQSV9UT09MX0RFRkFVTFRfQ09OTkVDVF9USU1FT1VUOi0xMH0nCiAgQVBJX1RPT0xfREVGQVVMVF9SRUFEX1RJTUVPVVQ6ICcke0FQSV9UT09MX0RFRkFVTFRfUkVBRF9USU1FT1VUOi02MH0nCiAgREJfVVNFUk5BTUU6ICRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICBEQl9QQVNTV09SRDogJFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICBEQl9IT1NUOiAnJHtEQl9IT1NUOi1kYn0nCiAgREJfUE9SVDogJyR7REJfUE9SVDotNTQzMn0nCiAgREJfREFUQUJBU0U6IGRpZnkKICBTUUxBTENIRU1ZX1BPT0xfU0laRTogJyR7U1FMQUxDSEVNWV9QT09MX1NJWkU6LTMwfScKICBTUUxBTENIRU1ZX1BPT0xfUkVDWUNMRTogJyR7U1FMQUxDSEVNWV9QT09MX1JFQ1lDTEU6LTM2MDB9JwogIFNRTEFMQ0hFTVlfRUNITzogJyR7U1FMQUxDSEVNWV9FQ0hPOi1mYWxzZX0nCiAgUE9TVEdSRVNfTUFYX0NPTk5FQ1RJT05TOiAnJHtQT1NUR1JFU19NQVhfQ09OTkVDVElPTlM6LTEwMH0nCiAgUE9TVEdSRVNfU0hBUkVEX0JVRkZFUlM6ICcke1BPU1RHUkVTX1NIQVJFRF9CVUZGRVJTOi0xMjhNQn0nCiAgUE9TVEdSRVNfV09SS19NRU06ICcke1BPU1RHUkVTX1dPUktfTUVNOi00TUJ9JwogIFBPU1RHUkVTX01BSU5URU5BTkNFX1dPUktfTUVNOiAnJHtQT1NUR1JFU19NQUlOVEVOQU5DRV9XT1JLX01FTTotNjRNQn0nCiAgUE9TVEdSRVNfRUZGRUNUSVZFX0NBQ0hFX1NJWkU6ICcke1BPU1RHUkVTX0VGRkVDVElWRV9DQUNIRV9TSVpFOi00MDk2TUJ9JwogIFJFRElTX0hPU1Q6ICcke1JFRElTX0hPU1Q6LXJlZGlzfScKICBSRURJU19QT1JUOiAnJHtSRURJU19QT1JUOi02Mzc5fScKICBSRURJU19VU0VSTkFNRTogJyR7UkVESVNfVVNFUk5BTUU6LX0nCiAgUkVESVNfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgUkVESVNfVVNFX1NTTDogJyR7UkVESVNfVVNFX1NTTDotZmFsc2V9JwogIFJFRElTX0RCOiAwCiAgQ0VMRVJZX0JST0tFUl9VUkw6ICdyZWRpczovLzokU0VSVklDRV9QQVNTV09SRF9SRURJU0ByZWRpczo2Mzc5LzEnCiAgQlJPS0VSX1VTRV9TU0w6ICcke0JST0tFUl9VU0VfU1NMOi1mYWxzZX0nCiAgV0VCX0FQSV9DT1JTX0FMTE9XX09SSUdJTlM6ICcke1dFQl9BUElfQ09SU19BTExPV19PUklHSU5TOi0qfScKICBDT05TT0xFX0NPUlNfQUxMT1dfT1JJR0lOUzogJyR7Q09OU09MRV9DT1JTX0FMTE9XX09SSUdJTlM6LSp9JwogIFNUT1JBR0VfVFlQRTogJyR7U1RPUkFHRV9UWVBFOi1sb2NhbH0nCiAgU1RPUkFHRV9MT0NBTF9QQVRIOiBzdG9yYWdlCiAgUzNfVVNFX0FXU19NQU5BR0VEX0lBTTogJyR7UzNfVVNFX0FXU19NQU5BR0VEX0lBTTotZmFsc2V9JwogIFMzX0VORFBPSU5UOiAnJHtTM19FTkRQT0lOVDotfScKICBTM19CVUNLRVRfTkFNRTogJyR7UzNfQlVDS0VUX05BTUU6LX0nCiAgUzNfQUNDRVNTX0tFWTogJyR7UzNfQUNDRVNTX0tFWTotfScKICBTM19TRUNSRVRfS0VZOiAnJHtTM19TRUNSRVRfS0VZOi19JwogIFMzX1JFR0lPTjogJyR7UzNfUkVHSU9OOi11cy1lYXN0LTF9JwogIEFaVVJFX0JMT0JfQUNDT1VOVF9OQU1FOiAnJHtBWlVSRV9CTE9CX0FDQ09VTlRfTkFNRTotfScKICBBWlVSRV9CTE9CX0FDQ09VTlRfS0VZOiAnJHtBWlVSRV9CTE9CX0FDQ09VTlRfS0VZOi19JwogIEFaVVJFX0JMT0JfQ09OVEFJTkVSX05BTUU6ICcke0FaVVJFX0JMT0JfQ09OVEFJTkVSX05BTUU6LX0nCiAgQVpVUkVfQkxPQl9BQ0NPVU5UX1VSTDogJyR7QVpVUkVfQkxPQl9BQ0NPVU5UX1VSTDotfScKICBHT09HTEVfU1RPUkFHRV9CVUNLRVRfTkFNRTogJyR7R09PR0xFX1NUT1JBR0VfQlVDS0VUX05BTUU6LX0nCiAgR09PR0xFX1NUT1JBR0VfU0VSVklDRV9BQ0NPVU5UX0pTT05fQkFTRTY0OiAnJHtHT09HTEVfU1RPUkFHRV9TRVJWSUNFX0FDQ09VTlRfSlNPTl9CQVNFNjQ6LX0nCiAgQUxJWVVOX09TU19CVUNLRVRfTkFNRTogJyR7QUxJWVVOX09TU19CVUNLRVRfTkFNRTotfScKICBBTElZVU5fT1NTX0FDQ0VTU19LRVk6ICcke0FMSVlVTl9PU1NfQUNDRVNTX0tFWTotfScKICBBTElZVU5fT1NTX1NFQ1JFVF9LRVk6ICcke0FMSVlVTl9PU1NfU0VDUkVUX0tFWTotfScKICBBTElZVU5fT1NTX0VORFBPSU5UOiAnJHtBTElZVU5fT1NTX0VORFBPSU5UOi19JwogIEFMSVlVTl9PU1NfUkVHSU9OOiAnJHtBTElZVU5fT1NTX1JFR0lPTjotfScKICBBTElZVU5fT1NTX0FVVEhfVkVSU0lPTjogJyR7QUxJWVVOX09TU19BVVRIX1ZFUlNJT046LXY0fScKICBURU5DRU5UX0NPU19CVUNLRVRfTkFNRTogJyR7VEVOQ0VOVF9DT1NfQlVDS0VUX05BTUU6LX0nCiAgVEVOQ0VOVF9DT1NfU0VDUkVUX0tFWTogJyR7VEVOQ0VOVF9DT1NfU0VDUkVUX0tFWTotfScKICBURU5DRU5UX0NPU19TRUNSRVRfSUQ6ICcke1RFTkNFTlRfQ09TX1NFQ1JFVF9JRDotfScKICBURU5DRU5UX0NPU19SRUdJT046ICcke1RFTkNFTlRfQ09TX1JFR0lPTjotfScKICBURU5DRU5UX0NPU19TQ0hFTUU6ICcke1RFTkNFTlRfQ09TX1NDSEVNRTotfScKICBPQ0lfRU5EUE9JTlQ6ICcke09DSV9FTkRQT0lOVDotfScKICBPQ0lfQlVDS0VUX05BTUU6ICcke09DSV9CVUNLRVRfTkFNRTotfScKICBPQ0lfQUNDRVNTX0tFWTogJyR7T0NJX0FDQ0VTU19LRVk6LX0nCiAgT0NJX1NFQ1JFVF9LRVk6ICcke09DSV9TRUNSRVRfS0VZOi19JwogIE9DSV9SRUdJT046ICcke09DSV9SRUdJT046LX0nCiAgVkVDVE9SX1NUT1JFOiAnJHtWRUNUT1JfU1RPUkU6LXdlYXZpYXRlfScKICBXRUFWSUFURV9FTkRQT0lOVDogJyR7V0VBVklBVEVfRU5EUE9JTlQ6LWh0dHA6Ly93ZWF2aWF0ZTo4MDgwfScKICBXRUFWSUFURV9BUElfS0VZOiAkU0VSVklDRV9QQVNTV09SRF9XRUFWSUFURQogIFJFTFlUX0hPU1Q6ICcke1JFTFlUX0hPU1Q6LWRifScKICBSRUxZVF9QT1JUOiAnJHtSRUxZVF9QT1JUOi01NDMyfScKICBSRUxZVF9VU0VSOiAkU0VSVklDRV9VU0VSX1JFTFlUCiAgUkVMWVRfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1JFTFlUCiAgUkVMWVRfREFUQUJBU0U6ICcke1JFTFlUX0RBVEFCQVNFOi1wb3N0Z3Jlc30nCiAgVElEQl9WRUNUT1JfSE9TVDogJyR7VElEQl9WRUNUT1JfSE9TVDotdGlkYn0nCiAgVElEQl9WRUNUT1JfUE9SVDogJyR7VElEQl9WRUNUT1JfUE9SVDotNDAwMH0nCiAgVElEQl9WRUNUT1JfVVNFUjogJFNFUlZJQ0VfVVNFUl9USURCCiAgVElEQl9WRUNUT1JfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1RJREIKICBUSURCX1ZFQ1RPUl9EQVRBQkFTRTogJyR7VElEQl9WRUNUT1JfREFUQUJBU0U6LWRpZnl9JwogIEFOQUxZVElDREJfS0VZX0lEOiAnJHtBTkFMWVRJQ0RCX0tFWV9JRDotfScKICBBTkFMWVRJQ0RCX0tFWV9TRUNSRVQ6ICcke0FOQUxZVElDREJfS0VZX1NFQ1JFVDotfScKICBBTkFMWVRJQ0RCX1JFR0lPTl9JRDogJyR7QU5BTFlUSUNEQl9SRUdJT05fSUQ6LX0nCiAgQU5BTFlUSUNEQl9JTlNUQU5DRV9JRDogJyR7QU5BTFlUSUNEQl9JTlNUQU5DRV9JRDotfScKICBBTkFMWVRJQ0RCX0FDQ09VTlQ6ICcke0FOQUxZVElDREJfQUNDT1VOVDotfScKICBBTkFMWVRJQ0RCX1BBU1NXT1JEOiAnJHtBTkFMWVRJQ0RCX1BBU1NXT1JEOi19JwogIEFOQUxZVElDREJfTkFNRVNQQUNFOiAnJHtBTkFMWVRJQ0RCX05BTUVTUEFDRTotZGlmeX0nCiAgQU5BTFlUSUNEQl9OQU1FU1BBQ0VfUEFTU1dPUkQ6ICcke0FOQUxZVElDREJfTkFNRVNQQUNFX1BBU1NXT1JEOi19JwogIFRFTkNFTlRfVkVDVE9SX0RCX1VSTDogJyR7VEVOQ0VOVF9WRUNUT1JfREJfVVJMOi1odHRwOi8vMTI3LjAuMC4xfScKICBURU5DRU5UX1ZFQ1RPUl9EQl9BUElfS0VZOiAnJHtURU5DRU5UX1ZFQ1RPUl9EQl9BUElfS0VZOi1kaWZ5fScKICBURU5DRU5UX1ZFQ1RPUl9EQl9USU1FT1VUOiAnJHtURU5DRU5UX1ZFQ1RPUl9EQl9USU1FT1VUOi0zMH0nCiAgVEVOQ0VOVF9WRUNUT1JfREJfVVNFUk5BTUU6ICcke1RFTkNFTlRfVkVDVE9SX0RCX1VTRVJOQU1FOi1kaWZ5fScKICBURU5DRU5UX1ZFQ1RPUl9EQl9EQVRBQkFTRTogJyR7VEVOQ0VOVF9WRUNUT1JfREJfREFUQUJBU0U6LWRpZnl9JwogIFRFTkNFTlRfVkVDVE9SX0RCX1NIQVJEOiAnJHtURU5DRU5UX1ZFQ1RPUl9EQl9TSEFSRDotMX0nCiAgVEVOQ0VOVF9WRUNUT1JfREJfUkVQTElDQVM6ICcke1RFTkNFTlRfVkVDVE9SX0RCX1JFUExJQ0FTOi0yfScKICBVUExPQURfRklMRV9TSVpFX0xJTUlUOiAnJHtVUExPQURfRklMRV9TSVpFX0xJTUlUOi0xNX0nCiAgVVBMT0FEX0ZJTEVfQkFUQ0hfTElNSVQ6ICcke1VQTE9BRF9GSUxFX0JBVENIX0xJTUlUOi01fScKICBFVExfVFlQRTogJyR7RVRMX1RZUEU6LWRpZnl9JwogIE1VTFRJTU9EQUxfU0VORF9JTUFHRV9GT1JNQVQ6ICcke01VTFRJTU9EQUxfU0VORF9JTUFHRV9GT1JNQVQ6LWJhc2U2NH0nCiAgVVBMT0FEX0lNQUdFX0ZJTEVfU0laRV9MSU1JVDogJyR7VVBMT0FEX0lNQUdFX0ZJTEVfU0laRV9MSU1JVDotMTB9JwogIFNFTlRSWV9EU046ICcke0FQSV9TRU5UUllfRFNOOi19JwogIFNFTlRSWV9UUkFDRVNfU0FNUExFX1JBVEU6ICcke0FQSV9TRU5UUllfVFJBQ0VTX1NBTVBMRV9SQVRFOi0xLjB9JwogIFNFTlRSWV9QUk9GSUxFU19TQU1QTEVfUkFURTogJyR7QVBJX1NFTlRSWV9QUk9GSUxFU19TQU1QTEVfUkFURTotMS4wfScKICBOT1RJT05fSU5URUdSQVRJT05fVFlQRTogJyR7Tk9USU9OX0lOVEVHUkFUSU9OX1RZUEU6LXB1YmxpY30nCiAgTk9USU9OX0NMSUVOVF9TRUNSRVQ6ICcke05PVElPTl9DTElFTlRfU0VDUkVUOi19JwogIE5PVElPTl9DTElFTlRfSUQ6ICcke05PVElPTl9DTElFTlRfSUQ6LX0nCiAgTk9USU9OX0lOVEVSTkFMX1NFQ1JFVDogJyR7Tk9USU9OX0lOVEVSTkFMX1NFQ1JFVDotfScKICBNQUlMX1RZUEU6ICcke01BSUxfVFlQRTotcmVzZW5kfScKICBNQUlMX0RFRkFVTFRfU0VORF9GUk9NOiAnJHtNQUlMX0RFRkFVTFRfU0VORF9GUk9NOi19JwogIFNNVFBfU0VSVkVSOiAnJHtTTVRQX1NFUlZFUjotfScKICBTTVRQX1BPUlQ6ICcke1NNVFBfUE9SVDotNDY1fScKICBTTVRQX1VTRVJOQU1FOiAnJHtTTVRQX1VTRVJOQU1FOi19JwogIFNNVFBfUEFTU1dPUkQ6ICcke1NNVFBfUEFTU1dPUkQ6LX0nCiAgU01UUF9VU0VfVExTOiAnJHtTTVRQX1VTRV9UTFM6LXRydWV9JwogIFNNVFBfT1BQT1JUVU5JU1RJQ19UTFM6ICcke1NNVFBfT1BQT1JUVU5JU1RJQ19UTFM6LWZhbHNlfScKICBSRVNFTkRfQVBJX0tFWTogJyR7UkVTRU5EX0FQSV9LRVk6LXlvdXItcmVzZW5kLWFwaS1rZXl9JwogIFJFU0VORF9BUElfVVJMOiAnaHR0cHM6Ly9hcGkucmVzZW5kLmNvbScKICBJTkRFWElOR19NQVhfU0VHTUVOVEFUSU9OX1RPS0VOU19MRU5HVEg6ICcke0lOREVYSU5HX01BWF9TRUdNRU5UQVRJT05fVE9LRU5TX0xFTkdUSDotMTAwMH0nCiAgSU5WSVRFX0VYUElSWV9IT1VSUzogJyR7SU5WSVRFX0VYUElSWV9IT1VSUzotNzJ9JwogIFJFU0VUX1BBU1NXT1JEX1RPS0VOX0VYUElSWV9IT1VSUzogJyR7UkVTRVRfUEFTU1dPUkRfVE9LRU5fRVhQSVJZX0hPVVJTOi0yNH0nCiAgQ09ERV9FWEVDVVRJT05fRU5EUE9JTlQ6ICcke0NPREVfRVhFQ1VUSU9OX0VORFBPSU5UOi1odHRwOi8vc2FuZGJveDo4MTk0fScKICBDT0RFX0VYRUNVVElPTl9BUElfS0VZOiAnJHtTQU5EQk9YX0FQSV9LRVk6LWRpZnktc2FuZGJveH0nCiAgQ09ERV9NQVhfTlVNQkVSOiAnJHtDT0RFX01BWF9OVU1CRVI6LTkyMjMzNzIwMzY4NTQ3NzU4MDd9JwogIENPREVfTUlOX05VTUJFUjogJyR7Q09ERV9NSU5fTlVNQkVSOi0tOTIyMzM3MjAzNjg1NDc3NTgwOH0nCiAgQ09ERV9NQVhfU1RSSU5HX0xFTkdUSDogJyR7Q09ERV9NQVhfU1RSSU5HX0xFTkdUSDotODAwMDB9JwogIFRFTVBMQVRFX1RSQU5TRk9STV9NQVhfTEVOR1RIOiAnJHtURU1QTEFURV9UUkFOU0ZPUk1fTUFYX0xFTkdUSDotODAwMDB9JwogIENPREVfTUFYX1NUUklOR19BUlJBWV9MRU5HVEg6ICcke0NPREVfTUFYX1NUUklOR19BUlJBWV9MRU5HVEg6LTMwfScKICBDT0RFX01BWF9PQkpFQ1RfQVJSQVlfTEVOR1RIOiAnJHtDT0RFX01BWF9PQkpFQ1RfQVJSQVlfTEVOR1RIOi0zMH0nCiAgQ09ERV9NQVhfTlVNQkVSX0FSUkFZX0xFTkdUSDogJyR7Q09ERV9NQVhfTlVNQkVSX0FSUkFZX0xFTkdUSDotMTAwMH0nCiAgU1NSRl9QUk9YWV9IVFRQX1VSTDogJyR7U1NSRl9QUk9YWV9IVFRQX1VSTDotaHR0cDovL3NzcmZfcHJveHk6MzEyOH0nCiAgU1NSRl9QUk9YWV9IVFRQU19VUkw6ICcke1NTUkZfUFJPWFlfSFRUUFNfVVJMOi1odHRwOi8vc3NyZl9wcm94eTozMTI4fScKc2VydmljZXM6CiAgYXBpOgogICAgaW1hZ2U6ICdsYW5nZ2VuaXVzL2RpZnktYXBpOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICBTRUNSRVRfS0VZOiAkU0VSVklDRV9QQVNTV09SRF82NF9TRUNSRVRLRVkKICAgICAgSU5JVF9QQVNTV09SRDogJFNFUlZJQ0VfVVNFUl9JTklUUEFTU1dPUkQKICAgICAgTE9HX0xFVkVMOiAnJHtMT0dfTEVWRUw6LUlORk99JwogICAgICBERUJVRzogJyR7REVCVUc6LWZhbHNlfScKICAgICAgRkxBU0tfREVCVUc6ICcke0ZMQVNLX0RFQlVHOi1mYWxzZX0nCiAgICAgIENPTlNPTEVfV0VCX1VSTDogJyR7Q09OU09MRV9XRUJfVVJMOi19JwogICAgICBDT05TT0xFX0FQSV9VUkw6ICcke0NPTlNPTEVfQVBJX1VSTDotfScKICAgICAgU0VSVklDRV9BUElfVVJMOiBudWxsCiAgICAgIEFQUF9XRUJfVVJMOiAnJHtBUFBfV0VCX1VSTDotfScKICAgICAgQ0hFQ0tfVVBEQVRFX1VSTDogJyR7Q0hFQ0tfVVBEQVRFX1VSTDotaHR0cHM6Ly91cGRhdGVzLmRpZnkuYWl9JwogICAgICBPUEVOQUlfQVBJX0JBU0U6ICcke09QRU5BSV9BUElfQkFTRTotaHR0cHM6Ly9hcGkub3BlbmFpLmNvbS92MX0nCiAgICAgIEZJTEVTX1VSTDogJyR7RklMRVNfVVJMOi19JwogICAgICBGSUxFU19BQ0NFU1NfVElNRU9VVDogJyR7RklMRVNfQUNDRVNTX1RJTUVPVVQ6LTMwMH0nCiAgICAgIEFQUF9NQVhfQUNUSVZFX1JFUVVFU1RTOiAnJHtBUFBfTUFYX0FDVElWRV9SRVFVRVNUUzotMH0nCiAgICAgIE1JR1JBVElPTl9FTkFCTEVEOiAnJHtNSUdSQVRJT05fRU5BQkxFRDotdHJ1ZX0nCiAgICAgIERFUExPWV9FTlY6ICcke0RFUExPWV9FTlY6LVBST0RVQ1RJT059JwogICAgICBESUZZX0JJTkRfQUREUkVTUzogJyR7RElGWV9CSU5EX0FERFJFU1M6LTAuMC4wLjB9JwogICAgICBESUZZX1BPUlQ6ICcke0RJRllfUE9SVDotNTAwMX0nCiAgICAgIFNFUlZFUl9XT1JLRVJfQU1PVU5UOiAnJHtTRVJWRVJfV09SS0VSX0FNT1VOVDotfScKICAgICAgU0VSVkVSX1dPUktFUl9DTEFTUzogJyR7U0VSVkVSX1dPUktFUl9DTEFTUzotfScKICAgICAgQ0VMRVJZX1dPUktFUl9DTEFTUzogJyR7Q0VMRVJZX1dPUktFUl9DTEFTUzotfScKICAgICAgR1VOSUNPUk5fVElNRU9VVDogJyR7R1VOSUNPUk5fVElNRU9VVDotMzYwfScKICAgICAgQ0VMRVJZX1dPUktFUl9BTU9VTlQ6ICcke0NFTEVSWV9XT1JLRVJfQU1PVU5UOi19JwogICAgICBDRUxFUllfQVVUT19TQ0FMRTogJyR7Q0VMRVJZX0FVVE9fU0NBTEU6LWZhbHNlfScKICAgICAgQ0VMRVJZX01BWF9XT1JLRVJTOiAnJHtDRUxFUllfTUFYX1dPUktFUlM6LX0nCiAgICAgIENFTEVSWV9NSU5fV09SS0VSUzogJyR7Q0VMRVJZX01JTl9XT1JLRVJTOi19JwogICAgICBBUElfVE9PTF9ERUZBVUxUX0NPTk5FQ1RfVElNRU9VVDogJyR7QVBJX1RPT0xfREVGQVVMVF9DT05ORUNUX1RJTUVPVVQ6LTEwfScKICAgICAgQVBJX1RPT0xfREVGQVVMVF9SRUFEX1RJTUVPVVQ6ICcke0FQSV9UT09MX0RFRkFVTFRfUkVBRF9USU1FT1VUOi02MH0nCiAgICAgIERCX1VTRVJOQU1FOiAkU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIERCX1BBU1NXT1JEOiAkU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICBEQl9IT1NUOiAnJHtEQl9IT1NUOi1kYn0nCiAgICAgIERCX1BPUlQ6ICcke0RCX1BPUlQ6LTU0MzJ9JwogICAgICBEQl9EQVRBQkFTRTogZGlmeQogICAgICBTUUxBTENIRU1ZX1BPT0xfU0laRTogJyR7U1FMQUxDSEVNWV9QT09MX1NJWkU6LTMwfScKICAgICAgU1FMQUxDSEVNWV9QT09MX1JFQ1lDTEU6ICcke1NRTEFMQ0hFTVlfUE9PTF9SRUNZQ0xFOi0zNjAwfScKICAgICAgU1FMQUxDSEVNWV9FQ0hPOiAnJHtTUUxBTENIRU1ZX0VDSE86LWZhbHNlfScKICAgICAgUE9TVEdSRVNfTUFYX0NPTk5FQ1RJT05TOiAnJHtQT1NUR1JFU19NQVhfQ09OTkVDVElPTlM6LTEwMH0nCiAgICAgIFBPU1RHUkVTX1NIQVJFRF9CVUZGRVJTOiAnJHtQT1NUR1JFU19TSEFSRURfQlVGRkVSUzotMTI4TUJ9JwogICAgICBQT1NUR1JFU19XT1JLX01FTTogJyR7UE9TVEdSRVNfV09SS19NRU06LTRNQn0nCiAgICAgIFBPU1RHUkVTX01BSU5URU5BTkNFX1dPUktfTUVNOiAnJHtQT1NUR1JFU19NQUlOVEVOQU5DRV9XT1JLX01FTTotNjRNQn0nCiAgICAgIFBPU1RHUkVTX0VGRkVDVElWRV9DQUNIRV9TSVpFOiAnJHtQT1NUR1JFU19FRkZFQ1RJVkVfQ0FDSEVfU0laRTotNDA5Nk1CfScKICAgICAgUkVESVNfSE9TVDogJyR7UkVESVNfSE9TVDotcmVkaXN9JwogICAgICBSRURJU19QT1JUOiAnJHtSRURJU19QT1JUOi02Mzc5fScKICAgICAgUkVESVNfVVNFUk5BTUU6ICcke1JFRElTX1VTRVJOQU1FOi19JwogICAgICBSRURJU19QQVNTV09SRDogJFNFUlZJQ0VfUEFTU1dPUkRfUkVESVMKICAgICAgUkVESVNfVVNFX1NTTDogJyR7UkVESVNfVVNFX1NTTDotZmFsc2V9JwogICAgICBSRURJU19EQjogMAogICAgICBDRUxFUllfQlJPS0VSX1VSTDogJ3JlZGlzOi8vOiRTRVJWSUNFX1BBU1NXT1JEX1JFRElTQHJlZGlzOjYzNzkvMScKICAgICAgQlJPS0VSX1VTRV9TU0w6ICcke0JST0tFUl9VU0VfU1NMOi1mYWxzZX0nCiAgICAgIFdFQl9BUElfQ09SU19BTExPV19PUklHSU5TOiAnJHtXRUJfQVBJX0NPUlNfQUxMT1dfT1JJR0lOUzotKn0nCiAgICAgIENPTlNPTEVfQ09SU19BTExPV19PUklHSU5TOiAnJHtDT05TT0xFX0NPUlNfQUxMT1dfT1JJR0lOUzotKn0nCiAgICAgIFNUT1JBR0VfVFlQRTogJyR7U1RPUkFHRV9UWVBFOi1sb2NhbH0nCiAgICAgIFNUT1JBR0VfTE9DQUxfUEFUSDogc3RvcmFnZQogICAgICBTM19VU0VfQVdTX01BTkFHRURfSUFNOiAnJHtTM19VU0VfQVdTX01BTkFHRURfSUFNOi1mYWxzZX0nCiAgICAgIFMzX0VORFBPSU5UOiAnJHtTM19FTkRQT0lOVDotfScKICAgICAgUzNfQlVDS0VUX05BTUU6ICcke1MzX0JVQ0tFVF9OQU1FOi19JwogICAgICBTM19BQ0NFU1NfS0VZOiAnJHtTM19BQ0NFU1NfS0VZOi19JwogICAgICBTM19TRUNSRVRfS0VZOiAnJHtTM19TRUNSRVRfS0VZOi19JwogICAgICBTM19SRUdJT046ICcke1MzX1JFR0lPTjotdXMtZWFzdC0xfScKICAgICAgQVpVUkVfQkxPQl9BQ0NPVU5UX05BTUU6ICcke0FaVVJFX0JMT0JfQUNDT1VOVF9OQU1FOi19JwogICAgICBBWlVSRV9CTE9CX0FDQ09VTlRfS0VZOiAnJHtBWlVSRV9CTE9CX0FDQ09VTlRfS0VZOi19JwogICAgICBBWlVSRV9CTE9CX0NPTlRBSU5FUl9OQU1FOiAnJHtBWlVSRV9CTE9CX0NPTlRBSU5FUl9OQU1FOi19JwogICAgICBBWlVSRV9CTE9CX0FDQ09VTlRfVVJMOiAnJHtBWlVSRV9CTE9CX0FDQ09VTlRfVVJMOi19JwogICAgICBHT09HTEVfU1RPUkFHRV9CVUNLRVRfTkFNRTogJyR7R09PR0xFX1NUT1JBR0VfQlVDS0VUX05BTUU6LX0nCiAgICAgIEdPT0dMRV9TVE9SQUdFX1NFUlZJQ0VfQUNDT1VOVF9KU09OX0JBU0U2NDogJyR7R09PR0xFX1NUT1JBR0VfU0VSVklDRV9BQ0NPVU5UX0pTT05fQkFTRTY0Oi19JwogICAgICBBTElZVU5fT1NTX0JVQ0tFVF9OQU1FOiAnJHtBTElZVU5fT1NTX0JVQ0tFVF9OQU1FOi19JwogICAgICBBTElZVU5fT1NTX0FDQ0VTU19LRVk6ICcke0FMSVlVTl9PU1NfQUNDRVNTX0tFWTotfScKICAgICAgQUxJWVVOX09TU19TRUNSRVRfS0VZOiAnJHtBTElZVU5fT1NTX1NFQ1JFVF9LRVk6LX0nCiAgICAgIEFMSVlVTl9PU1NfRU5EUE9JTlQ6ICcke0FMSVlVTl9PU1NfRU5EUE9JTlQ6LX0nCiAgICAgIEFMSVlVTl9PU1NfUkVHSU9OOiAnJHtBTElZVU5fT1NTX1JFR0lPTjotfScKICAgICAgQUxJWVVOX09TU19BVVRIX1ZFUlNJT046ICcke0FMSVlVTl9PU1NfQVVUSF9WRVJTSU9OOi12NH0nCiAgICAgIFRFTkNFTlRfQ09TX0JVQ0tFVF9OQU1FOiAnJHtURU5DRU5UX0NPU19CVUNLRVRfTkFNRTotfScKICAgICAgVEVOQ0VOVF9DT1NfU0VDUkVUX0tFWTogJyR7VEVOQ0VOVF9DT1NfU0VDUkVUX0tFWTotfScKICAgICAgVEVOQ0VOVF9DT1NfU0VDUkVUX0lEOiAnJHtURU5DRU5UX0NPU19TRUNSRVRfSUQ6LX0nCiAgICAgIFRFTkNFTlRfQ09TX1JFR0lPTjogJyR7VEVOQ0VOVF9DT1NfUkVHSU9OOi19JwogICAgICBURU5DRU5UX0NPU19TQ0hFTUU6ICcke1RFTkNFTlRfQ09TX1NDSEVNRTotfScKICAgICAgT0NJX0VORFBPSU5UOiAnJHtPQ0lfRU5EUE9JTlQ6LX0nCiAgICAgIE9DSV9CVUNLRVRfTkFNRTogJyR7T0NJX0JVQ0tFVF9OQU1FOi19JwogICAgICBPQ0lfQUNDRVNTX0tFWTogJyR7T0NJX0FDQ0VTU19LRVk6LX0nCiAgICAgIE9DSV9TRUNSRVRfS0VZOiAnJHtPQ0lfU0VDUkVUX0tFWTotfScKICAgICAgT0NJX1JFR0lPTjogJyR7T0NJX1JFR0lPTjotfScKICAgICAgVkVDVE9SX1NUT1JFOiAnJHtWRUNUT1JfU1RPUkU6LXdlYXZpYXRlfScKICAgICAgV0VBVklBVEVfRU5EUE9JTlQ6ICcke1dFQVZJQVRFX0VORFBPSU5UOi1odHRwOi8vd2VhdmlhdGU6ODA4MH0nCiAgICAgIFdFQVZJQVRFX0FQSV9LRVk6ICRTRVJWSUNFX1BBU1NXT1JEX1dFQVZJQVRFCiAgICAgIFJFTFlUX0hPU1Q6ICcke1JFTFlUX0hPU1Q6LWRifScKICAgICAgUkVMWVRfUE9SVDogJyR7UkVMWVRfUE9SVDotNTQzMn0nCiAgICAgIFJFTFlUX1VTRVI6ICRTRVJWSUNFX1VTRVJfUkVMWVQKICAgICAgUkVMWVRfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1JFTFlUCiAgICAgIFJFTFlUX0RBVEFCQVNFOiAnJHtSRUxZVF9EQVRBQkFTRTotcG9zdGdyZXN9JwogICAgICBUSURCX1ZFQ1RPUl9IT1NUOiAnJHtUSURCX1ZFQ1RPUl9IT1NUOi10aWRifScKICAgICAgVElEQl9WRUNUT1JfUE9SVDogJyR7VElEQl9WRUNUT1JfUE9SVDotNDAwMH0nCiAgICAgIFRJREJfVkVDVE9SX1VTRVI6ICRTRVJWSUNFX1VTRVJfVElEQgogICAgICBUSURCX1ZFQ1RPUl9QQVNTV09SRDogJFNFUlZJQ0VfUEFTU1dPUkRfVElEQgogICAgICBUSURCX1ZFQ1RPUl9EQVRBQkFTRTogJyR7VElEQl9WRUNUT1JfREFUQUJBU0U6LWRpZnl9JwogICAgICBBTkFMWVRJQ0RCX0tFWV9JRDogJyR7QU5BTFlUSUNEQl9LRVlfSUQ6LX0nCiAgICAgIEFOQUxZVElDREJfS0VZX1NFQ1JFVDogJyR7QU5BTFlUSUNEQl9LRVlfU0VDUkVUOi19JwogICAgICBBTkFMWVRJQ0RCX1JFR0lPTl9JRDogJyR7QU5BTFlUSUNEQl9SRUdJT05fSUQ6LX0nCiAgICAgIEFOQUxZVElDREJfSU5TVEFOQ0VfSUQ6ICcke0FOQUxZVElDREJfSU5TVEFOQ0VfSUQ6LX0nCiAgICAgIEFOQUxZVElDREJfQUNDT1VOVDogJyR7QU5BTFlUSUNEQl9BQ0NPVU5UOi19JwogICAgICBBTkFMWVRJQ0RCX1BBU1NXT1JEOiAnJHtBTkFMWVRJQ0RCX1BBU1NXT1JEOi19JwogICAgICBBTkFMWVRJQ0RCX05BTUVTUEFDRTogJyR7QU5BTFlUSUNEQl9OQU1FU1BBQ0U6LWRpZnl9JwogICAgICBBTkFMWVRJQ0RCX05BTUVTUEFDRV9QQVNTV09SRDogJyR7QU5BTFlUSUNEQl9OQU1FU1BBQ0VfUEFTU1dPUkQ6LX0nCiAgICAgIFRFTkNFTlRfVkVDVE9SX0RCX1VSTDogJyR7VEVOQ0VOVF9WRUNUT1JfREJfVVJMOi1odHRwOi8vMTI3LjAuMC4xfScKICAgICAgVEVOQ0VOVF9WRUNUT1JfREJfQVBJX0tFWTogJyR7VEVOQ0VOVF9WRUNUT1JfREJfQVBJX0tFWTotZGlmeX0nCiAgICAgIFRFTkNFTlRfVkVDVE9SX0RCX1RJTUVPVVQ6ICcke1RFTkNFTlRfVkVDVE9SX0RCX1RJTUVPVVQ6LTMwfScKICAgICAgVEVOQ0VOVF9WRUNUT1JfREJfVVNFUk5BTUU6ICcke1RFTkNFTlRfVkVDVE9SX0RCX1VTRVJOQU1FOi1kaWZ5fScKICAgICAgVEVOQ0VOVF9WRUNUT1JfREJfREFUQUJBU0U6ICcke1RFTkNFTlRfVkVDVE9SX0RCX0RBVEFCQVNFOi1kaWZ5fScKICAgICAgVEVOQ0VOVF9WRUNUT1JfREJfU0hBUkQ6ICcke1RFTkNFTlRfVkVDVE9SX0RCX1NIQVJEOi0xfScKICAgICAgVEVOQ0VOVF9WRUNUT1JfREJfUkVQTElDQVM6ICcke1RFTkNFTlRfVkVDVE9SX0RCX1JFUExJQ0FTOi0yfScKICAgICAgVVBMT0FEX0ZJTEVfU0laRV9MSU1JVDogJyR7VVBMT0FEX0ZJTEVfU0laRV9MSU1JVDotMTV9JwogICAgICBVUExPQURfRklMRV9CQVRDSF9MSU1JVDogJyR7VVBMT0FEX0ZJTEVfQkFUQ0hfTElNSVQ6LTV9JwogICAgICBFVExfVFlQRTogJyR7RVRMX1RZUEU6LWRpZnl9JwogICAgICBNVUxUSU1PREFMX1NFTkRfSU1BR0VfRk9STUFUOiAnJHtNVUxUSU1PREFMX1NFTkRfSU1BR0VfRk9STUFUOi1iYXNlNjR9JwogICAgICBVUExPQURfSU1BR0VfRklMRV9TSVpFX0xJTUlUOiAnJHtVUExPQURfSU1BR0VfRklMRV9TSVpFX0xJTUlUOi0xMH0nCiAgICAgIFNFTlRSWV9EU046ICcke0FQSV9TRU5UUllfRFNOOi19JwogICAgICBTRU5UUllfVFJBQ0VTX1NBTVBMRV9SQVRFOiAnJHtBUElfU0VOVFJZX1RSQUNFU19TQU1QTEVfUkFURTotMS4wfScKICAgICAgU0VOVFJZX1BST0ZJTEVTX1NBTVBMRV9SQVRFOiAnJHtBUElfU0VOVFJZX1BST0ZJTEVTX1NBTVBMRV9SQVRFOi0xLjB9JwogICAgICBOT1RJT05fSU5URUdSQVRJT05fVFlQRTogJyR7Tk9USU9OX0lOVEVHUkFUSU9OX1RZUEU6LXB1YmxpY30nCiAgICAgIE5PVElPTl9DTElFTlRfU0VDUkVUOiAnJHtOT1RJT05fQ0xJRU5UX1NFQ1JFVDotfScKICAgICAgTk9USU9OX0NMSUVOVF9JRDogJyR7Tk9USU9OX0NMSUVOVF9JRDotfScKICAgICAgTk9USU9OX0lOVEVSTkFMX1NFQ1JFVDogJyR7Tk9USU9OX0lOVEVSTkFMX1NFQ1JFVDotfScKICAgICAgTUFJTF9UWVBFOiAnJHtNQUlMX1RZUEU6LXJlc2VuZH0nCiAgICAgIE1BSUxfREVGQVVMVF9TRU5EX0ZST006ICcke01BSUxfREVGQVVMVF9TRU5EX0ZST006LX0nCiAgICAgIFNNVFBfU0VSVkVSOiAnJHtTTVRQX1NFUlZFUjotfScKICAgICAgU01UUF9QT1JUOiAnJHtTTVRQX1BPUlQ6LTQ2NX0nCiAgICAgIFNNVFBfVVNFUk5BTUU6ICcke1NNVFBfVVNFUk5BTUU6LX0nCiAgICAgIFNNVFBfUEFTU1dPUkQ6ICcke1NNVFBfUEFTU1dPUkQ6LX0nCiAgICAgIFNNVFBfVVNFX1RMUzogJyR7U01UUF9VU0VfVExTOi10cnVlfScKICAgICAgU01UUF9PUFBPUlRVTklTVElDX1RMUzogJyR7U01UUF9PUFBPUlRVTklTVElDX1RMUzotZmFsc2V9JwogICAgICBSRVNFTkRfQVBJX0tFWTogJyR7UkVTRU5EX0FQSV9LRVk6LXlvdXItcmVzZW5kLWFwaS1rZXl9JwogICAgICBSRVNFTkRfQVBJX1VSTDogJ2h0dHBzOi8vYXBpLnJlc2VuZC5jb20nCiAgICAgIElOREVYSU5HX01BWF9TRUdNRU5UQVRJT05fVE9LRU5TX0xFTkdUSDogJyR7SU5ERVhJTkdfTUFYX1NFR01FTlRBVElPTl9UT0tFTlNfTEVOR1RIOi0xMDAwfScKICAgICAgSU5WSVRFX0VYUElSWV9IT1VSUzogJyR7SU5WSVRFX0VYUElSWV9IT1VSUzotNzJ9JwogICAgICBSRVNFVF9QQVNTV09SRF9UT0tFTl9FWFBJUllfSE9VUlM6ICcke1JFU0VUX1BBU1NXT1JEX1RPS0VOX0VYUElSWV9IT1VSUzotMjR9JwogICAgICBDT0RFX0VYRUNVVElPTl9FTkRQT0lOVDogJyR7Q09ERV9FWEVDVVRJT05fRU5EUE9JTlQ6LWh0dHA6Ly9zYW5kYm94OjgxOTR9JwogICAgICBDT0RFX0VYRUNVVElPTl9BUElfS0VZOiAnJHtTQU5EQk9YX0FQSV9LRVk6LWRpZnktc2FuZGJveH0nCiAgICAgIENPREVfTUFYX05VTUJFUjogJyR7Q09ERV9NQVhfTlVNQkVSOi05MjIzMzcyMDM2ODU0Nzc1ODA3fScKICAgICAgQ09ERV9NSU5fTlVNQkVSOiAnJHtDT0RFX01JTl9OVU1CRVI6LS05MjIzMzcyMDM2ODU0Nzc1ODA4fScKICAgICAgQ09ERV9NQVhfU1RSSU5HX0xFTkdUSDogJyR7Q09ERV9NQVhfU1RSSU5HX0xFTkdUSDotODAwMDB9JwogICAgICBURU1QTEFURV9UUkFOU0ZPUk1fTUFYX0xFTkdUSDogJyR7VEVNUExBVEVfVFJBTlNGT1JNX01BWF9MRU5HVEg6LTgwMDAwfScKICAgICAgQ09ERV9NQVhfU1RSSU5HX0FSUkFZX0xFTkdUSDogJyR7Q09ERV9NQVhfU1RSSU5HX0FSUkFZX0xFTkdUSDotMzB9JwogICAgICBDT0RFX01BWF9PQkpFQ1RfQVJSQVlfTEVOR1RIOiAnJHtDT0RFX01BWF9PQkpFQ1RfQVJSQVlfTEVOR1RIOi0zMH0nCiAgICAgIENPREVfTUFYX05VTUJFUl9BUlJBWV9MRU5HVEg6ICcke0NPREVfTUFYX05VTUJFUl9BUlJBWV9MRU5HVEg6LTEwMDB9JwogICAgICBTU1JGX1BST1hZX0hUVFBfVVJMOiAnJHtTU1JGX1BST1hZX0hUVFBfVVJMOi1odHRwOi8vc3NyZl9wcm94eTozMTI4fScKICAgICAgU1NSRl9QUk9YWV9IVFRQU19VUkw6ICcke1NTUkZfUFJPWFlfSFRUUFNfVVJMOi1odHRwOi8vc3NyZl9wcm94eTozMTI4fScKICAgICAgTU9ERTogYXBpCiAgICBkZXBlbmRzX29uOgogICAgICBkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgdm9sdW1lczoKICAgICAgLSAnZGlmeS1zdG9yYWdlOi9hcHAvYXBpL3N0b3JhZ2UnCiAgICBuZXR3b3JrczoKICAgICAgLSBzc3JmX3Byb3h5X25ldHdvcmsKICAgICAgLSBkZWZhdWx0CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6NTAwMS9oZWFsdGgnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMKICAgICAgc3RhcnRfcGVyaW9kOiA0MHMKICB3b3JrZXI6CiAgICBpbWFnZTogJ2xhbmdnZW5pdXMvZGlmeS1hcGk6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIExPR19MRVZFTDogJyR7TE9HX0xFVkVMOi1JTkZPfScKICAgICAgREVCVUc6ICcke0RFQlVHOi1mYWxzZX0nCiAgICAgIEZMQVNLX0RFQlVHOiAnJHtGTEFTS19ERUJVRzotZmFsc2V9JwogICAgICBDT05TT0xFX1dFQl9VUkw6ICcke0NPTlNPTEVfV0VCX1VSTDotfScKICAgICAgQ09OU09MRV9BUElfVVJMOiAnJHtDT05TT0xFX0FQSV9VUkw6LX0nCiAgICAgIFNFUlZJQ0VfQVBJX1VSTDogbnVsbAogICAgICBBUFBfV0VCX1VSTDogJyR7QVBQX1dFQl9VUkw6LX0nCiAgICAgIENIRUNLX1VQREFURV9VUkw6ICcke0NIRUNLX1VQREFURV9VUkw6LWh0dHBzOi8vdXBkYXRlcy5kaWZ5LmFpfScKICAgICAgT1BFTkFJX0FQSV9CQVNFOiAnJHtPUEVOQUlfQVBJX0JBU0U6LWh0dHBzOi8vYXBpLm9wZW5haS5jb20vdjF9JwogICAgICBGSUxFU19VUkw6ICcke0ZJTEVTX1VSTDotfScKICAgICAgRklMRVNfQUNDRVNTX1RJTUVPVVQ6ICcke0ZJTEVTX0FDQ0VTU19USU1FT1VUOi0zMDB9JwogICAgICBBUFBfTUFYX0FDVElWRV9SRVFVRVNUUzogJyR7QVBQX01BWF9BQ1RJVkVfUkVRVUVTVFM6LTB9JwogICAgICBNSUdSQVRJT05fRU5BQkxFRDogJyR7TUlHUkFUSU9OX0VOQUJMRUQ6LXRydWV9JwogICAgICBERVBMT1lfRU5WOiAnJHtERVBMT1lfRU5WOi1QUk9EVUNUSU9OfScKICAgICAgRElGWV9CSU5EX0FERFJFU1M6ICcke0RJRllfQklORF9BRERSRVNTOi0wLjAuMC4wfScKICAgICAgRElGWV9QT1JUOiAnJHtESUZZX1BPUlQ6LTUwMDF9JwogICAgICBTRVJWRVJfV09SS0VSX0FNT1VOVDogJyR7U0VSVkVSX1dPUktFUl9BTU9VTlQ6LX0nCiAgICAgIFNFUlZFUl9XT1JLRVJfQ0xBU1M6ICcke1NFUlZFUl9XT1JLRVJfQ0xBU1M6LX0nCiAgICAgIENFTEVSWV9XT1JLRVJfQ0xBU1M6ICcke0NFTEVSWV9XT1JLRVJfQ0xBU1M6LX0nCiAgICAgIEdVTklDT1JOX1RJTUVPVVQ6ICcke0dVTklDT1JOX1RJTUVPVVQ6LTM2MH0nCiAgICAgIENFTEVSWV9XT1JLRVJfQU1PVU5UOiAnJHtDRUxFUllfV09SS0VSX0FNT1VOVDotfScKICAgICAgQ0VMRVJZX0FVVE9fU0NBTEU6ICcke0NFTEVSWV9BVVRPX1NDQUxFOi1mYWxzZX0nCiAgICAgIENFTEVSWV9NQVhfV09SS0VSUzogJyR7Q0VMRVJZX01BWF9XT1JLRVJTOi19JwogICAgICBDRUxFUllfTUlOX1dPUktFUlM6ICcke0NFTEVSWV9NSU5fV09SS0VSUzotfScKICAgICAgQVBJX1RPT0xfREVGQVVMVF9DT05ORUNUX1RJTUVPVVQ6ICcke0FQSV9UT09MX0RFRkFVTFRfQ09OTkVDVF9USU1FT1VUOi0xMH0nCiAgICAgIEFQSV9UT09MX0RFRkFVTFRfUkVBRF9USU1FT1VUOiAnJHtBUElfVE9PTF9ERUZBVUxUX1JFQURfVElNRU9VVDotNjB9JwogICAgICBEQl9VU0VSTkFNRTogJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICBEQl9QQVNTV09SRDogJFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgREJfSE9TVDogJyR7REJfSE9TVDotZGJ9JwogICAgICBEQl9QT1JUOiAnJHtEQl9QT1JUOi01NDMyfScKICAgICAgREJfREFUQUJBU0U6IGRpZnkKICAgICAgU1FMQUxDSEVNWV9QT09MX1NJWkU6ICcke1NRTEFMQ0hFTVlfUE9PTF9TSVpFOi0zMH0nCiAgICAgIFNRTEFMQ0hFTVlfUE9PTF9SRUNZQ0xFOiAnJHtTUUxBTENIRU1ZX1BPT0xfUkVDWUNMRTotMzYwMH0nCiAgICAgIFNRTEFMQ0hFTVlfRUNITzogJyR7U1FMQUxDSEVNWV9FQ0hPOi1mYWxzZX0nCiAgICAgIFBPU1RHUkVTX01BWF9DT05ORUNUSU9OUzogJyR7UE9TVEdSRVNfTUFYX0NPTk5FQ1RJT05TOi0xMDB9JwogICAgICBQT1NUR1JFU19TSEFSRURfQlVGRkVSUzogJyR7UE9TVEdSRVNfU0hBUkVEX0JVRkZFUlM6LTEyOE1CfScKICAgICAgUE9TVEdSRVNfV09SS19NRU06ICcke1BPU1RHUkVTX1dPUktfTUVNOi00TUJ9JwogICAgICBQT1NUR1JFU19NQUlOVEVOQU5DRV9XT1JLX01FTTogJyR7UE9TVEdSRVNfTUFJTlRFTkFOQ0VfV09SS19NRU06LTY0TUJ9JwogICAgICBQT1NUR1JFU19FRkZFQ1RJVkVfQ0FDSEVfU0laRTogJyR7UE9TVEdSRVNfRUZGRUNUSVZFX0NBQ0hFX1NJWkU6LTQwOTZNQn0nCiAgICAgIFJFRElTX0hPU1Q6ICcke1JFRElTX0hPU1Q6LXJlZGlzfScKICAgICAgUkVESVNfUE9SVDogJyR7UkVESVNfUE9SVDotNjM3OX0nCiAgICAgIFJFRElTX1VTRVJOQU1FOiAnJHtSRURJU19VU0VSTkFNRTotfScKICAgICAgUkVESVNfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgICAgIFJFRElTX1VTRV9TU0w6ICcke1JFRElTX1VTRV9TU0w6LWZhbHNlfScKICAgICAgUkVESVNfREI6IDAKICAgICAgQ0VMRVJZX0JST0tFUl9VUkw6ICdyZWRpczovLzokU0VSVklDRV9QQVNTV09SRF9SRURJU0ByZWRpczo2Mzc5LzEnCiAgICAgIEJST0tFUl9VU0VfU1NMOiAnJHtCUk9LRVJfVVNFX1NTTDotZmFsc2V9JwogICAgICBXRUJfQVBJX0NPUlNfQUxMT1dfT1JJR0lOUzogJyR7V0VCX0FQSV9DT1JTX0FMTE9XX09SSUdJTlM6LSp9JwogICAgICBDT05TT0xFX0NPUlNfQUxMT1dfT1JJR0lOUzogJyR7Q09OU09MRV9DT1JTX0FMTE9XX09SSUdJTlM6LSp9JwogICAgICBTVE9SQUdFX1RZUEU6ICcke1NUT1JBR0VfVFlQRTotbG9jYWx9JwogICAgICBTVE9SQUdFX0xPQ0FMX1BBVEg6IHN0b3JhZ2UKICAgICAgUzNfVVNFX0FXU19NQU5BR0VEX0lBTTogJyR7UzNfVVNFX0FXU19NQU5BR0VEX0lBTTotZmFsc2V9JwogICAgICBTM19FTkRQT0lOVDogJyR7UzNfRU5EUE9JTlQ6LX0nCiAgICAgIFMzX0JVQ0tFVF9OQU1FOiAnJHtTM19CVUNLRVRfTkFNRTotfScKICAgICAgUzNfQUNDRVNTX0tFWTogJyR7UzNfQUNDRVNTX0tFWTotfScKICAgICAgUzNfU0VDUkVUX0tFWTogJyR7UzNfU0VDUkVUX0tFWTotfScKICAgICAgUzNfUkVHSU9OOiAnJHtTM19SRUdJT046LXVzLWVhc3QtMX0nCiAgICAgIEFaVVJFX0JMT0JfQUNDT1VOVF9OQU1FOiAnJHtBWlVSRV9CTE9CX0FDQ09VTlRfTkFNRTotfScKICAgICAgQVpVUkVfQkxPQl9BQ0NPVU5UX0tFWTogJyR7QVpVUkVfQkxPQl9BQ0NPVU5UX0tFWTotfScKICAgICAgQVpVUkVfQkxPQl9DT05UQUlORVJfTkFNRTogJyR7QVpVUkVfQkxPQl9DT05UQUlORVJfTkFNRTotfScKICAgICAgQVpVUkVfQkxPQl9BQ0NPVU5UX1VSTDogJyR7QVpVUkVfQkxPQl9BQ0NPVU5UX1VSTDotfScKICAgICAgR09PR0xFX1NUT1JBR0VfQlVDS0VUX05BTUU6ICcke0dPT0dMRV9TVE9SQUdFX0JVQ0tFVF9OQU1FOi19JwogICAgICBHT09HTEVfU1RPUkFHRV9TRVJWSUNFX0FDQ09VTlRfSlNPTl9CQVNFNjQ6ICcke0dPT0dMRV9TVE9SQUdFX1NFUlZJQ0VfQUNDT1VOVF9KU09OX0JBU0U2NDotfScKICAgICAgQUxJWVVOX09TU19CVUNLRVRfTkFNRTogJyR7QUxJWVVOX09TU19CVUNLRVRfTkFNRTotfScKICAgICAgQUxJWVVOX09TU19BQ0NFU1NfS0VZOiAnJHtBTElZVU5fT1NTX0FDQ0VTU19LRVk6LX0nCiAgICAgIEFMSVlVTl9PU1NfU0VDUkVUX0tFWTogJyR7QUxJWVVOX09TU19TRUNSRVRfS0VZOi19JwogICAgICBBTElZVU5fT1NTX0VORFBPSU5UOiAnJHtBTElZVU5fT1NTX0VORFBPSU5UOi19JwogICAgICBBTElZVU5fT1NTX1JFR0lPTjogJyR7QUxJWVVOX09TU19SRUdJT046LX0nCiAgICAgIEFMSVlVTl9PU1NfQVVUSF9WRVJTSU9OOiAnJHtBTElZVU5fT1NTX0FVVEhfVkVSU0lPTjotdjR9JwogICAgICBURU5DRU5UX0NPU19CVUNLRVRfTkFNRTogJyR7VEVOQ0VOVF9DT1NfQlVDS0VUX05BTUU6LX0nCiAgICAgIFRFTkNFTlRfQ09TX1NFQ1JFVF9LRVk6ICcke1RFTkNFTlRfQ09TX1NFQ1JFVF9LRVk6LX0nCiAgICAgIFRFTkNFTlRfQ09TX1NFQ1JFVF9JRDogJyR7VEVOQ0VOVF9DT1NfU0VDUkVUX0lEOi19JwogICAgICBURU5DRU5UX0NPU19SRUdJT046ICcke1RFTkNFTlRfQ09TX1JFR0lPTjotfScKICAgICAgVEVOQ0VOVF9DT1NfU0NIRU1FOiAnJHtURU5DRU5UX0NPU19TQ0hFTUU6LX0nCiAgICAgIE9DSV9FTkRQT0lOVDogJyR7T0NJX0VORFBPSU5UOi19JwogICAgICBPQ0lfQlVDS0VUX05BTUU6ICcke09DSV9CVUNLRVRfTkFNRTotfScKICAgICAgT0NJX0FDQ0VTU19LRVk6ICcke09DSV9BQ0NFU1NfS0VZOi19JwogICAgICBPQ0lfU0VDUkVUX0tFWTogJyR7T0NJX1NFQ1JFVF9LRVk6LX0nCiAgICAgIE9DSV9SRUdJT046ICcke09DSV9SRUdJT046LX0nCiAgICAgIFZFQ1RPUl9TVE9SRTogJyR7VkVDVE9SX1NUT1JFOi13ZWF2aWF0ZX0nCiAgICAgIFdFQVZJQVRFX0VORFBPSU5UOiAnJHtXRUFWSUFURV9FTkRQT0lOVDotaHR0cDovL3dlYXZpYXRlOjgwODB9JwogICAgICBXRUFWSUFURV9BUElfS0VZOiAkU0VSVklDRV9QQVNTV09SRF9XRUFWSUFURQogICAgICBSRUxZVF9IT1NUOiAnJHtSRUxZVF9IT1NUOi1kYn0nCiAgICAgIFJFTFlUX1BPUlQ6ICcke1JFTFlUX1BPUlQ6LTU0MzJ9JwogICAgICBSRUxZVF9VU0VSOiAkU0VSVklDRV9VU0VSX1JFTFlUCiAgICAgIFJFTFlUX1BBU1NXT1JEOiAkU0VSVklDRV9QQVNTV09SRF9SRUxZVAogICAgICBSRUxZVF9EQVRBQkFTRTogJyR7UkVMWVRfREFUQUJBU0U6LXBvc3RncmVzfScKICAgICAgVElEQl9WRUNUT1JfSE9TVDogJyR7VElEQl9WRUNUT1JfSE9TVDotdGlkYn0nCiAgICAgIFRJREJfVkVDVE9SX1BPUlQ6ICcke1RJREJfVkVDVE9SX1BPUlQ6LTQwMDB9JwogICAgICBUSURCX1ZFQ1RPUl9VU0VSOiAkU0VSVklDRV9VU0VSX1RJREIKICAgICAgVElEQl9WRUNUT1JfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1RJREIKICAgICAgVElEQl9WRUNUT1JfREFUQUJBU0U6ICcke1RJREJfVkVDVE9SX0RBVEFCQVNFOi1kaWZ5fScKICAgICAgQU5BTFlUSUNEQl9LRVlfSUQ6ICcke0FOQUxZVElDREJfS0VZX0lEOi19JwogICAgICBBTkFMWVRJQ0RCX0tFWV9TRUNSRVQ6ICcke0FOQUxZVElDREJfS0VZX1NFQ1JFVDotfScKICAgICAgQU5BTFlUSUNEQl9SRUdJT05fSUQ6ICcke0FOQUxZVElDREJfUkVHSU9OX0lEOi19JwogICAgICBBTkFMWVRJQ0RCX0lOU1RBTkNFX0lEOiAnJHtBTkFMWVRJQ0RCX0lOU1RBTkNFX0lEOi19JwogICAgICBBTkFMWVRJQ0RCX0FDQ09VTlQ6ICcke0FOQUxZVElDREJfQUNDT1VOVDotfScKICAgICAgQU5BTFlUSUNEQl9QQVNTV09SRDogJyR7QU5BTFlUSUNEQl9QQVNTV09SRDotfScKICAgICAgQU5BTFlUSUNEQl9OQU1FU1BBQ0U6ICcke0FOQUxZVElDREJfTkFNRVNQQUNFOi1kaWZ5fScKICAgICAgQU5BTFlUSUNEQl9OQU1FU1BBQ0VfUEFTU1dPUkQ6ICcke0FOQUxZVElDREJfTkFNRVNQQUNFX1BBU1NXT1JEOi19JwogICAgICBURU5DRU5UX1ZFQ1RPUl9EQl9VUkw6ICcke1RFTkNFTlRfVkVDVE9SX0RCX1VSTDotaHR0cDovLzEyNy4wLjAuMX0nCiAgICAgIFRFTkNFTlRfVkVDVE9SX0RCX0FQSV9LRVk6ICcke1RFTkNFTlRfVkVDVE9SX0RCX0FQSV9LRVk6LWRpZnl9JwogICAgICBURU5DRU5UX1ZFQ1RPUl9EQl9USU1FT1VUOiAnJHtURU5DRU5UX1ZFQ1RPUl9EQl9USU1FT1VUOi0zMH0nCiAgICAgIFRFTkNFTlRfVkVDVE9SX0RCX1VTRVJOQU1FOiAnJHtURU5DRU5UX1ZFQ1RPUl9EQl9VU0VSTkFNRTotZGlmeX0nCiAgICAgIFRFTkNFTlRfVkVDVE9SX0RCX0RBVEFCQVNFOiAnJHtURU5DRU5UX1ZFQ1RPUl9EQl9EQVRBQkFTRTotZGlmeX0nCiAgICAgIFRFTkNFTlRfVkVDVE9SX0RCX1NIQVJEOiAnJHtURU5DRU5UX1ZFQ1RPUl9EQl9TSEFSRDotMX0nCiAgICAgIFRFTkNFTlRfVkVDVE9SX0RCX1JFUExJQ0FTOiAnJHtURU5DRU5UX1ZFQ1RPUl9EQl9SRVBMSUNBUzotMn0nCiAgICAgIFVQTE9BRF9GSUxFX1NJWkVfTElNSVQ6ICcke1VQTE9BRF9GSUxFX1NJWkVfTElNSVQ6LTE1fScKICAgICAgVVBMT0FEX0ZJTEVfQkFUQ0hfTElNSVQ6ICcke1VQTE9BRF9GSUxFX0JBVENIX0xJTUlUOi01fScKICAgICAgRVRMX1RZUEU6ICcke0VUTF9UWVBFOi1kaWZ5fScKICAgICAgTVVMVElNT0RBTF9TRU5EX0lNQUdFX0ZPUk1BVDogJyR7TVVMVElNT0RBTF9TRU5EX0lNQUdFX0ZPUk1BVDotYmFzZTY0fScKICAgICAgVVBMT0FEX0lNQUdFX0ZJTEVfU0laRV9MSU1JVDogJyR7VVBMT0FEX0lNQUdFX0ZJTEVfU0laRV9MSU1JVDotMTB9JwogICAgICBTRU5UUllfRFNOOiAnJHtBUElfU0VOVFJZX0RTTjotfScKICAgICAgU0VOVFJZX1RSQUNFU19TQU1QTEVfUkFURTogJyR7QVBJX1NFTlRSWV9UUkFDRVNfU0FNUExFX1JBVEU6LTEuMH0nCiAgICAgIFNFTlRSWV9QUk9GSUxFU19TQU1QTEVfUkFURTogJyR7QVBJX1NFTlRSWV9QUk9GSUxFU19TQU1QTEVfUkFURTotMS4wfScKICAgICAgTk9USU9OX0lOVEVHUkFUSU9OX1RZUEU6ICcke05PVElPTl9JTlRFR1JBVElPTl9UWVBFOi1wdWJsaWN9JwogICAgICBOT1RJT05fQ0xJRU5UX1NFQ1JFVDogJyR7Tk9USU9OX0NMSUVOVF9TRUNSRVQ6LX0nCiAgICAgIE5PVElPTl9DTElFTlRfSUQ6ICcke05PVElPTl9DTElFTlRfSUQ6LX0nCiAgICAgIE5PVElPTl9JTlRFUk5BTF9TRUNSRVQ6ICcke05PVElPTl9JTlRFUk5BTF9TRUNSRVQ6LX0nCiAgICAgIE1BSUxfVFlQRTogJyR7TUFJTF9UWVBFOi1yZXNlbmR9JwogICAgICBNQUlMX0RFRkFVTFRfU0VORF9GUk9NOiAnJHtNQUlMX0RFRkFVTFRfU0VORF9GUk9NOi19JwogICAgICBTTVRQX1NFUlZFUjogJyR7U01UUF9TRVJWRVI6LX0nCiAgICAgIFNNVFBfUE9SVDogJyR7U01UUF9QT1JUOi00NjV9JwogICAgICBTTVRQX1VTRVJOQU1FOiAnJHtTTVRQX1VTRVJOQU1FOi19JwogICAgICBTTVRQX1BBU1NXT1JEOiAnJHtTTVRQX1BBU1NXT1JEOi19JwogICAgICBTTVRQX1VTRV9UTFM6ICcke1NNVFBfVVNFX1RMUzotdHJ1ZX0nCiAgICAgIFNNVFBfT1BQT1JUVU5JU1RJQ19UTFM6ICcke1NNVFBfT1BQT1JUVU5JU1RJQ19UTFM6LWZhbHNlfScKICAgICAgUkVTRU5EX0FQSV9LRVk6ICcke1JFU0VORF9BUElfS0VZOi15b3VyLXJlc2VuZC1hcGkta2V5fScKICAgICAgUkVTRU5EX0FQSV9VUkw6ICdodHRwczovL2FwaS5yZXNlbmQuY29tJwogICAgICBJTkRFWElOR19NQVhfU0VHTUVOVEFUSU9OX1RPS0VOU19MRU5HVEg6ICcke0lOREVYSU5HX01BWF9TRUdNRU5UQVRJT05fVE9LRU5TX0xFTkdUSDotMTAwMH0nCiAgICAgIElOVklURV9FWFBJUllfSE9VUlM6ICcke0lOVklURV9FWFBJUllfSE9VUlM6LTcyfScKICAgICAgUkVTRVRfUEFTU1dPUkRfVE9LRU5fRVhQSVJZX0hPVVJTOiAnJHtSRVNFVF9QQVNTV09SRF9UT0tFTl9FWFBJUllfSE9VUlM6LTI0fScKICAgICAgQ09ERV9FWEVDVVRJT05fRU5EUE9JTlQ6ICcke0NPREVfRVhFQ1VUSU9OX0VORFBPSU5UOi1odHRwOi8vc2FuZGJveDo4MTk0fScKICAgICAgQ09ERV9FWEVDVVRJT05fQVBJX0tFWTogJyR7U0FOREJPWF9BUElfS0VZOi1kaWZ5LXNhbmRib3h9JwogICAgICBDT0RFX01BWF9OVU1CRVI6ICcke0NPREVfTUFYX05VTUJFUjotOTIyMzM3MjAzNjg1NDc3NTgwN30nCiAgICAgIENPREVfTUlOX05VTUJFUjogJyR7Q09ERV9NSU5fTlVNQkVSOi0tOTIyMzM3MjAzNjg1NDc3NTgwOH0nCiAgICAgIENPREVfTUFYX1NUUklOR19MRU5HVEg6ICcke0NPREVfTUFYX1NUUklOR19MRU5HVEg6LTgwMDAwfScKICAgICAgVEVNUExBVEVfVFJBTlNGT1JNX01BWF9MRU5HVEg6ICcke1RFTVBMQVRFX1RSQU5TRk9STV9NQVhfTEVOR1RIOi04MDAwMH0nCiAgICAgIENPREVfTUFYX1NUUklOR19BUlJBWV9MRU5HVEg6ICcke0NPREVfTUFYX1NUUklOR19BUlJBWV9MRU5HVEg6LTMwfScKICAgICAgQ09ERV9NQVhfT0JKRUNUX0FSUkFZX0xFTkdUSDogJyR7Q09ERV9NQVhfT0JKRUNUX0FSUkFZX0xFTkdUSDotMzB9JwogICAgICBDT0RFX01BWF9OVU1CRVJfQVJSQVlfTEVOR1RIOiAnJHtDT0RFX01BWF9OVU1CRVJfQVJSQVlfTEVOR1RIOi0xMDAwfScKICAgICAgU1NSRl9QUk9YWV9IVFRQX1VSTDogJyR7U1NSRl9QUk9YWV9IVFRQX1VSTDotaHR0cDovL3NzcmZfcHJveHk6MzEyOH0nCiAgICAgIFNTUkZfUFJPWFlfSFRUUFNfVVJMOiAnJHtTU1JGX1BST1hZX0hUVFBTX1VSTDotaHR0cDovL3NzcmZfcHJveHk6MzEyOH0nCiAgICAgIE1PREU6IHdvcmtlcgogICAgZGVwZW5kc19vbjoKICAgICAgZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2RpZnktc3RvcmFnZTovYXBwL2FwaS9zdG9yYWdlJwogICAgbmV0d29ya3M6CiAgICAgIC0gc3NyZl9wcm94eV9uZXR3b3JrCiAgICAgIC0gZGVmYXVsdAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdjZWxlcnkgaW5zcGVjdCBwaW5nJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgICAgIHN0YXJ0X3BlcmlvZDogNDBzCiAgd2ViOgogICAgaW1hZ2U6ICdsYW5nZ2VuaXVzL2RpZnktd2ViOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9XRUJfMzAwMAogICAgICAtICdDT05TT0xFX0FQSV9VUkw9JHtTRVJWSUNFX0ZRRE5fV0VCfScKICAgICAgLSAnQVBQX0FQSV9VUkw9JHtTRVJWSUNFX0ZRRE5fQVBJfScKICAgICAgLSAnU0VOVFJZX0RTTj0ke1dFQl9TRU5UUllfRFNOOi19JwogICAgICAtICdORVhUX1RFTEVNRVRSWV9ESVNBQkxFRD0ke05FWFRfVEVMRU1FVFJZX0RJU0FCTEVEOi0wfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnLXEnCiAgICAgICAgLSAnaHR0cDovL3dlYjozMDAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgICAgIHN0YXJ0X3BlcmlvZDogNDBzCiAgZGI6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE1LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICBQT1NUR1JFU19VU0VSOiAkU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIFBPU1RHUkVTX1BBU1NXT1JEOiAkU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICBQT1NUR1JFU19EQjogZGlmeQogICAgICBQR0RBVEE6IC92YXIvbGliL3Bvc3RncmVzcWwvZGF0YS9wZ2RhdGEKICAgIGNvbW1hbmQ6ICJwb3N0Z3JlcyAtYyAnbWF4X2Nvbm5lY3Rpb25zPSR7UE9TVEdSRVNfTUFYX0NPTk5FQ1RJT05TOi0xMDB9J1xuICAgICAgICAgLWMgJ3NoYXJlZF9idWZmZXJzPSR7UE9TVEdSRVNfU0hBUkVEX0JVRkZFUlM6LTEyOE1CfSdcbiAgICAgICAgIC1jICd3b3JrX21lbT0ke1BPU1RHUkVTX1dPUktfTUVNOi00TUJ9J1xuICAgICAgICAgLWMgJ21haW50ZW5hbmNlX3dvcmtfbWVtPSR7UE9TVEdSRVNfTUFJTlRFTkFOQ0VfV09SS19NRU06LTY0TUJ9J1xuICAgICAgICAgLWMgJ2VmZmVjdGl2ZV9jYWNoZV9zaXplPSR7UE9TVEdSRVNfRUZGRUNUSVZFX0NBQ0hFX1NJWkU6LTQwOTZNQn0nXG4iCiAgICB2b2x1bWVzOgogICAgICAtICdkaWZ5LWRiLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHBnX2lzcmVhZHkKICAgICAgICAtICctVScKICAgICAgICAtICRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgICAtICctZCcKICAgICAgICAtIGRpZnkKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOjYtYWxwaW5lJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIFJFRElTX1BBU1NXT1JEOiAkU0VSVklDRV9QQVNTV09SRF9SRURJUwogICAgdm9sdW1lczoKICAgICAgLSAnZGlmeS1yZWRpcy1kYXRhOi9kYXRhJwogICAgY29tbWFuZDogJ3JlZGlzLXNlcnZlciAtLXJlcXVpcmVwYXNzICIkU0VSVklDRV9QQVNTV09SRF9SRURJUyInCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSAnLWEnCiAgICAgICAgLSAkU0VSVklDRV9QQVNTV09SRF9SRURJUwogICAgICAgIC0gcGluZwogIHNhbmRib3g6CiAgICBpbWFnZTogJ2xhbmdnZW5pdXMvZGlmeS1zYW5kYm94OmxhdGVzdCcKICAgIHJlc3RhcnQ6IGFsd2F5cwogICAgZW52aXJvbm1lbnQ6CiAgICAgIEFQSV9LRVk6ICcke1NBTkRCT1hfQVBJX0tFWTotZGlmeS1zYW5kYm94fScKICAgICAgR0lOX01PREU6ICcke1NBTkRCT1hfR0lOX01PREU6LXJlbGVhc2V9JwogICAgICBXT1JLRVJfVElNRU9VVDogJyR7U0FOREJPWF9XT1JLRVJfVElNRU9VVDotMTV9JwogICAgICBFTkFCTEVfTkVUV09SSzogJyR7U0FOREJPWF9FTkFCTEVfTkVUV09SSzotdHJ1ZX0nCiAgICAgIEhUVFBfUFJPWFk6ICcke1NBTkRCT1hfSFRUUF9QUk9YWTotaHR0cDovL3NzcmZfcHJveHk6MzEyOH0nCiAgICAgIEhUVFBTX1BST1hZOiAnJHtTQU5EQk9YX0hUVFBTX1BST1hZOi1odHRwOi8vc3NyZl9wcm94eTozMTI4fScKICAgICAgU0FOREJPWF9QT1JUOiAnJHtTQU5EQk9YX1BPUlQ6LTgxOTR9JwogICAgdm9sdW1lczoKICAgICAgLSAnLi92b2x1bWVzL3NhbmRib3gvZGVwZW5kZW5jaWVzOi9kZXBlbmRlbmNpZXMnCiAgICBuZXR3b3JrczoKICAgICAgLSBzc3JmX3Byb3h5X25ldHdvcmsKICAgICAgLSBkZWZhdWx0CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gImJhc2ggLWMgJzo+IC9kZXYvdGNwLzEyNy4wLjAuMS84MTk0JyB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMwogIHNzcmZfcHJveHk6CiAgICBpbWFnZTogJ3VidW50dS9zcXVpZDpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9zc3JmX3Byb3h5L3NxdWlkLmNvbmYudGVtcGxhdGUKICAgICAgICB0YXJnZXQ6IC9ldGMvc3F1aWQvc3F1aWQuY29uZi50ZW1wbGF0ZQogICAgICAgIHJlYWRfb25seTogdHJ1ZQogICAgICAgIGNvbnRlbnQ6ICJhY2wgbG9jYWxuZXQgc3JjIDAuMC4wLjEtMC4yNTUuMjU1LjI1NVx0IyBSRkMgMTEyMiBcInRoaXNcIiBuZXR3b3JrIChMQU4pXG5hY2wgbG9jYWxuZXQgc3JjIDEwLjAuMC4wLzhcdFx0IyBSRkMgMTkxOCBsb2NhbCBwcml2YXRlIG5ldHdvcmsgKExBTilcbmFjbCBsb2NhbG5ldCBzcmMgMTAwLjY0LjAuMC8xMFx0XHQjIFJGQyA2NTk4IHNoYXJlZCBhZGRyZXNzIHNwYWNlIChDR04pXG5hY2wgbG9jYWxuZXQgc3JjIDE2OS4yNTQuMC4wLzE2IFx0IyBSRkMgMzkyNyBsaW5rLWxvY2FsIChkaXJlY3RseSBwbHVnZ2VkKSBtYWNoaW5lc1xuYWNsIGxvY2FsbmV0IHNyYyAxNzIuMTYuMC4wLzEyXHRcdCMgUkZDIDE5MTggbG9jYWwgcHJpdmF0ZSBuZXR3b3JrIChMQU4pXG5hY2wgbG9jYWxuZXQgc3JjIDE5Mi4xNjguMC4wLzE2XHRcdCMgUkZDIDE5MTggbG9jYWwgcHJpdmF0ZSBuZXR3b3JrIChMQU4pXG5hY2wgbG9jYWxuZXQgc3JjIGZjMDA6Oi83ICAgICAgIFx0IyBSRkMgNDE5MyBsb2NhbCBwcml2YXRlIG5ldHdvcmsgcmFuZ2VcbmFjbCBsb2NhbG5ldCBzcmMgZmU4MDo6LzEwICAgICAgXHQjIFJGQyA0MjkxIGxpbmstbG9jYWwgKGRpcmVjdGx5IHBsdWdnZWQpIG1hY2hpbmVzXG5hY2wgU1NMX3BvcnRzIHBvcnQgNDQzXG5hY2wgU2FmZV9wb3J0cyBwb3J0IDgwXHRcdCMgaHR0cFxuYWNsIFNhZmVfcG9ydHMgcG9ydCAyMVx0XHQjIGZ0cFxuYWNsIFNhZmVfcG9ydHMgcG9ydCA0NDNcdFx0IyBodHRwc1xuYWNsIFNhZmVfcG9ydHMgcG9ydCA3MFx0XHQjIGdvcGhlclxuYWNsIFNhZmVfcG9ydHMgcG9ydCAyMTBcdFx0IyB3YWlzXG5hY2wgU2FmZV9wb3J0cyBwb3J0IDEwMjUtNjU1MzVcdCMgdW5yZWdpc3RlcmVkIHBvcnRzXG5hY2wgU2FmZV9wb3J0cyBwb3J0IDI4MFx0XHQjIGh0dHAtbWdtdFxuYWNsIFNhZmVfcG9ydHMgcG9ydCA0ODhcdFx0IyBnc3MtaHR0cFxuYWNsIFNhZmVfcG9ydHMgcG9ydCA1OTFcdFx0IyBmaWxlbWFrZXJcbmFjbCBTYWZlX3BvcnRzIHBvcnQgNzc3XHRcdCMgbXVsdGlsaW5nIGh0dHBcbmFjbCBDT05ORUNUIG1ldGhvZCBDT05ORUNUXG5odHRwX2FjY2VzcyBkZW55ICFTYWZlX3BvcnRzXG5odHRwX2FjY2VzcyBkZW55IENPTk5FQ1QgIVNTTF9wb3J0c1xuaHR0cF9hY2Nlc3MgYWxsb3cgbG9jYWxob3N0IG1hbmFnZXJcbmh0dHBfYWNjZXNzIGRlbnkgbWFuYWdlclxuaHR0cF9hY2Nlc3MgYWxsb3cgbG9jYWxob3N0XG5pbmNsdWRlIC9ldGMvc3F1aWQvY29uZi5kLyouY29uZlxuaHR0cF9hY2Nlc3MgZGVueSBhbGxcblxuIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBQcm94eSBTZXJ2ZXIgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcbmh0dHBfcG9ydCAzMTI4XG5jb3JlZHVtcF9kaXIgJHtDT1JFRFVNUF9ESVJ9XG5yZWZyZXNoX3BhdHRlcm4gXmZ0cDpcdFx0MTQ0MFx0MjAlXHQxMDA4MFxucmVmcmVzaF9wYXR0ZXJuIF5nb3BoZXI6XHQxNDQwXHQwJVx0MTQ0MFxucmVmcmVzaF9wYXR0ZXJuIC1pICgvY2dpLWJpbi98XFw/KSAwXHQwJVx0MFxucmVmcmVzaF9wYXR0ZXJuIFxcLyhQYWNrYWdlc3xTb3VyY2VzKSh8XFwuYnoyfFxcLmd6fFxcLnh6KSQgMCAwJSAwIHJlZnJlc2gtaW1zXG5yZWZyZXNoX3BhdHRlcm4gXFwvUmVsZWFzZSh8XFwuZ3BnKSQgMCAwJSAwIHJlZnJlc2gtaW1zXG5yZWZyZXNoX3BhdHRlcm4gXFwvSW5SZWxlYXNlJCAwIDAlIDAgcmVmcmVzaC1pbXNcbnJlZnJlc2hfcGF0dGVybiBcXC8oVHJhbnNsYXRpb24tLiopKHxcXC5iejJ8XFwuZ3p8XFwueHopJCAwIDAlIDAgcmVmcmVzaC1pbXNcbnJlZnJlc2hfcGF0dGVybiAuXHRcdDBcdDIwJVx0NDMyMFxuXG5cbiMgY2FjaGVfZGlyIHVmcyAvdmFyL3Nwb29sL3NxdWlkIDEwMCAxNiAyNTZcbiMgdXBzdHJlYW0gcHJveHksIHNldCB0byB5b3VyIG93biB1cHN0cmVhbSBwcm94eSBJUCB0byBhdm9pZCBTU1JGIGF0dGFja3NcbiMgY2FjaGVfcGVlciAxNzIuMS4xLjEgcGFyZW50IDMxMjggMCBuby1xdWVyeSBuby1kaWdlc3Qgbm8tbmV0ZGItZXhjaGFuZ2UgZGVmYXVsdCBcblxuIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBSZXZlcnNlIFByb3h5IFRvIFNhbmRib3ggIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcbmh0dHBfcG9ydCAzMTI5IGFjY2VsIHZob3N0XG5jYWNoZV9wZWVyICR7U0FOREJPWF9IT1NUfSBwYXJlbnQgJHtTQU5EQk9YX1BPUlR9IDAgbm8tcXVlcnkgb3JpZ2luc2VydmVyXG5hY2wgc3JjX2FsbCBzcmMgYWxsXG5odHRwX2FjY2VzcyBhbGxvdyBzcmNfYWxsXG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3NzcmZfcHJveHkvZG9ja2VyLWVudHJ5cG9pbnQuc2gKICAgICAgICB0YXJnZXQ6IC9kb2NrZXItZW50cnlwb2ludC5zaAogICAgICAgIHJlYWRfb25seTogdHJ1ZQogICAgICAgIGNvbnRlbnQ6ICIjIS9iaW4vYmFzaFxuXG4jIE1vZGlmaWVkIGJhc2VkIG9uIFNxdWlkIE9DSSBpbWFnZSBlbnRyeXBvaW50XG5cbiMgVGhpcyBlbnRyeXBvaW50IGFpbXMgdG8gZm9yd2FyZCB0aGUgc3F1aWQgbG9ncyB0byBzdGRvdXQgdG8gYXNzaXN0IHVzZXJzIG9mXG4jIGNvbW1vbiBjb250YWluZXIgcmVsYXRlZCB0b29saW5nIChlLmcuLCBrdWJlcm5ldGVzLCBkb2NrZXItY29tcG9zZSwgZXRjKSB0b1xuIyBhY2Nlc3MgdGhlIHNlcnZpY2UgbG9ncy5cblxuIyBNb3Jlb3ZlciwgaXQgaW52b2tlcyB0aGUgc3F1aWQgYmluYXJ5LCBsZWF2aW5nIGFsbCB0aGUgZGVzaXJlZCBwYXJhbWV0ZXJzIHRvXG4jIGJlIHByb3ZpZGVkIGJ5IHRoZSBcImNvbW1hbmRcIiBwYXNzZWQgdG8gdGhlIHNwYXduZWQgY29udGFpbmVyLiBJZiBubyBjb21tYW5kXG4jIGlzIHByb3ZpZGVkIGJ5IHRoZSB1c2VyLCB0aGUgZGVmYXVsdCBiZWhhdmlvciAoYXMgcGVyIHRoZSBDTUQgc3RhdGVtZW50IGluXG4jIHRoZSBEb2NrZXJmaWxlKSB3aWxsIGJlIHRvIHVzZSBVYnVudHUncyBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gWzFdIGFuZCBydW5cbiMgc3F1aWQgd2l0aCB0aGUgXCItTllDXCIgb3B0aW9ucyB0byBtaW1pYyB0aGUgYmVoYXZpb3Igb2YgdGhlIFVidW50dSBwcm92aWRlZFxuIyBzeXN0ZW1kIHVuaXQuXG5cbiMgWzFdIFRoZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gaXMgY2hhbmdlZCBpbiB0aGUgRG9ja2VyZmlsZSB0byBhbGxvdyBsb2NhbFxuIyBuZXR3b3JrIGNvbm5lY3Rpb25zLiBTZWUgdGhlIERvY2tlcmZpbGUgZm9yIGZ1cnRoZXIgaW5mb3JtYXRpb24uXG5cbmVjaG8gXCJbRU5UUllQT0lOVF0gcmUtY3JlYXRlIHNuYWtlb2lsIHNlbGYtc2lnbmVkIGNlcnRpZmljYXRlIHJlbW92ZWQgaW4gdGhlIGJ1aWxkIHByb2Nlc3NcIlxuaWYgWyAhIC1mIC9ldGMvc3NsL3ByaXZhdGUvc3NsLWNlcnQtc25ha2VvaWwua2V5IF07IHRoZW5cbiAgICAvdXNyL3NiaW4vbWFrZS1zc2wtY2VydCBnZW5lcmF0ZS1kZWZhdWx0LXNuYWtlb2lsIC0tZm9yY2Utb3ZlcndyaXRlID4gL2Rldi9udWxsIDI+JjFcbmZpXG5cbnRhaWwgLUYgL3Zhci9sb2cvc3F1aWQvYWNjZXNzLmxvZyAyPi9kZXYvbnVsbCAmXG50YWlsIC1GIC92YXIvbG9nL3NxdWlkL2Vycm9yLmxvZyAyPi9kZXYvbnVsbCAmXG50YWlsIC1GIC92YXIvbG9nL3NxdWlkL3N0b3JlLmxvZyAyPi9kZXYvbnVsbCAmXG50YWlsIC1GIC92YXIvbG9nL3NxdWlkL2NhY2hlLmxvZyAyPi9kZXYvbnVsbCAmXG5cbiMgUmVwbGFjZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgaW4gdGhlIHRlbXBsYXRlIGFuZCBvdXRwdXQgdG8gdGhlIHNxdWlkLmNvbmZcbmVjaG8gXCJbRU5UUllQT0lOVF0gcmVwbGFjaW5nIGVudmlyb25tZW50IHZhcmlhYmxlcyBpbiB0aGUgdGVtcGxhdGVcIlxuYXdrICd7XG4gICAgd2hpbGUobWF0Y2goJDAsIC9cXCR7W0EtWmEtel9dW0EtWmEtel8wLTldKn0vKSkge1xuICAgICAgICB2YXIgPSBzdWJzdHIoJDAsIFJTVEFSVCsyLCBSTEVOR1RILTMpXG4gICAgICAgIHZhbCA9IEVOVklST05bdmFyXVxuICAgICAgICAkMCA9IHN1YnN0cigkMCwgMSwgUlNUQVJULTEpIHZhbCBzdWJzdHIoJDAsIFJTVEFSVCtSTEVOR1RIKVxuICAgIH1cbiAgICBwcmludFxufScgL2V0Yy9zcXVpZC9zcXVpZC5jb25mLnRlbXBsYXRlID4gL2V0Yy9zcXVpZC9zcXVpZC5jb25mXG5cbi91c3Ivc2Jpbi9zcXVpZCAtTnpcbmVjaG8gXCJbRU5UUllQT0lOVF0gc3RhcnRpbmcgc3F1aWRcIlxuL3Vzci9zYmluL3NxdWlkIC1mIC9ldGMvc3F1aWQvc3F1aWQuY29uZiAtTllDIDFcbiIKICAgICAgLSAnc3NyZl9wcm94eV92YXJfbG9nX3NxdWlkOi92YXIvbG9nL3NxdWlkJwogICAgICAtICdzc3JmX3Byb3h5X3Zhcl9zcG9vbF9zcXVpZDovdmFyL3Nwb29sL3NxdWlkJwogICAgZW50cnlwb2ludDoKICAgICAgLSAvYmluL3NoCiAgICAgIC0gL2RvY2tlci1lbnRyeXBvaW50LnNoCiAgICBlbnZpcm9ubWVudDoKICAgICAgSFRUUF9QT1JUOiAnJHtTU1JGX0hUVFBfUE9SVDotMzEyOH0nCiAgICAgIENPUkVEVU1QX0RJUjogJyR7U1NSRl9DT1JFRFVNUF9ESVI6LS92YXIvc3Bvb2wvc3F1aWR9JwogICAgICBSRVZFUlNFX1BST1hZX1BPUlQ6ICcke1NTUkZfUkVWRVJTRV9QUk9YWV9QT1JUOi04MTk0fScKICAgICAgU0FOREJPWF9IT1NUOiAnJHtTU1JGX1NBTkRCT1hfSE9TVDotc2FuZGJveH0nCiAgICAgIFNBTkRCT1hfUE9SVDogJyR7U0FOREJPWF9QT1JUOi04MTk0fScKICAgIG5ldHdvcmtzOgogICAgICAtIHNzcmZfcHJveHlfbmV0d29yawogICAgICAtIGRlZmF1bHQKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBzcXVpZAogICAgICAgIC0gJy1rJwogICAgICAgIC0gY2hlY2sKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogICAgICBzdGFydF9wZXJpb2Q6IDQwcwogIG5naW54OgogICAgaW1hZ2U6ICduZ2lueDpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9uZ2lueC9uZ2lueC5jb25mLnRlbXBsYXRlCiAgICAgICAgdGFyZ2V0OiAvZXRjL25naW54L25naW54LmNvbmYudGVtcGxhdGUKICAgICAgICByZWFkX29ubHk6IHRydWUKICAgICAgICBjb250ZW50OiAiIyBQbGVhc2UgZG8gbm90IGRpcmVjdGx5IGVkaXQgdGhpcyBmaWxlLiBJbnN0ZWFkLCBtb2RpZnkgdGhlIC5lbnYgdmFyaWFibGVzIHJlbGF0ZWQgdG8gTkdJTlggY29uZmlndXJhdGlvbi5cblxudXNlciAgbmdpbng7XG4gICAgd29ya2VyX3Byb2Nlc3NlcyAgJHtOR0lOWF9XT1JLRVJfUFJPQ0VTU0VTfTtcblxuICAgIGVycm9yX2xvZyAgL3Zhci9sb2cvbmdpbngvZXJyb3IubG9nIG5vdGljZTtcbiAgICBwaWQgICAgICAgIC92YXIvcnVuL25naW54LnBpZDtcblxuXG4gICAgZXZlbnRzIHtcbiAgICAgICAgd29ya2VyX2Nvbm5lY3Rpb25zICAxMDI0O1xuICAgIH1cblxuXG4gICAgaHR0cCB7XG4gICAgICAgIGluY2x1ZGUgICAgICAgL2V0Yy9uZ2lueC9taW1lLnR5cGVzO1xuICAgICAgICBkZWZhdWx0X3R5cGUgIGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbTtcblxuICAgICAgICBsb2dfZm9ybWF0ICBtYWluICAnJHJlbW90ZV9hZGRyIC0gJHJlbW90ZV91c2VyIFskdGltZV9sb2NhbF0gXCIkcmVxdWVzdFwiICdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJyRzdGF0dXMgJGJvZHlfYnl0ZXNfc2VudCBcIiRodHRwX3JlZmVyZXJcIiAnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdcIiRodHRwX3VzZXJfYWdlbnRcIiBcIiRodHRwX3hfZm9yd2FyZGVkX2ZvclwiJztcblxuICAgICAgICBhY2Nlc3NfbG9nICAvdmFyL2xvZy9uZ2lueC9hY2Nlc3MubG9nICBtYWluO1xuXG4gICAgICAgIHNlbmRmaWxlICAgICAgICBvbjtcbiAgICAgICAgI3RjcF9ub3B1c2ggICAgIG9uO1xuXG4gICAgICAgIGtlZXBhbGl2ZV90aW1lb3V0ICAke05HSU5YX0tFRVBBTElWRV9USU1FT1VUfTtcblxuICAgICAgICAjZ3ppcCAgb247XG4gICAgICAgIGNsaWVudF9tYXhfYm9keV9zaXplICR7TkdJTlhfQ0xJRU5UX01BWF9CT0RZX1NJWkV9O1xuXG4gICAgICAgIGluY2x1ZGUgL2V0Yy9uZ2lueC9jb25mLmQvKi5jb25mO1xuICAgIH1cbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vbmdpbngvcHJveHkuY29uZi50ZW1wbGF0ZQogICAgICAgIHRhcmdldDogL2V0Yy9uZ2lueC9wcm94eS5jb25mLnRlbXBsYXRlCiAgICAgICAgcmVhZF9vbmx5OiB0cnVlCiAgICAgICAgY29udGVudDogIiMgUGxlYXNlIGRvIG5vdCBkaXJlY3RseSBlZGl0IHRoaXMgZmlsZS4gSW5zdGVhZCwgbW9kaWZ5IHRoZSAuZW52IHZhcmlhYmxlcyByZWxhdGVkIHRvIE5HSU5YIGNvbmZpZ3VyYXRpb24uXG4gIHByb3h5X3NldF9oZWFkZXIgSG9zdCAkaG9zdDtcbiAgcHJveHlfc2V0X2hlYWRlciBYLUZvcndhcmRlZC1Gb3IgJHByb3h5X2FkZF94X2ZvcndhcmRlZF9mb3I7XG4gIHByb3h5X3NldF9oZWFkZXIgWC1Gb3J3YXJkZWQtUHJvdG8gJHNjaGVtZTtcbiAgcHJveHlfaHR0cF92ZXJzaW9uIDEuMTtcbiAgcHJveHlfc2V0X2hlYWRlciBDb25uZWN0aW9uIFwiXCI7XG4gIHByb3h5X2J1ZmZlcmluZyBvZmY7XG4gIHByb3h5X3JlYWRfdGltZW91dCAke05HSU5YX1BST1hZX1JFQURfVElNRU9VVH07XG4gIHByb3h5X3NlbmRfdGltZW91dCAke05HSU5YX1BST1hZX1NFTkRfVElNRU9VVH07XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL25naW54L2h0dHBzLmNvbmYudGVtcGxhdGUKICAgICAgICB0YXJnZXQ6IC9ldGMvbmdpbngvaHR0cHMuY29uZi50ZW1wbGF0ZQogICAgICAgIHJlYWRfb25seTogdHJ1ZQogICAgICAgIGNvbnRlbnQ6ICIjIFBsZWFzZSBkbyBub3QgZGlyZWN0bHkgZWRpdCB0aGlzIGZpbGUuIEluc3RlYWQsIG1vZGlmeSB0aGUgLmVudiB2YXJpYWJsZXMgcmVsYXRlZCB0byBOR0lOWCBjb25maWd1cmF0aW9uLlxuXG5saXN0ZW4gJHtOR0lOWF9TU0xfUE9SVH0gc3NsO1xuc3NsX2NlcnRpZmljYXRlICR7U1NMX0NFUlRJRklDQVRFX1BBVEh9O1xuc3NsX2NlcnRpZmljYXRlX2tleSAke1NTTF9DRVJUSUZJQ0FURV9LRVlfUEFUSH07XG5zc2xfcHJvdG9jb2xzICR7TkdJTlhfU1NMX1BST1RPQ09MU307XG5zc2xfcHJlZmVyX3NlcnZlcl9jaXBoZXJzIG9uO1xuc3NsX3Nlc3Npb25fY2FjaGUgc2hhcmVkOlNTTDoxMG07XG5zc2xfc2Vzc2lvbl90aW1lb3V0IDEwbTtcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vbmdpbngvZG9ja2VyLWVudHJ5cG9pbnQuc2gKICAgICAgICB0YXJnZXQ6IC9kb2NrZXItZW50cnlwb2ludC1tb3VudC5zaAogICAgICAgIHJlYWRfb25seTogdHJ1ZQogICAgICAgIGNvbnRlbnQ6ICIjIS9iaW4vYmFzaFxuXG5pZiBbIFwiJHtOR0lOWF9IVFRQU19FTkFCTEVEfVwiID0gXCJ0cnVlXCIgXTsgdGhlblxuICAgICMgQ2hlY2sgaWYgdGhlIGNlcnRpZmljYXRlIGFuZCBrZXkgZmlsZXMgZm9yIHRoZSBzcGVjaWZpZWQgZG9tYWluIGV4aXN0XG4gICAgaWYgWyAtbiBcIiR7Q0VSVEJPVF9ET01BSU59XCIgXSAmJiBcXFxuICAgICAgWyAtZiBcIi9ldGMvbGV0c2VuY3J5cHQvbGl2ZS8ke0NFUlRCT1RfRE9NQUlOfS8ke05HSU5YX1NTTF9DRVJUX0ZJTEVOQU1FfVwiIF0gJiYgXFxcbiAgICAgIFsgLWYgXCIvZXRjL2xldHNlbmNyeXB0L2xpdmUvJHtDRVJUQk9UX0RPTUFJTn0vJHtOR0lOWF9TU0xfQ0VSVF9LRVlfRklMRU5BTUV9XCIgXTsgdGhlblxuICAgICAgICBTU0xfQ0VSVElGSUNBVEVfUEFUSD1cIi9ldGMvbGV0c2VuY3J5cHQvbGl2ZS8ke0NFUlRCT1RfRE9NQUlOfS8ke05HSU5YX1NTTF9DRVJUX0ZJTEVOQU1FfVwiXG4gICAgICAgIFNTTF9DRVJUSUZJQ0FURV9LRVlfUEFUSD1cIi9ldGMvbGV0c2VuY3J5cHQvbGl2ZS8ke0NFUlRCT1RfRE9NQUlOfS8ke05HSU5YX1NTTF9DRVJUX0tFWV9GSUxFTkFNRX1cIlxuICAgIGVsc2VcbiAgICAgICAgU1NMX0NFUlRJRklDQVRFX1BBVEg9XCIvZXRjL3NzbC8ke05HSU5YX1NTTF9DRVJUX0ZJTEVOQU1FfVwiXG4gICAgICAgIFNTTF9DRVJUSUZJQ0FURV9LRVlfUEFUSD1cIi9ldGMvc3NsLyR7TkdJTlhfU1NMX0NFUlRfS0VZX0ZJTEVOQU1FfVwiXG4gICAgZmlcbiAgICBleHBvcnQgU1NMX0NFUlRJRklDQVRFX1BBVEhcbiAgICBleHBvcnQgU1NMX0NFUlRJRklDQVRFX0tFWV9QQVRIXG5cbiAgICAjIHNldCB0aGUgSFRUUFNfQ09ORklHIGVudmlyb25tZW50IHZhcmlhYmxlIHRvIHRoZSBjb250ZW50IG9mIHRoZSBodHRwcy5jb25mLnRlbXBsYXRlXG4gICAgSFRUUFNfQ09ORklHPSQoZW52c3Vic3QgPCAvZXRjL25naW54L2h0dHBzLmNvbmYudGVtcGxhdGUpXG4gICAgZXhwb3J0IEhUVFBTX0NPTkZJR1xuICAgICMgU3Vic3RpdHV0ZSB0aGUgSFRUUFNfQ09ORklHIGluIHRoZSBkZWZhdWx0LmNvbmYudGVtcGxhdGUgd2l0aCBjb250ZW50IGZyb20gaHR0cHMuY29uZi50ZW1wbGF0ZVxuICAgIGVudnN1YnN0ICcke0hUVFBTX0NPTkZJR30nIDwgL2V0Yy9uZ2lueC9jb25mLmQvZGVmYXVsdC5jb25mLnRlbXBsYXRlID4gL2V0Yy9uZ2lueC9jb25mLmQvZGVmYXVsdC5jb25mXG5maVxuXG5pZiBbIFwiJHtOR0lOWF9FTkFCTEVfQ0VSVEJPVF9DSEFMTEVOR0V9XCIgPSBcInRydWVcIiBdOyB0aGVuXG4gICAgQUNNRV9DSEFMTEVOR0VfTE9DQVRJT049J2xvY2F0aW9uIC8ud2VsbC1rbm93bi9hY21lLWNoYWxsZW5nZS8geyByb290IC92YXIvd3d3L2h0bWw7IH0nXG5lbHNlXG4gICAgQUNNRV9DSEFMTEVOR0VfTE9DQVRJT049JydcbmZpXG5leHBvcnQgQUNNRV9DSEFMTEVOR0VfTE9DQVRJT05cblxuZW52X3ZhcnM9JChwcmludGVudiB8IGN1dCAtZD0gLWYxIHwgc2VkICdzL14vJC9nJyB8IHBhc3RlIC1zZCwgLSlcblxuZW52c3Vic3QgXCIkZW52X3ZhcnNcIiA8IC9ldGMvbmdpbngvbmdpbnguY29uZi50ZW1wbGF0ZSA+IC9ldGMvbmdpbngvbmdpbnguY29uZlxuZW52c3Vic3QgXCIkZW52X3ZhcnNcIiA8IC9ldGMvbmdpbngvcHJveHkuY29uZi50ZW1wbGF0ZSA+IC9ldGMvbmdpbngvcHJveHkuY29uZlxuXG5lbnZzdWJzdCA8IC9ldGMvbmdpbngvY29uZi5kL2RlZmF1bHQuY29uZi50ZW1wbGF0ZSA+IC9ldGMvbmdpbngvY29uZi5kL2RlZmF1bHQuY29uZlxuXG4jIFN0YXJ0IE5naW54IHVzaW5nIHRoZSBkZWZhdWx0IGVudHJ5cG9pbnRcbmV4ZWMgbmdpbnggLWcgJ2RhZW1vbiBvZmY7J1xuIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9uZ2lueC9kZWZhdWx0LmNvbmYudGVtcGxhdGUKICAgICAgICB0YXJnZXQ6IC9ldGMvbmdpbngvY29uZi5kL2RlZmF1bHQuY29uZi50ZW1wbGF0ZQogICAgICAgIHJlYWRfb25seTogdHJ1ZQogICAgICAgIGNvbnRlbnQ6ICIjIFBsZWFzZSBkbyBub3QgZGlyZWN0bHkgZWRpdCB0aGlzIGZpbGUuIEluc3RlYWQsIG1vZGlmeSB0aGUgLmVudiB2YXJpYWJsZXMgcmVsYXRlZCB0byBOR0lOWCBjb25maWd1cmF0aW9uLlxuXG5zZXJ2ZXIge1xuICAgIGxpc3RlbiAke05HSU5YX1BPUlR9O1xuICAgIHNlcnZlcl9uYW1lICR7TkdJTlhfU0VSVkVSX05BTUV9O1xuXG4gICAgbG9jYXRpb24gL2NvbnNvbGUvYXBpIHtcbiAgICAgIHByb3h5X3Bhc3MgaHR0cDovL2FwaTo1MDAxO1xuICAgICAgaW5jbHVkZSBwcm94eS5jb25mO1xuICAgIH1cblxuICAgIGxvY2F0aW9uIC9hcGkge1xuICAgICAgcHJveHlfcGFzcyBodHRwOi8vYXBpOjUwMDE7XG4gICAgICBpbmNsdWRlIHByb3h5LmNvbmY7XG4gICAgfVxuXG4gICAgbG9jYXRpb24gL3YxIHtcbiAgICAgIHByb3h5X3Bhc3MgaHR0cDovL2FwaTo1MDAxO1xuICAgICAgaW5jbHVkZSBwcm94eS5jb25mO1xuICAgIH1cblxuICAgIGxvY2F0aW9uIC9maWxlcyB7XG4gICAgICBwcm94eV9wYXNzIGh0dHA6Ly9hcGk6NTAwMTtcbiAgICAgIGluY2x1ZGUgcHJveHkuY29uZjtcbiAgICB9XG5cbiAgICBsb2NhdGlvbiAvIHtcbiAgICAgIHByb3h5X3Bhc3MgaHR0cDovL3dlYjozMDAwO1xuICAgICAgaW5jbHVkZSBwcm94eS5jb25mO1xuICAgIH1cblxuICAgICMgcGxhY2Vob2xkZXIgZm9yIGFjbWUgY2hhbGxlbmdlIGxvY2F0aW9uXG4gICAgJHtBQ01FX0NIQUxMRU5HRV9MT0NBVElPTn1cblxuICAgICMgcGxhY2Vob2xkZXIgZm9yIGh0dHBzIGNvbmZpZyBkZWZpbmVkIGluIGh0dHBzLmNvbmYudGVtcGxhdGVcbiAgICAke0hUVFBTX0NPTkZJR31cbn1cbiIKICAgICAgLSAnLi9uZ2lueC9zc2w6L2V0Yy9zc2wnCiAgICAgIC0gJy4vdm9sdW1lcy9jZXJ0Ym90L2NvbmYvbGl2ZTovZXRjL2xldHNlbmNyeXB0L2xpdmUnCiAgICAgIC0gJy4vdm9sdW1lcy9jZXJ0Ym90L2NvbmY6L2V0Yy9sZXRzZW5jcnlwdCcKICAgICAgLSAnLi92b2x1bWVzL2NlcnRib3Qvd3d3Oi92YXIvd3d3L2h0bWwnCiAgICBlbnRyeXBvaW50OgogICAgICAtIHNoCiAgICAgIC0gJy1jJwogICAgICAtICJjcCAvZG9ja2VyLWVudHJ5cG9pbnQtbW91bnQuc2ggL2RvY2tlci1lbnRyeXBvaW50LnNoICYmIHNlZCAtaSAncy9cciQkLy8nIC9kb2NrZXItZW50cnlwb2ludC5zaCAmJiBjaG1vZCAreCAvZG9ja2VyLWVudHJ5cG9pbnQuc2ggJiYgL2RvY2tlci1lbnRyeXBvaW50LnNoIgogICAgZW52aXJvbm1lbnQ6CiAgICAgIE5HSU5YX1NFUlZFUl9OQU1FOiAkU0VSVklDRV9GUUROX05HSU5YCiAgICAgIE5HSU5YX0hUVFBTX0VOQUJMRUQ6ICcke05HSU5YX0hUVFBTX0VOQUJMRUQ6LWZhbHNlfScKICAgICAgTkdJTlhfU1NMX1BPUlQ6ICcke05HSU5YX1NTTF9QT1JUOi00NDN9JwogICAgICBOR0lOWF9QT1JUOiAnJHtOR0lOWF9QT1JUOi04MH0nCiAgICAgIE5HSU5YX1NTTF9DRVJUX0ZJTEVOQU1FOiAnJHtOR0lOWF9TU0xfQ0VSVF9GSUxFTkFNRTotZGlmeS5jcnR9JwogICAgICBOR0lOWF9TU0xfQ0VSVF9LRVlfRklMRU5BTUU6ICcke05HSU5YX1NTTF9DRVJUX0tFWV9GSUxFTkFNRTotZGlmeS5rZXl9JwogICAgICBOR0lOWF9TU0xfUFJPVE9DT0xTOiAnJHtOR0lOWF9TU0xfUFJPVE9DT0xTOi1UTFN2MS4xIFRMU3YxLjIgVExTdjEuM30nCiAgICAgIE5HSU5YX1dPUktFUl9QUk9DRVNTRVM6ICcke05HSU5YX1dPUktFUl9QUk9DRVNTRVM6LWF1dG99JwogICAgICBOR0lOWF9DTElFTlRfTUFYX0JPRFlfU0laRTogJyR7TkdJTlhfQ0xJRU5UX01BWF9CT0RZX1NJWkU6LTE1TX0nCiAgICAgIE5HSU5YX0tFRVBBTElWRV9USU1FT1VUOiAnJHtOR0lOWF9LRUVQQUxJVkVfVElNRU9VVDotNjV9JwogICAgICBOR0lOWF9QUk9YWV9SRUFEX1RJTUVPVVQ6ICcke05HSU5YX1BST1hZX1JFQURfVElNRU9VVDotMzYwMHN9JwogICAgICBOR0lOWF9QUk9YWV9TRU5EX1RJTUVPVVQ6ICcke05HSU5YX1BST1hZX1NFTkRfVElNRU9VVDotMzYwMHN9JwogICAgICBOR0lOWF9FTkFCTEVfQ0VSVEJPVF9DSEFMTEVOR0U6ICcke05HSU5YX0VOQUJMRV9DRVJUQk9UX0NIQUxMRU5HRTotZmFsc2V9JwogICAgICBDRVJUQk9UX0RPTUFJTjogJyR7Q0VSVEJPVF9ET01BSU46LX0nCiAgICBkZXBlbmRzX29uOgogICAgICAtIGFwaQogICAgICAtIHdlYgogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIG5naW54CiAgICAgICAgLSAnLXQnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMKICAgICAgc3RhcnRfcGVyaW9kOiA0MHMKICB3ZWF2aWF0ZToKICAgIGltYWdlOiAnc2VtaXRlY2hub2xvZ2llcy93ZWF2aWF0ZToxLjE5LjAnCiAgICBwcm9maWxlczoKICAgICAgLSAnJwogICAgICAtIHdlYXZpYXRlCiAgICB2b2x1bWVzOgogICAgICAtICdkaWZ5LXdlYXZpYXRlLWRhdGE6L3Zhci9saWIvd2VhdmlhdGUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgUEVSU0lTVEVOQ0VfREFUQV9QQVRIOiAnJHtXRUFWSUFURV9QRVJTSVNURU5DRV9EQVRBX1BBVEg6LS92YXIvbGliL3dlYXZpYXRlfScKICAgICAgUVVFUllfREVGQVVMVFNfTElNSVQ6ICcke1dFQVZJQVRFX1FVRVJZX0RFRkFVTFRTX0xJTUlUOi0yNX0nCiAgICAgIEFVVEhFTlRJQ0FUSU9OX0FOT05ZTU9VU19BQ0NFU1NfRU5BQkxFRDogJyR7V0VBVklBVEVfQVVUSEVOVElDQVRJT05fQU5PTllNT1VTX0FDQ0VTU19FTkFCTEVEOi1mYWxzZX0nCiAgICAgIERFRkFVTFRfVkVDVE9SSVpFUl9NT0RVTEU6ICcke1dFQVZJQVRFX0RFRkFVTFRfVkVDVE9SSVpFUl9NT0RVTEU6LW5vbmV9JwogICAgICBDTFVTVEVSX0hPU1ROQU1FOiAnJHtXRUFWSUFURV9DTFVTVEVSX0hPU1ROQU1FOi1ub2RlMX0nCiAgICAgIEFVVEhFTlRJQ0FUSU9OX0FQSUtFWV9FTkFCTEVEOiAnJHtXRUFWSUFURV9BVVRIRU5USUNBVElPTl9BUElLRVlfRU5BQkxFRDotdHJ1ZX0nCiAgICAgIEFVVEhFTlRJQ0FUSU9OX0FQSUtFWV9BTExPV0VEX0tFWVM6ICRTRVJWSUNFX1BBU1NXT1JEX1dFQVZJQVRFCiAgICAgIEFVVEhFTlRJQ0FUSU9OX0FQSUtFWV9VU0VSUzogJFNFUlZJQ0VfVVNFUl9XRUFWSUFURQogICAgICBBVVRIT1JJWkFUSU9OX0FETUlOTElTVF9FTkFCTEVEOiAnJHtXRUFWSUFURV9BVVRIT1JJWkFUSU9OX0FETUlOTElTVF9FTkFCTEVEOi10cnVlfScKICAgICAgQVVUSE9SSVpBVElPTl9BRE1JTkxJU1RfVVNFUlM6ICRTRVJWSUNFX1VTRVJfV0VBVklBVEUKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnLXEnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo4MDgwL3YxLy53ZWxsLWtub3duL2xpdmUnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMKICAgICAgc3RhcnRfcGVyaW9kOiA0MHMKbmV0d29ya3M6CiAgc3NyZl9wcm94eV9uZXR3b3JrOgogICAgZHJpdmVyOiBicmlkZ2UKICAgIGludGVybmFsOiB0cnVlCnZvbHVtZXM6CiAgc3NyZl9wcm94eV92YXJfbG9nX3NxdWlkOiBudWxsCiAgc3NyZl9wcm94eV92YXJfc3Bvb2xfc3F1aWQ6IG51bGwK", + "tags": [ + "ai", + "weaviate", + "openai", + "gpt", + "llm", + "lmops", + "dify", + "redis", + "postgres", + "qdrant", + "rag", + "agent" + ], + "logo": "svgs/dify.png", + "minversion": "0.0.0", + "port": "3000" + }, "directus-with-postgresql": { "documentation": "https://directus.io?utm_source=coolify.io", "slogan": "Directus wraps databases with a dynamic API, and provides an intuitive app for managing its content.", @@ -575,6 +647,54 @@ "minversion": "0.0.0", "port": "8080" }, + "flowise-with-databases": { + "documentation": "https://docs.flowiseai.com/?utm_source=coolify.io", + "slogan": "Flowise is an open source low-code tool for developers to build customized LLM orchestration flows & AI agents. Also deploys Redis, Postgres and other services.", + "compose": "c2VydmljZXM6CiAgZmxvd2lzZToKICAgIGltYWdlOiAnZmxvd2lzZWFpL2Zsb3dpc2U6bGF0ZXN0JwogICAgZGVwZW5kc19vbjoKICAgICAgcGctcmVjb3JkLW1hbmFnZXI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXMtY2FjaGU6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcWRyYW50OgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fRkxPV0lTRV8zMDAxCiAgICAgIC0gJ0RFQlVHPSR7REVCVUc6LWZhbHNlfScKICAgICAgLSAnRElTQUJMRV9GTE9XSVNFX1RFTEVNRVRSWT0ke0RJU0FCTEVfRkxPV0lTRV9URUxFTUVUUlk6LXRydWV9JwogICAgICAtICdQT1JUPSR7UE9SVDotMzAwMX0nCiAgICAgIC0gREFUQUJBU0VfUEFUSD0vcm9vdC8uZmxvd2lzZQogICAgICAtIEFQSUtFWV9QQVRIPS9yb290Ly5mbG93aXNlCiAgICAgIC0gU0VDUkVUS0VZX1BBVEg9L3Jvb3QvLmZsb3dpc2UKICAgICAgLSBMT0dfUEFUSD0vcm9vdC8uZmxvd2lzZS9sb2dzCiAgICAgIC0gQkxPQl9TVE9SQUdFX1BBVEg9L3Jvb3QvLmZsb3dpc2Uvc3RvcmFnZQogICAgICAtICdGTE9XSVNFX1VTRVJOQU1FPSR7U0VSVklDRV9VU0VSX0ZMT1dJU0V9JwogICAgICAtICdGTE9XSVNFX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9GTE9XSVNFfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2Zsb3dpc2UtZGF0YTovcm9vdC8uZmxvd2lzZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnd2dldCAtcU8tIGh0dHA6Ly8xMjcuMC4wLjE6MzAwMSB8fCBleGl0IDEnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAzCiAgcGctcmVjb3JkLW1hbmFnZXI6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wZy1yZWNvcmQtbWFuYWdlcn0nCiAgICB2b2x1bWVzOgogICAgICAtICdwZy1yZWNvcmQtbWFuYWdlci1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtaCBsb2NhbGhvc3QgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAKICAgICAgc3RhcnRfcGVyaW9kOiAyMHMKICByZWRpcy1jYWNoZToKICAgIGltYWdlOiAncmVkaXM6NycKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2Zsb3dpc2UtcmVkaXMtY2FjaGUtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncmVkaXMtY2xpIC1oIGxvY2FsaG9zdCAtcCA2Mzc5IHBpbmcnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAzCiAgcWRyYW50OgogICAgaW1hZ2U6ICdxZHJhbnQvcWRyYW50OmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9RRFJBTlRfNjMzMwogICAgICAtICdRRFJBTlRfX1NFUlZJQ0VfX0FQSV9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX1FEUkFOVEFQSUtFWX0nCiAgICB2b2x1bWVzOgogICAgICAtICdmbG93aXNlLXFkcmFudC1kYXRhOi9xZHJhbnQvc3RvcmFnZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAiYmFzaCAtYyAnOj4gL2Rldi90Y3AvMTI3LjAuMC4xLzYzMzMnIHx8IGV4aXQgMSIKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDMK", + "tags": [ + "lowcode", + "nocode", + "ai", + "llm", + "openai", + "anthropic", + "machine-learning", + "rag", + "agents", + "chatbot", + "api", + "team", + "bot", + "flows" + ], + "logo": "svgs/flowise.png", + "minversion": "0.0.0", + "port": "3001" + }, + "flowise": { + "documentation": "https://docs.flowiseai.com/?utm_source=coolify.io", + "slogan": "Flowise is an open source low-code tool for developers to build customized LLM orchestration flows & AI agents.", + "compose": "c2VydmljZXM6CiAgZmxvd2lzZToKICAgIGltYWdlOiAnZmxvd2lzZWFpL2Zsb3dpc2U6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0ZMT1dJU0VfMzAwMQogICAgICAtICdERUJVRz0ke0RFQlVHOi1mYWxzZX0nCiAgICAgIC0gJ0RJU0FCTEVfRkxPV0lTRV9URUxFTUVUUlk9JHtESVNBQkxFX0ZMT1dJU0VfVEVMRU1FVFJZOi10cnVlfScKICAgICAgLSAnUE9SVD0ke1BPUlQ6LTMwMDF9JwogICAgICAtIERBVEFCQVNFX1BBVEg9L3Jvb3QvLmZsb3dpc2UKICAgICAgLSBBUElLRVlfUEFUSD0vcm9vdC8uZmxvd2lzZQogICAgICAtIFNFQ1JFVEtFWV9QQVRIPS9yb290Ly5mbG93aXNlCiAgICAgIC0gTE9HX1BBVEg9L3Jvb3QvLmZsb3dpc2UvbG9ncwogICAgICAtIEJMT0JfU1RPUkFHRV9QQVRIPS9yb290Ly5mbG93aXNlL3N0b3JhZ2UKICAgICAgLSAnRkxPV0lTRV9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9GTE9XSVNFfScKICAgICAgLSAnRkxPV0lTRV9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfRkxPV0lTRX0nCiAgICB2b2x1bWVzOgogICAgICAtICdmbG93aXNlLWRhdGE6L3Jvb3QvLmZsb3dpc2UnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3dnZXQgLXFPLSBodHRwOi8vMTI3LjAuMC4xOjMwMDEgfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMwo=", + "tags": [ + "lowcode", + "nocode", + "ai", + "llm", + "openai", + "anthropic", + "machine-learning", + "rag", + "agents", + "chatbot", + "api", + "team", + "bot", + "flows" + ], + "logo": "svgs/flowise.png", + "minversion": "0.0.0", + "port": "3001" + }, "forgejo-with-mariadb": { "documentation": "https://forgejo.org/docs?utm_source=coolify.io", "slogan": "Forgejo is a self-hosted lightweight software forge. Easy to install and low maintenance, it just does the job.", @@ -736,6 +856,54 @@ "minversion": "0.0.0", "port": "3000" }, + "freshrss-with-mariadb": { + "documentation": "https://freshrss.org/index.html?utm_source=coolify.io", + "slogan": "A free, self-hostable feed aggregator.", + "compose": "c2VydmljZXM6CiAgZnJlc2hyc3M6CiAgICBpbWFnZTogJ2ZyZXNocnNzL2ZyZXNocnNzOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9GUkVTSFJTU184MAogICAgICAtICdDUk9OX01JTj0ke0NST05fTUlOOi0xLDMxfScKICAgICAgLSAnTUFSSUFEQl9EQj0ke01BUklBREJfREFUQUJBU0U6LWZyZXNocnNzfScKICAgICAgLSAnTUFSSUFEQl9VU0VSPSR7U0VSVklDRV9VU0VSX01BUklBREJ9JwogICAgICAtICdNQVJJQURCX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ZyZXNocnNzLWRhdGE6L3Zhci93d3cvRnJlc2hSU1MvZGF0YScKICAgICAgLSAnZnJlc2hyc3MtZXh0ZW5zaW9uczovdmFyL3d3dy9GcmVzaFJTUy9leHRlbnNpb25zJwogICAgZGVwZW5kc19vbjoKICAgICAgZnJlc2hyc3MtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAiYmFzaCAtYyAnOj4gL2Rldi90Y3AvMTI3LjAuMC4xLzgwJyB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMwogIGZyZXNocnNzLWRiOgogICAgaW1hZ2U6ICdtYXJpYWRiOjExJwogICAgdm9sdW1lczoKICAgICAgLSAnbWFyaWFkYi1kYXRhOi92YXIvbGliL215c3FsJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gTVlTUUxfUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9ST09UCiAgICAgIC0gJ01ZU1FMX0RBVEFCQVNFPSR7TUFSSUFEQl9EQVRBQkFTRTotZnJlc2hyc3N9JwogICAgICAtICdNWVNRTF9VU0VSPSR7U0VSVklDRV9VU0VSX01BUklBREJ9JwogICAgICAtICdNWVNRTF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTUFSSUFEQn0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gaGVhbHRoY2hlY2suc2gKICAgICAgICAtICctLWNvbm5lY3QnCiAgICAgICAgLSAnLS1pbm5vZGJfaW5pdGlhbGl6ZWQnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "tags": [ + "rss", + "feed" + ], + "logo": "svgs/freshrss.png", + "minversion": "0.0.0", + "port": "80" + }, + "freshrss-with-mysql": { + "documentation": "https://freshrss.org/index.html?utm_source=coolify.io", + "slogan": "A free, self-hostable feed aggregator.", + "compose": "c2VydmljZXM6CiAgZnJlc2hyc3M6CiAgICBpbWFnZTogJ2ZyZXNocnNzL2ZyZXNocnNzOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9GUkVTSFJTU184MAogICAgICAtICdDUk9OX01JTj0ke0NST05fTUlOOi0xLDMxfScKICAgICAgLSAnTVlTUUxfREI9JHtNWVNRTF9EQVRBQkFTRTotZnJlc2hyc3N9JwogICAgICAtICdNWVNRTF9VU0VSPSR7U0VSVklDRV9VU0VSX01ZU1FMfScKICAgICAgLSAnTVlTUUxfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01ZU1FMfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ZyZXNocnNzLWRhdGE6L3Zhci93d3cvRnJlc2hSU1MvZGF0YScKICAgICAgLSAnZnJlc2hyc3MtZXh0ZW5zaW9uczovdmFyL3d3dy9GcmVzaFJTUy9leHRlbnNpb25zJwogICAgZGVwZW5kc19vbjoKICAgICAgZnJlc2hyc3MtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAiYmFzaCAtYyAnOj4gL2Rldi90Y3AvMTI3LjAuMC4xLzgwJyB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMwogIGZyZXNocnNzLWRiOgogICAgaW1hZ2U6ICdteXNxbDo4JwogICAgdm9sdW1lczoKICAgICAgLSAnbXlzcWwtZGF0YTovdmFyL2xpYi9teXNxbCcKICAgIGVudmlyb25tZW50OgogICAgICAtIE1ZU1FMX1JPT1RfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUk9PVAogICAgICAtICdNWVNRTF9EQVRBQkFTRT0ke01ZU1FMX0RBVEFCQVNFOi1mcmVzaHJzc30nCiAgICAgIC0gTVlTUUxfVVNFUj0kU0VSVklDRV9VU0VSX01ZU1FMCiAgICAgIC0gTVlTUUxfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfTVlTUUwKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBteXNxbGFkbWluCiAgICAgICAgLSBwaW5nCiAgICAgICAgLSAnLWgnCiAgICAgICAgLSAxMjcuMC4wLjEKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=", + "tags": [ + "rss", + "feed" + ], + "logo": "svgs/freshrss.png", + "minversion": "0.0.0", + "port": "80" + }, + "freshrss-with-postgresql": { + "documentation": "https://freshrss.org/index.html?utm_source=coolify.io", + "slogan": "A free, self-hostable feed aggregator.", + "compose": "c2VydmljZXM6CiAgZnJlc2hyc3M6CiAgICBpbWFnZTogJ2ZyZXNocnNzL2ZyZXNocnNzOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9GUkVTSFJTU184MAogICAgICAtICdDUk9OX01JTj0ke0NST05fTUlOOi0xLDMxfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU1FMX0RBVEFCQVNFOi1mcmVzaHJzc30nCiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSBQT1NUR1JFU19IT1NUPXBvc3RncmVzcWwKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ZyZXNocnNzLWRhdGE6L3Zhci93d3cvRnJlc2hSU1MvZGF0YScKICAgICAgLSAnZnJlc2hyc3MtZXh0ZW5zaW9uczovdmFyL3d3dy9GcmVzaFJTUy9leHRlbnNpb25zJwogICAgZGVwZW5kc19vbjoKICAgICAgZnJlc2hyc3MtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAiYmFzaCAtYyAnOj4gL2Rldi90Y3AvMTI3LjAuMC4xLzgwJyB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMwogIGZyZXNocnNzLWRiOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNicKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ZyZXNocnNzLXBvc3RncmVzcWwtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTUUx9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTUUxfREFUQUJBU0U6LWZyZXNocnNzfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "tags": [ + "rss", + "feed" + ], + "logo": "svgs/freshrss.png", + "minversion": "0.0.0", + "port": "80" + }, + "freshrss": { + "documentation": "https://freshrss.org/index.html?utm_source=coolify.io", + "slogan": "A free, self-hostable feed aggregator.", + "compose": "c2VydmljZXM6CiAgZnJlc2hyc3M6CiAgICBpbWFnZTogJ2ZyZXNocnNzL2ZyZXNocnNzOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9GUkVTSFJTU184MAogICAgICAtICdDUk9OX01JTj0ke0NST05fTUlOOi0xLDMxfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ZyZXNocnNzLWRhdGE6L3Zhci93d3cvRnJlc2hSU1MvZGF0YScKICAgICAgLSAnZnJlc2hyc3MtZXh0ZW5zaW9uczovdmFyL3d3dy9GcmVzaFJTUy9leHRlbnNpb25zJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICJiYXNoIC1jICc6PiAvZGV2L3RjcC8xMjcuMC4wLjEvODAnIHx8IGV4aXQgMSIKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAzCg==", + "tags": [ + "rss", + "feed" + ], + "logo": "svgs/freshrss.png", + "minversion": "0.0.0", + "port": "80" + }, "getoutline": { "documentation": "https://docs.getoutline.com/s/hosting/doc/hosting-outline-nipGaCRBDu?utm_source=coolify.io", "slogan": "Your team\u2019s knowledge base", @@ -882,7 +1050,7 @@ "glitchtip": { "documentation": "https://glitchtip.com?utm_source=coolify.io", "slogan": "GlitchTip is a self-hosted, open-source error tracking system.", - "compose": "c2VydmljZXM6CiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTUUx9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNRTF9EQVRBQkFTRTotZ2xpdGNodGlwfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3BnLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHJlZGlzOgogICAgaW1hZ2U6IHJlZGlzCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSBwaW5nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICB3ZWI6CiAgICBpbWFnZTogZ2xpdGNodGlwL2dsaXRjaHRpcAogICAgZGVwZW5kc19vbjoKICAgICAgLSBwb3N0Z3JlcwogICAgICAtIHJlZGlzCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fR0xJVENIVElQXzgwODAKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTUUxAcG9zdGdyZXM6NTQzMi8ke1BPU1RHUkVTUUxfREFUQUJBU0U6LWdsaXRjaHRpcH0nCiAgICAgIC0gU0VDUkVUX0tFWT0kU0VSVklDRV9CQVNFNjRfNjRfRU5DUllQVElPTgogICAgICAtICdFTUFJTF9VUkw9JHtFTUFJTF9VUkw6LWNvbnNvbGVtYWlsOi8vfScKICAgICAgLSAnR0xJVENIVElQX0RPTUFJTj0ke1NFUlZJQ0VfRlFETl9HTElUQ0hUSVB9JwogICAgICAtICdERUZBVUxUX0ZST01fRU1BSUw9JHtERUZBVUxUX0ZST01fRU1BSUw6LXRlc3RAZXhhbXBsZS5jb219JwogICAgICAtICdDRUxFUllfV09SS0VSX0FVVE9TQ0FMRT0ke0NFTEVSWV9XT1JLRVJfQVVUT1NDQUxFOi0xLDN9JwogICAgICAtICdDRUxFUllfV09SS0VSX01BWF9UQVNLU19QRVJfQ0hJTEQ9JHtDRUxFUllfV09SS0VSX01BWF9UQVNLU19QRVJfQ0hJTEQ6LTEwMDAwfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3VwbG9hZHM6L2NvZGUvdXBsb2FkcycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBlY2hvCiAgICAgICAgLSBvawogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgd29ya2VyOgogICAgaW1hZ2U6IGdsaXRjaHRpcC9nbGl0Y2h0aXAKICAgIGNvbW1hbmQ6IC4vYmluL3J1bi1jZWxlcnktd2l0aC1iZWF0LnNoCiAgICBkZXBlbmRzX29uOgogICAgICAtIHBvc3RncmVzCiAgICAgIC0gcmVkaXMKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9HTElUQ0hUSVAKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTUUxAcG9zdGdyZXM6NTQzMi8ke1BPU1RHUkVTUUxfREFUQUJBU0U6LWdsaXRjaHRpcH0nCiAgICAgIC0gU0VDUkVUX0tFWT0kU0VSVklDRV9CQVNFNjRfNjRfRU5DUllQVElPTgogICAgICAtICdFTUFJTF9VUkw9JHtFTUFJTF9VUkw6LWNvbnNvbGVtYWlsOi8vfScKICAgICAgLSAnR0xJVENIVElQX0RPTUFJTj0ke1NFUlZJQ0VfRlFETl9HTElUQ0hUSVB9JwogICAgICAtICdERUZBVUxUX0ZST01fRU1BSUw9JHtERUZBVUxUX0ZST01fRU1BSUw6LXRlc3RAZXhhbXBsZS5jb219JwogICAgICAtICdDRUxFUllfV09SS0VSX0FVVE9TQ0FMRT0ke0NFTEVSWV9XT1JLRVJfQVVUT1NDQUxFOi0xLDN9JwogICAgICAtICdDRUxFUllfV09SS0VSX01BWF9UQVNLU19QRVJfQ0hJTEQ9JHtDRUxFUllfV09SS0VSX01BWF9UQVNLU19QRVJfQ0hJTEQ6LTEwMDAwfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3VwbG9hZHM6L2NvZGUvdXBsb2FkcycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBlY2hvCiAgICAgICAgLSBvawogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgbWlncmF0ZToKICAgIGltYWdlOiBnbGl0Y2h0aXAvZ2xpdGNodGlwCiAgICByZXN0YXJ0OiAnbm8nCiAgICBkZXBlbmRzX29uOgogICAgICAtIHBvc3RncmVzCiAgICAgIC0gcmVkaXMKICAgIGNvbW1hbmQ6ICcuL21hbmFnZS5weSBtaWdyYXRlJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVNRTDokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMQHBvc3RncmVzOjU0MzIvJHtQT1NUR1JFU1FMX0RBVEFCQVNFOi1nbGl0Y2h0aXB9JwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0VOQ1JZUFRJT04KICAgICAgLSAnRU1BSUxfVVJMPSR7RU1BSUxfVVJMOi1jb25zb2xlbWFpbDovL30nCiAgICAgIC0gJ0RFRkFVTFRfRlJPTV9FTUFJTD0ke0RFRkFVTFRfRlJPTV9FTUFJTDotdGVzdEBleGFtcGxlLmNvbX0nCiAgICAgIC0gJ0NFTEVSWV9XT1JLRVJfQVVUT1NDQUxFPSR7Q0VMRVJZX1dPUktFUl9BVVRPU0NBTEU6LTEsM30nCiAgICAgIC0gJ0NFTEVSWV9XT1JLRVJfTUFYX1RBU0tTX1BFUl9DSElMRD0ke0NFTEVSWV9XT1JLRVJfTUFYX1RBU0tTX1BFUl9DSElMRDotMTAwMDB9Jwo=", + "compose": "c2VydmljZXM6CiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTUUx9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNRTF9EQVRBQkFTRTotZ2xpdGNodGlwfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2dsaXRjaHRpcC1wb3N0Z3Jlcy1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICByZWRpczoKICAgIGltYWdlOiByZWRpcwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gcGluZwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgd2ViOgogICAgaW1hZ2U6IGdsaXRjaHRpcC9nbGl0Y2h0aXAKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fR0xJVENIVElQXzgwODAKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTUUxAcG9zdGdyZXM6NTQzMi8ke1BPU1RHUkVTUUxfREFUQUJBU0U6LWdsaXRjaHRpcH0nCiAgICAgIC0gU0VDUkVUX0tFWT0kU0VSVklDRV9CQVNFNjRfNjRfRU5DUllQVElPTgogICAgICAtICdFTUFJTF9VUkw9JHtFTUFJTF9VUkw6LWNvbnNvbGVtYWlsOi8vfScKICAgICAgLSAnR0xJVENIVElQX0RPTUFJTj0ke1NFUlZJQ0VfRlFETl9HTElUQ0hUSVB9JwogICAgICAtICdERUZBVUxUX0ZST01fRU1BSUw9JHtERUZBVUxUX0ZST01fRU1BSUw6LXRlc3RAZXhhbXBsZS5jb219JwogICAgICAtICdDRUxFUllfV09SS0VSX0FVVE9TQ0FMRT0ke0NFTEVSWV9XT1JLRVJfQVVUT1NDQUxFOi0xLDN9JwogICAgICAtICdDRUxFUllfV09SS0VSX01BWF9UQVNLU19QRVJfQ0hJTEQ9JHtDRUxFUllfV09SS0VSX01BWF9UQVNLU19QRVJfQ0hJTEQ6LTEwMDAwfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3VwbG9hZHM6L2NvZGUvdXBsb2FkcycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBlY2hvCiAgICAgICAgLSBvawogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgd29ya2VyOgogICAgaW1hZ2U6IGdsaXRjaHRpcC9nbGl0Y2h0aXAKICAgIGNvbW1hbmQ6IC4vYmluL3J1bi1jZWxlcnktd2l0aC1iZWF0LnNoCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVNRTDokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMQHBvc3RncmVzOjU0MzIvJHtQT1NUR1JFU1FMX0RBVEFCQVNFOi1nbGl0Y2h0aXB9JwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0VOQ1JZUFRJT04KICAgICAgLSAnRU1BSUxfVVJMPSR7RU1BSUxfVVJMOi1jb25zb2xlbWFpbDovL30nCiAgICAgIC0gJ0dMSVRDSFRJUF9ET01BSU49JHtTRVJWSUNFX0ZRRE5fR0xJVENIVElQfScKICAgICAgLSAnREVGQVVMVF9GUk9NX0VNQUlMPSR7REVGQVVMVF9GUk9NX0VNQUlMOi10ZXN0QGV4YW1wbGUuY29tfScKICAgICAgLSAnQ0VMRVJZX1dPUktFUl9BVVRPU0NBTEU9JHtDRUxFUllfV09SS0VSX0FVVE9TQ0FMRTotMSwzfScKICAgICAgLSAnQ0VMRVJZX1dPUktFUl9NQVhfVEFTS1NfUEVSX0NISUxEPSR7Q0VMRVJZX1dPUktFUl9NQVhfVEFTS1NfUEVSX0NISUxEOi0xMDAwMH0nCiAgICB2b2x1bWVzOgogICAgICAtICd1cGxvYWRzOi9jb2RlL3VwbG9hZHMnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gZWNobwogICAgICAgIC0gb2sKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIG1pZ3JhdGU6CiAgICBpbWFnZTogZ2xpdGNodGlwL2dsaXRjaHRpcAogICAgcmVzdGFydDogJ25vJwogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGNvbW1hbmQ6ICcuL21hbmFnZS5weSBtaWdyYXRlJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVNRTDokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMQHBvc3RncmVzOjU0MzIvJHtQT1NUR1JFU1FMX0RBVEFCQVNFOi1nbGl0Y2h0aXB9JwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0VOQ1JZUFRJT04KICAgICAgLSAnRU1BSUxfVVJMPSR7RU1BSUxfVVJMOi1jb25zb2xlbWFpbDovL30nCiAgICAgIC0gJ0RFRkFVTFRfRlJPTV9FTUFJTD0ke0RFRkFVTFRfRlJPTV9FTUFJTDotdGVzdEBleGFtcGxlLmNvbX0nCiAgICAgIC0gJ0NFTEVSWV9XT1JLRVJfQVVUT1NDQUxFPSR7Q0VMRVJZX1dPUktFUl9BVVRPU0NBTEU6LTEsM30nCiAgICAgIC0gJ0NFTEVSWV9XT1JLRVJfTUFYX1RBU0tTX1BFUl9DSElMRD0ke0NFTEVSWV9XT1JLRVJfTUFYX1RBU0tTX1BFUl9DSElMRDotMTAwMDB9Jwo=", "tags": [ "error", "tracking", @@ -949,6 +1117,24 @@ "logo": "svgs/coolify.png", "minversion": "0.0.0" }, + "heyform": { + "documentation": "https://docs.heyform.net/open-source/self-hosting?utm_source=coolify.io", + "slogan": "Allows anyone to create engaging conversational forms for surveys, questionnaires, quizzes, and polls. No coding skills required.", + "compose": "c2VydmljZXM6CiAgaGV5Zm9ybToKICAgIGltYWdlOiAnaGV5Zm9ybS9jb21tdW5pdHktZWRpdGlvbjpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdoZXlmb3JtLWFzc2V0czovYXBwL3N0YXRpYy91cGxvYWQnCiAgICBkZXBlbmRzX29uOgogICAgICBtb25nbzoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBrZXlkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0hFWUZPUk1fODAwMAogICAgICAtICdBUFBfSE9NRVBBR0VfVVJMPSR7U0VSVklDRV9GUUROX0hFWUZPUk19JwogICAgICAtICdTRVNTSU9OX0tFWT0ke1NFUlZJQ0VfQkFTRTY0XzY0X1NFU1NJT059JwogICAgICAtICdGT1JNX0VOQ1JZUFRJT05fS0VZPSR7U0VSVklDRV9CQVNFNjRfNjRfRk9STX0nCiAgICAgIC0gJ01PTkdPX1VSST1tb25nb2RiOi8vbW9uZ286MjcwMTcvaGV5Zm9ybScKICAgICAgLSBSRURJU19IT1NUPWtleWRiCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3dnZXQgLXFPLSBodHRwOi8vMTI3LjAuMC4xOjgwMDAgfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMwogIG1vbmdvOgogICAgaW1hZ2U6ICdwZXJjb25hL3BlcmNvbmEtc2VydmVyLW1vbmdvZGI6bGF0ZXN0JwogICAgdm9sdW1lczoKICAgICAgLSAnaGV5Zm9ybS1tb25nby1kYXRhOi9kYXRhL2RiJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICJlY2hvICdvaycgPiAvZGV2L251bGwgMj4mMSIKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMKICBrZXlkYjoKICAgIGltYWdlOiAnZXFhbHBoYS9rZXlkYjpsYXRlc3QnCiAgICBjb21tYW5kOiAna2V5ZGItc2VydmVyIC0tYXBwZW5kb25seSB5ZXMnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnS0VZREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX0tFWURCfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2hleWZvcm0ta2V5ZGItZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBrZXlkYi1jbGkKICAgICAgICAtICctLXBhc3MnCiAgICAgICAgLSAnJHtTRVJWSUNFX1BBU1NXT1JEX0tFWURCfScKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogNXMK", + "tags": [ + "form", + "builder", + "forms", + "survey", + "quiz", + "open source", + "self-hosted", + "docker" + ], + "logo": "svgs/heyform.svg", + "minversion": "0.0.0", + "port": "8000" + }, "homarr": { "documentation": "https://homarr.dev?utm_source=coolify.io", "slogan": "Homarr is a self-hosted homepage for your services.", @@ -962,6 +1148,19 @@ "minversion": "0.0.0", "port": "7575" }, + "homebox": { + "documentation": "https://github.com/hay-kot/homebox?utm_source=coolify.io", + "slogan": "Homebox is a self-hosted file management solution.", + "compose": "c2VydmljZXM6CiAgaG9tZWJveDoKICAgIGltYWdlOiAnZ2hjci5pby9oYXkta290L2hvbWVib3g6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0hPTUVCT1hfNzc0NQogICAgICAtICdIQk9YX0xPR19MRVZFTD0ke0hCT1hfTE9HX0xFVkVMOi1pbmZvfScKICAgICAgLSAnSEJPWF9MT0dfRk9STUFUPSR7SEJPWF9MT0dfRk9STUFUOi10ZXh0fScKICAgICAgLSAnSEJPWF9XRUJfTUFYX1VQTE9BRF9TSVpFPSR7SEJPWF9XRUJfTUFYX1VQTE9BRF9TSVpFOi0xMH0nCiAgICB2b2x1bWVzOgogICAgICAtICdob21lYm94LWRhdGE6L2RhdGEvJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctcScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjc3NDUnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "tags": [ + "homebox", + "file-management", + "self-hosted" + ], + "logo": "svgs/homebox.svg", + "minversion": "0.0.0", + "port": "7745" + }, "homepage": { "documentation": "https://gethomepage.dev/latest/?utm_source=coolify.io", "slogan": "A modern, fully static, fast, secure fully proxied, highly customizable application dashboard", @@ -974,6 +1173,26 @@ "minversion": "0.0.0", "port": "3000" }, + "immich": { + "documentation": "https://immich.app/docs/overview/introduction?utm_source=coolify.io", + "slogan": "Self-hosted photo and video management solution.", + "compose": "c2VydmljZXM6CiAgaW1taWNoOgogICAgaW1hZ2U6ICdnaGNyLmlvL2ltbWljaC1hcHAvaW1taWNoLXNlcnZlcjpyZWxlYXNlJwogICAgdm9sdW1lczoKICAgICAgLSAnaW1taWNoLXVwbG9hZHM6L3Vzci9zcmMvYXBwL3VwbG9hZCcKICAgICAgLSAnL2V0Yy9sb2NhbHRpbWU6L2V0Yy9sb2NhbHRpbWU6cm8nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fSU1NSUNIXzMwMDEKICAgICAgLSBVUExPQURfTE9DQVRJT049Li9saWJyYXJ5CiAgICAgIC0gREJfREFUQV9MT0NBVElPTj0uL3Bvc3RncmVzCiAgICAgIC0gREJfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgLSBEQl9VU0VSTkFNRT0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gJ0RCX0RBVEFCQVNFX05BTUU9JHtEQl9EQVRBQkFTRV9OQU1FOi1pbW1pY2h9JwogICAgICAtICdUWj0ke1RaOi1FdGMvVVRDfScKICAgIGRlcGVuZHNfb246CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIGRhdGFiYXNlOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgZGlzYWJsZTogZmFsc2UKICBpbW1pY2gtbWFjaGluZS1sZWFybmluZzoKICAgIGNvbnRhaW5lcl9uYW1lOiBpbW1pY2hfbWFjaGluZV9sZWFybmluZwogICAgaW1hZ2U6ICdnaGNyLmlvL2ltbWljaC1hcHAvaW1taWNoLW1hY2hpbmUtbGVhcm5pbmc6cmVsZWFzZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ltbWljaC1tb2RlbC1jYWNoZTovY2FjaGUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBVUExPQURfTE9DQVRJT049Li9saWJyYXJ5CiAgICAgIC0gREJfREFUQV9MT0NBVElPTj0uL3Bvc3RncmVzCiAgICAgIC0gREJfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgLSBEQl9VU0VSTkFNRT0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gJ0RCX0RBVEFCQVNFX05BTUU9JHtEQl9EQVRBQkFTRV9OQU1FOi1pbW1pY2h9JwogICAgICAtICdUWj0ke1RaOi1FdGMvVVRDfScKICAgIGhlYWx0aGNoZWNrOgogICAgICBkaXNhYmxlOiBmYWxzZQogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LjQtYWxwaW5lJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gUElORwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDIwCiAgZGF0YWJhc2U6CiAgICBpbWFnZTogJ2RvY2tlci5pby90ZW5zb3JjaG9yZC9wZ3ZlY3RvLXJzOnBnMTQtdjAuMi4wQHNoYTI1Njo5MDcyNDE4NmYwYTM1MTdjZjY5MTQyOTViNWFiNDEwZGI5Y2UyMzE5MGEyZDlkMGI5ZGQ2NDYzZTNmYTI5OGYwJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIFBPU1RHUkVTX1BBU1NXT1JEOiAnJHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgUE9TVEdSRVNfVVNFUjogJyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgUE9TVEdSRVNfREI6ICcke0RCX0RBVEFCQVNFX05BTUU6LWltbWljaH0nCiAgICAgIFBPU1RHUkVTX0lOSVREQl9BUkdTOiAnLS1kYXRhLWNoZWNrc3VtcycKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ltbWljaC1wb3N0Z3Jlcy1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "tags": [ + "photo", + "video", + "management", + "server", + "cloud", + "storage", + "sharing", + "metadata", + "face", + "recognition" + ], + "logo": "svgs/immich.svg", + "minversion": "0.0.0", + "port": "2283" + }, "infisical": { "documentation": "https://infisical.com/docs/documentation/getting-started/introduction?utm_source=coolify.io", "slogan": "Infisical is the open source secret management platform that developers use to centralize their application configuration and secrets like API keys and database credentials.", @@ -1103,6 +1322,18 @@ "minversion": "0.0.0", "port": "8080" }, + "kimai": { + "documentation": "https://www.kimai.org/?utm_source=coolify.io", + "slogan": "Open source time-tracking app.", + "compose": "c2VydmljZXM6CiAgbXlzcWw6CiAgICBpbWFnZTogJ215c3FsOjgnCiAgICB2b2x1bWVzOgogICAgICAtICdraW1haS1teXNxbC1kYXRhOi92YXIvbGliL215c3FsJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ01ZU1FMX0RBVEFCQVNFPSR7TVlTUUxfREFUQUJBU0U6LWtpbWFpfScKICAgICAgLSAnTVlTUUxfVVNFUj0ke1NFUlZJQ0VfVVNFUl9NWVNRTH0nCiAgICAgIC0gJ01ZU1FMX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NWVNRTH0nCiAgICAgIC0gJ01ZU1FMX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1JPT1R9JwogICAgY29tbWFuZDogJy0tZGVmYXVsdC1zdG9yYWdlLWVuZ2luZSBpbm5vZGInCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbXlzcWxhZG1pbgogICAgICAgIC0gcGluZwogICAgICAgIC0gJy1oJwogICAgICAgIC0gMTI3LjAuMC4xCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICBraW1haToKICAgIGltYWdlOiAna2ltYWkva2ltYWkyOmFwYWNoZS1sYXRlc3QnCiAgICBjb250YWluZXJfbmFtZToga2ltYWkKICAgIGRlcGVuZHNfb246CiAgICAgIG15c3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICB2b2x1bWVzOgogICAgICAtICdraW1haS1kYXRhOi9vcHQva2ltYWkvdmFyL2RhdGEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fS0lNQUlfODAwMQogICAgICAtICdBUFBfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9BUFBTRUNSRVR9JwogICAgICAtICdNQUlMRVJfRlJPTT0ke01BSUxFUl9GUk9NOi1raW1haUBleGFtcGxlLmNvbX0nCiAgICAgIC0gJ01BSUxFUl9VUkw9JHtNQUlMRVJfVVJMOi1udWxsOi8vbnVsbH0nCiAgICAgIC0gJ0FETUlOTUFJTD0ke0FETUlOTUFJTDotYWRtaW5Aa2ltYWkubG9jYWx9JwogICAgICAtICdBRE1JTlBBU1M9JHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOUEFTU30nCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1teXNxbDovLyR7U0VSVklDRV9VU0VSX01ZU1FMfToke1NFUlZJQ0VfUEFTU1dPUkRfTVlTUUx9QG15c3FsLyR7TVlTUUxfREFUQUJBU0V9P2NoYXJzZXQ9dXRmOG1iNCZzZXJ2ZXJWZXJzaW9uPTguMy4wJwogICAgICAtIFRSVVNURURfSE9TVFM9bG9jYWxob3N0CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6ODAwMScKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQo=", + "tags": [ + "time-tracking", + "open-source" + ], + "logo": "svgs/kimai.svg", + "minversion": "0.0.0", + "port": "8001" + }, "kuzzle": { "documentation": "https://kuzzle.io?utm_source=coolify.io", "slogan": "Kuzzle is a generic backend offering the basic building blocks common to every application.", @@ -1185,6 +1416,18 @@ "minversion": "0.0.0", "port": "3000" }, + "libretranslate": { + "documentation": "https://libretranslate.com/docs/?utm_source=coolify.io", + "slogan": "Free and open-source machine translation API, entirely self-hosted.", + "compose": "c2VydmljZXM6CiAgbGlicmV0cmFuc2xhdGU6CiAgICBpbWFnZTogJ2xpYnJldHJhbnNsYXRlL2xpYnJldHJhbnNsYXRlOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9MSUJSRVRSQU5TTEFURV81MDAwCiAgICAgIC0gJ0xUX1NTTD0ke0xUX1NTTDotdHJ1ZX0nCiAgICAgIC0gJ0xUX1VQREFURV9NT0RFTFM9JHtMVF9VUERBVEVfTU9ERUxTOi10cnVlfScKICAgICAgLSAnTFRfTE9BRF9PTkxZPSR7TFRfTE9BRF9PTkxZOi1lbixlcyxmcixkZSxqYX0nCiAgICB2b2x1bWVzOgogICAgICAtICdsaWJyZXRyYW5zbGF0ZS1hcGkta2V5czovYXBwL2RiJwogICAgICAtICdsaWJyZXRyYW5zbGF0ZS1tb2RlbHM6L2hvbWUvbGlicmV0cmFuc2xhdGUvLmxvY2FsJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICcuL3ZlbnYvYmluL3B5dGhvbiBzY3JpcHRzL2hlYWx0aGNoZWNrLnB5Jwo=", + "tags": [ + "translate", + "api" + ], + "logo": "svgs/libretranslate.svg", + "minversion": "0.0.0", + "port": "5000" + }, "listmonk": { "documentation": "https://listmonk.app/?utm_source=coolify.io", "slogan": "Self-hosted newsletter and mailing list manager", @@ -1452,10 +1695,10 @@ "minversion": "0.0.0", "port": "3000" }, - "nextcloud": { + "nextcloud-with-mariadb": { "documentation": "https://docs.nextcloud.com?utm_source=coolify.io", "slogan": "NextCloud is a self-hosted, open-source platform that provides file storage, collaboration, and communication tools for seamless data management.", - "compose": "c2VydmljZXM6CiAgbmV4dGNsb3VkOgogICAgaW1hZ2U6ICdsc2NyLmlvL2xpbnV4c2VydmVyL25leHRjbG91ZDpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTkVYVENMT1VECiAgICAgIC0gUFVJRD0xMDAwCiAgICAgIC0gUEdJRD0xMDAwCiAgICAgIC0gVFo9RXVyb3BlL01hZHJpZAogICAgdm9sdW1lczoKICAgICAgLSAnbmV4dGNsb3VkLWNvbmZpZzovY29uZmlnJwogICAgICAtICduZXh0Y2xvdWQtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo4MCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQo=", + "compose": "c2VydmljZXM6CiAgbmV4dGNsb3VkOgogICAgaW1hZ2U6ICdsc2NyLmlvL2xpbnV4c2VydmVyL25leHRjbG91ZDpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTkVYVENMT1VEXzgwCiAgICAgIC0gUFVJRD0xMDAwCiAgICAgIC0gUEdJRD0xMDAwCiAgICAgIC0gJ1RaPSR7VFo6LUV1cm9wZS9QYXJpc30nCiAgICAgIC0gJ01ZU1FMX0RBVEFCQVNFPSR7TUFSSUFEQl9EQVRBQkFTRTotbmV4dGNsb3VkfScKICAgICAgLSAnTVlTUUxfVVNFUj0ke1NFUlZJQ0VfVVNFUl9NQVJJQURCfScKICAgICAgLSAnTVlTUUxfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01BUklBREJ9JwogICAgICAtIE1ZU1FMX0hPU1Q9bmV4dGNsb3VkLWRiCiAgICAgIC0gUkVESVNfSE9TVD1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgdm9sdW1lczoKICAgICAgLSAnbmV4dGNsb3VkLWNvbmZpZzovY29uZmlnJwogICAgICAtICduZXh0Y2xvdWQtZGF0YTovZGF0YScKICAgIGRlcGVuZHNfb246CiAgICAgIG5leHRjbG91ZC1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjgwJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1CiAgbmV4dGNsb3VkLWRiOgogICAgaW1hZ2U6ICdtYXJpYWRiOjExJwogICAgdm9sdW1lczoKICAgICAgLSAnbmV4dGNsb3VkLW1hcmlhZGItZGF0YTovdmFyL2xpYi9teXNxbCcKICAgIGVudmlyb25tZW50OgogICAgICAtICdNWVNRTF9ST09UX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9ST09UfScKICAgICAgLSAnTVlTUUxfREFUQUJBU0U9JHtNQVJJQURCX0RBVEFCQVNFOi1uZXh0Y2xvdWR9JwogICAgICAtICdNWVNRTF9VU0VSPSR7U0VSVklDRV9VU0VSX01BUklBREJ9JwogICAgICAtICdNWVNRTF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTUFSSUFEQn0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gaGVhbHRoY2hlY2suc2gKICAgICAgICAtICctLWNvbm5lY3QnCiAgICAgICAgLSAnLS1pbm5vZGJfaW5pdGlhbGl6ZWQnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICByZWRpczoKICAgIGltYWdlOiAncmVkaXM6Ny40LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ25leHRjbG91ZC1yZWRpcy1kYXRhOi9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gUElORwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDIwCg==", "tags": [ "cloud", "collaboration", @@ -1464,7 +1707,53 @@ "data" ], "logo": "svgs/nextcloud.svg", - "minversion": "0.0.0" + "minversion": "0.0.0", + "port": "80" + }, + "nextcloud-with-mysql": { + "documentation": "https://docs.nextcloud.com?utm_source=coolify.io", + "slogan": "NextCloud is a self-hosted, open-source platform that provides file storage, collaboration, and communication tools for seamless data management.", + "compose": "c2VydmljZXM6CiAgbmV4dGNsb3VkOgogICAgaW1hZ2U6ICdsc2NyLmlvL2xpbnV4c2VydmVyL25leHRjbG91ZDpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTkVYVENMT1VEXzgwCiAgICAgIC0gUFVJRD0xMDAwCiAgICAgIC0gUEdJRD0xMDAwCiAgICAgIC0gJ1RaPSR7VFo6LUV1cm9wZS9QYXJpc30nCiAgICAgIC0gJ01ZU1FMX0RBVEFCQVNFPSR7TVlTUUxfREFUQUJBU0U6LW5leHRjbG91ZH0nCiAgICAgIC0gJ01ZU1FMX1VTRVI9JHtTRVJWSUNFX1VTRVJfTVlTUUx9JwogICAgICAtICdNWVNRTF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTVlTUUx9JwogICAgICAtIE1ZU1FMX0hPU1Q9bmV4dGNsb3VkLWRiCiAgICAgIC0gUkVESVNfSE9TVD1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgdm9sdW1lczoKICAgICAgLSAnbmV4dGNsb3VkLWNvbmZpZzovY29uZmlnJwogICAgICAtICduZXh0Y2xvdWQtZGF0YTovZGF0YScKICAgIGRlcGVuZHNfb246CiAgICAgIG5leHRjbG91ZC1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjgwJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1CiAgbmV4dGNsb3VkLWRiOgogICAgaW1hZ2U6ICdteXNxbDo4LjQuMicKICAgIHZvbHVtZXM6CiAgICAgIC0gJ25leHRjbG91ZC1teXNxbC1kYXRhOi92YXIvbGliL215c3FsJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ01ZU1FMX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1JPT1R9JwogICAgICAtICdNWVNRTF9EQVRBQkFTRT0ke01ZU1FMX0RBVEFCQVNFOi1uZXh0Y2xvdWR9JwogICAgICAtICdNWVNRTF9VU0VSPSR7U0VSVklDRV9VU0VSX01ZU1FMfScKICAgICAgLSAnTVlTUUxfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01ZU1FMfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBteXNxbGFkbWluCiAgICAgICAgLSBwaW5nCiAgICAgICAgLSAnLWgnCiAgICAgICAgLSAxMjcuMC4wLjEKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LjQtYWxwaW5lJwogICAgdm9sdW1lczoKICAgICAgLSAnbmV4dGNsb3VkLXJlZGlzLWRhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSBQSU5HCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMjAK", + "tags": [ + "cloud", + "collaboration", + "communication", + "filestorage", + "data" + ], + "logo": "svgs/nextcloud.svg", + "minversion": "0.0.0", + "port": "80" + }, + "nextcloud-with-postgres": { + "documentation": "https://docs.nextcloud.com?utm_source=coolify.io", + "slogan": "NextCloud is a self-hosted, open-source platform that provides file storage, collaboration, and communication tools for seamless data management.", + "compose": "c2VydmljZXM6CiAgbmV4dGNsb3VkOgogICAgaW1hZ2U6ICdsc2NyLmlvL2xpbnV4c2VydmVyL25leHRjbG91ZDpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTkVYVENMT1VEXzgwCiAgICAgIC0gUFVJRD0xMDAwCiAgICAgIC0gUEdJRD0xMDAwCiAgICAgIC0gJ1RaPSR7VFo6LUV1cm9wZS9QYXJpc30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LW5leHRjbG91ZH0nCiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtIFBPU1RHUkVTX0hPU1Q9bmV4dGNsb3VkLWRiCiAgICAgIC0gUkVESVNfSE9TVD1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgdm9sdW1lczoKICAgICAgLSAnbmV4dGNsb3VkLWNvbmZpZzovY29uZmlnJwogICAgICAtICduZXh0Y2xvdWQtZGF0YTovZGF0YScKICAgIGRlcGVuZHNfb246CiAgICAgIG5leHRjbG91ZC1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjgwJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1CiAgbmV4dGNsb3VkLWRiOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICB2b2x1bWVzOgogICAgICAtICduZXh0Y2xvdWQtcG9zdGdyZXNxbC1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotbmV4dGNsb3VkfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICByZWRpczoKICAgIGltYWdlOiAncmVkaXM6Ny40LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ25leHRjbG91ZC1yZWRpcy1kYXRhOi9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gUElORwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDIwCg==", + "tags": [ + "cloud", + "collaboration", + "communication", + "filestorage", + "data" + ], + "logo": "svgs/nextcloud.svg", + "minversion": "0.0.0", + "port": "80" + }, + "nextcloud": { + "documentation": "https://docs.nextcloud.com?utm_source=coolify.io", + "slogan": "NextCloud is a self-hosted, open-source platform that provides file storage, collaboration, and communication tools for seamless data management.", + "compose": "c2VydmljZXM6CiAgbmV4dGNsb3VkOgogICAgaW1hZ2U6ICdsc2NyLmlvL2xpbnV4c2VydmVyL25leHRjbG91ZDpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTkVYVENMT1VEXzgwCiAgICAgIC0gUFVJRD0xMDAwCiAgICAgIC0gUEdJRD0xMDAwCiAgICAgIC0gJ1RaPSR7VFo6LUV1cm9wZS9NYWRyaWR9JwogICAgdm9sdW1lczoKICAgICAgLSAnbmV4dGNsb3VkLWNvbmZpZzovY29uZmlnJwogICAgICAtICduZXh0Y2xvdWQtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo4MCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQo=", + "tags": [ + "cloud", + "collaboration", + "communication", + "filestorage", + "data" + ], + "logo": "svgs/nextcloud.svg", + "minversion": "0.0.0", + "port": "80" }, "nitropage-with-postgresql": { "documentation": "https://nitropage.com?utm_source=coolify.io", @@ -1517,6 +1806,21 @@ "minversion": "0.0.0", "port": "8080" }, + "ntfy": { + "documentation": "https://docs.ntfy.sh/?utm_source=coolify.io", + "slogan": "ntfy is a simple HTTP-based pub-sub notification service. It allows you to send notifications to your phone or desktop via scripts from any computer, and/or using a REST API.", + "compose": "c2VydmljZXM6CiAgbnRmeToKICAgIGltYWdlOiBiaW53aWVkZXJoaWVyL250ZnkKICAgIGNvbW1hbmQ6CiAgICAgIC0gc2VydmUKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9OVEZZXzgwCiAgICAgIC0gJ05URllfQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fTlRGWX0nCiAgICAgIC0gJ1RaPSR7VFo6LVVUQ30nCiAgICAgIC0gTlRGWV9DQUNIRV9GSUxFPS92YXIvY2FjaGUvbnRmeS9jYWNoZS5kYgogICAgICAtIE5URllfQVVUSF9GSUxFPS92YXIvbGliL250ZnkvYXV0aC5kYgogICAgICAtICdOVEZZX1VQU1RSRUFNX0JBU0VfVVJMPSR7VVBTVFJFQU1fQkFTRV9VUkw6LWh0dHBzOi8vbnRmeS5zaH0nCiAgICAgIC0gJ05URllfRU5BQkxFX1NJR05VUD0ke05URllfRU5BQkxFX1NJR05VUDotdHJ1ZX0nCiAgICAgIC0gJ05URllfRU5BQkxFX0xPR0lOPSR7TlRGWV9FTkFCTEVfTE9HSU46LXRydWV9JwogICAgICAtICdOVEZZX0NBQ0hFX0RVUkFUSU9OPSR7TlRGWV9DQUNIRV9EVVJBVElPTjotMjRofScKICAgICAgLSAnTlRGWV9BVFRBQ0hNRU5UX1RPVEFMX1NJWkVfTElNSVQ9JHtOVEZZX0FUVEFDSE1FTlRfVE9UQUxfU0laRV9MSU1JVDotMUd9JwogICAgICAtICdOVEZZX0FUVEFDSE1FTlRfRklMRV9TSVpFX0xJTUlUPSR7TlRGWV9BVFRBQ0hNRU5UX0ZJTEVfU0laRV9MSU1JVDotMTBNfScKICAgICAgLSAnTlRGWV9BVFRBQ0hNRU5UX0VYUElSWV9EVVJBVElPTj0ke05URllfQVRUQUNITUVOVF9FWFBJUllfRFVSQVRJT046LTI0aH0nCiAgICAgIC0gJ05URllfU01UUF9TRU5ERVJfQUREUj0ke05URllfU01UUF9TRU5ERVJfQUREUjotc210cC55b3VyLWRvbWFpbi5kZX0nCiAgICAgIC0gJ05URllfU01UUF9TRU5ERVJfVVNFUj0ke05URllfU01UUF9TRU5ERVJfVVNFUjotbm8tcmVwbHlAZGV9JwogICAgICAtICdOVEZZX1NNVFBfU0VOREVSX1BBU1M9JHtOVEZZX1NNVFBfU0VOREVSX1BBU1M6LXBhc3N3b3JkfScKICAgICAgLSAnTlRGWV9TTVRQX1NFTkRFUl9GUk9NPSR7TlRGWV9TTVRQX1NFTkRFUl9GUk9NOi1uby1yZXBseUBkZX0nCiAgICAgIC0gJ05URllfS0VFUEFMSVZFX0lOVEVSVkFMPSR7TlRGWV9LRUVQQUxJVkVfSU5URVJWQUw6LTVtfScKICAgICAgLSAnTlRGWV9NQU5BR0VSX0lOVEVSVkFMPSR7TlRGWV9NQU5BR0VSX0lOVEVSVkFMOi01bX0nCiAgICAgIC0gJ05URllfVklTSVRPUl9NRVNTQUdFX0RBSUxZX0xJTUlUPSR7TlRGWV9WSVNJVE9SX01FU1NBR0VfREFJTFlfTElNSVQ6LTEwMH0nCiAgICAgIC0gJ05URllfVklTSVRPUl9BVFRBQ0hNRU5UX0RBSUxZX0JBTkRXSURUSF9MSU1JVD0ke05URllfVklTSVRPUl9BVFRBQ0hNRU5UX0RBSUxZX0JBTkRXSURUSF9MSU1JVDotMUd9JwogICAgICAtICdOVEZZX1VQU1RSRUFNX0FDQ0VTU19UT0tFTj0ke1VQU1RSRUFNX0FDQ0VTU19UT0tFTn0nCiAgICAgIC0gJ05URllfQVVUSF9ERUZBVUxUX0FDQ0VTUz0ke05URllfQVVUSF9ERUZBVUxUX0FDQ0VTUzotcmVhZC13cml0ZX0nCiAgICAgIC0gJ05URllfV0VCX1BVU0hfUFVCTElDX0tFWT0ke05URllfV0VCX1BVU0hfUFVCTElDX0tFWX0nCiAgICAgIC0gJ05URllfV0VCX1BVU0hfUFJJVkFURV9LRVk9JHtOVEZZX1dFQl9QVVNIX1BSSVZBVEVfS0VZfScKICAgICAgLSAnTlRGWV9XRUJfUFVTSF9FTUFJTF9BRERSRVNTPSR7TlRGWV9XRUJfUFVTSF9FTUFJTF9BRERSRVNTfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ250ZnktY2FjaGU6L3Zhci9jYWNoZS9udGZ5JwogICAgICAtICdudGZ5LWRiOi92YXIvbGliL250ZnkvJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICd3Z2V0IC1xIC0tdHJpZXM9MSBodHRwOi8vbG9jYWxob3N0OjgwL3YxL2hlYWx0aCAtTyAtIHwgZ3JlcCAtRW8gJyciaGVhbHRoeSJccyo6XHMqdHJ1ZScnIHx8IGV4aXQgMScKICAgICAgaW50ZXJ2YWw6IDYwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogICAgICBzdGFydF9wZXJpb2Q6IDQwcwo=", + "tags": [ + "ntfy", + "notification", + "push notification", + "pub-sub", + "notify" + ], + "logo": "svgs/ntfy.svg", + "minversion": "0.0.0", + "port": "80" + }, "odoo": { "documentation": "https://www.odoo.com/?utm_source=coolify.io", "slogan": "Odoo is a suite of open-source business apps that cover all your company needs.", @@ -1601,6 +1905,21 @@ "minversion": "0.0.0", "port": "80" }, + "owncloud": { + "documentation": "https://owncloud.com/docs?utm_source=coolify.io", + "slogan": "OwnCloud with Open Web UI integrates file management with a powerful, user-friendly interface.", + "compose": "c2VydmljZXM6CiAgb3duY2xvdWQ6CiAgICBpbWFnZTogJ293bmNsb3VkL3NlcnZlcjpsYXRlc3QnCiAgICBkZXBlbmRzX29uOgogICAgICBtYXJpYWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fT1dOQ0xPVURfODA4MAogICAgICAtICdPV05DTE9VRF9ET01BSU49JHtTRVJWSUNFX0ZRRE5fT1dOQ0xPVUR9JwogICAgICAtICdPV05DTE9VRF9UUlVTVEVEX0RPTUFJTlM9JHtTRVJWSUNFX1VSTF9PV05DTE9VRH0nCiAgICAgIC0gT1dOQ0xPVURfREJfVFlQRT1teXNxbAogICAgICAtIE9XTkNMT1VEX0RCX0hPU1Q9bWFyaWFkYgogICAgICAtICdPV05DTE9VRF9EQl9OQU1FPSR7REJfTkFNRTotb3duY2xvdWR9JwogICAgICAtICdPV05DTE9VRF9EQl9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9NQVJJQURCfScKICAgICAgLSAnT1dOQ0xPVURfREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01BUklBREJ9JwogICAgICAtICdPV05DTE9VRF9BRE1JTl9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9PV05DTE9VRH0nCiAgICAgIC0gJ09XTkNMT1VEX0FETUlOX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9PV05DTE9VRH0nCiAgICAgIC0gJ09XTkNMT1VEX01ZU1FMX1VURjhNQjQ9JHtNWVNRTF9VVEY4TUI0Oi10cnVlfScKICAgICAgLSAnT1dOQ0xPVURfUkVESVNfRU5BQkxFRD0ke1JFRElTX0VOQUJMRUQ6LXRydWV9JwogICAgICAtIE9XTkNMT1VEX1JFRElTX0hPU1Q9cmVkaXMKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSAvdXNyL2Jpbi9oZWFsdGhjaGVjawogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiA1CiAgICB2b2x1bWVzOgogICAgICAtICdvd25jbG91ZC1kYXRhOi9tbnQvZGF0YScKICBtYXJpYWRiOgogICAgaW1hZ2U6ICdtYXJpYWRiOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtICdNWVNRTF9ST09UX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCUk9PVH0nCiAgICAgIC0gJ01ZU1FMX1VTRVI9JHtTRVJWSUNFX1VTRVJfTUFSSUFEQn0nCiAgICAgIC0gJ01ZU1FMX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCfScKICAgICAgLSAnTVlTUUxfREFUQUJBU0U9JHtEQl9OQU1FOi1vd25jbG91ZH0nCiAgICAgIC0gVFo9YXV0bwogICAgY29tbWFuZDoKICAgICAgLSAnLS1jaGFyYWN0ZXItc2V0LXNlcnZlcj11dGY4bWI0JwogICAgICAtICctLWNvbGxhdGlvbi1zZXJ2ZXI9dXRmOG1iNF9iaW4nCiAgICAgIC0gJy0tbWF4LWFsbG93ZWQtcGFja2V0PTEyOE0nCiAgICAgIC0gJy0taW5ub2RiLWxvZy1maWxlLXNpemU9NjRNJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGhlYWx0aGNoZWNrLnNoCiAgICAgICAgLSAnLS1jb25uZWN0JwogICAgICAgIC0gJy0taW5ub2RiX2luaXRpYWxpemVkJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgICB2b2x1bWVzOgogICAgICAtICdvd25jbG91ZC1teXNxbC1kYXRhOi92YXIvbGliL215c3FsJwogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo2JwogICAgY29tbWFuZDoKICAgICAgLSAnLS1kYXRhYmFzZXMnCiAgICAgIC0gJzEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSBwaW5nCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQo=", + "tags": [ + "owncloud", + "file-management", + "open-web-ui", + "integration", + "cloud" + ], + "logo": "svgs/owncloud.svg", + "minversion": "0.0.0", + "port": "8080" + }, "pairdrop": { "documentation": "https://pairdrop.net/?utm_source=coolify.io", "slogan": "Pairdrop is a self-hosted file sharing and collaboration platform, offering secure file sharing and collaboration capabilities for efficient teamwork.", @@ -1639,6 +1958,20 @@ "logo": "svgs/coolify.png", "minversion": "0.0.0" }, + "peppermint": { + "documentation": "https://docs.peppermint.sh/?utm_source=coolify.io", + "slogan": "Open source helpdesk solution designed to enhance the user experience for teams currently utilizing costly software alternatives", + "compose": "c2VydmljZXM6CiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3BlcHBlcm1pbnQtcG9zdGdyZXNxbC1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotcGVwcGVybWludC1kYn0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcGVwcGVybWludDoKICAgIGltYWdlOiAncGVwcGVybGFicy9wZXBwZXJtaW50OmxhdGVzdCcKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1BFUFBFUk1JTlRfMzAwMAogICAgICAtIFNFUlZJQ0VfRlFETl9QRVBQRVJNSU5UXzUwMDMKICAgICAgLSAnREJfVVNFUk5BTUU9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdEQl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtIERCX0hPU1Q9cG9zdGdyZXMKICAgICAgLSAnREJfTkFNRT0ke1BPU1RHUkVTX0RCOi1wZXBwZXJtaW50LWRifScKICAgICAgLSAnU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9QRVBQRVJNSU5UfScKICAgICAgLSAnQVBJX1VSTD0ke1NFUlZJQ0VfRlFETl9QRVBQRVJNSU5UXzUwMDN9Jwo=", + "tags": [ + "helpdesk", + "open-source", + "peppermint", + "postgres" + ], + "logo": "svgs/peppermint.png", + "minversion": "0.0.0", + "port": "3000" + }, "phpmyadmin": { "documentation": "https://phpmyadmin.net?utm_source=coolify.io", "slogan": "phpMyAdmin is a web-based database management tool for administering your MySQL and MariaDB databases through a user-friendly interface.", @@ -1652,7 +1985,7 @@ "plane": { "documentation": "https://docs.plane.so/self-hosting/methods/docker-compose?utm_source=coolify.io", "slogan": "The open source project management tool", - "compose": "eC1hcHAtZW52OgogIGVudmlyb25tZW50OgogICAgLSAnV0VCX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgIC0gJ0NPUlNfQUxMT1dFRF9PUklHSU5TPSR7Q09SU19BTExPV0VEX09SSUdJTjotaHR0cDovL2xvY2FsaG9zdH0nCiAgICAtICdHVU5JQ09STl9XT1JLRVJTPSR7R1VOSUNPUk5fV09SS0VSUzotMX0nCiAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgLSBQR0RBVEFCQVNFPXBsYW5lCiAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgLSBQT1NUR1JFU19EQj1wbGFuZQogICAgLSBQT1NUR1JFU19QT1JUPTU0MzIKICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzcWw6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBsYW5lLWRiL3BsYW5lJwogICAgLSBSRURJU19IT1NUPXBsYW5lLXJlZGlzCiAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgLSAnUkVESVNfVVJMPSR7UkVESVNfVVJMOi1yZWRpczovL3BsYW5lLXJlZGlzOjYzNzkvfScKICAgIC0gU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF82NF9TRUNSRVRLRVkKICAgIC0gJ1VTRV9NSU5JTz0ke1VTRV9NSU5JTzotMX0nCiAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAtIEFXU19BQ0NFU1NfS0VZX0lEPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgIC0gQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAtICdBV1NfUzNfRU5EUE9JTlRfVVJMPSR7QVdTX1MzX0VORFBPSU5UX1VSTDotaHR0cDovL3BsYW5lLW1pbmlvOjkwMDB9JwogICAgLSAnQVdTX1MzX0JVQ0tFVF9OQU1FPSR7QVdTX1MzX0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgIC0gTUlOSU9fUk9PVF9VU0VSPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgLSAnQlVDS0VUX05BTUU9JHtCVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAtICdGSUxFX1NJWkVfTElNSVQ9JHtGSUxFX1NJWkVfTElNSVQ6LTUyNDI4ODB9JwogICAgLSAnQURNSU5fQkFTRV9VUkw9JHtBRE1JTl9CQVNFX1VSTH0nCiAgICAtICdTUEFDRV9CQVNFX1VSTD0ke1NQQUNFX0JBU0VfVVJMfScKICAgIC0gJ0FQUF9CQVNFX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCnNlcnZpY2VzOgogIHByb3h5OgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1BMQU5FCiAgICAgIC0gJ0ZJTEVfU0laRV9MSU1JVD0ke0ZJTEVfU0laRV9MSU1JVDotNTI0Mjg4MH0nCiAgICAgIC0gJ0JVQ0tFVF9OQU1FPSR7QlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgaW1hZ2U6ICdtYWtlcGxhbmUvcGxhbmUtcHJveHk6c3RhYmxlJwogICAgZGVwZW5kc19vbjoKICAgICAgLSB3ZWIKICAgICAgLSBhcGkKICAgICAgLSBzcGFjZQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjgwJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1CiAgd2ViOgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1dFQl9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgICAgLSAnQ09SU19BTExPV0VEX09SSUdJTlM9JHtDT1JTX0FMTE9XRURfT1JJR0lOOi1odHRwOi8vbG9jYWxob3N0fScKICAgICAgLSAnR1VOSUNPUk5fV09SS0VSUz0ke0dVTklDT1JOX1dPUktFUlM6LTF9JwogICAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgICAtIFBHREFUQUJBU0U9cGxhbmUKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX0RCPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcGxhbmUtZGIvcGxhbmUnCiAgICAgIC0gUkVESVNfSE9TVD1wbGFuZS1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtICdSRURJU19VUkw9JHtSRURJU19VUkw6LXJlZGlzOi8vcGxhbmUtcmVkaXM6NjM3OS99JwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfU0VDUkVUS0VZCiAgICAgIC0gJ1VTRV9NSU5JTz0ke1VTRV9NSU5JTzotMX0nCiAgICAgIC0gJ0FXU19SRUdJT049JHtBV1NfUkVHSU9OfScKICAgICAgLSBBV1NfQUNDRVNTX0tFWV9JRD0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0FXU19TM19FTkRQT0lOVF9VUkw9JHtBV1NfUzNfRU5EUE9JTlRfVVJMOi1odHRwOi8vcGxhbmUtbWluaW86OTAwMH0nCiAgICAgIC0gJ0FXU19TM19CVUNLRVRfTkFNRT0ke0FXU19TM19CVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gTUlOSU9fUk9PVF9VU0VSPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBNSU5JT19ST09UX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0JVQ0tFVF9OQU1FPSR7QlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtICdGSUxFX1NJWkVfTElNSVQ9JHtGSUxFX1NJWkVfTElNSVQ6LTUyNDI4ODB9JwogICAgICAtICdBRE1JTl9CQVNFX1VSTD0ke0FETUlOX0JBU0VfVVJMfScKICAgICAgLSAnU1BBQ0VfQkFTRV9VUkw9JHtTUEFDRV9CQVNFX1VSTH0nCiAgICAgIC0gJ0FQUF9CQVNFX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICBpbWFnZTogJ21ha2VwbGFuZS9wbGFuZS1mcm9udGVuZDpzdGFibGUnCiAgICBjb21tYW5kOiAnbm9kZSB3ZWIvc2VydmVyLmpzIHdlYicKICAgIGRlcGVuZHNfb246CiAgICAgIC0gYXBpCiAgICAgIC0gd29ya2VyCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDogJ3dnZXQgLXFPLSBodHRwOi8vYGhvc3RuYW1lYDozMDAwJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1CiAgc3BhY2U6CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnV0VCX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICAgIC0gJ0RFQlVHPSR7REVCVUc6LTB9JwogICAgICAtICdDT1JTX0FMTE9XRURfT1JJR0lOUz0ke0NPUlNfQUxMT1dFRF9PUklHSU46LWh0dHA6Ly9sb2NhbGhvc3R9JwogICAgICAtICdHVU5JQ09STl9XT1JLRVJTPSR7R1VOSUNPUk5fV09SS0VSUzotMX0nCiAgICAgIC0gUEdIT1NUPXBsYW5lLWRiCiAgICAgIC0gUEdEQVRBQkFTRT1wbGFuZQogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfREI9cGxhbmUKICAgICAgLSBQT1NUR1JFU19QT1JUPTU0MzIKICAgICAgLSBQR0RBVEE9L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0BwbGFuZS1kYi9wbGFuZScKICAgICAgLSBSRURJU19IT1NUPXBsYW5lLXJlZGlzCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICAgIC0gJ1JFRElTX1VSTD0ke1JFRElTX1VSTDotcmVkaXM6Ly9wbGFuZS1yZWRpczo2Mzc5L30nCiAgICAgIC0gU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF82NF9TRUNSRVRLRVkKICAgICAgLSAnVVNFX01JTklPPSR7VVNFX01JTklPOi0xfScKICAgICAgLSAnQVdTX1JFR0lPTj0ke0FXU19SRUdJT059JwogICAgICAtIEFXU19BQ0NFU1NfS0VZX0lEPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgICAgLSAnQVdTX1MzX0VORFBPSU5UX1VSTD0ke0FXU19TM19FTkRQT0lOVF9VUkw6LWh0dHA6Ly9wbGFuZS1taW5pbzo5MDAwfScKICAgICAgLSAnQVdTX1MzX0JVQ0tFVF9OQU1FPSR7QVdTX1MzX0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSBNSU5JT19ST09UX1VTRVI9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIE1JTklPX1JPT1RfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgICAgLSAnQlVDS0VUX05BTUU9JHtCVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gJ0ZJTEVfU0laRV9MSU1JVD0ke0ZJTEVfU0laRV9MSU1JVDotNTI0Mjg4MH0nCiAgICAgIC0gJ0FETUlOX0JBU0VfVVJMPSR7QURNSU5fQkFTRV9VUkx9JwogICAgICAtICdTUEFDRV9CQVNFX1VSTD0ke1NQQUNFX0JBU0VfVVJMfScKICAgICAgLSAnQVBQX0JBU0VfVVJMPSR7U0VSVklDRV9GUUROX1BMQU5FfScKICAgIGltYWdlOiAnbWFrZXBsYW5lL3BsYW5lLXNwYWNlOnN0YWJsZScKICAgIGNvbW1hbmQ6ICdub2RlIHNwYWNlL3NlcnZlci5qcyBzcGFjZScKICAgIGRlcGVuZHNfb246CiAgICAgIC0gYXBpCiAgICAgIC0gd29ya2VyCiAgICAgIC0gd2ViCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gZWNobwogICAgICAgIC0gJ2hleSB3aGF0cyB1cCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogIGFkbWluOgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1dFQl9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgICAgLSAnQ09SU19BTExPV0VEX09SSUdJTlM9JHtDT1JTX0FMTE9XRURfT1JJR0lOOi1odHRwOi8vbG9jYWxob3N0fScKICAgICAgLSAnR1VOSUNPUk5fV09SS0VSUz0ke0dVTklDT1JOX1dPUktFUlM6LTF9JwogICAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgICAtIFBHREFUQUJBU0U9cGxhbmUKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX0RCPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcGxhbmUtZGIvcGxhbmUnCiAgICAgIC0gUkVESVNfSE9TVD1wbGFuZS1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtICdSRURJU19VUkw9JHtSRURJU19VUkw6LXJlZGlzOi8vcGxhbmUtcmVkaXM6NjM3OS99JwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfU0VDUkVUS0VZCiAgICAgIC0gJ1VTRV9NSU5JTz0ke1VTRV9NSU5JTzotMX0nCiAgICAgIC0gJ0FXU19SRUdJT049JHtBV1NfUkVHSU9OfScKICAgICAgLSBBV1NfQUNDRVNTX0tFWV9JRD0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0FXU19TM19FTkRQT0lOVF9VUkw9JHtBV1NfUzNfRU5EUE9JTlRfVVJMOi1odHRwOi8vcGxhbmUtbWluaW86OTAwMH0nCiAgICAgIC0gJ0FXU19TM19CVUNLRVRfTkFNRT0ke0FXU19TM19CVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gTUlOSU9fUk9PVF9VU0VSPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBNSU5JT19ST09UX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0JVQ0tFVF9OQU1FPSR7QlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtICdGSUxFX1NJWkVfTElNSVQ9JHtGSUxFX1NJWkVfTElNSVQ6LTUyNDI4ODB9JwogICAgICAtICdBRE1JTl9CQVNFX1VSTD0ke0FETUlOX0JBU0VfVVJMfScKICAgICAgLSAnU1BBQ0VfQkFTRV9VUkw9JHtTUEFDRV9CQVNFX1VSTH0nCiAgICAgIC0gJ0FQUF9CQVNFX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICBpbWFnZTogJ21ha2VwbGFuZS9wbGFuZS1hZG1pbjpzdGFibGUnCiAgICBjb21tYW5kOiAnbm9kZSBhZG1pbi9zZXJ2ZXIuanMgYWRtaW4nCiAgICBkZXBlbmRzX29uOgogICAgICAtIGFwaQogICAgICAtIHdlYgogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGVjaG8KICAgICAgICAtICdoZXkgd2hhdHMgdXAnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUKICBhcGk6CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnV0VCX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICAgIC0gJ0RFQlVHPSR7REVCVUc6LTB9JwogICAgICAtICdDT1JTX0FMTE9XRURfT1JJR0lOUz0ke0NPUlNfQUxMT1dFRF9PUklHSU46LWh0dHA6Ly9sb2NhbGhvc3R9JwogICAgICAtICdHVU5JQ09STl9XT1JLRVJTPSR7R1VOSUNPUk5fV09SS0VSUzotMX0nCiAgICAgIC0gUEdIT1NUPXBsYW5lLWRiCiAgICAgIC0gUEdEQVRBQkFTRT1wbGFuZQogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfREI9cGxhbmUKICAgICAgLSBQT1NUR1JFU19QT1JUPTU0MzIKICAgICAgLSBQR0RBVEE9L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0BwbGFuZS1kYi9wbGFuZScKICAgICAgLSBSRURJU19IT1NUPXBsYW5lLXJlZGlzCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICAgIC0gJ1JFRElTX1VSTD0ke1JFRElTX1VSTDotcmVkaXM6Ly9wbGFuZS1yZWRpczo2Mzc5L30nCiAgICAgIC0gU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF82NF9TRUNSRVRLRVkKICAgICAgLSAnVVNFX01JTklPPSR7VVNFX01JTklPOi0xfScKICAgICAgLSAnQVdTX1JFR0lPTj0ke0FXU19SRUdJT059JwogICAgICAtIEFXU19BQ0NFU1NfS0VZX0lEPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgICAgLSAnQVdTX1MzX0VORFBPSU5UX1VSTD0ke0FXU19TM19FTkRQT0lOVF9VUkw6LWh0dHA6Ly9wbGFuZS1taW5pbzo5MDAwfScKICAgICAgLSAnQVdTX1MzX0JVQ0tFVF9OQU1FPSR7QVdTX1MzX0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSBNSU5JT19ST09UX1VTRVI9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIE1JTklPX1JPT1RfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgICAgLSAnQlVDS0VUX05BTUU9JHtCVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gJ0ZJTEVfU0laRV9MSU1JVD0ke0ZJTEVfU0laRV9MSU1JVDotNTI0Mjg4MH0nCiAgICAgIC0gJ0FETUlOX0JBU0VfVVJMPSR7QURNSU5fQkFTRV9VUkx9JwogICAgICAtICdTUEFDRV9CQVNFX1VSTD0ke1NQQUNFX0JBU0VfVVJMfScKICAgICAgLSAnQVBQX0JBU0VfVVJMPSR7U0VSVklDRV9GUUROX1BMQU5FfScKICAgIGltYWdlOiAnbWFrZXBsYW5lL3BsYW5lLWJhY2tlbmQ6c3RhYmxlJwogICAgY29tbWFuZDogLi9iaW4vZG9ja2VyLWVudHJ5cG9pbnQtYXBpLnNoCiAgICB2b2x1bWVzOgogICAgICAtICdsb2dzX2FwaTovY29kZS9wbGFuZS9sb2dzJwogICAgZGVwZW5kc19vbjoKICAgICAgLSBwbGFuZS1kYgogICAgICAtIHBsYW5lLXJlZGlzCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gZWNobwogICAgICAgIC0gJ2hleSB3aGF0cyB1cCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogIHdvcmtlcjoKICAgIGVudmlyb25tZW50OgogICAgICAtICdXRUJfVVJMPSR7U0VSVklDRV9GUUROX1BMQU5FfScKICAgICAgLSAnREVCVUc9JHtERUJVRzotMH0nCiAgICAgIC0gJ0NPUlNfQUxMT1dFRF9PUklHSU5TPSR7Q09SU19BTExPV0VEX09SSUdJTjotaHR0cDovL2xvY2FsaG9zdH0nCiAgICAgIC0gJ0dVTklDT1JOX1dPUktFUlM9JHtHVU5JQ09STl9XT1JLRVJTOi0xfScKICAgICAgLSBQR0hPU1Q9cGxhbmUtZGIKICAgICAgLSBQR0RBVEFCQVNFPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfVVNFUj0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19EQj1wbGFuZQogICAgICAtIFBPU1RHUkVTX1BPUlQ9NTQzMgogICAgICAtIFBHREFUQT0vdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzcWw6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBsYW5lLWRiL3BsYW5lJwogICAgICAtIFJFRElTX0hPU1Q9cGxhbmUtcmVkaXMKICAgICAgLSBSRURJU19QT1JUPTYzNzkKICAgICAgLSAnUkVESVNfVVJMPSR7UkVESVNfVVJMOi1yZWRpczovL3BsYW5lLXJlZGlzOjYzNzkvfScKICAgICAgLSBTRUNSRVRfS0VZPSRTRVJWSUNFX1BBU1NXT1JEXzY0X1NFQ1JFVEtFWQogICAgICAtICdVU0VfTUlOSU89JHtVU0VfTUlOSU86LTF9JwogICAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAgIC0gQVdTX0FDQ0VTU19LRVlfSUQ9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIEFXU19TRUNSRVRfQUNDRVNTX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdBV1NfUzNfRU5EUE9JTlRfVVJMPSR7QVdTX1MzX0VORFBPSU5UX1VSTDotaHR0cDovL3BsYW5lLW1pbmlvOjkwMDB9JwogICAgICAtICdBV1NfUzNfQlVDS0VUX05BTUU9JHtBV1NfUzNfQlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdCVUNLRVRfTkFNRT0ke0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSAnRklMRV9TSVpFX0xJTUlUPSR7RklMRV9TSVpFX0xJTUlUOi01MjQyODgwfScKICAgICAgLSAnQURNSU5fQkFTRV9VUkw9JHtBRE1JTl9CQVNFX1VSTH0nCiAgICAgIC0gJ1NQQUNFX0JBU0VfVVJMPSR7U1BBQ0VfQkFTRV9VUkx9JwogICAgICAtICdBUFBfQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgaW1hZ2U6ICdtYWtlcGxhbmUvcGxhbmUtYmFja2VuZDpzdGFibGUnCiAgICBjb21tYW5kOiAuL2Jpbi9kb2NrZXItZW50cnlwb2ludC13b3JrZXIuc2gKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2xvZ3Nfd29ya2VyOi9jb2RlL3BsYW5lL2xvZ3MnCiAgICBkZXBlbmRzX29uOgogICAgICAtIGFwaQogICAgICAtIHBsYW5lLWRiCiAgICAgIC0gcGxhbmUtcmVkaXMKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBlY2hvCiAgICAgICAgLSAnaGV5IHdoYXRzIHVwJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1CiAgYmVhdC13b3JrZXI6CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnV0VCX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICAgIC0gJ0RFQlVHPSR7REVCVUc6LTB9JwogICAgICAtICdDT1JTX0FMTE9XRURfT1JJR0lOUz0ke0NPUlNfQUxMT1dFRF9PUklHSU46LWh0dHA6Ly9sb2NhbGhvc3R9JwogICAgICAtICdHVU5JQ09STl9XT1JLRVJTPSR7R1VOSUNPUk5fV09SS0VSUzotMX0nCiAgICAgIC0gUEdIT1NUPXBsYW5lLWRiCiAgICAgIC0gUEdEQVRBQkFTRT1wbGFuZQogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfREI9cGxhbmUKICAgICAgLSBQT1NUR1JFU19QT1JUPTU0MzIKICAgICAgLSBQR0RBVEE9L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0BwbGFuZS1kYi9wbGFuZScKICAgICAgLSBSRURJU19IT1NUPXBsYW5lLXJlZGlzCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICAgIC0gJ1JFRElTX1VSTD0ke1JFRElTX1VSTDotcmVkaXM6Ly9wbGFuZS1yZWRpczo2Mzc5L30nCiAgICAgIC0gU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF82NF9TRUNSRVRLRVkKICAgICAgLSAnVVNFX01JTklPPSR7VVNFX01JTklPOi0xfScKICAgICAgLSAnQVdTX1JFR0lPTj0ke0FXU19SRUdJT059JwogICAgICAtIEFXU19BQ0NFU1NfS0VZX0lEPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgICAgLSAnQVdTX1MzX0VORFBPSU5UX1VSTD0ke0FXU19TM19FTkRQT0lOVF9VUkw6LWh0dHA6Ly9wbGFuZS1taW5pbzo5MDAwfScKICAgICAgLSAnQVdTX1MzX0JVQ0tFVF9OQU1FPSR7QVdTX1MzX0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSBNSU5JT19ST09UX1VTRVI9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIE1JTklPX1JPT1RfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgICAgLSAnQlVDS0VUX05BTUU9JHtCVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gJ0ZJTEVfU0laRV9MSU1JVD0ke0ZJTEVfU0laRV9MSU1JVDotNTI0Mjg4MH0nCiAgICAgIC0gJ0FETUlOX0JBU0VfVVJMPSR7QURNSU5fQkFTRV9VUkx9JwogICAgICAtICdTUEFDRV9CQVNFX1VSTD0ke1NQQUNFX0JBU0VfVVJMfScKICAgICAgLSAnQVBQX0JBU0VfVVJMPSR7U0VSVklDRV9GUUROX1BMQU5FfScKICAgIGltYWdlOiAnbWFrZXBsYW5lL3BsYW5lLWJhY2tlbmQ6c3RhYmxlJwogICAgY29tbWFuZDogLi9iaW4vZG9ja2VyLWVudHJ5cG9pbnQtYmVhdC5zaAogICAgdm9sdW1lczoKICAgICAgLSAnbG9nc19iZWF0LXdvcmtlcjovY29kZS9wbGFuZS9sb2dzJwogICAgZGVwZW5kc19vbjoKICAgICAgLSBhcGkKICAgICAgLSBwbGFuZS1kYgogICAgICAtIHBsYW5lLXJlZGlzCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gZWNobwogICAgICAgIC0gJ2hleSB3aGF0cyB1cCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogIG1pZ3JhdG9yOgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1dFQl9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgICAgLSAnQ09SU19BTExPV0VEX09SSUdJTlM9JHtDT1JTX0FMTE9XRURfT1JJR0lOOi1odHRwOi8vbG9jYWxob3N0fScKICAgICAgLSAnR1VOSUNPUk5fV09SS0VSUz0ke0dVTklDT1JOX1dPUktFUlM6LTF9JwogICAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgICAtIFBHREFUQUJBU0U9cGxhbmUKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX0RCPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcGxhbmUtZGIvcGxhbmUnCiAgICAgIC0gUkVESVNfSE9TVD1wbGFuZS1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtICdSRURJU19VUkw9JHtSRURJU19VUkw6LXJlZGlzOi8vcGxhbmUtcmVkaXM6NjM3OS99JwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfU0VDUkVUS0VZCiAgICAgIC0gJ1VTRV9NSU5JTz0ke1VTRV9NSU5JTzotMX0nCiAgICAgIC0gJ0FXU19SRUdJT049JHtBV1NfUkVHSU9OfScKICAgICAgLSBBV1NfQUNDRVNTX0tFWV9JRD0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0FXU19TM19FTkRQT0lOVF9VUkw9JHtBV1NfUzNfRU5EUE9JTlRfVVJMOi1odHRwOi8vcGxhbmUtbWluaW86OTAwMH0nCiAgICAgIC0gJ0FXU19TM19CVUNLRVRfTkFNRT0ke0FXU19TM19CVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gTUlOSU9fUk9PVF9VU0VSPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBNSU5JT19ST09UX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0JVQ0tFVF9OQU1FPSR7QlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtICdGSUxFX1NJWkVfTElNSVQ9JHtGSUxFX1NJWkVfTElNSVQ6LTUyNDI4ODB9JwogICAgICAtICdBRE1JTl9CQVNFX1VSTD0ke0FETUlOX0JBU0VfVVJMfScKICAgICAgLSAnU1BBQ0VfQkFTRV9VUkw9JHtTUEFDRV9CQVNFX1VSTH0nCiAgICAgIC0gJ0FQUF9CQVNFX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICBpbWFnZTogJ21ha2VwbGFuZS9wbGFuZS1iYWNrZW5kOnN0YWJsZScKICAgIHJlc3RhcnQ6ICdubycKICAgIGNvbW1hbmQ6IC4vYmluL2RvY2tlci1lbnRyeXBvaW50LW1pZ3JhdG9yLnNoCiAgICB2b2x1bWVzOgogICAgICAtICdsb2dzX21pZ3JhdG9yOi9jb2RlL3BsYW5lL2xvZ3MnCiAgICBkZXBlbmRzX29uOgogICAgICAtIHBsYW5lLWRiCiAgICAgIC0gcGxhbmUtcmVkaXMKICBwbGFuZS1kYjoKICAgIGVudmlyb25tZW50OgogICAgICAtICdXRUJfVVJMPSR7U0VSVklDRV9GUUROX1BMQU5FfScKICAgICAgLSAnREVCVUc9JHtERUJVRzotMH0nCiAgICAgIC0gJ0NPUlNfQUxMT1dFRF9PUklHSU5TPSR7Q09SU19BTExPV0VEX09SSUdJTjotaHR0cDovL2xvY2FsaG9zdH0nCiAgICAgIC0gJ0dVTklDT1JOX1dPUktFUlM9JHtHVU5JQ09STl9XT1JLRVJTOi0xfScKICAgICAgLSBQR0hPU1Q9cGxhbmUtZGIKICAgICAgLSBQR0RBVEFCQVNFPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfVVNFUj0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19EQj1wbGFuZQogICAgICAtIFBPU1RHUkVTX1BPUlQ9NTQzMgogICAgICAtIFBHREFUQT0vdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzcWw6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBsYW5lLWRiL3BsYW5lJwogICAgICAtIFJFRElTX0hPU1Q9cGxhbmUtcmVkaXMKICAgICAgLSBSRURJU19QT1JUPTYzNzkKICAgICAgLSAnUkVESVNfVVJMPSR7UkVESVNfVVJMOi1yZWRpczovL3BsYW5lLXJlZGlzOjYzNzkvfScKICAgICAgLSBTRUNSRVRfS0VZPSRTRVJWSUNFX1BBU1NXT1JEXzY0X1NFQ1JFVEtFWQogICAgICAtICdVU0VfTUlOSU89JHtVU0VfTUlOSU86LTF9JwogICAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAgIC0gQVdTX0FDQ0VTU19LRVlfSUQ9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIEFXU19TRUNSRVRfQUNDRVNTX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdBV1NfUzNfRU5EUE9JTlRfVVJMPSR7QVdTX1MzX0VORFBPSU5UX1VSTDotaHR0cDovL3BsYW5lLW1pbmlvOjkwMDB9JwogICAgICAtICdBV1NfUzNfQlVDS0VUX05BTUU9JHtBV1NfUzNfQlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdCVUNLRVRfTkFNRT0ke0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSAnRklMRV9TSVpFX0xJTUlUPSR7RklMRV9TSVpFX0xJTUlUOi01MjQyODgwfScKICAgICAgLSAnQURNSU5fQkFTRV9VUkw9JHtBRE1JTl9CQVNFX1VSTH0nCiAgICAgIC0gJ1NQQUNFX0JBU0VfVVJMPSR7U1BBQ0VfQkFTRV9VUkx9JwogICAgICAtICdBUFBfQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNS41LWFscGluZScKICAgIGNvbW1hbmQ6ICJwb3N0Z3JlcyAtYyAnbWF4X2Nvbm5lY3Rpb25zPTEwMDAnIgogICAgdm9sdW1lczoKICAgICAgLSAncGdkYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICBwbGFuZS1yZWRpczoKICAgIGVudmlyb25tZW50OgogICAgICAtICdXRUJfVVJMPSR7U0VSVklDRV9GUUROX1BMQU5FfScKICAgICAgLSAnREVCVUc9JHtERUJVRzotMH0nCiAgICAgIC0gJ0NPUlNfQUxMT1dFRF9PUklHSU5TPSR7Q09SU19BTExPV0VEX09SSUdJTjotaHR0cDovL2xvY2FsaG9zdH0nCiAgICAgIC0gJ0dVTklDT1JOX1dPUktFUlM9JHtHVU5JQ09STl9XT1JLRVJTOi0xfScKICAgICAgLSBQR0hPU1Q9cGxhbmUtZGIKICAgICAgLSBQR0RBVEFCQVNFPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfVVNFUj0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19EQj1wbGFuZQogICAgICAtIFBPU1RHUkVTX1BPUlQ9NTQzMgogICAgICAtIFBHREFUQT0vdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzcWw6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBsYW5lLWRiL3BsYW5lJwogICAgICAtIFJFRElTX0hPU1Q9cGxhbmUtcmVkaXMKICAgICAgLSBSRURJU19QT1JUPTYzNzkKICAgICAgLSAnUkVESVNfVVJMPSR7UkVESVNfVVJMOi1yZWRpczovL3BsYW5lLXJlZGlzOjYzNzkvfScKICAgICAgLSBTRUNSRVRfS0VZPSRTRVJWSUNFX1BBU1NXT1JEXzY0X1NFQ1JFVEtFWQogICAgICAtICdVU0VfTUlOSU89JHtVU0VfTUlOSU86LTF9JwogICAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAgIC0gQVdTX0FDQ0VTU19LRVlfSUQ9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIEFXU19TRUNSRVRfQUNDRVNTX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdBV1NfUzNfRU5EUE9JTlRfVVJMPSR7QVdTX1MzX0VORFBPSU5UX1VSTDotaHR0cDovL3BsYW5lLW1pbmlvOjkwMDB9JwogICAgICAtICdBV1NfUzNfQlVDS0VUX05BTUU9JHtBV1NfUzNfQlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdCVUNLRVRfTkFNRT0ke0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSAnRklMRV9TSVpFX0xJTUlUPSR7RklMRV9TSVpFX0xJTUlUOi01MjQyODgwfScKICAgICAgLSAnQURNSU5fQkFTRV9VUkw9JHtBRE1JTl9CQVNFX1VSTH0nCiAgICAgIC0gJ1NQQUNFX0JBU0VfVVJMPSR7U1BBQ0VfQkFTRV9VUkx9JwogICAgICAtICdBUFBfQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgaW1hZ2U6ICd2YWxrZXkvdmFsa2V5OjcuMi41LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHBsYW5lLW1pbmlvOgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1dFQl9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgICAgLSAnQ09SU19BTExPV0VEX09SSUdJTlM9JHtDT1JTX0FMTE9XRURfT1JJR0lOOi1odHRwOi8vbG9jYWxob3N0fScKICAgICAgLSAnR1VOSUNPUk5fV09SS0VSUz0ke0dVTklDT1JOX1dPUktFUlM6LTF9JwogICAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgICAtIFBHREFUQUJBU0U9cGxhbmUKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX0RCPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcGxhbmUtZGIvcGxhbmUnCiAgICAgIC0gUkVESVNfSE9TVD1wbGFuZS1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtICdSRURJU19VUkw9JHtSRURJU19VUkw6LXJlZGlzOi8vcGxhbmUtcmVkaXM6NjM3OS99JwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfU0VDUkVUS0VZCiAgICAgIC0gJ1VTRV9NSU5JTz0ke1VTRV9NSU5JTzotMX0nCiAgICAgIC0gJ0FXU19SRUdJT049JHtBV1NfUkVHSU9OfScKICAgICAgLSBBV1NfQUNDRVNTX0tFWV9JRD0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0FXU19TM19FTkRQT0lOVF9VUkw9JHtBV1NfUzNfRU5EUE9JTlRfVVJMOi1odHRwOi8vcGxhbmUtbWluaW86OTAwMH0nCiAgICAgIC0gJ0FXU19TM19CVUNLRVRfTkFNRT0ke0FXU19TM19CVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gTUlOSU9fUk9PVF9VU0VSPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBNSU5JT19ST09UX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0JVQ0tFVF9OQU1FPSR7QlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtICdGSUxFX1NJWkVfTElNSVQ9JHtGSUxFX1NJWkVfTElNSVQ6LTUyNDI4ODB9JwogICAgICAtICdBRE1JTl9CQVNFX1VSTD0ke0FETUlOX0JBU0VfVVJMfScKICAgICAgLSAnU1BBQ0VfQkFTRV9VUkw9JHtTUEFDRV9CQVNFX1VSTH0nCiAgICAgIC0gJ0FQUF9CQVNFX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICBpbWFnZTogJ21pbmlvL21pbmlvOmxhdGVzdCcKICAgIGNvbW1hbmQ6ICdzZXJ2ZXIgL2V4cG9ydCAtLWNvbnNvbGUtYWRkcmVzcyAiOjkwOTAiJwogICAgdm9sdW1lczoKICAgICAgLSAndXBsb2FkczovZXhwb3J0JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIG1jCiAgICAgICAgLSByZWFkeQogICAgICAgIC0gbG9jYWwKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=", + "compose": "eC1hcHAtZW52OgogIGVudmlyb25tZW50OgogICAgLSAnV0VCX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgIC0gJ0NPUlNfQUxMT1dFRF9PUklHSU5TPSR7Q09SU19BTExPV0VEX09SSUdJTjotaHR0cDovL2xvY2FsaG9zdH0nCiAgICAtICdHVU5JQ09STl9XT1JLRVJTPSR7R1VOSUNPUk5fV09SS0VSUzotMX0nCiAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgLSBQR0RBVEFCQVNFPXBsYW5lCiAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgLSBQT1NUR1JFU19EQj1wbGFuZQogICAgLSBQT1NUR1JFU19QT1JUPTU0MzIKICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzcWw6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBsYW5lLWRiL3BsYW5lJwogICAgLSBSRURJU19IT1NUPXBsYW5lLXJlZGlzCiAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgLSAnUkVESVNfVVJMPSR7UkVESVNfVVJMOi1yZWRpczovL3BsYW5lLXJlZGlzOjYzNzkvfScKICAgIC0gUkFCQklUTVFfSE9TVD1wbGFuZS1tcQogICAgLSAnUkFCQklUTVFfUE9SVD0ke1JBQkJJVE1RX1BPUlQ6LTU2NzJ9JwogICAgLSAnUkFCQklUTVFfREVGQVVMVF9VU0VSPSR7U0VSVklDRV9VU0VSX1JBQkJJVE1ROi1wbGFuZX0nCiAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1BBU1M9JHtTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1ROi1wbGFuZX0nCiAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1ZIT1NUPSR7UkFCQklUTVFfVkhPU1Q6LXBsYW5lfScKICAgIC0gJ1JBQkJJVE1RX1ZIT1NUPSR7UkFCQklUTVFfVkhPU1Q6LXBsYW5lfScKICAgIC0gJ0FNUVBfVVJMPWFtcXA6Ly8ke1NFUlZJQ0VfVVNFUl9SQUJCSVRNUX06JHtTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1RfUBwbGFuZS1tcToke1JBQkJJVE1RX1BPUlR9L3BsYW5lJwogICAgLSBTRUNSRVRfS0VZPSRTRVJWSUNFX1BBU1NXT1JEXzY0X1NFQ1JFVEtFWQogICAgLSAnVVNFX01JTklPPSR7VVNFX01JTklPOi0xfScKICAgIC0gJ0FXU19SRUdJT049JHtBV1NfUkVHSU9OfScKICAgIC0gQVdTX0FDQ0VTU19LRVlfSUQ9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgLSBBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgIC0gJ0FXU19TM19FTkRQT0lOVF9VUkw9JHtBV1NfUzNfRU5EUE9JTlRfVVJMOi1odHRwOi8vcGxhbmUtbWluaW86OTAwMH0nCiAgICAtICdBV1NfUzNfQlVDS0VUX05BTUU9JHtBV1NfUzNfQlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgLSBNSU5JT19ST09UX1VTRVI9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgLSBNSU5JT19ST09UX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAtICdCVUNLRVRfTkFNRT0ke0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgIC0gJ0ZJTEVfU0laRV9MSU1JVD0ke0ZJTEVfU0laRV9MSU1JVDotNTI0Mjg4MH0nCiAgICAtICdBUElfQkFTRV9VUkw9JHtBUElfQkFTRV9VUkw6LWh0dHA6Ly9hcGk6ODAwMH0nCnNlcnZpY2VzOgogIHByb3h5OgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1BMQU5FCiAgICAgIC0gJ0ZJTEVfU0laRV9MSU1JVD0ke0ZJTEVfU0laRV9MSU1JVDotNTI0Mjg4MH0nCiAgICAgIC0gJ0JVQ0tFVF9OQU1FPSR7QlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgaW1hZ2U6ICdtYWtlcGxhbmUvcGxhbmUtcHJveHk6c3RhYmxlJwogICAgZGVwZW5kc19vbjoKICAgICAgLSB3ZWIKICAgICAgLSBhcGkKICAgICAgLSBzcGFjZQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjgwJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1CiAgd2ViOgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1dFQl9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgICAgLSAnQ09SU19BTExPV0VEX09SSUdJTlM9JHtDT1JTX0FMTE9XRURfT1JJR0lOOi1odHRwOi8vbG9jYWxob3N0fScKICAgICAgLSAnR1VOSUNPUk5fV09SS0VSUz0ke0dVTklDT1JOX1dPUktFUlM6LTF9JwogICAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgICAtIFBHREFUQUJBU0U9cGxhbmUKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX0RCPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcGxhbmUtZGIvcGxhbmUnCiAgICAgIC0gUkVESVNfSE9TVD1wbGFuZS1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtICdSRURJU19VUkw9JHtSRURJU19VUkw6LXJlZGlzOi8vcGxhbmUtcmVkaXM6NjM3OS99JwogICAgICAtIFJBQkJJVE1RX0hPU1Q9cGxhbmUtbXEKICAgICAgLSAnUkFCQklUTVFfUE9SVD0ke1JBQkJJVE1RX1BPUlQ6LTU2NzJ9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1VTRVI9JHtTRVJWSUNFX1VTRVJfUkFCQklUTVE6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfREVGQVVMVF9QQVNTPSR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUTotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1ZIT1NUPSR7UkFCQklUTVFfVkhPU1Q6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfVkhPU1Q9JHtSQUJCSVRNUV9WSE9TVDotcGxhbmV9JwogICAgICAtICdBTVFQX1VSTD1hbXFwOi8vJHtTRVJWSUNFX1VTRVJfUkFCQklUTVF9OiR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUX1AcGxhbmUtbXE6JHtSQUJCSVRNUV9QT1JUfS9wbGFuZScKICAgICAgLSBTRUNSRVRfS0VZPSRTRVJWSUNFX1BBU1NXT1JEXzY0X1NFQ1JFVEtFWQogICAgICAtICdVU0VfTUlOSU89JHtVU0VfTUlOSU86LTF9JwogICAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAgIC0gQVdTX0FDQ0VTU19LRVlfSUQ9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIEFXU19TRUNSRVRfQUNDRVNTX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdBV1NfUzNfRU5EUE9JTlRfVVJMPSR7QVdTX1MzX0VORFBPSU5UX1VSTDotaHR0cDovL3BsYW5lLW1pbmlvOjkwMDB9JwogICAgICAtICdBV1NfUzNfQlVDS0VUX05BTUU9JHtBV1NfUzNfQlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdCVUNLRVRfTkFNRT0ke0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSAnRklMRV9TSVpFX0xJTUlUPSR7RklMRV9TSVpFX0xJTUlUOi01MjQyODgwfScKICAgICAgLSAnQVBJX0JBU0VfVVJMPSR7QVBJX0JBU0VfVVJMOi1odHRwOi8vYXBpOjgwMDB9JwogICAgaW1hZ2U6ICdtYWtlcGxhbmUvcGxhbmUtZnJvbnRlbmQ6c3RhYmxlJwogICAgY29tbWFuZDogJ25vZGUgd2ViL3NlcnZlci5qcyB3ZWInCiAgICBkZXBlbmRzX29uOgogICAgICAtIGFwaQogICAgICAtIHdvcmtlcgogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6ICd3Z2V0IC1xTy0gaHR0cDovL2Bob3N0bmFtZWA6MzAwMCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogIHNwYWNlOgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1dFQl9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgICAgLSAnQ09SU19BTExPV0VEX09SSUdJTlM9JHtDT1JTX0FMTE9XRURfT1JJR0lOOi1odHRwOi8vbG9jYWxob3N0fScKICAgICAgLSAnR1VOSUNPUk5fV09SS0VSUz0ke0dVTklDT1JOX1dPUktFUlM6LTF9JwogICAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgICAtIFBHREFUQUJBU0U9cGxhbmUKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX0RCPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcGxhbmUtZGIvcGxhbmUnCiAgICAgIC0gUkVESVNfSE9TVD1wbGFuZS1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtICdSRURJU19VUkw9JHtSRURJU19VUkw6LXJlZGlzOi8vcGxhbmUtcmVkaXM6NjM3OS99JwogICAgICAtIFJBQkJJVE1RX0hPU1Q9cGxhbmUtbXEKICAgICAgLSAnUkFCQklUTVFfUE9SVD0ke1JBQkJJVE1RX1BPUlQ6LTU2NzJ9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1VTRVI9JHtTRVJWSUNFX1VTRVJfUkFCQklUTVE6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfREVGQVVMVF9QQVNTPSR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUTotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1ZIT1NUPSR7UkFCQklUTVFfVkhPU1Q6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfVkhPU1Q9JHtSQUJCSVRNUV9WSE9TVDotcGxhbmV9JwogICAgICAtICdBTVFQX1VSTD1hbXFwOi8vJHtTRVJWSUNFX1VTRVJfUkFCQklUTVF9OiR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUX1AcGxhbmUtbXE6JHtSQUJCSVRNUV9QT1JUfS9wbGFuZScKICAgICAgLSBTRUNSRVRfS0VZPSRTRVJWSUNFX1BBU1NXT1JEXzY0X1NFQ1JFVEtFWQogICAgICAtICdVU0VfTUlOSU89JHtVU0VfTUlOSU86LTF9JwogICAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAgIC0gQVdTX0FDQ0VTU19LRVlfSUQ9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIEFXU19TRUNSRVRfQUNDRVNTX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdBV1NfUzNfRU5EUE9JTlRfVVJMPSR7QVdTX1MzX0VORFBPSU5UX1VSTDotaHR0cDovL3BsYW5lLW1pbmlvOjkwMDB9JwogICAgICAtICdBV1NfUzNfQlVDS0VUX05BTUU9JHtBV1NfUzNfQlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdCVUNLRVRfTkFNRT0ke0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSAnRklMRV9TSVpFX0xJTUlUPSR7RklMRV9TSVpFX0xJTUlUOi01MjQyODgwfScKICAgICAgLSAnQVBJX0JBU0VfVVJMPSR7QVBJX0JBU0VfVVJMOi1odHRwOi8vYXBpOjgwMDB9JwogICAgaW1hZ2U6ICdtYWtlcGxhbmUvcGxhbmUtc3BhY2U6c3RhYmxlJwogICAgY29tbWFuZDogJ25vZGUgc3BhY2Uvc2VydmVyLmpzIHNwYWNlJwogICAgZGVwZW5kc19vbjoKICAgICAgLSBhcGkKICAgICAgLSB3b3JrZXIKICAgICAgLSB3ZWIKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBlY2hvCiAgICAgICAgLSAnaGV5IHdoYXRzIHVwJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1CiAgYWRtaW46CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnV0VCX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICAgIC0gJ0RFQlVHPSR7REVCVUc6LTB9JwogICAgICAtICdDT1JTX0FMTE9XRURfT1JJR0lOUz0ke0NPUlNfQUxMT1dFRF9PUklHSU46LWh0dHA6Ly9sb2NhbGhvc3R9JwogICAgICAtICdHVU5JQ09STl9XT1JLRVJTPSR7R1VOSUNPUk5fV09SS0VSUzotMX0nCiAgICAgIC0gUEdIT1NUPXBsYW5lLWRiCiAgICAgIC0gUEdEQVRBQkFTRT1wbGFuZQogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfREI9cGxhbmUKICAgICAgLSBQT1NUR1JFU19QT1JUPTU0MzIKICAgICAgLSBQR0RBVEE9L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0BwbGFuZS1kYi9wbGFuZScKICAgICAgLSBSRURJU19IT1NUPXBsYW5lLXJlZGlzCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICAgIC0gJ1JFRElTX1VSTD0ke1JFRElTX1VSTDotcmVkaXM6Ly9wbGFuZS1yZWRpczo2Mzc5L30nCiAgICAgIC0gUkFCQklUTVFfSE9TVD1wbGFuZS1tcQogICAgICAtICdSQUJCSVRNUV9QT1JUPSR7UkFCQklUTVFfUE9SVDotNTY3Mn0nCiAgICAgIC0gJ1JBQkJJVE1RX0RFRkFVTFRfVVNFUj0ke1NFUlZJQ0VfVVNFUl9SQUJCSVRNUTotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1BBU1M9JHtTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1ROi1wbGFuZX0nCiAgICAgIC0gJ1JBQkJJVE1RX0RFRkFVTFRfVkhPU1Q9JHtSQUJCSVRNUV9WSE9TVDotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9WSE9TVD0ke1JBQkJJVE1RX1ZIT1NUOi1wbGFuZX0nCiAgICAgIC0gJ0FNUVBfVVJMPWFtcXA6Ly8ke1NFUlZJQ0VfVVNFUl9SQUJCSVRNUX06JHtTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1RfUBwbGFuZS1tcToke1JBQkJJVE1RX1BPUlR9L3BsYW5lJwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfU0VDUkVUS0VZCiAgICAgIC0gJ1VTRV9NSU5JTz0ke1VTRV9NSU5JTzotMX0nCiAgICAgIC0gJ0FXU19SRUdJT049JHtBV1NfUkVHSU9OfScKICAgICAgLSBBV1NfQUNDRVNTX0tFWV9JRD0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0FXU19TM19FTkRQT0lOVF9VUkw9JHtBV1NfUzNfRU5EUE9JTlRfVVJMOi1odHRwOi8vcGxhbmUtbWluaW86OTAwMH0nCiAgICAgIC0gJ0FXU19TM19CVUNLRVRfTkFNRT0ke0FXU19TM19CVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gTUlOSU9fUk9PVF9VU0VSPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBNSU5JT19ST09UX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0JVQ0tFVF9OQU1FPSR7QlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtICdGSUxFX1NJWkVfTElNSVQ9JHtGSUxFX1NJWkVfTElNSVQ6LTUyNDI4ODB9JwogICAgICAtICdBUElfQkFTRV9VUkw9JHtBUElfQkFTRV9VUkw6LWh0dHA6Ly9hcGk6ODAwMH0nCiAgICBpbWFnZTogJ21ha2VwbGFuZS9wbGFuZS1hZG1pbjpzdGFibGUnCiAgICBjb21tYW5kOiAnbm9kZSBhZG1pbi9zZXJ2ZXIuanMgYWRtaW4nCiAgICBkZXBlbmRzX29uOgogICAgICAtIGFwaQogICAgICAtIHdlYgogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGVjaG8KICAgICAgICAtICdoZXkgd2hhdHMgdXAnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUKICBsaXZlOgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1dFQl9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgICAgLSAnQ09SU19BTExPV0VEX09SSUdJTlM9JHtDT1JTX0FMTE9XRURfT1JJR0lOOi1odHRwOi8vbG9jYWxob3N0fScKICAgICAgLSAnR1VOSUNPUk5fV09SS0VSUz0ke0dVTklDT1JOX1dPUktFUlM6LTF9JwogICAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgICAtIFBHREFUQUJBU0U9cGxhbmUKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX0RCPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcGxhbmUtZGIvcGxhbmUnCiAgICAgIC0gUkVESVNfSE9TVD1wbGFuZS1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtICdSRURJU19VUkw9JHtSRURJU19VUkw6LXJlZGlzOi8vcGxhbmUtcmVkaXM6NjM3OS99JwogICAgICAtIFJBQkJJVE1RX0hPU1Q9cGxhbmUtbXEKICAgICAgLSAnUkFCQklUTVFfUE9SVD0ke1JBQkJJVE1RX1BPUlQ6LTU2NzJ9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1VTRVI9JHtTRVJWSUNFX1VTRVJfUkFCQklUTVE6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfREVGQVVMVF9QQVNTPSR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUTotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1ZIT1NUPSR7UkFCQklUTVFfVkhPU1Q6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfVkhPU1Q9JHtSQUJCSVRNUV9WSE9TVDotcGxhbmV9JwogICAgICAtICdBTVFQX1VSTD1hbXFwOi8vJHtTRVJWSUNFX1VTRVJfUkFCQklUTVF9OiR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUX1AcGxhbmUtbXE6JHtSQUJCSVRNUV9QT1JUfS9wbGFuZScKICAgICAgLSBTRUNSRVRfS0VZPSRTRVJWSUNFX1BBU1NXT1JEXzY0X1NFQ1JFVEtFWQogICAgICAtICdVU0VfTUlOSU89JHtVU0VfTUlOSU86LTF9JwogICAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAgIC0gQVdTX0FDQ0VTU19LRVlfSUQ9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIEFXU19TRUNSRVRfQUNDRVNTX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdBV1NfUzNfRU5EUE9JTlRfVVJMPSR7QVdTX1MzX0VORFBPSU5UX1VSTDotaHR0cDovL3BsYW5lLW1pbmlvOjkwMDB9JwogICAgICAtICdBV1NfUzNfQlVDS0VUX05BTUU9JHtBV1NfUzNfQlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdCVUNLRVRfTkFNRT0ke0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSAnRklMRV9TSVpFX0xJTUlUPSR7RklMRV9TSVpFX0xJTUlUOi01MjQyODgwfScKICAgICAgLSAnQVBJX0JBU0VfVVJMPSR7QVBJX0JBU0VfVVJMOi1odHRwOi8vYXBpOjgwMDB9JwogICAgaW1hZ2U6ICdtYWtlcGxhbmUvcGxhbmUtbGl2ZTpzdGFibGUnCiAgICBjb21tYW5kOiAnbm9kZSBsaXZlL2Rpc3Qvc2VydmVyLmpzIGxpdmUnCiAgICBkZXBlbmRzX29uOgogICAgICAtIGFwaQogICAgICAtIHdlYgogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGVjaG8KICAgICAgICAtICdoZXkgd2hhdHMgdXAnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUKICBhcGk6CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnV0VCX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICAgIC0gJ0RFQlVHPSR7REVCVUc6LTB9JwogICAgICAtICdDT1JTX0FMTE9XRURfT1JJR0lOUz0ke0NPUlNfQUxMT1dFRF9PUklHSU46LWh0dHA6Ly9sb2NhbGhvc3R9JwogICAgICAtICdHVU5JQ09STl9XT1JLRVJTPSR7R1VOSUNPUk5fV09SS0VSUzotMX0nCiAgICAgIC0gUEdIT1NUPXBsYW5lLWRiCiAgICAgIC0gUEdEQVRBQkFTRT1wbGFuZQogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfREI9cGxhbmUKICAgICAgLSBQT1NUR1JFU19QT1JUPTU0MzIKICAgICAgLSBQR0RBVEE9L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0BwbGFuZS1kYi9wbGFuZScKICAgICAgLSBSRURJU19IT1NUPXBsYW5lLXJlZGlzCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICAgIC0gJ1JFRElTX1VSTD0ke1JFRElTX1VSTDotcmVkaXM6Ly9wbGFuZS1yZWRpczo2Mzc5L30nCiAgICAgIC0gUkFCQklUTVFfSE9TVD1wbGFuZS1tcQogICAgICAtICdSQUJCSVRNUV9QT1JUPSR7UkFCQklUTVFfUE9SVDotNTY3Mn0nCiAgICAgIC0gJ1JBQkJJVE1RX0RFRkFVTFRfVVNFUj0ke1NFUlZJQ0VfVVNFUl9SQUJCSVRNUTotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1BBU1M9JHtTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1ROi1wbGFuZX0nCiAgICAgIC0gJ1JBQkJJVE1RX0RFRkFVTFRfVkhPU1Q9JHtSQUJCSVRNUV9WSE9TVDotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9WSE9TVD0ke1JBQkJJVE1RX1ZIT1NUOi1wbGFuZX0nCiAgICAgIC0gJ0FNUVBfVVJMPWFtcXA6Ly8ke1NFUlZJQ0VfVVNFUl9SQUJCSVRNUX06JHtTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1RfUBwbGFuZS1tcToke1JBQkJJVE1RX1BPUlR9L3BsYW5lJwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfU0VDUkVUS0VZCiAgICAgIC0gJ1VTRV9NSU5JTz0ke1VTRV9NSU5JTzotMX0nCiAgICAgIC0gJ0FXU19SRUdJT049JHtBV1NfUkVHSU9OfScKICAgICAgLSBBV1NfQUNDRVNTX0tFWV9JRD0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0FXU19TM19FTkRQT0lOVF9VUkw9JHtBV1NfUzNfRU5EUE9JTlRfVVJMOi1odHRwOi8vcGxhbmUtbWluaW86OTAwMH0nCiAgICAgIC0gJ0FXU19TM19CVUNLRVRfTkFNRT0ke0FXU19TM19CVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gTUlOSU9fUk9PVF9VU0VSPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBNSU5JT19ST09UX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0JVQ0tFVF9OQU1FPSR7QlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtICdGSUxFX1NJWkVfTElNSVQ9JHtGSUxFX1NJWkVfTElNSVQ6LTUyNDI4ODB9JwogICAgICAtICdBUElfQkFTRV9VUkw9JHtBUElfQkFTRV9VUkw6LWh0dHA6Ly9hcGk6ODAwMH0nCiAgICBpbWFnZTogJ21ha2VwbGFuZS9wbGFuZS1iYWNrZW5kOnN0YWJsZScKICAgIGNvbW1hbmQ6IC4vYmluL2RvY2tlci1lbnRyeXBvaW50LWFwaS5zaAogICAgdm9sdW1lczoKICAgICAgLSAnbG9nc19hcGk6L2NvZGUvcGxhbmUvbG9ncycKICAgIGRlcGVuZHNfb246CiAgICAgIC0gcGxhbmUtZGIKICAgICAgLSBwbGFuZS1yZWRpcwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGVjaG8KICAgICAgICAtICdoZXkgd2hhdHMgdXAnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUKICB3b3JrZXI6CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnV0VCX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICAgIC0gJ0RFQlVHPSR7REVCVUc6LTB9JwogICAgICAtICdDT1JTX0FMTE9XRURfT1JJR0lOUz0ke0NPUlNfQUxMT1dFRF9PUklHSU46LWh0dHA6Ly9sb2NhbGhvc3R9JwogICAgICAtICdHVU5JQ09STl9XT1JLRVJTPSR7R1VOSUNPUk5fV09SS0VSUzotMX0nCiAgICAgIC0gUEdIT1NUPXBsYW5lLWRiCiAgICAgIC0gUEdEQVRBQkFTRT1wbGFuZQogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfREI9cGxhbmUKICAgICAgLSBQT1NUR1JFU19QT1JUPTU0MzIKICAgICAgLSBQR0RBVEE9L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0BwbGFuZS1kYi9wbGFuZScKICAgICAgLSBSRURJU19IT1NUPXBsYW5lLXJlZGlzCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICAgIC0gJ1JFRElTX1VSTD0ke1JFRElTX1VSTDotcmVkaXM6Ly9wbGFuZS1yZWRpczo2Mzc5L30nCiAgICAgIC0gUkFCQklUTVFfSE9TVD1wbGFuZS1tcQogICAgICAtICdSQUJCSVRNUV9QT1JUPSR7UkFCQklUTVFfUE9SVDotNTY3Mn0nCiAgICAgIC0gJ1JBQkJJVE1RX0RFRkFVTFRfVVNFUj0ke1NFUlZJQ0VfVVNFUl9SQUJCSVRNUTotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1BBU1M9JHtTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1ROi1wbGFuZX0nCiAgICAgIC0gJ1JBQkJJVE1RX0RFRkFVTFRfVkhPU1Q9JHtSQUJCSVRNUV9WSE9TVDotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9WSE9TVD0ke1JBQkJJVE1RX1ZIT1NUOi1wbGFuZX0nCiAgICAgIC0gJ0FNUVBfVVJMPWFtcXA6Ly8ke1NFUlZJQ0VfVVNFUl9SQUJCSVRNUX06JHtTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1RfUBwbGFuZS1tcToke1JBQkJJVE1RX1BPUlR9L3BsYW5lJwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfU0VDUkVUS0VZCiAgICAgIC0gJ1VTRV9NSU5JTz0ke1VTRV9NSU5JTzotMX0nCiAgICAgIC0gJ0FXU19SRUdJT049JHtBV1NfUkVHSU9OfScKICAgICAgLSBBV1NfQUNDRVNTX0tFWV9JRD0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0FXU19TM19FTkRQT0lOVF9VUkw9JHtBV1NfUzNfRU5EUE9JTlRfVVJMOi1odHRwOi8vcGxhbmUtbWluaW86OTAwMH0nCiAgICAgIC0gJ0FXU19TM19CVUNLRVRfTkFNRT0ke0FXU19TM19CVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gTUlOSU9fUk9PVF9VU0VSPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBNSU5JT19ST09UX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0JVQ0tFVF9OQU1FPSR7QlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtICdGSUxFX1NJWkVfTElNSVQ9JHtGSUxFX1NJWkVfTElNSVQ6LTUyNDI4ODB9JwogICAgICAtICdBUElfQkFTRV9VUkw9JHtBUElfQkFTRV9VUkw6LWh0dHA6Ly9hcGk6ODAwMH0nCiAgICBpbWFnZTogJ21ha2VwbGFuZS9wbGFuZS1iYWNrZW5kOnN0YWJsZScKICAgIGNvbW1hbmQ6IC4vYmluL2RvY2tlci1lbnRyeXBvaW50LXdvcmtlci5zaAogICAgdm9sdW1lczoKICAgICAgLSAnbG9nc193b3JrZXI6L2NvZGUvcGxhbmUvbG9ncycKICAgIGRlcGVuZHNfb246CiAgICAgIC0gYXBpCiAgICAgIC0gcGxhbmUtZGIKICAgICAgLSBwbGFuZS1yZWRpcwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGVjaG8KICAgICAgICAtICdoZXkgd2hhdHMgdXAnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUKICBiZWF0LXdvcmtlcjoKICAgIGVudmlyb25tZW50OgogICAgICAtICdXRUJfVVJMPSR7U0VSVklDRV9GUUROX1BMQU5FfScKICAgICAgLSAnREVCVUc9JHtERUJVRzotMH0nCiAgICAgIC0gJ0NPUlNfQUxMT1dFRF9PUklHSU5TPSR7Q09SU19BTExPV0VEX09SSUdJTjotaHR0cDovL2xvY2FsaG9zdH0nCiAgICAgIC0gJ0dVTklDT1JOX1dPUktFUlM9JHtHVU5JQ09STl9XT1JLRVJTOi0xfScKICAgICAgLSBQR0hPU1Q9cGxhbmUtZGIKICAgICAgLSBQR0RBVEFCQVNFPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfVVNFUj0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19EQj1wbGFuZQogICAgICAtIFBPU1RHUkVTX1BPUlQ9NTQzMgogICAgICAtIFBHREFUQT0vdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzcWw6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBsYW5lLWRiL3BsYW5lJwogICAgICAtIFJFRElTX0hPU1Q9cGxhbmUtcmVkaXMKICAgICAgLSBSRURJU19QT1JUPTYzNzkKICAgICAgLSAnUkVESVNfVVJMPSR7UkVESVNfVVJMOi1yZWRpczovL3BsYW5lLXJlZGlzOjYzNzkvfScKICAgICAgLSBSQUJCSVRNUV9IT1NUPXBsYW5lLW1xCiAgICAgIC0gJ1JBQkJJVE1RX1BPUlQ9JHtSQUJCSVRNUV9QT1JUOi01NjcyfScKICAgICAgLSAnUkFCQklUTVFfREVGQVVMVF9VU0VSPSR7U0VSVklDRV9VU0VSX1JBQkJJVE1ROi1wbGFuZX0nCiAgICAgIC0gJ1JBQkJJVE1RX0RFRkFVTFRfUEFTUz0ke1NFUlZJQ0VfUEFTU1dPUkRfUkFCQklUTVE6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfREVGQVVMVF9WSE9TVD0ke1JBQkJJVE1RX1ZIT1NUOi1wbGFuZX0nCiAgICAgIC0gJ1JBQkJJVE1RX1ZIT1NUPSR7UkFCQklUTVFfVkhPU1Q6LXBsYW5lfScKICAgICAgLSAnQU1RUF9VUkw9YW1xcDovLyR7U0VSVklDRV9VU0VSX1JBQkJJVE1RfToke1NFUlZJQ0VfUEFTU1dPUkRfUkFCQklUTVF9QHBsYW5lLW1xOiR7UkFCQklUTVFfUE9SVH0vcGxhbmUnCiAgICAgIC0gU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF82NF9TRUNSRVRLRVkKICAgICAgLSAnVVNFX01JTklPPSR7VVNFX01JTklPOi0xfScKICAgICAgLSAnQVdTX1JFR0lPTj0ke0FXU19SRUdJT059JwogICAgICAtIEFXU19BQ0NFU1NfS0VZX0lEPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgICAgLSAnQVdTX1MzX0VORFBPSU5UX1VSTD0ke0FXU19TM19FTkRQT0lOVF9VUkw6LWh0dHA6Ly9wbGFuZS1taW5pbzo5MDAwfScKICAgICAgLSAnQVdTX1MzX0JVQ0tFVF9OQU1FPSR7QVdTX1MzX0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSBNSU5JT19ST09UX1VTRVI9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIE1JTklPX1JPT1RfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgICAgLSAnQlVDS0VUX05BTUU9JHtCVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gJ0ZJTEVfU0laRV9MSU1JVD0ke0ZJTEVfU0laRV9MSU1JVDotNTI0Mjg4MH0nCiAgICAgIC0gJ0FQSV9CQVNFX1VSTD0ke0FQSV9CQVNFX1VSTDotaHR0cDovL2FwaTo4MDAwfScKICAgIGltYWdlOiAnbWFrZXBsYW5lL3BsYW5lLWJhY2tlbmQ6c3RhYmxlJwogICAgY29tbWFuZDogLi9iaW4vZG9ja2VyLWVudHJ5cG9pbnQtYmVhdC5zaAogICAgdm9sdW1lczoKICAgICAgLSAnbG9nc19iZWF0LXdvcmtlcjovY29kZS9wbGFuZS9sb2dzJwogICAgZGVwZW5kc19vbjoKICAgICAgLSBhcGkKICAgICAgLSBwbGFuZS1kYgogICAgICAtIHBsYW5lLXJlZGlzCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gZWNobwogICAgICAgIC0gJ2hleSB3aGF0cyB1cCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogIG1pZ3JhdG9yOgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1dFQl9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgICAgLSAnQ09SU19BTExPV0VEX09SSUdJTlM9JHtDT1JTX0FMTE9XRURfT1JJR0lOOi1odHRwOi8vbG9jYWxob3N0fScKICAgICAgLSAnR1VOSUNPUk5fV09SS0VSUz0ke0dVTklDT1JOX1dPUktFUlM6LTF9JwogICAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgICAtIFBHREFUQUJBU0U9cGxhbmUKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX0RCPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcGxhbmUtZGIvcGxhbmUnCiAgICAgIC0gUkVESVNfSE9TVD1wbGFuZS1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtICdSRURJU19VUkw9JHtSRURJU19VUkw6LXJlZGlzOi8vcGxhbmUtcmVkaXM6NjM3OS99JwogICAgICAtIFJBQkJJVE1RX0hPU1Q9cGxhbmUtbXEKICAgICAgLSAnUkFCQklUTVFfUE9SVD0ke1JBQkJJVE1RX1BPUlQ6LTU2NzJ9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1VTRVI9JHtTRVJWSUNFX1VTRVJfUkFCQklUTVE6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfREVGQVVMVF9QQVNTPSR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUTotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1ZIT1NUPSR7UkFCQklUTVFfVkhPU1Q6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfVkhPU1Q9JHtSQUJCSVRNUV9WSE9TVDotcGxhbmV9JwogICAgICAtICdBTVFQX1VSTD1hbXFwOi8vJHtTRVJWSUNFX1VTRVJfUkFCQklUTVF9OiR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUX1AcGxhbmUtbXE6JHtSQUJCSVRNUV9QT1JUfS9wbGFuZScKICAgICAgLSBTRUNSRVRfS0VZPSRTRVJWSUNFX1BBU1NXT1JEXzY0X1NFQ1JFVEtFWQogICAgICAtICdVU0VfTUlOSU89JHtVU0VfTUlOSU86LTF9JwogICAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAgIC0gQVdTX0FDQ0VTU19LRVlfSUQ9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIEFXU19TRUNSRVRfQUNDRVNTX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdBV1NfUzNfRU5EUE9JTlRfVVJMPSR7QVdTX1MzX0VORFBPSU5UX1VSTDotaHR0cDovL3BsYW5lLW1pbmlvOjkwMDB9JwogICAgICAtICdBV1NfUzNfQlVDS0VUX05BTUU9JHtBV1NfUzNfQlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdCVUNLRVRfTkFNRT0ke0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSAnRklMRV9TSVpFX0xJTUlUPSR7RklMRV9TSVpFX0xJTUlUOi01MjQyODgwfScKICAgICAgLSAnQVBJX0JBU0VfVVJMPSR7QVBJX0JBU0VfVVJMOi1odHRwOi8vYXBpOjgwMDB9JwogICAgaW1hZ2U6ICdtYWtlcGxhbmUvcGxhbmUtYmFja2VuZDpzdGFibGUnCiAgICByZXN0YXJ0OiAnbm8nCiAgICBjb21tYW5kOiAuL2Jpbi9kb2NrZXItZW50cnlwb2ludC1taWdyYXRvci5zaAogICAgdm9sdW1lczoKICAgICAgLSAnbG9nc19taWdyYXRvcjovY29kZS9wbGFuZS9sb2dzJwogICAgZGVwZW5kc19vbjoKICAgICAgLSBwbGFuZS1kYgogICAgICAtIHBsYW5lLXJlZGlzCiAgcGxhbmUtZGI6CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnV0VCX1VSTD0ke1NFUlZJQ0VfRlFETl9QTEFORX0nCiAgICAgIC0gJ0RFQlVHPSR7REVCVUc6LTB9JwogICAgICAtICdDT1JTX0FMTE9XRURfT1JJR0lOUz0ke0NPUlNfQUxMT1dFRF9PUklHSU46LWh0dHA6Ly9sb2NhbGhvc3R9JwogICAgICAtICdHVU5JQ09STl9XT1JLRVJTPSR7R1VOSUNPUk5fV09SS0VSUzotMX0nCiAgICAgIC0gUEdIT1NUPXBsYW5lLWRiCiAgICAgIC0gUEdEQVRBQkFTRT1wbGFuZQogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfREI9cGxhbmUKICAgICAgLSBQT1NUR1JFU19QT1JUPTU0MzIKICAgICAgLSBQR0RBVEE9L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0BwbGFuZS1kYi9wbGFuZScKICAgICAgLSBSRURJU19IT1NUPXBsYW5lLXJlZGlzCiAgICAgIC0gUkVESVNfUE9SVD02Mzc5CiAgICAgIC0gJ1JFRElTX1VSTD0ke1JFRElTX1VSTDotcmVkaXM6Ly9wbGFuZS1yZWRpczo2Mzc5L30nCiAgICAgIC0gUkFCQklUTVFfSE9TVD1wbGFuZS1tcQogICAgICAtICdSQUJCSVRNUV9QT1JUPSR7UkFCQklUTVFfUE9SVDotNTY3Mn0nCiAgICAgIC0gJ1JBQkJJVE1RX0RFRkFVTFRfVVNFUj0ke1NFUlZJQ0VfVVNFUl9SQUJCSVRNUTotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1BBU1M9JHtTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1ROi1wbGFuZX0nCiAgICAgIC0gJ1JBQkJJVE1RX0RFRkFVTFRfVkhPU1Q9JHtSQUJCSVRNUV9WSE9TVDotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9WSE9TVD0ke1JBQkJJVE1RX1ZIT1NUOi1wbGFuZX0nCiAgICAgIC0gJ0FNUVBfVVJMPWFtcXA6Ly8ke1NFUlZJQ0VfVVNFUl9SQUJCSVRNUX06JHtTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1RfUBwbGFuZS1tcToke1JBQkJJVE1RX1BPUlR9L3BsYW5lJwogICAgICAtIFNFQ1JFVF9LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfNjRfU0VDUkVUS0VZCiAgICAgIC0gJ1VTRV9NSU5JTz0ke1VTRV9NSU5JTzotMX0nCiAgICAgIC0gJ0FXU19SRUdJT049JHtBV1NfUkVHSU9OfScKICAgICAgLSBBV1NfQUNDRVNTX0tFWV9JRD0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0FXU19TM19FTkRQT0lOVF9VUkw9JHtBV1NfUzNfRU5EUE9JTlRfVVJMOi1odHRwOi8vcGxhbmUtbWluaW86OTAwMH0nCiAgICAgIC0gJ0FXU19TM19CVUNLRVRfTkFNRT0ke0FXU19TM19CVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gTUlOSU9fUk9PVF9VU0VSPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBNSU5JT19ST09UX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01JTklPCiAgICAgIC0gJ0JVQ0tFVF9OQU1FPSR7QlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtICdGSUxFX1NJWkVfTElNSVQ9JHtGSUxFX1NJWkVfTElNSVQ6LTUyNDI4ODB9JwogICAgICAtICdBUElfQkFTRV9VUkw9JHtBUElfQkFTRV9VUkw6LWh0dHA6Ly9hcGk6ODAwMH0nCiAgICBpbWFnZTogJ3Bvc3RncmVzOjE1LjctYWxwaW5lJwogICAgY29tbWFuZDogInBvc3RncmVzIC1jICdtYXhfY29ubmVjdGlvbnM9MTAwMCciCiAgICB2b2x1bWVzOgogICAgICAtICdwZ2RhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHBsYW5lLXJlZGlzOgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1dFQl9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgICAgLSAnQ09SU19BTExPV0VEX09SSUdJTlM9JHtDT1JTX0FMTE9XRURfT1JJR0lOOi1odHRwOi8vbG9jYWxob3N0fScKICAgICAgLSAnR1VOSUNPUk5fV09SS0VSUz0ke0dVTklDT1JOX1dPUktFUlM6LTF9JwogICAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgICAtIFBHREFUQUJBU0U9cGxhbmUKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX0RCPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcGxhbmUtZGIvcGxhbmUnCiAgICAgIC0gUkVESVNfSE9TVD1wbGFuZS1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtICdSRURJU19VUkw9JHtSRURJU19VUkw6LXJlZGlzOi8vcGxhbmUtcmVkaXM6NjM3OS99JwogICAgICAtIFJBQkJJVE1RX0hPU1Q9cGxhbmUtbXEKICAgICAgLSAnUkFCQklUTVFfUE9SVD0ke1JBQkJJVE1RX1BPUlQ6LTU2NzJ9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1VTRVI9JHtTRVJWSUNFX1VTRVJfUkFCQklUTVE6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfREVGQVVMVF9QQVNTPSR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUTotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1ZIT1NUPSR7UkFCQklUTVFfVkhPU1Q6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfVkhPU1Q9JHtSQUJCSVRNUV9WSE9TVDotcGxhbmV9JwogICAgICAtICdBTVFQX1VSTD1hbXFwOi8vJHtTRVJWSUNFX1VTRVJfUkFCQklUTVF9OiR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUX1AcGxhbmUtbXE6JHtSQUJCSVRNUV9QT1JUfS9wbGFuZScKICAgICAgLSBTRUNSRVRfS0VZPSRTRVJWSUNFX1BBU1NXT1JEXzY0X1NFQ1JFVEtFWQogICAgICAtICdVU0VfTUlOSU89JHtVU0VfTUlOSU86LTF9JwogICAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAgIC0gQVdTX0FDQ0VTU19LRVlfSUQ9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIEFXU19TRUNSRVRfQUNDRVNTX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdBV1NfUzNfRU5EUE9JTlRfVVJMPSR7QVdTX1MzX0VORFBPSU5UX1VSTDotaHR0cDovL3BsYW5lLW1pbmlvOjkwMDB9JwogICAgICAtICdBV1NfUzNfQlVDS0VUX05BTUU9JHtBV1NfUzNfQlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdCVUNLRVRfTkFNRT0ke0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSAnRklMRV9TSVpFX0xJTUlUPSR7RklMRV9TSVpFX0xJTUlUOi01MjQyODgwfScKICAgICAgLSAnQVBJX0JBU0VfVVJMPSR7QVBJX0JBU0VfVVJMOi1odHRwOi8vYXBpOjgwMDB9JwogICAgaW1hZ2U6ICd2YWxrZXkvdmFsa2V5OjcuMi41LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHBsYW5lLW1xOgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1dFQl9VUkw9JHtTRVJWSUNFX0ZRRE5fUExBTkV9JwogICAgICAtICdERUJVRz0ke0RFQlVHOi0wfScKICAgICAgLSAnQ09SU19BTExPV0VEX09SSUdJTlM9JHtDT1JTX0FMTE9XRURfT1JJR0lOOi1odHRwOi8vbG9jYWxob3N0fScKICAgICAgLSAnR1VOSUNPUk5fV09SS0VSUz0ke0dVTklDT1JOX1dPUktFUlM6LTF9JwogICAgICAtIFBHSE9TVD1wbGFuZS1kYgogICAgICAtIFBHREFUQUJBU0U9cGxhbmUKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX0RCPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfUE9SVD01NDMyCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YQogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcGxhbmUtZGIvcGxhbmUnCiAgICAgIC0gUkVESVNfSE9TVD1wbGFuZS1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtICdSRURJU19VUkw9JHtSRURJU19VUkw6LXJlZGlzOi8vcGxhbmUtcmVkaXM6NjM3OS99JwogICAgICAtIFJBQkJJVE1RX0hPU1Q9cGxhbmUtbXEKICAgICAgLSAnUkFCQklUTVFfUE9SVD0ke1JBQkJJVE1RX1BPUlQ6LTU2NzJ9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1VTRVI9JHtTRVJWSUNFX1VTRVJfUkFCQklUTVE6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfREVGQVVMVF9QQVNTPSR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUTotcGxhbmV9JwogICAgICAtICdSQUJCSVRNUV9ERUZBVUxUX1ZIT1NUPSR7UkFCQklUTVFfVkhPU1Q6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfVkhPU1Q9JHtSQUJCSVRNUV9WSE9TVDotcGxhbmV9JwogICAgICAtICdBTVFQX1VSTD1hbXFwOi8vJHtTRVJWSUNFX1VTRVJfUkFCQklUTVF9OiR7U0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUX1AcGxhbmUtbXE6JHtSQUJCSVRNUV9QT1JUfS9wbGFuZScKICAgICAgLSBTRUNSRVRfS0VZPSRTRVJWSUNFX1BBU1NXT1JEXzY0X1NFQ1JFVEtFWQogICAgICAtICdVU0VfTUlOSU89JHtVU0VfTUlOSU86LTF9JwogICAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAgIC0gQVdTX0FDQ0VTU19LRVlfSUQ9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIEFXU19TRUNSRVRfQUNDRVNTX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdBV1NfUzNfRU5EUE9JTlRfVVJMPSR7QVdTX1MzX0VORFBPSU5UX1VSTDotaHR0cDovL3BsYW5lLW1pbmlvOjkwMDB9JwogICAgICAtICdBV1NfUzNfQlVDS0VUX05BTUU9JHtBV1NfUzNfQlVDS0VUX05BTUU6LXVwbG9hZHN9JwogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdCVUNLRVRfTkFNRT0ke0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSAnRklMRV9TSVpFX0xJTUlUPSR7RklMRV9TSVpFX0xJTUlUOi01MjQyODgwfScKICAgICAgLSAnQVBJX0JBU0VfVVJMPSR7QVBJX0JBU0VfVVJMOi1odHRwOi8vYXBpOjgwMDB9JwogICAgaW1hZ2U6ICdyYWJiaXRtcTozLjEzLjYtbWFuYWdlbWVudC1hbHBpbmUnCiAgICByZXN0YXJ0OiBhbHdheXMKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JhYmJpdG1xX2RhdGE6L3Zhci9saWIvcmFiYml0bXEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDogJ3JhYmJpdG1xLWRpYWdub3N0aWNzIC1xIHBpbmcnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMzBzCiAgICAgIHJldHJpZXM6IDMKICBwbGFuZS1taW5pbzoKICAgIGVudmlyb25tZW50OgogICAgICAtICdXRUJfVVJMPSR7U0VSVklDRV9GUUROX1BMQU5FfScKICAgICAgLSAnREVCVUc9JHtERUJVRzotMH0nCiAgICAgIC0gJ0NPUlNfQUxMT1dFRF9PUklHSU5TPSR7Q09SU19BTExPV0VEX09SSUdJTjotaHR0cDovL2xvY2FsaG9zdH0nCiAgICAgIC0gJ0dVTklDT1JOX1dPUktFUlM9JHtHVU5JQ09STl9XT1JLRVJTOi0xfScKICAgICAgLSBQR0hPU1Q9cGxhbmUtZGIKICAgICAgLSBQR0RBVEFCQVNFPXBsYW5lCiAgICAgIC0gUE9TVEdSRVNfVVNFUj0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19EQj1wbGFuZQogICAgICAtIFBPU1RHUkVTX1BPUlQ9NTQzMgogICAgICAtIFBHREFUQT0vdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzcWw6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBsYW5lLWRiL3BsYW5lJwogICAgICAtIFJFRElTX0hPU1Q9cGxhbmUtcmVkaXMKICAgICAgLSBSRURJU19QT1JUPTYzNzkKICAgICAgLSAnUkVESVNfVVJMPSR7UkVESVNfVVJMOi1yZWRpczovL3BsYW5lLXJlZGlzOjYzNzkvfScKICAgICAgLSBSQUJCSVRNUV9IT1NUPXBsYW5lLW1xCiAgICAgIC0gJ1JBQkJJVE1RX1BPUlQ9JHtSQUJCSVRNUV9QT1JUOi01NjcyfScKICAgICAgLSAnUkFCQklUTVFfREVGQVVMVF9VU0VSPSR7U0VSVklDRV9VU0VSX1JBQkJJVE1ROi1wbGFuZX0nCiAgICAgIC0gJ1JBQkJJVE1RX0RFRkFVTFRfUEFTUz0ke1NFUlZJQ0VfUEFTU1dPUkRfUkFCQklUTVE6LXBsYW5lfScKICAgICAgLSAnUkFCQklUTVFfREVGQVVMVF9WSE9TVD0ke1JBQkJJVE1RX1ZIT1NUOi1wbGFuZX0nCiAgICAgIC0gJ1JBQkJJVE1RX1ZIT1NUPSR7UkFCQklUTVFfVkhPU1Q6LXBsYW5lfScKICAgICAgLSAnQU1RUF9VUkw9YW1xcDovLyR7U0VSVklDRV9VU0VSX1JBQkJJVE1RfToke1NFUlZJQ0VfUEFTU1dPUkRfUkFCQklUTVF9QHBsYW5lLW1xOiR7UkFCQklUTVFfUE9SVH0vcGxhbmUnCiAgICAgIC0gU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF82NF9TRUNSRVRLRVkKICAgICAgLSAnVVNFX01JTklPPSR7VVNFX01JTklPOi0xfScKICAgICAgLSAnQVdTX1JFR0lPTj0ke0FXU19SRUdJT059JwogICAgICAtIEFXU19BQ0NFU1NfS0VZX0lEPSRTRVJWSUNFX1VTRVJfTUlOSU8KICAgICAgLSBBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgICAgLSAnQVdTX1MzX0VORFBPSU5UX1VSTD0ke0FXU19TM19FTkRQT0lOVF9VUkw6LWh0dHA6Ly9wbGFuZS1taW5pbzo5MDAwfScKICAgICAgLSAnQVdTX1MzX0JVQ0tFVF9OQU1FPSR7QVdTX1MzX0JVQ0tFVF9OQU1FOi11cGxvYWRzfScKICAgICAgLSBNSU5JT19ST09UX1VTRVI9JFNFUlZJQ0VfVVNFUl9NSU5JTwogICAgICAtIE1JTklPX1JPT1RfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfTUlOSU8KICAgICAgLSAnQlVDS0VUX05BTUU9JHtCVUNLRVRfTkFNRTotdXBsb2Fkc30nCiAgICAgIC0gJ0ZJTEVfU0laRV9MSU1JVD0ke0ZJTEVfU0laRV9MSU1JVDotNTI0Mjg4MH0nCiAgICAgIC0gJ0FQSV9CQVNFX1VSTD0ke0FQSV9CQVNFX1VSTDotaHR0cDovL2FwaTo4MDAwfScKICAgIGltYWdlOiAnbWluaW8vbWluaW86bGF0ZXN0JwogICAgY29tbWFuZDogJ3NlcnZlciAvZXhwb3J0IC0tY29uc29sZS1hZGRyZXNzICI6OTA5MCInCiAgICB2b2x1bWVzOgogICAgICAtICd1cGxvYWRzOi9leHBvcnQnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbWMKICAgICAgICAtIHJlYWR5CiAgICAgICAgLSBsb2NhbAogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCg==", "tags": [ "plane", "project-management", @@ -1672,7 +2005,7 @@ "plunk": { "documentation": "https://docs.useplunk.com/getting-started/introduction?utm_source=coolify.io", "slogan": "Plunk, The Open-Source Email Platform for AWS", - "compose": "dmVyc2lvbjogJzMnCnNlcnZpY2VzOgogIHBsdW5rOgogICAgaW1hZ2U6IGRyaWF1Zy9wbHVuawogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXNxbDoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2Vfc3RhcnRlZAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1BMVU5LXzMwMDAKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vcmVkaXM6NjM3OScKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzcWw6Ly8ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU306JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUBwb3N0Z3Jlc3FsL3BsdW5rP3NjaGVtYT1wdWJsaWMnCiAgICAgIC0gJ0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVF9TRUNSRVR9JwogICAgICAtICdBV1NfUkVHSU9OPSR7QVdTX1JFR0lPTn0nCiAgICAgIC0gJ0FXU19BQ0NFU1NfS0VZX0lEPSR7QVdTX0FDQ0VTU19LRVlfSUR9JwogICAgICAtICdBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JHtBV1NfU0VDUkVUX0FDQ0VTU19LRVl9JwogICAgICAtICdBV1NfU0VTX0NPTkZJR1VSQVRJT05fU0VUPSR7QVdTX1NFU19DT05GSUdVUkFUSU9OX1NFVH0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQSV9VUkk9JHtTRVJWSUNFX0ZRRE5fUExVTkt9L2FwaScKICAgICAgLSAnQVBQX1VSST0ke1NFUlZJQ0VfRlFETl9QTFVOS30nCiAgICAgIC0gJ0FQSV9VUkk9JHtTRVJWSUNFX0ZRRE5fUExVTkt9L2FwaScKICAgICAgLSBESVNBQkxFX1NJR05VUFM9RmFsc2UKICAgIGVudHJ5cG9pbnQ6CiAgICAgIC0gL2FwcC9lbnRyeS5zaAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctcScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjMwMDAnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wbHVua30nCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VIHBvc3RncmVzIC1kIHBvc3RncmVzJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDIwCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOjcuNC1hbHBpbmUnCiAgICB2b2x1bWVzOgogICAgICAtICdyZWRpcy1kYXRhOi9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gUElORwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDIwCg==", + "compose": "c2VydmljZXM6CiAgcGx1bms6CiAgICBpbWFnZTogJ2RyaWF1Zy9wbHVuazpsYXRlc3QnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9zdGFydGVkCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fUExVTktfMzAwMAogICAgICAtICdSRURJU19VUkw9cmVkaXM6Ly9yZWRpczo2Mzc5JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QHBvc3RncmVzcWwvcGx1bmstZGI/c2NoZW1hPXB1YmxpYycKICAgICAgLSAnSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUU0VDUkVUfScKICAgICAgLSAnQVdTX1JFR0lPTj0ke0FXU19SRUdJT059JwogICAgICAtICdBV1NfQUNDRVNTX0tFWV9JRD0ke0FXU19BQ0NFU1NfS0VZX0lEfScKICAgICAgLSAnQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSR7QVdTX1NFQ1JFVF9BQ0NFU1NfS0VZfScKICAgICAgLSAnQVdTX1NFU19DT05GSUdVUkFUSU9OX1NFVD0ke0FXU19TRVNfQ09ORklHVVJBVElPTl9TRVR9JwogICAgICAtICdORVhUX1BVQkxJQ19BUElfVVJJPSR7U0VSVklDRV9GUUROX1BMVU5LfS9hcGknCiAgICAgIC0gJ0FQUF9VUkk9JHtTRVJWSUNFX0ZRRE5fUExVTkt9JwogICAgICAtICdBUElfVVJJPSR7U0VSVklDRV9GUUROX1BMVU5LfS9hcGknCiAgICAgIC0gJ0RJU0FCTEVfU0lHTlVQUz0ke0RJU0FCTEVfU0lHTlVQUzotRmFsc2V9JwogICAgZW50cnlwb2ludDoKICAgICAgLSAvYXBwL2VudHJ5LnNoCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy1xJwogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogIHBvc3RncmVzcWw6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotcGx1bmstZGJ9JwogICAgdm9sdW1lczoKICAgICAgLSAncGx1bmstcG9zdGdyZXNxbC1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICByZWRpczoKICAgIGltYWdlOiAncmVkaXM6Ny40LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3BsdW5rLXJlZGlzLWRhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSBQSU5HCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMjAK", "tags": [ "plunk", "email", @@ -1731,6 +2064,19 @@ "minversion": "0.0.0", "port": "4200" }, + "qbittorrent": { + "documentation": "https://docs.linuxserver.io/images/docker-qbittorrent/?utm_source=coolify.io", + "slogan": "The qBittorrent project aims to provide an open-source software alternative to \u03bcTorrent.", + "compose": "c2VydmljZXM6CiAgcWJpdDoKICAgIGltYWdlOiAnbHNjci5pby9saW51eHNlcnZlci9xYml0dG9ycmVudDpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnV0VCVUlfUE9SVD0ke1dFQlVJX1BPUlQ6LTgwODB9JwogICAgICAtIFBVSUQ9MTAwMAogICAgICAtIFBHSUQ9MTAwMAogICAgdm9sdW1lczoKICAgICAgLSAncWJpdHRvcnJlbnQtY29uZmlnOi9jb25maWcnCiAgICAgIC0gJ3FiaXR0b3JyZW50LWRvd25sb2FkczovZG93bmxvYWRzJwogICAgICAtICdxYml0dG9ycmVudC10b3JyZW50czovdG9ycmVudHMnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy1xJwogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6ODA4MC8nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICB2dWV0b3JyZW50LWJhY2tlbmQ6CiAgICBpbWFnZTogJ2doY3IuaW8vdnVldG9ycmVudC92dWV0b3JyZW50LWJhY2tlbmQ6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1FCSVRPUlJFTlRfODA4MAogICAgICAtICdQT1JUPSR7V0VCVUlfUE9SVDotODA4MH0nCiAgICAgIC0gJ1FCSVRfQkFTRT0ke1NFUlZJQ0VfRlFETl9RQklUT1JSRU5UfScKICAgICAgLSAnUkVMRUFTRV9UWVBFPSR7UkVMRUFTRV9UWVBFOi1zdGFibGV9JwogICAgICAtICdVUERBVEVfVlRfQ1JPTj0ke1VQREFURV9WVF9DUk9OOi0iMCAqICogKiAqIn0nCiAgICB2b2x1bWVzOgogICAgICAtICd2dWV0b3JyZW50LWNvbmZpZzovY29uZmlnJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctcScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjgwODAvJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCg==", + "tags": [ + "torrent", + "streaming", + "webui" + ], + "logo": "svgs/qbittorrent.svg", + "minversion": "0.0.0", + "port": "8080" + }, "qdrant": { "documentation": "https://qdrant.tech/documentation/?utm_source=coolify.io", "slogan": "Qdrant is a vector similarity search engine that provides a production-ready service with a convenient API to store, search, and manage points (i.e. vectors) with an additional payload.", @@ -1932,7 +2278,7 @@ "supabase": { "documentation": "https://supabase.io?utm_source=coolify.io", "slogan": "The open source Firebase alternative.", - "compose": "c2VydmljZXM6CiAgc3VwYWJhc2Uta29uZzoKICAgIGltYWdlOiAna29uZzoyLjguMScKICAgIGVudHJ5cG9pbnQ6ICdiYXNoIC1jICcnZXZhbCAiZWNobyBcIiQkKGNhdCB+L3RlbXAueW1sKVwiIiA+IH4va29uZy55bWwgJiYgL2RvY2tlci1lbnRyeXBvaW50LnNoIGtvbmcgZG9ja2VyLXN0YXJ0JycnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9TVVBBQkFTRUtPTkcKICAgICAgLSAnSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSBLT05HX0RBVEFCQVNFPW9mZgogICAgICAtIEtPTkdfREVDTEFSQVRJVkVfQ09ORklHPS9ob21lL2tvbmcva29uZy55bWwKICAgICAgLSAnS09OR19ETlNfT1JERVI9TEFTVCxBLENOQU1FJwogICAgICAtICdLT05HX1BMVUdJTlM9cmVxdWVzdC10cmFuc2Zvcm1lcixjb3JzLGtleS1hdXRoLGFjbCxiYXNpYy1hdXRoJwogICAgICAtIEtPTkdfTkdJTlhfUFJPWFlfUFJPWFlfQlVGRkVSX1NJWkU9MTYwawogICAgICAtICdLT05HX05HSU5YX1BST1hZX1BST1hZX0JVRkZFUlM9NjQgMTYwaycKICAgICAgLSAnU1VQQUJBU0VfQU5PTl9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAtICdTVVBBQkFTRV9TRVJWSUNFX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VTRVJWSUNFX0tFWX0nCiAgICAgIC0gJ0RBU0hCT0FSRF9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9BRE1JTn0nCiAgICAgIC0gJ0RBU0hCT0FSRF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfQURNSU59JwogICAgdm9sdW1lczoKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9hcGkva29uZy55bWwKICAgICAgICB0YXJnZXQ6IC9ob21lL2tvbmcvdGVtcC55bWwKICAgICAgICBjb250ZW50OiAiX2Zvcm1hdF92ZXJzaW9uOiAnMi4xJ1xuX3RyYW5zZm9ybTogdHJ1ZVxuXG4jIyNcbiMjIyBDb25zdW1lcnMgLyBVc2Vyc1xuIyMjXG5jb25zdW1lcnM6XG4gIC0gdXNlcm5hbWU6IERBU0hCT0FSRFxuICAtIHVzZXJuYW1lOiBhbm9uXG4gICAga2V5YXV0aF9jcmVkZW50aWFsczpcbiAgICAgIC0ga2V5OiAkU1VQQUJBU0VfQU5PTl9LRVlcbiAgLSB1c2VybmFtZTogc2VydmljZV9yb2xlXG4gICAga2V5YXV0aF9jcmVkZW50aWFsczpcbiAgICAgIC0ga2V5OiAkU1VQQUJBU0VfU0VSVklDRV9LRVlcblxuIyMjXG4jIyMgQWNjZXNzIENvbnRyb2wgTGlzdFxuIyMjXG5hY2xzOlxuICAtIGNvbnN1bWVyOiBhbm9uXG4gICAgZ3JvdXA6IGFub25cbiAgLSBjb25zdW1lcjogc2VydmljZV9yb2xlXG4gICAgZ3JvdXA6IGFkbWluXG5cbiMjI1xuIyMjIERhc2hib2FyZCBjcmVkZW50aWFsc1xuIyMjXG5iYXNpY2F1dGhfY3JlZGVudGlhbHM6XG4tIGNvbnN1bWVyOiBEQVNIQk9BUkRcbiAgdXNlcm5hbWU6ICREQVNIQk9BUkRfVVNFUk5BTUVcbiAgcGFzc3dvcmQ6ICREQVNIQk9BUkRfUEFTU1dPUkRcblxuXG4jIyNcbiMjIyBBUEkgUm91dGVzXG4jIyNcbnNlcnZpY2VzOlxuXG4gICMjIE9wZW4gQXV0aCByb3V0ZXNcbiAgLSBuYW1lOiBhdXRoLXYxLW9wZW5cbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1hdXRoOjk5OTkvdmVyaWZ5XG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBhdXRoLXYxLW9wZW5cbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9hdXRoL3YxL3ZlcmlmeVxuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgLSBuYW1lOiBhdXRoLXYxLW9wZW4tY2FsbGJhY2tcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1hdXRoOjk5OTkvY2FsbGJhY2tcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtb3Blbi1jYWxsYmFja1xuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2F1dGgvdjEvY2FsbGJhY2tcbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gIC0gbmFtZTogYXV0aC12MS1vcGVuLWF1dGhvcml6ZVxuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS9hdXRob3JpemVcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtb3Blbi1hdXRob3JpemVcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9hdXRoL3YxL2F1dGhvcml6ZVxuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcblxuICAjIyBTZWN1cmUgQXV0aCByb3V0ZXNcbiAgLSBuYW1lOiBhdXRoLXYxXG4gICAgX2NvbW1lbnQ6ICdHb1RydWU6IC9hdXRoL3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvYXV0aC92MS9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiBmYWxzZVxuICAgICAgLSBuYW1lOiBhY2xcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfZ3JvdXBzX2hlYWRlcjogdHJ1ZVxuICAgICAgICAgIGFsbG93OlxuICAgICAgICAgICAgLSBhZG1pblxuICAgICAgICAgICAgLSBhbm9uXG5cbiAgIyMgU2VjdXJlIFJFU1Qgcm91dGVzXG4gIC0gbmFtZTogcmVzdC12MVxuICAgIF9jb21tZW50OiAnUG9zdGdSRVNUOiAvcmVzdC92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvKidcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiByZXN0LXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL3Jlc3QvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogdHJ1ZVxuICAgICAgLSBuYW1lOiBhY2xcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfZ3JvdXBzX2hlYWRlcjogdHJ1ZVxuICAgICAgICAgIGFsbG93OlxuICAgICAgICAgICAgLSBhZG1pblxuICAgICAgICAgICAgLSBhbm9uXG5cbiAgIyMgU2VjdXJlIEdyYXBoUUwgcm91dGVzXG4gIC0gbmFtZTogZ3JhcGhxbC12MVxuICAgIF9jb21tZW50OiAnUG9zdGdSRVNUOiAvZ3JhcGhxbC92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvcnBjL2dyYXBocWwnXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtcmVzdDozMDAwL3JwYy9ncmFwaHFsXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBncmFwaHFsLXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2dyYXBocWwvdjFcbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiB0cnVlXG4gICAgICAtIG5hbWU6IHJlcXVlc3QtdHJhbnNmb3JtZXJcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGFkZDpcbiAgICAgICAgICAgIGhlYWRlcnM6XG4gICAgICAgICAgICAgIC0gQ29udGVudC1Qcm9maWxlOmdyYXBocWxfcHVibGljXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cblxuICAjIyBTZWN1cmUgUmVhbHRpbWUgcm91dGVzXG4gIC0gbmFtZTogcmVhbHRpbWUtdjEtd3NcbiAgICBfY29tbWVudDogJ1JlYWx0aW1lOiAvcmVhbHRpbWUvdjEvKiAtPiB3czovL3JlYWx0aW1lOjQwMDAvc29ja2V0LyonXG4gICAgdXJsOiBodHRwOi8vcmVhbHRpbWUtZGV2OjQwMDAvc29ja2V0XG4gICAgcHJvdG9jb2w6IHdzXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiByZWFsdGltZS12MS13c1xuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL3JlYWx0aW1lL3YxL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IGZhbHNlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cbiAgLSBuYW1lOiByZWFsdGltZS12MS1yZXN0XG4gICAgX2NvbW1lbnQ6ICdSZWFsdGltZTogL3JlYWx0aW1lL3YxLyogLT4gd3M6Ly9yZWFsdGltZTo0MDAwL3NvY2tldC8qJ1xuICAgIHVybDogaHR0cDovL3JlYWx0aW1lLWRldjo0MDAwL2FwaVxuICAgIHByb3RvY29sOiBodHRwXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiByZWFsdGltZS12MS1yZXN0XG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcmVhbHRpbWUvdjEvYXBpXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogZmFsc2VcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cbiAgICAgICAgICAgIC0gYW5vblxuXG4gICMjIFN0b3JhZ2Ugcm91dGVzOiB0aGUgc3RvcmFnZSBzZXJ2ZXIgbWFuYWdlcyBpdHMgb3duIGF1dGhcbiAgLSBuYW1lOiBzdG9yYWdlLXYxXG4gICAgX2NvbW1lbnQ6ICdTdG9yYWdlOiAvc3RvcmFnZS92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1zdG9yYWdlOjUwMDAvKidcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1zdG9yYWdlOjUwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBzdG9yYWdlLXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL3N0b3JhZ2UvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuXG4gICMjIEVkZ2UgRnVuY3Rpb25zIHJvdXRlc1xuICAtIG5hbWU6IGZ1bmN0aW9ucy12MVxuICAgIF9jb21tZW50OiAnRWRnZSBGdW5jdGlvbnM6IC9mdW5jdGlvbnMvdjEvKiAtPiBodHRwOi8vc3VwYWJhc2UtZWRnZS1mdW5jdGlvbnM6OTAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWVkZ2UtZnVuY3Rpb25zOjkwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBmdW5jdGlvbnMtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvZnVuY3Rpb25zL3YxL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcblxuICAjIyBBbmFseXRpY3Mgcm91dGVzXG4gIC0gbmFtZTogYW5hbHl0aWNzLXYxXG4gICAgX2NvbW1lbnQ6ICdBbmFseXRpY3M6IC9hbmFseXRpY3MvdjEvKiAtPiBodHRwOi8vbG9nZmxhcmU6NDAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYW5hbHl0aWNzLXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2FuYWx5dGljcy92MS9cblxuICAjIyBTZWN1cmUgRGF0YWJhc2Ugcm91dGVzXG4gIC0gbmFtZTogbWV0YVxuICAgIF9jb21tZW50OiAncGctbWV0YTogL3BnLyogLT4gaHR0cDovL3N1cGFiYXNlLW1ldGE6ODA4MC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLW1ldGE6ODA4MC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IG1ldGEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcGcvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IGZhbHNlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG5cbiAgIyMgUHJvdGVjdGVkIERhc2hib2FyZCAtIGNhdGNoIGFsbCByZW1haW5pbmcgcm91dGVzXG4gIC0gbmFtZTogZGFzaGJvYXJkXG4gICAgX2NvbW1lbnQ6ICdTdHVkaW86IC8qIC0+IGh0dHA6Ly9zdHVkaW86MzAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLXN0dWRpbzozMDAwL1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogZGFzaGJvYXJkLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZTogYmFzaWMtYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogdHJ1ZVxuIgogIHN1cGFiYXNlLXN0dWRpbzoKICAgIGltYWdlOiAnc3VwYWJhc2Uvc3R1ZGlvOjIwMjQwNzI5LWNlNDIxMzknCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbm9kZQogICAgICAgIC0gJy1lJwogICAgICAgIC0gInJlcXVpcmUoJ2h0dHAnKS5nZXQoJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMC9hcGkvcHJvZmlsZScsIChyKSA9PiB7aWYgKHIuc3RhdHVzQ29kZSAhPT0gMjAwKSBwcm9jZXNzLmV4aXQoMSk7IGVsc2UgcHJvY2Vzcy5leGl0KDApOyB9KS5vbignZXJyb3InLCAoKSA9PiBwcm9jZXNzLmV4aXQoMSkpIgogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBIT1NUTkFNRT0wLjAuMC4wCiAgICAgIC0gJ1NUVURJT19QR19NRVRBX1VSTD1odHRwOi8vc3VwYWJhc2UtbWV0YTo4MDgwJwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdERUZBVUxUX09SR0FOSVpBVElPTl9OQU1FPSR7U1RVRElPX0RFRkFVTFRfT1JHQU5JWkFUSU9OOi1EZWZhdWx0IE9yZ2FuaXphdGlvbn0nCiAgICAgIC0gJ0RFRkFVTFRfUFJPSkVDVF9OQU1FPSR7U1RVRElPX0RFRkFVTFRfUFJPSkVDVDotRGVmYXVsdCBQcm9qZWN0fScKICAgICAgLSAnU1VQQUJBU0VfVVJMPSR7U0VSVklDRV9GUUROX1NVUEFCQVNFS09OR30nCiAgICAgIC0gJ1NVUEFCQVNFX1BVQkxJQ19VUkw9JHtTRVJWSUNFX0ZRRE5fU1VQQUJBU0VLT05HfScKICAgICAgLSAnU1VQQUJBU0VfQU5PTl9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAtICdTVVBBQkFTRV9TRVJWSUNFX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VTRVJWSUNFX0tFWX0nCiAgICAgIC0gJ0FVVEhfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnTE9HRkxBUkVfQVBJX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfTE9HRkxBUkV9JwogICAgICAtICdMT0dGTEFSRV9VUkw9aHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwJwogICAgICAtIE5FWFRfUFVCTElDX0VOQUJMRV9MT0dTPXRydWUKICAgICAgLSBORVhUX0FOQUxZVElDU19CQUNLRU5EX1BST1ZJREVSPXBvc3RncmVzCiAgc3VwYWJhc2UtZGI6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3Bvc3RncmVzOjE1LjEuMS43OCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OiAncGdfaXNyZWFkeSAtVSBwb3N0Z3JlcyAtaCAxMjcuMC4wLjEnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAxMAogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtdmVjdG9yOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBjb21tYW5kOgogICAgICAtIHBvc3RncmVzCiAgICAgIC0gJy1jJwogICAgICAtIGNvbmZpZ19maWxlPS9ldGMvcG9zdGdyZXNxbC9wb3N0Z3Jlc3FsLmNvbmYKICAgICAgLSAnLWMnCiAgICAgIC0gbG9nX21pbl9tZXNzYWdlcz1mYXRhbAogICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWQKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPU1RHUkVTX0hPU1Q9L3Zhci9ydW4vcG9zdGdyZXNxbAogICAgICAtICdQR1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUE9TVEdSRVNfUE9SVD0ke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9JwogICAgICAtICdQR1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BHREFUQUJBU0U9JHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ0pXVF9FWFA9JHtKV1RfRVhQSVJZOi0zNjAwfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3N1cGFiYXNlLWRiLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2RiL3JlYWx0aW1lLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTktcmVhbHRpbWUuc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IHBndXNlciBgZWNobyBcInN1cGFiYXNlX2FkbWluXCJgXG5cbmNyZWF0ZSBzY2hlbWEgaWYgbm90IGV4aXN0cyBfcmVhbHRpbWU7XG5hbHRlciBzY2hlbWEgX3JlYWx0aW1lIG93bmVyIHRvIDpwZ3VzZXI7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvd2ViaG9va3Muc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvaW5pdC1zY3JpcHRzLzk4LXdlYmhvb2tzLnNxbAogICAgICAgIGNvbnRlbnQ6ICJCRUdJTjtcbi0tIENyZWF0ZSBwZ19uZXQgZXh0ZW5zaW9uXG5DUkVBVEUgRVhURU5TSU9OIElGIE5PVCBFWElTVFMgcGdfbmV0IFNDSEVNQSBleHRlbnNpb25zO1xuLS0gQ3JlYXRlIHN1cGFiYXNlX2Z1bmN0aW9ucyBzY2hlbWFcbkNSRUFURSBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIEFVVEhPUklaQVRJT04gc3VwYWJhc2VfYWRtaW47XG5HUkFOVCBVU0FHRSBPTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gVEFCTEVTIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gRlVOQ1RJT05TIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gU0VRVUVOQ0VTIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4tLSBzdXBhYmFzZV9mdW5jdGlvbnMubWlncmF0aW9ucyBkZWZpbml0aW9uXG5DUkVBVEUgVEFCTEUgc3VwYWJhc2VfZnVuY3Rpb25zLm1pZ3JhdGlvbnMgKFxuICB2ZXJzaW9uIHRleHQgUFJJTUFSWSBLRVksXG4gIGluc2VydGVkX2F0IHRpbWVzdGFtcHR6IE5PVCBOVUxMIERFRkFVTFQgTk9XKClcbik7XG4tLSBJbml0aWFsIHN1cGFiYXNlX2Z1bmN0aW9ucyBtaWdyYXRpb25cbklOU0VSVCBJTlRPIHN1cGFiYXNlX2Z1bmN0aW9ucy5taWdyYXRpb25zICh2ZXJzaW9uKSBWQUxVRVMgKCdpbml0aWFsJyk7XG4tLSBzdXBhYmFzZV9mdW5jdGlvbnMuaG9va3MgZGVmaW5pdGlvblxuQ1JFQVRFIFRBQkxFIHN1cGFiYXNlX2Z1bmN0aW9ucy5ob29rcyAoXG4gIGlkIGJpZ3NlcmlhbCBQUklNQVJZIEtFWSxcbiAgaG9va190YWJsZV9pZCBpbnRlZ2VyIE5PVCBOVUxMLFxuICBob29rX25hbWUgdGV4dCBOT1QgTlVMTCxcbiAgY3JlYXRlZF9hdCB0aW1lc3RhbXB0eiBOT1QgTlVMTCBERUZBVUxUIE5PVygpLFxuICByZXF1ZXN0X2lkIGJpZ2ludFxuKTtcbkNSRUFURSBJTkRFWCBzdXBhYmFzZV9mdW5jdGlvbnNfaG9va3NfcmVxdWVzdF9pZF9pZHggT04gc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIFVTSU5HIGJ0cmVlIChyZXF1ZXN0X2lkKTtcbkNSRUFURSBJTkRFWCBzdXBhYmFzZV9mdW5jdGlvbnNfaG9va3NfaF90YWJsZV9pZF9oX25hbWVfaWR4IE9OIHN1cGFiYXNlX2Z1bmN0aW9ucy5ob29rcyBVU0lORyBidHJlZSAoaG9va190YWJsZV9pZCwgaG9va19uYW1lKTtcbkNPTU1FTlQgT04gVEFCTEUgc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIElTICdTdXBhYmFzZSBGdW5jdGlvbnMgSG9va3M6IEF1ZGl0IHRyYWlsIGZvciB0cmlnZ2VyZWQgaG9va3MuJztcbkNSRUFURSBGVU5DVElPTiBzdXBhYmFzZV9mdW5jdGlvbnMuaHR0cF9yZXF1ZXN0KClcbiAgUkVUVVJOUyB0cmlnZ2VyXG4gIExBTkdVQUdFIHBscGdzcWxcbiAgQVMgJGZ1bmN0aW9uJFxuICBERUNMQVJFXG4gICAgcmVxdWVzdF9pZCBiaWdpbnQ7XG4gICAgcGF5bG9hZCBqc29uYjtcbiAgICB1cmwgdGV4dCA6PSBUR19BUkdWWzBdOjp0ZXh0O1xuICAgIG1ldGhvZCB0ZXh0IDo9IFRHX0FSR1ZbMV06OnRleHQ7XG4gICAgaGVhZGVycyBqc29uYiBERUZBVUxUICd7fSc6Ompzb25iO1xuICAgIHBhcmFtcyBqc29uYiBERUZBVUxUICd7fSc6Ompzb25iO1xuICAgIHRpbWVvdXRfbXMgaW50ZWdlciBERUZBVUxUIDEwMDA7XG4gIEJFR0lOXG4gICAgSUYgdXJsIElTIE5VTEwgT1IgdXJsID0gJ251bGwnIFRIRU5cbiAgICAgIFJBSVNFIEVYQ0VQVElPTiAndXJsIGFyZ3VtZW50IGlzIG1pc3NpbmcnO1xuICAgIEVORCBJRjtcblxuICAgIElGIG1ldGhvZCBJUyBOVUxMIE9SIG1ldGhvZCA9ICdudWxsJyBUSEVOXG4gICAgICBSQUlTRSBFWENFUFRJT04gJ21ldGhvZCBhcmd1bWVudCBpcyBtaXNzaW5nJztcbiAgICBFTkQgSUY7XG5cbiAgICBJRiBUR19BUkdWWzJdIElTIE5VTEwgT1IgVEdfQVJHVlsyXSA9ICdudWxsJyBUSEVOXG4gICAgICBoZWFkZXJzID0gJ3tcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIn0nOjpqc29uYjtcbiAgICBFTFNFXG4gICAgICBoZWFkZXJzID0gVEdfQVJHVlsyXTo6anNvbmI7XG4gICAgRU5EIElGO1xuXG4gICAgSUYgVEdfQVJHVlszXSBJUyBOVUxMIE9SIFRHX0FSR1ZbM10gPSAnbnVsbCcgVEhFTlxuICAgICAgcGFyYW1zID0gJ3t9Jzo6anNvbmI7XG4gICAgRUxTRVxuICAgICAgcGFyYW1zID0gVEdfQVJHVlszXTo6anNvbmI7XG4gICAgRU5EIElGO1xuXG4gICAgSUYgVEdfQVJHVls0XSBJUyBOVUxMIE9SIFRHX0FSR1ZbNF0gPSAnbnVsbCcgVEhFTlxuICAgICAgdGltZW91dF9tcyA9IDEwMDA7XG4gICAgRUxTRVxuICAgICAgdGltZW91dF9tcyA9IFRHX0FSR1ZbNF06OmludGVnZXI7XG4gICAgRU5EIElGO1xuXG4gICAgQ0FTRVxuICAgICAgV0hFTiBtZXRob2QgPSAnR0VUJyBUSEVOXG4gICAgICAgIFNFTEVDVCBodHRwX2dldCBJTlRPIHJlcXVlc3RfaWQgRlJPTSBuZXQuaHR0cF9nZXQoXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgIHRpbWVvdXRfbXNcbiAgICAgICAgKTtcbiAgICAgIFdIRU4gbWV0aG9kID0gJ1BPU1QnIFRIRU5cbiAgICAgICAgcGF5bG9hZCA9IGpzb25iX2J1aWxkX29iamVjdChcbiAgICAgICAgICAnb2xkX3JlY29yZCcsIE9MRCxcbiAgICAgICAgICAncmVjb3JkJywgTkVXLFxuICAgICAgICAgICd0eXBlJywgVEdfT1AsXG4gICAgICAgICAgJ3RhYmxlJywgVEdfVEFCTEVfTkFNRSxcbiAgICAgICAgICAnc2NoZW1hJywgVEdfVEFCTEVfU0NIRU1BXG4gICAgICAgICk7XG5cbiAgICAgICAgU0VMRUNUIGh0dHBfcG9zdCBJTlRPIHJlcXVlc3RfaWQgRlJPTSBuZXQuaHR0cF9wb3N0KFxuICAgICAgICAgIHVybCxcbiAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgIHRpbWVvdXRfbXNcbiAgICAgICAgKTtcbiAgICAgIEVMU0VcbiAgICAgICAgUkFJU0UgRVhDRVBUSU9OICdtZXRob2QgYXJndW1lbnQgJSBpcyBpbnZhbGlkJywgbWV0aG9kO1xuICAgIEVORCBDQVNFO1xuXG4gICAgSU5TRVJUIElOVE8gc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzXG4gICAgICAoaG9va190YWJsZV9pZCwgaG9va19uYW1lLCByZXF1ZXN0X2lkKVxuICAgIFZBTFVFU1xuICAgICAgKFRHX1JFTElELCBUR19OQU1FLCByZXF1ZXN0X2lkKTtcblxuICAgIFJFVFVSTiBORVc7XG4gIEVORFxuJGZ1bmN0aW9uJDtcbi0tIFN1cGFiYXNlIHN1cGVyIGFkbWluXG5ET1xuJCRcbkJFR0lOXG4gIElGIE5PVCBFWElTVFMgKFxuICAgIFNFTEVDVCAxXG4gICAgRlJPTSBwZ19yb2xlc1xuICAgIFdIRVJFIHJvbG5hbWUgPSAnc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluJ1xuICApXG4gIFRIRU5cbiAgICBDUkVBVEUgVVNFUiBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4gTk9JTkhFUklUIENSRUFURVJPTEUgTE9HSU4gTk9SRVBMSUNBVElPTjtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbkdSQU5UIEFMTCBQUklWSUxFR0VTIE9OIFNDSEVNQSBzdXBhYmFzZV9mdW5jdGlvbnMgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gQUxMIFRBQkxFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkdSQU5UIEFMTCBQUklWSUxFR0VTIE9OIEFMTCBTRVFVRU5DRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5BTFRFUiBVU0VSIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBTRVQgc2VhcmNoX3BhdGggPSBcInN1cGFiYXNlX2Z1bmN0aW9uc1wiO1xuQUxURVIgdGFibGUgXCJzdXBhYmFzZV9mdW5jdGlvbnNcIi5taWdyYXRpb25zIE9XTkVSIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkFMVEVSIHRhYmxlIFwic3VwYWJhc2VfZnVuY3Rpb25zXCIuaG9va3MgT1dORVIgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuQUxURVIgZnVuY3Rpb24gXCJzdXBhYmFzZV9mdW5jdGlvbnNcIi5odHRwX3JlcXVlc3QoKSBPV05FUiBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5HUkFOVCBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4gVE8gcG9zdGdyZXM7XG4tLSBSZW1vdmUgdW51c2VkIHN1cGFiYXNlX3BnX25ldF9hZG1pbiByb2xlXG5ET1xuJCRcbkJFR0lOXG4gIElGIEVYSVNUUyAoXG4gICAgU0VMRUNUIDFcbiAgICBGUk9NIHBnX3JvbGVzXG4gICAgV0hFUkUgcm9sbmFtZSA9ICdzdXBhYmFzZV9wZ19uZXRfYWRtaW4nXG4gIClcbiAgVEhFTlxuICAgIFJFQVNTSUdOIE9XTkVEIEJZIHN1cGFiYXNlX3BnX25ldF9hZG1pbiBUTyBzdXBhYmFzZV9hZG1pbjtcbiAgICBEUk9QIE9XTkVEIEJZIHN1cGFiYXNlX3BnX25ldF9hZG1pbjtcbiAgICBEUk9QIFJPTEUgc3VwYWJhc2VfcGdfbmV0X2FkbWluO1xuICBFTkQgSUY7XG5FTkRcbiQkO1xuLS0gcGdfbmV0IGdyYW50cyB3aGVuIGV4dGVuc2lvbiBpcyBhbHJlYWR5IGVuYWJsZWRcbkRPXG4kJFxuQkVHSU5cbiAgSUYgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfZXh0ZW5zaW9uXG4gICAgV0hFUkUgZXh0bmFtZSA9ICdwZ19uZXQnXG4gIClcbiAgVEhFTlxuICAgIEdSQU5UIFVTQUdFIE9OIFNDSEVNQSBuZXQgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VDVVJJVFkgREVGSU5FUjtcbiAgICBBTFRFUiBmdW5jdGlvbiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBGUk9NIFBVQkxJQztcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbi0tIEV2ZW50IHRyaWdnZXIgZm9yIHBnX25ldFxuQ1JFQVRFIE9SIFJFUExBQ0UgRlVOQ1RJT04gZXh0ZW5zaW9ucy5ncmFudF9wZ19uZXRfYWNjZXNzKClcblJFVFVSTlMgZXZlbnRfdHJpZ2dlclxuTEFOR1VBR0UgcGxwZ3NxbFxuQVMgJCRcbkJFR0lOXG4gIElGIEVYSVNUUyAoXG4gICAgU0VMRUNUIDFcbiAgICBGUk9NIHBnX2V2ZW50X3RyaWdnZXJfZGRsX2NvbW1hbmRzKCkgQVMgZXZcbiAgICBKT0lOIHBnX2V4dGVuc2lvbiBBUyBleHRcbiAgICBPTiBldi5vYmppZCA9IGV4dC5vaWRcbiAgICBXSEVSRSBleHQuZXh0bmFtZSA9ICdwZ19uZXQnXG4gIClcbiAgVEhFTlxuICAgIEdSQU5UIFVTQUdFIE9OIFNDSEVNQSBuZXQgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VDVVJJVFkgREVGSU5FUjtcbiAgICBBTFRFUiBmdW5jdGlvbiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBGUk9NIFBVQkxJQztcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgRU5EIElGO1xuRU5EO1xuJCQ7XG5DT01NRU5UIE9OIEZVTkNUSU9OIGV4dGVuc2lvbnMuZ3JhbnRfcGdfbmV0X2FjY2VzcyBJUyAnR3JhbnRzIGFjY2VzcyB0byBwZ19uZXQnO1xuRE9cbiQkXG5CRUdJTlxuICBJRiBOT1QgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfZXZlbnRfdHJpZ2dlclxuICAgIFdIRVJFIGV2dG5hbWUgPSAnaXNzdWVfcGdfbmV0X2FjY2VzcydcbiAgKSBUSEVOXG4gICAgQ1JFQVRFIEVWRU5UIFRSSUdHRVIgaXNzdWVfcGdfbmV0X2FjY2VzcyBPTiBkZGxfY29tbWFuZF9lbmQgV0hFTiBUQUcgSU4gKCdDUkVBVEUgRVhURU5TSU9OJylcbiAgICBFWEVDVVRFIFBST0NFRFVSRSBleHRlbnNpb25zLmdyYW50X3BnX25ldF9hY2Nlc3MoKTtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbklOU0VSVCBJTlRPIHN1cGFiYXNlX2Z1bmN0aW9ucy5taWdyYXRpb25zICh2ZXJzaW9uKSBWQUxVRVMgKCcyMDIxMDgwOTE4MzQyM191cGRhdGVfZ3JhbnRzJyk7XG5BTFRFUiBmdW5jdGlvbiBzdXBhYmFzZV9mdW5jdGlvbnMuaHR0cF9yZXF1ZXN0KCkgU0VDVVJJVFkgREVGSU5FUjtcbkFMVEVSIGZ1bmN0aW9uIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKSBTRVQgc2VhcmNoX3BhdGggPSBzdXBhYmFzZV9mdW5jdGlvbnM7XG5SRVZPS0UgQUxMIE9OIEZVTkNUSU9OIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKSBGUk9NIFBVQkxJQztcbkdSQU5UIEVYRUNVVEUgT04gRlVOQ1RJT04gc3VwYWJhc2VfZnVuY3Rpb25zLmh0dHBfcmVxdWVzdCgpIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5DT01NSVQ7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvcm9sZXMuc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvaW5pdC1zY3JpcHRzLzk5LXJvbGVzLnNxbAogICAgICAgIGNvbnRlbnQ6ICItLSBOT1RFOiBjaGFuZ2UgdG8geW91ciBvd24gcGFzc3dvcmRzIGZvciBwcm9kdWN0aW9uIGVudmlyb25tZW50c1xuIFxcc2V0IHBncGFzcyBgZWNobyBcIiRQT1NUR1JFU19QQVNTV09SRFwiYFxuXG4gQUxURVIgVVNFUiBhdXRoZW50aWNhdG9yIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgcGdib3VuY2VyIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgc3VwYWJhc2VfYXV0aF9hZG1pbiBXSVRIIFBBU1NXT1JEIDoncGdwYXNzJztcbiBBTFRFUiBVU0VSIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBXSVRIIFBBU1NXT1JEIDoncGdwYXNzJztcbiBBTFRFUiBVU0VSIHN1cGFiYXNlX3N0b3JhZ2VfYWRtaW4gV0lUSCBQQVNTV09SRCA6J3BncGFzcyc7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvand0LnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL2luaXQtc2NyaXB0cy85OS1qd3Quc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IGp3dF9zZWNyZXQgYGVjaG8gXCIkSldUX1NFQ1JFVFwiYFxuXFxzZXQgand0X2V4cCBgZWNobyBcIiRKV1RfRVhQXCJgXG5cXHNldCBkYl9uYW1lIGBlY2hvIFwiJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9XCJgXG5cbkFMVEVSIERBVEFCQVNFIDpkYl9uYW1lIFNFVCBcImFwcC5zZXR0aW5ncy5qd3Rfc2VjcmV0XCIgVE8gOidqd3Rfc2VjcmV0JztcbkFMVEVSIERBVEFCQVNFIDpkYl9uYW1lIFNFVCBcImFwcC5zZXR0aW5ncy5qd3RfZXhwXCIgVE8gOidqd3RfZXhwJztcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9sb2dzLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTktbG9ncy5zcWwKICAgICAgICBjb250ZW50OiAiXFxzZXQgcGd1c2VyIGBlY2hvIFwic3VwYWJhc2VfYWRtaW5cImBcblxuY3JlYXRlIHNjaGVtYSBpZiBub3QgZXhpc3RzIF9hbmFseXRpY3M7XG5hbHRlciBzY2hlbWEgX2FuYWx5dGljcyBvd25lciB0byA6cGd1c2VyO1xuIgogICAgICAtICdzdXBhYmFzZS1kYi1jb25maWc6L2V0Yy9wb3N0Z3Jlc3FsLWN1c3RvbScKICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICBpbWFnZTogJ3N1cGFiYXNlL2xvZ2ZsYXJlOjEuNC4wJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjQwMDAvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMTAKICAgIHJlc3RhcnQ6IHVubGVzcy1zdG9wcGVkCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gTE9HRkxBUkVfTk9ERV9IT1NUPTEyNy4wLjAuMQogICAgICAtIERCX1VTRVJOQU1FPXN1cGFiYXNlX2FkbWluCiAgICAgIC0gJ0RCX0RBVEFCQVNFPSR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnREJfSE9TVE5BTUU9JHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9JwogICAgICAtICdEQl9QT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gJ0RCX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gREJfU0NIRU1BPV9hbmFseXRpY3MKICAgICAgLSAnTE9HRkxBUkVfQVBJX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfTE9HRkxBUkV9JwogICAgICAtIExPR0ZMQVJFX1NJTkdMRV9URU5BTlQ9dHJ1ZQogICAgICAtIExPR0ZMQVJFX1NJTkdMRV9URU5BTlRfTU9ERT10cnVlCiAgICAgIC0gTE9HRkxBUkVfU1VQQUJBU0VfTU9ERT10cnVlCiAgICAgIC0gTE9HRkxBUkVfTUlOX0NMVVNURVJfU0laRT0xCiAgICAgIC0gJ1BPU1RHUkVTX0JBQ0tFTkRfVVJMPXBvc3RncmVzcWw6Ly9zdXBhYmFzZV9hZG1pbjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSBQT1NUR1JFU19CQUNLRU5EX1NDSEVNQT1fYW5hbHl0aWNzCiAgICAgIC0gTE9HRkxBUkVfRkVBVFVSRV9GTEFHX09WRVJSSURFPW11bHRpYmFja2VuZD10cnVlCiAgc3VwYWJhc2UtdmVjdG9yOgogICAgaW1hZ2U6ICd0aW1iZXJpby92ZWN0b3I6MC4yOC4xLWFscGluZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1uby12ZXJib3NlJwogICAgICAgIC0gJy0tdHJpZXM9MScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vc3VwYWJhc2UtdmVjdG9yOjkwMDEvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgdm9sdW1lczoKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9sb2dzL3ZlY3Rvci55bWwKICAgICAgICB0YXJnZXQ6IC9ldGMvdmVjdG9yL3ZlY3Rvci55bWwKICAgICAgICByZWFkX29ubHk6IHRydWUKICAgICAgICBjb250ZW50OiAiYXBpOlxuICBlbmFibGVkOiB0cnVlXG4gIGFkZHJlc3M6IDAuMC4wLjA6OTAwMVxuXG5zb3VyY2VzOlxuICBkb2NrZXJfaG9zdDpcbiAgICB0eXBlOiBkb2NrZXJfbG9nc1xuICAgIGV4Y2x1ZGVfY29udGFpbmVyczpcbiAgICAgIC0gc3VwYWJhc2UtdmVjdG9yXG5cbnRyYW5zZm9ybXM6XG4gIHByb2plY3RfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gZG9ja2VyX2hvc3RcbiAgICBzb3VyY2U6IHwtXG4gICAgICAucHJvamVjdCA9IFwiZGVmYXVsdFwiXG4gICAgICAuZXZlbnRfbWVzc2FnZSA9IGRlbCgubWVzc2FnZSlcbiAgICAgIC5hcHBuYW1lID0gZGVsKC5jb250YWluZXJfbmFtZSlcbiAgICAgIGRlbCguY29udGFpbmVyX2NyZWF0ZWRfYXQpXG4gICAgICBkZWwoLmNvbnRhaW5lcl9pZClcbiAgICAgIGRlbCguc291cmNlX3R5cGUpXG4gICAgICBkZWwoLnN0cmVhbSlcbiAgICAgIGRlbCgubGFiZWwpXG4gICAgICBkZWwoLmltYWdlKVxuICAgICAgZGVsKC5ob3N0KVxuICAgICAgZGVsKC5zdHJlYW0pXG4gIHJvdXRlcjpcbiAgICB0eXBlOiByb3V0ZVxuICAgIGlucHV0czpcbiAgICAgIC0gcHJvamVjdF9sb2dzXG4gICAgcm91dGU6XG4gICAgICBrb25nOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2Uta29uZ1wiKSdcbiAgICAgIGF1dGg6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1hdXRoXCIpJ1xuICAgICAgcmVzdDogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLXJlc3RcIiknXG4gICAgICByZWFsdGltZTogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInJlYWx0aW1lLWRldlwiKSdcbiAgICAgIHN0b3JhZ2U6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1zdG9yYWdlXCIpJ1xuICAgICAgZnVuY3Rpb25zOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2UtZnVuY3Rpb25zXCIpJ1xuICAgICAgZGI6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1kYlwiKSdcbiAgIyBJZ25vcmVzIG5vbiBuZ2lueCBlcnJvcnMgc2luY2UgdGhleSBhcmUgcmVsYXRlZCB3aXRoIGtvbmcgYm9vdGluZyB1cFxuICBrb25nX2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5rb25nXG4gICAgc291cmNlOiB8LVxuICAgICAgcmVxLCBlcnIgPSBwYXJzZV9uZ2lueF9sb2coLmV2ZW50X21lc3NhZ2UsIFwiY29tYmluZWRcIilcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAudGltZXN0YW1wID0gcmVxLnRpbWVzdGFtcFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LmhlYWRlcnMucmVmZXJlciA9IHJlcS5yZWZlcmVyXG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QuaGVhZGVycy51c2VyX2FnZW50ID0gcmVxLmFnZW50XG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QuaGVhZGVycy5jZl9jb25uZWN0aW5nX2lwID0gcmVxLmNsaWVudFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0Lm1ldGhvZCA9IHJlcS5tZXRob2RcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wYXRoID0gcmVxLnBhdGhcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wcm90b2NvbCA9IHJlcS5wcm90b2NvbFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXNwb25zZS5zdGF0dXNfY29kZSA9IHJlcS5zdGF0dXNcbiAgICAgIH1cbiAgICAgIGlmIGVyciAhPSBudWxsIHtcbiAgICAgICAgYWJvcnRcbiAgICAgIH1cbiAgIyBJZ25vcmVzIG5vbiBuZ2lueCBlcnJvcnMgc2luY2UgdGhleSBhcmUgcmVsYXRlZCB3aXRoIGtvbmcgYm9vdGluZyB1cFxuICBrb25nX2VycjpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmtvbmdcbiAgICBzb3VyY2U6IHwtXG4gICAgICAubWV0YWRhdGEucmVxdWVzdC5tZXRob2QgPSBcIkdFVFwiXG4gICAgICAubWV0YWRhdGEucmVzcG9uc2Uuc3RhdHVzX2NvZGUgPSAyMDBcbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfbmdpbnhfbG9nKC5ldmVudF9tZXNzYWdlLCBcImVycm9yXCIpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLnRpbWVzdGFtcCA9IHBhcnNlZC50aW1lc3RhbXBcbiAgICAgICAgICAuc2V2ZXJpdHkgPSBwYXJzZWQuc2V2ZXJpdHlcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5ob3N0ID0gcGFyc2VkLmhvc3RcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5oZWFkZXJzLmNmX2Nvbm5lY3RpbmdfaXAgPSBwYXJzZWQuY2xpZW50XG4gICAgICAgICAgdXJsLCBlcnIgPSBzcGxpdChwYXJzZWQucmVxdWVzdCwgXCIgXCIpXG4gICAgICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5tZXRob2QgPSB1cmxbMF1cbiAgICAgICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QucGF0aCA9IHVybFsxXVxuICAgICAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wcm90b2NvbCA9IHVybFsyXVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIGVyciAhPSBudWxsIHtcbiAgICAgICAgYWJvcnRcbiAgICAgIH1cbiAgIyBHb3RydWUgbG9ncyBhcmUgc3RydWN0dXJlZCBqc29uIHN0cmluZ3Mgd2hpY2ggZnJvbnRlbmQgcGFyc2VzIGRpcmVjdGx5LiBCdXQgd2Uga2VlcCBtZXRhZGF0YSBmb3IgY29uc2lzdGVuY3kuXG4gIGF1dGhfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmF1dGhcbiAgICBzb3VyY2U6IHwtXG4gICAgICBwYXJzZWQsIGVyciA9IHBhcnNlX2pzb24oLmV2ZW50X21lc3NhZ2UpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLm1ldGFkYXRhLnRpbWVzdGFtcCA9IHBhcnNlZC50aW1lXG4gICAgICAgICAgLm1ldGFkYXRhID0gbWVyZ2UhKC5tZXRhZGF0YSwgcGFyc2VkKVxuICAgICAgfVxuICAjIFBvc3RnUkVTVCBsb2dzIGFyZSBzdHJ1Y3R1cmVkIHNvIHdlIHNlcGFyYXRlIHRpbWVzdGFtcCBmcm9tIG1lc3NhZ2UgdXNpbmcgcmVnZXhcbiAgcmVzdF9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIucmVzdFxuICAgIHNvdXJjZTogfC1cbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfcmVnZXgoLmV2ZW50X21lc3NhZ2UsIHInXig/UDx0aW1lPi4qKTogKD9QPG1zZz4uKikkJylcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAuZXZlbnRfbWVzc2FnZSA9IHBhcnNlZC5tc2dcbiAgICAgICAgICAudGltZXN0YW1wID0gdG9fdGltZXN0YW1wIShwYXJzZWQudGltZSlcbiAgICAgICAgICAubWV0YWRhdGEuaG9zdCA9IC5wcm9qZWN0XG4gICAgICB9XG4gICMgUmVhbHRpbWUgbG9ncyBhcmUgc3RydWN0dXJlZCBzbyB3ZSBwYXJzZSB0aGUgc2V2ZXJpdHkgbGV2ZWwgdXNpbmcgcmVnZXggKGlnbm9yZSB0aW1lIGJlY2F1c2UgaXQgaGFzIG5vIGRhdGUpXG4gIHJlYWx0aW1lX2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5yZWFsdGltZVxuICAgIHNvdXJjZTogfC1cbiAgICAgIC5tZXRhZGF0YS5wcm9qZWN0ID0gZGVsKC5wcm9qZWN0KVxuICAgICAgLm1ldGFkYXRhLmV4dGVybmFsX2lkID0gLm1ldGFkYXRhLnByb2plY3RcbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfcmVnZXgoLmV2ZW50X21lc3NhZ2UsIHInXig/UDx0aW1lPlxcZCs6XFxkKzpcXGQrXFwuXFxkKykgXFxbKD9QPGxldmVsPlxcdyspXFxdICg/UDxtc2c+LiopJCcpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLmV2ZW50X21lc3NhZ2UgPSBwYXJzZWQubXNnXG4gICAgICAgICAgLm1ldGFkYXRhLmxldmVsID0gcGFyc2VkLmxldmVsXG4gICAgICB9XG4gICMgU3RvcmFnZSBsb2dzIG1heSBjb250YWluIGpzb24gb2JqZWN0cyBzbyB3ZSBwYXJzZSB0aGVtIGZvciBjb21wbGV0ZW5lc3NcbiAgc3RvcmFnZV9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIuc3RvcmFnZVxuICAgIHNvdXJjZTogfC1cbiAgICAgIC5tZXRhZGF0YS5wcm9qZWN0ID0gZGVsKC5wcm9qZWN0KVxuICAgICAgLm1ldGFkYXRhLnRlbmFudElkID0gLm1ldGFkYXRhLnByb2plY3RcbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfanNvbiguZXZlbnRfbWVzc2FnZSlcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAuZXZlbnRfbWVzc2FnZSA9IHBhcnNlZC5tc2dcbiAgICAgICAgICAubWV0YWRhdGEubGV2ZWwgPSBwYXJzZWQubGV2ZWxcbiAgICAgICAgICAubWV0YWRhdGEudGltZXN0YW1wID0gcGFyc2VkLnRpbWVcbiAgICAgICAgICAubWV0YWRhdGEuY29udGV4dFswXS5ob3N0ID0gcGFyc2VkLmhvc3RuYW1lXG4gICAgICAgICAgLm1ldGFkYXRhLmNvbnRleHRbMF0ucGlkID0gcGFyc2VkLnBpZFxuICAgICAgfVxuICAjIFBvc3RncmVzIGxvZ3Mgc29tZSBtZXNzYWdlcyB0byBzdGRlcnIgd2hpY2ggd2UgbWFwIHRvIHdhcm5pbmcgc2V2ZXJpdHkgbGV2ZWxcbiAgZGJfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmRiXG4gICAgc291cmNlOiB8LVxuICAgICAgLm1ldGFkYXRhLmhvc3QgPSBcImRiLWRlZmF1bHRcIlxuICAgICAgLm1ldGFkYXRhLnBhcnNlZC50aW1lc3RhbXAgPSAudGltZXN0YW1wXG5cbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfcmVnZXgoLmV2ZW50X21lc3NhZ2UsIHInLiooP1A8bGV2ZWw+SU5GT3xOT1RJQ0V8V0FSTklOR3xFUlJPUnxMT0d8RkFUQUx8UEFOSUM/KTouKicsIG51bWVyaWNfZ3JvdXBzOiB0cnVlKVxuXG4gICAgICBpZiBlcnIgIT0gbnVsbCB8fCBwYXJzZWQgPT0gbnVsbCB7XG4gICAgICAgIC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkgPSBcImluZm9cIlxuICAgICAgfVxuICAgICAgaWYgcGFyc2VkICE9IG51bGwge1xuICAgICAgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9IHBhcnNlZC5sZXZlbFxuICAgICAgfVxuICAgICAgaWYgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9PSBcImluZm9cIiB7XG4gICAgICAgICAgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9IFwibG9nXCJcbiAgICAgIH1cbiAgICAgIC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkgPSB1cGNhc2UhKC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkpXG5cbnNpbmtzOlxuICBsb2dmbGFyZV9hdXRoOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gYXV0aF9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPWdvdHJ1ZS5sb2dzLnByb2QmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX3JlYWx0aW1lOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gcmVhbHRpbWVfbG9nc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1yZWFsdGltZS5sb2dzLnByb2QmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX3Jlc3Q6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSByZXN0X2xvZ3NcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9cG9zdGdSRVNULmxvZ3MucHJvZCZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfZGI6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSBkYl9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgIyBXZSBtdXN0IHJvdXRlIHRoZSBzaW5rIHRocm91Z2gga29uZyBiZWNhdXNlIGluZ2VzdGluZyBsb2dzIGJlZm9yZSBsb2dmbGFyZSBpcyBmdWxseSBpbml0aWFsaXNlZCB3aWxsXG4gICAgIyBsZWFkIHRvIGJyb2tlbiBxdWVyaWVzIGZyb20gc3R1ZGlvLiBUaGlzIHdvcmtzIGJ5IHRoZSBhc3N1bXB0aW9uIHRoYXQgY29udGFpbmVycyBhcmUgc3RhcnRlZCBpbiB0aGVcbiAgICAjIGZvbGxvd2luZyBvcmRlcjogdmVjdG9yID4gZGIgPiBsb2dmbGFyZSA+IGtvbmdcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2Uta29uZzo4MDAwL2FuYWx5dGljcy92MS9hcGkvbG9ncz9zb3VyY2VfbmFtZT1wb3N0Z3Jlcy5sb2dzJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9mdW5jdGlvbnM6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIuZnVuY3Rpb25zXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPWRlbm8tcmVsYXktbG9ncyZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfc3RvcmFnZTpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIHN0b3JhZ2VfbG9nc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1zdG9yYWdlLmxvZ3MucHJvZC4yJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9rb25nOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0ga29uZ19sb2dzXG4gICAgICAtIGtvbmdfZXJyXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPWNsb3VkZmxhcmUubG9ncy5wcm9kJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuIgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jazpybycKICAgIGVudmlyb25tZW50OgogICAgICAtICdMT0dGTEFSRV9BUElfS0VZPSR7U0VSVklDRV9QQVNTV09SRF9MT0dGTEFSRX0nCiAgICBjb21tYW5kOgogICAgICAtICctLWNvbmZpZycKICAgICAgLSBldGMvdmVjdG9yL3ZlY3Rvci55bWwKICBzdXBhYmFzZS1yZXN0OgogICAgaW1hZ2U6ICdwb3N0Z3Jlc3QvcG9zdGdyZXN0OnYxMi4yLjAnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHJlc3RhcnQ6IHVubGVzcy1zdG9wcGVkCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUEdSU1RfREJfVVJJPXBvc3RncmVzOi8vYXV0aGVudGljYXRvcjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnUEdSU1RfREJfU0NIRU1BUz0ke1BHUlNUX0RCX1NDSEVNQVM6LXB1YmxpY30nCiAgICAgIC0gUEdSU1RfREJfQU5PTl9ST0xFPWFub24KICAgICAgLSAnUEdSU1RfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSBQR1JTVF9EQl9VU0VfTEVHQUNZX0dVQ1M9ZmFsc2UKICAgICAgLSAnUEdSU1RfQVBQX1NFVFRJTkdTX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ1BHUlNUX0FQUF9TRVRUSU5HU19KV1RfRVhQPSR7SldUX0VYUElSWTotMzYwMH0nCiAgICBjb21tYW5kOiBwb3N0Z3Jlc3QKICAgIGV4Y2x1ZGVfZnJvbV9oYzogdHJ1ZQogIHN1cGFiYXNlLWF1dGg6CiAgICBpbWFnZTogJ3N1cGFiYXNlL2dvdHJ1ZTp2Mi4xNTEuMCcKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLW5vLXZlcmJvc2UnCiAgICAgICAgLSAnLS10cmllcz0xJwogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6OTk5OS9oZWFsdGgnCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAzCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBHT1RSVUVfQVBJX0hPU1Q9MC4wLjAuMAogICAgICAtIEdPVFJVRV9BUElfUE9SVD05OTk5CiAgICAgIC0gJ0FQSV9FWFRFUk5BTF9VUkw9JHtBUElfRVhURVJOQUxfVVJMOi1odHRwOi8vc3VwYWJhc2Uta29uZzo4MDAwfScKICAgICAgLSBHT1RSVUVfREJfRFJJVkVSPXBvc3RncmVzCiAgICAgIC0gJ0dPVFJVRV9EQl9EQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly9zdXBhYmFzZV9hdXRoX2FkbWluOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9OiR7UE9TVEdSRVNfUE9SVDotNTQzMn0vJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdHT1RSVUVfU0lURV9VUkw9JHtTRVJWSUNFX0ZRRE5fU1VQQUJBU0VLT05HfScKICAgICAgLSAnR09UUlVFX1VSSV9BTExPV19MSVNUPSR7QURESVRJT05BTF9SRURJUkVDVF9VUkxTfScKICAgICAgLSAnR09UUlVFX0RJU0FCTEVfU0lHTlVQPSR7RElTQUJMRV9TSUdOVVA6LWZhbHNlfScKICAgICAgLSBHT1RSVUVfSldUX0FETUlOX1JPTEVTPXNlcnZpY2Vfcm9sZQogICAgICAtIEdPVFJVRV9KV1RfQVVEPWF1dGhlbnRpY2F0ZWQKICAgICAgLSBHT1RSVUVfSldUX0RFRkFVTFRfR1JPVVBfTkFNRT1hdXRoZW50aWNhdGVkCiAgICAgIC0gJ0dPVFJVRV9KV1RfRVhQPSR7SldUX0VYUElSWTotMzYwMH0nCiAgICAgIC0gJ0dPVFJVRV9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdHT1RSVUVfRVhURVJOQUxfRU1BSUxfRU5BQkxFRD0ke0VOQUJMRV9FTUFJTF9TSUdOVVA6LXRydWV9JwogICAgICAtICdHT1RSVUVfRVhURVJOQUxfQU5PTllNT1VTX1VTRVJTX0VOQUJMRUQ9JHtFTkFCTEVfQU5PTllNT1VTX1VTRVJTOi1mYWxzZX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfQVVUT0NPTkZJUk09JHtFTkFCTEVfRU1BSUxfQVVUT0NPTkZJUk06LWZhbHNlfScKICAgICAgLSAnR09UUlVFX1NNVFBfQURNSU5fRU1BSUw9JHtTTVRQX0FETUlOX0VNQUlMfScKICAgICAgLSAnR09UUlVFX1NNVFBfSE9TVD0ke1NNVFBfSE9TVH0nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX1BPUlQ9JHtTTVRQX1BPUlQ6LTU4N30nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX1VTRVI9JHtTTVRQX1VTRVJ9JwogICAgICAtICdHT1RSVUVfU01UUF9QQVNTPSR7U01UUF9QQVNTfScKICAgICAgLSAnR09UUlVFX1NNVFBfU0VOREVSX05BTUU9JHtTTVRQX1NFTkRFUl9OQU1FfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9VUkxQQVRIU19JTlZJVEU9JHtNQUlMRVJfVVJMUEFUSFNfSU5WSVRFOi0vYXV0aC92MS92ZXJpZnl9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1VSTFBBVEhTX0NPTkZJUk1BVElPTj0ke01BSUxFUl9VUkxQQVRIU19DT05GSVJNQVRJT046LS9hdXRoL3YxL3ZlcmlmeX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVVJMUEFUSFNfUkVDT1ZFUlk9JHtNQUlMRVJfVVJMUEFUSFNfUkVDT1ZFUlk6LS9hdXRoL3YxL3ZlcmlmeX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVVJMUEFUSFNfRU1BSUxfQ0hBTkdFPSR7TUFJTEVSX1VSTFBBVEhTX0VNQUlMX0NIQU5HRTotL2F1dGgvdjEvdmVyaWZ5fScKICAgICAgLSAnR09UUlVFX01BSUxFUl9URU1QTEFURVNfSU5WSVRFPSR7TUFJTEVSX1RFTVBMQVRFU19JTlZJVEV9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1RFTVBMQVRFU19DT05GSVJNQVRJT049JHtNQUlMRVJfVEVNUExBVEVTX0NPTkZJUk1BVElPTn0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVEVNUExBVEVTX1JFQ09WRVJZPSR7TUFJTEVSX1RFTVBMQVRFU19SRUNPVkVSWX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVEVNUExBVEVTX01BR0lDX0xJTks9JHtNQUlMRVJfVEVNUExBVEVTX01BR0lDX0xJTkt9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1RFTVBMQVRFU19FTUFJTF9DSEFOR0U9JHtNQUlMRVJfVEVNUExBVEVTX0VNQUlMX0NIQU5HRX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfU1VCSkVDVFNfQ09ORklSTUFUSU9OPSR7TUFJTEVSX1NVQkpFQ1RTX0NPTkZJUk1BVElPTn0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfU1VCSkVDVFNfUkVDT1ZFUlk9JHtNQUlMRVJfU1VCSkVDVFNfUkVDT1ZFUll9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1NVQkpFQ1RTX01BR0lDX0xJTks9JHtNQUlMRVJfU1VCSkVDVFNfTUFHSUNfTElOS30nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfU1VCSkVDVFNfRU1BSUxfQ0hBTkdFPSR7TUFJTEVSX1NVQkpFQ1RTX0VNQUlMX0NIQU5HRX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfU1VCSkVDVFNfSU5WSVRFPSR7TUFJTEVSX1NVQkpFQ1RTX0lOVklURX0nCiAgICAgIC0gJ0dPVFJVRV9FWFRFUk5BTF9QSE9ORV9FTkFCTEVEPSR7RU5BQkxFX1BIT05FX1NJR05VUDotdHJ1ZX0nCiAgICAgIC0gJ0dPVFJVRV9TTVNfQVVUT0NPTkZJUk09JHtFTkFCTEVfUEhPTkVfQVVUT0NPTkZJUk06LXRydWV9JwogIHJlYWx0aW1lLWRldjoKICAgIGltYWdlOiAnc3VwYWJhc2UvcmVhbHRpbWU6djIuMzAuMjMnCiAgICBjb250YWluZXJfbmFtZTogcmVhbHRpbWUtZGV2LnN1cGFiYXNlLXJlYWx0aW1lCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLXNTZkwnCiAgICAgICAgLSAnLS1oZWFkJwogICAgICAgIC0gJy1vJwogICAgICAgIC0gL2Rldi9udWxsCiAgICAgICAgLSAnLUgnCiAgICAgICAgLSAnQXV0aG9yaXphdGlvbjogQmVhcmVyICR7U0VSVklDRV9TVVBBQkFTRUFOT05fS0VZfScKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjQwMDAvYXBpL3RlbmFudHMvcmVhbHRpbWUtZGV2L2hlYWx0aCcKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPUlQ9NDAwMAogICAgICAtICdEQl9IT1NUPSR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifScKICAgICAgLSAnREJfUE9SVD0ke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9JwogICAgICAtIERCX1VTRVI9c3VwYWJhc2VfYWRtaW4KICAgICAgLSAnREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnREJfTkFNRT0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ0RCX0FGVEVSX0NPTk5FQ1RfUVVFUlk9U0VUIHNlYXJjaF9wYXRoIFRPIF9yZWFsdGltZScKICAgICAgLSBEQl9FTkNfS0VZPXN1cGFiYXNlcmVhbHRpbWUKICAgICAgLSAnQVBJX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gRkxZX0FMTE9DX0lEPWZseTEyMwogICAgICAtIEZMWV9BUFBfTkFNRT1yZWFsdGltZQogICAgICAtICdTRUNSRVRfS0VZX0JBU0U9JHtTRUNSRVRfUEFTU1dPUkRfUkVBTFRJTUV9JwogICAgICAtICdFUkxfQUZMQUdTPS1wcm90b19kaXN0IGluZXRfdGNwJwogICAgICAtIEVOQUJMRV9UQUlMU0NBTEU9ZmFsc2UKICAgICAgLSAiRE5TX05PREVTPScnIgogICAgICAtIFJMSU1JVF9OT0ZJTEU9MTAwMDAKICAgICAgLSBBUFBfTkFNRT1yZWFsdGltZQogICAgICAtIFNFRURfU0VMRl9IT1NUPXRydWUKICAgIGNvbW1hbmQ6ICJzaCAtYyBcIi9hcHAvYmluL21pZ3JhdGUgJiYgL2FwcC9iaW4vcmVhbHRpbWUgZXZhbCAnUmVhbHRpbWUuUmVsZWFzZS5zZWVkcyhSZWFsdGltZS5SZXBvKScgJiYgL2FwcC9iaW4vc2VydmVyXCJcbiIKICBzdXBhYmFzZS1taW5pbzoKICAgIGltYWdlOiBtaW5pby9taW5pbwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ01JTklPX1JPT1RfVVNFUj0ke1NFUlZJQ0VfVVNFUl9NSU5JT30nCiAgICAgIC0gJ01JTklPX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01JTklPfScKICAgIGNvbW1hbmQ6ICdzZXJ2ZXIgLS1jb25zb2xlLWFkZHJlc3MgIjo5MDAxIiAvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OiAnc2xlZXAgNSAmJiBleGl0IDAnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogNQogICAgdm9sdW1lczoKICAgICAgLSAnLi92b2x1bWVzL3N0b3JhZ2U6L2RhdGEnCiAgbWluaW8tY3JlYXRlYnVja2V0OgogICAgaW1hZ2U6IG1pbmlvL21jCiAgICByZXN0YXJ0OiAnbm8nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnTUlOSU9fUk9PVF9VU0VSPSR7U0VSVklDRV9VU0VSX01JTklPfScKICAgICAgLSAnTUlOSU9fUk9PVF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTUlOSU99JwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtbWluaW86CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudHJ5cG9pbnQ6CiAgICAgIC0gL2VudHJ5cG9pbnQuc2gKICAgIHZvbHVtZXM6CiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL2VudHJ5cG9pbnQuc2gKICAgICAgICB0YXJnZXQ6IC9lbnRyeXBvaW50LnNoCiAgICAgICAgY29udGVudDogIiMhL2Jpbi9zaFxuL3Vzci9iaW4vbWMgYWxpYXMgc2V0IHN1cGFiYXNlLW1pbmlvIGh0dHA6Ly9zdXBhYmFzZS1taW5pbzo5MDAwICR7TUlOSU9fUk9PVF9VU0VSfSAke01JTklPX1JPT1RfUEFTU1dPUkR9O1xuL3Vzci9iaW4vbWMgbWIgLS1pZ25vcmUtZXhpc3Rpbmcgc3VwYWJhc2UtbWluaW8vc3R1YjtcbmV4aXQgMFxuIgogIHN1cGFiYXNlLXN0b3JhZ2U6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3N0b3JhZ2UtYXBpOnYxLjAuNicKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLXJlc3Q6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX3N0YXJ0ZWQKICAgICAgaW1ncHJveHk6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX3N0YXJ0ZWQKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1uby12ZXJib3NlJwogICAgICAgIC0gJy0tdHJpZXM9MScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjUwMDAvc3RhdHVzJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVkVSX1BPUlQ9NTAwMAogICAgICAtIFNFUlZFUl9SRUdJT049bG9jYWwKICAgICAgLSBNVUxUSV9URU5BTlQ9ZmFsc2UKICAgICAgLSAnQVVUSF9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly9zdXBhYmFzZV9zdG9yYWdlX2FkbWluOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9OiR7UE9TVEdSRVNfUE9SVDotNTQzMn0vJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtIERCX0lOU1RBTExfUk9MRVM9ZmFsc2UKICAgICAgLSBTVE9SQUdFX0JBQ0tFTkQ9czMKICAgICAgLSBTVE9SQUdFX1MzX0JVQ0tFVD1zdHViCiAgICAgIC0gJ1NUT1JBR0VfUzNfRU5EUE9JTlQ9aHR0cDovL3N1cGFiYXNlLW1pbmlvOjkwMDAnCiAgICAgIC0gU1RPUkFHRV9TM19GT1JDRV9QQVRIX1NUWUxFPXRydWUKICAgICAgLSBTVE9SQUdFX1MzX1JFR0lPTj11cy1lYXN0LTEKICAgICAgLSAnQVdTX0FDQ0VTU19LRVlfSUQ9JHtTRVJWSUNFX1VTRVJfTUlOSU99JwogICAgICAtICdBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX01JTklPfScKICAgICAgLSBVUExPQURfRklMRV9TSVpFX0xJTUlUPTUyNDI4ODAwMAogICAgICAtIFVQTE9BRF9GSUxFX1NJWkVfTElNSVRfU1RBTkRBUkQ9NTI0Mjg4MDAwCiAgICAgIC0gVVBMT0FEX1NJR05FRF9VUkxfRVhQSVJBVElPTl9USU1FPTEyMAogICAgICAtIFRVU19VUkxfUEFUSD0vdXBsb2FkL3Jlc3VtYWJsZQogICAgICAtIFRVU19NQVhfU0laRT0zNjAwMDAwCiAgICAgIC0gSU1BR0VfVFJBTlNGT1JNQVRJT05fRU5BQkxFRD10cnVlCiAgICAgIC0gJ0lNR1BST1hZX1VSTD1odHRwOi8vaW1ncHJveHk6ODA4MCcKICAgICAgLSBJTUdQUk9YWV9SRVFVRVNUX1RJTUVPVVQ9MTUKICAgICAgLSBEQVRBQkFTRV9TRUFSQ0hfUEFUSD1zdG9yYWdlCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvc3RvcmFnZTovdmFyL2xpYi9zdG9yYWdlJwogIGltZ3Byb3h5OgogICAgaW1hZ2U6ICdkYXJ0aHNpbS9pbWdwcm94eTp2My44LjAnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gaW1ncHJveHkKICAgICAgICAtIGhlYWx0aAogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gSU1HUFJPWFlfTE9DQUxfRklMRVNZU1RFTV9ST09UPS8KICAgICAgLSBJTUdQUk9YWV9VU0VfRVRBRz10cnVlCiAgICAgIC0gJ0lNR1BST1hZX0VOQUJMRV9XRUJQX0RFVEVDVElPTj0ke0lNR1BST1hZX0VOQUJMRV9XRUJQX0RFVEVDVElPTjotdHJ1ZX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvc3RvcmFnZTovdmFyL2xpYi9zdG9yYWdlJwogIHN1cGFiYXNlLW1ldGE6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3Bvc3RncmVzLW1ldGE6djAuODMuMicKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUEdfTUVUQV9QT1JUPTgwODAKICAgICAgLSAnUEdfTUVUQV9EQl9IT1NUPSR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifScKICAgICAgLSAnUEdfTUVUQV9EQl9QT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gJ1BHX01FVEFfREJfTkFNRT0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gUEdfTUVUQV9EQl9VU0VSPXN1cGFiYXNlX2FkbWluCiAgICAgIC0gJ1BHX01FVEFfREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICBzdXBhYmFzZS1lZGdlLWZ1bmN0aW9uczoKICAgIGltYWdlOiAnc3VwYWJhc2UvZWRnZS1ydW50aW1lOnYxLjUzLjMnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBlY2hvCiAgICAgICAgLSAnRWRnZSBGdW5jdGlvbnMgaXMgaGVhbHRoeScKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdTVVBBQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fU1VQQUJBU0VLT05HfScKICAgICAgLSAnU1VQQUJBU0VfQU5PTl9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAtICdTVVBBQkFTRV9TRVJWSUNFX1JPTEVfS0VZPSR7U0VSVklDRV9TVVBBQkFTRVNFUlZJQ0VfS0VZfScKICAgICAgLSAnU1VQQUJBU0VfREJfVVJMPXBvc3RncmVzcWw6Ly9wb3N0Z3Jlczoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnVkVSSUZZX0pXVD0ke0ZVTkNUSU9OU19WRVJJRllfSldUOi1mYWxzZX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvZnVuY3Rpb25zOi9ob21lL2Rlbm8vZnVuY3Rpb25zJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2Z1bmN0aW9ucy9tYWluL2luZGV4LnRzCiAgICAgICAgdGFyZ2V0OiAvaG9tZS9kZW5vL2Z1bmN0aW9ucy9tYWluL2luZGV4LnRzCiAgICAgICAgY29udGVudDogImltcG9ydCB7IHNlcnZlIH0gZnJvbSAnaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTMxLjAvaHR0cC9zZXJ2ZXIudHMnXG5pbXBvcnQgKiBhcyBqb3NlIGZyb20gJ2h0dHBzOi8vZGVuby5sYW5kL3gvam9zZUB2NC4xNC40L2luZGV4LnRzJ1xuXG5jb25zb2xlLmxvZygnbWFpbiBmdW5jdGlvbiBzdGFydGVkJylcblxuY29uc3QgSldUX1NFQ1JFVCA9IERlbm8uZW52LmdldCgnSldUX1NFQ1JFVCcpXG5jb25zdCBWRVJJRllfSldUID0gRGVuby5lbnYuZ2V0KCdWRVJJRllfSldUJykgPT09ICd0cnVlJ1xuXG5mdW5jdGlvbiBnZXRBdXRoVG9rZW4ocmVxOiBSZXF1ZXN0KSB7XG4gIGNvbnN0IGF1dGhIZWFkZXIgPSByZXEuaGVhZGVycy5nZXQoJ2F1dGhvcml6YXRpb24nKVxuICBpZiAoIWF1dGhIZWFkZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgYXV0aG9yaXphdGlvbiBoZWFkZXInKVxuICB9XG4gIGNvbnN0IFtiZWFyZXIsIHRva2VuXSA9IGF1dGhIZWFkZXIuc3BsaXQoJyAnKVxuICBpZiAoYmVhcmVyICE9PSAnQmVhcmVyJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgQXV0aCBoZWFkZXIgaXMgbm90ICdCZWFyZXIge3Rva2VufSdgKVxuICB9XG4gIHJldHVybiB0b2tlblxufVxuXG5hc3luYyBmdW5jdGlvbiB2ZXJpZnlKV1Qoand0OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpXG4gIGNvbnN0IHNlY3JldEtleSA9IGVuY29kZXIuZW5jb2RlKEpXVF9TRUNSRVQpXG4gIHRyeSB7XG4gICAgYXdhaXQgam9zZS5qd3RWZXJpZnkoand0LCBzZWNyZXRLZXkpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNvbnNvbGUuZXJyb3IoZXJyKVxuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbnNlcnZlKGFzeW5jIChyZXE6IFJlcXVlc3QpID0+IHtcbiAgaWYgKHJlcS5tZXRob2QgIT09ICdPUFRJT05TJyAmJiBWRVJJRllfSldUKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRva2VuID0gZ2V0QXV0aFRva2VuKHJlcSlcbiAgICAgIGNvbnN0IGlzVmFsaWRKV1QgPSBhd2FpdCB2ZXJpZnlKV1QodG9rZW4pXG5cbiAgICAgIGlmICghaXNWYWxpZEpXVCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KHsgbXNnOiAnSW52YWxpZCBKV1QnIH0pLCB7XG4gICAgICAgICAgc3RhdHVzOiA0MDEsXG4gICAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcihlKVxuICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShKU09OLnN0cmluZ2lmeSh7IG1zZzogZS50b1N0cmluZygpIH0pLCB7XG4gICAgICAgIHN0YXR1czogNDAxLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgY29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsKVxuICBjb25zdCB7IHBhdGhuYW1lIH0gPSB1cmxcbiAgY29uc3QgcGF0aF9wYXJ0cyA9IHBhdGhuYW1lLnNwbGl0KCcvJylcbiAgY29uc3Qgc2VydmljZV9uYW1lID0gcGF0aF9wYXJ0c1sxXVxuXG4gIGlmICghc2VydmljZV9uYW1lIHx8IHNlcnZpY2VfbmFtZSA9PT0gJycpIHtcbiAgICBjb25zdCBlcnJvciA9IHsgbXNnOiAnbWlzc2luZyBmdW5jdGlvbiBuYW1lIGluIHJlcXVlc3QnIH1cbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KGVycm9yKSwge1xuICAgICAgc3RhdHVzOiA0MDAsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICB9KVxuICB9XG5cbiAgY29uc3Qgc2VydmljZVBhdGggPSBgL2hvbWUvZGVuby9mdW5jdGlvbnMvJHtzZXJ2aWNlX25hbWV9YFxuICBjb25zb2xlLmVycm9yKGBzZXJ2aW5nIHRoZSByZXF1ZXN0IHdpdGggJHtzZXJ2aWNlUGF0aH1gKVxuXG4gIGNvbnN0IG1lbW9yeUxpbWl0TWIgPSAxNTBcbiAgY29uc3Qgd29ya2VyVGltZW91dE1zID0gMSAqIDYwICogMTAwMFxuICBjb25zdCBub01vZHVsZUNhY2hlID0gZmFsc2VcbiAgY29uc3QgaW1wb3J0TWFwUGF0aCA9IG51bGxcbiAgY29uc3QgZW52VmFyc09iaiA9IERlbm8uZW52LnRvT2JqZWN0KClcbiAgY29uc3QgZW52VmFycyA9IE9iamVjdC5rZXlzKGVudlZhcnNPYmopLm1hcCgoaykgPT4gW2ssIGVudlZhcnNPYmpba11dKVxuXG4gIHRyeSB7XG4gICAgY29uc3Qgd29ya2VyID0gYXdhaXQgRWRnZVJ1bnRpbWUudXNlcldvcmtlcnMuY3JlYXRlKHtcbiAgICAgIHNlcnZpY2VQYXRoLFxuICAgICAgbWVtb3J5TGltaXRNYixcbiAgICAgIHdvcmtlclRpbWVvdXRNcyxcbiAgICAgIG5vTW9kdWxlQ2FjaGUsXG4gICAgICBpbXBvcnRNYXBQYXRoLFxuICAgICAgZW52VmFycyxcbiAgICB9KVxuICAgIHJldHVybiBhd2FpdCB3b3JrZXIuZmV0Y2gocmVxKVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc3QgZXJyb3IgPSB7IG1zZzogZS50b1N0cmluZygpIH1cbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KGVycm9yKSwge1xuICAgICAgc3RhdHVzOiA1MDAsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICB9KVxuICB9XG59KSIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9mdW5jdGlvbnMvaGVsbG8vaW5kZXgudHMKICAgICAgICB0YXJnZXQ6IC9ob21lL2Rlbm8vZnVuY3Rpb25zL2hlbGxvL2luZGV4LnRzCiAgICAgICAgY29udGVudDogIi8vIEZvbGxvdyB0aGlzIHNldHVwIGd1aWRlIHRvIGludGVncmF0ZSB0aGUgRGVubyBsYW5ndWFnZSBzZXJ2ZXIgd2l0aCB5b3VyIGVkaXRvcjpcbi8vIGh0dHBzOi8vZGVuby5sYW5kL21hbnVhbC9nZXR0aW5nX3N0YXJ0ZWQvc2V0dXBfeW91cl9lbnZpcm9ubWVudFxuLy8gVGhpcyBlbmFibGVzIGF1dG9jb21wbGV0ZSwgZ28gdG8gZGVmaW5pdGlvbiwgZXRjLlxuXG5pbXBvcnQgeyBzZXJ2ZSB9IGZyb20gXCJodHRwczovL2Rlbm8ubGFuZC9zdGRAMC4xNzcuMS9odHRwL3NlcnZlci50c1wiXG5cbnNlcnZlKGFzeW5jICgpID0+IHtcbiAgcmV0dXJuIG5ldyBSZXNwb25zZShcbiAgICBgXCJIZWxsbyBmcm9tIEVkZ2UgRnVuY3Rpb25zIVwiYCxcbiAgICB7IGhlYWRlcnM6IHsgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSB9LFxuICApXG59KVxuXG4vLyBUbyBpbnZva2U6XG4vLyBjdXJsICdodHRwOi8vbG9jYWxob3N0OjxLT05HX0hUVFBfUE9SVD4vZnVuY3Rpb25zL3YxL2hlbGxvJyBcXFxuLy8gICAtLWhlYWRlciAnQXV0aG9yaXphdGlvbjogQmVhcmVyIDxhbm9uL3NlcnZpY2Vfcm9sZSBBUEkga2V5PidcbiIKICAgIGNvbW1hbmQ6CiAgICAgIC0gc3RhcnQKICAgICAgLSAnLS1tYWluLXNlcnZpY2UnCiAgICAgIC0gL2hvbWUvZGVuby9mdW5jdGlvbnMvbWFpbgo=", + "compose": "c2VydmljZXM6CiAgc3VwYWJhc2Uta29uZzoKICAgIGltYWdlOiAna29uZzoyLjguMScKICAgIGVudHJ5cG9pbnQ6ICdiYXNoIC1jICcnZXZhbCAiZWNobyBcIiQkKGNhdCB+L3RlbXAueW1sKVwiIiA+IH4va29uZy55bWwgJiYgL2RvY2tlci1lbnRyeXBvaW50LnNoIGtvbmcgZG9ja2VyLXN0YXJ0JycnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9TVVBBQkFTRUtPTkdfODAwMAogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIEtPTkdfREFUQUJBU0U9b2ZmCiAgICAgIC0gS09OR19ERUNMQVJBVElWRV9DT05GSUc9L2hvbWUva29uZy9rb25nLnltbAogICAgICAtICdLT05HX0ROU19PUkRFUj1MQVNULEEsQ05BTUUnCiAgICAgIC0gJ0tPTkdfUExVR0lOUz1yZXF1ZXN0LXRyYW5zZm9ybWVyLGNvcnMsa2V5LWF1dGgsYWNsLGJhc2ljLWF1dGgnCiAgICAgIC0gS09OR19OR0lOWF9QUk9YWV9QUk9YWV9CVUZGRVJfU0laRT0xNjBrCiAgICAgIC0gJ0tPTkdfTkdJTlhfUFJPWFlfUFJPWFlfQlVGRkVSUz02NCAxNjBrJwogICAgICAtICdTVVBBQkFTRV9BTk9OX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VBTk9OX0tFWX0nCiAgICAgIC0gJ1NVUEFCQVNFX1NFUlZJQ0VfS0VZPSR7U0VSVklDRV9TVVBBQkFTRVNFUlZJQ0VfS0VZfScKICAgICAgLSAnREFTSEJPQVJEX1VTRVJOQU1FPSR7U0VSVklDRV9VU0VSX0FETUlOfScKICAgICAgLSAnREFTSEJPQVJEX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0nCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2FwaS9rb25nLnltbAogICAgICAgIHRhcmdldDogL2hvbWUva29uZy90ZW1wLnltbAogICAgICAgIGNvbnRlbnQ6ICJfZm9ybWF0X3ZlcnNpb246ICcyLjEnXG5fdHJhbnNmb3JtOiB0cnVlXG5cbiMjI1xuIyMjIENvbnN1bWVycyAvIFVzZXJzXG4jIyNcbmNvbnN1bWVyczpcbiAgLSB1c2VybmFtZTogREFTSEJPQVJEXG4gIC0gdXNlcm5hbWU6IGFub25cbiAgICBrZXlhdXRoX2NyZWRlbnRpYWxzOlxuICAgICAgLSBrZXk6ICRTVVBBQkFTRV9BTk9OX0tFWVxuICAtIHVzZXJuYW1lOiBzZXJ2aWNlX3JvbGVcbiAgICBrZXlhdXRoX2NyZWRlbnRpYWxzOlxuICAgICAgLSBrZXk6ICRTVVBBQkFTRV9TRVJWSUNFX0tFWVxuXG4jIyNcbiMjIyBBY2Nlc3MgQ29udHJvbCBMaXN0XG4jIyNcbmFjbHM6XG4gIC0gY29uc3VtZXI6IGFub25cbiAgICBncm91cDogYW5vblxuICAtIGNvbnN1bWVyOiBzZXJ2aWNlX3JvbGVcbiAgICBncm91cDogYWRtaW5cblxuIyMjXG4jIyMgRGFzaGJvYXJkIGNyZWRlbnRpYWxzXG4jIyNcbmJhc2ljYXV0aF9jcmVkZW50aWFsczpcbi0gY29uc3VtZXI6IERBU0hCT0FSRFxuICB1c2VybmFtZTogJERBU0hCT0FSRF9VU0VSTkFNRVxuICBwYXNzd29yZDogJERBU0hCT0FSRF9QQVNTV09SRFxuXG5cbiMjI1xuIyMjIEFQSSBSb3V0ZXNcbiMjI1xuc2VydmljZXM6XG5cbiAgIyMgT3BlbiBBdXRoIHJvdXRlc1xuICAtIG5hbWU6IGF1dGgtdjEtb3BlblxuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS92ZXJpZnlcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtb3BlblxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2F1dGgvdjEvdmVyaWZ5XG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAtIG5hbWU6IGF1dGgtdjEtb3Blbi1jYWxsYmFja1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS9jYWxsYmFja1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYXV0aC12MS1vcGVuLWNhbGxiYWNrXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvYXV0aC92MS9jYWxsYmFja1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgLSBuYW1lOiBhdXRoLXYxLW9wZW4tYXV0aG9yaXplXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtYXV0aDo5OTk5L2F1dGhvcml6ZVxuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYXV0aC12MS1vcGVuLWF1dGhvcml6ZVxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2F1dGgvdjEvYXV0aG9yaXplXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuXG4gICMjIFNlY3VyZSBBdXRoIHJvdXRlc1xuICAtIG5hbWU6IGF1dGgtdjFcbiAgICBfY29tbWVudDogJ0dvVHJ1ZTogL2F1dGgvdjEvKiAtPiBodHRwOi8vc3VwYWJhc2UtYXV0aDo5OTk5LyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtYXV0aDo5OTk5L1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYXV0aC12MS1hbGxcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9hdXRoL3YxL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IGZhbHNlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cblxuICAjIyBTZWN1cmUgUkVTVCByb3V0ZXNcbiAgLSBuYW1lOiByZXN0LXYxXG4gICAgX2NvbW1lbnQ6ICdQb3N0Z1JFU1Q6IC9yZXN0L3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLXJlc3Q6MzAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLXJlc3Q6MzAwMC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHJlc3QtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcmVzdC92MS9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiB0cnVlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cblxuICAjIyBTZWN1cmUgR3JhcGhRTCByb3V0ZXNcbiAgLSBuYW1lOiBncmFwaHFsLXYxXG4gICAgX2NvbW1lbnQ6ICdQb3N0Z1JFU1Q6IC9ncmFwaHFsL3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLXJlc3Q6MzAwMC9ycGMvZ3JhcGhxbCdcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvcnBjL2dyYXBocWxcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGdyYXBocWwtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvZ3JhcGhxbC92MVxuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IHRydWVcbiAgICAgIC0gbmFtZTogcmVxdWVzdC10cmFuc2Zvcm1lclxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgYWRkOlxuICAgICAgICAgICAgaGVhZGVyczpcbiAgICAgICAgICAgICAgLSBDb250ZW50LVByb2ZpbGU6Z3JhcGhxbF9wdWJsaWNcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cbiAgICAgICAgICAgIC0gYW5vblxuXG4gICMjIFNlY3VyZSBSZWFsdGltZSByb3V0ZXNcbiAgLSBuYW1lOiByZWFsdGltZS12MS13c1xuICAgIF9jb21tZW50OiAnUmVhbHRpbWU6IC9yZWFsdGltZS92MS8qIC0+IHdzOi8vcmVhbHRpbWU6NDAwMC9zb2NrZXQvKidcbiAgICB1cmw6IGh0dHA6Ly9yZWFsdGltZS1kZXY6NDAwMC9zb2NrZXRcbiAgICBwcm90b2NvbDogd3NcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHJlYWx0aW1lLXYxLXdzXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcmVhbHRpbWUvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogZmFsc2VcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cbiAgICAgICAgICAgIC0gYW5vblxuICAtIG5hbWU6IHJlYWx0aW1lLXYxLXJlc3RcbiAgICBfY29tbWVudDogJ1JlYWx0aW1lOiAvcmVhbHRpbWUvdjEvKiAtPiB3czovL3JlYWx0aW1lOjQwMDAvc29ja2V0LyonXG4gICAgdXJsOiBodHRwOi8vcmVhbHRpbWUtZGV2OjQwMDAvYXBpXG4gICAgcHJvdG9jb2w6IGh0dHBcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHJlYWx0aW1lLXYxLXJlc3RcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9yZWFsdGltZS92MS9hcGlcbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiBmYWxzZVxuICAgICAgLSBuYW1lOiBhY2xcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfZ3JvdXBzX2hlYWRlcjogdHJ1ZVxuICAgICAgICAgIGFsbG93OlxuICAgICAgICAgICAgLSBhZG1pblxuICAgICAgICAgICAgLSBhbm9uXG5cbiAgIyMgU3RvcmFnZSByb3V0ZXM6IHRoZSBzdG9yYWdlIHNlcnZlciBtYW5hZ2VzIGl0cyBvd24gYXV0aFxuICAtIG5hbWU6IHN0b3JhZ2UtdjFcbiAgICBfY29tbWVudDogJ1N0b3JhZ2U6IC9zdG9yYWdlL3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLXN0b3JhZ2U6NTAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLXN0b3JhZ2U6NTAwMC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHN0b3JhZ2UtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvc3RvcmFnZS92MS9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG5cbiAgIyMgRWRnZSBGdW5jdGlvbnMgcm91dGVzXG4gIC0gbmFtZTogZnVuY3Rpb25zLXYxXG4gICAgX2NvbW1lbnQ6ICdFZGdlIEZ1bmN0aW9uczogL2Z1bmN0aW9ucy92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1lZGdlLWZ1bmN0aW9uczo5MDAwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtZWRnZS1mdW5jdGlvbnM6OTAwMC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGZ1bmN0aW9ucy12MS1hbGxcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9mdW5jdGlvbnMvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuXG4gICMjIEFuYWx5dGljcyByb3V0ZXNcbiAgLSBuYW1lOiBhbmFseXRpY3MtdjFcbiAgICBfY29tbWVudDogJ0FuYWx5dGljczogL2FuYWx5dGljcy92MS8qIC0+IGh0dHA6Ly9sb2dmbGFyZTo0MDAwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBhbmFseXRpY3MtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvYW5hbHl0aWNzL3YxL1xuXG4gICMjIFNlY3VyZSBEYXRhYmFzZSByb3V0ZXNcbiAgLSBuYW1lOiBtZXRhXG4gICAgX2NvbW1lbnQ6ICdwZy1tZXRhOiAvcGcvKiAtPiBodHRwOi8vc3VwYWJhc2UtbWV0YTo4MDgwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtbWV0YTo4MDgwL1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogbWV0YS1hbGxcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9wZy9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogZmFsc2VcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cblxuICAjIyBQcm90ZWN0ZWQgRGFzaGJvYXJkIC0gY2F0Y2ggYWxsIHJlbWFpbmluZyByb3V0ZXNcbiAgLSBuYW1lOiBkYXNoYm9hcmRcbiAgICBfY29tbWVudDogJ1N0dWRpbzogLyogLT4gaHR0cDovL3N0dWRpbzozMDAwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2Utc3R1ZGlvOjMwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBkYXNoYm9hcmQtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBiYXNpYy1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiB0cnVlXG4iCiAgc3VwYWJhc2Utc3R1ZGlvOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9zdHVkaW86MjAyNDA5MjMtMmUzZTkwYycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBub2RlCiAgICAgICAgLSAnLWUnCiAgICAgICAgLSAicmVxdWlyZSgnaHR0cCcpLmdldCgnaHR0cDovLzEyNy4wLjAuMTozMDAwL2FwaS9wcm9maWxlJywgKHIpID0+IHtpZiAoci5zdGF0dXNDb2RlICE9PSAyMDApIHByb2Nlc3MuZXhpdCgxKTsgZWxzZSBwcm9jZXNzLmV4aXQoMCk7IH0pLm9uKCdlcnJvcicsICgpID0+IHByb2Nlc3MuZXhpdCgxKSkiCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAzCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIEhPU1ROQU1FPTAuMC4wLjAKICAgICAgLSAnU1RVRElPX1BHX01FVEFfVVJMPWh0dHA6Ly9zdXBhYmFzZS1tZXRhOjgwODAnCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ0RFRkFVTFRfT1JHQU5JWkFUSU9OX05BTUU9JHtTVFVESU9fREVGQVVMVF9PUkdBTklaQVRJT046LURlZmF1bHQgT3JnYW5pemF0aW9ufScKICAgICAgLSAnREVGQVVMVF9QUk9KRUNUX05BTUU9JHtTVFVESU9fREVGQVVMVF9QUk9KRUNUOi1EZWZhdWx0IFByb2plY3R9JwogICAgICAtICdTVVBBQkFTRV9VUkw9aHR0cDovL3N1cGFiYXNlLWtvbmc6ODAwMCcKICAgICAgLSAnU1VQQUJBU0VfUFVCTElDX1VSTD0ke1NFUlZJQ0VfRlFETl9TVVBBQkFTRUtPTkd9JwogICAgICAtICdTVVBBQkFTRV9BTk9OX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VBTk9OX0tFWX0nCiAgICAgIC0gJ1NVUEFCQVNFX1NFUlZJQ0VfS0VZPSR7U0VSVklDRV9TVVBBQkFTRVNFUlZJQ0VfS0VZfScKICAgICAgLSAnQVVUSF9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdMT0dGTEFSRV9BUElfS0VZPSR7U0VSVklDRV9QQVNTV09SRF9MT0dGTEFSRX0nCiAgICAgIC0gJ0xPR0ZMQVJFX1VSTD1odHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAnCiAgICAgIC0gJ1NVUEFCQVNFX1BVQkxJQ19BUEk9JHtTRVJWSUNFX0ZRRE5fU1VQQUJBU0VLT05HfScKICAgICAgLSBORVhUX1BVQkxJQ19FTkFCTEVfTE9HUz10cnVlCiAgICAgIC0gTkVYVF9BTkFMWVRJQ1NfQkFDS0VORF9QUk9WSURFUj1wb3N0Z3JlcwogIHN1cGFiYXNlLWRiOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9wb3N0Z3JlczoxNS4xLjEuNzgnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDogJ3BnX2lzcmVhZHkgLVUgcG9zdGdyZXMgLWggMTI3LjAuMC4xJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLXZlY3RvcjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgY29tbWFuZDoKICAgICAgLSBwb3N0Z3JlcwogICAgICAtICctYycKICAgICAgLSBjb25maWdfZmlsZT0vZXRjL3Bvc3RncmVzcWwvcG9zdGdyZXNxbC5jb25mCiAgICAgIC0gJy1jJwogICAgICAtIGxvZ19taW5fbWVzc2FnZXM9ZmF0YWwKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPU1RHUkVTX0hPU1Q9L3Zhci9ydW4vcG9zdGdyZXNxbAogICAgICAtICdQR1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUE9TVEdSRVNfUE9SVD0ke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9JwogICAgICAtICdQR1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BHREFUQUJBU0U9JHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ0pXVF9FWFA9JHtKV1RfRVhQSVJZOi0zNjAwfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3N1cGFiYXNlLWRiLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2RiL3JlYWx0aW1lLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTktcmVhbHRpbWUuc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IHBndXNlciBgZWNobyBcInN1cGFiYXNlX2FkbWluXCJgXG5cbmNyZWF0ZSBzY2hlbWEgaWYgbm90IGV4aXN0cyBfcmVhbHRpbWU7XG5hbHRlciBzY2hlbWEgX3JlYWx0aW1lIG93bmVyIHRvIDpwZ3VzZXI7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvX3N1cGFiYXNlLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTctX3N1cGFiYXNlLnNxbAogICAgICAgIGNvbnRlbnQ6ICJcXHNldCBwZ3VzZXIgYGVjaG8gXCIkUE9TVEdSRVNfVVNFUlwiYFxuXG5DUkVBVEUgREFUQUJBU0UgX3N1cGFiYXNlIFdJVEggT1dORVIgOnBndXNlcjtcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9wb29sZXIuc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvbWlncmF0aW9ucy85OS1wb29sZXIuc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IHBndXNlciBgZWNobyBcInN1cGFiYXNlX2FkbWluXCJgXG5cXGMgX3N1cGFiYXNlXG5jcmVhdGUgc2NoZW1hIGlmIG5vdCBleGlzdHMgX3N1cGF2aXNvcjtcbmFsdGVyIHNjaGVtYSBfc3VwYXZpc29yIG93bmVyIHRvIDpwZ3VzZXI7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvd2ViaG9va3Muc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvaW5pdC1zY3JpcHRzLzk4LXdlYmhvb2tzLnNxbAogICAgICAgIGNvbnRlbnQ6ICJCRUdJTjtcbi0tIENyZWF0ZSBwZ19uZXQgZXh0ZW5zaW9uXG5DUkVBVEUgRVhURU5TSU9OIElGIE5PVCBFWElTVFMgcGdfbmV0IFNDSEVNQSBleHRlbnNpb25zO1xuLS0gQ3JlYXRlIHN1cGFiYXNlX2Z1bmN0aW9ucyBzY2hlbWFcbkNSRUFURSBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIEFVVEhPUklaQVRJT04gc3VwYWJhc2VfYWRtaW47XG5HUkFOVCBVU0FHRSBPTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gVEFCTEVTIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gRlVOQ1RJT05TIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gU0VRVUVOQ0VTIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4tLSBzdXBhYmFzZV9mdW5jdGlvbnMubWlncmF0aW9ucyBkZWZpbml0aW9uXG5DUkVBVEUgVEFCTEUgc3VwYWJhc2VfZnVuY3Rpb25zLm1pZ3JhdGlvbnMgKFxuICB2ZXJzaW9uIHRleHQgUFJJTUFSWSBLRVksXG4gIGluc2VydGVkX2F0IHRpbWVzdGFtcHR6IE5PVCBOVUxMIERFRkFVTFQgTk9XKClcbik7XG4tLSBJbml0aWFsIHN1cGFiYXNlX2Z1bmN0aW9ucyBtaWdyYXRpb25cbklOU0VSVCBJTlRPIHN1cGFiYXNlX2Z1bmN0aW9ucy5taWdyYXRpb25zICh2ZXJzaW9uKSBWQUxVRVMgKCdpbml0aWFsJyk7XG4tLSBzdXBhYmFzZV9mdW5jdGlvbnMuaG9va3MgZGVmaW5pdGlvblxuQ1JFQVRFIFRBQkxFIHN1cGFiYXNlX2Z1bmN0aW9ucy5ob29rcyAoXG4gIGlkIGJpZ3NlcmlhbCBQUklNQVJZIEtFWSxcbiAgaG9va190YWJsZV9pZCBpbnRlZ2VyIE5PVCBOVUxMLFxuICBob29rX25hbWUgdGV4dCBOT1QgTlVMTCxcbiAgY3JlYXRlZF9hdCB0aW1lc3RhbXB0eiBOT1QgTlVMTCBERUZBVUxUIE5PVygpLFxuICByZXF1ZXN0X2lkIGJpZ2ludFxuKTtcbkNSRUFURSBJTkRFWCBzdXBhYmFzZV9mdW5jdGlvbnNfaG9va3NfcmVxdWVzdF9pZF9pZHggT04gc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIFVTSU5HIGJ0cmVlIChyZXF1ZXN0X2lkKTtcbkNSRUFURSBJTkRFWCBzdXBhYmFzZV9mdW5jdGlvbnNfaG9va3NfaF90YWJsZV9pZF9oX25hbWVfaWR4IE9OIHN1cGFiYXNlX2Z1bmN0aW9ucy5ob29rcyBVU0lORyBidHJlZSAoaG9va190YWJsZV9pZCwgaG9va19uYW1lKTtcbkNPTU1FTlQgT04gVEFCTEUgc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIElTICdTdXBhYmFzZSBGdW5jdGlvbnMgSG9va3M6IEF1ZGl0IHRyYWlsIGZvciB0cmlnZ2VyZWQgaG9va3MuJztcbkNSRUFURSBGVU5DVElPTiBzdXBhYmFzZV9mdW5jdGlvbnMuaHR0cF9yZXF1ZXN0KClcbiAgUkVUVVJOUyB0cmlnZ2VyXG4gIExBTkdVQUdFIHBscGdzcWxcbiAgQVMgJGZ1bmN0aW9uJFxuICBERUNMQVJFXG4gICAgcmVxdWVzdF9pZCBiaWdpbnQ7XG4gICAgcGF5bG9hZCBqc29uYjtcbiAgICB1cmwgdGV4dCA6PSBUR19BUkdWWzBdOjp0ZXh0O1xuICAgIG1ldGhvZCB0ZXh0IDo9IFRHX0FSR1ZbMV06OnRleHQ7XG4gICAgaGVhZGVycyBqc29uYiBERUZBVUxUICd7fSc6Ompzb25iO1xuICAgIHBhcmFtcyBqc29uYiBERUZBVUxUICd7fSc6Ompzb25iO1xuICAgIHRpbWVvdXRfbXMgaW50ZWdlciBERUZBVUxUIDEwMDA7XG4gIEJFR0lOXG4gICAgSUYgdXJsIElTIE5VTEwgT1IgdXJsID0gJ251bGwnIFRIRU5cbiAgICAgIFJBSVNFIEVYQ0VQVElPTiAndXJsIGFyZ3VtZW50IGlzIG1pc3NpbmcnO1xuICAgIEVORCBJRjtcblxuICAgIElGIG1ldGhvZCBJUyBOVUxMIE9SIG1ldGhvZCA9ICdudWxsJyBUSEVOXG4gICAgICBSQUlTRSBFWENFUFRJT04gJ21ldGhvZCBhcmd1bWVudCBpcyBtaXNzaW5nJztcbiAgICBFTkQgSUY7XG5cbiAgICBJRiBUR19BUkdWWzJdIElTIE5VTEwgT1IgVEdfQVJHVlsyXSA9ICdudWxsJyBUSEVOXG4gICAgICBoZWFkZXJzID0gJ3tcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIn0nOjpqc29uYjtcbiAgICBFTFNFXG4gICAgICBoZWFkZXJzID0gVEdfQVJHVlsyXTo6anNvbmI7XG4gICAgRU5EIElGO1xuXG4gICAgSUYgVEdfQVJHVlszXSBJUyBOVUxMIE9SIFRHX0FSR1ZbM10gPSAnbnVsbCcgVEhFTlxuICAgICAgcGFyYW1zID0gJ3t9Jzo6anNvbmI7XG4gICAgRUxTRVxuICAgICAgcGFyYW1zID0gVEdfQVJHVlszXTo6anNvbmI7XG4gICAgRU5EIElGO1xuXG4gICAgSUYgVEdfQVJHVls0XSBJUyBOVUxMIE9SIFRHX0FSR1ZbNF0gPSAnbnVsbCcgVEhFTlxuICAgICAgdGltZW91dF9tcyA9IDEwMDA7XG4gICAgRUxTRVxuICAgICAgdGltZW91dF9tcyA9IFRHX0FSR1ZbNF06OmludGVnZXI7XG4gICAgRU5EIElGO1xuXG4gICAgQ0FTRVxuICAgICAgV0hFTiBtZXRob2QgPSAnR0VUJyBUSEVOXG4gICAgICAgIFNFTEVDVCBodHRwX2dldCBJTlRPIHJlcXVlc3RfaWQgRlJPTSBuZXQuaHR0cF9nZXQoXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgIHRpbWVvdXRfbXNcbiAgICAgICAgKTtcbiAgICAgIFdIRU4gbWV0aG9kID0gJ1BPU1QnIFRIRU5cbiAgICAgICAgcGF5bG9hZCA9IGpzb25iX2J1aWxkX29iamVjdChcbiAgICAgICAgICAnb2xkX3JlY29yZCcsIE9MRCxcbiAgICAgICAgICAncmVjb3JkJywgTkVXLFxuICAgICAgICAgICd0eXBlJywgVEdfT1AsXG4gICAgICAgICAgJ3RhYmxlJywgVEdfVEFCTEVfTkFNRSxcbiAgICAgICAgICAnc2NoZW1hJywgVEdfVEFCTEVfU0NIRU1BXG4gICAgICAgICk7XG5cbiAgICAgICAgU0VMRUNUIGh0dHBfcG9zdCBJTlRPIHJlcXVlc3RfaWQgRlJPTSBuZXQuaHR0cF9wb3N0KFxuICAgICAgICAgIHVybCxcbiAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgIHRpbWVvdXRfbXNcbiAgICAgICAgKTtcbiAgICAgIEVMU0VcbiAgICAgICAgUkFJU0UgRVhDRVBUSU9OICdtZXRob2QgYXJndW1lbnQgJSBpcyBpbnZhbGlkJywgbWV0aG9kO1xuICAgIEVORCBDQVNFO1xuXG4gICAgSU5TRVJUIElOVE8gc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzXG4gICAgICAoaG9va190YWJsZV9pZCwgaG9va19uYW1lLCByZXF1ZXN0X2lkKVxuICAgIFZBTFVFU1xuICAgICAgKFRHX1JFTElELCBUR19OQU1FLCByZXF1ZXN0X2lkKTtcblxuICAgIFJFVFVSTiBORVc7XG4gIEVORFxuJGZ1bmN0aW9uJDtcbi0tIFN1cGFiYXNlIHN1cGVyIGFkbWluXG5ET1xuJCRcbkJFR0lOXG4gIElGIE5PVCBFWElTVFMgKFxuICAgIFNFTEVDVCAxXG4gICAgRlJPTSBwZ19yb2xlc1xuICAgIFdIRVJFIHJvbG5hbWUgPSAnc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluJ1xuICApXG4gIFRIRU5cbiAgICBDUkVBVEUgVVNFUiBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4gTk9JTkhFUklUIENSRUFURVJPTEUgTE9HSU4gTk9SRVBMSUNBVElPTjtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbkdSQU5UIEFMTCBQUklWSUxFR0VTIE9OIFNDSEVNQSBzdXBhYmFzZV9mdW5jdGlvbnMgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gQUxMIFRBQkxFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkdSQU5UIEFMTCBQUklWSUxFR0VTIE9OIEFMTCBTRVFVRU5DRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5BTFRFUiBVU0VSIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBTRVQgc2VhcmNoX3BhdGggPSBcInN1cGFiYXNlX2Z1bmN0aW9uc1wiO1xuQUxURVIgdGFibGUgXCJzdXBhYmFzZV9mdW5jdGlvbnNcIi5taWdyYXRpb25zIE9XTkVSIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkFMVEVSIHRhYmxlIFwic3VwYWJhc2VfZnVuY3Rpb25zXCIuaG9va3MgT1dORVIgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuQUxURVIgZnVuY3Rpb24gXCJzdXBhYmFzZV9mdW5jdGlvbnNcIi5odHRwX3JlcXVlc3QoKSBPV05FUiBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5HUkFOVCBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4gVE8gcG9zdGdyZXM7XG4tLSBSZW1vdmUgdW51c2VkIHN1cGFiYXNlX3BnX25ldF9hZG1pbiByb2xlXG5ET1xuJCRcbkJFR0lOXG4gIElGIEVYSVNUUyAoXG4gICAgU0VMRUNUIDFcbiAgICBGUk9NIHBnX3JvbGVzXG4gICAgV0hFUkUgcm9sbmFtZSA9ICdzdXBhYmFzZV9wZ19uZXRfYWRtaW4nXG4gIClcbiAgVEhFTlxuICAgIFJFQVNTSUdOIE9XTkVEIEJZIHN1cGFiYXNlX3BnX25ldF9hZG1pbiBUTyBzdXBhYmFzZV9hZG1pbjtcbiAgICBEUk9QIE9XTkVEIEJZIHN1cGFiYXNlX3BnX25ldF9hZG1pbjtcbiAgICBEUk9QIFJPTEUgc3VwYWJhc2VfcGdfbmV0X2FkbWluO1xuICBFTkQgSUY7XG5FTkRcbiQkO1xuLS0gcGdfbmV0IGdyYW50cyB3aGVuIGV4dGVuc2lvbiBpcyBhbHJlYWR5IGVuYWJsZWRcbkRPXG4kJFxuQkVHSU5cbiAgSUYgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfZXh0ZW5zaW9uXG4gICAgV0hFUkUgZXh0bmFtZSA9ICdwZ19uZXQnXG4gIClcbiAgVEhFTlxuICAgIEdSQU5UIFVTQUdFIE9OIFNDSEVNQSBuZXQgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VDVVJJVFkgREVGSU5FUjtcbiAgICBBTFRFUiBmdW5jdGlvbiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBGUk9NIFBVQkxJQztcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbi0tIEV2ZW50IHRyaWdnZXIgZm9yIHBnX25ldFxuQ1JFQVRFIE9SIFJFUExBQ0UgRlVOQ1RJT04gZXh0ZW5zaW9ucy5ncmFudF9wZ19uZXRfYWNjZXNzKClcblJFVFVSTlMgZXZlbnRfdHJpZ2dlclxuTEFOR1VBR0UgcGxwZ3NxbFxuQVMgJCRcbkJFR0lOXG4gIElGIEVYSVNUUyAoXG4gICAgU0VMRUNUIDFcbiAgICBGUk9NIHBnX2V2ZW50X3RyaWdnZXJfZGRsX2NvbW1hbmRzKCkgQVMgZXZcbiAgICBKT0lOIHBnX2V4dGVuc2lvbiBBUyBleHRcbiAgICBPTiBldi5vYmppZCA9IGV4dC5vaWRcbiAgICBXSEVSRSBleHQuZXh0bmFtZSA9ICdwZ19uZXQnXG4gIClcbiAgVEhFTlxuICAgIEdSQU5UIFVTQUdFIE9OIFNDSEVNQSBuZXQgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VDVVJJVFkgREVGSU5FUjtcbiAgICBBTFRFUiBmdW5jdGlvbiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBGUk9NIFBVQkxJQztcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgRU5EIElGO1xuRU5EO1xuJCQ7XG5DT01NRU5UIE9OIEZVTkNUSU9OIGV4dGVuc2lvbnMuZ3JhbnRfcGdfbmV0X2FjY2VzcyBJUyAnR3JhbnRzIGFjY2VzcyB0byBwZ19uZXQnO1xuRE9cbiQkXG5CRUdJTlxuICBJRiBOT1QgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfZXZlbnRfdHJpZ2dlclxuICAgIFdIRVJFIGV2dG5hbWUgPSAnaXNzdWVfcGdfbmV0X2FjY2VzcydcbiAgKSBUSEVOXG4gICAgQ1JFQVRFIEVWRU5UIFRSSUdHRVIgaXNzdWVfcGdfbmV0X2FjY2VzcyBPTiBkZGxfY29tbWFuZF9lbmQgV0hFTiBUQUcgSU4gKCdDUkVBVEUgRVhURU5TSU9OJylcbiAgICBFWEVDVVRFIFBST0NFRFVSRSBleHRlbnNpb25zLmdyYW50X3BnX25ldF9hY2Nlc3MoKTtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbklOU0VSVCBJTlRPIHN1cGFiYXNlX2Z1bmN0aW9ucy5taWdyYXRpb25zICh2ZXJzaW9uKSBWQUxVRVMgKCcyMDIxMDgwOTE4MzQyM191cGRhdGVfZ3JhbnRzJyk7XG5BTFRFUiBmdW5jdGlvbiBzdXBhYmFzZV9mdW5jdGlvbnMuaHR0cF9yZXF1ZXN0KCkgU0VDVVJJVFkgREVGSU5FUjtcbkFMVEVSIGZ1bmN0aW9uIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKSBTRVQgc2VhcmNoX3BhdGggPSBzdXBhYmFzZV9mdW5jdGlvbnM7XG5SRVZPS0UgQUxMIE9OIEZVTkNUSU9OIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKSBGUk9NIFBVQkxJQztcbkdSQU5UIEVYRUNVVEUgT04gRlVOQ1RJT04gc3VwYWJhc2VfZnVuY3Rpb25zLmh0dHBfcmVxdWVzdCgpIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5DT01NSVQ7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvcm9sZXMuc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvaW5pdC1zY3JpcHRzLzk5LXJvbGVzLnNxbAogICAgICAgIGNvbnRlbnQ6ICItLSBOT1RFOiBjaGFuZ2UgdG8geW91ciBvd24gcGFzc3dvcmRzIGZvciBwcm9kdWN0aW9uIGVudmlyb25tZW50c1xuIFxcc2V0IHBncGFzcyBgZWNobyBcIiRQT1NUR1JFU19QQVNTV09SRFwiYFxuXG4gQUxURVIgVVNFUiBhdXRoZW50aWNhdG9yIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgcGdib3VuY2VyIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgc3VwYWJhc2VfYXV0aF9hZG1pbiBXSVRIIFBBU1NXT1JEIDoncGdwYXNzJztcbiBBTFRFUiBVU0VSIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBXSVRIIFBBU1NXT1JEIDoncGdwYXNzJztcbiBBTFRFUiBVU0VSIHN1cGFiYXNlX3N0b3JhZ2VfYWRtaW4gV0lUSCBQQVNTV09SRCA6J3BncGFzcyc7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvand0LnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL2luaXQtc2NyaXB0cy85OS1qd3Quc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IGp3dF9zZWNyZXQgYGVjaG8gXCIkSldUX1NFQ1JFVFwiYFxuXFxzZXQgand0X2V4cCBgZWNobyBcIiRKV1RfRVhQXCJgXG5cXHNldCBkYl9uYW1lIGBlY2hvIFwiJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9XCJgXG5cbkFMVEVSIERBVEFCQVNFIDpkYl9uYW1lIFNFVCBcImFwcC5zZXR0aW5ncy5qd3Rfc2VjcmV0XCIgVE8gOidqd3Rfc2VjcmV0JztcbkFMVEVSIERBVEFCQVNFIDpkYl9uYW1lIFNFVCBcImFwcC5zZXR0aW5ncy5qd3RfZXhwXCIgVE8gOidqd3RfZXhwJztcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9sb2dzLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTktbG9ncy5zcWwKICAgICAgICBjb250ZW50OiAiXFxzZXQgcGd1c2VyIGBlY2hvIFwic3VwYWJhc2VfYWRtaW5cImBcblxcYyBfc3VwYWJhc2VcbmNyZWF0ZSBzY2hlbWEgaWYgbm90IGV4aXN0cyBfYW5hbHl0aWNzO1xuYWx0ZXIgc2NoZW1hIF9hbmFseXRpY3Mgb3duZXIgdG8gOnBndXNlcjtcbiIKICAgICAgLSAnc3VwYWJhc2UtZGItY29uZmlnOi9ldGMvcG9zdGdyZXNxbC1jdXN0b20nCiAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9sb2dmbGFyZToxLjQuMCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo0MDAwL2hlYWx0aCcKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gTE9HRkxBUkVfTk9ERV9IT1NUPTEyNy4wLjAuMQogICAgICAtIERCX1VTRVJOQU1FPXN1cGFiYXNlX2FkbWluCiAgICAgIC0gREJfREFUQUJBU0U9X3N1cGFiYXNlCiAgICAgIC0gJ0RCX0hPU1ROQU1FPSR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifScKICAgICAgLSAnREJfUE9SVD0ke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9JwogICAgICAtICdEQl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtIERCX1NDSEVNQT1fYW5hbHl0aWNzCiAgICAgIC0gJ0xPR0ZMQVJFX0FQSV9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX0xPR0ZMQVJFfScKICAgICAgLSBMT0dGTEFSRV9TSU5HTEVfVEVOQU5UPXRydWUKICAgICAgLSBMT0dGTEFSRV9TSU5HTEVfVEVOQU5UX01PREU9dHJ1ZQogICAgICAtIExPR0ZMQVJFX1NVUEFCQVNFX01PREU9dHJ1ZQogICAgICAtIExPR0ZMQVJFX01JTl9DTFVTVEVSX1NJWkU9MQogICAgICAtICdQT1NUR1JFU19CQUNLRU5EX1VSTD1wb3N0Z3Jlc3FsOi8vc3VwYWJhc2VfYWRtaW46JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUAke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn06JHtQT1NUR1JFU19QT1JUOi01NDMyfS9fc3VwYWJhc2UnCiAgICAgIC0gUE9TVEdSRVNfQkFDS0VORF9TQ0hFTUE9X2FuYWx5dGljcwogICAgICAtIExPR0ZMQVJFX0ZFQVRVUkVfRkxBR19PVkVSUklERT1tdWx0aWJhY2tlbmQ9dHJ1ZQogIHN1cGFiYXNlLXZlY3RvcjoKICAgIGltYWdlOiAndGltYmVyaW8vdmVjdG9yOjAuMjguMS1hbHBpbmUnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tbm8tdmVyYm9zZScKICAgICAgICAtICctLXRyaWVzPTEnCiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnaHR0cDovL3N1cGFiYXNlLXZlY3Rvcjo5MDAxL2hlYWx0aCcKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIHZvbHVtZXM6CiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvbG9ncy92ZWN0b3IueW1sCiAgICAgICAgdGFyZ2V0OiAvZXRjL3ZlY3Rvci92ZWN0b3IueW1sCiAgICAgICAgcmVhZF9vbmx5OiB0cnVlCiAgICAgICAgY29udGVudDogImFwaTpcbiAgZW5hYmxlZDogdHJ1ZVxuICBhZGRyZXNzOiAwLjAuMC4wOjkwMDFcblxuc291cmNlczpcbiAgZG9ja2VyX2hvc3Q6XG4gICAgdHlwZTogZG9ja2VyX2xvZ3NcbiAgICBleGNsdWRlX2NvbnRhaW5lcnM6XG4gICAgICAtIHN1cGFiYXNlLXZlY3RvclxuXG50cmFuc2Zvcm1zOlxuICBwcm9qZWN0X2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIGRvY2tlcl9ob3N0XG4gICAgc291cmNlOiB8LVxuICAgICAgLnByb2plY3QgPSBcImRlZmF1bHRcIlxuICAgICAgLmV2ZW50X21lc3NhZ2UgPSBkZWwoLm1lc3NhZ2UpXG4gICAgICAuYXBwbmFtZSA9IGRlbCguY29udGFpbmVyX25hbWUpXG4gICAgICBkZWwoLmNvbnRhaW5lcl9jcmVhdGVkX2F0KVxuICAgICAgZGVsKC5jb250YWluZXJfaWQpXG4gICAgICBkZWwoLnNvdXJjZV90eXBlKVxuICAgICAgZGVsKC5zdHJlYW0pXG4gICAgICBkZWwoLmxhYmVsKVxuICAgICAgZGVsKC5pbWFnZSlcbiAgICAgIGRlbCguaG9zdClcbiAgICAgIGRlbCguc3RyZWFtKVxuICByb3V0ZXI6XG4gICAgdHlwZTogcm91dGVcbiAgICBpbnB1dHM6XG4gICAgICAtIHByb2plY3RfbG9nc1xuICAgIHJvdXRlOlxuICAgICAga29uZzogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLWtvbmdcIiknXG4gICAgICBhdXRoOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2UtYXV0aFwiKSdcbiAgICAgIHJlc3Q6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1yZXN0XCIpJ1xuICAgICAgcmVhbHRpbWU6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJyZWFsdGltZS1kZXZcIiknXG4gICAgICBzdG9yYWdlOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2Utc3RvcmFnZVwiKSdcbiAgICAgIGZ1bmN0aW9uczogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLWZ1bmN0aW9uc1wiKSdcbiAgICAgIGRiOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2UtZGJcIiknXG4gICMgSWdub3JlcyBub24gbmdpbnggZXJyb3JzIHNpbmNlIHRoZXkgYXJlIHJlbGF0ZWQgd2l0aCBrb25nIGJvb3RpbmcgdXBcbiAga29uZ19sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIua29uZ1xuICAgIHNvdXJjZTogfC1cbiAgICAgIHJlcSwgZXJyID0gcGFyc2VfbmdpbnhfbG9nKC5ldmVudF9tZXNzYWdlLCBcImNvbWJpbmVkXCIpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLnRpbWVzdGFtcCA9IHJlcS50aW1lc3RhbXBcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5oZWFkZXJzLnJlZmVyZXIgPSByZXEucmVmZXJlclxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LmhlYWRlcnMudXNlcl9hZ2VudCA9IHJlcS5hZ2VudFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LmhlYWRlcnMuY2ZfY29ubmVjdGluZ19pcCA9IHJlcS5jbGllbnRcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5tZXRob2QgPSByZXEubWV0aG9kXG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QucGF0aCA9IHJlcS5wYXRoXG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QucHJvdG9jb2wgPSByZXEucHJvdG9jb2xcbiAgICAgICAgICAubWV0YWRhdGEucmVzcG9uc2Uuc3RhdHVzX2NvZGUgPSByZXEuc3RhdHVzXG4gICAgICB9XG4gICAgICBpZiBlcnIgIT0gbnVsbCB7XG4gICAgICAgIGFib3J0XG4gICAgICB9XG4gICMgSWdub3JlcyBub24gbmdpbnggZXJyb3JzIHNpbmNlIHRoZXkgYXJlIHJlbGF0ZWQgd2l0aCBrb25nIGJvb3RpbmcgdXBcbiAga29uZ19lcnI6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5rb25nXG4gICAgc291cmNlOiB8LVxuICAgICAgLm1ldGFkYXRhLnJlcXVlc3QubWV0aG9kID0gXCJHRVRcIlxuICAgICAgLm1ldGFkYXRhLnJlc3BvbnNlLnN0YXR1c19jb2RlID0gMjAwXG4gICAgICBwYXJzZWQsIGVyciA9IHBhcnNlX25naW54X2xvZyguZXZlbnRfbWVzc2FnZSwgXCJlcnJvclwiKVxuICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgIC50aW1lc3RhbXAgPSBwYXJzZWQudGltZXN0YW1wXG4gICAgICAgICAgLnNldmVyaXR5ID0gcGFyc2VkLnNldmVyaXR5XG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QuaG9zdCA9IHBhcnNlZC5ob3N0XG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QuaGVhZGVycy5jZl9jb25uZWN0aW5nX2lwID0gcGFyc2VkLmNsaWVudFxuICAgICAgICAgIHVybCwgZXJyID0gc3BsaXQocGFyc2VkLnJlcXVlc3QsIFwiIFwiKVxuICAgICAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QubWV0aG9kID0gdXJsWzBdXG4gICAgICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LnBhdGggPSB1cmxbMV1cbiAgICAgICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QucHJvdG9jb2wgPSB1cmxbMl1cbiAgICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiBlcnIgIT0gbnVsbCB7XG4gICAgICAgIGFib3J0XG4gICAgICB9XG4gICMgR290cnVlIGxvZ3MgYXJlIHN0cnVjdHVyZWQganNvbiBzdHJpbmdzIHdoaWNoIGZyb250ZW5kIHBhcnNlcyBkaXJlY3RseS4gQnV0IHdlIGtlZXAgbWV0YWRhdGEgZm9yIGNvbnNpc3RlbmN5LlxuICBhdXRoX2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5hdXRoXG4gICAgc291cmNlOiB8LVxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9qc29uKC5ldmVudF9tZXNzYWdlKVxuICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgIC5tZXRhZGF0YS50aW1lc3RhbXAgPSBwYXJzZWQudGltZVxuICAgICAgICAgIC5tZXRhZGF0YSA9IG1lcmdlISgubWV0YWRhdGEsIHBhcnNlZClcbiAgICAgIH1cbiAgIyBQb3N0Z1JFU1QgbG9ncyBhcmUgc3RydWN0dXJlZCBzbyB3ZSBzZXBhcmF0ZSB0aW1lc3RhbXAgZnJvbSBtZXNzYWdlIHVzaW5nIHJlZ2V4XG4gIHJlc3RfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLnJlc3RcbiAgICBzb3VyY2U6IHwtXG4gICAgICBwYXJzZWQsIGVyciA9IHBhcnNlX3JlZ2V4KC5ldmVudF9tZXNzYWdlLCByJ14oP1A8dGltZT4uKik6ICg/UDxtc2c+LiopJCcpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLmV2ZW50X21lc3NhZ2UgPSBwYXJzZWQubXNnXG4gICAgICAgICAgLnRpbWVzdGFtcCA9IHRvX3RpbWVzdGFtcCEocGFyc2VkLnRpbWUpXG4gICAgICAgICAgLm1ldGFkYXRhLmhvc3QgPSAucHJvamVjdFxuICAgICAgfVxuICAjIFJlYWx0aW1lIGxvZ3MgYXJlIHN0cnVjdHVyZWQgc28gd2UgcGFyc2UgdGhlIHNldmVyaXR5IGxldmVsIHVzaW5nIHJlZ2V4IChpZ25vcmUgdGltZSBiZWNhdXNlIGl0IGhhcyBubyBkYXRlKVxuICByZWFsdGltZV9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIucmVhbHRpbWVcbiAgICBzb3VyY2U6IHwtXG4gICAgICAubWV0YWRhdGEucHJvamVjdCA9IGRlbCgucHJvamVjdClcbiAgICAgIC5tZXRhZGF0YS5leHRlcm5hbF9pZCA9IC5tZXRhZGF0YS5wcm9qZWN0XG4gICAgICBwYXJzZWQsIGVyciA9IHBhcnNlX3JlZ2V4KC5ldmVudF9tZXNzYWdlLCByJ14oP1A8dGltZT5cXGQrOlxcZCs6XFxkK1xcLlxcZCspIFxcWyg/UDxsZXZlbD5cXHcrKVxcXSAoP1A8bXNnPi4qKSQnKVxuICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgIC5ldmVudF9tZXNzYWdlID0gcGFyc2VkLm1zZ1xuICAgICAgICAgIC5tZXRhZGF0YS5sZXZlbCA9IHBhcnNlZC5sZXZlbFxuICAgICAgfVxuICAjIFN0b3JhZ2UgbG9ncyBtYXkgY29udGFpbiBqc29uIG9iamVjdHMgc28gd2UgcGFyc2UgdGhlbSBmb3IgY29tcGxldGVuZXNzXG4gIHN0b3JhZ2VfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLnN0b3JhZ2VcbiAgICBzb3VyY2U6IHwtXG4gICAgICAubWV0YWRhdGEucHJvamVjdCA9IGRlbCgucHJvamVjdClcbiAgICAgIC5tZXRhZGF0YS50ZW5hbnRJZCA9IC5tZXRhZGF0YS5wcm9qZWN0XG4gICAgICBwYXJzZWQsIGVyciA9IHBhcnNlX2pzb24oLmV2ZW50X21lc3NhZ2UpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLmV2ZW50X21lc3NhZ2UgPSBwYXJzZWQubXNnXG4gICAgICAgICAgLm1ldGFkYXRhLmxldmVsID0gcGFyc2VkLmxldmVsXG4gICAgICAgICAgLm1ldGFkYXRhLnRpbWVzdGFtcCA9IHBhcnNlZC50aW1lXG4gICAgICAgICAgLm1ldGFkYXRhLmNvbnRleHRbMF0uaG9zdCA9IHBhcnNlZC5ob3N0bmFtZVxuICAgICAgICAgIC5tZXRhZGF0YS5jb250ZXh0WzBdLnBpZCA9IHBhcnNlZC5waWRcbiAgICAgIH1cbiAgIyBQb3N0Z3JlcyBsb2dzIHNvbWUgbWVzc2FnZXMgdG8gc3RkZXJyIHdoaWNoIHdlIG1hcCB0byB3YXJuaW5nIHNldmVyaXR5IGxldmVsXG4gIGRiX2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5kYlxuICAgIHNvdXJjZTogfC1cbiAgICAgIC5tZXRhZGF0YS5ob3N0ID0gXCJkYi1kZWZhdWx0XCJcbiAgICAgIC5tZXRhZGF0YS5wYXJzZWQudGltZXN0YW1wID0gLnRpbWVzdGFtcFxuXG4gICAgICBwYXJzZWQsIGVyciA9IHBhcnNlX3JlZ2V4KC5ldmVudF9tZXNzYWdlLCByJy4qKD9QPGxldmVsPklORk98Tk9USUNFfFdBUk5JTkd8RVJST1J8TE9HfEZBVEFMfFBBTklDPyk6LionLCBudW1lcmljX2dyb3VwczogdHJ1ZSlcblxuICAgICAgaWYgZXJyICE9IG51bGwgfHwgcGFyc2VkID09IG51bGwge1xuICAgICAgICAubWV0YWRhdGEucGFyc2VkLmVycm9yX3NldmVyaXR5ID0gXCJpbmZvXCJcbiAgICAgIH1cbiAgICAgIGlmIHBhcnNlZCAhPSBudWxsIHtcbiAgICAgIC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkgPSBwYXJzZWQubGV2ZWxcbiAgICAgIH1cbiAgICAgIGlmIC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkgPT0gXCJpbmZvXCIge1xuICAgICAgICAgIC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkgPSBcImxvZ1wiXG4gICAgICB9XG4gICAgICAubWV0YWRhdGEucGFyc2VkLmVycm9yX3NldmVyaXR5ID0gdXBjYXNlISgubWV0YWRhdGEucGFyc2VkLmVycm9yX3NldmVyaXR5KVxuXG5zaW5rczpcbiAgbG9nZmxhcmVfYXV0aDpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIGF1dGhfbG9nc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1nb3RydWUubG9ncy5wcm9kJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9yZWFsdGltZTpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIHJlYWx0aW1lX2xvZ3NcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9cmVhbHRpbWUubG9ncy5wcm9kJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9yZXN0OlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gcmVzdF9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPXBvc3RnUkVTVC5sb2dzLnByb2QmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX2RiOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gZGJfbG9nc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgICMgV2UgbXVzdCByb3V0ZSB0aGUgc2luayB0aHJvdWdoIGtvbmcgYmVjYXVzZSBpbmdlc3RpbmcgbG9ncyBiZWZvcmUgbG9nZmxhcmUgaXMgZnVsbHkgaW5pdGlhbGlzZWQgd2lsbFxuICAgICMgbGVhZCB0byBicm9rZW4gcXVlcmllcyBmcm9tIHN0dWRpby4gVGhpcyB3b3JrcyBieSB0aGUgYXNzdW1wdGlvbiB0aGF0IGNvbnRhaW5lcnMgYXJlIHN0YXJ0ZWQgaW4gdGhlXG4gICAgIyBmb2xsb3dpbmcgb3JkZXI6IHZlY3RvciA+IGRiID4gbG9nZmxhcmUgPiBrb25nXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWtvbmc6ODAwMC9hbmFseXRpY3MvdjEvYXBpL2xvZ3M/c291cmNlX25hbWU9cG9zdGdyZXMubG9ncyZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfZnVuY3Rpb25zOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmZ1bmN0aW9uc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1kZW5vLXJlbGF5LWxvZ3MmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX3N0b3JhZ2U6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSBzdG9yYWdlX2xvZ3NcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9c3RvcmFnZS5sb2dzLnByb2QuMiZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfa29uZzpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIGtvbmdfbG9nc1xuICAgICAgLSBrb25nX2VyclxuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1jbG91ZGZsYXJlLmxvZ3MucHJvZCZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiIKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2s6cm8nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnTE9HRkxBUkVfQVBJX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfTE9HRkxBUkV9JwogICAgY29tbWFuZDoKICAgICAgLSAnLS1jb25maWcnCiAgICAgIC0gZXRjL3ZlY3Rvci92ZWN0b3IueW1sCiAgc3VwYWJhc2UtcmVzdDoKICAgIGltYWdlOiAncG9zdGdyZXN0L3Bvc3RncmVzdDp2MTIuMi4wJwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUEdSU1RfREJfVVJJPXBvc3RncmVzOi8vYXV0aGVudGljYXRvcjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnUEdSU1RfREJfU0NIRU1BUz0ke1BHUlNUX0RCX1NDSEVNQVM6LXB1YmxpYyxzdG9yYWdlLGdyYXBocWxfcHVibGljfScKICAgICAgLSBQR1JTVF9EQl9BTk9OX1JPTEU9YW5vbgogICAgICAtICdQR1JTVF9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIFBHUlNUX0RCX1VTRV9MRUdBQ1lfR1VDUz1mYWxzZQogICAgICAtICdQR1JTVF9BUFBfU0VUVElOR1NfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnUEdSU1RfQVBQX1NFVFRJTkdTX0pXVF9FWFA9JHtKV1RfRVhQSVJZOi0zNjAwfScKICAgIGNvbW1hbmQ6IHBvc3RncmVzdAogICAgZXhjbHVkZV9mcm9tX2hjOiB0cnVlCiAgc3VwYWJhc2UtYXV0aDoKICAgIGltYWdlOiAnc3VwYWJhc2UvZ290cnVlOnYyLjE1OC4xJwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tbm8tdmVyYm9zZScKICAgICAgICAtICctLXRyaWVzPTEnCiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo5OTk5L2hlYWx0aCcKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtIEdPVFJVRV9BUElfSE9TVD0wLjAuMC4wCiAgICAgIC0gR09UUlVFX0FQSV9QT1JUPTk5OTkKICAgICAgLSAnQVBJX0VYVEVSTkFMX1VSTD0ke0FQSV9FWFRFUk5BTF9VUkw6LWh0dHA6Ly9zdXBhYmFzZS1rb25nOjgwMDB9JwogICAgICAtIEdPVFJVRV9EQl9EUklWRVI9cG9zdGdyZXMKICAgICAgLSAnR09UUlVFX0RCX0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3N1cGFiYXNlX2F1dGhfYWRtaW46JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUAke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn06JHtQT1NUR1JFU19QT1JUOi01NDMyfS8ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ0dPVFJVRV9TSVRFX1VSTD0ke1NFUlZJQ0VfRlFETl9TVVBBQkFTRUtPTkd9JwogICAgICAtICdHT1RSVUVfVVJJX0FMTE9XX0xJU1Q9JHtBRERJVElPTkFMX1JFRElSRUNUX1VSTFN9JwogICAgICAtICdHT1RSVUVfRElTQUJMRV9TSUdOVVA9JHtESVNBQkxFX1NJR05VUDotZmFsc2V9JwogICAgICAtIEdPVFJVRV9KV1RfQURNSU5fUk9MRVM9c2VydmljZV9yb2xlCiAgICAgIC0gR09UUlVFX0pXVF9BVUQ9YXV0aGVudGljYXRlZAogICAgICAtIEdPVFJVRV9KV1RfREVGQVVMVF9HUk9VUF9OQU1FPWF1dGhlbnRpY2F0ZWQKICAgICAgLSAnR09UUlVFX0pXVF9FWFA9JHtKV1RfRVhQSVJZOi0zNjAwfScKICAgICAgLSAnR09UUlVFX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ0dPVFJVRV9FWFRFUk5BTF9FTUFJTF9FTkFCTEVEPSR7RU5BQkxFX0VNQUlMX1NJR05VUDotdHJ1ZX0nCiAgICAgIC0gJ0dPVFJVRV9FWFRFUk5BTF9BTk9OWU1PVVNfVVNFUlNfRU5BQkxFRD0ke0VOQUJMRV9BTk9OWU1PVVNfVVNFUlM6LWZhbHNlfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9BVVRPQ09ORklSTT0ke0VOQUJMRV9FTUFJTF9BVVRPQ09ORklSTTotZmFsc2V9JwogICAgICAtICdHT1RSVUVfU01UUF9BRE1JTl9FTUFJTD0ke1NNVFBfQURNSU5fRU1BSUx9JwogICAgICAtICdHT1RSVUVfU01UUF9IT1NUPSR7U01UUF9IT1NUfScKICAgICAgLSAnR09UUlVFX1NNVFBfUE9SVD0ke1NNVFBfUE9SVDotNTg3fScKICAgICAgLSAnR09UUlVFX1NNVFBfVVNFUj0ke1NNVFBfVVNFUn0nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX1BBU1M9JHtTTVRQX1BBU1N9JwogICAgICAtICdHT1RSVUVfU01UUF9TRU5ERVJfTkFNRT0ke1NNVFBfU0VOREVSX05BTUV9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1VSTFBBVEhTX0lOVklURT0ke01BSUxFUl9VUkxQQVRIU19JTlZJVEU6LS9hdXRoL3YxL3ZlcmlmeX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVVJMUEFUSFNfQ09ORklSTUFUSU9OPSR7TUFJTEVSX1VSTFBBVEhTX0NPTkZJUk1BVElPTjotL2F1dGgvdjEvdmVyaWZ5fScKICAgICAgLSAnR09UUlVFX01BSUxFUl9VUkxQQVRIU19SRUNPVkVSWT0ke01BSUxFUl9VUkxQQVRIU19SRUNPVkVSWTotL2F1dGgvdjEvdmVyaWZ5fScKICAgICAgLSAnR09UUlVFX01BSUxFUl9VUkxQQVRIU19FTUFJTF9DSEFOR0U9JHtNQUlMRVJfVVJMUEFUSFNfRU1BSUxfQ0hBTkdFOi0vYXV0aC92MS92ZXJpZnl9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1RFTVBMQVRFU19JTlZJVEU9JHtNQUlMRVJfVEVNUExBVEVTX0lOVklURX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVEVNUExBVEVTX0NPTkZJUk1BVElPTj0ke01BSUxFUl9URU1QTEFURVNfQ09ORklSTUFUSU9OfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9URU1QTEFURVNfUkVDT1ZFUlk9JHtNQUlMRVJfVEVNUExBVEVTX1JFQ09WRVJZfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9URU1QTEFURVNfTUFHSUNfTElOSz0ke01BSUxFUl9URU1QTEFURVNfTUFHSUNfTElOS30nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVEVNUExBVEVTX0VNQUlMX0NIQU5HRT0ke01BSUxFUl9URU1QTEFURVNfRU1BSUxfQ0hBTkdFfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9TVUJKRUNUU19DT05GSVJNQVRJT049JHtNQUlMRVJfU1VCSkVDVFNfQ09ORklSTUFUSU9OfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9TVUJKRUNUU19SRUNPVkVSWT0ke01BSUxFUl9TVUJKRUNUU19SRUNPVkVSWX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfU1VCSkVDVFNfTUFHSUNfTElOSz0ke01BSUxFUl9TVUJKRUNUU19NQUdJQ19MSU5LfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9TVUJKRUNUU19FTUFJTF9DSEFOR0U9JHtNQUlMRVJfU1VCSkVDVFNfRU1BSUxfQ0hBTkdFfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9TVUJKRUNUU19JTlZJVEU9JHtNQUlMRVJfU1VCSkVDVFNfSU5WSVRFfScKICAgICAgLSAnR09UUlVFX0VYVEVSTkFMX1BIT05FX0VOQUJMRUQ9JHtFTkFCTEVfUEhPTkVfU0lHTlVQOi10cnVlfScKICAgICAgLSAnR09UUlVFX1NNU19BVVRPQ09ORklSTT0ke0VOQUJMRV9QSE9ORV9BVVRPQ09ORklSTTotdHJ1ZX0nCiAgcmVhbHRpbWUtZGV2OgogICAgaW1hZ2U6ICdzdXBhYmFzZS9yZWFsdGltZTp2Mi4zMC4zNCcKICAgIGNvbnRhaW5lcl9uYW1lOiByZWFsdGltZS1kZXYuc3VwYWJhc2UtcmVhbHRpbWUKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctc1NmTCcKICAgICAgICAtICctLWhlYWQnCiAgICAgICAgLSAnLW8nCiAgICAgICAgLSAvZGV2L251bGwKICAgICAgICAtICctSCcKICAgICAgICAtICdBdXRob3JpemF0aW9uOiBCZWFyZXIgJHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6NDAwMC9hcGkvdGVuYW50cy9yZWFsdGltZS1kZXYvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9SVD00MDAwCiAgICAgIC0gJ0RCX0hPU1Q9JHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9JwogICAgICAtICdEQl9QT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gREJfVVNFUj1zdXBhYmFzZV9hZG1pbgogICAgICAtICdEQl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdEQl9OQU1FPSR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnREJfQUZURVJfQ09OTkVDVF9RVUVSWT1TRVQgc2VhcmNoX3BhdGggVE8gX3JlYWx0aW1lJwogICAgICAtIERCX0VOQ19LRVk9c3VwYWJhc2VyZWFsdGltZQogICAgICAtICdBUElfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSBGTFlfQUxMT0NfSUQ9Zmx5MTIzCiAgICAgIC0gRkxZX0FQUF9OQU1FPXJlYWx0aW1lCiAgICAgIC0gJ1NFQ1JFVF9LRVlfQkFTRT0ke1NFQ1JFVF9QQVNTV09SRF9SRUFMVElNRX0nCiAgICAgIC0gJ0VSTF9BRkxBR1M9LXByb3RvX2Rpc3QgaW5ldF90Y3AnCiAgICAgIC0gRU5BQkxFX1RBSUxTQ0FMRT1mYWxzZQogICAgICAtICJETlNfTk9ERVM9JyciCiAgICAgIC0gUkxJTUlUX05PRklMRT0xMDAwMAogICAgICAtIEFQUF9OQU1FPXJlYWx0aW1lCiAgICAgIC0gU0VFRF9TRUxGX0hPU1Q9dHJ1ZQogICAgY29tbWFuZDogInNoIC1jIFwiL2FwcC9iaW4vbWlncmF0ZSAmJiAvYXBwL2Jpbi9yZWFsdGltZSBldmFsICdSZWFsdGltZS5SZWxlYXNlLnNlZWRzKFJlYWx0aW1lLlJlcG8pJyAmJiAvYXBwL2Jpbi9zZXJ2ZXJcIlxuIgogIHN1cGFiYXNlLW1pbmlvOgogICAgaW1hZ2U6IG1pbmlvL21pbmlvCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnTUlOSU9fUk9PVF9VU0VSPSR7U0VSVklDRV9VU0VSX01JTklPfScKICAgICAgLSAnTUlOSU9fUk9PVF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTUlOSU99JwogICAgY29tbWFuZDogJ3NlcnZlciAtLWNvbnNvbGUtYWRkcmVzcyAiOjkwMDEiIC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6ICdzbGVlcCA1ICYmIGV4aXQgMCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiA1CiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvc3RvcmFnZTovZGF0YScKICBtaW5pby1jcmVhdGVidWNrZXQ6CiAgICBpbWFnZTogbWluaW8vbWMKICAgIHJlc3RhcnQ6ICdubycKICAgIGVudmlyb25tZW50OgogICAgICAtICdNSU5JT19ST09UX1VTRVI9JHtTRVJWSUNFX1VTRVJfTUlOSU99JwogICAgICAtICdNSU5JT19ST09UX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NSU5JT30nCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1taW5pbzoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW50cnlwb2ludDoKICAgICAgLSAvZW50cnlwb2ludC5zaAogICAgdm9sdW1lczoKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vZW50cnlwb2ludC5zaAogICAgICAgIHRhcmdldDogL2VudHJ5cG9pbnQuc2gKICAgICAgICBjb250ZW50OiAiIyEvYmluL3NoXG4vdXNyL2Jpbi9tYyBhbGlhcyBzZXQgc3VwYWJhc2UtbWluaW8gaHR0cDovL3N1cGFiYXNlLW1pbmlvOjkwMDAgJHtNSU5JT19ST09UX1VTRVJ9ICR7TUlOSU9fUk9PVF9QQVNTV09SRH07XG4vdXNyL2Jpbi9tYyBtYiAtLWlnbm9yZS1leGlzdGluZyBzdXBhYmFzZS1taW5pby9zdHViO1xuZXhpdCAwXG4iCiAgc3VwYWJhc2Utc3RvcmFnZToKICAgIGltYWdlOiAnc3VwYWJhc2Uvc3RvcmFnZS1hcGk6djEuMTAuMScKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLXJlc3Q6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX3N0YXJ0ZWQKICAgICAgaW1ncHJveHk6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX3N0YXJ0ZWQKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1uby12ZXJib3NlJwogICAgICAgIC0gJy0tdHJpZXM9MScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjUwMDAvc3RhdHVzJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVkVSX1BPUlQ9NTAwMAogICAgICAtIFNFUlZFUl9SRUdJT049bG9jYWwKICAgICAgLSBNVUxUSV9URU5BTlQ9ZmFsc2UKICAgICAgLSAnQVVUSF9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly9zdXBhYmFzZV9zdG9yYWdlX2FkbWluOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9OiR7UE9TVEdSRVNfUE9SVDotNTQzMn0vJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtIERCX0lOU1RBTExfUk9MRVM9ZmFsc2UKICAgICAgLSBTVE9SQUdFX0JBQ0tFTkQ9czMKICAgICAgLSBTVE9SQUdFX1MzX0JVQ0tFVD1zdHViCiAgICAgIC0gJ1NUT1JBR0VfUzNfRU5EUE9JTlQ9aHR0cDovL3N1cGFiYXNlLW1pbmlvOjkwMDAnCiAgICAgIC0gU1RPUkFHRV9TM19GT1JDRV9QQVRIX1NUWUxFPXRydWUKICAgICAgLSBTVE9SQUdFX1MzX1JFR0lPTj11cy1lYXN0LTEKICAgICAgLSAnQVdTX0FDQ0VTU19LRVlfSUQ9JHtTRVJWSUNFX1VTRVJfTUlOSU99JwogICAgICAtICdBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX01JTklPfScKICAgICAgLSBVUExPQURfRklMRV9TSVpFX0xJTUlUPTUyNDI4ODAwMAogICAgICAtIFVQTE9BRF9GSUxFX1NJWkVfTElNSVRfU1RBTkRBUkQ9NTI0Mjg4MDAwCiAgICAgIC0gVVBMT0FEX1NJR05FRF9VUkxfRVhQSVJBVElPTl9USU1FPTEyMAogICAgICAtIFRVU19VUkxfUEFUSD0vdXBsb2FkL3Jlc3VtYWJsZQogICAgICAtIFRVU19NQVhfU0laRT0zNjAwMDAwCiAgICAgIC0gSU1BR0VfVFJBTlNGT1JNQVRJT05fRU5BQkxFRD10cnVlCiAgICAgIC0gJ0lNR1BST1hZX1VSTD1odHRwOi8vaW1ncHJveHk6ODA4MCcKICAgICAgLSBJTUdQUk9YWV9SRVFVRVNUX1RJTUVPVVQ9MTUKICAgICAgLSBEQVRBQkFTRV9TRUFSQ0hfUEFUSD1zdG9yYWdlCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvc3RvcmFnZTovdmFyL2xpYi9zdG9yYWdlJwogIGltZ3Byb3h5OgogICAgaW1hZ2U6ICdkYXJ0aHNpbS9pbWdwcm94eTp2My44LjAnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gaW1ncHJveHkKICAgICAgICAtIGhlYWx0aAogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gSU1HUFJPWFlfTE9DQUxfRklMRVNZU1RFTV9ST09UPS8KICAgICAgLSBJTUdQUk9YWV9VU0VfRVRBRz10cnVlCiAgICAgIC0gJ0lNR1BST1hZX0VOQUJMRV9XRUJQX0RFVEVDVElPTj0ke0lNR1BST1hZX0VOQUJMRV9XRUJQX0RFVEVDVElPTjotdHJ1ZX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvc3RvcmFnZTovdmFyL2xpYi9zdG9yYWdlJwogIHN1cGFiYXNlLW1ldGE6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3Bvc3RncmVzLW1ldGE6djAuODMuMicKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUEdfTUVUQV9QT1JUPTgwODAKICAgICAgLSAnUEdfTUVUQV9EQl9IT1NUPSR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifScKICAgICAgLSAnUEdfTUVUQV9EQl9QT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gJ1BHX01FVEFfREJfTkFNRT0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gUEdfTUVUQV9EQl9VU0VSPXN1cGFiYXNlX2FkbWluCiAgICAgIC0gJ1BHX01FVEFfREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICBzdXBhYmFzZS1lZGdlLWZ1bmN0aW9uczoKICAgIGltYWdlOiAnc3VwYWJhc2UvZWRnZS1ydW50aW1lOnYxLjU4LjMnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBlY2hvCiAgICAgICAgLSAnRWRnZSBGdW5jdGlvbnMgaXMgaGVhbHRoeScKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdTVVBBQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fU1VQQUJBU0VLT05HfScKICAgICAgLSAnU1VQQUJBU0VfQU5PTl9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAtICdTVVBBQkFTRV9TRVJWSUNFX1JPTEVfS0VZPSR7U0VSVklDRV9TVVBBQkFTRVNFUlZJQ0VfS0VZfScKICAgICAgLSAnU1VQQUJBU0VfREJfVVJMPXBvc3RncmVzcWw6Ly9wb3N0Z3Jlczoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnVkVSSUZZX0pXVD0ke0ZVTkNUSU9OU19WRVJJRllfSldUOi1mYWxzZX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvZnVuY3Rpb25zOi9ob21lL2Rlbm8vZnVuY3Rpb25zJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2Z1bmN0aW9ucy9tYWluL2luZGV4LnRzCiAgICAgICAgdGFyZ2V0OiAvaG9tZS9kZW5vL2Z1bmN0aW9ucy9tYWluL2luZGV4LnRzCiAgICAgICAgY29udGVudDogImltcG9ydCB7IHNlcnZlIH0gZnJvbSAnaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTMxLjAvaHR0cC9zZXJ2ZXIudHMnXG5pbXBvcnQgKiBhcyBqb3NlIGZyb20gJ2h0dHBzOi8vZGVuby5sYW5kL3gvam9zZUB2NC4xNC40L2luZGV4LnRzJ1xuXG5jb25zb2xlLmxvZygnbWFpbiBmdW5jdGlvbiBzdGFydGVkJylcblxuY29uc3QgSldUX1NFQ1JFVCA9IERlbm8uZW52LmdldCgnSldUX1NFQ1JFVCcpXG5jb25zdCBWRVJJRllfSldUID0gRGVuby5lbnYuZ2V0KCdWRVJJRllfSldUJykgPT09ICd0cnVlJ1xuXG5mdW5jdGlvbiBnZXRBdXRoVG9rZW4ocmVxOiBSZXF1ZXN0KSB7XG4gIGNvbnN0IGF1dGhIZWFkZXIgPSByZXEuaGVhZGVycy5nZXQoJ2F1dGhvcml6YXRpb24nKVxuICBpZiAoIWF1dGhIZWFkZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgYXV0aG9yaXphdGlvbiBoZWFkZXInKVxuICB9XG4gIGNvbnN0IFtiZWFyZXIsIHRva2VuXSA9IGF1dGhIZWFkZXIuc3BsaXQoJyAnKVxuICBpZiAoYmVhcmVyICE9PSAnQmVhcmVyJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgQXV0aCBoZWFkZXIgaXMgbm90ICdCZWFyZXIge3Rva2VufSdgKVxuICB9XG4gIHJldHVybiB0b2tlblxufVxuXG5hc3luYyBmdW5jdGlvbiB2ZXJpZnlKV1Qoand0OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpXG4gIGNvbnN0IHNlY3JldEtleSA9IGVuY29kZXIuZW5jb2RlKEpXVF9TRUNSRVQpXG4gIHRyeSB7XG4gICAgYXdhaXQgam9zZS5qd3RWZXJpZnkoand0LCBzZWNyZXRLZXkpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNvbnNvbGUuZXJyb3IoZXJyKVxuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbnNlcnZlKGFzeW5jIChyZXE6IFJlcXVlc3QpID0+IHtcbiAgaWYgKHJlcS5tZXRob2QgIT09ICdPUFRJT05TJyAmJiBWRVJJRllfSldUKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRva2VuID0gZ2V0QXV0aFRva2VuKHJlcSlcbiAgICAgIGNvbnN0IGlzVmFsaWRKV1QgPSBhd2FpdCB2ZXJpZnlKV1QodG9rZW4pXG5cbiAgICAgIGlmICghaXNWYWxpZEpXVCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KHsgbXNnOiAnSW52YWxpZCBKV1QnIH0pLCB7XG4gICAgICAgICAgc3RhdHVzOiA0MDEsXG4gICAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcihlKVxuICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShKU09OLnN0cmluZ2lmeSh7IG1zZzogZS50b1N0cmluZygpIH0pLCB7XG4gICAgICAgIHN0YXR1czogNDAxLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgY29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsKVxuICBjb25zdCB7IHBhdGhuYW1lIH0gPSB1cmxcbiAgY29uc3QgcGF0aF9wYXJ0cyA9IHBhdGhuYW1lLnNwbGl0KCcvJylcbiAgY29uc3Qgc2VydmljZV9uYW1lID0gcGF0aF9wYXJ0c1sxXVxuXG4gIGlmICghc2VydmljZV9uYW1lIHx8IHNlcnZpY2VfbmFtZSA9PT0gJycpIHtcbiAgICBjb25zdCBlcnJvciA9IHsgbXNnOiAnbWlzc2luZyBmdW5jdGlvbiBuYW1lIGluIHJlcXVlc3QnIH1cbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KGVycm9yKSwge1xuICAgICAgc3RhdHVzOiA0MDAsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICB9KVxuICB9XG5cbiAgY29uc3Qgc2VydmljZVBhdGggPSBgL2hvbWUvZGVuby9mdW5jdGlvbnMvJHtzZXJ2aWNlX25hbWV9YFxuICBjb25zb2xlLmVycm9yKGBzZXJ2aW5nIHRoZSByZXF1ZXN0IHdpdGggJHtzZXJ2aWNlUGF0aH1gKVxuXG4gIGNvbnN0IG1lbW9yeUxpbWl0TWIgPSAxNTBcbiAgY29uc3Qgd29ya2VyVGltZW91dE1zID0gMSAqIDYwICogMTAwMFxuICBjb25zdCBub01vZHVsZUNhY2hlID0gZmFsc2VcbiAgY29uc3QgaW1wb3J0TWFwUGF0aCA9IG51bGxcbiAgY29uc3QgZW52VmFyc09iaiA9IERlbm8uZW52LnRvT2JqZWN0KClcbiAgY29uc3QgZW52VmFycyA9IE9iamVjdC5rZXlzKGVudlZhcnNPYmopLm1hcCgoaykgPT4gW2ssIGVudlZhcnNPYmpba11dKVxuXG4gIHRyeSB7XG4gICAgY29uc3Qgd29ya2VyID0gYXdhaXQgRWRnZVJ1bnRpbWUudXNlcldvcmtlcnMuY3JlYXRlKHtcbiAgICAgIHNlcnZpY2VQYXRoLFxuICAgICAgbWVtb3J5TGltaXRNYixcbiAgICAgIHdvcmtlclRpbWVvdXRNcyxcbiAgICAgIG5vTW9kdWxlQ2FjaGUsXG4gICAgICBpbXBvcnRNYXBQYXRoLFxuICAgICAgZW52VmFycyxcbiAgICB9KVxuICAgIHJldHVybiBhd2FpdCB3b3JrZXIuZmV0Y2gocmVxKVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc3QgZXJyb3IgPSB7IG1zZzogZS50b1N0cmluZygpIH1cbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KGVycm9yKSwge1xuICAgICAgc3RhdHVzOiA1MDAsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICB9KVxuICB9XG59KVxuIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2Z1bmN0aW9ucy9oZWxsby9pbmRleC50cwogICAgICAgIHRhcmdldDogL2hvbWUvZGVuby9mdW5jdGlvbnMvaGVsbG8vaW5kZXgudHMKICAgICAgICBjb250ZW50OiAiLy8gRm9sbG93IHRoaXMgc2V0dXAgZ3VpZGUgdG8gaW50ZWdyYXRlIHRoZSBEZW5vIGxhbmd1YWdlIHNlcnZlciB3aXRoIHlvdXIgZWRpdG9yOlxuLy8gaHR0cHM6Ly9kZW5vLmxhbmQvbWFudWFsL2dldHRpbmdfc3RhcnRlZC9zZXR1cF95b3VyX2Vudmlyb25tZW50XG4vLyBUaGlzIGVuYWJsZXMgYXV0b2NvbXBsZXRlLCBnbyB0byBkZWZpbml0aW9uLCBldGMuXG5cbmltcG9ydCB7IHNlcnZlIH0gZnJvbSBcImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE3Ny4xL2h0dHAvc2VydmVyLnRzXCJcblxuc2VydmUoYXN5bmMgKCkgPT4ge1xuICByZXR1cm4gbmV3IFJlc3BvbnNlKFxuICAgIGBcIkhlbGxvIGZyb20gRWRnZSBGdW5jdGlvbnMhXCJgLFxuICAgIHsgaGVhZGVyczogeyBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9IH0sXG4gIClcbn0pXG5cbi8vIFRvIGludm9rZTpcbi8vIGN1cmwgJ2h0dHA6Ly9sb2NhbGhvc3Q6PEtPTkdfSFRUUF9QT1JUPi9mdW5jdGlvbnMvdjEvaGVsbG8nIFxcXG4vLyAgIC0taGVhZGVyICdBdXRob3JpemF0aW9uOiBCZWFyZXIgPGFub24vc2VydmljZV9yb2xlIEFQSSBrZXk+J1xuIgogICAgY29tbWFuZDoKICAgICAgLSBzdGFydAogICAgICAtICctLW1haW4tc2VydmljZScKICAgICAgLSAvaG9tZS9kZW5vL2Z1bmN0aW9ucy9tYWluCiAgc3VwYWJhc2Utc3VwYXZpc29yOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9zdXBhdmlzb3I6MS4xLjU2JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctc1NmTCcKICAgICAgICAtICctbycKICAgICAgICAtIC9kZXYvbnVsbAogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6NDAwMC9hcGkvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9PTEVSX1RFTkFOVF9JRD1kZXZfdGVuYW50CiAgICAgIC0gUE9PTEVSX1BPT0xfTU9ERT10cmFuc2FjdGlvbgogICAgICAtICdQT09MRVJfREVGQVVMVF9QT09MX1NJWkU9JHtQT09MRVJfREVGQVVMVF9QT09MX1NJWkU6LTIwfScKICAgICAgLSAnUE9PTEVSX01BWF9DTElFTlRfQ09OTj0ke1BPT0xFUl9NQVhfQ0xJRU5UX0NPTk46LTEwMH0nCiAgICAgIC0gUE9SVD00MDAwCiAgICAgIC0gJ1BPU1RHUkVTX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUE9TVEdSRVNfSE9TVE5BTUU9JHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1lY3RvOi8vc3VwYWJhc2VfYWRtaW46JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUAke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn06JHtQT1NUR1JFU19QT1JUOi01NDMyfS9fc3VwYWJhc2UnCiAgICAgIC0gQ0xVU1RFUl9QT1NUR1JFUz10cnVlCiAgICAgIC0gJ1NFQ1JFVF9LRVlfQkFTRT0ke1NFUlZJQ0VfUEFTU1dPUkRfU1VQQVZJU09SU0VDUkVUfScKICAgICAgLSAnVkFVTFRfRU5DX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfVkFVTFRFTkN9JwogICAgICAtICdBUElfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnTUVUUklDU19KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIFJFR0lPTj1sb2NhbAogICAgICAtICdFUkxfQUZMQUdTPS1wcm90b19kaXN0IGluZXRfdGNwJwogICAgY29tbWFuZDoKICAgICAgLSAvYmluL3NoCiAgICAgIC0gJy1jJwogICAgICAtICcvYXBwL2Jpbi9taWdyYXRlICYmIC9hcHAvYmluL3N1cGF2aXNvciBldmFsICIkJChjYXQgL2V0Yy9wb29sZXIvcG9vbGVyLmV4cykiICYmIC9hcHAvYmluL3NlcnZlcicKICAgIHZvbHVtZXM6CiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvcG9vbGVyL3Bvb2xlci5leHMKICAgICAgICB0YXJnZXQ6IC9ldGMvcG9vbGVyL3Bvb2xlci5leHMKICAgICAgICBjb250ZW50OiAiezpvaywgX30gPSBBcHBsaWNhdGlvbi5lbnN1cmVfYWxsX3N0YXJ0ZWQoOnN1cGF2aXNvcilcbns6b2ssIHZlcnNpb259ID1cbiAgICBjYXNlIFN1cGF2aXNvci5SZXBvLnF1ZXJ5IShcInNlbGVjdCB2ZXJzaW9uKClcIikgZG9cbiAgICAle3Jvd3M6IFtbdmVyXV19IC0+IFN1cGF2aXNvci5IZWxwZXJzLnBhcnNlX3BnX3ZlcnNpb24odmVyKVxuICAgIF8gLT4gbmlsXG4gICAgZW5kXG5wYXJhbXMgPSAle1xuICAgIFwiZXh0ZXJuYWxfaWRcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPT0xFUl9URU5BTlRfSURcIiksXG4gICAgXCJkYl9ob3N0XCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT1NUR1JFU19IT1NUTkFNRVwiKSxcbiAgICBcImRiX3BvcnRcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPU1RHUkVTX1BPUlRcIikgfD4gU3RyaW5nLnRvX2ludGVnZXIoKSxcbiAgICBcImRiX2RhdGFiYXNlXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT1NUR1JFU19EQlwiKSxcbiAgICBcInJlcXVpcmVfdXNlclwiID0+IGZhbHNlLFxuICAgIFwiYXV0aF9xdWVyeVwiID0+IFwiU0VMRUNUICogRlJPTSBwZ2JvdW5jZXIuZ2V0X2F1dGgoJDEpXCIsXG4gICAgXCJkZWZhdWx0X21heF9jbGllbnRzXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfTUFYX0NMSUVOVF9DT05OXCIpLFxuICAgIFwiZGVmYXVsdF9wb29sX3NpemVcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPT0xFUl9ERUZBVUxUX1BPT0xfU0laRVwiKSxcbiAgICBcImRlZmF1bHRfcGFyYW1ldGVyX3N0YXR1c1wiID0+ICV7XCJzZXJ2ZXJfdmVyc2lvblwiID0+IHZlcnNpb259LFxuICAgIFwidXNlcnNcIiA9PiBbJXtcbiAgICBcImRiX3VzZXJcIiA9PiBcInBnYm91bmNlclwiLFxuICAgIFwiZGJfcGFzc3dvcmRcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPU1RHUkVTX1BBU1NXT1JEXCIpLFxuICAgIFwibW9kZV90eXBlXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfUE9PTF9NT0RFXCIpLFxuICAgIFwicG9vbF9zaXplXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfREVGQVVMVF9QT09MX1NJWkVcIiksXG4gICAgXCJpc19tYW5hZ2VyXCIgPT4gdHJ1ZVxuICAgIH1dXG59XG5cbnRlbmFudCA9IFN1cGF2aXNvci5UZW5hbnRzLmdldF90ZW5hbnRfYnlfZXh0ZXJuYWxfaWQocGFyYW1zW1wiZXh0ZXJuYWxfaWRcIl0pXG5cbmlmIHRlbmFudCBkb1xuICB7Om9rLCBffSA9IFN1cGF2aXNvci5UZW5hbnRzLnVwZGF0ZV90ZW5hbnQodGVuYW50LCBwYXJhbXMpXG5lbHNlXG4gIHs6b2ssIF99ID0gU3VwYXZpc29yLlRlbmFudHMuY3JlYXRlX3RlbmFudChwYXJhbXMpXG5lbmRcbiIK", "tags": [ "firebase", "alternative", @@ -2011,6 +2357,34 @@ "minversion": "0.0.0", "port": "8080" }, + "traccar": { + "documentation": "https://www.traccar.org/documentation/?utm_source=coolify.io", + "slogan": "Traccar is a free and open source modern GPS tracking system.", + "compose": "c2VydmljZXM6CiAgdHJhY2NhcjoKICAgIGltYWdlOiAndHJhY2Nhci90cmFjY2FyOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9UUkFDQ0FSXzgwODIKICAgICAgLSBTRVJWSUNFX0ZRRE5fVFJBQ0NBUkFQSV81MTU5CiAgICAgIC0gJ0NPTkZJR19VU0VfRU5WSVJPTk1FTlRfVkFSSUFCTEVTPSR7Q09ORklHX1VTRV9FTlZJUk9OTUVOVF9WQVJJQUJMRVM6LXRydWV9JwogICAgICAtICdEQVRBQkFTRV9VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnREFUQUJBU0VfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgIHZvbHVtZXM6CiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3Nydi90cmFjY2FyL2NvbmYvdHJhY2Nhci54bWwKICAgICAgICB0YXJnZXQ6IC9vcHQvdHJhY2Nhci9jb25mL3RyYWNjYXIueG1sCiAgICAgICAgY29udGVudDogIjw/eG1sIHZlcnNpb249JzEuMCcgZW5jb2Rpbmc9J1VURi04Jz8+XG48IURPQ1RZUEUgcHJvcGVydGllcyBTWVNURU0gJ2h0dHA6Ly9qYXZhLnN1bi5jb20vZHRkL3Byb3BlcnRpZXMuZHRkJz5cbjxwcm9wZXJ0aWVzPlxuICAgIDxlbnRyeSBrZXk9J2NvbmZpZy5kZWZhdWx0Jz4uL2NvbmYvZGVmYXVsdC54bWw8L2VudHJ5PlxuICAgIDxlbnRyeSBrZXk9J2RhdGFiYXNlLmRyaXZlcic+b3JnLnBvc3RncmVzcWwuRHJpdmVyPC9lbnRyeT5cbiAgICA8ZW50cnkga2V5PSdkYXRhYmFzZS51cmwnPmpkYmM6cG9zdGdyZXNxbDovL3Bvc3RncmVzOjU0MzIvdHJhY2NhcjwvZW50cnk+XG48L3Byb3BlcnRpZXM+XG4iCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLW5vLXZlcmJvc2UnCiAgICAgICAgLSAnLS10cmllcz0xJwogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6ODA4Mi9waW5nJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgICAgIHN0YXJ0X3BlcmlvZDogMTVzCiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTUUxfREFUQUJBU0U6LXRyYWNjYXJ9JwogICAgdm9sdW1lczoKICAgICAgLSAndHJhY2Nhci1wb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhLycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "tags": [ + "traccar", + "gps", + "tracking", + "open", + "source" + ], + "logo": "svgs/traccar.png", + "minversion": "0.0.0", + "port": "8082" + }, + "transmission": { + "documentation": "https://docs.linuxserver.io/images/docker-transmission/?utm_source=coolify.io", + "slogan": "Fast, easy, and free BitTorrent client.", + "compose": "c2VydmljZXM6CiAgdHJhbnNtaXNzaW9uOgogICAgaW1hZ2U6ICdsc2NyLmlvL2xpbnV4c2VydmVyL3RyYW5zbWlzc2lvbjpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fVFJBTlNNSVNTSU9OXzkwOTEKICAgICAgLSBQVUlEPTEwMDAKICAgICAgLSBQR0lEPTEwMDAKICAgICAgLSAnVVNFUj0ke1NFUlZJQ0VfVVNFUl9BRE1JTn0nCiAgICAgIC0gJ1BBU1M9JHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3RyYW5zbWlzc2lvbi1jb25maWc6L2NvbmZpZycKICAgICAgLSAndHJhbnNtaXNzaW9uLWRvd25sb2FkczovZG93bmxvYWRzJwogICAgICAtICd0cmFuc21pc3Npb24td2F0Y2g6L3dhdGNoJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctc1NmTCcKICAgICAgICAtICctdScKICAgICAgICAtICcke1NFUlZJQ0VfVVNFUl9BRE1JTn06JHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOfScKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjkwOTEvJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCg==", + "tags": [ + "bittorrent", + "torrent", + "peer-to-peer" + ], + "logo": "svgs/transmission.svg", + "minversion": "0.0.0", + "port": "9091" + }, "trigger-with-external-database": { "documentation": "https://trigger.dev?utm_source=coolify.io", "slogan": "The open source Background Jobs framework for TypeScript", @@ -2101,6 +2475,22 @@ "minversion": "0.0.0", "port": "4242" }, + "unsend": { + "documentation": "https://docs.unsend.dev/get-started/self-hosting?utm_source=coolify.io", + "slogan": "Unsend is an open-source alternative to Resend, Sendgrid, Mailgun and Postmark etc.", + "compose": "c2VydmljZXM6CiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1NFUlZJQ0VfREJfUE9TVEdSRVM6LXVuc2VuZH0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgICB2b2x1bWVzOgogICAgICAtICd1bnNlbmQtcG9zdGdyZXMtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOjcnCiAgICB2b2x1bWVzOgogICAgICAtICd1bnNlbmQtcmVkaXMtZGF0YTovZGF0YScKICAgIGNvbW1hbmQ6CiAgICAgIC0gcmVkaXMtc2VydmVyCiAgICAgIC0gJy0tbWF4bWVtb3J5LXBvbGljeScKICAgICAgLSBub2V2aWN0aW9uCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSBQSU5HCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMjAKICB1bnNlbmQ6CiAgICBpbWFnZTogJ3Vuc2VuZC91bnNlbmQ6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1VOU0VORF8zMDAwCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AcG9zdGdyZXM6NTQzMi8ke1NFUlZJQ0VfREJfUE9TVEdSRVM6LXVuc2VuZH0nCiAgICAgIC0gJ05FWFRBVVRIX1VSTD0ke1NFUlZJQ0VfRlFETl9VTlNFTkR9JwogICAgICAtICdORVhUQVVUSF9TRUNSRVQ9JHtTRVJWSUNFX0JBU0U2NF82NF9ORVhUQVVUSFNFQ1JFVH0nCiAgICAgIC0gJ0FXU19BQ0NFU1NfS0VZPSR7U0VSVklDRV9BV1NfQUNDRVNTX0tFWX0nCiAgICAgIC0gJ0FXU19TRUNSRVRfS0VZPSR7U0VSVklDRV9BV1NfU0VDUkVUX0tFWX0nCiAgICAgIC0gJ0FXU19ERUZBVUxUX1JFR0lPTj0ke1NFUlZJQ0VfQVdTX0RFRkFVTFRfUkVHSU9OfScKICAgICAgLSAnR0lUSFVCX0lEPSR7U0VSVklDRV9HSVRIVUJfSUR9JwogICAgICAtICdHSVRIVUJfU0VDUkVUPSR7U0VSVklDRV9HSVRIVUJfU0VDUkVUfScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vcmVkaXM6NjM3OScKICAgICAgLSAnTkVYVF9QVUJMSUNfSVNfQ0xPVUQ9JHtORVhUX1BVQkxJQ19JU19DTE9VRDotZmFsc2V9JwogICAgICAtICdBUElfUkFURV9MSU1JVD0ke1NFUlZJQ0VfQVBJX1JBVEVfTElNSVQ6LTF9JwogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnd2dldCAtcU8tIGh0dHA6Ly8xMjcuMC4wLjE6MzAwMCB8fCBleGl0IDEnCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAxMAogICAgICB0aW1lb3V0OiAycwo=", + "tags": [ + "resend", + "mailer", + "marketing emails", + "transaction emails", + "self-hosting", + "postmark" + ], + "logo": "svgs/unsend.svg", + "minversion": "0.0.0", + "port": "3000" + }, "unstructured": { "documentation": "https://github.com/Unstructured-IO/unstructured-api?tab=readme-ov-file#--general-pre-processing-pipeline-for-documents?utm_source=coolify.io", "slogan": "Unstructured provides a platform and tools to ingest and process unstructured documents for Retrieval Augmented Generation (RAG) and model fine-tuning.", @@ -2175,6 +2565,66 @@ "minversion": "0.0.0", "port": "3456" }, + "vvveb-with-mariadb": { + "documentation": "https://docs.vvveb.com?utm_source=coolify.io", + "slogan": "Powerful and easy to use cms to build websites, blogs or ecommerce stores.", + "compose": "c2VydmljZXM6CiAgdnZ2ZWI6CiAgICBpbWFnZTogJ3Z2dmViL3Z2dmViY21zOmxhdGVzdCcKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Z2dmViLWRhdGE6L3Zhci93d3cvaHRtbCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9WVlZFQl84MAogICAgICAtIERCX0VOR0lORT1teXNxbGkKICAgICAgLSBEQl9IT1NUPW1hcmlhZGIKICAgICAgLSAnREJfVVNFUj0ke1NFUlZJQ0VfVVNFUl9WVlZFQn0nCiAgICAgIC0gJ0RCX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9WVlZFQn0nCiAgICAgIC0gJ0RCX05BTUU9JHtNQVJJQURCX0RBVEFCQVNFOi12dnZlYn0nCiAgICBkZXBlbmRzX29uOgogICAgICBtYXJpYWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjEnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTAKICBtYXJpYWRiOgogICAgaW1hZ2U6ICdtYXJpYWRiOjExJwogICAgdm9sdW1lczoKICAgICAgLSAndnZ2ZWItbWFyaWFkYi1kYXRhOi92YXIvbGliL215c3FsJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ01ZU1FMX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1JPT1R9JwogICAgICAtICdNWVNRTF9EQVRBQkFTRT0ke01BUklBREJfREFUQUJBU0U6LXZ2dmVifScKICAgICAgLSAnTVlTUUxfVVNFUj0ke1NFUlZJQ0VfVVNFUl9WVlZFQn0nCiAgICAgIC0gJ01ZU1FMX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9WVlZFQn0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gaGVhbHRoY2hlY2suc2gKICAgICAgICAtICctLWNvbm5lY3QnCiAgICAgICAgLSAnLS1pbm5vZGJfaW5pdGlhbGl6ZWQnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "tags": [ + "cms", + "blog", + "content", + "management", + "ecommerce", + "page-builder", + "nocode", + "mysql", + "sqlite", + "pgsql" + ], + "logo": "svgs/vvveb.svg", + "minversion": "0.0.0", + "port": "80" + }, + "vvveb-with-mysql": { + "documentation": "https://docs.vvveb.com?utm_source=coolify.io", + "slogan": "Powerful and easy to use cms to build websites, blogs or ecommerce stores.", + "compose": "c2VydmljZXM6CiAgdnZ2ZWI6CiAgICBpbWFnZTogJ3Z2dmViL3Z2dmViY21zOmxhdGVzdCcKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Z2dmViLWRhdGE6L3Zhci93d3cvaHRtbCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9WVlZFQl84MAogICAgICAtIERCX0VOR0lORT1teXNxbGkKICAgICAgLSBEQl9IT1NUPW15c3FsCiAgICAgIC0gJ0RCX1VTRVI9JHtTRVJWSUNFX1VTRVJfVlZWRUJ9JwogICAgICAtICdEQl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfVlZWRUJ9JwogICAgICAtICdEQl9OQU1FPSR7TVlTUUxfREFUQUJBU0U6LXZ2dmVifScKICAgIGRlcGVuZHNfb246CiAgICAgIG15c3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjEnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTAKICBteXNxbDoKICAgIGltYWdlOiAnbXlzcWw6OC40LjInCiAgICB2b2x1bWVzOgogICAgICAtICd2dnZlYi1teXNxbC1kYXRhOi92YXIvbGliL215c3FsJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ01ZU1FMX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1JPT1R9JwogICAgICAtICdNWVNRTF9EQVRBQkFTRT0ke01ZU1FMX0RBVEFCQVNFOi12dnZlYn0nCiAgICAgIC0gJ01ZU1FMX1VTRVI9JHtTRVJWSUNFX1VTRVJfVlZWRUJ9JwogICAgICAtICdNWVNRTF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfVlZWRUJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIG15c3FsYWRtaW4KICAgICAgICAtIHBpbmcKICAgICAgICAtICctaCcKICAgICAgICAtIDEyNy4wLjAuMQogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCg==", + "tags": [ + "cms", + "blog", + "content", + "management", + "ecommerce", + "page-builder", + "nocode", + "mysql", + "sqlite", + "pgsql" + ], + "logo": "svgs/vvveb.svg", + "minversion": "0.0.0", + "port": "80" + }, + "vvveb": { + "documentation": "https://docs.vvveb.com?utm_source=coolify.io", + "slogan": "Powerful and easy to use cms to build websites, blogs or ecommerce stores.", + "compose": "c2VydmljZXM6CiAgdnZ2ZWI6CiAgICBpbWFnZTogJ3Z2dmViL3Z2dmViY21zOmxhdGVzdCcKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Z2dmViLWRhdGE6L3Zhci93d3cvaHRtbCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9WVlZFQl84MAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDEwCg==", + "tags": [ + "cms", + "blog", + "content", + "management", + "ecommerce", + "page-builder", + "nocode", + "mysql", + "sqlite", + "pgsql" + ], + "logo": "svgs/vvveb.svg", + "minversion": "0.0.0", + "port": "80" + }, "weaviate": { "documentation": "https://weaviate.io/developers/weaviate?utm_source=coolify.io", "slogan": "Weaviate is an open-source vector database that stores both objects and vectors, allowing for combining vector search with structured filtering.", @@ -2276,5 +2726,44 @@ ], "logo": "svgs/wordpress.svg", "minversion": "0.0.0" + }, + "zep": { + "documentation": "https://help.getzep.com/concepts?utm_source=coolify.io", + "slogan": "Zep enhances your AI agent's knowledge through continuous learning from user interactions, enabling personalized experiences and improved accuracy.", + "compose": "c2VydmljZXM6CiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ2doY3IuaW8vZ2V0emVwL3Bvc3RncmVzOnBvc3RncmVzLTE1JwogICAgc2htX3NpemU6IDEyOG1iCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICB2b2x1bWVzOgogICAgICAtICdwZ19kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtaCBsb2NhbGhvc3QgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgcG9zdGdyZXMnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgbmxwOgogICAgaW1hZ2U6ICdnaGNyLmlvL2dldHplcC96ZXAtbmxwLXNlcnZlcjowLjQnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTkxQXzU1NTcKICAgICAgLSAnWkVQX09QRU5BSV9BUElfS0VZPSR7T1BFTkFJX0FQSV9LRVl9JwogICAgICAtICdaRVBfQVVUSF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0FVVEhTRUNSRVR9JwogICAgICAtICdaRVBfU0VSVkVSX1dFQl9FTkFCTEVEPSR7WkVQX1NFUlZFUl9XRUJfRU5BQkxFRDotZmFsc2V9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6ICJ0aW1lb3V0IDEwcyBiYXNoIC1jICc6PiAvZGV2L3RjcC8xMjcuMC4wLjEvNTU1NycgfHwgZXhpdCAxIgogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiA0NXMKICB6ZXA6CiAgICBpbWFnZTogJ2doY3IuaW8vZ2V0emVwL3plcDpsYXRlc3QnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBubHA6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9aRVBfODAwMAogICAgICAtICdaRVBfU1RPUkVfUE9TVEdSRVNfRFNOPXBvc3RncmVzOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AcG9zdGdyZXM6NTQzMi9wb3N0Z3Jlcz9zc2xtb2RlPWRpc2FibGUnCiAgICAgIC0gJ1pFUF9OTFBfU0VSVkVSX1VSTD1odHRwOi8vbmxwOjU1NTcnCiAgICAgIC0gJ1pFUF9FWFRSQUNUT1JTX0RPQ1VNRU5UU19FTUJFRERJTkdTX1NFUlZJQ0U9JHtFWFRSQUNUT1JTX0RPQ1VNRU5UU19FTUJFRERJTkdTX1NFUlZJQ0U6LW9wZW5haX0nCiAgICAgIC0gJ1pFUF9FWFRSQUNUT1JTX0RPQ1VNRU5UU19FTUJFRERJTkdTX0RJTUVOU0lPTlM9JHtFWFRSQUNUT1JTX0RPQ1VNRU5UU19FTUJFRERJTkdTX0RJTUVOU0lPTlM6LTE1MzZ9JwogICAgICAtICdaRVBfRVhUUkFDVE9SU19NRVNTQUdFU19FTUJFRERJTkdTX1NFUlZJQ0U9JHtFWFRSQUNUT1JTX01FU1NBR0VTX0VNQkVERElOR1NfU0VSVklDRTotb3BlbmFpfScKICAgICAgLSAnWkVQX0VYVFJBQ1RPUlNfTUVTU0FHRVNfRU1CRURESU5HU19ESU1FTlNJT05TPSR7RVhUUkFDVE9SU19NRVNTQUdFU19FTUJFRERJTkdTX0RJTUVOU0lPTlM6LTE1MzZ9JwogICAgICAtICdaRVBfRVhUUkFDVE9SU19NRVNTQUdFU19TVU1NQVJJWkVSX0VNQkVERElOR1NfU0VSVklDRT0ke0VYVFJBQ1RPUlNfTUVTU0FHRVNfU1VNTUFSSVpFUl9FTUJFRERJTkdTX1NFUlZJQ0U6LW9wZW5haX0nCiAgICAgIC0gJ1pFUF9FWFRSQUNUT1JTX01FU1NBR0VTX1NVTU1BUklaRVJfRU1CRURESU5HU19ESU1FTlNJT05TPSR7RVhUUkFDVE9SU19NRVNTQUdFU19TVU1NQVJJWkVSX0VNQkVERElOR1NfRElNRU5TSU9OUzotMTUzNn0nCiAgICAgIC0gJ1pFUF9PUEVOQUlfQVBJX0tFWT0ke09QRU5BSV9BUElfS0VZfScKICAgICAgLSAnWkVQX0FVVEhfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9BVVRIU0VDUkVUfScKICAgICAgLSAnWkVQX1NFUlZFUl9XRUJfRU5BQkxFRD0ke1pFUF9TRVJWRVJfV0VCX0VOQUJMRUQ6LWZhbHNlfScKICAgIHZvbHVtZXM6CiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL2NvbmZpZy55YW1sCiAgICAgICAgdGFyZ2V0OiAvYXBwL2NvbmZpZy55YW1sCiAgICAgICAgY29udGVudDogImxsbTpcbiAgIyBvcGVuYWkgb3IgYW50aHJvcGljXG4gIHNlcnZpY2U6IFwib3BlbmFpXCJcbiAgIyBPcGVuQUk6IGdwdC0zLjUtdHVyYm8sIGdwdC00LCBncHQtMy41LXR1cmJvLTExMDYsIGdwdC0zLjUtdHVyYm8tMTZrLCBncHQtNC0zMmssIGdwdC00by1taW5pLCBncHQtNG8tbWluaS0yMDI0LTA3LTE4OyBBbnRocm9waWM6IGNsYXVkZS1pbnN0YW50LTEgb3IgY2xhdWRlLTJcbiAgbW9kZWw6IFwiZ3B0LTRvLW1pbmlcIlxuICAjIyBPcGVuQUktc3BlY2lmaWMgc2V0dGluZ3NcbiAgIyBPbmx5IHVzZWQgZm9yIEF6dXJlIE9wZW5BSSBBUElcbiAgYXp1cmVfb3BlbmFpX2VuZHBvaW50OlxuICAjIGZvciBBenVyZSBPcGVuQUkgQVBJIGRlcGxveW1lbnQsIHRoZSBtb2RlbCBtYXkgYmUgZGVwbG95ZWQgd2l0aCBjdXN0b20gZGVwbG95bWVudCBuYW1lc1xuICAjIHNldCB0aGUgZGVwbG95bWVudCBuYW1lcyBpZiB5b3UgZW5jb3VudGVyIGluIGxvZ3MgSFRUUCA0MDQgZXJyb3JzOlxuICAjICAgXCJUaGUgQVBJIGRlcGxveW1lbnQgZm9yIHRoaXMgcmVzb3VyY2UgZG9lcyBub3QgZXhpc3QuXCJcbiAgYXp1cmVfb3BlbmFpOlxuICAjIGxsbS5tb2RlbCBuYW1lIGlzIHVzZWQgYXMgZGVwbG95bWVudCBuYW1lIGFzIHJlYXNvbmFibGUgZGVmYXVsdCBpZiBub3Qgc2V0XG4gICMgYXNzdW1pbmcgYmFzZSBtb2RlbCBpcyBkZXBsb3llZCB3aXRoIGRlcGxveW1lbnQgbmFtZSBtYXRjaGluZyBtb2RlbCBuYW1lXG4gICMgICBsbG1fZGVwbG95bWVudDogXCJncHQtNG8tbWluaS1jdXN0b21uYW1lXCJcbiAgIyBlbWJlZGRpbmdzIGRlcGxveW1lbnQgaXMgcmVxdWlyZWQgd2hlbiBaZXAgaXMgY29uZmlndXJlZCB0byB1c2UgT3BlbkFJIGVtYmVkZGluZ3NcbiAgIyAgIGVtYmVkZGluZ19kZXBsb3ltZW50OiBcInRleHQtZW1iZWRkaW5nLWFkYS0wMDItY3VzdG9tbmFtZVwiXG4gICMgVXNlIG9ubHkgd2l0aCBhbiBhbHRlcm5hdGUgT3BlbkFJLWNvbXBhdGlibGUgQVBJIGVuZHBvaW50XG4gICAgbGxtX2RlcGxveW1lbnQ6XG4gICAgZW1iZWRkaW5nX2RlcGxveW1lbnQ6XG4gIG9wZW5haV9lbmRwb2ludDpcbiAgb3BlbmFpX29yZ19pZDpcbm5scDpcbiAgc2VydmVyX3VybDogXCJodHRwOi8vbG9jYWxob3N0OjU1NTdcIlxubWVtb3J5OlxuICBtZXNzYWdlX3dpbmRvdzogMTJcbmV4dHJhY3RvcnM6XG4gIGRvY3VtZW50czpcbiAgICBlbWJlZGRpbmdzOlxuICAgICAgZW5hYmxlZDogdHJ1ZVxuICAgICAgY2h1bmtfc2l6ZTogMTAwMFxuICAgICAgZGltZW5zaW9uczogMzg0XG4gICAgICBzZXJ2aWNlOiBcImxvY2FsXCJcbiMgICAgICBkaW1lbnNpb25zOiAxNTM2XG4jICAgICAgc2VydmljZTogXCJvcGVuYWlcIlxuICBtZXNzYWdlczpcbiAgICBzdW1tYXJpemVyOlxuICAgICAgZW5hYmxlZDogdHJ1ZVxuICAgICAgZW50aXRpZXM6XG4gICAgICAgIGVuYWJsZWQ6IHRydWVcbiAgICAgIGVtYmVkZGluZ3M6XG4gICAgICAgIGVuYWJsZWQ6IHRydWVcbiAgICAgICAgZGltZW5zaW9uczogMzg0XG4gICAgICAgIHNlcnZpY2U6IFwibG9jYWxcIlxuICAgIGVudGl0aWVzOlxuICAgICAgZW5hYmxlZDogdHJ1ZVxuICAgIGludGVudDpcbiAgICAgIGVuYWJsZWQ6IHRydWVcbiAgICBlbWJlZGRpbmdzOlxuICAgICAgZW5hYmxlZDogdHJ1ZVxuICAgICAgZGltZW5zaW9uczogMzg0XG4gICAgICBzZXJ2aWNlOiBcImxvY2FsXCJcbiMgICAgICBkaW1lbnNpb25zOiAxNTM2XG4jICAgICAgc2VydmljZTogXCJvcGVuYWlcIlxuc3RvcmU6XG4gIHR5cGU6IFwicG9zdGdyZXNcIlxuICBwb3N0Z3JlczpcbiAgICBkc246IFwicG9zdGdyZXM6Ly9wb3N0Z3Jlczpwb3N0Z3Jlc0Bsb2NhbGhvc3Q6NTQzMi8/c3NsbW9kZT1kaXNhYmxlXCJcbnNlcnZlcjpcbiAgIyBTcGVjaWZ5IHRoZSBob3N0IHRvIGxpc3RlbiBvbi4gRGVmYXVsdHMgdG8gMC4wLjAuMFxuICBob3N0OiAwLjAuMC4wXG4gIHBvcnQ6IDgwMDBcbiAgIyBJcyB0aGUgV2ViIFVJIGVuYWJsZWQ/XG4gICMgV2FybmluZzogVGhlIFdlYiBVSSBpcyBub3Qgc2VjdXJlZCBieSBhdXRoZW50aWNhdGlvbiBhbmQgc2hvdWxkIG5vdCBiZSBlbmFibGVkIGlmXG4gICMgWmVwIGlzIGV4cG9zZWQgdG8gdGhlIHB1YmxpYyBpbnRlcm5ldC5cbiAgd2ViX2VuYWJsZWQ6IHRydWVcbiAgIyBUaGUgbWF4aW11bSBzaXplIG9mIGEgcmVxdWVzdCBib2R5LCBpbiBieXRlcy4gRGVmYXVsdHMgdG8gNU1CLlxuICBtYXhfcmVxdWVzdF9zaXplOiA1MjQyODgwXG5hdXRoOlxuICAjIFNldCB0byB0cnVlIHRvIGVuYWJsZSBhdXRoZW50aWNhdGlvblxuICByZXF1aXJlZDogdHJ1ZVxuICAjIERvIG5vdCB1c2UgdGhpcyBzZWNyZXQgaW4gcHJvZHVjdGlvbi4gVGhlIFpFUF9BVVRIX1NFQ1JFVCBlbnZpcm9ubWVudCB2YXJpYWJsZSBzaG91bGQgYmVcbiAgIyBzZXQgdG8gYSBjcnlwdG9ncmFwaGljYWxseSBzZWN1cmUgc2VjcmV0LiBTZWUgdGhlIFplcCBkb2NzIGZvciBkZXRhaWxzLlxuICBzZWNyZXQ6IFwiZG8tbm90LXVzZS10aGlzLXNlY3JldC1pbi1wcm9kdWN0aW9uXCJcbmRhdGE6XG4gICMgIFB1cmdlRXZlcnkgaXMgdGhlIHBlcmlvZCBiZXR3ZWVuIGhhcmQgZGVsZXRlcywgaW4gbWludXRlcy5cbiAgIyAgSWYgc2V0IHRvIDAgb3IgdW5kZWZpbmVkLCBoYXJkIGRlbGV0ZXMgd2lsbCBub3QgYmUgcGVyZm9ybWVkLlxuICBwdXJnZV9ldmVyeTogNjBcbmxvZzpcbiAgbGV2ZWw6IFwiaW5mb1wiXG5vcGVudGVsZW1ldHJ5OlxuICBlbmFibGVkOiBmYWxzZVxuIyBDdXN0b20gUHJvbXB0cyBDb25maWd1cmF0aW9uXG4jIEFsbG93cyBjdXN0b21pemF0aW9uIG9mIGV4dHJhY3RvciBwcm9tcHRzLlxuY3VzdG9tX3Byb21wdHM6XG4gIHN1bW1hcml6ZXJfcHJvbXB0czpcbiAgICAjIEFudGhyb3BpYyBHdWlkZWxpbmVzOlxuICAgICMgLSBVc2UgWE1MLXN0eWxlIHRhZ3MgbGlrZSA8Y3VycmVudF9zdW1tYXJ5PiBhcyBlbGVtZW50IGlkZW50aWZpZXJzLlxuICAgICMgLSBJbmNsdWRlIHt7LlByZXZTdW1tYXJ5fX0gYW5kIHt7Lk1lc3NhZ2VzSm9pbmVkfX0gYXMgdGVtcGxhdGUgdmFyaWFibGVzLlxuICAgICMgLSBDbGVhcmx5IGV4cGxhaW4gbW9kZWwgaW5zdHJ1Y3Rpb25zLCBlLmcuLCBcIlJldmlldyBjb250ZW50IGluc2lkZSA8Y3VycmVudF9zdW1tYXJ5PjwvY3VycmVudF9zdW1tYXJ5PiB0YWdzXCIuXG4gICAgIyAtIFByb3ZpZGUgYSBjbGVhciBleGFtcGxlIHdpdGhpbiB0aGUgcHJvbXB0LlxuICAgICNcbiAgICAjIEV4YW1wbGUgZm9ybWF0OlxuICAgICMgYW50aHJvcGljOiB8XG4gICAgIyAgIDxZT1VSIElOU1RSVUNUSU9OUyBIRVJFPlxuICAgICMgICA8ZXhhbXBsZT5cbiAgICAjICAgICA8UFJPVklERSBBTiBFWEFNUExFPlxuICAgICMgICA8L2V4YW1wbGU+XG4gICAgIyAgIDxjdXJyZW50X3N1bW1hcnk+e3suUHJldlN1bW1hcnl9fTwvY3VycmVudF9zdW1tYXJ5PlxuICAgICMgICA8bmV3X2xpbmVzPnt7Lk1lc3NhZ2VzSm9pbmVkfX08L25ld19saW5lcz5cbiAgICAjICAgUmVzcG9uc2Ugd2l0aG91dCBwcmVhbWJsZS5cbiAgICAjXG4gICAgIyBJZiBsZWZ0IGVtcHR5LCB0aGUgZGVmYXVsdCBBbnRocm9waWMgc3VtbWFyeSBwcm9tcHQgZnJvbSB6ZXAvcGtnL2V4dHJhY3RvcnMvcHJvbXB0cy5nbyB3aWxsIGJlIHVzZWQuXG4gICAgYW50aHJvcGljOiB8XG5cbiAgICAjIE9wZW5BSSBzdW1tYXJpemVyIHByb21wdCBjb25maWd1cmF0aW9uLlxuICAgICMgR3VpZGVsaW5lczpcbiAgICAjIC0gSW5jbHVkZSB7ey5QcmV2U3VtbWFyeX19IGFuZCB7ey5NZXNzYWdlc0pvaW5lZH19IGFzIHRlbXBsYXRlIHZhcmlhYmxlcy5cbiAgICAjIC0gUHJvdmlkZSBhIGNsZWFyIGV4YW1wbGUgd2l0aGluIHRoZSBwcm9tcHQuXG4gICAgI1xuICAgICMgRXhhbXBsZSBmb3JtYXQ6XG4gICAgIyBvcGVuYWk6IHxcbiAgICAjICAgPFlPVVIgSU5TVFJVQ1RJT05TIEhFUkU+XG4gICAgIyAgIEV4YW1wbGU6XG4gICAgIyAgICAgPFBST1ZJREUgQU4gRVhBTVBMRT5cbiAgICAjICAgQ3VycmVudCBzdW1tYXJ5OiB7ey5QcmV2U3VtbWFyeX19XG4gICAgIyAgIE5ldyBsaW5lcyBvZiBjb252ZXJzYXRpb246IHt7Lk1lc3NhZ2VzSm9pbmVkfX1cbiAgICAjICAgTmV3IHN1bW1hcnk6YFxuICAgICNcbiAgICAjIElmIGxlZnQgZW1wdHksIHRoZSBkZWZhdWx0IE9wZW5BSSBzdW1tYXJ5IHByb21wdCBmcm9tIHplcC9wa2cvZXh0cmFjdG9ycy9wcm9tcHRzLmdvIHdpbGwgYmUgdXNlZC5cbiAgICBvcGVuYWk6IHwiCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDogInRpbWVvdXQgMTBzIGJhc2ggLWMgJzo+IC9kZXYvdGNwLzEyNy4wLjAuMS84MDAwJyB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogICAgICBzdGFydF9wZXJpb2Q6IDQwcwo=", + "tags": [ + "lowcode", + "nocode", + "ai", + "llm", + "openai", + "anthropic", + "machine-learning", + "rag", + "agents", + "chatbot", + "api", + "team", + "bot", + "flows", + "memory" + ], + "logo": "svgs/zep.png", + "minversion": "0.0.0", + "port": "8000" + }, + "zipline": { + "documentation": "https://github.com/diced/zipline?utm_source=coolify.io", + "slogan": "A ShareX/file upload server that is easy to use, packed with features, and with an easy setup!", + "compose": "c2VydmljZXM6CiAgemlwbGluZToKICAgIGltYWdlOiAnZ2hjci5pby9kaWNlZC96aXBsaW5lOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9aSVBMSU5FXzMwMDAKICAgICAgLSAnQ09SRV9SRVRVUk5fSFRUUFM9JHtDT1JFX1JFVFVSTl9IVFRQUzotZmFsc2V9JwogICAgICAtICdDT1JFX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfNjRfWklQTElORX0nCiAgICAgIC0gJ0NPUkVfREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AcG9zdGdyZXMvJHtQT1NUR1JFU19EQjotemlwbGluZS1kYn0nCiAgICAgIC0gJ0NPUkVfTE9HR0VSPSR7Q09SRV9MT0dHRVI6LXRydWV9JwogICAgdm9sdW1lczoKICAgICAgLSAnemlwbGluZS11cGxvYWRzOi96aXBsaW5lL3VwbG9hZHMnCiAgICAgIC0gJ3ppcGxpbmUtcHVibGljOi96aXBsaW5lL3B1YmxpYycKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy1xJwogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMC9hdXRoL2xvZ2luJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3ppcGxpbmUtcG9zdGdyZXMtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LXppcGxpbmUtZGJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=", + "tags": [ + "zipline", + "file-sharing", + "upload", + "sharing" + ], + "logo": "svgs/zipline.png", + "minversion": "0.0.0", + "port": "3000" } } From ea7c96a6600bf5341235aa6a0978b3582a59cfb8 Mon Sep 17 00:00:00 2001 From: Vik Borges Date: Fri, 11 Oct 2024 12:59:55 +0800 Subject: [PATCH 072/500] =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/svgs/litequeen.svg | 1 + templates/compose/litequeen.yaml | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 public/svgs/litequeen.svg create mode 100644 templates/compose/litequeen.yaml diff --git a/public/svgs/litequeen.svg b/public/svgs/litequeen.svg new file mode 100644 index 000000000..aa0b8e038 --- /dev/null +++ b/public/svgs/litequeen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/compose/litequeen.yaml b/templates/compose/litequeen.yaml new file mode 100644 index 000000000..5ab19ee98 --- /dev/null +++ b/templates/compose/litequeen.yaml @@ -0,0 +1,15 @@ +# documentation: https://litequeen.com/ +# slogan: Manage SQLite databases on your server with ease. +# tags: sqlite, sqlite-database-management, self-hosted, VPS +# logo: svgs/litequeen.svg +# port: 8000 + +services: + litequeen: + image: kivsegrob/lite-queen:latest + environment: + - SERVICE_FQDN_LITEQUEEN_8000 + - SQLITE_DATABASES_LOCATION=${SQLITE_DATABASES_LOCATION} + volumes: + - litequeen-data:/home/litequeen/data + - ${SQLITE_DATABASES_LOCATION}:/www From bf1dd72176c48dee409bb00573d0dc6295e0bda5 Mon Sep 17 00:00:00 2001 From: Kanhai Chhugani Date: Fri, 11 Oct 2024 10:46:34 +0530 Subject: [PATCH 073/500] adding osticket service --- public/svgs/osticket.png | Bin 0 -> 12347 bytes templates/compose/osticket.yaml | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 public/svgs/osticket.png create mode 100644 templates/compose/osticket.yaml diff --git a/public/svgs/osticket.png b/public/svgs/osticket.png new file mode 100644 index 0000000000000000000000000000000000000000..65885b71b8ffce9c7b0a30a76bfbf2d523364408 GIT binary patch literal 12347 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 QKLr5PpKB>sJ%hjdAG@yD{{R30 literal 0 HcmV?d00001 diff --git a/templates/compose/osticket.yaml b/templates/compose/osticket.yaml new file mode 100644 index 000000000..286d0e55e --- /dev/null +++ b/templates/compose/osticket.yaml @@ -0,0 +1,57 @@ +# documentation: https://docs.osticket.com/en/latest/ +# slogan: osTicket is a widely-used open source support ticket system. It seamlessly integrates inquiries created via email, phone and web-based forms into a simple easy-to-use multi-user web interface. Manage, organize and archive all your support requests and responses in one place while providing your customers with accountability and responsiveness they deserve. +# tags: helpdesk, ticketing, support, open-source +# port: 80 + +services: + osticket: + image: tiredofit/osticket + restart: always + environment: + - 'APP_URL=${SERVICE_FQDN_OSTICKET}' + - CRON_INTERVAL=10 + - DB_HOST=mariadb + - 'DB_NAME=${OSTICKET_DATABASE:-osticket}' + - 'DB_USER=${SERVICE_USER_MARIADB}' + - 'DB_PASS=${SERVICE_PASSWORD_MARIADB}' + - 'INSTALL_SECRET=${SERVICE_PASSWORD_OSTICKETSECRET}' + - 'ADMIN_FIRSTNAME=${OSTICKET_FIRSTNAME:-Admin}' + - 'ADMIN_LASTNAME=${OSTICKET_LASTNAME:-istrator}' + - 'ADMIN_EMAIL=${OSTICKET_ADMIN_EMAIL:-admin@example.com}' + - 'ADMIN_USER=${OSTICKET_ADMIN_USER:-admin}' + - 'ADMIN_PASS=${SERVICE_PASSWORD_OSTICKETADMINPASS}' + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1/"] + start_period: 10s + interval: 10s + timeout: 5s + retries: 3 + depends_on: + - mariadb + links: + - mariadb + volumes: + - 'osticket_data:/www/osticket' + mariadb: + image: 'mariadb:11' + restart: always + environment: + MARIADB_ROOT_PASSWORD: '${SERVICE_PASSWORD_MARIADBROOT}' + MARIADB_DATABASE: '${OSTICKET_DATABASE:-osticket}' + MARIADB_USER: '${SERVICE_USER_MARIADB}' + MARIADB_PASSWORD: '${SERVICE_PASSWORD_MARIADB}' + healthcheck: + test: + - CMD + - healthcheck.sh + - '--connect' + - '--innodb_initialized' + start_period: 10s + interval: 10s + timeout: 5s + retries: 3 + volumes: + - 'db_data:/var/lib/mysql' +volumes: + db_data: { } + osticket_data: { } From effe425b9572787dc22fccaf2dd3573151cafcf7 Mon Sep 17 00:00:00 2001 From: Vik Borges Date: Fri, 11 Oct 2024 13:40:28 +0800 Subject: [PATCH 074/500] mount host sqlite directory --- templates/compose/litequeen.yaml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/templates/compose/litequeen.yaml b/templates/compose/litequeen.yaml index 5ab19ee98..34bf390a0 100644 --- a/templates/compose/litequeen.yaml +++ b/templates/compose/litequeen.yaml @@ -1,6 +1,6 @@ # documentation: https://litequeen.com/ # slogan: Manage SQLite databases on your server with ease. -# tags: sqlite, sqlite-database-management, self-hosted, VPS +# tags: sqlite, sqlite-database-management, self-hosted, VPS, database # logo: svgs/litequeen.svg # port: 8000 @@ -9,7 +9,11 @@ services: image: kivsegrob/lite-queen:latest environment: - SERVICE_FQDN_LITEQUEEN_8000 - - SQLITE_DATABASES_LOCATION=${SQLITE_DATABASES_LOCATION} + - SQLITE_DATABASES_LOCATION=${SQLITE_DATABASES_LOCATION:-/var/www} volumes: - litequeen-data:/home/litequeen/data - - ${SQLITE_DATABASES_LOCATION}:/www + - type: bind + source: ${SQLITE_DATABASES_LOCATION} + target: /www + is_directory: true + From a03288ab6f0f26a55388d1d4bd8ebc48d06702d3 Mon Sep 17 00:00:00 2001 From: Vik Borges Date: Fri, 11 Oct 2024 13:58:36 +0800 Subject: [PATCH 075/500] healthcheck --- templates/compose/litequeen.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/templates/compose/litequeen.yaml b/templates/compose/litequeen.yaml index 34bf390a0..28b7901a7 100644 --- a/templates/compose/litequeen.yaml +++ b/templates/compose/litequeen.yaml @@ -16,4 +16,10 @@ services: source: ${SQLITE_DATABASES_LOCATION} target: /www is_directory: true - + healthcheck: + test: + - CMD-SHELL + - bash -c ':> /dev/tcp/127.0.0.1/8000' || exit 1 + interval: 5s + timeout: 5s + retries: 3 From ed9410e3c2a9b0b5ce96f0ae14fcb5722858569b Mon Sep 17 00:00:00 2001 From: Vik Borges Date: Fri, 11 Oct 2024 14:16:20 +0800 Subject: [PATCH 076/500] =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/compose/litequeen.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/litequeen.yaml b/templates/compose/litequeen.yaml index 28b7901a7..2af8c65a2 100644 --- a/templates/compose/litequeen.yaml +++ b/templates/compose/litequeen.yaml @@ -1,5 +1,5 @@ # documentation: https://litequeen.com/ -# slogan: Manage SQLite databases on your server with ease. +# slogan: Lite Queen is an open-source SQLite database management software that runs on your server. # tags: sqlite, sqlite-database-management, self-hosted, VPS, database # logo: svgs/litequeen.svg # port: 8000 From b4a8f38485e893309235e9cfee060be609f54f9f Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 11 Oct 2024 11:19:34 +0200 Subject: [PATCH 077/500] fix litequeen --- templates/compose/litequeen.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/compose/litequeen.yaml b/templates/compose/litequeen.yaml index 2af8c65a2..134c51575 100644 --- a/templates/compose/litequeen.yaml +++ b/templates/compose/litequeen.yaml @@ -9,12 +9,12 @@ services: image: kivsegrob/lite-queen:latest environment: - SERVICE_FQDN_LITEQUEEN_8000 - - SQLITE_DATABASES_LOCATION=${SQLITE_DATABASES_LOCATION:-/var/www} + - SQLITE_DATABASES_LOCATION=${SQLITE_DATABASES_LOCATION:-./var/www/html} volumes: - litequeen-data:/home/litequeen/data - type: bind source: ${SQLITE_DATABASES_LOCATION} - target: /www + target: /var/www/html is_directory: true healthcheck: test: From 77600e9f461f4f27457c1fa78c6fecde3f38c09a Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 11 Oct 2024 11:37:14 +0200 Subject: [PATCH 078/500] fix osticket --- templates/compose/osticket.yaml | 52 +++++++++++++++------------------ 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/templates/compose/osticket.yaml b/templates/compose/osticket.yaml index 286d0e55e..7e2fbcbcf 100644 --- a/templates/compose/osticket.yaml +++ b/templates/compose/osticket.yaml @@ -1,25 +1,26 @@ # documentation: https://docs.osticket.com/en/latest/ -# slogan: osTicket is a widely-used open source support ticket system. It seamlessly integrates inquiries created via email, phone and web-based forms into a simple easy-to-use multi-user web interface. Manage, organize and archive all your support requests and responses in one place while providing your customers with accountability and responsiveness they deserve. +# slogan: osTicket is a widely-used open source support ticket system. # tags: helpdesk, ticketing, support, open-source +# logo: svgs/osticket.png # port: 80 services: osticket: - image: tiredofit/osticket - restart: always + image: tiredofit/osticket:latest environment: - - 'APP_URL=${SERVICE_FQDN_OSTICKET}' - - CRON_INTERVAL=10 + - SERVICE_FQDN_OSTICKET_80 + - APP_URL=${SERVICE_FQDN_OSTICKET} + - CRON_INTERVAL=${CRON_INTERVAL:-10} - DB_HOST=mariadb - - 'DB_NAME=${OSTICKET_DATABASE:-osticket}' - - 'DB_USER=${SERVICE_USER_MARIADB}' - - 'DB_PASS=${SERVICE_PASSWORD_MARIADB}' - - 'INSTALL_SECRET=${SERVICE_PASSWORD_OSTICKETSECRET}' - - 'ADMIN_FIRSTNAME=${OSTICKET_FIRSTNAME:-Admin}' - - 'ADMIN_LASTNAME=${OSTICKET_LASTNAME:-istrator}' - - 'ADMIN_EMAIL=${OSTICKET_ADMIN_EMAIL:-admin@example.com}' - - 'ADMIN_USER=${OSTICKET_ADMIN_USER:-admin}' - - 'ADMIN_PASS=${SERVICE_PASSWORD_OSTICKETADMINPASS}' + - DB_NAME=${OSTICKET_DATABASE:-osticket-db} + - DB_USER=${SERVICE_USER_MARIADB} + - DB_PASS=${SERVICE_PASSWORD_MARIADB} + - INSTALL_SECRET=${SERVICE_PASSWORD_OSTICKETSECRET} + - ADMIN_FIRSTNAME=${OSTICKET_FIRSTNAME:-Admin} + - ADMIN_LASTNAME=${OSTICKET_LASTNAME:-istrator} + - ADMIN_EMAIL=${OSTICKET_ADMIN_EMAIL:-admin@example.com} + - ADMIN_USER=${SERVICE_USER_OSTICKETADMIN} + - ADMIN_PASS=${SERVICE_PASSWORD_OSTICKETADMINPASS} healthcheck: test: ["CMD", "curl", "-f", "http://127.0.0.1/"] start_period: 10s @@ -27,19 +28,17 @@ services: timeout: 5s retries: 3 depends_on: - - mariadb - links: - - mariadb + mariadb: + condition: service_healthy volumes: - - 'osticket_data:/www/osticket' + - osticket-data:/www/osticket mariadb: - image: 'mariadb:11' - restart: always + image: mariadb:11 environment: - MARIADB_ROOT_PASSWORD: '${SERVICE_PASSWORD_MARIADBROOT}' - MARIADB_DATABASE: '${OSTICKET_DATABASE:-osticket}' - MARIADB_USER: '${SERVICE_USER_MARIADB}' - MARIADB_PASSWORD: '${SERVICE_PASSWORD_MARIADB}' + MARIADB_ROOT_PASSWORD: ${SERVICE_PASSWORD_MARIADBROOT} + MARIADB_DATABASE: ${OSTICKET_DATABASE:-osticket-db} + MARIADB_USER: ${SERVICE_USER_MARIADB} + MARIADB_PASSWORD: ${SERVICE_PASSWORD_MARIADB} healthcheck: test: - CMD @@ -51,7 +50,4 @@ services: timeout: 5s retries: 3 volumes: - - 'db_data:/var/lib/mysql' -volumes: - db_data: { } - osticket_data: { } + - osticket-mariadb-data:/var/lib/mysql From 8e004a28303f73c7e43d86b1ac4d4c440986f20f Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 11 Oct 2024 11:45:26 +0200 Subject: [PATCH 079/500] Update service-templates.json --- templates/service-templates.json | 78 +++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/templates/service-templates.json b/templates/service-templates.json index 471abc9fb..ff9310135 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -647,7 +647,54 @@ "minversion": "0.0.0", "port": "8080" }, - + "flowise-with-databases": { + "documentation": "https://docs.flowiseai.com/?utm_source=coolify.io", + "slogan": "Flowise is an open source low-code tool for developers to build customized LLM orchestration flows & AI agents. Also deploys Redis, Postgres and other services.", + "compose": "c2VydmljZXM6CiAgZmxvd2lzZToKICAgIGltYWdlOiAnZmxvd2lzZWFpL2Zsb3dpc2U6bGF0ZXN0JwogICAgZGVwZW5kc19vbjoKICAgICAgcGctcmVjb3JkLW1hbmFnZXI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXMtY2FjaGU6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcWRyYW50OgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fRkxPV0lTRV8zMDAxCiAgICAgIC0gJ0RFQlVHPSR7REVCVUc6LWZhbHNlfScKICAgICAgLSAnRElTQUJMRV9GTE9XSVNFX1RFTEVNRVRSWT0ke0RJU0FCTEVfRkxPV0lTRV9URUxFTUVUUlk6LXRydWV9JwogICAgICAtICdQT1JUPSR7UE9SVDotMzAwMX0nCiAgICAgIC0gREFUQUJBU0VfUEFUSD0vcm9vdC8uZmxvd2lzZQogICAgICAtIEFQSUtFWV9QQVRIPS9yb290Ly5mbG93aXNlCiAgICAgIC0gU0VDUkVUS0VZX1BBVEg9L3Jvb3QvLmZsb3dpc2UKICAgICAgLSBMT0dfUEFUSD0vcm9vdC8uZmxvd2lzZS9sb2dzCiAgICAgIC0gQkxPQl9TVE9SQUdFX1BBVEg9L3Jvb3QvLmZsb3dpc2Uvc3RvcmFnZQogICAgICAtICdGTE9XSVNFX1VTRVJOQU1FPSR7U0VSVklDRV9VU0VSX0ZMT1dJU0V9JwogICAgICAtICdGTE9XSVNFX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9GTE9XSVNFfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2Zsb3dpc2UtZGF0YTovcm9vdC8uZmxvd2lzZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnd2dldCAtcU8tIGh0dHA6Ly8xMjcuMC4wLjE6MzAwMSB8fCBleGl0IDEnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAzCiAgcGctcmVjb3JkLW1hbmFnZXI6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wZy1yZWNvcmQtbWFuYWdlcn0nCiAgICB2b2x1bWVzOgogICAgICAtICdwZy1yZWNvcmQtbWFuYWdlci1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtaCBsb2NhbGhvc3QgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAKICAgICAgc3RhcnRfcGVyaW9kOiAyMHMKICByZWRpcy1jYWNoZToKICAgIGltYWdlOiAncmVkaXM6NycKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2Zsb3dpc2UtcmVkaXMtY2FjaGUtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncmVkaXMtY2xpIC1oIGxvY2FsaG9zdCAtcCA2Mzc5IHBpbmcnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAzCiAgcWRyYW50OgogICAgaW1hZ2U6ICdxZHJhbnQvcWRyYW50OmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9RRFJBTlRfNjMzMwogICAgICAtICdRRFJBTlRfX1NFUlZJQ0VfX0FQSV9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX1FEUkFOVEFQSUtFWX0nCiAgICB2b2x1bWVzOgogICAgICAtICdmbG93aXNlLXFkcmFudC1kYXRhOi9xZHJhbnQvc3RvcmFnZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAiYmFzaCAtYyAnOj4gL2Rldi90Y3AvMTI3LjAuMC4xLzYzMzMnIHx8IGV4aXQgMSIKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDMK", + "tags": [ + "lowcode", + "nocode", + "ai", + "llm", + "openai", + "anthropic", + "machine-learning", + "rag", + "agents", + "chatbot", + "api", + "team", + "bot", + "flows" + ], + "logo": "svgs/flowise.png", + "minversion": "0.0.0", + "port": "3001" + }, + "flowise": { + "documentation": "https://docs.flowiseai.com/?utm_source=coolify.io", + "slogan": "Flowise is an open source low-code tool for developers to build customized LLM orchestration flows & AI agents.", + "compose": "c2VydmljZXM6CiAgZmxvd2lzZToKICAgIGltYWdlOiAnZmxvd2lzZWFpL2Zsb3dpc2U6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0ZMT1dJU0VfMzAwMQogICAgICAtICdERUJVRz0ke0RFQlVHOi1mYWxzZX0nCiAgICAgIC0gJ0RJU0FCTEVfRkxPV0lTRV9URUxFTUVUUlk9JHtESVNBQkxFX0ZMT1dJU0VfVEVMRU1FVFJZOi10cnVlfScKICAgICAgLSAnUE9SVD0ke1BPUlQ6LTMwMDF9JwogICAgICAtIERBVEFCQVNFX1BBVEg9L3Jvb3QvLmZsb3dpc2UKICAgICAgLSBBUElLRVlfUEFUSD0vcm9vdC8uZmxvd2lzZQogICAgICAtIFNFQ1JFVEtFWV9QQVRIPS9yb290Ly5mbG93aXNlCiAgICAgIC0gTE9HX1BBVEg9L3Jvb3QvLmZsb3dpc2UvbG9ncwogICAgICAtIEJMT0JfU1RPUkFHRV9QQVRIPS9yb290Ly5mbG93aXNlL3N0b3JhZ2UKICAgICAgLSAnRkxPV0lTRV9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9GTE9XSVNFfScKICAgICAgLSAnRkxPV0lTRV9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfRkxPV0lTRX0nCiAgICB2b2x1bWVzOgogICAgICAtICdmbG93aXNlLWRhdGE6L3Jvb3QvLmZsb3dpc2UnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3dnZXQgLXFPLSBodHRwOi8vMTI3LjAuMC4xOjMwMDEgfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMwo=", + "tags": [ + "lowcode", + "nocode", + "ai", + "llm", + "openai", + "anthropic", + "machine-learning", + "rag", + "agents", + "chatbot", + "api", + "team", + "bot", + "flows" + ], + "logo": "svgs/flowise.png", + "minversion": "0.0.0", + "port": "3001" + }, "formbricks": { "documentation": "https://formbricks.com/docs/self-hosting/configuration?utm_source=coolify.io", "slogan": "Open Source Survey Platform", @@ -1278,6 +1325,21 @@ "minversion": "0.0.0", "port": "4000" }, + "litequeen": { + "documentation": "https://litequeen.com/?utm_source=coolify.io", + "slogan": "Lite Queen is an open-source SQLite database management software that runs on your server.", + "compose": "c2VydmljZXM6CiAgbGl0ZXF1ZWVuOgogICAgaW1hZ2U6ICdraXZzZWdyb2IvbGl0ZS1xdWVlbjpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTElURVFVRUVOXzgwMDAKICAgICAgLSAnU1FMSVRFX0RBVEFCQVNFU19MT0NBVElPTj0ke1NRTElURV9EQVRBQkFTRVNfTE9DQVRJT046LS4vdmFyL3d3dy9odG1sfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2xpdGVxdWVlbi1kYXRhOi9ob21lL2xpdGVxdWVlbi9kYXRhJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogJyR7U1FMSVRFX0RBVEFCQVNFU19MT0NBVElPTn0nCiAgICAgICAgdGFyZ2V0OiAvdmFyL3d3dy9odG1sCiAgICAgICAgaXNfZGlyZWN0b3J5OiB0cnVlCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gImJhc2ggLWMgJzo+IC9kZXYvdGNwLzEyNy4wLjAuMS84MDAwJyB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAzCg==", + "tags": [ + "sqlite", + "sqlite-database-management", + "self-hosted", + "vps", + "database" + ], + "logo": "svgs/litequeen.svg", + "minversion": "0.0.0", + "port": "8000" + }, "logto": { "documentation": "https://docs.logto.io/docs/tutorials/get-started/#logto-oss-self-hosted?utm_source=coolify.io", "slogan": "A comprehensive identity solution covering both the front and backend, complete with pre-built infrastructure and enterprise-grade solutions.", @@ -1716,6 +1778,20 @@ "minversion": "0.0.0", "port": "80" }, + "osticket": { + "documentation": "https://docs.osticket.com/en/latest/?utm_source=coolify.io", + "slogan": "osTicket is a widely-used open source support ticket system.", + "compose": "c2VydmljZXM6CiAgb3N0aWNrZXQ6CiAgICBpbWFnZTogJ3RpcmVkb2ZpdC9vc3RpY2tldDpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fT1NUSUNLRVRfODAKICAgICAgLSAnQVBQX1VSTD0ke1NFUlZJQ0VfRlFETl9PU1RJQ0tFVH0nCiAgICAgIC0gJ0NST05fSU5URVJWQUw9JHtDUk9OX0lOVEVSVkFMOi0xMH0nCiAgICAgIC0gREJfSE9TVD1tYXJpYWRiCiAgICAgIC0gJ0RCX05BTUU9JHtPU1RJQ0tFVF9EQVRBQkFTRTotb3N0aWNrZXQtZGJ9JwogICAgICAtICdEQl9VU0VSPSR7U0VSVklDRV9VU0VSX01BUklBREJ9JwogICAgICAtICdEQl9QQVNTPSR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCfScKICAgICAgLSAnSU5TVEFMTF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX09TVElDS0VUU0VDUkVUfScKICAgICAgLSAnQURNSU5fRklSU1ROQU1FPSR7T1NUSUNLRVRfRklSU1ROQU1FOi1BZG1pbn0nCiAgICAgIC0gJ0FETUlOX0xBU1ROQU1FPSR7T1NUSUNLRVRfTEFTVE5BTUU6LWlzdHJhdG9yfScKICAgICAgLSAnQURNSU5fRU1BSUw9JHtPU1RJQ0tFVF9BRE1JTl9FTUFJTDotYWRtaW5AZXhhbXBsZS5jb219JwogICAgICAtICdBRE1JTl9VU0VSPSR7U0VSVklDRV9VU0VSX09TVElDS0VUQURNSU59JwogICAgICAtICdBRE1JTl9QQVNTPSR7U0VSVklDRV9QQVNTV09SRF9PU1RJQ0tFVEFETUlOUEFTU30nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjEvJwogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGRlcGVuZHNfb246CiAgICAgIG1hcmlhZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ29zdGlja2V0LWRhdGE6L3d3dy9vc3RpY2tldCcKICBtYXJpYWRiOgogICAgaW1hZ2U6ICdtYXJpYWRiOjExJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIE1BUklBREJfUk9PVF9QQVNTV09SRDogJyR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCUk9PVH0nCiAgICAgIE1BUklBREJfREFUQUJBU0U6ICcke09TVElDS0VUX0RBVEFCQVNFOi1vc3RpY2tldC1kYn0nCiAgICAgIE1BUklBREJfVVNFUjogJyR7U0VSVklDRV9VU0VSX01BUklBREJ9JwogICAgICBNQVJJQURCX1BBU1NXT1JEOiAnJHtTRVJWSUNFX1BBU1NXT1JEX01BUklBREJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGhlYWx0aGNoZWNrLnNoCiAgICAgICAgLSAnLS1jb25uZWN0JwogICAgICAgIC0gJy0taW5ub2RiX2luaXRpYWxpemVkJwogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIHZvbHVtZXM6CiAgICAgIC0gJ29zdGlja2V0LW1hcmlhZGItZGF0YTovdmFyL2xpYi9teXNxbCcK", + "tags": [ + "helpdesk", + "ticketing", + "support", + "open-source" + ], + "logo": "svgs/osticket.png", + "minversion": "0.0.0", + "port": "80" + }, "owncloud": { "documentation": "https://owncloud.com/docs?utm_source=coolify.io", "slogan": "OwnCloud with Open Web UI integrates file management with a powerful, user-friendly interface.", From 06b795c66ebe08c3aa21fb5e337ea215478902a7 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 11 Oct 2024 12:09:47 +0200 Subject: [PATCH 080/500] chore: Update version numbers to 4.0.0-beta.360 in configuration files --- config/sentry.php | 2 +- config/version.php | 2 +- versions.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/sentry.php b/config/sentry.php index 03d36280c..ade6923ac 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.359', + 'release' => '4.0.0-beta.360', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 6d3ef4243..97a085fe6 100644 --- a/config/version.php +++ b/config/version.php @@ -1,4 +1,4 @@ Date: Fri, 11 Oct 2024 12:29:13 +0200 Subject: [PATCH 081/500] fix: do not allow to change number of lines when streaming logs --- resources/views/livewire/project/shared/get-logs.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/livewire/project/shared/get-logs.blade.php b/resources/views/livewire/project/shared/get-logs.blade.php index 22d797ea3..42e6f8535 100644 --- a/resources/views/livewire/project/shared/get-logs.blade.php +++ b/resources/views/livewire/project/shared/get-logs.blade.php @@ -48,8 +48,8 @@

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

- +
Refresh From b039a481c739332fcba360d1ccea86e39b3091a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=8F=94=EF=B8=8F=20Peak?= <122374094+peaklabs-dev@users.noreply.github.com> Date: Fri, 11 Oct 2024 13:04:20 +0200 Subject: [PATCH 082/500] Update package.json --- docker/coolify-realtime/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/coolify-realtime/package.json b/docker/coolify-realtime/package.json index 90d4f77db..146e6b90a 100644 --- a/docker/coolify-realtime/package.json +++ b/docker/coolify-realtime/package.json @@ -4,7 +4,7 @@ "dependencies": { "@xterm/addon-fit": "^0.10.0", "@xterm/xterm": "^5.5.0", - "cookie": "^0.6.0", + "cookie": "^0.7.0", "axios": "1.7.5", "dotenv": "^16.4.5", "node-pty": "^1.0.0", From 88f1e58c6350a323a6c028e2697336ebac0adfc0 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 11 Oct 2024 14:38:22 +0200 Subject: [PATCH 083/500] feat: required envs --- app/Livewire/Project/Service/Navbar.php | 1 + .../Shared/EnvironmentVariable/Show.php | 16 +- app/Models/EnvironmentVariable.php | 9 +- app/Models/Service.php | 17 +- bootstrap/helpers/shared.php | 5 + ...0_11_114331_add_required_env_variables.php | 28 ++ .../livewire/project/service/navbar.blade.php | 250 ++++++++++-------- .../shared/environment-variable/all.blade.php | 9 +- .../environment-variable/show.blade.php | 7 +- 9 files changed, 214 insertions(+), 128 deletions(-) create mode 100644 database/migrations/2024_10_11_114331_add_required_env_variables.php diff --git a/app/Livewire/Project/Service/Navbar.php b/app/Livewire/Project/Service/Navbar.php index 70b3b5db6..fa76ee26f 100644 --- a/app/Livewire/Project/Service/Navbar.php +++ b/app/Livewire/Project/Service/Navbar.php @@ -39,6 +39,7 @@ class Navbar extends Component return [ "echo-private:user.{$userId},ServiceStatusChanged" => 'serviceStarted', + "envsUpdated" => '$refresh', ]; } diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/Show.php b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php index 463ceecad..0538a6bdb 100644 --- a/app/Livewire/Project/Shared/EnvironmentVariable/Show.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php @@ -37,6 +37,7 @@ class Show extends Component 'env.is_literal' => 'required|boolean', 'env.is_shown_once' => 'required|boolean', 'env.real_value' => 'nullable', + 'env.is_required' => 'required|boolean', ]; protected $validationAttributes = [ @@ -46,6 +47,7 @@ class Show extends Component 'env.is_multiline' => 'Multiline', 'env.is_literal' => 'Literal', 'env.is_shown_once' => 'Shown Once', + 'env.is_required' => 'Required', ]; public function refresh() @@ -109,14 +111,14 @@ class Show extends Component } else { $this->validate(); } - // if (str($this->env->value)->startsWith('{{') && str($this->env->value)->endsWith('}}')) { - // $type = str($this->env->value)->after('{{')->before('.')->value; - // if (! collect(SHARED_VARIABLE_TYPES)->contains($type)) { - // $this->dispatch('error', 'Invalid shared variable type.', 'Valid types are: team, project, environment.'); - // return; - // } - // } + if ($this->env->is_required && str($this->env->real_value)->isEmpty()) { + $oldValue = $this->env->getOriginal('value'); + $this->env->value = $oldValue; + $this->dispatch('error', 'Required environment variable cannot be empty.'); + + return; + } $this->serialize(); $this->env->save(); $this->dispatch('success', 'Environment variable updated.'); diff --git a/app/Models/EnvironmentVariable.php b/app/Models/EnvironmentVariable.php index 9f8e4b342..531c8fa40 100644 --- a/app/Models/EnvironmentVariable.php +++ b/app/Models/EnvironmentVariable.php @@ -44,7 +44,7 @@ class EnvironmentVariable extends Model 'version' => 'string', ]; - protected $appends = ['real_value', 'is_shared']; + protected $appends = ['real_value', 'is_shared', 'is_really_required']; protected static function booted() { @@ -130,6 +130,13 @@ class EnvironmentVariable extends Model ); } + protected function isReallyRequired(): Attribute + { + return Attribute::make( + get: fn () => $this->is_required && str($this->real_value)->isEmpty(), + ); + } + protected function isShared(): Attribute { return Attribute::make( diff --git a/app/Models/Service.php b/app/Models/Service.php index 0036a9fda..16e11ecb6 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -1232,7 +1232,6 @@ class Service extends BaseModel public function environment_variables(): HasMany { - return $this->hasMany(EnvironmentVariable::class)->orderByRaw("LOWER(key) LIKE LOWER('SERVICE%') DESC, LOWER(key) ASC"); } @@ -1316,4 +1315,20 @@ class Service extends BaseModel return $networks; } + + protected function isDeployable(): Attribute + { + return Attribute::make( + get: function () { + $envs = $this->environment_variables()->where('is_required', true)->get(); + foreach ($envs as $env) { + if ($env->is_really_required) { + return false; + } + } + return true; + } + ); + } + } diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index cfdea81fb..ea9d6ff3c 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -3569,6 +3569,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int ]); } else { if ($value->startsWith('$')) { + $isRequired = false; if ($value->contains(':-')) { $value = replaceVariables($value); $key = $value->before(':'); @@ -3583,11 +3584,13 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int $key = $value->before(':'); $value = $value->after(':?'); + $isRequired = true; } elseif ($value->contains('?')) { $value = replaceVariables($value); $key = $value->before('?'); $value = $value->after('?'); + $isRequired = true; } if ($originalValue->value() === $value->value()) { // This means the variable does not have a default value, so it needs to be created in Coolify @@ -3598,6 +3601,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int ], [ 'is_build_time' => false, 'is_preview' => false, + 'is_required' => $isRequired, ]); // Add the variable to the environment so it will be shown in the deployable compose file $environment[$parsedKeyValue->value()] = $resource->environment_variables()->where('key', $parsedKeyValue)->where($nameOfId, $resource->id)->first()->value; @@ -3611,6 +3615,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int 'value' => $value, 'is_build_time' => false, 'is_preview' => false, + 'is_required' => $isRequired, ]); } diff --git a/database/migrations/2024_10_11_114331_add_required_env_variables.php b/database/migrations/2024_10_11_114331_add_required_env_variables.php new file mode 100644 index 000000000..4fde0c2bb --- /dev/null +++ b/database/migrations/2024_10_11_114331_add_required_env_variables.php @@ -0,0 +1,28 @@ +boolean('is_required')->default(false); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('environment_variables', function (Blueprint $table) { + $table->dropColumn('is_required'); + }); + } +}; diff --git a/resources/views/livewire/project/service/navbar.blade.php b/resources/views/livewire/project/service/navbar.blade.php index 6ff297c61..342c071d4 100644 --- a/resources/views/livewire/project/service/navbar.blade.php +++ b/resources/views/livewire/project/service/navbar.blade.php @@ -20,127 +20,143 @@
-
- @if (str($service->status())->contains('running')) - - - Advanced - - + Deploy + + @endif +
+ @else + + @endif @script
-

Memory (%)

+

Memory (%)

- -
-

Memory (%)

-
- - + +
+

Memory (%)

+
+ + + +
+
+
diff --git a/resources/views/livewire/server/cloudflare-tunnels.blade.php b/resources/views/livewire/server/cloudflare-tunnels.blade.php index acca66d60..4cb7fc2ec 100644 --- a/resources/views/livewire/server/cloudflare-tunnels.blade.php +++ b/resources/views/livewire/server/cloudflare-tunnels.blade.php @@ -1,42 +1,54 @@
-
-

Cloudflare Tunnels

- -
-
- @if ($server->settings->is_cloudflare_tunnel) -
- -
- @elseif (!$server->isFunctional()) -
- To automatically configure Cloudflare Tunnels, please - validate your server first. Then you will need a Cloudflare token and an SSH - domain configured. -
- To manually configure Cloudflare Tunnels, please - click here, then you should validate the server. -

- For more information, please read our documentation. -
- @endif - @if (!$server->settings->is_cloudflare_tunnel && $server->isFunctional()) - - - - @endif - @if ($server->isFunctional() && !$server->settings->is_cloudflare_tunnel) -
- I have configured Cloudflare Tunnels manually -
- @endif + + {{ data_get_str($server, 'name')->limit(10) }} > Cloudflare Tunnels | Coolify + + +
+ +
+
+
+

Cloudflare Tunnels

+ +
+
Secure your servers with Cloudflare Tunnels
+
+
+ @if ($isCloudflareTunnelsEnabled) +
+ +
+ @elseif (!$server->isFunctional()) +
+ To automatically configure Cloudflare Tunnels, please + validate your server first. Then you will need a Cloudflare token and an SSH + domain configured. +
+ To manually configure Cloudflare Tunnels, please + click here, + then you should validate the server. +

+ For more information, please read our documentation. +
+ @endif + @if (!$isCloudflareTunnelsEnabled && $server->isFunctional()) +

Configuration

+
+ + + + + Manual + +
+ @endif +
+
diff --git a/resources/views/livewire/server/delete.blade.php b/resources/views/livewire/server/delete.blade.php index 978943158..1b56b35c9 100644 --- a/resources/views/livewire/server/delete.blade.php +++ b/resources/views/livewire/server/delete.blade.php @@ -1,22 +1,31 @@
- @if ($server->id !== 0) -

Danger Zone

-
Woah. I hope you know what are you doing.
-

Delete Server

-
This will remove this server from Coolify. Beware! There is no coming - back! + + {{ data_get_str($server, 'name')->limit(10) }} > Delete Server | Coolify + + +
+ +
+ @if ($server->id !== 0) +

Danger Zone

+
Woah. I hope you know what are you doing.
+

Delete Server

+
This will remove this server from Coolify. Beware! There is no coming + back! +
+ @if ($server->definedResources()->count() > 0) +
You need to delete all resources before deleting this server.
+ + @else + + @endif + @endif
- @if ($server->definedResources()->count() > 0) -
You need to delete all resources before deleting this server.
- - @else - - @endif - @endif +
diff --git a/resources/views/livewire/server/destination/show.blade.php b/resources/views/livewire/server/destination/show.blade.php index fb9ab4fbb..9dba9c0d6 100644 --- a/resources/views/livewire/server/destination/show.blade.php +++ b/resources/views/livewire/server/destination/show.blade.php @@ -2,6 +2,48 @@ {{ data_get_str($server, 'name')->limit(10) }} > Server Destinations | Coolify - {{-- --}} - + +
+ +
+ @if ($server->isFunctional()) +
+

Destinations

+ + + + Scan for Destinations +
+
Destinations are used to segregate resources by network.
+

Available Destinations

+
+ @foreach ($server->standaloneDockers as $docker) + + {{ data_get($docker, 'network') }} + + @endforeach + @foreach ($server->swarmDockers as $docker) + + {{ data_get($docker, 'network') }} + + @endforeach +
+ @if ($networks->count() > 0) +
+

Found Destinations

+
+ @foreach ($networks as $network) +
+ Add + {{ data_get($network, 'Name') }} +
+ @endforeach +
+
+ @endif + @else +
Server is not validated. Validate first.
+ @endif +
+
diff --git a/resources/views/livewire/server/log-drains.blade.php b/resources/views/livewire/server/log-drains.blade.php index ac905e8bb..2ababba93 100644 --- a/resources/views/livewire/server/log-drains.blade.php +++ b/resources/views/livewire/server/log-drains.blade.php @@ -1,120 +1,118 @@
- {{ data_get_str($server, 'name')->limit(10) }} > Server LogDrains | Coolify + {{ data_get_str($server, 'name')->limit(10) }} > Server Log Drains | Coolify - {{-- --}} - @if ($server->isFunctional()) -

Log Drains

-
Sends service logs to 3rd party tools.
-
-
- -

New Relic

-
- -
-
-
- @if ($server->isLogDrainEnabled()) - - + +
+ +
+ @if ($server->isFunctional()) +
+

Log Drains

+ +
+
Sends service logs to 3rd party tools.
+
+
+ +

New Relic

+
+ @if ($isLogDrainAxiomEnabled || $isLogDrainCustomEnabled) + + @else + + @endif +
+
+
+ @if ($server->isLogDrainEnabled()) + + + @else + + + @endif +
+
+
+ + Save + +
+ + +

Axiom

+
+ @if ($isLogDrainNewRelicEnabled || $isLogDrainCustomEnabled) + @else - - + @endif
-
-
- - Save - -
- - -

Axiom

-
- -
-
-
-
- @if ($server->isLogDrainEnabled()) - - + +
+
+ @if ($server->isLogDrainEnabled()) + + + @else + + + @endif +
+
+
+ + Save + +
+ +

Custom FluentBit

+
+ @if ($isLogDrainNewRelicEnabled || $isLogDrainAxiomEnabled) + @else - - + @endif
-
-
- - Save - -
- - {{--

Highlight.io

-
- -
-
-
-
- -
-
-
- - Save - -
-
--}} -

Custom FluentBit configuration

-
- -
-
-
- @if ($server->isLogDrainEnabled()) - - - @else - - - @endif + +
+ @if ($server->isLogDrainEnabled()) + + + @else + + + @endif + +
+
+ + Save + +
+
-
- - Save - -
- - -
+
+ @else +
Server is not validated. Validate first.
+ @endif
- @else -
Server is not validated. Validate first.
- @endif +
diff --git a/resources/views/livewire/server/private-key/show.blade.php b/resources/views/livewire/server/private-key/show.blade.php index 014de2e7c..725d10f8e 100644 --- a/resources/views/livewire/server/private-key/show.blade.php +++ b/resources/views/livewire/server/private-key/show.blade.php @@ -1,6 +1,43 @@
- Server Connection | Coolify + {{ data_get_str($server, 'name')->limit(10) }} > Server Connection | Coolify - + +
+ +
+
+

Private Key

+ + + + + Check connection + +
+
Change your server's private key.
+
+ @forelse ($privateKeys as $private_key) +
+
+
{{ $private_key->name }}
+
{{ $private_key->description }}
+
+ @if (data_get($server, 'privateKey.uuid') !== $private_key->uuid) + + Use this key + + @else + + Currently used + + @endif +
+ @empty +
No private keys found.
+ @endforelse +
+
+
diff --git a/resources/views/livewire/server/proxy/dynamic-configurations.blade.php b/resources/views/livewire/server/proxy/dynamic-configurations.blade.php index 42967efca..ec63f451b 100644 --- a/resources/views/livewire/server/proxy/dynamic-configurations.blade.php +++ b/resources/views/livewire/server/proxy/dynamic-configurations.blade.php @@ -4,7 +4,7 @@
- +
@if ($server->isFunctional())
diff --git a/resources/views/livewire/server/proxy/logs.blade.php b/resources/views/livewire/server/proxy/logs.blade.php index f0c1ea85c..4556d67bd 100644 --- a/resources/views/livewire/server/proxy/logs.blade.php +++ b/resources/views/livewire/server/proxy/logs.blade.php @@ -4,7 +4,7 @@
- +

Logs

diff --git a/resources/views/livewire/server/proxy/show.blade.php b/resources/views/livewire/server/proxy/show.blade.php index 2d8d4e42a..2370ab797 100644 --- a/resources/views/livewire/server/proxy/show.blade.php +++ b/resources/views/livewire/server/proxy/show.blade.php @@ -5,7 +5,7 @@ @if ($server->isFunctional())
- +
diff --git a/resources/views/livewire/server/show-private-key.blade.php b/resources/views/livewire/server/show-private-key.blade.php deleted file mode 100644 index 7c24a3a9b..000000000 --- a/resources/views/livewire/server/show-private-key.blade.php +++ /dev/null @@ -1,36 +0,0 @@ -
-
-

Private Key

- - - - - Check connection - -
- -
-
Change your server's private key.
-
-
- @forelse ($privateKeys as $private_key) -
-
-
{{ $private_key->name }}
-
{{ $private_key->description }}
-
- @if (data_get($server, 'privateKey.uuid') !== $private_key->uuid) - - Use this key - - @else - - Currently used - - @endif -
- @empty -
No private keys found.
- @endforelse -
-
diff --git a/resources/views/livewire/server/show.blade.php b/resources/views/livewire/server/show.blade.php index a5b75dcf2..6d2fdc42b 100644 --- a/resources/views/livewire/server/show.blade.php +++ b/resources/views/livewire/server/show.blade.php @@ -2,71 +2,237 @@ {{ data_get_str($server, 'name')->limit(10) }} > Server Configurations | Coolify - -
-
- General - @if ($server->isFunctional()) - Advanced - - @endif - Private - Key - @if ($server->isFunctional()) - Cloudflare Tunnels - Destinations - Log - Drains - Metrics - @endif - @if (!$server->isLocalhost()) - Danger - @endif -
+ +
+
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- @if ($server->isFunctional() && $server->isMetricsEnabled()) -

Metrics

-
Basic metrics for your container.
-
- -
- @else - No metrics available. - @endif -
- @if (!$server->isLocalhost()) -
- +
+
+

General

+ @if ($server->id === 0) + + @else + Save + @if ($server->isFunctional()) + + Validate & configure + + + + + Revalidate server + + + @endif + @endif
+ @if ($server->isFunctional()) + Server is reachable and validated. + @else + You can't use this server until it is validated. + @endif + @if ((!$isReachable || !$isUsable) && $server->id !== 0) + + Validate & configure + + + + + Validate Server & Install Docker Engine + + + @if ($server->validation_logs) +

Previous Validation Logs

+
+ {!! $server->validation_logs !!} +
+ @endif + @endif + @if ((!$isReachable || !$isUsable) && $server->id === 0) + + Validate Server + + @endif + @if ($server->isForceDisabled() && isCloud()) +
The system has disabled the server because you have + exceeded the + number of servers for which you have paid.
+ @endif +
+
+ + + @if (!$isSwarmWorker && !$isBuildServer) + + @endif + +
+
+ +
+ + +
+
+
+
+ + +
+
+
+ + + + +
+
+ +
+
+
+ +
+ @if (!$server->isLocalhost()) +
+ +
+ + @if (!$server->isBuildServer() && !$server->settings->is_cloudflare_tunnel) +

Swarm (experimental) +

+
Read the docs here. +
+
+ @if ($server->settings->is_swarm_worker) + + @else + + @endif + + @if ($server->settings->is_swarm_manager) + + @else + + @endif +
+ @endif + @endif +
+
+
+ @if ($server->isFunctional() && !$server->isSwarm() && !$server->isBuildServer()) +
+
+

Sentinel

+ @if ($server->isSentinelEnabled()) +
+ @if ($server->isSentinelLive()) + + Save + Restart + @else + + Save + Sync + @endif +
+ @endif +
+
+
Experimental feature +
+
+ + @if ($server->isSentinelEnabled()) + + + @else + + + label="Enable Metrics" /> + @endif +
+ @if ($server->isSentinelEnabled()) +
+ + Regenerate +
+ + + +
+
+ + + +
+
+ @endif +
+
@endif
diff --git a/routes/web.php b/routes/web.php index b9976a088..6f442e0fe 100644 --- a/routes/web.php +++ b/routes/web.php @@ -34,6 +34,10 @@ use App\Livewire\Project\Show as ProjectShow; use App\Livewire\Security\ApiTokens; use App\Livewire\Security\PrivateKey\Index as SecurityPrivateKeyIndex; use App\Livewire\Security\PrivateKey\Show as SecurityPrivateKeyShow; +use App\Livewire\Server\Advanced as ServerAdvanced; +use App\Livewire\Server\Charts as ServerCharts; +use App\Livewire\Server\CloudflareTunnels; +use App\Livewire\Server\Delete as DeleteServer; use App\Livewire\Server\Destination\Show as DestinationShow; use App\Livewire\Server\Index as ServerIndex; use App\Livewire\Server\LogDrains; @@ -205,13 +209,17 @@ Route::middleware(['auth', 'verified'])->group(function () { Route::prefix('server/{server_uuid}')->group(function () { Route::get('/', ServerShow::class)->name('server.show'); + Route::get('/advanced', ServerAdvanced::class)->name('server.advanced'); + Route::get('/private-key', PrivateKeyShow::class)->name('server.private-key'); Route::get('/resources', ResourcesShow::class)->name('server.resources'); + Route::get('/cloudflare-tunnels', CloudflareTunnels::class)->name('server.cloudflare-tunnels'); + Route::get('/destinations', DestinationShow::class)->name('server.destinations'); + Route::get('/log-drains', LogDrains::class)->name('server.log-drains'); + Route::get('/metrics', ServerCharts::class)->name('server.charts'); + Route::get('/danger', DeleteServer::class)->name('server.delete'); Route::get('/proxy', ProxyShow::class)->name('server.proxy'); Route::get('/proxy/dynamic', ProxyDynamicConfigurations::class)->name('server.proxy.dynamic-confs'); Route::get('/proxy/logs', ProxyLogs::class)->name('server.proxy.logs'); - Route::get('/private-key', PrivateKeyShow::class)->name('server.private-key'); - Route::get('/destinations', DestinationShow::class)->name('server.destinations'); - Route::get('/log-drains', LogDrains::class)->name('server.log-drains'); Route::get('/terminal', ExecuteContainerCommand::class)->name('server.command'); }); From b846b40813317b1b3869560e7322521c9311c84b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 30 Oct 2024 20:03:23 +0100 Subject: [PATCH 354/500] remove coolify managed label from coolify images --- .github/workflows/coolify-production-build.yml | 4 ---- .github/workflows/coolify-staging-build.yml | 4 ---- 2 files changed, 8 deletions(-) diff --git a/.github/workflows/coolify-production-build.yml b/.github/workflows/coolify-production-build.yml index 771687d4b..7017b4897 100644 --- a/.github/workflows/coolify-production-build.yml +++ b/.github/workflows/coolify-production-build.yml @@ -53,8 +53,6 @@ jobs: tags: | ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} - labels: | - coolify.managed=true aarch64: runs-on: [self-hosted, arm64] @@ -90,8 +88,6 @@ jobs: tags: | ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 - labels: | - coolify.managed=true merge-manifest: runs-on: ubuntu-latest diff --git a/.github/workflows/coolify-staging-build.yml b/.github/workflows/coolify-staging-build.yml index dd5e6ebd6..6e4d4adc3 100644 --- a/.github/workflows/coolify-staging-build.yml +++ b/.github/workflows/coolify-staging-build.yml @@ -48,8 +48,6 @@ jobs: tags: | ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} - labels: | - coolify.managed=true aarch64: runs-on: [self-hosted, arm64] @@ -83,8 +81,6 @@ jobs: tags: | ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 - labels: | - coolify.managed=true merge-manifest: runs-on: ubuntu-latest From 86cf1ae3198dffe6cca45f957b25b021ecb616d8 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 30 Oct 2024 21:33:01 +0100 Subject: [PATCH 355/500] Refactor Server model to remove SSH multiplexing file --- app/Models/Server.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/Models/Server.php b/app/Models/Server.php index bd09f1b85..a9e3acde4 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -5,6 +5,7 @@ namespace App\Models; use App\Actions\Server\InstallDocker; use App\Actions\Server\StartSentinel; use App\Enums\ProxyTypes; +use App\Helpers\SshMultiplexingHelper; use App\Jobs\CheckAndStartSentinelJob; use App\Notifications\Server\Reachable; use App\Notifications\Server\Unreachable; @@ -1064,6 +1065,8 @@ $schema://$host { { config()->set('constants.ssh.mux_enabled', ! $isManualCheck); + SshMultiplexingHelper::removeMuxFile($this); + if ($this->skipServer()) { return ['uptime' => false, 'error' => 'Server skipped.']; } From 8fbd0b44d5fd7e87a69e4c305037b87015747d49 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Wed, 30 Oct 2024 21:33:06 +0100 Subject: [PATCH 356/500] Refactor Server model to remove SSH multiplexing file and add ServerCleanupMux job - Remove SSH multiplexing file from the Server model - Add ServerCleanupMux job to cleanup multiplexed connections every hour --- app/Console/Kernel.php | 3 +++ app/Jobs/ServerCleanupMux.php | 42 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 app/Jobs/ServerCleanupMux.php diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 67ff819ed..cd560eee3 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -12,6 +12,7 @@ use App\Jobs\DockerCleanupJob; use App\Jobs\PullTemplatesFromCDN; use App\Jobs\ScheduledTaskJob; use App\Jobs\ServerCheckJob; +use App\Jobs\ServerCleanupMux; use App\Jobs\UpdateCoolifyJob; use App\Models\ScheduledDatabaseBackup; use App\Models\ScheduledTask; @@ -120,6 +121,8 @@ class Kernel extends ConsoleKernel } else { $schedule->job(new DockerCleanupJob($server))->everyTenMinutes()->timezone($serverTimezone)->onOneServer(); } + // Cleanup multiplexed connections every hour + $schedule->job(new ServerCleanupMux($server))->hourly()->onOneServer(); // Temporary solution until we have better memory management for Sentinel if ($server->isSentinelEnabled()) { diff --git a/app/Jobs/ServerCleanupMux.php b/app/Jobs/ServerCleanupMux.php new file mode 100644 index 000000000..70ea59752 --- /dev/null +++ b/app/Jobs/ServerCleanupMux.php @@ -0,0 +1,42 @@ +server->serverStatus() === false) { + return 'Server is not reachable or not ready.'; + } + SshMultiplexingHelper::removeMuxFile($this->server); + + } catch (\Throwable $e) { + return handleError($e); + } + + } +} From 5d5a06dcf6344cdf9ee49f7f63891c4c4f8c09ad Mon Sep 17 00:00:00 2001 From: Alberto Rizzi Date: Wed, 30 Oct 2024 22:21:52 +0100 Subject: [PATCH 357/500] fix typo --- resources/views/livewire/server/form.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index 48c16051e..bff029b6f 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -192,7 +192,7 @@
- @if ($server->isFunctional()) -

Settings

-
-
-
-
- -
- @if ($server->isFunctional() && !$server->isSwarm() && !$server->isBuildServer())
From 6be0affa79a49ccc4c3500e900bfd7b5e597122f Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 31 Oct 2024 11:35:16 +0100 Subject: [PATCH 359/500] fix typo --- resources/views/livewire/server/advanced.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/server/advanced.blade.php b/resources/views/livewire/server/advanced.blade.php index 2440f49d0..fc1be78d8 100644 --- a/resources/views/livewire/server/advanced.blade.php +++ b/resources/views/livewire/server/advanced.blade.php @@ -46,7 +46,7 @@ - -
- @php - $passwordConfirm = Str::uuid(); - @endphp - - - - - -

- @error('password') -

{{ $message }}

- @enderror
@if (!empty($checkboxes)) @endif -
+
@@ -353,16 +329,19 @@

Please enter your password to confirm this destructive action.

- -
- + + +
-

-

+

@error('password')

{{ $message }}

@enderror From 9a93e4511ee7f85ea25e1c5ed787fc6a3307416d Mon Sep 17 00:00:00 2001 From: Lucas Michot Date: Thu, 10 Oct 2024 12:55:31 +0200 Subject: [PATCH 361/500] Simplify and optimize the service-templates.yaml generation command --- app/Console/Commands/ServicesGenerate.php | 137 ++++++++-------------- 1 file changed, 46 insertions(+), 91 deletions(-) diff --git a/app/Console/Commands/ServicesGenerate.php b/app/Console/Commands/ServicesGenerate.php index 9720e81ac..7e91b38ad 100644 --- a/app/Console/Commands/ServicesGenerate.php +++ b/app/Console/Commands/ServicesGenerate.php @@ -3,128 +3,83 @@ namespace App\Console\Commands; use Illuminate\Console\Command; +use Illuminate\Support\Arr; use Symfony\Component\Yaml\Yaml; class ServicesGenerate extends Command { /** - * The name and signature of the console command. - * - * @var string + * {@inheritdoc} */ protected $signature = 'services:generate'; /** - * The console command description. - * - * @var string + * {@inheritdoc} */ protected $description = 'Generate service-templates.yaml based on /templates/compose directory'; - /** - * Execute the console command. - */ - public function handle() + public function handle(): int { - $files = array_diff(scandir(base_path('templates/compose')), ['.', '..']); - $files = array_filter($files, function ($file) { - return strpos($file, '.yaml') !== false; - }); - $serviceTemplatesJson = []; - foreach ($files as $file) { - $parsed = $this->process_file($file); - if ($parsed) { - $name = data_get($parsed, 'name'); - $parsed = data_forget($parsed, 'name'); - $serviceTemplatesJson[$name] = $parsed; - } - } - $serviceTemplatesJson = json_encode($serviceTemplatesJson, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + $serviceTemplatesJson = collect(glob(base_path('templates/compose/*.yaml'))) + ->mapWithKeys(function ($file): array { + $file = basename($file); + $parsed = $this->processFile($file); + + return $parsed === false ? [] : [ + Arr::pull($parsed, 'name') => $parsed, + ]; + })->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + file_put_contents(base_path('templates/service-templates.json'), $serviceTemplatesJson.PHP_EOL); + + return self::SUCCESS; } - private function process_file($file) + private function processFile(string $file): false|array { - $serviceName = str($file)->before('.yaml')->value(); $content = file_get_contents(base_path("templates/compose/$file")); - // $this->info($content); - $ignore = collect(preg_grep('/^# ignore:/', explode("\n", $content)))->values(); - if ($ignore->count() > 0) { - $ignore = (bool) str($ignore[0])->after('# ignore:')->trim()->value(); - } else { - $ignore = false; - } - if ($ignore) { + + preg_match_all( + '/#\s*(documentation|env_file|ignore|logo|minversion|port|slogan|tags)\s*:\s*(.+)\s*/', + $content, $matches + ); + + $data = array_combine($matches[1], $matches[2]); + + if (str($data['ignore'] ?? false)->toBoolean()) { $this->info("Ignoring $file"); - return; + return false; } + $this->info("Processing $file"); - $documentation = collect(preg_grep('/^# documentation:/', explode("\n", $content)))->values(); - if ($documentation->count() > 0) { - $documentation = str($documentation[0])->after('# documentation:')->trim()->value(); - $documentation = str($documentation)->append('?utm_source=coolify.io'); - } else { - $documentation = 'https://coolify.io/docs'; - } - $slogan = collect(preg_grep('/^# slogan:/', explode("\n", $content)))->values(); - if ($slogan->count() > 0) { - $slogan = str($slogan[0])->after('# slogan:')->trim()->value(); - } else { - $slogan = str($file)->headline()->value(); - } - $logo = collect(preg_grep('/^# logo:/', explode("\n", $content)))->values(); - if ($logo->count() > 0) { - $logo = str($logo[0])->after('# logo:')->trim()->value(); - } else { - $logo = 'svgs/coolify.png'; - } - $minversion = collect(preg_grep('/^# minversion:/', explode("\n", $content)))->values(); - if ($minversion->count() > 0) { - $minversion = str($minversion[0])->after('# minversion:')->trim()->value(); - } else { - $minversion = '0.0.0'; - } - $env_file = collect(preg_grep('/^# env_file:/', explode("\n", $content)))->values(); - if ($env_file->count() > 0) { - $env_file = str($env_file[0])->after('# env_file:')->trim()->value(); - } else { - $env_file = null; - } + $documentation = $data['documentation'] ?? null; + $documentation = $documentation ? $documentation.'?utm_source=coolify.io' : 'https://coolify.io/docs'; - $tags = collect(preg_grep('/^# tags:/', explode("\n", $content)))->values(); - if ($tags->count() > 0) { - $tags = str($tags[0])->after('# tags:')->trim()->explode(',')->map(function ($tag) { - return str($tag)->trim()->lower()->value(); - })->values(); - } else { - $tags = null; - } - $port = collect(preg_grep('/^# port:/', explode("\n", $content)))->values(); - if ($port->count() > 0) { - $port = str($port[0])->after('# port:')->trim()->value(); - } else { - $port = null; - } $json = Yaml::parse($content); - $yaml = base64_encode(Yaml::dump($json, 10, 2)); + $compose = base64_encode(Yaml::dump($json, 10, 2)); + + $tags = str($data['tags'] ?? '')->lower()->explode(',')->map(fn ($tag) => trim($tag))->filter(); + $tags = $tags->isEmpty() ? null : $tags->all(); + $payload = [ - 'name' => $serviceName, + 'name' => pathinfo($file, PATHINFO_FILENAME), 'documentation' => $documentation, - 'slogan' => $slogan, - 'compose' => $yaml, + 'slogan' => $data['slogan'] ?? str($file)->headline(), + 'compose' => $compose, 'tags' => $tags, - 'logo' => $logo, - 'minversion' => $minversion, + 'logo' => $data['logo'] ?? 'svgs/coolify.png', + 'minversion' => $data['minversion'] ?? '0.0.0', ]; - if ($port) { + + if ($port = $data['port'] ?? null) { $payload['port'] = $port; } - if ($env_file) { - $env_file_content = file_get_contents(base_path("templates/compose/$env_file")); - $env_file_base64 = base64_encode($env_file_content); - $payload['envs'] = $env_file_base64; + + if ($envFile = $data['env_file'] ?? null) { + $envFileContent = file_get_contents(base_path("templates/compose/$envFile")); + $payload['envs'] = base64_encode($envFileContent); } return $payload; From 79d5434da282501ae12d6097c1f48562316155f4 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 31 Oct 2024 14:20:11 +0100 Subject: [PATCH 362/500] Update service-templates.json --- templates/service-templates.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/service-templates.json b/templates/service-templates.json index b693b6638..0cecec796 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -1492,7 +1492,7 @@ "mediawiki": { "documentation": "https://www.mediawiki.org?utm_source=coolify.io", "slogan": "MediaWiki is a collaboration and documentation platform brought to you by a vibrant community.", - "compose": "c2VydmljZXM6CiAgbWVkaWF3aWtpOgogICAgaW1hZ2U6ICdtZWRpYXdpa2k6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX01FRElBV0lLSV84MAogICAgdm9sdW1lczoKICAgICAgLSAnbWVkaWF3aWtpLWltYWdlczovdmFyL3d3dy9odG1sL2ltYWdlcycKICAgICAgLSAnbWVkaWF3aWtpLXNxbGl0ZTovdmFyL3d3dy9odG1sL2RhdGEnCiAgICAgIC0gJy4vTG9jYWxTZXR0aW5ncy5waHA6L3Zhci93d3cvaHRtbC9Mb2NhbFNldHRpbmdzLnBocCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo4MCcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=", + "compose": "c2VydmljZXM6CiAgbWVkaWF3aWtpOgogICAgaW1hZ2U6ICdtZWRpYXdpa2k6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX01FRElBV0lLSV84MAogICAgdm9sdW1lczoKICAgICAgLSAnbWVkaWF3aWtpLWltYWdlczovdmFyL3d3dy9odG1sL2ltYWdlcycKICAgICAgLSAnbWVkaWF3aWtpLXNxbGl0ZTovdmFyL3d3dy9odG1sL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6ODAnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", "tags": [ "wiki", "collaboration", From fc1b43cd89ddcb886030696252b260cbba3d68d6 Mon Sep 17 00:00:00 2001 From: Lucas Michot Date: Thu, 31 Oct 2024 14:59:17 +0100 Subject: [PATCH 363/500] Adapt command --- app/Console/Commands/ServicesGenerate.php | 25 +++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/app/Console/Commands/ServicesGenerate.php b/app/Console/Commands/ServicesGenerate.php index 7e91b38ad..1559e5f6d 100644 --- a/app/Console/Commands/ServicesGenerate.php +++ b/app/Console/Commands/ServicesGenerate.php @@ -39,14 +39,13 @@ class ServicesGenerate extends Command { $content = file_get_contents(base_path("templates/compose/$file")); - preg_match_all( - '/#\s*(documentation|env_file|ignore|logo|minversion|port|slogan|tags)\s*:\s*(.+)\s*/', - $content, $matches - ); + $data = collect(explode(PHP_EOL, $content))->mapWithKeys(function ($line): array { + preg_match('/^#(?.*):(?.*)$/U', $line, $m); - $data = array_combine($matches[1], $matches[2]); + return $m ? [trim($m['key']) => trim($m['value'])] : []; + }); - if (str($data['ignore'] ?? false)->toBoolean()) { + if (str($data->get('ignore'))->toBoolean()) { $this->info("Ignoring $file"); return false; @@ -54,30 +53,30 @@ class ServicesGenerate extends Command $this->info("Processing $file"); - $documentation = $data['documentation'] ?? null; + $documentation = $data->get('documentation'); $documentation = $documentation ? $documentation.'?utm_source=coolify.io' : 'https://coolify.io/docs'; $json = Yaml::parse($content); $compose = base64_encode(Yaml::dump($json, 10, 2)); - $tags = str($data['tags'] ?? '')->lower()->explode(',')->map(fn ($tag) => trim($tag))->filter(); + $tags = str($data->get('tags'))->lower()->explode(',')->map(fn ($tag) => trim($tag))->filter(); $tags = $tags->isEmpty() ? null : $tags->all(); $payload = [ 'name' => pathinfo($file, PATHINFO_FILENAME), 'documentation' => $documentation, - 'slogan' => $data['slogan'] ?? str($file)->headline(), + 'slogan' => $data->get('slogan', str($file)->headline()), 'compose' => $compose, 'tags' => $tags, - 'logo' => $data['logo'] ?? 'svgs/coolify.png', - 'minversion' => $data['minversion'] ?? '0.0.0', + 'logo' => $data->get('logo', 'svgs/coolify.png'), + 'minversion' => $data->get('minversion', '0.0.0'), ]; - if ($port = $data['port'] ?? null) { + if ($port = $data->get('port')) { $payload['port'] = $port; } - if ($envFile = $data['env_file'] ?? null) { + if ($envFile = $data->get('env_file')) { $envFileContent = file_get_contents(base_path("templates/compose/$envFile")); $payload['envs'] = base64_encode($envFileContent); } From fca18152169c67c5f54f51dc22b511e522dee4f0 Mon Sep 17 00:00:00 2001 From: Tim Koch Date: Sun, 27 Oct 2024 11:25:55 +0100 Subject: [PATCH 364/500] Apply tailwind shadow to .box class Makes .box elements appear raised above the background. Only works in light mode! --- resources/css/app.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/css/app.css b/resources/css/app.css index 00a62a131..55d8d95f8 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -217,7 +217,7 @@ tr td:first-child { } .box { - @apply relative flex lg:flex-row flex-col p-2 transition-colors cursor-pointer min-h-[4rem] dark:bg-coolgray-100 bg-white border text-black dark:text-white hover:text-black border-neutral-200 dark:border-black hover:bg-neutral-100 dark:hover:bg-coollabs-100 dark:hover:text-white hover:no-underline; + @apply relative flex lg:flex-row flex-col p-2 transition-colors cursor-pointer min-h-[4rem] dark:bg-coolgray-100 shadow bg-white border text-black dark:text-white hover:text-black border-neutral-200 dark:border-black hover:bg-neutral-100 dark:hover:bg-coollabs-100 dark:hover:text-white hover:no-underline; } .box-boarding { From a35e2f427bb077f0ab563c44e62de4eb21175b5b Mon Sep 17 00:00:00 2001 From: Tim Koch Date: Sun, 27 Oct 2024 12:10:07 +0100 Subject: [PATCH 365/500] Fix inconsistent navbar padding "Coolify" had pl-3 while the SwitchTeam element and the menu items below had px-2 --- resources/views/components/navbar.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/components/navbar.blade.php b/resources/views/components/navbar.blade.php index 93dd72f8e..460b9350b 100644 --- a/resources/views/components/navbar.blade.php +++ b/resources/views/components/navbar.blade.php @@ -46,7 +46,7 @@ } } }"> -
+
Coolify
From f073d01a5f819ad209f6d78ee3ccd7c5fa436113 Mon Sep 17 00:00:00 2001 From: Tim Koch Date: Sun, 27 Oct 2024 12:24:34 +0100 Subject: [PATCH 366/500] Give more space to navbar Especially in full width and mobile view, the navbar looked cramped because there was very little padding to the left end of the screen. This commit adds horizontal padding to the navbar and increases its width from 48 to 56 tailwind units. --- resources/views/components/navbar.blade.php | 2 +- resources/views/layouts/app.blade.php | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/views/components/navbar.blade.php b/resources/views/components/navbar.blade.php index 460b9350b..2f908fc81 100644 --- a/resources/views/components/navbar.blade.php +++ b/resources/views/components/navbar.blade.php @@ -1,4 +1,4 @@ -