Compare commits

...

283 Commits

Author SHA1 Message Date
Anthony Stirling
63eacf443e Merge pull request #610 from Frooodle/fix
required false
2023-12-30 02:20:34 +00:00
Anthony Stirling
b32c28e9cb Update build.gradle 2023-12-30 02:20:16 +00:00
Anthony Stirling
a5ee10e029 required flase 2023-12-30 02:19:30 +00:00
Anthony Stirling
bb1d41d74a Merge pull request #605 from Frooodle/expose-port
refactor: expose local application server port
2023-12-29 23:27:59 +00:00
Anthony Stirling
0698e2888d Merge pull request #608 from Frooodle/overlay
messages
2023-12-29 22:57:29 +00:00
Anthony Stirling
e1f0a6cb1d messages 2023-12-29 22:56:38 +00:00
Anthony Stirling
7fecae8b0d Merge pull request #607 from Frooodle/overlay
overlay fix for sequential
2023-12-29 22:54:07 +00:00
Anthony Stirling
e6622dfdc4 overlay fix for sequential 2023-12-29 22:53:46 +00:00
sbplat
34b4ae0e03 refactor: reflect changes to pipeline release 2023-12-29 17:13:36 -05:00
sbplat
036fd711f9 Merge branch 'main' into expose-port 2023-12-29 17:01:49 -05:00
Anthony Stirling
80a59205fa Merge pull request #570 from Frooodle/test
Pipeline release
2023-12-29 21:51:06 +00:00
Anthony Stirling
cbe4bca716 add banner and remove unused class 2023-12-29 21:46:17 +00:00
Anthony Stirling
232a556425 Merge branch 'test' of git@github.com:Frooodle/Stirling-PDF.git into test 2023-12-29 21:05:42 +00:00
Anthony Stirling
a497ad8c41 api changes to get metrics working 2023-12-29 21:05:32 +00:00
Anthony Stirling
3041e80c37 Merge branch 'main' into test 2023-12-29 20:48:27 +00:00
Anthony Stirling
1b2df20fdd reviews 2023-12-29 20:48:21 +00:00
Anthony Stirling
0e69f7e0e8 Merge pull request #604 from iLern/feat-zhCN
Enhance Chinese Translations and Correct Errors
2023-12-29 18:26:55 +00:00
sbplat
94aba370e0 refactor: expose local application server port 2023-12-29 13:05:01 -05:00
TieStone
cd49d7ffa2 add more Chinese Translations 2023-12-30 00:45:36 +08:00
TieStone
dc297644d1 add more Chinese Translations 2023-12-30 00:45:36 +08:00
TieStone
a7b4e44e6d remove duplicated property keys 2023-12-30 00:45:36 +08:00
Anthony Stirling
610ff22abe empty dir fix 2023-12-29 13:53:55 +00:00
Anthony Stirling
27e8335f79 Merge pull request #602 from Antiarchitect/set-file-encoding
Set java file.encoding to support non-latin customizations
2023-12-29 13:38:03 +00:00
Anthony Stirling
168a0f001c changes 2023-12-29 13:30:28 +00:00
Anthony Stirling
5c6936b494 Rework and cleanup 2023-12-29 12:55:22 +00:00
Anthony Stirling
a715dbb25d cleanup 2023-12-29 11:43:36 +00:00
Andrey Voronkov
a43e13cf94 Set java file.encoding to support non-latin customizations with UI_APPNAME, UI_HOMEDESCRIPTION, etc 2023-12-29 12:35:02 +03:00
Anthony Stirling
7f805d16a1 Merge pull request #600 from sudotman/main
Added missing Hindi (hi_IN) translations and fixed a few broken ones.
2023-12-29 07:57:43 +00:00
Satyam Kashyap
6f3cbe0cae added missing hindi (hi_IN) translations and fixed some broken translations - also updated readme to reflect the newly added translations 2023-12-29 06:05:48 +00:00
Anthony Stirling
44e3556382 Create CODEOWNERS 2023-12-28 23:13:47 +00:00
Anthony Stirling
c5ba546a02 Merge pull request #598 from vivekmaru36/add-hindi-language
Add hindi Translation
2023-12-28 18:56:27 +00:00
Anthony Stirling
d63519bbf4 Merge branch 'main' into add-hindi-language 2023-12-28 18:54:56 +00:00
Anthony Stirling
aeadc88f92 resolve .exe showing other entries it doesnt support 2023-12-28 18:46:54 +00:00
Anthony Stirling
829e98c29b MaxRAMPercentage 75 for #540 2023-12-28 17:49:45 +00:00
vivekmaru36
3e3f4a0188 Add hindi Translation 2023-12-28 23:09:38 +05:30
Anthony Stirling
e5bdd52b7c Merge pull request #589 from sbplat/main
fix: sequentially convert each pdf page into a BufferedImage to avoid getting out of memory errors for large pdf files
2023-12-28 17:39:02 +00:00
Anthony Stirling
e653ef6522 Merge branch 'main' into main 2023-12-28 17:32:38 +00:00
Anthony Stirling
5fcb4e893b pipeline refactor beginnings 2023-12-28 17:23:19 +00:00
Anthony Stirling
c2b524e459 Merge pull request #596 from eltociear/patch-2
chore: update README.md
2023-12-28 17:09:08 +00:00
sbplat
5a055bae5e Merge branch 'main' into main 2023-12-28 11:47:44 -05:00
Ikko Eltociear Ashimine
c3f501d701 chore: update README.md
a -> an
2023-12-29 00:34:56 +09:00
Anthony Stirling
8acab77ae3 contextPath fixes 2023-12-28 13:50:31 +00:00
Anthony Stirling
8bd2784f37 Merge pull request #594 from albanobattistella/patch-3
Update messages_it_IT.properties
2023-12-28 09:31:29 +00:00
albanobattistella
e2c5027311 Update messages_it_IT.properties 2023-12-28 10:28:21 +01:00
Anthony Stirling
d2b2adcbc1 Merge pull request #593 from aancw/id-translate
Add Indonesia Translation
2023-12-28 09:04:07 +00:00
Anthony Stirling
48158379ee Merge branch 'main' into id-translate 2023-12-28 09:03:02 +00:00
Aan
6ba84a190f translate file word to indonesia 2023-12-28 15:34:50 +07:00
Aan
d349aea1be Translate file word 2023-12-28 15:30:36 +07:00
Aan
79e2683cbe Keep watermark translation 2023-12-28 15:12:18 +07:00
Anthony Stirling
e4fb64ce16 Merge pull request #588 from Emad-Eldin-G/patch-1
Optimized the code in detect-blank-pages.py
2023-12-28 07:55:25 +00:00
sbplat
d405b7a810 perf: avoid re-rendering the first pdf page 2023-12-27 22:46:55 -05:00
sbplat
1d243a0ca5 fix: clean up redundant variable 2023-12-27 22:43:30 -05:00
sbplat
1f10693eaf fix: sequentially convert each pdf page into a BufferedImage to avoid getting MLE for large pdf files 2023-12-28 03:23:55 +00:00
EmadEldin Osman
b7f62a635d Optimized the code in detect-blank-pages.py
Made use of Numpy arrays
2023-12-28 04:51:50 +03:00
Anthony Stirling
4e991e7ec2 Merge pull request #582 from manuelkamp/patch-5
Update LocalRunGuide.md
2023-12-28 00:49:02 +00:00
Anthony Stirling
8fe7e57a6a Merge branch 'main' into patch-5 2023-12-28 00:47:06 +00:00
Anthony Stirling
5c79a5da29 Merge pull request #585 from Saneeitas/Saneeitas-patch-1
Update README.md
2023-12-28 00:37:24 +00:00
Muhammad Sani Ibrahim
d01473aceb Update README.md
made the english more standard
2023-12-28 01:27:25 +01:00
Anthony Stirling
3911be0177 Add Demo user 2023-12-27 22:56:51 +00:00
Anthony Stirling
78da44ad83 fix for #583 2023-12-27 19:28:49 +00:00
manuelkamp
54859ac3ba Update LocalRunGuide.md
Improved optional service section regarding environment variables in a separate .env file
2023-12-27 19:52:51 +01:00
Anthony Stirling
9cb8c9f655 Merge pull request #581 from manuelkamp/patch-4
Update LocalRunGuide.md
2023-12-27 18:48:30 +00:00
manuelkamp
dfda474ba5 Update LocalRunGuide.md
Added option to set up Stirling-PDF as a service
2023-12-27 19:30:28 +01:00
Anthony Stirling
43f15b3e55 Merge pull request #579 from manuelkamp/patch-3
Update LocalRunGuide.md
2023-12-27 18:10:13 +00:00
Anthony Stirling
86c45f6f8f Merge pull request #578 from manuelkamp/patch-2
Update LocalRunGuide.md
2023-12-27 18:10:03 +00:00
Anthony Stirling
de83321c62 Merge pull request #577 from manuelkamp/patch-1
Update LocalRunGuide.md #575
2023-12-27 18:09:43 +00:00
manuelkamp
7b44cf77d6 Update LocalRunGuide.md
Added "WeasyPrint" to pip3 install section
2023-12-27 18:54:55 +01:00
manuelkamp
c769a02982 Update LocalRunGuide.md
Edited run via java, since on previous step we moved the jar-file to /opt/Stirling-PDF
2023-12-27 18:51:51 +01:00
manuelkamp
aa671b8bd6 Update LocalRunGuide.md 2023-12-27 18:46:37 +01:00
Anthony Stirling
6e7c066e57 Merge pull request #574 from eltociear/patch-1
Update README.md
2023-12-27 15:39:54 +00:00
Ikko Eltociear Ashimine
78ac9231c5 Update README.md
temporay -> temporary
2023-12-28 00:34:30 +09:00
Anthony Stirling
e9947da5b4 changes 2023-12-27 15:18:26 +00:00
Anthony Stirling
8df7dfc3be Merge pull request #569 from albanobattistella/patch-2
Update messages_it_IT.properties
2023-12-27 15:03:44 +00:00
albanobattistella
d79db6f3da Update messages_it_IT.properties 2023-12-27 16:01:00 +01:00
Anthony Stirling
84aebe3851 validate button color 2023-12-27 13:22:28 +00:00
Anthony Stirling
f5c285a70f mild cleanup 2023-12-27 12:51:17 +00:00
Perdana Hadi
2d6bf43bdb update tags translations 2023-12-27 15:52:11 +07:00
Aan
964f22e3e0 Add Bahasa Indonesia 2023-12-27 14:43:32 +07:00
Aan
d325020e22 home page section done, todo tags extractImages.tags 2023-12-27 14:37:25 +07:00
Aan
aec85ddd66 missing quote 2023-12-27 14:09:57 +07:00
Perdana Hadi
32b009b11f remove extra line, add white space 2023-12-27 12:38:17 +07:00
Perdana Hadi
2e5b72e4fb add web-pages translation 2023-12-27 12:28:31 +07:00
Aan
1d3cf2bdc3 Remove DS_Store 2023-12-27 10:27:39 +07:00
Aan
2a5fe2bd74 27/12/2023 2023-12-27 10:06:09 +07:00
Anthony Stirling
61ff0248da close 2023-12-27 01:00:42 +00:00
Anthony Stirling
659af2089c setup 2023-12-27 00:53:31 +00:00
Anthony Stirling
8960313a2b Merge pull request #566 from sbplat/main
fix: add default value for the position in Add Page Numbers
2023-12-26 20:55:48 +00:00
Anthony Stirling
6ee8e1e37f auto disable in UI 2023-12-26 20:33:17 +00:00
Anthony Stirling
05977aa3a6 enableAlphaFunctionality 2023-12-26 20:10:37 +00:00
sbplat
f7dbb8d0a6 Merge branch 'main' of https://github.com/sbplat/Stirling-PDF 2023-12-26 13:32:13 -05:00
sbplat
eaf65d7981 fix: add selectedPosition style to the Add Page Number position selector default value 2023-12-26 13:31:33 -05:00
sbplat
a10e3a025b Merge branch 'Frooodle:main' into main 2023-12-26 13:27:21 -05:00
sbplat
4d3e442ecc fix: add default value for the position in Add Page Numbers 2023-12-26 13:26:37 -05:00
Anthony Stirling
49576c0aa4 Merge pull request #564 from farwill/farwill-patch-1
Fix README.md typo
2023-12-26 09:08:16 +00:00
farwill
960af83f11 Fix README.md typo 2023-12-26 14:30:18 +08:00
Aan
cf42ef7faa Intial Draft #1 2023-12-26 12:38:27 +07:00
Anthony Stirling
d894937c22 Merge pull request #560 from sbplat/main
fix(multitool): hide dragged pdf page at the start so it doesn't teleport
2023-12-25 22:27:30 +00:00
Anthony Stirling
8938e86223 Merge branch 'main' into main 2023-12-25 22:24:30 +00:00
Anthony Stirling
c1a39e53dc Merge pull request #559 from DimK10/main
Fixes #324 issue
2023-12-25 21:47:09 +00:00
dkaitantzidis
cf3693186a Fixes headers issue in merge pdfs. 2023-12-25 23:27:08 +02:00
Anthony Stirling
0fb0cb8bca apply local 2023-12-25 20:51:32 +00:00
dkaitantzidis
fb18d0d04d WIP: Fixes issue - needs refactor 2023-12-25 22:36:08 +02:00
sbplat
779d9028fe fix(multitool): hide dragged pdf page at the start so it doesn't teleport 2023-12-25 15:34:16 -05:00
Anthony Stirling
f2b701e3e3 todos 2023-12-25 18:52:11 +00:00
Anthony Stirling
a138d5f5a9 imports 2023-12-25 16:16:50 +00:00
Anthony Stirling
6276f028ac validate operations 2023-12-25 16:15:42 +00:00
Anthony Stirling
b962e867d8 log remove 2023-12-25 15:17:06 +00:00
Anthony Stirling
a286a92ede cleanups 2023-12-25 15:15:46 +00:00
Anthony Stirling
7fb8f5ed28 create logs dir 2023-12-25 15:03:45 +00:00
Anthony Stirling
03d3235e1d Merge remote-tracking branch 'origin/main' into test 2023-12-25 13:26:13 +00:00
Anthony Stirling
d23551857c deps 2023-12-25 13:00:44 +00:00
Anthony Stirling
dd9dd72f35 Role stuff 2023-12-25 12:58:49 +00:00
Anthony Stirling
9652f59ae9 Merge pull request #555 from sbplat/main
feat: merge pdf into multiple frames if the format is TIFF
2023-12-25 10:14:23 +00:00
sbplat
3469beb5b3 feat: merge pdf into multiple frames if the format is TIFF instead of a single big image 2023-12-24 22:52:39 -05:00
Anthony Stirling
690720f4e3 test interface 2023-12-25 01:25:17 +00:00
Anthony Stirling
491be75e1f Merge pull request #554 from sbplat/main
feat: make multiple images the default setting for PDF to Image
2023-12-24 22:29:07 +00:00
sbplat
a868b2c649 feat: make multiple images the default setting for PDF to Image 2023-12-24 16:55:11 -05:00
Anthony Stirling
0b49993d80 Merge pull request #553 from sbplat/main
fix!: map BMP and TIFF extensions to the proper MIME types
2023-12-24 21:50:17 +00:00
sbplat
995a926e35 fix!: map BMP and TIFF extensions to the proper MIME types
Remove the WBMP image format from PDF to Image
2023-12-24 15:27:16 -05:00
Anthony Stirling
914dd0a21a Merge pull request #552 from sbplat/main
fix: use JPEGFactory for jpeg
2023-12-24 18:02:12 +00:00
Anthony Stirling
d9b5d08b06 import clean 2023-12-24 17:56:31 +00:00
sbplat
344d1163ff Merge branch 'Frooodle:main' into main 2023-12-24 12:53:29 -05:00
sbplat
3f50979d3e fix: use JPEGFactory for jpeg 2023-12-24 12:52:55 -05:00
Anthony Stirling
c681f48459 Merge pull request #549 from sbplat/main
feat: add support for svg+webp images to convert to pdf
2023-12-24 17:18:37 +00:00
Anthony Stirling
2f5d7ed712 internal API plus brute force security 2023-12-24 17:12:32 +00:00
sbplat
1efefcfcb8 feat: add support for svg+webp images to convert to pdf 2023-12-23 20:27:04 -05:00
Anthony Stirling
909c9ed4d9 Merge pull request #548 from sbplat/main
Add remove annotations
2023-12-23 19:07:20 +00:00
sbplat
116b3535ee Update messages_en_GB.properties 2023-12-23 13:49:50 -05:00
sbplat
b7d6107a2d feat: add remove annotations 2023-12-23 13:47:21 -05:00
Anthony Stirling
120b017b1a serial 2023-12-23 16:26:09 +00:00
Anthony Stirling
24568f4a42 Merge pull request #547 from simovics/main
Adding Hungarian language support to Stirling-PDF
2023-12-23 16:00:54 +00:00
Anthony Stirling
03450454c5 pipeline 2023-12-23 15:47:18 +00:00
simovics
7e982e125d Create hu.svg
Adding Hungarian flag icon to the set.
2023-12-23 14:46:42 +01:00
simovics
e725451530 Update languages.html
Fixing indentation.
2023-12-23 14:21:51 +01:00
simovics
d7d6bc8108 Update languages.html
Adding Hungarian language reference to the navbar.
2023-12-23 14:19:07 +01:00
simovics
6d66ac0a8b Create messages_hu_HU.properties
Hungarian translation for Stirling-PDF.
2023-12-23 14:15:10 +01:00
Anthony Stirling
93f12d1313 pipeline changes 2023-12-23 12:29:32 +00:00
Anthony Stirling
eab9e3cffc changes pipeline 2023-12-20 19:29:13 +00:00
Anthony Stirling
d74c25e678 Merge pull request #542 from NeilJared/main
Update messages_es_ES.properties
2023-12-19 21:17:13 +00:00
NeilJared
c729b7201f Merge branch 'main' into main 2023-12-19 19:44:22 +01:00
NeilJared
beab9932d7 Update messages_es_ES.properties
Updated es_ES translation
2023-12-19 19:41:11 +01:00
Anthony Stirling
65fcf29fd5 Merge pull request #537 from Frooodle/dependabot/gradle/io.swagger.swaggerhub-1.3.2
Bump io.swagger.swaggerhub from 1.2.0 to 1.3.2
2023-12-19 18:34:24 +00:00
Anthony Stirling
73007239ee Merge branch 'main' into dependabot/gradle/io.swagger.swaggerhub-1.3.2 2023-12-19 18:32:46 +00:00
Anthony Stirling
816d874ac4 Merge pull request #541 from dhenry437/fix/bootstrap-icons
Fix for bootstrap icons
2023-12-19 13:59:05 +00:00
Dan Henry
b66f86f7cc add missing bootstrap icons link in head 2023-12-19 22:51:00 +11:00
Dan Henry
168ef747de add up to date minified bootstrap icons 2023-12-19 22:50:46 +11:00
dependabot[bot]
ad047ab012 Bump io.swagger.swaggerhub from 1.2.0 to 1.3.2
Bumps io.swagger.swaggerhub from 1.2.0 to 1.3.2.

---
updated-dependencies:
- dependency-name: io.swagger.swaggerhub
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-12-18 22:45:51 +00:00
Anthony Stirling
1ea3fb209b ARG VERSION_TAG 2023-12-18 16:39:26 +00:00
Anthony Stirling
875d9da36b Update Dockerfile 2023-12-18 15:41:05 +00:00
Anthony Stirling
b21d2ecbd1 Update push-docker.yml 2023-12-18 15:38:37 +00:00
Anthony Stirling
3bffc1da76 gradle changes 2023-12-18 14:58:06 +00:00
Anthony Stirling
631d3948bd fix for #531 plus seperated out some things 2023-12-18 14:52:18 +00:00
Anthony Stirling
5774a22b64 possible fixes for overlay 2023-12-17 12:35:50 +00:00
ant
39345bb6bb Merge branch 'main' of git@github.com:Frooodle/Stirling-PDF.git into main 2023-12-17 12:31:24 +00:00
Anthony Stirling
57b483047e splitPdf sections cleanup 2023-12-17 12:23:11 +00:00
Anthony Stirling
0fb7633da8 Merge pull request #528 from NicolasFR/lang/FR_fr-updates
lang: update fr_FR
2023-12-17 11:34:09 +00:00
Nicolas
dae2f33772 lang: update fr_FR 2023-12-17 10:39:33 +01:00
Anthony Stirling
31ac877612 Update build.gradle 2023-12-16 19:56:56 +00:00
Anthony Stirling
79dcf99cce Clean imports and lang updates 2023-12-16 19:30:47 +00:00
Anthony Stirling
c28a40ffe8 Split by sections #506 2023-12-16 19:29:43 +00:00
Anthony Stirling
12dccab460 auth log #522 2023-12-16 18:18:00 +00:00
Anthony Stirling
0a26e2e6d6 new deps 2023-12-16 10:42:27 +00:00
Anthony Stirling
74f6cd63f4 other JS changes 2023-12-16 10:35:45 +00:00
Anthony Stirling
e8de5739fa Resolve has Update button to stay hidden if error 2023-12-16 10:26:35 +00:00
Anthony Stirling
1b2734d99c login enable and security stuff 2023-12-16 10:22:33 +00:00
Anthony Stirling
206cf40cb5 Update Dockerfile-ultra-lite
login
2023-12-16 10:11:34 +00:00
Anthony Stirling
78473e96fd Update Dockerfile-lite
fix for #526 Support for login in lite
2023-12-16 10:08:09 +00:00
Anthony Stirling
b7d6ac2cc3 extra fonts, ocr display full names, overlay fixes 2023-12-12 23:25:56 +00:00
Anthony Stirling
4068d9530f svg 2023-12-11 23:24:13 +00:00
Anthony Stirling
8a331956c2 Merge branch 'main' of git@github.com:Frooodle/Stirling-PDF.git into main 2023-12-11 23:20:43 +00:00
Anthony Stirling
1d3e018a56 init overlay and auto split 2023-12-11 23:20:31 +00:00
Anthony Stirling
3602034938 Merge pull request #520 from NicolasFR/patch-1
Update messages_fr_FR.properties
2023-12-11 18:39:05 +00:00
NicolasFR
eb4e2d5fca Update messages_fr_FR.properties 2023-12-11 17:56:38 +01:00
Anthony Stirling
b6671939e5 Merge pull request #517 from NeilJared/es_ES
Update messages_es_ES.properties
2023-12-11 12:12:17 +00:00
Anthony Stirling
41d09e40a1 Merge branch 'main' into es_ES 2023-12-11 12:11:10 +00:00
Anthony Stirling
9b0dba7f65 Update account.html
#515 fix
2023-12-11 12:10:10 +00:00
NeilJared
ac0dc8b5c7 Update messages_es_ES.properties
Updated es_ES translation
2023-12-11 13:06:59 +01:00
Anthony Stirling
723216c693 Merge pull request #516 from Frooodle/Frooodle-patch-1
Update build.gradle
2023-12-11 11:02:45 +00:00
Anthony Stirling
46f9a5057f Update build.gradle 2023-12-11 11:01:48 +00:00
Anthony Stirling
8a2633ca93 Update build.gradle 2023-12-11 10:59:05 +00:00
Anthony Stirling
a03470d2de Update Dockerfile 2023-12-11 10:09:28 +00:00
Anthony Stirling
ef7c98e5cb Merge pull request #514 from Frooodle/securityStuff
Security stuff
2023-12-11 10:00:57 +00:00
Anthony Stirling
c9cd1331d2 Merge branch 'main' into securityStuff 2023-12-11 09:58:09 +00:00
Anthony Stirling
ddc14517b8 Merge branch 'securityStuff' of git@github.com:Frooodle/Stirling-PDF.git into securityStuff 2023-12-11 09:57:37 +00:00
Anthony Stirling
578aecf977 WeasyPrint 2023-12-11 09:57:28 +00:00
Anthony Stirling
b1ca938053 Merge pull request #513 from Frooodle/securityStuff
fix
2023-12-11 09:35:23 +00:00
Anthony Stirling
298fe349c1 Merge branch 'main' into securityStuff 2023-12-11 09:33:20 +00:00
Anthony Stirling
f4364a3f33 bump 2023-12-11 09:33:05 +00:00
Anthony Stirling
e0f068bc9d test 2023-12-11 09:32:36 +00:00
Anthony Stirling
d7f8219b80 Update view-pdf.html 2023-12-10 23:22:25 +00:00
Anthony Stirling
87bc0fc975 Merge pull request #509 from Frooodle/securityStuff
Docker file security updates and minor fixes to things
2023-12-10 23:10:04 +00:00
Anthony Stirling
9f21ce96de Merge branch 'main' into securityStuff 2023-12-10 23:08:34 +00:00
Anthony Stirling
1f29033f17 docker changes 2023-12-10 23:06:35 +00:00
Anthony Stirling
59c7978330 docker and ocr updates 2023-12-10 22:02:30 +00:00
Anthony Stirling
8b55ffff96 changes 2023-12-10 16:33:44 +00:00
Anthony Stirling
a94808fd19 dark mode fixes 2023-12-10 15:29:12 +00:00
Anthony Stirling
7b2ffcff01 Merge pull request #504 from albanobattistella/patch-1
Update messages_it_IT.properties
2023-12-10 14:11:17 +00:00
Anthony Stirling
28a9daff62 init 2023-12-10 14:09:28 +00:00
albanobattistella
435753f50b Update messages_it_IT.properties 2023-12-08 16:01:14 +01:00
Anthony Stirling
1e6f288d72 Merge pull request #501 from alexdraconian/lang-ko
Add/improve Korean translation
2023-12-07 17:39:28 +00:00
Anthony Stirling
6d3fece5a6 Merge branch 'main' into lang-ko 2023-12-07 16:21:01 +00:00
alexdraconian
db926c50d8 Add/improve Korean translation 2023-12-07 21:47:20 +09:00
Anthony Stirling
dd9333f42e Merge pull request #491 from digitalindependent/patch-1
Typo fixed in HowToUseOCR.md
2023-12-02 23:39:42 +00:00
digitalindependent
3fa5acc51c Typo fixed in HowToUseOCR.md
ITS => IT'S
2023-12-02 22:34:43 +01:00
Anthony Stirling
15fa3df424 Merge pull request #475 from danielr1996/main
ci: add helm package/push to Jenkinsfile
2023-11-30 20:08:31 +00:00
Anthony Stirling
06c4ec95d5 Merge branch 'main' into main 2023-11-24 14:36:19 +00:00
Anthony Stirling
1a6afc1582 Merge pull request #470 from trytomakeyouprivate/main
added Podman and Distrobox notes
2023-11-24 13:35:10 +00:00
trytomakeyouprivate
ad2e1e4a18 Merge branch 'Frooodle:main' into main 2023-11-24 12:56:02 +00:00
Anthony Stirling
a1d0dcff41 Merge pull request #479 from Ludy87/german-translation
update language german
2023-11-17 15:16:57 +00:00
Ludy87
08da0f5c56 update language german 2023-11-17 16:07:02 +01:00
Daniel Richter
0b666674f7 fix(helm): move ci build to github actions
Signed-off-by: Daniel Richter <danielrichter@posteo.de>
2023-11-16 23:04:32 +01:00
Daniel Richter
d3fe467f6f ci: add helm package/push to Jenkinsfile
Signed-off-by: Daniel Richter <danielrichter@posteo.de>
2023-11-12 22:31:35 +01:00
trytomakeyouprivate
732fa0ec40 added Podman and Distrobox note 2023-11-07 11:49:11 +00:00
trytomakeyouprivate
7a7c978df2 added Podman
Podman is supposedly more Secure and used and distributed by Redhat and Fedora. It is CLI compatible with Docker
2023-11-07 11:45:42 +00:00
Anthony Stirling
9d052b310f Merge pull request #459 from Artem-ka-create/issue-372-pdfbox
Issue 372 pdfbox
2023-11-05 19:49:14 +00:00
Atrem Petrenko
8ff1a63276 Merge branch 'main' into issue-372-pdfbox 2023-11-05 14:49:04 +01:00
Anthony Stirling
ffd413ce7f Merge pull request #464 from NeilJared/main
Update messages_es_ES.properties
2023-11-05 11:23:18 +00:00
NeilJared
f2607bd161 Update messages_es_ES.properties
Modified!
2023-11-05 11:59:15 +01:00
NeilJared
ba5f3e12d7 Update messages_es_ES.properties
Updated Spanish translation
2023-11-05 11:39:53 +01:00
Anthony Stirling
ddc48429b1 Merge pull request #403 from Pixee-Bot-Java/pixeebot/drip-2023-10-05-pixee-java/secure-random
Introduced protections against predictable RNG abuse
2023-11-03 00:58:11 +00:00
Anthony Stirling
b8b7adbaf9 Merge pull request #456 from omerbustun/main
Add Turkish language support
2023-11-03 00:52:20 +00:00
Anthony Stirling
4ae945d08a Merge branch 'main' into main 2023-11-03 00:51:12 +00:00
Anthony Stirling
12f5a5e6d0 Merge pull request #460 from sanjeevneo/main
Enhance navbar for dark mode support
2023-11-02 19:16:48 +00:00
sanjeevneo
f85a7cb04d Enhance navbar for dark mode support 2023-11-03 02:15:02 +11:00
Atrem Petrenko
2f6a885bb0 update language properties 2023-11-02 12:13:33 +01:00
Atrem Petrenko
c8ac1f7029 implementing extracting tables from pdf by pdfbox 2023-11-02 11:50:50 +01:00
Atrem Petrenko
d6afb07533 starting issue, implementing pdf-to-csv view 2023-10-31 18:58:40 +01:00
Zach Carroll
a55f9f0ec8 Merge branch 'main' into pixeebot/drip-2023-10-05-pixee-java/secure-random 2023-10-30 15:26:14 -04:00
Ömer Üstün
06401d875b Merge branch 'Frooodle:main' into main 2023-10-30 20:01:26 +03:00
Ömer Üstün
4a29fd4b73 Update README.md 2023-10-30 19:59:15 +03:00
Ömer Üstün
02c53b90b3 Update messages_tr_TR.properties 2023-10-30 19:58:04 +03:00
Ömer Üstün
6ca1d82188 Update messages_tr_TR.properties 2023-10-30 19:19:12 +03:00
Anthony Stirling
18c5f5bb2b Merge pull request #455 from sanjeevneo/main
Optimize Dark Mode Toggle for Additional UI Elements
2023-10-30 10:34:27 +00:00
Anthony Stirling
33d21a7a85 Merge pull request #453 from tkymmm/main
Update messages_ja_JP.properties
2023-10-30 10:34:04 +00:00
Neo
c48c3e8897 Dark Mode Improvements 2023-10-30 18:29:55 +11:00
tkymmm
67f34016ce Update messages_ja_JP.properties 2023-10-30 09:21:02 +09:00
Ömer Üstün
c1434df259 Update messages_tr_TR.properties 2023-10-29 22:55:06 +03:00
Ömer Üstün
dd0eaf9182 Update messages_tr_TR.properties 2023-10-29 22:55:06 +03:00
Ömer Üstün
cfe50bcd81 Update messages_tr_TR.properties 2023-10-29 22:55:06 +03:00
omerbustun
a75bbff7cf Update messages_tr_TR.properties 2023-10-29 22:55:06 +03:00
omerbustun
2e9d88da0e Add Turkish option to navbar language selector
- Updated the navbar to include the Turkish language option.
- Added the Turkish flag SVG to the assets folder.
- Translated a portion of the .properties file to support Turkish.
2023-10-29 22:55:06 +03:00
Anthony Stirling
124c7801c5 Merge pull request #440 from quyleanh/patch-1
Update README.md to correct Endpoint-groups.md link
2023-10-29 15:59:24 +00:00
Anthony Stirling
8490613ada Merge pull request #450 from maxi322/main
Add german translation for View PDF
2023-10-29 15:59:12 +00:00
Anthony Stirling
80553ce95a Merge branch 'main' into patch-1 2023-10-28 15:29:22 +01:00
maxi322
d9206bfd2a Add german translation for View PDF 2023-10-28 15:31:44 +02:00
Anthony Stirling
7aae688db2 add searchbar translation option 2023-10-28 13:30:48 +01:00
Anthony Stirling
347b4cfa85 Update build.gradle 2023-10-28 12:14:11 +01:00
Anthony Stirling
f2eebcc396 extra lang 2023-10-28 12:12:54 +01:00
Anthony Stirling
19c26f0552 lang update 2023-10-28 12:06:23 +01:00
Anthony Stirling
d532db91f9 fixes for #438 and #423 2023-10-28 10:40:26 +01:00
Anthony Stirling
bd0bf404f5 Merge pull request #445 from DimK10/Feature-request-pdf-reader
Adds navbar logo to pdf viewer
2023-10-27 18:28:33 +01:00
Dimitris Kaitantzidis
e51a9c209a Merge branch 'main' into Feature-request-pdf-reader 2023-10-27 20:11:14 +03:00
Dimitrios Kaitantzidis
6bf172fb25 Adds navbar logo to pdf viewer 2023-10-27 20:08:13 +03:00
Anthony Stirling
a1e93e0f5d Update .gitattributes 2023-10-25 22:07:05 +01:00
Anthony Stirling
6392f6ec12 Merge pull request #442 from joleaf/main
Fix help text in addPageNumbers.customNumberDesc
2023-10-25 10:20:33 +01:00
joleaf
fbdff5c97f Update messages_it_IT.properties - fix helptext addPageNumbers.customNumberDesc 2023-10-25 10:55:13 +02:00
joleaf
2ecc4ed080 Update messages_es_ES.properties - Fix helptext addPageNumbers.customNumberDesc 2023-10-25 10:54:21 +02:00
joleaf
3318cb96b2 Update messages_de_DE.properties - fix helptext addPageNumbers.customNumberDesc 2023-10-25 10:53:10 +02:00
Quy Le Anh
6be0a1fb05 Update README.md to correct Endpoint-groups.md link 2023-10-24 17:11:48 +09:00
Anthony Stirling
ab1297aee0 Version bump and readme change 2023-10-22 23:14:18 +01:00
Anthony Stirling
25a0cb7681 Merge pull request #439 from DimK10/Feature-request-pdf-reader
Feature request pdf reader
2023-10-22 23:02:14 +01:00
Dimitrios Kaitantzidis
116b034878 Adds support for greek language. 2023-10-23 00:56:53 +03:00
Dimitrios Kaitantzidis
038de2e264 Adds ignore for .idea folder entirely 2023-10-23 00:43:43 +03:00
Dimitrios Kaitantzidis
7e51cf8c5a Removes .idea files and updates README.md. 2023-10-23 00:40:03 +03:00
Dimitrios Kaitantzidis
a1eadba769 Fixes .idea ignored files. 2023-10-23 00:27:36 +03:00
Dimitrios Kaitantzidis
3145f5fdd0 Feature ready. 2023-10-23 00:12:13 +03:00
Dimitrios Kaitantzidis
8393dd4731 Deletes unnecessary files 2023-10-22 20:54:23 +03:00
Dimitrios Kaitantzidis
768877d969 Reader works correctly 2023-10-22 20:32:19 +03:00
Dimitrios Kaitantzidis
14a90f5e50 WIP: No errors but nothing is working 2023-10-22 20:16:59 +03:00
Dimitrios Kaitantzidis
99b0150e7a WIP: Adds Drap and drop 2023-10-21 11:26:58 +03:00
Anthony Stirling
3be12c8988 Merge pull request #424 from DimK10/Bug-Multitool-Filename
Bug multitool filename
2023-10-15 17:37:46 +01:00
Dimitrios Kaitantzidis
89345c8d60 Removes commas in multiple dots with text. 2023-10-15 19:10:30 +03:00
Dimitrios Kaitantzidis
49f1f4e7c7 Fixes bug with unfinished filename extension (multiple dots problem) 2023-10-15 19:03:10 +03:00
Dimitrios Kaitantzidis
d0ce7db9ee Fixes bug with unfinished filename extension (file.p) 2023-10-15 18:35:39 +03:00
Dimitrios Kaitantzidis
53a0291cc2 Adds requested changes 2023-10-15 16:49:12 +03:00
Dimitrios Kaitantzidis
9a3bc839dd Merge remote-tracking branch 'origin/Bug-Multitool-Filename' into Bug-Multitool-Filename 2023-10-14 00:38:16 +03:00
Dimitrios Kaitantzidis
e519840bd6 Fixes issue with light theme support. 2023-10-14 00:37:52 +03:00
Dimitris Kaitantzidis
ed32a3ca33 Merge branch 'main' into Bug-Multitool-Filename 2023-10-14 00:06:36 +03:00
Dimitrios Kaitantzidis
369ac99a16 Fixes issue. 2023-10-14 00:03:08 +03:00
Dimitrios Kaitantzidis
74da8c340d Adds support for disabled filename input if not pdf is loaded. Need to disable the input if all pages are deleted. 2023-10-10 20:24:11 +03:00
Dimitrios Kaitantzidis
323745e61f Change in name works. 2023-10-08 19:57:19 +03:00
Dimitrios Kaitantzidis
a1b7aaddb8 Changes filename using js, but the old filename persists in download 2023-10-08 18:59:43 +03:00
pixeebot[bot]
db488b39bb Introduced protections against predictable RNG abuse 2023-10-05 20:29:56 +00:00
513 changed files with 76463 additions and 25933 deletions

1
.gitattributes vendored
View File

@@ -1,5 +1,6 @@
# Ignore all JavaScript files in a directory
src/main/resources/static/pdfjs/* linguist-vendored
src/main/resources/static/pdfjs/** linguist-vendored
src/main/resources/static/css/bootstrap-icons.css linguist-vendored
src/main/resources/static/css/bootstrap.min.css linguist-vendored
src/main/resources/static/css/fonts/* linguist-vendored

2
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,2 @@
# All PRs to V1 must be approved by Frooodle
* @Frooodle

View File

@@ -139,4 +139,10 @@ jobs:
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
- name: Build and Push Helm Chart
run: |
helm package chart/stirling-pdf
helm push stirling-pdf-chart-1.0.0.tgz oci://registry-1.docker.io/frooodle

11
.gitignore vendored
View File

@@ -15,8 +15,8 @@ local.properties
.classpath
.project
version.properties
pipeline/
pipeline/watchedFolders/
pipeline/finishedFolders/
#### Stirling-PDF Files ###
customFiles/
configs/
@@ -119,4 +119,9 @@ watchedFolders/
*.db
/build
/.vscode
/.vscode
/.idea
# Ignore Mac DS_Store files
.DS_Store
**/.DS_Store

View File

@@ -1,12 +1,13 @@
# Use the base image
FROM frooodle/stirling-pdf-base:beta4
FROM frooodle/stirling-pdf-base:version8
ARG VERSION_TAG
# Set Environment Variables
ENV DOCKER_ENABLE_SECURITY=false \
HOME=/home/stirlingpdfuser \
VERSION_TAG=$VERSION_TAG
VERSION_TAG=$VERSION_TAG \
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75"
# PUID=1000 \
# PGID=1000 \
# UMASK=022 \
@@ -18,19 +19,20 @@ ENV DOCKER_ENABLE_SECURITY=false \
## mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME
# Set up necessary directories and permissions
RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /customFiles
RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /logs /customFiles /pipeline /pipeline/defaultWebUIConfigs /pipeline/watchedFolders /pipeline/finishedFolders
##&& \
## chown -R stirlingpdfuser:stirlingpdfgroup /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /customFiles && \
## chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/tesseract-ocr-original
# Copy necessary files
COPY ./scripts/* /scripts/
COPY ./pipeline/ /pipeline/
COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto/
COPY build/libs/*.jar app.jar
# Set font cache and permissions
RUN fc-cache -f -v && chmod +x /scripts/init.sh
RUN fc-cache -f -v && chmod +x /scripts/*
##&& \
## chown stirlingpdfuser:stirlingpdfgroup /app.jar && \
@@ -42,4 +44,4 @@ EXPOSE 8080
# Set user and run command
##USER stirlingpdfuser
ENTRYPOINT ["/scripts/init.sh"]
CMD ["java", "-jar", "/app.jar"]
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]

View File

@@ -1,12 +1,15 @@
# Build jbig2enc in a separate stage
FROM bellsoft/liberica-openjdk-debian:17
ARG VERSION_TAG
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libreoffice-core-nogui \
libreoffice-core \
libreoffice-common \
libreoffice-writer-nogui \
libreoffice-calc-nogui \
libreoffice-impress-nogui \
libreoffice-writer \
libreoffice-calc \
libreoffice-impress \
unoconv && \
rm -rf /var/lib/apt/lists/*
@@ -14,7 +17,8 @@ RUN apt-get update && \
# Set Environment Variables
ENV DOCKER_ENABLE_SECURITY=false \
HOME=/home/stirlingpdfuser \
VERSION_TAG=$VERSION_TAG
VERSION_TAG=$VERSION_TAG \
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75"
# PUID=1000 \
# PGID=1000 \
# UMASK=022 \
@@ -25,17 +29,24 @@ ENV DOCKER_ENABLE_SECURITY=false \
# mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME
# Set up necessary directories and permissions
RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /configs /customFiles
RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /configs /customFiles /logs /pipeline /pipeline/defaultWebUIConfigs /pipeline/watchedFolders /pipeline/finishedFolders
# chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/fonts/opentype/noto /configs /customFiles
# Copy necessary files
COPY ./scripts/download-security-jar.sh /scripts/download-security-jar.sh
COPY ./scripts/init-without-ocr.sh /scripts/init-without-ocr.sh
COPY ./pipeline/ /pipeline/
COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto/
COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto/
COPY build/libs/*.jar app.jar
# Set font cache and permissions
RUN fc-cache -f -v
RUN fc-cache -f -v && \
chmod +x /scripts/init-without-ocr.sh && \
chmod +x /scripts/download-security-jar.sh
# chown stirlingpdfuser:stirlingpdfgroup /app.jar
@@ -50,5 +61,5 @@ ENV DOCKER_ENABLE_SECURITY=false
# Run the application
#USER stirlingpdfuser
CMD ["java", "-jar", "/app.jar"]
ENTRYPOINT ["/scripts/init-without-ocr.sh"]
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]

View File

@@ -1,34 +1,46 @@
# Build jbig2enc in a separate stage
FROM bellsoft/liberica-openjdk-alpine:17
ARG VERSION_TAG
# Set Environment Variables
ENV PUID=1000 \
PGID=1000 \
UMASK=022 \
DOCKER_ENABLE_SECURITY=false \
ENV DOCKER_ENABLE_SECURITY=false \
HOME=/home/stirlingpdfuser \
VERSION_TAG=$VERSION_TAG
VERSION_TAG=$VERSION_TAG \
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75"
# PUID=1000 \
# PGID=1000 \
# UMASK=022 \
# Create user and group using Alpine's addgroup and adduser
RUN addgroup -g $PGID stirlingpdfgroup && \
adduser -u $PUID -G stirlingpdfgroup -s /bin/sh -D stirlingpdfuser && \
mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME
#RUN addgroup -g $PGID stirlingpdfgroup && \
# adduser -u $PUID -G stirlingpdfgroup -s /bin/sh -D stirlingpdfuser && \
# mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME
# Set up necessary directories and permissions
RUN mkdir -p /scripts /configs /customFiles && \
chown -R stirlingpdfuser:stirlingpdfgroup /scripts /configs /customFiles
#RUN mkdir -p /scripts /configs /customFiles && \
# chown -R stirlingpdfuser:stirlingpdfgroup /scripts /configs /customFiles /logs /pipeline /pipeline/defaultWebUIConfigs /pipeline/watchedFolders /pipeline/finishedFolders
RUN mkdir -p /scripts /usr/share/fonts/opentype/noto /configs /customFiles
COPY ./scripts/download-security-jar.sh /scripts/download-security-jar.sh
COPY ./scripts/init-without-ocr.sh /scripts/init-without-ocr.sh
COPY ./pipeline/ /pipeline/
COPY build/libs/*.jar app.jar
# Set font cache and permissions
RUN chown stirlingpdfuser:stirlingpdfgroup /app.jar
#RUN chown stirlingpdfuser:stirlingpdfgroup /app.jar
RUN chmod +x /scripts/init-without-ocr.sh && \
chmod +x /scripts/download-security-jar.sh && \
apk add --no-cache curl
# Expose the application port
EXPOSE 8080
# Set environment variables
ENV ENDPOINTS_GROUPS_TO_REMOVE=CLI
ENV DOCKER_ENABLE_SECURITY=false
ENTRYPOINT ["/scripts/init-without-ocr.sh"]
# Run the application
CMD ["java", "-jar", "/app.jar"]
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]

View File

@@ -1,37 +1,50 @@
# Main stage
FROM bellsoft/liberica-openjdk-debian:17 AS base
FROM ubuntu:latest AS base
# JDK for app
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libreoffice-core-nogui \
openjdk-17-jre
# Doc conversion
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libreoffice-core \
libreoffice-common \
libreoffice-writer-nogui \
libreoffice-calc-nogui \
libreoffice-impress-nogui \
python3-uno \
libreoffice-writer \
libreoffice-calc \
libreoffice-impress \
python3-uno \
curl \
unoconv
# OCR MY PDF (unpaper for descew and other advanced featues)
RUN apt-get update && apt-get install -y --no-install-recommends software-properties-common gnupg2 && \
add-apt-repository ppa:alex-p/tesseract-ocr5 && apt install -y --no-install-recommends tesseract-ocr && \
apt-get update && \
apt-get install -y --no-install-recommends \
ghostscript \
python3-pip \
unoconv \
pngquant \
unpaper \
ocrmypdf && \
rm -rf /var/lib/apt/lists/* && \
ocrmypdf \
unpaper && \
pip install --upgrade pip && \
pip install --no-cache-dir --upgrade ocrmypdf && \
pip install --no-cache-dir --upgrade pillow==10.0.1 reportlab==3.6.13 wheel==0.38.1 setuptools==65.5.1 pyjwt==2.4.0 cryptography==39.0.1
#CV and HTML
RUN pip install --no-cache-dir opencv-python-headless WeasyPrint
# cleanup and etc
RUN rm -rf /var/lib/apt/lists/* && \
mkdir /usr/share/tesseract-ocr-original && \
cp -r /usr/share/tesseract-ocr/* /usr/share/tesseract-ocr-original && \
rm -rf /usr/share/tesseract-ocr
# Python packages stage
FROM base AS python-packages
RUN apt-get update && \
apt-get install -y --no-install-recommends \
build-essential \
libffi-dev \
libssl-dev \
zlib1g-dev \
libjpeg-dev && \
pip install --upgrade pip && \
pip install --no-cache-dir \
opencv-python-headless WeasyPrint && \
rm -rf /var/lib/apt/lists/*
# Final stage: Copy necessary files from the previous stage
FROM base
COPY --from=python-packages /usr/local /usr/local

View File

@@ -2,6 +2,9 @@
This document provides instructions on how to add additional language packs for the OCR tab in Stirling-PDF, both inside and outside of Docker.
## My OCR used to work and now doesnt!
Please update your tesseract docker volume path version from 4.00 to 5
## How does the OCR Work
Stirling-PDF uses [OCRmyPDF](https://github.com/ocrmypdf/OCRmyPDF) which in turn uses tesseract for its text recognition.
All credit goes to them for this awesome work!
@@ -18,9 +21,9 @@ Depending on your requirements, you can choose the appropriate language pack for
### Installing Language Packs
1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need.
2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tesseract-ocr/4.00/tessdata` (Debian) or `/usr/share/tesseract/tessdata` (Fedora)
2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tesseract-ocr/5/tessdata` (Debian) or `/usr/share/tesseract/tessdata` (Fedora)
# DO NOT REMOVE EXISTING ENG.TRAINEDDATA, ITS REQUIRED.
# DO NOT REMOVE EXISTING ENG.TRAINEDDATA, IT'S REQUIRED.
#### Docker
@@ -34,14 +37,14 @@ services:
your_service_name:
image: your_docker_image_name
volumes:
- /location/of/trainingData:/usr/share/tesseract-ocr/4.00/tessdata
- /location/of/trainingData:/usr/share/tesseract-ocr/5/tessdata
```
#### Docker run
Add the following to your existing docker run command
```bash
-v /location/of/trainingData:/usr/share/tesseract-ocr/4.00/tessdata
-v /location/of/trainingData:/usr/share/tesseract-ocr/5/tessdata
```
#### Non-Docker

20
Jenkinsfile vendored
View File

@@ -22,12 +22,24 @@ pipeline {
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
def image = "frooodle/s-pdf:$appVersion"
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
sh "docker push $image"
}
}
}
}
}
}
stage('Helm Push') {
steps {
script {
//TODO: Read chartVersion from Chart.yaml
def chartVersion = '1.0.0'
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
sh "helm package chart/stirling-pdf"
sh "helm push stirling-pdf-chart-1.0.0.tgz oci://registry-1.docker.io/frooodle"
}
}
}
}
}
}

View File

@@ -1,5 +1,5 @@
To run the application without Docker, you will need to manually install all dependencies and build the necessary components.
To run the application without Docker/Podman, you will need to manually install all dependencies and build the necessary components.
Note that some dependencies might not be available in the standard repositories of all Linux distributions, and may require additional steps to install.
@@ -8,6 +8,8 @@ The following guide assumes you have a basic understanding of using a command li
It should work on most Linux distributions and MacOS. For Windows, you might need to use Windows Subsystem for Linux (WSL) for certain steps.
The amount of dependencies is to actually reduce overall size, ie installing LibreOffice sub components rather than full LibreOffice package.
You could theoretically use a Distrobox/Toolbox, if your Distribution has old or not all Packages. But you might just as well use the Docker Container then.
### Step 1: Prerequisites
Install the following software, if not already installed:
@@ -18,7 +20,7 @@ Install the following software, if not already installed:
- Git
- Python 3 (with pip)
- Python 3.8 (with pip)
- Make
@@ -93,14 +95,14 @@ For Debian-based systems, you can use the following command:
```bash
sudo apt-get install -y libreoffice-writer libreoffice-calc libreoffice-impress unpaper ocrmypdf
pip3 install uno opencv-python-headless unoconv pngquant
pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
```
For Fedora:
```bash
sudo dnf install -y libreoffice-writer libreoffice-calc libreoffice-impress unpaper ocrmypdf
pip3 install uno opencv-python-headless unoconv pngquant
pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
```
### Step 4: Clone and Build Stirling-PDF
@@ -137,7 +139,7 @@ Easiest is to use the langpacks provided by your repositories. Skip the other st
Manual:
1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need.
2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tesseract-ocr/4.00/tessdata`
2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tesseract-ocr/5/tessdata`
3.
Please view [OCRmyPDF install guide](https://ocrmypdf.readthedocs.io/en/latest/installation.html) for more info.
**IMPORTANT:** DO NOT REMOVE EXISTING `eng.traineddata`, IT'S REQUIRED.
@@ -174,7 +176,7 @@ rpm -qa | grep tesseract-langpack | sed 's/tesseract-langpack-//g'
```bash
./gradlew bootRun
or
java -jar build/libs/app.jar
java -jar /opt/Stirling-PDF/Stirling-PDF-*.jar
```
### Step 8: Adding a Desktop icon
@@ -200,6 +202,64 @@ EOF
Note: Currently the app will run in the background until manually closed.
### Optional: Run Stirling-PDF as a service
First create a .env file, where you can store environment variables:
```
touch /opt/Stirling-PDF/.env
```
In this file you can add all variables, one variable per line, as stated in the main readme (for example SYSTEM_DEFAULTLOCALE="de-DE").
Create a new file where we store our service settings and open it with nano editor:
```
nano /etc/systemd/system/stirlingpdf.service
```
Paste this content, make sure to update the filename of the jar-file. Press Ctrl+S and Ctrl+X to save and exit the nano editor:
```
[Unit]
Description=Stirling-PDF service
After=syslog.target network.target
[Service]
SuccessExitStatus=143
User=root
Group=root
Type=simple
EnvironmentFile=/opt/Stirling-PDF/.env
WorkingDirectory=/opt/Stirling-PDF
ExecStart=/usr/bin/java -jar Stirling-PDF-0.17.2.jar
ExecStop=/bin/kill -15 $MAINPID
[Install]
WantedBy=multi-user.target
```
Notify systemd that it has to rebuild its internal service database (you have to run this command every time you make a change in the service file):
```
sudo systemctl daemon-reload
```
Enable the service to tell the service to start it automatically:
```
sudo systemctl enable stirlingpdf.service
```
See the status of the service:
```
sudo systemctl status stirlingpdf.service
```
Manually start/stop/restart the service:
```
sudo systemctl start stirlingpdf.service
sudo systemctl stop stirlingpdf.service
sudo systemctl restart stirlingpdf.service
```
---
Remember to set the necessary environment variables before running the project if you want to customize the application the list can be seen in the main readme.

View File

@@ -14,10 +14,9 @@ This is a powerful locally hosted web based PDF manipulation tool using docker t
Stirling PDF makes no outbound calls for any record keeping or tracking.
All files and PDFs are either purely client side, in server memory only during the execution of the task or within a temporay file only for execution of the task.
Any file which has been downloaded by the user will have already been deleted from the server by that time.
All files and PDFs exist either exclusively on the client side, reside in server memory only during task execution, or temporarily reside in a file solely for the execution of the task. Any file downloaded by the user will have been deleted from the server by that point.
Feel free to request any features or bug fixes either in github issues or our [Discord](https://discord.gg/Cn8pWhQRxZ)
Please feel free to submit feature requests or report bugs either through GitHub issues or on our [Discord](https://discord.gg/Cn8pWhQRxZ)
![stirling-home](images/stirling-home.png)
@@ -32,6 +31,7 @@ Feel free to request any features or bug fixes either in github issues or our [D
## **PDF Features**
### **Page Operations**
- View and modify PDFs - View multi page PDFs with custom viewing sorting and searching. Plus on page edit features like annotate, draw and adding text and images. (Using PDF.js with Joxit and Liberation.Liberation fonts)
- Full interactive GUI for merging/splitting/rotating/moving PDFs and their pages.
- Merge multiple PDFs together into a single resultant file.
- Split PDFs into multiple files at specified page numbers or extract all pages as individual files.
@@ -80,7 +80,7 @@ Feel free to request any features or bug fixes either in github issues or our [D
- Get all information on a PDF to view or export as JSON.
For a overview of the tasks and the technology each uses please view [groups.md](https://github.com/Frooodle/Stirling-PDF/blob/main/Groups.md)
For a overview of the tasks and the technology each uses please view [Endpoint-groups.md](https://github.com/Frooodle/Stirling-PDF/blob/main/Endpoint-groups.md)
Hosted instance/demo of the app can be seen [here](https://pdf.adminforge.de/) hosted by the team at adminforge.de
## Technologies used
@@ -98,7 +98,7 @@ Hosted instance/demo of the app can be seen [here](https://pdf.adminforge.de/) h
### Locally
Please view https://github.com/Frooodle/Stirling-PDF/blob/main/LocalRunGuide.md
### Docker
### Docker / Podman
https://hub.docker.com/r/frooodle/s-pdf
Stirling PDF has 3 different versions, a Full version, Lite, and ultra-Lite. Depending on the types of features you use you may want a smaller image to save on space.
@@ -112,8 +112,9 @@ Docker Run
```
docker run -d \
-p 8080:8080 \
-v /location/of/trainingData:/usr/share/tesseract-ocr/4.00/tessdata \
-v /location/of/trainingData:/usr/share/tesseract-ocr/5/tessdata \
-v /location/of/extraConfigs:/configs \
-v /location/of/logs:/logs \
-e DOCKER_ENABLE_SECURITY=false \
--name stirling-pdf \
frooodle/s-pdf:latest
@@ -132,19 +133,21 @@ services:
ports:
- '8080:8080'
volumes:
- /location/of/trainingData:/usr/share/tesseract-ocr/4.00/tessdata #Required for extra OCR languages
- /location/of/trainingData:/usr/share/tesseract-ocr/5/tessdata #Required for extra OCR languages
- /location/of/extraConfigs:/configs
# - /location/of/customFiles:/customFiles/
# - /location/of/logs:/logs/
environment:
- DOCKER_ENABLE_SECURITY=false
```
Note: Podman is CLI-compatible with Docker, so simply replace "docker" with "podman".
## Enable OCR/Compression feature
Please view https://github.com/Frooodle/Stirling-PDF/blob/main/HowToUseOCR.md
## Want to add your own language?
Stirling PDF currently supports 18!
Stirling PDF currently supports 21!
- English (English) (en_GB)
- English (US) (en_US)
- Arabic (العربية) (ar_AR)
@@ -163,6 +166,10 @@ Stirling PDF currently supports 18!
- Basque (Euskara) (eu_ES)
- Japanese (日本語) (ja_JP)
- Dutch (Nederlands) (nl_NL)
- Greek (el_GR)
- Turkish (Türkçe) (tr_TR)
- Indonesia (Bahasa Indonesia) (id_ID)
- Hindi (हिंदी) (hi_IN)
If you want to add your own language to Stirling-PDF please refer
https://github.com/Frooodle/Stirling-PDF/blob/main/HowToAddNewLanguage.md
@@ -217,7 +224,7 @@ metrics:
enabled: true # 'true' to enable Info APIs endpoints (view http://localhost:8080/swagger-ui/index.html#/API to learn more), 'false' to disable
```
### Extra notes
- Endpoints. Currently, the endpoints ENDPOINTS_TO_REMOVE and GROUPS_TO_REMOVE can include comma separate lists of endpoints and groups to disable as example ENDPOINTS_TO_REMOVE=img-to-pdf,remove-pages would disable both image-to-pdf and remove pages, GROUPS_TO_REMOVE=LibreOffice Would disable all things that use LibreOffice. You can see a list of all endpoints and groups [here](https://github.com/Frooodle/Stirling-PDF/blob/main/groups.md)
- Endpoints. Currently, the endpoints ENDPOINTS_TO_REMOVE and GROUPS_TO_REMOVE can include comma separate lists of endpoints and groups to disable as example ENDPOINTS_TO_REMOVE=img-to-pdf,remove-pages would disable both image-to-pdf and remove pages, GROUPS_TO_REMOVE=LibreOffice Would disable all things that use LibreOffice. You can see a list of all endpoints and groups [here](https://github.com/Frooodle/Stirling-PDF/blob/main/Endpoint-groups.md)
- customStaticFilePath. Customise static files such as the app logo by placing files in the /customFiles/static/ directory. An example of customising app logo is placing a /customFiles/static/favicon.svg to override current SVG. This can be used to change any images/icons/css/fonts/js etc in Stirling-PDF
### Environment only parameters
@@ -257,12 +264,11 @@ For API usage you must provide a header with 'X-API-Key' and the associated API
- Folder support with auto scanning to perform operations on
- Redact text (Via UI not just automated way)
- Add Forms
- Annotations
- Multi page layout (Stich PDF pages together) support x rows y columns and custom page sizing
- Fill forms mannual and automatic
### Q2: Why is my application downloading .htm files?
This is a issue caused commonly by your NGINX congifuration. The default file upload size for NGINX is 1MB, you need to add the following in your Nginx sites-available file. ``client_max_body_size SIZE;`` Where "SIZE" is 50M for example for 50MB files.
This is an issue caused commonly by your NGINX configuration. The default file upload size for NGINX is 1MB, you need to add the following in your Nginx sites-available file. ``client_max_body_size SIZE;`` Where "SIZE" is 50M for example for 50MB files.
### Q3: Why is my download timing out
NGINX has timeout values by default so if you are running Stirling-PDF behind NGINX you may need to set a timeout value such as adding the config ``proxy_read_timeout 3600;``

View File

@@ -19,6 +19,7 @@ add-image | ✔️ | ✔️ | ✔️
add-watermark | ✔️ | ✔️ | ✔️
adjust-contrast | ✔️ | ✔️ | ✔️
auto-split-pdf | ✔️ | ✔️ | ✔️
auto-redact | ✔️ | ✔️ | ✔️
auto-rename | ✔️ | ✔️ | ✔️
cert-sign | ✔️ | ✔️ | ✔️
crop | ✔️ | ✔️ | ✔️
@@ -33,7 +34,9 @@ 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 | ✔️ | ✔️ | ✔️
@@ -43,6 +46,8 @@ sanitize-pdf | ✔️ | ✔️ | ✔️
scale-pages | ✔️ | ✔️ | ✔️
sign | ✔️ | ✔️ | ✔️
show-javascript | ✔️ | ✔️ | ✔️
split-by-size-or-count | ✔️ | ✔️ | ✔️
split-pdf-by-sections | ✔️ | ✔️ | ✔️
split-pdfs | ✔️ | ✔️ | ✔️
file-to-pdf | | ✔️ | ✔️
pdf-to-html | | ✔️ | ✔️

View File

@@ -2,13 +2,13 @@ plugins {
id 'java'
id 'org.springframework.boot' version '3.1.2'
id 'io.spring.dependency-management' version '1.1.3'
id 'org.springdoc.openapi-gradle-plugin' version '1.6.0'
id "io.swagger.swaggerhub" version "1.2.0"
id 'org.springdoc.openapi-gradle-plugin' version '1.8.0'
id "io.swagger.swaggerhub" version "1.3.2"
id 'edu.sc.seis.launch4j' version '3.0.5'
}
group = 'stirling.software'
version = '0.14.5'
version = '0.18.1'
sourceCompatibility = '17'
repositories {
@@ -32,7 +32,6 @@ sourceSets {
}
}
openApi {
apiDocsUrl = "http://localhost:8080/v1/api-docs"
outputDir = file("$projectDir")
@@ -46,15 +45,15 @@ launch4j {
outfile="Stirling-PDF.exe"
headerType="console"
jarTask = tasks.bootJar
errTitle="Encountered error, Do you have Java 17?"
downloadUrl="https://download.oracle.com/java/17/latest/jdk-17_windows-x64_bin.exe"
variables=["BROWSER_OPEN=true"]
downloadUrl="https://download.oracle.com/java/17/latest/jdk-17_windows-x64_bin.exe"
variables=["BROWSER_OPEN=true", "ENDPOINTS_GROUPS_TO_REMOVE=CLI"]
jreMinVersion="17"
mutexName="Stirling-PDF"
windowTitle="Stirling-PDF"
messagesStartupError="An error occurred while starting Stirling-PDF"
//messagesJreNotFoundError="This application requires a Java Runtime Environment, Please download Java 17."
messagesJreVersionError="You are running the wrong version of Java, Please download Java 17."
@@ -63,46 +62,79 @@ launch4j {
}
dependencies {
implementation 'org.yaml:snakeyaml:2.1'
implementation 'org.springframework.boot:spring-boot-starter-web:3.1.2'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.1.2'
//security updates
implementation 'ch.qos.logback:logback-classic:1.4.14'
implementation 'ch.qos.logback:logback-core:1.4.14'
implementation 'org.springframework:spring-webmvc:6.0.15'
if (System.getenv('DOCKER_ENABLE_SECURITY') != 'false') {
implementation 'org.springframework.boot:spring-boot-starter-security:3.1.2'
implementation 'org.yaml:snakeyaml:2.1'
implementation 'org.springframework.boot:spring-boot-starter-web:3.2.1'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.2.1'
if (System.getenv('DOCKER_ENABLE_SECURITY') != 'false') {
implementation 'org.springframework.boot:spring-boot-starter-security:3.2.1'
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE'
implementation "org.springframework.boot:spring-boot-starter-data-jpa"
implementation "com.h2database:h2"
implementation "com.h2database:h2"
}
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.1.4'
// https://mvnrepository.com/artifact/org.apache.pdfbox/jbig2-imageio
implementation group: 'org.apache.pdfbox', name: 'jbig2-imageio', version: '3.0.4'
implementation 'commons-io:commons-io:2.13.0'
testImplementation 'org.springframework.boot:spring-boot-starter-test:3.2.1'
// Batik
implementation 'org.apache.xmlgraphics:batik-all:1.17'
// TwelveMonkeys
implementation 'com.twelvemonkeys.imageio:imageio-batik:3.10.1'
implementation 'com.twelvemonkeys.imageio:imageio-bmp:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-hdr:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-icns:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-iff:3.10.1'
implementation 'com.twelvemonkeys.imageio:imageio-jpeg:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-pcx:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-pict:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-pnm:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-psd:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-sgi:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-tga:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-thumbsdb:3.10.1'
implementation 'com.twelvemonkeys.imageio:imageio-tiff:3.10.1'
implementation 'com.twelvemonkeys.imageio:imageio-webp:3.10.1'
// implementation 'com.twelvemonkeys.imageio:imageio-xwd:3.10.1'
implementation 'commons-io:commons-io:2.15.1'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'
//general PDF
// https://mvnrepository.com/artifact/com.opencsv/opencsv
implementation ('com.opencsv:opencsv:5.7.1') {
exclude group: 'commons-logging', module: 'commons-logging'
}
//general PDF
implementation 'org.apache.pdfbox:pdfbox:2.0.29'
implementation 'org.apache.pdfbox:xmpbox:2.0.29'
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'
implementation ('org.apache.pdfbox:pdfbox:2.0.29'){
exclude group: 'commons-logging', module: 'commons-logging'
}
implementation ('org.apache.pdfbox:xmpbox:2.0.29'){
exclude group: 'commons-logging', module: 'commons-logging'
}
implementation 'org.bouncycastle:bcprov-jdk18on:1.77'
implementation 'org.bouncycastle:bcpkix-jdk18on:1.77'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-core'
implementation group: 'com.google.zxing', name: 'core', version: '3.5.2'
// https://mvnrepository.com/artifact/org.commonmark/commonmark
implementation 'org.commonmark:commonmark:0.21.0'
implementation 'org.commonmark:commonmark:0.21.0'
// https://mvnrepository.com/artifact/com.github.vladimir-bukhtoyarov/bucket4j-core
implementation 'com.github.vladimir-bukhtoyarov:bucket4j-core:7.6.0'
developmentOnly("org.springframework.boot:spring-boot-devtools")
compileOnly 'org.projectlombok:lombok:1.18.28'
annotationProcessor 'org.projectlombok:lombok:1.18.28'
implementation 'com.github.vladimir-bukhtoyarov:bucket4j-core:7.6.0'
developmentOnly("org.springframework.boot:spring-boot-devtools")
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.28'
}
task writeVersion {
def propsFile = file('src/main/resources/version.properties')
def props = new Properties()
@@ -128,7 +160,7 @@ jar {
attributes 'Implementation-Title': 'Stirling-PDF',
'Implementation-Version': project.version
}
}
tasks.named('test') {

View File

@@ -9,7 +9,7 @@ keywords:
maintainers:
- name: Frooodle
url: https://github.com/Frooodle/Stirling-PDF
name: stirling-pdf
name: stirling-pdf-chart
sources:
- https://github.com/Frooodle/Stirling-PDF
version: 1.0.0

View File

@@ -0,0 +1,39 @@
{
"name": "Prepare-pdfs-for-email",
"pipeline": [
{
"operation": "/api/v1/misc/repair",
"parameters": {}
},
{
"operation": "/api/v1/security/sanitize-pdf",
"parameters": {
"removeJavaScript": true,
"removeEmbeddedFiles": false,
"removeMetadata": false,
"removeLinks": false,
"removeFonts": false
}
},
{
"operation": "/api/v1/misc/compress-pdf",
"parameters": {
"optimizeLevel": 2,
"expectedOutputSize": ""
}
},
{
"operation": "/api/v1/general/split-by-size-or-count",
"parameters": {
"splitType": 0,
"splitValue": "15MB"
}
}
],
"_examples": {
"outputDir": "{outputFolder}/{folderName}",
"outputFileName": "{filename}-{pipelineName}-{date}-{time}"
},
"outputDir": "httpWebRequest",
"outputFileName": "{filename}"
}

View File

@@ -0,0 +1,33 @@
{
"name": "split-rotate-auto-rename",
"pipeline": [
{
"operation": "/api/v1/general/split-pdf-by-sections",
"parameters": {
"horizontalDivisions": 2,
"verticalDivisions": 2,
"fileInput": "automated"
}
},
{
"operation": "/api/v1/general/rotate-pdf",
"parameters": {
"angle": 90,
"fileInput": "automated"
}
},
{
"operation": "/api/v1/misc/auto-rename",
"parameters": {
"useFirstTextAsFallback": false,
"fileInput": "automated"
}
}
],
"_examples": {
"outputDir": "{outputFolder}/{folderName}",
"outputFileName": "{filename}-{pipelineName}-{date}-{time}"
},
"outputDir": "{outputFolder}",
"outputFileName": "{filename}"
}

View File

@@ -1,10 +1,11 @@
import cv2
import sys
import argparse
import numpy as np
def is_blank_image(image_path, threshold=10, white_percent=99, white_value=255, blur_size=5):
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if image is None:
print(f"Error: Unable to read the image file: {image_path}")
return False
@@ -15,19 +16,11 @@ def is_blank_image(image_path, threshold=10, white_percent=99, white_value=255,
_, thresholded_image = cv2.threshold(blurred_image, white_value - threshold, white_value, cv2.THRESH_BINARY)
# Calculate the percentage of white pixels in the thresholded image
white_pixels = 0
total_pixels = thresholded_image.size
for i in range(0, thresholded_image.shape[0], 2):
for j in range(0, thresholded_image.shape[1], 2):
if thresholded_image[i, j] == white_value:
white_pixels += 1
white_pixel_percentage = (white_pixels / (i * thresholded_image.shape[1] + j + 1)) * 100
if white_pixel_percentage < white_percent:
return False
white_pixels = np.sum(thresholded_image == white_value)
white_pixel_percentage = (white_pixels / thresholded_image.size) * 100
print(f"Page has white pixel percent of {white_pixel_percentage}")
return True
return white_pixel_percentage >= white_percent
if __name__ == "__main__":
@@ -39,9 +32,6 @@ if __name__ == "__main__":
blank = is_blank_image(args.image_path, args.threshold, args.white_percent)
if blank:
# Return code 1: The image is considered blank.
sys.exit(1)
else:
# Return code 0: The image is not considered blank.
sys.exit(0)
# Return code 1: The image is considered blank.
# Return code 0: The image is not considered blank.
sys.exit(int(blank))

View File

@@ -0,0 +1,19 @@
echo "Running Stirling PDF with DOCKER_ENABLE_SECURITY=${DOCKER_ENABLE_SECURITY} and VERSION_TAG=${VERSION_TAG}"
# Check for DOCKER_ENABLE_SECURITY and download the appropriate JAR if required
if [ "$DOCKER_ENABLE_SECURITY" = "true" ] && [ "$VERSION_TAG" != "alpha" ]; then
if [ ! -f app-security.jar ]; then
echo "Trying to download from: https://github.com/Frooodle/Stirling-PDF/releases/download/v$VERSION_TAG/Stirling-PDF-with-login.jar"
curl -L -o app-security.jar https://github.com/Frooodle/Stirling-PDF/releases/download/v$VERSION_TAG/Stirling-PDF-with-login.jar
# If the first download attempt failed, try with the 'v' prefix
if [ $? -ne 0 ]; then
echo "Trying to download from: https://github.com/Frooodle/Stirling-PDF/releases/download/$VERSION_TAG/Stirling-PDF-with-login.jar"
curl -L -o app-security.jar https://github.com/Frooodle/Stirling-PDF/releases/download/$VERSION_TAG/Stirling-PDF-with-login.jar
fi
if [ $? -eq 0 ]; then # checks if curl was successful
rm -f app.jar
ln -s app-security.jar app.jar
fi
fi
fi

View File

@@ -0,0 +1,6 @@
#!/bin/sh
/scripts/download-security-jar.sh
# Run the main command
exec "$@"

View File

@@ -3,7 +3,11 @@
# Copy the original tesseract-ocr files to the volume directory without overwriting existing files
echo "Copying original files without overwriting existing files"
mkdir -p /usr/share/tesseract-ocr
cp -rn /usr/share/tesseract-ocr-original/* /usr/share/tesseract-ocr
cp -rn /usr/share/tesseract-ocr-original/* /usr/share/tesseract-ocr
if [ -d /usr/share/tesseract-ocr/4.00/tessdata ]; then
cp -r /usr/share/tesseract-ocr/4.00/tessdata/* /usr/share/tesseract-ocr/5/tessdata/ || true;
fi
# Check if TESSERACT_LANGS environment variable is set and is not empty
if [[ -n "$TESSERACT_LANGS" ]]; then
@@ -16,25 +20,7 @@ if [[ -n "$TESSERACT_LANGS" ]]; then
done
fi
# Check for DOCKER_ENABLE_SECURITY and download the appropriate JAR if required
if [ "$DOCKER_ENABLE_SECURITY" = "true" ] && [ "$VERSION_TAG" != "alpha" ]; then
if [ ! -f app-security.jar ]; then
echo "Trying to download from: https://github.com/Frooodle/Stirling-PDF/releases/download/v$VERSION_TAG/Stirling-PDF-with-login.jar"
curl -L -o app-security.jar https://github.com/Frooodle/Stirling-PDF/releases/download/v$VERSION_TAG/Stirling-PDF-with-login.jar
# If the first download attempt failed, try with the 'v' prefix
if [ $? -ne 0 ]; then
echo "Trying to download from: https://github.com/Frooodle/Stirling-PDF/releases/download/$VERSION_TAG/Stirling-PDF-with-login.jar"
curl -L -o app-security.jar https://github.com/Frooodle/Stirling-PDF/releases/download/$VERSION_TAG/Stirling-PDF-with-login.jar
fi
if [ $? -eq 0 ]; then # checks if curl was successful
rm -f app.jar
ln -s app-security.jar app.jar
fi
fi
fi
/scripts/download-security-jar.sh
# Run the main command
exec "$@"

View File

@@ -8,15 +8,16 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableScheduling;
import jakarta.annotation.PostConstruct;
import stirling.software.SPDF.config.ConfigInitializer;
import stirling.software.SPDF.utils.GeneralUtils;
@SpringBootApplication
//@EnableScheduling
@EnableScheduling
public class SPdfApplication {
@Autowired
private Environment env;
@@ -28,11 +29,7 @@ public class SPdfApplication {
if (browserOpen) {
try {
String port = env.getProperty("local.server.port");
if(port == null || port.length() == 0) {
port="8080";
}
String url = "http://localhost:" + port;
String url = "http://localhost:" + getPort();
String os = System.getProperty("os.name").toLowerCase();
Runtime rt = Runtime.getRuntime();
@@ -45,7 +42,7 @@ public class SPdfApplication {
}
}
}
public static void main(String[] args) {
SpringApplication app = new SpringApplication(SPdfApplication.class);
app.addInitializers(new ConfigInitializer());
@@ -55,28 +52,28 @@ public class SPdfApplication {
System.out.println("External configuration file 'configs/settings.yml' does not exist. Using default configuration and environment configuration instead.");
}
app.run(args);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
GeneralUtils.createDir("customFiles/static/");
GeneralUtils.createDir("customFiles/templates/");
System.out.println("Stirling-PDF Started.");
String port = System.getProperty("local.server.port");
if(port == null || port.length() == 0) {
port="8080";
}
String url = "http://localhost:" + port;
String url = "http://localhost:" + getPort();
System.out.println("Navigate to " + url);
}
}
public static String getPort() {
String port = System.getProperty("local.server.port");
if (port == null || port.isEmpty()) {
port = "8080";
}
return port;
}
}

View File

@@ -1,6 +1,5 @@
package stirling.software.SPDF.config;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -42,12 +41,16 @@ public class AppConfig {
return (defaultNavBar != null) ? defaultNavBar : "Stirling PDF";
}
@Bean(name = "enableAlphaFunctionality")
public boolean enableAlphaFunctionality() {
return applicationProperties.getSystem().getEnableAlphaFunctionality() != null ? applicationProperties.getSystem().getEnableAlphaFunctionality() : false;
}
@Bean(name = "rateLimit")
public boolean rateLimit() {
String appName = System.getProperty("rateLimit");
if (appName == null)
appName = System.getenv("rateLimit");
System.out.println("rateLimit=" + appName);
return (appName != null) ? Boolean.valueOf(appName) : false;
}

View File

@@ -81,6 +81,10 @@ public class EndpointConfiguration {
addEndpointToGroup("PageOps", "auto-split-pdf");
addEndpointToGroup("PageOps", "extract-page");
addEndpointToGroup("PageOps", "pdf-to-single-page");
addEndpointToGroup("PageOps", "split-by-size-or-count");
addEndpointToGroup("PageOps", "overlay-pdf");
addEndpointToGroup("PageOps", "split-pdf-by-sections");
// Adding endpoints to "Convert" group
addEndpointToGroup("Convert", "pdf-to-img");
@@ -96,6 +100,8 @@ public class EndpointConfiguration {
addEndpointToGroup("Convert", "html-to-pdf");
addEndpointToGroup("Convert", "url-to-pdf");
addEndpointToGroup("Convert", "markdown-to-pdf");
addEndpointToGroup("Convert", "pdf-to-csv");
// Adding endpoints to "Security" group
addEndpointToGroup("Security", "add-password");
@@ -104,6 +110,7 @@ public class EndpointConfiguration {
addEndpointToGroup("Security", "add-watermark");
addEndpointToGroup("Security", "cert-sign");
addEndpointToGroup("Security", "sanitize-pdf");
addEndpointToGroup("Security", "auto-redact");
// Adding endpoints to "Other" group
@@ -117,6 +124,7 @@ public class EndpointConfiguration {
addEndpointToGroup("Other", "flatten");
addEndpointToGroup("Other", "repair");
addEndpointToGroup("Other", "remove-blanks");
addEndpointToGroup("Other", "remove-annotations");
addEndpointToGroup("Other", "compare");
addEndpointToGroup("Other", "add-page-numbers");
addEndpointToGroup("Other", "auto-rename");
@@ -197,6 +205,11 @@ public class EndpointConfiguration {
addEndpointToGroup("Java", "pdf-to-single-page");
addEndpointToGroup("Java", "markdown-to-pdf");
addEndpointToGroup("Java", "show-javascript");
addEndpointToGroup("Java", "auto-redact");
addEndpointToGroup("Java", "pdf-to-csv");
addEndpointToGroup("Java", "split-by-size-or-count");
addEndpointToGroup("Java", "overlay-pdf");
addEndpointToGroup("Java", "split-pdf-by-sections");
//Javascript
addEndpointToGroup("Javascript", "pdf-organizer");

View File

@@ -16,33 +16,35 @@ import jakarta.servlet.http.HttpServletResponse;
@Component
public class MetricsFilter extends OncePerRequestFilter {
private final MeterRegistry meterRegistry;
private final MeterRegistry meterRegistry;
@Autowired
public MetricsFilter(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@Autowired
public MetricsFilter(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String uri = request.getRequestURI();
//System.out.println("uri="+uri + ", method=" + request.getMethod() );
// Ignore static resources
if (!(uri.startsWith("/js") || uri.startsWith("api-docs") || uri.endsWith("robots.txt") || uri.startsWith("/images") || uri.endsWith(".png") || uri.endsWith(".ico") || uri.endsWith(".css") || uri.endsWith(".svg")|| uri.endsWith(".js") || uri.contains("swagger") || uri.startsWith("/api"))) {
Counter counter = Counter.builder("http.requests")
.tag("uri", uri)
.tag("method", request.getMethod())
.register(meterRegistry);
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String uri = request.getRequestURI();
counter.increment();
//System.out.println("Counted");
}
// System.out.println("uri="+uri + ", method=" + request.getMethod() );
// Ignore static resources
if (!(uri.startsWith("/js") || uri.startsWith("/v1/api-docs") || uri.endsWith("robots.txt")
|| uri.startsWith("/images") || uri.startsWith("/images")|| uri.endsWith(".png") || uri.endsWith(".ico") || uri.endsWith(".css") || uri.endsWith(".map")
|| uri.endsWith(".svg") || uri.endsWith(".js") || uri.contains("swagger")
|| uri.startsWith("/api/v1/info") || uri.startsWith("/site.webmanifest") || uri.startsWith("/fonts") || uri.startsWith("/pdfjs") )) {
Counter counter = Counter.builder("http.requests").tag("uri", uri).tag("method", request.getMethod())
.register(meterRegistry);
filterChain.doFilter(request, response);
}
counter.increment();
// System.out.println("Counted");
}
filterChain.doFilter(request, response);
}
}

View File

@@ -1,27 +1,42 @@
package stirling.software.SPDF.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import stirling.software.SPDF.model.ApplicationProperties;
@Configuration
public class OpenApiConfig {
@Autowired
ApplicationProperties applicationProperties;
@Bean
public OpenAPI customOpenAPI() {
String version = getClass().getPackage().getImplementationVersion();
if (version == null) {
version = "1.0.0"; // default version if all else fails
}
String version = getClass().getPackage().getImplementationVersion();
if (version == null) {
version = "1.0.0"; // default version if all else fails
}
SecurityScheme apiKeyScheme = new SecurityScheme().type(SecurityScheme.Type.APIKEY).in(SecurityScheme.In.HEADER)
.name("X-API-KEY");
if (!applicationProperties.getSecurity().getEnableLogin()) {
return new OpenAPI().components(new Components())
.info(new Info().title("Stirling PDF API").version(version).description(
"API documentation for all Server-Side processing.\nPlease note some functionality might be UI only and missing from here."));
} else {
return new OpenAPI().components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
.info(new Info().title("Stirling PDF API").version(version).description(
"API documentation for all Server-Side processing.\nPlease note some functionality might be UI only and missing from here."))
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
}
return new OpenAPI().components(new Components()).info(
new Info().title("Stirling PDF API").version(version).description("API documentation for all Server-Side processing.\nPlease note some functionality might be UI only and missing from here."));
}
}
}

View File

@@ -2,25 +2,46 @@ package stirling.software.SPDF.config.security;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@Component
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
@Autowired
private final LoginAttemptService loginAttemptService;
@Autowired
public CustomAuthenticationFailureHandler(LoginAttemptService loginAttemptService) {
this.loginAttemptService = loginAttemptService;
}
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
throws IOException, ServletException {
if (exception.getClass().isAssignableFrom(BadCredentialsException.class)) {
setDefaultFailureUrl("/login?error=badcredentials");
} else if (exception.getClass().isAssignableFrom(LockedException.class)) {
String ip = request.getRemoteAddr();
logger.error("Failed login attempt from IP: " + ip);
String username = request.getParameter("username");
if(loginAttemptService.loginAttemptCheck(username)) {
setDefaultFailureUrl("/login?error=locked");
} else {
if (exception.getClass().isAssignableFrom(BadCredentialsException.class)) {
setDefaultFailureUrl("/login?error=badcredentials");
} else if (exception.getClass().isAssignableFrom(LockedException.class)) {
setDefaultFailureUrl("/login?error=locked");
}
}
super.onAuthenticationFailure(request, response, exception);
}
}

View File

@@ -0,0 +1,44 @@
package stirling.software.SPDF.config.security;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Component;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import stirling.software.SPDF.utils.RequestUriUtils;
@Component
public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
@Autowired
private LoginAttemptService loginAttemptService;
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws ServletException, IOException {
String username = request.getParameter("username");
loginAttemptService.loginSucceeded(username);
// Get the saved request
HttpSession session = request.getSession(false);
SavedRequest savedRequest = session != null ? (SavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST") : null;
if (savedRequest != null && !RequestUriUtils.isStaticResource(savedRequest.getRedirectUrl())) {
// Redirect to the original destination
super.onAuthenticationSuccess(request, response, authentication);
} else {
// Redirect to the root URL (considering context path)
getRedirectStrategy().sendRedirect(request, response, "/");
}
//super.onAuthenticationSuccess(request, response, authentication);
}
}

View File

@@ -5,6 +5,7 @@ import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
@@ -22,12 +23,18 @@ public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Autowired
private LoginAttemptService loginAttemptService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("No user found with username: " + username));
if (loginAttemptService.isBlocked(username)) {
throw new LockedException("Your account has been locked due to too many failed login attempts.");
}
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),

View File

@@ -15,6 +15,7 @@ import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import stirling.software.SPDF.model.User;
import stirling.software.SPDF.utils.RequestUriUtils;
@Component
public class FirstLoginFilter extends OncePerRequestFilter {
@@ -28,11 +29,7 @@ public class FirstLoginFilter extends OncePerRequestFilter {
String method = request.getMethod();
String requestURI = request.getRequestURI();
// Check if the request is for static resources
boolean isStaticResource = requestURI.startsWith("/css/")
|| requestURI.startsWith("/js/")
|| requestURI.startsWith("/images/")
|| requestURI.startsWith("/public/")
|| requestURI.endsWith(".svg");
boolean isStaticResource = RequestUriUtils.isStaticResource(requestURI);
// If it's a static resource, just continue the filter chain and skip the logic below
if (isStaticResource) {

View File

@@ -0,0 +1,65 @@
package stirling.software.SPDF.config.security;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import stirling.software.SPDF.utils.RequestUriUtils;
public class IPRateLimitingFilter implements Filter {
private final ConcurrentHashMap<String, AtomicInteger> requestCounts = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, AtomicInteger> getCounts = new ConcurrentHashMap<>();
private final int maxRequests;
private final int maxGetRequests;
public IPRateLimitingFilter(int maxRequests, int maxGetRequests) {
this.maxRequests = maxRequests;
this.maxGetRequests = maxGetRequests;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String method = httpRequest.getMethod();
String requestURI = httpRequest.getRequestURI();
// Check if the request is for static resources
boolean isStaticResource = RequestUriUtils.isStaticResource(requestURI);
// If it's a static resource, just continue the filter chain and skip the logic below
if (isStaticResource) {
chain.doFilter(request, response);
return;
}
String clientIp = request.getRemoteAddr();
requestCounts.computeIfAbsent(clientIp, k -> new AtomicInteger(0));
if (!"GET".equalsIgnoreCase(method)) {
if (requestCounts.get(clientIp).incrementAndGet() > maxRequests) {
// Handle limit exceeded (e.g., send error response)
response.getWriter().write("Rate limit exceeded");
return;
}
} else {
if (requestCounts.get(clientIp).incrementAndGet() > maxGetRequests) {
// Handle limit exceeded (e.g., send error response)
response.getWriter().write("GET Rate limit exceeded");
return;
}
}
}
chain.doFilter(request, response);
}
public void resetRequestCounts() {
requestCounts.clear();
getCounts.clear();
}
}

View File

@@ -37,8 +37,10 @@ public class InitialSecuritySetup {
initialPassword = "stirling";
userService.saveUser(initialUsername, initialPassword, Role.ADMIN.getRoleId(), true);
}
}
if(!userService.usernameExists(Role.INTERNAL_API_USER.getRoleId())) {
userService.saveUser(Role.INTERNAL_API_USER.getRoleId(), UUID.randomUUID().toString(), Role.INTERNAL_API_USER.getRoleId());
userService.addApiKeyToUser(Role.INTERNAL_API_USER.getRoleId());
}
}

View File

@@ -0,0 +1,56 @@
package stirling.software.SPDF.config.security;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.annotation.PostConstruct;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.AttemptCounter;
@Service
public class LoginAttemptService {
@Autowired
ApplicationProperties applicationProperties;
private int MAX_ATTEMPTS;
private long ATTEMPT_INCREMENT_TIME;
@PostConstruct
public void init() {
MAX_ATTEMPTS = applicationProperties.getSecurity().getLoginAttemptCount();
ATTEMPT_INCREMENT_TIME = TimeUnit.MINUTES.toMillis(applicationProperties.getSecurity().getLoginResetTimeMinutes());
}
private final ConcurrentHashMap<String, AttemptCounter> attemptsCache = new ConcurrentHashMap<>();
public void loginSucceeded(String key) {
attemptsCache.remove(key);
}
public boolean loginAttemptCheck(String key) {
attemptsCache.compute(key, (k, attemptCounter) -> {
if (attemptCounter == null || attemptCounter.shouldReset(ATTEMPT_INCREMENT_TIME)) {
return new AttemptCounter();
} else {
attemptCounter.increment();
return attemptCounter;
}
});
return attemptsCache.get(key).getAttemptCount() >= MAX_ATTEMPTS;
}
public boolean isBlocked(String key) {
AttemptCounter attemptCounter = attemptsCache.get(key);
if (attemptCounter != null) {
return attemptCounter.getAttemptCount() >= MAX_ATTEMPTS;
}
return false;
}
}

View File

@@ -0,0 +1,18 @@
package stirling.software.SPDF.config.security;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class RateLimitResetScheduler {
private final IPRateLimitingFilter rateLimitingFilter;
public RateLimitResetScheduler(IPRateLimitingFilter rateLimitingFilter) {
this.rateLimitingFilter = rateLimitingFilter;
}
@Scheduled(cron = "0 0 0 * * MON") // At 00:00 every Monday TODO: configurable
public void resetRateLimit() {
rateLimitingFilter.resetRequestCounts();
}
}

View File

@@ -6,7 +6,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
@@ -15,12 +15,13 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.security.web.savedrequest.NullRequestCache;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import stirling.software.SPDF.repository.JPATokenRepositoryImpl;
@Configuration
@EnableWebSecurity()
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableMethodSecurity
public class SecurityConfiguration {
@Autowired
@@ -40,6 +41,11 @@ public class SecurityConfiguration {
@Autowired
private UserAuthenticationFilter userAuthenticationFilter;
@Autowired
private LoginAttemptService loginAttemptService;
@Autowired
private FirstLoginFilter firstLoginFilter;
@@ -51,14 +57,18 @@ public class SecurityConfiguration {
if(loginEnabledValue) {
http.csrf(csrf -> csrf.disable());
http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class);
http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class);
http
.formLogin(formLogin -> formLogin
.loginPage("/login")
.successHandler(new CustomAuthenticationSuccessHandler())
.defaultSuccessUrl("/")
.failureHandler(new CustomAuthenticationFailureHandler())
.failureHandler(new CustomAuthenticationFailureHandler(loginAttemptService))
.permitAll()
)
).requestCache(requestCache -> requestCache
.requestCache(new NullRequestCache())
)
.logout(logout -> logout
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout=true")
@@ -70,8 +80,19 @@ public class SecurityConfiguration {
.tokenValiditySeconds(1209600) // 2 weeks
)
.authorizeHttpRequests(authz -> authz
.requestMatchers(req -> req.getRequestURI().startsWith("/login") || req.getRequestURI().endsWith(".svg") || req.getRequestURI().startsWith("/register") || req.getRequestURI().startsWith("/error") || req.getRequestURI().startsWith("/images/") || req.getRequestURI().startsWith("/public/") || req.getRequestURI().startsWith("/css/") || req.getRequestURI().startsWith("/js/"))
.permitAll()
.requestMatchers(req -> {
String uri = req.getRequestURI();
String contextPath = req.getContextPath();
// Remove the context path from the URI
String trimmedUri = uri.startsWith(contextPath) ? uri.substring(contextPath.length()) : uri;
return trimmedUri.startsWith("/login") || trimmedUri.endsWith(".svg") ||
trimmedUri.startsWith("/register") || trimmedUri.startsWith("/error") ||
trimmedUri.startsWith("/images/") || trimmedUri.startsWith("/public/") ||
trimmedUri.startsWith("/css/") || trimmedUri.startsWith("/js/");
}
).permitAll()
.anyRequest().authenticated()
)
.userDetailsService(userDetailsService)
@@ -84,8 +105,17 @@ public class SecurityConfiguration {
}
return http.build();
}
@Bean
public IPRateLimitingFilter rateLimitingFilter() {
int maxRequestsPerIp = 1000000; // Example limit TODO add config level
return new IPRateLimitingFilter(maxRequestsPerIp, maxRequestsPerIp);
}
@Bean
public DaoAuthenticationProvider authenticationProvider() {

View File

@@ -74,15 +74,17 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
// If we still don't have any authentication, deny the request
if (authentication == null || !authentication.isAuthenticated()) {
String method = request.getMethod();
if ("GET".equalsIgnoreCase(method) && !"/login".equals(requestURI)) {
response.sendRedirect("/login"); // redirect to the login page
String contextPath = request.getContextPath();
if ("GET".equalsIgnoreCase(method) && ! (contextPath + "/login").equals(requestURI)) {
response.sendRedirect(contextPath + "/login"); // redirect to the login page
return;
} else {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.getWriter().write("Authentication required. Please provide a X-API-KEY in request header.\nThis is found in Settings -> Account Settings -> API Key\nAlternativly you can disable authentication if this is unexpected");
return;
}
}
}
filterChain.doFilter(request, response);
}
@@ -90,15 +92,17 @@ public class UserAuthenticationFilter extends OncePerRequestFilter {
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
String uri = request.getRequestURI();
String contextPath = request.getContextPath();
String[] permitAllPatterns = {
"/login",
"/register",
"/error",
"/images/",
"/public/",
"/css/",
"/js/"
contextPath + "/login",
contextPath + "/register",
contextPath + "/error",
contextPath + "/images/",
contextPath + "/public/",
contextPath + "/css/",
contextPath + "/js/",
contextPath + "/pdfjs/",
contextPath + "/site.webmanifest"
};
for (String pattern : permitAllPatterns) {

View File

@@ -16,11 +16,13 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
import stirling.software.SPDF.model.Authority;
import stirling.software.SPDF.model.Role;
import stirling.software.SPDF.model.User;
import stirling.software.SPDF.repository.UserRepository;
@Service
public class UserService {
public class UserService implements UserServiceInterface{
@Autowired
private UserRepository userRepository;
@@ -136,6 +138,11 @@ public class UserService {
public void deleteUser(String username) {
Optional<User> userOpt = userRepository.findByUsername(username);
if (userOpt.isPresent()) {
for (Authority authority : userOpt.get().getAuthorities()) {
if (authority.getAuthority().equals(Role.INTERNAL_API_USER.getRoleId())) {
return;
}
}
userRepository.delete(userOpt.get());
}
}

View File

@@ -1,15 +1,9 @@
package stirling.software.SPDF.controller.api;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.slf4j.Logger;
@@ -20,12 +14,19 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.MergePdfsRequest;
import stirling.software.SPDF.utils.WebResponseUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
@RestController
@RequestMapping("/api/v1/general")
@Tag(name = "General", description = "General APIs")
@@ -34,82 +35,80 @@ public class MergeController {
private static final Logger logger = LoggerFactory.getLogger(MergeController.class);
private PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
PDDocument mergedDoc = new PDDocument();
for (PDDocument doc : documents) {
for (PDPage page : doc.getPages()) {
mergedDoc.addPage(page);
}
}
return mergedDoc;
}
private Comparator<MultipartFile> getSortComparator(String sortType) {
switch (sortType) {
case "byFileName":
return Comparator.comparing(MultipartFile::getOriginalFilename);
case "byDateModified":
return (file1, file2) -> {
try {
BasicFileAttributes attr1 = Files.readAttributes(Paths.get(file1.getOriginalFilename()), BasicFileAttributes.class);
BasicFileAttributes attr2 = Files.readAttributes(Paths.get(file2.getOriginalFilename()), BasicFileAttributes.class);
return attr1.lastModifiedTime().compareTo(attr2.lastModifiedTime());
} catch (IOException e) {
return 0; // If there's an error, treat them as equal
}
};
case "byDateCreated":
return (file1, file2) -> {
try {
BasicFileAttributes attr1 = Files.readAttributes(Paths.get(file1.getOriginalFilename()), BasicFileAttributes.class);
BasicFileAttributes attr2 = Files.readAttributes(Paths.get(file2.getOriginalFilename()), BasicFileAttributes.class);
return attr1.creationTime().compareTo(attr2.creationTime());
} catch (IOException e) {
return 0; // If there's an error, treat them as equal
}
};
case "byPDFTitle":
return (file1, file2) -> {
try (PDDocument doc1 = PDDocument.load(file1.getInputStream());
PDDocument doc2 = PDDocument.load(file2.getInputStream())) {
String title1 = doc1.getDocumentInformation().getTitle();
String title2 = doc2.getDocumentInformation().getTitle();
return title1.compareTo(title2);
} catch (IOException e) {
return 0;
}
};
case "orderProvided":
default:
return (file1, file2) -> 0; // Default is the order provided
}
}
@PostMapping(consumes = "multipart/form-data", value = "/merge-pdfs")
@Operation(summary = "Merge multiple PDF files into one",
description = "This endpoint merges multiple PDF files into a single PDF file. The merged file will contain all pages from the input files in the order they were provided. Input:PDF Output:PDF Type:MISO")
public ResponseEntity<byte[]> mergePdfs(@ModelAttribute MergePdfsRequest form) throws IOException {
MultipartFile[] files = form.getFileInput();
Arrays.sort(files, getSortComparator(form.getSortType()));
List<PDDocument> documents = new ArrayList<>();
for (MultipartFile file : files) {
try (InputStream is = file.getInputStream()) {
documents.add(PDDocument.load(is));
}
}
try (PDDocument mergedDoc = mergeDocuments(documents)) {
ResponseEntity<byte[]> response = WebResponseUtils.pdfDocToWebResponse(mergedDoc, files[0].getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_merged.pdf");
return response;
} finally {
private PDDocument mergeDocuments(List<PDDocument> documents) throws IOException {
PDDocument mergedDoc = new PDDocument();
for (PDDocument doc : documents) {
if (doc != null) {
doc.close();
for (PDPage page : doc.getPages()) {
mergedDoc.addPage(page);
}
}
return mergedDoc;
}
private Comparator<MultipartFile> getSortComparator(String sortType) {
switch (sortType) {
case "byFileName":
return Comparator.comparing(MultipartFile::getOriginalFilename);
case "byDateModified":
return (file1, file2) -> {
try {
BasicFileAttributes attr1 = Files.readAttributes(Paths.get(file1.getOriginalFilename()), BasicFileAttributes.class);
BasicFileAttributes attr2 = Files.readAttributes(Paths.get(file2.getOriginalFilename()), BasicFileAttributes.class);
return attr1.lastModifiedTime().compareTo(attr2.lastModifiedTime());
} catch (IOException e) {
return 0; // If there's an error, treat them as equal
}
};
case "byDateCreated":
return (file1, file2) -> {
try {
BasicFileAttributes attr1 = Files.readAttributes(Paths.get(file1.getOriginalFilename()), BasicFileAttributes.class);
BasicFileAttributes attr2 = Files.readAttributes(Paths.get(file2.getOriginalFilename()), BasicFileAttributes.class);
return attr1.creationTime().compareTo(attr2.creationTime());
} catch (IOException e) {
return 0; // If there's an error, treat them as equal
}
};
case "byPDFTitle":
return (file1, file2) -> {
try (PDDocument doc1 = PDDocument.load(file1.getInputStream());
PDDocument doc2 = PDDocument.load(file2.getInputStream())) {
String title1 = doc1.getDocumentInformation().getTitle();
String title2 = doc2.getDocumentInformation().getTitle();
return title1.compareTo(title2);
} catch (IOException e) {
return 0;
}
};
case "orderProvided":
default:
return (file1, file2) -> 0; // Default is the order provided
}
}
@PostMapping(consumes = "multipart/form-data", value = "/merge-pdfs")
@Operation(summary = "Merge multiple PDF files into one",
description = "This endpoint merges multiple PDF files into a single PDF file. The merged file will contain all pages from the input files in the order they were provided. Input:PDF Output:PDF Type:MISO")
public ResponseEntity<byte[]> mergePdfs(@ModelAttribute MergePdfsRequest form) throws IOException {
try {
MultipartFile[] files = form.getFileInput();
Arrays.sort(files, getSortComparator(form.getSortType()));
PDFMergerUtility mergedDoc = new PDFMergerUtility();
ByteArrayOutputStream docOutputstream = new ByteArrayOutputStream();
for (MultipartFile file : files) {
mergedDoc.addSource(new ByteArrayInputStream(file.getBytes()));
}
mergedDoc.setDestinationFileName(files[0].getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_merged.pdf");
mergedDoc.setDestinationStream(docOutputstream);
mergedDoc.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
return WebResponseUtils.bytesToWebResponse(docOutputstream.toByteArray(), mergedDoc.getDestinationFileName());
} catch (Exception ex) {
logger.error("Error in merge pdf process", ex);
throw ex;
}
}
}
}

View File

@@ -0,0 +1,173 @@
package stirling.software.SPDF.controller.api;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import org.apache.pdfbox.multipdf.Overlay;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.OverlayPdfsRequest;
import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/general")
@Tag(name = "General", description = "General APIs")
public class PdfOverlayController {
@PostMapping(value = "/overlay-pdfs", consumes = "multipart/form-data")
@Operation(summary = "Overlay PDF files in various modes", description = "Overlay PDF files onto a base PDF with different modes: Sequential, Interleaved, or Fixed Repeat. Input:PDF Output:PDF Type:MIMO")
public ResponseEntity<byte[]> overlayPdfs(@ModelAttribute OverlayPdfsRequest request) throws IOException {
MultipartFile baseFile = request.getFileInput();
int overlayPos = request.getOverlayPosition();
MultipartFile[] overlayFiles = request.getOverlayFiles();
File[] overlayPdfFiles = new File[overlayFiles.length];
List<File> tempFiles = new ArrayList<>(); // List to keep track of temporary files
try {
for (int i = 0; i < overlayFiles.length; i++) {
overlayPdfFiles[i] = GeneralUtils.multipartToFile(overlayFiles[i]);
}
String mode = request.getOverlayMode(); // "SequentialOverlay", "InterleavedOverlay", "FixedRepeatOverlay"
int[] counts = request.getCounts(); // Used for FixedRepeatOverlay mode
try (PDDocument basePdf = PDDocument.load(baseFile.getInputStream());
Overlay overlay = new Overlay()) {
Map<Integer, String> overlayGuide = prepareOverlayGuide(basePdf.getNumberOfPages(), overlayPdfFiles, mode, counts, tempFiles);
overlay.setInputPDF(basePdf);
if (overlayPos == 0) {
overlay.setOverlayPosition(Overlay.Position.FOREGROUND);
} else {
overlay.setOverlayPosition(Overlay.Position.BACKGROUND);
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
overlay.overlay(overlayGuide).save(outputStream);
byte[] data = outputStream.toByteArray();
String outputFilename = baseFile.getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_overlayed.pdf"; // Remove file extension and append .pdf
return WebResponseUtils.bytesToWebResponse(data, outputFilename, MediaType.APPLICATION_PDF);
}
} finally {
for (File overlayPdfFile : overlayPdfFiles) {
if (overlayPdfFile != null) {
overlayPdfFile.delete();
}
}
for (File tempFile : tempFiles) { // Delete temporary files
if (tempFile != null) {
tempFile.delete();
}
}
}
}
private Map<Integer, String> prepareOverlayGuide(int basePageCount, File[] overlayFiles, String mode, int[] counts, List<File> tempFiles) throws IOException {
Map<Integer, String> overlayGuide = new HashMap<>();
switch (mode) {
case "SequentialOverlay":
sequentialOverlay(overlayGuide, overlayFiles, basePageCount, tempFiles);
break;
case "InterleavedOverlay":
interleavedOverlay(overlayGuide, overlayFiles, basePageCount);
break;
case "FixedRepeatOverlay":
fixedRepeatOverlay(overlayGuide, overlayFiles, counts, basePageCount);
break;
default:
throw new IllegalArgumentException("Invalid overlay mode");
}
return overlayGuide;
}
private void sequentialOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int basePageCount, List<File> tempFiles) throws IOException {
int overlayFileIndex = 0;
int pageCountInCurrentOverlay = 0;
for (int basePageIndex = 1; basePageIndex <= basePageCount; basePageIndex++) {
if (pageCountInCurrentOverlay == 0 || pageCountInCurrentOverlay >= getNumberOfPages(overlayFiles[overlayFileIndex])) {
pageCountInCurrentOverlay = 0;
overlayFileIndex = (overlayFileIndex + 1) % overlayFiles.length;
}
try (PDDocument overlayPdf = PDDocument.load(overlayFiles[overlayFileIndex])) {
PDDocument singlePageDocument = new PDDocument();
singlePageDocument.addPage(overlayPdf.getPage(pageCountInCurrentOverlay));
File tempFile = File.createTempFile("overlay-page-", ".pdf");
singlePageDocument.save(tempFile);
singlePageDocument.close();
overlayGuide.put(basePageIndex, tempFile.getAbsolutePath());
tempFiles.add(tempFile); // Keep track of the temporary file for cleanup
}
pageCountInCurrentOverlay++;
}
}
private int getNumberOfPages(File file) throws IOException {
try (PDDocument doc = PDDocument.load(file)) {
return doc.getNumberOfPages();
}
}
private void interleavedOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int basePageCount) throws IOException {
for (int basePageIndex = 1; basePageIndex <= basePageCount; basePageIndex++) {
File overlayFile = overlayFiles[(basePageIndex - 1) % overlayFiles.length];
// Load the overlay document to check its page count
try (PDDocument overlayPdf = PDDocument.load(overlayFile)) {
int overlayPageCount = overlayPdf.getNumberOfPages();
if ((basePageIndex - 1) % overlayPageCount < overlayPageCount) {
overlayGuide.put(basePageIndex, overlayFile.getAbsolutePath());
}
}
}
}
private void fixedRepeatOverlay(Map<Integer, String> overlayGuide, File[] overlayFiles, int[] counts, int basePageCount) throws IOException {
if (overlayFiles.length != counts.length) {
throw new IllegalArgumentException("Counts array length must match the number of overlay files");
}
int currentPage = 1;
for (int i = 0; i < overlayFiles.length; i++) {
File overlayFile = overlayFiles[i];
int repeatCount = counts[i];
// Load the overlay document to check its page count
try (PDDocument overlayPdf = PDDocument.load(overlayFile)) {
int overlayPageCount = overlayPdf.getNumberOfPages();
for (int j = 0; j < repeatCount; j++) {
for (int page = 0; page < overlayPageCount; page++) {
if (currentPage > basePageCount) break;
overlayGuide.put(currentPage++, overlayFile.getAbsolutePath());
}
}
}
}
}
}
// Additional classes like OverlayPdfsRequest, WebResponseUtils, etc. are assumed to be defined elsewhere.

View File

@@ -12,13 +12,10 @@ 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.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.SortTypes;
import stirling.software.SPDF.model.api.PDFWithPageNums;

View File

@@ -27,7 +27,7 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.PDFWithPageNums;
import stirling.software.SPDF.utils.WebResponseUtils;
import org.apache.pdfbox.multipdf.Splitter;
@RestController
@RequestMapping("/api/v1/general")
@Tag(name = "General", description = "General APIs")
@@ -50,24 +50,26 @@ public class SplitPDFController {
pageNumbers.add(document.getNumberOfPages()- 1);
logger.info("Splitting PDF into pages: {}", pageNumbers.stream().map(String::valueOf).collect(Collectors.joining(",")));
Splitter splitter = new Splitter();
// split the document
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
int previousPageNumber = 1; // PDFBox uses 1-based indexing for pages.
int previousPageNumber = 0;
for (int splitPoint : pageNumbers) {
splitPoint = splitPoint + 1;
splitter.setStartPage(previousPageNumber);
splitter.setEndPage(splitPoint);
List<PDDocument> splitDocuments = splitter.split(document);
try (PDDocument splitDocument = new PDDocument()) {
for (int i = previousPageNumber; i <= splitPoint; i++) {
PDPage page = document.getPage(i);
splitDocument.addPage(page);
logger.debug("Adding page {} to split document", i);
}
previousPageNumber = splitPoint + 1;
for (PDDocument splitDoc : splitDocuments) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
splitDoc.save(baos);
splitDocumentsBoas.add(baos);
splitDoc.close();
}
splitDocument.save(baos);
previousPageNumber = splitPoint + 1;
splitDocumentsBoas.add(baos);
} catch (Exception e) {
logger.error("Failed splitting documents and saving them", e);
throw e;
}
}
@@ -106,4 +108,4 @@ public class SplitPDFController {
}
}
}

View File

@@ -0,0 +1,135 @@
package stirling.software.SPDF.controller.api;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.pdfbox.multipdf.LayerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
import org.apache.pdfbox.util.Matrix;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.SplitPdfBySectionsRequest;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/general")
@Tag(name = "General", description = "General APIs")
public class SplitPdfBySectionsController {
@PostMapping(value = "/split-pdf-by-sections", consumes = "multipart/form-data")
@Operation(summary = "Split PDF pages into smaller sections", description = "Split each page of a PDF into smaller sections based on the user's choice (halves, thirds, quarters, etc.), both vertically and horizontally. Input:PDF Output:ZIP-PDF Type:SISO")
public ResponseEntity<byte[]> splitPdf(@ModelAttribute SplitPdfBySectionsRequest request) throws Exception {
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<>();
MultipartFile file = request.getFileInput();
PDDocument sourceDocument = PDDocument.load(file.getInputStream());
// Process the PDF based on split parameters
int horiz = request.getHorizontalDivisions() + 1;
int verti = request.getVerticalDivisions() + 1;
List<PDDocument> splitDocuments = splitPdfPages(sourceDocument, verti, horiz);
for (PDDocument doc : splitDocuments) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
doc.save(baos);
doc.close();
splitDocumentsBoas.add(baos);
}
sourceDocument.close();
Path zipFile = Files.createTempFile("split_documents", ".zip");
String filename = file.getOriginalFilename().replaceFirst("[.][^.]+$", "");
byte[] data;
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
int pageNum = 1;
for (int i = 0; i < splitDocumentsBoas.size(); i++) {
ByteArrayOutputStream baos = splitDocumentsBoas.get(i);
int sectionNum = (i % (horiz * verti)) + 1;
String fileName = filename + "_" + pageNum + "_" + sectionNum + ".pdf";
byte[] pdf = baos.toByteArray();
ZipEntry pdfEntry = new ZipEntry(fileName);
zipOut.putNextEntry(pdfEntry);
zipOut.write(pdf);
zipOut.closeEntry();
if (sectionNum == horiz * verti) pageNum++;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
data = Files.readAllBytes(zipFile);
Files.delete(zipFile);
}
return WebResponseUtils.bytesToWebResponse(data, filename + "_split.zip", MediaType.APPLICATION_OCTET_STREAM);
}
public List<PDDocument> splitPdfPages(PDDocument document, int horizontalDivisions, int verticalDivisions) throws IOException {
List<PDDocument> splitDocuments = new ArrayList<>();
for (PDPage originalPage : document.getPages()) {
PDRectangle originalMediaBox = originalPage.getMediaBox();
float width = originalMediaBox.getWidth();
float height = originalMediaBox.getHeight();
float subPageWidth = width / horizontalDivisions;
float subPageHeight = height / verticalDivisions;
LayerUtility layerUtility = new LayerUtility(document);
for (int i = 0; i < horizontalDivisions; i++) {
for (int j = 0; j < verticalDivisions; j++) {
PDDocument subDoc = new PDDocument();
PDPage subPage = new PDPage(new PDRectangle(subPageWidth, subPageHeight));
subDoc.addPage(subPage);
PDFormXObject form = layerUtility.importPageAsForm(document, document.getPages().indexOf(originalPage));
try (PDPageContentStream contentStream = new PDPageContentStream(subDoc, subPage)) {
// Set clipping area and position
float translateX = -subPageWidth * i;
float translateY = height - subPageHeight * (verticalDivisions - j);
contentStream.saveGraphicsState();
contentStream.addRect(0, 0, subPageWidth, subPageHeight);
contentStream.clip();
contentStream.transform(new Matrix(1, 0, 0, 1, translateX, translateY));
// Draw the form
contentStream.drawForm(form);
contentStream.restoreGraphicsState();
}
splitDocuments.add(subDoc);
}
}
}
return splitDocuments;
}
}

View File

@@ -0,0 +1,153 @@
package stirling.software.SPDF.controller.api;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.general.SplitPdfBySizeOrCountRequest;
import stirling.software.SPDF.utils.GeneralUtils;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/general")
@Tag(name = "General", description = "General APIs")
public class SplitPdfBySizeController {
@PostMapping(value = "/split-by-size-or-count", consumes = "multipart/form-data")
@Operation(summary = "Auto split PDF pages into separate documents based on size or count", description = "split PDF into multiple paged documents based on size/count, ie if 20 pages and split into 5, it does 5 documents each 4 pages\r\n"
+ " if 10MB and each page is 1MB and you enter 2MB then 5 docs each 2MB (rounded so that it accepts 1.9MB but not 2.1MB) Input:PDF Output:ZIP-PDF Type:SISO")
public ResponseEntity<byte[]> autoSplitPdf(@ModelAttribute SplitPdfBySizeOrCountRequest request) throws Exception {
List<ByteArrayOutputStream> splitDocumentsBoas = new ArrayList<ByteArrayOutputStream>();
MultipartFile file = request.getFileInput();
PDDocument sourceDocument = PDDocument.load(file.getInputStream());
//0 = size, 1 = page count, 2 = doc count
int type = request.getSplitType();
String value = request.getSplitValue();
if (type == 0) { // Split by size
long maxBytes = GeneralUtils.convertSizeToBytes(value);
long currentSize = 0;
PDDocument currentDoc = new PDDocument();
for (PDPage page : sourceDocument.getPages()) {
ByteArrayOutputStream pageOutputStream = new ByteArrayOutputStream();
PDDocument tempDoc = new PDDocument();
tempDoc.addPage(page);
tempDoc.save(pageOutputStream);
tempDoc.close();
long pageSize = pageOutputStream.size();
if (currentSize + pageSize > maxBytes) {
// Save and reset current document
splitDocumentsBoas.add(currentDocToByteArray(currentDoc));
currentDoc = new PDDocument();
currentSize = 0;
}
currentDoc.addPage(page);
currentSize += pageSize;
}
// Add the last document if it contains any pages
if (currentDoc.getPages().getCount() != 0) {
splitDocumentsBoas.add(currentDocToByteArray(currentDoc));
}
} else if (type == 1) { // Split by page count
int pageCount = Integer.parseInt(value);
int currentPageCount = 0;
PDDocument currentDoc = new PDDocument();
for (PDPage page : sourceDocument.getPages()) {
currentDoc.addPage(page);
currentPageCount++;
if (currentPageCount == pageCount) {
// Save and reset current document
splitDocumentsBoas.add(currentDocToByteArray(currentDoc));
currentDoc = new PDDocument();
currentPageCount = 0;
}
}
// Add the last document if it contains any pages
if (currentDoc.getPages().getCount() != 0) {
splitDocumentsBoas.add(currentDocToByteArray(currentDoc));
}
} else if (type == 2) { // Split by doc count
int documentCount = Integer.parseInt(value);
int totalPageCount = sourceDocument.getNumberOfPages();
int pagesPerDocument = totalPageCount / documentCount;
int extraPages = totalPageCount % documentCount;
int currentPageIndex = 0;
for (int i = 0; i < documentCount; i++) {
PDDocument currentDoc = new PDDocument();
int pagesToAdd = pagesPerDocument + (i < extraPages ? 1 : 0);
for (int j = 0; j < pagesToAdd; j++) {
currentDoc.addPage(sourceDocument.getPage(currentPageIndex++));
}
splitDocumentsBoas.add(currentDocToByteArray(currentDoc));
}
} else {
throw new IllegalArgumentException("Invalid argument for split type");
}
sourceDocument.close();
Path zipFile = Files.createTempFile("split_documents", ".zip");
String filename = file.getOriginalFilename().replaceFirst("[.][^.]+$", "");
byte[] data;
try (ZipOutputStream zipOut = new ZipOutputStream(Files.newOutputStream(zipFile))) {
for (int i = 0; i < splitDocumentsBoas.size(); i++) {
String fileName = filename + "_" + (i + 1) + ".pdf";
ByteArrayOutputStream baos = splitDocumentsBoas.get(i);
byte[] pdf = baos.toByteArray();
ZipEntry pdfEntry = new ZipEntry(fileName);
zipOut.putNextEntry(pdfEntry);
zipOut.write(pdf);
zipOut.closeEntry();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
data = Files.readAllBytes(zipFile);
Files.delete(zipFile);
}
return WebResponseUtils.bytesToWebResponse(data, filename + ".zip", MediaType.APPLICATION_OCTET_STREAM);
}
private ByteArrayOutputStream currentDocToByteArray(PDDocument document) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
document.save(baos);
document.close();
return baos;
}
}

View File

@@ -23,6 +23,7 @@ import org.springframework.web.servlet.view.RedirectView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import stirling.software.SPDF.config.security.UserService;
import stirling.software.SPDF.model.Role;
import stirling.software.SPDF.model.User;
@Controller
@@ -32,6 +33,7 @@ public class UserController {
@Autowired
private UserService userService;
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/register")
public String register(@RequestParam String username, @RequestParam String password, Model model) {
if(userService.usernameExists(username)) {
@@ -43,6 +45,7 @@ public class UserController {
return "redirect:/login?registered=true";
}
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/change-username-and-password")
public RedirectView changeUsernameAndPassword(Principal principal,
@RequestParam String currentPassword,
@@ -85,7 +88,7 @@ public class UserController {
}
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/change-username")
public RedirectView changeUsername(Principal principal,
@RequestParam String currentPassword,
@@ -122,7 +125,8 @@ public class UserController {
return new RedirectView("/login?messageType=credsUpdated");
}
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/change-password")
public RedirectView changePassword(Principal principal,
@RequestParam String currentPassword,
@@ -154,7 +158,7 @@ public class UserController {
return new RedirectView("/login?messageType=credsUpdated");
}
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/updateUserSettings")
public String updateUserSettings(HttpServletRequest request, Principal principal) {
Map<String, String[]> paramMap = request.getParameterMap();
@@ -182,6 +186,18 @@ public class UserController {
if(userService.usernameExists(username)) {
return new RedirectView("/addUsers?messageType=usernameExists");
}
try {
// Validate the role
Role roleEnum = Role.fromString(role);
if (roleEnum == Role.INTERNAL_API_USER) {
// If the role is INTERNAL_API_USER, reject the request
return new RedirectView("/addUsers?messageType=invalidRole");
}
} catch (IllegalArgumentException e) {
// If the role ID is not valid, redirect with an error message
return new RedirectView("/addUsers?messageType=invalidRole");
}
userService.saveUser(username, password, role, forceChange);
return new RedirectView("/addUsers"); // Redirect to account page after adding the user
}
@@ -203,6 +219,7 @@ public class UserController {
return "redirect:/addUsers";
}
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/get-api-key")
public ResponseEntity<String> getApiKey(Principal principal) {
if (principal == null) {
@@ -216,6 +233,7 @@ public class UserController {
return ResponseEntity.ok(apiKey);
}
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@PostMapping("/update-api-key")
public ResponseEntity<String> updateApiKey(Principal principal) {
if (principal == null) {

View File

@@ -1,130 +0,0 @@
package stirling.software.SPDF.controller.api.converters;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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 org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.GeneralFile;
import stirling.software.SPDF.utils.FileToPdf;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/convert")
@Tag(name = "Convert", description = "Convert APIs")
public class ConvertEpubToPdf {
//TODO
@PostMapping(consumes = "multipart/form-data", value = "/epub-to-single-pdf")
@Hidden
@Operation(
summary = "Convert an EPUB file to a single PDF",
description = "This endpoint takes an EPUB file input and converts it to a single PDF."
)
public ResponseEntity<byte[]> epubToSinglePdf(
@ModelAttribute GeneralFile request)
throws Exception {
MultipartFile fileInput = request.getFileInput();
if (fileInput == null) {
throw new IllegalArgumentException("Please provide an EPUB file for conversion.");
}
String originalFilename = fileInput.getOriginalFilename();
if (originalFilename == null || !originalFilename.endsWith(".epub")) {
throw new IllegalArgumentException("File must be in .epub format.");
}
Map<String, byte[]> epubContents = extractEpubContent(fileInput);
List<String> htmlFilesOrder = getHtmlFilesOrderFromOpf(epubContents);
List<byte[]> individualPdfs = new ArrayList<>();
for (String htmlFile : htmlFilesOrder) {
byte[] htmlContent = epubContents.get(htmlFile);
byte[] pdfBytes = FileToPdf.convertHtmlToPdf(htmlContent, htmlFile.replace(".html", ".pdf"));
individualPdfs.add(pdfBytes);
}
// Pseudo-code to merge individual PDFs into one.
byte[] mergedPdfBytes = mergeMultiplePdfsIntoOne(individualPdfs);
return WebResponseUtils.bytesToWebResponse(mergedPdfBytes, originalFilename.replace(".epub", ".pdf"));
}
// Assuming a pseudo-code function that merges multiple PDFs into one.
private byte[] mergeMultiplePdfsIntoOne(List<byte[]> individualPdfs) {
// You can use a library such as PDFBox to perform the merging here.
// Return the byte[] of the merged PDF.
return null;
}
private Map<String, byte[]> extractEpubContent(MultipartFile fileInput) throws IOException {
Map<String, byte[]> contentMap = new HashMap<>();
try (ZipInputStream zis = new ZipInputStream(fileInput.getInputStream())) {
ZipEntry zipEntry = zis.getNextEntry();
while (zipEntry != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int read = 0;
while ((read = zis.read(buffer)) != -1) {
baos.write(buffer, 0, read);
}
contentMap.put(zipEntry.getName(), baos.toByteArray());
zipEntry = zis.getNextEntry();
}
}
return contentMap;
}
private List<String> getHtmlFilesOrderFromOpf(Map<String, byte[]> epubContents) throws Exception {
String opfContent = new String(epubContents.get("OEBPS/content.opf")); // Adjusting for given path
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(opfContent));
Document doc = dBuilder.parse(is);
NodeList itemRefs = doc.getElementsByTagName("itemref");
List<String> htmlFilesOrder = new ArrayList<>();
for (int i = 0; i < itemRefs.getLength(); i++) {
Element itemRef = (Element) itemRefs.item(i);
String idref = itemRef.getAttribute("idref");
NodeList items = doc.getElementsByTagName("item");
for (int j = 0; j < items.getLength(); j++) {
Element item = (Element) items.item(j);
if (idref.equals(item.getAttribute("id"))) {
htmlFilesOrder.add(item.getAttribute("href")); // Fetching the actual href
break;
}
}
}
return htmlFilesOrder;
}
}

View File

@@ -1,6 +1,7 @@
package stirling.software.SPDF.controller.api.converters;
import java.io.IOException;
import java.net.URLConnection;
import org.apache.pdfbox.rendering.ImageType;
import org.slf4j.Logger;
@@ -23,6 +24,7 @@ import stirling.software.SPDF.model.api.converters.ConvertToImageRequest;
import stirling.software.SPDF.model.api.converters.ConvertToPdfRequest;
import stirling.software.SPDF.utils.PdfUtils;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/convert")
@Tag(name = "Convert", description = "Convert APIs")
@@ -89,15 +91,7 @@ public class ConvertImgPDFController {
}
private String getMediaType(String imageFormat) {
if (imageFormat.equalsIgnoreCase("PNG"))
return "image/png";
else if (imageFormat.equalsIgnoreCase("JPEG") || imageFormat.equalsIgnoreCase("JPG"))
return "image/jpeg";
else if (imageFormat.equalsIgnoreCase("GIF"))
return "image/gif";
else
return "application/octet-stream";
String mimeType = URLConnection.guessContentTypeFromName("." + imageFormat);
return mimeType.equals("null") ? "application/octet-stream" : mimeType;
}
}

View File

@@ -28,7 +28,7 @@ public class ConvertWebsiteToPDF {
@PostMapping(consumes = "multipart/form-data", value = "/url/pdf")
@Operation(
summary = "Convert a URL to a PDF",
description = "This endpoint fetches content from a URL and converts it to a PDF format."
description = "This endpoint fetches content from a URL and converts it to a PDF format. Input:N/A Output:PDF Type:SISO"
)
public ResponseEntity<byte[]> urlToPdf(@ModelAttribute UrlToPdfRequest request) throws IOException, InterruptedException {
String URL = request.getUrlInput();

View File

@@ -0,0 +1,123 @@
package stirling.software.SPDF.controller.api.converters;
import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
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 com.opencsv.CSVWriter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.controller.api.CropController;
import stirling.software.SPDF.controller.api.strippers.PDFTableStripper;
import stirling.software.SPDF.model.api.extract.PDFFilePage;
@RestController
@RequestMapping("/api/v1/convert")
@Tag(name = "Convert", description = "Convert APIs")
public class ExtractController {
private static final Logger logger = LoggerFactory.getLogger(CropController.class);
@PostMapping(value = "/pdf/csv", consumes = "multipart/form-data")
@Operation(summary = "Extracts a PDF document to csv", description = "This operation takes an input PDF file and returns CSV file of whole page. Input:PDF Output:CSV Type:SISO")
public ResponseEntity<String> PdfToCsv(@ModelAttribute PDFFilePage form)
throws Exception {
ArrayList<String> tableData = new ArrayList<>();
int columnsCount = 0;
try (PDDocument document = PDDocument.load(new ByteArrayInputStream(form.getFileInput().getBytes()))) {
final double res = 72; // PDF units are at 72 DPI
PDFTableStripper stripper = new PDFTableStripper();
PDPage pdPage = document.getPage(form.getPageId() - 1);
stripper.extractTable(pdPage);
columnsCount = stripper.getColumns();
for (int c = 0; c < columnsCount; ++c) {
for(int r=0; r<stripper.getRows(); ++r) {
tableData.add(stripper.getText(r, c));
}
}
}
ArrayList<String> notEmptyColumns = new ArrayList<>();
for (String item: tableData) {
if(!item.trim().isEmpty()){
notEmptyColumns.add(item);
}else{
columnsCount--;
}
}
List<String> fullTable = notEmptyColumns.stream().map((entity)->
entity.replace('\n',' ').replace('\r',' ').trim().replaceAll("\\s{2,}", "|")).toList();
int rowsCount = fullTable.get(0).split("\\|").length;
ArrayList<String> headersList = getTableHeaders(columnsCount,fullTable);
ArrayList<String> recordList = getRecordsList(rowsCount,fullTable);
if(headersList.size() == 0 && recordList.size() == 0) {
throw new Exception("No table detected, no headers or records found");
}
StringWriter writer = new StringWriter();
try (CSVWriter csvWriter = new CSVWriter(writer)) {
csvWriter.writeNext(headersList.toArray(new String[0]));
for (String record : recordList) {
csvWriter.writeNext(record.split("\\|"));
}
}
HttpHeaders headers = new HttpHeaders();
headers.setContentDisposition(ContentDisposition.builder("attachment").filename(form.getFileInput().getOriginalFilename().replaceFirst("[.][^.]+$", "") + "_extracted.csv").build());
headers.setContentType(MediaType.parseMediaType("text/csv"));
return ResponseEntity.ok()
.headers(headers)
.body(writer.toString());
}
private ArrayList<String> getRecordsList( int rowsCounts ,List<String> items){
ArrayList<String> recordsList = new ArrayList<>();
for (int b=1; b<rowsCounts;b++) {
StringBuilder strbldr = new StringBuilder();
for (int i=0;i<items.size();i++){
String[] parts = items.get(i).split("\\|");
strbldr.append(parts[b]);
if (i!= items.size()-1){
strbldr.append("|");
}
}
recordsList.add(strbldr.toString());
}
return recordsList;
}
private ArrayList<String> getTableHeaders(int columnsCount, List<String> items){
ArrayList<String> resultList = new ArrayList<>();
for (int i=0;i<columnsCount;i++){
String[] parts = items.get(i).split("\\|");
resultList.add(parts[0]);
}
return resultList;
}
}

View File

@@ -43,7 +43,7 @@ public class AutoSplitPdfController {
private static final String QR_CONTENT = "https://github.com/Frooodle/Stirling-PDF";
@PostMapping(value = "/auto-split-pdf", consumes = "multipart/form-data")
@Operation(summary = "Auto split PDF pages into separate documents", description = "This endpoint accepts a PDF file, scans each page for a specific QR code, and splits the document at the QR code boundaries. The output is a zip file containing each separate PDF document. Input:PDF Output:ZIP Type:SISO")
@Operation(summary = "Auto split PDF pages into separate documents", description = "This endpoint accepts a PDF file, scans each page for a specific QR code, and splits the document at the QR code boundaries. The output is a zip file containing each separate PDF document. Input:PDF Output:ZIP-PDF Type:SISO")
public ResponseEntity<byte[]> autoSplitPdf(@ModelAttribute AutoSplitPdfRequest request) throws IOException {
MultipartFile file = request.getFileInput();
boolean duplexMode = request.isDuplexMode();

View File

@@ -1,14 +1,12 @@
package stirling.software.SPDF.controller.api.misc;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

View File

@@ -13,6 +13,7 @@ import java.io.ByteArrayOutputStream;
//Required for file input/output
import java.io.File;
import java.io.IOException;
import java.security.SecureRandom;
//Other required classes
import java.util.Random;
@@ -85,7 +86,7 @@ public class FakeScanControllerWIP {
op.filter(sourceImage, destinationImage);
// Apply a rotation effect
double rotationRequired = Math.toRadians((new Random().nextInt(3 - 1) + 1)); // Random angle between 1 and 3 degrees
double rotationRequired = Math.toRadians((new SecureRandom().nextInt(3 - 1) + 1)); // Random angle between 1 and 3 degrees
double locationX = destinationImage.getWidth() / 2;
double locationY = destinationImage.getHeight() / 2;
AffineTransform tx = AffineTransform.getRotateInstance(rotationRequired, locationX, locationY);
@@ -103,7 +104,7 @@ public class FakeScanControllerWIP {
destinationImage = blurOp.filter(destinationImage, null);
// Add noise to the image based on the "dirtiness"
Random random = new Random();
Random random = new SecureRandom();
for (int y = 0; y < destinationImage.getHeight(); y++) {
for (int x = 0; x < destinationImage.getWidth(); x++) {
if (random.nextInt(100) < dirtiness) {

View File

@@ -39,7 +39,7 @@ public class OCRController {
private static final Logger logger = LoggerFactory.getLogger(OCRController.class);
public List<String> getAvailableTesseractLanguages() {
String tessdataDir = "/usr/share/tesseract-ocr/4.00/tessdata";
String tessdataDir = "/usr/share/tesseract-ocr/5/tessdata";
File[] files = new File(tessdataDir).listFiles();
if (files == null) {
return Collections.emptyList();

View File

@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.api.PDFFile;
import stirling.software.SPDF.utils.WebResponseUtils;
@@ -25,6 +26,7 @@ public class ShowJavascript {
private static final Logger logger = LoggerFactory.getLogger(ShowJavascript.class);
@PostMapping(consumes = "multipart/form-data", value = "/show-javascript")
@Operation(summary = "Grabs all JS from a PDF and returns a single JS file with all code", description = "desc. Input:PDF Output:JS Type:SISO")
public ResponseEntity<byte[]> extractHeader(@ModelAttribute PDFFile request) throws Exception {
MultipartFile inputFile = request.getFileInput();
String script = "";

View File

@@ -0,0 +1,123 @@
package stirling.software.SPDF.controller.api.pipeline;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletContext;
import stirling.software.SPDF.SPdfApplication;
import stirling.software.SPDF.model.ApiEndpoint;
import stirling.software.SPDF.model.Role;
import org.slf4j.Logger;
@Service
public class ApiDocService {
private final Map<String, ApiEndpoint> apiDocumentation = new HashMap<>();
private static final Logger logger = LoggerFactory.getLogger(ApiDocService.class);
@Autowired
private ServletContext servletContext;
private String getApiDocsUrl() {
String contextPath = servletContext.getContextPath();
String port = SPdfApplication.getPort();
return "http://localhost:"+ port + contextPath + "/v1/api-docs";
}
@Autowired(required=false)
private UserServiceInterface userService;
private String getApiKeyForUser() {
if(userService == null)
return "";
return userService.getApiKeyForUser(Role.INTERNAL_API_USER.getRoleId());
}
JsonNode apiDocsJsonRootNode;
//@EventListener(ApplicationReadyEvent.class)
private synchronized void loadApiDocumentation() {
String apiDocsJson = "";
try {
HttpHeaders headers = new HttpHeaders();
String apiKey = getApiKeyForUser();
if (!apiKey.isEmpty()) {
headers.set("X-API-KEY", apiKey);
}
HttpEntity<String> entity = new HttpEntity<>(headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange(getApiDocsUrl(), HttpMethod.GET, entity, String.class);
apiDocsJson = response.getBody();
ObjectMapper mapper = new ObjectMapper();
apiDocsJsonRootNode = mapper.readTree(apiDocsJson);
JsonNode paths = apiDocsJsonRootNode.path("paths");
paths.fields().forEachRemaining(entry -> {
String path = entry.getKey();
JsonNode pathNode = entry.getValue();
if (pathNode.has("post")) {
JsonNode postNode = pathNode.get("post");
ApiEndpoint endpoint = new ApiEndpoint(path, postNode);
apiDocumentation.put(path, endpoint);
}
});
} catch (Exception e) {
// Handle exceptions
logger.error("Error grabbing swagger doc, body result {}", apiDocsJson);
}
}
public boolean isValidOperation(String operationName, Map<String, Object> parameters) {
if(apiDocumentation.size() == 0) {
loadApiDocumentation();
}
if (!apiDocumentation.containsKey(operationName)) {
return false;
}
ApiEndpoint endpoint = apiDocumentation.get(operationName);
return endpoint.areParametersValid(parameters);
}
public boolean isMultiInput(String operationName) {
if(apiDocsJsonRootNode == null || apiDocumentation.size() == 0) {
loadApiDocumentation();
}
if (!apiDocumentation.containsKey(operationName)) {
return false;
}
ApiEndpoint endpoint = apiDocumentation.get(operationName);
String description = endpoint.getDescription();
Pattern pattern = Pattern.compile("Type:(\\w+)");
Matcher matcher = pattern.matcher(description);
if (matcher.find()) {
String type = matcher.group(1);
return type.startsWith("MI");
}
return false;
}
}
// Model class for API Endpoint

View File

@@ -1,56 +1,31 @@
package stirling.software.SPDF.controller.api.pipeline;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
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.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.PipelineConfig;
import stirling.software.SPDF.model.PipelineOperation;
import stirling.software.SPDF.model.api.HandleDataRequest;
import stirling.software.SPDF.utils.WebResponseUtils;
@@ -60,373 +35,39 @@ import stirling.software.SPDF.utils.WebResponseUtils;
public class PipelineController {
private static final Logger logger = LoggerFactory.getLogger(PipelineController.class);
@Autowired
private ObjectMapper objectMapper;
final String jsonFileName = "pipelineConfig.json";
final String watchedFoldersDir = "./pipeline/watchedFolders/";
final String finishedFoldersDir = "./pipeline/finishedFolders/";
@Autowired
PipelineProcessor processor;
@Scheduled(fixedRate = 25000)
public void scanFolders() {
logger.info("Scanning folders...");
Path watchedFolderPath = Paths.get(watchedFoldersDir);
if (!Files.exists(watchedFolderPath)) {
try {
Files.createDirectories(watchedFolderPath);
logger.info("Created directory: {}", watchedFolderPath);
} catch (IOException e) {
logger.error("Error creating directory: {}", watchedFolderPath, e);
return;
}
}
try (Stream<Path> paths = Files.walk(watchedFolderPath)) {
paths.filter(Files::isDirectory).forEach(t -> {
try {
if (!t.equals(watchedFolderPath) && !t.endsWith("processing")) {
handleDirectory(t);
}
} catch (Exception e) {
logger.error("Error handling directory: {}", t, e);
}
});
} catch (Exception e) {
logger.error("Error walking through directory: {}", watchedFolderPath, e);
}
}
@Autowired
ApplicationProperties applicationProperties;
private void handleDirectory(Path dir) throws Exception {
logger.info("Handling directory: {}", dir);
Path jsonFile = dir.resolve(jsonFileName);
Path processingDir = dir.resolve("processing"); // Directory to move files during processing
if (!Files.exists(processingDir)) {
Files.createDirectory(processingDir);
logger.info("Created processing directory: {}", processingDir);
}
if (Files.exists(jsonFile)) {
// Read JSON file
String jsonString;
try {
jsonString = new String(Files.readAllBytes(jsonFile));
logger.info("Read JSON file: {}", jsonFile);
} catch (IOException e) {
logger.error("Error reading JSON file: {}", jsonFile, e);
return;
}
// Decode JSON to PipelineConfig
PipelineConfig config;
try {
config = objectMapper.readValue(jsonString, PipelineConfig.class);
// Assuming your PipelineConfig class has getters for all necessary fields, you
// can perform checks here
if (config.getOperations() == null || config.getOutputDir() == null || config.getName() == null) {
throw new IOException("Invalid JSON format");
}
} catch (IOException e) {
logger.error("Error parsing PipelineConfig: {}", jsonString, e);
return;
}
// For each operation in the pipeline
for (PipelineOperation operation : config.getOperations()) {
// Collect all files based on fileInput
File[] files;
String fileInput = (String) operation.getParameters().get("fileInput");
if ("automated".equals(fileInput)) {
// If fileInput is "automated", process all files in the directory
try (Stream<Path> paths = Files.list(dir)) {
files = paths
.filter(path -> !Files.isDirectory(path)) // exclude directories
.filter(path -> !path.equals(jsonFile)) // exclude jsonFile
.map(Path::toFile)
.toArray(File[]::new);
} catch (IOException e) {
e.printStackTrace();
return;
}
} else {
// If fileInput contains a path, process only this file
files = new File[] { new File(fileInput) };
}
// Prepare the files for processing
List<File> filesToProcess = new ArrayList<>();
for (File file : files) {
logger.info(file.getName());
logger.info("{} to {}",file.toPath(), processingDir.resolve(file.getName()));
Files.move(file.toPath(), processingDir.resolve(file.getName()));
filesToProcess.add(processingDir.resolve(file.getName()).toFile());
}
// Process the files
try {
List<Resource> resources = handleFiles(filesToProcess.toArray(new File[0]), jsonString);
if(resources == null) {
return;
}
// Move resultant files and rename them as per config in JSON file
for (Resource resource : resources) {
String resourceName = resource.getFilename();
String baseName = resourceName.substring(0, resourceName.lastIndexOf("."));
String extension = resourceName.substring(resourceName.lastIndexOf(".")+1);
String outputFileName = config.getOutputPattern().replace("{filename}", baseName);
outputFileName = outputFileName.replace("{pipelineName}", config.getName());
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
outputFileName = outputFileName.replace("{date}", LocalDate.now().format(dateFormatter));
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HHmmss");
outputFileName = outputFileName.replace("{time}", LocalTime.now().format(timeFormatter));
outputFileName += "." + extension;
// {filename} {folder} {date} {tmime} {pipeline}
String outputDir = config.getOutputDir();
String outputFolder = applicationProperties.getAutoPipeline().getOutputFolder();
if (outputFolder == null || outputFolder.isEmpty()) {
// If the environment variable is not set, use the default value
outputFolder = finishedFoldersDir;
}
logger.info("outputDir 0={}", outputDir);
// Replace the placeholders in the outputDir string
outputDir = outputDir.replace("{outputFolder}", outputFolder);
outputDir = outputDir.replace("{folderName}", dir.toString());
logger.info("outputDir 1={}", outputDir);
outputDir = outputDir.replace("\\watchedFolders", "");
outputDir = outputDir.replace("//watchedFolders", "");
outputDir = outputDir.replace("\\\\watchedFolders", "");
outputDir = outputDir.replace("/watchedFolders", "");
Path outputPath;
logger.info("outputDir 2={}", outputDir);
if (Paths.get(outputDir).isAbsolute()) {
// If it's an absolute path, use it directly
outputPath = Paths.get(outputDir);
} else {
// If it's a relative path, make it relative to the current working directory
outputPath = Paths.get(".", outputDir);
}
logger.info("outputPath={}", outputPath);
if (!Files.exists(outputPath)) {
try {
Files.createDirectories(outputPath);
logger.info("Created directory: {}", outputPath);
} catch (IOException e) {
logger.error("Error creating directory: {}", outputPath, e);
return;
}
}
logger.info("outputPath {}", outputPath);
logger.info("outputPath.resolve(outputFileName).toString() {}", outputPath.resolve(outputFileName).toString());
File newFile = new File(outputPath.resolve(outputFileName).toString());
OutputStream os = new FileOutputStream(newFile);
os.write(((ByteArrayResource)resource).getByteArray());
os.close();
logger.info("made {}", outputPath.resolve(outputFileName));
}
// If successful, delete the original files
for (File file : filesToProcess) {
Files.deleteIfExists(processingDir.resolve(file.getName()));
}
} catch (Exception e) {
// If an error occurs, move the original files back
for (File file : filesToProcess) {
Files.move(processingDir.resolve(file.getName()), file.toPath());
}
throw e;
}
}
}
}
List<Resource> processFiles(List<Resource> outputFiles, String jsonString) throws Exception {
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonString);
JsonNode pipelineNode = jsonNode.get("pipeline");
logger.info("Running pipelineNode: {}", pipelineNode);
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
PrintStream logPrintStream = new PrintStream(logStream);
boolean hasErrors = false;
for (JsonNode operationNode : pipelineNode) {
String operation = operationNode.get("operation").asText();
logger.info("Running operation: {}", operation);
JsonNode parametersNode = operationNode.get("parameters");
String inputFileExtension = "";
if (operationNode.has("inputFileType")) {
inputFileExtension = operationNode.get("inputFileType").asText();
} else {
inputFileExtension = ".pdf";
}
List<Resource> newOutputFiles = new ArrayList<>();
boolean hasInputFileType = false;
for (Resource file : outputFiles) {
if (file.getFilename().endsWith(inputFileExtension)) {
hasInputFileType = true;
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("fileInput", file);
Iterator<Map.Entry<String, JsonNode>> parameters = parametersNode.fields();
while (parameters.hasNext()) {
Map.Entry<String, JsonNode> parameter = parameters.next();
body.add(parameter.getKey(), parameter.getValue().asText());
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8080/" + operation;
ResponseEntity<byte[]> response = restTemplate.exchange(url, HttpMethod.POST, entity, byte[].class);
// If the operation is filter and the response body is null or empty, skip this file
if (operation.startsWith("filter-") && (response.getBody() == null || response.getBody().length == 0)) {
logger.info("Skipping file due to failing {}", operation);
continue;
}
if (!response.getStatusCode().equals(HttpStatus.OK)) {
logPrintStream.println("Error: " + response.getBody());
hasErrors = true;
continue;
}
// Define filename
String filename;
if ("auto-rename".equals(operation)) {
// If the operation is "auto-rename", generate a new filename.
// This is a simple example of generating a filename using current timestamp.
// Modify as per your needs.
filename = "file_" + System.currentTimeMillis();
} else {
// Otherwise, keep the original filename.
filename = file.getFilename();
}
// Check if the response body is a zip file
if (isZip(response.getBody())) {
// Unzip the file and add all the files to the new output files
newOutputFiles.addAll(unzip(response.getBody()));
} else {
Resource outputResource = new ByteArrayResource(response.getBody()) {
@Override
public String getFilename() {
return filename;
}
};
newOutputFiles.add(outputResource);
}
}
if (!hasInputFileType) {
logPrintStream.println(
"No files with extension " + inputFileExtension + " found for operation " + operation);
hasErrors = true;
}
outputFiles = newOutputFiles;
}
logPrintStream.close();
}
if (hasErrors) {
logger.error("Errors occurred during processing. Log: {}", logStream.toString());
}
return outputFiles;
}
List<Resource> handleFiles(File[] files, String jsonString) throws Exception {
if(files == null || files.length == 0) {
logger.info("No files");
return null;
}
logger.info("Handling files: {} files, with JSON string of length: {}", files.length, jsonString.length());
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonString);
JsonNode pipelineNode = jsonNode.get("pipeline");
boolean hasErrors = false;
List<Resource> outputFiles = new ArrayList<>();
for (File file : files) {
Path path = Paths.get(file.getAbsolutePath());
System.out.println("Reading file: " + path); // debug statement
if (Files.exists(path)) {
Resource fileResource = new ByteArrayResource(Files.readAllBytes(path)) {
@Override
public String getFilename() {
return file.getName();
}
};
outputFiles.add(fileResource);
} else {
System.out.println("File not found: " + path); // debug statement
}
}
logger.info("Files successfully loaded. Starting processing...");
return processFiles(outputFiles, jsonString);
}
List<Resource> handleFiles(MultipartFile[] files, String jsonString) throws Exception {
if(files == null || files.length == 0) {
logger.info("No files");
return null;
}
logger.info("Handling files: {} files, with JSON string of length: {}", files.length, jsonString.length());
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(jsonString);
JsonNode pipelineNode = jsonNode.get("pipeline");
boolean hasErrors = false;
List<Resource> outputFiles = new ArrayList<>();
for (MultipartFile file : files) {
Resource fileResource = new ByteArrayResource(file.getBytes()) {
@Override
public String getFilename() {
return file.getOriginalFilename();
}
};
outputFiles.add(fileResource);
}
logger.info("Files successfully loaded. Starting processing...");
return processFiles(outputFiles, jsonString);
}
@Autowired
private ObjectMapper objectMapper;
@PostMapping("/handleData")
public ResponseEntity<byte[]> handleData(@ModelAttribute HandleDataRequest request) {
MultipartFile[] files = request.getFileInputs();
String jsonString = request.getJsonString();
public ResponseEntity<byte[]> handleData(@ModelAttribute HandleDataRequest request) throws JsonMappingException, JsonProcessingException {
if (!Boolean.TRUE.equals(applicationProperties.getSystem().getEnableAlphaFunctionality())) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
MultipartFile[] files = request.getFileInput();
String jsonString = request.getJson();
if (files == null) {
return null;
}
PipelineConfig config = objectMapper.readValue(jsonString, PipelineConfig.class);
logger.info("Received POST request to /handleData with {} files", files.length);
try {
List<Resource> outputFiles = handleFiles(files, jsonString);
List<Resource> inputFiles = processor.generateInputFiles(files);
if(inputFiles == null || inputFiles.size() == 0) {
return null;
}
List<Resource> outputFiles = processor.runPipelineAgainstFiles(inputFiles, config);
if (outputFiles != null && outputFiles.size() == 1) {
// If there is only one file, return it directly
Resource singleFile = outputFiles.get(0);
@@ -473,52 +114,4 @@ public class PipelineController {
}
}
private boolean isZip(byte[] data) {
if (data == null || data.length < 4) {
return false;
}
// Check the first four bytes of the data against the standard zip magic number
return data[0] == 0x50 && data[1] == 0x4B && data[2] == 0x03 && data[3] == 0x04;
}
private List<Resource> unzip(byte[] data) throws IOException {
logger.info("Unzipping data of length: {}", data.length);
List<Resource> unzippedFiles = new ArrayList<>();
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
ZipInputStream zis = new ZipInputStream(bais)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
while ((count = zis.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
final String filename = entry.getName();
Resource fileResource = new ByteArrayResource(baos.toByteArray()) {
@Override
public String getFilename() {
return filename;
}
};
// If the unzipped file is a zip file, unzip it
if (isZip(baos.toByteArray())) {
logger.info("File {} is a zip file. Unzipping...", filename);
unzippedFiles.addAll(unzip(baos.toByteArray()));
} else {
unzippedFiles.add(fileResource);
}
}
}
logger.info("Unzipping completed. {} files were unzipped.", unzippedFiles.size());
return unzippedFiles;
}
}

View File

@@ -0,0 +1,258 @@
package stirling.software.SPDF.controller.api.pipeline;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import stirling.software.SPDF.model.ApplicationProperties;
import stirling.software.SPDF.model.PipelineConfig;
import stirling.software.SPDF.model.PipelineOperation;
@Service
public class PipelineDirectoryProcessor {
private static final Logger logger = LoggerFactory.getLogger(PipelineDirectoryProcessor.class);
@Autowired
private ObjectMapper objectMapper;
@Autowired
private ApiDocService apiDocService;
@Autowired
private ApplicationProperties applicationProperties;
final String watchedFoldersDir = "./pipeline/watchedFolders/";
final String finishedFoldersDir = "./pipeline/finishedFolders/";
@Autowired
PipelineProcessor processor;
@Scheduled(fixedRate = 60000)
public void scanFolders() {
if (!Boolean.TRUE.equals(applicationProperties.getSystem().getEnableAlphaFunctionality())) {
return;
}
Path watchedFolderPath = Paths.get(watchedFoldersDir);
if (!Files.exists(watchedFolderPath)) {
try {
Files.createDirectories(watchedFolderPath);
logger.info("Created directory: {}", watchedFolderPath);
} catch (IOException e) {
logger.error("Error creating directory: {}", watchedFolderPath, e);
return;
}
}
try (Stream<Path> paths = Files.walk(watchedFolderPath)) {
paths.filter(Files::isDirectory).forEach(t -> {
try {
if (!t.equals(watchedFolderPath) && !t.endsWith("processing")) {
handleDirectory(t);
}
} catch (Exception e) {
logger.error("Error handling directory: {}", t, e);
}
});
} catch (Exception e) {
logger.error("Error walking through directory: {}", watchedFolderPath, e);
}
}
public void handleDirectory(Path dir) throws IOException {
logger.info("Handling directory: {}", dir);
Path processingDir = createProcessingDirectory(dir);
Optional<Path> jsonFileOptional = findJsonFile(dir);
if (!jsonFileOptional.isPresent()) {
logger.warn("No .JSON settings file found. No processing will happen for dir {}.", dir);
return;
}
Path jsonFile = jsonFileOptional.get();
PipelineConfig config = readAndParseJson(jsonFile);
processPipelineOperations(dir, processingDir, jsonFile, config);
}
private Path createProcessingDirectory(Path dir) throws IOException {
Path processingDir = dir.resolve("processing");
if (!Files.exists(processingDir)) {
Files.createDirectory(processingDir);
logger.info("Created processing directory: {}", processingDir);
}
return processingDir;
}
private Optional<Path> findJsonFile(Path dir) throws IOException {
try (Stream<Path> paths = Files.list(dir)) {
return paths.filter(file -> file.toString().endsWith(".json")).findFirst();
}
}
private PipelineConfig readAndParseJson(Path jsonFile) throws IOException {
String jsonString = new String(Files.readAllBytes(jsonFile), StandardCharsets.UTF_8);
logger.debug("Reading JSON file: {}", jsonFile);
return objectMapper.readValue(jsonString, PipelineConfig.class);
}
private void processPipelineOperations(Path dir, Path processingDir, Path jsonFile, PipelineConfig config) throws IOException {
for (PipelineOperation operation : config.getOperations()) {
validateOperation(operation);
File[] files = collectFilesForProcessing(dir, jsonFile, operation);
if(files == null || files.length == 0) {
logger.debug("No files detected for {} ", dir);
return;
}
List<File> filesToProcess = prepareFilesForProcessing(files, processingDir);
runPipelineAgainstFiles(filesToProcess, config, dir, processingDir);
}
}
private void validateOperation(PipelineOperation operation) throws IOException {
if (!apiDocService.isValidOperation(operation.getOperation(), operation.getParameters())) {
throw new IOException("Invalid operation: " + operation.getOperation());
}
}
private File[] collectFilesForProcessing(Path dir, Path jsonFile, PipelineOperation operation) 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))
.map(Path::toFile)
.toArray(File[]::new);
} else {
String fileInput = (String) operation.getParameters().get("fileInput");
return new File[]{new File(fileInput)};
}
}
}
private List<File> prepareFilesForProcessing(File[] files, Path processingDir) throws IOException {
List<File> filesToProcess = new ArrayList<>();
for (File file : files) {
Path targetPath = resolveUniqueFilePath(processingDir, file.getName());
Files.move(file.toPath(), targetPath);
filesToProcess.add(targetPath.toFile());
}
return filesToProcess;
}
private Path resolveUniqueFilePath(Path directory, String originalFileName) {
Path filePath = directory.resolve(originalFileName);
int counter = 1;
while (Files.exists(filePath)) {
String newName = appendSuffixToFileName(originalFileName, "(" + counter + ")");
filePath = directory.resolve(newName);
counter++;
}
return filePath;
}
private String appendSuffixToFileName(String originalFileName, String suffix) {
int dotIndex = originalFileName.lastIndexOf('.');
if (dotIndex == -1) {
return originalFileName + suffix;
} else {
return originalFileName.substring(0, dotIndex) + suffix + originalFileName.substring(dotIndex);
}
}
private void runPipelineAgainstFiles(List<File> filesToProcess, PipelineConfig config, Path dir, Path processingDir) throws IOException {
try {
List<Resource> inputFiles = processor.generateInputFiles(filesToProcess.toArray(new File[0]));
if(inputFiles == null || inputFiles.size() == 0) {
return;
}
List<Resource> outputFiles = processor.runPipelineAgainstFiles(inputFiles, config);
if (outputFiles == null) return;
moveAndRenameFiles(outputFiles, config, dir);
deleteOriginalFiles(filesToProcess, processingDir);
} catch (Exception e) {
logger.error("error during processing", e);
moveFilesBack(filesToProcess, processingDir);
}
}
private void moveAndRenameFiles(List<Resource> resources, PipelineConfig config, Path dir) throws IOException {
for (Resource resource : resources) {
String outputFileName = createOutputFileName(resource, config);
Path outputPath = determineOutputPath(config, dir);
if (!Files.exists(outputPath)) {
Files.createDirectories(outputPath);
logger.info("Created directory: {}", outputPath);
}
Path outputFile = outputPath.resolve(outputFileName);
try (OutputStream os = new FileOutputStream(outputFile.toFile())) {
os.write(((ByteArrayResource) resource).getByteArray());
}
logger.info("File moved and renamed to {}", outputFile);
}
}
private String createOutputFileName(Resource resource, PipelineConfig config) {
String resourceName = resource.getFilename();
String baseName = resourceName.substring(0, resourceName.lastIndexOf('.'));
String extension = resourceName.substring(resourceName.lastIndexOf('.') + 1);
String outputFileName = config.getOutputPattern()
.replace("{filename}", baseName)
.replace("{pipelineName}", config.getName())
.replace("{date}", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")))
.replace("{time}", LocalTime.now().format(DateTimeFormatter.ofPattern("HHmmss")))
+ "." + extension;
return outputFileName;
}
private Path determineOutputPath(PipelineConfig config, Path dir) {
String outputDir = config.getOutputDir()
.replace("{outputFolder}", finishedFoldersDir)
.replace("{folderName}", dir.toString())
.replaceAll("\\\\?watchedFolders", "");
return Paths.get(outputDir).isAbsolute() ? Paths.get(outputDir) : Paths.get(".", outputDir);
}
private void deleteOriginalFiles(List<File> filesToProcess, Path processingDir) throws IOException {
for (File file : filesToProcess) {
Files.deleteIfExists(processingDir.resolve(file.getName()));
logger.info("Deleted original file: {}", file.getName());
}
}
private void moveFilesBack(List<File> filesToProcess, Path processingDir) {
for (File file : filesToProcess) {
try {
Files.move(processingDir.resolve(file.getName()), file.toPath());
logger.info("Moved file back to original location: {} , {}",file.toPath(), file.getName());
} catch (IOException e) {
logger.error("Error moving file back to original location: {}", file.getName(), e);
}
}
}
}

View File

@@ -0,0 +1,332 @@
package stirling.software.SPDF.controller.api.pipeline;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import jakarta.servlet.ServletContext;
import stirling.software.SPDF.SPdfApplication;
import stirling.software.SPDF.model.PipelineConfig;
import stirling.software.SPDF.model.PipelineOperation;
import stirling.software.SPDF.model.Role;
@Service
public class PipelineProcessor {
private static final Logger logger = LoggerFactory.getLogger(PipelineProcessor.class);
@Autowired
private ApiDocService apiDocService;
@Autowired(required=false)
private UserServiceInterface userService;
@Autowired
private ServletContext servletContext;
private String getApiKeyForUser() {
if (userService == null)
return "";
return userService.getApiKeyForUser(Role.INTERNAL_API_USER.getRoleId());
}
private String getBaseUrl() {
String contextPath = servletContext.getContextPath();
String port = SPdfApplication.getPort();
return "http://localhost:" + port + contextPath + "/";
}
List<Resource> runPipelineAgainstFiles(List<Resource> outputFiles, PipelineConfig config) throws Exception {
ByteArrayOutputStream logStream = new ByteArrayOutputStream();
PrintStream logPrintStream = new PrintStream(logStream);
boolean hasErrors = false;
for (PipelineOperation pipelineOperation : config.getOperations()) {
String operation = pipelineOperation.getOperation();
boolean isMultiInputOperation = apiDocService.isMultiInput(operation);
logger.info("Running operation: {} isMultiInputOperation {}", operation, isMultiInputOperation);
Map<String, Object> parameters = pipelineOperation.getParameters();
String inputFileExtension = "";
//TODO
//if (operationNode.has("inputFileType")) {
// inputFileExtension = operationNode.get("inputFileType").asText();
//} else {
inputFileExtension = ".pdf";
//}
final String finalInputFileExtension = inputFileExtension;
String url = getBaseUrl() + operation;
List<Resource> newOutputFiles = new ArrayList<>();
if (!isMultiInputOperation) {
for (Resource file : outputFiles) {
boolean hasInputFileType = false;
if (file.getFilename().endsWith(inputFileExtension)) {
hasInputFileType = true;
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("fileInput", file);
for(Entry<String, Object> entry : parameters.entrySet()) {
body.add(entry.getKey(), entry.getValue());
}
ResponseEntity<byte[]> response = sendWebRequest(url, body);
// If the operation is filter and the response body is null or empty, skip this
// file
if (operation.startsWith("filter-")
&& (response.getBody() == null || response.getBody().length == 0)) {
logger.info("Skipping file due to failing {}", operation);
continue;
}
if (!response.getStatusCode().equals(HttpStatus.OK)) {
logPrintStream.println("Error: " + response.getBody());
hasErrors = true;
continue;
}
processOutputFiles(operation, file.getFilename(), response, newOutputFiles);
}
if (!hasInputFileType) {
logPrintStream.println(
"No files with extension " + inputFileExtension + " found for operation " + operation);
hasErrors = true;
}
outputFiles = newOutputFiles;
}
} else {
// Filter and collect all files that match the inputFileExtension
List<Resource> matchingFiles = outputFiles.stream()
.filter(file -> file.getFilename().endsWith(finalInputFileExtension))
.collect(Collectors.toList());
// Check if there are matching files
if (!matchingFiles.isEmpty()) {
// Create a new MultiValueMap for the request body
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
// Add all matching files to the body
for (Resource file : matchingFiles) {
body.add("fileInput", file);
}
for(Entry<String, Object> entry : parameters.entrySet()) {
body.add(entry.getKey(), entry.getValue());
}
ResponseEntity<byte[]> response = sendWebRequest(url, body);
// Handle the response
if (response.getStatusCode().equals(HttpStatus.OK)) {
processOutputFiles(operation, matchingFiles.get(0).getFilename(), response, newOutputFiles);
} else {
// Log error if the response status is not OK
logPrintStream.println("Error in multi-input operation: " + response.getBody());
hasErrors = true;
}
} else {
logPrintStream.println("No files with extension " + inputFileExtension + " found for multi-input operation " + operation);
hasErrors = true;
}
}
logPrintStream.close();
}
if (hasErrors) {
logger.error("Errors occurred during processing. Log: {}", logStream.toString());
}
return outputFiles;
}
private ResponseEntity<byte[]> sendWebRequest(String url, MultiValueMap<String, Object> body ){
RestTemplate restTemplate = new RestTemplate();
// Set up headers, including API key
HttpHeaders headers = new HttpHeaders();
String apiKey = getApiKeyForUser();
headers.add("X-API-Key", apiKey);
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
// Create HttpEntity with the body and headers
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);
// Make the request to the REST endpoint
return restTemplate.exchange(url, HttpMethod.POST, entity, byte[].class);
}
private List<Resource> processOutputFiles(String operation, String fileName, ResponseEntity<byte[]> response, List<Resource> newOutputFiles) throws IOException{
// Define filename
String newFilename;
if ("auto-rename".equals(operation)) {
// If the operation is "auto-rename", generate a new filename.
// This is a simple example of generating a filename using current timestamp.
// Modify as per your needs.
newFilename = "file_" + System.currentTimeMillis();
} else {
// Otherwise, keep the original filename.
newFilename = fileName;
}
// Check if the response body is a zip file
if (isZip(response.getBody())) {
// Unzip the file and add all the files to the new output files
newOutputFiles.addAll(unzip(response.getBody()));
} else {
Resource outputResource = new ByteArrayResource(response.getBody()) {
@Override
public String getFilename() {
return newFilename;
}
};
newOutputFiles.add(outputResource);
}
return newOutputFiles;
}
List<Resource> generateInputFiles(File[] files) throws Exception {
if (files == null || files.length == 0) {
logger.info("No files");
return null;
}
List<Resource> outputFiles = new ArrayList<>();
for (File file : files) {
Path path = Paths.get(file.getAbsolutePath());
logger.info("Reading file: " + path); // debug statement
if (Files.exists(path)) {
Resource fileResource = new ByteArrayResource(Files.readAllBytes(path)) {
@Override
public String getFilename() {
return file.getName();
}
};
outputFiles.add(fileResource);
} else {
logger.info("File not found: " + path);
}
}
logger.info("Files successfully loaded. Starting processing...");
return outputFiles;
}
List<Resource> generateInputFiles(MultipartFile[] files) throws Exception {
if (files == null || files.length == 0) {
logger.info("No files");
return null;
}
List<Resource> outputFiles = new ArrayList<>();
for (MultipartFile file : files) {
Resource fileResource = new ByteArrayResource(file.getBytes()) {
@Override
public String getFilename() {
return file.getOriginalFilename();
}
};
outputFiles.add(fileResource);
}
logger.info("Files successfully loaded. Starting processing...");
return outputFiles;
}
private boolean isZip(byte[] data) {
if (data == null || data.length < 4) {
return false;
}
// Check the first four bytes of the data against the standard zip magic number
return data[0] == 0x50 && data[1] == 0x4B && data[2] == 0x03 && data[3] == 0x04;
}
private List<Resource> unzip(byte[] data) throws IOException {
logger.info("Unzipping data of length: {}", data.length);
List<Resource> unzippedFiles = new ArrayList<>();
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
ZipInputStream zis = new ZipInputStream(bais)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;
while ((count = zis.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
final String filename = entry.getName();
Resource fileResource = new ByteArrayResource(baos.toByteArray()) {
@Override
public String getFilename() {
return filename;
}
};
// If the unzipped file is a zip file, unzip it
if (isZip(baos.toByteArray())) {
logger.info("File {} is a zip file. Unzipping...", filename);
unzippedFiles.addAll(unzip(baos.toByteArray()));
} else {
unzippedFiles.add(fileResource);
}
}
}
logger.info("Unzipping completed. {} files were unzipped.", unzippedFiles.size());
return unzippedFiles;
}
}

View File

@@ -0,0 +1,4 @@
package stirling.software.SPDF.controller.api.pipeline;
public interface UserServiceInterface {
String getApiKeyForUser(String username);
}

View File

@@ -0,0 +1,358 @@
package stirling.software.SPDF.controller.api.strippers;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.apache.fontbox.util.BoundingBox;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType3Font;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.PDFTextStripperByArea;
import org.apache.pdfbox.text.TextPosition;
/**
*
* Class to extract tabular data from a PDF.
* Works by making a first pass of the page to group all nearby text items
* together, and then inferring a 2D grid from these regions. Each table cell
* is then extracted using a PDFTextStripperByArea object.
*
* Works best when
* headers are included in the detected region, to ensure representative text
* in every column.
*
* Based upon DrawPrintTextLocations PDFBox example
* (https://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/util/DrawPrintTextLocations.java)
*
* @author Beldaz
*/
public class PDFTableStripper extends PDFTextStripper
{
/**
* This will print the documents data, for each table cell.
*
* @param args The command line arguments.
*
* @throws IOException If there is an error parsing the document.
*/
/*
* Used in methods derived from DrawPrintTextLocations
*/
private AffineTransform flipAT;
private AffineTransform rotateAT;
/**
* Regions updated by calls to writeString
*/
private Set<Rectangle2D> boxes;
// Border to allow when finding intersections
private double dx = 1.0; // This value works for me, feel free to tweak (or add setter)
private double dy = 0.000; // Rows of text tend to overlap, so need to extend
/**
* Region in which to find table (otherwise whole page)
*/
private Rectangle2D regionArea;
/**
* Number of rows in inferred table
*/
private int nRows=0;
/**
* Number of columns in inferred table
*/
private int nCols=0;
/**
* This is the object that does the text extraction
*/
private PDFTextStripperByArea regionStripper;
/**
* 1D intervals - used for calculateTableRegions()
* @author Beldaz
*
*/
public static class Interval {
double start;
double end;
public Interval(double start, double end) {
this.start=start; this.end = end;
}
public void add(Interval col) {
if(col.start<start)
start = col.start;
if(col.end>end)
end = col.end;
}
public static void addTo(Interval x, LinkedList<Interval> columns) {
int p = 0;
Iterator<Interval> it = columns.iterator();
// Find where x should go
while(it.hasNext()) {
Interval col = it.next();
if(x.end>=col.start) {
if(x.start<=col.end) { // overlaps
x.add(col);
it.remove();
}
break;
}
++p;
}
while(it.hasNext()) {
Interval col = it.next();
if(x.start>col.end)
break;
x.add(col);
it.remove();
}
columns.add(p, x);
}
}
/**
* Instantiate a new PDFTableStripper object.
*
* @param document
* @throws IOException If there is an error loading the properties.
*/
public PDFTableStripper() throws IOException
{
super.setShouldSeparateByBeads(false);
regionStripper = new PDFTextStripperByArea();
regionStripper.setSortByPosition( true );
}
/**
* Define the region to group text by.
*
* @param rect The rectangle area to retrieve the text from.
*/
public void setRegion(Rectangle2D rect )
{
regionArea = rect;
}
public int getRows()
{
return nRows;
}
public int getColumns()
{
return nCols;
}
/**
* Get the text for the region, this should be called after extractTable().
*
* @return The text that was identified in that region.
*/
public String getText(int row, int col)
{
return regionStripper.getTextForRegion("el"+col+"x"+row);
}
public void extractTable(PDPage pdPage) throws IOException
{
setStartPage(getCurrentPageNo());
setEndPage(getCurrentPageNo());
boxes = new HashSet<Rectangle2D>();
// flip y-axis
flipAT = new AffineTransform();
flipAT.translate(0, pdPage.getBBox().getHeight());
flipAT.scale(1, -1);
// page may be rotated
rotateAT = new AffineTransform();
int rotation = pdPage.getRotation();
if (rotation != 0)
{
PDRectangle mediaBox = pdPage.getMediaBox();
switch (rotation)
{
case 90:
rotateAT.translate(mediaBox.getHeight(), 0);
break;
case 270:
rotateAT.translate(0, mediaBox.getWidth());
break;
case 180:
rotateAT.translate(mediaBox.getWidth(), mediaBox.getHeight());
break;
default:
break;
}
rotateAT.rotate(Math.toRadians(rotation));
}
// Trigger processing of the document so that writeString is called.
try (Writer dummy = new OutputStreamWriter(new ByteArrayOutputStream())) {
super.output = dummy;
super.processPage(pdPage);
}
Rectangle2D[][] regions = calculateTableRegions();
// System.err.println("Drawing " + nCols + "x" + nRows + "="+ nRows*nCols + " regions");
for(int i=0; i<nCols; ++i) {
for(int j=0; j<nRows; ++j) {
final Rectangle2D region = regions[i][j];
regionStripper.addRegion("el"+i+"x"+j, region);
}
}
regionStripper.extractRegions(pdPage);
}
/**
* Infer a rectangular grid of regions from the boxes field.
*
* @return 2D array of table regions (as Rectangle2D objects). Note that
* some of these regions may have no content.
*/
private Rectangle2D[][] calculateTableRegions() {
// Build up a list of all table regions, based upon the populated
// regions of boxes field. Treats the horizontal and vertical extents
// of each box as distinct
LinkedList<Interval> columns = new LinkedList<Interval>();
LinkedList<Interval> rows = new LinkedList<Interval>();
for(Rectangle2D box: boxes) {
Interval x = new Interval(box.getMinX(), box.getMaxX());
Interval y = new Interval(box.getMinY(), box.getMaxY());
Interval.addTo(x, columns);
Interval.addTo(y, rows);
}
nRows = rows.size();
nCols = columns.size();
Rectangle2D[][] regions = new Rectangle2D[nCols][nRows];
int i=0;
// Label regions from top left, rather than the transformed orientation
for(Interval column: columns) {
int j=0;
for(Interval row: rows) {
regions[nCols-i-1][nRows-j-1] = new Rectangle2D.Double(column.start, row.start, column.end - column.start, row.end - row.start);
++j;
}
++i;
}
return regions;
}
/**
* Register each character's bounding box, updating boxes field to maintain
* a list of all distinct groups of characters.
*
* Overrides the default functionality of PDFTextStripper.
* Most of this is taken from DrawPrintTextLocations.java, with extra steps
* at end of main loop
*/
@Override
protected void writeString(String string, List<TextPosition> textPositions) throws IOException
{
for (TextPosition text : textPositions)
{
// glyph space -> user space
// note: text.getTextMatrix() is *not* the Text Matrix, it's the Text Rendering Matrix
AffineTransform at = text.getTextMatrix().createAffineTransform();
PDFont font = text.getFont();
BoundingBox bbox = font.getBoundingBox();
// advance width, bbox height (glyph space)
float xadvance = font.getWidth(text.getCharacterCodes()[0]); // todo: should iterate all chars
Rectangle2D.Float rect = new Rectangle2D.Float(0, bbox.getLowerLeftY(), xadvance, bbox.getHeight());
if (font instanceof PDType3Font)
{
// bbox and font matrix are unscaled
at.concatenate(font.getFontMatrix().createAffineTransform());
}
else
{
// bbox and font matrix are already scaled to 1000
at.scale(1/1000f, 1/1000f);
}
Shape s = at.createTransformedShape(rect);
s = flipAT.createTransformedShape(s);
s = rotateAT.createTransformedShape(s);
//
// Merge character's bounding box with boxes field
//
Rectangle2D bounds = s.getBounds2D();
// Pad sides to detect almost touching boxes
Rectangle2D hitbox = bounds.getBounds2D();
hitbox.add(bounds.getMinX() - dx , bounds.getMinY() - dy);
hitbox.add(bounds.getMaxX() + dx , bounds.getMaxY() + dy);
// Find all overlapping boxes
List<Rectangle2D> intersectList = new ArrayList<Rectangle2D>();
for(Rectangle2D box: boxes) {
if(box.intersects(hitbox)) {
intersectList.add(box);
}
}
// Combine all touching boxes and update
// (NOTE: Potentially this could leave some overlapping boxes un-merged,
// but it's sufficient for now and get's fixed up in calculateTableRegions)
for(Rectangle2D box: intersectList) {
bounds.add(box);
boxes.remove(box);
}
boxes.add(bounds);
}
}
/**
* This method does nothing in this derived class, because beads and regions are incompatible. Beads are
* ignored when stripping by area.
*
* @param aShouldSeparateByBeads The new grouping of beads.
*/
@Override
public final void setShouldSeparateByBeads(boolean aShouldSeparateByBeads)
{
}
/**
* Adapted from PDFTextStripperByArea
* {@inheritDoc}
*/
@Override
protected void processTextPosition( TextPosition text )
{
if(regionArea!=null && !regionArea.contains( text.getX(), text.getY() ) ) {
// skip character
} else {
super.processTextPosition( text );
}
}
}

View File

@@ -1,4 +1,5 @@
package stirling.software.SPDF.controller.web;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
@@ -15,6 +16,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import stirling.software.SPDF.model.Authority;
import stirling.software.SPDF.model.Role;
import stirling.software.SPDF.model.User;
import stirling.software.SPDF.repository.UserRepository;
@Controller
@@ -46,14 +49,28 @@ public class AccountWebController {
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/addUsers")
public String showAddUserForm(Model model, Authentication authentication) {
List<User> allUsers = userRepository.findAll();
List<User> allUsers = userRepository.findAll();
Iterator<User> iterator = allUsers.iterator();
while(iterator.hasNext()) {
User user = iterator.next();
if(user != null) {
for (Authority authority : user.getAuthorities()) {
if (authority.getAuthority().equals(Role.INTERNAL_API_USER.getRoleId())) {
iterator.remove();
break; // Break out of the inner loop once the user is removed
}
}
}
}
model.addAttribute("users", allUsers);
model.addAttribute("currentUsername", authentication.getName());
return "addUsers";
}
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@GetMapping("/account")
public String account(HttpServletRequest request, Model model, Authentication authentication) {
if (authentication == null || !authentication.isAuthenticated()) {
@@ -100,7 +117,7 @@ public class AccountWebController {
}
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
@GetMapping("/change-creds")
public String changeCreds(HttpServletRequest request, Model model, Authentication authentication) {
if (authentication == null || !authentication.isAuthenticated()) {

View File

@@ -99,6 +99,14 @@ public class ConverterWebController {
return modelAndView;
}
@GetMapping("/pdf-to-csv")
@Hidden
public ModelAndView pdfToCSV() {
ModelAndView modelAndView = new ModelAndView("convert/pdf-to-csv");
modelAndView.addObject("currentPage", "pdf-to-csv");
return modelAndView;
}
@GetMapping("/pdf-to-pdfa")
@Hidden

View File

@@ -1,4 +1,6 @@
package stirling.software.SPDF.controller.web;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -40,31 +42,44 @@ public class GeneralWebController {
model.addAttribute("currentPage", "pipeline");
List<String> pipelineConfigs = new ArrayList<>();
try (Stream<Path> paths = Files.walk(Paths.get("./pipeline/defaultWebUIConfigs/"))) {
List<Path> jsonFiles = paths
.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".json"))
.collect(Collectors.toList());
for (Path jsonFile : jsonFiles) {
String content = Files.readString(jsonFile, StandardCharsets.UTF_8);
pipelineConfigs.add(content);
}
List<Map<String, String>> pipelineConfigsWithNames = new ArrayList<>();
for (String config : pipelineConfigs) {
Map<String, Object> jsonContent = new ObjectMapper().readValue(config, new TypeReference<Map<String, Object>>(){});
String name = (String) jsonContent.get("name");
Map<String, String> configWithName = new HashMap<>();
configWithName.put("json", config);
configWithName.put("name", name);
List<Map<String, String>> pipelineConfigsWithNames = new ArrayList<>();
if(new File("./pipeline/defaultWebUIConfigs/").exists()) {
try (Stream<Path> paths = Files.walk(Paths.get("./pipeline/defaultWebUIConfigs/"))) {
List<Path> jsonFiles = paths
.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".json"))
.collect(Collectors.toList());
for (Path jsonFile : jsonFiles) {
String content = Files.readString(jsonFile, StandardCharsets.UTF_8);
pipelineConfigs.add(content);
}
for (String config : pipelineConfigs) {
Map<String, Object> jsonContent = new ObjectMapper().readValue(config, new TypeReference<Map<String, Object>>(){});
String name = (String) jsonContent.get("name");
Map<String, String> configWithName = new HashMap<>();
configWithName.put("json", config);
configWithName.put("name", name);
pipelineConfigsWithNames.add(configWithName);
}
} catch (IOException e) {
e.printStackTrace();
}
}
if(pipelineConfigsWithNames.size() == 0) {
Map<String, String> configWithName = new HashMap<>();
configWithName.put("json", "");
configWithName.put("name", "No preloaded configs found");
pipelineConfigsWithNames.add(configWithName);
}
model.addAttribute("pipelineConfigsWithNames", pipelineConfigsWithNames);
} catch (IOException e) {
e.printStackTrace();
}
model.addAttribute("pipelineConfigsWithNames", pipelineConfigsWithNames);
model.addAttribute("pipelineConfigs", pipelineConfigs);
@@ -81,6 +96,19 @@ public class GeneralWebController {
return "merge-pdfs";
}
@GetMapping("/split-pdf-by-sections")
@Hidden
public String splitPdfBySections(Model model) {
model.addAttribute("currentPage", "split-pdf-by-sections");
return "split-pdf-by-sections";
}
@GetMapping("/view-pdf")
@Hidden
public String ViewPdfForm2(Model model) {
model.addAttribute("currentPage", "view-pdf");
return "view-pdf";
}
@GetMapping("/multi-tool")
@Hidden
@@ -155,6 +183,20 @@ public class GeneralWebController {
return "scale-pages";
}
@GetMapping("/split-by-size-or-count")
@Hidden
public String splitBySizeOrCount(Model model) {
model.addAttribute("currentPage", "split-by-size-or-count");
return "split-by-size-or-count";
}
@GetMapping("/overlay-pdf")
@Hidden
public String overlayPdf(Model model) {
model.addAttribute("currentPage", "overlay-pdf");
return "overlay-pdf";
}
@Autowired

View File

@@ -27,8 +27,8 @@ import stirling.software.SPDF.config.StartupApplicationListener;
import stirling.software.SPDF.model.ApplicationProperties;
@RestController
@RequestMapping("/api/v1")
@Tag(name = "API", description = "Info APIs")
@RequestMapping("/api/v1/info")
@Tag(name = "Info", description = "Info APIs")
public class MetricsController {

View File

@@ -78,7 +78,7 @@ public class OtherWebController {
}
public List<String> getAvailableTesseractLanguages() {
String tessdataDir = "/usr/share/tesseract-ocr/4.00/tessdata";
String tessdataDir = "/usr/share/tesseract-ocr/5/tessdata";
File[] files = new File(tessdataDir).listFiles();
if (files == null) {
return Collections.emptyList();
@@ -98,7 +98,7 @@ public class OtherWebController {
return modelAndView;
}
@GetMapping("/add-image")
@Hidden
public String overlayImage(Model model) {
@@ -126,7 +126,13 @@ public class OtherWebController {
model.addAttribute("currentPage", "remove-blanks");
return "misc/remove-blanks";
}
@GetMapping("/remove-annotations")
@Hidden
public String removeAnnotationsForm(Model model) {
model.addAttribute("currentPage", "remove-annotations");
return "misc/remove-annotations";
}
@GetMapping("/auto-crop")
@Hidden

View File

@@ -0,0 +1,42 @@
package stirling.software.SPDF.model;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.databind.JsonNode;
public class ApiEndpoint {
private String name;
private Map<String, JsonNode> parameters;
private String description;
public ApiEndpoint(String name, JsonNode postNode) {
this.name = name;
this.parameters = new HashMap<>();
postNode.path("parameters").forEach(paramNode -> {
String paramName = paramNode.path("name").asText();
parameters.put(paramName, paramNode);
});
this.description = postNode.path("description").asText();
}
public boolean areParametersValid(Map<String, Object> providedParams) {
for (String requiredParam : parameters.keySet()) {
if (!providedParams.containsKey(requiredParam)) {
return false;
}
}
return true;
}
public String getDescription() {
return description;
}
@Override
public String toString() {
return "ApiEndpoint [name=" + name + ", parameters=" + parameters + "]";
}
}

View File

@@ -106,6 +106,25 @@ public class ApplicationProperties {
private Boolean enableLogin;
private Boolean csrfDisabled;
private InitialLogin initialLogin;
private int loginAttemptCount;
private long loginResetTimeMinutes;
public int getLoginAttemptCount() {
return loginAttemptCount;
}
public void setLoginAttemptCount(int loginAttemptCount) {
this.loginAttemptCount = loginAttemptCount;
}
public long getLoginResetTimeMinutes() {
return loginResetTimeMinutes;
}
public void setLoginResetTimeMinutes(long loginResetTimeMinutes) {
this.loginResetTimeMinutes = loginResetTimeMinutes;
}
public InitialLogin getInitialLogin() {
return initialLogin != null ? initialLogin : new InitialLogin();
@@ -175,6 +194,19 @@ public class ApplicationProperties {
private String rootURIPath;
private String customStaticFilePath;
private Integer maxFileSize;
private Boolean enableAlphaFunctionality;
public Boolean getEnableAlphaFunctionality() {
return enableAlphaFunctionality;
}
public void setEnableAlphaFunctionality(Boolean enableAlphaFunctionality) {
this.enableAlphaFunctionality = enableAlphaFunctionality;
}
public String getDefaultLocale() {
return defaultLocale;
@@ -218,12 +250,13 @@ public class ApplicationProperties {
@Override
public String toString() {
return "System [defaultLocale=" + defaultLocale + ", googlevisibility=" + googlevisibility + ", rootURIPath="
+ rootURIPath + ", customStaticFilePath=" + customStaticFilePath + ", maxFileSize=" + maxFileSize
+ "]";
return "System [defaultLocale=" + defaultLocale + ", googlevisibility=" + googlevisibility
+ ", rootURIPath=" + rootURIPath + ", customStaticFilePath=" + customStaticFilePath
+ ", maxFileSize=" + maxFileSize + ", enableAlphaFunctionality=" + enableAlphaFunctionality + "]";
}
}
public static class Ui {

View File

@@ -0,0 +1,27 @@
package stirling.software.SPDF.model;
public class AttemptCounter {
private int attemptCount;
private long lastAttemptTime;
public AttemptCounter() {
this.attemptCount = 1;
this.lastAttemptTime = System.currentTimeMillis();
}
public void increment() {
this.attemptCount++;
this.lastAttemptTime = System.currentTimeMillis();
}
public int getAttemptCount() {
return attemptCount;
}
public long getlastAttemptTime() {
return lastAttemptTime;
}
public boolean shouldReset(long ATTEMPT_INCREMENT_TIME) {
return System.currentTimeMillis() - lastAttemptTime > ATTEMPT_INCREMENT_TIME;
}
}

View File

@@ -14,8 +14,13 @@ public enum Role {
EXTRA_LIMITED_API_USER("ROLE_EXTRA_LIMITED_API_USER", 20, 20),
// 0 API calls per day and 20 web calls
WEB_ONLY_USER("ROLE_WEB_ONLY_USER", 0, 20);
WEB_ONLY_USER("ROLE_WEB_ONLY_USER", 0, 20),
INTERNAL_API_USER("STIRLING-PDF-BACKEND-API-USER", Integer.MAX_VALUE, Integer.MAX_VALUE),
DEMO_USER("ROLE_DEMO_USER", 100, 100);
private final String roleId;
private final int apiCallsPerDay;
private final int webCallsPerDay;

View File

@@ -13,8 +13,8 @@ import lombok.NoArgsConstructor;
public class HandleDataRequest {
@Schema(description = "The input files")
private MultipartFile[] fileInputs;
private MultipartFile[] fileInput;
@Schema(description = "JSON String")
private String jsonString;
private String json;
}

View File

@@ -5,6 +5,7 @@ import java.util.List;
import org.apache.pdfbox.pdmodel.PDDocument;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -18,7 +19,7 @@ public class PDFWithPageNums extends PDFFile {
@Schema(description = "The pages to select, Supports ranges (e.g., '1,3,5-9'), or 'all' or functions in the format 'an+b' where 'a' is the multiplier of the page number 'n', and 'b' is a constant (e.g., '2n+1', '3n', '6n-5')\"")
private String pageNumbers;
@Hidden
public List<Integer> getPageNumbersList(){
int pageCount = 0;
try {
@@ -30,6 +31,8 @@ public class PDFWithPageNums extends PDFFile {
return GeneralUtils.parsePageString(pageNumbers, pageCount);
}
@Hidden
public List<Integer> getPageNumbersList(PDDocument doc){
int pageCount = 0;
pageCount = doc.getNumberOfPages();

View File

@@ -0,0 +1,16 @@
package stirling.software.SPDF.model.api;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper=true)
public class SplitPdfBySectionsRequest extends PDFFile {
@Schema(description = "Number of horizontal divisions for each PDF page", example = "2")
private int horizontalDivisions;
@Schema(description = "Number of vertical divisions for each PDF page", example = "2")
private int verticalDivisions;
}

View File

@@ -0,0 +1,18 @@
package stirling.software.SPDF.model.api.extract;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.SPDF.model.api.PDFFile;
@Data
@EqualsAndHashCode(callSuper=true)
public class PDFFilePage extends PDFFile {
@Schema(description = "Number of chosen page", type = "number")
private int pageId;
}

View File

@@ -0,0 +1,24 @@
package stirling.software.SPDF.model.api.general;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.SPDF.model.api.PDFFile;
@Data
@EqualsAndHashCode(callSuper = true)
public class OverlayPdfsRequest extends PDFFile {
@Schema(description = "An array of PDF files to be used as overlays on the base PDF. The order in these files is applied based on the selected mode.")
private MultipartFile[] overlayFiles;
@Schema(description = "The mode of overlaying: 'SequentialOverlay' for sequential application, 'InterleavedOverlay' for round-robin application, 'FixedRepeatOverlay' for fixed repetition based on provided counts", required = true)
private String overlayMode;
@Schema(description = "An array of integers specifying the number of times each corresponding overlay file should be applied in the 'FixedRepeatOverlay' mode. This should match the length of the overlayFiles array.", required = false)
private int[] counts;
@Schema(description = "Overlay position 0 is Foregound, 1 is Background")
private int overlayPosition;
}

View File

@@ -3,7 +3,6 @@ package stirling.software.SPDF.model.api.general;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.SPDF.model.api.PDFFile;
import stirling.software.SPDF.model.api.PDFWithPageSize;
@Data

View File

@@ -0,0 +1,18 @@
package stirling.software.SPDF.model.api.general;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.SPDF.model.api.PDFFile;
@Data
@EqualsAndHashCode(callSuper=true)
public class SplitPdfBySizeOrCountRequest extends PDFFile {
@Schema(description = "Determines the type of split: 0 for size, 1 for page count, 2 for document count", required = false, defaultValue = "0")
private int splitType;
@Schema(description = "Value for split: size in MB (e.g., '10MB') or number of pages (e.g., '5')", required = false, defaultValue = "10MB")
private String splitValue;
}

View File

@@ -1,6 +1,9 @@
package stirling.software.SPDF.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.FileVisitResult;
@@ -12,6 +15,7 @@ import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
public class GeneralUtils {
public static void deleteDirectory(Path path) throws IOException {
@@ -48,6 +52,18 @@ public class GeneralUtils {
}
}
public static File multipartToFile(MultipartFile multipart) throws IOException {
Path tempFile = Files.createTempFile("overlay-", ".pdf");
try (InputStream in = multipart.getInputStream();
FileOutputStream out = new FileOutputStream(tempFile.toFile())) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return tempFile.toFile();
}
public static Long convertSizeToBytes(String sizeStr) {
if (sizeStr == null) {

View File

@@ -4,19 +4,18 @@ import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
@@ -199,36 +198,56 @@ public class PdfUtils {
try (PDDocument document = PDDocument.load(new ByteArrayInputStream(inputStream))) {
PDFRenderer pdfRenderer = new PDFRenderer(document);
int pageCount = document.getNumberOfPages();
List<BufferedImage> images = new ArrayList<>();
// Create images of all pages
for (int i = 0; i < pageCount; i++) {
images.add(pdfRenderer.renderImageWithDPI(i, DPI, colorType));
}
if (singleImage) {
// Combine all images into a single big image
BufferedImage combined = new BufferedImage(images.get(0).getWidth(), images.get(0).getHeight() * pageCount, BufferedImage.TYPE_INT_RGB);
Graphics g = combined.getGraphics();
for (int i = 0; i < images.size(); i++) {
g.drawImage(images.get(i), 0, i * images.get(0).getHeight(), null);
}
images = Arrays.asList(combined);
}
// Create a ByteArrayOutputStream to save the image(s) to
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (singleImage) {
// Write the image to the output stream
ImageIO.write(images.get(0), imageType, baos);
if (imageType.toLowerCase().equals("tiff") || imageType.toLowerCase().equals("tif")) {
// Write the images to the output stream as a TIFF with multiple frames
ImageWriter writer = ImageIO.getImageWritersByFormatName("tiff").next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionType("ZLib");
param.setCompressionQuality(1.0f);
try (ImageOutputStream ios = ImageIO.createImageOutputStream(baos)) {
writer.setOutput(ios);
writer.prepareWriteSequence(null);
for (int i = 0; i < pageCount; ++i) {
BufferedImage image = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
writer.writeToSequence(new IIOImage(image, null, null), param);
}
writer.endWriteSequence();
}
writer.dispose();
} else {
// Combine all images into a single big image
BufferedImage image = pdfRenderer.renderImageWithDPI(0, DPI, colorType);
BufferedImage combined = new BufferedImage(image.getWidth(), image.getHeight() * pageCount, BufferedImage.TYPE_INT_RGB);
Graphics g = combined.getGraphics();
for (int i = 0; i < pageCount; ++i) {
if (i != 0) {
image = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
}
g.drawImage(image, 0, i * image.getHeight(), null);
}
// Write the image to the output stream
ImageIO.write(combined, imageType, baos);
}
// Log that the image was successfully written to the byte array
logger.info("Image successfully written to byte array");
} else {
// Zip the images and return as byte array
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
for (int i = 0; i < images.size(); i++) {
BufferedImage image = images.get(i);
for (int i = 0; i < pageCount; ++i) {
BufferedImage image = pdfRenderer.renderImageWithDPI(i, DPI, colorType);
try (ByteArrayOutputStream baosImage = new ByteArrayOutputStream()) {
ImageIO.write(image, imageType, baosImage);
@@ -264,28 +283,13 @@ public class PdfUtils {
addImageToDocument(doc, pdImage, fitOption, autoRotate);
}
} else {
File imageFile = Files.createTempFile("image", ".png").toFile();
try (FileOutputStream fos = new FileOutputStream(imageFile); InputStream input = file.getInputStream()) {
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
BufferedImage image = ImageIO.read(imageFile);
BufferedImage convertedImage = ImageProcessingUtils.convertColorType(image, colorType);
PDImageXObject pdImage;
if (contentType != null && (contentType.equals("image/jpeg"))) {
pdImage = JPEGFactory.createFromImage(doc, convertedImage);
} else {
pdImage = LosslessFactory.createFromImage(doc, convertedImage);
}
addImageToDocument(doc, pdImage, fitOption, autoRotate);
} catch (IOException e) {
logger.error("Error writing image to file: {}", imageFile.getAbsolutePath(), e);
throw e;
} finally {
imageFile.delete();
}
BufferedImage image = ImageIO.read(file.getInputStream());
BufferedImage convertedImage = ImageProcessingUtils.convertColorType(image, colorType);
// Use JPEGFactory if it's JPEG since JPEG is lossy
PDImageXObject pdImage = (contentType != null && contentType.equals("image/jpeg"))
? JPEGFactory.createFromImage(doc, convertedImage)
: LosslessFactory.createFromImage(doc, convertedImage);
addImageToDocument(doc, pdImage, fitOption, autoRotate);
}
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

View File

@@ -0,0 +1,16 @@
package stirling.software.SPDF.utils;
public class RequestUriUtils {
public static boolean isStaticResource(String requestURI) {
return requestURI.startsWith("/css/")
|| requestURI.startsWith("/js/")
|| requestURI.startsWith("/images/")
|| requestURI.startsWith("/public/")
|| requestURI.startsWith("/pdfjs/")
|| requestURI.endsWith(".svg");
}
}

View File

@@ -35,7 +35,7 @@ spring.datasource.url=jdbc:h2:file:./configs/stirling-pdf-DB;DB_CLOSE_DELAY=-1;D
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
spring.h2.console.enabled=false
spring.jpa.hibernate.ddl-auto=update
# Change the default URL path for OpenAPI JSON

View File

@@ -0,0 +1,6 @@
____ _____ ___ ____ _ ___ _ _ ____ ____ ____ _____
/ ___|_ _|_ _| _ \| | |_ _| \ | |/ ___| | _ \| _ \| ___|
\___ \ | | | || |_) | | | || \| | | _ _____| |_) | | | | |_
___) || | | || _ <| |___ | || |\ | |_| |_____| __/| |_| | _|
|____/ |_| |___|_| \_\_____|___|_| \_|\____| |_| |____/|_|
Powered by Spring Boot ${spring-boot.version}

View File

@@ -1,8 +0,0 @@
log4j.rootLogger=ERROR,stdout
log4j.logger.com.endeca=INFO
# Logger for crawl metrics
log4j.logger.com.endeca.itl.web.metrics=INFO
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%p\t%d{ISO8601}\t%r\t%c\t[%t]\t%m%n

View File

@@ -0,0 +1,51 @@
<configuration>
<!-- Console Appender -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Rolling File Appender -->
<appender name="AUTHLOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/invalid-auths.log</file>
<encoder>
<pattern>%d %p %c{1} [%thread] %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover and keep 7 days' worth of history -->
<fileNamePattern>logs/auth-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>1</maxHistory>
</rollingPolicy>
</appender>
<!-- Rolling File Appender -->
<appender name="GENERAL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/info.log</file>
<encoder>
<pattern>%d %p %c{1} [%thread] %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover and keep 7 days' worth of history -->
<fileNamePattern>logs/info-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>1</maxHistory>
</rollingPolicy>
</appender>
<!-- Root Logger -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="GENERAL"/>
</root>
<!-- Specific Logger -->
<logger name="stirling.software.SPDF.config.security.CustomAuthenticationFailureHandler" level="ERROR" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="AUTHLOG"/>
</logger>
</configuration>

View File

@@ -119,6 +119,7 @@ adminUserSettings.role=Role
adminUserSettings.actions=Actions
adminUserSettings.apiUser=Limited API User
adminUserSettings.webOnlyUser=Web Only User
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Force user to change username/password on login
adminUserSettings.submit=Save User
@@ -126,8 +127,13 @@ adminUserSettings.submit=Save User
# HOME-PAGE #
#############
home.desc=متجرك الشامل المستضاف محليًا لجميع احتياجات PDF الخاصة بك.
home.searchBar=Search for features...
home.viewPdf.title=View PDF
home.viewPdf.desc=View, annotate, add text or images
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=أداة متعددة PDF
home.multiTool.desc=دمج الصفحات وتدويرها وإعادة ترتيبها وإزالتها
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
@@ -250,6 +256,10 @@ home.removeBlanks.title=إزالة الصفحات الفارغة
home.removeBlanks.desc=يكتشف ويزيل الصفحات الفارغة من المستند
removeBlanks.tags=cleanup,streamline,non-content,organize
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=قارن
home.compare.desc=يقارن ويظهر الاختلافات بين 2 من مستندات PDF
compare.tags=differentiate,contrast,changes,analysis
@@ -331,6 +341,24 @@ home.autoRedact.title=Auto Redact
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
showJS.tags=JS
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -478,9 +506,6 @@ pipeline.title=Pipeline
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
##########################
### TODO: Translate ###
##########################
pageLayout.addBorder=Add Borders
pageLayout.submit=Submit
@@ -519,6 +544,12 @@ removeBlanks.whitePercentDesc=النسبة المئوية للصفحة التي
removeBlanks.submit=إزالة الفراغات
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=يقارن
compare.header=قارن ملفات PDF
@@ -635,6 +666,9 @@ pdfOrganiser.submit=إعادة ترتيب الصفحات
multiTool.title=أداة متعددة PDF
multiTool.header=أداة متعددة PDF
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=مزيل الصفحة
@@ -818,3 +852,45 @@ PDFToXML.title=تحويل PDF إلى XML
PDFToXML.header=تحويل PDF إلى XML
PDFToXML.credit=تستخدم هذه الخدمة LibreOffice لتحويل الملفات.
PDFToXML.submit=تحويل
#PDFToCSV
PDFToCSV.title=PDF ??? CSV
PDFToCSV.header=PDF ??? CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=??????
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -1,7 +1,7 @@
###########
# Generic #
###########
# the direction that the language is written (ltr = left to right, rtl = right to left)
# the direction that the language is written (ltr=left to right, rtl = right to left)
language.direction=ltr
pdfPrompt=Изберете PDF(и)
@@ -25,7 +25,7 @@ downloadPdf=Изтеглете PDF
text=Текст
font=Шрифт
selectFillter=-- Изберете --
pageNum=Брой страница
pageNum=Брой страница
sizes.small=Малък
sizes.medium=Среден
sizes.large=Голям
@@ -92,7 +92,7 @@ account.title=Настройки на акаунта
account.accountSettings=Настройки на акаунта
account.adminSettings=Настройки на администратора - Преглед и добавяне на потребители
account.userControlSettings=Настройки за потребителски контрол
account.changeUsername=Нов потребител
account.changeUsername=Промени потребител
account.changeUsername=Промени потребител
account.password=Парола за потвърждение
account.oldPassword=Стара парола
@@ -119,15 +119,21 @@ adminUserSettings.role=Роля
adminUserSettings.actions=Действия
adminUserSettings.apiUser=Ограничен API потребител
adminUserSettings.webOnlyUser=Само за уеб-потребител
adminUserSettings.forceChange = Принудете потребителя да промени потребителското име/парола при влизане
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Принудете потребителя да промени потребителското име/парола при влизане
adminUserSettings.submit=Съхранете потребителя
#############
# HOME-PAGE #
#############
home.desc=Вашето локално хоствано обслужване на едно място за всички ваши PDF нужди.
home.searchBar=Search for features...
home.viewPdf.title=View PDF
home.viewPdf.desc=View, annotate, add text or images
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=PDF Мулти инструмент
home.multiTool.desc=Обединяване, завъртане, пренареждане и премахване на страници
multiTool.tags=Мултиинструмент,Мулти операции,UI,плъзгане с щракване,потребителска част,страна на клиента,интерактивен,неразрешим,преместване
@@ -250,6 +256,10 @@ home.removeBlanks.title=Премахване на празни страници
home.removeBlanks.desc=Открива и премахва празни страници от документ
removeBlanks.tags=почистване,рационализиране,без съдържание,организиране
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Сравнете
home.compare.desc=Сравнява и показва разликите между 2 PDF документа
compare.tags=разграничаване,контраст,промени,анализ
@@ -325,12 +335,30 @@ PdfToSinglePage.tags=единична страница
home.showJS.title=Показване на Javascript
home.showJS.desc=Търси и показва всеки JS, инжектиран в PDF
showJS.tags=JS
showJS.tags=Редактиране,Скриване,затъмняване,черен,маркер,скрит
home.autoRedact.title=Автоматично редактиране
home.autoRedact.desc=Автоматично редактира (зачернява) текст в PDF въз основа на въведен текст
showJS.tags=Редактиране,Скриване,затъмняване,черен,маркер,скрит
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -372,9 +400,9 @@ pdfToSinglePage.submit=Преобразуване към единична стр
#pageExtracter
pageExtrater.title=Извличане на страници
pageExtrater.header=Извличане на страници
pageExtrater.submit=Извличане
pageExtracter.title=Extract Pages
pageExtracter.header=Extract Pages
pageExtracter.submit=Extract
#getPdfInfo
@@ -516,6 +544,12 @@ removeBlanks.whitePercentDesc=Процент от страницата, коят
removeBlanks.submit=Премахване на празни места
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Сравнявай
compare.header=Сравнявай PDF-и
@@ -632,6 +666,9 @@ pdfOrganiser.submit=Пренареждане на страниците
multiTool.title=PDF Мулти инструмент
multiTool.header=PDF Мулти инструмент
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=Премахване на страници
@@ -753,7 +790,7 @@ removePassword.submit=Премахване
#changeMetadata
changeMetadata.title=Промени метаданните
changeMetadata.title=Заглавие:
changeMetadata.header=Промени метаданните
changeMetadata.selectText.1=Моля, редактирайте променливите, които искате да промените
changeMetadata.selectText.2=Изтрий всички метаданни
@@ -814,4 +851,46 @@ PDFToHTML.submit=Преобразуване
PDFToXML.title=PDF към XML
PDFToXML.header=PDF към XML
PDFToXML.credit=Тази услуга използва LibreOffice за преобразуване на файлове.
PDFToXML.submit=Преобразуване
PDFToXML.submit=Преобразуване
#PDFToCSV
PDFToCSV.title=PDF ??? CSV
PDFToCSV.header=PDF ??? CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=????????
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -119,6 +119,7 @@ adminUserSettings.role=Rol
adminUserSettings.actions=Accions
adminUserSettings.apiUser=Usuari amb API limitada
adminUserSettings.webOnlyUser=Usuari només WEB
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Force user to change username/password on login
adminUserSettings.submit=Desar Usuari
@@ -126,8 +127,13 @@ adminUserSettings.submit=Desar Usuari
# HOME-PAGE #
#############
home.desc=L'eina allotjada localment per a necessitats PDF.
home.searchBar=Search for features...
home.viewPdf.title=View PDF
home.viewPdf.desc=View, annotate, add text or images
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=PDF Multi Tool
home.multiTool.desc=Fusiona, Rota, Reorganitza, i Esborra pàgines
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
@@ -250,6 +256,10 @@ home.removeBlanks.title=Elimina les pàgines en blanc
home.removeBlanks.desc=Detecta i elimina les pàgines en blanc d'un document
removeBlanks.tags=cleanup,streamline,non-content,organize
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Compara
home.compare.desc=Compara i mostra les diferències entre 2 documents PDF
compare.tags=differentiate,contrast,changes,analysis
@@ -331,6 +341,24 @@ home.autoRedact.title=Auto Redact
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
showJS.tags=JS
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -478,9 +506,6 @@ pipeline.title=Pipeline
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
##########################
### TODO: Translate ###
##########################
pageLayout.addBorder=Add Borders
pageLayout.submit=Submit
@@ -519,6 +544,12 @@ removeBlanks.whitePercentDesc=Percentatge de pàgina que ha de ser blanca per el
removeBlanks.submit=Elimina els espais en blanc
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Comparar
compare.header=Compara PDF
@@ -635,6 +666,9 @@ pdfOrganiser.submit=Reorganitza Pàgines
multiTool.title=PDF Multi Tool
multiTool.header=PDF Multi Tool
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=Eliminació Pàgines
@@ -818,3 +852,45 @@ PDFToXML.title=PDF a XML
PDFToXML.header=PDF a XML
PDFToXML.credit=Utilitza LibreOffice per a la conversió d'Arxius.
PDFToXML.submit=Converteix
#PDFToCSV
PDFToCSV.title=PDF a CSV
PDFToCSV.header=PDF a CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extracte
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -43,11 +43,11 @@ green=Grün
blue=Blau
custom=benutzerdefiniert...
changedCredsMessage=Credentials changed!
notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists.
changedCredsMessage=Anmeldedaten geändert!
notAuthenticatedMessage=Benutzer nicht authentifiziert.
userNotFoundMessage=Benutzer nicht gefunden.
incorrectPasswordMessage=Das Passwort ist falsch.
usernameExistsMessage=Neuer Benutzername existiert bereits.
@@ -77,14 +77,14 @@ settings.accountSettings=Kontoeinstellungen
changeCreds.title=Change Credentials
changeCreds.header=Update Your Account Details
changeCreds.changeUserAndPassword=You are using default login credentials. Please enter a new password (and username if wanted)
changeCreds.newUsername=New Username
changeCreds.oldPassword=Current Password
changeCreds.newPassword=New Password
changeCreds.confirmNewPassword=Confirm New Password
changeCreds.submit=Submit Changes
changeCreds.title=Anmeldeinformationen ändern
changeCreds.header=Aktualisieren Sie Ihre Kontodaten
changeCreds.changeUserAndPassword=Sie verwenden Standard-Anmeldeinformationen. Bitte geben Sie ein neues Passwort (und ggf. einen Benutzernamen) ein.
changeCreds.newUsername=Neuer Benutzername
changeCreds.oldPassword=Aktuelles Passwort
changeCreds.newPassword=Neues Passwort
changeCreds.confirmNewPassword=Neues Passwort bestätigen
changeCreds.submit=Änderung speichern
@@ -92,8 +92,8 @@ account.title=Kontoeinstellungen
account.accountSettings=Kontoeinstellungen
account.adminSettings=Admin Einstellungen - Benutzer anzeigen und hinzufügen
account.userControlSettings=Benutzerkontrolle
account.changeUsername=Passwort ändern
account.changeUsername=Passwort ändern
account.changeUsername=Benutzername ändern
account.changeUsername=Benutzername ändern
account.password=Bestätigungspasswort
account.oldPassword=Altes Passwort
account.newPassword=Neues Passwort
@@ -119,15 +119,21 @@ adminUserSettings.role=Rolle
adminUserSettings.actions=Aktion
adminUserSettings.apiUser=Eingeschränkter API-Benutzer
adminUserSettings.webOnlyUser=Nur Web-Benutzer
adminUserSettings.forceChange=Force user to change username/password on login
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Benutzer dazu zwingen, Benutzernamen/Passwort bei der Anmeldung zu ändern
adminUserSettings.submit=Benutzer speichern
#############
# HOME-PAGE #
#############
home.desc=Ihr lokal gehosteter One-Stop-Shop für alle Ihre PDF-Anforderungen.
home.searchBar=Suche nach Funktionen...
home.viewPdf.title=PDF anzeigen
home.viewPdf.desc=Anzeigen, Kommentieren, Text oder Bilder hinzufügen
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=PDF-Multitool
home.multiTool.desc=Seiten zusammenführen, drehen, neu anordnen und entfernen
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
@@ -250,6 +256,10 @@ home.removeBlanks.title=Leere Seiten entfernen
home.removeBlanks.desc=Erkennt und entfernt leere Seiten aus einem Dokument
removeBlanks.tags=cleanup,streamline,non-content,organize
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Vergleichen
home.compare.desc=Vergleicht und zeigt die Unterschiede zwischen zwei PDF-Dokumenten an
compare.tags=differentiate,contrast,changes,analysis
@@ -328,9 +338,27 @@ home.showJS.desc=Alle Javascript Funktionen in einer PDF anzeigen
showJS.tags=JS
home.autoRedact.title=Automatisch zensieren/schwärzen
home.autoRedact.desc=Automatisches zensiertes (Schwärzen) von Text in einer PDF-Datei basierend auf dem eingegebenen Text
home.autoRedact.desc=Automatisches zensierten (Schwärzen) von Text in einer PDF-Datei basierend auf dem eingegebenen Text
showJS.tags=JS
home.tableExtraxt.title=Tabelle extrahieren
home.tableExtraxt.desc=Tabelle aus PDF in CSV extrahieren
tableExtraxt.tags=CSV
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -430,7 +458,7 @@ addPageNumbers.selectText.5=Seiten zu nummerieren
addPageNumbers.selectText.6=Benutzerdefinierter Text
addPageNumbers.customTextDesc=Benutzerdefinierter Text
addPageNumbers.numberPagesDesc=Welche Seiten nummeriert werden sollen, Standardeinstellung 'alle' ('all'), akzeptiert auch 1-5 oder 2,5,9 usw.
addPageNumbers.customNumberDesc=Standardmäßig {n}, akzeptiert auch 'Seite {n} von {insgesamt}', 'Text-{n}', '{Dateiname}-{n} ('{filename}-{n})
addPageNumbers.customNumberDesc=Standardmäßig {n}, akzeptiert auch 'Seite {n} von {total}', 'Text-{n}', '{filename}-{n}'
addPageNumbers.submit=Seitenzahlen hinzufügen
@@ -478,9 +506,6 @@ pipeline.title=Pipeline
pageLayout.title=Mehrseitiges Layout
pageLayout.header=Mehrseitiges Layout
pageLayout.pagesPerSheet=Seiten pro Blatt:
##########################
### TODO: Translate ###
##########################
pageLayout.addBorder=Add Borders
pageLayout.submit=Abschicken
@@ -519,6 +544,12 @@ removeBlanks.whitePercentDesc=Prozentsatz der Seite, die weiß sein muss, um ent
removeBlanks.submit=Leere Seiten entfernen
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Vergleichen
compare.header=PDFs vergleichen
@@ -635,6 +666,9 @@ pdfOrganiser.submit=Seiten anordnen
multiTool.title=PDF-Multitool
multiTool.header=PDF-Multitool
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=Seiten entfernen
@@ -818,3 +852,45 @@ PDFToXML.title=PDF in XML
PDFToXML.header=PDF in XML
PDFToXML.credit=Dieser Dienst verwendet LibreOffice für die Dateikonvertierung.
PDFToXML.submit=Konvertieren
#PDFToCSV
PDFToCSV.title=PDF zu CSV
PDFToCSV.header=PDF zu CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extrakt
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -1,7 +1,7 @@
###########
# Generic #
###########
# the direction that the language is written (ltr = left to right, rtl = right to left)
# the direction that the language is written (ltr=left to right, rtl = right to left)
language.direction=ltr
pdfPrompt=\u0395\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE PDF(s)
@@ -92,7 +92,7 @@ account.title=\u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2 \u039B\u03B
account.accountSettings=\u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2 \u039B\u03BF\u03B3\u03B1\u03C1\u03B9\u03B1\u03C3\u03BC\u03BF\u03CD
account.adminSettings=\u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2 \u0394\u03B9\u03B1\u03C7\u03B5\u03B9\u03C1\u03B9\u03C3\u03C4\u03AE - \u03A0\u03C1\u03BF\u03B2\u03BF\u03BB\u03AE \u03BA\u03B1\u03B9 \u03C0\u03C1\u03BF\u03C3\u03B8\u03AE\u03BA\u03B7 \u03C7\u03C1\u03B7\u03C3\u03C4\u03CE\u03BD
account.userControlSettings=\u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2 \u03A7\u03B5\u03B9\u03C1\u03B9\u03C3\u03BC\u03BF\u03CD \u03A7\u03C1\u03B7\u03C3\u03C4\u03CE\u03BD
account.changeUsername=\u039D\u03AD\u03BF \u038C\u03BD\u03BF\u03BC\u03B1 \u03A7\u03C1\u03AE\u03C3\u03C4\u03B7
account.changeUsername=\u0391\u03BB\u03BB\u03B1\u03B3\u03AE \u039F\u03BD\u03CC\u03BC\u03B1\u03C4\u03BF\u03C2 \u03A7\u03C1\u03AE\u03C3\u03C4\u03B7
account.changeUsername=\u0391\u03BB\u03BB\u03B1\u03B3\u03AE \u039F\u03BD\u03CC\u03BC\u03B1\u03C4\u03BF\u03C2 \u03A7\u03C1\u03AE\u03C3\u03C4\u03B7
account.password=\u0395\u03C0\u03B9\u03B2\u03B5\u03B2\u03B1\u03AF\u03C9\u03C3\u03B7 \u039A\u03C9\u03B4\u03B9\u03BA\u03BF\u03CD \u03A0\u03C1\u03CC\u03C3\u03B2\u03B1\u03C3\u03B7\u03C2
account.oldPassword=\u03A0\u03B1\u03BB\u03B9\u03CC\u03C2 \u039A\u03C9\u03B4\u03B9\u03BA\u03CC\u03C2 \u03A0\u03C1\u03CC\u03C3\u03B2\u03B1\u03C3\u03B7\u03C2
@@ -106,10 +106,10 @@ account.settingsCompare=\u03A3\u03CD\u03B3\u03BA\u03C1\u03B9\u03C3\u03B7 \u03A1\
account.property=Property
account.webBrowserSettings=\u03A1\u03CD\u03B8\u03BC\u03B9\u03C3\u03B7 \u03C6\u03C5\u03BB\u03BB\u03BF\u03BC\u03B5\u03C4\u03C1\u03B7\u03C4\u03AE (Web Browser)
account.syncToBrowser=\u03A3\u03C5\u03B3\u03C7\u03C1\u03BF\u03BD\u03B9\u03C3\u03BC\u03CC\u03C2 \u039B\u03BF\u03B3\u03B1\u03C1\u03B9\u03B1\u03C3\u03BC\u03BF\u03CD -> \u03A6\u03C5\u03BB\u03BB\u03BF\u03BC\u03B5\u03C4\u03C1\u03B7\u03C4\u03AE (Web Browser)
account.syncToAccount= \u03A3\u03C5\u03B3\u03C7\u03C1\u03BF\u03BD\u03B9\u03C3\u03BC\u03CC\u03C2 \u039B\u03BF\u03B3\u03B1\u03C1\u03B9\u03B1\u03C3\u03BC\u03BF\u03CD <- \u03A6\u03C5\u03BB\u03BB\u03BF\u03BC\u03B5\u03C4\u03C1\u03B7\u03C4\u03AE (Web Browser)
account.syncToAccount=\u03A3\u03C5\u03B3\u03C7\u03C1\u03BF\u03BD\u03B9\u03C3\u03BC\u03CC\u03C2 \u039B\u03BF\u03B3\u03B1\u03C1\u03B9\u03B1\u03C3\u03BC\u03BF\u03CD <- \u03A6\u03C5\u03BB\u03BB\u03BF\u03BC\u03B5\u03C4\u03C1\u03B7\u03C4\u03AE (Web Browser)
adminUserSettings.title= \u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2 \u03B5\u03BB\u03AD\u03B3\u03C7\u03BF\u03C5 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7
adminUserSettings.title=\u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2 \u03B5\u03BB\u03AD\u03B3\u03C7\u03BF\u03C5 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7
adminUserSettings.header=\u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2 \u03B5\u03BB\u03AD\u03B3\u03C7\u03BF\u03C5 \u0394\u03B9\u03B1\u03C7\u03B5\u03B9\u03C1\u03B9\u03C3\u03C4\u03AE
adminUserSettings.admin=\u0394\u03B9\u03B1\u03C7\u03B5\u03B9\u03C1\u03B9\u03C3\u03C4\u03AE\u03C2
adminUserSettings.user=\u03A7\u03C1\u03AE\u03C3\u03C4\u03B7\u03C2
@@ -119,15 +119,21 @@ adminUserSettings.role=\u03A1\u03CC\u03BB\u03BF\u03C2
adminUserSettings.actions=\u0395\u03BD\u03AD\u03C1\u03B3\u03B5\u03B9\u03B5\u03C2
adminUserSettings.apiUser=\u03A0\u03B5\u03C1\u03B9\u03BF\u03C1\u03B9\u03C3\u03BC\u03AD\u03BD\u03BF\u03C2 \u03A7\u03C1\u03AE\u03C3\u03C4\u03B7\u03C2 \u03B3\u03B9\u03B1 \u03B4\u03B9\u03B5\u03C0\u03B1\u03C6\u03AE \u03C0\u03C1\u03BF\u03B3\u03C1\u03B1\u03BC\u03BC\u03B1\u03C4\u03B9\u03C3\u03BC\u03BF\u03CD \u03B5\u03C6\u03B1\u03C1\u03BC\u03BF\u03B3\u03CE\u03BD (API User)
adminUserSettings.webOnlyUser=\u03A7\u03C1\u03AE\u03C3\u03C4\u03B7\u03C2 \u03BC\u03CC\u03BD\u03BF \u0399\u03C3\u03C4\u03BF\u03CD
adminUserSettings.forceChange = \u0391\u03BD\u03B1\u03B3\u03BA\u03AC\u03C3\u03C4\u03B5 \u03C4\u03BF\u03BD \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7 \u03BD\u03B1 \u03B1\u03BB\u03BB\u03AC\u03BE\u03B5\u03B9 \u03C4\u03BF \u03CC\u03BD\u03BF\u03BC\u03B1 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7/\u03BA\u03C9\u03B4\u03B9\u03BA\u03CC \u03C0\u03C1\u03CC\u03C3\u03B2\u03B1\u03C3\u03B7\u03C2 \u03BA\u03B1\u03C4\u03AC \u03C4\u03B7 \u03C3\u03CD\u03BD\u03B4\u03B5\u03C3\u03B7
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=\u0391\u03BD\u03B1\u03B3\u03BA\u03AC\u03C3\u03C4\u03B5 \u03C4\u03BF\u03BD \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7 \u03BD\u03B1 \u03B1\u03BB\u03BB\u03AC\u03BE\u03B5\u03B9 \u03C4\u03BF \u03CC\u03BD\u03BF\u03BC\u03B1 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B7/\u03BA\u03C9\u03B4\u03B9\u03BA\u03CC \u03C0\u03C1\u03CC\u03C3\u03B2\u03B1\u03C3\u03B7\u03C2 \u03BA\u03B1\u03C4\u03AC \u03C4\u03B7 \u03C3\u03CD\u03BD\u03B4\u03B5\u03C3\u03B7
adminUserSettings.submit=\u0391\u03C0\u03BF\u03B8\u03AE\u03BA\u03B5\u03C5\u03C3\u03B7 \u03A7\u03C1\u03AE\u03C3\u03C4\u03B7
#############
# HOME-PAGE #
#############
home.desc= \u0397 \u03C4\u03BF\u03C0\u03B9\u03BA\u03AC \u03C6\u03B9\u03BB\u03BF\u03BE\u03B5\u03BD\u03BF\u03CD\u03BC\u03B5\u03BD\u03B7 one-stop-shop \u03C3\u03B1\u03C2 \u03B3\u03B9\u03B1 \u03CC\u03BB\u03B5\u03C2 \u03C4\u03B9\u03C2 \u03B1\u03BD\u03AC\u03B3\u03BA\u03B5\u03C2 \u03C3\u03B1\u03C2 \u03C3\u03B5 PDF.
home.desc=\u0397 \u03C4\u03BF\u03C0\u03B9\u03BA\u03AC \u03C6\u03B9\u03BB\u03BF\u03BE\u03B5\u03BD\u03BF\u03CD\u03BC\u03B5\u03BD\u03B7 one-stop-shop \u03C3\u03B1\u03C2 \u03B3\u03B9\u03B1 \u03CC\u03BB\u03B5\u03C2 \u03C4\u03B9\u03C2 \u03B1\u03BD\u03AC\u03B3\u03BA\u03B5\u03C2 \u03C3\u03B1\u03C2 \u03C3\u03B5 PDF.
home.searchBar=Search for features...
home.viewPdf.title=\u0395\u03BC\u03C6\u03AC\u03BD\u03B9\u03C3\u03B7 PDF
home.viewPdf.desc=\u0395\u03BC\u03C6\u03AC\u03BD\u03B9\u03C3\u03B7, \u03C0\u03C1\u03BF\u03C3\u03B8\u03AE\u03BA\u03B7 \u03C3\u03C7\u03B5\u03B4\u03AF\u03BF\u03C5, \u03C0\u03C1\u03BF\u03C3\u03B8\u03AE\u03BA\u03B7 \u03BA\u03B5\u03B9\u03BC\u03AD\u03BD\u03BF\u03C5 \u03AE \u03B5\u03B9\u03BA\u03CC\u03BD\u03C9\u03BD
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=PDF \u03A0\u03BF\u03BB\u03C5\u03B5\u03C1\u03B3\u03B1\u03BB\u03B5\u03AF\u03BF
home.multiTool.desc=\u03A3\u03C5\u03B3\u03C7\u03CE\u03BD\u03B5\u03C5\u03C3\u03B7, \u03A0\u03B5\u03C1\u03B9\u03C3\u03C4\u03C1\u03BF\u03C6\u03AE, \u0391\u03BD\u03B1\u03B4\u03B9\u03AC\u03C4\u03B1\u03BE\u03B7 \u03BA\u03B1\u03B9 \u039A\u03B1\u03C4\u03AC\u03C1\u03B3\u03B7\u03C3\u03B7 \u03C3\u03B5\u03BB\u03AF\u03B4\u03C9\u03BD
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move
@@ -250,6 +256,10 @@ home.removeBlanks.title=\u0391\u03C6\u03B1\u03AF\u03C1\u03B5\u03C3\u03B7 \u03BA\
home.removeBlanks.desc=\u0391\u03BD\u03AF\u03C7\u03B5\u03C5\u03C3\u03B7 \u03BA\u03B1\u03B9 \u03B1\u03C6\u03B1\u03AF\u03C1\u03B5\u03C3\u03B7 \u03BA\u03B5\u03BD\u03CE\u03BD \u03C3\u03B5\u03BB\u03AF\u03B4\u03C9\u03BD \u03B1\u03C0\u03CC \u03AD\u03BD\u03B1 \u03AD\u03B3\u03B3\u03C1\u03B1\u03C6\u03BF
removeBlanks.tags=cleanup,streamline,non-content,organize
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=\u03A3\u03CD\u03B3\u03BA\u03C1\u03B9\u03C3\u03B7
home.compare.desc=\u03A3\u03CD\u03B3\u03BA\u03C1\u03B9\u03C3\u03B7 \u03BA\u03B1\u03B9 \u03B5\u03BC\u03C6\u03AC\u03BD\u03B9\u03C3\u03B7 \u03C4\u03C9\u03BD \u03B4\u03B9\u03B1\u03C6\u03BF\u03C1\u03CE\u03BD \u03BC\u03B5\u03C4\u03B1\u03BE\u03CD \u03B4\u03CD\u03BF PDF \u03B1\u03C1\u03C7\u03B5\u03AF\u03C9\u03BD
compare.tags=differentiate,contrast,changes,analysis
@@ -267,7 +277,7 @@ home.scalePages.desc=\u0391\u03BB\u03BB\u03B1\u03B3\u03AE \u03C4\u03BF\u03C5 \u0
scalePages.tags=resize,modify,dimension,adapt
home.pipeline.title=Pipeline (\u0393\u03B9\u03B1 \u03C0\u03C1\u03BF\u03C7\u03C9\u03C1\u03B7\u03BC\u03AD\u03BD\u03BF\u03C5\u03C2)
home.pipeline.desc= \u0395\u03BA\u03C4\u03AD\u03BB\u03B5\u03C3\u03B7 \u03C0\u03BF\u03BB\u03BB\u03B1\u03C0\u03BB\u03CE\u03BD \u03B5\u03BD\u03B5\u03C1\u03B3\u03B5\u03B9\u03CE\u03BD \u03C3\u03B5 \u03B1\u03C1\u03C7\u03B5\u03AF\u03B1 PDF \u03BF\u03C1\u03AF\u03B6\u03BF\u03BD\u03C4\u03B1\u03C2 pipeline scripts
home.pipeline.desc=\u0395\u03BA\u03C4\u03AD\u03BB\u03B5\u03C3\u03B7 \u03C0\u03BF\u03BB\u03BB\u03B1\u03C0\u03BB\u03CE\u03BD \u03B5\u03BD\u03B5\u03C1\u03B3\u03B5\u03B9\u03CE\u03BD \u03C3\u03B5 \u03B1\u03C1\u03C7\u03B5\u03AF\u03B1 PDF \u03BF\u03C1\u03AF\u03B6\u03BF\u03BD\u03C4\u03B1\u03C2 pipeline scripts
pipeline.tags=automate,sequence,scripted,batch-process
home.add-page-numbers.title=\u03A0\u03C1\u03BF\u03C3\u03B8\u03AE\u03BA\u03B7 \u03B1\u03C1\u03B9\u03B8\u03BC\u03CE\u03BD \u03C3\u03B5 \u03A3\u03B5\u03BB\u03AF\u03B4\u03B5\u03C2
@@ -325,12 +335,30 @@ PdfToSinglePage.tags=single page
home.showJS.title=\u0395\u03BC\u03C6\u03AC\u03BD\u03B9\u03C3\u03B7 Javascript
home.showJS.desc=\u0391\u03BD\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7 \u03BA\u03B1\u03B9 \u03B5\u03BC\u03C6\u03AC\u03BD\u03B9\u03C3\u03B7 \u03BA\u03CE\u03B4\u03B9\u03BA\u03B1 Javascript \u03C0\u03BF\u03C5 \u03B5\u03AF\u03BD\u03B1\u03B9 \u03B5\u03BD\u03C3\u03C9\u03BC\u03B1\u03C4\u03C9\u03BC\u03AD\u03BD\u03BF \u03BC\u03AD\u03C3\u03B1 \u03C3\u03B5 \u03AD\u03BD\u03B1 PDF
showJS.tags=JS
showJS.tags=Redact,Hide,black out,black,marker,hidden
home.autoRedact.title=\u0391\u03C5\u03C4\u03CC\u03BC\u03B1\u03C4\u03BF \u039C\u03B1\u03CD\u03C1\u03B9\u03C3\u03BC\u03B1 \u039A\u03B5\u03B9\u03BC\u03AD\u03BD\u03BF\u03C5
home.autoRedact.desc=\u0391\u03C5\u03C4\u03CC\u03BC\u03B1\u03C4\u03B7 \u03B5\u03C0\u03B5\u03BE\u03B5\u03C1\u03B3\u03B1\u03C3\u03AF\u03B1 (\u039C\u03B1\u03CD\u03C1\u03B9\u03C3\u03BC\u03B1) \u03BA\u03B5\u03AF\u03BC\u03B5\u03BD\u03BF\u03C5 \u03C3\u03B5 PDF \u03BC\u03B5 \u03B2\u03AC\u03C3\u03B7 \u03C4\u03BF \u03BA\u03B5\u03AF\u03BC\u03B5\u03BD\u03BF \u03B5\u03B9\u03C3\u03B1\u03B3\u03C9\u03B3\u03AE\u03C2
showJS.tags=Redact,Hide,black out,black,marker,hidden
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -494,15 +522,15 @@ scalePages.submit=\u03A5\u03C0\u03BF\u03B2\u03BF\u03BB\u03AE
certSign.title=\u03A5\u03C0\u03BF\u03B3\u03C1\u03B1\u03C6\u03AE \u03A0\u03B9\u03C3\u03C4\u03BF\u03C0\u03BF\u03B9\u03B7\u03C4\u03B9\u03BA\u03BF\u03CD
certSign.header=\u03A5\u03C0\u03BF\u03B3\u03C1\u03AC\u03C8\u03C4\u03B5 \u03AD\u03BD\u03B1 \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF PDF \u03BC\u03B5 \u03C4\u03BF \u03C0\u03B9\u03C3\u03C4\u03BF\u03C0\u03BF\u03B9\u03B7\u03C4\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2 (\u0395\u03C1\u03B3\u03B1\u03C3\u03AF\u03B1 \u03C3\u03B5 \u03B5\u03BE\u03AD\u03BB\u03B9\u03BE\u03B7)
certSign.selectPDF=\u0395\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF\u03C5 PDF \u03B3\u03B9\u03B1 \u03C5\u03C0\u03BF\u03B3\u03C1\u03B1\u03C6\u03AE:
certSign.selectKey=\u0395\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03C4\u03BF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF \u03C4\u03BF\u03C5 \u03B9\u03B4\u03B9\u03C9\u03C4\u03B9\u03BA\u03BF\u03CD \u03BA\u03BB\u03B5\u03B9\u03B4\u03B9\u03BF\u03CD \u03C3\u03B1\u03C2 (\u03BC\u03BF\u03C1\u03C6\u03AE PKCS#8, \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF \u03BD\u03B1 \u03B5\u03AF\u03BD\u03B1\u03B9 .pem \u03AE .der):
certSign.selectCert=\u0395\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03C4\u03BF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF \u03C0\u03B9\u03C3\u03C4\u03BF\u03C0\u03BF\u03B9\u03B7\u03C4\u03B9\u03BA\u03BF\u03CD \u03C3\u03B1\u03C2 (\u03BC\u03BF\u03C1\u03C6\u03AE X.509, \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF \u03BD\u03B1 \u03B5\u03AF\u03BD\u03B1\u03B9 .pem \u03AE .der):
certSign.selectP12=\u0395\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03C4\u03BF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF PKCS#12 Keystore (.p12 \u03AE .pfx) (\u03A0\u03C1\u03BF\u03B1\u03B9\u03C1\u03B5\u03C4\u03B9\u03BA\u03CC, \u03B5\u03AC\u03BD \u03C0\u03B1\u03C1\u03AD\u03C7\u03B5\u03C4\u03B1\u03B9, \u03B8\u03B1 \u03C0\u03C1\u03AD\u03C0\u03B5\u03B9 \u03BD\u03B1 \u03C0\u03B5\u03C1\u03B9\u03AD\u03C7\u03B5\u03B9 \u03C4\u03BF \u03B9\u03B4\u03B9\u03C9\u03C4\u03B9\u03BA\u03CC \u03BA\u03BB\u03B5\u03B9\u03B4\u03AF \u03BA\u03B1\u03B9 \u03C4\u03BF \u03C0\u03B9\u03C3\u03C4\u03BF\u03C0\u03BF\u03B9\u03B7\u03C4\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2):
certSign.selectKey=\u0395\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03C4\u03BF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF \u03C4\u03BF\u03C5 \u03B9\u03B4\u03B9\u03C9\u03C4\u03B9\u03BA\u03BF\u03CD \u03BA\u03BB\u03B5\u03B9\u03B4\u03B9\u03BF\u03CD \u03C3\u03B1\u03C2 (\u03BC\u03BF\u03C1\u03C6\u03AE PKCS#8, \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF \u03BD\u03B1 \u03B5\u03AF\u03BD\u03B1\u03B9 .pem \u03AE .der):
certSign.selectCert=\u0395\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03C4\u03BF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF \u03C0\u03B9\u03C3\u03C4\u03BF\u03C0\u03BF\u03B9\u03B7\u03C4\u03B9\u03BA\u03BF\u03CD \u03C3\u03B1\u03C2 (\u03BC\u03BF\u03C1\u03C6\u03AE X.509, \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF \u03BD\u03B1 \u03B5\u03AF\u03BD\u03B1\u03B9 .pem \u03AE .der):
certSign.selectP12=\u0395\u03C0\u03B9\u03BB\u03AD\u03BE\u03C4\u03B5 \u03C4\u03BF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF PKCS#12 Keystore (.p12 \u03AE .pfx) (\u03A0\u03C1\u03BF\u03B1\u03B9\u03C1\u03B5\u03C4\u03B9\u03BA\u03CC, \u03B5\u03AC\u03BD \u03C0\u03B1\u03C1\u03AD\u03C7\u03B5\u03C4\u03B1\u03B9, \u03B8\u03B1 \u03C0\u03C1\u03AD\u03C0\u03B5\u03B9 \u03BD\u03B1 \u03C0\u03B5\u03C1\u03B9\u03AD\u03C7\u03B5\u03B9 \u03C4\u03BF \u03B9\u03B4\u03B9\u03C9\u03C4\u03B9\u03BA\u03CC \u03BA\u03BB\u03B5\u03B9\u03B4\u03AF \u03BA\u03B1\u03B9 \u03C4\u03BF \u03C0\u03B9\u03C3\u03C4\u03BF\u03C0\u03BF\u03B9\u03B7\u03C4\u03B9\u03BA\u03CC \u03C3\u03B1\u03C2):
certSign.certType=\u03A4\u03CD\u03C0\u03BF\u03C2 \u03A0\u03B9\u03C3\u03C4\u03BF\u03C0\u03BF\u03B9\u03B7\u03C4\u03B9\u03BA\u03BF\u03CD
certSign.password=\u0395\u03B9\u03C3\u03B1\u03B3\u03AC\u03B3\u03B5\u03C4\u03B5 \u03C4\u03BF\u03BD \u03BA\u03C9\u03B4\u03B9\u03BA\u03CC \u03C4\u03BF\u03C5 Keystore \u03AE \u03C4\u03BF\u03C5 \u0399\u03B4\u03B9\u03C9\u03C4\u03B9\u03BA\u03BF\u03CD \u039A\u03BB\u03B5\u03B9\u03B4\u03B9\u03BF\u03CD (\u03B5\u03AC\u03BD \u03C5\u03C0\u03AC\u03C1\u03C7\u03B5\u03B9):
certSign.password=\u0395\u03B9\u03C3\u03B1\u03B3\u03AC\u03B3\u03B5\u03C4\u03B5 \u03C4\u03BF\u03BD \u03BA\u03C9\u03B4\u03B9\u03BA\u03CC \u03C4\u03BF\u03C5 Keystore \u03AE \u03C4\u03BF\u03C5 \u0399\u03B4\u03B9\u03C9\u03C4\u03B9\u03BA\u03BF\u03CD \u039A\u03BB\u03B5\u03B9\u03B4\u03B9\u03BF\u03CD (\u03B5\u03AC\u03BD \u03C5\u03C0\u03AC\u03C1\u03C7\u03B5\u03B9):
certSign.showSig=\u0395\u03BC\u03C6\u03AC\u03BD\u03B9\u03C3\u03B7 \u03A5\u03C0\u03BF\u03B3\u03C1\u03B1\u03C6\u03AE\u03C2
certSign.reason=\u0391\u03B9\u03C4\u03AF\u03B1
certSign.location=\u03A4\u03BF\u03C0\u03BF\u03B8\u03B5\u03C3\u03AF\u03B1
certSign.name=\u038C\u03BD\u03BF\u03BC\u03B1
certSign.name=\u038C\u03BD\u03BF\u03BC\u03B1
certSign.submit=\u03A5\u03C0\u03BF\u03B3\u03C1\u03B1\u03C6\u03AE PDF
@@ -516,6 +544,12 @@ removeBlanks.whitePercentDesc=\u03A4\u03BF \u03C0\u03BF\u03C3\u03BF\u03C3\u03C4\
removeBlanks.submit=\u0391\u03C6\u03B1\u03AF\u03C1\u03B5\u03C3\u03B7 \u039A\u03B5\u03BD\u03CE\u03BD
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=\u03A3\u03CD\u03B3\u03BA\u03C1\u03B9\u03C3\u03B7
compare.header=\u03A3\u03CD\u03B3\u03BA\u03C1\u03B9\u03C3\u03B7 PDFs
@@ -558,7 +592,7 @@ ScannerImageSplit.selectText.8=\u03A1\u03C5\u03B8\u03BC\u03AF\u03B6\u03B5\u03B9
ScannerImageSplit.selectText.9=\u039C\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03BF\u03C2:
ScannerImageSplit.selectText.10=\u039F\u03C1\u03AF\u03B6\u03B5\u03B9 \u03C4\u03BF \u03BC\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 \u03C4\u03BF\u03C5 \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03BF\u03C2 \u03C0\u03BF\u03C5 \u03C0\u03C1\u03BF\u03C3\u03C4\u03AF\u03B8\u03B5\u03C4\u03B1\u03B9 \u03BA\u03B1\u03B9 \u03B1\u03C6\u03B1\u03B9\u03C1\u03B5\u03AF\u03C4\u03B1\u03B9 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03B1\u03C0\u03BF\u03C4\u03C1\u03AD\u03C0\u03BF\u03BD\u03C4\u03B1\u03B9 \u03BB\u03B5\u03C5\u03BA\u03AC \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03B1 \u03C3\u03C4\u03B7\u03BD \u03AD\u03BE\u03BF\u03B4\u03BF (\u03C0\u03C1\u03BF\u03B5\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE: 1).
#OCR
ocr.title=\u039F\u03C0\u03C4\u03B9\u03BA\u03AE \u03B1\u03BD\u03B1\u03B3\u03BD\u03CE\u03C1\u03B9\u03C3\u03B7 \u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03C9\u03BD (OCR) / \u03A3\u03B1\u03C1\u03CE\u03C3\u03B5\u03B9\u03C2 Cleanup
ocr.header=\u03A3\u03B1\u03C1\u03CE\u03C3\u03B5\u03B9\u03C2 Cleanup / OCR (Optical Character Recognition - \u039F\u03C0\u03C4\u03B9\u03BA\u03AE \u03B1\u03BD\u03B1\u03B3\u03BD\u03CE\u03C1\u03B9\u03C3\u03B7 \u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03C9\u03BD)
@@ -602,7 +636,7 @@ compress.selectText.1=\u03A7\u03B5\u03B9\u03C1\u03BF\u03BA\u03AF\u03BD\u03B7\u03
compress.selectText.2=\u0395\u03C0\u03AF\u03C0\u03B5\u03B4\u03BF \u0392\u03B5\u03BB\u03C4\u03B9\u03C3\u03C4\u03BF\u03C0\u03BF\u03AF\u03B7\u03C3\u03B7\u03C2:
compress.selectText.3=4 (\u03A0\u03BF\u03BB\u03CD \u03BA\u03B1\u03BA\u03CC \u03B3\u03B9\u03B1 \u03B5\u03B9\u03BA\u03CC\u03BD\u03B5\u03C2 \u03BA\u03B5\u03B9\u03BC\u03AD\u03BD\u03BF\u03C5)
compress.selectText.4=\u0391\u03C5\u03C4\u03CC\u03BC\u03B1\u03C4\u03B7 \u039B\u03B5\u03B9\u03C4\u03BF\u03C5\u03C1\u03B3\u03AF\u03B1 - Auto mode - \u03A0\u03C1\u03BF\u03C3\u03B1\u03C1\u03BC\u03CC\u03B6\u03B5\u03B9 \u03B1\u03C5\u03C4\u03CC\u03BC\u03B1\u03C4\u03B1 \u03C4\u03B7\u03BD \u03C0\u03BF\u03B9\u03CC\u03C4\u03B7\u03C4\u03B1 \u03B3\u03B9\u03B1 \u03BB\u03AE\u03C8\u03B7 PDF \u03C3\u03C4\u03BF \u03B1\u03BA\u03C1\u03B9\u03B2\u03AD\u03C2 \u03BC\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2
compress.selectText.5=\u0391\u03BD\u03B1\u03BC\u03B5\u03BD\u03CC\u03BC\u03B5\u03BD\u03BF \u039C\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 PDF (\u03C0.\u03C7 25MB, 10.8MB, 25KB)
compress.selectText.5=\u0391\u03BD\u03B1\u03BC\u03B5\u03BD\u03CC\u03BC\u03B5\u03BD\u03BF \u039C\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 PDF (\u03C0.\u03C7 25MB, 10.8MB, 25KB)
compress.submit=\u03A3\u03C5\u03BC\u03C0\u03AF\u03B5\u03C3\u03B7
@@ -632,6 +666,9 @@ pdfOrganiser.submit=\u0391\u03BD\u03B1\u03B4\u03B9\u03AC\u03C4\u03B1\u03BE\u03B7
multiTool.title=PDF \u03A0\u03BF\u03BB\u03C5\u03B5\u03C1\u03B3\u03B1\u03BB\u03B5\u03AF\u03BF
multiTool.header=PDF \u03A0\u03BF\u03BB\u03C5\u03B5\u03C1\u03B3\u03B1\u03BB\u03B5\u03AF\u03BF
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=\u0391\u03C6\u03B1\u03B9\u03C1\u03B5\u03C4\u03AE\u03C2 \u03A3\u03B5\u03BB\u03AF\u03B4\u03C9\u03BD
@@ -643,7 +680,7 @@ pageRemover.submit=\u0391\u03C6\u03B1\u03AF\u03C1\u03B5\u03C3\u03B7 \u03A3\u03B5
#rotate
rotate.title=\u03A0\u03B5\u03C1\u03B9\u03C3\u03C4\u03C1\u03BF\u03C6\u03AE PDF
rotate.header=\u03A0\u03B5\u03C1\u03B9\u03C3\u03C4\u03C1\u03BF\u03C6\u03AE PDF
rotate.\u03A0\u03B5\u03C1\u03B9\u03C3\u03C4\u03C1\u03BF\u03C6\u03AE=\u0395\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE \u03B3\u03C9\u03BD\u03AF\u03B1\u03C2 \u03C0\u03B5\u03C1\u03B9\u03C3\u03C4\u03C1\u03BF\u03C6\u03AE\u03C2 (\u03C3\u03B5 \u03C0\u03BF\u03BB\u03BB\u03B1\u03C0\u03BB\u03AC\u03C3\u03B9\u03BF \u03C4\u03C9\u03BD 90 \u03BC\u03BF\u03B9\u03C1\u03CE\u03BD):
rotate.selectAngle=Select rotation angle (in multiples of 90 degrees):
rotate.submit=Rotate
@@ -753,7 +790,7 @@ removePassword.submit=\u0391\u03C6\u03B1\u03AF\u03C1\u03B5\u03C3\u03B7
#changeMetadata
changeMetadata.title=\u0391\u03BB\u03BB\u03B1\u03B3\u03AE \u039C\u03B5\u03C4\u03B1\u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03C9\u03BD
changeMetadata.title=\u03A4\u03AF\u03C4\u03BB\u03BF\u03C2:
changeMetadata.header=\u0391\u03BB\u03BB\u03B1\u03B3\u03AE \u039C\u03B5\u03C4\u03B1\u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03C9\u03BD
changeMetadata.selectText.1=\u03A0\u03B1\u03C1\u03B1\u03BA\u03B1\u03BB\u03BF\u03CD\u03BC\u03B5 \u03B5\u03C0\u03B5\u03BE\u03B5\u03C1\u03B3\u03B1\u03C3\u03C4\u03B5\u03AF\u03C4\u03B5 \u03C4\u03B9\u03C2 \u03BC\u03B5\u03C4\u03B1\u03B2\u03BB\u03B7\u03C4\u03AD\u03C2 \u03C0\u03BF\u03C5 \u03B8\u03AD\u03BB\u03B5\u03C4\u03B5 \u03BD\u03B1 \u03B1\u03BB\u03BB\u03AC\u03BE\u03B5\u03C4\u03B5
changeMetadata.selectText.2=\u0394\u03B9\u03B1\u03B3\u03C1\u03B1\u03C6\u03AE \u03CC\u03BB\u03C9\u03BD \u03C4\u03C9\u03BD \u03BC\u03B5\u03C4\u03B1\u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03C9\u03BD
@@ -814,4 +851,46 @@ PDFToHTML.submit=\u039C\u03B5\u03C4\u03B1\u03C4\u03C1\u03BF\u03C0\u03AE
PDFToXML.title=PDF \u03C3\u03B5 XML
PDFToXML.header=PDF \u03C3\u03B5 XML
PDFToXML.credit=\u0391\u03C5\u03C4\u03AE \u03B7 \u03C5\u03C0\u03B7\u03C1\u03B5\u03C3\u03AF\u03B1 \u03C7\u03C1\u03B7\u03C3\u03B9\u03BC\u03BF\u03C0\u03BF\u03B9\u03B5\u03AF LibreOffice \u03B3\u03B9\u03B1 \u03C4\u03B7 \u03BC\u03B5\u03C4\u03B1\u03C4\u03C1\u03BF\u03C0\u03AE \u03C4\u03C9\u03BD \u03B1\u03C1\u03C7\u03B5\u03AF\u03C9\u03BD.
PDFToXML.submit=\u039C\u03B5\u03C4\u03B1\u03C4\u03C1\u03BF\u03C0\u03AE
PDFToXML.submit=\u039C\u03B5\u03C4\u03B1\u03C4\u03C1\u03BF\u03C0\u03AE
#PDFToCSV
PDFToCSV.title=PDF ?? CSV
PDFToCSV.header=PDF ?? CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=?????????
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -119,6 +119,7 @@ adminUserSettings.role=Role
adminUserSettings.actions=Actions
adminUserSettings.apiUser=Limited API User
adminUserSettings.webOnlyUser=Web Only User
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange = Force user to change username/password on login
adminUserSettings.submit=Save User
@@ -126,8 +127,13 @@ adminUserSettings.submit=Save User
# HOME-PAGE #
#############
home.desc=Your locally hosted one-stop-shop for all your PDF needs.
home.searchBar=Search for features...
home.viewPdf.title=View PDF
home.viewPdf.desc=View, annotate, add text or images
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=PDF Multi Tool
home.multiTool.desc=Merge, Rotate, Rearrange, and Remove pages
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move
@@ -250,6 +256,10 @@ home.removeBlanks.title=Remove Blank pages
home.removeBlanks.desc=Detects and removes blank pages from a document
removeBlanks.tags=cleanup,streamline,non-content,organize
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Compare
home.compare.desc=Compares and shows the differences between 2 PDF Documents
compare.tags=differentiate,contrast,changes,analysis
@@ -331,6 +341,24 @@ home.autoRedact.title=Auto Redact
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
showJS.tags=Redact,Hide,black out,black,marker,hidden
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -516,6 +544,12 @@ removeBlanks.whitePercentDesc=Percent of page that must be 'white' pixels to be
removeBlanks.submit=Remove Blanks
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Compare
compare.header=Compare PDFs
@@ -632,6 +666,9 @@ pdfOrganiser.submit=Rearrange Pages
multiTool.title=PDF Multi Tool
multiTool.header=PDF Multi Tool
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=Page Remover
@@ -814,4 +851,46 @@ PDFToHTML.submit=Convert
PDFToXML.title=PDF to XML
PDFToXML.header=PDF to XML
PDFToXML.credit=This service uses LibreOffice for file conversion.
PDFToXML.submit=Convert
PDFToXML.submit=Convert
#PDFToCSV
PDFToCSV.title=PDF to CSV
PDFToCSV.header=PDF to CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extract
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -119,6 +119,7 @@ adminUserSettings.role=Role
adminUserSettings.actions=Actions
adminUserSettings.apiUser=Limited API User
adminUserSettings.webOnlyUser=Web Only User
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Force user to change username/password on login
adminUserSettings.submit=Save User
@@ -126,8 +127,13 @@ adminUserSettings.submit=Save User
# HOME-PAGE #
#############
home.desc=Your locally hosted one-stop-shop for all your PDF needs.
home.searchBar=Search for features...
home.viewPdf.title=View PDF
home.viewPdf.desc=View, annotate, add text or images
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=PDF Multi Tool
home.multiTool.desc=Merge, Rotate, Rearrange, and Remove pages
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move
@@ -250,6 +256,10 @@ home.removeBlanks.title=Remove Blank pages
home.removeBlanks.desc=Detects and removes blank pages from a document
removeBlanks.tags=cleanup,streamline,non-content,organize
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Compare
home.compare.desc=Compares and shows the differences between 2 PDF Documents
compare.tags=differentiate,contrast,changes,analysis
@@ -331,6 +341,24 @@ home.autoRedact.title=Auto Redact
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
showJS.tags=JS
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -478,9 +506,6 @@ pipeline.title=Pipeline
pageLayout.title=Multi Page Layout
pageLayout.header=Multi Page Layout
pageLayout.pagesPerSheet=Pages per sheet:
##########################
### TODO: Translate ###
##########################
pageLayout.addBorder=Add Borders
pageLayout.submit=Submit
@@ -519,6 +544,12 @@ removeBlanks.whitePercentDesc=Percent of page that must be 'white' pixels to be
removeBlanks.submit=Remove Blanks
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Compare
compare.header=Compare PDFs
@@ -635,6 +666,9 @@ pdfOrganiser.submit=Rearrange Pages
multiTool.title=PDF Multi Tool
multiTool.header=PDF Multi Tool
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=Page Remover
@@ -818,3 +852,45 @@ PDFToXML.title=PDF to XML
PDFToXML.header=PDF to XML
PDFToXML.credit=This service uses LibreOffice for file conversion.
PDFToXML.submit=Convert
#PDFToCSV
PDFToCSV.title=PDF to CSV
PDFToCSV.header=PDF to CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extract
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -26,7 +26,7 @@ text=Texto
font=Fuente
selectFillter=-- Seleccionar --
pageNum=Número de página
sizes.small=Paqueño
sizes.small=Pequeño
sizes.medium=Mediano
sizes.large=Grande
sizes.x-large=Extra grande
@@ -44,7 +44,7 @@ blue=Azul
custom=Personalizado...
changedCredsMessage=Se cambiaron las credenciales!
notAuthenticatedMessage=Usuario njo autentificado.
notAuthenticatedMessage=Usuario no autentificado.
userNotFoundMessage=Usuario no encontrado.
incorrectPasswordMessage=La contraseña actual no es correcta.
usernameExistsMessage=El nuevo nombre de usuario está en uso.
@@ -70,8 +70,8 @@ settings.appVersion=Versión de la aplicación:
settings.downloadOption.title=Elegir la opción de descarga (para descargas de un solo archivo sin ZIP):
settings.downloadOption.1=Abrir en la misma ventana
settings.downloadOption.2=Abrir en una nueva ventana
settings.downloadOption.3=Descargar el fichero
settings.zipThreshold=Ficheros ZIP cuando excede el número de ficheros descargados
settings.downloadOption.3=Descargar el archivo
settings.zipThreshold=Archivos ZIP cuando excede el número de archivos descargados
settings.signOut=Desconectar
settings.accountSettings=Configuración de la cuenta
@@ -119,15 +119,21 @@ adminUserSettings.role=Rol
adminUserSettings.actions=Acciones
adminUserSettings.apiUser=Usuario limitado de API
adminUserSettings.webOnlyUser=Usuario solo web
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Forzar usuario a cambiar usuario/contraseña en el acceso
adminUserSettings.submit=Guardar Usuario
#############
# HOME-PAGE #
#############
home.desc=Su ventanilla única autohospedada para todas tus necesidades PDF
home.desc=Su ventanilla única autohospedada para todas sus necesidades PDF
home.searchBar=Buscar características...
home.viewPdf.title=Ver PDF
home.viewPdf.desc=Ver, anotar, añadir texto o imágenes
viewPdf.tags=ver,leer,anotar,texto,imagen
home.multiTool.title=Multi-herramienta PDF
home.multiTool.desc=Combinar, rotar, reorganizar y eliminar páginas
multiTool.tags=Multi-herramienta,Multi-operación,Interfaz de usuario,Arrastrar con un click,front end,lado del cliente
@@ -159,12 +165,12 @@ pdfOrganiser.tags=doble cara,pares,impares,ordenar,mover
home.addImage.title=Agregar imagen al PDF
home.addImage.desc=Agregar una imagen en una ubicación establecida en el PDF (en desarrollo)
home.addImage.desc=Agregar una imagen en el PDF en una ubicación establecida (en desarrollo)
addImage.tags=img,jpg,imagen,fotografía
home.watermark.title=Añadir marca de agua
home.watermark.desc=Añadir una marca de agua predefinida al documento PDF
watermark.tags=Texto,repetir,etiquetar,propietario,copyight,marca comercial,img,jpg,imagen,fotografía
watermark.tags=Texto,repetir,etiquetar,propietario,copyright,marca comercial,img,jpg,imagen,fotografía
home.permissions.title=Cambiar permisos
home.permissions.desc=Cambiar los permisos del documento PDF
@@ -184,7 +190,7 @@ home.removePassword.desc=Eliminar la contraseña del documento PDF
removePassword.tags=seguro,Desencriptar,seguridad,quitar contraseña,eliminar contraseña
home.compressPdfs.title=Comprimir
home.compressPdfs.desc=Comprimir PDFs para reducir el tamaño del fichero
home.compressPdfs.desc=Comprimir PDFs para reducir el tamaño del archivo
compressPdfs.tags=aplastar,pequeño,diminuto
@@ -192,7 +198,7 @@ home.changeMetadata.title=Cambiar metadatos
home.changeMetadata.desc=Cambiar/Eliminar/Añadir metadatos al documento PDF
changeMetadata.tags==Título,autor,fecha,creación,hora,editorial,productor,estadísticas
home.fileToPDF.title=Convertir fichero a PDF
home.fileToPDF.title=Convertir archivo a PDF
home.fileToPDF.desc=Convertir casi cualquier archivo a PDF (DOCX, PNG, XLS, PPT, TXT y más)
fileToPDF.tags=transformación,formato,documento,imagen,diapositiva,texto,conversión,office,docs,word,excel,powerpoint
@@ -207,7 +213,7 @@ extractImages.tags=imagen,fotografía,guardar,archivo,zip,capturar,coger
home.pdfToPDFA.title=Convertir PDF a PDF/A
home.pdfToPDFA.desc=Convertir PDF a PDF/A para almacenamiento a largo plazo
pdfToPDFA.tags=archivo,largo plazo,estándar,conversión,almacewnamiento,conservación
pdfToPDFA.tags=archivo,largo plazo,estándar,conversión,almacenamiento,conservación
home.PDFToWord.title=PDF a Word
home.PDFToWord.desc=Convertir formatos PDF a Word (DOC, DOCX y ODT)
@@ -250,6 +256,10 @@ home.removeBlanks.title=Eliminar páginas en blanco
home.removeBlanks.desc=Detectar y eliminar páginas en blanco de un documento
removeBlanks.tags=limpieza,dinámica,sin contenido,organizar
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Comparar
home.compare.desc=Comparar y mostrar las diferencias entre 2 documentos PDF
compare.tags=diferenciar,contrastar,cambios,análisis
@@ -274,8 +284,8 @@ home.add-page-numbers.title=Añadir números de página
home.add-page-numbers.desc=Añadir números de página en un documento en una ubicación concreta
add-page-numbers.tags=paginar,etiquetar,organizar,indexar
home.auto-rename.title=Auto renombrar archivo PDF
home.auto-rename.desc=Auto renombrar un archivo PDF según el encabezamiento detectado
home.auto-rename.title=Renombrar archivo PDF automáticamente
home.auto-rename.desc=Renombrar automáticamente un archivo PDF según el encabezamiento detectado
auto-rename.tags=auto-detectar,basado en el encabezamiento,organizar,re-etiquetar
home.adjust-contrast.title=Ajustar Color/Contraste
@@ -296,7 +306,7 @@ sanitizePdf.tags=limpiar,asegurar,seguro,quitar amenazas
home.URLToPDF.title=URL/Página web a PDF
home.URLToPDF.desc=Convierte cualquier dirección http(s) a PDF
URLToPDF.tags=captura web,guardar página,web-a-doc,archivo
URLToPDF.tags=captura web,guardar página,web a documento,archivo
home.HTMLToPDF.title=HTML a PDF
home.HTMLToPDF.desc=Convierte cualquier archivo HTML o ZIP a PDF
@@ -310,7 +320,7 @@ MarkdownToPDF.tags=margen,contenido web,transformación,convertir
home.getPdfInfo.title=Obtener toda la información en PDF
home.getPdfInfo.desc=Obtiene toda la información posible de archivos PDF
getPdfInfo.tags=información,datos,stats,estadísticas
getPdfInfo.tags=información,datos,estadísticas,estadísticas
home.extractPage.title=Extraer página(s)
@@ -331,6 +341,24 @@ home.autoRedact.title=Auto Redactar
home.autoRedact.desc=Redactar automáticamente (ocultar) texto en un PDF según el texto introducido
showJS.tags=JS
home.tableExtraxt.title=PDF a CSV
home.tableExtraxt.desc=Extraer Tablas de un PDF convirtiéndolas a CSV
tableExtraxt.tags=CSV,Extraer tabla,extraer,convertir
home.autoSizeSplitPDF.title=Auto dividir por tamaño/conteo
home.autoSizeSplitPDF.desc=Divide un solo PDF en múltiples documentos según su tamaño, número de páginas, o número de documento
autoSizeSplitPDF.tags=pdf,dividir,documento,organización
home.overlay-pdfs.title=Superponer PDFs
home.overlay-pdfs.desc=Superponer PDFs encima de otro PDF
overlay-pdfs.tags=Superponer
home.split-by-sections.title=Dividir PDF por Seccioned
home.split-by-sections.desc=Dividir cada página de un PDF en secciones verticales y horizontales más pequeñas
split-by-sections.tags=Dividir sección, Dividir, Personalizar
###########################
# #
# WEB PAGES #
@@ -354,7 +382,7 @@ autoRedact.textsToRedactPlaceholder=por ej. \nConfidencial \nAlto-Secreto
autoRedact.useRegexLabel=Usar Regex
autoRedact.wholeWordSearchLabel=Búsqueda por palabra completa
autoRedact.customPaddingLabel=Extra Padding personalizado
autoRedact.convertPDFToImageLabel=Convertir PDF a imagen-PDF (Utilizado para quitar el texto detrás del cajetín)
autoRedact.convertPDFToImageLabel=Convertir PDF a imagen PDF (Utilizado para quitar el texto detrás del cajetín)
autoRedact.submitButton=Enviar
@@ -403,7 +431,7 @@ URLToPDF.credit=Utiliza WeasyPrint
#html-to-pdf
HTMLToPDF.title=HTML a PDF
HTMLToPDF.header=HTML a PDF
HTMLToPDF.help=Acepta archivos HTML y ZIPs conteniendo los html/css/imágenes etc requeridas
HTMLToPDF.help=Acepta archivos HTML y ZIPs conteniendo los html/css/imágenes, etc, requeridas
HTMLToPDF.submit=Convertir
HTMLToPDF.credit=Utiliza WeasyPrint
@@ -430,14 +458,14 @@ addPageNumbers.selectText.5=Páginas a numerar
addPageNumbers.selectText.6=Texto personalizado
addPageNumbers.customTextDesc=Texto personalizado
addPageNumbers.numberPagesDesc=Qué páginas numerar, por defecto 'todas', también acepta 1-5 o 2,5,9 etc
addPageNumbers.customNumberDesc=Por defecto a {n}, también acepta 'Página {n} de {total}', 'Texto-{n}', '{nombre de archivo}-{n}
addPageNumbers.customNumberDesc=Por defecto a {n}, también acepta 'Página {n} de {total}', 'Texto-{n}', '{filename}-{n}
addPageNumbers.submit=Añadir Números de Página
#auto-rename
auto-rename.title=Auto Renombrar
auto-rename.header=Auto Renombrar PDF
auto-rename.submit=Auto Renombrar
auto-rename.title=Renombrar automáticamente
auto-rename.header=Renombrar PDF automáticamente
auto-rename.submit=Renombrar automáticamente
#adjustContrast
@@ -456,8 +484,8 @@ crop.submit=Entregar
#autoSplitPDF
autoSplitPDF.title=Auto Dividir PDF
autoSplitPDF.header=Auto Dividir PDF
autoSplitPDF.title=Dividir PDF automáticamente
autoSplitPDF.header=Dividir PDF automáticamente
autoSplitPDF.description=Imprimir, Insertar, Escanear, cargar, y déjenos sepsrar automáticamente sus documentos. No se necesita clasificación manual.
autoSplitPDF.selectText.1=Imprimir algunas hojas divisorias desde la parte inferior (Blanco y negro está bien).
autoSplitPDF.selectText.2=Escanee todos sus documentos a la vez insertando la hoja divisoria entre ellos.
@@ -465,8 +493,8 @@ autoSplitPDF.selectText.3=Cargue un único archivo PDF escaneado de gran tamaño
autoSplitPDF.selectText.4=Las páginas divisorias son automáticamente detectadas y eliminadas, garantizando un buen documento final.
autoSplitPDF.formPrompt=Entregar PDF conteniendo divisores de página de Stirling-PDF:
autoSplitPDF.duplexMode=Modo Dúplex (Escaneado de ambas caras)
autoSplitPDF.dividerDownload1=Descargar 'Auto Splitter Divider (mínima).pdf'
autoSplitPDF.dividerDownload2=Descargar 'Auto Splitter Divider (con instrucciones).pdf'
autoSplitPDF.dividerDownload1=Descargar 'Divisor automático (mínima).pdf'
autoSplitPDF.dividerDownload2=Descargar 'Divisor automático (con instrucciones).pdf'
autoSplitPDF.submit=Entregar
@@ -478,10 +506,7 @@ pipeline.title=Pipeline
pageLayout.title=Diseño de varias páginas
pageLayout.header=Diseño de varias páginas
pageLayout.pagesPerSheet=Páginas por hoja:
##########################
### TODO: Translate ###
##########################
pageLayout.addBorder=Add Borders
pageLayout.addBorder=Añadir bordes
pageLayout.submit=Entregar
@@ -494,7 +519,7 @@ scalePages.submit=Entregar
#certSign
certSign.title=Firma de certificado
certSign.title=Firma con certificado
certSign.header=Firmar un PDF con su certificado (en desarrollo)
certSign.selectPDF=Seleccione un archivo PDF para firmar:
certSign.selectKey=Seleccione su archivo de clave privada (formato PKCS#8, podría ser .pem o .der):
@@ -519,6 +544,12 @@ removeBlanks.whitePercentDesc=Porcentaje de página que debe ser blanca para ser
removeBlanks.submit=Eliminar espacios en blanco
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Comparar
compare.header=Comparar archivos PDF
@@ -556,7 +587,7 @@ ScannerImageSplit.selectText.3=Tolerancia:
ScannerImageSplit.selectText.4=Determinar el rango de variación de color alrededor del color de fondo estimado (predeterminado: 30).
ScannerImageSplit.selectText.5=Área mínima:
ScannerImageSplit.selectText.6=Establecer el umbral mínimo de área para una foto (predeterminado: 10000).
ScannerImageSplit.selectText.7=Área de contorno mínima:
ScannerImageSplit.selectText.7=Área mínima de contorno:
ScannerImageSplit.selectText.8=Establecer el umbral mínimo del área de contorno para una foto
ScannerImageSplit.selectText.9=Tamaño del borde:
ScannerImageSplit.selectText.10=Establece el tamaño del borde agregado y eliminado para evitar bordes blancos en la salida (predeterminado: 1).
@@ -592,8 +623,8 @@ extractImages.submit=Extraer
#File to PDF
fileToPDF.title=Archivo a PDF
fileToPDF.header=Convertir cualquier archivo a PDF
fileToPDF.credit=Este servicio usa LibreOffice y Unoconv para la conversión de ficheros
fileToPDF.supportedFileTypes=Los tipos de ficheros soportados deben incluir los de abajo; sin embargo, para una completa y acutualizada lista de formatos soportados, por favor consulte la documentación de LibreOffice
fileToPDF.credit=Este servicio usa LibreOffice y Unoconv para la conversión de archivos
fileToPDF.supportedFileTypes=Los tipos de archivo soportados deben incluir los indicados a continuación; sin embargo, para una completa y acutualizada lista de formatos soportados, por favor consulte la documentación de LibreOffice
fileToPDF.submit=Convertir a PDF
@@ -635,6 +666,9 @@ pdfOrganiser.submit=Organizar páginas
multiTool.title=Multi-herramienta PDF
multiTool.header=Multi-herramienta PDF
#view pdf
viewPdf.title=Ver PDF
viewPdf.header=Ver PDF
#pageRemover
pageRemover.title=Eliminador de páginas
@@ -669,10 +703,10 @@ split.submit=Dividir
imageToPDF.title=Imagen a PDF
imageToPDF.header=Imagen a PDF
imageToPDF.submit=Convertir
imageToPDF.selectLabel=Image Fit Options
imageToPDF.fillPage=Fill Page
imageToPDF.fitDocumentToImage=Fit Page to Image
imageToPDF.maintainAspectRatio=Maintain Aspect Ratios
imageToPDF.selectLabel=Opciones de ajuste de imagen
imageToPDF.fillPage=Ocupar toda la página
imageToPDF.fitDocumentToImage=Ajustar página a imagen
imageToPDF.maintainAspectRatio=Mantener relación de aspecto
imageToPDF.selectText.2=Rotación automática del PDF
imageToPDF.selectText.3=Lógica de archivos múltiples (únicamente activado si funciona con multiples imágenes)
imageToPDF.selectText.4=Unir en un único archivo PDF
@@ -710,8 +744,8 @@ addPassword.selectText.11=Impedir modificación de anotaciones
addPassword.selectText.12=Impedir imprimir
addPassword.selectText.13=Impedir imprimir diferentes formatos
addPassword.selectText.14=Contraseña
addPassword.selectText.15=Restringe qué se puede hacer con el documento una vez abierto (no soportado por todos los lectores)
addPassword.selectText.16=Restringe la apertura del propio documento
addPassword.selectText.15=Restringir qué se puede hacer con el documento una vez abierto (no soportado por todos los lectores)
addPassword.selectText.16=Restringir la apertura del propio documento
addPassword.submit=Encriptar
@@ -818,3 +852,45 @@ PDFToXML.title=PDF a XML
PDFToXML.header=PDF a XML
PDFToXML.credit=Este servicio utiliza LibreOffice para la conversión de archivos
PDFToXML.submit=Convertir
#PDFToCSV
PDFToCSV.title=PDF a CSV
PDFToCSV.header=PDF a CSV
PDFToCSV.prompt=Elija una página para extraer la tabla
PDFToCSV.submit=Extraer
#split-by-size-or-count
split-by-size-or-count.header=Dividir PDF por tamaño o número
split-by-size-or-count.type.label=Seleccionar tipo de división
split-by-size-or-count.type.size=Por tamaño
split-by-size-or-count.type.pageCount=Por número de páginas
split-by-size-or-count.type.docCount=por recuento de documentos
split-by-size-or-count.value.label=Introduzca valor
split-by-size-or-count.value.placeholder=Introduzca tamaño (p.ej., 2MB o 3KB) or recuento (p.ej., 5)
split-by-size-or-count.submit=Enviar
#overlay-pdfs
overlay-pdfs.header=Superponer archivos PDF
overlay-pdfs.baseFile.label=Selleccione archivo PDF de base
overlay-pdfs.overlayFiles.label=Seleccione archivos PDF a superponer
overlay-pdfs.mode.label=Seleccione modo de superposición
overlay-pdfs.mode.sequential=Superposición Sequencial
overlay-pdfs.mode.interleaved=Superposición Intercalada
overlay-pdfs.mode.fixedRepeat=Superposición de repetición fija
overlay-pdfs.counts.label=Recuento de superposición (para Modo de Repetición Fija)
overlay-pdfs.counts.placeholder=Introduzca recuento separado por comas (p.ej., 2,3,1)
overlay-pdfs.position.label=Seleccione Posición de Superposición
overlay-pdfs.position.foreground=Arriba
overlay-pdfs.position.background=Fondo
overlay-pdfs.submit=Enviar
#split-by-sections
split-by-sections.title=Dividir PDF por Secciones
split-by-sections.header=Dividir PDF por Secciones
split-by-sections.horizontal.label=Divisiones Horizontales
split-by-sections.vertical.label=Divisiones Verticales
split-by-sections.horizontal.placeholder=Introduzca el número de divisiones horizontales
split-by-sections.vertical.placeholder=Introduzca el número de divisiones verticales
split-by-sections.submit=Dividir PDF

View File

@@ -119,6 +119,7 @@ adminUserSettings.role=Rol
adminUserSettings.actions=Ekintzak
adminUserSettings.apiUser=APIren erabiltzaile mugatua
adminUserSettings.webOnlyUser=Web-erabiltzailea bakarrik
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Force user to change username/password on login
adminUserSettings.submit=Gorde Erabiltzailea
@@ -126,8 +127,13 @@ adminUserSettings.submit=Gorde Erabiltzailea
# HOME-PAGE #
#############
home.desc=Zure leihatila bakarra autoostatatua zure PDF behar guztietarako
home.searchBar=Search for features...
home.viewPdf.title=View PDF
home.viewPdf.desc=View, annotate, add text or images
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=Erabilera anitzeko tresna PDF
home.multiTool.desc=Orriak konbinatu, biratu, berrantolatu eta ezabatu
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
@@ -250,6 +256,10 @@ home.removeBlanks.title=Ezabatu orrialde zuriak
home.removeBlanks.desc=Detektatu orrialde zuriak eta dokumentutik ezabatu
removeBlanks.tags=cleanup,streamline,non-content,organize
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Konparatu
home.compare.desc=Konparatu eta erakutsi 2 PDF dokumenturen aldeak
compare.tags=differentiate,contrast,changes,analysis
@@ -331,6 +341,24 @@ home.autoRedact.title=Auto Idatzi
home.autoRedact.desc=Auto Idatzi testua pdf fitxategian sarrerako testuan oinarritua
showJS.tags=JS
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -478,9 +506,6 @@ pipeline.title=Hodia
pageLayout.title=Hainbat orrialderen diseinua
pageLayout.header=Hainbat orrialderen diseinua
pageLayout.pagesPerSheet=Orrialdeak orriko:
##########################
### TODO: Translate ###
##########################
pageLayout.addBorder=Add Borders
pageLayout.submit=Entregatu
@@ -519,6 +544,12 @@ removeBlanks.whitePercentDesc=Zuria izan behar den orriaren ehunekoa ezabatua iz
removeBlanks.submit=Ezabatu zuriuneak
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Konparatu
compare.header=Konparatu PDF fitxategiak
@@ -635,6 +666,9 @@ pdfOrganiser.submit=Antolatu orrialdeak
multiTool.title=PDF erabilera anitzeko tresna
multiTool.header=PDF erabilera anitzeko tresna
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=Orrialdeen ezabatzailea
@@ -818,3 +852,45 @@ PDFToXML.title=PDFa XML bihurtu
PDFToXML.header=PDFa XML bihurtu
PDFToXML.credit=Zerbitzu honek LibreOffice erabiltzen du fitxategiak bihurtzeko
PDFToXML.submit=Bihurtu
#PDFToCSV
PDFToCSV.title=PDF a CSV
PDFToCSV.header=PDF a CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extracto
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -1,7 +1,7 @@
###########
# Generic #
###########
# the direction that the language is written (ltr = left to right, rtl = right to left)
# the direction that the language is written (ltr=left to right, rtl = right to left)
language.direction=ltr
pdfPrompt=Sélectionnez le(s) PDF
@@ -119,6 +119,7 @@ adminUserSettings.role=Rôle
adminUserSettings.actions=Actions
adminUserSettings.apiUser=Utilisateur API limité
adminUserSettings.webOnlyUser=Utilisateur Web uniquement
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Forcer l\u2019utilisateur à changer son nom d\u2019utilisateur/mot de passe lors de la connexion
adminUserSettings.submit=Ajouter
@@ -126,8 +127,13 @@ adminUserSettings.submit=Ajouter
# HOME-PAGE #
#############
home.desc=Votre application Web hébergée localement pour répondre à tous vos besoins PDF.
home.searchBar=Rechercher des fonctionnalités...
home.viewPdf.title=Visionner le PDF
home.viewPdf.desc=Visionner, annoter, ajouter du texte ou des images
viewPdf.tags=visualiser,lire,annoter,texte,image
home.multiTool.title=Outil multifonction PDF
home.multiTool.desc=Fusionnez, faites pivoter, réorganisez et supprimez des pages.
multiTool.tags=outil multifonction,opération multifonction,interface utilisateur,glisser déposer,front-end,client side,interactif,intransigeant,déplacer,multi tool
@@ -250,6 +256,10 @@ home.removeBlanks.title=Supprimer les pages vierges
home.removeBlanks.desc=Détectez et supprimez les pages vierges d\u2019un PDF.
removeBlanks.tags=pages vierges,supprimer,nettoyer,cleanup,streamline,non-content,organize
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Comparer
home.compare.desc=Comparez et visualisez les différences entre deux PDF.
compare.tags=comparer,analyser,differentiate,contrast,changes,analysis
@@ -331,6 +341,24 @@ home.autoRedact.title=Caviarder automatiquement
home.autoRedact.desc=Caviardez automatiquement les informations sensibles d\u2019un PDF.
showJS.tags=caviarder,redact,auto
home.tableExtraxt.title=PDF en CSV
home.tableExtraxt.desc=Extrait les tableaux d\u2019un PDF et les transforme en CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Séparer automatiquement par taille/nombre
home.autoSizeSplitPDF.desc=Séparer un PDF unique en plusieurs documents en fonction de la taille, du nombre de pages ou du nombre de documents.
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Incrustation de PDF
home.overlay-pdfs.desc=Incrustation d\u2019un PDF sur un autre PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -430,7 +458,7 @@ addPageNumbers.selectText.5=Pages à numéroter
addPageNumbers.selectText.6=Texte personnalisé
addPageNumbers.customTextDesc=Texte personnalisé
addPageNumbers.numberPagesDesc=Quelles pages numéroter, par défaut 'all' (toutes les pages), accepte également 1-5 ou 2,5,9, etc.
addPageNumbers.customNumberDesc=La valeur par défaut est '{n}', accepte également 'Page {n} sur {total}', 'Texte-{n}', '{filename}-{n}
addPageNumbers.customNumberDesc=La valeur par défaut est '{n}', accepte également 'Page {n} sur {total}', 'Texte-{n}', '{filename}-{n}'
addPageNumbers.submit=Ajouter les numéros de page
@@ -516,6 +544,12 @@ removeBlanks.whitePercentDesc=Pourcentage de la page qui doit contenir des pixel
removeBlanks.submit=Supprimer les pages vierges
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Comparer
compare.header=Comparer
@@ -558,7 +592,7 @@ ScannerImageSplit.selectText.8=Définit la surface de contour minimale pour une
ScannerImageSplit.selectText.9=Taille de la bordure
ScannerImageSplit.selectText.10=Définit la taille de la bordure ajoutée et supprimée pour éviter les bordures blanches dans la sortie (par défaut\u00a0: 1).
#OCR
ocr.title=OCR / Nettoyage des numérisations
ocr.header=OCR (Reconnaissance optique de caractères) / Nettoyage des numérisations
@@ -632,6 +666,9 @@ pdfOrganiser.submit=Organiser
multiTool.title=Outil multifonction PDF
multiTool.header=Outil multifonction PDF
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=Supprimer des pages
@@ -674,8 +711,8 @@ imageToPDF.selectText.2=Rotation automatique du PDF
imageToPDF.selectText.3=Logique multi-fichiers (uniquement activée si vous travaillez avec plusieurs images)
imageToPDF.selectText.4=Fusionner en un seul PDF
imageToPDF.selectText.5=Convertir en PDF séparés
#pdfToImage
pdfToImage.title=Image en PDF
pdfToImage.header=Image en PDF
@@ -815,3 +852,45 @@ PDFToXML.title=PDF en XML
PDFToXML.header=PDF en XML
PDFToXML.credit=Ce service utilise LibreOffice pour la conversion de fichiers.
PDFToXML.submit=Convertir
#PDFToCSV
PDFToCSV.title=PDF en CSV
PDFToCSV.header=PDF en CSV
PDFToCSV.prompt=Choisir la page pour en extraire le tableau
PDFToCSV.submit=Extrait
#split-by-size-or-count
split-by-size-or-count.header=Séparer le PDF par taille ou par nombre
split-by-size-or-count.type.label=Sélectionner le type de division
split-by-size-or-count.type.size=Par taille
split-by-size-or-count.type.pageCount=Par nombre de pages
split-by-size-or-count.type.docCount=Par nombre de documents
split-by-size-or-count.value.label=Entrer la valeur
split-by-size-or-count.value.placeholder=Saisir la taille (par exemple, 2MB ou 3KB) ou le nombre (par exemple, 5)
split-by-size-or-count.submit=Séparer
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Sélectionner le fichier PDF de base
overlay-pdfs.overlayFiles.label=Sélectionner les fichiers PDF à superposer
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Superposition à répétition fixe
overlay-pdfs.counts.label=Nombre de superpositions (pour le mode de répétition fixe)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Premier plan
overlay-pdfs.position.background=Arrière-plan
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Diviser le PDF en sections
split-by-sections.header=Diviser le PDF en sections
split-by-sections.horizontal.label=Divisions horizontales
split-by-sections.vertical.label=Divisions verticales
split-by-sections.horizontal.placeholder=Saisir le nombre de divisions horizontales
split-by-sections.vertical.placeholder=Entrer le nombre de divisions verticales
split-by-sections.submit=Diviser le PDF

View File

@@ -0,0 +1,896 @@
###########
# Generic #
###########
# the direction that the language is written (ltr=left to right, rtl = right to left)
language.direction=ltr
pdfPrompt=पीडीएफ़(फ़ाइलें) चुनें
multiPdfPrompt=पीडीएफ़(फ़ाइलें) चुनें (2+)
multiPdfDropPrompt=सभी पीडीएफ़(फ़ाइलें) को चुनें (या खींचें और छोड़ें)
imgPrompt=छवियों का चयन करें
genericSubmit=प्रस्तुत करें
processTimeWarning=चेतावनी: यह प्रक्रिया फ़ाइल के आकार पर निर्भर करती है और यह से एक मिनट तक लग सकती है
pageOrderPrompt=कस्टम पेज क्रम (पेज नंबरों या 2n+1 जैसे कार्यों की एक कॉमा से अलग-अलग सूची दर्ज करें):
goToPage=जाएँ
true=सही
false=गलत
unknown=अज्ञात
save=सहेजें
close=बंद करें
filesSelected=फ़ाइलें चयनित हैं
noFavourites=कोई पसंदीदा जोड़ा नहीं गया है
bored=बोर हो रहे हैं?
alphabet=वर्णमाला
downloadPdf=पीडीएफ़ डाउनलोड करें
text=टेक्स्ट
font=फ़ॉन्ट
selectFillter=-- चुनें --
pageNum=पृष्ठ संख्या
sizes.small=छोटा
sizes.medium=मध्यम
sizes.large=बड़ा
sizes.x-large=बहुत बड़ा
error.pdfPassword=पीडीएफ़ दस्तावेज़ पासवर्ड से सुरक्षित है और या तो पासवर्ड नहीं दिया गया था या गलत था
delete=हटाएँ
username=उपयोगकर्ता नाम
password=पासवर्ड
welcome=स्वागत है
property=संपत्ति
black=काला
white=सफ़ेद
red=लाल
green=हरा
blue=नीला
custom=कस्टम...
changedCredsMessage=क्रेडेंशियल्स बदल दी गईं!
notAuthenticatedMessage=उपयोगकर्ता प्रमाणित नहीं है।
userNotFoundMessage=उपयोगकर्ता नहीं मिला।
incorrectPasswordMessage=वर्तमान पासवर्ड गलत है।
usernameExistsMessage=नया उपयोगकर्ता नाम पहले से मौजूद है।
#############
# NAVBAR #
#############
navbar.convert=कनवर्ट
navbar.security=सुरक्षा
navbar.other=विविध
navbar.darkmode=डार्क मोड
navbar.pageOps=पेज कार्य
navbar.settings=सेटिंग्स
#############
# SETTINGS #
#############
settings.title=सेटिंग्स
settings.update=अपडेट उपलब्ध है
settings.appVersion=ऐप संस्करण:
settings.downloadOption.title=डाउनलोड विकल्प चुनें (एकल फ़ाइल गैर-ज़िप डाउनलोड के लिए):
settings.downloadOption.1=एक ही विंडो में खोलें
settings.downloadOption.2=नई विंडो में खोलें
settings.downloadOption.3=फ़ाइल डाउनलोड करें
settings.zipThreshold=जब डाउनलोड की गई फ़ाइलों की संख्या सीमा से अधिक हो
settings.signOut=साइन आउट
settings.accountSettings=खाता सेटिंग्स
changeCreds.title=क्रेडेंशियल बदलें
changeCreds.header=अपना खाता विवरण अपडेट करें
changeCreds.changeUserAndPassword=आप डिफ़ॉल्ट लॉगिन क्रेडेंशियल का उपयोग कर रहे हैं। कृपया एक नया पासवर्ड दर्ज करें (और यदि चाहें तो उपयोगकर्ता नाम)
changeCreds.newUsername=नया उपयोगकर्ता नाम
changeCreds.oldPassword=वर्तमान पासवर्ड
changeCreds.newPassword=नया पासवर्ड
changeCreds.confirmNewPassword=नए पासवर्ड की पुष्टि करें
changeCreds.submit=परिवर्तन सबमिट करें
account.title=खाता सेटिंग्स
account.accountSettings=खाता सेटिंग्स
account.adminSettings=व्यवस्थापक सेटिंग्स - उपयोगकर्ताओं को देखें और जोड़ें
account.userControlSettings=उपयोगकर्ता नियंत्रण सेटिंग्स
account.changeUsername=उपयोगकर्ता नाम परिवर्तन करें
account.changeUsername=उपयोगकर्ता नाम परिवर्तन करें
account.password=पासवर्ड पुष्टि
account.oldPassword=पुराना पासवर्ड
account.newPassword=नया पासवर्ड
account.changePassword=पासवर्ड बदलें
account.confirmNewPassword=नए पासवर्ड की पुष्टि करें
account.signOut=साइन आउट
account.yourApiKey=आपकी API कुंजी
account.syncTitle=अकाउंट से ब्राउज़र सेटिंग्स को सिंक करें
account.settingsCompare=सेटिंग्स तुलना:
account.property=संपत्ति
account.webBrowserSettings=वेब ब्राउज़र सेटिंग्स
account.syncToBrowser=सिंक अकाउंट -> ब्राउज़र
account.syncToAccount=सिंक अकाउंट <- ब्राउज़र
adminUserSettings.title=उपयोगकर्ता नियंत्रण सेटिंग्स
adminUserSettings.header=व्यवस्थापक उपयोगकर्ता नियंत्रण सेटिंग्स
adminUserSettings.admin=व्यवस्थापक
adminUserSettings.user=उपयोगकर्ता
adminUserSettings.addUser=नया उपयोगकर्ता जोड़ें
adminUserSettings.roles=रोल्स
adminUserSettings.role=रोल
adminUserSettings.actions=क्रियाएँ
adminUserSettings.apiUser=सीमित API उपयोगकर्ता
adminUserSettings.webOnlyUser=केवल वेब उपयोगकर्ता
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=उपयोगकर्ता को लॉगिन पर उपयोगकर्ता नाम/पासवर्ड बदलने के लिए मजबूर करें
adminUserSettings.submit=उपयोगकर्ता को सहेजें
#############
# HOME-PAGE #
#############
home.desc=आपकी स्थानीय होस्ट की एक स्थानीय सेवा जहां आपकी सभी पीडीएफ़ आवश्यकताओं के लिए है।
home.searchBar=विशेषताओं की खोज करें...
home.viewPdf.title=पीडीएफ़ देखें
home.viewPdf.desc=देखें, टिप्पणी करें, पाठ या छवियों को जोड़ें
viewPdf.tags=देखें, पढ़ें, टिप्पणी, पाठ, छवि
home.multiTool.title=पीडीएफ़ मल्टी टूल
home.multiTool.desc=पृष्ठ जोड़ें, घुमाएं, व्यवस्थित करें, और हटाएं
multiTool.tags=मल्टी टूल, मल्टी ऑपरेशन, यूआई, क्लिक और खींचें, फ्रंट एंड, क्लाइंट साइड, इंटरैक्टिव, हिलनेवाला
home.merge.title=मर्ज
home.merge.desc=आसानी से कई पीडीएफ़ को एक में मर्ज करें।
merge.tags=मर्ज, पेज कार्य, बैक एंड, सर्वर साइड
home.split.title=विभाजन
home.split.desc=पीडीएफ़ को कई दस्तावेज़ों में विभाजित करें
split.tags=पेज कार्य, विभाजित करें, मल्टी पेज, कट, सर्वर साइड
home.rotate.title=रोटेट
home.rotate.desc=आसानी से अपने पीडीएफ़ को घुमाएँ।
rotate.tags=सर्वर साइड
home.imageToPdf.title=छवि से पीडीएफ़ तक
home.imageToPdf.desc=छवि (PNG, JPEG, GIF) को पीडीएफ़ में बदलें।
imageToPdf.tags=परिवर्तन, छवि, jpg, चित्र, फोटो
home.pdfToImage.title=पीडीएफ़ से छवि तक
home.pdfToImage.desc=पीडीएफ़ को छवि में बदलें। (PNG, JPEG, GIF)
pdfToImage.tags=परिवर्तन, छवि, jpg, चित्र, फोटो
home.pdfOrganiser.title=संगठन करें
home.pdfOrganiser.desc=किसी भी क्रम में पृष्ठ हटाएं/पुनःव्यवस्थित करें
pdfOrganiser.tags=डुप्लेक्स, सम, विषम, क्रमबद्ध करें, विस्थापित
home.addImage.title=छवि जोड़ें
home.addImage.desc=पीडीएफ़ पर एक छवि को एक सेट स्थान पर जोड़ता है।
addImage.tags=छवि, jpg, चित्र, फोटो
home.watermark.title=वॉटरमार्क जोड़ें
home.watermark.desc=अपने पीडीएफ़ दस्तावेज़ में एक कस्टम वॉटरमार्क जोड़ें।
watermark.tags=पाठ, बार-बार, लेबल, अपना, कॉपीराइट, ट्रेडमार्क, छवि, jpg, चित्र, फोटो
home.permissions.title=अनुमतियाँ बदलें
home.permissions.desc=अपने पीडीएफ़ दस्तावेज़ की अनुमतियाँ बदलें
permissions.tags=पढ़ें, लिखें, संपादित करें, प्रिंट
home.removePages.title=हटाएं
home.removePages.desc=अपने पीडीएफ़ दस्तावेज़ से अनचाहे पृष्ठों को हटाएं।
removePages.tags=पृष्ठ हटाएं, पृष्ठ मिटाएं
home.addPassword.title=पासवर्ड जोड़ें
home.addPassword.desc=अपने पीडीएफ़ दस्तावेज़ को एक पासवर्ड से एन्क्रिप्ट करें।
addPassword.tags=सुरक्षित, सुरक्षा
home.removePassword.title=पासवर्ड हटाएं
home.removePassword.desc=अपने पीडीएफ़ दस्तावेज़ से पासवर्ड सुरक्षा को हटाएं।
removePassword.tags=सुरक्षित, डिक्रिप्ट, सुरक्षा, पासवर्ड हटाएं, पासवर्ड मिटाएं
home.compressPdfs.title=संकुचित करें (कम्प्रेस)
home.compressPdfs.desc=फ़ाइल का आकार कम करने के लिए PDF को कम्प्रेस करें।
compressPdfs.tags=स्क्विश, छोटा, छोटा
home.changeMetadata.title=मेटाडेटा बदलें
home.changeMetadata.desc=PDF दस्तावेज़ से मेटाडेटा बदलें/हटाएं/जोड़ें।
changeMetadata.tags=शीर्षक, लेखक, तारीख, निर्माण, समय, प्रकाशक, उत्पादक, आँकड़े
home.fileToPDF.title=फ़ाइल को पीडीएफ़ में रूपांतरित करें
home.fileToPDF.desc=लगभग किसी भी फ़ाइल को पीडीएफ़ में रूपांतरित करें (DOCX, PNG, XLS, PPT, TXT और अधिक)
fileToPDF.tags=परिवर्तन, प्रारूप, दस्तावेज़, चित्र, स्लाइड, पाठ, परिवर्तन, ऑफिस, डॉक्स, वर्ड, एक्सेल, पावरपॉइंट
home.ocr.title=OCR / स्कैन को साफ करें
home.ocr.desc=स्कैन को साफ करता है और पीडीएफ़ में छवियों से पाठ को पहचानता है और टेक्स्ट के रूप में फिर से जोड़ता है।
ocr.tags=पहचान, टेक्स्ट, छवि, स्कैन, पढ़ें, पहचान, पता लगाना, संपादनीय
home.extractImages.title=छवियां निकालें
home.extractImages.desc=पीडीएफ़ से सभी छवियों को निकालता है और उन्हें ज़िप में सहेजता है
extractImages.tags=चित्र, फोटो, सहेजें, संग्रह, ज़िप, कैप्चर, ग्रैब
home.pdfToPDFA.title=PDF से PDF/A में
home.pdfToPDFA.desc=लंबे समय के लिए स्टोरेज के लिए पीडीएफ़ को पीडीएफ़/ए में रूपांतरित करें
pdfToPDFA.tags=संग्रह, लंबे समय के लिए, मानक, परिवर्तन, स्टोरेज, संरक्षण
home.PDFToWord.title=PDF से वर्ड में
home.PDFToWord.desc=PDF को वर्ड प्रारूपों में रूपांतरित करें (DOC, DOCX और ODT)
PDFToWord.tags=doc,docx,odt,word,परिवर्तन,प्रारूप,रूपांतरण,ऑफिस,माइक्रोसॉफ्ट,डॉक फ़ाइल
home.PDFToPresentation.title=PDF से प्रस्तुति में
home.PDFToPresentation.desc=PDF को प्रस्तुति प्रारूपों में रूपांतरित करें (PPT, PPTX और ODP)
PDFToPresentation.tags=स्लाइड,दिखाना,ऑफिस,माइक्रोसॉफ्ट
home.PDFToText.title=PDF से RTF (पाठ) में
home.PDFToText.desc=PDF को पाठ या RTF प्रारूप में रूपांतरित करें
PDFToText.tags=रिचफॉर्मेट, रिचटेक्स्टफॉर्मेट, रिच टेक्स्ट फॉर्मेट
home.PDFToHTML.title=PDF से HTML में
home.PDFToHTML.desc=PDF को HTML प्रारूप में रूपांतरित करें
PDFToHTML.tags=वेब सामग्री, ब्राउज़र अनुकूल
home.PDFToXML.title=PDF से XML में
home.PDFToXML.desc=PDF को XML प्रारूप में रूपांतरित करें
PDFToXML.tags=डेटा-निकालन, संरचित सामग्री, अंतरसंवाद, परिवर्तन, रूपांतरण
home.ScannerImageSplit.title=स्कैन की गई फोटो का पता लगाएं/विभाजित करें
home.ScannerImageSplit.desc=एक फोटो/PDF के भीतर से कई फोटो को विभाजित करता है
ScannerImageSplit.tags=अलग, ऑटो-डिटेक्ट, स्कैन, मल्टी-फोटो, संगठित
home.sign.title=हस्ताक्षर
home.sign.desc=हस्ताक्षर को ड्राइंग, पाठ या छवि के रूप में पीडीएफ़ में जोड़ता है।
sign.tags=अधिकृत करें, आदेश, ड्राइंग-हस्ताक्षर, पाठ-हस्ताक्षर, छवि-हस्ताक्षर
home.flatten.title=समतल करें
home.flatten.desc=पीडीएफ़ से सभी इंटरैक्टिव तत्वों और फ़ॉर्म को हटाएं।
flatten.tags=स्थैतिक, निष्क्रिय करें, गैर-इंटरैक्टिव, सरलीकृत
home.repair.title=मरम्मत
home.repair.desc=किसी कोरप्ट/टूटे हुए पीडीएफ़ को मरम्मत करने का प्रयास करता है।
repair.tags=ठीक करें, पुनर्स्थापित करें, सुधार, पुनर्प्राप्ति
home.removeBlanks.title=खाली पृष्ठ हटाएं
home.removeBlanks.desc=दस्तावेज़ से खाली पृष्ठों का पता लगाता है और हटाता है
removeBlanks.tags=सफ़ाई, सरलीकरण, गैर-सामग्री, संगठित
home.removeAnnotations.title=टिप्पणियाँ हटाएं
home.removeAnnotations.desc=पीडीएफ़ से सभी टिप्पणियाँ/एनोटेशन्स को हटाता है
removeAnnotations.tags=टिप्पणियाँ, हाइलाइट, नोट्स, मार्कअप, हटाएं
home.compare.title=तुलना करें
home.compare.desc=2 पीडीएफ़ दस्तावेज़ों के बीच अंतर को तुलना करता है और दिखाता है
compare.tags=भिन्नता, विविधता, परिवर्तन, विश्लेषण
home.certSign.title=प्रमाणपत्र के साथ हस्ताक्षर करें
home.certSign.desc=पीडीएफ़ को प्रमाणपत्र/कुंजी (PEM/P12) के साथ हस्ताक्षरित करता है।
certSign.tags=प्रमाणीकरण, PEM, P12, आधिकारिक, एन्क्रिप्ट
home.pageLayout.title=मल्टी-पेज लेआउट
home.pageLayout.desc=पीडीएफ़ दस्तावेज़ के कई पेजों को एक ही पेज में मर्ज करता है।
pageLayout.tags=मर्ज, संयोजित, एकल दृश्य, संगठित
home.scalePages.title=पेज का आकार/स्केल समायोजित करें
home.scalePages.desc=पेज और/या उसकी सामग्री का आकार/स्केल बदलें।
scalePages.tags=रीसाइज़, संशोधित, आयाम, अनुकूल
home.pipeline.title=पाइपलाइन (उन्नत)
home.pipeline.desc=पाइपलाइन स्क्रिप्ट्स को परिभाषित करके पीडीएफ़ पर कई क्रियाएँ चलाएं
pipeline.tags=स्वचालित करें, क्रम, स्क्रिप्टित, बैच-प्रक्रिया
home.add-page-numbers.title=पेज नंबर जोड़ें
home.add-page-numbers.desc=एक सेट स्थान पर दस्तावेज़ के लिए पेज नंबर जोड़ें
add-page-numbers.tags=पृष्ठांकन, लेबल, संगठन, सूचीकरण
home.auto-rename.title=ऑटो रिनेम पीडीएफ़ फ़ाइल
home.auto-rename.desc=पाया गया है हैडर के आधार पर पीडीएफ़ फ़ाइल को ऑटोमैटिक रूप से नामांकित करता है
auto-rename.tags=ऑटो-डिटेक्ट, हेडर-आधारित, संगठन, नया नाम देना
home.adjust-contrast.title=रंग/कंट्रास्ट समायोजित करें
home.adjust-contrast.desc=पीडीएफ़ का कंट्रास्ट, सैट्युरेशन और ब्राइटनेस समायोजित करें
adjust-contrast.tags=रंग सुधार, ट्यूनिंग, संशोधित करें, बेहतर
home.crop.title=क्रॉप पीडीएफ़
home.crop.desc=पीडीएफ़ का साइज़ कम करने के लिए क्रॉप करें (पाठ को संरक्षित रखें!)
crop.tags=ट्रिम, छोटा करें, संपादित करें, आकार
home.autoSplitPDF.title=ऑटो स्प्लिट पेज्स
home.autoSplitPDF.desc=फिजिकल स्कैन किए गए पेज स्प्लिटर QR कोड के साथ ऑटो स्प्लिट स्कैन किया गया पीडीएफ़
autoSplitPDF.tags=क्यूआर-आधारित, अलग करें, स्कैन-खंड, संगठित
home.sanitizePdf.title=सैनिटाइज़
home.sanitizePdf.desc=पीडीएफ़ फ़ाइलों से स्क्रिप्ट और अन्य तत्वों को हटाता है
sanitizePdf.tags=साफ, सुरक्षित, सुरक्षित, हटाएँ-खतरे
home.URLToPDF.title=URL/वेबसाइट से पीडीएफ़
home.URLToPDF.desc=किसी भी http(s) URL को पीडीएफ़ में रूपांतरित करता है
URLToPDF.tags=वेब-कैप्चर, पेज सहेजें, वेब-से-डॉक, संग्रह
home.HTMLToPDF.title=HTML से पीडीएफ़
home.HTMLToPDF.desc=किसी भी HTML फ़ाइल या ज़िप को पीडीएफ़ में रूपांतरित करता है
HTMLToPDF.tags=मार्कअप, वेब-सामग्री, परिवर्तन, रूपांतरण
home.MarkdownToPDF.title=मार्कडाउन से पीडीएफ़
home.MarkdownToPDF.desc=किसी भी मार्कडाउन फ़ाइल को पीडीएफ़ में रूपांतरित करता है
MarkdownToPDF.tags=मार्कअप, वेब-सामग्री, परिवर्तन, रूपांतरण
home.getPdfInfo.title=पीडीएफ़ पर सभी जानकारी प्राप्त करें
home.getPdfInfo.desc=पीडीएफ़ पर संभावना से सभी सूचना को प्राप्त करता है
getPdfInfo.tags=जानकारी, डेटा, स्टैट्स, सांख्यिकी
home.extractPage.title=पृष्ठ(ओं) को निकालें
home.extractPage.desc=पीडीएफ़ से चयनित पेजों को निकालता है
extractPage.tags=निकालें
home.PdfToSinglePage.title=पीडीएफ़ से एक बड़े पृष्ठ में
home.PdfToSinglePage.desc=सभी पीडीएफ़ पेजों को एक बड़े एकल पृष्ठ में मर्ज करता है
PdfToSinglePage.tags=एकल पृष्ठ
home.showJS.title=जावास्क्रिप्ट दिखाएं
home.showJS.desc=पीडीएफ़ में डाला गया कोई भी जावास्क्रिप्ट खोजता है और प्रदर्शित करता है
showJS.tags=गोपनीयकरण, छिपाना, काला करना, काला, मार्कर, छिपा हुआ
home.autoRedact.title=स्वतः गोपनीयकरण
home.autoRedact.desc=प्रविष्ट पाठ के आधार पर पीडीएफ़ में पाठ को स्वतः गोपनीयकरित(काला करें)
showJS.tags=गोपनीयकरण, छिपाना, काला करना, काला, मार्कर, छिपा हुआ
home.tableExtraxt.title=PDF से CSV में
home.tableExtraxt.desc=CSV में बदलते हुए पीडीएफ़ से तालिकाएँ निकालता है
tableExtraxt.tags=CSV, तालिका निकालना, निकालना, परिवर्तित करना
home.autoSizeSplitPDF.title=साइज़/गणना के आधार पर स्वतः विभाजित करें
home.autoSizeSplitPDF.desc=आकार, पृष्ठ संख्या या दस्तावेज़ संख्या के आधार पर एक पीडीएफ़ को विभाजित करें
autoSizeSplitPDF.tags=पीडीएफ़, विभाजन, दस्तावेज़, संगठन
home.overlay-pdfs.title=पीडीएफ़ ओवरले
home.overlay-pdfs.desc=एक पीडीएफ़ के ऊपर दूसरे पीडीएफ़ को ओवरले करता है
overlay-pdfs.tags=ओवरले
home.split-by-sections.title=खंडों से पीडीएफ़ विभाजित करें
home.split-by-sections.desc=पीडीएफ़ के प्रत्येक पृष्ठ को छोटे से छोटे क्षैतिज और ऊर्ध्वाधर खंडों में विभाजित करें
split-by-sections.tags=खंड विभाजन, विभाजित करें, अनुकूलित
###########################
# #
# WEB PAGES #
# #
###########################
#login
login.title=साइन इन करें
login.signin=साइन इन करें
login.rememberme=मुझे याद रखें
login.invalid=अमान्य उपयोगकर्ता नाम या पासवर्ड।
login.locked=आपका खाता लॉक कर दिया गया है।
login.signinTitle=कृपया साइन इन करें
#auto-redact
autoRedact.title=स्वत: गोपनीयकरण
autoRedact.header=स्वत: गोपनीयकरण
autoRedact.colorLabel=रंग
autoRedact.textsToRedactLabel=गोपनीयकरण के लिए पाठ (लाइनों में अलग)
autoRedact.textsToRedactPlaceholder=जैसे \nगोपनीय \nटॉप-सीक्रेट
autoRedact.useRegexLabel=रेगेक्स का प्रयोग करें
autoRedact.wholeWordSearchLabel=पूरे शब्द की खोज
autoRedact.customPaddingLabel=कस्टम अतिरिक्त पैडिंग
autoRedact.convertPDFToImageLabel=PDF को छवि में बदलें (बॉक्स के पीछे पाठ को हटाने के लिए प्रयोग किया जाता है)
autoRedact.submitButton=प्रस्तुत करें
#showJS
showJS.title=जावास्क्रिप्ट दिखाएं
showJS.header=जावास्क्रिप्ट दिखाएं
showJS.downloadJS=जावास्क्रिप्ट डाउनलोड करें
showJS.submit=दिखाएं
#pdfToSinglePage
pdfToSinglePage.title=पीडीएफ़ से एकल पृष्ठ
pdfToSinglePage.header=पीडीएफ़ से एकल पृष्ठ
pdfToSinglePage.submit=एकल पृष्ठ में परिवर्तित करें
#pageExtracter
pageExtracter.title=पृष्ठों को निकालें
pageExtracter.header=पृष्ठों को निकालें
pageExtracter.submit=निकालें
#getPdfInfo
getPdfInfo.title=पीडीएफ़ पर जानकारी प्राप्त करें
getPdfInfo.header=पीडीएफ़ पर जानकारी प्राप्त करें
getPdfInfo.submit=जानकारी प्राप्त करें
getPdfInfo.downloadJson=JSON डाउनलोड करें
#markdown-to-pdf
MarkdownToPDF.title=मार्कडाउन से पीडीएफ़
MarkdownToPDF.header=मार्कडाउन से पीडीएफ़
MarkdownToPDF.submit=रूपांतरित करें
MarkdownToPDF.help=काम चल रहा है
MarkdownToPDF.credit=WeasyPrint का प्रयोग होता है
#url-to-pdf
URLToPDF.title=URL से पीडीएफ़
URLToPDF.header=URL से पीडीएफ़
URLToPDF.submit=रूपांतरित करें
URLToPDF.credit=WeasyPrint का प्रयोग होता है
#html-to-pdf
HTMLToPDF.title=HTML से पीडीएफ़
HTMLToPDF.header=HTML से पीडीएफ़
HTMLToPDF.help=HTML फ़ाइलों और html/css/images आदि को आत्मसात करने वाले ZIPs को स्वीकार करता है
HTMLToPDF.submit=रूपांतरित करें
HTMLToPDF.credit=WeasyPrint का प्रयोग होता है
#sanitizePDF
sanitizePDF.title=पीडीएफ़ को सफाई करें
sanitizePDF.header=एक पीडीएफ़ फ़ाइल को सफाई करें
sanitizePDF.selectText.1=जावास्क्रिप्ट क्रियाएँ हटाएं
sanitizePDF.selectText.2=एम्बेडेड फ़ाइलें हटाएं
sanitizePDF.selectText.3=मेटाडेटा हटाएं
sanitizePDF.selectText.4=लिंक हटाएं
sanitizePDF.selectText.5=फ़ॉन्ट्स हटाएं
sanitizePDF.submit=पीडीएफ़ को सफाई करें
#addPageNumbers
addPageNumbers.title=पृष्ठ संख्या जोड़ें
addPageNumbers.header=पृष्ठ संख्या जोड़ें
addPageNumbers.selectText.1=पीडीएफ़ फ़ाइल का चयन करें:
addPageNumbers.selectText.2=मार्जिन आकार
addPageNumbers.selectText.3=स्थान
addPageNumbers.selectText.4=शुरुआती संख्या
addPageNumbers.selectText.5=संख्यांकित करने के लिए पृष्ठ
addPageNumbers.selectText.6=कस्टम पाठ
addPageNumbers.customTextDesc=कस्टम पाठ
addPageNumbers.numberPagesDesc=किस पृष्ठों को संख्यांकित करना है, डिफ़ॉल्ट 'सभी', यहां 1-5 या 2,5,9 भी स्वीकार करता है
addPageNumbers.customNumberDesc=डिफ़ॉल्ट {n}, 'पेज {n} का {total}', 'पाठ-{n}', '{filename}-{n}' भी स्वीकार करता है
addPageNumbers.submit=पृष्ठ संख्या जोड़ें
#auto-rename
auto-rename.title=स्वतः नाम परिवर्तन (खुद ब खुद नाम बदलें)
auto-rename.header=स्वतः नाम परिवर्तन पीडीएफ़
auto-rename.submit=स्वतः नाम परिवर्तन
#adjustContrast
adjustContrast.title=कंट्रास्ट समायोजित करें
adjustContrast.header=कंट्रास्ट समायोजित करें
adjustContrast.contrast=कंट्रास्ट:
adjustContrast.brightness=चमक:
adjustContrast.saturation=संतृप्ति:
adjustContrast.download=डाउनलोड
#crop
crop.title=कटौती
crop.header=छवि काटो
crop.submit=प्रस्तुत करें
#autoSplitPDF
autoSplitPDF.title=ऑटो स्प्लिट पीडीएफ
autoSplitPDF.header=ऑटो स्प्लिट पीडीएफ
autoSplitPDF.description=प्रिंट, इंसर्ट, स्कैन, अपलोड करें, और हमें आपके दस्तावेजों को स्वत: अलग करने दें। कोई मैनुअल सॉर्टिंग की आवश्यकता नहीं है।
autoSplitPDF.selectText.1=नीचे से कुछ विभाजक शीट्स प्रिंट करें (काला और सफेद ठीक है)।
autoSplitPDF.selectText.2=सभी दस्तावेजों को एक साथ स्कैन करें, उनके बीच में विभाजक शीट डालें।
autoSplitPDF.selectText.3=एक ही बड़ी स्कैन की गई पीडीएफ फ़ाइल अपलोड करें और स्टर्लिंग पीडीएफ से बाकी का संबोधन करें।
autoSplitPDF.selectText.4=विभाजक पृष्ठ स्वत: पहचाने जाते हैं और हटाए जाते हैं, एक साफ़ अंतिम दस्तावेज़ की गारंटी करते हैं।
autoSplitPDF.formPrompt=स्टर्लिंग-पीडीएफ पेज विभाजक शामिल पीडीएफ प्रस्तुत करें:
autoSplitPDF.duplexMode=डुप्लेक्स मोड (सामने और पीछे स्कैनिंग)
autoSplitPDF.dividerDownload1='ऑटो स्प्लिटर विभाजक (न्यूनतम).pdf' डाउनलोड करें
autoSplitPDF.dividerDownload2='ऑटो स्प्लिटर विभाजक (निर्देशों के साथ).pdf' डाउनलोड करें
autoSplitPDF.submit=प्रस्तुत करें
#pipeline
pipeline.title=पाइपलाइन
#pageLayout
pageLayout.title=मल्टी पेज लेआउट
pageLayout.header=मल्टी पेज लेआउट
pageLayout.pagesPerSheet=प्रति पृष्ठ पेज:
pageLayout.addBorder=सीमा जोड़ें
pageLayout.submit=प्रस्तुत क
#scalePages
scalePages.title=पृष्ठ-स्केल समायोजित करें
scalePages.header=पृष्ठ-स्केल समायोजित करें
scalePages.pageSize=दस्तावेज़ के पृष्ठ का आकार।
scalePages.scaleFactor=पृष्ठ का ज़ूम स्तर (क्रॉप)।
scalePages.submit=प्रस्तुत करें
#certSign
certSign.title=प्रमाणपत्र साइनिंग
certSign.header=अपने प्रमाणपत्र के साथ एक पीडीएफ़ पर हस्ताक्षर करें (काम जारी है)
certSign.selectPDF=साइन करने के लिए एक पीडीएफ़ फ़ाइल का चयन करें:
certSign.selectKey=अपनी निजी कुंजी फ़ाइल का चयन करें (PKCS#8 प्रारूप, .pem या .der हो सकता है):
certSign.selectCert=अपनी प्रमाणपत्र फ़ाइल का चयन करें (X.509 प्रारूप, .pem या .der हो सकता है):
certSign.selectP12=अपनी PKCS#12 कीस्टोर फ़ाइल का चयन करें (.p12 या .pfx) (वैकल्पिक, यदि प्रदान की गई हो, तो इसमें आपकी निजी कुंजी और प्रमाणपत्र होना चाहिए):
certSign.certType=प्रमाणपत्र प्रकार
certSign.password=अपनी कीस्टोर या निजी कुंजी पासवर्ड दर्ज करें (यदि कोई हो):
certSign.showSig=हस्ताक्षर दिखाएं
certSign.reason=कारण
certSign.location=स्थान
certSign.name=नाम
certSign.submit=पीडीएफ़ पर हस्ताक्षर करें
#removeBlanks
removeBlanks.title=खाली पेज हटाएं
removeBlanks.header=खाली पेज हटाएं
removeBlanks.threshold=पिक्सेल गोराई थ्रेशोल्ड:
removeBlanks.thresholdDesc='सफेद' क्लास बनाने के लिए पिक्सेल कितना सफेद होना चाहिए यह तय करने के लिए थ्रेशोल्ड। 0 = काला, 255 पूरी सफेद।
removeBlanks.whitePercent=सफेद प्रतिशत (%):
removeBlanks.whitePercentDesc='सफेद' पिक्सेल हटाए जाने के लिए पृष्ठ का प्रतिशत।
removeBlanks.submit=खाली पेज हटाएं
#removeAnnotations
removeAnnotations.title=एनोटेशन्स हटाएं
removeAnnotations.header=एनोटेशन्स हटाएं
removeAnnotations.submit=हटाएं
#compare
compare.title=तुलना करें
compare.header=पीडीएफ़ तुलना करें
compare.document.1=दस्तावेज़ 1
compare.document.2=दस्तावेज़ 2
compare.submit=तुलना करें
#sign
sign.title=हस्ताक्षर
sign.header=पीडीएफ़ पर हस्ताक्षर करें
sign.upload=छवि अपलोड करें
sign.draw=हस्ताक्षर बनाएँ
sign.text=पाठ इनपुट
sign.clear=साफ़ करें
sign.add=जोड़ें
#repair
repair.title=मरम्मत
repair.header=पीडीएफ़ मरम्मत करें
repair.submit=मरम्मत
#flatten
flatten.title=समतल करें
flatten.header=पीडीएफ़ समतल करें
flatten.submit=समतल करें
#ScannerImageSplit
ScannerImageSplit.selectText.1=कोण थ्रेशोल्ड:
ScannerImageSplit.selectText.2=छवि को घुमाने के लिए आवश्यक न्यूनतम स्पष्ट कोण को सेट करता है (डिफ़ॉल्ट: 10)।
ScannerImageSplit.selectText.3=तौररी:
ScannerImageSplit.selectText.4=पूर्वानुमानित पृष्ठभूमि रंग के आस-पास के रंग परिवर्तन की श्रेणी तय करता है (डिफ़ॉल्ट: 30)।
ScannerImageSplit.selectText.5=न्यूनतम क्षेत्र:
ScannerImageSplit.selectText.6=फोटो के लिए न्यूनतम क्षेत्र थ्रेशोल्ड को सेट करता है (डिफ़ॉल्ट: 10000)।
ScannerImageSplit.selectText.7=न्यूनतम कंटोर क्षेत्र:
ScannerImageSplit.selectText.8=फोटो के लिए न्यूनतम कंटोर क्षेत्र थ्रेशोल्ड को सेट करता है।
ScannerImageSplit.selectText.9=बॉर्डर का आकार:
ScannerImageSplit.selectText.10=निकालने और जोड़ने के लिए जोड़ा जाने वाला बॉर्डर का आकार सेट करता है ताकि आउटपुट में सफेद बॉर्डर न आए (डिफ़ॉल्ट: 1)।
#OCR
ocr.title=OCR / स्कैन सफाई
ocr.header=स्कैन सफाई / OCR (ऑप्टिकल कैरेक्टर रिकग्निशन)
ocr.selectText.1=PDF में जिन भाषाओं का पता लगाया जाना है (जो वर्तमान में पता लगाए गए हैं):
ocr.selectText.2=OCR के साथ OCR टेक्स्ट को सहित टेक्स्ट फ़ाइल बनाएँ
ocr.selectText.3=यहाँ चयन करें की क्या आप OCR'ed पीडीएफ़ के साथ स्क्यूड एंगल पर स्कैन किये गए पेज को सही करना चाहते हैं।
ocr.selectText.4=पेज को साफ करें ताकि OCR बैकग्राउंड नॉइज़ में टेक्स्ट न ढूंढे। (कोई आउटपुट परिवर्तन नहीं होगा)
ocr.selectText.5=पेज को साफ करें ताकि OCR बैकग्राउंड नॉइज़ में टेक्स्ट कम से कम ढूंढे, आउटपुट में सफाई बनाए रखता है।
ocr.selectText.6=यह पेज को अन्दर्स्टैंड करने वाले पेज को छोड़ देगा, जो सिर्फ़ इमेजेस पर OCR करेगा
ocr.selectText.7=जब OCR चालू होता है, तो हर पेज को OCR करेगा और सभी मूल टेक्स्ट तत्वों को हटा देगा
ocr.selectText.8=सामान्य (यदि पीडीएफ़ में टेक्स्ट है तो त्रुटि होगी)
ocr.selectText.9=अतिरिक्त सेटिंग्स
ocr.selectText.10=OCR मोड
ocr.selectText.11=OCR के बाद छवियां हटाएँ (सभी छवियां हटाएँ, केवल परिवर्तन चरण का हिस्सा होता है)
ocr.selectText.12=रेंडर टाइप (उन्नत)
ocr.help=कृपया इस डॉक्यूमेंटेशन को पढ़ें कि इसे अन्य भाषाओं के लिए कैसे उपयोग किया जाता है और/या डॉकर में नहीं हैं
ocr.credit=इस सेवा में OCRmyPDF और टेसरेक्ट का उपयोग होता है।
ocr.submit=OCR के साथ PDF प्रोसेस करें
#extractImages
extractImages.title=छवियां निकालें
extractImages.header=छवियां निकालें
extractImages.selectText=निकाली गई छवियों को कन्वर्ट करने के लिए छवि प्रारूप चुनें
extractImages.submit=निकालें
#File to PDF
fileToPDF.title=फ़ाइल से पीडीएफ़
fileToPDF.header=किसी भी फ़ाइल को पीडीएफ़ में बदलें
fileToPDF.credit=यह सेवा फ़ाइल परिवर्तन के लिए LibreOffice और Unoconv का उपयोग करती है।
fileToPDF.supportedFileTypes=समर्थित फ़ाइल प्रकार नीचे दिए गए होने चाहिए हालांकि समर्थित प्रारूपों की पूरी अद्यतन सूची के लिए कृपया LibreOffice दस्तावेज़ीकरण से संदर्भित करें
fileToPDF.submit=पीडीएफ़ में बदलें
#compress
compress.title=संकुचित करें
compress.header=PDF को संकुचित करें
compress.credit=यह सेवा PDF संकुचन/अनुकूलन के लिए Ghostscript का उपयोग करती है।
compress.selectText.1=मैनुअल मोड - 1 से 4 तक
compress.selectText.2=अनुकूलन स्तर:
compress.selectText.3=4 (पाठ छवियों के लिए अत्यधिक)
compress.selectText.4=स्वत: मोड - निर्धारित आकार पाने के लिए गुणवत्ता को स्वत: समायोजित करता है
compress.selectText.5=प्रत्याशित PDF आकार (जैसे 25MB, 10.8MB, 25KB)
compress.submit=संकुचित करें
#Add image
addImage.title=छवि जोड़ें
addImage.header=PDF में छवि जोड़ें
addImage.everyPage=हर पृष्ठ?
addImage.upload=छवि जोड़ें
addImage.submit=छवि जोड़ें
#merge
merge.title=मर्ज
merge.header=एक से अधिक PDF एक साथ मर्ज करें (2+)
merge.sortByName=नाम से क्रमबद्ध करें
merge.sortByDate=तारीख से क्रमबद्ध करें
merge.submit=मर्ज करें
#pdfOrganiser
pdfOrganiser.title=पेज व्यवस्थापक
pdfOrganiser.header=PDF पेज व्यवस्थापक
pdfOrganiser.submit=पृष्ठों को पुनः व्यवस्थित करें
#multiTool
multiTool.title=पीडीएफ मल्टी टूल
multiTool.header=पीडीएफ मल्टी टूल
#view pdf
viewPdf.title=पीडीएफ देखें
viewPdf.header=पीडीएफ देखें
#pageRemover
pageRemover.title=पेज हटाने वाला
pageRemover.header=पीडीएफ पेज हटाने वाला
pageRemover.pagesToDelete=हटाने के पेज (पृष्ठ संख्याओं की व्यवस्था के लिए एक कॉमा से अलग संख्याओं की सूची दर्ज करें):
pageRemover.submit=पेज हटाएं
#rotate
rotate.title=पीडीएफ घुमाएं
rotate.header=पीडीएफ घुमाएं
rotate.selectAngle=चुनें घुमाने का कोण (90 डिग्री के गुणकों में):
rotate.submit=घुमाएं
#merge
split.title=पीडीएफ को विभाजित करें
split.header=पीडीएफ को विभाजित करें
split.desc.1=जिन नंबरों को आप चुनते हैं, वे पृष्ठ संख्या होती हैं जिन पर आप विभाजन करना चाहते हैं।
split.desc.2=इसलिए, 1,3,7-8 का चयन करना एक 10 पृष्ठों के दस्तावेज़ को 6 अलग-अलग पीडीएफ में विभाजित करेगा जैसे:
split.desc.3=दस्तावेज़ #1: पृष्ठ 1
split.desc.4=दस्तावेज़ #2: पृष्ठ 2 और 3
split.desc.5=दस्तावेज़ #3: पृष्ठ 4, 5 और 6
split.desc.6=दस्तावेज़ #4: पृष्ठ 7
split.desc.7=दस्तावेज़ #5: पृष्ठ 8
split.desc.8=दस्तावेज़ #6: पृष्ठ 9 और 10
split.splitPages=विभाजन करने के लिए पृष्ठ दर्ज करें:
split.submit=विभाजित करें
#merge
imageToPDF.title=छवि से पीडीएफ में
imageToPDF.header=छवि से पीडीएफ में
imageToPDF.submit=परिवर्तित करें
imageToPDF.selectLabel=छवि फिट विकल्प
imageToPDF.fillPage=पेज भरें
imageToPDF.fitDocumentToImage=पेज को छवि के आकार में फिट करें
imageToPDF.maintainAspectRatio=प्रमाण अनुपात बनाए रखें
imageToPDF.selectText.2=पीडीएफ को ऑटो रोटेट करें
imageToPDF.selectText.3=मल्टी फ़ाइल तर्क (केवल यदि कई छवियों के साथ काम किया जा रहा है)
imageToPDF.selectText.4=एक ही पीडीएफ में मर्ज करें
imageToPDF.selectText.5=अलग-अलग पीडीएफ में परिवर्तित करें
#pdfToImage
pdfToImage.title=पीडीएफ से छवि
pdfToImage.header=पीडीएफ से छवि
pdfToImage.selectText=छवि प्रारूप
pdfToImage.singleOrMultiple=पेज से छवि परिणाम प्रकार
pdfToImage.single=एक बड़ी छवि, सभी पेजों को कंबाइन करें
pdfToImage.multi=कई छवियाँ, प्रति पेज एक छवि
pdfToImage.colorType=रंग प्रकार
pdfToImage.color=रंगीन
pdfToImage.grey=ग्रे स्केल
pdfToImage.blackwhite=काला और सफेद (डेटा खो सकता है!)
pdfToImage.submit=परिवर्तित करें
#addPassword
addPassword.title=पासवर्ड जोड़ें
addPassword.header=पासवर्ड जोड़ें (एन्क्रिप्ट)
addPassword.selectText.1=एन्क्रिप्ट करने के लिए पीडीएफ चुनें
addPassword.selectText.2=उपयोगकर्ता पासवर्ड
addPassword.selectText.3=एन्क्रिप्शन की लंबाई
addPassword.selectText.4=अधिक मान मजबूत होते हैं, लेकिन कम मानों में अधिक संगतता होती है।
addPassword.selectText.5=सेट करने की अनुमतियाँ (स्वामी पासवर्ड के साथ प्रयोग किया जाना सिफारिश है)
addPassword.selectText.6=दस्तावेज़ के संघटन को रोकें
addPassword.selectText.7=सामग्री निष्कर्षण को रोकें
addPassword.selectText.8=पहुंचनीयता के लिए निष्कर्षण को रोकें
addPassword.selectText.9=फॉर्म भरने को रोकें
addPassword.selectText.10=संशोधन को रोकें
addPassword.selectText.11=टिप्पणी संशोधन को रोकें
addPassword.selectText.12=छापने को रोकें
addPassword.selectText.13=विभिन्न प्रारूपों में छापने को रोकें
addPassword.selectText.14=स्वामी पासवर्ड
addPassword.selectText.15=दस्तावेज़ के साथ क्या किया जा सकता है, इसे खोलने के बाद (सभी रीडर्स द्वारा समर्थित नहीं है)
addPassword.selectText.16=दस्तावेज़ का खोलना परिमित करें
addPassword.submit=एन्क्रिप्ट करें
#watermark
watermark.title=वॉटरमार्क जोड़ें
watermark.header=वॉटरमार्क जोड़ें
watermark.selectText.1=वॉटरमार्क जोड़ने के लिए पीडीएफ चुनें:
watermark.selectText.2=वॉटरमार्क टेक्स्ट:
watermark.selectText.3=फ़ॉन्ट साइज़:
watermark.selectText.4=रोटेशन (0-360):
watermark.selectText.5=चौड़ाई स्पेसर (प्रत्येक वॉटरमार्क के बीच की जगह आंतरिक रूप से):
watermark.selectText.6=ऊंचाई स्पेसर (प्रत्येक वॉटरमार्क के बीच की जगह लंबवती रूप से):
watermark.selectText.7=अपारदर्शिता (0% - 100%):
watermark.selectText.8=वॉटरमार्क प्रकार:
watermark.selectText.9=वॉटरमार्क छवि:
watermark.submit=वॉटरमार्क जोड़ें
#Change permissions
permissions.title=अनुमतियाँ बदलें
permissions.header=अनुमतियाँ बदलें
permissions.warning=इन अनुमतियों को अथवा इन्हें बदलने से बचाने के लिए, यह सुनिश्चित करने के लिए सुझाव दिया जाता है कि आप इन्हें एक पासवर्ड के साथ जोड़े, जैसे कि विशेषज्ञता जोड़ने पृष्ठ पर
permissions.selectText.1=अनुमतियाँ बदलने के लिए पीडीएफ चुनें
permissions.selectText.2=निर्धारित करने के लिए अनुमतियाँ
permissions.selectText.3=दस्तावेज़ का संघटन रोकें
permissions.selectText.4=सामग्री निकासी रोकें
permissions.selectText.5=पहुंचनीयता के लिए निकासी रोकें
permissions.selectText.6=फ़ॉर्म भरना रोकें
permissions.selectText.7=संशोधन रोकें
permissions.selectText.8=टिप्पणी संशोधन रोकें
permissions.selectText.9=प्रिंटिंग रोकें
permissions.selectText.10=विभिन्न प्रारूपों में प्रिंटिंग रोकें
permissions.submit=बदलें
#remove password
removePassword.title=पासवर्ड हटाएं
removePassword.header=पासवर्ड हटाएं (डिक्रिप्ट)
removePassword.selectText.1=डिक्रिप्ट करने के लिए पीडीएफ चुनें
removePassword.selectText.2=पासवर्ड
removePassword.submit=हटाएं
#changeMetadata
changeMetadata.title=शीर्षक:
changeMetadata.header=मेटाडेटा बदलें
changeMetadata.selectText.1=कृपया उन चरों को संपादित करें जिन्हें आप बदलना चाहते हैं
changeMetadata.selectText.2=सभी मेटाडेटा हटाएं
changeMetadata.selectText.3=कस्टम मेटाडेटा दिखाएं:
changeMetadata.author=लेखक:
changeMetadata.creationDate=निर्माण तिथि (yyyy/MM/dd HH:mm:ss):
changeMetadata.creator=निर्माता:
changeMetadata.keywords=कीवर्ड्स:
changeMetadata.modDate=संशोधन तिथि (yyyy/MM/dd HH:mm:ss):
changeMetadata.producer=निर्माता:
changeMetadata.subject=विषय:
changeMetadata.title=शीर्षक:
changeMetadata.trapped=फंसा हुआ:
changeMetadata.selectText.4=अन्य मेटाडेटा:
changeMetadata.selectText.5=कस्टम मेटाडेटा एंट्री जोड़ें
changeMetadata.submit=बदलें
#pdfToPDFA
pdfToPDFA.title=PDF से PDF/A में
pdfToPDFA.header=PDF से PDF/A में
pdfToPDFA.credit=इस सेवा में PDF/A परिवर्तन के लिए OCRmyPDF का उपयोग किया जाता है।
pdfToPDFA.submit=परिवर्तित करें
#PDFToWord
PDFToWord.title=PDF से वर्ड
PDFToWord.header=PDF से वर्ड
PDFToWord.selectText.1=आउटपुट फ़ाइल प्रारूप
PDFToWord.credit=यह सेवा फ़ाइल परिवर्तन के लिए LibreOffice का उपयोग करती है।
PDFToWord.submit=परिवर्तित करें
#PDFToPresentation
PDFToPresentation.title=PDF से प्रस्तुति
PDFToPresentation.header=PDF से प्रस्तुति
PDFToPresentation.selectText.1=आउटपुट फ़ाइल प्रारूप
PDFToPresentation.credit=यह सेवा फ़ाइल परिवर्तन के लिए LibreOffice का उपयोग करती है।
PDFToPresentation.submit=परिवर्तित करें
#PDFToText
PDFToText.title=PDF से RTF (पाठ)
PDFToText.header=PDF से RTF (पाठ)
PDFToText.selectText.1=आउटपुट फ़ाइल प्रारूप
PDFToText.credit=यह सेवा फ़ाइल परिवर्तन के लिए LibreOffice का उपयोग करती है।
PDFToText.submit=परिवर्तित करें
#PDFToHTML
PDFToHTML.title=PDF से HTML
PDFToHTML.header=PDF से HTML
PDFToHTML.credit=यह सेवा फ़ाइल परिवर्तन के लिए LibreOffice का उपयोग करती है।
PDFToHTML.submit=परिवर्तित करें
#PDFToXML
PDFToXML.title=PDF से XML
PDFToXML.header=PDF से XML
PDFToXML.credit=यह सेवा फ़ाइल परिवर्तन के लिए LibreOffice का उपयोग करती है।
PDFToXML.submit=परिवर्तित करें
#PDFToCSV
PDFToCSV.title=PDF से CSV
PDFToCSV.header=PDF से CSV
PDFToCSV.prompt=टेबल निकालने के लिए पृष्ठ चुनें
PDFToCSV.submit=निकालें
#split-by-size-or-count
split-by-size-or-count.header=आकार या गणना द्वारा PDF को विभाजित करें
split-by-size-or-count.type.label=स्प्लिट प्रकार चुनें
split-by-size-or-count.type.size=आकार द्वारा
split-by-size-or-count.type.pageCount=पृष्ठ गणना द्वारा
split-by-size-or-count.type.docCount=दस्तावेज़ गणना द्वारा
split-by-size-or-count.value.label=मूल्य दर्ज करें
split-by-size-or-count.value.placeholder=आकार दर्ज करें (उदाहरण के लिए, 2MB या 3KB) या गणना (उदाहरण के लिए, 5)
split-by-size-or-count.submit=प्रस्तुत करें
#overlay-pdfs
overlay-pdfs.header=PDF फ़ाइलों को ओवरले करें
overlay-pdfs.baseFile.label=मूल PDF फ़ाइल का चयन करें
overlay-pdfs.overlayFiles.label=ओवरले करने वाली PDF फ़ाइलें चुनें
overlay-pdfs.mode.label=ओवरले मोड का चयन करें
overlay-pdfs.mode.sequential=क्रमशः ओवरले करें
overlay-pdfs.mode.interleaved=इंटरलीव्ड ओवरले करें
overlay-pdfs.mode.fixedRepeat=निश्चित पुनरावृत्ति ओवरले करें
overlay-pdfs.counts.label=ओवरले की संख्या (निश्चित पुनरावृत्ति मोड के लिए)
overlay-pdfs.counts.placeholder=कमा-विराम दिया गया संख्या दर्ज करें (उदाहरण के लिए, 2,3,1)
overlay-pdfs.position.label=ओवरले की स्थिति का चयन करें
overlay-pdfs.position.foreground=पृष्ठरेखा
overlay-pdfs.position.background=पृष्ठमाध्य
overlay-pdfs.submit=प्रस्तुत करें
#split-by-sections
split-by-sections.title=अनुभागों में PDF को विभाजित करें
split-by-sections.header=खंडों में PDF को विभाजित करें
split-by-sections.horizontal.label=क्षैतिज विभाजन
split-by-sections.vertical.label=लंबवत विभाजन
split-by-sections.horizontal.placeholder=क्षैतिज विभाजन की संख्या दर्ज करें
split-by-sections.vertical.placeholder=लंबवत विभाजन की संख्या दर्ज करें
split-by-sections.submit=PDF को विभाजित करें

View File

@@ -0,0 +1,896 @@
###########
# Generic #
###########
# the direction that the language is written (ltr=left to right, rtl = right to left)
language.direction=ltr
pdfPrompt=Válasszon PDF-fájlokat
multiPdfPrompt=Válasszon PDF-fájlokat (2+)
multiPdfDropPrompt=Válassza ki (vagy húzza ide) az összes szükséges PDF-fájlt
imgPrompt=Válasszon képeket
genericSubmit=Beküldés
processTimeWarning=Figyelmeztetés: Ez a folyamat akár egy percig is eltarthat a fájlmérettől függően
pageOrderPrompt=Egyedi oldalsorrend (Adjon meg vesszővel elválasztott oldalszámokat vagy függvényeket, például 2n+1):
goToPage=Ugrás
true=Igaz
false=Hamis
unknown=Ismeretlen
save=Mentés
close=Bezárás
filesSelected=kiválasztott fájlok
noFavourites=Nincs hozzáadva kedvenc
bored=Unatkozol?
alphabet=Ábécé
downloadPdf=PDF letöltése
text=Szöveg
font=Betűtípus
selectFillter=-- Válasszon --
pageNum=Oldalszám
sizes.small=Kicsi
sizes.medium=Közepes
sizes.large=Nagy
sizes.x-large=X-Nagy
error.pdfPassword=A PDF-dokumentum jelszóval védett, és vagy nem adták meg a jelszót, vagy helytelen volt
delete=Törlés
username=Felhasználónév
password=Jelszó
welcome=Üdvözöljük
property=Tulajdonság
black=Fekete
white=Fehér
red=Piros
green=Zöld
blue=Kék
custom=Egyedi...
changedCredsMessage=A hitelek megváltoztak!
notAuthenticatedMessage=Felhasználó nincs hitelesítve.
userNotFoundMessage=A felhasználó nem található.
incorrectPasswordMessage=A jelenlegi jelszó helytelen.
usernameExistsMessage=Az új felhasználónév már létezik.
#############
# NAVBAR #
#############
navbar.convert=Átalakítás
navbar.security=Biztonság
navbar.other=Egyéb
navbar.darkmode=Sötét mód
navbar.pageOps=Lap műveletek
navbar.settings=Beállítások
#############
# SETTINGS #
#############
settings.title=Beállítások
settings.update=Frisítés elérhető
settings.appVersion=App Verzió:
settings.downloadOption.title=Válassza ki a letöltési lehetőséget (Egyetlen fájl esetén a nem tömörített letöltésekhez):
settings.downloadOption.1=Nyissa meg ugyanabban az ablakban
settings.downloadOption.2=Nyissa meg új ablakban
settings.downloadOption.3=Töltse le a fájlt
settings.zipThreshold=Fájlok tömörítése, ha a letöltött fájlok száma meghaladja
settings.signOut=Kijelentkezés
settings.accountSettings=Fiókbeállítások
changeCreds.title=Hitelesítés megváltoztatása
changeCreds.header=Frissítse fiókadatait
changeCreds.changeUserAndPassword=Alapértelmezett bejelentkezési adatokat használ. Adjon meg egy új jelszót (és felhasználónevet, ha szeretné)
changeCreds.newUsername=Új felhasználónév
changeCreds.oldPassword=Jelenlegi jelszó
changeCreds.newPassword=Új jelszó
changeCreds.confirmNewPassword=Új jelszó megerősítése
changeCreds.submit=Változtatások elküldése
account.title=Fiókbeállítások
account.accountSettings=Fiókbeállítások
account.adminSettings=Admin Beállítások - Felhasználók megtekintése és hozzáadása
account.userControlSettings=Felhasználói vezérlési beállítások
account.changeUsername=Új felhasználónév
account.changeUsername=Új felhasználónév
account.password=Megerősítő jelszó
account.oldPassword=Régi jelszó
account.newPassword=Új jelszó
account.changePassword=Jelszó módosítása
account.confirmNewPassword=Új jelszó megerősítése
account.signOut=Kijelentkezés
account.yourApiKey=Az Ön API-kulcsa
account.syncTitle=Böngészőbeállítások szinkronizálása a fiókkal
account.settingsCompare=Beállítások összehasonlítása:
account.property=Ingatlan
account.webBrowserSettings=Web Böngésző beállítása
account.syncToBrowser=Szinkronizálás Fiók -> Böngésző
account.syncToAccount=Szinkronizálás Fiók <- Böngésző
adminUserSettings.title=Felhasználói Vezérlési Beállítások
adminUserSettings.header=Adminisztrátori Felhasználói Vezérlési Beállítások
adminUserSettings.admin=Adminisztrátor
adminUserSettings.user=Felhasználó
adminUserSettings.addUser=Új felhasználó hozzáadása
adminUserSettings.roles=Szerepek
adminUserSettings.role=Szerep
adminUserSettings.actions=Műveletek
adminUserSettings.apiUser=Korlátozott API-felhasználó
adminUserSettings.webOnlyUser=Csak webes felhasználó
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Kényszerítse a felhasználót a felhasználónév/jelszó megváltoztatására bejelentkezéskor
adminUserSettings.submit=Felhasználó mentése
#############
# HOME-PAGE #
#############
home.desc=Lokálisan hostolt egyszerű megoldás minden PDF igényéhez.
home.searchBar=Keresés funkciókra...
home.viewPdf.title=PDF Megtekintése
home.viewPdf.desc=Megtekintés, annotálás, szöveg vagy képek hozzáadása
viewPdf.tags=megtekintés,olvasás,annotálás,szöveg,kép
home.multiTool.title=PDF Multi Eszköz
home.multiTool.desc=Egyesítés, forgatás, átrendezés és lapok eltávolítása
multiTool.tags=Multi Eszköz,Multi művelet,UI,kattintás húzás,előtér,ügyfél oldal,interaktív,megfogható,mozgás
home.merge.title=Egyesítés
home.merge.desc=Több PDF egyszerű egyesítése.
merge.tags=egyesítés,Lapműveletek,Háttér,server oldal
home.split.title=Osztás
home.split.desc=PDF-ek felosztása több dokumentumra
split.tags=Lapműveletek,osztás,Több oldal,vágás,server oldal
home.rotate.title=Forgatás
home.rotate.desc=PDF-ek egyszerű forgatása.
rotate.tags=server oldal
home.imageToPdf.title=Kép PDF-be
home.imageToPdf.desc=Kép (PNG, JPEG, GIF) konvertálása PDF-fé.
imageToPdf.tags=konverzió,img,jpg,kép,fotó
home.pdfToImage.title=PDF képpé
home.pdfToImage.desc=PDF konvertálása képpé. (PNG, JPEG, GIF)
pdfToImage.tags=konverzió,img,jpg,kép,fotó
home.pdfOrganiser.title=Szervezés
home.pdfOrganiser.desc=Lapok eltávolítása/átszervezése bármilyen sorrendben
pdfOrganiser.tags=duplex,páros,páratlan,rendezés,mozgatás
home.addImage.title=Kép hozzáadása
home.addImage.desc=Kép hozzáadása a PDF megadott helyére
addImage.tags=img,jpg,kép,fotó
home.watermark.title=Vízjel hozzáadása
home.watermark.desc=Egyéni vízjel hozzáadása a PDF dokumentumhoz.
watermark.tags=Szöveg,ismétlődő,címke,saját,szerzői jog,védjegy,img,jpg,kép,fotó
home.permissions.title=Engedélyek módosítása
home.permissions.desc=Változtassa meg a PDF dokumentum engedélyeit
permissions.tags=olvasás,írás,szerkesztés,nyomtatás
home.removePages.title=Eltávolítás
home.removePages.desc=Szükségtelen lapok törlése a PDF dokumentumból.
removePages.tags=Lapok eltávolítása,lapok törlése
home.addPassword.title=Jelszó hozzáadása
home.addPassword.desc=Titkosítsa a PDF dokumentumát jelszóval.
addPassword.tags=biztonság,biztonságos
home.removePassword.title=Jelszó eltávolítása
home.removePassword.desc=Vegye le a jelszóvédelmet a PDF dokumentumáról.
removePassword.tags=biztonság,Lezárat, biztonság,jelszó törlése
home.compressPdfs.title=Tömörítés
home.compressPdfs.desc=PDF-ek tömörítése a fájlméret csökkentése érdekében.
compressPdfs.tags=szorít,kicsi,miniatűr
home.changeMetadata.title=Metaadatok Módosítása
home.changeMetadata.desc=Metaadatok Módosítása/Eltávolítása/Hozzáadása egy PDF dokumentumból
changeMetadata.tags=Cím,szerző,dátum,alkotás,idő,közzétevő,gyártó,statisztika
home.fileToPDF.title=Fájl konvertálása PDF-be
home.fileToPDF.desc=Közel minden fájl konvertálása PDF-be (DOCX, PNG, XLS, PPT, TXT és más)
fileToPDF.tags=transzformáció,formátum,dokumentum,kép,dia,szöveg,konverzió,iroda,dokumentumok,word,excel,powerpoint
home.ocr.title=OCR / Tisztítás szkennelésekből
home.ocr.desc=Tisztítás szkennelésekből és szöveg észlelése képeken belül egy PDF-ben, majd visszahozza szövegként.
ocr.tags=felismerés,szöveg,kép,szken,gép,felismert,azonosítás,szerkeszthető
home.extractImages.title=Képek kinyerése
home.extractImages.desc=Az összes kép kinyerése egy PDF-ből és mentése zip-be
extractImages.tags=kép,fotó,mentés,archívum,zip,rögzítés,gyűjtés
home.pdfToPDFA.title=PDF >> PDF/A
home.pdfToPDFA.desc=PDF konvertálása PDF/A formátumra hosszú távú tárolás céljából
pdfToPDFA.tags=archívum,hosszú távú,standard,konverzió,tárolás,megőrzés
home.PDFToWord.title=PDF >> Word
home.PDFToWord.desc=PDF konvertálása Word formátumokra (DOC, DOCX és ODT)
PDFToWord.tags=doc,docx,odt,word,transzformáció,formátum,konverzió,iroda,microsoft,docfile
home.PDFToPresentation.title=PDF >> Presentation
home.PDFToPresentation.desc=PDF konvertálása prezentációs formátumokra (PPT, PPTX és ODP)
PDFToPresentation.tags=dia,bemutatás,iroda,microsoft
home.PDFToText.title=PDF >> RTF (szöveg)
home.PDFToText.desc=PDF konvertálása Szöveg vagy RTF formátumra
PDFToText.tags=richformat,rich text format
home.PDFToHTML.title=PDF >> HTML
home.PDFToHTML.desc=PDF konvertálása HTML formátumra
PDFToHTML.tags=web tartalom,böngészőbarát
home.PDFToXML.title=PDF >> XML
home.PDFToXML.desc=PDF konvertálása XML formátumra
PDFToXML.tags=adat-kinyerés,strukturált tartalom,interop,konverzió
home.ScannerImageSplit.title=Szkennelt fotók észlelése/Osztás
home.ScannerImageSplit.desc=Több fénykép szétválasztása egy fénykép/PDF-ben belül
ScannerImageSplit.tags=külön,kép észlelés,szkennelés,többfénykép,szervez
home.sign.title=Aláírás
home.sign.desc=Aláírás hozzáadása PDF-hez rajzzal, szöveggel vagy képpel
sign.tags=jogosítvány,jegyzék,rajzolt-aláírás,szöveg-aláírás,kép-aláírás
home.flatten.title=Lapok laposítása
home.flatten.desc=Minden interaktív elem és űrlap eltávolítása egy PDF-ből
flatten.tags=statikus,dezaktiválás,nem-interaktív,egyszerűsít
home.repair.title=Javítás
home.repair.desc=Megpróbálja helyreállítani a sérült/hiba PDF-t
repair.tags=javítás,visszaállítás,korrektúra,visszaszerzés
home.removeBlanks.title=Üres lapok eltávolítása
home.removeBlanks.desc=Felismeri és eltávolítja az üres lapokat a dokumentumból
removeBlanks.tags=takarítás,egyszerűsítés,nem-tartalom,szervez
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Összehasonlítás
home.compare.desc=Összehasonlítja és megmutatja a különbségeket két PDF dokumentum között
compare.tags=kiemel,ellentét,változások,elemzés
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.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
home.scalePages.title=Oldalméret/skála beállítása
home.scalePages.desc=Oldal méretének/skálájának megváltoztatása és/vagy tartalmának
scalePages.tags=átalakítás,módosítás,méret,alkalmazkodik
home.pipeline.title=Csővezeték (Haladó)
home.pipeline.desc=Több művelet futtatása PDF-eken csővezeték scriptek definiálásával
pipeline.tags=automatizálás,sorrend,szkriptelt,csomag-feldolgozás
home.add-page-numbers.title=Lapok számának hozzáadása
home.add-page-numbers.desc=Lapszám hozzáadása a dokumentumhoz egy meghatározott helyen
add-page-numbers.tags=lapszámozás,címke,szervez,index
home.auto-rename.title=Automatikus átnevezés PDF fájl
home.auto-rename.desc=Automatikusan átnevezi a PDF fájlt a felderített fejléc alapján
auto-rename.tags=auto-felismerés,fejléc-alapú,szervezés,címkézés
home.adjust-contrast.title=Színek/Kontraszt beállítása
home.adjust-contrast.desc=PDF kontrasztjának, telítettségének és világosságának beállítása
adjust-contrast.tags=szín-korrekció,beállítás,módosítás,fokoz
home.crop.title=Crop PDF
home.crop.desc=PDF vágása a méret csökkentése érdekében (a szöveg megőrzése mellett!)
crop.tags=vágás,csökkentés,szerkesztés,forma
home.autoSplitPDF.title=Automatikus oldalak szétválasztása
home.autoSplitPDF.desc=Automatikus szétválasztás a beolvasott oldalas PDF alapján fizikai szkennelt oldal szétválasztó QR kóddal
autoSplitPDF.tags=QR-alapú,külön,szkennel-oldal,szervez
home.sanitizePdf.title=Szankcionálás
home.sanitizePdf.desc=Szankcionálja a szkripteket és egyéb elemeket a PDF fájlokból
sanitizePdf.tags=tisztítás,biztonságos,biztonság,töröl-veszélyek
home.URLToPDF.title=URL/Weboldal PDF-be
home.URLToPDF.desc=Bármely http(s) URL átalakítása PDF-be
URLToPDF.tags=web-rögzítés,oldal-mentés,web-dokumentum,archívum
home.HTMLToPDF.title=HTML PDF-be
home.HTMLToPDF.desc=Bármely HTML fájl vagy tömörített fájl átalakítása PDF-be
HTMLToPDF.tags=markup,web-tartalom,transzformáció,konverzió
home.MarkdownToPDF.title=Markdown PDF-be
home.MarkdownToPDF.desc=Bármely Markdown fájl átalakítása PDF-be
MarkdownToPDF.tags=markup,web-tartalom,transzformáció,konverzió
home.getPdfInfo.title=Összes információ a PDF-ről
home.getPdfInfo.desc=Az összes lehetséges információ beszerzése a PDF-ekről
getPdfInfo.tags=információ,adat,statisztika,statisztika
home.extractPage.title=Lapok kinyerése
home.extractPage.desc=Válassza ki a lapokat a PDF-ből
extractPage.tags=kinyer
home.PdfToSinglePage.title=PDF egyetlen nagy lapba
home.PdfToSinglePage.desc=Az összes PDF lap egyesítése egyetlen nagy lapba
PdfToSinglePage.tags=egyetlen lap
home.showJS.title=JavaScript megjelenítése
home.showJS.desc=Keres és megjelenít bármilyen JS-t, amit beinjektáltak a PDF-be
showJS.tags=Elrejt,Elrejtés,kitakarás,fekete,fekete,marker,elrejtett
home.autoRedact.title=Automatikus Elrejtés
home.autoRedact.desc=Automatikusan kitakar (elrejt) szöveget egy PDF-ben az input szöveg alapján
showJS.tags=Elrejt,Elrejtés,kitakarás,fekete,fekete,marker,elrejtett
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Táblázatok kinyerése a PDF-ből CSV formátumra konvertálva
tableExtraxt.tags=CSV,Táblázat kinyerése,kinyer,konvertál
home.autoSizeSplitPDF.title=Automatikus szétválasztás méret/számláló alapján
home.autoSizeSplitPDF.desc=Egyetlen PDF szétválasztása több dokumentummá méret, oldalszám vagy dokumentum szám alapján
autoSizeSplitPDF.tags=pdf,szétválasztás,dokumentum,szervezet
home.overlay-pdfs.title=PDF fájlok átlapolása
home.overlay-pdfs.desc=PDF fájlok átlapolása egyik dokumentum a másik fölé helyezésével
overlay-pdfs.tags=Átlapolás
home.split-by-sections.title=PDF Szakaszokra osztása
home.split-by-sections.desc=Minden oldal felosztása kisebb vízszintes és függőleges szakaszokra
split-by-sections.tags=Szakasz elosztás, felosztás, testreszabás
###########################
# #
# WEB PAGES #
# #
###########################
#login
login.title=Bejelentkezés
login.signin=Bejelentkezés
login.rememberme=Emlékezz rám
login.invalid=Érvénytelen felhasználónév vagy jelszó!
login.locked=A fiókja zárolva lett!
login.signinTitle=Kérjük, jelentkezzen be!
#auto-redact
autoRedact.title=Érzékeny tartalom eltávolítása
autoRedact.header=Érzékeny tartalom eltávolítása
autoRedact.colorLabel=Szín
autoRedact.textsToRedactLabel=Kivonand szövegek (sorokra bontva)
autoRedact.textsToRedactPlaceholder=például \nBizalmas \nLegfelsőbb Titok
autoRedact.useRegexLabel=Reguláris kifejezés használata
autoRedact.wholeWordSearchLabel=Teljes szó keresése
autoRedact.customPaddingLabel=Egyedi extra kitöltés
autoRedact.convertPDFToImageLabel=PDF átalakítása PDF-képé (a doboz mögötti szöveg eltávolításához)
autoRedact.submitButton=Elküld
#showJS
showJS.title=JavaScript megjelenítése
showJS.header=JavaScript megjelenítése
showJS.downloadJS=JavaScript letöltése
showJS.submit=Megjelenítés
#pdfToSinglePage
pdfToSinglePage.title=PDF egyetlen oldalra
pdfToSinglePage.header=PDF egyetlen oldalra
pdfToSinglePage.submit=Átalakítás egyetlen oldallá
#pageExtracter
pageExtracter.title=Oldalak kinyerése
pageExtracter.header=Oldalak kinyerése
pageExtracter.submit=Kinyerés
#getPdfInfo
getPdfInfo.title=Információk kinyerése a PDF-ről
getPdfInfo.header=Információk kinyerése a PDF-ről
getPdfInfo.submit=Információk kinyerése
getPdfInfo.downloadJson=JSON letöltése
#markdown-to-pdf
MarkdownToPDF.title=Markdown >> PDF
MarkdownToPDF.header=Markdown >> PDF
MarkdownToPDF.submit=Átalakítás
MarkdownToPDF.help=Az átalakítás folyamatban
MarkdownToPDF.credit=WeasyPrint alkalmazása
#url-to-pdf
URLToPDF.title=URL >> PDF
URLToPDF.header=URL >> PDF
URLToPDF.submit=Átalakítás
URLToPDF.credit=WeasyPrint alkalmazása
#html-to-pdf
HTMLToPDF.title=HTML >> PDF
HTMLToPDF.header=HTML >> PDF
HTMLToPDF.help=Elfogad HTML fájlokat és ZIP-fájlokat, amelyek tartalmaznak html/css/képeket stb.
HTMLToPDF.submit=Átalakítás
HTMLToPDF.credit=WeasyPrint alkalmazása
#sanitizePDF
sanitizePDF.title=PDF tisztítása
sanitizePDF.header=PDF fájl megtisztítása
sanitizePDF.selectText.1=JavaScript műveletek eltávolítása
sanitizePDF.selectText.2=Beágyazott fájlok eltávolítása
sanitizePDF.selectText.3=Metaadatok eltávolítása
sanitizePDF.selectText.4=Hivatkozások eltávolítása
sanitizePDF.selectText.5=Betűtípusok eltávolítása
sanitizePDF.submit=PDF tisztítása
#addPageNumbers
addPageNumbers.title=Oldalszámok hozzáadása
addPageNumbers.header=Oldalszámok hozzáadása
addPageNumbers.selectText.1=Válassza ki a PDF fájlt:
addPageNumbers.selectText.2=Margó mérete
addPageNumbers.selectText.3=Pozíció
addPageNumbers.selectText.4=Kezdő szám
addPageNumbers.selectText.5=Oldalak számozása
addPageNumbers.selectText.6=Egyedi szöveg
addPageNumbers.customTextDesc=Egyedi szöveg
addPageNumbers.numberPagesDesc=Melyik oldalakat számozzuk? Alapértelmezés szerint 'mind', vagy megadhatja még így: 1-5, esetleg 2,5,9.
addPageNumbers.customNumberDesc=Alapértelmezés szerint {n}, megadhatja még 'Oldal {n} a {teljes}', 'Szöveg-{n}', '{fájlnév}-{n}' formában.
addPageNumbers.submit=Oldalszámok hozzáadása
#auto-rename
auto-rename.title=Automatikus átnevezés
auto-rename.header=Automatikus átnevezés PDF
auto-rename.submit=Automatikus átnevezés
#adjustContrast
adjustContrast.title=Kontraszt beállítása
adjustContrast.header=Kontraszt beállítása
adjustContrast.contrast=Kontraszt:
adjustContrast.brightness=Fényerő:
adjustContrast.saturation=Színtelítettség:
adjustContrast.download=Letöltés
#crop
crop.title=Körülvágás
crop.header=Kép körülvégésa
crop.submit=Elküldés
#autoSplitPDF
autoSplitPDF.title=Automatikus PDF szétválasztás
autoSplitPDF.header=Automatikus PDF szétválasztás
autoSplitPDF.description=Nyomtasson, helyezzen be, szkenneljen, töltse fel, és hagyja, hogy az automatikus szétválasztás elvégezze a dokumentumok rendezését. A rendezéshez nincs szükség manuális beavatkozásra.
autoSplitPDF.selectText.1=Nyomtasson ki néhány elválasztó lapot lentebb (Fekete-fehér is megfelel).
autoSplitPDF.selectText.2=Helyezze be az összes dokumentumot egyszerre az elválasztó lapok közé történő beillesztéssel.
autoSplitPDF.selectText.3=Töltse fel a készített egyetlen nagy szkennelt PDF fájlt, és hagyja, hogy a Stirling PDF megoldja a többit.
autoSplitPDF.selectText.4=Az elválasztó lapok automatikusan észlelhetők és eltávolíthatók, így garantáltan tiszta lesz a végső dokumentum.
autoSplitPDF.formPrompt=Küldje el a Stirling-PDF oldal-elválasztót tartalmazó PDF-t:
autoSplitPDF.duplexMode=Duplex mód (Elő- és hátlapi szkennelés)
autoSplitPDF.dividerDownload1='Automatikus Szétválasztó Elválasztólap letöltése (minimális).pdf'
autoSplitPDF.dividerDownload2='Automatikus Szétválasztó Elválasztólap letöltése (utasításokkal).pdf'
autoSplitPDF.submit=Elküldés
#pipeline
pipeline.title=Folyamat
#pageLayout
pageLayout.title=Többoldalas elrendezés
pageLayout.header=Többoldalas elrendezés
pageLayout.pagesPerSheet=Oldalak laponként:
pageLayout.addBorder=Keret hozzáadása
pageLayout.submit=Elküldés
#scalePages
scalePages.title=Oldalméret beállítása
scalePages.header=Oldalméret beállítása
scalePages.pageSize=A dokumentum egy oldalának mérete.
scalePages.scaleFactor=Az oldal nagyításának szintje (vágás).
scalePages.submit=Küldés
#certSign
certSign.title=Tanúsítvánnyal történő aláírás
certSign.header=Aláírás PDF tanúsítvánnyal (fejlesztés alatt)
certSign.selectPDF=Válasszon PDF fájlt az aláíráshoz:
certSign.selectKey=Válassza ki a saját kulcsfájlját (PKCS#8 formátum, lehet .pem vagy .der kiterjesztésű):
certSign.selectCert=Válassza ki a tanúsítványfájlját (X.509 formátum, lehet .pem vagy .der kiterjesztésű):
certSign.selectP12=Válassza ki a PKCS#12 kulcstár fájlját (.p12 vagy .pfx) (Opcionális, ha rendelkezésre áll, tartalmaznia kell a privát kulcsot és a tanúsítványt.):
certSign.certType=Tanúsítvány típusa
certSign.password=Adja meg a kulcstár vagy a privát kulcs jelszavát (ha van):
certSign.showSig=Aláírás megjelenítése
certSign.reason=Ok
certSign.location=Hely
certSign.name=Név
certSign.submit=PDF aláírása
#removeBlanks
removeBlanks.title=Üres oldalak eltávolítása
removeBlanks.header=Üres oldalak eltávolítása
removeBlanks.threshold=Pixel fehérség küszöbértéke:
removeBlanks.thresholdDesc=A "fehér" pixel meghatározásához szükséges küszöbérték. 0 = fekete, 255 = tiszta fehér.
removeBlanks.whitePercent=Fehér százalék (%):
removeBlanks.whitePercentDesc=Az oldalakon található 'fehér' pixelek százaléka, amelyek eltávolításra kerülnek.
removeBlanks.submit=Üres oldalak eltávolítása
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Összehasonlítás
compare.header=PDF-ek összehasonlítása
compare.document.1=Dokumentum 1
compare.document.2=Dokumentum 2
compare.submit=Összehasonlítás
#sign
sign.title=Aláírás
sign.header=PDF-ek aláírása
sign.upload=Kép feltöltése
sign.draw=Aláírás rajzolása
sign.text=Szöveg beírása
sign.clear=Törlés
sign.add=Hozzáadás
#repair
repair.title=Javítás
repair.header=PDF-ek javítása
repair.submit=Javítás
#flatten
flatten.title=Kiegyenlítés
flatten.header=PDF-ek kiegyenlítése
flatten.submit=Kiegyenlítés
#ScannerImageSplit
ScannerImageSplit.selectText.1=Szög küszöbértéke:
ScannerImageSplit.selectText.2=Minimális forgatás abszolút szögének meghatározása (alapértelmezett: 10).
ScannerImageSplit.selectText.3=Tolerancia:
ScannerImageSplit.selectText.4=A háttér szín körülbelüli változási tartományának meghatározása (alapértelmezett: 30).
ScannerImageSplit.selectText.5=Minimális terület:
ScannerImageSplit.selectText.6=A fotók minimális területének beállítása (alapértelmezett: 10000).
ScannerImageSplit.selectText.7=Minimális kontúr terület:
ScannerImageSplit.selectText.8=A fotók minimális kontúrterületének beállítása
ScannerImageSplit.selectText.9=Keret mérete:
ScannerImageSplit.selectText.10=A hozzáadott és eltávolított keret méretének beállítása a fehér keretek elkerülése érdekében a kimeneten (alapértelmezett: 1).
#OCR
ocr.title=OCR / szkennelés tisztázása
ocr.header=Szkennelés tisztázása / OCR (Optikai karakterfelismerés)
ocr.selectText.1=Válassza ki azokat a nyelveket, amelyeket fel kell ismerni a PDF-ben (az alább felsoroltak azok, amelyeket jelenleg képesek vagyunk azonosítani):
ocr.selectText.2=Hozzon létre szövegfájlt az OCR szöveg mellett az OCR-es PDF-ben
ocr.selectText.3=Korrigálja azokat az oldalakat, amelyek ferdén lettek beolvasva, és fogassa vissza őket a helyes szögbe
ocr.selectText.4=Tisztítsa meg az oldalt, hogy az OCR pontosabban dolgozzon, ne érzékeljen szöveget a háttérzajban. (Nincs kimeneti változás)
ocr.selectText.5=Tisztítsa meg az oldalt, hogy az OCR pontosabban dolgozzon, ne érzékeljen szöveget a háttérzajban, és a tisztítást a kimeneten is őrizze meg.
ocr.selectText.6=Hagyja figyelmen kívül azokat az oldalakat, amelyeken interaktív szöveg található, csak azon oldalakat dolgozza el OCR-rel, amelyek képek
ocr.selectText.7=OCR kényszerítése, minden oldalt OCR-el, eltávolítva az összes eredeti szövegelemet
ocr.selectText.8=Normál (Hiba esetén, ha a PDF szöveget tartalmaz)
ocr.selectText.9=További beállítások
ocr.selectText.10=OCR mód
ocr.selectText.11=Képek eltávolítása OCR után (Az ÖSSZES kép eltávolítása, csak akkor hasznos, ha a konverzió része)
ocr.selectText.12=Render típusa (Speciális)
ocr.help=Kérjük, olvassa el ezt a dokumentációt az egyéb nyelvek használatához és/vagy a nem Docker-es használathoz.
ocr.credit=Ez a szolgáltatás az OCRmyPDF és a Tesseract OCR használatával működik.
ocr.submit=PDF feldolgozása OCR-rel
#extractImages
extractImages.title=Képek kinyerése
extractImages.header=Képek kinyerése
extractImages.selectText=Válassza ki a képformátumot a kinyert képek konvertálásához
extractImages.submit=Kinyerés
#File to PDF
fileToPDF.title=Fájl PDF dokumentummá alakítása
fileToPDF.header=Konvertáljon bármilyen fájlt PDF dokumentummá
fileToPDF.credit=Ez a szolgáltatás a LibreOffice-t és az Unoconv-ot használja a fájlkonverzióhoz.
fileToPDF.supportedFileTypes=A funkció az alábbi fájltípusokat támogatja, azonban a teljesen friss támogatott formátumok listájáért kérjük, tekintse meg a LibreOffice dokumentációját
fileToPDF.submit=Konvertálás PDF dokumentummá
#compress
compress.title=Tömörítés
compress.header=PDF tömörítése
compress.credit=Ez a szolgáltatás a Ghostscript-et használja a PDF tömörítéséhez/optimalizálásához.
compress.selectText.1=Kézi mód - 1-től 4-ig
compress.selectText.2=Optimalizálási szint:
compress.selectText.3=4 (nem ajánlott a szöveges képekhez)
compress.selectText.4=Automatikus mód - Az automata állítja a minőséget úgy, hogy a beállított méretű PDF-et generálja.
compress.selectText.5=Várt PDF méret (pl. 25MB, 10,8MB, 25KB)
compress.submit=Tömörítés
#Add image
addImage.title=Kép hozzáadása
addImage.header=Kép hozzáadása a PDF-hez
addImage.everyPage=Minden oldal?
addImage.upload=Kép hozzáadása
addImage.submit=Kép hozzáadása
#merge
merge.title=Összevonás
merge.header=Több PDF összevonása (2+)
merge.sortByName=Név szerinti rendezés
merge.sortByDate=Dátum szerinti rendezés
merge.submit=Összevonás
#pdfOrganiser
pdfOrganiser.title=Oldalszervező
pdfOrganiser.header=PDF Oldalszervező
pdfOrganiser.submit=Oldalak átrendezése
#multiTool
multiTool.title=PDF többfunkciós eszköz
multiTool.header=PDF többfunkciós eszköz
#view pdf
viewPdf.title=PDF megtekintése
viewPdf.header=PDF megtekintése
#pageRemover
pageRemover.title=Oldaltörlő
pageRemover.header=PDF oldaltörlő
pageRemover.pagesToDelete=Törlendő oldalak (adja meg az oldalszámok vesszővel elválasztott listáját):
pageRemover.submit=Oldalak törlése
#rotate
rotate.title=PDF forgatás
rotate.header=PDF forgatás
rotate.selectAngle=Válassza ki a forgatási szöget (90 fok egész számú többszörösei):
rotate.submit=Forgatás
#merge
split.title=PDF szétválasztás
split.header=PDF szétválasztás
split.desc.1=A kiválasztott számok a szétválasztani kívánt oldalszámok
split.desc.2=Például az 1,3,7-8 kiválasztása egy 10 oldalas dokumentumot 6 különálló PDF-fé szétválaszt
split.desc.3=Dokumentum #1: Oldal 1
split.desc.4=Dokumentum #2: Oldal 2 és 3
split.desc.5=Dokumentum #3: Oldal 4, 5 és 6
split.desc.6=Dokumentum #4: Oldal 7
split.desc.7=Dokumentum #5: Oldal 8
split.desc.8=Dokumentum #6: Oldal 9 és 10
split.splitPages=Adja meg az oldalakat, amelyekre szét akarja választani:
split.submit=Szétválasztás
#merge
imageToPDF.title=Kép PDF-be
imageToPDF.header=Kép PDF-be
imageToPDF.submit=Átalakítás
imageToPDF.selectLabel=Kép illesztési beállítások
imageToPDF.fillPage=Teljes oldal kitöltése
imageToPDF.fitDocumentToImage=Oldal illesztése a képhez
imageToPDF.maintainAspectRatio=Arányok megtartása
imageToPDF.selectText.2=Automatikus forgatás PDF
imageToPDF.selectText.3=Több fájl logika (csak akkor engedélyezett, ha több képpel dolgozik)
imageToPDF.selectText.4=Egyesítse egyetlen PDF-fé
imageToPDF.selectText.5=Átalakítás különálló PDF-fé
#pdfToImage
pdfToImage.title=PDF képpé alakítása
pdfToImage.header=PDF képpé alakítása
pdfToImage.selectText=Képformátum
pdfToImage.singleOrMultiple=Oldal kép típusa
pdfToImage.single=Egyetlen nagy kép az összes oldallal
pdfToImage.multi=Több kép, egy kép oldalanként
pdfToImage.colorType=Szín típusa
pdfToImage.color=színes
pdfToImage.grey=szürkeárnyalatos
pdfToImage.blackwhite=fekete-fehér (adatvesztéssel járhat!)
pdfToImage.submit=Átalakítás
#addPassword
addPassword.title=Jelszó hozzáadása
addPassword.header=Jelszó hozzáadása (Titkosítás)
addPassword.selectText.1=Válassza ki a titkosítandó PDF-t
addPassword.selectText.2=Felhasználói jelszó
addPassword.selectText.3=Titkosítási kulcs hossza
addPassword.selectText.4=A magasabb értékek erősebbek, de az alacsonyabb értékek jobb kompatibilitást biztosítanak.
addPassword.selectText.5=Beállítandó engedélyek (Ajánlott a Tulajdonos jelszóval együtt használni)
addPassword.selectText.6=Más dokumentummal történő egyesítés megakadályozása
addPassword.selectText.7=Tartalomkivonás megakadályozása
addPassword.selectText.8=Elérhetőség kivonásának megakadályozása
addPassword.selectText.9=Űrlap kitöltésének megakadályozása
addPassword.selectText.10=Módosítás megakadályozása
addPassword.selectText.11=Jegyzet módosításának megakadályozása
addPassword.selectText.12=Nyomtatás megakadályozása
addPassword.selectText.13=Többféle formátumú nyomtatás megakadályozása
addPassword.selectText.14=Tulajdonos jelszó
addPassword.selectText.15=Korlátozza, hogy mi végezhető el a dokumentum megnyitása után (Nem minden olvasó támogatja)
addPassword.selectText.16=Korlátozza a dokumentum megnyithatságát
addPassword.submit=Titkosítás
#watermark
watermark.title=Vízjel hozzáadása
watermark.header=Vízjel hozzáadása
watermark.selectText.1=Válassza ki a PDF-t, amelyhez vízjelet kíván hozzáadni:
watermark.selectText.2=Vízjel szövege:
watermark.selectText.3=Betűméret:
watermark.selectText.4=Forgatás (0-360):
watermark.selectText.5=widthSpacer (Hely a vízjelek között vízszintesen):
watermark.selectText.6=heightSpacer (Hely a vízjelek között függőlegesen):
watermark.selectText.7=Átlátszóság (0% - 100%):
watermark.selectText.8=Vízjel típusa:
watermark.selectText.9=Vízjel képe:
watermark.submit=Vízjel hozzáadása
#Change permissions
permissions.title=Jogosultságok módosítása
permissions.header=Jogosultságok módosítása
permissions.warning=Figyelem: Ahhoz, hogy ezek a jogosultságok ne legyenek később módosíthatók, javasolt a dokumentumhoz jelszót beállítani a Jelszó hozzáadása funkcióval.
permissions.selectText.1=Válassza ki a PDF-fájlt a jogosultságok módosításához
permissions.selectText.2=Beállítandó jogosultságok
permissions.selectText.3=Más dokumentummal történő egyesítés megakadályozása
permissions.selectText.4=Tartalom kivonásának megakadályozása
permissions.selectText.5=Elérhetőség kivonásának megakadályozása
permissions.selectText.6=Űrlap kitöltésének megakadályozása
permissions.selectText.7=Módosítás megakadályozása
permissions.selectText.8=Jegyzet módosításának megakadályozása
permissions.selectText.9=Nyomtatás megakadályozása
permissions.selectText.10=Többféle formátumú nyomtatás megakadályozása
permissions.submit=Módosítás
#remove password
removePassword.title=Jelszó eltávolítása
removePassword.header=Jelszó eltávolítása (dekódolás)
removePassword.selectText.1=Válassza ki a PDF-fájlt a dekódoláshoz
removePassword.selectText.2=Jelszó
removePassword.submit=Eltávolítás
#changeMetadata
changeMetadata.title=Cím:
changeMetadata.header=Metaadatok módosítása
changeMetadata.selectText.1=Kérjük, szerkessze azokat a változókat, amelyeket módosítani szeretne
changeMetadata.selectText.2=Minden metaadat törlése
changeMetadata.selectText.3=Egyedi metaadatok megjelenítése:
changeMetadata.author=Szerző:
changeMetadata.creationDate=Létrehozás dátuma (éééé/hh/nn ÓÓ:PP:MM):
changeMetadata.creator=Létrehozó:
changeMetadata.keywords=Kulcsszavak:
changeMetadata.modDate=Módosítás dátuma (éééé/hh/nn ÓÓ:PP:MM):
changeMetadata.producer=Készítő:
changeMetadata.subject=Tárgy:
changeMetadata.title=Cím:
changeMetadata.trapped=Trapped:
changeMetadata.selectText.4=Egyéb metaadatok:
changeMetadata.selectText.5=Egyedi metaadatbejegyzés hozzáadása
changeMetadata.submit=Módosítás
#pdfToPDFA
pdfToPDFA.title=PDF >> PDF/A
pdfToPDFA.header=PDF >> PDF/A
pdfToPDFA.credit=Ez a szolgáltatás az OCRmyPDF-t használja a PDF/A konverzióhoz
pdfToPDFA.submit=Konvertálás
#PDFToWord
PDFToWord.title=PDF >> Word
PDFToWord.header=PDF >> Word
PDFToWord.selectText.1=Kimeneti fájlformátum
PDFToWord.credit=Ez a szolgáltatás a LibreOffice-t használja a fájlkonverzióhoz.
PDFToWord.submit=Konvertálás
#PDFToPresentation
PDFToPresentation.title=PDF >> prezentáció
PDFToPresentation.header=PDF >> prezentáció
PDFToPresentation.selectText.1=Kimeneti fájlformátum
PDFToPresentation.credit=Ez a szolgáltatás a LibreOffice-t használja a fájlkonverzióhoz.
PDFToPresentation.submit=Konvertálás
#PDFToText
PDFToText.title=PDF >> RTF (szöveg)
PDFToText.header=PDF >> RTF (szöveg)
PDFToText.selectText.1=Kimeneti fájlformátum
PDFToText.credit=Ez a szolgáltatás a LibreOffice-t használja a fájlkonverzióhoz.
PDFToText.submit=Konvertálás
#PDFToHTML
PDFToHTML.title=PDF >> HTML
PDFToHTML.header=PDF >> HTML
PDFToHTML.credit=Ez a szolgáltatás a LibreOffice-t használja a fájlkonverzióhoz.
PDFToHTML.submit=Konvertálás
#PDFToXML
PDFToXML.title=PDF >> XML
PDFToXML.header=PDF >> XML
PDFToXML.credit=Ez a szolgáltatás a LibreOffice-t használja a fájlkonverzióhoz.
PDFToXML.submit=Konvertálás
#PDFToCSV
PDFToCSV.title=PDF >> CSV
PDFToCSV.header=PDF >> CSV
PDFToCSV.prompt=Válassza ki az oldalt a táblázat kinyeréséhez
PDFToCSV.submit=Kinyerés
#split-by-size-or-count
split-by-size-or-count.header=PDF felosztása méret vagy oldalszám alapján
split-by-size-or-count.type.label=Válassza ki a felosztás típusát
split-by-size-or-count.type.size=Méret alapján
split-by-size-or-count.type.pageCount=Oldalszám alapján
split-by-size-or-count.type.docCount=Dokumentumok száma alapján
split-by-size-or-count.value.label=Adja meg az értéket
split-by-size-or-count.value.placeholder=Adja meg a méretet (pl. 2 MB vagy 3 KB) vagy az oldalszámot (pl. 5)
split-by-size-or-count.submit=Elküld
#overlay-pdfs
overlay-pdfs.header=PDF fájlok átfedése
overlay-pdfs.baseFile.label=Válassza ki az alap PDF fájlt
overlay-pdfs.overlayFiles.label=Válassza ki az átfedő PDF fájlokat
overlay-pdfs.mode.label=Válassza ki az átfedés módját
overlay-pdfs.mode.sequential=Soros átfedés
overlay-pdfs.mode.interleaved=Váltott átfedés
overlay-pdfs.mode.fixedRepeat=Rögzített ismétlődő átfedés
overlay-pdfs.counts.label=Átfedések száma (rögzített ismétlődő mód esetén)
overlay-pdfs.counts.placeholder=Adja meg a vesszővel elválasztott számokat (pl. 2,3,1)
overlay-pdfs.position.label=Válassza ki az átfedés pozícióját
overlay-pdfs.position.foreground=Előtér
overlay-pdfs.position.background=Háttér
overlay-pdfs.submit=Elküld
#split-by-sections
split-by-sections.title=PDF szakaszokra osztása
split-by-sections.header=PDF szakaszokra osztása
split-by-sections.horizontal.label=Függőleges szakaszok
split-by-sections.vertical.label=Vízszintes szakaszok
split-by-sections.horizontal.placeholder=Adja meg a vízszintes szakaszok számát
split-by-sections.vertical.placeholder=Adja meg a függőleges szakaszok számát
split-by-sections.submit=Felosztás

View File

@@ -0,0 +1,896 @@
###########
# Generic #
###########
# the direction that the language is written (ltr=left to right, rtl=right to left)
language.direction=ltr
pdfPrompt=Pilih PDF
multiPdfPrompt=Pilih PDF (2+)
multiPdfDropPrompt=Pilih (atau seret & letakkan)) semua PDF yang Anda butuhkan
imgPrompt=Pilih Gambar
genericSubmit=Kirim
processTimeWarning=Peringatan: Proses ini dapat memakan waktu hingga satu menit, tergantung pada ukuran berkas
pageOrderPrompt=Urutan Halaman Khusus (Masukkan daftar nomor halaman yang dipisahkan dengan koma atau Fungsi seperti 2n + 1) :
goToPage=Ke
true=Benar
false=Salah
unknown=Tidak diketahui
save=Simpan
close=Tutup
filesSelected=berkas dipilih
noFavourites=Tidak ada favorit yang ditambahkan
bored=Bosan Menunggu?
alphabet=Abjad
downloadPdf=Unduh PDF
text=Teks
font=Jenis huruf
selectFillter=-- Pilih --
pageNum=Nomor Halaman
sizes.small=Kecil
sizes.medium=Sedang
sizes.large=Besar
sizes.x-large=Sangat Besar
error.pdfPassword=Dokumen PDF disandikan dan kata sandi tidak diberikan atau kata sandi salah
delete=Hapus
username=Nama pengguna
password=Kata sandi
welcome=Selamat Datang
property=Properti
black=Hitam
white=Putih
red=Merah
green=Hijau
blue=Biru
custom=Kustom...
changedCredsMessage=Kredensial berubah!!
notAuthenticatedMessage=Pengguna tidak ter-autentikasi.
userNotFoundMessage=Pengguna tidak ditemukan.
incorrectPasswordMessage=Kata sandi saat ini salah.
usernameExistsMessage=Nama pengguna baru sudah ada.
#############
# NAVBAR #
#############
navbar.convert=Konversi
navbar.security=Keamanan
navbar.other=Lain-lain
navbar.darkmode=Mode Gelap
navbar.pageOps=Operasi Halaman
navbar.settings=Pengaturan
#############
# SETTINGS #
#############
settings.title=Pengaturan
settings.update=Pembaruan tersedia
settings.appVersion=Versi Aplikasi:
settings.downloadOption.title=Pilih opsi unduhan (Untuk unduhan berkas tunggal non zip):
settings.downloadOption.1=Buka di jendela yang sama
settings.downloadOption.2=Buka di jendela baru
settings.downloadOption.3=Unduh berkas
settings.zipThreshold=Berkas zip ketika jumlah berkas yang diunduh melebihi
settings.signOut=Keluar
settings.accountSettings=Pengaturan Akun
changeCreds.title=Ubah Kredensial
changeCreds.header=Perbarui Detail Akun Anda
changeCreds.changeUserAndPassword=Anda menggunakan kredensial masuk default. Masukkan kata sandi baru (dan nama pengguna jika diinginkan)
changeCreds.newUsername=Nama Pengguna Baru
changeCreds.oldPassword=Kata Sandi Saat Ini
changeCreds.newPassword=Kata Sandi Baru
changeCreds.confirmNewPassword=Konfirmasi Kata Sandi Baru
changeCreds.submit=Kirim Perubahan
account.title=Pengaturan Akun
account.accountSettings=Pengaturan Akun
account.adminSettings=Pengaturan Admin - Melihat dan Menambahkan Pengguna
account.userControlSettings=Pengaturan Kontrol Pengguna
account.changeUsername=Ubah Nama Pengguna
account.changeUsername=Ubah Nama Pengguna
account.password=Konfirmasi Kata sandi
account.oldPassword=Kata sandi lama
account.newPassword=Kata Sandi Baru
account.changePassword=Ubah Kata Sandi
account.confirmNewPassword=Konfirmasi Kata Sandi Baru
account.signOut=Keluar
account.yourApiKey=API Key Anda
account.syncTitle=Menyinkronkan pengaturan browser dengan Akun
account.settingsCompare=Perbandingan Pengaturan:
account.property=Properti
account.webBrowserSettings=Pengaturan Peramban Web
account.syncToBrowser=Sinkronisasi Akun -> Browser
account.syncToAccount=Sinkronisasi Akun <- Browser
adminUserSettings.title=Pengaturan Kontrol Pengguna
adminUserSettings.header=Pengaturan Kontrol Admin
adminUserSettings.admin=Admin
adminUserSettings.user=Pengguna
adminUserSettings.addUser=Tambahkan Pengguna Baru
adminUserSettings.roles=Peran
adminUserSettings.role=Peran
adminUserSettings.actions=Tindakan
adminUserSettings.apiUser=Pengguna API Terbatas
adminUserSettings.webOnlyUser=Pengguna Khusus Web
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Memaksa pengguna untuk mengubah nama pengguna/kata sandi saat masuk
adminUserSettings.submit=Simpan Pengguna
#############
# HOME-PAGE #
#############
home.desc=Semua kebutuhan PDF Anda, langsung dari komputer lokal Anda.
home.searchBar=Mencari fitur...
home.viewPdf.title=Lihat PDF
home.viewPdf.desc=Melihat, membuat anotasi, menambahkan teks atau gambar
viewPdf.tags=melihat,membaca,membuat anotasi,teks,gambar
home.multiTool.title=Alat Multi PDF
home.multiTool.desc=Menggabungkan, Memutar, Mengatur Ulang, dan Menghapus halaman
multiTool.tags=Alat multi,Operasi multi,UI,klik seret,front end,sisi klien,interaktif,sulit diatur,pindah
home.merge.title=Menggabungkan
home.merge.desc=Gabungkan beberapa PDF dengan mudah menjadi satu.
merge.tags=menggabungkan,Pengoperasian halaman,Back end,sisi server
home.split.title=Membagi
home.split.desc=Membagi PDF menjadi beberapa dokumen
split.tags=Pengoperasian halaman,membagi,Multi Halaman,memotong,sisi server
home.rotate.title=Putar
home.rotate.desc=Memutar PDF Anda dengan mudah.
rotate.tags=sisi server
home.imageToPdf.title=Gambar ke PDF
home.imageToPdf.desc=Mengonversi gambar (PNG, JPEG, GIF) ke PDF.
imageToPdf.tags=konversi,img,jpg,gambar,foto
home.pdfToImage.title=PDF ke Gambar
home.pdfToImage.desc=Mengonversi PDF ke gambar. (PNG, JPEG, GIF)
pdfToImage.tags=konversi,img,jpg,gambar,foto
home.pdfOrganiser.title=Mengatur
home.pdfOrganiser.desc=Menghapus/Mengatur ulang halaman dalam urutan apa pun
pdfOrganiser.tags=dupleks,genap,ganjil,sortir,pindah
home.addImage.title=Tambahkan gambar
home.addImage.desc=Menambahkan gambar ke lokasi yang ditentukan pada PDF
addImage.tags=img,jpg,gambar,foto
home.watermark.title=Tambahkan watermark
home.watermark.desc=Menambahkan watermark khusus ke dokumen PDF Anda.
watermark.tags=Teks,berulang,label,sendiri,hak cipta,watermark,img,jpg,picture,photo
home.permissions.title=Izin Perubahan
home.permissions.desc=Mengubah izin dokumen PDF Anda
permissions.tags=baca,tulis,sunting,cetak
home.removePages.title=Menghapus
home.removePages.desc=Menghapus halaman yang tidak diinginkan dari dokumen PDF Anda.
removePages.tags=Menghapus halaman,menghapus halaman
home.addPassword.title=Tambahkan Kata Sandi
home.addPassword.desc=Enkripsi dokumen PDF Anda dengan kata sandi.
addPassword.tags=aman,Keamanan
home.removePassword.title=Hapus Kata Sandi
home.removePassword.desc=Menghapus perlindungan kata sandi dari dokumen PDF Anda.
removePassword.tags=aman,Dekripsi,keamanan,buka kata sandi,hapus kata sandi
home.compressPdfs.title=Kompres
home.compressPdfs.desc=Kompres PDF untuk mengurangi ukuran berkas.
compressPdfs.tags=squish, kecil, kecil
home.changeMetadata.title=Ubah Metadata
home.changeMetadata.desc=Mengubah/Menghapus/Menambahkan metadata dari dokumen PDF
changeMetadata.tags==Judul,penulis,tanggal,pembuatan,waktu,penerbit,produser,statistik
home.fileToPDF.title=Mengonversi berkas ke PDF
home.fileToPDF.desc=Mengonversi hampir semua berkas ke PDF (DOCX, PNG, XLS, PPT, TXT dan lain-lain)
fileToPDF.tags=transformasi,format,dokumen,gambar,slide,text,konversi,office,docs,word,excel,powerpoint
home.ocr.title=Pemindaian/Pembersihan OCR
home.ocr.desc=Memindai dan mendeteksi teks dari gambar di dalam PDF dan menambahkannya kembali sebagai teks.
ocr.tags=rekognisi,teks,gambar,pindai,baca,identifikasi,deteksi,dapat diedit
home.extractImages.title=Ekstrak Gambar
home.extractImages.desc=Mengekstrak semua gambar dari PDF dan menyimpannya ke zip
extractImages.tags=gambar, foto, simpan, arsip, zip, tangkap, ambil
home.pdfToPDFA.title=PDF ke PDF/A
home.pdfToPDFA.desc=Konversi PDF ke PDF/A untuk penyimpanan jangka panjang
pdfToPDFA.tags=arsip, jangka panjang, standar, konversi, penyimpanan, pelestarian
home.PDFToWord.title=PDF ke Word
home.PDFToWord.desc=Mengonversi format PDF ke Word (DOC, DOCX, dan ODT)
PDFToWord.tags=doc, docx, odt, kata, transformasi, format, konversi, kantor, microsoft, docfile
home.PDFToPresentation.title=PDF ke Presentasi
home.PDFToPresentation.desc=Mengonversi PDF ke format Presentasi (PPT, PPTX, dan ODP)
PDFToPresentation.tags=slide, pertunjukan, kantor, microsoft
home.PDFToText.title=PDF ke RTF (Teks)
home.PDFToText.desc=Konversi PDF ke format Teks atau RTF
PDFToText.tags=format kaya, format teks kaya, format teks kaya
home.PDFToHTML.title=PDF ke HTML
home.PDFToHTML.desc=Mengonversi PDF ke format HTML
PDFToHTML.tags=konten web, ramah browser
home.PDFToXML.title=PDF ke XML
home.PDFToXML.desc=Mengonversi PDF ke format XML
PDFToXML.tags=ekstraksi data, konten terstruktur, interop, transformasi, konversi
home.ScannerImageSplit.title=Mendeteksi/Memisahkan foto yang dipindai
home.ScannerImageSplit.desc=Memisahkan beberapa foto dari dalam sebuah foto/PDF
ScannerImageSplit.tags=pisahkan, deteksi otomatis, pindai, multi-foto, atur
home.sign.title=Tanda Tangan
home.sign.desc=Menambahkan tanda tangan ke PDF dengan gambar, teks, atau gambar
sign.tags=mengesahkan, inisial, tanda tangan yang digambar, tanda tangan teks, tanda tangan gambar
home.flatten.title=Meratakan
home.flatten.desc=Menghapus semua elemen dan formulir interaktif dari PDF
flatten.tags=statis, nonaktif, non-interaktif, ramping
home.repair.title=Perbaikan
home.repair.desc=Melakukan perbaikan PDF yang rusak/rusak
repair.tags=perbaiki, pulihkan, koreksi, pulihkan
home.removeBlanks.title=Menghapus halaman kosong
home.removeBlanks.desc=Mendeteksi dan menghapus halaman kosong dari dokumen
removeBlanks.tags=membersihkan, merampingkan, non-konten, mengatur
home.removeAnnotations.title=Menghapus Anotasi
home.removeAnnotations.desc=Menghapus semua komentar/anotasi dari PDF
removeAnnotations.tags=komentar, sorot, catatan, markup, hapus
home.compare.title=Bandingkan
home.compare.desc=Membandingkan dan menunjukkan perbedaan antara 2 Dokumen PDF
compare.tags=membedakan, kontras, perubahan, analisis
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.pageLayout.title=Tata Letak Multi-Halaman
home.pageLayout.desc=Menggabungkan beberapa halaman dokumen PDF menjadi satu halaman
pageLayout.tags=menggabungkan, komposit, tampilan tunggal, mengatur
home.scalePages.title=Menyesuaikan ukuran/skala halaman
home.scalePages.desc=Mengubah ukuran/skala halaman dan/atau isinya.
scalePages.tags=mengubah ukuran, memodifikasi, dimensi, mengadaptasi
home.pipeline.title=Pipeline (Lanjutan)
home.pipeline.desc=Menjalankan beberapa tindakan pada PDF dengan mendefinisikan skrip pipeline
pipeline.tags=mengotomatiskan, mengurutkan, menulis, proses batch
home.add-page-numbers.title=Tambahkan Nomor Halaman
home.add-page-numbers.desc=Menambahkan nomor Halaman di seluruh dokumen di lokasi yang ditetapkan
add-page-numbers.tags=beri halaman, beri label, atur, indeks
home.auto-rename.title=Ubah Nama Berkas PDF Secara Otomatis
home.auto-rename.desc=Mengganti nama berkas PDF secara otomatis berdasarkan tajuk yang terdeteksi
auto-rename.tags=deteksi otomatis, berbasis tajuk, atur, beri label ulang
home.adjust-contrast.title=Menyesuaikan Warna/Kontras
home.adjust-contrast.desc=Sesuaikan Kontras, Saturasi, dan Kecerahan PDF
adjust-contrast.tags=koreksi warna, menyetel, memodifikasi, meningkatkan
home.crop.title=Pangkas PDF
home.crop.desc=Pangkas PDF untuk memperkecil ukurannya (mempertahankan teks!)
crop.tags=memangkas, mengecilkan, mengedit, membentuk
home.autoSplitPDF.title=Membagi Halaman Secara Otomatis
home.autoSplitPDF.desc=Membagi PDF yang dipindai secara otomatis dengan Kode QR pembagi halaman yang dipindai secara fisik
autoSplitPDF.tags=Berbasis QR, pisahkan, pindai segmen, atur
home.sanitizePdf.title=Sanitasi
home.sanitizePdf.desc=Menghapus skrip dan elemen lain dari file PDF
sanitizePdf.tags=bersih, terlindungi, aman, menghilangkan ancaman
home.URLToPDF.title=URL/Situs Web ke PDF
home.URLToPDF.desc=Mengonversi URL http apa pun ke PDF
URLToPDF.tags=tangkap web, simpan halaman, web-ke-dok, arsip
home.HTMLToPDF.title=HTML ke PDF
home.HTMLToPDF.desc=Mengonversi berkas HTML atau zip ke PDF
HTMLToPDF.tags=markup, konten web, transformasi, konversi
home.MarkdownToPDF.title=Penurunan harga ke PDF
home.MarkdownToPDF.desc=Mengonversi berkas Markdown apa pun ke PDF
MarkdownToPDF.tags=markup, konten web, transformasi, konversi
home.getPdfInfo.title=Dapatkan Semua Info tentang PDF
home.getPdfInfo.desc=Mengambil setiap dan semua informasi yang mungkin ada pada PDF
getPdfInfo.tags=informasi, data, statistik, statistik
home.extractPage.title=Ekstrak halaman
home.extractPage.desc=Mengekstrak halaman tertentu dari PDF
extractPage.tags=ekstrak
home.PdfToSinglePage.title=PDF ke Satu Halaman Besar
home.PdfToSinglePage.desc=Menggabungkan semua halaman PDF menjadi satu halaman besar
PdfToSinglePage.tags=halaman tunggal
home.showJS.title=Tampilkan Javascript
home.showJS.desc=Mencari dan menampilkan JS apa pun yang disuntikkan ke dalam PDF
showJS.tags=Hapus, Sembunyikan, padamkan, hitam, hitam, penanda, tersembunyi
home.autoRedact.title=Redaksional Otomatis
home.autoRedact.desc=Menyunting Otomatis (Menghitamkan) teks dalam PDF berdasarkan teks masukan
showJS.tags=Hapus, Sembunyikan, padamkan, hitam, hitam, penanda, tersembunyi
home.tableExtraxt.title=PDF ke CSV
home.tableExtraxt.desc=Mengekstrak Tabel dari PDF yang mengonversinya menjadi CSV
tableExtraxt.tags=CSV, Ekstraksi Tabel, ekstrak, konversi
home.autoSizeSplitPDF.title=Pemisahan Otomatis berdasarkan Ukuran/Hitungan
home.autoSizeSplitPDF.desc=Membagi satu PDF menjadi beberapa dokumen berdasarkan ukuran, jumlah halaman, atau jumlah dokumen
autoSizeSplitPDF.tags=pdf, membagi, dokumen, organisasi
home.overlay-pdfs.title=Tumpuk PDF
home.overlay-pdfs.desc=Menumpuk PDF di atas PDF lain
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Membagi PDF berdasarkan Bagian
home.split-by-sections.desc=Membagi setiap halaman PDF menjadi beberapa bagian horizontal dan vertikal yang lebih kecil
split-by-sections.tags=Membagi Bagian, Membagi, Menyesuaikan
###########################
# #
# WEB PAGES #
# #
###########################
#login
login.title=Masuk
login.signin=Masuk
login.rememberme=Ingat saya
login.invalid=Nama pengguna atau kata sandi tidak valid.
login.locked=Akun Anda telah dikunci.
login.signinTitle=Silakan masuk
#auto-redact
autoRedact.title=Redaksional Otomatis
autoRedact.header=Redaksional Otomatis
autoRedact.colorLabel=Warna
autoRedact.textsToRedactLabel=Teks untuk Disunting (dipisahkan baris)
autoRedact.textsToRedactPlaceholder=misalnya \nRahasia \nRahasia Tertinggi
autoRedact.useRegexLabel=Gunakan Regex
autoRedact.wholeWordSearchLabel=Pencarian Seluruh Kata
autoRedact.customPaddingLabel=Padding Ekstra Kustom
autoRedact.convertPDFToImageLabel=Konversi PDF ke PDF-Gambar (Digunakan untuk menghapus teks di belakang kotak)
autoRedact.submitButton=Kirim
#showJS
showJS.title=Tampilkan Javascript
showJS.header=Tampilkan Javascript
showJS.downloadJS=Unduh Javascript
showJS.submit=Tampilkan
#pdfToSinglePage
pdfToSinglePage.title=PDF Ke Halaman Tunggal
pdfToSinglePage.header=PDF Ke Halaman Tunggal
pdfToSinglePage.submit=Konversi ke Halaman Tunggal
#pageExtracter
pageExtracter.title=Ekstrak Halaman
pageExtracter.header=Ekstrak Halaman
pageExtracter.submit=Ekstrak
#getPdfInfo
getPdfInfo.title=Dapatkan Info tentang PDF
getPdfInfo.header=Dapatkan Info tentang PDF
getPdfInfo.submit=Dapatkan Info
getPdfInfo.downloadJson=Unduh JSON
#markdown-to-pdf
MarkdownToPDF.title=Markdown ke PDF
MarkdownToPDF.header=Markdown Ke PDF
MarkdownToPDF.submit=Konversi
MarkdownToPDF.help=Pekerjaan sedang berlangsung
MarkdownToPDF.credit=Menggunakan WeasyPrint
#url-to-pdf
URLToPDF.title=URL ke PDF
URLToPDF.header=URL Ke PDF
URLToPDF.submit=Konversi
URLToPDF.credit=Menggunakan WeasyPrint
#html-to-pdf
HTMLToPDF.title=HTML Ke PDF
HTMLToPDF.header=HTML Ke PDF
HTMLToPDF.help=Menerima berkas HTML dan ZIP yang berisi html / css / gambar, dll yang diperlukan
HTMLToPDF.submit=Konversi
HTMLToPDF.credit=Menggunakan WeasyPrint
#sanitizePDF
sanitizePDF.title=Bersihkan PDF
sanitizePDF.header=Membersihkan berkas PDF
sanitizePDF.selectText.1=Hapus tindakan JavaScript
sanitizePDF.selectText.2=Hapus berkas yang disematkan
sanitizePDF.selectText.3=Hapus metadata
sanitizePDF.selectText.4=Hapus tautan
sanitizePDF.selectText.5=Hapus font
sanitizePDF.submit=Membersihkan PDF
#addPageNumbers
addPageNumbers.title=Tambahkan Nomor Halaman
addPageNumbers.header=Tambahkan Nomor Halaman
addPageNumbers.selectText.1=Pilih berkas PDF:
addPageNumbers.selectText.2=Ukuran Margin
addPageNumbers.selectText.3=Posisi
addPageNumbers.selectText.4=Nomor Awal
addPageNumbers.selectText.5=Halaman ke Nomor
addPageNumbers.selectText.6=Teks Khusus
addPageNumbers.customTextDesc=Teks Khusus
addPageNumbers.numberPagesDesc=Halaman mana yang akan diberi nomor, default 'semua', juga menerima 1-5 atau 2,5,9, dll.
addPageNumbers.customNumberDesc=Default untuk {n}, juga menerima 'Halaman {n} dari {total}', 'Teks-{n}', '{nama berkas}-{n}'
addPageNumbers.submit=Tambahkan Nomor Halaman
#auto-rename
auto-rename.title=Ganti Nama Otomatis
auto-rename.header=Ganti Nama PDF Otomatis
auto-rename.submit=Ganti Nama Otomatis
#adjustContrast
adjustContrast.title=Sesuaikan Kontras
adjustContrast.header=Sesuaikan Kontras
adjustContrast.contrast=Kontras:
adjustContrast.brightness=Kecerahan:
adjustContrast.saturation=Saturasi:
adjustContrast.download=Unduh
#crop
crop.title=Pangkas
crop.header=Pangkas Gambar
crop.submit=Kirim
#autoSplitPDF
autoSplitPDF.title=PDF Pisah Otomatis
autoSplitPDF.header=Pisahkan PDF secara otomatis
autoSplitPDF.description=Cetak, Sisipkan, Pindai, unggah, dan biarkan kami memisahkan dokumen Anda secara otomatis. Tidak perlu menyortir secara manual.
autoSplitPDF.selectText.1=Cetak beberapa lembar pembatas dari bawah (Hitam putih tidak masalah).
autoSplitPDF.selectText.2=Pindai semua dokumen Anda sekaligus dengan memasukkan lembar pembatas di antaranya.
autoSplitPDF.selectText.3=Unggah satu berkas PDF besar yang dipindai dan biarkan Stirling PDF menangani sisanya.
autoSplitPDF.selectText.4=Halaman pembatas secara otomatis terdeteksi dan dihapus, menjamin dokumen akhir yang rapi.
autoSplitPDF.formPrompt=Kirimkan PDF yang berisi pembagi Halaman Stirling-PDF:
autoSplitPDF.duplexMode=Mode Dupleks (Pemindaian depan dan belakang)
autoSplitPDF.dividerDownload1=Unduh 'Pembagi Pembagi Otomatis (minimal).pdf'
autoSplitPDF.dividerDownload2=Unduh 'Pembagi Pembagi Otomatis (dengan instruksi).pdf'
autoSplitPDF.submit=Kirim
#pipeline
pipeline.title=Pipeline
#pageLayout
pageLayout.title=Tata Letak Multi Halaman
pageLayout.header=Tata Letak Multi Halaman
pageLayout.pagesPerSheet=Halaman per lembar:
pageLayout.addBorder=Menambahkan Batas
pageLayout.submit=Kirim
#scalePages
scalePages.title=Sesuaikan skala halaman
scalePages.header=Sesuaikan skala halaman
scalePages.pageSize=Ukuran halaman dokumen.
scalePages.scaleFactor=Tingkat zoom (potong) halaman.
scalePages.submit=Kirim
#certSign
certSign.title=Penandatanganan Sertifikat
certSign.header=Menandatangani PDF dengan sertifikat Anda (Sedang dalam proses)
certSign.selectPDF=Pilih Berkas PDF untuk Penandatanganan:
certSign.selectKey=Pilih Berkas Kunci Pribadi Anda (format PKCS # 8, bisa .pem atau .der):
certSign.selectCert=Pilih Berkas Sertifikat Anda (format X.509, bisa .pem atau .der):
certSign.selectP12=Pilih Berkas Keystore PKCS #12 Anda (.p12 atau .pfx) (Opsional, Jika disediakan, berkas tersebut harus berisi kunci pribadi dan sertifikat Anda):
certSign.certType=Jenis Sertifikat
certSign.password=Masukkan Kata Sandi Kunci atau Kunci Pribadi Anda (Jika Ada):
certSign.showSig=Tampilkan Tanda Tangan
certSign.reason=Alasan
certSign.location=Lokasi
certSign.name=Nama
certSign.submit=Tanda tangani PDF
#removeBlanks
removeBlanks.title=Hapus Halaman Kosong
removeBlanks.header=Remove Blank Pages
removeBlanks.threshold=Ambang Batas Keputihan Piksel:
removeBlanks.thresholdDesc=Ambang batas untuk menentukan seberapa putih piksel putih yang harus diklasifikasikan sebagai 'Putih'. 0=Hitam, 255 putih murni.
removeBlanks.whitePercent=Persen Putih (%):
removeBlanks.whitePercentDesc=Persentase halaman yang harus berupa piksel 'putih' yang akan dihapus
removeBlanks.submit=Hapus Kosong
#removeAnnotations
removeAnnotations.title=Hapus Anotasi
removeAnnotations.header=Hapus Anotasi
removeAnnotations.submit=Hapus
#compare
compare.title=Bandingkan
compare.header=Bandingkan PDF
compare.document.1=Dokumen 1
compare.document.2=Dokumen 2
compare.submit=Bandingkan
#sign
sign.title=Tanda
sign.header=Tandatangani PDF
sign.upload=Unggah Gambar
sign.draw=Gambar Tanda Tangan
sign.text=Masukan Teks
sign.clear=Hapus
sign.add=Tambah
#repair
repair.title=Perbaiki
repair.header=Perbaiki PDF
repair.submit=Perbaiki
#flatten
flatten.title=Ratakan
flatten.header=Ratakan PDF
flatten.submit=Ratakan
#ScannerImageSplit
ScannerImageSplit.selectText.1=Ambang Batas Sudut:
ScannerImageSplit.selectText.2=Menetapkan sudut absolut minimum yang diperlukan agar gambar dapat diputar (default: 10).
ScannerImageSplit.selectText.3=Toleransi:
ScannerImageSplit.selectText.4=Menentukan kisaran variasi warna di sekitar perkiraan warna latar belakang (default: 30).
ScannerImageSplit.selectText.5=Area Minimum:
ScannerImageSplit.selectText.6=Menetapkan ambang batas area minimum untuk foto (default: 10000).
ScannerImageSplit.selectText.7=Area Kontur Minimum:
ScannerImageSplit.selectText.8=Menetapkan ambang batas area kontur minimum untuk foto
ScannerImageSplit.selectText.9=Ukuran Batas:
ScannerImageSplit.selectText.10=Menetapkan ukuran batas yang ditambahkan dan dihapus untuk mencegah batas putih pada output (default: 1).
#OCR
ocr.title=OCR / Pembersihan Pindaian
ocr.header=Pemindaian Pembersihan / OCR (Pengenalan Karakter Optik)
ocr.selectText.1=Pilih bahasa yang akan dideteksi di dalam PDF (Bahasa yang terdaftar adalah bahasa yang saat ini terdeteksi):
ocr.selectText.2=Menghasilkan berkas teks yang berisi teks OCR di samping PDF yang di-OCR
ocr.selectText.3=Halaman yang benar dipindai pada sudut miring dengan memutarnya kembali ke tempatnya
ocr.selectText.4=Halaman yang bersih sehingga kecil kemungkinan OCR akan menemukan teks dalam kebisingan latar belakang. (Tidak ada perubahan output)
ocr.selectText.5=Bersihkan halaman sehingga kecil kemungkinan OCR akan menemukan teks dalam kebisingan latar belakang, mempertahankan pembersihan pada keluaran.
ocr.selectText.6=Mengabaikan halaman yang memiliki teks interaktif, hanya halaman OCR yang berupa gambar
ocr.selectText.7=Memaksa OCR, akan meng-OCR setiap halaman dengan menghapus semua elemen teks asli
ocr.selectText.8=Normal (Akan terjadi kesalahan jika PDF berisi teks)
ocr.selectText.9=Pengaturan Tambahan
ocr.selectText.10=Mode OCR
ocr.selectText.11=Hapus gambar setelah OCR (Menghapus Semua gambar, hanya berguna jika merupakan bagian dari langkah konversi)
ocr.selectText.12=Jenis Render (Lanjutan)
ocr.help=Silakan baca dokumentasi ini tentang cara menggunakan ini untuk bahasa lain dan/atau penggunaan yang tidak ada di docker
ocr.credit=Layanan ini menggunakan OCRmyPDF dan Tesseract untuk OCR.
ocr.submit=Memproses PDF dengan OCR
#extractImages
extractImages.title=Ekstrak Gambar
extractImages.header=Mengekstrak Gambar
extractImages.selectText=Pilih format gambar yang akan dikonversi
extractImages.submit=Ekstrak
#File to PDF
fileToPDF.title=Berkas ke PDF
fileToPDF.header=Mengonversi berkas apa pun ke PDF
fileToPDF.credit=Layanan ini menggunakan LibreOffice dan Unoconv untuk konversi berkas.
fileToPDF.supportedFileTypes=Jenis berkas yang didukung harus mencakup yang di bawah ini, namun untuk daftar lengkap format yang didukung, silakan lihat dokumentasi LibreOffice
fileToPDF.submit=Konversi ke PDF
#compress
compress.title=Kompres
compress.header=Kompres PDF
compress.credit=Layanan ini menggunakan Ghostscript untuk Kompresi/Optimalisasi PDF.
compress.selectText.1=Mode Manual - Dari 1 hingga 4
compress.selectText.2=Tingkat Optimalisasi:
compress.selectText.3=4 (Buruk untuk gambar teks)
compress.selectText.4=Mode Otomatis - Menyesuaikan kualitas secara otomatis untuk mendapatkan PDF dengan ukuran yang tepat
compress.selectText.5=Ukuran PDF yang diharapkan (mis. 25MB, 10,8MB, 25KB)
compress.submit=Kompres
#Add image
addImage.title=Tambahkan Gambar
addImage.header=Tambahkan Gambar ke PDF
addImage.everyPage=Setiap Halaman?
addImage.upload=Tambahkan Gambar
addImage.submit=Tambahkan Gambar
#merge
merge.title=Gabungkan
merge.header=Gabungkan beberapa PDFs (2+)
merge.sortByName=Sortir berdasarkan nama
merge.sortByDate=Sortir berdasrkan tanggal
merge.submit=Gabungkan
#pdfOrganiser
pdfOrganiser.title=Pengaturan Halaman
pdfOrganiser.header=Pengaturan Halaman PDF
pdfOrganiser.submit=Susun ulang halaman
#multiTool
multiTool.title=Alat Multi PDF
multiTool.header=Alat Multi PDF
#view pdf
viewPdf.title=Lihat PDF
viewPdf.header=Lihat PDF
#pageRemover
pageRemover.title=Penghapus Halaman
pageRemover.header=Penghapus Halaman PDF
pageRemover.pagesToDelete=Halaman yang akan dihapus (Masukkan daftar nomor halaman yang dipisahkan dengan koma) :
pageRemover.submit=Hapus Halaman
#rotate
rotate.title=Rotasi PDF
rotate.header=Rotasi PDF
rotate.selectAngle=Pilih sudut rotasi (dalam kelipatan 90 derajat):
rotate.submit=Rotasi
#merge
split.title=Membagi PDF
split.header=Membagi PDF
split.desc.1=Angka yang Anda pilih adalah nomor halaman yang ingin Anda pisahkan
split.desc.2=Dengan demikian, memilih 1,3,7-8 akan membagi dokumen 10 halaman menjadi 6 PDF terpisah:
split.desc.3=Dokumen #1: Halaman 1
split.desc.4=Dokumen #2: Halaman 2 dan 3
split.desc.5=Dokumen #3: Halaman 4, 5 dan 6
split.desc.6=Dokumen #4: Halaman 7
split.desc.7=Dokumen #5: Halaman 8
split.desc.8=Dokumen #6: Halaman 9 dan 10
split.splitPages=Masukkan halaman yang akan dipisah:
split.submit=Pisahkan
#merge
imageToPDF.title=Gambar ke PDF
imageToPDF.header=Gambar ke PDF
imageToPDF.submit=Konversi
imageToPDF.selectLabel=Opsi Kesesuaian Gambar
imageToPDF.fillPage=Isi Halaman
imageToPDF.fitDocumentToImage=Isi Dokumen dengan Gambar
imageToPDF.maintainAspectRatio=Pertahankan aspek rasio
imageToPDF.selectText.2=Putar PDF secara otomatis
imageToPDF.selectText.3=Logika multi berkas (Hanya diaktifkan jika bekerja dengan banyak gambar)
imageToPDF.selectText.4=Gabungkan menjadi satu PDF
imageToPDF.selectText.5=Mengonversi ke PDF yang terpisah
#pdfToImage
pdfToImage.title=PDF ke Gambar
pdfToImage.header=PDF ke Gambar
pdfToImage.selectText=Format Gambar
pdfToImage.singleOrMultiple=Tipe hasil halaman ke gambar
pdfToImage.single=Gambar Besar Tunggal Menggabungkan semua halaman
pdfToImage.multi=Beberapa Gambar, satu gambar per halaman
pdfToImage.colorType=Tipe warna
pdfToImage.color=Warna
pdfToImage.grey=Skala abu-abu
pdfToImage.blackwhite=Black and White (Bisa kehilangan data!)
pdfToImage.submit=Konversi
#addPassword
addPassword.title=Tambahkan kata sandi
addPassword.header=Tambahkan kata sandi (Enkrip)
addPassword.selectText.1=Pilih PDF untuk enkripsi
addPassword.selectText.2=Kata sandi Pengguna
addPassword.selectText.3=Panjang kunci enkripsi
addPassword.selectText.4=Nilai yang lebih tinggi lebih kuat, tetapi nilai yang lebih rendah memiliki kompatibilitas yang lebih baik.
addPassword.selectText.5=Perizinan untuk diubah (Disarankan untuk digunakan bersama dengan kata sandi Pemilik)
addPassword.selectText.6=Pencegahan untuk penyusunan dokumen
addPassword.selectText.7=Pencegahan untuk ekstraksi konten
addPassword.selectText.8=Pencegahan ekstraksi untuk aksesibilitas
addPassword.selectText.9=Pencegahan untuk mengisi formulir
addPassword.selectText.10=Pencegahan untuk pengubahan
addPassword.selectText.11=Pencegahan untuk perubahan anotasi
addPassword.selectText.12=Pencegahan untuk mencetak
addPassword.selectText.13=Pencegahan untuk mencetak format yang berbeda
addPassword.selectText.14=Kata sandi Pemilik
addPassword.selectText.15=Membatasi apa yang dapat dilakukan dengan dokumen setelah dibuka (Tidak didukung oleh semua pembaca)
addPassword.selectText.16=Membatasi pembukaan dokumen itu sendiri
addPassword.submit=Enkripsi
#watermark
watermark.title=Tambahkan Watermark
watermark.header=Tambahkan Watermark
watermark.selectText.1=Pilih PDF untuk menambahkan watermark:
watermark.selectText.2=Text Watermark:
watermark.selectText.3=Ukuran Huruf:
watermark.selectText.4=Rotasi (0-360):
watermark.selectText.5=widthSpacer (Spasi diantara setiap watermark horisontal):
watermark.selectText.6=heightSpacer (Spasi diantara setiap watermark vertikal):
watermark.selectText.7=Opacity (0% - 100%):
watermark.selectText.8=Tipe Watermark:
watermark.selectText.9=Gambar Watermark:
watermark.submit=Tambahkan Watermark
#Change permissions
permissions.title=Ganti Perizinan
permissions.header=Ganti Perizinan
permissions.warning=Peringatan untuk menyetel izin yang tidak dapat diubah, disarankan untuk menyetel izin dengan kata sandi melalui halaman tambah kata sandi
permissions.selectText.1=Pilih PDF untuk mengubah izin
permissions.selectText.2=Perizinan untuk diubah
permissions.selectText.3=Pencegahan untuk penyusunan dokumen
permissions.selectText.4=Pencegahan untuk ekstraksi konten
permissions.selectText.5=Pencegahan ekstraksi untuk aksesibilitas
permissions.selectText.6=Pencegahan untuk mengisi formulir
permissions.selectText.7=Pencegahan untuk pengubahan
permissions.selectText.8=Pencegahan untuk perubahan anotasi
permissions.selectText.9=Pencegahan untuk mencetak
permissions.selectText.10=Pencegahan untuk mencetak format yang berbeda
permissions.submit=Ganti
#remove password
removePassword.title=Hapus kata sandi
removePassword.header=Hapus kata sandi (Dekrip)
removePassword.selectText.1=Pilih PDF yang akan di Dekrip
removePassword.selectText.2=Kata Sandi
removePassword.submit=Hapus
#changeMetadata
changeMetadata.title=Judul:
changeMetadata.header=Ganti Metadata
changeMetadata.selectText.1=Silakan edit variabel yang ingin Anda ubah
changeMetadata.selectText.2=Hapus semua metadata
changeMetadata.selectText.3=Tampilkan Metadata Khusus:
changeMetadata.author=Penulis:
changeMetadata.creationDate=Tanggal Dibuat (yyyy/MM/dd HH:mm:ss):
changeMetadata.creator=Pencipta:
changeMetadata.keywords=Kata kunci:
changeMetadata.modDate=Tangal Diupdate (yyyy/MM/dd HH:mm:ss):
changeMetadata.producer=Produser:
changeMetadata.subject=Subjek:
changeMetadata.title=Judul:
changeMetadata.trapped=Terperangkap:
changeMetadata.selectText.4=Metadata Lain-lain:
changeMetadata.selectText.5=Tambahkan Metadata Khusus
changeMetadata.submit=Ganti
#pdfToPDFA
pdfToPDFA.title=PDF Ke PDF/A
pdfToPDFA.header=PDF ke PDF/A
pdfToPDFA.credit=Layanan ini menggunakan OCRmyPDF untuk konversi PDF/A.
pdfToPDFA.submit=Konversi
#PDFToWord
PDFToWord.title=PDF Ke Word
PDFToWord.header=PDF ke Word
PDFToWord.selectText.1=Hasil format berkas
PDFToWord.credit=Layanan ini menggunakan LibreOffice untuk konversi berkas.
PDFToWord.submit=Konversi
#PDFToPresentation
PDFToPresentation.title=PDF Ke Presentation
PDFToPresentation.header=PDF ke Presentation
PDFToPresentation.selectText.1=Hasil format berkas
PDFToPresentation.credit=Layanan ini menggunakan LibreOffice untuk konversi berkas.
PDFToPresentation.submit=Konversi
#PDFToText
PDFToText.title=PDF Ke RTF (Text)
PDFToText.header=PDF ke RTF (Text)
PDFToText.selectText.1=Hasil format berkas
PDFToText.credit=Layanan ini menggunakan LibreOffice untuk konversi berkas.
PDFToText.submit=Konversi
#PDFToHTML
PDFToHTML.title=PDF Ke HTML
PDFToHTML.header=PDF ke HTML
PDFToHTML.credit=Layanan ini menggunakan LibreOffice untuk konversi berkas.
PDFToHTML.submit=Konversi
#PDFToXML
PDFToXML.title=PDF Ke XML
PDFToXML.header=PDF ke XML
PDFToXML.credit=Layanan ini menggunakan LibreOffice untuk konversi berkas.
PDFToXML.submit=Konversi
#PDFToCSV
PDFToCSV.title=PDF Ke CSV
PDFToCSV.header=PDF ke CSV
PDFToCSV.prompt=Pilih halaman untuk mengambil tabel
PDFToCSV.submit=Ektraksi
#split-by-size-or-count
split-by-size-or-count.header=Pisahkan PDF berdasarkan ukuran atau jumlah
split-by-size-or-count.type.label=Pilih Tipe Split
split-by-size-or-count.type.size=Berdasarkan Ukuran
split-by-size-or-count.type.pageCount=Berdasarkan Jumlah Halaman
split-by-size-or-count.type.docCount=Berdasarkan Jumlah Dokumen
split-by-size-or-count.value.label=Masukkan Jumlah
split-by-size-or-count.value.placeholder=Masukkan ukuran (e.g., 2MB or 3KB) atau hitungan (e.g., 5)
split-by-size-or-count.submit=Kirim
#overlay-pdfs
overlay-pdfs.header=Hamparan berkas PDF
overlay-pdfs.baseFile.label=Pilih basis berkas PDF
overlay-pdfs.overlayFiles.label=Pilih hamparan berkas PDF
overlay-pdfs.mode.label=Pilih Mode Hamparan
overlay-pdfs.mode.sequential=Hamparan Sequential
overlay-pdfs.mode.interleaved=Hamparan Interleaved
overlay-pdfs.mode.fixedRepeat=Hamparan Fixed Repeat
overlay-pdfs.counts.label=Jumlah Overlay (Untuk hamparan fixed repeat)
overlay-pdfs.counts.placeholder=Masukkan hitungan yang dipisahkan oleh koma (e.g., 2,3,1)
overlay-pdfs.position.label=Pilih posisi hamparan
overlay-pdfs.position.foreground=Latar depan
overlay-pdfs.position.background=Latar belakang
overlay-pdfs.submit=Kirim
#split-by-sections
split-by-sections.title=Pisahkan PDF berdasarkan bagian
split-by-sections.header=Pisahkan PDF menjadi beberapa bagian
split-by-sections.horizontal.label=Pembagian Horizontal
split-by-sections.vertical.label=Pembagian Vertikal
split-by-sections.horizontal.placeholder=Input angka untuk pembagian horizontal
split-by-sections.vertical.placeholder=Input angka untuk pembagian vertikal
split-by-sections.submit=Pisahkan PDF

View File

@@ -43,11 +43,11 @@ green=Verde
blue=Blu
custom=Personalizzato
changedCredsMessage=Credentials changed!
notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists.
changedCredsMessage=Credenziali cambiate!
notAuthenticatedMessage=Utente non autenticato.
userNotFoundMessage=Utente non trovato.
incorrectPasswordMessage=La password attuale non è corretta.
usernameExistsMessage=Il nuovo nome utente esiste già.
@@ -77,14 +77,14 @@ settings.accountSettings=Impostazioni Account
changeCreds.title=Change Credentials
changeCreds.header=Update Your Account Details
changeCreds.changeUserAndPassword=You are using default login credentials. Please enter a new password (and username if wanted)
changeCreds.newUsername=New Username
changeCreds.oldPassword=Current Password
changeCreds.newPassword=New Password
changeCreds.confirmNewPassword=Confirm New Password
changeCreds.submit=Submit Changes
changeCreds.title=Cambia credenziali
changeCreds.header=Aggiorna i dettagli del tuo account
changeCreds.changeUserAndPassword=Stai utilizzando le credenziali di accesso predefinite. Inserisci una nuova password (e un nome utente se lo desideri)
changeCreds.newUsername=Nuovo nome utente
changeCreds.oldPassword=Password attuale
changeCreds.newPassword=Nuova Password
changeCreds.confirmNewPassword=Conferma Nuova Password
changeCreds.submit=Invia modifiche
@@ -119,18 +119,24 @@ adminUserSettings.role=Ruolo
adminUserSettings.actions=Azioni
adminUserSettings.apiUser=Utente API limitato
adminUserSettings.webOnlyUser=Utente solo Web
adminUserSettings.forceChange=Force user to change username/password on login
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Forza l'utente a cambiare nome username/password all'accesso
adminUserSettings.submit=Salva utente
#############
# HOME-PAGE #
#############
home.desc=La tua pagina self-hostata per gestire qualsiasi PDF.
home.searchBar=Cerca funzionalità...
home.viewPdf.title=Visualizza PDF
home.viewPdf.desc=Visualizza, annota, aggiungi testo o immagini
viewPdf.tags=visualizzare,leggere,annotare,testo,immagine
home.multiTool.title=Multifunzione PDF
home.multiTool.desc=Unisci, Ruota, Riordina, e Rimuovi pagine
multiTool.tags=Strumento multiplo, operazione multipla, interfaccia utente, trascinamento clic, front-end, lato client
multiTool.tags=Strumento multiplo,operazione multipla,interfaccia utente,trascinamento clic,front-end,lato client
home.merge.title=Unisci
home.merge.desc=Unisci facilmente più PDF in uno.
@@ -138,7 +144,7 @@ merge.tags=unione, operazioni sulla pagina, back end, lato server
home.split.title=Dividi
home.split.desc=Dividi un singolo PDF in più documenti.
split.tags=Operazioni sulla pagina, divisione, multi pagina, taglio, lato server
split.tags=Operazioni sulla pagina,divisione,multi pagina,taglio,lato server
home.rotate.title=Ruota
home.rotate.desc=Ruota un PDF.
@@ -155,7 +161,7 @@ pdfToImage.tags=conversione,img,jpg,immagine,foto
home.pdfOrganiser.title=Organizza
home.pdfOrganiser.desc=Rimuovi/Riordina le pagine in qualsiasi ordine.
pdfOrganiser.tags=duplex,even,odd,sort,move
pdfOrganiser.tags=duplex,pari,dispari,ordinamento,spostamento
home.addImage.title=Aggiungi Immagine
@@ -164,41 +170,41 @@ addImage.tags=img,jpg,picture,photo
home.watermark.title=Aggiungi Filigrana
home.watermark.desc=Aggiungi una filigrana al tuo PDF.
watermark.tags=Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo
watermark.tags=Testo,ripetizione,etichetta,proprio,copyright,marchio,img,jpg,immagine,foto
home.permissions.title=Cambia Permessi
home.permissions.desc=Cambia i permessi del tuo PDF.
permissions.tags=read,write,edit,print
permissions.tags=leggere,scrivere,modificare,stampare
home.removePages.title=Rimuovi
home.removePages.desc=Elimina alcune pagine dal PDF.
removePages.tags=Remove pages,delete pages
removePages.tags=Rimuovere pagine,eliminare pagine
home.addPassword.title=Aggiungi Password
home.addPassword.desc=Crittografa il tuo PDF con una password.
addPassword.tags=secure,security
addPassword.tags=sicuro,sicurezza
home.removePassword.title=Rimuovi Password
home.removePassword.desc=Rimuovi la password dal tuo PDF.
removePassword.tags=secure,Decrypt,security,unpassword,delete password
removePassword.tags=Decriptare,proteggere,rimuovere la password,eliminare la password
home.compressPdfs.title=Comprimi
home.compressPdfs.desc=Comprimi PDF per ridurne le dimensioni.
compressPdfs.tags=squish,small,tiny
compressPdfs.tags=comprimere,piccolo,minuscolo
home.changeMetadata.title=Modifica Proprietà
home.changeMetadata.desc=Modifica/Aggiungi/Rimuovi le proprietà di un documento PDF.
changeMetadata.tags==Title,author,date,creation,time,publisher,producer,stats
changeMetadata.tags==Titolo,autore,data,creazione,ora,editore,produttore,statistiche
home.fileToPDF.title=Converti file in PDF
home.fileToPDF.desc=Converti quasi ogni file in PDF (DOCX, PNG, XLS, PPT, TXT e altro)
fileToPDF.tags=transformation,format,document,picture,slide,text,conversion,office,docs,word,excel,powerpoint
fileToPDF.tags=trasformazione,formato,documento,immagine,diapositiva,testo,conversione,ufficio,documenti,parola,excel,powerpoint
home.ocr.title=OCR / Pulisci scansioni
home.ocr.desc=Pulisci scansioni ed estrai testo da immagini, convertendo le immagini in testo puro.
ocr.tags=recognition,text,image,scan,read,identify,detection,editable
ocr.tags=riconoscimento,testo,immagine,scansione,lettura,identificazione,rilevamento,modificabile
home.extractImages.title=Estrai immagini
@@ -207,120 +213,124 @@ extractImages.tags=picture,photo,save,archive,zip,capture,grab
home.pdfToPDFA.title=Converti in PDF/A
home.pdfToPDFA.desc=Converti un PDF nel formato PDF/A per archiviazione a lungo termine.
pdfToPDFA.tags=archive,long-term,standard,conversion,storage,preservation
pdfToPDFA.tags=archivio,a lungo termine,standard,conversione,archiviazione,conservazione
home.PDFToWord.title=Da PDF a Word
home.PDFToWord.desc=Converti un PDF nei formati Word (DOC, DOCX e ODT)
PDFToWord.tags=doc,docx,odt,word,transformation,format,conversion,office,microsoft,docfile
PDFToWord.tags=doc,docx,odt,word,trasformazione,formato,conversione,office,microsoft,filedoc
home.PDFToPresentation.title=Da PDF a presentazioni
home.PDFToPresentation.desc=Converti un PDF in presentazioni (PPT, PPTX and ODP)
PDFToPresentation.tags=slides,show,office,microsoft
PDFToPresentation.tags=diapositive,mostra,office,microsoft
home.PDFToText.title=Da PDF a testo/RTF
home.PDFToText.desc=Converti un PDF in testo o RTF.
PDFToText.tags=richformat,richtextformat,rich text format
PDFToText.tags=Microsoft Rich Format,formato Rich Text,formato Rich Text
home.PDFToHTML.title=Da PDF ad HTML
home.PDFToHTML.desc=Converti un PDF in HTML.
PDFToHTML.tags=web content,browser friendly
PDFToHTML.tags=contenuto web,facile da usare per il browser
home.PDFToXML.title=Da PDF a XML
home.PDFToXML.desc=Converti un PDF in XML.
PDFToXML.tags=data-extraction,structured-content,interop,transformation,convert
PDFToXML.tags=estrazione dati,contenuto strutturato,interoperabilità,trasformazione,conversione
home.ScannerImageSplit.title=Trova/Dividi foto scansionate
home.ScannerImageSplit.desc=Estrai più foto da una singola foto o PDF.
ScannerImageSplit.tags=separate,auto-detect,scans,multi-photo,organize
ScannerImageSplit.tags=separa,rileva automaticamente,scansiona,multi-foto,organizza
home.sign.title=Firma
home.sign.desc=Aggiungi una firma al PDF da disegno, testo o immagine.
sign.tags=authorize,initials,drawn-signature,text-sign,image-signature
sign.tags=autorizza,iniziali,firma-tracciata,segno-testo,firma-immagine
home.flatten.title=Appiattisci
home.flatten.desc=Rimuovi tutti gli elementi interattivi e moduli da un PDF.
flatten.tags=static,deactivate,non-interactive,streamline
flatten.tags=statico,disattivato,non interattivo,ottimizzato
home.repair.title=Ripara
home.repair.desc=Prova a riparare un PDF corrotto.
repair.tags=fix,restore,correction,recover
repair.tags=aggiustare,ripristinare,correggere,recuperare
home.removeBlanks.title=Rimuovi pagine vuote
home.removeBlanks.desc=Trova e rimuovi pagine vuote da un PDF.
removeBlanks.tags=cleanup,streamline,non-content,organize
removeBlanks.tags=pulire,semplificare,non contenere contenuti,organizzare
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Compara
home.compare.desc=Vedi e compara le differenze tra due PDF.
compare.tags=differentiate,contrast,changes,analysis
compare.tags=differenziare,contrastare,cambiare,analisi
home.certSign.title=Firma con certificato
home.certSign.desc=Firma un PDF con un certificato/chiave (PEM/P12)
certSign.tags=authenticate,PEM,P12,official,encrypt
certSign.tags=autenticare,PEM,P12,ufficiale,crittografare
home.pageLayout.title=Layout multipagina
home.pageLayout.desc=Unisci più pagine di un documento PDF in un'unica pagina
pageLayout.tags=merge,composite,single-view,organize
pageLayout.tags=unire,comporre,visualizzazione singola,organizzare
home.scalePages.title=Regola le dimensioni/scala della pagina
home.scalePages.desc=Modificare le dimensioni/scala della pagina e/o dei suoi contenuti.
scalePages.tags=resize,modify,dimension,adapt
scalePages.tags=ridimensionare,modificare,dimensionare,adattare
home.pipeline.title=Pipeline (avanzato)
home.pipeline.desc=Esegui più azioni sui PDF definendo script di pipeline
pipeline.tags=automate,sequence,scripted,batch-process
pipeline.tags=automatizzare,sequenziare,scriptare,elaborare in batch
home.add-page-numbers.title=Aggiungi numeri di pagina
home.add-page-numbers.desc=Aggiungi numeri di pagina in tutto un documento in una posizione prestabilita
add-page-numbers.tags=paginate,label,organize,index
add-page-numbers.tags=impaginare,etichettare,organizzare,indicizzare
home.auto-rename.title=Rinomina automaticamente il file PDF
home.auto-rename.desc=Rinomina automaticamente un file PDF in base all'intestazione rilevata
auto-rename.tags=auto-detect,header-based,organize,relabel
auto-rename.tags=arilevamento automatico,basato su intestazione,organizzazione,rietichettatura
home.adjust-contrast.title=Regola colori/contrasto
home.adjust-contrast.desc=Regola contrasto, saturazione e luminosità di un PDF
adjust-contrast.tags=color-correction,tune,modify,enhance
adjust-contrast.tags=correzione del colore,messa a punto,modifica,miglioramento
home.crop.title=Ritaglia PDF
home.crop.desc=Ritaglia un PDF per ridurne le dimensioni (mantiene il testo!)
crop.tags=trim,shrink,edit,shape
crop.tags=tagliare,ridurre,modificare,modellare
home.autoSplitPDF.title=Pagine divise automaticamente
home.autoSplitPDF.desc=Dividi automaticamente il PDF scansionato con il codice QR dello divisore di pagina fisico scansionato
autoSplitPDF.tags=QR-based,separate,scan-segment,organize
autoSplitPDF.tags=Basato su QR,separato,scansiona segmenti,organizza
home.sanitizePdf.title=Igienizzare
home.sanitizePdf.title=Pulire
home.sanitizePdf.desc=Rimuovi script e altri elementi dai file PDF
sanitizePdf.tags=clean,secure,safe,remove-threats
sanitizePdf.tags=pulire,proteggere,rimuovere le minacce
home.URLToPDF.title=URL/sito Web in PDF
home.URLToPDF.desc=Converte qualsiasi URL http(s) in PDF
URLToPDF.tags=web-capture,save-page,web-to-doc,archive
URLToPDF.tags=acquisizione web,salvataggio pagina,web-to-doc,archivio
home.HTMLToPDF.title=Da HTML a PDF
home.HTMLToPDF.desc=Converte qualsiasi file HTML o zip in PDF
HTMLToPDF.tags=markup,web-content,transformation,convert
HTMLToPDF.tags=markup,contenuto web,trasformazione,conversione
home.MarkdownToPDF.title=Markdown in PDF
home.MarkdownToPDF.desc=Converte qualsiasi file Markdown in PDF
MarkdownToPDF.tags=markup,web-content,transformation,convert
MarkdownToPDF.tags=markup,contenuto web,trasformazione,conversione
home.getPdfInfo.title=Ottieni TUTTE le informazioni in PDF
home.getPdfInfo.desc=Raccogli tutte le informazioni possibili sui PDF
getPdfInfo.tags=infomation,data,stats,statistics
getPdfInfo.tags=informazioni,dati,stati,statistiche
home.extractPage.title=Estrai pagina/e
home.extractPage.desc=Estrae le pagine selezionate dal PDF
extractPage.tags=extract
extractPage.tags=estrarre
home.PdfToSinglePage.title=PDF in un'unica pagina di grandi dimensioni
home.PdfToSinglePage.desc=Unisce tutte le pagine PDF in un'unica grande pagina
PdfToSinglePage.tags=single page
PdfToSinglePage.tags=pagina singola
home.showJS.title=Mostra Javascript
@@ -331,6 +341,24 @@ home.autoRedact.title=Redazione automatica
home.autoRedact.desc=Redige automaticamente (oscura) il testo in un PDF in base al testo immesso
showJS.tags=JS
home.tableExtraxt.title=Da PDF a CSV
home.tableExtraxt.desc=Estrae tabelle da un PDF convertendolo in CSV
tableExtraxt.tags=CSV,Estrazione tabella,estrai,converti
home.autoSizeSplitPDF.title=Divisione automatica per dimensione/numero
home.autoSizeSplitPDF.desc=Dividi un singolo PDF in più documenti in base alle dimensioni, al numero di pagine o al numero di documenti
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
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
split-by-sections.tags=Dividi sezione, dividi, personalizza
###########################
# #
# WEB PAGES #
@@ -409,14 +437,14 @@ HTMLToPDF.credit=Utilizza WeasyPrint
#sanitizePDF
sanitizePDF.title=Disinfetta PDF
sanitizePDF.header=Disinfettare un file PDF
sanitizePDF.title=Pulire PDF
sanitizePDF.header=Pulisci un file PDF
sanitizePDF.selectText.1=Rimuovi le azioni JavaScript
sanitizePDF.selectText.2=Rimuovi i file incorporati
sanitizePDF.selectText.3=Rimuovi i metadati
sanitizePDF.selectText.4=Rimuovi collegamenti
sanitizePDF.selectText.5=Rimuovi i fonts
sanitizePDF.submit=Disinfetta PDF
sanitizePDF.submit=Pulisci PDF
#addPageNumbers
@@ -429,8 +457,8 @@ addPageNumbers.selectText.4=Numero di partenza
addPageNumbers.selectText.5=Pagine da numerare
addPageNumbers.selectText.6=Testo personalizzato
addPageNumbers.customTextDesc=Testo personalizzato
addPageNumbers.numberPagesDesc=Quali pagine numerare, impostazione predefinita "tutte", accetta anche 1-5 o 2,5,9 ecc
addPageNumbers.customNumberDesc=Il valore predefinito è {n}, accetta anche 'Pagina {n} di {totale}', 'Testo-{n}', '{nomefile}-{n}
addPageNumbers.numberPagesDesc=Quali pagine numerare, impostazione predefinita "all", accetta anche 1-5 o 2,5,9 ecc
addPageNumbers.customNumberDesc=Il valore predefinito è {n}, accetta anche 'Pagina {n} di {total}', 'Testo-{n}', '{filename}-{n}
addPageNumbers.submit=Aggiungi numeri di pagina
@@ -478,10 +506,7 @@ pipeline.title=Pipeline
pageLayout.title=Layout multipagina
pageLayout.header=Layout multipagina
pageLayout.pagesPerSheet=Pagine per foglio:
##########################
### TODO: Translate ###
##########################
pageLayout.addBorder=Add Borders
pageLayout.addBorder=Aggiungi bordi
pageLayout.submit=Invia
@@ -519,6 +544,12 @@ removeBlanks.whitePercentDesc=Percentuale della pagina che deve essere bianca pe
removeBlanks.submit=Rimuovi
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Compara
compare.header=Compara PDF
@@ -635,6 +666,9 @@ pdfOrganiser.submit=Riordina pagine
multiTool.title=Multifunzione PDF
multiTool.header=Multifunzione PDF
#view pdf
viewPdf.title=Visualizza PDF
viewPdf.header=Visualizza PDF
#pageRemover
pageRemover.title=Rimuovi pagine
@@ -669,10 +703,10 @@ split.submit=Dividi
imageToPDF.title=Immagine a PDF
imageToPDF.header=Immagine a PDF
imageToPDF.submit=Converti
imageToPDF.selectLabel=Image Fit Options
imageToPDF.fillPage=Fill Page
imageToPDF.fitDocumentToImage=Fit Page to Image
imageToPDF.maintainAspectRatio=Maintain Aspect Ratios
imageToPDF.selectLabel=Opzioni di adattamento immagine
imageToPDF.fillPage=Riempi la pagina
imageToPDF.fitDocumentToImage=Adatta la pagina all'immagine
imageToPDF.maintainAspectRatio=Mantieni le proporzioni
imageToPDF.selectText.2=Ruota automaticamente PDF
imageToPDF.selectText.3=Logica multi-file (funziona solo se ci sono più immagini)
imageToPDF.selectText.4=Unisci in un unico PDF
@@ -818,3 +852,45 @@ PDFToXML.title=Da PDF a XML
PDFToXML.header=Da PDF a XML
PDFToXML.credit=Questo servizio utilizza LibreOffice per la conversione.
PDFToXML.submit=Converti
#PDFToCSV
PDFToCSV.title=Da PDF a CSV
PDFToCSV.header=Da PDF a CSV
PDFToCSV.prompt=Scegli la pagina per estrarre la tabella
PDFToCSV.submit=Estratto
#split-by-size-or-count
split-by-size-or-count.header=Dividi il PDF per dimensione o numero
split-by-size-or-count.type.label=Seleziona il tipo di divisione
split-by-size-or-count.type.size=Per dimensione
split-by-size-or-count.type.pageCount=Per numero di pagine
split-by-size-or-count.type.docCount=Per numero di documento
split-by-size-or-count.value.label=Inserire il valore
split-by-size-or-count.value.placeholder=Inserisci la dimensione (ad esempio, 2 MB o 3 KB) o il numero (ad esempio, 5)
split-by-size-or-count.submit=Separa
#overlay-pdfs
overlay-pdfs.header=Invia file PDF in sovrapposizione
overlay-pdfs.baseFile.label=Seleziona File PDF di base
overlay-pdfs.overlayFiles.label=Seleziona sovrapposizione file PDF
overlay-pdfs.mode.label=Seleziona la modalità di sovrapposizione
overlay-pdfs.mode.sequential=Sovrapposizione sequenziale
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Inserisci i numeri separati da virgole (ad esempio, 2,3,1)
overlay-pdfs.position.label=Seleziona posizione di sovrapposizione
overlay-pdfs.position.foreground=Primo piano
overlay-pdfs.position.background=Sfondo
overlay-pdfs.submit=Sovrapponi
#split-by-sections
split-by-sections.title=Dividi PDF per sezioni
split-by-sections.header=Dividi il PDF in sezioni
split-by-sections.horizontal.label=Divisioni orizzontali
split-by-sections.vertical.label=Divisioni verticali
split-by-sections.horizontal.placeholder=Inserire il numero di divisioni orizzontali
split-by-sections.vertical.placeholder=Inserire il numero di divisioni verticali
split-by-sections.submit=Dividi PDF

View File

@@ -43,11 +43,11 @@ green=緑
blue=
custom=カスタム...
changedCredsMessage=Credentials changed!
notAuthenticatedMessage=User not authenticated.
userNotFoundMessage=User not found.
incorrectPasswordMessage=Current password is incorrect.
usernameExistsMessage=New Username already exists.
changedCredsMessage=資格情報が変更されました!
notAuthenticatedMessage=ユーザーが認証されていません。
userNotFoundMessage=ユーザーが見つかりません。
incorrectPasswordMessage=現在のパスワードが正しくありません。
usernameExistsMessage=新しいユーザー名はすでに存在します。
@@ -77,14 +77,14 @@ settings.accountSettings=アカウント設定
changeCreds.title=Change Credentials
changeCreds.header=Update Your Account Details
changeCreds.changeUserAndPassword=You are using default login credentials. Please enter a new password (and username if wanted)
changeCreds.newUsername=New Username
changeCreds.oldPassword=Current Password
changeCreds.newPassword=New Password
changeCreds.confirmNewPassword=Confirm New Password
changeCreds.submit=Submit Changes
changeCreds.title=資格情報の変更
changeCreds.header=アカウントの詳細を更新する
changeCreds.changeUserAndPassword=デフォルトのログイン認証情報を使用しています。新しいパスワード (必要に応じてユーザー名も) を入力してください
changeCreds.newUsername=新しいユーザー名
changeCreds.oldPassword=現在のパスワード
changeCreds.newPassword=新しいパスワード
changeCreds.confirmNewPassword=新しいパスワードの確認
changeCreds.submit=変更を送信
@@ -119,15 +119,21 @@ adminUserSettings.role=役割
adminUserSettings.actions=アクション
adminUserSettings.apiUser=限定されたAPIユーザー
adminUserSettings.webOnlyUser=ウェブ専用ユーザー
adminUserSettings.forceChange=Force user to change username/password on login
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=ログイン時にユーザー名/パスワードを強制的に変更する
adminUserSettings.submit=ユーザーの保存
#############
# HOME-PAGE #
#############
home.desc=PDFのあらゆるニーズに対応するローカルホスティングされた総合窓口です。
home.searchBar=機能検索...
home.viewPdf.title=View PDF
home.viewPdf.desc=表示、注釈、テキストや画像の追加
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=PDFマルチツール
home.multiTool.desc=ページの結合、回転、並べ替え、削除します。
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side,interactive,intractable,move
@@ -250,6 +256,10 @@ home.removeBlanks.title=空白ページの削除
home.removeBlanks.desc=ドキュメントから空白ページを検出して削除します。
removeBlanks.tags=cleanup,streamline,non-content,organize
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=比較
home.compare.desc=2つのPDFを比較して表示します。
compare.tags=differentiate,contrast,changes,analysis
@@ -331,6 +341,24 @@ home.autoRedact.title=自動塗りつぶし
home.autoRedact.desc=入力したテキストに基づいてPDF内のテキストを自動で塗りつぶし(黒塗り)します。
showJS.tags=JS
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -478,9 +506,6 @@ pipeline.title=パイプライン
pageLayout.title=マルチページレイアウト
pageLayout.header=マルチページレイアウト
pageLayout.pagesPerSheet=1枚あたりのページ数:
##########################
### TODO: Translate ###
##########################
pageLayout.addBorder=Add Borders
pageLayout.submit=送信
@@ -495,7 +520,7 @@ scalePages.submit=送信
#certSign
certSign.title=証明書による署名
certSign.header=証明書を使用してPDFに署名します。 (進行中)
certSign.header=証明書を使用してPDFに署名します。 (制作中)
certSign.selectPDF=署名するPDFファイルを選択:
certSign.selectKey=秘密キーファイルを選択 (PKCS#8形式、.pemまたは.der) :
certSign.selectCert=証明書ファイルを選択 (X.509形式、.pemまたは.der) :
@@ -519,6 +544,12 @@ removeBlanks.whitePercentDesc=削除するページの白の割合
removeBlanks.submit=空白ページの削除
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=比較
compare.header=PDFの比較
@@ -620,8 +651,8 @@ addImage.submit=画像の追加
#merge
merge.title=結合
merge.header=複数のPDFを結合 (2ファイル以上)
merge.sortByName=Sort by name
merge.sortByDate=Sort by date
merge.sortByName=名前で並べ替え
merge.sortByDate=日付で並べ替え
merge.submit=結合
@@ -635,6 +666,9 @@ pdfOrganiser.submit=ページの整理
multiTool.title=PDFマルチツール
multiTool.header=PDFマルチツール
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=ページ削除
@@ -669,10 +703,10 @@ split.submit=分割
imageToPDF.title=画像をPDFに変換
imageToPDF.header=画像をPDFに変換
imageToPDF.submit=変換
imageToPDF.selectLabel=Image Fit Options
imageToPDF.fillPage=Fill Page
imageToPDF.fitDocumentToImage=Fit Page to Image
imageToPDF.maintainAspectRatio=Maintain Aspect Ratios
imageToPDF.selectLabel=画像フィットオプション
imageToPDF.fillPage=フルページ
imageToPDF.fitDocumentToImage=ページを画像に合わせる
imageToPDF.maintainAspectRatio=アスペクト比を維持する
imageToPDF.selectText.2=PDFの自動回転
imageToPDF.selectText.3=マルチファイルの処理 (複数の画像を操作する場合に有効になります)
imageToPDF.selectText.4=1つのPDFに結合
@@ -818,3 +852,45 @@ PDFToXML.title=PDFをXMLに変換
PDFToXML.header=PDFをXMLに変換
PDFToXML.credit=本サービスはファイル変換にLibreOfficeを使用しています。
PDFToXML.submit=変換
#PDFToCSV
PDFToCSV.title=PDF??CSV?
PDFToCSV.header=PDF??CSV?
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=????
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

File diff suppressed because it is too large Load Diff

View File

@@ -119,6 +119,7 @@ adminUserSettings.role=Rol
adminUserSettings.actions=Acties
adminUserSettings.apiUser=Beperkte API gebruiker
adminUserSettings.webOnlyUser=Alleen web gebruiker
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Force user to change username/password on login
adminUserSettings.submit=Sla gebruiker op
@@ -126,8 +127,13 @@ adminUserSettings.submit=Sla gebruiker op
# HOME-PAGE #
#############
home.desc=Jouw lokaal gehoste one-stop-shop voor al je PDF-behoeften.
home.searchBar=Search for features...
home.viewPdf.title=View PDF
home.viewPdf.desc=View, annotate, add text or images
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=PDF Multitool
home.multiTool.desc=Samenvoegen, draaien, herschikken en pagina''s verwijderen
multiTool.tags=Multitool,Multi bewerking,UI,klik sleep,voorkant,clientzijde,interactief,beweegbaar,verplaats
@@ -250,6 +256,10 @@ home.removeBlanks.title=Verwijder lege pagina''s
home.removeBlanks.desc=Detecteert en verwijdert lege pagina''s uit een document
removeBlanks.tags=opruimen,stroomlijnen,geen-inhoud,organiseren
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Vergelijken
home.compare.desc=Vergelijkt en toont de verschillen tussen 2 PDF-documenten
compare.tags=onderscheiden,contrasteren,veranderingen,analyse
@@ -331,6 +341,24 @@ home.autoRedact.title=Auto Redact
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
showJS.tags=JS
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -478,9 +506,6 @@ pipeline.title=Pijplijn
pageLayout.title=Meerdere pagina indeling
pageLayout.header=Meerdere pagina indeling
pageLayout.pagesPerSheet=Pagina''s per vel:
##########################
### TODO: Translate ###
##########################
pageLayout.addBorder=Add Borders
pageLayout.submit=Indienen
@@ -519,6 +544,12 @@ removeBlanks.whitePercentDesc=Percentage van de pagina dat ''witte'' pixels moet
removeBlanks.submit=Blanco''s verwijderen
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Vergelijken
compare.header=PDF''s vergelijken
@@ -635,6 +666,9 @@ pdfOrganiser.submit=Pagina''s herschikken
multiTool.title=PDF Multitool
multiTool.header=PDF Multitool
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=Pagina verwijderaar
@@ -818,3 +852,45 @@ PDFToXML.title=PDF naar XML
PDFToXML.header=PDF naar XML
PDFToXML.credit=Deze service gebruikt LibreOffice voor bestandsconversie.
PDFToXML.submit=Converteren
#PDFToCSV
PDFToCSV.title=PDF naar CSV
PDFToCSV.header=PDF naar CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Extract
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

View File

@@ -119,6 +119,7 @@ adminUserSettings.role=Role
adminUserSettings.actions=Actions
adminUserSettings.apiUser=Limited API User
adminUserSettings.webOnlyUser=Web Only User
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.forceChange=Force user to change username/password on login
adminUserSettings.submit=Save User
@@ -126,8 +127,13 @@ adminUserSettings.submit=Save User
# HOME-PAGE #
#############
home.desc=Twoja lokalna aplikacja do kompleksowej obsługi Twoich potrzeb związanych z dokumentami PDF.
home.searchBar=Search for features...
home.viewPdf.title=View PDF
home.viewPdf.desc=View, annotate, add text or images
viewPdf.tags=view,read,annotate,text,image
home.multiTool.title=Multi narzędzie PDF
home.multiTool.desc=Łącz, dziel, obracaj, zmieniaj kolejność i usuwaj strony
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
@@ -250,6 +256,10 @@ home.removeBlanks.title=Usuń puste strony
home.removeBlanks.desc=Wykrywa i usuwa puste strony z dokumentu PDF
removeBlanks.tags=cleanup,streamline,non-content,organize
home.removeAnnotations.title=Remove Annotations
home.removeAnnotations.desc=Removes all comments/annotations from a PDF
removeAnnotations.tags=comments,highlight,notes,markup,remove
home.compare.title=Porównaj
home.compare.desc=Porównuje i pokazuje różnice między dwoma dokumentami PDF
compare.tags=differentiate,contrast,changes,analysis
@@ -331,6 +341,24 @@ home.autoRedact.title=Auto Redact
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
showJS.tags=JS
home.tableExtraxt.title=PDF to CSV
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Auto Split by Size/Count
home.autoSizeSplitPDF.desc=Split a single PDF into multiple documents based on size, page count, or document count
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Split PDF by Sections
home.split-by-sections.desc=Divide each page of a PDF into smaller horizontal and vertical sections
split-by-sections.tags=Section Split, Divide, Customize
###########################
# #
# WEB PAGES #
@@ -478,9 +506,6 @@ pipeline.title=Pipeline
pageLayout.title=Układ wielu stron
pageLayout.header=Układ wielu stron
pageLayout.pagesPerSheet=Stron na jednym arkuszu:
##########################
### TODO: Translate ###
##########################
pageLayout.addBorder=Add Borders
pageLayout.submit=Wykonaj
@@ -519,6 +544,12 @@ removeBlanks.whitePercentDesc=Procent strony, która musi być biała, aby zosta
removeBlanks.submit=Usuń puste
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
#compare
compare.title=Porównaj
compare.header=Porównaj PDF(y)
@@ -635,6 +666,9 @@ pdfOrganiser.submit=Zmień kolejność stron
multiTool.title=Multi narzędzie PDF
multiTool.header=Multi narzędzie PDF
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
#pageRemover
pageRemover.title=Narzędzie do usuwania stron
@@ -818,3 +852,45 @@ PDFToXML.title=PDF na XML
PDFToXML.header=PDF na XML
PDFToXML.credit=Ta usługa używa LibreOffice do konwersji plików.
PDFToXML.submit=Konwertuj
#PDFToCSV
PDFToCSV.title=PDF na CSV
PDFToCSV.header=PDF na CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Wyci?g
#split-by-size-or-count
split-by-size-or-count.header=Split PDF by Size or Count
split-by-size-or-count.type.label=Select Split Type
split-by-size-or-count.type.size=By Size
split-by-size-or-count.type.pageCount=By Page Count
split-by-size-or-count.type.docCount=By Document Count
split-by-size-or-count.value.label=Enter Value
split-by-size-or-count.value.placeholder=Enter size (e.g., 2MB or 3KB) or count (e.g., 5)
split-by-size-or-count.submit=Submit
#overlay-pdfs
overlay-pdfs.header=Overlay PDF Files
overlay-pdfs.baseFile.label=Select Base PDF File
overlay-pdfs.overlayFiles.label=Select Overlay PDF Files
overlay-pdfs.mode.label=Select Overlay Mode
overlay-pdfs.mode.sequential=Sequential Overlay
overlay-pdfs.mode.interleaved=Interleaved Overlay
overlay-pdfs.mode.fixedRepeat=Fixed Repeat Overlay
overlay-pdfs.counts.label=Overlay Counts (for Fixed Repeat Mode)
overlay-pdfs.counts.placeholder=Enter comma-separated counts (e.g., 2,3,1)
overlay-pdfs.position.label=Select Overlay Position
overlay-pdfs.position.foreground=Foreground
overlay-pdfs.position.background=Background
overlay-pdfs.submit=Submit
#split-by-sections
split-by-sections.title=Split PDF by Sections
split-by-sections.header=Split PDF into Sections
split-by-sections.horizontal.label=Horizontal Divisions
split-by-sections.vertical.label=Vertical Divisions
split-by-sections.horizontal.placeholder=Enter number of horizontal divisions
split-by-sections.vertical.placeholder=Enter number of vertical divisions
split-by-sections.submit=Split PDF

Some files were not shown because too many files have changed in this diff Show More