diff --git a/.gitignore b/.gitignore index c565df53..7b20f999 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,8 @@ Thumbs.db temp/ **/*.db-journal -uploads/ \ No newline at end of file +uploads/ + +# Paraglide +src/lib/paraglide +project.inlang/cache/ diff --git a/README.md b/README.md index 52c75044..d7a3fc4b 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,16 @@ ## ✨ Features -- 🚗 **Vehicle Management:** Add, edit, and manage multiple vehicles. +- 🚗 **Vehicle Management:** Add, edit, and manage multiple vehicles with support for different fuel types. - ⛽ **Fuel Tracking:** Log fuel refills and monitor fuel efficiency over time. - 🛠️ **Maintenance Log:** Record and view maintenance history for each vehicle. -- 📄 **Document Tracking:** Track insurance, pollution certificates, and other important documents. -- 📊 **Dashboard:** Visualize key metrics and upcoming renewals. +- 📄 **Document Tracking:** Track insurance and pollution certificates with renewal dates. +- 🔔 **Reminders:** Set and manage reminders for maintenance, renewals, and other vehicle events. +- 📊 **Dashboard:** Visualize key metrics, analytics, and upcoming renewals. - 🔒 **User Authentication:** Secure username/password authentication with session management. +- 🎨 **Feature Toggles:** Enable or disable specific features based on your needs. -## 🖼️ images +## 🖼️ Screenshots

🔐 Login Page


@@ -82,20 +84,28 @@ ## 🛠️ Tech Stack -- 🎨 **Frontend:** SvelteKit, Tailwind CSS -- 🖥️ **Backend:** Node.js, Express.js -- 🗄️ **Database:** SQLite, sequelize ORM -- 🐳 **Containerization:** Docker & Docker Compose +- 🎨 **Frontend:** SvelteKit, Tailwind CSS, Svelte 5 +- 🖥️ **Backend:** SvelteKit Server Routes +- 🗄️ **Database:** SQLite with Drizzle ORM +- 🐳 **Deployment:** Docker & Docker Compose ## 🚀 Getting Started -Please check the [installation guide](./docs/installation.md) for detailed instructions on setting up the project. +Refer to the [installation guide](./docs/installation.md) for setup instructions. + +## 📚 Documentation + +- [Installation Guide](./docs/installation.md) - Setup instructions for Docker, local development, and Proxmox LXC +- [Authentication](./docs/authentication.md) - User authentication and session management +- [Environment Variables](./docs/environment.md) - Configuration options +- [Feature Toggles](./docs/feature-toggles.md) - Customizing enabled features +- [Contributing](./docs/contributing.md) - Guidelines for contributing ## 🤝 Contributing Contributions are welcome! Please read the [contributing guidelines](./docs/contributing.md) before submitting a pull request. -Please consider supporting this project by giving it a star! ⭐ or [sponsoring](https://github.com/sponsors/javedh-dev). +Consider supporting this project by giving it a star ⭐ or [sponsoring](https://github.com/sponsors/javedh-dev). ## 📄 License diff --git a/docs/authentication.md b/docs/authentication.md index 83bd914e..1968ac58 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -1,47 +1,30 @@ -# Authentication System +# Authentication -Tracktor uses a modern username/password authentication system with session management for secure access to your vehicle data. +Tracktor uses username/password authentication with session management for secure access. -## Overview +## Features -The authentication system has been migrated from PIN-based authentication to a more robust username/password system with the following features: +- **Username/Password Authentication**: Secure login credentials +- **Session Management**: HTTP-only secure session cookies +- **User Registration**: First time account creation through web interface +- **Password Hashing**: Bcrypt-based password security +- **Session Expiration**: Automatic expiration after 30 days of inactivity -- **Username/Password Authentication**: Secure login with username and password -- **Session Management**: Uses secure session cookies for maintaining login state -- **User Registration**: Create new user accounts -- **Password Hashing**: Passwords are securely hashed using bcrypt -- **Session Expiration**: Sessions automatically expire after 30 days of inactivity +## Creating User Accounts -## Creating Your First User - -When you first set up Tracktor, you'll need to create a user account. You can do this in two ways: - -### Method 1: Through the Web Interface +### Web Interface 1. Navigate to the login page -2. If no users exist, you'll see a registration form -3. Enter your desired username and password +2. If no users exist, a registration form will be displayed +3. Enter username and password 4. Click "Create Account" + ˝ -### Method 2: Using the Command Line Script - -```bash -pnpm tsx scripts/create-user.ts -``` - -Example: - -```bash -pnpm tsx scripts/create-user.ts admin mypassword123 -``` - -## API Authentication - -For API access, the system uses session-based authentication: +## API Endpoints ### Login -```bash +```http POST /api/auth Content-Type: application/json @@ -53,50 +36,44 @@ Content-Type: application/json ### Logout -```bash +```http DELETE /api/auth ``` ### Check Authentication Status -```bash +```http GET /api/auth ``` ## Session Management -- Sessions are stored in the database and linked to user accounts -- Session cookies are HTTP-only and secure (in production) -- Sessions automatically refresh when they're close to expiring -- Sessions are invalidated on logout - -## Security Features - -- **Password Hashing**: All passwords are hashed using bcrypt with salt rounds -- **Session Tokens**: Cryptographically secure session tokens -- **Automatic Cleanup**: Expired sessions are automatically removed -- **CSRF Protection**: Session cookies include CSRF protection +- Sessions stored in database and linked to user accounts +- HTTP-only secure cookies (in production) +- Automatic session refresh when approaching expiration +- Sessions invalidated on logout -## Migration from PIN Authentication +## Security -If you're upgrading from a PIN-based system: +- **Password Hashing**: Bcrypt with salt rounds +- **Session Tokens**: Cryptographically secure tokens +- **Automatic Cleanup**: Expired sessions removed automatically +- **CSRF Protection**: Built-in session cookie protection -1. The old PIN authentication table is preserved for backward compatibility -2. Create new user accounts using the registration system -3. The old PIN endpoints are still available but deprecated -4. Consider migrating to the new authentication system for better security +## Configuration -## Environment Variables +**Environment Variable**: `TRACKTOR_DISABLE_AUTH` -- `TRACKTOR_DISABLE_AUTH`: Set to 'true' to disable authentication (not recommended for production) +- Set to `true` to disable authentication (not recommended for production) +- Default: `false` ## Troubleshooting -### Can't Login +**Login Issues**: -- Ensure you've created a user account -- Check that your username and password are correct -- Clear your browser cookies if you're having session issues +- Verify user account exists +- Confirm username and password are correct +- Clear browser cookies if experiencing session issues ### Session Expired diff --git a/docs/contributing.md b/docs/contributing.md index 1c2dd2a0..90102207 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -1,22 +1,49 @@ # Contributing -We welcome contributions from the community! If you'd like to contribute to this project, please follow these steps: +Contributions are welcome! Follow these guidelines to contribute to Tracktor. -1. Fork the repository on GitHub. -2. Clone your forked repository to your local machine. -3. Create a new branch for your feature or bug fix. -4. Make your changes and commit them with clear messages. -5. Run tests to ensure everything works as expected. -6. Run the linter to ensure code quality. -7. Push your changes to your forked repository. -8. Open a pull request against the main repository's master branch. - Please ensure your code adheres to the project's coding standards and includes appropriate tests. We appreciate your - contributions and look forward to collaborating with you! +## Getting Started -# License +1. Fork the repository on GitHub +2. Clone your forked repository to your local machine +3. Create a new branch for your feature or bug fix +4. Make your changes with clear, descriptive commit messages +5. Run tests to ensure everything works +6. Run the linter to maintain code quality +7. Push your changes to your forked repository +8. Open a pull request against the dev repository -This project is licensed under the MIT License. See the LICENSE file for details. +## Development Workflow -# Contact +### Running Tests -If you have any questions or need further assistance, feel free to reach out to the project maintainer at [javedh.dev@gmail.com](mailto:javedh.dev@gmail.com) +```bash +pnpm run test +``` + +### Linting and Formatting + +```bash +pnpm run lint +pnpm run format +``` + +## Guidelines + +- Follow the project's coding standards +- Include appropriate tests for new features +- Write clear commit messages +- Update documentation when necessary +- Ensure all tests pass before submitting a pull request + +## Code Quality + +All contributions should maintain or improve code quality. Run linting and formatting tools before committing changes. + +## License + +This project is licensed under the MIT License. See the [LICENSE](../LICENSE) file for details. + +## Contact + +For questions or assistance, contact the project maintainer at [javedh.dev@gmail.com](mailto:javedh.dev@gmail.com). diff --git a/docs/environment.md b/docs/environment.md index d77eb96e..ed6f3fa4 100644 --- a/docs/environment.md +++ b/docs/environment.md @@ -1,63 +1,114 @@ -Tracktor app uses environment variables to configure its settings. Here are some common environment variables used in Tracktor: +# Environment Variables -1. **NODE_ENV** - Specifies the environment in which the application is running. - - Possible values are `dev`, `production`, and `test`. - - Default : `development`. +Configure Tracktor by setting environment variables in a `.env` file in the root directory or as system environment variables. -2. **SERVER_HOST** - Defines the hostname or IP address where the server will listen for incoming requests. If You want the server to be accessible from all network interfaces, you can set this to `0.0.0.0` - - Possible values are any valid hostname or IP address. - - Default : `localhost`. +## Application Settings -3. **SERVER_PORT** - Sets the port number on which the server will listen for incoming requests. - - Possible values are any valid port number (e.g., `3000`, `8080`). That port must be free. - - Default : `3000`. +### NODE_ENV -4. **DB_PATH** - Specifies the file path to the database used by Tracktor. This is typically a SQLite database file. - - Possible values are any valid file path (e.g., `/path/to/tracktor.db`). - - Default : `./tracktor.db`. - - For docker setup this environment variable is set to `/data/tracktor.db`. +Application environment. -5. **UPLOADS_DIR** - Defines the directory path where uploaded files will be stored. - - Possible values are any valid directory path (e.g., `/path/to/uploads`). - - Default : `./uploads`. - - For docker setup this environment variable is set to `/data/uploads`. +- **Values**: `dev`, `production`, `test` +- **Default**: `dev` -6. **AUTH_PIN** - Sets a PIN code for authentication purposes. This is used to log in to the Tracktor application. - - Possible values are any 6 digit string representing the PIN code (e.g., `000000`). - - Default : `123456`. - **NOTE:** To change the pin update this environment variable before starting the application. +### HOST -7. **CORS_ORIGINS** - Specifies the allowed origins for Cross-Origin Resource Sharing (CORS). This is useful for controlling which domains can access the Tracktor API. - - Possible values are a comma-separated list of allowed origins (e.g., `http://example.com,https://anotherdomain.com,http::3000`). - - Default : `*` (allows all origins). - **NOTE:** When using Tracktor with a frontend application hosted on a different domain or port or behind reverse proxy, it's recommended to set this variable to the specific origin of the frontend application for security reasons. +Hostname or IP address for the server. Set to `0.0.0.0` to listen on all network interfaces. -8. **TRACKTOR_DEMO_MODE** - A boolean flag that, when set to `true`, enables demo mode features in the application by seeding some demo data to try out application features. - - Possible values are `true` or `false`. - - Default : `false`. +- **Values**: Any valid hostname or IP address. Used only on production or build +- **Default**: `localhost` -9. **FORCE_DATA_SEED** - A boolean flag that, when set to `true`, forces the application to seed the database with demo data on startup if `TRACKTOR_DEMO_MODE` is set to true. - - Possible values are `true` or `false`. - - Default : `false`. +### PORT -10. **LOG_REQUESTS** - A boolean flag that, when set to `true`, enables logging of incoming HTTP requests in backend API. - - Possible values are `true` or `false`. - - Default : `true`. +Port number for the server. -11. **LOG_LEVEL** - Sets the logging level for the application. The logging level determines the severity of messages that will be logged. - - Possible values are `error`, `warn`, `info`, `http`, `verbose`, `debug`, and `silly`. - - Default : `info`. +- **Values**: Any available port number. Used only on production or build +- **Default**: `3000` -12. **LOG_DIR** - Specifies the directory path where log files will be stored. - - Possible values are any valid directory path (e.g., `/path/to/logs`). - - Default : `./logs`. +## Database -13. **TRACKTOR_API_BASE_URL** - Defines the base URL for the public API endpoints. This is useful when the application is behind a reverse proxy or load balancer. - - Possible values are any valid URL (e.g., `http://example.com`). - - Default : `http://localhost:3000`. +### DB_PATH -14. **TRACKTOR_DISABLE_AUTH** - A boolean flag that, when set to `true`, disables authentication for the public API endpoints. - - Possible values are `true` or `false`. - - Default : `false`. +Path to the SQLite database file. -**NOTE:** These environment variables can be set in your system or in a `.env` file in the root directory of the Tracktor application. Make sure to restart the application after changing any environment variables for the changes to take effect. +- **Values**: Any valid file path +- **Default**: `./tracktor.db` +- **Docker**: `/data/tracktor.db` + +## File Storage + +### UPLOADS_DIR + +Directory for uploaded files. + +- **Values**: Any valid directory path +- **Default**: `./uploads` +- **Docker**: `/data/uploads` + +## Security + +### CORS_ORIGINS + +Allowed origins for Cross-Origin Resource Sharing (CORS). When using Tracktor behind a reverse proxy or with a frontend on a different domain/port, set this to specific origins for security. + +- **Values**: Comma-separated list of origins (e.g., `http://example.com,https://anotherdomain.com`) +- **Default**: `*` (allows all origins) + +### TRACKTOR_DISABLE_AUTH + +Disable authentication (not recommended for production). + +- **Values**: `true`, `false` +- **Default**: `false` + +## Demo Mode + +### TRACKTOR_DEMO_MODE + +Enable demo mode with sample data. + +- **Values**: `true`, `false` +- **Default**: `false` + +### FORCE_DATA_SEED + +Force database seeding with demo data on startup overwriting the existing data (requires `TRACKTOR_DEMO_MODE=true`). + +- **Values**: `true`, `false` +- **Default**: `false` + +## Logging + +### LOG_REQUESTS + +Enable HTTP request logging. + +- **Values**: `true`, `false` +- **Default**: `true` + +### LOG_LEVEL + +Logging verbosity level. + +- **Values**: `error`, `warn`, `info`, `http`, `verbose`, `debug`, `silly` +- **Default**: `info` + +### LOG_DIR + +Directory for log files. + +- **Values**: Any valid directory path +- **Default**: `./logs` + +### BODY_SIZE_LIMIT + +Limits the upload size of image/documents. + +- **values**: Any number (size in bytes) +- **Defaut**: 512Kb +- **Docker**: Infinity (removes restriction) + +## Notes + +- Environment variables can be set in a `.env` file in the root directory or as system environment variables +- Restart the application after changing environment variables for changes to take effect diff --git a/docs/feature-toggles.md b/docs/feature-toggles.md new file mode 100644 index 00000000..edd934ea --- /dev/null +++ b/docs/feature-toggles.md @@ -0,0 +1,198 @@ +# Feature Toggle System + +This document explains how to use the feature toggle system in Tracktor. + +## Overview + +The feature toggle system allows you to enable or disable specific features throughout the application. This is useful for: + +- Rolling out features gradually +- A/B testing +- Providing customization options to users +- Hiding incomplete features + +## Available Features + +The following features can be toggled: + +1. **Fuel Log** - Track and manage fuel consumption and refueling history +2. **Maintenance** - Record and schedule vehicle maintenance activities +3. **PUCC** - Manage Pollution Under Control Certificate records +4. **Reminders** - Set and receive reminders for important vehicle events +5. **Insurance** - Manage vehicle insurance details and renewals +6. **Overview** - Display overview dashboard with key vehicle metrics + +## Configuration + +Features are configured through the Settings page under the "Features" tab. Each feature has a checkbox that can be toggled on or off. + +### Database Storage + +Feature toggles are stored in the `configs` table with the following keys: + +- `featureFuelLog` +- `featureMaintenance` +- `featurePucc` +- `featureReminders` +- `featureInsurance` +- `featureOverview` + +Values are stored as strings: `'true'` or `'false'` + +## Usage in Code + +### Using the FeatureGate Component + +The easiest way to conditionally show/hide components based on feature flags: + +```svelte + + + + + + + + + + + + + + + + + + + + {#snippet children()} + + {/snippet} + {#snippet fallback()} +

Overview feature is currently disabled

+ {/snippet} +
+``` + +### Using Helper Functions + +For more programmatic control: + +```typescript +import { + isFeatureEnabled, + Features, + getEnabledFeatures, + areAllFeaturesEnabled, + isAnyFeatureEnabled +} from '$lib/helper/feature.helper'; + +// Check if a single feature is enabled +if (isFeatureEnabled(Features.FUEL_LOG)) { + // Show fuel log functionality +} + +// Get all enabled features +const enabledFeatures = getEnabledFeatures(); +console.log('Enabled features:', enabledFeatures); + +// Check if all features are enabled +if (areAllFeaturesEnabled([Features.FUEL_LOG, Features.MAINTENANCE])) { + // Show combined view +} + +// Check if any feature is enabled +if (isAnyFeatureEnabled([Features.INSURANCE, Features.PUCC])) { + // Show documents section +} +``` + +### Direct Access via Config Store + +```typescript +import { configStore } from '$stores/config.svelte'; + +// In a Svelte component +let showFuelLog = $derived(configStore.configs.featureFuelLog); +``` + +## Conditional Navigation + +You can use feature flags to conditionally show/hide navigation items: + +```svelte + + +{#if configStore.configs.featureFuelLog} + Fuel Log +{/if} + +{#if configStore.configs.featureMaintenance} + Maintenance +{/if} +``` + +## Best Practices + +1. **Always provide fallback UI** - Consider what users should see when a feature is disabled +2. **Use semantic checks** - Instead of checking multiple flags separately, use `requireAll` or `requireAny` +3. **Keep flags granular** - Each feature should be independently toggleable +4. **Document dependencies** - If Feature B requires Feature A, document this relationship +5. **Test both states** - Always test with features both enabled and disabled + +## Adding New Features + +To add a new feature toggle: + +1. **Create a migration** to add the config: + + ```sql + INSERT INTO `configs` VALUES + ('featureNewFeature','true','Description of the feature', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); + ``` + +2. **Update the Config interface** in [src/lib/domain/config.ts](../domain/config.ts): + + ```typescript + export interface Configs { + // ... existing fields + featureNewFeature?: boolean; + } + ``` + +3. **Update the config store** in [src/lib/stores/config.svelte.ts](../stores/config.svelte.ts): + - Add default value + - Add case in switch statement + +4. **Update the schema** in [SettingsForm.svelte](../components/feature/settings/SettingsForm.svelte): + + ```typescript + const configSchema = z.object({ + // ... existing fields + featureNewFeature: z.boolean().optional() + }); + ``` + +5. **Add checkbox** to the Features tab in SettingsForm.svelte + +6. **Update the Features constant** in [src/lib/helper/feature.helper.ts](feature.helper.ts): + ```typescript + export const Features = { + // ... existing features + NEW_FEATURE: 'newFeature' + } as const; + ``` + +## Migration + +Run migrations to apply the feature toggle configs: + +```bash +pnpm db:push +# or +pnpm db:migrate +``` diff --git a/docs/i18n.md b/docs/i18n.md new file mode 100644 index 00000000..ca0b6d7e --- /dev/null +++ b/docs/i18n.md @@ -0,0 +1,33 @@ +# Internationalization (i18n) + +Tracktor uses Paraglide (inlang) with the Svelte 5 addon for runtime-localized UI and proper `lang` propagation. + +## How it works + +- Paraglide runtime and middleware are scaffolded under `src/lib/paraglide/`. +- `src/hooks.server.ts` uses `paraglideMiddleware` to determine the request locale and set the HTML `lang` attribute (see `src/app.html`). +- The current locale is determined via Paraglide's strategy (cookie → global variable → base locale) and can be updated at runtime. +- App configuration stores the preferred locale in the `configs` table (`key = 'locale'`). + +## Config-driven locale + +- On startup and whenever configs refresh, the app sets Paraglide's locale without reloading for a smooth init (`setLocale(configs.locale, { reload: false })`). +- When you change locale from Settings, the app saves the new value and then calls `setLocale(newLocale)` which updates the cookie and reloads the page. + +## Changing the language + +1. Go to Dashboard → Settings. +2. Under Personalization, use the Locale dropdown to choose a language. +3. The app reloads with the new locale and remembers it via cookie and configs. + +## Adding a new language + +1. Add the language in your Paraglide source/messages and regenerate the compiled outputs under `src/lib/paraglide/messages/`. +2. Ensure the new language code is included in Paraglide's generated `locales` array (in `src/lib/paraglide/runtime.js`). +3. Optionally add a human-readable label in `src/lib/components/feature/settings/SettingsForm.svelte` in the `localeLabels` map. +4. Provide translations for your messages via inlang tooling (VS Code Sherlock, Fink, etc.). + +## Notes + +- The `lang` attribute is set server-side for accessibility and SEO. +- If you integrate URL-based localization later, update Paraglide `strategy` to include `url` and keep the existing middleware as-is. diff --git a/docs/installation.md b/docs/installation.md index bb876f7d..55facdb0 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,14 +1,18 @@ -# Installation +# Installation Guide -There are couple of ways to install the tracktor app. +This guide covers multiple installation methods for Tracktor. ## Docker Compose (Recommended) -The recommended way to install tracktor is by using Docker Compose. This method ensures that all dependencies are properly managed and the application runs in an isolated environment. +Docker Compose is the recommended installation method as it ensures proper dependency management and runs the application in an isolated environment. -1. Make sure you have Docker and Docker Compose installed on your system. +### Prerequisites -2. Create a `docker-compose.yml` file with the following content: +- Docker and Docker Compose installed on your system + +### Steps + +1. Create a `docker-compose.yml` file: ```yaml services: @@ -35,13 +39,13 @@ volumes: name: tracktor-data ``` -3. Start the application using Docker Compose: +2. Start the application: ```bash docker-compose up -d ``` -4. Access the application by navigating to `http://:3333` in your web browser. +3. Access the application at `http://:3333`. ### Updating Tracktor @@ -83,24 +87,27 @@ docker-compose down docker volume rm tracktor-data ``` -## Manual Docker Installation +## Docker (Manual) -If you prefer not to use Docker Compose, you can manually run the Tracktor application using Docker +### Prerequisites -1. Make sure you have Docker installed on your system. -2. Pull the latest Tracktor image from GitHub Container Registry: +- Docker installed on your system + +### Steps + +1. Pull the latest Tracktor image: ```bash docker pull ghcr.io/javedh-dev/tracktor:latest ``` -3. Create a Docker volume to persist data: +2. Create a Docker volume: ```bash docker volume create tracktor-data ``` -4. Run the Tracktor container with the necessary configurations: +3. Run the container: ```bash docker run -d \ @@ -113,31 +120,23 @@ docker run -d \ ghcr.io/javedh-dev/tracktor:latest ``` -5. Access the application by navigating to `http://:3333` in your web browser. +4. Access the application at `http://:3333`. -### Updating Tracktor - -To update Tracktor to the latest version, follow these steps: +### Updating -1. Stop the running Tracktor container: +1. Stop and remove the container: ```bash -docker stop tracktor-app +docker stop tracktor-app && docker rm tracktor-app ``` -2. Remove the existing Tracktor container: - -```bash -docker rm tracktor-app -``` - -3. Pull the latest Tracktor image from GitHub Container Registry: +2. Pull the latest image: ```bash docker pull ghcr.io/javedh-dev/tracktor:latest ``` -4. Re-run the Tracktor container with the same configurations as before: +3. Restart the container with the same configuration as before: ```bash docker run -d \ @@ -150,73 +149,70 @@ docker run -d \ ghcr.io/javedh-dev/tracktor:latest ``` -5. Access the application by navigating to `http://:3333` in your web browser. - -### Uninstalling Tracktor - -To uninstall Tracktor and remove all associated data, follow these steps: +### Uninstalling -1. Stop the running Tracktor container: +1. Stop and remove the container: ```bash -docker stop tracktor-app +docker stop tracktor-app && docker rm tracktor-app ``` -2. Remove the Tracktor container: +2. Remove the data volume: ```bash -docker rm tracktor-app +docker volume rm tracktor-data ``` -3. Remove the Docker volume that contains Tracktor data: +## Proxmox LXC -```bash -docker volume rm tracktor-data -``` +For Proxmox LXC container setup, use [Community-Scripts](https://community-scripts.github.io/ProxmoxVE/scripts?id=tracktor) for a streamlined installation process. -## Proxmox LXC Setup +## Local Development -To set up Tracktor in a Proxmox LXC container, Please use [Community-Scripts](https://community-scripts.github.io/ProxmoxVE/scripts?id=tracktor) by following the instructions provided there for a streamlined installation process. +### Prerequisites -## Local Development Setup +- Node.js (v18 or higher) +- pnpm package manager -To set up Tracktor for local development, follow these steps: +### Steps -1. Ensure you have Node.js and pnpm installed on your system. -2. Clone the Tracktor repository from GitHub: +1. Clone the repository: ```bash git clone https://github.com/javedh-dev/tracktor.git cd tracktor ``` -3. Install the required dependencies: +2. Install dependencies: ```bash pnpm install ``` -4. Update the environment variables as needed in the `.env` file in root directory. +3. Configure environment variables in the `.env` file (refer to [environment.md](./environment.md)). -5. Migrate the database: +4. Run database migrations: ```bash -pnpm run db:migrate:dev +pnpm run db:migrate ``` -6. Start the development server: +5. Start the development server: ```bash pnpm run dev ``` -7. Access the application by navigating to `http://localhost:5173` in your web browser. - The app is now running in development mode. Both frontend and backend will automatically reload upon code changes. Frontend runs on port 5173 and backend on port 3000 by default. +6. Access the application at `http://localhost:5173`. + +The development server runs on port 5173 with hot module reloading enabled. -## Additional Configuration +## Configuration -For more configuration options and environment variables, please refer to the official documentation. +For environment variables and configuration options, refer to the [environment documentation](./environment.md). ## Troubleshooting -If you encounter any issues during installation or setup, please check the logs of the Docker container or the terminal output for error messages. You can also refer to the GitHub repository for known issues and solutions. +- Check Docker container logs: `docker logs tracktor-app` +- For local development, check terminal output for error messages +- Review the [GitHub repository](https://github.com/javedh-dev/tracktor) for known issues and solutions diff --git a/messages/de.json b/messages/de.json new file mode 100644 index 00000000..849e0126 --- /dev/null +++ b/messages/de.json @@ -0,0 +1,440 @@ +{ + "$schema": "https://inlang.com/schema/inlang-message-format", + "hello_world": "Hallo, {name} aus de!", + "app_title": "Deine Garage", + "app_add_vehicle": "Fahrzeug hinzufügen", + "app_empty_select_message": "Wähle ein Fahrzeug aus, um Details anzuzeigen", + "app_empty_select_hint": "Wähle oben im Garagenbereich ein Fahrzeug, um sein Dashboard zu laden.", + "demo_banner": "Dies ist eine Demo-Instanz. Daten werden regelmäßig zurückgesetzt und nicht dauerhaft gespeichert. Bitte füge keine persönlichen Informationen hinzu.", + "default_login": "Standardanmeldung: demo / demo", + "settings_tab_personalization": "Personalisierung", + "settings_tab_interface": "Oberfläche", + "settings_tab_features": "Funktionen", + "settings_label_date_format": "Datumsformat", + "settings_label_locale": "Sprache", + "settings_label_timezone": "Zeitzone", + "settings_label_currency": "Währung", + "settings_label_unit_distance": "Entfernungseinheit", + "settings_label_unit_volume": "Volumeneinheit", + "settings_label_theme": "Design", + "settings_label_custom_css": "Benutzerdefiniertes CSS", + "settings_update_button": "Einstellungen aktualisieren", + "settings_select_unit_system": "Einheitensystem auswählen", + "settings_select_theme": "Design auswählen", + "settings_desc_date_format": "Bevorzugtes Datumsformat wählen", + "settings_desc_locale": "Sprache der Oberfläche wählen", + "settings_desc_timezone": "Zeitzone für Datumsanzeige wählen", + "settings_desc_currency": "Bevorzugte Währung wählen", + "settings_desc_unit_distance": "Maßeinheit für Entfernung", + "settings_desc_unit_volume": "Maßeinheit für Volumen", + "settings_desc_theme": "Bevorzugtes Design wählen", + "settings_desc_custom_css": "CSS-Stile zur Anpassung der Oberfläche", + "settings_select_language": "Sprache auswählen", + "settings_updated_success": "Konfiguration erfolgreich aktualisiert!", + "common_example_prefix": "Beispiel - ", + "common_invalid_format": "Ungültiges Format...", + "common_kilometer": "Kilometer", + "common_mile": "Meilen", + "common_litre": "Liter", + "common_gallon": "Gallone", + "common_submit": "Senden", + "common_yes": "Ja", + "common_no": "Nein", + "common_cancel": "Abbrechen", + "common_continue": "Weiter", + "common_skip": "Überspringen", + "delete_dialog_title": "Löschen", + "delete_dialog_message": "Bist du sicher, dass du löschen möchtest?", + "common_select_column": "Spalte auswählen", + "common_import": "Importieren", + "nav_overview": "Übersicht", + "nav_fuel_logs": "Kraftstoffprotokolle", + "nav_maintenance": "Wartung", + "nav_insurance": "Versicherung", + "nav_pollution": "Abgaszertifikat", + "nav_reminders": "Erinnerungen", + "tools_export_data": "Daten exportieren", + "tools_import_data": "Daten importieren", + "vehicle_form_make_label": "Marke", + "vehicle_form_make_desc": "Hersteller des Fahrzeugs", + "vehicle_form_model_label": "Modell", + "vehicle_form_model_desc": "Modell des Fahrzeugs", + "vehicle_form_year_label": "Baujahr", + "vehicle_form_year_desc": "Baujahr", + "vehicle_form_color_label": "Farbe", + "vehicle_form_color_desc": "Farbe des Fahrzeugs", + "vehicle_form_fuel_type_label": "Kraftstoffart", + "vehicle_form_fuel_type_desc": "Art des im Fahrzeug verwendeten Kraftstoffs", + "vehicle_form_fuel_type_placeholder": "Kraftstoffart auswählen", + "vehicle_form_odometer_label": "Kilometerstand", + "vehicle_form_odometer_desc": "Aktueller Kilometerstand", + "vehicle_form_license_label": "Kennzeichen", + "vehicle_form_license_desc": "Amtliches Kennzeichen des Fahrzeugs", + "vehicle_form_vin_label": "FIN", + "vehicle_form_vin_desc": "Fahrzeug-Identifikationsnummer", + "vehicle_toast_saved": "Fahrzeug erfolgreich gespeichert", + "vehicle_toast_updated": "Fahrzeug erfolgreich aktualisiert", + "vehicle_toast_error_prefix": "Fehler beim Speichern: ", + "vehicle_list_empty": "Hier ist es leer. Fügen Sie Ihr erstes Fahrzeug hinzu, um zu starten.", + "vehicle_delete_success": "Fahrzeug erfolgreich gelöscht.", + "vehicle_delete_error": "Beim Löschen des Fahrzeugs ist ein Fehler aufgetreten.", + "vehicle_action_add_fuel_log": "Tankvorgang hinzufügen", + "vehicle_action_add_maintenance_log": "Wartungseintrag hinzufügen", + "vehicle_action_add_insurance": "Versicherung hinzufügen", + "vehicle_action_add_pollution": "Abgaszertifikat hinzufügen", + "vehicle_action_add_reminder": "Erinnerung hinzufügen", + "vehicle_action_more_info": "Mehr Infos", + "vehicle_action_update_vehicle": "Fahrzeug aktualisieren", + "vehicle_action_edit": "Bearbeiten", + "vehicle_action_delete": "Löschen", + "tools_export_encrypt_label": "Exportdaten verschlüsseln", + "tools_export_password_label": "Verschlüsselungspasswort", + "tools_export_password_placeholder": "Passwort zum Verschlüsseln eingeben", + "tools_export_password_hint": "Passwort sicher aufbewahren – es wird zum Entschlüsseln beim Import benötigt.", + "tools_export_status_exporting": "Exportiere...", + "tools_export_button": "Datenbank exportieren", + "tools_export_info_title": "Export-Informationen", + "tools_export_info_bullet_1": "Exportiert alle Datenbanktabellen und Daten", + "tools_export_info_bullet_2": "Beinhaltet Fahrzeuge, Tankbelege, Wartungen usw.", + "tools_export_info_bullet_3": "Optionale Verschlüsselung zum Schutz sensibler Daten", + "tools_export_info_bullet_4": "Download als JSON-Datei", + "tools_export_success": "Daten erfolgreich exportiert", + "tools_export_error": "Daten konnten nicht exportiert werden", + "tools_import_upload_label": "JSON-Datei hochladen", + "tools_import_paste_label": "Oder JSON-Daten einfügen", + "tools_import_paste_placeholder": "Füge hier deine exportierten JSON-Daten ein...", + "tools_import_password_label": "Entschlüsselungspasswort (falls verschlüsselt)", + "tools_import_password_placeholder": "Passwort eingeben, wenn die Daten verschlüsselt sind", + "tools_import_status_importing": "Importiere...", + "tools_import_button": "Datenbank importieren", + "tools_import_warning_title": "⚠️ Import-Warnung", + "tools_import_warning_bullet_1": "Dies ersetzt ALLE bestehenden Daten", + "tools_import_warning_bullet_2": "Sichere die aktuellen Daten zuerst", + "tools_import_warning_bullet_3": "Import kann nicht rückgängig gemacht werden", + "tools_import_warning_bullet_4": "Stelle sicher, dass das JSON-Format korrekt ist", + "tools_import_success": "Daten erfolgreich importiert", + "tools_import_error": "Daten konnten nicht importiert werden", + "tools_import_invalid_json": "Ungültiges JSON-Format", + "feature_overview_disabled_title": "Übersicht-Funktion deaktiviert", + "feature_overview_disabled_hint": "Aktivieren Sie diese Funktion in den Einstellungen, um das Übersichts-Dashboard zu sehen", + "feature_fuel_disabled_title": "Kraftstoff-Funktion deaktiviert", + "feature_fuel_disabled_hint": "Aktivieren Sie diese Funktion in den Einstellungen, um den Verbrauch zu verfolgen", + "feature_maintenance_disabled_title": "Wartungs-Funktion deaktiviert", + "feature_maintenance_disabled_hint": "Aktivieren Sie diese Funktion, um Wartungen zu verwalten", + "feature_pucc_disabled_title": "PUCC-Funktion deaktiviert", + "feature_pucc_disabled_hint": "Aktivieren Sie diese Funktion, um Verschmutzungszertifikate zu verwalten", + "feature_reminders_disabled_title": "Erinnerungen-Funktion deaktiviert", + "feature_reminders_disabled_hint": "Aktivieren Sie diese Funktion, um Fahrzeugerinnerungen zu verwalten", + "feature_insurance_disabled_title": "Versicherungs-Funktion deaktiviert", + "feature_insurance_disabled_hint": "Aktivieren Sie diese Funktion, um Versicherungsdetails zu verwalten", + "overview_chart_no_data": "Keine Daten verfügbar", + "overview_chart_cost_label": "Kosten", + "overview_chart_cost_title": "Kosten über die Zeit ({currency})", + "overview_chart_mileage_label": "Verbrauch", + "overview_chart_mileage_title": "Verbrauch über die Zeit ({unit})", + "fuel_import_title": "Kraftstoffprotokolle importieren", + "fuel_add_title": "Kraftstoffprotokoll hinzufügen", + "col_date": "Datum", + "col_odometer": "Kilometerzähler", + "col_filled": "Gefüllt", + "col_missed_last": "Zuletzt verpasst", + "col_fuel_amount": "Kraftstoffmenge", + "col_cost": "Kosten", + "col_mileage": "Verbrauch", + "col_notes": "Notizen", + "col_attachment": "Anhang", + "col_no_end_date": "Kein Enddatum", + "fuel_volume_label_fuel": "Kraftstoffmenge", + "fuel_volume_label_energy": "Energie", + "fuel_empty_list": "Keine Kraftstoffprotokolle für dieses Fahrzeug gefunden.", + "form_date": "Datum", + "form_date_desc": "Datum der Betankung", + "form_odometer": "Kilometerzähler", + "form_odometer_desc": "Aktueller Kilometerzählerstand", + "form_volume_fuel": "Kraftstoffvolumen", + "form_volume_energy": "Verbrauchte Energie", + "form_cost": "Kosten", + "form_cost_desc": "Kosten der Betankung", + "form_cost_desc_ev": "Kosten des Ladens", + "form_full_charge": "Vollladung", + "form_full_tank": "Voller Tank", + "form_full_charge_desc": "Ist die Batterie vollständig geladen?", + "form_full_tank_desc": "Ist der Tank vollständig gefüllt?", + "form_missed_last": "Zuletzt verpasst", + "form_missed_last_desc": "Wurden letzte Einträge verpasst?", + "form_notes": "Notizen", + "form_notes_placeholder": "Weitere Details hinzufügen, falls vorhanden...", + "form_attachment": "Anhang", + "fuel_toast_saved": "Kraftstoffprotokoll erfolgreich gespeichert...!!!", + "fuel_toast_updated": "Kraftstoffprotokoll erfolgreich aktualisiert...!!!", + "fuel_toast_error_prefix": "Fehler beim Speichern: ", + "notifications_title": "Benachrichtigungen", + "notifications_new": "neu", + "notifications_select_vehicle_hint": "Wähle ein Fahrzeug, um Erinnerungen und Alarme zu laden.", + "notifications_syncing": "Aktualisiere neueste Daten...", + "notifications_caught_up": "Du bist auf dem neuesten Stand.", + "notifications_section_reminders": "Erinnerungen", + "notifications_section_alerts": "Compliance-Warnungen", + "notifications_mark_done_title": "Erinnerung als erledigt markieren", + "notifications_mark_done_aria": "{type}-Erinnerung als erledigt markieren", + "notifications_overdue_days": "{days} Tag{plural} überfällig", + "notifications_due_today": "Heute fällig", + "notifications_due_tomorrow": "Morgen fällig", + "notifications_due_in_days": "Fällig in {days} Tagen", + "alerts_status_expired": "Abgelaufen", + "alerts_status_expiring": "Läuft bald ab", + "alerts_status_valid": "Gültig", + "alerts_status_missing": "Fehlt", + "notifications_expires": "Gültig bis", + "notifications_error_no_id": "Ohne ID kann nicht aktualisiert werden.", + "notifications_error_update_failed": "Aktualisierung der Erinnerung fehlgeschlagen.", + "notifications_success_marked_done": "Erinnerung als erledigt markiert.", + "notifications_severity_overdue": "Überfällig", + "notifications_severity_due_soon": "Bald fällig", + "notifications_severity_upcoming": "Bevorstehend", + "settings_custom_css_placeholder": "Füge hier dein benutzerdefiniertes CSS hinzu...", + "settings_features_intro": "Aktiviere oder deaktiviere Funktionen zur Anpassung deiner Erfahrung", + "feature_label_fuel": "Kraftstoffprotokoll", + "feature_desc_fuel": "Verbrauch und Betankungen verwalten und nachverfolgen", + "feature_label_maintenance": "Wartung", + "feature_desc_maintenance": "Wartungsaktivitäten erfassen und planen", + "feature_label_pucc": "Verschmutzung", + "feature_desc_pucc": "PUCC-Zertifikate verwalten", + "feature_label_reminders": "Erinnerungen", + "feature_desc_reminders": "Erinnerungen für wichtige Ereignisse setzen und erhalten", + "feature_label_insurance": "Versicherung", + "feature_desc_insurance": "Versicherungsdetails und -verlängerungen verwalten", + "feature_label_overview": "Übersicht", + "feature_desc_overview": "Übersichts-Dashboard mit wichtigen Fahrzeugkennzahlen anzeigen", + "settings_error_date_format_invalid": "Format ungültig", + "settings_error_timezone_invalid": "Ungültiger Zeitzonenwert.", + "settings_error_currency_required": "Währung ist erforderlich", + "maintenance_form_attachment_label": "Anhang", + "maintenance_form_attachment_desc": "Beleg oder Wartungsdokument hochladen", + "maintenance_form_date_label": "Datum", + "maintenance_form_date_desc": "Wartungsdatum", + "maintenance_form_odometer_label": "Kilometerstand", + "maintenance_form_odometer_desc": "Aktueller Kilometerstand", + "maintenance_form_service_center_label": "Werkstatt", + "maintenance_form_service_center_desc": "Name der Werkstatt", + "maintenance_form_cost_label": "Kosten", + "maintenance_form_cost_desc": "Wartungskosten", + "maintenance_form_notes_label": "Notizen", + "maintenance_form_notes_desc": "Weitere Details", + "maintenance_form_notes_placeholder": "Fügen Sie bei Bedarf weitere Details hinzu...", + "maintenance_toast_saved": "Wartungseintrag erfolgreich gespeichert", + "maintenance_toast_updated": "Wartungseintrag erfolgreich aktualisiert", + "maintenance_toast_error_prefix": "Fehler beim Speichern: ", + "maintenance_form_error_fix": "Bitte beheben Sie die Fehler im Formular, bevor Sie absenden.", + "maintenance_list_empty": "Keine Wartungseinträge für dieses Fahrzeug gefunden.", + "maintenance_col_service_center": "Werkstatt", + "maintenance_menu_open": "Menü öffnen", + "maintenance_menu_edit": "Bearbeiten", + "maintenance_menu_delete": "Löschen", + "maintenance_menu_sheet_title": "Wartungseintrag aktualisieren", + "maintenance_tab_title": "Wartungshistorie", + "maintenance_add_action": "Wartungseintrag hinzufügen", + "maintenance_delete_success": "Wartungseintrag gelöscht.", + "maintenance_delete_error": "Beim Löschen des Wartungseintrags ist ein Fehler aufgetreten.", + "insurance_form_provider_label": "Versicherungsanbieter", + "insurance_form_provider_desc": "Name der Versicherungsgesellschaft", + "insurance_form_policy_number_label": "Versicherungspolice-Nummer", + "insurance_form_policy_number_desc": "Policennummer aus dem Versicherungsdokument", + "insurance_form_start_date_label": "Versicherungsstartdatum", + "insurance_form_start_date_desc": "Datum, ab dem der Versicherungsschutz beginnt", + "insurance_form_recurrence_type_label": "Wie sollte sich diese Versicherung erneuern?", + "insurance_form_recurrence_type_desc": "Erneuerungstyp für diese Versicherung", + "insurance_form_recurrence_interval_label": "Erneuerungshäufigkeit", + "insurance_form_recurrence_interval_desc": "Wie oft die Versicherung sich erneuert", + "insurance_form_end_date_label": "Versicherungsendatum", + "insurance_form_end_date_desc": "Datum, an dem der Versicherungsschutz endet", + "insurance_form_cost_label": "Versicherungskosten", + "insurance_form_cost_desc": "Jährliche oder Policenperioden-Kosten", + "insurance_form_notes_label": "Zusätzliche Notizen", + "insurance_form_notes_desc": "Weitere Informationen zur Police", + "insurance_form_notes_placeholder": "Weitere Details zur Versicherung hinzufügen...", + "insurance_form_attachment_label": "Versicherungsdokument", + "insurance_form_attachment_desc": "Versicherungsdokument hochladen", + "insurance_form_error_fix": "Bitte beheben Sie die Fehler im Formular, bevor Sie absenden.", + "insurance_toast_saved": "Versicherung erfolgreich gespeichert", + "insurance_toast_updated": "Versicherung erfolgreich aktualisiert", + "insurance_toast_error_prefix": "Fehler beim Speichern: ", + "insurance_list_empty": "Keine Versicherung für dieses Fahrzeug gefunden.", + "insurance_col_policy_number": "Policennummer", + "insurance_col_cost": "Kosten", + "insurance_col_start_date": "Startdatum", + "insurance_col_end_date": "Enddatum", + "insurance_col_next_due": "Nächstes Fälligkeitsdatum", + "insurance_col_recurrence": "Erneuerung", + "insurance_col_notes": "Notizen", + "insurance_col_view_document": "Dokument anzeigen", + "insurance_menu_open": "Menü öffnen", + "insurance_menu_edit": "Bearbeiten", + "insurance_menu_delete": "Löschen", + "insurance_menu_sheet_title": "Versicherung aktualisieren", + "insurance_tab_title": "Versicherungsdetails", + "insurance_add_action": "Versicherung hinzufügen", + "insurance_delete_success": "Versicherung gelöscht.", + "insurance_delete_error": "Beim Löschen der Versicherung ist ein Fehler aufgetreten.", + "pollution_form_certificate_number_label": "Zertifikatnummer", + "pollution_form_certificate_number_desc": "Abgasprüfzertifikat-Nummer", + "pollution_form_issue_date_label": "Ausstellungsdatum", + "pollution_form_issue_date_desc": "Ausstellungsdatum des Zertifikats", + "pollution_form_recurrence_type_label": "Wie sollte sich dieses Zertifikat erneuern?", + "pollution_form_recurrence_type_desc": "Erneuerungstyp für dieses Zertifikat", + "pollution_form_recurrence_interval_label": "Erneuerungshäufigkeit", + "pollution_form_recurrence_interval_desc": "Wie oft sich das Zertifikat erneuert", + "pollution_form_expiry_date_label": "Ablaufdatum", + "pollution_form_expiry_date_desc": "PUCC-Ablaufdatum", + "pollution_form_testing_center_label": "Prüfzentrum", + "pollution_form_testing_center_desc": "Name des Prüfzentrums", + "pollution_form_notes_label": "Zusätzliche Notizen", + "pollution_form_notes_desc": "Weitere Informationen", + "pollution_form_notes_placeholder": "Weitere Notizen hinzufügen...", + "pollution_form_attachment_label": "Zertifikatdokument", + "pollution_form_attachment_desc": "Zertifikatdokument hochladen", + "pollution_form_error_fix": "Bitte beheben Sie die Fehler im Formular, bevor Sie absenden.", + "pollution_toast_saved": "Abgasprüfzertifikat erfolgreich gespeichert", + "pollution_toast_updated": "Abgasprüfzertifikat erfolgreich aktualisiert", + "pollution_toast_error_prefix": "Fehler beim Speichern: ", + "pollution_list_empty": "Keine Abgasprüfzertifikate für dieses Fahrzeug gefunden.", + "pollution_col_certificate_number": "Zertifikatnummer", + "pollution_col_issue_date": "Ausstellungsdatum", + "pollution_col_expiry_date": "Ablaufdatum", + "pollution_col_next_due": "Nächstes Fälligkeitsdatum", + "pollution_col_testing_center": "Prüfzentrum", + "pollution_col_notes": "Notizen", + "pollution_col_view_certificate": "Zertifikat anzeigen", + "pollution_col_recurrence": "Erneuerung", + "pollution_menu_open": "Menü öffnen", + "pollution_menu_edit": "Bearbeiten", + "pollution_menu_delete": "Löschen", + "pollution_menu_sheet_title": "Abgasprüfzertifikat aktualisieren", + "pollution_tab_title": "Abgasprüfzertifikat-Details", + "pollution_add_action": "Abgasprüfzertifikat hinzufügen", + "pollution_delete_success": "PUCC gelöscht.", + "pollution_delete_error": "Beim Löschen des PUCC ist ein Fehler aufgetreten.", + "reminder_form_due_date_label": "Fälligkeitsdatum", + "reminder_form_due_date_desc": "Wann sollte diese Erinnerung ausgelöst werden?", + "reminder_form_type_label": "Typ", + "reminder_form_type_desc": "Erinnerungstyp wählen", + "reminder_form_schedule_label": "Erinnerungsplan", + "reminder_form_schedule_desc": "Wann sollten wir Sie erinnern?", + "reminder_form_recurrence_type_label": "Wiederholung", + "reminder_form_recurrence_type_desc": "Sollte sich diese Erinnerung wiederholen?", + "reminder_form_recurrence_interval_label": "Alle wiederholen", + "reminder_form_recurrence_interval_desc": "Häufigkeit der Wiederholung", + "reminder_form_recurrence_end_date_label": "Enddatum", + "reminder_form_recurrence_end_date_desc": "Wann sollte die Wiederholung beendet werden? (optional)", + "reminder_form_note_label": "Notiz", + "reminder_form_note_desc": "Fügen Sie mehr Kontext hinzu", + "reminder_form_note_placeholder": "Details, die Aufmerksamkeit benötigen", + "reminder_form_is_completed_label": "Als erledigt markieren", + "reminder_toast_created": "Erinnerung erfolgreich erstellt.", + "reminder_toast_updated": "Erinnerung erfolgreich aktualisiert", + "reminder_toast_error_prefix": "Fehler beim Speichern: ", + "reminder_list_empty": "Noch keine Erinnerungen. Erstellen Sie eine, um bevorstehenden Verlängerungen voraus zu sein.", + "reminder_list_select_vehicle": "Wählen Sie ein Fahrzeug, um Erinnerungen zu sehen.", + "reminder_list_select_hint": "Wählen Sie oben ein Fahrzeug aus, um bevorstehende Erinnerungen zu laden.", + "reminder_col_due_date": "Fälligkeitsdatum", + "reminder_col_reminder_schedule": "Erinnerungsplan", + "reminder_col_recurrence": "Wiederholung", + "reminder_col_note": "Notizen", + "reminder_menu_toggle_done": "Als {status} markieren", + "reminder_menu_toggle_done_done": "Als ausstehend markieren", + "reminder_menu_toggle_done_pending": "Als erledigt markieren", + "reminder_menu_edit": "Bearbeiten", + "reminder_menu_delete": "Löschen", + "reminder_menu_open": "Menü öffnen", + "reminder_menu_sheet_title": "Erinnerung aktualisieren", + "reminder_tab_title": "Erinnerungen", + "reminder_add_action": "Erinnerung hinzufügen", + "reminder_delete_success": "Erinnerung gelöscht.", + "reminder_delete_error": "Beim Löschen der Erinnerung ist ein Fehler aufgetreten.", + "reminder_status_error": "Fehler beim Aktualisieren des Erinnerungsstatus.", + "reminder_toast_error_fallback": "Fehler beim Speichern der Erinnerung.", + "reminder_status_completed": "Abgeschlossen", + "reminder_status_pending": "Ausstehend", + "reminder_status_overdue": "Überfällig", + "settings_sheet_title": "Einstellungen", + "settings_features_intro": "Aktivieren oder deaktivieren Sie Funktionen, um Ihr Erlebnis anzupassen", + "feature_label_fuel": "Tankbuch", + "feature_desc_fuel": "Überwachung und Verwaltung des Kraftstoffverbrauchs und der Betankungshistorie", + "feature_label_maintenance": "Wartung", + "feature_desc_maintenance": "Verzeichnis und Planung von Fahrzeugwartungsaktivitäten", + "feature_label_pollution": "Schadstoffkontrolle", + "feature_desc_pollution": "Verwaltung von Registern für Schadstoffkontrollzertifikate", + "feature_label_reminders": "Erinnerungen", + "feature_desc_reminders": "Legen Sie Erinnerungen für wichtige Fahrzeugereignisse fest und erhalten Sie diese", + "feature_label_insurance": "Versicherung", + "feature_desc_insurance": "Verwaltung von Fahrzeugversicherungsdetails und -erneuerungen", + "feature_label_overview": "Überblick", + "feature_desc_overview": "Zeigen Sie das Überblicks-Dashboard mit wichtigen Fahrzeugmetriken an", + "profile_menu_item": "Profil", + "profile_sheet_title": "Profil", + "profile_sheet_desc": "Aktualisieren Sie Ihren Benutzernamen und Ihr Passwort", + "profile_username": "Benutzername", + "profile_username_desc": "Ihr Anzeigename", + "profile_password_hint": "Lassen Sie die Passwortfelder leer, um Ihr aktuelles Passwort zu behalten", + "profile_current_password": "Aktuelles Passwort", + "profile_current_password_desc": "Erforderlich zum Ändern des Passworts", + "profile_new_password": "Neues Passwort", + "profile_new_password_desc": "Mindestens 6 Zeichen", + "profile_confirm_password": "Passwort bestätigen", + "profile_confirm_password_desc": "Geben Sie Ihr neues Passwort erneut ein", + "profile_update_button": "Profil aktualisieren", + "tools_menu": "Werkzeuge", + "data_export_import_menu_item": "Daten exportieren/importieren", + "data_export_import_sheet_title": "Datenexport/-import", + "data_export_import_sheet_desc": "Exportieren oder importieren Sie Ihre Datenbank mit optionaler Verschlüsselung", + "logout_menu_item": "Abmelden", + "nav_overview": "Überblick", + "nav_fuel_logs": "Tankbuch", + "nav_maintenance": "Wartung", + "nav_insurance": "Versicherung", + "nav_pollution": "Schadstoffkontrolle", + "nav_reminders": "Erinnerungen", + "custom_fields_label": "Benutzerdefinierte Felder", + "custom_fields_add_button": "Feld hinzufügen", + "custom_fields_name_placeholder": "Feldname", + "custom_fields_value_placeholder": "Feldwert", + "custom_fields_remove_aria": "Feld entfernen", + "custom_fields_empty_message": "Keine benutzerdefinierten Felder hinzugefügt. Klicken Sie auf \"Feld hinzufügen\", um zu beginnen.", + "vehicle_details_vin": "FIN", + "vehicle_details_not_specified": "Nicht angegeben", + "vehicle_details_section_title": "Details", + "vehicle_details_license_plate": "Kennzeichen", + "vehicle_details_fuel_type": "Kraftstoffart", + "vehicle_details_odometer": "Kilometerstand", + "vehicle_details_not_recorded": "Nicht erfasst", + "vehicle_details_color": "Farbe", + "vehicle_details_year": "Jahr", + "fuel_type_diesel": "Diesel", + "fuel_type_petrol": "Benzin", + "fuel_type_ev": "Elektrisch (EV)", + "reminder_schedule_same_day": "Am Fälligkeitsdatum", + "reminder_schedule_one_day_before": "1 Tag vorher", + "reminder_schedule_three_days_before": "3 Tage vorher", + "reminder_schedule_one_week_before": "1 Woche vorher", + "reminder_schedule_one_month_before": "1 Monat vorher", + "recurrence_type_none": "Keine Wiederholung", + "recurrence_type_daily": "Täglich", + "recurrence_type_weekly": "Wöchentlich", + "recurrence_type_monthly": "Monatlich", + "recurrence_type_yearly": "Jährlich", + "recurrence_every": "alle", + "recurrence_renew_every": "Erneuern alle", + "recurrence_interval_days": "Tage", + "recurrence_interval_weeks": "Wochen", + "recurrence_interval_months": "Monate", + "recurrence_interval_years": "Jahre", + "recurrence_until": "Bis", + "insurance_recurrence_type_fixed": "Festes Enddatum", + "insurance_recurrence_type_yearly": "Verlängert sich jährlich", + "insurance_recurrence_type_monthly": "Verlängert sich monatlich", + "insurance_recurrence_type_no_end": "Kein Enddatum", + "pollution_recurrence_type_fixed": "Festes Enddatum", + "pollution_recurrence_type_yearly": "Verlängert sich jährlich", + "pollution_recurrence_type_monthly": "Verlängert sich monatlich", + "pollution_recurrence_type_no_end": "Kein Enddatum" +} diff --git a/messages/en.json b/messages/en.json new file mode 100644 index 00000000..4dfab53e --- /dev/null +++ b/messages/en.json @@ -0,0 +1,441 @@ +{ + "$schema": "https://inlang.com/schema/inlang-message-format", + "hello_world": "Hello, {name} from en!", + "app_title": "Your Garage", + "app_add_vehicle": "Add Vehicle", + "app_empty_select_message": "Select a vehicle to view its details", + "app_empty_select_hint": "Choose one from the garage above to load its dashboard.", + "demo_banner": "This is a demo instance. Data will be reset periodically and is not saved permanently. Please avoid adding any personal info.", + "default_login": "Default Login: demo / demo", + "settings_tab_personalization": "Personalization", + "settings_tab_interface": "Interface", + "settings_tab_features": "Features", + "settings_label_date_format": "Date Format", + "settings_label_locale": "Locale", + "settings_label_timezone": "Timezone", + "settings_label_currency": "Currency", + "settings_label_unit_distance": "Unit of Distance", + "settings_label_unit_volume": "Unit of Volume", + "settings_label_theme": "Theme", + "settings_label_custom_css": "Custom CSS", + "settings_update_button": "Update Settings", + "settings_select_unit_system": "Select unit system", + "settings_select_theme": "Select theme", + "settings_desc_date_format": "Choose your preferred date format", + "settings_desc_locale": "Choose the language for the interface", + "settings_desc_timezone": "Choose your timezone for date display", + "settings_desc_currency": "Choose your preferred currency", + "settings_desc_unit_distance": "Measurement of distance unit", + "settings_desc_unit_volume": "Measurement of volume unit", + "settings_desc_theme": "Choose your preferred theme", + "settings_desc_custom_css": "CSS Styles for customizing the interface", + "settings_select_language": "Select language", + "settings_updated_success": "Configuration updated successfully!", + "common_example_prefix": "Example - ", + "common_invalid_format": "Invalid Format...", + "common_kilometer": "Kilometer", + "common_mile": "Miles", + "common_litre": "Litre", + "common_gallon": "Gallon", + "common_submit": "Submit", + "common_yes": "Yes", + "common_no": "No", + "common_cancel": "Cancel", + "common_confirm": "Confirm", + "common_continue": "Continue", + "common_skip": "Skip", + "delete_dialog_title": "Delete", + "delete_dialog_message": "Are you sure you want to delete?", + "common_select_column": "Select column", + "common_import": "Import", + "nav_overview": "Overview", + "nav_fuel_logs": "Fuel Logs", + "nav_maintenance": "Maintenance", + "nav_insurance": "Insurance", + "nav_pollution": "Pollution Certificate", + "nav_reminders": "Reminders", + "tools_export_data": "Export Data", + "tools_import_data": "Import Data", + "vehicle_form_make_label": "Make", + "vehicle_form_make_desc": "Manufacturer of the vehicle", + "vehicle_form_model_label": "Model", + "vehicle_form_model_desc": "Model of the vehicle", + "vehicle_form_year_label": "Year", + "vehicle_form_year_desc": "Year of manufacturing", + "vehicle_form_color_label": "Color", + "vehicle_form_color_desc": "Color of the vehicle", + "vehicle_form_fuel_type_label": "Fuel Type", + "vehicle_form_fuel_type_desc": "Type of fuel used by the vehicle", + "vehicle_form_fuel_type_placeholder": "Select fuel type", + "vehicle_form_odometer_label": "Odometer", + "vehicle_form_odometer_desc": "Current vehicle odometer reading", + "vehicle_form_license_label": "License Plate", + "vehicle_form_license_desc": "Registration number of vehicle", + "vehicle_form_vin_label": "VIN", + "vehicle_form_vin_desc": "Vehicle Identification Number", + "vehicle_toast_saved": "Vehicle saved successfully", + "vehicle_toast_updated": "Vehicle updated successfully", + "vehicle_toast_error_prefix": "Error while saving: ", + "vehicle_list_empty": "It's empty here. Please add your first vehicle to begin.", + "vehicle_delete_success": "Successfully deleted vehicle.", + "vehicle_delete_error": "Some error occurred while deleting vehicle.", + "vehicle_action_add_fuel_log": "Add Fuel Log", + "vehicle_action_add_maintenance_log": "Add Maintenance Log", + "vehicle_action_add_insurance": "Add Insurance", + "vehicle_action_add_pollution": "Add Pollution Certificate", + "vehicle_action_add_reminder": "Add Reminder", + "vehicle_action_more_info": "More info", + "vehicle_action_update_vehicle": "Update Vehicle", + "vehicle_action_edit": "Edit", + "vehicle_action_delete": "Delete", + "tools_export_encrypt_label": "Encrypt export data", + "tools_export_password_label": "Encryption Password", + "tools_export_password_placeholder": "Enter password for encryption", + "tools_export_password_hint": "Keep this password safe - you'll need it to decrypt the data during import.", + "tools_export_status_exporting": "Exporting...", + "tools_export_button": "Export Database", + "tools_export_info_title": "Export Information", + "tools_export_info_bullet_1": "Exports all database tables and data", + "tools_export_info_bullet_2": "Includes vehicles, fuel logs, maintenance records, etc.", + "tools_export_info_bullet_3": "Optional encryption for sensitive data protection", + "tools_export_info_bullet_4": "Downloads as JSON file", + "tools_export_success": "Data exported successfully", + "tools_export_error": "Failed to export data", + "tools_import_upload_label": "Upload JSON File", + "tools_import_paste_label": "Or Paste JSON Data", + "tools_import_paste_placeholder": "Paste your exported JSON data here...", + "tools_import_password_label": "Decryption Password (if encrypted)", + "tools_import_password_placeholder": "Enter password if data is encrypted", + "tools_import_status_importing": "Importing...", + "tools_import_button": "Import Database", + "tools_import_warning_title": "⚠️ Import Warning", + "tools_import_warning_bullet_1": "This will replace ALL existing data", + "tools_import_warning_bullet_2": "Make sure to backup current data first", + "tools_import_warning_bullet_3": "Import cannot be undone", + "tools_import_warning_bullet_4": "Verify the JSON format is correct", + "tools_import_success": "Data imported successfully", + "tools_import_error": "Failed to import data", + "tools_import_invalid_json": "Invalid JSON format", + "feature_overview_disabled_title": "Overview Feature Disabled", + "feature_overview_disabled_hint": "Enable this feature in Settings to view the overview dashboard", + "feature_fuel_disabled_title": "Fuel Log Feature Disabled", + "feature_fuel_disabled_hint": "Enable this feature in Settings to track fuel consumption", + "feature_maintenance_disabled_title": "Maintenance Feature Disabled", + "feature_maintenance_disabled_hint": "Enable this feature in Settings to manage maintenance records", + "feature_pucc_disabled_title": "PUCC Feature Disabled", + "feature_pucc_disabled_hint": "Enable this feature in Settings to manage pollution certificates", + "feature_reminders_disabled_title": "Reminders Feature Disabled", + "feature_reminders_disabled_hint": "Enable this feature in Settings to manage vehicle reminders", + "feature_insurance_disabled_title": "Insurance Feature Disabled", + "feature_insurance_disabled_hint": "Enable this feature in Settings to manage insurance details", + "overview_chart_no_data": "No data available", + "overview_chart_cost_label": "Cost", + "overview_chart_cost_title": "Cost over Time in ({currency})", + "overview_chart_mileage_label": "Mileage", + "overview_chart_mileage_title": "Mileage over Time in ({unit})", + "fuel_import_title": "Import Fuel Logs", + "fuel_add_title": "Add Fuel Log", + "col_date": "Date", + "col_odometer": "Odometer", + "col_filled": "Filled", + "col_missed_last": "Missed Last", + "col_fuel_amount": "Fuel Amount", + "col_cost": "Cost", + "col_mileage": "Mileage", + "col_notes": "Notes", + "col_attachment": "Attachment", + "col_no_end_date": "No end date", + "fuel_volume_label_fuel": "Fuel Amount", + "fuel_volume_label_energy": "Energy", + "fuel_empty_list": "No fuel refill logs found for this vehicle.", + "form_date": "Date", + "form_date_desc": "Date of fuel refill", + "form_odometer": "Odometer", + "form_odometer_desc": "Current vehicle odometer reading", + "form_volume_fuel": "Volume of fuel", + "form_volume_energy": "Energy consumed", + "form_cost": "Cost", + "form_cost_desc": "Cost of refill", + "form_cost_desc_ev": "Cost of charging", + "form_full_charge": "Full Charge", + "form_full_tank": "Full Tank", + "form_full_charge_desc": "Is battery fully charged?", + "form_full_tank_desc": "Is tank filled to top?", + "form_missed_last": "Missed Last", + "form_missed_last_desc": "Were any of last entries missed?", + "form_notes": "Notes", + "form_notes_placeholder": "Add more details. If any...", + "form_attachment": "Attachment", + "fuel_toast_saved": "FuelLog saved successfully...!!!", + "fuel_toast_updated": "FuelLog updated successfully...!!!", + "fuel_toast_error_prefix": "Error while saving : ", + "notifications_title": "Notifications", + "notifications_new": "new", + "notifications_select_vehicle_hint": "Select a vehicle to load reminders and alerts.", + "notifications_syncing": "Syncing latest data...", + "notifications_caught_up": "You're all caught up.", + "notifications_section_reminders": "Reminders", + "notifications_section_alerts": "Compliance Alerts", + "notifications_mark_done_title": "Mark reminder as done", + "notifications_mark_done_aria": "Mark {type} reminder as done", + "notifications_overdue_days": "{days} day{plural} overdue", + "notifications_due_today": "Due today", + "notifications_due_tomorrow": "Due tomorrow", + "notifications_due_in_days": "Due in {days} days", + "alerts_status_expired": "Expired", + "alerts_status_expiring": "Expiring", + "alerts_status_valid": "Healthy", + "alerts_status_missing": "Missing", + "notifications_expires": "Expires", + "notifications_error_no_id": "Unable to update reminder without an id.", + "notifications_error_update_failed": "Failed to update reminder.", + "notifications_success_marked_done": "Reminder marked as done.", + "notifications_severity_overdue": "Overdue", + "notifications_severity_due_soon": "Due Soon", + "notifications_severity_upcoming": "Upcoming", + "settings_custom_css_placeholder": "Add your custom CSS here...", + "settings_features_intro": "Enable or disable features to customize your experience", + "feature_label_fuel": "Fuel Log", + "feature_desc_fuel": "Track and manage fuel consumption and refueling history", + "feature_label_maintenance": "Maintenance", + "feature_desc_maintenance": "Record and schedule vehicle maintenance activities", + "feature_label_pucc": "Pollution", + "feature_desc_pucc": "Manage Pollution Under Control Certificate records", + "feature_label_reminders": "Reminders", + "feature_desc_reminders": "Set and receive reminders for important vehicle events", + "feature_label_insurance": "Insurance", + "feature_desc_insurance": "Manage vehicle insurance details and renewals", + "feature_label_overview": "Overview", + "feature_desc_overview": "Display overview dashboard with key vehicle metrics", + "settings_error_date_format_invalid": "Format not valid", + "settings_error_timezone_invalid": "Invalid timezone value.", + "settings_error_currency_required": "Currency is required", + "maintenance_form_attachment_label": "Attachment", + "maintenance_form_attachment_desc": "Upload receipt or maintenance document", + "maintenance_form_date_label": "Date", + "maintenance_form_date_desc": "Maintenance date", + "maintenance_form_odometer_label": "Odometer", + "maintenance_form_odometer_desc": "Current vehicle odometer reading", + "maintenance_form_service_center_label": "Service Center", + "maintenance_form_service_center_desc": "Name of service center", + "maintenance_form_cost_label": "Cost", + "maintenance_form_cost_desc": "Cost of maintenance", + "maintenance_form_notes_label": "Notes", + "maintenance_form_notes_desc": "More details", + "maintenance_form_notes_placeholder": "Add more details, if any...", + "maintenance_toast_saved": "Maintenance log saved successfully", + "maintenance_toast_updated": "Maintenance log updated successfully", + "maintenance_toast_error_prefix": "Error while saving: ", + "maintenance_form_error_fix": "Please fix the errors in the form before submitting.", + "maintenance_list_empty": "No maintenance logs found for this vehicle.", + "maintenance_col_service_center": "Service Center", + "maintenance_menu_open": "Open menu", + "maintenance_menu_edit": "Edit", + "maintenance_menu_delete": "Delete", + "maintenance_menu_sheet_title": "Update Maintenance Log", + "maintenance_tab_title": "Maintenance History", + "maintenance_add_action": "Add Maintenance Log", + "maintenance_delete_success": "Deleted maintenance log.", + "maintenance_delete_error": "Some error occurred while deleting maintenance log.", + "insurance_form_provider_label": "Insurance Provider", + "insurance_form_provider_desc": "Name of the insurance company", + "insurance_form_policy_number_label": "Insurance Policy Number", + "insurance_form_policy_number_desc": "Policy number from your insurance document", + "insurance_form_start_date_label": "Insurance Start Date", + "insurance_form_start_date_desc": "Date when coverage begins", + "insurance_form_recurrence_type_label": "How should this insurance renew?", + "insurance_form_recurrence_type_desc": "Renewal type for this insurance", + "insurance_form_recurrence_interval_label": "Renewal Frequency", + "insurance_form_recurrence_interval_desc": "How often the insurance renews", + "insurance_form_end_date_label": "Insurance End Date", + "insurance_form_end_date_desc": "Date when coverage expires", + "insurance_form_cost_label": "Insurance Cost", + "insurance_form_cost_desc": "Annual or policy period cost", + "insurance_form_notes_label": "Additional Notes", + "insurance_form_notes_desc": "Any extra information about the policy", + "insurance_form_notes_placeholder": "Add more details about the insurance...", + "insurance_form_attachment_label": "Policy Document", + "insurance_form_attachment_desc": "Upload policy document", + "insurance_form_error_fix": "Please fix the errors in the form before submitting.", + "insurance_toast_saved": "Insurance saved successfully", + "insurance_toast_updated": "Insurance updated successfully", + "insurance_toast_error_prefix": "Error while saving: ", + "insurance_list_empty": "No Insurance found for this vehicle.", + "insurance_col_policy_number": "Policy Number", + "insurance_col_cost": "Cost", + "insurance_col_start_date": "Start Date", + "insurance_col_end_date": "End Date", + "insurance_col_next_due": "Next Due", + "insurance_col_recurrence": "Recurrence", + "insurance_col_notes": "Notes", + "insurance_menu_open": "Open menu", + "insurance_menu_edit": "Edit", + "insurance_menu_delete": "Delete", + "insurance_menu_sheet_title": "Update Insurance", + "insurance_tab_title": "Insurance Details", + "insurance_add_action": "Add Insurance", + "insurance_delete_success": "Deleted Insurance.", + "insurance_delete_error": "Some error occurred while deleting insurance.", + "insurance_col_view_document": "View Document", + "pollution_form_certificate_number_label": "Certificate Number", + "pollution_form_certificate_number_desc": "Pollution certificate number", + "pollution_form_issue_date_label": "Issue Date", + "pollution_form_issue_date_desc": "Certificate issue date", + "pollution_form_recurrence_type_label": "How should this certificate renew?", + "pollution_form_recurrence_type_desc": "Renewal type for this certificate", + "pollution_form_recurrence_interval_label": "Renewal Frequency", + "pollution_form_recurrence_interval_desc": "How often the certificate renews", + "pollution_form_expiry_date_label": "Expiry Date", + "pollution_form_expiry_date_desc": "PUCC expiry date", + "pollution_form_testing_center_label": "Testing Center", + "pollution_form_testing_center_desc": "Testing center name", + "pollution_form_notes_label": "Additional Notes", + "pollution_form_notes_desc": "Any extra information", + "pollution_form_notes_placeholder": "Add additional notes...", + "pollution_form_attachment_label": "Certificate Document", + "pollution_form_attachment_desc": "Upload certificate document", + "pollution_form_error_fix": "Please fix the errors in the form before submitting.", + "pollution_toast_saved": "Pollution Certificate saved successfully", + "pollution_toast_updated": "Pollution Certificate updated successfully", + "pollution_toast_error_prefix": "Error while saving: ", + "pollution_list_empty": "No Pollution Certificates for this vehicle.", + "pollution_col_certificate_number": "Certificate Number", + "pollution_col_issue_date": "Issue Date", + "pollution_col_expiry_date": "Expiry Date", + "pollution_col_next_due": "Next Due", + "pollution_col_testing_center": "Testing Center", + "pollution_col_notes": "Notes", + "pollution_col_view_certificate": "View Certificate", + "pollution_col_recurrence": "Recurrence", + "pollution_menu_open": "Open menu", + "pollution_menu_edit": "Edit", + "pollution_menu_delete": "Delete", + "pollution_menu_sheet_title": "Update Pollution Certificate", + "pollution_tab_title": "Pollution Certificate Details", + "pollution_add_action": "Add Pollution Certificate", + "pollution_delete_success": "Deleted PUCC.", + "pollution_delete_error": "Some error occurred while deleting PUCC.", + "reminder_form_due_date_label": "Due Date", + "reminder_form_due_date_desc": "When should this reminder trigger?", + "reminder_form_type_label": "Type", + "reminder_form_type_desc": "Choose the reminder type", + "reminder_form_schedule_label": "Reminder Schedule", + "reminder_form_schedule_desc": "When should we remind you?", + "reminder_form_recurrence_type_label": "Recurrence", + "reminder_form_recurrence_type_desc": "Should this reminder repeat?", + "reminder_form_recurrence_interval_label": "Repeat Every", + "reminder_form_recurrence_interval_desc": "Frequency of recurrence", + "reminder_form_recurrence_end_date_label": "End Date", + "reminder_form_recurrence_end_date_desc": "When should recurrence stop? (optional)", + "reminder_form_note_label": "Note", + "reminder_form_note_desc": "Add more context", + "reminder_form_note_placeholder": "Detail what needs attention", + "reminder_form_is_completed_label": "Mark as done", + "reminder_toast_created": "Reminder created successfully.", + "reminder_toast_updated": "Reminder updated successfully", + "reminder_toast_error_prefix": "Error while saving: ", + "reminder_list_empty": "No reminders yet. Create one to stay ahead of upcoming renewals.", + "reminder_list_select_vehicle": "Select a vehicle to view reminders.", + "reminder_list_select_hint": "Pick a vehicle above to load its upcoming reminders.", + "reminder_col_due_date": "Due Date", + "reminder_col_reminder_schedule": "Reminder Schedule", + "reminder_col_recurrence": "Recurrence", + "reminder_col_note": "Notes", + "reminder_menu_toggle_done": "Mark as {status}", + "reminder_menu_toggle_done_done": "Mark as pending", + "reminder_menu_toggle_done_pending": "Mark as done", + "reminder_menu_edit": "Edit", + "reminder_menu_delete": "Delete", + "reminder_menu_open": "Open menu", + "reminder_menu_sheet_title": "Update Reminder", + "reminder_tab_title": "Reminders", + "reminder_add_action": "Add Reminder", + "reminder_delete_success": "Deleted reminder.", + "reminder_delete_error": "Some error occurred while deleting reminder.", + "reminder_status_completed": "Completed", + "reminder_status_pending": "Pending", + "reminder_status_overdue": "Overdue", + "reminder_status_error": "Unable to update reminder status.", + "reminder_toast_error_fallback": "Failed to save reminder.", + "settings_sheet_title": "Settings", + "settings_features_intro": "Enable or disable features to customize your experience", + "feature_label_fuel": "Fuel Log", + "feature_desc_fuel": "Track and manage fuel consumption and refueling history", + "feature_label_maintenance": "Maintenance", + "feature_desc_maintenance": "Record and schedule vehicle maintenance activities", + "feature_label_pollution": "Pollution", + "feature_desc_pollution": "Manage Pollution Under Control Certificate records", + "feature_label_reminders": "Reminders", + "feature_desc_reminders": "Set and receive reminders for important vehicle events", + "feature_label_insurance": "Insurance", + "feature_desc_insurance": "Manage vehicle insurance details and renewals", + "feature_label_overview": "Overview", + "feature_desc_overview": "Display overview dashboard with key vehicle metrics", + "profile_menu_item": "Profile", + "profile_sheet_title": "Profile", + "profile_sheet_desc": "Update your username and password", + "profile_username": "Username", + "profile_username_desc": "Your display name", + "profile_password_hint": "Leave password fields empty to keep your current password", + "profile_current_password": "Current Password", + "profile_current_password_desc": "Required to change password", + "profile_new_password": "New Password", + "profile_new_password_desc": "Minimum 6 characters", + "profile_confirm_password": "Confirm Password", + "profile_confirm_password_desc": "Re-enter your new password", + "profile_update_button": "Update Profile", + "tools_menu": "Tools", + "data_export_import_menu_item": "Export/Import Data", + "data_export_import_sheet_title": "Data Export/Import", + "data_export_import_sheet_desc": "Export or import your database with optional encryption", + "logout_menu_item": "Logout", + "nav_overview": "Overview", + "nav_fuel_logs": "Fuel Logs", + "nav_maintenance": "Maintenance", + "nav_insurance": "Insurance", + "nav_pollution": "Pollution", + "nav_reminders": "Reminders", + "custom_fields_label": "Custom Fields", + "custom_fields_add_button": "Add Field", + "custom_fields_name_placeholder": "Field name", + "custom_fields_value_placeholder": "Field value", + "custom_fields_remove_aria": "Remove field", + "custom_fields_empty_message": "No custom fields added. Click \"Add Field\" to get started.", + "vehicle_details_vin": "VIN", + "vehicle_details_not_specified": "Not specified", + "vehicle_details_section_title": "Details", + "vehicle_details_license_plate": "License Plate", + "vehicle_details_fuel_type": "Fuel Type", + "vehicle_details_odometer": "Odometer", + "vehicle_details_not_recorded": "Not recorded", + "vehicle_details_color": "Color", + "vehicle_details_year": "Year", + "fuel_type_diesel": "Diesel", + "fuel_type_petrol": "Petrol", + "fuel_type_ev": "Electric (EV)", + "reminder_schedule_same_day": "On due date", + "reminder_schedule_one_day_before": "1 day before", + "reminder_schedule_three_days_before": "3 days before", + "reminder_schedule_one_week_before": "1 week before", + "reminder_schedule_one_month_before": "1 month before", + "recurrence_type_none": "No recurrence", + "recurrence_type_daily": "Daily", + "recurrence_type_weekly": "Weekly", + "recurrence_type_monthly": "Monthly", + "recurrence_type_yearly": "Yearly", + "recurrence_every": "every", + "recurrence_renew_every": "Renew every", + "recurrence_interval_days": "days", + "recurrence_interval_weeks": "weeks", + "recurrence_interval_months": "months", + "recurrence_interval_years": "years", + "recurrence_until": "Until", + "insurance_recurrence_type_fixed": "Fixed end date", + "insurance_recurrence_type_yearly": "Renews yearly", + "insurance_recurrence_type_monthly": "Renews monthly", + "insurance_recurrence_type_no_end": "No end date", + "pollution_recurrence_type_fixed": "Fixed end date", + "pollution_recurrence_type_yearly": "Renews yearly", + "pollution_recurrence_type_monthly": "Renews monthly", + "pollution_recurrence_type_no_end": "No end date" +} diff --git a/messages/es.json b/messages/es.json new file mode 100644 index 00000000..693580df --- /dev/null +++ b/messages/es.json @@ -0,0 +1,440 @@ +{ + "$schema": "https://inlang.com/schema/inlang-message-format", + "hello_world": "Hola, {name} desde es!", + "app_title": "Tu Garaje", + "app_add_vehicle": "Agregar Vehículo", + "app_empty_select_message": "Selecciona un vehículo para ver sus detalles", + "app_empty_select_hint": "Elige uno del garaje de arriba para cargar su panel.", + "demo_banner": "Esta es una instancia de demostración. Los datos se restablecerán periódicamente y no se guardan de forma permanente. Por favor evita añadir información personal.", + "default_login": "Usuario por defecto: demo / demo", + "settings_tab_personalization": "Personalización", + "settings_tab_interface": "Interfaz", + "settings_tab_features": "Funciones", + "settings_label_date_format": "Formato de fecha", + "settings_label_locale": "Idioma", + "settings_label_timezone": "Zona horaria", + "settings_label_currency": "Moneda", + "settings_label_unit_distance": "Unidad de distancia", + "settings_label_unit_volume": "Unidad de volumen", + "settings_label_theme": "Tema", + "settings_label_custom_css": "CSS personalizado", + "settings_update_button": "Actualizar configuración", + "settings_select_unit_system": "Selecciona el sistema de unidades", + "settings_select_theme": "Selecciona un tema", + "settings_desc_date_format": "Elige tu formato de fecha preferido", + "settings_desc_locale": "Elige el idioma de la interfaz", + "settings_desc_timezone": "Elige tu zona horaria para mostrar fechas", + "settings_desc_currency": "Elige tu moneda preferida", + "settings_desc_unit_distance": "Unidad de medida de distancia", + "settings_desc_unit_volume": "Unidad de medida de volumen", + "settings_desc_theme": "Elige tu tema preferido", + "settings_desc_custom_css": "Estilos CSS para personalizar la interfaz", + "settings_select_language": "Selecciona el idioma", + "settings_updated_success": "¡Configuración actualizada con éxito!", + "common_example_prefix": "Ejemplo - ", + "common_invalid_format": "Formato no válido...", + "common_kilometer": "Kilómetro", + "common_mile": "Millas", + "common_litre": "Litro", + "common_gallon": "Galón", + "common_submit": "Enviar", + "common_yes": "Sí", + "common_no": "No", + "common_cancel": "Cancelar", + "common_continue": "Continuar", + "common_skip": "Omitir", + "delete_dialog_title": "Eliminar", + "delete_dialog_message": "¿Estás seguro de que deseas eliminar?", + "common_select_column": "Seleccionar columna", + "common_import": "Importar", + "nav_overview": "Resumen", + "nav_fuel_logs": "Registros de combustible", + "nav_maintenance": "Mantenimiento", + "nav_insurance": "Seguro", + "nav_pollution": "Certificado de emisiones", + "nav_reminders": "Recordatorios", + "tools_export_data": "Exportar datos", + "tools_import_data": "Importar datos", + "vehicle_form_make_label": "Marca", + "vehicle_form_make_desc": "Fabricante del vehículo", + "vehicle_form_model_label": "Modelo", + "vehicle_form_model_desc": "Modelo del vehículo", + "vehicle_form_year_label": "Año", + "vehicle_form_year_desc": "Año de fabricación", + "vehicle_form_color_label": "Color", + "vehicle_form_color_desc": "Color del vehículo", + "vehicle_form_fuel_type_label": "Tipo de combustible", + "vehicle_form_fuel_type_desc": "Tipo de combustible del vehículo", + "vehicle_form_fuel_type_placeholder": "Selecciona el tipo de combustible", + "vehicle_form_odometer_label": "Odómetro", + "vehicle_form_odometer_desc": "Lectura actual del odómetro", + "vehicle_form_license_label": "Matrícula", + "vehicle_form_license_desc": "Número de registro del vehículo", + "vehicle_form_vin_label": "VIN", + "vehicle_form_vin_desc": "Número de identificación del vehículo", + "vehicle_toast_saved": "Vehículo guardado correctamente", + "vehicle_toast_updated": "Vehículo actualizado correctamente", + "vehicle_toast_error_prefix": "Error al guardar: ", + "vehicle_list_empty": "Está vacío. Agrega tu primer vehículo para comenzar.", + "vehicle_delete_success": "Vehículo eliminado correctamente.", + "vehicle_delete_error": "Ocurrió un error al eliminar el vehículo.", + "vehicle_action_add_fuel_log": "Agregar registro de combustible", + "vehicle_action_add_maintenance_log": "Agregar registro de mantenimiento", + "vehicle_action_add_insurance": "Agregar seguro", + "vehicle_action_add_pollution": "Agregar certificado de emisiones", + "vehicle_action_add_reminder": "Agregar recordatorio", + "vehicle_action_more_info": "Más información", + "vehicle_action_update_vehicle": "Actualizar vehículo", + "vehicle_action_edit": "Editar", + "vehicle_action_delete": "Eliminar", + "tools_export_encrypt_label": "Encriptar datos de exportación", + "tools_export_password_label": "Contraseña de cifrado", + "tools_export_password_placeholder": "Ingresa la contraseña para cifrar", + "tools_export_password_hint": "Guarda esta contraseña: la necesitarás para descifrar los datos al importar.", + "tools_export_status_exporting": "Exportando...", + "tools_export_button": "Exportar base de datos", + "tools_export_info_title": "Información de exportación", + "tools_export_info_bullet_1": "Exporta todas las tablas y datos", + "tools_export_info_bullet_2": "Incluye vehículos, registros de combustible, mantenimiento, etc.", + "tools_export_info_bullet_3": "Cifrado opcional para proteger datos sensibles", + "tools_export_info_bullet_4": "Descarga como archivo JSON", + "tools_export_success": "Datos exportados correctamente", + "tools_export_error": "No se pudieron exportar los datos", + "tools_import_upload_label": "Subir archivo JSON", + "tools_import_paste_label": "O pega datos JSON", + "tools_import_paste_placeholder": "Pega aquí tus datos JSON exportados...", + "tools_import_password_label": "Contraseña de descifrado (si está cifrado)", + "tools_import_password_placeholder": "Ingresa la contraseña si los datos están cifrados", + "tools_import_status_importing": "Importando...", + "tools_import_button": "Importar base de datos", + "tools_import_warning_title": "⚠️ Advertencia de importación", + "tools_import_warning_bullet_1": "Esto reemplazará TODOS los datos existentes", + "tools_import_warning_bullet_2": "Asegúrate de hacer copia de seguridad primero", + "tools_import_warning_bullet_3": "La importación no se puede deshacer", + "tools_import_warning_bullet_4": "Verifica que el formato JSON sea correcto", + "tools_import_success": "Datos importados correctamente", + "tools_import_error": "No se pudieron importar los datos", + "tools_import_invalid_json": "Formato JSON no válido", + "feature_overview_disabled_title": "Función de Resumen deshabilitada", + "feature_overview_disabled_hint": "Habilita esta función en Configuración para ver el panel de resumen", + "feature_fuel_disabled_title": "Función de Combustible deshabilitada", + "feature_fuel_disabled_hint": "Habilita esta función en Configuración para registrar el consumo", + "feature_maintenance_disabled_title": "Función de Mantenimiento deshabilitada", + "feature_maintenance_disabled_hint": "Habilita esta función en Configuración para gestionar mantenimientos", + "feature_pucc_disabled_title": "Función PUCC deshabilitada", + "feature_pucc_disabled_hint": "Habilita esta función en Configuración para gestionar certificados de contaminación", + "feature_reminders_disabled_title": "Función de Recordatorios deshabilitada", + "feature_reminders_disabled_hint": "Habilita esta función en Configuración para gestionar recordatorios", + "feature_insurance_disabled_title": "Función de Seguro deshabilitada", + "feature_insurance_disabled_hint": "Habilita esta función en Configuración para gestionar los seguros", + "overview_chart_no_data": "No hay datos disponibles", + "overview_chart_cost_label": "Costo", + "overview_chart_cost_title": "Costo a lo largo del tiempo ({currency})", + "overview_chart_mileage_label": "Rendimiento", + "overview_chart_mileage_title": "Rendimiento a lo largo del tiempo ({unit})", + "fuel_import_title": "Importar registros de combustible", + "fuel_add_title": "Agregar registro de combustible", + "col_date": "Fecha", + "col_odometer": "Odómetro", + "col_filled": "Llenado", + "col_missed_last": "Último omitido", + "col_fuel_amount": "Cantidad de combustible", + "col_cost": "Costo", + "col_mileage": "Rendimiento", + "col_notes": "Notas", + "col_attachment": "Adjunto", + "col_no_end_date": "Sin fecha de finalización", + "fuel_volume_label_fuel": "Cantidad de combustible", + "fuel_volume_label_energy": "Energía", + "fuel_empty_list": "No se encontraron registros de combustible para este vehículo.", + "form_date": "Fecha", + "form_date_desc": "Fecha del llenado", + "form_odometer": "Odómetro", + "form_odometer_desc": "Lectura actual del odómetro", + "form_volume_fuel": "Volumen de combustible", + "form_volume_energy": "Energía consumida", + "form_cost": "Costo", + "form_cost_desc": "Costo del llenado", + "form_cost_desc_ev": "Costo de la carga", + "form_full_charge": "Carga completa", + "form_full_tank": "Tanque lleno", + "form_full_charge_desc": "¿La batería está completamente cargada?", + "form_full_tank_desc": "¿El tanque está lleno?", + "form_missed_last": "Último omitido", + "form_missed_last_desc": "¿Se omitieron entradas anteriores?", + "form_notes": "Notas", + "form_notes_placeholder": "Agrega más detalles, si los hay...", + "form_attachment": "Adjunto", + "fuel_toast_saved": "Registro de combustible guardado correctamente...!!!", + "fuel_toast_updated": "Registro de combustible actualizado correctamente...!!!", + "fuel_toast_error_prefix": "Error al guardar: ", + "notifications_title": "Notificaciones", + "notifications_new": "nuevo", + "notifications_select_vehicle_hint": "Selecciona un vehículo para cargar recordatorios y alertas.", + "notifications_syncing": "Sincronizando datos más recientes...", + "notifications_caught_up": "Estás al día.", + "notifications_section_reminders": "Recordatorios", + "notifications_section_alerts": "Alertas de cumplimiento", + "notifications_mark_done_title": "Marcar recordatorio como completado", + "notifications_mark_done_aria": "Marcar recordatorio de {type} como completado", + "notifications_overdue_days": "{days} día{plural} de retraso", + "notifications_due_today": "Vence hoy", + "notifications_due_tomorrow": "Vence mañana", + "notifications_due_in_days": "Vence en {days} días", + "alerts_status_expired": "Vencido", + "alerts_status_expiring": "Por vencer", + "alerts_status_valid": "Vigente", + "alerts_status_missing": "Faltante", + "notifications_expires": "Vence", + "notifications_error_no_id": "No se puede actualizar sin ID.", + "notifications_error_update_failed": "Error al actualizar el recordatorio.", + "notifications_success_marked_done": "Recordatorio marcado como completado.", + "notifications_severity_overdue": "Atrasado", + "notifications_severity_due_soon": "Próximo a vencer", + "notifications_severity_upcoming": "Próximo", + "settings_custom_css_placeholder": "Agrega tu CSS personalizado aquí...", + "settings_features_intro": "Habilita o deshabilita funciones para personalizar tu experiencia", + "feature_label_fuel": "Registro de combustible", + "feature_desc_fuel": "Gestiona y registra el consumo y los repostajes", + "feature_label_maintenance": "Mantenimiento", + "feature_desc_maintenance": "Registra y programa actividades de mantenimiento", + "feature_label_pucc": "Contaminación", + "feature_desc_pucc": "Gestiona los certificados de contaminación (PUCC)", + "feature_label_reminders": "Recordatorios", + "feature_desc_reminders": "Configura y recibe recordatorios de eventos importantes", + "feature_label_insurance": "Seguro", + "feature_desc_insurance": "Gestiona detalles y renovaciones del seguro del vehículo", + "feature_label_overview": "Resumen", + "feature_desc_overview": "Muestra el panel con métricas clave del vehículo", + "settings_error_date_format_invalid": "Formato no válido", + "settings_error_timezone_invalid": "Valor de zona horaria no válido.", + "settings_error_currency_required": "La moneda es obligatoria", + "maintenance_form_attachment_label": "Adjunto", + "maintenance_form_attachment_desc": "Sube el recibo o documento de mantenimiento", + "maintenance_form_date_label": "Fecha", + "maintenance_form_date_desc": "Fecha de mantenimiento", + "maintenance_form_odometer_label": "Odómetro", + "maintenance_form_odometer_desc": "Lectura actual del odómetro", + "maintenance_form_service_center_label": "Centro de servicio", + "maintenance_form_service_center_desc": "Nombre del centro de servicio", + "maintenance_form_cost_label": "Costo", + "maintenance_form_cost_desc": "Costo del mantenimiento", + "maintenance_form_notes_label": "Notas", + "maintenance_form_notes_desc": "Más detalles", + "maintenance_form_notes_placeholder": "Agrega más detalles, si los hay...", + "maintenance_toast_saved": "Registro de mantenimiento guardado correctamente", + "maintenance_toast_updated": "Registro de mantenimiento actualizado correctamente", + "maintenance_toast_error_prefix": "Error al guardar: ", + "maintenance_form_error_fix": "Corrige los errores del formulario antes de enviar.", + "maintenance_list_empty": "No se encontraron registros de mantenimiento para este vehículo.", + "maintenance_col_service_center": "Centro de servicio", + "maintenance_menu_open": "Abrir menú", + "maintenance_menu_edit": "Editar", + "maintenance_menu_delete": "Eliminar", + "maintenance_menu_sheet_title": "Actualizar registro de mantenimiento", + "maintenance_tab_title": "Historial de mantenimiento", + "maintenance_add_action": "Agregar registro de mantenimiento", + "maintenance_delete_success": "Registro de mantenimiento eliminado.", + "maintenance_delete_error": "Ocurrió un error al eliminar el registro de mantenimiento.", + "insurance_form_provider_label": "Proveedor de seguro", + "insurance_form_provider_desc": "Nombre de la compañía aseguradora", + "insurance_form_policy_number_label": "Número de póliza de seguro", + "insurance_form_policy_number_desc": "Número de póliza de tu documento de seguro", + "insurance_form_start_date_label": "Fecha de inicio del seguro", + "insurance_form_start_date_desc": "Fecha en que comienza la cobertura", + "insurance_form_recurrence_type_label": "¿Cómo debería renovarse este seguro?", + "insurance_form_recurrence_type_desc": "Tipo de renovación para este seguro", + "insurance_form_recurrence_interval_label": "Frecuencia de renovación", + "insurance_form_recurrence_interval_desc": "Con qué frecuencia se renueva el seguro", + "insurance_form_end_date_label": "Fecha de vencimiento del seguro", + "insurance_form_end_date_desc": "Fecha en que vence la cobertura", + "insurance_form_cost_label": "Costo del seguro", + "insurance_form_cost_desc": "Costo anual o del período de póliza", + "insurance_form_notes_label": "Notas adicionales", + "insurance_form_notes_desc": "Información adicional sobre la póliza", + "insurance_form_notes_placeholder": "Agrega más detalles sobre el seguro...", + "insurance_form_attachment_label": "Documento de póliza", + "insurance_form_attachment_desc": "Sube el documento de póliza", + "insurance_form_error_fix": "Corrige los errores del formulario antes de enviar.", + "insurance_toast_saved": "Seguro guardado correctamente", + "insurance_toast_updated": "Seguro actualizado correctamente", + "insurance_toast_error_prefix": "Error al guardar: ", + "insurance_list_empty": "No se encontró seguro para este vehículo.", + "insurance_col_policy_number": "Número de póliza", + "insurance_col_cost": "Costo", + "insurance_col_start_date": "Fecha de inicio", + "insurance_col_end_date": "Fecha de vencimiento", + "insurance_col_next_due": "Próximo vencimiento", + "insurance_col_recurrence": "Renovación", + "insurance_col_notes": "Notas", + "insurance_menu_open": "Abrir menú", + "insurance_menu_edit": "Editar", + "insurance_menu_delete": "Eliminar", + "insurance_menu_sheet_title": "Actualizar seguro", + "insurance_tab_title": "Detalles del seguro", + "insurance_add_action": "Agregar seguro", + "insurance_delete_success": "Seguro eliminado.", + "insurance_delete_error": "Ocurrió un error al eliminar el seguro.", + "insurance_col_view_document": "Ver documento", + "pollution_form_certificate_number_label": "Número de certificado", + "pollution_form_certificate_number_desc": "Número de certificado de contaminación", + "pollution_form_issue_date_label": "Fecha de emisión", + "pollution_form_issue_date_desc": "Fecha de emisión del certificado", + "pollution_form_recurrence_type_label": "¿Cómo debería renovarse este certificado?", + "pollution_form_recurrence_type_desc": "Tipo de renovación para este certificado", + "pollution_form_recurrence_interval_label": "Frecuencia de renovación", + "pollution_form_recurrence_interval_desc": "Con qué frecuencia se renueva el certificado", + "pollution_form_expiry_date_label": "Fecha de vencimiento", + "pollution_form_expiry_date_desc": "Fecha de vencimiento del PUCC", + "pollution_form_testing_center_label": "Centro de pruebas", + "pollution_form_testing_center_desc": "Nombre del centro de pruebas", + "pollution_form_notes_label": "Notas adicionales", + "pollution_form_notes_desc": "Información adicional", + "pollution_form_notes_placeholder": "Agrega notas adicionales...", + "pollution_form_attachment_label": "Documento de certificado", + "pollution_form_attachment_desc": "Sube el documento de certificado", + "pollution_form_error_fix": "Corrige los errores del formulario antes de enviar.", + "pollution_toast_saved": "Certificado de contaminación guardado correctamente", + "pollution_toast_updated": "Certificado de contaminación actualizado correctamente", + "pollution_toast_error_prefix": "Error al guardar: ", + "pollution_list_empty": "No se encontraron certificados de contaminación para este vehículo.", + "pollution_col_certificate_number": "Número de certificado", + "pollution_col_issue_date": "Fecha de emisión", + "pollution_col_expiry_date": "Fecha de vencimiento", + "pollution_col_next_due": "Próximo vencimiento", + "pollution_col_testing_center": "Centro de pruebas", + "pollution_col_notes": "Notas", + "pollution_col_view_certificate": "Ver certificado", + "pollution_col_recurrence": "Renovación", + "pollution_menu_open": "Abrir menú", + "pollution_menu_edit": "Editar", + "pollution_menu_delete": "Eliminar", + "pollution_menu_sheet_title": "Actualizar certificado de contaminación", + "pollution_tab_title": "Detalles del certificado de contaminación", + "pollution_add_action": "Agregar certificado de contaminación", + "pollution_delete_success": "PUCC eliminado.", + "pollution_delete_error": "Ocurrió un error al eliminar el PUCC.", + "reminder_form_due_date_label": "Fecha de vencimiento", + "reminder_form_due_date_desc": "¿Cuándo debería activarse este recordatorio?", + "reminder_form_type_label": "Tipo", + "reminder_form_type_desc": "Elige el tipo de recordatorio", + "reminder_form_schedule_label": "Calendario de recordatorio", + "reminder_form_schedule_desc": "¿Cuándo deberíamos recordarte?", + "reminder_form_recurrence_type_label": "Renovación", + "reminder_form_recurrence_type_desc": "¿Debería repetirse este recordatorio?", + "reminder_form_recurrence_interval_label": "Repetir cada", + "reminder_form_recurrence_interval_desc": "Frecuencia de renovación", + "reminder_form_recurrence_end_date_label": "Fecha de finalización", + "reminder_form_recurrence_end_date_desc": "¿Cuándo debería detenerse la repetición? (opcional)", + "reminder_form_note_label": "Nota", + "reminder_form_note_desc": "Agrega más contexto", + "reminder_form_note_placeholder": "Detalla qué necesita atención", + "reminder_form_is_completed_label": "Marcar como hecho", + "reminder_toast_created": "Recordatorio creado correctamente.", + "reminder_toast_updated": "Recordatorio actualizado correctamente", + "reminder_toast_error_prefix": "Error al guardar: ", + "reminder_list_empty": "Sin recordatorios aún. Crea uno para adelantarte a las renovaciones.", + "reminder_list_select_vehicle": "Selecciona un vehículo para ver recordatorios.", + "reminder_list_select_hint": "Elige un vehículo arriba para cargar recordatorios próximos.", + "reminder_col_due_date": "Fecha de vencimiento", + "reminder_col_reminder_schedule": "Calendario de recordatorio", + "reminder_col_recurrence": "Renovación", + "reminder_col_note": "Notas", + "reminder_menu_toggle_done": "Marcar como {status}", + "reminder_menu_toggle_done_done": "Marcar como pendiente", + "reminder_menu_toggle_done_pending": "Marcar como hecho", + "reminder_menu_edit": "Editar", + "reminder_menu_delete": "Eliminar", + "reminder_menu_open": "Abrir menú", + "reminder_menu_sheet_title": "Actualizar recordatorio", + "reminder_tab_title": "Recordatorios", + "reminder_add_action": "Agregar recordatorio", + "reminder_delete_success": "Recordatorio eliminado.", + "reminder_delete_error": "Ocurrió un error al eliminar el recordatorio.", + "reminder_status_error": "Error al actualizar el estado del recordatorio.", + "reminder_toast_error_fallback": "Error al guardar el recordatorio.", + "reminder_status_completed": "Completado", + "reminder_status_pending": "Pendiente", + "reminder_status_overdue": "Vencido", + "settings_sheet_title": "Configuración", + "settings_features_intro": "Habilita o deshabilita funciones para personalizar tu experiencia", + "feature_label_fuel": "Registro de combustible", + "feature_desc_fuel": "Rastrea y gestiona el consumo de combustible y el historial de reabastecimiento", + "feature_label_maintenance": "Mantenimiento", + "feature_desc_maintenance": "Registra y programa actividades de mantenimiento del vehículo", + "feature_label_pollution": "Contaminación", + "feature_desc_pollution": "Gestiona registros del Certificado de Control de Contaminación", + "feature_label_reminders": "Recordatorios", + "feature_desc_reminders": "Establece y recibe recordatorios de eventos importantes del vehículo", + "feature_label_insurance": "Seguro", + "feature_desc_insurance": "Gestiona detalles de seguros del vehículo y renovaciones", + "feature_label_overview": "Resumen", + "feature_desc_overview": "Muestra un panel de resumen con las métricas clave del vehículo", + "profile_menu_item": "Perfil", + "profile_sheet_title": "Perfil", + "profile_sheet_desc": "Actualiza tu nombre de usuario y contraseña", + "profile_username": "Nombre de usuario", + "profile_username_desc": "Tu nombre de visualización", + "profile_password_hint": "Deja los campos de contraseña vacíos para mantener tu contraseña actual", + "profile_current_password": "Contraseña actual", + "profile_current_password_desc": "Requerido para cambiar la contraseña", + "profile_new_password": "Nueva contraseña", + "profile_new_password_desc": "Mínimo 6 caracteres", + "profile_confirm_password": "Confirmar contraseña", + "profile_confirm_password_desc": "Vuelve a ingresar tu nueva contraseña", + "profile_update_button": "Actualizar perfil", + "tools_menu": "Herramientas", + "data_export_import_menu_item": "Exportar/Importar datos", + "data_export_import_sheet_title": "Exportar/Importar datos", + "data_export_import_sheet_desc": "Exporte o importe su base de datos con cifrado opcional", + "logout_menu_item": "Cerrar sesión", + "nav_overview": "Resumen", + "nav_fuel_logs": "Registros de combustible", + "nav_maintenance": "Mantenimiento", + "nav_insurance": "Seguro", + "nav_pollution": "Contaminación", + "nav_reminders": "Recordatorios", + "custom_fields_label": "Campos personalizados", + "custom_fields_add_button": "Agregar campo", + "custom_fields_name_placeholder": "Nombre del campo", + "custom_fields_value_placeholder": "Valor del campo", + "custom_fields_remove_aria": "Eliminar campo", + "custom_fields_empty_message": "No se han agregado campos personalizados. Haz clic en \"Agregar campo\" para comenzar.", + "vehicle_details_vin": "VIN", + "vehicle_details_not_specified": "No especificado", + "vehicle_details_section_title": "Detalles", + "vehicle_details_license_plate": "Matrícula", + "vehicle_details_fuel_type": "Tipo de combustible", + "vehicle_details_odometer": "Odómetro", + "vehicle_details_not_recorded": "No registrado", + "vehicle_details_color": "Color", + "vehicle_details_year": "Año", + "fuel_type_diesel": "Diésel", + "fuel_type_petrol": "Gasolina", + "fuel_type_ev": "Eléctrico (EV)", + "reminder_schedule_same_day": "En la fecha de vencimiento", + "reminder_schedule_one_day_before": "1 día antes", + "reminder_schedule_three_days_before": "3 días antes", + "reminder_schedule_one_week_before": "1 semana antes", + "reminder_schedule_one_month_before": "1 mes antes", + "recurrence_type_none": "Sin repetición", + "recurrence_type_daily": "Diario", + "recurrence_type_weekly": "Semanal", + "recurrence_type_monthly": "Mensual", + "recurrence_type_yearly": "Anual", + "recurrence_every": "cada", + "recurrence_renew_every": "Renovar cada", + "recurrence_interval_days": "días", + "recurrence_interval_weeks": "semanas", + "recurrence_interval_months": "meses", + "recurrence_interval_years": "años", + "recurrence_until": "Hasta", + "insurance_recurrence_type_fixed": "Fecha de fin fija", + "insurance_recurrence_type_yearly": "Se renueva anualmente", + "insurance_recurrence_type_monthly": "Se renueva mensualmente", + "insurance_recurrence_type_no_end": "Sin fecha de fin", + "pollution_recurrence_type_fixed": "Fecha de fin fija", + "pollution_recurrence_type_yearly": "Se renueva anualmente", + "pollution_recurrence_type_monthly": "Se renueva mensualmente", + "pollution_recurrence_type_no_end": "Sin fecha de fin" +} diff --git a/messages/fr.json b/messages/fr.json new file mode 100644 index 00000000..11008d12 --- /dev/null +++ b/messages/fr.json @@ -0,0 +1,440 @@ +{ + "$schema": "https://inlang.com/schema/inlang-message-format", + "hello_world": "Bonjour, {name} depuis fr !", + "app_title": "Votre Garage", + "app_add_vehicle": "Ajouter un véhicule", + "app_empty_select_message": "Sélectionnez un véhicule pour voir ses détails", + "app_empty_select_hint": "Choisissez-en un dans le garage ci-dessus pour charger son tableau de bord.", + "demo_banner": "Ceci est une instance de démonstration. Les données seront réinitialisées périodiquement et ne sont pas enregistrées de manière permanente. Veuillez éviter d'ajouter des informations personnelles.", + "default_login": "Identifiants par défaut : demo / demo", + "settings_tab_personalization": "Personnalisation", + "settings_tab_interface": "Interface", + "settings_tab_features": "Fonctionnalités", + "settings_label_date_format": "Format de date", + "settings_label_locale": "Langue", + "settings_label_timezone": "Fuseau horaire", + "settings_label_currency": "Devise", + "settings_label_unit_distance": "Unité de distance", + "settings_label_unit_volume": "Unité de volume", + "settings_label_theme": "Thème", + "settings_label_custom_css": "CSS personnalisé", + "settings_update_button": "Mettre à jour les paramètres", + "settings_select_unit_system": "Sélectionnez le système d'unités", + "settings_select_theme": "Sélectionnez un thème", + "settings_desc_date_format": "Choisissez votre format de date préféré", + "settings_desc_locale": "Choisissez la langue de l'interface", + "settings_desc_timezone": "Choisissez votre fuseau horaire pour l'affichage des dates", + "settings_desc_currency": "Choisissez votre devise préférée", + "settings_desc_unit_distance": "Unité de mesure de distance", + "settings_desc_unit_volume": "Unité de mesure de volume", + "settings_desc_theme": "Choisissez votre thème préféré", + "settings_desc_custom_css": "Styles CSS pour personnaliser l'interface", + "settings_select_language": "Sélectionnez la langue", + "settings_updated_success": "Configuration mise à jour avec succès !", + "common_example_prefix": "Exemple - ", + "common_invalid_format": "Format invalide...", + "common_kilometer": "Kilomètre", + "common_mile": "Miles", + "common_litre": "Litre", + "common_gallon": "Gallon", + "common_submit": "Envoyer", + "common_yes": "Oui", + "common_no": "Non", + "common_cancel": "Annuler", + "common_continue": "Continuer", + "common_skip": "Ignorer", + "delete_dialog_title": "Supprimer", + "delete_dialog_message": "Êtes-vous sûr de vouloir supprimer ?", + "common_select_column": "Sélectionner une colonne", + "common_import": "Importer", + "nav_overview": "Aperçu", + "nav_fuel_logs": "Journaux de carburant", + "nav_maintenance": "Maintenance", + "nav_insurance": "Assurance", + "nav_pollution": "Certificat antipollution", + "nav_reminders": "Rappels", + "tools_export_data": "Exporter les données", + "tools_import_data": "Importer des données", + "vehicle_form_make_label": "Marque", + "vehicle_form_make_desc": "Fabricant du véhicule", + "vehicle_form_model_label": "Modèle", + "vehicle_form_model_desc": "Modèle du véhicule", + "vehicle_form_year_label": "Année", + "vehicle_form_year_desc": "Année de fabrication", + "vehicle_form_color_label": "Couleur", + "vehicle_form_color_desc": "Couleur du véhicule", + "vehicle_form_fuel_type_label": "Type de carburant", + "vehicle_form_fuel_type_desc": "Type de carburant utilisé par le véhicule", + "vehicle_form_fuel_type_placeholder": "Sélectionnez le type de carburant", + "vehicle_form_odometer_label": "Odomètre", + "vehicle_form_odometer_desc": "Relevé actuel de l'odomètre", + "vehicle_form_license_label": "Plaque d'immatriculation", + "vehicle_form_license_desc": "Numéro d'immatriculation du véhicule", + "vehicle_form_vin_label": "VIN", + "vehicle_form_vin_desc": "Numéro d'identification du véhicule", + "vehicle_toast_saved": "Véhicule enregistré avec succès", + "vehicle_toast_updated": "Véhicule mis à jour avec succès", + "vehicle_toast_error_prefix": "Erreur lors de l'enregistrement : ", + "vehicle_list_empty": "C'est vide ici. Ajoutez votre premier véhicule pour commencer.", + "vehicle_delete_success": "Véhicule supprimé avec succès.", + "vehicle_delete_error": "Une erreur s'est produite lors de la suppression du véhicule.", + "vehicle_action_add_fuel_log": "Ajouter un journal de carburant", + "vehicle_action_add_maintenance_log": "Ajouter un journal de maintenance", + "vehicle_action_add_insurance": "Ajouter une assurance", + "vehicle_action_add_pollution": "Ajouter un certificat antipollution", + "vehicle_action_add_reminder": "Ajouter un rappel", + "vehicle_action_more_info": "Plus d'infos", + "vehicle_action_update_vehicle": "Mettre à jour le véhicule", + "vehicle_action_edit": "Modifier", + "vehicle_action_delete": "Supprimer", + "tools_export_encrypt_label": "Chiffrer les données d'export", + "tools_export_password_label": "Mot de passe de chiffrement", + "tools_export_password_placeholder": "Saisissez un mot de passe pour chiffrer", + "tools_export_password_hint": "Gardez ce mot de passe en lieu sûr - il sera nécessaire pour déchiffrer les données à l'import.", + "tools_export_status_exporting": "Exportation...", + "tools_export_button": "Exporter la base de données", + "tools_export_info_title": "Informations sur l'export", + "tools_export_info_bullet_1": "Exporte toutes les tables et données", + "tools_export_info_bullet_2": "Inclut véhicules, pleins, maintenance, etc.", + "tools_export_info_bullet_3": "Chiffrement optionnel pour protéger les données sensibles", + "tools_export_info_bullet_4": "Télécharge en fichier JSON", + "tools_export_success": "Données exportées avec succès", + "tools_export_error": "Échec de l'export des données", + "tools_import_upload_label": "Téléverser un fichier JSON", + "tools_import_paste_label": "Ou coller des données JSON", + "tools_import_paste_placeholder": "Collez ici vos données JSON exportées...", + "tools_import_password_label": "Mot de passe de déchiffrement (si chiffré)", + "tools_import_password_placeholder": "Saisissez le mot de passe si les données sont chiffrées", + "tools_import_status_importing": "Importation...", + "tools_import_button": "Importer la base de données", + "tools_import_warning_title": "⚠️ Avertissement d'import", + "tools_import_warning_bullet_1": "Cela remplacera TOUTES les données existantes", + "tools_import_warning_bullet_2": "Sauvegardez d'abord les données actuelles", + "tools_import_warning_bullet_3": "L'import ne peut pas être annulé", + "tools_import_warning_bullet_4": "Vérifiez que le format JSON est correct", + "tools_import_success": "Données importées avec succès", + "tools_import_error": "Échec de l'import des données", + "tools_import_invalid_json": "Format JSON invalide", + "feature_overview_disabled_title": "Fonction Aperçu désactivée", + "feature_overview_disabled_hint": "Activez cette fonctionnalité dans les paramètres pour voir le tableau de bord d'aperçu", + "feature_fuel_disabled_title": "Fonction Carburant désactivée", + "feature_fuel_disabled_hint": "Activez cette fonctionnalité pour suivre la consommation", + "feature_maintenance_disabled_title": "Fonction Maintenance désactivée", + "feature_maintenance_disabled_hint": "Activez cette fonctionnalité pour gérer les maintenances", + "feature_pucc_disabled_title": "Fonction PUCC désactivée", + "feature_pucc_disabled_hint": "Activez cette fonctionnalité pour gérer les certificats de pollution", + "feature_reminders_disabled_title": "Fonction Rappels désactivée", + "feature_reminders_disabled_hint": "Activez cette fonctionnalité pour gérer les rappels", + "feature_insurance_disabled_title": "Fonction Assurance désactivée", + "feature_insurance_disabled_hint": "Activez cette fonctionnalité pour gérer les assurances", + "overview_chart_no_data": "Aucune donnée disponible", + "overview_chart_cost_label": "Coût", + "overview_chart_cost_title": "Coût dans le temps ({currency})", + "overview_chart_mileage_label": "Kilométrage", + "overview_chart_mileage_title": "Kilométrage dans le temps ({unit})", + "fuel_import_title": "Importer des journaux de carburant", + "fuel_add_title": "Ajouter un journal de carburant", + "col_date": "Date", + "col_odometer": "Odomètre", + "col_filled": "Rempli", + "col_missed_last": "Dernier manqué", + "col_fuel_amount": "Quantité de carburant", + "col_cost": "Coût", + "col_mileage": "Kilométrage", + "col_notes": "Notes", + "col_attachment": "Pièce jointe", + "col_no_end_date": "Pas de date de fin", + "fuel_volume_label_fuel": "Quantité de carburant", + "fuel_volume_label_energy": "Énergie", + "fuel_empty_list": "Aucun journal de carburant trouvé pour ce véhicule.", + "form_date": "Date", + "form_date_desc": "Date du remplissage", + "form_odometer": "Odomètre", + "form_odometer_desc": "Lecture actuelle de l'odomètre", + "form_volume_fuel": "Volume de carburant", + "form_volume_energy": "Énergie consommée", + "form_cost": "Coût", + "form_cost_desc": "Coût du remplissage", + "form_cost_desc_ev": "Coût de la recharge", + "form_full_charge": "Charge complète", + "form_full_tank": "Plein", + "form_full_charge_desc": "La batterie est-elle complètement chargée ?", + "form_full_tank_desc": "Le réservoir est-il plein ?", + "form_missed_last": "Dernier manqué", + "form_missed_last_desc": "Des entrées précédentes ont-elles été omises ?", + "form_notes": "Notes", + "form_notes_placeholder": "Ajoutez plus de détails, le cas échéant...", + "form_attachment": "Pièce jointe", + "fuel_toast_saved": "Journal de carburant enregistré avec succès...!!!", + "fuel_toast_updated": "Journal de carburant mis à jour avec succès...!!!", + "fuel_toast_error_prefix": "Erreur lors de l'enregistrement : ", + "notifications_title": "Notifications", + "notifications_new": "nouveau", + "notifications_select_vehicle_hint": "Sélectionnez un véhicule pour charger les rappels et alertes.", + "notifications_syncing": "Synchronisation des dernières données...", + "notifications_caught_up": "Vous êtes à jour.", + "notifications_section_reminders": "Rappels", + "notifications_section_alerts": "Alertes de conformité", + "notifications_mark_done_title": "Marquer le rappel comme effectué", + "notifications_mark_done_aria": "Marquer le rappel {type} comme effectué", + "notifications_overdue_days": "{days} jour{plural} de retard", + "notifications_due_today": "Échéance aujourd'hui", + "notifications_due_tomorrow": "Échéance demain", + "notifications_due_in_days": "Échéance dans {days} jours", + "alerts_status_expired": "Expiré", + "alerts_status_expiring": "Expire bientôt", + "alerts_status_valid": "Valide", + "alerts_status_missing": "Manquant", + "notifications_expires": "Expire", + "notifications_error_no_id": "Impossible de mettre à jour sans identifiant.", + "notifications_error_update_failed": "Échec de la mise à jour du rappel.", + "notifications_success_marked_done": "Rappel marqué comme effectué.", + "notifications_severity_overdue": "En retard", + "notifications_severity_due_soon": "Bientôt dû", + "notifications_severity_upcoming": "À venir", + "settings_custom_css_placeholder": "Ajoutez votre CSS personnalisé ici...", + "settings_features_intro": "Activez ou désactivez des fonctionnalités pour personnaliser votre expérience", + "feature_label_fuel": "Journal de carburant", + "feature_desc_fuel": "Suivre et gérer la consommation et les pleins", + "feature_label_maintenance": "Maintenance", + "feature_desc_maintenance": "Enregistrer et planifier les activités de maintenance", + "feature_label_pucc": "Pollution", + "feature_desc_pucc": "Gérer les certificats antipollution (PUCC)", + "feature_label_reminders": "Rappels", + "feature_desc_reminders": "Configurer et recevoir des rappels d'événements importants", + "feature_label_insurance": "Assurance", + "feature_desc_insurance": "Gérer les détails et renouvellements d'assurance du véhicule", + "feature_label_overview": "Aperçu", + "feature_desc_overview": "Afficher le tableau de bord avec les métriques clés du véhicule", + "settings_error_date_format_invalid": "Format non valide", + "settings_error_timezone_invalid": "Valeur de fuseau horaire invalide.", + "settings_error_currency_required": "La devise est requise", + "maintenance_form_attachment_label": "Pièce jointe", + "maintenance_form_attachment_desc": "Téléverser un reçu ou document de maintenance", + "maintenance_form_date_label": "Date", + "maintenance_form_date_desc": "Date de maintenance", + "maintenance_form_odometer_label": "Odomètre", + "maintenance_form_odometer_desc": "Relevé actuel de l'odomètre", + "maintenance_form_service_center_label": "Centre de service", + "maintenance_form_service_center_desc": "Nom du centre de service", + "maintenance_form_cost_label": "Coût", + "maintenance_form_cost_desc": "Coût de la maintenance", + "maintenance_form_notes_label": "Notes", + "maintenance_form_notes_desc": "Plus de détails", + "maintenance_form_notes_placeholder": "Ajoutez plus de détails, le cas échéant...", + "maintenance_toast_saved": "Journal de maintenance enregistré avec succès", + "maintenance_toast_updated": "Journal de maintenance mis à jour avec succès", + "maintenance_toast_error_prefix": "Erreur lors de l'enregistrement : ", + "maintenance_form_error_fix": "Corrigez les erreurs du formulaire avant de soumettre.", + "maintenance_list_empty": "Aucun journal de maintenance trouvé pour ce véhicule.", + "maintenance_col_service_center": "Centre de service", + "maintenance_menu_open": "Ouvrir le menu", + "maintenance_menu_edit": "Modifier", + "maintenance_menu_delete": "Supprimer", + "maintenance_menu_sheet_title": "Mettre à jour le journal de maintenance", + "maintenance_tab_title": "Historique de maintenance", + "maintenance_add_action": "Ajouter un journal de maintenance", + "maintenance_delete_success": "Journal de maintenance supprimé.", + "maintenance_delete_error": "Une erreur s'est produite lors de la suppression du journal de maintenance.", + "insurance_form_provider_label": "Fournisseur d'assurance", + "insurance_form_provider_desc": "Nom de la compagnie d'assurance", + "insurance_form_policy_number_label": "Numéro de police d'assurance", + "insurance_form_policy_number_desc": "Numéro de police de votre document d'assurance", + "insurance_form_start_date_label": "Date de début de l'assurance", + "insurance_form_start_date_desc": "Date du début de la couverture", + "insurance_form_recurrence_type_label": "Comment cette assurance devrait-elle se renouveler ?", + "insurance_form_recurrence_type_desc": "Type de renouvellement pour cette assurance", + "insurance_form_recurrence_interval_label": "Fréquence de renouvellement", + "insurance_form_recurrence_interval_desc": "Fréquence de renouvellement de l'assurance", + "insurance_form_end_date_label": "Date de fin de l'assurance", + "insurance_form_end_date_desc": "Date d'expiration de la couverture", + "insurance_form_cost_label": "Coût de l'assurance", + "insurance_form_cost_desc": "Coût annuel ou de la période de police", + "insurance_form_notes_label": "Notes supplémentaires", + "insurance_form_notes_desc": "Informations supplémentaires sur la police", + "insurance_form_notes_placeholder": "Ajoutez plus de détails sur l'assurance...", + "insurance_form_attachment_label": "Document de police", + "insurance_form_attachment_desc": "Téléverser le document de police", + "insurance_form_error_fix": "Corrigez les erreurs du formulaire avant de soumettre.", + "insurance_toast_saved": "Assurance enregistrée avec succès", + "insurance_toast_updated": "Assurance mise à jour avec succès", + "insurance_toast_error_prefix": "Erreur lors de l'enregistrement : ", + "insurance_list_empty": "Aucune assurance trouvée pour ce véhicule.", + "insurance_col_policy_number": "Numéro de police", + "insurance_col_cost": "Coût", + "insurance_col_start_date": "Date de début", + "insurance_col_end_date": "Date de fin", + "insurance_col_next_due": "Prochain renouvellement", + "insurance_col_recurrence": "Renouvellement", + "insurance_col_notes": "Notes", + "insurance_col_view_document": "Afficher le document", + "insurance_menu_open": "Ouvrir le menu", + "insurance_menu_edit": "Modifier", + "insurance_menu_delete": "Supprimer", + "insurance_menu_sheet_title": "Mettre à jour l'assurance", + "insurance_tab_title": "Détails de l'assurance", + "insurance_add_action": "Ajouter une assurance", + "insurance_delete_success": "Assurance supprimée.", + "insurance_delete_error": "Une erreur s'est produite lors de la suppression de l'assurance.", + "pollution_form_certificate_number_label": "Numéro de certificat", + "pollution_form_certificate_number_desc": "Numéro de certificat de pollution", + "pollution_form_issue_date_label": "Date de délivrance", + "pollution_form_issue_date_desc": "Date de délivrance du certificat", + "pollution_form_recurrence_type_label": "Comment ce certificat devrait-il se renouveler ?", + "pollution_form_recurrence_type_desc": "Type de renouvellement pour ce certificat", + "pollution_form_recurrence_interval_label": "Fréquence de renouvellement", + "pollution_form_recurrence_interval_desc": "Fréquence de renouvellement du certificat", + "pollution_form_expiry_date_label": "Date d'expiration", + "pollution_form_expiry_date_desc": "Date d'expiration du PUCC", + "pollution_form_testing_center_label": "Centre de test", + "pollution_form_testing_center_desc": "Nom du centre de test", + "pollution_form_notes_label": "Notes supplémentaires", + "pollution_form_notes_desc": "Informations supplémentaires", + "pollution_form_notes_placeholder": "Ajoutez des notes supplémentaires...", + "pollution_form_attachment_label": "Document de certificat", + "pollution_form_attachment_desc": "Téléverser le document de certificat", + "pollution_form_error_fix": "Corrigez les erreurs du formulaire avant de soumettre.", + "pollution_toast_saved": "Certificat de pollution enregistré avec succès", + "pollution_toast_updated": "Certificat de pollution mis à jour avec succès", + "pollution_toast_error_prefix": "Erreur lors de l'enregistrement : ", + "pollution_list_empty": "Aucun certificat de pollution trouvé pour ce véhicule.", + "pollution_col_certificate_number": "Numéro de certificat", + "pollution_col_issue_date": "Date de délivrance", + "pollution_col_expiry_date": "Date d'expiration", + "pollution_col_next_due": "Prochain renouvellement", + "pollution_col_testing_center": "Centre de test", + "pollution_col_notes": "Notes", + "pollution_col_view_certificate": "Afficher le certificat", + "pollution_col_recurrence": "Renouvellement", + "pollution_menu_open": "Ouvrir le menu", + "pollution_menu_edit": "Modifier", + "pollution_menu_delete": "Supprimer", + "pollution_menu_sheet_title": "Mettre à jour le certificat de pollution", + "pollution_tab_title": "Détails du certificat de pollution", + "pollution_add_action": "Ajouter un certificat de pollution", + "pollution_delete_success": "PUCC supprimé.", + "pollution_delete_error": "Une erreur s'est produite lors de la suppression du PUCC.", + "reminder_form_due_date_label": "Date d'échéance", + "reminder_form_due_date_desc": "Quand ce rappel devrait-il se déclencher ?", + "reminder_form_type_label": "Type", + "reminder_form_type_desc": "Choisir le type de rappel", + "reminder_form_schedule_label": "Calendrier des rappels", + "reminder_form_schedule_desc": "Quand devrions-nous vous rappeler ?", + "reminder_form_recurrence_type_label": "Renouvellement", + "reminder_form_recurrence_type_desc": "Ce rappel devrait-il se répéter ?", + "reminder_form_recurrence_interval_label": "Répéter tous les", + "reminder_form_recurrence_interval_desc": "Fréquence de renouvellement", + "reminder_form_recurrence_end_date_label": "Date de fin", + "reminder_form_recurrence_end_date_desc": "Quand la récurrence devrait-elle s'arrêter ? (optionnel)", + "reminder_form_note_label": "Note", + "reminder_form_note_desc": "Ajoutez plus de contexte", + "reminder_form_note_placeholder": "Détailler ce qui nécessite attention", + "reminder_form_is_completed_label": "Marquer comme terminé", + "reminder_toast_created": "Rappel créé avec succès.", + "reminder_toast_updated": "Rappel mis à jour avec succès", + "reminder_toast_error_prefix": "Erreur lors de l'enregistrement : ", + "reminder_list_empty": "Pas encore de rappels. Créez-en un pour anticiper les renouvellements.", + "reminder_list_select_vehicle": "Sélectionnez un véhicule pour voir les rappels.", + "reminder_list_select_hint": "Choisissez un véhicule ci-dessus pour charger ses rappels à venir.", + "reminder_col_due_date": "Date d'échéance", + "reminder_col_reminder_schedule": "Calendrier des rappels", + "reminder_col_recurrence": "Renouvellement", + "reminder_col_note": "Notes", + "reminder_menu_toggle_done": "Marquer comme {status}", + "reminder_menu_toggle_done_done": "Marquer comme en attente", + "reminder_menu_toggle_done_pending": "Marquer comme terminé", + "reminder_menu_edit": "Modifier", + "reminder_menu_delete": "Supprimer", + "reminder_menu_open": "Ouvrir le menu", + "reminder_menu_sheet_title": "Mettre à jour le rappel", + "reminder_tab_title": "Rappels", + "reminder_add_action": "Ajouter un rappel", + "reminder_delete_success": "Rappel supprimé.", + "reminder_delete_error": "Une erreur s'est produite lors de la suppression du rappel.", + "reminder_status_error": "Erreur lors de la mise à jour du statut du rappel.", + "reminder_toast_error_fallback": "Erreur lors de l'enregistrement du rappel.", + "reminder_status_completed": "Terminé", + "reminder_status_pending": "En attente", + "reminder_status_overdue": "En retard", + "settings_sheet_title": "Paramètres", + "settings_features_intro": "Activez ou désactivez les fonctionnalités pour personnaliser votre expérience", + "feature_label_fuel": "Journal du carburant", + "feature_desc_fuel": "Suivi et gestion de la consommation de carburant et de l'historique de ravitaillement", + "feature_label_maintenance": "Maintenance", + "feature_desc_maintenance": "Enregistrez et planifiez les activités de maintenance des véhicules", + "feature_label_pollution": "Pollution", + "feature_desc_pollution": "Gérer les enregistrements du certificat de lutte contre la pollution", + "feature_label_reminders": "Rappels", + "feature_desc_reminders": "Définissez et recevez des rappels pour les événements importants du véhicule", + "feature_label_insurance": "Assurance", + "feature_desc_insurance": "Gérer les détails d'assurance du véhicule et les renouvellements", + "feature_label_overview": "Aperçu", + "feature_desc_overview": "Afficher le tableau de bord d'aperçu avec les métriques clés du véhicule", + "profile_menu_item": "Profil", + "profile_sheet_title": "Profil", + "profile_sheet_desc": "Mettez à jour votre nom d'utilisateur et votre mot de passe", + "profile_username": "Nom d'utilisateur", + "profile_username_desc": "Votre nom d'affichage", + "profile_password_hint": "Laissez les champs de mot de passe vides pour conserver votre mot de passe actuel", + "profile_current_password": "Mot de passe actuel", + "profile_current_password_desc": "Requis pour changer le mot de passe", + "profile_new_password": "Nouveau mot de passe", + "profile_new_password_desc": "Minimum 6 caractères", + "profile_confirm_password": "Confirmer le mot de passe", + "profile_confirm_password_desc": "Saisissez à nouveau votre nouveau mot de passe", + "profile_update_button": "Mettre à jour le profil", + "tools_menu": "Outils", + "data_export_import_menu_item": "Exporter/Importer les données", + "data_export_import_sheet_title": "Exportation/Importation de données", + "data_export_import_sheet_desc": "Exportez ou importez votre base de données avec chiffrement facultatif", + "logout_menu_item": "Déconnexion", + "nav_overview": "Aperçu", + "nav_fuel_logs": "Journaux de carburant", + "nav_maintenance": "Maintenance", + "nav_insurance": "Assurance", + "nav_pollution": "Pollution", + "nav_reminders": "Rappels", + "custom_fields_label": "Champs personnalisés", + "custom_fields_add_button": "Ajouter un champ", + "custom_fields_name_placeholder": "Nom du champ", + "custom_fields_value_placeholder": "Valeur du champ", + "custom_fields_remove_aria": "Supprimer le champ", + "custom_fields_empty_message": "Aucun champ personnalisé ajouté. Cliquez sur \"Ajouter un champ\" pour commencer.", + "vehicle_details_vin": "NIV", + "vehicle_details_not_specified": "Non spécifié", + "vehicle_details_section_title": "Détails", + "vehicle_details_license_plate": "Plaque d'immatriculation", + "vehicle_details_fuel_type": "Type de carburant", + "vehicle_details_odometer": "Odomètre", + "vehicle_details_not_recorded": "Non enregistré", + "vehicle_details_color": "Couleur", + "vehicle_details_year": "Année", + "fuel_type_diesel": "Diesel", + "fuel_type_petrol": "Essence", + "fuel_type_ev": "Électrique (VE)", + "reminder_schedule_same_day": "À la date d'échéance", + "reminder_schedule_one_day_before": "1 jour avant", + "reminder_schedule_three_days_before": "3 jours avant", + "reminder_schedule_one_week_before": "1 semaine avant", + "reminder_schedule_one_month_before": "1 mois avant", + "recurrence_type_none": "Aucune récurrence", + "recurrence_type_daily": "Quotidien", + "recurrence_type_weekly": "Hebdomadaire", + "recurrence_type_monthly": "Mensuel", + "recurrence_type_yearly": "Annuel", + "recurrence_every": "tous les", + "recurrence_renew_every": "Renouveler tous les", + "recurrence_interval_days": "jours", + "recurrence_interval_weeks": "semaines", + "recurrence_interval_months": "mois", + "recurrence_interval_years": "ans", + "recurrence_until": "Jusqu'au", + "insurance_recurrence_type_fixed": "Date de fin fixe", + "insurance_recurrence_type_yearly": "Se renouvelle annuellement", + "insurance_recurrence_type_monthly": "Se renouvelle mensuellement", + "insurance_recurrence_type_no_end": "Pas de date de fin", + "pollution_recurrence_type_fixed": "Date de fin fixe", + "pollution_recurrence_type_yearly": "Se renouvelle annuellement", + "pollution_recurrence_type_monthly": "Se renouvelle mensuellement", + "pollution_recurrence_type_no_end": "Pas de date de fin" +} diff --git a/messages/hi.json b/messages/hi.json new file mode 100644 index 00000000..70479c91 --- /dev/null +++ b/messages/hi.json @@ -0,0 +1,440 @@ +{ + "$schema": "https://inlang.com/schema/inlang-message-format", + "hello_world": "Hello, {name} from hi!", + "app_title": "आपका गैराज", + "app_add_vehicle": "वाहन जोड़ें", + "app_empty_select_message": "विवरण देखने के लिए एक वाहन चुनें", + "app_empty_select_hint": "डैशबोर्ड लोड करने के लिए ऊपर से एक वाहन चुनें।", + "demo_banner": "यह एक डेमो इंस्टेंस है। डेटा समय-समय पर रीसेट किया जाएगा और स्थायी रूप से सहेजा नहीं जाएगा। कृपया कोई व्यक्तिगत जानकारी जोड़ने से बचें।", + "default_login": "डिफ़ॉल्ट लॉगिन: demo / demo", + "settings_tab_personalization": "व्यक्तिकरण", + "settings_tab_interface": "इंटरफ़ेस", + "settings_tab_features": "फ़ीचर्स", + "settings_label_date_format": "तिथि प्रारूप", + "settings_label_locale": "भाषा", + "settings_label_timezone": "समय क्षेत्र", + "settings_label_currency": "मुद्रा", + "settings_label_unit_distance": "दूरी की इकाई", + "settings_label_unit_volume": "आयतन की इकाई", + "settings_label_theme": "थीम", + "settings_label_custom_css": "कस्टम CSS", + "settings_update_button": "सेटिंग्स अपडेट करें", + "settings_select_unit_system": "यूनिट सिस्टम चुनें", + "settings_select_theme": "थीम चुनें", + "settings_desc_date_format": "अपना पसंदीदा तिथि प्रारूप चुनें", + "settings_desc_locale": "इंटरफ़ेस की भाषा चुनें", + "settings_desc_timezone": "दिनांक प्रदर्शन के लिए अपना समय क्षेत्र चुनें", + "settings_desc_currency": "अपनी पसंदीदा मुद्रा चुनें", + "settings_desc_unit_distance": "दूरी माप की इकाई", + "settings_desc_unit_volume": "आयतन माप की इकाई", + "settings_desc_theme": "अपनी पसंदीदा थीम चुनें", + "settings_desc_custom_css": "इंटरफ़ेस को कस्टमाइज़ करने के लिए CSS स्टाइल्स", + "settings_select_language": "भाषा चुनें", + "settings_updated_success": "कॉन्फ़िगरेशन सफलतापूर्वक अपडेट हुआ!", + "common_example_prefix": "उदाहरण - ", + "common_invalid_format": "अमान्य प्रारूप...", + "common_kilometer": "किलोमीटर", + "common_mile": "मील", + "common_litre": "लीटर", + "common_gallon": "गैलन", + "common_submit": "सबमिट", + "common_yes": "हाँ", + "common_no": "नहीं", + "common_cancel": "रद्द करें", + "common_continue": "जारी रखें", + "common_skip": "छोड़ें", + "delete_dialog_title": "हटाएँ", + "delete_dialog_message": "क्या आप वाकई हटाना चाहते हैं?", + "common_select_column": "कॉलम चुनें", + "common_import": "आयात करें", + "nav_overview": "ओवरव्यू", + "nav_fuel_logs": "फ्यूल लॉग्स", + "nav_maintenance": "मेंटेनेंस", + "nav_insurance": "बीमा", + "nav_pollution": "प्रदूषण प्रमाणपत्र", + "nav_reminders": "रिमाइंडर्स", + "tools_export_data": "डेटा निर्यात", + "tools_import_data": "डेटा आयात", + "vehicle_form_make_label": "निर्माता", + "vehicle_form_make_desc": "वाहन का निर्माता", + "vehicle_form_model_label": "मॉडल", + "vehicle_form_model_desc": "वाहन का मॉडल", + "vehicle_form_year_label": "वर्ष", + "vehicle_form_year_desc": "निर्माण वर्ष", + "vehicle_form_color_label": "रंग", + "vehicle_form_color_desc": "वाहन का रंग", + "vehicle_form_fuel_type_label": "ईंधन प्रकार", + "vehicle_form_fuel_type_desc": "वाहन में उपयोग होने वाला ईंधन", + "vehicle_form_fuel_type_placeholder": "ईंधन प्रकार चुनें", + "vehicle_form_odometer_label": "ओडोमीटर", + "vehicle_form_odometer_desc": "वर्तमान ओडोमीटर रीडिंग", + "vehicle_form_license_label": "लाइसेंस प्लेट", + "vehicle_form_license_desc": "वाहन का पंजीकरण नंबर", + "vehicle_form_vin_label": "VIN", + "vehicle_form_vin_desc": "वाहन पहचान संख्या", + "vehicle_toast_saved": "वाहन सफलतापूर्वक सहेजा गया", + "vehicle_toast_updated": "वाहन सफलतापूर्वक अपडेट हुआ", + "vehicle_toast_error_prefix": "सेव करते समय त्रुटि: ", + "vehicle_list_empty": "यहाँ कुछ नहीं है। शुरू करने के लिए अपना पहला वाहन जोड़ें।", + "vehicle_delete_success": "वाहन सफलतापूर्वक हटाया गया।", + "vehicle_delete_error": "वाहन हटाते समय कोई त्रुटि हुई।", + "vehicle_action_add_fuel_log": "फ्यूल लॉग जोड़ें", + "vehicle_action_add_maintenance_log": "मेंटेनेंस लॉग जोड़ें", + "vehicle_action_add_insurance": "बीमा जोड़ें", + "vehicle_action_add_pollution": "प्रदूषण प्रमाणपत्र जोड़ें", + "vehicle_action_add_reminder": "रिमाइंडर जोड़ें", + "vehicle_action_more_info": "अधिक जानकारी", + "vehicle_action_update_vehicle": "वाहन अपडेट करें", + "vehicle_action_edit": "संपादित करें", + "vehicle_action_delete": "हटाएँ", + "tools_export_encrypt_label": "निर्यात डेटा एन्क्रिप्ट करें", + "tools_export_password_label": "एन्क्रिप्शन पासवर्ड", + "tools_export_password_placeholder": "एन्क्रिप्शन के लिए पासवर्ड दर्ज करें", + "tools_export_password_hint": "इस पासवर्ड को सुरक्षित रखें - आयात के समय डिक्रिप्ट करने के लिए यही चाहिए होगा।", + "tools_export_status_exporting": "निर्यात हो रहा है...", + "tools_export_button": "डेटाबेस निर्यात", + "tools_export_info_title": "निर्यात जानकारी", + "tools_export_info_bullet_1": "सभी डेटाबेस टेबल्स और डेटा निर्यात करता है", + "tools_export_info_bullet_2": "वाहन, फ्यूल लॉग, मेंटेनेंस रिकॉर्ड आदि शामिल", + "tools_export_info_bullet_3": "संवेदनशील डेटा की सुरक्षा हेतु वैकल्पिक एन्क्रिप्शन", + "tools_export_info_bullet_4": "JSON फ़ाइल के रूप में डाउनलोड", + "tools_export_success": "डेटा सफलतापूर्वक निर्यात हुआ", + "tools_export_error": "डेटा निर्यात करने में विफल", + "tools_import_upload_label": "JSON फ़ाइल अपलोड करें", + "tools_import_paste_label": "या JSON डेटा पेस्ट करें", + "tools_import_paste_placeholder": "यहाँ अपना निर्यात किया हुआ JSON डेटा पेस्ट करें...", + "tools_import_password_label": "डिक्रिप्शन पासवर्ड (यदि एन्क्रिप्टेड हो)", + "tools_import_password_placeholder": "यदि डेटा एन्क्रिप्टेड है तो पासवर्ड दर्ज करें", + "tools_import_status_importing": "आयात हो रहा है...", + "tools_import_button": "डेटाबेस आयात", + "tools_import_warning_title": "⚠️ आयात चेतावनी", + "tools_import_warning_bullet_1": "यह सभी मौजूदा डेटा को बदल देगा", + "tools_import_warning_bullet_2": "पहले वर्तमान डेटा का बैकअप सुनिश्चित करें", + "tools_import_warning_bullet_3": "आयात वापस नहीं लिया जा सकता", + "tools_import_warning_bullet_4": "सुनिश्चित करें कि JSON प्रारूप सही है", + "tools_import_success": "डेटा सफलतापूर्वक आयात हुआ", + "tools_import_error": "डेटा आयात करने में विफल", + "tools_import_invalid_json": "अमान्य JSON प्रारूप", + "feature_overview_disabled_title": "ओवरव्यू फीचर निष्क्रिय", + "feature_overview_disabled_hint": "ओवरव्यू डैशबोर्ड देखने के लिए सेटिंग्स में इस फीचर को सक्षम करें", + "feature_fuel_disabled_title": "फ्यूल लॉग फीचर निष्क्रिय", + "feature_fuel_disabled_hint": "फ्यूल खपत को ट्रैक करने के लिए सेटिंग्स में सक्षम करें", + "feature_maintenance_disabled_title": "मेंटेनेंस फीचर निष्क्रिय", + "feature_maintenance_disabled_hint": "मेंटेनेंस रिकॉर्ड प्रबंधित करने के लिए सेटिंग्स में सक्षम करें", + "feature_pucc_disabled_title": "PUCC फीचर निष्क्रिय", + "feature_pucc_disabled_hint": "प्रदूषण प्रमाणपत्र प्रबंधित करने के लिए सेटिंग्स में सक्षम करें", + "feature_reminders_disabled_title": "रिमाइंडर्स फीचर निष्क्रिय", + "feature_reminders_disabled_hint": "वाहन रिमाइंडर्स प्रबंधित करने के लिए सेटिंग्स में सक्षम करें", + "feature_insurance_disabled_title": "इंश्योरेंस फीचर निष्क्रिय", + "feature_insurance_disabled_hint": "बीमा विवरण प्रबंधित करने के लिए सेटिंग्स में सक्षम करें", + "overview_chart_no_data": "डेटा उपलब्ध नहीं", + "overview_chart_cost_label": "खर्च", + "overview_chart_cost_title": "समय के साथ खर्च ({currency})", + "overview_chart_mileage_label": "माइलेज", + "overview_chart_mileage_title": "समय के साथ माइलेज ({unit})", + "fuel_import_title": "फ्यूल लॉग आयात करें", + "fuel_add_title": "फ्यूल लॉग जोड़ें", + "col_date": "तिथि", + "col_odometer": "ओडोमीटर", + "col_filled": "भराव", + "col_missed_last": "पिछला छूटा", + "col_fuel_amount": "ईंधन मात्रा", + "col_cost": "खर्च", + "col_mileage": "माइलेज", + "col_notes": "नोट्स", + "col_attachment": "संलग्नक", + "col_no_end_date": "कोई अंतिम तारीख नहीं", + "fuel_volume_label_fuel": "ईंधन मात्रा", + "fuel_volume_label_energy": "ऊर्जा", + "fuel_empty_list": "इस वाहन के लिए कोई फ्यूल लॉग नहीं मिला।", + "form_date": "तिथि", + "form_date_desc": "फ्यूल रिफिल की तिथि", + "form_odometer": "ओडोमीटर", + "form_odometer_desc": "वर्तमान ओडोमीटर रीडिंग", + "form_volume_fuel": "ईंधन की मात्रा", + "form_volume_energy": "खपत ऊर्जा", + "form_cost": "खर्च", + "form_cost_desc": "रिफिल की लागत", + "form_cost_desc_ev": "चार्जिंग की लागत", + "form_full_charge": "पूर्ण चार्ज", + "form_full_tank": "फुल टैंक", + "form_full_charge_desc": "क्या बैटरी पूरी तरह चार्ज है?", + "form_full_tank_desc": "क्या टैंक पूरी तरह भरा है?", + "form_missed_last": "पिछला छूटा", + "form_missed_last_desc": "क्या पिछली प्रविष्टियाँ छूटीं?", + "form_notes": "नोट्स", + "form_notes_placeholder": "अधिक विवरण जोड़ें, यदि कोई हो...", + "form_attachment": "संलग्नक", + "fuel_toast_saved": "फ्यूल लॉग सफलतापूर्वक सहेजा गया...!!!", + "fuel_toast_updated": "फ्यूल लॉग सफलतापूर्वक अपडेट हुआ...!!!", + "fuel_toast_error_prefix": "सेव करते समय त्रुटि: ", + "notifications_title": "सूचनाएँ", + "notifications_new": "नया", + "notifications_select_vehicle_hint": "रिमाइंडर और अलर्ट लोड करने के लिए वाहन चुनें।", + "notifications_syncing": "नवीनतम डेटा सिंक हो रहा है...", + "notifications_caught_up": "आप पूरी तरह अपडेट हैं।", + "notifications_section_reminders": "रिमाइंडर्स", + "notifications_section_alerts": "अनुपालन अलर्ट", + "notifications_mark_done_title": "रिमाइंडर पूर्ण चिन्हित करें", + "notifications_mark_done_aria": "{type} रिमाइंडर को पूर्ण चिन्हित करें", + "notifications_overdue_days": "{days} दिन{plural} देरी", + "notifications_due_today": "आज देय", + "notifications_due_tomorrow": "कल देय", + "notifications_due_in_days": "{days} दिनों में देय", + "alerts_status_expired": "समाप्त", + "alerts_status_expiring": "शीघ्र समाप्त", + "alerts_status_valid": "सही", + "alerts_status_missing": "लापता", + "notifications_expires": "समाप्ति", + "notifications_error_no_id": "आईडी के बिना रिमाइंडर अपडेट नहीं हो सकता।", + "notifications_error_update_failed": "रिमाइंडर अपडेट विफल।", + "notifications_success_marked_done": "रिमाइंडर पूर्ण चिन्हित किया गया।", + "notifications_severity_overdue": "विलंबित", + "notifications_severity_due_soon": "जल्द देय", + "notifications_severity_upcoming": "आगामी", + "settings_custom_css_placeholder": "अपना कस्टम CSS यहाँ जोड़ें...", + "settings_features_intro": "अपना अनुभव अनुकूलित करने के लिए फीचर्स सक्षम/अक्षम करें", + "feature_label_fuel": "फ्यूल लॉग", + "feature_desc_fuel": "ईंधन खपत और रिफ्यूलिंग इतिहास ट्रैक व प्रबंधित करें", + "feature_label_maintenance": "मेंटेनेंस", + "feature_desc_maintenance": "वाहन रखरखाव गतिविधियों को रिकॉर्ड और शेड्यूल करें", + "feature_label_pucc": "प्रदूषण", + "feature_desc_pucc": "PUCC रिकॉर्ड प्रबंधित करें", + "feature_label_reminders": "रिमाइंडर्स", + "feature_desc_reminders": "महत्वपूर्ण वाहन घटनाओं के लिए रिमाइंडर सेट और प्राप्त करें", + "feature_label_insurance": "बीमा", + "feature_desc_insurance": "वाहन बीमा विवरण और नवीनीकरण प्रबंधित करें", + "feature_label_overview": "ओवरव्यू", + "feature_desc_overview": "महत्वपूर्ण वाहन मेट्रिक्स के साथ डैशबोर्ड दिखाएँ", + "settings_error_date_format_invalid": "प्रारूप मान्य नहीं", + "settings_error_timezone_invalid": "अमान्य समय क्षेत्र मान।", + "settings_error_currency_required": "मुद्रा आवश्यक है", + "maintenance_form_attachment_label": "संलग्नक", + "maintenance_form_attachment_desc": "रसीद या मेंटेनेंस दस्तावेज़ अपलोड करें", + "maintenance_form_date_label": "तिथि", + "maintenance_form_date_desc": "मेंटेनेंस तिथि", + "maintenance_form_odometer_label": "ओडोमीटर", + "maintenance_form_odometer_desc": "वर्तमान ओडोमीटर रीडिंग", + "maintenance_form_service_center_label": "सर्विस सेंटर", + "maintenance_form_service_center_desc": "सर्विस सेंटर का नाम", + "maintenance_form_cost_label": "खर्च", + "maintenance_form_cost_desc": "मेंटेनेंस की लागत", + "maintenance_form_notes_label": "नोट्स", + "maintenance_form_notes_desc": "अधिक विवरण", + "maintenance_form_notes_placeholder": "यदि कोई हो तो और विवरण जोड़ें...", + "maintenance_toast_saved": "मेंटेनेंस लॉग सफलतापूर्वक सहेजा गया", + "maintenance_toast_updated": "मेंटेनेंस लॉग सफलतापूर्वक अपडेट हुआ", + "maintenance_toast_error_prefix": "सेव करते समय त्रुटि: ", + "maintenance_form_error_fix": "सबमिट करने से पहले फॉर्म की त्रुटियाँ ठीक करें।", + "maintenance_list_empty": "इस वाहन के लिए कोई मेंटेनेंस लॉग नहीं मिला।", + "maintenance_col_service_center": "सर्विस सेंटर", + "maintenance_menu_open": "मेनू खोलें", + "maintenance_menu_edit": "संपादित करें", + "maintenance_menu_delete": "हटाएँ", + "maintenance_menu_sheet_title": "मेंटेनेंस लॉग अपडेट करें", + "maintenance_tab_title": "मेंटेनेंस इतिहास", + "maintenance_add_action": "मेंटेनेंस लॉग जोड़ें", + "maintenance_delete_success": "मेंटेनेंस लॉग हटा दिया गया।", + "maintenance_delete_error": "मेंटेनेंस लॉग हटाते समय कोई त्रुटि हुई।", + "insurance_form_provider_label": "बीमा प्रदाता", + "insurance_form_provider_desc": "बीमा कंपनी का नाम", + "insurance_form_policy_number_label": "बीमा पॉलिसी संख्या", + "insurance_form_policy_number_desc": "आपके बीमा दस्तावेज़ से पॉलिसी संख्या", + "insurance_form_start_date_label": "बीमा शुरुआत तिथि", + "insurance_form_start_date_desc": "जिस तारीख से कवरेज शुरू होता है", + "insurance_form_recurrence_type_label": "यह बीमा कैसे नवीनीकृत होना चाहिए?", + "insurance_form_recurrence_type_desc": "इस बीमा के लिए नवीनीकरण प्रकार", + "insurance_form_recurrence_interval_label": "नवीनीकरण आवृत्ति", + "insurance_form_recurrence_interval_desc": "बीमा कितनी बार नवीनीकृत होता है", + "insurance_form_end_date_label": "बीमा समाप्ति तिथि", + "insurance_form_end_date_desc": "जिस तारीख को कवरेज समाप्त होता है", + "insurance_form_cost_label": "बीमा लागत", + "insurance_form_cost_desc": "वार्षिक या पॉलिसी अवधि की लागत", + "insurance_form_notes_label": "अतिरिक्त नोट्स", + "insurance_form_notes_desc": "पॉलिसी के बारे में कोई अतिरिक्त जानकारी", + "insurance_form_notes_placeholder": "बीमा के बारे में अधिक विवरण जोड़ें...", + "insurance_form_attachment_label": "पॉलिसी दस्तावेज़", + "insurance_form_attachment_desc": "पॉलिसी दस्तावेज़ अपलोड करें", + "insurance_form_error_fix": "सबमिट करने से पहले फॉर्म की त्रुटियाँ ठीक करें।", + "insurance_toast_saved": "बीमा सफलतापूर्वक सहेजा गया", + "insurance_toast_updated": "बीमा सफलतापूर्वक अपडेट हुआ", + "insurance_toast_error_prefix": "सेव करते समय त्रुटि: ", + "insurance_list_empty": "इस वाहन के लिए कोई बीमा नहीं मिला।", + "insurance_col_policy_number": "पॉलिसी संख्या", + "insurance_col_cost": "लागत", + "insurance_col_start_date": "शुरुआत तिथि", + "insurance_col_end_date": "समाप्ति तिथि", + "insurance_col_next_due": "अगली देय तिथि", + "insurance_col_recurrence": "नवीनीकरण", + "insurance_col_notes": "नोट्स", + "insurance_col_view_document": "दस्तावेज़ देखें", + "insurance_menu_open": "मेनू खोलें", + "insurance_menu_edit": "संपादित करें", + "insurance_menu_delete": "हटाएँ", + "insurance_menu_sheet_title": "बीमा अपडेट करें", + "insurance_tab_title": "बीमा विवरण", + "insurance_add_action": "बीमा जोड़ें", + "insurance_delete_success": "बीमा हटा दिया गया।", + "insurance_delete_error": "बीमा हटाते समय कोई त्रुटि हुई।", + "pollution_form_certificate_number_label": "प्रमाणपत्र संख्या", + "pollution_form_certificate_number_desc": "प्रदूषण प्रमाणपत्र संख्या", + "pollution_form_issue_date_label": "जारी करने की तिथि", + "pollution_form_issue_date_desc": "प्रमाणपत्र जारी करने की तिथि", + "pollution_form_recurrence_type_label": "यह प्रमाणपत्र कैसे नवीनीकृत होना चाहिए?", + "pollution_form_recurrence_type_desc": "इस प्रमाणपत्र के लिए नवीनीकरण प्रकार", + "pollution_form_recurrence_interval_label": "नवीनीकरण आवृत्ति", + "pollution_form_recurrence_interval_desc": "प्रमाणपत्र कितनी बार नवीनीकृत होता है", + "pollution_form_expiry_date_label": "समाप्ति की तिथि", + "pollution_form_expiry_date_desc": "PUCC समाप्ति तिथि", + "pollution_form_testing_center_label": "परीक्षण केंद्र", + "pollution_form_testing_center_desc": "परीक्षण केंद्र का नाम", + "pollution_form_notes_label": "अतिरिक्त नोट्स", + "pollution_form_notes_desc": "कोई अतिरिक्त जानकारी", + "pollution_form_notes_placeholder": "अतिरिक्त नोट्स जोड़ें...", + "pollution_form_attachment_label": "प्रमाणपत्र दस्तावेज़", + "pollution_form_attachment_desc": "प्रमाणपत्र दस्तावेज़ अपलोड करें", + "pollution_form_error_fix": "सबमिट करने से पहले फॉर्म की त्रुटियाँ ठीक करें।", + "pollution_toast_saved": "प्रदूषण प्रमाणपत्र सफलतापूर्वक सहेजा गया", + "pollution_toast_updated": "प्रदूषण प्रमाणपत्र सफलतापूर्वक अपडेट हुआ", + "pollution_toast_error_prefix": "सेव करते समय त्रुटि: ", + "pollution_list_empty": "इस वाहन के लिए कोई प्रदूषण प्रमाणपत्र नहीं मिला।", + "pollution_col_certificate_number": "प्रमाणपत्र संख्या", + "pollution_col_issue_date": "जारी करने की तिथि", + "pollution_col_expiry_date": "समाप्ति की तिथि", + "pollution_col_next_due": "अगली देय तिथि", + "pollution_col_testing_center": "परीक्षण केंद्र", + "pollution_col_notes": "नोट्स", + "pollution_col_view_certificate": "प्रमाणपत्र देखें", + "pollution_col_recurrence": "नवीनीकरण", + "pollution_menu_open": "मेनू खोलें", + "pollution_menu_edit": "संपादित करें", + "pollution_menu_delete": "हटाएँ", + "pollution_menu_sheet_title": "प्रदूषण प्रमाणपत्र अपडेट करें", + "pollution_tab_title": "प्रदूषण प्रमाणपत्र विवरण", + "pollution_add_action": "प्रदूषण प्रमाणपत्र जोड़ें", + "pollution_delete_success": "PUCC हटा दिया गया।", + "pollution_delete_error": "PUCC हटाते समय कोई त्रुटि हुई।", + "reminder_form_due_date_label": "देय तिथि", + "reminder_form_due_date_desc": "यह रिमाइंडर कब ट्रिगर होना चाहिए?", + "reminder_form_type_label": "प्रकार", + "reminder_form_type_desc": "रिमाइंडर प्रकार चुनें", + "reminder_form_schedule_label": "रिमाइंडर शेड्यूल", + "reminder_form_schedule_desc": "हमें कब आपको रिमाइंड करना चाहिए?", + "reminder_form_recurrence_type_label": "पुनरावृत्ति", + "reminder_form_recurrence_type_desc": "क्या यह रिमाइंडर दोहराया जाना चाहिए?", + "reminder_form_recurrence_interval_label": "हर दोहराएँ", + "reminder_form_recurrence_interval_desc": "पुनरावृत्ति की आवृत्ति", + "reminder_form_recurrence_end_date_label": "समाप्ति तिथि", + "reminder_form_recurrence_end_date_desc": "पुनरावृत्ति कब रुकनी चाहिए? (वैकल्पिक)", + "reminder_form_note_label": "नोट", + "reminder_form_note_desc": "अधिक संदर्भ जोड़ें", + "reminder_form_note_placeholder": "उस विवरण के साथ यह क्या चाहिए", + "reminder_form_is_completed_label": "पूर्ण के रूप में चिह्नित करें", + "reminder_toast_created": "रिमाइंडर सफलतापूर्वक बनाया गया।", + "reminder_toast_updated": "रिमाइंडर सफलतापूर्वक अपडेट हुआ", + "reminder_toast_error_prefix": "सेव करते समय त्रुटि: ", + "reminder_list_empty": "अभी कोई रिमाइंडर नहीं। आने वाले नवीनीकरण से आगे रहने के लिए एक बनाएं।", + "reminder_list_select_vehicle": "रिमाइंडर देखने के लिए वाहन चुनें।", + "reminder_list_select_hint": "आने वाले रिमाइंडर लोड करने के लिए ऊपर एक वाहन चुनें।", + "reminder_col_due_date": "देय तिथि", + "reminder_col_reminder_schedule": "रिमाइंडर शेड्यूल", + "reminder_col_recurrence": "पुनरावृत्ति", + "reminder_col_note": "नोट्स", + "reminder_menu_toggle_done": "इस रूप में चिह्नित करें {status}", + "reminder_menu_toggle_done_done": "लंबित के रूप में चिह्नित करें", + "reminder_menu_toggle_done_pending": "पूर्ण के रूप में चिह्नित करें", + "reminder_menu_edit": "संपादित करें", + "reminder_menu_delete": "हटाएँ", + "reminder_menu_open": "मेनू खोलें", + "reminder_menu_sheet_title": "रिमाइंडर अपडेट करें", + "reminder_tab_title": "रिमाइंडर्स", + "reminder_add_action": "रिमाइंडर जोड़ें", + "reminder_delete_success": "रिमाइंडर हटा दिया गया।", + "reminder_delete_error": "रिमाइंडर हटाते समय कोई त्रुटि हुई।", + "reminder_status_error": "रिमाइंडर स्थिति अपडेट करते समय त्रुटि।", + "reminder_toast_error_fallback": "रिमाइंडर सेव करते समय त्रुटि।", + "reminder_status_completed": "पूर्ण", + "reminder_status_pending": "लंबित", + "reminder_status_overdue": "अतिदेय", + "settings_sheet_title": "सेटिंग्स", + "settings_features_intro": "अपने अनुभव को अनुकूलित करने के लिए सुविधाओं को सक्षम या अक्षम करें", + "feature_label_fuel": "ईंधन लॉग", + "feature_desc_fuel": "ईंधन की खपत और ईंधन भरने के इतिहास को ट्रैक और प्रबंधित करें", + "feature_label_maintenance": "रखरखाव", + "feature_desc_maintenance": "वाहन रखरखाव गतिविधियों को दर्ज और शेड्यूल करें", + "feature_label_pollution": "प्रदूषण", + "feature_desc_pollution": "प्रदूषण नियंत्रण प्रमाण पत्र रिकॉर्ड प्रबंधित करें", + "feature_label_reminders": "रिमाइंडर्स", + "feature_desc_reminders": "महत्वपूर्ण वाहन घटनाओं के लिए रिमाइंडर सेट करें और प्राप्त करें", + "feature_label_insurance": "बीमा", + "feature_desc_insurance": "वाहन बीमा विवरण और नवीकरण प्रबंधित करें", + "feature_label_overview": "अवलोकन", + "feature_desc_overview": "मुख्य वाहन मेट्रिक्स के साथ अवलोकन डैशबोर्ड प्रदर्शित करें", + "profile_menu_item": "प्रोफ़ाइल", + "profile_sheet_title": "प्रोफ़ाइल", + "profile_sheet_desc": "अपना उपयोगकर्ता नाम और पासवर्ड अपडेट करें", + "profile_username": "उपयोगकर्ता नाम", + "profile_username_desc": "आपका प्रदर्शन नाम", + "profile_password_hint": "अपना वर्तमान पासवर्ड रखने के लिए पासवर्ड फ़ील्ड खाली छोड़ दें", + "profile_current_password": "वर्तमान पासवर्ड", + "profile_current_password_desc": "पासवर्ड बदलने के लिए आवश्यक", + "profile_new_password": "नया पासवर्ड", + "profile_new_password_desc": "न्यूनतम 6 वर्ण", + "profile_confirm_password": "पासवर्ड की पुष्टि करें", + "profile_confirm_password_desc": "अपना नया पासवर्ड पुनः दर्ज करें", + "profile_update_button": "प्रोफ़ाइल अपडेट करें", + "tools_menu": "उपकरण", + "data_export_import_menu_item": "डेटा निर्यात/आयात करें", + "data_export_import_sheet_title": "डेटा निर्यात/आयात", + "data_export_import_sheet_desc": "वैकल्पिक एन्क्रिप्शन के साथ अपने डेटाबेस को निर्यात या आयात करें", + "logout_menu_item": "लॉगआउट", + "nav_overview": "अवलोकन", + "nav_fuel_logs": "ईंधन लॉग", + "nav_maintenance": "रखरखाव", + "nav_insurance": "बीमा", + "nav_pollution": "प्रदूषण", + "nav_reminders": "रिमाइंडर्स", + "custom_fields_label": "कस्टम फ़ील्ड", + "custom_fields_add_button": "फ़ील्ड जोड़ें", + "custom_fields_name_placeholder": "फ़ील्ड का नाम", + "custom_fields_value_placeholder": "फ़ील्ड मूल्य", + "custom_fields_remove_aria": "फ़ील्ड हटाएं", + "custom_fields_empty_message": "कोई कस्टम फ़ील्ड नहीं जोड़े गए। शुरू करने के लिए \"फ़ील्ड जोड़ें\" पर क्लिक करें।", + "vehicle_details_vin": "VIN", + "vehicle_details_not_specified": "निर्दिष्ट नहीं", + "vehicle_details_section_title": "विवरण", + "vehicle_details_license_plate": "लाइसेंस प्लेट", + "vehicle_details_fuel_type": "ईंधन प्रकार", + "vehicle_details_odometer": "ओडोमीटर", + "vehicle_details_not_recorded": "दर्ज नहीं", + "vehicle_details_color": "रंग", + "vehicle_details_year": "वर्ष", + "fuel_type_diesel": "डीजल", + "fuel_type_petrol": "पेट्रोल", + "fuel_type_ev": "इलेक्ट्रिक (EV)", + "reminder_schedule_same_day": "नियत तारीख पर", + "reminder_schedule_one_day_before": "1 दिन पहले", + "reminder_schedule_three_days_before": "3 दिन पहले", + "reminder_schedule_one_week_before": "1 सप्ताह पहले", + "reminder_schedule_one_month_before": "1 महीना पहले", + "recurrence_type_none": "कोई पुनरावृत्ति नहीं", + "recurrence_type_daily": "दैनिक", + "recurrence_type_weekly": "साप्ताहिक", + "recurrence_type_monthly": "मासिक", + "recurrence_type_yearly": "वार्षिक", + "recurrence_every": "हर", + "recurrence_renew_every": "हर बार नवीनीकरण करें", + "recurrence_interval_days": "दिन", + "recurrence_interval_weeks": "सप्ताह", + "recurrence_interval_months": "महीने", + "recurrence_interval_years": "वर्ष", + "recurrence_until": "तक", + "insurance_recurrence_type_fixed": "निश्चित समाप्ति तिथि", + "insurance_recurrence_type_yearly": "वार्षिक नवीनीकरण", + "insurance_recurrence_type_monthly": "मासिक नवीनीकरण", + "insurance_recurrence_type_no_end": "कोई समाप्ति तिथि नहीं", + "pollution_recurrence_type_fixed": "निश्चित समाप्ति तिथि", + "pollution_recurrence_type_yearly": "वार्षिक नवीनीकरण", + "pollution_recurrence_type_monthly": "मासिक नवीनीकरण", + "pollution_recurrence_type_no_end": "कोई समाप्ति तिथि नहीं" +} diff --git a/migrations/20251219101830_adding-configs.sql b/migrations/20251219101830_adding-configs.sql new file mode 100644 index 00000000..bb3e8f6a --- /dev/null +++ b/migrations/20251219101830_adding-configs.sql @@ -0,0 +1,14 @@ +-- Custom SQL migration file, put your code below! -- +INSERT into `configs` values ('customCss','','Custom CSS for the application', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); +--> statement-breakpoint +INSERT INTO `configs` VALUES ('featureFuelLog','true','Enable/Disable Fuel Log feature', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); +--> statement-breakpoint +INSERT INTO `configs` VALUES ('featureMaintenance','true','Enable/Disable Maintenance feature', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); +--> statement-breakpoint +INSERT INTO `configs` VALUES ('featurePucc','true','Enable/Disable PUCC feature', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); +--> statement-breakpoint +INSERT INTO `configs` VALUES ('featureReminders','true','Enable/Disable Reminders feature', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); +--> statement-breakpoint +INSERT INTO `configs` VALUES ('featureInsurance','true','Enable/Disable Insurance feature', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); +--> statement-breakpoint +INSERT INTO `configs` VALUES ('featureOverview','true','Enable/Disable Overview feature', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP); diff --git a/migrations/20251220051351_adding-custom-fields.sql b/migrations/20251220051351_adding-custom-fields.sql new file mode 100644 index 00000000..916d3989 --- /dev/null +++ b/migrations/20251220051351_adding-custom-fields.sql @@ -0,0 +1,2 @@ +-- Add custom_fields column to vehicles table +ALTER TABLE vehicles ADD COLUMN custom_fields TEXT; diff --git a/migrations/20251228111609_adding-recurring-end-dates.sql b/migrations/20251228111609_adding-recurring-end-dates.sql new file mode 100644 index 00000000..58b84609 --- /dev/null +++ b/migrations/20251228111609_adding-recurring-end-dates.sql @@ -0,0 +1,102 @@ +-- Add recurrence fields to insurances and Make end_date nullable in insurances + +PRAGMA foreign_keys=OFF; + +--> statement-breakpoint +CREATE TABLE insurances_new ( + id TEXT PRIMARY KEY, + vehicle_id TEXT NOT NULL REFERENCES vehicles(id) ON DELETE CASCADE, + provider TEXT NOT NULL, + policy_number TEXT NOT NULL, + start_date TEXT NOT NULL, + end_date TEXT, -- now nullable + recurrence_type TEXT NOT NULL DEFAULT 'none', + recurrence_interval INTEGER NOT NULL DEFAULT 1, + cost REAL NOT NULL, + notes TEXT, + attachment TEXT, + created_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), + updated_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP) +); +--> statement-breakpoint +INSERT INTO insurances_new ( + id, vehicle_id, provider, policy_number, start_date, end_date, + recurrence_type, recurrence_interval, cost, notes, attachment, + created_at, updated_at +) +SELECT + id, vehicle_id, provider, policy_number, start_date, end_date, + 'none', 1, cost, notes, attachment, + created_at, updated_at +FROM insurances; +--> statement-breakpoint +DROP TABLE insurances; +--> statement-breakpoint +ALTER TABLE insurances_new RENAME TO insurances; +--> statement-breakpoint + +-- Make expiry_date nullable in pollution_certificates +CREATE TABLE pollution_certificates_new ( + id TEXT PRIMARY KEY, + vehicle_id TEXT NOT NULL REFERENCES vehicles(id) ON DELETE CASCADE, + certificate_number TEXT NOT NULL, + issue_date TEXT NOT NULL, + expiry_date TEXT, -- now nullable + recurrence_type TEXT NOT NULL DEFAULT 'none', + recurrence_interval INTEGER NOT NULL DEFAULT 1, + testing_center TEXT NOT NULL, + notes TEXT, + attachment TEXT, + created_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), + updated_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP) +); +--> statement-breakpoint +INSERT INTO pollution_certificates_new ( + id, vehicle_id, certificate_number, issue_date, expiry_date, + recurrence_type, recurrence_interval, testing_center, notes, + attachment, created_at, updated_at +) +SELECT + id, vehicle_id, certificate_number, issue_date, expiry_date, + 'none', 1, testing_center, notes, + attachment, created_at, updated_at +FROM pollution_certificates; +--> statement-breakpoint +DROP TABLE pollution_certificates; +--> statement-breakpoint +ALTER TABLE pollution_certificates_new RENAME TO pollution_certificates; +--> statement-breakpoint + +-- Add recurrence_end_date to reminders +CREATE TABLE reminders_new ( + id TEXT PRIMARY KEY, + vehicle_id TEXT NOT NULL REFERENCES vehicles(id) ON DELETE CASCADE, + type TEXT NOT NULL, + due_date TEXT NOT NULL, + remind_schedule TEXT NOT NULL, + recurrence_type TEXT NOT NULL DEFAULT 'none', + recurrence_interval INTEGER NOT NULL DEFAULT 1, + recurrence_end_date TEXT, -- nullable end date + note TEXT, + is_completed INTEGER NOT NULL DEFAULT 0, + created_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP), + updated_at TEXT NOT NULL DEFAULT (CURRENT_TIMESTAMP) +); +--> statement-breakpoint +INSERT INTO reminders_new ( + id, vehicle_id, type, due_date, remind_schedule, + recurrence_type, recurrence_interval, recurrence_end_date, + note, is_completed, created_at, updated_at +) +SELECT + id, vehicle_id, type, due_date, remind_schedule, + 'none', 1, NULL, + note, is_completed, created_at, updated_at +FROM reminders; +--> statement-breakpoint +DROP TABLE reminders; +--> statement-breakpoint +ALTER TABLE reminders_new RENAME TO reminders; +--> statement-breakpoint + +PRAGMA foreign_keys=ON; \ No newline at end of file diff --git a/migrations/meta/20251219101830_snapshot.json b/migrations/meta/20251219101830_snapshot.json new file mode 100644 index 00000000..25921c71 --- /dev/null +++ b/migrations/meta/20251219101830_snapshot.json @@ -0,0 +1,637 @@ +{ + "id": "a5f718c5-5da1-4eda-b7eb-06e7c8f5438e", + "prevId": "784d9213-14d7-4b45-88d5-2cb4ce8b063f", + "version": "6", + "dialect": "sqlite", + "tables": { + "auth": { + "name": "auth", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "hash": { + "name": "hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "config": { + "name": "config", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "fuel_logs": { + "name": "fuel_logs", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "date": { + "name": "date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "odometer": { + "name": "odometer", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "fuel_amount": { + "name": "fuel_amount", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cost": { + "name": "cost", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filled": { + "name": "filled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "missed_last": { + "name": "missed_last", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "fuel_logs_vehicle_id_vehicles_id_fk": { + "name": "fuel_logs_vehicle_id_vehicles_id_fk", + "tableFrom": "fuel_logs", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "insurances": { + "name": "insurances", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "policy_number": { + "name": "policy_number", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "start_date": { + "name": "start_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "end_date": { + "name": "end_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cost": { + "name": "cost", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "insurances_vehicle_id_vehicles_id_fk": { + "name": "insurances_vehicle_id_vehicles_id_fk", + "tableFrom": "insurances", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "maintenance_logs": { + "name": "maintenance_logs", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "date": { + "name": "date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "odometer": { + "name": "odometer", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "service_center": { + "name": "service_center", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cost": { + "name": "cost", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "maintenance_logs_vehicle_id_vehicles_id_fk": { + "name": "maintenance_logs_vehicle_id_vehicles_id_fk", + "tableFrom": "maintenance_logs", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "pollution_certificates": { + "name": "pollution_certificates", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "certificate_number": { + "name": "certificate_number", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "issue_date": { + "name": "issue_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expiry_date": { + "name": "expiry_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "testing_center": { + "name": "testing_center", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "pollution_certificates_vehicle_id_vehicles_id_fk": { + "name": "pollution_certificates_vehicle_id_vehicles_id_fk", + "tableFrom": "pollution_certificates", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "reminders": { + "name": "reminders", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "due_date": { + "name": "due_date", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "remind_schedule": { + "name": "remind_schedule", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_completed": { + "name": "is_completed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "reminders_vehicle_id_vehicles_id_fk": { + "name": "reminders_vehicle_id_vehicles_id_fk", + "tableFrom": "reminders", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "vehicles": { + "name": "vehicles", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "make": { + "name": "make", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "license_plate": { + "name": "license_plate", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vin": { + "name": "vin", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "odometer": { + "name": "odometer", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/migrations/meta/20251220051351_snapshot.json b/migrations/meta/20251220051351_snapshot.json new file mode 100644 index 00000000..e68c27f2 --- /dev/null +++ b/migrations/meta/20251220051351_snapshot.json @@ -0,0 +1,637 @@ +{ + "id": "c9b90cca-f079-43a8-a3c7-1a7b7cc45123", + "prevId": "a5f718c5-5da1-4eda-b7eb-06e7c8f5438e", + "version": "6", + "dialect": "sqlite", + "tables": { + "auth": { + "name": "auth", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "hash": { + "name": "hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "config": { + "name": "config", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "fuel_logs": { + "name": "fuel_logs", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "date": { + "name": "date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "odometer": { + "name": "odometer", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "fuel_amount": { + "name": "fuel_amount", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cost": { + "name": "cost", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filled": { + "name": "filled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "missed_last": { + "name": "missed_last", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "fuel_logs_vehicle_id_vehicles_id_fk": { + "name": "fuel_logs_vehicle_id_vehicles_id_fk", + "tableFrom": "fuel_logs", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "insurances": { + "name": "insurances", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "policy_number": { + "name": "policy_number", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "start_date": { + "name": "start_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "end_date": { + "name": "end_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cost": { + "name": "cost", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "insurances_vehicle_id_vehicles_id_fk": { + "name": "insurances_vehicle_id_vehicles_id_fk", + "tableFrom": "insurances", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "maintenance_logs": { + "name": "maintenance_logs", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "date": { + "name": "date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "odometer": { + "name": "odometer", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "service_center": { + "name": "service_center", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cost": { + "name": "cost", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "maintenance_logs_vehicle_id_vehicles_id_fk": { + "name": "maintenance_logs_vehicle_id_vehicles_id_fk", + "tableFrom": "maintenance_logs", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "pollution_certificates": { + "name": "pollution_certificates", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "certificate_number": { + "name": "certificate_number", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "issue_date": { + "name": "issue_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expiry_date": { + "name": "expiry_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "testing_center": { + "name": "testing_center", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "pollution_certificates_vehicle_id_vehicles_id_fk": { + "name": "pollution_certificates_vehicle_id_vehicles_id_fk", + "tableFrom": "pollution_certificates", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "reminders": { + "name": "reminders", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "due_date": { + "name": "due_date", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "remind_schedule": { + "name": "remind_schedule", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_completed": { + "name": "is_completed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "reminders_vehicle_id_vehicles_id_fk": { + "name": "reminders_vehicle_id_vehicles_id_fk", + "tableFrom": "reminders", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "vehicles": { + "name": "vehicles", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "make": { + "name": "make", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "license_plate": { + "name": "license_plate", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vin": { + "name": "vin", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "odometer": { + "name": "odometer", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/migrations/meta/20251228111609_snapshot.json b/migrations/meta/20251228111609_snapshot.json new file mode 100644 index 00000000..5305f73a --- /dev/null +++ b/migrations/meta/20251228111609_snapshot.json @@ -0,0 +1,637 @@ +{ + "id": "8ab3b73d-040d-4a3f-8e50-d973d972b6d8", + "prevId": "c9b90cca-f079-43a8-a3c7-1a7b7cc45123", + "version": "6", + "dialect": "sqlite", + "tables": { + "auth": { + "name": "auth", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "hash": { + "name": "hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "config": { + "name": "config", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "fuel_logs": { + "name": "fuel_logs", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "date": { + "name": "date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "odometer": { + "name": "odometer", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "fuel_amount": { + "name": "fuel_amount", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cost": { + "name": "cost", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filled": { + "name": "filled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "missed_last": { + "name": "missed_last", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "fuel_logs_vehicle_id_vehicles_id_fk": { + "name": "fuel_logs_vehicle_id_vehicles_id_fk", + "tableFrom": "fuel_logs", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "insurances": { + "name": "insurances", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "policy_number": { + "name": "policy_number", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "start_date": { + "name": "start_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "end_date": { + "name": "end_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cost": { + "name": "cost", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "insurances_vehicle_id_vehicles_id_fk": { + "name": "insurances_vehicle_id_vehicles_id_fk", + "tableFrom": "insurances", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "maintenance_logs": { + "name": "maintenance_logs", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "date": { + "name": "date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "odometer": { + "name": "odometer", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "service_center": { + "name": "service_center", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cost": { + "name": "cost", + "type": "real", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "maintenance_logs_vehicle_id_vehicles_id_fk": { + "name": "maintenance_logs_vehicle_id_vehicles_id_fk", + "tableFrom": "maintenance_logs", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "pollution_certificates": { + "name": "pollution_certificates", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "certificate_number": { + "name": "certificate_number", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "issue_date": { + "name": "issue_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "expiry_date": { + "name": "expiry_date", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "testing_center": { + "name": "testing_center", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "pollution_certificates_vehicle_id_vehicles_id_fk": { + "name": "pollution_certificates_vehicle_id_vehicles_id_fk", + "tableFrom": "pollution_certificates", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "reminders": { + "name": "reminders", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "vehicle_id": { + "name": "vehicle_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "due_date": { + "name": "due_date", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "remind_schedule": { + "name": "remind_schedule", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "is_completed": { + "name": "is_completed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "reminders_vehicle_id_vehicles_id_fk": { + "name": "reminders_vehicle_id_vehicles_id_fk", + "tableFrom": "reminders", + "columnsFrom": [ + "vehicle_id" + ], + "tableTo": "vehicles", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "vehicles": { + "name": "vehicles", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "make": { + "name": "make", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "license_plate": { + "name": "license_plate", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "vin": { + "name": "vin", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color": { + "name": "color", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "odometer": { + "name": "odometer", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + } + }, + "views": {}, + "enums": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/migrations/meta/_journal.json b/migrations/meta/_journal.json index bd17e04d..96c1953c 100644 --- a/migrations/meta/_journal.json +++ b/migrations/meta/_journal.json @@ -64,6 +64,27 @@ "when": 1765980000000, "tag": "20251217120000_add_reminders_table", "breakpoints": true + }, + { + "idx": 9, + "version": "6", + "when": 1766139510883, + "tag": "20251219101830_adding-configs", + "breakpoints": true + }, + { + "idx": 10, + "version": "6", + "when": 1766207631034, + "tag": "20251220051351_adding-custom-fields", + "breakpoints": true + }, + { + "idx": 11, + "version": "6", + "when": 1766920569315, + "tag": "20251228111609_adding-recurring-end-dates", + "breakpoints": true } ] } diff --git a/package.json b/package.json index 798e6654..087ad2d9 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ }, "devDependencies": { "@eslint/js": "^9.39.2", + "@inlang/paraglide-js": "^2.6.0", "@internationalized/date": "^3.10.1", "@lucide/svelte": "^0.562.0", "@sveltejs/adapter-node": "^5.4.0", @@ -31,11 +32,11 @@ "@tailwindcss/typography": "^0.5.19", "@tailwindcss/vite": "^4.1.18", "@tanstack/table-core": "^8.21.3", - "@testing-library/svelte": "^5.2.9", + "@testing-library/svelte": "^5.3.1", "@types/node": "^25.0.3", "@types/supertest": "^6.0.3", - "@typescript-eslint/eslint-plugin": "^8.50.0", - "@typescript-eslint/parser": "^8.50.0", + "@typescript-eslint/eslint-plugin": "^8.50.1", + "@typescript-eslint/parser": "^8.50.1", "@vitest/coverage-v8": "^4.0.16", "bits-ui": "^2.14.4", "clsx": "^2.1.1", @@ -54,15 +55,15 @@ "eslint-plugin-unused-imports": "^4.3.0", "formsnap": "^2.0.1", "globals": "^16.5.0", - "jsdom": "^27.3.0", + "jsdom": "^27.4.0", "layerchart": "2.0.0-next.27", "prettier": "^3.7.4", "prettier-plugin-svelte": "^3.4.1", "prettier-plugin-tailwindcss": "^0.7.2", "supertest": "^7.1.4", - "svelte": "^5.46.0", + "svelte": "^5.46.1", "svelte-awesome-color-picker": "^4.1.0", - "svelte-check": "^4.3.4", + "svelte-check": "^4.3.5", "svelte-eslint-parser": "^1.4.1", "svelte-sonner": "^1.0.7", "sveltekit-superforms": "^2.29.1", @@ -89,6 +90,7 @@ "@types/multer": "^2.0.0", "bcrypt": "^6.0.0", "cors": "^2.8.5", + "csv-parse": "^6.1.0", "dotenv": "^17.2.3", "express": "^5.2.1", "express-rate-limit": "^8.2.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac4878fd..e8436e04 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: cors: specifier: ^2.8.5 version: 2.8.5 + csv-parse: + specifier: ^6.1.0 + version: 6.1.0 dotenv: specifier: ^17.2.3 version: 17.2.3 @@ -64,7 +67,7 @@ importers: version: 8.1.0 mode-watcher: specifier: ^1.1.0 - version: 1.1.0(svelte@5.46.0) + version: 1.1.0(svelte@5.46.1) multer: specifier: ^2.0.2 version: 2.0.2 @@ -78,21 +81,24 @@ importers: '@eslint/js': specifier: ^9.39.2 version: 9.39.2 + '@inlang/paraglide-js': + specifier: ^2.6.0 + version: 2.7.1 '@internationalized/date': specifier: ^3.10.1 version: 3.10.1 '@lucide/svelte': specifier: ^0.562.0 - version: 0.562.0(svelte@5.46.0) + version: 0.562.0(svelte@5.46.1) '@sveltejs/adapter-node': specifier: ^5.4.0 - version: 5.4.0(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))) + version: 5.4.0(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))) '@sveltejs/kit': specifier: ^2.49.2 - version: 2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) + version: 2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) '@sveltejs/vite-plugin-svelte': specifier: ^6.2.1 - version: 6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) + version: 6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) '@tailwindcss/forms': specifier: ^0.5.11 version: 0.5.11(tailwindcss@4.1.18) @@ -106,8 +112,8 @@ importers: specifier: ^8.21.3 version: 8.21.3 '@testing-library/svelte': - specifier: ^5.2.9 - version: 5.2.9(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))(vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0)) + specifier: ^5.3.1 + version: 5.3.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))(vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0)) '@types/node': specifier: ^25.0.3 version: 25.0.3 @@ -115,17 +121,17 @@ importers: specifier: ^6.0.3 version: 6.0.3 '@typescript-eslint/eslint-plugin': - specifier: ^8.50.0 - version: 8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.50.1 + version: 8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@typescript-eslint/parser': - specifier: ^8.50.0 - version: 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + specifier: ^8.50.1 + version: 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) '@vitest/coverage-v8': specifier: ^4.0.16 - version: 4.0.16(vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0)) + version: 4.0.16(vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0)) bits-ui: specifier: ^2.14.4 - version: 2.14.4(@internationalized/date@3.10.1)(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0) + version: 2.14.4(@internationalized/date@3.10.1)(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -155,7 +161,7 @@ importers: version: 0.31.8 drizzle-orm: specifier: ^0.45.1 - version: 0.45.1(@libsql/client@0.15.15) + version: 0.45.1(@libsql/client@0.15.15)(kysely@0.27.6) eslint: specifier: ^9.39.2 version: 9.39.2(jiti@2.6.1) @@ -164,52 +170,52 @@ importers: version: 10.1.8(eslint@9.39.2(jiti@2.6.1)) eslint-plugin-svelte: specifier: ^3.13.1 - version: 3.13.1(eslint@9.39.2(jiti@2.6.1))(svelte@5.46.0) + version: 3.13.1(eslint@9.39.2(jiti@2.6.1))(svelte@5.46.1) eslint-plugin-unused-imports: specifier: ^4.3.0 - version: 4.3.0(@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) + version: 4.3.0(@typescript-eslint/eslint-plugin@8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)) formsnap: specifier: ^2.0.1 - version: 2.0.1(svelte@5.46.0)(sveltekit-superforms@2.29.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(@types/json-schema@7.0.15)(svelte@5.46.0)(typescript@5.9.3)) + version: 2.0.1(svelte@5.46.1)(sveltekit-superforms@2.29.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(@types/json-schema@7.0.15)(svelte@5.46.1)(typescript@5.9.3)) globals: specifier: ^16.5.0 version: 16.5.0 jsdom: - specifier: ^27.3.0 - version: 27.3.0(postcss@8.5.6) + specifier: ^27.4.0 + version: 27.4.0(postcss@8.5.6) layerchart: specifier: 2.0.0-next.27 - version: 2.0.0-next.27(svelte@5.46.0) + version: 2.0.0-next.27(svelte@5.46.1) prettier: specifier: ^3.7.4 version: 3.7.4 prettier-plugin-svelte: specifier: ^3.4.1 - version: 3.4.1(prettier@3.7.4)(svelte@5.46.0) + version: 3.4.1(prettier@3.7.4)(svelte@5.46.1) prettier-plugin-tailwindcss: specifier: ^0.7.2 - version: 0.7.2(prettier-plugin-svelte@3.4.1(prettier@3.7.4)(svelte@5.46.0))(prettier@3.7.4) + version: 0.7.2(prettier-plugin-svelte@3.4.1(prettier@3.7.4)(svelte@5.46.1))(prettier@3.7.4) supertest: specifier: ^7.1.4 version: 7.1.4 svelte: - specifier: ^5.46.0 - version: 5.46.0 + specifier: ^5.46.1 + version: 5.46.1 svelte-awesome-color-picker: specifier: ^4.1.0 - version: 4.1.0(svelte@5.46.0) + version: 4.1.0(svelte@5.46.1) svelte-check: - specifier: ^4.3.4 - version: 4.3.4(picomatch@4.0.3)(svelte@5.46.0)(typescript@5.9.3) + specifier: ^4.3.5 + version: 4.3.5(picomatch@4.0.3)(svelte@5.46.1)(typescript@5.9.3) svelte-eslint-parser: specifier: ^1.4.1 - version: 1.4.1(svelte@5.46.0) + version: 1.4.1(svelte@5.46.1) svelte-sonner: specifier: ^1.0.7 - version: 1.0.7(svelte@5.46.0) + version: 1.0.7(svelte@5.46.1) sveltekit-superforms: specifier: ^2.29.1 - version: 2.29.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(@types/json-schema@7.0.15)(svelte@5.46.0)(typescript@5.9.3) + version: 2.29.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(@types/json-schema@7.0.15)(svelte@5.46.1)(typescript@5.9.3) tailwind-merge: specifier: ^3.4.0 version: 3.4.0 @@ -233,7 +239,7 @@ importers: version: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) vitest: specifier: ^4.0.16 - version: 4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0) + version: 4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0) packages: @@ -825,6 +831,15 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@exodus/bytes@1.6.0': + resolution: {integrity: sha512-y32mI9627q5LR/L8fLc4YyDRJQOi+jK0D9okzLilAdiU3F9we3zC7Y7CFrR/8vAvUyv7FgBAYcNHtvbmhKCFcw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@exodus/crypto': ^1.0.0-rc.4 + peerDependenciesMeta: + '@exodus/crypto': + optional: true + '@exodus/schemasafe@1.3.0': resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==} @@ -863,6 +878,17 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@inlang/paraglide-js@2.7.1': + resolution: {integrity: sha512-wCpnS9iRTRYMilvWBjB0ndf8+moon+AXz23Uh4wbpQjWhRJyvCytkGFzm7jeqAGggK4v3oeuyjva91TDMS+qhw==} + hasBin: true + + '@inlang/recommend-sherlock@0.2.1': + resolution: {integrity: sha512-ckv8HvHy/iTqaVAEKrr+gnl+p3XFNwe5D2+6w6wJk2ORV2XkcRkKOJ/XsTUJbPSiyi4PI+p+T3bqbmNx/rDUlg==} + + '@inlang/sdk@2.4.10': + resolution: {integrity: sha512-MLcYSb9ERwvyfxMsMXGjmAYfh6Bn/rkT58ffkibWxbFLiL3ejSdmLGP8Wl7118dMo6nj2PXTcEPzUw+2YPQ62Q==} + engines: {node: '>=18.0.0'} + '@internationalized/date@3.10.1': resolution: {integrity: sha512-oJrXtQiAXLvT9clCf1K4kxp3eKsQhIaZqxEyowkBcsvZDdZkbWrVmnGknxs5flTD0VGsxrxKgBCZty1EzoiMzA==} @@ -955,6 +981,13 @@ packages: cpu: [x64] os: [win32] + '@lix-js/sdk@0.4.7': + resolution: {integrity: sha512-pRbW+joG12L0ULfMiWYosIW0plmW4AsUdiPCp+Z8rAsElJ+wJ6in58zhD3UwUcd4BNcpldEGjg6PdA7e0RgsDQ==} + engines: {node: '>=18'} + + '@lix-js/server-protocol-schema@0.1.1': + resolution: {integrity: sha512-jBeALB6prAbtr5q4vTuxnRZZv1M2rKe8iNqRQhFJ4Tv7150unEa0vKyz0hs8Gl3fUGsWaNJBh3J8++fpbrpRBQ==} + '@lucide/svelte@0.562.0': resolution: {integrity: sha512-wDMULwtTFN2Sc/TFBm6gfuVCNb4Y5P9LDrwxNnUbV52+IEU7NXZmvxwXoz+vrrpad6Xupq+Hw5eUlqIHEGhouw==} peerDependencies: @@ -1143,9 +1176,16 @@ packages: '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + '@sinclair/typebox@0.31.28': + resolution: {integrity: sha512-/s55Jujywdw/Jpan+vsy6JZs1z2ZTGxTmbZTPiuSL2wz9mfzA2gN1zzaqmvfi4pq+uOt7Du85fkiwv5ymW84aQ==} + '@so-ric/colorspace@1.1.6': resolution: {integrity: sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==} + '@sqlite.org/sqlite-wasm@3.48.0-build4': + resolution: {integrity: sha512-hI6twvUkzOmyGZhQMza1gpfqErZxXRw6JEsiVjUbo7tFanVD+8Oil0Ih3l2nGzHdxPI41zFmfUQG7GHqhciKZQ==} + hasBin: true + '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -1298,8 +1338,14 @@ packages: resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} engines: {node: '>=18'} - '@testing-library/svelte@5.2.9': - resolution: {integrity: sha512-p0Lg/vL1iEsEasXKSipvW9nBCtItQGhYvxL8OZ4w7/IDdC+LGoSJw4mMS5bndVFON/gWryitEhMr29AlO4FvBg==} + '@testing-library/svelte-core@1.0.0': + resolution: {integrity: sha512-VkUePoLV6oOYwSUvX6ShA8KLnJqZiYMIbP2JW2t0GLWLkJxKGvuH5qrrZBV/X7cXFnLGuFQEC7RheYiZOW68KQ==} + engines: {node: '>=16'} + peerDependencies: + svelte: ^3 || ^4 || ^5 || ^5.0.0-next.0 + + '@testing-library/svelte@5.3.1': + resolution: {integrity: sha512-8Ez7ZOqW5geRf9PF5rkuopODe5RGy3I9XR+kc7zHh26gBiktLaxTfKmhlGaSHYUOTQE7wFsLMN9xCJVCszw47w==} engines: {node: '>= 10'} peerDependencies: svelte: ^3 || ^4 || ^5 || ^5.0.0-next.0 @@ -1423,63 +1469,63 @@ packages: '@types/json-schema': optional: true - '@typescript-eslint/eslint-plugin@8.50.0': - resolution: {integrity: sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==} + '@typescript-eslint/eslint-plugin@8.50.1': + resolution: {integrity: sha512-PKhLGDq3JAg0Jk/aK890knnqduuI/Qj+udH7wCf0217IGi4gt+acgCyPVe79qoT+qKUvHMDQkwJeKW9fwl8Cyw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.50.0 + '@typescript-eslint/parser': ^8.50.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.50.0': - resolution: {integrity: sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==} + '@typescript-eslint/parser@8.50.1': + resolution: {integrity: sha512-hM5faZwg7aVNa819m/5r7D0h0c9yC4DUlWAOvHAtISdFTc8xB86VmX5Xqabrama3wIPJ/q9RbGS1worb6JfnMg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.50.0': - resolution: {integrity: sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==} + '@typescript-eslint/project-service@8.50.1': + resolution: {integrity: sha512-E1ur1MCVf+YiP89+o4Les/oBAVzmSbeRB0MQLfSlYtbWU17HPxZ6Bhs5iYmKZRALvEuBoXIZMOIRRc/P++Ortg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.50.0': - resolution: {integrity: sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==} + '@typescript-eslint/scope-manager@8.50.1': + resolution: {integrity: sha512-mfRx06Myt3T4vuoHaKi8ZWNTPdzKPNBhiblze5N50//TSHOAQQevl/aolqA/BcqqbJ88GUnLqjjcBc8EWdBcVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.50.0': - resolution: {integrity: sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==} + '@typescript-eslint/tsconfig-utils@8.50.1': + resolution: {integrity: sha512-ooHmotT/lCWLXi55G4mvaUF60aJa012QzvLK0Y+Mp4WdSt17QhMhWOaBWeGTFVkb2gDgBe19Cxy1elPXylslDw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.50.0': - resolution: {integrity: sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==} + '@typescript-eslint/type-utils@8.50.1': + resolution: {integrity: sha512-7J3bf022QZE42tYMO6SL+6lTPKFk/WphhRPe9Tw/el+cEwzLz1Jjz2PX3GtGQVxooLDKeMVmMt7fWpYRdG5Etg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.50.0': - resolution: {integrity: sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==} + '@typescript-eslint/types@8.50.1': + resolution: {integrity: sha512-v5lFIS2feTkNyMhd7AucE/9j/4V9v5iIbpVRncjk/K0sQ6Sb+Np9fgYS/63n6nwqahHQvbmujeBL7mp07Q9mlA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.50.0': - resolution: {integrity: sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==} + '@typescript-eslint/typescript-estree@8.50.1': + resolution: {integrity: sha512-woHPdW+0gj53aM+cxchymJCrh0cyS7BTIdcDxWUNsclr9VDkOSbqC13juHzxOmQ22dDkMZEpZB+3X1WpUvzgVQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.50.0': - resolution: {integrity: sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==} + '@typescript-eslint/utils@8.50.1': + resolution: {integrity: sha512-lCLp8H1T9T7gPbEuJSnHwnSuO9mDf8mfK/Nion5mZmiEaQD9sWf9W4dfeFqRyqRjF06/kBuTmAqcs9sewM2NbQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.50.0': - resolution: {integrity: sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==} + '@typescript-eslint/visitor-keys@8.50.1': + resolution: {integrity: sha512-IrDKrw7pCRUR94zeuCSUWQ+w8JEf5ZX5jl/e6AHGSLi1/zIr0lgutfn/7JpfCey+urpgQEdrZVYzCaVVKiTwhQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@valibot/to-json-schema@1.5.0': @@ -1585,6 +1631,9 @@ packages: arktype@2.1.29: resolution: {integrity: sha512-jyfKk4xIOzvYNayqnD8ZJQqOwcrTOUbIU4293yrzAjA3O1dWh61j71ArMQ6tS/u4pD7vabSPe7nG3RCyoXW6RQ==} + array-timsort@1.0.3: + resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} + asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} @@ -1712,10 +1761,18 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + commander@7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} + comment-json@4.5.1: + resolution: {integrity: sha512-taEtr3ozUmOB7it68Jll7s0Pwm+aoiHyXKrEC8SEodL4rNpdfDLqa7PfBlrgFoCNNdR8ImL+muti5IGvktJAAg==} + engines: {node: '>= 6'} + commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} @@ -1734,6 +1791,10 @@ packages: engines: {node: '>=18'} hasBin: true + consola@3.4.0: + resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} + engines: {node: ^14.18.0 || >=16.10.0} + content-disposition@1.0.1: resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} engines: {node: '>=18'} @@ -1757,6 +1818,9 @@ packages: cookiejar@2.1.4: resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} @@ -1778,6 +1842,9 @@ packages: resolution: {integrity: sha512-KyOS/kJMEq5O9GdPnaf82noigg5X5DYn0kZPJTaAsCUaBizp6Xa1y9D4Qoqf/JazEXWuruErHgVXwjN5391ZJw==} engines: {node: '>=20'} + csv-parse@6.1.0: + resolution: {integrity: sha512-CEE+jwpgLn+MmtCpVcPtiCZpVtB6Z2OKPTr34pycYYoL7sxdOkXDdQ4lRiw6ioC0q6BLqhc6cKweCVvral8yhw==} + currency-codes@2.2.0: resolution: {integrity: sha512-vpbQc5sEYHGdTVAYUhHnKv0DWiYLRvzl/KKyqeHzBh7HD/j3UlWoScpZ9tN/jG6w2feddWoObsBbaNVu5yDapg==} @@ -1915,6 +1982,14 @@ packages: decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + dedent@1.5.1: + resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -2189,6 +2264,11 @@ packages: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -2382,9 +2462,9 @@ packages: resolution: {integrity: sha512-jOiHyAZsmnr8LqoPGmCjYAaiuWwjAPLgY8ZX2XrmHawt99/u1y6RgrZMTeoPfpUbV96HOalYgz1qzkRbw54Pmg==} engines: {node: '>=18.0.0'} - html-encoding-sniffer@4.0.0: - resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} - engines: {node: '>=18'} + html-encoding-sniffer@6.0.0: + resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -2401,6 +2481,10 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} + human-id@4.1.3: + resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} + hasBin: true + iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -2510,6 +2594,9 @@ packages: js-base64@3.7.8: resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} + js-sha256@0.11.1: + resolution: {integrity: sha512-o6WSo/LUvY2uC4j7mO50a2ms7E/EAdbP0swigLV+nzHKTTaYnaLIWJ02VdXrsJX0vGedDESQnLsOekr94ryfjg==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2520,8 +2607,8 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsdom@27.3.0: - resolution: {integrity: sha512-GtldT42B8+jefDUC4yUKAvsaOrH7PDHmZxZXNgF2xMmymjUbRYJvpAybZAKEmXDGTM0mCsz8duOa4vTm5AY2Kg==} + jsdom@27.4.0: + resolution: {integrity: sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: canvas: ^3.0.0 @@ -2542,6 +2629,11 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -2555,6 +2647,10 @@ packages: kuler@2.0.0: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} + kysely@0.27.6: + resolution: {integrity: sha512-FIyV/64EkKhJmjgC0g2hygpBv5RNWVPyNCqSAD7eTCv6eFWNIi4PN1UvdSJGicN/o35bnevgis4Y0UDC0qi8jQ==} + engines: {node: '>=14.0.0'} + layerchart@2.0.0-next.27: resolution: {integrity: sha512-yt28xU8WzXq0AliX7eiC0JKZGQtO8M9FmHvt8sESNitSc/yC+fYeTghaO9lMRwcYCmi6D1NjbFyD9mWFeazNIQ==} peerDependencies: @@ -3176,6 +3272,11 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + sqlite-wasm-kysely@0.3.0: + resolution: {integrity: sha512-TzjBNv7KwRw6E3pdKdlRyZiTmUIE0UttT/Sl56MVwVARl/u5gp978KepazCJZewFUnlWHz9i3NQd4kOtP/Afdg==} + peerDependencies: + kysely: '*' + stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} @@ -3245,8 +3346,8 @@ packages: peerDependencies: svelte: ^5.0.0 - svelte-check@4.3.4: - resolution: {integrity: sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw==} + svelte-check@4.3.5: + resolution: {integrity: sha512-e4VWZETyXaKGhpkxOXP+B/d0Fp/zKViZoJmneZWe/05Y2aqSKj3YN2nLfYPJBQ87WEiY4BQCQ9hWGu9mPT1a1Q==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: @@ -3285,8 +3386,8 @@ packages: peerDependencies: svelte: ^5.0.0 - svelte@5.46.0: - resolution: {integrity: sha512-ZhLtvroYxUxr+HQJfMZEDRsGsmU46x12RvAv/zi9584f5KOX7bUrEbhPJ7cKFmUvZTJXi/CFZUYwDC6M1FigPw==} + svelte@5.46.1: + resolution: {integrity: sha512-ynjfCHD3nP2el70kN5Pmg37sSi0EjOm9FgHYQdC4giWG/hzO3AatzXXJJgP305uIhGQxSufJLuYWtkY8uK/8RA==} engines: {node: '>=18'} sveltekit-superforms@2.29.1: @@ -3434,12 +3535,23 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unplugin@2.3.11: + resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} + engines: {node: '>=18.12.0'} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + urlpattern-polyfill@10.1.0: + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + valibot@1.2.0: resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==} peerDependencies: @@ -3550,9 +3662,8 @@ packages: resolution: {integrity: sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA==} engines: {node: '>=20'} - whatwg-encoding@3.1.1: - resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} - engines: {node: '>=18'} + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} whatwg-mimetype@4.0.0: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} @@ -4019,6 +4130,8 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@exodus/bytes@1.6.0': {} + '@exodus/schemasafe@1.3.0': optional: true @@ -4054,6 +4167,32 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@inlang/paraglide-js@2.7.1': + dependencies: + '@inlang/recommend-sherlock': 0.2.1 + '@inlang/sdk': 2.4.10 + commander: 11.1.0 + consola: 3.4.0 + json5: 2.2.3 + unplugin: 2.3.11 + urlpattern-polyfill: 10.1.0 + transitivePeerDependencies: + - babel-plugin-macros + + '@inlang/recommend-sherlock@0.2.1': + dependencies: + comment-json: 4.5.1 + + '@inlang/sdk@2.4.10': + dependencies: + '@lix-js/sdk': 0.4.7 + '@sinclair/typebox': 0.31.28 + kysely: 0.27.6 + sqlite-wasm-kysely: 0.3.0(kysely@0.27.6) + uuid: 10.0.0 + transitivePeerDependencies: + - babel-plugin-macros + '@internationalized/date@3.10.1': dependencies: '@swc/helpers': 0.5.17 @@ -4164,9 +4303,23 @@ snapshots: '@libsql/win32-x64-msvc@0.5.22': optional: true - '@lucide/svelte@0.562.0(svelte@5.46.0)': + '@lix-js/sdk@0.4.7': + dependencies: + '@lix-js/server-protocol-schema': 0.1.1 + dedent: 1.5.1 + human-id: 4.1.3 + js-sha256: 0.11.1 + kysely: 0.27.6 + sqlite-wasm-kysely: 0.3.0(kysely@0.27.6) + uuid: 10.0.0 + transitivePeerDependencies: + - babel-plugin-macros + + '@lix-js/server-protocol-schema@0.1.1': {} + + '@lucide/svelte@0.562.0(svelte@5.46.1)': dependencies: - svelte: 5.46.0 + svelte: 5.46.1 '@neon-rs/load@0.0.4': {} @@ -4307,30 +4460,34 @@ snapshots: '@sideway/pinpoint@2.0.0': optional: true + '@sinclair/typebox@0.31.28': {} + '@so-ric/colorspace@1.1.6': dependencies: color: 5.0.3 text-hex: 1.0.0 + '@sqlite.org/sqlite-wasm@3.48.0-build4': {} + '@standard-schema/spec@1.0.0': {} '@sveltejs/acorn-typescript@1.0.8(acorn@8.15.0)': dependencies: acorn: 8.15.0 - '@sveltejs/adapter-node@5.4.0(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))': + '@sveltejs/adapter-node@5.4.0(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))': dependencies: '@rollup/plugin-commonjs': 28.0.9(rollup@4.53.3) '@rollup/plugin-json': 6.1.0(rollup@4.53.3) '@rollup/plugin-node-resolve': 16.0.3(rollup@4.53.3) - '@sveltejs/kit': 2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) + '@sveltejs/kit': 2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) rollup: 4.53.3 - '@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': + '@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 @@ -4342,25 +4499,25 @@ snapshots: sade: 1.8.1 set-cookie-parser: 2.7.2 sirv: 3.0.2 - svelte: 5.46.0 + svelte: 5.46.1 vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) - '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) debug: 4.4.3 - svelte: 5.46.0 + svelte: 5.46.1 vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) debug: 4.4.3 deepmerge: 4.3.1 magic-string: 0.30.21 - svelte: 5.46.0 + svelte: 5.46.1 vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) vitefu: 1.1.1(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) transitivePeerDependencies: @@ -4461,13 +4618,18 @@ snapshots: picocolors: 1.1.1 pretty-format: 27.5.1 - '@testing-library/svelte@5.2.9(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))(vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0))': + '@testing-library/svelte-core@1.0.0(svelte@5.46.1)': + dependencies: + svelte: 5.46.1 + + '@testing-library/svelte@5.3.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0))(vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: '@testing-library/dom': 10.4.1 - svelte: 5.46.0 + '@testing-library/svelte-core': 1.0.0(svelte@5.46.1) + svelte: 5.46.1 optionalDependencies: vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) - vitest: 4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0) + vitest: 4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0) '@types/aria-query@5.0.4': {} @@ -4592,14 +4754,14 @@ snapshots: '@types/json-schema': 7.0.15 optional: true - '@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.50.0 - '@typescript-eslint/type-utils': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.50.0 + '@typescript-eslint/parser': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.50.1 + '@typescript-eslint/type-utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.50.1 eslint: 9.39.2(jiti@2.6.1) ignore: 7.0.5 natural-compare: 1.4.0 @@ -4608,41 +4770,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.50.0 - '@typescript-eslint/types': 8.50.0 - '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.50.0 + '@typescript-eslint/scope-manager': 8.50.1 + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.50.1 debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.50.0(typescript@5.9.3)': + '@typescript-eslint/project-service@8.50.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) - '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.9.3) + '@typescript-eslint/types': 8.50.1 debug: 4.4.3 typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.50.0': + '@typescript-eslint/scope-manager@8.50.1': dependencies: - '@typescript-eslint/types': 8.50.0 - '@typescript-eslint/visitor-keys': 8.50.0 + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/visitor-keys': 8.50.1 - '@typescript-eslint/tsconfig-utils@8.50.0(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.50.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/type-utils@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.50.0 - '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) debug: 4.4.3 eslint: 9.39.2(jiti@2.6.1) ts-api-utils: 2.1.0(typescript@5.9.3) @@ -4650,14 +4812,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.50.0': {} + '@typescript-eslint/types@8.50.1': {} - '@typescript-eslint/typescript-estree@8.50.0(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.50.1(typescript@5.9.3)': dependencies: - '@typescript-eslint/project-service': 8.50.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.50.0(typescript@5.9.3) - '@typescript-eslint/types': 8.50.0 - '@typescript-eslint/visitor-keys': 8.50.0 + '@typescript-eslint/project-service': 8.50.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.50.1(typescript@5.9.3) + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/visitor-keys': 8.50.1 debug: 4.4.3 minimatch: 9.0.5 semver: 7.7.3 @@ -4667,20 +4829,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': + '@typescript-eslint/utils@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1)) - '@typescript-eslint/scope-manager': 8.50.0 - '@typescript-eslint/types': 8.50.0 - '@typescript-eslint/typescript-estree': 8.50.0(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.50.1 + '@typescript-eslint/types': 8.50.1 + '@typescript-eslint/typescript-estree': 8.50.1(typescript@5.9.3) eslint: 9.39.2(jiti@2.6.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.50.0': + '@typescript-eslint/visitor-keys@8.50.1': dependencies: - '@typescript-eslint/types': 8.50.0 + '@typescript-eslint/types': 8.50.1 eslint-visitor-keys: 4.2.1 '@valibot/to-json-schema@1.5.0(valibot@1.2.0(typescript@5.9.3))': @@ -4703,7 +4865,7 @@ snapshots: validator: 13.15.23 optional: true - '@vitest/coverage-v8@4.0.16(vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0))': + '@vitest/coverage-v8@4.0.16(vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.0.16 @@ -4716,7 +4878,7 @@ snapshots: obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0) + vitest: 4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0) transitivePeerDependencies: - supports-color @@ -4809,6 +4971,8 @@ snapshots: arkregex: 0.0.5 optional: true + array-timsort@1.0.3: {} + asap@2.0.6: {} assertion-error@2.0.1: {} @@ -4836,15 +5000,15 @@ snapshots: dependencies: require-from-string: 2.0.2 - bits-ui@2.14.4(@internationalized/date@3.10.1)(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0): + bits-ui@2.14.4(@internationalized/date@3.10.1)(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1): dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/dom': 1.7.4 '@internationalized/date': 3.10.1 esm-env: 1.2.2 - runed: 0.35.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0) - svelte: 5.46.0 - svelte-toolbelt: 0.10.6(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0) + runed: 0.35.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1) + svelte: 5.46.1 + svelte-toolbelt: 0.10.6(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1) tabbable: 6.3.0 transitivePeerDependencies: - '@sveltejs/kit' @@ -4948,8 +5112,16 @@ snapshots: dependencies: delayed-stream: 1.0.0 + commander@11.1.0: {} + commander@7.2.0: {} + comment-json@4.5.1: + dependencies: + array-timsort: 1.0.3 + core-util-is: 1.0.3 + esprima: 4.0.1 + commondir@1.0.1: {} component-emitter@1.3.1: {} @@ -4972,6 +5144,8 @@ snapshots: tree-kill: 1.2.2 yargs: 17.7.2 + consola@3.4.0: {} + content-disposition@1.0.1: {} content-type@1.0.5: {} @@ -4984,6 +5158,8 @@ snapshots: cookiejar@2.1.4: {} + core-util-is@1.0.3: {} + cors@2.8.5: dependencies: object-assign: 4.1.1 @@ -5010,6 +5186,8 @@ snapshots: transitivePeerDependencies: - postcss + csv-parse@6.1.0: {} + currency-codes@2.2.0: dependencies: first-match: 0.0.1 @@ -5137,6 +5315,8 @@ snapshots: decimal.js@10.6.0: {} + dedent@1.5.1: {} + deep-is@0.1.4: {} deepmerge@4.3.1: {} @@ -5178,9 +5358,10 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.45.1(@libsql/client@0.15.15): + drizzle-orm@0.45.1(@libsql/client@0.15.15)(kysely@0.27.6): optionalDependencies: '@libsql/client': 0.15.15 + kysely: 0.27.6 dunder-proto@1.0.1: dependencies: @@ -5326,7 +5507,7 @@ snapshots: dependencies: eslint: 9.39.2(jiti@2.6.1) - eslint-plugin-svelte@3.13.1(eslint@9.39.2(jiti@2.6.1))(svelte@5.46.0): + eslint-plugin-svelte@3.13.1(eslint@9.39.2(jiti@2.6.1))(svelte@5.46.1): dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2(jiti@2.6.1)) '@jridgewell/sourcemap-codec': 1.5.5 @@ -5338,17 +5519,17 @@ snapshots: postcss-load-config: 3.1.4(postcss@8.5.6) postcss-safe-parser: 7.0.1(postcss@8.5.6) semver: 7.7.3 - svelte-eslint-parser: 1.4.1(svelte@5.46.0) + svelte-eslint-parser: 1.4.1(svelte@5.46.1) optionalDependencies: - svelte: 5.46.0 + svelte: 5.46.1 transitivePeerDependencies: - ts-node - eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): + eslint-plugin-unused-imports@4.3.0(@typescript-eslint/eslint-plugin@8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1)): dependencies: eslint: 9.39.2(jiti@2.6.1) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.50.1(@typescript-eslint/parser@8.50.1(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) eslint-scope@8.4.0: dependencies: @@ -5408,6 +5589,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 4.2.1 + esprima@4.0.1: {} + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -5550,11 +5733,11 @@ snapshots: dezalgo: 1.0.4 once: 1.4.0 - formsnap@2.0.1(svelte@5.46.0)(sveltekit-superforms@2.29.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(@types/json-schema@7.0.15)(svelte@5.46.0)(typescript@5.9.3)): + formsnap@2.0.1(svelte@5.46.1)(sveltekit-superforms@2.29.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(@types/json-schema@7.0.15)(svelte@5.46.1)(typescript@5.9.3)): dependencies: - svelte: 5.46.0 - svelte-toolbelt: 0.5.0(svelte@5.46.0) - sveltekit-superforms: 2.29.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(@types/json-schema@7.0.15)(svelte@5.46.0)(typescript@5.9.3) + svelte: 5.46.1 + svelte-toolbelt: 0.5.0(svelte@5.46.1) + sveltekit-superforms: 2.29.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(@types/json-schema@7.0.15)(svelte@5.46.1)(typescript@5.9.3) forwarded@0.2.0: {} @@ -5615,9 +5798,11 @@ snapshots: helmet@8.1.0: {} - html-encoding-sniffer@4.0.0: + html-encoding-sniffer@6.0.0: dependencies: - whatwg-encoding: 3.1.1 + '@exodus/bytes': 1.6.0 + transitivePeerDependencies: + - '@exodus/crypto' html-escaper@2.0.2: {} @@ -5643,6 +5828,8 @@ snapshots: transitivePeerDependencies: - supports-color + human-id@4.1.3: {} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -5738,6 +5925,8 @@ snapshots: js-base64@3.7.8: {} + js-sha256@0.11.1: {} + js-tokens@4.0.0: {} js-tokens@9.0.1: {} @@ -5746,14 +5935,15 @@ snapshots: dependencies: argparse: 2.0.1 - jsdom@27.3.0(postcss@8.5.6): + jsdom@27.4.0(postcss@8.5.6): dependencies: '@acemir/cssom': 0.9.29 '@asamuzakjp/dom-selector': 6.7.6 + '@exodus/bytes': 1.6.0 cssstyle: 5.3.4(postcss@8.5.6) data-urls: 6.0.0 decimal.js: 10.6.0 - html-encoding-sniffer: 4.0.0 + html-encoding-sniffer: 6.0.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 @@ -5763,12 +5953,12 @@ snapshots: tough-cookie: 6.0.0 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.0 - whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 15.1.0 ws: 8.18.3 xml-name-validator: 5.0.0 transitivePeerDependencies: + - '@exodus/crypto' - bufferutil - postcss - supports-color @@ -5786,6 +5976,8 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} + json5@2.2.3: {} + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -5796,7 +5988,9 @@ snapshots: kuler@2.0.0: {} - layerchart@2.0.0-next.27(svelte@5.46.0): + kysely@0.27.6: {} + + layerchart@2.0.0-next.27(svelte@5.46.1): dependencies: '@dagrejs/dagre': 1.1.8 '@layerstack/svelte-actions': 1.0.1-next.12 @@ -5824,8 +6018,8 @@ snapshots: d3-time: 3.1.0 lodash-es: 4.17.21 memoize: 10.2.0 - runed: 0.28.0(svelte@5.46.0) - svelte: 5.46.0 + runed: 0.28.0(svelte@5.46.1) + svelte: 5.46.1 levn@0.4.1: dependencies: @@ -5990,11 +6184,11 @@ snapshots: dependencies: minimist: 1.2.8 - mode-watcher@1.1.0(svelte@5.46.0): + mode-watcher@1.1.0(svelte@5.46.1): dependencies: - runed: 0.25.0(svelte@5.46.0) - svelte: 5.46.0 - svelte-toolbelt: 0.7.1(svelte@5.46.0) + runed: 0.25.0(svelte@5.46.1) + svelte: 5.46.1 + svelte-toolbelt: 0.7.1(svelte@5.46.1) mri@1.2.0: {} @@ -6127,16 +6321,16 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-svelte@3.4.1(prettier@3.7.4)(svelte@5.46.0): + prettier-plugin-svelte@3.4.1(prettier@3.7.4)(svelte@5.46.1): dependencies: prettier: 3.7.4 - svelte: 5.46.0 + svelte: 5.46.1 - prettier-plugin-tailwindcss@0.7.2(prettier-plugin-svelte@3.4.1(prettier@3.7.4)(svelte@5.46.0))(prettier@3.7.4): + prettier-plugin-tailwindcss@0.7.2(prettier-plugin-svelte@3.4.1(prettier@3.7.4)(svelte@5.46.1))(prettier@3.7.4): dependencies: prettier: 3.7.4 optionalDependencies: - prettier-plugin-svelte: 3.4.1(prettier@3.7.4)(svelte@5.46.0) + prettier-plugin-svelte: 3.4.1(prettier@3.7.4)(svelte@5.46.1) prettier@3.7.4: {} @@ -6238,29 +6432,29 @@ snapshots: transitivePeerDependencies: - supports-color - runed@0.23.4(svelte@5.46.0): + runed@0.23.4(svelte@5.46.1): dependencies: esm-env: 1.2.2 - svelte: 5.46.0 + svelte: 5.46.1 - runed@0.25.0(svelte@5.46.0): + runed@0.25.0(svelte@5.46.1): dependencies: esm-env: 1.2.2 - svelte: 5.46.0 + svelte: 5.46.1 - runed@0.28.0(svelte@5.46.0): + runed@0.28.0(svelte@5.46.1): dependencies: esm-env: 1.2.2 - svelte: 5.46.0 + svelte: 5.46.1 - runed@0.35.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0): + runed@0.35.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1): dependencies: dequal: 2.0.3 esm-env: 1.2.2 lz-string: 1.5.0 - svelte: 5.46.0 + svelte: 5.46.1 optionalDependencies: - '@sveltejs/kit': 2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) + '@sveltejs/kit': 2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) rw@1.3.3: {} @@ -6366,6 +6560,11 @@ snapshots: source-map@0.6.1: {} + sqlite-wasm-kysely@0.3.0(kysely@0.27.6): + dependencies: + '@sqlite.org/sqlite-wasm': 3.48.0-build4 + kysely: 0.27.6 + stack-trace@0.0.10: {} stackback@0.0.2: {} @@ -6430,29 +6629,29 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-awesome-color-picker@4.1.0(svelte@5.46.0): + svelte-awesome-color-picker@4.1.0(svelte@5.46.1): dependencies: colord: 2.9.3 - svelte: 5.46.0 - svelte-awesome-slider: 2.0.0(svelte@5.46.0) + svelte: 5.46.1 + svelte-awesome-slider: 2.0.0(svelte@5.46.1) - svelte-awesome-slider@2.0.0(svelte@5.46.0): + svelte-awesome-slider@2.0.0(svelte@5.46.1): dependencies: - svelte: 5.46.0 + svelte: 5.46.1 - svelte-check@4.3.4(picomatch@4.0.3)(svelte@5.46.0)(typescript@5.9.3): + svelte-check@4.3.5(picomatch@4.0.3)(svelte@5.46.1)(typescript@5.9.3): dependencies: '@jridgewell/trace-mapping': 0.3.31 chokidar: 4.0.3 fdir: 6.5.0(picomatch@4.0.3) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.46.0 + svelte: 5.46.1 typescript: 5.9.3 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.4.1(svelte@5.46.0): + svelte-eslint-parser@1.4.1(svelte@5.46.1): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -6461,36 +6660,36 @@ snapshots: postcss-scss: 4.0.9(postcss@8.5.6) postcss-selector-parser: 7.1.1 optionalDependencies: - svelte: 5.46.0 + svelte: 5.46.1 - svelte-sonner@1.0.7(svelte@5.46.0): + svelte-sonner@1.0.7(svelte@5.46.1): dependencies: - runed: 0.28.0(svelte@5.46.0) - svelte: 5.46.0 + runed: 0.28.0(svelte@5.46.1) + svelte: 5.46.1 - svelte-toolbelt@0.10.6(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0): + svelte-toolbelt@0.10.6(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1): dependencies: clsx: 2.1.1 - runed: 0.35.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0) + runed: 0.35.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1) style-to-object: 1.0.14 - svelte: 5.46.0 + svelte: 5.46.1 transitivePeerDependencies: - '@sveltejs/kit' - svelte-toolbelt@0.5.0(svelte@5.46.0): + svelte-toolbelt@0.5.0(svelte@5.46.1): dependencies: clsx: 2.1.1 style-to-object: 1.0.14 - svelte: 5.46.0 + svelte: 5.46.1 - svelte-toolbelt@0.7.1(svelte@5.46.0): + svelte-toolbelt@0.7.1(svelte@5.46.1): dependencies: clsx: 2.1.1 - runed: 0.23.4(svelte@5.46.0) + runed: 0.23.4(svelte@5.46.1) style-to-object: 1.0.14 - svelte: 5.46.0 + svelte: 5.46.1 - svelte@5.46.0: + svelte@5.46.1: dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 @@ -6508,12 +6707,12 @@ snapshots: magic-string: 0.30.21 zimmerframe: 1.1.4 - sveltekit-superforms@2.29.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(@types/json-schema@7.0.15)(svelte@5.46.0)(typescript@5.9.3): + sveltekit-superforms@2.29.1(@sveltejs/kit@2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(@types/json-schema@7.0.15)(svelte@5.46.1)(typescript@5.9.3): dependencies: - '@sveltejs/kit': 2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.0)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) + '@sveltejs/kit': 2.49.2(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)))(svelte@5.46.1)(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) devalue: 5.6.1 memoize-weak: 1.0.2 - svelte: 5.46.0 + svelte: 5.46.1 ts-deepmerge: 7.0.3 optionalDependencies: '@exodus/schemasafe': 1.3.0 @@ -6641,12 +6840,23 @@ snapshots: unpipe@1.0.0: {} + unplugin@2.3.11: + dependencies: + '@jridgewell/remapping': 2.3.5 + acorn: 8.15.0 + picomatch: 4.0.3 + webpack-virtual-modules: 0.6.2 + uri-js@4.4.1: dependencies: punycode: 2.3.1 + urlpattern-polyfill@10.1.0: {} + util-deprecate@1.0.2: {} + uuid@10.0.0: {} + valibot@1.2.0(typescript@5.9.3): optionalDependencies: typescript: 5.9.3 @@ -6675,7 +6885,7 @@ snapshots: optionalDependencies: vite: 7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0) - vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0): + vitest@4.0.16(@types/node@25.0.3)(jiti@2.6.1)(jsdom@27.4.0(postcss@8.5.6))(lightningcss@1.30.2)(tsx@4.21.0): dependencies: '@vitest/expect': 4.0.16 '@vitest/mocker': 4.0.16(vite@7.3.0(@types/node@25.0.3)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)) @@ -6699,7 +6909,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 25.0.3 - jsdom: 27.3.0(postcss@8.5.6) + jsdom: 27.4.0(postcss@8.5.6) transitivePeerDependencies: - jiti - less @@ -6721,9 +6931,7 @@ snapshots: webidl-conversions@8.0.0: {} - whatwg-encoding@3.1.1: - dependencies: - iconv-lite: 0.6.3 + webpack-virtual-modules@0.6.2: {} whatwg-mimetype@4.0.0: {} diff --git a/project.inlang/project_id b/project.inlang/project_id new file mode 100644 index 00000000..a55a6247 --- /dev/null +++ b/project.inlang/project_id @@ -0,0 +1 @@ +iYqM0PXxJ6fvRb4qpQ \ No newline at end of file diff --git a/project.inlang/settings.json b/project.inlang/settings.json new file mode 100644 index 00000000..0998338e --- /dev/null +++ b/project.inlang/settings.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://inlang.com/schema/project-settings", + "modules": [ + "https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@4/dist/index.js", + "https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@2/dist/index.js" + ], + "plugin.inlang.messageFormat": { + "pathPattern": "./messages/{locale}.json" + }, + "baseLocale": "en", + "locales": ["en", "hi", "es", "fr", "de"] +} diff --git a/sample-fuel-import.csv b/sample-fuel-import.csv new file mode 100644 index 00000000..34e041ca --- /dev/null +++ b/sample-fuel-import.csv @@ -0,0 +1,11 @@ +Date,Odometer,FuelAmount,Cost,Filled,MissedLast,Notes +2025-01-01,45000,50.5,75.25,true,false,Full tank +2025-01-05,45250,48.2,72.30,true,false,Regular fill +2025-01-10,45500,52.1,78.15,true,false,Highway drive +2025-01-15,45750,49.8,74.70,true,false,City driving +2025-01-20,46000,51.3,77.00,true,false,Mixed route +2025-01-25,46250,47.9,71.85,false,true,Partial fill +2025-02-01,46500,50.0,75.00,true,false,Full tank at station +2025-02-05,46750,48.5,72.75,true,false,Regular fill +2025-02-10,47000,51.0,76.50,true,false,Premium fuel +2025-02-15,47250,49.5,74.25,true,false,Standard fuel diff --git a/src/app.html b/src/app.html index e31ef468..6640a956 100644 --- a/src/app.html +++ b/src/app.html @@ -1,5 +1,5 @@ - + diff --git a/src/hooks.server.ts b/src/hooks.server.ts index c3684156..32851c38 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,79 +1,116 @@ +import { sequence } from '@sveltejs/kit/hooks'; +import { paraglideMiddleware } from '$lib/paraglide/server'; import type { Handle, HandleServerError } from '@sveltejs/kit'; import { createErrorResponseBody, logError } from './server/utils/errorHandler'; + import { CorsMiddleware, RateLimitMiddleware, AuthMiddleware, LoggingMiddleware } from '$server/middlewares'; + import { MiddlewareChain } from '$server/middlewares/base'; import { initializeDatabase } from '$server/db/init'; import { appAsciiArt, logger } from '$server/config'; import { env } from '$lib/config/env.server'; +import { ensureAppDirectories } from '$server/utils/fs'; const middlewareChain = new MiddlewareChain(); -// Initialize database once when the server starts +const envSnapshot = () => ({ + LOG_LEVEL: env.LOG_LEVEL, + LOG_DIR: env.LOG_DIR, + NODE_ENV: env.NODE_ENV, + DB_PATH: env.DB_PATH, + DEMO_MODE: env.DEMO_MODE, + FORCE_DATA_SEED: env.FORCE_DATA_SEED +}); + +const logEnvSnapshot = () => { + const snapshot = envSnapshot(); + + Object.entries(snapshot).forEach(([key, value]) => logger.info(`${key}: ${String(value)}`)); +}; + let dbInitialized = false; + const initPromise = (async () => { - if (!dbInitialized) { - try { - logger.info(appAsciiArt); - // Log environment variables without secrets in prettty print - logger.info( - 'Environment variables: \n' + - JSON.stringify( - { - LOG_LEVEL: env.LOG_LEVEL, - LOG_DIR: env.LOG_DIR, - NODE_ENV: env.NODE_ENV, - DB_PATH: env.DB_PATH, - DEMO_MODE: env.DEMO_MODE, - FORCE_DATA_SEED: env.FORCE_DATA_SEED - }, - null, - 2 - ) - ); - await initializeDatabase(); - dbInitialized = true; - logger.info('Database initialization completed'); - } catch (error) { - logger.error('Failed to initialize database on startup:', error); - throw error; - } + if (dbInitialized) return; + + try { + logger.info(appAsciiArt); + logEnvSnapshot(); + } catch (error) { + logger.error('Failed to log startup banner', error); + } + + try { + await ensureAppDirectories(); + } catch (error) { + logger.error('Failed to create required application directories', error); + + const wrapped = new Error('Failed to create required application directories'); + + (wrapped as any).cause = error; + + throw wrapped; + } + + try { + await initializeDatabase(); + dbInitialized = true; + logger.info('Database initialization completed'); + } catch (error) { + logger.error('Failed to initialize database', error); + + const wrapped = new Error('Failed to initialize database'); + + (wrapped as any).cause = error; + + throw wrapped; } })(); -export const handle: Handle = async ({ event, resolve }) => { - // Ensure database is initialized before handling any requests +const buildMiddlewares = () => [ + new CorsMiddleware(), + new AuthMiddleware(), + new RateLimitMiddleware(), + new LoggingMiddleware() +]; + +export const handleError: HandleServerError = async ({ error, event }) => { + logError(error, event); + + const body = createErrorResponseBody(error); + + return { message: body.message || 'Internal server error' }; +}; + +const originalHandle: Handle = async ({ event, resolve }) => { await initPromise; + middlewareChain.init(buildMiddlewares()); - middlewareChain.init([ - new CorsMiddleware(), - new AuthMiddleware(), - new RateLimitMiddleware(), - new LoggingMiddleware() - ]); + const middlewareResult = await middlewareChain.handle(event); - const result = await middlewareChain.handle(event); - if (result.response) { - return result.response; + if (middlewareResult.response) { + return middlewareResult.response; } const response = await resolve(event); - // Add CORS headers to all responses CorsMiddleware.addCorsHeaders(response, event.request); return response; }; -export const handleError: HandleServerError = async ({ error, event }) => { - logError(error, event); - const body = createErrorResponseBody(error); +const handleParaglide: Handle = ({ event, resolve }) => + paraglideMiddleware(event.request, ({ request, locale }) => { + event.request = request; - return { - message: body.message || 'Internal server error' - }; -}; + return resolve(event, { + transformPageChunk: ({ html }) => html.replace('%paraglide.lang%', locale) + }); + }); + +export const handle = sequence(originalHandle, handleParaglide); diff --git a/src/hooks.ts b/src/hooks.ts new file mode 100644 index 00000000..e75600b3 --- /dev/null +++ b/src/hooks.ts @@ -0,0 +1,3 @@ +import { deLocalizeUrl } from '$lib/paraglide/runtime'; + +export const reroute = (request) => deLocalizeUrl(request.url).pathname; diff --git a/src/lib/components/app/AttachmentLink.svelte b/src/lib/components/app/AttachmentLink.svelte index 02f176e5..3ad0ce9f 100644 --- a/src/lib/components/app/AttachmentLink.svelte +++ b/src/lib/components/app/AttachmentLink.svelte @@ -13,7 +13,8 @@ + + +
+ {#each fields as field, index (index)} +
+ updateCustomFields()} + class="flex-1" + disabled={false} + /> + updateCustomFields()} + class="flex-1" + disabled={false} + /> + removeField(index)} + ariaLabel={m.custom_fields_remove_aria()} + buttonStyles="hover:bg-red-100 dark:hover:bg-red-700" + iconStyles="text-red-500" + /> +
+ {/each} +
+ + {#if fields.length === 0} +

+ {m.custom_fields_empty_message()} +

+ {/if} + diff --git a/src/lib/components/app/DeleteConfirmation.svelte b/src/lib/components/app/DeleteConfirmation.svelte index 994e5ccc..adeb26b0 100644 --- a/src/lib/components/app/DeleteConfirmation.svelte +++ b/src/lib/components/app/DeleteConfirmation.svelte @@ -2,24 +2,38 @@ import { scale } from 'svelte/transition'; import Trash2 from '@lucide/svelte/icons/trash-2'; import Button from '../ui/button/button.svelte'; + import * as m from '$lib/paraglide/messages'; let { onConfirm, open = $bindable() } = $props(); {#if open} -
+
- + -

Delete

-
Are you sure you want to delete?
-
- - +

+ {m.delete_dialog_title()} +

+
{m.delete_dialog_message()}
+
+ +
diff --git a/src/lib/components/app/FileDropZone.svelte b/src/lib/components/app/FileDropZone.svelte index 703af8b4..63be6279 100644 --- a/src/lib/components/app/FileDropZone.svelte +++ b/src/lib/components/app/FileDropZone.svelte @@ -49,6 +49,9 @@ ...rest }: Props = $props(); + const inputId = $derived(id); + const labelId = $derived(`${inputId}-label`); + let uploading = $state(false); let previewSrc = $state(); let fileType = $state<'image' | 'pdf' | 'unknown'>('unknown'); @@ -60,7 +63,7 @@ (variant === 'image' ? 'Click or drag image to upload' : variant === 'attachment' - ? 'Drop receipt here, or click to select' + ? 'Drop file here, or click to select' : 'Click or drag files to upload') ); @@ -220,17 +223,19 @@ const canUploadFiles = $derived(!disabled && !uploading); -
+
{#if shouldShowFile} {#if fileType === 'image' && previewSrc && showPreview}
Uploaded
@@ -271,29 +279,40 @@ {:else}