mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-10-03 10:13:47 +10:00
📦 v5.0.7 - Changelog: https://docs.rxresu.me/changelog (#2696)
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
const nextPackages = ["@monaco-editor/react"];
|
||||
|
||||
const betaPackages = ["drizzle-orm", "drizzle-kit", "@better-auth/core", "@better-auth/passkey", "better-auth"];
|
||||
const betaPackages = ["vite", "drizzle-orm", "drizzle-kit", "@better-auth/core", "@better-auth/passkey", "better-auth"];
|
||||
|
||||
/** @type {import('npm-check-updates').RunOptions} */
|
||||
module.exports = {
|
||||
|
||||
Vendored
+7
-7
@@ -10,19 +10,19 @@
|
||||
"*.css": "tailwindcss"
|
||||
},
|
||||
"files.readonlyInclude": {
|
||||
"pnpm-lock.yaml": true,
|
||||
"**/routeTree.gen.ts": true
|
||||
"**/routeTree.gen.ts": true,
|
||||
"pnpm-lock.yaml": true
|
||||
},
|
||||
"files.watcherExclude": {
|
||||
"pnpm-lock.yaml": true,
|
||||
"**/routeTree.gen.ts": true
|
||||
"**/routeTree.gen.ts": true,
|
||||
"pnpm-lock.yaml": true
|
||||
},
|
||||
"i18n-ally.enabledParsers": ["po"],
|
||||
"i18n-ally.localesPaths": ["locales"],
|
||||
"i18n-ally.sourceLanguage": "en-US",
|
||||
"search.exclude": {
|
||||
"pnpm-lock.yaml": true,
|
||||
"**/routeTree.gen.ts": true
|
||||
"**/routeTree.gen.ts": true,
|
||||
"pnpm-lock.yaml": true
|
||||
},
|
||||
"tailwindCSS.classFunctions": ["cn", "cva"],
|
||||
"tailwindCSS.experimental.classRegex": [
|
||||
@@ -31,5 +31,5 @@
|
||||
["cn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
|
||||
],
|
||||
"tailwindCSS.experimental.configFile": "src/styles/globals.css",
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
"typescript.experimental.useTsgo": true
|
||||
}
|
||||
|
||||
+2
-3
@@ -10,9 +10,9 @@
|
||||
"ignoreUnknown": true,
|
||||
"includes": [
|
||||
"**",
|
||||
"!**/docs/spec.json",
|
||||
"!**/webfontlist.json",
|
||||
"!**/schema/schema.json",
|
||||
"!**/docs/spec.json",
|
||||
"!**/src/routeTree.gen.ts"
|
||||
]
|
||||
},
|
||||
@@ -24,8 +24,7 @@
|
||||
"actions": {
|
||||
"recommended": true,
|
||||
"source": {
|
||||
"organizeImports": "on",
|
||||
"useSortedProperties": "on"
|
||||
"organizeImports": "on"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -4,6 +4,19 @@ description: "List of all notable changes and updates to Reactive Resume"
|
||||
rss: true
|
||||
---
|
||||
|
||||
<Update label="v5.0.7" description="9th February 2026">
|
||||
- Introduce a new **MCP (Model Context Protocol) server** that lets you manage and edit resumes from any MCP-compatible AI tool — Claude Desktop, Cursor, Codex, and more. Supports listing, reading, creating, deleting, locking/unlocking, and patching resumes via natural language. [(guide)](/guides/using-the-mcp-server)
|
||||
- Add an **AI Chat** panel to the resume builder, allowing you to modify your resume through conversational AI directly within the editor. The chat uses tool-calling to apply JSON Patch operations to your resume in real-time, with visual feedback for each change.
|
||||
- Add a system prompt and `patch_resume` tool for the AI chat, enabling structured, minimal-diff resume edits following RFC 6902 JSON Patch operations.
|
||||
- Chat history is now persisted per resume in localStorage, so conversations are preserved across sessions.
|
||||
- Fix rendering issues in the Lapras and Onyx resume templates.
|
||||
- Improvements to the Combobox and ScrollArea UI components.
|
||||
- Fix an issue with skills item rendering in the shared resume components.
|
||||
- Update authentication configuration and auth route handling.
|
||||
- Update the JSON Schema to reflect the latest resume data model.
|
||||
- Update dependencies to the latest versions.
|
||||
</Update>
|
||||
|
||||
<Update label="v5.0.6" description="8th February 2026">
|
||||
- Implement Atomic Resume Patching API for fine-grained resume updates, allowing partial, atomic updates to resumes via a new PATCH endpoint. [#2692](https://github.com/amruthpillai/reactive-resume/pull/2692)
|
||||
- The API endpoint `PUT /resume/{id}` now returns the updated resume object instead of void. Also, resume routing/services now use explicit DTOs for input and output schemas. [#2688](https://github.com/amruthpillai/reactive-resume/pull/2688)
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"pages": [
|
||||
"guides/using-the-api",
|
||||
"guides/using-the-patch-api",
|
||||
"guides/using-the-mcp-server",
|
||||
"guides/using-ai",
|
||||
"guides/json-resume-schema"
|
||||
]
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
---
|
||||
title: "Using the MCP Server"
|
||||
description: "Connect Reactive Resume to AI tools like Claude Desktop, Cursor, and Codex using the Model Context Protocol"
|
||||
---
|
||||
|
||||
The Reactive Resume MCP server lets you manage and modify your resumes through any MCP-compatible AI tool — Claude Desktop, Cursor, Codex, and more. It connects to the Reactive Resume API and exposes tools for listing, reading, and patching resumes using natural language.
|
||||
|
||||
## What is MCP?
|
||||
|
||||
The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is a standard that lets LLM-powered tools connect to external services. Instead of being limited to the built-in chat UI, you can use any MCP client to interact with your resumes.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
<Steps>
|
||||
<Step title="Create an API key">
|
||||
Follow the [Using the API](/guides/using-the-api) guide to create an API key in your Reactive Resume dashboard.
|
||||
</Step>
|
||||
|
||||
<Step title="Install Node.js">
|
||||
The MCP server requires [Node.js](https://nodejs.org) version 18 or later.
|
||||
</Step>
|
||||
|
||||
<Step title="Install dependencies">
|
||||
From the Reactive Resume repository root, install dependencies (the MCP server uses the main project's dependencies):
|
||||
|
||||
```bash
|
||||
cd /path/to/reactive-resume
|
||||
pnpm install
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Running the MCP server
|
||||
|
||||
The server is a single TypeScript entry point and is run with **tsx** (no build step). From the repository root:
|
||||
|
||||
```bash
|
||||
npx tsx /path/to/reactive-resume/mcp/index.ts
|
||||
```
|
||||
|
||||
The working directory must be the **repository root** so that `node_modules` (and thus `@modelcontextprotocol/sdk`) is resolved. Configure your MCP client with `cwd` set to the repo path.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Claude Desktop
|
||||
|
||||
Add the following to your `claude_desktop_config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"reactive-resume": {
|
||||
"command": "npx",
|
||||
"args": ["tsx", "/path/to/reactive-resume/mcp/index.ts"],
|
||||
"cwd": "/path/to/reactive-resume",
|
||||
"env": {
|
||||
"REACTIVE_RESUME_API_KEY": "your-api-key",
|
||||
"REACTIVE_RESUME_URL": "https://rxresu.me"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Info>
|
||||
Replace `/path/to/reactive-resume` with the actual path to your cloned repository, and `your-api-key` with the API key you created.
|
||||
</Info>
|
||||
|
||||
### Cursor
|
||||
|
||||
Add the following to `.cursor/mcp.json` in your project or home directory:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"reactive-resume": {
|
||||
"command": "npx",
|
||||
"args": ["tsx", "/path/to/reactive-resume/mcp/index.ts"],
|
||||
"cwd": "/path/to/reactive-resume",
|
||||
"env": {
|
||||
"REACTIVE_RESUME_API_KEY": "your-api-key",
|
||||
"REACTIVE_RESUME_URL": "https://rxresu.me"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Available Tools
|
||||
|
||||
The MCP server exposes three tools:
|
||||
|
||||
| Tool | Description |
|
||||
| --- | --- |
|
||||
| `list_resumes` | List all your resumes with their IDs, names, tags, and status |
|
||||
| `get_resume` | Get the full data of a specific resume by ID |
|
||||
| `patch_resume` | Apply JSON Patch operations to modify a resume |
|
||||
|
||||
## Available Resources
|
||||
|
||||
| Resource | Description |
|
||||
| --- | --- |
|
||||
| `resume://{id}` | The full resume data as a readable JSON resource |
|
||||
| `resume://schema` | The ResumeData JSON schema for understanding the data structure |
|
||||
|
||||
## Usage Examples
|
||||
|
||||
Once your MCP client is connected, you can use natural language to interact with your resumes:
|
||||
|
||||
### Browsing
|
||||
|
||||
- "List my resumes"
|
||||
- "Show me my resume named 'Software Engineer'"
|
||||
- "What skills are listed on my resume?"
|
||||
|
||||
### Editing
|
||||
|
||||
- "Update my name to Jane Doe"
|
||||
- "Change my headline to Senior Software Engineer"
|
||||
- "Add TypeScript to my skills with an Advanced proficiency level"
|
||||
- "Add a new experience entry for my role as Staff Engineer at Acme Corp from Jan 2024 to Present"
|
||||
- "Remove the third item from my skills section"
|
||||
|
||||
### Styling
|
||||
|
||||
- "Change the template to bronzor"
|
||||
- "Set the primary color to blue"
|
||||
- "Hide the interests section"
|
||||
|
||||
<Tip>
|
||||
The AI will use `get_resume` to inspect your current resume before making changes with `patch_resume`. This ensures the correct JSON paths are used.
|
||||
</Tip>
|
||||
|
||||
## Self-Hosting
|
||||
|
||||
If you're running a self-hosted Reactive Resume instance, set `REACTIVE_RESUME_URL` to your instance URL:
|
||||
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"REACTIVE_RESUME_API_KEY": "your-api-key",
|
||||
"REACTIVE_RESUME_URL": "https://resume.example.com"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
| --- | --- | --- | --- |
|
||||
| `REACTIVE_RESUME_API_KEY` | Yes | — | API key from Reactive Resume settings |
|
||||
| `REACTIVE_RESUME_URL` | No | `https://rxresu.me` | Base URL of the Reactive Resume instance |
|
||||
| `TRANSPORT` | No | `stdio` | Transport mode: `stdio` or `http` |
|
||||
| `PORT` | No | `3100` | Port for streamable HTTP transport |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | Solution |
|
||||
| --- | --- |
|
||||
| "REACTIVE_RESUME_API_KEY is required" | Set the `REACTIVE_RESUME_API_KEY` environment variable in your MCP client configuration |
|
||||
| "API error (401)" | Your API key is invalid or expired. Create a new one in the dashboard |
|
||||
| "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 |
|
||||
| Connection refused | Check that `REACTIVE_RESUME_URL` is correct and the instance is running |
|
||||
| Module not found / Cannot find package | Ensure `cwd` is the repository root so the main project's `node_modules` is used |
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -4,6 +4,12 @@
|
||||
"tailwind": { "entry": ["src/styles.css"] },
|
||||
"project": ["src/**/*.{js,jsx,ts,tsx,mdx,css}"],
|
||||
"ignoreBinaries": ["mint"],
|
||||
"ignoreDependencies": ["npm-check-updates", "reflect-metadata", "node-addon-api", "node-gyp"],
|
||||
"ignoreDependencies": [
|
||||
"@modelcontextprotocol/sdk",
|
||||
"npm-check-updates",
|
||||
"reflect-metadata",
|
||||
"node-addon-api",
|
||||
"node-gyp"
|
||||
],
|
||||
"ignore": ["src/schema/**/*.ts", "src/components/**/*.{ts,tsx}", "src/routeTree.gen.ts"]
|
||||
}
|
||||
|
||||
Generated
BIN
Binary file not shown.
Generated
+32
@@ -207,6 +207,10 @@ msgstr "ከዚህ በኋላ ረድፍ ያክሉ"
|
||||
msgid "Add Row Before"
|
||||
msgstr "ከዚህ በፊት ረድፍ ያክሉ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "አፍሪካንስ"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "አልባኒኛ"
|
||||
@@ -340,6 +348,10 @@ 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 "የመገናኛ መጠን"
|
||||
@@ -534,6 +546,10 @@ msgstr "ቻይንኛ (ባለባለት)"
|
||||
msgid "Circle"
|
||||
msgstr "ክብ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "ምርጫን ሰርዝ"
|
||||
@@ -945,6 +961,10 @@ msgstr "የየታሪክዎን ቅጂ በመፍጠር ላይ…"
|
||||
msgid "Dutch"
|
||||
msgstr "ደች"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "ትምህርት"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "የይለፍ ቃልዎ አስታውሰዎ? <0><1>አሁን ይግቡ <2/
|
||||
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 "የይለፍ ቃል ጥበቃን በማስወገድ ላይ…"
|
||||
@@ -2357,6 +2381,10 @@ msgstr "ከዚያም መተግበሪያው ሰጥቶት የ 6 አሃዝ ኮድ
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "የይለፍ ቃልዎን በመዘመን ላይ…"
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "إضافة صف بعد"
|
||||
msgid "Add Row Before"
|
||||
msgstr "إضافة صف قبل"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "الأفريقانس"
|
||||
msgid "AI"
|
||||
msgstr "الذكاء الاصطناعي"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "الألبانية"
|
||||
@@ -340,6 +348,10 @@ 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 "نسبة الأبعاد"
|
||||
@@ -534,6 +546,10 @@ msgstr "الصينية (التقليدية)"
|
||||
msgid "Circle"
|
||||
msgstr "دائرة"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "مسح التحديد"
|
||||
@@ -945,6 +961,10 @@ msgstr "جاري استنساخ سيرتك الذاتية..."
|
||||
msgid "Dutch"
|
||||
msgstr "الهولندية"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "التعليم"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "هل تذكّرت كلمة المرور؟ <0><1>سجّل الدخول ا
|
||||
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 "جاري إزالة حماية كلمة المرور..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "بعد ذلك، أدخِل الرمز المكوَّن من 6 أرقام
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "جاري تحديث كلمة المرور..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ 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 ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "Süni İntellekt"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanca"
|
||||
@@ -340,6 +348,10 @@ 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 ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
|
||||
msgid "Aspect Ratio"
|
||||
msgstr "Proporsiya"
|
||||
@@ -534,6 +546,10 @@ msgstr "Çin (Ənənəvi)"
|
||||
msgid "Circle"
|
||||
msgstr "Dairə"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Seçimi təmizlə"
|
||||
@@ -945,6 +961,10 @@ msgstr "Özgeçmişiniz dublikat edilir..."
|
||||
msgid "Dutch"
|
||||
msgstr "Niderland"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Təhsil"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Parolunuzu xatırladınız? <0><1>İndi daxil olun <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Parolu Sil"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Parol qorunması silinir..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Sonra, davam etmək üçün tətbiqin təqdim etdiyi 6 rəqəmli kodu da
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Özgeçmişi Yenilə"
|
||||
msgid "Update your password"
|
||||
msgstr "Parolunuzu yeniləyin"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Parolunuz yenilənir..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Добавяне на ред след"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Добавяне на ред преди"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Африканс"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Албански"
|
||||
@@ -340,6 +348,10 @@ 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 "Съотношение на страните"
|
||||
@@ -534,6 +546,10 @@ msgstr "Китайски (традиционен)"
|
||||
msgid "Circle"
|
||||
msgstr "Кръг"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Изчистване на избора"
|
||||
@@ -945,6 +961,10 @@ msgstr "Вашата автобиография се дублира..."
|
||||
msgid "Dutch"
|
||||
msgstr "Нидерландски"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Образование"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Спомнихте си паролата? <0><1>Влезте сега <2
|
||||
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 "Премахване на защитата с парола..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "Актуализиране на паролата ви..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "পরের দিকে সারি যোগ করুন"
|
||||
msgid "Add Row Before"
|
||||
msgstr "আগের দিকে সারি যোগ করুন"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "আফ্রিকান্স"
|
||||
msgid "AI"
|
||||
msgstr "এআই"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "আলবেনিয়ান"
|
||||
@@ -340,6 +348,10 @@ 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 "আকারের অনুপাত"
|
||||
@@ -534,6 +546,10 @@ msgstr "চীনা (প্রচলিত)"
|
||||
msgid "Circle"
|
||||
msgstr "বৃত্ত"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "নির্বাচন মুছে ফেলুন"
|
||||
@@ -945,6 +961,10 @@ msgstr "আপনার জীবনবৃত্তান্ত ডুপ্ল
|
||||
msgid "Dutch"
|
||||
msgstr "ডাচ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "শিক্ষা"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "পাসওয়ার্ড মনে আছে? <0><1>এখনই
|
||||
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 "পাসওয়ার্ড সুরক্ষা সরানো হচ্ছে..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "আপনার পাসওয়ার্ড আপডেট করা হচ্ছে..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Afegeix una fila després"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Afegeix una fila abans"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "IA"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanès"
|
||||
@@ -340,6 +348,10 @@ msgstr "Àrea d’estudi"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Intel·ligència artificial"
|
||||
|
||||
#: 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 "Relació d’aspecte"
|
||||
@@ -534,6 +546,10 @@ msgstr "Xinès (tradicional)"
|
||||
msgid "Circle"
|
||||
msgstr "Cercle"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Esborra la selecció"
|
||||
@@ -945,6 +961,10 @@ msgstr "S’està duplicant el currículum..."
|
||||
msgid "Dutch"
|
||||
msgstr "Neerlandès"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Educació"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Recordes la contrasenya? <0><1>Inicia sessió ara <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Elimina la contrasenya"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "S’està desactivant la protecció amb contrasenya..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "A continuació, introdueix el codi de 6 dígits que proporciona l’apli
|
||||
msgid "There was a problem while generating the PDF, please try again in some time."
|
||||
msgstr "S’ha produït un problema en generar el PDF, torna-ho a provar més tard."
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Actualitza el currículum"
|
||||
msgid "Update your password"
|
||||
msgstr "Actualitza la contrasenya"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "S’està actualitzant la contrasenya..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Přidat řádek za"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Přidat řádek před"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikánština"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albánština"
|
||||
@@ -340,6 +348,10 @@ msgstr "Studijní obor"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Umělá inteligence"
|
||||
|
||||
#: 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 "Poměr stran"
|
||||
@@ -534,6 +546,10 @@ msgstr "Čínština (tradiční)"
|
||||
msgid "Circle"
|
||||
msgstr "Kruh"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Zrušit výběr"
|
||||
@@ -945,6 +961,10 @@ msgstr "Duplikování životopisu…"
|
||||
msgid "Dutch"
|
||||
msgstr "Nizozemština"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Vzdělání"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Pamatujete si heslo? <0><1>Přihlaste se nyní <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Odebrat heslo"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Odstraňování ochrany heslem…"
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Poté zadejte šestimístný kód, který aplikace poskytne, abyste mohl
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Aktualizovat životopis"
|
||||
msgid "Update your password"
|
||||
msgstr "Aktualizujte své heslo"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Aktualizace hesla…"
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ 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 ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albansk"
|
||||
@@ -340,6 +348,10 @@ msgstr "Studieområde"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Kunstig intelligens"
|
||||
|
||||
#: 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 "Billedformat"
|
||||
@@ -534,6 +546,10 @@ msgstr "Kinesisk (traditionelt)"
|
||||
msgid "Circle"
|
||||
msgstr "Cirkel"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Ryd markering"
|
||||
@@ -945,6 +961,10 @@ msgstr "Duplikerer dit CV..."
|
||||
msgid "Dutch"
|
||||
msgstr "Hollandsk"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Uddannelse"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Kan du huske din adgangskode? <0><1>Log ind nu <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Fjern adgangskode"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Fjerner adgangskodebeskyttelse..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Indtast derefter den 6-cifrede kode, som appen giver, for at fortsætte.
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Opdater CV"
|
||||
msgid "Update your password"
|
||||
msgstr "Opdater din adgangskode"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Opdaterer din adgangskode..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Zeile danach einfügen"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Zeile davor einfügen"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "KI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanisch"
|
||||
@@ -340,6 +348,10 @@ msgstr "Studienfach"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Künstliche Intelligenz"
|
||||
|
||||
#: 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 "Seitenverhältnis"
|
||||
@@ -534,6 +546,10 @@ msgstr "Chinesisch (traditionell)"
|
||||
msgid "Circle"
|
||||
msgstr "Kreis"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Auswahl löschen"
|
||||
@@ -945,6 +961,10 @@ msgstr "Ihr Lebenslauf wird dupliziert..."
|
||||
msgid "Dutch"
|
||||
msgstr "Niederländisch"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Ausbildung"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Sie erinnern sich wieder an Ihr Passwort? <0><1>Jetzt anmelden <2/></1><
|
||||
msgid "Remove Password"
|
||||
msgstr "Passwort entfernen"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Passwortschutz wird entfernt..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Geben Sie dann den 6-stelligen Code ein, den die App bereitstellt, um fo
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Lebenslauf aktualisieren"
|
||||
msgid "Update your password"
|
||||
msgstr "Aktualisieren Sie Ihr Passwort"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Ihr Passwort wird aktualisiert..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Προσθήκη γραμμής μετά"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Προσθήκη γραμμής πριν"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Αφρικάανς"
|
||||
msgid "AI"
|
||||
msgstr "ΤΝ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Αλβανικά"
|
||||
@@ -340,6 +348,10 @@ 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 "Αναλογία διαστάσεων"
|
||||
@@ -534,6 +546,10 @@ msgstr "Κινέζικα (Παραδοσιακά)"
|
||||
msgid "Circle"
|
||||
msgstr "Κύκλος"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Απαλοιφή επιλογής"
|
||||
@@ -945,6 +961,10 @@ msgstr "Δημιουργία αντιγράφου του βιογραφικού
|
||||
msgid "Dutch"
|
||||
msgstr "Ολλανδικά"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Εκπαίδευση"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Θυμάστε τον κωδικό πρόσβασής σας; <0><1>Συ
|
||||
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 "Κατάργηση προστασίας με κωδικό πρόσβασης..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Στη συνέχεια, εισαγάγετε τον 6ψήφιο κωδ
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "Ενημέρωση του κωδικού πρόσβασής σας..."
|
||||
|
||||
Generated
+32
@@ -202,6 +202,10 @@ msgstr "Add Row After"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Add Row Before"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr "Added"
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -220,6 +224,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr "AI Chat"
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanian"
|
||||
@@ -335,6 +343,10 @@ 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"
|
||||
@@ -529,6 +541,10 @@ msgstr "Chinese (Traditional)"
|
||||
msgid "Circle"
|
||||
msgstr "Circle"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr "Clear chat history"
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Clear selection"
|
||||
@@ -940,6 +956,10 @@ msgstr "Duplicating your resume..."
|
||||
msgid "Dutch"
|
||||
msgstr "Dutch"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr "e.g. Change my name to..."
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Education"
|
||||
@@ -1891,6 +1911,10 @@ msgstr "Remember your password? <0><1>Sign in now <2/></1></0>"
|
||||
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..."
|
||||
@@ -2352,6 +2376,10 @@ msgstr "Then, enter the 6 digit code that the app provides to continue."
|
||||
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
|
||||
@@ -2615,6 +2643,10 @@ 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..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Añadir fila después"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Añadir fila antes"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikáans"
|
||||
msgid "AI"
|
||||
msgstr "IA"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanés"
|
||||
@@ -340,6 +348,10 @@ msgstr "Área de estudio"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Inteligencia artificial"
|
||||
|
||||
#: 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 "Relación de aspecto"
|
||||
@@ -534,6 +546,10 @@ msgstr "Chino (tradicional)"
|
||||
msgid "Circle"
|
||||
msgstr "Círculo"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Borrar selección"
|
||||
@@ -945,6 +961,10 @@ msgstr "Duplicando tu currículum..."
|
||||
msgid "Dutch"
|
||||
msgstr "Neerlandés"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Formación académica"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "¿Recuerdas tu contraseña? <0><1>Inicia sesión ahora <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Quitar contraseña"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Quitando la protección con contraseña..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Luego, introduce el código de 6 dígitos que te proporciona la aplicaci
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Actualizar currículum"
|
||||
msgid "Update your password"
|
||||
msgstr "Actualiza tu contraseña"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Actualizando tu contraseña..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "افزودن ردیف بعد از این"
|
||||
msgid "Add Row Before"
|
||||
msgstr "افزودن ردیف قبل از این"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "آفریکانس"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "آلبانیایی"
|
||||
@@ -340,6 +348,10 @@ 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 "نسبت تصویر"
|
||||
@@ -534,6 +546,10 @@ msgstr "چینی (سنتی)"
|
||||
msgid "Circle"
|
||||
msgstr "دایره"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "پاک کردن انتخاب"
|
||||
@@ -945,6 +961,10 @@ msgstr "در حال تکثیر رزومه شما..."
|
||||
msgid "Dutch"
|
||||
msgstr "هلندی"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "تحصیلات"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "گذرواژهتان را به یاد آوردید؟ <0><1>همین
|
||||
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 "در حال حذف حفاظت با گذرواژه..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "در حال بهروزرسانی گذرواژه شما..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Lisää rivi jälkeen"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Lisää rivi ennen"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "albania"
|
||||
@@ -340,6 +348,10 @@ msgstr "Opintoala"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Tekoäly"
|
||||
|
||||
#: 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 "Kuvasuhde"
|
||||
@@ -534,6 +546,10 @@ msgstr "kiina (perinteinen)"
|
||||
msgid "Circle"
|
||||
msgstr "Ympyrä"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Tyhjennä valinta"
|
||||
@@ -945,6 +961,10 @@ msgstr "Monistetaan ansioluetteloasi..."
|
||||
msgid "Dutch"
|
||||
msgstr "hollanti"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Koulutus"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Muistatko salasanasi? <0><1>Kirjaudu sisään nyt <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Poista salasana"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Poistetaan salasanasuojausta..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Syötä sitten sovelluksen antama kuusinumeroinen koodi jatkaaksesi."
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Päivitä ansioluettelo"
|
||||
msgid "Update your password"
|
||||
msgstr "Päivitä salasanasi"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Päivitetään salasanaasi..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Ajouter une ligne après"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Ajouter une ligne avant"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "IA"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanais"
|
||||
@@ -340,6 +348,10 @@ msgstr "Domaine d'étude"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Intelligence artificielle"
|
||||
|
||||
#: 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 "Format d'image"
|
||||
@@ -534,6 +546,10 @@ msgstr "Chinois (traditionnel)"
|
||||
msgid "Circle"
|
||||
msgstr "Cercle"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Effacer la sélection"
|
||||
@@ -945,6 +961,10 @@ msgstr "Duplication de votre CV..."
|
||||
msgid "Dutch"
|
||||
msgstr "Néerlandais"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Formation"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Vous vous souvenez de votre mot de passe ? <0><1>Connectez-vous maintena
|
||||
msgid "Remove Password"
|
||||
msgstr "Supprimer le mot de passe"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Suppression de la protection par mot de passe..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Ensuite, entrez le code à 6 chiffres fourni par l'application pour cont
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Modifier le CV"
|
||||
msgid "Update your password"
|
||||
msgstr "Modifier votre mot de passe"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Mise à jour de votre mot de passe..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "הוספת שורה אחרי"
|
||||
msgid "Add Row Before"
|
||||
msgstr "הוספת שורה לפני"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "אפריקאנס"
|
||||
msgid "AI"
|
||||
msgstr "בינה מלאכותית"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "אלבנית"
|
||||
@@ -340,6 +348,10 @@ 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 "יחס גובה־רוחב"
|
||||
@@ -534,6 +546,10 @@ msgstr "סינית (מסורתית)"
|
||||
msgid "Circle"
|
||||
msgstr "עיגול"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "ניקוי הבחירה"
|
||||
@@ -945,6 +961,10 @@ msgstr "משכפל את קורות החיים שלך..."
|
||||
msgid "Dutch"
|
||||
msgstr "הולנדית"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "השכלה"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "נזכרת בסיסמה? <0><1>התחברות עכשיו <2/></1></0>"
|
||||
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 "מסיר את ההגנה באמצעות סיסמה..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "לאחר מכן, הזן את הקוד בן 6 הספרות שהאפליק
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "מעדכן את הסיסמה שלך..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "इसके बाद पंक्ति जोड़ें"
|
||||
msgid "Add Row Before"
|
||||
msgstr "इसके पहले पंक्ति जोड़ें"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "अफ्रीकान्स"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "अल्बानियाई"
|
||||
@@ -340,6 +348,10 @@ 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 "आकार अनुपात"
|
||||
@@ -534,6 +546,10 @@ msgstr "चीनी (परंपरागत)"
|
||||
msgid "Circle"
|
||||
msgstr "गोला"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "चयन साफ़ करें"
|
||||
@@ -945,6 +961,10 @@ msgstr "आपका रेज़्यूमे डुप्लिकेट क
|
||||
msgid "Dutch"
|
||||
msgstr "डच"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "शिक्षा"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "पासवर्ड याद है? <0><1>अभी साइन इ
|
||||
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 "पासवर्ड सुरक्षा हटाई जा रही है..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "आपका पासवर्ड अपडेट किया जा रहा है..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ 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 ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "albán"
|
||||
@@ -340,6 +348,10 @@ 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 ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
|
||||
msgid "Aspect Ratio"
|
||||
msgstr "Méretarány"
|
||||
@@ -534,6 +546,10 @@ msgstr "kínai (hagyományos)"
|
||||
msgid "Circle"
|
||||
msgstr "Kör"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Kijelölés törlése"
|
||||
@@ -945,6 +961,10 @@ msgstr "Önéletrajz duplikálása..."
|
||||
msgid "Dutch"
|
||||
msgstr "holland"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Tanulmányok"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Eszébe jutott a jelszó? <0><1>Jelentkezz be most <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Jelszó eltávolítása"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Jelszóvédelem eltávolítása..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Ezután írd be a folytatáshoz az alkalmazás által megadott 6 számje
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Önéletrajz frissítése"
|
||||
msgid "Update your password"
|
||||
msgstr "Jelszó frissítése"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Jelszó frissítése..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Tambah Baris Setelah"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Tambah Baris Sebelum"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "Kecerdasan Buatan"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albania"
|
||||
@@ -340,6 +348,10 @@ msgstr "Bidang Studi"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Kecerdasan Buatan"
|
||||
|
||||
#: 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 "Rasio Aspek"
|
||||
@@ -534,6 +546,10 @@ msgstr "Cina (Tradisional)"
|
||||
msgid "Circle"
|
||||
msgstr "Lingkaran"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Hapus pilihan"
|
||||
@@ -945,6 +961,10 @@ msgstr "Menduplikasi resume Anda..."
|
||||
msgid "Dutch"
|
||||
msgstr "Belanda"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Pendidikan"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Ingat kata sandi Anda? <0><1>Masuk sekarang <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Hapus Kata Sandi"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Menghapus perlindungan kata sandi..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Lalu, masukkan kode 6 digit yang diberikan aplikasi untuk melanjutkan."
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Perbarui Resume"
|
||||
msgid "Update your password"
|
||||
msgstr "Perbarui kata sandi Anda"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Memperbarui kata sandi Anda..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Aggiungi riga dopo"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Aggiungi riga prima"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "IA"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanese"
|
||||
@@ -340,6 +348,10 @@ msgstr "Area di studio"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Intelligenza artificiale"
|
||||
|
||||
#: 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 "Proporzioni"
|
||||
@@ -534,6 +546,10 @@ msgstr "Cinese (tradizionale)"
|
||||
msgid "Circle"
|
||||
msgstr "Cerchio"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Pulisci selezione"
|
||||
@@ -945,6 +961,10 @@ msgstr "Duplicazione del tuo curriculum in corso..."
|
||||
msgid "Dutch"
|
||||
msgstr "Olandese"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Formazione"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Ti ricordi la password? <0><1>Accedi ora <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Rimuovi password"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Rimozione della protezione tramite password..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Quindi inserisci il codice a 6 cifre fornito dall'app per continuare."
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Aggiorna curriculum"
|
||||
msgid "Update your password"
|
||||
msgstr "Aggiorna la tua password"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Aggiornamento della tua password in corso..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "後に行を追加"
|
||||
msgid "Add Row Before"
|
||||
msgstr "前に行を追加"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "アフリカーンス語"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "アルバニア語"
|
||||
@@ -340,6 +348,10 @@ 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 "アスペクト比"
|
||||
@@ -534,6 +546,10 @@ msgstr "中国語(繁体字)"
|
||||
msgid "Circle"
|
||||
msgstr "円"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "選択をクリア"
|
||||
@@ -945,6 +961,10 @@ msgstr "履歴書を複製しています..."
|
||||
msgid "Dutch"
|
||||
msgstr "オランダ語"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "学歴"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "パスワードを思い出しましたか?<0><1>今すぐサインイ
|
||||
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 "パスワード保護を解除しています..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "次に、続行するためにアプリが表示する 6 桁のコード
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "パスワードを更新しています..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "បន្ថែមជួរដេកនៅក្រោយ"
|
||||
msgid "Add Row Before"
|
||||
msgstr "បន្ថែមជួរដេកនៅមុខ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanian"
|
||||
@@ -340,6 +348,10 @@ 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 "សមាមាត្រទ្រង់ទ្រាយ"
|
||||
@@ -534,6 +546,10 @@ msgstr "Chinese (Traditional)"
|
||||
msgid "Circle"
|
||||
msgstr "រង្វង់"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "សម្អាតការជ្រើសរើស"
|
||||
@@ -945,6 +961,10 @@ msgstr "កំពុងស្ទួនប្រវត្តិរូប
|
||||
msgid "Dutch"
|
||||
msgstr "Dutch"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "ការសិក្សា"
|
||||
@@ -1896,6 +1916,10 @@ 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 "កំពុងដកការការពារដោយពាក្យសម្ងាត់..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "កំពុងបច្ចុប្បន្នភាពពាក្យសម្ងាត់របស់អ្នក..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "ಸಾಲನ್ನು ನಂತರ ಸೇರಿಸಿ"
|
||||
msgid "Add Row Before"
|
||||
msgstr "ಸಾಲನ್ನು ಮೊದಲು ಸೇರಿಸಿ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "ಆಫ್ರಿಕಾನ್ಸ್"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "ಅಲ್ಬೇನಿಯನ್"
|
||||
@@ -340,6 +348,10 @@ 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 "ಆಕಾರ ಅನುಪಾತ"
|
||||
@@ -534,6 +546,10 @@ msgstr "ಚೈನೀಸ್ (ಸಾಂಪ್ರದಾಯಿಕ)"
|
||||
msgid "Circle"
|
||||
msgstr "ವೃತ್ತ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "ಆಯ್ಕೆಯನ್ನು ತೆರವುಗೊಳಿಸಿ"
|
||||
@@ -945,6 +961,10 @@ msgstr "ನಿಮ್ಮ ರೆಸ್ಯೂಮ್ ನಕಲಿಸಲಾಗುತ
|
||||
msgid "Dutch"
|
||||
msgstr "ಡಚ್"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "ಶಿಕ್ಷಣ"
|
||||
@@ -1896,6 +1916,10 @@ 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 "ಪಾಸ್ವರ್ಡ್ ರಕ್ಷಣೆಯನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತಿದೆ..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "ನಂತರ, ಆ್ಯಪ್ ನೀಡುವ 6 ಅಂಕಿಯ ಕೋ
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನವೀಕರಿಸಲಾಗುತ್ತಿದೆ..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "뒤에 행 추가"
|
||||
msgid "Add Row Before"
|
||||
msgstr "앞에 행 추가"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "아프리칸스어"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "알바니아어"
|
||||
@@ -340,6 +348,10 @@ 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 "가로세로 비율"
|
||||
@@ -534,6 +546,10 @@ msgstr "중국어(번체)"
|
||||
msgid "Circle"
|
||||
msgstr "원"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "선택 해제"
|
||||
@@ -945,6 +961,10 @@ msgstr "이력서를 복제하는 중입니다..."
|
||||
msgid "Dutch"
|
||||
msgstr "네덜란드어"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "학력"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "비밀번호가 기억나시나요? <0><1>지금 로그인하기 <2/></1
|
||||
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 "비밀번호 보호를 제거하는 중입니다..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "그 다음, 앱에 표시된 6자리 코드를 입력해 계속 진행
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "비밀번호를 업데이트하는 중입니다..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Pridėti eilutę po"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Pridėti eilutę prieš"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikanso"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanų"
|
||||
@@ -340,6 +348,10 @@ msgstr "Studijų sritis"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Dirbtinis intelektas"
|
||||
|
||||
#: 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 "Vaizdo santykis"
|
||||
@@ -534,6 +546,10 @@ msgstr "Kinų (tradicinė)"
|
||||
msgid "Circle"
|
||||
msgstr "Apskritimas"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Išvalyti pasirinkimą"
|
||||
@@ -945,6 +961,10 @@ msgstr "Dubliuojamas jūsų gyvenimo aprašymas..."
|
||||
msgid "Dutch"
|
||||
msgstr "Olandų"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Išsilavinimas"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Prisiminate slaptažodį? <0><1>Prisijunkite dabar <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Pašalinti slaptažodį"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Šalinama apsauga slaptažodžiu..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Tada įveskite programos sugeneruotą 6 skaitmenų kodą, kad tęstumėt
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Atnaujinti gyvenimo aprašymą"
|
||||
msgid "Update your password"
|
||||
msgstr "Atnaujinkite savo slaptažodį"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Atnaujinamas jūsų slaptažodis..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Pievienot rindu pēc"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Pievienot rindu pirms"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikandu"
|
||||
msgid "AI"
|
||||
msgstr "MI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albāņu"
|
||||
@@ -340,6 +348,10 @@ msgstr "Studiju joma"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Mākslīgais intelekts"
|
||||
|
||||
#: 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 "Proporcijas"
|
||||
@@ -534,6 +546,10 @@ msgstr "Ķīniešu (tradicionālā)"
|
||||
msgid "Circle"
|
||||
msgstr "Aplis"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Notīrīt izvēli"
|
||||
@@ -945,6 +961,10 @@ msgstr "Tiek dublēts jūsu CV..."
|
||||
msgid "Dutch"
|
||||
msgstr "Holandiešu"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Izglītība"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Atceraties savu paroli? <0><1>Piesakieties tagad <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Noņemt paroli"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Tiek noņemta paroles aizsardzība..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Pēc tam ievadiet 6 ciparu kodu, ko nodrošina lietotne, lai turpinātu.
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Atjaunināt CV"
|
||||
msgid "Update your password"
|
||||
msgstr "Atjauniniet savu paroli"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Tiek atjaunināta jūsu parole..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "വരി പിന്നീട് ചേർക്കുക"
|
||||
msgid "Add Row Before"
|
||||
msgstr "വരി മുമ്പ് ചേർക്കുക"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "ആഫ്രിക്കാൻസ്"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "അൽബേനിയൻ"
|
||||
@@ -340,6 +348,10 @@ 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 "ആസ്പെക്ട് റേഷ്യോ"
|
||||
@@ -534,6 +546,10 @@ msgstr "ചൈനീസ് (ട്രഡീഷണൽ)"
|
||||
msgid "Circle"
|
||||
msgstr "വൃത്തം"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "തിരഞ്ഞെടുപ്പ് ക്ലിയർ ചെയ്യുക"
|
||||
@@ -945,6 +961,10 @@ msgstr "നിങ്ങളുടെ റിസ്യൂം ഡൂപ്ലിക
|
||||
msgid "Dutch"
|
||||
msgstr "ഡച്ച്"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "വിദ്യാഭ്യാസം"
|
||||
@@ -1896,6 +1916,10 @@ 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 "പാസ്വേഡ് സംരക്ഷണം നീക്കം ചെയ്യുന്നു..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "ശേഷം, ആപ്പ് നൽകുന്ന 6 അക്ക ക
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "നിങ്ങളുടെ പാസ്വേഡ് അപ്ഡേറ്റ് ചെയ്യുന്നു..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "नंतर ओळ जोडा"
|
||||
msgid "Add Row Before"
|
||||
msgstr "आधी ओळ जोडा"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "आफ्रिकान्स"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "अल्बेनियन"
|
||||
@@ -340,6 +348,10 @@ 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 "प्रसर गुणोत्तर"
|
||||
@@ -534,6 +546,10 @@ msgstr "चीनी (परंपरागत)"
|
||||
msgid "Circle"
|
||||
msgstr "गोलाकार"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "निवड साफ करा"
|
||||
@@ -945,6 +961,10 @@ msgstr "तुमचा रेझ्युमे डुप्लिकेट क
|
||||
msgid "Dutch"
|
||||
msgstr "डच"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "शिक्षण"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "पासवर्ड आठवला? <0><1>आता साइन इ
|
||||
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 "पासवर्ड संरक्षण काढून टाकले जात आहे..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "तुमचा पासवर्ड अपडेट केला जात आहे..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Tambah Baris Selepas"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Tambah Baris Sebelum"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanian"
|
||||
@@ -340,6 +348,10 @@ msgstr "Bidang Pengajian"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Kecerdasan Buatan"
|
||||
|
||||
#: 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 "Nisbah Aspek"
|
||||
@@ -534,6 +546,10 @@ msgstr "Cina (Tradisional)"
|
||||
msgid "Circle"
|
||||
msgstr "Bulatan"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Kosongkan pilihan"
|
||||
@@ -945,6 +961,10 @@ msgstr "Menduplikasi resume anda..."
|
||||
msgid "Dutch"
|
||||
msgstr "Belanda"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Pendidikan"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Masih ingat kata laluan anda? <0><1>Log masuk sekarang <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Buang Kata Laluan"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Membuang perlindungan kata laluan..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Kemudian, masukkan kod 6 digit yang diberikan oleh apl untuk meneruskan.
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Kemas Kini Resume"
|
||||
msgid "Update your password"
|
||||
msgstr "Kemas kini kata laluan anda"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Mengemas kini kata laluan anda..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "पछि पङ्क्ति थप्नुहोस्"
|
||||
msgid "Add Row Before"
|
||||
msgstr "अघिल्लो पङ्क्ति थप्नुहोस्"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "अफ्रिकान्स"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "अल्बानियन"
|
||||
@@ -340,6 +348,10 @@ 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)"
|
||||
@@ -534,6 +546,10 @@ msgstr "चिनियाँ (परम्परागत)"
|
||||
msgid "Circle"
|
||||
msgstr "वृत्त"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "चयन खाली गर्नुहोस्"
|
||||
@@ -945,6 +961,10 @@ msgstr "तपाईंको बायोडाटा नक्कल हुँ
|
||||
msgid "Dutch"
|
||||
msgstr "डच"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "शिक्षा"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "पासवर्ड सम्झनुभयो? <0><1>अहिले
|
||||
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 "पासवर्ड सुरक्षा हटाइँदैछ..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "तपाईंको पासवर्ड अद्यावधिक हुँदैछ..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Rij erna toevoegen"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Rij ervoor toevoegen"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanees"
|
||||
@@ -340,6 +348,10 @@ msgstr "Studierichting"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Kunstmatige intelligentie"
|
||||
|
||||
#: 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 "Beeldverhouding"
|
||||
@@ -534,6 +546,10 @@ msgstr "Chinees (traditioneel)"
|
||||
msgid "Circle"
|
||||
msgstr "Cirkel"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Selectie wissen"
|
||||
@@ -945,6 +961,10 @@ msgstr "Uw cv wordt gedupliceerd..."
|
||||
msgid "Dutch"
|
||||
msgstr "Nederlands"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Opleiding"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Herinnert u zich uw wachtwoord? <0><1>Meld u nu aan <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Wachtwoord verwijderen"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Wachtwoordbeveiliging wordt verwijderd..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Voer vervolgens de 6-cijferige code in die de app geeft om door te gaan.
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Cv bijwerken"
|
||||
msgid "Update your password"
|
||||
msgstr "Werk uw wachtwoord bij"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Uw wachtwoord wordt bijgewerkt..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Legg til rad etter"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Legg til rad før"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "KI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albansk"
|
||||
@@ -340,6 +348,10 @@ msgstr "Studiefelt"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Kunstig intelligens"
|
||||
|
||||
#: 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 "Størrelsesforhold"
|
||||
@@ -534,6 +546,10 @@ msgstr "Kinesisk (tradisjonell)"
|
||||
msgid "Circle"
|
||||
msgstr "Sirkel"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Fjern valg"
|
||||
@@ -945,6 +961,10 @@ msgstr "Dupliserer CV-en din..."
|
||||
msgid "Dutch"
|
||||
msgstr "Nederlandsk"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Utdanning"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Husker du passordet ditt? <0><1>Logg inn nå <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Fjern passord"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Fjerner passordbeskyttelse..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Skriv deretter inn den 6-sifrede koden som appen gir deg for å fortsett
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Oppdater CV"
|
||||
msgid "Update your password"
|
||||
msgstr "Oppdater passordet ditt"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Oppdaterer passordet ditt..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "ପରେ ପଙ୍କ୍ତି ଯୋଡନ୍ତୁ"
|
||||
msgid "Add Row Before"
|
||||
msgstr "ପୂର୍ବେ ପଙ୍କ୍ତି ଯୋଡନ୍ତୁ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "ଆଫ୍ରିକାନ୍ସ"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "ଆଲବାନିଆନ୍"
|
||||
@@ -340,6 +348,10 @@ 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 "ଆସ୍ପେକ୍ଟ ଅନୁପାତ"
|
||||
@@ -534,6 +546,10 @@ msgstr "ଚାଇନିଜ୍ (ପାରମ୍ପରିକ)"
|
||||
msgid "Circle"
|
||||
msgstr "ବୃତ୍ତ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "ଚୟନ ସଫା କରନ୍ତୁ"
|
||||
@@ -945,6 +961,10 @@ msgstr "ଆପଣଙ୍କ ରେଜ୍ୟୁମେ ନକଲ ହେଉଛି...
|
||||
msgid "Dutch"
|
||||
msgstr "ଡଚ୍"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "ଶିକ୍ଷା"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "ପାସୱାର୍ଡ ମନେ ପକାଇଲେ କି? <0><1>ଏ
|
||||
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 "ପାସୱାର୍ଡ ସୁରକ୍ଷା ଅପସାରଣ ହେଉଛି..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "ଆପଣଙ୍କ ପାସୱାର୍ଡ ଅଦ୍ୟତନ ହେଉଛି..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Dodaj wiersz po"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Dodaj wiersz przed"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albański"
|
||||
@@ -340,6 +348,10 @@ msgstr "Kierunek studiów"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Sztuczna inteligencja"
|
||||
|
||||
#: 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 "Proporcje obrazu"
|
||||
@@ -534,6 +546,10 @@ msgstr "Chiński (tradycyjny)"
|
||||
msgid "Circle"
|
||||
msgstr "Koło"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Wyczyść wybór"
|
||||
@@ -945,6 +961,10 @@ msgstr "Duplikowanie CV..."
|
||||
msgid "Dutch"
|
||||
msgstr "Holenderski"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Wykształcenie"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Pamiętasz hasło? <0><1>Zaloguj się teraz <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Usuń hasło"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Wyłączanie ochrony hasłem..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Następnie wpisz 6-cyfrowy kod podany przez aplikację, aby kontynuować
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Zaktualizuj CV"
|
||||
msgid "Update your password"
|
||||
msgstr "Zaktualizuj swoje hasło"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Aktualizowanie hasła..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Adicionar linha depois"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Adicionar linha antes"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Africâner"
|
||||
msgid "AI"
|
||||
msgstr "IA"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanês"
|
||||
@@ -340,6 +348,10 @@ msgstr "Área de estudo"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Inteligência Artificial"
|
||||
|
||||
#: 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 "Proporção da imagem"
|
||||
@@ -534,6 +546,10 @@ msgstr "Chinês (Tradicional)"
|
||||
msgid "Circle"
|
||||
msgstr "Círculo"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Limpar seleção"
|
||||
@@ -945,6 +961,10 @@ msgstr "Duplicando seu currículo..."
|
||||
msgid "Dutch"
|
||||
msgstr "Holandês"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Formação"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Lembrou da sua senha? <0><1>Entre agora <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Remover senha"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Removendo proteção por senha..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Em seguida, insira o código de 6 dígitos fornecido pelo aplicativo par
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Atualizar currículo"
|
||||
msgid "Update your password"
|
||||
msgstr "Atualize sua senha"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Atualizando sua senha..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Adicionar linha após"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Adicionar linha antes"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Africâner"
|
||||
msgid "AI"
|
||||
msgstr "IA"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanês"
|
||||
@@ -340,6 +348,10 @@ msgstr "Área de estudo"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Inteligência Artificial"
|
||||
|
||||
#: 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 "Proporção"
|
||||
@@ -534,6 +546,10 @@ msgstr "Chinês (tradicional)"
|
||||
msgid "Circle"
|
||||
msgstr "Círculo"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Limpar seleção"
|
||||
@@ -945,6 +961,10 @@ msgstr "A duplicar o seu currículo..."
|
||||
msgid "Dutch"
|
||||
msgstr "Neerlandês"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Formação"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Lembra-se da sua senha? <0><1>Inicie sessão agora <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Remover senha"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "A remover a proteção por senha..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Em seguida, introduza o código de 6 dígitos fornecido pela aplicação
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Atualizar currículo"
|
||||
msgid "Update your password"
|
||||
msgstr "Atualize a sua senha"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "A atualizar a sua senha..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ 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 ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albaneză"
|
||||
@@ -340,6 +348,10 @@ msgstr "Domeniu de studiu"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Inteligență artificială"
|
||||
|
||||
#: 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 "Raport de aspect"
|
||||
@@ -534,6 +546,10 @@ msgstr "Chineză (tradițională)"
|
||||
msgid "Circle"
|
||||
msgstr "Cerc"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Ștergeți selecția"
|
||||
@@ -945,6 +961,10 @@ msgstr "Se duplică CV-ul..."
|
||||
msgid "Dutch"
|
||||
msgstr "Olandeză"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Educație"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Vă amintiți parola? <0><1>Autentificați-vă acum <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Elimină parola"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Se elimină protecția prin parolă..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Apoi introduceți codul din 6 cifre oferit de aplicație pentru a contin
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Actualizați CV-ul"
|
||||
msgid "Update your password"
|
||||
msgstr "Actualizați-vă parola"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Se actualizează parola..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Добавить строку после"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Добавить строку до"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Африкаанс"
|
||||
msgid "AI"
|
||||
msgstr "ИИ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Албанский"
|
||||
@@ -340,6 +348,10 @@ 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 "Соотношение сторон"
|
||||
@@ -534,6 +546,10 @@ msgstr "Китайский (традиционный)"
|
||||
msgid "Circle"
|
||||
msgstr "Круг"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Очистить выбор"
|
||||
@@ -945,6 +961,10 @@ msgstr "Дублирование вашего резюме..."
|
||||
msgid "Dutch"
|
||||
msgstr "Нидерландский"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Образование"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Вспомнили пароль? <0><1>Войдите сейчас <2/><
|
||||
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 "Отключение защиты паролем..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "Обновление пароля..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Pridať riadok za"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Pridať riadok pred"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikánčina"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albánčina"
|
||||
@@ -340,6 +348,10 @@ msgstr "Študijný odbor"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Umelá inteligencia"
|
||||
|
||||
#: 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 "Pomer strán"
|
||||
@@ -534,6 +546,10 @@ msgstr "Čínština (tradičná)"
|
||||
msgid "Circle"
|
||||
msgstr "Kruh"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Zrušiť výber"
|
||||
@@ -945,6 +961,10 @@ msgstr "Duplikujem tvoj životopis..."
|
||||
msgid "Dutch"
|
||||
msgstr "Holandčina"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Vzdelanie"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Spomínaš si na heslo? <0><1>Prihlás sa teraz <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Odstrániť heslo"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Odstraňujem ochranu heslom..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Potom zadaj 6‑ciferný kód, ktorý ti aplikácia vygeneruje, aby si p
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Aktualizovať životopis"
|
||||
msgid "Update your password"
|
||||
msgstr "Aktualizuj svoje heslo"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Aktualizujem tvoje heslo..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Shto rresht pas"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Shto rresht para"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikanisht"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Shqip"
|
||||
@@ -340,6 +348,10 @@ msgstr "Fusha e studimit"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Inteligjenca Artificiale"
|
||||
|
||||
#: 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 "Proporcioni"
|
||||
@@ -534,6 +546,10 @@ msgstr "Kinezçe (Tradicionale)"
|
||||
msgid "Circle"
|
||||
msgstr "Rreth"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Pastro përzgjedhjen"
|
||||
@@ -945,6 +961,10 @@ msgstr "Po dyfishohet CV-ja juaj..."
|
||||
msgid "Dutch"
|
||||
msgstr "Holandisht"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Arsimimi"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "E kujtuat fjalëkalimin? <0><1>Hyni tani <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Hiq fjalëkalimin"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Po hiqet mbrojtja me fjalëkalim..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Më pas, futni kodin 6-shifror që jep aplikacioni për të vazhduar."
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ 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 ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Po përditësohet fjalëkalimi juaj..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Додај ред после"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Додај ред пре"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Африканс"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Албански"
|
||||
@@ -340,6 +348,10 @@ 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 "Однос стране"
|
||||
@@ -534,6 +546,10 @@ msgstr "Кинески (традиционални)"
|
||||
msgid "Circle"
|
||||
msgstr "Круг"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Обриши избор"
|
||||
@@ -945,6 +961,10 @@ msgstr "Дуплирање вашег резимеа..."
|
||||
msgid "Dutch"
|
||||
msgstr "Холандски"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Образовање"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Сећате се лозинке? <0><1>Пријавите се сада
|
||||
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 "Уклањање заштите лозинком..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "Ажурирање ваше лозинке..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ 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 ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikanska"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Albanska"
|
||||
@@ -340,6 +348,10 @@ msgstr "Studieområde"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Artificiell intelligens"
|
||||
|
||||
#: 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 "Bildförhållande"
|
||||
@@ -534,6 +546,10 @@ msgstr "Kinesiska (traditionell)"
|
||||
msgid "Circle"
|
||||
msgstr "Cirkel"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Rensa markering"
|
||||
@@ -945,6 +961,10 @@ msgstr "Duplicerar ditt CV..."
|
||||
msgid "Dutch"
|
||||
msgstr "Nederländska"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Utbildning"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Kommer du ihåg ditt lösenord? <0><1>Logga in nu <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Ta bort lösenord"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Tar bort lösenordsskydd..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Ange sedan den sexsiffriga kod som appen ger för att fortsätta."
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Uppdatera CV"
|
||||
msgid "Update your password"
|
||||
msgstr "Uppdatera ditt lösenord"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Uppdaterar ditt lösenord..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "பின் வரியைச் சேர்க்கவும்"
|
||||
msgid "Add Row Before"
|
||||
msgstr "முன் வரியைச் சேர்க்கவும்"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "ஆஃப்ரிகான்ஸ்"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "அல்பேனியன்"
|
||||
@@ -340,6 +348,10 @@ 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 "ஒப்புத்திணைவு விகிதம்"
|
||||
@@ -534,6 +546,10 @@ msgstr "சீனம் (சம்பிரதாய)"
|
||||
msgid "Circle"
|
||||
msgstr "வட்டம்"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "தேர்வை அழிக்கவும்"
|
||||
@@ -945,6 +961,10 @@ msgstr "உங்கள் ரெஸ்யூமியின் நகலை உ
|
||||
msgid "Dutch"
|
||||
msgstr "டச்சு"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "கல்வி"
|
||||
@@ -1896,6 +1916,10 @@ 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 "கடவுச்சொல் பாதுகாப்பை நீக்கிக் கொண்டிருக்கிறது..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "பின்னர், செயலி வழங்கும் 6 இல
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "உங்கள் கடவுச்சொல்லை புதுப்பித்து கொண்டிருக்கிறது..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "తరువాత వరుస చేర్చండి"
|
||||
msgid "Add Row Before"
|
||||
msgstr "ముందు వరుస చేర్చండి"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "ఆఫ్రికాన్స్"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "అల్బేనియన్"
|
||||
@@ -340,6 +348,10 @@ 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 "కారక నిష్పత్తి"
|
||||
@@ -534,6 +546,10 @@ msgstr "చైనీస్ (సాంప్రదాయ)"
|
||||
msgid "Circle"
|
||||
msgstr "వృత్తం"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "ఎంపికను క్లియర్ చేయండి"
|
||||
@@ -945,6 +961,10 @@ msgstr "మీ రిజ్యూమ్ను నకిలీ చేస్త
|
||||
msgid "Dutch"
|
||||
msgstr "డచ్"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "విద్య"
|
||||
@@ -1896,6 +1916,10 @@ 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 "పాస్వర్డ్ రక్షణను తీసివేస్తున్నాము..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "తర్వాత, యాప్ ఇచ్చిన 6 అంకెల
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "మీ పాస్వర్డ్ను నవీకరిస్తోంది..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "เพิ่มแถวหลัง"
|
||||
msgid "Add Row Before"
|
||||
msgstr "เพิ่มแวก่อน"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "อาฟรีกานส์"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "แอลเบเนีย"
|
||||
@@ -340,6 +348,10 @@ 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 "อัตราส่วนภาพ"
|
||||
@@ -534,6 +546,10 @@ msgstr "จีน (ตัวเต็ม)"
|
||||
msgid "Circle"
|
||||
msgstr "วงกลม"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "ล้างการเลือก"
|
||||
@@ -945,6 +961,10 @@ msgstr "กำลังคัดลอกเรซูเม่ของคุณ
|
||||
msgid "Dutch"
|
||||
msgstr "ดัตช์"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "การศึกษา"
|
||||
@@ -1896,6 +1916,10 @@ 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 "กำลังลบการป้องกันด้วยรหัสผ่าน..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "จากนั้น กรอกรหัส 6 หลักที่
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "กำลังอัปเดตรหัสผ่านของคุณ..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Sonra Satır Ekle"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Önce Satır Ekle"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "Yapay Zeka"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Arnavutça"
|
||||
@@ -340,6 +348,10 @@ msgstr "Çalışma alanı"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Yapay Zekâ"
|
||||
|
||||
#: 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 "En/Boy Oranı"
|
||||
@@ -534,6 +546,10 @@ msgstr "Çince (Geleneksel)"
|
||||
msgid "Circle"
|
||||
msgstr "Daire"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Seçimi temizle"
|
||||
@@ -945,6 +961,10 @@ msgstr "Özgeçmişiniz çoğaltılıyor..."
|
||||
msgid "Dutch"
|
||||
msgstr "Felemenkçe"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Eğitim"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Şifrenizi hatırlıyor musunuz? <0><1>Şimdi giriş yapın <2/></1></0>
|
||||
msgid "Remove Password"
|
||||
msgstr "Şifreyi Kaldır"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Şifre koruması kaldırılıyor..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Daha sonra, devam etmek için uygulamanın verdiği 6 haneli kodu girin.
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Özgeçmişi Güncelle"
|
||||
msgid "Update your password"
|
||||
msgstr "Şifrenizi güncelleyin"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Şifreniz güncelleniyor..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Додати Рядок Знизу"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Додати Рядок Згори"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Африканська"
|
||||
msgid "AI"
|
||||
msgstr "ШІ"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Албанська"
|
||||
@@ -340,6 +348,10 @@ 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 "Пропорції"
|
||||
@@ -534,6 +546,10 @@ msgstr "Китайська (традиційна)"
|
||||
msgid "Circle"
|
||||
msgstr "Кругле"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Очистити вибір"
|
||||
@@ -945,6 +961,10 @@ msgstr "Дублювання резюме..."
|
||||
msgid "Dutch"
|
||||
msgstr "Голландська"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Освіта"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Пам’ятаєте свій пароль? <0><1>Увійдіть за
|
||||
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 "Видалення захисту паролем..."
|
||||
@@ -2357,6 +2381,10 @@ 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
|
||||
@@ -2620,6 +2648,10 @@ 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 "Оновлення пароля..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "Qatordan keyin qator qo‘shish"
|
||||
msgid "Add Row Before"
|
||||
msgstr "Qatordan oldin qator qo‘shish"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "SO"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Alban tili"
|
||||
@@ -340,6 +348,10 @@ msgstr "Ta'lim sohasi"
|
||||
msgid "Artificial Intelligence"
|
||||
msgstr "Sun'iy intellekt"
|
||||
|
||||
#: 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 "Tomonlar nisbati"
|
||||
@@ -534,6 +546,10 @@ msgstr "Xitoy (An’anaviy)"
|
||||
msgid "Circle"
|
||||
msgstr "Doira"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Tanlovni tozalash"
|
||||
@@ -945,6 +961,10 @@ msgstr "Rezyume nusxalanmoqda..."
|
||||
msgid "Dutch"
|
||||
msgstr "Golland tili"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Ta'lim"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Parolingiz esingizdami? <0><1>Hozir kiring <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Parolni olib tashlash"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Parol himoyasi olib tashlanmoqda..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Keyin, davom etish uchun ilova taqdim etgan 6 xonali kodni kiriting."
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ msgstr "Rezyumeni yangilash"
|
||||
msgid "Update your password"
|
||||
msgstr "Parolingizni yangilash"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Updated"
|
||||
msgstr ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Parolingiz yangilanmoqda..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ 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 ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "Tiếng Afrikaans"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "Tiếng Albania"
|
||||
@@ -340,6 +348,10 @@ 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 ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/left/sections/picture.tsx
|
||||
msgid "Aspect Ratio"
|
||||
msgstr "Tỷ lệ khung hình"
|
||||
@@ -534,6 +546,10 @@ msgstr "Tiếng Trung (Phồn thể)"
|
||||
msgid "Circle"
|
||||
msgstr "Vòng tròn"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "Xóa lựa chọn"
|
||||
@@ -945,6 +961,10 @@ msgstr "Đang tạo bản sao bản lý lịch của bạn..."
|
||||
msgid "Dutch"
|
||||
msgstr "Tiếng Hà Lan"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "Giáo dục"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "Bạn nhớ mật khẩu? <0><1>Đăng nhập ngay <2/></1></0>"
|
||||
msgid "Remove Password"
|
||||
msgstr "Xóa mật khẩu"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Removed"
|
||||
msgstr ""
|
||||
|
||||
#: src/routes/builder/$resumeId/-sidebar/right/sections/sharing.tsx
|
||||
msgid "Removing password protection..."
|
||||
msgstr "Đang xóa bảo vệ mật khẩu..."
|
||||
@@ -2357,6 +2381,10 @@ msgstr "Sau đó, nhập mã 6 chữ số mà ứng dụng cung cấp để ti
|
||||
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 ""
|
||||
|
||||
#: 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
|
||||
@@ -2620,6 +2648,10 @@ 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 ""
|
||||
|
||||
#: src/dialogs/auth/change-password.tsx
|
||||
msgid "Updating your password..."
|
||||
msgstr "Đang cập nhật mật khẩu của bạn..."
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "在后面添加行"
|
||||
msgid "Add Row Before"
|
||||
msgstr "在前面添加行"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "南非语"
|
||||
msgid "AI"
|
||||
msgstr "AI(人工智能)"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "阿尔巴尼亚语"
|
||||
@@ -340,6 +348,10 @@ 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 "宽高比"
|
||||
@@ -534,6 +546,10 @@ msgstr "中文(繁体)"
|
||||
msgid "Circle"
|
||||
msgstr "圆形"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "清除选择"
|
||||
@@ -945,6 +961,10 @@ msgstr "正在复制你的简历…"
|
||||
msgid "Dutch"
|
||||
msgstr "荷兰语"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "教育经历"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "想起你的密码了?<0><1>立即登录 <2/></1></0>"
|
||||
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 "正在移除密码保护…"
|
||||
@@ -2357,6 +2381,10 @@ msgstr "然后,输入应用提供的 6 位验证码以继续。"
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "正在更新你的密码…"
|
||||
|
||||
Generated
+32
@@ -207,6 +207,10 @@ msgstr "在後方新增列"
|
||||
msgid "Add Row Before"
|
||||
msgstr "在前方新增列"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -225,6 +229,10 @@ msgstr "南非荷蘭語"
|
||||
msgid "AI"
|
||||
msgstr "AI"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr "阿爾巴尼亞語"
|
||||
@@ -340,6 +348,10 @@ 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 "顯示比例"
|
||||
@@ -534,6 +546,10 @@ msgstr "中文(繁體)"
|
||||
msgid "Circle"
|
||||
msgstr "圓形"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr "清除選取"
|
||||
@@ -945,6 +961,10 @@ msgstr "正在複製您的履歷…"
|
||||
msgid "Dutch"
|
||||
msgstr "荷蘭語"
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr "學歷"
|
||||
@@ -1896,6 +1916,10 @@ msgstr "想起密碼了嗎?<0><1>立即登入 <2/></1></0>"
|
||||
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 "正在移除密碼保護…"
|
||||
@@ -2357,6 +2381,10 @@ msgstr "接著,請輸入應用程式提供的 6 位數驗證碼以繼續。"
|
||||
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
|
||||
@@ -2620,6 +2648,10 @@ 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 "正在更新您的密碼…"
|
||||
|
||||
Generated
+32
@@ -202,6 +202,10 @@ msgstr ""
|
||||
msgid "Add Row Before"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Added"
|
||||
msgstr ""
|
||||
|
||||
#. placeholder {0}: passkey.createdAt.toLocaleDateString()
|
||||
#: src/routes/dashboard/settings/authentication/-components/passkeys.tsx
|
||||
msgid "Added on {0}"
|
||||
@@ -220,6 +224,10 @@ msgstr ""
|
||||
msgid "AI"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "AI Chat"
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/locale.ts
|
||||
msgid "Albanian"
|
||||
msgstr ""
|
||||
@@ -335,6 +343,10 @@ 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 ""
|
||||
@@ -529,6 +541,10 @@ msgstr ""
|
||||
msgid "Circle"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "Clear chat history"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ui/multiple-combobox.tsx
|
||||
msgid "Clear selection"
|
||||
msgstr ""
|
||||
@@ -940,6 +956,10 @@ msgstr ""
|
||||
msgid "Dutch"
|
||||
msgstr ""
|
||||
|
||||
#: src/components/ai/chat.tsx
|
||||
msgid "e.g. Change my name to..."
|
||||
msgstr ""
|
||||
|
||||
#: src/utils/resume/section.tsx
|
||||
msgid "Education"
|
||||
msgstr ""
|
||||
@@ -1891,6 +1911,10 @@ 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 ""
|
||||
@@ -2352,6 +2376,10 @@ 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
|
||||
@@ -2615,6 +2643,10 @@ 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 ""
|
||||
|
||||
+434
@@ -0,0 +1,434 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Reactive Resume MCP server — single entry point. Run with:
|
||||
* npx tsx /path/to/reactive-resume/mcp
|
||||
*
|
||||
* Env: REACTIVE_RESUME_API_KEY (required), REACTIVE_RESUME_URL (default https://rxresu.me),
|
||||
* TRANSPORT (stdio | http), PORT (default 3100).
|
||||
*/
|
||||
|
||||
import * as http from "node:http";
|
||||
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
||||
import type { Operation } from "fast-json-patch";
|
||||
import { z } from "zod";
|
||||
import type { RouterInput, RouterOutput } from "@/integrations/orpc/client";
|
||||
import { jsonPatchOperationSchema } from "@/utils/resume/patch";
|
||||
import schemaJSON from "../src/schema/schema.json";
|
||||
|
||||
// --- Env ---
|
||||
const API_KEY = process.env.REACTIVE_RESUME_API_KEY;
|
||||
const BASE_URL = (process.env.REACTIVE_RESUME_URL ?? "https://rxresu.me").replace(/\/$/, "");
|
||||
const TRANSPORT = process.env.TRANSPORT ?? "stdio";
|
||||
const PORT = Number.parseInt(process.env.PORT ?? "3100", 10);
|
||||
|
||||
if (!API_KEY) {
|
||||
console.error("ERROR: REACTIVE_RESUME_API_KEY is required. Create one in Settings > API Keys.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const apiKey = API_KEY;
|
||||
|
||||
// --- API client ---
|
||||
async function apiRequest<T>(method: string, path: string, body?: unknown): Promise<T> {
|
||||
const url = `${BASE_URL}${path}`;
|
||||
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers: {
|
||||
"x-api-key": apiKey,
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => "Unknown error");
|
||||
throw new Error(`Reactive Resume API error (${res.status}): ${text}`);
|
||||
}
|
||||
|
||||
return res.json() as Promise<T>;
|
||||
}
|
||||
|
||||
async function listResumes(): Promise<RouterOutput["resume"]["list"]> {
|
||||
return apiRequest("GET", "/api/openapi/resumes");
|
||||
}
|
||||
|
||||
async function getResume(id: string): Promise<RouterOutput["resume"]["getById"]> {
|
||||
return apiRequest("GET", `/api/openapi/resumes/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
async function patchResume(id: string, operations: Operation[]): Promise<RouterOutput["resume"]["patch"]> {
|
||||
return apiRequest("PATCH", `/api/openapi/resumes/${encodeURIComponent(id)}`, { operations });
|
||||
}
|
||||
|
||||
async function createResume(input: RouterInput["resume"]["create"]): Promise<RouterOutput["resume"]["create"]> {
|
||||
return apiRequest("POST", "/api/openapi/resumes", input);
|
||||
}
|
||||
|
||||
async function deleteResume(id: string): Promise<RouterOutput["resume"]["delete"]> {
|
||||
return apiRequest("DELETE", `/api/openapi/resumes/${encodeURIComponent(id)}`);
|
||||
}
|
||||
|
||||
async function setResumeLocked(id: string, isLocked: boolean): Promise<RouterOutput["resume"]["setLocked"]> {
|
||||
return apiRequest("POST", `/api/openapi/resumes/${encodeURIComponent(id)}/lock`, { isLocked });
|
||||
}
|
||||
|
||||
// --- MCP server ---
|
||||
const server = new McpServer({ name: "reactive-resume-mcp-server", version: "1.0.0" });
|
||||
|
||||
// Tool: list_resumes
|
||||
server.registerTool(
|
||||
"list_resumes",
|
||||
{
|
||||
title: "List Resumes",
|
||||
description:
|
||||
"List all resumes for the authenticated user. Returns id, name, slug, tags, visibility, lock status, timestamps.",
|
||||
inputSchema: z.object({}).strict(),
|
||||
},
|
||||
async () => {
|
||||
try {
|
||||
const resumes = await listResumes();
|
||||
if (resumes.length === 0)
|
||||
return {
|
||||
content: [{ type: "text", text: "No resumes found. Use create_resume to create one." }],
|
||||
};
|
||||
const lines = [`# Your Resumes (${resumes.length})`, ""];
|
||||
for (const r of resumes) {
|
||||
const tags = r.tags.length > 0 ? ` [${r.tags.join(", ")}]` : "";
|
||||
const flags = [r.isPublic ? "public" : "private", r.isLocked ? "locked" : ""].filter(Boolean).join(", ");
|
||||
lines.push(`- **${r.name}** (${r.id})${tags}`);
|
||||
lines.push(` Status: ${flags} | Updated: ${r.updatedAt}`);
|
||||
}
|
||||
return { content: [{ type: "text", text: lines.join("\n") }] };
|
||||
} catch (error) {
|
||||
return {
|
||||
isError: true,
|
||||
content: [
|
||||
{ type: "text", text: `Error listing resumes: ${error instanceof Error ? error.message : String(error)}` },
|
||||
],
|
||||
};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Tool: get_resume
|
||||
server.registerTool(
|
||||
"get_resume",
|
||||
{
|
||||
title: "Get Resume",
|
||||
description: "Get the full data of a specific resume by ID. Use list_resumes to find IDs.",
|
||||
inputSchema: z.object({ id: z.string().min(1).describe("Resume ID") }).strict(),
|
||||
},
|
||||
async ({ id }: { id: string }) => {
|
||||
try {
|
||||
const resume = await getResume(id);
|
||||
return { content: [{ type: "text", text: JSON.stringify(resume.data, null, 2) }] };
|
||||
} catch (error) {
|
||||
return {
|
||||
isError: true,
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Error getting resume: ${error instanceof Error ? error.message : String(error)}. Use list_resumes to find valid IDs.`,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Tool: patch_resume
|
||||
server.registerTool(
|
||||
"patch_resume",
|
||||
{
|
||||
title: "Patch Resume",
|
||||
description:
|
||||
"Apply JSON Patch (RFC 6902) operations. Use get_resume first to inspect structure. Paths like /basics/name, /sections/skills/items/-.",
|
||||
inputSchema: z
|
||||
.object({
|
||||
id: z.string().min(1).describe("Resume ID"),
|
||||
operations: z.array(jsonPatchOperationSchema).min(1).describe("JSON Patch operations"),
|
||||
})
|
||||
.strict(),
|
||||
},
|
||||
async ({ id, operations }: { id: string; operations: Operation[] }) => {
|
||||
try {
|
||||
const resume = await patchResume(id, operations);
|
||||
const summary = operations.map((op) => `${op.op} ${op.path}`).join(", ");
|
||||
|
||||
return {
|
||||
content: [{ type: "text", text: `Applied ${operations.length} operation(s) to "${resume.name}": ${summary}` }],
|
||||
};
|
||||
} catch (error) {
|
||||
const msg = error instanceof Error ? error.message : String(error);
|
||||
let hint = "";
|
||||
if (msg.includes("400")) hint = " Use get_resume to check structure and paths.";
|
||||
if (msg.includes("403")) hint = " Resume is locked. Use unlock_resume first.";
|
||||
if (msg.includes("404")) hint = " Use list_resumes to find valid IDs.";
|
||||
return { isError: true, content: [{ type: "text", text: `Error patching resume: ${msg}${hint}` }] };
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Tool: create_resume
|
||||
server.registerTool(
|
||||
"create_resume",
|
||||
{
|
||||
title: "Create Resume",
|
||||
description:
|
||||
"Create a new resume with a name, slug, and optional tags. Set withSampleData to true to pre-fill with example content.",
|
||||
inputSchema: z
|
||||
.object({
|
||||
name: z.string().min(1).max(64).describe("Name for the new resume"),
|
||||
slug: z.string().min(1).max(64).describe("URL-friendly slug (must be unique across your resumes)"),
|
||||
tags: z.array(z.string()).optional().default([]).describe("Optional tags to categorize the resume"),
|
||||
withSampleData: z.boolean().optional().default(false).describe("If true, pre-fill the resume with sample data"),
|
||||
})
|
||||
.strict(),
|
||||
},
|
||||
async ({
|
||||
name,
|
||||
slug,
|
||||
tags,
|
||||
withSampleData,
|
||||
}: {
|
||||
name: string;
|
||||
slug: string;
|
||||
tags: string[];
|
||||
withSampleData: boolean;
|
||||
}) => {
|
||||
try {
|
||||
const id = await createResume({ name, slug, tags, withSampleData });
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Created resume "${name}" (${id}) with slug "${slug}".${withSampleData ? " Pre-filled with sample data." : ""} Use get_resume to view or patch_resume to edit it.`,
|
||||
},
|
||||
],
|
||||
};
|
||||
} catch (error) {
|
||||
const msg = error instanceof Error ? error.message : String(error);
|
||||
let hint = "";
|
||||
if (msg.includes("400")) hint = " The slug may already be in use — try a different one.";
|
||||
return { isError: true, content: [{ type: "text", text: `Error creating resume: ${msg}${hint}` }] };
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Tool: delete_resume
|
||||
server.registerTool(
|
||||
"delete_resume",
|
||||
{
|
||||
title: "Delete Resume",
|
||||
description:
|
||||
"Permanently delete a resume and its associated files (screenshots, PDFs). Locked resumes cannot be deleted — unlock first. This action is irreversible.",
|
||||
inputSchema: z
|
||||
.object({
|
||||
id: z.string().min(1).describe("Resume ID to delete. Use list_resumes to find IDs."),
|
||||
})
|
||||
.strict(),
|
||||
},
|
||||
async ({ id }: { id: string }) => {
|
||||
try {
|
||||
await deleteResume(id);
|
||||
|
||||
return { content: [{ type: "text", text: `Successfully deleted resume (${id}) and its associated files.` }] };
|
||||
} catch (error) {
|
||||
const msg = error instanceof Error ? error.message : String(error);
|
||||
let hint = "";
|
||||
if (msg.includes("403")) hint = " The resume may be locked. Use unlock_resume first.";
|
||||
if (msg.includes("404")) hint = " Use list_resumes to find valid IDs.";
|
||||
return { isError: true, content: [{ type: "text", text: `Error deleting resume: ${msg}${hint}` }] };
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Tool: lock_resume
|
||||
server.registerTool(
|
||||
"lock_resume",
|
||||
{
|
||||
title: "Lock Resume",
|
||||
description:
|
||||
"Lock a resume to prevent edits, patches, or deletion. Useful for protecting finalized resumes from accidental changes.",
|
||||
inputSchema: z
|
||||
.object({
|
||||
id: z.string().min(1).describe("Resume ID to lock. Use list_resumes to find IDs."),
|
||||
})
|
||||
.strict(),
|
||||
},
|
||||
async ({ id }: { id: string }) => {
|
||||
try {
|
||||
await setResumeLocked(id, true);
|
||||
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: `Resume (${id}) is now locked. It cannot be edited, patched, or deleted until unlocked.`,
|
||||
},
|
||||
],
|
||||
};
|
||||
} catch (error) {
|
||||
const msg = error instanceof Error ? error.message : String(error);
|
||||
let hint = "";
|
||||
if (msg.includes("404")) hint = " Use list_resumes to find valid IDs.";
|
||||
return { isError: true, content: [{ type: "text", text: `Error locking resume: ${msg}${hint}` }] };
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Tool: unlock_resume
|
||||
server.registerTool(
|
||||
"unlock_resume",
|
||||
{
|
||||
title: "Unlock Resume",
|
||||
description: "Unlock a previously locked resume, allowing edits, patches, and deletion again.",
|
||||
inputSchema: z
|
||||
.object({
|
||||
id: z.string().min(1).describe("Resume ID to unlock. Use list_resumes to find IDs."),
|
||||
})
|
||||
.strict(),
|
||||
},
|
||||
async ({ id }: { id: string }) => {
|
||||
try {
|
||||
await setResumeLocked(id, false);
|
||||
|
||||
return {
|
||||
content: [{ type: "text", text: `Resume (${id}) is now unlocked. It can be edited, patched, and deleted.` }],
|
||||
};
|
||||
} catch (error) {
|
||||
const msg = error instanceof Error ? error.message : String(error);
|
||||
let hint = "";
|
||||
if (msg.includes("404")) hint = " Use list_resumes to find valid IDs.";
|
||||
return { isError: true, content: [{ type: "text", text: `Error unlocking resume: ${msg}${hint}` }] };
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Resource: resume://{id}
|
||||
const resumeTemplate = new ResourceTemplate("resume://{id}", {
|
||||
list: async () => {
|
||||
const resumes = await listResumes();
|
||||
|
||||
return {
|
||||
resources: resumes.map((r) => ({
|
||||
uri: `resume://${r.id}`,
|
||||
name: r.name,
|
||||
mimeType: "application/json" as const,
|
||||
description: `Resume: ${r.name}`,
|
||||
})),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
server.registerResource(
|
||||
"resume",
|
||||
resumeTemplate,
|
||||
{
|
||||
description: "Full resume data as JSON. Use resume://{id} with ID from list_resumes.",
|
||||
mimeType: "application/json",
|
||||
},
|
||||
async (uri: URL) => {
|
||||
const id = uri.href.replace(/^resume:\/\//, "");
|
||||
if (!id) throw new Error("Invalid resume URI: resume://{id}");
|
||||
const resume = await getResume(id);
|
||||
return {
|
||||
contents: [{ uri: uri.href, mimeType: "application/json" as const, text: JSON.stringify(resume.data, null, 2) }],
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
// Resource: resume://schema
|
||||
server.registerResource(
|
||||
"resume-schema",
|
||||
"resume://schema",
|
||||
{
|
||||
description: "Resume Data JSON Schema for generating correct JSON Patch operations.",
|
||||
mimeType: "application/json",
|
||||
},
|
||||
async (uri: URL) => ({
|
||||
contents: [{ uri: uri.href, mimeType: "application/json" as const, text: JSON.stringify(schemaJSON, null, 2) }],
|
||||
}),
|
||||
);
|
||||
|
||||
// --- Transport: stdio (default) ---
|
||||
async function runStdio(): Promise<void> {
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
console.error("Reactive Resume MCP server running via stdio");
|
||||
}
|
||||
|
||||
// --- Transport: HTTP (Node http server) ---
|
||||
function readBody(req: http.IncomingMessage): Promise<unknown> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunks: Buffer[] = [];
|
||||
|
||||
req.on("data", (chunk) => chunks.push(chunk));
|
||||
|
||||
req.on("end", () => {
|
||||
const raw = Buffer.concat(chunks).toString("utf8");
|
||||
if (!raw.trim()) return resolve(undefined);
|
||||
|
||||
try {
|
||||
resolve(JSON.parse(raw));
|
||||
} catch {
|
||||
reject(new Error("Invalid JSON body"));
|
||||
}
|
||||
});
|
||||
|
||||
req.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
async function runHttp(): Promise<void> {
|
||||
const { StreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
||||
|
||||
const httpServer = http.createServer(async (req, res) => {
|
||||
if (req.method !== "POST" || req.url !== "/mcp") {
|
||||
res.writeHead(404, { "Content-Type": "text/plain" });
|
||||
res.end("Not Found");
|
||||
return;
|
||||
}
|
||||
|
||||
let body: unknown;
|
||||
|
||||
try {
|
||||
body = await readBody(req);
|
||||
} catch {
|
||||
res.writeHead(400, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ jsonrpc: "2.0", error: { code: -32700, message: "Parse error" }, id: null }));
|
||||
return;
|
||||
}
|
||||
|
||||
const transport = new StreamableHTTPServerTransport({
|
||||
sessionIdGenerator: undefined,
|
||||
enableJsonResponse: true,
|
||||
});
|
||||
|
||||
res.on("close", () => transport.close());
|
||||
|
||||
await server.connect(transport);
|
||||
await transport.handleRequest(req as never, res as never, body);
|
||||
});
|
||||
|
||||
httpServer.listen(PORT, "127.0.0.1", () => {
|
||||
console.error(`Reactive Resume MCP server running on http://127.0.0.1:${PORT}/mcp`);
|
||||
});
|
||||
}
|
||||
|
||||
if (TRANSPORT === "http") {
|
||||
runHttp().catch((err) => {
|
||||
console.error("Server error:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
} else {
|
||||
runStdio().catch((err) => {
|
||||
console.error("Server error:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
+13
-11
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "reactive-resume",
|
||||
"description": "Reactive Resume is a free and open-source resume builder that simplifies the process of creating, updating, and sharing your resume.",
|
||||
"version": "5.0.6",
|
||||
"version": "5.0.7",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"packageManager": "pnpm@10.29.1+sha512.48dae233635a645768a3028d19545cacc1688639eeb1f3734e42d6d6b971afbf22aa1ac9af52a173d9c3a20c15857cfa400f19994d79a2f626fcc73fccda9bbc",
|
||||
@@ -26,14 +26,15 @@
|
||||
"docs:dev": "cd docs && npx mint dev",
|
||||
"knip": "knip",
|
||||
"lingui:extract": "lingui extract --clean --overwrite",
|
||||
"lint": "biome check --write .",
|
||||
"lint": "biome check --write",
|
||||
"start": "node .output/server/index.mjs",
|
||||
"typecheck": "tsc --noEmit"
|
||||
"typecheck": "tsgo --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "^3.0.38",
|
||||
"@ai-sdk/anthropic": "^3.0.39",
|
||||
"@ai-sdk/google": "^3.0.22",
|
||||
"@ai-sdk/openai": "^3.0.26",
|
||||
"@ai-sdk/react": "^3.0.79",
|
||||
"@aws-sdk/client-s3": "^3.985.0",
|
||||
"@better-auth/core": "1.5.0-beta.13",
|
||||
"@better-auth/passkey": "1.5.0-beta.13",
|
||||
@@ -56,10 +57,10 @@
|
||||
"@sindresorhus/slugify": "^3.0.0",
|
||||
"@t3-oss/env-core": "^0.13.10",
|
||||
"@tanstack/react-query": "5.90.20",
|
||||
"@tanstack/react-router": "^1.158.4",
|
||||
"@tanstack/react-router-ssr-query": "^1.158.4",
|
||||
"@tanstack/react-start": "^1.159.2",
|
||||
"@tanstack/zod-adapter": "^1.158.4",
|
||||
"@tanstack/react-router": "^1.159.3",
|
||||
"@tanstack/react-router-ssr-query": "^1.159.3",
|
||||
"@tanstack/react-start": "^1.159.3",
|
||||
"@tanstack/zod-adapter": "^1.159.3",
|
||||
"@tiptap/extension-highlight": "^3.19.0",
|
||||
"@tiptap/extension-table": "^3.19.0",
|
||||
"@tiptap/extension-text-align": "^3.19.0",
|
||||
@@ -76,6 +77,7 @@
|
||||
"dompurify": "^3.3.1",
|
||||
"drizzle-orm": "^1.0.0-beta.15-859cf75",
|
||||
"drizzle-zod": "^0.8.3",
|
||||
"@modelcontextprotocol/sdk": "^1.26.0",
|
||||
"es-toolkit": "^1.44.0",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-json-patch": "^3.1.1",
|
||||
@@ -127,6 +129,7 @@
|
||||
"@types/pg": "^8.16.0",
|
||||
"@types/react": "^19.2.13",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@typescript/native-preview": "7.0.0-dev.20260208.1",
|
||||
"@vitejs/plugin-react": "^5.1.3",
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"drizzle-kit": "^1.0.0-beta.15-859cf75",
|
||||
@@ -136,13 +139,12 @@
|
||||
"node-gyp": "^12.2.0",
|
||||
"npm-check-updates": "^19.3.2",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "^5.9.3",
|
||||
"vite": "npm:rolldown-vite@latest",
|
||||
"vite": "^8.0.0-beta.13",
|
||||
"vite-plugin-pwa": "^1.2.0"
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"vite": "npm:rolldown-vite@latest"
|
||||
"vite": "^8.0.0-beta.13"
|
||||
},
|
||||
"onlyBuiltDependencies": [
|
||||
"@prisma/engines",
|
||||
|
||||
Generated
+361
-216
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,408 @@
|
||||
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 type { UIMessage } from "ai";
|
||||
import type { Operation } from "fast-json-patch";
|
||||
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;
|
||||
|
||||
// biome-ignore lint/suspicious/noExplicitAny: AI SDK tool parts have dynamic shapes
|
||||
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 font-medium text-[11px]",
|
||||
"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="whitespace-pre-wrap text-[13px] leading-relaxed">
|
||||
{part.text}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
if (part.type === "reasoning" && part.text.trim()) {
|
||||
return (
|
||||
<p key={i} className="whitespace-pre-wrap text-[11px] text-muted-foreground italic leading-relaxed">
|
||||
{part.text}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
if (part.type === "tool-patch_resume") {
|
||||
// biome-ignore lint/suspicious/noExplicitAny: AI SDK tool parts have dynamic shapes
|
||||
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;
|
||||
// biome-ignore lint/suspicious/noExplicitAny: AI SDK tool parts have dynamic shapes
|
||||
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(
|
||||
(e: React.SubmitEvent) => {
|
||||
e.preventDefault();
|
||||
if (!input.trim() || status !== "ready") return;
|
||||
sendMessage({ text: input });
|
||||
setInput("");
|
||||
},
|
||||
[input, status, sendMessage],
|
||||
);
|
||||
|
||||
if (!enabled) return null;
|
||||
|
||||
const isLoading = status === "submitted" || status === "streaming";
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={handleOpenChange}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button size="icon" variant="ghost">
|
||||
<SparkleIcon />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
|
||||
<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="font-medium text-muted-foreground text-xs">
|
||||
<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-muted-foreground text-xs">
|
||||
<Trans>Ask me to update your resume...</Trans>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex flex-col gap-4">
|
||||
{messages.map((message) => (
|
||||
<div key={message.id} className={cn("flex", message.role === "user" ? "justify-end" : "justify-start")}>
|
||||
<div
|
||||
data-role={message.role}
|
||||
className={cn(
|
||||
"max-w-[85%] rounded-xl 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>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{status === "submitted" && (
|
||||
<div className="flex justify-start">
|
||||
<div className="rounded-xl 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>
|
||||
);
|
||||
}
|
||||
@@ -12,17 +12,13 @@ export function CoverLetterItem({ className, ...item }: CoverLetterItemProps) {
|
||||
|
||||
return (
|
||||
<div className={cn("cover-letter-item", className)}>
|
||||
{stripHtml(item.recipient) && (
|
||||
<div className="cover-letter-item-recipient mb-4">
|
||||
<TiptapContent content={item.recipient} />
|
||||
</div>
|
||||
)}
|
||||
<div className={cn("cover-letter-item-recipient mb-4", !stripHtml(item.recipient) && "hidden")}>
|
||||
<TiptapContent content={item.recipient} />
|
||||
</div>
|
||||
|
||||
{stripHtml(item.content) && (
|
||||
<div className="cover-letter-item-content">
|
||||
<TiptapContent content={item.content} />
|
||||
</div>
|
||||
)}
|
||||
<div className={cn("cover-letter-item-content", !stripHtml(item.content) && "hidden")}>
|
||||
<TiptapContent content={item.content} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,15 +17,11 @@ export function SkillsItem({ className, ...item }: SkillsItemProps) {
|
||||
</div>
|
||||
|
||||
{/* Proficiency */}
|
||||
{item.proficiency && (
|
||||
<span className="section-item-metadata skills-item-proficiency inline-block">{item.proficiency}</span>
|
||||
)}
|
||||
{item.proficiency && <div className="section-item-metadata skills-item-proficiency">{item.proficiency}</div>}
|
||||
|
||||
{/* Keywords */}
|
||||
{item.keywords.length > 0 && (
|
||||
<span className="section-item-keywords skills-item-keywords inline-block opacity-80">
|
||||
{item.keywords.join(", ")}
|
||||
</span>
|
||||
<div className="section-item-keywords skills-item-keywords opacity-80">{item.keywords.join(", ")}</div>
|
||||
)}
|
||||
|
||||
{/* Level */}
|
||||
|
||||
@@ -65,7 +65,7 @@ function Header() {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"page-header flex items-center gap-x-(--page-gap-x)",
|
||||
"page-header flex items-center gap-x-(--page-margin-x)",
|
||||
"rounded-(--picture-border-radius) border border-(--page-text-color)/10 bg-(--page-background-color) p-4",
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -43,7 +43,7 @@ function Header() {
|
||||
const basics = useResumeStore((state) => state.resume.data.basics);
|
||||
|
||||
return (
|
||||
<div className="page-header flex items-center gap-x-(--page-gap-x) border-(--page-primary-color) border-b pb-(--page-margin-y)">
|
||||
<div className="page-header flex items-center gap-x-(--page-margin-x) border-(--page-primary-color) border-b pb-(--page-margin-y)">
|
||||
<PagePicture />
|
||||
|
||||
<div className="page-basics space-y-(--page-gap-y)">
|
||||
|
||||
@@ -129,7 +129,7 @@ function Combobox<TValue extends string | number = string>({
|
||||
<CommandGroup>
|
||||
{options.map((option) => {
|
||||
const isSelected = selectedValue === option.value;
|
||||
const isDisabled = option.disabled ?? (false || disabled);
|
||||
const isDisabled = option.disabled ?? disabled;
|
||||
|
||||
return (
|
||||
<CommandItem
|
||||
|
||||
@@ -7,7 +7,7 @@ function ScrollArea({ className, children, ...props }: React.ComponentProps<type
|
||||
<ScrollAreaPrimitive.Root data-slot="scroll-area" className={cn("relative", className)} {...props}>
|
||||
<ScrollAreaPrimitive.Viewport
|
||||
data-slot="scroll-area-viewport"
|
||||
className="size-full rounded-[inherit] outline-none transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
className="[&>div]:block! size-full rounded-[inherit] outline-none transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
>
|
||||
{children}
|
||||
</ScrollAreaPrimitive.Viewport>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
You are an expert resume writer and a specialist in JSON Patch (RFC 6902) operations. Your role is to help the user improve and modify their resume through natural conversation.
|
||||
|
||||
## Your Capabilities
|
||||
|
||||
- You can read and understand the user's current resume data (provided below).
|
||||
- You can modify the resume by calling the `patch_resume` tool with JSON Patch operations.
|
||||
- You can advise on resume best practices, wording, and structure.
|
||||
|
||||
## Rules
|
||||
|
||||
1. **Always use the `patch_resume` tool** to make changes. Never output raw JSON or patch operations in your text response.
|
||||
2. **Generate the minimal set of operations** needed for each change. Do not replace entire objects when only a single field needs updating.
|
||||
3. **Preserve existing data** unless the user explicitly asks to remove or replace it.
|
||||
4. **Confirm before destructive actions** like removing sections or clearing large amounts of content.
|
||||
5. **Stay on topic.** Only discuss resume-related content. Politely decline off-topic requests.
|
||||
6. **Do not fabricate content.** Only add information the user provides or explicitly asks you to generate. If generating content (e.g. a summary), make it clear you are drafting and ask for approval.
|
||||
7. **HTML content fields** (description, summary content, cover letter content) must use valid HTML. Use `<p>` for paragraphs, `<ul>`/`<li>` for lists, `<strong>` for bold, `<em>` for italic.
|
||||
8. **IDs for new items** must be valid UUIDs (use the format `xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`).
|
||||
|
||||
## Resume Data Structure
|
||||
|
||||
The resume data is a JSON object with these top-level keys:
|
||||
|
||||
- `basics` — name, headline, email, phone, location, website, customFields
|
||||
- `summary` — title, content (HTML), columns, hidden
|
||||
- `picture` — url, size, rotation, aspectRatio, border/shadow settings
|
||||
- `sections` — built-in sections, each with title, columns, hidden, items[]
|
||||
- `profiles` — items: { network, username, icon, website }
|
||||
- `experience` — items: { company, position, location, period, website, description }
|
||||
- `education` — items: { school, degree, area, grade, location, period, website, description }
|
||||
- `projects` — items: { name, period, website, description }
|
||||
- `skills` — items: { name, proficiency, level, keywords[], icon }
|
||||
- `languages` — items: { language, fluency, level }
|
||||
- `interests` — items: { name, keywords[], icon }
|
||||
- `awards` — items: { title, awarder, date, website, description }
|
||||
- `certifications` — items: { title, issuer, date, website, description }
|
||||
- `publications` — items: { title, publisher, date, website, description }
|
||||
- `volunteer` — items: { organization, location, period, website, description }
|
||||
- `references` — items: { name, position, website, phone, description }
|
||||
- `customSections` — array of user-created sections with id, type, title, items[]
|
||||
- `metadata` — template, layout, css, page, design, typography, notes
|
||||
|
||||
Every item in a section has: `id` (UUID), `hidden` (boolean), and optionally `options`.
|
||||
Every `website` field is an object: `{ url: string, label: string }`.
|
||||
|
||||
## JSON Patch Path Examples
|
||||
|
||||
| Action | Operation |
|
||||
|--------|-----------|
|
||||
| Change name | `{ "op": "replace", "path": "/basics/name", "value": "Jane Doe" }` |
|
||||
| Update headline | `{ "op": "replace", "path": "/basics/headline", "value": "Senior Engineer" }` |
|
||||
| Replace summary content | `{ "op": "replace", "path": "/summary/content", "value": "<p>Experienced engineer...</p>" }` |
|
||||
| Add experience item | `{ "op": "add", "path": "/sections/experience/items/-", "value": { ...full item object } }` |
|
||||
| Remove skill at index 2 | `{ "op": "remove", "path": "/sections/skills/items/2" }` |
|
||||
| Update a specific item field | `{ "op": "replace", "path": "/sections/experience/items/0/company", "value": "New Corp" }` |
|
||||
| Change template | `{ "op": "replace", "path": "/metadata/template", "value": "bronzor" }` |
|
||||
| Change primary color | `{ "op": "replace", "path": "/metadata/design/colors/primary", "value": "rgba(37, 99, 235, 1)" }` |
|
||||
| Hide a section | `{ "op": "replace", "path": "/sections/interests/hidden", "value": true }` |
|
||||
| Rename a section title | `{ "op": "replace", "path": "/sections/experience/title", "value": "Work History" }` |
|
||||
|
||||
## Current Resume Data
|
||||
|
||||
```json
|
||||
{{RESUME_DATA}}
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { Operation } from "fast-json-patch";
|
||||
import z from "zod";
|
||||
import type { ResumeData } from "@/schema/resume/data";
|
||||
import { applyResumePatches, jsonPatchOperationSchema } from "@/utils/resume/patch";
|
||||
|
||||
export const patchResumeInputSchema = z.object({
|
||||
operations: z
|
||||
.array(jsonPatchOperationSchema)
|
||||
.min(1)
|
||||
.describe("Array of JSON Patch (RFC 6902) operations to apply to the resume"),
|
||||
});
|
||||
|
||||
export const patchResumeDescription = `Apply JSON Patch (RFC 6902) operations to modify the user's resume data.
|
||||
Use this tool whenever the user asks to change, add, or remove content from their resume.
|
||||
Always generate the minimal set of operations needed. Prefer "replace" for updates, "add" for new content, "remove" for deletions.
|
||||
Use the special "-" index to append to arrays (e.g. "/sections/experience/items/-").`;
|
||||
|
||||
export function executePatchResume(resumeData: ResumeData, operations: Operation[]) {
|
||||
// Validates operations structurally and against the schema; throws on invalid
|
||||
applyResumePatches(resumeData, operations);
|
||||
return { success: true as const, appliedOperations: operations };
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { BetterAuthError } from "@better-auth/core/error";
|
||||
import { passkey } from "@better-auth/passkey";
|
||||
import { drizzleAdapter } from "better-auth/adapters/drizzle";
|
||||
import { betterAuth } from "better-auth/minimal";
|
||||
import { apiKey, type GenericOAuthConfig, genericOAuth, twoFactor } from "better-auth/plugins";
|
||||
import { apiKey, type GenericOAuthConfig, genericOAuth, openAPI, twoFactor } from "better-auth/plugins";
|
||||
import { username } from "better-auth/plugins/username";
|
||||
import { tanstackStartCookies } from "better-auth/tanstack-start";
|
||||
import { and, eq, or } from "drizzle-orm";
|
||||
@@ -211,6 +211,7 @@ const getAuthConfig = () => {
|
||||
},
|
||||
|
||||
plugins: [
|
||||
openAPI(),
|
||||
apiKey({
|
||||
enableSessionForAPIKeys: true,
|
||||
rateLimit: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createORPCClient } from "@orpc/client";
|
||||
import { createORPCClient, onError } from "@orpc/client";
|
||||
import { RPCLink } from "@orpc/client/fetch";
|
||||
import { BatchLinkPlugin } from "@orpc/client/plugins";
|
||||
import { BatchLinkPlugin, SimpleCsrfProtectionLinkPlugin } from "@orpc/client/plugins";
|
||||
import { createRouterClient, type InferRouterInputs, type InferRouterOutputs, type RouterClient } from "@orpc/server";
|
||||
import { createTanstackQueryUtils } from "@orpc/tanstack-query";
|
||||
import { createIsomorphicFn } from "@tanstack/react-start";
|
||||
@@ -11,6 +11,11 @@ import { getLocale } from "@/utils/locale";
|
||||
export const getORPCClient = createIsomorphicFn()
|
||||
.server((): RouterClient<typeof router> => {
|
||||
return createRouterClient(router, {
|
||||
interceptors: [
|
||||
onError((error) => {
|
||||
console.error(`ERROR [oRPC]: ${error}`);
|
||||
}),
|
||||
],
|
||||
context: async () => {
|
||||
const locale = await getLocale();
|
||||
const reqHeaders = getRequestHeaders();
|
||||
@@ -25,10 +30,20 @@ export const getORPCClient = createIsomorphicFn()
|
||||
.client((): RouterClient<typeof router> => {
|
||||
const link = new RPCLink({
|
||||
url: `${window.location.origin}/api/rpc`,
|
||||
plugins: [new BatchLinkPlugin({ groups: [{ condition: () => true, context: {} }] })],
|
||||
fetch: (request, init) => {
|
||||
return fetch(request, { ...init, credentials: "include" });
|
||||
},
|
||||
fetch: (request, init) => fetch(request, { ...init, credentials: "include" }),
|
||||
plugins: [
|
||||
new SimpleCsrfProtectionLinkPlugin(),
|
||||
new BatchLinkPlugin({
|
||||
mode: typeof window === "undefined" ? "buffered" : "streaming",
|
||||
groups: [{ condition: () => true, context: {} }],
|
||||
}),
|
||||
],
|
||||
interceptors: [
|
||||
onError((error) => {
|
||||
if (error instanceof DOMException && error.name === "AbortError") return;
|
||||
console.error(`ERROR [oRPC]: ${error}`);
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
return createORPCClient(link);
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
import { ORPCError } from "@orpc/client";
|
||||
import { AISDKError } from "ai";
|
||||
import { type } from "@orpc/server";
|
||||
import { AISDKError, type UIMessage } from "ai";
|
||||
import { OllamaError } from "ai-sdk-ollama";
|
||||
import z, { ZodError } from "zod";
|
||||
import type { ResumeData } from "@/schema/resume/data";
|
||||
import { protectedProcedure } from "../context";
|
||||
import { aiCredentialsSchema, aiProviderSchema, aiService, fileInputSchema, formatZodError } from "../services/ai";
|
||||
|
||||
type AIProvider = z.infer<typeof aiProviderSchema>;
|
||||
|
||||
export const aiRouter = {
|
||||
testConnection: protectedProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/ai/test-connection",
|
||||
tags: ["AI"],
|
||||
operationId: "testAiConnection",
|
||||
summary: "Test AI provider connection",
|
||||
description:
|
||||
"Validates the connection to an AI provider by sending a simple test prompt. Requires the provider type, model name, API key, and an optional base URL. Supported providers: OpenAI, Anthropic, Google Gemini, Ollama, and Vercel AI Gateway. Requires authentication.",
|
||||
successDescription: "The AI provider connection was successful.",
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
provider: aiProviderSchema,
|
||||
@@ -14,11 +29,17 @@ export const aiRouter = {
|
||||
baseURL: z.string(),
|
||||
}),
|
||||
)
|
||||
.errors({
|
||||
BAD_GATEWAY: {
|
||||
message: "The AI provider returned an error or is unreachable.",
|
||||
status: 502,
|
||||
},
|
||||
})
|
||||
.handler(async ({ input }) => {
|
||||
try {
|
||||
return await aiService.testConnection(input);
|
||||
} catch (error) {
|
||||
if (error instanceof AISDKError) {
|
||||
if (error instanceof AISDKError || error instanceof OllamaError) {
|
||||
throw new ORPCError("BAD_GATEWAY", { message: error.message });
|
||||
}
|
||||
|
||||
@@ -27,13 +48,29 @@ export const aiRouter = {
|
||||
}),
|
||||
|
||||
parsePdf: protectedProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/ai/parse-pdf",
|
||||
tags: ["AI"],
|
||||
operationId: "parseResumePdf",
|
||||
summary: "Parse a PDF file into resume data",
|
||||
description:
|
||||
"Extracts structured resume data from a PDF file using the specified AI provider. The file should be sent as a base64-encoded string along with AI provider credentials. Returns a complete ResumeData object. Requires authentication.",
|
||||
successDescription: "The PDF was successfully parsed into structured resume data.",
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
...aiCredentialsSchema.shape,
|
||||
file: fileInputSchema,
|
||||
}),
|
||||
)
|
||||
.handler(async ({ input }) => {
|
||||
.errors({
|
||||
BAD_GATEWAY: {
|
||||
message: "The AI provider returned an error or is unreachable.",
|
||||
status: 502,
|
||||
},
|
||||
})
|
||||
.handler(async ({ input }): Promise<ResumeData> => {
|
||||
try {
|
||||
return await aiService.parsePdf(input);
|
||||
} catch (error) {
|
||||
@@ -49,6 +86,16 @@ export const aiRouter = {
|
||||
}),
|
||||
|
||||
parseDocx: protectedProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/ai/parse-docx",
|
||||
tags: ["AI"],
|
||||
operationId: "parseResumeDocx",
|
||||
summary: "Parse a DOCX file into resume data",
|
||||
description:
|
||||
"Extracts structured resume data from a DOCX or DOC file using the specified AI provider. The file should be sent as a base64-encoded string along with AI provider credentials and the document's media type. Returns a complete ResumeData object. Requires authentication.",
|
||||
successDescription: "The DOCX was successfully parsed into structured resume data.",
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
...aiCredentialsSchema.shape,
|
||||
@@ -59,6 +106,12 @@ export const aiRouter = {
|
||||
]),
|
||||
}),
|
||||
)
|
||||
.errors({
|
||||
BAD_GATEWAY: {
|
||||
message: "The AI provider returned an error or is unreachable.",
|
||||
status: 502,
|
||||
},
|
||||
})
|
||||
.handler(async ({ input }) => {
|
||||
try {
|
||||
return await aiService.parseDocx(input);
|
||||
@@ -71,6 +124,38 @@ export const aiRouter = {
|
||||
throw new Error(formatZodError(error));
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}),
|
||||
|
||||
chat: protectedProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/ai/chat",
|
||||
tags: ["AI"],
|
||||
operationId: "aiChat",
|
||||
summary: "Chat with AI to modify resume",
|
||||
description:
|
||||
"Streams a chat response from the configured AI provider. The LLM can call the patch_resume tool to generate JSON Patch operations that modify the resume. Requires authentication and AI provider credentials.",
|
||||
})
|
||||
.input(
|
||||
type<{
|
||||
provider: AIProvider;
|
||||
model: string;
|
||||
apiKey: string;
|
||||
baseURL: string;
|
||||
messages: UIMessage[];
|
||||
resumeData: ResumeData;
|
||||
}>(),
|
||||
)
|
||||
.handler(async ({ input }) => {
|
||||
try {
|
||||
return await aiService.chat(input);
|
||||
} catch (error) {
|
||||
if (error instanceof AISDKError || error instanceof OllamaError) {
|
||||
throw new ORPCError("BAD_GATEWAY", { message: error.message });
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import z from "zod";
|
||||
import { protectedProcedure, publicProcedure } from "../context";
|
||||
import { authService, type ProviderList } from "../services/auth";
|
||||
|
||||
@@ -7,48 +6,29 @@ export const authRouter = {
|
||||
list: publicProcedure
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/auth/providers/list",
|
||||
path: "/auth/providers",
|
||||
tags: ["Authentication"],
|
||||
summary: "List all auth providers",
|
||||
operationId: "listAuthProviders",
|
||||
summary: "List authentication providers",
|
||||
description:
|
||||
"A list of all authentication providers, and their display names, supported by the instance of Reactive Resume.",
|
||||
"Returns a list of all authentication providers enabled on this Reactive Resume instance, along with their display names. Possible providers include password-based credentials, Google, GitHub, and custom OAuth. No authentication required.",
|
||||
successDescription: "A map of enabled authentication provider identifiers to their display names.",
|
||||
})
|
||||
.handler((): ProviderList => {
|
||||
return authService.providers.list();
|
||||
}),
|
||||
},
|
||||
|
||||
verifyResumePassword: publicProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/auth/verify-resume-password",
|
||||
tags: ["Authentication", "Resume"],
|
||||
summary: "Verify resume password",
|
||||
description: "Verify a resume password, to grant access to the locked resume.",
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
slug: z.string().min(1),
|
||||
username: z.string().min(1),
|
||||
password: z.string().min(1),
|
||||
}),
|
||||
)
|
||||
.output(z.boolean())
|
||||
.handler(async ({ input }): Promise<boolean> => {
|
||||
return await authService.verifyResumePassword({
|
||||
slug: input.slug,
|
||||
username: input.username,
|
||||
password: input.password,
|
||||
});
|
||||
}),
|
||||
|
||||
deleteAccount: protectedProcedure
|
||||
.route({
|
||||
method: "DELETE",
|
||||
path: "/auth/delete-account",
|
||||
path: "/auth/account",
|
||||
tags: ["Authentication"],
|
||||
operationId: "deleteAccount",
|
||||
summary: "Delete user account",
|
||||
description: "Delete the authenticated user's account and all associated data.",
|
||||
description:
|
||||
"Permanently deletes the authenticated user's account, including all resumes, uploaded files (profile pictures, screenshots, PDFs), and associated data. This action is irreversible. Requires authentication.",
|
||||
successDescription: "The user account and all associated data have been successfully deleted.",
|
||||
})
|
||||
.handler(async ({ context }): Promise<void> => {
|
||||
return await authService.deleteAccount({ userId: context.user.id });
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import z from "zod";
|
||||
import { publicProcedure } from "../context";
|
||||
import { type FeatureFlags, flagsService } from "../services/flags";
|
||||
|
||||
@@ -7,8 +8,17 @@ export const flagsRouter = {
|
||||
method: "GET",
|
||||
path: "/flags",
|
||||
tags: ["Feature Flags"],
|
||||
operationId: "getFeatureFlags",
|
||||
summary: "Get feature flags",
|
||||
description: "Returns the current feature flags for this instance.",
|
||||
description:
|
||||
"Returns the current feature flags for this Reactive Resume instance. Feature flags control instance-wide settings such as whether new user signups or email-based authentication are disabled. No authentication required.",
|
||||
successDescription: "The current feature flags for this instance.",
|
||||
})
|
||||
.output(
|
||||
z.object({
|
||||
disableSignups: z.boolean().describe("Whether new user signups are disabled on this instance."),
|
||||
disableEmailAuth: z.boolean().describe("Whether email-based authentication is disabled on this instance."),
|
||||
}),
|
||||
)
|
||||
.handler((): FeatureFlags => flagsService.getFlags()),
|
||||
};
|
||||
|
||||
@@ -7,13 +7,16 @@ export const printerRouter = {
|
||||
printResumeAsPDF: publicProcedure
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/printer/resume/{id}/pdf",
|
||||
tags: ["Resume", "Printer"],
|
||||
path: "/resumes/{id}/pdf",
|
||||
tags: ["Resume Export"],
|
||||
operationId: "exportResumePdf",
|
||||
summary: "Export resume as PDF",
|
||||
description: "Export a resume as a PDF. Returns a URL to download the PDF.",
|
||||
description:
|
||||
"Generates a PDF from the specified resume and uploads it to storage. Returns a URL to download the generated PDF file. If the request is made by an unauthenticated user (e.g. via a public share link), the resume's download count is incremented. Authentication is optional.",
|
||||
successDescription: "The PDF was generated successfully. Returns a URL to download the file.",
|
||||
})
|
||||
.input(z.object({ id: z.string() }))
|
||||
.output(z.object({ url: z.string() }))
|
||||
.input(z.object({ id: z.string().describe("The unique identifier of the resume to export.") }))
|
||||
.output(z.object({ url: z.string().describe("The URL to download the generated PDF file.") }))
|
||||
.handler(async ({ input, context }) => {
|
||||
const { id, data, userId } = await resumeService.getByIdForPrinter({ id: input.id });
|
||||
const url = await printerService.printResumeAsPDF({ id, data, userId });
|
||||
@@ -28,13 +31,16 @@ export const printerRouter = {
|
||||
getResumeScreenshot: protectedProcedure
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/printer/resume/{id}/screenshot",
|
||||
tags: ["Resume", "Printer"],
|
||||
path: "/resumes/{id}/screenshot",
|
||||
tags: ["Resume Export"],
|
||||
operationId: "getResumeScreenshot",
|
||||
summary: "Get resume screenshot",
|
||||
description: "Get a screenshot of a resume. Returns a URL to the screenshot image.",
|
||||
description:
|
||||
"Returns a URL to a screenshot image of the first page of the specified resume. Screenshots are cached for up to 6 hours and regenerated automatically when the resume is updated. Returns null if the screenshot cannot be generated. Requires authentication.",
|
||||
successDescription: "The screenshot URL, or null if the screenshot could not be generated.",
|
||||
})
|
||||
.input(z.object({ id: z.string() }))
|
||||
.output(z.object({ url: z.string().nullable() }))
|
||||
.input(z.object({ id: z.string().describe("The unique identifier of the resume.") }))
|
||||
.output(z.object({ url: z.string().nullable().describe("The URL to the screenshot image, or null.") }))
|
||||
.handler(async ({ input }) => {
|
||||
try {
|
||||
const { id, data, userId, updatedAt } = await resumeService.getByIdForPrinter({ id: input.id });
|
||||
|
||||
@@ -9,10 +9,13 @@ const tagsRouter = {
|
||||
list: protectedProcedure
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/resume/tags/list",
|
||||
tags: ["Resume"],
|
||||
path: "/resumes/tags",
|
||||
tags: ["Resumes"],
|
||||
operationId: "listResumeTags",
|
||||
summary: "List all resume tags",
|
||||
description: "List all tags for the authenticated user's resumes. Used to populate the filter in the dashboard.",
|
||||
description:
|
||||
"Returns a sorted list of all unique tags across the authenticated user's resumes. Useful for populating tag filters in the dashboard. Requires authentication.",
|
||||
successDescription: "A sorted array of unique tag strings.",
|
||||
})
|
||||
.output(z.array(z.string()))
|
||||
.handler(async ({ context }) => {
|
||||
@@ -24,19 +27,22 @@ const statisticsRouter = {
|
||||
getById: protectedProcedure
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/resume/statistics/{id}",
|
||||
tags: ["Resume"],
|
||||
path: "/resumes/{id}/statistics",
|
||||
tags: ["Resume Statistics"],
|
||||
operationId: "getResumeStatistics",
|
||||
summary: "Get resume statistics",
|
||||
description: "Get the statistics for a resume, such as number of views and downloads.",
|
||||
description:
|
||||
"Returns view and download statistics for the specified resume, including total counts and the timestamps of the last view and download. Requires authentication.",
|
||||
successDescription: "The resume's view and download statistics.",
|
||||
})
|
||||
.input(z.object({ id: z.string() }))
|
||||
.input(z.object({ id: z.string().describe("The unique identifier of the resume.") }))
|
||||
.output(
|
||||
z.object({
|
||||
isPublic: z.boolean(),
|
||||
views: z.number(),
|
||||
downloads: z.number(),
|
||||
lastViewedAt: z.date().nullable(),
|
||||
lastDownloadedAt: z.date().nullable(),
|
||||
isPublic: z.boolean().describe("Whether the resume is currently public."),
|
||||
views: z.number().describe("Total number of times the resume has been viewed."),
|
||||
downloads: z.number().describe("Total number of times the resume has been downloaded."),
|
||||
lastViewedAt: z.date().nullable().describe("Timestamp of the last view, or null if never viewed."),
|
||||
lastDownloadedAt: z.date().nullable().describe("Timestamp of the last download, or null if never downloaded."),
|
||||
}),
|
||||
)
|
||||
.handler(async ({ context, input }) => {
|
||||
@@ -44,7 +50,7 @@ const statisticsRouter = {
|
||||
}),
|
||||
|
||||
increment: publicProcedure
|
||||
.route({ tags: ["Internal"], summary: "Increment resume statistics" })
|
||||
.route({ tags: ["Internal"], operationId: "incrementResumeStatistics", summary: "Increment resume statistics" })
|
||||
.input(z.object({ id: z.string(), views: z.boolean().default(false), downloads: z.boolean().default(false) }))
|
||||
.handler(async ({ input }) => {
|
||||
return await resumeService.statistics.increment(input);
|
||||
@@ -58,10 +64,13 @@ export const resumeRouter = {
|
||||
list: protectedProcedure
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/resume/list",
|
||||
tags: ["Resume"],
|
||||
path: "/resumes",
|
||||
tags: ["Resumes"],
|
||||
operationId: "listResumes",
|
||||
summary: "List all resumes",
|
||||
description: "List of all the resumes for the authenticated user.",
|
||||
description:
|
||||
"Returns a list of all resumes belonging to the authenticated user. Results can be filtered by tags and sorted by last updated date, creation date, or name. Resume data is not included in the response for performance; use the get endpoint to fetch full resume data. Requires authentication.",
|
||||
successDescription: "A list of resumes with their metadata (without full resume data).",
|
||||
})
|
||||
.input(resumeDto.list.input.optional().default({ tags: [], sort: "lastUpdatedAt" }))
|
||||
.output(resumeDto.list.output)
|
||||
@@ -76,10 +85,13 @@ export const resumeRouter = {
|
||||
getById: protectedProcedure
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/resume/{id}",
|
||||
tags: ["Resume"],
|
||||
path: "/resumes/{id}",
|
||||
tags: ["Resumes"],
|
||||
operationId: "getResume",
|
||||
summary: "Get resume by ID",
|
||||
description: "Get a resume, along with its data, by its ID.",
|
||||
description:
|
||||
"Returns a single resume with its full data, identified by its unique ID. Only resumes belonging to the authenticated user can be retrieved. Requires authentication.",
|
||||
successDescription: "The resume with its full data.",
|
||||
})
|
||||
.input(resumeDto.getById.input)
|
||||
.output(resumeDto.getById.output)
|
||||
@@ -88,7 +100,7 @@ export const resumeRouter = {
|
||||
}),
|
||||
|
||||
getByIdForPrinter: serverOnlyProcedure
|
||||
.route({ tags: ["Internal"], summary: "Get resume by ID for printer" })
|
||||
.route({ tags: ["Internal"], operationId: "getResumeForPrinter", summary: "Get resume by ID for printer" })
|
||||
.input(resumeDto.getById.input)
|
||||
.handler(async ({ input }) => {
|
||||
return await resumeService.getByIdForPrinter({ id: input.id });
|
||||
@@ -97,10 +109,13 @@ export const resumeRouter = {
|
||||
getBySlug: publicProcedure
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/resume/{username}/{slug}",
|
||||
tags: ["Resume"],
|
||||
summary: "Get resume by username and slug",
|
||||
description: "Get a resume, along with its data, by its username and slug.",
|
||||
path: "/resumes/{username}/{slug}",
|
||||
tags: ["Resume Sharing"],
|
||||
operationId: "getResumeBySlug",
|
||||
summary: "Get public resume by username and slug",
|
||||
description:
|
||||
"Returns a publicly shared resume identified by the owner's username and the resume's slug. If the resume is password-protected and the viewer has not yet verified the password, a 401 error with code NEED_PASSWORD is returned. No authentication required for public resumes; if authenticated as the owner, private resumes are also accessible.",
|
||||
successDescription: "The public resume with its full data.",
|
||||
})
|
||||
.input(resumeDto.getBySlug.input)
|
||||
.output(resumeDto.getBySlug.output)
|
||||
@@ -111,10 +126,13 @@ export const resumeRouter = {
|
||||
create: protectedProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/resume/create",
|
||||
tags: ["Resume"],
|
||||
path: "/resumes",
|
||||
tags: ["Resumes"],
|
||||
operationId: "createResume",
|
||||
summary: "Create a new resume",
|
||||
description: "Create a new resume, with the ability to initialize it with sample data.",
|
||||
description:
|
||||
"Creates a new resume with the given name, slug, and tags. Optionally initializes the resume with sample data by setting withSampleData to true. The slug must be unique across the user's resumes. Returns the ID of the newly created resume. Requires authentication.",
|
||||
successDescription: "The ID of the newly created resume.",
|
||||
})
|
||||
.input(resumeDto.create.input)
|
||||
.output(resumeDto.create.output)
|
||||
@@ -138,10 +156,13 @@ export const resumeRouter = {
|
||||
import: protectedProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/resume/import",
|
||||
tags: ["Resume"],
|
||||
path: "/resumes/import",
|
||||
tags: ["Resumes"],
|
||||
operationId: "importResume",
|
||||
summary: "Import a resume",
|
||||
description: "Import a resume from a file.",
|
||||
description:
|
||||
"Creates a new resume from an existing ResumeData object (e.g. from a previously exported JSON file). A random name and slug are generated automatically. Returns the ID of the imported resume. Requires authentication.",
|
||||
successDescription: "The ID of the imported resume.",
|
||||
})
|
||||
.input(resumeDto.import.input)
|
||||
.output(resumeDto.import.output)
|
||||
@@ -168,10 +189,13 @@ export const resumeRouter = {
|
||||
update: protectedProcedure
|
||||
.route({
|
||||
method: "PUT",
|
||||
path: "/resume/{id}",
|
||||
tags: ["Resume"],
|
||||
path: "/resumes/{id}",
|
||||
tags: ["Resumes"],
|
||||
operationId: "updateResume",
|
||||
summary: "Update a resume",
|
||||
description: "Update a resume, along with its data, by its ID.",
|
||||
description:
|
||||
"Updates one or more fields of a resume identified by its ID. All fields are optional; only provided fields will be updated. Locked resumes cannot be updated. Requires authentication.",
|
||||
successDescription: "The updated resume with its full data.",
|
||||
})
|
||||
.input(resumeDto.update.input)
|
||||
.output(resumeDto.update.output)
|
||||
@@ -196,11 +220,13 @@ export const resumeRouter = {
|
||||
patch: protectedProcedure
|
||||
.route({
|
||||
method: "PATCH",
|
||||
path: "/resume/{id}",
|
||||
tags: ["Resume"],
|
||||
summary: "Patch a resume",
|
||||
path: "/resumes/{id}",
|
||||
tags: ["Resumes"],
|
||||
operationId: "patchResume",
|
||||
summary: "Patch resume data",
|
||||
description:
|
||||
"Apply JSON Patch (RFC 6902) operations to partially update a resume's data. This allows you to make small, targeted changes without sending the entire resume object.",
|
||||
"Applies JSON Patch (RFC 6902) operations to partially update a resume's data. This allows small, targeted changes (e.g. updating a single field) without sending the entire resume object. Locked resumes cannot be patched. Requires authentication.",
|
||||
successDescription: "The patched resume with its full data.",
|
||||
})
|
||||
.input(resumeDto.patch.input)
|
||||
.output(resumeDto.patch.output)
|
||||
@@ -221,10 +247,13 @@ export const resumeRouter = {
|
||||
setLocked: protectedProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/resume/{id}/set-locked",
|
||||
tags: ["Resume"],
|
||||
summary: "Set resume locked status",
|
||||
description: "Toggle the locked status of a resume, by its ID.",
|
||||
path: "/resumes/{id}/lock",
|
||||
tags: ["Resumes"],
|
||||
operationId: "setResumeLocked",
|
||||
summary: "Set resume lock status",
|
||||
description:
|
||||
"Toggles the locked status of a resume. When locked, a resume cannot be updated, patched, or deleted. Useful for protecting finalized resumes from accidental edits. Requires authentication.",
|
||||
successDescription: "The resume lock status was updated successfully.",
|
||||
})
|
||||
.input(resumeDto.setLocked.input)
|
||||
.output(resumeDto.setLocked.output)
|
||||
@@ -238,11 +267,14 @@ export const resumeRouter = {
|
||||
|
||||
setPassword: protectedProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/resume/{id}/set-password",
|
||||
tags: ["Resume"],
|
||||
summary: "Set password on a resume",
|
||||
description: "Set a password on a resume to protect it from unauthorized access when shared publicly.",
|
||||
method: "PUT",
|
||||
path: "/resumes/{id}/password",
|
||||
tags: ["Resume Sharing"],
|
||||
operationId: "setResumePassword",
|
||||
summary: "Set resume password",
|
||||
description:
|
||||
"Sets or updates a password on a resume. When a password is set, viewers of the public resume must enter the password before the resume data is revealed. The password must be between 6 and 64 characters. Requires authentication.",
|
||||
successDescription: "The resume password was set successfully.",
|
||||
})
|
||||
.input(resumeDto.setPassword.input)
|
||||
.output(resumeDto.setPassword.output)
|
||||
@@ -254,13 +286,43 @@ export const resumeRouter = {
|
||||
});
|
||||
}),
|
||||
|
||||
removePassword: protectedProcedure
|
||||
verifyPassword: publicProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/resume/{id}/remove-password",
|
||||
tags: ["Resume"],
|
||||
summary: "Remove password from a resume",
|
||||
description: "Remove password protection from a resume.",
|
||||
path: "/resumes/{username}/{slug}/password/verify",
|
||||
tags: ["Resume Sharing"],
|
||||
operationId: "verifyResumePassword",
|
||||
summary: "Verify resume password",
|
||||
description:
|
||||
"Verifies a password for a password-protected public resume. On success, the viewer is granted access to view the resume data for the duration of their session. No authentication required.",
|
||||
successDescription: "The password was verified successfully and access has been granted.",
|
||||
})
|
||||
.input(
|
||||
z.object({
|
||||
username: z.string().min(1).describe("The username of the resume owner."),
|
||||
slug: z.string().min(1).describe("The slug of the resume."),
|
||||
password: z.string().min(1).describe("The password to verify."),
|
||||
}),
|
||||
)
|
||||
.output(z.boolean())
|
||||
.handler(async ({ input }): Promise<boolean> => {
|
||||
return await resumeService.verifyPassword({
|
||||
username: input.username,
|
||||
slug: input.slug,
|
||||
password: input.password,
|
||||
});
|
||||
}),
|
||||
|
||||
removePassword: protectedProcedure
|
||||
.route({
|
||||
method: "DELETE",
|
||||
path: "/resumes/{id}/password",
|
||||
tags: ["Resume Sharing"],
|
||||
operationId: "removeResumePassword",
|
||||
summary: "Remove resume password",
|
||||
description:
|
||||
"Removes password protection from a resume. After removal, the resume (if public) can be viewed without entering a password. Requires authentication.",
|
||||
successDescription: "The resume password was removed successfully.",
|
||||
})
|
||||
.input(resumeDto.removePassword.input)
|
||||
.output(resumeDto.removePassword.output)
|
||||
@@ -274,10 +336,13 @@ export const resumeRouter = {
|
||||
duplicate: protectedProcedure
|
||||
.route({
|
||||
method: "POST",
|
||||
path: "/resume/{id}/duplicate",
|
||||
tags: ["Resume"],
|
||||
path: "/resumes/{id}/duplicate",
|
||||
tags: ["Resumes"],
|
||||
operationId: "duplicateResume",
|
||||
summary: "Duplicate a resume",
|
||||
description: "Duplicate a resume, by its ID.",
|
||||
description:
|
||||
"Creates a copy of an existing resume with the same data. Optionally override the name, slug, and tags for the duplicate. If not provided, the original resume's name, slug, and tags are used. Returns the ID of the duplicated resume. Requires authentication.",
|
||||
successDescription: "The ID of the duplicated resume.",
|
||||
})
|
||||
.input(resumeDto.duplicate.input)
|
||||
.output(resumeDto.duplicate.output)
|
||||
@@ -297,10 +362,13 @@ export const resumeRouter = {
|
||||
delete: protectedProcedure
|
||||
.route({
|
||||
method: "DELETE",
|
||||
path: "/resume/{id}",
|
||||
tags: ["Resume"],
|
||||
path: "/resumes/{id}",
|
||||
tags: ["Resumes"],
|
||||
operationId: "deleteResume",
|
||||
summary: "Delete a resume",
|
||||
description: "Delete a resume, by its ID.",
|
||||
description:
|
||||
"Permanently deletes a resume and its associated files (screenshots, PDFs) from storage. Locked resumes cannot be deleted; unlock the resume first. Requires authentication.",
|
||||
successDescription: "The resume and its associated files were deleted successfully.",
|
||||
})
|
||||
.input(resumeDto.delete.input)
|
||||
.output(resumeDto.delete.output)
|
||||
|
||||
@@ -6,12 +6,15 @@ const userRouter = {
|
||||
getCount: publicProcedure
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/statistics/user/count",
|
||||
tags: ["Statistics"],
|
||||
path: "/statistics/users",
|
||||
tags: ["Platform Statistics"],
|
||||
operationId: "getUserCount",
|
||||
summary: "Get total number of users",
|
||||
description: "Get the total number of users for the Reactive Resume.",
|
||||
description:
|
||||
"Returns the total number of registered users on this Reactive Resume instance. The count is cached for up to 6 hours for performance. No authentication required.",
|
||||
successDescription: "The total number of registered users.",
|
||||
})
|
||||
.output(z.number())
|
||||
.output(z.number().describe("The total number of registered users."))
|
||||
.handler(async (): Promise<number> => {
|
||||
return await statisticsService.user.getCount();
|
||||
}),
|
||||
@@ -21,12 +24,15 @@ const resumeRouter = {
|
||||
getCount: publicProcedure
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/statistics/resume/count",
|
||||
tags: ["Statistics"],
|
||||
path: "/statistics/resumes",
|
||||
tags: ["Platform Statistics"],
|
||||
operationId: "getResumeCount",
|
||||
summary: "Get total number of resumes",
|
||||
description: "Get the total number of resumes for the Reactive Resume.",
|
||||
description:
|
||||
"Returns the total number of resumes created on this Reactive Resume instance. The count is cached for up to 6 hours for performance. No authentication required.",
|
||||
successDescription: "The total number of resumes created.",
|
||||
})
|
||||
.output(z.number())
|
||||
.output(z.number().describe("The total number of resumes created."))
|
||||
.handler(async (): Promise<number> => {
|
||||
return await statisticsService.resume.getCount();
|
||||
}),
|
||||
@@ -37,11 +43,14 @@ const githubRouter = {
|
||||
.route({
|
||||
method: "GET",
|
||||
path: "/statistics/github/stars",
|
||||
tags: ["Statistics"],
|
||||
summary: "Get GitHub Repository stargazers count",
|
||||
description: "Get the stargazers count for the Reactive Resume GitHub repository, at the time of writing.",
|
||||
tags: ["Platform Statistics"],
|
||||
operationId: "getGitHubStarCount",
|
||||
summary: "Get GitHub star count",
|
||||
description:
|
||||
"Returns the number of GitHub stars for the Reactive Resume repository. The count is cached for up to 6 hours and falls back to a last-known value if the GitHub API is unavailable. No authentication required.",
|
||||
successDescription: "The number of GitHub stars for the Reactive Resume repository.",
|
||||
})
|
||||
.output(z.number())
|
||||
.output(z.number().describe("The number of GitHub stars."))
|
||||
.handler(async (): Promise<number> => {
|
||||
return await statisticsService.github.getStarCount();
|
||||
}),
|
||||
|
||||
@@ -7,17 +7,26 @@ const storageService = getStorageService();
|
||||
|
||||
const fileSchema = z.file().max(10 * 1024 * 1024, "File size must be less than 10MB");
|
||||
|
||||
const filenameSchema = z.object({ filename: z.string().min(1) });
|
||||
const filenameSchema = z.object({
|
||||
filename: z.string().min(1).describe("The path or filename of the file to delete."),
|
||||
});
|
||||
|
||||
export const storageRouter = {
|
||||
uploadFile: protectedProcedure
|
||||
.route({ tags: ["Internal"], summary: "Upload a file" })
|
||||
.route({
|
||||
tags: ["Internal"],
|
||||
operationId: "uploadFile",
|
||||
summary: "Upload a file",
|
||||
description:
|
||||
"Uploads a file to storage. Images are automatically resized and converted to WebP format. Maximum file size is 10MB. Requires authentication.",
|
||||
successDescription: "The file was uploaded successfully.",
|
||||
})
|
||||
.input(fileSchema)
|
||||
.output(
|
||||
z.object({
|
||||
url: z.string(),
|
||||
path: z.string(),
|
||||
contentType: z.string(),
|
||||
url: z.string().describe("The public URL to access the uploaded file."),
|
||||
path: z.string().describe("The storage path of the uploaded file."),
|
||||
contentType: z.string().describe("The MIME type of the uploaded file."),
|
||||
}),
|
||||
)
|
||||
.handler(async ({ context, input: file }) => {
|
||||
@@ -52,9 +61,22 @@ export const storageRouter = {
|
||||
}),
|
||||
|
||||
deleteFile: protectedProcedure
|
||||
.route({ tags: ["Internal"], summary: "Delete a file" })
|
||||
.route({
|
||||
tags: ["Internal"],
|
||||
operationId: "deleteFile",
|
||||
summary: "Delete a file",
|
||||
description:
|
||||
"Deletes a file from storage by its filename or path. If the filename does not start with 'uploads/', the user's picture directory is assumed. Requires authentication.",
|
||||
successDescription: "The file was deleted successfully.",
|
||||
})
|
||||
.input(filenameSchema)
|
||||
.output(z.void())
|
||||
.errors({
|
||||
NOT_FOUND: {
|
||||
message: "The specified file was not found in storage.",
|
||||
status: 404,
|
||||
},
|
||||
})
|
||||
.handler(async ({ context, input }): Promise<void> => {
|
||||
// The filename is now the full path from the URL (e.g., "uploads/userId/pictures/timestamp.webp")
|
||||
// We need to extract just the path portion that matches the storage key
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
import { createAnthropic } from "@ai-sdk/anthropic";
|
||||
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
||||
import { createOpenAI } from "@ai-sdk/openai";
|
||||
import { createGateway, generateText, Output } from "ai";
|
||||
import { streamToEventIterator } from "@orpc/server";
|
||||
import {
|
||||
convertToModelMessages,
|
||||
createGateway,
|
||||
generateText,
|
||||
Output,
|
||||
stepCountIs,
|
||||
streamText,
|
||||
tool,
|
||||
type UIMessage,
|
||||
} from "ai";
|
||||
import { createOllama } from "ai-sdk-ollama";
|
||||
import { match } from "ts-pattern";
|
||||
import type { ZodError } from "zod";
|
||||
import z, { flattenError } from "zod";
|
||||
import chatSystemPromptTemplate from "@/integrations/ai/prompts/chat-system.md?raw";
|
||||
import docxParserSystemPrompt from "@/integrations/ai/prompts/docx-parser-system.md?raw";
|
||||
import docxParserUserPrompt from "@/integrations/ai/prompts/docx-parser-user.md?raw";
|
||||
import pdfParserSystemPrompt from "@/integrations/ai/prompts/pdf-parser-system.md?raw";
|
||||
import pdfParserUserPrompt from "@/integrations/ai/prompts/pdf-parser-user.md?raw";
|
||||
import {
|
||||
executePatchResume,
|
||||
patchResumeDescription,
|
||||
patchResumeInputSchema,
|
||||
} from "@/integrations/ai/tools/patch-resume";
|
||||
import type { ResumeData } from "@/schema/resume/data";
|
||||
import { defaultResumeData, resumeDataSchema } from "@/schema/resume/data";
|
||||
|
||||
@@ -141,8 +157,39 @@ export function formatZodError(error: ZodError): string {
|
||||
return JSON.stringify(flattenError(error));
|
||||
}
|
||||
|
||||
function buildChatSystemPrompt(resumeData: ResumeData): string {
|
||||
return chatSystemPromptTemplate.replace("{{RESUME_DATA}}", JSON.stringify(resumeData, null, 2));
|
||||
}
|
||||
|
||||
type ChatInput = z.infer<typeof aiCredentialsSchema> & {
|
||||
messages: UIMessage[];
|
||||
resumeData: ResumeData;
|
||||
};
|
||||
|
||||
async function chat(input: ChatInput) {
|
||||
const model = getModel(input);
|
||||
const systemPrompt = buildChatSystemPrompt(input.resumeData);
|
||||
|
||||
const result = streamText({
|
||||
model,
|
||||
system: systemPrompt,
|
||||
messages: await convertToModelMessages(input.messages),
|
||||
tools: {
|
||||
patch_resume: tool({
|
||||
description: patchResumeDescription,
|
||||
inputSchema: patchResumeInputSchema,
|
||||
execute: async ({ operations }) => executePatchResume(input.resumeData, operations),
|
||||
}),
|
||||
},
|
||||
stopWhen: stepCountIs(3),
|
||||
});
|
||||
|
||||
return streamToEventIterator(result.toUIMessageStream());
|
||||
}
|
||||
|
||||
export const aiService = {
|
||||
testConnection,
|
||||
parsePdf,
|
||||
parseDocx,
|
||||
chat,
|
||||
};
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { ORPCError } from "@orpc/client";
|
||||
import { and, eq, isNotNull } from "drizzle-orm";
|
||||
import { eq } from "drizzle-orm";
|
||||
import type { AuthProvider } from "@/integrations/auth/types";
|
||||
import { schema } from "@/integrations/drizzle";
|
||||
import { db } from "@/integrations/drizzle/client";
|
||||
import { env } from "@/utils/env";
|
||||
import { verifyPassword } from "@/utils/password";
|
||||
import { grantResumeAccess } from "../helpers/resume-access";
|
||||
import { getStorageService } from "./storage";
|
||||
|
||||
export type ProviderList = Partial<Record<AuthProvider, string>>;
|
||||
@@ -25,31 +23,6 @@ const providers = {
|
||||
export const authService = {
|
||||
providers,
|
||||
|
||||
verifyResumePassword: async (input: { slug: string; username: string; password: string }): Promise<boolean> => {
|
||||
const [resume] = await db
|
||||
.select({ id: schema.resume.id, password: schema.resume.password })
|
||||
.from(schema.resume)
|
||||
.innerJoin(schema.user, eq(schema.resume.userId, schema.user.id))
|
||||
.where(
|
||||
and(
|
||||
isNotNull(schema.resume.password),
|
||||
eq(schema.resume.slug, input.slug),
|
||||
eq(schema.user.username, input.username),
|
||||
),
|
||||
);
|
||||
|
||||
if (!resume) throw new ORPCError("NOT_FOUND");
|
||||
|
||||
const passwordHash = resume.password as string;
|
||||
const isValid = await verifyPassword(input.password, passwordHash);
|
||||
|
||||
if (!isValid) throw new ORPCError("INVALID_PASSWORD");
|
||||
|
||||
grantResumeAccess(resume.id, passwordHash);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
deleteAccount: async (input: { userId: string }): Promise<void> => {
|
||||
if (!input.userId || input.userId.length === 0) return;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ORPCError } from "@orpc/client";
|
||||
import { and, arrayContains, asc, desc, eq, sql } from "drizzle-orm";
|
||||
import { and, arrayContains, asc, desc, eq, isNotNull, sql } from "drizzle-orm";
|
||||
import { get } from "es-toolkit/compat";
|
||||
import type { Operation } from "fast-json-patch";
|
||||
import { match } from "ts-pattern";
|
||||
@@ -9,10 +9,10 @@ import type { ResumeData } from "@/schema/resume/data";
|
||||
import { defaultResumeData } from "@/schema/resume/data";
|
||||
import { env } from "@/utils/env";
|
||||
import type { Locale } from "@/utils/locale";
|
||||
import { hashPassword } from "@/utils/password";
|
||||
import { hashPassword, verifyPassword } from "@/utils/password";
|
||||
import { applyResumePatches, ResumePatchError } from "@/utils/resume/patch";
|
||||
import { generateId } from "@/utils/string";
|
||||
import { hasResumeAccess } from "../helpers/resume-access";
|
||||
import { grantResumeAccess, hasResumeAccess } from "../helpers/resume-access";
|
||||
import { getStorageService } from "./storage";
|
||||
|
||||
const tags = {
|
||||
@@ -383,6 +383,31 @@ export const resumeService = {
|
||||
.where(and(eq(schema.resume.id, input.id), eq(schema.resume.userId, input.userId)));
|
||||
},
|
||||
|
||||
verifyPassword: async (input: { slug: string; username: string; password: string }) => {
|
||||
const [resume] = await db
|
||||
.select({ id: schema.resume.id, password: schema.resume.password })
|
||||
.from(schema.resume)
|
||||
.innerJoin(schema.user, eq(schema.resume.userId, schema.user.id))
|
||||
.where(
|
||||
and(
|
||||
isNotNull(schema.resume.password),
|
||||
eq(schema.resume.slug, input.slug),
|
||||
eq(schema.user.username, input.username),
|
||||
),
|
||||
);
|
||||
|
||||
if (!resume) throw new ORPCError("NOT_FOUND");
|
||||
|
||||
const passwordHash = resume.password as string;
|
||||
const isValid = await verifyPassword(input.password, passwordHash);
|
||||
|
||||
if (!isValid) throw new ORPCError("INVALID_PASSWORD");
|
||||
|
||||
grantResumeAccess(resume.id, passwordHash);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
removePassword: async (input: { id: string; userId: string }) => {
|
||||
await db
|
||||
.update(schema.resume)
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import { auth } from "@/integrations/auth/config";
|
||||
|
||||
function handler({ request }: { request: Request }) {
|
||||
async function handler({ request }: { request: Request }) {
|
||||
if (request.method === "GET" && request.url.endsWith("/spec.json")) {
|
||||
const spec = await auth.api.generateOpenAPISchema();
|
||||
|
||||
return Response.json(spec);
|
||||
}
|
||||
|
||||
return auth.handler(request);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,25 +2,28 @@ import { SmartCoercionPlugin } from "@orpc/json-schema";
|
||||
import { OpenAPIGenerator } from "@orpc/openapi";
|
||||
import { OpenAPIHandler } from "@orpc/openapi/fetch";
|
||||
import { onError } from "@orpc/server";
|
||||
import { RequestHeadersPlugin } from "@orpc/server/plugins";
|
||||
import { BatchHandlerPlugin, RequestHeadersPlugin, StrictGetMethodPlugin } from "@orpc/server/plugins";
|
||||
import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import router from "@/integrations/orpc/router";
|
||||
import { resumeDataSchema } from "@/schema/resume/data";
|
||||
import { env } from "@/utils/env";
|
||||
import { getLocale } from "@/utils/locale";
|
||||
|
||||
const openAPIHandler = new OpenAPIHandler(router, {
|
||||
plugins: [
|
||||
new BatchHandlerPlugin(),
|
||||
new RequestHeadersPlugin(),
|
||||
new StrictGetMethodPlugin(),
|
||||
new SmartCoercionPlugin({
|
||||
schemaConverters: [new ZodToJsonSchemaConverter()],
|
||||
}),
|
||||
],
|
||||
interceptors: [
|
||||
onError((error) => {
|
||||
console.error(`ERROR [OpenAPI]: ${error}`);
|
||||
}),
|
||||
],
|
||||
plugins: [
|
||||
new RequestHeadersPlugin(),
|
||||
new SmartCoercionPlugin({
|
||||
schemaConverters: [new ZodToJsonSchemaConverter()],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const openAPIGenerator = new OpenAPIGenerator({
|
||||
@@ -34,13 +37,16 @@ async function handler({ request }: { request: Request }) {
|
||||
const spec = await openAPIGenerator.generate(router, {
|
||||
info: {
|
||||
title: "Reactive Resume",
|
||||
version: "5.0.0",
|
||||
version: __APP_VERSION__,
|
||||
description: "Reactive Resume API",
|
||||
license: { name: "MIT", url: "https://github.com/amruthpillai/reactive-resume/blob/main/LICENSE" },
|
||||
contact: { name: "Amruth Pillai", email: "hello@amruthpillai.com", url: "https://amruthpillai.com" },
|
||||
},
|
||||
servers: [{ url: `${env.APP_URL}/api/openapi` }],
|
||||
externalDocs: { url: "https://docs.rxresu.me", description: "Reactive Resume Documentation" },
|
||||
commonSchemas: {
|
||||
ResumeData: { schema: resumeDataSchema },
|
||||
},
|
||||
components: {
|
||||
securitySchemes: {
|
||||
apiKey: {
|
||||
|
||||
+12
-2
@@ -1,17 +1,27 @@
|
||||
import { onError } from "@orpc/server";
|
||||
import { RPCHandler } from "@orpc/server/fetch";
|
||||
import { BatchHandlerPlugin, RequestHeadersPlugin } from "@orpc/server/plugins";
|
||||
import {
|
||||
BatchHandlerPlugin,
|
||||
RequestHeadersPlugin,
|
||||
SimpleCsrfProtectionHandlerPlugin,
|
||||
StrictGetMethodPlugin,
|
||||
} from "@orpc/server/plugins";
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import router from "@/integrations/orpc/router";
|
||||
import { getLocale } from "@/utils/locale";
|
||||
|
||||
const rpcHandler = new RPCHandler(router, {
|
||||
plugins: [
|
||||
new BatchHandlerPlugin(),
|
||||
new RequestHeadersPlugin(),
|
||||
new StrictGetMethodPlugin(),
|
||||
new SimpleCsrfProtectionHandlerPlugin(),
|
||||
],
|
||||
interceptors: [
|
||||
onError((error) => {
|
||||
console.error(`ERROR [oRPC]: ${error}`);
|
||||
}),
|
||||
],
|
||||
plugins: [new BatchHandlerPlugin(), new RequestHeadersPlugin()],
|
||||
});
|
||||
|
||||
async function handler({ request }: { request: Request }) {
|
||||
|
||||
@@ -44,7 +44,7 @@ function RouteComponent() {
|
||||
const { redirect } = Route.useSearch();
|
||||
const [showPassword, toggleShowPassword] = useToggle(false);
|
||||
|
||||
const { mutate: verifyPassword } = useMutation(orpc.auth.verifyResumePassword.mutationOptions());
|
||||
const { mutate: verifyPassword } = useMutation(orpc.resume.verifyPassword.mutationOptions());
|
||||
|
||||
const [username, slug] = useMemo(() => {
|
||||
const [username, slug] = redirect.split("/").slice(1) as [string, string];
|
||||
|
||||
@@ -19,6 +19,7 @@ import { useHotkeys } from "react-hotkeys-hook";
|
||||
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";
|
||||
@@ -121,6 +122,7 @@ 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
|
||||
|
||||
@@ -107,11 +107,11 @@ function BuilderLayout({ initialLayout, ...props }: BuilderLayoutProps) {
|
||||
>
|
||||
<BuilderSidebarLeft />
|
||||
</ResizablePanel>
|
||||
<ResizableSeparator withHandle className="z-20 border-s" />
|
||||
<ResizableSeparator withHandle className="z-50 border-s" />
|
||||
<ResizablePanel id="artboard" defaultSize={artboardSize} className="h-[calc(100svh-3.5rem)]">
|
||||
<Outlet />
|
||||
</ResizablePanel>
|
||||
<ResizableSeparator withHandle className="z-20 border-e" />
|
||||
<ResizableSeparator withHandle className="z-50 border-e" />
|
||||
<ResizablePanel
|
||||
collapsible
|
||||
id="right"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -169,18 +169,3 @@
|
||||
break-inside: avoid;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix for ScrollArea viewport width overflow */
|
||||
[data-slot="scroll-area-viewport"] > div {
|
||||
box-sizing: border-box !important;
|
||||
display: block !important;
|
||||
width: 100% !important;
|
||||
min-width: 0 !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
[data-slot="scroll-area-viewport"] {
|
||||
box-sizing: border-box !important;
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
|
||||
+1
-1
@@ -64,7 +64,7 @@ export function generateRandomName() {
|
||||
* @param html - The HTML string to strip.
|
||||
* @returns The text content without HTML tags.
|
||||
*/
|
||||
export function stripHtml(html: string | undefined) {
|
||||
export function stripHtml(html: string | undefined): string {
|
||||
if (!html) return "";
|
||||
return html.replace(/<[^>]*>/g, "").trim();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"noUncheckedSideEffectImports": false,
|
||||
|
||||
/* Paths */
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user