Merge branch 'main' into redesign

This commit is contained in:
Anthony Stirling 2024-05-09 19:49:06 +01:00 committed by GitHub
commit 29ec42bc35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
42 changed files with 425 additions and 248 deletions

View file

@ -5,7 +5,7 @@ FROM alpine:20240329
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 src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto/
COPY build/libs/*.jar app.jar
ARG VERSION_TAG

View file

@ -51,8 +51,16 @@ For Fedora-based systems use this command:
sudo dnf install -y git automake autoconf libtool leptonica-devel pkg-config zlib-devel make gcc-c++ java-17-openjdk python3 python3-pip
```
For non-root users with Nix Package Manager, use the following command:
```bash
nix-channel --update
nix-env -iA nixpkgs.jdk17 nixpkgs.git nixpkgs.python38 nixpkgs.gnumake nixpkgs.libgcc nixpkgs.automake nixpkgs.autoconf nixpkgs.libtool nixpkgs.pkg-config nixpkgs.zlib nixpkgs.leptonica
```
### Step 2: Clone and Build jbig2enc (Only required for certain OCR functionality)
For Debian and Fedora, you can build it from source using the following commands:
```bash
mkdir ~/.git
cd ~/.git &&\
@ -64,6 +72,11 @@ make &&\
sudo make install
```
For Nix, you will face `Leptonica not detected`. Bypass this by installing it directly using the following command:
```bash
nix-env -iA nixpkgs.jbig2enc
```
### Step 3: Install Additional Software
Next we need to install LibreOffice for conversions, ocrmypdf for OCR, and opencv for pattern recognition functionality.
@ -105,6 +118,13 @@ sudo dnf install -y libreoffice-writer libreoffice-calc libreoffice-impress unpa
pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
```
For Nix:
```bash
nix-env -iA nixpkgs.unpaper nixpkgs.libreoffice nixpkgs.ocrmypdf nixpkgs.poppler_utils
pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
```
### Step 4: Clone and Build Stirling-PDF
```bash
@ -115,13 +135,12 @@ chmod +x ./gradlew &&\
./gradlew build
```
### Step 5: Move jar to desired location
After the build process, a `.jar` file will be generated in the `build/libs` directory.
You can move this file to a desired location, for example, `/opt/Stirling-PDF/`.
You must also move the Script folder within the Stirling-PDF repo that you have downloaded to this directory.
This folder is required for the python scripts using OpenCV
This folder is required for the python scripts using OpenCV.
```bash
sudo mkdir /opt/Stirling-PDF &&\
@ -129,19 +148,25 @@ sudo mv ./build/libs/Stirling-PDF-*.jar /opt/Stirling-PDF/ &&\
sudo mv scripts /opt/Stirling-PDF/ &&\
echo "Scripts installed."
```
For non-root users, you can just keep the jar in the main directory of Stirling-PDF using the following command:
```bash
mv ./build/libs/Stirling-PDF-*.jar ./Stirling-PDF-*.jar
```
### Step 6: Other files
#### OCR
If you plan to use the OCR (Optical Character Recognition) functionality, you might need to install language packs for Tesseract if running non-english scanning.
##### Installing Language Packs
Easiest is to use the langpacks provided by your repositories. Skip the other steps
Easiest is to use the langpacks provided by your repositories. Skip the other steps.
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/tessdata`
3.
Please view [OCRmyPDF install guide](https://ocrmypdf.readthedocs.io/en/latest/installation.html) for more info.
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.
Debian based systems, install languages with this command:
@ -171,14 +196,38 @@ dnf search -C tesseract-langpack-
rpm -qa | grep tesseract-langpack | sed 's/tesseract-langpack-//g'
```
Nix:
```bash
nix-env -iA nixpkgs.tesseract
```
**Note:** Nix Package Manager pre-installs almost all the language packs when tesseract is installed.
### Step 7: Run Stirling-PDF
Those who have pushed to the root directory, run the following commands:
```bash
./gradlew bootRun
or
java -jar /opt/Stirling-PDF/Stirling-PDF-*.jar
```
Since libreoffice, soffice, and conversion tools have their dbus_tmp_dir set as `dbus_tmp_dir="/run/user/$(id -u)/libreoffice-dbus"`, you might get the following error when using their endpoints:
```
[Thread-7] INFO s.s.SPDF.utils.ProcessExecutor - mkdir: cannot create directory /run/user/1501: Permission denied
```
To resolve this, before starting the Stirling-PDF, you have to set the environment variable to a directory you have write access to by using the following commands:
```bash
mkdir temp
export DBUS_SESSION_BUS_ADDRESS="unix:path=./temp"
./gradlew bootRun
or
java -jar ./Stirling-PDF-*.jar
```
### Step 8: Adding a Desktop icon
This will add a modified Appstarter to your Appmenu.
@ -202,7 +251,19 @@ EOF
Note: Currently the app will run in the background until manually closed.
### Optional: Run Stirling-PDF as a service
### Optional: Changing the host and port of the application:
To override the default configuration, you can add the following to `/.git/Stirling-PDF/configs/custom_settings.yml` file:
```bash
server:
host: 0.0.0.0
port: 3000
```
**Note:** This file is created after the first application launch. To have it before that, you can create the directory and add the file yourself.
### Optional: Run Stirling-PDF as a service (requires root).
First create a .env file, where you can store environment variables:
```
@ -239,6 +300,7 @@ 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
```

View file

@ -166,7 +166,7 @@ Stirling PDF currently supports 27!
| English (English) (en_GB) | ![100%](https://geps.dev/progress/100) |
| English (US) (en_US) | ![100%](https://geps.dev/progress/100) |
| Arabic (العربية) (ar_AR) | ![42%](https://geps.dev/progress/42) |
| German (Deutsch) (de_DE) | ![100%](https://geps.dev/progress/100) |
| German (Deutsch) (de_DE) | ![99%](https://geps.dev/progress/99) |
| French (Français) (fr_FR) | ![91%](https://geps.dev/progress/91) |
| Spanish (Español) (es_ES) | ![99%](https://geps.dev/progress/99) |
| Simplified Chinese (简体中文) (zh_CN) | ![98%](https://geps.dev/progress/98) |
@ -178,16 +178,16 @@ Stirling PDF currently supports 27!
| Romanian (Română) (ro_RO) | ![41%](https://geps.dev/progress/41) |
| Korean (한국어) (ko_KR) | ![91%](https://geps.dev/progress/91) |
| Portuguese Brazilian (Português) (pt_BR) | ![64%](https://geps.dev/progress/64) |
| Russian (Русский) (ru_RU) | ![91%](https://geps.dev/progress/91) |
| Russian (Русский) (ru_RU) | ![90%](https://geps.dev/progress/90) |
| Basque (Euskara) (eu_ES) | ![66%](https://geps.dev/progress/66) |
| Japanese (日本語) (ja_JP) | ![91%](https://geps.dev/progress/91) |
| Dutch (Nederlands) (nl_NL) | ![88%](https://geps.dev/progress/88) |
| Greek (Ελληνικά) (el_GR) | ![88%](https://geps.dev/progress/88) |
| Greek (Ελληνικά) (el_GR) | ![89%](https://geps.dev/progress/89) |
| Turkish (Türkçe) (tr_TR) | ![99%](https://geps.dev/progress/99) |
| Indonesia (Bahasa Indonesia) (id_ID) | ![82%](https://geps.dev/progress/82) |
| Hindi (हिंदी) (hi_IN) | ![82%](https://geps.dev/progress/82) |
| Hungarian (Magyar) (hu_HU) | ![81%](https://geps.dev/progress/81) |
| Bulgarian (Български) (bg_BG) | ![75%](https://geps.dev/progress/75) |
| Bulgarian (Български) (bg_BG) | ![98%](https://geps.dev/progress/98) |
| Sebian Latin alphabet (Srpski) (sr_LATN_RS) | ![84%](https://geps.dev/progress/84) |
| Ukrainian (Українська) (uk_UA) | ![90%](https://geps.dev/progress/90) |
@ -271,7 +271,7 @@ For those wanting to use Stirling-PDFs backend API to link with their own custom
### Prerequisites:
- User must have the folder ./configs volumed within docker so that it is retained during updates.
- Docker uses must download the security jar version by setting ``DOCKER_ENABLE_SECURITY`` to ``true`` in environment variables.
- Docker users must download the security jar version by setting ``DOCKER_ENABLE_SECURITY`` to ``true`` in environment variables.
- Then either enable login via the settings.yml file or via setting ``SECURITY_ENABLE_LOGIN`` to ``true``
- Now the initial user will be generated with username ``admin`` and password ``stirling``. On login you will be forced to change the password to a new one. You can also use the environment variables ``SECURITY_INITIALLOGIN_USERNAME`` and ``SECURITY_INITIALLOGIN_PASSWORD`` to set your own straight away (Recommended to remove them after user creation).

View file

@ -12,7 +12,7 @@ plugins {
import com.github.jk1.license.render.*
group = 'stirling.software'
version = '0.23.1'
version = '0.23.2'
sourceCompatibility = '17'
repositories {

View file

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

View file

@ -13,8 +13,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
@ -76,6 +74,7 @@ public class ConfigInitializer
Files.createFile(customSettingsPath);
}
}
private static Map<String, String> extractEntries(List<String> lines) {
Map<String, String> entries = new HashMap<>();
StringBuilder currentEntry = new StringBuilder();
@ -121,8 +120,10 @@ public class ConfigInitializer
return entries;
}
private static List<String> mergeConfigs(List<String> templateLines, Map<String, String> templateEntries, Map<String, String> userEntries) {
private static List<String> mergeConfigs(
List<String> templateLines,
Map<String, String> templateEntries,
Map<String, String> userEntries) {
List<String> mergedLines = new ArrayList<>();
Set<String> handledKeys = new HashSet<>();
@ -141,7 +142,8 @@ public class ConfigInitializer
blockIndent = indentLevel;
}
if (userEntries.containsKey(currentBlockKey) && !handledKeys.contains(currentBlockKey)) {
if (userEntries.containsKey(currentBlockKey)
&& !handledKeys.contains(currentBlockKey)) {
mergedLines.add(userEntries.get(currentBlockKey));
handledKeys.add(currentBlockKey);
} else if (!handledKeys.contains(currentBlockKey)) {
@ -152,8 +154,6 @@ public class ConfigInitializer
return mergedLines;
}
private static List<String> cleanInvalidYamlEntries(List<String> lines) {
List<String> cleanedLines = new ArrayList<>();
for (int i = 0; i < lines.size(); i++) {

View file

@ -85,6 +85,7 @@ public class InitialSecuritySetup {
// Write back to the file
Files.write(path, lines);
}
private boolean isValidUUID(String uuid) {
if (uuid == null) {
return false;
@ -96,5 +97,4 @@ public class InitialSecuritySetup {
return false;
}
}
}

View file

@ -1,5 +1,6 @@
package stirling.software.SPDF.config.security;
import io.github.pixee.security.Newlines;
import java.io.IOException;
import java.time.Duration;
import java.util.Map;
@ -125,12 +126,12 @@ public class UserBasedRateLimitingFilter extends OncePerRequestFilter {
ConsumptionProbe probe = userBucket.tryConsumeAndReturnRemaining(1);
if (probe.isConsumed()) {
response.setHeader("X-Rate-Limit-Remaining", Long.toString(probe.getRemainingTokens()));
response.setHeader("X-Rate-Limit-Remaining", Newlines.stripAll(Long.toString(probe.getRemainingTokens())));
filterChain.doFilter(request, response);
} else {
long waitForRefill = probe.getNanosToWaitForRefill() / 1_000_000_000;
response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
response.setHeader("X-Rate-Limit-Retry-After-Seconds", String.valueOf(waitForRefill));
response.setHeader("X-Rate-Limit-Retry-After-Seconds", Newlines.stripAll(String.valueOf(waitForRefill)));
response.getWriter().write("Rate limit exceeded for POST requests.");
}
}

View file

@ -0,0 +1,84 @@
package stirling.software.SPDF.controller.api.misc;
import java.awt.image.BufferedImage;
import java.io.IOException;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.JPEGFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import stirling.software.SPDF.model.PdfMetadata;
import stirling.software.SPDF.model.api.misc.FlattenRequest;
import stirling.software.SPDF.utils.PdfUtils;
import stirling.software.SPDF.utils.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/misc")
@Tag(name = "Misc", description = "Miscellaneous APIs")
public class FlattenController {
@PostMapping(consumes = "multipart/form-data", value = "/flatten")
@Operation(
summary = "Flatten PDF form fields or full page",
description =
"Flattening just PDF form fields or converting each page to images to make text unselectable. Input: PDF, Output: PDF. Type: SISO")
public ResponseEntity<byte[]> flatten(@ModelAttribute FlattenRequest request) throws Exception {
MultipartFile file = request.getFileInput();
PDDocument document = Loader.loadPDF(file.getBytes());
PdfMetadata metadata = PdfUtils.extractMetadataFromPdf(document);
Boolean flattenOnlyForms = request.getFlattenOnlyForms();
if (Boolean.TRUE.equals(flattenOnlyForms)) {
PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
if (acroForm != null) {
acroForm.flatten();
}
return WebResponseUtils.pdfDocToWebResponse(
document, Filenames.toSimpleFileName(file.getOriginalFilename()));
} else {
// flatten whole page aka convert each page to image and readd it (making text
// unselectable)
PDFRenderer pdfRenderer = new PDFRenderer(document);
PDDocument newDocument = new PDDocument();
int numPages = document.getNumberOfPages();
for (int i = 0; i < numPages; i++) {
try {
BufferedImage image = pdfRenderer.renderImageWithDPI(i, 300, ImageType.RGB);
PDPage page = new PDPage();
page.setMediaBox(document.getPage(i).getMediaBox());
newDocument.addPage(page);
try (PDPageContentStream contentStream =
new PDPageContentStream(newDocument, page)) {
PDImageXObject pdImage = JPEGFactory.createFromImage(newDocument, image);
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
contentStream.drawImage(pdImage, 0, 0, pageWidth, pageHeight);
}
} catch (IOException e) {
e.printStackTrace();
}
}
PdfUtils.setMetadataToPdf(newDocument, metadata);
return WebResponseUtils.pdfDocToWebResponse(
newDocument, Filenames.toSimpleFileName(file.getOriginalFilename()));
}
}
}

View file

@ -0,0 +1,17 @@
package stirling.software.SPDF.model.api.misc;
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 FlattenRequest extends PDFFile {
@Schema(
description =
"True to flatten only the forms, false to flatten full PDF (Convert page to image)")
private Boolean flattenOnlyForms;
}

View file

@ -58,10 +58,10 @@ public class ProcessExecutor {
long timeoutMinutes =
switch (key) {
case LIBRE_OFFICE -> 30;
case PDFTOHTML -> 5;
case PDFTOHTML -> 20;
case OCR_MY_PDF -> 30;
case PYTHON_OPENCV -> 30;
case GHOSTSCRIPT -> 5;
case GHOSTSCRIPT -> 30;
case WEASYPRINT -> 30;
case INSTALL_APP -> 60;
case CALIBRE -> 30;

View file

@ -24,8 +24,8 @@ spring.devtools.livereload.enabled=true
spring.thymeleaf.encoding=UTF-8
server.connection-timeout=${SYSTEM_CONNECTIONTIMEOUTMINUTES:5m}
spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:300000}
server.connection-timeout=${SYSTEM_CONNECTIONTIMEOUTMINUTES:20m}
spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:1200000}
spring.resources.static-locations=file:customFiles/static/
#spring.thymeleaf.prefix=file:/customFiles/templates/,classpath:/templates/

View file

@ -698,6 +698,7 @@ repair.submit=الإصلاح
#flatten
flatten.title=تسطيح
flatten.header=تسوية ملفات PDF
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=تسطيح

View file

@ -11,17 +11,17 @@ imgPrompt=Изберете изображение(я)
genericSubmit=Подайте
processTimeWarning=Предупреждение: Този процес може да отнеме до минута в зависимост от размера на файла
pageOrderPrompt=Персонализиран ред на страниците (Въведете разделен със запетаи списък с номера на страници или функции като 2n+1):
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
pageSelectionPrompt=Персонализиран избор на страница (Въведете списък с номера на страници 1,5,6, разделени със запетая, или функции като 2n+1) :
goToPage=Давай
true=Вярно
false=Невярно
unknown=Непознат
save=Съхранете
saveToBrowser=Save to Browser
saveToBrowser=Съхраняване в браузъра
close=Затворете
filesSelected=избрани файлове
noFavourites=Няма добавени любими
downloadComplete=Download Complete
downloadComplete=Свалянето завършено
bored=Отекчени сте да чакате?
alphabet=Азбука
downloadPdf=Изтеглете PDF
@ -45,57 +45,58 @@ red=Червено
green=Зелено
blue=Синьо
custom=Персонализиране...
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
poweredBy=Powered by
yes=Yes
no=No
WorkInProgess=Работата е в ход, може да не работи или да има грешки, моля, докладвайте за проблеми!
poweredBy=Задвижван чрез
yes=Да
no=Не
changedCredsMessage=Идентификационните данни са променени!
notAuthenticatedMessage=Потребителят не е автентикиран.
userNotFoundMessage=Потребителят не е намерен
incorrectPasswordMessage=Текущата парола е неправилна.
usernameExistsMessage=Новият потребител вече съществува.
invalidUsernameMessage=Invalid username, Username must only contain alphabet characters and numbers.
deleteCurrentUserMessage=Cannot delete currently logged in user.
deleteUsernameExistsMessage=The username does not exist and cannot be deleted.
invalidUsernameMessage=Невалидно потребителско име, потребителското име трябва да съдържа само букви и цифри.
deleteCurrentUserMessage=Не може да се изтрие вписания в момента потребител.
deleteUsernameExistsMessage=Потребителското име не съществува и не може да бъде изтрито.
downgradeCurrentUserMessage=Не може да се понижи ролята на текущия потребител
downgradeCurrentUserLongMessage=Не може да се понижи ролята на текущия потребител. Следователно текущият потребител няма да бъде показан.
error=Error
oops=Oops!
help=Help
goHomepage=Go to Homepage
joinDiscord=Join our Discord server
seeDockerHub=See Docker Hub
visitGithub=Visit Github Repository
donate=Donate
color=Color
sponsor=Sponsor
error=Грешка
oops=Опаа!
help=Помощ
goHomepage=Отидете на началната страница
joinDiscord=Присъединете се към нашия Discord сървър
seeDockerHub=Погледнете Docker Hub
visitGithub=Посетете Github Repository
donate=Направете дарение
color=Цвят
sponsor=Спонсор
info=Info
###############
# Pipeline #
###############
pipeline.header=Pipeline Menu (Beta)
pipeline.uploadButton=Upload Custom
pipeline.configureButton=Configure
pipeline.defaultOption=Custom
pipeline.submitButton=Submit
pipeline.help=Pipeline Help
pipeline.scanHelp=Folder Scanning Help
pipeline.header=Pipeline Меню (Бета)
pipeline.uploadButton=Качване на персонализиран
pipeline.configureButton=Настройка
pipeline.defaultOption=Персонализиран
pipeline.submitButton=Подайте
pipeline.help=Pipeline Помощ
pipeline.scanHelp=Помощ за сканиране на папки
######################
# Pipeline Options #
######################
pipelineOptions.header=Pipeline Configuration
pipelineOptions.pipelineNameLabel=Pipeline Name
pipelineOptions.saveSettings=Save Operation Settings
pipelineOptions.pipelineNamePrompt=Enter pipeline name here
pipelineOptions.selectOperation=Select Operation
pipelineOptions.addOperationButton=Add operation
pipelineOptions.header=Pipeline Конфигурация
pipelineOptions.pipelineNameLabel=Pipeline име
pipelineOptions.saveSettings=Запазете настройките за работа
pipelineOptions.pipelineNamePrompt=Въведете името на pipeline тук
pipelineOptions.selectOperation=Избор на операция
pipelineOptions.addOperationButton=Добавяне на операция
pipelineOptions.pipelineHeader=Pipeline:
pipelineOptions.saveButton=Download
pipelineOptions.validateButton=Validate
pipelineOptions.saveButton=Изтегли
pipelineOptions.validateButton=Валидирай
@ -119,7 +120,7 @@ navbar.sections.edit=View & Edit
#############
settings.title=Настройки
settings.update=Налична актуализация
settings.updateAvailable={0} is the current installed version. A new version ({1}) is available.
settings.updateAvailable={0} е текущата инсталирана версия. Налична е нова версия ({1}).
settings.appVersion=Версия на приложението:
settings.downloadOption.title=Изберете опция за изтегляне (за изтегляния на един файл без да е архивиран):
settings.downloadOption.1=Отваряне в същия прозорец
@ -128,13 +129,13 @@ settings.downloadOption.3=Изтегли файл
settings.zipThreshold=Архивирайте файловете, когато броят на изтеглените файлове надвишава
settings.signOut=Изход
settings.accountSettings=Настройки на акаунта
settings.bored.help=Enables easter egg game
settings.cacheInputs.name=Save form inputs
settings.cacheInputs.help=Enable to store previously used inputs for future runs
settings.bored.help=Активира игра с великденски яйца
settings.cacheInputs.name=Запазете въведените формуляри
settings.cacheInputs.help=Активирайте за съхраняване на предишни използвани въведени данни за бъдещи изпълнения
changeCreds.title=Промяна на идентификационните данни
changeCreds.header=Актуализирайте данните за акаунта си
changeCreds.changePassword=You are using default login credentials. Please enter a new password
changeCreds.changePassword=Използвате идентификационни данни за вход по подразбиране. Моля, въведете нова парола
changeCreds.newUsername=Ново потребителско име
changeCreds.oldPassword=Текуща парола
changeCreds.newPassword=Нова парола
@ -160,8 +161,8 @@ account.syncTitle=Синхронизиране на настройките на
account.settingsCompare=Сравняване на настройките:
account.property=Свойство
account.webBrowserSettings=Уеб-браузър настройки
account.syncToBrowser=Синхронизиране на акаунт -> Бразър
account.syncToAccount=Синхронизиране на акаунт <- Бразър
account.syncToBrowser=Синхронизиране на акаунт -> Браузър
account.syncToAccount=Синхронизиране на акаунт <- Браузър
adminUserSettings.title=Настройки за потребителски контрол
@ -169,15 +170,15 @@ adminUserSettings.header=Настройки за администраторск
adminUserSettings.admin=Администратор
adminUserSettings.user=Потребител
adminUserSettings.addUser=Добавяне на нов потребител
adminUserSettings.usernameInfo=Username must only contain letters and numbers, no spaces or special characters.
adminUserSettings.usernameInfo=Потребителското име трябва да съдържа само букви и цифри, без интервали или специални знаци.
adminUserSettings.roles=Роли
adminUserSettings.role=Роля
adminUserSettings.actions=Действия
adminUserSettings.apiUser=Ограничен API потребител
adminUserSettings.extraApiUser=Additional Limited API User
adminUserSettings.extraApiUser=Допълнителен ограничен API потребител
adminUserSettings.webOnlyUser=Само за уеб-потребител
adminUserSettings.demoUser=Demo User (No custom settings)
adminUserSettings.internalApiUser=Internal API User
adminUserSettings.demoUser=Демо потребител (без персонализирани настройки)
adminUserSettings.internalApiUser=Вътрешен API потребител
adminUserSettings.forceChange=Принудете потребителя да промени потребителското име/парола при влизане
adminUserSettings.submit=Съхранете потребителя
adminUserSettings.changeUserRole=Промяна на ролята на потребителя
@ -186,12 +187,12 @@ adminUserSettings.changeUserRole=Промяна на ролята на потр
# HOME-PAGE #
#############
home.desc=Вашето локално хоствано обслужване на едно място за всички ваши PDF нужди.
home.searchBar=Search for features...
home.searchBar=Търсене на функции...
home.viewPdf.title=View PDF
home.viewPdf.desc=View, annotate, add text or images
viewPdf.tags=view,read,annotate,text,image
home.viewPdf.title=Преглед на PDF
home.viewPdf.desc=Преглеждайте, коментирайте, добавяйте текст или изображения
viewPdf.tags=преглед,четене,анотиране,текст,изображение
home.multiTool.title=PDF Мулти инструмент
home.multiTool.desc=Обединяване, завъртане, пренареждане и премахване на страници
@ -262,7 +263,7 @@ home.fileToPDF.desc=Преобразуване почти всеки файл к
fileToPDF.tags=трансформация,формат,документ,изображение,слайд,текст,преобразуване,офис,документи,word,excel,powerpoint
home.ocr.title=OCR / Почистващи сканирания
home.ocr.desc=Cleanup сканира и открива текст от изображения към PDF и го добавя отново като текст.
home.ocr.desc=Почистване, сканира и открива текст от изображения към PDF и го добавя отново като текст.
ocr.tags=разпознаване,текст,изображение,сканиране,четене,идентифициране,откриване,редактиране
@ -315,9 +316,9 @@ 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.removeAnnotations.title=Премахване на анотации
home.removeAnnotations.desc=Премахва всички коментари/анотации от PDF
removeAnnotations.tags=коментари, маркиране, бележки, маркиране, премахване
home.compare.title=Сравнете
home.compare.desc=Сравнява и показва разликите между 2 PDF документа
@ -359,7 +360,7 @@ home.autoSplitPDF.title=Автоматично разделяне на стра
home.autoSplitPDF.desc=Автоматично разделяне на сканиран PDF файл с QR код за разделяне на физически сканирани страници
autoSplitPDF.tags=QR-базиран,отделен,сканиране-сегмент,организиране
home.sanitizePdf.title=Дезинфекцирай
home.sanitizePdf.title=Дезинфенкцирам
home.sanitizePdf.desc=Премахване на скриптове и други елементи от PDF файлове
sanitizePdf.tags=чисти,сигурни,безопасни,премахване-заплахи
@ -401,35 +402,35 @@ home.autoRedact.desc=Автоматично редактира (зачерняв
autoRedact.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.tableExtraxt.desc=Извлича таблици от PDF, като ги конвертира в CSV
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.autoSizeSplitPDF.title=Автоматично разделяне по размер/брой
home.autoSizeSplitPDF.desc=Разделете един PDF на множество документи въз основа на размер, брой страници или брой документи
autoSizeSplitPDF.tags=pdf,разделяне,документ,организация
home.overlay-pdfs.title=Overlay PDFs
home.overlay-pdfs.desc=Overlays PDFs on-top of another PDF
overlay-pdfs.tags=Overlay
home.overlay-pdfs.title=Наслагване PDF-и
home.overlay-pdfs.desc=Наслагва PDF файлове върху друг PDF
overlay-pdfs.tags=Наслагване
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
home.split-by-sections.title=Разделяне на PDF по секции
home.split-by-sections.desc=Разделете всяка страница от PDF на по-малки хоризонтални и вертикални секции
split-by-sections.tags=Разделяне на секция,Разделяне,Персонализиране
home.AddStampRequest.title=Add Stamp to PDF
home.AddStampRequest.desc=Add text or add image stamps at set locations
AddStampRequest.tags=Stamp, Add image, center image, Watermark, PDF, Embed, Customize
home.AddStampRequest.title=Добавяне на печат към PDF
home.AddStampRequest.desc=Добавете текст или добавете печати с изображения на определени места
AddStampRequest.tags=Печат,добавяне на изображение,централно изображение,воден знак,PDF,вграждане,персонализиране
home.PDFToBook.title=PDF to Book
home.PDFToBook.desc=Converts PDF to Book/Comic formats using calibre
PDFToBook.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.PDFToBook.title=PDF към книга
home.PDFToBook.desc=Преобразува PDF във формати на книги/комикси с помощта на calibre
PDFToBook.tags=Книга,комикс,calibre,конвертиране,манга,Amazon,Kindle
home.BookToPDF.title=Book to PDF
home.BookToPDF.desc=Converts Books/Comics formats to PDF using calibre
BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.BookToPDF.title=Книга към PDF
home.BookToPDF.desc=Преобразува формати на книги/комикси в PDF с помощта на calibre
BookToPDF.tags=Книга,комикс,calibre,конвертиране,манга,Amazon,Kindle
###########################
@ -476,9 +477,9 @@ pdfToSinglePage.submit=Преобразуване към единична стр
#pageExtracter
pageExtracter.title=Extract Pages
pageExtracter.header=Extract Pages
pageExtracter.submit=Extract
pageExtracter.title=Извличане на страници
pageExtracter.header=Извличане на страници
pageExtracter.submit=Извличане
pageExtracter.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
@ -508,40 +509,40 @@ URLToPDF.credit=Използва WeasyPrint
#html-to-pdf
HTMLToPDF.title=HTML към PDF
HTMLToPDF.header=HTML към PDF
HTMLToPDF.help=Приема HTML файлове и ZIP файлове, съдържащи html/css/изображения и т.н
HTMLToPDF.help=Приемане на HTML файлове и ZIP файлове, съдържащи html/css/изображения и т.н.
HTMLToPDF.submit=Преобразуване
HTMLToPDF.credit=Използва WeasyPrint
HTMLToPDF.zoom=Zoom level for displaying the website.
HTMLToPDF.pageWidth=Width of the page in centimeters. (Blank to default)
HTMLToPDF.pageHeight=Height of the page in centimeters. (Blank to default)
HTMLToPDF.marginTop=Top margin of the page in millimeters. (Blank to default)
HTMLToPDF.marginBottom=Bottom margin of the page in millimeters. (Blank to default)
HTMLToPDF.marginLeft=Left margin of the page in millimeters. (Blank to default)
HTMLToPDF.marginRight=Right margin of the page in millimeters. (Blank to default)
HTMLToPDF.printBackground=Render the background of websites.
HTMLToPDF.defaultHeader=Enable Default Header (Name and page number)
HTMLToPDF.cssMediaType=Change the CSS media type of the page.
HTMLToPDF.none=None
HTMLToPDF.print=Print
HTMLToPDF.screen=Screen
HTMLToPDF.zoom=Ниво на мащабиране за показване на уебсайта.
HTMLToPDF.pageWidth=Ширина на страницата в сантиметри. (Празно по подразбиране)
HTMLToPDF.pageHeight=Височина на страницата в сантиметри. (Празно по подразбиране)
HTMLToPDF.marginTop=Горно поле на страницата в милиметри. (Празно по подразбиране)
HTMLToPDF.marginBottom=Долно поле на страницата в милиметри. (Празно по подразбиране)
HTMLToPDF.marginLeft=Ляво поле на страницата в милиметри. (Празно по подразбиране)
HTMLToPDF.marginRight=Дясно поле на страницата в милиметри. (Празно по подразбиране)
HTMLToPDF.printBackground=Изобразете фона на уебсайтове.
HTMLToPDF.defaultHeader=Активиране на горния колонтитул по подразбиране (име и номер на страница)
HTMLToPDF.cssMediaType=Променете CSS медийния тип на страницата.
HTMLToPDF.none=Няма
HTMLToPDF.print=Печат
HTMLToPDF.screen=Екран
#AddStampRequest
AddStampRequest.header=Stamp PDF
AddStampRequest.title=Stamp PDF
AddStampRequest.stampType=Stamp Type
AddStampRequest.stampText=Stamp Text
AddStampRequest.stampImage=Stamp Image
AddStampRequest.alphabet=Alphabet
AddStampRequest.fontSize=Font/Image Size
AddStampRequest.rotation=Rotation
AddStampRequest.opacity=Opacity
AddStampRequest.position=Position
AddStampRequest.overrideX=Override X Coordinate
AddStampRequest.overrideY=Override Y Coordinate
AddStampRequest.customMargin=Custom Margin
AddStampRequest.customColor=Custom Text Color
AddStampRequest.submit=Submit
AddStampRequest.header=Поставяне на печат на PDF
AddStampRequest.title=Поставяне на печат на PDF
AddStampRequest.stampType=Тип печат
AddStampRequest.stampText=Поставяне на текст
AddStampRequest.stampImage=Изображение с печат
AddStampRequest.alphabet=Азбука
AddStampRequest.fontSize=Размер на шрифта/изображението
AddStampRequest.rotation=Ротация
AddStampRequest.opacity=Непрозрачност
AddStampRequest.position=Позиция
AddStampRequest.overrideX=Замяна на X координата
AddStampRequest.overrideY=Замяна на Y координата
AddStampRequest.customMargin=Персонализиран марж
AddStampRequest.customColor=Персонализиран цвят на текста
AddStampRequest.submit=Изпращане
#sanitizePDF
@ -630,11 +631,11 @@ scalePages.submit=Подайте
certSign.title=Подписване на сертификат
certSign.header=Подпишете PDF с вашия сертификат (В процес на работа)
certSign.selectPDF=Изберете PDF файл за подписване:
certSign.jksNote=Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below.
certSign.jksNote=Забележка: Ако вашият тип сертификат не е в списъка по-долу, моля, конвертирайте го във файл на Java Keystore (.jks) с помощта на инструмента за команден ред keytool. След това изберете опцията за .jks файл по-долу.
certSign.selectKey=Изберете вашия файл с личен ключ (формат PKCS#8, може да бъде .pem или .der):
certSign.selectCert=Изберете вашия файл със сертификат (формат X.509, може да бъде .pem или .der):
certSign.selectP12=Изберете вашия PKCS#12 Keystore файл (.p12 или .pfx) (По избор, ако е предоставен, трябва да съдържа вашия личен ключ и сертификат):
certSign.selectJKS=Select Your Java Keystore File (.jks or .keystore):
certSign.selectJKS=Изберете Вашия Java Keystore Файл (.jks или .keystore):
certSign.certType=Тип сертификат
certSign.password=Въведете вашата парола за Keystore за ключове или частен ключ (ако има):
certSign.showSig=Показване на подпис
@ -655,9 +656,9 @@ removeBlanks.submit=Премахване на празни места
#removeAnnotations
removeAnnotations.title=Remove Annotations
removeAnnotations.header=Remove Annotations
removeAnnotations.submit=Remove
removeAnnotations.title=Премахване на анотации
removeAnnotations.header=Премахване на анотации
removeAnnotations.submit=Премахване
#compare
@ -668,17 +669,17 @@ compare.document.2=Документ 2
compare.submit=Сравнявай
#BookToPDF
BookToPDF.title=Books and Comics to PDF
BookToPDF.header=Book to PDF
BookToPDF.credit=Uses Calibre
BookToPDF.submit=Convert
BookToPDF.title=Книги и комикси в PDF
BookToPDF.header=Книга в PDF
BookToPDF.credit=Използва Calibre
BookToPDF.submit=Конвертиране
#PDFToBook
PDFToBook.title=PDF to Book
PDFToBook.header=PDF to Book
PDFToBook.selectText.1=Format
PDFToBook.credit=Uses Calibre
PDFToBook.submit=Convert
PDFToBook.title=PDF към книга
PDFToBook.header=PDF към книга
PDFToBook.selectText.1=Формат
PDFToBook.credit=Използва Calibre
PDFToBook.submit=Конвертиране
#sign
sign.title=Подпишете
@ -699,6 +700,7 @@ repair.submit=Поправи
#flatten
flatten.title=Изравнете
flatten.header=Изравнете PDF-и
flatten.flattenOnlyForms=Изравнете само форми
flatten.submit=Изравнете
@ -759,7 +761,7 @@ compress.selectText.1=Ръчен режим - От 1 до 4
compress.selectText.2=Ниво на оптимизация:
compress.selectText.3=4 (Ужасно за текстови изображения)
compress.selectText.4=Автоматичен режим - Автоматично настройва качеството, за да получи PDF точен размер
compress.selectText.5=Очакван PDF размер (напр. 25MB, 10.8MB, 25KB)
compress.selectText.5=Очакван PDF размер (напр. 25МБ, 10.8МБ, 25КБ)
compress.submit=Компресиране
@ -783,17 +785,17 @@ merge.submit=Обединяване
pdfOrganiser.title=Организатор на страници
pdfOrganiser.header=Организатор на PDF страници
pdfOrganiser.submit=Пренареждане на страниците
pdfOrganiser.mode=Mode
pdfOrganiser.mode.1=Custom Page Order
pdfOrganiser.mode.2=Reverse Order
pdfOrganiser.mode.3=Duplex Sort
pdfOrganiser.mode.4=Booklet Sort
pdfOrganiser.mode.5=Side Stitch Booklet Sort
pdfOrganiser.mode.6=Odd-Even Split
pdfOrganiser.mode.7=Remove First
pdfOrganiser.mode.8=Remove Last
pdfOrganiser.mode.9=Remove First and Last
pdfOrganiser.placeholder=(e.g. 1,3,2 or 4-8,2,10-12 or 2n-1)
pdfOrganiser.mode=Режим
pdfOrganiser.mode.1=Персонализиран ред на страниците
pdfOrganiser.mode.2=Обърнат ред
pdfOrganiser.mode.3=Двустранно сортиране
pdfOrganiser.mode.4=Сортиране на брошури
pdfOrganiser.mode.5=Сортиране на брошури със страничен шев
pdfOrganiser.mode.6=Четно-нечетно разделяне
pdfOrganiser.mode.7=Премахни първо
pdfOrganiser.mode.8=Премахване на последния
pdfOrganiser.mode.9=Премахване на първия и последния
pdfOrganiser.placeholder=(напр. 1,3,2 или 4-8,2,10-12 или 2n-1)
#multiTool
@ -801,9 +803,10 @@ multiTool.title=PDF Мулти инструмент
multiTool.header=PDF Мулти инструмент
multiTool.uploadPrompts=File Name
#view pdf
viewPdf.title=View PDF
viewPdf.header=View PDF
viewPdf.title=Преглед на PDF
viewPdf.header=Преглед на PDF
#pageRemover
pageRemover.title=Премахване на страници
@ -951,8 +954,8 @@ pdfToPDFA.title=PDF към PDF/A
pdfToPDFA.header=PDF към PDF/A
pdfToPDFA.credit=Тази услуга използва OCRmyPDF за PDF/A преобразуване.
pdfToPDFA.submit=Преобразуване
pdfToPDFA.tip=Currently does not work for multiple inputs at once
pdfToPDFA.outputFormat=Output format
pdfToPDFA.tip=В момента не работи за няколко входа наведнъж
pdfToPDFA.outputFormat=Изходен формат
#PDFToWord
@ -995,75 +998,75 @@ PDFToXML.submit=Преобразуване
#PDFToCSV
PDFToCSV.title=PDF ??? CSV
PDFToCSV.header=PDF ??? CSV
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=????????
PDFToCSV.prompt=Изберете страница за извличане на таблица
PDFToCSV.submit=????
#split-by-size-or-count
split-by-size-or-count.title=Split PDF 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
split-by-size-or-count.title=Разделяне на PDF по размер или брой
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=Въведете размер (напр. 2МБ или 3КБ) или брой (напр. 5)
split-by-size-or-count.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
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=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
split-by-sections.merge=Merge Into One PDF
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
split-by-sections.merge=Сливане в един PDF
#printFile
printFile.title=Print File
printFile.header=Print File to Printer
printFile.selectText.1=Select File to Print
printFile.selectText.2=Enter Printer Name
printFile.submit=Print
printFile.title=Печат на файл
printFile.header=Печат на файл на принтер
printFile.selectText.1=Изберете файл за печат
printFile.selectText.2=Въведете име на принтер
printFile.submit=Печат
#licenses
licenses.nav=Licenses
licenses.title=3rd Party Licenses
licenses.header=3rd Party Licenses
licenses.module=Module
licenses.version=Version
licenses.license=License
licenses.nav=Лицензи
licenses.title=Лицензи на трети страни
licenses.header=Лицензи на трети страни
licenses.module=Модул
licenses.version=Версия
licenses.license=Лиценз
# error
error.sorry=Sorry for the issue!
error.needHelp=Need help / Found an issue?
error.contactTip=If you're still having trouble, don't hesitate to reach out to us for help. You can submit a ticket on our GitHub page or contact us through Discord:
error.404.head=404 - Page Not Found | Oops, we tripped in the code!
error.404.1=We can't seem to find the page you're looking for.
error.404.2=Something went wrong
error.github=Submit a ticket on GitHub
error.showStack=Show Stack Trace
error.copyStack=Copy Stack Trace
error.githubSubmit=GitHub - Submit a ticket
error.discordSubmit=Discord - Submit Support post
error.sorry=Извинете за проблема!
error.needHelp=Нуждаете се от помощ / Открихте проблем?
error.contactTip=Ако все още имате проблеми, не се колебайте да се свържете с нас за помощ. Можете да изпратите запитване на нашата страница в GitHub или да се свържете с нас чрез Discord:
error.404.head=404 - Страницата не е намерена | Опа! Спънахме се в кода!
error.404.1=Изглежда не можем да намерим страницата, която търсите.
error.404.2=Нещо се обърка
error.github=Изпратете запитване в GitHub
error.showStack=Покажи проследяване на стека
error.copyStack=Копиране на проследяване на стека
error.githubSubmit=GitHub - Изпратете запитване
error.discordSubmit=Discord - Изпратете запитване за поддръжка

View file

@ -699,6 +699,7 @@ repair.submit=Reparar
#flatten
flatten.title=Aplanar
flatten.header=Aplana els PDF
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Aplanar

View file

@ -699,6 +699,7 @@ repair.submit=Reparieren
#flatten
flatten.title=Abflachen
flatten.header=PDFs reduzieren
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Abflachen

View file

@ -699,6 +699,7 @@ repair.submit=Επιδιόρθωση
#flatten
flatten.title=Flatten
flatten.header=Flatten PDFs
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Flatten

View file

@ -698,7 +698,8 @@ repair.submit=Repair
#flatten
flatten.title=Flatten
flatten.header=Flatten PDFs
flatten.header=Flatten PDF
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Flatten

View file

@ -698,6 +698,7 @@ repair.submit=Repair
#flatten
flatten.title=Flatten
flatten.header=Flatten PDFs
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Flatten

View file

@ -702,6 +702,7 @@ repair.submit=Reparar
#flatten
flatten.title=Aplanar
flatten.header=Acoplar archivos PDF
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Aplanar

View file

@ -699,6 +699,7 @@ repair.submit=Konpondu
#flatten
flatten.title=Lautu
flatten.header=Akoplatu PDF fitxategiak
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Lautu

View file

@ -698,6 +698,7 @@ repair.submit=Réparer
#flatten
flatten.title=Rendre inerte
flatten.header=Rendre inerte
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Rendre inerte

View file

@ -699,6 +699,7 @@ repair.submit=मरम्मत
#flatten
flatten.title=समतल करें
flatten.header=पीडीएफ़ समतल करें
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=समतल करें

View file

@ -699,6 +699,7 @@ repair.submit=Javítás
#flatten
flatten.title=Kiegyenlítés
flatten.header=PDF-ek kiegyenlítése
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Kiegyenlítés

View file

@ -699,6 +699,7 @@ repair.submit=Perbaiki
#flatten
flatten.title=Ratakan
flatten.header=Ratakan PDF
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Ratakan

View file

@ -119,7 +119,7 @@ navbar.sections.edit=View & Edit
#############
settings.title=Impostazioni
settings.update=Aggiornamento disponibile
settings.updateAvailable={0} is the current installed version. A new version ({1}) is available.
settings.updateAvailable={0} è la versione attualmente installata. Una nuova versione ({1}) è disponibile.
settings.appVersion=Versione App:
settings.downloadOption.title=Scegli opzione di download (Per file singoli non compressi):
settings.downloadOption.1=Apri in questa finestra
@ -697,8 +697,9 @@ repair.submit=Ripara
#flatten
flatten.title=Appiattisci
flatten.title=Appiattire
flatten.header=Appiattisci PDF
flatten.flattenOnlyForms=Appiattisci solo i moduli
flatten.submit=Appiattisci

View file

@ -699,6 +699,7 @@ repair.submit=修復
#flatten
flatten.title=平坦化
flatten.header=PDFを平坦化する
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=平坦化

View file

@ -700,6 +700,7 @@ repair.submit=복구
#flatten
flatten.title=평탄화
flatten.header=PDF 문서의 레이어 평탄화
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=평탄화

View file

@ -699,6 +699,7 @@ repair.submit=Repareren
#flatten
flatten.title=Afvlakken
flatten.header=PDF's afvlakken
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Afvlakken

View file

@ -699,6 +699,7 @@ repair.submit=Napraw
#flatten
flatten.title=Spłaszcz
flatten.header=Spłaszcz dokument(y) PDF
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Spłaszcz

View file

@ -699,6 +699,7 @@ repair.submit=Reparar
#flatten
flatten.title=Achatar
flatten.header=Achatar PDFs
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Achatar

View file

@ -699,6 +699,7 @@ repair.submit=Reparar
#flatten
flatten.title=Achatar
flatten.header=Achatar PDFs
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Achatar

View file

@ -699,6 +699,7 @@ repair.submit=Repară
#flatten
flatten.title=Nivelare
flatten.header=Nivelează documente PDF
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Nivelează

View file

@ -700,6 +700,7 @@ repair.submit=Ремонт
#flatten
flatten.title=Сглаживание
flatten.header=Сглаживание PDF ов
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Сгладить

View file

@ -699,6 +699,7 @@ repair.submit=Popravi
#flatten
flatten.title=Ravnanje
flatten.header=Ravnanje PDF fajlova
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Ravnanje

View file

@ -699,6 +699,7 @@ repair.submit=Reparera
#flatten
flatten.title=Platta till
flatten.header=Placera PDF-filer
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Platta till

View file

@ -699,6 +699,7 @@ repair.submit=Onar
#flatten
flatten.title=Düzleştir
flatten.header=PDF'leri Düzleştir
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Düzleştir

View file

@ -694,6 +694,7 @@ repair.submit=Ремонтувати
#flatten
flatten.title=Згладжування
flatten.header=Згладжування PDF
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=Згладити

View file

@ -699,6 +699,7 @@ repair.submit=修复
#flatten
flatten.title=展平
flatten.header=展平 PDF
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=展平

View file

@ -699,6 +699,7 @@ repair.submit=修復
#flatten
flatten.title=平坦化
flatten.header=PDF 平坦化
flatten.flattenOnlyForms=Flatten only forms
flatten.submit=平坦化

View file

@ -71,6 +71,7 @@
<script src="js/darkmode.js"></script>
</th:block>
<th:block th:fragment="game">
<dialog id="game-container-wrapper" class="game-container-wrapper" data-bs-modal>
<script th:inline="javascript">

View file

@ -11,41 +11,23 @@
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6" id="bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon other">layers_clear</span>
<span class="tool-header-text" th:text="#{flatten.header}"></span>
</div>
<form id="pdfForm" class="mb-3">
<form method="post" enctype="multipart/form-data" th:action="@{api/v1/misc/flatten}" id="pdfForm" class="mb-3">
<div class="custom-file">
<div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf', remoteCall='false')}"></div>
</div>
<div class="form-check ms-3">
<input type="checkbox" id="flattenOnlyForms" name="flattenOnlyForms">
<label for="flattenOnlyForms" th:text="#{flatten.flattenOnlyForms}" ></label>
</div>
</div>
<br>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{flatten.submit}"></button>
<script src="js/local-pdf-input-download.js"></script>
<script>
document.getElementById('pdfForm').addEventListener('submit', async (e) => {
e.preventDefault();
const { PDFDocument } = PDFLib;
const processFile = async (file) => {
const origFileUrl = URL.createObjectURL(file);
const formPdfBytes = await fetch(origFileUrl).then(res => res.arrayBuffer());
const pdfDoc = await PDFDocument.load(formPdfBytes, { ignoreEncryption: true });
const form = pdfDoc.getForm();
form.flatten();
const pdfBytes = await pdfDoc.save();
const pdfBlob = new Blob([pdfBytes], { type: 'application/pdf' });
const fileName = (file.name ? file.name.replace('.pdf', '') : 'pdf') + '_flattened.pdf';
return { processedData: pdfBlob, fileName };
};
await downloadFilesWithCallback(processFile);
});
</script>
</form>
</div>
</div>