Compare commits

...

52 Commits

Author SHA1 Message Date
Anthony Stirling
086daf8351 Merge pull request #1361 from Stirling-Tools/sync_version
💾 Update Version
2024-06-02 10:32:41 +01:00
GitHub Action action@github.com
2741094a8a 💾 Sync Versions
> Made via sync_files.yml
2024-06-02 09:28:30 +00:00
Anthony Stirling
b4dc766f7a Update build.gradle 2024-06-02 10:28:16 +01:00
Anthony Stirling
75e2cfb234 Merge pull request #1359 from albanobattistella/patch-29
Update messages_it_IT.properties
2024-06-01 22:32:34 +01:00
Anthony Stirling
c5f7000e72 Merge pull request #1360 from Ludy87/remove_digi_sign
new workaround for remove digital signature
2024-06-01 22:31:05 +01:00
Ludy87
ca0432e0b4 notification 2024-06-01 21:33:21 +02:00
Ludy87
5799e61385 new workaround for remove digital signature 2024-06-01 21:30:05 +02:00
albanobattistella
f2784c85d6 Update messages_it_IT.properties 2024-06-01 21:07:02 +02:00
Anthony Stirling
01a3fa8cfe Update push-docker.yml 2024-06-01 14:12:57 +01:00
Anthony Stirling
41138cb2be Merge pull request #1356 from Stirling-Tools/fatDockerAutomation
automate fat docker
2024-06-01 14:03:20 +01:00
Anthony Stirling
995de6abc3 automate fat docker 2024-06-01 13:55:28 +01:00
Anthony Stirling
36deb32f07 Merge pull request #1355 from Stirling-Tools/fatDocker
fat docker
2024-06-01 13:06:51 +01:00
Anthony Stirling
6a38c55867 remove headless due to com.sun.imageio.plugins.jpeg.JPEGImageWriter 2024-06-01 12:57:11 +01:00
Anthony Stirling
96e390c98d Merge branch 'main' into fatDocker 2024-06-01 12:41:51 +01:00
Anthony Stirling
52978ec9ad fat docker 2024-06-01 12:38:10 +01:00
Anthony Stirling
fcd4af2d09 Merge pull request #1354 from foivospro/main
Fix Error When Submitting Crop Tool Without Making a Selection
2024-06-01 12:02:18 +01:00
foiv
963c1f4874 fix the crop problem 2024-06-01 13:58:56 +03:00
Anthony Stirling
aa42806a9e Merge pull request #1352 from Ludy87/fix_admin_exe_windows
Fix: Initialization Issue and Enhance Configuration Management for Co…
2024-06-01 09:41:54 +01:00
Ludy87
19c564a6f7 Fix: Initialization Issue and Enhance Configuration Management for ConfigInitializer #1324 2024-05-31 23:51:42 +02:00
Anthony Stirling
6afbd8bd24 Update build.gradle 2024-05-31 21:04:42 +01:00
Anthony Stirling
76bfc09a44 Merge pull request #1344 from andrewdolphin/main
Update view-pdf.html
2024-05-31 20:55:22 +01:00
Anthony Stirling
6df412c576 Merge pull request #1347 from Stirling-Tools/sync_readme
📝 Update README: Translation Progress Table
2024-05-31 20:55:09 +01:00
Anthony Stirling
37bb890cb9 Merge branch 'main' into sync_readme 2024-05-31 20:54:55 +01:00
Anthony Stirling
9bd15d7ef3 Update README.md 2024-05-31 20:53:05 +01:00
Anthony Stirling
b0671943f7 Merge pull request #1345 from onyxfin/main
Croatian language Translation.
2024-05-31 20:50:30 +01:00
GitHub Action action@github.com
7cbad4df4f 📝 Sync README
> Made via sync_files.yml
2024-05-31 19:50:13 +00:00
Anthony Stirling
e27651826e Merge pull request #1346 from Ludy87/remove_cert_sign
add remove digital signature
2024-05-31 20:49:57 +01:00
onyxfin
5b0de9eac1 Update languages.html 2024-05-31 15:45:47 +02:00
onyxfin
b646d8c481 Add files via upload 2024-05-31 15:24:01 +02:00
andrewdolphin
cd2f628168 Update view-pdf.html
Remove bootstrap.css which regresses a previous issue that caused imported images to incorrectly resize.

Reintroduce "Import image" option.
2024-05-31 12:16:57 +01:00
Ludy87
aef0d32b5b add remove digital signature 2024-05-31 11:31:07 +02:00
onyxfin
e761ad8e51 Merge pull request #1 from onyxfin/onyxfin-patch-1
Add files via upload
2024-05-30 22:11:09 +02:00
onyxfin
059296d444 Add files via upload 2024-05-30 22:01:29 +02:00
Anthony Stirling
9c1de1cb10 Merge pull request #1336 from Stirling-Tools/sync_readme
📝 Update README: Translation Progress Table
2024-05-30 20:55:34 +01:00
Anthony Stirling
ebba39ce10 Merge pull request #1334 from Ludy87/fix_docker_sso
add properties Docker
2024-05-30 20:54:28 +01:00
Anthony Stirling
361b4c2db4 Merge pull request #1333 from Ludy87/fix_viewer_pdf
Fix: Can't select the Draw tool in View #1328
2024-05-30 20:54:15 +01:00
Anthony Stirling
d221654121 Merge pull request #1331 from pcanham/hotfix/typo-fix-for-google
fix: type correction around google OAUTH2 provider
2024-05-30 20:54:08 +01:00
GitHub Action action@github.com
7ac41d7863 📝 Sync README
> Made via sync_files.yml
2024-05-30 19:54:03 +00:00
Anthony Stirling
f1476d197f Merge pull request #1326 from NicolasFR/feat/utf8-mdToPdf
feat: Force UTF-8 encoding of input characters
2024-05-30 20:53:58 +01:00
Anthony Stirling
4a53195c25 Merge pull request #1322 from albanobattistella/patch-28
Update messages_it_IT.properties
2024-05-30 20:53:50 +01:00
Anthony Stirling
e2bed6f6af Merge pull request #1321 from nimdassdev/main
Update messages_bg_BG.properties
2024-05-30 20:53:45 +01:00
Anthony Stirling
5d6e23d4b7 Merge pull request #1282 from kkdlau/bugfix/1214-grab-zero-byte-pdf
#1214 Only take pdf that are good for processing
2024-05-30 20:53:21 +01:00
Ludy87
dfb8ba857f add properties Docker 2024-05-30 11:52:13 +02:00
Ludy87
1572404e6f Fix: Can't select the Draw tool in View #1328 2024-05-30 11:42:49 +02:00
Paul Canham
76dc90d587 fi: type correction around google OAUTH2 provider 2024-05-30 09:42:23 +01:00
Anthony Stirling
316b4e42af Update README.md 2024-05-29 23:36:14 +01:00
Nicolas
f61bbd312f feat: Force UTF-8 encoding of input characters 2024-05-29 22:09:09 +02:00
Danny Lau
65b9544942 #1214 Fix unable to create FileMonitor if the root directory does not exist 2024-05-29 23:03:24 +08:00
albanobattistella
7e8b86e6eb Update messages_it_IT.properties 2024-05-29 12:08:25 +02:00
IT Creativity + Art Team
2ab5bc1e18 Update messages_bg_BG.properties
Updated/improved Bulgarian language strings. Thank you.
2024-05-29 09:56:21 +03:00
Danny Lau
17ef2e9b5d Merge branch 'main' into bugfix/1214-grab-zero-byte-pdf 2024-05-25 08:20:57 +08:00
Danny Lau
801dcdb463 #1214 Only take files that are good for processing 2024-05-25 00:22:01 +08:00
60 changed files with 2302 additions and 201 deletions

View File

@@ -110,3 +110,31 @@ jobs:
labels: ${{ steps.meta2.outputs.labels }}
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
platforms: linux/amd64,linux/arm64/v8
- name: Generate tags fat
id: meta3
uses: docker/metadata-action@v5
if: github.ref != 'refs/heads/main'
with:
images: |
${{ secrets.DOCKER_HUB_USERNAME }}/s-pdf
ghcr.io/${{ steps.repoowner.outputs.lowercase }}/s-pdf
tags: |
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-fat,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest-fat,enable=${{ github.ref == 'refs/heads/master' }}
- name: Build and push main Dockerfile fat
uses: docker/build-push-action@v5
if: github.ref != 'refs/heads/main'
with:
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: ${{ steps.meta3.outputs.tags }}
labels: ${{ steps.meta3.outputs.labels }}
build-args: VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
platforms: linux/amd64,linux/arm64/v8

84
Dockerfile-fat Normal file
View File

@@ -0,0 +1,84 @@
# Build the application
FROM gradle:7.6-jdk17 AS build
# Set the working directory
WORKDIR /app
# Copy the entire project to the working directory
COPY . .
# Build the application with DOCKER_ENABLE_SECURITY=false
RUN DOCKER_ENABLE_SECURITY=true \
./gradlew clean build
# Main stage
FROM alpine:3.20.0
# Copy necessary files
COPY scripts /scripts
COPY pipeline /pipeline
COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
COPY --from=build /app/build/libs/*.jar app.jar
ARG VERSION_TAG
# Set Environment Variables
ENV DOCKER_ENABLE_SECURITY=false \
VERSION_TAG=$VERSION_TAG \
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75" \
HOME=/home/stirlingpdfuser \
PUID=1000 \
PGID=1000 \
UMASK=022 \
FAT_DOCKER=true \
INSTALL_BOOK_AND_ADVANCED_HTML_OPS=true
# JDK for app
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
apk upgrade --no-cache -a && \
apk add --no-cache \
ca-certificates \
tzdata \
tini \
bash \
curl \
calibre@testing \
shadow \
su-exec \
openssl \
openssl-dev \
openjdk21-jre \
# Doc conversion
libreoffice \
# pdftohtml
poppler-utils \
# OCR MY PDF (unpaper for descew and other advanced featues)
ocrmypdf \
tesseract-ocr-data-eng \
font-terminus font-dejavu font-noto font-noto-cjk font-awesome font-noto-extra \
# CV
py3-opencv \
# python3/pip
python3 && \
wget https://bootstrap.pypa.io/get-pip.py -qO - | python3 - --break-system-packages --no-cache-dir --upgrade && \
# uno unoconv and HTML
pip install --break-system-packages --no-cache-dir --upgrade unoconv WeasyPrint && \
mv /usr/share/tessdata /usr/share/tessdata-original && \
mkdir -p $HOME /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \
fc-cache -f -v && \
chmod +x /scripts/* && \
chmod +x /scripts/init.sh && \
# User permissions
addgroup -S stirlingpdfgroup && adduser -S stirlingpdfuser -G stirlingpdfgroup && \
chown -R stirlingpdfuser:stirlingpdfgroup $HOME /scripts /usr/share/fonts/opentype/noto /configs /customFiles /pipeline && \
chown stirlingpdfuser:stirlingpdfgroup /app.jar && \
tesseract --list-langs
EXPOSE 8080/tcp
# Set user and run command
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]

View File

@@ -1,46 +1,47 @@
| Operation | PageOps | Convert | Security | Other | CLI | Python | OpenCV | LibreOffice | OCRmyPDF | Java | Javascript |
|---------------------|---------|---------|----------|-------|------|--------|--------|-------------|----------|----------|------------|
| adjust-contrast | ✔️ | | | | | | | | | | ✔️ |
| auto-split-pdf | ✔️ | | | | | | | | | ✔️ | |
| crop | ✔️ | | | | | | | | | ✔️ | |
| extract-page | ✔️ | | | | | | | | | ✔️ | |
| merge-pdfs | ✔️ | | | | | | | | | ✔️ | |
| multi-page-layout | ✔️ | | | | | | | | | ✔️ | |
| pdf-organizer | ✔️ | | | | | | | | | ✔️ | ✔️ |
| pdf-to-single-page | ✔️ | | | | | | | | | ✔️ | |
| remove-pages | ✔️ | | | | | | | | | ✔️ | |
| rotate-pdf | ✔️ | | | | | | | | | ✔️ | |
| scale-pages | ✔️ | | | | | | | | | ✔️ | |
| split-pdfs | ✔️ | | | | | | | | | ✔️ | |
| file-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | |
| img-to-pdf | | ✔️ | | | | | | | | ✔️ | |
| pdf-to-html | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-img | | ✔️ | | | | | | | | ✔️ | |
| pdf-to-pdfa | | ✔️ | | | ✔️ | | | | ✔️ | | |
| pdf-to-markdown | | ✔️ | | | | | | | | ✔️ | |
| pdf-to-presentation | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-text | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-word | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-xml | | ✔️ | | | ✔️ | | | ✔️ | | | |
| xlsx-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | |
| add-password | | | ✔️ | | | | | | | ✔️ | |
| add-watermark | | | ✔️ | | | | | | | ✔️ | |
| cert-sign | | | ✔️ | | | | | | | ✔️ | |
| change-permissions | | | ✔️ | | | | | | | ✔️ | |
| remove-password | | | ✔️ | | | | | | | ✔️ | |
| sanitize-pdf | | | ✔️ | | | | | | | ✔️ | |
| add-image | | | | ✔️ | | | | | | ✔️ | |
| add-page-numbers | | | | ✔️ | | | | | | ✔️ | |
| auto-rename | | | | ✔️ | | | | | | ✔️ | |
| change-metadata | | | | ✔️ | | | | | | ✔️ | |
| compare | | | | ✔️ | | | | | | | ✔️ |
| compress-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |
| extract-image-scans | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | |
| extract-images | | | | ✔️ | | | | | | ✔️ | |
| flatten | | | | ✔️ | | | | | | | ✔️ |
| get-info-on-pdf | | | | ✔️ | | | | | | ✔️ | |
| ocr-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |
| remove-blanks | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | |
| repair | | | | ✔️ | ✔️ | | | ✔️ | | | |
| show-javascript | | | | ✔️ | | | | | | | ✔️ |
| sign | | | | ✔️ | | | | | | | ✔️ |
| Operation | PageOps | Convert | Security | Other | CLI | Python | OpenCV | LibreOffice | OCRmyPDF | Java | Javascript |
| ------------------- | ------- | ------- | -------- | ----- | --- | ------ | ------ | ----------- | -------- | ---- | ---------- |
| adjust-contrast | ✔️ | | | | | | | | | | ✔️ |
| auto-split-pdf | ✔️ | | | | | | | | | ✔️ | |
| crop | ✔️ | | | | | | | | | ✔️ | |
| extract-page | ✔️ | | | | | | | | | ✔️ | |
| merge-pdfs | ✔️ | | | | | | | | | ✔️ | |
| multi-page-layout | ✔️ | | | | | | | | | ✔️ | |
| pdf-organizer | ✔️ | | | | | | | | | ✔️ | ✔️ |
| pdf-to-single-page | ✔️ | | | | | | | | | ✔️ | |
| remove-pages | ✔️ | | | | | | | | | ✔️ | |
| rotate-pdf | ✔️ | | | | | | | | | ✔️ | |
| scale-pages | ✔️ | | | | | | | | | ✔️ | |
| split-pdfs | ✔️ | | | | | | | | | ✔️ | |
| file-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | |
| img-to-pdf | | ✔️ | | | | | | | | ✔️ | |
| pdf-to-html | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-img | | ✔️ | | | | | | | | ✔️ | |
| pdf-to-pdfa | | ✔️ | | | ✔️ | | | | ✔️ | | |
| pdf-to-markdown | | ✔️ | | | | | | | | ✔️ | |
| pdf-to-presentation | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-text | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-word | | ✔️ | | | ✔️ | | | ✔️ | | | |
| pdf-to-xml | | ✔️ | | | ✔️ | | | ✔️ | | | |
| xlsx-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | |
| add-password | | | ✔️ | | | | | | | ✔️ | |
| add-watermark | | | ✔️ | | | | | | | ✔️ | |
| cert-sign | | | ✔️ | | | | | | | ✔️ | |
| remove-cert-sign | | | ✔️ | | | | | | | ✔️ | |
| change-permissions | | | ✔️ | | | | | | | ✔️ | |
| remove-password | | | ✔️ | | | | | | | ✔️ | |
| sanitize-pdf | | | ✔️ | | | | | | | ✔️ | |
| add-image | | | | ✔️ | | | | | | ✔️ | |
| add-page-numbers | | | | ✔️ | | | | | | ✔️ | |
| auto-rename | | | | ✔️ | | | | | | ✔️ | |
| change-metadata | | | | ✔️ | | | | | | ✔️ | |
| compare | | | | ✔️ | | | | | | | ✔️ |
| compress-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |
| extract-image-scans | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | |
| extract-images | | | | ✔️ | | | | | | ✔️ | |
| flatten | | | | ✔️ | | | | | | | ✔️ |
| get-info-on-pdf | | | | ✔️ | | | | | | ✔️ | |
| ocr-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |
| remove-blanks | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | |
| repair | | | | ✔️ | ✔️ | | | ✔️ | | | |
| show-javascript | | | | ✔️ | | | | | | | ✔️ |
| sign | | | | ✔️ | | | | | | | ✔️ |

View File

@@ -165,33 +165,34 @@ Stirling PDF currently supports 28!
| ------------------------------------------- | -------------------------------------- |
| English (English) (en_GB) | ![100%](https://geps.dev/progress/100) |
| English (US) (en_US) | ![100%](https://geps.dev/progress/100) |
| Arabic (العربية) (ar_AR) | ![41%](https://geps.dev/progress/41) |
| German (Deutsch) (de_DE) | ![100%](https://geps.dev/progress/100) |
| Arabic (العربية) (ar_AR) | ![40%](https://geps.dev/progress/40) |
| German (Deutsch) (de_DE) | ![99%](https://geps.dev/progress/99) |
| French (Français) (fr_FR) | ![94%](https://geps.dev/progress/94) |
| Spanish (Español) (es_ES) | ![96%](https://geps.dev/progress/96) |
| Simplified Chinese (简体中文) (zh_CN) | ![96%](https://geps.dev/progress/96) |
| Traditional Chinese (繁體中文) (zh_TW) | ![95%](https://geps.dev/progress/95) |
| Spanish (Español) (es_ES) | ![95%](https://geps.dev/progress/95) |
| Simplified Chinese (简体中文) (zh_CN) | ![95%](https://geps.dev/progress/95) |
| Traditional Chinese (繁體中文) (zh_TW) | ![94%](https://geps.dev/progress/94) |
| Catalan (Català) (ca_CA) | ![49%](https://geps.dev/progress/49) |
| Italian (Italiano) (it_IT) | ![99%](https://geps.dev/progress/99) |
| Swedish (Svenska) (sv_SE) | ![41%](https://geps.dev/progress/41) |
| Italian (Italiano) (it_IT) | ![98%](https://geps.dev/progress/98) |
| Swedish (Svenska) (sv_SE) | ![40%](https://geps.dev/progress/40) |
| Polish (Polski) (pl_PL) | ![43%](https://geps.dev/progress/43) |
| Romanian (Română) (ro_RO) | ![40%](https://geps.dev/progress/40) |
| Korean (한국어) (ko_KR) | ![88%](https://geps.dev/progress/88) |
| Portuguese Brazilian (Português) (pt_BR) | ![62%](https://geps.dev/progress/62) |
| Russian (Русский) (ru_RU) | ![88%](https://geps.dev/progress/88) |
| Basque (Euskara) (eu_ES) | ![64%](https://geps.dev/progress/64) |
| Japanese (日本語) (ja_JP) | ![88%](https://geps.dev/progress/88) |
| Dutch (Nederlands) (nl_NL) | ![86%](https://geps.dev/progress/86) |
| Greek (Ελληνικά) (el_GR) | ![86%](https://geps.dev/progress/86) |
| Korean (한국어) (ko_KR) | ![87%](https://geps.dev/progress/87) |
| Portuguese Brazilian (Português) (pt_BR) | ![61%](https://geps.dev/progress/61) |
| Russian (Русский) (ru_RU) | ![87%](https://geps.dev/progress/87) |
| Basque (Euskara) (eu_ES) | ![63%](https://geps.dev/progress/63) |
| Japanese (日本語) (ja_JP) | ![87%](https://geps.dev/progress/87) |
| Dutch (Nederlands) (nl_NL) | ![85%](https://geps.dev/progress/85) |
| Greek (Ελληνικά) (el_GR) | ![85%](https://geps.dev/progress/85) |
| Turkish (Türkçe) (tr_TR) | ![98%](https://geps.dev/progress/98) |
| Indonesia (Bahasa Indonesia) (id_ID) | ![79%](https://geps.dev/progress/79) |
| Hindi (हिंदी) (hi_IN) | ![80%](https://geps.dev/progress/80) |
| Hungarian (Magyar) (hu_HU) | ![79%](https://geps.dev/progress/79) |
| Bulgarian (Български) (bg_BG) | ![96%](https://geps.dev/progress/96) |
| Hindi (हिंदी) (hi_IN) | ![79%](https://geps.dev/progress/79) |
| Hungarian (Magyar) (hu_HU) | ![78%](https://geps.dev/progress/78) |
| Bulgarian (Български) (bg_BG) | ![98%](https://geps.dev/progress/98) |
| Sebian Latin alphabet (Srpski) (sr_LATN_RS) | ![81%](https://geps.dev/progress/81) |
| Ukrainian (Українська) (uk_UA) | ![87%](https://geps.dev/progress/87) |
| Slovakian (Slovensky) (sk_SK) | ![96%](https://geps.dev/progress/96) |
| Czech (Česky) (cs_CZ) | ![94%](https://geps.dev/progress/94) |
| Croatian (Hrvatski) (hr_HR) | ![94%](https://geps.dev/progress/94) |
## Contributing (creating issues, translations, fixing bugs, etc.)
@@ -213,10 +214,10 @@ For example in the settings.yml you have
```yaml
system:
defaultLocale: 'en-US'
enableLogin: 'true'
```
To have this via an environment variable you would have ``SYSTEM_DEFAULTLOCALE``
To have this via an environment variable you would have ``SYSTEM_ENABLELOGIN``
The Current list of settings is

View File

@@ -1,52 +1,53 @@
| Technology | Ultra-Lite | Full |
|----------------|:----------:|:----:|
| Java | ✔️ | ✔️ |
| JavaScript | ✔️ | ✔️ |
| Libre | | ✔️ |
| Python | | ✔️ |
| OpenCV | | ✔️ |
| OCRmyPDF | | ✔️ |
| Technology | Ultra-Lite | Full |
| ---------- | :--------: | :---: |
| Java | ✔️ | ✔️ |
| JavaScript | ✔️ | ✔️ |
| Libre | | ✔️ |
| Python | | ✔️ |
| OpenCV | | ✔️ |
| OCRmyPDF | | ✔️ |
Operation | Ultra-Lite | Full
-------------------------|------------|-----
add-page-numbers | ✔️ | ✔️
add-password | ✔️ | ✔️
add-image | ✔️ | ✔️
add-watermark | ✔️ | ✔️
adjust-contrast | ✔️ | ✔️
auto-split-pdf | ✔️ | ✔️
auto-redact | ✔️ | ✔️
auto-rename | ✔️ | ✔️
cert-sign | ✔️ | ✔️
crop | ✔️ | ✔️
change-metadata | ✔️ | ✔️
change-permissions | ✔️ | ✔️
compare | ✔️ | ✔️
extract-page | ✔️ | ✔️
extract-images | ✔️ | ✔️
flatten | ✔️ | ✔️
get-info-on-pdf | ✔️ | ✔️
img-to-pdf | ✔️ | ✔️
markdown-to-pdf | ✔️ | ✔️
merge-pdfs | ✔️ | ✔️
multi-page-layout | ✔️ | ✔️
overlay-pdf | ✔️ | ✔️
pdf-organizer | ✔️ | ✔️
pdf-to-csv | ✔️ | ✔️
pdf-to-img | ✔️ | ✔️
pdf-to-single-page | ✔️ | ✔️
remove-pages | ✔️ | ✔️
remove-password | ✔️ | ✔️
rotate-pdf | ✔️ | ✔️
sanitize-pdf | ✔️ | ✔️
scale-pages | ✔️ | ✔️
sign | ✔️ | ✔️
show-javascript | ✔️ | ✔️
split-by-size-or-count | ✔️ | ✔️
split-pdf-by-sections | ✔️ | ✔️
split-pdfs | ✔️ | ✔️
compress-pdf | | ✔️
extract-image-scans | | ✔️
ocr-pdf | | ✔️
pdf-to-pdfa | | ✔️
remove-blanks | | ✔️
| Operation | Ultra-Lite | Full |
| ---------------------- | ---------- | ---- |
| add-page-numbers | ✔️ | ✔️ |
| add-password | ✔️ | ✔️ |
| add-image | ✔️ | ✔️ |
| add-watermark | ✔️ | ✔️ |
| adjust-contrast | ✔️ | ✔️ |
| auto-split-pdf | ✔️ | ✔️ |
| auto-redact | ✔️ | ✔️ |
| auto-rename | ✔️ | ✔️ |
| cert-sign | ✔️ | ✔️ |
| remove-cert-sign | ✔️ | ✔️ |
| crop | ✔️ | ✔️ |
| change-metadata | ✔️ | ✔️ |
| change-permissions | ✔️ | ✔️ |
| compare | ✔️ | ✔️ |
| extract-page | ✔️ | ✔️ |
| extract-images | ✔️ | ✔️ |
| flatten | ✔️ | ✔️ |
| get-info-on-pdf | ✔️ | ✔️ |
| img-to-pdf | ✔️ | ✔️ |
| markdown-to-pdf | ✔️ | ✔️ |
| merge-pdfs | ✔️ | ✔️ |
| multi-page-layout | ✔️ | ✔️ |
| overlay-pdf | ✔️ | ✔️ |
| pdf-organizer | ✔️ | ✔️ |
| pdf-to-csv | ✔️ | ✔️ |
| pdf-to-img | ✔️ | ✔️ |
| pdf-to-single-page | ✔️ | ✔️ |
| remove-pages | ✔️ | ✔️ |
| remove-password | ✔️ | ✔️ |
| rotate-pdf | ✔️ | ✔️ |
| sanitize-pdf | ✔️ | ✔️ |
| scale-pages | ✔️ | ✔️ |
| sign | ✔️ | ✔️ |
| show-javascript | ✔️ | ✔️ |
| split-by-size-or-count | ✔️ | ✔️ |
| split-pdf-by-sections | ✔️ | ✔️ |
| split-pdfs | ✔️ | ✔️ |
| compress-pdf | | ✔️ |
| extract-image-scans | | ✔️ |
| ocr-pdf | | ✔️ |
| pdf-to-pdfa | | ✔️ |
| remove-blanks | | ✔️ |

View File

@@ -12,7 +12,7 @@ plugins {
import com.github.jk1.license.render.*
group = 'stirling.software'
version = '0.25.0'
version = '0.25.1'
//17 is lowest but we support and recommend 21
sourceCompatibility = '17'
@@ -21,7 +21,6 @@ repositories {
mavenCentral()
}
licenseReport {
renderers = [new JsonReportRenderer()]
}

View File

@@ -1,5 +1,5 @@
apiVersion: v2
appVersion: 0.25.0
appVersion: 0.25.1
description: locally hosted web application that allows you to perform various operations
on PDF files
home: https://github.com/Stirling-Tools/Stirling-PDF

View File

@@ -0,0 +1,34 @@
version: '3.3'
services:
stirling-pdf:
container_name: Stirling-PDF-Security-Fat
image: frooodle/s-pdf:latest-fat
deploy:
resources:
limits:
memory: 4G
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8080/api/v1/info/status | grep -q 'UP' && curl -fL http://localhost:8080/ | grep -q 'Please sign in'"]
interval: 5s
timeout: 10s
retries: 16
ports:
- 8080:8080
volumes:
- /stirling/latest/data:/usr/share/tessdata:rw
- /stirling/latest/config:/configs:rw
- /stirling/latest/logs:/logs:rw
environment:
DOCKER_ENABLE_SECURITY: "true"
SECURITY_ENABLELOGIN: "true"
PUID: 1002
PGID: 1002
UMASK: "022"
SYSTEM_DEFAULTLOCALE: en-US
UI_APPNAME: Stirling-PDF
UI_HOMEDESCRIPTION: Demo site for Stirling-PDF Latest-fat with Security
UI_APPNAMENAVBAR: Stirling-PDF Latest-fat
SYSTEM_MAXFILESIZE: "100"
METRICS_ENABLED: "true"
SYSTEM_GOOGLEVISIBILITY: "true"
restart: on-failure:5

View File

@@ -27,6 +27,8 @@ services:
SECURITY_OAUTH2_CLIENTID: "<YOUR CLIENT ID>.apps.googleusercontent.com" # Client ID from your provider
SECURITY_OAUTH2_CLIENTSECRET: "<YOUR CLIENT SECRET>" # Client Secret from your provider
SECURITY_OAUTH2_SCOPES: "openid,profile,email" # Expected OAuth2 Scope
SECURITY_OAUTH2_USEASUSERNAME: "email" # Default is 'email'; custom fields can be used as the username
SECURITY_OAUTH2_PROVIDER: "google" # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak'
PUID: 1002
PGID: 1002
UMASK: "022"

View File

@@ -11,14 +11,16 @@ if [ ! -z "$PGID" ] && [ "$PGID" != "$(getent group stirlingpdfgroup | cut -d: -
fi
umask "$UMASK" || true
if [[ "$INSTALL_BOOK_AND_ADVANCED_HTML_OPS" == "true" ]]; then
if [[ "$INSTALL_BOOK_AND_ADVANCED_HTML_OPS" == "true" && "$FAT_DOCKER" != "true" ]]; then
apk add --no-cache calibre@testing
fi
/scripts/download-security-jar.sh
if [[ "$FAT_DOCKER" != "true" ]]; then
/scripts/download-security-jar.sh
fi
if [[ -n "$LANGS" ]]; then
/scripts/installFonts.sh $LANGS
/scripts/installFonts.sh $LANGS
fi
echo "Setting permissions and ownership for necessary directories..."

View File

@@ -2,8 +2,10 @@ package stirling.software.SPDF.config;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Properties;
import java.util.function.Predicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
@@ -108,4 +110,26 @@ public class AppConfig {
public boolean missingActivSecurity() {
return false;
}
@Bean(name = "watchedFoldersDir")
public String watchedFoldersDir() {
return "./pipeline/watchedFolders/";
}
@Bean(name = "finishedFoldersDir")
public String finishedFoldersDir() {
return "./pipeline/finishedFolders/";
}
@Bean(name = "directoryFilter")
public Predicate<Path> processPDFOnlyFilter() {
return path -> {
if (Files.isDirectory(path)) {
return !path.toString().contains("processing");
} else {
String fileName = path.getFileName().toString();
return fileName.endsWith(".pdf");
}
};
}
}

View File

@@ -1,8 +1,10 @@
package stirling.software.SPDF.config;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -45,15 +47,27 @@ public class ConfigInitializer
}
}
} else {
Path templatePath =
Paths.get(
getClass()
.getClassLoader()
.getResource("settings.yml.template")
.toURI());
Path userPath = Paths.get("configs", "settings.yml");
// Load the template content from classpath
List<String> templateLines;
try (InputStream in =
getClass().getClassLoader().getResourceAsStream("settings.yml.template")) {
if (in == null) {
throw new FileNotFoundException(
"Resource file not found: settings.yml.template");
}
templateLines = new ArrayList<>();
try (var reader = new InputStreamReader(in)) {
try (var bufferedReader = new BufferedReader(reader)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
templateLines.add(line);
}
}
}
}
List<String> templateLines = Files.readAllLines(templatePath);
// Read the user settings file if it exists
Path userPath = Paths.get("configs", "settings.yml");
List<String> userLines =
Files.exists(userPath) ? Files.readAllLines(userPath) : new ArrayList<>();
@@ -87,6 +101,7 @@ public class ConfigInitializer
Files.write(userPath, resultLines);
}
// Ensure the custom settings file exists
Path customSettingsPath = Paths.get("configs", "custom_settings.yml");
if (!Files.exists(customSettingsPath)) {
Files.createFile(customSettingsPath);

View File

@@ -116,6 +116,7 @@ public class EndpointConfiguration {
addEndpointToGroup("Security", "change-permissions");
addEndpointToGroup("Security", "add-watermark");
addEndpointToGroup("Security", "cert-sign");
addEndpointToGroup("Security", "remove-cert-sign");
addEndpointToGroup("Security", "sanitize-pdf");
addEndpointToGroup("Security", "auto-redact");
@@ -200,6 +201,7 @@ public class EndpointConfiguration {
addEndpointToGroup("Java", "extract-images");
addEndpointToGroup("Java", "change-metadata");
addEndpointToGroup("Java", "cert-sign");
addEndpointToGroup("Java", "remove-cert-sign");
addEndpointToGroup("Java", "multi-page-layout");
addEndpointToGroup("Java", "scale-pages");
addEndpointToGroup("Java", "add-page-numbers");

View File

@@ -1,10 +1,22 @@
package stirling.software.SPDF.controller.api.converters;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
@@ -26,6 +38,8 @@ import stirling.software.SPDF.utils.WebResponseUtils;
@Tag(name = "Convert", description = "Convert APIs")
public class ConvertPDFToPDFA {
private static final Logger logger = LoggerFactory.getLogger(ConvertPDFToPDFA.class);
@PostMapping(consumes = "multipart/form-data", value = "/pdf/pdfa")
@Operation(
summary = "Convert a PDF to a PDF/A",
@@ -36,9 +50,39 @@ public class ConvertPDFToPDFA {
MultipartFile inputFile = request.getFileInput();
String outputFormat = request.getOutputFormat();
// Save the uploaded file to a temporary location
// Convert MultipartFile to byte[]
byte[] pdfBytes = inputFile.getBytes();
// Load the PDF document
PDDocument document = Loader.loadPDF(pdfBytes);
// Get the document catalog
PDDocumentCatalog catalog = document.getDocumentCatalog();
// Get the AcroForm
PDAcroForm acroForm = catalog.getAcroForm();
if (acroForm != null) {
// Remove signature fields safely
List<PDField> fieldsToRemove =
acroForm.getFields().stream()
.filter(field -> field instanceof PDSignatureField)
.collect(Collectors.toList());
if (!fieldsToRemove.isEmpty()) {
acroForm.flatten(fieldsToRemove, false);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
document.save(baos);
pdfBytes = baos.toByteArray();
}
}
document.close();
// Save the uploaded (and possibly modified) file to a temporary location
Path tempInputFile = Files.createTempFile("input_", ".pdf");
inputFile.transferTo(tempInputFile.toFile());
try (OutputStream outputStream = new FileOutputStream(tempInputFile.toFile())) {
outputStream.write(pdfBytes);
}
// Prepare the output file path
Path tempOutputFile = Files.createTempFile("output_", ".pdf");
@@ -58,7 +102,7 @@ public class ConvertPDFToPDFA {
.runCommandWithOutputHandling(command);
// Read the optimized PDF file
byte[] pdfBytes = Files.readAllBytes(tempOutputFile);
byte[] optimizedPdfBytes = Files.readAllBytes(tempOutputFile);
// Clean up the temporary files
Files.deleteIfExists(tempInputFile);
@@ -69,6 +113,6 @@ public class ConvertPDFToPDFA {
Filenames.toSimpleFileName(inputFile.getOriginalFilename())
.replaceFirst("[.][^.]+$", "")
+ "_PDFA.pdf";
return WebResponseUtils.bytesToWebResponse(pdfBytes, outputFilename);
return WebResponseUtils.bytesToWebResponse(optimizedPdfBytes, outputFilename);
}
}

View File

@@ -19,6 +19,7 @@ import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.scheduling.annotation.Scheduled;
@@ -28,6 +29,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import stirling.software.SPDF.model.PipelineConfig;
import stirling.software.SPDF.model.PipelineOperation;
import stirling.software.SPDF.utils.FileMonitor;
@Service
public class PipelineDirectoryProcessor {
@@ -35,11 +37,18 @@ public class PipelineDirectoryProcessor {
private static final Logger logger = LoggerFactory.getLogger(PipelineDirectoryProcessor.class);
@Autowired private ObjectMapper objectMapper;
@Autowired private ApiDocService apiDocService;
final String watchedFoldersDir = "./pipeline/watchedFolders/";
final String finishedFoldersDir = "./pipeline/finishedFolders/";
@Autowired PipelineProcessor processor;
@Autowired FileMonitor fileMonitor;
final String watchedFoldersDir;
final String finishedFoldersDir;
public PipelineDirectoryProcessor(
@Qualifier("watchedFoldersDir") String watchedFoldersDir,
@Qualifier("finishedFoldersDir") String finishedFoldersDir) {
this.watchedFoldersDir = watchedFoldersDir;
this.finishedFoldersDir = finishedFoldersDir;
}
@Scheduled(fixedRate = 60000)
public void scanFolders() {
@@ -130,7 +139,11 @@ public class PipelineDirectoryProcessor {
throws IOException {
try (Stream<Path> paths = Files.list(dir)) {
if ("automated".equals(operation.getParameters().get("fileInput"))) {
return paths.filter(path -> !Files.isDirectory(path) && !path.equals(jsonFile))
return paths.filter(
path ->
!Files.isDirectory(path)
&& !path.equals(jsonFile)
&& fileMonitor.isFileReadyForProcessing(path))
.map(Path::toFile)
.toArray(File[]::new);
} else {

View File

@@ -0,0 +1,81 @@
package stirling.software.SPDF.controller.api.security;
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDField;
import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.PDFFile;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/security")
@Tag(name = "Security", description = "Security APIs")
public class RemoveCertSignController {
private static final Logger logger = LoggerFactory.getLogger(RemoveCertSignController.class);
@PostMapping(consumes = "multipart/form-data", value = "/remove-cert-sign")
@Operation(
summary = "Remove digital signature from PDF",
description =
"This endpoint accepts a PDF file and returns the PDF file without the digital signature. Input: PDF, Output: PDF")
public ResponseEntity<byte[]> removeCertSignPDF(@ModelAttribute PDFFile request)
throws Exception {
MultipartFile pdf = request.getFileInput();
// Convert MultipartFile to byte[]
byte[] pdfBytes = pdf.getBytes();
// Create a ByteArrayOutputStream to hold the resulting PDF
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Load the PDF document
PDDocument document = Loader.loadPDF(pdfBytes);
// Get the document catalog
PDDocumentCatalog catalog = document.getDocumentCatalog();
// Get the AcroForm
PDAcroForm acroForm = catalog.getAcroForm();
if (acroForm != null) {
// Remove signature fields safely
List<PDField> fieldsToRemove =
acroForm.getFields().stream()
.filter(field -> field instanceof PDSignatureField)
.collect(Collectors.toList());
if (!fieldsToRemove.isEmpty()) {
acroForm.flatten(fieldsToRemove, false);
}
}
// Save the modified document to the ByteArrayOutputStream
document.save(baos);
document.close();
// Return the modified PDF as a response
return WebResponseUtils.boasToWebResponse(
baos,
Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
+ "_unsigned.pdf");
}
}

View File

@@ -53,6 +53,13 @@ public class SecurityWebController {
return "security/cert-sign";
}
@GetMapping("/remove-cert-sign")
@Hidden
public String certUnSignForm(Model model) {
model.addAttribute("currentPage", "remove-cert-sign");
return "security/remove-cert-sign";
}
@GetMapping("/sanitize-pdf")
@Hidden
public String sanitizeForm(Model model) {

View File

@@ -357,7 +357,7 @@ public class ApplicationProperties {
public Provider get(String registrationId) throws Exception {
switch (registrationId) {
case "gogole":
case "google":
return getGoogle();
case "github":
return getGithub();

View File

@@ -0,0 +1,168 @@
package stirling.software.SPDF.utils;
import static java.nio.file.StandardWatchEventKinds.*;
import java.io.IOException;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class FileMonitor {
private static final Logger logger = LoggerFactory.getLogger(FileMonitor.class);
private final Map<Path, WatchKey> path2KeyMapping;
private final Set<Path> newlyDiscoveredFiles;
private final ConcurrentHashMap.KeySetView<Path, Boolean> readyForProcessingFiles;
private final WatchService watchService;
private final Predicate<Path> pathFilter;
private final Path rootDir;
private Set<Path> stagingFiles;
/**
* @param rootDirectory the root directory to monitor
* @param pathFilter the filter to apply to the paths, return true if the path should be
* monitored, false otherwise
*/
@Autowired
public FileMonitor(
@Qualifier("watchedFoldersDir") String rootDirectory,
@Qualifier("directoryFilter") Predicate<Path> pathFilter)
throws IOException {
this.newlyDiscoveredFiles = new HashSet<>();
this.path2KeyMapping = new HashMap<>();
this.stagingFiles = new HashSet<>();
this.pathFilter = pathFilter;
this.readyForProcessingFiles = ConcurrentHashMap.newKeySet();
this.watchService = FileSystems.getDefault().newWatchService();
this.rootDir = Path.of(rootDirectory);
}
private boolean shouldNotProcess(Path path) {
return !pathFilter.test(path);
}
private void recursivelyRegisterEntry(Path dir) throws IOException {
WatchKey key = dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
path2KeyMapping.put(dir, key);
logger.info("Registered directory: {}", dir);
try (Stream<Path> directoryVisitor = Files.walk(dir, 1)) {
final Iterator<Path> iterator = directoryVisitor.iterator();
while (iterator.hasNext()) {
Path path = iterator.next();
if (path.equals(dir) || shouldNotProcess(path)) continue;
if (Files.isDirectory(path)) {
recursivelyRegisterEntry(path);
} else if (Files.isRegularFile(path)) {
handleFileCreation(path);
}
}
}
}
@Scheduled(fixedRate = 5000)
public void trackFiles() {
/*
All files observed changes in the last iteration will be considered as staging files.
If those files are not modified in current iteration, they will be considered as ready for processing.
*/
stagingFiles = new HashSet<>(newlyDiscoveredFiles);
readyForProcessingFiles.clear();
if (path2KeyMapping.isEmpty()) {
logger.warn(
"not monitoring any directory, even the root directory itself: {}", rootDir);
if (Files.exists(
rootDir)) { // if the root directory exists, re-register the root directory
try {
recursivelyRegisterEntry(rootDir);
} catch (IOException e) {
logger.error("unable to register monitoring", e);
}
}
}
WatchKey key;
while ((key = watchService.poll()) != null) {
final Path watchingDir = (Path) key.watchable();
key.pollEvents()
.forEach(
(evt) -> {
final Path path = (Path) evt.context();
final WatchEvent.Kind<?> kind = evt.kind();
if (shouldNotProcess(path)) return;
try {
if (Files.isDirectory(path)) {
if (kind == ENTRY_CREATE) {
handleDirectoryCreation(path);
}
/*
we don't need to handle directory deletion or modification
- directory deletion will be handled by key.reset()
- directory modification indicates a new file creation or deletion, which is handled by below
*/
}
Path relativePathFromRoot = watchingDir.resolve(path);
if (kind == ENTRY_CREATE) {
handleFileCreation(relativePathFromRoot);
} else if (kind == ENTRY_DELETE) {
handleFileRemoval(relativePathFromRoot);
} else if (kind == ENTRY_MODIFY) {
handleFileModification(relativePathFromRoot);
}
} catch (Exception e) {
logger.error("Error while processing file: {}", path, e);
}
});
boolean isKeyValid = key.reset();
if (!isKeyValid) { // key is invalid when the directory itself is no longer exists
path2KeyMapping.remove((Path) key.watchable());
}
}
readyForProcessingFiles.addAll(stagingFiles);
}
private void handleDirectoryCreation(Path dir) throws IOException {
WatchKey key = dir.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
path2KeyMapping.put(dir, key);
}
private void handleFileRemoval(Path path) {
newlyDiscoveredFiles.remove(path);
stagingFiles.remove(path);
}
private void handleFileCreation(Path path) {
newlyDiscoveredFiles.add(path);
stagingFiles.remove(path);
}
private void handleFileModification(Path path) {
// the logic is the same
handleFileCreation(path);
}
/**
* Check if the file is ready for processing.
*
* <p>A file is ready for processing if it is not being modified for 5000ms.
*
* @param path the path of the file
* @return true if the file is ready for processing, false otherwise
*/
public boolean isFileReadyForProcessing(Path path) {
return readyForProcessingFiles.contains(path);
}
}

View File

@@ -42,6 +42,7 @@ public class FileToPdf {
List<String> command = new ArrayList<>();
if (!htmlFormatsInstalled) {
command.add("weasyprint");
command.add("-e utf-8");
command.add(tempInputFile.toString());
command.add(tempOutputFile.toString());

View File

@@ -332,6 +332,10 @@ home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=الاسم
certSign.submit=تسجيل PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=إزالة الفراغات
removeBlanks.header=إزالة الصفحات الفارغة
@@ -965,6 +976,7 @@ pdfToPDFA.credit=تستخدم هذه الخدمة OCRmyPDF لتحويل PDF / A.
pdfToPDFA.submit=تحويل
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -59,8 +59,8 @@ deleteCurrentUserMessage=Не може да се изтрие вписания
deleteUsernameExistsMessage=Потребителското име не съществува и не може да бъде изтрито.
downgradeCurrentUserMessage=Не може да се понижи ролята на текущия потребител
downgradeCurrentUserLongMessage=Не може да се понижи ролята на текущия потребител. Следователно текущият потребител няма да бъде показан.
userAlreadyExistsOAuthMessage=The user already exists as an OAuth2 user.
userAlreadyExistsWebMessage=The user already exists as an web user.
userAlreadyExistsOAuthMessage=Потребителят вече съществува като OAuth2 потребител.
userAlreadyExistsWebMessage=Потребителят вече съществува като уеб-потребител.
error=Грешка
oops=Опаа!
help=Помощ
@@ -105,18 +105,18 @@ pipelineOptions.validateButton=Валидирай
#############
# NAVBAR #
#############
navbar.favorite=Favorites
navbar.favorite=Любими
navbar.darkmode=Тъмна тема
navbar.language=Languages
navbar.language=Езици
navbar.settings=Настройки
navbar.allTools=Tools
navbar.multiTool=Multi Tools
navbar.sections.organize=Organize
navbar.sections.convertTo=Convert to PDF
navbar.sections.convertFrom=Convert from PDF
navbar.sections.security=Sign & Security
navbar.sections.advance=Advanced
navbar.sections.edit=View & Edit
navbar.allTools=Инструменти
navbar.multiTool=Мулти инструменти
navbar.sections.organize=Организирайте
navbar.sections.convertTo=Преобразуване в PDF
navbar.sections.convertFrom=Преобразуване от PDF
navbar.sections.security=Подписване и сигурност
navbar.sections.advance=Разширено
navbar.sections.edit=Преглед и редактиране
#############
# SETTINGS #
@@ -185,7 +185,7 @@ adminUserSettings.internalApiUser=Вътрешен API потребител
adminUserSettings.forceChange=Принудете потребителя да промени потребителското име/парола при влизане
adminUserSettings.submit=Съхранете потребителя
adminUserSettings.changeUserRole=Промяна на ролята на потребителя
adminUserSettings.authenticated=Authenticated
adminUserSettings.authenticated=Удостоверен
#############
# HOME-PAGE #
@@ -267,7 +267,7 @@ home.fileToPDF.desc=Преобразуване почти всеки файл к
fileToPDF.tags=трансформация,формат,документ,изображение,слайд,текст,преобразуване,офис,документи,word,excel,powerpoint
home.ocr.title=OCR / Почистващи сканирания
home.ocr.desc=Почистване, сканира и открива текст от изображения към PDF и го добавя отново като текст.
home.ocr.desc=Почиства, сканира и открива текст от изображения в PDF и го добавя отново като текст.
ocr.tags=разпознаване,текст,изображение,сканиране,четене,идентифициране,откриване,редактиране
@@ -313,7 +313,7 @@ home.flatten.desc=Премахнете всички интерактивни е
flatten.tags=статичен,деактивиран,неинтерактивен,рационализиран
home.repair.title=Поправи
home.repair.desc=Опитва се да поправи повреден/счупен PDF
home.repair.desc=Опитва се да поправи повреден PDF
repair.tags=поправка,възстановяване,корекция,възстановяване
home.removeBlanks.title=Премахване на празни страници
@@ -332,6 +332,10 @@ home.certSign.title=Подпишете със сертификат
home.certSign.desc=Подписва PDF със сертификат/ключ (PEM/P12)
certSign.tags=удостоверяване,PEM,P12,официален,шифроване
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Оформление с няколко страници
home.pageLayout.desc=Слейте няколко страници от PDF документ в една страница
pageLayout.tags=сливане,комбиниран,единичен изглед,организиране
@@ -364,7 +368,7 @@ home.autoSplitPDF.title=Автоматично разделяне на стра
home.autoSplitPDF.desc=Автоматично разделяне на сканиран PDF файл с QR код за разделяне на физически сканирани страници
autoSplitPDF.tags=QR-базиран,отделен,сканиране-сегмент,организиране
home.sanitizePdf.title=Дезинфенкцирам
home.sanitizePdf.title=Обеззаразяване
home.sanitizePdf.desc=Премахване на скриптове и други елементи от PDF файлове
sanitizePdf.tags=чисти,сигурни,безопасни,премахване-заплахи
@@ -382,8 +386,8 @@ home.MarkdownToPDF.desc=Преобразува всеки Markdown файл къ
MarkdownToPDF.tags=маркиране,уеб-съдържание,трансформация,преобразуване
home.getPdfInfo.title=Вземете ЦЯЛАТА информация към PDF
home.getPdfInfo.desc=Взема всяка възможна информация от PDF файлове
home.getPdfInfo.title=Вземете ЦЯЛАТА информация от PDF
home.getPdfInfo.desc=Взима всяка възможна информация от PDF файлове
getPdfInfo.tags=информация,данни,статистики,статистика
@@ -405,7 +409,7 @@ home.autoRedact.title=Автоматично редактиране
home.autoRedact.desc=Автоматично редактира (зачернява) текст в PDF въз основа на въведен текст
autoRedact.tags=Редактиране,Скриване,затъмняване,черен,маркер,скрит
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.title=PDF в CSV
home.tableExtraxt.desc=Извлича таблици от PDF, като ги конвертира в CSV
tableExtraxt.tags=CSV,извличане на таблица,извличане,конвертиране
@@ -452,12 +456,12 @@ login.locked=Вашият акаунт е заключен.
login.signinTitle=Моля впишете се
login.ssoSignIn=Влизане чрез еднократно влизане
login.oauth2AutoCreateDisabled=OAUTH2 Автоматично създаване на потребител е деактивирано
login.oauth2RequestNotFound=Authorization request not found
login.oauth2InvalidUserInfoResponse=Invalid User Info Response
login.oauth2invalidRequest=Invalid Request
login.oauth2AccessDenied=Access Denied
login.oauth2InvalidTokenResponse=Invalid Token Response
login.oauth2InvalidIdToken=Invalid Id Token
login.oauth2RequestNotFound=Заявката за оторизация не е намерена
login.oauth2InvalidUserInfoResponse=Невалидна информация за потребителя
login.oauth2invalidRequest=Невалидна заявка
login.oauth2AccessDenied=Отказан достъп
login.oauth2InvalidTokenResponse=Невалиден отговор на токена
login.oauth2InvalidIdToken=Невалиден токен за идентификатор
#auto-redact
@@ -638,7 +642,7 @@ scalePages.submit=Подайте
#certSign
certSign.title=Подписване на сертификат
certSign.title=Подписване със сертификат
certSign.header=Подпишете PDF с вашия сертификат (В процес на работа)
certSign.selectPDF=Изберете PDF файл за подписване:
certSign.jksNote=Забележка: Ако вашият тип сертификат не е в списъка по-долу, моля, конвертирайте го във файл на Java Keystore (.jks) с помощта на инструмента за команден ред keytool. След това изберете опцията за .jks файл по-долу.
@@ -655,6 +659,13 @@ certSign.name=Име
certSign.submit=Подпишете PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Премахване на празни места
removeBlanks.header=Премахване на празни страници
@@ -758,7 +769,7 @@ extractImages.submit=Извличане
fileToPDF.title=Файл към PDF
fileToPDF.header=Конвертирайте всеки файл към PDF
fileToPDF.credit=Тази услуга използва LibreOffice и Unoconv за преобразуване на файлове.
fileToPDF.supportedFileTypesInfo=Supported File types
fileToPDF.supportedFileTypesInfo=Поддържание файлови типове
fileToPDF.supportedFileTypes=Поддържаните типове файлове трябва да включват по-долу, но за пълен актуализиран списък на поддържаните формати, моля, вижте документацията на LibreOffice
fileToPDF.submit=Преобразуване към PDF
@@ -767,10 +778,10 @@ fileToPDF.submit=Преобразуване към PDF
compress.title=Компресиране
compress.header=Компресиране на PDF
compress.credit=Тази услуга използва Ghostscript за PDF компресиране/оптимизиране.
compress.selectText.1=Ръчен режим - От 1 до 4
compress.selectText.1=Ръчен режим - от 1 до 4
compress.selectText.2=Ниво на оптимизация:
compress.selectText.3=4 (Ужасно за текстови изображения)
compress.selectText.4=Автоматичен режим - Автоматично настройва качеството, за да получи PDF точен размер
compress.selectText.4=Автоматичен режим - Автоматично настройва качеството, за да получи PDF с точен размер
compress.selectText.5=Очакван PDF размер (напр. 25МБ, 10.8МБ, 25КБ)
compress.submit=Компресиране
@@ -811,7 +822,7 @@ pdfOrganiser.placeholder=(напр. 1,3,2 или 4-8,2,10-12 или 2n-1)
#multiTool
multiTool.title=PDF Мулти инструмент
multiTool.header=PDF Мулти инструмент
multiTool.uploadPrompts=File Name
multiTool.uploadPrompts=Име на файл
#view pdf
viewPdf.title=Преглед на PDF
@@ -910,8 +921,8 @@ watermark.selectText.7=Непрозрачност (0% - 100%):
watermark.selectText.8=Тип воден знак:
watermark.selectText.9=Изображение за воден знак:
watermark.submit=Добавяне на воден знак
watermark.type.1=Text
watermark.type.2=Image
watermark.type.1=Текст
watermark.type.2=Изображение
#Change permissions
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Тази услуга използва OCRmyPDF за PDF/A пр
pdfToPDFA.submit=Преобразуване
pdfToPDFA.tip=В момента не работи за няколко входа наведнъж
pdfToPDFA.outputFormat=Изходен формат
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Signa amb Certificat
home.certSign.desc=Sign PDF amb Certificate/Clau (PEM/P12)
certSign.tags=authentica,PEM,P12,official,encripta
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Nom
certSign.submit=Firma PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Elimina els espais en blanc
removeBlanks.header=Elimina les pàgines en blanc
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Utilitza OCRmyPDF per la conversió a PDF/A
pdfToPDFA.submit=Converteix
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Podpis s certifikátem
home.certSign.desc=Podpis PDF s certifikátem/klíčem (PEM/P12)
certSign.tags=autentizace,PEM,P12,oficiální,šifrování
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Vícestránkové rozložení
home.pageLayout.desc=Sloučení více stránek dokumentu PDF do jedné stránky
pageLayout.tags=sloučit,kompozitní,jedno zobrazení,organizovat
@@ -655,6 +659,13 @@ certSign.name=Název
certSign.submit=Podepsat PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Odebrat prázdné stránky
removeBlanks.header=Odebrat prázdné stránky
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Tato služba používá OCRmyPDF pro konverzi do formátu PDF/A
pdfToPDFA.submit=Převést
pdfToPDFA.tip=V současné době nepracuje pro více vstupů najednou
pdfToPDFA.outputFormat=Výstupní formát
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Mit Zertifikat signieren
home.certSign.desc=Ein PDF mit einem Zertifikat/Schlüssel (PEM/P12) signieren
certSign.tags=authentifizieren,pem,p12,offiziell,verschlüsseln
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Mehrseitiges Layout
home.pageLayout.desc=Mehrere Seiten eines PDF zu einer Seite zusammenführen
pageLayout.tags=zusammenführen,zusammensetzen,einzelansicht,organisieren
@@ -655,6 +659,13 @@ certSign.name=Name
certSign.submit=PDF signieren
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Leere Seiten entfernen
removeBlanks.header=Leere Seiten entfernen
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Dieser Dienst verwendet OCRmyPDF für die PDF/A-Konvertierung
pdfToPDFA.submit=Konvertieren
pdfToPDFA.tip=Dieser Dienst kann nur einzelne Eingangsdateien verarbeiten.
pdfToPDFA.outputFormat=Ausgabeformat
pdfToPDFA.pdfWithDigitalSignature=Das PDF enthält eine digitale Signatur. Sie wird im nächsten Schritt entfernt.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Υπογραφή με Πιστοποιητικό
home.certSign.desc=Υπογραφή ενός PDF αρχείου με ένα Πιστοποιητικό/Κλειδί (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Διάταξη πολλών σελίδων
home.pageLayout.desc=Συγχώνευση πολλαπλών σελίδων ενός εγγράφου PDF σε μία μόνο σελίδα
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Όνομα
certSign.submit=Υπογραφή PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Αφαίρεση Κενών
removeBlanks.header=Αφαίρεση Κενών Σελίδων
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Αυτή η υπηρεσία χρησιμοποιεί OCRmyPDF
pdfToPDFA.submit=Μετατροπή
pdfToPDFA.tip=Προς το παρόν δεν λειτουργεί για πολλαπλές εισόδους ταυτόχρονα
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Name
certSign.submit=Sign PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Remove Blanks
removeBlanks.header=Remove Blank Pages
@@ -965,6 +976,7 @@ pdfToPDFA.credit=This service uses OCRmyPDF for PDF/A conversion
pdfToPDFA.submit=Convert
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Name
certSign.submit=Sign PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Remove Blanks
removeBlanks.header=Remove Blank Pages
@@ -965,6 +976,7 @@ pdfToPDFA.credit=This service uses OCRmyPDF for PDF/A conversion
pdfToPDFA.submit=Convert
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Firmar con certificado
home.certSign.desc=Firmar un PDF con un Certificado/Clave (PEM/P12)
certSign.tags=autentificar,PEM,P12,oficial,encriptar
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Diseño de varias páginas
home.pageLayout.desc=Unir varias páginas de un documento PDF en una sola página
pageLayout.tags=unir,compuesto,vista única,organizar
@@ -655,6 +659,13 @@ certSign.name=Nombre
certSign.submit=Firmar PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Eliminar espacios en blanco
removeBlanks.header=Eliminar páginas en blanco
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Este servicio usa OCRmyPDF para la conversión a PDF/A
pdfToPDFA.submit=Convertir
pdfToPDFA.tip=Actualmente no funciona para múltiples entrada a la vez
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Sinatu ziurtagiriarekin
home.certSign.desc=Sinatu PDF bat Ziurtagiri/Gako batekin (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Zenbait orrialderen diseinua
home.pageLayout.desc=Elkartu orri bakar batean PDF dokumentu baten zenbait orrialde
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Izena
certSign.submit=Sinatu PDFa
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Ezabatu zuriuneak
removeBlanks.header=Ezabatu orrialde zuriak
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Zerbitzu honek OCRmyPDF erabiltzen du PDFak PDF/A bihurtzeko
pdfToPDFA.submit=Bihurtu
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Signer avec un certificat
home.certSign.desc=Signez un PDF avec un certificat ou une clé (PEM/P12).
certSign.tags=signer,chiffrer,certificat,authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Fusionner des pages
home.pageLayout.desc=Fusionnez plusieurs pages dun PDF en une seule.
pageLayout.tags=fusionner,merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Nom
certSign.submit=Signer
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Supprimer les pages vierges
removeBlanks.header=Supprimer les pages vierges
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Ce service utilise OCRmyPDF pour la conversion en PDF/A.
pdfToPDFA.submit=Convertir
pdfToPDFA.tip=Ne fonctionne actuellement pas pour plusieurs entrées à la fois
pdfToPDFA.outputFormat=Format de sortie
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=प्रमाणपत्र के साथ हस्त
home.certSign.desc=पीडीएफ़ को प्रमाणपत्र/कुंजी (PEM/P12) के साथ हस्ताक्षरित करता है।
certSign.tags=प्रमाणीकरण, PEM, P12, आधिकारिक, एन्क्रिप्ट
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=मल्टी-पेज लेआउट
home.pageLayout.desc=पीडीएफ़ दस्तावेज़ के कई पेजों को एक ही पेज में मर्ज करता है।
pageLayout.tags=मर्ज, संयोजित, एकल दृश्य, संगठित
@@ -655,6 +659,13 @@ certSign.name=नाम
certSign.submit=पीडीएफ़ पर हस्ताक्षर करें
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=खाली पेज हटाएं
removeBlanks.header=खाली पेज हटाएं
@@ -965,6 +976,7 @@ pdfToPDFA.credit=इस सेवा में PDF/A परिवर्तन
pdfToPDFA.submit=परिवर्तित करें
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

File diff suppressed because it is too large Load Diff

View File

@@ -332,6 +332,10 @@ home.certSign.title=Aláírás Tanúsítvánnyal
home.certSign.desc=PDF aláírása tanúsítvánnyal/kulccsal (PEM/P12)
certSign.tags=hitelesítés,PEM,P12,hivatalos,segitít,álca
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Több oldal elrendezése
home.pageLayout.desc=Több oldal egyesítése egy PDF dokumentumban egyetlen oldallá
pageLayout.tags=egyesítés,kompozit,egy oldal,megszervez
@@ -655,6 +659,13 @@ certSign.name=Név
certSign.submit=PDF aláírása
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Üres oldalak eltávolítása
removeBlanks.header=Üres oldalak eltávolítása
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Ez a szolgáltatás az OCRmyPDF-t használja a PDF/A konverzió
pdfToPDFA.submit=Konvertálás
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Tanda tangani dengan Sertifikat
home.certSign.desc=Menandatangani PDF dengan Certificate/Key (PEM/P12)
certSign.tags=mengotentikasi, PEM, P12, resmi, mengenkripsi
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Tata Letak Multi-Halaman
home.pageLayout.desc=Menggabungkan beberapa halaman dokumen PDF menjadi satu halaman
pageLayout.tags=menggabungkan, komposit, tampilan tunggal, mengatur
@@ -655,6 +659,13 @@ certSign.name=Nama
certSign.submit=Tanda tangani PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Hapus Halaman Kosong
removeBlanks.header=Remove Blank Pages
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Layanan ini menggunakan OCRmyPDF untuk konversi PDF/A.
pdfToPDFA.submit=Konversi
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Firma con certificato
home.certSign.desc=Firma un PDF con un certificato/chiave (PEM/P12)
certSign.tags=autenticare,PEM,P12,ufficiale,crittografare
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Layout multipagina
home.pageLayout.desc=Unisci più pagine di un documento PDF in un'unica pagina
pageLayout.tags=unire,comporre,visualizzazione singola,organizzare
@@ -417,7 +421,7 @@ autoSizeSplitPDF.tags=pdf,diviso,documento,organizzazione
home.overlay-pdfs.title=Sovrapposizione di PDF
home.overlay-pdfs.desc=Sovrappone i PDF sopra un altro PDF
overlay-pdfs.tags=Svrapponi
overlay-pdfs.tags=Sovrapponi
home.split-by-sections.title=Dividi PDF per sezioni
home.split-by-sections.desc=Dividi ciascuna pagina di un PDF in sezioni orizzontali e verticali più piccole
@@ -457,7 +461,7 @@ login.oauth2InvalidUserInfoResponse=Risposta relativa alle informazioni utente n
login.oauth2invalidRequest=Richiesta non valida
login.oauth2AccessDenied=Accesso negato
login.oauth2InvalidTokenResponse=Risposta token non valida
login.oauth2InvalidIdToken=Invalid Id Token
login.oauth2InvalidIdToken=Id Token non valido
#auto-redact
@@ -655,6 +659,13 @@ certSign.name=Nome
certSign.submit=Firma PDF
#removeCertSign
removeCertSign.title=Rimuovi certificato della firma
removeCertSign.header=Rimuovere il certificato digitale dal PDF
removeCertSign.selectPDF=Seleziona un file PDF:
removeCertSign.submit=Rimuovi firma
#removeBlanks
removeBlanks.title=Rimuovi spazi vuoti
removeBlanks.header=Rimuovi pagine vuote
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Questo servizio utilizza OCRmyPDF per la conversione in PDF/A.
pdfToPDFA.submit=Converti
pdfToPDFA.tip=Attualmente non funziona per più input contemporaneamente
pdfToPDFA.outputFormat=Formato di output
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=証明書による署名
home.certSign.desc=証明書/キーを使用してPDFに署名します。 (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=マルチページレイアウト
home.pageLayout.desc=PDFの複数のページを1ページに結合します。
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=名前
certSign.submit=PDFに署名
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=空白の削除
removeBlanks.header=空白ページの削除
@@ -965,6 +976,7 @@ pdfToPDFA.credit=本サービスはPDF/Aの変換にOCRmyPDFを使用してい
pdfToPDFA.submit=変換
pdfToPDFA.tip=現在、一度に複数の入力に対して機能しません
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=인증서로 서명
home.certSign.desc=PDF 문서에 인증서 또는 키로 서명합니다. (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=다중 페이지 레이아웃
home.pageLayout.desc=PDF 문서의 여러 페이지를 한 페이지로 합칩니다.
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=이름
certSign.submit=PDF 서명
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=빈 페이지 제거
removeBlanks.header=빈 페이지 제거
@@ -965,6 +976,7 @@ pdfToPDFA.credit=이 서비스는 PDF/A 변환을 위해 OCRmyPDF 문서를 사
pdfToPDFA.submit=변환
pdfToPDFA.tip=현재 한 번에 여러 입력에 대해 작동하지 않습니다.
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Ondertekenen met certificaat
home.certSign.desc=Ondertekent een PDF met een certificaat/sleutel (PEM/P12)
certSign.tags=authenticeren,PEM,P12,officieel,versleutelen
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Multi-pagina indeling
home.pageLayout.desc=Voeg meerdere pagina's van een PDF-document samen op één pagina
pageLayout.tags=samenvoegen,composiet,enkel-zicht,organiseren
@@ -655,6 +659,13 @@ certSign.name=Naam
certSign.submit=PDF ondertekenen
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Verwijder blanco's
removeBlanks.header=Verwijder lege pagina's
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Deze service gebruikt OCRmyPDF voor PDF/A-conversie
pdfToPDFA.submit=Converteren
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Podpisz certyfikatem
home.certSign.desc=Podpisz dokument PDF za pomocą certyfikatu/klucza prywatnego (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Układ wielu stron
home.pageLayout.desc=Scal wiele stron dokumentu PDF w jedną stronę
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Nazwa
certSign.submit=Podpisz PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Usuń puste
removeBlanks.header=Usuń puste strony
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Ta usługa używa OCRmyPDF do konwersji PDF/A
pdfToPDFA.submit=Konwertuj
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Assinar com Certificado
home.certSign.desc=Assinar um PDF com um Certificado/Chave (PEM/P12)
certSign.tags=autenticar,PEM,P12,oficial,criptografar
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Layout de Múltiplas Páginas
home.pageLayout.desc=Mesclar várias páginas de um documento PDF em uma única página
pageLayout.tags=mesclar,composto,vista-única,organizar
@@ -655,6 +659,13 @@ certSign.name=Nome
certSign.submit=Assinar PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Remover Páginas em Branco
removeBlanks.header=Remover Páginas em Branco
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Este serviço usa OCRmyPDF para Conversão de PDF/A
pdfToPDFA.submit=Converter
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Assinar com Certificado
home.certSign.desc=Assinar um PDF com um Certificado/Chave (PEM/P12)
certSign.tags=autenticar,PEM,P12,oficial,criptografar
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Layout de Múltiplas Páginas
home.pageLayout.desc=Juntar várias páginas de um documento PDF em uma única página
pageLayout.tags=juntar,composto,vista-única,organizar
@@ -655,6 +659,13 @@ certSign.name=Nome
certSign.submit=Assinar PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Remover Páginas em Branco
removeBlanks.header=Remover Páginas em Branco
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Este serviço usa OCRmyPDF para Conversão de PDF/A
pdfToPDFA.submit=Converter
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Semnare cu certificat
home.certSign.desc=Semnează un PDF cu un certificat/cheie (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Numele
certSign.submit=Semnează PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Elimină pagini goale
removeBlanks.header=Elimină pagini goale
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Acest serviciu utilizează OCRmyPDF pentru conversia în PDF/A
pdfToPDFA.submit=Convert
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Подписать сертификатом
home.certSign.desc=Подписать PDF сертификатом/ключом (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Объединить страницы
home.pageLayout.desc=Объединение нескольких страниц документа PDF в одну страницу
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Имя
certSign.submit=Подписать PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Удалить Пустые
removeBlanks.header=Удалить Пустые Страницы
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Этот сервис использует OCRmyPDF для пр
pdfToPDFA.submit=Конвертировать
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Podpísať s certifikátom
home.certSign.desc=Podpísať PDF s certifikátom/kľúčom (PEM/P12)
certSign.tags=autentifikovať,PEM,P12,oficiálne,šifrovať
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Viacstranové usporiadanie
home.pageLayout.desc=Zlúčte viacero stránok PDF dokumentu do jednej stránky
pageLayout.tags=zlúčiť,zjednotiť,jednostranový pohľad,organizovať
@@ -655,6 +659,13 @@ certSign.name=Meno
certSign.submit=Podpísať PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Odstrániť prázdne stránky
removeBlanks.header=Odstrániť prázdne stránky
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Táto služba používa OCRmyPDF na konverziu PDF/A
pdfToPDFA.submit=Konvertovať
pdfToPDFA.tip=Momentálne nefunguje pre viacero vstupov naraz
pdfToPDFA.outputFormat=Výstupný formát
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Potpis sa sertifikatom
home.certSign.desc=Potpisuje PDF sa sertifikatom/ključem (PEM/P12)
certSign.tags=autentifikacija,PEM,P12,zvanično,šifrovanje
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Višestruki prikaz stranica
home.pageLayout.desc=Spaja više stranica PDF dokumenta u jednu stranicu
pageLayout.tags=spajanje,kompozit,pojedinačan-prikaz,organizacija
@@ -655,6 +659,13 @@ certSign.name=Ime
certSign.submit=Potpiši PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Ukloni prazne stranice
removeBlanks.header=Ukloni prazne stranice
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Ova usluga koristi OCRmyPDF za konverziju u PDF/A format
pdfToPDFA.submit=Konvertuj
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Sign with Certificate
home.certSign.desc=Signs a PDF with a Certificate/Key (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Multi-Page Layout
home.pageLayout.desc=Merge multiple pages of a PDF document into a single page
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Namn
certSign.submit=Skriv under PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Ta bort tomrum
removeBlanks.header=Ta bort tomma sidor
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Denna tjänst använder OCRmyPDF för PDF/A-konvertering
pdfToPDFA.submit=Konvertera
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Sertifika ile İmzala
home.certSign.desc=Bir PDF'i Sertifika/Anahtar (PEM/P12) ile imzalar
certSign.tags=doğrula,PEM,P12,resmi,şifrele
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Çoklu-Sayfa Düzeni
home.pageLayout.desc=Bir PDF belgesinin çoklu sayfalarını tek bir sayfada birleştirir
pageLayout.tags=birleştir,kompozit,tek-görünüm,düzenle
@@ -655,6 +659,13 @@ certSign.name=İsim
certSign.submit=PDF'i İmzala
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Boşları Kaldır
removeBlanks.header=Boş Sayfaları Kaldır
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Bu hizmet PDF/A dönüşümü için OCRmyPDF kullanır
pdfToPDFA.submit=Dönüştür
pdfToPDFA.tip=Şu anda aynı anda birden fazla giriş için çalışmıyor
pdfToPDFA.outputFormat=Çıkış formatı
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=Підписати сертифікатом
home.certSign.desc=Підписати PDF сертифікатом/ключем (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Об'єднати сторінки
home.pageLayout.desc=Об'єднання кількох сторінок документа PDF в одну сторінку
pageLayout.tags=merge,composite,single-view,organize
@@ -655,6 +659,13 @@ certSign.name=Ім'я
certSign.submit=Підписати PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=Видалити порожні
removeBlanks.header=Видалити порожні сторінки
@@ -965,6 +976,7 @@ pdfToPDFA.credit=Цей сервіс використовує OCRmyPDF для п
pdfToPDFA.submit=Конвертувати
pdfToPDFA.tip=Наразі не працює для кількох вхідних файлів одночасно
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=使用证书签署
home.certSign.desc=使用证书/密钥PEM/P12对PDF进行签署
certSign.tags=身份验证、PEM、P12、官方、加密
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=多页布局
home.pageLayout.desc=将PDF文档的多个页面合并成一页
pageLayout.tags=合并、组合、单视图、整理
@@ -655,6 +659,13 @@ certSign.name=名称
certSign.submit=签署 PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=删除空白
removeBlanks.header=删除空白页
@@ -965,6 +976,7 @@ pdfToPDFA.credit=此服务使用OCRmyPDF进行PDF/A转换
pdfToPDFA.submit=转换
pdfToPDFA.tip=目前不支持上传多个
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -332,6 +332,10 @@ home.certSign.title=使用憑證簽章
home.certSign.desc=使用憑證/金鑰PEM/P12簽章 PDF
certSign.tags=驗證,PEM,P12,官方,加密
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=多頁面版面配置
home.pageLayout.desc=將 PDF 檔案的多個頁面合併到單一頁面
pageLayout.tags=合併,複合,單一檢視,組織
@@ -655,6 +659,13 @@ certSign.name=名稱
certSign.submit=簽章 PDF
#removeCertSign
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
removeBlanks.title=移除空白頁面
removeBlanks.header=移除空白頁面
@@ -965,6 +976,7 @@ pdfToPDFA.credit=此服務使用 OCRmyPDF 進行 PDF/A 轉換
pdfToPDFA.submit=轉換
pdfToPDFA.tip=目前不支援上傳多個
pdfToPDFA.outputFormat=Output format
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -21,15 +21,51 @@
<form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/pdf/pdfa}">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
<div class="mb-3">
<label th:text="#{pdfToPDFA.outputFormat}"></label>
<select class="form-control" name="outputFormat">
<label for="outputFormat" th:text="#{pdfToPDFA.outputFormat}"></label>
<select class="form-control" name="outputFormat" id="outputFormat">
<option value="pdfa-1">PDF/A-1b</option>
<option value="pdfa">PDF/A-2b</option>
</select>
</div>
<br>
<div id="result" class="alert-warning"></div>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pdfToPDFA.submit}"></button>
</form>
<script th:inline="javascript">
document.getElementById('fileInput-input').addEventListener('change', async () => {
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs/pdf.worker.mjs';
const fileInput = document.getElementById('fileInput-input');
const resultDiv = document.getElementById('result');
const file = fileInput.files[0];
const arrayBuffer = await file.arrayBuffer();
try {
const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
let hasSignature = false;
for (let i = 1; i <= pdf.numPages; i++) {
const page = await pdf.getPage(i);
const annotations = await page.getAnnotations({ intent: 'display' });
annotations.forEach(annotation => {
console.log(annotation)
if (annotation.subtype === 'Widget' && annotation.fieldType === 'Sig') {
hasSignature = true;
}
});
}
if (hasSignature) {
/*<![CDATA[*/
resultDiv.textContent = /*[[#{pdfToPDFA.pdfWithDigitalSignature}]]*/ "The PDF contains a digital signature. This will be removed in the next step.";
/*]]>*/
}
} catch (error) {
resultDiv.textContent = 'Error reading the PDF: ' + error.message;
}
});
</script>
<p class="mt-3" th:text="#{pdfToPDFA.credit}"></p>
</div>
</div>

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{crop.title}, header=#{crop.header})}"></th:block>
<th:block th:insert="~{fragments/common :: head(title=#{crop.title}, header=#{crop.header})}"></th:block>
</head>
<body>
@@ -75,6 +75,16 @@
}
});
cropForm.addEventListener('submit', function(e) {
if (xInput.value == "" && yInput.value == "" && widthInput.value == "" && heightInput.value == "") {
// Ορίστε συντεταγμένες για ολόκληρη την επιφάνεια του PDF
xInput.value = 0;
yInput.value = 0;
widthInput.value = pdfCanvas.width;
heightInput.value = pdfCanvas.height;
}
});
overlayCanvas.addEventListener('mousedown', function(e) {
// Clear previously drawn rectangle on the main canvas
context.clearRect(0, 0, pdfCanvas.width, pdfCanvas.height);
@@ -138,4 +148,4 @@
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>
</html>

View File

@@ -29,4 +29,5 @@
<a class="dropdown-item lang_dropdown-item" href="" data-bs-language-code="sr_LATN_RS"> <img 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 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 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 src="images/flags/hr.svg" alt="icon" width="20" height="15"> Hrvatski</a>
</th:block>

View File

@@ -22,8 +22,7 @@
<ul class="navbar-nav me-auto flex-nowrap">
<!-- All Tools -->
<li class="nav-item dropdown dropdown-mega position-static"
th:classappend="${currentPage}=='remove-pages' OR ${currentPage}=='merge-pdfs' OR ${currentPage}=='split-pdfs' OR ${currentPage}=='crop' OR ${currentPage}=='adjust-contrast' OR ${currentPage}=='pdf-organizer' OR ${currentPage}=='rotate-pdf' OR ${currentPage}=='multi-page-layout' OR ${currentPage}=='scale-pages' OR ${currentPage}=='auto-split-pdf' OR ${currentPage}=='extract-page' OR ${currentPage}=='pdf-to-single-page' OR ${currentPage}=='add-password' OR ${currentPage}=='remove-password' OR ${currentPage}=='add-watermark' OR ${currentPage}=='cert-sign' OR ${currentPage}=='sanitize-pdf' OR ${currentPage}=='img-to-pdf' OR ${currentPage}=='file-to-pdf' OR ${currentPage}=='html-to-pdf' OR ${currentPage}=='url-to-pdf' OR ${currentPage}=='pdf-to-img' OR ${currentPage}=='pdf-to-word' OR ${currentPage}=='pdf-to-presentation' OR ${currentPage}=='pdf-to-text' OR ${currentPage}=='pdf-to-html' OR ${currentPage}=='pdf-to-xml' OR ${currentPage}=='pdf-to-pdfa' OR ${currentPage}=='sign' OR ${currentPage}=='repair' OR ${currentPage}=='compare' OR ${currentPage}=='show-javascript' OR ${currentPage}=='flatten' OR ${currentPage}=='remove-blanks' OR ${currentPage}=='remove-annotations' OR ${currentPage}=='extract-image-scans' OR ${currentPage}=='change-metadata' OR ${currentPage}=='add-image' OR ${currentPage}=='ocr-pdf' OR ${currentPage}=='change-permissions' OR ${currentPage}=='extract-images' OR ${currentPage}=='compress-pdf' OR ${currentPage}=='add-page-numbers' OR ${currentPage}=='auto-rename' OR ${currentPage}=='get-info-on-pdf' ? 'active' : ''">
<li class="nav-item dropdown dropdown-mega position-static">
<a class="nav-link" id="navbarDropdown-1" href="#" role="button" data-bs-toggle="dropdown"
aria-haspopup="true" aria-expanded="false">
<span class="material-symbols-rounded">
@@ -91,6 +90,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry ('markdown-to-pdf', 'markdown', 'home.MarkdownToPDF.title', 'home.MarkdownToPDF.desc', 'MarkdownToPDF.tags', 'convert')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry ('book-to-pdf', 'book', 'home.BookToPDF.title', 'home.BookToPDF.desc', 'BookToPDF.tags', 'convert')}">
</div>
</div>
<!-- Convert from PDF menu items -->
<div class="col-lg-2 col-sm-6 py px-xl-1 px-2">
@@ -119,6 +121,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry ('pdf-to-csv', 'csv', 'home.tableExtraxt.title', 'home.tableExtraxt.desc', 'pdfToPDFA.tags', 'convert')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry ('pdf-to-book', 'book', 'home.PDFToBook.title', 'home.PDFToBook.desc', 'PDFToBook.tags', 'convert')}">
</div>
</div>
<!-- Security menu items -->
<div class="col-lg-2 col-sm-6 py px-xl-1 px-2">
@@ -141,6 +146,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry ('cert-sign', 'workspace_premium', 'home.certSign.title', 'home.certSign.desc', 'certSign.tags', 'security')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry ('remove-cert-sign', 'remove_moderator', 'home.removeCertSign.title', 'home.removeCertSign.desc', 'removeCertSign.tags', 'security')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry ('sanitize-pdf', 'sanitizer', 'home.sanitizePdf.title', 'home.sanitizePdf.desc', 'sanitizePdf.tags', 'security')}">
</div>
@@ -233,7 +241,7 @@
</li>
<li class="nav-item">
<li class="nav-item" th:if="${@endpointConfiguration.isEndpointEnabled('multi-tool')}">
<a class="nav-link" href="#" th:href="@{multi-tool}"
th:classappend="${currentPage}=='multi-tool' ? 'active' : ''" th:title="#{home.multiTool.desc}">
<span class="material-symbols-rounded">
@@ -243,7 +251,7 @@
</a>
</li>
<li class="nav-item">
<li class="nav-item" th:if="${@endpointConfiguration.isEndpointEnabled('pipeline')}" >
<a class="nav-link" href="#" th:href="@{pipeline}"
th:classappend="${currentPage}=='pipeline' ? 'active' : ''" th:title="#{home.pipeline.desc}">
<span class="material-symbols-rounded">
@@ -253,7 +261,7 @@
</a>
</li>
<li class="nav-item">
<li class="nav-item" th:if="${@endpointConfiguration.isEndpointEnabled('compress-pdf')}" >
<a class="nav-link" href="#" title="#{home.compressPdfs.title}" th:href="@{compress-pdf}"
th:classappend="${currentPage}=='compress-pdf' ? 'active' : ''" th:title="#{home.compressPdfs.desc}">
<span class="material-symbols-rounded">

View File

@@ -164,6 +164,9 @@
<div
th:replace="~{fragments/card :: card(id='cert-sign', cardTitle=#{home.certSign.title}, cardText=#{home.certSign.desc}, cardLink='cert-sign', toolIcon='workspace_premium', tags=#{certSign.tags}, toolGroup='security')}">
</div>
<div
th:replace="~{fragments/card :: card(id='remove-cert-sign', cardTitle=#{home.removeCertSign.title}, cardText=#{home.removeCertSign.desc}, cardLink='remove-cert-sign', toolIcon='remove_moderator', tags=#{removeCertSign.tags}, toolGroup='security')}">
</div>
<div
th:replace="~{fragments/card :: card(id='multi-page-layout', cardTitle=#{home.pageLayout.title}, cardText=#{home.pageLayout.desc}, cardLink='multi-page-layout', toolIcon='dashboard', tags=#{pageLayout.tags}, toolGroup='organize')}">
</div>

View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{removeCertSign.title}, header=#{removeCertSign.header})}"></th:block>
</head>
<body>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon security">remove_moderator</span>
<span class="tool-header-text" th:text="#{removeCertSign.header}"></span>
</div>
<form action="api/v1/security/remove-cert-sign" method="post" enctype="multipart/form-data">
<div class="mb-3">
<label th:text="#{removeCertSign.selectPDF}"></label>
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div>
</div>
<div class="mb-3 text-center">
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{removeCertSign.submit}"></button>
</div>
</form>
</div>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>

View File

@@ -30,7 +30,6 @@ See https://github.com/adobe-type-tools/cmap-resources
<!-- Bootstrap -->
<script src="js/thirdParty/popper.min.js"></script>
<script src="js/thirdParty/bootstrap.min.js"></script>
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/theme/componentes.css">
<link rel="stylesheet" href="css/navbar.css">
@@ -321,10 +320,7 @@ See https://github.com/adobe-type-tools/cmap-resources
<button id="download" class="toolbarButton hiddenMediumView" title="Save" role="radio" aria-checked="false" tabindex="35" data-l10n-id="pdfjs-save-button">
<span data-l10n-id="pdfjs-save-button-label">Save</span>
</button>
<button id="editorInk" class="toolbarButton" hidden="true" disabled="disabled" title="Draw" role="radio" aria-checked="false" aria-controls="editorInkParamsToolbar" tabindex="36" data-l10n-id="pdfjs-editor-ink-button">
<span data-l10n-id="pdfjs-editor-ink-button-label">Draw</span>
</button>
<button id="editorStamp" class="toolbarButton hidden" hidden="true" disabled="disabled" title="Add or edit images" role="radio" aria-checked="false" aria-controls="editorStampParamsToolbar" tabindex="37" data-l10n-id="pdfjs-editor-stamp-button">
<button id="editorStamp" class="toolbarButton hiddenMediumView" title="Add or edit images" role="radio" aria-checked="false" aria-controls="editorStampParamsToolbar" tabindex="36" data-l10n-id="pdfjs-editor-stamp-button">
<span data-l10n-id="pdfjs-editor-stamp-button-label">Add or edit images</span>
</button>
</div>
@@ -334,21 +330,14 @@ See https://github.com/adobe-type-tools/cmap-resources
<button id="editorFreeText" class="toolbarButton hiddenMediumView" title="Text" tabindex="41" data-l10n-id="pdfjs-editor-free-text-button">
<span data-l10n-id="pdfjs-editor-free-text-button-label">Text</span>
</button>
<button id="print" class="toolbarButton hiddenMediumView" hidden="true" title="Print" tabindex="42" data-l10n-id="pdfjs-print-button">
<span data-l10n-id="pdfjs-print-button-label">Print</span>
</button>
<button id="download" class="toolbarButton hiddenMediumView" hidden="true" title="Save" tabindex="43" data-l10n-id="pdfjs-save-button">
<span data-l10n-id="pdfjs-save-button-label">Save</span>
</button>
<button id="editorInk" class="toolbarButton hiddenMediumView" title="Draw" tabindex="44" data-l10n-id="pdfjs-editor-ink-button">
<button id="editorInk" class="toolbarButton hiddenMediumView" title="Draw" tabindex="42" data-l10n-id="pdfjs-editor-ink-button">
<span data-l10n-id="pdfjs-editor-ink-button-label">Draw</span>
</button>
<div class="verticalToolbarSeparator hiddenMediumView"></div>
<button id="secondaryToolbarToggle" class="toolbarButton" title="Tools" tabindex="45" data-l10n-id="pdfjs-tools-button">
<button id="secondaryToolbarToggle" class="toolbarButton" title="Tools" tabindex="43" data-l10n-id="pdfjs-tools-button">
<span data-l10n-id="pdfjs-tools-button-label">Tools</span>
</button>
</div>

11
test.sh
View File

@@ -75,7 +75,7 @@ main() {
# Building Docker images
docker build --no-cache --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile .
docker build --no-cache --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
# Test each configuration
run_tests "Stirling-PDF-Ultra-Lite" "./exampleYmlFiles/docker-compose-latest-ultra-lite.yml"
docker-compose -f "./exampleYmlFiles/docker-compose-latest-ultra-lite.yml" down
@@ -104,13 +104,18 @@ main() {
# Building Docker images with security enabled
docker build --no-cache --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest -f ./Dockerfile .
docker build --no-cache --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-ultra-lite -f ./Dockerfile-ultra-lite .
docker build --no-cache --build-arg VERSION_TAG=alpha -t frooodle/s-pdf:latest-fat -f ./Dockerfile-fat .
# Test each configuration with security
run_tests "Stirling-PDF-Ultra-Lite-Security" "./exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml"
docker-compose -f "./exampleYmlFiles/docker-compose-latest-ultra-lite-security.yml" down
run_tests "Stirling-PDF-Security" "./exampleYmlFiles/docker-compose-latest-security.yml"
docker-compose -f "./exampleYmlFiles/docker-compose-latest-security.yml" down
run_tests "Stirling-PDF-Security-Fat" "./exampleYmlFiles/docker-compose-latest-fat-security.yml"
docker-compose -f "./exampleYmlFiles/docker-compose-latest-fat-security.yml" down
# Report results
echo "All tests completed in $SECONDS seconds."