Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca8295b02e | ||
|
|
b37457b41d | ||
|
|
46c53a9c88 | ||
|
|
5f610da671 | ||
|
|
bacc502f07 | ||
|
|
883281e4df | ||
|
|
9e8c16f313 | ||
|
|
4a7df3fd3f | ||
|
|
f725f92e1a | ||
|
|
9d2c23f612 | ||
|
|
637446fab8 | ||
|
|
196c0f4a39 | ||
|
|
f9b92eec71 | ||
|
|
3be6b0659e | ||
|
|
00e1f74f48 | ||
|
|
6ae2fddd48 | ||
|
|
c5cffdcacb | ||
|
|
d9eda14521 | ||
|
|
b865f4379f | ||
|
|
4294dc54b1 |
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1,2 +1,2 @@
|
|||||||
# All PRs to V1 must be approved by Frooodle
|
# All PRs to V1 must be approved by Frooodle
|
||||||
* @Frooodle @reecebrowne @Ludy87 @DarioGii
|
* @Frooodle @reecebrowne @Ludy87 @DarioGii @ConnorYoh
|
||||||
|
|||||||
5
.github/workflows/PR-Demo-Comment.yml
vendored
5
.github/workflows/PR-Demo-Comment.yml
vendored
@@ -27,7 +27,8 @@ jobs:
|
|||||||
github.event.comment.user.login == 'LaserKaspar' ||
|
github.event.comment.user.login == 'LaserKaspar' ||
|
||||||
github.event.comment.user.login == 'sbplat' ||
|
github.event.comment.user.login == 'sbplat' ||
|
||||||
github.event.comment.user.login == 'reecebrowne' ||
|
github.event.comment.user.login == 'reecebrowne' ||
|
||||||
github.event.comment.user.login == 'DarioGii'
|
github.event.comment.user.login == 'DarioGii' ||
|
||||||
|
github.event.comment.user.login == 'ConnorYoh'
|
||||||
)
|
)
|
||||||
outputs:
|
outputs:
|
||||||
pr_number: ${{ steps.get-pr.outputs.pr_number }}
|
pr_number: ${{ steps.get-pr.outputs.pr_number }}
|
||||||
@@ -93,7 +94,7 @@ jobs:
|
|||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Set up JDK
|
- name: Set up JDK
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|||||||
35
.github/workflows/build.yml
vendored
35
.github/workflows/build.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK ${{ matrix.jdk-version }}
|
- name: Set up JDK ${{ matrix.jdk-version }}
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: ${{ matrix.jdk-version }}
|
java-version: ${{ matrix.jdk-version }}
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
@@ -64,6 +64,35 @@ jobs:
|
|||||||
build/reports/problems/
|
build/reports/problems/
|
||||||
retention-days: 3
|
retention-days: 3
|
||||||
|
|
||||||
|
check-licence:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Harden Runner
|
||||||
|
uses: step-security/harden-runner@cb605e52c26070c328afc4562f0b4ada7618a84e # v2.10.4
|
||||||
|
with:
|
||||||
|
egress-policy: audit
|
||||||
|
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
|
with:
|
||||||
|
java-version: "17"
|
||||||
|
distribution: "adopt"
|
||||||
|
|
||||||
|
- name: check the licenses for compatibility
|
||||||
|
run: ./gradlew clean checkLicense
|
||||||
|
|
||||||
|
- name: FAILED - check the licenses for compatibility
|
||||||
|
if: failure()
|
||||||
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: dependencies-without-allowed-license.json
|
||||||
|
path: |
|
||||||
|
build/reports/dependency-license/dependencies-without-allowed-license.json
|
||||||
|
retention-days: 3
|
||||||
|
|
||||||
docker-compose-tests:
|
docker-compose-tests:
|
||||||
# if: github.event_name == 'push' && github.ref == 'refs/heads/main' ||
|
# if: github.event_name == 'push' && github.ref == 'refs/heads/main' ||
|
||||||
# (github.event_name == 'pull_request' &&
|
# (github.event_name == 'pull_request' &&
|
||||||
@@ -91,7 +120,7 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up Java 17
|
- name: Set up Java 17
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "adopt"
|
distribution: "adopt"
|
||||||
@@ -105,7 +134,7 @@ jobs:
|
|||||||
sudo chmod +x /usr/local/bin/docker-compose
|
sudo chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
cache: 'pip' # caching pip dependencies
|
cache: 'pip' # caching pip dependencies
|
||||||
|
|||||||
2
.github/workflows/check_properties.yml
vendored
2
.github/workflows/check_properties.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
|
|
||||||
|
|||||||
19
.github/workflows/licenses-update.yml
vendored
19
.github/workflows/licenses-update.yml
vendored
@@ -24,24 +24,33 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.GH_APP_ID }}
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "adopt"
|
distribution: "adopt"
|
||||||
|
|
||||||
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
- uses: gradle/actions/setup-gradle@0bdd871935719febd78681f197cd39af5b6e16a6 # v4.2.2
|
||||||
|
|
||||||
- name: Run Gradle Command
|
- name: check the licenses for compatibility
|
||||||
run: ./gradlew clean generateLicenseReport
|
run: ./gradlew clean checkLicense
|
||||||
|
|
||||||
|
- name: FAILED - check the licenses for compatibility
|
||||||
|
if: failure()
|
||||||
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: dependencies-without-allowed-license.json
|
||||||
|
path: |
|
||||||
|
build/reports/dependency-license/dependencies-without-allowed-license.json
|
||||||
|
retention-days: 3
|
||||||
|
|
||||||
- name: Move and Rename License File
|
- name: Move and Rename License File
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
2
.github/workflows/manage-label.yml
vendored
2
.github/workflows/manage-label.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Run Labeler
|
- name: Run Labeler
|
||||||
uses: crazy-max/ghaction-github-labeler@b54af0c25861143e7c8813d7cbbf46d2c341680c # v5.1.0
|
uses: crazy-max/ghaction-github-labeler@31674a3852a9074f2086abcf1c53839d466a47e7 # v5.2.0
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
yaml-file: .github/labels.yml
|
yaml-file: .github/labels.yml
|
||||||
|
|||||||
4
.github/workflows/multiOSReleases.yml
vendored
4
.github/workflows/multiOSReleases.yml
vendored
@@ -58,7 +58,7 @@ jobs:
|
|||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 21
|
- name: Set up JDK 21
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "21"
|
java-version: "21"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
@@ -146,7 +146,7 @@ jobs:
|
|||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 21
|
- name: Set up JDK 21
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "21"
|
java-version: "21"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|||||||
4
.github/workflows/pre_commit.yml
vendored
4
.github/workflows/pre_commit.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.GH_APP_ID }}
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
@@ -42,7 +42,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||||
with:
|
with:
|
||||||
python-version: 3.12
|
python-version: 3.12
|
||||||
cache: 'pip' # caching pip dependencies
|
cache: 'pip' # caching pip dependencies
|
||||||
|
|||||||
2
.github/workflows/push-docker.yml
vendored
2
.github/workflows/push-docker.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
|||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|||||||
2
.github/workflows/releaseArtifacts.yml
vendored
2
.github/workflows/releaseArtifacts.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
|||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|||||||
2
.github/workflows/scorecards.yml
vendored
2
.github/workflows/scorecards.yml
vendored
@@ -74,6 +74,6 @@ jobs:
|
|||||||
|
|
||||||
# Upload the results to GitHub's code scanning dashboard.
|
# Upload the results to GitHub's code scanning dashboard.
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@17a820bf2e43b47be2c72b39cc905417bc1ab6d0 # v3.28.6
|
uses: github/codeql-action/upload-sarif@dd746615b3b9d728a6a37ca2045b68ca76d4841a # v3.28.8
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|||||||
37
.github/workflows/sonarqube.yml
vendored
Normal file
37
.github/workflows/sonarqube.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
branches: [ "main" ]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
pull-requests: read
|
||||||
|
name: Run Sonarqube
|
||||||
|
jobs:
|
||||||
|
sonarqube:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Analyze with SonarCloud
|
||||||
|
|
||||||
|
# You can pin the exact commit or the version.
|
||||||
|
# uses: SonarSource/sonarcloud-github-action@v2.2.0
|
||||||
|
uses: SonarSource/sonarcloud-github-action@4006f663ecaf1f8093e8e4abb9227f6041f52216 #v2.2.0
|
||||||
|
env:
|
||||||
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # Generate a token on Sonarcloud.io, add it to the secrets of this repo with the name SONAR_TOKEN (Settings > Secrets > Actions > add new repository secret)
|
||||||
|
with:
|
||||||
|
# Additional arguments for the SonarScanner CLI
|
||||||
|
args:
|
||||||
|
# Unique keys of your project and organization. You can find them in SonarCloud > Information (bottom-left menu)
|
||||||
|
# mandatory
|
||||||
|
-Dsonar.projectKey=Stirling-Tools_Stirling-PDF
|
||||||
|
-Dsonar.organization=stirling-tools
|
||||||
|
# Comma-separated paths to directories containing main source files.
|
||||||
|
#-Dsonar.sources= # optional, default is project base directory
|
||||||
|
# Comma-separated paths to directories containing test source files.
|
||||||
|
#-Dsonar.tests= # optional. For more info about Code Coverage, please refer to https://docs.sonarcloud.io/enriching/test-coverage/overview/
|
||||||
|
# Adds more detail to both client and server-side analysis logs, activating DEBUG mode for the scanner, and adding client-side environment variables and system properties to the server-side log of analysis report processing.
|
||||||
|
#-Dsonar.verbose= # optional, default is false
|
||||||
|
# When you need the analysis to take place in a directory other than the one from which it was launched, default is .
|
||||||
|
projectBaseDir: .
|
||||||
2
.github/workflows/swagger.yml
vendored
2
.github/workflows/swagger.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: "17"
|
java-version: "17"
|
||||||
distribution: "temurin"
|
distribution: "temurin"
|
||||||
|
|||||||
6
.github/workflows/sync_files.yml
vendored
6
.github/workflows/sync_files.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.GH_APP_ID }}
|
app-id: ${{ secrets.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
@@ -65,7 +65,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Generate GitHub App Token
|
- name: Generate GitHub App Token
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
|
uses: actions/create-github-app-token@136412a57a7081aa63c935a2cc2918f76c34f514 # v1.11.2
|
||||||
with:
|
with:
|
||||||
app-id: ${{ vars.GH_APP_ID }}
|
app-id: ${{ vars.GH_APP_ID }}
|
||||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||||
@@ -73,7 +73,7 @@ jobs:
|
|||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
cache: 'pip' # caching pip dependencies
|
cache: 'pip' # caching pip dependencies
|
||||||
|
|||||||
2
.github/workflows/testdriver.yml
vendored
2
.github/workflows/testdriver.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
- name: Set up JDK
|
- name: Set up JDK
|
||||||
uses: actions/setup-java@7a6d8a8234af8eb26422e24e3006232cccaa061b # v4.6.0
|
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12 # v4.7.0
|
||||||
with:
|
with:
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -140,6 +140,7 @@ venv.bak/
|
|||||||
# VS Code
|
# VS Code
|
||||||
/.vscode/**/*
|
/.vscode/**/*
|
||||||
!/.vscode/settings.json
|
!/.vscode/settings.json
|
||||||
|
!/.vscode/extensions.json
|
||||||
|
|
||||||
# IntelliJ IDEA
|
# IntelliJ IDEA
|
||||||
.idea/
|
.idea/
|
||||||
|
|||||||
24
.vscode/extensions.json
vendored
Normal file
24
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"elagil.pre-commit-helper", // Support for pre-commit hooks to enforce code quality
|
||||||
|
"josevseb.google-java-format-for-vs-code", // Google Java code formatter to follow the Google Java Style Guide
|
||||||
|
"ms-python.black-formatter", // Python code formatter using Black
|
||||||
|
"ms-python.flake8", // Flake8 linter for Python to enforce code quality
|
||||||
|
"ms-python.python", // Official Microsoft Python extension with IntelliSense, debugging, and Jupyter support
|
||||||
|
// "ms-vscode-remote.remote-containers", // Support for remote development with containers (Docker, Dev Containers)
|
||||||
|
// "ms-vscode-remote.vscode-remote-extensionpack", // Remote Development Pack for SSH, WSL, and Containers
|
||||||
|
"Oracle.oracle-java", // Oracle Java extension with additional features for Java development
|
||||||
|
"redhat.java", // Java support by Red Hat with IntelliSense, debugging, and code navigation
|
||||||
|
"shengchen.vscode-checkstyle", // Checkstyle integration for Java code quality checks
|
||||||
|
"streetsidesoftware.code-spell-checker", // Spell checker for code to avoid typos
|
||||||
|
"vmware.vscode-boot-dev-pack", // Developer tools for Spring Boot by VMware
|
||||||
|
"vmware.vscode-spring-boot", // Spring Boot tools by VMware for enhanced Spring development
|
||||||
|
"vscjava.vscode-gradle", // Gradle extension for build and automation support
|
||||||
|
"vscjava.vscode-java-debug", // Debugging support for Java projects
|
||||||
|
"vscjava.vscode-java-dependency", // Java dependency management within VS Code
|
||||||
|
"vscjava.vscode-java-pack", // Java Extension Pack with essential Java tools for VS Code
|
||||||
|
"vscjava.vscode-java-test", // Java test framework for running and debugging tests in VS Code
|
||||||
|
"vscjava.vscode-spring-boot-dashboard", // Spring Boot dashboard for managing and visualizing Spring Boot applications
|
||||||
|
"vscjava.vscode-spring-initializr" // Support for Spring Initializr to create new Spring projects
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -39,6 +39,16 @@ Stirling-PDF is built using:
|
|||||||
2. Install Docker and JDK17 if not already installed.
|
2. Install Docker and JDK17 if not already installed.
|
||||||
|
|
||||||
3. Install a recommended Java IDE such as Eclipse, IntelliJ, or VSCode
|
3. Install a recommended Java IDE such as Eclipse, IntelliJ, or VSCode
|
||||||
|
1. Only VSCode
|
||||||
|
1. Open VS Code.
|
||||||
|
2. When prompted, install the recommended extensions.
|
||||||
|
3. Alternatively, open the command palette (`Ctrl + Shift + P` or `Cmd + Shift + P` on macOS) and run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
Extensions: Show Recommended Extensions
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Install the required extensions from the list.
|
||||||
|
|
||||||
4. Lombok Setup
|
4. Lombok Setup
|
||||||
Stirling-PDF uses Lombok to reduce boilerplate code. Some IDEs, like Eclipse, don't support Lombok out of the box. To set up Lombok in your development environment:
|
Stirling-PDF uses Lombok to reduce boilerplate code. Some IDEs, like Eclipse, don't support Lombok out of the box. To set up Lombok in your development environment:
|
||||||
@@ -594,7 +604,7 @@ dependencies {
|
|||||||
# Generate verification metadata with signatures and checksums
|
# Generate verification metadata with signatures and checksums
|
||||||
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp
|
./gradlew clean dependencies buildEnvironment spotlessApply --write-verification-metadata sha256,pgp
|
||||||
|
|
||||||
# Export the .keys file
|
# Export the .keys file
|
||||||
./gradlew --export-keys
|
./gradlew --export-keys
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -613,4 +623,3 @@ dependencies {
|
|||||||
- Review the changes in `verification-metadata.xml` to ensure they match your dependency updates
|
- Review the changes in `verification-metadata.xml` to ensure they match your dependency updates
|
||||||
|
|
||||||
This ensures dependencies are properly verified and secure while maintaining transparency in the repository.
|
This ensures dependencies are properly verified and secure while maintaining transparency in the repository.
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,7 @@ Any SVG flags are fine; most of the current ones were sourced from [here](https:
|
|||||||
For example, to add Polish, you would add:
|
For example, to add Polish, you would add:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL">
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'pl_PL')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL"> <img th:src="@{'/images/flags/pl.svg'}" alt="icon" width="20" height="15"> Polski</a>
|
||||||
<img src="images/flags/pl.svg" alt="icon" width="20" height="15"> Polski
|
|
||||||
</a>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The `data-bs-language-code` is the code used to reference the file in the next step.
|
The `data-bs-language-code` is the code used to reference the file in the next step.
|
||||||
|
|||||||
@@ -117,14 +117,14 @@ Stirling-PDF currently supports 39 languages!
|
|||||||
|
|
||||||
| Language | Progress |
|
| Language | Progress |
|
||||||
| -------------------------------------------- | -------------------------------------- |
|
| -------------------------------------------- | -------------------------------------- |
|
||||||
| Arabic (العربية) (ar_AR) |  |
|
| Arabic (العربية) (ar_AR) |  |
|
||||||
| Azerbaijani (Azərbaycan Dili) (az_AZ) |  |
|
| 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) |  |
|
||||||
@@ -133,7 +133,7 @@ Stirling-PDF currently supports 39 languages!
|
|||||||
| 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) |  |
|
||||||
@@ -155,7 +155,7 @@ Stirling-PDF currently supports 39 languages!
|
|||||||
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
| Tibetan (བོད་ཡིག་) (zh_BO) |  |
|
||||||
| 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) |  |
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
164
allowed-licenses.json
Normal file
164
allowed-licenses.json
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
{
|
||||||
|
"allowedLicenses": [
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "BSD License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The BSD License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "BSD-2-Clause"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "BSD 2-Clause License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The 2-Clause BSD License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The BSD 3-Clause License (BSD3)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "BSD-4 License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "MIT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "MIT License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The MIT License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "com.github.jai-imageio:jai-imageio-core",
|
||||||
|
"moduleLicense": "LICENSE.txt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "com.github.jai-imageio:jai-imageio-jpeg2000",
|
||||||
|
"moduleLicense": "LICENSE-JJ2000.txt, LICENSE-Sun.txt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache 2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache-2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache-2.0 License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache License 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache License Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Apache License, Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The Apache License, Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The Apache Software License, Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "com.nimbusds:oauth2-oidc-sdk",
|
||||||
|
"moduleLicense": "\"Apache License, version 2.0\";link=\"https://www.apache.org/licenses/LICENSE-2.0.html\""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "MPL 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "UnboundID SCIM2 SDK Free Use License"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "GPL2 w/ CPE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "GPLv2+CE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "GNU GENERAL PUBLIC LICENSE, Version 2 + Classpath Exception"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "com.martiansoftware:jsap",
|
||||||
|
"moduleLicense": "LGPL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": "org.hibernate.orm:hibernate-core",
|
||||||
|
"moduleLicense": "GNU Library General Public License v2.1 or later"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Eclipse Public License - v 1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Eclipse Public License v. 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Eclipse Public License - v 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Eclipse Public License - Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Eclipse Public License, Version 2.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Ubuntu Font Licence 1.0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Bouncy Castle Licence"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "Public Domain, per Creative Commons CC0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"moduleName": ".*",
|
||||||
|
"moduleLicense": "The W3C License"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@ ext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "stirling.software"
|
group = "stirling.software"
|
||||||
version = "0.40.0"
|
version = "0.40.1"
|
||||||
|
|
||||||
java {
|
java {
|
||||||
// 17 is lowest but we support and recommend 21
|
// 17 is lowest but we support and recommend 21
|
||||||
@@ -41,6 +41,7 @@ repositories {
|
|||||||
|
|
||||||
licenseReport {
|
licenseReport {
|
||||||
renderers = [new JsonReportRenderer()]
|
renderers = [new JsonReportRenderer()]
|
||||||
|
allowedLicensesFile = new File("$projectDir/allowed-licenses.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -366,7 +367,7 @@ dependencies {
|
|||||||
exclude group: "commons-logging", module: "commons-logging"
|
exclude group: "commons-logging", module: "commons-logging"
|
||||||
}
|
}
|
||||||
implementation "org.apache.pdfbox:preflight:$pdfboxVersion"
|
implementation "org.apache.pdfbox:preflight:$pdfboxVersion"
|
||||||
|
|
||||||
|
|
||||||
implementation ("org.apache.pdfbox:xmpbox:$pdfboxVersion") {
|
implementation ("org.apache.pdfbox:xmpbox:$pdfboxVersion") {
|
||||||
exclude group: "commons-logging", module: "commons-logging"
|
exclude group: "commons-logging", module: "commons-logging"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
@@ -74,6 +75,11 @@ public class AppConfig {
|
|||||||
: "null";
|
: "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Bean(name = "languages")
|
||||||
|
public List<String> languages() {
|
||||||
|
return applicationProperties.getUi().getLanguages();
|
||||||
|
}
|
||||||
|
|
||||||
@Bean(name = "navBarText")
|
@Bean(name = "navBarText")
|
||||||
public String navBarText() {
|
public String navBarText() {
|
||||||
String defaultNavBar =
|
String defaultNavBar =
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package stirling.software.SPDF.controller.api;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -26,11 +28,11 @@ public class AdditionalLanguageJsController {
|
|||||||
@Hidden
|
@Hidden
|
||||||
@GetMapping(value = "/additionalLanguageCode.js", produces = "application/javascript")
|
@GetMapping(value = "/additionalLanguageCode.js", produces = "application/javascript")
|
||||||
public void generateAdditionalLanguageJs(HttpServletResponse response) throws IOException {
|
public void generateAdditionalLanguageJs(HttpServletResponse response) throws IOException {
|
||||||
List<String> supportedLanguages = languageService.getSupportedLanguages();
|
Set<String> supportedLanguages = languageService.getSupportedLanguages();
|
||||||
response.setContentType("application/javascript");
|
response.setContentType("application/javascript");
|
||||||
PrintWriter writer = response.getWriter();
|
PrintWriter writer = response.getWriter();
|
||||||
// Erstelle das JavaScript dynamisch
|
// Erstelle das JavaScript dynamisch
|
||||||
writer.println("const supportedLanguages = " + toJsonArray(supportedLanguages) + ";");
|
writer.println("const supportedLanguages = " + toJsonArray(new ArrayList<>(supportedLanguages)) + ";");
|
||||||
// Generiere die `getDetailedLanguageCode`-Funktion
|
// Generiere die `getDetailedLanguageCode`-Funktion
|
||||||
writer.println(
|
writer.println(
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ 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.model.api.converters.HTMLToPdfRequest;
|
import stirling.software.SPDF.model.api.converters.HTMLToPdfRequest;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.FileToPdf;
|
import stirling.software.SPDF.utils.FileToPdf;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
@@ -27,12 +28,16 @@ public class ConvertHtmlToPDF {
|
|||||||
|
|
||||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ConvertHtmlToPDF(
|
public ConvertHtmlToPDF(
|
||||||
CustomPDDocumentFactory pdfDocumentFactory,
|
CustomPDDocumentFactory pdfDocumentFactory,
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
|
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled,
|
||||||
|
ApplicationProperties applicationProperties) {
|
||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
||||||
|
this.applicationProperties = applicationProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/html/pdf")
|
||||||
@@ -54,12 +59,16 @@ public class ConvertHtmlToPDF {
|
|||||||
|| (!originalFilename.endsWith(".html") && !originalFilename.endsWith(".zip"))) {
|
|| (!originalFilename.endsWith(".html") && !originalFilename.endsWith(".zip"))) {
|
||||||
throw new IllegalArgumentException("File must be either .html or .zip format.");
|
throw new IllegalArgumentException("File must be either .html or .zip format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean disableSanitize = Boolean.TRUE.equals(applicationProperties.getSystem().getDisableSanitize());
|
||||||
|
|
||||||
byte[] pdfBytes =
|
byte[] pdfBytes =
|
||||||
FileToPdf.convertHtmlToPdf(
|
FileToPdf.convertHtmlToPdf(
|
||||||
request,
|
request,
|
||||||
fileInput.getBytes(),
|
fileInput.getBytes(),
|
||||||
originalFilename,
|
originalFilename,
|
||||||
bookAndHtmlFormatsInstalled);
|
bookAndHtmlFormatsInstalled,
|
||||||
|
disableSanitize);
|
||||||
|
|
||||||
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ 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.model.api.GeneralFile;
|
import stirling.software.SPDF.model.api.GeneralFile;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
import stirling.software.SPDF.service.CustomPDDocumentFactory;
|
||||||
import stirling.software.SPDF.utils.FileToPdf;
|
import stirling.software.SPDF.utils.FileToPdf;
|
||||||
import stirling.software.SPDF.utils.WebResponseUtils;
|
import stirling.software.SPDF.utils.WebResponseUtils;
|
||||||
@@ -37,12 +38,16 @@ public class ConvertMarkdownToPdf {
|
|||||||
|
|
||||||
private final CustomPDDocumentFactory pdfDocumentFactory;
|
private final CustomPDDocumentFactory pdfDocumentFactory;
|
||||||
|
|
||||||
|
private final ApplicationProperties applicationProperties;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ConvertMarkdownToPdf(
|
public ConvertMarkdownToPdf(
|
||||||
CustomPDDocumentFactory pdfDocumentFactory,
|
CustomPDDocumentFactory pdfDocumentFactory,
|
||||||
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled) {
|
@Qualifier("bookAndHtmlFormatsInstalled") boolean bookAndHtmlFormatsInstalled,
|
||||||
|
ApplicationProperties applicationProperties) {
|
||||||
this.pdfDocumentFactory = pdfDocumentFactory;
|
this.pdfDocumentFactory = pdfDocumentFactory;
|
||||||
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
this.bookAndHtmlFormatsInstalled = bookAndHtmlFormatsInstalled;
|
||||||
|
this.applicationProperties = applicationProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
@PostMapping(consumes = "multipart/form-data", value = "/markdown/pdf")
|
||||||
@@ -76,12 +81,15 @@ public class ConvertMarkdownToPdf {
|
|||||||
|
|
||||||
String htmlContent = renderer.render(document);
|
String htmlContent = renderer.render(document);
|
||||||
|
|
||||||
|
boolean disableSanitize = Boolean.TRUE.equals(applicationProperties.getSystem().getDisableSanitize());
|
||||||
|
|
||||||
byte[] pdfBytes =
|
byte[] pdfBytes =
|
||||||
FileToPdf.convertHtmlToPdf(
|
FileToPdf.convertHtmlToPdf(
|
||||||
null,
|
null,
|
||||||
htmlContent.getBytes(),
|
htmlContent.getBytes(),
|
||||||
"converted.html",
|
"converted.html",
|
||||||
bookAndHtmlFormatsInstalled);
|
bookAndHtmlFormatsInstalled,
|
||||||
|
disableSanitize);
|
||||||
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
pdfBytes = pdfDocumentFactory.createNewBytesBasedOnOldDocument(pdfBytes);
|
||||||
String outputFilename =
|
String outputFilename =
|
||||||
originalFilename.replaceFirst("[.][^.]+$", "")
|
originalFilename.replaceFirst("[.][^.]+$", "")
|
||||||
|
|||||||
@@ -36,8 +36,9 @@ public class DatabaseWebController {
|
|||||||
}
|
}
|
||||||
List<FileInfo> backupList = databaseService.getBackupList();
|
List<FileInfo> backupList = databaseService.getBackupList();
|
||||||
model.addAttribute("backupFiles", backupList);
|
model.addAttribute("backupFiles", backupList);
|
||||||
model.addAttribute("databaseVersion", databaseService.getH2Version());
|
String dbVersion = databaseService.getH2Version();
|
||||||
if ("Unknown".equalsIgnoreCase(databaseService.getH2Version())) {
|
model.addAttribute("databaseVersion", dbVersion);
|
||||||
|
if ("Unknown".equalsIgnoreCase(dbVersion)) {
|
||||||
model.addAttribute("infoMessage", "notSupported");
|
model.addAttribute("infoMessage", "notSupported");
|
||||||
}
|
}
|
||||||
return "database";
|
return "database";
|
||||||
|
|||||||
@@ -265,7 +265,8 @@ public class ApplicationProperties {
|
|||||||
return getKeycloak();
|
return getKeycloak();
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedProviderException(
|
throw new UnsupportedProviderException(
|
||||||
"Logout from the provider is not supported? Report it at https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
"Logout from the provider is not supported? Report it at"
|
||||||
|
+ " https://github.com/Stirling-Tools/Stirling-PDF/issues");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,6 +284,7 @@ public class ApplicationProperties {
|
|||||||
private Boolean enableAlphaFunctionality;
|
private Boolean enableAlphaFunctionality;
|
||||||
private String enableAnalytics;
|
private String enableAnalytics;
|
||||||
private Datasource datasource;
|
private Datasource datasource;
|
||||||
|
private Boolean disableSanitize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@@ -312,10 +314,10 @@ public class ApplicationProperties {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return """
|
return """
|
||||||
Driver {
|
Driver {
|
||||||
driverName='%s'
|
driverName='%s'
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
.formatted(driverName);
|
.formatted(driverName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -325,6 +327,7 @@ public class ApplicationProperties {
|
|||||||
private String appName;
|
private String appName;
|
||||||
private String homeDescription;
|
private String homeDescription;
|
||||||
private String appNameNavbar;
|
private String appNameNavbar;
|
||||||
|
private List<String> languages;
|
||||||
|
|
||||||
public String getAppName() {
|
public String getAppName() {
|
||||||
return appName != null && appName.trim().length() > 0 ? appName : null;
|
return appName != null && appName.trim().length() > 0 ? appName : null;
|
||||||
|
|||||||
@@ -1,41 +1,57 @@
|
|||||||
package stirling.software.SPDF.service;
|
package stirling.software.SPDF.service;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import stirling.software.SPDF.model.ApplicationProperties;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@Slf4j
|
||||||
public class LanguageService {
|
public class LanguageService {
|
||||||
|
|
||||||
|
private final ApplicationProperties applicationProperties;
|
||||||
private final PathMatchingResourcePatternResolver resourcePatternResolver =
|
private final PathMatchingResourcePatternResolver resourcePatternResolver =
|
||||||
new PathMatchingResourcePatternResolver();
|
new PathMatchingResourcePatternResolver();
|
||||||
|
|
||||||
public List<String> getSupportedLanguages() {
|
public LanguageService(
|
||||||
List<String> supportedLanguages = new ArrayList<>();
|
ApplicationProperties applicationProperties) {
|
||||||
|
this.applicationProperties = applicationProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getSupportedLanguages() {
|
||||||
try {
|
try {
|
||||||
Resource[] resources =
|
Resource[] resources =
|
||||||
resourcePatternResolver.getResources("classpath*:messages_*.properties");
|
resourcePatternResolver.getResources("classpath*:messages_*.properties");
|
||||||
for (Resource resource : resources) {
|
|
||||||
if (resource.exists() && resource.isReadable()) {
|
|
||||||
String filename = resource.getFilename();
|
|
||||||
if (filename != null
|
|
||||||
&& filename.startsWith("messages_")
|
|
||||||
&& filename.endsWith(".properties")) {
|
|
||||||
String languageCode =
|
|
||||||
filename.replace("messages_", "").replace(".properties", "");
|
|
||||||
supportedLanguages.add(languageCode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return supportedLanguages;
|
return Arrays.stream(resources)
|
||||||
|
.map(Resource::getFilename)
|
||||||
|
.filter(
|
||||||
|
filename ->
|
||||||
|
filename != null
|
||||||
|
&& filename.startsWith("messages_")
|
||||||
|
&& filename.endsWith(".properties"))
|
||||||
|
.map(filename -> filename.replace("messages_", "").replace(".properties", ""))
|
||||||
|
.filter(
|
||||||
|
languageCode -> {
|
||||||
|
Set<String> allowedLanguages =
|
||||||
|
new HashSet<>(applicationProperties.getUi().getLanguages());
|
||||||
|
return allowedLanguages.isEmpty()
|
||||||
|
|| allowedLanguages.contains(languageCode)
|
||||||
|
|| "en_GB".equals(languageCode);
|
||||||
|
})
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error retrieving supported languages", e);
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ public class FileToPdf {
|
|||||||
HTMLToPdfRequest request,
|
HTMLToPdfRequest request,
|
||||||
byte[] fileBytes,
|
byte[] fileBytes,
|
||||||
String fileName,
|
String fileName,
|
||||||
boolean htmlFormatsInstalled)
|
boolean htmlFormatsInstalled,
|
||||||
|
boolean disableSanitize)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
|
|
||||||
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
|
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
|
||||||
@@ -35,13 +36,12 @@ public class FileToPdf {
|
|||||||
try {
|
try {
|
||||||
if (fileName.endsWith(".html")) {
|
if (fileName.endsWith(".html")) {
|
||||||
tempInputFile = Files.createTempFile("input_", ".html");
|
tempInputFile = Files.createTempFile("input_", ".html");
|
||||||
String sanitizedHtml =
|
String sanitizedHtml = sanitizeHtmlContent(new String(fileBytes, StandardCharsets.UTF_8), disableSanitize);
|
||||||
sanitizeHtmlContent(new String(fileBytes, StandardCharsets.UTF_8));
|
|
||||||
Files.write(tempInputFile, sanitizedHtml.getBytes(StandardCharsets.UTF_8));
|
Files.write(tempInputFile, sanitizedHtml.getBytes(StandardCharsets.UTF_8));
|
||||||
} else if (fileName.endsWith(".zip")) {
|
} else if (fileName.endsWith(".zip")) {
|
||||||
tempInputFile = Files.createTempFile("input_", ".zip");
|
tempInputFile = Files.createTempFile("input_", ".zip");
|
||||||
Files.write(tempInputFile, fileBytes);
|
Files.write(tempInputFile, fileBytes);
|
||||||
sanitizeHtmlFilesInZip(tempInputFile);
|
sanitizeHtmlFilesInZip(tempInputFile, disableSanitize);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported file format: " + fileName);
|
throw new IllegalArgumentException("Unsupported file format: " + fileName);
|
||||||
}
|
}
|
||||||
@@ -89,11 +89,11 @@ public class FileToPdf {
|
|||||||
return pdfBytes;
|
return pdfBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String sanitizeHtmlContent(String htmlContent) {
|
private static String sanitizeHtmlContent(String htmlContent, boolean disableSanitize) {
|
||||||
return CustomHtmlSanitizer.sanitize(htmlContent);
|
return (!disableSanitize) ? CustomHtmlSanitizer.sanitize(htmlContent) : htmlContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void sanitizeHtmlFilesInZip(Path zipFilePath) throws IOException {
|
private static void sanitizeHtmlFilesInZip(Path zipFilePath, boolean disableSanitize) throws IOException {
|
||||||
Path tempUnzippedDir = Files.createTempDirectory("unzipped_");
|
Path tempUnzippedDir = Files.createTempDirectory("unzipped_");
|
||||||
try (ZipInputStream zipIn =
|
try (ZipInputStream zipIn =
|
||||||
ZipSecurity.createHardenedInputStream(
|
ZipSecurity.createHardenedInputStream(
|
||||||
@@ -106,7 +106,7 @@ public class FileToPdf {
|
|||||||
if (entry.getName().toLowerCase().endsWith(".html")
|
if (entry.getName().toLowerCase().endsWith(".html")
|
||||||
|| entry.getName().toLowerCase().endsWith(".htm")) {
|
|| entry.getName().toLowerCase().endsWith(".htm")) {
|
||||||
String content = new String(zipIn.readAllBytes(), StandardCharsets.UTF_8);
|
String content = new String(zipIn.readAllBytes(), StandardCharsets.UTF_8);
|
||||||
String sanitizedContent = sanitizeHtmlContent(content);
|
String sanitizedContent = sanitizeHtmlContent(content, disableSanitize);
|
||||||
Files.write(filePath, sanitizedContent.getBytes(StandardCharsets.UTF_8));
|
Files.write(filePath, sanitizedContent.getBytes(StandardCharsets.UTF_8));
|
||||||
} else {
|
} else {
|
||||||
Files.copy(zipIn, filePath);
|
Files.copy(zipIn, filePath);
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=أداة متعددة PDF
|
home.multiTool.title=أداة متعددة PDF
|
||||||
home.multiTool.desc=دمج الصفحات وتدويرها وإعادة ترتيبها وإزالتها
|
home.multiTool.desc=دمج الصفحات وتدويرها وإعادة ترتيبها وإزالتها
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi-alət
|
home.multiTool.title=PDF Multi-alət
|
||||||
home.multiTool.desc=Səhifələri Birləşdir, Çevir, Yenidən Sırala, Böl və Sil
|
home.multiTool.desc=Səhifələri Birləşdir, Çevir, Yenidən Sırala, Böl və Sil
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Мулти инструмент
|
home.multiTool.title=PDF Мулти инструмент
|
||||||
home.multiTool.desc=Обединяване, завъртане, пренареждане и премахване на страници
|
home.multiTool.desc=Обединяване, завъртане, пренареждане и премахване на страници
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Eina Multifunció de PDF
|
home.multiTool.title=Eina Multifunció de PDF
|
||||||
home.multiTool.desc=Fusiona, Rota, Reorganitza i Esborra pàgines
|
home.multiTool.desc=Fusiona, Rota, Reorganitza i Esborra pàgines
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi nástroj
|
home.multiTool.title=PDF Multi nástroj
|
||||||
home.multiTool.desc=Sloučit, otočit, přeuspořádat, rozdělit a odstranit stránky
|
home.multiTool.desc=Sloučit, otočit, přeuspořádat, rozdělit a odstranit stránky
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Værktøj
|
home.multiTool.title=PDF Multi Værktøj
|
||||||
home.multiTool.desc=Flet, Rotér, Omarrangér og Fjern sider
|
home.multiTool.desc=Flet, Rotér, Omarrangér og Fjern sider
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ analytics.settings=Sie können die Einstellungen für die Analytics in der confi
|
|||||||
# NAVBAR #
|
# NAVBAR #
|
||||||
#############
|
#############
|
||||||
navbar.favorite=Favoriten
|
navbar.favorite=Favoriten
|
||||||
navbar.recent=New and recently updated
|
navbar.recent=Neu und kürzlich aktualisiert
|
||||||
navbar.darkmode=Dunkler Modus
|
navbar.darkmode=Dunkler Modus
|
||||||
navbar.language=Sprachen
|
navbar.language=Sprachen
|
||||||
navbar.settings=Einstellungen
|
navbar.settings=Einstellungen
|
||||||
@@ -266,13 +266,14 @@ home.viewPdf.title=PDF anzeigen
|
|||||||
home.viewPdf.desc=Anzeigen, Kommentieren, Text oder Bilder hinzufügen
|
home.viewPdf.desc=Anzeigen, Kommentieren, Text oder Bilder hinzufügen
|
||||||
viewPdf.tags=anzeigen,lesen,kommentieren,text,bild
|
viewPdf.tags=anzeigen,lesen,kommentieren,text,bild
|
||||||
|
|
||||||
home.setFavorites=Set Favourites
|
home.setFavorites=Favoriten festlegen
|
||||||
home.hideFavorites=Hide Favourites
|
home.hideFavorites=Favoriten ausblenden
|
||||||
home.showFavorites=Show Favourites
|
home.showFavorites=Favoriten anzeigen
|
||||||
home.legacyHomepage=Old homepage
|
home.legacyHomepage=Alte Homepage
|
||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Probieren Sie unsere neue Homepage aus!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetisch
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Beliebtheit
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF-Multitool
|
home.multiTool.title=PDF-Multitool
|
||||||
home.multiTool.desc=Seiten zusammenführen, drehen, neu anordnen und entfernen
|
home.multiTool.desc=Seiten zusammenführen, drehen, neu anordnen und entfernen
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Πολυεργαλείο PDF
|
home.multiTool.title=Πολυεργαλείο PDF
|
||||||
home.multiTool.desc=Συγχώνευση, Περιστροφή, Αναδιάταξη, Διαχωρισμός και Αφαίρεση σελίδων
|
home.multiTool.desc=Συγχώνευση, Περιστροφή, Αναδιάταξη, Διαχωρισμός και Αφαίρεση σελίδων
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Tool
|
home.multiTool.title=PDF Multi Tool
|
||||||
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Tool
|
home.multiTool.title=PDF Multi Tool
|
||||||
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
home.multiTool.desc=Merge, Rotate, Rearrange, Split, and Remove pages
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Multi-herramienta PDF
|
home.multiTool.title=Multi-herramienta PDF
|
||||||
home.multiTool.desc=Combinar, rotar, reorganizar y eliminar páginas
|
home.multiTool.desc=Combinar, rotar, reorganizar y eliminar páginas
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Erabilera anitzeko tresna PDF
|
home.multiTool.title=Erabilera anitzeko tresna PDF
|
||||||
home.multiTool.desc=Orriak konbinatu, biratu, berrantolatu eta ezabatu
|
home.multiTool.desc=Orriak konbinatu, biratu, berrantolatu eta ezabatu
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=ابزار چندگانه PDF
|
home.multiTool.title=ابزار چندگانه PDF
|
||||||
home.multiTool.desc=ترکیب، چرخش، بازآرایی، تقسیم و حذف صفحات
|
home.multiTool.desc=ترکیب، چرخش، بازآرایی، تقسیم و حذف صفحات
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Outil multifonction PDF
|
home.multiTool.title=Outil multifonction PDF
|
||||||
home.multiTool.desc=Fusionnez, faites pivoter, réorganisez et supprimez des pages.
|
home.multiTool.desc=Fusionnez, faites pivoter, réorganisez et supprimez des pages.
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Il-uirlis PDF
|
home.multiTool.title=Il-uirlis PDF
|
||||||
home.multiTool.desc=Cumaisc, Rothlaigh, Atheagraigh, agus Bain leathanaigh
|
home.multiTool.desc=Cumaisc, Rothlaigh, Atheagraigh, agus Bain leathanaigh
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF मल्टी टूल
|
home.multiTool.title=PDF मल्टी टूल
|
||||||
home.multiTool.desc=मर्ज करें, घुमाएं, पुनर्व्यवस्थित करें और पृष्ठ हटाएं
|
home.multiTool.desc=मर्ज करें, घुमाएं, पुनर्व्यवस्थित करें और पृष्ठ हटाएं
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Višestruki alat
|
home.multiTool.title=PDF Višestruki alat
|
||||||
home.multiTool.desc=Spajanje, rotiranje, preuređivanje i uklanjanje stranica
|
home.multiTool.desc=Spajanje, rotiranje, preuređivanje i uklanjanje stranica
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF többfunkciós eszköz
|
home.multiTool.title=PDF többfunkciós eszköz
|
||||||
home.multiTool.desc=Egyesítés, forgatás, átrendezés és oldalak eltávolítása
|
home.multiTool.desc=Egyesítés, forgatás, átrendezés és oldalak eltávolítása
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Alat Multi PDF
|
home.multiTool.title=Alat Multi PDF
|
||||||
home.multiTool.desc=Menggabungkan, Memutar, Mengatur Ulang, dan Menghapus halaman
|
home.multiTool.desc=Menggabungkan, Memutar, Mengatur Ulang, dan Menghapus halaman
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Vecchia homepage
|
|||||||
home.newHomePage=Prova la nostra nuova homepage!
|
home.newHomePage=Prova la nostra nuova homepage!
|
||||||
home.alphabetical=Alfabetico
|
home.alphabetical=Alfabetico
|
||||||
home.globalPopularity=Popolarità globale
|
home.globalPopularity=Popolarità globale
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Multifunzione PDF
|
home.multiTool.title=Multifunzione PDF
|
||||||
home.multiTool.desc=Unisci, Ruota, Riordina, e Rimuovi pagine
|
home.multiTool.desc=Unisci, Ruota, Riordina, e Rimuovi pagine
|
||||||
@@ -601,7 +602,7 @@ autoRedact.submitButton=Invia
|
|||||||
redact.title=Redazione manuale
|
redact.title=Redazione manuale
|
||||||
redact.header=Redazione manuale
|
redact.header=Redazione manuale
|
||||||
redact.submit=Redazione
|
redact.submit=Redazione
|
||||||
redact.textBasedRedaction=TRedazione basata sul testo
|
redact.textBasedRedaction=Redazione basata sul testo
|
||||||
redact.pageBasedRedaction=Redazione basata sulla pagina
|
redact.pageBasedRedaction=Redazione basata sulla pagina
|
||||||
redact.convertPDFToImageLabel=Converti PDF in immagine PDF (utilizzato per rimuovere il testo dietro la casella)
|
redact.convertPDFToImageLabel=Converti PDF in immagine PDF (utilizzato per rimuovere il testo dietro la casella)
|
||||||
redact.pageRedactionNumbers.title=Pagine
|
redact.pageRedactionNumbers.title=Pagine
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDFマルチツール
|
home.multiTool.title=PDFマルチツール
|
||||||
home.multiTool.desc=ページの結合、回転、並べ替え、削除します。
|
home.multiTool.desc=ページの結合、回転、並べ替え、削除します。
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF 멀티 도구
|
home.multiTool.title=PDF 멀티 도구
|
||||||
home.multiTool.desc=병합, 회전, 재배치, 분할 및 페이지 제거
|
home.multiTool.desc=병합, 회전, 재배치, 분할 및 페이지 제거
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF multitool
|
home.multiTool.title=PDF multitool
|
||||||
home.multiTool.desc=Pagina's samenvoegen, draaien, herschikken en verwijderen
|
home.multiTool.desc=Pagina's samenvoegen, draaien, herschikken en verwijderen
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Verktøy
|
home.multiTool.title=PDF Multi Verktøy
|
||||||
home.multiTool.desc=Slå sammen, roter, omorganiser og fjern sider
|
home.multiTool.desc=Slå sammen, roter, omorganiser og fjern sider
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Wielofunkcyjne Narzędzie PDF
|
home.multiTool.title=Wielofunkcyjne Narzędzie PDF
|
||||||
home.multiTool.desc=Łącz, dziel, obracaj, zmieniaj kolejność i usuwaj strony
|
home.multiTool.desc=Łącz, dziel, obracaj, zmieniaj kolejność i usuwaj strony
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Multiferramentas de PDF
|
home.multiTool.title=Multiferramentas de PDF
|
||||||
home.multiTool.desc=Mesclar, girar, reorganizar, dividir, inserir e remover páginas.
|
home.multiTool.desc=Mesclar, girar, reorganizar, dividir, inserir e remover páginas.
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Multi Ferramenta PDF
|
home.multiTool.title=Multi Ferramenta PDF
|
||||||
home.multiTool.desc=Juntar, Rodar, Reorganizar, Dividir e Remover páginas
|
home.multiTool.desc=Juntar, Rodar, Reorganizar, Dividir e Remover páginas
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Instrument multiplu PDF
|
home.multiTool.title=Instrument multiplu PDF
|
||||||
home.multiTool.desc=Unifică, rotește, rearanjează și elimină pagini
|
home.multiTool.desc=Unifică, rotește, rearanjează și elimină pagini
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Мультиинструмент PDF
|
home.multiTool.title=Мультиинструмент PDF
|
||||||
home.multiTool.desc=Объединение, поворот, переупорядочивание и удаление страниц
|
home.multiTool.desc=Объединение, поворот, переупорядочивание и удаление страниц
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Tool
|
home.multiTool.title=PDF Multi Tool
|
||||||
home.multiTool.desc=Zlúčiť, otočiť, preusporiadať a odstrániť stránky
|
home.multiTool.desc=Zlúčiť, otočiť, preusporiadať a odstrániť stránky
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Tool
|
home.multiTool.title=PDF Multi Tool
|
||||||
home.multiTool.desc=Spoji, zavrti, prerazporedi, razdeli in odstrani strani
|
home.multiTool.desc=Spoji, zavrti, prerazporedi, razdeli in odstrani strani
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi Alat
|
home.multiTool.title=PDF Multi Alat
|
||||||
home.multiTool.desc=Spajanje, rotacija, premeštanje i uklanjanje stranica
|
home.multiTool.desc=Spajanje, rotacija, premeštanje i uklanjanje stranica
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Multi-verktyg
|
home.multiTool.title=PDF Multi-verktyg
|
||||||
home.multiTool.desc=Sammanfoga, rotera, ordna om och ta bort sidor
|
home.multiTool.desc=Sammanfoga, rotera, ordna om och ta bort sidor
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=เครื่องมือ PDF หลายตัว
|
home.multiTool.title=เครื่องมือ PDF หลายตัว
|
||||||
home.multiTool.desc=รวม หมุน จัดเรียง และลบหน้าต่างๆ
|
home.multiTool.desc=รวม หมุน จัดเรียง และลบหน้าต่างๆ
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF Çoklu Araç
|
home.multiTool.title=PDF Çoklu Araç
|
||||||
home.multiTool.desc=Birleştir, Döndür, Yeniden Düzenle ve Sayfaları Kaldır
|
home.multiTool.desc=Birleştir, Döndür, Yeniden Düzenle ve Sayfaları Kaldır
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Мультіінструмент PDF
|
home.multiTool.title=Мультіінструмент PDF
|
||||||
home.multiTool.desc=Об'єднання, поворот, зміна порядку та видалення сторінок
|
home.multiTool.desc=Об'єднання, поворот, зміна порядку та видалення сторінок
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=Đa công cụ PDF
|
home.multiTool.title=Đa công cụ PDF
|
||||||
home.multiTool.desc=Ghép nối, Xoay, Sắp xếp lại và Xóa trang
|
home.multiTool.desc=Ghép nối, Xoay, Sắp xếp lại và Xóa trang
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF ལག་ཆ་མང་པོ།
|
home.multiTool.title=PDF ལག་ཆ་མང་པོ།
|
||||||
home.multiTool.desc=སྡེབ་སྦྱོར། འཁོར་སྐྱོད། བསྐྱར་སྒྲིག ཁ་གྱེས། དང་ཤོག་ངོས་སུབ་པ།
|
home.multiTool.desc=སྡེབ་སྦྱོར། འཁོར་སྐྱོད། བསྐྱར་སྒྲིག ཁ་གྱེས། དང་ཤོག་ངོས་སུབ་པ།
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF 多功能工具
|
home.multiTool.title=PDF 多功能工具
|
||||||
home.multiTool.desc=合并、旋转、重新排列和删除 PDF 页面
|
home.multiTool.desc=合并、旋转、重新排列和删除 PDF 页面
|
||||||
|
|||||||
@@ -273,6 +273,7 @@ home.legacyHomepage=Old homepage
|
|||||||
home.newHomePage=Try our new homepage!
|
home.newHomePage=Try our new homepage!
|
||||||
home.alphabetical=Alphabetical
|
home.alphabetical=Alphabetical
|
||||||
home.globalPopularity=Global Popularity
|
home.globalPopularity=Global Popularity
|
||||||
|
home.sortBy=Sort by:
|
||||||
|
|
||||||
home.multiTool.title=PDF 複合工具
|
home.multiTool.title=PDF 複合工具
|
||||||
home.multiTool.desc=合併、旋轉、重新排列和移除頁面
|
home.multiTool.desc=合併、旋轉、重新排列和移除頁面
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ security:
|
|||||||
csrfDisabled: false # set to 'true' to disable CSRF protection (not recommended for production)
|
csrfDisabled: false # set to 'true' to disable CSRF protection (not recommended for production)
|
||||||
loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1
|
loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1
|
||||||
loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
|
loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
|
||||||
loginMethod: all # Accepts values like 'all' and 'normal'(only Login with Username/Password), 'oauth2'(only Login with OAuth2) or 'saml2'(only Login with SAML2)
|
loginMethod: all # Accepts values like 'all' and 'normal'(only Login with Username/Password), 'oauth2'(only Login with OAuth2) or 'saml2'(only Login with SAML2)
|
||||||
initialLogin:
|
initialLogin:
|
||||||
username: '' # initial username for the first login
|
username: '' # initial username for the first login
|
||||||
password: '' # initial password for the first login
|
password: '' # initial password for the first login
|
||||||
@@ -86,6 +86,7 @@ system:
|
|||||||
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template HTML files
|
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template HTML files
|
||||||
tessdataDir: /usr/share/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored.
|
tessdataDir: /usr/share/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored.
|
||||||
enableAnalytics: 'true' # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
|
enableAnalytics: 'true' # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
|
||||||
|
disableSanitize: false # set to true to disable Sanitize HTML; (can lead to injections in HTML)
|
||||||
datasource:
|
datasource:
|
||||||
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
|
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
|
||||||
customDatabaseUrl: '' # eg jdbc:postgresql://localhost:5432/postgres, set the url for your own custom database connection. If provided, the type, hostName, port and name are not necessary and will not be used
|
customDatabaseUrl: '' # eg jdbc:postgresql://localhost:5432/postgres, set the url for your own custom database connection. If provided, the type, hostName, port and name are not necessary and will not be used
|
||||||
@@ -100,6 +101,7 @@ ui:
|
|||||||
appName: '' # application's visible name
|
appName: '' # application's visible name
|
||||||
homeDescription: '' # short description or tagline shown on the homepage
|
homeDescription: '' # short description or tagline shown on the homepage
|
||||||
appNameNavbar: '' # name displayed on the navigation bar
|
appNameNavbar: '' # name displayed on the navigation bar
|
||||||
|
languages: [] # If empty, all languages are enabled. To display only German and Polish ["de_DE", "pl_PL"]. British English is always enabled.
|
||||||
|
|
||||||
endpoints:
|
endpoints:
|
||||||
toRemove: [] # list endpoints to disable (e.g. ['img-to-pdf', 'remove-pages'])
|
toRemove: [] # list endpoints to disable (e.g. ['img-to-pdf', 'remove-pages'])
|
||||||
@@ -113,7 +115,7 @@ AutomaticallyGenerated:
|
|||||||
key: example
|
key: example
|
||||||
UUID: example
|
UUID: example
|
||||||
appVersion: 0.35.0
|
appVersion: 0.35.0
|
||||||
|
|
||||||
processExecutor:
|
processExecutor:
|
||||||
sessionLimit: # Process executor instances limits
|
sessionLimit: # Process executor instances limits
|
||||||
libreOfficeSessionLimit: 1
|
libreOfficeSessionLimit: 1
|
||||||
|
|||||||
@@ -95,24 +95,23 @@ function reorderCards(container) {
|
|||||||
|
|
||||||
function initializeCards() {
|
function initializeCards() {
|
||||||
updateFavoritesSection();
|
updateFavoritesSection();
|
||||||
|
updateFavoritesView();
|
||||||
updateFavoritesDropdown();
|
updateFavoritesDropdown();
|
||||||
filterCards();
|
filterCards();
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateFavoritesView() {
|
function updateFavoritesView() {
|
||||||
const isFavoritesView = JSON.parse(localStorage.getItem('favoritesView') || 'false');
|
const isFavoritesView = JSON.parse(localStorage.getItem('favoritesView') || 'false');
|
||||||
const textElement = document.getElementById('toggle-favourites-text');
|
|
||||||
const iconElement = document.getElementById('toggle-favourites-icon');
|
const iconElement = document.getElementById('toggle-favourites-icon');
|
||||||
const favoritesGroup = document.querySelector('#groupFavorites');
|
const favoritesGroup = document.querySelector('#groupFavorites');
|
||||||
const favoritesList = JSON.parse(localStorage.getItem('favoritesList')) || [];
|
const favoritesList = JSON.parse(localStorage.getItem('favoritesList')) || [];
|
||||||
document.getElementById('favouritesVisibility').style.display = 'flex';
|
|
||||||
|
|
||||||
if (isFavoritesView && favoritesList.length > 0) {
|
if (isFavoritesView && favoritesList.length > 0) {
|
||||||
iconElement.textContent = 'visibility_off';
|
document.getElementById('favouritesVisibility').style.display = 'flex';
|
||||||
favoritesGroup.style.display = 'flex';
|
favoritesGroup.style.display = 'flex';
|
||||||
} else {
|
} else {
|
||||||
if (favoritesList.length > 0) {
|
if (favoritesList.length > 0) {
|
||||||
iconElement.textContent = 'visibility';
|
document.getElementById('favouritesVisibility').style.display = 'flex';
|
||||||
favoritesGroup.style.display = 'none';
|
favoritesGroup.style.display = 'none';
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('favouritesVisibility').style.display = 'none';
|
document.getElementById('favouritesVisibility').style.display = 'none';
|
||||||
|
|||||||
@@ -43,37 +43,36 @@ function toolsManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.tooltipSetup = () => {
|
window.tooltipSetup = () => {
|
||||||
const tooltipElements = document.querySelectorAll("[title]");
|
const tooltipElements = document.querySelectorAll('[title]');
|
||||||
|
|
||||||
tooltipElements.forEach((element) => {
|
tooltipElements.forEach((element) => {
|
||||||
const tooltipText = element.getAttribute("title");
|
const tooltipText = element.getAttribute('title');
|
||||||
element.removeAttribute("title");
|
element.removeAttribute('title');
|
||||||
|
element.setAttribute('data-title', 'tooltipText');
|
||||||
const customTooltip = document.createElement("div");
|
const customTooltip = document.createElement('div');
|
||||||
customTooltip.className = "btn-tooltip";
|
customTooltip.className = 'btn-tooltip';
|
||||||
customTooltip.textContent = tooltipText;
|
customTooltip.textContent = tooltipText;
|
||||||
|
|
||||||
document.body.appendChild(customTooltip);
|
document.body.appendChild(customTooltip);
|
||||||
|
|
||||||
element.addEventListener("mouseenter", (event) => {
|
element.addEventListener('mouseenter', (event) => {
|
||||||
customTooltip.style.display = "block";
|
customTooltip.style.display = 'block';
|
||||||
customTooltip.style.left = `${event.pageX + 10}px`; // Position tooltip slightly away from the cursor
|
customTooltip.style.left = `${event.pageX + 10}px`; // Position tooltip slightly away from the cursor
|
||||||
customTooltip.style.top = `${event.pageY + 10}px`;
|
customTooltip.style.top = `${event.pageY + 10}px`;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update the position of the tooltip as the user moves the mouse
|
// Update the position of the tooltip as the user moves the mouse
|
||||||
element.addEventListener("mousemove", (event) => {
|
element.addEventListener('mousemove', (event) => {
|
||||||
customTooltip.style.left = `${event.pageX + 10}px`;
|
customTooltip.style.left = `${event.pageX + 10}px`;
|
||||||
customTooltip.style.top = `${event.pageY + 10}px`;
|
customTooltip.style.top = `${event.pageY + 10}px`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Hide the tooltip when the mouse leaves
|
// Hide the tooltip when the mouse leaves
|
||||||
element.addEventListener("mouseleave", () => {
|
element.addEventListener('mouseleave', () => {
|
||||||
customTooltip.style.display = "none";
|
customTooltip.style.display = 'none';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
tooltipSetup();
|
tooltipSetup();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -127,14 +127,9 @@ function adjustVisibleElements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function adjustContainerAlignment() {
|
function adjustContainerAlignment() {
|
||||||
console.log('Adjusting container alignment');
|
|
||||||
|
|
||||||
document.querySelectorAll('.features-container').forEach((parent) => {
|
document.querySelectorAll('.features-container').forEach((parent) => {
|
||||||
parent.querySelectorAll('.feature-rows').forEach((container) => {
|
parent.querySelectorAll('.feature-rows').forEach((container) => {
|
||||||
const childElements = Array.from(container.children);
|
|
||||||
|
|
||||||
const containerWidth = parent.offsetWidth;
|
const containerWidth = parent.offsetWidth;
|
||||||
console.log(containerWidth < 32 * parseFloat(getComputedStyle(document.documentElement).fontSize));
|
|
||||||
if (containerWidth < 32 * parseFloat(getComputedStyle(document.documentElement).fontSize)) {
|
if (containerWidth < 32 * parseFloat(getComputedStyle(document.documentElement).fontSize)) {
|
||||||
container.classList.add('single-column');
|
container.classList.add('single-column');
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
TabContainer = {
|
TabContainer = {
|
||||||
initTabGroups() {
|
initTabGroups() {
|
||||||
const groups = document.querySelectorAll(".tab-group");
|
const groups = document.querySelectorAll('.tab-group');
|
||||||
const unloadedGroups = [...groups].filter((g) => !g.initialised);
|
const unloadedGroups = [...groups].filter((g) => !g.initialised);
|
||||||
unloadedGroups.forEach((group) => {
|
unloadedGroups.forEach((group) => {
|
||||||
const containers = group.querySelectorAll(".tab-container");
|
const containers = group.querySelectorAll('.tab-container');
|
||||||
const tabTitles = [...containers].map((c) => c.getAttribute("title"));
|
const tabTitles = [...containers].map((c) => c.getAttribute('data-title'));
|
||||||
|
const tabList = document.createElement('div');
|
||||||
const tabList = document.createElement("div");
|
tabList.classList.add('tab-buttons');
|
||||||
tabList.classList.add("tab-buttons");
|
|
||||||
tabTitles.forEach((title) => {
|
tabTitles.forEach((title) => {
|
||||||
const tabButton = document.createElement("button");
|
const tabButton = document.createElement('button');
|
||||||
tabButton.innerHTML = title;
|
tabButton.innerHTML = title;
|
||||||
tabButton.onclick = (e) => {
|
tabButton.onclick = (e) => {
|
||||||
this.setActiveTab(e.target);
|
this.setActiveTab(e.target);
|
||||||
@@ -24,15 +23,15 @@ TabContainer = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
setActiveTab(tabButton) {
|
setActiveTab(tabButton) {
|
||||||
const group = tabButton.closest(".tab-group");
|
const group = tabButton.closest('.tab-group');
|
||||||
|
|
||||||
group.querySelectorAll(".active").forEach((el) => el.classList.remove("active"));
|
group.querySelectorAll('.active').forEach((el) => el.classList.remove('active'));
|
||||||
|
|
||||||
tabButton.classList.add("active");
|
tabButton.classList.add('active');
|
||||||
group.querySelector(`[title="${tabButton.innerHTML}"]`).classList.add("active");
|
group.querySelector(`[data-title="${tabButton.innerHTML}"]`).classList.add('active');
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
TabContainer.initTabGroups();
|
TabContainer.initTabGroups();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
<th:block th:fragment="langs">
|
<th:block th:fragment="langs">
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="bg_BG"> <img th:src="@{'/images/flags/bg.svg'}" alt="icon" width="20" height="15"> Български</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'bg_BG')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="bg_BG"> <img th:src="@{'/images/flags/bg.svg'}" alt="icon" width="20" height="15"> Български</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ar_AR"> <img th:src="@{'/images/flags/sa.svg'}" alt="icon" width="20" height="15"> العربية</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'ar_AR')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ar_AR"> <img th:src="@{'/images/flags/sa.svg'}" alt="icon" width="20" height="15"> العربية</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 th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'ca_CA')}" 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 th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'zh_CN')}" 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 th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'zh_TW')}" 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_BO"> <img th:src="@{'/images/flags/cn.svg'}" alt="icon" width="20" height="15"> བོད་ཡིག</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'zh_BO')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="zh_BO"> <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="az_AZ"> <img th:src="@{'/images/flags/az.svg'}" alt="icon" width="20" height="15"> Azərbaycan Dili</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'az_AZ')}" 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 th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'da_DK')}" 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 th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'de_DE')}" 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>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="en_US"> <img th:src="@{'/images/flags/us.svg'}" alt="icon" width="20" height="15"> English (US)</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'en_US')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="en_US"> <img th:src="@{'/images/flags/us.svg'}" alt="icon" width="20" height="15"> English (US)</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="eu_ES"> <img th:src="@{'/images/flags/eu.svg'}" alt="icon" width="20" height="15"> Euskara</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'eu_ES')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="eu_ES"> <img th:src="@{'/images/flags/eu.svg'}" alt="icon" width="20" height="15"> Euskara</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="es_ES"> <img th:src="@{'/images/flags/es.svg'}" alt="icon" width="20" height="15"> Español</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'es_ES')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="es_ES"> <img th:src="@{'/images/flags/es.svg'}" alt="icon" width="20" height="15"> Español</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="fr_FR"> <img th:src="@{'/images/flags/fr.svg'}" alt="icon" width="20" height="15"> Français</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'fr_FR')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="fr_FR"> <img th:src="@{'/images/flags/fr.svg'}" alt="icon" width="20" height="15"> Français</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="id_ID"> <img th:src="@{'/images/flags/id.svg'}" alt="icon" width="20" height="15"> Indonesia</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'id_ID')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="id_ID"> <img th:src="@{'/images/flags/id.svg'}" alt="icon" width="20" height="15"> Indonesia</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ga_IE"> <img th:src="@{'/images/flags/ie.svg'}" alt="icon" width="20" height="15"> Irish</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'ga_IE')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ga_IE"> <img th:src="@{'/images/flags/ie.svg'}" alt="icon" width="20" height="15"> Irish</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="it_IT"> <img th:src="@{'/images/flags/it.svg'}" alt="icon" width="20" height="15"> Italiano</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'it_IT')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="it_IT"> <img th:src="@{'/images/flags/it.svg'}" alt="icon" width="20" height="15"> Italiano</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="nl_NL"> <img th:src="@{'/images/flags/nl.svg'}" alt="icon" width="20" height="15"> Nederlands</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'nl_NL')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="nl_NL"> <img th:src="@{'/images/flags/nl.svg'}" alt="icon" width="20" height="15"> Nederlands</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="fa_IR"> <img th:src="@{'/images/flags/ir.svg'}" alt="icon" width="20" height="15"> پارسی</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'fa_IR')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="fa_IR"> <img th:src="@{'/images/flags/ir.svg'}" alt="icon" width="20" height="15"> پارسی</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL"> <img th:src="@{'/images/flags/pl.svg'}" alt="icon" width="20" height="15"> Polski</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'pl_PL')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pl_PL"> <img th:src="@{'/images/flags/pl.svg'}" alt="icon" width="20" height="15"> Polski</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pt_BR"> <img th:src="@{'/images/flags/pt_br.svg'}" alt="icon" width="20" height="15"> Português (BR)</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'pt_BR')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pt_BR"> <img th:src="@{'/images/flags/pt_br.svg'}" alt="icon" width="20" height="15"> Português (BR)</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pt_PT"> <img th:src="@{'/images/flags/pt_pt.svg'}" alt="icon" width="20" height="15"> Português (PT)</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'pt_PT')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="pt_PT"> <img th:src="@{'/images/flags/pt_pt.svg'}" alt="icon" width="20" height="15"> Português (PT)</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ro_RO"> <img th:src="@{'/images/flags/ro.svg'}" alt="icon" width="20" height="15"> Romanian</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'ro_RO')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ro_RO"> <img th:src="@{'/images/flags/ro.svg'}" alt="icon" width="20" height="15"> Romanian</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="sk_SK"> <img th:src="@{'/images/flags/sk.svg'}" alt="icon" width="20" height="15"> Slovensky</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'sk_SK')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="sk_SK"> <img th:src="@{'/images/flags/sk.svg'}" alt="icon" width="20" height="15"> Slovensky</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="sl_SI"> <img th:src="@{'/images/flags/si.svg'}" alt="icon" width="20" height="15"> Slovenian</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'sl_SI')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="sl_SI"> <img th:src="@{'/images/flags/si.svg'}" alt="icon" width="20" height="15"> Slovenian</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="sv_SE"> <img th:src="@{'/images/flags/se.svg'}" alt="icon" width="20" height="15"> Svenska</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'sv_SE')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="sv_SE"> <img th:src="@{'/images/flags/se.svg'}" alt="icon" width="20" height="15"> Svenska</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="tr_TR"> <img th:src="@{'/images/flags/tr.svg'}" alt="icon" width="20" height="15"> Türkçe</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'tr_TR')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="tr_TR"> <img th:src="@{'/images/flags/tr.svg'}" alt="icon" width="20" height="15"> Türkçe</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ru_RU"> <img th:src="@{'/images/flags/ru.svg'}" alt="icon" width="20" height="15"> Русский</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'ru_RU')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ru_RU"> <img th:src="@{'/images/flags/ru.svg'}" alt="icon" width="20" height="15"> Русский</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ko_KR"> <img th:src="@{'/images/flags/kr.svg'}" alt="icon" width="20" height="15"> 한국어</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'ko_KR')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ko_KR"> <img th:src="@{'/images/flags/kr.svg'}" alt="icon" width="20" height="15"> 한국어</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ja_JP"> <img th:src="@{'/images/flags/jp.svg'}" alt="icon" width="20" height="15"> 日本語</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'ja_JP')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="ja_JP"> <img th:src="@{'/images/flags/jp.svg'}" alt="icon" width="20" height="15"> 日本語</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="el_GR"> <img th:src="@{'/images/flags/gr.svg'}" alt="icon" width="20" height="15"> Ελληνικά</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'el_GR')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="el_GR"> <img th:src="@{'/images/flags/gr.svg'}" alt="icon" width="20" height="15"> Ελληνικά</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="hu_HU"> <img th:src="@{'/images/flags/hu.svg'}" alt="icon" width="20" height="15"> Hungarian</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'hu_HU')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="hu_HU"> <img th:src="@{'/images/flags/hu.svg'}" alt="icon" width="20" height="15"> Hungarian</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="hi_IN"> <img th:src="@{'/images/flags/in.svg'}" alt="icon" width="20" height="15"> हिन्दी</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'hi_IN')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="hi_IN"> <img th:src="@{'/images/flags/in.svg'}" alt="icon" width="20" height="15"> हिन्दी</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="sr_LATN_RS"> <img th:src="@{'/images/flags/rs.svg'}" alt="icon" width="20" height="15"> Srpski</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'sr_LATN_RS')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="sr_LATN_RS"> <img th:src="@{'/images/flags/rs.svg'}" alt="icon" width="20" height="15"> Srpski</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="uk_UA"> <img th:src="@{'/images/flags/ua.svg'}" alt="icon" width="20" height="15"> Українська</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'uk_UA')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="uk_UA"> <img th:src="@{'/images/flags/ua.svg'}" alt="icon" width="20" height="15"> Українська</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="cs_CZ"> <img th:src="@{'/images/flags/cz.svg'}" alt="icon" width="20" height="15"> Česky</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'cs_CZ')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="cs_CZ"> <img th:src="@{'/images/flags/cz.svg'}" alt="icon" width="20" height="15"> Česky</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="hr_HR"> <img th:src="@{'/images/flags/hr.svg'}" alt="icon" width="20" height="15"> Hrvatski</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'hr_HR')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="hr_HR"> <img th:src="@{'/images/flags/hr.svg'}" alt="icon" width="20" height="15"> Hrvatski</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="no_NB"> <img th:src="@{'/images/flags/no.svg'}" alt="icon" width="20" height="15"> Norsk</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'no_NB')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="no_NB"> <img th:src="@{'/images/flags/no.svg'}" alt="icon" width="20" height="15"> Norsk</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="th_TH"> <img th:src="@{'/images/flags/th.svg'}" alt="icon" width="20" height="15"> ไทย</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'th_TH')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="th_TH"> <img th:src="@{'/images/flags/th.svg'}" alt="icon" width="20" height="15"> ไทย</a>
|
||||||
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="vi_VN"> <img th:src="@{'/images/flags/vn.svg'}" alt="icon" width="20" height="15"> Tiếng Việt</a>
|
<a th:if="${#lists.isEmpty(@languages) or #lists.contains(@languages, 'vi_VN')}" class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="vi_VN"> <img th:src="@{'/images/flags/vn.svg'}" alt="icon" width="20" height="15"> Tiếng Việt</a>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|||||||
@@ -55,10 +55,10 @@
|
|||||||
</span>
|
</span>
|
||||||
<input type="text" id="searchBar" onkeyup="filterCards()" th:placeholder="#{home.searchBar}" autofocus>
|
<input type="text" id="searchBar" onkeyup="filterCards()" th:placeholder="#{home.searchBar}" autofocus>
|
||||||
|
|
||||||
<div style="display: flex;">
|
<div style="display: flex; column-gap: 3rem; flex-wrap: wrap; margin-left:1rem">
|
||||||
<div
|
<div
|
||||||
style="height:2.5rem; display: flex; align-items: center; cursor: pointer; justify-content: center;">
|
style="height:2.5rem; display: flex; align-items: center; cursor: pointer; justify-content: center;">
|
||||||
<label for="sort-options">Sort by:</label>
|
<label for="sort-options" th:text="#{home.sortBy}">Sort by:</label>
|
||||||
<select id="sort-options" style="border:none;">
|
<select id="sort-options" style="border:none;">
|
||||||
<option value="alphabetical" th:text="#{home.alphabetical}"> </option>
|
<option value="alphabetical" th:text="#{home.alphabetical}"> </option>
|
||||||
<!-- <option value="personal">Your most used</option> -->
|
<!-- <option value="personal">Your most used</option> -->
|
||||||
@@ -66,9 +66,8 @@
|
|||||||
<!-- <option value="server">Popularity in organisation</option> -->
|
<!-- <option value="server">Popularity in organisation</option> -->
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div style="display: flex; align-items: center; flex-wrap: wrap; align-content: flex-start; width: fit-content; max-width: 100%; gap:2rem; justify-content: center;">
|
||||||
style="display: flex; margin-left:2rem;align-items: center; flex-wrap: wrap; align-content: flex-start; width: fit-content; max-width: 100%; gap:3rem; justify-content: center;">
|
<div th:title="#{home.setFavorites}" style="display: flex; align-items: center; cursor: pointer;" onclick="toggleFavoritesMode()">
|
||||||
<div th:title="#{home.setFavorites}" style="display: flex; align-items: center; cursor: pointer;" onclick="toggleFavoritesMode()">
|
|
||||||
<span class="material-symbols-rounded toggle-favourites"
|
<span class="material-symbols-rounded toggle-favourites"
|
||||||
style="font-size: 2rem; margin-left: 0.2rem;">
|
style="font-size: 2rem; margin-left: 0.2rem;">
|
||||||
star
|
star
|
||||||
|
|||||||
@@ -43,13 +43,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
|
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
|
||||||
<div class="tab-group show-on-file-selected">
|
<div class="tab-group show-on-file-selected">
|
||||||
<div class="tab-container" th:title="#{sign.upload}">
|
<div class="tab-container" th:title="#{sign.upload}" th:data-title="#{sign.upload}">
|
||||||
<div
|
<div
|
||||||
th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=false, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}">
|
th:replace="~{fragments/common :: fileSelector(name='image-upload', disableMultipleFiles=false, multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-container drawing-pad-container" th:title="#{sign.draw}">
|
<div class="tab-container drawing-pad-container" th:title="#{sign.draw}" th:data-title="#{sign.draw}">
|
||||||
<canvas id="drawing-pad-canvas"></canvas>
|
<canvas id="drawing-pad-canvas"></canvas>
|
||||||
<br>
|
<br>
|
||||||
<button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()"
|
<button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()"
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
th:text="#{sign.add}"></button>
|
th:text="#{sign.add}"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-container" th:title="#{sign.saved}">
|
<div class="tab-container" th:title="#{sign.saved}" th:data-title="#{sign.saved}">
|
||||||
<div class="saved-signatures-section" th:if="${not #lists.isEmpty(signatures)}">
|
<div class="saved-signatures-section" th:if="${not #lists.isEmpty(signatures)}">
|
||||||
|
|
||||||
<!-- Preview Modal -->
|
<!-- Preview Modal -->
|
||||||
@@ -130,7 +130,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-container" th:title="#{sign.text}">
|
<div class="tab-container" th:title="#{sign.text}" th:data-title="#{sign.text}">
|
||||||
<label class="form-check-label" for="sigText" th:text="#{text}"></label>
|
<label class="form-check-label" for="sigText" th:text="#{text}"></label>
|
||||||
<textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
|
<textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
|
||||||
<label th:text="#{font}"></label>
|
<label th:text="#{font}"></label>
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ public class FileToPdfTest {
|
|||||||
byte[] fileBytes = new byte[0]; // Sample file bytes
|
byte[] fileBytes = new byte[0]; // Sample file bytes
|
||||||
String fileName = "test.html"; // Sample file name
|
String fileName = "test.html"; // Sample file name
|
||||||
boolean htmlFormatsInstalled = true; // Sample boolean value
|
boolean htmlFormatsInstalled = true; // Sample boolean value
|
||||||
|
boolean disableSanitize = false; // Sample boolean value
|
||||||
|
|
||||||
// Check if the method throws IOException
|
// Check if the method throws IOException
|
||||||
assertThrows(IOException.class, () -> {
|
assertThrows(IOException.class, () -> {
|
||||||
FileToPdf.convertHtmlToPdf(request, fileBytes, fileName, htmlFormatsInstalled);
|
FileToPdf.convertHtmlToPdf(request, fileBytes, fileName, htmlFormatsInstalled, disableSanitize);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user