\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /proc/self/root/proc/self/root/var/softaculous/eventsch/

Viewing File: .env

APP_NAME=Laravel
APP_ENV=production
APP_KEY=[[key]]
APP_DEBUG=false
APP_TIMEZONE=UTC
APP_URL="[[softurl]]/public"
REPORT_ERRORS=false

APP_LOCALE=en
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US

APP_MAINTENANCE_DRIVER=file
# APP_MAINTENANCE_STORE=database

BCRYPT_ROUNDS=12

LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
# Use "debug" for development; use "warning" or "error" in production
LOG_LEVEL=warning

DB_CONNECTION=mysql
DB_HOST="[[softdbhost]]"
DB_PORT=3306
DB_DATABASE="[[softdb]]"
DB_USERNAME="[[softdbuser]]"
DB_PASSWORD="[[softdbpass]]"

SESSION_DRIVER=file
SESSION_LIFETIME=120
SESSION_ENCRYPT=true
SESSION_PATH=/
# In hosted mode (IS_HOSTED=true) set to your base domain with a leading dot
# (e.g. .yourdomain.com) so sessions span subdomains. If left unset, hosted
# mode defaults it to the APP_URL base domain automatically.
SESSION_DOMAIN=null
# Set to false for local development without HTTPS
SESSION_SECURE_COOKIE=true

BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync

# Where backup export archives are written. Defaults to the local disk (storage/app), which is
# correct for a single-server install. Set these only if the app runs on more than one container or
# server, where the process that builds an export is not the one that later serves the download.
#
# WARNING: this must NOT be the same bucket you serve images from. An export archive contains every
# sale, attendee email and phone number for the schedules in it, and image buckets are typically
# public and CDN-fronted. Use a separate private bucket with no public policy. BACKUP_SPACES_BUCKET
# has no fallback on purpose: a missing value fails rather than writing backups somewhere public.
# BACKUP_DISK_DRIVER=s3
# BACKUP_SPACES_KEY=
# BACKUP_SPACES_SECRET=
# BACKUP_SPACES_REGION=
# BACKUP_SPACES_ENDPOINT=
# BACKUP_SPACES_BUCKET=

CACHE_STORE=file
CACHE_PREFIX=

MEMCACHED_HOST=127.0.0.1

REDIS_CLIENT=phpredis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=log
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false

VITE_APP_NAME="${APP_NAME}"

GEMINI_API_KEY=
OPENAI_API_KEY=

# AI provider selection (gemini or openai)
AI_TEXT_PROVIDER=gemini
AI_IMAGE_PROVIDER=openai

# AI model selection (optional)
# Translation models are used for batch translation tasks
# Content models are used for interactive features (event parsing, AI details, style generation, blog posts)
GEMINI_TRANSLATION_MODEL=
GEMINI_CONTENT_MODEL=
GEMINI_IMAGE_MODEL=
OPENAI_TRANSLATION_MODEL=
OPENAI_CONTENT_MODEL=
OPENAI_IMAGE_MODEL=

# Stripe Platform
# Used for subscription billing (hosted mode) AND direct ticket payments (self-hosted mode)
# In self-hosted mode, STRIPE_PLATFORM_KEY and STRIPE_PLATFORM_SECRET enable Stripe payments for ticket sales
STRIPE_PLATFORM_KEY=
STRIPE_PLATFORM_SECRET=
STRIPE_PLATFORM_WEBHOOK_SECRET=
STRIPE_PRICE_MONTHLY=
STRIPE_PRICE_YEARLY=
STRIPE_ENTERPRISE_PRICE_MONTHLY=
STRIPE_ENTERPRISE_PRICE_YEARLY=

# Displayed plan prices. These must match the amounts on the Stripe Price objects above:
# nothing reconciles them, so a mismatch means the site advertises one number and charges
# another. Defaults live in config/services.php (5 / 50 / 15 / 150).
#
# A super-admin can override all four at /admin/settings without touching this file or
# re-running config:cache. That override is display only, exactly as these are. Keep these set
# anyway: revenue reporting (ARR, MRR) and renewal emails deliberately read the values here, so
# that a marketing change cannot restate revenue that was already booked.
STRIPE_PRICE_MONTHLY_AMOUNT=
STRIPE_PRICE_YEARLY_AMOUNT=
STRIPE_ENTERPRISE_PRICE_MONTHLY_AMOUNT=
STRIPE_ENTERPRISE_PRICE_YEARLY_AMOUNT=

# The currency those amounts are shown in, everywhere the app quotes its OWN price: the
# marketing pages, the Plan tab, upgrade prompts and the JSON-LD offers. Also the fallback
# currency for a new event whose schedule has no country set.
#
# A label, like the amounts above - what a customer is charged comes from the Stripe Price.
# A super-admin can change it at /admin/settings, which overrides this. Defaults to USD.
# PLATFORM_CURRENCY=USD

# Payfast Platform
# Payfast is the dominant gateway in South Africa, where Stripe is not available. Setting all
# three values below enables Payfast for ticket sales across every schedule on a selfhosted
# install, the same way STRIPE_PLATFORM_KEY and STRIPE_PLATFORM_SECRET do for Stripe.
#
# These are a DEFAULT, never an override: a schedule owner who connects their own Payfast
# account in Settings > Payment Methods keeps using it, and their money keeps reaching them.
# Ignored in hosted mode, where each owner must connect their own account.
#
# The passphrase is optional at Payfast but required here - without one, the payment
# notification signature is a plain MD5 that anyone could reproduce.
PAYFAST_MERCHANT_ID=
PAYFAST_MERCHANT_KEY=
PAYFAST_PASSPHRASE=
# Use Payfast's sandbox instead of live. Test payments look completely normal, so leave this
# false unless you are testing.
PAYFAST_SANDBOX=false
# Restrict the checkout to ONE payment type, e.g. "ef" for Instant EFT. Leave empty to let
# Payfast offer everything. Codes: cc dc ef cp ap sp gp mc mt ss zp mu nd pf rc ab sc mp
PAYFAST_PAYMENT_TYPES=

# What a new event's payment method starts on. Defaults to cash. Set this to the gateway your
# install actually uses - e.g. payfast - so owners are not picking it by hand every time. It
# only applies when the gateway is genuinely usable for that event (connected, and able to
# settle the event's currency); anything else falls back to cash.
DEFAULT_PAYMENT_METHOD=

# White-label settings
IS_HOSTED=false

# Selfhosted installs are single user by default: the first account created is the
# instance admin, and further sign-ups are blocked. Set to true to let anyone register.
# Registered users can create their own schedules, so only enable this on a trusted
# network. For real multi-tenant hosting use IS_HOSTED=true (self-hosted SaaS) instead.
ALLOW_REGISTRATION=false
APP_LOGO_DARK=/images/dark_logo.png
APP_LOGO_LIGHT=/images/light_logo.png
APP_MARKETING_URL=https://eventschedule.com
SUPPORT_EMAIL=contact@eventschedule.com
# The upstream Event Schedule app this install talks to: where shared translation
# improvements are sent, and where federated events are published. Defaults to
# eventschedule.com, so it only needs setting to point at a different network.
#NEXUS_URL=https://eventschedule.com
TRIAL_DAYS=365

# Custom dashboard links (optional) - up to 3 links shown in the admin sidebar
# for all admins. A link only appears when BOTH its title and URL are set.
# Works in both selfhosted and hosted (SaaS) deployments.
CUSTOM_LINK_1_TITLE=
CUSTOM_LINK_1_URL=
CUSTOM_LINK_2_TITLE=
CUSTOM_LINK_2_URL=
CUSTOM_LINK_3_TITLE=
CUSTOM_LINK_3_URL=

# Exclude events/schedules from a country in marketing search (2-letter ISO code, e.g. "us"). Blank = no filter.
SEARCH_EXCLUDE_COUNTRY=

# Secret token for cron job endpoints (/release_tickets, /translate_data)
APP_CRON_SECRET=

# How stale the scheduler heartbeat may get before the admin panel warns that scheduled tasks have
# stopped. Both cron rails stamp it every tick, so this is many missed ticks, not one slow one.
# Keep it above 15: the /translate_data rail holds a 900-second lock, and a request killed by a
# timeout leaves that lock held for its full TTL with no heartbeat stamped behind it.
# SCHEDULER_STALE_MINUTES=20

# Which cron rail this process is, shown on /admin/queue so a dead worker is visible even while
# another rail is still ticking. schedule:run cannot tell a crontab from a worker, so the
# deployment has to say. Set to 'worker' on a dedicated scheduler container.
# SCHEDULER_RAIL=cron

# Which rail MUST be alive for scheduled work to count as happening. Leave unset on a single-cron
# install. Set it to 'worker' once a dedicated scheduler container exists: otherwise another rail
# keeping the shared heartbeat fresh masks a dead worker, and the admin panel reports all clear.
# It must match that container's SCHEDULER_RAIL exactly - any name works, but a mismatch means the
# admin panel is watching a rail nothing writes, and reports a stall that is not real.
# SCHEDULER_EXPECTED_RAIL=

# Trusted proxies - required when running behind a reverse proxy (Nginx/Apache/Cloudflare)
# to avoid infinite HTTPS redirect loops. Set to * to trust all proxies, or a
# comma-separated list of proxy IPs/CIDRs (e.g. 10.0.0.0/8,192.168.1.1).
TRUSTED_PROXIES=

# Twilio SMS (optional phone verification)
TWILIO_SID=
TWILIO_AUTH_TOKEN=
TWILIO_FROM_NUMBER=

# OneSignal push notifications (optional). When set, the app and visitors'
# browsers communicate with OneSignal's servers and load OneSignal's SDK from
# their CDN. Leave blank to disable push entirely (no SDK is loaded and no
# external calls are made). Get these from the OneSignal dashboard.
ONESIGNAL_APP_ID=
ONESIGNAL_REST_API_KEY=
# ONESIGNAL_SAFARI_WEB_ID=   # only needed for legacy macOS Safari web push

# Cookie consent banner. Normally shown only when something on the page actually needs
# consent (Google Analytics via ANALYTICS_ID, ADS_ENABLED, STAY22_ENABLED). Set this to true
# to show it anyway, which is what enables the 30-day UTM attribution cookies
# (utm_params, utm_referrer_url, utm_landing_page) used to credit a signup or sale to the
# link that brought the visitor. Those are written only after a visitor clicks Allow.
# Left false, a bare install shows no banner and sets no non-essential cookies: attribution
# still works within a single session, it just does not survive across sessions.
COOKIE_CONSENT_BANNER=false

# Monetization (optional, multi-tenant hosted installs only). Off by default.
# When enabled, free-tier schedules' public pages can carry Google AdSense and/or paid
# promotions bought by other schedules; paid schedules never show either. ADS_ENABLED is a
# deploy-time gate that cannot be overridden from the admin panel - leave it false and the
# feature does not exist. See https://eventschedule.com/docs/saas/monetization for the
# consent and AdSense policy obligations this places on you as the operator.
#
# Turning promotions OFF at /admin/settings is safe at any time: campaigns stop serving and
# the scheduled promo:sync keeps settling and refunding what is already paid for. Setting
# ADS_ENABLED back to false, however, also stops promo:sync, so leave it true until any
# outstanding campaigns have completed and refunded.
ADS_ENABLED=false

# The settings below are editable at /admin/settings once the feature is on; the values here
# only supply the starting defaults.
# ADSENSE_ENABLED=true
# ADSENSE_PUBLISHER_ID=ca-pub-XXXXXXXXXXXXXXXX
# ADSENSE_EVENT_SLOT_ID=XXXXXXXXXX
# ADSENSE_PERSONALIZED=false                  # true opts into personalized ads; see the consent obligations
# PROMOTIONS_ENGINE_ENABLED=true
# NATIVE_PROMO_PRIORITY_OVER_PROGRAMMATIC=true
# PROMOTIONS_NETWORK_CPM=2.00
# PROMOTIONS_NETWORK_CPC=0.25

# These have no admin-panel equivalent - they can only be set here.
#
# PROMOTIONS_CURRENCY is deliberately NOT tied to the platform currency picked at
# /admin/settings: a promotion purchase is a live Stripe charge, and re-denominating one from a
# dropdown documented as display-only is not something an admin should be able to do by accident.
# PROMOTIONS_CURRENCY=USD
# PROMOTIONS_MIN_BUDGET=5.00
# PROMOTIONS_MAX_BUDGET=1000.00               # a schedule's own trust limit can still be lower
# PROMOTIONS_MAX_CONCURRENT=2                 # live promotions per schedule
# PROMOTIONS_FREQUENCY_CAP=3                  # times a visitor sees the same promotion per day
# PROMOTIONS_AUTO_APPROVE_AFTER=3             # approved campaigns before an advertiser skips review
# PROMOTIONS_MIN_CTR=0.0002                   # CPC campaigns below this are paused
# PROMOTIONS_MIN_CTR_IMPRESSIONS=5000         # ...but only once they have this many impressions
# PROMOTIONS_CACHE_TTL=300                    # seconds the servable-campaign list is cached
# PROMOTIONS_STATS_RETENTION_DAYS=400

# Stay22 accommodation map (optional). Independent of ADS_ENABLED: it applies to paid schedules
# too, and each schedule may supply its own affiliate ID and keep the commission itself.
#
# STAY22_ENABLED is a deploy-time gate that cannot be overridden from the admin panel, because the
# Content-Security-Policy is built from it on every request. Leave it false and the feature does not
# exist: no frame host is allow-listed, and the per-schedule toggle is not even rendered. Changing it
# requires regenerating the config cache (php artisan config:cache).
#
# The map never loads until a visitor either has accepted cookies or explicitly clicks to show it.
# See https://eventschedule.com/docs/saas/monetization for the disclosure obligations this places on
# you as the operator.
STAY22_ENABLED=false

# Fallback affiliate ID, used for schedules that enabled the map but did not add their own. Editable
# at /admin/settings once the feature is on; the value here only supplies the starting default.
# Never used on a customer's own custom domain.
# STAY22_AID=
# STAY22_MAX_NIGHTS=30                        # upper bound on the derived stay length

# Tickets
# How many options the guest quantity dropdown offers for a ticket with no "Max Per Order"
# of its own. Clamped to 1-100. Not a purchase limit: checkout enforces only the ticket's
# own max per order and its remaining stock.
# MAX_TICKETS_PER_ORDER=20

# DigitalOcean App Platform (optional custom domain provisioning)
DO_API_TOKEN=
DO_APP_ID=
DO_APP_HOSTNAME=

# Cloudflare Turnstile (optional bot protection)
TURNSTILE_SITE_KEY=
TURNSTILE_SECRET_KEY=

# Web accessibility (optional overrides; see config/accessibility.php)
# ACCESSIBILITY_CONTACT_EMAIL=accessibility@example.com
# ACCESSIBILITY_WCAG_TARGET_LABEL="WCAG 2.1 Level AA"
# ACCESSIBILITY_REFERENCE_IS_5568=true
# ACCESSIBILITY_RESPONSE_SLA_BUSINESS_DAYS=10
# ACCESSIBILITY_LAST_REVIEWED=2026-05-03

# Nexus / marketing-site behaviour. IS_NEXUS marks the one install that serves the marketing
# pages (eventschedule.com). It is not a cosmetic flag: App\Http\Middleware\
# CacheableMarketingResponse and TrackMarketingVisit both stand down entirely when it is false,
# so edge caching of marketing HTML and beacon page-view counting are inert without it.
# IS_NEXUS=false

# The session cookie name. Unset it and config/session.php derives one from APP_NAME
# ("laravel_session" for the shipped APP_NAME). Worth knowing before you change either: a shared
# cache in front of the app has to bypass on this exact cookie name to keep a signed-in visitor
# off a stored anonymous page, and that rule is written in the CDN, not here. See docs/CACHING.md.
# SESSION_COOKIE=

# How long the homepage poster wall query is cached. 0 disables the cache, which is what the test
# suite does - so DO NOT set this to an empty value on a deployed install. An empty value is read
# as 0 and puts five correlated subqueries plus a regex pass on every origin hit of "/".
# MARKETING_WALL_CACHE_SECONDS=600

# Ceilings on one run of each nudge or announcement command, so a backlog drains over several
# runs rather than in one burst of mail. See config/usage.php for what each one bounds.
# ONBOARDING_NUDGE_BATCH=500
# ACTIVATION_NUDGE_BATCH=200
# AUDIENCE_ANNOUNCEMENT_BATCH=100
# AUDIENCE_ANNOUNCEMENT_RECIPIENT_BATCH=2000

# Minimum hours between automatic new-event announcements to a schedule's subscribers. This is
# the cadence the subscribe confirmation email promises ("at most one every few days"), so
# lowering it breaks a promise already made to people who opted in.
# AUDIENCE_ANNOUNCEMENT_MIN_HOURS=72

# Recipients one newsletter or announcement may reach when the sending schedule has neither its
# own SMTP nor an SMS-verified owner, and so is going out on the platform's shared mailer.
# AUDIENCE_MAIL_UNVERIFIED_MAX_RECIPIENTS=50