Compare commits
78 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7eb7774979 | ||
|
|
10158fa408 | ||
|
|
dab6613f1b | ||
|
|
1d016df92e | ||
|
|
0631e3071c | ||
|
|
ba1b4b502c | ||
|
|
7865bf720f | ||
|
|
06abc82fbc | ||
|
|
3afacf2405 | ||
|
|
ba259a2d8d | ||
|
|
45895cd6bf | ||
|
|
66d0ad5071 | ||
|
|
c5ae576541 | ||
|
|
2bcdd8cce6 | ||
|
|
c96765f962 | ||
|
|
3830c7d1f3 | ||
|
|
05add001fb | ||
|
|
abc3ff3529 | ||
|
|
737be6c458 | ||
|
|
2e8abb7bb2 | ||
|
|
e2d75ead27 | ||
|
|
28e89a373f | ||
|
|
b4451da2f4 | ||
|
|
8353c399d2 | ||
|
|
af1b156ba6 | ||
|
|
3654743d95 | ||
|
|
58bd9b36cd | ||
|
|
d31b379b5c | ||
|
|
35c85bfeb8 | ||
|
|
64469061fd | ||
|
|
57c343910f | ||
|
|
319ba24be0 | ||
|
|
ec12470188 | ||
|
|
ec88e893c8 | ||
|
|
4ef5a0688b | ||
|
|
86438d7ad3 | ||
|
|
3b15a166c5 | ||
|
|
907a0fb4ff | ||
|
|
8b28bf66fa | ||
|
|
6bd7eadd85 | ||
|
|
a46a570c8a | ||
|
|
a64acb3126 | ||
|
|
2229f38602 | ||
|
|
901bf50d54 | ||
|
|
6f9d8d6351 | ||
|
|
e6874cb219 | ||
|
|
b4b5a2419b | ||
|
|
c888cef023 | ||
|
|
0e807d72ef | ||
|
|
3799ab529f | ||
|
|
65370a19a2 | ||
|
|
2dbd58860e | ||
|
|
63bfcc2011 | ||
|
|
ee3496255b | ||
|
|
db945bc833 | ||
|
|
fc40aaca63 | ||
|
|
313116ebcb | ||
|
|
1de33cf36c | ||
|
|
fcb3d48a1f | ||
|
|
6834067e7a | ||
|
|
d4b120b5f8 | ||
|
|
f0310a4177 | ||
|
|
06a53de350 | ||
|
|
bb99f9ff83 | ||
|
|
72b7b1b838 | ||
|
|
cbaea9cca9 | ||
|
|
5605e4d3bb | ||
|
|
bf0958f588 | ||
|
|
0ae862a84a | ||
|
|
3e216872ce | ||
|
|
1b26fa40f2 | ||
|
|
672389d6b8 | ||
|
|
888ef104a2 | ||
|
|
f90db3cff7 | ||
|
|
e0f553c15a | ||
|
|
89d319332a | ||
|
|
225e797176 | ||
|
|
5e28023853 |
29
.github/pull_request_template.md
vendored
29
.github/pull_request_template.md
vendored
@@ -1,15 +1,34 @@
|
||||
# Description
|
||||
# Description of Changes
|
||||
|
||||
Please provide a summary of the changes, including relevant motivation and context.
|
||||
Please provide a summary of the changes, including:
|
||||
|
||||
- What was changed
|
||||
- Why the change was made
|
||||
- Any challenges encountered
|
||||
|
||||
Closes #(issue_number)
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
### General
|
||||
|
||||
- [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
|
||||
- [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable)
|
||||
- [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable)
|
||||
- [ ] I have performed a self-review of my own code
|
||||
- [ ] I have attached images of the change if it is UI based
|
||||
- [ ] I have commented my code, particularly in hard-to-understand areas
|
||||
- [ ] If my code has heavily changed functionality I have updated relevant docs on [Stirling-PDFs doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
|
||||
- [ ] My changes generate no new warnings
|
||||
|
||||
### Documentation
|
||||
|
||||
- [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed)
|
||||
- [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only)
|
||||
|
||||
### UI Changes (if applicable)
|
||||
|
||||
- [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR)
|
||||
|
||||
### Testing (if applicable)
|
||||
|
||||
- [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details.
|
||||
|
||||
51
.github/scripts/check_duplicates.py
vendored
51
.github/scripts/check_duplicates.py
vendored
@@ -1,51 +0,0 @@
|
||||
import sys
|
||||
|
||||
|
||||
def find_duplicate_keys(file_path):
|
||||
"""
|
||||
Finds duplicate keys in a properties file and returns their occurrences.
|
||||
|
||||
This function reads a properties file, identifies any keys that occur more than
|
||||
once, and returns a dictionary with these keys and the line numbers of their occurrences.
|
||||
|
||||
Parameters:
|
||||
file_path (str): The path to the properties file to be checked.
|
||||
|
||||
Returns:
|
||||
dict: A dictionary where each key is a duplicated key in the file, and the value is a list
|
||||
of line numbers where the key occurs.
|
||||
"""
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
lines = file.readlines()
|
||||
|
||||
keys = {}
|
||||
duplicates = {}
|
||||
|
||||
for line_number, line in enumerate(lines, start=1):
|
||||
line = line.strip()
|
||||
if line and not line.startswith("#") and "=" in line:
|
||||
key = line.split("=", 1)[0].strip()
|
||||
if key in keys:
|
||||
# If the key already exists, add the current line number
|
||||
duplicates.setdefault(key, []).append(line_number)
|
||||
# Also add the first instance of the key if not already done
|
||||
if keys[key] not in duplicates[key]:
|
||||
duplicates[key].insert(0, keys[key])
|
||||
else:
|
||||
# Store the line number of the first instance of the key
|
||||
keys[key] = line_number
|
||||
|
||||
return duplicates
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
failed = False
|
||||
for ar in sys.argv[1:]:
|
||||
duplicates = find_duplicate_keys(ar)
|
||||
if duplicates:
|
||||
for key, lines in duplicates.items():
|
||||
lines_str = ", ".join(map(str, lines))
|
||||
print(f"{key} duplicated in {ar} on lines {lines_str}")
|
||||
failed = True
|
||||
if failed:
|
||||
sys.exit(1)
|
||||
107
.github/scripts/check_language_properties.py
vendored
107
.github/scripts/check_language_properties.py
vendored
@@ -11,6 +11,8 @@ 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
|
||||
@@ -19,25 +21,60 @@ 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 list of objects (including comments, empty lines, and line numbers)."""
|
||||
"""
|
||||
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()
|
||||
|
||||
# Empty lines
|
||||
# Handle empty lines
|
||||
if not stripped_line:
|
||||
properties_list.append(
|
||||
{"line_number": line_number, "type": "empty", "content": ""}
|
||||
)
|
||||
continue
|
||||
|
||||
# Comments
|
||||
# Handle comments
|
||||
if stripped_line.startswith("#"):
|
||||
properties_list.append(
|
||||
{
|
||||
@@ -48,7 +85,7 @@ def parse_properties_file(file_path):
|
||||
)
|
||||
continue
|
||||
|
||||
# Key-value pairs
|
||||
# Handle key-value pairs
|
||||
match = re.match(r"^([^=]+)=(.*)$", line)
|
||||
if match:
|
||||
key, value = match.groups()
|
||||
@@ -65,9 +102,14 @@ def parse_properties_file(file_path):
|
||||
|
||||
|
||||
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 by line numbers and retain comments and empty lines
|
||||
# Sort lines by their numbers and retain comments and empty lines
|
||||
all_lines = sorted(set(updated_lines.keys()))
|
||||
|
||||
original_format = []
|
||||
@@ -86,8 +128,8 @@ def write_json_file(file_path, updated_properties):
|
||||
# Replace entries with those from the current JSON
|
||||
original_format.append(entry)
|
||||
|
||||
# Write back in the original format
|
||||
with open(file_path, "w", encoding="utf-8") as file:
|
||||
# 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")
|
||||
@@ -98,6 +140,12 @@ def write_json_file(file_path, updated_properties):
|
||||
|
||||
|
||||
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))
|
||||
@@ -164,8 +212,14 @@ def check_for_differences(reference_file, file_list, branch, actor):
|
||||
basename_current_file = os.path.basename(os.path.join(branch, file_path))
|
||||
if (
|
||||
basename_current_file == basename_reference_file
|
||||
or not file_path.startswith(
|
||||
os.path.join("src", "main", "resources", "messages_")
|
||||
or (
|
||||
# only local windows command
|
||||
not file_path.startswith(
|
||||
os.path.join("", "src", "main", "resources", "messages_")
|
||||
)
|
||||
and not file_path.startswith(
|
||||
os.path.join(os.getcwd(), "src", "main", "resources", "messages_")
|
||||
)
|
||||
)
|
||||
or not file_path.endswith(".properties")
|
||||
or not basename_current_file.startswith("messages_")
|
||||
@@ -237,6 +291,24 @@ def check_for_differences(reference_file, file_list, branch, actor):
|
||||
)
|
||||
else:
|
||||
report.append("2. **Test Status:** ✅ **_Passed_**")
|
||||
|
||||
if find_duplicate_keys(os.path.join(branch, file_path)):
|
||||
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_path)
|
||||
)
|
||||
]
|
||||
)
|
||||
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("")
|
||||
@@ -275,6 +347,12 @@ if __name__ == "__main__":
|
||||
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="+",
|
||||
@@ -293,11 +371,14 @@ if __name__ == "__main__":
|
||||
|
||||
file_list = args.files
|
||||
if file_list is None:
|
||||
file_list = glob.glob(
|
||||
os.path.join(
|
||||
os.getcwd(), "src", "main", "resources", "messages_*.properties"
|
||||
if args.check_file:
|
||||
file_list = [args.check_file]
|
||||
else:
|
||||
file_list = glob.glob(
|
||||
os.path.join(
|
||||
os.getcwd(), "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)
|
||||
|
||||
85
.github/scripts/check_tabulator.py
vendored
85
.github/scripts/check_tabulator.py
vendored
@@ -1,85 +0,0 @@
|
||||
"""check_tabulator.py"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
|
||||
def check_tabs(file_path):
|
||||
"""
|
||||
Checks for tabs in the specified file.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file to be checked.
|
||||
|
||||
Returns:
|
||||
bool: True if tabs are found, False otherwise.
|
||||
"""
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
content = file.read()
|
||||
|
||||
if "\t" in content:
|
||||
print(f"Tab found in {file_path}")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def replace_tabs_with_spaces(file_path, replace_with=" "):
|
||||
"""
|
||||
Replaces tabs with a specified number of spaces in the file.
|
||||
|
||||
Args:
|
||||
file_path (str): The path to the file where tabs will be replaced.
|
||||
replace_with (str): The character(s) to replace tabs with. Defaults to two spaces.
|
||||
"""
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
content = file.read()
|
||||
|
||||
updated_content = content.replace("\t", replace_with)
|
||||
|
||||
with open(file_path, "w", encoding="utf-8") as file:
|
||||
file.write(updated_content)
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main function to replace tabs with spaces in the provided files.
|
||||
The replacement character and files to check are taken from command line arguments.
|
||||
"""
|
||||
# Create ArgumentParser instance
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Replace tabs in files with specified characters."
|
||||
)
|
||||
|
||||
# Define optional argument `--replace_with`
|
||||
parser.add_argument(
|
||||
"--replace_with",
|
||||
default=" ",
|
||||
help="Character(s) to replace tabs with. Default is two spaces.",
|
||||
)
|
||||
|
||||
# Define argument for file paths
|
||||
parser.add_argument("files", metavar="FILE", nargs="+", help="Files to process.")
|
||||
|
||||
# Parse arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
# Extract replacement characters and files from the parsed arguments
|
||||
replace_with = args.replace_with
|
||||
files_checked = args.files
|
||||
|
||||
error = False
|
||||
|
||||
for file_path in files_checked:
|
||||
if check_tabs(file_path):
|
||||
replace_tabs_with_spaces(file_path, replace_with)
|
||||
error = True
|
||||
|
||||
if error:
|
||||
print("Error: Originally found tabs in HTML files, now replaced.")
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1
.github/scripts/requirements_pre_commit.in
vendored
Normal file
1
.github/scripts/requirements_pre_commit.in
vendored
Normal file
@@ -0,0 +1 @@
|
||||
pre-commit
|
||||
93
.github/scripts/requirements_pre_commit.txt
vendored
Normal file
93
.github/scripts/requirements_pre_commit.txt
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
#
|
||||
# This file is autogenerated by pip-compile with Python 3.10
|
||||
# by the following command:
|
||||
#
|
||||
# pip-compile --generate-hashes --output-file='.github\scripts\requirements_pre_commit.txt' '.github\scripts\requirements_pre_commit.in'
|
||||
#
|
||||
cfgv==3.4.0 \
|
||||
--hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \
|
||||
--hash=sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560
|
||||
# via pre-commit
|
||||
distlib==0.3.9 \
|
||||
--hash=sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87 \
|
||||
--hash=sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403
|
||||
# via virtualenv
|
||||
filelock==3.16.1 \
|
||||
--hash=sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0 \
|
||||
--hash=sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435
|
||||
# via virtualenv
|
||||
identify==2.6.5 \
|
||||
--hash=sha256:14181a47091eb75b337af4c23078c9d09225cd4c48929f521f3bf16b09d02566 \
|
||||
--hash=sha256:c10b33f250e5bba374fae86fb57f3adcebf1161bce7cdf92031915fd480c13bc
|
||||
# via pre-commit
|
||||
nodeenv==1.9.1 \
|
||||
--hash=sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f \
|
||||
--hash=sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9
|
||||
# via pre-commit
|
||||
platformdirs==4.3.6 \
|
||||
--hash=sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907 \
|
||||
--hash=sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb
|
||||
# via virtualenv
|
||||
pre-commit==4.0.1 \
|
||||
--hash=sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2 \
|
||||
--hash=sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878
|
||||
# via -r .github\scripts\requirements_pre_commit.in
|
||||
pyyaml==6.0.2 \
|
||||
--hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \
|
||||
--hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \
|
||||
--hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \
|
||||
--hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \
|
||||
--hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \
|
||||
--hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \
|
||||
--hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \
|
||||
--hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \
|
||||
--hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \
|
||||
--hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \
|
||||
--hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \
|
||||
--hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \
|
||||
--hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \
|
||||
--hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \
|
||||
--hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \
|
||||
--hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \
|
||||
--hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \
|
||||
--hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \
|
||||
--hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \
|
||||
--hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \
|
||||
--hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \
|
||||
--hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \
|
||||
--hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \
|
||||
--hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \
|
||||
--hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \
|
||||
--hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \
|
||||
--hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \
|
||||
--hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \
|
||||
--hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \
|
||||
--hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \
|
||||
--hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \
|
||||
--hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \
|
||||
--hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \
|
||||
--hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \
|
||||
--hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \
|
||||
--hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \
|
||||
--hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \
|
||||
--hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \
|
||||
--hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \
|
||||
--hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \
|
||||
--hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \
|
||||
--hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \
|
||||
--hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \
|
||||
--hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \
|
||||
--hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \
|
||||
--hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \
|
||||
--hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \
|
||||
--hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \
|
||||
--hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \
|
||||
--hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \
|
||||
--hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \
|
||||
--hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \
|
||||
--hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4
|
||||
# via pre-commit
|
||||
virtualenv==20.28.1 \
|
||||
--hash=sha256:412773c85d4dab0409b83ec36f7a6499e72eaf08c80e81e9576bca61831c71cb \
|
||||
--hash=sha256:5d34ab240fdb5d21549b76f9e8ff3af28252f5499fb6d6f031adac4e5a8c5329
|
||||
# via pre-commit
|
||||
10
.github/workflows/PR-Demo-Comment.yml
vendored
10
.github/workflows/PR-Demo-Comment.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -81,7 +81,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -95,8 +95,8 @@ jobs:
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
java-version: "17"
|
||||
distribution: "temurin"
|
||||
|
||||
- name: Run Gradle Command
|
||||
run: ./gradlew clean build
|
||||
@@ -119,7 +119,7 @@ jobs:
|
||||
password: ${{ secrets.DOCKER_HUB_API }}
|
||||
|
||||
- name: Build and push PR-specific image
|
||||
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
|
||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
|
||||
6
.github/workflows/PR-Demo-cleanup.yml
vendored
6
.github/workflows/PR-Demo-cleanup.yml
vendored
@@ -8,8 +8,8 @@ permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
SERVER_IP: ${{ secrets.VPS_IP }} # Add this to your GitHub secrets
|
||||
CLEANUP_PERFORMED: 'false' # Add flag to track if cleanup occurred
|
||||
SERVER_IP: ${{ secrets.VPS_IP }} # Add this to your GitHub secrets
|
||||
CLEANUP_PERFORMED: "false" # Add flag to track if cleanup occurred
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
||||
2
.github/workflows/auto-labeler.yml
vendored
2
.github/workflows/auto-labeler.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
||||
22
.github/workflows/build.yml
vendored
22
.github/workflows/build.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -37,6 +37,12 @@ jobs:
|
||||
java-version: ${{ matrix.jdk-version }}
|
||||
distribution: "temurin"
|
||||
|
||||
- name: PR | Generate verification metadata with signatures and checksums for dependabot[bot]
|
||||
if: github.event.pull_request.user.login == 'dependabot[bot]'
|
||||
run: |
|
||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256 --refresh-dependencies help
|
||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp --refresh-keys --export-keys --refresh-dependencies help
|
||||
|
||||
- name: Build with Gradle and no spring security
|
||||
run: ./gradlew clean build
|
||||
env:
|
||||
@@ -49,7 +55,7 @@ jobs:
|
||||
|
||||
- name: Upload Test Reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: test-reports-jdk-${{ matrix.jdk-version }}
|
||||
path: |
|
||||
@@ -77,7 +83,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -95,19 +101,21 @@ jobs:
|
||||
|
||||
- name: Install Docker Compose
|
||||
run: |
|
||||
sudo curl -SL "https://github.com/docker/compose/releases/download/v2.32.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo curl -SL "https://github.com/docker/compose/releases/download/v2.32.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: 'pip' # caching pip dependencies
|
||||
|
||||
- name: Pip requirements
|
||||
run: |
|
||||
pip install --require-hashes -r ./cucumber/requirements.txt
|
||||
pip install --require-hashes -r ./testing/cucumber/requirements.txt
|
||||
|
||||
- name: Run Docker Compose Tests
|
||||
run: |
|
||||
chmod +x ./test.sh
|
||||
./test.sh
|
||||
chmod +x ./testing/test_webpages.sh
|
||||
chmod +x ./testing/test.sh
|
||||
./testing/test.sh "${{ github.event.pull_request.user.login == 'dependabot[bot]' }}"
|
||||
|
||||
6
.github/workflows/check_properties.yml
vendored
6
.github/workflows/check_properties.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
run: |
|
||||
echo "Fetching PR changed files..."
|
||||
echo "Getting list of changed files from PR..."
|
||||
gh pr view ${{ steps.get-pr-data.outputs.pr_number }} --json files -q ".files[].path" | grep -E '^src/main/resources/messages_[a-zA-Z_]+\.properties$' > changed_files.txt # Filter only matching property files
|
||||
gh pr view ${{ steps.get-pr-data.outputs.pr_number }} --json files -q ".files[].path" | grep -E '^src/main/resources/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}\.properties$' > changed_files.txt # Filter only matching property files
|
||||
|
||||
- name: Determine reference file test
|
||||
id: determine-file
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
// Filter for relevant files based on the PR changes
|
||||
const changedFiles = files
|
||||
.map(file => file.filename)
|
||||
.filter(file => /^src\/main\/resources\/messages_[a-zA-Z_]+\.properties$/.test(file));
|
||||
.filter(file => /^src\/main\/resources\/messages_[a-zA-Z_]{2}_[a-zA-Z_]{2,7}\.properties$/.test(file));
|
||||
|
||||
console.log("Changed files:", changedFiles);
|
||||
|
||||
|
||||
2
.github/workflows/codeql.yml-disabled
vendored
2
.github/workflows/codeql.yml-disabled
vendored
@@ -42,7 +42,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@c95a14d0e5bab51a9f56296a4eb0e416910cd350 # v2.10.3
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
||||
8
.github/workflows/dependency-review.yml
vendored
8
.github/workflows/dependency-review.yml
vendored
@@ -6,7 +6,7 @@
|
||||
# PRs introducing known-vulnerable packages will be blocked from merging.
|
||||
#
|
||||
# Source repository: https://github.com/actions/dependency-review-action
|
||||
name: 'Dependency Review'
|
||||
name: "Dependency Review"
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
@@ -17,11 +17,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: 'Checkout Repository'
|
||||
- name: "Checkout Repository"
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: 'Dependency Review'
|
||||
- name: "Dependency Review"
|
||||
uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4.5.0
|
||||
|
||||
37
.github/workflows/licenses-update.yml
vendored
37
.github/workflows/licenses-update.yml
vendored
@@ -18,10 +18,17 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Check out code
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
@@ -42,8 +49,8 @@ jobs:
|
||||
|
||||
- name: Set up git config
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --global user.name "stirlingbot[bot]"
|
||||
git config --global user.email "1113334+stirlingbot[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Run git add
|
||||
run: |
|
||||
@@ -55,32 +62,22 @@ jobs:
|
||||
if: env.CHANGES_DETECTED == 'true'
|
||||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
commit-message: "Update 3rd Party Licenses"
|
||||
committer: GitHub Action <action@github.com>
|
||||
author: GitHub Action <action@github.com>
|
||||
committer: "stirlingbot[bot] <1113334+stirlingbot[bot]@users.noreply.github.com>"
|
||||
author: "stirlingbot[bot] <1113334+stirlingbot[bot]@users.noreply.github.com>"
|
||||
signoff: true
|
||||
branch: update-3rd-party-licenses
|
||||
title: "Update 3rd Party Licenses"
|
||||
body: |
|
||||
Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
Auto-generated by StirlingBot
|
||||
labels: licenses,github-actions
|
||||
draft: false
|
||||
delete-branch: true
|
||||
sign-commits: true
|
||||
|
||||
- name: Auto approve
|
||||
- name: Enable Pull Request Automerge
|
||||
if: steps.cpr.outputs.pull-request-operation == 'created'
|
||||
run: gh pr review --approve "${{ steps.cpr.outputs.pull-request-number }}"
|
||||
run: gh pr merge --squash --auto "${{ steps.cpr.outputs.pull-request-number }}"
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Enable auto-merge
|
||||
if: steps.cpr.outputs.pull-request-operation == 'created'
|
||||
uses: peter-evans/enable-pull-request-automerge@a660677d5469627102a1c1e11409dd063606628d # v3.0.0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
pull-request-number: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
merge-method: squash # Choose the merge method: merge, squash, or rebase
|
||||
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
|
||||
2
.github/workflows/manage-label.yml
vendored
2
.github/workflows/manage-label.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
||||
77
.github/workflows/multiOSReleases.yml
vendored
77
.github/workflows/multiOSReleases.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
versionMac: ${{ steps.versionNumberMac.outputs.versionNumberMac }}
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -46,12 +46,12 @@ jobs:
|
||||
enable_security: [true, false]
|
||||
include:
|
||||
- enable_security: true
|
||||
file_suffix: "with-login-"
|
||||
file_suffix: "-with-login"
|
||||
- enable_security: false
|
||||
file_suffix: ""
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c95a14d0e5bab51a9f56296a4eb0e416910cd350 # v2.10.3
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -75,18 +75,18 @@ jobs:
|
||||
|
||||
- name: Rename binaries
|
||||
run: |
|
||||
mv ./build/launch4j/Stirling-PDF.exe ./win-Stirling-PDF-portable-Server-${{ matrix.file_suffix }}${{ needs.read_versions.outputs.version }}.exe
|
||||
mv ./build/libs/Stirling-PDF-${{ needs.read_versions.outputs.version }}.jar ./Stirling-PDF-${{ matrix.file_suffix }}${{ needs.read_versions.outputs.version }}.jar
|
||||
mkdir ./binaries
|
||||
mv ./build/launch4j/Stirling-PDF.exe ./binaries/win-Stirling-PDF-portable-Server${{ matrix.file_suffix }}.exe
|
||||
mv ./build/libs/Stirling-PDF-${{ needs.read_versions.outputs.version }}.jar ./binaries/Stirling-PDF${{ matrix.file_suffix }}.jar
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
name: stirling-${{ matrix.file_suffix }}binaries
|
||||
name: stirling${{ matrix.file_suffix }}-binaries
|
||||
path: |
|
||||
./win-Stirling-PDF-portable-Server-${{ matrix.file_suffix }}${{ needs.read_versions.outputs.version }}.exe
|
||||
./Stirling-PDF-${{ matrix.file_suffix }}${{ needs.read_versions.outputs.version }}.jar
|
||||
./binaries/*
|
||||
|
||||
sign_verify-portable:
|
||||
needs: [build-portable, read_versions]
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
file_suffix: ""
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c95a14d0e5bab51a9f56296a4eb0e416910cd350 # v2.10.3
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -129,23 +129,17 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- os: windows-latest
|
||||
extra: "-installer"
|
||||
platform: win-
|
||||
ext: exe
|
||||
# - os: macos-latest
|
||||
# extra: ""
|
||||
# platform: mac-
|
||||
# ext: dmg
|
||||
- os: macos-latest
|
||||
platform: mac-
|
||||
# - os: ubuntu-latest
|
||||
# extra: ""
|
||||
# platform: linux-
|
||||
# ext: deb
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -174,20 +168,25 @@ jobs:
|
||||
env:
|
||||
DOCKER_ENABLE_SECURITY: false
|
||||
STIRLING_PDF_DESKTOP_UI: true
|
||||
BROWSER_OPEN: true
|
||||
|
||||
# Rename and collect artifacts based on OS
|
||||
- name: Prepare artifacts
|
||||
id: prepare
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir ./binaries
|
||||
if [ "${{ matrix.os }}" = "windows-latest" ]; then
|
||||
mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.version }}.exe" "${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.${{ matrix.ext }}"
|
||||
mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.version }}.exe" "./binaries/Stirling-PDF-win-installer.exe"
|
||||
elif [ "${{ matrix.os }}" = "macos-latest" ]; then
|
||||
mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.versionMac }}.dmg" "${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.${{ matrix.ext }}"
|
||||
mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-installer.dmg"
|
||||
else
|
||||
mv "./build/jpackage/stirling-pdf_${{ needs.read_versions.outputs.version }}-1_amd64.deb" "${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.${{ matrix.ext }}"
|
||||
mv "./build/jpackage/stirling-pdf_${{ needs.read_versions.outputs.version }}-1_amd64.deb" "./binaries/Stirling-PDF-linux-installer.deb"
|
||||
fi
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R ./binaries
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
@@ -195,7 +194,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
name: ${{ matrix.platform }}binaries
|
||||
path: |
|
||||
./${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.${{ matrix.ext }}
|
||||
./binaries/*
|
||||
|
||||
sign_verify:
|
||||
needs: [read_versions, build-installers]
|
||||
@@ -203,21 +202,15 @@ jobs:
|
||||
matrix:
|
||||
include:
|
||||
- os: windows-latest
|
||||
extra: "-installer"
|
||||
platform: win-
|
||||
ext: exe
|
||||
# - os: macos-latest
|
||||
# extra: ""
|
||||
# platform: mac-
|
||||
# ext: dmg
|
||||
- os: macos-latest
|
||||
platform: mac-
|
||||
# - os: ubuntu-latest
|
||||
# extra: ""
|
||||
# platform: linux-
|
||||
# ext: deb
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c95a14d0e5bab51a9f56296a4eb0e416910cd350 # v2.10.3
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -243,20 +236,23 @@ jobs:
|
||||
cosign sign-blob \
|
||||
--key ./cosign.key \
|
||||
--yes \
|
||||
--output-signature ./${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.${{ matrix.ext }}.sig \
|
||||
./${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.${{ matrix.ext }}
|
||||
--output-signature ./Stirling-PDF-win-installer.exe.sig \
|
||||
./Stirling-PDF-win-installer.exe
|
||||
|
||||
cosign attest-blob \
|
||||
--predicate - \
|
||||
--key ./cosign.key \
|
||||
--yes \
|
||||
--output-attestation ./${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.${{ matrix.ext }}.intoto.jsonl \
|
||||
./${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.${{ matrix.ext }}
|
||||
--output-attestation ./Stirling-PDF-win-installer.exe.intoto.jsonl \
|
||||
./Stirling-PDF-win-installer.exe
|
||||
|
||||
cosign verify-blob \
|
||||
--key ./cosign.pub \
|
||||
--signature ./${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.${{ matrix.ext }}.sig \
|
||||
./${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.${{ matrix.ext }}
|
||||
--signature ./Stirling-PDF-win-installer.exe.sig \
|
||||
./Stirling-PDF-win-installer.exe
|
||||
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
|
||||
- name: Upload signed artifacts
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
@@ -265,7 +261,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
name: ${{ matrix.platform }}signed
|
||||
path: |
|
||||
./${{ matrix.platform }}Stirling-PDF${{ matrix.extra }}-${{ needs.read_versions.outputs.version }}.*
|
||||
./Stirling-PDF-${{ matrix.platform }}installer.*
|
||||
!cosign.*
|
||||
|
||||
create-release:
|
||||
@@ -274,6 +270,11 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Download signed artifacts
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
- name: Display structure of downloaded files
|
||||
|
||||
55
.github/workflows/pre_commit.yml
vendored
55
.github/workflows/pre_commit.yml
vendored
@@ -1,20 +1,42 @@
|
||||
name: Pre-commit
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "0 0 * * 1"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
update:
|
||||
if: ${{ github.event.pull_request.user.login != 'dependabot[bot]' }}
|
||||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Get GitHub App User ID
|
||||
id: get-user-id
|
||||
run: echo "user-id=$(gh api "/users/${{ steps.generate-token.outputs.app-slug }}[bot]" --jq .id)" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
|
||||
- id: committer
|
||||
run: |
|
||||
echo "string=${{ steps.generate-token.outputs.app-slug }}[bot] <${{ steps.get-user-id.outputs.user-id }}+${{ steps.generate-token.outputs.app-slug }}[bot]@users.noreply.github.com>" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
@@ -23,30 +45,33 @@ jobs:
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
with:
|
||||
python-version: 3.12
|
||||
cache: 'pip' # caching pip dependencies
|
||||
- name: Run Pre-Commit Hooks
|
||||
uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
|
||||
run: |
|
||||
pip install --require-hashes -r ./.github/scripts/requirements_pre_commit.txt
|
||||
- run: pre-commit run --all-files -c .pre-commit-config.yaml
|
||||
continue-on-error: true
|
||||
- name: Set up git config
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --global user.name ${{ steps.generate-token.outputs.app-slug }}[bot]
|
||||
git config --global user.email "${{ steps.get-user-id.outputs.user-id }}+${{ steps.generate-token.outputs.app-slug }}[bot]@users.noreply.github.com"
|
||||
- name: git add
|
||||
run: |
|
||||
git add .
|
||||
git diff --staged --quiet || git commit -m ":file_folder: pre-commit
|
||||
> Made via .github/workflows/pre_commit.yml" || echo "pre-commit: no changes"
|
||||
git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
- name: Create Pull Request
|
||||
if: env.CHANGES_DETECTED == 'true'
|
||||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: "ci: 🤖 format everything with pre-commit"
|
||||
committer: GitHub Action <action@github.com>
|
||||
author: GitHub Action <action@github.com>
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
commit-message: ":file_folder: pre-commit"
|
||||
committer: ${{ steps.committer.outputs.string }}
|
||||
author: ${{ steps.committer.outputs.string }}
|
||||
signoff: true
|
||||
branch: pre-commit
|
||||
title: "🤖 format everything with pre-commit by <github-actions[bot]>"
|
||||
title: "🤖 format everything with pre-commit by <${{ steps.generate-token.outputs.app-slug }}>"
|
||||
body: |
|
||||
Auto-generated by [create-pull-request][1]
|
||||
Auto-generated by [create-pull-request][1] with **${{ steps.generate-token.outputs.app-slug }}**
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
draft: false
|
||||
|
||||
12
.github/workflows/push-docker.yml
vendored
12
.github/workflows/push-docker.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
if: github.ref == 'refs/heads/master'
|
||||
uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0
|
||||
with:
|
||||
cosign-release: 'v2.4.1'
|
||||
cosign-release: "v2.4.1"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
password: ${{ github.token }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
|
||||
uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0
|
||||
|
||||
- name: Convert repository owner to lowercase
|
||||
id: repoowner
|
||||
@@ -89,7 +89,7 @@ jobs:
|
||||
|
||||
- name: Build and push main Dockerfile
|
||||
id: build-push-regular
|
||||
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
|
||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
|
||||
- name: Build and push Dockerfile-ultra-lite
|
||||
id: build-push-lite
|
||||
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
|
||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
||||
if: github.ref != 'refs/heads/main'
|
||||
with:
|
||||
context: .
|
||||
@@ -165,7 +165,7 @@ jobs:
|
||||
|
||||
- name: Build and push main Dockerfile fat
|
||||
id: build-push-fat
|
||||
uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0
|
||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
||||
if: github.ref != 'refs/heads/main'
|
||||
with:
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
|
||||
10
.github/workflows/releaseArtifacts.yml
vendored
10
.github/workflows/releaseArtifacts.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
version: ${{ steps.versionNumber.outputs.versionNumber }}
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
ls -R ./build/launch4j
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: binaries${{ matrix.file_suffix }}
|
||||
path: |
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
file_suffix: ""
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c95a14d0e5bab51a9f56296a4eb0e416910cd350 # v2.10.3
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -139,7 +139,7 @@ jobs:
|
||||
./launch4j/Stirling-PDF-Server${{ matrix.file_suffix }}.exe
|
||||
|
||||
- name: Upload signed artifacts
|
||||
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: signed${{ matrix.file_suffix }}
|
||||
path: |
|
||||
@@ -161,7 +161,7 @@ jobs:
|
||||
file_suffix: ""
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@c95a14d0e5bab51a9f56296a4eb0e416910cd350 # v2.10.3
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
||||
8
.github/workflows/scorecards.yml
vendored
8
.github/workflows/scorecards.yml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
# To guarantee Maintained check is occasionally updated. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
|
||||
schedule:
|
||||
- cron: '20 7 * * 2'
|
||||
- cron: "20 7 * * 2"
|
||||
push:
|
||||
branches: ["main"]
|
||||
permissions: read-all
|
||||
@@ -34,7 +34,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
@@ -74,6 +74,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0
|
||||
uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c # v3.28.1
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
4
.github/workflows/stale.yml
vendored
4
.github/workflows/stale.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
@@ -37,4 +37,4 @@ jobs:
|
||||
only-issue-labels: "more-info-needed"
|
||||
days-before-pr-stale: -1 # Prevents PRs from being marked as stale
|
||||
days-before-pr-close: -1 # Prevents PRs from being closed
|
||||
start-date: '2024-07-06T00:00:00Z' # ISO 8601 Format
|
||||
start-date: "2024-07-06T00:00:00Z" # ISO 8601 Format
|
||||
|
||||
2
.github/workflows/swagger.yml
vendored
2
.github/workflows/swagger.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
|
||||
148
.github/workflows/sync_files.yml
vendored
148
.github/workflows/sync_files.yml
vendored
@@ -1,62 +1,170 @@
|
||||
name: Sync Files
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "build.gradle"
|
||||
- "README.md"
|
||||
- "gradle/verification-keyring.keys"
|
||||
- "gradle/verification-metadata.xml"
|
||||
- "src/main/resources/messages_*.properties"
|
||||
- "src/main/resources/static/3rdPartyLicenses.json"
|
||||
- "scripts/ignore_translation.toml"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
sync-readme:
|
||||
read_bot_entries:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
outputs:
|
||||
userName: ${{ steps.get-user-id.outputs.user_name }}
|
||||
userEmail: ${{ steps.get-user-id.outputs.user_email }}
|
||||
committer: ${{ steps.committer.outputs.committer }}
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
||||
with:
|
||||
app-id: ${{ secrets.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
|
||||
- name: Get GitHub App User ID
|
||||
id: get-user-id
|
||||
run: |
|
||||
USER_NAME="${{ steps.generate-token.outputs.app-slug }}[bot]"
|
||||
USER_ID=$(gh api "/users/$USER_NAME" --jq .id)
|
||||
USER_EMAIL="$USER_ID+$USER_NAME@users.noreply.github.com"
|
||||
echo "user_name=$USER_NAME" >> "$GITHUB_OUTPUT"
|
||||
echo "user_email=$USER_EMAIL" >> "$GITHUB_OUTPUT"
|
||||
echo "user-id=$USER_ID" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
|
||||
- id: committer
|
||||
run: |
|
||||
COMMITTER="${{ steps.get-user-id.outputs.user_name }} <${{ steps.get-user-id.outputs.user_email }}>"
|
||||
echo "committer=$COMMITTER" >> "$GITHUB_OUTPUT"
|
||||
|
||||
sync-files:
|
||||
needs: ["read_bot_entries"]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Generate GitHub App Token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
||||
with:
|
||||
app-id: ${{ vars.GH_APP_ID }}
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
- name: Install dependencies
|
||||
run: pip install --require-hashes -r ./.github/scripts/requirements_sync_readme.txt
|
||||
- name: Sync README
|
||||
run: python scripts/counter_translation.py
|
||||
cache: 'pip' # caching pip dependencies
|
||||
|
||||
- name: Sync translation property files
|
||||
run: |
|
||||
python .github/scripts/check_language_properties.py --reference-file "src/main/resources/messages_en_GB.properties" --branch main
|
||||
|
||||
- name: Set up git config
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --global user.name ${{ needs.read_bot_entries.outputs.userName }}
|
||||
git config --global user.email ${{ needs.read_bot_entries.outputs.userEmail }}
|
||||
|
||||
- name: Run git add
|
||||
run: |
|
||||
git add .
|
||||
git diff --staged --quiet || git commit -m ":memo: Sync README
|
||||
> Made via sync_files.yml" || echo "no changes"
|
||||
git add src/main/resources/messages_*.properties
|
||||
git diff --staged --quiet || git commit -m ":memo: Sync translation files" || echo "no changes"
|
||||
|
||||
- name: Install dependencies
|
||||
run: pip install --require-hashes -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
|
||||
git diff --staged --quiet || git commit -m ":memo: Sync README.md" || echo "no changes"
|
||||
|
||||
- name: Generate verification metadata with signatures and checksums
|
||||
run: |
|
||||
set -e
|
||||
if [ -f ./gradle/verification-metadata.xml ]; then
|
||||
rm ./gradle/verification-metadata.xml
|
||||
fi
|
||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256 help
|
||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp --refresh-keys --export-keys --refresh-dependencies help
|
||||
./gradlew clean build
|
||||
|
||||
- name: Run git add
|
||||
run: |
|
||||
git add gradle/verification-keyring.keys
|
||||
git add gradle/verification-metadata.xml
|
||||
git diff --staged --quiet || git commit -m ":memo: Generate verification metadata with signatures and checksums" || echo "no changes"
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
commit-message: Update files
|
||||
committer: GitHub Action <action@github.com>
|
||||
author: GitHub Action <action@github.com>
|
||||
committer: ${{ needs.read_bot_entries.outputs.committer }}
|
||||
author: ${{ needs.read_bot_entries.outputs.committer }}
|
||||
signoff: true
|
||||
branch: sync_readme
|
||||
title: ":memo: Update README: Translation Progress Table"
|
||||
title: ":globe_with_meridians: Sync Translations + Update README Progress Table + Update Verification Metadata"
|
||||
body: |
|
||||
Auto-generated by [create-pull-request][1]
|
||||
### Description of Changes
|
||||
|
||||
This Pull Request was automatically generated to synchronize updates to translation files, verification metadata, 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.
|
||||
|
||||
#### **3. Verification Metadata Updates**
|
||||
- Generated or refreshed the `verification-keyring.keys` and `verification-metadata.xml` files.
|
||||
- Included the latest dependency signatures and checksums to enhance the build's integrity.
|
||||
|
||||
#### **Why these changes are necessary**
|
||||
- Keeps translation files aligned with the latest reference updates.
|
||||
- Ensures the documentation reflects the current translation progress.
|
||||
- Strengthens dependency verification for a more secure build process.
|
||||
|
||||
---
|
||||
|
||||
Auto-generated by [create-pull-request][1].
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
draft: false
|
||||
delete-branch: true
|
||||
labels: Documentation,Translation,github-actions
|
||||
labels: github-actions
|
||||
sign-commits: true
|
||||
add-paths: |
|
||||
README.md
|
||||
src/main/resources/messages_*.properties
|
||||
gradle/verification-keyring.keys
|
||||
gradle/verification-metadata.xml
|
||||
|
||||
154
.github/workflows/testdriver.yml
vendored
Normal file
154
.github/workflows/testdriver.yml
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
name: UI test with TestDriverAI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["master", "UITest", "testdriver"]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew clean build
|
||||
env:
|
||||
DOCKER_ENABLE_SECURITY: false
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
|
||||
|
||||
- name: Get version number
|
||||
id: versionNumber
|
||||
run: |
|
||||
VERSION=$(grep "^version =" build.gradle | awk -F'"' '{print $2}')
|
||||
echo "versionNumber=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_HUB_API }}
|
||||
|
||||
- name: Build and push test image
|
||||
uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
tags: ${{ secrets.DOCKER_HUB_USERNAME }}/test:test-${{ github.sha }}
|
||||
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
|
||||
platforms: linux/amd64
|
||||
|
||||
- name: Set up SSH
|
||||
run: |
|
||||
mkdir -p ~/.ssh/
|
||||
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
|
||||
sudo chmod 600 ../private.key
|
||||
|
||||
- name: Deploy to VPS
|
||||
run: |
|
||||
cat > docker-compose.yml << EOF
|
||||
version: '3.3'
|
||||
services:
|
||||
stirling-pdf:
|
||||
container_name: stirling-pdf-test-${{ github.sha }}
|
||||
image: ${{ secrets.DOCKER_HUB_USERNAME }}/test:test-${{ github.sha }}
|
||||
ports:
|
||||
- "1337:8080"
|
||||
volumes:
|
||||
- /stirling/test-${{ github.sha }}/data:/usr/share/tessdata:rw
|
||||
- /stirling/test-${{ github.sha }}/config:/configs:rw
|
||||
- /stirling/test-${{ github.sha }}/logs:/logs:rw
|
||||
environment:
|
||||
DOCKER_ENABLE_SECURITY: "false"
|
||||
SECURITY_ENABLELOGIN: "false"
|
||||
SYSTEM_DEFAULTLOCALE: en-GB
|
||||
UI_APPNAME: "Stirling-PDF Test"
|
||||
UI_HOMEDESCRIPTION: "Test Deployment"
|
||||
UI_APPNAMENAVBAR: "Test"
|
||||
SYSTEM_MAXFILESIZE: "100"
|
||||
METRICS_ENABLED: "true"
|
||||
SYSTEM_GOOGLEVISIBILITY: "false"
|
||||
SYSTEM_ENABLEANALYTICS: "false"
|
||||
restart: on-failure:5
|
||||
EOF
|
||||
|
||||
scp -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null docker-compose.yml ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }}:/tmp/docker-compose.yml
|
||||
|
||||
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << EOF
|
||||
mkdir -p /stirling/test-${{ github.sha }}/{data,config,logs}
|
||||
mv /tmp/docker-compose.yml /stirling/test-${{ github.sha }}/docker-compose.yml
|
||||
cd /stirling/test-${{ github.sha }}
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
EOF
|
||||
|
||||
test:
|
||||
needs: deploy
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Run TestDriver.ai
|
||||
uses: testdriverai/action@47e87c5d50beeeb3da624b2d9b5c1391269d6d22 #1.0.0
|
||||
with:
|
||||
key: ${{secrets.TESTDRIVER_API_KEY}}
|
||||
prerun: |
|
||||
npm install
|
||||
npm run build
|
||||
npm install dashcam-chrome --save
|
||||
Start-Process "C:/Program Files/Google/Chrome/Application/chrome.exe" -ArgumentList "--start-maximized", "--load-extension=$(pwd)/node_modules/dashcam-chrome/build", "http://${{ secrets.VPS_HOST }}:1337"
|
||||
Start-Sleep -Seconds 20
|
||||
prompt: |
|
||||
1. /run testing/testdriver/test.yml
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
FORCE_COLOR: "3"
|
||||
|
||||
cleanup:
|
||||
needs: [deploy, test]
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Set up SSH
|
||||
run: |
|
||||
mkdir -p ~/.ssh/
|
||||
echo "${{ secrets.VPS_SSH_KEY }}" > ../private.key
|
||||
sudo chmod 600 ../private.key
|
||||
|
||||
- name: Cleanup deployment
|
||||
run: |
|
||||
ssh -i ../private.key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${{ secrets.VPS_USERNAME }}@${{ secrets.VPS_HOST }} << EOF
|
||||
cd /stirling/test-${{ github.sha }}
|
||||
docker-compose down
|
||||
cd /stirling
|
||||
rm -rf test-${{ github.sha }}
|
||||
EOF
|
||||
72
.github/workflows/update-translations.yml
vendored
72
.github/workflows/update-translations.yml
vendored
@@ -1,72 +0,0 @@
|
||||
name: Update Translations
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
paths:
|
||||
- "src/main/resources/messages_en_GB.properties"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
update-translations-main:
|
||||
if: github.event_name == 'push'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Run Python script to check files
|
||||
id: run-check
|
||||
run: |
|
||||
echo "Running Python script to check files..."
|
||||
python .github/scripts/check_language_properties.py \
|
||||
--reference-file src/main/resources/messages_en_GB.properties \
|
||||
--branch main
|
||||
|
||||
- name: Set up git config
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Add translation keys
|
||||
run: |
|
||||
git add src/main/resources/messages_*.properties
|
||||
git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||
|
||||
- name: Create Pull Request
|
||||
id: cpr
|
||||
if: env.CHANGES_DETECTED == 'true'
|
||||
uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7.0.6
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: "Update translation files"
|
||||
committer: GitHub Action <action@github.com>
|
||||
author: GitHub Action <action@github.com>
|
||||
signoff: true
|
||||
branch: update_translation_files
|
||||
title: "Update translation files"
|
||||
add-paths: |
|
||||
src/main/resources/messages_*.properties
|
||||
body: |
|
||||
Auto-generated by [create-pull-request][1]
|
||||
|
||||
[1]: https://github.com/peter-evans/create-pull-request
|
||||
draft: false
|
||||
delete-branch: true
|
||||
labels: Translation,github-actions
|
||||
sign-commits: true
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -21,9 +21,11 @@ pipeline/finishedFolders/
|
||||
customFiles/
|
||||
configs/
|
||||
watchedFolders/
|
||||
clientWebUI/
|
||||
!cucumber/
|
||||
!cucumber/exampleFiles/
|
||||
!cucumber/exampleFiles/example_html.zip
|
||||
exampleYmlFiles/stirling/
|
||||
|
||||
# Gradle
|
||||
.gradle
|
||||
|
||||
@@ -6,10 +6,10 @@ repos:
|
||||
args:
|
||||
- --fix
|
||||
- --line-length=127
|
||||
files: ^((.github/scripts|scripts)/.+)?[^/]+\.py$
|
||||
files: ^((\.github/scripts|scripts)/.+)?[^/]+\.py$
|
||||
exclude: (split_photos.py)
|
||||
- id: ruff-format
|
||||
files: ^((.github/scripts|scripts)/.+)?[^/]+\.py$
|
||||
files: ^((\.github/scripts|scripts)/.+)?[^/]+\.py$
|
||||
exclude: (split_photos.py)
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.3.0
|
||||
@@ -19,39 +19,18 @@ repos:
|
||||
- --ignore-words-list=
|
||||
- --skip="./.*,*.csv,*.json,*.ambr"
|
||||
- --quiet-level=2
|
||||
files: \.(properties|html|css|js|py|md)$
|
||||
files: \.(html|css|js|py|md)$
|
||||
exclude: (.vscode|.devcontainer|src/main/resources|Dockerfile|.*/pdfjs.*|.*/thirdParty.*|bootstrap.*|.*\.min\..*|.*diff\.js)
|
||||
- repo: https://github.com/gitleaks/gitleaks
|
||||
rev: v8.22.0
|
||||
hooks:
|
||||
- id: gitleaks
|
||||
- repo: https://github.com/jumanjihouse/pre-commit-hooks
|
||||
rev: 3.0.0
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
files: ^.*(\.bash|\.sh|\.ksh|\.zsh)$
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: end-of-file-fixer
|
||||
files: ^.*(\.js|\.java|\.py|\.yml)$
|
||||
exclude: ^(.*/pdfjs.*|.*/thirdParty.*|bootstrap.*|.*\.min\..*|.*diff\.js$)
|
||||
exclude: ^(.*/pdfjs.*|.*/thirdParty.*|bootstrap.*|.*\.min\..*|.*diff\.js|\.github/workflows/.*$)
|
||||
- id: trailing-whitespace
|
||||
files: ^.*(\.js|\.java|\.py|\.yml)$
|
||||
exclude: ^(.*/pdfjs.*|.*/thirdParty.*|bootstrap.*|.*\.min\..*|.*diff\.js$)
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: check-duplicate-properties-keys
|
||||
name: Check Duplicate Properties Keys
|
||||
entry: python .github/scripts/check_duplicates.py
|
||||
language: python
|
||||
files: ^(src)/.+\.properties$
|
||||
- id: check-html-tabs
|
||||
name: Check HTML for tabs
|
||||
description: Ensures HTML/CSS/JS files do not contain tab characters
|
||||
# args: ["--replace_with= "]
|
||||
entry: python .github/scripts/check_tabulator.py
|
||||
language: python
|
||||
exclude: ^(.*/pdfjs.*|.*/thirdParty.*|bootstrap.*|.*\.min\..*|.*diff\.js$)
|
||||
files: ^.*(\.html|\.css|\.js)$
|
||||
exclude: ^(.*/pdfjs.*|.*/thirdParty.*|bootstrap.*|.*\.min\..*|.*diff\.js|\.github/workflows/.*$)
|
||||
|
||||
@@ -575,3 +575,42 @@ In your Thymeleaf templates, use the `#{key}` syntax to reference the new transl
|
||||
```
|
||||
|
||||
Remember, never hard-code text in your templates or Java code. Always use translation keys to ensure proper localization.
|
||||
|
||||
|
||||
## Managing Dependencies
|
||||
|
||||
When adding new dependencies or updating existing ones in Stirling-PDF, follow these steps to ensure proper verification and security:
|
||||
|
||||
1. Update the dependency in `build.gradle`:
|
||||
```groovy
|
||||
dependencies {
|
||||
// Add or update your dependency
|
||||
implementation "com.example:new-library:1.2.3"
|
||||
}
|
||||
```
|
||||
|
||||
2. Generate new verification metadata and keys:
|
||||
```bash
|
||||
# Generate verification metadata with signatures and checksums
|
||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp
|
||||
|
||||
# Export the .keys file
|
||||
./gradlew --export-keys
|
||||
```
|
||||
|
||||
3. Files to commit:
|
||||
- `build.gradle` - Your dependency changes
|
||||
- `gradle/verification-metadata.xml` - Contains verification rules and checksums
|
||||
- `gradle/verification-keyring.keys` - Contains PGP keys in text format
|
||||
|
||||
4. Verify the build works with the new verification:
|
||||
```bash
|
||||
./gradlew build
|
||||
```
|
||||
|
||||
5. Before committing, check:
|
||||
- Verify any new BOM files are properly handled in verification metadata
|
||||
- Review the changes in `verification-metadata.xml` to ensure they match your dependency updates
|
||||
|
||||
This ensures dependencies are properly verified and secure while maintaining transparency in the repository.
|
||||
|
||||
|
||||
@@ -25,7 +25,13 @@ LABEL org.opencontainers.image.keywords="PDF, manipulation, merge, split, conver
|
||||
# Set Environment Variables
|
||||
ENV DOCKER_ENABLE_SECURITY=false \
|
||||
VERSION_TAG=$VERSION_TAG \
|
||||
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" \
|
||||
JAVA_TOOL_OPTIONS="-XX:+UnlockExperimentalVMOptions \
|
||||
-XX:MaxRAMPercentage=75 \
|
||||
-XX:InitiatingHeapOccupancyPercent=20 \
|
||||
-XX:+G1PeriodicGCInvokesConcurrent \
|
||||
-XX:G1PeriodicGCInterval=10000 \
|
||||
-XX:+UseStringDeduplication \
|
||||
-XX:G1PeriodicGCSystemLoadThreshold=70" \
|
||||
HOME=/home/stirlingpdfuser \
|
||||
PUID=1000 \
|
||||
PGID=1000 \
|
||||
|
||||
@@ -25,7 +25,13 @@ ARG VERSION_TAG
|
||||
# Set Environment Variables
|
||||
ENV DOCKER_ENABLE_SECURITY=false \
|
||||
VERSION_TAG=$VERSION_TAG \
|
||||
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" \
|
||||
JAVA_TOOL_OPTIONS="-XX:+UnlockExperimentalVMOptions \
|
||||
-XX:MaxRAMPercentage=75 \
|
||||
-XX:InitiatingHeapOccupancyPercent=20 \
|
||||
-XX:+G1PeriodicGCInvokesConcurrent \
|
||||
-XX:G1PeriodicGCInterval=10000 \
|
||||
-XX:+UseStringDeduplication \
|
||||
-XX:G1PeriodicGCSystemLoadThreshold=70" \
|
||||
HOME=/home/stirlingpdfuser \
|
||||
PUID=1000 \
|
||||
PGID=1000 \
|
||||
|
||||
@@ -7,7 +7,13 @@ ARG VERSION_TAG
|
||||
ENV DOCKER_ENABLE_SECURITY=false \
|
||||
HOME=/home/stirlingpdfuser \
|
||||
VERSION_TAG=$VERSION_TAG \
|
||||
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" \
|
||||
JAVA_TOOL_OPTIONS="-XX:+UnlockExperimentalVMOptions \
|
||||
-XX:MaxRAMPercentage=75 \
|
||||
-XX:InitiatingHeapOccupancyPercent=20 \
|
||||
-XX:+G1PeriodicGCInvokesConcurrent \
|
||||
-XX:G1PeriodicGCInterval=10000 \
|
||||
-XX:+UseStringDeduplication \
|
||||
-XX:G1PeriodicGCSystemLoadThreshold=70" \
|
||||
PUID=1000 \
|
||||
PGID=1000 \
|
||||
UMASK=022
|
||||
|
||||
@@ -60,3 +60,13 @@ ignore = [
|
||||
- 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.
|
||||
|
||||
### Use this code to perform a local check
|
||||
|
||||
#### Windows command
|
||||
|
||||
```ps
|
||||
python .github/scripts/check_language_properties.py --reference-file src\main\resources\messages_en_GB.properties --branch "" --files src\main\resources\messages_pl_PL.properties
|
||||
|
||||
python .github/scripts/check_language_properties.py --reference-file src\main\resources\messages_en_GB.properties --branch "" --check-file src\main\resources\messages_pl_PL.properties
|
||||
```
|
||||
|
||||
51
README.md
51
README.md
@@ -113,45 +113,46 @@ Visit our comprehensive documentation at [docs.stirlingpdf.com](https://docs.sti
|
||||
|
||||
## Supported Languages
|
||||
|
||||
Stirling-PDF currently supports 38 languages!
|
||||
Stirling-PDF currently supports 39 languages!
|
||||
|
||||
| Language | Progress |
|
||||
| -------------------------------------------- | -------------------------------------- |
|
||||
| Arabic (العربية) (ar_AR) |  |
|
||||
| Arabic (العربية) (ar_AR) |  |
|
||||
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
||||
| Basque (Euskara) (eu_ES) |  |
|
||||
| Bulgarian (Български) (bg_BG) |  |
|
||||
| Bulgarian (Български) (bg_BG) |  |
|
||||
| Catalan (Català) (ca_CA) |  |
|
||||
| Croatian (Hrvatski) (hr_HR) |  |
|
||||
| Czech (Česky) (cs_CZ) |  |
|
||||
| Danish (Dansk) (da_DK) |  |
|
||||
| Dutch (Nederlands) (nl_NL) |  |
|
||||
| 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) |  |
|
||||
| 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) |  |
|
||||
| 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) |  |
|
||||
| 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) |  |
|
||||
| Spanish (Español) (es_ES) |  |
|
||||
| Swedish (Svenska) (sv_SE) |  |
|
||||
| Thai (ไทย) (th_TH) |  |
|
||||
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
||||
| Slovenian (Slovenščina) (sl_SI) |  |
|
||||
| Spanish (Español) (es_ES) |  |
|
||||
| Swedish (Svenska) (sv_SE) |  |
|
||||
| Thai (ไทย) (th_TH) |  |
|
||||
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||
| Turkish (Türkçe) (tr_TR) |  |
|
||||
| Ukrainian (Українська) (uk_UA) |  |
|
||||
|
||||
45
USERS.md
Normal file
45
USERS.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Who is using Stirling-PDF?
|
||||
|
||||
Understanding the diverse applications of Stirling-PDF can be an invaluable resource for collaboration and learning. This page provides a directory of users and use cases. If you are using Stirling-PDF, consider sharing your experiences to help others and foster a community of best practices.
|
||||
|
||||
## Adding Yourself as a User
|
||||
|
||||
If you're using Stirling-PDF or have integrated it into your platform or workflow, please consider contributing to this list by describing your use case. You can do this by opening a pull request to this file and adding your details in the format below:
|
||||
|
||||
- **N**: Name of the organization or individual.
|
||||
- **D**: A brief description of your usage.
|
||||
- **U**: Specific features or capabilities utilized.
|
||||
- **L**: Optional link for further information (e.g., website, blog post).
|
||||
- **Q**: Contact information for sharing insights (optional).
|
||||
|
||||
Example entry:
|
||||
|
||||
```
|
||||
* N: Example Corp
|
||||
D: Using Stirling-PDF for automated document processing in our SaaS platform focusing on compression.
|
||||
U: OCR, merging PDFs, metadata editing, encryption, compression.
|
||||
L: https://example.com/stirling-pdf
|
||||
Q: @example-user on Discord/email
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Requirements for Listing
|
||||
|
||||
- You must represent the entity you're listing and ensure the details are accurate.
|
||||
- Trial deployments are welcome if they represent a realistic evaluation of Stirling-PDF in action.
|
||||
- Community contributions, including home-lab setups or non-commercial uses, are encouraged.
|
||||
|
||||
---
|
||||
|
||||
## Users (Alphabetically)
|
||||
|
||||
* N:
|
||||
D:
|
||||
U:
|
||||
L:
|
||||
|
||||
* N:
|
||||
D:
|
||||
U:
|
||||
L:
|
||||
111
build.gradle
111
build.gradle
@@ -5,14 +5,12 @@ plugins {
|
||||
id "org.springdoc.openapi-gradle-plugin" version "1.8.0"
|
||||
id "io.swagger.swaggerhub" version "1.3.2"
|
||||
id "edu.sc.seis.launch4j" version "3.0.6"
|
||||
id "com.diffplug.spotless" version "7.0.1"
|
||||
id "com.diffplug.spotless" version "7.0.2"
|
||||
id "com.github.jk1.dependency-license-report" version "2.9"
|
||||
//id "nebula.lint" version "19.0.3"
|
||||
id("org.panteleyev.jpackageplugin") version "1.6.0"
|
||||
//id "nebula.lint" version "19.0.3"
|
||||
id("org.panteleyev.jpackageplugin") version "1.6.0"
|
||||
}
|
||||
|
||||
|
||||
|
||||
import com.github.jk1.license.render.*
|
||||
|
||||
ext {
|
||||
@@ -21,13 +19,13 @@ ext {
|
||||
logbackVersion = "1.5.7"
|
||||
imageioVersion = "3.12.0"
|
||||
lombokVersion = "1.18.36"
|
||||
bouncycastleVersion = "1.79"
|
||||
bouncycastleVersion = "1.80"
|
||||
springSecuritySamlVersion = "6.4.2"
|
||||
openSamlVersion = "4.3.2"
|
||||
}
|
||||
|
||||
group = "stirling.software"
|
||||
version = "0.37.0"
|
||||
version = "0.39.0"
|
||||
|
||||
|
||||
java {
|
||||
@@ -37,9 +35,9 @@ java {
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://jitpack.io" }
|
||||
maven { url "https://build.shibboleth.net/maven/releases" }
|
||||
maven { url "https://maven.pkg.github.com/jcefmaven/jcefmaven" }
|
||||
maven { url = "https://jitpack.io" }
|
||||
maven { url = "https://build.shibboleth.net/maven/releases" }
|
||||
maven { url = "https://maven.pkg.github.com/jcefmaven/jcefmaven" }
|
||||
|
||||
}
|
||||
|
||||
@@ -68,7 +66,7 @@ sourceSets {
|
||||
}
|
||||
|
||||
if (System.getenv("STIRLING_PDF_DESKTOP_UI") == "false") {
|
||||
exclude "stirling/software/SPDF/UI/impl/**"
|
||||
exclude "stirling/software/SPDF/UI/impl/**"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -113,18 +111,15 @@ def getMacVersion(String version) {
|
||||
|
||||
jpackage {
|
||||
input = "build/libs"
|
||||
|
||||
destination = "${projectDir}/build/jpackage"
|
||||
mainJar = "Stirling-PDF-${project.version}.jar"
|
||||
appName = "Stirling-PDF"
|
||||
appVersion = project.version
|
||||
vendor = "Stirling-Software"
|
||||
appDescription = "Stirling PDF - Your Local PDF Editor"
|
||||
|
||||
mainJar = "Stirling-PDF-${project.version}.jar"
|
||||
mainClass = "org.springframework.boot.loader.launch.JarLauncher"
|
||||
|
||||
appDescription = "Stirling PDF - Your Local PDF Editor"
|
||||
icon = "src/main/resources/static/favicon.ico"
|
||||
|
||||
|
||||
verbose = true
|
||||
// mainClass = "org.springframework.boot.loader.launch.JarLauncher"
|
||||
|
||||
// JVM Options
|
||||
javaOptions = [
|
||||
@@ -132,23 +127,21 @@ jpackage {
|
||||
"-DSTIRLING_PDF_DESKTOP_UI=true",
|
||||
"-Djava.awt.headless=false",
|
||||
"-Dapple.awt.UIElement=true",
|
||||
"--add-opens", "java.base/java.lang=ALL-UNNAMED",
|
||||
"--add-opens", "java.desktop/java.awt.event=ALL-UNNAMED",
|
||||
"--add-opens", "java.desktop/sun.awt=ALL-UNNAMED"
|
||||
|
||||
"--add-opens=java.base/java.lang=ALL-UNNAMED",
|
||||
"--add-opens=java.desktop/java.awt.event=ALL-UNNAMED",
|
||||
"--add-opens=java.desktop/sun.awt=ALL-UNNAMED",
|
||||
"--add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED",
|
||||
"--add-opens=java.desktop/sun.awt.windows=ALL-UNNAMED",
|
||||
"--add-opens=java.desktop/sun.lwawt=ALL-UNNAMED",
|
||||
"--add-opens=java.desktop/sun.lwawt.macosx=ALL-UNNAMED",
|
||||
]
|
||||
|
||||
|
||||
verbose = true
|
||||
|
||||
destination = "${projectDir}/build/jpackage"
|
||||
|
||||
// Windows-specific configuration
|
||||
windows {
|
||||
launcherAsService = false
|
||||
appVersion = project.version
|
||||
launcherAsService = false
|
||||
appVersion = project.version
|
||||
|
||||
winConsole = false
|
||||
winConsole = false
|
||||
winMenu = true // Creates start menu entry
|
||||
winShortcut = true // Creates desktop shortcut
|
||||
winShortcutPrompt = true // Lets user choose whether to create shortcuts
|
||||
@@ -164,7 +157,7 @@ jpackage {
|
||||
|
||||
// macOS-specific configuration
|
||||
mac {
|
||||
appVersion = getMacVersion(project.version.toString())
|
||||
appVersion = getMacVersion(project.version.toString())
|
||||
icon = "src/main/resources/static/favicon.icns"
|
||||
type = "dmg"
|
||||
macPackageIdentifier = "com.stirling.software.pdf"
|
||||
@@ -188,7 +181,7 @@ jpackage {
|
||||
|
||||
// Linux-specific configuration
|
||||
linux {
|
||||
appVersion = project.version
|
||||
appVersion = project.version
|
||||
icon = "src/main/resources/static/favicon.png"
|
||||
type = "deb" // Can also use "rpm" for Red Hat-based systems
|
||||
|
||||
@@ -236,9 +229,9 @@ launch4j {
|
||||
outfile="Stirling-PDF.exe"
|
||||
|
||||
if(System.getenv("STIRLING_PDF_DESKTOP_UI") == 'true') {
|
||||
headerType = "gui"
|
||||
headerType = "gui"
|
||||
} else {
|
||||
headerType = "console"
|
||||
headerType = "console"
|
||||
}
|
||||
jarTask = tasks.bootJar
|
||||
|
||||
@@ -246,13 +239,11 @@ launch4j {
|
||||
downloadUrl="https://download.oracle.com/java/21/latest/jdk-21_windows-x64_bin.exe"
|
||||
|
||||
if(System.getenv("STIRLING_PDF_DESKTOP_UI") == 'true') {
|
||||
variables=["BROWSER_OPEN=true", "STIRLING_PDF_DESKTOP_UI=true"]
|
||||
variables=["BROWSER_OPEN=true", "STIRLING_PDF_DESKTOP_UI=true"]
|
||||
} else {
|
||||
variables=["BROWSER_OPEN=true"]
|
||||
variables=["BROWSER_OPEN=true"]
|
||||
}
|
||||
|
||||
|
||||
|
||||
jreMinVersion="17"
|
||||
|
||||
mutexName="Stirling-PDF"
|
||||
@@ -274,7 +265,7 @@ spotless {
|
||||
importOrder("java", "javax", "org", "com", "net", "io")
|
||||
toggleOffOn()
|
||||
trimTrailingWhitespace()
|
||||
indentWithSpaces()
|
||||
leadingTabsToSpaces()
|
||||
endWithNewline()
|
||||
}
|
||||
}
|
||||
@@ -293,14 +284,14 @@ configurations.all {
|
||||
}
|
||||
dependencies {
|
||||
|
||||
if (System.getenv("STIRLING_PDF_DESKTOP_UI") != "false") {
|
||||
implementation "me.friwi:jcefmaven:127.3.1"
|
||||
implementation "org.openjfx:javafx-controls:21"
|
||||
implementation "org.openjfx:javafx-swing:21"
|
||||
if (System.getenv("STIRLING_PDF_DESKTOP_UI") != "false") {
|
||||
implementation "me.friwi:jcefmaven:127.3.1"
|
||||
implementation "org.openjfx:javafx-controls:21"
|
||||
implementation "org.openjfx:javafx-swing:21"
|
||||
}
|
||||
|
||||
//security updates
|
||||
implementation "org.springframework:spring-webmvc:6.2.1"
|
||||
implementation "org.springframework:spring-webmvc:6.2.2"
|
||||
|
||||
implementation("io.github.pixee:java-security-toolkit:1.2.1")
|
||||
|
||||
@@ -322,10 +313,10 @@ dependencies {
|
||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
||||
|
||||
implementation "org.springframework.session:spring-session-core:$springBootVersion"
|
||||
implementation "org.springframework:spring-jdbc:6.2.1"
|
||||
implementation "org.springframework.session:spring-session-core:$springBootVersion"
|
||||
implementation "org.springframework:spring-jdbc:6.2.2"
|
||||
|
||||
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
|
||||
implementation 'com.unboundid.product.scim2:scim2-sdk-client:2.3.5'
|
||||
// Don't upgrade h2database
|
||||
runtimeOnly "com.h2database:h2:2.3.232"
|
||||
runtimeOnly "org.postgresql:postgresql:42.7.4"
|
||||
@@ -335,7 +326,7 @@ dependencies {
|
||||
implementation "org.opensaml:opensaml-saml-impl:$openSamlVersion"
|
||||
}
|
||||
implementation "org.springframework.security:spring-security-saml2-service-provider:$springSecuritySamlVersion"
|
||||
// implementation 'org.springframework.security:spring-security-core:$springSecuritySamlVersion'
|
||||
// implementation 'org.springframework.security:spring-security-core:$springSecuritySamlVersion'
|
||||
implementation 'com.coveo:saml-client:5.0.0'
|
||||
|
||||
|
||||
@@ -372,13 +363,15 @@ dependencies {
|
||||
//general PDF
|
||||
|
||||
// https://mvnrepository.com/artifact/com.opencsv/opencsv
|
||||
implementation ("com.opencsv:opencsv:5.9") {
|
||||
implementation ("com.opencsv:opencsv:5.10") {
|
||||
exclude group: "commons-logging", module: "commons-logging"
|
||||
}
|
||||
|
||||
implementation ("org.apache.pdfbox:pdfbox:$pdfboxVersion") {
|
||||
exclude group: "commons-logging", module: "commons-logging"
|
||||
}
|
||||
implementation "org.apache.pdfbox:preflight:$pdfboxVersion"
|
||||
|
||||
|
||||
implementation ("org.apache.pdfbox:xmpbox:$pdfboxVersion") {
|
||||
exclude group: "commons-logging", module: "commons-logging"
|
||||
@@ -396,7 +389,7 @@ dependencies {
|
||||
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
|
||||
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
|
||||
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
|
||||
implementation "io.micrometer:micrometer-core:1.14.2"
|
||||
implementation "io.micrometer:micrometer-core:1.14.3"
|
||||
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
|
||||
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
||||
implementation "org.commonmark:commonmark:0.24.0"
|
||||
@@ -405,6 +398,8 @@ dependencies {
|
||||
implementation "com.bucket4j:bucket4j_jdk17-core:8.14.0"
|
||||
implementation "com.fathzer:javaluator:3.0.5"
|
||||
|
||||
implementation 'com.vladsch.flexmark:flexmark-html2md-converter:0.64.8'
|
||||
|
||||
developmentOnly("org.springframework.boot:spring-boot-devtools:$springBootVersion")
|
||||
compileOnly "org.projectlombok:lombok:$lombokVersion"
|
||||
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
|
||||
@@ -428,13 +423,13 @@ task writeVersion {
|
||||
}
|
||||
|
||||
swaggerhubUpload {
|
||||
//dependsOn generateOpenApiDocs // Depends on your task generating Swagger docs
|
||||
api "Stirling-PDF" // The name of your API on SwaggerHub
|
||||
owner "Frooodle" // Your SwaggerHub username (or organization name)
|
||||
version project.version // The version of your API
|
||||
inputFile "./SwaggerDoc.json" // The path to your Swagger docs
|
||||
token "${System.getenv("SWAGGERHUB_API_KEY")}" // Your SwaggerHub API key, passed as an environment variable
|
||||
oas "3.0.0" // The version of the OpenAPI Specification you"re using
|
||||
// dependsOn = generateOpenApiDocs // Depends on your task generating Swagger docs
|
||||
api = "Stirling-PDF" // The name of your API on SwaggerHub
|
||||
owner = "Frooodle" // Your SwaggerHub username (or organization name)
|
||||
version = project.version // The version of your API
|
||||
inputFile = "./SwaggerDoc.json" // The path to your Swagger docs
|
||||
token = "${System.getenv("SWAGGERHUB_API_KEY")}" // Your SwaggerHub API key, passed as an environment variable
|
||||
oas = "3.0.0" // The version of the OpenAPI Specification you"re using
|
||||
}
|
||||
|
||||
jar {
|
||||
|
||||
@@ -60,4 +60,4 @@ services:
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
volumes:
|
||||
- ./stirling/latest/data:/pgdata
|
||||
- ./stirling/latest/data:/pgdata
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
stirling-pdf:
|
||||
container_name: Stirling-PDF-Security-Fat
|
||||
container_name: Stirling-PDF-Security-Fat-with-login
|
||||
image: stirlingtools/stirling-pdf:latest-fat
|
||||
deploy:
|
||||
resources:
|
||||
|
||||
6661
gradle/verification-keyring.keys
Normal file
6661
gradle/verification-keyring.keys
Normal file
File diff suppressed because it is too large
Load Diff
4553
gradle/verification-metadata.xml
Normal file
4553
gradle/verification-metadata.xml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -75,7 +75,7 @@ def write_readme(progress_list: list[tuple[str, int]]) -> None:
|
||||
f"",
|
||||
)
|
||||
|
||||
with open("README.md", "w", encoding="utf-8") as file:
|
||||
with open("README.md", "w", encoding="utf-8", newline="\n") as file:
|
||||
file.writelines(content)
|
||||
|
||||
|
||||
@@ -135,9 +135,10 @@ def compare_files(
|
||||
# elif "language.direction" in sort_ignore_translation[language]["missing"]:
|
||||
# sort_ignore_translation[language]["missing"].remove("language.direction")
|
||||
|
||||
with open(default_file_path, encoding="utf-8") as default_file, open(
|
||||
file_path, encoding="utf-8"
|
||||
) as file:
|
||||
with (
|
||||
open(default_file_path, encoding="utf-8") as default_file,
|
||||
open(file_path, encoding="utf-8") as file,
|
||||
):
|
||||
for _ in range(5):
|
||||
next(default_file)
|
||||
try:
|
||||
@@ -195,7 +196,7 @@ def compare_files(
|
||||
)
|
||||
)
|
||||
ignore_translation = convert_to_multiline(sort_ignore_translation)
|
||||
with open(ignore_translation_file, "w", encoding="utf-8") as file:
|
||||
with open(ignore_translation_file, "w", encoding="utf-8", newline="\n") as file:
|
||||
file.write(tomlkit.dumps(ignore_translation))
|
||||
|
||||
unique_data = list(set(result_list))
|
||||
|
||||
@@ -24,7 +24,6 @@ ignore = [
|
||||
[cs_CZ]
|
||||
ignore = [
|
||||
'language.direction',
|
||||
'pipeline.header',
|
||||
'text',
|
||||
]
|
||||
|
||||
@@ -50,6 +49,7 @@ ignore = [
|
||||
'pipeline.title',
|
||||
'pipelineOptions.pipelineHeader',
|
||||
'pro',
|
||||
'redact.zoom',
|
||||
'sponsor',
|
||||
'text',
|
||||
'validateSignature.cert.bits',
|
||||
@@ -210,6 +210,11 @@ ignore = [
|
||||
'watermark.type.1',
|
||||
]
|
||||
|
||||
[sl_SI]
|
||||
ignore = [
|
||||
'language.direction',
|
||||
]
|
||||
|
||||
[sr_LATN_RS]
|
||||
ignore = [
|
||||
'language.direction',
|
||||
|
||||
@@ -126,6 +126,7 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Convert", "url-to-pdf");
|
||||
addEndpointToGroup("Convert", "markdown-to-pdf");
|
||||
addEndpointToGroup("Convert", "pdf-to-csv");
|
||||
addEndpointToGroup("Convert", "pdf-to-markdown");
|
||||
|
||||
// Adding endpoints to "Security" group
|
||||
addEndpointToGroup("Security", "add-password");
|
||||
@@ -182,7 +183,6 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Python", "extract-image-scans");
|
||||
addEndpointToGroup("Python", "html-to-pdf");
|
||||
addEndpointToGroup("Python", "url-to-pdf");
|
||||
addEndpointToGroup("Python", "pdf-to-img");
|
||||
addEndpointToGroup("Python", "file-to-pdf");
|
||||
|
||||
// openCV
|
||||
@@ -244,6 +244,7 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Java", REMOVE_BLANKS);
|
||||
addEndpointToGroup("Java", "pdf-to-text");
|
||||
addEndpointToGroup("Java", "remove-image-pdf");
|
||||
addEndpointToGroup("Java", "pdf-to-markdown");
|
||||
|
||||
// Javascript
|
||||
addEndpointToGroup("Javascript", "pdf-organizer");
|
||||
@@ -259,9 +260,11 @@ public class EndpointConfiguration {
|
||||
// Weasyprint dependent endpoints
|
||||
addEndpointToGroup("Weasyprint", "html-to-pdf");
|
||||
addEndpointToGroup("Weasyprint", "url-to-pdf");
|
||||
addEndpointToGroup("Weasyprint", "markdown-to-pdf");
|
||||
|
||||
// Pdftohtml dependent endpoints
|
||||
addEndpointToGroup("Pdftohtml", "pdf-to-html");
|
||||
addEndpointToGroup("Pdftohtml", "pdf-to-markdown");
|
||||
|
||||
// disabled for now while we resolve issues
|
||||
disableEndpoint("pdf-to-pdfa");
|
||||
|
||||
@@ -23,12 +23,12 @@ public class InstallationPathConfig {
|
||||
private static final String PIPELINE_WATCHED_FOLDERS_PATH;
|
||||
private static final String PIPELINE_FINISHED_FOLDERS_PATH;
|
||||
private static final String PIPELINE_DEFAULT_WEB_UI_CONFIGS;
|
||||
|
||||
|
||||
// Custom file paths
|
||||
private static final String STATIC_PATH;
|
||||
private static final String TEMPLATES_PATH;
|
||||
private static final String SIGNATURES_PATH;
|
||||
|
||||
|
||||
static {
|
||||
BASE_PATH = initializeBasePath();
|
||||
|
||||
@@ -47,7 +47,7 @@ public class InstallationPathConfig {
|
||||
PIPELINE_WATCHED_FOLDERS_PATH = PIPELINE_PATH + "watchedFolders" + File.separator;
|
||||
PIPELINE_FINISHED_FOLDERS_PATH = PIPELINE_PATH + "finishedFolders" + File.separator;
|
||||
PIPELINE_DEFAULT_WEB_UI_CONFIGS = PIPELINE_PATH + "defaultWebUIConfigs" + File.separator;
|
||||
|
||||
|
||||
// Initialize custom file paths
|
||||
STATIC_PATH = CUSTOM_FILES_PATH + "static" + File.separator;
|
||||
TEMPLATES_PATH = CUSTOM_FILES_PATH + "templates" + File.separator;
|
||||
@@ -123,7 +123,7 @@ public class InstallationPathConfig {
|
||||
public static String getPipelineDefaultWebUIConfigsDir() {
|
||||
return PIPELINE_DEFAULT_WEB_UI_CONFIGS;
|
||||
}
|
||||
|
||||
|
||||
public static String getStaticPath() {
|
||||
return STATIC_PATH;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import stirling.software.SPDF.model.provider.UnsupportedProviderException;
|
||||
public class DatabaseConfig {
|
||||
|
||||
public final String DATASOURCE_DEFAULT_URL;
|
||||
|
||||
|
||||
public static final String DATASOURCE_URL_TEMPLATE = "jdbc:%s://%s:%4d/%s";
|
||||
public static final String DEFAULT_DRIVER = "org.h2.Driver";
|
||||
public static final String DEFAULT_USERNAME = "sa";
|
||||
@@ -33,7 +33,11 @@ public class DatabaseConfig {
|
||||
public DatabaseConfig(
|
||||
ApplicationProperties applicationProperties,
|
||||
@Qualifier("runningEE") boolean runningEE) {
|
||||
DATASOURCE_DEFAULT_URL = "jdbc:h2:file:" + InstallationPathConfig.getConfigPath() + File.separator + "stirling-pdf-DB-2.3.232;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE";
|
||||
DATASOURCE_DEFAULT_URL =
|
||||
"jdbc:h2:file:"
|
||||
+ InstallationPathConfig.getConfigPath()
|
||||
+ File.separator
|
||||
+ "stirling-pdf-DB-2.3.232;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE";
|
||||
this.applicationProperties = applicationProperties;
|
||||
this.runningEE = runningEE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
package stirling.software.SPDF.controller.api;
|
||||
|
||||
import org.apache.pdfbox.Loader;
|
||||
import org.apache.pdfbox.cos.COSName;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.pdmodel.PDPage;
|
||||
import org.apache.pdfbox.pdmodel.PDPageTree;
|
||||
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
|
||||
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
|
||||
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
|
||||
import org.apache.pdfbox.pdmodel.encryption.PDEncryption;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import stirling.software.SPDF.model.api.PDFFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/analysis")
|
||||
@Tag(name = "Analysis", description = "Analysis APIs")
|
||||
public class AnalysisController {
|
||||
|
||||
|
||||
@PostMapping(value = "/page-count", consumes = "multipart/form-data")
|
||||
@Operation(summary = "Get PDF page count",
|
||||
description = "Returns total number of pages in PDF. Input:PDF Output:JSON Type:SISO")
|
||||
public Map<String, Integer> getPageCount(@ModelAttribute PDFFile file) throws IOException {
|
||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||
return Map.of("pageCount", document.getNumberOfPages());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value ="/basic-info", consumes = "multipart/form-data")
|
||||
@Operation(summary = "Get basic PDF information",
|
||||
description = "Returns page count, version, file size. Input:PDF Output:JSON Type:SISO")
|
||||
public Map<String, Object> getBasicInfo(@ModelAttribute PDFFile file) throws IOException {
|
||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||
Map<String, Object> info = new HashMap<>();
|
||||
info.put("pageCount", document.getNumberOfPages());
|
||||
info.put("pdfVersion", document.getVersion());
|
||||
info.put("fileSize", file.getFileInput().getSize());
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value ="/document-properties", consumes = "multipart/form-data")
|
||||
@Operation(summary = "Get PDF document properties",
|
||||
description = "Returns title, author, subject, etc. Input:PDF Output:JSON Type:SISO")
|
||||
public Map<String, String> getDocumentProperties(@ModelAttribute PDFFile file) throws IOException {
|
||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||
PDDocumentInformation info = document.getDocumentInformation();
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
properties.put("title", info.getTitle());
|
||||
properties.put("author", info.getAuthor());
|
||||
properties.put("subject", info.getSubject());
|
||||
properties.put("keywords", info.getKeywords());
|
||||
properties.put("creator", info.getCreator());
|
||||
properties.put("producer", info.getProducer());
|
||||
properties.put("creationDate", info.getCreationDate().toString());
|
||||
properties.put("modificationDate", info.getModificationDate().toString());
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value ="/page-dimensions", consumes = "multipart/form-data")
|
||||
@Operation(summary = "Get page dimensions for all pages",
|
||||
description = "Returns width and height of each page. Input:PDF Output:JSON Type:SISO")
|
||||
public List<Map<String, Float>> getPageDimensions(@ModelAttribute PDFFile file) throws IOException {
|
||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||
List<Map<String, Float>> dimensions = new ArrayList<>();
|
||||
PDPageTree pages = document.getPages();
|
||||
|
||||
for (PDPage page : pages) {
|
||||
Map<String, Float> pageDim = new HashMap<>();
|
||||
pageDim.put("width", page.getBBox().getWidth());
|
||||
pageDim.put("height", page.getBBox().getHeight());
|
||||
dimensions.add(pageDim);
|
||||
}
|
||||
return dimensions;
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value ="/form-fields", consumes = "multipart/form-data")
|
||||
@Operation(summary = "Get form field information",
|
||||
description = "Returns count and details of form fields. Input:PDF Output:JSON Type:SISO")
|
||||
public Map<String, Object> getFormFields(@ModelAttribute PDFFile file) throws IOException {
|
||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||
Map<String, Object> formInfo = new HashMap<>();
|
||||
PDAcroForm form = document.getDocumentCatalog().getAcroForm();
|
||||
|
||||
if (form != null) {
|
||||
formInfo.put("fieldCount", form.getFields().size());
|
||||
formInfo.put("hasXFA", form.hasXFA());
|
||||
formInfo.put("isSignaturesExist", form.isSignaturesExist());
|
||||
} else {
|
||||
formInfo.put("fieldCount", 0);
|
||||
formInfo.put("hasXFA", false);
|
||||
formInfo.put("isSignaturesExist", false);
|
||||
}
|
||||
return formInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value ="/annotation-info", consumes = "multipart/form-data")
|
||||
@Operation(summary = "Get annotation information",
|
||||
description = "Returns count and types of annotations. Input:PDF Output:JSON Type:SISO")
|
||||
public Map<String, Object> getAnnotationInfo(@ModelAttribute PDFFile file) throws IOException {
|
||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||
Map<String, Object> annotInfo = new HashMap<>();
|
||||
int totalAnnotations = 0;
|
||||
Map<String, Integer> annotationTypes = new HashMap<>();
|
||||
|
||||
for (PDPage page : document.getPages()) {
|
||||
for (PDAnnotation annot : page.getAnnotations()) {
|
||||
totalAnnotations++;
|
||||
String subType = annot.getSubtype();
|
||||
annotationTypes.merge(subType, 1, Integer::sum);
|
||||
}
|
||||
}
|
||||
|
||||
annotInfo.put("totalCount", totalAnnotations);
|
||||
annotInfo.put("typeBreakdown", annotationTypes);
|
||||
return annotInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value ="/font-info", consumes = "multipart/form-data")
|
||||
@Operation(summary = "Get font information",
|
||||
description = "Returns list of fonts used in the document. Input:PDF Output:JSON Type:SISO")
|
||||
public Map<String, Object> getFontInfo(@ModelAttribute PDFFile file) throws IOException {
|
||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||
Map<String, Object> fontInfo = new HashMap<>();
|
||||
Set<String> fontNames = new HashSet<>();
|
||||
|
||||
for (PDPage page : document.getPages()) {
|
||||
for (COSName font : page.getResources().getFontNames()) {
|
||||
fontNames.add(font.getName());
|
||||
}
|
||||
}
|
||||
|
||||
fontInfo.put("fontCount", fontNames.size());
|
||||
fontInfo.put("fonts", fontNames);
|
||||
return fontInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping(value ="/security-info", consumes = "multipart/form-data")
|
||||
@Operation(summary = "Get security information",
|
||||
description = "Returns encryption and permission details. Input:PDF Output:JSON Type:SISO")
|
||||
public Map<String, Object> getSecurityInfo(@ModelAttribute PDFFile file) throws IOException {
|
||||
try (PDDocument document = Loader.loadPDF(file.getFileInput().getBytes())) {
|
||||
Map<String, Object> securityInfo = new HashMap<>();
|
||||
PDEncryption encryption = document.getEncryption();
|
||||
|
||||
if (encryption != null) {
|
||||
securityInfo.put("isEncrypted", true);
|
||||
securityInfo.put("keyLength", encryption.getLength());
|
||||
|
||||
// Get permissions
|
||||
Map<String, Boolean> permissions = new HashMap<>();
|
||||
permissions.put("canPrint", document.getCurrentAccessPermission().canPrint());
|
||||
permissions.put("canModify", document.getCurrentAccessPermission().canModify());
|
||||
permissions.put("canExtractContent", document.getCurrentAccessPermission().canExtractContent());
|
||||
permissions.put("canModifyAnnotations", document.getCurrentAccessPermission().canModifyAnnotations());
|
||||
|
||||
securityInfo.put("permissions", permissions);
|
||||
} else {
|
||||
securityInfo.put("isEncrypted", false);
|
||||
}
|
||||
|
||||
return securityInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -214,6 +214,7 @@ public class WatermarkController {
|
||||
+ Math.abs(watermarkHeight * Math.cos(radians)));
|
||||
|
||||
// Calculating the number of rows and columns.
|
||||
|
||||
int watermarkRows = (int) (pageHeight / newWatermarkHeight + 1);
|
||||
int watermarkCols = (int) (pageWidth / newWatermarkWidth + 1);
|
||||
|
||||
|
||||
@@ -44,6 +44,13 @@ public class ConverterWebController {
|
||||
return "convert/markdown-to-pdf";
|
||||
}
|
||||
|
||||
@GetMapping("/pdf-to-markdown")
|
||||
@Hidden
|
||||
public String convertPdfToMarkdownForm(Model model) {
|
||||
model.addAttribute("currentPage", "pdf-to-markdown");
|
||||
return "convert/pdf-to-markdown";
|
||||
}
|
||||
|
||||
@GetMapping("/url-to-pdf")
|
||||
@Hidden
|
||||
public String convertURLToPdfForm(Model model) {
|
||||
|
||||
@@ -55,7 +55,10 @@ public class GeneralWebController {
|
||||
List<String> pipelineConfigs = new ArrayList<>();
|
||||
List<Map<String, String>> pipelineConfigsWithNames = new ArrayList<>();
|
||||
if (new File(InstallationPathConfig.getPipelineDefaultWebUIConfigsDir()).exists()) {
|
||||
try (Stream<Path> paths = Files.walk(Paths.get(InstallationPathConfig.getPipelineDefaultWebUIConfigsDir()))) {
|
||||
try (Stream<Path> paths =
|
||||
Files.walk(
|
||||
Paths.get(
|
||||
InstallationPathConfig.getPipelineDefaultWebUIConfigsDir()))) {
|
||||
List<Path> jsonFiles =
|
||||
paths.filter(Files::isRegularFile)
|
||||
.filter(p -> p.toString().endsWith(".json"))
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package stirling.software.SPDF.model.api.converters;
|
||||
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
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 stirling.software.SPDF.model.api.PDFFile;
|
||||
import stirling.software.SPDF.utils.PDFToFile;
|
||||
|
||||
@RestController
|
||||
@Tag(name = "Convert", description = "Convert APIs")
|
||||
@RequestMapping("/api/v1/convert")
|
||||
public class ConvertPDFToMarkdown {
|
||||
|
||||
@PostMapping(consumes = "multipart/form-data", value = "/pdf/markdown")
|
||||
@Operation(
|
||||
summary = "Convert PDF to Markdown",
|
||||
description =
|
||||
"This endpoint converts a PDF file to Markdown format. Input:PDF Output:Markdown Type:SISO")
|
||||
public ResponseEntity<byte[]> processPdfToMarkdown(@ModelAttribute PDFFile request)
|
||||
throws Exception {
|
||||
MultipartFile inputFile = request.getFileInput();
|
||||
PDFToFile pdfToFile = new PDFToFile();
|
||||
return pdfToFile.processPdfToMarkdown(inputFile);
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ public class OptimizePdfRequest extends PDFFile {
|
||||
|
||||
@Schema(
|
||||
description =
|
||||
"Whether to normalize the PDF content for better compatibility. Default is true.",
|
||||
defaultValue = "true")
|
||||
private Boolean normalize = true;
|
||||
"Whether to normalize the PDF content for better compatibility. Default is false.",
|
||||
defaultValue = "false")
|
||||
private Boolean normalize = false;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class MetricsAggregatorService {
|
||||
if (method == null || uri == null) {
|
||||
return;
|
||||
}
|
||||
if (!method.equals("GET") && !method.equals("POST")) {
|
||||
if (!"GET".equals(method) && !"POST".equals(method)) {
|
||||
return;
|
||||
}
|
||||
// Skip URIs that are 2 characters or shorter
|
||||
|
||||
@@ -20,6 +20,9 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter;
|
||||
import com.vladsch.flexmark.util.data.MutableDataSet;
|
||||
|
||||
import io.github.pixee.security.Filenames;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -28,6 +31,123 @@ import stirling.software.SPDF.utils.ProcessExecutor.ProcessExecutorResult;
|
||||
@Slf4j
|
||||
public class PDFToFile {
|
||||
|
||||
public ResponseEntity<byte[]> processPdfToMarkdown(MultipartFile inputFile)
|
||||
throws IOException, InterruptedException {
|
||||
if (!"application/pdf".equals(inputFile.getContentType())) {
|
||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
MutableDataSet options =
|
||||
new MutableDataSet()
|
||||
.set(
|
||||
FlexmarkHtmlConverter.MAX_BLANK_LINES,
|
||||
2) // Control max consecutive blank lines
|
||||
.set(
|
||||
FlexmarkHtmlConverter.MAX_TRAILING_BLANK_LINES,
|
||||
1) // Control trailing blank lines
|
||||
.set(
|
||||
FlexmarkHtmlConverter.SETEXT_HEADINGS,
|
||||
true) // Use Setext headings for h1 and h2
|
||||
.set(
|
||||
FlexmarkHtmlConverter.OUTPUT_UNKNOWN_TAGS,
|
||||
false) // Don't output HTML for unknown tags
|
||||
.set(
|
||||
FlexmarkHtmlConverter.TYPOGRAPHIC_QUOTES,
|
||||
true) // Convert quotation marks
|
||||
.set(
|
||||
FlexmarkHtmlConverter.BR_AS_PARA_BREAKS,
|
||||
true) // Convert <br> to paragraph breaks
|
||||
.set(FlexmarkHtmlConverter.CODE_INDENT, " "); // Indent for code blocks
|
||||
|
||||
FlexmarkHtmlConverter htmlToMarkdownConverter =
|
||||
FlexmarkHtmlConverter.builder(options).build();
|
||||
|
||||
String originalPdfFileName = Filenames.toSimpleFileName(inputFile.getOriginalFilename());
|
||||
String pdfBaseName = originalPdfFileName;
|
||||
if (originalPdfFileName.contains(".")) {
|
||||
pdfBaseName = originalPdfFileName.substring(0, originalPdfFileName.lastIndexOf('.'));
|
||||
}
|
||||
|
||||
Path tempInputFile = null;
|
||||
Path tempOutputDir = null;
|
||||
byte[] fileBytes;
|
||||
String fileName = "temp.file";
|
||||
|
||||
try {
|
||||
tempInputFile = Files.createTempFile("input_", ".pdf");
|
||||
inputFile.transferTo(tempInputFile);
|
||||
tempOutputDir = Files.createTempDirectory("output_");
|
||||
|
||||
List<String> command =
|
||||
new ArrayList<>(
|
||||
Arrays.asList(
|
||||
"pdftohtml",
|
||||
"-s",
|
||||
"-noframes",
|
||||
"-c",
|
||||
tempInputFile.toString(),
|
||||
pdfBaseName));
|
||||
|
||||
ProcessExecutorResult returnCode =
|
||||
ProcessExecutor.getInstance(ProcessExecutor.Processes.PDFTOHTML)
|
||||
.runCommandWithOutputHandling(command, tempOutputDir.toFile());
|
||||
// Process HTML files to Markdown
|
||||
File[] outputFiles = Objects.requireNonNull(tempOutputDir.toFile().listFiles());
|
||||
List<File> markdownFiles = new ArrayList<>();
|
||||
|
||||
// Convert HTML files to Markdown
|
||||
for (File outputFile : outputFiles) {
|
||||
if (outputFile.getName().endsWith(".html")) {
|
||||
String html = Files.readString(outputFile.toPath());
|
||||
String markdown = htmlToMarkdownConverter.convert(html);
|
||||
|
||||
String mdFileName = outputFile.getName().replace(".html", ".md");
|
||||
File mdFile = new File(tempOutputDir.toFile(), mdFileName);
|
||||
Files.writeString(mdFile.toPath(), markdown);
|
||||
markdownFiles.add(mdFile);
|
||||
}
|
||||
}
|
||||
|
||||
// If there's only one markdown file, return it directly
|
||||
if (markdownFiles.size() == 1) {
|
||||
fileName = pdfBaseName + ".md";
|
||||
fileBytes = Files.readAllBytes(markdownFiles.get(0).toPath());
|
||||
} else {
|
||||
// Multiple files - create a zip
|
||||
fileName = pdfBaseName + "ToMarkdown.zip";
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
|
||||
try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) {
|
||||
// Add markdown files
|
||||
for (File mdFile : markdownFiles) {
|
||||
ZipEntry mdEntry = new ZipEntry(mdFile.getName());
|
||||
zipOutputStream.putNextEntry(mdEntry);
|
||||
Files.copy(mdFile.toPath(), zipOutputStream);
|
||||
zipOutputStream.closeEntry();
|
||||
}
|
||||
|
||||
// Add images and other assets
|
||||
for (File file : outputFiles) {
|
||||
if (!file.getName().endsWith(".html") && !file.getName().endsWith(".md")) {
|
||||
ZipEntry assetEntry = new ZipEntry(file.getName());
|
||||
zipOutputStream.putNextEntry(assetEntry);
|
||||
Files.copy(file.toPath(), zipOutputStream);
|
||||
zipOutputStream.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileBytes = byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (tempInputFile != null) Files.deleteIfExists(tempInputFile);
|
||||
if (tempOutputDir != null) FileUtils.deleteDirectory(tempOutputDir.toFile());
|
||||
}
|
||||
return WebResponseUtils.bytesToWebResponse(
|
||||
fileBytes, fileName, MediaType.APPLICATION_OCTET_STREAM);
|
||||
}
|
||||
|
||||
public ResponseEntity<byte[]> processPdfToHtml(MultipartFile inputFile)
|
||||
throws IOException, InterruptedException {
|
||||
if (!"application/pdf".equals(inputFile.getContentType())) {
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown إلى PDF
|
||||
home.MarkdownToPDF.desc=يحول أي ملف Markdown إلى PDF
|
||||
MarkdownToPDF.tags=لغة الترميز,محتوى الويب,تحويل,تحويل
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=الحصول على جميع المعلومات عن PDF
|
||||
home.getPdfInfo.desc=يجمع أي وكل المعلومات الممكنة عن ملفات PDF
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=العمل قيد التقدم
|
||||
MarkdownToPDF.credit=يستخدم WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL إلى PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=تحويل إلى PDF
|
||||
compress.title=ضغط
|
||||
compress.header=ضغط ملف PDF
|
||||
compress.credit=تستخدم هذه الخدمة qpdf لضغط / تحسين PDF.
|
||||
compress.selectText.1=الوضع اليدوي - من 1 إلى 4
|
||||
compress.selectText.1=الوضع اليدوي - من 1 إلى 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=مستوى التحسين:
|
||||
compress.selectText.3=4 (رهيب للصور النصية)
|
||||
compress.selectText.4=الوضع التلقائي - يضبط الجودة تلقائيًا للحصول على ملف PDF بالحجم المحدد
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown-dan PDF-ə
|
||||
home.MarkdownToPDF.desc=Hər hansı Markdown faylını PDF-ə çevirir
|
||||
MarkdownToPDF.tags=işarələmə,web-məzmun,dəyişmə,çevirmə
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=PDF-in Bütün Məlumatları
|
||||
home.getPdfInfo.desc=PDF barədə mümkün olan bütün məlumatları əldə edir
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=İş davam edir
|
||||
MarkdownToPDF.credit=WeasyPrint İstifadə Edir
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL-i PDF-ə
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=PDF-ə Çevir
|
||||
compress.title=Sıxışdır
|
||||
compress.header=PDF-i Sıxışdır
|
||||
compress.credit=Bu servis PDF sıxışdırılması/Optimizasiyası üçün Ghostscript istifadə edir.
|
||||
compress.selectText.1=Manual Mod - 1-dən 4-ə
|
||||
compress.selectText.1=Manual Mod - 1-dən 5-ə
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimizasiya səviyyəsi:
|
||||
compress.selectText.3=4 (Mətn şəkilləri üçün yaxşı deyil)
|
||||
compress.selectText.4=Avto mod - PDF-in dəqiq ölçüsünü əldə etmək üçün keyfiyyəti avtomatik tənzimləyir
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown към PDF
|
||||
home.MarkdownToPDF.desc=Преобразува всеки Markdown файл към PDF
|
||||
MarkdownToPDF.tags=маркиране,уеб-съдържание,трансформация,преобразуване
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Вземете ЦЯЛАТА информация от PDF
|
||||
home.getPdfInfo.desc=Взима всяка възможна информация от PDF файлове
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Работата е в ход
|
||||
MarkdownToPDF.credit=Използва WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL към PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Преобразуване към PDF
|
||||
compress.title=Компресиране
|
||||
compress.header=Компресиране на PDF
|
||||
compress.credit=Тази услуга използва qpdf за PDF компресиране/оптимизиране.
|
||||
compress.selectText.1=Ръчен режим - от 1 до 4
|
||||
compress.selectText.1=Ръчен режим - от 1 до 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Ниво на оптимизация:
|
||||
compress.selectText.3=4 (Ужасно за текстови изображения)
|
||||
compress.selectText.4=Автоматичен режим - Автоматично настройва качеството, за да получи PDF с точен размер
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown a PDF
|
||||
home.MarkdownToPDF.desc=Converteix qualsevol fitxer Markdown a PDF
|
||||
MarkdownToPDF.tags=markup,web-content,transformation,convert
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Obteniu Tota la Informació sobre el PDF
|
||||
home.getPdfInfo.desc=Recupera tota la informació possible sobre els PDFs
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Work in progress
|
||||
MarkdownToPDF.credit=Uses WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL a PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Converteix a PDF
|
||||
compress.title=Comprimir
|
||||
compress.header=Comprimir PDF
|
||||
compress.credit=Aquest servei utilitza qpdf per a la compressió/optimització de PDF.
|
||||
compress.selectText.1=Mode manual: de l'1 al 4
|
||||
compress.selectText.1=Mode manual: de l'1 al 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Nivell d'optimització:
|
||||
compress.selectText.3=4 (terrible per a imatges de text)
|
||||
compress.selectText.4=Mode automàtic: ajusta automàticament la qualitat perquè el PDF tingui la mida exacta
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown til PDF
|
||||
home.MarkdownToPDF.desc=Konverterer enhver Markdown-fil til PDF
|
||||
MarkdownToPDF.tags=markup,webindhold,transformation,konvertér
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Få ALLE Oplysninger om PDF
|
||||
home.getPdfInfo.desc=Henter alle mulige oplysninger om PDF'er
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Arbejde i gang
|
||||
MarkdownToPDF.credit=Bruger WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL Til PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Konvertér til PDF
|
||||
compress.title=Komprimer
|
||||
compress.header=Komprimer PDF
|
||||
compress.credit=Denne tjeneste bruger qpdf til PDF Komprimering/Optimering.
|
||||
compress.selectText.1=Manuel Tilstand - Fra 1 til 4
|
||||
compress.selectText.1=Manuel Tilstand - Fra 1 til 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimeringsniveau:
|
||||
compress.selectText.3=4 (Forfærdelig for tekstbilleder)
|
||||
compress.selectText.4=Auto tilstand - Justerer automatisk kvaliteten for at få PDF'en til en præcis størrelse
|
||||
|
||||
@@ -82,7 +82,7 @@ pages=Seiten
|
||||
loading=Laden...
|
||||
addToDoc=In Dokument hinzufügen
|
||||
reset=Zurücksetzen
|
||||
apply=Apply
|
||||
apply=Anwenden
|
||||
|
||||
legal.privacy=Datenschutz
|
||||
legal.terms=AGB
|
||||
@@ -249,7 +249,7 @@ database.backupCreated=Datenbanksicherung erfolgreich
|
||||
database.fileNotFound=Datei nicht gefunden
|
||||
database.fileNullOrEmpty=Datei darf nicht null oder leer sein
|
||||
database.failedImportFile=Dateiimport fehlgeschlagen
|
||||
database.notSupported=This function is not available for your database connection.
|
||||
database.notSupported=Diese Funktion ist für deine Datenbankverbindung nicht verfügbar.
|
||||
|
||||
session.expired=Ihre Sitzung ist abgelaufen. Bitte laden Sie die Seite neu und versuchen Sie es erneut.
|
||||
session.refreshPage=Seite aktualisieren
|
||||
@@ -271,7 +271,7 @@ multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
|
||||
|
||||
home.merge.title=Zusammenführen
|
||||
home.merge.desc=Mehrere PDF-Dateien zu einer einzigen zusammenführen
|
||||
merge.tags=zusammenführen,seitenvorgänge,back end,serverseite
|
||||
merge.tags=zusammenführen,seitenvorgänge,back end,serverseitig
|
||||
|
||||
home.split.title=Aufteilen
|
||||
home.split.desc=PDFs in mehrere Dokumente aufteilen
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown zu PDF
|
||||
home.MarkdownToPDF.desc=Konvertiert jede Markdown-Datei zu PDF
|
||||
MarkdownToPDF.tags=markup,web-content,transformation,konvertieren
|
||||
|
||||
home.PDFToMarkdown.title=PDF zu Markdown
|
||||
home.PDFToMarkdown.desc=Konvertiert jedes PDF in Markdown
|
||||
PDFToMarkdown.tags=markup,web inhalt,transformation,konvertieren,md
|
||||
|
||||
home.getPdfInfo.title=Alle Informationen anzeigen
|
||||
home.getPdfInfo.desc=Erfasst alle möglichen Informationen in einer PDF
|
||||
@@ -476,9 +479,9 @@ home.autoRedact.title=Automatisch zensieren/schwärzen
|
||||
home.autoRedact.desc=Automatisches Zensieren (Schwärzen) von Text in einer PDF-Datei basierend auf dem eingegebenen Text
|
||||
autoRedact.tags=zensieren,schwärzen
|
||||
|
||||
home.redact.title=Manual Redaction
|
||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
||||
home.redact.title=Manuell zensieren/schwärzen
|
||||
home.redact.desc=Zensiere (Schwärze) eine PDF-Datei durch Auswählen von Text, gezeichneten Formen und/oder ausgewählten Seite(n)
|
||||
redact.tags=zensieren,schwärzen,verstecken,verdunkeln,schwarz,markieren,verbergen,manuell
|
||||
|
||||
home.tableExtraxt.title=Tabelle extrahieren
|
||||
home.tableExtraxt.desc=Tabelle aus PDF in CSV extrahieren
|
||||
@@ -586,30 +589,30 @@ autoRedact.convertPDFToImageLabel=PDF in PDF-Bild konvertieren (zum Entfernen vo
|
||||
autoRedact.submitButton=Zensieren
|
||||
|
||||
#redact
|
||||
redact.title=Manual Redaction
|
||||
redact.header=Manual Redaction
|
||||
redact.submit=Redact
|
||||
redact.textBasedRedaction=Text based Redaction
|
||||
redact.pageBasedRedaction=Page-based Redaction
|
||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
||||
redact.pageRedactionNumbers.title=Pages
|
||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
||||
redact.redactionColor.title=Redaction Color
|
||||
redact.export=Export
|
||||
redact.upload=Upload
|
||||
redact.boxRedaction=Box draw redaction
|
||||
redact.title=Manuelles Zensieren (Schwärzen)
|
||||
redact.header=Manuelles Zensieren (Schwärzen)
|
||||
redact.submit=Zensieren
|
||||
redact.textBasedRedaction=Textbasiertes Zensieren
|
||||
redact.pageBasedRedaction=Seitenweises Zensieren
|
||||
redact.convertPDFToImageLabel=Konvertiere PDF zu einem Bild (Zum Entfernen von Text hinter der Box verwenden)
|
||||
redact.pageRedactionNumbers.title=Seiten
|
||||
redact.pageRedactionNumbers.placeholder=(z.B. 1,2,8 oder 4,7,12-16 oder 2n-1)
|
||||
redact.redactionColor.title=Zensurfarbe
|
||||
redact.export=Exportieren
|
||||
redact.upload=Hochladen
|
||||
redact.boxRedaction=Rechteck zeichnen zum zensieren
|
||||
redact.zoom=Zoom
|
||||
redact.zoomIn=Zoom in
|
||||
redact.zoomOut=Zoom out
|
||||
redact.nextPage=Next Page
|
||||
redact.previousPage=Previous Page
|
||||
redact.toggleSidebar=Toggle Sidebar
|
||||
redact.showThumbnails=Show Thumbnails
|
||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
||||
redact.showAttatchments=Show Attachments
|
||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||
redact.colourPicker=Colour Picker
|
||||
redact.findCurrentOutlineItem=Find current outline item
|
||||
redact.zoomIn=Vergrößern
|
||||
redact.zoomOut=Verkleinern
|
||||
redact.nextPage=Nächste Seite
|
||||
redact.previousPage=Vorherige Seite
|
||||
redact.toggleSidebar=Seitenleiste umschalten
|
||||
redact.showThumbnails=Vorschau anzeigen
|
||||
redact.showDocumentOutline=Dokumentübersicht anzeigen (Doppelklick zum Auf/Einklappen aller Elemente)
|
||||
redact.showAttatchments=Zeige Anhänge
|
||||
redact.showLayers=Ebenen anzeigen (Doppelklick, um alle Ebenen auf den Standardzustand zurückzusetzen)
|
||||
redact.colourPicker=Farbauswahl
|
||||
redact.findCurrentOutlineItem=Aktuell gewähltes Element finden
|
||||
|
||||
#showJS
|
||||
showJS.title=Javascript anzeigen
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=In Arbeit
|
||||
MarkdownToPDF.credit=Verwendet WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF zu Markdown
|
||||
PDFToMarkdown.header=PDF zu Markdown
|
||||
PDFToMarkdown.submit=Konvertieren
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL zu PDF
|
||||
@@ -862,7 +870,7 @@ sign.first=Erste Seite
|
||||
sign.last=Letzte Seite
|
||||
sign.next=Nächste Seite
|
||||
sign.previous=Vorherige Seite
|
||||
sign.maintainRatio=Toggle maintain aspect ratio
|
||||
sign.maintainRatio=Seitenverhältnis beibehalten ein-/ausschalten
|
||||
|
||||
|
||||
#repair
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=In PDF konvertieren
|
||||
compress.title=Komprimieren
|
||||
compress.header=PDF komprimieren
|
||||
compress.credit=Dieser Dienst verwendet qpdf für die PDF-Komprimierung/-Optimierung.
|
||||
compress.selectText.1=Manueller Modus – Von 1 bis 4
|
||||
compress.selectText.1=Manueller Modus – Von 1 bis 5
|
||||
compress.selectText.1.1=In den Optimierungsstufen 6 bis 9 wird zusätzlich zur allgemeinen PDF-Komprimierung die Bildauflösung reduziert, um die Dateigröße weiter zu verringern. Höhere Stufen führen zu einer stärkeren Bildkomprimierung (bis zu 50 % der Originalgröße), wodurch eine stärkere Größenreduzierung erreicht wird, die jedoch mit einem möglichen Qualitätsverlust der Bilder einhergeht.
|
||||
compress.selectText.2=Optimierungsstufe:
|
||||
compress.selectText.3=4 (Schrecklich für Textbilder)
|
||||
compress.selectText.4=Automatischer Modus – Passt die Qualität automatisch an, um das PDF auf die exakte Größe zu bringen
|
||||
@@ -1319,8 +1328,8 @@ splitByChapters.submit=PDF teilen
|
||||
fileChooser.click=Klicken
|
||||
fileChooser.or=oder
|
||||
fileChooser.dragAndDrop=Drag & Drop
|
||||
fileChooser.dragAndDropPDF=Drag & Drop PDF file
|
||||
fileChooser.dragAndDropImage=Drag & Drop Image file
|
||||
fileChooser.dragAndDropPDF=Drag & Drop PDF-Datei
|
||||
fileChooser.dragAndDropImage=Drag & Drop Bilddatei
|
||||
fileChooser.hoveredDragAndDrop=Datei(en) hierhin Ziehen & Fallenlassen
|
||||
|
||||
#release notes
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -450,8 +450,11 @@ HTMLToPDF.tags=markup,web-content,transformation,convert
|
||||
|
||||
home.MarkdownToPDF.title=Markdown to PDF
|
||||
home.MarkdownToPDF.desc=Converts any Markdown file to PDF
|
||||
MarkdownToPDF.tags=markup,web-content,transformation,convert
|
||||
MarkdownToPDF.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Get ALL Info on PDF
|
||||
home.getPdfInfo.desc=Grabs any and all information possible on PDFs
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Work in progress
|
||||
MarkdownToPDF.credit=Uses WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL To PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Convert to PDF
|
||||
compress.title=Compress
|
||||
compress.header=Compress PDF
|
||||
compress.credit=This service uses qpdf for PDF Compress/Optimisation.
|
||||
compress.selectText.1=Manual Mode - From 1 to 4
|
||||
compress.selectText.1=Manual Mode - From 1 to 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimisation level:
|
||||
compress.selectText.3=4 (Terrible for text images)
|
||||
compress.selectText.4=Auto mode - Auto adjusts quality to get PDF to exact size
|
||||
|
||||
@@ -450,8 +450,11 @@ HTMLToPDF.tags=markup,web-content,transformation,convert
|
||||
|
||||
home.MarkdownToPDF.title=Markdown to PDF
|
||||
home.MarkdownToPDF.desc=Converts any Markdown file to PDF
|
||||
MarkdownToPDF.tags=markup,web-content,transformation,convert
|
||||
MarkdownToPDF.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Get ALL Info on PDF
|
||||
home.getPdfInfo.desc=Grabs any and all information possible on PDFs
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Work in progress
|
||||
MarkdownToPDF.credit=Uses WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL To PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Convert to PDF
|
||||
compress.title=Compress
|
||||
compress.header=Compress PDF
|
||||
compress.credit=This service uses qpdf for PDF Compress/Optimisation.
|
||||
compress.selectText.1=Manual Mode - From 1 to 4
|
||||
compress.selectText.1=Manual Mode - From 1 to 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimization level:
|
||||
compress.selectText.3=4 (Terrible for text images)
|
||||
compress.selectText.4=Auto mode - Auto adjusts quality to get PDF to exact size
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown a PDF
|
||||
home.MarkdownToPDF.desc=Convierte cualquier archivo Markdown a PDF
|
||||
MarkdownToPDF.tags=margen,contenido web,transformación,convertir
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Obtener toda la información en PDF
|
||||
home.getPdfInfo.desc=Obtiene toda la información posible de archivos PDF
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Tarea en proceso
|
||||
MarkdownToPDF.credit=Usa WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL a PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Convertir a PDF
|
||||
compress.title=Comprimir
|
||||
compress.header=Comprimir PDF
|
||||
compress.credit=Este servicio utiliza qpdf para compresión/optimización de PDF
|
||||
compress.selectText.1=Modo manual - De 1 a 4
|
||||
compress.selectText.1=Modo manual - De 1 a 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Nivel de optimización:
|
||||
compress.selectText.3=4 (Terrible para imágenes de texto)
|
||||
compress.selectText.4=Modo automático: ajusta automáticamente la calidad para que el PDF tenga el tamaño exacto
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown PDF-ra
|
||||
home.MarkdownToPDF.desc=Bihurtu Markdown fitxategi guztiak PDF
|
||||
MarkdownToPDF.tags=markup,web-content,transformation,convert
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Lortu informazio guztia PDF-tik
|
||||
home.getPdfInfo.desc=Eskuratu PDF fitxategiko Informazio guztia
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Lanean
|
||||
MarkdownToPDF.credit=WeasyPrint darabil
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL bat PDF-ra
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=PDF bihurtu
|
||||
compress.title=Konprimatu
|
||||
compress.header=PDFa konprimatu
|
||||
compress.credit=Zerbitzu honek qpdf erabiltzen du PDFak komprimatzeko/optimizatzeko
|
||||
compress.selectText.1=Eskuz 1etik 4ra
|
||||
compress.selectText.1=Eskuz 1etik 5ra
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimizazio maila:
|
||||
compress.selectText.3=4 (Izugarria testu-irudietarako)
|
||||
compress.selectText.4=Automatikoa: automatikoki egokitzen du kalitatea PDFak tamaina doi-doia izan dezan
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=مارکداون به PDF
|
||||
home.MarkdownToPDF.desc=تبدیل هر فایل مارکداون به PDF
|
||||
MarkdownToPDF.tags=مارکآپ،محتوای وب،تبدیل،تغییر
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=دریافت تمام اطلاعات در مورد PDF
|
||||
home.getPdfInfo.desc=گرفتن هر اطلاعات ممکن در مورد PDF
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=در حال پیشرفت
|
||||
MarkdownToPDF.credit=از WeasyPrint استفاده میکند
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL به PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=تبدیل به PDF
|
||||
compress.title=فشردهسازی
|
||||
compress.header=فشردهسازی PDF
|
||||
compress.credit=این سرویس از qpdf برای فشردهسازی / بهینهسازی PDF استفاده میکند.
|
||||
compress.selectText.1=حالت دستی - از ۱ تا ۴
|
||||
compress.selectText.1=حالت دستی - از 1 تا 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=سطح بهینهسازی:
|
||||
compress.selectText.3=۴ (خیلی بد برای تصاویر متنی)
|
||||
compress.selectText.4=حالت خودکار - کیفیت را به طور خودکار تنظیم میکند تا PDF به اندازه دقیق برسد
|
||||
|
||||
@@ -82,7 +82,7 @@ pages=Pages
|
||||
loading=Chargement...
|
||||
addToDoc=Ajouter au Document
|
||||
reset=Réinitialiser
|
||||
apply=Apply
|
||||
apply=Appliquer
|
||||
|
||||
legal.privacy=Politique de Confidentialité
|
||||
legal.terms=Conditions Générales
|
||||
@@ -239,20 +239,20 @@ database.creationDate=Date de Création
|
||||
database.fileSize=Taille du Fichier
|
||||
database.deleteBackupFile=Supprimer le fichier de sauvegarde
|
||||
database.importBackupFile=Importer le fichier de sauvegarde
|
||||
database.createBackupFile=Create Backup File
|
||||
database.createBackupFile=Créer un fichier de sauvegarde
|
||||
database.downloadBackupFile=Télécharger le fichier de sauvegarde
|
||||
database.info_1=Lors de l'importation des données, il est crucial de garantir la structure correcte. Si vous n'êtes pas sûr de ce que vous faites, sollicitez un avis et un soutien d'un professionnel. Une erreur dans la structure peut entraîner des dysfonctionnements de l'application, allant jusqu'à l'incapacité totale d'exécuter l'application.
|
||||
database.info_2=Le nom du fichier ne fait pas de différence lors de l'upload. Il sera renommé ultérieurement selon le format backup_user_yyyyMMddHHmm.sql, assurant ainsi une convention de nommage cohérente.
|
||||
database.submit=Importer la sauvegarde
|
||||
database.importIntoDatabaseSuccessed=Importation dans la base de données réussie
|
||||
database.backupCreated=Database backup successful
|
||||
database.fileNotFound=File not Found
|
||||
database.backupCreated=Sauvegarde de la base de donnée réussie
|
||||
database.fileNotFound=Fichier introuvable
|
||||
database.fileNullOrEmpty=Fichier ne peut pas être null ou vide
|
||||
database.failedImportFile=Failed Import File
|
||||
database.notSupported=This function is not available for your database connection.
|
||||
database.failedImportFile=Échec de l'imporation du fichier
|
||||
database.notSupported=Cette fonctionnalité n'est pas supportée avec votre base de donnée
|
||||
|
||||
session.expired=Votre session a expiré. Veuillez recharger la page et réessayer.
|
||||
session.refreshPage=Refresh Page
|
||||
session.refreshPage=Rafraichir la page
|
||||
|
||||
#############
|
||||
# HOME-PAGE #
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown en PDF
|
||||
home.MarkdownToPDF.desc=Convertissez n'importe quel fichier Markdown en PDF.
|
||||
MarkdownToPDF.tags=markdown,markup,contenu Web,transformation,convert
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Récupérer les informations
|
||||
home.getPdfInfo.desc=Récupérez toutes les informations possibles sur un PDF.
|
||||
@@ -476,8 +479,8 @@ home.autoRedact.title=Caviarder automatiquement
|
||||
home.autoRedact.desc=Caviardez automatiquement les informations sensibles d'un PDF.
|
||||
autoRedact.tags=caviarder,redact,auto
|
||||
|
||||
home.redact.title=Manual Redaction
|
||||
home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s)
|
||||
home.redact.title=Rédaction manuelle
|
||||
home.redact.desc=Rédiger un PDF en fonction de texte sélectionné, formes dessinées et/ou des pages sélectionnées.
|
||||
redact.tags=Redact,Hide,black out,black,marker,hidden,manual
|
||||
|
||||
home.tableExtraxt.title=PDF en CSV
|
||||
@@ -586,30 +589,30 @@ autoRedact.convertPDFToImageLabel=Convertir un PDF en PDF-Image (utilisé pour s
|
||||
autoRedact.submitButton=Caviarder
|
||||
|
||||
#redact
|
||||
redact.title=Manual Redaction
|
||||
redact.header=Manual Redaction
|
||||
redact.submit=Redact
|
||||
redact.textBasedRedaction=Text based Redaction
|
||||
redact.pageBasedRedaction=Page-based Redaction
|
||||
redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box)
|
||||
redact.title=Rédaction manuelle
|
||||
redact.header=Rédaction manuelle
|
||||
redact.submit=Rédiger
|
||||
redact.textBasedRedaction=Rédaction en fonction de texte
|
||||
redact.pageBasedRedaction=Rédaction en fonction de pages
|
||||
redact.convertPDFToImageLabel=Convertir en PDF-Image (pour supprimer le texte derrière le rectangle)
|
||||
redact.pageRedactionNumbers.title=Pages
|
||||
redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
|
||||
redact.redactionColor.title=Redaction Color
|
||||
redact.export=Export
|
||||
redact.upload=Upload
|
||||
redact.boxRedaction=Box draw redaction
|
||||
redact.pageRedactionNumbers.placeholder=(ex: 1,2,8 ou 4,7,12-16 ou 2n-1)
|
||||
redact.redactionColor.title=Couleur
|
||||
redact.export=Exporter
|
||||
redact.upload=Téléverser
|
||||
redact.boxRedaction=Dessiner le rectangle à rédiger
|
||||
redact.zoom=Zoom
|
||||
redact.zoomIn=Zoom in
|
||||
redact.zoomOut=Zoom out
|
||||
redact.nextPage=Next Page
|
||||
redact.previousPage=Previous Page
|
||||
redact.zoomIn=Zoom avant
|
||||
redact.zoomOut=Zoom arrière
|
||||
redact.nextPage=Page suivante
|
||||
redact.previousPage=Page précédente
|
||||
redact.toggleSidebar=Toggle Sidebar
|
||||
redact.showThumbnails=Show Thumbnails
|
||||
redact.showDocumentOutline=Show Document Outline (double-click to expand/collapse all items)
|
||||
redact.showAttatchments=Show Attachments
|
||||
redact.showLayers=Show Layers (double-click to reset all layers to the default state)
|
||||
redact.colourPicker=Colour Picker
|
||||
redact.findCurrentOutlineItem=Find current outline item
|
||||
redact.showThumbnails=Afficher les miniatures
|
||||
redact.showDocumentOutline=Montrer les contours du document (double-click pour agrandir/réduire tous les éléments)
|
||||
redact.showAttatchments=Montrer les éléments attachés
|
||||
redact.showLayers=Montrer les calques (double-click pour réinitialiser tous les calques à l'état par défaut)
|
||||
redact.colourPicker=Sélection de couleur
|
||||
redact.findCurrentOutlineItem=Trouver l'élément de contour courrant
|
||||
|
||||
#showJS
|
||||
showJS.title=Afficher le JavaScript
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=(Travail en cours).
|
||||
MarkdownToPDF.credit=Utilise WeasyPrint.
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL en PDF
|
||||
@@ -856,13 +864,13 @@ sign.save=Enregistrer le sceau
|
||||
sign.personalSigs=Sceaux personnels
|
||||
sign.sharedSigs=Sceaux partagés
|
||||
sign.noSavedSigs=Aucun sceau enregistré trouvé
|
||||
sign.addToAll=Add to all pages
|
||||
sign.delete=Delete
|
||||
sign.first=First page
|
||||
sign.last=Last page
|
||||
sign.next=Next page
|
||||
sign.previous=Previous page
|
||||
sign.maintainRatio=Toggle maintain aspect ratio
|
||||
sign.addToAll=Ajouter à toutes les pages
|
||||
sign.delete=Supprimer
|
||||
sign.first=Première page
|
||||
sign.last=Dernière page
|
||||
sign.next=Page suivante
|
||||
sign.previous=Page précédente
|
||||
sign.maintainRatio=Conserver les proportions
|
||||
|
||||
|
||||
#repair
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Convertir
|
||||
compress.title=Compresser un PDF
|
||||
compress.header=Compresser un PDF (lorsque c'est possible!)
|
||||
compress.credit=Ce service utilise qpdf pour la compression et l'optimisation des PDF.
|
||||
compress.selectText.1=Mode manuel – de 1 à 4
|
||||
compress.selectText.1=Mode manuel – de 1 à 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Niveau d'optimisation
|
||||
compress.selectText.3=4 (terrible pour les images textuelles)
|
||||
compress.selectText.4=Mode automatique – ajuste automatiquement la qualité pour obtenir le PDF à la taille exacte
|
||||
@@ -1002,14 +1011,14 @@ multiTool.undo=Undo
|
||||
multiTool.redo=Redo
|
||||
|
||||
#decrypt
|
||||
decrypt.passwordPrompt=This file is password-protected. Please enter the password:
|
||||
decrypt.cancelled=Operation cancelled for PDF: {0}
|
||||
decrypt.noPassword=No password provided for encrypted PDF: {0}
|
||||
decrypt.invalidPassword=Please try again with the correct password.
|
||||
decrypt.invalidPasswordHeader=Incorrect password or unsupported encryption for PDF: {0}
|
||||
decrypt.unexpectedError=There was an error processing the file. Please try again.
|
||||
decrypt.serverError=Server error while decrypting: {0}
|
||||
decrypt.success=File decrypted successfully.
|
||||
decrypt.passwordPrompt=Ce fichier est protégé par un mot de passe. Veuillez saisir le mot de passe :
|
||||
decrypt.cancelled=Operation annulée pour le PDF: {0}
|
||||
decrypt.noPassword=Pas de mot de passe fourni pour le PDF chiffré : {0}
|
||||
decrypt.invalidPassword=Veuillez réessayer avec le bon mot de passe
|
||||
decrypt.invalidPasswordHeader=Mauvais mot de passe ou chiffrement non supporté pour le PDF : {0}
|
||||
decrypt.unexpectedError=Une erreur est survenue lors de traitement du fichier. Veuillez essayer de nouveau.
|
||||
decrypt.serverError=Erreur du serveur lors du déchiffrement : {0}
|
||||
decrypt.success=Fichier déchiffré avec succès.
|
||||
|
||||
#multiTool-advert
|
||||
multiTool-advert.message=Cette fonctionnalité est aussi disponible dans la <a href="{0}">page de l'outil multifonction</a>. Allez-y pour une interface page par page améliorée et des fonctionnalités additionnelles !
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Marcáil síos go PDF
|
||||
home.MarkdownToPDF.desc=Tiontaíonn aon chomhad Markdown go PDF
|
||||
MarkdownToPDF.tags=marcáil, ábhar gréasáin, claochlú, tiontú
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Faigh GACH Eolas ar PDF
|
||||
home.getPdfInfo.desc=Grab aon fhaisnéis agus is féidir ar PDFs
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Obair idir lámha
|
||||
MarkdownToPDF.credit=Úsáideann WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL go PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Tiontaigh go PDF
|
||||
compress.title=Comhbhrúigh
|
||||
compress.header=Comhbhrúigh PDF
|
||||
compress.credit=Úsáideann an tseirbhís seo qpdf le haghaidh Comhbhrú/Optimization PDF.
|
||||
compress.selectText.1=Mód Láimhe - Ó 1 go 4
|
||||
compress.selectText.1=Mód Láimhe - Ó 1 go 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Leibhéal optamaithe:
|
||||
compress.selectText.3=4 (Uafásach le haghaidh íomhánna téacs)
|
||||
compress.selectText.4=Mód uathoibríoch - Coigeartaíonn Auto cáilíocht chun PDF a fháil go dtí an méid cruinn
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown u PDF
|
||||
home.MarkdownToPDF.desc=Pretvara bilo koju Markdown datoteku u PDF
|
||||
MarkdownToPDF.tags=oznake,web-sadržaj,transformacija,konvertiranje
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Dohvati SVE informacije o PDF-u
|
||||
home.getPdfInfo.desc=Dohvaća sve moguće informacije o PDF-ovima
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Rad u toku
|
||||
MarkdownToPDF.credit=Koristi WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL u PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Pretvori u PDF
|
||||
compress.title=Komprimirajte
|
||||
compress.header=Komprimirajte PDF
|
||||
compress.credit=Ova usluga koristi qpdf za komprimiranje / optimizaciju PDF-a.
|
||||
compress.selectText.1=Ručni režim - Od 1 do 4
|
||||
compress.selectText.1=Ručni režim - Od 1 do 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Nivo optimizacije:
|
||||
compress.selectText.3=4 (Užasno za tekstualne slike)
|
||||
compress.selectText.4=Automatski način - Automatski prilagođava kvalitetu kako bi PDF dobio točnu veličinu
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown konvertálása PDF-be
|
||||
home.MarkdownToPDF.desc=Markdown fájl konvertálása PDF-be
|
||||
MarkdownToPDF.tags=jelölőnyelv,webtartalom,átalakítás,konvertálás
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=PDF összes információjának lekérése
|
||||
home.getPdfInfo.desc=Minden elérhető információ lekérése PDF-ekről
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Fejlesztés alatt
|
||||
MarkdownToPDF.credit=WeasyPrint használatával
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL konvertálása PDF-be
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Konvertálás PDF-be
|
||||
compress.title=Tömörítés
|
||||
compress.header=PDF tömörítése
|
||||
compress.credit=Ez a szolgáltatás a qpdf használatával végzi a PDF tömörítését/optimalizálását.
|
||||
compress.selectText.1=Kézi mód - 1-től 4-ig
|
||||
compress.selectText.1=Kézi mód - 1-től 5-ig
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimalizálási szint:
|
||||
compress.selectText.3=4 (Szöveges képeknél nem ajánlott)
|
||||
compress.selectText.4=Automatikus mód - Automatikusan állítja a minőséget a megadott PDF méret eléréséhez
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Penurunan harga ke PDF
|
||||
home.MarkdownToPDF.desc=Mengonversi berkas Markdown apa pun ke PDF
|
||||
MarkdownToPDF.tags=markup, konten web, transformasi, konversi
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Dapatkan Semua Info tentang PDF
|
||||
home.getPdfInfo.desc=Mengambil setiap dan semua informasi yang mungkin ada pada PDF
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Pekerjaan sedang berlangsung
|
||||
MarkdownToPDF.credit=Menggunakan WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL ke PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Konversi ke PDF
|
||||
compress.title=Kompres
|
||||
compress.header=Kompres PDF
|
||||
compress.credit=Layanan ini menggunakan qpdf untuk Kompresi/Optimalisasi PDF.
|
||||
compress.selectText.1=Mode Manual - Dari 1 hingga 4
|
||||
compress.selectText.1=Mode Manual - Dari 1 hingga 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Tingkat Optimalisasi:
|
||||
compress.selectText.3=4 (Buruk untuk gambar teks)
|
||||
compress.selectText.4=Mode Otomatis - Menyesuaikan kualitas secara otomatis untuk mendapatkan PDF dengan ukuran yang tepat
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown in PDF
|
||||
home.MarkdownToPDF.desc=Converte qualsiasi file Markdown in PDF
|
||||
MarkdownToPDF.tags=markup,contenuto web,trasformazione,conversione
|
||||
|
||||
home.PDFToMarkdown.title=PDF in Markdown
|
||||
home.PDFToMarkdown.desc=Converte qualsiasi PDF in Markdown
|
||||
PDFToMarkdown.tags=markup,contenuto-web,trasformazione,convertire,md
|
||||
|
||||
home.getPdfInfo.title=Ottieni TUTTE le informazioni in PDF
|
||||
home.getPdfInfo.desc=Raccogli tutte le informazioni possibili sui PDF
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Conversione in corso
|
||||
MarkdownToPDF.credit=Utilizza WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF in Markdown
|
||||
PDFToMarkdown.header=PDF in Markdown
|
||||
PDFToMarkdown.submit=Converti
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL a PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Converti in PDF
|
||||
compress.title=Comprimi
|
||||
compress.header=Comprimi PDF
|
||||
compress.credit=Questo servizio utilizza qpdf per la compressione/ottimizzazione dei PDF.
|
||||
compress.selectText.1=Modalità manuale - Da 1 a 4
|
||||
compress.selectText.1=Modalità manuale - Da 1 a 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Livello di ottimizzazione:
|
||||
compress.selectText.3=4 (Terribile per le immagini di testo)
|
||||
compress.selectText.4=Modalità automatica - Regola automaticamente la qualità per ottenere le dimensioni esatte del PDF
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=MarkdownをPDFに変換
|
||||
home.MarkdownToPDF.desc=あらゆるMarkdownファイルをPDFに変換します。
|
||||
MarkdownToPDF.tags=markup,web-content,transformation,convert
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=PDFのすべての情報を入手
|
||||
home.getPdfInfo.desc=PDFのあらゆる情報を取得します。
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=処理中
|
||||
MarkdownToPDF.credit=WeasyPrintを使用
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URLをPDFに変換
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=PDFを変換
|
||||
compress.title=圧縮
|
||||
compress.header=PDFを圧縮
|
||||
compress.credit=本サービスはPDFの圧縮/最適化にqpdfを使用しています。
|
||||
compress.selectText.1=手動モード - 1 から 4
|
||||
compress.selectText.1=手動モード - 1 から 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=品質レベル:
|
||||
compress.selectText.3=4 (テキスト画像は最悪)
|
||||
compress.selectText.4=自動モード - PDFを正確なサイズにするために品質を自動調整する。
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown naar PDF
|
||||
home.MarkdownToPDF.desc=Zet Markdown-bestand om naar PDF
|
||||
MarkdownToPDF.tags=markup,web-inhoud,transformatie,omzetten
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Haal ALLE informatie op over PDF
|
||||
home.getPdfInfo.desc=Haalt alle mogelijke informatie op van PDF's
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=In ontwikkeling
|
||||
MarkdownToPDF.credit=Gebruikt WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL naar PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Omzetten naar PDF
|
||||
compress.title=Comprimeren
|
||||
compress.header=PDF comprimeren
|
||||
compress.credit=Deze functie gebruikt qpdf voor PDF Compressie/Optimalisatie.
|
||||
compress.selectText.1=Handmatige modus - Van 1 tot 4
|
||||
compress.selectText.1=Handmatige modus - Van 1 tot 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimalisatieniveau:
|
||||
compress.selectText.3=4 (Verschrikkelijk voor tekstafbeeldingen)
|
||||
compress.selectText.4=Automatische modus - Past kwaliteit automatisch aan om PDF naar exacte grootte te krijgen
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown til PDF
|
||||
home.MarkdownToPDF.desc=Konverter hvilken som helst Markdown-fil til PDF
|
||||
MarkdownToPDF.tags=markup,web-innhold,transformasjon,konverter
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Få ALL informasjon om PDF
|
||||
home.getPdfInfo.desc=Fanger opp all tilgjengelig informasjon om PDF-er
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Arbeid pågår
|
||||
MarkdownToPDF.credit=Bruker WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL Til PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Konverter til PDF
|
||||
compress.title=Komprimer
|
||||
compress.header=Komprimer PDF
|
||||
compress.credit=Denne tjenesten bruker qpdf for PDF-komprimering/optimisering.
|
||||
compress.selectText.1=Manuell modus - Fra 1 til 4
|
||||
compress.selectText.1=Manuell modus - Fra 1 til 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimeringsnivå:
|
||||
compress.selectText.3=4 (Dårlig for tekstbilder)
|
||||
compress.selectText.4=Automatisk modus - Justerer automatisk kvaliteten for å få PDF til nøyaktig størrelse
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown do PDF
|
||||
home.MarkdownToPDF.desc=Zapisuje dokument Markdown do PDF
|
||||
MarkdownToPDF.tags=znaczniki, treść internetowa, transformacja, konwertowanie
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Pobierz informacje o pliku PDF
|
||||
home.getPdfInfo.desc=Pobiera wszelkie informacje o pliku PDF
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Prace trwają
|
||||
MarkdownToPDF.credit=Użyj WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL do PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Konwertuj na PDF
|
||||
compress.title=Kompresuj
|
||||
compress.header=Kompresuj PDF
|
||||
compress.credit=Ta usługa używa qpdf do kompresji/optymalizacji PDF.
|
||||
compress.selectText.1=Tryb ręczny - Od 1 do 4
|
||||
compress.selectText.1=Tryb ręczny - Od 1 do 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Poziom optymalizacji:
|
||||
compress.selectText.3=4 (Duże dla obrazów tekstowych)
|
||||
compress.selectText.4=Tryb automatyczny - Automatycznie dostosowuje jakość, aby uzyskać dokładny rozmiar pliku PDF
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown para PDF
|
||||
home.MarkdownToPDF.desc=Converte qualquer arquivo Markdown para PDF.
|
||||
MarkdownToPDF.tags=marcação,conteúdo-web,transformação,converter
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Obter Informações de um PDF
|
||||
home.getPdfInfo.desc=Obtém informações (metadata) de um PDF.
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Em desenvolvimento.
|
||||
MarkdownToPDF.credit=Utiliza o WeasyPrint.
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=Converter URL/Site para PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Converter para PDF
|
||||
compress.title=Comprimir
|
||||
compress.header=Comprimir
|
||||
compress.credit=Este serviço usa o Qpdf para compressão/otimização de PDF.
|
||||
compress.selectText.1=Modo Manual - 1 (Menos) a 9 (Mais)
|
||||
compress.selectText.1=Modo Manual - De 1 a 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Nível de Otimização:
|
||||
compress.selectText.3=4 (Pior para imagens de texto)
|
||||
compress.selectText.4=Modo Automático - Ajusta automaticamente a qualidade para atingir o tamanho exato desejado
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown în PDF
|
||||
home.MarkdownToPDF.desc=Convertește orice fișier Markdown în PDF
|
||||
MarkdownToPDF.tags=markup,conținut-web,transformare,convertește
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Obține TOATE Informațiile despre PDF
|
||||
home.getPdfInfo.desc=Extrage orice și toate informațiile posibile despre PDF-uri
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Lucrare în curs
|
||||
MarkdownToPDF.credit=Folosește WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL în PDF
|
||||
@@ -933,11 +941,12 @@ fileToPDF.submit=Convertiți în PDF
|
||||
compress.title=Comprimare
|
||||
compress.header=Comprimare PDF
|
||||
compress.credit=Acest serviciu utilizează qpdf pentru comprimarea/optimizarea PDF-urilor.
|
||||
compress.selectText.1=Nivel de optimizare:
|
||||
compress.selectText.2=0 (Fără optimizare)
|
||||
compress.selectText.3=1 (Implicit, optimizare fără pierdere)
|
||||
compress.selectText.4=2 (Optimizare cu pierdere)
|
||||
compress.selectText.5=3 (Optimizare cu pierdere, mai agresivă)
|
||||
compress.selectText.1=Modul manual - de la 1 la 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Nivel de optimizare:
|
||||
compress.selectText.3=4 (Îngrozitor pentru imaginile text)
|
||||
compress.selectText.4=Mod automat - ajustează automat calitatea pentru a aduce PDF-ul la dimensiunea exactă
|
||||
compress.selectText.5=Dimensiunea PDF așteptată (de ex. 25MB, 10.8MB, 25KB)
|
||||
compress.submit=Comprimare
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown do PDF
|
||||
home.MarkdownToPDF.desc=Konvertuje akýkoľvek Markdown súbor do PDF
|
||||
MarkdownToPDF.tags=markup, webový obsah, transformácia, konvertovať
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Získať všetky informácie o PDF
|
||||
home.getPdfInfo.desc=Získava všetky dostupné informácie o PDF
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Práca prebieha
|
||||
MarkdownToPDF.credit=Používa WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL do PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Konvertovať do PDF
|
||||
compress.title=Komprimovať
|
||||
compress.header=Komprimovať PDF
|
||||
compress.credit=Táto služba používa qpdf pre kompresiu/optimalizáciu PDF.
|
||||
compress.selectText.1=Manuálny režim - Od 1 do 4
|
||||
compress.selectText.1=Manuálny režim - Od 1 do 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Úroveň optimalizácie:
|
||||
compress.selectText.3=4 (Hrozné pre textové obrázky)
|
||||
compress.selectText.4=Automatický režim - Automaticky upravuje kvalitu, aby sa PDF dostalo na presnú veľkosť
|
||||
|
||||
1375
src/main/resources/messages_sl_SI.properties
Normal file
1375
src/main/resources/messages_sl_SI.properties
Normal file
File diff suppressed because it is too large
Load Diff
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown u PDF
|
||||
home.MarkdownToPDF.desc=Konvertuje bilo koji Markdown fajl u PDF
|
||||
MarkdownToPDF.tags=oznake,web-sadržaj,transformacija,konvertovanje
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Dohvati SVE informacije o PDF-u
|
||||
home.getPdfInfo.desc=Dobavlja sve moguće informacije o PDF-ovima
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Rad u toku
|
||||
MarkdownToPDF.credit=Koristi WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL u PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Konvertuj u PDF
|
||||
compress.title=Kompresija
|
||||
compress.header=Kompresuj PDF
|
||||
compress.credit=Ova usluga koristi qpdf za kompresiju / optimizaciju PDF-a.
|
||||
compress.selectText.1=Ručni režim - Od 1 do 4
|
||||
compress.selectText.1=Ručni režim - Od 1 do 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Nivo optimizacije:
|
||||
compress.selectText.3=4 (Užasno za tekstualne slike)
|
||||
compress.selectText.4=Automatski režim - Automatski prilagođava kvalitet kako bi PDF bio tačne veličine
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown till PDF
|
||||
home.MarkdownToPDF.desc=Konverterar valfri Markdown-fil till PDF
|
||||
MarkdownToPDF.tags=markup,webbinnehåll,transformation,konvertera
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Hämta ALL information om PDF
|
||||
home.getPdfInfo.desc=Hämtar all möjlig information om PDF:er
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Pågående arbete
|
||||
MarkdownToPDF.credit=Använder WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL till PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Konvertera till PDF
|
||||
compress.title=Komprimera
|
||||
compress.header=Komprimera PDF
|
||||
compress.credit=Denna tjänst använder qpdf för PDF-komprimering/optimering.
|
||||
compress.selectText.1=Manuellt läge - Från 1 till 4
|
||||
compress.selectText.1=Manuellt läge - Från 1 till 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimeringsnivå:
|
||||
compress.selectText.3=4 (Fruktansvärt för textbilder)
|
||||
compress.selectText.4=Autoläge - Autojusterar kvaliteten för att få PDF till exakt storlek
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown เป็น PDF
|
||||
home.MarkdownToPDF.desc=แปลงไฟล์ Markdown เป็น PDF
|
||||
MarkdownToPDF.tags=มาร์กอัป, เนื้อหาเว็บ, การแปลง, การแปลง
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=รับข้อมูลทั้งหมดเกี่ยวกับ PDF
|
||||
home.getPdfInfo.desc=รับข้อมูลที่เป็นไปได้ทั้งหมดเกี่ยวกับ PDF
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=กำลังดำเนินการ
|
||||
MarkdownToPDF.credit=ใช้ WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL เป็น PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=แปลงเป็น PDF
|
||||
compress.title=บีบอัด
|
||||
compress.header=บีบอัด PDF
|
||||
compress.credit=บริการนี้ใช้ qpdf สำหรับการบีบอัด/การเพิ่มประสิทธิภาพ PDF
|
||||
compress.selectText.1=โหมดแมนนวล - จาก 1 ถึง 4
|
||||
compress.selectText.1=โหมดแมนนวล - จาก 1 ถึง 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=ระดับการเพิ่มประสิทธิภาพ:
|
||||
compress.selectText.3=4 (ไม่ดีสำหรับภาพข้อความ)
|
||||
compress.selectText.4=โหมดอัตโนมัติ - ปรับคุณภาพอัตโนมัติเพื่อให้ PDF ตรงกับขนาดที่ต้องการ
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown'dan PDF'e
|
||||
home.MarkdownToPDF.desc=Herhangi bir Markdown dosyasını PDF'e dönüştürür
|
||||
MarkdownToPDF.tags=biçimlendirme,web-içeriği,dönüşüm,dönüştür
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=PDF Hakkında TÜM Bilgiyi Al
|
||||
home.getPdfInfo.desc=PDF'ler hakkında mümkün olan her türlü bilgiyi toplar
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Devam eden iş
|
||||
MarkdownToPDF.credit=WeasyPrint Kullanıyor
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL'den PDF'e
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=PDF'e Dönüştür
|
||||
compress.title=Sıkıştır
|
||||
compress.header=PDF'i Sıkıştır
|
||||
compress.credit=Bu hizmet PDF Sıkıştırma/Optimizasyonu için qpdf kullanır.
|
||||
compress.selectText.1=Manuel Mod - 1'den 4'e
|
||||
compress.selectText.1=Manuel Mod - 1'den 5'e
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimizasyon seviyesi:
|
||||
compress.selectText.3=4 (Metin resimleri için hiç uygun değil)
|
||||
compress.selectText.4=Otomatik mod - PDF'in tam boyutuna ulaşmak için kaliteyi otomatik ayarlar
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown у PDF
|
||||
home.MarkdownToPDF.desc=Конвертує будь-який файл Markdown у PDF
|
||||
MarkdownToPDF.tags=markup,web-content,transformation,convert
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Отримати ВСЮ інформацію у форматі PDF
|
||||
home.getPdfInfo.desc=Збирає будь-яку можливу інформацію у PDF-файлах.
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Робота в процесі
|
||||
MarkdownToPDF.credit=Використовує WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL у PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Перетворити у PDF
|
||||
compress.title=Стиснути
|
||||
compress.header=Стиснути PDF
|
||||
compress.credit=Ця служба використовує qpdf для стиснення/оптимізації PDF.
|
||||
compress.selectText.1=Ручний режим - від 1 до 4
|
||||
compress.selectText.1=Ручний режим - від 1 до 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Рівень оптимізації:
|
||||
compress.selectText.3=4 (Жахливо для текстових зображень)
|
||||
compress.selectText.4=Автоматичний режим - автоматично налаштовує якість для отримання PDF точного розміру
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown sang PDF
|
||||
home.MarkdownToPDF.desc=Chuyển đổi bất kỳ tệp Markdown nào thành PDF
|
||||
MarkdownToPDF.tags=đánh dấu,nội dung web,chuyển đổi,chuyển
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=Lấy TẤT CẢ thông tin về PDF
|
||||
home.getPdfInfo.desc=Lấy bất kỳ và tất cả thông tin có thể về PDF
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=Đang trong quá trình phát triển
|
||||
MarkdownToPDF.credit=Sử dụng WeasyPrint
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL sang PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=Chuyển đổi sang PDF
|
||||
compress.title=Nén
|
||||
compress.header=Nén PDF
|
||||
compress.credit=Dịch vụ này sử dụng qpdf để Nén/Tối ưu hóa PDF.
|
||||
compress.selectText.1=Chế độ thủ công - Từ 1 đến 4
|
||||
compress.selectText.1=Chế độ thủ công - Từ 1 đến 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Mức độ tối ưu hóa:
|
||||
compress.selectText.3=4 (Tệ cho hình ảnh văn bản)
|
||||
compress.selectText.4=Chế độ tự động - Tự động điều chỉnh chất lượng để đạt được kích thước PDF chính xác
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown ནས་ PDF ལ།
|
||||
home.MarkdownToPDF.desc=Markdown ཡིག་ཆ་གང་རུང་ PDF ལ་བསྒྱུར་བ།
|
||||
MarkdownToPDF.tags=རྟགས་རྒྱག,དྲ་ངོས་ནང་དོན།,བསྒྱུར་བཅོས།,བསྒྱུར་བ།
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=PDF ཡི་གནས་ཚུལ་ཆ་ཚང་ལེན་པ།
|
||||
home.getPdfInfo.desc=PDF ཡི་གནས་ཚུལ་ཡོད་ཚད་ལེན་པ།
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=ལས་ཀ་བྱེད་བཞིན་པ།
|
||||
MarkdownToPDF.credit=WeasyPrint བེད་སྤྱོད་བྱེད་པ།
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL ནས་ PDF ལ།
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=PDF ལ་བསྒྱུར་བ།
|
||||
compress.title=སྡུད་སྒྲིལ།
|
||||
compress.header=PDF སྡུད་སྒྲིལ།
|
||||
compress.credit=ཞབས་ཞུ་འདིས་ PDF སྡུད་སྒྲིལ་/ཡར་རྒྱས་གཏོང་བའི་ཆེད་དུ་ qpdf བེད་སྤྱོད་བྱེད་པ།
|
||||
compress.selectText.1=ལག་བཟོས་<EFBFBD><EFBFBD>ྣམ་པ། - 1 ནས་ 4 བར།
|
||||
compress.selectText.1=Manual Mode - From 1 to 4
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=Optimisation level:
|
||||
compress.selectText.3=4 (Terrible for text images)
|
||||
compress.selectText.4=རང་འགུལ་རྣམ་པ། - PDF ཏག་ཏག་ཆེ་ཆུང་ཚད་ལ་འཁྲིད་པའི་ཆེད་དུ་སྤུས་ཚད་རང་འགུལ་གྱིས་སྙོམ་སྒྲིག་བྱེད་པ།
|
||||
|
||||
@@ -452,6 +452,9 @@ home.MarkdownToPDF.title=Markdown 转 PDF
|
||||
home.MarkdownToPDF.desc=将任何 Markdown 文件转换为 PDF
|
||||
MarkdownToPDF.tags=标记、网页内容、转换、转换
|
||||
|
||||
home.PDFToMarkdown.title=PDF to Markdown
|
||||
home.PDFToMarkdown.desc=Converts any PDF to Markdown
|
||||
PDFToMarkdown.tags=markup,web-content,transformation,convert,md
|
||||
|
||||
home.getPdfInfo.title=获取 PDF 的所有信息
|
||||
home.getPdfInfo.desc=获取 PDF 的所有可能的信息
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=正在努力中
|
||||
MarkdownToPDF.credit=此服务使用 WeasyPrint 进行文件转换。
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL 转 PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=转换为 PDF
|
||||
compress.title=压缩
|
||||
compress.header=压缩 PDF
|
||||
compress.credit=此服务使用qpdf进行 PDF 压缩/优化。
|
||||
compress.selectText.1=手动模式 - 从 1 到 4
|
||||
compress.selectText.1=手动模式 - 从 1 到 5
|
||||
compress.selectText.1.1=In optimization levels 6 to 9, in addition to general PDF compression, image resolution is scaled down to further reduce file size. Higher levels result in stronger image compression (up to 50% of the original size), achieving greater size reduction but with potential quality loss in images.
|
||||
compress.selectText.2=优化级别:
|
||||
compress.selectText.3=4(文本图像很糟糕)
|
||||
compress.selectText.4=自动模式 - 自动调整质量以获得精确大小的PDF
|
||||
|
||||
@@ -331,7 +331,7 @@ changeMetadata.tags=標題,作者,日期,建立,時間,出版商,製作人,統
|
||||
|
||||
home.fileToPDF.title=檔案轉 PDF
|
||||
home.fileToPDF.desc=將幾乎所有格式轉換為 PDF(DOCX、PNG、XLS、PPT、TXT 等等)
|
||||
fileToPDF.tags=轉換,格式,文件,圖片,幻燈片,文字,轉換,辦公室,文件,Word,Excel,PowerPoint
|
||||
fileToPDF.tags=轉換,格式,文件,圖片,投影片,文字,轉換,office,docs,Word,Excel,PowerPoint
|
||||
|
||||
home.ocr.title=OCR / 清理掃描
|
||||
home.ocr.desc=清理掃描並從 PDF 中的影像中偵測文字並重新新增為文字。
|
||||
@@ -344,15 +344,15 @@ extractImages.tags=圖片,照片,儲存,存檔,壓縮檔,捕獲,抓取
|
||||
|
||||
home.pdfToPDFA.title=PDF 轉 PDF/A
|
||||
home.pdfToPDFA.desc=將 PDF 轉換為長期儲存的 PDF/A
|
||||
pdfToPDFA.tags=存檔,長期,標準,轉換,儲存,儲存
|
||||
pdfToPDFA.tags=存檔,長期,標準,轉換,儲存,保存
|
||||
|
||||
home.PDFToWord.title=PDF 轉 Word
|
||||
home.PDFToWord.desc=將 PDF 轉換為 Word 格式(DOC、DOCX 和 ODT)
|
||||
PDFToWord.tags=doc,docx,odt,word,轉換,格式,轉換,辦公室,微軟,docfile
|
||||
PDFToWord.tags=doc,docx,odt,word,轉換,格式,轉檔,office,微軟,docfile
|
||||
|
||||
home.PDFToPresentation.title=PDF 轉簡報
|
||||
home.PDFToPresentation.desc=將 PDF 轉換為簡報格式(PPT、PPTX 和 ODP)
|
||||
PDFToPresentation.tags=幻燈片,展示,辦公室,微軟
|
||||
PDFToPresentation.tags=投影片,展示,office,微軟
|
||||
|
||||
home.PDFToText.title=PDF 轉 RTF(文字)
|
||||
home.PDFToText.desc=將 PDF 轉換為文字或 RTF 格式
|
||||
@@ -365,7 +365,7 @@ PDFToHTML.tags=網頁內容,瀏覽器友善
|
||||
|
||||
home.PDFToXML.title=PDF 轉 XML
|
||||
home.PDFToXML.desc=將 PDF 轉換為 XML 格式
|
||||
PDFToXML.tags=資料提取,結構化內容,互操作,轉換,轉換
|
||||
PDFToXML.tags=資料提取,結構化內容,互操作,轉換,轉檔
|
||||
|
||||
home.ScannerImageSplit.title=偵測/分割掃描照片
|
||||
home.ScannerImageSplit.desc=從照片/PDF 中分割多張照片
|
||||
@@ -381,7 +381,7 @@ flatten.tags=靜態,停用,非互動,簡化
|
||||
|
||||
home.repair.title=修復
|
||||
home.repair.desc=嘗試修復損壞/破損的 PDF
|
||||
repair.tags=修復,恢復,修正,恢復
|
||||
repair.tags=修復,恢復,修正,復原
|
||||
|
||||
home.removeBlanks.title=移除空白頁面
|
||||
home.removeBlanks.desc=偵測並從文件中移除空白頁面
|
||||
@@ -437,7 +437,7 @@ autoSplitPDF.tags=基於 QR Code,分離,掃描區段,組織
|
||||
|
||||
home.sanitizePdf.title=清理
|
||||
home.sanitizePdf.desc=從 PDF 檔案中移除指令碼和其他元素
|
||||
sanitizePdf.tags=清理,安全,安全,移除威脅
|
||||
sanitizePdf.tags=清理,安全,無害,移除威脅
|
||||
|
||||
home.URLToPDF.title=網址/網站轉 PDF
|
||||
home.URLToPDF.desc=將任何 http(s) 網址轉換為 PDF
|
||||
@@ -445,13 +445,16 @@ URLToPDF.tags=網頁捕獲,儲存頁面,網頁轉文件,存檔
|
||||
|
||||
home.HTMLToPDF.title=HTML 轉 PDF
|
||||
home.HTMLToPDF.desc=將任何 HTML 檔案或壓縮檔轉換為 PDF
|
||||
HTMLToPDF.tags=標記,網頁內容,轉換,轉換
|
||||
HTMLToPDF.tags=標記,網頁內容,轉換,轉檔
|
||||
|
||||
|
||||
home.MarkdownToPDF.title=Markdown 轉 PDF
|
||||
home.MarkdownToPDF.desc=將任何 Markdown 檔案轉換為 PDF
|
||||
MarkdownToPDF.tags=標記,網頁內容,轉換,轉換
|
||||
MarkdownToPDF.tags=標記,網頁內容,轉換,轉檔,md
|
||||
|
||||
home.PDFToMarkdown.title=PDF 轉 Markdown
|
||||
home.PDFToMarkdown.desc=將任何 PDF 轉換為 Markdown 檔案
|
||||
PDFToMarkdown.tags=標記語言,網頁內容,轉換,轉檔,md
|
||||
|
||||
home.getPdfInfo.title=取得 PDF 的所有資訊
|
||||
home.getPdfInfo.desc=取得 PDF 的所有可能資訊
|
||||
@@ -474,11 +477,11 @@ showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=自動塗黑
|
||||
home.autoRedact.desc=根據輸入的文字自動塗黑 PDF 中的文字
|
||||
autoRedact.tags=塗黑,隱藏,塗黑,黑色,標記,隱藏
|
||||
autoRedact.tags=塗改,隱藏,塗黑,黑色,標記,遮蔽
|
||||
|
||||
home.redact.title=手動塗黑
|
||||
home.redact.desc=依據選取的文字、繪製的形狀和選取的頁面塗黑 PDF
|
||||
redact.tags=塗黑,隱藏,黑色標記,黑色,標記,隱藏,手動
|
||||
redact.tags=塗改,隱藏,塗黑,黑色,標記,遮蔽,手動
|
||||
|
||||
home.tableExtraxt.title=PDF 轉 CSV
|
||||
home.tableExtraxt.desc=從 PDF 中提取表格並將其轉換為 CSV
|
||||
@@ -646,6 +649,11 @@ MarkdownToPDF.help=正在進行中
|
||||
MarkdownToPDF.credit=此服務使用 WeasyPrint 進行轉換
|
||||
|
||||
|
||||
#pdf-to-markdown
|
||||
PDFToMarkdown.title=PDF To Markdown
|
||||
PDFToMarkdown.header=PDF To Markdown
|
||||
PDFToMarkdown.submit=Convert
|
||||
|
||||
|
||||
#url-to-pdf
|
||||
URLToPDF.title=URL 轉 PDF
|
||||
@@ -933,7 +941,8 @@ fileToPDF.submit=轉換為 PDF
|
||||
compress.title=壓縮
|
||||
compress.header=壓縮 PDF
|
||||
compress.credit=此服務使用 qpdf 進行 PDF 壓縮/最佳化。
|
||||
compress.selectText.1=手動模式 - 從 1 到 4
|
||||
compress.selectText.1=手動模式 - 從 1 到 5
|
||||
compress.selectText.1.1=在最佳化等級 6 到 9 時,除了一般 PDF 壓縮外,圖片解析度也會降低以進一步減少檔案大小。較高的壓縮等級會進行更高強度的圖片壓縮(最多可壓縮到原始大小的 50%),以達到更高的壓縮率,但可能會影響圖片品質。
|
||||
compress.selectText.2=最佳化等級:
|
||||
compress.selectText.3=4(對於含有文字的影像來說結果很糟)
|
||||
compress.selectText.4=自動模式 - 自動調整品質使 PDF 達到指定的檔案大小
|
||||
|
||||
@@ -284,7 +284,7 @@
|
||||
{
|
||||
"moduleName": "com.opencsv:opencsv",
|
||||
"moduleUrl": "http://opencsv.sf.net",
|
||||
"moduleVersion": "5.9",
|
||||
"moduleVersion": "5.10",
|
||||
"moduleLicense": "Apache 2",
|
||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
},
|
||||
@@ -376,6 +376,132 @@
|
||||
"moduleLicense": "UnboundID SCIM2 SDK Free Use License",
|
||||
"moduleLicenseUrl": "https://github.com/pingidentity/scim2"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-ext-emoji",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-ext-gfm-strikethrough",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-ext-ins",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-ext-superscript",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-ext-tables",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-ext-wikilink",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-html2md-converter",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-jira-converter",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-ast",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-builder",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-collection",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-data",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-dependency",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-format",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-html",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-misc",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-options",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-sequence",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.vladsch.flexmark:flexmark-util-visitor",
|
||||
"moduleVersion": "0.64.8",
|
||||
"moduleLicense": "BSD 2-Clause License",
|
||||
"moduleLicenseUrl": "http://opensource.org/licenses/BSD-2-Clause"
|
||||
},
|
||||
{
|
||||
"moduleName": "com.zaxxer:HikariCP",
|
||||
"moduleUrl": "https://github.com/brettwooldridge/HikariCP",
|
||||
@@ -385,9 +511,9 @@
|
||||
},
|
||||
{
|
||||
"moduleName": "commons-beanutils:commons-beanutils",
|
||||
"moduleUrl": "https://commons.apache.org/proper/commons-beanutils/",
|
||||
"moduleVersion": "1.9.4",
|
||||
"moduleLicense": "Apache License, Version 2.0",
|
||||
"moduleUrl": "https://commons.apache.org/proper/commons-beanutils",
|
||||
"moduleVersion": "1.10.0",
|
||||
"moduleLicense": "Apache-2.0",
|
||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
},
|
||||
{
|
||||
@@ -448,7 +574,7 @@
|
||||
{
|
||||
"moduleName": "io.micrometer:micrometer-core",
|
||||
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
||||
"moduleVersion": "1.14.2",
|
||||
"moduleVersion": "1.14.3",
|
||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
},
|
||||
@@ -690,7 +816,7 @@
|
||||
{
|
||||
"moduleName": "org.apache.commons:commons-text",
|
||||
"moduleUrl": "https://commons.apache.org/proper/commons-text",
|
||||
"moduleVersion": "1.11.0",
|
||||
"moduleVersion": "1.13.0",
|
||||
"moduleLicense": "Apache-2.0",
|
||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
},
|
||||
@@ -747,6 +873,13 @@
|
||||
"moduleLicense": "Apache-2.0",
|
||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
},
|
||||
{
|
||||
"moduleName": "org.apache.pdfbox:preflight",
|
||||
"moduleUrl": "https://pdfbox.apache.org",
|
||||
"moduleVersion": "3.0.3",
|
||||
"moduleLicense": "Apache-2.0",
|
||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
},
|
||||
{
|
||||
"moduleName": "org.apache.pdfbox:xmpbox",
|
||||
"moduleUrl": "https://pdfbox.apache.org",
|
||||
@@ -818,15 +951,15 @@
|
||||
},
|
||||
{
|
||||
"moduleName": "org.bouncycastle:bcpkix-jdk18on",
|
||||
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
||||
"moduleVersion": "1.79",
|
||||
"moduleUrl": "https://www.bouncycastle.org/download/bouncy-castle-java/",
|
||||
"moduleVersion": "1.80",
|
||||
"moduleLicense": "Bouncy Castle Licence",
|
||||
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
||||
},
|
||||
{
|
||||
"moduleName": "org.bouncycastle:bcprov-jdk18on",
|
||||
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
||||
"moduleVersion": "1.79",
|
||||
"moduleUrl": "https://www.bouncycastle.org/download/bouncy-castle-java/",
|
||||
"moduleVersion": "1.80",
|
||||
"moduleLicense": "Bouncy Castle Licence",
|
||||
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
||||
},
|
||||
@@ -839,8 +972,8 @@
|
||||
},
|
||||
{
|
||||
"moduleName": "org.bouncycastle:bcutil-jdk18on",
|
||||
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
||||
"moduleVersion": "1.79",
|
||||
"moduleUrl": "https://www.bouncycastle.org/download/bouncy-castle-java/",
|
||||
"moduleVersion": "1.80",
|
||||
"moduleLicense": "Bouncy Castle Licence",
|
||||
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
||||
},
|
||||
@@ -1108,6 +1241,20 @@
|
||||
"moduleLicense": "Apache License 2.0",
|
||||
"moduleLicenseUrl": "https://repository.jboss.org/licenses/apache-2.0.txt"
|
||||
},
|
||||
{
|
||||
"moduleName": "org.jetbrains:annotations",
|
||||
"moduleUrl": "https://github.com/JetBrains/java-annotations",
|
||||
"moduleVersion": "24.0.1",
|
||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||
},
|
||||
{
|
||||
"moduleName": "org.jsoup:jsoup",
|
||||
"moduleUrl": "https://jsoup.org/",
|
||||
"moduleVersion": "1.15.4",
|
||||
"moduleLicense": "The MIT License",
|
||||
"moduleLicenseUrl": "https://jsoup.org/license"
|
||||
},
|
||||
{
|
||||
"moduleName": "org.latencyutils:LatencyUtils",
|
||||
"moduleUrl": "http://latencyutils.github.io/LatencyUtils/",
|
||||
@@ -1518,7 +1665,7 @@
|
||||
{
|
||||
"moduleName": "org.springframework:spring-jdbc",
|
||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||
"moduleVersion": "6.2.1",
|
||||
"moduleVersion": "6.2.2",
|
||||
"moduleLicense": "Apache License, Version 2.0",
|
||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||
},
|
||||
@@ -1546,7 +1693,7 @@
|
||||
{
|
||||
"moduleName": "org.springframework:spring-webmvc",
|
||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||
"moduleVersion": "6.2.1",
|
||||
"moduleVersion": "6.2.2",
|
||||
"moduleLicense": "Apache License, Version 2.0",
|
||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||
},
|
||||
|
||||
@@ -126,6 +126,10 @@ html {
|
||||
border-color: rgba(6, 114, 197, 0.82) !important;
|
||||
}
|
||||
|
||||
#pdfToImageBtn:hover .btn-tooltip {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#redactionsPaletteContainer {
|
||||
height: var(--toolButton-height);
|
||||
width: var(--toolButton-width);
|
||||
|
||||
@@ -32,7 +32,7 @@ select#font-select option {
|
||||
margin-left: -2.2rem;
|
||||
}
|
||||
|
||||
.draggable-buttons-box>button {
|
||||
.draggable-buttons-box > button {
|
||||
z-index: 4;
|
||||
background-color: rgba(13, 110, 253, 0.1);
|
||||
flex: 1 1 auto;
|
||||
@@ -40,7 +40,6 @@ select#font-select option {
|
||||
max-width: 4rem;
|
||||
}
|
||||
|
||||
|
||||
.rotation-handle {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
@@ -163,3 +162,76 @@ select#font-select option {
|
||||
.small-file-container-saved:hover .drag-icon {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* The container must be positioned relative: */
|
||||
.custom-select {
|
||||
position: relative;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.custom-select select {
|
||||
display: none; /*hide original SELECT element: */
|
||||
}
|
||||
|
||||
.select-selected {
|
||||
background-color: inherit;
|
||||
line-height: 30px;
|
||||
font-size: 30px;
|
||||
border-radius: 3rem !important;
|
||||
}
|
||||
|
||||
/* Style the arrow inside the select element: */
|
||||
.select-selected:after {
|
||||
position: absolute;
|
||||
content: "";
|
||||
top: 50%;
|
||||
right: 10px;
|
||||
translate: 0 -50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border: 6px solid transparent;
|
||||
border-color: #fff transparent transparent transparent;
|
||||
}
|
||||
|
||||
/* Point the arrow upwards when the select box is open (active): */
|
||||
.select-selected.select-arrow-active:after {
|
||||
border-color: transparent transparent #fff transparent;
|
||||
translate: 0 -75%;
|
||||
}
|
||||
|
||||
/* style the items (options), including the selected item: */
|
||||
.select-items div,
|
||||
.select-selected {
|
||||
color: inherit;
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.select-items div {
|
||||
border: 1px solid transparent;
|
||||
border-color: transparent transparent transparent transparent;
|
||||
|
||||
line-height: 30px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
/* Style items (options): */
|
||||
.select-items {
|
||||
position: absolute;
|
||||
background-color: inherit;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 101;
|
||||
border: inherit;
|
||||
}
|
||||
|
||||
/* Hide the items when the select box is closed: */
|
||||
.select-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select-items div:hover,
|
||||
.same-as-selected {
|
||||
background-color: rgba(54, 54, 54, 0.1);
|
||||
}
|
||||
|
||||
18
src/main/resources/static/images/flags/si.svg
Normal file
18
src/main/resources/static/images/flags/si.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-si" viewBox="0 0 640 480">
|
||||
<defs>
|
||||
<clipPath id="si-a">
|
||||
<path fill-opacity=".7" d="M-15 0h682.6v512H-15.1z"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g fill-rule="evenodd" stroke-width="1pt" clip-path="url(#si-a)" transform="translate(14.1)scale(.9375)">
|
||||
<path fill="#fff" d="M-62 0H962v512H-62z"/>
|
||||
<path fill="#d50000" d="M-62 341.3H962V512H-62z"/>
|
||||
<path fill="#0000bf" d="M-62 170.7H962v170.6H-62z"/>
|
||||
<path fill="#d50000" d="M228.4 93c-4 61.6-6.4 95.4-15.7 111-10.2 16.8-20 29.1-59.7 44-39.6-14.9-49.4-27.2-59.6-44-9.4-15.6-11.7-49.4-15.7-111l5.8-2c11.8-3.6 20.6-6.5 27.1-7.8 9.3-2 17.3-4.2 42.3-4.7 25 .4 33 2.8 42.3 4.8q9.7 2.1 27.3 7.7z"/>
|
||||
<path fill="#0000bf" d="M222.6 91c-3.8 61.5-7 89.7-12 103.2-9.6 23.2-24.8 35.9-57.6 48-32.8-12.1-48-24.8-57.7-48-5-13.6-8-41.7-11.8-103.3q17.4-5.6 27.1-7.7c9.3-2 17.3-4.3 42.3-4.7 25 .4 33 2.7 42.3 4.7a284 284 0 0 1 27.4 7.7z"/>
|
||||
<path fill="#ffdf00" d="m153 109.8 1.5 3.7 7 1-4.5 2.7 4.3 2.9-6.3 1-2 3.4-2-3.5-6-.8 4-3-4.2-2.7 6.7-1z"/>
|
||||
<path fill="#fff" d="m208.3 179.6-3.9-3-2.7-4.6-5.4-4.7-2.9-4.7-5.4-4.9-2.6-4.7-3-2.3-1.8-1.9-5 4.3-2.6 4.7-3.3 3-3.7-2.9-2.7-4.8-10.3-18.3-10.3 18.3-2.7 4.8-3.7 2.9-3.3-3-2.7-4.7-4.9-4.3-1.9 1.8-2.9 2.4-2.6 4.7-5.4 4.9-2.9 4.7-5.4 4.7-2.7 4.6-3.9 3a66 66 0 0 0 18.6 36.3 107 107 0 0 0 36.6 20.5 104 104 0 0 0 36.8-20.5c5.8-6 16.6-19.3 18.6-36.3"/>
|
||||
<path fill="#ffdf00" d="m169.4 83.9 1.6 3.7 7 1-4.6 2.7 4.4 2.9-6.3 1-2 3.4-2-3.5-6-.8 4-3-4.2-2.7 6.6-1zm-33 0 1.6 3.7 7 .9-4.5 2.7 4.3 2.9-6.3 1-2 3.4-2-3.4-6-.9 4-3-4.2-2.7 6.7-1z"/>
|
||||
<path fill="#0000bf" d="M199.7 203h-7.4l-7-.5-8.3-4h-9.4l-8.1 4-6.5.6-6.4-.6-8.1-4H129l-8.4 4-6.9.6-7.6-.1-3.6-6.2.1-.2 11.2 1.9 6.9-.5 8.3-4.1h9.4l8.2 4 6.4.6 6.5-.6 8.1-4h9.4l8.4 4 6.9.6 10.8-2 .2.4zm-86.4 9.5 7.4-.5 8.3-4h9.4l8.2 4 6.4.5 6.4-.5 8.2-4h9.4l8.3 4 7.5.5 4.8-6h-.1l-5.2 1.4-6.9-.5-8.3-4h-9.4l-8.2 4-6.4.6-6.5-.6-8.1-4H129l-8.4 4-6.9.6-5-1.3v.2l4.5 5.6z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
@@ -8,21 +8,21 @@ window.goToFirstOrLastPage = goToFirstOrLastPage;
|
||||
let currentPreviewSrc = null;
|
||||
|
||||
function toggleSignatureView() {
|
||||
const gridView = document.getElementById('gridView');
|
||||
const listView = document.getElementById('listView');
|
||||
const gridText = document.querySelector('.grid-view-text');
|
||||
const listText = document.querySelector('.list-view-text');
|
||||
const gridView = document.getElementById("gridView");
|
||||
const listView = document.getElementById("listView");
|
||||
const gridText = document.querySelector(".grid-view-text");
|
||||
const listText = document.querySelector(".list-view-text");
|
||||
|
||||
if (gridView.style.display !== 'none') {
|
||||
gridView.style.display = 'none';
|
||||
listView.style.display = 'block';
|
||||
gridText.style.display = 'none';
|
||||
listText.style.display = 'inline';
|
||||
if (gridView.style.display !== "none") {
|
||||
gridView.style.display = "none";
|
||||
listView.style.display = "block";
|
||||
gridText.style.display = "none";
|
||||
listText.style.display = "inline";
|
||||
} else {
|
||||
gridView.style.display = 'block';
|
||||
listView.style.display = 'none';
|
||||
gridText.style.display = 'inline';
|
||||
listText.style.display = 'none';
|
||||
gridView.style.display = "block";
|
||||
listView.style.display = "none";
|
||||
gridText.style.display = "inline";
|
||||
listText.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,63 +30,204 @@ function previewSignature(element) {
|
||||
const src = element.dataset.src;
|
||||
currentPreviewSrc = src;
|
||||
|
||||
const filename = element.querySelector('.signature-list-name').textContent;
|
||||
const filename = element.querySelector(".signature-list-name").textContent;
|
||||
|
||||
const previewImage = document.getElementById('previewImage');
|
||||
const previewFileName = document.getElementById('previewFileName');
|
||||
const previewImage = document.getElementById("previewImage");
|
||||
const previewFileName = document.getElementById("previewFileName");
|
||||
|
||||
previewImage.src = src;
|
||||
previewFileName.textContent = filename;
|
||||
|
||||
const modal = new bootstrap.Modal(document.getElementById('signaturePreview'));
|
||||
const modal = new bootstrap.Modal(
|
||||
document.getElementById("signaturePreview")
|
||||
);
|
||||
modal.show();
|
||||
}
|
||||
|
||||
function addSignatureFromPreview() {
|
||||
if (currentPreviewSrc) {
|
||||
DraggableUtils.createDraggableCanvasFromUrl(currentPreviewSrc);
|
||||
bootstrap.Modal.getInstance(document.getElementById('signaturePreview')).hide();
|
||||
bootstrap.Modal.getInstance(
|
||||
document.getElementById("signaturePreview")
|
||||
).hide();
|
||||
}
|
||||
}
|
||||
|
||||
let originalFileName = '';
|
||||
document.querySelector('input[name=pdf-upload]').addEventListener('change', async (event) => {
|
||||
const fileInput = event.target;
|
||||
fileInput.addEventListener('file-input-change', async (e) => {
|
||||
const {allFiles} = e.detail;
|
||||
if (allFiles && allFiles.length > 0) {
|
||||
const file = allFiles[0];
|
||||
originalFileName = file.name.replace(/\.[^/.]+$/, '');
|
||||
const pdfData = await file.arrayBuffer();
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
|
||||
const pdfDoc = await pdfjsLib.getDocument({data: pdfData}).promise;
|
||||
await DraggableUtils.renderPage(pdfDoc, 0);
|
||||
let originalFileName = "";
|
||||
document
|
||||
.querySelector("input[name=pdf-upload]")
|
||||
.addEventListener("change", async (event) => {
|
||||
const fileInput = event.target;
|
||||
fileInput.addEventListener("file-input-change", async (e) => {
|
||||
const { allFiles } = e.detail;
|
||||
if (allFiles && allFiles.length > 0) {
|
||||
const file = allFiles[0];
|
||||
originalFileName = file.name.replace(/\.[^/.]+$/, "");
|
||||
const pdfData = await file.arrayBuffer();
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"./pdfjs-legacy/pdf.worker.mjs";
|
||||
const pdfDoc = await pdfjsLib.getDocument({ data: pdfData }).promise;
|
||||
await DraggableUtils.renderPage(pdfDoc, 0);
|
||||
|
||||
document.querySelectorAll('.show-on-file-selected').forEach((el) => {
|
||||
el.style.cssText = '';
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.querySelectorAll('.show-on-file-selected').forEach((el) => {
|
||||
el.style.cssText = 'display:none !important';
|
||||
});
|
||||
document.querySelectorAll('.small-file-container-saved img ').forEach((img) => {
|
||||
img.addEventListener('dragstart', (e) => {
|
||||
e.dataTransfer.setData('fileUrl', img.src);
|
||||
document.querySelectorAll(".show-on-file-selected").forEach((el) => {
|
||||
el.style.cssText = "";
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Delete') {
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.querySelectorAll(".show-on-file-selected").forEach((el) => {
|
||||
el.style.cssText = "display:none !important";
|
||||
});
|
||||
document
|
||||
.querySelectorAll(".small-file-container-saved img ")
|
||||
.forEach((img) => {
|
||||
img.addEventListener("dragstart", (e) => {
|
||||
e.dataTransfer.setData("fileUrl", img.src);
|
||||
});
|
||||
});
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Delete") {
|
||||
DraggableUtils.deleteDraggableCanvas(DraggableUtils.getLastInteracted());
|
||||
}
|
||||
});
|
||||
|
||||
addCustomSelect();
|
||||
});
|
||||
|
||||
const imageUpload = document.querySelector('input[name=image-upload]');
|
||||
imageUpload.addEventListener('change', (e) => {
|
||||
function addCustomSelect() {
|
||||
let customSelectElementContainer =
|
||||
document.getElementById("signFontSelection");
|
||||
let originalSelectElement =
|
||||
customSelectElementContainer.querySelector("select");
|
||||
|
||||
let optionsCount = originalSelectElement.length;
|
||||
|
||||
let selectedItem = createAndStyleSelectedItem();
|
||||
|
||||
customSelectElementContainer.appendChild(selectedItem);
|
||||
|
||||
let customSelectionsOptionsContainer = createCustomOptionsContainer();
|
||||
createAndAddCustomOptions();
|
||||
customSelectElementContainer.appendChild(customSelectionsOptionsContainer);
|
||||
|
||||
selectedItem.addEventListener("click", function (e) {
|
||||
/* When the select box is clicked, close any other select boxes,
|
||||
and open/close the current select box: */
|
||||
e.stopPropagation();
|
||||
closeAllSelect(this);
|
||||
this.nextSibling.classList.toggle("select-hide");
|
||||
this.classList.toggle("select-arrow-active");
|
||||
});
|
||||
|
||||
function createAndAddCustomOptions() {
|
||||
for (let j = 0; j < optionsCount; j++) {
|
||||
/* For each option in the original select element,
|
||||
create a new DIV that will act as an option item: */
|
||||
let customOptionItem = createAndStyleCustomOption(j);
|
||||
|
||||
customOptionItem.addEventListener("click", onCustomOptionClick);
|
||||
customSelectionsOptionsContainer.appendChild(customOptionItem);
|
||||
}
|
||||
}
|
||||
|
||||
function createCustomOptionsContainer() {
|
||||
let customSelectionsOptionsContainer = document.createElement("DIV");
|
||||
customSelectionsOptionsContainer.setAttribute(
|
||||
"class",
|
||||
"select-items select-hide"
|
||||
);
|
||||
return customSelectionsOptionsContainer;
|
||||
}
|
||||
|
||||
function createAndStyleSelectedItem() {
|
||||
let selectedItem = document.createElement("DIV");
|
||||
selectedItem.setAttribute("class", "select-selected");
|
||||
selectedItem.innerHTML =
|
||||
originalSelectElement.options[
|
||||
originalSelectElement.selectedIndex
|
||||
].innerHTML;
|
||||
|
||||
selectedItem.style.fontFamily = window.getComputedStyle(
|
||||
originalSelectElement.options[originalSelectElement.selectedIndex]
|
||||
).fontFamily;
|
||||
return selectedItem;
|
||||
}
|
||||
|
||||
function onCustomOptionClick(e) {
|
||||
/* When an item is clicked, update the original select box,
|
||||
and the selected item: */
|
||||
let selectElement =
|
||||
this.parentNode.parentNode.getElementsByTagName("select")[0];
|
||||
let optionsCount = selectElement.length;
|
||||
let currentlySelectedCustomOption = this.parentNode.previousSibling;
|
||||
for (let i = 0; i < optionsCount; i++) {
|
||||
if (selectElement.options[i].innerHTML == this.innerHTML) {
|
||||
selectElement.selectedIndex = i;
|
||||
currentlySelectedCustomOption.innerHTML = this.innerHTML;
|
||||
currentlySelectedCustomOption.style.fontFamily = this.style.fontFamily;
|
||||
|
||||
let previouslySelectedOption =
|
||||
this.parentNode.getElementsByClassName("same-as-selected");
|
||||
|
||||
if (previouslySelectedOption && previouslySelectedOption.length > 0)
|
||||
previouslySelectedOption[0].classList.remove("same-as-selected");
|
||||
|
||||
this.classList.add("same-as-selected");
|
||||
break;
|
||||
}
|
||||
}
|
||||
currentlySelectedCustomOption.click();
|
||||
}
|
||||
|
||||
function createAndStyleCustomOption(j) {
|
||||
let customOptionItem = document.createElement("DIV");
|
||||
customOptionItem.innerHTML = originalSelectElement.options[j].innerHTML;
|
||||
customOptionItem.classList.add(originalSelectElement.options[j].className);
|
||||
customOptionItem.style.fontFamily = window.getComputedStyle(
|
||||
originalSelectElement.options[j]
|
||||
).fontFamily;
|
||||
|
||||
if (j == originalSelectElement.selectedIndex)
|
||||
customOptionItem.classList.add("same-as-selected");
|
||||
return customOptionItem;
|
||||
}
|
||||
|
||||
function closeAllSelect(element) {
|
||||
/* A function that will close all select boxes in the document,
|
||||
except the current select box: */
|
||||
let allSelectedOptions = document.getElementsByClassName("select-selected");
|
||||
let allSelectedOptionsCount = allSelectedOptions.length;
|
||||
let indicesOfContainersToHide = [];
|
||||
for (let i = 0; i < allSelectedOptionsCount; i++) {
|
||||
if (element == allSelectedOptions[i]) {
|
||||
indicesOfContainersToHide.push(i);
|
||||
} else {
|
||||
allSelectedOptions[i].classList.remove("select-arrow-active");
|
||||
}
|
||||
}
|
||||
|
||||
hideOptionsContainers(indicesOfContainersToHide);
|
||||
}
|
||||
|
||||
/* If the user clicks anywhere outside the select box,
|
||||
then close all select boxes: */
|
||||
document.addEventListener("click", closeAllSelect);
|
||||
|
||||
function hideOptionsContainers(containersIndices) {
|
||||
let allOptionsContainers = document.getElementsByClassName("select-items");
|
||||
let allSelectionListsContainerCount = allOptionsContainers.length;
|
||||
for (let i = 0; i < allSelectionListsContainerCount; i++) {
|
||||
if (containersIndices.indexOf(i)) {
|
||||
allOptionsContainers[i].classList.add("select-hide");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const imageUpload = document.querySelector("input[name=image-upload]");
|
||||
imageUpload.addEventListener("change", (e) => {
|
||||
if (!e.target.files) return;
|
||||
for (const imageFile of e.target.files) {
|
||||
var reader = new FileReader();
|
||||
@@ -97,11 +238,11 @@ imageUpload.addEventListener('change', (e) => {
|
||||
}
|
||||
});
|
||||
|
||||
const signaturePadCanvas = document.getElementById('drawing-pad-canvas');
|
||||
const signaturePadCanvas = document.getElementById("drawing-pad-canvas");
|
||||
const signaturePad = new SignaturePad(signaturePadCanvas, {
|
||||
minWidth: 1,
|
||||
maxWidth: 2,
|
||||
penColor: 'black',
|
||||
penColor: "black",
|
||||
});
|
||||
|
||||
function addDraggableFromPad() {
|
||||
@@ -113,7 +254,7 @@ function addDraggableFromPad() {
|
||||
}
|
||||
|
||||
function getCroppedCanvasDataUrl(canvas) {
|
||||
let originalCtx = canvas.getContext('2d');
|
||||
let originalCtx = canvas.getContext("2d");
|
||||
let originalWidth = canvas.width;
|
||||
let originalHeight = canvas.height;
|
||||
let imageData = originalCtx.getImageData(0, 0, originalWidth, originalHeight);
|
||||
@@ -129,7 +270,8 @@ function getCroppedCanvasDataUrl(canvas) {
|
||||
for (y = 0; y < originalHeight; y++) {
|
||||
for (x = 0; x < originalWidth; x++) {
|
||||
currentPixelColorValueIndex = (y * originalWidth + x) * 4;
|
||||
let currentPixelAlphaValue = imageData.data[currentPixelColorValueIndex + 3];
|
||||
let currentPixelAlphaValue =
|
||||
imageData.data[currentPixelColorValueIndex + 3];
|
||||
if (currentPixelAlphaValue > 0) {
|
||||
if (minX > x) minX = x;
|
||||
if (maxX < x) maxX = x;
|
||||
@@ -142,10 +284,15 @@ function getCroppedCanvasDataUrl(canvas) {
|
||||
let croppedWidth = maxX - minX;
|
||||
let croppedHeight = maxY - minY;
|
||||
if (croppedWidth < 0 || croppedHeight < 0) return null;
|
||||
let cuttedImageData = originalCtx.getImageData(minX, minY, croppedWidth, croppedHeight);
|
||||
let cuttedImageData = originalCtx.getImageData(
|
||||
minX,
|
||||
minY,
|
||||
croppedWidth,
|
||||
croppedHeight
|
||||
);
|
||||
|
||||
let croppedCanvas = document.createElement('canvas'),
|
||||
croppedCtx = croppedCanvas.getContext('2d');
|
||||
let croppedCanvas = document.createElement("canvas"),
|
||||
croppedCtx = croppedCanvas.getContext("2d");
|
||||
|
||||
croppedCanvas.width = croppedWidth;
|
||||
croppedCanvas.height = croppedHeight;
|
||||
@@ -158,9 +305,13 @@ function resizeCanvas() {
|
||||
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
||||
var additionalFactor = 10;
|
||||
|
||||
signaturePadCanvas.width = signaturePadCanvas.offsetWidth * ratio * additionalFactor;
|
||||
signaturePadCanvas.height = signaturePadCanvas.offsetHeight * ratio * additionalFactor;
|
||||
signaturePadCanvas.getContext('2d').scale(ratio * additionalFactor, ratio * additionalFactor);
|
||||
signaturePadCanvas.width =
|
||||
signaturePadCanvas.offsetWidth * ratio * additionalFactor;
|
||||
signaturePadCanvas.height =
|
||||
signaturePadCanvas.offsetHeight * ratio * additionalFactor;
|
||||
signaturePadCanvas
|
||||
.getContext("2d")
|
||||
.scale(ratio * additionalFactor, ratio * additionalFactor);
|
||||
|
||||
signaturePad.clear();
|
||||
}
|
||||
@@ -174,12 +325,12 @@ new IntersectionObserver((entries, observer) => {
|
||||
new ResizeObserver(resizeCanvas).observe(signaturePadCanvas);
|
||||
|
||||
function addDraggableFromText() {
|
||||
const sigText = document.getElementById('sigText').value;
|
||||
const font = document.querySelector('select[name=font]').value;
|
||||
const sigText = document.getElementById("sigText").value;
|
||||
const font = document.querySelector("select[name=font]").value;
|
||||
const fontSize = 100;
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const canvas = document.createElement("canvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.font = `${fontSize}px ${font}`;
|
||||
const textWidth = ctx.measureText(sigText).width;
|
||||
const textHeight = fontSize;
|
||||
@@ -190,7 +341,7 @@ function addDraggableFromText() {
|
||||
canvas.height = paragraphs.length * textHeight * 1.35; // for tails
|
||||
ctx.font = `${fontSize}px ${font}`;
|
||||
|
||||
ctx.textBaseline = 'top';
|
||||
ctx.textBaseline = "top";
|
||||
|
||||
let y = 0;
|
||||
|
||||
@@ -212,8 +363,8 @@ async function goToFirstOrLastPage(page) {
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('download-pdf').addEventListener('click', async () => {
|
||||
const downloadButton = document.getElementById('download-pdf');
|
||||
document.getElementById("download-pdf").addEventListener("click", async () => {
|
||||
const downloadButton = document.getElementById("download-pdf");
|
||||
const originalContent = downloadButton.innerHTML;
|
||||
|
||||
downloadButton.disabled = true;
|
||||
@@ -224,13 +375,13 @@ document.getElementById('download-pdf').addEventListener('click', async () => {
|
||||
try {
|
||||
const modifiedPdf = await DraggableUtils.getOverlayedPdfDocument();
|
||||
const modifiedPdfBytes = await modifiedPdf.save();
|
||||
const blob = new Blob([modifiedPdfBytes], {type: 'application/pdf'});
|
||||
const link = document.createElement('a');
|
||||
const blob = new Blob([modifiedPdfBytes], { type: "application/pdf" });
|
||||
const link = document.createElement("a");
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = originalFileName + '_signed.pdf';
|
||||
link.download = originalFileName + "_signed.pdf";
|
||||
link.click();
|
||||
} catch (error) {
|
||||
console.error('Error downloading PDF:', error);
|
||||
console.error("Error downloading PDF:", error);
|
||||
} finally {
|
||||
downloadButton.disabled = false;
|
||||
downloadButton.innerHTML = originalContent;
|
||||
|
||||
@@ -222,30 +222,30 @@ document.getElementById('deletePipelineBtn').addEventListener('click', function(
|
||||
event.preventDefault();
|
||||
let pipelineName = document.getElementById('pipelineName').value;
|
||||
|
||||
if (confirm(deletePipelineText + pipelineName)) {
|
||||
removePipelineFromUI(pipelineName);
|
||||
let key = "#Pipeline-" + pipelineName;
|
||||
if (localStorage.getItem(key)) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
let pipelineSelect = document.getElementById("pipelineSelect");
|
||||
let modal = document.getElementById('pipelineSettingsModal');
|
||||
if (modal.style.display !== 'none') {
|
||||
$('#pipelineSettingsModal').modal('hide');
|
||||
}
|
||||
if (confirm(deletePipelineText + pipelineName)) {
|
||||
removePipelineFromUI(pipelineName);
|
||||
let key = "#Pipeline-" + pipelineName;
|
||||
if (localStorage.getItem(key)) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
let pipelineSelect = document.getElementById("pipelineSelect");
|
||||
let modal = document.getElementById('pipelineSettingsModal');
|
||||
if (modal.style.display !== 'none') {
|
||||
$('#pipelineSettingsModal').modal('hide');
|
||||
}
|
||||
|
||||
if (pipelineSelect.options.length > 0) {
|
||||
pipelineSelect.selectedIndex = 0;
|
||||
pipelineSelect.dispatchEvent(new Event('change'));
|
||||
}
|
||||
if (pipelineSelect.options.length > 0) {
|
||||
pipelineSelect.selectedIndex = 0;
|
||||
pipelineSelect.dispatchEvent(new Event('change'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function removePipelineFromUI(pipelineName) {
|
||||
let pipelineSelect = document.getElementById("pipelineSelect");
|
||||
for (let i = 0; i < pipelineSelect.options.length; i++) {
|
||||
console.log(pipelineSelect.options[i])
|
||||
console.log("list " + pipelineSelect.options[i].innerText + " vs " + pipelineName)
|
||||
console.log(pipelineSelect.options[i])
|
||||
console.log("list " + pipelineSelect.options[i].innerText + " vs " + pipelineName)
|
||||
if (pipelineSelect.options[i].innerText === pipelineName) {
|
||||
pipelineSelect.remove(i);
|
||||
break;
|
||||
@@ -414,22 +414,22 @@ document.getElementById("addOperationBtn").addEventListener("click", function ()
|
||||
parameterInput.type = "checkbox";
|
||||
if (defaultValue === true) parameterInput.checked = true;
|
||||
break;
|
||||
case "array":
|
||||
// If parameter.schema.format === 'binary' is to be checked, it should be checked here
|
||||
parameterInput = document.createElement("textarea");
|
||||
parameterInput.placeholder = 'Enter a JSON formatted array, e.g., ["item1", "item2", "item3"]';
|
||||
parameterInput.className = "form-control";
|
||||
break;
|
||||
case "object":
|
||||
parameterInput = document.createElement("textarea");
|
||||
parameterInput.placeholder = 'Enter a JSON formatted object, e.g., {"key": "value"} If this is a fileInput, it is not currently supported';
|
||||
parameterInput.className = "form-control";
|
||||
break;
|
||||
default:
|
||||
parameterInput = document.createElement("input");
|
||||
parameterInput.type = "text";
|
||||
parameterInput.className = "form-control";
|
||||
if (defaultValue !== undefined) parameterInput.value = defaultValue;
|
||||
case "array":
|
||||
// If parameter.schema.format === 'binary' is to be checked, it should be checked here
|
||||
parameterInput = document.createElement("textarea");
|
||||
parameterInput.placeholder = 'Enter a JSON formatted array, e.g., ["item1", "item2", "item3"]';
|
||||
parameterInput.className = "form-control";
|
||||
break;
|
||||
case "object":
|
||||
parameterInput = document.createElement("textarea");
|
||||
parameterInput.placeholder = 'Enter a JSON formatted object, e.g., {"key": "value"} If this is a fileInput, it is not currently supported';
|
||||
parameterInput.className = "form-control";
|
||||
break;
|
||||
default:
|
||||
parameterInput = document.createElement("input");
|
||||
parameterInput.type = "text";
|
||||
parameterInput.className = "form-control";
|
||||
if (defaultValue !== undefined) parameterInput.value = defaultValue;
|
||||
}
|
||||
}
|
||||
parameterInput.id = parameter.name;
|
||||
@@ -481,21 +481,21 @@ document.getElementById("addOperationBtn").addEventListener("click", function ()
|
||||
break;
|
||||
case "array":
|
||||
case "object":
|
||||
if (value === null || value === "") {
|
||||
settings[parameter.name] = "";
|
||||
} else {
|
||||
try {
|
||||
const parsedValue = JSON.parse(value);
|
||||
if (Array.isArray(parsedValue)) {
|
||||
settings[parameter.name] = parsedValue;
|
||||
} else {
|
||||
settings[parameter.name] = value;
|
||||
}
|
||||
} catch (e) {
|
||||
settings[parameter.name] = value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (value === null || value === "") {
|
||||
settings[parameter.name] = "";
|
||||
} else {
|
||||
try {
|
||||
const parsedValue = JSON.parse(value);
|
||||
if (Array.isArray(parsedValue)) {
|
||||
settings[parameter.name] = parsedValue;
|
||||
} else {
|
||||
settings[parameter.name] = value;
|
||||
}
|
||||
} catch (e) {
|
||||
settings[parameter.name] = value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
settings[parameter.name] = value;
|
||||
}
|
||||
@@ -686,13 +686,13 @@ async function processPipelineConfig(configString) {
|
||||
case "text":
|
||||
case "textarea":
|
||||
default:
|
||||
var value = operationConfig.parameters[parameterName]
|
||||
if (typeof value !== 'string') {
|
||||
input.value = JSON.stringify(value) ;
|
||||
} else {
|
||||
input.value = value;
|
||||
}
|
||||
|
||||
var value = operationConfig.parameters[parameterName]
|
||||
if (typeof value !== 'string') {
|
||||
input.value = JSON.stringify(value) ;
|
||||
} else {
|
||||
input.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4919,6 +4919,26 @@ dialog :link {
|
||||
left: 3px;
|
||||
top: var(--toolbar-height);
|
||||
}
|
||||
|
||||
#toolbarViewerRight > div.splitToolbarButton .btn-tooltip {
|
||||
bottom: unset !important;
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
#man-shape-redact {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#man-shape-redact .btn-tooltip {
|
||||
bottom: 100%;
|
||||
left: -5px;
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
#redactionsPaletteContainer .btn-tooltip {
|
||||
white-space: normal !important;
|
||||
hyphens: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 885px) {
|
||||
|
||||
31
src/main/resources/templates/convert/pdf-to-markdown.html
Normal file
31
src/main/resources/templates/convert/pdf-to-markdown.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
|
||||
<head>
|
||||
<th:block th:insert="~{fragments/common :: head(title=#{PDFToMarkdown.title}, header=#{PDFToMarkdown.header})}"></th:block>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<th:block th:insert="~{fragments/common :: game}"></th:block>
|
||||
<div id="page-container">
|
||||
<div id="content-wrap">
|
||||
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon convert">markdown_copy</span>
|
||||
<span class="tool-header-text" th:text="#{PDFToMarkdown.header}"></span>
|
||||
</div>
|
||||
<form method="post" enctype="multipart/form-data" th:action="@{'/api/v1/convert/pdf/markdown'}">
|
||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='.pdf')}"></div>
|
||||
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{PDFToMarkdown.submit}"></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user