feat(mcp): add OAuth 2.1 for claude.ai MCP connector (#2829)

* feat(mcp): add OAuth 2.1 authentication for claude.ai MCP connector

Enable OAuth 2.1 (RFC 8414 + RFC 7591) for the MCP endpoint using
better-auth's MCP plugin. This allows claude.ai and other MCP clients
to authenticate via Dynamic Client Registration and Authorization Code
flow with PKCE, using the existing login page.

- Add `mcp()` plugin to better-auth config with login page redirect
- Add `.well-known/oauth-authorization-server` discovery endpoint
- Add `.well-known/oauth-protected-resource` metadata endpoint
- Update MCP handler to accept Bearer tokens via `getMcpSession`
- Retain `x-api-key` fallback for backward compatibility
- Return proper HTTP 401 + WWW-Authenticate header for unauthed requests
- Add `oauthApplication`, `oauthAccessToken`, `oauthConsent` tables

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mcp): use typed AuthError and suppress noisy verifyApiKey throws

- Replace string-matching error detection with instanceof AuthError
- Wrap verifyApiKey in try-catch to avoid logging malformed key errors
- Move console.error below auth check so 401s don't pollute logs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(mcp): add database migration for OAuth tables

Creates oauth_application, oauth_access_token, and oauth_consent tables
required for MCP OAuth 2.1 Dynamic Client Registration flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mcp): resolve OAuth Bearer token auth for oRPC tool calls

The oRPC context only checked session cookies and API keys, causing
MCP tool calls from OAuth clients (claude.ai) to fail with Unauthorized
even though the MCP endpoint itself authenticated successfully.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mcp): look up user by userId from OAuth access token

getMcpSession returns OAuthAccessToken (with userId), not a session
object with a user property. Must query the user table by userId.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor(mcp): migrate from deprecated mcp() plugin to @better-auth/oauth-provider

The better-auth MCP plugin is marked for deprecation in favor of the
OAuth Provider plugin. This refactors the entire OAuth 2.1 flow to use
@better-auth/oauth-provider with JWT-based token verification, replacing
the opaque token lookup via getMcpSession().

Key changes:
- Replace mcp() with jwt() + oauthProvider() in auth config
- Replace getMcpSession() with verifyAccessToken() (JWT/JWKS)
- Replace oauthApplication table with oauthClient (RFC 7591 compliant)
- Add oauthRefreshToken table and jwks table for JWT signing keys
- Extract shared authBaseUrl and verifyOAuthToken helper
- Hoist McpServer to module scope (avoid per-request reconstruction)
- Update .well-known discovery endpoints for OAuth Provider

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mcp): resolve OAuth 2.1 flow for claude.ai MCP connector

Multiple fixes required to make the full MCP OAuth flow work with
claude.ai's implementation:

- Add RFC 8414 discovery route at /.well-known/oauth-authorization-server/api/auth
  (claude.ai appends the issuer path per spec)
- Add /auth/oauth server route to handle login/consent flow
  (generates auth codes directly, bypassing h3 cookie issues)
- Default token_endpoint_auth_method to "none" via onRequest plugin hook
  (claude.ai omits this field, causing confidential client rejection)
- Strip prompt=consent from authorize requests via onRequest hook
  (better-auth checks prompt before skipConsent, causing redirect loops)
- Add validAudiences for MCP resource URL
  (JWT aud claim contains the MCP URL, not the base URL)
- Disable CSRF check for cross-origin OAuth flows
- Log token endpoint errors for debugging
- Set skipConsent on OAuth clients via /auth/oauth route

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(mcp): harden OAuth security and enforce lock on delete

- Scope CSRF bypass to OAuth2 paths only instead of disabling globally
- Validate redirect_uri against registered client URIs (prevents code interception)
- Use pathname matching instead of fragile url.includes() for route guards
- Replace biased modulo code generation with crypto.randomBytes
- Enforce resume lock check on delete (previously silently ignored)
- Remove debug console.error logging of OAuth token response bodies
- Use Response.json() consistently for MCP 401 response

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update dependencies, refine ignore patterns, and enhance documentation

- Updated various dependencies in package.json and pnpm-lock.yaml for improved stability and features.
- Adjusted ignore patterns in knip.json to include specific component directories.
- Enhanced documentation for the MCP server, clarifying authentication methods and configuration options.
- Made minor adjustments to VSCode settings for better code organization.

* fix(mcp): resolve OAuth client registration and stale token handling

Claude.ai sends token_endpoint_auth_method: "client_secret_post" without
a client_secret during Dynamic Client Registration, causing Better Auth to
reject it as an unauthenticated confidential client. Force to "none" for
unauthenticated registrations.

Also catch JWKS verification errors (e.g. key rotation after redeployment)
so stale Bearer tokens return 401 instead of 200 with an error body,
allowing clients to re-initiate the OAuth flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* reiterate on tests

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Amruth Pillai <im.amruth@gmail.com>
This commit is contained in:
Christian Pojoni
2026-03-24 11:03:56 +01:00
committed by GitHub
parent e3274d7c95
commit b4aaf9712f
103 changed files with 5221 additions and 3174 deletions
+2 -2
View File
@@ -22,7 +22,7 @@ jobs:
- run: vp install
- run: vp fmt
- run: vp lint --fix
- run: vp test
- run: vp check --fix
- uses: autofix-ci/action@7a166d7532b277f34e16238930461bf77f9d7ed8
+1
View File
@@ -5,6 +5,7 @@ dist
.output
.vercel
.cursor
.claude
TODO.md
coverage
.netlify
+1
View File
@@ -3,6 +3,7 @@
"editor.defaultFormatter": "oxc.oxc-vscode"
},
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit",
"source.fixAll.oxc": "explicit"
},
"editor.defaultFormatter": "oxc.oxc-vscode",
+96 -89
View File
@@ -1,12 +1,71 @@
# AGENTS.md
## Cursor Cloud specific instructions
## Overview
### Overview
Reactive Resume is a single-package full-stack TypeScript app (not a monorepo) built with [TanStack Start](https://tanstack.com/start/latest/docs/framework/react/overview) (React, Vite, Nitro). It serves both frontend and API on port 3000.
Reactive Resume is a single-package full-stack TypeScript app (not a monorepo) built with TanStack Start (React 19, Vite, Nitro). It serves both frontend and API on port 3000.
This project uses [Vite+](https://vite.dev/blog/announcing-viteplus), a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. All modules should be imported from the `vite-plus` dependency (e.g., `import { defineConfig } from 'vite-plus'` or `import { expect, test, vi } from 'vite-plus/test'`).
### Infrastructure services
## Key Libraries
| Area | Library | Docs |
| -------------------- | ------------------------------------------------------------------------ | ---------------------------------- |
| Frontend framework | React | https://react.dev |
| Full-stack framework | TanStack Start | https://tanstack.com/start/latest |
| Router | TanStack React Router | https://tanstack.com/router/latest |
| Server state | TanStack React Query | https://tanstack.com/query/latest |
| Client state | Zustand (+ Zundo for undo/redo, Immer for immutable updates) | https://zustand.docs.pmnd.rs |
| Type-safe API | oRPC | https://orpc.unnoq.com |
| Database ORM | Drizzle ORM (PostgreSQL) | https://orm.drizzle.team |
| Authentication | Better Auth (+ Drizzle adapter, OAuth provider, API keys, 2FA, Passkeys) | https://www.better-auth.com |
| Styling | Tailwind CSS | https://tailwindcss.com |
| UI Components | shadcn/ui (built on Base UI) | https://ui.shadcn.com |
| Icons | Phosphor Icons | https://phosphoricons.com |
| Forms | React Hook Form (+ Zod resolvers) | https://react-hook-form.com |
| Rich text editor | Tiptap | https://tiptap.dev |
| Validation | Zod | https://zod.dev |
| AI | Vercel AI SDK (OpenAI, Anthropic, Google, Ollama providers) | https://ai-sdk.dev |
| MCP | Model Context Protocol SDK | https://modelcontextprotocol.io |
| i18n | Lingui | https://lingui.dev |
| Animations | Motion (Framer Motion) | https://motion.dev |
| PDF export | Puppeteer Core (via Browserless) | https://pptr.dev |
| Drag and drop | dnd-kit | https://dndkit.com |
| Server engine | Nitro | https://nitro.build |
| PWA | Vite PWA Plugin | https://vite-pwa-org.netlify.app |
| Unused deps | Knip | https://knip.dev |
## Project Structure
```
src/
components/ UI, resume, layout, animation, theme, locale components
routes/ File-based routing (TanStack React Router)
integrations/ Feature modules (auth, drizzle, orpc, ai, email, jobs, mcp, storage)
schema/ Zod schemas for resume data validation
utils/ Utility functions (locale, theme, env, resume processing)
dialogs/ Modal/dialog components
hooks/ Custom React hooks
styles/ CSS and Tailwind configuration
stores/ Zustand stores (resume, AI, dialog, command palette)
migrations/ Drizzle database migrations
locales/ Lingui i18n message catalogs (47+ locales)
```
### Key Config Files
- `vite.config.ts` — Vite + Nitro + TanStack Start + PWA + Tailwind + Lingui
- `drizzle.config.ts` — PostgreSQL dialect, schema at `./src/integrations/drizzle/schema.ts`
- `tsconfig.json` — ES2022, strict mode, path alias `@/*``./src/*`
- `lingui.config.ts` — i18n extraction and locale configuration
- `components.json` — shadcn CLI configuration
### API Architecture
- **oRPC API** (`/api/rpc/*`) — Type-safe RPC with routers for: `ai`, `auth`, `resume`, `storage`, `printer`, `jobs`, `statistics`, `flags`. Three procedure types: `publicProcedure`, `protectedProcedure`, `serverOnlyProcedure`.
- **Better Auth API** (`/api/auth/*`) — OAuth, session management, social provider callbacks.
- **MCP Server** (`/mcp/`) — Model Context Protocol with OAuth Bearer tokens and API key auth. Exposes resumes as resources and tools for resume CRUD.
## Infrastructure Services
Before running the dev server, Docker must be running with at least PostgreSQL. Start services via `compose.dev.yml`:
@@ -18,7 +77,7 @@ sudo docker compose -f compose.dev.yml up -d postgres browserless
- **PostgreSQL** (port 5432) — required. The app auto-runs Drizzle migrations on startup via a Nitro plugin.
- **Browserless** (port 4000) — required for PDF export. Maps container port 3000 to host port 4000.
### Environment variables
## Environment Variables
Copy `.env.example` to `.env` if not present. Key notes for local dev:
@@ -28,99 +87,47 @@ Copy `.env.example` to `.env` if not present. Key notes for local dev:
- `DATABASE_URL` — PostgreSQL connection using `postgres:postgres` credentials on localhost:5432.
- S3/Storage and SMTP vars can be left empty — the app falls back to local filesystem and console-logged emails.
### Common commands
## Common Commands
See `scripts` in `package.json`. Key ones:
`vp` is the global CLI for Vite+. Do not use pnpm/npm/yarn directly — Vite+ wraps the underlying package manager.
| Task | Command |
| -------------- | --------------------------------------------------------------- |
| Dev server | `pnpm dev` (port 3000) |
| Lint (Oxlint) | `pnpm lint` |
| Format (Oxfmt) | `pnpm fmt` |
| Typecheck | `pnpm typecheck` |
| DB migrations | `pnpm db:generate` / `pnpm db:migrate` (auto-runs on dev start) |
| Task | Command |
| -------------------------- | --------------------------------------------------------------- |
| Install dependencies | `vp install` |
| Dev server (port 3000) | `vp dev` |
| Lint (Oxlint, type-aware) | `vp lint --type-aware` |
| Format (Oxfmt) | `vp fmt` |
| Check (lint + fmt + types) | `vp check` |
| Typecheck | `pnpm typecheck` (uses tsgo) |
| Run tests | `vp test` |
| DB migrations | `pnpm db:generate` / `pnpm db:migrate` (auto-runs on dev start) |
| DB studio | `pnpm db:studio` |
| i18n extraction | `pnpm lingui:extract` |
| Add a dependency | `vp add <package>` |
| Remove a dependency | `vp remove <package>` |
| One-off binary | `vp dlx <package>` |
| Build for production | `vp build` |
| Preview production build | `vp preview` |
| Start production server | `pnpm start` |
### Gotchas
## Vite+ Pitfalls
- **Do not use pnpm/npm/yarn directly** for package operations — use `vp add`, `vp remove`, `vp install`, etc.
- **Do not run `vp vitest` or `vp oxlint`** — they don't exist. Use `vp test` and `vp lint`.
- **Do not install Vitest, Oxlint, Oxfmt, or tsdown directly** — Vite+ bundles them.
- **Import from `vite-plus`**, not from `vite` or `vitest` directly (e.g., `import { defineConfig } from 'vite-plus'`).
- **Vite+ commands take precedence** over `package.json` scripts. If there's a naming conflict, use `vp run <script>`.
- **Use `vp dlx`** instead of `npx` or `pnpm dlx`.
- **Type-aware linting** works out of the box with `vp lint --type-aware` — no need to install `oxlint-tsgolint`.
## Gotchas
- The Docker daemon needs `fuse-overlayfs` storage driver and `iptables-legacy` in the cloud VM (nested container environment).
- `pnpm.onlyBuiltDependencies` in `package.json` controls which packages are allowed to run install scripts — no interactive `pnpm approve-builds` needed.
- Email verification is optional in dev — after signup, click "Continue" to skip.
- Vite 8 is beta (`^8.0.0-beta.15`); Nitro uses a nightly build. Occasional upstream issues may occur.
<!--VITE PLUS START-->
# Using Vite+, the Unified Toolchain for the Web
This project is using Vite+, a unified toolchain built on top of Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, and Vite Task. Vite+ wraps runtime management, package management, and frontend tooling in a single global CLI called `vp`. Vite+ is distinct from Vite, but it invokes Vite through `vp dev` and `vp build`.
## Vite+ Workflow
`vp` is a global binary that handles the full development lifecycle. Run `vp help` to print a list of commands and `vp <command> --help` for information about a specific command.
### Start
- create - Create a new project from a template
- migrate - Migrate an existing project to Vite+
- config - Configure hooks and agent integration
- staged - Run linters on staged files
- install (`i`) - Install dependencies
- env - Manage Node.js versions
### Develop
- dev - Run the development server
- check - Run format, lint, and TypeScript type checks
- lint - Lint code
- fmt - Format code
- test - Run tests
### Execute
- run - Run monorepo tasks
- exec - Execute a command from local `node_modules/.bin`
- dlx - Execute a package binary without installing it as a dependency
- cache - Manage the task cache
### Build
- build - Build for production
- pack - Build libraries
- preview - Preview production build
### Manage Dependencies
Vite+ automatically detects and wraps the underlying package manager such as pnpm, npm, or Yarn through the `packageManager` field in `package.json` or package manager-specific lockfiles.
- add - Add packages to dependencies
- remove (`rm`, `un`, `uninstall`) - Remove packages from dependencies
- update (`up`) - Update packages to latest versions
- dedupe - Deduplicate dependencies
- outdated - Check for outdated packages
- list (`ls`) - List installed packages
- why (`explain`) - Show why a package is installed
- info (`view`, `show`) - View package information from the registry
- link (`ln`) / unlink - Manage local package links
- pm - Forward a command to the package manager
### Maintain
- upgrade - Update `vp` itself to the latest version
These commands map to their corresponding tools. For example, `vp dev --port 3000` runs Vite's dev server and works the same as Vite. `vp test` runs JavaScript tests through the bundled Vitest. The version of all tools can be checked using `vp --version`. This is useful when researching documentation, features, and bugs.
## Common Pitfalls
- **Using the package manager directly:** Do not use pnpm, npm, or Yarn directly. Vite+ can handle all package manager operations.
- **Always use Vite commands to run tools:** Don't attempt to run `vp vitest` or `vp oxlint`. They do not exist. Use `vp test` and `vp lint` instead.
- **Running scripts:** Vite+ commands take precedence over `package.json` scripts. If there is a `test` script defined in `scripts` that conflicts with the built-in `vp test` command, run it using `vp run test`.
- **Do not install Vitest, Oxlint, Oxfmt, or tsdown directly:** Vite+ wraps these tools. They must not be installed directly. You cannot upgrade these tools by installing their latest versions. Always use Vite+ commands.
- **Use Vite+ wrappers for one-off binaries:** Use `vp dlx` instead of package-manager-specific `dlx`/`npx` commands.
- **Import JavaScript modules from `vite-plus`:** Instead of importing from `vite` or `vitest`, all modules should be imported from the project's `vite-plus` dependency. For example, `import { defineConfig } from 'vite-plus';` or `import { expect, test, vi } from 'vite-plus/test';`. You must not install `vitest` to import test utilities.
- **Type-Aware Linting:** There is no need to install `oxlint-tsgolint`, `vp lint --type-aware` works out of the box.
- Vite and Nitro use beta/nightly builds. Occasional upstream issues may occur.
## Review Checklist for Agents
- [ ] Run `vp install` after pulling remote changes and before getting started.
- [ ] Run `vp check` and `vp test` to validate changes.
<!--VITE PLUS END-->
+133 -5
View File
@@ -12,7 +12,17 @@ The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is a standar
## Prerequisites
<Steps>
<Step title="Create an API key">
<Step title="Choose your authentication method">
Reactive Resume MCP supports two authentication methods:
- **OAuth2 (recommended):** best user experience for clients that support MCP OAuth.
- **API key (fallback):** works in all clients that can send custom headers.
Use OAuth2 whenever your MCP client supports it. Use API key only when OAuth is unavailable in that client.
</Step>
<Step title="If using API key, create one">
Head over to [https://rxresu.me](https://rxresu.me) (or your self-hosted instance), sign in, and navigate to **Settings → API Keys**. Click **Create a new API key**, give it a name, and copy the secret — it's only shown once.
For the full walkthrough, see [Using the API](/guides/using-the-api).
@@ -22,11 +32,31 @@ The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is a standar
## Configuration
There are two ways to connect, depending on whether your MCP client supports the Streamable HTTP transport natively.
There are two transport options, and each can use either OAuth2 or API key depending on your client capabilities.
### Method 1: Streamable HTTP (recommended)
If your client supports the `url` field (e.g. **Cursor**), use this — no extra dependencies required:
If your client supports the `url` field (e.g. **Cursor**, **Codex**, Claude custom connectors), use this.
#### Option A: OAuth2 (recommended)
Most OAuth-capable clients only need the MCP URL:
```json
{
"mcpServers": {
"reactive-resume": {
"url": "https://rxresu.me/mcp"
}
}
}
```
Then connect/sign in from the client UI (or with the client's OAuth login command).
#### Option B: API key (fallback)
If OAuth is not supported in your client, send `x-api-key`:
```json
{
@@ -43,7 +73,9 @@ If your client supports the `url` field (e.g. **Cursor**), use this — no extra
### Method 2: mcp-remote
If your client only supports `command` / `args` (e.g. **Claude Desktop**), use [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) as a bridge. This requires [Node.js](https://nodejs.org) **20 or later**.
If your client only supports `command` / `args` (for example, local-only Claude Desktop config), use [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) as a bridge. This requires [Node.js](https://nodejs.org) **20 or later**.
`mcp-remote` is most commonly used with API keys:
```json
{
@@ -63,9 +95,103 @@ If your client only supports `command` / `args` (e.g. **Claude Desktop**), use [
| Client | Config file |
| ----------------- | ------------------------------------------------------------------------------------------------ |
| Cursor | `.cursor/mcp.json` in your project or home directory |
| Claude Desktop | `claude_desktop_config.json` ([docs](https://modelcontextprotocol.io/docs/tools/claude-desktop)) |
| Claude Desktop | `claude_desktop_config.json` ([docs](https://modelcontextprotocol.io/quickstart/user)) |
| Codex | `~/.codex/config.toml` or `.codex/config.toml` ([docs](https://developers.openai.com/codex/mcp)) |
| Other MCP clients | Refer to the client's documentation |
## Authentication Details (How Reactive Resume MCP Works)
Reactive Resume MCP accepts authentication in this order:
1. **Bearer token (OAuth2 access token)** via `Authorization: Bearer <token>`
2. **API key fallback** via `x-api-key: <key>`
If neither is valid, the MCP endpoint responds with `401` and advertises OAuth metadata using:
- `WWW-Authenticate: Bearer resource_metadata="<instance>/.well-known/oauth-protected-resource"`
This lets OAuth-capable MCP clients discover and complete the OAuth flow automatically.
### OAuth2 flow used by this server
Reactive Resume is configured as an OAuth authorization server for MCP clients:
- The MCP endpoint is `https://rxresu.me/mcp`.
- OAuth discovery metadata is exposed under `/.well-known/*` endpoints.
- The login/authorization route is `/auth/oauth`.
- If the user is not signed in, `/auth/oauth` redirects to `/auth/login`, then resumes OAuth.
- If the user is signed in, `/auth/oauth` validates `client_id` and `redirect_uri`, issues an authorization code, and redirects back to the client.
- PKCE parameters (`code_challenge`, `code_challenge_method`) are preserved in the authorization flow.
## Popular Client Setup
### Cursor
**OAuth2 (recommended):**
```json
{
"mcpServers": {
"reactive-resume": {
"url": "https://rxresu.me/mcp"
}
}
}
```
**API key fallback:**
```json
{
"mcpServers": {
"reactive-resume": {
"url": "https://rxresu.me/mcp",
"headers": {
"x-api-key": "your-api-key"
}
}
}
}
```
### Codex (CLI / IDE extension)
Add server:
```bash
codex mcp add reactive-resume --url https://rxresu.me/mcp
```
Then log in with OAuth:
```bash
codex mcp login reactive-resume
```
API key fallback (`config.toml`):
```toml
[mcp_servers."reactive-resume"]
url = "https://rxresu.me/mcp"
http_headers = { "x-api-key" = "your-api-key" }
```
### Claude (web app custom connector)
Add `https://rxresu.me/mcp` as a custom remote MCP connector, then connect with OAuth in Claude's connector UI.
### Claude Desktop (local config file)
Use `mcp-remote` bridge with API key (example shown above in **Method 2**).
## External References
- [Cursor MCP docs](https://cursor.sh/docs/mcp)
- [MCP quickstart for users (Claude Desktop example)](https://modelcontextprotocol.io/quickstart/user)
- [OpenAI Codex MCP docs](https://developers.openai.com/codex/mcp)
- [Claude custom connectors (remote MCP)](https://claude.com/docs/connectors/custom/remote-mcp)
- [MCP Authorization spec](https://modelcontextprotocol.io/specification/latest/basic/authorization)
## Self-Hosting
If you're running a self-hosted Reactive Resume instance, replace `https://rxresu.me/mcp` with your instance URL:
@@ -168,6 +294,8 @@ Once your MCP client is connected, you can use natural language to interact with
| Issue | Solution |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| "Unauthorized" with no login prompt | Your client may not support MCP OAuth discovery. Use API key mode (`x-api-key`) |
| OAuth login opens but fails redirect/callback | Confirm your client's MCP OAuth callback settings and retry the connection |
| "API error (401)" | Your API key is invalid or expired. Create a new one in **Settings → API Keys** |
| "API error (404)" | The resume ID doesn't exist. Use `list_resumes` to find valid IDs |
| "API error (403)" | The resume is locked. Unlock it in the Reactive Resume dashboard |
+1 -1
View File
@@ -5,5 +5,5 @@
"project": ["src/**/*.{js,jsx,ts,tsx,mdx,css}"],
"ignoreBinaries": ["mint"],
"ignoreDependencies": ["npm-check-updates", "node-addon-api", "node-gyp"],
"ignore": ["src/schema/**/*.ts", "src/components/**/*.{ts,tsx}"]
"ignore": ["src/schema/**/*.ts", "src/components/ui/**/*.{ts,tsx}"]
}
-33
View File
@@ -244,10 +244,6 @@ msgstr "Voeg ry daarna by"
msgid "Add Row Before"
msgstr "Voeg ry voor by"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Bygevoeg"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "KI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "KI-gesels"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI het 'n paar ongeldige verwysings teruggegee."
@@ -414,10 +406,6 @@ msgstr "Studierigting"
msgid "Artificial Intelligence"
msgstr "Kunsmatige Intelligensie"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Vra my om jou CV op te dateer..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Aspekverhouding"
@@ -623,10 +611,6 @@ msgstr "Sirkel"
msgid "Clear all"
msgstr "Maak alles skoon"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Vee gesprekgeskiedenis uit"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Klik hier om 'n lêer te kies om in te voer"
@@ -1086,10 +1070,6 @@ msgstr "bv. 150000"
msgid "e.g. 50000"
msgstr "bv. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "bv. Verander my naam na..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "bv. frontend-ontwikkelaar-werk in Berlyn"
@@ -2205,10 +2185,6 @@ msgstr "Verwyder"
msgid "Remove Password"
msgstr "Verwyder wagwoord"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Verwyder"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Besig om wagwoordbeskerming te verwyder..."
@@ -2748,10 +2724,6 @@ msgstr "Daar was 'n probleem tydens die generering van die DOCX, probeer assebli
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Daar was 'n probleem met die generering van die PDF. Probeer asseblief weer oor 'n ruk."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Dink na..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Werk CV by"
msgid "Update your password"
msgstr "Werk jou wagwoord by"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Opgedateer"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Besig om jou wagwoord by te werk..."
@@ -3276,4 +3244,3 @@ msgstr "Zoem uit"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zoeloe"
-33
View File
@@ -244,10 +244,6 @@ msgstr "ከዚህ በኋላ ረድፍ ያክሉ"
msgid "Add Row Before"
msgstr "ከዚህ በፊት ረድፍ ያክሉ"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "ተጨምሯል"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "አፍሪካንስ"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI ውይይት"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr ""
@@ -414,10 +406,6 @@ msgstr "የስልጠና መስክ"
msgid "Artificial Intelligence"
msgstr "አርቲፊሻል ኢንተለጀንስ"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "የእርስዎን ማስታወሻ እንዲያዘምን ጠይቁኝ..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "የመገናኛ መጠን"
@@ -623,10 +611,6 @@ msgstr "ክብ"
msgid "Clear all"
msgstr ""
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "የውይይት ታሪክ አጽዳ"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "ፋይል ለማምጣት ለመምረጥ እዚህ ጠቅ ያድርጉ"
@@ -1086,10 +1070,6 @@ msgstr ""
msgid "e.g. 50000"
msgstr ""
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "ለምሳሌ ስሜን ወደ...ቀይር"
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr ""
@@ -2205,10 +2185,6 @@ msgstr "አስወግድ"
msgid "Remove Password"
msgstr "የይለፍ ቃል አስወግድ"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "ተወግዷል"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "የይለፍ ቃል ጥበቃን በማስወገድ ላይ…"
@@ -2748,10 +2724,6 @@ msgstr ""
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF በማመንጨት ጊዜ ችግኝ ተፈጥሯል፣ እባክዎን ጥቂት ጊዜ በኋላ ደግመው ይሞክሩ።"
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "እያሰብኩ ነው..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "የየታሪክ ማቅረቢያን አዘምን"
msgid "Update your password"
msgstr "የይለፍ ቃልዎን አዘምኑ"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "ተዘምኗል"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "የይለፍ ቃልዎን በመዘመን ላይ…"
@@ -3276,4 +3244,3 @@ msgstr "አጉር"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "ዙሉ"
-33
View File
@@ -244,10 +244,6 @@ msgstr "إضافة صف بعد"
msgid "Add Row Before"
msgstr "إضافة صف قبل"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "تمت الإضافة"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "الأفريقانس"
msgid "AI"
msgstr "الذكاء الاصطناعي"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "محادثة الذكاء الاصطناعي"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "أرجع الذكاء الاصطناعي بعض المراجع غير الصالحة"
@@ -414,10 +406,6 @@ msgstr "مجال الدراسة"
msgid "Artificial Intelligence"
msgstr "الذكاء الاصطناعي"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "اطلب مني تحديث سيرتك الذاتية..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "نسبة الأبعاد"
@@ -623,10 +611,6 @@ msgstr "دائرة"
msgid "Clear all"
msgstr "مسح الكل"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "مسح سجل المحادثة"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "انقر هنا لتحديد ملف لاستيراده"
@@ -1086,10 +1070,6 @@ msgstr "على سبيل المثال 150000"
msgid "e.g. 50000"
msgstr "على سبيل المثال 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "مثال: غيّر اسمي إلى..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "على سبيل المثال وظائف مطور واجهة أمامية في برلين"
@@ -2205,10 +2185,6 @@ msgstr "إزالة"
msgid "Remove Password"
msgstr "إزالة كلمة المرور"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "تمت الإزالة"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "جاري إزالة حماية كلمة المرور..."
@@ -2748,10 +2724,6 @@ msgstr "حدثت مشكلة أثناء إنشاء DOCX، يرجى المحاول
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "حدثت مشكلة أثناء إنشاء ملف PDF، يُرجى المحاولة مرة أخرى بعد فترة."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "أفكر..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "تحديث السيرة الذاتية"
msgid "Update your password"
msgstr "حدّث كلمة المرور الخاصة بك"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "تم التحديث"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "جاري تحديث كلمة المرور..."
@@ -3276,4 +3244,3 @@ msgstr "تصغير"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "الزولو"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Sonra Sətir əlavə et"
msgid "Add Row Before"
msgstr "Əvvəl Sətir əlavə et"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Əlavə edildi"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "Süni İntellekt"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI Söhbət"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI etibarsız istinadlar qaytardı."
@@ -414,10 +406,6 @@ msgstr "Təhsil sahəsi"
msgid "Artificial Intelligence"
msgstr "Süni İntellekt"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "CV-nizi yeniləməyimi xahiş edin..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Propor­siya"
@@ -623,10 +611,6 @@ msgstr "Dairə"
msgid "Clear all"
msgstr "Həps et"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Söhbət tarixçəsini təmizlə"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "İdxal üçün fayl seçmək üçün bura klikləyin"
@@ -1086,10 +1070,6 @@ msgstr "məsələn 150000"
msgid "e.g. 50000"
msgstr "məsələn 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "məs. Adımı ...ə dəyiş"
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "Məsələn, Berlin şəhərində frontend inkişaf etdirici işləri"
@@ -2205,10 +2185,6 @@ msgstr "Sil"
msgid "Remove Password"
msgstr "Parolu Sil"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Silindi"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Parol qorunması silinir..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX yaradılarkən problem yaranıb, zəhmət olmasa yenidən cəhd edi
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF yaradılarkən problem yarandı, zəhmət olmasa, bir müddət sonra yenidən cəhd edin."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Düşünürəm..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Özgeçmişi Yenilə"
msgid "Update your password"
msgstr "Parolunuzu yeniləyin"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Yeniləndi"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Parolunuz yenilənir..."
@@ -3276,4 +3244,3 @@ msgstr "Uzaqlaşdır"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Добавяне на ред след"
msgid "Add Row Before"
msgstr "Добавяне на ред преди"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Добавено"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Африканс"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI чат"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI върна някои невалидни препратки"
@@ -414,10 +406,6 @@ msgstr "Област на обучение"
msgid "Artificial Intelligence"
msgstr "Изкуствен интелект"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Помолете ме да актуализирам автобиографията ви..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Съотношение на страните"
@@ -623,10 +611,6 @@ msgstr "Кръг"
msgid "Clear all"
msgstr "Изчистване на всички"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Изчистване на историята на чата"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Кликнете тук, за да изберете файл за импортиране"
@@ -1086,10 +1070,6 @@ msgstr "напр. 150000"
msgid "e.g. 50000"
msgstr "напр. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "напр. Промени името ми на..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "напр. работни места за frontend разработчици в Берлин"
@@ -2205,10 +2185,6 @@ msgstr "Премахване"
msgid "Remove Password"
msgstr "Премахване на парола"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Премахнато"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Премахване на защитата с парола..."
@@ -2748,10 +2724,6 @@ msgstr "Имаше проблем при генерирането на DOCX, м
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Възникна проблем при генерирането на PDF, моля, опитайте отново след известно време."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Мисля..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Актуализиране на автобиография"
msgid "Update your password"
msgstr "Актуализирайте паролата си"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Актуализирано"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Актуализиране на паролата ви..."
@@ -3276,4 +3244,3 @@ msgstr "Намаляване"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Зулуски"
-33
View File
@@ -244,10 +244,6 @@ msgstr "পরের দিকে সারি যোগ করুন"
msgid "Add Row Before"
msgstr "আগের দিকে সারি যোগ করুন"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "যোগ করা হয়েছে"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "আফ্রিকান্স"
msgid "AI"
msgstr "এআই"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI চ্যাট"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "এআই কিছু অবৈধ রেফারেন্স ফেরত দিয়েছে।"
@@ -414,10 +406,6 @@ msgstr "অধ্যয়নের এলাকা"
msgid "Artificial Intelligence"
msgstr "কৃত্রিম বুদ্ধিমত্তা"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "আমাকে আপনার রিজিউমে আপডেট করতে বলুন..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "আকারের অনুপাত"
@@ -623,10 +611,6 @@ msgstr "বৃত্ত"
msgid "Clear all"
msgstr "সব মুছুন"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "চ্যাট ইতিহাস মুছুন"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "ইমপোর্ট করার জন্য এখান ক্লিক করে একটি ফাইল নির্বাচন করুন"
@@ -1086,10 +1070,6 @@ msgstr "যেমন ১৫০০০০"
msgid "e.g. 50000"
msgstr "যেমন 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "যেমন আমার নাম পরিবর্তন করুন..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "যেমন: বার্লিনে ফ্রন্টএন্ড ডেভেলপার চাকরির সুযোগ"
@@ -2205,10 +2185,6 @@ msgstr "সরান"
msgid "Remove Password"
msgstr "পাসওয়ার্ড সরিয়ে ফেলুন"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "সরানো হয়েছে"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "পাসওয়ার্ড সুরক্ষা সরানো হচ্ছে..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX তৈরি করার সময় একটি সমস্য
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF তৈরি করার সময় একটি সমস্যা হয়েছে, অনুগ্রহ করে কিছু সময় পরে আবার চেষ্টা করুন।"
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "ভাবছি..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "জীবনবৃত্তান্ত আপডেট করুন"
msgid "Update your password"
msgstr "আপনার পাসওয়ার্ড আপডেট করুন"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "আপডেট করা হয়েছে"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "আপনার পাসওয়ার্ড আপডেট করা হচ্ছে..."
@@ -3276,4 +3244,3 @@ msgstr "জুম আউট"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "জুলু"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Afegeix una fila després"
msgid "Add Row Before"
msgstr "Afegeix una fila abans"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Afegit"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "IA"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Xat amb IA"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "L'IA ha retornat algunes referències invàlides."
@@ -414,10 +406,6 @@ msgstr "Àrea destudi"
msgid "Artificial Intelligence"
msgstr "Intel·ligència artificial"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Demaneu-me que actualitzi el vostre currículum..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Relació daspecte"
@@ -623,10 +611,6 @@ msgstr "Cercle"
msgid "Clear all"
msgstr "Esborra tot"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Esborra l'historial del xat"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Fes clic aquí per seleccionar un fitxer per importar"
@@ -1086,10 +1070,6 @@ msgstr "p. ex. 150000"
msgid "e.g. 50000"
msgstr "p. ex. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "p.ex. Canvia el meu nom a..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "p. ex. feines de desenvolupador/a de frontend a Berlín"
@@ -2205,10 +2185,6 @@ msgstr "Elimina"
msgid "Remove Password"
msgstr "Elimina la contrasenya"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Eliminat"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Sestà desactivant la protecció amb contrasenya..."
@@ -2748,10 +2724,6 @@ msgstr "S'ha produït un problema mentre es generava el DOCX, si us plau, torni
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Sha produït un problema en generar el PDF, torna-ho a provar més tard."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Pensant..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Actualitza el currículum"
msgid "Update your password"
msgstr "Actualitza la contrasenya"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Actualitzat"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Sestà actualitzant la contrasenya..."
@@ -3276,4 +3244,3 @@ msgstr "Allunya"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulú"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Přidat řádek za"
msgid "Add Row Before"
msgstr "Přidat řádek před"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Přidáno"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikánština"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Chat s AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI vrátila některé neplatné odkazy"
@@ -414,10 +406,6 @@ msgstr "Studijní obor"
msgid "Artificial Intelligence"
msgstr "Umělá inteligence"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Požádejte mě o aktualizaci vašeho životopisu..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Poměr stran"
@@ -623,10 +611,6 @@ msgstr "Kruh"
msgid "Clear all"
msgstr "Vymazat vše"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Vymazat historii chatu"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Kliknutím zde vyberte soubor k importu"
@@ -1086,10 +1070,6 @@ msgstr "např. 150000"
msgid "e.g. 50000"
msgstr "např. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "např. Změňte moje jméno na..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "např. frontend developer pracovních míst v Berlíně"
@@ -2205,10 +2185,6 @@ msgstr "Odstranit"
msgid "Remove Password"
msgstr "Odebrat heslo"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Odstraněno"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Odstraňování ochrany heslem…"
@@ -2748,10 +2724,6 @@ msgstr "Při generování DOCX došlo k problému, zkuste to prosím znovu."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Při generování PDF došlo k problému, zkuste to prosím znovu za chvíli."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Přemýšlím..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Aktualizovat životopis"
msgid "Update your password"
msgstr "Aktualizujte své heslo"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Aktualizováno"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Aktualizace hesla…"
@@ -3276,4 +3244,3 @@ msgstr "Oddálit"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Tilføj række efter"
msgid "Add Row Before"
msgstr "Tilføj række før"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Tilføjet"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI-chat"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI returnerede nogle ugyldige referencer"
@@ -414,10 +406,6 @@ msgstr "Studieområde"
msgid "Artificial Intelligence"
msgstr "Kunstig intelligens"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Bed mig om at opdatere dit CV..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Billedformat"
@@ -623,10 +611,6 @@ msgstr "Cirkel"
msgid "Clear all"
msgstr "Ryd alle"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Ryd chathistorik"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Klik her for at vælge en fil, der skal importeres"
@@ -1086,10 +1070,6 @@ msgstr "f.eks. 150000"
msgid "e.g. 50000"
msgstr "f.eks. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "f.eks. Skift mit navn til..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "f.eks. frontend-udvikler job i Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Fjern"
msgid "Remove Password"
msgstr "Fjern adgangskode"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Fjernet"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Fjerner adgangskodebeskyttelse..."
@@ -2748,10 +2724,6 @@ msgstr "Der opstod et problem under genereringen af DOCX'en, prøv venligst igen
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Der opstod et problem under generering af PDF'en, prøv igen om lidt."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Tænker..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Opdater CV"
msgid "Update your password"
msgstr "Opdater din adgangskode"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Opdateret"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Opdaterer din adgangskode..."
@@ -3276,4 +3244,3 @@ msgstr "Zoom ud"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Zeile danach einfügen"
msgid "Add Row Before"
msgstr "Zeile davor einfügen"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Hinzugefügt"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "KI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "KI-Chat"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI hat einige ungültige Referenzen zurückgegeben"
@@ -414,10 +406,6 @@ msgstr "Studienfach"
msgid "Artificial Intelligence"
msgstr "Künstliche Intelligenz"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Fragen Sie mich, Ihren Lebenslauf zu aktualisieren..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Seitenverhältnis"
@@ -623,10 +611,6 @@ msgstr "Kreis"
msgid "Clear all"
msgstr "Alles löschen"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Chatverlauf löschen"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Hier klicken, um eine Datei zum Importieren auszuwählen"
@@ -1086,10 +1070,6 @@ msgstr "z.B. 150000"
msgid "e.g. 50000"
msgstr "z.B. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "z. B. meinen Namen ändern zu..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "z.B. Frontend Entwickler Jobs in Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Entfernen"
msgid "Remove Password"
msgstr "Passwort entfernen"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Entfernt"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Passwortschutz wird entfernt..."
@@ -2748,10 +2724,6 @@ msgstr "Bei der Erstellung der DOCX-Datei ist ein Problem aufgetreten. Bitte ver
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Beim Erzeugen des PDFs ist ein Problem aufgetreten, bitte versuche es in einiger Zeit erneut."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Denkt nach..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Lebenslauf aktualisieren"
msgid "Update your password"
msgstr "Aktualisieren Sie Ihr Passwort"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Aktualisiert"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Ihr Passwort wird aktualisiert..."
@@ -3276,4 +3244,3 @@ msgstr "Herauszoomen"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Προσθήκη γραμμής μετά"
msgid "Add Row Before"
msgstr "Προσθήκη γραμμής πριν"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Προστέθηκε"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Αφρικάανς"
msgid "AI"
msgstr "ΤΝ"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Συνομιλία AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "Η AI επέστρεψε κάποιες άκυρες αναφορές"
@@ -414,10 +406,6 @@ msgstr "Τομέας σπουδών"
msgid "Artificial Intelligence"
msgstr "Τεχνητή Νοημοσύνη"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Ζητήστε μου να ενημερώσω το βιογραφικό σας..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Αναλογία διαστάσεων"
@@ -623,10 +611,6 @@ msgstr "Κύκλος"
msgid "Clear all"
msgstr "Εκκαθάριση όλων"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Εκκαθάριση ιστορικού συνομιλίας"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Κάντε κλικ εδώ για να επιλέξετε ένα αρχείο προς εισαγωγή"
@@ -1086,10 +1070,6 @@ msgstr "π.χ. 150000"
msgid "e.g. 50000"
msgstr "π.χ. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "π.χ. Άλλαξε το όνομά μου σε..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "π.χ. frontend developer θέσεις εργασίας σε Βερολίνο"
@@ -2205,10 +2185,6 @@ msgstr "Αφαίρεση"
msgid "Remove Password"
msgstr "Κατάργηση κωδικού πρόσβασης"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Αφαιρέθηκε"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Κατάργηση προστασίας με κωδικό πρόσβασης..."
@@ -2748,10 +2724,6 @@ msgstr "Υπήρξε ένα πρόβλημα κατά τη δημιουργία
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Παρουσιάστηκε πρόβλημα κατά τη δημιουργία του PDF, δοκιμάστε ξανά σε λίγο."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Σκέφτομαι..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Ενημέρωση βιογραφικού σημειώματος"
msgid "Update your password"
msgstr "Ενημερώστε τον κωδικό πρόσβασής σας"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Ενημερώθηκε"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Ενημέρωση του κωδικού πρόσβασής σας..."
@@ -3276,4 +3244,3 @@ msgstr "Σμίκρυνση"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Ζουλού"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Add Row After"
msgid "Add Row Before"
msgstr "Add Row Before"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Added"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI Chat"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI returned some invalid references"
@@ -414,10 +406,6 @@ msgstr "Area of Study"
msgid "Artificial Intelligence"
msgstr "Artificial Intelligence"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Ask me to update your resume..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Aspect Ratio"
@@ -623,10 +611,6 @@ msgstr "Circle"
msgid "Clear all"
msgstr "Clear all"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Clear chat history"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Click here to select a file to import"
@@ -1086,10 +1070,6 @@ msgstr "e.g. 150000"
msgid "e.g. 50000"
msgstr "e.g. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "e.g. Change my name to..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "e.g. frontend developer jobs in Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Remove"
msgid "Remove Password"
msgstr "Remove Password"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Removed"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Removing password protection..."
@@ -2748,10 +2724,6 @@ msgstr "There was a problem while generating the DOCX, please try again."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "There was a problem while generating the PDF, please try again in some time."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Thinking..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Update Resume"
msgid "Update your password"
msgstr "Update your password"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Updated"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Updating your password..."
@@ -3276,4 +3244,3 @@ msgstr "Zoom out"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-32
View File
@@ -239,10 +239,6 @@ msgstr "Add Row After"
msgid "Add Row Before"
msgstr "Add Row Before"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Added"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -261,10 +257,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI Chat"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI returned some invalid references"
@@ -409,10 +401,6 @@ msgstr "Area of Study"
msgid "Artificial Intelligence"
msgstr "Artificial Intelligence"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Ask me to update your resume..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Aspect Ratio"
@@ -618,10 +606,6 @@ msgstr "Circle"
msgid "Clear all"
msgstr "Clear all"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Clear chat history"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Click here to select a file to import"
@@ -1081,10 +1065,6 @@ msgstr "e.g. 150000"
msgid "e.g. 50000"
msgstr "e.g. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "e.g. Change my name to..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "e.g. frontend developer jobs in Berlin"
@@ -2200,10 +2180,6 @@ msgstr "Remove"
msgid "Remove Password"
msgstr "Remove Password"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Removed"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Removing password protection..."
@@ -2743,10 +2719,6 @@ msgstr "There was a problem while generating the DOCX, please try again."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "There was a problem while generating the PDF, please try again in some time."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Thinking..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3032,10 +3004,6 @@ msgstr "Update Resume"
msgid "Update your password"
msgstr "Update your password"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Updated"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Updating your password..."
-33
View File
@@ -244,10 +244,6 @@ msgstr "Añadir fila después"
msgid "Add Row Before"
msgstr "Añadir fila antes"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Añadido"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikáans"
msgid "AI"
msgstr "IA"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Chat con IA"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI devolvió algunas referencias no válidas"
@@ -414,10 +406,6 @@ msgstr "Área de estudio"
msgid "Artificial Intelligence"
msgstr "Inteligencia artificial"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Pídame que actualice su currículum..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Relación de aspecto"
@@ -623,10 +611,6 @@ msgstr "Círculo"
msgid "Clear all"
msgstr "Borrar todo"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Limpiar historial del chat"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Haz clic aquí para seleccionar un archivo para importar"
@@ -1086,10 +1070,6 @@ msgstr "por ejemplo, 150000"
msgid "e.g. 50000"
msgstr "por ejemplo, 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "ej. Cambiar mi nombre a..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "p.ej. trabajos de desarrollador frontend en Berlín"
@@ -2205,10 +2185,6 @@ msgstr "Eliminar"
msgid "Remove Password"
msgstr "Quitar contraseña"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Eliminado"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Quitando la protección con contraseña..."
@@ -2748,10 +2724,6 @@ msgstr "Se ha producido un problema al generar el DOCX, inténtelo de nuevo."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Ha habido un problema al generar el PDF, inténtalo de nuevo dentro de un rato."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Pensando..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Actualizar currículum"
msgid "Update your password"
msgstr "Actualiza tu contraseña"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Actualizado"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Actualizando tu contraseña..."
@@ -3276,4 +3244,3 @@ msgstr "Alejar"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulú"
-33
View File
@@ -244,10 +244,6 @@ msgstr "افزودن ردیف بعد از این"
msgid "Add Row Before"
msgstr "افزودن ردیف قبل از این"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "اضافه شد"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "آفریکانس"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "چت هوش مصنوعی"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI چند ارجاع نامعتبر بازگرداند."
@@ -414,10 +406,6 @@ msgstr "حوزهٔ تحصیل"
msgid "Artificial Intelligence"
msgstr "هوش مصنوعی"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "از من بخواهید رزومه‌تان را به‌روز کنم..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "نسبت تصویر"
@@ -623,10 +611,6 @@ msgstr "دایره"
msgid "Clear all"
msgstr "تمیز کردن همه"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "پاک کردن تاریخچه چت"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "برای انتخاب فایل برای وارد کردن، اینجا کلیک کنید"
@@ -1086,10 +1070,6 @@ msgstr "مثلاً ۱۵۰۰۰۰"
msgid "e.g. 50000"
msgstr "مثلاً ۵۰۰۰۰"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "مثال: نام مرا به ... تغییر بده"
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "مثلاً مشاغل توسعه‌دهنده فرانت‌اند در برلین"
@@ -2205,10 +2185,6 @@ msgstr "حذف"
msgid "Remove Password"
msgstr "حذف گذرواژه"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "حذف شد"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "در حال حذف حفاظت با گذرواژه..."
@@ -2748,10 +2724,6 @@ msgstr "هنگام تولید فایل DOCX مشکلی پیش آمد، لطفا
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "هنگام تولید PDF مشکلی پیش آمد، لطفاً بعداً دوباره تلاش کنید."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "در حال فکر کردن..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "به‌روزرسانی رزومه"
msgid "Update your password"
msgstr "گذرواژهٔ خود را به‌روزرسانی کنید"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "به‌روز شد"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "در حال به‌روزرسانی گذرواژه شما..."
@@ -3276,4 +3244,3 @@ msgstr "کوچک‌نمایی"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "زولو"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Lisää rivi jälkeen"
msgid "Add Row Before"
msgstr "Lisää rivi ennen"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Lisätty"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Tekoälychat"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI palautti joitakin virheellisiä viittauksia"
@@ -414,10 +406,6 @@ msgstr "Opintoala"
msgid "Artificial Intelligence"
msgstr "Tekoäly"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Pyydä minua päivittämään ansioluettelosi..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Kuvasuhde"
@@ -623,10 +611,6 @@ msgstr "Ympyrä"
msgid "Clear all"
msgstr "Tyhjennä kaikki"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Tyhjennä chat-historia"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Napsauta tästä valitaksesi tuotavan tiedoston"
@@ -1086,10 +1070,6 @@ msgstr "esim. 150000"
msgid "e.g. 50000"
msgstr "esim. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "esim. Vaihda nimeni..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "esim. frontend developer työpaikat Berliinissä"
@@ -2205,10 +2185,6 @@ msgstr "Poista"
msgid "Remove Password"
msgstr "Poista salasana"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Poistettu"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Poistetaan salasanasuojausta..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX-tiedoston luomisessa ilmeni ongelma, yritä uudelleen."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF:n luonnissa ilmeni ongelma, yritä hetken kuluttua uudelleen."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Mietitään..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Päivitä ansioluettelo"
msgid "Update your password"
msgstr "Päivitä salasanasi"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Päivitetty"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Päivitetään salasanaasi..."
@@ -3276,4 +3244,3 @@ msgstr "Loitonna"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Ajouter une ligne après"
msgid "Add Row Before"
msgstr "Ajouter une ligne avant"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Ajouté"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "IA"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Chat avec l'IA"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "L'IA a renvoyé des références non valides"
@@ -414,10 +406,6 @@ msgstr "Domaine d'étude"
msgid "Artificial Intelligence"
msgstr "Intelligence artificielle"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Demandez-moi de mettre à jour votre CV."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Format d'image"
@@ -623,10 +611,6 @@ msgstr "Cercle"
msgid "Clear all"
msgstr "Tout effacer"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Effacer l'historique de chat"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Cliquez ici pour sélectionner un fichier à importer"
@@ -1086,10 +1070,6 @@ msgstr "par exemple 150000"
msgid "e.g. 50000"
msgstr "par exemple 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "Par ex. : Changer mon nom en"
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "par exemple, les emplois de développeur frontend à Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Supprimer"
msgid "Remove Password"
msgstr "Supprimer le mot de passe"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Supprimé"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Suppression de la protection par mot de passe..."
@@ -2748,10 +2724,6 @@ msgstr "Il y a eu un problème lors de la génération du DOCX, veuillez réessa
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Un problème est survenu lors de la génération du PDF, veuillez réessayer dans quelque temps."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Réflexion..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Modifier le CV"
msgid "Update your password"
msgstr "Modifier votre mot de passe"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Mis à jour"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Mise à jour de votre mot de passe..."
@@ -3276,4 +3244,3 @@ msgstr "Zoom arrière"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zoulou"
-33
View File
@@ -244,10 +244,6 @@ msgstr "הוספת שורה אחרי"
msgid "Add Row Before"
msgstr "הוספת שורה לפני"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "נוסף"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "אפריקאנס"
msgid "AI"
msgstr "בינה מלאכותית"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "צ'אט AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "ה-AI החזיר כמה הפניות לא חוקיות"
@@ -414,10 +406,6 @@ msgstr "תחום לימודים"
msgid "Artificial Intelligence"
msgstr "בינה מלאכותית"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "בקש ממני לעדכן את קורות החיים שלך..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "יחס גובה־רוחב"
@@ -623,10 +611,6 @@ msgstr "עיגול"
msgid "Clear all"
msgstr "נקה הכל"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "נקה היסטוריית צ'אט"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "לחץ כאן כדי לבחור קובץ לייבוא"
@@ -1086,10 +1070,6 @@ msgstr "למשל: 150,000"
msgid "e.g. 50000"
msgstr "למשל 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "לדוגמה: שנה את שמי ל..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "למשל, משרות למפתחי frontend בברלין"
@@ -2205,10 +2185,6 @@ msgstr "הסר"
msgid "Remove Password"
msgstr "הסרת סיסמה"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "הוסר"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "מסיר את ההגנה באמצעות סיסמה..."
@@ -2748,10 +2724,6 @@ msgstr "אירעה תקלה בעת יצירת קובץ ה-DOCX. אנא נסה ש
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "אירעה בעיה בעת יצירת קובץ ה־PDF, נא לנסות שוב מאוחר יותר."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "חושב..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "עדכון קורות חיים"
msgid "Update your password"
msgstr "עדכון הסיסמה שלך"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "עודכן"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "מעדכן את הסיסמה שלך..."
@@ -3276,4 +3244,3 @@ msgstr "התרחקות"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "זולו"
-33
View File
@@ -244,10 +244,6 @@ msgstr "इसके बाद पंक्ति जोड़ें"
msgid "Add Row Before"
msgstr "इसके पहले पंक्ति जोड़ें"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "जोड़ा गया"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "अफ्रीकान्स"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI चैट"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "एआई ने कुछ अमान्य संदर्भ लौटाए।"
@@ -414,10 +406,6 @@ msgstr "अध्ययन का क्षेत्र"
msgid "Artificial Intelligence"
msgstr "कृत्रिम बुद्धिमत्ता"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "मुझसे अपना रिज्यूमे अपडेट करने के लिए कहें..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "आकार अनुपात"
@@ -623,10 +611,6 @@ msgstr "गोला"
msgid "Clear all"
msgstr "सभी साफ़ करें"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "चैट इतिहास साफ़ करें"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "इम्पोर्ट करने के लिए फ़ाइल चुनने हेतु यहाँ क्लिक करें"
@@ -1086,10 +1070,6 @@ msgstr "उदा. 150000"
msgid "e.g. 50000"
msgstr "उदा. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "उदा. मेरा नाम बदलकर..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "उदाहरण के लिए बर्लिन में फ्रंटएंड डेवलपर की नौकरियाँ"
@@ -2205,10 +2185,6 @@ msgstr "हटाएं"
msgid "Remove Password"
msgstr "पासवर्ड हटाएँ"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "हटाया गया"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "पासवर्ड सुरक्षा हटाई जा रही है..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX उत्पन्न करते समय एक समस्य
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF जेनरेट करते समय कोई समस्या आई, कृपया कुछ समय बाद फिर से प्रयास करें।"
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "सोच रहा हूं..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "रेज़्यूमे अपडेट करें"
msgid "Update your password"
msgstr "अपना पासवर्ड अपडेट करें"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "अपडेट किया गया"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "आपका पासवर्ड अपडेट किया जा रहा है..."
@@ -3276,4 +3244,3 @@ msgstr "ज़ूम आउट"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "ज़ुलु"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Sor hozzáadása alá"
msgid "Add Row Before"
msgstr "Sor hozzáadása fölé"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Hozzáadva"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI-csevegés"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "Az AI néhány érvénytelen hivatkozást adott vissza"
@@ -414,10 +406,6 @@ msgstr "Tanulmányok területe"
msgid "Artificial Intelligence"
msgstr "Mesterséges intelligencia"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Kérjen meg az önéletrajz frissítésére..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Méretarány"
@@ -623,10 +611,6 @@ msgstr "Kör"
msgid "Clear all"
msgstr "Mindent törölni"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Csevegési előzmények törlése"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Kattints ide az importálandó fájl kiválasztásához"
@@ -1086,10 +1070,6 @@ msgstr "pl. 150000"
msgid "e.g. 50000"
msgstr "pl. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "pl. Változtasd a nevem erre:..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "pl. frontend developer állások ebben Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Eltávolítás"
msgid "Remove Password"
msgstr "Jelszó eltávolítása"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Eltávolítva"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Jelszóvédelem eltávolítása..."
@@ -2748,10 +2724,6 @@ msgstr "A DOCX generálása során probléma merült fel, kérjük, próbálja m
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Hiba történt a PDF generálása közben, kérjük, próbáld meg később újra."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Gondolkodom..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Önéletrajz frissítése"
msgid "Update your password"
msgstr "Jelszó frissítése"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Frissítve"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Jelszó frissítése..."
@@ -3276,4 +3244,3 @@ msgstr "Kicsinyítés"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Tambah Baris Setelah"
msgid "Add Row Before"
msgstr "Tambah Baris Sebelum"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Ditambahkan"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "Kecerdasan Buatan"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Chat AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI mengembalikan beberapa referensi yang tidak valid"
@@ -414,10 +406,6 @@ msgstr "Bidang Studi"
msgid "Artificial Intelligence"
msgstr "Kecerdasan Buatan"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Minta saya memperbarui resume Anda..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Rasio Aspek"
@@ -623,10 +611,6 @@ msgstr "Lingkaran"
msgid "Clear all"
msgstr "Hapus semua"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Hapus riwayat obrolan"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Klik di sini untuk memilih file yang akan diimpor"
@@ -1086,10 +1070,6 @@ msgstr "misalnya 150000"
msgid "e.g. 50000"
msgstr "misalnya 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "mis. Ubah nama saya menjadi..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "mis. pekerjaan pengembang frontend di Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Hapus"
msgid "Remove Password"
msgstr "Hapus Kata Sandi"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Dihapus"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Menghapus perlindungan kata sandi..."
@@ -2748,10 +2724,6 @@ msgstr "Ada masalah saat membuat DOCX, silakan coba lagi."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Terjadi masalah saat membuat PDF, silakan coba lagi nanti."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Berpikir..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Perbarui Resume"
msgid "Update your password"
msgstr "Perbarui kata sandi Anda"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Diperbarui"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Memperbarui kata sandi Anda..."
@@ -3276,4 +3244,3 @@ msgstr "Perkecil"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Aggiungi riga dopo"
msgid "Add Row Before"
msgstr "Aggiungi riga prima"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Aggiunto"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "IA"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Chat IA"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI ha restituito alcuni riferimenti non validi"
@@ -414,10 +406,6 @@ msgstr "Area di studio"
msgid "Artificial Intelligence"
msgstr "Intelligenza artificiale"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Chiedimi di aggiornare il tuo curriculum..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Proporzioni"
@@ -623,10 +611,6 @@ msgstr "Cerchio"
msgid "Clear all"
msgstr "Cancella tutto"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Cancella la cronologia della chat"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Fai clic qui per selezionare un file da importare"
@@ -1086,10 +1070,6 @@ msgstr "Ad esempio, 150000"
msgid "e.g. 50000"
msgstr "ad esempio 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "es. Cambia il mio nome in..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "Ad esempio, lavori come sviluppatore frontend a Berlino"
@@ -2205,10 +2185,6 @@ msgstr "Rimuovi"
msgid "Remove Password"
msgstr "Rimuovi password"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Rimosso"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Rimozione della protezione tramite password..."
@@ -2748,10 +2724,6 @@ msgstr "Si è verificato un problema durante la generazione del DOCX, la preghia
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Si è verificato un problema durante la generazione del PDF, riprova tra qualche istante."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Sto pensando..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Aggiorna curriculum"
msgid "Update your password"
msgstr "Aggiorna la tua password"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Aggiornato"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Aggiornamento della tua password in corso..."
@@ -3276,4 +3244,3 @@ msgstr "Rimpicciolisci"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "後に行を追加"
msgid "Add Row Before"
msgstr "前に行を追加"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "追加済み"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "アフリカーンス語"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AIチャット"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AIはいくつかの無効な参照を返した"
@@ -414,10 +406,6 @@ msgstr "研究分野"
msgid "Artificial Intelligence"
msgstr "人工知能"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "履歴書の更新をお願いしてください..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "アスペクト比"
@@ -623,10 +611,6 @@ msgstr "円"
msgid "Clear all"
msgstr "すべてクリア"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "チャット履歴を消去"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "ここをクリックしてインポートするファイルを選択"
@@ -1086,10 +1070,6 @@ msgstr "例:150000"
msgid "e.g. 50000"
msgstr "例:50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "例:名前を〇〇に変更する..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "例)フロントエンド開発者の求人(ベルリン"
@@ -2205,10 +2185,6 @@ msgstr "削除"
msgid "Remove Password"
msgstr "パスワードを削除"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "削除済み"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "パスワード保護を解除しています..."
@@ -2748,10 +2724,6 @@ msgstr "DOCXの生成中に問題が発生しました。"
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF の生成中に問題が発生しました。しばらくしてからもう一度お試しください。"
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "考え中..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "履歴書を更新"
msgid "Update your password"
msgstr "パスワードを更新してください。"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "更新済み"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "パスワードを更新しています..."
@@ -3276,4 +3244,3 @@ msgstr "ズームアウト"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "ズールー語"
-33
View File
@@ -244,10 +244,6 @@ msgstr "បន្ថែម​ជួរដេក​នៅ​ក្រោយ"
msgid "Add Row Before"
msgstr "បន្ថែម​ជួរដេក​នៅ​មុខ"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "បានបន្ថែម"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI ជជែក"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr ""
@@ -414,10 +406,6 @@ msgstr "ជំនាញ​រៀន"
msgid "Artificial Intelligence"
msgstr "បញ្ញាសិប្បនិម្មិត"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "សុំឱ្យខ្ញុំធ្វើបច្ចុប្បន្នភាពប្រវត្តិរូបរបស់អ្នក..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "សមាមាត្រទ្រង់ទ្រាយ"
@@ -623,10 +611,6 @@ msgstr "រង្វង់"
msgid "Clear all"
msgstr ""
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "សម្អាតប្រវត្តិជជែក"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "ចុច​ទីនេះ​ដើម្បី​ជ្រើស​ឯកសារ​មួយ​ដើម្បី​នាំចូល"
@@ -1086,10 +1070,6 @@ msgstr ""
msgid "e.g. 50000"
msgstr ""
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "ឧ. ប្តូរឈ្មោះខ្ញុំទៅ..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr ""
@@ -2205,10 +2185,6 @@ msgstr "លុបចេញ"
msgid "Remove Password"
msgstr "ដក​ពាក្យសម្ងាត់"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "បានលុបចេញ"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "កំពុង​ដក​ការ​ការពារ​ដោយ​ពាក្យសម្ងាត់..."
@@ -2748,10 +2724,6 @@ msgstr ""
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "មាន​បញ្ហា​មួយ​កើតឡើង ខណៈពេល​កំពុង​បង្កើត PDF សូម​ព្យាយាម​ម្ដង​ទៀត​ក្រោយ​មក។"
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "កំពុងគិត..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "បច្ចុប្បន្នភាព​ប្រវត្តិរ
msgid "Update your password"
msgstr "បច្ចុប្បន្នភាព​ពាក្យសម្ងាត់​របស់​អ្នក"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "បានធ្វើបច្ចុប្បន្នភាព"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "កំពុង​បច្ចុប្បន្នភាព​ពាក្យសម្ងាត់​របស់​អ្នក..."
@@ -3276,4 +3244,3 @@ msgstr "បង្រួម"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "ಸಾಲನ್ನು ನಂತರ ಸೇರಿಸಿ"
msgid "Add Row Before"
msgstr "ಸಾಲನ್ನು ಮೊದಲು ಸೇರಿಸಿ"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "ಸೇರಿಸಲಾಗಿದೆ"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "ಆಫ್ರಿಕಾನ್ಸ್"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI ಚಾಟ್"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr ""
@@ -414,10 +406,6 @@ msgstr "ಅಧ್ಯಯನದ ಕ್ಷೇತ್ರ"
msgid "Artificial Intelligence"
msgstr "ಕೃತಕ ಬುದ್ಧಿವಂತಿಕೆ"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "ನಿಮ್ಮ ರೆಸ್ಯೂಮೆ ನವೀಕರಿಸಲು ನನ್ನನ್ನು ಕೇಳಿ..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "ಆಕಾರ ಅನುಪಾತ"
@@ -623,10 +611,6 @@ msgstr "ವೃತ್ತ"
msgid "Clear all"
msgstr ""
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "ಚಾಟ್ ಇತಿಹಾಸ ತೆರವುಗೊಳಿಸಿ"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "ಆಮದು ಮಾಡಲು ಕಡತವನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಇಲ್ಲಿ ಕ್ಲಿಕ್ ಮಾಡಿ"
@@ -1086,10 +1070,6 @@ msgstr ""
msgid "e.g. 50000"
msgstr ""
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "ಉದಾ. ನನ್ನ ಹೆಸರನ್ನು ಬದಲಿಸಿ..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr ""
@@ -2205,10 +2185,6 @@ msgstr "ತೆಗೆದುಹಾಕಿ"
msgid "Remove Password"
msgstr "ಪಾಸ್‌ವರ್ಡ್ ತೆಗೆದುಹಾಕಿ"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "ತೆಗೆದುಹಾಕಲಾಗಿದೆ"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "ಪಾಸ್‌ವರ್ಡ್ ರಕ್ಷಣೆಯನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತಿದೆ..."
@@ -2748,10 +2724,6 @@ msgstr ""
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF ರಚಿಸುವಾಗ ಒಂದು ಸಮಸ್ಯೆ ಉಂಟಾಯಿತು, ದಯವಿಟ್ಟು ಸ್ವಲ್ಪ ಸಮಯದ ಬಳಿಕ ಮರುಪ್ರಯತ್ನಿಸಿ."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "ಯೋಚಿಸುತ್ತಿದ್ದೇನೆ..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "ರೆಸ್ಯೂಮ್ ನವೀಕರಿಸಿ"
msgid "Update your password"
msgstr "ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ನವೀಕರಿಸಿ"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "ನವೀಕರಿಸಲಾಗಿದೆ"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್ ಅನ್ನು ನವೀಕರಿಸಲಾಗುತ್ತಿದೆ..."
@@ -3276,4 +3244,3 @@ msgstr "ಗಾತ್ರ ಕುಗ್ಗಿಸಿ"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "ಜೂಲೂ"
-33
View File
@@ -244,10 +244,6 @@ msgstr "뒤에 행 추가"
msgid "Add Row Before"
msgstr "앞에 행 추가"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "추가됨"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "아프리칸스어"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI 채팅"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI가 일부 잘못된 참조를 반환했습니다."
@@ -414,10 +406,6 @@ msgstr "연구 분야"
msgid "Artificial Intelligence"
msgstr "인공지능"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "이력서 업데이트를 요청하세요..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "가로세로 비율"
@@ -623,10 +611,6 @@ msgstr "원"
msgid "Clear all"
msgstr "모두 지우기"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "채팅 기록 지우기"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "가져올 파일을 선택하려면 여기를 클릭하세요"
@@ -1086,10 +1070,6 @@ msgstr "예: 150000"
msgid "e.g. 50000"
msgstr "예: 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "예: 내 이름을 ...으로 바꿔줘"
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "예: 베를린의 프론트엔드 개발자 채용 정보"
@@ -2205,10 +2185,6 @@ msgstr "제거"
msgid "Remove Password"
msgstr "비밀번호 제거"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "제거됨"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "비밀번호 보호를 제거하는 중입니다..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX를 생성하는 동안 문제가 발생했습니다. 다시 시도
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF를 생성하는 동안 문제가 발생했습니다. 잠시 후 다시 시도해 주세요."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "생각 중..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "이력서 업데이트"
msgid "Update your password"
msgstr "비밀번호 업데이트"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "업데이트됨"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "비밀번호를 업데이트하는 중입니다..."
@@ -3276,4 +3244,3 @@ msgstr "축소"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "줄루어"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Pridėti eilutę po"
msgid "Add Row Before"
msgstr "Pridėti eilutę prieš"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Pridėta"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikanso"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "DI pokalbiai"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI grąžino keletą negaliojančių nuorodų"
@@ -414,10 +406,6 @@ msgstr "Studijų sritis"
msgid "Artificial Intelligence"
msgstr "Dirbtinis intelektas"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Paprašykite manęs atnaujinti jūsų gyvenimo aprašymą..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Vaizdo santykis"
@@ -623,10 +611,6 @@ msgstr "Apskritimas"
msgid "Clear all"
msgstr "Išvalyti viską"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Išvalyti pokalbių istoriją"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Spustelėkite čia, kad pasirinktumėte importuojamą failą"
@@ -1086,10 +1070,6 @@ msgstr "pvz., 150000"
msgid "e.g. 50000"
msgstr "pvz., 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "pvz. Pakeiskite mano vardą į..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "pvz., frontend kūrėjo darbo vietos Berlyne"
@@ -2205,10 +2185,6 @@ msgstr "Pašalinti"
msgid "Remove Password"
msgstr "Pašalinti slaptažodį"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Pašalinta"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Šalinama apsauga slaptažodžiu..."
@@ -2748,10 +2724,6 @@ msgstr "Generuojant DOCX iškilo problema, pabandykite dar kartą."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Kilo problema generuojant PDF. Bandykite dar kartą po kurio laiko."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Galvoju..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Atnaujinti gyvenimo aprašymą"
msgid "Update your password"
msgstr "Atnaujinkite savo slaptažodį"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Atnaujinta"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Atnaujinamas jūsų slaptažodis..."
@@ -3276,4 +3244,3 @@ msgstr "Tolinti"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulų"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Pievienot rindu pēc"
msgid "Add Row Before"
msgstr "Pievienot rindu pirms"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Pievienots"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikandu"
msgid "AI"
msgstr "MI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI tērzēšana"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI atgrieza dažas nederīgas atsauces"
@@ -414,10 +406,6 @@ msgstr "Studiju joma"
msgid "Artificial Intelligence"
msgstr "Mākslīgais intelekts"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Lūdziet mani atjaunināt jūsu CV..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Proporcijas"
@@ -623,10 +611,6 @@ msgstr "Aplis"
msgid "Clear all"
msgstr "Notīrīt visus"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Notīrīt tērzēšanas vēsturi"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Noklikšķiniet šeit, lai izvēlētos importējamo failu"
@@ -1086,10 +1070,6 @@ msgstr "piem., 150000"
msgid "e.g. 50000"
msgstr "piemēram, 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "piemēram: Nomainiet manu vārdu uz..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "piem., frontend izstrādātāja darbavietas Berlīnē"
@@ -2205,10 +2185,6 @@ msgstr "Noņemt"
msgid "Remove Password"
msgstr "Noņemt paroli"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Noņemts"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Tiek noņemta paroles aizsardzība..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX ģenerēšanas laikā radās problēma, lūdzu, mēģiniet vēlreiz
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Radās problēma, ģenerējot PDF, lūdzu, mēģiniet vēlreiz pēc kāda laika."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Domāju..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Atjaunināt CV"
msgid "Update your password"
msgstr "Atjauniniet savu paroli"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Atjaunināts"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Tiek atjaunināta jūsu parole..."
@@ -3276,4 +3244,3 @@ msgstr "Tālināt"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "വരി പിന്നീട് ചേർക്കുക"
msgid "Add Row Before"
msgstr "വരി മുമ്പ് ചേർക്കുക"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "ചേർത്തു"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "ആഫ്രിക്കാൻസ്"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI ചാറ്റ്"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "എഐ ചില അസാധുവായ റെഫറൻസുകൾ നൽകി"
@@ -414,10 +406,6 @@ msgstr "പഠന മേഖല"
msgid "Artificial Intelligence"
msgstr "ആർട്ടിഫിഷ്യൽ ഇന്റലിജൻസ്"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "നിങ്ങളുടെ റെസ്യൂമെ അപ്ഡേറ്റ് ചെയ്യാൻ എന്നോട് ആവശ്യപ്പെടുക..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "ആസ്പെക്ട് റേഷ്യോ"
@@ -623,10 +611,6 @@ msgstr "വൃത്തം"
msgid "Clear all"
msgstr "എല്ലാം മായ്ക്കുക"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "ചാറ്റ് ചരിത്രം മായ്ക്കുക"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "ഇംപോർട്ട് ചെയ്യാൻ ഒരു ഫയൽ തിരഞ്ഞെടുക്കാൻ ഇവിടെ ക്ലിക്ക് ചെയ്യുക"
@@ -1086,10 +1070,6 @@ msgstr "ഉദാ. 150000"
msgid "e.g. 50000"
msgstr "ഉദാ. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "ഉദാ. എന്റെ പേര് മാറ്റുക..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "ഉദാ. ബെർലിനിലെ ഫ്രണ്ടെൻഡ് ഡെവലപ്പർ ജോലികൾ"
@@ -2205,10 +2185,6 @@ msgstr "നീക്കം ചെയ്യുക"
msgid "Remove Password"
msgstr "പാസ്‌വേഡ് നീക്കുക"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "നീക്കം ചെയ്തു"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "പാസ്‌വേഡ് സംരക്ഷണം നീക്കം ചെയ്യുന്നു..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX ഉണ്ടാക്കുന്നതിനിടയിൽ ഒര
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF നിർമ്മിക്കുന്നതിനിടെ ഒരു പ്രശ്നം ഉണ്ടായി, ദയവായി കുറച്ചുസമയം കഴിഞ്ഞ് വീണ്ടും ശ്രമിക്കുക."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "ചിന്തിക്കുന്നു..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "റിസ്യൂം അപ്‌ഡേറ്റ് ചെയ്യു
msgid "Update your password"
msgstr "നിങ്ങളുടെ പാസ്‌വേഡ് അപ്‌ഡേറ്റ് ചെയ്യുക"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "അപ്ഡേറ്റ് ചെയ്തു"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "നിങ്ങളുടെ പാസ്‌വേഡ് അപ്‌ഡേറ്റ് ചെയ്യുന്നു..."
@@ -3276,4 +3244,3 @@ msgstr "സൂം ഔട്ട് ചെയ്യുക"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "സൂളു"
-33
View File
@@ -244,10 +244,6 @@ msgstr "नंतर ओळ जोडा"
msgid "Add Row Before"
msgstr "आधी ओळ जोडा"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "जोडले"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "आफ्रिकान्स"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI चॅट"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "एआयने काही अमान्य संदर्भ परत केले"
@@ -414,10 +406,6 @@ msgstr "अभ्यासाचे क्षेत्र"
msgid "Artificial Intelligence"
msgstr "कृत्रिम बुद्धिमत्ता"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "तुमचा बायोडेटा अपडेट करण्यासाठी मला सांगा..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "प्रसर गुणोत्तर"
@@ -623,10 +611,6 @@ msgstr "गोलाकार"
msgid "Clear all"
msgstr "सर्व मिटवा"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "चॅट इतिहास साफ करा"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "इम्पोर्ट करण्यासाठी फाईल निवडण्यासाठी येथे क्लिक करा"
@@ -1086,10 +1070,6 @@ msgstr "उदा. १५००००"
msgid "e.g. 50000"
msgstr "उदा. ५००००"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "उदा. माझे नाव बदला..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "उदा. बर्लिनमधील फ्रंटएंड डेव्हलपर नोकऱ्या"
@@ -2205,10 +2185,6 @@ msgstr "काढा"
msgid "Remove Password"
msgstr "पासवर्ड काढा"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "काढले"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "पासवर्ड संरक्षण काढून टाकले जात आहे..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX तयार करताना अडचण आली, कृप
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF तयार करताना समस्या आली, कृपया थोड्या वेळाने पुन्हा प्रयत्न करा."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "विचार करत आहे..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "रेझ्युमे अपडेट करा"
msgid "Update your password"
msgstr "तुमचा पासवर्ड अपडेट करा"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "अपडेट केले"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "तुमचा पासवर्ड अपडेट केला जात आहे..."
@@ -3276,4 +3244,3 @@ msgstr "बाहेर झूम करा"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "झुलू"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Tambah Baris Selepas"
msgid "Add Row Before"
msgstr "Tambah Baris Sebelum"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Ditambah"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Sembang AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI mengembalikan beberapa rujukan yang tidak sah"
@@ -414,10 +406,6 @@ msgstr "Bidang Pengajian"
msgid "Artificial Intelligence"
msgstr "Kecerdasan Buatan"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Minta saya mengemaskini resume anda..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Nisbah Aspek"
@@ -623,10 +611,6 @@ msgstr "Bulatan"
msgid "Clear all"
msgstr "Bersihkan semuanya"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Kosongkan sejarah sembang"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Klik di sini untuk memilih fail untuk diimport"
@@ -1086,10 +1070,6 @@ msgstr "contohnya 150000"
msgid "e.g. 50000"
msgstr "contohnya 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "cth. Tukar nama saya kepada..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "contohnya pekerjaan pembangun frontend di Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Alih keluar"
msgid "Remove Password"
msgstr "Buang Kata Laluan"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Dialih keluar"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Membuang perlindungan kata laluan..."
@@ -2748,10 +2724,6 @@ msgstr "Terdapat masalah semasa menjana DOCX, sila cuba lagi."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Terdapat masalah semasa menjana PDF, sila cuba lagi selepas beberapa ketika."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Berfikir..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Kemas Kini Resume"
msgid "Update your password"
msgstr "Kemas kini kata laluan anda"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Dikemaskini"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Mengemas kini kata laluan anda..."
@@ -3276,4 +3244,3 @@ msgstr "Zum keluar"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "पछि पङ्क्ति थप्नुहोस्"
msgid "Add Row Before"
msgstr "अघिल्लो पङ्क्ति थप्नुहोस्"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "थपियो"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "अफ्रिकान्स"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI च्याट"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "एआईले केही अमान्य सन्दर्भहरू फर्कायो।"
@@ -414,10 +406,6 @@ msgstr "अध्ययन क्षेत्र"
msgid "Artificial Intelligence"
msgstr "कृत्रिम बौद्धिकता"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "मलाई तपाईंको रिज्युमे अपडेट गर्न भन्नुहोस्..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "आकार अनुपात (Aspect Ratio)"
@@ -623,10 +611,6 @@ msgstr "वृत्त"
msgid "Clear all"
msgstr "सबै सफा गर्नुहोस्"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "च्याट इतिहास हटाउनुहोस्"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "आयात गर्न फाइल छान्न यहाँ क्लिक गर्नुहोस्"
@@ -1086,10 +1070,6 @@ msgstr "जस्तै १५००००"
msgid "e.g. 50000"
msgstr "जस्तै ५००००"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "उदा. मेरो नाम बदल्नुहोस्..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "जस्तै बर्लिनमा फ्रन्टएन्ड डेभलपरका जागिरहरू"
@@ -2205,10 +2185,6 @@ msgstr "हटाउनुहोस्"
msgid "Remove Password"
msgstr "पासवर्ड हटाउनुहोस्"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "हटाइयो"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "पासवर्ड सुरक्षा हटाइँदैछ..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX उत्पन्न गर्दा समस्या भयो,
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF बनाउने क्रममा समस्या आयो, कृपया केही समयपछि पुनः प्रयास गर्नुहोस्।"
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "सोच्दैछ..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "बायोडाटा अद्यावधिक गर्नुह
msgid "Update your password"
msgstr "तपाईंको पासवर्ड अद्यावधिक गर्नुहोस्"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "अपडेट गरियो"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "तपाईंको पासवर्ड अद्यावधिक हुँदैछ..."
@@ -3276,4 +3244,3 @@ msgstr "जूम आउट"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "जुलु"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Rij erna toevoegen"
msgid "Add Row Before"
msgstr "Rij ervoor toevoegen"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Toegevoegd"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI Chatten"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI retourneerde enkele ongeldige referenties"
@@ -414,10 +406,6 @@ msgstr "Studierichting"
msgid "Artificial Intelligence"
msgstr "Kunstmatige intelligentie"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Vraag me om uw cv bij te werken..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Beeldverhouding"
@@ -623,10 +611,6 @@ msgstr "Cirkel"
msgid "Clear all"
msgstr "Alles wissen"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Chatgeschiedenis verwijderen"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Klik hier om een bestand te selecteren om te importeren"
@@ -1086,10 +1070,6 @@ msgstr "bijv. 150000"
msgid "e.g. 50000"
msgstr "bijv. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "bijv. Wijzig mijn naam naar..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "Banen als frontend ontwikkelaar in Berlijn"
@@ -2205,10 +2185,6 @@ msgstr "Verwijderen"
msgid "Remove Password"
msgstr "Wachtwoord verwijderen"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Verwijderd"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Wachtwoordbeveiliging wordt verwijderd..."
@@ -2748,10 +2724,6 @@ msgstr "Er is een probleem opgetreden tijdens het genereren van de DOCX, probeer
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Er is een probleem opgetreden bij het genereren van de PDF, probeer het over enige tijd opnieuw."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Even nadenken..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Cv bijwerken"
msgid "Update your password"
msgstr "Werk uw wachtwoord bij"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Bijgewerkt"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Uw wachtwoord wordt bijgewerkt..."
@@ -3276,4 +3244,3 @@ msgstr "Uitzoomen"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Legg til rad etter"
msgid "Add Row Before"
msgstr "Legg til rad før"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Lagt til"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "KI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI-chat"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr ""
@@ -414,10 +406,6 @@ msgstr "Studiefelt"
msgid "Artificial Intelligence"
msgstr "Kunstig intelligens"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Be meg om å oppdatere CV-en din..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Størrelsesforhold"
@@ -623,10 +611,6 @@ msgstr "Sirkel"
msgid "Clear all"
msgstr ""
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Tøm chatlogg"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Klikk her for å velge en fil å importere"
@@ -1086,10 +1070,6 @@ msgstr ""
msgid "e.g. 50000"
msgstr ""
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "f.eks. Endre navnet mitt til..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr ""
@@ -2205,10 +2185,6 @@ msgstr "Fjern"
msgid "Remove Password"
msgstr "Fjern passord"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Fjernet"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Fjerner passordbeskyttelse..."
@@ -2748,10 +2724,6 @@ msgstr ""
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Det oppstod et problem under generering av PDF-en, prøv igjen om en stund."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Tenker..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Oppdater CV"
msgid "Update your password"
msgstr "Oppdater passordet ditt"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Oppdatert"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Oppdaterer passordet ditt..."
@@ -3276,4 +3244,3 @@ msgstr "Zoom ut"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "ପରେ ପଙ୍କ୍ତି ଯୋଡନ୍ତୁ"
msgid "Add Row Before"
msgstr "ପୂର୍ବେ ପଙ୍କ୍ତି ଯୋଡନ୍ତୁ"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "ଯୋଡ଼ାଗଲା"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "ଆଫ୍ରିକାନ୍ସ"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI ଚାଟ୍"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr ""
@@ -414,10 +406,6 @@ msgstr "ଅଧ୍ୟୟନ କ୍ଷେତ୍ର"
msgid "Artificial Intelligence"
msgstr "କୃତ୍ରିମ ବୁଦ୍ଧିମତ୍ତା"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "ମୋତେ ଆପଣଙ୍କ ରିଜ୍ୟୁମ ଅପଡେଟ୍ କରିବାକୁ କୁହନ୍ତୁ..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "ଆସ୍ପେକ୍ଟ ଅନୁପାତ"
@@ -623,10 +611,6 @@ msgstr "ବୃତ୍ତ"
msgid "Clear all"
msgstr ""
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "ଚାଟ୍ ଇତିହାସ ସଫା କରନ୍ତୁ"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "ଆୟାତ କରିବା ପାଇଁ ଫାଇଲ୍ ଚୟନ କରିବାକୁ ଏଠାରେ କ୍ଲିକ୍ କରନ୍ତୁ"
@@ -1086,10 +1070,6 @@ msgstr ""
msgid "e.g. 50000"
msgstr ""
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "ଯଥା ମୋ ନାମ ବଦଳାନ୍ତୁ..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr ""
@@ -2205,10 +2185,6 @@ msgstr "ବାହାର କରନ୍ତୁ"
msgid "Remove Password"
msgstr "ପାସୱାର୍ଡ ଅପସାରଣ କରନ୍ତୁ"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "ବାହାର କରାଗଲା"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "ପାସୱାର୍ଡ ସୁରକ୍ଷା ଅପସାରଣ ହେଉଛି..."
@@ -2748,10 +2724,6 @@ msgstr ""
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF ସୃଷ୍ଟି କରୁଥିବା ସମୟରେ ସମସ୍ୟା ହୋଇଛି, ଦୟାକରି କିଛି ସମୟ ପରେ ପୁନଃ ଚେଷ୍ଟା କରନ୍ତୁ।"
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "ଚିନ୍ତା କରୁଛି..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "ରେଜ୍ୟୁମେ ଅଦ୍ୟତନ କରନ୍ତୁ"
msgid "Update your password"
msgstr "ଆପଣଙ୍କ ପାସୱାର୍ଡ ଅଦ୍ୟତନ କରନ୍ତୁ"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "ଅପଡେଟ୍ ହେଲା"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "ଆପଣଙ୍କ ପାସୱାର୍ଡ ଅଦ୍ୟତନ ହେଉଛି..."
@@ -3276,4 +3244,3 @@ msgstr "ଜୁମ୍ ଆଉଟ୍ କରନ୍ତୁ"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "ଜୁଲୁ"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Dodaj wiersz po"
msgid "Add Row Before"
msgstr "Dodaj wiersz przed"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Dodano"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Czat AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "Sztuczna inteligencja zwróciła nieprawidłowe referencje"
@@ -414,10 +406,6 @@ msgstr "Kierunek studiów"
msgid "Artificial Intelligence"
msgstr "Sztuczna inteligencja"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Poproś mnie o aktualizację Twojego CV..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Proporcje obrazu"
@@ -623,10 +611,6 @@ msgstr "Koło"
msgid "Clear all"
msgstr "Wyczyść wszystko"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Wyczyść historię czatu"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Kliknij tutaj, aby wybrać plik do importu"
@@ -1086,10 +1070,6 @@ msgstr "np. 150000"
msgid "e.g. 50000"
msgstr "np. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "np. Zmień moje imię na..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "np. oferty pracy dla programistów frontend w Berlinie"
@@ -2205,10 +2185,6 @@ msgstr "Usuń"
msgid "Remove Password"
msgstr "Usuń hasło"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Usunięto"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Wyłączanie ochrony hasłem..."
@@ -2748,10 +2724,6 @@ msgstr "Wystąpił problem podczas generowania DOCX, proszę spróbować ponowni
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Wystąpił problem podczas generowania pliku PDF, spróbuj ponownie za chwilę."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Myślę..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Zaktualizuj CV"
msgid "Update your password"
msgstr "Zaktualizuj swoje hasło"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Zaktualizowano"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Aktualizowanie hasła..."
@@ -3276,4 +3244,3 @@ msgstr "Pomniejsz"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Adicionar linha depois"
msgid "Add Row Before"
msgstr "Adicionar linha antes"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Adicionado"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Africâner"
msgid "AI"
msgstr "IA"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Chat com IA"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "A IA retornou algumas referências inválidas"
@@ -414,10 +406,6 @@ msgstr "Área de estudo"
msgid "Artificial Intelligence"
msgstr "Inteligência Artificial"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Me peça para atualizar seu currículo..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Proporção da imagem"
@@ -623,10 +611,6 @@ msgstr "Círculo"
msgid "Clear all"
msgstr "Limpar tudo"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Limpar histórico do chat"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Clique aqui para selecionar um arquivo para importar"
@@ -1086,10 +1070,6 @@ msgstr "Por exemplo, 150000"
msgid "e.g. 50000"
msgstr "Por exemplo, 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "ex.: Mude meu nome para..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "por exemplo, empregos de desenvolvedor front-end em Berlim"
@@ -2205,10 +2185,6 @@ msgstr "Remover"
msgid "Remove Password"
msgstr "Remover senha"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Removido"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Removendo proteção por senha..."
@@ -2748,10 +2724,6 @@ msgstr "Houve um problema ao gerar o DOCX, tente novamente."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Houve um problema ao gerar o PDF, tente novamente em alguns instantes."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Pensando..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Atualizar currículo"
msgid "Update your password"
msgstr "Atualize sua senha"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Atualizado"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Atualizando sua senha..."
@@ -3276,4 +3244,3 @@ msgstr "Diminuir zoom"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Adicionar linha após"
msgid "Add Row Before"
msgstr "Adicionar linha antes"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Adicionado"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Africâner"
msgid "AI"
msgstr "IA"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Chat com IA"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "A IA devolveu algumas referências inválidas"
@@ -414,10 +406,6 @@ msgstr "Área de estudo"
msgid "Artificial Intelligence"
msgstr "Inteligência Artificial"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Peça-me para atualizar o seu currículo..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Proporção"
@@ -623,10 +611,6 @@ msgstr "Círculo"
msgid "Clear all"
msgstr "Limpar tudo"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Limpar histórico do chat"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Clique aqui para selecionar um ficheiro para importar"
@@ -1086,10 +1070,6 @@ msgstr "por exemplo, 150000"
msgid "e.g. 50000"
msgstr "por exemplo, 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "ex.: Mude o meu nome para..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "por exemplo, empregos de programador front-end em Berlim"
@@ -2205,10 +2185,6 @@ msgstr "Remover"
msgid "Remove Password"
msgstr "Remover senha"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Removido"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "A remover a proteção por senha..."
@@ -2748,10 +2724,6 @@ msgstr "Ocorreu um problema ao gerar o DOCX, tente novamente."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Houve um problema ao gerar o PDF, tente novamente dentro de algum tempo."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "A pensar..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Atualizar currículo"
msgid "Update your password"
msgstr "Atualize a sua senha"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Atualizado"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "A atualizar a sua senha..."
@@ -3276,4 +3244,3 @@ msgstr "Afastar"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Adăugați rând după"
msgid "Add Row Before"
msgstr "Adăugați rând înainte"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Adăugat"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Chat AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI a returnat unele referințe invalide"
@@ -414,10 +406,6 @@ msgstr "Domeniu de studiu"
msgid "Artificial Intelligence"
msgstr "Inteligență artificială"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Cere-mi să îți actualizez CV-ul..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Raport de aspect"
@@ -623,10 +611,6 @@ msgstr "Cerc"
msgid "Clear all"
msgstr "Ștergeți toate"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Șterge istoricul conversației"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Faceți clic aici pentru a selecta un fișier de importat"
@@ -1086,10 +1070,6 @@ msgstr "de ex. 150000"
msgid "e.g. 50000"
msgstr "de ex. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "ex.: Schimbă-mi numele în..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "de exemplu, frontend developer locuri de muncă în Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Elimină"
msgid "Remove Password"
msgstr "Elimină parola"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Eliminat"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Se elimină protecția prin parolă..."
@@ -2748,10 +2724,6 @@ msgstr "A apărut o problemă în timpul generării DOCX, vă rugăm să încerc
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "A apărut o problemă la generarea PDF-ului, vă rugăm să încercați din nou peste câteva momente."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Mă gândesc..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Actualizați CV-ul"
msgid "Update your password"
msgstr "Actualizați-vă parola"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Actualizat"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Se actualizează parola..."
@@ -3276,4 +3244,3 @@ msgstr "Micșorează"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Добавить строку после"
msgid "Add Row Before"
msgstr "Добавить строку до"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Добавлено"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Африкаанс"
msgid "AI"
msgstr "ИИ"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Чат с ИИ"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI вернул несколько недопустимых ссылок"
@@ -414,10 +406,6 @@ msgstr "Область обучения"
msgid "Artificial Intelligence"
msgstr "Искусственный интеллект"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Попросите меня обновить ваше резюме..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Соотношение сторон"
@@ -623,10 +611,6 @@ msgstr "Круг"
msgid "Clear all"
msgstr "Очистить все"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Очистить историю чата"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Нажмите здесь, чтобы выбрать файл для импорта"
@@ -1086,10 +1070,6 @@ msgstr "Например, 150000"
msgid "e.g. 50000"
msgstr "Например, 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "напр.: Измените моё имя на..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "Например, вакансии фронтенд-разработчика в Берлине"
@@ -2205,10 +2185,6 @@ msgstr "Удалить"
msgid "Remove Password"
msgstr "Удалить пароль"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Удалено"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Отключение защиты паролем..."
@@ -2748,10 +2724,6 @@ msgstr "При создании DOCX возникла проблема, пожа
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Возникла проблема при генерации PDF, пожалуйста, попробуйте еще раз через некоторое время."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Думаю..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Обновить резюме"
msgid "Update your password"
msgstr "Обновите пароль"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Обновлено"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Обновление пароля..."
@@ -3276,4 +3244,3 @@ msgstr "Уменьшить"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Зулу"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Pridať riadok za"
msgid "Add Row Before"
msgstr "Pridať riadok pred"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Pridané"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikánčina"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Chat s AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI vrátila niektoré neplatné odkazy"
@@ -414,10 +406,6 @@ msgstr "Študijný odbor"
msgid "Artificial Intelligence"
msgstr "Umelá inteligencia"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Požiadajte ma o aktualizáciu vášho životopisu..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Pomer strán"
@@ -623,10 +611,6 @@ msgstr "Kruh"
msgid "Clear all"
msgstr "Vymazať všetko"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Vymazať históriu chatu"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Kliknutím sem vyber súbor na import"
@@ -1086,10 +1070,6 @@ msgstr "napr. 150000"
msgid "e.g. 50000"
msgstr "napr. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "napr. Zmeňte moje meno na..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "napr. frontend developer pracovných miest v Berlíne"
@@ -2205,10 +2185,6 @@ msgstr "Odstrániť"
msgid "Remove Password"
msgstr "Odstrániť heslo"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Odstránené"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Odstraňujem ochranu heslom..."
@@ -2748,10 +2724,6 @@ msgstr "Pri generovaní DOCX došlo k problému, skúste to prosím znova."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Pri generovaní PDF sa vyskytol problém, skús to prosím znova o chvíľu."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Premýšľam..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Aktualizovať životopis"
msgid "Update your password"
msgstr "Aktualizuj svoje heslo"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Aktualizované"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Aktualizujem tvoje heslo..."
@@ -3276,4 +3244,3 @@ msgstr "Oddialiť"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Dodaj vrstico za"
msgid "Add Row Before"
msgstr "Dodaj vrstico pred"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Dodano"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afriščina"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Klepet z AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI je vrnil nekaj neveljavnih referenc"
@@ -414,10 +406,6 @@ msgstr "Področje študija"
msgid "Artificial Intelligence"
msgstr "Umetna inteligenca"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Prosite me za posodobitev vašega življenjepisa..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Razmerje stranic"
@@ -623,10 +611,6 @@ msgstr "Krog"
msgid "Clear all"
msgstr "Počisti vse"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Počistite zgodovino klepeta"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Kliknite tukaj za izbiro datoteke za uvoz"
@@ -1086,10 +1070,6 @@ msgstr "npr. 150000"
msgid "e.g. 50000"
msgstr "npr. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "npr. Spremenite moje ime v..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "npr. delovna mesta frontend razvijalca v Berlinu"
@@ -2205,10 +2185,6 @@ msgstr "Odstrani"
msgid "Remove Password"
msgstr "Odstrani geslo"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Odstranjeno"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Odstranjevanje zaščite z geslom..."
@@ -2748,10 +2724,6 @@ msgstr "Pri ustvarjanju DOCX je prišlo do težave, poskusite znova."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Prišlo je do težave pri ustvarjanju PDF-ja, poskusite znova čez nekaj časa."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Razmišljam..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Posodobi življenjepis"
msgid "Update your password"
msgstr "Posodobite svoje geslo"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Posodobljeno"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Posodabljanje vašega gesla..."
@@ -3276,4 +3244,3 @@ msgstr "Oddalji"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zuluščina"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Shto rresht pas"
msgid "Add Row Before"
msgstr "Shto rresht para"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Shtuar"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikanisht"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Bisedë me AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI ktheu disa referenca të pavlefshme"
@@ -414,10 +406,6 @@ msgstr "Fusha e studimit"
msgid "Artificial Intelligence"
msgstr "Inteligjenca Artificiale"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Më kërkoni të përditësoj CV-në tuaj..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Proporcioni"
@@ -623,10 +611,6 @@ msgstr "Rreth"
msgid "Clear all"
msgstr "Pastro të gjitha"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Pastro historikun e bisedës"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Klikoni këtu për të zgjedhur një skedar për importim"
@@ -1086,10 +1070,6 @@ msgstr "p.sh. 150000"
msgid "e.g. 50000"
msgstr "p.sh. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "p.sh. Ndrysho emrin tim në..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "p.sh. vende pune për zhvillues frontend në Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Hiq"
msgid "Remove Password"
msgstr "Hiq fjalëkalimin"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Hequr"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Po hiqet mbrojtja me fjalëkalim..."
@@ -2748,10 +2724,6 @@ msgstr "Ndodhi një problem gjatë gjenerimit të DOCX-it, ju lutemi provoni pë
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Pati një problem gjatë gjenerimit të PDF-së, ju lutemi provoni përsëri pas pak."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Duke menduar..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Përditëso CV-në"
msgid "Update your password"
msgstr "Përditësoni fjalëkalimin tuaj"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Përditësuar"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Po përditësohet fjalëkalimi juaj..."
@@ -3276,4 +3244,3 @@ msgstr "Zvogëlo"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Додај ред после"
msgid "Add Row Before"
msgstr "Додај ред пре"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Додато"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Африканс"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI ћаскање"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI је вратио неке неважеће референце"
@@ -414,10 +406,6 @@ msgstr "Област студија"
msgid "Artificial Intelligence"
msgstr "Вештачка интелигенција"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Замолите ме да ажурирам ваш животопис..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Однос стране"
@@ -623,10 +611,6 @@ msgstr "Круг"
msgid "Clear all"
msgstr "Очисти све"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Обришите историју ћаскања"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Кликните овде да изаберете датотеку за увоз"
@@ -1086,10 +1070,6 @@ msgstr "нпр. 150000"
msgid "e.g. 50000"
msgstr "нпр. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "нпр. Промените моје име у..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "нпр. послови фронтенд програмера у Берлину"
@@ -2205,10 +2185,6 @@ msgstr "Уклони"
msgid "Remove Password"
msgstr "Уклони лозинку"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Уклоњено"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Уклањање заштите лозинком..."
@@ -2748,10 +2724,6 @@ msgstr "Дошло је до проблема при генерисању DOCX-
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Дошло је до проблема током генерисања PDF-а, покушајте поново након неког времена."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Размишљам..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Ажурирај резиме"
msgid "Update your password"
msgstr "Ажурирајте своју лозинку"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Ажурирано"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Ажурирање ваше лозинке..."
@@ -3276,4 +3244,3 @@ msgstr "Умањи"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Зулу"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Lägg till rad efter"
msgid "Add Row Before"
msgstr "Lägg till rad före"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Tillagd"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikanska"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI-chatt"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI returnerade några ogiltiga referenser"
@@ -414,10 +406,6 @@ msgstr "Studieområde"
msgid "Artificial Intelligence"
msgstr "Artificiell intelligens"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Be mig att uppdatera ditt CV..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Bildförhållande"
@@ -623,10 +611,6 @@ msgstr "Cirkel"
msgid "Clear all"
msgstr "Rensa alla"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Rensa chatthistorik"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Klicka här för att välja en fil att importera"
@@ -1086,10 +1070,6 @@ msgstr "t.ex. 150000"
msgid "e.g. 50000"
msgstr "t.ex. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "t.ex. Ändra mitt namn till..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "t.ex. frontend utvecklare jobb i Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Ta bort"
msgid "Remove Password"
msgstr "Ta bort lösenord"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Borttagen"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Tar bort lösenordsskydd..."
@@ -2748,10 +2724,6 @@ msgstr "Det uppstod ett problem vid genereringen av DOCX, försök igen."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Det uppstod ett problem när PDF-filen skulle genereras, försök igen om en stund."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Tänker..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Uppdatera CV"
msgid "Update your password"
msgstr "Uppdatera ditt lösenord"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Uppdaterad"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Uppdaterar ditt lösenord..."
@@ -3276,4 +3244,3 @@ msgstr "Zooma ut"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "பின் வரியைச் சேர்க்கவும்"
msgid "Add Row Before"
msgstr "முன் வரியைச் சேர்க்கவும்"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "சேர்க்கப்பட்டது"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "ஆஃப்ரிகான்ஸ்"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI அரட்டை"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI சில செல்லாத குறிப்புகளைத் திருப்பியனுப்பியது."
@@ -414,10 +406,6 @@ msgstr "கற்றல் துறை"
msgid "Artificial Intelligence"
msgstr "செயற்கை நுண்ணறிவு"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "உங்கள் ரெஸ்யூமேவை புதுப்பிக்கச் சொல்லுங்கள்..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "ஒப்புத்திணைவு விகிதம்"
@@ -623,10 +611,6 @@ msgstr "வட்டம்"
msgid "Clear all"
msgstr "அனைத்தையும் நீக்கு"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "அரட்டை வரலாற்றை அழி"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "இறக்குமதி செய்ய ஒரு கோப்பை தேர்ந்தெடுக்க இங்கே கிளிக் செய்யவும்"
@@ -1086,10 +1070,6 @@ msgstr "எ.கா. 150000"
msgid "e.g. 50000"
msgstr "எ.கா. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "எ.கா. என் பெயரை மாற்று..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "எ.கா. பெர்லினில் முன்முனை உருவாக்குநர் வேலைகள்"
@@ -2205,10 +2185,6 @@ msgstr "நீக்கு"
msgid "Remove Password"
msgstr "கடவுச்சொல்லை நீக்கு"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "நீக்கப்பட்டது"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "கடவுச்சொல் பாதுகாப்பை நீக்கிக் கொண்டிருக்கிறது..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX-ஐ உருவாக்கும்போது ஒரு சி
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF உருவாக்கும் போது ஒரு பிரச்சனை ஏற்பட்டது, தயவுசெய்து சில நேரம் கழித்து மீண்டும் முயற்சிக்கவும்."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "சிந்திக்கிறேன்..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "ரெஸ்யூமியை புதுப்பிக்கவு
msgid "Update your password"
msgstr "உங்கள் கடவுச்சொல்லை புதுப்பிக்கவும்"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "புதுப்பிக்கப்பட்டது"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "உங்கள் கடவுச்சொல்லை புதுப்பித்து கொண்டிருக்கிறது..."
@@ -3276,4 +3244,3 @@ msgstr "சிறிதாக்கு"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "ஜூலு"
-33
View File
@@ -244,10 +244,6 @@ msgstr "తరువాత వరుస చేర్చండి"
msgid "Add Row Before"
msgstr "ముందు వరుస చేర్చండి"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "జోడించబడింది"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "ఆఫ్రికాన్స్"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI చాట్"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI కొన్ని చెల్లని సూచనలను తిరిగి ఇచ్చింది"
@@ -414,10 +406,6 @@ msgstr "అధ్యయన విభాగం"
msgid "Artificial Intelligence"
msgstr "ఆర్టిఫిషియల్ ఇంటెలిజెన్స్"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "మీ రెజ్యూమెను అప్‌డేట్ చేయమని నన్ను అడగండి..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "కారక నిష్పత్తి"
@@ -623,10 +611,6 @@ msgstr "వృత్తం"
msgid "Clear all"
msgstr "అన్నింటినీ తొలగించండి"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "చాట్ చరిత్రను క్లియర్ చేయి"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "ఇంపోర్ట్ చేయడానికి ఫైల్ ను ఎంచుకోవడానికి ఇక్కడ క్లిక్ చేయండి"
@@ -1086,10 +1070,6 @@ msgstr "ఉదా. 150000"
msgid "e.g. 50000"
msgstr "ఉదా. 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "ఉదా. నా పేరు మార్చు..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "ఉదా. బెర్లిన్‌లో ఫ్రంట్‌ఎండ్ డెవలపర్ ఉద్యోగాలు"
@@ -2205,10 +2185,6 @@ msgstr "తొలగించు"
msgid "Remove Password"
msgstr "పాస్‌వర్డ్‌ను తీసివేయండి"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "తొలగించబడింది"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "పాస్‌వర్డ్ రక్షణను తీసివేస్తున్నాము..."
@@ -2748,10 +2724,6 @@ msgstr "DOCXను రూపొందించేటప్పుడు ఒక
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF రూపొందించడంలో సమస్య ఏర్పడింది, దయచేసి కొద్దిసేపటి తరువాత మళ్లీ ప్రయత్నించండి."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "ఆలోచిస్తున్నాను..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "రిజ్యూమ్‌ను నవీకరించండి"
msgid "Update your password"
msgstr "మీ పాస్‌వర్డ్‌ను నవీకరించండి"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "అప్‌డేట్ చేయబడింది"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "మీ పాస్‌వర్డ్‌ను నవీకరిస్తోంది..."
@@ -3276,4 +3244,3 @@ msgstr "జూమ్ అవుట్ చేయండి"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "జులు"
-33
View File
@@ -244,10 +244,6 @@ msgstr "เพิ่มแถวหลัง"
msgid "Add Row Before"
msgstr "เพิ่มแวก่อน"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "เพิ่มแล้ว"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "อาฟรีกานส์"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "แชท AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI ส่งคืนการอ้างอิงที่ไม่ถูกต้องบางรายการ"
@@ -414,10 +406,6 @@ msgstr "สาขาวิชา"
msgid "Artificial Intelligence"
msgstr "ปัญญาประดิษฐ์"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "ขอให้ฉันอัปเดตเรซูเม่ของคุณ..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "อัตราส่วนภาพ"
@@ -623,10 +611,6 @@ msgstr "วงกลม"
msgid "Clear all"
msgstr "ล้างทั้งหมด"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "ล้างประวัติแชท"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "คลิกที่นี่เพื่อเลือกไฟล์ที่จะนำเข้า"
@@ -1086,10 +1070,6 @@ msgstr "เช่น 150000"
msgid "e.g. 50000"
msgstr "เช่น 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "เช่น เปลี่ยนชื่อฉันเป็น..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "เช่น งานนักพัฒนาฟรอนต์เอนด์ในเบอร์ลิน"
@@ -2205,10 +2185,6 @@ msgstr "ลบ"
msgid "Remove Password"
msgstr "ลบรหัสผ่าน"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "ลบแล้ว"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "กำลังลบการป้องกันด้วยรหัสผ่าน..."
@@ -2748,10 +2724,6 @@ msgstr "เกิดปัญหาในระหว่างการสร้
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "เกิดปัญหาในการสร้าง PDF โปรดลองใหม่อีกครั้งในภายหลัง"
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "กำลังคิด..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "อัปเดตประวัติย่อ"
msgid "Update your password"
msgstr "อัปเดตรหัสผ่านของคุณ"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "อัปเดตแล้ว"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "กำลังอัปเดตรหัสผ่านของคุณ..."
@@ -3276,4 +3244,3 @@ msgstr "ซูมออก"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "ซูลู"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Sonra Satır Ekle"
msgid "Add Row Before"
msgstr "Önce Satır Ekle"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Eklendi"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "Yapay Zeka"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Yapay Zeka Sohbeti"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI bazı geçersiz referanslar döndürdü"
@@ -414,10 +406,6 @@ msgstr "Çalışma alanı"
msgid "Artificial Intelligence"
msgstr "Yapay Zekâ"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Özgeçmişinizi güncellememi isteyin..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "En/Boy Oranı"
@@ -623,10 +611,6 @@ msgstr "Daire"
msgid "Clear all"
msgstr "Tümünü temizle"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Sohbet geçmişini temizle"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "İçe aktarmak için bir dosya seçmek üzere buraya tıklayın"
@@ -1086,10 +1070,6 @@ msgstr "örneğin 150000"
msgid "e.g. 50000"
msgstr "örneğin 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "örn. Adımı şu şekilde değiştir:..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "örneğin Berlin'de frontend developer işleri"
@@ -2205,10 +2185,6 @@ msgstr "Kaldır"
msgid "Remove Password"
msgstr "Şifreyi Kaldır"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Kaldırıldı"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Şifre koruması kaldırılıyor..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX oluşturulurken bir sorun oluştu, lütfen tekrar deneyin."
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF oluşturulurken bir sorun oluştu, lütfen daha sonra tekrar deneyin."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Düşünüyor..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Özgeçmişi Güncelle"
msgid "Update your password"
msgstr "Şifrenizi güncelleyin"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Güncellendi"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Şifreniz güncelleniyor..."
@@ -3276,4 +3244,3 @@ msgstr "Uzaklaştır"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Додати Рядок Знизу"
msgid "Add Row Before"
msgstr "Додати Рядок Згори"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Додано"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Африканська"
msgid "AI"
msgstr "ШІ"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Чат з ШІ"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "ШІ повернув кілька невірних посилань"
@@ -414,10 +406,6 @@ msgstr "Освітня програма"
msgid "Artificial Intelligence"
msgstr "Штучний інтелект"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Попросіть мене оновити ваше резюме..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Пропорції"
@@ -623,10 +611,6 @@ msgstr "Кругле"
msgid "Clear all"
msgstr "Зачистити все."
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Очистити історію чату"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Натисніть тут, щоб вибрати файл для імпорту"
@@ -1086,10 +1070,6 @@ msgstr "наприклад, 150000"
msgid "e.g. 50000"
msgstr "наприклад, 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "напр.: Змініть моє ім'я на..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "наприклад, вакансії фронтенд-розробника в Берліні"
@@ -2205,10 +2185,6 @@ msgstr "Видалити"
msgid "Remove Password"
msgstr "Видалити пароль"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Видалено"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Видалення захисту паролем..."
@@ -2748,10 +2724,6 @@ msgstr "Під час генерації DOCX виникла проблема,
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Сталася проблема під час створення PDF, будь ласка, спробуйте ще раз пізніше."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Думаю..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Оновити резюме"
msgid "Update your password"
msgstr "Оновіть свій пароль"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Оновлено"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Оновлення пароля..."
@@ -3276,4 +3244,3 @@ msgstr "Зменшити"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Зулу"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Qatordan keyin qator qoshish"
msgid "Add Row Before"
msgstr "Qatordan oldin qator qoshish"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Qoʻshildi"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Afrikaans"
msgid "AI"
msgstr "SO"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr ""
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI ba'zi nomaqbul havolalarni qaytardi"
@@ -414,10 +406,6 @@ msgstr "Ta'lim sohasi"
msgid "Artificial Intelligence"
msgstr "Sun'iy intellekt"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Rezyumeyingizni yangilashimni soʻrang..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Tomonlar nisbati"
@@ -623,10 +611,6 @@ msgstr "Doira"
msgid "Clear all"
msgstr "Barchasini tozalash"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Chat tarixini tozalash"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Import qilish uchun faylni tanlash uchun shu yerni bosing"
@@ -1086,10 +1070,6 @@ msgstr "masalan 150000"
msgid "e.g. 50000"
msgstr "masalan 50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "masalan, Ismimni ...ga oʻzgartiring"
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "Masalan, Berlin shahrida frontend-dasturchi ish o'rinlari"
@@ -2205,10 +2185,6 @@ msgstr "Olib tashlash"
msgid "Remove Password"
msgstr "Parolni olib tashlash"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Olib tashlandi"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Parol himoyasi olib tashlanmoqda..."
@@ -2748,10 +2724,6 @@ msgstr "DOCX faylini yaratishda muammo yuzaga keldi, iltimos, yana urinib ko'rin
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "PDF yaratishda muammo yuzaga keldi, iltimos, birozdan so'ng qaytadan urinib ko'ring."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Oʻylayapman..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Rezyumeni yangilash"
msgid "Update your password"
msgstr "Parolingizni yangilash"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Yangilandi"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Parolingiz yangilanmoqda..."
@@ -3276,4 +3244,3 @@ msgstr "Kichraytirish"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "Thêm dòng sau"
msgid "Add Row Before"
msgstr "Thêm dòng trước"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "Đã thêm"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "Tiếng Afrikaans"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "Trò chuyện AI"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI đã trả về một số tham chiếu không hợp lệ"
@@ -414,10 +406,6 @@ msgstr "Lĩnh vực học tập"
msgid "Artificial Intelligence"
msgstr "Trí tuệ nhân tạo"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "Hãy nhờ tôi cập nhật hồ sơ của bạn..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "Tỷ lệ khung hình"
@@ -623,10 +611,6 @@ msgstr "Vòng tròn"
msgid "Clear all"
msgstr "Xóa tất cả"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "Xóa lịch sử trò chuyện"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "Nhấn vào đây để chọn file cần nhập khẩu"
@@ -1086,10 +1070,6 @@ msgstr "ví dụ: 150.000"
msgid "e.g. 50000"
msgstr "ví dụ: 50.000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "vd. Đổi tên tôi thành..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "Ví dụ: các vị trí tuyển dụng lập trình viên frontend tại Berlin"
@@ -2205,10 +2185,6 @@ msgstr "Xóa"
msgid "Remove Password"
msgstr "Xóa mật khẩu"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "Đã xóa"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "Đang xóa bảo vệ mật khẩu..."
@@ -2748,10 +2724,6 @@ msgstr "Đã xảy ra sự cố trong quá trình tạo tệp DOCX, vui lòng th
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "Đã xảy ra sự cố khi tạo PDF, hãy thử lại sau."
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "Đang suy nghĩ..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "Cập nhật resume"
msgid "Update your password"
msgstr "Cập nhật mật khẩu của bạn"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "Đã cập nhật"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "Đang cập nhật mật khẩu của bạn..."
@@ -3276,4 +3244,3 @@ msgstr "Thu nhỏ"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "Zulu"
-33
View File
@@ -244,10 +244,6 @@ msgstr "在后面添加行"
msgid "Add Row Before"
msgstr "在前面添加行"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "已添加"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "南非语"
msgid "AI"
msgstr "AI(人工智能)"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI 对话"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "人工智能返回了一些无效引用"
@@ -414,10 +406,6 @@ msgstr "学习领域"
msgid "Artificial Intelligence"
msgstr "人工智能"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "让我来更新你的简历..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "宽高比"
@@ -623,10 +611,6 @@ msgstr "圆形"
msgid "Clear all"
msgstr "全部清除"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "清除聊天记录"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "点击此处选择要导入的文件"
@@ -1086,10 +1070,6 @@ msgstr "例如:150000"
msgid "e.g. 50000"
msgstr "例如:50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "例如:将我的名字改为..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "例如:柏林前端开发员职位"
@@ -2205,10 +2185,6 @@ msgstr "移除"
msgid "Remove Password"
msgstr "移除密码"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "已移除"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "正在移除密码保护…"
@@ -2748,10 +2724,6 @@ msgstr "生成 DOCX 时出现问题,请重试。"
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "生成 PDF 时出现问题,请稍后重试。"
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "思考中..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "更新简历"
msgid "Update your password"
msgstr "更新你的密码"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "已更新"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "正在更新你的密码…"
@@ -3276,4 +3244,3 @@ msgstr "缩小"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "祖鲁语"
-33
View File
@@ -244,10 +244,6 @@ msgstr "在後方新增列"
msgid "Add Row Before"
msgstr "在前方新增列"
#: src/components/ai/chat.tsx
msgid "Added"
msgstr "已新增"
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -266,10 +262,6 @@ msgstr "南非荷蘭語"
msgid "AI"
msgstr "AI"
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr "AI 對話"
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr "AI 返回了一些無效的參照"
@@ -414,10 +406,6 @@ msgstr "學習領域"
msgid "Artificial Intelligence"
msgstr "人工智慧"
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr "讓我來更新您的履歷..."
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr "顯示比例"
@@ -623,10 +611,6 @@ msgstr "圓形"
msgid "Clear all"
msgstr "清除所有"
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr "清除聊天紀錄"
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr "按這裡選擇要匯入的檔案"
@@ -1086,10 +1070,6 @@ msgstr "例如:150000"
msgid "e.g. 50000"
msgstr "例如:50000"
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr "例如:將我的姓名改為..."
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr "例如:在柏林的前端開發人員工作"
@@ -2205,10 +2185,6 @@ msgstr "移除"
msgid "Remove Password"
msgstr "移除密碼"
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr "已移除"
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr "正在移除密碼保護…"
@@ -2748,10 +2724,6 @@ msgstr "生成 DOCX 時出現問題,請重試。"
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr "產生 PDF 時發生問題,請稍後再試一次。"
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr "思考中..."
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3037,10 +3009,6 @@ msgstr "更新履歷"
msgid "Update your password"
msgstr "更新您的密碼"
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr "已更新"
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr "正在更新您的密碼…"
@@ -3276,4 +3244,3 @@ msgstr "縮小"
#: src/utils/locale.ts
msgid "Zulu"
msgstr "祖魯語"
-32
View File
@@ -239,10 +239,6 @@ msgstr ""
msgid "Add Row Before"
msgstr ""
#: src/components/ai/chat.tsx
msgid "Added"
msgstr ""
#. placeholder {0}: skillsToSync.length
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "Added {0} new skills to your original resume"
@@ -261,10 +257,6 @@ msgstr ""
msgid "AI"
msgstr ""
#: src/components/ai/chat.tsx
msgid "AI Chat"
msgstr ""
#: src/routes/dashboard/job-search/-components/tailor-dialog.tsx
msgid "AI returned some invalid references"
msgstr ""
@@ -409,10 +401,6 @@ msgstr ""
msgid "Artificial Intelligence"
msgstr ""
#: src/components/ai/chat.tsx
msgid "Ask me to update your resume..."
msgstr ""
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
msgid "Aspect Ratio"
msgstr ""
@@ -618,10 +606,6 @@ msgstr ""
msgid "Clear all"
msgstr ""
#: src/components/ai/chat.tsx
msgid "Clear chat history"
msgstr ""
#: src/dialogs/resume/import.tsx
msgid "Click here to select a file to import"
msgstr ""
@@ -1081,10 +1065,6 @@ msgstr ""
msgid "e.g. 50000"
msgstr ""
#: src/components/ai/chat.tsx
msgid "e.g. Change my name to..."
msgstr ""
#: src/routes/dashboard/job-search/index.tsx
msgid "e.g. frontend developer jobs in Berlin"
msgstr ""
@@ -2200,10 +2180,6 @@ msgstr ""
msgid "Remove Password"
msgstr ""
#: src/components/ai/chat.tsx
msgid "Removed"
msgstr ""
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
msgid "Removing password protection..."
msgstr ""
@@ -2743,10 +2719,6 @@ msgstr ""
msgid "There was a problem while generating the PDF, please try again in some time."
msgstr ""
#: src/components/ai/chat.tsx
msgid "Thinking..."
msgstr ""
#: src/routes/builder/$resumeId/-components/header.tsx
#: src/routes/dashboard/resumes/-components/menus/context-menu.tsx
#: src/routes/dashboard/resumes/-components/menus/dropdown-menu.tsx
@@ -3032,10 +3004,6 @@ msgstr ""
msgid "Update your password"
msgstr ""
#: src/components/ai/chat.tsx
msgid "Updated"
msgstr ""
#: src/dialogs/auth/change-password.tsx
msgid "Updating your password..."
msgstr ""
@@ -0,0 +1,92 @@
CREATE TABLE "jwks" (
"id" uuid PRIMARY KEY,
"public_key" text NOT NULL,
"private_key" text NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"expires_at" timestamp with time zone
);
--> statement-breakpoint
CREATE TABLE "oauth_access_token" (
"id" uuid PRIMARY KEY,
"token" text NOT NULL UNIQUE,
"client_id" text NOT NULL,
"session_id" uuid,
"user_id" uuid,
"reference_id" text,
"refresh_id" uuid,
"expires_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now(),
"scopes" text[] NOT NULL
);
--> statement-breakpoint
CREATE TABLE "oauth_client" (
"id" uuid PRIMARY KEY,
"client_id" text NOT NULL UNIQUE,
"client_secret" text,
"disabled" boolean DEFAULT false,
"skip_consent" boolean,
"enable_end_session" boolean,
"subject_type" text,
"scopes" text[],
"user_id" uuid,
"created_at" timestamp with time zone DEFAULT now(),
"updated_at" timestamp with time zone DEFAULT now(),
"name" text,
"uri" text,
"icon" text,
"contacts" text[],
"tos" text,
"policy" text,
"software_id" text,
"software_version" text,
"software_statement" text,
"redirect_uris" text[] NOT NULL,
"post_logout_redirect_uris" text[],
"token_endpoint_auth_method" text,
"grant_types" text[],
"response_types" text[],
"public" boolean,
"type" text,
"require_pkce" boolean,
"reference_id" text,
"metadata" jsonb
);
--> statement-breakpoint
CREATE TABLE "oauth_consent" (
"id" uuid PRIMARY KEY,
"client_id" text NOT NULL,
"user_id" uuid,
"reference_id" text,
"scopes" text[] NOT NULL,
"created_at" timestamp with time zone DEFAULT now(),
"updated_at" timestamp with time zone DEFAULT now()
);
--> statement-breakpoint
CREATE TABLE "oauth_refresh_token" (
"id" uuid PRIMARY KEY,
"token" text NOT NULL,
"client_id" text NOT NULL,
"session_id" uuid,
"user_id" uuid NOT NULL,
"reference_id" text,
"expires_at" timestamp with time zone,
"created_at" timestamp with time zone DEFAULT now(),
"revoked" timestamp with time zone,
"auth_time" timestamp with time zone,
"scopes" text[] NOT NULL
);
--> statement-breakpoint
CREATE INDEX "oauth_access_token_token_index" ON "oauth_access_token" ("token");--> statement-breakpoint
CREATE INDEX "oauth_client_client_id_index" ON "oauth_client" ("client_id");--> statement-breakpoint
CREATE INDEX "oauth_consent_user_id_client_id_index" ON "oauth_consent" ("user_id","client_id");--> statement-breakpoint
CREATE INDEX "oauth_refresh_token_token_index" ON "oauth_refresh_token" ("token");--> statement-breakpoint
ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_client_id_oauth_client_client_id_fkey" FOREIGN KEY ("client_id") REFERENCES "oauth_client"("client_id") ON DELETE CASCADE;--> statement-breakpoint
ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_session_id_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "session"("id") ON DELETE SET NULL;--> statement-breakpoint
ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_user_id_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE;--> statement-breakpoint
ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_refresh_id_oauth_refresh_token_id_fkey" FOREIGN KEY ("refresh_id") REFERENCES "oauth_refresh_token"("id") ON DELETE CASCADE;--> statement-breakpoint
ALTER TABLE "oauth_client" ADD CONSTRAINT "oauth_client_user_id_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE;--> statement-breakpoint
ALTER TABLE "oauth_consent" ADD CONSTRAINT "oauth_consent_client_id_oauth_client_client_id_fkey" FOREIGN KEY ("client_id") REFERENCES "oauth_client"("client_id") ON DELETE CASCADE;--> statement-breakpoint
ALTER TABLE "oauth_consent" ADD CONSTRAINT "oauth_consent_user_id_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE;--> statement-breakpoint
ALTER TABLE "oauth_refresh_token" ADD CONSTRAINT "oauth_refresh_token_client_id_oauth_client_client_id_fkey" FOREIGN KEY ("client_id") REFERENCES "oauth_client"("client_id") ON DELETE CASCADE;--> statement-breakpoint
ALTER TABLE "oauth_refresh_token" ADD CONSTRAINT "oauth_refresh_token_session_id_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "session"("id") ON DELETE SET NULL;--> statement-breakpoint
ALTER TABLE "oauth_refresh_token" ADD CONSTRAINT "oauth_refresh_token_user_id_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE;
File diff suppressed because it is too large Load Diff
+27 -26
View File
@@ -34,15 +34,15 @@
"typecheck": "tsgo --noEmit"
},
"dependencies": {
"@ai-sdk/anthropic": "^3.0.58",
"@ai-sdk/google": "^3.0.43",
"@ai-sdk/openai": "^3.0.41",
"@ai-sdk/react": "^3.0.118",
"@aws-sdk/client-s3": "^3.1012.0",
"@ai-sdk/anthropic": "^3.0.64",
"@ai-sdk/google": "^3.0.53",
"@ai-sdk/openai": "^3.0.48",
"@aws-sdk/client-s3": "^3.1015.0",
"@base-ui/react": "^1.3.0",
"@better-auth/api-key": "^1.5.5",
"@better-auth/drizzle-adapter": "^1.5.5",
"@better-auth/infra": "^0.1.12",
"@better-auth/api-key": "^1.5.6",
"@better-auth/drizzle-adapter": "^1.5.6",
"@better-auth/infra": "^0.1.13",
"@better-auth/oauth-provider": "^1.5.6",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
@@ -61,11 +61,11 @@
"@phosphor-icons/react": "^2.1.10",
"@phosphor-icons/web": "^2.1.2",
"@sindresorhus/slugify": "^3.0.0",
"@t3-oss/env-core": "^0.13.10",
"@tanstack/react-query": "^5.91.2",
"@tanstack/react-router": "^1.167.5",
"@tanstack/react-router-ssr-query": "^1.166.9",
"@tanstack/react-start": "^1.166.17",
"@t3-oss/env-core": "^0.13.11",
"@tanstack/react-query": "^5.95.2",
"@tanstack/react-router": "^1.168.3",
"@tanstack/react-router-ssr-query": "^1.166.10",
"@tanstack/react-start": "^1.167.5",
"@tanstack/zod-adapter": "^1.166.9",
"@tiptap/extension-highlight": "^3.20.4",
"@tiptap/extension-table": "^3.20.4",
@@ -75,16 +75,16 @@
"@tiptap/starter-kit": "^3.20.4",
"@uiw/color-convert": "^2.9.6",
"@uiw/react-color-colorful": "^2.9.6",
"ai": "^6.0.116",
"ai-sdk-ollama": "^3.8.1",
"ai": "^6.0.137",
"ai-sdk-ollama": "^3.8.2",
"bcrypt": "^6.0.0",
"better-auth": "^1.5.5",
"better-auth": "^1.5.6",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"docx": "^9.6.1",
"dompurify": "^3.3.3",
"drizzle-orm": "1.0.0-beta.18-7eb39f0",
"drizzle-orm": "1.0.0-beta.19",
"drizzle-zod": "^1.0.0-beta.14-a36c63d",
"es-toolkit": "^1.45.1",
"fast-deep-equal": "^3.1.3",
@@ -101,15 +101,15 @@
"qrcode.react": "^4.2.0",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-hook-form": "^7.71.2",
"react-hook-form": "^7.72.0",
"react-hotkeys-hook": "^5.2.4",
"react-resizable-panels": "^4.7.3",
"react-resizable-panels": "^4.7.5",
"react-window": "^2.2.7",
"react-zoom-pan-pinch": "^3.7.0",
"shadcn": "^4.0.8",
"shadcn": "^4.1.0",
"sharp": "^0.34.5",
"sonner": "^2.0.7",
"srvx": "^0.11.12",
"srvx": "^0.11.13",
"tailwind-merge": "^3.5.0",
"tailwindcss": "^4.2.2",
"ts-pattern": "^5.9.0",
@@ -133,15 +133,16 @@
"@types/js-cookie": "^3.0.6",
"@types/node": "^25.5.0",
"@types/nodemailer": "^7.0.11",
"@types/pg": "^8.18.0",
"@types/pg": "^8.20.0",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@typescript/native-preview": "7.0.0-dev.20260319.1",
"@typescript/native-preview": "7.0.0-dev.20260324.1",
"@vitejs/plugin-react": "^6.0.1",
"babel-plugin-macros": "^3.1.0",
"drizzle-kit": "1.0.0-beta.18-7eb39f0",
"jsdom": "^29.0.0",
"knip": "^5.88.1",
"drizzle-kit": "1.0.0-beta.19",
"jose": "^6.2.2",
"jsdom": "^29.0.1",
"knip": "^6.0.4",
"nitro": "3.0.260311-beta",
"node-addon-api": "^8.6.0",
"node-gyp": "^12.2.0",
+805 -599
View File
File diff suppressed because it is too large Load Diff
-422
View File
@@ -1,422 +0,0 @@
import type { UIMessage } from "ai";
import type { Operation } from "fast-json-patch";
import { useChat } from "@ai-sdk/react";
import { t } from "@lingui/core/macro";
import { Trans } from "@lingui/react/macro";
import { eventIteratorToUnproxiedDataStream } from "@orpc/client";
import {
CheckCircleIcon,
CircleNotchIcon,
PaperPlaneRightIcon,
SparkleIcon,
StopIcon,
TrashSimpleIcon,
} from "@phosphor-icons/react";
import { AnimatePresence, motion } from "motion/react";
import { useCallback, useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { ScrollArea } from "@/components/ui/scroll-area";
import { useAIStore } from "@/integrations/ai/store";
import { client } from "@/integrations/orpc/client";
import { applyResumePatches } from "@/utils/resume/patch";
import { cn } from "@/utils/style";
import { useResumeStore } from "../resume/store/resume";
/**
* Extract patch operations from the latest assistant messages' tool call parts.
* Returns operations that haven't been applied yet (tracked by processedToolCallIds).
*/
function extractNewPatchOperations(
messages: UIMessage[],
processedIds: Set<string>,
): { operations: Operation[]; newIds: string[] } {
const operations: Operation[] = [];
const newIds: string[] = [];
for (const message of messages) {
if (message.role !== "assistant") continue;
for (const part of message.parts) {
if (part.type !== "tool-patch_resume") continue;
const toolPart = part as any;
if (toolPart.state !== "output-available") continue;
const callId = toolPart.toolCallId as string;
if (processedIds.has(callId)) continue;
const result = toolPart.output as { success: boolean; appliedOperations?: Operation[] } | undefined;
if (result?.success && result.appliedOperations) {
operations.push(...result.appliedOperations);
newIds.push(callId);
}
}
}
return { operations, newIds };
}
/**
* LocalStorage helpers for persisting chat messages per resume.
*/
const STORAGE_KEY_PREFIX = "ai-chat-messages";
function getStorageKey(resumeId: string): string {
return `${STORAGE_KEY_PREFIX}:${resumeId}`;
}
function loadStoredMessages(resumeId: string): UIMessage[] {
try {
const stored = localStorage.getItem(getStorageKey(resumeId));
if (!stored) return [];
return JSON.parse(stored) as UIMessage[];
} catch {
return [];
}
}
function saveStoredMessages(resumeId: string, messages: UIMessage[]): void {
try {
localStorage.setItem(getStorageKey(resumeId), JSON.stringify(messages));
} catch {
// Silently fail if localStorage is full or unavailable
}
}
function clearStoredMessages(resumeId: string): void {
localStorage.removeItem(getStorageKey(resumeId));
}
function formatPath(path: string): string {
return path.replace(/^\//, "").replace(/\//g, " ");
}
function formatOperationLabel(op: string): string {
switch (op) {
case "replace":
return t`Updated`;
case "add":
return t`Added`;
case "remove":
return t`Removed`;
default:
return op;
}
}
function ToolBadge({ state, operations }: { state: string; operations?: { op: string; path: string }[] }) {
const isDone = state === "output-available";
return (
<div className="my-0.5 flex flex-col gap-1.5">
<span
data-state={state}
className={cn(
"inline-flex w-fit items-center gap-1.5 rounded-full border px-2.5 py-1 text-[11px] font-medium",
"data-[state=output-available]:border-emerald-500/30 data-[state=output-available]:bg-emerald-500/10 data-[state=output-available]:text-emerald-600 dark:data-[state=output-available]:text-emerald-400",
)}
>
{isDone ? (
<CheckCircleIcon weight="fill" className="size-3" />
) : (
<CircleNotchIcon className="size-3 animate-spin" />
)}
{isDone ? "Changes applied" : "Applying changes..."}
</span>
{isDone && operations && operations.length > 0 && (
<div className="flex flex-col gap-0.5 pl-1 text-[11px] text-muted-foreground">
{operations.map((op, i) => (
<span key={i} className="flex items-center gap-1">
<span className="opacity-40"></span>
{formatOperationLabel(op.op)} {formatPath(op.path)}
</span>
))}
</div>
)}
</div>
);
}
function MessageParts({ message }: { message: UIMessage }) {
const parts = message.parts;
if (parts.length === 0) return null;
return (
<div className="flex flex-col gap-2">
{parts.map((part, i) => {
if (part.type === "step-start") {
if (i === 0) return null;
return <hr key={i} className="my-0.5 border-border/40" />;
}
if (part.type === "text" && part.text.trim()) {
return (
<p key={i} className="text-[13px] leading-relaxed whitespace-pre-wrap">
{part.text}
</p>
);
}
if (part.type === "reasoning" && part.text.trim()) {
return (
<p key={i} className="text-[11px] leading-relaxed whitespace-pre-wrap text-muted-foreground italic">
{part.text}
</p>
);
}
if (part.type === "tool-patch_resume") {
const toolPart = part as any;
const state = toolPart.state as string;
const operations = toolPart.input?.operations as { op: string; path: string }[] | undefined;
return <ToolBadge key={i} state={state} operations={operations} />;
}
return null;
})}
</div>
);
}
export function AIChat() {
const enabled = useAIStore((s) => s.enabled);
const provider = useAIStore((s) => s.provider);
const model = useAIStore((s) => s.model);
const apiKey = useAIStore((s) => s.apiKey);
const baseURL = useAIStore((s) => s.baseURL);
const resumeId = useResumeStore((s) => s.resume.id);
const resumeData = useResumeStore((s) => s.resume.data);
const updateResumeData = useResumeStore((s) => s.updateResumeData);
const [input, setInput] = useState("");
const [open, setOpen] = useState(false);
const bottomRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
const processedToolCallIds = useRef(new Set<string>());
// Load stored messages once on mount and pre-populate processedToolCallIds
// so that already-applied patches are not re-applied.
const [initialMessages] = useState(() => {
const stored = loadStoredMessages(resumeId);
for (const msg of stored) {
if (msg.role !== "assistant") continue;
for (const part of msg.parts) {
if (part.type !== "tool-patch_resume") continue;
const toolPart = part as any;
if (toolPart.state === "output-available") {
processedToolCallIds.current.add(toolPart.toolCallId as string);
}
}
}
return stored;
});
const { messages, sendMessage, status, stop, setMessages } = useChat({
messages: initialMessages,
transport: {
async sendMessages(options) {
return eventIteratorToUnproxiedDataStream(
await client.ai.chat(
{
provider,
model,
apiKey,
baseURL,
messages: options.messages,
resumeData,
},
{ signal: options.abortSignal },
),
);
},
reconnectToStream() {
throw new Error("Unsupported");
},
},
onError(error) {
toast.error("AI chat error", { description: error.message });
},
});
// Apply patches when new tool results arrive
useEffect(() => {
const { operations, newIds } = extractNewPatchOperations(messages, processedToolCallIds.current);
if (operations.length === 0) return;
try {
const patched = applyResumePatches(resumeData, operations);
updateResumeData((draft) => {
Object.assign(draft, patched);
});
for (const id of newIds) processedToolCallIds.current.add(id);
} catch (error) {
toast.error("Failed to apply resume changes", {
description: error instanceof Error ? error.message : "Unknown error",
});
}
}, [messages, resumeData, updateResumeData]);
// Persist messages to localStorage whenever they change
useEffect(() => {
saveStoredMessages(resumeId, messages);
}, [resumeId, messages]);
// Auto-scroll to bottom (sentinel so it works with ScrollArea viewport)
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
}, [messages]);
// Refocus the input when the AI finishes responding
useEffect(() => {
if (status === "ready") inputRef.current?.focus();
}, [status]);
const handleOpenChange = useCallback((nextOpen: boolean) => {
setOpen(nextOpen);
}, []);
const handleClearMessages = useCallback(() => {
setMessages([]);
clearStoredMessages(resumeId);
processedToolCallIds.current.clear();
}, [resumeId, setMessages]);
const handleSubmit = useCallback(
async (e: React.SubmitEvent) => {
e.preventDefault();
if (!input.trim() || status !== "ready") return;
await sendMessage({ text: input });
setInput("");
},
[input, status, sendMessage],
);
if (!enabled) return null;
const isLoading = status === "submitted" || status === "streaming";
return (
<Popover open={open} onOpenChange={handleOpenChange}>
<PopoverTrigger
render={
<Button size="icon" variant="ghost">
<SparkleIcon />
</Button>
}
/>
<PopoverContent className="flex h-128 w-md flex-col gap-y-0 overflow-hidden p-0" side="top" align="center">
{/* Header with clear button */}
<div className="flex shrink-0 items-center justify-between border-b px-3 py-1.5">
<p className="text-xs font-medium text-muted-foreground">
<Trans>AI Chat</Trans>
</p>
<Button
size="icon-sm"
variant="ghost"
className="size-7"
title={t`Clear chat history`}
onClick={handleClearMessages}
disabled={messages.length === 0 || isLoading}
>
<TrashSimpleIcon className="size-3" />
</Button>
</div>
{/* Message list — min-h-0 so flex constrains height and viewport scrolls */}
<ScrollArea className="min-h-0 flex-1 px-4">
<div className="flex flex-col gap-y-4 pt-4">
{messages.length === 0 && (
<div className="flex h-full items-center justify-center py-6">
<p className="text-center text-xs text-muted-foreground">
<Trans>Ask me to update your resume...</Trans>
</p>
</div>
)}
<div className="flex flex-col gap-4">
<AnimatePresence initial={false} mode="popLayout">
{messages.map((message) => (
<motion.div
key={message.id}
className={cn("flex", message.role === "user" ? "justify-end" : "justify-start")}
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -8 }}
transition={{ duration: 0.16, ease: "easeOut" }}
style={{ willChange: "transform, opacity" }}
layout
>
<div
data-role={message.role}
className={cn(
"max-w-[85%] rounded-md px-3.5 py-2.5",
"data-[role=user]:rounded-br-sm data-[role=user]:bg-primary data-[role=user]:text-primary-foreground",
"data-[role=assistant]:rounded-bl-sm data-[role=assistant]:bg-muted data-[role=assistant]:text-foreground",
)}
>
{message.role === "user" ? (
<p className="text-[13px] leading-relaxed">
{message.parts.map((part, i) =>
part.type === "text" ? <span key={i}>{part.text}</span> : null,
)}
</p>
) : (
<MessageParts message={message} />
)}
</div>
</motion.div>
))}
</AnimatePresence>
{status === "submitted" && (
<div className="flex justify-start">
<div className="rounded-md rounded-bl-sm bg-muted px-3.5 py-2.5">
<div className="flex items-center gap-2 text-[13px] text-muted-foreground">
<CircleNotchIcon className="size-3 animate-spin" />
<span>
<Trans>Thinking...</Trans>
</span>
</div>
</div>
</div>
)}
<div ref={bottomRef} aria-hidden />
</div>
</div>
</ScrollArea>
{/* Input form — shrink-0 so it stays visible when content scrolls */}
<form onSubmit={handleSubmit} className="flex shrink-0 items-center gap-1.5 border-t px-3 py-2">
<input
ref={inputRef}
value={input}
disabled={!enabled || isLoading}
onChange={(e) => setInput(e.target.value)}
placeholder={t`e.g. Change my name to...`}
className="flex-1 bg-transparent text-[13px] outline-none placeholder:text-muted-foreground"
/>
{isLoading ? (
<Button type="button" size="icon" variant="ghost" onClick={stop} className="size-7 shrink-0">
<StopIcon className="size-3.5" />
</Button>
) : (
<Button type="submit" size="icon" variant="ghost" disabled={!input.trim()} className="size-7 shrink-0">
<PaperPlaneRightIcon className="size-3.5" />
</Button>
)}
</form>
</PopoverContent>
</Popover>
);
}
@@ -1,138 +0,0 @@
import * as React from "react";
type InputValue = string[] | string;
interface VisuallyHiddenInputProps<T = InputValue> extends Omit<
React.InputHTMLAttributes<HTMLInputElement>,
"value" | "checked" | "onReset"
> {
value?: T;
checked?: boolean;
control: HTMLElement | null;
bubbles?: boolean;
}
export function VisuallyHiddenInput<T = InputValue>(props: VisuallyHiddenInputProps<T>) {
const { control, value, checked, bubbles = true, type = "hidden", style, ...inputProps } = props;
const isCheckInput = React.useMemo(() => type === "checkbox" || type === "radio" || type === "switch", [type]);
const inputRef = React.useRef<HTMLInputElement>(null);
const prevValueRef = React.useRef<{
value: T | boolean | undefined;
previous: T | boolean | undefined;
}>({
value: isCheckInput ? checked : value,
previous: isCheckInput ? checked : value,
});
const prevValue = React.useMemo(() => {
const currentValue = isCheckInput ? checked : value;
if (prevValueRef.current.value !== currentValue) {
prevValueRef.current.previous = prevValueRef.current.value;
prevValueRef.current.value = currentValue;
}
return prevValueRef.current.previous;
}, [isCheckInput, value, checked]);
const [controlSize, setControlSize] = React.useState<{
width?: number;
height?: number;
}>({});
React.useLayoutEffect(() => {
if (!control) {
setControlSize({});
return;
}
setControlSize({
width: control.offsetWidth,
height: control.offsetHeight,
});
if (typeof window === "undefined") return;
const resizeObserver = new ResizeObserver((entries) => {
if (!Array.isArray(entries) || !entries.length) return;
const entry = entries[0];
if (!entry) return;
let width: number;
let height: number;
if ("borderBoxSize" in entry) {
const borderSizeEntry = entry.borderBoxSize;
const borderSize = Array.isArray(borderSizeEntry) ? borderSizeEntry[0] : borderSizeEntry;
width = borderSize.inlineSize;
height = borderSize.blockSize;
} else {
width = control.offsetWidth;
height = control.offsetHeight;
}
setControlSize({ width, height });
});
resizeObserver.observe(control, { box: "border-box" });
return () => {
resizeObserver.disconnect();
};
}, [control]);
React.useEffect(() => {
const input = inputRef.current;
if (!input) return;
const inputProto = window.HTMLInputElement.prototype;
const propertyKey = isCheckInput ? "checked" : "value";
const eventType = isCheckInput ? "click" : "input";
const currentValue = isCheckInput ? checked : value;
const serializedCurrentValue = isCheckInput
? checked
: typeof value === "object" && value !== null
? JSON.stringify(value)
: value;
const descriptor = Object.getOwnPropertyDescriptor(inputProto, propertyKey);
const setter = descriptor?.set?.bind(input);
if (prevValue !== currentValue && setter) {
const event = new Event(eventType, { bubbles });
setter.call(input, serializedCurrentValue);
input.dispatchEvent(event);
}
}, [prevValue, value, checked, bubbles, isCheckInput]);
const composedStyle = React.useMemo<React.CSSProperties>(() => {
return {
...style,
...(controlSize.width !== undefined && controlSize.height !== undefined ? controlSize : {}),
border: 0,
clip: "rect(0 0 0 0)",
clipPath: "inset(50%)",
height: "1px",
margin: "-1px",
overflow: "hidden",
padding: 0,
position: "absolute",
whiteSpace: "nowrap",
width: "1px",
};
}, [style, controlSize]);
return (
<input
type={type}
{...inputProps}
ref={inputRef}
aria-hidden={isCheckInput}
tabIndex={-1}
defaultChecked={isCheckInput ? checked : undefined}
style={composedStyle}
/>
);
}
+1 -1
View File
@@ -12,7 +12,7 @@ type LevelType = z.infer<typeof levelDesignSchema>["type"];
type LevelTypeComboboxProps = Omit<SingleComboboxProps, "options">;
export const getLevelTypeName = (type: LevelType) => {
const getLevelTypeName = (type: LevelType) => {
return match(type)
.with("hidden", () => t`Hidden`)
.with("circle", () => t`Circle`)
+1 -1
View File
@@ -38,4 +38,4 @@ function Badge({
});
}
export { Badge, badgeVariants };
export { Badge };
+1 -1
View File
@@ -73,4 +73,4 @@ function ButtonGroupSeparator({
);
}
export { ButtonGroup, ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants };
export { ButtonGroup, ButtonGroupSeparator, ButtonGroupText };
+1 -7
View File
@@ -244,10 +244,6 @@ function ComboboxChipsInput({ className, ...props }: ComboboxPrimitive.Input.Pro
);
}
function useComboboxAnchor() {
return React.useRef<HTMLDivElement | null>(null);
}
type ComboboxOption<TValue extends string | number = string> = {
value: TValue;
label: React.ReactNode;
@@ -442,13 +438,11 @@ export {
ComboboxItem,
ComboboxLabel,
ComboboxList,
type ComboboxOption,
type ComboboxProps,
ComboboxRoot,
ComboboxSeparator,
ComboboxTrigger,
ComboboxValue,
type ComboboxOption,
type MultiComboboxProps,
type SingleComboboxProps,
useComboboxAnchor,
};
+1 -1
View File
@@ -66,4 +66,4 @@ function TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {
);
}
export { Tabs, TabsContent, TabsList, TabsTrigger, tabsListVariants };
export { Tabs, TabsContent, TabsList, TabsTrigger };
+1 -1
View File
@@ -33,4 +33,4 @@ function Toggle({
return <TogglePrimitive data-slot="toggle" className={cn(toggleVariants({ variant, size, className }))} {...props} />;
}
export { Toggle, toggleVariants };
export { Toggle };
+4
View File
@@ -1,5 +1,7 @@
import { apiKeyClient } from "@better-auth/api-key/client";
import { dashClient } from "@better-auth/infra/client";
import { oauthProviderClient } from "@better-auth/oauth-provider/client";
import { oauthProviderResourceClient } from "@better-auth/oauth-provider/resource-client";
import { genericOAuthClient, inferAdditionalFields, twoFactorClient, usernameClient } from "better-auth/client/plugins";
import { createAuthClient } from "better-auth/react";
@@ -20,6 +22,8 @@ const getAuthClient = () => {
},
}),
genericOAuthClient(),
oauthProviderClient(),
oauthProviderResourceClient(),
inferAdditionalFields<typeof auth>(),
],
});
+32 -2
View File
@@ -1,10 +1,13 @@
import type { GenericOAuthConfig } from "better-auth/plugins";
import type { JWTPayload } from "jose";
import { apiKey } from "@better-auth/api-key";
import { drizzleAdapter } from "@better-auth/drizzle-adapter";
import { dash } from "@better-auth/infra";
import { oauthProvider } from "@better-auth/oauth-provider";
import { BetterAuthError, betterAuth } from "better-auth";
import { openAPI } from "better-auth/plugins";
import { verifyAccessToken } from "better-auth/oauth2";
import { jwt, openAPI } from "better-auth/plugins";
import { genericOAuth } from "better-auth/plugins/generic-oauth";
import { twoFactor } from "better-auth/plugins/two-factor";
import { username } from "better-auth/plugins/username";
@@ -18,6 +21,24 @@ import { schema } from "../drizzle";
import { db } from "../drizzle/client";
import { sendEmail } from "../email/service";
export const authBaseUrl = process.env.BETTER_AUTH_URL ?? env.APP_URL;
function getOAuthAudiences(): string[] {
const base = authBaseUrl.replace(/\/$/, "");
return [base, `${base}/`, `${base}/mcp`, `${base}/mcp/`];
}
export async function verifyOAuthToken(token: string): Promise<JWTPayload> {
return await verifyAccessToken(token, {
jwksUrl: `${authBaseUrl}/api/auth/jwks`,
verifyOptions: {
issuer: `${authBaseUrl}/api/auth`,
audience: getOAuthAudiences(),
},
});
}
function isCustomOAuthProviderEnabled() {
const hasDiscovery = Boolean(env.OAUTH_DISCOVERY_URL);
const hasManual =
@@ -86,7 +107,7 @@ const getAuthConfig = () => {
return betterAuth({
appName: "Reactive Resume",
baseURL: process.env.BETTER_AUTH_URL ?? env.APP_URL,
baseURL: authBaseUrl,
secret: process.env.BETTER_AUTH_SECRET ?? env.AUTH_SECRET,
database: drizzleAdapter(db, { schema, provider: "pg" }),
@@ -231,11 +252,20 @@ const getAuthConfig = () => {
},
plugins: [
jwt(),
openAPI(),
genericOAuth({ config: authConfigs }),
twoFactor({ issuer: "Reactive Resume" }),
apiKey({ enableSessionForAPIKeys: true, rateLimit: { enabled: false } }),
dash({ apiKey: env.BETTER_AUTH_API_KEY, activityTracking: { enabled: true } }),
oauthProvider({
loginPage: "/auth/oauth",
consentPage: "/auth/oauth",
validAudiences: getOAuthAudiences(),
allowDynamicClientRegistration: true,
allowUnauthenticatedClientRegistration: true,
silenceWarnings: { oauthAuthServerConfig: true },
}),
username({
minUsernameLength: 3,
maxUsernameLength: 64,
+208 -1
View File
@@ -269,8 +269,155 @@ export const apikey = pg.pgTable(
],
);
export const jwks = pg.pgTable("jwks", {
id: pg
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
publicKey: pg.text("public_key").notNull(),
privateKey: pg.text("private_key").notNull(),
createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
expiresAt: pg.timestamp("expires_at", { withTimezone: true }),
});
export const oauthClient = pg.pgTable(
"oauth_client",
{
id: pg
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
clientId: pg.text("client_id").notNull().unique(),
clientSecret: pg.text("client_secret"),
disabled: pg.boolean("disabled").default(false),
skipConsent: pg.boolean("skip_consent"),
enableEndSession: pg.boolean("enable_end_session"),
subjectType: pg.text("subject_type"),
scopes: pg.text("scopes").array(),
userId: pg.uuid("user_id").references(() => user.id, { onDelete: "cascade" }),
createdAt: pg.timestamp("created_at", { withTimezone: true }).defaultNow(),
updatedAt: pg
.timestamp("updated_at", { withTimezone: true })
.defaultNow()
.$onUpdate(() => /* @__PURE__ */ new Date()),
name: pg.text("name"),
uri: pg.text("uri"),
icon: pg.text("icon"),
contacts: pg.text("contacts").array(),
tos: pg.text("tos"),
policy: pg.text("policy"),
softwareId: pg.text("software_id"),
softwareVersion: pg.text("software_version"),
softwareStatement: pg.text("software_statement"),
redirectUris: pg.text("redirect_uris").array().notNull(),
postLogoutRedirectUris: pg.text("post_logout_redirect_uris").array(),
tokenEndpointAuthMethod: pg.text("token_endpoint_auth_method"),
grantTypes: pg.text("grant_types").array(),
responseTypes: pg.text("response_types").array(),
public: pg.boolean("public"),
type: pg.text("type"),
requirePKCE: pg.boolean("require_pkce"),
referenceId: pg.text("reference_id"),
metadata: pg.jsonb("metadata"),
},
(t) => [pg.index().on(t.clientId)],
);
export const oauthRefreshToken = pg.pgTable(
"oauth_refresh_token",
{
id: pg
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
token: pg.text("token").notNull(),
clientId: pg
.text("client_id")
.notNull()
.references(() => oauthClient.clientId, { onDelete: "cascade" }),
sessionId: pg.uuid("session_id").references(() => session.id, { onDelete: "set null" }),
userId: pg
.uuid("user_id")
.notNull()
.references(() => user.id, { onDelete: "cascade" }),
referenceId: pg.text("reference_id"),
expiresAt: pg.timestamp("expires_at", { withTimezone: true }),
createdAt: pg.timestamp("created_at", { withTimezone: true }).defaultNow(),
revoked: pg.timestamp("revoked", { withTimezone: true }),
authTime: pg.timestamp("auth_time", { withTimezone: true }),
scopes: pg.text("scopes").array().notNull(),
},
(t) => [pg.index().on(t.token)],
);
export const oauthAccessToken = pg.pgTable(
"oauth_access_token",
{
id: pg
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
token: pg.text("token").notNull().unique(),
clientId: pg
.text("client_id")
.notNull()
.references(() => oauthClient.clientId, { onDelete: "cascade" }),
sessionId: pg.uuid("session_id").references(() => session.id, { onDelete: "set null" }),
userId: pg.uuid("user_id").references(() => user.id, { onDelete: "cascade" }),
referenceId: pg.text("reference_id"),
refreshId: pg.uuid("refresh_id").references(() => oauthRefreshToken.id, { onDelete: "cascade" }),
expiresAt: pg.timestamp("expires_at", { withTimezone: true }),
createdAt: pg.timestamp("created_at", { withTimezone: true }).defaultNow(),
scopes: pg.text("scopes").array().notNull(),
},
(t) => [pg.index().on(t.token)],
);
export const oauthConsent = pg.pgTable(
"oauth_consent",
{
id: pg
.uuid("id")
.notNull()
.primaryKey()
.$defaultFn(() => generateId()),
clientId: pg
.text("client_id")
.notNull()
.references(() => oauthClient.clientId, { onDelete: "cascade" }),
userId: pg.uuid("user_id").references(() => user.id, { onDelete: "cascade" }),
referenceId: pg.text("reference_id"),
scopes: pg.text("scopes").array().notNull(),
createdAt: pg.timestamp("created_at", { withTimezone: true }).defaultNow(),
updatedAt: pg
.timestamp("updated_at", { withTimezone: true })
.defaultNow()
.$onUpdate(() => /* @__PURE__ */ new Date()),
},
(t) => [pg.index().on(t.userId, t.clientId)],
);
export const relations = defineRelations(
{ user, session, account, verification, twoFactor, passkey, resume, resumeStatistics, apikey },
{
user,
session,
account,
verification,
twoFactor,
passkey,
resume,
resumeStatistics,
apikey,
jwks,
oauthClient,
oauthRefreshToken,
oauthAccessToken,
oauthConsent,
},
(r) => ({
user: {
sessions: r.many.session(),
@@ -279,12 +426,24 @@ export const relations = defineRelations(
passkeys: r.many.passkey(),
resumes: r.many.resume(),
apiKeys: r.many.apikey(),
oauthClients: r.many.oauthClient(),
oauthRefreshTokens: r.many.oauthRefreshToken(),
oauthAccessTokens: r.many.oauthAccessToken(),
oauthConsents: r.many.oauthConsent(),
},
session: {
user: r.one.user({
from: r.session.userId,
to: r.user.id,
}),
oauthRefreshTokens: r.many.oauthRefreshToken({
from: r.session.id,
to: r.oauthRefreshToken.sessionId,
}),
oauthAccessTokens: r.many.oauthAccessToken({
from: r.session.id,
to: r.oauthAccessToken.sessionId,
}),
},
account: {
user: r.one.user({
@@ -326,5 +485,53 @@ export const relations = defineRelations(
to: r.user.id,
}),
},
oauthClient: {
user: r.one.user({
from: r.oauthClient.userId,
to: r.user.id,
}),
oauthRefreshTokens: r.many.oauthRefreshToken({
from: r.oauthClient.clientId,
to: r.oauthRefreshToken.clientId,
}),
oauthAccessTokens: r.many.oauthAccessToken({
from: r.oauthClient.clientId,
to: r.oauthAccessToken.clientId,
}),
oauthConsents: r.many.oauthConsent({
from: r.oauthClient.clientId,
to: r.oauthConsent.clientId,
}),
},
oauthRefreshToken: {
user: r.one.user({
from: r.oauthRefreshToken.userId,
to: r.user.id,
}),
session: r.one.session({
from: r.oauthRefreshToken.sessionId,
to: r.session.id,
}),
},
oauthAccessToken: {
user: r.one.user({
from: r.oauthAccessToken.userId,
to: r.user.id,
}),
session: r.one.session({
from: r.oauthAccessToken.sessionId,
to: r.session.id,
}),
refreshToken: r.one.oauthRefreshToken({
from: r.oauthAccessToken.refreshId,
to: r.oauthRefreshToken.id,
}),
},
oauthConsent: {
user: r.one.user({
from: r.oauthConsent.userId,
to: r.user.id,
}),
},
}),
);
-29
View File
@@ -1,29 +0,0 @@
import { describe, expect, it } from "vitest";
import { createJobSearchProvider } from "./factory";
import { JSearchProvider } from "./providers/jsearch";
describe("createJobSearchProvider", () => {
it("should return a JSearchProvider instance", () => {
const provider = createJobSearchProvider("test-api-key");
expect(provider).toBeInstanceOf(JSearchProvider);
});
it("should create provider with correct API key", async () => {
const provider = createJobSearchProvider("my-secret-key");
// Provider should have the API key (indirectly verified by checking it's a JSearchProvider)
expect(provider).toBeInstanceOf(JSearchProvider);
});
it("should have all required JobSearchProvider methods", () => {
const provider = createJobSearchProvider("test-api-key");
expect(provider).toHaveProperty("search");
expect(provider).toHaveProperty("testConnection");
expect(typeof provider.search).toBe("function");
expect(typeof provider.testConnection).toBe("function");
});
});
@@ -1,4 +1,4 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { afterEach, beforeEach, describe, expect, it, vi } from "vite-plus/test";
import { JSearchProvider } from "./jsearch";
+19 -2
View File
@@ -7,7 +7,7 @@ import type { Locale } from "@/utils/locale";
import { env } from "@/utils/env";
import { auth } from "../auth/config";
import { auth, verifyOAuthToken } from "../auth/config";
import { db } from "../drizzle/client";
import { user } from "../drizzle/schema";
@@ -16,6 +16,21 @@ interface ORPCContext {
reqHeaders?: Headers;
}
async function getUserFromBearerToken(headers: Headers): Promise<User | null> {
try {
const authHeader = headers.get("authorization");
if (!authHeader?.startsWith("Bearer ")) return null;
const payload = await verifyOAuthToken(authHeader.slice(7));
if (!payload?.sub) return null;
const [userResult] = await db.select().from(user).where(eq(user.id, payload.sub)).limit(1);
return userResult ?? null;
} catch {
return null;
}
}
async function getUserFromHeaders(headers: Headers): Promise<User | null> {
try {
const result = await auth.api.getSession({ headers });
@@ -47,7 +62,9 @@ export const publicProcedure = base.use(async ({ context, next }) => {
const headers = context.reqHeaders ?? new Headers();
const apiKey = headers.get("x-api-key");
const user = apiKey ? await getUserFromApiKey(apiKey) : await getUserFromHeaders(headers);
const user = apiKey
? await getUserFromApiKey(apiKey)
: ((await getUserFromBearerToken(headers)) ?? (await getUserFromHeaders(headers)));
return next({
context: {
+1 -1
View File
@@ -1,4 +1,4 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vite-plus/test";
import type { JobResult, PostFilterOptions, RapidApiQuota } from "@/schema/jobs";
+8
View File
@@ -426,6 +426,14 @@ export const resumeService = {
},
delete: async (input: { id: string; userId: string }) => {
const [resume] = await db
.select({ isLocked: schema.resume.isLocked })
.from(schema.resume)
.where(and(eq(schema.resume.id, input.id), eq(schema.resume.userId, input.userId)));
if (!resume) throw new ORPCError("NOT_FOUND");
if (resume.isLocked) throw new ORPCError("RESUME_LOCKED");
const storageService = getStorageService();
const deleteResumePromise = db
+159
View File
@@ -23,9 +23,13 @@ import { Route as AuthVerify2faRouteImport } from "./routes/auth/verify-2fa";
import { Route as AuthResumePasswordRouteImport } from "./routes/auth/resume-password";
import { Route as AuthResetPasswordRouteImport } from "./routes/auth/reset-password";
import { Route as AuthRegisterRouteImport } from "./routes/auth/register";
import { Route as AuthOauthRouteImport } from "./routes/auth/oauth";
import { Route as AuthLoginRouteImport } from "./routes/auth/login";
import { Route as AuthForgotPasswordRouteImport } from "./routes/auth/forgot-password";
import { Route as ApiHealthRouteImport } from "./routes/api/health";
import { Route as DotwellKnownOpenidConfigurationRouteImport } from "./routes/[.]well-known/openid-configuration";
import { Route as DotwellKnownOauthProtectedResourceRouteImport } from "./routes/[.]well-known/oauth-protected-resource";
import { Route as DotwellKnownOauthAuthorizationServerRouteImport } from "./routes/[.]well-known/oauth-authorization-server";
import { Route as UsernameSlugRouteImport } from "./routes/$username/$slug";
import { Route as BuilderResumeIdRouteRouteImport } from "./routes/builder/$resumeId/route";
import { Route as DashboardResumesIndexRouteImport } from "./routes/dashboard/resumes/index";
@@ -41,6 +45,8 @@ import { Route as DashboardSettingsAiRouteImport } from "./routes/dashboard/sett
import { Route as ApiRpcSplatRouteImport } from "./routes/api/rpc.$";
import { Route as ApiOpenapiSplatRouteImport } from "./routes/api/openapi.$";
import { Route as ApiAuthSplatRouteImport } from "./routes/api/auth.$";
import { Route as DotwellKnownOauthProtectedResourceSplatRouteImport } from "./routes/[.]well-known/oauth-protected-resource.$";
import { Route as DotwellKnownOauthAuthorizationServerSplatRouteImport } from "./routes/[.]well-known/oauth-authorization-server.$";
import { Route as DashboardSettingsAuthenticationIndexRouteImport } from "./routes/dashboard/settings/authentication/index";
const SchemaDotjsonRoute = SchemaDotjsonRouteImport.update({
@@ -112,6 +118,11 @@ const AuthRegisterRoute = AuthRegisterRouteImport.update({
path: "/register",
getParentRoute: () => AuthRouteRoute,
} as any);
const AuthOauthRoute = AuthOauthRouteImport.update({
id: "/oauth",
path: "/oauth",
getParentRoute: () => AuthRouteRoute,
} as any);
const AuthLoginRoute = AuthLoginRouteImport.update({
id: "/login",
path: "/login",
@@ -127,6 +138,24 @@ const ApiHealthRoute = ApiHealthRouteImport.update({
path: "/api/health",
getParentRoute: () => rootRouteImport,
} as any);
const DotwellKnownOpenidConfigurationRoute =
DotwellKnownOpenidConfigurationRouteImport.update({
id: "/.well-known/openid-configuration",
path: "/.well-known/openid-configuration",
getParentRoute: () => rootRouteImport,
} as any);
const DotwellKnownOauthProtectedResourceRoute =
DotwellKnownOauthProtectedResourceRouteImport.update({
id: "/.well-known/oauth-protected-resource",
path: "/.well-known/oauth-protected-resource",
getParentRoute: () => rootRouteImport,
} as any);
const DotwellKnownOauthAuthorizationServerRoute =
DotwellKnownOauthAuthorizationServerRouteImport.update({
id: "/.well-known/oauth-authorization-server",
path: "/.well-known/oauth-authorization-server",
getParentRoute: () => rootRouteImport,
} as any);
const UsernameSlugRoute = UsernameSlugRouteImport.update({
id: "/$username/$slug",
path: "/$username/$slug",
@@ -207,6 +236,18 @@ const ApiAuthSplatRoute = ApiAuthSplatRouteImport.update({
path: "/api/auth/$",
getParentRoute: () => rootRouteImport,
} as any);
const DotwellKnownOauthProtectedResourceSplatRoute =
DotwellKnownOauthProtectedResourceSplatRouteImport.update({
id: "/$",
path: "/$",
getParentRoute: () => DotwellKnownOauthProtectedResourceRoute,
} as any);
const DotwellKnownOauthAuthorizationServerSplatRoute =
DotwellKnownOauthAuthorizationServerSplatRouteImport.update({
id: "/$",
path: "/$",
getParentRoute: () => DotwellKnownOauthAuthorizationServerRoute,
} as any);
const DashboardSettingsAuthenticationIndexRoute =
DashboardSettingsAuthenticationIndexRouteImport.update({
id: "/settings/authentication/",
@@ -221,9 +262,13 @@ export interface FileRoutesByFullPath {
"/schema.json": typeof SchemaDotjsonRoute;
"/builder/$resumeId": typeof BuilderResumeIdRouteRouteWithChildren;
"/$username/$slug": typeof UsernameSlugRoute;
"/.well-known/oauth-authorization-server": typeof DotwellKnownOauthAuthorizationServerRouteWithChildren;
"/.well-known/oauth-protected-resource": typeof DotwellKnownOauthProtectedResourceRouteWithChildren;
"/.well-known/openid-configuration": typeof DotwellKnownOpenidConfigurationRoute;
"/api/health": typeof ApiHealthRoute;
"/auth/forgot-password": typeof AuthForgotPasswordRoute;
"/auth/login": typeof AuthLoginRoute;
"/auth/oauth": typeof AuthOauthRoute;
"/auth/register": typeof AuthRegisterRoute;
"/auth/reset-password": typeof AuthResetPasswordRoute;
"/auth/resume-password": typeof AuthResumePasswordRoute;
@@ -233,6 +278,8 @@ export interface FileRoutesByFullPath {
"/auth/": typeof AuthIndexRoute;
"/dashboard/": typeof DashboardIndexRoute;
"/mcp/": typeof McpIndexRoute;
"/.well-known/oauth-authorization-server/$": typeof DotwellKnownOauthAuthorizationServerSplatRoute;
"/.well-known/oauth-protected-resource/$": typeof DotwellKnownOauthProtectedResourceSplatRoute;
"/api/auth/$": typeof ApiAuthSplatRoute;
"/api/openapi/$": typeof ApiOpenapiSplatRoute;
"/api/rpc/$": typeof ApiRpcSplatRoute;
@@ -251,9 +298,13 @@ export interface FileRoutesByFullPath {
export interface FileRoutesByTo {
"/schema.json": typeof SchemaDotjsonRoute;
"/$username/$slug": typeof UsernameSlugRoute;
"/.well-known/oauth-authorization-server": typeof DotwellKnownOauthAuthorizationServerRouteWithChildren;
"/.well-known/oauth-protected-resource": typeof DotwellKnownOauthProtectedResourceRouteWithChildren;
"/.well-known/openid-configuration": typeof DotwellKnownOpenidConfigurationRoute;
"/api/health": typeof ApiHealthRoute;
"/auth/forgot-password": typeof AuthForgotPasswordRoute;
"/auth/login": typeof AuthLoginRoute;
"/auth/oauth": typeof AuthOauthRoute;
"/auth/register": typeof AuthRegisterRoute;
"/auth/reset-password": typeof AuthResetPasswordRoute;
"/auth/resume-password": typeof AuthResumePasswordRoute;
@@ -264,6 +315,8 @@ export interface FileRoutesByTo {
"/auth": typeof AuthIndexRoute;
"/dashboard": typeof DashboardIndexRoute;
"/mcp": typeof McpIndexRoute;
"/.well-known/oauth-authorization-server/$": typeof DotwellKnownOauthAuthorizationServerSplatRoute;
"/.well-known/oauth-protected-resource/$": typeof DotwellKnownOauthProtectedResourceSplatRoute;
"/api/auth/$": typeof ApiAuthSplatRoute;
"/api/openapi/$": typeof ApiOpenapiSplatRoute;
"/api/rpc/$": typeof ApiRpcSplatRoute;
@@ -287,9 +340,13 @@ export interface FileRoutesById {
"/schema.json": typeof SchemaDotjsonRoute;
"/builder/$resumeId": typeof BuilderResumeIdRouteRouteWithChildren;
"/$username/$slug": typeof UsernameSlugRoute;
"/.well-known/oauth-authorization-server": typeof DotwellKnownOauthAuthorizationServerRouteWithChildren;
"/.well-known/oauth-protected-resource": typeof DotwellKnownOauthProtectedResourceRouteWithChildren;
"/.well-known/openid-configuration": typeof DotwellKnownOpenidConfigurationRoute;
"/api/health": typeof ApiHealthRoute;
"/auth/forgot-password": typeof AuthForgotPasswordRoute;
"/auth/login": typeof AuthLoginRoute;
"/auth/oauth": typeof AuthOauthRoute;
"/auth/register": typeof AuthRegisterRoute;
"/auth/reset-password": typeof AuthResetPasswordRoute;
"/auth/resume-password": typeof AuthResumePasswordRoute;
@@ -300,6 +357,8 @@ export interface FileRoutesById {
"/auth/": typeof AuthIndexRoute;
"/dashboard/": typeof DashboardIndexRoute;
"/mcp/": typeof McpIndexRoute;
"/.well-known/oauth-authorization-server/$": typeof DotwellKnownOauthAuthorizationServerSplatRoute;
"/.well-known/oauth-protected-resource/$": typeof DotwellKnownOauthProtectedResourceSplatRoute;
"/api/auth/$": typeof ApiAuthSplatRoute;
"/api/openapi/$": typeof ApiOpenapiSplatRoute;
"/api/rpc/$": typeof ApiRpcSplatRoute;
@@ -324,9 +383,13 @@ export interface FileRouteTypes {
| "/schema.json"
| "/builder/$resumeId"
| "/$username/$slug"
| "/.well-known/oauth-authorization-server"
| "/.well-known/oauth-protected-resource"
| "/.well-known/openid-configuration"
| "/api/health"
| "/auth/forgot-password"
| "/auth/login"
| "/auth/oauth"
| "/auth/register"
| "/auth/reset-password"
| "/auth/resume-password"
@@ -336,6 +399,8 @@ export interface FileRouteTypes {
| "/auth/"
| "/dashboard/"
| "/mcp/"
| "/.well-known/oauth-authorization-server/$"
| "/.well-known/oauth-protected-resource/$"
| "/api/auth/$"
| "/api/openapi/$"
| "/api/rpc/$"
@@ -354,9 +419,13 @@ export interface FileRouteTypes {
to:
| "/schema.json"
| "/$username/$slug"
| "/.well-known/oauth-authorization-server"
| "/.well-known/oauth-protected-resource"
| "/.well-known/openid-configuration"
| "/api/health"
| "/auth/forgot-password"
| "/auth/login"
| "/auth/oauth"
| "/auth/register"
| "/auth/reset-password"
| "/auth/resume-password"
@@ -367,6 +436,8 @@ export interface FileRouteTypes {
| "/auth"
| "/dashboard"
| "/mcp"
| "/.well-known/oauth-authorization-server/$"
| "/.well-known/oauth-protected-resource/$"
| "/api/auth/$"
| "/api/openapi/$"
| "/api/rpc/$"
@@ -389,9 +460,13 @@ export interface FileRouteTypes {
| "/schema.json"
| "/builder/$resumeId"
| "/$username/$slug"
| "/.well-known/oauth-authorization-server"
| "/.well-known/oauth-protected-resource"
| "/.well-known/openid-configuration"
| "/api/health"
| "/auth/forgot-password"
| "/auth/login"
| "/auth/oauth"
| "/auth/register"
| "/auth/reset-password"
| "/auth/resume-password"
@@ -402,6 +477,8 @@ export interface FileRouteTypes {
| "/auth/"
| "/dashboard/"
| "/mcp/"
| "/.well-known/oauth-authorization-server/$"
| "/.well-known/oauth-protected-resource/$"
| "/api/auth/$"
| "/api/openapi/$"
| "/api/rpc/$"
@@ -425,6 +502,9 @@ export interface RootRouteChildren {
SchemaDotjsonRoute: typeof SchemaDotjsonRoute;
BuilderResumeIdRouteRoute: typeof BuilderResumeIdRouteRouteWithChildren;
UsernameSlugRoute: typeof UsernameSlugRoute;
DotwellKnownOauthAuthorizationServerRoute: typeof DotwellKnownOauthAuthorizationServerRouteWithChildren;
DotwellKnownOauthProtectedResourceRoute: typeof DotwellKnownOauthProtectedResourceRouteWithChildren;
DotwellKnownOpenidConfigurationRoute: typeof DotwellKnownOpenidConfigurationRoute;
ApiHealthRoute: typeof ApiHealthRoute;
PrinterResumeIdRoute: typeof PrinterResumeIdRoute;
McpIndexRoute: typeof McpIndexRoute;
@@ -534,6 +614,13 @@ declare module "@tanstack/react-router" {
preLoaderRoute: typeof AuthRegisterRouteImport;
parentRoute: typeof AuthRouteRoute;
};
"/auth/oauth": {
id: "/auth/oauth";
path: "/oauth";
fullPath: "/auth/oauth";
preLoaderRoute: typeof AuthOauthRouteImport;
parentRoute: typeof AuthRouteRoute;
};
"/auth/login": {
id: "/auth/login";
path: "/login";
@@ -555,6 +642,27 @@ declare module "@tanstack/react-router" {
preLoaderRoute: typeof ApiHealthRouteImport;
parentRoute: typeof rootRouteImport;
};
"/.well-known/openid-configuration": {
id: "/.well-known/openid-configuration";
path: "/.well-known/openid-configuration";
fullPath: "/.well-known/openid-configuration";
preLoaderRoute: typeof DotwellKnownOpenidConfigurationRouteImport;
parentRoute: typeof rootRouteImport;
};
"/.well-known/oauth-protected-resource": {
id: "/.well-known/oauth-protected-resource";
path: "/.well-known/oauth-protected-resource";
fullPath: "/.well-known/oauth-protected-resource";
preLoaderRoute: typeof DotwellKnownOauthProtectedResourceRouteImport;
parentRoute: typeof rootRouteImport;
};
"/.well-known/oauth-authorization-server": {
id: "/.well-known/oauth-authorization-server";
path: "/.well-known/oauth-authorization-server";
fullPath: "/.well-known/oauth-authorization-server";
preLoaderRoute: typeof DotwellKnownOauthAuthorizationServerRouteImport;
parentRoute: typeof rootRouteImport;
};
"/$username/$slug": {
id: "/$username/$slug";
path: "/$username/$slug";
@@ -660,6 +768,20 @@ declare module "@tanstack/react-router" {
preLoaderRoute: typeof ApiAuthSplatRouteImport;
parentRoute: typeof rootRouteImport;
};
"/.well-known/oauth-protected-resource/$": {
id: "/.well-known/oauth-protected-resource/$";
path: "/$";
fullPath: "/.well-known/oauth-protected-resource/$";
preLoaderRoute: typeof DotwellKnownOauthProtectedResourceSplatRouteImport;
parentRoute: typeof DotwellKnownOauthProtectedResourceRoute;
};
"/.well-known/oauth-authorization-server/$": {
id: "/.well-known/oauth-authorization-server/$";
path: "/$";
fullPath: "/.well-known/oauth-authorization-server/$";
preLoaderRoute: typeof DotwellKnownOauthAuthorizationServerSplatRouteImport;
parentRoute: typeof DotwellKnownOauthAuthorizationServerRoute;
};
"/dashboard/settings/authentication/": {
id: "/dashboard/settings/authentication/";
path: "/settings/authentication";
@@ -685,6 +807,7 @@ const HomeRouteRouteWithChildren = HomeRouteRoute._addFileChildren(
interface AuthRouteRouteChildren {
AuthForgotPasswordRoute: typeof AuthForgotPasswordRoute;
AuthLoginRoute: typeof AuthLoginRoute;
AuthOauthRoute: typeof AuthOauthRoute;
AuthRegisterRoute: typeof AuthRegisterRoute;
AuthResetPasswordRoute: typeof AuthResetPasswordRoute;
AuthResumePasswordRoute: typeof AuthResumePasswordRoute;
@@ -696,6 +819,7 @@ interface AuthRouteRouteChildren {
const AuthRouteRouteChildren: AuthRouteRouteChildren = {
AuthForgotPasswordRoute: AuthForgotPasswordRoute,
AuthLoginRoute: AuthLoginRoute,
AuthOauthRoute: AuthOauthRoute,
AuthRegisterRoute: AuthRegisterRoute,
AuthResetPasswordRoute: AuthResetPasswordRoute,
AuthResumePasswordRoute: AuthResumePasswordRoute,
@@ -750,6 +874,36 @@ const BuilderResumeIdRouteRouteChildren: BuilderResumeIdRouteRouteChildren = {
const BuilderResumeIdRouteRouteWithChildren =
BuilderResumeIdRouteRoute._addFileChildren(BuilderResumeIdRouteRouteChildren);
interface DotwellKnownOauthAuthorizationServerRouteChildren {
DotwellKnownOauthAuthorizationServerSplatRoute: typeof DotwellKnownOauthAuthorizationServerSplatRoute;
}
const DotwellKnownOauthAuthorizationServerRouteChildren: DotwellKnownOauthAuthorizationServerRouteChildren =
{
DotwellKnownOauthAuthorizationServerSplatRoute:
DotwellKnownOauthAuthorizationServerSplatRoute,
};
const DotwellKnownOauthAuthorizationServerRouteWithChildren =
DotwellKnownOauthAuthorizationServerRoute._addFileChildren(
DotwellKnownOauthAuthorizationServerRouteChildren,
);
interface DotwellKnownOauthProtectedResourceRouteChildren {
DotwellKnownOauthProtectedResourceSplatRoute: typeof DotwellKnownOauthProtectedResourceSplatRoute;
}
const DotwellKnownOauthProtectedResourceRouteChildren: DotwellKnownOauthProtectedResourceRouteChildren =
{
DotwellKnownOauthProtectedResourceSplatRoute:
DotwellKnownOauthProtectedResourceSplatRoute,
};
const DotwellKnownOauthProtectedResourceRouteWithChildren =
DotwellKnownOauthProtectedResourceRoute._addFileChildren(
DotwellKnownOauthProtectedResourceRouteChildren,
);
const rootRouteChildren: RootRouteChildren = {
HomeRouteRoute: HomeRouteRouteWithChildren,
AuthRouteRoute: AuthRouteRouteWithChildren,
@@ -757,6 +911,11 @@ const rootRouteChildren: RootRouteChildren = {
SchemaDotjsonRoute: SchemaDotjsonRoute,
BuilderResumeIdRouteRoute: BuilderResumeIdRouteRouteWithChildren,
UsernameSlugRoute: UsernameSlugRoute,
DotwellKnownOauthAuthorizationServerRoute:
DotwellKnownOauthAuthorizationServerRouteWithChildren,
DotwellKnownOauthProtectedResourceRoute:
DotwellKnownOauthProtectedResourceRouteWithChildren,
DotwellKnownOpenidConfigurationRoute: DotwellKnownOpenidConfigurationRoute,
ApiHealthRoute: ApiHealthRoute,
PrinterResumeIdRoute: PrinterResumeIdRoute,
McpIndexRoute: McpIndexRoute,
-3
View File
@@ -21,9 +21,6 @@ type LoaderData = Omit<RouterOutput["resume"]["getBySlug"], "data"> & { data: Re
export const Route = createFileRoute("/$username/$slug")({
component: RouteComponent,
loader: async ({ context, params: { username, slug } }) => {
// Ignore .well-known requests
if (username === ".well-known") throw notFound();
const resume = await context.queryClient.ensureQueryData(
orpc.resume.getBySlug.queryOptions({ input: { username, slug } }),
);
@@ -0,0 +1,14 @@
import { oauthProviderAuthServerMetadata } from "@better-auth/oauth-provider";
import { createFileRoute } from "@tanstack/react-router";
import { auth } from "@/integrations/auth/config";
const handler = oauthProviderAuthServerMetadata(auth);
export const Route = createFileRoute("/.well-known/oauth-authorization-server/$")({
server: {
handlers: {
GET: ({ request }) => handler(request),
},
},
});
@@ -0,0 +1,14 @@
import { oauthProviderAuthServerMetadata } from "@better-auth/oauth-provider";
import { createFileRoute } from "@tanstack/react-router";
import { auth } from "@/integrations/auth/config";
const handler = oauthProviderAuthServerMetadata(auth);
export const Route = createFileRoute("/.well-known/oauth-authorization-server")({
server: {
handlers: {
GET: ({ request }) => handler(request),
},
},
});
@@ -0,0 +1,25 @@
import { createFileRoute } from "@tanstack/react-router";
import { authClient } from "@/integrations/auth/client";
import { authBaseUrl } from "@/integrations/auth/config";
export const Route = createFileRoute("/.well-known/oauth-protected-resource/$")({
server: {
handlers: {
GET: async () => {
const metadata = await authClient.getProtectedResourceMetadata({
resource: authBaseUrl,
bearer_methods_supported: ["header"],
authorization_servers: [authBaseUrl, `${authBaseUrl}/api/auth`],
});
return Response.json(metadata, {
headers: {
"Content-Type": "application/json",
"Cache-Control": "public, max-age=15, stale-while-revalidate=15, stale-if-error=86400",
},
});
},
},
},
});
@@ -0,0 +1,25 @@
import { createFileRoute } from "@tanstack/react-router";
import { authClient } from "@/integrations/auth/client";
import { authBaseUrl } from "@/integrations/auth/config";
export const Route = createFileRoute("/.well-known/oauth-protected-resource")({
server: {
handlers: {
GET: async () => {
const metadata = await authClient.getProtectedResourceMetadata({
resource: authBaseUrl,
bearer_methods_supported: ["header"],
authorization_servers: [authBaseUrl, `${authBaseUrl}/api/auth`],
});
return Response.json(metadata, {
headers: {
"Content-Type": "application/json",
"Cache-Control": "public, max-age=15, stale-while-revalidate=15, stale-if-error=86400",
},
});
},
},
},
});
@@ -0,0 +1,14 @@
import { oauthProviderOpenIdConfigMetadata } from "@better-auth/oauth-provider";
import { createFileRoute } from "@tanstack/react-router";
import { auth } from "@/integrations/auth/config";
const handler = oauthProviderOpenIdConfigMetadata(auth);
export const Route = createFileRoute("/.well-known/openid-configuration")({
server: {
handlers: {
GET: ({ request }) => handler(request),
},
},
});
+76 -1
View File
@@ -2,14 +2,89 @@ import { createFileRoute } from "@tanstack/react-router";
import { auth } from "@/integrations/auth/config";
function sanitizeOAuthAuthorizeRequest(request: Request): Request {
if (request.method !== "GET") return request;
const url = new URL(request.url);
if (!url.pathname.endsWith("/oauth2/authorize")) return request;
const sanitizeValue = (value: string) =>
value
.replace(/[\r\n\t]+/g, " ")
.replace(/\s+/g, " ")
.trim();
const sanitizeParam = (key: string) => {
const value = url.searchParams.get(key);
if (!value) return;
url.searchParams.set(key, sanitizeValue(value));
};
sanitizeParam("prompt");
sanitizeParam("redirect_uri");
sanitizeParam("client_id");
sanitizeParam("code_challenge");
sanitizeParam("code_challenge_method");
sanitizeParam("response_type");
sanitizeParam("scope");
sanitizeParam("state");
sanitizeParam("resource");
const redirectUri = url.searchParams.get("redirect_uri");
if (redirectUri && !URL.canParse(redirectUri)) {
try {
const decodedRedirectUri = decodeURIComponent(redirectUri);
if (URL.canParse(decodedRedirectUri)) {
url.searchParams.set("redirect_uri", decodedRedirectUri);
}
} catch {
// Ignore malformed encoded values and let Better Auth validation handle them.
}
}
if (url.toString() === request.url) return request;
return new Request(url, request);
}
async function defaultPublicClientRegistration(request: Request): Promise<Request> {
if (request.method !== "POST") return request;
const url = new URL(request.url);
if (!url.pathname.endsWith("/oauth2/register")) return request;
const cloned = request.clone();
let body: Record<string, unknown>;
try {
body = await cloned.json();
} catch {
return request;
}
// Claude.ai sends token_endpoint_auth_method: "client_secret_post" without a
// client_secret, causing Better Auth to require authentication for what is
// effectively a public client. Force to "none" for unauthenticated registrations.
if (!request.headers.get("authorization")) {
body.token_endpoint_auth_method = "none";
}
return new Request(url, {
method: request.method,
headers: request.headers,
body: JSON.stringify(body),
});
}
async function handler({ request }: { request: Request }) {
const sanitizedRequest = sanitizeOAuthAuthorizeRequest(request);
const finalRequest = await defaultPublicClientRegistration(sanitizedRequest);
if (request.method === "GET" && request.url.endsWith("/spec.json")) {
const spec = await auth.api.generateOpenAPISchema();
return Response.json(spec);
}
return auth.handler(request);
return auth.handler(finalRequest);
}
export const Route = createFileRoute("/api/auth/$")({
+103
View File
@@ -0,0 +1,103 @@
import { createFileRoute } from "@tanstack/react-router";
import { eq } from "drizzle-orm";
import crypto from "node:crypto";
import { auth, authBaseUrl } from "@/integrations/auth/config";
import { db } from "@/integrations/drizzle/client";
import { oauthClient, verification } from "@/integrations/drizzle/schema";
import { generateId } from "@/utils/string";
function generateCode() {
return crypto.randomBytes(32).toString("base64url");
}
function hashCode(code: string) {
return crypto.createHash("sha256").update(code).digest("base64url");
}
export const Route = createFileRoute("/auth/oauth")({
server: {
handlers: {
GET: async ({ request }) => {
const session = await auth.api.getSession({ headers: request.headers });
const url = new URL(request.url);
if (session?.user) {
const clientId = url.searchParams.get("client_id");
const redirectUri = url.searchParams.get("redirect_uri");
const state = url.searchParams.get("state");
const scope = url.searchParams.get("scope");
const codeChallenge = url.searchParams.get("code_challenge");
const codeChallengeMethod = url.searchParams.get("code_challenge_method");
if (!clientId || !redirectUri) {
return Response.json({ error: "missing client_id or redirect_uri" }, { status: 400 });
}
const [client] = await db.select().from(oauthClient).where(eq(oauthClient.clientId, clientId)).limit(1);
if (!client) {
return Response.json({ error: "invalid client" }, { status: 400 });
}
if (!client.redirectUris.includes(redirectUri)) {
return Response.json({ error: "invalid redirect_uri" }, { status: 400 });
}
const code = generateCode();
const hashedCode = hashCode(code);
const now = new Date();
const expiresAt = new Date(now.getTime() + 600_000); // 10 min
await db.insert(verification).values({
id: generateId(),
identifier: hashedCode,
value: JSON.stringify({
type: "authorization_code",
query: {
response_type: "code",
client_id: clientId,
redirect_uri: redirectUri,
scope,
state,
code_challenge: codeChallenge,
code_challenge_method: codeChallengeMethod,
},
userId: session.user.id,
sessionId: session.session.id,
authTime: new Date(session.session.createdAt).getTime(),
}),
expiresAt,
createdAt: now,
updatedAt: now,
});
const callbackUrl = new URL(redirectUri);
callbackUrl.searchParams.set("code", code);
if (state) callbackUrl.searchParams.set("state", state);
callbackUrl.searchParams.set("iss", `${authBaseUrl}/api/auth`);
return new Response(null, {
status: 302,
headers: { Location: callbackUrl.toString() },
});
}
// Not logged in — redirect to the real login page with a callback
const loginUrl = new URL("/auth/login", url.origin);
const oauthParams = new URLSearchParams();
for (const [key, value] of url.searchParams) {
if (!["exp", "sig"].includes(key)) {
oauthParams.set(key, value);
}
}
loginUrl.searchParams.set("callbackURL", `/auth/oauth?${oauthParams.toString()}`);
return new Response(null, {
status: 302,
headers: { Location: loginUrl.toString() },
});
},
},
},
});
@@ -21,7 +21,6 @@ import { useControls } from "react-zoom-pan-pinch";
import { toast } from "sonner";
import { useCopyToClipboard } from "usehooks-ts";
import { AIChat } from "@/components/ai/chat";
import { useTemporalStore } from "@/components/resume/store/resume";
import { Button } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
@@ -138,7 +137,6 @@ export function BuilderDock() {
<DockIcon icon={MagnifyingGlassMinusIcon} title={t`Zoom out`} onClick={() => zoomOut(0.1)} />
<DockIcon icon={CubeFocusIcon} title={t`Center view`} onClick={() => centerView()} />
<div className="mx-1 h-8 w-px bg-border" />
<AIChat />
<DockIcon icon={LinkSimpleIcon} title={t`Copy URL`} onClick={() => onCopyUrl()} />
<DockIcon icon={FileJsIcon} title={t`Download JSON`} onClick={() => onDownloadJSON()} />
<DockIcon icon={FileDocIcon} title={t`Download DOCX`} onClick={() => onDownloadDOCX()} />
@@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest";
import { describe, expect, it } from "vite-plus/test";
import {
buildPostFilters,
+49 -2
View File
@@ -2,6 +2,8 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
import { createFileRoute } from "@tanstack/react-router";
import { auth, authBaseUrl, verifyOAuthToken } from "@/integrations/auth/config";
import { registerPrompts } from "./-helpers/prompts";
import { registerResources } from "./-helpers/resources";
import { registerTools } from "./-helpers/tools";
@@ -35,13 +37,46 @@ function createMcpServer() {
return server;
}
class AuthError extends Error {
constructor() {
super("Unauthorized");
}
}
async function authenticateRequest(request: Request): Promise<void> {
// Try OAuth Bearer token first (for claude.ai and other MCP OAuth clients)
const authHeader = request.headers.get("authorization");
if (authHeader?.startsWith("Bearer ")) {
try {
const payload = await verifyOAuthToken(authHeader.slice(7));
if (payload?.sub) return;
} catch {
// Invalid or expired token (e.g. JWKS key mismatch) — fall through to AuthError
}
}
// Fall back to API key authentication
const apiKey = request.headers.get("x-api-key");
if (apiKey) {
try {
const result = await auth.api.verifyApiKey({ body: { key: apiKey } });
if (result.valid) return;
} catch {
// Invalid or malformed key — fall through to AuthError
}
}
throw new AuthError();
}
export const Route = createFileRoute("/mcp/")({
server: {
handlers: {
ANY: async ({ request }) => {
try {
const apiKey = request.headers.get("x-api-key");
if (!apiKey) throw new Error("Unauthorized");
await authenticateRequest(request);
const server = createMcpServer();
const transport = new WebStandardStreamableHTTPServerTransport({
@@ -52,6 +87,18 @@ export const Route = createFileRoute("/mcp/")({
return await transport.handleRequest(request);
} catch (error) {
if (error instanceof AuthError) {
return Response.json(
{ id: null, jsonrpc: "2.0", error: { code: -32603, message: "Unauthorized" } },
{
status: 401,
headers: {
"WWW-Authenticate": `Bearer resource_metadata="${authBaseUrl}/.well-known/oauth-protected-resource"`,
},
},
);
}
console.error("[MCP]", error);
return Response.json({
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest";
import { describe, expect, it } from "vite-plus/test";
import {
applyOptionSchema,
+41
View File
@@ -0,0 +1,41 @@
import { describe, expect, it } from "vite-plus/test";
import { parseColorString } from "./color";
describe("parseColorString", () => {
it("should parse a 6-digit hex color", () => {
expect(parseColorString("#ff8800")).toEqual({ r: 255, g: 136, b: 0, a: 1 });
});
it("should parse a 3-digit hex color", () => {
expect(parseColorString("#f80")).toEqual({ r: 255, g: 136, b: 0, a: 1 });
});
it("should be case-insensitive for hex", () => {
expect(parseColorString("#FF8800")).toEqual(parseColorString("#ff8800"));
});
it("should parse rgb()", () => {
expect(parseColorString("rgb(10, 20, 30)")).toEqual({ r: 10, g: 20, b: 30, a: 1 });
});
it("should parse rgba() with alpha", () => {
expect(parseColorString("rgba(10, 20, 30, 0.5)")).toEqual({ r: 10, g: 20, b: 30, a: 0.5 });
});
it("should handle whitespace around the value", () => {
expect(parseColorString(" #000000 ")).toEqual({ r: 0, g: 0, b: 0, a: 1 });
});
it("should return null for invalid input", () => {
expect(parseColorString("not-a-color")).toBeNull();
});
it("should return null for empty string", () => {
expect(parseColorString("")).toBeNull();
});
it("should return null for incomplete hex", () => {
expect(parseColorString("#ff")).toBeNull();
});
});
+6 -14
View File
@@ -1,31 +1,23 @@
import { describe, expect, it } from "vitest";
import { describe, expect, it } from "vite-plus/test";
import { generateFilename } from "./file";
describe("generateFilename", () => {
it("should return name with extension", () => {
it("should slugify the prefix and append the extension", () => {
expect(generateFilename("My Resume", "docx")).toBe("my-resume.docx");
});
it("should return name without extension when none provided", () => {
it("should return slugified name without extension when none provided", () => {
expect(generateFilename("My Resume")).toBe("my-resume");
});
it("should preserve the exact resume name with special characters", () => {
expect(generateFilename("John Doe - CS Base - Program Coordinator", "docx")).toBe(
"john-doe-cs-base-program-coordinator.docx",
);
});
it("should work with pdf extension", () => {
it("should handle special characters in the prefix", () => {
expect(generateFilename("John Doe - CS Base - Program Coordinator", "pdf")).toBe(
"john-doe-cs-base-program-coordinator.pdf",
);
});
it("should work with json extension", () => {
expect(generateFilename("John Doe - CS Base - Program Coordinator", "json")).toBe(
"john-doe-cs-base-program-coordinator.json",
);
it("should handle empty prefix", () => {
expect(generateFilename("", "pdf")).toBe(".pdf");
});
});
+38
View File
@@ -0,0 +1,38 @@
import { describe, expect, it, vi } from "vite-plus/test";
// Mock @lingui/core/macro since the `msg` macro requires babel transformation
vi.mock("@lingui/core/macro", () => ({
msg: (strings: TemplateStringsArray) => ({ id: strings[0] }),
}));
// Import after mock setup
const { isLocale, isRTL } = await import("./locale");
describe("isLocale", () => {
it("should return true for valid locales", () => {
expect(isLocale("en-US")).toBe(true);
expect(isLocale("fr-FR")).toBe(true);
expect(isLocale("zh-CN")).toBe(true);
});
it("should return false for invalid locales", () => {
expect(isLocale("xx-YY")).toBe(false);
expect(isLocale("english")).toBe(false);
expect(isLocale("")).toBe(false);
});
});
describe("isRTL", () => {
it("should return true for RTL languages", () => {
expect(isRTL("ar-SA")).toBe(true);
expect(isRTL("he-IL")).toBe(true);
expect(isRTL("fa-IR")).toBe(true);
expect(isRTL("ur-PK")).toBe(true);
});
it("should return false for LTR languages", () => {
expect(isRTL("en-US")).toBe(false);
expect(isRTL("fr-FR")).toBe(false);
expect(isRTL("zh-CN")).toBe(false);
});
});
+1 -3
View File
@@ -1,7 +1,5 @@
// @vitest-environment jsdom
import { Document } from "docx";
import { describe, expect, it } from "vitest";
import { describe, expect, it } from "vite-plus/test";
import type { ResumeData } from "@/schema/resume/data";
+1 -3
View File
@@ -1,7 +1,5 @@
// @vitest-environment jsdom
import { ExternalHyperlink, Paragraph, TextRun } from "docx";
import { describe, expect, it } from "vitest";
import { describe, expect, it } from "vite-plus/test";
import { htmlToParagraphs } from "./html-to-docx";
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest";
import { describe, expect, it } from "vite-plus/test";
import type { ResumeData } from "@/schema/resume/data";
import type { TailorOutput } from "@/schema/tailor";

Some files were not shown because too many files have changed in this diff Show More