mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-03 21:30:14 +03:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79e2366d67 |
@@ -5,7 +5,6 @@ frontend/dist
|
||||
frontend/build
|
||||
frontend/.vite
|
||||
frontend/.tauri
|
||||
frontend/src-tauri/target
|
||||
|
||||
# Gradle build artifacts
|
||||
.gradle
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""
|
||||
Author: Ludy87
|
||||
Description: This script processes TOML translation files for localization checks. It compares translation files in a branch with
|
||||
Description: This script processes JSON translation files for localization checks. It compares translation files in a branch with
|
||||
a reference file to ensure consistency. The script performs two main checks:
|
||||
1. Verifies that the number of translation keys in the translation files matches the reference file.
|
||||
2. Ensures that all keys in the translation files are present in the reference file and vice versa.
|
||||
@@ -9,10 +9,10 @@ The script also provides functionality to update the translation files to match
|
||||
adjusting the format.
|
||||
|
||||
Usage:
|
||||
python check_language_toml.py --reference-file <path_to_reference_file> --branch <branch_name> [--actor <actor_name>] [--files <list_of_changed_files>]
|
||||
python check_language_json.py --reference-file <path_to_reference_file> --branch <branch_name> [--actor <actor_name>] [--files <list_of_changed_files>]
|
||||
"""
|
||||
# Sample for Windows:
|
||||
# python .github/scripts/check_language_toml.py --reference-file frontend/public/locales/en-GB/translation.toml --branch "" --files frontend/public/locales/de-DE/translation.toml frontend/public/locales/fr-FR/translation.toml
|
||||
# python .github/scripts/check_language_json.py --reference-file frontend/public/locales/en-GB/translation.json --branch "" --files frontend/public/locales/de-DE/translation.json frontend/public/locales/fr-FR/translation.json
|
||||
|
||||
import copy
|
||||
import glob
|
||||
@@ -20,14 +20,12 @@ import os
|
||||
import argparse
|
||||
import re
|
||||
import json
|
||||
import tomllib # Python 3.11+ (stdlib)
|
||||
import tomli_w # For writing TOML files
|
||||
|
||||
|
||||
def find_duplicate_keys(file_path, keys=None, prefix=""):
|
||||
"""
|
||||
Identifies duplicate keys in a TOML file (including nested keys).
|
||||
:param file_path: Path to the TOML file.
|
||||
Identifies duplicate keys in a JSON file (including nested keys).
|
||||
:param file_path: Path to the JSON file.
|
||||
:param keys: Dictionary to track keys (used for recursion).
|
||||
:param prefix: Prefix for nested keys.
|
||||
:return: List of tuples (key, first_occurrence_path, duplicate_path).
|
||||
@@ -37,9 +35,8 @@ def find_duplicate_keys(file_path, keys=None, prefix=""):
|
||||
|
||||
duplicates = []
|
||||
|
||||
# Load TOML file
|
||||
with open(file_path, 'rb') as file:
|
||||
data = tomllib.load(file)
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
data = json.load(file)
|
||||
|
||||
def process_dict(obj, current_prefix=""):
|
||||
for key, value in obj.items():
|
||||
@@ -57,18 +54,18 @@ def find_duplicate_keys(file_path, keys=None, prefix=""):
|
||||
return duplicates
|
||||
|
||||
|
||||
# Maximum size for TOML files (e.g., 500 KB)
|
||||
# Maximum size for JSON files (e.g., 500 KB)
|
||||
MAX_FILE_SIZE = 500 * 1024
|
||||
|
||||
|
||||
def parse_toml_file(file_path):
|
||||
def parse_json_file(file_path):
|
||||
"""
|
||||
Parses a TOML translation file and returns a flat dictionary of all keys.
|
||||
:param file_path: Path to the TOML file.
|
||||
Parses a JSON translation file and returns a flat dictionary of all keys.
|
||||
:param file_path: Path to the JSON file.
|
||||
:return: Dictionary with flattened keys.
|
||||
"""
|
||||
with open(file_path, 'rb') as file:
|
||||
data = tomllib.load(file)
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
data = json.load(file)
|
||||
|
||||
def flatten_dict(d, parent_key="", sep="."):
|
||||
items = {}
|
||||
@@ -102,37 +99,38 @@ def unflatten_dict(d, sep="."):
|
||||
return result
|
||||
|
||||
|
||||
def write_toml_file(file_path, updated_properties):
|
||||
def write_json_file(file_path, updated_properties):
|
||||
"""
|
||||
Writes updated properties back to the TOML file.
|
||||
:param file_path: Path to the TOML file.
|
||||
Writes updated properties back to the JSON file.
|
||||
:param file_path: Path to the JSON file.
|
||||
:param updated_properties: Dictionary of updated properties to write.
|
||||
"""
|
||||
nested_data = unflatten_dict(updated_properties)
|
||||
|
||||
with open(file_path, "wb") as file:
|
||||
tomli_w.dump(nested_data, file)
|
||||
with open(file_path, "w", encoding="utf-8", newline="\n") as file:
|
||||
json.dump(nested_data, file, ensure_ascii=False, indent=2)
|
||||
file.write("\n") # Add trailing newline
|
||||
|
||||
|
||||
def update_missing_keys(reference_file, file_list, branch=""):
|
||||
"""
|
||||
Updates missing keys in the translation files based on the reference file.
|
||||
:param reference_file: Path to the reference TOML file.
|
||||
:param reference_file: Path to the reference JSON file.
|
||||
:param file_list: List of translation files to update.
|
||||
:param branch: Branch where the files are located.
|
||||
"""
|
||||
reference_properties = parse_toml_file(reference_file)
|
||||
reference_properties = parse_json_file(reference_file)
|
||||
|
||||
for file_path in file_list:
|
||||
basename_current_file = os.path.basename(os.path.join(branch, file_path))
|
||||
if (
|
||||
basename_current_file == os.path.basename(reference_file)
|
||||
or not file_path.endswith(".toml")
|
||||
or not file_path.endswith(".json")
|
||||
or not os.path.dirname(file_path).endswith("locales")
|
||||
):
|
||||
continue
|
||||
|
||||
current_properties = parse_toml_file(os.path.join(branch, file_path))
|
||||
current_properties = parse_json_file(os.path.join(branch, file_path))
|
||||
updated_properties = {}
|
||||
|
||||
for ref_key, ref_value in reference_properties.items():
|
||||
@@ -143,16 +141,16 @@ def update_missing_keys(reference_file, file_list, branch=""):
|
||||
# Add missing key with reference value
|
||||
updated_properties[ref_key] = ref_value
|
||||
|
||||
write_toml_file(os.path.join(branch, file_path), updated_properties)
|
||||
write_json_file(os.path.join(branch, file_path), updated_properties)
|
||||
|
||||
|
||||
def check_for_missing_keys(reference_file, file_list, branch):
|
||||
update_missing_keys(reference_file, file_list, branch)
|
||||
|
||||
|
||||
def read_toml_keys(file_path):
|
||||
def read_json_keys(file_path):
|
||||
if os.path.isfile(file_path) and os.path.exists(file_path):
|
||||
return parse_toml_file(file_path)
|
||||
return parse_json_file(file_path)
|
||||
return {}
|
||||
|
||||
|
||||
@@ -162,7 +160,7 @@ def check_for_differences(reference_file, file_list, branch, actor):
|
||||
|
||||
report = []
|
||||
report.append(f"#### 🔄 Reference Branch: `{reference_branch}`")
|
||||
reference_keys = read_toml_keys(reference_file)
|
||||
reference_keys = read_json_keys(reference_file)
|
||||
has_differences = False
|
||||
|
||||
only_reference_file = True
|
||||
@@ -199,12 +197,12 @@ def check_for_differences(reference_file, file_list, branch, actor):
|
||||
):
|
||||
continue
|
||||
|
||||
if not file_normpath.endswith(".toml") or basename_current_file != "translation.toml":
|
||||
if not file_normpath.endswith(".json") or basename_current_file != "translation.json":
|
||||
continue
|
||||
|
||||
only_reference_file = False
|
||||
report.append(f"#### 📃 **File Check:** `{locale_dir}/{basename_current_file}`")
|
||||
current_keys = read_toml_keys(os.path.join(branch, file_path))
|
||||
current_keys = read_json_keys(os.path.join(branch, file_path))
|
||||
reference_key_count = len(reference_keys)
|
||||
current_key_count = len(current_keys)
|
||||
|
||||
@@ -274,7 +272,7 @@ def check_for_differences(reference_file, file_list, branch, actor):
|
||||
report.append("## ❌ Overall Check Status: **_Failed_**")
|
||||
report.append("")
|
||||
report.append(
|
||||
f"@{actor} please check your translation if it conforms to the standard. Follow the format of [en-GB/translation.toml](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/frontend/public/locales/en-GB/translation.toml)"
|
||||
f"@{actor} please check your translation if it conforms to the standard. Follow the format of [en-GB/translation.json](https://github.com/Stirling-Tools/Stirling-PDF/blob/V2/frontend/public/locales/en-GB/translation.json)"
|
||||
)
|
||||
else:
|
||||
report.append("## ✅ Overall Check Status: **_Success_**")
|
||||
@@ -288,7 +286,7 @@ def check_for_differences(reference_file, file_list, branch, actor):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Find missing keys in TOML translation files")
|
||||
parser = argparse.ArgumentParser(description="Find missing keys")
|
||||
parser.add_argument(
|
||||
"--actor",
|
||||
required=False,
|
||||
@@ -339,9 +337,9 @@ if __name__ == "__main__":
|
||||
"public",
|
||||
"locales",
|
||||
"*",
|
||||
"translation.toml",
|
||||
"translation.json",
|
||||
)
|
||||
)
|
||||
update_missing_keys(args.reference_file, file_list)
|
||||
else:
|
||||
check_for_differences(args.reference_file, file_list, args.branch, args.actor)
|
||||
check_for_differences(args.reference_file, file_list, args.branch, args.actor)
|
||||
@@ -0,0 +1,403 @@
|
||||
"""
|
||||
Author: Ludy87
|
||||
Description: This script processes .properties files for localization checks. It compares translation files in a branch with
|
||||
a reference file to ensure consistency. The script performs two main checks:
|
||||
1. Verifies that the number of lines (including comments and empty lines) in the translation files matches the reference file.
|
||||
2. Ensures that all keys in the translation files are present in the reference file and vice versa.
|
||||
|
||||
The script also provides functionality to update the translation files to match the reference file by adding missing keys and
|
||||
adjusting the format.
|
||||
|
||||
Usage:
|
||||
python check_language_properties.py --reference-file <path_to_reference_file> --branch <branch_name> [--actor <actor_name>] [--files <list_of_changed_files>]
|
||||
"""
|
||||
# Sample for Windows:
|
||||
# python .github/scripts/check_language_properties.py --reference-file src\main\resources\messages_en_GB.properties --branch "" --files src\main\resources\messages_de_DE.properties src\main\resources\messages_uk_UA.properties
|
||||
|
||||
import copy
|
||||
import glob
|
||||
import os
|
||||
import argparse
|
||||
import re
|
||||
|
||||
|
||||
def find_duplicate_keys(file_path):
|
||||
"""
|
||||
Identifies duplicate keys in a .properties file.
|
||||
:param file_path: Path to the .properties file.
|
||||
:return: List of tuples (key, first_occurrence_line, duplicate_line).
|
||||
"""
|
||||
keys = {}
|
||||
duplicates = []
|
||||
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
for line_number, line in enumerate(file, start=1):
|
||||
stripped_line = line.strip()
|
||||
|
||||
# Skip empty lines and comments
|
||||
if not stripped_line or stripped_line.startswith("#"):
|
||||
continue
|
||||
|
||||
# Split the line into key and value
|
||||
if "=" in stripped_line:
|
||||
key, _ = stripped_line.split("=", 1)
|
||||
key = key.strip()
|
||||
|
||||
# Check if the key already exists
|
||||
if key in keys:
|
||||
duplicates.append((key, keys[key], line_number))
|
||||
else:
|
||||
keys[key] = line_number
|
||||
|
||||
return duplicates
|
||||
|
||||
|
||||
# Maximum size for properties files (e.g., 200 KB)
|
||||
MAX_FILE_SIZE = 200 * 1024
|
||||
|
||||
|
||||
def parse_properties_file(file_path):
|
||||
"""
|
||||
Parses a .properties file and returns a structured list of its contents.
|
||||
:param file_path: Path to the .properties file.
|
||||
:return: List of dictionaries representing each line in the file.
|
||||
"""
|
||||
properties_list = []
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
for line_number, line in enumerate(file, start=1):
|
||||
stripped_line = line.strip()
|
||||
|
||||
# Handle empty lines
|
||||
if not stripped_line:
|
||||
properties_list.append(
|
||||
{"line_number": line_number, "type": "empty", "content": ""}
|
||||
)
|
||||
continue
|
||||
|
||||
# Handle comments
|
||||
if stripped_line.startswith("#"):
|
||||
properties_list.append(
|
||||
{
|
||||
"line_number": line_number,
|
||||
"type": "comment",
|
||||
"content": stripped_line,
|
||||
}
|
||||
)
|
||||
continue
|
||||
|
||||
# Handle key-value pairs
|
||||
match = re.match(r"^([^=]+)=(.*)$", line)
|
||||
if match:
|
||||
key, value = match.groups()
|
||||
properties_list.append(
|
||||
{
|
||||
"line_number": line_number,
|
||||
"type": "entry",
|
||||
"key": key.strip(),
|
||||
"value": value.strip(),
|
||||
}
|
||||
)
|
||||
|
||||
return properties_list
|
||||
|
||||
|
||||
def write_json_file(file_path, updated_properties):
|
||||
"""
|
||||
Writes updated properties back to the file in their original format.
|
||||
:param file_path: Path to the .properties file.
|
||||
:param updated_properties: List of updated properties to write.
|
||||
"""
|
||||
updated_lines = {entry["line_number"]: entry for entry in updated_properties}
|
||||
|
||||
# Sort lines by their numbers and retain comments and empty lines
|
||||
all_lines = sorted(set(updated_lines.keys()))
|
||||
|
||||
original_format = []
|
||||
for line in all_lines:
|
||||
if line in updated_lines:
|
||||
entry = updated_lines[line]
|
||||
else:
|
||||
entry = None
|
||||
ref_entry = updated_lines[line]
|
||||
if ref_entry["type"] in ["comment", "empty"]:
|
||||
original_format.append(ref_entry)
|
||||
elif entry is None:
|
||||
# Add missing entries from the reference file
|
||||
original_format.append(ref_entry)
|
||||
elif entry["type"] == "entry":
|
||||
# Replace entries with those from the current JSON
|
||||
original_format.append(entry)
|
||||
|
||||
# Write the updated content back to the file
|
||||
with open(file_path, "w", encoding="utf-8", newline="\n") as file:
|
||||
for entry in original_format:
|
||||
if entry["type"] == "comment":
|
||||
file.write(f"{entry['content']}\n")
|
||||
elif entry["type"] == "empty":
|
||||
file.write(f"{entry['content']}\n")
|
||||
elif entry["type"] == "entry":
|
||||
file.write(f"{entry['key']}={entry['value']}\n")
|
||||
|
||||
|
||||
def update_missing_keys(reference_file, file_list, branch=""):
|
||||
"""
|
||||
Updates missing keys in the translation files based on the reference file.
|
||||
:param reference_file: Path to the reference .properties file.
|
||||
:param file_list: List of translation files to update.
|
||||
:param branch: Branch where the files are located.
|
||||
"""
|
||||
reference_properties = parse_properties_file(reference_file)
|
||||
for file_path in file_list:
|
||||
basename_current_file = os.path.basename(os.path.join(branch, file_path))
|
||||
if (
|
||||
basename_current_file == os.path.basename(reference_file)
|
||||
or not file_path.endswith(".properties")
|
||||
or not basename_current_file.startswith("messages_")
|
||||
):
|
||||
continue
|
||||
|
||||
current_properties = parse_properties_file(os.path.join(branch, file_path))
|
||||
updated_properties = []
|
||||
for ref_entry in reference_properties:
|
||||
ref_entry_copy = copy.deepcopy(ref_entry)
|
||||
for current_entry in current_properties:
|
||||
if current_entry["type"] == "entry":
|
||||
if ref_entry_copy["type"] != "entry":
|
||||
continue
|
||||
if ref_entry_copy["key"].lower() == current_entry["key"].lower():
|
||||
ref_entry_copy["value"] = current_entry["value"]
|
||||
updated_properties.append(ref_entry_copy)
|
||||
write_json_file(os.path.join(branch, file_path), updated_properties)
|
||||
|
||||
|
||||
def check_for_missing_keys(reference_file, file_list, branch):
|
||||
update_missing_keys(reference_file, file_list, branch)
|
||||
|
||||
|
||||
def read_properties(file_path):
|
||||
if os.path.isfile(file_path) and os.path.exists(file_path):
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
return file.read().splitlines()
|
||||
return [""]
|
||||
|
||||
|
||||
def check_for_differences(reference_file, file_list, branch, actor):
|
||||
reference_branch = reference_file.split("/")[0]
|
||||
basename_reference_file = os.path.basename(reference_file)
|
||||
|
||||
report = []
|
||||
report.append(f"#### 🔄 Reference Branch: `{reference_branch}`")
|
||||
reference_lines = read_properties(reference_file)
|
||||
has_differences = False
|
||||
|
||||
only_reference_file = True
|
||||
|
||||
file_arr = file_list
|
||||
|
||||
if len(file_list) == 1:
|
||||
file_arr = file_list[0].split()
|
||||
base_dir = os.path.abspath(
|
||||
os.path.join(os.getcwd(), "app", "core", "src", "main", "resources")
|
||||
)
|
||||
|
||||
for file_path in file_arr:
|
||||
file_normpath = os.path.normpath(file_path)
|
||||
absolute_path = os.path.abspath(file_normpath)
|
||||
# Verify that file is within the expected directory
|
||||
if not absolute_path.startswith(base_dir):
|
||||
raise ValueError(f"Unsafe file found: {file_normpath}")
|
||||
# Verify file size before processing
|
||||
if os.path.getsize(os.path.join(branch, file_normpath)) > MAX_FILE_SIZE:
|
||||
raise ValueError(
|
||||
f"The file {file_normpath} is too large and could pose a security risk."
|
||||
)
|
||||
|
||||
basename_current_file = os.path.basename(os.path.join(branch, file_normpath))
|
||||
if (
|
||||
basename_current_file == basename_reference_file
|
||||
or (
|
||||
# only local windows command
|
||||
not file_normpath.startswith(
|
||||
os.path.join(
|
||||
"", "app", "core", "src", "main", "resources", "messages_"
|
||||
)
|
||||
)
|
||||
and not file_normpath.startswith(
|
||||
os.path.join(
|
||||
os.getcwd(),
|
||||
"app",
|
||||
"core",
|
||||
"src",
|
||||
"main",
|
||||
"resources",
|
||||
"messages_",
|
||||
)
|
||||
)
|
||||
)
|
||||
or not file_normpath.endswith(".properties")
|
||||
or not basename_current_file.startswith("messages_")
|
||||
):
|
||||
continue
|
||||
only_reference_file = False
|
||||
report.append(f"#### 📃 **File Check:** `{basename_current_file}`")
|
||||
current_lines = read_properties(os.path.join(branch, file_path))
|
||||
reference_line_count = len(reference_lines)
|
||||
current_line_count = len(current_lines)
|
||||
|
||||
if reference_line_count != current_line_count:
|
||||
report.append("")
|
||||
report.append("1. **Test Status:** ❌ **_Failed_**")
|
||||
report.append(" - **Issue:**")
|
||||
has_differences = True
|
||||
if reference_line_count > current_line_count:
|
||||
report.append(
|
||||
f" - **_Mismatched line count_**: {reference_line_count} (reference) vs {current_line_count} (current). Comments, empty lines, or translation strings are missing."
|
||||
)
|
||||
elif reference_line_count < current_line_count:
|
||||
report.append(
|
||||
f" - **_Too many lines_**: {reference_line_count} (reference) vs {current_line_count} (current). Please verify if there is an additional line that needs to be removed."
|
||||
)
|
||||
else:
|
||||
report.append("1. **Test Status:** ✅ **_Passed_**")
|
||||
|
||||
# Check for missing or extra keys
|
||||
current_keys = []
|
||||
reference_keys = []
|
||||
for line in current_lines:
|
||||
if not line.startswith("#") and line != "" and "=" in line:
|
||||
key, _ = line.split("=", 1)
|
||||
current_keys.append(key)
|
||||
for line in reference_lines:
|
||||
if not line.startswith("#") and line != "" and "=" in line:
|
||||
key, _ = line.split("=", 1)
|
||||
reference_keys.append(key)
|
||||
|
||||
current_keys_set = set(current_keys)
|
||||
reference_keys_set = set(reference_keys)
|
||||
missing_keys = current_keys_set.difference(reference_keys_set)
|
||||
extra_keys = reference_keys_set.difference(current_keys_set)
|
||||
missing_keys_list = list(missing_keys)
|
||||
extra_keys_list = list(extra_keys)
|
||||
|
||||
if missing_keys_list or extra_keys_list:
|
||||
has_differences = True
|
||||
missing_keys_str = "`, `".join(missing_keys_list)
|
||||
extra_keys_str = "`, `".join(extra_keys_list)
|
||||
report.append("2. **Test Status:** ❌ **_Failed_**")
|
||||
report.append(" - **Issue:**")
|
||||
if missing_keys_list:
|
||||
spaces_keys_list = []
|
||||
for key in missing_keys_list:
|
||||
if " " in key:
|
||||
spaces_keys_list.append(key)
|
||||
if spaces_keys_list:
|
||||
spaces_keys_str = "`, `".join(spaces_keys_list)
|
||||
report.append(
|
||||
f" - **_Keys containing unnecessary spaces_**: `{spaces_keys_str}`!"
|
||||
)
|
||||
report.append(
|
||||
f" - **_Extra keys in `{basename_current_file}`_**: `{missing_keys_str}` that are not present in **_`{basename_reference_file}`_**."
|
||||
)
|
||||
if extra_keys_list:
|
||||
report.append(
|
||||
f" - **_Missing keys in `{basename_reference_file}`_**: `{extra_keys_str}` that are not present in **_`{basename_current_file}`_**."
|
||||
)
|
||||
else:
|
||||
report.append("2. **Test Status:** ✅ **_Passed_**")
|
||||
|
||||
if find_duplicate_keys(os.path.join(branch, file_normpath)):
|
||||
has_differences = True
|
||||
output = "\n".join(
|
||||
[
|
||||
f" - `{key}`: first at line {first}, duplicate at `line {duplicate}`"
|
||||
for key, first, duplicate in find_duplicate_keys(
|
||||
os.path.join(branch, file_normpath)
|
||||
)
|
||||
]
|
||||
)
|
||||
report.append("3. **Test Status:** ❌ **_Failed_**")
|
||||
report.append(" - **Issue:**")
|
||||
report.append(" - duplicate entries were found:")
|
||||
report.append(output)
|
||||
else:
|
||||
report.append("3. **Test Status:** ✅ **_Passed_**")
|
||||
|
||||
report.append("")
|
||||
report.append("---")
|
||||
report.append("")
|
||||
if has_differences:
|
||||
report.append("## ❌ Overall Check Status: **_Failed_**")
|
||||
report.append("")
|
||||
report.append(
|
||||
f"@{actor} please check your translation if it conforms to the standard. Follow the format of [messages_en_GB.properties](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/app/core/src/main/resources/messages_en_GB.properties)"
|
||||
)
|
||||
else:
|
||||
report.append("## ✅ Overall Check Status: **_Success_**")
|
||||
report.append("")
|
||||
report.append(
|
||||
f"Thanks @{actor} for your help in keeping the translations up to date."
|
||||
)
|
||||
|
||||
if not only_reference_file:
|
||||
print("\n".join(report))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Find missing keys")
|
||||
parser.add_argument(
|
||||
"--actor",
|
||||
required=False,
|
||||
help="Actor from PR.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--reference-file",
|
||||
required=True,
|
||||
help="Path to the reference file.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--branch",
|
||||
type=str,
|
||||
required=True,
|
||||
help="Branch name.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--check-file",
|
||||
type=str,
|
||||
required=False,
|
||||
help="List of changed files, separated by spaces.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--files",
|
||||
nargs="+",
|
||||
required=False,
|
||||
help="List of changed files, separated by spaces.",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
# Sanitize --actor input to avoid injection attacks
|
||||
if args.actor:
|
||||
args.actor = re.sub(r"[^a-zA-Z0-9_\\-]", "", args.actor)
|
||||
|
||||
# Sanitize --branch input to avoid injection attacks
|
||||
if args.branch:
|
||||
args.branch = re.sub(r"[^a-zA-Z0-9\\-]", "", args.branch)
|
||||
|
||||
file_list = args.files
|
||||
if file_list is None:
|
||||
if args.check_file:
|
||||
file_list = [args.check_file]
|
||||
else:
|
||||
file_list = glob.glob(
|
||||
os.path.join(
|
||||
os.getcwd(),
|
||||
"app",
|
||||
"core",
|
||||
"src",
|
||||
"main",
|
||||
"resources",
|
||||
"messages_*.properties",
|
||||
)
|
||||
)
|
||||
update_missing_keys(args.reference_file, file_list)
|
||||
else:
|
||||
check_for_differences(args.reference_file, file_list, args.branch, args.actor)
|
||||
@@ -180,7 +180,7 @@ jobs:
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:pr-${{ needs.check-comment.outputs.pr_number }}
|
||||
build-args: VERSION_TAG=alpha
|
||||
|
||||
@@ -262,7 +262,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
docker-rev: ["docker/embedded/Dockerfile", "docker/embedded/Dockerfile.ultra-lite", "docker/embedded/Dockerfile.fat"]
|
||||
docker-rev: ["Dockerfile", "Dockerfile.ultra-lite", "Dockerfile.fat"]
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
|
||||
@@ -301,7 +301,7 @@ jobs:
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
file: ./${{ matrix.docker-rev }}
|
||||
file: ./docker/backend/${{ matrix.docker-rev }}
|
||||
push: false
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
name: Check TOML Translation Files on PR
|
||||
|
||||
# This workflow validates TOML translation files
|
||||
name: Check Properties Files on PR
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths:
|
||||
- "frontend/public/locales/*/translation.toml"
|
||||
- "app/core/src/main/resources/messages_*.properties"
|
||||
|
||||
# cancel in-progress jobs if a new job is triggered
|
||||
# This is useful to avoid running multiple builds for the same branch if a new commit is pushed
|
||||
# or a pull request is updated.
|
||||
# It helps to save resources and time by ensuring that only the latest commit is built and tested
|
||||
# This is particularly useful for long-running jobs that may take a while to complete.
|
||||
# The `group` is set to a combination of the workflow name, event name, and branch name.
|
||||
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
|
||||
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref_name || github.ref }}
|
||||
cancel-in-progress: true
|
||||
@@ -68,22 +73,22 @@ jobs:
|
||||
run: |
|
||||
echo "Fetching PR changed files..."
|
||||
echo "Getting list of changed files from PR..."
|
||||
# Check if PR number exists
|
||||
if [ -z "${{ steps.get-pr-data.outputs.pr_number }}" ]; then
|
||||
echo "Error: PR number is empty"
|
||||
exit 1
|
||||
fi
|
||||
# Get changed files and filter for TOML translation files
|
||||
gh pr view ${{ steps.get-pr-data.outputs.pr_number }} --json files -q ".files[].path" | grep -E '^frontend/public/locales/[a-zA-Z-]+/translation\.toml$' > changed_files.txt || echo "No matching TOML files found in PR"
|
||||
# Check if any files were found
|
||||
if [ ! -s changed_files.txt ]; then
|
||||
echo "No TOML translation files changed in this PR"
|
||||
echo "Workflow will exit early as no relevant files to check"
|
||||
exit 0
|
||||
fi
|
||||
echo "Found $(wc -l < changed_files.txt) matching TOML files"
|
||||
# Check if PR number exists
|
||||
if [ -z "${{ steps.get-pr-data.outputs.pr_number }}" ]; then
|
||||
echo "Error: PR number is empty"
|
||||
exit 1
|
||||
fi
|
||||
# Get changed files and filter for properties files, handle case where no matches are found
|
||||
gh pr view ${{ steps.get-pr-data.outputs.pr_number }} --json files -q ".files[].path" | grep -E '^app/core/src/main/resources/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}\.properties$' > changed_files.txt || echo "No matching properties files found in PR"
|
||||
# Check if any files were found
|
||||
if [ ! -s changed_files.txt ]; then
|
||||
echo "No properties files changed in this PR"
|
||||
echo "Workflow will exit early as no relevant files to check"
|
||||
exit 0
|
||||
fi
|
||||
echo "Found $(wc -l < changed_files.txt) matching properties files"
|
||||
|
||||
- name: Determine reference file
|
||||
- name: Determine reference file test
|
||||
id: determine-file
|
||||
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
|
||||
with:
|
||||
@@ -120,11 +125,11 @@ jobs:
|
||||
pull_number: prNumber,
|
||||
});
|
||||
|
||||
// Filter for relevant TOML files based on the PR changes
|
||||
// Filter for relevant files based on the PR changes
|
||||
const changedFiles = files
|
||||
.filter(file =>
|
||||
file.status !== "removed" &&
|
||||
/^frontend\/public\/locales\/[a-zA-Z-]+\/translation\.toml$/.test(file.filename)
|
||||
/^app\/core\/src\/main\/resources\/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}\.properties$/.test(file.filename)
|
||||
)
|
||||
.map(file => file.filename);
|
||||
|
||||
@@ -164,16 +169,16 @@ jobs:
|
||||
|
||||
// Determine reference file
|
||||
let referenceFilePath;
|
||||
if (changedFiles.includes("frontend/public/locales/en-GB/translation.toml")) {
|
||||
if (changedFiles.includes("app/core/src/main/resources/messages_en_GB.properties")) {
|
||||
console.log("Using PR branch reference file.");
|
||||
const { data: fileContent } = await github.rest.repos.getContent({
|
||||
owner: prRepoOwner,
|
||||
repo: prRepoName,
|
||||
path: "frontend/public/locales/en-GB/translation.toml",
|
||||
path: "app/core/src/main/resources/messages_en_GB.properties",
|
||||
ref: branch,
|
||||
});
|
||||
|
||||
referenceFilePath = "pr-branch-translation-en-GB.toml";
|
||||
referenceFilePath = "pr-branch-messages_en_GB.properties";
|
||||
const content = Buffer.from(fileContent.content, "base64").toString("utf-8");
|
||||
fs.writeFileSync(referenceFilePath, content);
|
||||
} else {
|
||||
@@ -181,11 +186,11 @@ jobs:
|
||||
const { data: fileContent } = await github.rest.repos.getContent({
|
||||
owner: repoOwner,
|
||||
repo: repoName,
|
||||
path: "frontend/public/locales/en-GB/translation.toml",
|
||||
path: "app/core/src/main/resources/messages_en_GB.properties",
|
||||
ref: "main",
|
||||
});
|
||||
|
||||
referenceFilePath = "main-branch-translation-en-GB.toml";
|
||||
referenceFilePath = "main-branch-messages_en_GB.properties";
|
||||
const content = Buffer.from(fileContent.content, "base64").toString("utf-8");
|
||||
fs.writeFileSync(referenceFilePath, content);
|
||||
}
|
||||
@@ -193,20 +198,11 @@ jobs:
|
||||
console.log(`Reference file path: ${referenceFilePath}`);
|
||||
core.exportVariable("REFERENCE_FILE", referenceFilePath);
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
pip install tomli-w
|
||||
|
||||
- name: Run Python script to check files
|
||||
id: run-check
|
||||
run: |
|
||||
echo "Running Python script to check TOML files..."
|
||||
python .github/scripts/check_language_toml.py \
|
||||
echo "Running Python script to check files..."
|
||||
python .github/scripts/check_language_properties.py \
|
||||
--actor ${{ github.event.pull_request.user.login }} \
|
||||
--reference-file "${REFERENCE_FILE}" \
|
||||
--branch "pr-branch" \
|
||||
@@ -217,7 +213,7 @@ jobs:
|
||||
id: capture-output
|
||||
run: |
|
||||
if [ -f result.txt ] && [ -s result.txt ]; then
|
||||
echo "Capturing output..."
|
||||
echo "Test, capturing output..."
|
||||
SCRIPT_OUTPUT=$(cat result.txt)
|
||||
echo "SCRIPT_OUTPUT<<EOF" >> $GITHUB_ENV
|
||||
echo "$SCRIPT_OUTPUT" >> $GITHUB_ENV
|
||||
@@ -231,7 +227,7 @@ jobs:
|
||||
echo "FAIL_JOB=false" >> $GITHUB_ENV
|
||||
fi
|
||||
else
|
||||
echo "No output found."
|
||||
echo "No update found."
|
||||
echo "SCRIPT_OUTPUT=" >> $GITHUB_ENV
|
||||
echo "FAIL_JOB=false" >> $GITHUB_ENV
|
||||
fi
|
||||
@@ -253,7 +249,7 @@ jobs:
|
||||
issue_number: issueNumber
|
||||
});
|
||||
|
||||
const comment = comments.data.find(c => c.body.includes("## 🌐 TOML Translation Verification Summary"));
|
||||
const comment = comments.data.find(c => c.body.includes("## 🚀 Translation Verification Summary"));
|
||||
|
||||
// Only update or create comments by the action user
|
||||
const expectedActor = "${{ steps.setup-bot.outputs.app-slug }}[bot]";
|
||||
@@ -264,7 +260,7 @@ jobs:
|
||||
owner: repoOwner,
|
||||
repo: repoName,
|
||||
comment_id: comment.id,
|
||||
body: `## 🌐 TOML Translation Verification Summary\n\n\n${SCRIPT_OUTPUT}\n`
|
||||
body: `## 🚀 Translation Verification Summary\n\n\n${SCRIPT_OUTPUT}\n`
|
||||
});
|
||||
console.log("Updated existing comment.");
|
||||
} else if (!comment) {
|
||||
@@ -273,7 +269,7 @@ jobs:
|
||||
owner: repoOwner,
|
||||
repo: repoName,
|
||||
issue_number: issueNumber,
|
||||
body: `## 🌐 TOML Translation Verification Summary\n\n\n${SCRIPT_OUTPUT}\n`
|
||||
body: `## 🚀 Translation Verification Summary\n\n\n${SCRIPT_OUTPUT}\n`
|
||||
});
|
||||
console.log("Created new comment.");
|
||||
} else {
|
||||
@@ -291,6 +287,6 @@ jobs:
|
||||
run: |
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -rf pr-branch
|
||||
rm -f pr-branch-translation-en-GB.toml main-branch-translation-en-GB.toml changed_files.txt result.txt
|
||||
rm -f pr-branch-messages_en_GB.properties main-branch-messages_en_GB.properties changed_files.txt result.txt
|
||||
echo "Cleanup complete."
|
||||
continue-on-error: true # Ensure cleanup runs even if previous steps fail
|
||||
@@ -5,7 +5,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- V2-master
|
||||
- alljavadocker
|
||||
|
||||
# cancel in-progress jobs if a new job is triggered
|
||||
# This is useful to avoid running multiple builds for the same branch if a new commit is pushed
|
||||
@@ -94,10 +93,10 @@ jobs:
|
||||
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}
|
||||
type=raw,value=latest
|
||||
|
||||
- name: Generate tags for latest (alljavadocker branch - test)
|
||||
- name: Generate tags for latest (V2-demo branch - test)
|
||||
id: meta-test
|
||||
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||
if: github.ref == 'refs/heads/alljavadocker'
|
||||
if: github.ref == 'refs/heads/V2-demo'
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/stirling-tools/stirling-pdf-test
|
||||
@@ -111,7 +110,7 @@ jobs:
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile
|
||||
file: ./docker/Dockerfile.unified
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
@@ -150,10 +149,10 @@ jobs:
|
||||
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-fat
|
||||
type=raw,value=latest-fat
|
||||
|
||||
- name: Generate tags for latest-fat (alljavadocker branch - test)
|
||||
- name: Generate tags for latest-fat (V2-demo branch - test)
|
||||
id: meta-fat-test
|
||||
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||
if: github.ref == 'refs/heads/alljavadocker'
|
||||
if: github.ref == 'refs/heads/V2-demo'
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/stirling-tools/stirling-pdf-test
|
||||
@@ -167,7 +166,7 @@ jobs:
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile.fat
|
||||
file: ./docker/Dockerfile.unified
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
@@ -204,10 +203,10 @@ jobs:
|
||||
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-ultra-lite
|
||||
type=raw,value=latest-ultra-lite
|
||||
|
||||
- name: Generate tags for ultra-lite (alljavadocker branch - test)
|
||||
- name: Generate tags for ultra-lite (V2-demo branch - test)
|
||||
id: meta-lite-test
|
||||
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||
if: github.ref == 'refs/heads/alljavadocker'
|
||||
if: github.ref == 'refs/heads/V2-demo'
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/stirling-tools/stirling-pdf-test
|
||||
@@ -221,7 +220,7 @@ jobs:
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile.ultra-lite
|
||||
file: ./docker/Dockerfile.unified-lite
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
if: github.ref != 'refs/heads/main'
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile.ultra-lite
|
||||
file: ./Dockerfile.ultra-lite
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
@@ -183,7 +183,7 @@ jobs:
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile.fat
|
||||
file: ./Dockerfile.fat
|
||||
push: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
name: Sync Files
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "build.gradle"
|
||||
- "README.md"
|
||||
- "app/core/src/main/resources/messages_*.properties"
|
||||
- "app/core/src/main/resources/static/3rdPartyLicenses.json"
|
||||
- "scripts/ignore_translation.toml"
|
||||
|
||||
# cancel in-progress jobs if a new job is triggered
|
||||
# This is useful to avoid running multiple builds for the same branch if a new commit is pushed
|
||||
# or a pull request is updated.
|
||||
# It helps to save resources and time by ensuring that only the latest commit is built and tested
|
||||
# This is particularly useful for long-running jobs that may take a while to complete.
|
||||
# The `group` is set to a combination of the workflow name, event name, and branch name.
|
||||
# This ensures that jobs are grouped by the workflow and branch, allowing for cancellation of
|
||||
# in-progress jobs when a new commit is pushed to the same branch or a new pull request is opened.
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref_name || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
sync-files:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# Prevents sdist builds → no tar extraction
|
||||
PIP_ONLY_BINARY: ":all:"
|
||||
PIP_DISABLE_PIP_VERSION_CHECK: "1"
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
- name: Setup GitHub App Bot
|
||||
id: setup-bot
|
||||
uses: ./.github/actions/setup-bot
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: "pip" # caching pip dependencies
|
||||
|
||||
- name: Sync translation property files
|
||||
run: |
|
||||
python .github/scripts/check_language_properties.py --reference-file "app/core/src/main/resources/messages_en_GB.properties" --branch main
|
||||
|
||||
- name: Commit translation files
|
||||
run: |
|
||||
git add app/core/src/main/resources/messages_*.properties
|
||||
git diff --staged --quiet || git commit -m ":memo: Sync translation files" || echo "No changes detected"
|
||||
|
||||
- name: Install dependencies
|
||||
# Wheels-only + Hash-Pinning
|
||||
run: |
|
||||
pip install --require-hashes --only-binary=:all: -r ./.github/scripts/requirements_sync_readme.txt
|
||||
|
||||
- name: Sync README.md
|
||||
run: |
|
||||
python scripts/counter_translation.py
|
||||
|
||||
- name: Run git add
|
||||
run: |
|
||||
git add README.md scripts/ignore_translation.toml
|
||||
git diff --staged --quiet || git commit -m ":memo: Sync README.md & scripts/ignore_translation.toml" || echo "No changes detected"
|
||||
|
||||
- name: Create Pull Request
|
||||
if: always()
|
||||
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
||||
with:
|
||||
token: ${{ steps.setup-bot.outputs.token }}
|
||||
commit-message: Update files
|
||||
committer: ${{ steps.setup-bot.outputs.committer }}
|
||||
author: ${{ steps.setup-bot.outputs.committer }}
|
||||
signoff: true
|
||||
branch: sync_readme
|
||||
title: ":globe_with_meridians: Sync Translations + Update README Progress Table"
|
||||
body: |
|
||||
### Description of Changes
|
||||
|
||||
This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made:
|
||||
|
||||
#### **1. Synchronization of Translation Files**
|
||||
- Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`.
|
||||
- Ensured consistency and synchronization across all supported language files.
|
||||
- Highlighted any missing or incomplete translations.
|
||||
|
||||
#### **2. Update README.md**
|
||||
- Generated the translation progress table in `README.md`.
|
||||
- Added a summary of the current translation status for all supported languages.
|
||||
- Included up-to-date statistics on translation coverage.
|
||||
|
||||
#### **Why these changes are necessary**
|
||||
- Keeps translation files aligned with the latest reference updates.
|
||||
- Ensures the documentation reflects the current translation progress.
|
||||
|
||||
---
|
||||
|
||||
Auto-generated by [create-pull-request][1].
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
draft: false
|
||||
delete-branch: true
|
||||
labels: github-actions
|
||||
sign-commits: true
|
||||
add-paths: |
|
||||
README.md
|
||||
app/core/src/main/resources/messages_*.properties
|
||||
@@ -1,15 +1,15 @@
|
||||
name: Sync Files (TOML)
|
||||
name: Sync Files V2
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- V2
|
||||
- syncLangTest
|
||||
paths:
|
||||
- "build.gradle"
|
||||
- "README.md"
|
||||
- "frontend/public/locales/*/translation.toml"
|
||||
- "frontend/public/locales/*/translation.json"
|
||||
- "app/core/src/main/resources/static/3rdPartyLicenses.json"
|
||||
- "scripts/ignore_translation.toml"
|
||||
|
||||
@@ -52,25 +52,21 @@ jobs:
|
||||
python-version: "3.12"
|
||||
cache: "pip" # caching pip dependencies
|
||||
|
||||
- name: Install Python dependencies
|
||||
- name: Sync translation JSON files
|
||||
run: |
|
||||
pip install tomli-w
|
||||
|
||||
- name: Sync translation TOML files
|
||||
run: |
|
||||
python .github/scripts/check_language_toml.py --reference-file "frontend/public/locales/en-GB/translation.toml" --branch main
|
||||
python .github/scripts/check_language_json.py --reference-file "frontend/public/locales/en-GB/translation.json" --branch V2
|
||||
|
||||
- name: Commit translation files
|
||||
run: |
|
||||
git add frontend/public/locales/*/translation.toml
|
||||
git diff --staged --quiet || git commit -m ":memo: Sync translation files (TOML)" || echo "No changes detected"
|
||||
git add frontend/public/locales/*/translation.json
|
||||
git diff --staged --quiet || git commit -m ":memo: Sync translation files" || echo "No changes detected"
|
||||
|
||||
- name: Install README dependencies
|
||||
- name: Install dependencies
|
||||
run: pip install --require-hashes -r ./.github/scripts/requirements_sync_readme.txt
|
||||
|
||||
- name: Sync README.md
|
||||
run: |
|
||||
python scripts/counter_translation_v3.py
|
||||
python scripts/counter_translation_v2.py
|
||||
|
||||
- name: Run git add
|
||||
run: |
|
||||
@@ -86,22 +82,21 @@ jobs:
|
||||
committer: ${{ steps.setup-bot.outputs.committer }}
|
||||
author: ${{ steps.setup-bot.outputs.committer }}
|
||||
signoff: true
|
||||
branch: sync_readme_v3
|
||||
base: main
|
||||
title: ":globe_with_meridians: Sync Translations + Update README Progress Table"
|
||||
branch: sync_readme_v2
|
||||
base: V2
|
||||
title: ":globe_with_meridians: [V2] Sync Translations + Update README Progress Table"
|
||||
body: |
|
||||
### Description of Changes
|
||||
|
||||
This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made:
|
||||
This Pull Request was automatically generated to synchronize updates to translation files and documentation for the **V2 branch**. Below are the details of the changes made:
|
||||
|
||||
#### **1. Synchronization of Translation Files**
|
||||
- Updated translation files (`frontend/public/locales/*/translation.toml`) to reflect changes in the reference file `en-GB/translation.toml`.
|
||||
- Updated translation files (`frontend/public/locales/*/translation.json`) to reflect changes in the reference file `en-GB/translation.json`.
|
||||
- Ensured consistency and synchronization across all supported language files.
|
||||
- Highlighted any missing or incomplete translations.
|
||||
- **Format**: TOML
|
||||
|
||||
#### **2. Update README.md**
|
||||
- Generated the translation progress table in `README.md` using `counter_translation_v3.py`.
|
||||
- Generated the translation progress table in `README.md`.
|
||||
- Added a summary of the current translation status for all supported languages.
|
||||
- Included up-to-date statistics on translation coverage.
|
||||
|
||||
@@ -120,5 +115,4 @@ jobs:
|
||||
sign-commits: true
|
||||
add-paths: |
|
||||
README.md
|
||||
frontend/public/locales/*/translation.toml
|
||||
scripts/ignore_translation.toml
|
||||
frontend/public/locales/*/translation.json
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||
with:
|
||||
context: .
|
||||
file: ./docker/embedded/Dockerfile
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:test-${{ github.sha }}
|
||||
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
|
||||
|
||||
+3
-3
@@ -202,10 +202,10 @@ const [ToolName] = (props: BaseToolProps) => {
|
||||
## 5. Add Translations
|
||||
Update translation files. **Important: Only update `en-GB` files** - other languages are handled separately.
|
||||
|
||||
**File to update:** `frontend/public/locales/en-GB/translation.toml`
|
||||
**File to update:** `frontend/public/locales/en-GB/translation.json`
|
||||
|
||||
**Required Translation Keys**:
|
||||
```toml
|
||||
```json
|
||||
{
|
||||
"home": {
|
||||
"[toolName]": {
|
||||
@@ -251,7 +251,7 @@ Update translation files. **Important: Only update `en-GB` files** - other langu
|
||||
```
|
||||
|
||||
**Translation Notes:**
|
||||
- **Only update `en-GB/translation.toml`** - other locale files are managed separately
|
||||
- **Only update `en-GB/translation.json`** - other locale files are managed separately
|
||||
- Use descriptive keys that match your component's `t()` calls
|
||||
- Include tooltip translations if you created tooltip hooks
|
||||
- Add `options.*` keys if your tool has settings with descriptions
|
||||
|
||||
@@ -1,69 +1,173 @@
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/main/docs/stirling.png" width="80" alt="Stirling PDF logo">
|
||||
</p>
|
||||
<p align="center"><img src="https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/main/docs/stirling.png" width="80"></p>
|
||||
<h1 align="center">Stirling-PDF</h1>
|
||||
|
||||
<h1 align="center">Stirling PDF - The Open-Source PDF Platform</h1>
|
||||
[](https://hub.docker.com/r/frooodle/s-pdf)
|
||||
[](https://discord.gg/HYmhKj45pU)
|
||||
[](https://scorecard.dev/viewer/?uri=github.com/Stirling-Tools/Stirling-PDF)
|
||||
[](https://github.com/Stirling-Tools/stirling-pdf)
|
||||
|
||||
Stirling PDF is a powerful, open-source PDF editing platform. Run it as a personal desktop app, in the browser, or deploy it on your own servers with a private API. Edit, sign, redact, convert, and automate PDFs without sending documents to external services.
|
||||
<a href="https://www.producthunt.com/posts/stirling-pdf?embed=true&utm_source=badge-featured&utm_medium=badge&utm_souce=badge-stirling-pdf" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=641239&theme=light" alt="Stirling PDF - Open source locally hosted web PDF editor | Product Hunt" style="width: 250px; height: 54px;" width="250" height="54" /></a>
|
||||
[](https://cloud.digitalocean.com/apps/new?repo=https://github.com/Stirling-Tools/Stirling-PDF/tree/digitalOcean&refcode=c3210994b1af)
|
||||
|
||||
<p align="center">
|
||||
<a href="https://hub.docker.com/r/stirlingtools/stirling-pdf">
|
||||
<img src="https://img.shields.io/docker/pulls/frooodle/s-pdf" alt="Docker Pulls">
|
||||
</a>
|
||||
<a href="https://discord.gg/HYmhKj45pU">
|
||||
<img src="https://img.shields.io/discord/1068636748814483718?label=Discord" alt="Discord">
|
||||
</a>
|
||||
<a href="https://scorecard.dev/viewer/?uri=github.com/Stirling-Tools/Stirling-PDF">
|
||||
<img src="https://api.scorecard.dev/projects/github.com/Stirling-Tools/Stirling-PDF/badge" alt="OpenSSF Scorecard">
|
||||
</a>
|
||||
<a href="https://github.com/Stirling-Tools/stirling-pdf">
|
||||
<img src="https://img.shields.io/github/stars/stirling-tools/stirling-pdf?style=social" alt="GitHub Repo stars">
|
||||
</a>
|
||||
</p>
|
||||
[Stirling-PDF](https://www.stirlingpdf.com) is a robust, locally hosted web-based PDF manipulation tool using Docker. It enables you to carry out various operations on PDF files, including splitting, merging, converting, reorganizing, adding images, rotating, compressing, and more. This locally hosted web application has evolved to encompass a comprehensive set of features, addressing all your PDF requirements.
|
||||
|
||||

|
||||
All files and PDFs exist either exclusively on the client side, reside in server memory only during task execution, or temporarily reside in a file solely for the execution of the task. Any file downloaded by the user will have been deleted from the server by that point.
|
||||
|
||||
## Key Capabilities
|
||||
Homepage: [https://stirlingpdf.com](https://stirlingpdf.com)
|
||||
|
||||
- **Everywhere you work** - Desktop client, browser UI, and self-hosted server with a private API.
|
||||
- **50+ PDF tools** - Edit, merge, split, sign, redact, convert, OCR, compress, and more.
|
||||
- **Automation & workflows** - No-code pipelines direct in UI with APIs to process millions of PDFs.
|
||||
- **Enterprise‑grade** - SSO, auditing, and flexible on‑prem deployments.
|
||||
- **Developer platform** - REST APIs available for nearly all tools to integrate into your existing systems.
|
||||
- **Global UI** - Interface available in 40+ languages.
|
||||
All documentation available at [https://docs.stirlingpdf.com/](https://docs.stirlingpdf.com/)
|
||||
|
||||
For a full feature list, see the docs: **https://docs.stirlingpdf.com**
|
||||

|
||||
|
||||
## Quick Start
|
||||
## Features
|
||||
|
||||
```bash
|
||||
docker run -p 8080:8080 docker.stirlingpdf.com/stirlingtools/stirling-pdf
|
||||
```
|
||||
- 50+ PDF Operations
|
||||
- Parallel file processing and downloads
|
||||
- Dark mode support
|
||||
- Custom download options
|
||||
- Custom 'Pipelines' to run multiple features in a automated queue
|
||||
- API for integration with external scripts
|
||||
- Optional Login and Authentication support (see [here](https://docs.stirlingpdf.com/Advanced%20Configuration/System%20and%20Security) for documentation)
|
||||
- Database Backup and Import (see [here](https://docs.stirlingpdf.com/Advanced%20Configuration/DATABASE) for documentation)
|
||||
- Enterprise features like SSO (see [here](https://docs.stirlingpdf.com/Advanced%20Configuration/Single%20Sign-On%20Configuration) for documentation)
|
||||
|
||||
Then open: http://localhost:8080
|
||||
## PDF Features
|
||||
|
||||
For full installation options (including desktop and Kubernetes), see our [Documentation Guide](https://docs.stirlingpdf.com/#documentation-guide).
|
||||
### Page Operations
|
||||
|
||||
## Resources
|
||||
- View and modify PDFs - View multi-page PDFs with custom viewing, sorting, and searching. Plus, on-page edit features like annotating, drawing, and adding text and images. (Using PDF.js with Joxit and Liberation fonts)
|
||||
- Full interactive GUI for merging/splitting/rotating/moving PDFs and their pages
|
||||
- Merge multiple PDFs into a single resultant file
|
||||
- Split PDFs into multiple files at specified page numbers or extract all pages as individual files
|
||||
- Reorganize PDF pages into different orders
|
||||
- Rotate PDFs in 90-degree increments
|
||||
- Remove pages
|
||||
- Multi-page layout (format PDFs into a multi-paged page)
|
||||
- Scale page contents size by set percentage
|
||||
- Adjust contrast
|
||||
- Crop PDF
|
||||
- Auto-split PDF (with physically scanned page dividers)
|
||||
- Extract page(s)
|
||||
- Convert PDF to a single page
|
||||
- Overlay PDFs on top of each other
|
||||
- PDF to a single page
|
||||
- Split PDF by sections
|
||||
|
||||
- [**Documentation**](https://docs.stirlingpdf.com)
|
||||
- [**Homepage**](https://stirling.com)
|
||||
- [**API Docs**](https://registry.scalar.com/@stirlingpdf/apis/stirling-pdf-processing-api/)
|
||||
- [**Server Plan & Enterprise**](https://docs.stirlingpdf.com/Paid-Offerings)
|
||||
### Conversion Operations
|
||||
|
||||
## Support
|
||||
- Convert PDFs to and from images
|
||||
- Convert any common file to PDF (using LibreOffice)
|
||||
- Convert PDF to Word/PowerPoint/others (using LibreOffice)
|
||||
- Convert HTML to PDF
|
||||
- Convert PDF to XML
|
||||
- Convert PDF to CSV
|
||||
- URL to PDF
|
||||
- Markdown to PDF
|
||||
|
||||
- **Community** [Discord](https://discord.gg/HYmhKj45pU)
|
||||
- **Bug Reports**: [Github issues](https://github.com/Stirling-Tools/Stirling-PDF/issues)
|
||||
### Security & Permissions
|
||||
|
||||
## Contributing
|
||||
- Add and remove passwords
|
||||
- Change/set PDF permissions
|
||||
- Add watermark(s)
|
||||
- Certify/sign PDFs
|
||||
- Sanitize PDFs
|
||||
- Auto-redact text
|
||||
|
||||
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
||||
### Other Operations
|
||||
|
||||
For development setup, see the [Developer Guide](DeveloperGuide.md).
|
||||
- Add/generate/write signatures
|
||||
- Split by Size or PDF
|
||||
- Repair PDFs
|
||||
- Detect and remove blank pages
|
||||
- Compare two PDFs and show differences in text
|
||||
- Add images to PDFs
|
||||
- Compress PDFs to decrease their filesize (using qpdf)
|
||||
- Extract images from PDF
|
||||
- Remove images from PDF
|
||||
- Extract images from scans
|
||||
- Remove annotations
|
||||
- Add page numbers
|
||||
- Auto-rename files by detecting PDF header text
|
||||
- OCR on PDF (using Tesseract OCR)
|
||||
- PDF/A conversion (using LibreOffice)
|
||||
- Edit metadata
|
||||
- Flatten PDFs
|
||||
- Get all information on a PDF to view or export as JSON
|
||||
- Show/detect embedded JavaScript
|
||||
|
||||
For adding translations, see the [Translation Guide](devGuide/HowToAddNewLanguage.md).
|
||||
|
||||
## License
|
||||
|
||||
Stirling PDF is open-core. See [LICENSE](LICENSE) for details.
|
||||
# 📖 Get Started
|
||||
|
||||
Visit our comprehensive documentation at [docs.stirlingpdf.com](https://docs.stirlingpdf.com) for:
|
||||
|
||||
- Installation guides for all platforms
|
||||
- Configuration options
|
||||
- Feature documentation
|
||||
- API reference
|
||||
- Security setup
|
||||
- Enterprise features
|
||||
|
||||
|
||||
## Supported Languages
|
||||
|
||||
Stirling-PDF currently supports 40 languages!
|
||||
|
||||
| Language | Progress |
|
||||
| -------------------------------------------- | -------------------------------------- |
|
||||
| Arabic (العربية) (ar_AR) |  |
|
||||
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
||||
| Basque (Euskara) (eu_ES) |  |
|
||||
| Bulgarian (Български) (bg_BG) |  |
|
||||
| Catalan (Català) (ca_CA) |  |
|
||||
| Croatian (Hrvatski) (hr_HR) |  |
|
||||
| Czech (Česky) (cs_CZ) |  |
|
||||
| Danish (Dansk) (da_DK) |  |
|
||||
| Dutch (Nederlands) (nl_NL) |  |
|
||||
| English (English) (en_GB) |  |
|
||||
| English (US) (en_US) |  |
|
||||
| French (Français) (fr_FR) |  |
|
||||
| German (Deutsch) (de_DE) |  |
|
||||
| Greek (Ελληνικά) (el_GR) |  |
|
||||
| Hindi (हिंदी) (hi_IN) |  |
|
||||
| Hungarian (Magyar) (hu_HU) |  |
|
||||
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
||||
| Irish (Gaeilge) (ga_IE) |  |
|
||||
| Italian (Italiano) (it_IT) |  |
|
||||
| Japanese (日本語) (ja_JP) |  |
|
||||
| Korean (한국어) (ko_KR) |  |
|
||||
| Norwegian (Norsk) (no_NB) |  |
|
||||
| Persian (فارسی) (fa_IR) |  |
|
||||
| Polish (Polski) (pl_PL) |  |
|
||||
| Portuguese (Português) (pt_PT) |  |
|
||||
| Portuguese Brazilian (Português) (pt_BR) |  |
|
||||
| Romanian (Română) (ro_RO) |  |
|
||||
| Russian (Русский) (ru_RU) |  |
|
||||
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
||||
| Simplified Chinese (简体中文) (zh_CN) |  |
|
||||
| Slovakian (Slovensky) (sk_SK) |  |
|
||||
| Slovenian (Slovenščina) (sl_SI) |  |
|
||||
| Spanish (Español) (es_ES) |  |
|
||||
| Swedish (Svenska) (sv_SE) |  |
|
||||
| Thai (ไทย) (th_TH) |  |
|
||||
| Tibetan (བོད་ཡིག་) (bo_CN) |  |
|
||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||
| Turkish (Türkçe) (tr_TR) |  |
|
||||
| Ukrainian (Українська) (uk_UA) |  |
|
||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||
| Malayalam (മലയാളം) (ml_IN) |  |
|
||||
|
||||
## Stirling PDF Enterprise
|
||||
|
||||
Stirling PDF offers an Enterprise edition of its software. This is the same great software but with added features, support and comforts.
|
||||
Check out our [Enterprise docs](https://docs.stirlingpdf.com/Pro)
|
||||
|
||||
|
||||
## 🤝 Looking to contribute?
|
||||
|
||||
Join our community:
|
||||
- [Contribution Guidelines](CONTRIBUTING.md)
|
||||
- [Translation Guide (How to add custom languages)](devGuide/HowToAddNewLanguage.md)
|
||||
- [Developer Guide](devGuide/DeveloperGuide.md)
|
||||
- [Issue Tracker](https://github.com/Stirling-Tools/Stirling-PDF/issues)
|
||||
- [Discord Community](https://discord.gg/HYmhKj45pU)
|
||||
|
||||
@@ -22,13 +22,25 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
name = "Analysis",
|
||||
description =
|
||||
"""
|
||||
Read-only inspection of PDFs: page count, page sizes, fonts, form fields, annotations, document properties, and security details.
|
||||
Use these endpoints to understand what's inside a document without changing it.
|
||||
Document analysis and information extraction services for content intelligence and insights.
|
||||
|
||||
Typical uses:
|
||||
• Get page counts and dimensions for layout or print rules
|
||||
• List fonts and annotations to spot compatibility issues
|
||||
• Inspect form fields before deciding how to fill or modify them
|
||||
• Pull metadata and security settings for audits or reports
|
||||
This endpoint group provides analytical capabilities to understand document structure,
|
||||
extract information, and generate insights from PDF content for automated processing.
|
||||
|
||||
Common use cases:
|
||||
• Document inventory management and content audit for compliance verification
|
||||
• Quality assurance workflows and business intelligence analytics
|
||||
• Migration planning, accessibility evaluation, and document forensics
|
||||
|
||||
Business applications:
|
||||
• Legal discovery, financial document review, and healthcare records analysis
|
||||
• Academic research, government processing, and publishing optimization
|
||||
|
||||
Operational scenarios:
|
||||
• Large-scale profiling, migration assessment, and performance optimization
|
||||
• Automated quality control and content strategy development
|
||||
|
||||
Target users: Data analysts, QA teams, administrators, and business intelligence
|
||||
professionals requiring detailed document insights.
|
||||
""")
|
||||
public @interface AnalysisApi {}
|
||||
|
||||
@@ -22,13 +22,25 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
name = "Convert",
|
||||
description =
|
||||
"""
|
||||
Convert PDFs to and from other formats (Word, images, HTML, Markdown, PDF/A, CBZ/CBR, EML, etc.).
|
||||
This group also powers the text-editor / jobId-based editing flow for incremental PDF edits.
|
||||
Document format transformation services for cross-platform compatibility and workflow integration.
|
||||
|
||||
Typical uses:
|
||||
• Turn PDFs into Word or text for editing
|
||||
• Convert office files, images, HTML, or email (EML) into PDFs
|
||||
• Create PDF/A for long-term archiving
|
||||
• Export PDFs as images, HTML, CSV, or Markdown for search, analysis, or reuse
|
||||
This endpoint group enables transformation between various formats, supporting
|
||||
diverse business workflows and system integrations for mixed document ecosystems.
|
||||
|
||||
Common use cases:
|
||||
• Legacy system integration, document migration, and cross-platform sharing
|
||||
• Archive standardization, publishing preparation, and content adaptation
|
||||
• Accessibility compliance and mobile-friendly document preparation
|
||||
|
||||
Business applications:
|
||||
• Enterprise content management, digital publishing, and educational platforms
|
||||
• Legal document processing, healthcare interoperability, and government standardization
|
||||
|
||||
Integration scenarios:
|
||||
• API-driven pipelines, automated workflow preparation, and batch conversions
|
||||
• Real-time format adaptation for user requests
|
||||
|
||||
Target users: System integrators, content managers, digital archivists, and
|
||||
organizations requiring flexible document format interoperability.
|
||||
""")
|
||||
public @interface ConvertApi {}
|
||||
|
||||
@@ -22,13 +22,25 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
name = "Filter",
|
||||
description =
|
||||
"""
|
||||
Check basic properties of PDFs before you process them: page count, file size, page size/rotation, and whether they contain text or images.
|
||||
Use these endpoints as a "pre-check" step to decide what to do with a file next.
|
||||
Document content filtering and search operations for information discovery and organization.
|
||||
|
||||
Typical uses:
|
||||
• Reject files that are too big or too small
|
||||
• Detect image-only PDFs that should go through OCR
|
||||
• Ensure a document has enough pages before it enters a workflow
|
||||
• Check orientation of pages before printing or merging
|
||||
This endpoint group enables intelligent content discovery and organization within
|
||||
document collections for content-based processing and information extraction.
|
||||
|
||||
Common use cases:
|
||||
• Legal discovery, research organization, and compliance auditing
|
||||
• Content moderation, academic research, and business intelligence
|
||||
• Quality assurance and content validation workflows
|
||||
|
||||
Business applications:
|
||||
• Contract analysis, financial review, and healthcare records organization
|
||||
• Government processing, educational curation, and IP protection
|
||||
|
||||
Workflow scenarios:
|
||||
• Large-scale processing, automated classification, and information extraction
|
||||
• Document preparation for further processing or analysis
|
||||
|
||||
Target users: Legal professionals, researchers, compliance officers, and
|
||||
organizations requiring intelligent document content discovery and organization.
|
||||
""")
|
||||
public @interface FilterApi {}
|
||||
|
||||
@@ -22,13 +22,21 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
name = "General",
|
||||
description =
|
||||
"""
|
||||
Page-level PDF editing: split, merge, rotate, crop, rearrange, and scale pages.
|
||||
These endpoints handle most daily "I opened a PDF editor just to…" type tasks.
|
||||
Core PDF processing operations for fundamental document manipulation workflows.
|
||||
|
||||
Typical uses:
|
||||
• Split a large PDF into smaller files (by pages, chapters, or size)
|
||||
• Merge several PDFs into one report or pack
|
||||
• Rotate or reorder pages before sending or archiving
|
||||
• Turn a multi-page document into one long scrolling page
|
||||
This endpoint group provides essential PDF functionality that forms the foundation
|
||||
of most document processing workflows across various industries.
|
||||
|
||||
Common use cases:
|
||||
• Document preparation for archival systems and content organization
|
||||
• File preparation for distribution, accessibility compliance, and batch processing
|
||||
• Document consolidation for reporting and legal compliance workflows
|
||||
|
||||
Typical applications:
|
||||
• Content management, publishing workflows, and educational content distribution
|
||||
• Business process automation and archive management
|
||||
|
||||
Target users: Content managers, document processors, and organizations requiring
|
||||
reliable foundational PDF manipulation capabilities.
|
||||
""")
|
||||
public @interface GeneralApi {}
|
||||
|
||||
@@ -22,15 +22,25 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
name = "Misc",
|
||||
description =
|
||||
"""
|
||||
Tools that don't fit neatly elsewhere: OCR, compress, repair, flatten, extract images, update metadata, add stamps/page numbers/images, and more.
|
||||
These endpoints help fix problem PDFs and prepare them for sharing, storage, or further processing.
|
||||
Specialized utilities and supplementary tools for enhanced document processing workflows.
|
||||
|
||||
Typical uses:
|
||||
• Repair a damaged PDF or remove blank pages
|
||||
• Run OCR on scanned PDFs so they become searchable
|
||||
• Compress large PDFs for email or web download
|
||||
• Extract embedded images or scans
|
||||
• Add page numbers, stamps, or overlay an image (e.g. logo, seal)
|
||||
• Update PDF metadata (title, author, etc.)
|
||||
This endpoint group provides utility operations that support core document processing
|
||||
tasks and address specific workflow needs in real-world scenarios.
|
||||
|
||||
Common use cases:
|
||||
• Document optimization for bandwidth-limited environments and storage cost management
|
||||
• Document repair, content extraction, and validation for quality assurance
|
||||
• Accessibility improvement and custom processing for specialized needs
|
||||
|
||||
Business applications:
|
||||
• Web publishing optimization, email attachment management, and archive efficiency
|
||||
• Mobile compatibility, print production, and legacy document recovery
|
||||
|
||||
Operational scenarios:
|
||||
• Batch processing, quality control, and performance optimization
|
||||
• Troubleshooting and recovery of problematic documents
|
||||
|
||||
Target users: System administrators, document specialists, and organizations requiring
|
||||
specialized document processing and optimization tools.
|
||||
""")
|
||||
public @interface MiscApi {}
|
||||
|
||||
@@ -22,12 +22,25 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
name = "Pipeline",
|
||||
description =
|
||||
"""
|
||||
Run several PDF operations in one configured pipeline instead of calling multiple endpoints yourself.
|
||||
Useful when you always do the same steps in sequence (for example: convert → OCR → compress → watermark).
|
||||
Automated document processing workflows for complex multi-stage business operations.
|
||||
|
||||
Typical uses:
|
||||
• Process incoming invoices in one go (clean, OCR, compress, stamp, etc.)
|
||||
• Normalise documents before they enter an archive
|
||||
• Wrap a complex document flow behind a single API call for your own apps
|
||||
This endpoint group enables organizations to create sophisticated document processing
|
||||
workflows that combine multiple operations into streamlined, repeatable processes.
|
||||
|
||||
Common use cases:
|
||||
• Invoice processing, legal document review, and healthcare records standardization
|
||||
• Government processing, educational content preparation, and publishing automation
|
||||
• Contract lifecycle management and approval processes
|
||||
|
||||
Business applications:
|
||||
• Automated compliance reporting, large-scale migration, and quality assurance
|
||||
• Archive preparation, content delivery, and document approval workflows
|
||||
|
||||
Operational scenarios:
|
||||
• Scheduled batch processing and event-driven document processing
|
||||
• Multi-department coordination and business system integration
|
||||
|
||||
Target users: Business process managers, IT automation specialists, and organizations
|
||||
requiring consistent, repeatable document processing workflows.
|
||||
""")
|
||||
public @interface PipelineApi {}
|
||||
|
||||
@@ -22,13 +22,25 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
name = "Security",
|
||||
description =
|
||||
"""
|
||||
Protect and clean PDFs: passwords, digital signatures, redaction, and sanitizing.
|
||||
These endpoints help you control who can open a file, what they can do with it, and remove sensitive content when needed.
|
||||
Document security and protection services for confidential and sensitive content.
|
||||
|
||||
Typical uses:
|
||||
• Add or remove a password on a PDF
|
||||
• Redact personal or confidential information (manually or automatically)
|
||||
• Validate or remove digital signatures
|
||||
• Sanitize a PDF to strip scripts and embedded content
|
||||
This endpoint group provides essential security operations for organizations handling
|
||||
sensitive documents and materials requiring controlled access.
|
||||
|
||||
Common use cases:
|
||||
• Legal confidentiality, healthcare privacy (HIPAA), and financial regulatory compliance
|
||||
• Government classified handling, corporate IP protection, and educational privacy (FERPA)
|
||||
• Contract security for business transactions
|
||||
|
||||
Business applications:
|
||||
• Document authentication, confidential sharing, and secure archiving
|
||||
• Content watermarking, access control, and privacy protection through redaction
|
||||
|
||||
Industry scenarios:
|
||||
• Legal discovery, medical records exchange, financial audit documentation
|
||||
• Enterprise policy enforcement and data governance
|
||||
|
||||
Target users: Legal professionals, healthcare administrators, compliance officers,
|
||||
government agencies, and enterprises handling sensitive content.
|
||||
""")
|
||||
public @interface SecurityApi {}
|
||||
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
package stirling.software.common.service;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Interface for personal signature access (proprietary feature). Implemented only in proprietary
|
||||
* module to provide authenticated users access to their personal signatures.
|
||||
*/
|
||||
public interface PersonalSignatureServiceInterface {
|
||||
|
||||
/**
|
||||
* Get a personal signature from the user's folder. Only checks personal folder, not shared
|
||||
* folder.
|
||||
*
|
||||
* @param username Username of the signature owner
|
||||
* @param fileName Signature filename
|
||||
* @return Personal signature image bytes
|
||||
* @throws IOException If file not found or read error
|
||||
*/
|
||||
byte[] getPersonalSignatureBytes(String username, String fileName) throws IOException;
|
||||
}
|
||||
@@ -39,7 +39,6 @@ public class RequestUriUtils {
|
||||
// Specific static files bundled with the frontend
|
||||
if (normalizedUri.equals("/robots.txt")
|
||||
|| normalizedUri.equals("/favicon.ico")
|
||||
|| normalizedUri.equals("/manifest.json")
|
||||
|| normalizedUri.equals("/site.webmanifest")
|
||||
|| normalizedUri.equals("/manifest-classic.json")
|
||||
|| normalizedUri.equals("/index.html")) {
|
||||
@@ -160,8 +159,6 @@ public class RequestUriUtils {
|
||||
|| trimmedUri.startsWith(
|
||||
"/api/v1/proprietary/ui-data/login") // Login page config (SSO providers +
|
||||
// enableLogin)
|
||||
|| trimmedUri.startsWith(
|
||||
"/api/v1/ui-data/footer-info") // Public footer configuration
|
||||
|| trimmedUri.startsWith("/v1/api-docs")
|
||||
|| trimmedUri.startsWith("/api/v1/invite/validate")
|
||||
|| trimmedUri.startsWith("/api/v1/invite/accept")
|
||||
|
||||
@@ -51,8 +51,7 @@ public class RequestUriUtilsTest {
|
||||
|
||||
@Test
|
||||
void testIsFrontendRoute() {
|
||||
assertTrue(
|
||||
RequestUriUtils.isFrontendRoute("", "/"), "Root path should be a frontend route");
|
||||
assertTrue(RequestUriUtils.isFrontendRoute("", "/"), "Root path should be a frontend route");
|
||||
assertTrue(
|
||||
RequestUriUtils.isFrontendRoute("", "/app/dashboard"),
|
||||
"React routes without extensions should be frontend routes");
|
||||
|
||||
@@ -21,9 +21,6 @@ public class SpringDocConfig {
|
||||
"/api/v1/user/**",
|
||||
"/api/v1/settings/**",
|
||||
"/api/v1/team/**",
|
||||
"/api/v1/auth/**",
|
||||
"/api/v1/invite/**",
|
||||
"/api/v1/audit/**",
|
||||
"/api/v1/ui-data/**",
|
||||
"/api/v1/proprietary/ui-data/**",
|
||||
"/api/v1/info/**",
|
||||
@@ -36,7 +33,7 @@ public class SpringDocConfig {
|
||||
openApi.getInfo()
|
||||
.title("Stirling PDF - Processing API")
|
||||
.description(
|
||||
"APIs for converting, editing, securing, and analysing PDF documents. Use these endpoints to automate common PDF tasks (like split, merge, convert, OCR) and plug them into your own apps and backend jobs."));
|
||||
"API documentation for PDF processing operations including conversion, manipulation, security, and utilities."));
|
||||
})
|
||||
.build();
|
||||
}
|
||||
@@ -50,17 +47,14 @@ public class SpringDocConfig {
|
||||
"/api/v1/admin/**",
|
||||
"/api/v1/user/**",
|
||||
"/api/v1/settings/**",
|
||||
"/api/v1/team/**",
|
||||
"/api/v1/auth/**",
|
||||
"/api/v1/invite/**",
|
||||
"/api/v1/audit/**")
|
||||
"/api/v1/team/**")
|
||||
.addOpenApiCustomizer(
|
||||
openApi -> {
|
||||
openApi.info(
|
||||
openApi.getInfo()
|
||||
.title("Stirling PDF - Management API")
|
||||
.title("Stirling PDF - Admin API")
|
||||
.description(
|
||||
"Endpoints for authentication, user management, invitations, audit logging, and system configuration."));
|
||||
"API documentation for administrative functions, user management, and system configuration."));
|
||||
})
|
||||
.build();
|
||||
}
|
||||
@@ -82,7 +76,7 @@ public class SpringDocConfig {
|
||||
openApi.getInfo()
|
||||
.title("Stirling PDF - System API")
|
||||
.description(
|
||||
"System information, UI metadata, job status, and file management endpoints."));
|
||||
"API documentation for system information, UI data, and utility endpoints."));
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.Dependency;
|
||||
import stirling.software.SPDF.model.SignatureFile;
|
||||
import stirling.software.SPDF.service.SharedSignatureService;
|
||||
import stirling.software.SPDF.service.SignatureService;
|
||||
import stirling.software.common.annotations.api.UiDataApi;
|
||||
import stirling.software.common.configuration.InstallationPathConfig;
|
||||
import stirling.software.common.configuration.RuntimePathConfig;
|
||||
@@ -40,14 +40,14 @@ import stirling.software.common.util.GeneralUtils;
|
||||
public class UIDataController {
|
||||
|
||||
private final ApplicationProperties applicationProperties;
|
||||
private final SharedSignatureService signatureService;
|
||||
private final SignatureService signatureService;
|
||||
private final UserServiceInterface userService;
|
||||
private final ResourceLoader resourceLoader;
|
||||
private final RuntimePathConfig runtimePathConfig;
|
||||
|
||||
public UIDataController(
|
||||
ApplicationProperties applicationProperties,
|
||||
SharedSignatureService signatureService,
|
||||
SignatureService signatureService,
|
||||
@Autowired(required = false) UserServiceInterface userService,
|
||||
ResourceLoader resourceLoader,
|
||||
RuntimePathConfig runtimePathConfig) {
|
||||
@@ -58,21 +58,6 @@ public class UIDataController {
|
||||
this.runtimePathConfig = runtimePathConfig;
|
||||
}
|
||||
|
||||
@GetMapping("/footer-info")
|
||||
@Operation(summary = "Get public footer configuration data")
|
||||
public ResponseEntity<FooterData> getFooterData() {
|
||||
FooterData data = new FooterData();
|
||||
data.setAnalyticsEnabled(applicationProperties.getSystem().getEnableAnalytics());
|
||||
data.setTermsAndConditions(applicationProperties.getLegal().getTermsAndConditions());
|
||||
data.setPrivacyPolicy(applicationProperties.getLegal().getPrivacyPolicy());
|
||||
data.setAccessibilityStatement(
|
||||
applicationProperties.getLegal().getAccessibilityStatement());
|
||||
data.setCookiePolicy(applicationProperties.getLegal().getCookiePolicy());
|
||||
data.setImpressum(applicationProperties.getLegal().getImpressum());
|
||||
|
||||
return ResponseEntity.ok(data);
|
||||
}
|
||||
|
||||
@GetMapping("/home")
|
||||
@Operation(summary = "Get home page data")
|
||||
public ResponseEntity<HomeData> getHomeData() {
|
||||
@@ -252,16 +237,6 @@ public class UIDataController {
|
||||
}
|
||||
|
||||
// Data classes
|
||||
@Data
|
||||
public static class FooterData {
|
||||
private Boolean analyticsEnabled;
|
||||
private String termsAndConditions;
|
||||
private String privacyPolicy;
|
||||
private String accessibilityStatement;
|
||||
private String cookiePolicy;
|
||||
private String impressum;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class HomeData {
|
||||
private boolean showSurveyFromDocker;
|
||||
|
||||
+3
-3
@@ -25,7 +25,7 @@ import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.SignatureFile;
|
||||
import stirling.software.SPDF.service.SharedSignatureService;
|
||||
import stirling.software.SPDF.service.SignatureService;
|
||||
import stirling.software.common.configuration.InstallationPathConfig;
|
||||
import stirling.software.common.configuration.RuntimePathConfig;
|
||||
import stirling.software.common.service.UserServiceInterface;
|
||||
@@ -37,13 +37,13 @@ import stirling.software.common.util.GeneralUtils;
|
||||
@Slf4j
|
||||
public class GeneralWebController {
|
||||
|
||||
private final SharedSignatureService signatureService;
|
||||
private final SignatureService signatureService;
|
||||
private final UserServiceInterface userService;
|
||||
private final ResourceLoader resourceLoader;
|
||||
private final RuntimePathConfig runtimePathConfig;
|
||||
|
||||
public GeneralWebController(
|
||||
SharedSignatureService signatureService,
|
||||
SignatureService signatureService,
|
||||
@Autowired(required = false) UserServiceInterface userService,
|
||||
ResourceLoader resourceLoader,
|
||||
RuntimePathConfig runtimePathConfig) {
|
||||
|
||||
+6
-77
@@ -1,89 +1,18 @@
|
||||
package stirling.software.SPDF.controller.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
@Controller
|
||||
public class ReactRoutingController {
|
||||
|
||||
@Value("${server.servlet.context-path:/}")
|
||||
private String contextPath;
|
||||
|
||||
private String cachedIndexHtml;
|
||||
private boolean indexHtmlExists = false;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
// Only cache if index.html exists (production builds)
|
||||
ClassPathResource resource = new ClassPathResource("static/index.html");
|
||||
if (resource.exists()) {
|
||||
try {
|
||||
this.cachedIndexHtml = processIndexHtml();
|
||||
this.indexHtmlExists = true;
|
||||
} catch (IOException e) {
|
||||
// Failed to cache, will process on each request
|
||||
this.indexHtmlExists = false;
|
||||
}
|
||||
}
|
||||
@GetMapping("/{path:^(?!api|static|robots\\.txt|favicon\\.ico|pipeline|pdfjs|pdfjs-legacy|fonts|images|files|css|js)[^\\.]*$}")
|
||||
public String forwardRootPaths() {
|
||||
return "forward:/index.html";
|
||||
}
|
||||
|
||||
private String processIndexHtml() throws IOException {
|
||||
ClassPathResource resource = new ClassPathResource("static/index.html");
|
||||
|
||||
try (InputStream inputStream = resource.getInputStream()) {
|
||||
String html = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
|
||||
|
||||
// Replace %BASE_URL% with the actual context path for base href
|
||||
String baseUrl = contextPath.endsWith("/") ? contextPath : contextPath + "/";
|
||||
html = html.replace("%BASE_URL%", baseUrl);
|
||||
// Also rewrite any existing <base> tag (Vite may have baked one in)
|
||||
html =
|
||||
html.replaceFirst(
|
||||
"<base href=\\\"[^\\\"]*\\\"\\s*/?>",
|
||||
"<base href=\\\"" + baseUrl + "\\\" />");
|
||||
|
||||
// Inject context path as a global variable for API calls
|
||||
String contextPathScript =
|
||||
"<script>window.STIRLING_PDF_API_BASE_URL = '" + baseUrl + "';</script>";
|
||||
html = html.replace("</head>", contextPathScript + "</head>");
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/", "/index.html"}, produces = MediaType.TEXT_HTML_VALUE)
|
||||
public ResponseEntity<String> serveIndexHtml(HttpServletRequest request)
|
||||
throws IOException {
|
||||
if (indexHtmlExists && cachedIndexHtml != null) {
|
||||
return ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body(cachedIndexHtml);
|
||||
}
|
||||
// Fallback: process on each request (dev mode or cache failed)
|
||||
return ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body(processIndexHtml());
|
||||
}
|
||||
|
||||
@GetMapping(
|
||||
"/{path:^(?!api|static|robots\\.txt|favicon\\.ico|manifest.*\\.json|pipeline|pdfjs|pdfjs-legacy|fonts|images|files|css|js|assets|locales|modern-logo|classic-logo|Login|og_images|samples)[^\\.]*$}")
|
||||
public ResponseEntity<String> forwardRootPaths(HttpServletRequest request)
|
||||
throws IOException {
|
||||
return serveIndexHtml(request);
|
||||
}
|
||||
|
||||
@GetMapping(
|
||||
"/{path:^(?!api|static|pipeline|pdfjs|pdfjs-legacy|fonts|images|files|css|js|assets|locales|modern-logo|classic-logo|Login|og_images|samples)[^\\.]*}/{subpath:^(?!.*\\.).*$}")
|
||||
public ResponseEntity<String> forwardNestedPaths(HttpServletRequest request)
|
||||
throws IOException {
|
||||
return serveIndexHtml(request);
|
||||
@GetMapping("/{path:^(?!api|static|pipeline|pdfjs|pdfjs-legacy|fonts|images|files|css|js)[^\\.]*}/{subpath:^(?!.*\\.).*$}")
|
||||
public String forwardNestedPaths() {
|
||||
return "forward:/index.html";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package stirling.software.SPDF.controller.web;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import stirling.software.SPDF.service.SignatureService;
|
||||
import stirling.software.common.service.UserServiceInterface;
|
||||
|
||||
// @Controller // Disabled - Backend-only mode, no Thymeleaf UI
|
||||
@RequestMapping("/api/v1/general")
|
||||
public class SignatureController {
|
||||
|
||||
private final SignatureService signatureService;
|
||||
|
||||
private final UserServiceInterface userService;
|
||||
|
||||
public SignatureController(
|
||||
SignatureService signatureService,
|
||||
@Autowired(required = false) UserServiceInterface userService) {
|
||||
this.signatureService = signatureService;
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@GetMapping("/sign/{fileName}")
|
||||
public ResponseEntity<byte[]> getSignature(@PathVariable(name = "fileName") String fileName)
|
||||
throws IOException {
|
||||
String username = "NON_SECURITY_USER";
|
||||
if (userService != null) {
|
||||
username = userService.getCurrentUsername();
|
||||
}
|
||||
// Verify access permission
|
||||
if (!signatureService.hasAccessToFile(username, fileName)) {
|
||||
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
|
||||
}
|
||||
byte[] imageBytes = signatureService.getSignatureBytes(username, fileName);
|
||||
return ResponseEntity.ok()
|
||||
.contentType( // Adjust based on file type
|
||||
MediaType.IMAGE_JPEG)
|
||||
.body(imageBytes);
|
||||
}
|
||||
}
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
package stirling.software.SPDF.controller.web;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.service.SharedSignatureService;
|
||||
import stirling.software.common.service.PersonalSignatureServiceInterface;
|
||||
import stirling.software.common.service.UserServiceInterface;
|
||||
|
||||
/**
|
||||
* Unified signature image controller that works for both authenticated and unauthenticated users.
|
||||
* Uses composition pattern: - Core SharedSignatureService (always available): reads shared
|
||||
* signatures - PersonalSignatureService (proprietary, optional): reads personal signatures For
|
||||
* authenticated signature management (save/delete), see proprietary SignatureController.
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/general")
|
||||
public class SignatureImageController {
|
||||
|
||||
private final SharedSignatureService sharedSignatureService;
|
||||
private final PersonalSignatureServiceInterface personalSignatureService;
|
||||
private final UserServiceInterface userService;
|
||||
|
||||
public SignatureImageController(
|
||||
SharedSignatureService sharedSignatureService,
|
||||
@Autowired(required = false) PersonalSignatureServiceInterface personalSignatureService,
|
||||
@Autowired(required = false) UserServiceInterface userService) {
|
||||
this.sharedSignatureService = sharedSignatureService;
|
||||
this.personalSignatureService = personalSignatureService;
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a signature image (works for both authenticated and unauthenticated users). -
|
||||
* Authenticated with proprietary: tries personal first, then shared - Unauthenticated or
|
||||
* community: tries shared only
|
||||
*/
|
||||
@GetMapping("/signatures/{fileName}")
|
||||
public ResponseEntity<byte[]> getSignature(@PathVariable(name = "fileName") String fileName) {
|
||||
try {
|
||||
byte[] imageBytes = null;
|
||||
|
||||
// If proprietary service available and user authenticated, try personal folder first
|
||||
if (personalSignatureService != null && userService != null) {
|
||||
try {
|
||||
String username = userService.getCurrentUsername();
|
||||
imageBytes =
|
||||
personalSignatureService.getPersonalSignatureBytes(username, fileName);
|
||||
} catch (Exception e) {
|
||||
// Not found in personal folder or not authenticated, will try shared
|
||||
log.debug("Personal signature not found, trying shared: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// If not found in personal (or no personal service), try shared
|
||||
if (imageBytes == null) {
|
||||
imageBytes = sharedSignatureService.getSharedSignatureBytes(fileName);
|
||||
}
|
||||
|
||||
// Determine content type from file extension
|
||||
MediaType contentType = MediaType.IMAGE_PNG; // Default
|
||||
String lowerFileName = fileName.toLowerCase();
|
||||
if (lowerFileName.endsWith(".jpg") || lowerFileName.endsWith(".jpeg")) {
|
||||
contentType = MediaType.IMAGE_JPEG;
|
||||
}
|
||||
|
||||
return ResponseEntity.ok().contentType(contentType).body(imageBytes);
|
||||
} catch (IOException e) {
|
||||
log.debug("Signature not found: {}", fileName);
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
package stirling.software.SPDF.model.api.signature;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class SavedSignatureRequest {
|
||||
private String id;
|
||||
private String label;
|
||||
private String type; // "canvas", "image", "text"
|
||||
private String scope; // "personal", "shared"
|
||||
private String dataUrl; // For canvas and image types
|
||||
private String signerName; // For text type
|
||||
private String fontFamily; // For text type
|
||||
private Integer fontSize; // For text type
|
||||
private String textColor; // For text type
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package stirling.software.SPDF.model.api.signature;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SavedSignatureResponse {
|
||||
private String id;
|
||||
private String label;
|
||||
private String type; // "canvas", "image", "text"
|
||||
private String scope; // "personal", "shared"
|
||||
private String dataUrl; // For canvas and image types (or URL to fetch image)
|
||||
private String signerName; // For text type
|
||||
private String fontFamily; // For text type
|
||||
private Integer fontSize; // For text type
|
||||
private String textColor; // For text type
|
||||
private Long createdAt;
|
||||
private Long updatedAt;
|
||||
}
|
||||
@@ -1,308 +0,0 @@
|
||||
package stirling.software.SPDF.service;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.SignatureFile;
|
||||
import stirling.software.SPDF.model.api.signature.SavedSignatureRequest;
|
||||
import stirling.software.SPDF.model.api.signature.SavedSignatureResponse;
|
||||
import stirling.software.common.configuration.InstallationPathConfig;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SharedSignatureService {
|
||||
|
||||
private final String SIGNATURE_BASE_PATH;
|
||||
private final String ALL_USERS_FOLDER = "ALL_USERS";
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public SharedSignatureService() {
|
||||
SIGNATURE_BASE_PATH = InstallationPathConfig.getSignaturesPath();
|
||||
this.objectMapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
public boolean hasAccessToFile(String username, String fileName) throws IOException {
|
||||
validateFileName(fileName);
|
||||
// Check if file exists in user's personal folder or ALL_USERS folder
|
||||
Path userPath = Paths.get(SIGNATURE_BASE_PATH, username, fileName);
|
||||
Path allUsersPath = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER, fileName);
|
||||
|
||||
return Files.exists(userPath) || Files.exists(allUsersPath);
|
||||
}
|
||||
|
||||
public List<SignatureFile> getAvailableSignatures(String username) {
|
||||
List<SignatureFile> signatures = new ArrayList<>();
|
||||
|
||||
// Get signatures from user's personal folder
|
||||
if (StringUtils.hasText(username)) {
|
||||
Path userFolder = Paths.get(SIGNATURE_BASE_PATH, username);
|
||||
if (Files.exists(userFolder)) {
|
||||
try {
|
||||
signatures.addAll(getSignaturesFromFolder(userFolder, "Personal"));
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading user signatures folder", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get signatures from ALL_USERS folder
|
||||
Path allUsersFolder = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER);
|
||||
if (Files.exists(allUsersFolder)) {
|
||||
try {
|
||||
signatures.addAll(getSignaturesFromFolder(allUsersFolder, "Shared"));
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading shared signatures folder", e);
|
||||
}
|
||||
}
|
||||
|
||||
return signatures;
|
||||
}
|
||||
|
||||
private List<SignatureFile> getSignaturesFromFolder(Path folder, String category)
|
||||
throws IOException {
|
||||
try (Stream<Path> stream = Files.list(folder)) {
|
||||
return stream.filter(this::isImageFile)
|
||||
.map(path -> new SignatureFile(path.getFileName().toString(), category))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a signature from the shared (ALL_USERS) folder. This is always available for both
|
||||
* authenticated and unauthenticated users.
|
||||
*/
|
||||
public byte[] getSharedSignatureBytes(String fileName) throws IOException {
|
||||
validateFileName(fileName);
|
||||
Path allUsersPath = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER, fileName);
|
||||
if (!Files.exists(allUsersPath)) {
|
||||
throw new FileNotFoundException("Shared signature file not found");
|
||||
}
|
||||
return Files.readAllBytes(allUsersPath);
|
||||
}
|
||||
|
||||
private boolean isImageFile(Path path) {
|
||||
String fileName = path.getFileName().toString().toLowerCase();
|
||||
return fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") || fileName.endsWith(".png");
|
||||
}
|
||||
|
||||
private void validateFileName(String fileName) {
|
||||
if (fileName.contains("..") || fileName.contains("/") || fileName.contains("\\")) {
|
||||
throw new IllegalArgumentException("Invalid filename");
|
||||
}
|
||||
// Only allow alphanumeric, hyphen, underscore, and dot (for extensions)
|
||||
if (!fileName.matches("^[a-zA-Z0-9_.-]+$")) {
|
||||
throw new IllegalArgumentException("Filename contains invalid characters");
|
||||
}
|
||||
}
|
||||
|
||||
private String validateAndNormalizeExtension(String extension) {
|
||||
String normalized = extension.toLowerCase().trim();
|
||||
// Whitelist only safe image extensions
|
||||
if (normalized.equals("png") || normalized.equals("jpg") || normalized.equals("jpeg")) {
|
||||
return normalized;
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported image extension: " + extension);
|
||||
}
|
||||
|
||||
private void verifyPathWithinDirectory(Path resolvedPath, Path targetDirectory)
|
||||
throws IOException {
|
||||
Path canonicalTarget = targetDirectory.toAbsolutePath().normalize();
|
||||
Path canonicalResolved = resolvedPath.toAbsolutePath().normalize();
|
||||
if (!canonicalResolved.startsWith(canonicalTarget)) {
|
||||
throw new IOException("Resolved path is outside the target directory");
|
||||
}
|
||||
}
|
||||
|
||||
/** Save a signature as image file */
|
||||
public SavedSignatureResponse saveSignature(String username, SavedSignatureRequest request)
|
||||
throws IOException {
|
||||
validateFileName(request.getId());
|
||||
|
||||
// Determine folder based on scope
|
||||
String scope = request.getScope();
|
||||
if (scope == null || scope.isEmpty()) {
|
||||
scope = "personal"; // Default to personal
|
||||
}
|
||||
|
||||
String folderName = "shared".equals(scope) ? ALL_USERS_FOLDER : username;
|
||||
Path targetFolder = Paths.get(SIGNATURE_BASE_PATH, folderName);
|
||||
Files.createDirectories(targetFolder);
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
SavedSignatureResponse response = new SavedSignatureResponse();
|
||||
response.setId(request.getId());
|
||||
response.setLabel(request.getLabel());
|
||||
response.setType(request.getType());
|
||||
response.setScope(scope);
|
||||
response.setCreatedAt(timestamp);
|
||||
response.setUpdatedAt(timestamp);
|
||||
|
||||
// Extract and save image data
|
||||
String dataUrl = request.getDataUrl();
|
||||
if (dataUrl != null && dataUrl.startsWith("data:image/")) {
|
||||
// Extract base64 data
|
||||
String base64Data = dataUrl.substring(dataUrl.indexOf(",") + 1);
|
||||
byte[] imageBytes = Base64.getDecoder().decode(base64Data);
|
||||
|
||||
// Determine and validate file extension from data URL
|
||||
String mimeType = dataUrl.substring(dataUrl.indexOf(":") + 1, dataUrl.indexOf(";"));
|
||||
String rawExtension = mimeType.substring(mimeType.indexOf("/") + 1);
|
||||
String extension = validateAndNormalizeExtension(rawExtension);
|
||||
|
||||
// Save image file only
|
||||
String imageFileName = request.getId() + "." + extension;
|
||||
Path imagePath = targetFolder.resolve(imageFileName);
|
||||
|
||||
// Verify path is within target directory
|
||||
verifyPathWithinDirectory(imagePath, targetFolder);
|
||||
|
||||
Files.write(
|
||||
imagePath,
|
||||
imageBytes,
|
||||
StandardOpenOption.CREATE,
|
||||
StandardOpenOption.TRUNCATE_EXISTING);
|
||||
|
||||
// Store reference to image file
|
||||
response.setDataUrl("/api/v1/general/signatures/" + imageFileName);
|
||||
}
|
||||
|
||||
log.info("Saved signature {} for user {}", request.getId(), username);
|
||||
return response;
|
||||
}
|
||||
|
||||
/** Get all saved signatures for a user */
|
||||
public List<SavedSignatureResponse> getSavedSignatures(String username) throws IOException {
|
||||
List<SavedSignatureResponse> signatures = new ArrayList<>();
|
||||
|
||||
// Load personal signatures
|
||||
Path personalFolder = Paths.get(SIGNATURE_BASE_PATH, username);
|
||||
if (Files.exists(personalFolder)) {
|
||||
try (Stream<Path> stream = Files.list(personalFolder)) {
|
||||
stream.filter(this::isImageFile)
|
||||
.forEach(
|
||||
path -> {
|
||||
try {
|
||||
String fileName = path.getFileName().toString();
|
||||
String id =
|
||||
fileName.substring(0, fileName.lastIndexOf('.'));
|
||||
|
||||
SavedSignatureResponse sig = new SavedSignatureResponse();
|
||||
sig.setId(id);
|
||||
sig.setLabel(id); // Use ID as label
|
||||
sig.setType("image"); // Default type
|
||||
sig.setScope("personal");
|
||||
sig.setDataUrl("/api/v1/general/signatures/" + fileName);
|
||||
sig.setCreatedAt(
|
||||
Files.getLastModifiedTime(path).toMillis());
|
||||
sig.setUpdatedAt(
|
||||
Files.getLastModifiedTime(path).toMillis());
|
||||
|
||||
signatures.add(sig);
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading signature file: " + path, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Load shared signatures
|
||||
Path sharedFolder = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER);
|
||||
if (Files.exists(sharedFolder)) {
|
||||
try (Stream<Path> stream = Files.list(sharedFolder)) {
|
||||
stream.filter(this::isImageFile)
|
||||
.forEach(
|
||||
path -> {
|
||||
try {
|
||||
String fileName = path.getFileName().toString();
|
||||
String id =
|
||||
fileName.substring(0, fileName.lastIndexOf('.'));
|
||||
|
||||
SavedSignatureResponse sig = new SavedSignatureResponse();
|
||||
sig.setId(id);
|
||||
sig.setLabel(id); // Use ID as label
|
||||
sig.setType("image"); // Default type
|
||||
sig.setScope("shared");
|
||||
sig.setDataUrl("/api/v1/general/signatures/" + fileName);
|
||||
sig.setCreatedAt(
|
||||
Files.getLastModifiedTime(path).toMillis());
|
||||
sig.setUpdatedAt(
|
||||
Files.getLastModifiedTime(path).toMillis());
|
||||
|
||||
signatures.add(sig);
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading signature file: " + path, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return signatures;
|
||||
}
|
||||
|
||||
/** Delete a saved signature */
|
||||
public void deleteSignature(String username, String signatureId) throws IOException {
|
||||
validateFileName(signatureId);
|
||||
|
||||
// Try to find and delete image file in personal folder
|
||||
Path personalFolder = Paths.get(SIGNATURE_BASE_PATH, username);
|
||||
boolean deleted = false;
|
||||
|
||||
if (Files.exists(personalFolder)) {
|
||||
try (Stream<Path> stream = Files.list(personalFolder)) {
|
||||
List<Path> matchingFiles =
|
||||
stream.filter(
|
||||
path ->
|
||||
path.getFileName()
|
||||
.toString()
|
||||
.startsWith(signatureId + "."))
|
||||
.toList();
|
||||
for (Path file : matchingFiles) {
|
||||
Files.delete(file);
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try shared folder if not found in personal
|
||||
if (!deleted) {
|
||||
Path sharedFolder = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER);
|
||||
if (Files.exists(sharedFolder)) {
|
||||
try (Stream<Path> stream = Files.list(sharedFolder)) {
|
||||
List<Path> matchingFiles =
|
||||
stream.filter(
|
||||
path ->
|
||||
path.getFileName()
|
||||
.toString()
|
||||
.startsWith(signatureId + "."))
|
||||
.toList();
|
||||
for (Path file : matchingFiles) {
|
||||
Files.delete(file);
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!deleted) {
|
||||
throw new FileNotFoundException("Signature not found");
|
||||
}
|
||||
|
||||
log.info("Deleted signature {} for user {}", signatureId, username);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package stirling.software.SPDF.service;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.SPDF.model.SignatureFile;
|
||||
import stirling.software.common.configuration.InstallationPathConfig;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SignatureService {
|
||||
|
||||
private final String SIGNATURE_BASE_PATH;
|
||||
private final String ALL_USERS_FOLDER = "ALL_USERS";
|
||||
|
||||
public SignatureService() {
|
||||
SIGNATURE_BASE_PATH = InstallationPathConfig.getSignaturesPath();
|
||||
}
|
||||
|
||||
public boolean hasAccessToFile(String username, String fileName) throws IOException {
|
||||
validateFileName(fileName);
|
||||
// Check if file exists in user's personal folder or ALL_USERS folder
|
||||
Path userPath = Paths.get(SIGNATURE_BASE_PATH, username, fileName);
|
||||
Path allUsersPath = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER, fileName);
|
||||
|
||||
return Files.exists(userPath) || Files.exists(allUsersPath);
|
||||
}
|
||||
|
||||
public List<SignatureFile> getAvailableSignatures(String username) {
|
||||
List<SignatureFile> signatures = new ArrayList<>();
|
||||
|
||||
// Get signatures from user's personal folder
|
||||
if (StringUtils.hasText(username)) {
|
||||
Path userFolder = Paths.get(SIGNATURE_BASE_PATH, username);
|
||||
if (Files.exists(userFolder)) {
|
||||
try {
|
||||
signatures.addAll(getSignaturesFromFolder(userFolder, "Personal"));
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading user signatures folder", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get signatures from ALL_USERS folder
|
||||
Path allUsersFolder = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER);
|
||||
if (Files.exists(allUsersFolder)) {
|
||||
try {
|
||||
signatures.addAll(getSignaturesFromFolder(allUsersFolder, "Shared"));
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading shared signatures folder", e);
|
||||
}
|
||||
}
|
||||
|
||||
return signatures;
|
||||
}
|
||||
|
||||
private List<SignatureFile> getSignaturesFromFolder(Path folder, String category)
|
||||
throws IOException {
|
||||
try (Stream<Path> stream = Files.list(folder)) {
|
||||
return stream.filter(this::isImageFile)
|
||||
.map(path -> new SignatureFile(path.getFileName().toString(), category))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getSignatureBytes(String username, String fileName) throws IOException {
|
||||
validateFileName(fileName);
|
||||
// First try user's personal folder
|
||||
Path userPath = Paths.get(SIGNATURE_BASE_PATH, username, fileName);
|
||||
if (Files.exists(userPath)) {
|
||||
return Files.readAllBytes(userPath);
|
||||
}
|
||||
|
||||
// Then try ALL_USERS folder
|
||||
Path allUsersPath = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER, fileName);
|
||||
if (Files.exists(allUsersPath)) {
|
||||
return Files.readAllBytes(allUsersPath);
|
||||
}
|
||||
|
||||
throw new FileNotFoundException("Signature file not found");
|
||||
}
|
||||
|
||||
private boolean isImageFile(Path path) {
|
||||
String fileName = path.getFileName().toString().toLowerCase();
|
||||
return fileName.endsWith(".jpg")
|
||||
|| fileName.endsWith(".jpeg")
|
||||
|| fileName.endsWith(".png")
|
||||
|| fileName.endsWith(".gif");
|
||||
}
|
||||
|
||||
private void validateFileName(String fileName) {
|
||||
if (fileName.contains("..") || fileName.contains("/") || fileName.contains("\\")) {
|
||||
throw new IllegalArgumentException("Invalid filename");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,8 @@
|
||||
--cc-toggle-on-knob-bg: var(--cc-btn-primary-color);
|
||||
--cc-toggle-off-knob-bg: var(--cc-btn-primary-color);
|
||||
|
||||
--cc-toggle-enabled-icon-color: var(--cc-btn-primary-color);
|
||||
--cc-toggle-disabled-icon-color: var(--cc-btn-primary-color);
|
||||
--cc-toggle-enabled-icon-color: var(--cc-btn-primary-color);
|
||||
--cc-toggle-disabled-icon-color: var(--cc-btn-primary-color);
|
||||
|
||||
--cc-toggle-readonly-bg: var(--md-sys-color-surface);
|
||||
--cc-toggle-readonly-knob-bg: var(--md-sys-color-outline);
|
||||
@@ -34,10 +34,10 @@
|
||||
--cc-section-category-border: var(--md-sys-color-outline);
|
||||
|
||||
--cc-cookie-category-block-bg: var(--cc-btn-secondary-bg);
|
||||
--cc-cookie-category-block-border: var(--cc-btn-secondary-bg);
|
||||
--cc-cookie-category-block-border: var(--cc-btn-secondary-bg);
|
||||
--cc-cookie-category-block-hover-bg: var(--cc-btn-secondary-bg);
|
||||
--cc-cookie-category-block-hover-border: var(--cc-btn-secondary-bg);
|
||||
|
||||
|
||||
--cc-cookie-category-expanded-block-bg: var(--cc-btn-secondary-bg);
|
||||
--cc-cookie-category-expanded-block-hover-bg: var(--cc-toggle-readonly-bg);
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
*/
|
||||
--cc-footer-bg: var(--cc-bg);
|
||||
--cc-footer-color: var(--cc-primary-color);
|
||||
--cc-footer-border-color: var(--cc-bg);
|
||||
--cc-footer-border-color: var(--cc-bg);
|
||||
}
|
||||
.cm__body{
|
||||
max-width: 90% !important;
|
||||
@@ -81,4 +81,4 @@
|
||||
/* Lower z-index so cookie banner appears behind onboarding modals */
|
||||
#cc-main {
|
||||
z-index: 100 !important;
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ import stirling.software.common.configuration.InstallationPathConfig;
|
||||
class SignatureServiceTest {
|
||||
|
||||
@TempDir Path tempDir;
|
||||
private SharedSignatureService signatureService;
|
||||
private SignatureService signatureService;
|
||||
private Path personalSignatureFolder;
|
||||
private Path sharedSignatureFolder;
|
||||
private final String ALL_USERS_FOLDER = "ALL_USERS";
|
||||
@@ -53,7 +53,7 @@ class SignatureServiceTest {
|
||||
.thenReturn(tempDir.toString());
|
||||
|
||||
// Initialize the service with our temp directory
|
||||
signatureService = new SharedSignatureService();
|
||||
signatureService = new SignatureService();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ class SignatureServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetSharedSignatureBytes_SharedFile() throws IOException {
|
||||
void testGetSignatureBytes_PersonalFile() throws IOException {
|
||||
// Mock static method for each test
|
||||
try (MockedStatic<InstallationPathConfig> mockedConfig =
|
||||
mockStatic(InstallationPathConfig.class)) {
|
||||
@@ -173,8 +173,28 @@ class SignatureServiceTest {
|
||||
.when(InstallationPathConfig::getSignaturesPath)
|
||||
.thenReturn(tempDir.toString());
|
||||
|
||||
// Test - core service only reads shared signatures
|
||||
byte[] bytes = signatureService.getSharedSignatureBytes("shared.jpg");
|
||||
// Test
|
||||
byte[] bytes = signatureService.getSignatureBytes(TEST_USER, "personal.png");
|
||||
|
||||
// Verify
|
||||
assertEquals(
|
||||
"personal signature content",
|
||||
new String(bytes),
|
||||
"Should return the correct content for personal file");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetSignatureBytes_SharedFile() throws IOException {
|
||||
// Mock static method for each test
|
||||
try (MockedStatic<InstallationPathConfig> mockedConfig =
|
||||
mockStatic(InstallationPathConfig.class)) {
|
||||
mockedConfig
|
||||
.when(InstallationPathConfig::getSignaturesPath)
|
||||
.thenReturn(tempDir.toString());
|
||||
|
||||
// Test
|
||||
byte[] bytes = signatureService.getSignatureBytes(TEST_USER, "shared.jpg");
|
||||
|
||||
// Verify
|
||||
assertEquals(
|
||||
@@ -185,7 +205,7 @@ class SignatureServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetSharedSignatureBytes_FileNotFound() {
|
||||
void testGetSignatureBytes_FileNotFound() {
|
||||
// Mock static method for each test
|
||||
try (MockedStatic<InstallationPathConfig> mockedConfig =
|
||||
mockStatic(InstallationPathConfig.class)) {
|
||||
@@ -196,13 +216,13 @@ class SignatureServiceTest {
|
||||
// Test and verify
|
||||
assertThrows(
|
||||
FileNotFoundException.class,
|
||||
() -> signatureService.getSharedSignatureBytes("nonexistent.png"),
|
||||
() -> signatureService.getSignatureBytes(TEST_USER, "nonexistent.png"),
|
||||
"Should throw exception for non-existent files");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetSharedSignatureBytes_InvalidFileName() {
|
||||
void testGetSignatureBytes_InvalidFileName() {
|
||||
// Mock static method for each test
|
||||
try (MockedStatic<InstallationPathConfig> mockedConfig =
|
||||
mockStatic(InstallationPathConfig.class)) {
|
||||
@@ -213,28 +233,11 @@ class SignatureServiceTest {
|
||||
// Test and verify
|
||||
assertThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> signatureService.getSharedSignatureBytes("../invalid.png"),
|
||||
() -> signatureService.getSignatureBytes(TEST_USER, "../invalid.png"),
|
||||
"Should throw exception for file names with directory traversal");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetSharedSignatureBytes_CannotAccessPersonalFiles() {
|
||||
// Mock static method for each test
|
||||
try (MockedStatic<InstallationPathConfig> mockedConfig =
|
||||
mockStatic(InstallationPathConfig.class)) {
|
||||
mockedConfig
|
||||
.when(InstallationPathConfig::getSignaturesPath)
|
||||
.thenReturn(tempDir.toString());
|
||||
|
||||
// Test and verify - core service should NOT be able to read personal files
|
||||
assertThrows(
|
||||
FileNotFoundException.class,
|
||||
() -> signatureService.getSharedSignatureBytes("personal.png"),
|
||||
"Core service should not have access to personal signatures");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetAvailableSignatures_EmptyUsername() throws IOException {
|
||||
// Mock static method for each test
|
||||
|
||||
-195
@@ -1,195 +0,0 @@
|
||||
package stirling.software.proprietary.controller.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.common.annotations.api.UserApi;
|
||||
import stirling.software.common.configuration.InstallationPathConfig;
|
||||
import stirling.software.proprietary.model.api.signature.SavedSignatureRequest;
|
||||
import stirling.software.proprietary.model.api.signature.SavedSignatureResponse;
|
||||
import stirling.software.proprietary.security.service.UserService;
|
||||
import stirling.software.proprietary.service.SignatureService;
|
||||
|
||||
/**
|
||||
* Controller for managing user signatures in proprietary/authenticated mode only. Requires user
|
||||
* authentication and enforces per-user storage limits. All endpoints require authentication
|
||||
* via @PreAuthorize("isAuthenticated()").
|
||||
*/
|
||||
@UserApi
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/proprietary/signatures")
|
||||
@RequiredArgsConstructor
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
public class SignatureController {
|
||||
|
||||
private final SignatureService signatureService;
|
||||
private final UserService userService;
|
||||
private static final String ALL_USERS_FOLDER = "ALL_USERS";
|
||||
|
||||
/**
|
||||
* Save a new signature for the authenticated user. Enforces storage limits and authentication
|
||||
* requirements.
|
||||
*/
|
||||
@PostMapping
|
||||
public ResponseEntity<SavedSignatureResponse> saveSignature(
|
||||
@RequestBody SavedSignatureRequest request) {
|
||||
try {
|
||||
String username = userService.getCurrentUsername();
|
||||
|
||||
// Validate request
|
||||
if (request.getDataUrl() == null || request.getDataUrl().isEmpty()) {
|
||||
log.warn("User {} attempted to save signature without dataUrl", username);
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
|
||||
SavedSignatureResponse response = signatureService.saveSignature(username, request);
|
||||
log.info("User {} saved signature {}", username, request.getId());
|
||||
return ResponseEntity.ok(response);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.warn("Invalid signature save request: {}", e.getMessage());
|
||||
return ResponseEntity.badRequest().build();
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to save signature", e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List all signatures accessible to the authenticated user. Includes both personal and shared
|
||||
* signatures.
|
||||
*/
|
||||
@GetMapping
|
||||
public ResponseEntity<List<SavedSignatureResponse>> listSignatures() {
|
||||
try {
|
||||
String username = userService.getCurrentUsername();
|
||||
List<SavedSignatureResponse> signatures = signatureService.getSavedSignatures(username);
|
||||
return ResponseEntity.ok(signatures);
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to list signatures for user", e);
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a signature label. Users can update labels for their own personal signatures and for
|
||||
* shared signatures.
|
||||
*/
|
||||
@PostMapping("/{signatureId}/label")
|
||||
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
|
||||
public ResponseEntity<Void> updateSignatureLabel(
|
||||
@PathVariable String signatureId, @RequestBody Map<String, String> body) {
|
||||
try {
|
||||
String username = userService.getCurrentUsername();
|
||||
String newLabel = body.get("label");
|
||||
|
||||
if (newLabel == null || newLabel.trim().isEmpty()) {
|
||||
log.warn("Invalid label update request");
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
|
||||
signatureService.updateSignatureLabel(username, signatureId, newLabel);
|
||||
log.info("User {} updated label for signature {}", username, signatureId);
|
||||
return ResponseEntity.noContent().build();
|
||||
} catch (IOException e) {
|
||||
log.warn("Failed to update signature label: {}", e.getMessage());
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a signature owned by the authenticated user. Users can delete their own personal
|
||||
* signatures. Admins can also delete shared signatures.
|
||||
*/
|
||||
@DeleteMapping("/{signatureId}")
|
||||
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
|
||||
public ResponseEntity<Void> deleteSignature(@PathVariable String signatureId) {
|
||||
try {
|
||||
String username = userService.getCurrentUsername();
|
||||
boolean isAdmin = userService.isCurrentUserAdmin();
|
||||
|
||||
// Validate filename to prevent path traversal
|
||||
if (signatureId.contains("..")
|
||||
|| signatureId.contains("/")
|
||||
|| signatureId.contains("\\")) {
|
||||
log.warn("Invalid signature ID: {}", signatureId);
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
|
||||
// Try to delete from personal folder first
|
||||
try {
|
||||
signatureService.deleteSignature(username, signatureId);
|
||||
log.info("User {} deleted personal signature {}", username, signatureId);
|
||||
return ResponseEntity.noContent().build();
|
||||
} catch (IOException e) {
|
||||
// If not found in personal folder, check if it's in shared folder
|
||||
if (isAdmin) {
|
||||
// Admin can delete from shared folder
|
||||
if (deleteFromSharedFolder(signatureId)) {
|
||||
log.info("Admin {} deleted shared signature {}", username, signatureId);
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
}
|
||||
// If not admin or not found in shared folder either, return 404
|
||||
throw e;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.warn("Failed to delete signature {} for user: {}", signatureId, e.getMessage());
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a signature from the shared (ALL_USERS) folder. Only admins should call this method.
|
||||
*/
|
||||
private boolean deleteFromSharedFolder(String signatureId) throws IOException {
|
||||
String signatureBasePath = InstallationPathConfig.getSignaturesPath();
|
||||
Path sharedFolder = Paths.get(signatureBasePath, ALL_USERS_FOLDER);
|
||||
boolean deleted = false;
|
||||
|
||||
if (Files.exists(sharedFolder)) {
|
||||
try (Stream<Path> stream = Files.list(sharedFolder)) {
|
||||
List<Path> matchingFiles =
|
||||
stream.filter(
|
||||
path ->
|
||||
path.getFileName()
|
||||
.toString()
|
||||
.startsWith(signatureId + "."))
|
||||
.toList();
|
||||
for (Path file : matchingFiles) {
|
||||
Files.delete(file);
|
||||
deleted = true;
|
||||
log.info("Deleted shared signature file: {}", file);
|
||||
}
|
||||
}
|
||||
|
||||
// Also delete metadata file if it exists
|
||||
Path metadataPath = sharedFolder.resolve(signatureId + ".json");
|
||||
if (Files.exists(metadataPath)) {
|
||||
Files.delete(metadataPath);
|
||||
log.info("Deleted shared signature metadata: {}", metadataPath);
|
||||
}
|
||||
}
|
||||
|
||||
return deleted;
|
||||
}
|
||||
}
|
||||
+1
-13
@@ -34,19 +34,7 @@ import stirling.software.proprietary.util.FormUtils;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/form")
|
||||
@Tag(
|
||||
name = "Forms",
|
||||
description =
|
||||
"""
|
||||
Work with PDF form fields: read them, fill them, edit them, or remove them.
|
||||
Treats a PDF as a structured form instead of just flat pages.
|
||||
|
||||
Typical uses:
|
||||
• Inspect which form fields exist in a PDF
|
||||
• Autofill forms from your own systems (e.g. CRM, ERP)
|
||||
• Change or delete form fields before sending out a final, non-editable copy
|
||||
• Unlock read-only form fields when you need to update them
|
||||
""")
|
||||
@Tag(name = "Forms", description = "PDF form APIs")
|
||||
@RequiredArgsConstructor
|
||||
public class FormFillController {
|
||||
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
package stirling.software.proprietary.model.api.signature;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class SavedSignatureRequest {
|
||||
private String id;
|
||||
private String label;
|
||||
private String type; // "canvas", "image", "text"
|
||||
private String scope; // "personal", "shared"
|
||||
private String dataUrl; // For canvas and image types
|
||||
private String signerName; // For text type
|
||||
private String fontFamily; // For text type
|
||||
private Integer fontSize; // For text type
|
||||
private String textColor; // For text type
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
package stirling.software.proprietary.model.api.signature;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SavedSignatureResponse {
|
||||
private String id;
|
||||
private String label;
|
||||
private String type; // "canvas", "image", "text"
|
||||
private String scope; // "personal", "shared"
|
||||
private String dataUrl; // For canvas and image types (or URL to fetch image)
|
||||
private String signerName; // For text type
|
||||
private String fontFamily; // For text type
|
||||
private Integer fontSize; // For text type
|
||||
private String textColor; // For text type
|
||||
private Long createdAt;
|
||||
private Long updatedAt;
|
||||
}
|
||||
+4
-29
@@ -35,40 +35,15 @@ public class MailConfig {
|
||||
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||
mailSender.setHost(mailProperties.getHost());
|
||||
mailSender.setPort(mailProperties.getPort());
|
||||
mailSender.setUsername(mailProperties.getUsername());
|
||||
mailSender.setPassword(mailProperties.getPassword());
|
||||
mailSender.setDefaultEncoding("UTF-8");
|
||||
|
||||
// Only set username and password if they are provided
|
||||
String username = mailProperties.getUsername();
|
||||
String password = mailProperties.getPassword();
|
||||
boolean hasCredentials =
|
||||
(username != null && !username.trim().isEmpty())
|
||||
|| (password != null && !password.trim().isEmpty());
|
||||
|
||||
if (username != null && !username.trim().isEmpty()) {
|
||||
mailSender.setUsername(username);
|
||||
log.info("SMTP username configured");
|
||||
} else {
|
||||
log.info("SMTP username not configured - using anonymous connection");
|
||||
}
|
||||
|
||||
if (password != null && !password.trim().isEmpty()) {
|
||||
mailSender.setPassword(password);
|
||||
log.info("SMTP password configured");
|
||||
} else {
|
||||
log.info("SMTP password not configured");
|
||||
}
|
||||
|
||||
// Retrieves the JavaMail properties to configure additional SMTP parameters
|
||||
Properties props = mailSender.getJavaMailProperties();
|
||||
|
||||
// Only enable SMTP authentication if credentials are provided
|
||||
if (hasCredentials) {
|
||||
props.put("mail.smtp.auth", "true");
|
||||
log.info("SMTP authentication enabled");
|
||||
} else {
|
||||
props.put("mail.smtp.auth", "false");
|
||||
log.info("SMTP authentication disabled - no credentials provided");
|
||||
}
|
||||
// Enables SMTP authentication
|
||||
props.put("mail.smtp.auth", "true");
|
||||
|
||||
// Enables STARTTLS to encrypt the connection if supported by the SMTP server
|
||||
props.put("mail.smtp.starttls.enable", "true");
|
||||
|
||||
+1
-5
@@ -324,14 +324,10 @@ public class SecurityConfiguration {
|
||||
.authenticated());
|
||||
// Handle User/Password Logins
|
||||
if (securityProperties.isUserPass()) {
|
||||
// v2: Authentication is handled via API (/api/v1/auth/login), not form login
|
||||
// We configure form login to handle Spring Security redirects,
|
||||
// but use /perform_login as the processing URL so /login remains a React route
|
||||
http.formLogin(
|
||||
formLogin ->
|
||||
formLogin
|
||||
.loginPage("/login") // Redirect here when unauthenticated
|
||||
.loginProcessingUrl("/perform_login") // Process form posts here (not /login)
|
||||
.loginPage("/login")
|
||||
.successHandler(
|
||||
new CustomAuthenticationSuccessHandler(
|
||||
loginAttemptService,
|
||||
|
||||
-165
@@ -1,32 +1,22 @@
|
||||
package stirling.software.proprietary.security.controller.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.common.configuration.InstallationPathConfig;
|
||||
import stirling.software.common.model.ApplicationProperties;
|
||||
import stirling.software.common.util.GeneralUtils;
|
||||
import stirling.software.proprietary.security.configuration.ee.KeygenLicenseVerifier;
|
||||
@@ -252,159 +242,4 @@ public class AdminLicenseController {
|
||||
.body(Map.of("error", "Failed to retrieve license information"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a license certificate file for offline activation. Accepts .lic or .cert files,
|
||||
* validates the certificate format, saves to configs directory, and activates the license.
|
||||
*
|
||||
* @param file The license certificate file to upload
|
||||
* @return Response with success status, license type, and file information
|
||||
*/
|
||||
@PostMapping(value = "/license-file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
@Operation(
|
||||
summary = "Upload license certificate file",
|
||||
description =
|
||||
"Upload a license certificate file (.lic, .cert) for offline activation."
|
||||
+ " Validates the file format and activates the license.")
|
||||
public ResponseEntity<Map<String, Object>> uploadLicenseFile(
|
||||
@RequestParam("file") MultipartFile file) {
|
||||
|
||||
// Validate file exists
|
||||
if (file == null || file.isEmpty()) {
|
||||
return ResponseEntity.badRequest()
|
||||
.body(Map.of("success", false, "error", "File is empty"));
|
||||
}
|
||||
|
||||
String filename = file.getOriginalFilename();
|
||||
if (filename == null || filename.trim().isEmpty()) {
|
||||
return ResponseEntity.badRequest()
|
||||
.body(Map.of("success", false, "error", "Invalid filename"));
|
||||
}
|
||||
// Prevent path traversal and enforce single filename component
|
||||
if (filename.contains("..") || filename.contains("/") || filename.contains("\\")) {
|
||||
return ResponseEntity.badRequest()
|
||||
.body(
|
||||
Map.of(
|
||||
"success",
|
||||
false,
|
||||
"error",
|
||||
"Filename must not contain path separators or '..'"));
|
||||
}
|
||||
|
||||
// Validate file extension
|
||||
if (!isValidLicenseFile(filename)) {
|
||||
return ResponseEntity.badRequest()
|
||||
.body(
|
||||
Map.of(
|
||||
"success",
|
||||
false,
|
||||
"error",
|
||||
"Invalid file type. Expected .lic or .cert"));
|
||||
}
|
||||
|
||||
// Check file size (max 1MB for license files)
|
||||
if (file.getSize() > 1_048_576) {
|
||||
return ResponseEntity.badRequest()
|
||||
.body(Map.of("success", false, "error", "File too large. Maximum 1MB allowed"));
|
||||
}
|
||||
|
||||
try {
|
||||
// Validate certificate format by reading content
|
||||
byte[] fileBytes = file.getBytes();
|
||||
String content = new String(fileBytes, StandardCharsets.UTF_8);
|
||||
if (!content.trim().startsWith("-----BEGIN LICENSE FILE-----")) {
|
||||
return ResponseEntity.badRequest()
|
||||
.body(
|
||||
Map.of(
|
||||
"success",
|
||||
false,
|
||||
"error",
|
||||
"Invalid license certificate format"));
|
||||
}
|
||||
|
||||
// Get config directory and target path
|
||||
Path configPath = Paths.get(InstallationPathConfig.getConfigPath());
|
||||
Path targetPath = configPath.resolve(filename).normalize();
|
||||
// Prevent directory traversal: ensure targetPath is inside configPath
|
||||
if (!targetPath.startsWith(configPath.normalize().toAbsolutePath())) {
|
||||
return ResponseEntity.badRequest()
|
||||
.body(Map.of("success", false, "error", "Invalid file path"));
|
||||
}
|
||||
|
||||
// Backup existing file if present
|
||||
if (Files.exists(targetPath)) {
|
||||
Path backupDir = configPath.resolve("backup");
|
||||
Files.createDirectories(backupDir);
|
||||
|
||||
String backupFilename = filename + ".bak." + System.currentTimeMillis();
|
||||
Path backupPath = backupDir.resolve(backupFilename);
|
||||
|
||||
Files.copy(targetPath, backupPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
log.info("Backed up existing license file to: {}", backupPath);
|
||||
}
|
||||
|
||||
// Write new license file
|
||||
Files.write(targetPath, fileBytes);
|
||||
log.info("License file saved to: {}", targetPath);
|
||||
|
||||
// assume premium enabled when setting license key
|
||||
applicationProperties.getPremium().setEnabled(true);
|
||||
|
||||
// Update settings with file reference (relative path)
|
||||
String fileReference = "file:configs/" + filename;
|
||||
licenseKeyChecker.updateLicenseKey(fileReference);
|
||||
|
||||
// Get license status after activation
|
||||
License license = licenseKeyChecker.getPremiumLicenseEnabledResult();
|
||||
|
||||
Map<String, Object> response = new HashMap<>();
|
||||
response.put("success", true);
|
||||
response.put("licenseType", license.name());
|
||||
response.put("filename", filename);
|
||||
response.put("filePath", "configs/" + filename);
|
||||
response.put("enabled", applicationProperties.getPremium().isEnabled());
|
||||
response.put("maxUsers", applicationProperties.getPremium().getMaxUsers());
|
||||
response.put("message", "License file uploaded and activated");
|
||||
|
||||
log.info(
|
||||
"License file uploaded and activated: filename={}, type={}",
|
||||
filename,
|
||||
license.name());
|
||||
|
||||
return ResponseEntity.ok(response);
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to save license file", e);
|
||||
return ResponseEntity.internalServerError()
|
||||
.body(
|
||||
Map.of(
|
||||
"success",
|
||||
false,
|
||||
"error",
|
||||
"Failed to save license file: " + e.getMessage()));
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to activate license from file", e);
|
||||
return ResponseEntity.badRequest()
|
||||
.body(
|
||||
Map.of(
|
||||
"success",
|
||||
false,
|
||||
"error",
|
||||
"Failed to activate license: " + e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates if the filename has a valid license file extension (.lic or .cert)
|
||||
*
|
||||
* @param filename The filename to validate
|
||||
* @return true if the filename ends with .lic or .cert (case-insensitive)
|
||||
*/
|
||||
private boolean isValidLicenseFile(String filename) {
|
||||
if (filename == null) {
|
||||
return false;
|
||||
}
|
||||
String lower = filename.toLowerCase();
|
||||
return lower.endsWith(".lic") || lower.endsWith(".cert");
|
||||
}
|
||||
}
|
||||
|
||||
+4
-38
@@ -407,8 +407,7 @@ public class UserController {
|
||||
public ResponseEntity<?> inviteUsers(
|
||||
@RequestParam(name = "emails", required = true) String emails,
|
||||
@RequestParam(name = "role", defaultValue = "ROLE_USER") String role,
|
||||
@RequestParam(name = "teamId", required = false) Long teamId,
|
||||
HttpServletRequest request)
|
||||
@RequestParam(name = "teamId", required = false) Long teamId)
|
||||
throws SQLException, UnsupportedProviderException {
|
||||
|
||||
// Check if email invites are enabled
|
||||
@@ -478,9 +477,6 @@ public class UserController {
|
||||
}
|
||||
}
|
||||
|
||||
// Build login URL
|
||||
String loginUrl = buildLoginUrl(request);
|
||||
|
||||
int successCount = 0;
|
||||
int failureCount = 0;
|
||||
StringBuilder errors = new StringBuilder();
|
||||
@@ -492,7 +488,7 @@ public class UserController {
|
||||
continue;
|
||||
}
|
||||
|
||||
InviteResult result = processEmailInvite(email, effectiveTeamId, role, loginUrl);
|
||||
InviteResult result = processEmailInvite(email, effectiveTeamId, role);
|
||||
if (result.isSuccess()) {
|
||||
successCount++;
|
||||
} else {
|
||||
@@ -691,45 +687,15 @@ public class UserController {
|
||||
return ResponseEntity.ok(apiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to build the login URL from the application configuration or request.
|
||||
*
|
||||
* @param request The HTTP request
|
||||
* @return The login URL
|
||||
*/
|
||||
private String buildLoginUrl(HttpServletRequest request) {
|
||||
String baseUrl;
|
||||
String configuredFrontendUrl = applicationProperties.getSystem().getFrontendUrl();
|
||||
if (configuredFrontendUrl != null && !configuredFrontendUrl.trim().isEmpty()) {
|
||||
// Use configured frontend URL (remove trailing slash if present)
|
||||
baseUrl =
|
||||
configuredFrontendUrl.endsWith("/")
|
||||
? configuredFrontendUrl.substring(0, configuredFrontendUrl.length() - 1)
|
||||
: configuredFrontendUrl;
|
||||
} else {
|
||||
// Fall back to backend URL from request
|
||||
baseUrl =
|
||||
request.getScheme()
|
||||
+ "://"
|
||||
+ request.getServerName()
|
||||
+ (request.getServerPort() != 80 && request.getServerPort() != 443
|
||||
? ":" + request.getServerPort()
|
||||
: "");
|
||||
}
|
||||
return baseUrl + "/login";
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to process a single email invitation.
|
||||
*
|
||||
* @param email The email address to invite
|
||||
* @param teamId The team ID to assign the user to
|
||||
* @param role The role to assign to the user
|
||||
* @param loginUrl The URL to the login page
|
||||
* @return InviteResult containing success status and optional error message
|
||||
*/
|
||||
private InviteResult processEmailInvite(
|
||||
String email, Long teamId, String role, String loginUrl) {
|
||||
private InviteResult processEmailInvite(String email, Long teamId, String role) {
|
||||
try {
|
||||
// Validate email format (basic check)
|
||||
if (!email.contains("@") || !email.contains(".")) {
|
||||
@@ -749,7 +715,7 @@ public class UserController {
|
||||
|
||||
// Send invite email
|
||||
try {
|
||||
emailService.get().sendInviteEmail(email, email, temporaryPassword, loginUrl);
|
||||
emailService.get().sendInviteEmail(email, email, temporaryPassword);
|
||||
log.info("Sent invite email to: {}", email);
|
||||
return InviteResult.success();
|
||||
} catch (Exception emailEx) {
|
||||
|
||||
-13
@@ -56,19 +56,6 @@ public interface UserRepository extends JpaRepository<User, Long> {
|
||||
+ "OR LOWER(u.authenticationType) IN ('sso', 'oauth2', 'saml2')")
|
||||
List<User> findAllSsoUsers();
|
||||
|
||||
/**
|
||||
* Finds SSO users who have never created a session (pending activation) and are not yet
|
||||
* grandfathered.
|
||||
*/
|
||||
@Query(
|
||||
"SELECT u FROM User u "
|
||||
+ "LEFT JOIN SessionEntity s ON u.username = s.principalName "
|
||||
+ "WHERE (u.ssoProvider IS NOT NULL "
|
||||
+ "OR LOWER(u.authenticationType) IN ('sso', 'oauth2', 'saml2')) "
|
||||
+ "AND (u.oauthGrandfathered IS NULL OR u.oauthGrandfathered = false) "
|
||||
+ "AND s.sessionId IS NULL")
|
||||
List<User> findPendingSsoUsersWithoutSession();
|
||||
|
||||
/**
|
||||
* Counts all SSO users - those with sso_provider set OR authenticationType is sso/oauth2/saml2.
|
||||
*/
|
||||
|
||||
+5
-1
@@ -105,18 +105,22 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
}
|
||||
|
||||
try {
|
||||
log.debug("Validating JWT token");
|
||||
jwtService.validateToken(jwtToken);
|
||||
log.debug("JWT token validated successfully");
|
||||
} catch (AuthenticationFailureException e) {
|
||||
log.debug("JWT validation failed: {}", e.getMessage());
|
||||
log.warn("JWT validation failed: {}", e.getMessage());
|
||||
handleAuthenticationFailure(request, response, e);
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Object> claims = jwtService.extractClaims(jwtToken);
|
||||
String tokenUsername = claims.get("sub").toString();
|
||||
log.debug("JWT token username: {}", tokenUsername);
|
||||
|
||||
try {
|
||||
authenticate(request, claims);
|
||||
log.debug("Authentication successful for user: {}", tokenUsername);
|
||||
} catch (SQLException | UnsupportedProviderException e) {
|
||||
log.error("Error processing user authentication for user: {}", tokenUsername, e);
|
||||
handleAuthenticationFailure(
|
||||
|
||||
+1
-2
@@ -299,8 +299,7 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
|
||||
contextPath + "/api/v1/auth/refresh",
|
||||
contextPath + "/api/v1/auth/me",
|
||||
contextPath + "/api/v1/invite/validate",
|
||||
contextPath + "/api/v1/invite/accept",
|
||||
contextPath + "/api/v1/ui-data/footer-info"
|
||||
contextPath + "/api/v1/invite/accept"
|
||||
};
|
||||
|
||||
for (String pattern : publicApiPatterns) {
|
||||
|
||||
+5
-5
@@ -67,19 +67,19 @@ public class CustomSaml2AuthenticationSuccessHandler
|
||||
|
||||
boolean userExists = userService.usernameExistsIgnoreCase(username);
|
||||
|
||||
// Check if user is eligible for SAML (grandfathered or system has ENTERPRISE license)
|
||||
// Check if user is eligible for SAML (grandfathered or system has paid license)
|
||||
if (userExists) {
|
||||
stirling.software.proprietary.security.model.User user =
|
||||
userService.findByUsernameIgnoreCase(username).orElse(null);
|
||||
|
||||
if (user != null && !licenseSettingsService.isSamlEligible(user)) {
|
||||
// User is not grandfathered and no ENTERPRISE license - block SAML login
|
||||
if (user != null && !licenseSettingsService.isOAuthEligible(user)) {
|
||||
// User is not grandfathered and no paid license - block SAML login
|
||||
response.sendRedirect(
|
||||
request.getContextPath() + "/logout?saml2RequiresLicense=true");
|
||||
return;
|
||||
}
|
||||
} else if (!licenseSettingsService.isSamlEligible(null)) {
|
||||
// No existing user and no ENTERPRISE license -> block auto creation
|
||||
} else if (!licenseSettingsService.isOAuthEligible(null)) {
|
||||
// No existing user and no paid license -> block auto creation
|
||||
response.sendRedirect(
|
||||
request.getContextPath() + "/logout?saml2RequiresLicense=true");
|
||||
return;
|
||||
|
||||
+2
-12
@@ -115,12 +115,10 @@ public class EmailService {
|
||||
* @param to The recipient email address
|
||||
* @param username The username for the new account
|
||||
* @param temporaryPassword The temporary password
|
||||
* @param loginUrl The URL to the login page
|
||||
* @throws MessagingException If there is an issue with creating or sending the email.
|
||||
*/
|
||||
@Async
|
||||
public void sendInviteEmail(
|
||||
String to, String username, String temporaryPassword, String loginUrl)
|
||||
public void sendInviteEmail(String to, String username, String temporaryPassword)
|
||||
throws MessagingException {
|
||||
String subject = "Welcome to Stirling PDF";
|
||||
|
||||
@@ -146,14 +144,6 @@ public class EmailService {
|
||||
<div style="background-color: #fff3cd; border-left: 4px solid #ffc107; padding: 15px; margin: 20px 0; border-radius: 4px;">
|
||||
<p style="margin: 0; color: #856404;"><strong>⚠️ Important:</strong> You will be required to change your password upon first login for security reasons.</p>
|
||||
</div>
|
||||
<!-- CTA Button -->
|
||||
<div style="text-align: center; margin: 30px 0;">
|
||||
<a href="%s" style="display: inline-block; background-color: #007bff; color: #ffffff; padding: 14px 28px; text-decoration: none; border-radius: 5px; font-weight: bold;">Log In to Stirling PDF</a>
|
||||
</div>
|
||||
<p style="font-size: 14px; color: #666;">Or copy and paste this link in your browser:</p>
|
||||
<div style="background-color: #f8f9fa; padding: 12px; margin: 15px 0; border-radius: 4px; word-break: break-all; font-size: 13px; color: #555;">
|
||||
%s
|
||||
</div>
|
||||
<p>Please keep these credentials secure and do not share them with anyone.</p>
|
||||
<p style="margin-bottom: 0;">— The Stirling PDF Team</p>
|
||||
</div>
|
||||
@@ -165,7 +155,7 @@ public class EmailService {
|
||||
</div>
|
||||
</body></html>
|
||||
"""
|
||||
.formatted(username, temporaryPassword, loginUrl, loginUrl);
|
||||
.formatted(username, temporaryPassword);
|
||||
|
||||
sendPlainEmail(to, subject, body, true);
|
||||
}
|
||||
|
||||
+5
-1
@@ -50,6 +50,7 @@ public class JwtService implements JwtServiceInterface {
|
||||
KeyPersistenceServiceInterface keyPersistenceService) {
|
||||
this.v2Enabled = v2Enabled;
|
||||
this.keyPersistenceService = keyPersistenceService;
|
||||
log.info("JwtService initialized");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -255,9 +256,11 @@ public class JwtService implements JwtServiceInterface {
|
||||
String authHeader = request.getHeader("Authorization");
|
||||
if (authHeader != null && authHeader.startsWith("Bearer ")) {
|
||||
String token = authHeader.substring(7); // Remove "Bearer " prefix
|
||||
log.debug("JWT token extracted from Authorization header");
|
||||
return token;
|
||||
}
|
||||
|
||||
log.debug("No JWT token found in Authorization header");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -280,9 +283,10 @@ public class JwtService implements JwtServiceInterface {
|
||||
.parse(token)
|
||||
.getHeader()
|
||||
.get("kid");
|
||||
log.debug("Extracted key ID from token: {}", keyId);
|
||||
return keyId;
|
||||
} catch (Exception e) {
|
||||
log.debug("Failed to extract key ID from token header: {}", e.getMessage());
|
||||
log.warn("Failed to extract key ID from token header: {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -55,6 +55,7 @@ public class KeyPairCleanupService {
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Removing keys older than retention period");
|
||||
removeKeys(eligibleKeys);
|
||||
keyPersistenceService.refreshActiveKeyPair();
|
||||
}
|
||||
|
||||
-26
@@ -778,30 +778,4 @@ public class UserService implements UserServiceInterface {
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grandfathers SSO users who have never created a session (invited/pending accounts). These
|
||||
* users would otherwise be blocked when SSO requires a paid license despite existing before the
|
||||
* policy change.
|
||||
*
|
||||
* @return Number of pending users updated
|
||||
*/
|
||||
@Transactional
|
||||
public int grandfatherPendingSsoUsersWithoutSession() {
|
||||
List<User> pendingUsers = userRepository.findPendingSsoUsersWithoutSession();
|
||||
int updated = 0;
|
||||
|
||||
for (User user : pendingUsers) {
|
||||
if (!user.isOauthGrandfathered()) {
|
||||
user.setOauthGrandfathered(true);
|
||||
updated++;
|
||||
}
|
||||
}
|
||||
|
||||
if (updated > 0) {
|
||||
userRepository.saveAll(pendingUsers);
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
}
|
||||
|
||||
-390
@@ -1,390 +0,0 @@
|
||||
package stirling.software.proprietary.service;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import stirling.software.common.configuration.InstallationPathConfig;
|
||||
import stirling.software.common.service.PersonalSignatureServiceInterface;
|
||||
import stirling.software.proprietary.model.api.signature.SavedSignatureRequest;
|
||||
import stirling.software.proprietary.model.api.signature.SavedSignatureResponse;
|
||||
|
||||
/**
|
||||
* Service for managing user signatures with authentication and storage limits. This proprietary
|
||||
* version enforces per-user quotas and requires authentication. Provides access to personal
|
||||
* signatures only (shared signatures handled by core service).
|
||||
*/
|
||||
@Service
|
||||
@Slf4j
|
||||
public class SignatureService implements PersonalSignatureServiceInterface {
|
||||
|
||||
private final String SIGNATURE_BASE_PATH;
|
||||
private final String ALL_USERS_FOLDER = "ALL_USERS";
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
// Storage limits per user
|
||||
private static final int MAX_SIGNATURES_PER_USER = 20;
|
||||
private static final long MAX_SIGNATURE_SIZE_BYTES = 2_000_000; // 2MB per signature
|
||||
private static final long MAX_TOTAL_USER_STORAGE_BYTES = 20_000_000; // 20MB total per user
|
||||
|
||||
public SignatureService() {
|
||||
SIGNATURE_BASE_PATH = InstallationPathConfig.getSignaturesPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a personal signature from the user's folder only. Does NOT check shared folder (that's
|
||||
* handled by core service).
|
||||
*/
|
||||
@Override
|
||||
public byte[] getPersonalSignatureBytes(String username, String fileName) throws IOException {
|
||||
validateFileName(fileName);
|
||||
Path userPath = Paths.get(SIGNATURE_BASE_PATH, username, fileName);
|
||||
|
||||
if (!Files.exists(userPath)) {
|
||||
throw new FileNotFoundException("Personal signature not found");
|
||||
}
|
||||
|
||||
return Files.readAllBytes(userPath);
|
||||
}
|
||||
|
||||
/** Save a signature with storage limits enforced. */
|
||||
public SavedSignatureResponse saveSignature(String username, SavedSignatureRequest request)
|
||||
throws IOException {
|
||||
validateFileName(request.getId());
|
||||
|
||||
// Determine folder based on scope
|
||||
String scope = request.getScope();
|
||||
if (scope == null || scope.isEmpty()) {
|
||||
scope = "personal"; // Default to personal
|
||||
}
|
||||
|
||||
String folderName = "shared".equals(scope) ? ALL_USERS_FOLDER : username;
|
||||
Path targetFolder = Paths.get(SIGNATURE_BASE_PATH, folderName);
|
||||
|
||||
// Only enforce limits for personal signatures (not shared)
|
||||
if ("personal".equals(scope)) {
|
||||
enforceStorageLimits(username, request.getDataUrl());
|
||||
}
|
||||
|
||||
Files.createDirectories(targetFolder);
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
SavedSignatureResponse response = new SavedSignatureResponse();
|
||||
response.setId(request.getId());
|
||||
response.setLabel(request.getLabel());
|
||||
response.setType(request.getType());
|
||||
response.setScope(scope);
|
||||
response.setCreatedAt(timestamp);
|
||||
response.setUpdatedAt(timestamp);
|
||||
|
||||
// Copy text signature properties if present
|
||||
if ("text".equals(request.getType())) {
|
||||
response.setSignerName(request.getSignerName());
|
||||
response.setFontFamily(request.getFontFamily());
|
||||
response.setFontSize(request.getFontSize());
|
||||
response.setTextColor(request.getTextColor());
|
||||
}
|
||||
|
||||
// Extract and save image data
|
||||
String dataUrl = request.getDataUrl();
|
||||
if (dataUrl != null && dataUrl.startsWith("data:image/")) {
|
||||
// Validate dataUrl size before decoding
|
||||
if (dataUrl.length() > MAX_SIGNATURE_SIZE_BYTES * 2) {
|
||||
throw new IllegalArgumentException(
|
||||
"Signature data too large (max "
|
||||
+ (MAX_SIGNATURE_SIZE_BYTES / 1024)
|
||||
+ "KB)");
|
||||
}
|
||||
|
||||
// Extract base64 data
|
||||
String base64Data = dataUrl.substring(dataUrl.indexOf(",") + 1);
|
||||
byte[] imageBytes = Base64.getDecoder().decode(base64Data);
|
||||
|
||||
// Validate decoded size
|
||||
if (imageBytes.length > MAX_SIGNATURE_SIZE_BYTES) {
|
||||
throw new IllegalArgumentException(
|
||||
"Signature image too large (max "
|
||||
+ (MAX_SIGNATURE_SIZE_BYTES / 1024)
|
||||
+ "KB)");
|
||||
}
|
||||
|
||||
// Determine and validate file extension from data URL
|
||||
String mimeType = dataUrl.substring(dataUrl.indexOf(":") + 1, dataUrl.indexOf(";"));
|
||||
String rawExtension = mimeType.substring(mimeType.indexOf("/") + 1);
|
||||
String extension = validateAndNormalizeExtension(rawExtension);
|
||||
|
||||
// Save image file
|
||||
String imageFileName = request.getId() + "." + extension;
|
||||
Path imagePath = targetFolder.resolve(imageFileName);
|
||||
|
||||
// Verify path is within target directory
|
||||
verifyPathWithinDirectory(imagePath, targetFolder);
|
||||
|
||||
Files.write(
|
||||
imagePath,
|
||||
imageBytes,
|
||||
StandardOpenOption.CREATE,
|
||||
StandardOpenOption.TRUNCATE_EXISTING);
|
||||
|
||||
// Store reference to image file (unified endpoint for all signatures)
|
||||
response.setDataUrl("/api/v1/general/signatures/" + imageFileName);
|
||||
}
|
||||
|
||||
// Save metadata JSON file
|
||||
String metadataFileName = request.getId() + ".json";
|
||||
Path metadataPath = targetFolder.resolve(metadataFileName);
|
||||
verifyPathWithinDirectory(metadataPath, targetFolder);
|
||||
|
||||
String metadataJson = objectMapper.writeValueAsString(response);
|
||||
Files.writeString(
|
||||
metadataPath,
|
||||
metadataJson,
|
||||
StandardCharsets.UTF_8,
|
||||
StandardOpenOption.CREATE,
|
||||
StandardOpenOption.TRUNCATE_EXISTING);
|
||||
|
||||
log.info("Saved signature {} for user {} (scope: {})", request.getId(), username, scope);
|
||||
return response;
|
||||
}
|
||||
|
||||
/** Get all saved signatures for a user (personal + shared). */
|
||||
public List<SavedSignatureResponse> getSavedSignatures(String username) throws IOException {
|
||||
List<SavedSignatureResponse> signatures = new ArrayList<>();
|
||||
|
||||
// Load personal signatures
|
||||
Path personalFolder = Paths.get(SIGNATURE_BASE_PATH, username);
|
||||
if (Files.exists(personalFolder)) {
|
||||
signatures.addAll(loadSignaturesFromFolder(personalFolder, "personal", true));
|
||||
}
|
||||
|
||||
// Load shared signatures
|
||||
Path sharedFolder = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER);
|
||||
if (Files.exists(sharedFolder)) {
|
||||
signatures.addAll(loadSignaturesFromFolder(sharedFolder, "shared", false));
|
||||
}
|
||||
|
||||
return signatures;
|
||||
}
|
||||
|
||||
/** Delete a signature from user's personal folder. Cannot delete shared signatures. */
|
||||
public void deleteSignature(String username, String signatureId) throws IOException {
|
||||
validateFileName(signatureId);
|
||||
|
||||
// Only allow deletion from personal folder
|
||||
Path personalFolder = Paths.get(SIGNATURE_BASE_PATH, username);
|
||||
boolean deleted = false;
|
||||
|
||||
if (Files.exists(personalFolder)) {
|
||||
try (Stream<Path> stream = Files.list(personalFolder)) {
|
||||
List<Path> matchingFiles =
|
||||
stream.filter(
|
||||
path ->
|
||||
path.getFileName()
|
||||
.toString()
|
||||
.startsWith(signatureId + "."))
|
||||
.toList();
|
||||
for (Path file : matchingFiles) {
|
||||
Files.delete(file);
|
||||
deleted = true;
|
||||
log.info("Deleted signature file: {}", file);
|
||||
}
|
||||
}
|
||||
|
||||
// Also delete metadata file if it exists
|
||||
Path metadataPath = personalFolder.resolve(signatureId + ".json");
|
||||
if (Files.exists(metadataPath)) {
|
||||
Files.delete(metadataPath);
|
||||
log.info("Deleted signature metadata: {}", metadataPath);
|
||||
}
|
||||
}
|
||||
|
||||
if (!deleted) {
|
||||
throw new FileNotFoundException("Signature not found or cannot be deleted");
|
||||
}
|
||||
}
|
||||
|
||||
/** Update a signature label. */
|
||||
public void updateSignatureLabel(String username, String signatureId, String newLabel)
|
||||
throws IOException {
|
||||
validateFileName(signatureId);
|
||||
|
||||
// Try personal folder first
|
||||
Path personalFolder = Paths.get(SIGNATURE_BASE_PATH, username);
|
||||
Path metadataPath = personalFolder.resolve(signatureId + ".json");
|
||||
|
||||
if (Files.exists(metadataPath)) {
|
||||
updateMetadataLabel(metadataPath, newLabel);
|
||||
log.info("Updated label for personal signature {} (user: {})", signatureId, username);
|
||||
return;
|
||||
}
|
||||
|
||||
// If not found in personal, try shared folder
|
||||
Path sharedFolder = Paths.get(SIGNATURE_BASE_PATH, ALL_USERS_FOLDER);
|
||||
Path sharedMetadataPath = sharedFolder.resolve(signatureId + ".json");
|
||||
|
||||
if (Files.exists(sharedMetadataPath)) {
|
||||
updateMetadataLabel(sharedMetadataPath, newLabel);
|
||||
log.info("Updated label for shared signature {}", signatureId);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new FileNotFoundException("Signature metadata not found");
|
||||
}
|
||||
|
||||
private void updateMetadataLabel(Path metadataPath, String newLabel) throws IOException {
|
||||
String metadataJson = Files.readString(metadataPath, StandardCharsets.UTF_8);
|
||||
SavedSignatureResponse sig =
|
||||
objectMapper.readValue(metadataJson, SavedSignatureResponse.class);
|
||||
sig.setLabel(newLabel);
|
||||
sig.setUpdatedAt(System.currentTimeMillis());
|
||||
|
||||
String updatedJson = objectMapper.writeValueAsString(sig);
|
||||
Files.writeString(
|
||||
metadataPath,
|
||||
updatedJson,
|
||||
StandardCharsets.UTF_8,
|
||||
StandardOpenOption.CREATE,
|
||||
StandardOpenOption.TRUNCATE_EXISTING);
|
||||
}
|
||||
|
||||
// Private helper methods
|
||||
|
||||
private void enforceStorageLimits(String username, String dataUrlToAdd) throws IOException {
|
||||
Path userFolder = Paths.get(SIGNATURE_BASE_PATH, username);
|
||||
|
||||
if (!Files.exists(userFolder)) {
|
||||
return; // First signature, no limits to check
|
||||
}
|
||||
|
||||
// Count existing signatures
|
||||
long signatureCount;
|
||||
try (Stream<Path> stream = Files.list(userFolder)) {
|
||||
signatureCount = stream.filter(this::isImageFile).count();
|
||||
}
|
||||
|
||||
if (signatureCount >= MAX_SIGNATURES_PER_USER) {
|
||||
throw new IllegalArgumentException(
|
||||
"Maximum signatures limit reached (" + MAX_SIGNATURES_PER_USER + ")");
|
||||
}
|
||||
|
||||
// Calculate total storage used
|
||||
long totalSize = 0;
|
||||
try (Stream<Path> stream = Files.list(userFolder)) {
|
||||
totalSize =
|
||||
stream.filter(this::isImageFile)
|
||||
.mapToLong(
|
||||
path -> {
|
||||
try {
|
||||
return Files.size(path);
|
||||
} catch (IOException e) {
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
.sum();
|
||||
}
|
||||
|
||||
// Estimate new signature size (base64 decodes to ~75% of original)
|
||||
long estimatedNewSize = (long) (dataUrlToAdd.length() * 0.75);
|
||||
|
||||
if (totalSize + estimatedNewSize > MAX_TOTAL_USER_STORAGE_BYTES) {
|
||||
throw new IllegalArgumentException(
|
||||
"Storage quota exceeded (max "
|
||||
+ (MAX_TOTAL_USER_STORAGE_BYTES / 1_000_000)
|
||||
+ "MB)");
|
||||
}
|
||||
}
|
||||
|
||||
private List<SavedSignatureResponse> loadSignaturesFromFolder(
|
||||
Path folder, String scope, boolean isPersonal) throws IOException {
|
||||
List<SavedSignatureResponse> signatures = new ArrayList<>();
|
||||
|
||||
try (Stream<Path> stream = Files.list(folder)) {
|
||||
stream.filter(this::isImageFile)
|
||||
.forEach(
|
||||
path -> {
|
||||
try {
|
||||
String fileName = path.getFileName().toString();
|
||||
String id = fileName.substring(0, fileName.lastIndexOf('.'));
|
||||
|
||||
// Try to load metadata from JSON file
|
||||
Path metadataPath = folder.resolve(id + ".json");
|
||||
SavedSignatureResponse sig;
|
||||
|
||||
if (Files.exists(metadataPath)) {
|
||||
// Load from metadata file
|
||||
String metadataJson =
|
||||
Files.readString(
|
||||
metadataPath, StandardCharsets.UTF_8);
|
||||
sig =
|
||||
objectMapper.readValue(
|
||||
metadataJson, SavedSignatureResponse.class);
|
||||
} else {
|
||||
// Fallback for old signatures without metadata
|
||||
sig = new SavedSignatureResponse();
|
||||
sig.setId(id);
|
||||
sig.setLabel(id);
|
||||
sig.setType("image");
|
||||
sig.setScope(scope);
|
||||
sig.setCreatedAt(
|
||||
Files.getLastModifiedTime(path).toMillis());
|
||||
sig.setUpdatedAt(
|
||||
Files.getLastModifiedTime(path).toMillis());
|
||||
sig.setDataUrl("/api/v1/general/signatures/" + fileName);
|
||||
}
|
||||
|
||||
signatures.add(sig);
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading signature file: " + path, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return signatures;
|
||||
}
|
||||
|
||||
private boolean isImageFile(Path path) {
|
||||
String fileName = path.getFileName().toString().toLowerCase();
|
||||
return fileName.endsWith(".jpg") || fileName.endsWith(".jpeg") || fileName.endsWith(".png");
|
||||
}
|
||||
|
||||
private void validateFileName(String fileName) {
|
||||
if (fileName.contains("..") || fileName.contains("/") || fileName.contains("\\")) {
|
||||
throw new IllegalArgumentException("Invalid filename");
|
||||
}
|
||||
if (!fileName.matches("^[a-zA-Z0-9_.-]+$")) {
|
||||
throw new IllegalArgumentException("Filename contains invalid characters");
|
||||
}
|
||||
}
|
||||
|
||||
private String validateAndNormalizeExtension(String extension) {
|
||||
String normalized = extension.toLowerCase().trim();
|
||||
if (normalized.equals("png") || normalized.equals("jpg") || normalized.equals("jpeg")) {
|
||||
return normalized;
|
||||
}
|
||||
throw new IllegalArgumentException("Unsupported image extension: " + extension);
|
||||
}
|
||||
|
||||
private void verifyPathWithinDirectory(Path resolvedPath, Path targetDirectory)
|
||||
throws IOException {
|
||||
Path canonicalTarget = targetDirectory.toAbsolutePath().normalize();
|
||||
Path canonicalResolved = resolvedPath.toAbsolutePath().normalize();
|
||||
if (!canonicalResolved.startsWith(canonicalTarget)) {
|
||||
throw new IOException("Resolved path is outside the target directory");
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-46
@@ -192,18 +192,10 @@ public class UserLicenseSettingsService {
|
||||
+ "They will retain OAuth access even without a paid license. "
|
||||
+ "New users will require a paid license for OAuth.",
|
||||
updated);
|
||||
}
|
||||
|
||||
// Grandfather pending users (invited but never logged in)
|
||||
// The query filters to non-grandfathered users only, so this is idempotent
|
||||
if (grandfatheredCount > 0 || oauthUsersCount > 0) {
|
||||
int pendingUpdated = userService.grandfatherPendingSsoUsersWithoutSession();
|
||||
if (pendingUpdated > 0) {
|
||||
log.warn(
|
||||
"OAuth GRANDFATHERING: Marked {} pending SSO users (no prior sessions) as"
|
||||
+ " grandfathered.",
|
||||
pendingUpdated);
|
||||
}
|
||||
} else if (grandfatheredCount > 0) {
|
||||
log.debug(
|
||||
"OAuth grandfathering already completed: {} users grandfathered",
|
||||
grandfatheredCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,17 +323,17 @@ public class UserLicenseSettingsService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a user is eligible to use OAuth authentication.
|
||||
* Checks if a user is eligible to use OAuth/SAML authentication.
|
||||
*
|
||||
* <p>A user is eligible if:
|
||||
*
|
||||
* <ul>
|
||||
* <li>They are grandfathered for OAuth (existing user before policy change), OR
|
||||
* <li>The system has a paid license (SERVER or ENTERPRISE)
|
||||
* <li>The system has an ENTERPRISE license (SSO is enterprise-only)
|
||||
* </ul>
|
||||
*
|
||||
* @param user The user to check
|
||||
* @return true if the user can use OAuth
|
||||
* @return true if the user can use OAuth/SAML
|
||||
*/
|
||||
public boolean isOAuthEligible(stirling.software.proprietary.security.model.User user) {
|
||||
// Grandfathered users always have OAuth access
|
||||
@@ -350,36 +342,10 @@ public class UserLicenseSettingsService {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Users can use OAuth with SERVER or ENTERPRISE license
|
||||
boolean hasPaid = hasPaidLicense();
|
||||
log.debug("OAuth eligibility check: hasPaidLicense={}", hasPaid);
|
||||
return hasPaid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a user is eligible to use SAML authentication.
|
||||
*
|
||||
* <p>A user is eligible if:
|
||||
*
|
||||
* <ul>
|
||||
* <li>They are grandfathered for OAuth (existing user before policy change), OR
|
||||
* <li>The system has an ENTERPRISE license (SAML is enterprise-only)
|
||||
* </ul>
|
||||
*
|
||||
* @param user The user to check
|
||||
* @return true if the user can use SAML
|
||||
*/
|
||||
public boolean isSamlEligible(stirling.software.proprietary.security.model.User user) {
|
||||
// Grandfathered users always have SAML access
|
||||
if (user != null && user.isOauthGrandfathered()) {
|
||||
log.debug("User {} is grandfathered for SAML", user.getUsername());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Users can use SAML only with ENTERPRISE license
|
||||
boolean hasEnterprise = hasEnterpriseLicense();
|
||||
log.debug("SAML eligibility check: hasEnterpriseLicense={}", hasEnterprise);
|
||||
return hasEnterprise;
|
||||
// Users can use OAuth/SAML only if system has ENTERPRISE license
|
||||
boolean hasEnterpriseLicense = hasEnterpriseLicense();
|
||||
log.debug("OAuth eligibility check: hasEnterpriseLicense={}", hasEnterpriseLicense);
|
||||
return hasEnterpriseLicense;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -526,7 +492,8 @@ public class UserLicenseSettingsService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the system has an ENTERPRISE license. Used for enterprise-only features like SAML.
|
||||
* Checks if the system has an ENTERPRISE license. Used for enterprise-only features like SSO
|
||||
* (OAuth/SAML).
|
||||
*
|
||||
* @return true if ENTERPRISE license is active
|
||||
*/
|
||||
|
||||
-69
@@ -2,9 +2,6 @@ package stirling.software.proprietary.service;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -201,70 +198,4 @@ class UserLicenseSettingsServiceTest {
|
||||
|
||||
assertEquals(5, result, "Should fall back to default 5 users if grandfathered is 0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void grandfatherExistingOAuthUsers_runsOnlyWhenNoneGrandfathered() {
|
||||
// With grandfatheredCount == 0, should run grandfathering for all users
|
||||
when(userService.countOAuthUsers()).thenReturn(10L);
|
||||
when(userService.countGrandfatheredOAuthUsers()).thenReturn(0L);
|
||||
when(userService.grandfatherAllOAuthUsers()).thenReturn(10);
|
||||
when(userService.grandfatherPendingSsoUsersWithoutSession()).thenReturn(0);
|
||||
|
||||
service.grandfatherExistingOAuthUsers();
|
||||
|
||||
verify(userService, times(1)).grandfatherAllOAuthUsers();
|
||||
verify(userService, times(1)).grandfatherPendingSsoUsersWithoutSession();
|
||||
}
|
||||
|
||||
@Test
|
||||
void grandfatherExistingOAuthUsers_skipsMainButRunsPendingWhenSomeAlreadyGrandfathered() {
|
||||
// V2→V2.1 upgrade: some users already grandfathered, but pending users need to be checked
|
||||
when(userService.countOAuthUsers()).thenReturn(10L);
|
||||
when(userService.countGrandfatheredOAuthUsers()).thenReturn(4L);
|
||||
when(userService.grandfatherPendingSsoUsersWithoutSession()).thenReturn(2);
|
||||
|
||||
service.grandfatherExistingOAuthUsers();
|
||||
|
||||
verify(userService, never()).grandfatherAllOAuthUsers();
|
||||
verify(userService, times(1)).grandfatherPendingSsoUsersWithoutSession();
|
||||
}
|
||||
|
||||
@Test
|
||||
void grandfatherExistingOAuthUsers_stillChecksPendingWhenAllUsersGrandfathered() {
|
||||
// All active users grandfathered, but still check for pending users
|
||||
when(userService.countOAuthUsers()).thenReturn(10L);
|
||||
when(userService.countGrandfatheredOAuthUsers()).thenReturn(10L);
|
||||
when(userService.grandfatherPendingSsoUsersWithoutSession()).thenReturn(0);
|
||||
|
||||
service.grandfatherExistingOAuthUsers();
|
||||
|
||||
verify(userService, never()).grandfatherAllOAuthUsers();
|
||||
verify(userService, times(1)).grandfatherPendingSsoUsersWithoutSession();
|
||||
}
|
||||
|
||||
@Test
|
||||
void grandfatherExistingOAuthUsers_skipsWhenNoOAuthUsers() {
|
||||
when(userService.countOAuthUsers()).thenReturn(0L);
|
||||
when(userService.countGrandfatheredOAuthUsers()).thenReturn(0L);
|
||||
|
||||
service.grandfatherExistingOAuthUsers();
|
||||
|
||||
verify(userService, never()).grandfatherAllOAuthUsers();
|
||||
verify(userService, never()).grandfatherPendingSsoUsersWithoutSession();
|
||||
}
|
||||
|
||||
@Test
|
||||
void grandfatherExistingOAuthUsers_grandfathersPendingUsersOnFirstRun() {
|
||||
// Pending users (invited but never logged in) should be grandfathered
|
||||
// during the initial grandfathering run (when grandfatheredCount == 0)
|
||||
when(userService.countOAuthUsers()).thenReturn(5L);
|
||||
when(userService.countGrandfatheredOAuthUsers()).thenReturn(0L);
|
||||
when(userService.grandfatherAllOAuthUsers()).thenReturn(5);
|
||||
when(userService.grandfatherPendingSsoUsersWithoutSession()).thenReturn(3);
|
||||
|
||||
service.grandfatherExistingOAuthUsers();
|
||||
|
||||
verify(userService, times(1)).grandfatherAllOAuthUsers();
|
||||
verify(userService, times(1)).grandfatherPendingSsoUsersWithoutSession();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ repositories {
|
||||
|
||||
allprojects {
|
||||
group = 'stirling.software'
|
||||
version = '2.0.3'
|
||||
version = '2.0.1'
|
||||
|
||||
configurations.configureEach {
|
||||
exclude group: 'commons-logging', module: 'commons-logging'
|
||||
|
||||
@@ -8,33 +8,36 @@
|
||||
|
||||
Fork Stirling-PDF and create a new branch out of `main`.
|
||||
|
||||
## Frontend Translation Files (TOML Format)
|
||||
Then add a reference to the language in the navbar by adding a new language entry to the dropdown:
|
||||
|
||||
### Add Language Directory and Translation File
|
||||
- Edit the file: [languages.html](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/app/core/src/main/resources/templates/fragments/languages.html)
|
||||
|
||||
1. Create a new language directory in `frontend/public/locales/`
|
||||
- Use hyphenated format: `pl-PL` (not underscore)
|
||||
|
||||
2. Copy the reference translation file:
|
||||
- Source: `frontend/public/locales/en-GB/translation.toml`
|
||||
- Destination: `frontend/public/locales/pl-PL/translation.toml`
|
||||
For example, to add Polish, you would add:
|
||||
|
||||
3. Translate all entries in the TOML file
|
||||
- Keep the TOML structure intact
|
||||
- Preserve all placeholders like `{n}`, `{total}`, `{filename}`, `{{variable}}`
|
||||
- See `scripts/translations/README.md` for translation tools and workflows
|
||||
```html
|
||||
<div th:replace="~{fragments/languageEntry :: languageEntry ('pl_PL', 'Polski')}" ></div>
|
||||
```
|
||||
|
||||
4. Update the language selector in the frontend to include your new language
|
||||
The `data-bs-language-code` is the code used to reference the file in the next step.
|
||||
|
||||
Then make a Pull Request (PR) into `main` for others to use!
|
||||
### Add Language Property File
|
||||
|
||||
Start by copying the existing English property file:
|
||||
|
||||
- [messages_en_GB.properties](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/app/core/src/main/resources/messages_en_GB.properties)
|
||||
|
||||
Copy and rename it to `messages_{your data-bs-language-code here}.properties`. In the Polish example, you would set the name to `messages_pl_PL.properties`.
|
||||
|
||||
Then simply translate all property entries within that file and make a Pull Request (PR) into `main` for others to use!
|
||||
|
||||
If you do not have a Java IDE, I am happy to verify that the changes work once you raise the PR (but I won't be able to verify the translations themselves).
|
||||
|
||||
## Handling Untranslatable Strings
|
||||
|
||||
Sometimes, certain strings may not require translation because they are the same in the target language or are universal (like names of protocols, certain terminologies, etc.). To ensure accurate statistics for language progress, these strings should be added to the `ignore_translation.toml` file located in the `scripts` directory. This will exclude them from the translation progress calculations.
|
||||
Sometimes, certain strings in the properties file may not require translation because they are the same in the target language or are universal (like names of protocols, certain terminologies, etc.). To ensure accurate statistics for language progress, these strings should be added to the `ignore_translation.toml` file located in the `scripts` directory. This will exclude them from the translation progress calculations.
|
||||
|
||||
For example, if the English string `error` does not need translation in Polish, add it to the `ignore_translation.toml` under the Polish section:
|
||||
|
||||
**Note**: Use underscores in `ignore_translation.toml` even though frontend uses hyphens (e.g., `pl_PL` not `pl-PL`)
|
||||
For example, if the English string `error=Error` does not need translation in Polish, add it to the `ignore_translation.toml` under the Polish section:
|
||||
|
||||
```toml
|
||||
[pl_PL]
|
||||
@@ -47,27 +50,27 @@ ignore = [
|
||||
## Add New Translation Tags
|
||||
|
||||
> [!IMPORTANT]
|
||||
> If you add any new translation tags, they must first be added to the `en-GB/translation.toml` file. This ensures consistency across all language files.
|
||||
> If you add any new translation tags, they must first be added to the `messages_en_GB.properties` file. This ensures consistency across all language files.
|
||||
|
||||
- New translation tags **must be added** to `frontend/public/locales/en-GB/translation.toml` to maintain a reference for other languages.
|
||||
- After adding the new tags to `en-GB/translation.toml`, add and translate them in the respective language file (e.g., `pl-PL/translation.toml`).
|
||||
- Use the scripts in `scripts/translations/` to validate and manage translations (see `scripts/translations/README.md`)
|
||||
- New translation tags **must be added** to the `messages_en_GB.properties` file to maintain a reference for other languages.
|
||||
- After adding the new tags to `messages_en_GB.properties`, add and translate them in the respective language file (e.g., `messages_pl_PL.properties`).
|
||||
|
||||
Make sure to place the entry under the correct language section. This helps maintain the accuracy of translation progress statistics and ensures that the translation tool or scripts do not misinterpret the completion rate.
|
||||
|
||||
### Validation Commands
|
||||
### Use this code to perform a local check
|
||||
|
||||
Use the translation scripts in `scripts/translations/` directory:
|
||||
#### Windows command
|
||||
|
||||
```bash
|
||||
# Analyze translation progress
|
||||
python3 scripts/translations/translation_analyzer.py --language pl-PL
|
||||
```powershell
|
||||
python .github/scripts/check_language_properties.py --reference-file app\core\src\main\resources\messages_en_GB.properties --branch "" --files app\core\src\main\resources\messages_pl_PL.properties
|
||||
|
||||
# Validate TOML structure
|
||||
python3 scripts/translations/validate_json_structure.py --language pl-PL
|
||||
|
||||
# Validate placeholders
|
||||
python3 scripts/translations/validate_placeholders.py --language pl-PL
|
||||
python .github/scripts/check_language_properties.py --reference-file app\core\src\main\resources\messages_en_GB.properties --branch "" --check-file app\core\src\main\resources\messages_pl_PL.properties
|
||||
```
|
||||
|
||||
See `scripts/translations/README.md` for complete documentation.
|
||||
#### Linux command
|
||||
|
||||
```bash
|
||||
python3 .github/scripts/check_language_properties.py --reference-file app/core/src/main/resources/messages_en_GB.properties --branch "" --files app/core/src/main/resources/messages_pl_PL.properties
|
||||
|
||||
python3 .github/scripts/check_language_properties.py --reference-file app/core/src/main/resources/messages_en_GB.properties --branch "" --check-file app/core/src/main/resources/messages_pl_PL.properties
|
||||
```
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
# Stirling-PDF Dockerfile - Full version with embedded frontend
|
||||
# Single JAR contains both frontend and backend
|
||||
|
||||
# Stage 1: Build application with embedded frontend
|
||||
FROM gradle:8.14-jdk21 AS build
|
||||
|
||||
# Install Node.js and npm for frontend build
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||
&& apt-get install -y nodejs \
|
||||
&& npm --version \
|
||||
&& node --version \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy gradle files for dependency resolution
|
||||
COPY build.gradle .
|
||||
COPY settings.gradle .
|
||||
COPY gradlew .
|
||||
COPY gradle gradle/
|
||||
COPY app/core/build.gradle core/.
|
||||
COPY app/common/build.gradle common/.
|
||||
COPY app/proprietary/build.gradle proprietary/.
|
||||
RUN ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube || return 0
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy entire project
|
||||
COPY . .
|
||||
|
||||
# Build JAR with embedded frontend (includes security features controlled at runtime)
|
||||
RUN DISABLE_ADDITIONAL_FEATURES=false \
|
||||
STIRLING_PDF_DESKTOP_UI=false \
|
||||
./gradlew clean build -PbuildWithFrontend=true -x spotlessApply -x spotlessCheck -x test -x sonarqube
|
||||
|
||||
# Stage 2: Runtime image
|
||||
FROM alpine:3.22.1
|
||||
|
||||
ARG VERSION_TAG
|
||||
|
||||
# Labels
|
||||
LABEL org.opencontainers.image.title="Stirling-PDF"
|
||||
LABEL org.opencontainers.image.description="Stirling-PDF with embedded frontend - Full version"
|
||||
LABEL org.opencontainers.image.source="https://github.com/Stirling-Tools/Stirling-PDF"
|
||||
LABEL org.opencontainers.image.licenses="MIT"
|
||||
LABEL org.opencontainers.image.vendor="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.url="https://www.stirlingpdf.com"
|
||||
LABEL org.opencontainers.image.documentation="https://docs.stirlingpdf.com"
|
||||
LABEL maintainer="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.authors="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.version="${VERSION_TAG}"
|
||||
LABEL org.opencontainers.image.keywords="PDF, manipulation, API, Spring Boot, React"
|
||||
|
||||
# Copy scripts and fonts
|
||||
COPY scripts /scripts
|
||||
COPY app/core/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
|
||||
|
||||
# Copy built JAR from build stage
|
||||
COPY --from=build /app/app/core/build/libs/*.jar /app.jar
|
||||
COPY --from=build /app/build/libs/restart-helper.jar /restart-helper.jar
|
||||
|
||||
# Environment Variables
|
||||
ENV VERSION_TAG=$VERSION_TAG \
|
||||
JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \
|
||||
JAVA_CUSTOM_OPTS="" \
|
||||
HOME=/home/stirlingpdfuser \
|
||||
PUID=1000 \
|
||||
PGID=1000 \
|
||||
UMASK=022 \
|
||||
PYTHONPATH=/usr/lib/libreoffice/program:/opt/venv/lib/python3.12/site-packages \
|
||||
UNO_PATH=/usr/lib/libreoffice/program \
|
||||
URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc \
|
||||
PATH=$PATH:/opt/venv/bin \
|
||||
STIRLING_TEMPFILES_DIRECTORY=/tmp/stirling-pdf \
|
||||
TMPDIR=/tmp/stirling-pdf \
|
||||
TEMP=/tmp/stirling-pdf \
|
||||
TMP=/tmp/stirling-pdf
|
||||
|
||||
# Install all dependencies
|
||||
RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||
echo "@community https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
||||
apk upgrade --no-cache -a && \
|
||||
apk add --no-cache \
|
||||
ca-certificates \
|
||||
tzdata \
|
||||
tini \
|
||||
bash \
|
||||
curl \
|
||||
shadow \
|
||||
su-exec \
|
||||
openssl \
|
||||
openssl-dev \
|
||||
openjdk21-jre \
|
||||
# Doc conversion
|
||||
gcompat \
|
||||
libc6-compat \
|
||||
libreoffice \
|
||||
ghostscript \
|
||||
fontforge \
|
||||
# pdftohtml
|
||||
poppler-utils \
|
||||
# OCR MY PDF
|
||||
unpaper \
|
||||
tesseract-ocr-data-eng \
|
||||
tesseract-ocr-data-chi_sim \
|
||||
tesseract-ocr-data-deu \
|
||||
tesseract-ocr-data-fra \
|
||||
tesseract-ocr-data-por \
|
||||
ocrmypdf \
|
||||
# CV
|
||||
py3-opencv \
|
||||
python3 \
|
||||
py3-pip \
|
||||
py3-pillow@testing \
|
||||
py3-pdf2image@testing && \
|
||||
python3 -m venv /opt/venv && \
|
||||
/opt/venv/bin/pip install --upgrade pip setuptools && \
|
||||
/opt/venv/bin/pip install --no-cache-dir --upgrade unoserver weasyprint && \
|
||||
ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||
ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||
ln -s /usr/lib/libreoffice/program /opt/venv/lib/python3.12/site-packages/LibreOffice && \
|
||||
mv /usr/share/tessdata /usr/share/tessdata-original && \
|
||||
mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders /tmp/stirling-pdf && \
|
||||
fc-cache -f -v && \
|
||||
chmod +x /scripts/* && \
|
||||
# User permissions
|
||||
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /pipeline /usr/share/fonts/opentype/noto /configs /customFiles /tmp/stirling-pdf && \
|
||||
chown stirlingpdfuser:stirlingpdfgroup /app.jar /restart-helper.jar
|
||||
|
||||
EXPOSE 8080/tcp
|
||||
|
||||
# Set user and run command
|
||||
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
||||
CMD ["sh", "-c", "java -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/tmp/stirling-pdf -jar /app.jar & /opt/venv/bin/unoserver --port 2003 --interface 127.0.0.1"]
|
||||
@@ -1,142 +0,0 @@
|
||||
# Stirling-PDF Dockerfile - Fat version with embedded frontend
|
||||
# Single JAR contains both frontend and backend with extra fonts for air-gapped environments
|
||||
|
||||
# Stage 1: Build application with embedded frontend
|
||||
FROM gradle:8.14-jdk21 AS build
|
||||
|
||||
# Install Node.js and npm for frontend build
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||
&& apt-get install -y nodejs \
|
||||
&& npm --version \
|
||||
&& node --version \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy gradle files for dependency resolution
|
||||
COPY build.gradle .
|
||||
COPY settings.gradle .
|
||||
COPY gradlew .
|
||||
COPY gradle gradle/
|
||||
COPY app/core/build.gradle core/.
|
||||
COPY app/common/build.gradle common/.
|
||||
COPY app/proprietary/build.gradle proprietary/.
|
||||
RUN ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube || return 0
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy entire project
|
||||
COPY . .
|
||||
|
||||
# Build JAR with embedded frontend (includes security features controlled at runtime)
|
||||
RUN DISABLE_ADDITIONAL_FEATURES=false \
|
||||
STIRLING_PDF_DESKTOP_UI=false \
|
||||
./gradlew clean build -PbuildWithFrontend=true -x spotlessApply -x spotlessCheck -x test -x sonarqube
|
||||
|
||||
# Stage 2: Runtime image
|
||||
FROM alpine:3.22.1
|
||||
|
||||
ARG VERSION_TAG
|
||||
|
||||
# Labels
|
||||
LABEL org.opencontainers.image.title="Stirling-PDF Fat"
|
||||
LABEL org.opencontainers.image.description="Stirling-PDF with embedded frontend - Fat version with extra fonts for air-gapped environments"
|
||||
LABEL org.opencontainers.image.source="https://github.com/Stirling-Tools/Stirling-PDF"
|
||||
LABEL org.opencontainers.image.licenses="MIT"
|
||||
LABEL org.opencontainers.image.vendor="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.url="https://www.stirlingpdf.com"
|
||||
LABEL org.opencontainers.image.documentation="https://docs.stirlingpdf.com"
|
||||
LABEL maintainer="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.authors="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.version="${VERSION_TAG}"
|
||||
LABEL org.opencontainers.image.keywords="PDF, manipulation, fat, air-gapped, API, Spring Boot, React"
|
||||
|
||||
# Copy scripts and fonts
|
||||
COPY scripts /scripts
|
||||
COPY app/core/src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
|
||||
|
||||
# Copy built JAR from build stage
|
||||
COPY --from=build /app/app/core/build/libs/*.jar /app.jar
|
||||
COPY --from=build /app/build/libs/restart-helper.jar /restart-helper.jar
|
||||
|
||||
# Environment Variables
|
||||
ENV VERSION_TAG=$VERSION_TAG \
|
||||
JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \
|
||||
JAVA_CUSTOM_OPTS="" \
|
||||
HOME=/home/stirlingpdfuser \
|
||||
PUID=1000 \
|
||||
PGID=1000 \
|
||||
UMASK=022 \
|
||||
FAT_DOCKER=true \
|
||||
INSTALL_BOOK_AND_ADVANCED_HTML_OPS=false \
|
||||
PYTHONPATH=/usr/lib/libreoffice/program:/opt/venv/lib/python3.12/site-packages \
|
||||
UNO_PATH=/usr/lib/libreoffice/program \
|
||||
URE_BOOTSTRAP=file:///usr/lib/libreoffice/program/fundamentalrc \
|
||||
PATH=$PATH:/opt/venv/bin \
|
||||
STIRLING_TEMPFILES_DIRECTORY=/tmp/stirling-pdf \
|
||||
TMPDIR=/tmp/stirling-pdf \
|
||||
TEMP=/tmp/stirling-pdf \
|
||||
TMP=/tmp/stirling-pdf
|
||||
|
||||
# Install all dependencies plus extra fonts for air-gapped environments
|
||||
RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||
echo "@community https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
||||
apk upgrade --no-cache -a && \
|
||||
apk add --no-cache \
|
||||
ca-certificates \
|
||||
tzdata \
|
||||
tini \
|
||||
bash \
|
||||
curl \
|
||||
shadow \
|
||||
su-exec \
|
||||
openssl \
|
||||
openssl-dev \
|
||||
openjdk21-jre \
|
||||
# Doc conversion
|
||||
gcompat \
|
||||
libc6-compat \
|
||||
libreoffice \
|
||||
ghostscript \
|
||||
fontforge \
|
||||
# pdftohtml
|
||||
poppler-utils \
|
||||
# OCR MY PDF
|
||||
unpaper \
|
||||
tesseract-ocr-data-eng \
|
||||
tesseract-ocr-data-chi_sim \
|
||||
tesseract-ocr-data-deu \
|
||||
tesseract-ocr-data-fra \
|
||||
tesseract-ocr-data-por \
|
||||
ocrmypdf \
|
||||
# Extra fonts for fat version
|
||||
font-terminus font-dejavu font-noto font-noto-cjk font-awesome font-noto-extra font-liberation font-linux-libertine \
|
||||
# CV
|
||||
py3-opencv \
|
||||
python3 \
|
||||
py3-pip \
|
||||
py3-pillow@testing \
|
||||
py3-pdf2image@testing && \
|
||||
python3 -m venv /opt/venv && \
|
||||
/opt/venv/bin/pip install --upgrade pip setuptools && \
|
||||
/opt/venv/bin/pip install --no-cache-dir --upgrade unoserver weasyprint && \
|
||||
ln -s /usr/lib/libreoffice/program/uno.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||
ln -s /usr/lib/libreoffice/program/unohelper.py /opt/venv/lib/python3.12/site-packages/ && \
|
||||
ln -s /usr/lib/libreoffice/program /opt/venv/lib/python3.12/site-packages/LibreOffice && \
|
||||
mv /usr/share/tessdata /usr/share/tessdata-original && \
|
||||
mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders /tmp/stirling-pdf && \
|
||||
fc-cache -f -v && \
|
||||
chmod +x /scripts/* && \
|
||||
# User permissions
|
||||
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /pipeline /usr/share/fonts/opentype/noto /configs /customFiles /tmp/stirling-pdf && \
|
||||
chown stirlingpdfuser:stirlingpdfgroup /app.jar /restart-helper.jar
|
||||
|
||||
EXPOSE 8080/tcp
|
||||
|
||||
# Set user and run command
|
||||
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
||||
CMD ["sh", "-c", "java -Dfile.encoding=UTF-8 -Djava.io.tmpdir=/tmp/stirling-pdf -jar /app.jar & /opt/venv/bin/unoserver --port 2003 --interface 127.0.0.1"]
|
||||
@@ -1,104 +0,0 @@
|
||||
# Stirling-PDF Dockerfile - Ultra-lite version with embedded frontend
|
||||
# Single JAR contains both frontend and backend with minimal dependencies
|
||||
|
||||
# Stage 1: Build application with embedded frontend
|
||||
FROM gradle:8.14-jdk21 AS build
|
||||
|
||||
# Install Node.js and npm for frontend build
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
||||
&& apt-get install -y nodejs \
|
||||
&& npm --version \
|
||||
&& node --version \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy gradle files for dependency resolution
|
||||
COPY build.gradle .
|
||||
COPY settings.gradle .
|
||||
COPY gradlew .
|
||||
COPY gradle gradle/
|
||||
COPY app/core/build.gradle core/.
|
||||
COPY app/common/build.gradle common/.
|
||||
COPY app/proprietary/build.gradle proprietary/.
|
||||
RUN ./gradlew build -x spotlessApply -x spotlessCheck -x test -x sonarqube || return 0
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy entire project
|
||||
COPY . .
|
||||
|
||||
# Build ultra-lite JAR with embedded frontend (minimal features)
|
||||
RUN DISABLE_ADDITIONAL_FEATURES=true \
|
||||
STIRLING_PDF_DESKTOP_UI=false \
|
||||
./gradlew clean build -PbuildWithFrontend=true -x spotlessApply -x spotlessCheck -x test -x sonarqube
|
||||
|
||||
# Stage 2: Runtime image
|
||||
FROM alpine:3.22.1
|
||||
|
||||
ARG VERSION_TAG
|
||||
|
||||
# Labels
|
||||
LABEL org.opencontainers.image.title="Stirling-PDF Ultra-Lite"
|
||||
LABEL org.opencontainers.image.description="Stirling-PDF with embedded frontend - Ultra-lite version with minimal dependencies"
|
||||
LABEL org.opencontainers.image.source="https://github.com/Stirling-Tools/Stirling-PDF"
|
||||
LABEL org.opencontainers.image.licenses="MIT"
|
||||
LABEL org.opencontainers.image.vendor="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.url="https://www.stirlingpdf.com"
|
||||
LABEL org.opencontainers.image.documentation="https://docs.stirlingpdf.com"
|
||||
LABEL maintainer="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.authors="Stirling-Tools"
|
||||
LABEL org.opencontainers.image.version="${VERSION_TAG}"
|
||||
LABEL org.opencontainers.image.keywords="PDF, manipulation, ultra-lite, API, Spring Boot, React"
|
||||
|
||||
# Copy scripts
|
||||
COPY scripts/init-without-ocr.sh /scripts/init-without-ocr.sh
|
||||
COPY scripts/installFonts.sh /scripts/installFonts.sh
|
||||
|
||||
# Copy built JAR from build stage
|
||||
COPY --from=build /app/app/core/build/libs/*.jar /app.jar
|
||||
COPY --from=build /app/build/libs/restart-helper.jar /restart-helper.jar
|
||||
|
||||
# Environment Variables
|
||||
ENV VERSION_TAG=$VERSION_TAG \
|
||||
JAVA_BASE_OPTS="-XX:+UnlockExperimentalVMOptions -XX:MaxRAMPercentage=75 -XX:InitiatingHeapOccupancyPercent=20 -XX:+G1PeriodicGCInvokesConcurrent -XX:G1PeriodicGCInterval=10000 -XX:+UseStringDeduplication -XX:G1PeriodicGCSystemLoadThreshold=70" \
|
||||
JAVA_CUSTOM_OPTS="" \
|
||||
HOME=/home/stirlingpdfuser \
|
||||
PUID=1000 \
|
||||
PGID=1000 \
|
||||
UMASK=022 \
|
||||
STIRLING_TEMPFILES_DIRECTORY=/tmp/stirling-pdf \
|
||||
TMPDIR=/tmp/stirling-pdf \
|
||||
TEMP=/tmp/stirling-pdf \
|
||||
TMP=/tmp/stirling-pdf \
|
||||
ENDPOINTS_GROUPS_TO_REMOVE=CLI
|
||||
|
||||
# Install minimal dependencies
|
||||
RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||
echo "@community https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
||||
apk upgrade --no-cache -a && \
|
||||
apk add --no-cache \
|
||||
ca-certificates \
|
||||
tzdata \
|
||||
tini \
|
||||
bash \
|
||||
curl \
|
||||
shadow \
|
||||
su-exec \
|
||||
openjdk21-jre && \
|
||||
mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders /tmp/stirling-pdf && \
|
||||
mkdir -p /usr/share/fonts/opentype/noto && \
|
||||
chmod +x /scripts/*.sh && \
|
||||
# User permissions
|
||||
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
|
||||
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /configs /customFiles /pipeline /tmp/stirling-pdf && \
|
||||
chown stirlingpdfuser:stirlingpdfgroup /app.jar /restart-helper.jar
|
||||
|
||||
EXPOSE 8080/tcp
|
||||
|
||||
# Set user and run command
|
||||
ENTRYPOINT ["tini", "--", "/scripts/init-without-ocr.sh"]
|
||||
CMD ["java", "-Dfile.encoding=UTF-8", "-Djava.io.tmpdir=/tmp/stirling-pdf", "-jar", "/app.jar"]
|
||||
@@ -103,8 +103,8 @@ http {
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Cache static assets (but not API endpoints)
|
||||
location ~* ^(?!/api/).*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
# Cache static assets
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
@@ -106,8 +106,8 @@ http {
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# Cache static assets (but not API endpoints)
|
||||
location ~* ^(?!/api/).*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
# Cache static assets
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
+4
-4
@@ -3,21 +3,21 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<base href="%BASE_URL%" />
|
||||
<link rel="icon" href="modern-logo/favicon.ico" />
|
||||
<link rel="icon" href="/modern-logo/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="The Free Adobe Acrobat alternative (10M+ Downloads)"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="modern-logo/logo192.png" />
|
||||
<link rel="manifest" href="manifest.json" />
|
||||
<link rel="apple-touch-icon" href="/modern-logo/logo192.png" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
|
||||
<title>Stirling PDF</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="src/index.tsx"></script>
|
||||
<script type="module" src="/src/index.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Generated
+141
-159
@@ -11,26 +11,25 @@
|
||||
"dependencies": {
|
||||
"@atlaskit/pragmatic-drag-and-drop": "^1.7.7",
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@embedpdf/core": "^1.5.0",
|
||||
"@embedpdf/engines": "^1.5.0",
|
||||
"@embedpdf/plugin-annotation": "^1.5.0",
|
||||
"@embedpdf/plugin-bookmark": "^1.5.0",
|
||||
"@embedpdf/plugin-export": "^1.5.0",
|
||||
"@embedpdf/plugin-history": "^1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "^1.5.0",
|
||||
"@embedpdf/plugin-loader": "^1.5.0",
|
||||
"@embedpdf/plugin-pan": "^1.5.0",
|
||||
"@embedpdf/plugin-print": "^1.5.0",
|
||||
"@embedpdf/plugin-render": "^1.5.0",
|
||||
"@embedpdf/plugin-rotate": "^1.5.0",
|
||||
"@embedpdf/plugin-scroll": "^1.5.0",
|
||||
"@embedpdf/plugin-search": "^1.5.0",
|
||||
"@embedpdf/plugin-selection": "^1.5.0",
|
||||
"@embedpdf/plugin-spread": "^1.5.0",
|
||||
"@embedpdf/plugin-thumbnail": "^1.5.0",
|
||||
"@embedpdf/plugin-tiling": "^1.5.0",
|
||||
"@embedpdf/plugin-viewport": "^1.5.0",
|
||||
"@embedpdf/plugin-zoom": "^1.5.0",
|
||||
"@embedpdf/core": "^1.4.1",
|
||||
"@embedpdf/engines": "^1.4.1",
|
||||
"@embedpdf/plugin-annotation": "^1.4.1",
|
||||
"@embedpdf/plugin-bookmark": "^1.4.1",
|
||||
"@embedpdf/plugin-export": "^1.4.1",
|
||||
"@embedpdf/plugin-history": "^1.4.1",
|
||||
"@embedpdf/plugin-interaction-manager": "^1.4.1",
|
||||
"@embedpdf/plugin-loader": "^1.4.1",
|
||||
"@embedpdf/plugin-pan": "^1.4.1",
|
||||
"@embedpdf/plugin-render": "^1.4.1",
|
||||
"@embedpdf/plugin-rotate": "^1.4.1",
|
||||
"@embedpdf/plugin-scroll": "^1.4.1",
|
||||
"@embedpdf/plugin-search": "^1.4.1",
|
||||
"@embedpdf/plugin-selection": "^1.4.1",
|
||||
"@embedpdf/plugin-spread": "^1.4.1",
|
||||
"@embedpdf/plugin-thumbnail": "^1.4.1",
|
||||
"@embedpdf/plugin-tiling": "^1.4.1",
|
||||
"@embedpdf/plugin-viewport": "^1.4.1",
|
||||
"@embedpdf/plugin-zoom": "^1.4.1",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"@iconify/react": "^6.0.2",
|
||||
@@ -575,13 +574,13 @@
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/@embedpdf/core": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/core/-/core-1.5.0.tgz",
|
||||
"integrity": "sha512-Yrh9XoVaT8cUgzgqpJ7hx5wg6BqQrCFirqqlSwVb+Ly9oNn4fZbR9GycIWmzJOU5XBnaOJjXfQSaDyoNP0woNA==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/core/-/core-1.4.1.tgz",
|
||||
"integrity": "sha512-TGpxn2CvAKRnOJWJ3bsK+dKBiCp75ehxftRUmv7wAmPomhnG5XrDfoWJungvO+zbbqAwso6PocdeXINVt3hlAw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/engines": "1.5.0",
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/engines": "1.4.1",
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"preact": "^10.26.4",
|
||||
@@ -592,13 +591,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/engines": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/engines/-/engines-1.5.0.tgz",
|
||||
"integrity": "sha512-/GzhjHFHWfOaX7vjgFJX/pyq668wYjoda1bZ9MpwF/EF000Wwy2Q0AOhprjldPFz8ASKjwKwqsXmaqrK99yOAQ==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/engines/-/engines-1.4.1.tgz",
|
||||
"integrity": "sha512-yugIb5OwTI/1VnAaEvSYxAd2DvYBPkV/D7wytagyaOq98o3sqzcY2Q9zHt+LhnawA5KKG1e/FDPjCd4qm8gsvg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0",
|
||||
"@embedpdf/pdfium": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1",
|
||||
"@embedpdf/pdfium": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"preact": "^10.26.4",
|
||||
@@ -609,31 +608,31 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/models": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/models/-/models-1.5.0.tgz",
|
||||
"integrity": "sha512-x/1li3jdag+IzfZkcfRLKLqASLep4v6dgVi3z0JArwaicFra8k1IY2xaVTrwcZyx7pRb/rxvoO9yLHW0Y34NFw==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/models/-/models-1.4.1.tgz",
|
||||
"integrity": "sha512-2nTg8Q1qpplBvspZJXMCZOA+/OILpfdNRPddlplxZXY/Upx0rzKXx/e6pXWW7AuOgtfGneT4h9tMs3A595/PdQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@embedpdf/pdfium": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/pdfium/-/pdfium-1.5.0.tgz",
|
||||
"integrity": "sha512-PI32t2U4ThZC907n2Iwr8E5WqmC574G83u3V9ysNFl29N9kasrY9RiLSzU4W/yQvXPjIbpQHBsbMKXLjCFBI9w==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/pdfium/-/pdfium-1.4.1.tgz",
|
||||
"integrity": "sha512-BekKEK4UNCwzj7xOffKn6WpL0FQHxq+mTj2iGI3N7OwAX2J/BO2G+rDOB+lvojQG+Dkpg8uqm427ZKJDRyLgVQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-annotation": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-annotation/-/plugin-annotation-1.5.0.tgz",
|
||||
"integrity": "sha512-mxEPI6xYwOGaf9fYfoywuj6nwA10eHFPBuN066MzwphDk6DOHJGZ3Vq8zNQBXh20c/Lb25PL718D7MZWxZLUHg==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-annotation/-/plugin-annotation-1.4.1.tgz",
|
||||
"integrity": "sha512-d4HibNy6ecyDqx2Y2R8VjaqppSdjNofAJmU6VenOd88wn080sAUqvnkeVJ6ehJH5BoND4ymQrcAkcbVeYK0myA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0",
|
||||
"@embedpdf/utils": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1",
|
||||
"@embedpdf/utils": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-history": "1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "1.5.0",
|
||||
"@embedpdf/plugin-selection": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"@embedpdf/plugin-history": "1.4.1",
|
||||
"@embedpdf/plugin-interaction-manager": "1.4.1",
|
||||
"@embedpdf/plugin-selection": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -641,15 +640,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-bookmark": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-bookmark/-/plugin-bookmark-1.5.0.tgz",
|
||||
"integrity": "sha512-s3C9PtVesy5X8Ds/C9TEElFiqfKGRklG/uNPTROpNoolfpi0h7qX2xqqh/9+FzKH2nHjVcPB7Pp432v16h7eRA==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-bookmark/-/plugin-bookmark-1.4.1.tgz",
|
||||
"integrity": "sha512-WnfBJdv+Eq5zsMfwDZ5RlXZMGpvKm/ccL6jlTVwtELBhu3wvhjjbBmZdheEOzHMC3VXMNYDMjCeaXkUG4nWoDA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -657,15 +656,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-export": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-export/-/plugin-export-1.5.0.tgz",
|
||||
"integrity": "sha512-luk68mNW9l2X31qk4b02phKaqDl9aDXUAgHVz1EWrgwXQ3Oz9WEdu60utYARYDiepDo3Caadll8RwctYSf/anA==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-export/-/plugin-export-1.4.1.tgz",
|
||||
"integrity": "sha512-g89fREFM/zkt2Ai2Q5dWwDkhXgC/JmVyUniaMgm1fTG/MZ0Z05E7f34DUzX/CKcJyVjxEgl6tojBTMeUbm15bA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -674,15 +673,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-history": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-history/-/plugin-history-1.5.0.tgz",
|
||||
"integrity": "sha512-p7PTNNaIr4gH3jLwX+eLJe1DeUXgi21kVGN6SRx/pocH8esg4jqoOeD/YiRRZoZnPOiy0jBXVhkPkwSmY7a2hQ==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-history/-/plugin-history-1.4.1.tgz",
|
||||
"integrity": "sha512-5WLDiNMH6tACkLGGv/lJtNsDeozOhSbrh0mjD1btHun8u7Yscu/Vf8tdJRUOsd+nULivo2nQ2NFNKu0OTbVo8w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -690,15 +689,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-interaction-manager": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-interaction-manager/-/plugin-interaction-manager-1.5.0.tgz",
|
||||
"integrity": "sha512-ckHgTfvkW6c5Ta7Mc+Dl9C2foVnvEpqEJ84wyBnqrU0OWbe/jsiPhyKBVeartMGqNI/kVfaQTXupyrKhekAVmg==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-interaction-manager/-/plugin-interaction-manager-1.4.1.tgz",
|
||||
"integrity": "sha512-Ng02S9SFIAi9JZS5rI+NXSnZZ1Yk9YYRw4MlN2pig49qOyivZdz0oScZaYxQPewo8ccJkLeghjdeWswOBW/6cA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -707,15 +706,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-loader": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-loader/-/plugin-loader-1.5.0.tgz",
|
||||
"integrity": "sha512-P4YpIZfaW69etYIjphyaL4cGl2pB14h3OdTE0tRQ2pZYZHFLTvlt4q9B3PVSdhlSrHK5nob7jfLGon2U7xCslg==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-loader/-/plugin-loader-1.4.1.tgz",
|
||||
"integrity": "sha512-m3ZOk8JygsLxoa4cZ+0BVB5pfRWuBCg2/gPqjhoFZNKTqAFw4J6HGUrhYKg94GRYe+w1cTJl/NbTBYuU5DOrsA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -724,17 +723,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-pan": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-pan/-/plugin-pan-1.5.0.tgz",
|
||||
"integrity": "sha512-EMQ08dHqLkZmFVuLOO6h3AAinFPQoA1r6OlL9z+p0sswq31JAgd4X7+xjYIpI01z/V3+cTzPHzp7qwob5E4tbA==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-pan/-/plugin-pan-1.4.1.tgz",
|
||||
"integrity": "sha512-zmOZJ9dUqXiaV0F5GPf/5WTWf3jAEkiv153Tl3x8HT9Rfff+WQhV48NruCIBAy/T4jVt4aH7D1zt/B/ftvcdkA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "1.5.0",
|
||||
"@embedpdf/plugin-viewport": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"@embedpdf/plugin-interaction-manager": "1.4.1",
|
||||
"@embedpdf/plugin-viewport": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -742,33 +741,16 @@
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-print": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-print/-/plugin-print-1.5.0.tgz",
|
||||
"integrity": "sha512-rjorvNxAZfO9X4cFZVU9fHnldMWqMceJGmr3mH+yj7KdHePvNDDP+omyZyZKtxlUZENaeDI2h6k5z0GbhBz6sQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=18.0.0",
|
||||
"react-dom": ">=18.0.0",
|
||||
"svelte": ">=5 <6",
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-render": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-render/-/plugin-render-1.5.0.tgz",
|
||||
"integrity": "sha512-ywwSj0ByrlkvrJIHKRzqxARkOZriki8VJUC+T4MV8fGyF4CzvCRJyKlPktahFz+VxhoodqTh7lBCib68dH+GvA==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-render/-/plugin-render-1.4.1.tgz",
|
||||
"integrity": "sha512-gKCdNKw6WBHBEpTc2DLBWIWOxzsNnaNbpfeY6C4f2Bum0EO+XW3Hl2oIx1uaRHjIhhnXso1J3QweqelsPwDGwg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -777,15 +759,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-rotate": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-rotate/-/plugin-rotate-1.5.0.tgz",
|
||||
"integrity": "sha512-5EmBCsq0VfrE3xWY6ofuVm8S6aK95EbAycRIk1wczcmTdvpsuXZ6P2ZaECUgYMcpZ6uAg4/kGf8X8VVZuCihSQ==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-rotate/-/plugin-rotate-1.4.1.tgz",
|
||||
"integrity": "sha512-hVzHkKwMNH3tUhxqJGsj5qTLpYZXbj6E74AEcG0w/fz5FrK7EnofPqt0gRfYmIzxnQGIh+39BRtcp8gmx8UNnw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -794,16 +776,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-scroll": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-scroll/-/plugin-scroll-1.5.0.tgz",
|
||||
"integrity": "sha512-RNmTZCZ8X1mA8cw9M7TMDuhO9GtkOalGha2bBL3En3D1IlDRS7PzNNMSMV7eqT7OQICSTltlpJ8p8Qi5esvL/Q==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-scroll/-/plugin-scroll-1.4.1.tgz",
|
||||
"integrity": "sha512-Y9O+matB4j4fLim5s/jn7qIi+lMC9vmDJRpJhiWe8bvD9oYLP2xfD/DdhFgAjRKcNhPoxC+j8q8QN5BMeGAv2Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-viewport": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"@embedpdf/plugin-viewport": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -812,16 +794,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-search": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-search/-/plugin-search-1.5.0.tgz",
|
||||
"integrity": "sha512-TB5b0H8Iobx/azVUBIlG2ClaKtf0y3/Xi3E/iB8BwvkIE2+g6EGfp8IMXIn8WDXST6bbvJEP31Ab0Ilp6SVkiw==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-search/-/plugin-search-1.4.1.tgz",
|
||||
"integrity": "sha512-8JG4CbOcUsLuT0vHJJ4cECmu+Yn53EokWFUVXi2Mo/XvHjhrQuWmD7+y6s/qQPEpctFYWmUCXTDAX9ynPud+2Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-loader": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"@embedpdf/plugin-loader": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -830,17 +812,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-selection": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-selection/-/plugin-selection-1.5.0.tgz",
|
||||
"integrity": "sha512-zrxLBAZQoPswDuf9q9DrYaQc6B0Ysc2U1hueTjNH/4+ydfl0BFXZkKR63C2e3YmWtXvKjkoIj0GyPzsiBORLUw==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-selection/-/plugin-selection-1.4.1.tgz",
|
||||
"integrity": "sha512-lo5Ytk1PH0PrRKv6zKVupm4t02VGsqIrnSIeP6NO8Ujx0wfqEhj//sqIuO/EwfFVJD8lcQIP9UUo9y8baCrEog==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "1.5.0",
|
||||
"@embedpdf/plugin-viewport": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"@embedpdf/plugin-interaction-manager": "1.4.1",
|
||||
"@embedpdf/plugin-viewport": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -849,16 +831,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-spread": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-spread/-/plugin-spread-1.5.0.tgz",
|
||||
"integrity": "sha512-3EU5Cp+fPQSiMjvMR/P2kXxXry/RlnxHLs4JeskAaH95QcqWW3VD+DrHkWSiLFkdhI18rNNGNlMc5RvDGvbXGQ==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-spread/-/plugin-spread-1.4.1.tgz",
|
||||
"integrity": "sha512-l+SrDVGTiiItkt2cEtzv7V/X5HhmLbYHcQ8CFobGeIKdJtzKS1Nu/JSKqg7Ki7eCNgyPL1yMNfNE92bNKYVN4w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-loader": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"@embedpdf/plugin-loader": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -867,16 +849,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-thumbnail": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-thumbnail/-/plugin-thumbnail-1.5.0.tgz",
|
||||
"integrity": "sha512-Z2qpyyr5s2M6460KDGu1Vk6rdbQFIoCpnyFAT6e7UaTIKkqJSNpmjqMsBU5PosYCFu/cClpHPvS7tg9/IKAk6g==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-thumbnail/-/plugin-thumbnail-1.4.1.tgz",
|
||||
"integrity": "sha512-bN3msjI0PovazgbPK3LyugYVTwIDo0RyBUhBaG42FgJxeY3hmFOWTPgfUH1QF7twHlySnksIvHRFYR3nViryVw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-render": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"@embedpdf/plugin-render": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -885,18 +867,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-tiling": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-tiling/-/plugin-tiling-1.5.0.tgz",
|
||||
"integrity": "sha512-0Vx9elHNpMM+zv8hEoZXBEm8Q0+4kU52LxOlTYRr1A5FskF836sUct6g1ngwK1bmfbAfpz+62PnYI2EeilDZig==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-tiling/-/plugin-tiling-1.4.1.tgz",
|
||||
"integrity": "sha512-wgTfj5T8HV6KP61iiR63DVNrbVp8sPxTqa1Sm+2/D0jY+EPSSCmpt1/qYWiAXd1X+t78foOjCnfbo7fEMn5/pg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-render": "1.5.0",
|
||||
"@embedpdf/plugin-scroll": "1.5.0",
|
||||
"@embedpdf/plugin-viewport": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"@embedpdf/plugin-render": "1.4.1",
|
||||
"@embedpdf/plugin-scroll": "1.4.1",
|
||||
"@embedpdf/plugin-viewport": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -905,15 +887,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-viewport": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-viewport/-/plugin-viewport-1.5.0.tgz",
|
||||
"integrity": "sha512-G8GDyYRhfehw72+r4qKkydnA5+AU8qH67g01Y12b0DzI0VIzymh/05Z4dK8DsY3jyWPXJfw2hlg5+KDHaMBHgQ==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-viewport/-/plugin-viewport-1.4.1.tgz",
|
||||
"integrity": "sha512-+TgFHKPCLTBiDYe2DdsmTS37hwQgcZ3dYIc7bE0l5cp+GVwouu1h0MTmjL+90loizeWwCiu10E/zXR6hz+CUaQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0"
|
||||
"@embedpdf/models": "1.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -922,19 +904,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/plugin-zoom": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-zoom/-/plugin-zoom-1.5.0.tgz",
|
||||
"integrity": "sha512-LiDkCd5/IXg2CRORl1Yikan2op+AYXSxhHzCFatyBdwzVj+n4y9I74OwCI62Mar8WDAIMyXZDCQxGPToSm+zDw==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/plugin-zoom/-/plugin-zoom-1.4.1.tgz",
|
||||
"integrity": "sha512-9HocmXnPZxqN06q7kyNAmLjgDHOEW8/8QfgNE3nMpRyNHIgnAjxvsWc9lApgp5ErDPG0cSDt0Cduil6nB3wSBQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@embedpdf/models": "1.5.0",
|
||||
"@embedpdf/models": "1.4.1",
|
||||
"hammerjs": "^2.0.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@embedpdf/core": "1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "1.5.0",
|
||||
"@embedpdf/plugin-scroll": "1.5.0",
|
||||
"@embedpdf/plugin-viewport": "1.5.0",
|
||||
"@embedpdf/core": "1.4.1",
|
||||
"@embedpdf/plugin-interaction-manager": "1.4.1",
|
||||
"@embedpdf/plugin-scroll": "1.4.1",
|
||||
"@embedpdf/plugin-viewport": "1.4.1",
|
||||
"preact": "^10.26.4",
|
||||
"react": ">=16.8.0",
|
||||
"react-dom": ">=16.8.0",
|
||||
@@ -943,9 +925,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@embedpdf/utils": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/utils/-/utils-1.5.0.tgz",
|
||||
"integrity": "sha512-L6jsAPQPGM8ne+MMFAd5gqXb1RNEgNyh16VvVUVKcVnJlBhwil59nVeEQ0cwPhjF5qVeY6MQDIOjBzJqkgXOYg==",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@embedpdf/utils/-/utils-1.4.1.tgz",
|
||||
"integrity": "sha512-vvJ51Qsz3PyJWR2YvDMMpJXg4+YqdV7Vn2cusmW9sx+4EnAiBiw0HevEE+FepgFV8k+A0WbwXzmsujDIQJ7R4A==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"preact": "^10.26.4",
|
||||
|
||||
+19
-20
@@ -7,26 +7,25 @@
|
||||
"dependencies": {
|
||||
"@atlaskit/pragmatic-drag-and-drop": "^1.7.7",
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@embedpdf/core": "^1.5.0",
|
||||
"@embedpdf/engines": "^1.5.0",
|
||||
"@embedpdf/plugin-annotation": "^1.5.0",
|
||||
"@embedpdf/plugin-bookmark": "^1.5.0",
|
||||
"@embedpdf/plugin-export": "^1.5.0",
|
||||
"@embedpdf/plugin-history": "^1.5.0",
|
||||
"@embedpdf/plugin-interaction-manager": "^1.5.0",
|
||||
"@embedpdf/plugin-loader": "^1.5.0",
|
||||
"@embedpdf/plugin-pan": "^1.5.0",
|
||||
"@embedpdf/plugin-print": "^1.5.0",
|
||||
"@embedpdf/plugin-render": "^1.5.0",
|
||||
"@embedpdf/plugin-rotate": "^1.5.0",
|
||||
"@embedpdf/plugin-scroll": "^1.5.0",
|
||||
"@embedpdf/plugin-search": "^1.5.0",
|
||||
"@embedpdf/plugin-selection": "^1.5.0",
|
||||
"@embedpdf/plugin-spread": "^1.5.0",
|
||||
"@embedpdf/plugin-thumbnail": "^1.5.0",
|
||||
"@embedpdf/plugin-tiling": "^1.5.0",
|
||||
"@embedpdf/plugin-viewport": "^1.5.0",
|
||||
"@embedpdf/plugin-zoom": "^1.5.0",
|
||||
"@embedpdf/core": "^1.4.1",
|
||||
"@embedpdf/engines": "^1.4.1",
|
||||
"@embedpdf/plugin-annotation": "^1.4.1",
|
||||
"@embedpdf/plugin-bookmark": "^1.4.1",
|
||||
"@embedpdf/plugin-export": "^1.4.1",
|
||||
"@embedpdf/plugin-history": "^1.4.1",
|
||||
"@embedpdf/plugin-interaction-manager": "^1.4.1",
|
||||
"@embedpdf/plugin-loader": "^1.4.1",
|
||||
"@embedpdf/plugin-pan": "^1.4.1",
|
||||
"@embedpdf/plugin-render": "^1.4.1",
|
||||
"@embedpdf/plugin-rotate": "^1.4.1",
|
||||
"@embedpdf/plugin-scroll": "^1.4.1",
|
||||
"@embedpdf/plugin-search": "^1.4.1",
|
||||
"@embedpdf/plugin-selection": "^1.4.1",
|
||||
"@embedpdf/plugin-spread": "^1.4.1",
|
||||
"@embedpdf/plugin-thumbnail": "^1.4.1",
|
||||
"@embedpdf/plugin-tiling": "^1.4.1",
|
||||
"@embedpdf/plugin-viewport": "^1.4.1",
|
||||
"@embedpdf/plugin-zoom": "^1.4.1",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"@iconify/react": "^6.0.2",
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 6.9 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 9.5 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 7.4 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 11 KiB |
@@ -54,17 +54,17 @@
|
||||
--cc-secondary-color: #b0b0b0;
|
||||
|
||||
--cc-btn-primary-bg: #4dabf7;
|
||||
--cc-btn-primary-color: #ffffff;
|
||||
--cc-btn-primary-color: #2d2d2d;
|
||||
--cc-btn-primary-border-color: #4dabf7;
|
||||
--cc-btn-primary-hover-bg: #3d3d3d;
|
||||
--cc-btn-primary-hover-color: #ffffff;
|
||||
--cc-btn-primary-hover-color: #e5e5e5;
|
||||
--cc-btn-primary-hover-border-color: #3d3d3d;
|
||||
|
||||
--cc-btn-secondary-bg: #3d3d3d;
|
||||
--cc-btn-secondary-color: #ffffff;
|
||||
--cc-btn-secondary-color: #e5e5e5;
|
||||
--cc-btn-secondary-border-color: #3d3d3d;
|
||||
--cc-btn-secondary-hover-bg: #4dabf7;
|
||||
--cc-btn-secondary-hover-color: #ffffff;
|
||||
--cc-btn-secondary-hover-color: #2d2d2d;
|
||||
--cc-btn-secondary-hover-border-color: #4dabf7;
|
||||
|
||||
--cc-separator-border-color: #555555;
|
||||
@@ -180,27 +180,4 @@
|
||||
/* Lower z-index so cookie banner appears behind onboarding modals */
|
||||
#cc-main {
|
||||
z-index: 100 !important;
|
||||
}
|
||||
|
||||
/* Ensure consent modal text is visible in both themes */
|
||||
#cc-main .cm {
|
||||
background: var(--cc-bg) !important;
|
||||
color: var(--cc-primary-color) !important;
|
||||
}
|
||||
|
||||
#cc-main .cm__title {
|
||||
color: var(--cc-primary-color) !important;
|
||||
}
|
||||
|
||||
#cc-main .cm__desc {
|
||||
color: var(--cc-primary-color) !important;
|
||||
}
|
||||
|
||||
#cc-main .cm__footer {
|
||||
color: var(--cc-primary-color) !important;
|
||||
}
|
||||
|
||||
#cc-main .cm__footer-links a,
|
||||
#cc-main .cm__link {
|
||||
color: var(--cc-primary-color) !important;
|
||||
}
|
||||
@@ -163,11 +163,6 @@ unfavorite = "إزالة من المفضلة"
|
||||
fullscreen = "التبديل إلى وضع ملء الشاشة"
|
||||
sidebar = "التبديل إلى وضع الشريط الجانبي"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "لم يتم العثور على الخادم الخلفي"
|
||||
retry = "إعادة المحاولة"
|
||||
unreachable = "لا يمكن للتطبيق حالياً الاتصال بالخادم الخلفي. تحقق من حالة الخادم والاتصال بالشبكة، ثم حاول مرة أخرى."
|
||||
|
||||
[zipWarning]
|
||||
title = "ملف ZIP كبير"
|
||||
message = "هذا الملف ZIP يحتوي على {{count}} ملفات. هل تريد الاستخراج على أي حال؟"
|
||||
@@ -918,8 +913,8 @@ desc = "تراكب ملف PDF فوق آخر"
|
||||
title = "تراكب ملفات PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "محرر نص PDF"
|
||||
desc = "حرّر النصوص والصور الموجودة داخل ملفات PDF"
|
||||
title = "محرر نصوص PDF"
|
||||
desc = "مراجعة وتحرير صادرات Stirling PDF بصيغة JSON مع تحرير نصوص مجمّعة وإعادة إنشاء PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "نص,تعليق,تسمية"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "توقيع مرسوم"
|
||||
defaultImageLabel = "توقيع مرفوع"
|
||||
defaultTextLabel = "توقيع مكتوب"
|
||||
saveButton = "حفظ التوقيع"
|
||||
savePersonal = "حفظ شخصي"
|
||||
saveShared = "حفظ مشترك"
|
||||
saveUnavailable = "أنشئ توقيعاً أولاً لحفظه."
|
||||
noChanges = "التوقيع الحالي محفوظ بالفعل."
|
||||
tempStorageTitle = "تخزين مؤقت في المتصفح"
|
||||
tempStorageDescription = "يتم تخزين التواقيع في متصفحك فقط. ستُفقد إذا حذفت بيانات المتصفح أو بدّلت المتصفح."
|
||||
personalHeading = "تواقيع شخصية"
|
||||
sharedHeading = "تواقيع مشتركة"
|
||||
personalDescription = "أنت فقط من يمكنه رؤية هذه التواقيع."
|
||||
sharedDescription = "يمكن لجميع المستخدمين رؤية هذه التواقيع واستخدامها."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "رسم"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "الرجاء تسجيل الدخول"
|
||||
ssoSignIn = "تسجيل الدخول عبر تسجيل الدخول الأحادي"
|
||||
oAuth2AutoCreateDisabled = "تم تعطيل الإنشاء التلقائي لمستخدم OAuth2"
|
||||
oAuth2AdminBlockedUser = "تم حظر تسجيل أو تسجيل دخول المستخدمين غير المسجلين حاليًا. يرجى الاتصال بالمسؤول."
|
||||
oAuth2RequiresLicense = "يتطلب تسجيل الدخول عبر OAuth/SSO ترخيصاً مدفوعاً (Server أو Enterprise). يرجى الاتصال بالمسؤول لترقية باقتك."
|
||||
saml2RequiresLicense = "يتطلب تسجيل الدخول عبر SAML ترخيصاً مدفوعاً (Server أو Enterprise). يرجى الاتصال بالمسؤول لترقية باقتك."
|
||||
maxUsersReached = "تم الوصول إلى الحد الأقصى لعدد المستخدمين ضمن ترخيصك الحالي. يرجى الاتصال بالمسؤول لترقية باقتك أو إضافة مقاعد إضافية."
|
||||
oauth2RequestNotFound = "لم يتم العثور على طلب التفويض"
|
||||
oauth2InvalidUserInfoResponse = "استجابة معلومات المستخدم غير صالحة"
|
||||
oauth2invalidRequest = "طلب غير صالح"
|
||||
@@ -3790,7 +3774,7 @@ version = "الإصدار الحالي"
|
||||
title = "توثيق API"
|
||||
header = "توثيق API"
|
||||
desc = "عرض واختبار نقاط نهاية Stirling PDF API"
|
||||
tags = "api,توثيق,swagger,نقاط النهاية,تطوير"
|
||||
tags = "api,documentation,swagger,endpoints,development"
|
||||
|
||||
[cookieBanner.popUp]
|
||||
title = "كيف نستخدم ملفات تعريف الارتباط"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "ملاءمة للعرض"
|
||||
actualSize = "الحجم الفعلي"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "لا يمكن معاينة الملف"
|
||||
dualPageView = "عرض صفحتين"
|
||||
firstPage = "الصفحة الأولى"
|
||||
lastPage = "الصفحة الأخيرة"
|
||||
nextPage = "الصفحة التالية"
|
||||
onlyPdfSupported = "عارض الملفات يدعم ملفات PDF فقط. يبدو أن هذا الملف بتنسيق مختلف."
|
||||
previousPage = "الصفحة السابقة"
|
||||
singlePageView = "عرض صفحة واحدة"
|
||||
unknownFile = "ملف غير معروف"
|
||||
nextPage = "الصفحة التالية"
|
||||
zoomIn = "تكبير"
|
||||
zoomOut = "تصغير"
|
||||
singlePageView = "عرض صفحة واحدة"
|
||||
dualPageView = "عرض صفحتين"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "إغلاق الصفحات المحددة"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "تبديل الشريط الجانبي"
|
||||
exportSelected = "تصدير الصفحات المحددة"
|
||||
toggleAnnotations = "تبديل ظهور التعليقات التوضيحية"
|
||||
annotationMode = "تبديل وضع التعليقات"
|
||||
print = "طباعة PDF"
|
||||
draw = "رسم"
|
||||
save = "حفظ"
|
||||
saveChanges = "حفظ التغييرات"
|
||||
@@ -4517,7 +4497,6 @@ description = "عنوان URL أو اسم الملف الخاص بـ Impressum (
|
||||
title = "الممتاز والمؤسسي"
|
||||
description = "تهيئة مفتاح الترخيص للمزايا الممتازة أو المؤسسية."
|
||||
license = "تهيئة الترخيص"
|
||||
noInput = "يرجى تقديم مفتاح ترخيص أو ملف"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "هل لديك مفتاح ترخيص أو ملف شهادة؟"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "لا يمكن التراجع عن استبدال مفتاح الترخ
|
||||
line2 = "سيُفقد ترخيصك السابق نهائياً ما لم تكن قد احتفظت بنسخة احتياطية منه في مكان آخر."
|
||||
line3 = "مهم: احتفظ بمفاتيح الترخيص خاصة وآمنة. لا تشاركها علناً أبداً."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "مفتاح الترخيص"
|
||||
file = "ملف الشهادة"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "ملف شهادة الترخيص"
|
||||
description = "قم بتحميل ملف الترخيص .lic أو .cert من عمليات الشراء دون اتصال"
|
||||
choose = "اختر ملف الترخيص"
|
||||
selected = "المحدد: {{filename}} ({{size}})"
|
||||
successMessage = "تم تحميل ملف الترخيص وتفعيله بنجاح. لا يلزم إعادة التشغيل."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "الترخيص النشط"
|
||||
file = "المصدر: ملف الترخيص ({{path}})"
|
||||
key = "المصدر: مفتاح الترخيص"
|
||||
type = "النوع: {{type}}"
|
||||
noInput = "يرجى تقديم مفتاح ترخيص أو تحميل ملف شهادة"
|
||||
success = "نجاح"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "تمكين الميزات الممتازة"
|
||||
description = "تمكين التحقق من مفتاح الترخيص لميزات Pro/المؤسسة"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} محدد"
|
||||
download = "تنزيل"
|
||||
delete = "حذف"
|
||||
unsupported = "غير مدعوم"
|
||||
active = "نشط"
|
||||
addToUpload = "إضافة إلى الرفع"
|
||||
closeFile = "إغلاق الملف"
|
||||
deleteAll = "حذف الكل"
|
||||
loadingFiles = "جارٍ تحميل الملفات..."
|
||||
noFiles = "لا توجد ملفات متاحة"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "مطلوب عنوان بريد إلكتروني واحد على الأقل"
|
||||
submit = "إرسال الدعوات"
|
||||
success = "تمت دعوة المستخدم/المستخدمين بنجاح"
|
||||
partialFailure = "فشل بعض الدعوات"
|
||||
partialSuccess = "فشلت بعض الدعوات"
|
||||
allFailed = "فشلت دعوة المستخدمين"
|
||||
error = "فشل إرسال الدعوات"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "تسجيل الدخول"
|
||||
signInWith = "تسجيل الدخول باستخدام"
|
||||
oauthPending = "جارٍ فتح المتصفح للمصادقة..."
|
||||
orContinueWith = "أو المتابعة بالبريد الإلكتروني"
|
||||
serverRequirement = "ملاحظة: يجب أن يكون تسجيل الدخول مفعّلاً على الخادم."
|
||||
showInstructions = "كيفية التمكين؟"
|
||||
hideInstructions = "إخفاء الإرشادات"
|
||||
instructions = "لتمكين تسجيل الدخول على خادم Stirling PDF الخاص بك:"
|
||||
instructionsEnvVar = "عيّن متغيّر البيئة:"
|
||||
instructionsOrYml = "أو في settings.yml:"
|
||||
instructionsRestart = "ثم أعد تشغيل الخادم لتصبح التغييرات نافذة."
|
||||
|
||||
[setup.login.username]
|
||||
label = "اسم المستخدم"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Seçilmişlərdən çıxar"
|
||||
fullscreen = "Tam ekran rejiminə keç"
|
||||
sidebar = "Yan panel rejiminə keç"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend tapılmadı"
|
||||
retry = "Yenidən cəhd et"
|
||||
unreachable = "Tətbiq hazırda backend-ə qoşula bilmir. Backend-in vəziyyətini və şəbəkə bağlantısını yoxlayın, sonra yenidən cəhd edin."
|
||||
|
||||
[zipWarning]
|
||||
title = "Böyük ZIP faylı"
|
||||
message = "Bu ZIP {{count}} fayl ehtiva edir. Yenə də çıxarılsın?"
|
||||
@@ -919,7 +914,7 @@ title = "Üst-Üstə Qoy"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF Mətn Redaktoru"
|
||||
desc = "PDF-lərin içindəki mövcud mətn və şəkilləri redaktə edin"
|
||||
desc = "Qruplaşdırılmış mətn redaktəsi və PDF yenidən yaradılması ilə Stirling PDF JSON ixraclarını nəzərdən keçirin və redaktə edin"
|
||||
|
||||
[home.addText]
|
||||
tags = "mətn,şərh,etiket"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Çəkilmiş imza"
|
||||
defaultImageLabel = "Yüklənmiş imza"
|
||||
defaultTextLabel = "Yazılmış imza"
|
||||
saveButton = "İmzanı saxla"
|
||||
savePersonal = "Şəxsi yadda saxla"
|
||||
saveShared = "Paylaşılanı yadda saxla"
|
||||
saveUnavailable = "Saxlamaq üçün əvvəlcə imza yaradın."
|
||||
noChanges = "Cari imza artıq saxlanıb."
|
||||
tempStorageTitle = "Müvəqqəti brauzer yaddaşı"
|
||||
tempStorageDescription = "İmzalar yalnız brauzerinizdə saxlanılır. Brauzer məlumatlarını təmizləsəniz və ya brauzer dəyişsəniz, itəcək."
|
||||
personalHeading = "Şəxsi imzalar"
|
||||
sharedHeading = "Paylaşılan imzalar"
|
||||
personalDescription = "Bu imzaları yalnız siz görə bilirsiniz."
|
||||
sharedDescription = "Bütün istifadəçilər bu imzaları görə və istifadə edə bilərlər."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Rəsm"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Zəhmət olmasa, daxil olun"
|
||||
ssoSignIn = "Single Sign-on vasitəsilə daxil olun"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Auto-Create İstifadəçisi Deaktivləşdirilmişdir"
|
||||
oAuth2AdminBlockedUser = "Qeydiyyatdan keçməmiş istifadəçilərin qeydiyyatı və daxil olması hal-hazırda bloklanmışdır. Zəhmət olmasa, administratorla əlaqə saxlayın."
|
||||
oAuth2RequiresLicense = "OAuth/SSO ilə giriş üçün ödənişli lisenziya (Server və ya Enterprise) tələb olunur. Planınızı yüksəltmək üçün administratorla əlaqə saxlayın."
|
||||
saml2RequiresLicense = "SAML ilə giriş üçün ödənişli lisenziya (Server və ya Enterprise) tələb olunur. Planınızı yüksəltmək üçün administratorla əlaqə saxlayın."
|
||||
maxUsersReached = "Mövcud lisenziyanız üçün maksimum istifadəçi sayına çatılıb. Planınızı yüksəltmək və ya əlavə yerlər əlavə etmək üçün administratorla əlaqə saxlayın."
|
||||
oauth2RequestNotFound = "Təsdiqlənmə sorğusu tapılmadı"
|
||||
oauth2InvalidUserInfoResponse = "Yanlış İstifadəçi Məlumatı Cavabı"
|
||||
oauth2invalidRequest = "Etibarsız Sorğu"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Eninə sığdır"
|
||||
actualSize = "Həqiqi ölçü"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Faylın önizlənməsi mümkün deyil"
|
||||
dualPageView = "İki Səhifə Görünüşü"
|
||||
firstPage = "Birinci səhifə"
|
||||
lastPage = "Son səhifə"
|
||||
nextPage = "Növbəti səhifə"
|
||||
onlyPdfSupported = "Görüntüləyici yalnız PDF fayllarını dəstəkləyir. Bu fayl fərqli formatda görünür."
|
||||
previousPage = "Əvvəlki səhifə"
|
||||
singlePageView = "Tək Səhifə Görünüşü"
|
||||
unknownFile = "Naməlum fayl"
|
||||
nextPage = "Növbəti səhifə"
|
||||
zoomIn = "Böyüt"
|
||||
zoomOut = "Kiçilt"
|
||||
singlePageView = "Tək Səhifə Görünüşü"
|
||||
dualPageView = "İki Səhifə Görünüşü"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Seçilmiş faylları bağla"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Yan paneli aç/bağla"
|
||||
exportSelected = "Seçilmiş səhifələri ixrac et"
|
||||
toggleAnnotations = "Annotasiyaların görünməsini dəyiş"
|
||||
annotationMode = "Annotasiya rejimini dəyiş"
|
||||
print = "PDF-i çap et"
|
||||
draw = "Rəsm çək"
|
||||
save = "Yadda saxla"
|
||||
saveChanges = "Dəyişiklikləri yadda saxla"
|
||||
@@ -4430,7 +4410,7 @@ description = "Daha geniş sistem müvəqqəti qovluğunu təmizləyib-təmizlə
|
||||
label = "Proses İcraedicisi Limitləri"
|
||||
description = "Hər icraedici üçün sessiya limitlərini və taym-outları konfiqurasiya edin"
|
||||
libreOffice = "LibreOffice"
|
||||
pdfToHtml = "PDF-dən HTML-ə"
|
||||
pdfToHtml = "PDF to HTML"
|
||||
qpdf = "QPDF"
|
||||
tesseract = "Tesseract OCR"
|
||||
pythonOpenCv = "Python OpenCV"
|
||||
@@ -4517,7 +4497,6 @@ description = "Impressum üçün URL və ya fayl adı (bəzi yurisdiksiyalarda t
|
||||
title = "Premium və Enterprise"
|
||||
description = "Premium və ya enterprise lisenziya açarınızı konfiqurasiya edin."
|
||||
license = "Lisenziya Konfiqurasiyası"
|
||||
noInput = "Zəhmət olmasa lisenziya açarı və ya fayl təqdim edin"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Lisenziya açarınız və ya sertifikat faylınız var?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Cari lisenziya açarının üzərinə yazmaq geri alına bilməz."
|
||||
line2 = "Ehtiyat nüsxəsi yoxdursa, əvvəlki lisenziyanız birdəfəlik itəcək."
|
||||
line3 = "Vacibdir: Lisenziya açarlarını məxfi və təhlükəsiz saxlayın. Heç vaxt onları ictimai paylaşmayın."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Lisenziya açarı"
|
||||
file = "Sertifikat faylı"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Lisenziya sertifikat faylı"
|
||||
description = "Oflayn alışdan əldə etdiyiniz .lic və ya .cert lisenziya faylını yükləyin"
|
||||
choose = "Lisenziya faylını seçin"
|
||||
selected = "Seçildi: {{filename}} ({{size}})"
|
||||
successMessage = "Lisenziya faylı uğurla yüklənib və aktivləşdirilib. Yenidən başlatmağa ehtiyac yoxdur."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Aktiv lisenziya"
|
||||
file = "Mənbə: Lisenziya faylı ({{path}})"
|
||||
key = "Mənbə: Lisenziya açarı"
|
||||
type = "Növ: {{type}}"
|
||||
noInput = "Zəhmət olmasa lisenziya açarı verin və ya sertifikat faylı yükləyin"
|
||||
success = "Uğurlu"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Premium Xüsusiyyətlərini aktiv et"
|
||||
description = "Pro/enterprise xüsusiyyətləri üçün lisenziya açarı yoxlamalarını aktiv et"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} seçildi"
|
||||
download = "Endir"
|
||||
delete = "Sil"
|
||||
unsupported = "Dəstəklənmir"
|
||||
active = "Aktiv"
|
||||
addToUpload = "Yükləməyə əlavə et"
|
||||
closeFile = "Faylı bağla"
|
||||
deleteAll = "Hamısını sil"
|
||||
loadingFiles = "Fayllar yüklənir..."
|
||||
noFiles = "Fayl mövcud deyil"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Ən azı bir e-poçt ünvanı tələb olunur"
|
||||
submit = "Dəvətnamələri göndər"
|
||||
success = "istifadəçi(lər) uğurla dəvət olundu"
|
||||
partialFailure = "Bəzi dəvətlər uğursuz oldu"
|
||||
partialSuccess = "Bəzi dəvətnamələr alınmadı"
|
||||
allFailed = "İstifadəçiləri dəvət etmək alınmadı"
|
||||
error = "Dəvətnamələri göndərmək alınmadı"
|
||||
|
||||
@@ -5333,8 +5291,8 @@ emailDisabled = "E-poçt dəvətləri üçün ayarlarda SMTP konfiqurasiyası v
|
||||
[workspace.people.license]
|
||||
users = "istifadəçi"
|
||||
availableSlots = "Mövcud yerlər"
|
||||
grandfathered = "Əvvəlki şərtlərlə"
|
||||
grandfatheredShort = "{{count}} əvvəlki şərtlərlə"
|
||||
grandfathered = "Grandfathered"
|
||||
grandfatheredShort = "{{count}} grandfathered"
|
||||
fromLicense = "lisenziyadan"
|
||||
slotsAvailable = "{{count}} istifadəçi yeri mövcuddur"
|
||||
noSlotsAvailable = "Mövcud yer yoxdur"
|
||||
@@ -5842,13 +5800,6 @@ submit = "Daxil ol"
|
||||
signInWith = "Bununla daxil ol"
|
||||
oauthPending = "Təsdiqləmə üçün brauzer açılır..."
|
||||
orContinueWith = "Və ya e-poçt ilə davam edin"
|
||||
serverRequirement = "Qeyd: Serverdə giriş funksiyası aktiv olmalıdır."
|
||||
showInstructions = "Necə aktivləşdirmək olar?"
|
||||
hideInstructions = "Təlimatları gizlət"
|
||||
instructions = "Stirling PDF serverinizdə girişi aktivləşdirmək üçün:"
|
||||
instructionsEnvVar = "Mühit dəyişənini təyin edin:"
|
||||
instructionsOrYml = "Və ya settings.yml faylında:"
|
||||
instructionsRestart = "Dəyişikliklərin qüvvəyə minməsi üçün serveri yenidən başladın."
|
||||
|
||||
[setup.login.username]
|
||||
label = "İstifadəçi adı"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Премахване от любими"
|
||||
fullscreen = "Превключване към режим на цял екран"
|
||||
sidebar = "Превключване към режим със странична лента"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Бекендът не е намерен"
|
||||
retry = "Опитай отново"
|
||||
unreachable = "Приложението в момента не може да се свърже с бекенда. Проверете състоянието на бекенда и мрежовата свързаност, след което опитайте отново."
|
||||
|
||||
[zipWarning]
|
||||
title = "Голям ZIP файл"
|
||||
message = "Този ZIP съдържа {{count}} файла. Да се извлече въпреки това?"
|
||||
@@ -918,8 +913,8 @@ desc = "Наслагва PDF файлове върху друг PDF"
|
||||
title = "Наслагване PDF-и"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Редактор на текст в PDF"
|
||||
desc = "Редактирайте съществуващ текст и изображения в PDF файлове"
|
||||
title = "PDF текстов редактор"
|
||||
desc = "Преглеждайте и редактирайте JSON експорти на Stirling PDF с групово редактиране на текст и повторно генериране на PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "текст,анотация,етикет"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Нарисуван подпис"
|
||||
defaultImageLabel = "Качен подпис"
|
||||
defaultTextLabel = "Въведен подпис"
|
||||
saveButton = "Запази подписа"
|
||||
savePersonal = "Запази като личен"
|
||||
saveShared = "Запази като споделен"
|
||||
saveUnavailable = "Първо създайте подпис, за да го запазите."
|
||||
noChanges = "Текущият подпис вече е запазен."
|
||||
tempStorageTitle = "Временно съхранение в браузъра"
|
||||
tempStorageDescription = "Подписите се съхраняват само във вашия браузър. Ще бъдат загубени, ако изчистите данните на браузъра или смените браузър."
|
||||
personalHeading = "Лични подписи"
|
||||
sharedHeading = "Споделени подписи"
|
||||
personalDescription = "Само вие можете да виждате тези подписи."
|
||||
sharedDescription = "Всички потребители могат да виждат и използват тези подписи."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Рисунка"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Моля впишете се"
|
||||
ssoSignIn = "Влизане чрез еднократно влизане"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Автоматично създаване на потребител е деактивирано"
|
||||
oAuth2AdminBlockedUser = "Регистрацията или влизането на нерегистрирани потребители в момента е блокирано. Моля, свържете се с администратора."
|
||||
oAuth2RequiresLicense = "Вход с OAuth/SSO изисква платен лиценз (Server или Enterprise). Моля, свържете се с администратора, за да надстроите плана си."
|
||||
saml2RequiresLicense = "Вход със SAML изисква платен лиценз (Server или Enterprise). Моля, свържете се с администратора, за да надстроите плана си."
|
||||
maxUsersReached = "Достигнат е максималният брой потребители за текущия ви лиценз. Моля, свържете се с администратора, за да надстроите плана си или да добавите още места."
|
||||
oauth2RequestNotFound = "Заявката за оторизация не е намерена"
|
||||
oauth2InvalidUserInfoResponse = "Невалидна информация за потребителя"
|
||||
oauth2invalidRequest = "Невалидна заявка"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Побиране по ширина"
|
||||
actualSize = "Действителен размер"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Не може да се визуализира файлът"
|
||||
dualPageView = "Изглед: две страници"
|
||||
firstPage = "Първа страница"
|
||||
lastPage = "Последна страница"
|
||||
nextPage = "Следваща страница"
|
||||
onlyPdfSupported = "Прегледачът поддържа само PDF файлове. Този файл изглежда е в друг формат."
|
||||
previousPage = "Предишна страница"
|
||||
singlePageView = "Изглед: една страница"
|
||||
unknownFile = "Непознат файл"
|
||||
nextPage = "Следваща страница"
|
||||
zoomIn = "Увеличи"
|
||||
zoomOut = "Намали"
|
||||
singlePageView = "Изглед: една страница"
|
||||
dualPageView = "Изглед: две страници"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Затвори избраните файлове"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Показване/скриване на страничната
|
||||
exportSelected = "Експорт на избраните страници"
|
||||
toggleAnnotations = "Показване/скриване на анотациите"
|
||||
annotationMode = "Превключи режим на анотации"
|
||||
print = "Печат на PDF"
|
||||
draw = "Рисуване"
|
||||
save = "Запази"
|
||||
saveChanges = "Запази промените"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL или име на файл към импресум (задъ
|
||||
title = "Премиум и Enterprise"
|
||||
description = "Конфигурирайте вашия премиум или enterprise лицензионен ключ."
|
||||
license = "Конфигурация на лиценз"
|
||||
noInput = "Моля, предоставете лицензен ключ или файл"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Имате лицензен ключ или сертификат?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Презаписването на текущия лицензен кл
|
||||
line2 = "Предишният лиценз ще бъде окончателно загубен, освен ако не сте го архивирали другаде."
|
||||
line3 = "Важно: Пазете лицензните ключове поверителни и сигурни. Никога не ги споделяйте публично."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Лицензен ключ"
|
||||
file = "Файл със сертификат"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Файл с лицензен сертификат"
|
||||
description = "Качете вашия .lic или .cert лицензен файл от офлайн покупки"
|
||||
choose = "Изберете лицензен файл"
|
||||
selected = "Избрано: {{filename}} ({{size}})"
|
||||
successMessage = "Лицензният файл беше качен и активиран успешно. Не е необходимо рестартиране."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Активен лиценз"
|
||||
file = "Източник: Лицензен файл ({{path}})"
|
||||
key = "Източник: Лицензен ключ"
|
||||
type = "Тип: {{type}}"
|
||||
noInput = "Моля, предоставете лицензен ключ или качете файл със сертификат"
|
||||
success = "Успешно"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Активирай премиум функции"
|
||||
description = "Активира проверки на лицензионния ключ за pro/enterprise функции"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} избрани"
|
||||
download = "Изтегли"
|
||||
delete = "Изтрий"
|
||||
unsupported = "Неподдържано"
|
||||
active = "Активен"
|
||||
addToUpload = "Добави към качването"
|
||||
closeFile = "Затвори файла"
|
||||
deleteAll = "Изтрий всички"
|
||||
loadingFiles = "Зареждане на файлове..."
|
||||
noFiles = "Няма налични файлове"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Изисква се поне един имейл адрес"
|
||||
submit = "Изпрати покани"
|
||||
success = "Потребител(и) поканени успешно"
|
||||
partialFailure = "Някои покани бяха неуспешни"
|
||||
partialSuccess = "Някои покани не успяха"
|
||||
allFailed = "Неуспешно канене на потребители"
|
||||
error = "Неуспешно изпращане на покани"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "Вход"
|
||||
signInWith = "Вписване с"
|
||||
oauthPending = "Отваряне на браузър за удостоверяване..."
|
||||
orContinueWith = "Или продължете с имейл"
|
||||
serverRequirement = "Забележка: Сървърът трябва да има активиран вход."
|
||||
showInstructions = "Как да се активира?"
|
||||
hideInstructions = "Скрий инструкциите"
|
||||
instructions = "За да активирате вход на вашия Stirling PDF сървър:"
|
||||
instructionsEnvVar = "Задайте променливата на средата:"
|
||||
instructionsOrYml = "Или в settings.yml:"
|
||||
instructionsRestart = "След това рестартирайте сървъра, за да влязат промените в сила."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Потребителско име"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Elimina dels preferits"
|
||||
fullscreen = "Canvia al mode de pantalla completa"
|
||||
sidebar = "Canvia al mode de barra lateral"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend no trobat"
|
||||
retry = "Torneu-ho a intentar"
|
||||
unreachable = "L'aplicació no pot connectar-se al backend ara mateix. Verifiqueu l'estat del backend i la connectivitat de xarxa i torneu-ho a intentar."
|
||||
|
||||
[zipWarning]
|
||||
title = "Fitxer ZIP gran"
|
||||
message = "Aquest ZIP conté {{count}} fitxers. Vols extreure'l igualment?"
|
||||
@@ -919,7 +914,7 @@ title = "Superposar PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Editor de text PDF"
|
||||
desc = "Edita el text i les imatges existents dins dels PDF"
|
||||
desc = "Revisa i edita exportacions JSON de Stirling PDF amb edició de text agrupada i regeneració del PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "text,anotació,etiqueta"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Signatura dibuixada"
|
||||
defaultImageLabel = "Signatura pujada"
|
||||
defaultTextLabel = "Signatura teclejada"
|
||||
saveButton = "Desa la signatura"
|
||||
savePersonal = "Desa com a personal"
|
||||
saveShared = "Desa com a compartida"
|
||||
saveUnavailable = "Crea una signatura primer per poder-la desar."
|
||||
noChanges = "La signatura actual ja està desada."
|
||||
tempStorageTitle = "Emmagatzematge temporal del navegador"
|
||||
tempStorageDescription = "Les signatures només s'emmagatzemen al vostre navegador. Es perdran si netegeu les dades del navegador o canvieu de navegador."
|
||||
personalHeading = "Signatures personals"
|
||||
sharedHeading = "Signatures compartides"
|
||||
personalDescription = "Només vosaltres podeu veure aquestes signatures."
|
||||
sharedDescription = "Tots els usuaris poden veure i utilitzar aquestes signatures."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Dibuix"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Autenticat"
|
||||
ssoSignIn = "Inicia sessió mitjançant inici de sessió únic"
|
||||
oAuth2AutoCreateDisabled = "La creació automàtica d'usuaris OAUTH2 està desactivada"
|
||||
oAuth2AdminBlockedUser = "El registre o inici de sessió d'usuaris no registrats està actualment bloquejat. Si us plau, contacta amb l'administrador."
|
||||
oAuth2RequiresLicense = "L'inici de sessió OAuth/SSO requereix una llicència de pagament (Server o Enterprise). Poseu-vos en contacte amb l'administrador per actualitzar el vostre pla."
|
||||
saml2RequiresLicense = "L'inici de sessió SAML requereix una llicència de pagament (Server o Enterprise). Poseu-vos en contacte amb l'administrador per actualitzar el vostre pla."
|
||||
maxUsersReached = "S'ha assolit el nombre màxim d'usuaris de la vostra llicència actual. Poseu-vos en contacte amb l'administrador per actualitzar el vostre pla o afegir més places."
|
||||
oauth2RequestNotFound = "Sol·licitud d'autorització no trobada"
|
||||
oauth2InvalidUserInfoResponse = "Resposta d'informació d'usuari no vàlida"
|
||||
oauth2invalidRequest = "Sol·licitud no vàlida"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Ajusta a l'amplada"
|
||||
actualSize = "Mida real"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "No es pot previsualitzar el fitxer"
|
||||
dualPageView = "Vista de dues pàgines"
|
||||
firstPage = "Primera pàgina"
|
||||
lastPage = "Última pàgina"
|
||||
nextPage = "Pàgina següent"
|
||||
onlyPdfSupported = "El visualitzador només admet fitxers PDF. Aquest fitxer sembla ser d'un format diferent."
|
||||
previousPage = "Pàgina anterior"
|
||||
singlePageView = "Vista d'una sola pàgina"
|
||||
unknownFile = "Fitxer desconegut"
|
||||
nextPage = "Pàgina següent"
|
||||
zoomIn = "Amplia"
|
||||
zoomOut = "Redueix"
|
||||
singlePageView = "Vista d'una sola pàgina"
|
||||
dualPageView = "Vista de dues pàgines"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Tanca els fitxers seleccionats"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Mostra/oculta la barra lateral"
|
||||
exportSelected = "Exporta les pàgines seleccionades"
|
||||
toggleAnnotations = "Mostra/oculta les anotacions"
|
||||
annotationMode = "Activa/desactiva el mode d'anotació"
|
||||
print = "Imprimeix el PDF"
|
||||
draw = "Dibuixa"
|
||||
save = "Desa"
|
||||
saveChanges = "Desa els canvis"
|
||||
@@ -3948,7 +3928,7 @@ files = "Fitxers"
|
||||
activity = "Registre"
|
||||
help = "Ajuda"
|
||||
account = "Compte"
|
||||
config = "Configuració"
|
||||
config = "Config"
|
||||
settings = "Ajustos"
|
||||
adminSettings = "Ajustos admin"
|
||||
allTools = "All Tools"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL o nom de fitxer de l'impressum (requerit en algunes jurisdicc
|
||||
title = "Premium i Enterprise"
|
||||
description = "Configureu la clau de llicència Premium o Enterprise."
|
||||
license = "Configuració de llicència"
|
||||
noInput = "Proporcioneu una clau de llicència o un fitxer"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Tens una clau de llicència o un fitxer de certificat?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Sobreescriure la clau de llicència actual no es pot desfer."
|
||||
line2 = "La llicència anterior es perdrà permanentment si no en tens una còpia de seguretat."
|
||||
line3 = "Important: mantén les claus de llicència privades i segures. No les comparteixis mai públicament."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Clau de llicència"
|
||||
file = "Fitxer de certificat"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Fitxer de certificat de llicència"
|
||||
description = "Pugeu el vostre fitxer de llicència .lic o .cert de compres fora de línia"
|
||||
choose = "Trieu el fitxer de llicència"
|
||||
selected = "Seleccionat: {{filename}} ({{size}})"
|
||||
successMessage = "Fitxer de llicència pujat i activat correctament. No cal reiniciar."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Llicència activa"
|
||||
file = "Origen: Fitxer de llicència ({{path}})"
|
||||
key = "Origen: Clau de llicència"
|
||||
type = "Tipus: {{type}}"
|
||||
noInput = "Proporcioneu una clau de llicència o pugeu un fitxer de certificat"
|
||||
success = "Èxit"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Habilita les funcions Premium"
|
||||
description = "Habilita les comprovacions de clau per a funcions pro/enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} seleccionats"
|
||||
download = "Descarrega"
|
||||
delete = "Esborra"
|
||||
unsupported = "No compatible"
|
||||
active = "Actiu"
|
||||
addToUpload = "Afegeix a la pujada"
|
||||
closeFile = "Tanca el fitxer"
|
||||
deleteAll = "Suprimeix-ho tot"
|
||||
loadingFiles = "Carregant fitxers..."
|
||||
noFiles = "No hi ha fitxers disponibles"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Cal almenys una adreça de correu"
|
||||
submit = "Envia invitacions"
|
||||
success = "usuari(s) convidat(s) correctament"
|
||||
partialFailure = "Algunes invitacions han fallat"
|
||||
partialSuccess = "Algunes invitacions han fallat"
|
||||
allFailed = "No s’ha pogut convidar els usuaris"
|
||||
error = "No s’han pogut enviar les invitacions"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "Inicia sessió"
|
||||
signInWith = "Inicia sessió amb"
|
||||
oauthPending = "Obrint el navegador per autenticar-te..."
|
||||
orContinueWith = "O continua amb el correu electrònic"
|
||||
serverRequirement = "Nota: el servidor ha de tenir l'inici de sessió habilitat."
|
||||
showInstructions = "Com s'habilita?"
|
||||
hideInstructions = "Amagueu les instruccions"
|
||||
instructions = "Per habilitar l'inici de sessió al vostre servidor de Stirling PDF:"
|
||||
instructionsEnvVar = "Establiu la variable d'entorn:"
|
||||
instructionsOrYml = "O a settings.yml:"
|
||||
instructionsRestart = "A continuació, reinicieu el servidor perquè els canvis tinguin efecte."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Nom d'usuari"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Odebrat z oblíbených"
|
||||
fullscreen = "Přepnout na režim na celou obrazovku"
|
||||
sidebar = "Přepnout na režim postranního panelu"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend nebyl nalezen"
|
||||
retry = "Zkusit znovu"
|
||||
unreachable = "Aplikace se nyní nemůže připojit k backendu. Ověřte stav backendu a síťové připojení a poté to zkuste znovu."
|
||||
|
||||
[zipWarning]
|
||||
title = "Velký soubor ZIP"
|
||||
message = "Tento ZIP obsahuje {{count}} souborů. Přesto rozbalit?"
|
||||
@@ -352,7 +347,7 @@ teams = "Týmy"
|
||||
title = "Konfigurace"
|
||||
systemSettings = "Systémová nastavení"
|
||||
features = "Funkce"
|
||||
endpoints = "Koncové body"
|
||||
endpoints = "Endpoints"
|
||||
database = "Databáze"
|
||||
advanced = "Pokročilé"
|
||||
|
||||
@@ -919,7 +914,7 @@ title = "Překrýt PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Editor textu PDF"
|
||||
desc = "Upravujte existující text a obrázky v PDF"
|
||||
desc = "Prohlížejte a upravujte exporty JSON ze Stirling PDF se skupinovými úpravami textu a regenerací PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "text,anotace,štítek"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Nakreslený podpis"
|
||||
defaultImageLabel = "Nahraný podpis"
|
||||
defaultTextLabel = "Napsaný podpis"
|
||||
saveButton = "Uložit podpis"
|
||||
savePersonal = "Uložit osobní"
|
||||
saveShared = "Uložit sdílené"
|
||||
saveUnavailable = "Nejprve vytvořte podpis, abyste jej mohli uložit."
|
||||
noChanges = "Aktuální podpis je již uložen."
|
||||
tempStorageTitle = "Dočasné úložiště prohlížeče"
|
||||
tempStorageDescription = "Podpisy jsou uloženy pouze ve vašem prohlížeči. Při vymazání dat prohlížeče nebo při přepnutí na jiný prohlížeč budou ztraceny."
|
||||
personalHeading = "Osobní podpisy"
|
||||
sharedHeading = "Sdílené podpisy"
|
||||
personalDescription = "Tyto podpisy vidíte pouze vy."
|
||||
sharedDescription = "Všichni uživatelé mohou tyto podpisy vidět a používat."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Kresba"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Prosím přihlaste se"
|
||||
ssoSignIn = "Přihlásit se přes Single Sign-on"
|
||||
oAuth2AutoCreateDisabled = "Automatické vytváření OAUTH2 uživatelů je zakázáno"
|
||||
oAuth2AdminBlockedUser = "Registrace nebo přihlášení neregistrovaných uživatelů je momentálně blokováno. Kontaktujte prosím správce."
|
||||
oAuth2RequiresLicense = "Přihlášení pomocí OAuth/SSO vyžaduje placenou licenci (Server nebo Enterprise). Kontaktujte prosím administrátora kvůli upgradu vašeho plánu."
|
||||
saml2RequiresLicense = "Přihlášení pomocí SAML vyžaduje placenou licenci (Server nebo Enterprise). Kontaktujte prosím administrátora kvůli upgradu vašeho plánu."
|
||||
maxUsersReached = "Byl dosažen maximální počet uživatelů pro vaši aktuální licenci. Kontaktujte prosím administrátora kvůli upgradu vašeho plánu nebo přidání dalších míst."
|
||||
oauth2RequestNotFound = "Požadavek na autorizaci nebyl nalezen"
|
||||
oauth2InvalidUserInfoResponse = "Neplatná odpověď s informacemi o uživateli"
|
||||
oauth2invalidRequest = "Neplatný požadavek"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Přizpůsobit šířce"
|
||||
actualSize = "Skutečná velikost"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Nelze zobrazit náhled souboru"
|
||||
dualPageView = "Zobrazení dvou stránek"
|
||||
firstPage = "První stránka"
|
||||
lastPage = "Poslední stránka"
|
||||
nextPage = "Další stránka"
|
||||
onlyPdfSupported = "Prohlížeč podporuje pouze soubory PDF. Tento soubor má zřejmě jiný formát."
|
||||
previousPage = "Předchozí stránka"
|
||||
singlePageView = "Zobrazení jedné stránky"
|
||||
unknownFile = "Neznámý soubor"
|
||||
nextPage = "Další stránka"
|
||||
zoomIn = "Přiblížit"
|
||||
zoomOut = "Oddálit"
|
||||
singlePageView = "Zobrazení jedné stránky"
|
||||
dualPageView = "Zobrazení dvou stránek"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Zavřít vybrané soubory"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Přepnout postranní panel"
|
||||
exportSelected = "Exportovat vybrané stránky"
|
||||
toggleAnnotations = "Přepnout viditelnost anotací"
|
||||
annotationMode = "Přepnout režim anotací"
|
||||
print = "Tisk PDF"
|
||||
draw = "Kreslit"
|
||||
save = "Uložit"
|
||||
saveChanges = "Uložit změny"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL nebo název souboru k Impressu (vyžadováno v některých ju
|
||||
title = "Premium a Enterprise"
|
||||
description = "Nakonfigurujte svůj prémiový nebo enterprise licenční klíč."
|
||||
license = "Konfigurace licence"
|
||||
noInput = "Zadejte licenční klíč nebo soubor"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Máte licenční klíč nebo certifikační soubor?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Přepsání aktuálního licenčního klíče nelze vrátit zpět."
|
||||
line2 = "Předchozí licence bude trvale ztracena, pokud ji nemáte zálohovanou jinde."
|
||||
line3 = "Důležité: Uchovávejte licenční klíče v soukromí a v bezpečí. Nikdy je nesdílejte veřejně."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Licenční klíč"
|
||||
file = "Soubor certifikátu"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Soubor licenčního certifikátu"
|
||||
description = "Nahrajte svůj licenční soubor .lic nebo .cert z offline nákupu"
|
||||
choose = "Vybrat licenční soubor"
|
||||
selected = "Vybráno: {{filename}} ({{size}})"
|
||||
successMessage = "Licenční soubor byl úspěšně nahrán a aktivován. Restart není vyžadován."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Aktivní licence"
|
||||
file = "Zdroj: Licenční soubor ({{path}})"
|
||||
key = "Zdroj: Licenční klíč"
|
||||
type = "Typ: {{type}}"
|
||||
noInput = "Zadejte licenční klíč nebo nahrajte soubor certifikátu"
|
||||
success = "Úspěch"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Povolit prémiové funkce"
|
||||
description = "Povolit kontrolu licenčního klíče pro pro/enterprise funkce"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} vybráno"
|
||||
download = "Stáhnout"
|
||||
delete = "Smazat"
|
||||
unsupported = "Nepodporováno"
|
||||
active = "Aktivní"
|
||||
addToUpload = "Přidat k nahrání"
|
||||
closeFile = "Zavřít soubor"
|
||||
deleteAll = "Smazat vše"
|
||||
loadingFiles = "Načítání souborů..."
|
||||
noFiles = "Nejsou k dispozici žádné soubory"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "uzivatel1@priklad.cz, uzivatel2@priklad.cz"
|
||||
emailsRequired = "Je vyžadována alespoň jedna e‑mailová adresa"
|
||||
submit = "Odeslat pozvánky"
|
||||
success = "uživatel(é) úspěšně pozváni"
|
||||
partialFailure = "Některá pozvání selhala"
|
||||
partialSuccess = "Některé pozvánky se nepodařilo odeslat"
|
||||
allFailed = "Nepodařilo se pozvat uživatele"
|
||||
error = "Nepodařilo se odeslat pozvánky"
|
||||
|
||||
@@ -5754,7 +5712,7 @@ title = "Graf využití endpointů"
|
||||
|
||||
[usage.table]
|
||||
title = "Podrobné statistiky"
|
||||
endpoint = "Koncový bod"
|
||||
endpoint = "Endpoint"
|
||||
visits = "Návštěvy"
|
||||
percentage = "Procenta"
|
||||
noData = "Žádná data nejsou k dispozici"
|
||||
@@ -5842,13 +5800,6 @@ submit = "Přihlásit se"
|
||||
signInWith = "Přihlásit se pomocí"
|
||||
oauthPending = "Otevírám prohlížeč pro ověření..."
|
||||
orContinueWith = "Nebo pokračovat e-mailem"
|
||||
serverRequirement = "Poznámka: Na serveru musí být povoleno přihlášení."
|
||||
showInstructions = "Jak povolit?"
|
||||
hideInstructions = "Skrýt pokyny"
|
||||
instructions = "Chcete-li povolit přihlášení na vašem serveru Stirling PDF:"
|
||||
instructionsEnvVar = "Nastavte proměnnou prostředí:"
|
||||
instructionsOrYml = "Nebo v settings.yml:"
|
||||
instructionsRestart = "Poté restartujte server, aby se změny projevily."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Uživatelské jméno"
|
||||
@@ -5892,7 +5843,7 @@ paragraph = "Odstavcová stránka"
|
||||
sparse = "Řídký text"
|
||||
|
||||
[pdfTextEditor.groupingMode]
|
||||
auto = "Automaticky"
|
||||
auto = "Auto"
|
||||
paragraph = "Odstavec"
|
||||
singleLine = "Jeden řádek"
|
||||
|
||||
@@ -5984,13 +5935,13 @@ warnings = "Varování"
|
||||
suggestions = "Poznámky"
|
||||
currentPageFonts = "Fonty na této stránce"
|
||||
allFonts = "Všechny fonty"
|
||||
fallback = "náhradní"
|
||||
fallback = "fallback"
|
||||
missing = "chybí"
|
||||
perfectMessage = "Všechny fonty lze reprodukovat dokonale."
|
||||
warningMessage = "Některé fonty se nemusí vykreslit správně."
|
||||
infoMessage = "K dispozici jsou informace o reprodukci fontů."
|
||||
perfect = "dokonalé"
|
||||
subset = "podmnožina"
|
||||
perfect = "perfect"
|
||||
subset = "subset"
|
||||
|
||||
[pdfTextEditor.errors]
|
||||
invalidJson = "Nelze přečíst soubor JSON. Ujistěte se, že byl vytvořen nástrojem PDF to JSON."
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Fjern fra favoritter"
|
||||
fullscreen = "Skift til fuldskærmstilstand"
|
||||
sidebar = "Skift til sidepanel-tilstand"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend ikke fundet"
|
||||
retry = "Prøv igen"
|
||||
unreachable = "Programmet kan i øjeblikket ikke forbinde til backend. Kontroller backend-status og netværksforbindelse, og prøv igen."
|
||||
|
||||
[zipWarning]
|
||||
title = "Stor ZIP-fil"
|
||||
message = "Denne ZIP indeholder {{count}} filer. Udpak alligevel?"
|
||||
@@ -352,7 +347,7 @@ teams = "Teams"
|
||||
title = "Konfiguration"
|
||||
systemSettings = "Systemindstillinger"
|
||||
features = "Funktioner"
|
||||
endpoints = "Slutpunkter"
|
||||
endpoints = "Endpoints"
|
||||
database = "Database"
|
||||
advanced = "Avanceret"
|
||||
|
||||
@@ -364,7 +359,7 @@ connections = "Forbindelser"
|
||||
[settings.licensingAnalytics]
|
||||
title = "Licensering & Analytics"
|
||||
plan = "Plan"
|
||||
audit = "Revision"
|
||||
audit = "Audit"
|
||||
usageAnalytics = "Brugsanalyse"
|
||||
|
||||
[settings.policiesPrivacy]
|
||||
@@ -561,13 +556,13 @@ totalEndpoints = "Endpoints i alt"
|
||||
totalVisits = "Besøg i alt"
|
||||
showing = "Viser"
|
||||
selectedVisits = "Valgte besøg"
|
||||
endpoint = "Slutpunkt"
|
||||
endpoint = "Endpoint"
|
||||
visits = "Besøg"
|
||||
percentage = "Procent"
|
||||
loading = "Laster..."
|
||||
failedToLoad = "Kunne ikke indlæse endpoint-data. Prøv at opdatere."
|
||||
home = "Hjem"
|
||||
login = "Log ind"
|
||||
login = "Login"
|
||||
top = "Top"
|
||||
numberOfVisits = "Antal besøg"
|
||||
visitsTooltip = "Besøg: {0} ({1}% af totalen)"
|
||||
@@ -919,7 +914,7 @@ title = "Overlejr PDF'er"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF-teksteditor"
|
||||
desc = "Rediger eksisterende tekst og billeder i PDF'er"
|
||||
desc = "Gennemse og rediger Stirling PDF JSON-eksporter med grupperet tekstredigering og regenerering af PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "tekst,annotering,etiket"
|
||||
@@ -1181,7 +1176,7 @@ selectFilesPlaceholder = "Vælg filer i hovedvisningen for at komme i gang"
|
||||
settings = "Indstillinger"
|
||||
conversionCompleted = "Konvertering fuldført"
|
||||
results = "Resultater"
|
||||
defaultFilename = "konverteret_fil"
|
||||
defaultFilename = "converted_file"
|
||||
conversionResults = "Konverteringsresultater"
|
||||
convertFrom = "Konvertér fra"
|
||||
convertTo = "Konvertér til"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Tegnet signatur"
|
||||
defaultImageLabel = "Uploadet signatur"
|
||||
defaultTextLabel = "Indtastet signatur"
|
||||
saveButton = "Gem signatur"
|
||||
savePersonal = "Gem personlig"
|
||||
saveShared = "Gem delt"
|
||||
saveUnavailable = "Opret først en signatur for at gemme den."
|
||||
noChanges = "Nuværende signatur er allerede gemt."
|
||||
tempStorageTitle = "Midlertidig browserlagring"
|
||||
tempStorageDescription = "Signaturer gemmes kun i din browser. De går tabt, hvis du rydder browserdata eller skifter browser."
|
||||
personalHeading = "Personlige signaturer"
|
||||
sharedHeading = "Delte signaturer"
|
||||
personalDescription = "Kun du kan se disse signaturer."
|
||||
sharedDescription = "Alle brugere kan se og bruge disse signaturer."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Tegning"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Log venligst ind"
|
||||
ssoSignIn = "Log ind via Single Sign-on"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Auto-Opret Bruger Deaktiveret"
|
||||
oAuth2AdminBlockedUser = "Registrering eller login af ikke-registrerede brugere er i øjeblikket blokeret. Kontakt venligst administratoren."
|
||||
oAuth2RequiresLicense = "OAuth/SSO-login kræver en betalt licens (Server eller Enterprise). Kontakt administratoren for at opgradere din plan."
|
||||
saml2RequiresLicense = "SAML-login kræver en betalt licens (Server eller Enterprise). Kontakt administratoren for at opgradere din plan."
|
||||
maxUsersReached = "Maksimalt antal brugere er nået for din nuværende licens. Kontakt administratoren for at opgradere din plan eller tilføje flere pladser."
|
||||
oauth2RequestNotFound = "Autorisationsanmodning ikke fundet"
|
||||
oauth2InvalidUserInfoResponse = "Ugyldigt Brugerinfo Svar"
|
||||
oauth2invalidRequest = "Ugyldig Anmodning"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Tilpas til bredde"
|
||||
actualSize = "Faktisk størrelse"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Kan ikke forhåndsvise fil"
|
||||
dualPageView = "To-siders visning"
|
||||
firstPage = "Første side"
|
||||
lastPage = "Sidste side"
|
||||
nextPage = "Næste side"
|
||||
onlyPdfSupported = "Visningen understøtter kun PDF-filer. Denne fil ser ud til at være et andet format."
|
||||
previousPage = "Forrige side"
|
||||
singlePageView = "Enkelt-sides visning"
|
||||
unknownFile = "Ukendt fil"
|
||||
nextPage = "Næste side"
|
||||
zoomIn = "Zoom ind"
|
||||
zoomOut = "Zoom ud"
|
||||
singlePageView = "Enkelt-sides visning"
|
||||
dualPageView = "To-siders visning"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Luk valgte filer"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Skift sidepanel"
|
||||
exportSelected = "Eksporter valgte sider"
|
||||
toggleAnnotations = "Skift visning af annoteringer"
|
||||
annotationMode = "Skift annoteringstilstand"
|
||||
print = "Udskriv PDF"
|
||||
draw = "Tegn"
|
||||
save = "Gem"
|
||||
saveChanges = "Gem ændringer"
|
||||
@@ -4366,7 +4346,7 @@ features = "Funktionsflag"
|
||||
processing = "Behandling"
|
||||
|
||||
[admin.settings.advanced.endpoints]
|
||||
label = "Slutpunkter"
|
||||
label = "Endpoints"
|
||||
manage = "Administrer API-endpoints"
|
||||
description = "Endpointstyring konfigureres via YAML. Se dokumentationen for detaljer om aktivering/deaktivering af specifikke endpoints."
|
||||
|
||||
@@ -4517,7 +4497,6 @@ description = "URL eller filnavn til impressum (påkrævet i nogle jurisdiktione
|
||||
title = "Premium og Enterprise"
|
||||
description = "Konfigurer din premium- eller enterprise-licensnøgle."
|
||||
license = "Licenskonfiguration"
|
||||
noInput = "Angiv en licensnøgle eller fil"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Har du en licensnøgle eller en certifikatfil?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Overskrivning af din nuværende licensnøgle kan ikke fortrydes."
|
||||
line2 = "Din tidligere licens går permanent tabt, medmindre du har sikkerhedskopieret den andetsteds."
|
||||
line3 = "Vigtigt: Hold licensnøgler private og sikre. Del dem aldrig offentligt."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Licensnøgle"
|
||||
file = "Certifikatfil"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Licenscertifikatfil"
|
||||
description = "Upload din .lic- eller .cert-licensfil fra offlinekøb"
|
||||
choose = "Vælg licensfil"
|
||||
selected = "Valgt: {{filename}} ({{size}})"
|
||||
successMessage = "Licensfil uploadet og aktiveret. Genstart er ikke påkrævet."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Aktiv licens"
|
||||
file = "Kilde: Licensfil ({{path}})"
|
||||
key = "Kilde: Licensnøgle"
|
||||
type = "Type: {{type}}"
|
||||
noInput = "Angiv en licensnøgle eller upload en certifikatfil"
|
||||
success = "Succes"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Aktivér premium-funktioner"
|
||||
description = "Aktivér licensnøgletjek for pro-/enterprise-funktioner"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} valgt"
|
||||
download = "Download"
|
||||
delete = "Slet"
|
||||
unsupported = "Ikke understøttet"
|
||||
active = "Aktiv"
|
||||
addToUpload = "Føj til upload"
|
||||
closeFile = "Luk fil"
|
||||
deleteAll = "Slet alle"
|
||||
loadingFiles = "Indlæser filer..."
|
||||
noFiles = "Ingen filer tilgængelige"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Mindst én e-mailadresse er påkrævet"
|
||||
submit = "Send invitationer"
|
||||
success = "Bruger(e) inviteret"
|
||||
partialFailure = "Nogle invitationer mislykkedes"
|
||||
partialSuccess = "Nogle invitationer mislykkedes"
|
||||
allFailed = "Kunne ikke invitere brugere"
|
||||
error = "Kunne ikke sende invitationer"
|
||||
|
||||
@@ -5333,8 +5291,8 @@ emailDisabled = "E-mailinvitationer kræver SMTP-konfiguration og mail.enableInv
|
||||
[workspace.people.license]
|
||||
users = "brugere"
|
||||
availableSlots = "Tilgængelige pladser"
|
||||
grandfathered = "På gamle vilkår"
|
||||
grandfatheredShort = "{{count}} på gamle vilkår"
|
||||
grandfathered = "Grandfathered"
|
||||
grandfatheredShort = "{{count}} grandfathered"
|
||||
fromLicense = "fra licens"
|
||||
slotsAvailable = "{{count}} ledig(e) brugerplads(er)"
|
||||
noSlotsAvailable = "Ingen pladser tilgængelige"
|
||||
@@ -5754,7 +5712,7 @@ title = "Diagram over endpoint-brug"
|
||||
|
||||
[usage.table]
|
||||
title = "Detaljeret statistik"
|
||||
endpoint = "Slutpunkt"
|
||||
endpoint = "Endpoint"
|
||||
visits = "Besøg"
|
||||
percentage = "Procent"
|
||||
noData = "Ingen data tilgængelige"
|
||||
@@ -5797,7 +5755,7 @@ label = "Vælg server"
|
||||
description = "Selvhostet server"
|
||||
|
||||
[setup.step3]
|
||||
label = "Log ind"
|
||||
label = "Login"
|
||||
description = "Indtast loginoplysninger"
|
||||
|
||||
[setup.mode.saas]
|
||||
@@ -5842,13 +5800,6 @@ submit = "Log ind"
|
||||
signInWith = "Log ind med"
|
||||
oauthPending = "Åbner browser for godkendelse..."
|
||||
orContinueWith = "Eller fortsæt med email"
|
||||
serverRequirement = "Bemærk: Serveren skal have login aktiveret."
|
||||
showInstructions = "Hvordan aktiveres det?"
|
||||
hideInstructions = "Skjul instruktioner"
|
||||
instructions = "Sådan aktiverer du login på din Stirling PDF-server:"
|
||||
instructionsEnvVar = "Sæt miljøvariablen:"
|
||||
instructionsOrYml = "Eller i settings.yml:"
|
||||
instructionsRestart = "Genstart derefter serveren, så ændringerne træder i kraft."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Brugernavn"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Aus Favoriten entfernen"
|
||||
fullscreen = "In den Vollbildmodus wechseln"
|
||||
sidebar = "In den Seitenleistenmodus wechseln"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend nicht gefunden"
|
||||
retry = "Erneut versuchen"
|
||||
unreachable = "Die Anwendung kann derzeit keine Verbindung zum Backend herstellen. Überprüfen Sie den Backend-Status und die Netzwerkverbindung und versuchen Sie es dann erneut."
|
||||
|
||||
[zipWarning]
|
||||
title = "Große ZIP-Datei"
|
||||
message = "Dieses ZIP enthält {{count}} Dateien. Trotzdem extrahieren?"
|
||||
@@ -352,7 +347,7 @@ teams = "Teams"
|
||||
title = "Konfiguration"
|
||||
systemSettings = "Systemeinstellungen"
|
||||
features = "Funktionen"
|
||||
endpoints = "Endpunkte"
|
||||
endpoints = "Endpoints"
|
||||
database = "Datenbank"
|
||||
advanced = "Erweitert"
|
||||
|
||||
@@ -388,7 +383,7 @@ logout = "Abmelden"
|
||||
|
||||
[settings.connection.mode]
|
||||
saas = "Stirling Cloud"
|
||||
selfhosted = "Selbst gehostet"
|
||||
selfhosted = "Self-Hosted"
|
||||
|
||||
[settings.general]
|
||||
title = "Allgemein"
|
||||
@@ -617,7 +612,7 @@ desc = "Anzeigen, Kommentieren, Text oder Bilder hinzufügen"
|
||||
brandAlt = "Stirling PDF-Logo"
|
||||
openFiles = "Dateien öffnen"
|
||||
swipeHint = "Zum Wechseln der Ansicht nach links oder rechts wischen"
|
||||
tools = "Werkzeuge"
|
||||
tools = "Tools"
|
||||
toolsSlide = "Bereich für Toolauswahl"
|
||||
viewSwitcher = "Ansicht des Arbeitsbereichs wechseln"
|
||||
workbenchSlide = "Arbeitsbereichs-Panel"
|
||||
@@ -919,10 +914,10 @@ title = "PDFs überlagern"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF-Texteditor"
|
||||
desc = "Vorhandenen Text und Bilder in PDFs bearbeiten"
|
||||
desc = "Stirling PDF JSON-Exporte prüfen und bearbeiten – mit gruppierter Textbearbeitung und PDF-Neuerzeugung"
|
||||
|
||||
[home.addText]
|
||||
tags = "text,anmerkung,beschriftung"
|
||||
tags = "text,annotation,label"
|
||||
title = "Text hinzufügen"
|
||||
desc = "Beliebigen Text überall in Ihrem PDF hinzufügen"
|
||||
|
||||
@@ -1221,7 +1216,7 @@ pdfaDigitalSignatureWarning = "Das PDF enthält eine digitale Signatur. Sie wird
|
||||
fileFormat = "Dateiformat"
|
||||
wordDoc = "Word-Dokument"
|
||||
wordDocExt = "Word-Dokument (.docx)"
|
||||
odtExt = "OpenDocument-Text (.odt)"
|
||||
odtExt = "OpenDocument Text (.odt)"
|
||||
pptExt = "PowerPoint (.pptx)"
|
||||
odpExt = "OpenDocument Präsentation (.odp)"
|
||||
txtExt = "Einfacher Text (.txt)"
|
||||
@@ -2267,20 +2262,12 @@ defaultCanvasLabel = "Gezeichnete Unterschrift"
|
||||
defaultImageLabel = "Hochgeladene Unterschrift"
|
||||
defaultTextLabel = "Getippte Unterschrift"
|
||||
saveButton = "Unterschrift speichern"
|
||||
savePersonal = "Persönlich speichern"
|
||||
saveShared = "Geteilt speichern"
|
||||
saveUnavailable = "Erstellen Sie zuerst eine Unterschrift, um sie zu speichern."
|
||||
noChanges = "Die aktuelle Unterschrift ist bereits gespeichert."
|
||||
tempStorageTitle = "Temporärer Browser-Speicher"
|
||||
tempStorageDescription = "Signaturen werden nur in Ihrem Browser gespeichert. Sie gehen verloren, wenn Sie Browserdaten löschen oder den Browser wechseln."
|
||||
personalHeading = "Persönliche Signaturen"
|
||||
sharedHeading = "Geteilte Signaturen"
|
||||
personalDescription = "Nur Sie können diese Signaturen sehen."
|
||||
sharedDescription = "Alle Benutzer können diese Signaturen sehen und verwenden."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Zeichnung"
|
||||
image = "Hochladen"
|
||||
image = "Upload"
|
||||
text = "Text"
|
||||
|
||||
[sign.saved.status]
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Bitte melden Sie sich an."
|
||||
ssoSignIn = "Anmeldung per Single Sign-On"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Benutzer automatisch erstellen deaktiviert"
|
||||
oAuth2AdminBlockedUser = "Die Registrierung bzw. das anmelden von nicht registrierten Benutzern ist derzeit gesperrt. Bitte wenden Sie sich an den Administrator."
|
||||
oAuth2RequiresLicense = "OAuth/SSO-Anmeldung erfordert eine kostenpflichtige Lizenz (Server oder Enterprise). Bitte wenden Sie sich an den Administrator, um Ihren Plan zu aktualisieren."
|
||||
saml2RequiresLicense = "SAML-Anmeldung erfordert eine kostenpflichtige Lizenz (Server oder Enterprise). Bitte wenden Sie sich an den Administrator, um Ihren Plan zu aktualisieren."
|
||||
maxUsersReached = "Die maximale Benutzeranzahl für Ihre aktuelle Lizenz wurde erreicht. Bitte wenden Sie sich an den Administrator, um Ihren Plan zu aktualisieren oder weitere Benutzerplätze hinzuzufügen."
|
||||
oauth2RequestNotFound = "Autorisierungsanfrage nicht gefunden"
|
||||
oauth2InvalidUserInfoResponse = "Ungültige Benutzerinformationsantwort"
|
||||
oauth2invalidRequest = "ungültige Anfrage"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "An Breite anpassen"
|
||||
actualSize = "Originalgröße"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Datei kann nicht in der Vorschau angezeigt werden"
|
||||
dualPageView = "Doppelseitenansicht"
|
||||
firstPage = "Erste Seite"
|
||||
lastPage = "Letzte Seite"
|
||||
nextPage = "Nächste Seite"
|
||||
onlyPdfSupported = "Der Viewer unterstützt nur PDF-Dateien. Diese Datei scheint ein anderes Format zu haben."
|
||||
previousPage = "Vorherige Seite"
|
||||
singlePageView = "Einzelseitenansicht"
|
||||
unknownFile = "Unbekannte Datei"
|
||||
nextPage = "Nächste Seite"
|
||||
zoomIn = "Vergrößern"
|
||||
zoomOut = "Verkleinern"
|
||||
singlePageView = "Einzelseitenansicht"
|
||||
dualPageView = "Doppelseitenansicht"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Ausgewählte Dateien schließen"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Seitenleiste umschalten"
|
||||
exportSelected = "Ausgewählte Seiten exportieren"
|
||||
toggleAnnotations = "Anmerkungen ein-/ausblenden"
|
||||
annotationMode = "Anmerkungsmodus umschalten"
|
||||
print = "PDF drucken"
|
||||
draw = "Zeichnen"
|
||||
save = "Speichern"
|
||||
saveChanges = "Änderungen speichern"
|
||||
@@ -3951,7 +3931,7 @@ account = "Konto"
|
||||
config = "Konfig"
|
||||
settings = "Optionen"
|
||||
adminSettings = "Admin Optionen"
|
||||
allTools = "Werkzeuge"
|
||||
allTools = "Tools"
|
||||
reader = "Reader"
|
||||
|
||||
[quickAccess.helpMenu]
|
||||
@@ -4517,7 +4497,6 @@ description = "URL oder Dateiname zum Impressum (in einigen Rechtsordnungen erfo
|
||||
title = "Premium & Enterprise"
|
||||
description = "Ihren Premium- oder Enterprise-Lizenzschlüssel konfigurieren."
|
||||
license = "Lizenzkonfiguration"
|
||||
noInput = "Bitte geben Sie einen Lizenzschlüssel oder eine Datei an"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Lizenzschlüssel oder Zertifikatsdatei vorhanden?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Das Überschreiben Ihres aktuellen Lizenzschlüssels kann nicht rückg
|
||||
line2 = "Ihre vorherige Lizenz geht dauerhaft verloren, sofern Sie sie nicht anderweitig gesichert haben."
|
||||
line3 = "Wichtig: Halten Sie Lizenzschlüssel privat und sicher. Geben Sie sie niemals öffentlich weiter."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Lizenzschlüssel"
|
||||
file = "Zertifikatsdatei"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Lizenz-Zertifikatsdatei"
|
||||
description = "Laden Sie Ihre .lic- oder .cert-Lizenzdatei aus Offline-Käufen hoch"
|
||||
choose = "Lizenzdatei auswählen"
|
||||
selected = "Ausgewählt: {{filename}} ({{size}})"
|
||||
successMessage = "Lizenzdatei erfolgreich hochgeladen und aktiviert. Kein Neustart erforderlich."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Aktive Lizenz"
|
||||
file = "Quelle: Lizenzdatei ({{path}})"
|
||||
key = "Quelle: Lizenzschlüssel"
|
||||
type = "Typ: {{type}}"
|
||||
noInput = "Bitte geben Sie einen Lizenzschlüssel an oder laden Sie eine Zertifikatdatei hoch"
|
||||
success = "Erfolg"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Premium-Funktionen aktivieren"
|
||||
description = "Lizenzschlüssel-Prüfungen für Pro-/Enterprise-Funktionen aktivieren"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} ausgewählt"
|
||||
download = "Herunterladen"
|
||||
delete = "Löschen"
|
||||
unsupported = "Nicht unterstützt"
|
||||
active = "Aktiv"
|
||||
addToUpload = "Zum Upload hinzufügen"
|
||||
closeFile = "Datei schließen"
|
||||
deleteAll = "Alle löschen"
|
||||
loadingFiles = "Dateien werden geladen..."
|
||||
noFiles = "Keine Dateien verfügbar"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Mindestens eine E-Mail-Adresse ist erforderlich"
|
||||
submit = "Einladungen senden"
|
||||
success = "Benutzer erfolgreich eingeladen"
|
||||
partialFailure = "Einige Einladungen sind fehlgeschlagen"
|
||||
partialSuccess = "Einige Einladungen sind fehlgeschlagen"
|
||||
allFailed = "Benutzer konnten nicht eingeladen werden"
|
||||
error = "Einladungen konnten nicht gesendet werden"
|
||||
|
||||
@@ -5797,7 +5755,7 @@ label = "Server auswählen"
|
||||
description = "Self-Hosted-Server"
|
||||
|
||||
[setup.step3]
|
||||
label = "Anmeldung"
|
||||
label = "Login"
|
||||
description = "Anmeldedaten eingeben"
|
||||
|
||||
[setup.mode.saas]
|
||||
@@ -5838,17 +5796,10 @@ testFailed = "Verbindungstest fehlgeschlagen"
|
||||
title = "Anmelden"
|
||||
subtitle = "Geben Sie Ihre Anmeldedaten ein, um fortzufahren"
|
||||
connectingTo = "Verbinden mit:"
|
||||
submit = "Anmelden"
|
||||
submit = "Login"
|
||||
signInWith = "Anmelden mit"
|
||||
oauthPending = "Browser zur Authentifizierung wird geöffnet..."
|
||||
orContinueWith = "Oder mit E-Mail fortfahren"
|
||||
serverRequirement = "Hinweis: Auf dem Server muss die Anmeldung aktiviert sein."
|
||||
showInstructions = "Wie aktivieren?"
|
||||
hideInstructions = "Anleitung ausblenden"
|
||||
instructions = "So aktivieren Sie die Anmeldung auf Ihrem Stirling PDF-Server:"
|
||||
instructionsEnvVar = "Setzen Sie die Umgebungsvariable:"
|
||||
instructionsOrYml = "Oder in der settings.yml:"
|
||||
instructionsRestart = "Starten Sie anschließend Ihren Server neu, damit die Änderungen wirksam werden."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Benutzername"
|
||||
@@ -5899,7 +5850,7 @@ singleLine = "Einzeilig"
|
||||
[pdfTextEditor.badges]
|
||||
unsaved = "Bearbeitet"
|
||||
modified = "Bearbeitet"
|
||||
earlyAccess = "Früher Zugriff"
|
||||
earlyAccess = "Early Access"
|
||||
|
||||
[pdfTextEditor.actions]
|
||||
reset = "Änderungen zurücksetzen"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Αφαίρεση από τα Αγαπημένα"
|
||||
fullscreen = "Μετάβαση σε λειτουργία πλήρους οθόνης"
|
||||
sidebar = "Μετάβαση σε λειτουργία πλευρικής γραμμής"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Το backend δεν βρέθηκε"
|
||||
retry = "Επανάληψη"
|
||||
unreachable = "Η εφαρμογή δεν μπορεί προς το παρόν να συνδεθεί με το backend. Ελέγξτε την κατάσταση του backend και τη συνδεσιμότητα δικτύου, μετά δοκιμάστε ξανά."
|
||||
|
||||
[zipWarning]
|
||||
title = "Μεγάλο αρχείο ZIP"
|
||||
message = "Αυτό το ZIP περιέχει {{count}} αρχεία. Να γίνει αποσυμπίεση ούτως ή άλλως;"
|
||||
@@ -292,7 +287,7 @@ help = "Βοήθεια Pipeline"
|
||||
scanHelp = "Βοήθεια σάρωσης φακέλων"
|
||||
deletePrompt = "Είστε βέβαιοι ότι θέλετε να διαγράψετε το pipeline;"
|
||||
tags = "αυτοματοποίηση,ακολουθία,προγραμματισμένο,επεξεργασία-παρτίδας"
|
||||
title = "Ροή"
|
||||
title = "Pipeline"
|
||||
|
||||
[pipelineOptions]
|
||||
header = "Διαμόρφωση Pipeline"
|
||||
@@ -301,7 +296,7 @@ saveSettings = "Αποθήκευση ρυθμίσεων λειτουργίας"
|
||||
pipelineNamePrompt = "Εισάγετε όνομα pipeline εδώ"
|
||||
selectOperation = "Επιλογή λειτουργίας"
|
||||
addOperationButton = "Προσθήκη λειτουργίας"
|
||||
pipelineHeader = "Ροή:"
|
||||
pipelineHeader = "Pipeline:"
|
||||
saveButton = "Λήψη"
|
||||
validateButton = "Επικύρωση"
|
||||
|
||||
@@ -352,7 +347,7 @@ teams = "Ομάδες"
|
||||
title = "Διαμόρφωση"
|
||||
systemSettings = "Ρυθμίσεις συστήματος"
|
||||
features = "Δυνατότητες"
|
||||
endpoints = "Σημεία τερματισμού"
|
||||
endpoints = "Endpoints"
|
||||
database = "Βάση δεδομένων"
|
||||
advanced = "Προχωρημένα"
|
||||
|
||||
@@ -374,7 +369,7 @@ privacy = "Απόρρητο"
|
||||
|
||||
[settings.developer]
|
||||
title = "Προγραμματιστής"
|
||||
apiKeys = "Κλειδιά API"
|
||||
apiKeys = "API Keys"
|
||||
|
||||
[settings.tooltips]
|
||||
enableLoginFirst = "Ενεργοποιήστε πρώτα τη λειτουργία σύνδεσης"
|
||||
@@ -388,7 +383,7 @@ logout = "Αποσύνδεση"
|
||||
|
||||
[settings.connection.mode]
|
||||
saas = "Stirling Cloud"
|
||||
selfhosted = "Αυτο-φιλοξενούμενο"
|
||||
selfhosted = "Self-Hosted"
|
||||
|
||||
[settings.general]
|
||||
title = "Γενικά"
|
||||
@@ -919,7 +914,7 @@ title = "Επικάλυψη PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Επεξεργαστής κειμένου PDF"
|
||||
desc = "Επεξεργαστείτε υπάρχον κείμενο και εικόνες μέσα σε αρχεία PDF"
|
||||
desc = "Επιθεωρήστε και επεξεργαστείτε εξαγωγές JSON του Stirling PDF με ομαδοποιημένη επεξεργασία κειμένου και αναδημιουργία PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "κείμενο,σχολιασμός,ετικέτα"
|
||||
@@ -1181,7 +1176,7 @@ selectFilesPlaceholder = "Επιλέξτε αρχεία στην κύρια πρ
|
||||
settings = "Ρυθμίσεις"
|
||||
conversionCompleted = "Η μετατροπή ολοκληρώθηκε"
|
||||
results = "Αποτελέσματα"
|
||||
defaultFilename = "μετατραπμένο_αρχείο"
|
||||
defaultFilename = "converted_file"
|
||||
conversionResults = "Αποτελέσματα μετατροπής"
|
||||
convertFrom = "Μετατροπή από"
|
||||
convertTo = "Μετατροπή σε"
|
||||
@@ -1368,7 +1363,7 @@ title = "Προσθήκη υδατογραφήματος"
|
||||
desc = "Προσθέστε υδατογραφήματα κειμένου ή εικόνας σε αρχεία PDF"
|
||||
completed = "Το υδατογράφημα προστέθηκε"
|
||||
submit = "Προσθήκη υδατογραφήματος"
|
||||
filenamePrefix = "υδατογραφημένο"
|
||||
filenamePrefix = "watermarked"
|
||||
|
||||
[watermark.error]
|
||||
failed = "Παρουσιάστηκε σφάλμα κατά την προσθήκη υδατογραφήματος στο PDF."
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Σχεδιασμένη υπογραφή"
|
||||
defaultImageLabel = "Ανεβασμένη υπογραφή"
|
||||
defaultTextLabel = "Πληκτρολογημένη υπογραφή"
|
||||
saveButton = "Αποθήκευση υπογραφής"
|
||||
savePersonal = "Αποθήκευση ως Προσωπική"
|
||||
saveShared = "Αποθήκευση ως Κοινόχρηστη"
|
||||
saveUnavailable = "Δημιουργήστε πρώτα μια υπογραφή για να την αποθηκεύσετε."
|
||||
noChanges = "Η τρέχουσα υπογραφή είναι ήδη αποθηκευμένη."
|
||||
tempStorageTitle = "Προσωρινή αποθήκευση στον περιηγητή"
|
||||
tempStorageDescription = "Οι υπογραφές αποθηκεύονται μόνο στον περιηγητή σας. Θα χαθούν αν καθαρίσετε τα δεδομένα του περιηγητή ή αλλάξετε περιηγητή."
|
||||
personalHeading = "Προσωπικές υπογραφές"
|
||||
sharedHeading = "Κοινόχρηστες υπογραφές"
|
||||
personalDescription = "Μόνο εσείς μπορείτε να δείτε αυτές τις υπογραφές."
|
||||
sharedDescription = "Όλοι οι χρήστες μπορούν να βλέπουν και να χρησιμοποιούν αυτές τις υπογραφές."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Σχέδιο"
|
||||
@@ -2717,7 +2704,7 @@ header = "Αφαίρεση της ψηφιακής υπογραφής από τ
|
||||
selectPDF = "Επιλέξτε ένα αρχείο PDF:"
|
||||
submit = "Αφαίρεση υπογραφής"
|
||||
description = "Αυτό το εργαλείο θα αφαιρέσει τις υπογραφές ψηφιακού πιστοποιητικού από το PDF σας."
|
||||
filenamePrefix = "ανυπόγραφο"
|
||||
filenamePrefix = "unsigned"
|
||||
|
||||
[removeCertSign.files]
|
||||
placeholder = "Επιλέξτε ένα αρχείο PDF στην κύρια προβολή για να ξεκινήσετε"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Παρακαλώ συνδεθείτε"
|
||||
ssoSignIn = "Σύνδεση μέσω Single Sign-on"
|
||||
oAuth2AutoCreateDisabled = "Η αυτόματη δημιουργία χρήστη OAUTH2 είναι απενεργοποιημένη"
|
||||
oAuth2AdminBlockedUser = "Η εγγραφή ή σύνδεση μη εγγεγραμμένων χρηστών είναι προς το παρόν αποκλεισμένη. Παρακαλώ επικοινωνήστε με τον διαχειριστή."
|
||||
oAuth2RequiresLicense = "Η σύνδεση μέσω OAuth/SSO απαιτεί επί πληρωμή άδεια (Server ή Enterprise). Παρακαλούμε επικοινωνήστε με τον διαχειριστή για να αναβαθμίσετε το πλάνο σας."
|
||||
saml2RequiresLicense = "Η σύνδεση μέσω SAML απαιτεί επί πληρωμή άδεια (Server ή Enterprise). Παρακαλούμε επικοινωνήστε με τον διαχειριστή για να αναβαθμίσετε το πλάνο σας."
|
||||
maxUsersReached = "Έχει επιτευχθεί ο μέγιστος αριθμός χρηστών για την τρέχουσα άδειά σας. Παρακαλούμε επικοινωνήστε με τον διαχειριστή για να αναβαθμίσετε το πλάνο σας ή να προσθέσετε περισσότερες θέσεις."
|
||||
oauth2RequestNotFound = "Το αίτημα εξουσιοδότησης δεν βρέθηκε"
|
||||
oauth2InvalidUserInfoResponse = "Μη έγκυρη απόκριση πληροφοριών χρήστη"
|
||||
oauth2invalidRequest = "Μη έγκυρο αίτημα"
|
||||
@@ -3552,7 +3536,7 @@ title = "PDF σε μία σελίδα"
|
||||
header = "PDF σε μία σελίδα"
|
||||
submit = "Μετατροπή σε μία σελίδα"
|
||||
description = "Αυτό το εργαλείο θα συγχωνεύσει όλες τις σελίδες του PDF σας σε μία μεγάλη ενιαία σελίδα. Το πλάτος θα παραμείνει ίδιο με των αρχικών σελίδων, αλλά το ύψος θα είναι το άθροισμα όλων των υψών."
|
||||
filenamePrefix = "μονοσέλιδο"
|
||||
filenamePrefix = "single_page"
|
||||
|
||||
[pdfToSinglePage.files]
|
||||
placeholder = "Επιλέξτε ένα αρχείο PDF στην κύρια προβολή για να ξεκινήσετε"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Προσαρμογή στο πλάτος"
|
||||
actualSize = "Πραγματικό μέγεθος"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Δεν είναι δυνατή η προεπισκόπηση του αρχείου"
|
||||
dualPageView = "Προβολή διπλής σελίδας"
|
||||
firstPage = "Πρώτη σελίδα"
|
||||
lastPage = "Τελευταία σελίδα"
|
||||
nextPage = "Επόμενη σελίδα"
|
||||
onlyPdfSupported = "Ο προβολέας υποστηρίζει μόνο αρχεία PDF. Αυτό το αρχείο φαίνεται να είναι διαφορετικής μορφής."
|
||||
previousPage = "Προηγούμενη σελίδα"
|
||||
singlePageView = "Προβολή μίας σελίδας"
|
||||
unknownFile = "Άγνωστο αρχείο"
|
||||
nextPage = "Επόμενη σελίδα"
|
||||
zoomIn = "Μεγέθυνση"
|
||||
zoomOut = "Σμίκρυνση"
|
||||
singlePageView = "Προβολή μίας σελίδας"
|
||||
dualPageView = "Προβολή διπλής σελίδας"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Κλείσιμο επιλεγμένων αρχείων"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Εναλλαγή πλευρικής γραμμής"
|
||||
exportSelected = "Εξαγωγή επιλεγμένων σελίδων"
|
||||
toggleAnnotations = "Εναλλαγή ορατότητας σχολιασμών"
|
||||
annotationMode = "Εναλλαγή λειτουργίας σχολιασμού"
|
||||
print = "Εκτύπωση PDF"
|
||||
draw = "Σχεδίαση"
|
||||
save = "Αποθήκευση"
|
||||
saveChanges = "Αποθήκευση αλλαγών"
|
||||
@@ -4258,11 +4238,11 @@ label = "URL εκδότη"
|
||||
description = "Το URL εκδότη του παρόχου OAuth2"
|
||||
|
||||
[admin.settings.connections.oauth2.clientId]
|
||||
label = "Αναγνωριστικό πελάτη (Client ID)"
|
||||
label = "Client ID"
|
||||
description = "Το Client ID OAuth2 από τον πάροχό σας"
|
||||
|
||||
[admin.settings.connections.oauth2.clientSecret]
|
||||
label = "Μυστικό πελάτη (Client Secret)"
|
||||
label = "Client Secret"
|
||||
description = "Το Client Secret OAuth2 από τον πάροχό σας"
|
||||
|
||||
[admin.settings.connections.oauth2.useAsUsername]
|
||||
@@ -4517,7 +4497,6 @@ description = "URL ή όνομα αρχείου για το impressum (απαι
|
||||
title = "Premium & Enterprise"
|
||||
description = "Ρυθμίστε το κλειδί άδειας premium ή enterprise."
|
||||
license = "Διαμόρφωση άδειας"
|
||||
noInput = "Παρακαλώ δώστε ένα κλειδί άδειας ή αρχείο"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Έχετε κλειδί άδειας ή αρχείο πιστοποιητικού;"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Η αντικατάσταση του τρέχοντος κλειδιο
|
||||
line2 = "Η προηγούμενη άδεια θα χαθεί οριστικά εκτός αν την έχετε αποθηκεύσει αλλού."
|
||||
line3 = "Σημαντικό: Κρατήστε τα κλειδιά άδειας ιδιωτικά και ασφαλή. Μην τα κοινοποιείτε δημόσια."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Κλειδί άδειας"
|
||||
file = "Αρχείο πιστοποιητικού"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Αρχείο πιστοποιητικού άδειας"
|
||||
description = "Μεταφορτώστε το αρχείο άδειας .lic ή .cert από αγορές εκτός σύνδεσης"
|
||||
choose = "Επιλέξτε αρχείο άδειας"
|
||||
selected = "Επιλεγμένο: {{filename}} ({{size}})"
|
||||
successMessage = "Το αρχείο άδειας μεταφορτώθηκε και ενεργοποιήθηκε με επιτυχία. Δεν απαιτείται επανεκκίνηση."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Ενεργή άδεια"
|
||||
file = "Πηγή: Αρχείο άδειας ({{path}})"
|
||||
key = "Πηγή: Κλειδί άδειας"
|
||||
type = "Τύπος: {{type}}"
|
||||
noInput = "Παρακαλώ δώστε ένα κλειδί άδειας ή μεταφορτώστε ένα αρχείο πιστοποιητικού"
|
||||
success = "Επιτυχία"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Ενεργοποίηση λειτουργιών premium"
|
||||
description = "Ενεργοποίηση ελέγχων κλειδιού άδειας για λειτουργίες pro/enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} επιλεγμένα"
|
||||
download = "Λήψη"
|
||||
delete = "Διαγραφή"
|
||||
unsupported = "Μη υποστηριζόμενο"
|
||||
active = "Ενεργό"
|
||||
addToUpload = "Προσθήκη στη μεταφόρτωση"
|
||||
closeFile = "Κλείσιμο αρχείου"
|
||||
deleteAll = "Διαγραφή όλων"
|
||||
loadingFiles = "Φόρτωση αρχείων..."
|
||||
noFiles = "Δεν υπάρχουν διαθέσιμα αρχεία"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Απαιτείται τουλάχιστον μία διεύθυνση email"
|
||||
submit = "Αποστολή προσκλήσεων"
|
||||
success = "στάλθηκαν προσκλήσεις με επιτυχία"
|
||||
partialFailure = "Ορισμένες προσκλήσεις απέτυχαν"
|
||||
partialSuccess = "Κάποιες προσκλήσεις απέτυχαν"
|
||||
allFailed = "Αποτυχία πρόσκλησης χρηστών"
|
||||
error = "Αποτυχία αποστολής προσκλήσεων"
|
||||
|
||||
@@ -5754,7 +5712,7 @@ title = "Διάγραμμα χρήσης Endpoints"
|
||||
|
||||
[usage.table]
|
||||
title = "Αναλυτικά στατιστικά"
|
||||
endpoint = "Σημείο τερματισμού"
|
||||
endpoint = "Endpoint"
|
||||
visits = "Επισκέψεις"
|
||||
percentage = "Ποσοστό"
|
||||
noData = "Δεν υπάρχουν διαθέσιμα δεδομένα"
|
||||
@@ -5842,13 +5800,6 @@ submit = "Σύνδεση"
|
||||
signInWith = "Σύνδεση με"
|
||||
oauthPending = "Άνοιγμα προγράμματος περιήγησης για έλεγχο ταυτότητας..."
|
||||
orContinueWith = "Ή συνεχίστε με email"
|
||||
serverRequirement = "Σημείωση: Ο διακομιστής πρέπει να έχει ενεργοποιημένη τη σύνδεση."
|
||||
showInstructions = "Πώς ενεργοποιείται;"
|
||||
hideInstructions = "Απόκρυψη οδηγιών"
|
||||
instructions = "Για να ενεργοποιήσετε τη σύνδεση στον διακομιστή Stirling PDF:"
|
||||
instructionsEnvVar = "Ορίστε τη μεταβλητή περιβάλλοντος:"
|
||||
instructionsOrYml = "Ή στο settings.yml:"
|
||||
instructionsRestart = "Στη συνέχεια, επανεκκινήστε τον διακομιστή σας για να εφαρμοστούν οι αλλαγές."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Όνομα χρήστη"
|
||||
|
||||
@@ -919,7 +919,7 @@ title = "Overlay PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF Text Editor"
|
||||
desc = "Edit existing text and images inside PDFs"
|
||||
desc = "Review and edit Stirling PDF JSON exports with grouped text editing and PDF regeneration"
|
||||
|
||||
[home.addText]
|
||||
tags = "text,annotation,label"
|
||||
@@ -2267,16 +2267,8 @@ defaultCanvasLabel = "Drawing signature"
|
||||
defaultImageLabel = "Uploaded signature"
|
||||
defaultTextLabel = "Typed signature"
|
||||
saveButton = "Save signature"
|
||||
savePersonal = "Save Personal"
|
||||
saveShared = "Save Shared"
|
||||
saveUnavailable = "Create a signature first to save it."
|
||||
noChanges = "Current signature is already saved."
|
||||
tempStorageTitle = "Temporary browser storage"
|
||||
tempStorageDescription = "Signatures are stored in your browser only. They will be lost if you clear browser data or switch browsers."
|
||||
personalHeading = "Personal Signatures"
|
||||
sharedHeading = "Shared Signatures"
|
||||
personalDescription = "Only you can see these signatures."
|
||||
sharedDescription = "All users can see and use these signatures."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Drawing"
|
||||
@@ -3454,8 +3446,8 @@ signinTitle = "Please sign in"
|
||||
ssoSignIn = "Login via Single Sign-on"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Auto-Create User Disabled"
|
||||
oAuth2AdminBlockedUser = "Registration or logging in of non-registered users is currently blocked. Please contact the administrator."
|
||||
oAuth2RequiresLicense = "OAuth/SSO login requires a Server or Enterprise license. Please contact the administrator to upgrade your plan."
|
||||
saml2RequiresLicense = "SAML login requires an Enterprise license. Please contact the administrator to upgrade your plan."
|
||||
oAuth2RequiresLicense = "OAuth/SSO login requires a paid license (Server or Enterprise). Please contact the administrator to upgrade your plan."
|
||||
saml2RequiresLicense = "SAML login requires a paid license (Server or Enterprise). Please contact the administrator to upgrade your plan."
|
||||
maxUsersReached = "Maximum number of users reached for your current license. Please contact the administrator to upgrade your plan or add more seats."
|
||||
oauth2RequestNotFound = "Authorization request not found"
|
||||
oauth2InvalidUserInfoResponse = "Invalid User Info Response"
|
||||
@@ -3899,7 +3891,6 @@ toggleSidebar = "Toggle Sidebar"
|
||||
exportSelected = "Export Selected Pages"
|
||||
toggleAnnotations = "Toggle Annotations Visibility"
|
||||
annotationMode = "Toggle Annotation Mode"
|
||||
print = "Print PDF"
|
||||
draw = "Draw"
|
||||
save = "Save"
|
||||
saveChanges = "Save Changes"
|
||||
@@ -4517,7 +4508,6 @@ description = "URL or filename to impressum (required in some jurisdictions)"
|
||||
title = "Premium & Enterprise"
|
||||
description = "Configure your premium or enterprise license key."
|
||||
license = "License Configuration"
|
||||
noInput = "Please provide a license key or file"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Got a license key or certificate file?"
|
||||
@@ -4535,26 +4525,6 @@ line1 = "Overwriting your current license key cannot be undone."
|
||||
line2 = "Your previous license will be permanently lost unless you have backed it up elsewhere."
|
||||
line3 = "Important: Keep license keys private and secure. Never share them publicly."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "License Key"
|
||||
file = "Certificate File"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "License Certificate File"
|
||||
description = "Upload your .lic or .cert license file from offline purchases"
|
||||
choose = "Choose License File"
|
||||
selected = "Selected: {{filename}} ({{size}})"
|
||||
successMessage = "License file uploaded and activated successfully. No restart required."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Active License"
|
||||
file = "Source: License file ({{path}})"
|
||||
key = "Source: License key"
|
||||
type = "Type: {{type}}"
|
||||
|
||||
noInput = "Please provide a license key or upload a certificate file"
|
||||
success = "Success"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Enable Premium Features"
|
||||
description = "Enable license key checks for pro/enterprise features"
|
||||
@@ -5291,7 +5261,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "At least one email address is required"
|
||||
submit = "Send Invites"
|
||||
success = "user(s) invited successfully"
|
||||
partialFailure = "Some invites failed"
|
||||
partialSuccess = "Some invites failed"
|
||||
allFailed = "Failed to invite users"
|
||||
error = "Failed to send invites"
|
||||
|
||||
@@ -5807,7 +5777,7 @@ description = "Sign in with your Stirling account"
|
||||
|
||||
[setup.mode.selfhosted]
|
||||
title = "Self-Hosted Server"
|
||||
description = "Connect to your own Stirling PDF server with your personal account"
|
||||
description = "Connect to your own Stirling PDF server"
|
||||
|
||||
[setup.saas]
|
||||
title = "Sign in to Stirling"
|
||||
@@ -5843,13 +5813,6 @@ submit = "Login"
|
||||
signInWith = "Sign in with"
|
||||
oauthPending = "Opening browser for authentication..."
|
||||
orContinueWith = "Or continue with email"
|
||||
serverRequirement = "Note: The server must have login enabled."
|
||||
showInstructions = "How to enable?"
|
||||
hideInstructions = "Hide instructions"
|
||||
instructions = "To enable login on your Stirling PDF server:"
|
||||
instructionsEnvVar = "Set the environment variable:"
|
||||
instructionsOrYml = "Or in settings.yml:"
|
||||
instructionsRestart = "Then restart your server for the changes to take effect."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Username"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Quitar de favoritos"
|
||||
fullscreen = "Cambiar a modo pantalla completa"
|
||||
sidebar = "Cambiar a modo barra lateral"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend no encontrado"
|
||||
retry = "Reintentar"
|
||||
unreachable = "La aplicación no puede conectarse actualmente al backend. Verifique el estado del backend y la conectividad de red, luego inténtelo de nuevo."
|
||||
|
||||
[zipWarning]
|
||||
title = "Archivo ZIP grande"
|
||||
message = "Este ZIP contiene {{count}} archivos. ¿Extraer de todos modos?"
|
||||
@@ -352,7 +347,7 @@ teams = "Equipos"
|
||||
title = "Configuración"
|
||||
systemSettings = "Ajustes del sistema"
|
||||
features = "Funciones"
|
||||
endpoints = "Puntos de conexión"
|
||||
endpoints = "Endpoints"
|
||||
database = "Base de datos"
|
||||
advanced = "Avanzado"
|
||||
|
||||
@@ -918,8 +913,8 @@ desc = "Superponer PDFs encima de otro PDF"
|
||||
title = "Superponer PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Editor de texto de PDF"
|
||||
desc = "Edita texto e imágenes existentes dentro de archivos PDF"
|
||||
title = "Editor de texto PDF"
|
||||
desc = "Revise y edite exportaciones JSON de Stirling PDF con edición de texto agrupada y regeneración de PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "texto,anotación,etiqueta"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Firma dibujada"
|
||||
defaultImageLabel = "Firma subida"
|
||||
defaultTextLabel = "Firma escrita"
|
||||
saveButton = "Guardar firma"
|
||||
savePersonal = "Guardar personal"
|
||||
saveShared = "Guardar compartida"
|
||||
saveUnavailable = "Cree primero una firma para guardarla."
|
||||
noChanges = "La firma actual ya está guardada."
|
||||
tempStorageTitle = "Almacenamiento temporal del navegador"
|
||||
tempStorageDescription = "Las firmas se almacenan solo en tu navegador. Se perderán si borras los datos del navegador o cambias de navegador."
|
||||
personalHeading = "Firmas personales"
|
||||
sharedHeading = "Firmas compartidas"
|
||||
personalDescription = "Solo tú puedes ver estas firmas."
|
||||
sharedDescription = "Todos los usuarios pueden ver y usar estas firmas."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Dibujo"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Por favor, inicie sesión"
|
||||
ssoSignIn = "Iniciar sesión a través del inicio de sesión único"
|
||||
oAuth2AutoCreateDisabled = "Usuario de creación automática de OAUTH2 DESACTIVADO"
|
||||
oAuth2AdminBlockedUser = "El registro o inicio de sesión de usuarios no registrados está actualmente bloqueado. Por favor, póngase en contacto con el administrador."
|
||||
oAuth2RequiresLicense = "El inicio de sesión OAuth/SSO requiere una licencia de pago (Server o Enterprise). Póngase en contacto con el administrador para actualizar su plan."
|
||||
saml2RequiresLicense = "El inicio de sesión SAML requiere una licencia de pago (Server o Enterprise). Póngase en contacto con el administrador para actualizar su plan."
|
||||
maxUsersReached = "Se alcanzó el número máximo de usuarios para su licencia actual. Póngase en contacto con el administrador para actualizar su plan o añadir más plazas."
|
||||
oauth2RequestNotFound = "Solicitud de autorización no encontrada"
|
||||
oauth2InvalidUserInfoResponse = "Respuesta de información de usuario no válida"
|
||||
oauth2invalidRequest = "Solicitud no válida"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Ajustar al Ancho"
|
||||
actualSize = "Tamaño Real"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "No se puede previsualizar el archivo"
|
||||
dualPageView = "Vista de Página Doble"
|
||||
firstPage = "Primera Página"
|
||||
lastPage = "Última Página"
|
||||
nextPage = "Página Siguiente"
|
||||
onlyPdfSupported = "El visor solo admite archivos PDF. Este archivo parece ser de un formato diferente."
|
||||
previousPage = "Página Anterior"
|
||||
singlePageView = "Vista de Página Única"
|
||||
unknownFile = "Archivo desconocido"
|
||||
nextPage = "Página Siguiente"
|
||||
zoomIn = "Acercar"
|
||||
zoomOut = "Alejar"
|
||||
singlePageView = "Vista de Página Única"
|
||||
dualPageView = "Vista de Página Doble"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Cerrar Archivos Seleccionados"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Alternar Barra Lateral"
|
||||
exportSelected = "Exportar páginas seleccionadas"
|
||||
toggleAnnotations = "Mostrar/ocultar anotaciones"
|
||||
annotationMode = "Cambiar modo de anotaciones"
|
||||
print = "Imprimir PDF"
|
||||
draw = "Dibujar"
|
||||
save = "Guardar"
|
||||
saveChanges = "Guardar cambios"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL o nombre de archivo del impressum (requerido en algunas juris
|
||||
title = "Premium y Enterprise"
|
||||
description = "Configura tu clave de licencia premium o enterprise."
|
||||
license = "Configuración de licencia"
|
||||
noInput = "Proporciona una clave o archivo de licencia"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "¿Tiene una clave de licencia o un archivo de certificado?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Sobrescribir su clave de licencia actual no se puede deshacer."
|
||||
line2 = "Su licencia anterior se perderá de forma permanente a menos que la haya respaldado en otro lugar."
|
||||
line3 = "Importante: mantenga las claves de licencia privadas y seguras. Nunca las comparta públicamente."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Clave de licencia"
|
||||
file = "Archivo de certificado"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Archivo de certificado de licencia"
|
||||
description = "Sube tu archivo de licencia .lic o .cert de compras sin conexión"
|
||||
choose = "Elegir archivo de licencia"
|
||||
selected = "Seleccionado: {{filename}} ({{size}})"
|
||||
successMessage = "Archivo de licencia subido y activado correctamente. No es necesario reiniciar."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Licencia activa"
|
||||
file = "Origen: Archivo de licencia ({{path}})"
|
||||
key = "Origen: Clave de licencia"
|
||||
type = "Tipo: {{type}}"
|
||||
noInput = "Proporciona una clave de licencia o sube un archivo de certificado"
|
||||
success = "Éxito"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Habilitar funciones Premium"
|
||||
description = "Habilitar la verificación de la clave de licencia para funciones pro/enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} seleccionados"
|
||||
download = "Descargar"
|
||||
delete = "Borrar"
|
||||
unsupported = "No Soportado"
|
||||
active = "Activo"
|
||||
addToUpload = "Añadir a la subida"
|
||||
closeFile = "Cerrar archivo"
|
||||
deleteAll = "Eliminar todo"
|
||||
loadingFiles = "Cargando archivos..."
|
||||
noFiles = "No hay archivos disponibles"
|
||||
@@ -5249,7 +5207,7 @@ user = "Usuario"
|
||||
[workspace.people.addMember]
|
||||
title = "Añadir miembro"
|
||||
username = "Nombre de usuario (correo)"
|
||||
usernamePlaceholder = "usuario@ejemplo.com"
|
||||
usernamePlaceholder = "user@example.com"
|
||||
password = "Contraseña"
|
||||
passwordPlaceholder = "Introduce la contraseña"
|
||||
role = "Rol"
|
||||
@@ -5286,11 +5244,11 @@ error = "No se pudo eliminar el usuario"
|
||||
tab = "Invitación por correo electrónico"
|
||||
description = "Escribe o pega correos a continuación, separados por comas. Los usuarios recibirán credenciales de inicio de sesión por correo electrónico."
|
||||
emails = "Direcciones de correo electrónico"
|
||||
emailsPlaceholder = "usuario1@ejemplo.com, usuario2@ejemplo.com"
|
||||
emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Se requiere al menos una dirección de correo electrónico"
|
||||
submit = "Enviar invitaciones"
|
||||
success = "usuario(s) invitado(s) correctamente"
|
||||
partialFailure = "Algunas invitaciones fallaron"
|
||||
partialSuccess = "Algunas invitaciones fallaron"
|
||||
allFailed = "No se pudo invitar a los usuarios"
|
||||
error = "No se pudieron enviar las invitaciones"
|
||||
|
||||
@@ -5586,7 +5544,7 @@ emailInvalid = "Introduzca una dirección de correo válida"
|
||||
title = "Introduzca su correo electrónico"
|
||||
description = "Lo usaremos para enviar su clave de licencia y recibos."
|
||||
emailLabel = "Dirección de correo electrónico"
|
||||
emailPlaceholder = "su@email.com"
|
||||
emailPlaceholder = "your@email.com"
|
||||
continue = "Continuar"
|
||||
modalTitle = "Comenzar - {{planName}}"
|
||||
|
||||
@@ -5842,20 +5800,13 @@ submit = "Iniciar sesión"
|
||||
signInWith = "Iniciar sesión con"
|
||||
oauthPending = "Abriendo el navegador para autenticación..."
|
||||
orContinueWith = "O continuar con email"
|
||||
serverRequirement = "Nota: el servidor debe tener el inicio de sesión habilitado."
|
||||
showInstructions = "¿Cómo habilitarlo?"
|
||||
hideInstructions = "Ocultar instrucciones"
|
||||
instructions = "Para habilitar el inicio de sesión en su servidor de Stirling PDF:"
|
||||
instructionsEnvVar = "Establezca la variable de entorno:"
|
||||
instructionsOrYml = "O en settings.yml:"
|
||||
instructionsRestart = "Luego reinicie su servidor para que los cambios surtan efecto."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Nombre de usuario"
|
||||
placeholder = "Introduzca su nombre de usuario"
|
||||
|
||||
[setup.login.email]
|
||||
label = "Correo electrónico"
|
||||
label = "Email"
|
||||
placeholder = "Introduzca su email"
|
||||
|
||||
[setup.login.password]
|
||||
@@ -5892,7 +5843,7 @@ paragraph = "Página de párrafos"
|
||||
sparse = "Texto disperso"
|
||||
|
||||
[pdfTextEditor.groupingMode]
|
||||
auto = "Automático"
|
||||
auto = "Auto"
|
||||
paragraph = "Párrafo"
|
||||
singleLine = "Línea única"
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ visitGithub = "Bisitatu Github biltegia"
|
||||
donate = "Dohaintza egin"
|
||||
color = "Color"
|
||||
sponsor = "Babestu"
|
||||
info = "Informazioa"
|
||||
info = "Info"
|
||||
pro = "Pro"
|
||||
page = "Orrialdea"
|
||||
pages = "Orrialdeak"
|
||||
@@ -131,7 +131,7 @@ unsupported = "Ez da onartzen"
|
||||
|
||||
[toolPanel]
|
||||
placeholder = "Aukeratu tresna bat hasteko"
|
||||
alpha = "Alfa"
|
||||
alpha = "Alpha"
|
||||
premiumFeature = "Premium ezaugarria:"
|
||||
comingSoon = "Laster eskuragarri:"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Kendu gogokoetatik"
|
||||
fullscreen = "Aldatu pantaila osoko modura"
|
||||
sidebar = "Aldatu alboko barra modura"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend-a ez da aurkitu"
|
||||
retry = "Saiatu berriro"
|
||||
unreachable = "Aplikazioak une honetan ezin du backend-arekin konektatu. Egiaztatu backend-aren egoera eta sare-konexioa, eta saiatu berriro."
|
||||
|
||||
[zipWarning]
|
||||
title = "ZIP fitxategi handia"
|
||||
message = "ZIP honek {{count}} fitxategi ditu. Erauzi hala ere?"
|
||||
@@ -279,7 +274,7 @@ iAgreeToThe = "Onartzen ditut honako hauek guztiak"
|
||||
terms = "Baldintzak eta erabilera-baldintzak"
|
||||
accessibility = "Irisgarritasuna"
|
||||
cookie = "Cookie politika"
|
||||
impressum = "Lege oharra"
|
||||
impressum = "Impressum"
|
||||
showCookieBanner = "Cookie-hobespenak"
|
||||
|
||||
[pipeline]
|
||||
@@ -301,7 +296,7 @@ saveSettings = "Gorde eragiketa-ezarpenak"
|
||||
pipelineNamePrompt = "Sartu hemen pipeline izena"
|
||||
selectOperation = "Aukeratu eragiketa"
|
||||
addOperationButton = "Gehitu eragiketa"
|
||||
pipelineHeader = "Pipelinea:"
|
||||
pipelineHeader = "Pipeline:"
|
||||
saveButton = "Distira"
|
||||
validateButton = "Balidatu"
|
||||
|
||||
@@ -352,7 +347,7 @@ teams = "Taldeak"
|
||||
title = "Konfigurazioa"
|
||||
systemSettings = "Sistemaren ezarpenak"
|
||||
features = "Eginbideak"
|
||||
endpoints = "Amaiera-puntuak"
|
||||
endpoints = "Endpoints"
|
||||
database = "Datu-basea"
|
||||
advanced = "Aurreratua"
|
||||
|
||||
@@ -369,7 +364,7 @@ usageAnalytics = "Erabilera-analitika"
|
||||
|
||||
[settings.policiesPrivacy]
|
||||
title = "Politikak eta Pribatutasuna"
|
||||
legal = "Lege"
|
||||
legal = "Legal"
|
||||
privacy = "Pribatutasuna"
|
||||
|
||||
[settings.developer]
|
||||
@@ -518,7 +513,7 @@ syncToAccount = "Sync Kontua <- Nabigatzailea"
|
||||
[adminUserSettings]
|
||||
title = "Erabiltzailearen Ezarpenen Kontrolak"
|
||||
header = "Admin Erabiltzailearen Ezarpenen Kontrolak"
|
||||
admin = "Administratzailea"
|
||||
admin = "Admin"
|
||||
user = "Erabiltzaile"
|
||||
addUser = "Erabiltzaile berria"
|
||||
deleteUser = "Ezabatu erabiltzailea"
|
||||
@@ -918,8 +913,8 @@ desc = "Overlays PDFs on-top of another PDF"
|
||||
title = "Gainjarri PDFak"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF testu editorea"
|
||||
desc = "Editatu PDFetako lehendik dauden testuak eta irudiak"
|
||||
title = "PDF testu-editorea"
|
||||
desc = "Berrikusi eta editatu Stirling PDF JSON esportazioak taldekatutako testu-edizioarekin eta PDF birsorkuntzarekin"
|
||||
|
||||
[home.addText]
|
||||
tags = "testua,anotazioa,etiketa"
|
||||
@@ -1225,7 +1220,7 @@ odtExt = "OpenDocument testua (.odt)"
|
||||
pptExt = "PowerPoint (.pptx)"
|
||||
odpExt = "OpenDocument aurkezpena (.odp)"
|
||||
txtExt = "Testu laua (.txt)"
|
||||
rtfExt = "Testu aberatsaren formatua (.rtf)"
|
||||
rtfExt = "Rich Text Format (.rtf)"
|
||||
selectedFiles = "Hautatutako fitxategiak"
|
||||
noFileSelected = "Ez da fitxategirik hautatu. Erabili fitxategi-panela fitxategiak gehitzeko."
|
||||
convertFiles = "Bihurtu fitxategiak"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Marrazketa sinadura"
|
||||
defaultImageLabel = "Igotako sinadura"
|
||||
defaultTextLabel = "Idatzitako sinadura"
|
||||
saveButton = "Gorde sinadura"
|
||||
savePersonal = "Gorde pertsonala"
|
||||
saveShared = "Gorde partekatua"
|
||||
saveUnavailable = "Lehenik sortu sinadura bat gordetzeko."
|
||||
noChanges = "Uneko sinadura dagoeneko gorde da."
|
||||
tempStorageTitle = "Aldi baterako nabigatzaileko biltegiratzea"
|
||||
tempStorageDescription = "Sinadurak zure nabigatzailean bakarrik gordetzen dira. Nabigatzailearen datuak ezabatzen badituzu edo nabigatzailea aldatzen baduzu, galdu egingo dira."
|
||||
personalHeading = "Sinadura pertsonalak"
|
||||
sharedHeading = "Partekatutako sinadurak"
|
||||
personalDescription = "Zuk bakarrik ikus ditzakezu sinadura hauek."
|
||||
sharedDescription = "Erabiltzaile guztiek ikus eta erabil ditzakete sinadura hauek."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Marrazkia"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Mesedez, hasi saioa"
|
||||
ssoSignIn = "Hasi saioa Saioa hasteko modu bakarraren bidez"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Sortu automatikoki erabiltzailea desgaituta dago"
|
||||
oAuth2AdminBlockedUser = "Erregistratu gabeko erabiltzaileen erregistroa edo saio-hasiera une honetan blokeatuta dago. Jarri harremanetan administratzailearekin."
|
||||
oAuth2RequiresLicense = "OAuth/SSO bidezko saio-hasierak lizentzia ordaindua behar du (Server edo Enterprise). Mesedez, jarri harremanetan administratzailearekin plana eguneratzeko."
|
||||
saml2RequiresLicense = "SAML bidezko saio-hasierak lizentzia ordaindua behar du (Server edo Enterprise). Mesedez, jarri harremanetan administratzailearekin plana eguneratzeko."
|
||||
maxUsersReached = "Zure uneko lizentziarekin erabiltzaile kopuru maximoa gainditu da. Mesedez, jarri harremanetan administratzailearekin plana eguneratzeko edo eserleku gehiago gehitzeko."
|
||||
oauth2RequestNotFound = "Baimen-eskaera ez da aurkitu"
|
||||
oauth2InvalidUserInfoResponse = "Erabiltzaile-informazioaren erantzun baliogabea"
|
||||
oauth2invalidRequest = "Eskaera baliogabea"
|
||||
@@ -3552,7 +3536,7 @@ title = "PDF Orrialde bakarrera"
|
||||
header = "PDF Orrialde bakarrera"
|
||||
submit = "Orrialde bakarrera bihurtu"
|
||||
description = "Tresna honek zure PDFko orri guztiak orri handi bakarrean batuko ditu. Zabalera bera izango du jatorrizko orrienarekin, baina altuera orri guztien altueren batura izango da."
|
||||
filenamePrefix = "orrialde_bakarra"
|
||||
filenamePrefix = "single_page"
|
||||
|
||||
[pdfToSinglePage.files]
|
||||
placeholder = "Hautatu PDF fitxategi bat ikuspegi nagusian hasteko"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Zabalera egokitu"
|
||||
actualSize = "Benetako tamaina"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Ezin da fitxategia aurreikusi"
|
||||
dualPageView = "Orri biko ikuspegia"
|
||||
firstPage = "Lehen orria"
|
||||
lastPage = "Azken orria"
|
||||
nextPage = "Hurrengo orria"
|
||||
onlyPdfSupported = "Ikustaileak PDF fitxategiak bakarrik onartzen ditu. Fitxategi honek beste formatu batekoa dirudi."
|
||||
previousPage = "Aurreko orria"
|
||||
singlePageView = "Orri bakarreko ikuspegia"
|
||||
unknownFile = "Fitxategi ezezaguna"
|
||||
nextPage = "Hurrengo orria"
|
||||
zoomIn = "Zoom handitu"
|
||||
zoomOut = "Zoom txikitu"
|
||||
singlePageView = "Orri bakarreko ikuspegia"
|
||||
dualPageView = "Orri biko ikuspegia"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Itxi hautatutako fitxategiak"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Alboko barra txandakatu"
|
||||
exportSelected = "Esportatu hautatutako orriak"
|
||||
toggleAnnotations = "Oharpenen ikusgarritasuna txandakatu"
|
||||
annotationMode = "Oharpen modua txandakatu"
|
||||
print = "Inprimatu PDFa"
|
||||
draw = "Marraztu"
|
||||
save = "Gorde"
|
||||
saveChanges = "Aldaketak gorde"
|
||||
@@ -4430,7 +4410,7 @@ description = "Sistema zabalagoko aldi baterako direktorioa garbitu ala ez (kont
|
||||
label = "Prozesu-exekutorearen mugak"
|
||||
description = "Konfiguratu saio-mugak eta denbora-mugak prozesu-exekutore bakoitzerako"
|
||||
libreOffice = "LibreOffice"
|
||||
pdfToHtml = "PDFtik HTMLra"
|
||||
pdfToHtml = "PDF to HTML"
|
||||
qpdf = "QPDF"
|
||||
tesseract = "Tesseract OCR"
|
||||
pythonOpenCv = "Python OpenCV"
|
||||
@@ -4510,14 +4490,13 @@ label = "Cookieen politika"
|
||||
description = "Cookieen politikara doan URLa edo fitxategi-izena"
|
||||
|
||||
[admin.settings.legal.impressum]
|
||||
label = "Lege oharra"
|
||||
label = "Impressum"
|
||||
description = "Impressum-era doan URLa edo fitxategi-izena (beharrezkoa jurisdikzio batzuetan)"
|
||||
|
||||
[admin.settings.premium]
|
||||
title = "Premium eta Enterprise"
|
||||
description = "Konfiguratu zure premium edo enterprise lizentzia-gakoa."
|
||||
license = "Lizentziaren konfigurazioa"
|
||||
noInput = "Eman lizentzia-gakoa edo fitxategia, mesedez"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Lizentzia-gakoa edo ziurtagiri-fitxategia duzu?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Uneko lizentzia-gakoa gainidaztea ezin da desegin."
|
||||
line2 = "Aurreko lizentzia betiko galduko da beste nonbait babestu ezean."
|
||||
line3 = "Garrantzitsua: Mantendu lizentzia-gakoak pribatu eta seguru. Ez partekatu publikoki inoiz."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Lizentzia-gakoa"
|
||||
file = "Ziurtagiri-fitxategia"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Lizentzia-ziurtagiriaren fitxategia"
|
||||
description = "Igo zure .lic edo .cert lizentzia-fitxategia lineaz kanpoko erosketetatik"
|
||||
choose = "Aukeratu lizentzia-fitxategia"
|
||||
selected = "Hautatuta: {{filename}} ({{size}})"
|
||||
successMessage = "Lizentzia-fitxategia behar bezala igo eta aktibatu da. Ez da berrabiaraztea beharrezkoa."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Lizentzia aktiboa"
|
||||
file = "Iturburua: Lizentzia-fitxategia ({{path}})"
|
||||
key = "Iturburua: Lizentzia-gakoa"
|
||||
type = "Mota: {{type}}"
|
||||
noInput = "Eman lizentzia-gakoa edo igo ziurtagiri-fitxategi bat, mesedez"
|
||||
success = "Arrakasta"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Premium eginbideak gaitu"
|
||||
description = "Gaitu lizentzia-gakoen egiaztapenak pro/enterprise eginbideetarako"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} hautatuta"
|
||||
download = "Distira"
|
||||
delete = "ezabatu"
|
||||
unsupported = "Ez da onartzen"
|
||||
active = "Aktibo"
|
||||
addToUpload = "Gehitu igoerara"
|
||||
closeFile = "Itxi fitxategia"
|
||||
deleteAll = "Ezabatu denak"
|
||||
loadingFiles = "Fitxategiak kargatzen..."
|
||||
noFiles = "Ez dago fitxategirik eskuragarri"
|
||||
@@ -5223,7 +5181,7 @@ active = "Aktibo"
|
||||
disabled = "Desgaituta"
|
||||
activeSession = "Saio aktiboa"
|
||||
member = "Kidea"
|
||||
admin = "Administratzailea"
|
||||
admin = "Admin"
|
||||
editRole = "Rola editatu"
|
||||
enable = "Gaitu"
|
||||
disable = "Desgaitu"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Gutxienez helbide elektroniko bat behar da"
|
||||
submit = "Bidali gonbidapenak"
|
||||
success = "erabiltzaile(a)(k) ongi gonbidatu dira"
|
||||
partialFailure = "Gonbidapen batzuk huts egin dute"
|
||||
partialSuccess = "Gonbidapen batzuek huts egin dute"
|
||||
allFailed = "Ezin izan da erabiltzaileak gonbidatu"
|
||||
error = "Ezin izan dira gonbidapenak bidali"
|
||||
|
||||
@@ -5754,7 +5712,7 @@ title = "Endpoints erabileraren diagrama"
|
||||
|
||||
[usage.table]
|
||||
title = "Estatistika xeheak"
|
||||
endpoint = "Amaiera-puntua"
|
||||
endpoint = "Endpoint"
|
||||
visits = "Bisitak"
|
||||
percentage = "Ehunekoa"
|
||||
noData = "Ez dago daturik eskuragarri"
|
||||
@@ -5842,13 +5800,6 @@ submit = "Hasi saioa"
|
||||
signInWith = "Hasi saioa honekin"
|
||||
oauthPending = "Nabigatzailea irekitzen autentifikaziorako..."
|
||||
orContinueWith = "Edo jarraitu emailarekin"
|
||||
serverRequirement = "Oharra: zerbitzariak saioa hastea gaituta eduki behar du."
|
||||
showInstructions = "Nola gaitu?"
|
||||
hideInstructions = "Ezkutatu argibideak"
|
||||
instructions = "Saioa hastea gaitzeko zure Stirling PDF zerbitzarian:"
|
||||
instructionsEnvVar = "Ezarri ingurune-aldagaia:"
|
||||
instructionsOrYml = "Edo settings.yml fitxategian:"
|
||||
instructionsRestart = "Ondoren, berrabiarazi zerbitzaria aldaketak indarrean sartzeko."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Erabiltzaile-izena"
|
||||
@@ -5892,7 +5843,7 @@ paragraph = "Paragrafo orria"
|
||||
sparse = "Testu sakabanatua"
|
||||
|
||||
[pdfTextEditor.groupingMode]
|
||||
auto = "Automatikoa"
|
||||
auto = "Auto"
|
||||
paragraph = "Paragrafoa"
|
||||
singleLine = "Lerro bakarra"
|
||||
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "حذف از علاقهمندیها"
|
||||
fullscreen = "تغییر به حالت تمامصفحه"
|
||||
sidebar = "تغییر به حالت نوار کناری"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "بکاند یافت نشد"
|
||||
retry = "تلاش مجدد"
|
||||
unreachable = "برنامه در حال حاضر نمیتواند به بکاند متصل شود. وضعیت بکاند و اتصال شبکه را بررسی کرده و سپس دوباره تلاش کنید."
|
||||
|
||||
[zipWarning]
|
||||
title = "فایل ZIP بزرگ"
|
||||
message = "این ZIP شامل {{count}} فایل است. با این حال استخراج شود؟"
|
||||
@@ -919,7 +914,7 @@ title = "همپوشانی PDFها"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "ویرایشگر متن PDF"
|
||||
desc = "ویرایش متن و تصاویر موجود در PDFها"
|
||||
desc = "بازبینی و ویرایش خروجیهای JSON Stirling PDF با ویرایش گروهی متن و بازتولید PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "متن,حاشیهنویسی,برچسب"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "امضای ترسیمی"
|
||||
defaultImageLabel = "امضای بارگذاریشده"
|
||||
defaultTextLabel = "امضای تایپی"
|
||||
saveButton = "ذخیره امضا"
|
||||
savePersonal = "ذخیره شخصی"
|
||||
saveShared = "ذخیره اشتراکی"
|
||||
saveUnavailable = "برای ذخیره، ابتدا امضایی بسازید."
|
||||
noChanges = "امضای فعلی قبلاً ذخیره شده است."
|
||||
tempStorageTitle = "ذخیرهسازی موقت در مرورگر"
|
||||
tempStorageDescription = "امضاها فقط در مرورگر شما ذخیره میشوند. در صورت پاککردن دادههای مرورگر یا تعویض مرورگر، از بین میروند."
|
||||
personalHeading = "امضاهای شخصی"
|
||||
sharedHeading = "امضاهای اشتراکی"
|
||||
personalDescription = "تنها شما میتوانید این امضاها را ببینید."
|
||||
sharedDescription = "همه کاربران میتوانند این امضاها را ببینند و استفاده کنند."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "ترسیمی"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "لطفاً وارد شوید"
|
||||
ssoSignIn = "ورود از طریق Single Sign-on"
|
||||
oAuth2AutoCreateDisabled = "ایجاد خودکار کاربر با OAUTH2 غیرفعال است"
|
||||
oAuth2AdminBlockedUser = "ثبتنام یا ورود کاربران ثبتنشده در حال حاضر مسدود است. لطفاً با مدیر تماس بگیرید."
|
||||
oAuth2RequiresLicense = "ورود با OAuth/SSO به لایسنس پولی (Server یا Enterprise) نیاز دارد. لطفاً برای ارتقای طرح خود با مدیر تماس بگیرید."
|
||||
saml2RequiresLicense = "ورود با SAML به لایسنس پولی (Server یا Enterprise) نیاز دارد. لطفاً برای ارتقای طرح خود با مدیر تماس بگیرید."
|
||||
maxUsersReached = "حداکثر تعداد کاربران برای لایسنس کنونی شما به حد نصاب رسیده است. لطفاً برای ارتقای طرح یا افزودن کاربران بیشتر با مدیر تماس بگیرید."
|
||||
oauth2RequestNotFound = "درخواست احراز هویت پیدا نشد"
|
||||
oauth2InvalidUserInfoResponse = "پاسخ اطلاعات کاربری نامعتبر است"
|
||||
oauth2invalidRequest = "درخواست نامعتبر"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "تناسب با عرض"
|
||||
actualSize = "اندازه واقعی"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "امکان پیشنمایش فایل نیست"
|
||||
dualPageView = "نمای دوصفحهای"
|
||||
firstPage = "صفحه نخست"
|
||||
lastPage = "صفحه آخر"
|
||||
nextPage = "صفحه بعد"
|
||||
onlyPdfSupported = "نمایشگر فقط فایلهای PDF را پشتیبانی میکند. به نظر میرسد این فایل قالب متفاوتی دارد."
|
||||
previousPage = "صفحه قبل"
|
||||
singlePageView = "نمای تکصفحهای"
|
||||
unknownFile = "فایل ناشناخته"
|
||||
nextPage = "صفحه بعد"
|
||||
zoomIn = "بزرگنمایی"
|
||||
zoomOut = "کوچکنمایی"
|
||||
singlePageView = "نمای تکصفحهای"
|
||||
dualPageView = "نمای دوصفحهای"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "بستن فایلهای انتخابشده"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "تغییر وضعیت نوار کناری"
|
||||
exportSelected = "برونبری صفحات انتخابشده"
|
||||
toggleAnnotations = "تغییر وضعیت نمایش حاشیهنویسیها"
|
||||
annotationMode = "تغییر حالت حاشیهنویسی"
|
||||
print = "چاپ PDF"
|
||||
draw = "رسم"
|
||||
save = "ذخیره"
|
||||
saveChanges = "ذخیره تغییرات"
|
||||
@@ -4510,14 +4490,13 @@ label = "خطمشی کوکی"
|
||||
description = "URL یا نام فایل برای خطمشی کوکی"
|
||||
|
||||
[admin.settings.legal.impressum]
|
||||
label = "اطلاعات حقوقی"
|
||||
label = "Impressum"
|
||||
description = "URL یا نام فایل برای impressum (در برخی حوزههای قضایی الزامی است)"
|
||||
|
||||
[admin.settings.premium]
|
||||
title = "پرمیوم و سازمانی"
|
||||
description = "کلید لایسنس پرمیوم یا سازمانی خود را پیکربندی کنید."
|
||||
license = "پیکربندی لایسنس"
|
||||
noInput = "لطفاً کلید یا فایل مجوز را ارائه کنید"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "کلید لایسنس یا فایل گواهی دارید؟"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "بازنویسی کلید لایسنس فعلی قابل بازگشت
|
||||
line2 = "مگر آنکه در جایی پشتیبان گرفته باشید، لایسنس قبلی بهطور دائمی از دست میرود."
|
||||
line3 = "مهم: کلیدهای لایسنس را خصوصی و امن نگه دارید. هرگز آنها را عمومی بهاشتراک نگذارید."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "کلید مجوز"
|
||||
file = "فایل گواهی"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "فایل گواهی مجوز"
|
||||
description = "فایل مجوز .lic یا .cert مربوط به خریدهای آفلاین خود را بارگذاری کنید"
|
||||
choose = "انتخاب فایل مجوز"
|
||||
selected = "انتخابشده: {{filename}} ({{size}})"
|
||||
successMessage = "فایل مجوز با موفقیت بارگذاری و فعال شد. نیازی به راهاندازی مجدد نیست."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "مجوز فعال"
|
||||
file = "منبع: فایل مجوز ({{path}})"
|
||||
key = "منبع: کلید مجوز"
|
||||
type = "نوع: {{type}}"
|
||||
noInput = "لطفاً کلید مجوز ارائه کنید یا فایل گواهی را بارگذاری کنید"
|
||||
success = "موفق"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "فعالسازی قابلیتهای پرمیوم"
|
||||
description = "فعالسازی بررسی کلید لایسنس برای قابلیتهای حرفهای/سازمانی"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} مورد انتخابشده"
|
||||
download = "دانلود"
|
||||
delete = "حذف"
|
||||
unsupported = "پشتیبانینشده"
|
||||
active = "فعال"
|
||||
addToUpload = "افزودن به بارگذاری"
|
||||
closeFile = "بستن فایل"
|
||||
deleteAll = "حذف همه"
|
||||
loadingFiles = "در حال بارگذاری فایلها..."
|
||||
noFiles = "فایلی موجود نیست"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "حداقل یک آدرس ایمیل الزامی است"
|
||||
submit = "ارسال دعوتنامهها"
|
||||
success = "کاربر(ان) با موفقیت دعوت شد(ند)"
|
||||
partialFailure = "برخی دعوتها ناموفق بودند"
|
||||
partialSuccess = "برخی دعوتها ناموفق بود"
|
||||
allFailed = "دعوت کاربران ناموفق بود"
|
||||
error = "ارسال دعوتنامهها ناموفق بود"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "ورود"
|
||||
signInWith = "ورود با"
|
||||
oauthPending = "در حال باز کردن مرورگر برای احراز هویت..."
|
||||
orContinueWith = "یا با ایمیل ادامه دهید"
|
||||
serverRequirement = "توجه: سرور باید ورود را فعال کرده باشد."
|
||||
showInstructions = "نحوه فعالسازی؟"
|
||||
hideInstructions = "مخفی کردن دستورالعملها"
|
||||
instructions = "برای فعالسازی ورود در سرور Stirling PDF خود:"
|
||||
instructionsEnvVar = "متغیر محیطی را تنظیم کنید:"
|
||||
instructionsOrYml = "یا در settings.yml:"
|
||||
instructionsRestart = "سپس سرور خود را راهاندازی مجدد کنید تا تغییرات اعمال شوند."
|
||||
|
||||
[setup.login.username]
|
||||
label = "نام کاربری"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Retirer des favoris"
|
||||
fullscreen = "Passer en mode plein écran"
|
||||
sidebar = "Passer en mode barre latérale"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend introuvable"
|
||||
retry = "Réessayer"
|
||||
unreachable = "L’application ne peut actuellement pas se connecter au backend. Vérifiez l’état du backend et la connectivité réseau, puis réessayez."
|
||||
|
||||
[zipWarning]
|
||||
title = "Fichier ZIP volumineux"
|
||||
message = "Ce ZIP contient {{count}} fichiers. Extraire quand même ?"
|
||||
@@ -352,7 +347,7 @@ teams = "Équipes"
|
||||
title = "Configuration"
|
||||
systemSettings = "Paramètres système"
|
||||
features = "Fonctionnalités"
|
||||
endpoints = "Points de terminaison"
|
||||
endpoints = "Endpoints"
|
||||
database = "Base de données"
|
||||
advanced = "Avancé"
|
||||
|
||||
@@ -919,7 +914,7 @@ title = "Superposer des PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Éditeur de texte PDF"
|
||||
desc = "Modifier le texte et les images existants dans les PDF"
|
||||
desc = "Afficher et modifier les exports JSON de Stirling PDF avec édition de texte groupée et régénération du PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "texte,annotation,étiquette"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Signature dessinée"
|
||||
defaultImageLabel = "Signature téléversée"
|
||||
defaultTextLabel = "Signature saisie"
|
||||
saveButton = "Enregistrer la signature"
|
||||
savePersonal = "Enregistrer en personnel"
|
||||
saveShared = "Enregistrer en partagé"
|
||||
saveUnavailable = "Créez d’abord une signature pour l’enregistrer."
|
||||
noChanges = "La signature actuelle est déjà enregistrée."
|
||||
tempStorageTitle = "Stockage temporaire du navigateur"
|
||||
tempStorageDescription = "Les signatures sont stockées uniquement dans votre navigateur. Elles seront perdues si vous effacez les données du navigateur ou si vous changez de navigateur."
|
||||
personalHeading = "Signatures personnelles"
|
||||
sharedHeading = "Signatures partagées"
|
||||
personalDescription = "Vous seul pouvez voir ces signatures."
|
||||
sharedDescription = "Tous les utilisateurs peuvent voir et utiliser ces signatures."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Dessin"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Veuillez vous connecter"
|
||||
ssoSignIn = "Se connecter via l'authentification unique"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Création automatique d'utilisateur désactivée"
|
||||
oAuth2AdminBlockedUser = "La création ou l'authentification d'utilisateurs non enregistrés est actuellement bloquée. Veuillez contacter l'administrateur."
|
||||
oAuth2RequiresLicense = "La connexion OAuth/SSO nécessite une licence payante (Server ou Enterprise). Veuillez contacter l’administrateur pour mettre à niveau votre plan."
|
||||
saml2RequiresLicense = "La connexion SAML nécessite une licence payante (Server ou Enterprise). Veuillez contacter l’administrateur pour mettre à niveau votre plan."
|
||||
maxUsersReached = "Nombre maximal d’utilisateurs atteint pour votre licence actuelle. Veuillez contacter l’administrateur pour mettre à niveau votre plan ou ajouter des places."
|
||||
oauth2RequestNotFound = "Demande d'autorisation introuvable"
|
||||
oauth2InvalidUserInfoResponse = "Réponse contenant les informations de l'utilisateur est invalide"
|
||||
oauth2invalidRequest = "Requête invalide"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Ajuster à la largeur"
|
||||
actualSize = "Taille réelle"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Impossible d’afficher un aperçu du fichier"
|
||||
dualPageView = "Vue double page"
|
||||
firstPage = "Première page"
|
||||
lastPage = "Dernière page"
|
||||
nextPage = "Page suivante"
|
||||
onlyPdfSupported = "Le visualiseur prend uniquement en charge les fichiers PDF. Ce fichier semble être d’un autre format."
|
||||
previousPage = "Page précédente"
|
||||
singlePageView = "Vue page unique"
|
||||
unknownFile = "Fichier inconnu"
|
||||
nextPage = "Page suivante"
|
||||
zoomIn = "Zoom avant"
|
||||
zoomOut = "Zoom arrière"
|
||||
singlePageView = "Vue page unique"
|
||||
dualPageView = "Vue double page"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Fermer les fichiers sélectionnés"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Afficher/masquer la barre latérale"
|
||||
exportSelected = "Exporter les pages sélectionnées"
|
||||
toggleAnnotations = "Afficher/masquer les annotations"
|
||||
annotationMode = "Basculer en mode annotation"
|
||||
print = "Imprimer le PDF"
|
||||
draw = "Dessiner"
|
||||
save = "Enregistrer"
|
||||
saveChanges = "Enregistrer les modifications"
|
||||
@@ -4176,7 +4156,7 @@ description = "Suivre les actions des utilisateurs et les événements système
|
||||
|
||||
[admin.settings.security.audit.level]
|
||||
label = "Niveau d’audit"
|
||||
description = "0=DÉSACTIVÉ, 1=BASIQUE, 2=STANDARD, 3=VERBEUX"
|
||||
description = "0=OFF, 1=BASIC, 2=STANDARD, 3=VERBOSE"
|
||||
|
||||
[admin.settings.security.audit.retentionDays]
|
||||
label = "Rétention des journaux (jours)"
|
||||
@@ -4514,10 +4494,9 @@ label = "Mentions légales"
|
||||
description = "URL ou nom de fichier de l’impressum (obligatoire dans certaines juridictions)"
|
||||
|
||||
[admin.settings.premium]
|
||||
title = "Premium et Entreprise"
|
||||
title = "Premium & Enterprise"
|
||||
description = "Configurer votre clé de licence Premium ou Enterprise."
|
||||
license = "Configuration de la licence"
|
||||
noInput = "Veuillez fournir une clé de licence ou un fichier"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Vous avez une clé de licence ou un fichier de certificat ?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Écraser votre clé de licence actuelle est irréversible."
|
||||
line2 = "Votre licence précédente sera définitivement perdue, sauf si vous l’avez sauvegardée ailleurs."
|
||||
line3 = "Important : gardez vos clés de licence privées et sécurisées. Ne les partagez jamais publiquement."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Clé de licence"
|
||||
file = "Fichier de certificat"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Fichier de certificat de licence"
|
||||
description = "Téléversez votre fichier de licence .lic ou .cert issu d’achats hors ligne"
|
||||
choose = "Choisir le fichier de licence"
|
||||
selected = "Sélectionné: {{filename}} ({{size}})"
|
||||
successMessage = "Fichier de licence téléversé et activé avec succès. Aucun redémarrage requis."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Licence active"
|
||||
file = "Source: Fichier de licence ({{path}})"
|
||||
key = "Source: Clé de licence"
|
||||
type = "Type: {{type}}"
|
||||
noInput = "Veuillez fournir une clé de licence ou téléverser un fichier de certificat"
|
||||
success = "Succès"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Activer les fonctionnalités Premium"
|
||||
description = "Activer la vérification de la clé de licence pour les fonctionnalités Pro/Enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} sélectionné(s)"
|
||||
download = "Télécharger"
|
||||
delete = "Supprimer"
|
||||
unsupported = "Non pris en charge"
|
||||
active = "Actif"
|
||||
addToUpload = "Ajouter au téléversement"
|
||||
closeFile = "Fermer le fichier"
|
||||
deleteAll = "Tout supprimer"
|
||||
loadingFiles = "Chargement des fichiers..."
|
||||
noFiles = "Aucun fichier disponible"
|
||||
@@ -5223,7 +5181,7 @@ active = "Actif"
|
||||
disabled = "Désactivé"
|
||||
activeSession = "Session active"
|
||||
member = "Membre"
|
||||
admin = "Administrateur"
|
||||
admin = "Admin"
|
||||
editRole = "Modifier le rôle"
|
||||
enable = "Activer"
|
||||
disable = "Désactiver"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Au moins une adresse e-mail est requise"
|
||||
submit = "Envoyer les invitations"
|
||||
success = "Utilisateur(s) invité(s) avec succès"
|
||||
partialFailure = "Certaines invitations ont échoué"
|
||||
partialSuccess = "Certaines invitations ont échoué"
|
||||
allFailed = "Échec de l’invitation des utilisateurs"
|
||||
error = "Échec de l’envoi des invitations"
|
||||
|
||||
@@ -5754,7 +5712,7 @@ title = "Graphique d’utilisation des endpoints"
|
||||
|
||||
[usage.table]
|
||||
title = "Statistiques détaillées"
|
||||
endpoint = "Point de terminaison"
|
||||
endpoint = "Endpoint"
|
||||
visits = "Visites"
|
||||
percentage = "Pourcentage"
|
||||
noData = "Aucune donnée disponible"
|
||||
@@ -5842,20 +5800,13 @@ submit = "Se connecter"
|
||||
signInWith = "Se connecter avec"
|
||||
oauthPending = "Ouverture du navigateur pour l'authentification..."
|
||||
orContinueWith = "Ou continuer avec l’email"
|
||||
serverRequirement = "Remarque : le serveur doit avoir la connexion activée."
|
||||
showInstructions = "Comment l’activer ?"
|
||||
hideInstructions = "Masquer les instructions"
|
||||
instructions = "Pour activer la connexion sur votre serveur Stirling PDF :"
|
||||
instructionsEnvVar = "Définissez la variable d’environnement :"
|
||||
instructionsOrYml = "Ou dans settings.yml :"
|
||||
instructionsRestart = "Redémarrez ensuite votre serveur pour que les modifications prennent effet."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Nom d’utilisateur"
|
||||
placeholder = "Entrez votre nom d’utilisateur"
|
||||
|
||||
[setup.login.email]
|
||||
label = "E-mail"
|
||||
label = "Email"
|
||||
placeholder = "Saisissez votre email"
|
||||
|
||||
[setup.login.password]
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Bain den Cheanáin"
|
||||
fullscreen = "Athraigh go mód lánscáileáin"
|
||||
sidebar = "Athraigh go mód barra taoibh"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Níor aimsíodh an cúlchóras"
|
||||
retry = "Atriail"
|
||||
unreachable = "Ní féidir leis an bhfeidhmchlár ceangal leis an gcúlchóras faoi láthair. Deimhnigh stádas an chúlchórais agus nascacht an líonra, ansin bain triail eile as."
|
||||
|
||||
[zipWarning]
|
||||
title = "Comhad ZIP Mór"
|
||||
message = "Tá {{count}} comhad sa ZIP seo. An mbaineann tú amach mar sin féin?"
|
||||
@@ -919,7 +914,7 @@ title = "Forleagan PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Eagarthóir Téacs PDF"
|
||||
desc = "Cuir téacs agus íomhánna atá ann cheana in eagar laistigh de PDFanna"
|
||||
desc = "Athbhreithnigh agus cuir in eagar onnmhairí JSON ó Stirling PDF le heagarthóireacht téacs ghrúpáilte agus athghiniúint PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "téacs,anótáil,lipéad"
|
||||
@@ -1643,7 +1638,7 @@ subtitle = "Íoslódáil an comhad próiseáilte nó cealaigh an oibríocht thí
|
||||
[removePages]
|
||||
tags = "Bain leathanaigh, scrios leathanaigh"
|
||||
title = "Bain"
|
||||
filenamePrefix = "leathanaigh_bainte"
|
||||
filenamePrefix = "pages_removed"
|
||||
submit = "Bain"
|
||||
|
||||
[removePages.pageNumbers]
|
||||
@@ -1845,7 +1840,7 @@ title = "Bain Léamh-Amháin ó Réimsí Foirme"
|
||||
header = "Díghlasáil Foirmeacha PDF"
|
||||
submit = "Remove"
|
||||
description = "Bainfidh an uirlis seo srianta léamh-amáin ó réimsí foirme PDF, rud a fhágann go mbeidh siad in-eagarthóireachta agus inlíonta."
|
||||
filenamePrefix = "foirmeacha_díghlasáilte"
|
||||
filenamePrefix = "unlocked_forms"
|
||||
|
||||
[unlockPDFForms.files]
|
||||
placeholder = "Roghnaigh comhad PDF sa phríomh-amharc chun tosú"
|
||||
@@ -1859,7 +1854,7 @@ title = "Torthaí Díghlasála Foirmeacha"
|
||||
[changeMetadata]
|
||||
header = "Athraigh Meiteashonraí"
|
||||
submit = "Athrú"
|
||||
filenamePrefix = "meiteashonraí"
|
||||
filenamePrefix = "metadata"
|
||||
|
||||
[changeMetadata.settings]
|
||||
title = "Socruithe Meiteashonraí"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Síniú líníochta"
|
||||
defaultImageLabel = "Síniú uaslódáilte"
|
||||
defaultTextLabel = "Síniú clóscríofa"
|
||||
saveButton = "Sábháil síniú"
|
||||
savePersonal = "Sábháil Pearsanta"
|
||||
saveShared = "Sábháil Comhroinnte"
|
||||
saveUnavailable = "Cruthaigh síniú ar dtús chun é a shábháil."
|
||||
noChanges = "Tá an síniú reatha sábháilte cheana."
|
||||
tempStorageTitle = "Stóráil shealadach an bhrabhsálaí"
|
||||
tempStorageDescription = "Stóráiltear na sínithe i do bhrabhsálaí amháin. Caillfear iad má ghlanann tú sonraí an bhrabhsálaí nó má athraíonn tú brabhsálaithe."
|
||||
personalHeading = "Sínithe Pearsanta"
|
||||
sharedHeading = "Sínithe Comhroinnte"
|
||||
personalDescription = "Ní féidir ach leatsa na sínithe seo a fheiceáil."
|
||||
sharedDescription = "Is féidir le gach úsáideoir na sínithe seo a fheiceáil agus a úsáid."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Líníocht"
|
||||
@@ -2334,7 +2321,7 @@ title = "Comhcheangail"
|
||||
header = "PDF cothromú"
|
||||
flattenOnlyForms = "Flatten foirmeacha amháin"
|
||||
submit = "Comhcheangail"
|
||||
filenamePrefix = "maolaithe"
|
||||
filenamePrefix = "flattened"
|
||||
|
||||
[flatten.files]
|
||||
placeholder = "Roghnaigh comhad PDF sa phríomh-amharc chun tosú"
|
||||
@@ -2382,7 +2369,7 @@ title = "Deisiúchán"
|
||||
header = "PDF a dheisiú"
|
||||
submit = "Deisiúchán"
|
||||
description = "Déanfaidh an uirlis seo iarracht comhaid PDF truaillithe nó damáiste a dheisiú. Níl aon socruithe breise ag teastáil."
|
||||
filenamePrefix = "deisithe"
|
||||
filenamePrefix = "repaired"
|
||||
|
||||
[repair.files]
|
||||
placeholder = "Roghnaigh comhad PDF sa phríomh-amharc chun tosú"
|
||||
@@ -2583,7 +2570,7 @@ stopButton = "Stop comparáid"
|
||||
[certSign]
|
||||
tags = "fíordheimhnigh, PEM, P12, oifigiúil, criptigh"
|
||||
title = "Síniú Teastais"
|
||||
filenamePrefix = "síníthe"
|
||||
filenamePrefix = "signed"
|
||||
chooseCertificate = "Roghnaigh Comhad Teastais"
|
||||
chooseJksFile = "Roghnaigh Comhad JKS"
|
||||
chooseP12File = "Roghnaigh Comhad PKCS12"
|
||||
@@ -2717,7 +2704,7 @@ header = "Bain an deimhniú digiteach ó PDF"
|
||||
selectPDF = "Roghnaigh comhad PDF:"
|
||||
submit = "Bain Síniú"
|
||||
description = "Bainfidh an uirlis seo sínithe teastais dhigiteacha de do dhoiciméad PDF."
|
||||
filenamePrefix = "neamhshínithe"
|
||||
filenamePrefix = "unsigned"
|
||||
|
||||
[removeCertSign.files]
|
||||
placeholder = "Roghnaigh comhad PDF sa phríomh-amharc chun tosú"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Sínigh isteach le do thoil"
|
||||
ssoSignIn = "Logáil isteach trí Chlárú Aonair"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Uath-Chruthaigh Úsáideoir faoi Mhíchumas"
|
||||
oAuth2AdminBlockedUser = "Tá bac faoi láthair ar chlárú nó logáil isteach úsáideoirí neamhchláraithe. Déan teagmháil leis an riarthóir le do thoil."
|
||||
oAuth2RequiresLicense = "Teastaíonn ceadúnas íoctha (Server nó Enterprise) chun logáil isteach le OAuth/SSO. Déan teagmháil leis an riarthóir chun do phlean a uasghrádú."
|
||||
saml2RequiresLicense = "Teastaíonn ceadúnas íoctha (Server nó Enterprise) chun logáil isteach le SAML. Déan teagmháil leis an riarthóir chun do phlean a uasghrádú."
|
||||
maxUsersReached = "Sroicheadh an líon uasta úsáideoirí do do cheadúnas reatha. Déan teagmháil leis an riarthóir chun do phlean a uasghrádú nó suíocháin bhreise a chur leis."
|
||||
oauth2RequestNotFound = "Níor aimsíodh iarratas údaraithe"
|
||||
oauth2InvalidUserInfoResponse = "Freagra Neamhbhailí Faisnéise Úsáideora"
|
||||
oauth2invalidRequest = "Iarratas Neamhbhailí"
|
||||
@@ -3552,7 +3536,7 @@ title = "PDF go leathanach amháin"
|
||||
header = "PDF go leathanach amháin"
|
||||
submit = "Tiontaigh go Leathanach Aonair"
|
||||
description = "Cuirfidh an uirlis seo gach leathanach de do PDF le chéile in aon leathanach mór amháin. Fanfaidh an leithead mar an gcéanna leis na leathanaigh bhunaidh, ach beidh an airde cothrom le suim airde na leathanach go léir."
|
||||
filenamePrefix = "leathanach_aonair"
|
||||
filenamePrefix = "single_page"
|
||||
|
||||
[pdfToSinglePage.files]
|
||||
placeholder = "Roghnaigh comhad PDF sa phríomh-amharc chun tosú"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Oiriúnaigh don Leithead"
|
||||
actualSize = "Fíormhéid"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Ní féidir an comhad a réamhamharc."
|
||||
dualPageView = "Amharc Dhá Leathanach"
|
||||
firstPage = "An Chéad Leathanach"
|
||||
lastPage = "An Leathanach Deireanach"
|
||||
nextPage = "Leathanach Ar Aghaidh"
|
||||
onlyPdfSupported = "Ní thacaíonn an t-amharcán ach le comhaid PDF. Is cosúil gur formáid eile é an comhad seo."
|
||||
previousPage = "Leathanach Roimhe Seo"
|
||||
singlePageView = "Amharc Leathanach Aonair"
|
||||
unknownFile = "Comhad anaithnid"
|
||||
nextPage = "Leathanach Ar Aghaidh"
|
||||
zoomIn = "Súmáil Isteach"
|
||||
zoomOut = "Súmáil Amach"
|
||||
singlePageView = "Amharc Leathanach Aonair"
|
||||
dualPageView = "Amharc Dhá Leathanach"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Dún na Comhaid Roghnaithe"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Athraigh an Barra Taoibh"
|
||||
exportSelected = "Easpórtáil na Leathanaigh Roghnaithe"
|
||||
toggleAnnotations = "Athraigh Infheictheacht Anótálacha"
|
||||
annotationMode = "Athraigh Mód Anótála"
|
||||
print = "Priontáil PDF"
|
||||
draw = "Tarraing"
|
||||
save = "Sábháil"
|
||||
saveChanges = "Sábháil Athruithe"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL nó ainm comhaid don impressum (riachtanach i roinnt dlínsí
|
||||
title = "Préimh & Fiontar"
|
||||
description = "Cumraigh do eochair cheadúnais préimhe nó fiontair."
|
||||
license = "Cumraíocht Ceadúnais"
|
||||
noInput = "Tabhair eochair nó comhad ceadúnais, le do thoil"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "An bhfuil eochair cheadúnais nó comhad teastais agat?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Ní féidir forshcríobh ar do eochair cheadúnais reatha a chealú."
|
||||
line2 = "Caillefar do cheadúnas roimhe seo go buan mura bhfuil cúltaca de in áit eile agat."
|
||||
line3 = "Tábhachtach: Coinnigh eochracha ceadúnais príobháideach agus slán. Ná roinn go poiblí riamh."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Eochair Ceadúnais"
|
||||
file = "Comhad Teastais"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Comhad Teastais Ceadúnais"
|
||||
description = "Uaslódáil do chomhad ceadúnais .lic nó .cert ó cheannacháin as líne"
|
||||
choose = "Roghnaigh Comhad Ceadúnais"
|
||||
selected = "Roghnaithe: {{filename}} ({{size}})"
|
||||
successMessage = "D’éirigh le huaslódáil agus gníomhachtú an chomhaid cheadúnais. Níl atosú ag teastáil."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Ceadúnas Gníomhach"
|
||||
file = "Foinse: Comhad ceadúnais ({{path}})"
|
||||
key = "Foinse: Eochair ceadúnais"
|
||||
type = "Cineál: {{type}}"
|
||||
noInput = "Tabhair eochair ceadúnais nó uaslódáil comhad teastais, le do thoil"
|
||||
success = "Rath"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Cumasaigh Gnéithe Préimhe"
|
||||
description = "Cumasaigh seiceálacha eochrach ceadúnais do ghnéithe pro/fiontair"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} roghnaithe"
|
||||
download = "Íosluchtaigh"
|
||||
delete = "Scrios"
|
||||
unsupported = "Gan tacaíocht"
|
||||
active = "Gníomhach"
|
||||
addToUpload = "Cuir leis an Uaslódáil"
|
||||
closeFile = "Dún an comhad"
|
||||
deleteAll = "Scrios Uile"
|
||||
loadingFiles = "Comhaid á Luchtú..."
|
||||
noFiles = "Níl comhaid ar fáil"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Tá ar a laghad seoladh ríomhphoist amháin de dhíth"
|
||||
submit = "Seol Cuirí"
|
||||
success = "Tugadh cuireadh d’úsáideoir(í) go rathúil"
|
||||
partialFailure = "Níor éirigh le roinnt cuirí"
|
||||
partialSuccess = "Theip ar chuid de na cuirí"
|
||||
allFailed = "Theip ar úsáideoirí a thabhairt isteach"
|
||||
error = "Theip ar churí a sheoladh"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "Logáil Isteach"
|
||||
signInWith = "Sínigh isteach le"
|
||||
oauthPending = "Brabhsálaí á oscailt le haghaidh fíordheimhnithe..."
|
||||
orContinueWith = "Nó lean ar aghaidh le ríomhphost"
|
||||
serverRequirement = "Nóta: Ní mór an cumas logála isteach a bheith cumasaithe ar an bhfreastalaí."
|
||||
showInstructions = "Conas é a chumasú?"
|
||||
hideInstructions = "Folaigh na treoracha"
|
||||
instructions = "Chun logáil isteach a chumasú ar do fhreastalaí Stirling PDF:"
|
||||
instructionsEnvVar = "Socraigh an athróg chomhshaoil:"
|
||||
instructionsOrYml = "Nó i settings.yml:"
|
||||
instructionsRestart = "Ansin atosaigh do fhreastalaí chun go mbeidh na hathruithe i bhfeidhm."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Ainm Úsáideora"
|
||||
|
||||
@@ -131,7 +131,7 @@ unsupported = "असमर्थित"
|
||||
|
||||
[toolPanel]
|
||||
placeholder = "शुरू करने के लिए कोई टूल चुनें"
|
||||
alpha = "अल्फा"
|
||||
alpha = "Alpha"
|
||||
premiumFeature = "प्रीमियम फीचर:"
|
||||
comingSoon = "जल्द आ रहा है:"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "पसंदीदा से हटाएं"
|
||||
fullscreen = "फुलस्क्रीन मोड पर स्विच करें"
|
||||
sidebar = "साइडबार मोड पर स्विच करें"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "बैकएंड नहीं मिला"
|
||||
retry = "पुनः प्रयास करें"
|
||||
unreachable = "एप्लिकेशन फिलहाल बैकएंड से कनेक्ट नहीं हो पा रहा है। कृपया बैकएंड की स्थिति और नेटवर्क कनेक्टिविटी जांचें, फिर पुनः प्रयास करें।"
|
||||
|
||||
[zipWarning]
|
||||
title = "बड़ी ZIP फ़ाइल"
|
||||
message = "इस ZIP में {{count}} फ़ाइलें हैं। फिर भी निकालें?"
|
||||
@@ -374,7 +369,7 @@ privacy = "गोपनीयता"
|
||||
|
||||
[settings.developer]
|
||||
title = "डेवलपर"
|
||||
apiKeys = "API कुंजियाँ"
|
||||
apiKeys = "API Keys"
|
||||
|
||||
[settings.tooltips]
|
||||
enableLoginFirst = "पहले लॉगिन मोड सक्षम करें"
|
||||
@@ -919,7 +914,7 @@ title = "PDF ओवरले करें"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF टेक्स्ट एडिटर"
|
||||
desc = "PDF फ़ाइलों के भीतर मौजूदा टेक्स्ट और इमेज संपादित करें"
|
||||
desc = "ग्रुप्ड टेक्स्ट एडिटिंग और PDF पुनर्जनन के साथ Stirling PDF JSON एक्सपोर्ट की समीक्षा व संपादन करें"
|
||||
|
||||
[home.addText]
|
||||
tags = "text,annotation,label"
|
||||
@@ -1181,7 +1176,7 @@ selectFilesPlaceholder = "शुरू करने के लिए मुख
|
||||
settings = "सेटिंग्स"
|
||||
conversionCompleted = "रूपांतरण पूरा हुआ"
|
||||
results = "परिणाम"
|
||||
defaultFilename = "परिवर्तित_फ़ाइल"
|
||||
defaultFilename = "converted_file"
|
||||
conversionResults = "रूपांतरण परिणाम"
|
||||
convertFrom = "से रूपांतरित करें"
|
||||
convertTo = "में रूपांतरित करें"
|
||||
@@ -1224,8 +1219,8 @@ wordDocExt = "Word दस्तावेज़ (.docx)"
|
||||
odtExt = "OpenDocument Text (.odt)"
|
||||
pptExt = "PowerPoint (.pptx)"
|
||||
odpExt = "OpenDocument Presentation (.odp)"
|
||||
txtExt = "सादा पाठ (.txt)"
|
||||
rtfExt = "रिच टेक्स्ट फ़ॉर्मेट (.rtf)"
|
||||
txtExt = "Plain Text (.txt)"
|
||||
rtfExt = "Rich Text Format (.rtf)"
|
||||
selectedFiles = "चयनित फ़ाइलें"
|
||||
noFileSelected = "कोई फ़ाइल चयनित नहीं। फ़ाइलें जोड़ने के लिए फ़ाइल पैनल का उपयोग करें।"
|
||||
convertFiles = "फ़ाइलें रूपांतरित करें"
|
||||
@@ -1368,7 +1363,7 @@ title = "वॉटरमार्क जोड़ें"
|
||||
desc = "PDF फ़ाइलों में टेक्स्ट या इमेज वॉटरमार्क जोड़ें"
|
||||
completed = "वॉटरमार्क जोड़ा गया"
|
||||
submit = "वॉटरमार्क जोड़ें"
|
||||
filenamePrefix = "वॉटरमार्क_युक्त"
|
||||
filenamePrefix = "watermarked"
|
||||
|
||||
[watermark.error]
|
||||
failed = "PDF में वॉटरमार्क जोड़ते समय एक त्रुटि हुई।"
|
||||
@@ -1643,7 +1638,7 @@ subtitle = "प्रोसेस्ड फ़ाइल डाउनलोड
|
||||
[removePages]
|
||||
tags = "पृष्ठ निकालें,पृष्ठ हटाएं"
|
||||
title = "निकालें"
|
||||
filenamePrefix = "पृष्ठ_हटाए_गए"
|
||||
filenamePrefix = "pages_removed"
|
||||
submit = "निकालें"
|
||||
|
||||
[removePages.pageNumbers]
|
||||
@@ -1845,7 +1840,7 @@ title = "फॉर्म फ़ील्ड से Read-Only हटाएं"
|
||||
header = "PDF फॉर्म अनलॉक करें"
|
||||
submit = "Remove"
|
||||
description = "यह टूल PDF फॉर्म फ़ील्ड से Read-Only प्रतिबंध हटाएगा, जिससे वे संपादन योग्य और भरने योग्य बनेंगे।"
|
||||
filenamePrefix = "अनलॉक_फ़ॉर्म"
|
||||
filenamePrefix = "unlocked_forms"
|
||||
|
||||
[unlockPDFForms.files]
|
||||
placeholder = "शुरू करने के लिए मुख्य दृश्य में एक PDF फ़ाइल चुनें"
|
||||
@@ -1859,7 +1854,7 @@ title = "अनलॉक किए गए फॉर्म के परिणा
|
||||
[changeMetadata]
|
||||
header = "मेटाडेटा बदलें"
|
||||
submit = "बदलें"
|
||||
filenamePrefix = "मेटाडेटा"
|
||||
filenamePrefix = "metadata"
|
||||
|
||||
[changeMetadata.settings]
|
||||
title = "मेटाडेटा सेटिंग्स"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "ड्रॉइंग हस्ताक्षर"
|
||||
defaultImageLabel = "अपलोड किया गया हस्ताक्षर"
|
||||
defaultTextLabel = "टाइप किया हुआ हस्ताक्षर"
|
||||
saveButton = "हस्ताक्षर सहेजें"
|
||||
savePersonal = "व्यक्तिगत सहेजें"
|
||||
saveShared = "साझा सहेजें"
|
||||
saveUnavailable = "सेव करने के लिए पहले एक हस्ताक्षर बनाएँ।"
|
||||
noChanges = "वर्तमान हस्ताक्षर पहले से सहेजा गया है।"
|
||||
tempStorageTitle = "अस्थायी ब्राउज़र संग्रहण"
|
||||
tempStorageDescription = "हस्ताक्षर केवल आपके ब्राउज़र में संग्रहीत होते हैं। ब्राउज़र डेटा साफ़ करने या ब्राउज़र बदलने पर वे खो जाएंगे।"
|
||||
personalHeading = "व्यक्तिगत हस्ताक्षर"
|
||||
sharedHeading = "साझा हस्ताक्षर"
|
||||
personalDescription = "इन हस्ताक्षरों को केवल आप देख सकते हैं।"
|
||||
sharedDescription = "सभी उपयोगकर्ता इन हस्ताक्षरों को देख और उपयोग कर सकते हैं।"
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "ड्रॉइंग"
|
||||
@@ -2334,7 +2321,7 @@ title = "समतल करें"
|
||||
header = "PDF समतल करें"
|
||||
flattenOnlyForms = "केवल फ़ॉर्म समतल करें"
|
||||
submit = "समतल करें"
|
||||
filenamePrefix = "समतलीकृत"
|
||||
filenamePrefix = "flattened"
|
||||
|
||||
[flatten.files]
|
||||
placeholder = "शुरू करने के लिए मुख्य दृश्य में एक PDF फ़ाइल चुनें"
|
||||
@@ -2382,7 +2369,7 @@ title = "मरम्मत"
|
||||
header = "PDF मरम्मत"
|
||||
submit = "मरम्मत"
|
||||
description = "यह टूल भ्रष्ट या क्षतिग्रस्त PDF फ़ाइलों की मरम्मत करने का प्रयास करेगा। कोई अतिरिक्त सेटिंग्स आवश्यक नहीं हैं।"
|
||||
filenamePrefix = "मरम्मत_किया"
|
||||
filenamePrefix = "repaired"
|
||||
|
||||
[repair.files]
|
||||
placeholder = "शुरू करने के लिए मुख्य दृश्य में एक PDF फ़ाइल चुनें"
|
||||
@@ -2583,7 +2570,7 @@ stopButton = "तुलना रोकें"
|
||||
[certSign]
|
||||
tags = "प्रमाणीकरण,PEM,P12,आधिकारिक,एन्क्रिप्ट"
|
||||
title = "प्रमाणपत्र हस्ताक्षर"
|
||||
filenamePrefix = "हस्ताक्षरित"
|
||||
filenamePrefix = "signed"
|
||||
chooseCertificate = "प्रमाणपत्र फ़ाइल चुनें"
|
||||
chooseJksFile = "JKS फ़ाइल चुनें"
|
||||
chooseP12File = "PKCS12 फ़ाइल चुनें"
|
||||
@@ -2717,7 +2704,7 @@ header = "PDF से डिजिटल प्रमाणपत्र हटा
|
||||
selectPDF = "PDF फ़ाइल चुनें:"
|
||||
submit = "हस्ताक्षर हटाएं"
|
||||
description = "यह टूल आपके PDF दस्तावेज़ से डिजिटल प्रमाणपत्र हस्ताक्षर हटाएगा।"
|
||||
filenamePrefix = "अनहस्ताक्षरित"
|
||||
filenamePrefix = "unsigned"
|
||||
|
||||
[removeCertSign.files]
|
||||
placeholder = "शुरू करने के लिए मुख्य दृश्य में एक PDF फ़ाइल चुनें"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "कृपया साइन इन करें"
|
||||
ssoSignIn = "सिंगल साइन-ऑन के माध्यम से लॉगिन करें"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 स्वतः उपयोगकर्ता निर्माण अक्षम है"
|
||||
oAuth2AdminBlockedUser = "गैर-पंजीकृत उपयोगकर्ताओं का पंजीकरण या लॉगिन वर्तमान में अवरुद्ध है। कृपया व्यवस्थापक से संपर्क करें।"
|
||||
oAuth2RequiresLicense = "OAuth/SSO लॉगिन के लिए पेड लाइसेंस (Server या Enterprise) आवश्यक है। कृपया अपना प्लान अपग्रेड करने के लिए व्यवस्थापक से संपर्क करें।"
|
||||
saml2RequiresLicense = "SAML लॉगिन के लिए पेड लाइसेंस (Server या Enterprise) आवश्यक है। कृपया अपना प्लान अपग्रेड करने के लिए व्यवस्थापक से संपर्क करें।"
|
||||
maxUsersReached = "आपके वर्तमान लाइसेंस के लिए उपयोगकर्ताओं की अधिकतम सीमा पूरी हो चुकी है। कृपया अपना प्लान अपग्रेड करने या अधिक सीटें जोड़ने के लिए व्यवस्थापक से संपर्क करें।"
|
||||
oauth2RequestNotFound = "प्राधिकरण अनुरोध नहीं मिला"
|
||||
oauth2InvalidUserInfoResponse = "अमान्य उपयोगकर्ता जानकारी प्रतिक्रिया"
|
||||
oauth2invalidRequest = "अमान्य अनुरोध"
|
||||
@@ -3552,7 +3536,7 @@ title = "PDF को एकल पृष्ठ में"
|
||||
header = "PDF को एकल पृष्ठ में"
|
||||
submit = "एकल पृष्ठ में बदलें"
|
||||
description = "यह टूल आपके PDF के सभी पृष्ठों को एक बड़े एकल पृष्ठ में मिला देगा। चौड़ाई मूल पृष्ठों जैसी ही रहेगी, पर ऊँचाई सभी पृष्ठ ऊँचाइयों का योग होगी।"
|
||||
filenamePrefix = "एकल_पृष्ठ"
|
||||
filenamePrefix = "single_page"
|
||||
|
||||
[pdfToSinglePage.files]
|
||||
placeholder = "शुरू करने के लिए मुख्य दृश्य में एक PDF फ़ाइल चुनें"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "चौड़ाई के अनुसार फिट करे
|
||||
actualSize = "वास्तविक आकार"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "फ़ाइल का पूर्वावलोकन नहीं किया जा सकता"
|
||||
dualPageView = "दोहरा पृष्ठ दृश्य"
|
||||
firstPage = "पहला पृष्ठ"
|
||||
lastPage = "अंतिम पृष्ठ"
|
||||
nextPage = "अगला पृष्ठ"
|
||||
onlyPdfSupported = "व्यूअर केवल PDF फ़ाइलों का समर्थन करता है। यह फ़ाइल किसी भिन्न फ़ॉर्मेट में प्रतीत होती है।"
|
||||
previousPage = "पिछला पृष्ठ"
|
||||
singlePageView = "एकल पृष्ठ दृश्य"
|
||||
unknownFile = "अज्ञात फ़ाइल"
|
||||
nextPage = "अगला पृष्ठ"
|
||||
zoomIn = "ज़ूम इन"
|
||||
zoomOut = "ज़ूम आउट"
|
||||
singlePageView = "एकल पृष्ठ दृश्य"
|
||||
dualPageView = "दोहरा पृष्ठ दृश्य"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "चयनित फ़ाइलें बंद करें"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "साइडबार टॉगल करें"
|
||||
exportSelected = "चयनित पृष्ठ निर्यात करें"
|
||||
toggleAnnotations = "एनोटेशन दृश्यता टॉगल करें"
|
||||
annotationMode = "एनोटेशन मोड टॉगल करें"
|
||||
print = "PDF प्रिंट करें"
|
||||
draw = "ड्रॉ"
|
||||
save = "सहेजें"
|
||||
saveChanges = "परिवर्तनों को सहेजें"
|
||||
@@ -4254,7 +4234,7 @@ label = "प्रदाता"
|
||||
description = "प्रमाणीकरण के लिए उपयोग किया जाने वाला OAuth2 प्रदाता"
|
||||
|
||||
[admin.settings.connections.oauth2.issuer]
|
||||
label = "जारीकर्ता URL"
|
||||
label = "Issuer URL"
|
||||
description = "OAuth2 प्रदाता का Issuer URL"
|
||||
|
||||
[admin.settings.connections.oauth2.clientId]
|
||||
@@ -4430,7 +4410,7 @@ description = "विस्तृत सिस्टम टेम्प डा
|
||||
label = "प्रोसेस एक्सीक्यूटर सीमाएँ"
|
||||
description = "प्रत्येक प्रोसेस एक्सीक्यूटर के लिए सेशन सीमाएँ और टाइमआउट कॉन्फ़िगर करें"
|
||||
libreOffice = "LibreOffice"
|
||||
pdfToHtml = "PDF से HTML"
|
||||
pdfToHtml = "PDF to HTML"
|
||||
qpdf = "QPDF"
|
||||
tesseract = "Tesseract OCR"
|
||||
pythonOpenCv = "Python OpenCV"
|
||||
@@ -4517,7 +4497,6 @@ description = "Impressum का URL या फ़ाइल नाम (कुछ
|
||||
title = "प्रीमियम और एंटरप्राइज़"
|
||||
description = "अपनी प्रीमियम या एंटरप्राइज़ लाइसेंस कुंजी कॉन्फ़िगर करें।"
|
||||
license = "लाइसेंस कॉन्फ़िगरेशन"
|
||||
noInput = "कृपया लाइसेंस कुंजी या फ़ाइल प्रदान करें"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "क्या आपके पास लाइसेंस की या सर्टिफिकेट फ़ाइल है?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "वर्तमान लाइसेंस की को ओवरर
|
||||
line2 = "यदि आपने कहीं और बैकअप नहीं रखा है तो आपका पिछला लाइसेंस स्थायी रूप से खो जाएगा।"
|
||||
line3 = "महत्वपूर्ण: लाइसेंस की को निजी और सुरक्षित रखें। इन्हें कभी सार्वजनिक रूप से साझा न करें।"
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "लाइसेंस कुंजी"
|
||||
file = "प्रमाणपत्र फ़ाइल"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "लाइसेंस प्रमाणपत्र फ़ाइल"
|
||||
description = "ऑफ़लाइन खरीद से अपनी .lic या .cert लाइसेंस फ़ाइल अपलोड करें"
|
||||
choose = "लाइसेंस फ़ाइल चुनें"
|
||||
selected = "चयनित: {{filename}} ({{size}})"
|
||||
successMessage = "लाइसेंस फ़ाइल सफलतापूर्वक अपलोड और सक्रिय की गई। पुनः आरंभ की आवश्यकता नहीं।"
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "सक्रिय लाइसेंस"
|
||||
file = "स्रोत: लाइसेंस फ़ाइल ({{path}})"
|
||||
key = "स्रोत: लाइसेंस कुंजी"
|
||||
type = "प्रकार: {{type}}"
|
||||
noInput = "कृपया लाइसेंस कुंजी प्रदान करें या एक प्रमाणपत्र फ़ाइल अपलोड करें"
|
||||
success = "सफलता"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "प्रीमियम फ़ीचर्स सक्रिय करें"
|
||||
description = "प्रो/एंटरप्राइज़ फ़ीचर्स के लिए लाइसेंस कुंजी जाँच सक्षम करें"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} चयनित"
|
||||
download = "डाउनलोड करें"
|
||||
delete = "हटाएं"
|
||||
unsupported = "असमर्थित"
|
||||
active = "सक्रिय"
|
||||
addToUpload = "अपलोड में जोड़ें"
|
||||
closeFile = "फ़ाइल बंद करें"
|
||||
deleteAll = "सब हटाएँ"
|
||||
loadingFiles = "फ़ाइलें लोड हो रही हैं..."
|
||||
noFiles = "कोई फ़ाइल उपलब्ध नहीं"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "कम से कम एक ईमेल पता आवश्यक है"
|
||||
submit = "आमंत्रण भेजें"
|
||||
success = "उपयोगकर्ता(ओं) को सफलतापूर्वक आमंत्रित किया गया"
|
||||
partialFailure = "कुछ निमंत्रण विफल हुए"
|
||||
partialSuccess = "कुछ आमंत्रण विफल रहे"
|
||||
allFailed = "उपयोगकर्ताओं को आमंत्रित करने में विफल"
|
||||
error = "आमंत्रण भेजने में विफल"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "लॉगिन"
|
||||
signInWith = "इसके साथ साइन इन करें"
|
||||
oauthPending = "प्रमाणीकरण के लिए ब्राउज़र खुल रहा है..."
|
||||
orContinueWith = "या ईमेल के साथ जारी रखें"
|
||||
serverRequirement = "ध्यान दें: सर्वर पर लॉगिन सक्षम होना चाहिए।"
|
||||
showInstructions = "कैसे सक्षम करें?"
|
||||
hideInstructions = "निर्देश छिपाएँ"
|
||||
instructions = "अपने Stirling PDF सर्वर पर लॉगिन सक्षम करने के लिए:"
|
||||
instructionsEnvVar = "एन्वायरनमेंट वेरिएबल सेट करें:"
|
||||
instructionsOrYml = "या settings.yml में:"
|
||||
instructionsRestart = "इसके बाद बदलाव प्रभावी करने के लिए अपना सर्वर पुनः प्रारंभ करें।"
|
||||
|
||||
[setup.login.username]
|
||||
label = "उपयोगकर्ता नाम"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Ukloni iz omiljenih"
|
||||
fullscreen = "Prebaci na način cijelog zaslona"
|
||||
sidebar = "Prebaci na način bočne trake"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend nije pronađen"
|
||||
retry = "Pokušaj ponovno"
|
||||
unreachable = "Aplikacija se trenutačno ne može povezati s backendom. Provjerite status backenda i mrežnu povezanost, zatim pokušajte ponovno."
|
||||
|
||||
[zipWarning]
|
||||
title = "Velika ZIP datoteka"
|
||||
message = "Ovaj ZIP sadrži {{count}} datoteka. Ipak izdvojiti?"
|
||||
@@ -918,8 +913,8 @@ desc = "Preklapa PDF-ove na drugi PDF"
|
||||
title = "Preklapanje PDF-ova"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Uređivač teksta PDF-a"
|
||||
desc = "Uređujte postojeći tekst i slike unutar PDF-ova"
|
||||
title = "PDF uređivač teksta"
|
||||
desc = "Pregledajte i uredite Stirling PDF JSON izvoze s grupnim uređivanjem teksta i ponovnim generiranjem PDF-a"
|
||||
|
||||
[home.addText]
|
||||
tags = "tekst,anotacija,oznaka"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Crtani potpis"
|
||||
defaultImageLabel = "Učitani potpis"
|
||||
defaultTextLabel = "Upisani potpis"
|
||||
saveButton = "Spremi potpis"
|
||||
savePersonal = "Spremi osobno"
|
||||
saveShared = "Spremi dijeljeno"
|
||||
saveUnavailable = "Najprije izradite potpis da biste ga spremili."
|
||||
noChanges = "Trenutačni potpis je već spremljen."
|
||||
tempStorageTitle = "Privremena pohrana u pregledniku"
|
||||
tempStorageDescription = "Potpisi se pohranjuju samo u vašem pregledniku. Izgubit će se ako očistite podatke preglednika ili promijenite preglednik."
|
||||
personalHeading = "Osobni potpisi"
|
||||
sharedHeading = "Dijeljeni potpisi"
|
||||
personalDescription = "Samo vi možete vidjeti ove potpise."
|
||||
sharedDescription = "Svi korisnici mogu vidjeti i koristiti ove potpise."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Crtanje"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Molimo vas da se prijavite"
|
||||
ssoSignIn = "Prijavite se putem jedinstvene prijave"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 automatsko kreiranje korisnika je onemogućeno"
|
||||
oAuth2AdminBlockedUser = "Registracija ili prijava nekadreguiranih korisnika trenutno su blokirane. Molimo Vas da kontaktirate administratora."
|
||||
oAuth2RequiresLicense = "Prijava putem OAuth/SSO zahtijeva plaćenu licencu (Server ili Enterprise). Obratite se administratoru radi nadogradnje vašeg plana."
|
||||
saml2RequiresLicense = "Prijava putem SAML zahtijeva plaćenu licencu (Server ili Enterprise). Obratite se administratoru radi nadogradnje vašeg plana."
|
||||
maxUsersReached = "Dosegnut je maksimalan broj korisnika za vašu trenutačnu licencu. Obratite se administratoru radi nadogradnje plana ili dodavanja dodatnih mjesta."
|
||||
oauth2RequestNotFound = "Zahtjev za autorizaciju nije pronađen"
|
||||
oauth2InvalidUserInfoResponse = "Nevažeće informacije o korisniku"
|
||||
oauth2invalidRequest = "Neispravan zahtjev"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Prilagodi širini"
|
||||
actualSize = "Stvarna veličina"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Nije moguće pregledati datoteku"
|
||||
dualPageView = "Prikaz dviju stranica"
|
||||
firstPage = "Prva stranica"
|
||||
lastPage = "Zadnja stranica"
|
||||
nextPage = "Sljedeća stranica"
|
||||
onlyPdfSupported = "Preglednik podržava samo PDF datoteke. Čini se da je ova datoteka u drugačijem formatu."
|
||||
previousPage = "Prethodna stranica"
|
||||
singlePageView = "Prikaz jedne stranice"
|
||||
unknownFile = "Nepoznata datoteka"
|
||||
nextPage = "Sljedeća stranica"
|
||||
zoomIn = "Povećaj"
|
||||
zoomOut = "Umanji"
|
||||
singlePageView = "Prikaz jedne stranice"
|
||||
dualPageView = "Prikaz dviju stranica"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Zatvori odabrane datoteke"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Prebaci bočnu traku"
|
||||
exportSelected = "Izvezi odabrane stranice"
|
||||
toggleAnnotations = "Prebaci vidljivost bilješki"
|
||||
annotationMode = "Prebaci način bilješki"
|
||||
print = "Ispis PDF-a"
|
||||
draw = "Crtaj"
|
||||
save = "Spremi"
|
||||
saveChanges = "Spremi promjene"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL ili naziv datoteke za impresum (obvezno u nekim nadležnostim
|
||||
title = "Premium i Enterprise"
|
||||
description = "Konfigurirajte svoj premium ili enterprise licencni ključ."
|
||||
license = "Konfiguracija licence"
|
||||
noInput = "Molimo navedite licencni ključ ili datoteku"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Imate licencni ključ ili datoteku certifikata?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Prepisivanje vašeg trenutačnog licencnog ključa ne može se poništi
|
||||
line2 = "Vaša će prethodna licenca trajno biti izgubljena osim ako je niste sigurnosno kopirali drugdje."
|
||||
line3 = "Važno: Licencne ključeve držite privatnima i sigurnima. Nikada ih javno ne dijelite."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Licencni ključ"
|
||||
file = "Datoteka certifikata"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Datoteka certifikata licence"
|
||||
description = "Učitajte svoju .lic ili .cert licencnu datoteku iz izvanmrežnih kupnji"
|
||||
choose = "Odaberite licencnu datoteku"
|
||||
selected = "Odabrano: {{filename}} ({{size}})"
|
||||
successMessage = "Licencna datoteka je uspješno učitana i aktivirana. Nije potrebno ponovno pokretanje."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Aktivna licenca"
|
||||
file = "Izvor: Licencna datoteka ({{path}})"
|
||||
key = "Izvor: Licencni ključ"
|
||||
type = "Vrsta: {{type}}"
|
||||
noInput = "Navedite licencni ključ ili učitajte datoteku certifikata"
|
||||
success = "Uspjeh"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Omogući premium značajke"
|
||||
description = "Omogući provjere licencnog ključa za pro/enterprise značajke"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} odabrano"
|
||||
download = "Preuzmi datoteku"
|
||||
delete = "Izbriši"
|
||||
unsupported = "Nepodržano"
|
||||
active = "Aktivno"
|
||||
addToUpload = "Dodaj za otpremu"
|
||||
closeFile = "Zatvori datoteku"
|
||||
deleteAll = "Izbriši sve"
|
||||
loadingFiles = "Učitavanje datoteka..."
|
||||
noFiles = "Nema dostupnih datoteka"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Potreban je barem jedan e-mail"
|
||||
submit = "Pošalji pozive"
|
||||
success = "Korisnici su uspješno pozvani"
|
||||
partialFailure = "Neke pozivnice nisu uspjele"
|
||||
partialSuccess = "Neki pozivi nisu uspjeli"
|
||||
allFailed = "Pozivanje korisnika nije uspjelo"
|
||||
error = "Slanje poziva nije uspjelo"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "Prijava"
|
||||
signInWith = "Prijavite se pomoću"
|
||||
oauthPending = "Otvaranje preglednika za autentikaciju..."
|
||||
orContinueWith = "Ili nastavite s e-poštom"
|
||||
serverRequirement = "Napomena: Poslužitelj mora imati omogućenu prijavu."
|
||||
showInstructions = "Kako omogućiti?"
|
||||
hideInstructions = "Sakrij upute"
|
||||
instructions = "Da biste omogućili prijavu na svom Stirling PDF poslužitelju:"
|
||||
instructionsEnvVar = "Postavite varijablu okruženja:"
|
||||
instructionsOrYml = "Ili u settings.yml:"
|
||||
instructionsRestart = "Zatim ponovno pokrenite poslužitelj kako bi promjene stupile na snagu."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Korisničko ime"
|
||||
@@ -5892,7 +5843,7 @@ paragraph = "Stranica s odlomcima"
|
||||
sparse = "Rijedak tekst"
|
||||
|
||||
[pdfTextEditor.groupingMode]
|
||||
auto = "Automatski"
|
||||
auto = "Auto"
|
||||
paragraph = "Odlomak"
|
||||
singleLine = "Jedan redak"
|
||||
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Eltávolítás a kedvencekből"
|
||||
fullscreen = "Váltás teljes képernyős módra"
|
||||
sidebar = "Váltás oldalsáv módra"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend nem található"
|
||||
retry = "Próbálja újra"
|
||||
unreachable = "Az alkalmazás jelenleg nem tud csatlakozni a Backendhez. Ellenőrizze a Backend állapotát és a hálózati kapcsolatot, majd próbálja újra."
|
||||
|
||||
[zipWarning]
|
||||
title = "Nagy ZIP fájl"
|
||||
message = "Ez a ZIP {{count}} fájlt tartalmaz. Mégis kibontja?"
|
||||
@@ -919,7 +914,7 @@ title = "PDF-ek egymásra helyezése"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF szövegszerkesztő"
|
||||
desc = "Meglévő szöveg és képek szerkesztése a PDF-ekben"
|
||||
desc = "Nézze át és szerkessze a Stirling PDF JSON exportokat csoportosított szövegszerkesztéssel és PDF-újragenerálással"
|
||||
|
||||
[home.addText]
|
||||
tags = "szöveg, megjegyzés, címke"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Rajzolt aláírás"
|
||||
defaultImageLabel = "Feltöltött aláírás"
|
||||
defaultTextLabel = "Gépelt aláírás"
|
||||
saveButton = "Aláírás mentése"
|
||||
savePersonal = "Mentés személyesként"
|
||||
saveShared = "Mentés megosztottként"
|
||||
saveUnavailable = "Előbb hozzon létre egy aláírást a mentéshez."
|
||||
noChanges = "Az aktuális aláírás már mentve van."
|
||||
tempStorageTitle = "Ideiglenes böngészőbeli tárolás"
|
||||
tempStorageDescription = "Az aláírások csak a böngészőben tárolódnak. Elvesznek, ha törli a böngészőadatokat vagy böngészőt vált."
|
||||
personalHeading = "Személyes aláírások"
|
||||
sharedHeading = "Megosztott aláírások"
|
||||
personalDescription = "Csak Ön láthatja ezeket az aláírásokat."
|
||||
sharedDescription = "Minden felhasználó láthatja és használhatja ezeket az aláírásokat."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Rajz"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Kérjük, jelentkezzen be"
|
||||
ssoSignIn = "Bejelentkezés egyszeri bejelentkezéssel"
|
||||
oAuth2AutoCreateDisabled = "OAuth2 automatikus felhasználólétrehozás letiltva"
|
||||
oAuth2AdminBlockedUser = "A nem regisztrált felhasználók regisztrációja vagy bejelentkezése jelenleg le van tiltva. Kérjük, forduljon a rendszergazdához."
|
||||
oAuth2RequiresLicense = "Az OAuth/SSO bejelentkezés fizetős licencet igényel (Server vagy Enterprise). Kérjük, lépjen kapcsolatba az adminisztrátorral a csomag frissítéséhez."
|
||||
saml2RequiresLicense = "A SAML bejelentkezés fizetős licencet igényel (Server vagy Enterprise). Kérjük, lépjen kapcsolatba az adminisztrátorral a csomag frissítéséhez."
|
||||
maxUsersReached = "Elérte az aktuális licenchez tartozó felhasználók maximális számát. Kérjük, lépjen kapcsolatba az adminisztrátorral a csomag frissítéséhez vagy további felhasználói helyek hozzáadásához."
|
||||
oauth2RequestNotFound = "A hitelesítési kérés nem található"
|
||||
oauth2InvalidUserInfoResponse = "Érvénytelen felhasználói információ válasz"
|
||||
oauth2invalidRequest = "Érvénytelen kérés"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Szélességhez igazítás"
|
||||
actualSize = "Tényleges méret"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "A fájl előnézete nem lehetséges"
|
||||
dualPageView = "Kétoldalas nézet"
|
||||
firstPage = "Első oldal"
|
||||
lastPage = "Utolsó oldal"
|
||||
nextPage = "Következő oldal"
|
||||
onlyPdfSupported = "A megjelenítő csak PDF fájlokat támogat. Úgy tűnik, ez a fájl más formátumú."
|
||||
previousPage = "Előző oldal"
|
||||
singlePageView = "Egyoldalas nézet"
|
||||
unknownFile = "Ismeretlen fájl"
|
||||
nextPage = "Következő oldal"
|
||||
zoomIn = "Nagyítás"
|
||||
zoomOut = "Kicsinyítés"
|
||||
singlePageView = "Egyoldalas nézet"
|
||||
dualPageView = "Kétoldalas nézet"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Kijelölt fájlok bezárása"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Oldalsáv ki/be"
|
||||
exportSelected = "Kijelölt oldalak exportálása"
|
||||
toggleAnnotations = "Jegyzetek láthatóságának váltása"
|
||||
annotationMode = "Jegyzetelési mód váltása"
|
||||
print = "PDF nyomtatása"
|
||||
draw = "Rajzolás"
|
||||
save = "Mentés"
|
||||
saveChanges = "Változtatások mentése"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL vagy fájlnév az impresszumhoz (egyes joghatóságokban köt
|
||||
title = "Prémium és Vállalati"
|
||||
description = "Prémium vagy vállalati licenckulcs konfigurálása."
|
||||
license = "Licenckonfiguráció"
|
||||
noInput = "Kérjük, adjon meg egy licenckulcsot vagy fájlt"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Van licenckulcsa vagy tanúsítványfájlja?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "A jelenlegi licenckulcs felülírása nem vonható vissza."
|
||||
line2 = "A korábbi licenc végleg elveszik, hacsak nem készített róla máshol biztonsági másolatot."
|
||||
line3 = "Fontos: Tartsa a licenckulcsokat bizalmasan és biztonságban. Soha ne ossza meg nyilvánosan."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Licenckulcs"
|
||||
file = "Tanúsítványfájl"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Licenc tanúsítványfájl"
|
||||
description = "Töltse fel az offline vásárlásból származó .lic vagy .cert licencfájlt"
|
||||
choose = "Licencfájl kiválasztása"
|
||||
selected = "Kiválasztva: {{filename}} ({{size}})"
|
||||
successMessage = "A licencfájl feltöltése és aktiválása sikeres. Nincs szükség újraindításra."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Aktív licenc"
|
||||
file = "Forrás: licencfájl ({{path}})"
|
||||
key = "Forrás: licenckulcs"
|
||||
type = "Típus: {{type}}"
|
||||
noInput = "Adjon meg egy licenckulcsot, vagy töltsön fel tanúsítványfájlt"
|
||||
success = "Siker"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Prémium funkciók engedélyezése"
|
||||
description = "Licenckulcs-ellenőrzések engedélyezése a pro/vállalati funkciókhoz"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} kiválasztva"
|
||||
download = "Letöltés"
|
||||
delete = "Törlés"
|
||||
unsupported = "Nem támogatott"
|
||||
active = "Aktív"
|
||||
addToUpload = "Hozzáadás a feltöltéshez"
|
||||
closeFile = "Fájl bezárása"
|
||||
deleteAll = "Összes törlése"
|
||||
loadingFiles = "Fájlok betöltése..."
|
||||
noFiles = "Nem állnak rendelkezésre fájlok"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Legalább egy e-mail cím megadása szükséges"
|
||||
submit = "Meghívók küldése"
|
||||
success = "felhasználó sikeresen meghívva"
|
||||
partialFailure = "Néhány meghívás sikertelen volt"
|
||||
partialSuccess = "Néhány meghívó sikertelen volt"
|
||||
allFailed = "Nem sikerült meghívni a felhasználókat"
|
||||
error = "Nem sikerült elküldeni a meghívókat"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "Bejelentkezés"
|
||||
signInWith = "Bejelentkezés ezzel"
|
||||
oauthPending = "Böngésző megnyitása hitelesítéshez..."
|
||||
orContinueWith = "Vagy folytassa e-maillel"
|
||||
serverRequirement = "Megjegyzés: A szerveren engedélyezni kell a bejelentkezést."
|
||||
showInstructions = "Hogyan engedélyezhető?"
|
||||
hideInstructions = "Utasítások elrejtése"
|
||||
instructions = "A bejelentkezés engedélyezéséhez a Stirling PDF szerverén:"
|
||||
instructionsEnvVar = "Állítsa be a környezeti változót:"
|
||||
instructionsOrYml = "Vagy a settings.yml-ben:"
|
||||
instructionsRestart = "Ezután indítsa újra a szervert, hogy a módosítások életbe lépjenek."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Felhasználónév"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Hapus dari Favorit"
|
||||
fullscreen = "Beralih ke mode layar penuh"
|
||||
sidebar = "Beralih ke mode bilah sisi"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend tidak ditemukan"
|
||||
retry = "Coba lagi"
|
||||
unreachable = "Aplikasi saat ini tidak dapat terhubung ke backend. Periksa status backend dan konektivitas jaringan, lalu coba lagi."
|
||||
|
||||
[zipWarning]
|
||||
title = "File ZIP Besar"
|
||||
message = "ZIP ini berisi {{count}} file. Tetap ekstrak?"
|
||||
@@ -195,7 +190,7 @@ title = "Pengaturan Dibuka"
|
||||
message = "Silakan pilih Stirling PDF di pengaturan sistem Anda"
|
||||
|
||||
[defaultApp.error]
|
||||
title = "Kesalahan"
|
||||
title = "Error"
|
||||
message = "Gagal menyetel penangan PDF default"
|
||||
|
||||
[language]
|
||||
@@ -388,7 +383,7 @@ logout = "Keluar"
|
||||
|
||||
[settings.connection.mode]
|
||||
saas = "Stirling Cloud"
|
||||
selfhosted = "Dihost Sendiri"
|
||||
selfhosted = "Self-Hosted"
|
||||
|
||||
[settings.general]
|
||||
title = "Umum"
|
||||
@@ -549,8 +544,8 @@ usage = "Lihat Penggunaan"
|
||||
[endpointStatistics]
|
||||
title = "Statistik Endpoint"
|
||||
header = "Statistik Endpoint"
|
||||
top10 = "10 Teratas"
|
||||
top20 = "20 Teratas"
|
||||
top10 = "Top 10"
|
||||
top20 = "Top 20"
|
||||
all = "Semua"
|
||||
refresh = "Muat Ulang"
|
||||
dataTypeLabel = "Tipe Data:"
|
||||
@@ -919,7 +914,7 @@ title = "Tumpuk PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Editor Teks PDF"
|
||||
desc = "Edit teks dan gambar yang ada di dalam PDF"
|
||||
desc = "Tinjau dan edit ekspor Stirling PDF JSON dengan pengeditan teks terkelompok dan pembuatan ulang PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "teks,anotasi,label"
|
||||
@@ -1181,7 +1176,7 @@ selectFilesPlaceholder = "Pilih file di tampilan utama untuk memulai"
|
||||
settings = "Pengaturan"
|
||||
conversionCompleted = "Konversi selesai"
|
||||
results = "Hasil"
|
||||
defaultFilename = "file_terkonversi"
|
||||
defaultFilename = "converted_file"
|
||||
conversionResults = "Hasil Konversi"
|
||||
convertFrom = "Konversi dari"
|
||||
convertTo = "Konversi ke"
|
||||
@@ -1368,7 +1363,7 @@ title = "Tambahkan Watermark"
|
||||
desc = "Tambahkan tanda air teks atau gambar ke file PDF"
|
||||
completed = "Tanda air ditambahkan"
|
||||
submit = "Tambahkan Watermark"
|
||||
filenamePrefix = "bertanda_air"
|
||||
filenamePrefix = "watermarked"
|
||||
|
||||
[watermark.error]
|
||||
failed = "Terjadi kesalahan saat menambahkan tanda air ke PDF."
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Tanda tangan gambar"
|
||||
defaultImageLabel = "Tanda tangan terunggah"
|
||||
defaultTextLabel = "Tanda tangan ketik"
|
||||
saveButton = "Simpan tanda tangan"
|
||||
savePersonal = "Simpan Pribadi"
|
||||
saveShared = "Simpan Bersama"
|
||||
saveUnavailable = "Buat tanda tangan terlebih dahulu untuk menyimpannya."
|
||||
noChanges = "Tanda tangan saat ini sudah disimpan."
|
||||
tempStorageTitle = "Penyimpanan browser sementara"
|
||||
tempStorageDescription = "Tanda tangan disimpan hanya di browser Anda. Data akan hilang jika Anda membersihkan data browser atau berpindah browser."
|
||||
personalHeading = "Tanda Tangan Pribadi"
|
||||
sharedHeading = "Tanda Tangan Bersama"
|
||||
personalDescription = "Hanya Anda yang dapat melihat tanda tangan ini."
|
||||
sharedDescription = "Semua pengguna dapat melihat dan menggunakan tanda tangan ini."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Gambar"
|
||||
@@ -2717,7 +2704,7 @@ header = "Hapus sertifikat digital dari PDF"
|
||||
selectPDF = "Pilih file PDF:"
|
||||
submit = "Hapus Tanda Tangan"
|
||||
description = "Alat ini akan menghapus tanda tangan sertifikat digital dari dokumen PDF Anda."
|
||||
filenamePrefix = "tanpa_tanda_tangan"
|
||||
filenamePrefix = "unsigned"
|
||||
|
||||
[removeCertSign.files]
|
||||
placeholder = "Pilih file PDF di tampilan utama untuk memulai"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Silakan masuk"
|
||||
ssoSignIn = "Masuk melalui Single Sign - on"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Buat Otomatis Pengguna Dinonaktifkan"
|
||||
oAuth2AdminBlockedUser = "Registrasi atau login pengguna yang tidak terdaftar saat ini diblokir. Silakan hubungi administrator."
|
||||
oAuth2RequiresLicense = "Login OAuth/SSO memerlukan lisensi berbayar (Server atau Enterprise). Silakan hubungi administrator untuk meningkatkan paket Anda."
|
||||
saml2RequiresLicense = "Login SAML memerlukan lisensi berbayar (Server atau Enterprise). Silakan hubungi administrator untuk meningkatkan paket Anda."
|
||||
maxUsersReached = "Jumlah pengguna maksimum untuk lisensi Anda saat ini telah tercapai. Silakan hubungi administrator untuk meningkatkan paket Anda atau menambah seat."
|
||||
oauth2RequestNotFound = "Permintaan otorisasi tidak ditemukan"
|
||||
oauth2InvalidUserInfoResponse = "Respons Info Pengguna Tidak Valid"
|
||||
oauth2invalidRequest = "Permintaan Tidak Valid"
|
||||
@@ -3552,7 +3536,7 @@ title = "PDF Ke Halaman Tunggal"
|
||||
header = "PDF Ke Halaman Tunggal"
|
||||
submit = "Konversi ke Halaman Tunggal"
|
||||
description = "Alat ini akan menggabungkan semua halaman PDF Anda menjadi satu halaman besar. Lebarnya akan tetap sama dengan halaman asli, tetapi tingginya merupakan penjumlahan dari semua tinggi halaman."
|
||||
filenamePrefix = "halaman_tunggal"
|
||||
filenamePrefix = "single_page"
|
||||
|
||||
[pdfToSinglePage.files]
|
||||
placeholder = "Pilih file PDF di tampilan utama untuk memulai"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Sesuaikan ke Lebar"
|
||||
actualSize = "Ukuran Asli"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Tidak dapat menampilkan pratinjau file"
|
||||
dualPageView = "Tampilan Dua Halaman"
|
||||
firstPage = "Halaman Pertama"
|
||||
lastPage = "Halaman Terakhir"
|
||||
nextPage = "Halaman Berikutnya"
|
||||
onlyPdfSupported = "Penampil hanya mendukung file PDF. File ini tampaknya memiliki format yang berbeda."
|
||||
previousPage = "Halaman Sebelumnya"
|
||||
singlePageView = "Tampilan Satu Halaman"
|
||||
unknownFile = "File tidak dikenal"
|
||||
nextPage = "Halaman Berikutnya"
|
||||
zoomIn = "Perbesar"
|
||||
zoomOut = "Perkecil"
|
||||
singlePageView = "Tampilan Satu Halaman"
|
||||
dualPageView = "Tampilan Dua Halaman"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Tutup File Terpilih"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Alihkan Sidebar"
|
||||
exportSelected = "Ekspor Halaman Terpilih"
|
||||
toggleAnnotations = "Alihkan Visibilitas Anotasi"
|
||||
annotationMode = "Alihkan Mode Anotasi"
|
||||
print = "Cetak PDF"
|
||||
draw = "Gambar"
|
||||
save = "Simpan"
|
||||
saveChanges = "Simpan Perubahan"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL atau nama file untuk impressum (diperlukan di beberapa yurisd
|
||||
title = "Premium & Enterprise"
|
||||
description = "Konfigurasikan kunci lisensi premium atau enterprise Anda."
|
||||
license = "Konfigurasi Lisensi"
|
||||
noInput = "Harap berikan kunci atau file lisensi"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Punya kunci lisensi atau file sertifikat?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Menimpa kunci lisensi Anda saat ini tidak dapat dibatalkan."
|
||||
line2 = "Lisensi sebelumnya akan hilang permanen kecuali Anda mencadangkannya di tempat lain."
|
||||
line3 = "Penting: Jaga kunci lisensi tetap privat dan aman. Jangan pernah membagikannya secara publik."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Kunci Lisensi"
|
||||
file = "File Sertifikat"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "File Sertifikat Lisensi"
|
||||
description = "Unggah file lisensi .lic atau .cert Anda dari pembelian offline"
|
||||
choose = "Pilih File Lisensi"
|
||||
selected = "Dipilih: {{filename}} ({{size}})"
|
||||
successMessage = "File lisensi berhasil diunggah dan diaktifkan. Tidak perlu restart."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Lisensi Aktif"
|
||||
file = "Sumber: File lisensi ({{path}})"
|
||||
key = "Sumber: Kunci lisensi"
|
||||
type = "Tipe: {{type}}"
|
||||
noInput = "Harap berikan kunci lisensi atau unggah file sertifikat"
|
||||
success = "Berhasil"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Aktifkan Fitur Premium"
|
||||
description = "Aktifkan pemeriksaan kunci lisensi untuk fitur pro/enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} dipilih"
|
||||
download = "Unduh"
|
||||
delete = "Hapus"
|
||||
unsupported = "Tidak didukung"
|
||||
active = "Aktif"
|
||||
addToUpload = "Tambahkan ke Unggahan"
|
||||
closeFile = "Tutup File"
|
||||
deleteAll = "Hapus Semua"
|
||||
loadingFiles = "Memuat file..."
|
||||
noFiles = "Tidak ada file tersedia"
|
||||
@@ -4983,13 +4941,13 @@ done = "Selesai"
|
||||
loading = "Memuat..."
|
||||
back = "Kembali"
|
||||
continue = "Lanjut"
|
||||
error = "Kesalahan"
|
||||
error = "Error"
|
||||
|
||||
[config.overview]
|
||||
title = "Konfigurasi Aplikasi"
|
||||
description = "Pengaturan dan detail konfigurasi aplikasi saat ini."
|
||||
loading = "Memuat konfigurasi..."
|
||||
error = "Kesalahan"
|
||||
error = "Error"
|
||||
warning = "Peringatan Konfigurasi"
|
||||
|
||||
[config.overview.sections]
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Setidaknya satu alamat email diperlukan"
|
||||
submit = "Kirim Undangan"
|
||||
success = "pengguna berhasil diundang"
|
||||
partialFailure = "Beberapa undangan gagal"
|
||||
partialSuccess = "Beberapa undangan gagal"
|
||||
allFailed = "Gagal mengundang pengguna"
|
||||
error = "Gagal mengirim undangan"
|
||||
|
||||
@@ -5797,7 +5755,7 @@ label = "Pilih Server"
|
||||
description = "Server self-hosted"
|
||||
|
||||
[setup.step3]
|
||||
label = "Masuk"
|
||||
label = "Login"
|
||||
description = "Masukkan kredensial"
|
||||
|
||||
[setup.mode.saas]
|
||||
@@ -5838,17 +5796,10 @@ testFailed = "Tes koneksi gagal"
|
||||
title = "Masuk"
|
||||
subtitle = "Masukkan kredensial Anda untuk melanjutkan"
|
||||
connectingTo = "Menghubungkan ke:"
|
||||
submit = "Masuk"
|
||||
submit = "Login"
|
||||
signInWith = "Masuk dengan"
|
||||
oauthPending = "Membuka browser untuk autentikasi..."
|
||||
orContinueWith = "Atau lanjut dengan email"
|
||||
serverRequirement = "Catatan: Server harus mengaktifkan login."
|
||||
showInstructions = "Bagaimana cara mengaktifkannya?"
|
||||
hideInstructions = "Sembunyikan instruksi"
|
||||
instructions = "Untuk mengaktifkan login pada server Stirling PDF Anda:"
|
||||
instructionsEnvVar = "Setel variabel lingkungan:"
|
||||
instructionsOrYml = "Atau di settings.yml:"
|
||||
instructionsRestart = "Kemudian mulai ulang server Anda agar perubahan diterapkan."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Nama pengguna"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Rimuovi dai preferiti"
|
||||
fullscreen = "Passa alla modalità a schermo intero"
|
||||
sidebar = "Passa alla modalità barra laterale"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend non trovato"
|
||||
retry = "Riprova"
|
||||
unreachable = "L'applicazione al momento non riesce a connettersi al backend. Verificare lo stato del backend e la connettività di rete, quindi riprovare."
|
||||
|
||||
[zipWarning]
|
||||
title = "File ZIP di grandi dimensioni"
|
||||
message = "Questo ZIP contiene {{count}} file. Estrarre comunque?"
|
||||
@@ -344,7 +339,7 @@ popular = "Popolare"
|
||||
title = "Preferenze"
|
||||
|
||||
[settings.workspace]
|
||||
title = "Area di lavoro"
|
||||
title = "Workspace"
|
||||
people = "Persone"
|
||||
teams = "Team"
|
||||
|
||||
@@ -918,8 +913,8 @@ desc = "Sovrapponi un PDF sopra un altro"
|
||||
title = "Sovrapponi PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Editor di testo PDF"
|
||||
desc = "Modifica testo e immagini esistenti nei PDF"
|
||||
title = "Editor testo PDF"
|
||||
desc = "Rivedi e modifica le esportazioni JSON di Stirling PDF con modifica testo raggruppata e rigenerazione del PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "testo,annotazione,etichetta"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Firma disegnata"
|
||||
defaultImageLabel = "Firma caricata"
|
||||
defaultTextLabel = "Firma digitata"
|
||||
saveButton = "Salva firma"
|
||||
savePersonal = "Salva come personale"
|
||||
saveShared = "Salva come condivisa"
|
||||
saveUnavailable = "Crea prima una firma per salvarla."
|
||||
noChanges = "La firma corrente è già salvata."
|
||||
tempStorageTitle = "Archiviazione temporanea del browser"
|
||||
tempStorageDescription = "Le firme sono archiviate solo nel tuo browser. Verranno perse se cancelli i dati del browser o cambi browser."
|
||||
personalHeading = "Firme personali"
|
||||
sharedHeading = "Firme condivise"
|
||||
personalDescription = "Solo tu puoi vedere queste firme."
|
||||
sharedDescription = "Tutti gli utenti possono vedere e usare queste firme."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Disegno"
|
||||
@@ -2857,8 +2844,8 @@ label = "Fattore di scala"
|
||||
[adjustPageScale.pageSize]
|
||||
label = "Dimensione pagina di destinazione"
|
||||
keep = "Mantieni dimensioni originali"
|
||||
letter = "Lettera"
|
||||
legal = "Legale"
|
||||
letter = "Letter"
|
||||
legal = "Legal"
|
||||
|
||||
[adjustPageScale.error]
|
||||
failed = "Si è verificato un errore durante la regolazione della scala della pagina."
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Per favore accedi"
|
||||
ssoSignIn = "Accedi tramite Single Sign-on"
|
||||
oAuth2AutoCreateDisabled = "Creazione automatica utente OAUTH2 DISABILITATA"
|
||||
oAuth2AdminBlockedUser = "La registrazione o l'accesso degli utenti non registrati è attualmente bloccata. Si prega di contattare l'amministratore."
|
||||
oAuth2RequiresLicense = "L'accesso OAuth/SSO richiede una licenza a pagamento (Server o Enterprise). Contatta l'amministratore per aggiornare il tuo piano."
|
||||
saml2RequiresLicense = "L'accesso SAML richiede una licenza a pagamento (Server o Enterprise). Contatta l'amministratore per aggiornare il tuo piano."
|
||||
maxUsersReached = "Numero massimo di utenti raggiunto per la licenza corrente. Contatta l'amministratore per aggiornare il piano o aggiungere altri posti."
|
||||
oauth2RequestNotFound = "Richiesta di autorizzazione non trovata"
|
||||
oauth2InvalidUserInfoResponse = "Risposta relativa alle informazioni utente non valida"
|
||||
oauth2invalidRequest = "Richiesta non valida"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Adatta alla larghezza"
|
||||
actualSize = "Dimensione reale"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Impossibile visualizzare l'anteprima del file"
|
||||
dualPageView = "Vista doppia pagina"
|
||||
firstPage = "Prima pagina"
|
||||
lastPage = "Ultima pagina"
|
||||
nextPage = "Pagina successiva"
|
||||
onlyPdfSupported = "Il visualizzatore supporta solo file PDF. Questo file sembra essere in un formato diverso."
|
||||
previousPage = "Pagina precedente"
|
||||
singlePageView = "Vista pagina singola"
|
||||
unknownFile = "File sconosciuto"
|
||||
nextPage = "Pagina successiva"
|
||||
zoomIn = "Ingrandisci"
|
||||
zoomOut = "Riduci"
|
||||
singlePageView = "Vista pagina singola"
|
||||
dualPageView = "Vista doppia pagina"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Chiudi file selezionati"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Mostra/Nascondi barra laterale"
|
||||
exportSelected = "Esporta pagine selezionate"
|
||||
toggleAnnotations = "Attiva/disattiva visibilità annotazioni"
|
||||
annotationMode = "Attiva/disattiva modalità annotazione"
|
||||
print = "Stampa PDF"
|
||||
draw = "Disegna"
|
||||
save = "Salva"
|
||||
saveChanges = "Salva modifiche"
|
||||
@@ -3948,7 +3928,7 @@ files = "File"
|
||||
activity = "Attività"
|
||||
help = "Guida"
|
||||
account = "Account"
|
||||
config = "Configurazione"
|
||||
config = "Config"
|
||||
settings = "Opzioni"
|
||||
adminSettings = "Opzioni Admin"
|
||||
allTools = "Funzioni"
|
||||
@@ -4510,14 +4490,13 @@ label = "Informativa sui cookie"
|
||||
description = "URL o nome file della cookie policy"
|
||||
|
||||
[admin.settings.legal.impressum]
|
||||
label = "Note legali"
|
||||
label = "Impressum"
|
||||
description = "URL o nome file dell'Impressum (richiesto in alcune giurisdizioni)"
|
||||
|
||||
[admin.settings.premium]
|
||||
title = "Premium e Enterprise"
|
||||
description = "Configura la tua chiave di licenza premium o enterprise."
|
||||
license = "Configurazione licenza"
|
||||
noInput = "Fornisci una chiave o un file di licenza"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Hai una chiave di licenza o un file di certificato?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "La sovrascrittura della licenza attuale non può essere annullata."
|
||||
line2 = "La tua licenza precedente andrà persa in modo permanente a meno che tu non l'abbia salvata altrove."
|
||||
line3 = "Importante: mantieni le chiavi di licenza private e sicure. Non condividerle mai pubblicamente."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Chiave di licenza"
|
||||
file = "File del certificato"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "File del certificato di licenza"
|
||||
description = "Carica il file di licenza .lic o .cert degli acquisti offline"
|
||||
choose = "Scegli file di licenza"
|
||||
selected = "Selezionato: {{filename}} ({{size}})"
|
||||
successMessage = "File di licenza caricato e attivato con successo. Non è richiesto il riavvio."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Licenza attiva"
|
||||
file = "Origine: File di licenza ({{path}})"
|
||||
key = "Origine: Chiave di licenza"
|
||||
type = "Tipo: {{type}}"
|
||||
noInput = "Fornisci una chiave di licenza o carica un file di certificato"
|
||||
success = "Successo"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Abilita funzionalità Premium"
|
||||
description = "Abilita i controlli della chiave di licenza per funzionalità pro/enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} selezionati"
|
||||
download = "Salva"
|
||||
delete = "Elimina"
|
||||
unsupported = "Non supportato"
|
||||
active = "Attivo"
|
||||
addToUpload = "Aggiungi al caricamento"
|
||||
closeFile = "Chiudi file"
|
||||
deleteAll = "Elimina tutto"
|
||||
loadingFiles = "Caricamento file..."
|
||||
noFiles = "Nessun file disponibile"
|
||||
@@ -5239,7 +5197,7 @@ subtitle = "Digita o incolla le email qui sotto, separate da virgole. La tua are
|
||||
|
||||
[workspace.people.actions]
|
||||
label = "Azioni"
|
||||
upgrade = "Aggiorna"
|
||||
upgrade = "Upgrade"
|
||||
|
||||
[workspace.people.roleDescriptions]
|
||||
admin = "Può gestire impostazioni e invitare membri, con pieno accesso amministrativo."
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "È richiesto almeno un indirizzo email"
|
||||
submit = "Invia inviti"
|
||||
success = "utente/i invitato/i con successo"
|
||||
partialFailure = "Alcuni inviti non sono riusciti"
|
||||
partialSuccess = "Alcuni inviti non sono riusciti"
|
||||
allFailed = "Impossibile invitare gli utenti"
|
||||
error = "Invio inviti non riuscito"
|
||||
|
||||
@@ -5797,7 +5755,7 @@ label = "Seleziona server"
|
||||
description = "Server self-hosted"
|
||||
|
||||
[setup.step3]
|
||||
label = "Accesso"
|
||||
label = "Login"
|
||||
description = "Inserisci credenziali"
|
||||
|
||||
[setup.mode.saas]
|
||||
@@ -5838,17 +5796,10 @@ testFailed = "Test di connessione non riuscito"
|
||||
title = "Accedi"
|
||||
subtitle = "Inserisci le credenziali per continuare"
|
||||
connectingTo = "Connessione a:"
|
||||
submit = "Accedi"
|
||||
submit = "Login"
|
||||
signInWith = "Accedi con"
|
||||
oauthPending = "Apertura del browser per l'autenticazione..."
|
||||
orContinueWith = "Oppure continua con email"
|
||||
serverRequirement = "Nota: il server deve avere il login abilitato."
|
||||
showInstructions = "Come abilitarlo?"
|
||||
hideInstructions = "Nascondi istruzioni"
|
||||
instructions = "Per abilitare il login sul tuo server Stirling PDF:"
|
||||
instructionsEnvVar = "Imposta la variabile d'ambiente:"
|
||||
instructionsOrYml = "Oppure in settings.yml:"
|
||||
instructionsRestart = "Quindi riavvia il server affinché le modifiche abbiano effetto."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Nome utente"
|
||||
@@ -5892,7 +5843,7 @@ paragraph = "Pagina a paragrafi"
|
||||
sparse = "Testo sparso"
|
||||
|
||||
[pdfTextEditor.groupingMode]
|
||||
auto = "Automatico"
|
||||
auto = "Auto"
|
||||
paragraph = "Paragrafo"
|
||||
singleLine = "Riga singola"
|
||||
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "お気に入りから削除"
|
||||
fullscreen = "フルスクリーンモードに切り替え"
|
||||
sidebar = "サイドバーモードに切り替え"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "バックエンドが見つかりません"
|
||||
retry = "再試行"
|
||||
unreachable = "現在、アプリケーションはバックエンドに接続できません。バックエンドの稼働状況とネットワーク接続を確認し、再度お試しください。"
|
||||
|
||||
[zipWarning]
|
||||
title = "大きな ZIP ファイル"
|
||||
message = "このZIPには{{count}}個のファイルが含まれています。展開しますか?"
|
||||
@@ -918,8 +913,8 @@ desc = "1つのPDFを別のPDFの上に重ねます"
|
||||
title = "PDFを重ね合わせ"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDFテキストエディタ"
|
||||
desc = "PDF内の既存のテキストと画像を編集"
|
||||
title = "PDFテキストエディター"
|
||||
desc = "グループ化されたテキスト編集とPDF再生成で、Stirling PDF の JSON エクスポートをレビュー・編集します。"
|
||||
|
||||
[home.addText]
|
||||
tags = "テキスト,注釈,ラベル"
|
||||
@@ -1181,7 +1176,7 @@ selectFilesPlaceholder = "開始するにはメインビューでファイルを
|
||||
settings = "設定"
|
||||
conversionCompleted = "変換が完了しました"
|
||||
results = "結果"
|
||||
defaultFilename = "変換済みファイル"
|
||||
defaultFilename = "converted_file"
|
||||
conversionResults = "変換結果"
|
||||
convertFrom = "変換元"
|
||||
convertTo = "変換先"
|
||||
@@ -1368,7 +1363,7 @@ title = "透かしの追加"
|
||||
desc = "PDF ファイルにテキストまたは画像の透かしを追加"
|
||||
completed = "透かしを追加しました"
|
||||
submit = "透かしを追加"
|
||||
filenamePrefix = "透かし入り"
|
||||
filenamePrefix = "watermarked"
|
||||
|
||||
[watermark.error]
|
||||
failed = "PDF への透かし追加中にエラーが発生しました。"
|
||||
@@ -1643,7 +1638,7 @@ subtitle = "処理済みファイルをダウンロードするか、下で操
|
||||
[removePages]
|
||||
tags = "ページを削除,ページ削除"
|
||||
title = "削除"
|
||||
filenamePrefix = "ページ削除済み"
|
||||
filenamePrefix = "pages_removed"
|
||||
submit = "削除"
|
||||
|
||||
[removePages.pageNumbers]
|
||||
@@ -1845,7 +1840,7 @@ title = "フォームフィールドから読み取り専用を削除"
|
||||
header = "PDFフォームのロックを解除"
|
||||
submit = "Remove"
|
||||
description = "このツールは PDF フォームフィールドの読み取り専用制限を解除し、編集・入力可能にします。"
|
||||
filenamePrefix = "フォームのロック解除済み"
|
||||
filenamePrefix = "unlocked_forms"
|
||||
|
||||
[unlockPDFForms.files]
|
||||
placeholder = "メインビューで PDF ファイルを選択して開始してください"
|
||||
@@ -1859,7 +1854,7 @@ title = "フォームのロック解除結果"
|
||||
[changeMetadata]
|
||||
header = "メタデータの変更"
|
||||
submit = "変更"
|
||||
filenamePrefix = "メタデータ"
|
||||
filenamePrefix = "metadata"
|
||||
|
||||
[changeMetadata.settings]
|
||||
title = "メタデータ設定"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "手書き署名"
|
||||
defaultImageLabel = "アップロードした署名"
|
||||
defaultTextLabel = "入力した署名"
|
||||
saveButton = "署名を保存"
|
||||
savePersonal = "個人用として保存"
|
||||
saveShared = "共有用として保存"
|
||||
saveUnavailable = "まず署名を作成してから保存してください。"
|
||||
noChanges = "現在の署名はすでに保存済みです。"
|
||||
tempStorageTitle = "ブラウザーの一時ストレージ"
|
||||
tempStorageDescription = "署名はブラウザー内のみに保存されます。ブラウザーのデータを消去するか、別のブラウザーに切り替えると失われます。"
|
||||
personalHeading = "個人用署名"
|
||||
sharedHeading = "共有署名"
|
||||
personalDescription = "これらの署名はあなただけが表示できます。"
|
||||
sharedDescription = "すべてのユーザーがこれらの署名を表示して使用できます。"
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "描画"
|
||||
@@ -2334,7 +2321,7 @@ title = "平坦化"
|
||||
header = "PDFを平坦化する"
|
||||
flattenOnlyForms = "フォームのみを平坦にする"
|
||||
submit = "平坦化"
|
||||
filenamePrefix = "フラット化済み"
|
||||
filenamePrefix = "flattened"
|
||||
|
||||
[flatten.files]
|
||||
placeholder = "開始するにはメインビューで PDF ファイルを選択してください"
|
||||
@@ -2382,7 +2369,7 @@ title = "修復"
|
||||
header = "PDFを修復"
|
||||
submit = "修復"
|
||||
description = "このツールは破損または損傷した PDF ファイルの修復を試みます。追加の設定は不要です。"
|
||||
filenamePrefix = "修復済み"
|
||||
filenamePrefix = "repaired"
|
||||
|
||||
[repair.files]
|
||||
placeholder = "開始するにはメイン画面で PDF ファイルを選択してください"
|
||||
@@ -2583,7 +2570,7 @@ stopButton = "比較を停止"
|
||||
[certSign]
|
||||
tags = "authenticate,PEM,P12,official,encrypt"
|
||||
title = "証明書による署名"
|
||||
filenamePrefix = "署名済み"
|
||||
filenamePrefix = "signed"
|
||||
chooseCertificate = "証明書ファイルを選択"
|
||||
chooseJksFile = "JKS ファイルを選択"
|
||||
chooseP12File = "PKCS12 ファイルを選択"
|
||||
@@ -2717,7 +2704,7 @@ header = "PDFから電子証明書を削除する"
|
||||
selectPDF = "PDFファイルの選択:"
|
||||
submit = "署名の削除"
|
||||
description = "このツールは PDF 文書からデジタル証明書署名を削除します。"
|
||||
filenamePrefix = "署名なし"
|
||||
filenamePrefix = "unsigned"
|
||||
|
||||
[removeCertSign.files]
|
||||
placeholder = "開始するにはメイン画面で PDF ファイルを選択してください"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "サインインしてください"
|
||||
ssoSignIn = "シングルサインオンでログイン"
|
||||
oAuth2AutoCreateDisabled = "OAuth 2自動作成ユーザーが無効"
|
||||
oAuth2AdminBlockedUser = "現在、未登録ユーザーの登録またはログインはブロックされています。管理者にお問い合わせください。"
|
||||
oAuth2RequiresLicense = "OAuth/SSO ログインには有料ライセンス(Server または Enterprise)が必要です。プランのアップグレードについては管理者にお問い合わせください。"
|
||||
saml2RequiresLicense = "SAML ログインには有料ライセンス(Server または Enterprise)が必要です。プランのアップグレードについては管理者にお問い合わせください。"
|
||||
maxUsersReached = "現在のライセンスのユーザー数上限に達しました。プランのアップグレードまたはシート数の追加について、管理者にお問い合わせください。"
|
||||
oauth2RequestNotFound = "認証リクエストが見つかりません"
|
||||
oauth2InvalidUserInfoResponse = "無効なユーザー情報の応答"
|
||||
oauth2invalidRequest = "無効なリクエスト"
|
||||
@@ -3552,7 +3536,7 @@ title = "PDFを単一ページに変換"
|
||||
header = "PDFを単一ページに変換"
|
||||
submit = "単一ページに変換"
|
||||
description = "このツールは PDF の全ページを 1 つの大きな単一ページに結合します。幅は元のページと同じで、高さは全ページの高さの合計になります。"
|
||||
filenamePrefix = "単一ページ"
|
||||
filenamePrefix = "single_page"
|
||||
|
||||
[pdfToSinglePage.files]
|
||||
placeholder = "開始するにはメイン画面で PDF ファイルを選択してください"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "幅に合わせる"
|
||||
actualSize = "原寸"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "ファイルをプレビューできません"
|
||||
dualPageView = "見開き表示"
|
||||
firstPage = "最初のページ"
|
||||
lastPage = "最後のページ"
|
||||
nextPage = "次のページ"
|
||||
onlyPdfSupported = "このビューアは PDF ファイルのみをサポートしています。このファイルは別の形式のようです。"
|
||||
previousPage = "前のページ"
|
||||
singlePageView = "単一ページ表示"
|
||||
unknownFile = "不明なファイル"
|
||||
nextPage = "次のページ"
|
||||
zoomIn = "拡大"
|
||||
zoomOut = "縮小"
|
||||
singlePageView = "単一ページ表示"
|
||||
dualPageView = "見開き表示"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "選択したファイルを閉じる"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "サイドバーを切り替え"
|
||||
exportSelected = "選択したページを書き出し"
|
||||
toggleAnnotations = "注釈の表示を切り替え"
|
||||
annotationMode = "注釈モードを切り替え"
|
||||
print = "PDFを印刷"
|
||||
draw = "描画"
|
||||
save = "保存"
|
||||
saveChanges = "変更を保存"
|
||||
@@ -4254,15 +4234,15 @@ label = "プロバイダ"
|
||||
description = "認証に使用する OAuth2 プロバイダ"
|
||||
|
||||
[admin.settings.connections.oauth2.issuer]
|
||||
label = "発行者 URL"
|
||||
label = "Issuer URL"
|
||||
description = "OAuth2 プロバイダの Issuer URL"
|
||||
|
||||
[admin.settings.connections.oauth2.clientId]
|
||||
label = "クライアント ID"
|
||||
label = "Client ID"
|
||||
description = "プロバイダから発行された OAuth2 の Client ID"
|
||||
|
||||
[admin.settings.connections.oauth2.clientSecret]
|
||||
label = "クライアント シークレット"
|
||||
label = "Client Secret"
|
||||
description = "プロバイダから発行された OAuth2 の Client Secret"
|
||||
|
||||
[admin.settings.connections.oauth2.useAsUsername]
|
||||
@@ -4293,7 +4273,7 @@ label = "プロバイダ"
|
||||
description = "SAML2 プロバイダ名"
|
||||
|
||||
[admin.settings.connections.saml2.registrationId]
|
||||
label = "登録 ID"
|
||||
label = "Registration ID"
|
||||
description = "SAML2 の登録識別子"
|
||||
|
||||
[admin.settings.connections.saml2.autoCreateUser]
|
||||
@@ -4430,7 +4410,7 @@ description = "より広範なシステム一時ディレクトリをクリー
|
||||
label = "プロセス実行制限"
|
||||
description = "各プロセス実行器のセッション上限とタイムアウトを設定"
|
||||
libreOffice = "LibreOffice"
|
||||
pdfToHtml = "PDF を HTML に"
|
||||
pdfToHtml = "PDF to HTML"
|
||||
qpdf = "QPDF"
|
||||
tesseract = "Tesseract OCR"
|
||||
pythonOpenCv = "Python OpenCV"
|
||||
@@ -4517,7 +4497,6 @@ description = "インプリントへの URL またはファイル名(地域に
|
||||
title = "プレミアムとエンタープライズ"
|
||||
description = "プレミアムまたはエンタープライズのライセンスキーを構成します。"
|
||||
license = "ライセンス設定"
|
||||
noInput = "ライセンスキーまたはファイルを入力してください"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "ライセンスキーまたは証明書ファイルをお持ちですか?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "現在のライセンスキーを上書きすると元に戻せませ
|
||||
line2 = "別途バックアップしていない限り、以前のライセンスは永久に失われます。"
|
||||
line3 = "重要: ライセンスキーは秘密に安全に保管してください。公開で共有しないでください。"
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "ライセンスキー"
|
||||
file = "証明書ファイル"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "ライセンス証明書ファイル"
|
||||
description = "オフライン購入の .lic または .cert ライセンスファイルをアップロードしてください"
|
||||
choose = "ライセンスファイルを選択"
|
||||
selected = "選択済み: {{filename}} ({{size}})"
|
||||
successMessage = "ライセンスファイルをアップロードして有効化しました。再起動は不要です。"
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "有効なライセンス"
|
||||
file = "ソース: ライセンスファイル ({{path}})"
|
||||
key = "ソース: ライセンスキー"
|
||||
type = "種類: {{type}}"
|
||||
noInput = "ライセンスキーを入力するか、証明書ファイルをアップロードしてください"
|
||||
success = "成功"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "プレミアム機能を有効化"
|
||||
description = "Pro/Enterprise 機能のライセンスキー検証を有効化"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} 件選択"
|
||||
download = "ダウンロード"
|
||||
delete = "削除"
|
||||
unsupported = "未対応"
|
||||
active = "アクティブ"
|
||||
addToUpload = "アップロードに追加"
|
||||
closeFile = "ファイルを閉じる"
|
||||
deleteAll = "すべて削除"
|
||||
loadingFiles = "ファイルを読み込み中..."
|
||||
noFiles = "ファイルはありません"
|
||||
@@ -4714,7 +4672,7 @@ title = "サニタイズ"
|
||||
desc = "PDF ファイルから潜在的に有害な要素を削除します。"
|
||||
submit = "PDFをサニタイズ"
|
||||
completed = "サニタイズが正常に完了しました"
|
||||
filenamePrefix = "サニタイズ済み"
|
||||
filenamePrefix = "sanitised"
|
||||
sanitizationResults = "サニタイズ結果"
|
||||
|
||||
[sanitize.error]
|
||||
@@ -4762,7 +4720,7 @@ title = "パスワードの追加"
|
||||
desc = "パスワードで PDF 文書を暗号化します。"
|
||||
completed = "パスワード保護を適用しました"
|
||||
submit = "暗号化"
|
||||
filenamePrefix = "暗号化済み"
|
||||
filenamePrefix = "encrypted"
|
||||
|
||||
[addPassword.error]
|
||||
failed = "PDF の暗号化中にエラーが発生しました。"
|
||||
@@ -4857,7 +4815,7 @@ text = "これらの権限を変更不可にするには、パスワード追加
|
||||
title = "パスワードの削除"
|
||||
desc = "PDFからパスワードの削除します。"
|
||||
tags = "セキュア,復号,セキュリティ,パスワード解除,パスワード削除"
|
||||
filenamePrefix = "復号済み"
|
||||
filenamePrefix = "decrypted"
|
||||
submit = "削除"
|
||||
|
||||
[removePassword.password]
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "少なくとも1件のメールアドレスが必要です"
|
||||
submit = "招待を送信"
|
||||
success = "ユーザーを招待しました"
|
||||
partialFailure = "一部の招待に失敗しました"
|
||||
partialSuccess = "一部の招待に失敗しました"
|
||||
allFailed = "ユーザーの招待に失敗しました"
|
||||
error = "招待の送信に失敗しました"
|
||||
|
||||
@@ -5842,20 +5800,13 @@ submit = "ログイン"
|
||||
signInWith = "でサインイン"
|
||||
oauthPending = "認証のためブラウザーを開いています..."
|
||||
orContinueWith = "またはメールで続行"
|
||||
serverRequirement = "注: サーバーでログインを有効にする必要があります。"
|
||||
showInstructions = "有効化するには?"
|
||||
hideInstructions = "手順を非表示"
|
||||
instructions = "Stirling PDF サーバーでログインを有効にするには:"
|
||||
instructionsEnvVar = "環境変数を設定:"
|
||||
instructionsOrYml = "または settings.yml で:"
|
||||
instructionsRestart = "その後、サーバーを再起動して変更を反映させてください。"
|
||||
|
||||
[setup.login.username]
|
||||
label = "ユーザー名"
|
||||
placeholder = "ユーザー名を入力"
|
||||
|
||||
[setup.login.email]
|
||||
label = "メールアドレス"
|
||||
label = "Email"
|
||||
placeholder = "メールアドレスを入力"
|
||||
|
||||
[setup.login.password]
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "즐겨찾기에서 제거"
|
||||
fullscreen = "전체 화면 모드로 전환"
|
||||
sidebar = "사이드바 모드로 전환"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "백엔드를 찾을 수 없음"
|
||||
retry = "재시도"
|
||||
unreachable = "현재 애플리케이션이 백엔드에 연결할 수 없습니다. 백엔드 상태와 네트워크 연결을 확인한 후 다시 시도하세요."
|
||||
|
||||
[zipWarning]
|
||||
title = "큰 ZIP 파일"
|
||||
message = "이 ZIP에는 {{count}}개의 파일이 포함되어 있습니다. 그래도 압축을 해제하시겠습니까?"
|
||||
@@ -919,7 +914,7 @@ title = "PDF 오버레이"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF 텍스트 편집기"
|
||||
desc = "PDF 내부의 기존 텍스트와 이미지를 편집합니다"
|
||||
desc = "그룹화된 텍스트 편집과 PDF 재생성으로 Stirling PDF의 JSON 내보내기를 검토하고 편집하세요"
|
||||
|
||||
[home.addText]
|
||||
tags = "텍스트,주석,레이블"
|
||||
@@ -1909,8 +1904,8 @@ placeholder = "수정 날짜"
|
||||
[changeMetadata.trapped]
|
||||
label = "트래핑 상태"
|
||||
unknown = "알 수 없음"
|
||||
true = "참"
|
||||
false = "거짓"
|
||||
true = "True"
|
||||
false = "False"
|
||||
|
||||
[changeMetadata.advanced]
|
||||
title = "고급 옵션"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "그린 서명"
|
||||
defaultImageLabel = "업로드된 서명"
|
||||
defaultTextLabel = "입력한 서명"
|
||||
saveButton = "서명 저장"
|
||||
savePersonal = "개인용으로 저장"
|
||||
saveShared = "공유용으로 저장"
|
||||
saveUnavailable = "먼저 서명을 만든 후 저장하세요."
|
||||
noChanges = "현재 서명이 이미 저장되어 있습니다."
|
||||
tempStorageTitle = "임시 브라우저 저장소"
|
||||
tempStorageDescription = "서명은 브라우저에만 저장됩니다. 브라우저 데이터를 삭제하거나 브라우저를 변경하면 사라집니다."
|
||||
personalHeading = "개인 서명"
|
||||
sharedHeading = "공유 서명"
|
||||
personalDescription = "이 서명은 본인만 볼 수 있습니다."
|
||||
sharedDescription = "모든 사용자가 이 서명을 보고 사용할 수 있습니다."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "그리기"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "로그인해 주세요"
|
||||
ssoSignIn = "단일 로그인으로 로그인"
|
||||
oAuth2AutoCreateDisabled = "OAuth2 사용자 자동 생성이 비활성화되었습니다"
|
||||
oAuth2AdminBlockedUser = "현재 미등록 사용자의 등록 또는 로그인이 차단되어 있습니다. 관리자에게 문의하세요."
|
||||
oAuth2RequiresLicense = "OAuth/SSO 로그인은 유료 라이선스(서버 또는 엔터프라이즈)가 필요합니다. 플랜 업그레이드를 위해 관리자에게 문의하세요."
|
||||
saml2RequiresLicense = "SAML 로그인은 유료 라이선스(서버 또는 엔터프라이즈)가 필요합니다. 플랜 업그레이드를 위해 관리자에게 문의하세요."
|
||||
maxUsersReached = "현재 라이선스에서 허용된 최대 사용자 수에 도달했습니다. 플랜 업그레이드 또는 시트 추가를 위해 관리자에게 문의하세요."
|
||||
oauth2RequestNotFound = "인증 요청을 찾을 수 없습니다"
|
||||
oauth2InvalidUserInfoResponse = "잘못된 사용자 정보 응답"
|
||||
oauth2invalidRequest = "잘못된 요청"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "너비에 맞추기"
|
||||
actualSize = "실제 크기"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "파일을 미리보기할 수 없습니다"
|
||||
dualPageView = "두 페이지 보기"
|
||||
firstPage = "첫 페이지"
|
||||
lastPage = "마지막 페이지"
|
||||
nextPage = "다음 페이지"
|
||||
onlyPdfSupported = "뷰어는 PDF 파일만 지원합니다. 이 파일은 다른 형식인 것으로 보입니다."
|
||||
previousPage = "이전 페이지"
|
||||
singlePageView = "단일 페이지 보기"
|
||||
unknownFile = "알 수 없는 파일"
|
||||
nextPage = "다음 페이지"
|
||||
zoomIn = "확대"
|
||||
zoomOut = "축소"
|
||||
singlePageView = "단일 페이지 보기"
|
||||
dualPageView = "두 페이지 보기"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "선택한 파일 닫기"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "사이드바 전환"
|
||||
exportSelected = "선택한 페이지 내보내기"
|
||||
toggleAnnotations = "주석 가시성 전환"
|
||||
annotationMode = "주석 모드 전환"
|
||||
print = "PDF 인쇄"
|
||||
draw = "그리기"
|
||||
save = "저장"
|
||||
saveChanges = "변경 내용 저장"
|
||||
@@ -4176,7 +4156,7 @@ description = "컴플라이언스 및 보안 모니터링을 위해 사용자
|
||||
|
||||
[admin.settings.security.audit.level]
|
||||
label = "감사 수준"
|
||||
description = "0=끄기, 1=기본, 2=표준, 3=상세"
|
||||
description = "0=OFF, 1=BASIC, 2=STANDARD, 3=VERBOSE"
|
||||
|
||||
[admin.settings.security.audit.retentionDays]
|
||||
label = "감사 로그 보존 기간(일)"
|
||||
@@ -4430,7 +4410,7 @@ description = "더 넓은 시스템 임시 디렉터리를 정리할지 여부(
|
||||
label = "프로세스 실행기 제한"
|
||||
description = "각 프로세스 실행기의 세션 제한 및 시간 제한을 구성합니다"
|
||||
libreOffice = "LibreOffice"
|
||||
pdfToHtml = "PDF를 HTML로"
|
||||
pdfToHtml = "PDF to HTML"
|
||||
qpdf = "QPDF"
|
||||
tesseract = "Tesseract OCR"
|
||||
pythonOpenCv = "Python OpenCV"
|
||||
@@ -4510,14 +4490,13 @@ label = "쿠키 정책"
|
||||
description = "쿠키 정책의 URL 또는 파일 이름"
|
||||
|
||||
[admin.settings.legal.impressum]
|
||||
label = "법적 고지"
|
||||
label = "Impressum"
|
||||
description = "Impressum의 URL 또는 파일 이름(일부 관할권에서 필수)"
|
||||
|
||||
[admin.settings.premium]
|
||||
title = "프리미엄 및 엔터프라이즈"
|
||||
description = "프리미엄 또는 엔터프라이즈 라이선스 키를 구성합니다."
|
||||
license = "라이선스 구성"
|
||||
noInput = "라이선스 키 또는 파일을 입력해 주세요"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "라이선스 키나 인증서 파일이 있나요?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "현재 라이선스 키를 덮어쓰면 되돌릴 수 없습니다."
|
||||
line2 = "다른 곳에 백업하지 않았다면 이전 라이선스는 영구적으로 손실됩니다."
|
||||
line3 = "중요: 라이선스 키는 개인적으로 안전하게 보관하세요. 공개적으로 공유하지 마세요."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "라이선스 키"
|
||||
file = "인증서 파일"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "라이선스 인증서 파일"
|
||||
description = "오프라인 구매 시 받은 .lic 또는 .cert 라이선스 파일을 업로드하세요"
|
||||
choose = "라이선스 파일 선택"
|
||||
selected = "선택됨: {{filename}} ({{size}})"
|
||||
successMessage = "라이선스 파일이 업로드되어 성공적으로 활성화되었습니다. 재시작은 필요하지 않습니다."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "활성 라이선스"
|
||||
file = "소스: 라이선스 파일 ({{path}})"
|
||||
key = "소스: 라이선스 키"
|
||||
type = "유형: {{type}}"
|
||||
noInput = "라이선스 키를 입력하거나 인증서 파일을 업로드해 주세요"
|
||||
success = "성공"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "프리미엄 기능 활성화"
|
||||
description = "프로/엔터프라이즈 기능에 대한 라이선스 키 확인 활성화"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}}개 선택됨"
|
||||
download = "다운로드"
|
||||
delete = "삭제"
|
||||
unsupported = "지원되지 않음"
|
||||
active = "활성"
|
||||
addToUpload = "업로드에 추가"
|
||||
closeFile = "파일 닫기"
|
||||
deleteAll = "모두 삭제"
|
||||
loadingFiles = "파일 불러오는 중..."
|
||||
noFiles = "사용 가능한 파일이 없습니다"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "이메일 주소를 최소 한 개 이상 입력해야 합니다"
|
||||
submit = "초대장 보내기"
|
||||
success = "사용자 초대가 완료되었습니다"
|
||||
partialFailure = "일부 초대가 실패했습니다"
|
||||
partialSuccess = "일부 초대가 실패했습니다"
|
||||
allFailed = "사용자 초대에 실패했습니다"
|
||||
error = "초대장 전송에 실패했습니다"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "로그인"
|
||||
signInWith = "다음으로 로그인"
|
||||
oauthPending = "인증을 위해 브라우저를 여는 중..."
|
||||
orContinueWith = "또는 이메일로 계속"
|
||||
serverRequirement = "참고: 서버에서 로그인 기능이 활성화되어 있어야 합니다."
|
||||
showInstructions = "활성화 방법"
|
||||
hideInstructions = "지침 숨기기"
|
||||
instructions = "Stirling PDF 서버에서 로그인 기능을 활성화하려면:"
|
||||
instructionsEnvVar = "다음 환경 변수를 설정하세요:"
|
||||
instructionsOrYml = "또는 settings.yml에서:"
|
||||
instructionsRestart = "그런 다음 변경 사항을 적용하려면 서버를 재시작하세요."
|
||||
|
||||
[setup.login.username]
|
||||
label = "사용자 이름"
|
||||
|
||||
@@ -131,7 +131,7 @@ unsupported = "പിന്തുണയില്ല"
|
||||
|
||||
[toolPanel]
|
||||
placeholder = "തുടങ്ങാൻ ഒരു ടൂൾ തിരഞ്ഞെടുക്കുക"
|
||||
alpha = "ആൽഫ"
|
||||
alpha = "Alpha"
|
||||
premiumFeature = "പ്രീമിയം ഫീച്ചർ:"
|
||||
comingSoon = "വരുന്നു:"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "പ്രിയപ്പെട്ടവയിൽ നിന്ന
|
||||
fullscreen = "ഫുൾസ്ക്രീൻ മോഡിലേക്കു മാറ്റുക"
|
||||
sidebar = "സൈഡ്ബാർ മോഡിലേക്കു മാറ്റുക"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "ബാക്ക്എൻഡ് കണ്ടെത്താനായില്ല"
|
||||
retry = "വീണ്ടും ശ്രമിക്കുക"
|
||||
unreachable = "ഈ ആപ്പ്ലിക്കേഷൻ നിലവിൽ ബാക്ക്എൻഡുമായി കണക്റ്റ് ചെയ്യാൻ കഴിയുന്നില്ല. ബാക്ക്എൻഡിന്റെ നിലയും നെറ്റ്വർക്ക് കണക്റ്റിവിറ്റിയും പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക."
|
||||
|
||||
[zipWarning]
|
||||
title = "വലിയ ZIP ഫയൽ"
|
||||
message = "ഈ ZIP-ൽ {{count}} ഫയലുകൾ ഉണ്ട്. എങ്കിലും എക്സ്ട്രാക്റ്റ് ചെയ്യട്ടേ?"
|
||||
@@ -374,7 +369,7 @@ privacy = "സ്വകാര്യത"
|
||||
|
||||
[settings.developer]
|
||||
title = "ഡെവലപ്പർ"
|
||||
apiKeys = "API കീകൾ"
|
||||
apiKeys = "API Keys"
|
||||
|
||||
[settings.tooltips]
|
||||
enableLoginFirst = "ആദ്യം ലോഗിൻ മോഡ് സജീവമാക്കുക"
|
||||
@@ -714,7 +709,7 @@ title = "പരത്തുക"
|
||||
desc = "ഒരു PDF-ൽ നിന്ന് എല്ലാ ഇന്ററാക്ടീവ് ഘടകങ്ങളും ഫോമുകളും നീക്കം ചെയ്യുക"
|
||||
|
||||
[home.certSign]
|
||||
tags = "പ്രാമാണീകരണം,PEM,P12,ഔദ്യോഗികം,എൻക്രിപ്റ്റ്,സൈൻ,സർട്ടിഫിക്കറ്റ്,PKCS12,JKS,സെർവർ,മാനുവൽ,ഓട്ടോ"
|
||||
tags = "authenticate,PEM,P12,official,encrypt,sign,certificate,PKCS12,JKS,server,manual,auto"
|
||||
title = "സർട്ടിഫിക്കറ്റ് ഉപയോഗിച്ച് ഒപ്പിടുക"
|
||||
desc = "ഒരു സർട്ടിഫിക്കറ്റ്/കീ (PEM/P12) ഉപയോഗിച്ച് ഒരു PDF ഒപ്പിടുന്നു"
|
||||
|
||||
@@ -799,7 +794,7 @@ title = "ഒരൊറ്റ വലിയ പേജ്"
|
||||
desc = "എല്ലാ PDF പേജുകളും ഒരൊറ്റ വലിയ പേജിലേക്ക് ലയിപ്പിക്കുന്നു"
|
||||
|
||||
[home.showJS]
|
||||
tags = "javascript,കോഡ്,സ്ക്രിപ്റ്റ്"
|
||||
tags = "javascript,code,script"
|
||||
title = "ജാവാസ്ക്രിപ്റ്റ് കാണിക്കുക"
|
||||
desc = "ഒരു PDF-ൽ കുത്തിവച്ച ഏതെങ്കിലും JS തിരയുകയും പ്രദർശിപ്പിക്കുകയും ചെയ്യുന്നു"
|
||||
|
||||
@@ -919,10 +914,10 @@ title = "PDF-കൾ ഓവർലേ ചെയ്യുക"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF ടെക്സ്റ്റ് എഡിറ്റർ"
|
||||
desc = "PDFകളിലെ നിലവിലുള്ള ടെക്സ്റ്റും ചിത്രങ്ങളും തിരുത്തുക"
|
||||
desc = "ഗ്രൂപ്പുചെയ്ത ടെക്സ്റ്റ് എഡിറ്റിംഗിനോടും PDF വീണ്ടും സൃഷ്ടിക്കുന്നതോടും കൂടി Stirling PDF JSON എക്സ്പോർട്ടുകൾ റിവ്യൂ ചെയ്ത് എഡിറ്റ് ചെയ്യുക"
|
||||
|
||||
[home.addText]
|
||||
tags = "ടെക്സ്റ്റ്,അനോട്ടേഷൻ,ലേബൽ"
|
||||
tags = "text,annotation,label"
|
||||
title = "ടെക്സ്റ്റ് ചേർക്കുക"
|
||||
desc = "നിങ്ങളുടെ PDF-ൽ എവിടെയിലും കസ്റ്റം ടെക്സ്റ്റ് ചേർക്കുക"
|
||||
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "വരച്ച ഒപ്പ്"
|
||||
defaultImageLabel = "അപ്ലോഡ് ചെയ്ത ഒപ്പ്"
|
||||
defaultTextLabel = "ടൈപ്പ് ചെയ്ത ഒപ്പ്"
|
||||
saveButton = "ഒപ്പ് സേവ് ചെയ്യുക"
|
||||
savePersonal = "വ്യക്തിപരമായി സംരക്ഷിക്കുക"
|
||||
saveShared = "പങ്കിട്ടതായി സംരക്ഷിക്കുക"
|
||||
saveUnavailable = "സേവ് ചെയ്യാൻ ആദ്യം ഒരു ഒപ്പ് സൃഷ്ടിക്കുക."
|
||||
noChanges = "നിലവിലെ ഒപ്പ് ഇതിനകം സേവ് ചെയ്തിട്ടുണ്ട്."
|
||||
tempStorageTitle = "താൽക്കാലിക ബ്രൗസർ സ്റ്റോറേജ്"
|
||||
tempStorageDescription = "ഒപ്പുകൾ നിങ്ങളുടെ ബ്രൗസറിൽ മാത്രം സംഭരിക്കപ്പെടും. ബ്രൗസർ ഡാറ്റ നീക്കം ചെയ്താൽ അല്ലെങ്കിൽ ബ്രൗസർ മാറ്റിയാൽ അവ നഷ്ടപ്പെടും."
|
||||
personalHeading = "വ്യക്തിഗത ഒപ്പുകൾ"
|
||||
sharedHeading = "പങ്കിട്ട ഒപ്പുകൾ"
|
||||
personalDescription = "ഈ ഒപ്പുകൾ നിങ്ങള്ക്ക് മാത്രമേ കാണാനാകൂ."
|
||||
sharedDescription = "എല്ലാ ഉപയോക്താക്കളും ഈ ഒപ്പുകൾ കാണുകയും ഉപയോഗിക്കുകയും ചെയ്യാം."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "ഡ്രോയിംഗ്"
|
||||
@@ -2747,7 +2734,7 @@ submit = "സമർപ്പിക്കുക"
|
||||
failed = "മൾട്ടി-പേജ് ലേഔട്ട് സൃഷ്ടിക്കുമ്പോൾ പിശക് സംഭവിച്ചു."
|
||||
|
||||
[bookletImposition]
|
||||
tags = "ബുക്ക്ലെറ്റ്,ഇംപോസിഷൻ,പ്രിന്റിംഗ്,ബൈൻഡിംഗ്,മടക്കൽ,സിഗ്നേച്ചർ"
|
||||
tags = "booklet,imposition,printing,binding,folding,signature"
|
||||
title = "ബുക്ക്ലെറ്റ് ഇംപോസിഷൻ"
|
||||
header = "ബുക്ക്ലെറ്റ് ഇംപോസിഷൻ"
|
||||
submit = "ബുക്ക്ലെറ്റ് സൃഷ്ടിക്കുക"
|
||||
@@ -2846,7 +2833,7 @@ scaleFactor = "ഒരു പേജിന്റെ സൂം നില (ക്ര
|
||||
submit = "സമർപ്പിക്കുക"
|
||||
|
||||
[adjustPageScale]
|
||||
tags = "വലിപ്പമാറ്റം,ഭേദഗതി,പരിമാണം,അനുസൃതമാക്കൽ"
|
||||
tags = "resize,modify,dimension,adapt"
|
||||
title = "പേജ് സ്കെയിൽ ക്രമപ്പെടുത്തുക"
|
||||
header = "പേജ് സ്കെയിൽ ക്രമപ്പെടുത്തുക"
|
||||
submit = "പേജ് സ്കെയിൽ ക്രമപ്പെടുത്തുക"
|
||||
@@ -2857,8 +2844,8 @@ label = "സ്കെയിൽ ഫാക്ടർ"
|
||||
[adjustPageScale.pageSize]
|
||||
label = "ടാർഗറ്റ് പേജ് വലിപ്പം"
|
||||
keep = "അസൽ വലിപ്പം നിലനിർത്തുക"
|
||||
letter = "ലറ്റർ"
|
||||
legal = "ലീഗൽ"
|
||||
letter = "Letter"
|
||||
legal = "Legal"
|
||||
|
||||
[adjustPageScale.error]
|
||||
failed = "പേജ് സ്കെയിൽ ക്രമപ്പെടുത്തുന്നതിനിടെ പിശക് സംഭവിച്ചു."
|
||||
@@ -3396,7 +3383,7 @@ certHint = "കസ്റ്റം ട്രസ്റ്റ് സോഴ്സ
|
||||
title = "സ്ഥിരീകരണ സെറ്റിങ്ങുകൾ"
|
||||
|
||||
[replaceColor]
|
||||
tags = "നിറം പകരുക,പേജ് പ്രവർത്തനങ്ങൾ,ബാക്ക്എൻഡ്,സെർവർ-സൈഡ്"
|
||||
tags = "Replace Colour,Page operations,Back end,server side"
|
||||
|
||||
[replaceColor.labels]
|
||||
settings = "സെറ്റിങ്ങുകൾ"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "ദയവായി സൈൻ ഇൻ ചെയ്യുക"
|
||||
ssoSignIn = "സിംഗിൾ സൈൻ-ഓൺ വഴി ലോഗിൻ ചെയ്യുക"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 ഓട്ടോ-ക്രിയേറ്റ് യൂസർ പ്രവർത്തനരഹിതമാക്കി"
|
||||
oAuth2AdminBlockedUser = "രജിസ്റ്റർ ചെയ്യാത്ത ഉപയോക്താക്കളുടെ രജിസ്ട്രേഷനോ ലോഗിൻ ചെയ്യുന്നതോ നിലവിൽ തടഞ്ഞിരിക്കുന്നു. ദയവായി അഡ്മിനിസ്ട്രേറ്ററുമായി ബന്ധപ്പെടുക."
|
||||
oAuth2RequiresLicense = "OAuth/SSO ലോഗിനിന് ഒരു പെയ്ഡ് ലൈസൻസ് (Server അല്ലെങ്കിൽ Enterprise) ആവശ്യമാണ്. നിങ്ങളുടെ പ്ലാൻ അപ്ഗ്രേഡ് ചെയ്യാൻ അഡ്മിനിസ്ട്രേറ്ററുമായി ബന്ധപ്പെടുക."
|
||||
saml2RequiresLicense = "SAML ലോഗിനിന് ഒരു പെയ്ഡ് ലൈസൻസ് (Server അല്ലെങ്കിൽ Enterprise) ആവശ്യമാണ്. നിങ്ങളുടെ പ്ലാൻ അപ്ഗ്രേഡ് ചെയ്യാൻ അഡ്മിനിസ്ട്രേറ്ററുമായി ബന്ധപ്പെടുക."
|
||||
maxUsersReached = "നിലവിലുള്ള ലൈസൻസിലെ പരമാവധി ഉപയോക്താക്കൾ എത്തിച്ചേർന്നു. നിങ്ങളുടെ പ്ലാൻ അപ്ഗ്രേഡ് ചെയ്യുകയോ കൂടുതൽ സീറ്റുകൾ ചേർക്കുകയോ ചെയ്യാൻ അഡ്മിനിസ്ട്രേറ്ററുമായി ബന്ധപ്പെടുക."
|
||||
oauth2RequestNotFound = "അംഗീകാര അഭ്യർത്ഥന കണ്ടെത്തിയില്ല"
|
||||
oauth2InvalidUserInfoResponse = "അസാധുവായ ഉപയോക്തൃ വിവര പ്രതികരണം"
|
||||
oauth2invalidRequest = "അസാധുവായ അഭ്യർത്ഥന"
|
||||
@@ -3790,7 +3774,7 @@ version = "നിലവിലെ റിലീസ്"
|
||||
title = "API ഡോക്യുമെന്റേഷൻ"
|
||||
header = "API ഡോക്യുമെന്റേഷൻ"
|
||||
desc = "Stirling PDF API എൻഡ്പോയിന്റുകൾ കാണുകയും പരിശോധിക്കുകയും ചെയ്യുക"
|
||||
tags = "api,ഡോക്യുമെന്റേഷൻ,swagger,എൻഡ്പോയിന്റുകൾ,വികസനം"
|
||||
tags = "api,documentation,swagger,endpoints,development"
|
||||
|
||||
[cookieBanner.popUp]
|
||||
title = "ഞങ്ങൾ കുക്കികൾ എങ്ങനെ ഉപയോഗിക്കുന്നു"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "വീതിക്ക് ഒത്താക്കുക"
|
||||
actualSize = "യഥാർത്ഥ വലിപ്പം"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "ഫയൽ പ്രിവ്യൂ ചെയ്യാൻ കഴിയില്ല"
|
||||
dualPageView = "രണ്ടുപേജ് ദൃശ്യം"
|
||||
firstPage = "ആദ്യ പേജ്"
|
||||
lastPage = "അവസാന പേജ്"
|
||||
nextPage = "അടുത്ത പേജ്"
|
||||
onlyPdfSupported = "വ്യൂവറിന് PDF ഫയലുകൾ മാത്രം പിന്തുണയ്ക്കാം. ഈ ഫയൽ വേറെ ഒരു ഫോർമാറ്റാണെന്ന് തോന്നുന്നു."
|
||||
previousPage = "മുൻപത്തെ പേജ്"
|
||||
singlePageView = "ഒറ്റ പേജ് ദൃശ്യം"
|
||||
unknownFile = "അപരിചിതമായ ഫയൽ"
|
||||
nextPage = "അടുത്ത പേജ്"
|
||||
zoomIn = "സൂം ഇൻ"
|
||||
zoomOut = "സൂം ഔട്ട്"
|
||||
singlePageView = "ഒറ്റ പേജ് ദൃശ്യം"
|
||||
dualPageView = "രണ്ടുപേജ് ദൃശ്യം"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "തിരഞ്ഞെടുത്ത ഫയലുകൾ അടയ്ക്കുക"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "സൈഡ്ബാർ മാറ്റുക"
|
||||
exportSelected = "തിരഞ്ഞെടുത്ത പേജുകൾ എക്സ്പോർട്ട് ചെയ്യുക"
|
||||
toggleAnnotations = "അനോട്ടേഷൻ ദൃശ്യമാനം മാറ്റുക"
|
||||
annotationMode = "അനോട്ടേഷൻ മോഡ് മാറ്റുക"
|
||||
print = "PDF അച്ചടിക്കുക"
|
||||
draw = "വരയ്ക്കുക"
|
||||
save = "സംരക്ഷിക്കുക"
|
||||
saveChanges = "മാറ്റങ്ങൾ സംരക്ഷിക്കുക"
|
||||
@@ -4254,7 +4234,7 @@ label = "പ്രൊവൈഡർ"
|
||||
description = "ഓതന്റിക്കേഷനായി ഉപയോഗിക്കുന്ന OAuth2 പ്രൊവൈഡർ"
|
||||
|
||||
[admin.settings.connections.oauth2.issuer]
|
||||
label = "ഇഷ്യൂവർ URL"
|
||||
label = "Issuer URL"
|
||||
description = "OAuth2 പ്രൊവൈഡറിന്റെ issuer URL"
|
||||
|
||||
[admin.settings.connections.oauth2.clientId]
|
||||
@@ -4278,7 +4258,7 @@ label = "രജിസ്ട്രേഷൻ തടയുക"
|
||||
description = "OAuth2 വഴി പുതിയ ഉപയോക്തൃ രജിസ്ട്രേഷൻ തടയുക"
|
||||
|
||||
[admin.settings.connections.oauth2.scopes]
|
||||
label = "OAuth2 സ്കോപ്പുകൾ"
|
||||
label = "OAuth2 Scopes"
|
||||
description = "OAuth2 സ്കോപ്പുകളുടെ കോമ ഉപയോഗിച്ച് വേർതിരിച്ച പട്ടിക (ഉദാ., openid, profile, email)"
|
||||
|
||||
[admin.settings.connections.saml2]
|
||||
@@ -4517,7 +4497,6 @@ description = "Impressum-ലേക്ക് URL അല്ലെങ്കിൽ
|
||||
title = "പ്രീമിയം & എന്റർപ്രൈസ്"
|
||||
description = "നിങ്ങളുടെ പ്രീമിയം അല്ലെങ്കിൽ എന്റർപ്രൈസ് ലൈസൻസ് കീ ക്രമീകരിക്കുക."
|
||||
license = "ലൈസൻസ് കോൺഫിഗറേഷൻ"
|
||||
noInput = "ദയവായി ഒരു ലൈസന്റ്സ് കീ അല്ലെങ്കിൽ ഫയൽ നൽകുക"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "ലൈസൻസ് കീ അല്ലെങ്കിൽ സർട്ടിഫിക്കറ്റ് ഫയൽ ഉണ്ടോ?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "നിലവിലെ ലൈസൻസ് കീ ഓവർറൈറ്
|
||||
line2 = "നിങ്ങൾ മറ്റെവിടെയെങ്കിലും ബാക്കപ്പ് എടുത്തിട്ടില്ലെങ്കിൽ നിങ്ങളുടെ പഴയ ലൈസൻസ് സ്ഥിരമായി നഷ്ടപ്പെടും."
|
||||
line3 = "പ്രധാനപ്പെട്ടത്: ലൈസൻസ് കീകൾ സ്വകാര്യവും സുരക്ഷിതവുമാക്കി സൂക്ഷിക്കുക. ഒരിക്കലും അവ പൊതു വേദിയിൽ പങ്കുവെക്കരുത്."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "ലൈസൻസ് കീ"
|
||||
file = "സർട്ടിഫിക്കറ്റ് ഫയൽ"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "ലൈസൻസ് സർട്ടിഫിക്കറ്റ് ഫയൽ"
|
||||
description = "നിങ്ങളുടെ ഓഫ്ലൈൻ വാങ്ങലുകളിൽ നിന്നുള്ള .lic അല്ലെങ്കിൽ .cert ലൈസൻസ് ഫയൽ അപ്ലോഡ് ചെയ്യുക"
|
||||
choose = "ലൈസൻസ് ഫയൽ തിരഞ്ഞെടുക്കുക"
|
||||
selected = "തിരഞ്ഞെടുക്കിയത്: {{filename}} ({{size}})"
|
||||
successMessage = "ലൈസൻസ് ഫയൽ അപ്ലോഡ് ചെയ്തു വിജയകരമായി സജീവമാക്കിയിരിക്കുന്നു. റീസ്റ്റാർട്ട് ആവശ്യമില്ല."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "സജീവ ലൈസൻസ്"
|
||||
file = "ഉറവിടം: ലൈസൻസ് ഫയൽ ({{path}})"
|
||||
key = "ഉറവിടം: ലൈസൻസ് കീ"
|
||||
type = "തരം: {{type}}"
|
||||
noInput = "ദയവായി ഒരു ലൈസൻസ് കീ നൽകുകയോ ഒരു സർട്ടിഫിക്കറ്റ് ഫയൽ അപ്ലോഡ് ചെയ്യുകയോ ചെയ്യുക"
|
||||
success = "വിജയം"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "പ్రీമിയം സവിശേഷതകൾ പ്രാപ്തമാക്കുക"
|
||||
description = "പ്രോ/എന്റർപ്രൈസ് സവിശേഷതകൾക്കായി ലൈസൻസ് കീ പരിശോധനകൾ പ്രാപ്തമാക്കുക"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} തിരഞ്ഞെടുക്കപ്പെട
|
||||
download = "ഡൗൺലോഡ്"
|
||||
delete = "ഇല്ലാതാക്കുക"
|
||||
unsupported = "പിന്തുണയില്ല"
|
||||
active = "സജീവം"
|
||||
addToUpload = "അപ്ലോഡിലേക്ക് ചേർക്കുക"
|
||||
closeFile = "ഫയൽ അടയ്ക്കുക"
|
||||
deleteAll = "എല്ലാം ഇല്ലാതാക്കുക"
|
||||
loadingFiles = "ഫയലുകൾ ലോഡുചെയ്യുന്നു..."
|
||||
noFiles = "ഫയലുകളൊന്നും ലഭ്യമല്ല"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "കുറഞ്ഞത് ഒരു ഇമെയിൽ വിലാസമെങ്കിലും ആവശ്യമാണ്"
|
||||
submit = "ക്ഷണങ്ങൾ അയയ്ക്കുക"
|
||||
success = "ഉപയോക്താക്കളെ വിജയകരമായി ക്ഷണിച്ചു"
|
||||
partialFailure = "ചില ക്ഷണങ്ങൾ പരാജയപ്പെട്ടു"
|
||||
partialSuccess = "ചില ക്ഷണങ്ങൾ പരാജയപ്പെട്ടു"
|
||||
allFailed = "ഉപയോക്താക്കളെ ക്ഷണിക്കൽ പരാജയപ്പെട്ടു"
|
||||
error = "ക്ഷണങ്ങൾ അയയ്ക്കൽ പരാജയപ്പെട്ടു"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "ലോഗിൻ"
|
||||
signInWith = "ഇതുപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യുക"
|
||||
oauthPending = "ഓതന്റിക്കേഷനായി ബ്രൗസർ തുറക്കുന്നു..."
|
||||
orContinueWith = "അല്ലെങ്കിൽ ഇമെയിലോടെ തുടരുക"
|
||||
serverRequirement = "ശ്രദ്ധിക്കുക: സെർവറിൽ ലോഗിൻ പ്രവർത്തനക്ഷമമാക്കിയിരിക്കണം."
|
||||
showInstructions = "എങ്ങനെ പ്രവർത്തനക്ഷമമാക്കാം?"
|
||||
hideInstructions = "നിർദ്ദേശങ്ങൾ മറയ്ക്കുക"
|
||||
instructions = "നിങ്ങളുടെ Stirling PDF സെർവറിൽ ലോഗിൻ പ്രവർത്തനക്ഷമമാക്കാൻ:"
|
||||
instructionsEnvVar = "Environment variable സജ്ജമാക്കുക:"
|
||||
instructionsOrYml = "അല്ലെങ്കിൽ settings.yml-ൽ:"
|
||||
instructionsRestart = "തുടർന്ന് മാറ്റങ്ങൾ പ്രാബല്യത്തിൽ വരാൻ നിങ്ങളുടെ സെർവർ റീസ്റ്റാർട്ട് ചെയ്യുക."
|
||||
|
||||
[setup.login.username]
|
||||
label = "യൂസർനെയിം"
|
||||
@@ -5899,7 +5850,7 @@ singleLine = "സിംഗിൾ ലൈൻ"
|
||||
[pdfTextEditor.badges]
|
||||
unsaved = "എഡിറ്റ് ചെയ്തു"
|
||||
modified = "എഡിറ്റ് ചെയ്തു"
|
||||
earlyAccess = "എർലി ആക്സസ്"
|
||||
earlyAccess = "Early Access"
|
||||
|
||||
[pdfTextEditor.actions]
|
||||
reset = "മാറ്റങ്ങൾ റീസെറ്റ് ചെയ്യുക"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Uit favorieten verwijderen"
|
||||
fullscreen = "Overschakelen naar volledig scherm"
|
||||
sidebar = "Overschakelen naar zijbalkmodus"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend niet gevonden"
|
||||
retry = "Opnieuw proberen"
|
||||
unreachable = "De applicatie kan momenteel geen verbinding maken met de backend. Controleer de status van de backend en de netwerkverbinding en probeer het vervolgens opnieuw."
|
||||
|
||||
[zipWarning]
|
||||
title = "Groot ZIP-bestand"
|
||||
message = "Dit ZIP-bestand bevat {{count}} bestanden. Toch uitpakken?"
|
||||
@@ -352,7 +347,7 @@ teams = "Teams"
|
||||
title = "Configuratie"
|
||||
systemSettings = "Systeeminstellingen"
|
||||
features = "Functies"
|
||||
endpoints = "Eindpunten"
|
||||
endpoints = "Endpoints"
|
||||
database = "Database"
|
||||
advanced = "Geavanceerd"
|
||||
|
||||
@@ -561,7 +556,7 @@ totalEndpoints = "Totaal aantal endpoints"
|
||||
totalVisits = "Totaal aantal bezoeken"
|
||||
showing = "Weergeven"
|
||||
selectedVisits = "Geselecteerde bezoeken"
|
||||
endpoint = "Eindpunt"
|
||||
endpoint = "Endpoint"
|
||||
visits = "Bezoeken"
|
||||
percentage = "Percentage"
|
||||
loading = "Laden..."
|
||||
@@ -919,7 +914,7 @@ title = "PDF's overlappen"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF-teksteditor"
|
||||
desc = "Bewerk bestaande tekst en afbeeldingen in PDF's"
|
||||
desc = "Bekijk en bewerk Stirling PDF JSON-exporten met gegroepeerde tekstbewerking en het opnieuw genereren van PDF's"
|
||||
|
||||
[home.addText]
|
||||
tags = "tekst,annotatie,label"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Getekende handtekening"
|
||||
defaultImageLabel = "Geüploade handtekening"
|
||||
defaultTextLabel = "Getypte handtekening"
|
||||
saveButton = "Handtekening opslaan"
|
||||
savePersonal = "Als persoonlijk opslaan"
|
||||
saveShared = "Als gedeeld opslaan"
|
||||
saveUnavailable = "Maak eerst een handtekening om deze op te slaan."
|
||||
noChanges = "De huidige handtekening is al opgeslagen."
|
||||
tempStorageTitle = "Tijdelijke browseropslag"
|
||||
tempStorageDescription = "Handtekeningen worden alleen in je browser opgeslagen. Ze gaan verloren als je je browsergegevens wist of van browser wisselt."
|
||||
personalHeading = "Persoonlijke handtekeningen"
|
||||
sharedHeading = "Gedeelde handtekeningen"
|
||||
personalDescription = "Alleen jij kunt deze handtekeningen zien."
|
||||
sharedDescription = "Alle gebruikers kunnen deze handtekeningen zien en gebruiken."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Tekening"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Gelieve in te loggen"
|
||||
ssoSignIn = "Inloggen via Single Sign-on"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Automatisch aanmaken gebruiker uitgeschakeld"
|
||||
oAuth2AdminBlockedUser = "Registratie of inloggen van niet-registreerde gebruikers is helaas momenteel geblokkeerd. Neem contact op met de beheerder."
|
||||
oAuth2RequiresLicense = "OAuth/SSO-inloggen vereist een betaalde licentie (Server of Enterprise). Neem contact op met de beheerder om uw abonnement te upgraden."
|
||||
saml2RequiresLicense = "SAML-inloggen vereist een betaalde licentie (Server of Enterprise). Neem contact op met de beheerder om uw abonnement te upgraden."
|
||||
maxUsersReached = "Het maximumaantal gebruikers voor uw huidige licentie is bereikt. Neem contact op met de beheerder om uw abonnement te upgraden of extra plaatsen toe te voegen."
|
||||
oauth2RequestNotFound = "Autorisatieverzoek niet gevonden"
|
||||
oauth2InvalidUserInfoResponse = "Ongeldige reactie op gebruikersinfo"
|
||||
oauth2invalidRequest = "Ongeldig verzoek"
|
||||
@@ -3824,7 +3808,7 @@ description = "These cookies are essential for the website to function properly.
|
||||
2 = "Altijd ingeschakeld"
|
||||
|
||||
[cookieBanner.preferencesModal.analytics]
|
||||
title = "Analyse"
|
||||
title = "Analytics"
|
||||
description = "Deze cookies helpen ons te begrijpen hoe onze tools worden gebruikt, zodat we ons kunnen richten op het bouwen van de functies die onze community het meest waardeert. Wees gerust—Stirling PDF kan niet en zal nooit de inhoud van de documenten waarmee je werkt volgen."
|
||||
|
||||
[cookieBanner.services]
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Passend op breedte"
|
||||
actualSize = "Werkelijke grootte"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Kan voorbeeld van bestand niet weergeven"
|
||||
dualPageView = "Dubbele paginaweergave"
|
||||
firstPage = "Eerste pagina"
|
||||
lastPage = "Laatste pagina"
|
||||
nextPage = "Volgende pagina"
|
||||
onlyPdfSupported = "De viewer ondersteunt alleen PDF-bestanden. Dit bestand lijkt een ander formaat te hebben."
|
||||
previousPage = "Vorige pagina"
|
||||
singlePageView = "Enkele paginaweergave"
|
||||
unknownFile = "Onbekend bestand"
|
||||
nextPage = "Volgende pagina"
|
||||
zoomIn = "Inzoomen"
|
||||
zoomOut = "Uitzoomen"
|
||||
singlePageView = "Enkele paginaweergave"
|
||||
dualPageView = "Dubbele paginaweergave"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Geselecteerde bestanden sluiten"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Zijbalk tonen/verbergen"
|
||||
exportSelected = "Geselecteerde pagina's exporteren"
|
||||
toggleAnnotations = "Annotaties tonen/verbergen"
|
||||
annotationMode = "Annotatiemodus schakelen"
|
||||
print = "PDF afdrukken"
|
||||
draw = "Tekenen"
|
||||
save = "Opslaan"
|
||||
saveChanges = "Wijzigingen opslaan"
|
||||
@@ -4366,7 +4346,7 @@ features = "Feature-flags"
|
||||
processing = "Verwerking"
|
||||
|
||||
[admin.settings.advanced.endpoints]
|
||||
label = "Eindpunten"
|
||||
label = "Endpoints"
|
||||
manage = "API-endpoints beheren"
|
||||
description = "Endpointbeheer wordt geconfigureerd via YAML. Zie de documentatie voor details over het in-/uitschakelen van specifieke endpoints."
|
||||
|
||||
@@ -4517,7 +4497,6 @@ description = "URL of bestandsnaam van het impressum (in sommige jurisdicties ve
|
||||
title = "Premium & Enterprise"
|
||||
description = "Configureer je premium- of enterprise-licentiesleutel."
|
||||
license = "Licentieconfiguratie"
|
||||
noInput = "Geef een licentiesleutel of bestand op"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Heb je een licentiesleutel of certificaatbestand?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Het overschrijven van je huidige licentiesleutel kan niet ongedaan word
|
||||
line2 = "Je vorige licentie gaat permanent verloren, tenzij je er elders een back-up van hebt."
|
||||
line3 = "Belangrijk: houd licentiesleutels privé en veilig. Deel ze nooit openbaar."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Licentiesleutel"
|
||||
file = "Certificaatbestand"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Licentiecertificaatbestand"
|
||||
description = "Upload je .lic- of .cert-licentiebestand van offline aankopen"
|
||||
choose = "Kies licentiebestand"
|
||||
selected = "Geselecteerd: {{filename}} ({{size}})"
|
||||
successMessage = "Licentiebestand succesvol geüpload en geactiveerd. Herstarten niet vereist."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Actieve licentie"
|
||||
file = "Bron: licentiebestand ({{path}})"
|
||||
key = "Bron: licentiesleutel"
|
||||
type = "Type: {{type}}"
|
||||
noInput = "Geef een licentiesleutel op of upload een certificaatbestand"
|
||||
success = "Succes"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Premiumfuncties inschakelen"
|
||||
description = "Licentiesleutelcontrole inschakelen voor pro-/enterprise-functies"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} geselecteerd"
|
||||
download = "Downloaden"
|
||||
delete = "Verwijderen"
|
||||
unsupported = "Niet ondersteund"
|
||||
active = "Actief"
|
||||
addToUpload = "Aan upload toevoegen"
|
||||
closeFile = "Bestand sluiten"
|
||||
deleteAll = "Alles verwijderen"
|
||||
loadingFiles = "Bestanden laden..."
|
||||
noFiles = "Geen bestanden beschikbaar"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Er is minstens één e-mailadres vereist"
|
||||
submit = "Uitnodigingen verzenden"
|
||||
success = "Gebruiker(s) succesvol uitgenodigd"
|
||||
partialFailure = "Sommige uitnodigingen zijn mislukt"
|
||||
partialSuccess = "Sommige uitnodigingen zijn mislukt"
|
||||
allFailed = "Uitnodigen van gebruikers is mislukt"
|
||||
error = "Uitnodigingen verzenden is mislukt"
|
||||
|
||||
@@ -5754,7 +5712,7 @@ title = "Grafiek van endpointgebruik"
|
||||
|
||||
[usage.table]
|
||||
title = "Gedetailleerde statistieken"
|
||||
endpoint = "Eindpunt"
|
||||
endpoint = "Endpoint"
|
||||
visits = "Bezoeken"
|
||||
percentage = "Percentage"
|
||||
noData = "Geen gegevens beschikbaar"
|
||||
@@ -5842,13 +5800,6 @@ submit = "Inloggen"
|
||||
signInWith = "Inloggen met"
|
||||
oauthPending = "Browser wordt geopend voor authenticatie..."
|
||||
orContinueWith = "Of ga verder met e-mail"
|
||||
serverRequirement = "Let op: op de server moet inloggen zijn ingeschakeld."
|
||||
showInstructions = "Hoe inschakelen?"
|
||||
hideInstructions = "Instructies verbergen"
|
||||
instructions = "Om inloggen op uw Stirling PDF-server in te schakelen:"
|
||||
instructionsEnvVar = "Stel de omgevingsvariabele in:"
|
||||
instructionsOrYml = "Of in settings.yml:"
|
||||
instructionsRestart = "Start vervolgens uw server opnieuw zodat de wijzigingen van kracht worden."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Gebruikersnaam"
|
||||
|
||||
@@ -131,7 +131,7 @@ unsupported = "Ikke støttet"
|
||||
|
||||
[toolPanel]
|
||||
placeholder = "Velg et verktøy for å komme i gang"
|
||||
alpha = "Alfa"
|
||||
alpha = "Alpha"
|
||||
premiumFeature = "Premium-funksjon:"
|
||||
comingSoon = "Kommer snart:"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Fjern fra favoritter"
|
||||
fullscreen = "Bytt til fullskjerm-modus"
|
||||
sidebar = "Bytt til sidepanel-modus"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend ikke funnet"
|
||||
retry = "Prøv igjen"
|
||||
unreachable = "Programmet kan for øyeblikket ikke koble til backend. Kontroller backend-status og nettverkstilkobling, og prøv igjen."
|
||||
|
||||
[zipWarning]
|
||||
title = "Stor ZIP-fil"
|
||||
message = "Denne ZIP-en inneholder {{count}} filer. Pakk ut likevel?"
|
||||
@@ -918,8 +913,8 @@ desc = "Legger PDF-er over hverandre"
|
||||
title = "Overlay PDF-er"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "PDF-teksteditor"
|
||||
desc = "Rediger eksisterende tekst og bilder i PDF-filer"
|
||||
title = "PDF-tekstredigerer"
|
||||
desc = "Gå gjennom og rediger Stirling PDF JSON-eksporter med gruppert tekstredigering og regenerering av PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "tekst,merknad,etikett"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Tegnet signatur"
|
||||
defaultImageLabel = "Opplastet signatur"
|
||||
defaultTextLabel = "Tekstsignatur"
|
||||
saveButton = "Lagre signatur"
|
||||
savePersonal = "Lagre personlig"
|
||||
saveShared = "Lagre delt"
|
||||
saveUnavailable = "Opprett en signatur først for å lagre den."
|
||||
noChanges = "Gjeldende signatur er allerede lagret."
|
||||
tempStorageTitle = "Midlertidig nettleserlagring"
|
||||
tempStorageDescription = "Signaturer lagres bare i nettleseren din. De går tapt hvis du sletter nettleserdata eller bytter nettleser."
|
||||
personalHeading = "Personlige signaturer"
|
||||
sharedHeading = "Delte signaturer"
|
||||
personalDescription = "Bare du kan se disse signaturene."
|
||||
sharedDescription = "Alle brukere kan se og bruke disse signaturene."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Tegning"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Vennligst logg inn"
|
||||
ssoSignIn = "Logg inn via Enkel Pålogging"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Auto-Opretting av bruker deaktivert"
|
||||
oAuth2AdminBlockedUser = "Registrering eller pålogging for ikke-registrerte brukere er for øyeblikket blokkert. Vennligst kontakt administrator"
|
||||
oAuth2RequiresLicense = "OAuth/SSO-pålogging krever en betalt lisens (Server eller Enterprise). Kontakt administratoren for å oppgradere planen din."
|
||||
saml2RequiresLicense = "SAML-pålogging krever en betalt lisens (Server eller Enterprise). Kontakt administratoren for å oppgradere planen din."
|
||||
maxUsersReached = "Maksimalt antall brukere er nådd for din nåværende lisens. Kontakt administratoren for å oppgradere planen din eller legge til flere brukerplasser."
|
||||
oauth2RequestNotFound = "Autentiseringsforespørsel ikke funnet"
|
||||
oauth2InvalidUserInfoResponse = "Ugyldig brukerinforespons"
|
||||
oauth2invalidRequest = "Ugyldig forespørsel"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Tilpass til bredde"
|
||||
actualSize = "Faktisk størrelse"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Kan ikke forhåndsvise fil"
|
||||
dualPageView = "Dobbelsidevisning"
|
||||
firstPage = "Første side"
|
||||
lastPage = "Siste side"
|
||||
nextPage = "Neste side"
|
||||
onlyPdfSupported = "Visningsprogrammet støtter bare PDF-filer. Denne filen ser ut til å ha et annet format."
|
||||
previousPage = "Forrige side"
|
||||
singlePageView = "Enkeltsidevisning"
|
||||
unknownFile = "Ukjent fil"
|
||||
nextPage = "Neste side"
|
||||
zoomIn = "Zoom inn"
|
||||
zoomOut = "Zoom ut"
|
||||
singlePageView = "Enkeltsidevisning"
|
||||
dualPageView = "Dobbelsidevisning"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Lukk valgte filer"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Vis/skjul sidepanel"
|
||||
exportSelected = "Eksporter valgte sider"
|
||||
toggleAnnotations = "Vis/skjul merknader"
|
||||
annotationMode = "Veksle merknadsmodus"
|
||||
print = "Skriv ut PDF"
|
||||
draw = "Tegn"
|
||||
save = "Lagre"
|
||||
saveChanges = "Lagre endringer"
|
||||
@@ -4176,7 +4156,7 @@ description = "Spor brukerhandlinger og systemhendelser for etterlevelse og sikk
|
||||
|
||||
[admin.settings.security.audit.level]
|
||||
label = "Revisjonsnivå"
|
||||
description = "0=AV, 1=GRUNNLEGGENDE, 2=STANDARD, 3=DETALJERT"
|
||||
description = "0=OFF, 1=BASIC, 2=STANDARD, 3=VERBOSE"
|
||||
|
||||
[admin.settings.security.audit.retentionDays]
|
||||
label = "Bevaring av revisjon (dager)"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL eller filnavn til impressum (påkrevd i noen jurisdiksjoner)"
|
||||
title = "Premium og Enterprise"
|
||||
description = "Konfigurer din premium- eller enterprise-lisensnøkkel."
|
||||
license = "Lisenskonfigurasjon"
|
||||
noInput = "Oppgi en lisensnøkkel eller fil"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Har du en lisensnøkkel eller sertifikatfil?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Å overskrive gjeldende lisensnøkkel kan ikke angres."
|
||||
line2 = "Den forrige lisensen vil gå tapt permanent med mindre du har sikkerhetskopiert den et annet sted."
|
||||
line3 = "Viktig: Hold lisensnøkler private og sikre. Del dem aldri offentlig."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Lisensnøkkel"
|
||||
file = "Sertifikatfil"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Lisenssertifikatfil"
|
||||
description = "Last opp .lic- eller .cert-lisensfilen din fra offline-kjøp"
|
||||
choose = "Velg lisensfil"
|
||||
selected = "Valgt: {{filename}} ({{size}})"
|
||||
successMessage = "Lisensfilen ble lastet opp og aktivert. Omstart er ikke nødvendig."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Aktiv lisens"
|
||||
file = "Kilde: Lisensfil ({{path}})"
|
||||
key = "Kilde: Lisensnøkkel"
|
||||
type = "Type: {{type}}"
|
||||
noInput = "Oppgi en lisensnøkkel eller last opp en sertifikatfil"
|
||||
success = "Vellykket"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Aktiver premiumfunksjoner"
|
||||
description = "Aktiver lisensnøkkelkontroller for pro-/enterprise-funksjoner"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} valgt"
|
||||
download = "Last ned"
|
||||
delete = "Slett"
|
||||
unsupported = "Ikke støttet"
|
||||
active = "Aktiv"
|
||||
addToUpload = "Legg til i opplasting"
|
||||
closeFile = "Lukk fil"
|
||||
deleteAll = "Slett alt"
|
||||
loadingFiles = "Laster filer..."
|
||||
noFiles = "Ingen filer tilgjengelig"
|
||||
@@ -5104,7 +5062,7 @@ title = "Erstatt-Inverter-Farge"
|
||||
|
||||
[replace-color.options]
|
||||
fill = "Fyllfarge"
|
||||
gradient = "Fargeovergang"
|
||||
gradient = "Gradient"
|
||||
|
||||
[replace-color.selectText]
|
||||
1 = "Erstatt eller Inverter farge alternativer"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Minst én e-postadresse er påkrevd"
|
||||
submit = "Send invitasjoner"
|
||||
success = "bruker(e) invitert"
|
||||
partialFailure = "Noen invitasjoner mislyktes"
|
||||
partialSuccess = "Noen invitasjoner mislyktes"
|
||||
allFailed = "Kunne ikke invitere brukere"
|
||||
error = "Kunne ikke sende invitasjoner"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "Logg inn"
|
||||
signInWith = "Logg inn med"
|
||||
oauthPending = "Åpner nettleser for autentisering..."
|
||||
orContinueWith = "Eller fortsett med e-post"
|
||||
serverRequirement = "Merk: Serveren må ha pålogging aktivert."
|
||||
showInstructions = "Hvordan aktivere?"
|
||||
hideInstructions = "Skjul instruksjoner"
|
||||
instructions = "Slik aktiverer du pålogging på din Stirling PDF-server:"
|
||||
instructionsEnvVar = "Sett miljøvariabelen:"
|
||||
instructionsOrYml = "Eller i settings.yml:"
|
||||
instructionsRestart = "Start deretter serveren på nytt for at endringene skal tre i kraft."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Brukernavn"
|
||||
@@ -5892,7 +5843,7 @@ paragraph = "Avsnittsside"
|
||||
sparse = "Sparsom tekst"
|
||||
|
||||
[pdfTextEditor.groupingMode]
|
||||
auto = "Automatisk"
|
||||
auto = "Auto"
|
||||
paragraph = "Avsnitt"
|
||||
singleLine = "Én linje"
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ unsupported = "Nieobsługiwane"
|
||||
|
||||
[toolPanel]
|
||||
placeholder = "Wybierz narzędzie, aby zacząć"
|
||||
alpha = "Alfa"
|
||||
alpha = "Alpha"
|
||||
premiumFeature = "Funkcja premium:"
|
||||
comingSoon = "Wkrótce:"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Usuń z ulubionych"
|
||||
fullscreen = "Przełącz na tryb pełnoekranowy"
|
||||
sidebar = "Przełącz na tryb paska bocznego"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Nie znaleziono backendu"
|
||||
retry = "Spróbuj ponownie"
|
||||
unreachable = "Aplikacja nie może obecnie połączyć się z backendem. Sprawdź stan backendu i łączność sieciową, a następnie spróbuj ponownie."
|
||||
|
||||
[zipWarning]
|
||||
title = "Duży plik ZIP"
|
||||
message = "Ten ZIP zawiera {{count}} plików. Mimo to rozpakować?"
|
||||
@@ -919,7 +914,7 @@ title = "Nałóż PDFa"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Edytor tekstu PDF"
|
||||
desc = "Edytuj istniejący tekst i obrazy w plikach PDF"
|
||||
desc = "Przeglądaj i edytuj eksporty JSON z Stirling PDF z grupową edycją tekstu i ponowną generacją PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "tekst,adnotacja,etykieta"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Podpis rysowany"
|
||||
defaultImageLabel = "Przesłany podpis"
|
||||
defaultTextLabel = "Podpis wpisany"
|
||||
saveButton = "Zapisz podpis"
|
||||
savePersonal = "Zapisz osobiste"
|
||||
saveShared = "Zapisz udostępnione"
|
||||
saveUnavailable = "Najpierw utwórz podpis, aby go zapisać."
|
||||
noChanges = "Bieżący podpis jest już zapisany."
|
||||
tempStorageTitle = "Tymczasowe przechowywanie w przeglądarce"
|
||||
tempStorageDescription = "Podpisy są przechowywane tylko w Twojej przeglądarce. Zostaną utracone po wyczyszczeniu danych przeglądarki lub zmianie przeglądarki."
|
||||
personalHeading = "Osobiste podpisy"
|
||||
sharedHeading = "Udostępnione podpisy"
|
||||
personalDescription = "Tylko Ty widzisz te podpisy."
|
||||
sharedDescription = "Wszyscy użytkownicy mogą widzieć i używać tych podpisów."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Rysunek"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Zaloguj się"
|
||||
ssoSignIn = "Zaloguj się za pomocą logowania jednokrotnego"
|
||||
oAuth2AutoCreateDisabled = "Wyłączono automatyczne tworzenie użytkownika OAUTH2"
|
||||
oAuth2AdminBlockedUser = "Rejestracja lub logowanie niezarejestrowanych użytkowników jest obecnie zablokowane. Prosimy o kontakt z administratorem."
|
||||
oAuth2RequiresLicense = "Logowanie OAuth/SSO wymaga płatnej licencji (Server lub Enterprise). Skontaktuj się z administratorem, aby uaktualnić swój plan."
|
||||
saml2RequiresLicense = "Logowanie SAML wymaga płatnej licencji (Server lub Enterprise). Skontaktuj się z administratorem, aby uaktualnić swój plan."
|
||||
maxUsersReached = "Osiągnięto maksymalną liczbę użytkowników dla Twojej obecnej licencji. Skontaktuj się z administratorem, aby uaktualnić plan lub dodać więcej miejsc."
|
||||
oauth2RequestNotFound = "Błąd logowania OAuth2"
|
||||
oauth2InvalidUserInfoResponse = "Niewłaściwe dane logowania"
|
||||
oauth2invalidRequest = "Nieprawidłowe żądanie"
|
||||
@@ -3552,7 +3536,7 @@ title = "PDF do pojedyńczej strony"
|
||||
header = "PDF do pojedyńczej strony"
|
||||
submit = "Zapisz dokument jako PDF z jedną stroną"
|
||||
description = "To narzędzie scali wszystkie strony Twojego PDF w jedną dużą stronę. Szerokość pozostanie taka jak w oryginalnych stronach, a wysokość będzie sumą wysokości wszystkich stron."
|
||||
filenamePrefix = "pojedyncza_strona"
|
||||
filenamePrefix = "single_page"
|
||||
|
||||
[pdfToSinglePage.files]
|
||||
placeholder = "Wybierz plik PDF w widoku głównym, aby rozpocząć"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Dopasuj do szerokości"
|
||||
actualSize = "Rzeczywisty rozmiar"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Nie można wyświetlić podglądu pliku"
|
||||
dualPageView = "Widok dwóch stron"
|
||||
firstPage = "Pierwsza strona"
|
||||
lastPage = "Ostatnia strona"
|
||||
nextPage = "Następna strona"
|
||||
onlyPdfSupported = "Przeglądarka obsługuje tylko pliki PDF. Ten plik wydaje się mieć inny format."
|
||||
previousPage = "Poprzednia strona"
|
||||
singlePageView = "Widok pojedynczej strony"
|
||||
unknownFile = "Nieznany plik"
|
||||
nextPage = "Następna strona"
|
||||
zoomIn = "Powiększ"
|
||||
zoomOut = "Pomniejsz"
|
||||
singlePageView = "Widok pojedynczej strony"
|
||||
dualPageView = "Widok dwóch stron"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Zamknij wybrane pliki"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Przełącz panel boczny"
|
||||
exportSelected = "Eksportuj wybrane strony"
|
||||
toggleAnnotations = "Przełącz widoczność adnotacji"
|
||||
annotationMode = "Przełącz tryb adnotacji"
|
||||
print = "Drukuj PDF"
|
||||
draw = "Rysuj"
|
||||
save = "Zapisz"
|
||||
saveChanges = "Zapisz zmiany"
|
||||
@@ -4176,7 +4156,7 @@ description = "Śledź działania użytkowników i zdarzenia systemowe na potrze
|
||||
|
||||
[admin.settings.security.audit.level]
|
||||
label = "Poziom audytu"
|
||||
description = "0=WYŁ., 1=PODSTAWOWY, 2=STANDARDOWY, 3=SZCZEGÓŁOWY"
|
||||
description = "0=OFF, 1=BASIC, 2=STANDARD, 3=VERBOSE"
|
||||
|
||||
[admin.settings.security.audit.retentionDays]
|
||||
label = "Przechowywanie audytu (dni)"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL lub nazwa pliku do impressum (wymagane w niektórych jurysdyk
|
||||
title = "Premium i Enterprise"
|
||||
description = "Skonfiguruj swój klucz licencyjny premium lub enterprise."
|
||||
license = "Konfiguracja licencji"
|
||||
noInput = "Podaj klucz licencyjny lub plik"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Masz klucz licencyjny lub plik certyfikatu?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Nadpisania bieżącego klucza licencyjnego nie można cofnąć."
|
||||
line2 = "Poprzednia licencja zostanie trwale utracona, jeśli nie masz jej kopii zapasowej."
|
||||
line3 = "Ważne: przechowuj klucze licencyjne prywatnie i bezpiecznie. Nigdy nie udostępniaj ich publicznie."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Klucz licencyjny"
|
||||
file = "Plik certyfikatu"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Plik certyfikatu licencji"
|
||||
description = "Prześlij swój plik licencji .lic lub .cert z zakupów offline"
|
||||
choose = "Wybierz plik licencji"
|
||||
selected = "Wybrano: {{filename}} ({{size}})"
|
||||
successMessage = "Plik licencji przesłano i pomyślnie aktywowano. Ponowne uruchomienie nie jest wymagane."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Aktywna licencja"
|
||||
file = "Źródło: plik licencji ({{path}})"
|
||||
key = "Źródło: klucz licencyjny"
|
||||
type = "Typ: {{type}}"
|
||||
noInput = "Podaj klucz licencyjny lub prześlij plik certyfikatu"
|
||||
success = "Sukces"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Włącz funkcje premium"
|
||||
description = "Włącz weryfikację klucza licencyjnego dla funkcji pro/enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} wybrane"
|
||||
download = "Pobierz"
|
||||
delete = "usuń"
|
||||
unsupported = "Nieobsługiwane"
|
||||
active = "Aktywny"
|
||||
addToUpload = "Dodaj do przesyłania"
|
||||
closeFile = "Zamknij plik"
|
||||
deleteAll = "Usuń wszystko"
|
||||
loadingFiles = "Ładowanie plików..."
|
||||
noFiles = "Brak dostępnych plików"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Wymagany jest co najmniej jeden adres e‑mail"
|
||||
submit = "Wyślij zaproszenia"
|
||||
success = "Pomyślnie zaproszono użytkowników"
|
||||
partialFailure = "Niektóre zaproszenia nie powiodły się"
|
||||
partialSuccess = "Niektóre zaproszenia nie powiodły się"
|
||||
allFailed = "Nie udało się zaprosić użytkowników"
|
||||
error = "Nie udało się wysłać zaproszeń"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "Zaloguj"
|
||||
signInWith = "Zaloguj przez"
|
||||
oauthPending = "Otwieranie przeglądarki do uwierzytelnienia..."
|
||||
orContinueWith = "Lub kontynuuj e‑mailem"
|
||||
serverRequirement = "Uwaga: Na serwerze musi być włączone logowanie."
|
||||
showInstructions = "Jak włączyć?"
|
||||
hideInstructions = "Ukryj instrukcje"
|
||||
instructions = "Aby włączyć logowanie na swoim serwerze Stirling PDF:"
|
||||
instructionsEnvVar = "Ustaw zmienną środowiskową:"
|
||||
instructionsOrYml = "Lub w settings.yml:"
|
||||
instructionsRestart = "Następnie uruchom ponownie serwer, aby zmiany zaczęły obowiązywać."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Nazwa użytkownika"
|
||||
@@ -5892,7 +5843,7 @@ paragraph = "Strona akapitowa"
|
||||
sparse = "Rzadki tekst"
|
||||
|
||||
[pdfTextEditor.groupingMode]
|
||||
auto = "Automatycznie"
|
||||
auto = "Auto"
|
||||
paragraph = "Akapit"
|
||||
singleLine = "Pojedyncza linia"
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ unsupported = "Não suportado"
|
||||
|
||||
[toolPanel]
|
||||
placeholder = "Escolha uma ferramenta para começar"
|
||||
alpha = "Alfa"
|
||||
alpha = "Alpha"
|
||||
premiumFeature = "Recurso premium:"
|
||||
comingSoon = "Em breve:"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Remover dos favoritos"
|
||||
fullscreen = "Alternar para modo tela cheia"
|
||||
sidebar = "Alternar para modo barra lateral"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend não encontrado"
|
||||
retry = "Tentar novamente"
|
||||
unreachable = "No momento, o aplicativo não consegue se conectar ao backend. Verifique o status do backend e a conectividade de rede e tente novamente."
|
||||
|
||||
[zipWarning]
|
||||
title = "Arquivo ZIP grande"
|
||||
message = "Este ZIP contém {{count}} arquivos. Extrair mesmo assim?"
|
||||
@@ -918,8 +913,8 @@ desc = "Sobrepor um PDF sobre outro"
|
||||
title = "Sobrepor PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Editor de Texto em PDF"
|
||||
desc = "Edite texto e imagens existentes em PDFs"
|
||||
title = "Editor de texto de PDF"
|
||||
desc = "Revise e edite exportações JSON do Stirling PDF com edição de texto agrupada e regeneração do PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "texto,anotação,rótulo"
|
||||
@@ -1225,7 +1220,7 @@ odtExt = "Texto OpenDocument (.odt)"
|
||||
pptExt = "PowerPoint (.pptx)"
|
||||
odpExt = "Apresentação OpenDocument (.odp)"
|
||||
txtExt = "Texto simples (.txt)"
|
||||
rtfExt = "Formato Rich Text (.rtf)"
|
||||
rtfExt = "Rich Text Format (.rtf)"
|
||||
selectedFiles = "Arquivos selecionados"
|
||||
noFileSelected = "Nenhum arquivo selecionado. Use o painel de arquivos para adicionar arquivos."
|
||||
convertFiles = "Converter arquivos"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Assinatura desenhada"
|
||||
defaultImageLabel = "Assinatura enviada"
|
||||
defaultTextLabel = "Assinatura digitada"
|
||||
saveButton = "Salvar assinatura"
|
||||
savePersonal = "Salvar pessoal"
|
||||
saveShared = "Salvar compartilhado"
|
||||
saveUnavailable = "Crie uma assinatura primeiro para salvá-la."
|
||||
noChanges = "A assinatura atual já está salva."
|
||||
tempStorageTitle = "Armazenamento temporário do navegador"
|
||||
tempStorageDescription = "As assinaturas são armazenadas apenas no seu navegador. Elas serão perdidas se você limpar os dados do navegador ou trocar de navegador."
|
||||
personalHeading = "Assinaturas pessoais"
|
||||
sharedHeading = "Assinaturas compartilhadas"
|
||||
personalDescription = "Somente você pode ver essas assinaturas."
|
||||
sharedDescription = "Todos os usuários podem ver e usar essas assinaturas."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Desenho"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Por favor, inicie a sessão"
|
||||
ssoSignIn = "Iniciar sessão através de login único (SSO)"
|
||||
oAuth2AutoCreateDisabled = "Auto-Criar Usuário OAUTH2 Desativado"
|
||||
oAuth2AdminBlockedUser = "O registro ou login de usuários não registrados está atualmente bloqueado. Entre em contato com o administrador."
|
||||
oAuth2RequiresLicense = "O login via OAuth/SSO requer uma licença paga (Server ou Enterprise). Entre em contato com o administrador para atualizar seu plano."
|
||||
saml2RequiresLicense = "O login via SAML requer uma licença paga (Server ou Enterprise). Entre em contato com o administrador para atualizar seu plano."
|
||||
maxUsersReached = "Número máximo de usuários atingido para sua licença atual. Entre em contato com o administrador para atualizar seu plano ou adicionar mais assentos."
|
||||
oauth2RequestNotFound = "Solicitação de autorização não encontrada"
|
||||
oauth2InvalidUserInfoResponse = "Resposta de informação de usuário inválida"
|
||||
oauth2invalidRequest = "Requisição Inválida"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Ajustar à largura"
|
||||
actualSize = "Tamanho real"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Não é possível visualizar o arquivo"
|
||||
dualPageView = "Visualização de duas páginas"
|
||||
firstPage = "Primeira página"
|
||||
lastPage = "Última página"
|
||||
nextPage = "Próxima página"
|
||||
onlyPdfSupported = "O visualizador oferece suporte apenas a arquivos PDF. Este arquivo parece estar em um formato diferente."
|
||||
previousPage = "Página anterior"
|
||||
singlePageView = "Visualização de página única"
|
||||
unknownFile = "Arquivo desconhecido"
|
||||
nextPage = "Próxima página"
|
||||
zoomIn = "Ampliar"
|
||||
zoomOut = "Reduzir"
|
||||
singlePageView = "Visualização de página única"
|
||||
dualPageView = "Visualização de duas páginas"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Fechar arquivos selecionados"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Alternar barra lateral"
|
||||
exportSelected = "Exportar páginas selecionadas"
|
||||
toggleAnnotations = "Alternar visibilidade das anotações"
|
||||
annotationMode = "Alternar modo de anotação"
|
||||
print = "Imprimir PDF"
|
||||
draw = "Desenhar"
|
||||
save = "Salvar"
|
||||
saveChanges = "Salvar alterações"
|
||||
@@ -3948,7 +3928,7 @@ files = "Arquivos"
|
||||
activity = "Ativ."
|
||||
help = "Ajuda"
|
||||
account = "Conta"
|
||||
config = "Configurações"
|
||||
config = "Config"
|
||||
settings = "Ajustes"
|
||||
adminSettings = "Ajustes admin"
|
||||
allTools = "Ferram."
|
||||
@@ -4176,7 +4156,7 @@ description = "Rastrear ações do usuário e eventos do sistema para conformida
|
||||
|
||||
[admin.settings.security.audit.level]
|
||||
label = "Nível de auditoria"
|
||||
description = "0=DESLIGADO, 1=BÁSICO, 2=PADRÃO, 3=DETALHADO"
|
||||
description = "0=OFF, 1=BASIC, 2=STANDARD, 3=VERBOSE"
|
||||
|
||||
[admin.settings.security.audit.retentionDays]
|
||||
label = "Retenção de auditoria (dias)"
|
||||
@@ -4258,11 +4238,11 @@ label = "URL do emissor"
|
||||
description = "A URL do emissor do provedor OAuth2"
|
||||
|
||||
[admin.settings.connections.oauth2.clientId]
|
||||
label = "ID do cliente"
|
||||
label = "Client ID"
|
||||
description = "O Client ID do OAuth2 do seu provedor"
|
||||
|
||||
[admin.settings.connections.oauth2.clientSecret]
|
||||
label = "Segredo do cliente"
|
||||
label = "Client Secret"
|
||||
description = "O Client Secret do OAuth2 do seu provedor"
|
||||
|
||||
[admin.settings.connections.oauth2.useAsUsername]
|
||||
@@ -4517,7 +4497,6 @@ description = "URL ou nome de arquivo do impressum (exigido em algumas jurisdiç
|
||||
title = "Premium e Enterprise"
|
||||
description = "Configurar sua chave de licença premium ou enterprise."
|
||||
license = "Configuração de licença"
|
||||
noInput = "Forneça uma chave ou arquivo de licença"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Tem uma chave de licença ou arquivo de certificado?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Substituir sua chave de licença atual não pode ser desfeito."
|
||||
line2 = "Sua licença anterior será perdida permanentemente, a menos que você tenha um backup em outro lugar."
|
||||
line3 = "Importante: mantenha chaves de licença privadas e seguras. Nunca as compartilhe publicamente."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Chave de licença"
|
||||
file = "Arquivo de certificado"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Arquivo de certificado de licença"
|
||||
description = "Faça upload do seu arquivo de licença .lic ou .cert de compras offline"
|
||||
choose = "Escolher arquivo de licença"
|
||||
selected = "Selecionado: {{filename}} ({{size}})"
|
||||
successMessage = "Arquivo de licença enviado e ativado com sucesso. Não é necessário reiniciar."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Licença ativa"
|
||||
file = "Origem: arquivo de licença ({{path}})"
|
||||
key = "Origem: chave de licença"
|
||||
type = "Tipo: {{type}}"
|
||||
noInput = "Forneça uma chave de licença ou envie um arquivo de certificado"
|
||||
success = "Sucesso"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Habilitar recursos Premium"
|
||||
description = "Habilitar verificação de chave de licença para recursos pro/enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} selecionado(s)"
|
||||
download = "Baixar (JSON)"
|
||||
delete = "Apagar"
|
||||
unsupported = "Não suportado"
|
||||
active = "Ativo"
|
||||
addToUpload = "Adicionar ao upload"
|
||||
closeFile = "Fechar arquivo"
|
||||
deleteAll = "Excluir tudo"
|
||||
loadingFiles = "Carregando arquivos..."
|
||||
noFiles = "Nenhum arquivo disponível"
|
||||
@@ -5223,7 +5181,7 @@ active = "Ativo"
|
||||
disabled = "Desativado"
|
||||
activeSession = "Sessão ativa"
|
||||
member = "Membro"
|
||||
admin = "Administrador"
|
||||
admin = "Admin"
|
||||
editRole = "Editar função"
|
||||
enable = "Ativar"
|
||||
disable = "Desativar"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Ao menos um endereço de email é obrigatório"
|
||||
submit = "Enviar convites"
|
||||
success = "usuário(s) convidado(s) com sucesso"
|
||||
partialFailure = "Alguns convites falharam"
|
||||
partialSuccess = "Alguns convites falharam"
|
||||
allFailed = "Falha ao convidar usuários"
|
||||
error = "Falha ao enviar convites"
|
||||
|
||||
@@ -5842,20 +5800,13 @@ submit = "Login"
|
||||
signInWith = "Entrar com"
|
||||
oauthPending = "Abrindo o navegador para autenticação..."
|
||||
orContinueWith = "Ou continue com e-mail"
|
||||
serverRequirement = "Observação: o servidor deve ter o login ativado."
|
||||
showInstructions = "Como ativar?"
|
||||
hideInstructions = "Ocultar instruções"
|
||||
instructions = "Para ativar o login no seu servidor Stirling PDF:"
|
||||
instructionsEnvVar = "Defina a variável de ambiente:"
|
||||
instructionsOrYml = "Ou em settings.yml:"
|
||||
instructionsRestart = "Em seguida, reinicie o servidor para que as alterações entrem em vigor."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Usuário"
|
||||
placeholder = "Digite seu usuário"
|
||||
|
||||
[setup.login.email]
|
||||
label = "E-mail"
|
||||
label = "Email"
|
||||
placeholder = "Digite seu e-mail"
|
||||
|
||||
[setup.login.password]
|
||||
@@ -5892,7 +5843,7 @@ paragraph = "Página de parágrafos"
|
||||
sparse = "Texto esparso"
|
||||
|
||||
[pdfTextEditor.groupingMode]
|
||||
auto = "Automático"
|
||||
auto = "Auto"
|
||||
paragraph = "Parágrafo"
|
||||
singleLine = "Linha única"
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ unsupported = "Não suportado"
|
||||
|
||||
[toolPanel]
|
||||
placeholder = "Escolha uma ferramenta para começar"
|
||||
alpha = "Alfa"
|
||||
alpha = "Alpha"
|
||||
premiumFeature = "Funcionalidade premium:"
|
||||
comingSoon = "Em breve:"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Remover dos favoritos"
|
||||
fullscreen = "Mudar para modo de ecrã inteiro"
|
||||
sidebar = "Mudar para modo de barra lateral"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend não encontrado"
|
||||
retry = "Tentar novamente"
|
||||
unreachable = "A aplicação não consegue ligar-se ao backend neste momento. Verifique o estado do backend e a conectividade de rede e tente novamente."
|
||||
|
||||
[zipWarning]
|
||||
title = "Ficheiro ZIP grande"
|
||||
message = "Este ZIP contém {{count}} ficheiros. Extrair mesmo assim?"
|
||||
@@ -369,12 +364,12 @@ usageAnalytics = "Análise de utilização"
|
||||
|
||||
[settings.policiesPrivacy]
|
||||
title = "Políticas e Privacidade"
|
||||
legal = "Jurídico"
|
||||
legal = "Legal"
|
||||
privacy = "Privacidade"
|
||||
|
||||
[settings.developer]
|
||||
title = "Programador"
|
||||
apiKeys = "Chaves de API"
|
||||
apiKeys = "API Keys"
|
||||
|
||||
[settings.tooltips]
|
||||
enableLoginFirst = "Ative primeiro o modo de login"
|
||||
@@ -918,8 +913,8 @@ desc = "Sobrepõe PDFs em cima de outro PDF"
|
||||
title = "Sobrepor PDFs"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Editor de texto de PDF"
|
||||
desc = "Edite texto e imagens existentes dentro de PDFs"
|
||||
title = "Editor de texto PDF"
|
||||
desc = "Revise e edite exportações JSON do Stirling PDF com edição de texto agrupado e regeneração de PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "texto,anotação,etiqueta"
|
||||
@@ -1225,7 +1220,7 @@ odtExt = "Texto OpenDocument (.odt)"
|
||||
pptExt = "PowerPoint (.pptx)"
|
||||
odpExt = "Apresentação OpenDocument (.odp)"
|
||||
txtExt = "Texto simples (.txt)"
|
||||
rtfExt = "Formato de Texto Enriquecido (.rtf)"
|
||||
rtfExt = "Rich Text Format (.rtf)"
|
||||
selectedFiles = "Ficheiros selecionados"
|
||||
noFileSelected = "Nenhum ficheiro selecionado. Use o painel de ficheiros para adicionar ficheiros."
|
||||
convertFiles = "Converter ficheiros"
|
||||
@@ -1368,7 +1363,7 @@ title = "Adicionar Marca de Água"
|
||||
desc = "Adicionar marcas de água de texto ou imagem a ficheiros PDF"
|
||||
completed = "Marca de água adicionada"
|
||||
submit = "Adicionar Marca de Água"
|
||||
filenamePrefix = "com-marca-de-água"
|
||||
filenamePrefix = "watermarked"
|
||||
|
||||
[watermark.error]
|
||||
failed = "Ocorreu um erro ao adicionar a marca de água ao PDF."
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Assinatura desenhada"
|
||||
defaultImageLabel = "Assinatura carregada"
|
||||
defaultTextLabel = "Assinatura digitada"
|
||||
saveButton = "Guardar assinatura"
|
||||
savePersonal = "Guardar como pessoal"
|
||||
saveShared = "Guardar como partilhada"
|
||||
saveUnavailable = "Crie primeiro uma assinatura para a guardar."
|
||||
noChanges = "A assinatura atual já está guardada."
|
||||
tempStorageTitle = "Armazenamento temporário do navegador"
|
||||
tempStorageDescription = "As assinaturas são armazenadas apenas no seu navegador. Serão perdidas se limpar os dados do navegador ou mudar de navegador."
|
||||
personalHeading = "Assinaturas pessoais"
|
||||
sharedHeading = "Assinaturas partilhadas"
|
||||
personalDescription = "Apenas você pode ver estas assinaturas."
|
||||
sharedDescription = "Todos os utilizadores podem ver e usar estas assinaturas."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Desenho"
|
||||
@@ -2857,7 +2844,7 @@ label = "Fator de escala"
|
||||
[adjustPageScale.pageSize]
|
||||
label = "Tamanho da página de destino"
|
||||
keep = "Manter tamanho original"
|
||||
letter = "Carta"
|
||||
letter = "Letter"
|
||||
legal = "Legal"
|
||||
|
||||
[adjustPageScale.error]
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Por favor inicie sessão"
|
||||
ssoSignIn = "Iniciar sessão via Single Sign-On"
|
||||
oAuth2AutoCreateDisabled = "Criação Automática de Utilizador OAUTH2 Desativada"
|
||||
oAuth2AdminBlockedUser = "O registo ou login de utilizadores não registados está atualmente bloqueado. Por favor contacte o administrador."
|
||||
oAuth2RequiresLicense = "O início de sessão via OAuth/SSO requer uma licença paga (Server ou Enterprise). Contacte o administrador para atualizar o seu plano."
|
||||
saml2RequiresLicense = "O início de sessão SAML requer uma licença paga (Server ou Enterprise). Contacte o administrador para atualizar o seu plano."
|
||||
maxUsersReached = "Foi atingido o número máximo de utilizadores da sua licença atual. Contacte o administrador para atualizar o seu plano ou adicionar mais lugares."
|
||||
oauth2RequestNotFound = "Pedido de autorização não encontrado"
|
||||
oauth2InvalidUserInfoResponse = "Resposta de Informação de Utilizador Inválida"
|
||||
oauth2invalidRequest = "Pedido Inválido"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Ajustar à largura"
|
||||
actualSize = "Tamanho real"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Não é possível pré-visualizar o ficheiro"
|
||||
dualPageView = "Vista de duas páginas"
|
||||
firstPage = "Primeira página"
|
||||
lastPage = "Última página"
|
||||
nextPage = "Página seguinte"
|
||||
onlyPdfSupported = "O visualizador só suporta ficheiros PDF. Este ficheiro parece ter um formato diferente."
|
||||
previousPage = "Página anterior"
|
||||
singlePageView = "Vista de página única"
|
||||
unknownFile = "Ficheiro desconhecido"
|
||||
nextPage = "Página seguinte"
|
||||
zoomIn = "Ampliar"
|
||||
zoomOut = "Reduzir"
|
||||
singlePageView = "Vista de página única"
|
||||
dualPageView = "Vista de duas páginas"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Fechar ficheiros selecionados"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Alternar barra lateral"
|
||||
exportSelected = "Exportar páginas selecionadas"
|
||||
toggleAnnotations = "Alternar visibilidade das anotações"
|
||||
annotationMode = "Alternar modo de anotação"
|
||||
print = "Imprimir PDF"
|
||||
draw = "Desenhar"
|
||||
save = "Guardar"
|
||||
saveChanges = "Guardar alterações"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL ou nome de ficheiro para o impressum (obrigatório em algumas
|
||||
title = "Premium e Enterprise"
|
||||
description = "Configurar a sua chave de licença premium ou enterprise."
|
||||
license = "Configuração de licença"
|
||||
noInput = "Forneça uma chave ou ficheiro de licença"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Tem uma chave de licença ou ficheiro de certificado?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Sobrescrever a sua chave de licença atual não pode ser anulado."
|
||||
line2 = "A sua licença anterior será perdida permanentemente, a menos que a tenha guardado noutro local."
|
||||
line3 = "Importante: mantenha as chaves de licença privadas e seguras. Nunca as partilhe publicamente."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Chave de licença"
|
||||
file = "Ficheiro de certificado"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Ficheiro de certificado de licença"
|
||||
description = "Carregue o seu ficheiro de licença .lic ou .cert de compras offline"
|
||||
choose = "Escolher ficheiro de licença"
|
||||
selected = "Selecionado: {{filename}} ({{size}})"
|
||||
successMessage = "Ficheiro de licença carregado e ativado com sucesso. Não é necessário reiniciar."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Licença ativa"
|
||||
file = "Origem: ficheiro de licença ({{path}})"
|
||||
key = "Origem: chave de licença"
|
||||
type = "Tipo: {{type}}"
|
||||
noInput = "Forneça uma chave de licença ou carregue um ficheiro de certificado"
|
||||
success = "Sucesso"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Ativar funcionalidades premium"
|
||||
description = "Ativar verificações de chave de licença para funcionalidades pro/enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} selecionado(s)"
|
||||
download = "Transferir"
|
||||
delete = "Eliminar"
|
||||
unsupported = "Não suportado"
|
||||
active = "Ativo"
|
||||
addToUpload = "Adicionar ao carregamento"
|
||||
closeFile = "Fechar ficheiro"
|
||||
deleteAll = "Eliminar tudo"
|
||||
loadingFiles = "A carregar ficheiros..."
|
||||
noFiles = "Não há ficheiros disponíveis"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "É necessário pelo menos um endereço de email"
|
||||
submit = "Enviar convites"
|
||||
success = "utilizador(es) convidado(s) com sucesso"
|
||||
partialFailure = "Alguns convites falharam"
|
||||
partialSuccess = "Alguns convites falharam"
|
||||
allFailed = "Falha ao convidar utilizadores"
|
||||
error = "Falha ao enviar convites"
|
||||
|
||||
@@ -5327,7 +5285,7 @@ submit = "Gerar link de convite"
|
||||
[workspace.people.inviteMode]
|
||||
username = "Nome de utilizador"
|
||||
email = "Email"
|
||||
link = "Ligação"
|
||||
link = "Link"
|
||||
emailDisabled = "Convites por email requerem configuração de SMTP e mail.enableInvites=true nas definições"
|
||||
|
||||
[workspace.people.license]
|
||||
@@ -5842,13 +5800,6 @@ submit = "Iniciar sessão"
|
||||
signInWith = "Iniciar sessão com"
|
||||
oauthPending = "A abrir o navegador para autenticação..."
|
||||
orContinueWith = "Ou continuar com email"
|
||||
serverRequirement = "Nota: O servidor deve ter o início de sessão ativado."
|
||||
showInstructions = "Como ativar?"
|
||||
hideInstructions = "Ocultar instruções"
|
||||
instructions = "Para ativar o início de sessão no seu servidor Stirling PDF:"
|
||||
instructionsEnvVar = "Defina a variável de ambiente:"
|
||||
instructionsOrYml = "Ou em settings.yml:"
|
||||
instructionsRestart = "Em seguida, reinicie o servidor para que as alterações tenham efeito."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Nome de utilizador"
|
||||
@@ -5892,7 +5843,7 @@ paragraph = "Página de parágrafos"
|
||||
sparse = "Texto disperso"
|
||||
|
||||
[pdfTextEditor.groupingMode]
|
||||
auto = "Automático"
|
||||
auto = "Auto"
|
||||
paragraph = "Parágrafo"
|
||||
singleLine = "Linha única"
|
||||
|
||||
@@ -5984,7 +5935,7 @@ warnings = "Avisos"
|
||||
suggestions = "Notas"
|
||||
currentPageFonts = "Fontes nesta página"
|
||||
allFonts = "Todas as fontes"
|
||||
fallback = "alternativa"
|
||||
fallback = "fallback"
|
||||
missing = "em falta"
|
||||
perfectMessage = "Todas as fontes podem ser reproduzidas na perfeição."
|
||||
warningMessage = "Algumas fontes podem não ser renderizadas corretamente."
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Eliminați din favorite"
|
||||
fullscreen = "Comutați la modul ecran complet"
|
||||
sidebar = "Comutați la modul bară laterală"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend negăsit"
|
||||
retry = "Reîncearcă"
|
||||
unreachable = "Aplicația nu se poate conecta în prezent la backend. Verificați starea backend-ului și conexiunea la rețea, apoi încercați din nou."
|
||||
|
||||
[zipWarning]
|
||||
title = "Fișier ZIP mare"
|
||||
message = "Acest ZIP conține {{count}} fișiere. Extrageți oricum?"
|
||||
@@ -918,8 +913,8 @@ desc = "Suprapune PDF-uri peste alt PDF"
|
||||
title = "Suprapune PDF-uri"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Editor de text PDF"
|
||||
desc = "Editați textul și imaginile existente în PDF-uri"
|
||||
title = "Editor text PDF"
|
||||
desc = "Revizuiește și editează exporturile JSON Stirling PDF cu editare de text grupată și regenerare PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "text,anotare,etichetă"
|
||||
@@ -1221,11 +1216,11 @@ pdfaDigitalSignatureWarning = "PDF-ul conține o semnătură digitală. Aceasta
|
||||
fileFormat = "Format fișier"
|
||||
wordDoc = "Document Word"
|
||||
wordDocExt = "Document Word (.docx)"
|
||||
odtExt = "Text OpenDocument (.odt)"
|
||||
odtExt = "OpenDocument Text (.odt)"
|
||||
pptExt = "PowerPoint (.pptx)"
|
||||
odpExt = "Prezentare OpenDocument (.odp)"
|
||||
odpExt = "OpenDocument Presentation (.odp)"
|
||||
txtExt = "Text simplu (.txt)"
|
||||
rtfExt = "Format Rich Text (.rtf)"
|
||||
rtfExt = "Rich Text Format (.rtf)"
|
||||
selectedFiles = "Fișiere selectate"
|
||||
noFileSelected = "Niciun fișier selectat. Folosiți panoul de fișiere pentru a adăuga fișiere."
|
||||
convertFiles = "Convertiți fișiere"
|
||||
@@ -1403,7 +1398,7 @@ height = "Spațiere pe înălțime"
|
||||
width = "Spațiere pe lățime"
|
||||
|
||||
[watermark.alphabet]
|
||||
roman = "Romano/Latin"
|
||||
roman = "Roman/Latin"
|
||||
arabic = "Arabă"
|
||||
japanese = "Japoneză"
|
||||
korean = "Coreeană"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Semnătură desenată"
|
||||
defaultImageLabel = "Semnătură încărcată"
|
||||
defaultTextLabel = "Semnătură tastată"
|
||||
saveButton = "Salvează semnătura"
|
||||
savePersonal = "Salvați ca personal"
|
||||
saveShared = "Salvați ca partajat"
|
||||
saveUnavailable = "Creează mai întâi o semnătură pentru a o salva."
|
||||
noChanges = "Semnătura curentă este deja salvată."
|
||||
tempStorageTitle = "Stocare temporară în browser"
|
||||
tempStorageDescription = "Semnăturile sunt stocate doar în browserul dvs. Vor fi pierdute dacă ștergeți datele browserului sau schimbați browserul."
|
||||
personalHeading = "Semnături personale"
|
||||
sharedHeading = "Semnături partajate"
|
||||
personalDescription = "Doar dvs. puteți vedea aceste semnături."
|
||||
sharedDescription = "Toți utilizatorii pot vedea și utiliza aceste semnături."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Desen"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Te rugăm să te autentifici"
|
||||
ssoSignIn = "Conectare prin conectare unică"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Creare automată utilizator dezactivată"
|
||||
oAuth2AdminBlockedUser = "Înregistrarea sau conectarea utilizatorilor neînregistrați este în prezent blocată. Te rugăm să contactezi administratorul."
|
||||
oAuth2RequiresLicense = "Autentificarea OAuth/SSO necesită o licență plătită (Server sau Enterprise). Contactați administratorul pentru a vă actualiza planul."
|
||||
saml2RequiresLicense = "Autentificarea SAML necesită o licență plătită (Server sau Enterprise). Contactați administratorul pentru a vă actualiza planul."
|
||||
maxUsersReached = "Numărul maxim de utilizatori a fost atins pentru licența curentă. Contactați administratorul pentru a vă actualiza planul sau pentru a adăuga mai multe locuri."
|
||||
oauth2RequestNotFound = "Cererea de autorizare nu a fost găsită"
|
||||
oauth2InvalidUserInfoResponse = "Răspuns Invalid la Informațiile Utilizatorului"
|
||||
oauth2invalidRequest = "Cerere Invalidă"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Potriviți la lățime"
|
||||
actualSize = "Dimensiune reală"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Nu se poate previzualiza fișierul"
|
||||
dualPageView = "Vizualizare cu două pagini"
|
||||
firstPage = "Prima pagină"
|
||||
lastPage = "Ultima pagină"
|
||||
nextPage = "Pagina următoare"
|
||||
onlyPdfSupported = "Vizualizatorul acceptă doar fișiere PDF. Acest fișier pare a fi într-un format diferit."
|
||||
previousPage = "Pagina anterioară"
|
||||
singlePageView = "Vizualizare cu o singură pagină"
|
||||
unknownFile = "Fișier necunoscut"
|
||||
nextPage = "Pagina următoare"
|
||||
zoomIn = "Măriți"
|
||||
zoomOut = "Micșorați"
|
||||
singlePageView = "Vizualizare cu o singură pagină"
|
||||
dualPageView = "Vizualizare cu două pagini"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Închideți fișierele selectate"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Comutați bara laterală"
|
||||
exportSelected = "Exportați paginile selectate"
|
||||
toggleAnnotations = "Comutați vizibilitatea adnotărilor"
|
||||
annotationMode = "Comutați modul de adnotare"
|
||||
print = "Imprimați PDF"
|
||||
draw = "Desenați"
|
||||
save = "Salvați"
|
||||
saveChanges = "Salvați modificările"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL sau nume de fișier către impressum (necesar în unele juris
|
||||
title = "Premium și Enterprise"
|
||||
description = "Configurați cheia de licență premium sau enterprise."
|
||||
license = "Configurare licență"
|
||||
noInput = "Vă rugăm să furnizați o cheie sau un fișier de licență"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Ai o cheie de licență sau un fișier certificat?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Suprascrierea cheii de licență curente nu poate fi anulată."
|
||||
line2 = "Licența anterioară va fi pierdută definitiv dacă nu ai o copie de rezervă."
|
||||
line3 = "Important: Păstrează cheile de licență private și în siguranță. Nu le distribui public."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Cheie de licență"
|
||||
file = "Fișier de certificat"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Fișier certificat de licență"
|
||||
description = "Încărcați fișierul de licență .lic sau .cert din achizițiile offline"
|
||||
choose = "Alegeți fișierul de licență"
|
||||
selected = "Selectat: {{filename}} ({{size}})"
|
||||
successMessage = "Fișierul de licență a fost încărcat și activat cu succes. Nu este necesară repornirea."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Licență activă"
|
||||
file = "Sursă: Fișier de licență ({{path}})"
|
||||
key = "Sursă: Cheie de licență"
|
||||
type = "Tip: {{type}}"
|
||||
noInput = "Vă rugăm să furnizați o cheie de licență sau să încărcați un fișier de certificat"
|
||||
success = "Succes"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Activează funcțiile Premium"
|
||||
description = "Activează verificările cheii de licență pentru funcțiile pro/enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} selectate"
|
||||
download = "Descarcă"
|
||||
delete = "Șterge"
|
||||
unsupported = "Nesuportat"
|
||||
active = "Activ"
|
||||
addToUpload = "Adăugați la încărcare"
|
||||
closeFile = "Închide fișierul"
|
||||
deleteAll = "Ștergeți tot"
|
||||
loadingFiles = "Se încarcă fișierele..."
|
||||
noFiles = "Nu există fișiere disponibile"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Este necesară cel puțin o adresă de email"
|
||||
submit = "Trimiteți invitații"
|
||||
success = "utilizator(i) invitați cu succes"
|
||||
partialFailure = "Unele invitații au eșuat"
|
||||
partialSuccess = "Unele invitații au eșuat"
|
||||
allFailed = "Invitarea utilizatorilor a eșuat"
|
||||
error = "Trimiterea invitațiilor a eșuat"
|
||||
|
||||
@@ -5425,7 +5383,7 @@ submit = "Schimbă echipa"
|
||||
currency = "Monedă"
|
||||
popular = "Popular"
|
||||
current = "Plan curent"
|
||||
upgrade = "Actualizează"
|
||||
upgrade = "Upgrade"
|
||||
contact = "Contactează-ne"
|
||||
customPricing = "Personalizat"
|
||||
showComparison = "Compară toate funcțiile"
|
||||
@@ -5842,13 +5800,6 @@ submit = "Autentificare"
|
||||
signInWith = "Autentifică-te cu"
|
||||
oauthPending = "Se deschide browserul pentru autentificare..."
|
||||
orContinueWith = "Sau continuă cu email"
|
||||
serverRequirement = "Notă: Serverul trebuie să aibă autentificarea activată."
|
||||
showInstructions = "Cum se activează?"
|
||||
hideInstructions = "Ascunde instrucțiunile"
|
||||
instructions = "Pentru a activa autentificarea pe serverul dvs. Stirling PDF:"
|
||||
instructionsEnvVar = "Setați variabila de mediu:"
|
||||
instructionsOrYml = "Sau în settings.yml:"
|
||||
instructionsRestart = "Apoi reporniți serverul pentru ca modificările să intre în vigoare."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Utilizator"
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Удалить из избранного"
|
||||
fullscreen = "Переключиться в полноэкранный режим"
|
||||
sidebar = "Переключиться в режим боковой панели"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Серверная часть не найдена"
|
||||
retry = "Повторить"
|
||||
unreachable = "Приложение сейчас не может подключиться к серверной части. Проверьте состояние серверной части и подключение к сети, затем повторите попытку."
|
||||
|
||||
[zipWarning]
|
||||
title = "Большой ZIP-файл"
|
||||
message = "Этот ZIP содержит {{count}} файлов. Все равно извлечь?"
|
||||
@@ -918,8 +913,8 @@ desc = "Наложить один PDF поверх другого"
|
||||
title = "Наложение PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Редактор текста PDF"
|
||||
desc = "Редактируйте существующий текст и изображения внутри PDF-файлов"
|
||||
title = "Редактор текста в PDF"
|
||||
desc = "Просмотр и редактирование экспортов Stirling PDF в JSON с групповым редактированием текста и регенерацией PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "текст,аннотация,ярлык"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Рисованная подпись"
|
||||
defaultImageLabel = "Загруженная подпись"
|
||||
defaultTextLabel = "Введённая подпись"
|
||||
saveButton = "Сохранить подпись"
|
||||
savePersonal = "Сохранить как личную"
|
||||
saveShared = "Сохранить как общую"
|
||||
saveUnavailable = "Сначала создайте подпись, чтобы сохранить её."
|
||||
noChanges = "Текущая подпись уже сохранена."
|
||||
tempStorageTitle = "Временное хранилище браузера"
|
||||
tempStorageDescription = "Подписи сохраняются только в вашем браузере. Они будут потеряны, если вы очистите данные браузера или смените браузер."
|
||||
personalHeading = "Личные подписи"
|
||||
sharedHeading = "Общие подписи"
|
||||
personalDescription = "Эти подписи видны только вам."
|
||||
sharedDescription = "Все пользователи могут видеть и использовать эти подписи."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Рисунок"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Пожалуйста, войдите"
|
||||
ssoSignIn = "Вход через единый вход"
|
||||
oAuth2AutoCreateDisabled = "Автоматическое создание пользователей OAuth2 отключено"
|
||||
oAuth2AdminBlockedUser = "Регистрация или вход незарегистрированных пользователей в настоящее время заблокированы. Обратитесь к администратору."
|
||||
oAuth2RequiresLicense = "Вход через OAuth/SSO требует платную лицензию (Server или Enterprise). Пожалуйста, свяжитесь с администратором, чтобы обновить ваш план."
|
||||
saml2RequiresLicense = "Вход через SAML требует платную лицензию (Server или Enterprise). Пожалуйста, свяжитесь с администратором, чтобы обновить ваш план."
|
||||
maxUsersReached = "Достигнуто максимальное количество пользователей для вашей текущей лицензии. Пожалуйста, свяжитесь с администратором, чтобы обновить ваш план или добавить места."
|
||||
oauth2RequestNotFound = "Запрос авторизации не найден"
|
||||
oauth2InvalidUserInfoResponse = "Недействительный ответ с информацией о пользователе"
|
||||
oauth2invalidRequest = "Недействительный запрос"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "По ширине"
|
||||
actualSize = "Фактический размер"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Не удаётся просмотреть файл"
|
||||
dualPageView = "Двухстраничный вид"
|
||||
firstPage = "Первая страница"
|
||||
lastPage = "Последняя страница"
|
||||
nextPage = "Следующая страница"
|
||||
onlyPdfSupported = "Просмотрщик поддерживает только PDF-файлы. Похоже, этот файл другого формата."
|
||||
previousPage = "Предыдущая страница"
|
||||
singlePageView = "Одностраничный вид"
|
||||
unknownFile = "Неизвестный файл"
|
||||
nextPage = "Следующая страница"
|
||||
zoomIn = "Увеличить"
|
||||
zoomOut = "Уменьшить"
|
||||
singlePageView = "Одностраничный вид"
|
||||
dualPageView = "Двухстраничный вид"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Закрыть выбранные файлы"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Показать/скрыть боковую панель"
|
||||
exportSelected = "Экспортировать выбранные страницы"
|
||||
toggleAnnotations = "Показать/скрыть аннотации"
|
||||
annotationMode = "Переключить режим аннотаций"
|
||||
print = "Печать PDF"
|
||||
draw = "Рисовать"
|
||||
save = "Сохранить"
|
||||
saveChanges = "Сохранить изменения"
|
||||
@@ -4510,14 +4490,13 @@ label = "Политика cookie"
|
||||
description = "URL или имя файла для политики cookie"
|
||||
|
||||
[admin.settings.legal.impressum]
|
||||
label = "Юридическая информация"
|
||||
label = "Impressum"
|
||||
description = "URL или имя файла для impressum (требуется в некоторых юрисдикциях)"
|
||||
|
||||
[admin.settings.premium]
|
||||
title = "Премиум и Enterprise"
|
||||
description = "Настройте ключ лицензии премиум или enterprise."
|
||||
license = "Конфигурация лицензии"
|
||||
noInput = "Укажите лицензионный ключ или файл"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Есть лицензионный ключ или файл сертификата?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Перезапись текущего лицензионного клю
|
||||
line2 = "Предыдущая лицензия будет безвозвратно утеряна, если вы не сделали резервную копию где‑то ещё."
|
||||
line3 = "Важно: храните лицензионные ключи в секрете и безопасности. Никогда не публикуйте их."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Лицензионный ключ"
|
||||
file = "Файл сертификата"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Файл лицензионного сертификата"
|
||||
description = "Загрузите файл лицензии .lic или .cert из офлайн-покупки"
|
||||
choose = "Выберите файл лицензии"
|
||||
selected = "Выбрано: {{filename}} ({{size}})"
|
||||
successMessage = "Файл лицензии успешно загружен и активирован. Перезапуск не требуется."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Активная лицензия"
|
||||
file = "Источник: файл лицензии ({{path}})"
|
||||
key = "Источник: лицензионный ключ"
|
||||
type = "Тип: {{type}}"
|
||||
noInput = "Укажите лицензионный ключ или загрузите файл сертификата"
|
||||
success = "Успешно"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Включить премиум-функции"
|
||||
description = "Включить проверку лицензии для pro/enterprise функций"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} выбрано"
|
||||
download = "Скачать"
|
||||
delete = "Удалить"
|
||||
unsupported = "Не поддерживается"
|
||||
active = "Активный"
|
||||
addToUpload = "Добавить к загрузке"
|
||||
closeFile = "Закрыть файл"
|
||||
deleteAll = "Удалить все"
|
||||
loadingFiles = "Загрузка файлов..."
|
||||
noFiles = "Нет доступных файлов"
|
||||
@@ -5009,7 +4967,7 @@ description = "Привяжите аккаунт, чтобы сохранить
|
||||
socialLogin = "Обновить через соцсеть"
|
||||
linkWith = "Привязать к"
|
||||
emailPassword = "или введите email и пароль"
|
||||
email = "Эл. почта"
|
||||
email = "Email"
|
||||
emailPlaceholder = "Введите ваш email"
|
||||
password = "Пароль (необязательно)"
|
||||
passwordPlaceholder = "Задайте пароль"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Требуется хотя бы один адрес email"
|
||||
submit = "Отправить приглашения"
|
||||
success = "Пользователи успешно приглашены"
|
||||
partialFailure = "Некоторые приглашения не удалось отправить"
|
||||
partialSuccess = "Некоторые приглашения не отправлены"
|
||||
allFailed = "Не удалось пригласить пользователей"
|
||||
error = "Не удалось отправить приглашения"
|
||||
|
||||
@@ -5842,20 +5800,13 @@ submit = "Войти"
|
||||
signInWith = "Войти через"
|
||||
oauthPending = "Открываем браузер для аутентификации..."
|
||||
orContinueWith = "Или продолжить по email"
|
||||
serverRequirement = "Примечание: на сервере должен быть включён вход в систему."
|
||||
showInstructions = "Как включить?"
|
||||
hideInstructions = "Скрыть инструкции"
|
||||
instructions = "Чтобы включить вход в систему на вашем сервере Stirling PDF:"
|
||||
instructionsEnvVar = "Установите переменную окружения:"
|
||||
instructionsOrYml = "Или в settings.yml:"
|
||||
instructionsRestart = "Затем перезапустите сервер, чтобы изменения вступили в силу."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Имя пользователя"
|
||||
placeholder = "Введите имя пользователя"
|
||||
|
||||
[setup.login.email]
|
||||
label = "Эл. почта"
|
||||
label = "Email"
|
||||
placeholder = "Введите email"
|
||||
|
||||
[setup.login.password]
|
||||
|
||||
@@ -99,7 +99,7 @@ visitGithub = "Navštíviť GitHub repozitár"
|
||||
donate = "Darovať"
|
||||
color = "Farba"
|
||||
sponsor = "Sponzorovať"
|
||||
info = "Informácie"
|
||||
info = "Info"
|
||||
pro = "Pro"
|
||||
page = "Strana"
|
||||
pages = "Strany"
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Odstrániť z obľúbených"
|
||||
fullscreen = "Prepnúť na režim celej obrazovky"
|
||||
sidebar = "Prepnúť na režim bočného panela"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Backend sa nenašiel"
|
||||
retry = "Skúsiť znova"
|
||||
unreachable = "Aplikácia sa momentálne nedokáže pripojiť k backendu. Overte stav backendu a sieťové pripojenie, potom to skúste znova."
|
||||
|
||||
[zipWarning]
|
||||
title = "Veľký ZIP súbor"
|
||||
message = "Tento ZIP obsahuje {{count}} súborov. Aj tak rozbaliť?"
|
||||
@@ -279,7 +274,7 @@ iAgreeToThe = "Súhlasím so všetkými"
|
||||
terms = "Podmienkami používania"
|
||||
accessibility = "Prístupnosť"
|
||||
cookie = "Zásady používania súborov cookie"
|
||||
impressum = "Impresum"
|
||||
impressum = "Impressum"
|
||||
showCookieBanner = "Predvoľby súborov cookie"
|
||||
|
||||
[pipeline]
|
||||
@@ -518,7 +513,7 @@ syncToAccount = "Synchronizovať účet <- Prehliadač"
|
||||
[adminUserSettings]
|
||||
title = "Nastavenia kontroly používateľov"
|
||||
header = "Admin nastavenia kontroly používateľov"
|
||||
admin = "Administrátor"
|
||||
admin = "Admin"
|
||||
user = "Používateľ"
|
||||
addUser = "Pridať nového používateľa"
|
||||
deleteUser = "Odstrániť používateľa"
|
||||
@@ -919,7 +914,7 @@ title = "Prekrývanie PDF"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Editor textu PDF"
|
||||
desc = "Upravujte existujúci text a obrázky v PDF"
|
||||
desc = "Kontrolujte a upravujte Stirling PDF JSON exporty so skupinovými úpravami textu a opätovným vytvorením PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "text,anotácia,štítok"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Kreslený podpis"
|
||||
defaultImageLabel = "Nahraný podpis"
|
||||
defaultTextLabel = "Napísaný podpis"
|
||||
saveButton = "Uložiť podpis"
|
||||
savePersonal = "Uložiť osobné"
|
||||
saveShared = "Uložiť zdieľané"
|
||||
saveUnavailable = "Najprv vytvorte podpis, aby ste ho mohli uložiť."
|
||||
noChanges = "Aktuálny podpis je už uložený."
|
||||
tempStorageTitle = "Dočasné úložisko prehliadača"
|
||||
tempStorageDescription = "Podpisy sú uložené iba vo vašom prehliadači. Pri vymazaní údajov prehliadača alebo pri zmene prehliadača sa stratia."
|
||||
personalHeading = "Osobné podpisy"
|
||||
sharedHeading = "Zdieľané podpisy"
|
||||
personalDescription = "Tieto podpisy vidíte iba vy."
|
||||
sharedDescription = "Všetci používatelia môžu tieto podpisy vidieť a používať."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Kresba"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Prosím, prihláste sa"
|
||||
ssoSignIn = "Prihlásiť sa cez Single Sign-on"
|
||||
oAuth2AutoCreateDisabled = "Vytváranie používateľa cez OAUTH2 je zakázané"
|
||||
oAuth2AdminBlockedUser = "Registrácia alebo prihlasovanie neregistrovaných používateľov je momentálne blokované. Kontaktujte administrátora."
|
||||
oAuth2RequiresLicense = "Prihlásenie cez OAuth/SSO vyžaduje platenú licenciu (Server alebo Enterprise). Obráťte sa na administrátora, aby aktualizoval váš plán."
|
||||
saml2RequiresLicense = "Prihlásenie cez SAML vyžaduje platenú licenciu (Server alebo Enterprise). Obráťte sa na administrátora, aby aktualizoval váš plán."
|
||||
maxUsersReached = "Bol dosiahnutý maximálny počet používateľov pre vašu aktuálnu licenciu. Obráťte sa na administrátora, aby aktualizoval váš plán alebo pridal ďalšie miesta."
|
||||
oauth2RequestNotFound = "Požiadavka na autorizáciu sa nenašla"
|
||||
oauth2InvalidUserInfoResponse = "Neplatná odpoveď User Info"
|
||||
oauth2invalidRequest = "Neplatná požiadavka"
|
||||
@@ -3790,7 +3774,7 @@ version = "Aktuálne vydanie"
|
||||
title = "Dokumentácia API"
|
||||
header = "Dokumentácia API"
|
||||
desc = "Zobraziť a testovať API endpointy Stirling PDF"
|
||||
tags = "api,dokumentácia,swagger,endpointy,vývoj"
|
||||
tags = "api,documentation,swagger,endpoints,development"
|
||||
|
||||
[cookieBanner.popUp]
|
||||
title = "Ako používame súbory cookie"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Prispôsobiť šírke"
|
||||
actualSize = "Skutočná veľkosť"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Nedá sa zobraziť náhľad súboru"
|
||||
dualPageView = "Dvojstranové zobrazenie"
|
||||
firstPage = "Prvá strana"
|
||||
lastPage = "Posledná strana"
|
||||
nextPage = "Nasledujúca strana"
|
||||
onlyPdfSupported = "Prehliadač podporuje iba súbory PDF. Tento súbor sa zdá byť iného formátu."
|
||||
previousPage = "Predchádzajúca strana"
|
||||
singlePageView = "Zobrazenie jednej strany"
|
||||
unknownFile = "Neznámy súbor"
|
||||
nextPage = "Nasledujúca strana"
|
||||
zoomIn = "Priblížiť"
|
||||
zoomOut = "Oddialiť"
|
||||
singlePageView = "Zobrazenie jednej strany"
|
||||
dualPageView = "Dvojstranové zobrazenie"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Zavrieť vybrané súbory"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Prepnúť bočný panel"
|
||||
exportSelected = "Exportovať vybrané strany"
|
||||
toggleAnnotations = "Prepnúť zobrazenie anotácií"
|
||||
annotationMode = "Prepnúť režim anotácií"
|
||||
print = "Vytlačiť PDF"
|
||||
draw = "Kresliť"
|
||||
save = "Uložiť"
|
||||
saveChanges = "Uložiť zmeny"
|
||||
@@ -4510,14 +4490,13 @@ label = "Zásady používania súborov cookie"
|
||||
description = "URL alebo názov súboru so zásadami používania súborov cookie"
|
||||
|
||||
[admin.settings.legal.impressum]
|
||||
label = "Impresum"
|
||||
label = "Impressum"
|
||||
description = "URL alebo názov súboru k Impressu (požadované v niektorých jurisdikciách)"
|
||||
|
||||
[admin.settings.premium]
|
||||
title = "Premium a Enterprise"
|
||||
description = "Nakonfigurujte svoj Premium alebo Enterprise licenčný kľúč."
|
||||
license = "Konfigurácia licencie"
|
||||
noInput = "Zadajte licenčný kľúč alebo súbor"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Máte licenčný kľúč alebo súbor certifikátu?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Prepísanie aktuálneho licenčného kľúča nemožno vrátiť späť.
|
||||
line2 = "Vaša predchádzajúca licencia bude natrvalo stratená, pokiaľ ju nemáte zálohovanú inde."
|
||||
line3 = "Dôležité: Licenčné kľúče uchovávajte súkromné a v bezpečí. Nikdy ich nezdieľajte verejne."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Licenčný kľúč"
|
||||
file = "Súbor certifikátu"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Súbor licenčného certifikátu"
|
||||
description = "Nahrajte svoj licenčný súbor .lic alebo .cert z offline nákupu"
|
||||
choose = "Vybrať licenčný súbor"
|
||||
selected = "Vybrané: {{filename}} ({{size}})"
|
||||
successMessage = "Licenčný súbor bol úspešne nahraný a aktivovaný. Reštart nie je potrebný."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Aktívna licencia"
|
||||
file = "Zdroj: Licenčný súbor ({{path}})"
|
||||
key = "Zdroj: Licenčný kľúč"
|
||||
type = "Typ: {{type}}"
|
||||
noInput = "Zadajte licenčný kľúč alebo nahrajte súbor certifikátu"
|
||||
success = "Úspech"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Povoliť Premium funkcie"
|
||||
description = "Povoliť kontrolu licenčného kľúča pre pro/enterprise funkcie"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} vybraných"
|
||||
download = "Stiahnuť"
|
||||
delete = "Vymazať"
|
||||
unsupported = "Nepodporované"
|
||||
active = "Aktívne"
|
||||
addToUpload = "Pridať na nahratie"
|
||||
closeFile = "Zatvoriť súbor"
|
||||
deleteAll = "Odstrániť všetko"
|
||||
loadingFiles = "Načítavajú sa súbory..."
|
||||
noFiles = "Nie sú dostupné žiadne súbory"
|
||||
@@ -5223,7 +5181,7 @@ active = "Aktívny"
|
||||
disabled = "Zakázaný"
|
||||
activeSession = "Aktívna relácia"
|
||||
member = "Člen"
|
||||
admin = "Administrátor"
|
||||
admin = "Admin"
|
||||
editRole = "Upraviť rolu"
|
||||
enable = "Povoliť"
|
||||
disable = "Zakázať"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Vyžaduje sa aspoň jedna e-mailová adresa"
|
||||
submit = "Odoslať pozvánky"
|
||||
success = "Používatelia boli úspešne pozvaní"
|
||||
partialFailure = "Niektoré pozvánky zlyhali"
|
||||
partialSuccess = "Niektoré pozvánky zlyhali"
|
||||
allFailed = "Nepodarilo sa pozvať používateľov"
|
||||
error = "Nepodarilo sa odoslať pozvánky"
|
||||
|
||||
@@ -5842,20 +5800,13 @@ submit = "Prihlásiť sa"
|
||||
signInWith = "Prihlásiť sa cez"
|
||||
oauthPending = "Otvára sa prehliadač na overenie..."
|
||||
orContinueWith = "Alebo pokračujte emailom"
|
||||
serverRequirement = "Poznámka: Na serveri musí byť povolené prihlásenie."
|
||||
showInstructions = "Ako povoliť?"
|
||||
hideInstructions = "Skryť pokyny"
|
||||
instructions = "Na povolenie prihlásenia na vašom serveri Stirling PDF:"
|
||||
instructionsEnvVar = "Nastavte premennú prostredia:"
|
||||
instructionsOrYml = "Alebo v súbore settings.yml:"
|
||||
instructionsRestart = "Potom reštartujte server, aby sa zmeny prejavili."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Používateľské meno"
|
||||
placeholder = "Zadajte používateľské meno"
|
||||
|
||||
[setup.login.email]
|
||||
label = "E-mail"
|
||||
label = "Email"
|
||||
placeholder = "Zadajte svoj email"
|
||||
|
||||
[setup.login.password]
|
||||
@@ -5892,7 +5843,7 @@ paragraph = "Strana s odsekmi"
|
||||
sparse = "Riedky text"
|
||||
|
||||
[pdfTextEditor.groupingMode]
|
||||
auto = "Automaticky"
|
||||
auto = "Auto"
|
||||
paragraph = "Odsek"
|
||||
singleLine = "Jeden riadok"
|
||||
|
||||
|
||||
@@ -163,11 +163,6 @@ unfavorite = "Odstrani iz priljubljenih"
|
||||
fullscreen = "Preklopi na celozaslonski način"
|
||||
sidebar = "Preklopi na način stranske vrstice"
|
||||
|
||||
[backendStartup]
|
||||
notFoundTitle = "Zaledje ni najdeno"
|
||||
retry = "Poskusi znova"
|
||||
unreachable = "Aplikacija se trenutno ne more povezati z zaledjem. Preverite stanje zaledja in omrežno povezavo, nato poskusite znova."
|
||||
|
||||
[zipWarning]
|
||||
title = "Velika datoteka ZIP"
|
||||
message = "Ta ZIP vsebuje {{count}} datotek. Vseeno razpakiram?"
|
||||
@@ -919,7 +914,7 @@ title = "Prekrivanje PDF-jev"
|
||||
|
||||
[home.pdfTextEditor]
|
||||
title = "Urejevalnik besedila PDF"
|
||||
desc = "Urejajte obstoječe besedilo in slike v PDF-jih"
|
||||
desc = "Pregledujte in urejajte Stirling PDF JSON izvoze z urejanjem združenega besedila in ponovnim ustvarjanjem PDF"
|
||||
|
||||
[home.addText]
|
||||
tags = "besedilo,pripomba,oznaka"
|
||||
@@ -2267,16 +2262,8 @@ defaultCanvasLabel = "Narisan podpis"
|
||||
defaultImageLabel = "Naložen podpis"
|
||||
defaultTextLabel = "Vpisan podpis"
|
||||
saveButton = "Shrani podpis"
|
||||
savePersonal = "Shrani osebno"
|
||||
saveShared = "Shrani deljeno"
|
||||
saveUnavailable = "Najprej ustvarite podpis, da ga lahko shranite."
|
||||
noChanges = "Trenutni podpis je že shranjen."
|
||||
tempStorageTitle = "Začasno shranjevanje v brskalniku"
|
||||
tempStorageDescription = "Podpisi so shranjeni samo v vašem brskalniku. Izgubite jih, če počistite podatke brskalnika ali zamenjate brskalnik."
|
||||
personalHeading = "Osebni podpisi"
|
||||
sharedHeading = "Deljeni podpisi"
|
||||
personalDescription = "Te podpise vidite samo vi."
|
||||
sharedDescription = "Vsi uporabniki lahko te podpise vidijo in uporabljajo."
|
||||
|
||||
[sign.saved.type]
|
||||
canvas = "Risba"
|
||||
@@ -3454,9 +3441,6 @@ signinTitle = "Prosim prijavite se"
|
||||
ssoSignIn = "Prijava prek enotne prijave"
|
||||
oAuth2AutoCreateDisabled = "OAUTH2 Samodejno ustvarjanje uporabnika onemogočeno"
|
||||
oAuth2AdminBlockedUser = "Registracija ali prijava neregistriranih uporabnikov je trenutno blokirana. Prosimo kontaktirajte skrbnika."
|
||||
oAuth2RequiresLicense = "Prijava prek OAuth/SSO zahteva plačljivo licenco (Server ali Enterprise). Obrnite se na skrbnika, da nadgradi vaš načrt."
|
||||
saml2RequiresLicense = "Prijava prek SAML zahteva plačljivo licenco (Server ali Enterprise). Obrnite se na skrbnika, da nadgradi vaš načrt."
|
||||
maxUsersReached = "Doseženo je največje število uporabnikov za vašo trenutno licenco. Obrnite se na skrbnika, da nadgradi vaš načrt ali doda več mest."
|
||||
oauth2RequestNotFound = "Zahteva za avtorizacijo ni bila najdena"
|
||||
oauth2InvalidUserInfoResponse = "Neveljaven odgovor z informacijami o uporabniku"
|
||||
oauth2invalidRequest = "Neveljavna zahteva"
|
||||
@@ -3865,17 +3849,14 @@ fitToWidth = "Prilagodi širini"
|
||||
actualSize = "Dejanska velikost"
|
||||
|
||||
[viewer]
|
||||
cannotPreviewFile = "Predogled datoteke ni mogoč"
|
||||
dualPageView = "Dvo-stranski pogled"
|
||||
firstPage = "Prva stran"
|
||||
lastPage = "Zadnja stran"
|
||||
nextPage = "Naslednja stran"
|
||||
onlyPdfSupported = "Pregledovalnik podpira samo PDF datoteke. Ta datoteka je videti v drugačnem formatu."
|
||||
previousPage = "Prejšnja stran"
|
||||
singlePageView = "Enostranski pogled"
|
||||
unknownFile = "Neznana datoteka"
|
||||
nextPage = "Naslednja stran"
|
||||
zoomIn = "Povečaj"
|
||||
zoomOut = "Pomanjšaj"
|
||||
singlePageView = "Enostranski pogled"
|
||||
dualPageView = "Dvo-stranski pogled"
|
||||
|
||||
[rightRail]
|
||||
closeSelected = "Zapri izbrane datoteke"
|
||||
@@ -3899,7 +3880,6 @@ toggleSidebar = "Preklopi stransko vrstico"
|
||||
exportSelected = "Izvozi izbrane strani"
|
||||
toggleAnnotations = "Preklopi vidnost opomb"
|
||||
annotationMode = "Preklopi način opomb"
|
||||
print = "Natisni PDF"
|
||||
draw = "Riši"
|
||||
save = "Shrani"
|
||||
saveChanges = "Shrani spremembe"
|
||||
@@ -4517,7 +4497,6 @@ description = "URL ali ime datoteke do impressuma (zahtevano v nekaterih jurisdi
|
||||
title = "Premium in Enterprise"
|
||||
description = "Konfigurirajte svoj ključ licence Premium ali Enterprise."
|
||||
license = "Konfiguracija licence"
|
||||
noInput = "Navedite licenčni ključ ali datoteko"
|
||||
|
||||
[admin.settings.premium.licenseKey]
|
||||
toggle = "Imate licenčni ključ ali potrdilno datoteko?"
|
||||
@@ -4535,25 +4514,6 @@ line1 = "Prepis trenutnega licenčnega ključa ni mogoče razveljaviti."
|
||||
line2 = "Prejšnja licenca bo trajno izgubljena, razen če ste jo varnostno kopirali drugje."
|
||||
line3 = "Pomembno: Licenčne ključe hranite zasebno in varno. Nikoli jih ne delite javno."
|
||||
|
||||
[admin.settings.premium.inputMethod]
|
||||
text = "Licenčni ključ"
|
||||
file = "Datoteka potrdila"
|
||||
|
||||
[admin.settings.premium.file]
|
||||
label = "Datoteka licenčnega potrdila"
|
||||
description = "Naložite svojo licenčno datoteko .lic ali .cert iz nakupov brez povezave"
|
||||
choose = "Izberite licenčno datoteko"
|
||||
selected = "Izbrano: {{filename}} ({{size}})"
|
||||
successMessage = "Licenčna datoteka je bila uspešno naložena in aktivirana. Ponovni zagon ni potreben."
|
||||
|
||||
[admin.settings.premium.currentLicense]
|
||||
title = "Aktivna licenca"
|
||||
file = "Vir: licenčna datoteka ({{path}})"
|
||||
key = "Vir: licenčni ključ"
|
||||
type = "Vrsta: {{type}}"
|
||||
noInput = "Navedite licenčni ključ ali naložite datoteko potrdila"
|
||||
success = "Uspešno"
|
||||
|
||||
[admin.settings.premium.enabled]
|
||||
label = "Omogoči funkcije Premium"
|
||||
description = "Omogoči preverjanje licenčnega ključa za funkcije pro/enterprise"
|
||||
@@ -4687,9 +4647,7 @@ selectedCount = "{{count}} izbranih"
|
||||
download = "Prenos"
|
||||
delete = "Izbriši"
|
||||
unsupported = "Nepodprto"
|
||||
active = "Aktivno"
|
||||
addToUpload = "Dodaj k nalaganju"
|
||||
closeFile = "Zapri datoteko"
|
||||
deleteAll = "Izbriši vse"
|
||||
loadingFiles = "Nalaganje datotek..."
|
||||
noFiles = "Ni razpoložljivih datotek"
|
||||
@@ -5290,7 +5248,7 @@ emailsPlaceholder = "user1@example.com, user2@example.com"
|
||||
emailsRequired = "Zahtevan je vsaj en e-poštni naslov"
|
||||
submit = "Pošlji povabila"
|
||||
success = "uporabnik(i) uspešno povabljen(i)"
|
||||
partialFailure = "Nekatera povabila niso uspela"
|
||||
partialSuccess = "Nekatera povabila niso uspela"
|
||||
allFailed = "Uporabnikov ni bilo mogoče povabiti"
|
||||
error = "Pošiljanje povabil ni uspelo"
|
||||
|
||||
@@ -5842,13 +5800,6 @@ submit = "Prijava"
|
||||
signInWith = "Prijavite se z"
|
||||
oauthPending = "Odpiranje brskalnika za overjanje..."
|
||||
orContinueWith = "Ali nadaljujte z e-pošto"
|
||||
serverRequirement = "Opomba: Strežnik mora imeti omogočeno prijavo."
|
||||
showInstructions = "Kako omogočiti?"
|
||||
hideInstructions = "Skrij navodila"
|
||||
instructions = "Za omogočanje prijave na vašem strežniku Stirling PDF:"
|
||||
instructionsEnvVar = "Nastavite okoljsko spremenljivko:"
|
||||
instructionsOrYml = "Ali v settings.yml:"
|
||||
instructionsRestart = "Nato znova zaženite strežnik, da spremembe začnejo veljati."
|
||||
|
||||
[setup.login.username]
|
||||
label = "Uporabniško ime"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user