Compare commits
5 Commits
v0.34.0
...
Frooodle-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d19d87b8f0 | ||
|
|
a22ce69bc3 | ||
|
|
59b60ebfb8 | ||
|
|
b9a014b5c7 | ||
|
|
9e30918aae |
117
.github/scripts/check_language_properties.py
vendored
117
.github/scripts/check_language_properties.py
vendored
@@ -9,9 +9,8 @@ The script also provides functionality to update the translation files to match
|
|||||||
adjusting the format.
|
adjusting the format.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
python check_language_properties.py --reference-file <path_to_reference_file> --branch <branch_name> [--actor <actor_name>] [--files <list_of_changed_files>]
|
python script_name.py --reference-file <path_to_reference_file> --branch <branch_name> [--files <list_of_changed_files>]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
@@ -19,10 +18,6 @@ import argparse
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
# Maximum size for properties files (e.g., 200 KB)
|
|
||||||
MAX_FILE_SIZE = 200 * 1024
|
|
||||||
|
|
||||||
|
|
||||||
def parse_properties_file(file_path):
|
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 list of objects (including comments, empty lines, and line numbers)."""
|
||||||
properties_list = []
|
properties_list = []
|
||||||
@@ -100,7 +95,7 @@ def write_json_file(file_path, updated_properties):
|
|||||||
def update_missing_keys(reference_file, file_list, branch=""):
|
def update_missing_keys(reference_file, file_list, branch=""):
|
||||||
reference_properties = parse_properties_file(reference_file)
|
reference_properties = parse_properties_file(reference_file)
|
||||||
for file_path in file_list:
|
for file_path in file_list:
|
||||||
basename_current_file = os.path.basename(os.path.join(branch, file_path))
|
basename_current_file = os.path.basename(branch + file_path)
|
||||||
if (
|
if (
|
||||||
basename_current_file == os.path.basename(reference_file)
|
basename_current_file == os.path.basename(reference_file)
|
||||||
or not file_path.endswith(".properties")
|
or not file_path.endswith(".properties")
|
||||||
@@ -108,7 +103,7 @@ def update_missing_keys(reference_file, file_list, branch=""):
|
|||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
current_properties = parse_properties_file(os.path.join(branch, file_path))
|
current_properties = parse_properties_file(branch + file_path)
|
||||||
updated_properties = []
|
updated_properties = []
|
||||||
for ref_entry in reference_properties:
|
for ref_entry in reference_properties:
|
||||||
ref_entry_copy = copy.deepcopy(ref_entry)
|
ref_entry_copy = copy.deepcopy(ref_entry)
|
||||||
@@ -119,79 +114,60 @@ def update_missing_keys(reference_file, file_list, branch=""):
|
|||||||
if ref_entry_copy["key"] == current_entry["key"]:
|
if ref_entry_copy["key"] == current_entry["key"]:
|
||||||
ref_entry_copy["value"] = current_entry["value"]
|
ref_entry_copy["value"] = current_entry["value"]
|
||||||
updated_properties.append(ref_entry_copy)
|
updated_properties.append(ref_entry_copy)
|
||||||
write_json_file(os.path.join(branch, file_path), updated_properties)
|
write_json_file(branch + file_path, updated_properties)
|
||||||
|
|
||||||
|
|
||||||
def check_for_missing_keys(reference_file, file_list, branch):
|
def check_for_missing_keys(reference_file, file_list, branch):
|
||||||
update_missing_keys(reference_file, file_list, branch)
|
update_missing_keys(reference_file, file_list, branch + "/")
|
||||||
|
|
||||||
|
|
||||||
def read_properties(file_path):
|
def read_properties(file_path):
|
||||||
if os.path.isfile(file_path) and os.path.exists(file_path):
|
with open(file_path, "r", encoding="utf-8") as file:
|
||||||
with open(file_path, "r", encoding="utf-8") as file:
|
return file.read().splitlines()
|
||||||
return file.read().splitlines()
|
|
||||||
return [""]
|
|
||||||
|
|
||||||
|
|
||||||
def check_for_differences(reference_file, file_list, branch, actor):
|
def check_for_differences(reference_file, file_list, branch):
|
||||||
reference_branch = reference_file.split("/")[0]
|
reference_branch = reference_file.split("/")[0]
|
||||||
basename_reference_file = os.path.basename(reference_file)
|
basename_reference_file = os.path.basename(reference_file)
|
||||||
|
|
||||||
report = []
|
report = []
|
||||||
report.append(f"#### 🔄 Reference Branch: `{reference_branch}`")
|
report.append(
|
||||||
|
f"### 📋 Checking with the file `{basename_reference_file}` from the `{reference_branch}` - Checking the `{branch}`"
|
||||||
|
)
|
||||||
reference_lines = read_properties(reference_file)
|
reference_lines = read_properties(reference_file)
|
||||||
has_differences = False
|
has_differences = False
|
||||||
|
|
||||||
only_reference_file = True
|
only_reference_file = True
|
||||||
|
|
||||||
file_arr = file_list
|
for file_path in file_list:
|
||||||
|
basename_current_file = os.path.basename(branch + "/" + file_path)
|
||||||
if len(file_list) == 1:
|
|
||||||
file_arr = file_list[0].split()
|
|
||||||
base_dir = os.path.abspath(os.path.join(os.getcwd(), "src", "main", "resources"))
|
|
||||||
|
|
||||||
for file_path in file_arr:
|
|
||||||
absolute_path = os.path.abspath(file_path)
|
|
||||||
# Verify that file is within the expected directory
|
|
||||||
if not absolute_path.startswith(base_dir):
|
|
||||||
raise ValueError(f"Unsafe file found: {file_path}")
|
|
||||||
# Verify file size before processing
|
|
||||||
if os.path.getsize(os.path.join(branch, file_path)) > MAX_FILE_SIZE:
|
|
||||||
raise ValueError(
|
|
||||||
f"The file {file_path} is too large and could pose a security risk."
|
|
||||||
)
|
|
||||||
|
|
||||||
basename_current_file = os.path.basename(os.path.join(branch, file_path))
|
|
||||||
if (
|
if (
|
||||||
basename_current_file == basename_reference_file
|
basename_current_file == basename_reference_file
|
||||||
or not file_path.startswith(
|
|
||||||
os.path.join("src", "main", "resources", "messages_")
|
|
||||||
)
|
|
||||||
or not file_path.endswith(".properties")
|
or not file_path.endswith(".properties")
|
||||||
or not basename_current_file.startswith("messages_")
|
or not basename_current_file.startswith("messages_")
|
||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
only_reference_file = False
|
only_reference_file = False
|
||||||
report.append(f"#### 📃 **File Check:** `{basename_current_file}`")
|
report.append(f"#### 🗂️ **Checking File:** `{basename_current_file}`...")
|
||||||
current_lines = read_properties(os.path.join(branch, file_path))
|
current_lines = read_properties(branch + "/" + file_path)
|
||||||
reference_line_count = len(reference_lines)
|
reference_line_count = len(reference_lines)
|
||||||
current_line_count = len(current_lines)
|
current_line_count = len(current_lines)
|
||||||
|
|
||||||
if reference_line_count != current_line_count:
|
if reference_line_count != current_line_count:
|
||||||
report.append("")
|
report.append("")
|
||||||
report.append("1. **Test Status:** ❌ **_Failed_**")
|
report.append("- **Test 1 Status:** ❌ Failed")
|
||||||
report.append(" - **Issue:**")
|
|
||||||
has_differences = True
|
has_differences = True
|
||||||
if reference_line_count > current_line_count:
|
if reference_line_count > current_line_count:
|
||||||
report.append(
|
report.append(
|
||||||
f" - **_Mismatched line count_**: {reference_line_count} (reference) vs {current_line_count} (current). Comments, empty lines, or translation strings are missing."
|
f" - **Issue:** Missing lines! Comments, empty lines, or translation strings are missing. Details: {reference_line_count} (reference) vs {current_line_count} (current)."
|
||||||
)
|
)
|
||||||
elif reference_line_count < current_line_count:
|
elif reference_line_count < current_line_count:
|
||||||
report.append(
|
report.append(
|
||||||
f" - **_Too many lines_**: {reference_line_count} (reference) vs {current_line_count} (current). Please verify if there is an additional line that needs to be removed."
|
f" - **Issue:** Too many lines! Check your translation files! Details: {reference_line_count} (reference) vs {current_line_count} (current)."
|
||||||
)
|
)
|
||||||
|
# update_missing_keys(reference_file, [file_path], branch + "/")
|
||||||
else:
|
else:
|
||||||
report.append("1. **Test Status:** ✅ **_Passed_**")
|
report.append("- **Test 1 Status:** ✅ Passed")
|
||||||
|
|
||||||
# Check for missing or extra keys
|
# Check for missing or extra keys
|
||||||
current_keys = []
|
current_keys = []
|
||||||
@@ -216,42 +192,32 @@ def check_for_differences(reference_file, file_list, branch, actor):
|
|||||||
has_differences = True
|
has_differences = True
|
||||||
missing_keys_str = "`, `".join(missing_keys_list)
|
missing_keys_str = "`, `".join(missing_keys_list)
|
||||||
extra_keys_str = "`, `".join(extra_keys_list)
|
extra_keys_str = "`, `".join(extra_keys_list)
|
||||||
report.append("2. **Test Status:** ❌ **_Failed_**")
|
report.append("- **Test 2 Status:** ❌ Failed")
|
||||||
report.append(" - **Issue:**")
|
|
||||||
if missing_keys_list:
|
if missing_keys_list:
|
||||||
spaces_keys_list = []
|
|
||||||
for key in missing_keys_list:
|
|
||||||
if " " in key:
|
|
||||||
spaces_keys_list.append(key)
|
|
||||||
if spaces_keys_list:
|
|
||||||
spaces_keys_str = "`, `".join(spaces_keys_list)
|
|
||||||
report.append(
|
|
||||||
f" - **_Keys containing unnecessary spaces_**: `{spaces_keys_str}`!"
|
|
||||||
)
|
|
||||||
report.append(
|
report.append(
|
||||||
f" - **_Extra keys in `{basename_current_file}`_**: `{missing_keys_str}` that are not present in **_`{basename_reference_file}`_**."
|
f" - **Issue:** There are keys in ***{basename_current_file}*** `{missing_keys_str}` that are not present in ***{basename_reference_file}***!"
|
||||||
)
|
)
|
||||||
if extra_keys_list:
|
if extra_keys_list:
|
||||||
report.append(
|
report.append(
|
||||||
f" - **_Missing keys in `{basename_reference_file}`_**: `{extra_keys_str}` that are not present in **_`{basename_current_file}`_**."
|
f" - **Issue:** There are keys in ***{basename_reference_file}*** `{extra_keys_str}` that are not present in ***{basename_current_file}***!"
|
||||||
)
|
)
|
||||||
|
# update_missing_keys(reference_file, [file_path], branch + "/")
|
||||||
else:
|
else:
|
||||||
report.append("2. **Test Status:** ✅ **_Passed_**")
|
report.append("- **Test 2 Status:** ✅ Passed")
|
||||||
|
# if has_differences:
|
||||||
|
# report.append("")
|
||||||
|
# report.append(f"#### 🚧 ***{basename_current_file}*** will be corrected...")
|
||||||
report.append("")
|
report.append("")
|
||||||
report.append("---")
|
report.append("---")
|
||||||
report.append("")
|
report.append("")
|
||||||
|
# update_file_list = glob.glob(branch + "/src/**/messages_*.properties", recursive=True)
|
||||||
|
# update_missing_keys(reference_file, update_file_list)
|
||||||
|
# report.append("---")
|
||||||
|
# report.append("")
|
||||||
if has_differences:
|
if has_differences:
|
||||||
report.append("## ❌ Overall Check Status: **_Failed_**")
|
report.append("## ❌ Overall Check Status: **_Failed_**")
|
||||||
report.append("")
|
|
||||||
report.append(
|
|
||||||
f"@{actor} please check your translation if it conforms to the standard. Follow the format of [messages_en_GB.properties](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties)"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
report.append("## ✅ Overall Check Status: **_Success_**")
|
report.append("## ✅ Overall Check Status: **_Success_**")
|
||||||
report.append("")
|
|
||||||
report.append(
|
|
||||||
f"Thanks @{actor} for your help in keeping the translations up to date."
|
|
||||||
)
|
|
||||||
|
|
||||||
if not only_reference_file:
|
if not only_reference_file:
|
||||||
print("\n".join(report))
|
print("\n".join(report))
|
||||||
@@ -259,11 +225,6 @@ def check_for_differences(reference_file, file_list, branch, actor):
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="Find missing keys")
|
parser = argparse.ArgumentParser(description="Find missing keys")
|
||||||
parser.add_argument(
|
|
||||||
"--actor",
|
|
||||||
required=False,
|
|
||||||
help="Actor from PR.",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--reference-file",
|
"--reference-file",
|
||||||
required=True,
|
required=True,
|
||||||
@@ -283,21 +244,11 @@ if __name__ == "__main__":
|
|||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Sanitize --actor input to avoid injection attacks
|
|
||||||
if args.actor:
|
|
||||||
args.actor = re.sub(r"[^a-zA-Z0-9_\\-]", "", args.actor)
|
|
||||||
|
|
||||||
# Sanitize --branch input to avoid injection attacks
|
|
||||||
if args.branch:
|
|
||||||
args.branch = re.sub(r"[^a-zA-Z0-9\\-]", "", args.branch)
|
|
||||||
|
|
||||||
file_list = args.files
|
file_list = args.files
|
||||||
if file_list is None:
|
if file_list is None:
|
||||||
file_list = glob.glob(
|
file_list = glob.glob(
|
||||||
os.path.join(
|
os.getcwd() + "/src/**/messages_*.properties", recursive=True
|
||||||
os.getcwd(), "src", "main", "resources", "messages_*.properties"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
update_missing_keys(args.reference_file, file_list)
|
update_missing_keys(args.reference_file, file_list)
|
||||||
else:
|
else:
|
||||||
check_for_differences(args.reference_file, file_list, args.branch, args.actor)
|
check_for_differences(args.reference_file, file_list, args.branch)
|
||||||
|
|||||||
77
.github/workflows/check_properties.yml
vendored
77
.github/workflows/check_properties.yml
vendored
@@ -6,10 +6,14 @@ on:
|
|||||||
paths:
|
paths:
|
||||||
- "src/main/resources/messages_*.properties"
|
- "src/main/resources/messages_*.properties"
|
||||||
push:
|
push:
|
||||||
branches: ["main"]
|
|
||||||
paths:
|
paths:
|
||||||
- "src/main/resources/messages_en_GB.properties"
|
- "src/main/resources/messages_en_GB.properties"
|
||||||
|
|
||||||
|
# Permissions required for the workflow
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-files:
|
check-files:
|
||||||
if: github.event_name == 'pull_request_target'
|
if: github.event_name == 'pull_request_target'
|
||||||
@@ -50,7 +54,10 @@ jobs:
|
|||||||
echo "Getting list of changed files from PR..."
|
echo "Getting list of changed files from PR..."
|
||||||
gh pr view ${{ github.event.pull_request.number }} --json files -q ".files[].path" | grep -E '^src/main/resources/messages_[a-zA-Z_]+\.properties$' > ../changed_files.txt
|
gh pr view ${{ github.event.pull_request.number }} --json files -q ".files[].path" | grep -E '^src/main/resources/messages_[a-zA-Z_]+\.properties$' > ../changed_files.txt
|
||||||
cd ..
|
cd ..
|
||||||
|
echo "Setting branch path..."
|
||||||
|
BRANCH_PATH="pr-branch"
|
||||||
|
|
||||||
|
echo "BRANCH_PATH=${BRANCH_PATH}" >> $GITHUB_ENV
|
||||||
echo "Processing changed files..."
|
echo "Processing changed files..."
|
||||||
mapfile -t CHANGED_FILES < changed_files.txt
|
mapfile -t CHANGED_FILES < changed_files.txt
|
||||||
|
|
||||||
@@ -58,6 +65,7 @@ jobs:
|
|||||||
echo "CHANGED_FILES=${CHANGED_FILES_STR}" >> $GITHUB_ENV
|
echo "CHANGED_FILES=${CHANGED_FILES_STR}" >> $GITHUB_ENV
|
||||||
|
|
||||||
echo "Changed files: ${CHANGED_FILES_STR}"
|
echo "Changed files: ${CHANGED_FILES_STR}"
|
||||||
|
echo "Branch: ${BRANCH_PATH}"
|
||||||
|
|
||||||
- name: Determine reference file
|
- name: Determine reference file
|
||||||
id: determine-file
|
id: determine-file
|
||||||
@@ -79,40 +87,31 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
echo "Running Python script to check files..."
|
echo "Running Python script to check files..."
|
||||||
python main-branch/.github/scripts/check_language_properties.py \
|
python main-branch/.github/scripts/check_language_properties.py \
|
||||||
--actor ${{ github.event.pull_request.user.login }} \
|
|
||||||
--reference-file "${REFERENCE_FILE}" \
|
--reference-file "${REFERENCE_FILE}" \
|
||||||
--branch pr-branch \
|
--branch "${BRANCH_PATH}" \
|
||||||
--files "${CHANGED_FILES[@]}" > result.txt || true
|
--files ${CHANGED_FILES} > failure.txt || true
|
||||||
|
|
||||||
- name: Capture output
|
- name: Capture output
|
||||||
id: capture-output
|
id: capture-output
|
||||||
run: |
|
run: |
|
||||||
if [ -f result.txt ] && [ -s result.txt ]; then
|
if [ -f failure.txt ] && [ -s failure.txt ]; then
|
||||||
echo "Test, capturing output..."
|
echo "Test failed, capturing output..."
|
||||||
SCRIPT_OUTPUT=$(cat result.txt)
|
ERROR_OUTPUT=$(cat failure.txt)
|
||||||
echo "SCRIPT_OUTPUT<<EOF" >> $GITHUB_ENV
|
echo "ERROR_OUTPUT<<EOF" >> $GITHUB_ENV
|
||||||
echo "$SCRIPT_OUTPUT" >> $GITHUB_ENV
|
echo "$ERROR_OUTPUT" >> $GITHUB_ENV
|
||||||
echo "EOF" >> $GITHUB_ENV
|
echo "EOF" >> $GITHUB_ENV
|
||||||
echo "${SCRIPT_OUTPUT}"
|
echo "${ERROR_OUTPUT}"
|
||||||
|
|
||||||
# Set FAIL_JOB to true if SCRIPT_OUTPUT contains ❌
|
|
||||||
if [[ "$SCRIPT_OUTPUT" == *"❌"* ]]; then
|
|
||||||
echo "FAIL_JOB=true" >> $GITHUB_ENV
|
|
||||||
else
|
|
||||||
echo "FAIL_JOB=false" >> $GITHUB_ENV
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
echo "No update found."
|
echo "No errors found."
|
||||||
echo "SCRIPT_OUTPUT=" >> $GITHUB_ENV
|
echo "ERROR_OUTPUT=" >> $GITHUB_ENV
|
||||||
echo "FAIL_JOB=false" >> $GITHUB_ENV
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Post comment on PR
|
- name: Post comment on PR
|
||||||
if: env.SCRIPT_OUTPUT != ''
|
if: env.ERROR_OUTPUT != ''
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
const { GITHUB_REPOSITORY, SCRIPT_OUTPUT } = process.env;
|
const { GITHUB_REPOSITORY, ERROR_OUTPUT } = process.env;
|
||||||
const [repoOwner, repoName] = GITHUB_REPOSITORY.split('/');
|
const [repoOwner, repoName] = GITHUB_REPOSITORY.split('/');
|
||||||
const prNumber = context.issue.number;
|
const prNumber = context.issue.number;
|
||||||
|
|
||||||
@@ -134,7 +133,7 @@ jobs:
|
|||||||
owner: repoOwner,
|
owner: repoOwner,
|
||||||
repo: repoName,
|
repo: repoName,
|
||||||
comment_id: comment.id,
|
comment_id: comment.id,
|
||||||
body: `## 🚀 Translation Verification Summary\n\n\n${SCRIPT_OUTPUT}\n`
|
body: `## 🚀 Translation Verification Summary\n\n\n${ERROR_OUTPUT}\n`
|
||||||
});
|
});
|
||||||
console.log("Updated existing comment.");
|
console.log("Updated existing comment.");
|
||||||
} else if (!comment) {
|
} else if (!comment) {
|
||||||
@@ -143,24 +142,33 @@ jobs:
|
|||||||
owner: repoOwner,
|
owner: repoOwner,
|
||||||
repo: repoName,
|
repo: repoName,
|
||||||
issue_number: prNumber,
|
issue_number: prNumber,
|
||||||
body: `## 🚀 Translation Verification Summary\n\n\n${SCRIPT_OUTPUT}\n`
|
body: `## 🚀 Translation Verification Summary\n\n\n${ERROR_OUTPUT}\n`
|
||||||
});
|
});
|
||||||
console.log("Created new comment.");
|
console.log("Created new comment.");
|
||||||
} else {
|
} else {
|
||||||
console.log("Comment update attempt denied. Actor does not match.");
|
console.log("Comment update attempt denied. Actor does not match.");
|
||||||
}
|
}
|
||||||
|
|
||||||
- name: Fail job if errors found
|
# - name: Set up git config
|
||||||
if: env.FAIL_JOB == 'true'
|
# run: |
|
||||||
run: |
|
# git config --global user.name "github-actions[bot]"
|
||||||
echo "Failing the job because errors were detected."
|
# git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||||
exit 1
|
|
||||||
|
# - name: Add translation keys
|
||||||
|
# run: |
|
||||||
|
# cd ${{ env.BRANCH_PATH }}
|
||||||
|
# git add src/main/resources/messages_*.properties
|
||||||
|
# git diff --staged --quiet || echo "CHANGES_DETECTED=true" >> $GITHUB_ENV
|
||||||
|
# git commit -m "Update translation files" || echo "No changes to commit"
|
||||||
|
# - name: Push
|
||||||
|
# if: env.CHANGES_DETECTED == 'true'
|
||||||
|
# run: |
|
||||||
|
# cd pr-branch
|
||||||
|
# git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.event.pull_request.head.repo.full_name }}.git
|
||||||
|
# git push origin ${{ github.head_ref }} || echo "Push failed: possibly no changes to push"
|
||||||
|
|
||||||
update-translations-main:
|
update-translations-main:
|
||||||
if: github.event_name == 'push'
|
if: github.event_name == 'push'
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
pull-requests: write
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@@ -192,7 +200,7 @@ jobs:
|
|||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
id: cpr
|
id: cpr
|
||||||
if: env.CHANGES_DETECTED == 'true'
|
if: env.CHANGES_DETECTED == 'true'
|
||||||
uses: peter-evans/create-pull-request@v7
|
uses: peter-evans/create-pull-request@v6
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
commit-message: "Update translation files"
|
commit-message: "Update translation files"
|
||||||
@@ -201,8 +209,6 @@ jobs:
|
|||||||
signoff: true
|
signoff: true
|
||||||
branch: update_translation_files
|
branch: update_translation_files
|
||||||
title: "Update translation files"
|
title: "Update translation files"
|
||||||
add-paths: |
|
|
||||||
src/main/resources/messages_*.properties
|
|
||||||
body: |
|
body: |
|
||||||
Auto-generated by [create-pull-request][1]
|
Auto-generated by [create-pull-request][1]
|
||||||
|
|
||||||
@@ -210,4 +216,3 @@ jobs:
|
|||||||
labels: Translation
|
labels: Translation
|
||||||
draft: false
|
draft: false
|
||||||
delete-branch: true
|
delete-branch: true
|
||||||
sign-commits: true
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Build the application
|
# Build the application
|
||||||
FROM gradle:8.11-jdk17 AS build
|
FROM gradle:8.7-jdk17 AS build
|
||||||
|
|
||||||
# Set the working directory
|
# Set the working directory
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|||||||
69
README.md
69
README.md
@@ -186,47 +186,46 @@ Certain functionality like `Sign` supports pre-saved files stored at `/customFil
|
|||||||
|
|
||||||
## Supported Languages
|
## Supported Languages
|
||||||
|
|
||||||
Stirling-PDF currently supports 37 languages!
|
Stirling-PDF currently supports 36 languages!
|
||||||
|
|
||||||
| Language | Progress |
|
| Language | Progress |
|
||||||
| -------------------------------------------- | -------------------------------------- |
|
| -------------------------------------------- | -------------------------------------- |
|
||||||
| Arabic (العربية) (ar_AR) |  |
|
| Arabic (العربية) (ar_AR) |  |
|
||||||
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
| Basque (Euskara) (eu_ES) |  |
|
||||||
| Basque (Euskara) (eu_ES) |  |
|
| Bulgarian (Български) (bg_BG) |  |
|
||||||
| Bulgarian (Български) (bg_BG) |  |
|
| Catalan (Català) (ca_CA) |  |
|
||||||
| Catalan (Català) (ca_CA) |  |
|
| Croatian (Hrvatski) (hr_HR) |  |
|
||||||
| Croatian (Hrvatski) (hr_HR) |  |
|
| Czech (Česky) (cs_CZ) |  |
|
||||||
| Czech (Česky) (cs_CZ) |  |
|
| Danish (Dansk) (da_DK) |  |
|
||||||
| Danish (Dansk) (da_DK) |  |
|
| Dutch (Nederlands) (nl_NL) |  |
|
||||||
| Dutch (Nederlands) (nl_NL) |  |
|
|
||||||
| English (English) (en_GB) |  |
|
| English (English) (en_GB) |  |
|
||||||
| English (US) (en_US) |  |
|
| English (US) (en_US) |  |
|
||||||
| French (Français) (fr_FR) |  |
|
| French (Français) (fr_FR) |  |
|
||||||
| German (Deutsch) (de_DE) |  |
|
| German (Deutsch) (de_DE) |  |
|
||||||
| Greek (Ελληνικά) (el_GR) |  |
|
| Greek (Ελληνικά) (el_GR) |  |
|
||||||
| Hindi (हिंदी) (hi_IN) |  |
|
| Hindi (हिंदी) (hi_IN) |  |
|
||||||
| Hungarian (Magyar) (hu_HU) |  |
|
| Hungarian (Magyar) (hu_HU) |  |
|
||||||
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
| Indonesian (Bahasa Indonesia) (id_ID) |  |
|
||||||
| Irish (Gaeilge) (ga_IE) |  |
|
| Irish (Gaeilge) (ga_IE) |  |
|
||||||
| Italian (Italiano) (it_IT) |  |
|
| Italian (Italiano) (it_IT) |  |
|
||||||
| Japanese (日本語) (ja_JP) |  |
|
| Japanese (日本語) (ja_JP) |  |
|
||||||
| Korean (한국어) (ko_KR) |  |
|
| Korean (한국어) (ko_KR) |  |
|
||||||
| Norwegian (Norsk) (no_NB) |  |
|
| Norwegian (Norsk) (no_NB) |  |
|
||||||
| Polish (Polski) (pl_PL) |  |
|
| Polish (Polski) (pl_PL) |  |
|
||||||
| Portuguese (Português) (pt_PT) |  |
|
| Portuguese (Português) (pt_PT) |  |
|
||||||
| Portuguese Brazilian (Português) (pt_BR) |  |
|
| Portuguese Brazilian (Português) (pt_BR) |  |
|
||||||
| Romanian (Română) (ro_RO) |  |
|
| Romanian (Română) (ro_RO) |  |
|
||||||
| Russian (Русский) (ru_RU) |  |
|
| Russian (Русский) (ru_RU) |  |
|
||||||
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
| Serbian Latin alphabet (Srpski) (sr_LATN_RS) |  |
|
||||||
| Simplified Chinese (简体中文) (zh_CN) |  |
|
| Simplified Chinese (简体中文) (zh_CN) |  |
|
||||||
| Slovakian (Slovensky) (sk_SK) |  |
|
| Slovakian (Slovensky) (sk_SK) |  |
|
||||||
| Spanish (Español) (es_ES) |  |
|
| Spanish (Español) (es_ES) |  |
|
||||||
| Swedish (Svenska) (sv_SE) |  |
|
| Swedish (Svenska) (sv_SE) |  |
|
||||||
| Thai (ไทย) (th_TH) |  |
|
| Thai (ไทย) (th_TH) |  |
|
||||||
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
| Traditional Chinese (繁體中文) (zh_TW) |  |
|
||||||
| Turkish (Türkçe) (tr_TR) |  |
|
| Turkish (Türkçe) (tr_TR) |  |
|
||||||
| Ukrainian (Українська) (uk_UA) |  |
|
| Ukrainian (Українська) (uk_UA) |  |
|
||||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||||
|
|
||||||
## Contributing (Creating Issues, Translations, Fixing Bugs, etc.)
|
## Contributing (Creating Issues, Translations, Fixing Bugs, etc.)
|
||||||
|
|
||||||
|
|||||||
26
build.gradle
26
build.gradle
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id "java"
|
id "java"
|
||||||
id "org.springframework.boot" version "3.4.0"
|
id "org.springframework.boot" version "3.3.5"
|
||||||
id "io.spring.dependency-management" version "1.1.6"
|
id "io.spring.dependency-management" version "1.1.6"
|
||||||
id "org.springdoc.openapi-gradle-plugin" version "1.8.0"
|
id "org.springdoc.openapi-gradle-plugin" version "1.8.0"
|
||||||
id "io.swagger.swaggerhub" version "1.3.2"
|
id "io.swagger.swaggerhub" version "1.3.2"
|
||||||
@@ -15,16 +15,16 @@ plugins {
|
|||||||
import com.github.jk1.license.render.*
|
import com.github.jk1.license.render.*
|
||||||
|
|
||||||
ext {
|
ext {
|
||||||
springBootVersion = "3.4.0"
|
springBootVersion = "3.3.5"
|
||||||
pdfboxVersion = "3.0.3"
|
pdfboxVersion = "3.0.3"
|
||||||
logbackVersion = "1.5.7"
|
logbackVersion = "1.5.7"
|
||||||
imageioVersion = "3.12.0"
|
imageioVersion = "3.12.0"
|
||||||
lombokVersion = "1.18.36"
|
lombokVersion = "1.18.36"
|
||||||
bouncycastleVersion = "1.79"
|
bouncycastleVersion = "1.78.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "stirling.software"
|
group = "stirling.software"
|
||||||
version = "0.34.0"
|
version = "0.33.1"
|
||||||
|
|
||||||
java {
|
java {
|
||||||
// 17 is lowest but we support and recommend 21
|
// 17 is lowest but we support and recommend 21
|
||||||
@@ -121,7 +121,7 @@ configurations.all {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
//security updates
|
//security updates
|
||||||
implementation "org.springframework:spring-webmvc:6.2.0"
|
implementation "org.springframework:spring-webmvc:6.1.14"
|
||||||
|
|
||||||
implementation("io.github.pixee:java-security-toolkit:1.2.0")
|
implementation("io.github.pixee:java-security-toolkit:1.2.0")
|
||||||
|
|
||||||
@@ -143,10 +143,11 @@ dependencies {
|
|||||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-oauth2-client:$springBootVersion"
|
||||||
|
|
||||||
implementation 'org.springframework.security:spring-security-saml2-service-provider:6.4.1'
|
implementation 'org.springframework.security:spring-security-saml2-service-provider:6.3.4'
|
||||||
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
|
//2.2.x requires rebuild of DB file.. need migration path
|
||||||
runtimeOnly "com.h2database:h2:2.3.232"
|
runtimeOnly "com.h2database:h2:2.1.214"
|
||||||
|
// implementation "com.h2database:h2:2.2.224"
|
||||||
constraints {
|
constraints {
|
||||||
implementation "org.opensaml:opensaml-core"
|
implementation "org.opensaml:opensaml-core"
|
||||||
implementation "org.opensaml:opensaml-saml-api"
|
implementation "org.opensaml:opensaml-saml-api"
|
||||||
@@ -202,19 +203,12 @@ dependencies {
|
|||||||
exclude group: "commons-logging", module: "commons-logging"
|
exclude group: "commons-logging", module: "commons-logging"
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/technology.tabula/tabula
|
|
||||||
implementation ('technology.tabula:tabula:1.0.5') {
|
|
||||||
exclude group: "org.slf4j", module: "slf4j-simple"
|
|
||||||
exclude group: "org.bouncycastle", module: "bcprov-jdk15on"
|
|
||||||
exclude group: "com.google.code.gson", module: "gson"
|
|
||||||
}
|
|
||||||
|
|
||||||
implementation 'org.apache.pdfbox:jbig2-imageio:3.0.4'
|
implementation 'org.apache.pdfbox:jbig2-imageio:3.0.4'
|
||||||
|
|
||||||
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
|
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
|
||||||
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
|
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
|
||||||
implementation "io.micrometer:micrometer-core:1.14.1"
|
implementation "io.micrometer:micrometer-core:1.13.6"
|
||||||
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
|
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
|
||||||
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
||||||
implementation "org.commonmark:commonmark:0.24.0"
|
implementation "org.commonmark:commonmark:0.24.0"
|
||||||
|
|||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -3,11 +3,6 @@ ignore = [
|
|||||||
'language.direction',
|
'language.direction',
|
||||||
]
|
]
|
||||||
|
|
||||||
[az_AZ]
|
|
||||||
ignore = [
|
|
||||||
'language.direction',
|
|
||||||
]
|
|
||||||
|
|
||||||
[bg_BG]
|
[bg_BG]
|
||||||
ignore = [
|
ignore = [
|
||||||
'language.direction',
|
'language.direction',
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ public class SecurityConfiguration {
|
|||||||
RelyingPartyRegistration rp =
|
RelyingPartyRegistration rp =
|
||||||
RelyingPartyRegistration.withRegistrationId(samlConf.getRegistrationId())
|
RelyingPartyRegistration.withRegistrationId(samlConf.getRegistrationId())
|
||||||
.signingX509Credentials((c) -> c.add(signingCredential))
|
.signingX509Credentials((c) -> c.add(signingCredential))
|
||||||
.assertingPartyMetadata(
|
.assertingPartyDetails(
|
||||||
(details) ->
|
(details) ->
|
||||||
details.entityId(samlConf.getIdpIssuer())
|
details.entityId(samlConf.getIdpIssuer())
|
||||||
.singleSignOnServiceLocation(
|
.singleSignOnServiceLocation(
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package stirling.software.SPDF.controller.api.converters;
|
package stirling.software.SPDF.controller.api.converters;
|
||||||
|
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.csv.CSVFormat;
|
|
||||||
import org.apache.commons.csv.QuoteMode;
|
|
||||||
import org.apache.pdfbox.Loader;
|
import org.apache.pdfbox.Loader;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.http.ContentDisposition;
|
import org.springframework.http.ContentDisposition;
|
||||||
@@ -18,36 +18,79 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.opencsv.CSVWriter;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
|
||||||
import stirling.software.SPDF.controller.api.CropController;
|
import stirling.software.SPDF.controller.api.CropController;
|
||||||
|
import stirling.software.SPDF.controller.api.strippers.PDFTableStripper;
|
||||||
import stirling.software.SPDF.model.api.extract.PDFFilePage;
|
import stirling.software.SPDF.model.api.extract.PDFFilePage;
|
||||||
import stirling.software.SPDF.pdf.FlexibleCSVWriter;
|
|
||||||
import technology.tabula.ObjectExtractor;
|
|
||||||
import technology.tabula.Page;
|
|
||||||
import technology.tabula.Table;
|
|
||||||
import technology.tabula.extractors.SpreadsheetExtractionAlgorithm;
|
|
||||||
import technology.tabula.writers.Writer;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/v1/convert")
|
@RequestMapping("/api/v1/convert")
|
||||||
@Tag(name = "Convert", description = "Convert APIs")
|
@Tag(name = "Convert", description = "Convert APIs")
|
||||||
public class ExtractCSVController {
|
public class ExtractCSVController {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ExtractCSVController.class);
|
private static final Logger logger = LoggerFactory.getLogger(CropController.class);
|
||||||
|
|
||||||
@PostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
|
@PostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
|
||||||
@Operation(summary = "Extracts a CSV document from a PDF", description = "This operation takes an input PDF file and returns CSV file of whole page. Input:PDF Output:CSV Type:SISO")
|
@Operation(
|
||||||
|
summary = "Extracts a CSV document from a PDF",
|
||||||
|
description =
|
||||||
|
"This operation takes an input PDF file and returns CSV file of whole page. Input:PDF Output:CSV Type:SISO")
|
||||||
public ResponseEntity<String> PdfToCsv(@ModelAttribute PDFFilePage form) throws Exception {
|
public ResponseEntity<String> PdfToCsv(@ModelAttribute PDFFilePage form) throws Exception {
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
|
ArrayList<String> tableData = new ArrayList<>();
|
||||||
|
int columnsCount = 0;
|
||||||
|
|
||||||
try (PDDocument document = Loader.loadPDF(form.getFileInput().getBytes())) {
|
try (PDDocument document = Loader.loadPDF(form.getFileInput().getBytes())) {
|
||||||
CSVFormat format = CSVFormat.EXCEL.builder().setEscape('"').setQuoteMode(QuoteMode.ALL).build();
|
final double res = 72; // PDF units are at 72 DPI
|
||||||
Writer csvWriter = new FlexibleCSVWriter(format);
|
PDFTableStripper stripper = new PDFTableStripper();
|
||||||
SpreadsheetExtractionAlgorithm sea = new SpreadsheetExtractionAlgorithm();
|
PDPage pdPage = document.getPage(form.getPageId() - 1);
|
||||||
try (ObjectExtractor extractor = new ObjectExtractor(document)) {
|
stripper.extractTable(pdPage);
|
||||||
Page page = extractor.extract(form.getPageId());
|
columnsCount = stripper.getColumns();
|
||||||
List<Table> tables = sea.extract(page);
|
for (int c = 0; c < columnsCount; ++c) {
|
||||||
csvWriter.write(writer, tables);
|
for (int r = 0; r < stripper.getRows(); ++r) {
|
||||||
|
tableData.add(stripper.getText(r, c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<String> notEmptyColumns = new ArrayList<>();
|
||||||
|
|
||||||
|
for (String item : tableData) {
|
||||||
|
if (!item.trim().isEmpty()) {
|
||||||
|
notEmptyColumns.add(item);
|
||||||
|
} else {
|
||||||
|
columnsCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> fullTable =
|
||||||
|
notEmptyColumns.stream()
|
||||||
|
.map(
|
||||||
|
(entity) ->
|
||||||
|
entity.replace('\n', ' ')
|
||||||
|
.replace('\r', ' ')
|
||||||
|
.trim()
|
||||||
|
.replaceAll("\\s{2,}", "|"))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
int rowsCount = fullTable.get(0).split("\\|").length;
|
||||||
|
|
||||||
|
ArrayList<String> headersList = getTableHeaders(columnsCount, fullTable);
|
||||||
|
ArrayList<String> recordList = getRecordsList(rowsCount, fullTable);
|
||||||
|
|
||||||
|
if (headersList.size() == 0 && recordList.size() == 0) {
|
||||||
|
throw new Exception("No table detected, no headers or records found");
|
||||||
|
}
|
||||||
|
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
try (CSVWriter csvWriter = new CSVWriter(writer)) {
|
||||||
|
csvWriter.writeNext(headersList.toArray(new String[0]));
|
||||||
|
for (String record : recordList) {
|
||||||
|
csvWriter.writeNext(record.split("\\|"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,12 +99,41 @@ public class ExtractCSVController {
|
|||||||
ContentDisposition.builder("attachment")
|
ContentDisposition.builder("attachment")
|
||||||
.filename(
|
.filename(
|
||||||
form.getFileInput()
|
form.getFileInput()
|
||||||
.getOriginalFilename()
|
.getOriginalFilename()
|
||||||
.replaceFirst("[.][^.]+$", "")
|
.replaceFirst("[.][^.]+$", "")
|
||||||
+ "_extracted.csv")
|
+ "_extracted.csv")
|
||||||
.build());
|
.build());
|
||||||
headers.setContentType(MediaType.parseMediaType("text/csv"));
|
headers.setContentType(MediaType.parseMediaType("text/csv"));
|
||||||
|
|
||||||
return ResponseEntity.ok().headers(headers).body(writer.toString());
|
return ResponseEntity.ok().headers(headers).body(writer.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ArrayList<String> getRecordsList(int rowsCounts, List<String> items) {
|
||||||
|
ArrayList<String> recordsList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int b = 1; b < rowsCounts; b++) {
|
||||||
|
StringBuilder strbldr = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < items.size(); i++) {
|
||||||
|
String[] parts = items.get(i).split("\\|");
|
||||||
|
strbldr.append(parts[b]);
|
||||||
|
if (i != items.size() - 1) {
|
||||||
|
strbldr.append("|");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recordsList.add(strbldr.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return recordsList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList<String> getTableHeaders(int columnsCount, List<String> items) {
|
||||||
|
ArrayList<String> resultList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < columnsCount; i++) {
|
||||||
|
String[] parts = items.get(i).split("\\|");
|
||||||
|
resultList.add(parts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,10 +98,10 @@ public class CertSignController {
|
|||||||
|
|
||||||
public CreateSignature(KeyStore keystore, char[] pin)
|
public CreateSignature(KeyStore keystore, char[] pin)
|
||||||
throws KeyStoreException,
|
throws KeyStoreException,
|
||||||
UnrecoverableKeyException,
|
UnrecoverableKeyException,
|
||||||
NoSuchAlgorithmException,
|
NoSuchAlgorithmException,
|
||||||
IOException,
|
IOException,
|
||||||
CertificateException {
|
CertificateException {
|
||||||
super(keystore, pin);
|
super(keystore, pin);
|
||||||
ClassPathResource resource = new ClassPathResource("static/images/signature.png");
|
ClassPathResource resource = new ClassPathResource("static/images/signature.png");
|
||||||
try (InputStream is = resource.getInputStream()) {
|
try (InputStream is = resource.getInputStream()) {
|
||||||
@@ -160,7 +160,8 @@ public class CertSignController {
|
|||||||
extState.setNonStrokingAlphaConstant(0.5f);
|
extState.setNonStrokingAlphaConstant(0.5f);
|
||||||
cs.setGraphicsStateParameters(extState);
|
cs.setGraphicsStateParameters(extState);
|
||||||
cs.transform(Matrix.getScaleInstance(0.08f, 0.08f));
|
cs.transform(Matrix.getScaleInstance(0.08f, 0.08f));
|
||||||
PDImageXObject img = PDImageXObject.createFromFileByExtension(logoFile, doc);
|
PDImageXObject img =
|
||||||
|
PDImageXObject.createFromFileByExtension(logoFile, doc);
|
||||||
cs.drawImage(img, 100, 0);
|
cs.drawImage(img, 100, 0);
|
||||||
cs.restoreGraphicsState();
|
cs.restoreGraphicsState();
|
||||||
}
|
}
|
||||||
@@ -208,7 +209,10 @@ public class CertSignController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
|
@PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
|
||||||
@Operation(summary = "Sign PDF with a Digital Certificate", description = "This endpoint accepts a PDF file, a digital certificate and related information to sign the PDF. It then returns the digitally signed PDF file. Input:PDF Output:PDF Type:SISO")
|
@Operation(
|
||||||
|
summary = "Sign PDF with a Digital Certificate",
|
||||||
|
description =
|
||||||
|
"This endpoint accepts a PDF file, a digital certificate and related information to sign the PDF. It then returns the digitally signed PDF file. Input:PDF Output:PDF Type:SISO")
|
||||||
public ResponseEntity<byte[]> signPDFWithCert(@ModelAttribute SignPDFWithCertRequest request)
|
public ResponseEntity<byte[]> signPDFWithCert(@ModelAttribute SignPDFWithCertRequest request)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
MultipartFile pdf = request.getFileInput();
|
MultipartFile pdf = request.getFileInput();
|
||||||
@@ -238,7 +242,7 @@ public class CertSignController {
|
|||||||
PrivateKey privateKey = getPrivateKeyFromPEM(privateKeyFile.getBytes(), password);
|
PrivateKey privateKey = getPrivateKeyFromPEM(privateKeyFile.getBytes(), password);
|
||||||
Certificate cert = (Certificate) getCertificateFromPEM(certFile.getBytes());
|
Certificate cert = (Certificate) getCertificateFromPEM(certFile.getBytes());
|
||||||
ks.setKeyEntry(
|
ks.setKeyEntry(
|
||||||
"alias", privateKey, password.toCharArray(), new Certificate[] { cert });
|
"alias", privateKey, password.toCharArray(), new Certificate[] {cert});
|
||||||
break;
|
break;
|
||||||
case "PKCS12":
|
case "PKCS12":
|
||||||
ks = KeyStore.getInstance("PKCS12");
|
ks = KeyStore.getInstance("PKCS12");
|
||||||
@@ -310,19 +314,22 @@ public class CertSignController {
|
|||||||
|
|
||||||
private PrivateKey getPrivateKeyFromPEM(byte[] pemBytes, String password)
|
private PrivateKey getPrivateKeyFromPEM(byte[] pemBytes, String password)
|
||||||
throws IOException, OperatorCreationException, PKCSException {
|
throws IOException, OperatorCreationException, PKCSException {
|
||||||
try (PEMParser pemParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(pemBytes)))) {
|
try (PEMParser pemParser =
|
||||||
|
new PEMParser(new InputStreamReader(new ByteArrayInputStream(pemBytes)))) {
|
||||||
Object pemObject = pemParser.readObject();
|
Object pemObject = pemParser.readObject();
|
||||||
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
|
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
|
||||||
PrivateKeyInfo pkInfo;
|
PrivateKeyInfo pkInfo;
|
||||||
if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo) {
|
if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo) {
|
||||||
InputDecryptorProvider decProv = new JceOpenSSLPKCS8DecryptorProviderBuilder()
|
InputDecryptorProvider decProv =
|
||||||
.build(password.toCharArray());
|
new JceOpenSSLPKCS8DecryptorProviderBuilder().build(password.toCharArray());
|
||||||
pkInfo = ((PKCS8EncryptedPrivateKeyInfo) pemObject).decryptPrivateKeyInfo(decProv);
|
pkInfo = ((PKCS8EncryptedPrivateKeyInfo) pemObject).decryptPrivateKeyInfo(decProv);
|
||||||
} else if (pemObject instanceof PEMEncryptedKeyPair) {
|
} else if (pemObject instanceof PEMEncryptedKeyPair) {
|
||||||
PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
|
PEMDecryptorProvider decProv =
|
||||||
pkInfo = ((PEMEncryptedKeyPair) pemObject)
|
new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
|
||||||
.decryptKeyPair(decProv)
|
pkInfo =
|
||||||
.getPrivateKeyInfo();
|
((PEMEncryptedKeyPair) pemObject)
|
||||||
|
.decryptKeyPair(decProv)
|
||||||
|
.getPrivateKeyInfo();
|
||||||
} else {
|
} else {
|
||||||
pkInfo = ((PEMKeyPair) pemObject).getPrivateKeyInfo();
|
pkInfo = ((PEMKeyPair) pemObject).getPrivateKeyInfo();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,327 @@
|
|||||||
|
package stirling.software.SPDF.controller.api.strippers;
|
||||||
|
|
||||||
|
import java.awt.Shape;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.fontbox.util.BoundingBox;
|
||||||
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
|
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||||
|
import org.apache.pdfbox.pdmodel.font.PDType3Font;
|
||||||
|
import org.apache.pdfbox.text.PDFTextStripper;
|
||||||
|
import org.apache.pdfbox.text.PDFTextStripperByArea;
|
||||||
|
import org.apache.pdfbox.text.TextPosition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to extract tabular data from a PDF. Works by making a first pass of the page to group all
|
||||||
|
* nearby text items together, and then inferring a 2D grid from these regions. Each table cell is
|
||||||
|
* then extracted using a PDFTextStripperByArea object.
|
||||||
|
*
|
||||||
|
* <p>Works best when headers are included in the detected region, to ensure representative text in
|
||||||
|
* every column.
|
||||||
|
*
|
||||||
|
* <p>Based upon DrawPrintTextLocations PDFBox example
|
||||||
|
* (https://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/util/DrawPrintTextLocations.java)
|
||||||
|
*
|
||||||
|
* @author Beldaz
|
||||||
|
*/
|
||||||
|
public class PDFTableStripper extends PDFTextStripper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will print the documents data, for each table cell.
|
||||||
|
*
|
||||||
|
* @param args The command line arguments.
|
||||||
|
* @throws IOException If there is an error parsing the document.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Used in methods derived from DrawPrintTextLocations
|
||||||
|
*/
|
||||||
|
private AffineTransform flipAT;
|
||||||
|
|
||||||
|
private AffineTransform rotateAT;
|
||||||
|
|
||||||
|
/** Regions updated by calls to writeString */
|
||||||
|
private Set<Rectangle2D> boxes;
|
||||||
|
|
||||||
|
// Border to allow when finding intersections
|
||||||
|
private double dx = 1.0; // This value works for me, feel free to tweak (or add setter)
|
||||||
|
private double dy = 0.000; // Rows of text tend to overlap, so need to extend
|
||||||
|
|
||||||
|
/** Region in which to find table (otherwise whole page) */
|
||||||
|
private Rectangle2D regionArea;
|
||||||
|
|
||||||
|
/** Number of rows in inferred table */
|
||||||
|
private int nRows = 0;
|
||||||
|
|
||||||
|
/** Number of columns in inferred table */
|
||||||
|
private int nCols = 0;
|
||||||
|
|
||||||
|
/** This is the object that does the text extraction */
|
||||||
|
private PDFTextStripperByArea regionStripper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1D intervals - used for calculateTableRegions()
|
||||||
|
*
|
||||||
|
* @author Beldaz
|
||||||
|
*/
|
||||||
|
public static class Interval {
|
||||||
|
double start;
|
||||||
|
double end;
|
||||||
|
|
||||||
|
public Interval(double start, double end) {
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Interval col) {
|
||||||
|
if (col.start < start) start = col.start;
|
||||||
|
if (col.end > end) end = col.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addTo(Interval x, LinkedList<Interval> columns) {
|
||||||
|
int p = 0;
|
||||||
|
Iterator<Interval> it = columns.iterator();
|
||||||
|
// Find where x should go
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Interval col = it.next();
|
||||||
|
if (x.end >= col.start) {
|
||||||
|
if (x.start <= col.end) { // overlaps
|
||||||
|
x.add(col);
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Interval col = it.next();
|
||||||
|
if (x.start > col.end) break;
|
||||||
|
x.add(col);
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
columns.add(p, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate a new PDFTableStripper object.
|
||||||
|
*
|
||||||
|
* @throws IOException If there is an error loading the properties.
|
||||||
|
*/
|
||||||
|
public PDFTableStripper() throws IOException {
|
||||||
|
super.setShouldSeparateByBeads(false);
|
||||||
|
regionStripper = new PDFTextStripperByArea();
|
||||||
|
regionStripper.setSortByPosition(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the region to group text by.
|
||||||
|
*
|
||||||
|
* @param rect The rectangle area to retrieve the text from.
|
||||||
|
*/
|
||||||
|
public void setRegion(Rectangle2D rect) {
|
||||||
|
regionArea = rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRows() {
|
||||||
|
return nRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColumns() {
|
||||||
|
return nCols;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the text for the region, this should be called after extractTable().
|
||||||
|
*
|
||||||
|
* @return The text that was identified in that region.
|
||||||
|
*/
|
||||||
|
public String getText(int row, int col) {
|
||||||
|
return regionStripper.getTextForRegion("el" + col + "x" + row);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void extractTable(PDPage pdPage) throws IOException {
|
||||||
|
setStartPage(getCurrentPageNo());
|
||||||
|
setEndPage(getCurrentPageNo());
|
||||||
|
|
||||||
|
boxes = new HashSet<Rectangle2D>();
|
||||||
|
// flip y-axis
|
||||||
|
flipAT = new AffineTransform();
|
||||||
|
flipAT.translate(0, pdPage.getBBox().getHeight());
|
||||||
|
flipAT.scale(1, -1);
|
||||||
|
|
||||||
|
// page may be rotated
|
||||||
|
rotateAT = new AffineTransform();
|
||||||
|
int rotation = pdPage.getRotation();
|
||||||
|
if (rotation != 0) {
|
||||||
|
PDRectangle mediaBox = pdPage.getMediaBox();
|
||||||
|
switch (rotation) {
|
||||||
|
case 90:
|
||||||
|
rotateAT.translate(mediaBox.getHeight(), 0);
|
||||||
|
break;
|
||||||
|
case 270:
|
||||||
|
rotateAT.translate(0, mediaBox.getWidth());
|
||||||
|
break;
|
||||||
|
case 180:
|
||||||
|
rotateAT.translate(mediaBox.getWidth(), mediaBox.getHeight());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rotateAT.rotate(Math.toRadians(rotation));
|
||||||
|
}
|
||||||
|
// Trigger processing of the document so that writeString is called.
|
||||||
|
try (Writer dummy = new OutputStreamWriter(new ByteArrayOutputStream())) {
|
||||||
|
super.output = dummy;
|
||||||
|
super.processPage(pdPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle2D[][] regions = calculateTableRegions();
|
||||||
|
|
||||||
|
// System.err.println("Drawing " + nCols + "x" + nRows + "="+ nRows*nCols + "
|
||||||
|
// regions");
|
||||||
|
for (int i = 0; i < nCols; ++i) {
|
||||||
|
for (int j = 0; j < nRows; ++j) {
|
||||||
|
final Rectangle2D region = regions[i][j];
|
||||||
|
regionStripper.addRegion("el" + i + "x" + j, region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
regionStripper.extractRegions(pdPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Infer a rectangular grid of regions from the boxes field.
|
||||||
|
*
|
||||||
|
* @return 2D array of table regions (as Rectangle2D objects). Note that some of these regions
|
||||||
|
* may have no content.
|
||||||
|
*/
|
||||||
|
private Rectangle2D[][] calculateTableRegions() {
|
||||||
|
|
||||||
|
// Build up a list of all table regions, based upon the populated
|
||||||
|
// regions of boxes field. Treats the horizontal and vertical extents
|
||||||
|
// of each box as distinct
|
||||||
|
LinkedList<Interval> columns = new LinkedList<Interval>();
|
||||||
|
LinkedList<Interval> rows = new LinkedList<Interval>();
|
||||||
|
|
||||||
|
for (Rectangle2D box : boxes) {
|
||||||
|
Interval x = new Interval(box.getMinX(), box.getMaxX());
|
||||||
|
Interval y = new Interval(box.getMinY(), box.getMaxY());
|
||||||
|
|
||||||
|
Interval.addTo(x, columns);
|
||||||
|
Interval.addTo(y, rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
nRows = rows.size();
|
||||||
|
nCols = columns.size();
|
||||||
|
Rectangle2D[][] regions = new Rectangle2D[nCols][nRows];
|
||||||
|
int i = 0;
|
||||||
|
// Label regions from top left, rather than the transformed orientation
|
||||||
|
for (Interval column : columns) {
|
||||||
|
int j = 0;
|
||||||
|
for (Interval row : rows) {
|
||||||
|
regions[nCols - i - 1][nRows - j - 1] =
|
||||||
|
new Rectangle2D.Double(
|
||||||
|
column.start,
|
||||||
|
row.start,
|
||||||
|
column.end - column.start,
|
||||||
|
row.end - row.start);
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register each character's bounding box, updating boxes field to maintain a list of all
|
||||||
|
* distinct groups of characters.
|
||||||
|
*
|
||||||
|
* <p>Overrides the default functionality of PDFTextStripper. Most of this is taken from
|
||||||
|
* DrawPrintTextLocations.java, with extra steps at end of main loop
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void writeString(String string, List<TextPosition> textPositions) throws IOException {
|
||||||
|
for (TextPosition text : textPositions) {
|
||||||
|
// glyph space -> user space
|
||||||
|
// note: text.getTextMatrix() is *not* the Text Matrix, it's the Text Rendering Matrix
|
||||||
|
AffineTransform at = text.getTextMatrix().createAffineTransform();
|
||||||
|
PDFont font = text.getFont();
|
||||||
|
BoundingBox bbox = font.getBoundingBox();
|
||||||
|
|
||||||
|
// advance width, bbox height (glyph space)
|
||||||
|
float xadvance =
|
||||||
|
font.getWidth(text.getCharacterCodes()[0]); // todo: should iterate all chars
|
||||||
|
Rectangle2D.Float rect =
|
||||||
|
new Rectangle2D.Float(0, bbox.getLowerLeftY(), xadvance, bbox.getHeight());
|
||||||
|
|
||||||
|
if (font instanceof PDType3Font) {
|
||||||
|
// bbox and font matrix are unscaled
|
||||||
|
at.concatenate(font.getFontMatrix().createAffineTransform());
|
||||||
|
} else {
|
||||||
|
// bbox and font matrix are already scaled to 1000
|
||||||
|
at.scale(1 / 1000f, 1 / 1000f);
|
||||||
|
}
|
||||||
|
Shape s = at.createTransformedShape(rect);
|
||||||
|
s = flipAT.createTransformedShape(s);
|
||||||
|
s = rotateAT.createTransformedShape(s);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Merge character's bounding box with boxes field
|
||||||
|
//
|
||||||
|
Rectangle2D bounds = s.getBounds2D();
|
||||||
|
// Pad sides to detect almost touching boxes
|
||||||
|
Rectangle2D hitbox = bounds.getBounds2D();
|
||||||
|
hitbox.add(bounds.getMinX() - dx, bounds.getMinY() - dy);
|
||||||
|
hitbox.add(bounds.getMaxX() + dx, bounds.getMaxY() + dy);
|
||||||
|
|
||||||
|
// Find all overlapping boxes
|
||||||
|
List<Rectangle2D> intersectList = new ArrayList<Rectangle2D>();
|
||||||
|
for (Rectangle2D box : boxes) {
|
||||||
|
if (box.intersects(hitbox)) {
|
||||||
|
intersectList.add(box);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine all touching boxes and update
|
||||||
|
// (NOTE: Potentially this could leave some overlapping boxes un-merged,
|
||||||
|
// but it's sufficient for now and get's fixed up in calculateTableRegions)
|
||||||
|
for (Rectangle2D box : intersectList) {
|
||||||
|
bounds.add(box);
|
||||||
|
boxes.remove(box);
|
||||||
|
}
|
||||||
|
boxes.add(bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method does nothing in this derived class, because beads and regions are incompatible.
|
||||||
|
* Beads are ignored when stripping by area.
|
||||||
|
*
|
||||||
|
* @param aShouldSeparateByBeads The new grouping of beads.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void setShouldSeparateByBeads(boolean aShouldSeparateByBeads) {}
|
||||||
|
|
||||||
|
/** Adapted from PDFTextStripperByArea {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
protected void processTextPosition(TextPosition text) {
|
||||||
|
if (regionArea != null && !regionArea.contains(text.getX(), text.getY())) {
|
||||||
|
// skip character
|
||||||
|
} else {
|
||||||
|
super.processTextPosition(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,9 +34,7 @@ public class DatabaseWebController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<FileInfo> backupList = databaseBackupHelper.getBackupList();
|
List<FileInfo> backupList = databaseBackupHelper.getBackupList();
|
||||||
model.addAttribute("backupFiles", backupList);
|
model.addAttribute("systemUpdate", backupList);
|
||||||
|
|
||||||
model.addAttribute("databaseVersion", databaseBackupHelper.getH2Version());
|
|
||||||
|
|
||||||
return "database";
|
return "database";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
package stirling.software.SPDF.pdf;
|
|
||||||
|
|
||||||
import org.apache.commons.csv.CSVFormat;
|
|
||||||
|
|
||||||
import technology.tabula.writers.CSVWriter;
|
|
||||||
|
|
||||||
public class FlexibleCSVWriter extends CSVWriter {
|
|
||||||
|
|
||||||
public FlexibleCSVWriter() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public FlexibleCSVWriter(CSVFormat csvFormat) {
|
|
||||||
super(csvFormat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,7 +24,7 @@ public class MetricsAggregatorService {
|
|||||||
this.postHogService = postHogService;
|
this.postHogService = postHogService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Scheduled(fixedRate = 1800000) // Run every 30 minutes
|
@Scheduled(fixedRate = 900000) // Run every 15 minutes
|
||||||
public void aggregateAndSendMetrics() {
|
public void aggregateAndSendMetrics() {
|
||||||
Map<String, Object> metrics = new HashMap<>();
|
Map<String, Object> metrics = new HashMap<>();
|
||||||
Search.in(meterRegistry)
|
Search.in(meterRegistry)
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import java.util.TimeZone;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.posthog.java.PostHog;
|
import com.posthog.java.PostHog;
|
||||||
@@ -27,25 +26,19 @@ import stirling.software.SPDF.model.ApplicationProperties;
|
|||||||
public class PostHogService {
|
public class PostHogService {
|
||||||
private final PostHog postHog;
|
private final PostHog postHog;
|
||||||
private final String uniqueId;
|
private final String uniqueId;
|
||||||
private final String appVersion;
|
|
||||||
private final ApplicationProperties applicationProperties;
|
private final ApplicationProperties applicationProperties;
|
||||||
private final UserServiceInterface userService;
|
private final UserServiceInterface userService;
|
||||||
private final Environment env;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public PostHogService(
|
public PostHogService(
|
||||||
PostHog postHog,
|
PostHog postHog,
|
||||||
@Qualifier("UUID") String uuid,
|
@Qualifier("UUID") String uuid,
|
||||||
@Qualifier("appVersion") String appVersion,
|
|
||||||
ApplicationProperties applicationProperties,
|
ApplicationProperties applicationProperties,
|
||||||
@Autowired(required = false) UserServiceInterface userService,
|
@Autowired(required = false) UserServiceInterface userService) {
|
||||||
Environment env) {
|
|
||||||
this.postHog = postHog;
|
this.postHog = postHog;
|
||||||
this.uniqueId = uuid;
|
this.uniqueId = uuid;
|
||||||
this.appVersion = appVersion;
|
|
||||||
this.applicationProperties = applicationProperties;
|
this.applicationProperties = applicationProperties;
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.env = env;
|
|
||||||
captureSystemInfo();
|
captureSystemInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,16 +64,6 @@ public class PostHogService {
|
|||||||
Map<String, Object> metrics = new HashMap<>();
|
Map<String, Object> metrics = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//Application version
|
|
||||||
metrics.put("app_version", appVersion);
|
|
||||||
String deploymentType = "JAR"; // default
|
|
||||||
if ("true".equalsIgnoreCase(env.getProperty("BROWSER_OPEN"))) {
|
|
||||||
deploymentType = "EXE";
|
|
||||||
} else if (isRunningInDocker()) {
|
|
||||||
deploymentType = "DOCKER";
|
|
||||||
}
|
|
||||||
metrics.put("deployment_type", deploymentType);
|
|
||||||
|
|
||||||
// System info
|
// System info
|
||||||
metrics.put("os_name", System.getProperty("os.name"));
|
metrics.put("os_name", System.getProperty("os.name"));
|
||||||
metrics.put("os_version", System.getProperty("os.version"));
|
metrics.put("os_version", System.getProperty("os.version"));
|
||||||
@@ -149,6 +132,7 @@ public class PostHogService {
|
|||||||
|
|
||||||
// Docker detection and stats
|
// Docker detection and stats
|
||||||
boolean isDocker = isRunningInDocker();
|
boolean isDocker = isRunningInDocker();
|
||||||
|
metrics.put("is_docker", isDocker);
|
||||||
if (isDocker) {
|
if (isDocker) {
|
||||||
metrics.put("docker_metrics", getDockerMetrics());
|
metrics.put("docker_metrics", getDockerMetrics());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:1200000}
|
|||||||
#spring.thymeleaf.prefix=file:/customFiles/templates/,classpath:/templates/
|
#spring.thymeleaf.prefix=file:/customFiles/templates/,classpath:/templates/
|
||||||
#spring.thymeleaf.cache=false
|
#spring.thymeleaf.cache=false
|
||||||
|
|
||||||
spring.datasource.url=jdbc:h2:file:./configs/stirling-pdf-DB-2.3.232;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
spring.datasource.url=jdbc:h2:file:./configs/stirling-pdf-DB;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
|
||||||
spring.datasource.driver-class-name=org.h2.Driver
|
spring.datasource.driver-class-name=org.h2.Driver
|
||||||
spring.datasource.username=sa
|
spring.datasource.username=sa
|
||||||
spring.datasource.password=
|
spring.datasource.password=
|
||||||
|
|||||||
@@ -81,11 +81,11 @@ page=صفحة
|
|||||||
pages=صفحات
|
pages=صفحات
|
||||||
loading=جارٍ التحميل...
|
loading=جارٍ التحميل...
|
||||||
addToDoc=إضافة إلى المستند
|
addToDoc=إضافة إلى المستند
|
||||||
reset=إعداة ضبط
|
reset=Reset
|
||||||
|
|
||||||
legal.privacy=سياسة الخصوصية
|
legal.privacy=سياسة الخصوصية
|
||||||
legal.terms=شروط الاستخدام
|
legal.terms=شروط الاستخدام
|
||||||
legal.accessibility=إمكانية الوصول
|
legal.accessibility=Accessibility
|
||||||
legal.cookie=سياسة ملفات تعريف الارتباط
|
legal.cookie=سياسة ملفات تعريف الارتباط
|
||||||
legal.impressum=بيان الهوية
|
legal.impressum=بيان الهوية
|
||||||
|
|
||||||
@@ -119,8 +119,8 @@ pipelineOptions.validateButton=تحقق
|
|||||||
########################
|
########################
|
||||||
enterpriseEdition.button=ترقية إلى محترف
|
enterpriseEdition.button=ترقية إلى محترف
|
||||||
enterpriseEdition.warning=هذه الخاصية متوفرة فقط للمستخدمين المحترفين.
|
enterpriseEdition.warning=هذه الخاصية متوفرة فقط للمستخدمين المحترفين.
|
||||||
enterpriseEdition.yamlAdvert=يدعم Stirling PDF Pro ملفات الإعدادات YAML وميزات SSO أخرى
|
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
|
||||||
enterpriseEdition.ssoAdvert=هل تبحث عن المزيد من ميزات إدارة المستخدمين؟ اطلع على Stirling PDF Pro
|
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
|
||||||
|
|
||||||
|
|
||||||
#################
|
#################
|
||||||
@@ -142,7 +142,7 @@ navbar.language=اللغات
|
|||||||
navbar.settings=إعدادات
|
navbar.settings=إعدادات
|
||||||
navbar.allTools=أدوات
|
navbar.allTools=أدوات
|
||||||
navbar.multiTool=أدوات متعددة
|
navbar.multiTool=أدوات متعددة
|
||||||
navbar.search=البحث
|
navbar.search=Search
|
||||||
navbar.sections.organize=تنظيم
|
navbar.sections.organize=تنظيم
|
||||||
navbar.sections.convertTo=تحويل الى PDF
|
navbar.sections.convertTo=تحويل الى PDF
|
||||||
navbar.sections.convertFrom=تحويل من PDF
|
navbar.sections.convertFrom=تحويل من PDF
|
||||||
@@ -247,8 +247,8 @@ database.fileNotFound=لم يتم العثور على الملف
|
|||||||
database.fileNullOrEmpty=يجب ألا يكون الملف فارغًا أو خاليًا
|
database.fileNullOrEmpty=يجب ألا يكون الملف فارغًا أو خاليًا
|
||||||
database.failedImportFile=فشل استيراد الملف
|
database.failedImportFile=فشل استيراد الملف
|
||||||
|
|
||||||
session.expired=لقد انتهت جلستك. يرجى تحديث الصفحة والمحاولة مرة أخرى
|
session.expired=Your session has expired. Please refresh the page and try again.
|
||||||
session.refreshPage=تحديث الصفحة
|
session.refreshPage=Refresh Page
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# HOME-PAGE #
|
# HOME-PAGE #
|
||||||
@@ -513,15 +513,15 @@ home.splitPdfByChapters.desc=قسم مستند PDF إلى ملفات متعدد
|
|||||||
splitPdfByChapters.tags=تجزئة، فصول، علامات تبويب، تنظيم
|
splitPdfByChapters.tags=تجزئة، فصول، علامات تبويب، تنظيم
|
||||||
|
|
||||||
#replace-invert-color
|
#replace-invert-color
|
||||||
replace-color.title=إستبدال-عكس اللون
|
replace-color.title=Replace-Invert-Color
|
||||||
replace-color.header=استبدال-عكس لون PDF
|
replace-color.header=استبدال-إلغاء مirro لون PDF
|
||||||
home.replaceColorPdf.title=إستبدال و عكس الألوان
|
home.replaceColorPdf.title=Replace and Invert Color
|
||||||
home.replaceColorPdf.desc=استبدال الألوان للنصوص والخلفيات في المستندات PDF وإلغاء تعكير اللون الكامل للمستند لتقليل حجم الملف
|
home.replaceColorPdf.desc=استبدال الألوان للنصوص والخلفيات في المستندات PDF وإلغاء تعكير اللون الكامل للمستند لتقليل حجم الملف
|
||||||
replaceColorPdf.tags=استبدال اللون، عمليات الصفحة، الخلفية، جانب الخادم
|
replaceColorPdf.tags=استبدال اللون، عمليات الصفحة، الخلفية، جانب الخادم
|
||||||
replace-color.selectText.1=خيارات استبدال أو عكس الألوان
|
replace-color.selectText.1=خيارات استبدال-إلغاء مirro لون
|
||||||
replace-color.selectText.2=افتراضي(ألوان التباين العالي الافتراضية)
|
replace-color.selectText.2=Default(Default high contrast colors)
|
||||||
replace-color.selectText.3=خصيصة (ألوان شخصية)
|
replace-color.selectText.3=خصيصة (ألوان شخصية)
|
||||||
replace-color.selectText.4=عكس كامل(عكس جميع الألوان)
|
replace-color.selectText.4=Full-Invert(Invert all colors)
|
||||||
replace-color.selectText.5=خيارات ألوان التباين العالي
|
replace-color.selectText.5=خيارات ألوان التباين العالي
|
||||||
replace-color.selectText.6=نص أبيض على خلفية سوداء
|
replace-color.selectText.6=نص أبيض على خلفية سوداء
|
||||||
replace-color.selectText.7=نص أسود على خلفية بيضاء
|
replace-color.selectText.7=نص أسود على خلفية بيضاء
|
||||||
@@ -818,12 +818,7 @@ sign.save=حفظ توقيع
|
|||||||
sign.personalSigs=توقيعات شخصية
|
sign.personalSigs=توقيعات شخصية
|
||||||
sign.sharedSigs=توقيعات مشتركة
|
sign.sharedSigs=توقيعات مشتركة
|
||||||
sign.noSavedSigs=لم يتم العثور على توقيعات محفوظة
|
sign.noSavedSigs=لم يتم العثور على توقيعات محفوظة
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=إصلاح
|
repair.title=إصلاح
|
||||||
@@ -940,27 +935,17 @@ pdfOrganiser.placeholder=(مثال: 1,3,2 أو 4-8,2,10-12 أو 2n-1)
|
|||||||
multiTool.title=أداة متعددة PDF
|
multiTool.title=أداة متعددة PDF
|
||||||
multiTool.header=أداة متعددة PDF
|
multiTool.header=أداة متعددة PDF
|
||||||
multiTool.uploadPrompts=اسم الملف
|
multiTool.uploadPrompts=اسم الملف
|
||||||
multiTool.selectAll=تحديد الكل
|
multiTool.selectAll=Select All
|
||||||
multiTool.deselectAll=إلغاء تحديد الكل
|
multiTool.deselectAll=Deselect All
|
||||||
multiTool.selectPages=تحديد الصفحة
|
multiTool.selectPages=Page Select
|
||||||
multiTool.selectedPages=الصفحات المحددة
|
multiTool.selectedPages=Selected Pages
|
||||||
multiTool.page=صفحة
|
multiTool.page=Page
|
||||||
multiTool.deleteSelected=حذف المحدد
|
multiTool.deleteSelected=Delete Selected
|
||||||
multiTool.downloadAll=تصدير
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=تصدير المحدد
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=إدراج فاصل صفحات
|
|
||||||
multiTool.addFile=إضافة ملف
|
|
||||||
multiTool.rotateLeft=تدوير إلى اليسار
|
|
||||||
multiTool.rotateRight=تدوير إلى اليمين
|
|
||||||
multiTool.split=تقسيم
|
|
||||||
multiTool.moveLeft=تحريك إلى اليسار
|
|
||||||
multiTool.moveRight=تحريك إلى اليمين
|
|
||||||
multiTool.delete=حذف
|
|
||||||
multiTool.dragDropMessage=الصفحات المحددة
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=هذه الميزة متوفرة في <a href="{0}">صفحة الأدوات المتعددة</a> لدينا. اطلع عليها للحصول على واجهة مستخدم محسّنة لكل صفحة وميزات إضافية!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=عرض PDF
|
viewPdf.title=عرض PDF
|
||||||
@@ -1254,9 +1239,9 @@ splitByChapters.title=تجزئة المستند حسب الفصول
|
|||||||
splitByChapters.header=تجزئة المستند حسب الفصول
|
splitByChapters.header=تجزئة المستند حسب الفصول
|
||||||
splitByChapters.bookmarkLevel=مستوى العلامات التذكارية
|
splitByChapters.bookmarkLevel=مستوى العلامات التذكارية
|
||||||
splitByChapters.includeMetadata=شامل البيانات المرفقة
|
splitByChapters.includeMetadata=شامل البيانات المرفقة
|
||||||
splitByChapters.allowDuplicates=السماح بالتكرار
|
splitByChapters.allowDuplicates=Allow Duplicates
|
||||||
splitByChapters.desc.1=هذه الأداة تقوم بتقسيم ملف PDF إلى عدة ملفات PDF استناداً إلى بنية فصوله
|
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
|
||||||
splitByChapters.desc.2=مستوى الإشارة المرجعية: اختر مستوى الإشارات المرجعية التي تريد استخدامها للتقسيم (0 للمستوى الأعلى، 1 للمستوى الثاني، وما إلى ذلك)
|
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
|
||||||
splitByChapters.desc.3=تمثيل البيانات الأصلية: إذا تم اختيارها، سترمز البيانات المرجعية الأصلية إلى كل PDF مجزأ.
|
splitByChapters.desc.3=تمثيل البيانات الأصلية: إذا تم اختيارها، سترمز البيانات المرجعية الأصلية إلى كل PDF مجزأ.
|
||||||
splitByChapters.desc.4=سماح بالتكرار: إذا تم اختياره، يسمح بوجود معاينات متعددة في الصفحة نفسها لخلق ملفات PDF منفصلة.
|
splitByChapters.desc.4=سماح بالتكرار: إذا تم اختياره، يسمح بوجود معاينات متعددة في الصفحة نفسها لخلق ملفات PDF منفصلة.
|
||||||
splitByChapters.submit=تقطيع ملف PDF
|
splitByChapters.submit=تقطيع ملف PDF
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Поправи
|
repair.title=Поправи
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Desa Signatura
|
|||||||
sign.personalSigs=Signatures Personals
|
sign.personalSigs=Signatures Personals
|
||||||
sign.sharedSigs=Signatures Compartides
|
sign.sharedSigs=Signatures Compartides
|
||||||
sign.noSavedSigs=No s'han trobat signatures desades
|
sign.noSavedSigs=No s'han trobat signatures desades
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparar
|
repair.title=Reparar
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Uložit podpis
|
|||||||
sign.personalSigs=Osobní podpisy
|
sign.personalSigs=Osobní podpisy
|
||||||
sign.sharedSigs=Sdílené podpisy
|
sign.sharedSigs=Sdílené podpisy
|
||||||
sign.noSavedSigs=Nenašly se žádné uložené podpisy
|
sign.noSavedSigs=Nenašly se žádné uložené podpisy
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Opravit
|
repair.title=Opravit
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Gem Signatur
|
|||||||
sign.personalSigs=Personlige Signaturer
|
sign.personalSigs=Personlige Signaturer
|
||||||
sign.sharedSigs=Delte Signaturer
|
sign.sharedSigs=Delte Signaturer
|
||||||
sign.noSavedSigs=Ingen Gemte Signaturer Fundet
|
sign.noSavedSigs=Ingen Gemte Signaturer Fundet
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparér
|
repair.title=Reparér
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ page=Seite
|
|||||||
pages=Seiten
|
pages=Seiten
|
||||||
loading=Laden...
|
loading=Laden...
|
||||||
addToDoc=In Dokument hinzufügen
|
addToDoc=In Dokument hinzufügen
|
||||||
reset=Zurücksetzen
|
reset=Reset
|
||||||
|
|
||||||
legal.privacy=Datenschutz
|
legal.privacy=Datenschutz
|
||||||
legal.terms=AGB
|
legal.terms=AGB
|
||||||
@@ -818,12 +818,7 @@ sign.save=Signature speichern
|
|||||||
sign.personalSigs=Persönliche Signaturen
|
sign.personalSigs=Persönliche Signaturen
|
||||||
sign.sharedSigs=Geteilte Signaturen
|
sign.sharedSigs=Geteilte Signaturen
|
||||||
sign.noSavedSigs=Es wurden keine gespeicherten Signaturen gefunden
|
sign.noSavedSigs=Es wurden keine gespeicherten Signaturen gefunden
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparieren
|
repair.title=Reparieren
|
||||||
@@ -949,18 +944,8 @@ multiTool.deleteSelected=Auswahl löschen
|
|||||||
multiTool.downloadAll=Downloaden
|
multiTool.downloadAll=Downloaden
|
||||||
multiTool.downloadSelected=Auswahl downloaden
|
multiTool.downloadSelected=Auswahl downloaden
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=Diese Funktion ist auch auf unserer <a href="{0}">PDF-Multitool-Seite</a> verfügbar. Probieren Sie sie aus, denn sie bietet eine verbesserte Benutzeroberfläche und zusätzliche Funktionen!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=PDF anzeigen
|
viewPdf.title=PDF anzeigen
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Αποθήκευση Αλιάσης
|
|||||||
sign.personalSigs=Προσωπικές Αλιάσεις
|
sign.personalSigs=Προσωπικές Αλιάσεις
|
||||||
sign.sharedSigs=Μεταδότες Αλιάσεις
|
sign.sharedSigs=Μεταδότες Αλιάσεις
|
||||||
sign.noSavedSigs=Δεν βρέθηκαν αποθηκευμένες αλιάσεις
|
sign.noSavedSigs=Δεν βρέθηκαν αποθηκευμένες αλιάσεις
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Επιδιόρθωση
|
repair.title=Επιδιόρθωση
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Repair
|
repair.title=Repair
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Repair
|
repair.title=Repair
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Guardar Firma
|
|||||||
sign.personalSigs=Firmas Personales
|
sign.personalSigs=Firmas Personales
|
||||||
sign.sharedSigs=Firmas compartidas
|
sign.sharedSigs=Firmas compartidas
|
||||||
sign.noSavedSigs=No se encontraron firmas guardadas
|
sign.noSavedSigs=No se encontraron firmas guardadas
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparar
|
repair.title=Reparar
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Konpondu
|
repair.title=Konpondu
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ userNotFoundMessage=Utilisateur non trouvé.
|
|||||||
incorrectPasswordMessage=Le mot de passe actuel est incorrect.
|
incorrectPasswordMessage=Le mot de passe actuel est incorrect.
|
||||||
usernameExistsMessage=Le nouveau nom d'utilisateur existe déjà.
|
usernameExistsMessage=Le nouveau nom d'utilisateur existe déjà.
|
||||||
invalidUsernameMessage=Nom d'utilisateur invalide, le nom d'utilisateur ne peut contenir que des lettres, des chiffres et les caractères spéciaux suivants @._+- ou doit être une adresse e-mail valide.
|
invalidUsernameMessage=Nom d'utilisateur invalide, le nom d'utilisateur ne peut contenir que des lettres, des chiffres et les caractères spéciaux suivants @._+- ou doit être une adresse e-mail valide.
|
||||||
invalidPasswordMessage=Le mot de passe ne peut pas être vide et ne doit pas contenir d'espaces au début ou à la fin.
|
invalidPasswordMessage=Le mot de passe ne peut pas être vide et ne doit pas contenir d'espaces au début ou en fin.
|
||||||
confirmPasswordErrorMessage=Le nouveau mot de passe et sa confirmation doivent être identiques.
|
confirmPasswordErrorMessage=Nouveau Mot de passe et Confirmer le Nouveau Mot de passe doivent correspondre.
|
||||||
deleteCurrentUserMessage=Impossible de supprimer l'utilisateur actuellement connecté.
|
deleteCurrentUserMessage=Impossible de supprimer l'utilisateur actuellement connecté.
|
||||||
deleteUsernameExistsMessage=Le nom d'utilisateur n'existe pas et ne peut pas être supprimé.
|
deleteUsernameExistsMessage=Le nom d'utilisateur n'existe pas et ne peut pas être supprimé.
|
||||||
downgradeCurrentUserMessage=Impossible de rétrograder le rôle de l'utilisateur actuel.
|
downgradeCurrentUserMessage=Impossible de rétrograder le rôle de l'utilisateur actuel.
|
||||||
@@ -81,7 +81,7 @@ page=Page
|
|||||||
pages=Pages
|
pages=Pages
|
||||||
loading=Chargement...
|
loading=Chargement...
|
||||||
addToDoc=Ajouter au Document
|
addToDoc=Ajouter au Document
|
||||||
reset=Réinitialiser
|
reset=Reset
|
||||||
|
|
||||||
legal.privacy=Politique de Confidentialité
|
legal.privacy=Politique de Confidentialité
|
||||||
legal.terms=Conditions Générales
|
legal.terms=Conditions Générales
|
||||||
@@ -142,7 +142,7 @@ navbar.language=Langues
|
|||||||
navbar.settings=Paramètres
|
navbar.settings=Paramètres
|
||||||
navbar.allTools=Outils
|
navbar.allTools=Outils
|
||||||
navbar.multiTool=Outils Multiples
|
navbar.multiTool=Outils Multiples
|
||||||
navbar.search=Rechercher
|
navbar.search=Search
|
||||||
navbar.sections.organize=Organisation
|
navbar.sections.organize=Organisation
|
||||||
navbar.sections.convertTo=Convertir en PDF
|
navbar.sections.convertTo=Convertir en PDF
|
||||||
navbar.sections.convertFrom=Convertir depuis PDF
|
navbar.sections.convertFrom=Convertir depuis PDF
|
||||||
@@ -813,17 +813,12 @@ sign.draw=Dessiner une signature
|
|||||||
sign.text=Saisir de texte
|
sign.text=Saisir de texte
|
||||||
sign.clear=Effacer
|
sign.clear=Effacer
|
||||||
sign.add=Ajouter
|
sign.add=Ajouter
|
||||||
sign.saved=Sceaux enregistrées
|
sign.saved=Saved Signatures
|
||||||
sign.save=Enregistrer le sceau
|
sign.save=Enregistrer le sceau
|
||||||
sign.personalSigs=Sceaux personnels
|
sign.personalSigs=Sceaux personnels
|
||||||
sign.sharedSigs=Sceaux partagés
|
sign.sharedSigs=Sceaux partagés
|
||||||
sign.noSavedSigs=Aucun sceau enregistré trouvé
|
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Réparer
|
repair.title=Réparer
|
||||||
@@ -940,27 +935,17 @@ pdfOrganiser.placeholder=(par exemple 1,3,2 ou 4-8,2,10-12 ou 2n-1)
|
|||||||
multiTool.title=Outil multifonction PDF
|
multiTool.title=Outil multifonction PDF
|
||||||
multiTool.header=Outil multifonction PDF
|
multiTool.header=Outil multifonction PDF
|
||||||
multiTool.uploadPrompts=Nom du fichier
|
multiTool.uploadPrompts=Nom du fichier
|
||||||
multiTool.selectAll=Tout sélectionner
|
multiTool.selectAll=Select All
|
||||||
multiTool.deselectAll=Tout déselectionner
|
multiTool.deselectAll=Deselect All
|
||||||
multiTool.selectPages=Sélection des pages
|
multiTool.selectPages=Page Select
|
||||||
multiTool.selectedPages=Pages sélectionnées
|
multiTool.selectedPages=Selected Pages
|
||||||
multiTool.page=Page
|
multiTool.page=Page
|
||||||
multiTool.deleteSelected=Supprimer la sélection
|
multiTool.deleteSelected=Delete Selected
|
||||||
multiTool.downloadAll=Exporter
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Exporter la sélection
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insérer un saut de page
|
|
||||||
multiTool.addFile=Ajouter un fichier
|
|
||||||
multiTool.rotateLeft=Rotation vers la gauche
|
|
||||||
multiTool.rotateRight=Rotation vers la droite
|
|
||||||
multiTool.split=Diviser
|
|
||||||
multiTool.moveLeft=Déplacer vers la gauche
|
|
||||||
multiTool.moveRight=Déplacer vers la droite
|
|
||||||
multiTool.delete=Supprimer
|
|
||||||
multiTool.dragDropMessage=Page(s) sélectionnées
|
|
||||||
|
|
||||||
#multiTool-advert
|
#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 !
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
#view pdf
|
#view pdf
|
||||||
viewPdf.title=Visualiser un PDF
|
viewPdf.title=Visualiser un PDF
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Deisiúchán
|
repair.title=Deisiúchán
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=प्रदर्शन बचाएं
|
|||||||
sign.personalSigs=मौजूदा प्रदर्शन
|
sign.personalSigs=मौजूदा प्रदर्शन
|
||||||
sign.sharedSigs=साझेदार प्रदर्शन
|
sign.sharedSigs=साझेदार प्रदर्शन
|
||||||
sign.noSavedSigs=कोई भी संवर्तित प्रदर्शन नहीं मौजूद है
|
sign.noSavedSigs=कोई भी संवर्तित प्रदर्शन नहीं मौजूद है
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=मरम्मत
|
repair.title=मरम्मत
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Sačuvaj potpisnu oznaku
|
|||||||
sign.personalSigs=Osobni potpisi
|
sign.personalSigs=Osobni potpisi
|
||||||
sign.sharedSigs=Dijeljeni potpisi
|
sign.sharedSigs=Dijeljeni potpisi
|
||||||
sign.noSavedSigs=Nema sacuvanih potpisa pronađenih
|
sign.noSavedSigs=Nema sacuvanih potpisa pronađenih
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Popravi
|
repair.title=Popravi
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Aláíráshoz mentés
|
|||||||
sign.personalSigs=Személyi aláíráshoz
|
sign.personalSigs=Személyi aláíráshoz
|
||||||
sign.sharedSigs=Megosztott aláíráshoz
|
sign.sharedSigs=Megosztott aláíráshoz
|
||||||
sign.noSavedSigs=Nincsenek mentett aláírások találat
|
sign.noSavedSigs=Nincsenek mentett aláírások találat
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Javítás
|
repair.title=Javítás
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Simpan Tanda Tangan
|
|||||||
sign.personalSigs=Tanda Tangan Pribadi
|
sign.personalSigs=Tanda Tangan Pribadi
|
||||||
sign.sharedSigs=Tanda Tangan Berbagi
|
sign.sharedSigs=Tanda Tangan Berbagi
|
||||||
sign.noSavedSigs=Tidak ditemukan tanda tangan yang disimpan
|
sign.noSavedSigs=Tidak ditemukan tanda tangan yang disimpan
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Perbaiki
|
repair.title=Perbaiki
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Firma salvata
|
|||||||
sign.personalSigs=Firme personali
|
sign.personalSigs=Firme personali
|
||||||
sign.sharedSigs=Firme condivise
|
sign.sharedSigs=Firme condivise
|
||||||
sign.noSavedSigs=Nessuna firma salvata trovata
|
sign.noSavedSigs=Nessuna firma salvata trovata
|
||||||
sign.addToAll=Aggiungi a tutte le pagine
|
|
||||||
sign.delete=Elimina
|
|
||||||
sign.first=Prima pagina
|
|
||||||
sign.last=Ultima pagina
|
|
||||||
sign.next=Prossima pagina
|
|
||||||
sign.previous=Pagina precedente
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Ripara
|
repair.title=Ripara
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Elimina selezionata
|
|||||||
multiTool.downloadAll=Esporta
|
multiTool.downloadAll=Esporta
|
||||||
multiTool.downloadSelected=Esporta selezionata
|
multiTool.downloadSelected=Esporta selezionata
|
||||||
|
|
||||||
multiTool.insertPageBreak=Inserisci interruzione di pagina
|
|
||||||
multiTool.addFile=Aggiungi file
|
|
||||||
multiTool.rotateLeft=Ruota a sinistra
|
|
||||||
multiTool.rotateRight=Ruota a destra
|
|
||||||
multiTool.split=Dividi
|
|
||||||
multiTool.moveLeft=Sposta a sinistra
|
|
||||||
multiTool.moveRight=Sposta a destra
|
|
||||||
multiTool.delete=Elimina
|
|
||||||
multiTool.dragDropMessage=Pagina(e) selezionata(e)
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=Questa funzione è disponibile anche nella nostra <a href="{0}">pagina multi-strumento</a>. Scoprila per un'interfaccia utente pagina per pagina migliorata e funzionalità aggiuntive!
|
multiTool-advert.message=Questa funzione è disponibile anche nella nostra <a href="{0}">pagina multi-strumento</a>. Scoprila per un'interfaccia utente pagina per pagina migliorata e funzionalità aggiuntive!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=修復
|
repair.title=修復
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=서명 저장
|
|||||||
sign.personalSigs=개인용 서명
|
sign.personalSigs=개인용 서명
|
||||||
sign.sharedSigs=공유용 서명
|
sign.sharedSigs=공유용 서명
|
||||||
sign.noSavedSigs=저장된 서명이 없습니다
|
sign.noSavedSigs=저장된 서명이 없습니다
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=복구
|
repair.title=복구
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Opslaan Signatuur
|
|||||||
sign.personalSigs=Persoonlijke Signatuuren
|
sign.personalSigs=Persoonlijke Signatuuren
|
||||||
sign.sharedSigs=Gedeelde Signatuuren
|
sign.sharedSigs=Gedeelde Signatuuren
|
||||||
sign.noSavedSigs=Geen opgeslagen signatuuren gevonden
|
sign.noSavedSigs=Geen opgeslagen signatuuren gevonden
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Repareren
|
repair.title=Repareren
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparer
|
repair.title=Reparer
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Napraw
|
repair.title=Napraw
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Salvar Assinatura
|
|||||||
sign.personalSigs=Assinaturas Pessoais
|
sign.personalSigs=Assinaturas Pessoais
|
||||||
sign.sharedSigs=Assinaturas Compartilhadas
|
sign.sharedSigs=Assinaturas Compartilhadas
|
||||||
sign.noSavedSigs=Nenhuma assinatura salva encontrada
|
sign.noSavedSigs=Nenhuma assinatura salva encontrada
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparar
|
repair.title=Reparar
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Guardar Assinatura
|
|||||||
sign.personalSigs=Assinaturas Pessoais
|
sign.personalSigs=Assinaturas Pessoais
|
||||||
sign.sharedSigs=Assinaturas Compartilhadas
|
sign.sharedSigs=Assinaturas Compartilhadas
|
||||||
sign.noSavedSigs=Nenhuma assinatura guardada encontrada
|
sign.noSavedSigs=Nenhuma assinatura guardada encontrada
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparar
|
repair.title=Reparar
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Repară
|
repair.title=Repară
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Сохранить подпись
|
|||||||
sign.personalSigs=Личные подписи
|
sign.personalSigs=Личные подписи
|
||||||
sign.sharedSigs=Общие подписи
|
sign.sharedSigs=Общие подписи
|
||||||
sign.noSavedSigs=Найдено ни одной сохраненной подписи
|
sign.noSavedSigs=Найдено ни одной сохраненной подписи
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Ремонт
|
repair.title=Ремонт
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Opraviť
|
repair.title=Opraviť
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Popravi
|
repair.title=Popravi
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Spara signatur
|
|||||||
sign.personalSigs=Personliga signaturer
|
sign.personalSigs=Personliga signaturer
|
||||||
sign.sharedSigs=Delade signaturer
|
sign.sharedSigs=Delade signaturer
|
||||||
sign.noSavedSigs=Inga sparade signaturer hittades
|
sign.noSavedSigs=Inga sparade signaturer hittades
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Reparera
|
repair.title=Reparera
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=บันทึกลายเซ็น
|
|||||||
sign.personalSigs=ลายเซ็นส่วนตัว
|
sign.personalSigs=ลายเซ็นส่วนตัว
|
||||||
sign.sharedSigs=ลายเซ็นร่วม
|
sign.sharedSigs=ลายเซ็นร่วม
|
||||||
sign.noSavedSigs=ไม่พบลายเซ็นที่บันทึกไว้
|
sign.noSavedSigs=ไม่พบลายเซ็นที่บันทึกไว้
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=ซ่อมแซม
|
repair.title=ซ่อมแซม
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Onar
|
repair.title=Onar
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Ремонт
|
repair.title=Ремонт
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=Sửa chữa
|
repair.title=Sửa chữa
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=Save Signature
|
|||||||
sign.personalSigs=Personal Signatures
|
sign.personalSigs=Personal Signatures
|
||||||
sign.sharedSigs=Shared Signatures
|
sign.sharedSigs=Shared Signatures
|
||||||
sign.noSavedSigs=No saved signatures found
|
sign.noSavedSigs=No saved signatures found
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=修复
|
repair.title=修复
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -818,12 +818,7 @@ sign.save=儲存簽章
|
|||||||
sign.personalSigs=個人簽章
|
sign.personalSigs=個人簽章
|
||||||
sign.sharedSigs=共用簽章
|
sign.sharedSigs=共用簽章
|
||||||
sign.noSavedSigs=尚未儲存任何簽章
|
sign.noSavedSigs=尚未儲存任何簽章
|
||||||
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
|
|
||||||
|
|
||||||
#repair
|
#repair
|
||||||
repair.title=修復
|
repair.title=修復
|
||||||
@@ -949,16 +944,6 @@ multiTool.deleteSelected=Delete Selected
|
|||||||
multiTool.downloadAll=Export
|
multiTool.downloadAll=Export
|
||||||
multiTool.downloadSelected=Export Selected
|
multiTool.downloadSelected=Export Selected
|
||||||
|
|
||||||
multiTool.insertPageBreak=Insert Page Break
|
|
||||||
multiTool.addFile=Add File
|
|
||||||
multiTool.rotateLeft=Rotate Left
|
|
||||||
multiTool.rotateRight=Rotate Right
|
|
||||||
multiTool.split=Split
|
|
||||||
multiTool.moveLeft=Move Left
|
|
||||||
multiTool.moveRight=Move Right
|
|
||||||
multiTool.delete=Delete
|
|
||||||
multiTool.dragDropMessage=Page(s) Selected
|
|
||||||
|
|
||||||
#multiTool-advert
|
#multiTool-advert
|
||||||
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
multiTool-advert.message=This feature is also available in our <a href="{0}">multi-tool page</a>. Check it out for enhanced page-by-page UI and additional features!
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,14 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "ch.qos.logback:logback-classic",
|
"moduleName": "ch.qos.logback:logback-classic",
|
||||||
"moduleUrl": "http://www.qos.ch",
|
"moduleUrl": "http://www.qos.ch",
|
||||||
"moduleVersion": "1.5.12",
|
"moduleVersion": "1.5.11",
|
||||||
"moduleLicense": "GNU Lesser General Public License",
|
"moduleLicense": "GNU Lesser General Public License",
|
||||||
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
|
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "ch.qos.logback:logback-core",
|
"moduleName": "ch.qos.logback:logback-core",
|
||||||
"moduleUrl": "http://www.qos.ch",
|
"moduleUrl": "http://www.qos.ch",
|
||||||
"moduleVersion": "1.5.12",
|
"moduleVersion": "1.5.11",
|
||||||
"moduleLicense": "GNU Lesser General Public License",
|
"moduleLicense": "GNU Lesser General Public License",
|
||||||
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
|
"moduleLicenseUrl": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"
|
||||||
},
|
},
|
||||||
@@ -45,77 +45,77 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.core:jackson-annotations",
|
"moduleName": "com.fasterxml.jackson.core:jackson-annotations",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson",
|
"moduleUrl": "https://github.com/FasterXML/jackson",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.core:jackson-core",
|
"moduleName": "com.fasterxml.jackson.core:jackson-core",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-core",
|
"moduleUrl": "https://github.com/FasterXML/jackson-core",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.core:jackson-databind",
|
"moduleName": "com.fasterxml.jackson.core:jackson-databind",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson",
|
"moduleUrl": "https://github.com/FasterXML/jackson",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml",
|
"moduleName": "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-dataformats-text",
|
"moduleUrl": "https://github.com/FasterXML/jackson-dataformats-text",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jdk8",
|
"moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jdk8",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8",
|
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jdk8",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jsr310",
|
"moduleName": "com.fasterxml.jackson.datatype:jackson-datatype-jsr310",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310",
|
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-datatype-jsr310",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.jaxrs:jackson-jaxrs-base",
|
"moduleName": "com.fasterxml.jackson.jaxrs:jackson-jaxrs-base",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-base",
|
"moduleUrl": "https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-base",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider",
|
"moduleName": "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-json-provider",
|
"moduleUrl": "https://github.com/FasterXML/jackson-jaxrs-providers/jackson-jaxrs-json-provider",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.module:jackson-module-jaxb-annotations",
|
"moduleName": "com.fasterxml.jackson.module:jackson-module-jaxb-annotations",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-modules-base",
|
"moduleUrl": "https://github.com/FasterXML/jackson-modules-base",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson.module:jackson-module-parameter-names",
|
"moduleName": "com.fasterxml.jackson.module:jackson-module-parameter-names",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names",
|
"moduleUrl": "https://github.com/FasterXML/jackson-modules-java8/jackson-module-parameter-names",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.fasterxml.jackson:jackson-bom",
|
"moduleName": "com.fasterxml.jackson:jackson-bom",
|
||||||
"moduleUrl": "https://github.com/FasterXML/jackson-bom",
|
"moduleUrl": "https://github.com/FasterXML/jackson-bom",
|
||||||
"moduleVersion": "2.18.1",
|
"moduleVersion": "2.17.2",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@@ -146,18 +146,6 @@
|
|||||||
"moduleLicense": "GNU General Public License v3.0",
|
"moduleLicense": "GNU General Public License v3.0",
|
||||||
"moduleLicenseUrl": "https://api.github.com/licenses/gpl-3.0"
|
"moduleLicenseUrl": "https://api.github.com/licenses/gpl-3.0"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "com.github.jai-imageio:jai-imageio-core",
|
|
||||||
"moduleUrl": "https://github.com/jai-imageio/jai-imageio-core",
|
|
||||||
"moduleVersion": "1.4.0",
|
|
||||||
"moduleLicense": "LICENSE.txt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"moduleName": "com.github.jai-imageio:jai-imageio-jpeg2000",
|
|
||||||
"moduleUrl": "https://github.com/jai-imageio/jai-imageio-jpeg2000",
|
|
||||||
"moduleVersion": "1.4.0",
|
|
||||||
"moduleLicense": "LICENSE-JJ2000.txt, LICENSE-Sun.txt"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "com.github.stephenc.jcip:jcip-annotations",
|
"moduleName": "com.github.stephenc.jcip:jcip-annotations",
|
||||||
"moduleUrl": "http://stephenc.github.com/jcip-annotations",
|
"moduleUrl": "http://stephenc.github.com/jcip-annotations",
|
||||||
@@ -174,22 +162,21 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.google.errorprone:error_prone_annotations",
|
"moduleName": "com.google.errorprone:error_prone_annotations",
|
||||||
"moduleUrl": "https://errorprone.info/error_prone_annotations",
|
"moduleVersion": "2.11.0",
|
||||||
"moduleVersion": "2.28.0",
|
|
||||||
"moduleLicense": "Apache 2.0",
|
"moduleLicense": "Apache 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.google.guava:failureaccess",
|
"moduleName": "com.google.guava:failureaccess",
|
||||||
"moduleUrl": "https://github.com/google/guava/",
|
"moduleUrl": "https://github.com/google/guava/",
|
||||||
"moduleVersion": "1.0.2",
|
"moduleVersion": "1.0.1",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "com.google.guava:guava",
|
"moduleName": "com.google.guava:guava",
|
||||||
"moduleUrl": "https://github.com/google/guava/",
|
"moduleUrl": "https://github.com/google/guava/",
|
||||||
"moduleVersion": "33.3.1-jre",
|
"moduleVersion": "31.1-jre",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@@ -202,8 +189,8 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "com.google.j2objc:j2objc-annotations",
|
"moduleName": "com.google.j2objc:j2objc-annotations",
|
||||||
"moduleUrl": "https://github.com/google/j2objc/",
|
"moduleUrl": "https://github.com/google/j2objc/",
|
||||||
"moduleVersion": "3.0.0",
|
"moduleVersion": "1.3",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -235,7 +222,7 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "com.h2database:h2",
|
"moduleName": "com.h2database:h2",
|
||||||
"moduleUrl": "https://h2database.com",
|
"moduleUrl": "https://h2database.com",
|
||||||
"moduleVersion": "2.3.232",
|
"moduleVersion": "2.1.214",
|
||||||
"moduleLicense": "MPL 2.0",
|
"moduleLicense": "MPL 2.0",
|
||||||
"moduleLicenseUrl": "https://www.mozilla.org/en-US/MPL/2.0/"
|
"moduleLicenseUrl": "https://www.mozilla.org/en-US/MPL/2.0/"
|
||||||
},
|
},
|
||||||
@@ -383,17 +370,10 @@
|
|||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "commons-cli:commons-cli",
|
|
||||||
"moduleUrl": "http://commons.apache.org/proper/commons-cli/",
|
|
||||||
"moduleVersion": "1.4",
|
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "commons-codec:commons-codec",
|
"moduleName": "commons-codec:commons-codec",
|
||||||
"moduleUrl": "https://commons.apache.org/proper/commons-codec/",
|
"moduleUrl": "https://commons.apache.org/proper/commons-codec/",
|
||||||
"moduleVersion": "1.17.1",
|
"moduleVersion": "1.16.1",
|
||||||
"moduleLicense": "Apache-2.0",
|
"moduleLicense": "Apache-2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@@ -413,10 +393,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "commons-logging:commons-logging",
|
"moduleName": "commons-logging:commons-logging",
|
||||||
"moduleUrl": "https://commons.apache.org/proper/commons-logging/",
|
"moduleUrl": "http://jakarta.apache.org/commons/logging/",
|
||||||
"moduleVersion": "1.3.3",
|
"moduleVersion": "1.0.4",
|
||||||
"moduleLicense": "Apache-2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "/LICENSE.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.dropwizard.metrics:metrics-core",
|
"moduleName": "io.dropwizard.metrics:metrics-core",
|
||||||
@@ -434,34 +414,34 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "io.micrometer:micrometer-commons",
|
"moduleName": "io.micrometer:micrometer-commons",
|
||||||
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
||||||
"moduleVersion": "1.14.1",
|
"moduleVersion": "1.13.6",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.micrometer:micrometer-core",
|
"moduleName": "io.micrometer:micrometer-core",
|
||||||
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
||||||
"moduleVersion": "1.14.1",
|
"moduleVersion": "1.13.6",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.micrometer:micrometer-jakarta9",
|
"moduleName": "io.micrometer:micrometer-jakarta9",
|
||||||
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
||||||
"moduleVersion": "1.14.1",
|
"moduleVersion": "1.13.6",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.micrometer:micrometer-observation",
|
"moduleName": "io.micrometer:micrometer-observation",
|
||||||
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
"moduleUrl": "https://github.com/micrometer-metrics/micrometer",
|
||||||
"moduleVersion": "1.14.1",
|
"moduleVersion": "1.13.6",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "io.smallrye:jandex",
|
"moduleName": "io.smallrye:jandex",
|
||||||
"moduleVersion": "3.2.0",
|
"moduleVersion": "3.1.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@@ -593,7 +573,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "net.bytebuddy:byte-buddy",
|
"moduleName": "net.bytebuddy:byte-buddy",
|
||||||
"moduleVersion": "1.15.10",
|
"moduleVersion": "1.14.19",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@@ -631,17 +611,10 @@
|
|||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "org.apache.commons:commons-csv",
|
|
||||||
"moduleUrl": "https://commons.apache.org/proper/commons-csv/",
|
|
||||||
"moduleVersion": "1.9.0",
|
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "org.apache.commons:commons-lang3",
|
"moduleName": "org.apache.commons:commons-lang3",
|
||||||
"moduleUrl": "https://commons.apache.org/proper/commons-lang/",
|
"moduleUrl": "https://commons.apache.org/proper/commons-lang/",
|
||||||
"moduleVersion": "3.17.0",
|
"moduleVersion": "3.14.0",
|
||||||
"moduleLicense": "Apache-2.0",
|
"moduleLicense": "Apache-2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@@ -668,13 +641,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.apache.logging.log4j:log4j-api",
|
"moduleName": "org.apache.logging.log4j:log4j-api",
|
||||||
"moduleVersion": "2.24.1",
|
"moduleVersion": "2.23.1",
|
||||||
"moduleLicense": "Apache-2.0",
|
"moduleLicense": "Apache-2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.apache.logging.log4j:log4j-to-slf4j",
|
"moduleName": "org.apache.logging.log4j:log4j-to-slf4j",
|
||||||
"moduleVersion": "2.24.1",
|
"moduleVersion": "2.23.1",
|
||||||
"moduleLicense": "Apache-2.0",
|
"moduleLicense": "Apache-2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@@ -722,7 +695,7 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.apache.tomcat.embed:tomcat-embed-el",
|
"moduleName": "org.apache.tomcat.embed:tomcat-embed-el",
|
||||||
"moduleUrl": "https://tomcat.apache.org/",
|
"moduleUrl": "https://tomcat.apache.org/",
|
||||||
"moduleVersion": "10.1.33",
|
"moduleVersion": "10.1.31",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@@ -760,52 +733,31 @@
|
|||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "org.bouncycastle:bcmail-jdk15on",
|
|
||||||
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
|
||||||
"moduleVersion": "1.69",
|
|
||||||
"moduleLicense": "Bouncy Castle Licence",
|
|
||||||
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"moduleName": "org.bouncycastle:bcpkix-jdk15on",
|
|
||||||
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
|
||||||
"moduleVersion": "1.69",
|
|
||||||
"moduleLicense": "Bouncy Castle Licence",
|
|
||||||
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "org.bouncycastle:bcpkix-jdk18on",
|
"moduleName": "org.bouncycastle:bcpkix-jdk18on",
|
||||||
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
||||||
"moduleVersion": "1.79",
|
"moduleVersion": "1.78.1",
|
||||||
"moduleLicense": "Bouncy Castle Licence",
|
"moduleLicense": "Bouncy Castle Licence",
|
||||||
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.bouncycastle:bcprov-jdk18on",
|
"moduleName": "org.bouncycastle:bcprov-jdk18on",
|
||||||
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
||||||
"moduleVersion": "1.79",
|
"moduleVersion": "1.78.1",
|
||||||
"moduleLicense": "Bouncy Castle Licence",
|
|
||||||
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"moduleName": "org.bouncycastle:bcutil-jdk15on",
|
|
||||||
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
|
||||||
"moduleVersion": "1.69",
|
|
||||||
"moduleLicense": "Bouncy Castle Licence",
|
"moduleLicense": "Bouncy Castle Licence",
|
||||||
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.bouncycastle:bcutil-jdk18on",
|
"moduleName": "org.bouncycastle:bcutil-jdk18on",
|
||||||
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
"moduleUrl": "https://www.bouncycastle.org/java.html",
|
||||||
"moduleVersion": "1.79",
|
"moduleVersion": "1.78.1",
|
||||||
"moduleLicense": "Bouncy Castle Licence",
|
"moduleLicense": "Bouncy Castle Licence",
|
||||||
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
"moduleLicenseUrl": "https://www.bouncycastle.org/licence.html"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.checkerframework:checker-qual",
|
"moduleName": "org.checkerframework:checker-qual",
|
||||||
"moduleUrl": "https://checkerframework.org/",
|
"moduleUrl": "https://checkerframework.org",
|
||||||
"moduleVersion": "3.43.0",
|
"moduleVersion": "3.12.0",
|
||||||
"moduleLicense": "The MIT License",
|
"moduleLicense": "The MIT License",
|
||||||
"moduleLicenseUrl": "http://opensource.org/licenses/MIT"
|
"moduleLicenseUrl": "http://opensource.org/licenses/MIT"
|
||||||
},
|
},
|
||||||
@@ -838,182 +790,182 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-client",
|
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-client",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-common",
|
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-common",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server",
|
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jetty-server",
|
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jetty-server",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-servlet",
|
"moduleName": "org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-servlet",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-annotations",
|
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-annotations",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-plus",
|
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-plus",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-servlet",
|
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-servlet",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-servlets",
|
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-servlets",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-webapp",
|
"moduleName": "org.eclipse.jetty.ee10:jetty-ee10-webapp",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-client",
|
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-client",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-common",
|
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-common",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-server",
|
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-core-server",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-jetty-api",
|
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-jetty-api",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-jetty-common",
|
"moduleName": "org.eclipse.jetty.websocket:jetty-websocket-jetty-common",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-alpn-client",
|
"moduleName": "org.eclipse.jetty:jetty-alpn-client",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-client",
|
"moduleName": "org.eclipse.jetty:jetty-client",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-ee",
|
"moduleName": "org.eclipse.jetty:jetty-ee",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-http",
|
"moduleName": "org.eclipse.jetty:jetty-http",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-io",
|
"moduleName": "org.eclipse.jetty:jetty-io",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-plus",
|
"moduleName": "org.eclipse.jetty:jetty-plus",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-security",
|
"moduleName": "org.eclipse.jetty:jetty-security",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-server",
|
"moduleName": "org.eclipse.jetty:jetty-server",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-session",
|
"moduleName": "org.eclipse.jetty:jetty-session",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-util",
|
"moduleName": "org.eclipse.jetty:jetty-util",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.eclipse.jetty:jetty-xml",
|
"moduleName": "org.eclipse.jetty:jetty-xml",
|
||||||
"moduleUrl": "https://jetty.org/",
|
"moduleUrl": "https://jetty.org/",
|
||||||
"moduleVersion": "12.0.15",
|
"moduleVersion": "12.0.14",
|
||||||
"moduleLicense": "Eclipse Public License - Version 2.0",
|
"moduleLicense": "Eclipse Public License - Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
"moduleLicenseUrl": "https://www.eclipse.org/legal/epl-2.0/"
|
||||||
},
|
},
|
||||||
@@ -1048,23 +1000,23 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.hibernate.common:hibernate-commons-annotations",
|
"moduleName": "org.hibernate.common:hibernate-commons-annotations",
|
||||||
"moduleUrl": "http://hibernate.org",
|
"moduleUrl": "http://hibernate.org",
|
||||||
"moduleVersion": "7.0.3.Final",
|
"moduleVersion": "6.0.6.Final",
|
||||||
"moduleLicense": "Apache License Version 2.0",
|
"moduleLicense": "GNU Library General Public License v2.1 or later",
|
||||||
"moduleLicenseUrl": "https://opensource.org/licenses/Apache-2.0"
|
"moduleLicenseUrl": "http://www.opensource.org/licenses/LGPL-2.1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.hibernate.orm:hibernate-core",
|
"moduleName": "org.hibernate.orm:hibernate-core",
|
||||||
"moduleUrl": "https://www.hibernate.org/orm/6.6",
|
"moduleUrl": "https://www.hibernate.org/orm/6.5",
|
||||||
"moduleVersion": "6.6.2.Final",
|
"moduleVersion": "6.5.3.Final",
|
||||||
"moduleLicense": "GNU Library General Public License v2.1 or later",
|
"moduleLicense": "GNU Library General Public License v2.1 or later",
|
||||||
"moduleLicenseUrl": "https://www.opensource.org/licenses/LGPL-2.1"
|
"moduleLicenseUrl": "https://www.opensource.org/licenses/LGPL-2.1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.jboss.logging:jboss-logging",
|
"moduleName": "org.jboss.logging:jboss-logging",
|
||||||
"moduleUrl": "http://www.jboss.org",
|
"moduleUrl": "http://www.jboss.org",
|
||||||
"moduleVersion": "3.6.1.Final",
|
"moduleVersion": "3.5.3.Final",
|
||||||
"moduleLicense": "Apache License 2.0",
|
"moduleLicense": "Public Domain",
|
||||||
"moduleLicenseUrl": "https://repository.jboss.org/licenses/apache-2.0.txt"
|
"moduleLicenseUrl": "http://repository.jboss.org/licenses/cc0-1.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.latencyutils:LatencyUtils",
|
"moduleName": "org.latencyutils:LatencyUtils",
|
||||||
@@ -1073,12 +1025,6 @@
|
|||||||
"moduleLicense": "Public Domain, per Creative Commons CC0",
|
"moduleLicense": "Public Domain, per Creative Commons CC0",
|
||||||
"moduleLicenseUrl": "http://creativecommons.org/publicdomain/zero/1.0/"
|
"moduleLicenseUrl": "http://creativecommons.org/publicdomain/zero/1.0/"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "org.locationtech.jts:jts-core",
|
|
||||||
"moduleVersion": "1.18.1",
|
|
||||||
"moduleLicense": "Eclipse Public License, Version 2.0",
|
|
||||||
"moduleLicenseUrl": "https://github.com/locationtech/jts/blob/master/LICENSE_EPLv2.txt"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "org.opensaml:opensaml-core",
|
"moduleName": "org.opensaml:opensaml-core",
|
||||||
"moduleVersion": "4.3.2",
|
"moduleVersion": "4.3.2",
|
||||||
@@ -1154,21 +1100,21 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.ow2.asm:asm",
|
"moduleName": "org.ow2.asm:asm",
|
||||||
"moduleUrl": "http://asm.ow2.org",
|
"moduleUrl": "http://asm.ow2.org",
|
||||||
"moduleVersion": "9.7.1",
|
"moduleVersion": "9.7",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.ow2.asm:asm-commons",
|
"moduleName": "org.ow2.asm:asm-commons",
|
||||||
"moduleUrl": "http://asm.ow2.org",
|
"moduleUrl": "http://asm.ow2.org",
|
||||||
"moduleVersion": "9.7.1",
|
"moduleVersion": "9.7",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.ow2.asm:asm-tree",
|
"moduleName": "org.ow2.asm:asm-tree",
|
||||||
"moduleUrl": "http://asm.ow2.org",
|
"moduleUrl": "http://asm.ow2.org",
|
||||||
"moduleVersion": "9.7.1",
|
"moduleVersion": "9.7",
|
||||||
"moduleLicense": "The Apache Software License, Version 2.0",
|
"moduleLicense": "The Apache Software License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
@@ -1207,266 +1153,273 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot",
|
"moduleName": "org.springframework.boot:spring-boot",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-actuator",
|
"moduleName": "org.springframework.boot:spring-boot-actuator",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-actuator-autoconfigure",
|
"moduleName": "org.springframework.boot:spring-boot-actuator-autoconfigure",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-autoconfigure",
|
"moduleName": "org.springframework.boot:spring-boot-autoconfigure",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-devtools",
|
"moduleName": "org.springframework.boot:spring-boot-devtools",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter",
|
"moduleName": "org.springframework.boot:spring-boot-starter",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-actuator",
|
"moduleName": "org.springframework.boot:spring-boot-starter-actuator",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "org.springframework.boot:spring-boot-starter-aop",
|
||||||
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-data-jpa",
|
"moduleName": "org.springframework.boot:spring-boot-starter-data-jpa",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-jdbc",
|
"moduleName": "org.springframework.boot:spring-boot-starter-jdbc",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-jetty",
|
"moduleName": "org.springframework.boot:spring-boot-starter-jetty",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-json",
|
"moduleName": "org.springframework.boot:spring-boot-starter-json",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-logging",
|
"moduleName": "org.springframework.boot:spring-boot-starter-logging",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-oauth2-client",
|
"moduleName": "org.springframework.boot:spring-boot-starter-oauth2-client",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-security",
|
"moduleName": "org.springframework.boot:spring-boot-starter-security",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-thymeleaf",
|
"moduleName": "org.springframework.boot:spring-boot-starter-thymeleaf",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.boot:spring-boot-starter-web",
|
"moduleName": "org.springframework.boot:spring-boot-starter-web",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-boot",
|
"moduleUrl": "https://spring.io/projects/spring-boot",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.data:spring-data-commons",
|
"moduleName": "org.springframework.data:spring-data-commons",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-data",
|
"moduleUrl": "https://spring.io/projects/spring-data",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.data:spring-data-jpa",
|
"moduleName": "org.springframework.data:spring-data-jpa",
|
||||||
"moduleUrl": "https://projects.spring.io/spring-data-jpa",
|
"moduleUrl": "https://projects.spring.io/spring-data-jpa",
|
||||||
"moduleVersion": "3.4.0",
|
"moduleVersion": "3.3.5",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-config",
|
"moduleName": "org.springframework.security:spring-security-config",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.4.1",
|
"moduleVersion": "6.3.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-core",
|
"moduleName": "org.springframework.security:spring-security-core",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.4.1",
|
"moduleVersion": "6.3.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-crypto",
|
"moduleName": "org.springframework.security:spring-security-crypto",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.4.1",
|
"moduleVersion": "6.3.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-oauth2-client",
|
"moduleName": "org.springframework.security:spring-security-oauth2-client",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.4.1",
|
"moduleVersion": "6.3.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-oauth2-core",
|
"moduleName": "org.springframework.security:spring-security-oauth2-core",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.4.1",
|
"moduleVersion": "6.3.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-oauth2-jose",
|
"moduleName": "org.springframework.security:spring-security-oauth2-jose",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.4.1",
|
"moduleVersion": "6.3.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-saml2-service-provider",
|
"moduleName": "org.springframework.security:spring-security-saml2-service-provider",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.4.1",
|
"moduleVersion": "6.3.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework.security:spring-security-web",
|
"moduleName": "org.springframework.security:spring-security-web",
|
||||||
"moduleUrl": "https://spring.io/projects/spring-security",
|
"moduleUrl": "https://spring.io/projects/spring-security",
|
||||||
"moduleVersion": "6.4.1",
|
"moduleVersion": "6.3.4",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-aop",
|
"moduleName": "org.springframework:spring-aop",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-aspects",
|
"moduleName": "org.springframework:spring-aspects",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-beans",
|
"moduleName": "org.springframework:spring-beans",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-context",
|
"moduleName": "org.springframework:spring-context",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-core",
|
"moduleName": "org.springframework:spring-core",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-expression",
|
"moduleName": "org.springframework:spring-expression",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-jcl",
|
"moduleName": "org.springframework:spring-jcl",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-jdbc",
|
"moduleName": "org.springframework:spring-jdbc",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-orm",
|
"moduleName": "org.springframework:spring-orm",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-tx",
|
"moduleName": "org.springframework:spring-tx",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-web",
|
"moduleName": "org.springframework:spring-web",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"moduleName": "org.springframework:spring-webmvc",
|
"moduleName": "org.springframework:spring-webmvc",
|
||||||
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
"moduleUrl": "https://github.com/spring-projects/spring-framework",
|
||||||
"moduleVersion": "6.2.0",
|
"moduleVersion": "6.1.14",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
|
||||||
},
|
},
|
||||||
@@ -1511,17 +1464,10 @@
|
|||||||
{
|
{
|
||||||
"moduleName": "org.yaml:snakeyaml",
|
"moduleName": "org.yaml:snakeyaml",
|
||||||
"moduleUrl": "https://bitbucket.org/snakeyaml/snakeyaml",
|
"moduleUrl": "https://bitbucket.org/snakeyaml/snakeyaml",
|
||||||
"moduleVersion": "2.3",
|
"moduleVersion": "2.2",
|
||||||
"moduleLicense": "Apache License, Version 2.0",
|
"moduleLicense": "Apache License, Version 2.0",
|
||||||
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"moduleName": "technology.tabula:tabula",
|
|
||||||
"moduleUrl": "http://github.com/tabulapdf/tabula-java",
|
|
||||||
"moduleVersion": "1.0.5",
|
|
||||||
"moduleLicense": "MIT License",
|
|
||||||
"moduleLicenseUrl": "http://www.opensource.org/licenses/mit-license.php"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"moduleName": "xml-apis:xml-apis",
|
"moduleName": "xml-apis:xml-apis",
|
||||||
"moduleUrl": "http://xml.apache.org/commons/components/external/",
|
"moduleUrl": "http://xml.apache.org/commons/components/external/",
|
||||||
|
|||||||
@@ -19,15 +19,6 @@
|
|||||||
transform-origin: top left;
|
transform-origin: top left;
|
||||||
}
|
}
|
||||||
|
|
||||||
#drag-container .multidrag {
|
|
||||||
position: fixed;
|
|
||||||
max-width: 200px;
|
|
||||||
max-height: 200px;
|
|
||||||
transform-origin: top left;
|
|
||||||
margin-left: 1rem;
|
|
||||||
background-color: rgba(0, 29, 41, 0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
.drag-manager_dragging {
|
.drag-manager_dragging {
|
||||||
width: 0px;
|
width: 0px;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
|||||||
@@ -100,30 +100,3 @@ input:-webkit-autofill:focus {
|
|||||||
input[data-autocompleted] {
|
input[data-autocompleted] {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
.btn-tooltip {
|
|
||||||
position: absolute;
|
|
||||||
display: none;
|
|
||||||
bottom: 3.2rem;
|
|
||||||
white-space: nowrap;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
width: fit-content;
|
|
||||||
padding: 7px;
|
|
||||||
background-color: rgba(0, 29, 41, 0.9);
|
|
||||||
border-radius: 3px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: whitesmoke;
|
|
||||||
animation: fadeup 0.15s linear;
|
|
||||||
}
|
|
||||||
@keyframes fadeup {
|
|
||||||
0% {
|
|
||||||
transform: translateY(10px);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateY(0);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.btn:hover .btn-tooltip {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ label {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#export-button {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.bg-card {
|
.bg-card {
|
||||||
background-color: var(--md-sys-color-surface-5);
|
background-color: var(--md-sys-color-surface-5);
|
||||||
border-radius: 3rem;
|
border-radius: 3rem;
|
||||||
@@ -286,6 +290,3 @@ label {
|
|||||||
.checkbox-label {
|
.checkbox-label {
|
||||||
font-size: medium;
|
font-size: medium;
|
||||||
}
|
}
|
||||||
.btn {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
.pdf-actions_button-container {
|
.pdf-actions_button-container {
|
||||||
z-index: 4;
|
z-index: 2;
|
||||||
display: flex;
|
display: flex;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.1s linear;
|
transition: opacity 0.1s linear;
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
width: 80px;
|
width: 80px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
z-index: 3;
|
z-index: 1;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.2s;
|
transition: opacity 0.2s;
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,6 @@ html[dir="rtl"] .pdf-actions_container:last-child>.pdf-actions_insert-file-butto
|
|||||||
translate: 50% -50%;
|
translate: 50% -50%;
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
border-radius: 100px;
|
border-radius: 100px;
|
||||||
z-index: 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pdf-actions_split-file-button {
|
.pdf-actions_split-file-button {
|
||||||
@@ -126,9 +125,9 @@ html[dir="rtl"] .pdf-actions_container:last-child>.pdf-actions_insert-file-butto
|
|||||||
translate: 0 -50%;
|
translate: 0 -50%;
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
border-radius: 100px;
|
border-radius: 100px;
|
||||||
z-index: 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.pdf-actions_checkbox {
|
.pdf-actions_checkbox {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
@@ -138,7 +137,7 @@ html[dir="rtl"] .pdf-actions_container:last-child>.pdf-actions_insert-file-butto
|
|||||||
padding: 6px 8px;
|
padding: 6px 8px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
z-index: 10;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
@@ -151,5 +150,4 @@ html[dir="rtl"] .pdf-actions_container:last-child>.pdf-actions_insert-file-butto
|
|||||||
translate: 0% -50%;
|
translate: 0% -50%;
|
||||||
aspect-ratio: 1;
|
aspect-ratio: 1;
|
||||||
border-radius: 100px;
|
border-radius: 100px;
|
||||||
z-index: 5;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,54 +62,53 @@ select#font-select option {
|
|||||||
background-color: rgba(52, 152, 219, 0.2);
|
background-color: rgba(52, 152, 219, 0.2);
|
||||||
/* Darken background on hover */
|
/* Darken background on hover */
|
||||||
}
|
}
|
||||||
|
|
||||||
.signature-grid {
|
.signature-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signature-list {
|
.signature-list {
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signature-list-item {
|
.signature-list-item {
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
border: 1px solid #dee2e6;
|
border: 1px solid #dee2e6;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.2s;
|
transition: background-color 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signature-list-item:hover {
|
.signature-list-item:hover {
|
||||||
background-color: #f8f9fa;
|
background-color: #f8f9fa;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signature-list-info {
|
.signature-list-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signature-list-name {
|
.signature-list-name {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signature-list-details {
|
.signature-list-details {
|
||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
font-size: 0.875rem;
|
font-size: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.signature-list-details small:not(:last-child) {
|
.signature-list-details small:not(:last-child) {
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.view-toggle {
|
.view-toggle {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
}
|
}
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" id="flag-icons-az" viewBox="0 0 640 480">
|
|
||||||
<path fill="#3f9c35" d="M.1 0h640v480H.1z"/>
|
|
||||||
<path fill="#ed2939" d="M.1 0h640v320H.1z"/>
|
|
||||||
<path fill="#00b9e4" d="M.1 0h640v160H.1z"/>
|
|
||||||
<circle cx="304" cy="240" r="72" fill="#fff"/>
|
|
||||||
<circle cx="320" cy="240" r="60" fill="#ed2939"/>
|
|
||||||
<path fill="#fff" d="m384 200 7.7 21.5 20.6-9.8-9.8 20.7L424 240l-21.5 7.7 9.8 20.6-20.6-9.8L384 280l-7.7-21.5-20.6 9.8 9.8-20.6L344 240l21.5-7.7-9.8-20.6 20.6 9.8z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 501 B |
@@ -34,14 +34,6 @@
|
|||||||
const url = this.action;
|
const url = this.action;
|
||||||
const files = $("#fileInput-input")[0].files;
|
const files = $("#fileInput-input")[0].files;
|
||||||
const formData = new FormData(this);
|
const formData = new FormData(this);
|
||||||
const submitButton = document.getElementById("submitBtn");
|
|
||||||
const showGameBtn = document.getElementById("show-game-btn");
|
|
||||||
const originalButtonText = submitButton.textContent;
|
|
||||||
var boredWaiting = localStorage.getItem("boredWaiting") || "disabled";
|
|
||||||
|
|
||||||
if (showGameBtn) {
|
|
||||||
showGameBtn.style.display = "none";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove empty file entries
|
// Remove empty file entries
|
||||||
for (let [key, value] of formData.entries()) {
|
for (let [key, value] of formData.entries()) {
|
||||||
@@ -50,10 +42,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const override = $("#override").val() || "";
|
const override = $("#override").val() || "";
|
||||||
|
const originalButtonText = $("#submitBtn").text();
|
||||||
|
$("#submitBtn").text("Processing...");
|
||||||
console.log(override);
|
console.log(override);
|
||||||
|
|
||||||
// Set a timeout to show the game button if operation takes more than 5 seconds
|
// Set a timeout to show the game button if operation takes more than 5 seconds
|
||||||
const timeoutId = setTimeout(() => {
|
const timeoutId = setTimeout(() => {
|
||||||
|
var boredWaiting = localStorage.getItem("boredWaiting") || "disabled";
|
||||||
|
const showGameBtn = document.getElementById("show-game-btn");
|
||||||
if (boredWaiting === "enabled" && showGameBtn) {
|
if (boredWaiting === "enabled" && showGameBtn) {
|
||||||
showGameBtn.style.display = "block";
|
showGameBtn.style.display = "block";
|
||||||
showGameBtn.parentNode.insertBefore(document.createElement('br'), showGameBtn.nextSibling);
|
showGameBtn.parentNode.insertBefore(document.createElement('br'), showGameBtn.nextSibling);
|
||||||
@@ -61,9 +57,6 @@
|
|||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
submitButton.textContent = "Processing...";
|
|
||||||
submitButton.disabled = true;
|
|
||||||
|
|
||||||
if (remoteCall === true) {
|
if (remoteCall === true) {
|
||||||
if (override === "multi" || (!multipleInputsForSingleRequest && files.length > 1 && override !== "single")) {
|
if (override === "multi" || (!multipleInputsForSingleRequest && files.length > 1 && override !== "single")) {
|
||||||
await submitMultiPdfForm(url, files);
|
await submitMultiPdfForm(url, files);
|
||||||
@@ -72,17 +65,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
clearFileInput();
|
clearFileInput();
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
if (showGameBtn) {
|
$("#submitBtn").text(originalButtonText);
|
||||||
showGameBtn.style.display = "none";
|
|
||||||
showGameBtn.style.marginTop = "";
|
|
||||||
}
|
|
||||||
submitButton.textContent = originalButtonText;
|
|
||||||
submitButton.disabled = false;
|
|
||||||
|
|
||||||
// After process finishes, check for boredWaiting and gameDialog open status
|
// After process finishes, check for boredWaiting and gameDialog open status
|
||||||
|
const boredWaiting = localStorage.getItem("boredWaiting") || "disabled";
|
||||||
const gameDialog = document.getElementById('game-container-wrapper');
|
const gameDialog = document.getElementById('game-container-wrapper');
|
||||||
if (boredWaiting === "enabled" && gameDialog && gameDialog.open) {
|
if (boredWaiting === "enabled" && gameDialog && gameDialog.open) {
|
||||||
// Display a green banner at the bottom of the screen saying "Download complete"
|
// Display a green banner at the bottom of the screen saying "Download complete"
|
||||||
@@ -99,11 +87,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
clearFileInput();
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
showGameBtn.style.display = "none";
|
|
||||||
submitButton.textContent = originalButtonText;
|
|
||||||
submitButton.disabled = false;
|
|
||||||
handleDownloadError(error);
|
handleDownloadError(error);
|
||||||
|
$("#submitBtn").text(originalButtonText);
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -161,6 +148,7 @@
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
success = false;
|
success = false;
|
||||||
errorMessage = error.message;
|
errorMessage = error.message;
|
||||||
|
clearFileInput();
|
||||||
console.error("Error in handleSingleDownload:", error);
|
console.error("Error in handleSingleDownload:", error);
|
||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -168,16 +156,15 @@
|
|||||||
|
|
||||||
// Capture analytics
|
// Capture analytics
|
||||||
const pageCount = file && file.type === 'application/pdf' ? await getPDFPageCount(file) : null;
|
const pageCount = file && file.type === 'application/pdf' ? await getPDFPageCount(file) : null;
|
||||||
if(analyticsEnabled) {
|
|
||||||
posthog.capture('file_processing', {
|
posthog.capture('file_processing', {
|
||||||
success: success,
|
success: success,
|
||||||
file_type: file ? file.type || 'unknown' : 'unknown',
|
file_type: file ? file.type || 'unknown' : 'unknown',
|
||||||
file_size: file ? file.size : 0,
|
file_size: file ? file.size : 0,
|
||||||
processing_time: processingTime,
|
processing_time: processingTime,
|
||||||
error_message: errorMessage,
|
error_message: errorMessage,
|
||||||
pdf_pages: pageCount
|
pdf_pages: pageCount
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ const DraggableUtils = {
|
|||||||
nextId: 0,
|
nextId: 0,
|
||||||
pdfDoc: null,
|
pdfDoc: null,
|
||||||
pageIndex: 0,
|
pageIndex: 0,
|
||||||
elementAllPages: [],
|
|
||||||
documentsMap: new Map(),
|
documentsMap: new Map(),
|
||||||
lastInteracted: null,
|
lastInteracted: null,
|
||||||
|
|
||||||
@@ -198,68 +197,6 @@ const DraggableUtils = {
|
|||||||
deleteAllDraggableCanvases() {
|
deleteAllDraggableCanvases() {
|
||||||
this.boxDragContainer.querySelectorAll(".draggable-canvas").forEach((el) => el.remove());
|
this.boxDragContainer.querySelectorAll(".draggable-canvas").forEach((el) => el.remove());
|
||||||
},
|
},
|
||||||
async addAllPagesDraggableCanvas(element) {
|
|
||||||
if (element) {
|
|
||||||
let currentPage = this.pageIndex
|
|
||||||
if (!this.elementAllPages.includes(element)) {
|
|
||||||
this.elementAllPages.push(element)
|
|
||||||
element.style.filter = 'sepia(1) hue-rotate(90deg) brightness(1.2)';
|
|
||||||
let newElement = {
|
|
||||||
"element": element,
|
|
||||||
"offsetWidth": element.width,
|
|
||||||
"offsetHeight": element.height
|
|
||||||
}
|
|
||||||
|
|
||||||
let pagesMap = this.documentsMap.get(this.pdfDoc);
|
|
||||||
|
|
||||||
if (!pagesMap) {
|
|
||||||
pagesMap = {};
|
|
||||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
|
||||||
}
|
|
||||||
let page = this.pageIndex
|
|
||||||
|
|
||||||
for (let pageIndex = 0; pageIndex < this.pdfDoc.numPages; pageIndex++) {
|
|
||||||
|
|
||||||
if (pagesMap[`${pageIndex}-offsetWidth`]) {
|
|
||||||
if (!pagesMap[pageIndex].includes(newElement)) {
|
|
||||||
pagesMap[pageIndex].push(newElement);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pagesMap[pageIndex] = []
|
|
||||||
pagesMap[pageIndex].push(newElement)
|
|
||||||
pagesMap[`${pageIndex}-offsetWidth`] = pagesMap[`${page}-offsetWidth`];
|
|
||||||
pagesMap[`${pageIndex}-offsetHeight`] = pagesMap[`${page}-offsetHeight`];
|
|
||||||
}
|
|
||||||
await this.goToPage(pageIndex)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const index = this.elementAllPages.indexOf(element);
|
|
||||||
if (index !== -1) {
|
|
||||||
this.elementAllPages.splice(index, 1);
|
|
||||||
}
|
|
||||||
element.style.filter = '';
|
|
||||||
let pagesMap = this.documentsMap.get(this.pdfDoc);
|
|
||||||
|
|
||||||
if (!pagesMap) {
|
|
||||||
pagesMap = {};
|
|
||||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
|
||||||
}
|
|
||||||
for (let pageIndex = 0; pageIndex < this.pdfDoc.numPages; pageIndex++) {
|
|
||||||
if (pagesMap[`${pageIndex}-offsetWidth`] && pageIndex != currentPage) {
|
|
||||||
const pageElements = pagesMap[pageIndex];
|
|
||||||
pageElements.forEach(elementPage => {
|
|
||||||
const elementIndex = pageElements.findIndex(elementPage => elementPage['element'].id === element.id);
|
|
||||||
if (elementIndex !== -1) {
|
|
||||||
pageElements.splice(elementIndex, 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
await this.goToPage(pageIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
await this.goToPage(currentPage)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
deleteDraggableCanvas(element) {
|
deleteDraggableCanvas(element) {
|
||||||
if (element) {
|
if (element) {
|
||||||
//Check if deleted element is the last interacted
|
//Check if deleted element is the last interacted
|
||||||
@@ -304,7 +241,7 @@ const DraggableUtils = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const draggablesData = pagesMap[this.pageIndex];
|
const draggablesData = pagesMap[this.pageIndex];
|
||||||
if (draggablesData && Array.isArray(draggablesData)) {
|
if (draggablesData) {
|
||||||
draggablesData.forEach((draggableData) => this.boxDragContainer.appendChild(draggableData.element));
|
draggablesData.forEach((draggableData) => this.boxDragContainer.appendChild(draggableData.element));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,13 +273,6 @@ const DraggableUtils = {
|
|||||||
|
|
||||||
//return pdfCanvas.toDataURL();
|
//return pdfCanvas.toDataURL();
|
||||||
},
|
},
|
||||||
|
|
||||||
async goToPage(pageIndex) {
|
|
||||||
this.storePageContents();
|
|
||||||
await this.renderPage(this.pdfDoc, pageIndex);
|
|
||||||
this.loadPageContents();
|
|
||||||
},
|
|
||||||
|
|
||||||
async incrementPage() {
|
async incrementPage() {
|
||||||
if (this.pageIndex < this.pdfDoc.numPages - 1) {
|
if (this.pageIndex < this.pdfDoc.numPages - 1) {
|
||||||
this.storePageContents();
|
this.storePageContents();
|
||||||
@@ -367,7 +297,6 @@ const DraggableUtils = {
|
|||||||
this.storePageContents();
|
this.storePageContents();
|
||||||
|
|
||||||
const pagesMap = this.documentsMap.get(this.pdfDoc);
|
const pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||||
|
|
||||||
for (let pageIdx in pagesMap) {
|
for (let pageIdx in pagesMap) {
|
||||||
if (pageIdx.includes("offset")) {
|
if (pageIdx.includes("offset")) {
|
||||||
continue;
|
continue;
|
||||||
@@ -375,8 +304,7 @@ const DraggableUtils = {
|
|||||||
console.log(typeof pageIdx);
|
console.log(typeof pageIdx);
|
||||||
|
|
||||||
const page = pdfDocModified.getPage(parseInt(pageIdx));
|
const page = pdfDocModified.getPage(parseInt(pageIdx));
|
||||||
let draggablesData = pagesMap[pageIdx];
|
const draggablesData = pagesMap[pageIdx];
|
||||||
|
|
||||||
const offsetWidth = pagesMap[pageIdx + "-offsetWidth"];
|
const offsetWidth = pagesMap[pageIdx + "-offsetWidth"];
|
||||||
const offsetHeight = pagesMap[pageIdx + "-offsetHeight"];
|
const offsetHeight = pagesMap[pageIdx + "-offsetHeight"];
|
||||||
|
|
||||||
@@ -455,6 +383,7 @@ const DraggableUtils = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadPageContents();
|
this.loadPageContents();
|
||||||
return pdfDocModified;
|
return pdfDocModified;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,59 +1,27 @@
|
|||||||
function filterCards() {
|
function filterCards() {
|
||||||
var input = document.getElementById("searchBar");
|
var input = document.getElementById("searchBar");
|
||||||
var filter = input.value.toUpperCase();
|
var filter = input.value.toUpperCase();
|
||||||
|
var cards = document.querySelectorAll(".feature-card");
|
||||||
|
|
||||||
let featureGroups = document.querySelectorAll(".feature-group");
|
for (var i = 0; i < cards.length; i++) {
|
||||||
const collapsedGroups = getCollapsedGroups();
|
var card = cards[i];
|
||||||
|
var title = card.querySelector("h5.card-title").innerText;
|
||||||
|
var text = card.querySelector("p.card-text").innerText;
|
||||||
|
|
||||||
for (const featureGroup of featureGroups) {
|
// Get the navbar tags associated with the card
|
||||||
var cards = featureGroup.querySelectorAll(".feature-card");
|
var navbarItem = document.querySelector(`a.dropdown-item[href="${card.id}"]`);
|
||||||
|
var navbarTags = navbarItem ? navbarItem.getAttribute("data-bs-tags") : "";
|
||||||
|
|
||||||
let groupMatchesFilter = false;
|
var content = title + " " + text + " " + navbarTags;
|
||||||
for (var i = 0; i < cards.length; i++) {
|
|
||||||
var card = cards[i];
|
|
||||||
var title = card.querySelector("h5.card-title").innerText;
|
|
||||||
var text = card.querySelector("p.card-text").innerText;
|
|
||||||
|
|
||||||
// Get the navbar tags associated with the card
|
if (content.toUpperCase().indexOf(filter) > -1) {
|
||||||
var navbarItem = document.querySelector(`a.dropdown-item[href="${card.id}"]`);
|
card.style.display = "";
|
||||||
var navbarTags = navbarItem ? navbarItem.getAttribute("data-bs-tags") : "";
|
|
||||||
|
|
||||||
var content = title + " " + text + " " + navbarTags;
|
|
||||||
|
|
||||||
if (content.toUpperCase().indexOf(filter) > -1) {
|
|
||||||
card.style.display = "";
|
|
||||||
groupMatchesFilter = true;
|
|
||||||
} else {
|
|
||||||
card.style.display = "none";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!groupMatchesFilter) {
|
|
||||||
featureGroup.style.display = "none";
|
|
||||||
} else {
|
} else {
|
||||||
featureGroup.style.display = "";
|
card.style.display = "none";
|
||||||
resetOrTemporarilyExpandGroup(featureGroup, filter, collapsedGroups);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCollapsedGroups() {
|
|
||||||
return localStorage.getItem("collapsedGroups") ? JSON.parse(localStorage.getItem("collapsedGroups")) : [];
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetOrTemporarilyExpandGroup(featureGroup, filterKeywords = "", collapsedGroups = []) {
|
|
||||||
const shouldResetCollapse = filterKeywords.trim() === "";
|
|
||||||
if (shouldResetCollapse) {
|
|
||||||
// Resetting the group's expand/collapse to its original state (as in collapsed groups)
|
|
||||||
const isCollapsed = collapsedGroups.indexOf(featureGroup.id) != -1;
|
|
||||||
expandCollapseToggle(featureGroup, !isCollapsed);
|
|
||||||
} else {
|
|
||||||
// Temporarily expands feature group without affecting the actual/stored collapsed groups
|
|
||||||
featureGroup.classList.remove("collapsed");
|
|
||||||
featureGroup.querySelector(".header-expand-button").classList.remove("collapsed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateFavoritesSection() {
|
function updateFavoritesSection() {
|
||||||
const favoritesContainer = document.getElementById("groupFavorites").querySelector(".feature-group-container");
|
const favoritesContainer = document.getElementById("groupFavorites").querySelector(".feature-group-container");
|
||||||
favoritesContainer.style.maxHeight = "none";
|
favoritesContainer.style.maxHeight = "none";
|
||||||
|
|||||||
@@ -1,21 +1,29 @@
|
|||||||
class DragDropManager {
|
class DragDropManager {
|
||||||
|
dragContainer;
|
||||||
|
wrapper;
|
||||||
|
pageDirection;
|
||||||
|
movePageTo;
|
||||||
|
pageDragging;
|
||||||
|
draggelEl;
|
||||||
|
draggedImageEl;
|
||||||
|
hoveredEl;
|
||||||
|
endInsertionElement;
|
||||||
|
|
||||||
constructor(id, wrapperId) {
|
constructor(id, wrapperId) {
|
||||||
this.dragContainer = document.getElementById(id);
|
this.dragContainer = document.getElementById(id);
|
||||||
this.pageDirection = document.documentElement.getAttribute("dir");
|
this.pageDirection = document.documentElement.getAttribute("dir");
|
||||||
this.wrapper = document.getElementById(wrapperId);
|
this.wrapper = document.getElementById(wrapperId);
|
||||||
this.pageDragging = false;
|
this.pageDragging = false;
|
||||||
this.hoveredEl = undefined;
|
this.hoveredEl = undefined;
|
||||||
|
this.draggelEl = undefined;
|
||||||
this.draggedImageEl = undefined;
|
this.draggedImageEl = undefined;
|
||||||
this.draggedEl = undefined;
|
|
||||||
this.selectedPageElements = []; // Store selected pages for multi-page mode
|
|
||||||
|
|
||||||
// Add CSS dynamically
|
var styleElement = document.createElement("link");
|
||||||
const styleElement = document.createElement("link");
|
|
||||||
styleElement.rel = "stylesheet";
|
styleElement.rel = "stylesheet";
|
||||||
styleElement.href = "css/dragdrop.css";
|
styleElement.href = "css/dragdrop.css";
|
||||||
|
|
||||||
document.head.appendChild(styleElement);
|
document.head.appendChild(styleElement);
|
||||||
|
|
||||||
// Create the endpoint element
|
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
div.classList.add("drag-manager_endpoint");
|
div.classList.add("drag-manager_endpoint");
|
||||||
div.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-arrow-down" viewBox="0 0 16 16">
|
div.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark-arrow-down" viewBox="0 0 16 16">
|
||||||
@@ -24,7 +32,6 @@ class DragDropManager {
|
|||||||
</svg>`;
|
</svg>`;
|
||||||
this.endInsertionElement = div;
|
this.endInsertionElement = div;
|
||||||
|
|
||||||
// Bind methods
|
|
||||||
this.startDraggingPage = this.startDraggingPage.bind(this);
|
this.startDraggingPage = this.startDraggingPage.bind(this);
|
||||||
this.onDragEl = this.onDragEl.bind(this);
|
this.onDragEl = this.onDragEl.bind(this);
|
||||||
this.stopDraggingPage = this.stopDraggingPage.bind(this);
|
this.stopDraggingPage = this.stopDraggingPage.bind(this);
|
||||||
@@ -33,41 +40,20 @@ class DragDropManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
startDraggingPage(div) {
|
startDraggingPage(div) {
|
||||||
if (window.selectPage) {
|
this.pageDragging = true;
|
||||||
// Multi-page drag logic
|
this.draggedEl = div;
|
||||||
this.selectedPageElements = window.selectedPages.map((index) => {
|
const img = div.querySelector("img");
|
||||||
const pageEl = document.getElementById(`page-container-${index}`);
|
div.classList.add("drag-manager_dragging");
|
||||||
if (pageEl) {
|
const imageSrc = img.src;
|
||||||
pageEl.initialTransform = pageEl.style.transform || "translate(0px, 0px)";
|
|
||||||
}
|
|
||||||
return pageEl;
|
|
||||||
}).filter(Boolean);
|
|
||||||
|
|
||||||
if (this.selectedPageElements.length === 0) return;
|
const imgEl = document.createElement("img");
|
||||||
|
imgEl.classList.add("dragged-img");
|
||||||
|
imgEl.src = imageSrc;
|
||||||
|
this.draggedImageEl = imgEl;
|
||||||
|
imgEl.style.visibility = "hidden";
|
||||||
|
imgEl.style.transform = `rotate(${img.style.rotate === "" ? "0deg" : img.style.rotate}) translate(-50%, -50%)`;
|
||||||
|
this.dragContainer.appendChild(imgEl);
|
||||||
|
|
||||||
this.pageDragging = true;
|
|
||||||
this.draggedImageEl = document.createElement("div");
|
|
||||||
this.draggedImageEl.classList.add("multidrag");
|
|
||||||
this.draggedImageEl.textContent = `${this.selectedPageElements.length} ${window.translations.dragDropMessage}`;
|
|
||||||
this.draggedImageEl.style.visibility = "hidden";
|
|
||||||
this.dragContainer.appendChild(this.draggedImageEl);
|
|
||||||
} else {
|
|
||||||
// Single-page drag logic
|
|
||||||
this.pageDragging = true;
|
|
||||||
this.draggedEl = div;
|
|
||||||
const img = div.querySelector("img");
|
|
||||||
div.classList.add("drag-manager_dragging");
|
|
||||||
|
|
||||||
const imgEl = document.createElement("img");
|
|
||||||
imgEl.classList.add("dragged-img");
|
|
||||||
imgEl.src = img.src;
|
|
||||||
imgEl.style.visibility = "hidden";
|
|
||||||
imgEl.style.transform = `rotate(${img.style.rotate === "" ? "0deg" : img.style.rotate}) translate(-50%, -50%)`;
|
|
||||||
this.draggedImageEl = imgEl;
|
|
||||||
this.dragContainer.appendChild(imgEl);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Common setup for both modes
|
|
||||||
window.addEventListener("mouseup", this.stopDraggingPage);
|
window.addEventListener("mouseup", this.stopDraggingPage);
|
||||||
window.addEventListener("mousemove", this.onDragEl);
|
window.addEventListener("mousemove", this.onDragEl);
|
||||||
this.wrapper.classList.add("drag-manager_dragging-container");
|
this.wrapper.classList.add("drag-manager_dragging-container");
|
||||||
@@ -88,43 +74,21 @@ class DragDropManager {
|
|||||||
this.wrapper.classList.remove("drag-manager_dragging-container");
|
this.wrapper.classList.remove("drag-manager_dragging-container");
|
||||||
this.wrapper.removeChild(this.endInsertionElement);
|
this.wrapper.removeChild(this.endInsertionElement);
|
||||||
window.removeEventListener("mouseup", this.stopDraggingPage);
|
window.removeEventListener("mouseup", this.stopDraggingPage);
|
||||||
|
this.draggedImageEl = undefined;
|
||||||
if (this.draggedImageEl) {
|
|
||||||
this.dragContainer.removeChild(this.draggedImageEl);
|
|
||||||
this.draggedImageEl = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window.selectPage) {
|
|
||||||
// Multi-page drop logic
|
|
||||||
if (!this.hoveredEl) {
|
|
||||||
this.selectedPageElements.forEach((pageEl) => {
|
|
||||||
pageEl.style.transform = pageEl.initialTransform || "translate(0px, 0px)";
|
|
||||||
pageEl.classList.remove("drag-manager_dragging");
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.selectedPageElements.forEach((pageEl) => {
|
|
||||||
pageEl.classList.remove("drag-manager_dragging");
|
|
||||||
if (this.hoveredEl === this.endInsertionElement) {
|
|
||||||
this.movePageTo(pageEl);
|
|
||||||
} else {
|
|
||||||
this.movePageTo(pageEl, this.hoveredEl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.selectedPageElements = [];
|
|
||||||
window.resetPages()
|
|
||||||
} else {
|
|
||||||
// Single-page drop logic
|
|
||||||
if (!this.hoveredEl) return;
|
|
||||||
this.draggedEl.classList.remove("drag-manager_dragging");
|
|
||||||
if (this.hoveredEl === this.endInsertionElement) {
|
|
||||||
this.movePageTo(this.draggedEl);
|
|
||||||
} else {
|
|
||||||
this.movePageTo(this.draggedEl, this.hoveredEl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.pageDragging = false;
|
this.pageDragging = false;
|
||||||
|
this.draggedEl.classList.remove("drag-manager_dragging");
|
||||||
|
this.hoveredEl?.classList.remove("drag-manager_draghover");
|
||||||
|
this.dragContainer.childNodes.forEach((dragChild) => {
|
||||||
|
this.dragContainer.removeChild(dragChild);
|
||||||
|
});
|
||||||
|
if (!this.hoveredEl) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.hoveredEl === this.endInsertionElement) {
|
||||||
|
this.movePageTo(this.draggedEl);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.movePageTo(this.draggedEl, this.hoveredEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
setActions({ movePageTo }) {
|
setActions({ movePageTo }) {
|
||||||
|
|||||||
@@ -110,32 +110,31 @@ class PdfActionsManager {
|
|||||||
|
|
||||||
const moveUp = document.createElement("button");
|
const moveUp = document.createElement("button");
|
||||||
moveUp.classList.add("pdf-actions_move-left-button", "btn", "btn-secondary");
|
moveUp.classList.add("pdf-actions_move-left-button", "btn", "btn-secondary");
|
||||||
moveUp.innerHTML = `<span class="material-symbols-rounded">arrow_${leftDirection}_alt</span><span class="btn-tooltip">${window.translations.moveLeft}</span>`;
|
moveUp.innerHTML = `<span class="material-symbols-rounded">arrow_${leftDirection}_alt</span>`;
|
||||||
moveUp.onclick = this.moveUpButtonCallback;
|
moveUp.onclick = this.moveUpButtonCallback;
|
||||||
buttonContainer.appendChild(moveUp);
|
buttonContainer.appendChild(moveUp);
|
||||||
|
|
||||||
const moveDown = document.createElement("button");
|
const moveDown = document.createElement("button");
|
||||||
moveDown.classList.add("pdf-actions_move-right-button", "btn", "btn-secondary");
|
moveDown.classList.add("pdf-actions_move-right-button", "btn", "btn-secondary");
|
||||||
moveDown.innerHTML = `<span class="material-symbols-rounded">arrow_${rightDirection}_alt</span><span class="btn-tooltip">${window.translations.moveRight}</span>`;
|
moveDown.innerHTML = `<span class="material-symbols-rounded">arrow_${rightDirection}_alt</span>`;
|
||||||
moveDown.onclick = this.moveDownButtonCallback;
|
moveDown.onclick = this.moveDownButtonCallback;
|
||||||
buttonContainer.appendChild(moveDown);
|
buttonContainer.appendChild(moveDown);
|
||||||
|
|
||||||
|
|
||||||
const rotateCCW = document.createElement("button");
|
const rotateCCW = document.createElement("button");
|
||||||
rotateCCW.classList.add("btn", "btn-secondary");
|
rotateCCW.classList.add("btn", "btn-secondary");
|
||||||
rotateCCW.innerHTML = `<span class="material-symbols-rounded">rotate_left</span><span class="btn-tooltip">${window.translations.rotateLeft}</span>`;
|
rotateCCW.innerHTML = `<span class="material-symbols-rounded">rotate_left</span>`;
|
||||||
rotateCCW.onclick = this.rotateCCWButtonCallback;
|
rotateCCW.onclick = this.rotateCCWButtonCallback;
|
||||||
buttonContainer.appendChild(rotateCCW);
|
buttonContainer.appendChild(rotateCCW);
|
||||||
|
|
||||||
const rotateCW = document.createElement("button");
|
const rotateCW = document.createElement("button");
|
||||||
rotateCW.classList.add("btn", "btn-secondary");
|
rotateCW.classList.add("btn", "btn-secondary");
|
||||||
rotateCW.innerHTML = `<span class="material-symbols-rounded">rotate_right</span><span class="btn-tooltip">${window.translations.rotateRight}</span>`;
|
rotateCW.innerHTML = `<span class="material-symbols-rounded">rotate_right</span>`;
|
||||||
rotateCW.onclick = this.rotateCWButtonCallback;
|
rotateCW.onclick = this.rotateCWButtonCallback;
|
||||||
buttonContainer.appendChild(rotateCW);
|
buttonContainer.appendChild(rotateCW);
|
||||||
|
|
||||||
const deletePage = document.createElement("button");
|
const deletePage = document.createElement("button");
|
||||||
deletePage.classList.add("btn", "btn-danger");
|
deletePage.classList.add("btn", "btn-danger");
|
||||||
deletePage.innerHTML = `<span class="material-symbols-rounded">delete</span><span class="btn-tooltip"></span><span class="btn-tooltip">${window.translations.delete}</span>`;
|
deletePage.innerHTML = `<span class="material-symbols-rounded">delete</span>`;
|
||||||
deletePage.onclick = this.deletePageButtonCallback;
|
deletePage.onclick = this.deletePageButtonCallback;
|
||||||
buttonContainer.appendChild(deletePage);
|
buttonContainer.appendChild(deletePage);
|
||||||
|
|
||||||
@@ -190,19 +189,19 @@ class PdfActionsManager {
|
|||||||
|
|
||||||
const insertFileButton = document.createElement("button");
|
const insertFileButton = document.createElement("button");
|
||||||
insertFileButton.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button");
|
insertFileButton.classList.add("btn", "btn-primary", "pdf-actions_insert-file-button");
|
||||||
insertFileButton.innerHTML = `<span class="material-symbols-rounded">add</span></span><span class="btn-tooltip">${window.translations.addFile}</span>`;
|
insertFileButton.innerHTML = `<span class="material-symbols-rounded">add</span>`;
|
||||||
insertFileButton.onclick = this.insertFileButtonCallback;
|
insertFileButton.onclick = this.insertFileButtonCallback;
|
||||||
insertFileButtonContainer.appendChild(insertFileButton);
|
insertFileButtonContainer.appendChild(insertFileButton);
|
||||||
|
|
||||||
const splitFileButton = document.createElement("button");
|
const splitFileButton = document.createElement("button");
|
||||||
splitFileButton.classList.add("btn", "btn-primary", "pdf-actions_split-file-button");
|
splitFileButton.classList.add("btn", "btn-primary", "pdf-actions_split-file-button");
|
||||||
splitFileButton.innerHTML = `<span class="material-symbols-rounded">cut</span></span><span class="btn-tooltip">${window.translations.split}</span>`;
|
splitFileButton.innerHTML = `<span class="material-symbols-rounded">cut</span>`;
|
||||||
splitFileButton.onclick = this.splitFileButtonCallback;
|
splitFileButton.onclick = this.splitFileButtonCallback;
|
||||||
insertFileButtonContainer.appendChild(splitFileButton);
|
insertFileButtonContainer.appendChild(splitFileButton);
|
||||||
|
|
||||||
const insertFileBlankButton = document.createElement("button");
|
const insertFileBlankButton = document.createElement("button");
|
||||||
insertFileBlankButton.classList.add("btn", "btn-primary", "pdf-actions_insert-file-blank-button");
|
insertFileBlankButton.classList.add("btn", "btn-primary", "pdf-actions_insert-file-blank-button");
|
||||||
insertFileBlankButton.innerHTML = `<span class="material-symbols-rounded">insert_page_break</span></span><span class="btn-tooltip">${window.translations.insertPageBreak}</span>`;
|
insertFileBlankButton.innerHTML = `<span class="material-symbols-rounded">insert_page_break</span>`;
|
||||||
insertFileBlankButton.onclick = this.insertFileBlankButtonCallback;
|
insertFileBlankButton.onclick = this.insertFileBlankButtonCallback;
|
||||||
insertFileButtonContainer.appendChild(insertFileBlankButton);
|
insertFileButtonContainer.appendChild(insertFileBlankButton);
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ class PdfContainer {
|
|||||||
this.updatePagesFromCSV = this.updatePagesFromCSV.bind(this);
|
this.updatePagesFromCSV = this.updatePagesFromCSV.bind(this);
|
||||||
this.addFilesBlankAll = this.addFilesBlankAll.bind(this)
|
this.addFilesBlankAll = this.addFilesBlankAll.bind(this)
|
||||||
this.removeAllElements = this.removeAllElements.bind(this);
|
this.removeAllElements = this.removeAllElements.bind(this);
|
||||||
this.resetPages = this.resetPages.bind(this);
|
|
||||||
|
|
||||||
this.pdfAdapters = pdfAdapters;
|
this.pdfAdapters = pdfAdapters;
|
||||||
|
|
||||||
@@ -56,7 +55,6 @@ class PdfContainer {
|
|||||||
window.updatePageNumbersAndCheckboxes = this.updatePageNumbersAndCheckboxes;
|
window.updatePageNumbersAndCheckboxes = this.updatePageNumbersAndCheckboxes;
|
||||||
window.addFilesBlankAll = this.addFilesBlankAll
|
window.addFilesBlankAll = this.addFilesBlankAll
|
||||||
window.removeAllElements = this.removeAllElements;
|
window.removeAllElements = this.removeAllElements;
|
||||||
window.resetPages = this.resetPages;
|
|
||||||
|
|
||||||
const filenameInput = document.getElementById("filename-input");
|
const filenameInput = document.getElementById("filename-input");
|
||||||
const downloadBtn = document.getElementById("export-button");
|
const downloadBtn = document.getElementById("export-button");
|
||||||
@@ -122,24 +120,12 @@ class PdfContainer {
|
|||||||
async addFilesFromFiles(files, nextSiblingElement) {
|
async addFilesFromFiles(files, nextSiblingElement) {
|
||||||
this.fileName = files[0].name;
|
this.fileName = files[0].name;
|
||||||
for (var i = 0; i < files.length; i++) {
|
for (var i = 0; i < files.length; i++) {
|
||||||
const startTime = Date.now();
|
|
||||||
let processingTime, errorMessage = null, pageCount = 0;
|
|
||||||
try {
|
|
||||||
const file = files[i];
|
const file = files[i];
|
||||||
if (file.type === "application/pdf") {
|
if (file.type === "application/pdf") {
|
||||||
const { renderer, pdfDocument } = await this.loadFile(file);
|
await this.addPdfFile(file, nextSiblingElement);
|
||||||
pageCount = renderer.pageCount || 0;
|
|
||||||
await this.addPdfFile(renderer, pdfDocument, nextSiblingElement);
|
|
||||||
} else if (file.type.startsWith("image/")) {
|
} else if (file.type.startsWith("image/")) {
|
||||||
await this.addImageFile(file, nextSiblingElement);
|
await this.addImageFile(file, nextSiblingElement);
|
||||||
}
|
}
|
||||||
processingTime = Date.now() - startTime;
|
|
||||||
this.captureFileProcessingEvent(true, file, processingTime, null, pageCount);
|
|
||||||
} catch (error) {
|
|
||||||
processingTime = Date.now() - startTime;
|
|
||||||
errorMessage = error.message || "Unknown error";
|
|
||||||
this.captureFileProcessingEvent(false, files[i], processingTime, errorMessage, pageCount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelectorAll(".enable-on-file").forEach((element) => {
|
document.querySelectorAll(".enable-on-file").forEach((element) => {
|
||||||
@@ -147,23 +133,6 @@ class PdfContainer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
captureFileProcessingEvent(success, file, processingTime, errorMessage, pageCount) {
|
|
||||||
try{
|
|
||||||
if(analyticsEnabled){
|
|
||||||
posthog.capture('file_processing', {
|
|
||||||
success,
|
|
||||||
file_type: file?.type || 'unknown',
|
|
||||||
file_size: file?.size || 0,
|
|
||||||
processing_time: processingTime,
|
|
||||||
error_message: errorMessage,
|
|
||||||
pdf_pages: pageCount,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}catch{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async addFilesBlank(nextSiblingElement) {
|
async addFilesBlank(nextSiblingElement) {
|
||||||
const pdfContent = `
|
const pdfContent = `
|
||||||
%PDF-1.4
|
%PDF-1.4
|
||||||
@@ -217,12 +186,14 @@ class PdfContainer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async addPdfFile(renderer, pdfDocument, nextSiblingElement) {
|
async addPdfFile(file, nextSiblingElement) {
|
||||||
|
const { renderer, pdfDocument } = await this.loadFile(file);
|
||||||
|
|
||||||
for (var i = 0; i < renderer.pageCount; i++) {
|
for (var i = 0; i < renderer.pageCount; i++) {
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
|
|
||||||
div.classList.add("page-container");
|
div.classList.add("page-container");
|
||||||
div.id = "page-container-" + (i + 1);
|
|
||||||
var img = document.createElement("img");
|
var img = document.createElement("img");
|
||||||
img.classList.add("page-image");
|
img.classList.add("page-image");
|
||||||
const imageSrc = await renderer.renderPage(i);
|
const imageSrc = await renderer.renderPage(i);
|
||||||
@@ -231,6 +202,7 @@ class PdfContainer {
|
|||||||
img.rend = renderer;
|
img.rend = renderer;
|
||||||
img.doc = pdfDocument;
|
img.doc = pdfDocument;
|
||||||
div.appendChild(img);
|
div.appendChild(img);
|
||||||
|
|
||||||
this.pdfAdapters.forEach((adapter) => {
|
this.pdfAdapters.forEach((adapter) => {
|
||||||
adapter.adapt?.(div);
|
adapter.adapt?.(div);
|
||||||
});
|
});
|
||||||
@@ -369,8 +341,8 @@ class PdfContainer {
|
|||||||
toggleSelectAll() {
|
toggleSelectAll() {
|
||||||
const checkboxes = document.querySelectorAll(".pdf-actions_checkbox");
|
const checkboxes = document.querySelectorAll(".pdf-actions_checkbox");
|
||||||
window.selectAll = !window.selectAll;
|
window.selectAll = !window.selectAll;
|
||||||
const selectIcon = document.getElementById("select-All-Container");
|
const selectIcon = document.getElementById("select-icon");
|
||||||
const deselectIcon = document.getElementById("deselect-All-Container");
|
const deselectIcon = document.getElementById("deselect-icon");
|
||||||
|
|
||||||
if (selectIcon.style.display === "none") {
|
if (selectIcon.style.display === "none") {
|
||||||
selectIcon.style.display = "inline";
|
selectIcon.style.display = "inline";
|
||||||
@@ -469,7 +441,7 @@ class PdfContainer {
|
|||||||
const selectedPagesList = document.getElementById("selected-pages-list");
|
const selectedPagesList = document.getElementById("selected-pages-list");
|
||||||
const selectedPagesInput = document.getElementById("csv-input");
|
const selectedPagesInput = document.getElementById("csv-input");
|
||||||
selectedPagesList.innerHTML = ""; // Clear the list
|
selectedPagesList.innerHTML = ""; // Clear the list
|
||||||
window.selectedPages.sort((a, b) => a - b);
|
|
||||||
window.selectedPages.forEach((page) => {
|
window.selectedPages.forEach((page) => {
|
||||||
const pageItem = document.createElement("div");
|
const pageItem = document.createElement("div");
|
||||||
pageItem.className = "page-item";
|
pageItem.className = "page-item";
|
||||||
@@ -729,31 +701,6 @@ class PdfContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resetPages() {
|
|
||||||
const pageContainers = this.pagesContainer.querySelectorAll(".page-container");
|
|
||||||
|
|
||||||
pageContainers.forEach((container, index) => {
|
|
||||||
container.id = "page-container-" + (index + 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
const checkboxes = document.querySelectorAll(".pdf-actions_checkbox");
|
|
||||||
window.selectAll = false;
|
|
||||||
const selectIcon = document.getElementById("select-All-Container");
|
|
||||||
const deselectIcon = document.getElementById("deselect-All-Container");
|
|
||||||
|
|
||||||
selectIcon.style.display = "inline";
|
|
||||||
deselectIcon.style.display = "none";
|
|
||||||
|
|
||||||
checkboxes.forEach((checkbox) => {
|
|
||||||
const pageNumber = Array.from(checkbox.parentNode.parentNode.children).indexOf(checkbox.parentNode) + 1;
|
|
||||||
|
|
||||||
const index = window.selectedPages.indexOf(pageNumber);
|
|
||||||
if (index !== -1) {
|
|
||||||
window.selectedPages.splice(index, 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
window.toggleSelectPageVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
setDownloadAttribute() {
|
setDownloadAttribute() {
|
||||||
this.downloadLink.setAttribute("download", this.fileName ? this.fileName : "managed.pdf");
|
this.downloadLink.setAttribute("download", this.fileName ? this.fileName : "managed.pdf");
|
||||||
@@ -798,7 +745,7 @@ class PdfContainer {
|
|||||||
const selectedPages = document.getElementById("selected-pages-display");
|
const selectedPages = document.getElementById("selected-pages-display");
|
||||||
selectedPages.classList.toggle("hidden", !window.selectPage);
|
selectedPages.classList.toggle("hidden", !window.selectPage);
|
||||||
const selectAll = document.getElementById("select-All-Container");
|
const selectAll = document.getElementById("select-All-Container");
|
||||||
selectAll.classList.toggle("hidden", !window.selectPage);
|
selectedPages.classList.toggle("hidden", !window.selectPage);
|
||||||
const exportSelected = document.getElementById("export-selected-button");
|
const exportSelected = document.getElementById("export-selected-button");
|
||||||
exportSelected.classList.toggle("hidden", !window.selectPage);
|
exportSelected.classList.toggle("hidden", !window.selectPage);
|
||||||
const selectPagesButton = document.getElementById("select-pages-button");
|
const selectPagesButton = document.getElementById("select-pages-button");
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ window.onload = function () {
|
|||||||
// Show search results as user types in search box
|
// Show search results as user types in search box
|
||||||
document.querySelector("#navbarSearchInput").addEventListener("input", function (e) {
|
document.querySelector("#navbarSearchInput").addEventListener("input", function (e) {
|
||||||
var searchText = e.target.value.trim().toLowerCase(); // Trim whitespace and convert to lowercase
|
var searchText = e.target.value.trim().toLowerCase(); // Trim whitespace and convert to lowercase
|
||||||
var items = document.querySelectorAll('a.dropdown-item[data-bs-tags]');
|
var items = document.querySelectorAll(".dropdown-item, .nav-link");
|
||||||
var resultsBox = document.querySelector("#searchResults");
|
var resultsBox = document.querySelector("#searchResults");
|
||||||
|
|
||||||
// Clear any previous results
|
// Clear any previous results
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<form id="PDFToCSVForm" th:action="@{'/api/v1/convert/pdf/csv'}" method="post" enctype="multipart/form-data">
|
<form id="PDFToCSVForm" th:action="@{'/api/v1/convert/pdf/csv'}" method="post" enctype="multipart/form-data">
|
||||||
<input id="pageId" type="hidden" name="pageId">
|
<input id="pageId" type="hidden" name="pageId">
|
||||||
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}"></div>
|
||||||
<button type="submit" class="btn btn-primary" th:text="#{PDFToCSV.submit}" id="submitBtn"></button>
|
<button type="submit" class="btn btn-primary" th:text="#{PDFToCSV.submit}"></button>
|
||||||
</form>
|
</form>
|
||||||
<p id="instruction-text" style="margin: 0; display: none" th:text="#{PDFToCSV.prompt}"></p>
|
<p id="instruction-text" style="margin: 0; display: none" th:text="#{PDFToCSV.prompt}"></p>
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<div class="col-md-9 bg-card">
|
<div class="col-md-9 bg-card">
|
||||||
<div class="tool-header">
|
<div class="tool-header">
|
||||||
<span class="material-symbols-rounded tool-header-icon organize">database</span>
|
<span class="material-symbols-rounded tool-header-icon organize">database</span>
|
||||||
<span class="tool-header-text" th:text="#{database.title}">Database Im-/Export</span>
|
<span class="tool-header-text" text="#{database.title}">Database Im-/Export</span>
|
||||||
</div>
|
</div>
|
||||||
<p th:if="${error}" th:text="#{'database.' + ${error}}" class="alert alert-danger text-center"></p>
|
<p th:if="${error}" th:text="#{'database.' + ${error}}" class="alert alert-danger text-center"></p>
|
||||||
<p th:if="${infoMessage}" th:text="#{'database.' + ${infoMessage}}" class="alert alert-success text-center"></p>
|
<p th:if="${infoMessage}" th:text="#{'database.' + ${infoMessage}}" class="alert alert-success text-center"></p>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr th:each="backup : ${backupFiles}">
|
<tr th:each="backup : ${systemUpdate}">
|
||||||
<td th:text="${backup.fileName}"></td>
|
<td th:text="${backup.fileName}"></td>
|
||||||
<td th:text="${backup.formattedCreationDate}"></td>
|
<td th:text="${backup.formattedCreationDate}"></td>
|
||||||
<td th:text="${backup.formattedFileSize}"></td>
|
<td th:text="${backup.formattedFileSize}"></td>
|
||||||
@@ -41,11 +41,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<h6 class="text-end"><span class="badge bg-dark" th:text="${databaseVersion}">DB-Version</span></h6>
|
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<form th:action="@{'/api/v1/database/import-database'}" method="post" enctype="multipart/form-data" class="bg-card mt-3 mb-3">
|
<form th:action="@{'/api/v1/database/import-database'}" method="post" enctype="multipart/form-data" class="bg-card mt-3 mb-3">
|
||||||
<div style="background: var(--md-sys-color-error-container);border-radius: 2rem;" class="mb-3 p-3">
|
<div style="background: var(--md-sys-color-error-container);padding: .8rem;border-radius: 2rem;" class="mb-3">
|
||||||
<p th:text="#{database.info_1}"></p>
|
<p th:text="#{database.info_1}"></p>
|
||||||
<p th:text="#{database.info_2}"></p>
|
<p th:text="#{database.info_2}"></p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ca_CA"> <img th:src="@{'/images/flags/es-ct.svg'}" alt="icon" width="20" height="15"> Català</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ca_CA"> <img th:src="@{'/images/flags/es-ct.svg'}" alt="icon" width="20" height="15"> Català</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="zh_CN"> <img th:src="@{'/images/flags/cn.svg'}" alt="icon" width="20" height="15"> 简体中文</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="zh_CN"> <img th:src="@{'/images/flags/cn.svg'}" alt="icon" width="20" height="15"> 简体中文</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="zh_TW"> <img th:src="@{'/images/flags/tw.svg'}" alt="icon" width="20" height="15"> 繁體中文</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="zh_TW"> <img th:src="@{'/images/flags/tw.svg'}" alt="icon" width="20" height="15"> 繁體中文</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="az_AZ"> <img th:src="@{'/images/flags/az.svg'}" alt="icon" width="20" height="15"> Azərbaycan Dili</a>
|
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="da_DK"> <img th:src="@{'/images/flags/dk.svg'}" alt="icon" width="20" height="15"> Dansk</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="da_DK"> <img th:src="@{'/images/flags/dk.svg'}" alt="icon" width="20" height="15"> Dansk</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="de_DE"> <img th:src="@{'/images/flags/de.svg'}" alt="icon" width="20" height="15"> Deutsch</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="de_DE"> <img th:src="@{'/images/flags/de.svg'}" alt="icon" width="20" height="15"> Deutsch</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="en_GB"> <img th:src="@{'/images/flags/gb.svg'}" alt="icon" width="20" height="15"> English (GB)</a>
|
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="en_GB"> <img th:src="@{'/images/flags/gb.svg'}" alt="icon" width="20" height="15"> English (GB)</a>
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
<div>
|
<div>
|
||||||
<span th:utext="#{multiTool-advert.message(|/multi-tool|)}"></span>
|
<span th:utext="#{multiTool-advert.message(|/multi-tool|)}"></span>
|
||||||
<button id="closeMultiToolAdvert" style="position: absolute;
|
<button id="closeMultiToolAdvert" style="position: absolute;
|
||||||
inset-inline-end: 12px;
|
top: 10px;
|
||||||
inset-block-start: 10px;
|
right: 12px;
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: white;
|
color: white;
|
||||||
@@ -16,13 +16,13 @@
|
|||||||
<style>
|
<style>
|
||||||
.multi-toolAdvert {
|
.multi-toolAdvert {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
margin-inline-start: 50%;
|
margin-left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
max-width: 52rem;
|
max-width: 52rem;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
background-color: var(--md-sys-color-surface-5);
|
background-color: var(--md-sys-color-surface-5);
|
||||||
border-radius: 2rem;
|
border-radius: 2rem;
|
||||||
padding-block: 10px;
|
padding: 10px 27px 10px 20px;
|
||||||
padding-inline: 20px 27px;
|
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
display: none;
|
display: none;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -43,7 +43,6 @@
|
|||||||
const closeBtn = document.getElementById('closeMultiToolAdvert');
|
const closeBtn = document.getElementById('closeMultiToolAdvert');
|
||||||
|
|
||||||
const cacheKey = `closeMultiToolAdvert_${window.location.pathname}`;
|
const cacheKey = `closeMultiToolAdvert_${window.location.pathname}`;
|
||||||
const isRTL = document.documentElement.dir === 'rtl';
|
|
||||||
|
|
||||||
if (localStorage.getItem(cacheKey) !== 'true') {
|
if (localStorage.getItem(cacheKey) !== 'true') {
|
||||||
advert.style.display = 'flex';
|
advert.style.display = 'flex';
|
||||||
@@ -53,13 +52,6 @@
|
|||||||
advert.style.display = 'none';
|
advert.style.display = 'none';
|
||||||
localStorage.setItem(cacheKey, 'true');
|
localStorage.setItem(cacheKey, 'true');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
if (isRTL) {
|
|
||||||
advert.style.transform = 'translateX(50%)'; // Flip direction for RTL
|
|
||||||
} else {
|
|
||||||
advert.style.transform = 'translateX(-50%)';
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
<div class="navbar-item col-lg-2 col-sm-6 py px-xl-1 px-2">
|
<div class="navbar-item col-lg-2 col-sm-6 py px-xl-1 px-2">
|
||||||
<h6 class="menu-title" th:text="#{navbar.sections.organize}"></h6>
|
<h6 class="menu-title" th:text="#{navbar.sections.organize}"></h6>
|
||||||
<div
|
<div
|
||||||
th:replace="~{fragments/navbarEntry :: navbarEntry ('multi-tool', 'construction', 'home.multiTool.title', 'home.multiTool.desc', 'multiTool.tags', 'organize')}">
|
th:replace="~{fragments/navbarEntry :: navbarEntry ('compress-pdf', 'zoom_in_map', 'home.compressPdfs.title', 'home.compressPdfs.desc', 'compressPdfs.tags', 'advance')}">
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
th:replace="~{fragments/navbarEntry :: navbarEntry ('merge-pdfs', 'add_to_photos', 'home.merge.title', 'home.merge.desc', 'merge.tags', 'organize')}">
|
th:replace="~{fragments/navbarEntry :: navbarEntry ('merge-pdfs', 'add_to_photos', 'home.merge.title', 'home.merge.desc', 'merge.tags', 'organize')}">
|
||||||
@@ -214,7 +214,7 @@
|
|||||||
<div class="navbar-item col-lg-2 col-sm-6 py px-xl-1 px-2">
|
<div class="navbar-item col-lg-2 col-sm-6 py px-xl-1 px-2">
|
||||||
<h6 class="menu-title" th:text="#{navbar.sections.advance}"></h6>
|
<h6 class="menu-title" th:text="#{navbar.sections.advance}"></h6>
|
||||||
<div
|
<div
|
||||||
th:replace="~{fragments/navbarEntry :: navbarEntry ('compress-pdf', 'zoom_in_map', 'home.compressPdfs.title', 'home.compressPdfs.desc', 'compressPdfs.tags', 'advance')}">
|
th:replace="~{fragments/navbarEntry :: navbarEntry ('multi-tool', 'construction', 'home.multiTool.title', 'home.multiTool.desc', 'multiTool.tags', 'advance')}">
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
th:replace="~{fragments/navbarEntry :: navbarEntry ('pipeline', 'family_history', 'home.pipeline.title', 'home.pipeline.desc', 'pipeline.tags', 'advance')}">
|
th:replace="~{fragments/navbarEntry :: navbarEntry ('pipeline', 'family_history', 'home.pipeline.title', 'home.pipeline.desc', 'pipeline.tags', 'advance')}">
|
||||||
|
|||||||
@@ -31,79 +31,64 @@
|
|||||||
<span class="material-symbols-rounded">
|
<span class="material-symbols-rounded">
|
||||||
add
|
add
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.addFile}"></span>
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-secondary enable-on-file" onclick="rotateAll(-90)" disabled>
|
<button class="btn btn-secondary enable-on-file" onclick="rotateAll(-90)" disabled>
|
||||||
<span class="material-symbols-rounded">
|
<span class="material-symbols-rounded">
|
||||||
rotate_left
|
rotate_left
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.rotateLeft}"></span>
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-secondary enable-on-file" onclick="rotateAll(90)" disabled>
|
<button class="btn btn-secondary enable-on-file" onclick="rotateAll(90)" disabled>
|
||||||
<span class="material-symbols-rounded">
|
<span class="material-symbols-rounded">
|
||||||
rotate_right
|
rotate_right
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.rotateRight}"></span>
|
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-secondary enable-on-file" onclick="splitAll()" disabled>
|
<button class="btn btn-secondary enable-on-file" onclick="splitAll()" disabled>
|
||||||
<span class="material-symbols-rounded">
|
<span class="material-symbols-rounded">
|
||||||
cut
|
cut
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.split}"></span>
|
</button>
|
||||||
|
<button id="select-pages-container" class="btn btn-secondary enable-on-file"
|
||||||
|
th:title="#{multiTool.selectPages}" onclick="toggleSelectPageVisibility()" disabled>
|
||||||
|
<span id="select-pages-button" class="material-symbols-rounded">
|
||||||
|
event_list
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<button id="select-All-Container" class="btn btn-secondary enable-on-file hidden"
|
||||||
|
onclick="toggleSelectAll()" disabled>
|
||||||
|
<span th:title="#{multiTool.selectAll}" class="material-symbols-rounded"
|
||||||
|
id="select-icon">select_all</span>
|
||||||
|
<span th:title="#{multiTool.deselectAll}" class="material-symbols-rounded" style="display: none;"
|
||||||
|
id="deselect-icon">deselect</span>
|
||||||
|
</button>
|
||||||
|
<div class=" button-container">
|
||||||
|
<button th:title="#{multiTool.deleteSelected}" id="delete-button" class="btn btn-danger hidden"
|
||||||
|
onclick="deleteSelected()">
|
||||||
|
<span class="material-symbols-rounded">delete</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button id="export-selected-button" class="btn btn-primary enable-on-file hidden"
|
||||||
|
onclick="exportPdf(true)" disabled>
|
||||||
|
<span th:title="#{multiTool.downloadSelected}" class="material-symbols-rounded">
|
||||||
|
file_save
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-secondary enable-on-file" onclick="addFilesBlankAll()" disabled>
|
<button class="btn btn-secondary enable-on-file" onclick="addFilesBlankAll()" disabled>
|
||||||
<span class="material-symbols-rounded">
|
<span class="material-symbols-rounded">
|
||||||
insert_page_break
|
insert_page_break
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.insertPageBreak}"></span>
|
|
||||||
</button>
|
</button>
|
||||||
<button id="select-pages-container" class="btn btn-secondary enable-on-file"
|
<button id="export-button" class="btn btn-primary enable-on-file" onclick="exportPdf(false)" disabled>
|
||||||
onclick="toggleSelectPageVisibility()" disabled>
|
<span th:title="#{multiTool.downloadAll}" class="material-symbols-rounded">
|
||||||
<span id="select-pages-button" class="material-symbols-rounded">
|
download
|
||||||
event_list
|
|
||||||
</span>
|
</span>
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.selectPages}"></span>
|
|
||||||
|
|
||||||
</button>
|
</button>
|
||||||
<button id="deselect-All-Container" class="btn btn-secondary enable-on-file hidden"
|
|
||||||
onclick="toggleSelectAll()" disabled>
|
|
||||||
<span class="material-symbols-rounded" id="deselect-icon">deselect</span>
|
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.deselectAll}"></span>
|
|
||||||
</button>
|
|
||||||
<button id="select-All-Container" class="btn btn-secondary enable-on-file hidden"
|
|
||||||
onclick="toggleSelectAll()" disabled>
|
|
||||||
<span class="material-symbols-rounded"
|
|
||||||
id="select-icon">select_all</span>
|
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.selectAll}"></span>
|
|
||||||
</button>
|
|
||||||
<div class="button-container">
|
|
||||||
<button id="delete-button" class="btn btn-danger delete hidden" onclick="deleteSelected()">
|
|
||||||
<span class="material-symbols-rounded">delete</span>
|
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.deleteSelected}"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div style="margin-left:auto">
|
|
||||||
<button id="export-selected-button" class="btn btn-primary enable-on-file hidden"
|
|
||||||
onclick="exportPdf(true)" disabled>
|
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.downloadSelected}"></span>
|
|
||||||
<span class="material-symbols-rounded">
|
|
||||||
file_save
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button id="export-button" class="btn btn-primary enable-on-file" onclick="exportPdf(false)"
|
|
||||||
disabled>
|
|
||||||
<span class="material-symbols-rounded">
|
|
||||||
download
|
|
||||||
</span>
|
|
||||||
<span class="btn-tooltip" th:text="#{multiTool.downloadAll}"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="selected-pages-display" class="selected-pages-container hidden">
|
<div id="selected-pages-display" class="selected-pages-container hidden">
|
||||||
<div style="display:flex; height:3rem; margin-right:1rem">
|
<div style="display:flex; height:3rem; margin-right:1rem">
|
||||||
<h5 th:text="#{multiTool.selectedPages}" style="white-space: nowrap; margin-right: 1rem;">Selected
|
<h5 th:text="#{multiTool.selectedPages}" style="white-space: nowrap; margin-right: 1rem;">Selected
|
||||||
Pages</h5>
|
Pages</h5>
|
||||||
<input type="text" id="csv-input" class="form-control" style="height:2.5rem" placeholder="1,3,5-10" value="">
|
<input type="text" id="csv-input" class="form-control" style="height:2.5rem" placeholder="1,3,5-10"
|
||||||
|
value="">
|
||||||
</div>
|
</div>
|
||||||
<ul id="selected-pages-list" class="pages-list"></ul>
|
<ul id="selected-pages-list" class="pages-list"></ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -112,6 +97,13 @@
|
|||||||
<div class="multi-tool-container">
|
<div class="multi-tool-container">
|
||||||
<div class="d-flex flex-wrap" id="pages-container-wrapper">
|
<div class="d-flex flex-wrap" id="pages-container-wrapper">
|
||||||
<div id="pages-container">
|
<div id="pages-container">
|
||||||
|
<div class="page-container" th:each="file, status: ${fileList}"
|
||||||
|
th:id="'page-container-' + ${status.index}">
|
||||||
|
<div class="page-number-container">
|
||||||
|
<span th:text="${status.index + 1}"></span>
|
||||||
|
</div>
|
||||||
|
<img th:src="${file.imageUrl}" alt="File Page">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -129,21 +121,6 @@
|
|||||||
window.selectedPages = [];
|
window.selectedPages = [];
|
||||||
window.selectPage = false;
|
window.selectPage = false;
|
||||||
window.selectAll = false;
|
window.selectAll = false;
|
||||||
|
|
||||||
window.translations = {
|
|
||||||
rotateLeft: '[[#{multiTool.rotateLeft}]]',
|
|
||||||
rotateRight: '[[#{multiTool.rotateRight}]]',
|
|
||||||
moveLeft: '[[#{multiTool.moveLeft}]]',
|
|
||||||
moveRight: '[[#{multiTool.moveRight}]]',
|
|
||||||
delete: '[[#{multiTool.delete}]]',
|
|
||||||
split: '[[#{multiTool.split}]]',
|
|
||||||
addFile: '[[#{multiTool.addFile}]]',
|
|
||||||
insertPageBreak:'[[#{multiTool.insertPageBreak}]]',
|
|
||||||
dragDropMessage:'[[#{multiTool.dragDropMessage}]]'
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const csvInput = document.getElementById("csv-input");
|
const csvInput = document.getElementById("csv-input");
|
||||||
csvInput.addEventListener("keydown", function (event) {
|
csvInput.addEventListener("keydown", function (event) {
|
||||||
if (event.key === "Enter") {
|
if (event.key === "Enter") {
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}"
|
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
|
||||||
xmlns:th="https://www.thymeleaf.org">
|
<head>
|
||||||
|
|
||||||
<head>
|
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{sign.title}, header=#{sign.header})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{sign.title}, header=#{sign.header})}"></th:block>
|
||||||
<link rel="stylesheet" th:href="@{'/css/sign.css'}">
|
<link rel="stylesheet" th:href="@{'/css/sign.css'}">
|
||||||
|
|
||||||
<th:block th:each="font : ${fonts}">
|
<th:block th:each="font : ${fonts}">
|
||||||
<style th:inline="text">
|
<style th:inline="text">
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "[[${font.name}]]";
|
font-family: "[[${font.name}]]";
|
||||||
@@ -18,435 +16,372 @@
|
|||||||
cursive;
|
cursive;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
<script th:src="@{'/js/thirdParty/signature_pad.umd.min.js'}"></script>
|
<script th:src="@{'/js/thirdParty/signature_pad.umd.min.js'}"></script>
|
||||||
<script th:src="@{'/js/thirdParty/interact.min.js'}"></script>
|
<script th:src="@{'/js/thirdParty/interact.min.js'}"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="page-container">
|
<div id="page-container">
|
||||||
<div id="content-wrap">
|
<div id="content-wrap">
|
||||||
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||||
<br><br>
|
<br><br>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-6 bg-card">
|
<div class="col-md-6 bg-card">
|
||||||
<div class="tool-header">
|
<div class="tool-header">
|
||||||
<span class="material-symbols-rounded tool-header-icon sign">signature</span>
|
<span class="material-symbols-rounded tool-header-icon sign">signature</span>
|
||||||
<span class="tool-header-text" th:text="#{sign.header}"></span>
|
<span class="tool-header-text" th:text="#{sign.header}"></span>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- pdf selector -->
|
|
||||||
<div
|
|
||||||
th:replace="~{fragments/common :: fileSelector(name='pdf-upload', multipleInputsForSingleRequest=false, disableMultipleFiles=true, accept='application/pdf')}">
|
|
||||||
</div>
|
|
||||||
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
|
|
||||||
<script>
|
|
||||||
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');
|
|
||||||
|
|
||||||
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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function previewSignature(element) {
|
|
||||||
const src = element.dataset.src;
|
|
||||||
currentPreviewSrc = src;
|
|
||||||
|
|
||||||
// Extract filename from the data source path
|
|
||||||
const filename = element.querySelector('.signature-list-name').textContent;
|
|
||||||
|
|
||||||
// Update preview modal
|
|
||||||
const previewImage = document.getElementById('previewImage');
|
|
||||||
const previewFileName = document.getElementById('previewFileName');
|
|
||||||
|
|
||||||
previewImage.src = src;
|
|
||||||
previewFileName.textContent = filename;
|
|
||||||
|
|
||||||
const modal = new bootstrap.Modal(document.getElementById('signaturePreview'));
|
|
||||||
modal.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function addSignatureFromPreview() {
|
|
||||||
if (currentPreviewSrc) {
|
|
||||||
DraggableUtils.createDraggableCanvasFromUrl(currentPreviewSrc);
|
|
||||||
bootstrap.Modal.getInstance(document.getElementById('signaturePreview')).hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let originalFileName = '';
|
|
||||||
document.querySelector('input[name=pdf-upload]').addEventListener('change', async (event) => {
|
|
||||||
const file = event.target.files[0];
|
|
||||||
if (file) {
|
|
||||||
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";
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<div class="tab-group show-on-file-selected">
|
|
||||||
<div class="tab-container" th:title="#{sign.upload}">
|
|
||||||
<div
|
|
||||||
th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=true, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}">
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-container drawing-pad-container" th:title="#{sign.draw}">
|
<!-- pdf selector -->
|
||||||
<canvas id="drawing-pad-canvas"></canvas>
|
<div th:replace="~{fragments/common :: fileSelector(name='pdf-upload', multipleInputsForSingleRequest=false, disableMultipleFiles=true, accept='application/pdf')}"></div>
|
||||||
<br>
|
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
|
||||||
<button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()"
|
<script>
|
||||||
th:text="#{sign.clear}"></button>
|
let currentPreviewSrc = null;
|
||||||
<button id="save-signature" class="btn btn-outline-success mt-2" onclick="addDraggableFromPad()"
|
|
||||||
th:text="#{sign.add}"></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tab-container" th:title="#{sign.saved}">
|
function toggleSignatureView() {
|
||||||
<div class="saved-signatures-section" th:if="${not #lists.isEmpty(signatures)}">
|
const gridView = document.getElementById('gridView');
|
||||||
<!-- View Toggle Button -->
|
const listView = document.getElementById('listView');
|
||||||
<div class="view-toggle mb-3">
|
const gridText = document.querySelector('.grid-view-text');
|
||||||
<button class="btn btn-outline-secondary btn-sm" onclick="toggleSignatureView()">
|
const listText = document.querySelector('.list-view-text');
|
||||||
<span class="material-symbols-rounded grid-view-text">view_list</span>
|
|
||||||
<span class="material-symbols-rounded list-view-text" style="display: none;">grid_view</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Preview Modal -->
|
if (gridView.style.display !== 'none') {
|
||||||
<div class="modal fade" id="signaturePreview" tabindex="-1">
|
gridView.style.display = 'none';
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
listView.style.display = 'block';
|
||||||
<div class="modal-content">
|
gridText.style.display = 'none';
|
||||||
<div class="modal-header">
|
listText.style.display = 'inline';
|
||||||
<h5 class="modal-title"><span id="previewFileName"></span></h5>
|
} else {
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
gridView.style.display = 'block';
|
||||||
</div>
|
listView.style.display = 'none';
|
||||||
<div class="modal-body text-center">
|
gridText.style.display = 'inline';
|
||||||
<img id="previewImage" src="" alt="Signature Preview" style="max-width: 100%;">
|
listText.style.display = 'none';
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"
|
|
||||||
th:text="#{close}"></button>
|
|
||||||
<button type="button" class="btn btn-primary" onclick="addSignatureFromPreview()"
|
|
||||||
th:text="#{addToDoc}">Add to Document</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Grid View -->
|
|
||||||
<div id="gridView">
|
|
||||||
<!-- Personal Signatures -->
|
|
||||||
<div class="signature-category" th:if="${not #lists.isEmpty(signatures.?[category == 'Personal'])}">
|
|
||||||
<h5 th:text="#{sign.personalSigs}"></h5>
|
|
||||||
<div class="signature-grid">
|
|
||||||
<div th:each="sig : ${signatures}" th:if="${sig.category == 'Personal'}" class="signature-item">
|
|
||||||
<img th:src="@{'/api/v1/general/sign/' + ${sig.fileName}}" th:alt="${sig.fileName}"
|
|
||||||
th:data-filename="${sig.fileName}" style="max-width: 200px; cursor: pointer;"
|
|
||||||
onclick="DraggableUtils.createDraggableCanvasFromUrl(this.src)" />
|
|
||||||
<div class="signature-name" th:text="${sig.fileName}"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Shared Signatures -->
|
|
||||||
<div class="signature-category" th:if="${not #lists.isEmpty(signatures.?[category == 'Shared'])}">
|
|
||||||
<h5 th:text="#{sign.sharedSigs}"></h5>
|
|
||||||
<div class="signature-grid">
|
|
||||||
<div th:each="sig : ${signatures}" th:if="${sig.category == 'Shared'}" class="signature-item">
|
|
||||||
<img th:src="@{'/api/v1/general/sign/' + ${sig.fileName}}" th:alt="${sig.fileName}"
|
|
||||||
th:data-filename="${sig.fileName}" style="max-width: 200px; cursor: pointer;"
|
|
||||||
onclick="DraggableUtils.createDraggableCanvasFromUrl(this.src)" />
|
|
||||||
<div class="signature-name" th:text="${sig.fileName}"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- List View (Initially Hidden) -->
|
|
||||||
<div id="listView" style="display: none;">
|
|
||||||
<!-- Personal Signatures -->
|
|
||||||
<div class="signature-category" th:if="${not #lists.isEmpty(signatures.?[category == 'Personal'])}">
|
|
||||||
<h5 th:text="#{sign.personalSigs}"></h5>
|
|
||||||
<div class="signature-list">
|
|
||||||
<div th:each="sig : ${signatures}" th:if="${sig.category == 'Personal'}"
|
|
||||||
class="signature-list-item" th:data-src="@{'/api/v1/general/sign/' + ${sig.fileName}}"
|
|
||||||
onclick="previewSignature(this)">
|
|
||||||
<div class="signature-list-info">
|
|
||||||
<span th:text="${sig.fileName}" class="signature-list-name"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Shared Signatures -->
|
|
||||||
<div class="signature-category" th:if="${not #lists.isEmpty(signatures.?[category == 'Shared'])}">
|
|
||||||
<h5 th:text="#{sign.sharedSigs}"></h5>
|
|
||||||
<div class="signature-list">
|
|
||||||
<div th:each="sig : ${signatures}" th:if="${sig.category == 'Shared'}"
|
|
||||||
class="signature-list-item" th:data-src="@{'/api/v1/general/sign/' + ${sig.fileName}}"
|
|
||||||
onclick="previewSignature(this)">
|
|
||||||
<div class="signature-list-info">
|
|
||||||
<span th:text="${sig.fileName}" class="signature-list-name"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div th:if="${#lists.isEmpty(signatures)}" class="text-center p-3">
|
|
||||||
<p th:text="#{sign.noSavedSigs}">No saved signatures found</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tab-container" th:title="#{sign.text}">
|
|
||||||
<label class="form-check-label" for="sigText" th:text="#{text}"></label>
|
|
||||||
<textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
|
|
||||||
<label th:text="#{font}"></label>
|
|
||||||
<select class="form-control" name="font" id="font-select">
|
|
||||||
<option th:each="font : ${fonts}" th:value="${font.name}" th:text="${font.name}"
|
|
||||||
th:class="${font.name.toLowerCase()+'-font'}"></option>
|
|
||||||
</select>
|
|
||||||
<div class="margin-auto-parent">
|
|
||||||
<button id="save-text-signature" class="btn btn-outline-success mt-2 margin-center"
|
|
||||||
onclick="addDraggableFromText()" th:text="#{sign.add}"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
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();
|
|
||||||
reader.readAsDataURL(imageFile);
|
|
||||||
reader.onloadend = function (e) {
|
|
||||||
DraggableUtils.createDraggableCanvasFromUrl(e.target.result);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<script>
|
|
||||||
const signaturePadCanvas = document.getElementById('drawing-pad-canvas');
|
|
||||||
const signaturePad = new SignaturePad(signaturePadCanvas, {
|
|
||||||
minWidth: 1,
|
|
||||||
maxWidth: 2,
|
|
||||||
penColor: 'black',
|
|
||||||
});
|
|
||||||
|
|
||||||
function addDraggableFromPad() {
|
|
||||||
if (signaturePad.isEmpty()) return;
|
|
||||||
const startTime = Date.now();
|
|
||||||
const croppedDataUrl = getCroppedCanvasDataUrl(signaturePadCanvas);
|
|
||||||
console.log(Date.now() - startTime);
|
|
||||||
DraggableUtils.createDraggableCanvasFromUrl(croppedDataUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCroppedCanvasDataUrl(canvas) {
|
|
||||||
let originalCtx = canvas.getContext('2d');
|
|
||||||
let originalWidth = canvas.width;
|
|
||||||
let originalHeight = canvas.height;
|
|
||||||
let imageData = originalCtx.getImageData(0, 0, originalWidth, originalHeight);
|
|
||||||
|
|
||||||
let minX = originalWidth + 1, maxX = -1, minY = originalHeight + 1, maxY = -1, x = 0, y = 0, currentPixelColorValueIndex;
|
|
||||||
|
|
||||||
for (y = 0; y < originalHeight; y++) {
|
|
||||||
for (x = 0; x < originalWidth; x++) {
|
|
||||||
currentPixelColorValueIndex = (y * originalWidth + x) * 4;
|
|
||||||
let currentPixelAlphaValue = imageData.data[currentPixelColorValueIndex + 3];
|
|
||||||
if (currentPixelAlphaValue > 0) {
|
|
||||||
if (minX > x) minX = x;
|
|
||||||
if (maxX < x) maxX = x;
|
|
||||||
if (minY > y) minY = y;
|
|
||||||
if (maxY < y) maxY = y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let croppedWidth = maxX - minX;
|
function previewSignature(element) {
|
||||||
let croppedHeight = maxY - minY;
|
const src = element.dataset.src;
|
||||||
if (croppedWidth < 0 || croppedHeight < 0) return null;
|
currentPreviewSrc = src;
|
||||||
let cuttedImageData = originalCtx.getImageData(minX, minY, croppedWidth, croppedHeight);
|
|
||||||
|
|
||||||
let croppedCanvas = document.createElement('canvas'),
|
// Extract filename from the data source path
|
||||||
croppedCtx = croppedCanvas.getContext('2d');
|
const filename = element.querySelector('.signature-list-name').textContent;
|
||||||
|
|
||||||
croppedCanvas.width = croppedWidth;
|
// Update preview modal
|
||||||
croppedCanvas.height = croppedHeight;
|
const previewImage = document.getElementById('previewImage');
|
||||||
croppedCtx.putImageData(cuttedImageData, 0, 0);
|
const previewFileName = document.getElementById('previewFileName');
|
||||||
|
|
||||||
return croppedCanvas.toDataURL();
|
previewImage.src = src;
|
||||||
}
|
previewFileName.textContent = filename;
|
||||||
|
|
||||||
function resizeCanvas() {
|
const modal = new bootstrap.Modal(document.getElementById('signaturePreview'));
|
||||||
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
modal.show();
|
||||||
var additionalFactor = 10;
|
|
||||||
|
|
||||||
signaturePadCanvas.width = signaturePadCanvas.offsetWidth * ratio * additionalFactor;
|
|
||||||
signaturePadCanvas.height = signaturePadCanvas.offsetHeight * ratio * additionalFactor;
|
|
||||||
signaturePadCanvas.getContext("2d").scale(ratio * additionalFactor, ratio * additionalFactor);
|
|
||||||
|
|
||||||
signaturePad.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
new IntersectionObserver((entries, observer) => {
|
|
||||||
if (entries.some(entry => entry.intersectionRatio > 0)) {
|
|
||||||
resizeCanvas();
|
|
||||||
}
|
}
|
||||||
}).observe(signaturePadCanvas);
|
|
||||||
|
|
||||||
new ResizeObserver(resizeCanvas).observe(signaturePadCanvas);
|
function addSignatureFromPreview() {
|
||||||
</script>
|
if (currentPreviewSrc) {
|
||||||
<script>
|
DraggableUtils.createDraggableCanvasFromUrl(currentPreviewSrc);
|
||||||
function addDraggableFromText() {
|
bootstrap.Modal.getInstance(document.getElementById('signaturePreview')).hide();
|
||||||
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');
|
|
||||||
ctx.font = `${fontSize}px ${font}`;
|
|
||||||
const textWidth = ctx.measureText(sigText).width;
|
|
||||||
const textHeight = fontSize;
|
|
||||||
|
|
||||||
let paragraphs = sigText.split(/\r?\n/);
|
let originalFileName = '';
|
||||||
|
document.querySelector('input[name=pdf-upload]').addEventListener('change', async (event) => {
|
||||||
|
const file = event.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
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);
|
||||||
|
|
||||||
canvas.width = textWidth;
|
document.querySelectorAll(".show-on-file-selected").forEach(el => {
|
||||||
canvas.height = paragraphs.length * textHeight * 1.35; // for tails
|
el.style.cssText = '';
|
||||||
ctx.font = `${fontSize}px ${font}`;
|
});
|
||||||
|
}
|
||||||
ctx.textBaseline = 'top';
|
|
||||||
|
|
||||||
let y = 0;
|
|
||||||
|
|
||||||
paragraphs.forEach(paragraph => {
|
|
||||||
ctx.fillText(paragraph, 0, y);
|
|
||||||
y += fontSize;
|
|
||||||
});
|
});
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
document.querySelectorAll(".show-on-file-selected").forEach(el => {
|
||||||
|
el.style.cssText = "display:none !important";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
const dataURL = canvas.toDataURL();
|
<div class="tab-group show-on-file-selected">
|
||||||
DraggableUtils.createDraggableCanvasFromUrl(dataURL);
|
<div class="tab-container" th:title="#{sign.upload}">
|
||||||
}
|
<div th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=true, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}"></div>
|
||||||
</script>
|
<script>
|
||||||
|
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();
|
||||||
|
reader.readAsDataURL(imageFile);
|
||||||
|
reader.onloadend = function (e) {
|
||||||
|
DraggableUtils.createDraggableCanvasFromUrl(e.target.result);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- draggables box -->
|
<div class="tab-container drawing-pad-container" th:title="#{sign.draw}">
|
||||||
<div id="box-drag-container" class="show-on-file-selected">
|
<canvas id="drawing-pad-canvas"></canvas>
|
||||||
<canvas id="pdf-canvas"></canvas>
|
<br>
|
||||||
<script th:src="@{'/js/thirdParty/pdf-lib.min.js'}"></script>
|
<button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()" th:text="#{sign.clear}"></button>
|
||||||
<script th:src="@{'/js/draggable-utils.js'}"></script>
|
<button id="save-signature" class="btn btn-outline-success mt-2" onclick="addDraggableFromPad()" th:text="#{sign.add}"></button>
|
||||||
<div class="draggable-buttons-box ignore-rtl">
|
<script>
|
||||||
<button class="btn btn-outline-secondary"
|
const signaturePadCanvas = document.getElementById('drawing-pad-canvas');
|
||||||
onclick="DraggableUtils.deleteDraggableCanvas(DraggableUtils.getLastInteracted())">
|
const signaturePad = new SignaturePad(signaturePadCanvas, {
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash"
|
minWidth: 1,
|
||||||
viewBox="0 0 16 16">
|
maxWidth: 2,
|
||||||
<path
|
penColor: 'black',
|
||||||
d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z" />
|
});
|
||||||
<path
|
|
||||||
d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z" />
|
function addDraggableFromPad() {
|
||||||
</svg>
|
if (signaturePad.isEmpty()) return;
|
||||||
<span class="btn-tooltip" th:text="#{sign.delete}"></span>
|
const startTime = Date.now();
|
||||||
</button>
|
const croppedDataUrl = getCroppedCanvasDataUrl(signaturePadCanvas);
|
||||||
<button class="btn btn-outline-secondary"
|
console.log(Date.now() - startTime);
|
||||||
onclick="DraggableUtils.addAllPagesDraggableCanvas(DraggableUtils.getLastInteracted())">
|
DraggableUtils.createDraggableCanvasFromUrl(croppedDataUrl);
|
||||||
<span class="material-symbols-rounded">
|
}
|
||||||
content_copy
|
|
||||||
</span>
|
function getCroppedCanvasDataUrl(canvas) {
|
||||||
<span class="btn-tooltip" th:text="#{sign.addToAll}"></span>
|
let originalCtx = canvas.getContext('2d');
|
||||||
</button>
|
let originalWidth = canvas.width;
|
||||||
<button class="btn btn-outline-secondary" onclick="goToFirstOrLastPage(false)" style="margin-left:auto">
|
let originalHeight = canvas.height;
|
||||||
<span class="material-symbols-rounded">
|
let imageData = originalCtx.getImageData(0, 0, originalWidth, originalHeight);
|
||||||
keyboard_double_arrow_left
|
|
||||||
</span>
|
let minX = originalWidth + 1, maxX = -1, minY = originalHeight + 1, maxY = -1, x = 0, y = 0, currentPixelColorValueIndex;
|
||||||
<span class="btn-tooltip" th:text="#{sign.first}"></span>
|
|
||||||
</button>
|
for (y = 0; y < originalHeight; y++) {
|
||||||
<button class="btn btn-outline-secondary" id="incrementPage"
|
for (x = 0; x < originalWidth; x++) {
|
||||||
onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.incrementPage() : DraggableUtils.decrementPage()">
|
currentPixelColorValueIndex = (y * originalWidth + x) * 4;
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
|
let currentPixelAlphaValue = imageData.data[currentPixelColorValueIndex + 3];
|
||||||
class="bi bi-chevron-left" viewBox="0 0 16 16">
|
if (currentPixelAlphaValue > 0) {
|
||||||
<path fill-rule="evenodd"
|
if (minX > x) minX = x;
|
||||||
d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z" />
|
if (maxX < x) maxX = x;
|
||||||
</svg>
|
if (minY > y) minY = y;
|
||||||
<span class="btn-tooltip" th:text="#{sign.previous}"></span>
|
if (maxY < y) maxY = y;
|
||||||
</button>
|
}
|
||||||
<button class="btn btn-outline-secondary" id="decrementPage"
|
}
|
||||||
onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.decrementPage() : DraggableUtils.incrementPage()">
|
}
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
|
|
||||||
class="bi bi-chevron-right" viewBox="0 0 16 16">
|
let croppedWidth = maxX - minX;
|
||||||
<path fill-rule="evenodd"
|
let croppedHeight = maxY - minY;
|
||||||
d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z" />
|
if (croppedWidth < 0 || croppedHeight < 0) return null;
|
||||||
</svg>
|
let cuttedImageData = originalCtx.getImageData(minX, minY, croppedWidth, croppedHeight);
|
||||||
<span class="btn-tooltip" th:text="#{sign.next}"></span>
|
|
||||||
</button>
|
let croppedCanvas = document.createElement('canvas'),
|
||||||
<button class="btn btn-outline-secondary" onclick="goToFirstOrLastPage(true)">
|
croppedCtx = croppedCanvas.getContext('2d');
|
||||||
<span class="material-symbols-rounded">
|
|
||||||
keyboard_double_arrow_right
|
croppedCanvas.width = croppedWidth;
|
||||||
</span>
|
croppedCanvas.height = croppedHeight;
|
||||||
<span class="btn-tooltip" th:text="#{sign.last}"></span>
|
croppedCtx.putImageData(cuttedImageData, 0, 0);
|
||||||
</button>
|
|
||||||
|
return croppedCanvas.toDataURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
signaturePad.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
new IntersectionObserver((entries, observer) => {
|
||||||
|
if (entries.some(entry => entry.intersectionRatio > 0)) {
|
||||||
|
resizeCanvas();
|
||||||
|
}
|
||||||
|
}).observe(signaturePadCanvas);
|
||||||
|
|
||||||
|
new ResizeObserver(resizeCanvas).observe(signaturePadCanvas);
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-container" th:title="#{sign.saved}">
|
||||||
|
<div class="saved-signatures-section" th:if="${not #lists.isEmpty(signatures)}">
|
||||||
|
<!-- View Toggle Button -->
|
||||||
|
<div class="view-toggle mb-3">
|
||||||
|
<button class="btn btn-outline-secondary btn-sm" onclick="toggleSignatureView()">
|
||||||
|
<span class="material-symbols-rounded grid-view-text">view_list</span>
|
||||||
|
<span class="material-symbols-rounded list-view-text" style="display: none;">grid_view</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Preview Modal -->
|
||||||
|
<div class="modal fade" id="signaturePreview" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title"><span id="previewFileName"></span></h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body text-center">
|
||||||
|
<img id="previewImage" src="" alt="Signature Preview" style="max-width: 100%;">
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" th:text="#{close}"></button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="addSignatureFromPreview()" th:text="#{addToDoc}">Add to Document</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Grid View -->
|
||||||
|
<div id="gridView">
|
||||||
|
<!-- Personal Signatures -->
|
||||||
|
<div class="signature-category" th:if="${not #lists.isEmpty(signatures.?[category == 'Personal'])}">
|
||||||
|
<h5 th:text="#{sign.personalSigs}"></h5>
|
||||||
|
<div class="signature-grid">
|
||||||
|
<div th:each="sig : ${signatures}" th:if="${sig.category == 'Personal'}" class="signature-item">
|
||||||
|
<img th:src="@{'/api/v1/general/sign/' + ${sig.fileName}}" th:alt="${sig.fileName}" th:data-filename="${sig.fileName}" style="max-width: 200px; cursor: pointer;" onclick="DraggableUtils.createDraggableCanvasFromUrl(this.src)"/>
|
||||||
|
<div class="signature-name" th:text="${sig.fileName}"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Shared Signatures -->
|
||||||
|
<div class="signature-category" th:if="${not #lists.isEmpty(signatures.?[category == 'Shared'])}">
|
||||||
|
<h5 th:text="#{sign.sharedSigs}"></h5>
|
||||||
|
<div class="signature-grid">
|
||||||
|
<div th:each="sig : ${signatures}" th:if="${sig.category == 'Shared'}" class="signature-item">
|
||||||
|
<img th:src="@{'/api/v1/general/sign/' + ${sig.fileName}}" th:alt="${sig.fileName}" th:data-filename="${sig.fileName}" style="max-width: 200px; cursor: pointer;" onclick="DraggableUtils.createDraggableCanvasFromUrl(this.src)"/>
|
||||||
|
<div class="signature-name" th:text="${sig.fileName}"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- List View (Initially Hidden) -->
|
||||||
|
<div id="listView" style="display: none;">
|
||||||
|
<!-- Personal Signatures -->
|
||||||
|
<div class="signature-category" th:if="${not #lists.isEmpty(signatures.?[category == 'Personal'])}">
|
||||||
|
<h5 th:text="#{sign.personalSigs}"></h5>
|
||||||
|
<div class="signature-list">
|
||||||
|
<div th:each="sig : ${signatures}" th:if="${sig.category == 'Personal'}" class="signature-list-item" th:data-src="@{'/api/v1/general/sign/' + ${sig.fileName}}" onclick="previewSignature(this)">
|
||||||
|
<div class="signature-list-info">
|
||||||
|
<span th:text="${sig.fileName}" class="signature-list-name"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Shared Signatures -->
|
||||||
|
<div class="signature-category" th:if="${not #lists.isEmpty(signatures.?[category == 'Shared'])}">
|
||||||
|
<h5 th:text="#{sign.sharedSigs}"></h5>
|
||||||
|
<div class="signature-list">
|
||||||
|
<div th:each="sig : ${signatures}" th:if="${sig.category == 'Shared'}" class="signature-list-item" th:data-src="@{'/api/v1/general/sign/' + ${sig.fileName}}" onclick="previewSignature(this)">
|
||||||
|
<div class="signature-list-info">
|
||||||
|
<span th:text="${sig.fileName}" class="signature-list-name"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:if="${#lists.isEmpty(signatures)}" class="text-center p-3">
|
||||||
|
<p th:text="#{sign.noSavedSigs}">No saved signatures found</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-container" th:title="#{sign.text}">
|
||||||
|
<label class="form-check-label" for="sigText" th:text="#{text}"></label>
|
||||||
|
<textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
|
||||||
|
<label th:text="#{font}"></label>
|
||||||
|
<select class="form-control" name="font" id="font-select">
|
||||||
|
<option th:each="font : ${fonts}" th:value="${font.name}" th:text="${font.name}" th:class="${font.name.toLowerCase()+'-font'}"></option>
|
||||||
|
</select>
|
||||||
|
<div class="margin-auto-parent">
|
||||||
|
<button id="save-text-signature" class="btn btn-outline-success mt-2 margin-center" onclick="addDraggableFromText()" th:text="#{sign.add}"></button>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function addDraggableFromText() {
|
||||||
|
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');
|
||||||
|
ctx.font = `${fontSize}px ${font}`;
|
||||||
|
const textWidth = ctx.measureText(sigText).width;
|
||||||
|
const textHeight = fontSize;
|
||||||
|
|
||||||
|
let paragraphs = sigText.split(/\r?\n/);
|
||||||
|
|
||||||
|
canvas.width = textWidth;
|
||||||
|
canvas.height = paragraphs.length * textHeight * 1.35; // for tails
|
||||||
|
ctx.font = `${fontSize}px ${font}`;
|
||||||
|
|
||||||
|
ctx.textBaseline = 'top';
|
||||||
|
|
||||||
|
let y = 0;
|
||||||
|
|
||||||
|
paragraphs.forEach(paragraph => {
|
||||||
|
ctx.fillText(paragraph, 0, y);
|
||||||
|
y += fontSize;
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataURL = canvas.toDataURL();
|
||||||
|
DraggableUtils.createDraggableCanvasFromUrl(dataURL);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- draggables box -->
|
||||||
|
<div id="box-drag-container" class="show-on-file-selected">
|
||||||
|
<canvas id="pdf-canvas"></canvas>
|
||||||
|
<script th:src="@{'/js/thirdParty/pdf-lib.min.js'}"></script>
|
||||||
|
<script th:src="@{'/js/draggable-utils.js'}"></script>
|
||||||
|
<div class="draggable-buttons-box ignore-rtl">
|
||||||
|
<button class="btn btn-outline-secondary" onclick="DraggableUtils.deleteDraggableCanvas(DraggableUtils.getLastInteracted())">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
|
||||||
|
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z" />
|
||||||
|
<path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.incrementPage() : DraggableUtils.decrementPage()" style="margin-left:auto">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-left" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.decrementPage() : DraggableUtils.incrementPage()">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-right" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- download button -->
|
||||||
|
<div class="margin-auto-parent">
|
||||||
|
<button id="download-pdf" class="btn btn-primary mb-2 show-on-file-selected margin-center" th:text="#{downloadPdf}"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById("download-pdf").addEventListener('click', async () => {
|
||||||
|
const modifiedPdf = await DraggableUtils.getOverlayedPdfDocument();
|
||||||
|
const modifiedPdfBytes = await modifiedPdf.save();
|
||||||
|
const blob = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = URL.createObjectURL(blob);
|
||||||
|
link.download = originalFileName + '_signed.pdf';
|
||||||
|
link.click();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- download button -->
|
|
||||||
<div class="margin-auto-parent">
|
|
||||||
<button id="download-pdf" class="btn btn-primary mb-2 show-on-file-selected margin-center"
|
|
||||||
th:text="#{downloadPdf}"></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
async function goToFirstOrLastPage(page) {
|
|
||||||
if (page) {
|
|
||||||
const lastPage = DraggableUtils.pdfDoc.numPages
|
|
||||||
await DraggableUtils.goToPage(lastPage - 1)
|
|
||||||
} else {
|
|
||||||
await DraggableUtils.goToPage(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
document.getElementById("download-pdf").addEventListener('click', async () => {
|
|
||||||
const modifiedPdf = await DraggableUtils.getOverlayedPdfDocument();
|
|
||||||
const modifiedPdfBytes = await modifiedPdf.save();
|
|
||||||
const blob = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = URL.createObjectURL(blob);
|
|
||||||
link.download = originalFileName + '_signed.pdf';
|
|
||||||
link.click();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
||||||
</div>
|
</div>
|
||||||
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
|
<!-- Link the draggable.js file -->
|
||||||
</div>
|
<script th:src="@{'/js/draggable.js'}"></script>
|
||||||
<!-- Link the draggable.js file -->
|
</body>
|
||||||
<script th:src="@{'/js/draggable.js'}"></script>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user