feat(i18n): sync editor translations with pluralization support and new UI strings (#6565)

# Description of Changes

## What was changed

- Updated editor translation files across multiple locales.
- Migrated numerous count-based translation keys from legacy
`{{plural}}` handling to ICU-style plural forms using `_one`, `_other`,
and where applicable `_zero` variants.
- Added translations and localization keys for newly introduced features
and UI areas, including:
  - Stirling Agents
  - Chat interface and quick actions
  - Files management and folder organization
  - Desktop update workflow
  - Folder scanning warnings
  - Team and workspace management
  - Sharing and upload dialogs
  - Comparison status messages
  - Relative time formatting
  - Additional tool panel and update UI strings
- Added missing translation entries required by recently introduced
frontend functionality.
- Reorganized some translation sections to maintain consistency and key
ordering.

## Why the change was made

- To align locale files with the current frontend feature set.
- To support proper pluralization behavior across languages.
- To prevent missing translation keys and fallback text in newly added
UI components.
- To improve localization consistency and maintainability as the
application grows.

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
This commit is contained in:
Ludy
2026-06-19 10:34:55 +00:00
committed by GitHub
parent e6d476297d
commit f8ceca0c3f
51 changed files with 36420 additions and 61672 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -17,10 +17,12 @@ confirmCloseConfirm = "Close File"
confirmCloseDiscard = "Discard changes and close"
confirmCloseMessage = "Are you sure you want to close this file?"
confirmCloseSave = "Save and close"
confirmCloseSaveFailed = "Saved with errors. {{count}} file{{plural}} could not be saved."
confirmCloseSaveFailed_one = "Saved with errors. {{count}} file could not be saved."
confirmCloseSaveFailed_other = "Saved with errors. {{count}} files could not be saved."
confirmCloseSaveFailedTitle = "Save Failed"
confirmCloseUnsaved = "This file has unsaved changes."
confirmCloseUnsavedList = "You have {{count}} file{{plural}} with unsaved changes.\n\n{{fileList}}"
confirmCloseUnsavedList_one = "You have {{count}} file with unsaved changes.\n\n{{fileList}}"
confirmCloseUnsavedList_other = "You have {{count}} files with unsaved changes.\n\n{{fileList}}"
custom = "Custom..."
customPosition = "Custom Position"
customTextTooltip = "Optional custom format for page numbers. Use {n} as placeholder for the number. Example: \"Page {n}\" will show \"Page 1\", \"Page 2\", etc."
@@ -33,8 +35,8 @@ downloadUnavailable = "Download unavailable for this item"
edit = "Edit"
editSecret = "Edit this value"
editYourNewFiles = "Edit your new file(s)"
encryptedFileBlocked = "File is password-protected. Unlock it first."
encryptedFilesBlocked = "{{count}} files are password-protected. Unlock them first."
encryptedFilesBlocked_one = "File is password-protected. Unlock it first."
encryptedFilesBlocked_other = "{{count}} files are password-protected. Unlock them first."
exportAndContinue = "Export & Continue"
false = "False"
fileNotSavedToDisk = "Not saved to disk"
@@ -1516,12 +1518,18 @@ title = "Feedback Messages"
[admin.settings.telegram.feedback.channel]
title = "Channel Feedback Rules"
errorMessage.description = "Show detailed error messages for channels."
errorMessage.label = "Show error messages (Channel)"
errorProcessing.description = "Send processing error messages to channels."
errorProcessing.label = "Show processing errors (Channel)"
noValidDocument.description = "Suppress the no valid document response for channel uploads."
noValidDocument.label = "Show \"No valid document\" (Channel)"
[admin.settings.telegram.feedback.channel.errorMessage]
description = "Show detailed error messages for channels."
label = "Show error messages (Channel)"
[admin.settings.telegram.feedback.channel.errorProcessing]
description = "Send processing error messages to channels."
label = "Show processing errors (Channel)"
[admin.settings.telegram.feedback.channel.noValidDocument]
description = "Suppress the no valid document response for channel uploads."
label = "Show \"No valid document\" (Channel)"
[admin.settings.telegram.feedback.general.enabled]
description = "Control whether the bot sends feedback messages at all."
@@ -1529,12 +1537,18 @@ label = "Enable Feedback"
[admin.settings.telegram.feedback.user]
title = "User Feedback Rules"
errorMessage.description = "Show detailed error messages for users."
errorMessage.label = "Show error messages (User)"
errorProcessing.description = "Send processing error messages to users."
errorProcessing.label = "Show processing errors (User)"
noValidDocument.description = "Suppress the no valid document response for user uploads."
noValidDocument.label = "Show \"No valid document\" (User)"
[admin.settings.telegram.feedback.user.errorMessage]
description = "Show detailed error messages for users."
label = "Show error messages (User)"
[admin.settings.telegram.feedback.user.errorProcessing]
description = "Send processing error messages to users."
label = "Show processing errors (User)"
[admin.settings.telegram.feedback.user.noValidDocument]
description = "Suppress the no valid document response for user uploads."
label = "Show \"No valid document\" (User)"
[admin.settings.telegram.pipelineInboxFolder]
description = "Folder under the pipeline directory where incoming Telegram files are stored."
@@ -1575,30 +1589,7 @@ admin = "Admin"
title = "User Control Settings"
[agents]
auto_redaction_description = "Redact PII automatically"
auto_redaction_name = "Auto Redaction"
back_to_tools = "Back to tools"
coming_soon = "Coming soon"
compliance_description = "Audit documents for compliance"
compliance_name = "Compliance Check"
data_extraction_description = "Extract tables & structured data"
data_extraction_name = "Data Extraction"
doc_summary_description = "Summarise long documents"
doc_summary_name = "Summariser"
form_filler_description = "Fill PDF forms intelligently"
form_filler_name = "Form Filler"
pdf_to_markdown_description = "Convert PDFs to clean Markdown"
pdf_to_markdown_name = "PDF to Markdown"
section_title = "Agents"
show_less = "Show less"
start_chat = "Start chatting"
stirling_description = "Your general-purpose PDF assistant"
stirling_full_name = "Stirling General Agent"
stirling_long_description = "General purpose PDF assistant that can run tools, create PDFs and extract insights from your documents."
stirling_name = "Stirling"
stirling_running = "Running..."
stirling_tooltip = "Stirling agent"
view_all = "View all agents"
[analytics]
learnMore = "Learn more about our analytics"
@@ -1843,7 +1834,8 @@ desc = "Build multi-step workflows by chaining together PDF actions. Ideal for r
export = "Export"
exportForFolderScanning = "Export for Folder Scanning"
import = "Import"
importPartialSuccess = "Imported with {{count}} unmapped operation(s): {{ops}}"
importPartialSuccess_one = "Imported with {{count}} unmapped operation: {{ops}}"
importPartialSuccess_other = "Imported with {{count}} unmapped operations: {{ops}}"
importSuccess = "Imported automation: {{name}}"
invalidStep = "Invalid step"
reviewTitle = "Automation Results"
@@ -1903,7 +1895,8 @@ dropHint = "Drop JSON here or click to choose a file"
dropSubhint = "Both Automate and Folder Scanning configs are accepted"
dropzoneAriaLabel = "Drop an automation JSON file here"
intro = "Drop a JSON file or paste its contents below. The format (Automate or Folder Scanning) is detected automatically."
opCount = "{{count}} operation(s)"
opCount_one = "{{count}} operation"
opCount_other = "{{count}} operations"
parseError = "Could not parse: {{message}}"
pasteLabel = "Or paste JSON"
pastePlaceholder = "Paste your automation JSON here…"
@@ -1929,7 +1922,8 @@ title = "Suggested"
finish = "Finish"
run = "Run Automation"
running = "Running Automation..."
steps = "{{count}} steps"
steps_one = "{{count}} step"
steps_other = "{{count}} steps"
unnamed = "Unnamed Automation"
[automation.suggested]
@@ -2259,7 +2253,8 @@ title = "Which option should I use?"
stepTitle = "Certificate Format"
[certSign.collab.addParticipants]
add = "Add {{count}} Participant(s)"
add_one = "Add {{count}} Participant"
add_other = "Add {{count}} Participants"
reasonHelp = "Pre-set a signing reason for these participants (optional, they can override when signing)"
reasonPlaceholder = "e.g. Approval, Review..."
@@ -2372,7 +2367,8 @@ certInvalidFallback = "Invalid certificate"
certNetworkError = "Could not validate certificate"
certValidating = "Validating certificate..."
certValidUntil = "Certificate valid until {{date}}"
description = "You have placed {{count}} signature(s). Choose your certificate to complete signing."
description_one = "You have placed {{count}} signature. Choose your certificate to complete signing."
description_other = "You have placed {{count}} signatures. Choose your certificate to complete signing."
sign = "Sign Document"
title = "Configure Certificate"
@@ -2678,9 +2674,6 @@ title = "Change Permissions"
[changePermissions.tooltip.warning]
text = "To make these permissions unchangeable, use the Add Password tool to set an owner password."
[chat]
resize = "Resize chat panel"
[chat.actions]
copy = "Copy message"
@@ -2706,11 +2699,9 @@ executing_tool_single = "Running {{tool}}..."
executing_tool_step = "Running {{tool}} (step {{step}} of {{total}})..."
extracting_content = "Extracting content from your documents..."
processing = "Processing extracted content..."
ranForMinutes = "Ran for {{count}} minutes"
ranForMinutes_one = "Ran for 1 minute"
ranForMinutes_other = "Ran for {{count}} minutes"
ranForMinutesSeconds = "Ran for {{minutes}} min, {{seconds}} sec"
ranForSeconds = "Ran for {{count}} seconds"
ranForSeconds_one = "Ran for 1 second"
ranForSeconds_other = "Ran for {{count}} seconds"
thinking = "Thinking..."
@@ -2743,7 +2734,8 @@ unsupported_capability = "Unsupported capability: {{capability}}"
usage_limit_reached = "You've reached your usage limit. Check your plan options to keep going."
[chat.toolsUsed]
summary = "Ran {{count}} tools"
summary_one = "Ran 1 tool"
summary_other = "Ran {{count}} tools"
unknownTool = "Unknown tool"
[cloudBadge]
@@ -3211,10 +3203,6 @@ description = "These cookies are essential for the website to function properly.
posthog = "PostHog Analytics"
scarf = "Scarf Pixel"
[credits]
[credits.insufficient]
[credits.modal]
advancedMonitoring = "Advanced monitoring"
allInOneWorkspace = "All-in-one PDF workspace (viewer, tools & agent)"
@@ -3444,7 +3432,8 @@ title = "Remove password to continue"
unlock = "Unlock & Continue"
unlockAll = "Use for all ({{count}})"
unlockAllPartialFail = "Wrong password for: {{names}}"
unlockAllSuccess = "Unlocked {{count}} file(s)."
unlockAllSuccess_one = "Unlocked {{count}} file."
unlockAllSuccess_other = "Unlocked {{count}} files."
unlockPrompt = "Unlock PDF to continue"
viewerLocked = "This PDF is password-protected"
viewerUnlock = "Unlock"
@@ -3640,6 +3629,7 @@ workbench = "Workbench"
addFiles = "Add files"
collapse = "Collapse sidebar"
dropHint = "Open files to get started"
dropToAdd = "Drop files to add"
expand = "Expand sidebar"
files = "Files"
googleDrive = "Google Drive"
@@ -3679,20 +3669,25 @@ create = "Create"
cycleBlocked = "Can't move a folder into one of its own subfolders."
delete = "Delete"
deleteFilesChoiceBody = "Some of these files are saved both on this device and in the cloud. Where should they be deleted from?"
deleteFilesCloudBody = "Delete {{count}} file(s) from the cloud? This cannot be undone."
deleteFilesCloudBody_one = "Delete 1 file from the cloud? This cannot be undone."
deleteFilesCloudBody_other = "Delete {{count}} files from the cloud? This cannot be undone."
deleteFilesError = "Could not delete. Try again."
deleteFilesLocalBody = "Delete {{count}} file(s) from this device? This cannot be undone."
deleteFilesTitle = "Delete {{count}} file(s)?"
deleteFilesLocalBody_one = "Delete 1 file from this device? This cannot be undone."
deleteFilesLocalBody_other = "Delete {{count}} files from this device? This cannot be undone."
deleteFilesTitle_one = "Delete 1 file?"
deleteFilesTitle_other = "Delete {{count}} files?"
deleteFolder = "Delete folder"
deleteFolderBody = "Delete folder \"{{name}}\"?"
deleteFolderContents = "Also delete {{count}} file(s) inside the folder"
deleteFolderContents_one = "Also delete {{count}} file inside the folder"
deleteFolderContents_other = "Also delete {{count}} files inside the folder"
deleteFolderContentsWarning = "Files will be permanently removed and cannot be recovered."
deleteFolderError = "Could not delete the folder. Try again."
deleteFolderKeepHint = "Files inside will be moved to All files."
deleteFolderTitle = "Delete folder?"
deselectAll = "Clear selection"
details = "Details"
detailsCount = "{{count}} files selected"
detailsCount_one = "{{count}} file selected"
detailsCount_other = "{{count}} files selected"
dismissError = "Dismiss"
download = "Download"
downloadAll = "Download all"
@@ -3703,14 +3698,16 @@ file = "File"
fileInfo = "File info"
fileMenu = "File actions"
folder = "Folder"
folderItems = "{{count}} items"
folderItems_one = "{{count}} item"
folderItems_other = "{{count}} items"
folderMenu = "Folder actions"
inPath = "in {{path}}"
inWorkspace = "Open"
inWorkspaceAria = "Already in workspace"
loading = "Loading…"
localFoldersUnavailable = "Folders are cloud-only - save a file to the cloud to organise it."
moveSkippedRemote = "{{count}} file(s) couldn't be moved on the server (no permission or already deleted)."
moveSkippedRemote_one = "{{count}} file couldn't be moved on the server (no permission or already deleted)."
moveSkippedRemote_other = "{{count}} files couldn't be moved on the server (no permission or already deleted)."
moveTo = "Move to…"
myFiles = "My Files"
newFolder = "New folder"
@@ -3739,7 +3736,8 @@ shareDisabledHint = "File sharing isn't enabled on this server. Ask your admin t
shareManage = "Manage sharing"
showDetails = "Show details"
signInRequired = "Sign in to use cloud storage."
summary = "{{count}} items"
summary_one = "{{count}} item"
summary_other = "{{count}} items"
tree = "Folders"
upload = "Upload"
uploadedToLocal = "Uploaded files start in Local. Use 'Save to cloud' to put them in a folder."
@@ -3752,111 +3750,154 @@ versionOrigin = "Original upload"
versionsCount = "{{count}} versions"
versionShowHidden = "Show {{count}} earlier versions"
viewVersionHistory = "Version journey ({{count}})"
appearance.colour = "Colour"
appearance.icon = "Icon"
appearance.title = "Appearance"
appearance.useColour = "Use colour {{c}}"
column.modified = "Modified"
column.name = "Name"
column.size = "Size"
column.type = "Type"
deleteScope.cloud = "Cloud only"
deleteScope.cloudHint = "Deletes from the server. A copy stays on this device."
deleteScope.device = "This device only"
deleteScope.deviceHint = "Removes the local copy. The cloud copy is kept."
deleteScope.everywhere = "Everywhere"
deleteScope.everywhereHint = "Deletes the file from this device and the cloud."
empty.hint = "Drop PDFs anywhere on this page to upload, or use the New folder button to organise your files."
empty.newFolderCta = "Create folder"
empty.title = "This folder is empty"
empty.uploadCta = "Upload files"
empty.cloud.hint = "Upload a file to start, or create a folder to organise."
empty.cloud.offlineHint = "Reconnect to load your cloud library."
empty.cloud.offlineTitle = "No cached cloud files"
empty.cloud.title = "No cloud files yet"
empty.local.hint = "Files saved without uploading stay here. Drop a file to add one."
empty.local.title = "No local-only files"
empty.recent.hint = "Files you open or edit will appear here."
empty.recent.title = "Nothing modified yet"
empty.shared.hint = "When someone shares a file via link, it appears here."
empty.shared.title = "Nothing shared with you"
empty.sharedByMe.hint = "Create a share link or invite a teammate from any of your files to see it here."
empty.sharedByMe.title = "You haven't shared any files yet"
error.actionFailed = "Could not {{action}}."
error.actionFailedDetail = "Could not {{action}}: {{message}}"
error.cloudDeleteFailed = "Couldn't delete {{count}} file(s) from the cloud."
error.deleteFolderFailed = "Could not delete folder."
error.deleteFolderFailedDetail = "Could not delete folder: {{message}}"
error.folderAppearanceFailed = "Could not update folder appearance."
error.folderAppearanceFailedDetail = "Could not update folder appearance: {{message}}"
error.moveFilesFailed = "Could not move files."
error.moveFilesFailedDetail = "Could not move files: {{message}}"
error.moveFolderFailed = "Could not move folder."
error.moveFolderFailedDetail = "Could not move folder: {{message}}"
error.removeFilesFailed = "Could not remove files."
error.removeFilesFailedDetail = "Could not remove files: {{message}}"
error.uploadFilesFailed = "Could not upload files."
error.uploadFilesFailedDetail = "Could not upload files: {{message}}"
field.added = "Added"
field.count = "Files"
field.folder = "Folder"
field.modified = "Modified"
field.name = "Name"
field.size = "Size"
field.toolHistory = "Tool history"
field.toolHistoryAtVersion = "Cumulative tool chain"
field.totalSize = "Total size"
field.type = "Type"
field.versionHistory = "Version journey"
folderName.cancel = "Cancel"
folderName.error = "Could not save folder. Try again."
folderName.label = "Folder name"
folderName.placeholder = "Folder name"
moveDialog.cancel = "Cancel"
moveDialog.confirm = "Move here"
moveDialog.error = "Could not move. Try again."
moveDialog.hint = "Pick a destination folder. Tip: you can also drag and drop files onto folders in the tree on the left."
moveDialog.newFolderCancel = "Discard"
moveDialog.newFolderCreate = "Create"
moveDialog.newFolderError = "Could not create folder. Try again."
moveDialog.newFolderLabel = "New folder name"
moveDialog.newFolderPlaceholder = "Folder name"
moveDialog.newFolderToggle = "Create new folder…"
moveDialog.title = "Move to folder"
origin.all = "All sources"
origin.cloud = "Cloud"
origin.cloudHint = "Stored on the Stirling server"
origin.local = "Local"
origin.localHint = "Only stored in this browser"
origin.shared = "Shared"
origin.sharedHint = "Shared with you via link"
sort.modifiedAsc = "Oldest first"
sort.modifiedDesc = "Recent first"
sort.nameAsc = "Name A→Z"
sort.nameDesc = "Name Z→A"
sort.sizeAsc = "Smallest first"
sort.sizeDesc = "Largest first"
syncError.client = "Folder sync failed."
syncError.network = "Could not reach the server."
syncError.server = "Server error during folder sync."
tabName.local = "Local"
tabName.recent = "Recent"
tabName.shared = "Shared with me"
tabName.sharedByMe = "Shared by me"
tabs.all = "All"
tabs.ariaLabel = "File views"
tabs.recent = "Recent"
tabs.shared = "Shared with me"
tabs.sharedByMe = "Shared by me"
treeMenu.actions = "Folder actions for {{name}}"
treeMenu.delete = "Delete folder"
treeMenu.newSubfolder = "New subfolder"
treeMenu.rename = "Rename"
typeFilter.allTypes = "All types"
typeFilter.label = "Filter by type"
viewMode.grid = "Grid view"
viewMode.label = "View mode"
viewMode.list = "List view"
[filesPage.appearance]
colour = "Colour"
icon = "Icon"
title = "Appearance"
useColour = "Use colour {{c}}"
[filesPage.column]
modified = "Modified"
name = "Name"
size = "Size"
type = "Type"
[filesPage.deleteScope]
cloud = "Cloud only"
cloudHint = "Deletes from the server. A copy stays on this device."
device = "This device only"
deviceHint = "Removes the local copy. The cloud copy is kept."
everywhere = "Everywhere"
everywhereHint = "Deletes the file from this device and the cloud."
[filesPage.empty]
hint = "Drop PDFs anywhere on this page to upload, or use the New folder button to organise your files."
newFolderCta = "Create folder"
title = "This folder is empty"
uploadCta = "Upload files"
[filesPage.empty.cloud]
hint = "Upload a file to start, or create a folder to organise."
offlineHint = "Reconnect to load your cloud library."
offlineTitle = "No cached cloud files"
title = "No cloud files yet"
[filesPage.empty.local]
hint = "Files saved without uploading stay here. Drop a file to add one."
title = "No local-only files"
[filesPage.empty.recent]
hint = "Files you open or edit will appear here."
title = "Nothing modified yet"
[filesPage.empty.shared]
hint = "When someone shares a file via link, it appears here."
title = "Nothing shared with you"
[filesPage.empty.sharedByMe]
hint = "Create a share link or invite a teammate from any of your files to see it here."
title = "You haven't shared any files yet"
[filesPage.error]
actionFailed = "Could not {{action}}."
actionFailedDetail = "Could not {{action}}: {{message}}"
cloudDeleteFailed_one = "Couldn't delete 1 file from the cloud."
cloudDeleteFailed_other = "Couldn't delete {{count}} files from the cloud."
deleteFolderFailed = "Could not delete folder."
deleteFolderFailedDetail = "Could not delete folder: {{message}}"
folderAppearanceFailed = "Could not update folder appearance."
folderAppearanceFailedDetail = "Could not update folder appearance: {{message}}"
moveFilesFailed = "Could not move files."
moveFilesFailedDetail = "Could not move files: {{message}}"
moveFolderFailed = "Could not move folder."
moveFolderFailedDetail = "Could not move folder: {{message}}"
removeFilesFailed = "Could not remove files."
removeFilesFailedDetail = "Could not remove files: {{message}}"
uploadFilesFailed = "Could not upload files."
uploadFilesFailedDetail = "Could not upload files: {{message}}"
[filesPage.field]
added = "Added"
count = "Files"
folder = "Folder"
modified = "Modified"
name = "Name"
size = "Size"
toolHistory = "Tool history"
toolHistoryAtVersion = "Cumulative tool chain"
totalSize = "Total size"
type = "Type"
versionHistory = "Version journey"
[filesPage.folderName]
cancel = "Cancel"
error = "Could not save folder. Try again."
label = "Folder name"
placeholder = "Folder name"
[filesPage.moveDialog]
cancel = "Cancel"
confirm = "Move here"
error = "Could not move. Try again."
hint = "Pick a destination folder. Tip: you can also drag and drop files onto folders in the tree on the left."
newFolderCancel = "Discard"
newFolderCreate = "Create"
newFolderError = "Could not create folder. Try again."
newFolderLabel = "New folder name"
newFolderPlaceholder = "Folder name"
newFolderToggle = "Create new folder…"
title = "Move to folder"
[filesPage.origin]
all = "All sources"
cloud = "Cloud"
cloudHint = "Stored on the Stirling server"
local = "Local"
localHint = "Only stored in this browser"
shared = "Shared"
sharedHint = "Shared with you via link"
[filesPage.sort]
modifiedAsc = "Oldest first"
modifiedDesc = "Recent first"
nameAsc = "Name A→Z"
nameDesc = "Name Z→A"
sizeAsc = "Smallest first"
sizeDesc = "Largest first"
[filesPage.syncError]
client = "Folder sync failed."
network = "Could not reach the server."
server = "Server error during folder sync."
[filesPage.tabName]
local = "Local"
recent = "Recent"
shared = "Shared with me"
sharedByMe = "Shared by me"
[filesPage.tabs]
all = "All"
ariaLabel = "File views"
recent = "Recent"
shared = "Shared with me"
sharedByMe = "Shared by me"
[filesPage.treeMenu]
actions = "Folder actions for {{name}}"
delete = "Delete folder"
newSubfolder = "New subfolder"
rename = "Rename"
[filesPage.typeFilter]
allTypes = "All types"
label = "Filter by type"
[filesPage.viewMode]
grid = "Grid view"
label = "View mode"
list = "List view"
[fileToPDF]
tags = "transformation,format,document,picture,slide,text,conversion,office,docs,word,excel,powerpoint"
@@ -4027,7 +4068,8 @@ pages = "Pages"
pdfVersion = "PDF Version"
permsAll = "All Permissions Allowed"
permsMixed = "Some permissions restricted"
permsRestricted = "{{count}} restrictions"
permsRestricted_one = "{{count}} restriction"
permsRestricted_other = "{{count}} restrictions"
securityTitle = "Security Status"
technical = "Technical"
title = "PDF Summary"
@@ -4075,7 +4117,8 @@ location = "Location:"
logo = "Logo:"
logoHidden = "No logo"
logoShown = "Stirling PDF logo shown"
participantCount = "{{count}} participant(s) will sign in order"
participantCount_one = "{{count}} participant will sign in order"
participantCount_other = "{{count}} participants will sign in order"
participants = "Participants"
reason = "Reason:"
send = "Send Signing Requests"
@@ -4093,7 +4136,8 @@ title = "Select Document"
[groupSigning.steps.selectParticipants]
continue = "Continue to Signature Settings"
count = "{{count}} participant(s) selected"
count_one = "{{count}} participant selected"
count_other = "{{count}} participants selected"
label = "Select participants"
placeholder = "Choose participants to sign..."
title = "Choose Participants"
@@ -4689,7 +4733,8 @@ descriptionNoConvert = "Scan to upload photos from your mobile device."
error = "Connection Error"
expiryWarning = "Session Expiring Soon"
expiryWarningMessage = "This QR code will expire in {{seconds}} seconds. A new code will be generated automatically."
filesReceived = "{{count}} file(s) received"
filesReceived_one = "{{count}} file received"
filesReceived_other = "{{count}} files received"
instructions = "Scan with your phone camera. Images convert to PDF automatically."
instructionsNoConvert = "Scan with your phone camera to upload files."
pollingError = "Error checking for files"
@@ -5204,11 +5249,6 @@ toggle = "What counts as a PDF?"
body = "We couldn't reach the billing service. Refresh the page to try again."
title = "Couldn't load your plan"
[payg.exhausted]
body = "You've used all 500 of your free PDFs. Upgrade to Processor to keep going."
cta = "Go to billing"
title = "You've used your free PDFs"
[payg.free.cta]
benefit1Body = "chain tools, schedule runs, batch process"
benefit1Title = "Automation pipelines"
@@ -5802,11 +5842,6 @@ keyDescription = "Paste the licence key from your email"
success = "Licence Activated!"
successMessage = "Your licence has been successfully activated. You can now close this window."
[plan.team]
[plan.trial]
message = ""
[policies]
deleteConfirmBody = "This removes the policy and its workflow. Documents already processed are not affected."
deleteConfirmTitle = "Delete {{label}} policy?"
@@ -6768,6 +6803,7 @@ theme = "Theme"
themeDark = "Dark"
themeDescription = "Switch between light and dark mode"
themeLight = "Light"
themeSystem = "System"
title = "General"
user = "User"
@@ -6903,7 +6939,9 @@ trial = "Trial"
[settings.planBilling.team]
managedByTeam = "Managed by team"
memberCount = "{{count}} team members"
memberCount_one = "{{count}} team member"
memberCount_other = "{{count}} team members"
memberCount_zero = "no team members"
[settings.planBilling.tier]
enterprise = "Enterprise"
@@ -7481,7 +7519,8 @@ errorTitle = "Share failed"
expiredBody = "This share link is invalid or has expired."
expiredTitle = "Link expired"
failure = "Unable to generate a share link. Please try again."
fileCount = "{{count}} files"
fileCount_one = "{{count}} file"
fileCount_other = "{{count}} files"
fileLabel = "File"
generate = "Generate Link"
generated = "Share link generated"
@@ -7543,7 +7582,8 @@ description = "This uploads the current file to server storage for your own acce
errorTitle = "Upload failed"
failure = "Upload failed. Please check your login and storage settings."
featureDisabled = "Saving to the server isn't enabled on this server."
fileCount = "{{count}} files"
fileCount_one = "{{count}} file"
fileCount_other = "{{count}} files"
fileLabel = "File"
hint = "Public links and access modes are controlled by your server settings."
more = " +{{count}} more"
@@ -7552,6 +7592,9 @@ title = "Upload to Server"
updateButton = "Update on Server"
uploadButton = "Upload to Server"
[survey]
title = "Stirling-PDF Survey"
[swagger]
tags = "api,documentation,swagger,endpoints,development"
title = "API Documentation"
@@ -7574,7 +7617,9 @@ leaveButton = "Leave Team"
leaveError = "Failed to leave team"
leaveSuccess = "Successfully left team"
loading = "Loading team information..."
memberCount = "{{count}} members"
memberCount_one = "{{count}} member"
memberCount_other = "{{count}} members"
memberCount_zero = "no members"
memberRemoved = "Member removed successfully"
namePlaceholder = "Enter team name"
personal = "Personal"
@@ -7892,8 +7937,10 @@ generatedAt = "Generated"
noPdf = "PDF report will be available after a successful validation."
page = "Page"
shortTitle = "Signature Summary"
signatureCountLabel = "{{count}} signatures"
signaturesFound = "{{count}} signatures detected"
signatureCountLabel_one = "{{count}} signature"
signatureCountLabel_other = "{{count}} signatures"
signaturesFound_one = "{{count}} signature detected"
signaturesFound_other = "{{count}} signatures detected"
signaturesValid = "{{count}} fully valid"
title = "Signature Validation Report"
@@ -7958,8 +8005,8 @@ goToLink = "Go to link"
hint = "Place comments with the Comment, Insert Text, or Replace Text tools. They will appear here by page."
locateAnnotation = "Locate in document"
moreActions = "More actions"
nComments = "{{count}} comments"
oneComment = "1 comment"
nComments_one = "{{count}} comment"
nComments_other = "{{count}} comments"
pageLabel = "Page {{page}}"
removeCommentOnly = "Remove comment only"
saveReply = "Save reply"
@@ -8436,7 +8483,6 @@ loading = "Loading people..."
locked = "locked"
lockedBadge = "Locked"
loginRequired = "Enable login mode first"
member = "Member"
noMembersFound = "No members found"
role = "Role"
searchMembers = "Search members..."
@@ -8499,14 +8545,14 @@ success = "Password updated successfully"
title = "Change password"
[workspace.people.editMember]
editing = "Editing:"
editing = "Editing: <0>{{username}}</0>"
error = "Failed to update user"
role = "Role"
submit = "Update Member"
submit = "Update User"
success = "User updated successfully"
team = "Team (Optional)"
teamPlaceholder = "Select a team"
title = "Edit Member"
title = "Edit User"
[workspace.people.emailInvite]
allFailed = "Failed to invite users"
@@ -8547,9 +8593,11 @@ currentUsage = "Currently using {{current}} of {{max}} user licences"
fromLicense = "from licence"
grandfathered = "Grandfathered"
grandfatheredShort = "{{count}} grandfathered"
noSlotsAvailable = "No slots available"
slotsAvailable = "{{count}} user slot(s) available"
users = "users"
slotsAvailable_one = "{{count}} user slot available"
slotsAvailable_other = "{{count}} user slots available"
slotsAvailable_zero = "No slots available"
users_one = "user"
users_other = "users"
[workspace.people.mfa]
adminDisableError = "Failed to disable MFA for user"
@@ -8557,9 +8605,8 @@ adminDisableSuccess = "MFA disabled successfully for user"
disableByAdmin = "Disable MFA"
[workspace.people.roleDescriptions]
admin = "Can manage settings and invite members, with full administrative access."
member = "Can view and edit shared files, but cannot manage workspace settings or members."
user = "User"
admin = "Can manage settings and invite users, with full administrative access."
user = "Can view and edit shared files, but cannot manage workspace settings or users."
[workspace.people.toggleEnabled]
error = "Failed to update user status"
@@ -8579,7 +8626,9 @@ description = "Manage teams and organise workspace members"
loadError = "Failed to load team details"
loading = "Loading teams..."
loadingDetails = "Loading team details..."
memberCount = "{{count}} members"
memberCount_one = "{{count}} member"
memberCount_other = "{{count}} members"
memberCount_zero = "no members"
noMembers = "No members in this team"
noTeamsFound = "No teams found"
removeMember = "Remove from team"
@@ -8643,5 +8692,6 @@ title = "Rename Team"
[zipWarning]
cancel = "Cancel"
confirm = "Extract"
message = "This ZIP contains {{count}} files. Extract anyway?"
message_one = "This ZIP contains {{count}} file. Extract anyway?"
message_other = "This ZIP contains {{count}} files. Extract anyway?"
title = "Large ZIP File"
@@ -17,10 +17,12 @@ confirmCloseConfirm = "Close File"
confirmCloseDiscard = "Discard changes and close"
confirmCloseMessage = "Are you sure you want to close this file?"
confirmCloseSave = "Save and close"
confirmCloseSaveFailed = "Saved with errors. {{count}} file{{plural}} could not be saved."
confirmCloseSaveFailed_one = "Saved with errors. {{count}} file could not be saved."
confirmCloseSaveFailed_other = "Saved with errors. {{count}} files could not be saved."
confirmCloseSaveFailedTitle = "Save Failed"
confirmCloseUnsaved = "This file has unsaved changes."
confirmCloseUnsavedList = "You have {{count}} file{{plural}} with unsaved changes.\n\n{{fileList}}"
confirmCloseUnsavedList_one = "You have {{count}} file with unsaved changes.\n\n{{fileList}}"
confirmCloseUnsavedList_other = "You have {{count}} files with unsaved changes.\n\n{{fileList}}"
custom = "Custom..."
customPosition = "Custom Position"
customTextTooltip = "Optional custom format for page numbers. Use {n} as placeholder for the number. Example: \"Page {n}\" will show \"Page 1\", \"Page 2\", etc."
@@ -33,8 +35,8 @@ downloadUnavailable = "Download unavailable for this item"
edit = "Edit"
editSecret = "Edit this value"
editYourNewFiles = "Edit your new file(s)"
encryptedFileBlocked = "File is password-protected. Unlock it first."
encryptedFilesBlocked = "{{count}} files are password-protected. Unlock them first."
encryptedFilesBlocked_one = "File is password-protected. Unlock it first."
encryptedFilesBlocked_other = "{{count}} files are password-protected. Unlock them first."
exportAndContinue = "Export & Continue"
false = "False"
fileNotSavedToDisk = "Not saved to disk"
@@ -1516,12 +1518,18 @@ title = "Feedback Messages"
[admin.settings.telegram.feedback.channel]
title = "Channel Feedback Rules"
errorMessage.description = "Show detailed error messages for channels."
errorMessage.label = "Show error messages (Channel)"
errorProcessing.description = "Send processing error messages to channels."
errorProcessing.label = "Show processing errors (Channel)"
noValidDocument.description = "Suppress the no valid document response for channel uploads."
noValidDocument.label = "Show \"No valid document\" (Channel)"
[admin.settings.telegram.feedback.channel.errorMessage]
description = "Show detailed error messages for channels."
label = "Show error messages (Channel)"
[admin.settings.telegram.feedback.channel.errorProcessing]
description = "Send processing error messages to channels."
label = "Show processing errors (Channel)"
[admin.settings.telegram.feedback.channel.noValidDocument]
description = "Suppress the no valid document response for channel uploads."
label = "Show \"No valid document\" (Channel)"
[admin.settings.telegram.feedback.general.enabled]
description = "Control whether the bot sends feedback messages at all."
@@ -1529,12 +1537,18 @@ label = "Enable Feedback"
[admin.settings.telegram.feedback.user]
title = "User Feedback Rules"
errorMessage.description = "Show detailed error messages for users."
errorMessage.label = "Show error messages (User)"
errorProcessing.description = "Send processing error messages to users."
errorProcessing.label = "Show processing errors (User)"
noValidDocument.description = "Suppress the no valid document response for user uploads."
noValidDocument.label = "Show \"No valid document\" (User)"
[admin.settings.telegram.feedback.user.errorMessage]
description = "Show detailed error messages for users."
label = "Show error messages (User)"
[admin.settings.telegram.feedback.user.errorProcessing]
description = "Send processing error messages to users."
label = "Show processing errors (User)"
[admin.settings.telegram.feedback.user.noValidDocument]
description = "Suppress the no valid document response for user uploads."
label = "Show \"No valid document\" (User)"
[admin.settings.telegram.pipelineInboxFolder]
description = "Folder under the pipeline directory where incoming Telegram files are stored."
@@ -1820,7 +1834,8 @@ desc = "Build multi-step workflows by chaining together PDF actions. Ideal for r
export = "Export"
exportForFolderScanning = "Export for Folder Scanning"
import = "Import"
importPartialSuccess = "Imported with {{count}} unmapped operation(s): {{ops}}"
importPartialSuccess_one = "Imported with {{count}} unmapped operation: {{ops}}"
importPartialSuccess_other = "Imported with {{count}} unmapped operations: {{ops}}"
importSuccess = "Imported automation: {{name}}"
invalidStep = "Invalid step"
reviewTitle = "Automation Results"
@@ -1880,7 +1895,8 @@ dropHint = "Drop JSON here or click to choose a file"
dropSubhint = "Both Automate and Folder Scanning configs are accepted"
dropzoneAriaLabel = "Drop an automation JSON file here"
intro = "Drop a JSON file or paste its contents below. The format (Automate or Folder Scanning) is detected automatically."
opCount = "{{count}} operation(s)"
opCount_one = "{{count}} operation"
opCount_other = "{{count}} operations"
parseError = "Could not parse: {{message}}"
pasteLabel = "Or paste JSON"
pastePlaceholder = "Paste your automation JSON here…"
@@ -1906,7 +1922,8 @@ title = "Suggested"
finish = "Finish"
run = "Run Automation"
running = "Running Automation..."
steps = "{{count}} steps"
steps_one = "{{count}} step"
steps_other = "{{count}} steps"
unnamed = "Unnamed Automation"
[automation.suggested]
@@ -2236,7 +2253,8 @@ title = "Which option should I use?"
stepTitle = "Certificate Format"
[certSign.collab.addParticipants]
add = "Add {{count}} Participant(s)"
add_one = "Add {{count}} Participant"
add_other = "Add {{count}} Participants"
reasonHelp = "Pre-set a signing reason for these participants (optional, they can override when signing)"
reasonPlaceholder = "e.g. Approval, Review..."
@@ -2349,7 +2367,8 @@ certInvalidFallback = "Invalid certificate"
certNetworkError = "Could not validate certificate"
certValidating = "Validating certificate..."
certValidUntil = "Certificate valid until {{date}}"
description = "You have placed {{count}} signature(s). Choose your certificate to complete signing."
description_one = "You have placed {{count}} signature. Choose your certificate to complete signing."
description_other = "You have placed {{count}} signatures. Choose your certificate to complete signing."
sign = "Sign Document"
title = "Configure Certificate"
@@ -2680,11 +2699,9 @@ executing_tool_single = "Running {{tool}}..."
executing_tool_step = "Running {{tool}} (step {{step}} of {{total}})..."
extracting_content = "Extracting content from your documents..."
processing = "Processing extracted content..."
ranForMinutes = "Ran for {{count}} minutes"
ranForMinutes_one = "Ran for 1 minute"
ranForMinutes_other = "Ran for {{count}} minutes"
ranForMinutesSeconds = "Ran for {{minutes}} min, {{seconds}} sec"
ranForSeconds = "Ran for {{count}} seconds"
ranForSeconds_one = "Ran for 1 second"
ranForSeconds_other = "Ran for {{count}} seconds"
thinking = "Thinking..."
@@ -2717,7 +2734,8 @@ unsupported_capability = "Unsupported capability: {{capability}}"
usage_limit_reached = "You've reached your usage limit. Check your plan options to keep going."
[chat.toolsUsed]
summary = "Ran {{count}} tools"
summary_one = "Ran 1 tool"
summary_other = "Ran {{count}} tools"
unknownTool = "Unknown tool"
[cloudBadge]
@@ -3185,10 +3203,6 @@ description = "These cookies are essential for the website to function properly.
posthog = "PostHog Analytics"
scarf = "Scarf Pixel"
[credits]
[credits.insufficient]
[credits.modal]
advancedMonitoring = "Advanced monitoring"
allInOneWorkspace = "All-in-one PDF workspace (viewer, tools & agent)"
@@ -3418,7 +3432,8 @@ title = "Remove password to continue"
unlock = "Unlock & Continue"
unlockAll = "Use for all ({{count}})"
unlockAllPartialFail = "Wrong password for: {{names}}"
unlockAllSuccess = "Unlocked {{count}} file(s)."
unlockAllSuccess_one = "Unlocked {{count}} file."
unlockAllSuccess_other = "Unlocked {{count}} files."
unlockPrompt = "Unlock PDF to continue"
viewerLocked = "This PDF is password-protected"
viewerUnlock = "Unlock"
@@ -3654,20 +3669,25 @@ create = "Create"
cycleBlocked = "Can't move a folder into one of its own subfolders."
delete = "Delete"
deleteFilesChoiceBody = "Some of these files are saved both on this device and in the cloud. Where should they be deleted from?"
deleteFilesCloudBody = "Delete {{count}} file(s) from the cloud? This cannot be undone."
deleteFilesCloudBody_one = "Delete 1 file from the cloud? This cannot be undone."
deleteFilesCloudBody_other = "Delete {{count}} files from the cloud? This cannot be undone."
deleteFilesError = "Could not delete. Try again."
deleteFilesLocalBody = "Delete {{count}} file(s) from this device? This cannot be undone."
deleteFilesTitle = "Delete {{count}} file(s)?"
deleteFilesLocalBody_one = "Delete 1 file from this device? This cannot be undone."
deleteFilesLocalBody_other = "Delete {{count}} files from this device? This cannot be undone."
deleteFilesTitle_one = "Delete 1 file?"
deleteFilesTitle_other = "Delete {{count}} files?"
deleteFolder = "Delete folder"
deleteFolderBody = "Delete folder \"{{name}}\"?"
deleteFolderContents = "Also delete {{count}} file(s) inside the folder"
deleteFolderContents_one = "Also delete {{count}} file inside the folder"
deleteFolderContents_other = "Also delete {{count}} files inside the folder"
deleteFolderContentsWarning = "Files will be permanently removed and cannot be recovered."
deleteFolderError = "Could not delete the folder. Try again."
deleteFolderKeepHint = "Files inside will be moved to All files."
deleteFolderTitle = "Delete folder?"
deselectAll = "Clear selection"
details = "Details"
detailsCount = "{{count}} files selected"
detailsCount_one = "{{count}} file selected"
detailsCount_other = "{{count}} files selected"
dismissError = "Dismiss"
download = "Download"
downloadAll = "Download all"
@@ -3678,14 +3698,16 @@ file = "File"
fileInfo = "File info"
fileMenu = "File actions"
folder = "Folder"
folderItems = "{{count}} items"
folderItems_one = "{{count}} item"
folderItems_other = "{{count}} items"
folderMenu = "Folder actions"
inPath = "in {{path}}"
inWorkspace = "Open"
inWorkspaceAria = "Already in workspace"
loading = "Loading…"
localFoldersUnavailable = "Folders are cloud-only - save a file to the cloud to organize it."
moveSkippedRemote = "{{count}} file(s) couldn't be moved on the server (no permission or already deleted)."
moveSkippedRemote_one = "{{count}} file couldn't be moved on the server (no permission or already deleted)."
moveSkippedRemote_other = "{{count}} files couldn't be moved on the server (no permission or already deleted)."
moveTo = "Move to…"
myFiles = "My Files"
newFolder = "New folder"
@@ -3714,7 +3736,8 @@ shareDisabledHint = "File sharing isn't enabled on this server. Ask your admin t
shareManage = "Manage sharing"
showDetails = "Show details"
signInRequired = "Sign in to use cloud storage."
summary = "{{count}} items"
summary_one = "{{count}} item"
summary_other = "{{count}} items"
tree = "Folders"
upload = "Upload"
uploadedToLocal = "Uploaded files start in Local. Use 'Save to cloud' to put them in a folder."
@@ -3727,111 +3750,154 @@ versionOrigin = "Original upload"
versionsCount = "{{count}} versions"
versionShowHidden = "Show {{count}} earlier versions"
viewVersionHistory = "Version journey ({{count}})"
appearance.colour = "Color"
appearance.icon = "Icon"
appearance.title = "Appearance"
appearance.useColour = "Use color {{c}}"
column.modified = "Modified"
column.name = "Name"
column.size = "Size"
column.type = "Type"
deleteScope.cloud = "Cloud only"
deleteScope.cloudHint = "Deletes from the server. A copy stays on this device."
deleteScope.device = "This device only"
deleteScope.deviceHint = "Removes the local copy. The cloud copy is kept."
deleteScope.everywhere = "Everywhere"
deleteScope.everywhereHint = "Deletes the file from this device and the cloud."
empty.hint = "Drop PDFs anywhere on this page to upload, or use the New folder button to organize your files."
empty.newFolderCta = "Create folder"
empty.title = "This folder is empty"
empty.uploadCta = "Upload files"
empty.cloud.hint = "Upload a file to start, or create a folder to organize."
empty.cloud.offlineHint = "Reconnect to load your cloud library."
empty.cloud.offlineTitle = "No cached cloud files"
empty.cloud.title = "No cloud files yet"
empty.local.hint = "Files saved without uploading stay here. Drop a file to add one."
empty.local.title = "No local-only files"
empty.recent.hint = "Files you open or edit will appear here."
empty.recent.title = "Nothing modified yet"
empty.shared.hint = "When someone shares a file via link, it appears here."
empty.shared.title = "Nothing shared with you"
empty.sharedByMe.hint = "Create a share link or invite a teammate from any of your files to see it here."
empty.sharedByMe.title = "You haven't shared any files yet"
error.actionFailed = "Could not {{action}}."
error.actionFailedDetail = "Could not {{action}}: {{message}}"
error.cloudDeleteFailed = "Couldn't delete {{count}} file(s) from the cloud."
error.deleteFolderFailed = "Could not delete folder."
error.deleteFolderFailedDetail = "Could not delete folder: {{message}}"
error.folderAppearanceFailed = "Could not update folder appearance."
error.folderAppearanceFailedDetail = "Could not update folder appearance: {{message}}"
error.moveFilesFailed = "Could not move files."
error.moveFilesFailedDetail = "Could not move files: {{message}}"
error.moveFolderFailed = "Could not move folder."
error.moveFolderFailedDetail = "Could not move folder: {{message}}"
error.removeFilesFailed = "Could not remove files."
error.removeFilesFailedDetail = "Could not remove files: {{message}}"
error.uploadFilesFailed = "Could not upload files."
error.uploadFilesFailedDetail = "Could not upload files: {{message}}"
field.added = "Added"
field.count = "Files"
field.folder = "Folder"
field.modified = "Modified"
field.name = "Name"
field.size = "Size"
field.toolHistory = "Tool history"
field.toolHistoryAtVersion = "Cumulative tool chain"
field.totalSize = "Total size"
field.type = "Type"
field.versionHistory = "Version journey"
folderName.cancel = "Cancel"
folderName.error = "Could not save folder. Try again."
folderName.label = "Folder name"
folderName.placeholder = "Folder name"
moveDialog.cancel = "Cancel"
moveDialog.confirm = "Move here"
moveDialog.error = "Could not move. Try again."
moveDialog.hint = "Pick a destination folder. Tip: you can also drag and drop files onto folders in the tree on the left."
moveDialog.newFolderCancel = "Discard"
moveDialog.newFolderCreate = "Create"
moveDialog.newFolderError = "Could not create folder. Try again."
moveDialog.newFolderLabel = "New folder name"
moveDialog.newFolderPlaceholder = "Folder name"
moveDialog.newFolderToggle = "Create new folder…"
moveDialog.title = "Move to folder"
origin.all = "All sources"
origin.cloud = "Cloud"
origin.cloudHint = "Stored on the Stirling server"
origin.local = "Local"
origin.localHint = "Only stored in this browser"
origin.shared = "Shared"
origin.sharedHint = "Shared with you via link"
sort.modifiedAsc = "Oldest first"
sort.modifiedDesc = "Recent first"
sort.nameAsc = "Name A→Z"
sort.nameDesc = "Name Z→A"
sort.sizeAsc = "Smallest first"
sort.sizeDesc = "Largest first"
syncError.client = "Folder sync failed."
syncError.network = "Could not reach the server."
syncError.server = "Server error during folder sync."
tabName.local = "Local"
tabName.recent = "Recent"
tabName.shared = "Shared with me"
tabName.sharedByMe = "Shared by me"
tabs.all = "All"
tabs.ariaLabel = "File views"
tabs.recent = "Recent"
tabs.shared = "Shared with me"
tabs.sharedByMe = "Shared by me"
treeMenu.actions = "Folder actions for {{name}}"
treeMenu.delete = "Delete folder"
treeMenu.newSubfolder = "New subfolder"
treeMenu.rename = "Rename"
typeFilter.allTypes = "All types"
typeFilter.label = "Filter by type"
viewMode.grid = "Grid view"
viewMode.label = "View mode"
viewMode.list = "List view"
[filesPage.appearance]
colour = "Color"
icon = "Icon"
title = "Appearance"
useColour = "Use color {{c}}"
[filesPage.column]
modified = "Modified"
name = "Name"
size = "Size"
type = "Type"
[filesPage.deleteScope]
cloud = "Cloud only"
cloudHint = "Deletes from the server. A copy stays on this device."
device = "This device only"
deviceHint = "Removes the local copy. The cloud copy is kept."
everywhere = "Everywhere"
everywhereHint = "Deletes the file from this device and the cloud."
[filesPage.empty]
hint = "Drop PDFs anywhere on this page to upload, or use the New folder button to organize your files."
newFolderCta = "Create folder"
title = "This folder is empty"
uploadCta = "Upload files"
[filesPage.empty.cloud]
hint = "Upload a file to start, or create a folder to organize."
offlineHint = "Reconnect to load your cloud library."
offlineTitle = "No cached cloud files"
title = "No cloud files yet"
[filesPage.empty.local]
hint = "Files saved without uploading stay here. Drop a file to add one."
title = "No local-only files"
[filesPage.empty.recent]
hint = "Files you open or edit will appear here."
title = "Nothing modified yet"
[filesPage.empty.shared]
hint = "When someone shares a file via link, it appears here."
title = "Nothing shared with you"
[filesPage.empty.sharedByMe]
hint = "Create a share link or invite a teammate from any of your files to see it here."
title = "You haven't shared any files yet"
[filesPage.error]
actionFailed = "Could not {{action}}."
actionFailedDetail = "Could not {{action}}: {{message}}"
cloudDeleteFailed_one = "Couldn't delete 1 file from the cloud."
cloudDeleteFailed_other = "Couldn't delete {{count}} files from the cloud."
deleteFolderFailed = "Could not delete folder."
deleteFolderFailedDetail = "Could not delete folder: {{message}}"
folderAppearanceFailed = "Could not update folder appearance."
folderAppearanceFailedDetail = "Could not update folder appearance: {{message}}"
moveFilesFailed = "Could not move files."
moveFilesFailedDetail = "Could not move files: {{message}}"
moveFolderFailed = "Could not move folder."
moveFolderFailedDetail = "Could not move folder: {{message}}"
removeFilesFailed = "Could not remove files."
removeFilesFailedDetail = "Could not remove files: {{message}}"
uploadFilesFailed = "Could not upload files."
uploadFilesFailedDetail = "Could not upload files: {{message}}"
[filesPage.field]
added = "Added"
count = "Files"
folder = "Folder"
modified = "Modified"
name = "Name"
size = "Size"
toolHistory = "Tool history"
toolHistoryAtVersion = "Cumulative tool chain"
totalSize = "Total size"
type = "Type"
versionHistory = "Version journey"
[filesPage.folderName]
cancel = "Cancel"
error = "Could not save folder. Try again."
label = "Folder name"
placeholder = "Folder name"
[filesPage.moveDialog]
cancel = "Cancel"
confirm = "Move here"
error = "Could not move. Try again."
hint = "Pick a destination folder. Tip: you can also drag and drop files onto folders in the tree on the left."
newFolderCancel = "Discard"
newFolderCreate = "Create"
newFolderError = "Could not create folder. Try again."
newFolderLabel = "New folder name"
newFolderPlaceholder = "Folder name"
newFolderToggle = "Create new folder…"
title = "Move to folder"
[filesPage.origin]
all = "All sources"
cloud = "Cloud"
cloudHint = "Stored on the Stirling server"
local = "Local"
localHint = "Only stored in this browser"
shared = "Shared"
sharedHint = "Shared with you via link"
[filesPage.sort]
modifiedAsc = "Oldest first"
modifiedDesc = "Recent first"
nameAsc = "Name A→Z"
nameDesc = "Name Z→A"
sizeAsc = "Smallest first"
sizeDesc = "Largest first"
[filesPage.syncError]
client = "Folder sync failed."
network = "Could not reach the server."
server = "Server error during folder sync."
[filesPage.tabName]
local = "Local"
recent = "Recent"
shared = "Shared with me"
sharedByMe = "Shared by me"
[filesPage.tabs]
all = "All"
ariaLabel = "File views"
recent = "Recent"
shared = "Shared with me"
sharedByMe = "Shared by me"
[filesPage.treeMenu]
actions = "Folder actions for {{name}}"
delete = "Delete folder"
newSubfolder = "New subfolder"
rename = "Rename"
[filesPage.typeFilter]
allTypes = "All types"
label = "Filter by type"
[filesPage.viewMode]
grid = "Grid view"
label = "View mode"
list = "List view"
[fileToPDF]
tags = "transformation,format,document,picture,slide,text,conversion,office,docs,word,excel,powerpoint"
@@ -4002,7 +4068,8 @@ pages = "Pages"
pdfVersion = "PDF Version"
permsAll = "All Permissions Allowed"
permsMixed = "Some permissions restricted"
permsRestricted = "{{count}} restrictions"
permsRestricted_one = "{{count}} restriction"
permsRestricted_other = "{{count}} restrictions"
securityTitle = "Security Status"
technical = "Technical"
title = "PDF Summary"
@@ -4050,7 +4117,8 @@ location = "Location:"
logo = "Logo:"
logoHidden = "No logo"
logoShown = "Stirling PDF logo shown"
participantCount = "{{count}} participant(s) will sign in order"
participantCount_one = "{{count}} participant will sign in order"
participantCount_other = "{{count}} participants will sign in order"
participants = "Participants"
reason = "Reason:"
send = "Send Signing Requests"
@@ -4068,7 +4136,8 @@ title = "Select Document"
[groupSigning.steps.selectParticipants]
continue = "Continue to Signature Settings"
count = "{{count}} participant(s) selected"
count_one = "{{count}} participant selected"
count_other = "{{count}} participants selected"
label = "Select participants"
placeholder = "Choose participants to sign..."
title = "Choose Participants"
@@ -4664,7 +4733,8 @@ descriptionNoConvert = "Scan to upload photos from your mobile device."
error = "Connection Error"
expiryWarning = "Session Expiring Soon"
expiryWarningMessage = "This QR code will expire in {{seconds}} seconds. A new code will be generated automatically."
filesReceived = "{{count}} file(s) received"
filesReceived_one = "{{count}} file received"
filesReceived_other = "{{count}} files received"
instructions = "Scan with your phone camera. Images convert to PDF automatically."
instructionsNoConvert = "Scan with your phone camera to upload files."
pollingError = "Error checking for files"
@@ -5772,10 +5842,6 @@ keyDescription = "Paste the license key from your email"
success = "License Activated!"
successMessage = "Your license has been successfully activated. You can now close this window."
[plan.team]
[plan.trial]
[policies]
deleteConfirmBody = "This removes the policy and its workflow. Documents already processed are not affected."
deleteConfirmTitle = "Delete {{label}} policy?"
@@ -6873,7 +6939,9 @@ trial = "Trial"
[settings.planBilling.team]
managedByTeam = "Managed by team"
memberCount = "{{count}} team members"
memberCount_one = "{{count}} team member"
memberCount_other = "{{count}} team members"
memberCount_zero = "no team members"
[settings.planBilling.tier]
enterprise = "Enterprise"
@@ -7451,7 +7519,8 @@ errorTitle = "Share failed"
expiredBody = "This share link is invalid or has expired."
expiredTitle = "Link expired"
failure = "Unable to generate a share link. Please try again."
fileCount = "{{count}} files"
fileCount_one = "{{count}} file"
fileCount_other = "{{count}} files"
fileLabel = "File"
generate = "Generate Link"
generated = "Share link generated"
@@ -7513,7 +7582,8 @@ description = "This uploads the current file to server storage for your own acce
errorTitle = "Upload failed"
failure = "Upload failed. Please check your login and storage settings."
featureDisabled = "Saving to the server isn't enabled on this server."
fileCount = "{{count}} files"
fileCount_one = "{{count}} file"
fileCount_other = "{{count}} files"
fileLabel = "File"
hint = "Public links and access modes are controlled by your server settings."
more = " +{{count}} more"
@@ -7547,7 +7617,9 @@ leaveButton = "Leave Team"
leaveError = "Failed to leave team"
leaveSuccess = "Successfully left team"
loading = "Loading team information..."
memberCount = "{{count}} members"
memberCount_one = "{{count}} member"
memberCount_other = "{{count}} members"
memberCount_zero = "no members"
memberRemoved = "Member removed successfully"
namePlaceholder = "Enter team name"
personal = "Personal"
@@ -7863,8 +7935,10 @@ generatedAt = "Generated"
noPdf = "PDF report will be available after a successful validation."
page = "Page"
shortTitle = "Signature Summary"
signatureCountLabel = "{{count}} signatures"
signaturesFound = "{{count}} signatures detected"
signatureCountLabel_one = "{{count}} signature"
signatureCountLabel_other = "{{count}} signatures"
signaturesFound_one = "{{count}} signature detected"
signaturesFound_other = "{{count}} signatures detected"
signaturesValid = "{{count}} fully valid"
title = "Signature Validation Report"
@@ -7929,8 +8003,8 @@ goToLink = "Go to link"
hint = "Place comments with the Comment, Insert Text, or Replace Text tools. They will appear here by page."
locateAnnotation = "Locate in document"
moreActions = "More actions"
nComments = "{{count}} comments"
oneComment = "1 comment"
nComments_one = "{{count}} comment"
nComments_other = "{{count}} comments"
pageLabel = "Page {{page}}"
removeCommentOnly = "Remove comment only"
saveReply = "Save reply"
@@ -8407,7 +8481,6 @@ loading = "Loading people..."
locked = "locked"
lockedBadge = "Locked"
loginRequired = "Enable login mode first"
member = "Member"
noMembersFound = "No members found"
role = "Role"
searchMembers = "Search members..."
@@ -8470,14 +8543,14 @@ success = "Password updated successfully"
title = "Change password"
[workspace.people.editMember]
editing = "Editing:"
editing = "Editing: <0>{{username}}</0>"
error = "Failed to update user"
role = "Role"
submit = "Update Member"
submit = "Update User"
success = "User updated successfully"
team = "Team (Optional)"
teamPlaceholder = "Select a team"
title = "Edit Member"
title = "Edit User"
[workspace.people.emailInvite]
allFailed = "Failed to invite users"
@@ -8518,9 +8591,11 @@ currentUsage = "Currently using {{current}} of {{max}} user licenses"
fromLicense = "from license"
grandfathered = "Grandfathered"
grandfatheredShort = "{{count}} grandfathered"
noSlotsAvailable = "No slots available"
slotsAvailable = "{{count}} user slot(s) available"
users = "users"
slotsAvailable_one = "{{count}} user slot available"
slotsAvailable_other = "{{count}} user slots available"
slotsAvailable_zero = "No slots available"
users_one = "user"
users_other = "users"
[workspace.people.mfa]
adminDisableError = "Failed to disable MFA for user"
@@ -8528,9 +8603,8 @@ adminDisableSuccess = "MFA disabled successfully for user"
disableByAdmin = "Disable MFA"
[workspace.people.roleDescriptions]
admin = "Can manage settings and invite members, with full administrative access."
member = "Can view and edit shared files, but cannot manage workspace settings or members."
user = "User"
admin = "Can manage settings and invite users, with full administrative access."
user = "Can view and edit shared files, but cannot manage workspace settings or users."
[workspace.people.toggleEnabled]
error = "Failed to update user status"
@@ -8550,7 +8624,9 @@ description = "Manage teams and organize workspace members"
loadError = "Failed to load team details"
loading = "Loading teams..."
loadingDetails = "Loading team details..."
memberCount = "{{count}} members"
memberCount_one = "{{count}} member"
memberCount_other = "{{count}} members"
memberCount_zero = "no members"
noMembers = "No members in this team"
noTeamsFound = "No teams found"
removeMember = "Remove from team"
@@ -8614,5 +8690,6 @@ title = "Rename Team"
[zipWarning]
cancel = "Cancel"
confirm = "Extract"
message = "This ZIP contains {{count}} files. Extract anyway?"
message_one = "This ZIP contains {{count}} file. Extract anyway?"
message_other = "This ZIP contains {{count}} files. Extract anyway?"
title = "Large ZIP File"
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -617,11 +617,9 @@ export function CommentsSidebar({
})}
</Text>
<Text size="xs" c="dimmed" mb="sm">
{entries.length === 1
? t("viewer.comments.oneComment", "1 comment")
: t("viewer.comments.nComments", "{{count}} comments", {
count: entries.length,
})}
{t("viewer.comments.nComments", "{{count}} comment(s)", {
count: entries.length,
})}
</Text>
<Box
mb="xs"
@@ -155,18 +155,13 @@ export const useToolOperation = <TParams>(
fileActions.openEncryptedUnlockPrompt(ef.fileId);
}
actions.setError(
encryptedFiles.length === 1
? t(
"encryptedFileBlocked",
"File is password-protected. Unlock it first.",
)
: t(
"encryptedFilesBlocked",
"{{count}} files are password-protected. Unlock them first.",
{
count: encryptedFiles.length,
},
),
t(
"encryptedFilesBlocked",
"{{count}} files are password-protected. Unlock them first.",
{
count: encryptedFiles.length,
},
),
);
return;
}
@@ -22,6 +22,7 @@ const IGNORED_KEYS = new Set<string>([
// If the script has found a false-positive that shouldn't be in the translations, include it here
]);
const LIKELY_TRANSLATION_USAGE_RE = /(?:^|[^\w$])t\s*\(|\.t\s*\(|\bi18nKey\b/;
const PLURAL_SUFFIX_RE = /_(zero|one|two|few|many|other)$/;
type FoundKey = {
key: string;
@@ -53,6 +54,12 @@ const flattenKeys = (
return acc;
};
const hasPluralCoverage = (key: string, availableKeys: Set<string>): boolean =>
[...availableKeys].some(
(availableKey) =>
availableKey.startsWith(`${key}_`) && PLURAL_SUFFIX_RE.test(availableKey),
);
const listSourceFiles = (): string[] => {
const files = ts.sys.readDirectory(
SRC_ROOT,
@@ -188,7 +195,10 @@ describe("Missing translation coverage", () => {
.filter(({ key }) => !IGNORED_KEYS.has(key));
expect(usedKeys.length).toBeGreaterThan(100); // Sanity check
const missingKeys = usedKeys.filter(({ key }) => !availableKeys.has(key));
const missingKeys = usedKeys.filter(
({ key }) =>
!availableKeys.has(key) && !hasPluralCoverage(key, availableKeys),
);
const annotations = missingKeys.map(
({ key, fallback, file, line, column }) => {
@@ -18,6 +18,7 @@ const IGNORED_FILE_PATTERNS = [
/\.spec\./,
/\.stories\./,
];
const PLURAL_SUFFIX_PATTERN = /_(zero|one|two|few|many|other)$/;
/**
* Keys that look unused to the heuristic but are genuinely used: keep them.
@@ -149,6 +150,15 @@ const isIgnored = (key: string): boolean => {
return IGNORED_KEY_PATTERNS.some((re) => re.test(key));
};
const getTranslationLookupKeys = (key: string): string[] => {
const pluralBaseKey = key.replace(PLURAL_SUFFIX_PATTERN, "");
if (pluralBaseKey === key) {
return [key];
}
return [key, pluralBaseKey];
};
describe("Unused translation coverage", () => {
test(
"fails if any en-US translation key has no source references",
@@ -175,12 +185,19 @@ describe("Unused translation coverage", () => {
const unused = availableKeys.filter((key) => {
if (isIgnored(key)) return false;
const lookupKeys = getTranslationLookupKeys(key);
// Direct: the full key text appears anywhere in source (catches
// static t() calls, i18nKey props, constants, and any other place
// the literal string sits in code or comments).
if (source.includes(key)) return false;
// the literal string sits in code or comments). Plural variants also
// count as used when their base key is referenced because i18next
// resolves suffixes like _one/_other from a single base lookup.
if (lookupKeys.some((lookupKey) => source.includes(lookupKey))) {
return false;
}
// Dynamic: the key matches a template-literal shape from source.
return !shapeMatchers.some((re) => re.test(key));
return !lookupKeys.some((lookupKey) =>
shapeMatchers.some((re) => re.test(lookupKey)),
);
});
const localeRelative = path
@@ -42,10 +42,9 @@ export function useExitWarning() {
const choice = await message(
t(
"confirmCloseUnsavedList",
"You have {{count}} file{{plural}} with unsaved changes.\n\n{{fileList}}",
"You have {{count}} file(s) with unsaved changes.\n\n{{fileList}}",
{
count: dirtyStubs.length,
plural: dirtyStubs.length > 1 ? "s" : "",
fileList,
},
),
@@ -73,10 +72,9 @@ export function useExitWarning() {
await message(
t(
"confirmCloseSaveFailed",
"Saved with errors. {{count}} file{{plural}} could not be saved.",
"Saved with errors. {{count}} file(s) could not be saved.",
{
count: failedCount,
plural: failedCount > 1 ? "s" : "",
},
),
{
@@ -118,11 +118,11 @@ export default function InviteMembersModal({
const roleOptions = [
{
value: "ROLE_USER",
label: t("workspace.people.roleDescriptions.user", "User"),
label: t("workspace.people.user", "User"),
},
{
value: "ROLE_ADMIN",
label: t("workspace.people.roleDescriptions.admin", "Admin"),
label: t("workspace.people.admin", "Admin"),
},
];
@@ -414,15 +414,10 @@ export default function InviteMembersModal({
height="1rem"
/>
<Text size="sm" fw={500}>
{licenseInfo.availableSlots > 0
? t("workspace.people.license.slotsAvailable", {
count: licenseInfo.availableSlots,
defaultValue: `${licenseInfo.availableSlots} user slot(s) available`,
})
: t(
"workspace.people.license.noSlotsAvailable",
"No user slots available",
)}
{t("workspace.people.license.slotsAvailable", {
count: licenseInfo.availableSlots,
defaultValue: `${licenseInfo.availableSlots} user slot(s) available`,
})}
</Text>
</Group>
{licenseInfo.availableSlots === 0 && (
@@ -1,6 +1,6 @@
import { useState, useEffect } from "react";
import { isAxiosError } from "axios";
import { useTranslation } from "react-i18next";
import { Trans, useTranslation } from "react-i18next";
import {
Stack,
Text,
@@ -84,8 +84,11 @@ export default function PeopleSection() {
? t("workspace.people.loginRequired", "Enable login mode first")
: hasNoSlots
? t(
"workspace.people.license.noSlotsAvailable",
"workspace.people.license.slotsAvailable",
"No user slots available",
{
count: 0,
},
)
: null;
@@ -391,9 +394,9 @@ export default function PeopleSection() {
},
{
value: "ROLE_USER",
label: t("workspace.people.member"),
label: t("workspace.people.user"),
description: t(
"workspace.people.roleDescriptions.member",
"workspace.people.roleDescriptions.user",
"Can view and edit shared files, but cannot manage workspace settings or members.",
),
icon: "person",
@@ -479,8 +482,11 @@ export default function PeopleSection() {
<Group gap="xs" wrap="nowrap" align="center">
<Badge color="red" variant="light" size="sm">
{t(
"workspace.people.license.noSlotsAvailable",
"No slots available",
"workspace.people.license.slotsAvailable",
"No user slots available",
{
count: 0,
},
)}
</Badge>
<Button
@@ -709,7 +715,7 @@ export default function PeopleSection() {
>
{(user.rolesAsString || "").includes("ROLE_ADMIN")
? t("workspace.people.admin", "Admin")
: t("workspace.people.member", "Member")}
: t("workspace.people.user", "User")}
</Badge>
</Table.Td>
<Table.Td>
@@ -993,8 +999,12 @@ export default function PeopleSection() {
{t("workspace.people.editMember.title")}
</Text>
<Text size="sm" c="dimmed" ta="center">
{t("workspace.people.editMember.editing")}{" "}
<strong>{selectedUser?.username}</strong>
<Trans
i18nKey="workspace.people.editMember.editing"
defaults="Editing: <0>{{username}}</0>"
values={{ username: selectedUser?.username ?? "" }}
components={[<strong />]}
/>
</Text>
</Stack>
<Select
@@ -370,8 +370,7 @@ export default function TeamDetailsSection({
{team.name}
</Text>
<Text size="sm" c="dimmed">
{t("workspace.teams.memberCount", { count: teamUsers.length })}{" "}
{teamUsers.length === 1 ? "member" : "members"}
{t("workspace.teams.memberCount", { count: teamUsers.length })}
</Text>
</div>
</Group>
@@ -379,10 +378,9 @@ export default function TeamDetailsSection({
{/* Add Member Button */}
<Group justify="flex-end">
<Tooltip
label={t(
"workspace.people.license.noSlotsAvailable",
"No user slots available",
)}
label={t("workspace.people.license.slotsAvailable", {
count: licenseInfo ? licenseInfo.availableSlots : 0,
})}
disabled={!licenseInfo || licenseInfo.availableSlots > 0}
position="bottom"
withArrow
@@ -532,7 +530,7 @@ export default function TeamDetailsSection({
>
{(user.rolesAsString || "").includes("ROLE_ADMIN")
? t("workspace.people.admin")
: t("workspace.people.member")}
: t("workspace.people.user")}
</Badge>
</Table.Td>
<Table.Td>
-80
View File
@@ -22,13 +22,11 @@ ignore = [
'admin.settings.connections.oauth2.label',
'admin.settings.connections.saml2.label',
'convert.dpi',
'endpointStatistics.dataTypeApi',
'getPdfInfo.other.javaScript',
'getPdfInfo.other.xmp',
'getPdfInfo.summary.tech.javaScript',
'home.devApi.title',
'language.direction',
'removeBlanks.whitePercent.unit',
'showJS.tags',
'usage.controls.dataType.api',
'validateSignature.downloadType.csv',
@@ -76,7 +74,6 @@ ignore = [
'admin.settings.premium.title',
'alphabet',
'annotation.contents',
'annotation.ellipse',
'annotation.polygon',
'audit.events.details',
'audit.tabs.dashboard',
@@ -85,19 +82,10 @@ ignore = [
'certSign.name',
'common.save',
'convert.dpi',
'convert.markdown',
'convert.pptExt',
'convert.rtfExt',
'convert.textRtf',
'cookieBanner.services.posthog',
'cookieBanner.services.scarf',
'crop.autoCrop',
'details',
'endpointStatistics.dataTypeApi',
'endpointStatistics.dataTypeUi',
'endpointStatistics.top10',
'endpointStatistics.top20',
'fileChooser.dragAndDrop',
'fileManager.fileFormat',
'fileManager.fileName',
'fileManager.fileVersion',
@@ -117,29 +105,21 @@ ignore = [
'home.devApi.title',
'language.direction',
'legal.impressum',
'licenses.version',
'login.debug',
'pdfTextEditor.options.advanced.title',
'pipeline.title',
'pipelineOptions.pipelineHeader',
'plan.enterprise.name',
'plan.pro.name',
'plan.upgrade',
'pro',
'quickAccess.reader',
'redact.manual.zoom',
'removeBlanks.whitePercent.unit',
'settings.connection.mode.saas',
'settings.connection.server',
'settings.licensingAnalytics.audit',
'settings.licensingAnalytics.plan',
'settings.workspace.teams',
'setup.mode.saas.title',
'setup.server.type.saas',
'sign.saved.type.text',
'sign.type.text',
'signup.name',
'sponsor',
'text',
'toolPanel.alpha',
'update.priority.normal',
@@ -155,7 +135,6 @@ ignore = [
'validateSignature.downloadType.json',
'validateSignature.downloadType.pdf',
'validateSignature.report.downloads',
'validateSignature.status._value',
'watermark.type.1',
'watermark.watermarkType.text',
'workspace.people.actions.upgrade',
@@ -164,7 +143,6 @@ ignore = [
'workspace.people.emailInvite.emailsPlaceholder',
'workspace.people.inviteLink.emailPlaceholder',
'workspace.people.inviteMode.link',
'workspace.people.status',
'workspace.people.team',
'workspace.teams.system',
'workspace.teams.title',
@@ -192,7 +170,6 @@ ignore = [
'admin.settings.connections.pageFormatA4',
'admin.settings.connections.saml2.label',
'admin.settings.security.xFrameOptions.label',
'adminUserSettings.roles',
'audit.clearData.irreversible',
'certSign.appearance.invisible',
'certSign.appearance.visible',
@@ -210,22 +187,13 @@ ignore = [
'convert.cbzToPdf',
'convert.dpi',
'convert.ebookToPdf',
'convert.markdown',
'convert.pdfToCbr',
'convert.pdfToCbz',
'convert.pdfToEpub',
'convert.pptExt',
'convert.svgToPdf',
'cookieBanner.services.posthog',
'cookieBanner.services.scarf',
'credits.modal.enterpriseSubscription',
'credits.modal.popular',
'credits.modal.teamSubscription',
'defaultApp.error.title',
'endpointStatistics.dataTypeApi',
'endpointStatistics.dataTypeUi',
'endpointStatistics.top10',
'endpointStatistics.top20',
'error._value',
'fileManager.filterLocal',
'fileManager.googleDrive',
@@ -246,8 +214,6 @@ ignore = [
'plan.enterprise.name',
'plan.popular',
'plan.pro.name',
'plan.team.name',
'plan.trial.message',
'pro',
'provider.googledrive.name',
'provider.oauth2.generic.scope',
@@ -255,9 +221,7 @@ ignore = [
'provider.saml2.name',
'provider.saml2.scope',
'quickAccess.accessRoleEditor',
'redact.manual.zoom',
'redact.modeSelector.manual',
'removeBlanks.whitePercent.unit',
'settings.configuration.endpoints',
'settings.connection.mode.saas',
'settings.general.title',
@@ -267,8 +231,6 @@ ignore = [
'settings.planBilling.tier.teamBadge',
'settings.policiesPrivacy.legal',
'settings.securityAuth.telegram',
'setup.mode.saas.title',
'setup.server.type.saas',
'showJS.tags',
'storageShare.roleEditor',
'team.personal',
@@ -303,18 +265,9 @@ ignore = [
'AddStampRequest.alphabet',
'AddStampRequest.position',
'AddStampRequest.rotation',
'adminUserSettings.actions',
'alphabet',
'cookieBanner.preferencesModal.serviceCounterLabel',
'endpointStatistics.top',
'endpointStatistics.top10',
'endpointStatistics.top20',
'language.direction',
'licenses.license',
'licenses.module',
'licenses.nav',
'licenses.version',
'multiTool.page',
'page',
'pages',
'pipeline.title',
@@ -341,10 +294,6 @@ ignore = [
'admin.settings.database.port.label',
'admin.settings.legal.impressum.label',
'convert.dpi',
'convert.markdown',
'convert.pptExt',
'endpointStatistics.dataTypeApi',
'endpointStatistics.dataTypeUi',
'fileManager.googleDrive',
'footer.discord',
'footer.issues',
@@ -356,10 +305,7 @@ ignore = [
'legal.impressum',
'plan.pro.name',
'pro',
'removeBlanks.whitePercent.unit',
'settings.connection.mode.saas',
'setup.mode.saas.title',
'setup.server.type.saas',
'showJS.tags',
'usage.controls.dataType.api',
'usage.controls.dataType.ui',
@@ -381,8 +327,6 @@ ignore = [
[hu_HU]
ignore = [
'endpointStatistics.top10',
'endpointStatistics.top20',
'language.direction',
'pro',
'showJS.tags',
@@ -399,9 +343,7 @@ ignore = [
'no',
'password',
'pipeline.title',
'pipelineOptions.pipelineHeader',
'showJS.tags',
'sponsor',
]
[ja_JP]
@@ -428,7 +370,6 @@ ignore = [
[nl_NL]
ignore = [
'language.direction',
'sponsor',
]
[no_NB]
@@ -436,7 +377,6 @@ ignore = [
'adminUserSettings.admin',
'info',
'language.direction',
'sponsor',
]
[pk_sk]
@@ -452,15 +392,10 @@ ignore = [
[pt_BR]
ignore = [
'language.direction',
'pipelineOptions.pipelineHeader',
]
[pt_PT]
ignore = [
'endpointStatistics.endpoint',
'endpointStatistics.top',
'endpointStatistics.top10',
'endpointStatistics.top20',
'language.direction',
'pro',
'update.priority.normal',
@@ -490,9 +425,6 @@ ignore = [
[sr_LATN_RS]
ignore = [
'endpointStatistics.top',
'endpointStatistics.top10',
'endpointStatistics.top20',
'font',
'language.direction',
'pro',
@@ -555,18 +487,13 @@ ignore = [
'certSign.collab.signRequest.text.fontSizePlaceholder',
'convert.cbrToPdf',
'convert.cbzToPdf',
'convert.defaultFilename',
'convert.dpi',
'convert.ebookToPdf',
'convert.emlToPdf',
'convert.markdown',
'convert.pdfToCbr',
'convert.pdfToCbz',
'convert.pdfToEpub',
'convert.pptExt',
'convert.svgToPdf',
'endpointStatistics.dataTypeApi',
'endpointStatistics.dataTypeUi',
'fileManager.googleDrive',
'footer.discord',
'footer.issues',
@@ -577,8 +504,6 @@ ignore = [
'home.devApi.title',
'language.direction',
'payment.emailStage.emailPlaceholder',
'pdfToSinglePage.filenamePrefix',
'plan.trial.message',
'provider.googledrive.name',
'provider.oauth2.generic.scope',
'provider.oauth2.generic.scopes.label',
@@ -589,12 +514,8 @@ ignore = [
'provider.saml2.name',
'provider.saml2.scope',
'quickAccess.accessEmailPlaceholder',
'removeBlanks.whitePercent.unit',
'settings.connection.mode.saas',
'settings.securityAuth.telegram',
'setup.login.email.label',
'setup.mode.saas.title',
'setup.server.type.saas',
'showJS.tags',
'toolPanel.alpha',
'usage.controls.dataType.api',
@@ -602,7 +523,6 @@ ignore = [
'validateSignature.downloadType.csv',
'validateSignature.downloadType.json',
'validateSignature.downloadType.pdf',
'watermark.filenamePrefix',
'workspace.people.addMember.usernamePlaceholder',
'workspace.people.authType.oauth',
'workspace.people.authType.saml',