Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
baa8066
refactor(color-formatter): rename `gradientValue` parameter
eggy03 Feb 7, 2026
3e67bf6
refactor(audit-log): simplify audit log helper method signatures
eggy03 Feb 7, 2026
f0c66a9
refactor(audit-listeners): simplify event helpers
eggy03 Feb 7, 2026
a72fc6c
refactor(audit): enhance auto-mod event embeds
eggy03 Feb 7, 2026
8e08a13
refactor(automod): simplify automod rule event embeds
eggy03 Feb 7, 2026
1b76914
refactor(audit-log): streamline ban event embed creation
eggy03 Feb 7, 2026
5b9788b
refactor(audit-listeners): streamline `BotAddEventHelper` embed creation
eggy03 Feb 8, 2026
29fb157
refactor(project): reorganize package structure
eggy03 Feb 8, 2026
35a4dec
refactor(audit-events): improve moderation log embed clarity
eggy03 Feb 8, 2026
28706fd
refactor(audit-log-helper): improve channel create event embed fields
eggy03 Feb 8, 2026
fd78576
refactor(channel-delete-event): improve channel delete event helper
eggy03 Feb 8, 2026
a4846fa
refactor(audit): streamline channel delete event fields
eggy03 Feb 8, 2026
6dbdd54
style(audit-log): remove emoji from deleted channel ID field
eggy03 Feb 8, 2026
2f1c36d
refactor(audit-log-embeds): improve channel update event embed format…
eggy03 Feb 8, 2026
446a964
refactor(channel-overrides): centralize channel override utility methods
eggy03 Feb 8, 2026
72937ee
refactor(audit-log): improve voice channel status embed clarity
eggy03 Feb 8, 2026
7541fdc
refactor(embeds): inline embed builder call
eggy03 Feb 8, 2026
3f38708
refactor(automod): move automod type resolvers to dedicated utility
eggy03 Feb 8, 2026
d3ace64
refactor(audit-listeners): improve emoji audit log embed generation
eggy03 Feb 8, 2026
acca3e7
refactor(audit-log-helper): improve generic audit log embed display
eggy03 Feb 8, 2026
bf55f90
style(audit-log): display audit log fields on separate lines
eggy03 Feb 8, 2026
6e275b7
refactor(guild-utils): refactor guild property resolvers
eggy03 Feb 8, 2026
546fbe7
refactor(audit-helpers): standardize channel utility method names
eggy03 Feb 9, 2026
bf36a26
refactor(channel-utils): move channel-related utility methods
eggy03 Feb 9, 2026
d1986e8
refactor(onboarding-utils): move onboarding utilities to dedicated pa…
eggy03 Feb 9, 2026
8dc7b38
refactor(utils): centralize number parsing and improve resolution
eggy03 Feb 9, 2026
60ab4ad
refactor(audit): rename automod utility and refine embed fields
eggy03 Feb 9, 2026
5b0c847
refactor(audit): rename ban helper package to modactions
eggy03 Feb 9, 2026
fae20a3
refactor(audit): improve integration event processing
eggy03 Feb 9, 2026
cbb2118
refactor(audit-log): enhance event processing robustness
eggy03 Feb 9, 2026
3e9fd0f
fix(embed-handling): add check for sendable embeds
eggy03 Feb 9, 2026
3c152f9
refactor: improve member update event helper
eggy03 Feb 9, 2026
aa4ca6b
refactor(role-utils): relocate and enhance role parsing utility
eggy03 Feb 9, 2026
0584768
refactor(embed-messages): rephrase audit log event descriptions
eggy03 Feb 9, 2026
7be6caa
refactor(message): clarify pin/unpin event target details
eggy03 Feb 9, 2026
8fee58b
style(onboarding): remove 'unknown' from unimplemented change key mes…
eggy03 Feb 9, 2026
1ca49e0
refactor(utilities): improve null check and parameter name in `format…
eggy03 Feb 9, 2026
d3fb326
feat(audit-logs): enhance role and member event parsing
eggy03 Feb 9, 2026
65b1c08
refactor(utilities): remove message encryption and permission resolve…
eggy03 Feb 9, 2026
a4495d0
refactor(commons): standardize utility package and class names
eggy03 Feb 9, 2026
0375c55
refactor(commons): extract number parsing utilities
eggy03 Feb 9, 2026
f665643
refactor(scheduledevent): consolidate scheduled event utilities
eggy03 Feb 9, 2026
6714baa
refactor(auditlog): improve scheduled event audit log processing
eggy03 Feb 10, 2026
2342a31
style(log): shorten embed warning log messages
eggy03 Feb 10, 2026
a098f80
refactor(audit-log): improve soundboard event embeds
eggy03 Feb 10, 2026
e291816
feat(soundboard): add volume percentage formatting
eggy03 Feb 10, 2026
0b51706
refactor(commons): rename `NumberFormatUtils` to `NumberParseUtils`
eggy03 Feb 10, 2026
9af050b
refactor(stage-audit): enhance stage privacy level display
eggy03 Feb 10, 2026
398027d
refactor(utils): generalize guild events and add nullability annotations
eggy03 Feb 11, 2026
991a852
refactor(null-safety): enforce null-safety with `@NonNull` annotations
eggy03 Feb 11, 2026
edfd03f
refactor(project-info): apply @UtilityClass annotation
eggy03 Feb 11, 2026
2034404
style(ColorUtils): wrap single-line if statement in block
eggy03 Feb 11, 2026
c8487f1
refactor(listeners): replace explicit constructors with lombok
eggy03 Feb 11, 2026
1439415
style: apply jetbrains style cleanup
eggy03 Feb 11, 2026
4d68094
feat(sticker-audit): improve sticker audit log embeds
eggy03 Feb 11, 2026
e8e75b7
feat(sticker-audit): resolve related emojis in sticker audit logs
eggy03 Feb 11, 2026
5b75f5a
refactor(sticker-utils): add debug logging for sticker and emoji reso…
eggy03 Feb 11, 2026
513e8e6
feat(sticker): display sticker name in audit log for update events
eggy03 Feb 11, 2026
609a766
refactor(utils): add debug logging and improve error handling
eggy03 Feb 11, 2026
5523860
refactor(role-audit): relocate color formatting utilities
eggy03 Feb 11, 2026
783f244
refactor(utils): improve logging and standardize fallbacks
eggy03 Feb 11, 2026
2372331
refactor(scheduledevent): remove detailed recurrence rule from audit …
eggy03 Feb 11, 2026
9119262
feat(audit): enhance audit log processing and debugging
eggy03 Feb 11, 2026
558d2c4
docs(utils): add comment explaining logging rationale
eggy03 Feb 11, 2026
59f47bc
refactor(onboarding): standardize boolean status formatting
eggy03 Feb 12, 2026
addf9a5
feat(thread-events): add thread utilities and refactor audit embeds
eggy03 Feb 12, 2026
ec216ff
refactor(webhook): improve audit log event details
eggy03 Feb 12, 2026
04b13ab
style(audit-logs): improve audit log embed field display
eggy03 Feb 12, 2026
342f58b
refactor(codebase): add lombok `@NonNull` annotations
eggy03 Feb 12, 2026
ece6925
refactor(commands): improve slash command setup and listeners
eggy03 Feb 12, 2026
c273927
feat(audit): add supplementary audit event logging for guild events
eggy03 Feb 12, 2026
85f12f6
refactor(listeners): rename audit and supplementary audit packages
eggy03 Feb 13, 2026
30762a9
refactor(messagelog): extract event handling to helper classes
eggy03 Feb 13, 2026
50bfc3a
refactor(guild-member-remove): encapsulate member date retrieval logic
eggy03 Feb 13, 2026
bf98cf6
refactor(thread-utils): replace hardcoded fallback string with constant
eggy03 Feb 13, 2026
6e81c6d
refactor(commands): improve server stats command
eggy03 Feb 13, 2026
979ce9c
feat(debug): add debug slash command
eggy03 Feb 14, 2026
8f3c959
feat(listeners): display api health in debug command
eggy03 Feb 15, 2026
a2a6ee1
feat(debug): enhance debug command output
eggy03 Feb 15, 2026
d68ae64
docs: add contributing guidelines
eggy03 Feb 16, 2026
d82a3d8
chore: switch license to mit
eggy03 Feb 16, 2026
6dd8695
docs: update terms regarding data storage and project license
eggy03 Feb 16, 2026
2025e99
docs: expand and clarify data handling details
eggy03 Feb 16, 2026
0572ff7
docs: update last updated date
eggy03 Feb 16, 2026
cf8bbd2
docs: document sharding configuration and update license
eggy03 Feb 16, 2026
0535bab
docs: update supported event type count
eggy03 Feb 16, 2026
eaa1b0d
chore: add license header
eggy03 Feb 16, 2026
c433de1
fix: numeric ordering of examples
eggy03 Feb 16, 2026
9ffcacf
chore: bump jda version to `6.3.1`
eggy03 Feb 16, 2026
e615afe
docs: refine wording and formatting in privacy policy
eggy03 Feb 16, 2026
87f7b44
feat(activity): include /setup command in bot status
eggy03 Feb 16, 2026
7079e17
style: add arrow prefix to synced permissions message
eggy03 Feb 16, 2026
c414c88
feat(channel-update): add format for type and flags
eggy03 Feb 16, 2026
74b7b2b
feat(thread): log thread flag updates
eggy03 Feb 17, 2026
eca61b0
feat(auditlog): log home settings create and update events
eggy03 Feb 17, 2026
7a108be
feat(auditlog): handle application command privileges update event
eggy03 Feb 17, 2026
45cee12
chore: remove unused dependencies
eggy03 Feb 17, 2026
cab7223
chore: switch to APGLv3
eggy03 Feb 17, 2026
597a3e5
docs: update project overview and self-hosting guide
eggy03 Feb 17, 2026
4267f9d
docs: update project license reference to AGPLv3
eggy03 Feb 17, 2026
9bdaca5
feat(auditlog): handle `GUILD_PROFILE_UPDATE` events
eggy03 Feb 17, 2026
aaf5f3e
style(embeds): add arrow prefix to embed field values
eggy03 Feb 17, 2026
01deee6
refactor(webhook): reorder embed builder initialization and description
eggy03 Feb 17, 2026
42bff00
fix(embed): improve validation checks before building
eggy03 Feb 17, 2026
b7e99eb
Merge branch 'main' into develop-3.0.0
eggy03 Feb 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This project does not accept pull requests.

If you would like to modify or extend the bot, please feel free to fork the repository and maintain your own version.

Bug reports and suggestions are welcome through the Issues tab. I may review and address them as time permits.
862 changes: 661 additions & 201 deletions LICENSE

Large diffs are not rendered by default.

81 changes: 50 additions & 31 deletions PRIVACY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Privacy Policy

**Data Controller:** This project is maintained by [@Egg-03](https://github.com/eggy03).
**Data Controller:** This project is maintained by [@Egg-03](https://github.com/eggy03).

**Last Updated:** February 16, 2026

This Discord bot was built as an open source project with a privacy-first mindset.
The Service is provided at no cost and is intended for use as-is.
Expand Down Expand Up @@ -33,52 +35,70 @@ The bot only stores data when specific features are explicitly enabled by server
### If **Message Logging** is enabled:
- Message Content
- Message ID
- Author ID (Discord user ID)
- Author ID (Discord user ID of the message owner)
- Channel ID
- Guild ID
- Timestamp

Message content is stored in plain text and is not used for analytics or shared outside your server.

### If **only Audit Logging** is enabled:
- Guild ID
- Channel ID where audit logs should be sent (one per guild)

No message content or user data is stored in this case.
No message content, message ID or Author ID is stored in this case.

The stored data is used solely for server moderation purposes.
**Note on Direct Messages (DMs)**: The bot does not monitor, read, or store data from Direct Messages between users.
It only processes data within Discord Guilds (servers) where it has been explicitly invited.

---

## Data Retention

- All stored message contents and their metadata are automatically deleted after **30 days**.
- No data is permanently retained or used for any analytics.
- Configuration data (e.g., log channel IDs) is kept until the server administrator unregisters the bot or removes it from the server.
- Server administrators can also request immediate deletion of all stored data for their guild by contacting us.
We adhere to a strict data minimization policy.
Information is only retained for the duration necessary to provide the bot's logging features.

- **Temporary Message Logs**: All captured message content (text-only) and metadata logs are stored for a maximum period
of 30 days.
Following this period, data is programmatically purged from our production databases.
- **System Backups**: Data contained within database backups may persist for up to an additional 7 days beyond the
standard retention period before being overwritten.
- **Administrative Data**: Configuration settings (e.g. designated log channels) are retained as long as the bot
remains authorized within the Discord Guild.

---

## Diagnostic Logs
## Data Security

In case of runtime errors, the bot may log basic diagnostic information such as error messages, timestamps, and internal event states to assist with debugging.
Logs may include additional metadata such as guild IDs, channel IDs, message IDs, or user IDs when necessary to diagnose issues.
We implement reasonable technical and organizational measures to protect stored data from unauthorized access, loss,
or misuse. This includes strict access controls, limited operator access, and infrastructure security best practices.

Log retention is governed by our infrastructure providers and operational requirements, and may vary over time.
Logs are not used for analytics.
**Infrastructure & Storage**

---
- Cloud Providers: We utilize `Northflank` for application hosting and `Aiven` for managed database services.
- Encryption: While all collected data is stored in a readable format, our infrastructure providers employ encryption
to protect data on the physical disk level. To know more, read their security
policies of our providers [Northflank](https://northflank.com/security)
and [Aiven](https://aiven.io/security-compliance).

**Access Control**

## Security
Access to the production environment and database is strictly limited to the Data Controller (@Egg-03).
No other contributors or third parties have access to the raw data stored by the bot.

We take reasonable technical and organizational measures to protect stored data from unauthorized access, loss, or misuse.
This includes access controls, limited operator access, and infrastructure security best practices.
**Disclaimer**

Message content is stored in plain text on cloud infrastructure.
This is the same general model used by Discord (i.e., messages are not end-to-end encrypted).
We do not perform analytics on message content.
While we strive to use commercially acceptable means to protect your information, no method of transmission over the
internet or method of electronic storage is 100% secure.
We cannot guarantee absolute security and the service is provided on an "as-is" basis.

However, no method of transmission over the internet or method of electronic storage is 100% secure, and we cannot guarantee absolute security.
---

## Diagnostic Logs

In case of runtime errors, the bot may log basic diagnostic information such as error messages, timestamps, and internal event states to assist with debugging.
Logs may include additional metadata such as guild IDs, channel IDs, message IDs, or user IDs when necessary to diagnose issues.

Log retention is governed by our infrastructure providers and operational requirements, and may vary over time.
Logs are not used for analytics.

---

Expand All @@ -91,16 +111,15 @@ If it is discovered that such data has been inadvertently stored, it will be del

## User Rights

All users, regardless of location, have the following rights:

- **Right of Access**: You may request what data (if any) is associated with your Discord user ID.
- **Right to Erasure**: You may request deletion of your data from the database.
We respect the privacy rights of all Discord users. Regardless of your jurisdiction, you may exercise the following:

To protect user privacy, we will verify the identity of the requestor before fulfilling access or deletion requests (for example: confirmation from the guild owner or proof of control of the Discord user account).
We will respond to verified requests within 30 days.
If additional information is needed, we will notify you and may extend the response period where permitted by law.
- **Right to Access**: Users may request a transcript of all stored data associated with their Discord Snowflake ID.
- **Right to Erasure**: Users may request the immediate removal of their data from our active logs.

To request access or deletion, please contact us using the method below.
To submit a request: Please contact us using one of the methods below.
For security purposes, we may require you to verify your identity via a signed message or a direct interaction through
the official Discord client.
NOTE: We will never ask for any kinds of passwords or secret tokens from you.

---

Expand Down
173 changes: 120 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,147 @@
# Overview
PaperTrail is a free and open-source, self-hostable, and privacy-friendly Discord bot designed to provide audit log data directly in a channel—without requiring users to navigate server settings each time.

PaperTrail is a free and open-source, self-hostable, and privacy-friendly Discord bot
designed to provide audit log data directly in a channel without requiring users to navigate server settings each time.

Key Features:

- Full audit log integration (supports over 50+ event types) and generic support for unknown types
- Full audit log integration (supports over 72 event types) and generic support for unknown types
- Message logging (edit, delete)
- Member activity tracking (joins, leaves, kicks, bans, updates)
- Voice activity logging (join/leave, move)
- Auto-deletion of logged messages after 30 days

> Get it from here: https://discord.com/discovery/applications/1381658412550590475

# Repositories

| Repository | Description |
|---------------------------------------------------------------------------------------|------------------------------------------|
| [PaperTrailBot](https://github.com/eggy03/PaperTrailBot) | Core bot application |
| [PaperTrail SDK](https://github.com/eggy03/papertrail-sdk) | Client library for the API |
| [PaperTrail Persistence Service](https://github.com/eggy03/PaperTrail-PersistenceAPI) | Backend API for providing CRUD functions |

> [!IMPORTANT]
> PaperTrail is currently in maintenance mode. Existing bugs will be fixed, dependency updates will be provided
> but large new features will likely not be added.

# Self-Hosting Guide

> [!IMPORTANT]
> It is recommended that you deploy the [Persistence API](https://github.com/Egg-03/PaperTrail-PersistenceAPI?tab=readme-ov-file#papertrail-persistenceapi) service before deploying the bot itself since the bot relies on the URL of the service to communicate
> Please note that this is only for advanced users who want to self-host this bot
>
> Set up the API Service before setting up the bot

## Setting up the API Service

Follow this [guide](https://github.com/Egg-03/PaperTrail-PersistenceAPI?tab=readme-ov-file#papertrail-persistenceapi)

## Setting up the Bot Service

### Step 1: Create an application in the Developer Portal

Log on to the [Discord Developer Portal](https://discord.com/developers/applications) and create an application.

The application can have any name, avatar, banner and description but the following scopes, permissions and intents are
needed
for it to work properly:

**Installation Contexts**

The project is split into two services:
1) The core bot service
2) A [Persistence API](https://github.com/Egg-03/PaperTrail-PersistenceAPI) service
1) Guild Install

The following guide shows how to set up the bot service
**Scopes**

To read the guide on deploying the Persistence API Service, click [here](https://github.com/eggy03/PaperTrail-PersistenceAPI?tab=readme-ov-file#papertrail-persistenceapi)
1) applications.commands
2) bot

### Step 1: Get Required Secrets
**Permissions**

1) Manage Server
2) Read Message History
3) Send Messages
4) Send Messages In Threads
5) View Audit Log
6) View Channels

**Privileged Gateway Intents**

1) Presence Intent
2) Server Members Intent
3) Message Content Intent

Don't forget to copy the `bot token` as it will be required in the next step

### Step 2: Get Required Secrets

You will need the following environment variables to run the bot:

| Variable | Description |
|-----------|-----------------------------------------------------------------------------------------------------------|
| `TOKEN` | Discord application bot token (from the [Developer Portal](https://discord.com/developers/applications)) |
| `API_URL` | Internal URL of the Persistence API (e.g., `http://persistence:8080`) |
| Variable | Description |
|----------------|-----------------------------------------------------------------------|
| `TOKEN` | Discord application bot token (from the Developer Portal) |
| `API_URL` | Internal URL of the Persistence API (e.g., `http://persistence:8080`) |
| `TOTAL_SHARDS` | The total number of shards (connections) your bot is using overall. |
| `MIN_SHARD_ID` | The first shard number this bot instance should handle. |
| `MAX_SHARD_ID` | The last shard number this bot instance should handle. |

Each shard allows handling up-to 2500 guilds.

Take a look at the following configuration examples to have a clearer picture of what values to put
for your use-case

**1: JVM Instance / 1-2500 Guilds / 1 Shard**

If your bot is small or self-hosted for a limited number of servers, you only need one shard.
This should be sufficient for the majority of self-host users

```dotenv
TOTAL_SHARDS=1
MIN_SHARD_ID=0
MAX_SHARD_ID=0
```

**2: JVM Instance /2500-5000 Guilds / 2 Shards**

### Step 2: Deployment Options
If your bot is in more than 2,500 servers, but you are still running a single JVM instance, you can increase the total
shard count:

```dotenv
TOTAL_SHARDS=2
MIN_SHARD_ID=0
MAX_SHARD_ID=1
```

Remember that each shard can only handle up to 2500 guilds so plan the total number shards accordingly

**3: JVM Instances / 25000 Guilds / 10 Shards**

If you scale your bot horizontally, you need to split the shards between them.

Instance 1:

```dotenv
TOTAL_SHARDS=10
MIN_SHARD_ID=0
MAX_SHARD_ID=4
```

Instance 2:

```dotenv
TOTAL_SHARDS=10
MIN_SHARD_ID=5
MAX_SHARD_ID=9
```

Shard ID ranges must never overlap between running instances.

### Step 3: Deployment Options

Fork this repository to your GitHub account, connect it to your preferred cloud platform, and configure your environment variables in the platform.
Some platform services may also support adding secrets directly from your `.env` file.

#### Cloud Platforms with GitHub + Docker Support
- These can auto-deploy using the included `Dockerfile`
- Optional: The bot exposes a `/ping` endpoint which can be used by platforms to periodically check for it's health

#### Locally
- You can also test it locally by building and running using the `Dockerfile`
Expand All @@ -56,46 +156,13 @@ Some platform services may also support adding secrets directly from your `.env`
The bot exposes a `/ping` endpoint on port **8080**.
This endpoint simply returns `200 OK` and is intended for platforms or uptime monitors to check if the bot is alive.

> Note: This is **not a public API** and serves no other function beyond internal service health monitoring.

# Privacy

PaperTrail is built with privacy-first principles. By default, it **does not log any personal data** unless features are explicitly enabled by server admins.

- Messages are logged for moderation purposes only, if enabled.
- Logs are automatically deleted after 30 days.
- No personal data is used for analytics, profiling, or sold to third parties.
- If requested, users can have their data deleted by ID.

*Never post sensitive information in public channels.*

[Read the full Privacy Policy](./PRIVACY.md)

# Security

If you discover a security vulnerability in PaperTrail, please report it **privately**.

- Do **not** open public GitHub issues for security bugs.
- Instead, email me at 📧 **eggzerothree@proton.me**
- I will respond as soon as possible and work with you to resolve the issue.

[View the full Security Policy](./SECURITY.md)

# Terms of Use

PaperTrail is provided under the Apache 2.0 License and is intended for responsible use.
By using the official hosted instance or self-hosting it, you agree to the basic terms outlined in our [Terms of Service](./TERMS.md).
> Note: This is **not a public endpoint** and serves no other function beyond internal service health monitoring.

# License

PaperTrail is licensed under the [Apache License 2.0](./LICENSE).

You are free to:
- Use, modify, and redistribute the code
- Self-host or publicly host your own instance
- Build on top of this bot for your own projects

Just make sure to include proper attribution and comply with the [terms](https://www.apache.org/licenses/LICENSE-2.0).
- **PaperTrailBot**: AGPLv3
- **PaperTrail Persistence API**: AGPLv3
- **PaperTrail SDK**: GNU GPLv3

---
Feel free to contribute to this guide or raise issues on GitHub if you get stuck!
Feel free to raise issues on GitHub if you get stuck!
7 changes: 3 additions & 4 deletions TERMS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Terms of Service

_Last updated: February 02, 2026_
_Last updated: February 16, 2026_

Thank you for using **PaperTrail**, an open-source Discord audit and message logging bot.

Expand All @@ -24,7 +24,7 @@ You agree to use the bot responsibly, and not for any of the following:
## 2. Privacy

This bot logs message and event data **only if you enable those features**.
Message content is stored in plain text and logs are automatically deleted after 30 days.
All content is stored in a readable format .

See our [Privacy Policy](./PRIVACY.md) for full details on data handling, retention, and user rights.

Expand All @@ -43,8 +43,7 @@ The project maintainers are not responsible for how self-hosted instances handle

## 4. Modifications

You are free to fork, modify, or self-host this project under the terms of the [Apache 2.0 License](./LICENSE).
If you publicly redistribute a modified version, you must preserve the original license and attribution.
You are free to fork, modify, or self-host this project under the terms of the [AGPLv3](./LICENSE).

---

Expand Down
Loading
Loading