Compare commits

..

4 Commits

Author SHA1 Message Date
Dimitrios Kaitantzidis
5ad3cfdd07 login shows properly in keycloak, need to fix Xbool error for attributes extracting after successful login 2024-10-21 20:45:30 +03:00
Ludy87
34ef4c7384 relyingPartyRegistrations only enabled samle 2024-10-19 17:20:24 +02:00
Ludy87
1c1bea090d changed: deprecation code 2024-10-19 16:48:57 +02:00
Ludy87
f23007515a implement Saml2 login/logout 2024-10-19 14:48:12 +02:00
60 changed files with 749 additions and 767 deletions

View File

@@ -172,18 +172,18 @@ Stirling PDF currently supports 38!
| Language | Progress |
| ------------------------------------------- | -------------------------------------- |
| Arabic (العربية) (ar_AR) | ![94%](https://geps.dev/progress/94) |
| Arabic (العربية) (ar_AR) | ![93%](https://geps.dev/progress/93) |
| Basque (Euskara) (eu_ES) | ![57%](https://geps.dev/progress/57) |
| Bulgarian (Български) (bg_BG) | ![99%](https://geps.dev/progress/99) |
| Bulgarian (Български) (bg_BG) | ![86%](https://geps.dev/progress/86) |
| Catalan (Català) (ca_CA) | ![44%](https://geps.dev/progress/44) |
| Croatian (Hrvatski) (hr_HR) | ![87%](https://geps.dev/progress/87) |
| Czech (Česky) (cs_CZ) | ![83%](https://geps.dev/progress/83) |
| Czech (Česky) (cs_CZ) | ![82%](https://geps.dev/progress/82) |
| Danish (Dansk) (da_DK) | ![91%](https://geps.dev/progress/91) |
| Dutch (Nederlands) (nl_NL) | ![88%](https://geps.dev/progress/88) |
| English (English) (en_GB) | ![100%](https://geps.dev/progress/100) |
| English (US) (en_US) | ![100%](https://geps.dev/progress/100) |
| French (Français) (fr_FR) | ![88%](https://geps.dev/progress/88) |
| German (Deutsch) (de_DE) | ![94%](https://geps.dev/progress/94) |
| French (Français) (fr_FR) | ![85%](https://geps.dev/progress/85) |
| German (Deutsch) (de_DE) | ![93%](https://geps.dev/progress/93) |
| Greek (Ελληνικά) (el_GR) | ![75%](https://geps.dev/progress/75) |
| Hindi (हिंदी) (hi_IN) | ![72%](https://geps.dev/progress/72) |
| Hungarian (Magyar) (hu_HU) | ![69%](https://geps.dev/progress/69) |
@@ -193,7 +193,7 @@ Stirling PDF currently supports 38!
| Japanese (日本語) (ja_JP) | ![87%](https://geps.dev/progress/87) |
| Korean (한국어) (ko_KR) | ![77%](https://geps.dev/progress/77) |
| Norwegian (Norsk) (no_NB) | ![90%](https://geps.dev/progress/90) |
| Polish (Polski) (pl_PL) | ![99%](https://geps.dev/progress/99) |
| Polish (Polski) (pl_PL) | ![84%](https://geps.dev/progress/84) |
| Portuguese (Português) (pt_PT) | ![72%](https://geps.dev/progress/72) |
| Portuguese Brazilian (Português) (pt_BR) | ![99%](https://geps.dev/progress/99) |
| Romanian (Română) (ro_RO) | ![92%](https://geps.dev/progress/92) |
@@ -207,7 +207,7 @@ Stirling PDF currently supports 38!
| Traditional Chinese (繁體中文) (zh_TW) | ![99%](https://geps.dev/progress/99) |
| Turkish (Türkçe) (tr_TR) | ![94%](https://geps.dev/progress/94) |
| Ukrainian (Українська) (uk_UA) | ![82%](https://geps.dev/progress/82) |
| Vietnamese (Tiếng Việt) (vi_VN) | ![91%](https://geps.dev/progress/91) |
| Vietnamese (Tiếng Việt) (vi_VN) | ![90%](https://geps.dev/progress/90) |
## Contributing (creating issues, translations, fixing bugs, etc.)

View File

@@ -22,7 +22,7 @@ ext {
}
group = "stirling.software"
version = "0.30.1"
version = "0.30.0"
java {
// 17 is lowest but we support and recommend 21
@@ -119,7 +119,7 @@ configurations.all {
}
dependencies {
//security updates
implementation "org.springframework:spring-webmvc:6.1.14"
implementation "org.springframework:spring-webmvc:6.1.13"
implementation("io.github.pixee:java-security-toolkit:1.2.0")
@@ -204,8 +204,8 @@ dependencies {
implementation "io.micrometer:micrometer-core:1.13.6"
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
// https://mvnrepository.com/artifact/org.commonmark/commonmark
implementation "org.commonmark:commonmark:0.24.0"
implementation "org.commonmark:commonmark-ext-gfm-tables:0.24.0"
implementation "org.commonmark:commonmark:0.23.0"
implementation "org.commonmark:commonmark-ext-gfm-tables:0.23.0"
// https://mvnrepository.com/artifact/com.bucket4j/bucket4j_jdk17
implementation "com.bucket4j:bucket4j_jdk17-core:8.14.0"
implementation "com.fathzer:javaluator:3.0.5"

View File

@@ -1,5 +1,5 @@
apiVersion: v2
appVersion: 0.30.1
appVersion: 0.30.0
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

@@ -1,20 +0,0 @@
#!/bin/bash
# Check if a key was provided
if [ $# -eq 0 ]; then
echo "Please provide a key to remove."
exit 1
fi
key_to_remove="$1"
for file in ../src/main/resources/messages_*.properties; do
# If the key ends with a dot, remove all keys starting with it
if [[ "$key_to_remove" == *. ]]; then
sed -i "/^${key_to_remove//./\\.}/d" "$file"
else
# Otherwise, remove only the exact key match
sed -i "/^${key_to_remove//./\\.}=/d" "$file"
fi
echo "Updated $file"
done

View File

@@ -7,19 +7,20 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties;
@Configuration
@Lazy
@Slf4j
public class EEAppConfig {
private static final Logger logger = LoggerFactory.getLogger(EEAppConfig.class);
@Autowired ApplicationProperties applicationProperties;
@Autowired private LicenseKeyChecker licenseKeyChecker;
@Bean(name = "runningEE")
public boolean runningEnterpriseEdition() {
return licenseKeyChecker.getEnterpriseEnabledResult();
return licenseKeyChecker.getEnterpriseEnabledResult();
}
}
}

View File

@@ -15,7 +15,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
@@ -163,14 +162,12 @@ public class AppConfig {
}
@Bean(name = "analyticsPrompt")
@Scope("request")
public boolean analyticsPrompt() {
return applicationProperties.getSystem().getEnableAnalytics() == null
|| "undefined".equals(applicationProperties.getSystem().getEnableAnalytics());
}
@Bean(name = "analyticsEnabled")
@Scope("request")
public boolean analyticsEnabled() {
if (applicationProperties.getEnterpriseEdition().isEnabled()) return true;
return applicationProperties.getSystem().getEnableAnalytics() != null

View File

@@ -8,7 +8,6 @@ import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import io.micrometer.common.util.StringUtils;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import stirling.software.SPDF.model.ApplicationProperties;
@@ -40,26 +39,4 @@ public class InitialSetup {
applicationProperties.getAutomaticallyGenerated().setKey(secretKey);
}
}
@PostConstruct
public void initLegalUrls() throws IOException {
// Initialize Terms and Conditions
String termsUrl = applicationProperties.getLegal().getTermsAndConditions();
if (StringUtils.isEmpty(termsUrl)) {
String defaultTermsUrl = "https://www.stirlingpdf.com/terms-and-conditions";
GeneralUtils.saveKeyToConfig("legal.termsAndConditions", defaultTermsUrl);
applicationProperties.getLegal().setTermsAndConditions(defaultTermsUrl);
}
// Initialize Privacy Policy
String privacyUrl = applicationProperties.getLegal().getPrivacyPolicy();
if (StringUtils.isEmpty(privacyUrl)) {
String defaultPrivacyUrl = "https://www.stirlingpdf.com/privacy-policy";
GeneralUtils.saveKeyToConfig("legal.privacyPolicy", defaultPrivacyUrl);
applicationProperties.getLegal().setPrivacyPolicy(defaultPrivacyUrl);
}
}
}

View File

@@ -32,6 +32,7 @@ import org.springframework.security.saml2.provider.service.authentication.OpenSa
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrations;
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@@ -203,7 +204,7 @@ public class SecurityConfiguration {
}
// Handle SAML
if (applicationProperties.getSecurity().isSaml2Activ() && applicationProperties.getSystem().getEnableAlphaFunctionality()) {
if (applicationProperties.getSecurity().isSaml2Activ()) {
http.authenticationProvider(samlAuthenticationProvider());
http.saml2Login(
saml2 ->
@@ -397,17 +398,41 @@ public class SecurityConfiguration {
Saml2X509Credential verificationCredential = Saml2X509Credential.verification(idpCert);
RelyingPartyRegistration rp =
RelyingPartyRegistration.withRegistrationId(samlConf.getRegistrationId())
RelyingPartyRegistrations.fromMetadataLocation(samlConf.getIdpMetadataUriString())
.entityId(samlConf.getEntityId())
.registrationId(samlConf.getRegistrationId())
.signingX509Credentials((c) -> c.add(signingCredential))
.singleLogoutServiceLocation(samlConf.getIdpSingleLogoutUrl())
.assertingPartyDetails(
(details) ->
details.entityId(samlConf.getIdpIssuer())
.singleSignOnServiceLocation(
samlConf.getIdpSingleLoginUrl())
details
//
// .entityId(samlConf.getIdpIssuer())
//
// .singleSignOnServiceLocation(
//
// samlConf.getIdpSingleLoginUrl())
.verificationX509Credentials(
(c) -> c.add(verificationCredential))
.wantAuthnRequestsSigned(true))
.build();
/*
RelyingPartyRegistration rp =
RelyingPartyRegistration.withRegistrationId(samlConf.getRegistrationId())
.entityId(samlConf.getEntityId())
.signingX509Credentials((c) -> c.add(signingCredential))
.assertingPartyDetails(
(details) ->
details.entityId(samlConf.getEntityId())
.singleSignOnServiceLocation(
samlConf.getIdpSingleLoginUrl())
.verificationX509Credentials(
(c) -> c.add(verificationCredential))
.wantAuthnRequestsSigned(true))
.build();
*/
return new InMemoryRelyingPartyRegistrationRepository(rp);
}

View File

@@ -45,6 +45,9 @@ public class UserService implements UserServiceInterface {
@Autowired DatabaseBackupInterface databaseBackupHelper;
public long getTotalUserCount() {
return userRepository.count();
}
// Handle OAUTH2 login and user auto creation.
public boolean processOAuth2PostLogin(String username, boolean autoCreateUser)
@@ -359,9 +362,4 @@ public class UserService implements UserServiceInterface {
return principal.toString();
}
}
@Override
public long getTotalUsersCount() {
return userRepository.count();
}
}

View File

@@ -70,16 +70,21 @@ public class CustomSaml2ResponseAuthenticationConverter
private Map<String, List<Object>> extractAttributes(Assertion assertion) {
Map<String, List<Object>> attributes = new HashMap<>();
for (AttributeStatement attributeStatement : assertion.getAttributeStatements()) {
for (Attribute attribute : attributeStatement.getAttributes()) {
String attributeName = attribute.getName();
List<Object> values = new ArrayList<>();
for (XMLObject xmlObject : attribute.getAttributeValues()) {
log.info("BOOL: " + ((XSBoolean) xmlObject).getValue());
values.add(((XSString) xmlObject).getValue());
try {
for (AttributeStatement attributeStatement : assertion.getAttributeStatements()) {
for (Attribute attribute : attributeStatement.getAttributes()) {
String attributeName = attribute.getName();
List<Object> values = new ArrayList<>();
for (XMLObject xmlObject : attribute.getAttributeValues()) {
log.info("BOOL: " + ((XSBoolean) xmlObject).getValue());
values.add(((XSString) xmlObject).getValue());
}
attributes.put(attributeName, values);
}
attributes.put(attributeName, values);
}
} catch (Exception ex) {
log.error("Could not extract attributes. Error: " + ex.getMessage());
return attributes;
}
return attributes;
}

View File

@@ -32,7 +32,6 @@ public class SettingsController {
}
GeneralUtils.saveKeyToConfig("system.enableAnalytics", String.valueOf(enabled), false);
applicationProperties.getSystem().setEnableAnalytics(String.valueOf(enabled));
return ResponseEntity.ok("Updated");
}
}

View File

@@ -4,6 +4,4 @@ public interface UserServiceInterface {
String getApiKeyForUser(String username);
String getCurrentUsername();
long getTotalUsersCount();
}

View File

@@ -124,6 +124,7 @@ public class ApplicationProperties {
private Boolean enabled = false;
private Boolean autoCreateUser = false;
private Boolean blockRegistration = false;
private String entityId = "stirling";
private String registrationId = "stirling";
private String idpMetadataUri;
private String idpSingleLogoutUrl;
@@ -149,6 +150,10 @@ public class ApplicationProperties {
}
}
public String getIdpMetadataUriString() {
return this.idpMetadataUri;
}
public Resource getSpCert() {
if (spCert.startsWith("classpath:")) {
return new ClassPathResource(spCert.substring("classpath:".length()));
@@ -172,6 +177,10 @@ public class ApplicationProperties {
return new FileSystemResource(privateKey);
}
}
public String getEntityId() {
return entityId;
}
}
@Data

View File

@@ -19,7 +19,6 @@ import org.springframework.stereotype.Service;
import com.posthog.java.PostHog;
import stirling.software.SPDF.controller.api.pipeline.UserServiceInterface;
import stirling.software.SPDF.model.ApplicationProperties;
@Service
@@ -27,18 +26,15 @@ public class PostHogService {
private final PostHog postHog;
private final String uniqueId;
private final ApplicationProperties applicationProperties;
private final UserServiceInterface userService;
@Autowired
public PostHogService(
PostHog postHog,
@Qualifier("UUID") String uuid,
ApplicationProperties applicationProperties, @Autowired(required = false) UserServiceInterface userService) {
ApplicationProperties applicationProperties) {
this.postHog = postHog;
this.uniqueId = uuid;
this.applicationProperties = applicationProperties;
this.userService = userService;
captureSystemInfo();
}
@@ -137,11 +133,6 @@ public class PostHogService {
metrics.put("docker_metrics", getDockerMetrics());
}
metrics.put("application_properties", captureApplicationProperties());
if(userService != null) {
metrics.put("total_users_created", userService.getTotalUsersCount());
}
} catch (Exception e) {
metrics.put("error", e.getMessage());

View File

@@ -50,4 +50,6 @@ springdoc.swagger-ui.url=/v1/api-docs
posthog.api.key=phc_fiR65u5j6qmXTYL56MNrLZSWqLaDW74OrZH0Insd2xq
posthog.host=https://eu.i.posthog.com
posthog.host=https://eu.i.posthog.com
server.port=8090

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=تم تعطيل المستخدم، تم حظر تسجيل
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=حجب تلقائي

View File

@@ -3,8 +3,8 @@
###########
# the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr
addPageNumbers.fontSize=Размер на шрифт
addPageNumbers.fontName=Име на шрифт
addPageNumbers.fontSize=Font Size
addPageNumbers.fontName=Font Name
pdfPrompt=Изберете PDF(и)
multiPdfPrompt=Изберете PDF (2+)
multiPdfDropPrompt=Изберете (или плъзнете и пуснете) всички PDF файлове, от които се нуждаете
@@ -56,12 +56,12 @@ userNotFoundMessage=Потребителят не е намерен
incorrectPasswordMessage=Текущата парола е неправилна.
usernameExistsMessage=Новият потребител вече съществува.
invalidUsernameMessage=Невалидно потребителско име, потребителското име може да съдържа само букви, цифри и следните специални знаци @._+- или трябва да е валиден имейл адрес.
invalidPasswordMessage=Паролата не трябва да е празна и не трябва да има интервали в началото или в края.
confirmPasswordErrorMessage=Нова парола и Потвърждаване на новата парола трябва да съвпадат.
invalidPasswordMessage=The password must not be empty and must not have spaces at the beginning or end.
confirmPasswordErrorMessage=New Password and Confirm New Password must match.
deleteCurrentUserMessage=Не може да се изтрие вписания в момента потребител.
deleteUsernameExistsMessage=Потребителското име не съществува и не може да бъде изтрито.
downgradeCurrentUserMessage=Не може да се понижи ролята на текущия потребител
disabledCurrentUserMessage=Текущият потребител не може да бъде деактивиран
disabledCurrentUserMessage=The current user cannot be disabled
downgradeCurrentUserLongMessage=Не може да се понижи ролята на текущия потребител. Следователно текущият потребител няма да бъде показан.
userAlreadyExistsOAuthMessage=Потребителят вече съществува като OAuth2 потребител.
userAlreadyExistsWebMessage=Потребителят вече съществува като уеб-потребител.
@@ -75,16 +75,16 @@ visitGithub=Посетете Github Repository
donate=Направете дарение
color=Цвят
sponsor=Спонсор
info=Информация
info=Info
pro=Pro
page=Страница
pages=Страници
page=Page
pages=Pages
legal.privacy=Политика за поверителност
legal.terms=Правила и условия
legal.accessibility=Достъпност
legal.cookie=Политика за бисквитки
legal.impressum=Отпечатък
legal.privacy=Privacy Policy
legal.terms=Terms and Conditions
legal.accessibility=Accessibility
legal.cookie=Cookie Policy
legal.impressum=Impressum
###############
# Pipeline #
@@ -96,7 +96,7 @@ pipeline.defaultOption=Персонализиран
pipeline.submitButton=Подайте
pipeline.help=Pipeline Помощ
pipeline.scanHelp=Помощ за сканиране на папки
pipeline.deletePrompt=Сигурни ли сте, че искате да изтриете pipeline
pipeline.deletePrompt=Are you sure you want to delete pipeline
######################
# Pipeline Options #
@@ -114,21 +114,21 @@ pipelineOptions.validateButton=Валидирай
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Направете надстройка до Pro версията
enterpriseEdition.warning=Тази функция е достъпна само за потребители на Pro версията.
enterpriseEdition.yamlAdvert=Stirling PDF Pro поддържа YAML конфигурационни файлове и други SSO функции.
enterpriseEdition.ssoAdvert=Търсите повече функции за управление на потребителите? Погледнете за Stirling PDF Pro
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Искате ли да подобрите Stirling PDF?
analytics.paragraph1=Stirling PDF включва анализи, за да ни помогне да подобрим продукта. Ние не проследяваме лична информация или съдържание на файлове.
analytics.paragraph2=Моля, обмислете възможността за анализ, за ​​да помогнете на Stirling-PDF да расте и да ни позволи да разберем по-добре нашите потребители.
analytics.enable=Активиране на анализа
analytics.disable=Деактивиране на анализа
analytics.settings=Можете да промените настройките за анализ във config/settings.yml файла
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
#############
# NAVBAR #
@@ -145,7 +145,7 @@ navbar.sections.convertFrom=Преобразуване от PDF
navbar.sections.security=Подписване и сигурност
navbar.sections.advance=Разширено
navbar.sections.edit=Преглед и редактиране
navbar.sections.popular=Популярни
navbar.sections.popular=Popular
#############
# SETTINGS #
@@ -202,9 +202,9 @@ adminUserSettings.header=Настройки за администраторск
adminUserSettings.admin=Администратор
adminUserSettings.user=Потребител
adminUserSettings.addUser=Добавяне на нов потребител
adminUserSettings.deleteUser=Изтриване на потребител
adminUserSettings.confirmDeleteUser=Трябва ли потребителят да бъде изтрит?
adminUserSettings.confirmChangeUserStatus=Трябва ли потребителят да бъде деактивиран/активиран?
adminUserSettings.deleteUser=Delete User
adminUserSettings.confirmDeleteUser=Should the user be deleted?
adminUserSettings.confirmChangeUserStatus=Should the user be disabled/enabled?
adminUserSettings.usernameInfo=Потребителското име може да съдържа само букви, цифри и следните специални символи @._+- или трябва да е валиден имейл адрес.
adminUserSettings.roles=Роли
adminUserSettings.role=Роля
@@ -218,32 +218,32 @@ adminUserSettings.forceChange=Принудете потребителя да п
adminUserSettings.submit=Съхранете потребителя
adminUserSettings.changeUserRole=Промяна на ролята на потребителя
adminUserSettings.authenticated=Удостоверен
adminUserSettings.editOwnProfil=Редактиране на собствен профил
adminUserSettings.enabledUser=активиран потребител
adminUserSettings.disabledUser=деактивиран потребител
adminUserSettings.activeUsers=Активни потребители:
adminUserSettings.disabledUsers=Деактивирани потребители:
adminUserSettings.totalUsers=Общо потребители:
adminUserSettings.lastRequest=Последна заявка
adminUserSettings.editOwnProfil=Edit own profile
adminUserSettings.enabledUser=enabled user
adminUserSettings.disabledUser=disabled user
adminUserSettings.activeUsers=Active Users:
adminUserSettings.disabledUsers=Disabled Users:
adminUserSettings.totalUsers=Total Users:
adminUserSettings.lastRequest=Last Request
database.title=Импорт/Експорт на база данни
database.header=Импорт/Експорт на база данни
database.fileName=Име на файл
database.creationDate=Дата на създаване
database.fileSize=Размер на файла
database.deleteBackupFile=Изтриване на архивен файл
database.importBackupFile=Импортиране на архивен файл
database.downloadBackupFile=Изтеглете архивен файл
database.info_1=Когато импортирате данни, е от решаващо значение да осигурите правилната структура. Ако не сте сигурни в това, което правите, потърсете съвет и подкрепа от професионалист. Грешка в структурата може да причини неизправност на приложението, включително пълна невъзможност за стартиране на приложението.
database.info_2=Името на файла няма значение при качване. След това ще бъде преименуван, за да следва формата backup_user_yyyyMMddHHmm.sql, осигурявайки последователна конвенция за именуване.
database.submit=Импортиране на резервно копие
database.importIntoDatabaseSuccessed=Импортирането в базата данни бе успешно
database.fileNotFound=Файлът не е намерен
database.fileNullOrEmpty=Файлът не трябва да е нулев или празен
database.failedImportFile=Неуспешно импортиране на файл
database.title=Database Import/Export
database.header=Database Import/Export
database.fileName=File Name
database.creationDate=Creation Date
database.fileSize=File Size
database.deleteBackupFile=Delete Backup File
database.importBackupFile=Import Backup File
database.downloadBackupFile=Download Backup File
database.info_1=When importing data, it is crucial to ensure the correct structure. If you are unsure of what you are doing, seek advice and support from a professional. An error in the structure can cause application malfunctions, up to and including the complete inability to run the application.
database.info_2=The file name does not matter when uploading. It will be renamed afterward to follow the format backup_user_yyyyMMddHHmm.sql, ensuring a consistent naming convention.
database.submit=Import Backup
database.importIntoDatabaseSuccessed=Import into database successed
database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File
session.expired=Вашата сесия е изтекла. Моля, опреснете страницата и опитайте отново.
session.expired=Your session has expired. Please refresh the page and try again.
#############
# HOME-PAGE #
@@ -390,9 +390,9 @@ home.certSign.title=Подпишете със сертификат
home.certSign.desc=Подписва PDF със сертификат/ключ (PEM/P12)
certSign.tags=удостоверяване,PEM,P12,официален,шифроване
home.removeCertSign.title=Премахване на знака за сертификат
home.removeCertSign.desc=Премахване на подпис на сертификат от PDF
removeCertSign.tags=удостоверяване,PEM,P12,официален,декриптиране
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Оформление с няколко страници
home.pageLayout.desc=Слейте няколко страници от PDF документ в една страница
@@ -498,33 +498,33 @@ home.BookToPDF.title=Книга към PDF
home.BookToPDF.desc=Преобразува формати на книги/комикси в PDF с помощта на calibre
BookToPDF.tags=Книга,комикс,calibre,конвертиране,манга,Amazon,Kindle
home.removeImagePdf.title=Премахване на изображение
home.removeImagePdf.desc=Премахнете изображението от PDF, за да намалите размера на файла
removeImagePdf.tags=Премахване на изображение, операции на страници, админ страна, страна на сървъра
home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Разделете PDF по глави
home.splitPdfByChapters.desc=Разделете PDF на множество файлове въз основа на неговата структура на глави.
splitPdfByChapters.tags=разделяне, глави, отметки, организиране
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color
replace-color.title=Замени-инвертиране-на-цвят
replace-color.header=Замяна-инвертиране на цвят PDF
home.replaceColorPdf.title=Замяна и обръщане на цвят
home.replaceColorPdf.desc=Заменете цвета на текста и фона в PDF и обърнете пълния цвят на PDF, за да намалите размера на файла
replaceColorPdf.tags=Замяна на цвят, операции на страници, заден край, страна на сървъра
replace-color.selectText.1=Опции за замяна или инвертиране на цвят
replace-color.selectText.2=По подразбиране (цветове с висок контраст по подразбиране)
replace-color.selectText.3=По избор (персонализирани цветове)
replace-color.selectText.4=Пълно инвертиране (Инвертиране на всички цветове)
replace-color.selectText.5=Цветови опции с висок контраст
replace-color.selectText.6=Бял текст на черен фон
replace-color.selectText.7=Черен текст на бял фон
replace-color.selectText.8=Жълт текст на черен фон
replace-color.selectText.9=Зелен текст на черен фон
replace-color.selectText.10=Изберете цвят на текста
replace-color.selectText.11=Изберете цвят на фона
replace-color.submit=Замени
replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF
home.replaceColorPdf.title=Replace and Invert Color
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side
replace-color.selectText.1=Replace or Invert color Options
replace-color.selectText.2=Default(Default high contrast colors)
replace-color.selectText.3=Custom(Customized colors)
replace-color.selectText.4=Full-Invert(Invert all colors)
replace-color.selectText.5=High contrast color options
replace-color.selectText.6=white text on black background
replace-color.selectText.7=Black text on white background
replace-color.selectText.8=Yellow text on black background
replace-color.selectText.9=Green text on black background
replace-color.selectText.10=Choose text Color
replace-color.selectText.11=Choose background Color
replace-color.submit=Replace
@@ -543,17 +543,18 @@ login.locked=Вашият акаунт е заключен.
login.signinTitle=Моля впишете се
login.ssoSignIn=Влизане чрез еднократно влизане
login.oauth2AutoCreateDisabled=OAUTH2 Автоматично създаване на потребител е деактивирано
login.oauth2AdminBlockedUser=Регистрацията или влизането на нерегистрирани потребители в момента е блокирано. Моля, свържете се с администратора.
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
login.oauth2RequestNotFound=Заявката за оторизация не е намерена
login.oauth2InvalidUserInfoResponse=Невалидна информация за потребителя
login.oauth2invalidRequest=Невалидна заявка
login.oauth2AccessDenied=Отказан достъп
login.oauth2InvalidTokenResponse=Невалиден отговор на токена
login.oauth2InvalidIdToken=Невалиден токен за идентификатор
login.userIsDisabled=Потребителят е деактивиран, влизането в момента е блокирано с това потребителско име. Моля, свържете се с администратора.
login.alreadyLoggedIn=Вече сте влезли в
login.alreadyLoggedIn2=устройства. Моля, излезте от устройствата и опитайте отново.
login.toManySessions=Имате твърде много активни сесии
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Автоматично редактиране
@@ -728,7 +729,7 @@ pageLayout.submit=Подайте
scalePages.title=Коригиране на мащаба на страницата
scalePages.header=Коригиране на мащаба на страницата
scalePages.pageSize=Размер на страница от документа.
scalePages.keepPageSize=Оригинален размер
scalePages.keepPageSize=Original Size
scalePages.scaleFactor=Ниво на мащабиране (изрязване) на страница.
scalePages.submit=Подайте
@@ -752,10 +753,10 @@ certSign.submit=Подпишете PDF
#removeCertSign
removeCertSign.title=Премахване на подписа на сертификата
removeCertSign.header=Премахнете цифровия сертификат от PDF
removeCertSign.selectPDF=Изберете PDF файл:
removeCertSign.submit=Премахване на подпис
removeCertSign.title=Remove Certificate Signature
removeCertSign.header=Remove the digital certificate from the PDF
removeCertSign.selectPDF=Select a PDF file:
removeCertSign.submit=Remove Signature
#removeBlanks
@@ -777,8 +778,8 @@ removeAnnotations.submit=Премахване
#compare
compare.title=Сравнявай
compare.header=Сравнявай PDF-и
compare.highlightColor.1=Цвят на маркирането 1:
compare.highlightColor.2=Цвят на маркирането 2:
compare.highlightColor.1=Highlight Color 1:
compare.highlightColor.2=Highlight Color 2:
compare.document.1=Документ 1
compare.document.2=Документ 2
compare.submit=Сравнявай
@@ -830,7 +831,7 @@ ScannerImageSplit.selectText.7=Минимална контурна площ:
ScannerImageSplit.selectText.8=Задава минималния праг на контурната площ за изображение
ScannerImageSplit.selectText.9=Размер на рамката:
ScannerImageSplit.selectText.10=Задава размера на добавената и премахната граница, за да предотврати бели граници към изхода (по подразбиране: 1).
ScannerImageSplit.info=Python не е инсталиран. Изисква се да се изпълнява.
ScannerImageSplit.info=Python is not installed. It is required to run.
#OCR
@@ -857,7 +858,7 @@ ocr.submit=Обработка на PDF чрез OCR
extractImages.title=Извличане на изображения
extractImages.header=Извличане на изображения
extractImages.selectText=Изберете формат на изображението, в който да преобразувате извлечените изображения
extractImages.allowDuplicates=Запазване на дублирани изображения
extractImages.allowDuplicates=Save duplicate images
extractImages.submit=Извличане
@@ -895,7 +896,7 @@ merge.title=Обединяване
merge.header=Обединяване на множество PDF файлове (2+)
merge.sortByName=Сортиране по име
merge.sortByDate=Сортиране по дата
merge.removeCertSign=Премахване на цифровия подпис в обединения файл?
merge.removeCertSign=Remove digital signature in the merged file?
merge.submit=Обединяване
@@ -913,7 +914,7 @@ pdfOrganiser.mode.6=Четно-нечетно разделяне
pdfOrganiser.mode.7=Премахни първо
pdfOrganiser.mode.8=Премахване на последния
pdfOrganiser.mode.9=Премахване на първия и последния
pdfOrganiser.mode.10=Обединяване на четно и нечетно
pdfOrganiser.mode.10=Odd-Even Merge
pdfOrganiser.placeholder=(напр. 1,3,2 или 4-8,2,10-12 или 2n-1)
@@ -982,7 +983,7 @@ pdfToImage.color=Цвят
pdfToImage.grey=Скала на сивото
pdfToImage.blackwhite=Черно и бяло (може да загубите данни!)
pdfToImage.submit=Преобразуване
pdfToImage.info=Python не е инсталиран. Изисква се за конвертиране на WebP.
pdfToImage.info=Python is not installed. Required for WebP conversion.
#addPassword
@@ -1019,7 +1020,7 @@ watermark.selectText.6=дължинаSpacer (Разстояние между в
watermark.selectText.7=Непрозрачност (0% - 100%):
watermark.selectText.8=Тип воден знак:
watermark.selectText.9=Изображение за воден знак:
watermark.selectText.10=Конвертирайте PDF в PDF-изображение
watermark.selectText.10=Convert PDF to PDF-Image
watermark.submit=Добавяне на воден знак
watermark.type.1=Текст
watermark.type.2=Изображение
@@ -1076,7 +1077,7 @@ pdfToPDFA.credit=Тази услуга използва ghostscript за PDF/A
pdfToPDFA.submit=Преобразуване
pdfToPDFA.tip=В момента не работи за няколко входа наведнъж
pdfToPDFA.outputFormat=Изходен формат
pdfToPDFA.pdfWithDigitalSignature=PDF файлът съдържа цифров подпис. Това ще бъде премахнато в следващата стъпка.
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord
@@ -1117,10 +1118,10 @@ PDFToXML.credit=Тази услуга използва LibreOffice за прео
PDFToXML.submit=Преобразуване
#PDFToCSV
PDFToCSV.title=PDF към CSV
PDFToCSV.header=PDF към CSV
PDFToCSV.title=PDF ??? CSV
PDFToCSV.header=PDF ??? CSV
PDFToCSV.prompt=Изберете страница за извличане на таблица
PDFToCSV.submit=Преобразуване
PDFToCSV.submit=????
#split-by-size-or-count
split-by-size-or-count.title=Разделяне на PDF по размер или брой
@@ -1178,15 +1179,15 @@ licenses.version=Версия
licenses.license=Лиценз
#survey
survey.nav=Анкета
survey.title=Stirling-PDF Анкета
survey.description=Stirling-PDF няма проследяване, така че искаме да чуем мнението на нашите потребители за подобряване на Stirling-PDF!
survey.changes=Stirling-PDF се промени от последното проучване! За да научите повече, моля, проверете публикацията в нашия блог тук:
survey.changes2=С тези промени получаваме платена бизнес подкрепа и финансиране
survey.please=Моля, помислете дали да не участвате в нашата анкета!
survey.disabled=(Изскачащият прозорец с анкетата ще бъде деактивиран при следващите актуализации, но ще бъде наличен в долната част на страницата)
survey.button=Участвайте в анкетата
survey.dontShowAgain=Не показвай повече
survey.nav=Survey
survey.title=Stirling-PDF Survey
survey.description=Stirling-PDF has no tracking so we want to hear from our users to improve Stirling-PDF!
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Please consider taking our survey!
survey.disabled=(Survey popup will be disabled in following updates but available at foot of page)
survey.button=Take Survey
survey.dontShowAgain=Don't show again
#error
@@ -1204,21 +1205,21 @@ error.discordSubmit=Discord - Изпратете запитване за под
#remove-image
removeImage.title=Премахване на изображението
removeImage.header=Премахване на изображението
removeImage.removeImage=Премахване на изображението
removeImage.submit=Премахване на изображението
removeImage.title=Remove image
removeImage.header=Remove image
removeImage.removeImage=Remove image
removeImage.submit=Remove image
splitByChapters.title=Разделете PDF по глави
splitByChapters.header=Разделете PDF по глави
splitByChapters.bookmarkLevel=Ниво на отметка
splitByChapters.includeMetadata=Включете метаданни
splitByChapters.allowDuplicates=Разрешаване на дубликати
splitByChapters.desc.1=Този инструмент разделя PDF файл на множество PDF файлове въз основа на неговата структура на глави.
splitByChapters.desc.2=Ниво на отметка: Изберете нивото на отметките, които да използвате за разделяне (0 за най-високо ниво, 1 за второ ниво и т.н.).
splitByChapters.desc.3=Включване на метаданни: Ако е отметнато, метаданните на оригиналния PDF ще бъдат включени във всеки разделен PDF.
splitByChapters.desc.4=Разрешаване на дубликати: Ако е отметнато, позволява множество отметки на една и съща страница за създаване на отделни PDF файлове.
splitByChapters.submit=Разделяне на PDF
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Auto Redact

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Auto Redact

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=Bruger er deaktiveret, login er i øjeblikket blokeret med
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Auto Rediger

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=Benutzer ist deaktiviert, die Anmeldung ist mit diesem Benu
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Automatisch zensieren/schwärzen

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Αυτόματο Μαύρισμα Κειμένου

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Auto Redact

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Auto Redact

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=El usuario está desactivado, actualmente el acceso está b
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Auto Redactar

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Auto Idatzi

View File

@@ -145,7 +145,7 @@ navbar.sections.convertFrom=Convertir depuis PDF
navbar.sections.security=Signature et sécurité
navbar.sections.advance=Mode avancé
navbar.sections.edit=Voir et modifier
navbar.sections.popular=Populaire
navbar.sections.popular=Popular
#############
# SETTINGS #
@@ -202,9 +202,9 @@ adminUserSettings.header=Administration des paramètres des utilisateurs
adminUserSettings.admin=Administateur
adminUserSettings.user=Utilisateur
adminUserSettings.addUser=Ajouter un utilisateur
adminUserSettings.deleteUser=Supprimer l'utilisateur
adminUserSettings.confirmDeleteUser=Voulez vous vraiment supprimer l'utilisateur ?
adminUserSettings.confirmChangeUserStatus=Voulez vous vraiment déactiver/réactiver l'utilisateur ?
adminUserSettings.deleteUser=Delete User
adminUserSettings.confirmDeleteUser=Should the user be deleted?
adminUserSettings.confirmChangeUserStatus=Should the user be disabled/enabled?
adminUserSettings.usernameInfo=Le nom d'utilisateur ne peut contenir que des lettres, des chiffres et les caractères spéciaux suivants @._+- ou doit être une adresse e-mail valide.
adminUserSettings.roles=Rôles
adminUserSettings.role=Rôle
@@ -218,13 +218,13 @@ adminUserSettings.forceChange=Forcer lutilisateur à changer son nom dutil
adminUserSettings.submit=Ajouter
adminUserSettings.changeUserRole=Changer le rôle de l'utilisateur
adminUserSettings.authenticated=Authentifié
adminUserSettings.editOwnProfil=Éditer son propre profil
adminUserSettings.enabledUser=Utilisateur activé
adminUserSettings.disabledUser=Utilisateur désactivé
adminUserSettings.activeUsers=Utilisateurs actifs :
adminUserSettings.disabledUsers=Utilisateurs désactivés :
adminUserSettings.totalUsers=Utilisateurs au total :
adminUserSettings.lastRequest=Dernière requête
adminUserSettings.editOwnProfil=Edit own profile
adminUserSettings.enabledUser=enabled user
adminUserSettings.disabledUser=disabled user
adminUserSettings.activeUsers=Active Users:
adminUserSettings.disabledUsers=Disabled Users:
adminUserSettings.totalUsers=Total Users:
adminUserSettings.lastRequest=Last Request
database.title=Database Import/Export
@@ -243,7 +243,7 @@ database.fileNotFound=File not Found
database.fileNullOrEmpty=File must not be null or empty
database.failedImportFile=Failed Import File
session.expired=Votre session a expiré. Veuillez recharger la page et réessayer.
session.expired=Your session has expired. Please refresh the page and try again.
#############
# HOME-PAGE #
@@ -321,7 +321,7 @@ home.changeMetadata.desc=Modifiez, supprimez ou ajoutez des métadonnées à un
changeMetadata.tags=métadonnées,titre,auteur,date,création,heure,éditeur,statistiques,title,author,date,creation,time,publisher,producer,stats,metadata
home.fileToPDF.title=Fichier en PDF
home.fileToPDF.desc=Convertissez presque nimporte quel fichier en PDF (DOCX, PNG, XLS, PPT, TXT, etc.).
home.fileToPDF.desc=Convertissez presque nimporte quel fichiers en PDF (DOCX, PNG, XLS, PPT, TXT et plus).
fileToPDF.tags=convertion,transformation,format,document,image,slide,texte,conversion,office,docs,word,excel,powerpoint
home.ocr.title=OCR / Nettoyage des numérisations
@@ -390,9 +390,9 @@ home.certSign.title=Signer avec un certificat
home.certSign.desc=Signez un PDF avec un certificat ou une clé (PEM/P12).
certSign.tags=signer,chiffrer,certificat,authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Supprimer la signature par certificat
home.removeCertSign.desc=Supprimez la signature par certificat d'un PDF
removeCertSign.tags=signer,chiffrer,certificat,authenticate,PEM,P12,official,decrypt
home.removeCertSign.title=Remove Certificate Sign
home.removeCertSign.desc=Remove certificate signature from PDF
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Fusionner des pages
home.pageLayout.desc=Fusionnez plusieurs pages dun PDF en une seule.
@@ -498,14 +498,14 @@ home.BookToPDF.title=eBook vers PDF
home.BookToPDF.desc=Convertit les formats de livres/bandes dessinées en PDF à l'aide de calibre
BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.removeImagePdf.title=Supprimer les images
home.removeImagePdf.desc=Supprimez les images d'un PDF pour réduire sa taille
removeImagePdf.tags=Images,Remove Image,Page operations,Back end,server side
home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Séparer un PDF par chapitres
home.splitPdfByChapters.desc=Séparez un PDF en fichiers multiples en fonction de sa structure par chapitres.
splitPdfByChapters.tags=séparer,chapitres,split,chapters,bookmarks,organize
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color
replace-color.title=Replace-Invert-Color
@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Caviarder automatiquement
@@ -786,14 +787,14 @@ compare.submit=Comparer
#BookToPDF
BookToPDF.title=Livres et BD vers PDF
BookToPDF.header=Livre vers PDF
BookToPDF.credit=Utilise Calibre
BookToPDF.credit=Utiliser Calibre
BookToPDF.submit=Convertir
#PDFToBook
PDFToBook.title=PDF vers Livre
PDFToBook.header=PDF vers Livre
PDFToBook.selectText.1=Format
PDFToBook.credit=Utilise Calibre
PDFToBook.credit=Utiliser Calibre
PDFToBook.submit=Convertir
#sign
@@ -1076,7 +1077,7 @@ pdfToPDFA.credit=Ce service utilise ghostscript pour la conversion en PDF/A.
pdfToPDFA.submit=Convertir
pdfToPDFA.tip=Ne fonctionne actuellement pas pour plusieurs entrées à la fois
pdfToPDFA.outputFormat=Format de sortie
pdfToPDFA.pdfWithDigitalSignature=Le PDF contient une signature numérique. Elle sera supprimée dans l'étape suivante.
pdfToPDFA.pdfWithDigitalSignature=The PDF contains a digital signature. This will be removed in the next step.
#PDFToWord

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Auto Redact

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=स्वत: गोपनीयकरण

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Automatsko uređivanje

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Érzékeny tartalom eltávolítása

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Redaksional Otomatis

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=L'utente è disattivato, l'accesso è attualmente bloccato
login.alreadyLoggedIn=Hai già effettuato l'accesso a
login.alreadyLoggedIn2=dispositivi. Esci dai dispositivi e riprova.
login.toManySessions=Hai troppe sessioni attive
login.toManySessions2=Si prega di uscire dai dispositivi e riprovare. In alternativa, è possibile effettuare l'upgrade a Stirling PDF Pro.
#auto-redact
autoRedact.title=Redazione automatica

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=ユーザーは非アクティブ化されており、現
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=自動塗りつぶし

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=자동 검열

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Automatisch censureren

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Automatisk Sensurering

View File

@@ -3,8 +3,8 @@
###########
# the direction that the language is written (ltr = left to right, rtl = right to left)
language.direction=ltr
addPageNumbers.fontSize=Rozmiar Czcionki
addPageNumbers.fontName=Nazwa Czcionki
addPageNumbers.fontSize=Font Size
addPageNumbers.fontName=Font Name
pdfPrompt=Wybierz PDF
multiPdfPrompt=Wybierz PDF (2+)
multiPdfDropPrompt=Wybierz (lub przeciągnij i puść) wszystkie dokumenty PDF
@@ -56,12 +56,12 @@ userNotFoundMessage=Brak użytkownika.
incorrectPasswordMessage=Nieprawidłowe hasło.
usernameExistsMessage=Taki uzytkownik już istnieje.
invalidUsernameMessage=Niewłaściwa nazwa użytkownika - musi zawierać litery, cyfry i @._+- LUB być adresem email.
invalidPasswordMessage=Hasło nie może być puste i nie może zawierać spacji na początku ani na końcu.
invalidPasswordMessage=The password must not be empty and must not have spaces at the beginning or end.
confirmPasswordErrorMessage=Wpisz poprawnie hasło w OBA pola.
deleteCurrentUserMessage=Nie można usunąć zalogowanego użytkownika
deleteUsernameExistsMessage=Nie można usunąć zalogowanego użytkownika
downgradeCurrentUserMessage=Nie można obniżyć roli bieżącego użytkownika
disabledCurrentUserMessage=Nie można wyłączyć bieżącego użytkownika
disabledCurrentUserMessage=The current user cannot be disabled
downgradeCurrentUserLongMessage=Nie można obniżyć roli bieżącego użytkownika. W związku z tym bieżący użytkownik nie zostanie wyświetlony.
userAlreadyExistsOAuthMessage=Takie konto użytkownika istnieje - stworzone za pomocą OAuth2.
userAlreadyExistsWebMessage=Takie konto użytkownika istnieje - stworzone za pomocą przeglądarki.
@@ -77,14 +77,14 @@ color=kolor
sponsor=sponsor
info=informacje
pro=Pro
page=Strona
pages=Strony
page=Page
pages=Pages
legal.privacy=Polityka Prywatności
legal.terms=Zasady i Postanowienia
legal.accessibility=Dostępność
legal.cookie=Polityka plików cookie
legal.impressum=Impresja
legal.privacy=Privacy Policy
legal.terms=Terms and Conditions
legal.accessibility=Accessibility
legal.cookie=Cookie Policy
legal.impressum=Impressum
###############
# Pipeline #
@@ -114,21 +114,21 @@ pipelineOptions.validateButton=Waliduj
########################
# ENTERPRISE EDITION #
########################
enterpriseEdition.button=Uaktualnij do wersji Pro
enterpriseEdition.warning=Ta funkcja jest dostępna tylko dla użytkowników Pro.
enterpriseEdition.yamlAdvert=Stirling PDF Pro obsługuje pliki konfiguracyjne YAML i inne funkcje SSO.
enterpriseEdition.ssoAdvert=Szukasz więcej funkcji zarządzania użytkownikami? Sprawdź Stirling PDF Pro
enterpriseEdition.button=Upgrade to Pro
enterpriseEdition.warning=This feature is only available to Pro users.
enterpriseEdition.yamlAdvert=Stirling PDF Pro supports YAML configuration files and other SSO features.
enterpriseEdition.ssoAdvert=Looking for more user management features? Check out Stirling PDF Pro
#################
# Analytics #
#################
analytics.title=Czy chcesz ulepszyć Stirling PDF?
analytics.paragraph1=Stirling PDF ma opcję analizy, która pomaga nam udoskonalać produkt. Nie śledzimy żadnych danych osobowych ani zawartości plików.
analytics.paragraph2=Rozważ włączenie funkcji analitycznych, które pomogą w rozwoju Stirling-PDF i pozwolą nam lepiej zrozumieć naszych użytkowników.
analytics.enable=Włącz analitykę
analytics.disable=Wyłącz analitykę
analytics.settings=Możesz zmienić ustawienia analityki w pliku config/settings.yml
analytics.title=Do you want make Stirling PDF better?
analytics.paragraph1=Stirling PDF has opt in analytics to help us improve the product. We do not track any personal information or file contents.
analytics.paragraph2=Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.
analytics.enable=Enable analytics
analytics.disable=Disable analytics
analytics.settings=You can change the settings for analytics in the config/settings.yml file
#############
# NAVBAR #
@@ -138,14 +138,14 @@ navbar.darkmode=Tryb nocny
navbar.language=Języki
navbar.settings=Ustawienia
navbar.allTools=Narzędzia
navbar.multiTool=Narzędzie Wielofunkcyjne
navbar.multiTool=Multi Tools
navbar.sections.organize=Organizuj
navbar.sections.convertTo=Przetwórz na PDF
navbar.sections.convertFrom=Przetwórz z PDF
navbar.sections.security=Podpis i bezpieczeństwo
navbar.sections.advance=Zaawansowane
navbar.sections.edit=Podgląd i edycja
navbar.sections.popular=Popularne
navbar.sections.popular=Popular
#############
# SETTINGS #
@@ -218,13 +218,13 @@ adminUserSettings.forceChange=Wymuś zmianę hasło po zalogowaniu
adminUserSettings.submit=Zapisz użytkownika
adminUserSettings.changeUserRole=Zmień rolę użytkownika
adminUserSettings.authenticated=Zalogowany
adminUserSettings.editOwnProfil=Edytuj własny profil
adminUserSettings.enabledUser=włączony użytkownik
adminUserSettings.disabledUser=wyłączony użytkownik
adminUserSettings.activeUsers=Aktywni Użytkownicy:
adminUserSettings.disabledUsers=Wyłączeni Użytkownicy:
adminUserSettings.totalUsers=Łączna Liczba Użytkowników:
adminUserSettings.lastRequest=Ostatnie Zgłoszenie
adminUserSettings.editOwnProfil=Edit own profile
adminUserSettings.enabledUser=enabled user
adminUserSettings.disabledUser=disabled user
adminUserSettings.activeUsers=Active Users:
adminUserSettings.disabledUsers=Disabled Users:
adminUserSettings.totalUsers=Total Users:
adminUserSettings.lastRequest=Last Request
database.title=Import/Eksport bazy danych
@@ -243,7 +243,7 @@ database.fileNotFound=Plik nie znaleziony
database.fileNullOrEmpty=Plik nie może być pusty
database.failedImportFile=Nie udało się zaimportować pliku
session.expired=Twoja sesja wygasła. Odśwież stronę i spróbuj ponownie.
session.expired=Your session has expired. Please refresh the page and try again.
#############
# HOME-PAGE #
@@ -256,207 +256,207 @@ home.viewPdf.title=Podejrzyj PDF
home.viewPdf.desc=Wyświetl, adnotuj, dodaj tekst lub obrazy
viewPdf.tags=wyświetl,czytaj,adnotuj,tekst,obraz
home.multiTool.title=Wielofunkcyjne Narzędzie PDF
home.multiTool.title=Multi narzędzie PDF
home.multiTool.desc=Łącz, dziel, obracaj, zmieniaj kolejność i usuwaj strony
multiTool.tags=Wielofunkcyjne narzędzie, obsługa wielu operacji, interfejs użytkownika, przeciąganie kliknięć, front-end, strona klienta
multiTool.tags=Multi Tool,Multi operation,UI,click drag,front end,client side
home.merge.title=Połącz
home.merge.desc=Łatwe łączenie wielu dokumentów PDF w jeden.
merge.tags=scalanie, operacje na stronach, back-end, po stronie serwera
merge.tags=merge,Page operations,Back end,server side
home.split.title=Podziel
home.split.desc=Podziel dokument PDF na wiele dokumentów
split.tags=Operacje na stronach, dzielenie, wiele stron, cięcie, po stronie serwera
split.tags=Page operations,divide,Multi Page,cut,server side
home.rotate.title=Obróć
home.rotate.desc=Łatwo obracaj dokumenty PDF.
rotate.tags=strona serwera
rotate.tags=server side
home.imageToPdf.title=Obraz na PDF
home.imageToPdf.desc=Konwertuj obraz (PNG, JPEG, GIF) do dokumentu PDF.
imageToPdf.tags=konwersja,img,jpg,obraz,zdjęcie
imageToPdf.tags=conversion,img,jpg,picture,photo
home.pdfToImage.title=PDF na Obraz
home.pdfToImage.desc=Konwertuj plik PDF na obraz (PNG, JPEG, GIF).
pdfToImage.tags=konwersja,img,jpg,obraz,zdjęcie
pdfToImage.tags=conversion,img,jpg,picture,photo
home.pdfOrganiser.title=Uporządkuj
home.pdfOrganiser.desc=Usuń/Zmień kolejność stron w dowolnej kolejności
pdfOrganiser.tags=duplex,parzyste,nieparzyste,sortuj,przenieś
pdfOrganiser.tags=duplex,even,odd,sort,move
home.addImage.title=Dodaj obraz
home.addImage.desc=Dodaje obraz w wybranym miejscu w dokumencie PDF
addImage.tags=img,jpg,obraz,zdjęcie
addImage.tags=img,jpg,picture,photo
home.watermark.title=Dodaj znak wodny
home.watermark.desc=Dodaj niestandardowy znak wodny do dokumentu PDF.
watermark.tags=Tekst,powtarzanie,etykieta,własne,prawa autorskie,znak wodny,img,jpg,obraz,zdjęcie
watermark.tags=Text,repeating,label,own,copyright,trademark,img,jpg,picture,photo
home.permissions.title=Zmień uprawnienia
home.permissions.desc=Zmień uprawnienia dokumentu PDF
permissions.tags=odczyt,zapis,edycja,drukowanie
permissions.tags=read,write,edit,print
home.removePages.title=Usuń
home.removePages.desc=Usuń niechciane strony z dokumentu PDF.
removePages.tags=Usuń strony,usuwaj strony
removePages.tags=Remove pages,delete pages
home.addPassword.title=Dodaj hasło
home.addPassword.desc=Zaszyfruj dokument PDF za pomocą hasła.
addPassword.tags=bezpieczeństwo,ochrona
addPassword.tags=secure,security
home.removePassword.title=Usuń hasło
home.removePassword.desc=Usuń ochronę hasłem z dokumentu PDF.
removePassword.tags=zabezpieczenie,odszyfrowanie,bezpieczeństwo,odhasłowanie,usunięcie hasła
removePassword.tags=secure,Decrypt,security,unpassword,delete password
home.compressPdfs.title=Kompresuj
home.compressPdfs.desc=Kompresuj dokumenty PDF, aby zmniejszyć ich rozmiar.
compressPdfs.tags=zgniatać,mały,malutki
compressPdfs.tags=squish,small,tiny
home.changeMetadata.title=Zmień metadane
home.changeMetadata.desc=Zmień/Usuń/Dodaj metadane w dokumencie PDF
changeMetadata.tags=Tytuł,autor,data,utworzenie,czas,wydawca,producent,statystyki
changeMetadata.tags=Title,author,date,creation,time,publisher,producer,stats
home.fileToPDF.title=Konwertuj plik do PDF
home.fileToPDF.desc=Konwertuj dowolny plik do dokumentu PDF (DOCX, PNG, XLS, PPT, TXT i więcej)
fileToPDF.tags=transformacja,format,dokument,obraz,slajd,tekst,konwersja,office,dokumenty,word,excel,powerpoint
fileToPDF.tags=transformation,format,document,picture,slide,text,conversion,office,docs,word,excel,powerpoint
home.ocr.title=OCR / Zamiana na tekst
home.ocr.desc=OCR skanuje i wykrywa tekst z obrazów w dokumencie PDF i zamienia go na tekst.
ocr.tags=rozpoznawanie, tekst, obraz, skanowanie, odczyt, identyfikacja, wykrywanie, edytowalność
ocr.tags=recognition,text,image,scan,read,identify,detection,editable
home.extractImages.title=Wyodrębnij obrazy
home.extractImages.desc=Wyodrębnia wszystkie obrazy z dokumentu PDF i zapisuje je w wybranym formacie
extractImages.tags=obraz, zdjęcie, zapisz, archiwum, zip, przechwyć, złap
extractImages.tags=picture,photo,save,archive,zip,capture,grab
home.pdfToPDFA.title=PDF na PDF/A
home.pdfToPDFA.desc=Konwertuj dokument PDF na PDF/A w celu długoterminowego przechowywania
pdfToPDFA.tags=archiwum, długoterminowe, standardowe, konwersja, przechowywanie, konserwacja
pdfToPDFA.tags=archive,long-term,standard,conversion,storage,preservation
home.PDFToWord.title=PDF na Word
home.PDFToWord.desc=Konwertuj dokument PDF na formaty Word (DOC, DOCX i ODT)
PDFToWord.tags=doc,docx,odt,word, przekształcenie, transformacja, konwersja, office, microsoft, plik doc
PDFToWord.tags=doc,docx,odt,word,transformation,format,conversion,office,microsoft,docfile
home.PDFToPresentation.title=PDF na Prezentację
home.PDFToPresentation.desc=Konwertuj dokument PDF na formaty prezentacji (PPT, PPTX i ODP)
PDFToPresentation.tags=slajdy, pokaz, office, microsoft
PDFToPresentation.tags=slides,show,office,microsoft
home.PDFToText.title=PDF na Tekst/RTF
home.PDFToText.desc=Konwertuj dokument PDF na tekst lub format RTF
PDFToText.tags=format tekstu sformatowanego,rtf format
PDFToText.tags=richformat,richtextformat,rich text format
home.PDFToHTML.title=PDF na HTML
home.PDFToHTML.desc=Konwertuj dokument PDF na format HTML
PDFToHTML.tags=zawartość internetowa, przyjazne dla przeglądarek
PDFToHTML.tags=web content,browser friendly
home.PDFToXML.title=PDF na XML
home.PDFToXML.desc=Konwertuj dokument PDF na format XML
PDFToXML.tags=ekstrakcja danych, zawartość strukturalna, współdziałanie, transformacja, konwertowanie
PDFToXML.tags=data-extraction,structured-content,interop,transformation,convert
home.ScannerImageSplit.title=Wykryj/Podziel zeskanowane zdjęcia
home.ScannerImageSplit.desc=Podziel na wiele zdjęć z jednego zdjęcia/PDF
ScannerImageSplit.tags=oddzielne, automatyczne wykrywanie, skanowanie, wiele zdjęć, porządkowanie
ScannerImageSplit.tags=separate,auto-detect,scans,multi-photo,organize
home.sign.title=Podpis
home.sign.desc=Dodaje podpis do dokumentu PDF za pomocą rysunku, tekstu lub obrazu
sign.tags=autoryzacja, inicjały, podpis odręczny, podpis tekstowy, podpis graficzny
sign.tags=authorize,initials,drawn-signature,text-sign,image-signature
home.flatten.title=Spłaszcz
home.flatten.desc=Usuń wszystkie interaktywne elementy i formularze z dokumentu PDF
flatten.tags=statyczny, dezaktywacja, nieinteraktywny, opływowy, streamline
flatten.tags=static,deactivate,non-interactive,streamline
home.repair.title=Napraw
home.repair.desc=Spróbuj naprawić uszkodzony dokument PDF
repair.tags=naprawianie, naprawa, przywracanie, poprawianie, odzyskiwanie
repair.tags=fix,restore,correction,recover
home.removeBlanks.title=Usuń puste strony
home.removeBlanks.desc=Wykrywa i usuwa puste strony z dokumentu PDF
removeBlanks.tags=czyszczenie, usprawnianie, brak treści, organizowanie
removeBlanks.tags=cleanup,streamline,non-content,organize
home.removeAnnotations.title=Usuń notatki/przypisy
home.removeAnnotations.desc=Usuwa wszystkie notatki i przypisy z dokumentu PDF
removeAnnotations.tags=komentarze, podświetlanie, notatki, znaczniki, usuwanie
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=rozróżnienie, kontrast, zmiany, analiza
compare.tags=differentiate,contrast,changes,analysis
home.certSign.title=Podpisz certyfikatem
home.certSign.desc=Podpisz dokument PDF za pomocą certyfikatu/klucza prywatnego (PEM/P12)
certSign.tags=uwierzytelnianie, PEM, P12, oficjalny, szyfrowanie
certSign.tags=authenticate,PEM,P12,official,encrypt
home.removeCertSign.title=Usuń podpis certyfikatem
home.removeCertSign.desc=Usuń podpis certyfikatem z dokumentu PDF
removeCertSign.tags=uwierzytelnianie, PEM, P12, oficjalny, odszyfrowywanie
removeCertSign.tags=authenticate,PEM,P12,official,decrypt
home.pageLayout.title=Układ wielu stron
home.pageLayout.desc=Scal wiele stron dokumentu PDF w jedną stronę
pageLayout.tags=scalanie, kompozycja, pojedynczy widok, organizowanie, porządkowanie
pageLayout.tags=merge,composite,single-view,organize
home.scalePages.title=Dopasuj rozmiar stron
home.scalePages.desc=Dopasuj rozmiar stron wybranego dokumentu PDF
scalePages.tags=zmiana rozmiaru, modyfikacja, rozmiar, dostosowanie
scalePages.tags=resize,modify,dimension,adapt
home.pipeline.title=Automatyzacja
home.pipeline.desc=Wykonaj wiele akcji na dokumentach PDF, tworząc automatyzację
pipeline.tags=automatyzacja, sekwencja, skrypt, przetwarzanie wsadowe
pipeline.tags=automate,sequence,scripted,batch-process
home.add-page-numbers.title=Dodaj numery stron
home.add-page-numbers.desc=Dodaj numery strony w dokumencie PDF w podanej lokalizacji
add-page-numbers.tags=stronicowanie, etykieta, organizowanie, indeks, index
add-page-numbers.tags=paginate,label,organize,index
home.auto-rename.title=Automatycznie zmień nazwę PDF
home.auto-rename.desc=Automatycznie zmień nazwę PDF bazując na nagłówku
auto-rename.tags=automatyczne wykrywanie, oparte na nagłówkach, organizowanie, ponowne etykietowanie
auto-rename.tags=auto-detect,header-based,organize,relabel
home.adjust-contrast.title=Zmień kolor/nasycenie/jasność
home.adjust-contrast.desc=Zmień kolor/nasycenie/jasność w dokumencie PDF
adjust-contrast.tags=Korekcja kolorów, dostrajanie, modyfikacja, ulepszanie
adjust-contrast.tags=color-correction,tune,modify,enhance
home.crop.title=Przytnij PDF
home.crop.desc=Przytnij dokument PDF w celu zmniejszenia rozmiaru
crop.tags=przycinanie, zmniejszanie, edycja, kształtowanie
crop.tags=trim,shrink,edit,shape
home.autoSplitPDF.title=Automatycznie podziel strony
home.autoSplitPDF.desc=Automatycznie podziel dokument na strony
autoSplitPDF.tags=Oparty na QR, rozdzielanie, skanowanie, organizowanie
autoSplitPDF.tags=QR-based,separate,scan-segment,organize
home.sanitizePdf.title=Dezynfekcja
home.sanitizePdf.desc=Usuń skrypt i inne elementy z dokumentu PDF
sanitizePdf.tags=czyszczenie, ochrona, bezpieczeństwo, usuwanie zagrożeń
sanitizePdf.tags=clean,secure,safe,remove-threats
home.URLToPDF.title=Strona WWW do PDFa
home.URLToPDF.desc=Zapisuje podany adres WWW do PDFa
URLToPDF.tags=przechwytywanie stron internetowych, zapisywanie strony, strona internetowa do dokumentu, archiwizacja
URLToPDF.tags=web-capture,save-page,web-to-doc,archive
home.HTMLToPDF.title=HTML do PDF
home.HTMLToPDF.desc=Zapisuje podany plik HTML/ZIP do PDF
HTMLToPDF.tags=znaczniki, treść internetowa, transformacja, konwertowanie
HTMLToPDF.tags=markup,web-content,transformation,convert
home.MarkdownToPDF.title=Markdown do PDF
home.MarkdownToPDF.desc=Zapisuje dokument Markdown do PDF
MarkdownToPDF.tags=znaczniki, treść internetowa, transformacja, konwertowanie
MarkdownToPDF.tags=markup,web-content,transformation,convert
home.getPdfInfo.title=Pobierz informacje o pliku PDF
home.getPdfInfo.desc=Pobiera wszelkie informacje o pliku PDF
getPdfInfo.tags=informacje, dane, statystyka, statystyki
getPdfInfo.tags=infomation,data,stats,statistics
home.extractPage.title=Wyciągnij stronę z PDF
home.extractPage.desc=Wyciąga stronę z dokumentu PDF
extractPage.tags=wydobycie,separacja,wyciaganie
extractPage.tags=extract
home.PdfToSinglePage.title=PDF do jednej strony
home.PdfToSinglePage.desc=Łączy wszystkie strony PDFa w jedną wielką stronę PDF
PdfToSinglePage.tags=pojedyncza strona
PdfToSinglePage.tags=single page
home.showJS.title=Pokaż kod JavaScript
@@ -465,66 +465,66 @@ showJS.tags=JS
home.autoRedact.title=Zaciemnij
home.autoRedact.desc=Zaciemnia dokument PDF bazując na podanej wartości
autoRedact.tags=Redagowanie, ukrywanie, zaciemnianie, zaczernianie, zaznaczanie, ukrywanie
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
home.tableExtraxt.title=PDF do CSV
home.tableExtraxt.desc=Konwertuje tabele z PDF do pliku CSV
tableExtraxt.tags=CSV, ekstrakcja tabeli, ekstrakcja, konwersja, wydobywanie
tableExtraxt.tags=CSV,Table Extraction,extract,convert
home.autoSizeSplitPDF.title=Podziel (Rozmiar/Ilość stron)
home.autoSizeSplitPDF.desc=Rozdziela dokument PDF na wiele dokumentów bazując na podanym rozmiarze, ilości stron bądź ilości dokumentów
autoSizeSplitPDF.tags=pdf, dzielenie, dokument, organizacja
autoSizeSplitPDF.tags=pdf,split,document,organization
home.overlay-pdfs.title=Nałóż PDFa
home.overlay-pdfs.desc=Nakłada dokumenty PDF na siebie
overlay-pdfs.tags=Nakładka
overlay-pdfs.tags=Overlay
home.split-by-sections.title=Podziel PDF na sekcje
home.split-by-sections.desc=Podziel strony PDF w mniejsze sekcje
split-by-sections.tags=Podział sekcji, dzielenie, dostosowywanie
split-by-sections.tags=Section Split, Divide, Customize
home.AddStampRequest.title=Dodaj pieczęć
home.AddStampRequest.desc=Dodaj pieczęć tekstową/obrazową w wyznaczonej lokalizacji dokumentu
AddStampRequest.tags=Stempel, dodawanie obrazu, wyśrodkowanie obrazu, znak wodny, PDF, osadzanie, dostosowywanie
AddStampRequest.tags=Stamp, Add image, center image, Watermark, PDF, Embed, Customize
home.PDFToBook.title=PDF do eBooka
home.PDFToBook.desc=Zapisuje dokument PDF w formacie eBooka za pomocą Calibre
PDFToBook.tags=Książka,komiks,Calibre, konwertowanie, manga, amazon, kindle
PDFToBook.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.BookToPDF.title=eBook do PDF
home.BookToPDF.desc=Zapisuje ebooka do PDF za pomocą Calibre
BookToPDF.tags=Book,Comic,Calibre,Convert,manga,amazon,kindle
home.removeImagePdf.title=Usuń obraz
home.removeImagePdf.desc=Usuń obraz z pliku PDF, aby zmniejszyć rozmiar pliku
removeImagePdf.tags=Usuń obraz, operacje na stronie, back-end, strona serwera
home.removeImagePdf.title=Remove image
home.removeImagePdf.desc=Remove image from PDF to reduce file size
removeImagePdf.tags=Remove Image,Page operations,Back end,server side
home.splitPdfByChapters.title=Podziel PDF według rozdziałów
home.splitPdfByChapters.desc=Podział pliku PDF na wiele plików na podstawie struktury rozdziałów.
splitPdfByChapters.tags=podział, rozdziały, zakładki, porządkowanie, organizacja
home.splitPdfByChapters.title=Split PDF by Chapters
home.splitPdfByChapters.desc=Split a PDF into multiple files based on its chapter structure.
splitPdfByChapters.tags=split,chapters,bookmarks,organize
#replace-invert-color
replace-color.title=Zamień-Odwróć-Kolor
replace-color.header=Zamień-Odwróć kolor PDF
home.replaceColorPdf.title=Zastąp i Odwróć Kolor
home.replaceColorPdf.desc=Zastąp kolor tekstu i tła w pliku PDF i odwróć pełen kolor pliku PDF, aby zmniejszyć rozmiar pliku
replaceColorPdf.tags=Zastąp kolor, operacje na stronach, back-end, strona serwera
replace-color.selectText.1=Zastąp lub Odwróć opcje kolorów
replace-color.selectText.2=Domyślnie (domyślne kolory o wysokim kontraście)
replace-color.selectText.3=Niestandardowe (kolory niestandardowe)
replace-color.selectText.4=Całkowita-Odwrotność (Odwrócenie wszystkich kolorów)
replace-color.selectText.5=Wysoki kontrast opcji kolorystycznych
replace-color.selectText.6=biały tekst na czarnym tle
replace-color.selectText.7=Czarny tekst na białym tle
replace-color.selectText.8=Żółty tekst na czarnym tle
replace-color.selectText.9=Zielony tekst na czarnym tle
replace-color.selectText.10=Wybierz Kolor tekstu
replace-color.selectText.11=Wybierz Kolor tła
replace-color.submit=Zamień
replace-color.title=Replace-Invert-Color
replace-color.header=Replace-Invert Color PDF
home.replaceColorPdf.title=Replace and Invert Color
home.replaceColorPdf.desc=Replace color for text and background in PDF and invert full color of pdf to reduce file size
replaceColorPdf.tags=Replace Color,Page operations,Back end,server side
replace-color.selectText.1=Replace or Invert color Options
replace-color.selectText.2=Default(Default high contrast colors)
replace-color.selectText.3=Custom(Customized colors)
replace-color.selectText.4=Full-Invert(Invert all colors)
replace-color.selectText.5=High contrast color options
replace-color.selectText.6=white text on black background
replace-color.selectText.7=Black text on white background
replace-color.selectText.8=Yellow text on black background
replace-color.selectText.9=Green text on black background
replace-color.selectText.10=Choose text Color
replace-color.selectText.11=Choose background Color
replace-color.submit=Replace
@@ -543,17 +543,18 @@ login.locked=Konto jest zablokowane
login.signinTitle=Zaloguj się
login.ssoSignIn=Zaloguj się za pomocą logowania jednokrotnego
login.oauth2AutoCreateDisabled=Wyłączono automatyczne tworzenie użytkownika OAUTH2
login.oauth2AdminBlockedUser=Rejestracja lub logowanie niezarejestrowanych użytkowników jest obecnie zablokowane. Prosimy o kontakt z administratorem.
login.oauth2AdminBlockedUser=Registration or logging in of non-registered users is currently blocked. Please contact the administrator.
login.oauth2RequestNotFound=Błąd logowania OAuth2
login.oauth2InvalidUserInfoResponse=Niewłaściwe dane logowania
login.oauth2invalidRequest=Nieprawidłowe żądanie
login.oauth2AccessDenied=Brak dostępu
login.oauth2InvalidTokenResponse=Nieprawidłowa odpowiedź na token
login.oauth2InvalidIdToken=Nieprawidłowa wartość tokenu
login.userIsDisabled=Użytkownik jest nieaktywny, logowanie przy użyciu tej nazwy użytkownika jest obecnie zablokowane. Prosimy o kontakt z administratorem.
login.alreadyLoggedIn=Jesteś już zalogowany na
login.alreadyLoggedIn2=urządzeniach. Wyloguj się z tych urządzeń i spróbuj ponownie.
login.toManySessions=Masz zbyt wiele aktywnych sesji
login.userIsDisabled=User is deactivated, login is currently blocked with this username. Please contact the administrator.
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Automatyczne zaciemnienie
@@ -777,8 +778,8 @@ removeAnnotations.submit=Usuń
#compare
compare.title=Porównaj
compare.header=Porównaj PDF(y)
compare.highlightColor.1=Kolor Podświetlenia 1:
compare.highlightColor.2=Kolor Podświetlenia 2:
compare.highlightColor.1=Highlight Color 1:
compare.highlightColor.2=Highlight Color 2:
compare.document.1=Dokument 1
compare.document.2=Dokument 2
compare.submit=Porównaj
@@ -830,7 +831,7 @@ ScannerImageSplit.selectText.7=Minimalny obszar konturu:
ScannerImageSplit.selectText.8=Ustawia próg minimalnego obszaru konturu dla zdjęcia
ScannerImageSplit.selectText.9=Rozmiar obramowania:
ScannerImageSplit.selectText.10=Ustawia rozmiar dodawanego i usuwanego obramowania, aby uniknąć białych obramowań na wyjściu (domyślnie: 1).
ScannerImageSplit.info=Python nie został zainstalowany. Jest on wymagany do uruchomienia.
ScannerImageSplit.info=Python is not installed. It is required to run.
#OCR
@@ -857,7 +858,7 @@ ocr.submit=Przetwarzaj PDF za pomocą OCR
extractImages.title=Wyodrębnij obrazy
extractImages.header=Wyodrębnij obrazy
extractImages.selectText=Wybierz format obrazu, na który chcesz przekonwertować wyodrębniony obraz.
extractImages.allowDuplicates=Zapisz zduplikowane obrazy
extractImages.allowDuplicates=Save duplicate images
extractImages.submit=Wyodrębnij
@@ -918,8 +919,8 @@ pdfOrganiser.placeholder=(przykład 1,3,2 lub 4-8,2,10-12 lub 2n-1)
#multiTool
multiTool.title=Narzędzie Wielofunkcyjne PDF
multiTool.header=Narzędzie Wielofunkcyjne PDF
multiTool.title=Multi narzędzie PDF
multiTool.header=Multi narzędzie PDF
multiTool.uploadPrompts=Nazwa pliku
#view pdf
@@ -982,7 +983,7 @@ pdfToImage.color=Kolor
pdfToImage.grey=Odcień szarości
pdfToImage.blackwhite=Czarno-biały (może spowodować utratę danych!)
pdfToImage.submit=Konwertuj
pdfToImage.info=Python nie został zainstalowany. Jest wymagany do konwersji WebP.
pdfToImage.info=Python is not installed. Required for WebP conversion.
#addPassword
@@ -1019,7 +1020,7 @@ watermark.selectText.6=Odstęp w pionie (odstęp między każdym znakiem wodnym
watermark.selectText.7=Nieprzezroczystość (0% - 100%):
watermark.selectText.8=Typ znaku wodnego:
watermark.selectText.9=Obraz znaku wodnego:
watermark.selectText.10=Konwertuj PDF do PDF-Image
watermark.selectText.10=Convert PDF to PDF-Image
watermark.submit=Dodaj znak wodny
watermark.type.1=Tekst
watermark.type.2=Obraz
@@ -1119,7 +1120,7 @@ PDFToXML.submit=Konwertuj
#PDFToCSV
PDFToCSV.title=PDF na CSV
PDFToCSV.header=PDF na CSV
PDFToCSV.prompt=Wybierz stronę do wyodrębnienia tabeli
PDFToCSV.prompt=Choose page to extract table
PDFToCSV.submit=Zatwierdź
#split-by-size-or-count
@@ -1181,8 +1182,8 @@ licenses.license=Licencja
survey.nav=Ankieta
survey.title=Ankieta Stirling-PDF
survey.description=Stirling-PDF nie śledzi swoich użytkowników, więc chciałby poznać opinie swoich użytkowników!
survey.changes=Stirling-PDF zmieniło się od czasu ostatniej ankiety! Aby dowiedzieć się więcej, sprawdź nasz wpis na blogu tutaj:
survey.changes2=Dzięki tym zmianom otrzymujemy płatne wsparcie biznesowe i finansowanie
survey.changes=Stirling-PDF has changed since the last survey! To find out more please check our blog post here:
survey.changes2=With these changes we are getting paid business support and funding
survey.please=Wypełnij proszę ankietę dla nas!
survey.disabled=(Blokada wyskakującego okienka z ankieta zostanie dodane w następnych aktualizacjach, ale będzie dostępna na dole strony)
survey.button=Wypełnij ankietę
@@ -1204,21 +1205,21 @@ error.discordSubmit=Discord - wyślij posta z prośbą o pomoc
#remove-image
removeImage.title=Usuń obraz
removeImage.header=Usuń obraz
removeImage.removeImage=Usuń obraz
removeImage.submit=Usuń obraz
removeImage.title=Remove image
removeImage.header=Remove image
removeImage.removeImage=Remove image
removeImage.submit=Remove image
splitByChapters.title=Podziel PDF według Rozdziałów
splitByChapters.header=Podziel PDF według Rozdziałów
splitByChapters.bookmarkLevel=Poziom Zakładek
splitByChapters.includeMetadata=Dołącz Metadane
splitByChapters.allowDuplicates=Zezwalaj na Duplikaty
splitByChapters.desc.1=Narzędzie to dzieli plik PDF na wiele plików PDF w oparciu o strukturę rozdziałów.
splitByChapters.desc.2=Poziom Zakładek: Wybierz poziom zakładek, który ma zostać użyty do podziału (0 dla najwyższego poziomu, 1 dla drugiego poziomu itd.).
splitByChapters.desc.3=Dołącz Metadane: Jeśli opcja ta jest zaznaczona, metadane oryginalnego pliku PDF zostaną uwzględnione w każdym rozdzielonych plików PDF.
splitByChapters.desc.4=Zezwól na Duplikaty: Jeśli ta opcja jest zaznaczona, pozwala na tworzenie oddzielnych plików PDF przez wiele zakładek na tej samej stronie.
splitByChapters.submit=Podziel PDF
splitByChapters.title=Split PDF by Chapters
splitByChapters.header=Split PDF by Chapters
splitByChapters.bookmarkLevel=Bookmark Level
splitByChapters.includeMetadata=Include Metadata
splitByChapters.allowDuplicates=Allow Duplicates
splitByChapters.desc.1=This tool splits a PDF file into multiple PDFs based on its chapter structure.
splitByChapters.desc.2=Bookmark Level: Choose the level of bookmarks to use for splitting (0 for top-level, 1 for second-level, etc.).
splitByChapters.desc.3=Include Metadata: If checked, the original PDF's metadata will be included in each split PDF.
splitByChapters.desc.4=Allow Duplicates: If checked, allows multiple bookmarks on the same page to create separate PDFs.
splitByChapters.submit=Split PDF

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=O usuário está desativado, o login está atualmente bloqu
login.alreadyLoggedIn=Você já está conectado
login.alreadyLoggedIn2=aparelhos. Por favor saia dos aparelhos e tente novamente.
login.toManySessions=Você tem muitas sessões ativas
login.toManySessions2=Por favor saida dos aparelhos e tente novamente. Alternativamente você pode adquirir Stirling PDF Pro.
#auto-redact
autoRedact.title=Redação Automática de Dados

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Edição Automática

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=Utilizatorul este dezactivat, conectarea este în prezent b
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Redactare Automată

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Автоматическое редактирование

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Automatické redigovanie

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Auto Cenzura

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=Användaren är inaktiverad, inloggning är för närvarand
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Auto-redigera

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=ซ่อนข้อมูลอัตโนมัติ

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=Kullanıcı devre dışı bırakıldı, şu anda bu kullan
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Otomatik Karartma

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Автоматичне редагування

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=User is deactivated, login is currently blocked with this u
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=Tự động biên tập

View File

@@ -554,6 +554,7 @@ login.userIsDisabled=用户被禁用,登录已被阻止。请联系管理员
login.alreadyLoggedIn=You are already logged in to
login.alreadyLoggedIn2=devices. Please log out of the devices and try again.
login.toManySessions=You have too many active sessions
login.toManySessions2=Please log out of the devices and try again. Alternatively, you can upgrade to Stirling PDF Pro.
#auto-redact
autoRedact.title=自动删除

View File

@@ -21,7 +21,7 @@ save=儲存
saveToBrowser=儲存到瀏覽器
close=關閉
filesSelected=已選擇的檔案
noFavourites=還沒有功能被收藏
noFavourites=未新增收藏
downloadComplete=下載完成
bored=等待時覺得無聊?
alphabet=字母表
@@ -90,7 +90,7 @@ legal.impressum=版本說明
# Pipeline #
###############
pipeline.header=管道功能選單(測試版)
pipeline.uploadButton=上傳自訂設定
pipeline.uploadButton=上傳自訂
pipeline.configureButton=設定
pipeline.defaultOption=自訂
pipeline.submitButton=送出
@@ -256,9 +256,9 @@ home.viewPdf.title=檢視 PDF
home.viewPdf.desc=檢視、註釋、新增文字或圖片
viewPdf.tags=檢視,閱讀,註釋,文字,圖片
home.multiTool.title=PDF 複合工具
home.multiTool.title=PDF 工具
home.multiTool.desc=合併、旋轉、重新排列和移除頁面
multiTool.tags=複合工具,多功能,UI,點選拖,前端,客戶端,互動,互動,移動
multiTool.tags=工具,多操作,UI,點選拖,前端,客戶端,互動,互動,移動
home.merge.title=合併
home.merge.desc=輕鬆將多個 PDF 合併為一個。
@@ -554,6 +554,7 @@ login.userIsDisabled=使用者已停用,目前此使用者無法登入。請
login.alreadyLoggedIn=您已經登入了
login.alreadyLoggedIn2=個裝置。請登出其他裝置後再試一次。
login.toManySessions=您有太多使用中的工作階段
login.toManySessions2=請登出其他裝置後再試一次。或者,您可以升級至 Stirling PDF 專業版。
#auto-redact
autoRedact.title=自動塗黑
@@ -839,8 +840,8 @@ ocr.header=清理掃描 / OCR光學字元識別
ocr.selectText.1=選擇要在 PDF 中偵測的語言(列出的是目前可以偵測的語言):
ocr.selectText.2=產生包含 OCR 文字的文字文件,並與 OCR 的 PDF 一起
ocr.selectText.3=修正掃描的頁面傾斜角度,將它們旋轉回原位
ocr.selectText.4=清理頁面以降低 OCR 在背景雜訊中識別文字的機率。(無輸出變化)
ocr.selectText.5=清理頁面以降低 OCR 在背景雜訊中識別文字的機率,保持乾淨的輸出。
ocr.selectText.4=清理頁面,使 OCR 不太可能在背景噪音中找到文字。(無輸出變化)
ocr.selectText.5=清理頁面,使 OCR 不太可能在背景噪音中找到文字,保持清理的輸出。
ocr.selectText.6=忽略具有互動文字的頁面,只對影像頁面進行 OCR
ocr.selectText.7=強制 OCR將對每一頁進行 OCR移除所有原始文字元素
ocr.selectText.8=正常(如果 PDF 包含文字將出錯)
@@ -857,7 +858,7 @@ ocr.submit=使用 OCR 處理 PDF
extractImages.title=提取圖片
extractImages.header=提取圖片
extractImages.selectText=選擇要轉換提取影像的影像格式
extractImages.allowDuplicates=儲存重複的圖片
extractImages.allowDuplicates=Save duplicate images
extractImages.submit=提取
@@ -875,10 +876,10 @@ compress.title=壓縮
compress.header=壓縮 PDF
compress.credit=此服務使用 Ghostscript 進行 PDF 壓縮/最佳化。
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.2=最佳化級
compress.selectText.3=4對於文字影像非常糟糕
compress.selectText.4=自動模式 - 自動調整品質使 PDF 達到確定大小
compress.selectText.5=預期的 PDF 大小(例如 25MB, 10.8MB, 25KB
compress.submit=壓縮
@@ -918,8 +919,8 @@ pdfOrganiser.placeholder=(例如 1,3,2 或 4-8,2,10-12 或 2n-1
#multiTool
multiTool.title=PDF 複合工具
multiTool.header=PDF 複合工具
multiTool.title=PDF 工具
multiTool.header=PDF 工具
multiTool.uploadPrompts=檔名
#view pdf

View File

@@ -12,7 +12,7 @@
security:
enableLogin: false # set to 'true' to enable login
enableLogin: true # set to 'true' to enable login
csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production)
loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1
loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
@@ -47,31 +47,33 @@ security:
useAsUsername: email # Default is 'email'; custom fields can be used as the username
scopes: openid, profile, email # Specify the scopes for which the application will request permissions
provider: google # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak'
saml2:
enabled: false # Currently in alpha, not recommended for use yet, enableAlphaFunctionality must be set to true
saml2:
enabled: true
autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users
blockRegistration: false # set to 'true' to deny login with SSO without prior registration by an admin
registrationId: stirling
idpMetadataUri: https://dev-XXXXXXXX.okta.com/app/externalKey/sso/saml/metadata
idpSingleLogoutUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/slo/saml
idpSingleLoginUrl: https://dev-XXXXXXXX.okta.com/app/dev-XXXXXXXX_stirlingpdf_1/externalKey/sso/saml
idpIssuer: http://www.okta.com/externalKey
idpCert: classpath:octa.crt
privateKey: classpath:saml-private-key.key
spCert: classpath:saml-public-cert.crt
entityId: 'spring-boot-app'
registrationId: 'keycloak'
idpMetadataUri: 'http://localhost:8080/realms/saml-sso/protocol/saml/descriptor'
idpSingleLogoutUrl: 'http://localhost:8080/realms/saml-sso/protocol/saml'
idpSingleLoginUrl: 'http://localhost:8080/realms/saml-sso/protocol/saml'
idpIssuer: 'http://localhost:8080/realms/saml-sso'
idpCert: 'classpath:saml-public-cert.crt'
privateKey: 'classpath:local.key'
spCert: 'classpath:local.crt'
# Enterprise edition settings unused for now please ignore!
enterpriseEdition:
enabled: false # set to 'true' to enable enterprise edition
key: 00000000-0000-0000-0000-000000000000
CustomMetadata:
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
author: username # Supports text such as 'John Doe' or types such as username to autopopulate with users username
autoUpdateMetadata: true # set to 'true' to automatically update metadata with below values
author: username # Supports text such as 'John Doe' or types such as username
creator: Stirling-PDF # Supports text such as 'Company-PDF'
producer: Stirling-PDF # Supports text such as 'Company-PDF'
legal:
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms) Empty string to disable or filename to load from local file in static folder
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy) Empty string to disable or filename to load from local file in static folder
termsAndConditions: '' # URL to the terms and conditions of your application (e.g. https://example.com/terms) Empty string to disable or filename to load from local file in static folder
privacyPolicy: '' # URL to the privacy policy of your application (e.g. https://example.com/privacy) Empty string to disable or filename to load from local file in static folder
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility) Empty string to disable or filename to load from local file in static folder
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie) Empty string to disable or filename to load from local file in static folder
impressum: '' # URL to the impressum of your application (e.g. https://example.com/impressum) Empty string to disable or filename to load from local file in static folder

View File

@@ -21,13 +21,6 @@
"moduleLicense": "The Apache Software License, Version 2.0",
"moduleLicenseUrl": "http://www.apache.org/licenses/LICENSE-2.0"
},
{
"moduleName": "com.coveo:saml-client",
"moduleUrl": "https://github.com/coveo/saml-client",
"moduleVersion": "5.0.0",
"moduleLicense": "MIT",
"moduleLicenseUrl": "https://opensource.org/licenses/MIT"
},
{
"moduleName": "com.fasterxml.jackson.core:jackson-annotations",
"moduleUrl": "https://github.com/FasterXML/jackson",
@@ -749,14 +742,14 @@
},
{
"moduleName": "org.commonmark:commonmark",
"moduleVersion": "0.24.0",
"moduleLicense": "BSD-2-Clause",
"moduleVersion": "0.23.0",
"moduleLicense": "BSD 2-Clause License",
"moduleLicenseUrl": "https://opensource.org/licenses/BSD-2-Clause"
},
{
"moduleName": "org.commonmark:commonmark-ext-gfm-tables",
"moduleVersion": "0.24.0",
"moduleLicense": "BSD-2-Clause",
"moduleVersion": "0.23.0",
"moduleLicense": "BSD 2-Clause License",
"moduleLicenseUrl": "https://opensource.org/licenses/BSD-2-Clause"
},
{
@@ -1405,7 +1398,7 @@
{
"moduleName": "org.springframework:spring-webmvc",
"moduleUrl": "https://github.com/spring-projects/spring-framework",
"moduleVersion": "6.1.14",
"moduleVersion": "6.1.13",
"moduleLicense": "Apache License, Version 2.0",
"moduleLicenseUrl": "https://www.apache.org/licenses/LICENSE-2.0"
},

View File

@@ -1,9 +1,7 @@
select#font-select,
select#font-select option {
height: 60px;
/* Adjust as needed */
font-size: 30px;
/* Adjust as needed */
height: 60px; /* Adjust as needed */
font-size: 30px; /* Adjust as needed */
}
.drawing-pad-container {
@@ -15,12 +13,10 @@ select#font-select option {
width: 100%;
height: 300px;
}
#box-drag-container {
position: relative;
margin: 20px 0;
}
.draggable-buttons-box {
position: absolute;
top: 0;
@@ -28,37 +24,16 @@ select#font-select option {
width: 100%;
display: flex;
gap: 5px;
z-index: 5;
}
.draggable-buttons-box>button {
z-index: 4;
.draggable-buttons-box > button {
z-index: 10;
background-color: rgba(13, 110, 253, 0.1);
}
.draggable-canvas {
border: 2px solid #3498db;
border: 1px solid red;
position: absolute;
touch-action: none;
user-select: none;
top: 0px;
left: 0;
z-index: 100;
cursor: grab;
transition: transform 0.1s ease-out;
background-color: rgba(52, 152, 219, 0.1);
/* Light blue background */
}
.draggable-canvas:active {
cursor: grabbing;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
/* Shadow on active drag */
}
.draggable-canvas:hover {
border: 2px solid #2980b9;
/* Darker border on hover */
background-color: rgba(52, 152, 219, 0.2);
/* Darken background on hover */
}

View File

@@ -1,36 +0,0 @@
const draggableElement = document.querySelector('.draggable-canvas');
// Variables to store the current position of the draggable element
let offsetX, offsetY, isDragging = false;
draggableElement.addEventListener('mousedown', (e) => {
// Get the offset when the mouse is clicked inside the element
offsetX = e.clientX - draggableElement.getBoundingClientRect().left;
offsetY = e.clientY - draggableElement.getBoundingClientRect().top;
// Set isDragging to true
isDragging = true;
// Add event listeners for mouse movement and release
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
});
function onMouseMove(e) {
if (isDragging) {
// Calculate the new position of the element
const left = e.clientX - offsetX;
const top = e.clientY - offsetY;
// Move the element by setting its style
draggableElement.style.left = `${left}px`;
draggableElement.style.top = `${top}px`;
}
}
function onMouseUp() {
// Stop dragging and remove event listeners
isDragging = false;
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
}

View File

@@ -0,0 +1,39 @@
const scrollDivHorizontally = (id) => {
var scrollDeltaX = 0; // variable to store the accumulated horizontal scroll delta
var scrollDeltaY = 0; // variable to store the accumulated vertical scroll delta
var isScrolling = false; // variable to track if scroll is already in progress
const divToScroll = document.getElementById(id);
function scrollLoop() {
// Scroll the div horizontally and vertically by a fraction of the accumulated scroll delta
divToScroll.scrollLeft += scrollDeltaX * 0.1;
divToScroll.scrollTop += scrollDeltaY * 0.1;
// Reduce the accumulated scroll delta by a fraction
scrollDeltaX *= 0.9;
scrollDeltaY *= 0.9;
// If scroll delta is still significant, continue the scroll loop
if (Math.abs(scrollDeltaX) > 0.1 || Math.abs(scrollDeltaY) > 0.1) {
requestAnimationFrame(scrollLoop);
} else {
isScrolling = false; // Reset scroll in progress flag
}
}
divToScroll.addEventListener("wheel", function (e) {
e.preventDefault(); // prevent default mousewheel behavior
// Accumulate the horizontal and vertical scroll delta
scrollDeltaX -= e.deltaX || e.wheelDeltaX || -e.deltaY || -e.wheelDeltaY;
scrollDeltaY -= e.deltaY || e.wheelDeltaY || -e.deltaX || -e.wheelDeltaX;
// If scroll is not already in progress, start the scroll loop
if (!isScrolling) {
isScrolling = true;
requestAnimationFrame(scrollLoop);
}
});
};
export default scrollDivHorizontally;

View File

@@ -360,7 +360,7 @@
</div>
</li>
<li class="nav-item" th:if="${!@runningEE}">
<li class="nav-item">
<a href="https://stirlingpdf.com/pricing" class="nav-link go-pro-link" target="_blank" rel="noopener noreferrer">
<span class="go-pro-badge" th:text="#{enterpriseEdition.button}"></span>
</a>

View File

@@ -374,10 +374,10 @@
<p th:text="#{analytics.paragraph2}">Please consider enabling analytics to help Stirling-PDF grow and to allow us to understand our users better.</p>
<p th:text="#{analytics.settings}">You can change the settings for analytics in the config/settings.yml file</p>
</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" onclick="setAnalytics(false)" th:text="#{analytics.disable}">Disable analytics</button>
<button type="button" class="btn btn-primary" th:text="#{analytics.enable}" onclick="setAnalytics(true)">Enable analytics</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" th:text="#{analytics.enable}" onclick="setAnalytics(true)">Enable analytics</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" onclick="setAnalytics(false)" th:text="#{analytics.disable}">Disable analytics</button>
</div>
</div>
</div>
</div>
@@ -426,60 +426,50 @@
document.addEventListener("DOMContentLoaded", function() {
const surveyVersion = "2.0";
const modal = new bootstrap.Modal(document.getElementById('surveyModal'));
const dontShowAgain = document.getElementById('dontShowAgain');
const takeSurveyButton = document.getElementById('takeSurvey');
document.addEventListener("DOMContentLoaded", function() {
const surveyVersion = "2.0";
const modal = new bootstrap.Modal(document.getElementById('surveyModal'));
const dontShowAgain = document.getElementById('dontShowAgain');
const takeSurveyButton = document.getElementById('takeSurvey');
const viewThresholds = [5, 10, 15, 22, 30, 50, 75, 100, 150, 200];
const viewThresholds = [5, 15, 30, 50, 75, 100, 150, 200];
let pageViews = parseInt(localStorage.getItem('pageViews') || '0');
// Check if survey version changed and reset page views if it did
const storedVersion = localStorage.getItem('surveyVersion');
if (storedVersion && storedVersion !== surveyVersion) {
localStorage.setItem('pageViews', '0');
}
pageViews++;
localStorage.setItem('pageViews', pageViews.toString());
let pageViews = parseInt(localStorage.getItem('pageViews') || '0');
pageViews++;
localStorage.setItem('pageViews', pageViews.toString());
function shouldShowSurvey() {
if (localStorage.getItem('dontShowSurvey') === 'true' ||
localStorage.getItem('surveyTaken') === 'true') {
return false;
function shouldShowSurvey() {
if (localStorage.getItem('dontShowSurvey') === 'true' || localStorage.getItem('surveyTaken') === 'true') {
return false;
}
// If survey version changed and we hit a threshold, show the survey
if (localStorage.getItem('surveyVersion') !== surveyVersion &&
viewThresholds.includes(pageViews)) {
return true;
if (localStorage.getItem('surveyVersion') !== surveyVersion) {
return true;
}
return viewThresholds.includes(pageViews);
}
}
if (shouldShowSurvey()) {
if (shouldShowSurvey()) {
modal.show();
}
}
dontShowAgain.addEventListener('change', function() {
dontShowAgain.addEventListener('change', function() {
if (this.checked) {
localStorage.setItem('dontShowSurvey', 'true');
localStorage.setItem('surveyVersion', surveyVersion);
localStorage.setItem('dontShowSurvey', 'true');
localStorage.setItem('surveyVersion', surveyVersion);
} else {
localStorage.removeItem('dontShowSurvey');
localStorage.removeItem('surveyVersion');
localStorage.removeItem('dontShowSurvey');
localStorage.removeItem('surveyVersion');
}
});
});
takeSurveyButton.addEventListener('click', function() {
takeSurveyButton.addEventListener('click', function() {
localStorage.setItem('surveyTaken', 'true');
localStorage.setItem('surveyVersion', surveyVersion);
modal.hide();
});
});
});
</script>

View File

@@ -80,6 +80,7 @@
<script type="module">
import PdfContainer from './js/multitool/PdfContainer.js';
import DragDropManager from "./js/multitool/DragDropManager.js";
import scrollDivHorizontally from "./js/multitool/horizontalScroll.js";
import ImageHighlighter from "./js/multitool/ImageHighlighter.js";
import PdfActionsManager from './js/multitool/PdfActionsManager.js';
import FileDragManager from './js/multitool/fileInput.js';
@@ -92,6 +93,7 @@
const fileDragManager = new FileDragManager();
// Scroll the wrapper horizontally
scrollDivHorizontally('pages-container-wrapper');
// Automatically exposes rotateAll, addFiles and exportPdf to the window for the global buttons.
const pdfContainer = new PdfContainer(
@@ -109,4 +111,4 @@
</script>
</body>
</html>
</html>

View File

@@ -1,11 +1,8 @@
<!DOCTYPE html>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}"
xmlns:th="https://www.thymeleaf.org">
<head>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{sign.title}, header=#{sign.header})}"></th:block>
<link rel="stylesheet" th:href="@{'/css/sign.css'}">
<link rel="stylesheet" th:href="@{'/css/sign.css'}">
<th:block th:each="font : ${fonts}">
<style th:inline="text">
@font-face {
@@ -14,266 +11,268 @@
}
#font-select option[value="[[${font.name}]]"] {
font-family: "[[${font.name}]]",
cursive;
font-family: "[[${font.name}]]", cursive;
}
#font-select option[value='/*[[${font.name}]]*/'] {
font-family: '/*[[${font.name}]]*/', cursive;
}
</style>
</th:block>
<script th:src="@{'/js/thirdParty/signature_pad.umd.min.js'}"></script>
<script th:src="@{'/js/thirdParty/interact.min.js'}"></script>
</head>
<script th:src="@{'/js/thirdParty/signature_pad.umd.min.js'}"></script>
<script th:src="@{'/js/thirdParty/interact.min.js'}"></script>
</head>
<body>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon sign">signature</span>
<span class="tool-header-text" th:text="#{sign.header}"></span>
</div>
<body>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon sign">signature</span>
<span class="tool-header-text" th:text="#{sign.header}"></span>
</div>
<!-- pdf selector -->
<div th:replace="~{fragments/common :: fileSelector(name='pdf-upload', multipleInputsForSingleRequest=false, disableMultipleFiles=true, accept='application/pdf')}"></div>
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
<script>
let originalFileName = '';
document.querySelector('input[name=pdf-upload]').addEventListener('change', async (event) => {
const file = event.target.files[0];
if (file) {
originalFileName = file.name.replace(/\.[^/.]+$/, "");
const pdfData = await file.arrayBuffer();
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs'
const pdfDoc = await pdfjsLib.getDocument({ data: pdfData }).promise;
await DraggableUtils.renderPage(pdfDoc, 0);
<!-- pdf selector -->
<div
th:replace="~{fragments/common :: fileSelector(name='pdf-upload', multipleInputsForSingleRequest=false, disableMultipleFiles=true, accept='application/pdf')}">
</div>
<script type="module" th:src="@{'/pdfjs-legacy/pdf.mjs'}"></script>
<script>
let originalFileName = '';
document.querySelector('input[name=pdf-upload]').addEventListener('change', async (event) => {
const file = event.target.files[0];
if (file) {
originalFileName = file.name.replace(/\.[^/.]+$/, "");
const pdfData = await file.arrayBuffer();
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs-legacy/pdf.worker.mjs';
const pdfDoc = await pdfjsLib.getDocument({ data: pdfData }).promise;
await DraggableUtils.renderPage(pdfDoc, 0);
document.querySelectorAll(".show-on-file-selected").forEach(el => {
el.style.cssText = '';
});
}
});
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".show-on-file-selected").forEach(el => {
el.style.cssText = "display:none !important";
document.querySelectorAll(".show-on-file-selected").forEach(el => {
el.style.cssText = '';
})
}
});
});
</script>
<div class="tab-group show-on-file-selected">
<div class="tab-container" th:title="#{sign.upload}">
<div
th:replace="~{fragments/common :: fileSelector(name='image-upload', multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}">
</div>
<script>
const imageUpload = document.querySelector('input[name=image-upload]');
imageUpload.addEventListener('change', e => {
if (!e.target.files) return;
for (const imageFile of e.target.files) {
var reader = new FileReader();
reader.readAsDataURL(imageFile);
reader.onloadend = function (e) {
DraggableUtils.createDraggableCanvasFromUrl(e.target.result);
};
}
});
</script>
</div>
<div class="tab-container drawing-pad-container" th:title="#{sign.draw}">
<canvas id="drawing-pad-canvas"></canvas>
<br>
<button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()"
th:text="#{sign.clear}"></button>
<button id="save-signature" class="btn btn-outline-success mt-2" onclick="addDraggableFromPad()"
th:text="#{sign.add}"></button>
<script>
const signaturePadCanvas = document.getElementById('drawing-pad-canvas');
const signaturePad = new SignaturePad(signaturePadCanvas, {
minWidth: 1,
maxWidth: 2,
penColor: 'black',
});
function addDraggableFromPad() {
if (signaturePad.isEmpty()) return;
const startTime = Date.now();
const croppedDataUrl = getCroppedCanvasDataUrl(signaturePadCanvas);
console.log(Date.now() - startTime);
DraggableUtils.createDraggableCanvasFromUrl(croppedDataUrl);
}
function getCroppedCanvasDataUrl(canvas) {
let originalCtx = canvas.getContext('2d');
let originalWidth = canvas.width;
let originalHeight = canvas.height;
let imageData = originalCtx.getImageData(0, 0, originalWidth, originalHeight);
let minX = originalWidth + 1, maxX = -1, minY = originalHeight + 1, maxY = -1, x = 0, y = 0, currentPixelColorValueIndex;
for (y = 0; y < originalHeight; y++) {
for (x = 0; x < originalWidth; x++) {
currentPixelColorValueIndex = (y * originalWidth + x) * 4;
let currentPixelAlphaValue = imageData.data[currentPixelColorValueIndex + 3];
if (currentPixelAlphaValue > 0) {
if (minX > x) minX = x;
if (maxX < x) maxX = x;
if (minY > y) minY = y;
if (maxY < y) maxY = y;
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll(".show-on-file-selected").forEach(el => {
el.style.cssText = "display:none !important";
})
});
</script>
<div class="tab-group show-on-file-selected">
<div class="tab-container" th:title="#{sign.upload}">
<div th:replace="~{fragments/common :: fileSelector(name='image-upload', multipleInputsForSingleRequest=true, accept='image/*', inputText=#{imgPrompt})}"></div>
<script>
const imageUpload = document.querySelector('input[name=image-upload]');
imageUpload.addEventListener('change', e => {
if(!e.target.files) {
return;
}
for (const imageFile of e.target.files) {
var reader = new FileReader();
reader.readAsDataURL(imageFile);
reader.onloadend = function (e) {
DraggableUtils.createDraggableCanvasFromUrl(e.target.result);
};
}
});
</script>
</div>
<div class="tab-container drawing-pad-container" th:title="#{sign.draw}">
<canvas id="drawing-pad-canvas"></canvas>
<br>
<button id="clear-signature" class="btn btn-outline-danger mt-2" onclick="signaturePad.clear()" th:text="#{sign.clear}"></button>
<button id="save-signature" class="btn btn-outline-success mt-2" onclick="addDraggableFromPad()" th:text="#{sign.add}"></button>
<script>
const signaturePadCanvas = document.getElementById('drawing-pad-canvas');
const signaturePad = new SignaturePad(signaturePadCanvas, {
minWidth: 1,
maxWidth: 2,
penColor: 'black',
});
function addDraggableFromPad() {
if (signaturePad.isEmpty()) return;
const startTime = Date.now();
const croppedDataUrl = getCroppedCanvasDataUrl(signaturePadCanvas)
console.log(Date.now() - startTime);
DraggableUtils.createDraggableCanvasFromUrl(croppedDataUrl);
}
}
function getCroppedCanvasDataUrl(canvas) {
// code is from: https://github.com/szimek/signature_pad/issues/49#issuecomment-1104035775
let originalCtx = canvas.getContext('2d');
let croppedWidth = maxX - minX;
let croppedHeight = maxY - minY;
if (croppedWidth < 0 || croppedHeight < 0) return null;
let cuttedImageData = originalCtx.getImageData(minX, minY, croppedWidth, croppedHeight);
let originalWidth = canvas.width;
let originalHeight = canvas.height;
let imageData = originalCtx.getImageData(0,0, originalWidth, originalHeight);
let croppedCanvas = document.createElement('canvas'),
croppedCtx = croppedCanvas.getContext('2d');
let minX = originalWidth + 1, maxX = -1, minY = originalHeight + 1, maxY = -1, x = 0, y = 0, currentPixelColorValueIndex;
croppedCanvas.width = croppedWidth;
croppedCanvas.height = croppedHeight;
croppedCtx.putImageData(cuttedImageData, 0, 0);
for (y = 0; y < originalHeight; y++) {
for (x = 0; x < originalWidth; x++) {
currentPixelColorValueIndex = (y * originalWidth + x) * 4;
let currentPixelAlphaValue = imageData.data[currentPixelColorValueIndex + 3];
if (currentPixelAlphaValue > 0) {
if (minX > x) minX = x;
if (maxX < x) maxX = x;
if (minY > y) minY = y;
if (maxY < y) maxY = y;
}
}
}
return croppedCanvas.toDataURL();
}
let croppedWidth = maxX - minX;
let croppedHeight = maxY - minY;
if (croppedWidth < 0 || croppedHeight < 0) return null;
let cuttedImageData = originalCtx.getImageData(minX, minY, croppedWidth, croppedHeight);
function resizeCanvas() {
var ratio = Math.max(window.devicePixelRatio || 1, 1);
var additionalFactor = 10;
let croppedCanvas = document.createElement('canvas'),
croppedCtx = croppedCanvas.getContext('2d');
signaturePadCanvas.width = signaturePadCanvas.offsetWidth * ratio * additionalFactor;
signaturePadCanvas.height = signaturePadCanvas.offsetHeight * ratio * additionalFactor;
signaturePadCanvas.getContext("2d").scale(ratio * additionalFactor, ratio * additionalFactor);
croppedCanvas.width = croppedWidth;
croppedCanvas.height = croppedHeight;
croppedCtx.putImageData(cuttedImageData, 0, 0);
signaturePad.clear();
}
return croppedCanvas.toDataURL();
}
function resizeCanvas() {
// When zoomed out to less than 100%, for some very strange reason,
// some browsers report devicePixelRatio as less than 1
// and only part of the canvas is cleared then.
var ratio = Math.max(window.devicePixelRatio || 1, 1);
var additionalFactor = 10;
new IntersectionObserver((entries, observer) => {
if (entries.some(entry => entry.intersectionRatio > 0)) {
resizeCanvas();
}
}).observe(signaturePadCanvas);
signaturePadCanvas.width = signaturePadCanvas.offsetWidth * ratio * additionalFactor;
signaturePadCanvas.height = signaturePadCanvas.offsetHeight * ratio * additionalFactor;
signaturePadCanvas.getContext("2d").scale(ratio * additionalFactor, ratio * additionalFactor);
new ResizeObserver(resizeCanvas).observe(signaturePadCanvas);
</script>
</div>
// This library does not listen for canvas changes, so after the canvas is automatically
// cleared by the browser, SignaturePad#isEmpty might still return false, even though the
// canvas looks empty, because the internal data of this library wasn't cleared. To make sure
// that the state of this library is consistent with visual state of the canvas, you
// have to clear it manually.
signaturePad.clear();
}
new IntersectionObserver((entries, observer) => {
if (entries.some(entry => entry.intersectionRatio > 0)) {
resizeCanvas();
}
}).observe(signaturePadCanvas);
new ResizeObserver(resizeCanvas).observe(signaturePadCanvas);
</script>
</div>
<div class="tab-container" th:title="#{sign.text}">
<label class="form-check-label" for="sigText" th:text="#{text}"></label>
<textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
<label th:text="#{font}"></label>
<select class="form-control" name="font" id="font-select">
<option th:each="font : ${fonts}" th:value="${font.name}" th:text="${font.name}" th:class="${font.name.toLowerCase()+'-font'}">
</option>
</select>
<div class="margin-auto-parent">
<button id="save-text-signature" class="btn btn-outline-success mt-2 margin-center" onclick="addDraggableFromText()" th:text="#{sign.add}"></button>
</div>
<script>
function addDraggableFromText() {
const sigText = document.getElementById('sigText').value;
const font = document.querySelector('select[name=font]').value;
const fontSize = 100;
<div class="tab-container" th:title="#{sign.text}">
<label class="form-check-label" for="sigText" th:text="#{text}"></label>
<textarea class="form-control" id="sigText" name="sigText" rows="3"></textarea>
<label th:text="#{font}"></label>
<select class="form-control" name="font" id="font-select">
<option th:each="font : ${fonts}" th:value="${font.name}" th:text="${font.name}"
th:class="${font.name.toLowerCase()+'-font'}"></option>
</select>
<div class="margin-auto-parent">
<button id="save-text-signature" class="btn btn-outline-success mt-2 margin-center"
onclick="addDraggableFromText()" th:text="#{sign.add}"></button>
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.font = `${fontSize}px ${font}`;
const textWidth = ctx.measureText(sigText).width;
const textHeight = fontSize;
let paragraphs = sigText.split(/\r?\n/);
canvas.width = textWidth;
canvas.height = paragraphs.length * textHeight*1.35; //for tails
ctx.font = `${fontSize}px ${font}`;
ctx.textBaseline = 'top';
let y = 0;
paragraphs.forEach(paragraph => {
ctx.fillText(paragraph, 0, y);
y += fontSize;
});
const dataURL = canvas.toDataURL();
DraggableUtils.createDraggableCanvasFromUrl(dataURL);
}
</script>
<script>
const sigTextInput = document.getElementById('sigText');
const fontSelect = document.getElementById('font-select');
const updateOptionTexts = () => {
Array.from(fontSelect.options).forEach(option => {
const fontName = option.value.replace(/-regular$/i, '');
option.text = sigTextInput.value || fontName;
});
}
sigTextInput.addEventListener('input', updateOptionTexts);
fontSelect.addEventListener('change', (e) => {
e.target.style.fontFamily = e.target.value;
updateOptionTexts();
});
// Manually trigger the change event
fontSelect.dispatchEvent(new Event('change'));
</script>
</div>
<script>
function addDraggableFromText() {
const sigText = document.getElementById('sigText').value;
const font = document.querySelector('select[name=font]').value;
const fontSize = 100;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.font = `${fontSize}px ${font}`;
const textWidth = ctx.measureText(sigText).width;
const textHeight = fontSize;
let paragraphs = sigText.split(/\r?\n/);
canvas.width = textWidth;
canvas.height = paragraphs.length * textHeight * 1.35; // for tails
ctx.font = `${fontSize}px ${font}`;
ctx.textBaseline = 'top';
let y = 0;
paragraphs.forEach(paragraph => {
ctx.fillText(paragraph, 0, y);
y += fontSize;
});
const dataURL = canvas.toDataURL();
DraggableUtils.createDraggableCanvasFromUrl(dataURL);
}
</script>
</div>
</div>
<!-- draggables box -->
<div id="box-drag-container" class="show-on-file-selected">
<canvas id="pdf-canvas"></canvas>
<script th:src="@{'/js/thirdParty/pdf-lib.min.js'}"></script>
<script th:src="@{'/js/draggable-utils.js'}"></script>
<div class="draggable-buttons-box ignore-rtl">
<button class="btn btn-outline-secondary"
onclick="DraggableUtils.deleteDraggableCanvas(DraggableUtils.getLastInteracted())">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash"
viewBox="0 0 16 16">
<path
d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z" />
<path
d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z" />
</svg>
</button>
<button class="btn btn-outline-secondary"
onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.incrementPage() : DraggableUtils.decrementPage()"
style="margin-left:auto">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-chevron-left" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z" />
</svg>
</button>
<button class="btn btn-outline-secondary"
onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.decrementPage() : DraggableUtils.incrementPage()">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
class="bi bi-chevron-right" viewBox="0 0 16 16">
<path fill-rule="evenodd"
d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z" />
</svg>
</button>
<!-- draggables box -->
<div id="box-drag-container" class="show-on-file-selected">
<canvas id="pdf-canvas"></canvas>
<script th:src="@{'/js/thirdParty/pdf-lib.min.js'}"></script>
<script th:src="@{'/js/draggable-utils.js'}"></script>
<div class="draggable-buttons-box ignore-rtl">
<button class="btn btn-outline-secondary" onclick="DraggableUtils.deleteDraggableCanvas(DraggableUtils.getLastInteracted())">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash" viewBox="0 0 16 16">
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5Zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6Z"/>
<path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1ZM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118ZM2.5 3h11V2h-11v1Z"/>
</svg>
</button>
<button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.incrementPage() : DraggableUtils.decrementPage()" style="margin-left:auto">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-left" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z"/>
</svg>
</button>
<button class="btn btn-outline-secondary" onclick="document.documentElement.getAttribute('dir')==='rtl' ? DraggableUtils.decrementPage() : DraggableUtils.incrementPage()">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-right" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/>
</svg>
</button>
</div>
</div>
</div>
<!-- download button -->
<div class="margin-auto-parent">
<button id="download-pdf" class="btn btn-primary mb-2 show-on-file-selected margin-center"
th:text="#{downloadPdf}"></button>
</div>
<!-- download button -->
<div class="margin-auto-parent">
<button id="download-pdf" class="btn btn-primary mb-2 show-on-file-selected margin-center" th:text="#{downloadPdf}"></button>
</div>
<script>
document.getElementById("download-pdf").addEventListener('click', async () => {
const modifiedPdf = await DraggableUtils.getOverlayedPdfDocument();
const modifiedPdfBytes = await modifiedPdf.save();
const blob = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = originalFileName + '_signed.pdf';
link.click();
});
</script>
<script>
document.getElementById("download-pdf").addEventListener('click', async() => {
const modifiedPdf = await DraggableUtils.getOverlayedPdfDocument();
const modifiedPdfBytes = await modifiedPdf.save();
const blob = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = originalFileName + '_signed.pdf';
link.click();
});
</script>
</div>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
<!-- Link the draggable.js file -->
<script src="/path/to/your/draggable.js"></script>
</body>
</body>
</html>