Compare commits
35 Commits
normalize_
...
v0.21.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
625275124a | ||
|
|
c96ebccae4 | ||
|
|
20cb460a7e | ||
|
|
3a62d19979 | ||
|
|
51ad741744 | ||
|
|
673f005fe6 | ||
|
|
8d9f0361d0 | ||
|
|
56e3ec1219 | ||
|
|
a0acafcefc | ||
|
|
918f5954b7 | ||
|
|
148dcdaee7 | ||
|
|
a5f0777892 | ||
|
|
010426d488 | ||
|
|
6fc9c7be90 | ||
|
|
094fde9801 | ||
|
|
e4a76e96af | ||
|
|
68f582bcb9 | ||
|
|
639aed7120 | ||
|
|
994bb4d1d2 | ||
|
|
80b11a55fa | ||
|
|
3cfb554623 | ||
|
|
e84f9c5946 | ||
|
|
17cc31d6e7 | ||
|
|
0c6e10a6dd | ||
|
|
297c57631f | ||
|
|
bd4e252bb6 | ||
|
|
0ce34c70bc | ||
|
|
4df75cfba1 | ||
|
|
2aa435bcfb | ||
|
|
0a4a9e6947 | ||
|
|
d5860d0b55 | ||
|
|
6a487ce514 | ||
|
|
4f3b85e66b | ||
|
|
370cd97e05 | ||
|
|
55d4fda01b |
@@ -1,2 +1,5 @@
|
||||
# Formatting
|
||||
5f771b785130154ed47952635b7acef371ffe0ec
|
||||
5f771b785130154ed47952635b7acef371ffe0ec
|
||||
|
||||
# Normalize files
|
||||
55d4fda01b2f39f5b7d7b4fda5214bd7ff0fd5dd
|
||||
|
||||
22
.github/workflows/push-docker.yml
vendored
@@ -3,7 +3,7 @@ name: Push Docker Image with VersionNumber
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
permissions:
|
||||
@@ -15,13 +15,13 @@ jobs:
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v3.5.2
|
||||
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3.11.0
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
|
||||
|
||||
|
||||
- uses: gradle/gradle-build-action@v2.4.2
|
||||
env:
|
||||
@@ -32,11 +32,11 @@ jobs:
|
||||
|
||||
- name: Make Gradle wrapper executable
|
||||
run: chmod +x gradlew
|
||||
|
||||
|
||||
- name: Get version number
|
||||
id: versionNumber
|
||||
run: echo "::set-output name=versionNumber::$(./gradlew printVersion --quiet | tail -1)"
|
||||
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2.1.0
|
||||
with:
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
- name: Convert repository owner to lowercase
|
||||
id: repoowner
|
||||
run: echo "::set-output name=lowercase::$(echo ${{ github.repository_owner }} | awk '{print tolower($0)}')"
|
||||
|
||||
|
||||
- name: Generate tags
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4.4.0
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
cache-to: type=gha,mode=max
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-args:
|
||||
build-args:
|
||||
VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
tags: |
|
||||
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }}
|
||||
type=raw,value=latest-ultra-lite,enable=${{ github.ref == 'refs/heads/master' }}
|
||||
|
||||
|
||||
|
||||
- name: Build and push Dockerfile-ultra-lite
|
||||
uses: docker/build-push-action@v4.0.0
|
||||
@@ -112,7 +112,7 @@ jobs:
|
||||
cache-to: type=gha,mode=max
|
||||
tags: ${{ steps.meta2.outputs.tags }}
|
||||
labels: ${{ steps.meta2.outputs.labels }}
|
||||
build-args:
|
||||
build-args:
|
||||
VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
|
||||
@@ -129,7 +129,7 @@ jobs:
|
||||
tags: |
|
||||
type=raw,value=${{ steps.versionNumber.outputs.versionNumber }}-lite,enable=${{ github.ref == 'refs/heads/master' }}
|
||||
type=raw,value=latest-lite,enable=${{ github.ref == 'refs/heads/master' }}
|
||||
|
||||
|
||||
|
||||
- name: Build and push Dockerfile-lite
|
||||
uses: docker/build-push-action@v4.0.0
|
||||
@@ -142,7 +142,7 @@ jobs:
|
||||
cache-to: type=gha,mode=max
|
||||
tags: ${{ steps.meta3.outputs.tags }}
|
||||
labels: ${{ steps.meta3.outputs.labels }}
|
||||
build-args:
|
||||
build-args:
|
||||
VERSION_TAG=${{ steps.versionNumber.outputs.versionNumber }}
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
- name: Build and Push Helm Chart
|
||||
|
||||
12
.github/workflows/releaseArtifacts.yml
vendored
@@ -1,7 +1,7 @@
|
||||
name: Release Artifacts
|
||||
|
||||
on:
|
||||
release:
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -19,13 +19,13 @@ jobs:
|
||||
file_suffix: ''
|
||||
steps:
|
||||
- uses: actions/checkout@v3.5.2
|
||||
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3.11.0
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
|
||||
@@ -42,11 +42,11 @@ jobs:
|
||||
asset_name: Stirling-PDF${{ matrix.file_suffix }}.exe
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
||||
|
||||
|
||||
- name: Get version number
|
||||
id: versionNumber
|
||||
run: echo "::set-output name=versionNumber::$(./gradlew printVersion --quiet | tail -1)"
|
||||
|
||||
|
||||
- name: Upload jar binaries to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
|
||||
6
.github/workflows/swagger.yml
vendored
@@ -3,7 +3,7 @@ name: Update Swagger
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
branches:
|
||||
- master
|
||||
jobs:
|
||||
push:
|
||||
@@ -12,13 +12,13 @@ jobs:
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v3.5.2
|
||||
|
||||
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3.11.0
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
|
||||
|
||||
2
.github/workflows/test.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
||||
- name: Run Docker Compose Tests
|
||||
run: |
|
||||
chmod +x ./gradlew
|
||||
|
||||
|
||||
- name: Get version number
|
||||
id: versionNumber
|
||||
run: echo "::set-output name=versionNumber::$(./gradlew printVersion --quiet | tail -1)"
|
||||
|
||||
252
.gitignore
vendored
@@ -1,127 +1,127 @@
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
.recommenders
|
||||
.classpath
|
||||
.project
|
||||
version.properties
|
||||
pipeline/watchedFolders/
|
||||
pipeline/finishedFolders/
|
||||
#### Stirling-PDF Files ###
|
||||
customFiles/
|
||||
configs/
|
||||
watchedFolders/
|
||||
|
||||
|
||||
# Gradle
|
||||
.gradle
|
||||
.lock
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# PyDev specific (Python IDE for Eclipse)
|
||||
*.pydevproject
|
||||
|
||||
# CDT-specific (C/C++ Development Tooling)
|
||||
.cproject
|
||||
|
||||
# CDT- autotools
|
||||
.autotools
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific (PHP Development Tools)
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# Tern plugin
|
||||
.tern-project
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
|
||||
# Code Recommenders
|
||||
.recommenders/
|
||||
|
||||
# Annotation Processing
|
||||
.apt_generated/
|
||||
.apt_generated_test/
|
||||
|
||||
# Scala IDE specific (Scala & Java development for Eclipse)
|
||||
.cache-main
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
|
||||
# Uncomment this line if you wish to ignore the project description file.
|
||||
# Typically, this file would be tracked if it contains build/dependency configurations:
|
||||
#.project
|
||||
|
||||
### Eclipse Patch ###
|
||||
# Spring Boot Tooling
|
||||
.sts4-cache/
|
||||
|
||||
### Git ###
|
||||
# Created by git for backups. To disable backups in Git:
|
||||
# $ git config --global mergetool.keepBackup false
|
||||
*.orig
|
||||
|
||||
# Created by git when using merge tools for conflicts
|
||||
*.BACKUP.*
|
||||
*.BASE.*
|
||||
*.LOCAL.*
|
||||
*.REMOTE.*
|
||||
*_BACKUP_*.txt
|
||||
*_BASE_*.txt
|
||||
*_LOCAL_*.txt
|
||||
*_REMOTE_*.txt
|
||||
|
||||
### Java ###
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
*.db
|
||||
/build
|
||||
|
||||
/.vscode
|
||||
/.idea
|
||||
|
||||
# Ignore Mac DS_Store files
|
||||
.DS_Store
|
||||
|
||||
|
||||
### Eclipse ###
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
.recommenders
|
||||
.classpath
|
||||
.project
|
||||
version.properties
|
||||
pipeline/watchedFolders/
|
||||
pipeline/finishedFolders/
|
||||
#### Stirling-PDF Files ###
|
||||
customFiles/
|
||||
configs/
|
||||
watchedFolders/
|
||||
|
||||
|
||||
# Gradle
|
||||
.gradle
|
||||
.lock
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# PyDev specific (Python IDE for Eclipse)
|
||||
*.pydevproject
|
||||
|
||||
# CDT-specific (C/C++ Development Tooling)
|
||||
.cproject
|
||||
|
||||
# CDT- autotools
|
||||
.autotools
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific (PHP Development Tools)
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# Tern plugin
|
||||
.tern-project
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
|
||||
# Code Recommenders
|
||||
.recommenders/
|
||||
|
||||
# Annotation Processing
|
||||
.apt_generated/
|
||||
.apt_generated_test/
|
||||
|
||||
# Scala IDE specific (Scala & Java development for Eclipse)
|
||||
.cache-main
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
|
||||
# Uncomment this line if you wish to ignore the project description file.
|
||||
# Typically, this file would be tracked if it contains build/dependency configurations:
|
||||
#.project
|
||||
|
||||
### Eclipse Patch ###
|
||||
# Spring Boot Tooling
|
||||
.sts4-cache/
|
||||
|
||||
### Git ###
|
||||
# Created by git for backups. To disable backups in Git:
|
||||
# $ git config --global mergetool.keepBackup false
|
||||
*.orig
|
||||
|
||||
# Created by git when using merge tools for conflicts
|
||||
*.BACKUP.*
|
||||
*.BASE.*
|
||||
*.LOCAL.*
|
||||
*.REMOTE.*
|
||||
*_BACKUP_*.txt
|
||||
*_BASE_*.txt
|
||||
*_LOCAL_*.txt
|
||||
*_REMOTE_*.txt
|
||||
|
||||
### Java ###
|
||||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
*.db
|
||||
/build
|
||||
|
||||
/.vscode
|
||||
/.idea
|
||||
|
||||
# Ignore Mac DS_Store files
|
||||
.DS_Store
|
||||
**/.DS_Store
|
||||
138
Dockerfile
@@ -1,69 +1,69 @@
|
||||
# Main stage
|
||||
FROM alpine:3.19.1
|
||||
|
||||
# JDK for app
|
||||
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
||||
apk add --no-cache \
|
||||
ca-certificates \
|
||||
tzdata \
|
||||
tini \
|
||||
bash \
|
||||
curl \
|
||||
openjdk17-jre \
|
||||
# Doc conversion
|
||||
libreoffice@testing \
|
||||
# OCR MY PDF (unpaper for descew and other advanced featues)
|
||||
ocrmypdf \
|
||||
tesseract-ocr-data-eng \
|
||||
# CV
|
||||
py3-opencv \
|
||||
# python3/pip
|
||||
python3 && \
|
||||
wget https://bootstrap.pypa.io/get-pip.py -qO - | python3 - --break-system-packages --no-cache-dir --upgrade && \
|
||||
# uno unoconv and HTML
|
||||
pip install --break-system-packages --no-cache-dir --upgrade unoconv WeasyPrint && \
|
||||
mv /usr/share/tessdata /usr/share/tessdata-original
|
||||
|
||||
|
||||
|
||||
ARG VERSION_TAG
|
||||
|
||||
# Set Environment Variables
|
||||
ENV DOCKER_ENABLE_SECURITY=false \
|
||||
HOME=/home/stirlingpdfuser \
|
||||
VERSION_TAG=$VERSION_TAG \
|
||||
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75"
|
||||
# PUID=1000 \
|
||||
# PGID=1000 \
|
||||
# UMASK=022 \
|
||||
|
||||
# Copy necessary files
|
||||
COPY scripts /scripts
|
||||
COPY pipeline /pipeline
|
||||
COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto
|
||||
COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto
|
||||
COPY build/libs/*.jar app.jar
|
||||
|
||||
# Create user and group
|
||||
##RUN groupadd -g $PGID stirlingpdfgroup && \
|
||||
## useradd -u $PUID -g stirlingpdfgroup -s /bin/sh stirlingpdfuser && \
|
||||
## mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME && \
|
||||
# Set up necessary directories and permissions
|
||||
RUN mkdir -p /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \
|
||||
##&& \
|
||||
## chown -R stirlingpdfuser:stirlingpdfgroup /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /customFiles && \
|
||||
## chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/tesseract-ocr-original && \
|
||||
# Set font cache and permissions
|
||||
fc-cache -f -v && \
|
||||
chmod +x /scripts/*
|
||||
## chown stirlingpdfuser:stirlingpdfgroup /app.jar && \
|
||||
## chmod +x /scripts/init.sh
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
# Set user and run command
|
||||
##USER stirlingpdfuser
|
||||
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
||||
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]
|
||||
# Main stage
|
||||
FROM alpine:3.19.1
|
||||
|
||||
# JDK for app
|
||||
RUN echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/apk/repositories && \
|
||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/community" | tee -a /etc/apk/repositories && \
|
||||
echo "@testing https://dl-cdn.alpinelinux.org/alpine/edge/testing" | tee -a /etc/apk/repositories && \
|
||||
apk add --no-cache \
|
||||
ca-certificates \
|
||||
tzdata \
|
||||
tini \
|
||||
bash \
|
||||
curl \
|
||||
openjdk17-jre \
|
||||
# Doc conversion
|
||||
libreoffice@testing \
|
||||
# OCR MY PDF (unpaper for descew and other advanced featues)
|
||||
ocrmypdf \
|
||||
tesseract-ocr-data-eng \
|
||||
# CV
|
||||
py3-opencv \
|
||||
# python3/pip
|
||||
python3 && \
|
||||
wget https://bootstrap.pypa.io/get-pip.py -qO - | python3 - --break-system-packages --no-cache-dir --upgrade && \
|
||||
# uno unoconv and HTML
|
||||
pip install --break-system-packages --no-cache-dir --upgrade unoconv WeasyPrint && \
|
||||
mv /usr/share/tessdata /usr/share/tessdata-original
|
||||
|
||||
|
||||
|
||||
ARG VERSION_TAG
|
||||
|
||||
# Set Environment Variables
|
||||
ENV DOCKER_ENABLE_SECURITY=false \
|
||||
HOME=/home/stirlingpdfuser \
|
||||
VERSION_TAG=$VERSION_TAG \
|
||||
JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -XX:MaxRAMPercentage=75"
|
||||
# PUID=1000 \
|
||||
# PGID=1000 \
|
||||
# UMASK=022 \
|
||||
|
||||
# Copy necessary files
|
||||
COPY scripts /scripts
|
||||
COPY pipeline /pipeline
|
||||
COPY src/main/resources/static/fonts/*.ttf /usr/share/fonts/opentype/noto
|
||||
COPY src/main/resources/static/fonts/*.otf /usr/share/fonts/opentype/noto
|
||||
COPY build/libs/*.jar app.jar
|
||||
|
||||
# Create user and group
|
||||
##RUN groupadd -g $PGID stirlingpdfgroup && \
|
||||
## useradd -u $PUID -g stirlingpdfgroup -s /bin/sh stirlingpdfuser && \
|
||||
## mkdir -p $HOME && chown stirlingpdfuser:stirlingpdfgroup $HOME && \
|
||||
# Set up necessary directories and permissions
|
||||
RUN mkdir -p /configs /logs /customFiles /pipeline/watchedFolders /pipeline/finishedFolders && \
|
||||
##&& \
|
||||
## chown -R stirlingpdfuser:stirlingpdfgroup /scripts /usr/share/fonts/opentype/noto /usr/share/tesseract-ocr /configs /customFiles && \
|
||||
## chown -R stirlingpdfuser:stirlingpdfgroup /usr/share/tesseract-ocr-original && \
|
||||
# Set font cache and permissions
|
||||
fc-cache -f -v && \
|
||||
chmod +x /scripts/*
|
||||
## chown stirlingpdfuser:stirlingpdfgroup /app.jar && \
|
||||
## chmod +x /scripts/init.sh
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
# Set user and run command
|
||||
##USER stirlingpdfuser
|
||||
ENTRYPOINT ["tini", "--", "/scripts/init.sh"]
|
||||
CMD ["java", "-Dfile.encoding=UTF-8", "-jar", "/app.jar"]
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
| Operation | PageOps | Convert | Security | Other | CLI | Python | OpenCV | LibreOffice | OCRmyPDF | Java | Javascript |
|
||||
|---------------------|---------|---------|----------|-------|------|--------|--------|-------------|----------|----------|------------|
|
||||
| adjust-contrast | ✔️ | | | | | | | | | | ✔️ |
|
||||
| auto-split-pdf | ✔️ | | | | | | | | | ✔️ | |
|
||||
| crop | ✔️ | | | | | | | | | ✔️ | |
|
||||
| extract-page | ✔️ | | | | | | | | | ✔️ | |
|
||||
| merge-pdfs | ✔️ | | | | | | | | | ✔️ | |
|
||||
| multi-page-layout | ✔️ | | | | | | | | | ✔️ | |
|
||||
| pdf-organizer | ✔️ | | | | | | | | | ✔️ | ✔️ |
|
||||
| pdf-to-single-page | ✔️ | | | | | | | | | ✔️ | |
|
||||
| remove-pages | ✔️ | | | | | | | | | ✔️ | |
|
||||
| rotate-pdf | ✔️ | | | | | | | | | ✔️ | |
|
||||
| scale-pages | ✔️ | | | | | | | | | ✔️ | |
|
||||
| split-pdfs | ✔️ | | | | | | | | | ✔️ | |
|
||||
| file-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| img-to-pdf | | ✔️ | | | | | | | | ✔️ | |
|
||||
| pdf-to-html | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| pdf-to-img | | ✔️ | | | | | | | | ✔️ | |
|
||||
| pdf-to-pdfa | | ✔️ | | | ✔️ | | | | ✔️ | | |
|
||||
| pdf-to-markdown | | ✔️ | | | | | | | | ✔️ | |
|
||||
| pdf-to-presentation | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| pdf-to-text | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| pdf-to-word | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| pdf-to-xml | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| xlsx-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| add-password | | | ✔️ | | | | | | | ✔️ | |
|
||||
| add-watermark | | | ✔️ | | | | | | | ✔️ | |
|
||||
| cert-sign | | | ✔️ | | | | | | | ✔️ | |
|
||||
| change-permissions | | | ✔️ | | | | | | | ✔️ | |
|
||||
| remove-password | | | ✔️ | | | | | | | ✔️ | |
|
||||
| sanitize-pdf | | | ✔️ | | | | | | | ✔️ | |
|
||||
| add-image | | | | ✔️ | | | | | | ✔️ | |
|
||||
| add-page-numbers | | | | ✔️ | | | | | | ✔️ | |
|
||||
| auto-rename | | | | ✔️ | | | | | | ✔️ | |
|
||||
| change-metadata | | | | ✔️ | | | | | | ✔️ | |
|
||||
| compare | | | | ✔️ | | | | | | | ✔️ |
|
||||
| compress-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |
|
||||
| extract-image-scans | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | |
|
||||
| extract-images | | | | ✔️ | | | | | | ✔️ | |
|
||||
| flatten | | | | ✔️ | | | | | | | ✔️ |
|
||||
| get-info-on-pdf | | | | ✔️ | | | | | | ✔️ | |
|
||||
| ocr-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |
|
||||
| remove-blanks | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | |
|
||||
| repair | | | | ✔️ | ✔️ | | | ✔️ | | | |
|
||||
| show-javascript | | | | ✔️ | | | | | | | ✔️ |
|
||||
| Operation | PageOps | Convert | Security | Other | CLI | Python | OpenCV | LibreOffice | OCRmyPDF | Java | Javascript |
|
||||
|---------------------|---------|---------|----------|-------|------|--------|--------|-------------|----------|----------|------------|
|
||||
| adjust-contrast | ✔️ | | | | | | | | | | ✔️ |
|
||||
| auto-split-pdf | ✔️ | | | | | | | | | ✔️ | |
|
||||
| crop | ✔️ | | | | | | | | | ✔️ | |
|
||||
| extract-page | ✔️ | | | | | | | | | ✔️ | |
|
||||
| merge-pdfs | ✔️ | | | | | | | | | ✔️ | |
|
||||
| multi-page-layout | ✔️ | | | | | | | | | ✔️ | |
|
||||
| pdf-organizer | ✔️ | | | | | | | | | ✔️ | ✔️ |
|
||||
| pdf-to-single-page | ✔️ | | | | | | | | | ✔️ | |
|
||||
| remove-pages | ✔️ | | | | | | | | | ✔️ | |
|
||||
| rotate-pdf | ✔️ | | | | | | | | | ✔️ | |
|
||||
| scale-pages | ✔️ | | | | | | | | | ✔️ | |
|
||||
| split-pdfs | ✔️ | | | | | | | | | ✔️ | |
|
||||
| file-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| img-to-pdf | | ✔️ | | | | | | | | ✔️ | |
|
||||
| pdf-to-html | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| pdf-to-img | | ✔️ | | | | | | | | ✔️ | |
|
||||
| pdf-to-pdfa | | ✔️ | | | ✔️ | | | | ✔️ | | |
|
||||
| pdf-to-markdown | | ✔️ | | | | | | | | ✔️ | |
|
||||
| pdf-to-presentation | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| pdf-to-text | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| pdf-to-word | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| pdf-to-xml | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| xlsx-to-pdf | | ✔️ | | | ✔️ | | | ✔️ | | | |
|
||||
| add-password | | | ✔️ | | | | | | | ✔️ | |
|
||||
| add-watermark | | | ✔️ | | | | | | | ✔️ | |
|
||||
| cert-sign | | | ✔️ | | | | | | | ✔️ | |
|
||||
| change-permissions | | | ✔️ | | | | | | | ✔️ | |
|
||||
| remove-password | | | ✔️ | | | | | | | ✔️ | |
|
||||
| sanitize-pdf | | | ✔️ | | | | | | | ✔️ | |
|
||||
| add-image | | | | ✔️ | | | | | | ✔️ | |
|
||||
| add-page-numbers | | | | ✔️ | | | | | | ✔️ | |
|
||||
| auto-rename | | | | ✔️ | | | | | | ✔️ | |
|
||||
| change-metadata | | | | ✔️ | | | | | | ✔️ | |
|
||||
| compare | | | | ✔️ | | | | | | | ✔️ |
|
||||
| compress-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |
|
||||
| extract-image-scans | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | |
|
||||
| extract-images | | | | ✔️ | | | | | | ✔️ | |
|
||||
| flatten | | | | ✔️ | | | | | | | ✔️ |
|
||||
| get-info-on-pdf | | | | ✔️ | | | | | | ✔️ | |
|
||||
| ocr-pdf | | | | ✔️ | ✔️ | | | | ✔️ | | |
|
||||
| remove-blanks | | | | ✔️ | ✔️ | ✔️ | ✔️ | | | | |
|
||||
| repair | | | | ✔️ | ✔️ | | | ✔️ | | | |
|
||||
| show-javascript | | | | ✔️ | | | | | | | ✔️ |
|
||||
| sign | | | | ✔️ | | | | | | | ✔️ |
|
||||
@@ -9,13 +9,13 @@ Fork Stirling-PDF and make a new branch out of Main
|
||||
Then add reference to the language in the navbar by adding a new language entry to the dropdown
|
||||
|
||||
https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/templates/fragments/languages.html
|
||||
and add a flag svg file to
|
||||
and add a flag svg file to
|
||||
https://github.com/Stirling-Tools/Stirling-PDF/tree/main/src/main/resources/static/images/flags
|
||||
Any SVG flags are fine, i got most of mine from [here](https://flagicons.lipis.dev/)
|
||||
If your language isnt represented by a flag just find whichever closely matches it, such as for Arabic i chose Saudi Arabia
|
||||
If your language isn't represented by a flag just find whichever closely matches it, such as for Arabic i chose Saudi Arabia
|
||||
|
||||
|
||||
For example to add Polish you would add
|
||||
For example to add Polish you would add
|
||||
```html
|
||||
<a class="dropdown-item lang_dropdown-item" href="" data-language-code="pl_PL">
|
||||
<img src="images/flags/pl.svg" alt="icon" width="20" height="15"> Polski
|
||||
@@ -23,7 +23,7 @@ For example to add Polish you would add
|
||||
```
|
||||
The data-language-code is the code used to reference the file in the next step.
|
||||
|
||||
Start by copying the existing english property file
|
||||
Start by copying the existing english property file
|
||||
|
||||
[https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/src/main/resources/messages_en_GB.properties)
|
||||
|
||||
@@ -32,7 +32,7 @@ Copy and rename it to messages_{your data-language-code here}.properties, in the
|
||||
|
||||
Then simply translate all property entries within that file and make a PR into main for others to use!
|
||||
|
||||
If you do not have a java IDE i am happy to verify the changes worked once you raise PR (but wont be able to verify the translations themselves)
|
||||
If you do not have a java IDE i am happy to verify the changes worked once you raise PR (but won't be able to verify the translations themselves)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
This document provides instructions on how to add additional language packs for the OCR tab in Stirling-PDF, both inside and outside of Docker.
|
||||
|
||||
## My OCR used to work and now doesnt!
|
||||
Please update your tesseract docker volume path version from 4.00 to 5
|
||||
## My OCR used to work and now doesn't!
|
||||
The paths have changed for the tessadata locations on new docker images, please use ``/usr/share/tessdata`` (Others should still work for backwards compatability but might not)
|
||||
|
||||
## How does the OCR Work
|
||||
Stirling-PDF uses [OCRmyPDF](https://github.com/ocrmypdf/OCRmyPDF) which in turn uses tesseract for its text recognition.
|
||||
All credit goes to them for this awesome work!
|
||||
All credit goes to them for this awesome work!
|
||||
|
||||
## Language Packs
|
||||
|
||||
@@ -27,7 +27,7 @@ Depending on your requirements, you can choose the appropriate language pack for
|
||||
|
||||
#### Docker
|
||||
|
||||
If you are using Docker, you need to expose the Tesseract tessdata directory as a volume in order to use the additional language packs.
|
||||
If you are using Docker, you need to expose the Tesseract tessdata directory as a volume in order to use the additional language packs.
|
||||
#### Docker Compose
|
||||
Modify your `docker-compose.yml` file to include the following volume configuration:
|
||||
|
||||
|
||||
88
Jenkinsfile
vendored
@@ -1,45 +1,45 @@
|
||||
pipeline {
|
||||
agent any
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'chmod 755 gradlew'
|
||||
sh './gradlew build'
|
||||
}
|
||||
}
|
||||
stage('Docker Build') {
|
||||
steps {
|
||||
script {
|
||||
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
|
||||
def image = "frooodle/s-pdf:$appVersion"
|
||||
sh "docker build -t $image ."
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Docker Push') {
|
||||
steps {
|
||||
script {
|
||||
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
|
||||
def image = "frooodle/s-pdf:$appVersion"
|
||||
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
|
||||
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
|
||||
sh "docker push $image"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Helm Push') {
|
||||
steps {
|
||||
script {
|
||||
//TODO: Read chartVersion from Chart.yaml
|
||||
def chartVersion = '1.0.0'
|
||||
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
|
||||
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
|
||||
sh "helm package chart/stirling-pdf"
|
||||
sh "helm push stirling-pdf-chart-1.0.0.tgz oci://registry-1.docker.io/frooodle"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pipeline {
|
||||
agent any
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
sh 'chmod 755 gradlew'
|
||||
sh './gradlew build'
|
||||
}
|
||||
}
|
||||
stage('Docker Build') {
|
||||
steps {
|
||||
script {
|
||||
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
|
||||
def image = "frooodle/s-pdf:$appVersion"
|
||||
sh "docker build -t $image ."
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Docker Push') {
|
||||
steps {
|
||||
script {
|
||||
def appVersion = sh(returnStdout: true, script: './gradlew printVersion -q').trim()
|
||||
def image = "frooodle/s-pdf:$appVersion"
|
||||
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
|
||||
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
|
||||
sh "docker push $image"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Helm Push') {
|
||||
steps {
|
||||
script {
|
||||
//TODO: Read chartVersion from Chart.yaml
|
||||
def chartVersion = '1.0.0'
|
||||
withCredentials([string(credentialsId: 'docker_hub_access_token', variable: 'DOCKER_HUB_ACCESS_TOKEN')]) {
|
||||
sh "docker login --username frooodle --password $DOCKER_HUB_ACCESS_TOKEN"
|
||||
sh "helm package chart/stirling-pdf"
|
||||
sh "helm push stirling-pdf-chart-1.0.0.tgz oci://registry-1.docker.io/frooodle"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ sudo apt-get update
|
||||
sudo apt-get install -y git automake autoconf libtool libleptonica-dev pkg-config zlib1g-dev make g++ java-17-openjdk python3 python3-pip
|
||||
```
|
||||
|
||||
For Fedora-based systems use this command:
|
||||
For Fedora-based systems use this command:
|
||||
|
||||
```bash
|
||||
sudo dnf install -y git automake autoconf libtool leptonica-devel pkg-config zlib-devel make gcc-c++ java-17-openjdk python3 python3-pip
|
||||
@@ -65,7 +65,7 @@ sudo make install
|
||||
```
|
||||
|
||||
### Step 3: Install Additional Software
|
||||
Next we need to install LibreOffice for conversions, ocrmypdf for OCR, and opencv for patern recognition functionality.
|
||||
Next we need to install LibreOffice for conversions, ocrmypdf for OCR, and opencv for pattern recognition functionality.
|
||||
|
||||
Install the following software:
|
||||
|
||||
@@ -95,14 +95,14 @@ For Debian-based systems, you can use the following command:
|
||||
|
||||
```bash
|
||||
sudo apt-get install -y libreoffice-writer libreoffice-calc libreoffice-impress unpaper ocrmypdf
|
||||
pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
|
||||
pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
|
||||
```
|
||||
|
||||
For Fedora:
|
||||
|
||||
```bash
|
||||
sudo dnf install -y libreoffice-writer libreoffice-calc libreoffice-impress unpaper ocrmypdf
|
||||
pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
|
||||
pip3 install uno opencv-python-headless unoconv pngquant WeasyPrint
|
||||
```
|
||||
|
||||
### Step 4: Clone and Build Stirling-PDF
|
||||
@@ -140,7 +140,7 @@ Manual:
|
||||
|
||||
1. Download the desired language pack(s) by selecting the `.traineddata` file(s) for the language(s) you need.
|
||||
2. Place the `.traineddata` files in the Tesseract tessdata directory: `/usr/share/tessdata`
|
||||
3.
|
||||
3.
|
||||
Please view [OCRmyPDF install guide](https://ocrmypdf.readthedocs.io/en/latest/installation.html) for more info.
|
||||
**IMPORTANT:** DO NOT REMOVE EXISTING `eng.traineddata`, IT'S REQUIRED.
|
||||
|
||||
@@ -264,10 +264,10 @@ sudo systemctl restart stirlingpdf.service
|
||||
|
||||
Remember to set the necessary environment variables before running the project if you want to customize the application the list can be seen in the main readme.
|
||||
|
||||
You can do this in the terminal by using the `export` command or -D arguements to java -jar command:
|
||||
You can do this in the terminal by using the `export` command or -D argument to java -jar command:
|
||||
|
||||
```bash
|
||||
export APP_HOME_NAME="Stirling PDF"
|
||||
or
|
||||
-DAPP_HOME_NAME="Stirling PDF"
|
||||
-DAPP_HOME_NAME="Stirling PDF"
|
||||
```
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[](https://github.com/Stirling-Tools/Stirling-PDF/)
|
||||
[](https://github.com/Stirling-Tools/stirling-pdf)
|
||||
[](https://www.paypal.com/paypalme/froodleplex)
|
||||
[](https://github.com/sponsors/Frooodle)
|
||||
[](https://github.com/sponsors/Frooodle)
|
||||
|
||||
[](https://cloud.digitalocean.com/apps/new?repo=https://github.com/Stirling-Tools/Stirling-PDF/tree/digitalOcean&refcode=c3210994b1af)
|
||||
|
||||
@@ -172,7 +172,7 @@ Stirling PDF currently supports 26!
|
||||
- Hindi (हिंदी) (hi_IN)
|
||||
- Hungarian (Magyar) (hu_HU)
|
||||
- Bulgarian (Български) (bg_BG)
|
||||
- Sebian Latin alphabet (Srpski) (sr-Latn-RS)
|
||||
- Sebian Latin alphabet (Srpski) (sr_LATN_RS)
|
||||
|
||||
## Contributing (creating issues, translations, fixing bugs, etc.)
|
||||
|
||||
@@ -262,7 +262,7 @@ For API usage you must provide a header with 'X-API-Key' and the associated API
|
||||
- Redact text (Via UI not just automated way)
|
||||
- Add Forms
|
||||
- Multi page layout (Stich PDF pages together) support x rows y columns and custom page sizing
|
||||
- Fill forms mannual and automatic
|
||||
- Fill forms manually or automatically
|
||||
|
||||
### Q2: Why is my application downloading .htm files?
|
||||
This is an issue caused commonly by your NGINX configuration. The default file upload size for NGINX is 1MB, you need to add the following in your Nginx sites-available file. ``client_max_body_size SIZE;`` Where "SIZE" is 50M for example for 50MB files.
|
||||
|
||||
@@ -1,64 +1,64 @@
|
||||
|Technology | Ultra-Lite | Lite | Full |
|
||||
|----------------|:----------:|:----:|:----:|
|
||||
| Java | ✔️ | ✔️ | ✔️ |
|
||||
| JavaScript | ✔️ | ✔️ | ✔️ |
|
||||
| Libre | | ✔️ | ✔️ |
|
||||
| Python | | | ✔️ |
|
||||
| OpenCV | | | ✔️ |
|
||||
| OCRmyPDF | | | ✔️ |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Operation | Ultra-Lite | Lite | Full
|
||||
--------------------|------------|------|-----
|
||||
add-page-numbers | ✔️ | ✔️ | ✔️
|
||||
add-password | ✔️ | ✔️ | ✔️
|
||||
add-image | ✔️ | ✔️ | ✔️
|
||||
add-watermark | ✔️ | ✔️ | ✔️
|
||||
adjust-contrast | ✔️ | ✔️ | ✔️
|
||||
auto-split-pdf | ✔️ | ✔️ | ✔️
|
||||
auto-redact | ✔️ | ✔️ | ✔️
|
||||
auto-rename | ✔️ | ✔️ | ✔️
|
||||
cert-sign | ✔️ | ✔️ | ✔️
|
||||
crop | ✔️ | ✔️ | ✔️
|
||||
change-metadata | ✔️ | ✔️ | ✔️
|
||||
change-permissions | ✔️ | ✔️ | ✔️
|
||||
compare | ✔️ | ✔️ | ✔️
|
||||
extract-page | ✔️ | ✔️ | ✔️
|
||||
extract-images | ✔️ | ✔️ | ✔️
|
||||
flatten | ✔️ | ✔️ | ✔️
|
||||
get-info-on-pdf | ✔️ | ✔️ | ✔️
|
||||
img-to-pdf | ✔️ | ✔️ | ✔️
|
||||
markdown-to-pdf | ✔️ | ✔️ | ✔️
|
||||
merge-pdfs | ✔️ | ✔️ | ✔️
|
||||
multi-page-layout | ✔️ | ✔️ | ✔️
|
||||
overlay-pdf | ✔️ | ✔️ | ✔️
|
||||
pdf-organizer | ✔️ | ✔️ | ✔️
|
||||
pdf-to-csv | ✔️ | ✔️ | ✔️
|
||||
pdf-to-img | ✔️ | ✔️ | ✔️
|
||||
pdf-to-single-page | ✔️ | ✔️ | ✔️
|
||||
remove-pages | ✔️ | ✔️ | ✔️
|
||||
remove-password | ✔️ | ✔️ | ✔️
|
||||
rotate-pdf | ✔️ | ✔️ | ✔️
|
||||
sanitize-pdf | ✔️ | ✔️ | ✔️
|
||||
scale-pages | ✔️ | ✔️ | ✔️
|
||||
sign | ✔️ | ✔️ | ✔️
|
||||
show-javascript | ✔️ | ✔️ | ✔️
|
||||
split-by-size-or-count | ✔️ | ✔️ | ✔️
|
||||
split-pdf-by-sections | ✔️ | ✔️ | ✔️
|
||||
split-pdfs | ✔️ | ✔️ | ✔️
|
||||
file-to-pdf | | ✔️ | ✔️
|
||||
pdf-to-html | | ✔️ | ✔️
|
||||
pdf-to-presentation | | ✔️ | ✔️
|
||||
pdf-to-text | | ✔️ | ✔️
|
||||
pdf-to-word | | ✔️ | ✔️
|
||||
pdf-to-xml | | ✔️ | ✔️
|
||||
repair | | ✔️ | ✔️
|
||||
xlsx-to-pdf | | ✔️ | ✔️
|
||||
compress-pdf | | | ✔️
|
||||
extract-image-scans | | | ✔️
|
||||
ocr-pdf | | | ✔️
|
||||
pdf-to-pdfa | | | ✔️
|
||||
remove-blanks | | | ✔️
|
||||
|Technology | Ultra-Lite | Lite | Full |
|
||||
|----------------|:----------:|:----:|:----:|
|
||||
| Java | ✔️ | ✔️ | ✔️ |
|
||||
| JavaScript | ✔️ | ✔️ | ✔️ |
|
||||
| Libre | | ✔️ | ✔️ |
|
||||
| Python | | | ✔️ |
|
||||
| OpenCV | | | ✔️ |
|
||||
| OCRmyPDF | | | ✔️ |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Operation | Ultra-Lite | Lite | Full
|
||||
--------------------|------------|------|-----
|
||||
add-page-numbers | ✔️ | ✔️ | ✔️
|
||||
add-password | ✔️ | ✔️ | ✔️
|
||||
add-image | ✔️ | ✔️ | ✔️
|
||||
add-watermark | ✔️ | ✔️ | ✔️
|
||||
adjust-contrast | ✔️ | ✔️ | ✔️
|
||||
auto-split-pdf | ✔️ | ✔️ | ✔️
|
||||
auto-redact | ✔️ | ✔️ | ✔️
|
||||
auto-rename | ✔️ | ✔️ | ✔️
|
||||
cert-sign | ✔️ | ✔️ | ✔️
|
||||
crop | ✔️ | ✔️ | ✔️
|
||||
change-metadata | ✔️ | ✔️ | ✔️
|
||||
change-permissions | ✔️ | ✔️ | ✔️
|
||||
compare | ✔️ | ✔️ | ✔️
|
||||
extract-page | ✔️ | ✔️ | ✔️
|
||||
extract-images | ✔️ | ✔️ | ✔️
|
||||
flatten | ✔️ | ✔️ | ✔️
|
||||
get-info-on-pdf | ✔️ | ✔️ | ✔️
|
||||
img-to-pdf | ✔️ | ✔️ | ✔️
|
||||
markdown-to-pdf | ✔️ | ✔️ | ✔️
|
||||
merge-pdfs | ✔️ | ✔️ | ✔️
|
||||
multi-page-layout | ✔️ | ✔️ | ✔️
|
||||
overlay-pdf | ✔️ | ✔️ | ✔️
|
||||
pdf-organizer | ✔️ | ✔️ | ✔️
|
||||
pdf-to-csv | ✔️ | ✔️ | ✔️
|
||||
pdf-to-img | ✔️ | ✔️ | ✔️
|
||||
pdf-to-single-page | ✔️ | ✔️ | ✔️
|
||||
remove-pages | ✔️ | ✔️ | ✔️
|
||||
remove-password | ✔️ | ✔️ | ✔️
|
||||
rotate-pdf | ✔️ | ✔️ | ✔️
|
||||
sanitize-pdf | ✔️ | ✔️ | ✔️
|
||||
scale-pages | ✔️ | ✔️ | ✔️
|
||||
sign | ✔️ | ✔️ | ✔️
|
||||
show-javascript | ✔️ | ✔️ | ✔️
|
||||
split-by-size-or-count | ✔️ | ✔️ | ✔️
|
||||
split-pdf-by-sections | ✔️ | ✔️ | ✔️
|
||||
split-pdfs | ✔️ | ✔️ | ✔️
|
||||
file-to-pdf | | ✔️ | ✔️
|
||||
pdf-to-html | | ✔️ | ✔️
|
||||
pdf-to-presentation | | ✔️ | ✔️
|
||||
pdf-to-text | | ✔️ | ✔️
|
||||
pdf-to-word | | ✔️ | ✔️
|
||||
pdf-to-xml | | ✔️ | ✔️
|
||||
repair | | ✔️ | ✔️
|
||||
xlsx-to-pdf | | ✔️ | ✔️
|
||||
compress-pdf | | | ✔️
|
||||
extract-image-scans | | | ✔️
|
||||
ocr-pdf | | | ✔️
|
||||
pdf-to-pdfa | | | ✔️
|
||||
remove-blanks | | | ✔️
|
||||
|
||||
14
build.gradle
@@ -89,10 +89,10 @@ dependencies {
|
||||
//security updates
|
||||
implementation 'ch.qos.logback:logback-classic:1.4.14'
|
||||
implementation 'ch.qos.logback:logback-core:1.4.14'
|
||||
implementation 'org.springframework:spring-webmvc:6.1.2'
|
||||
implementation 'org.springframework:spring-webmvc:6.1.3'
|
||||
|
||||
implementation("io.github.pixee:java-security-toolkit:1.1.2")
|
||||
|
||||
|
||||
implementation 'org.yaml:snakeyaml:2.2'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web:3.2.2'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.2.2'
|
||||
@@ -101,7 +101,7 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-security:3.2.2'
|
||||
implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE'
|
||||
implementation "org.springframework.boot:spring-boot-starter-data-jpa:3.2.2"
|
||||
|
||||
|
||||
//2.2.x requires rebuild of DB file.. need migration path
|
||||
implementation "com.h2database:h2:2.1.214"
|
||||
}
|
||||
@@ -138,19 +138,19 @@ dependencies {
|
||||
implementation ('com.opencsv:opencsv:5.9') {
|
||||
exclude group: 'commons-logging', module: 'commons-logging'
|
||||
}
|
||||
|
||||
|
||||
implementation ('org.apache.pdfbox:pdfbox:3.0.1'){
|
||||
exclude group: 'commons-logging', module: 'commons-logging'
|
||||
}
|
||||
|
||||
|
||||
implementation ('org.apache.pdfbox:xmpbox:3.0.1'){
|
||||
exclude group: 'commons-logging', module: 'commons-logging'
|
||||
}
|
||||
|
||||
|
||||
implementation 'org.bouncycastle:bcprov-jdk18on:1.77'
|
||||
implementation 'org.bouncycastle:bcpkix-jdk18on:1.77'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-actuator:3.2.2'
|
||||
implementation 'io.micrometer:micrometer-core:1.12.2'
|
||||
implementation 'io.micrometer:micrometer-core:1.12.3'
|
||||
implementation group: 'com.google.zxing', name: 'core', version: '3.5.2'
|
||||
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
||||
implementation 'org.commonmark:commonmark:0.21.0'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
apiVersion: v2
|
||||
appVersion: 0.14.2
|
||||
appVersion: 0.20.2
|
||||
description: locally hosted web application that allows you to perform various operations on PDF files
|
||||
home: https://github.com/Stirling-Tools/Stirling-PDF
|
||||
keywords:
|
||||
|
||||
@@ -43,6 +43,6 @@ spec:
|
||||
name: http
|
||||
{{- end }}
|
||||
protocol: TCP
|
||||
|
||||
|
||||
selector:
|
||||
{{- include "stirlingpdf.selectorLabels" . | nindent 4 }}
|
||||
|
||||
@@ -16,11 +16,11 @@ commonLabels: {}
|
||||
# team_name: dev
|
||||
|
||||
envs: []
|
||||
# - name: PP_HOME_NAME
|
||||
# - name: UI_APP_NAME
|
||||
# value: "Stirling PDF"
|
||||
# - name: APP_HOME_DESCRIPTION
|
||||
# - name: UI_HOME_DESCRIPTION
|
||||
# value: "Your locally hosted one-stop-shop for all your PDF needs."
|
||||
# - name: APP_NAVBAR_NAME
|
||||
# - name: UI_APP_NAVBAR_NAME
|
||||
# value: "Stirling PDF"
|
||||
# - name: ALLOW_GOOGLE_VISIBILITY
|
||||
# value: "true"
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs173">
|
||||
|
||||
|
||||
|
||||
|
||||
<linearGradient
|
||||
id="XMLID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
@@ -37,7 +37,7 @@
|
||||
style="stop-color:#C2C2C9"
|
||||
id="stop158" />
|
||||
</linearGradient>
|
||||
|
||||
|
||||
</defs><sodipodi:namedview
|
||||
id="namedview171"
|
||||
pagecolor="#ffffff"
|
||||
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -15,7 +15,7 @@ services:
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /stirling/latest/data:/usr/share/tesseract-ocr/5/tessdata:rw
|
||||
- /stirling/latest/data:/usr/share/tessdata:rw
|
||||
- /stirling/latest/config:/configs:rw
|
||||
- /stirling/latest/logs:/logs:rw
|
||||
environment:
|
||||
|
||||
@@ -15,7 +15,7 @@ services:
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /stirling/latest/data:/usr/share/tesseract-ocr/5/tessdata:rw
|
||||
- /stirling/latest/data:/usr/share/tessdata:rw
|
||||
- /stirling/latest/config:/configs:rw
|
||||
- /stirling/latest/logs:/logs:rw
|
||||
environment:
|
||||
|
||||
@@ -15,7 +15,7 @@ services:
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /stirling/latest/data:/usr/share/tesseract-ocr/5/tessdata:rw
|
||||
- /stirling/latest/data:/usr/share/tessdata:rw
|
||||
- /stirling/latest/config:/configs:rw
|
||||
- /stirling/latest/logs:/logs:rw
|
||||
environment:
|
||||
|
||||
@@ -15,7 +15,7 @@ services:
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- /stirling/latest/data:/usr/share/tesseract-ocr/5/tessdata:rw
|
||||
- /stirling/latest/data:/usr/share/tessdata:rw
|
||||
- /stirling/latest/config:/configs:rw
|
||||
- /stirling/latest/logs:/logs:rw
|
||||
environment:
|
||||
|
||||
182
gradlew.bat
vendored
@@ -1,91 +1,91 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import cv2
|
||||
import sys
|
||||
import argparse
|
||||
import numpy as np
|
||||
|
||||
def is_blank_image(image_path, threshold=10, white_percent=99, white_value=255, blur_size=5):
|
||||
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
|
||||
|
||||
if image is None:
|
||||
print(f"Error: Unable to read the image file: {image_path}")
|
||||
return False
|
||||
|
||||
# Apply Gaussian blur to reduce noise
|
||||
blurred_image = cv2.GaussianBlur(image, (blur_size, blur_size), 0)
|
||||
|
||||
_, thresholded_image = cv2.threshold(blurred_image, white_value - threshold, white_value, cv2.THRESH_BINARY)
|
||||
|
||||
# Calculate the percentage of white pixels in the thresholded image
|
||||
white_pixels = np.sum(thresholded_image == white_value)
|
||||
white_pixel_percentage = (white_pixels / thresholded_image.size) * 100
|
||||
|
||||
print(f"Page has white pixel percent of {white_pixel_percentage}")
|
||||
return white_pixel_percentage >= white_percent
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Detect if an image is considered blank or not.')
|
||||
parser.add_argument('image_path', help='The path to the image file.')
|
||||
parser.add_argument('-t', '--threshold', type=int, default=10, help='Threshold for determining white pixels. The default value is 10.')
|
||||
parser.add_argument('-w', '--white_percent', type=float, default=99, help='The percentage of white pixels for an image to be considered blank. The default value is 99.')
|
||||
args = parser.parse_args()
|
||||
|
||||
blank = is_blank_image(args.image_path, args.threshold, args.white_percent)
|
||||
|
||||
# Return code 1: The image is considered blank.
|
||||
# Return code 0: The image is not considered blank.
|
||||
sys.exit(int(blank))
|
||||
@@ -4,7 +4,7 @@ if [ "$DOCKER_ENABLE_SECURITY" = "true" ] && [ "$VERSION_TAG" != "alpha" ]; then
|
||||
if [ ! -f app-security.jar ]; then
|
||||
echo "Trying to download from: https://github.com/Stirling-Tools/Stirling-PDF/releases/download/v$VERSION_TAG/Stirling-PDF-with-login.jar"
|
||||
curl -L -o app-security.jar https://github.com/Stirling-Tools/Stirling-PDF/releases/download/v$VERSION_TAG/Stirling-PDF-with-login.jar
|
||||
|
||||
|
||||
# If the first download attempt failed, try with the 'v' prefix
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Trying to download from: https://github.com/Stirling-Tools/Stirling-PDF/releases/download/$VERSION_TAG/Stirling-PDF-with-login.jar"
|
||||
|
||||
@@ -2,7 +2,7 @@ import argparse
|
||||
import sys
|
||||
import cv2
|
||||
import numpy as np
|
||||
import os
|
||||
import os
|
||||
|
||||
def find_photo_boundaries(image, background_color, tolerance=30, min_area=10000, min_contour_area=500):
|
||||
mask = cv2.inRange(image, background_color - tolerance, background_color + tolerance)
|
||||
@@ -49,9 +49,9 @@ def auto_rotate(image, angle_threshold=1):
|
||||
angles = []
|
||||
for rho, theta in lines[:, 0]:
|
||||
angles.append((theta * 180) / np.pi - 90)
|
||||
|
||||
|
||||
angle = np.median(angles)
|
||||
|
||||
|
||||
if abs(angle) < angle_threshold:
|
||||
return image
|
||||
|
||||
@@ -65,16 +65,16 @@ def auto_rotate(image, angle_threshold=1):
|
||||
|
||||
def crop_borders(image, border_color, tolerance=30):
|
||||
mask = cv2.inRange(image, border_color - tolerance, border_color + tolerance)
|
||||
|
||||
|
||||
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
||||
if len(contours) == 0:
|
||||
return image
|
||||
|
||||
largest_contour = max(contours, key=cv2.contourArea)
|
||||
x, y, w, h = cv2.boundingRect(largest_contour)
|
||||
|
||||
|
||||
return image[y:y+h, x:x+w]
|
||||
|
||||
|
||||
def split_photos(input_file, output_directory, tolerance=30, min_area=10000, min_contour_area=500, angle_threshold=10, border_size=0):
|
||||
image = cv2.imread(input_file)
|
||||
background_color = estimate_background_color(image)
|
||||
@@ -110,7 +110,7 @@ if __name__ == "__main__":
|
||||
parser.add_argument("--min_contour_area", type=int, default=500, help="Sets the minimum contour area threshold for a photo (default: 500).")
|
||||
parser.add_argument("--angle_threshold", type=int, default=10, help="Sets the minimum absolute angle required for the image to be rotated (default: 10).")
|
||||
parser.add_argument("--border_size", type=int, default=0, help="Sets the size of the border added and removed to prevent white borders in the output (default: 0).")
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
split_photos(args.input_file, args.output_directory, tolerance=args.tolerance, min_area=args.min_area, min_contour_area=args.min_contour_area, angle_threshold=args.angle_threshold, border_size=args.border_size)
|
||||
|
||||
@@ -79,6 +79,16 @@ public class ConfigInitializer
|
||||
return parts.length > 0 ? parts[0].trim().replace("#", "").trim() : "";
|
||||
};
|
||||
|
||||
Function<String, Integer> getIndentationLevel =
|
||||
line -> {
|
||||
int count = 0;
|
||||
for (char ch : line.toCharArray()) {
|
||||
if (ch == ' ') count++;
|
||||
else break;
|
||||
}
|
||||
return count;
|
||||
};
|
||||
|
||||
Set<String> userKeys = userLines.stream().map(extractKey).collect(Collectors.toSet());
|
||||
|
||||
for (String line : templateLines) {
|
||||
@@ -134,10 +144,77 @@ public class ConfigInitializer
|
||||
.map(extractKey)
|
||||
.anyMatch(templateKey -> templateKey.equalsIgnoreCase(userKey));
|
||||
if (!isPresentInTemplate && !isCommented.apply(userLine)) {
|
||||
mergedLines.add(userLine);
|
||||
if (!childOfTemplateEntry(
|
||||
isCommented,
|
||||
extractKey,
|
||||
getIndentationLevel,
|
||||
userLines,
|
||||
userLine,
|
||||
templateLines)) {
|
||||
// check if userLine is a child of a entry within templateLines or not, if child
|
||||
// of parent in templateLines then dont add to mergedLines, if anything else
|
||||
// then add
|
||||
mergedLines.add(userLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Files.write(outputPath, mergedLines, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
// New method to check if a userLine is a child of an entry in templateLines
|
||||
boolean childOfTemplateEntry(
|
||||
Function<String, Boolean> isCommented,
|
||||
Function<String, String> extractKey,
|
||||
Function<String, Integer> getIndentationLevel,
|
||||
List<String> userLines,
|
||||
String userLine,
|
||||
List<String> templateLines) {
|
||||
String userKey = extractKey.apply(userLine).trim();
|
||||
int userIndentation = getIndentationLevel.apply(userLine);
|
||||
|
||||
// Start by assuming the line is not a child of an entry in templateLines
|
||||
boolean isChild = false;
|
||||
|
||||
// Iterate backwards through userLines from the current line to find any parent
|
||||
for (int i = userLines.indexOf(userLine) - 1; i >= 0; i--) {
|
||||
String potentialParentLine = userLines.get(i);
|
||||
int parentIndentation = getIndentationLevel.apply(potentialParentLine);
|
||||
|
||||
// Check if we've reached a potential parent based on indentation
|
||||
if (parentIndentation < userIndentation) {
|
||||
String parentKey = extractKey.apply(potentialParentLine).trim();
|
||||
|
||||
// Now, check if this potential parent or any of its parents exist in templateLines
|
||||
boolean parentExistsInTemplate =
|
||||
templateLines.stream()
|
||||
.filter(line -> !isCommented.apply(line)) // Skip commented lines
|
||||
.anyMatch(
|
||||
templateLine -> {
|
||||
String templateKey =
|
||||
extractKey.apply(templateLine).trim();
|
||||
return parentKey.equalsIgnoreCase(templateKey);
|
||||
});
|
||||
|
||||
if (!parentExistsInTemplate) {
|
||||
// If the parent does not exist in template, check the next level parent
|
||||
userIndentation =
|
||||
parentIndentation; // Update userIndentation to the parent's indentation
|
||||
// for next iteration
|
||||
if (parentIndentation == 0) {
|
||||
// If we've reached the top-level parent and it's not in template, the
|
||||
// original line is considered not a child
|
||||
isChild = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// If any parent exists in template, the original line is considered a child
|
||||
isChild = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isChild; // Return true if the line is not a child of any entry in templateLines
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,6 @@ public class EndpointConfiguration {
|
||||
// CLI
|
||||
addEndpointToGroup("CLI", "compress-pdf");
|
||||
addEndpointToGroup("CLI", "extract-image-scans");
|
||||
addEndpointToGroup("CLI", "remove-blanks");
|
||||
addEndpointToGroup("CLI", "repair");
|
||||
addEndpointToGroup("CLI", "pdf-to-pdfa");
|
||||
addEndpointToGroup("CLI", "file-to-pdf");
|
||||
@@ -218,6 +217,7 @@ public class EndpointConfiguration {
|
||||
addEndpointToGroup("Java", "split-by-size-or-count");
|
||||
addEndpointToGroup("Java", "overlay-pdf");
|
||||
addEndpointToGroup("Java", "split-pdf-by-sections");
|
||||
addEndpointToGroup("Java", "remove-blanks");
|
||||
|
||||
// Javascript
|
||||
addEndpointToGroup("Javascript", "pdf-organizer");
|
||||
|
||||
@@ -9,6 +9,9 @@ import org.springframework.security.authentication.dao.DaoAuthenticationProvider
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.core.session.SessionRegistry;
|
||||
import org.springframework.security.core.session.SessionRegistryImpl;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
@@ -44,6 +47,11 @@ public class SecurityConfiguration {
|
||||
|
||||
@Autowired private FirstLoginFilter firstLoginFilter;
|
||||
|
||||
@Bean
|
||||
public SessionRegistry sessionRegistry() {
|
||||
return new SessionRegistryImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.addFilterBefore(userAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
@@ -53,6 +61,14 @@ public class SecurityConfiguration {
|
||||
http.csrf(csrf -> csrf.disable());
|
||||
http.addFilterBefore(rateLimitingFilter(), UsernamePasswordAuthenticationFilter.class);
|
||||
http.addFilterAfter(firstLoginFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
http.sessionManagement(
|
||||
sessionManagement ->
|
||||
sessionManagement
|
||||
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
|
||||
.maximumSessions(3)
|
||||
.maxSessionsPreventsLogin(true)
|
||||
.sessionRegistry(sessionRegistry())
|
||||
.expiredUrl("/login?logout=true"));
|
||||
http.formLogin(
|
||||
formLogin ->
|
||||
formLogin
|
||||
|
||||
@@ -10,6 +10,9 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.session.SessionInformation;
|
||||
import org.springframework.security.core.session.SessionRegistry;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
@@ -228,11 +231,27 @@ public class UserController {
|
||||
if (currentUsername.equals(username)) {
|
||||
throw new IllegalArgumentException("Cannot delete currently logined in user.");
|
||||
}
|
||||
|
||||
invalidateUserSessions(username);
|
||||
userService.deleteUser(username);
|
||||
return "redirect:/addUsers";
|
||||
}
|
||||
|
||||
@Autowired private SessionRegistry sessionRegistry;
|
||||
|
||||
private void invalidateUserSessions(String username) {
|
||||
for (Object principal : sessionRegistry.getAllPrincipals()) {
|
||||
if (principal instanceof UserDetails) {
|
||||
UserDetails userDetails = (UserDetails) principal;
|
||||
if (userDetails.getUsername().equals(username)) {
|
||||
for (SessionInformation session :
|
||||
sessionRegistry.getAllSessions(principal, false)) {
|
||||
session.expireNow();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PreAuthorize("!hasAuthority('ROLE_DEMO_USER')")
|
||||
@PostMapping("/get-api-key")
|
||||
public ResponseEntity<String> getApiKey(Principal principal) {
|
||||
|
||||
@@ -41,7 +41,7 @@ public class OCRController {
|
||||
private static final Logger logger = LoggerFactory.getLogger(OCRController.class);
|
||||
|
||||
public List<String> getAvailableTesseractLanguages() {
|
||||
String tessdataDir = "/usr/share/tesseract-ocr/5/tessdata";
|
||||
String tessdataDir = "/usr/share/tessdata";
|
||||
File[] files = new File(tessdataDir).listFiles();
|
||||
if (files == null) {
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -33,6 +33,8 @@ public class AccountWebController {
|
||||
return "redirect:/";
|
||||
}
|
||||
|
||||
model.addAttribute("currentPage", "login");
|
||||
|
||||
if (request.getParameter("error") != null) {
|
||||
|
||||
model.addAttribute("error", request.getParameter("error"));
|
||||
@@ -112,6 +114,7 @@ public class AccountWebController {
|
||||
model.addAttribute("role", user.get().getRolesAsString());
|
||||
model.addAttribute("settings", settingsJson);
|
||||
model.addAttribute("changeCredsFlag", user.get().isFirstLogin());
|
||||
model.addAttribute("currentPage", "account");
|
||||
}
|
||||
} else {
|
||||
return "redirect:/";
|
||||
|
||||
@@ -82,7 +82,7 @@ public class OtherWebController {
|
||||
}
|
||||
|
||||
public List<String> getAvailableTesseractLanguages() {
|
||||
String tessdataDir = "/usr/share/tesseract-ocr/5/tessdata";
|
||||
String tessdataDir = "/usr/share/tessdata";
|
||||
File[] files = new File(tessdataDir).listFiles();
|
||||
if (files == null) {
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -12,6 +12,6 @@ public class PdfToTextOrRTFRequest extends PDFFile {
|
||||
|
||||
@Schema(
|
||||
description = "The output Text or RTF format",
|
||||
allowableValues = {"rtf", "txt:Text"})
|
||||
allowableValues = {"rtf", "txt"})
|
||||
private String outputFormat;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ server.servlet.context-path=${SYSTEM_ROOTURIPATH:/}
|
||||
spring.devtools.restart.enabled=true
|
||||
spring.devtools.livereload.enabled=true
|
||||
|
||||
spring.thymeleaf.encoding=UTF-8
|
||||
spring.thymeleaf.encoding=UTF-8
|
||||
|
||||
server.connection-timeout=${SYSTEM_CONNECTIONTIMEOUTMINUTES:5m}
|
||||
spring.mvc.async.request-timeout=${SYSTEM_CONNECTIONTIMEOUTMILLISECONDS:300000}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
____ _____ ___ ____ _ ___ _ _ ____ ____ ____ _____
|
||||
____ _____ ___ ____ _ ___ _ _ ____ ____ ____ _____
|
||||
/ ___|_ _|_ _| _ \| | |_ _| \ | |/ ___| | _ \| _ \| ___|
|
||||
\___ \ | | | || |_) | | | || \| | | _ _____| |_) | | | | |_
|
||||
___) || | | || _ <| |___ | || |\ | |_| |_____| __/| |_| | _|
|
||||
|____/ |_| |___|_| \_\_____|___|_| \_|\____| |_| |____/|_|
|
||||
\___ \ | | | || |_) | | | || \| | | _ _____| |_) | | | | |_
|
||||
___) || | | || _ <| |___ | || |\ | |_| |_____| __/| |_| | _|
|
||||
|____/ |_| |___|_| \_\_____|___|_| \_|\____| |_| |____/|_|
|
||||
Powered by Spring Boot ${spring-boot.version}
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=Изберете изображение(я)
|
||||
genericSubmit=Подайте
|
||||
processTimeWarning=Предупреждение: Този процес може да отнеме до минута в зависимост от размера на файла
|
||||
pageOrderPrompt=Персонализиран ред на страниците (Въведете разделен със запетаи списък с номера на страници или функции като 2n+1):
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Давай
|
||||
true=Вярно
|
||||
false=Невярно
|
||||
@@ -19,6 +20,7 @@ save=Съхранете
|
||||
close=Затворете
|
||||
filesSelected=избрани файлове
|
||||
noFavourites=Няма добавени любими
|
||||
downloadComplete=Download Complete
|
||||
bored=Отекчени сте да чакате?
|
||||
alphabet=Азбука
|
||||
downloadPdf=Изтеглете PDF
|
||||
@@ -42,7 +44,7 @@ red=Червено
|
||||
green=Зелено
|
||||
blue=Синьо
|
||||
custom=Персонализиране...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=Настройки на акаунта
|
||||
account.adminSettings=Настройки на администратора - Преглед и добавяне на потребители
|
||||
account.userControlSettings=Настройки за потребителски контрол
|
||||
account.changeUsername=Промени потребител
|
||||
account.changeUsername=Промени потребител
|
||||
account.newUsername=Ново потребителско име
|
||||
account.password=Парола за потвърждение
|
||||
account.oldPassword=Стара парола
|
||||
account.newPassword=Нова парола
|
||||
@@ -362,11 +364,11 @@ PdfToSinglePage.tags=единична страница
|
||||
|
||||
home.showJS.title=Показване на Javascript
|
||||
home.showJS.desc=Търси и показва всеки JS, инжектиран в PDF
|
||||
showJS.tags=Редактиране,Скриване,затъмняване,черен,маркер,скрит
|
||||
showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=Автоматично редактиране
|
||||
home.autoRedact.desc=Автоматично редактира (зачернява) текст в PDF въз основа на въведен текст
|
||||
showJS.tags=Редактиране,Скриване,затъмняване,черен,маркер,скрит
|
||||
autoRedact.tags=Редактиране,Скриване,затъмняване,черен,маркер,скрит
|
||||
|
||||
home.tableExtraxt.title=PDF to CSV
|
||||
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
||||
@@ -410,7 +412,7 @@ autoRedact.title=Автоматично редактиране
|
||||
autoRedact.header=Автоматично редактиране
|
||||
autoRedact.colorLabel=Цвят
|
||||
autoRedact.textsToRedactLabel=Текст за редактиране (разделен с редове)
|
||||
autoRedact.textsToRedactPlaceholder=например: \nПоверително \nСтрого секретно
|
||||
autoRedact.textsToRedactPlaceholder=например: \nПоверително \nСтрого секретно
|
||||
autoRedact.useRegexLabel=Използване на Regex
|
||||
autoRedact.wholeWordSearchLabel=Търсене на цялата дума
|
||||
autoRedact.customPaddingLabel=Персонализирана допълнителна подложка
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=Дезинфектирай PDF
|
||||
sanitizePDF.header=Дезинфектира PDF файл
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=Задава минималния праг на
|
||||
ScannerImageSplit.selectText.9=Размер на рамката:
|
||||
ScannerImageSplit.selectText.10=Задава размера на добавената и премахната граница, за да предотврати бели граници към изхода (по подразбиране: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / Почистване на сканиране
|
||||
ocr.header=Почистващи сканирания / OCR (оптично разпознаване на знаци)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=Автоматично завъртане на PDF
|
||||
imageToPDF.selectText.3=Файлова логика с много (Активирано само ако работите с множество изображения)
|
||||
imageToPDF.selectText.4=Сливане към един PDF
|
||||
imageToPDF.selectText.5=Преобразуване към отделни PDF файлове
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF към Изображение
|
||||
pdfToImage.header=PDF към Изображение
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=Ключови думи:
|
||||
changeMetadata.modDate=Дата на промяна (гггг/ММ/дд ЧЧ:мм:сс):
|
||||
changeMetadata.producer=Продуцент:
|
||||
changeMetadata.subject=Тема:
|
||||
changeMetadata.title=Заглавие:
|
||||
changeMetadata.trapped=В капан:
|
||||
changeMetadata.selectText.4=Други метаданни:
|
||||
changeMetadata.selectText.5=Добавяне на персонализиране метаданни
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=\u0395\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE \u0395\u03B9\u03BA\u03CC\u0
|
||||
genericSubmit=\u03A5\u03C0\u03BF\u03B2\u03BF\u03BB\u03AE
|
||||
processTimeWarning=\u03A0\u03C1\u03BF\u03C3\u03BF\u03C7\u03AE: \u0391\u03C5\u03C4\u03AE \u03B7 \u03B4\u03B9\u03B1\u03B4\u03B9\u03BA\u03B1\u03C3\u03AF\u03B1 \u03BC\u03C0\u03BF\u03C1\u03B5\u03AF \u03BD\u03B1 \u03B4\u03B9\u03B1\u03C1\u03BA\u03AD\u03C3\u03B5\u03B9 \u03AD\u03C9\u03C2 \u03BA\u03B1\u03B9 \u03AD\u03BD\u03B1 \u03BB\u03B5\u03C0\u03C4\u03CC \u03B1\u03BD\u03AC\u03BB\u03BF\u03B3\u03B1 \u03BC\u03B5 \u03C4\u03BF \u03BC\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 \u03C4\u03BF\u03C5 \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF\u03C5
|
||||
pageOrderPrompt=\u03A0\u03C1\u03BF\u03C3\u03B1\u03C1\u03BC\u03BF\u03C3\u03BC\u03AD\u03BD\u03B7 \u03A3\u03B5\u03B9\u03C1\u03AC \u03A3\u03B5\u03BB\u03AF\u03B4\u03B1\u03C2 (\u03A0\u03C1\u03BF\u03C3\u03B8\u03AD\u03C3\u03C4\u03B5 \u03BC\u03AF\u03B1 \u03BB\u03AF\u03C3\u03C4\u03B5 \u03B1\u03C0\u03BF \u03B1\u03C1\u03B9\u03B8\u03BC\u03BF\u03CD\u03C2 \u03C3\u03B5\u03BB\u03B9\u03B4\u03CE\u03BD, \u03C7\u03C9\u03C1\u03B9\u03C3\u03BC\u03AD\u03BD\u03B5\u03C2 \u03BC\u03B5 \u03BA\u03CC\u03BC\u03BC\u03B1 \u03AE \u03C3\u03C5\u03BD\u03B1\u03C1\u03C4\u03AE\u03C3\u03B5\u03B9\u03C2 \u03CC\u03C0\u03C9\u03C2 2n+1) :
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Go
|
||||
true=\u0391\u03BB\u03B7\u03B8\u03AD\u03C2
|
||||
false=\u039B\u03B1\u03BD\u03B8\u03B1\u03C3\u03BC\u03AD\u03BD\u03BF
|
||||
@@ -19,6 +20,7 @@ save=\u0391\u03C0\u03BF\u03B8\u03AE\u03BA\u03B5\u03C5\u03C3\u03B7
|
||||
close=\u039A\u03BB\u03B5\u03AF\u03C3\u03B9\u03BC\u03BF
|
||||
filesSelected=\u03B1\u03C1\u03C7\u03B5\u03AF\u03B1 \u03C0\u03BF\u03C5 \u03B5\u03C0\u03B9\u03BB\u03AD\u03C7\u03B8\u03B7\u03BA\u03B1\u03BD
|
||||
noFavourites=\u039A\u03B1\u03BD\u03AD\u03BD\u03B1 \u03B1\u03B3\u03B1\u03C0\u03AE\u03BC\u03B5\u03BD\u03BF \u03B4\u03B5\u03BD \u03AD\u03C7\u03B5\u03B9 \u03C0\u03C1\u03BF\u03C3\u03C4\u03B5\u03B8\u03B5\u03AF
|
||||
downloadComplete=Download Complete
|
||||
bored=\u0392\u03B1\u03C1\u03B9\u03AD\u03C3\u03C4\u03B5 \u03BD\u03B1 \u03C0\u03B5\u03C1\u03B9\u03BC\u03AD\u03BD\u03B5\u03C4\u03B5;
|
||||
alphabet=\u0391\u03BB\u03C6\u03AC\u03B2\u03B7\u03C4\u03BF
|
||||
downloadPdf=\u039A\u03B1\u03C4\u03AD\u03B2\u03B1\u03C3\u03BC\u03B1 \u03C4\u03BF\u03C5 PDF
|
||||
@@ -42,7 +44,7 @@ red=\u039A\u03CC\u03BA\u03BA\u03B9\u03BD\u03BF
|
||||
green=\u03A0\u03C1\u03AC\u03C3\u03B9\u03BD\u03BF
|
||||
blue=\u039C\u03C0\u03BB\u03AD
|
||||
custom=\u03A0\u03C1\u03BF\u03C3\u03B1\u03C1\u03BC\u03BF\u03B3\u03AE...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=\u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2 \
|
||||
account.adminSettings=\u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2 \u0394\u03B9\u03B1\u03C7\u03B5\u03B9\u03C1\u03B9\u03C3\u03C4\u03AE - \u03A0\u03C1\u03BF\u03B2\u03BF\u03BB\u03AE \u03BA\u03B1\u03B9 \u03C0\u03C1\u03BF\u03C3\u03B8\u03AE\u03BA\u03B7 \u03C7\u03C1\u03B7\u03C3\u03C4\u03CE\u03BD
|
||||
account.userControlSettings=\u03A1\u03C5\u03B8\u03BC\u03AF\u03C3\u03B5\u03B9\u03C2 \u03A7\u03B5\u03B9\u03C1\u03B9\u03C3\u03BC\u03BF\u03CD \u03A7\u03C1\u03B7\u03C3\u03C4\u03CE\u03BD
|
||||
account.changeUsername=\u0391\u03BB\u03BB\u03B1\u03B3\u03AE \u039F\u03BD\u03CC\u03BC\u03B1\u03C4\u03BF\u03C2 \u03A7\u03C1\u03AE\u03C3\u03C4\u03B7
|
||||
account.changeUsername=\u0391\u03BB\u03BB\u03B1\u03B3\u03AE \u039F\u03BD\u03CC\u03BC\u03B1\u03C4\u03BF\u03C2 \u03A7\u03C1\u03AE\u03C3\u03C4\u03B7
|
||||
account.newUsername=\u039d\u03ad\u03bf \u038c\u03bd\u03bf\u03bc\u03b1 \u03a7\u03c1\u03ae\u03c3\u03c4\u03b7
|
||||
account.password=\u0395\u03C0\u03B9\u03B2\u03B5\u03B2\u03B1\u03AF\u03C9\u03C3\u03B7 \u039A\u03C9\u03B4\u03B9\u03BA\u03BF\u03CD \u03A0\u03C1\u03CC\u03C3\u03B2\u03B1\u03C3\u03B7\u03C2
|
||||
account.oldPassword=\u03A0\u03B1\u03BB\u03B9\u03CC\u03C2 \u039A\u03C9\u03B4\u03B9\u03BA\u03CC\u03C2 \u03A0\u03C1\u03CC\u03C3\u03B2\u03B1\u03C3\u03B7\u03C2
|
||||
account.newPassword=\u039D\u03AD\u03BF\u03C2 \u039A\u03C9\u03B4\u03B9\u03BA\u03CC\u03C2 \u03A0\u03C1\u03CC\u03C3\u03B2\u03B1\u03C3\u03B7\u03C2
|
||||
@@ -362,11 +364,11 @@ PdfToSinglePage.tags=single page
|
||||
|
||||
home.showJS.title=\u0395\u03BC\u03C6\u03AC\u03BD\u03B9\u03C3\u03B7 Javascript
|
||||
home.showJS.desc=\u0391\u03BD\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7 \u03BA\u03B1\u03B9 \u03B5\u03BC\u03C6\u03AC\u03BD\u03B9\u03C3\u03B7 \u03BA\u03CE\u03B4\u03B9\u03BA\u03B1 Javascript \u03C0\u03BF\u03C5 \u03B5\u03AF\u03BD\u03B1\u03B9 \u03B5\u03BD\u03C3\u03C9\u03BC\u03B1\u03C4\u03C9\u03BC\u03AD\u03BD\u03BF \u03BC\u03AD\u03C3\u03B1 \u03C3\u03B5 \u03AD\u03BD\u03B1 PDF
|
||||
showJS.tags=Redact,Hide,black out,black,marker,hidden
|
||||
showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=\u0391\u03C5\u03C4\u03CC\u03BC\u03B1\u03C4\u03BF \u039C\u03B1\u03CD\u03C1\u03B9\u03C3\u03BC\u03B1 \u039A\u03B5\u03B9\u03BC\u03AD\u03BD\u03BF\u03C5
|
||||
home.autoRedact.desc=\u0391\u03C5\u03C4\u03CC\u03BC\u03B1\u03C4\u03B7 \u03B5\u03C0\u03B5\u03BE\u03B5\u03C1\u03B3\u03B1\u03C3\u03AF\u03B1 (\u039C\u03B1\u03CD\u03C1\u03B9\u03C3\u03BC\u03B1) \u03BA\u03B5\u03AF\u03BC\u03B5\u03BD\u03BF\u03C5 \u03C3\u03B5 PDF \u03BC\u03B5 \u03B2\u03AC\u03C3\u03B7 \u03C4\u03BF \u03BA\u03B5\u03AF\u03BC\u03B5\u03BD\u03BF \u03B5\u03B9\u03C3\u03B1\u03B3\u03C9\u03B3\u03AE\u03C2
|
||||
showJS.tags=Redact,Hide,black out,black,marker,hidden
|
||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||
|
||||
home.tableExtraxt.title=PDF to CSV
|
||||
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
||||
@@ -410,7 +412,7 @@ autoRedact.title=\u0391\u03C5\u03C4\u03CC\u03BC\u03B1\u03C4\u03BF \u039C\u03B1\u
|
||||
autoRedact.header=\u0391\u03C5\u03C4\u03CC\u03BC\u03B1\u03C4\u03BF \u039C\u03B1\u03CD\u03C1\u03B9\u03C3\u03BC\u03B1 \u039A\u03B5\u03B9\u03BC\u03AD\u03BD\u03BF\u03C5
|
||||
autoRedact.colorLabel=\u03A7\u03C1\u03CE\u03BC\u03B1
|
||||
autoRedact.textsToRedactLabel=\u039A\u03B5\u03AF\u03BC\u03B5\u03BD\u03BF \u03B3\u03B9\u03B1 \u03BC\u03B1\u03CD\u03C1\u03B9\u03C3\u03BC\u03B1 (\u03B4\u03B9\u03B1\u03C7\u03C9\u03C1\u03B9\u03C3\u03BC\u03AD\u03BD\u03BF \u03C3\u03B5 \u03B3\u03C1\u03B1\u03BC\u03BC\u03AD\u03C2)
|
||||
autoRedact.textsToRedactPlaceholder=\u03C0.\u03C7. \n\u0395\u03BC\u03C0\u03B9\u03C3\u03C4\u03B5\u03C5\u03C4\u03B9\u03BA\u03CC \n\u0391\u03BA\u03C1\u03CE\u03C2 \u03B1\u03C0\u03CC\u03C1\u03C1\u03B7\u03C4\u03BF
|
||||
autoRedact.textsToRedactPlaceholder=\u03C0.\u03C7. \n\u0395\u03BC\u03C0\u03B9\u03C3\u03C4\u03B5\u03C5\u03C4\u03B9\u03BA\u03CC \n\u0391\u03BA\u03C1\u03CE\u03C2 \u03B1\u03C0\u03CC\u03C1\u03C1\u03B7\u03C4\u03BF
|
||||
autoRedact.useRegexLabel=\u03A7\u03C1\u03AE\u03C3\u03B7 Regex
|
||||
autoRedact.wholeWordSearchLabel=\u0391\u03BD\u03B1\u03B6\u03AE\u03C4\u03B7\u03C3\u03B7 \u03BF\u03BB\u03CC\u03BA\u03BB\u03B7\u03C1\u03B7\u03C2 \u03C4\u03B7\u03C2 \u03BB\u03AD\u03BE\u03B7\u03C2
|
||||
autoRedact.customPaddingLabel=Custom Extra Padding
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=\u0391\u03C0\u03BF\u03BB\u03CD\u03BC\u03B1\u03BD\u03C3\u03B7 PDF
|
||||
sanitizePDF.header=\u0391\u03C0\u03BF\u03BB\u03CD\u03BC\u03B1\u03BD\u03C3\u03B7 \u03B5\u03BD\u03CC\u03C2 PDF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF\u03C5
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=\u03A1\u03C5\u03B8\u03BC\u03AF\u03B6\u03B5\u03B9
|
||||
ScannerImageSplit.selectText.9=\u039C\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03BF\u03C2:
|
||||
ScannerImageSplit.selectText.10=\u039F\u03C1\u03AF\u03B6\u03B5\u03B9 \u03C4\u03BF \u03BC\u03AD\u03B3\u03B5\u03B8\u03BF\u03C2 \u03C4\u03BF\u03C5 \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03BF\u03C2 \u03C0\u03BF\u03C5 \u03C0\u03C1\u03BF\u03C3\u03C4\u03AF\u03B8\u03B5\u03C4\u03B1\u03B9 \u03BA\u03B1\u03B9 \u03B1\u03C6\u03B1\u03B9\u03C1\u03B5\u03AF\u03C4\u03B1\u03B9 \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03B1\u03C0\u03BF\u03C4\u03C1\u03AD\u03C0\u03BF\u03BD\u03C4\u03B1\u03B9 \u03BB\u03B5\u03C5\u03BA\u03AC \u03C0\u03B5\u03C1\u03B9\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03B1 \u03C3\u03C4\u03B7\u03BD \u03AD\u03BE\u03BF\u03B4\u03BF (\u03C0\u03C1\u03BF\u03B5\u03C0\u03B9\u03BB\u03BF\u03B3\u03AE: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=\u039F\u03C0\u03C4\u03B9\u03BA\u03AE \u03B1\u03BD\u03B1\u03B3\u03BD\u03CE\u03C1\u03B9\u03C3\u03B7 \u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03C9\u03BD (OCR) / \u03A3\u03B1\u03C1\u03CE\u03C3\u03B5\u03B9\u03C2 Cleanup
|
||||
ocr.header=\u03A3\u03B1\u03C1\u03CE\u03C3\u03B5\u03B9\u03C2 Cleanup / OCR (Optical Character Recognition - \u039F\u03C0\u03C4\u03B9\u03BA\u03AE \u03B1\u03BD\u03B1\u03B3\u03BD\u03CE\u03C1\u03B9\u03C3\u03B7 \u03C7\u03B1\u03C1\u03B1\u03BA\u03C4\u03AE\u03C1\u03C9\u03BD)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=\u0391\u03C5\u03C4\u03CC\u03BC\u03B1\u03C4\u03B7 \u03C0\
|
||||
imageToPDF.selectText.3=\u039B\u03BF\u03B3\u03B9\u03BA\u03AE \u03C0\u03BF\u03BB\u03BB\u03CE\u03BD \u03B1\u03C1\u03C7\u03B5\u03AF\u03C9\u03BD (\u0395\u03BD\u03B5\u03C1\u03B3\u03BF\u03C0\u03BF\u03B9\u03B5\u03AF\u03C4\u03B1\u03B9 \u03BC\u03CC\u03BD\u03BF \u03B5\u03AC\u03BD \u03B5\u03C1\u03B3\u03AC\u03B6\u03B5\u03C3\u03C4\u03B5 \u03BC\u03B5 \u03C0\u03BF\u03BB\u03BB\u03AD\u03C2 \u03B5\u03B9\u03BA\u03CC\u03BD\u03B5\u03C2)
|
||||
imageToPDF.selectText.4=\u03A3\u03C5\u03B3\u03C7\u03CE\u03BD\u03B5\u03C5\u03C3\u03B7 \u03C3\u03B5 \u03AD\u03BD\u03B1 PDF
|
||||
imageToPDF.selectText.5=\u039C\u03B5\u03C4\u03B1\u03C4\u03C1\u03BF\u03C0\u03AE \u03C3\u03B5 \u03BE\u03B5\u03C7\u03C9\u03C1\u03B9\u03C3\u03C4\u03AC \u03B1\u03C1\u03C7\u03B5\u03AF\u03B1 PDF
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF \u03C3\u03B5 \u0395\u03B9\u03BA\u03CC\u03BD\u03B1
|
||||
pdfToImage.header=PDF \u03C3\u03B5 \u0395\u03B9\u03BA\u03CC\u03BD\u03B1
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=\u039B\u03AD\u03BE\u03B5\u03B9\u03C2-\u03BA\u03BB\u03B5\
|
||||
changeMetadata.modDate=\u0397\u03BC\u03B5\u03C1\u03BF\u03BC\u03B7\u03BD\u03AF\u03B1 \u03A4\u03C1\u03BF\u03C0\u03BF\u03C0\u03BF\u03AF\u03B7\u03C3\u03B7\u03C2 (yyyy/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=\u03A0\u03B1\u03C1\u03B1\u03B3\u03C9\u03B3\u03CC\u03C2:
|
||||
changeMetadata.subject=\u0398\u03AD\u03BC\u03B1:
|
||||
changeMetadata.title=\u03A4\u03AF\u03C4\u03BB\u03BF\u03C2:
|
||||
changeMetadata.trapped=Trapped:
|
||||
changeMetadata.selectText.4=\u0386\u03BB\u03BB\u03B1 \u03BC\u03B5\u03C4\u03B1\u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03B1:
|
||||
changeMetadata.selectText.5=\u03A0\u03C1\u03BF\u03C3\u03B8\u03AE\u03BA\u03B7 \u03B5\u03B3\u03B3\u03C1\u03B1\u03C6\u03AE\u03C2 \u03C0\u03C1\u03BF\u03C3\u03B1\u03C1\u03BC\u03BF\u03C3\u03BC\u03AD\u03BD\u03C9\u03BD \u03BC\u03B5\u03C4\u03B1\u03B4\u03B5\u03B4\u03BF\u03BC\u03AD\u03BD\u03C9\u03BD
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr = left to right, rtl = right to left)
|
||||
@@ -20,13 +20,14 @@ save=Save
|
||||
close=Close
|
||||
filesSelected=files selected
|
||||
noFavourites=No favourites added
|
||||
downloadComplete=Download Complete
|
||||
bored=Bored Waiting?
|
||||
alphabet=Alphabet
|
||||
downloadPdf=Download PDF
|
||||
text=Text
|
||||
font=Font
|
||||
selectFillter=-- Select --
|
||||
pageNum=Page Number
|
||||
pageNum=Page Number
|
||||
sizes.small=Small
|
||||
sizes.medium=Medium
|
||||
sizes.large=Large
|
||||
@@ -43,7 +44,7 @@ red=Red
|
||||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -120,8 +121,8 @@ account.title=Account Settings
|
||||
account.accountSettings=Account Settings
|
||||
account.adminSettings=Admin Settings - View and Add Users
|
||||
account.userControlSettings=User Control Settings
|
||||
account.changeUsername=New Username
|
||||
account.changeUsername=Change Username
|
||||
account.newUsername=New Username
|
||||
account.password=Confirmation Password
|
||||
account.oldPassword=Old password
|
||||
account.newPassword=New Password
|
||||
@@ -172,7 +173,7 @@ merge.tags=merge,Page operations,Back end,server side
|
||||
|
||||
home.split.title=Split
|
||||
home.split.desc=Split PDFs into multiple documents
|
||||
split.tags=Page operations,divide,Multi Page,cut,server side
|
||||
split.tags=Page operations,divide,Multi Page,cut,server side
|
||||
|
||||
home.rotate.title=Rotate
|
||||
home.rotate.desc=Easily rotate your PDFs.
|
||||
@@ -313,7 +314,7 @@ home.add-page-numbers.desc=Add Page numbers throughout a document in a set locat
|
||||
add-page-numbers.tags=paginate,label,organize,index
|
||||
|
||||
home.auto-rename.title=Auto Rename PDF File
|
||||
home.auto-rename.desc=Auto renames a PDF file based on its detected header
|
||||
home.auto-rename.desc=Auto renames a PDF file based on its detected header
|
||||
auto-rename.tags=auto-detect,header-based,organize,relabel
|
||||
|
||||
home.adjust-contrast.title=Adjust Colors/Contrast
|
||||
@@ -367,7 +368,7 @@ showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=Auto Redact
|
||||
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
|
||||
showJS.tags=Redact,Hide,black out,black,marker,hidden
|
||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||
|
||||
home.tableExtraxt.title=PDF to CSV
|
||||
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
||||
@@ -411,7 +412,7 @@ autoRedact.title=Auto Redact
|
||||
autoRedact.header=Auto Redact
|
||||
autoRedact.colorLabel=Colour
|
||||
autoRedact.textsToRedactLabel=Text to Redact (line-separated)
|
||||
autoRedact.textsToRedactPlaceholder=e.g. \nConfidential \nTop-Secret
|
||||
autoRedact.textsToRedactPlaceholder=e.g. \nConfidential \nTop-Secret
|
||||
autoRedact.useRegexLabel=Use Regex
|
||||
autoRedact.wholeWordSearchLabel=Whole Word Search
|
||||
autoRedact.customPaddingLabel=Custom Extra Padding
|
||||
@@ -498,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=Sanitize PDF
|
||||
sanitizePDF.header=Sanitize a PDF file
|
||||
@@ -584,18 +586,18 @@ scalePages.submit=Submit
|
||||
#certSign
|
||||
certSign.title=Certificate Signing
|
||||
certSign.header=Sign a PDF with your certificate (Work in progress)
|
||||
certSign.selectPDF=Select a PDF File for Signing:
|
||||
certSign.selectPDF=Select a PDF File for Signing:
|
||||
certSign.jksNote=Note: If your certificate type is not listed below, please convert it to a Java Keystore (.jks) file using the keytool command line tool. Then, choose the .jks file option below.
|
||||
certSign.selectKey=Select Your Private Key File (PKCS#8 format, could be .pem or .der):
|
||||
certSign.selectCert=Select Your Certificate File (X.509 format, could be .pem or .der):
|
||||
certSign.selectP12=Select Your PKCS#12 Keystore File (.p12 or .pfx) (Optional, If provided, it should contain your private key and certificate):
|
||||
certSign.selectKey=Select Your Private Key File (PKCS#8 format, could be .pem or .der):
|
||||
certSign.selectCert=Select Your Certificate File (X.509 format, could be .pem or .der):
|
||||
certSign.selectP12=Select Your PKCS#12 Keystore File (.p12 or .pfx) (Optional, If provided, it should contain your private key and certificate):
|
||||
certSign.selectJKS=Select Your Java Keystore File (.jks or .keystore):
|
||||
certSign.certType=Certificate Type
|
||||
certSign.password=Enter Your Keystore or Private Key Password (If Any):
|
||||
certSign.password=Enter Your Keystore or Private Key Password (If Any):
|
||||
certSign.showSig=Show Signature
|
||||
certSign.reason=Reason
|
||||
certSign.location=Location
|
||||
certSign.name=Name
|
||||
certSign.name=Name
|
||||
certSign.submit=Sign PDF
|
||||
|
||||
|
||||
@@ -657,7 +659,7 @@ ScannerImageSplit.selectText.8=Sets the minimum contour area threshold for a pho
|
||||
ScannerImageSplit.selectText.9=Border Size:
|
||||
ScannerImageSplit.selectText.10=Sets the size of the border added and removed to prevent white borders in the output (default: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / Scan Cleanup
|
||||
ocr.header=Cleanup Scans / OCR (Optical Character Recognition)
|
||||
@@ -701,7 +703,7 @@ compress.selectText.1=Manual Mode - From 1 to 4
|
||||
compress.selectText.2=Optimization level:
|
||||
compress.selectText.3=4 (Terrible for text images)
|
||||
compress.selectText.4=Auto mode - Auto adjusts quality to get PDF to exact size
|
||||
compress.selectText.5=Expected PDF Size (e.g. 25MB, 10.8MB, 25KB)
|
||||
compress.selectText.5=Expected PDF Size (e.g. 25MB, 10.8MB, 25KB)
|
||||
compress.submit=Compress
|
||||
|
||||
|
||||
@@ -776,8 +778,8 @@ imageToPDF.selectText.2=Auto rotate PDF
|
||||
imageToPDF.selectText.3=Multi file logic (Only enabled if working with multiple images)
|
||||
imageToPDF.selectText.4=Merge into single PDF
|
||||
imageToPDF.selectText.5=Convert to separate PDFs
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF to Image
|
||||
pdfToImage.header=PDF to Image
|
||||
@@ -867,7 +869,6 @@ changeMetadata.keywords=Keywords:
|
||||
changeMetadata.modDate=Modification Date (yyyy/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=Producer:
|
||||
changeMetadata.subject=Subject:
|
||||
changeMetadata.title=Title:
|
||||
changeMetadata.trapped=Trapped:
|
||||
changeMetadata.selectText.4=Other Metadata:
|
||||
changeMetadata.selectText.5=Add Custom Metadata Entry
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=Select Image(s)
|
||||
genericSubmit=Submit
|
||||
processTimeWarning=Warning: This process can take up to a minute depending on file-size
|
||||
pageOrderPrompt=Custom Page Order (Enter a comma-separated list of page numbers or Functions like 2n+1) :
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Go
|
||||
true=True
|
||||
false=False
|
||||
@@ -19,6 +20,7 @@ save=Save
|
||||
close=Close
|
||||
filesSelected=files selected
|
||||
noFavourites=No favorites added
|
||||
downloadComplete=Download Complete
|
||||
bored=Bored Waiting?
|
||||
alphabet=Alphabet
|
||||
downloadPdf=Download PDF
|
||||
@@ -42,7 +44,7 @@ red=Red
|
||||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=Account Settings
|
||||
account.adminSettings=Admin Settings - View and Add Users
|
||||
account.userControlSettings=User Control Settings
|
||||
account.changeUsername=Change Username
|
||||
account.changeUsername=Change Username
|
||||
account.newUsername=New Username
|
||||
account.password=Confirmation Password
|
||||
account.oldPassword=Old password
|
||||
account.newPassword=New Password
|
||||
@@ -366,7 +368,7 @@ showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=Auto Redact
|
||||
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
|
||||
showJS.tags=JS
|
||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||
|
||||
home.tableExtraxt.title=PDF to CSV
|
||||
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
||||
@@ -410,7 +412,7 @@ autoRedact.title=Auto Redact
|
||||
autoRedact.header=Auto Redact
|
||||
autoRedact.colorLabel=Color
|
||||
autoRedact.textsToRedactLabel=Text to Redact (line-separated)
|
||||
autoRedact.textsToRedactPlaceholder=e.g. \nConfidential \nTop-Secret
|
||||
autoRedact.textsToRedactPlaceholder=e.g. \nConfidential \nTop-Secret
|
||||
autoRedact.useRegexLabel=Use Regex
|
||||
autoRedact.wholeWordSearchLabel=Whole Word Search
|
||||
autoRedact.customPaddingLabel=Custom Extra Padding
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=Sanitize PDF
|
||||
sanitizePDF.header=Sanitize a PDF file
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=Sets the minimum contour area threshold for a pho
|
||||
ScannerImageSplit.selectText.9=Border Size:
|
||||
ScannerImageSplit.selectText.10=Sets the size of the border added and removed to prevent white borders in the output (default: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / Scan Cleanup
|
||||
ocr.header=Cleanup Scans / OCR (Optical Character Recognition)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=Auto rotate PDF
|
||||
imageToPDF.selectText.3=Multi file logic (Only enabled if working with multiple images)
|
||||
imageToPDF.selectText.4=Merge into single PDF
|
||||
imageToPDF.selectText.5=Convert to separate PDFs
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF to Image
|
||||
pdfToImage.header=PDF to Image
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=Keywords:
|
||||
changeMetadata.modDate=Modification Date (yyyy/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=Producer:
|
||||
changeMetadata.subject=Subject:
|
||||
changeMetadata.title=Title:
|
||||
changeMetadata.trapped=Trapped:
|
||||
changeMetadata.selectText.4=Other Metadata:
|
||||
changeMetadata.selectText.5=Add Custom Metadata Entry
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=छवियों का चयन करें
|
||||
genericSubmit=प्रस्तुत करें
|
||||
processTimeWarning=चेतावनी: यह प्रक्रिया फ़ाइल के आकार पर निर्भर करती है और यह से एक मिनट तक लग सकती है
|
||||
pageOrderPrompt=कस्टम पेज क्रम (पेज नंबरों या 2n+1 जैसे कार्यों की एक कॉमा से अलग-अलग सूची दर्ज करें):
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=जाएँ
|
||||
true=सही
|
||||
false=गलत
|
||||
@@ -19,6 +20,7 @@ save=सहेजें
|
||||
close=बंद करें
|
||||
filesSelected=फ़ाइलें चयनित हैं
|
||||
noFavourites=कोई पसंदीदा जोड़ा नहीं गया है
|
||||
downloadComplete=Download Complete
|
||||
bored=बोर हो रहे हैं?
|
||||
alphabet=वर्णमाला
|
||||
downloadPdf=पीडीएफ़ डाउनलोड करें
|
||||
@@ -42,7 +44,7 @@ red=लाल
|
||||
green=हरा
|
||||
blue=नीला
|
||||
custom=कस्टम...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=खाता सेटिंग्स
|
||||
account.adminSettings=व्यवस्थापक सेटिंग्स - उपयोगकर्ताओं को देखें और जोड़ें
|
||||
account.userControlSettings=उपयोगकर्ता नियंत्रण सेटिंग्स
|
||||
account.changeUsername=उपयोगकर्ता नाम परिवर्तन करें
|
||||
account.changeUsername=उपयोगकर्ता नाम परिवर्तन करें
|
||||
account.newUsername=नया उपयोगकर्ता नाम
|
||||
account.password=पासवर्ड पुष्टि
|
||||
account.oldPassword=पुराना पासवर्ड
|
||||
account.newPassword=नया पासवर्ड
|
||||
@@ -362,11 +364,11 @@ PdfToSinglePage.tags=एकल पृष्ठ
|
||||
|
||||
home.showJS.title=जावास्क्रिप्ट दिखाएं
|
||||
home.showJS.desc=पीडीएफ़ में डाला गया कोई भी जावास्क्रिप्ट खोजता है और प्रदर्शित करता है
|
||||
showJS.tags=गोपनीयकरण, छिपाना, काला करना, काला, मार्कर, छिपा हुआ
|
||||
showJS.tags=जे एस
|
||||
|
||||
home.autoRedact.title=स्वतः गोपनीयकरण
|
||||
home.autoRedact.desc=प्रविष्ट पाठ के आधार पर पीडीएफ़ में पाठ को स्वतः गोपनीयकरित(काला करें)
|
||||
showJS.tags=गोपनीयकरण, छिपाना, काला करना, काला, मार्कर, छिपा हुआ
|
||||
autoRedact.tags=गोपनीयकरण, छिपाना, काला करना, काला, मार्कर, छिपा हुआ
|
||||
|
||||
home.tableExtraxt.title=PDF से CSV में
|
||||
home.tableExtraxt.desc=CSV में बदलते हुए पीडीएफ़ से तालिकाएँ निकालता है
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=पीडीएफ़ को सफाई करें
|
||||
sanitizePDF.header=एक पीडीएफ़ फ़ाइल को सफाई करें
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=फोटो के लिए न्यूनत
|
||||
ScannerImageSplit.selectText.9=बॉर्डर का आकार:
|
||||
ScannerImageSplit.selectText.10=निकालने और जोड़ने के लिए जोड़ा जाने वाला बॉर्डर का आकार सेट करता है ताकि आउटपुट में सफेद बॉर्डर न आए (डिफ़ॉल्ट: 1)।
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / स्कैन सफाई
|
||||
ocr.header=स्कैन सफाई / OCR (ऑप्टिकल कैरेक्टर रिकग्निशन)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=पीडीएफ को ऑटो रोटेट क
|
||||
imageToPDF.selectText.3=मल्टी फ़ाइल तर्क (केवल यदि कई छवियों के साथ काम किया जा रहा है)
|
||||
imageToPDF.selectText.4=एक ही पीडीएफ में मर्ज करें
|
||||
imageToPDF.selectText.5=अलग-अलग पीडीएफ में परिवर्तित करें
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=पीडीएफ से छवि
|
||||
pdfToImage.header=पीडीएफ से छवि
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=कीवर्ड्स:
|
||||
changeMetadata.modDate=संशोधन तिथि (yyyy/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=निर्माता:
|
||||
changeMetadata.subject=विषय:
|
||||
changeMetadata.title=शीर्षक:
|
||||
changeMetadata.trapped=फंसा हुआ:
|
||||
changeMetadata.selectText.4=अन्य मेटाडेटा:
|
||||
changeMetadata.selectText.5=कस्टम मेटाडेटा एंट्री जोड़ें
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=Válasszon képeket
|
||||
genericSubmit=Beküldés
|
||||
processTimeWarning=Figyelmeztetés: Ez a folyamat akár egy percig is eltarthat a fájlmérettől függően
|
||||
pageOrderPrompt=Egyedi oldalsorrend (Adjon meg vesszővel elválasztott oldalszámokat vagy függvényeket, például 2n+1):
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Ugrás
|
||||
true=Igaz
|
||||
false=Hamis
|
||||
@@ -19,6 +20,7 @@ save=Mentés
|
||||
close=Bezárás
|
||||
filesSelected=kiválasztott fájlok
|
||||
noFavourites=Nincs hozzáadva kedvenc
|
||||
downloadComplete=Download Complete
|
||||
bored=Unatkozol?
|
||||
alphabet=Ábécé
|
||||
downloadPdf=PDF letöltése
|
||||
@@ -42,7 +44,7 @@ red=Piros
|
||||
green=Zöld
|
||||
blue=Kék
|
||||
custom=Egyedi...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -119,8 +121,8 @@ account.title=Fiókbeállítások
|
||||
account.accountSettings=Fiókbeállítások
|
||||
account.adminSettings=Admin Beállítások - Felhasználók megtekintése és hozzáadása
|
||||
account.userControlSettings=Felhasználói vezérlési beállítások
|
||||
account.changeUsername=Új felhasználónév
|
||||
account.changeUsername=Új felhasználónév
|
||||
account.changeUsername=Felhasználónév módosítása
|
||||
account.newUsername=Új felhasználónév
|
||||
account.password=Megerősítő jelszó
|
||||
account.oldPassword=Régi jelszó
|
||||
account.newPassword=Új jelszó
|
||||
@@ -362,11 +364,11 @@ PdfToSinglePage.tags=egyetlen lap
|
||||
|
||||
home.showJS.title=JavaScript megjelenítése
|
||||
home.showJS.desc=Keres és megjelenít bármilyen JS-t, amit beinjektáltak a PDF-be
|
||||
showJS.tags=Elrejt,Elrejtés,kitakarás,fekete,fekete,marker,elrejtett
|
||||
showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=Automatikus Elrejtés
|
||||
home.autoRedact.desc=Automatikusan kitakar (elrejt) szöveget egy PDF-ben az input szöveg alapján
|
||||
showJS.tags=Elrejt,Elrejtés,kitakarás,fekete,fekete,marker,elrejtett
|
||||
autoRedact.tags=Elrejt,Elrejtés,kitakarás,fekete,fekete,marker,elrejtett
|
||||
|
||||
home.tableExtraxt.title=PDF to CSV
|
||||
home.tableExtraxt.desc=Táblázatok kinyerése a PDF-ből CSV formátumra konvertálva
|
||||
@@ -410,7 +412,7 @@ autoRedact.title=Érzékeny tartalom eltávolítása
|
||||
autoRedact.header=Érzékeny tartalom eltávolítása
|
||||
autoRedact.colorLabel=Szín
|
||||
autoRedact.textsToRedactLabel=Kivonand szövegek (sorokra bontva)
|
||||
autoRedact.textsToRedactPlaceholder=például \nBizalmas \nLegfelsőbb Titok
|
||||
autoRedact.textsToRedactPlaceholder=például \nBizalmas \nLegfelsőbb Titok
|
||||
autoRedact.useRegexLabel=Reguláris kifejezés használata
|
||||
autoRedact.wholeWordSearchLabel=Teljes szó keresése
|
||||
autoRedact.customPaddingLabel=Egyedi extra kitöltés
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=PDF tisztítása
|
||||
sanitizePDF.header=PDF fájl megtisztítása
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=A fotók minimális kontúrterületének beállí
|
||||
ScannerImageSplit.selectText.9=Keret mérete:
|
||||
ScannerImageSplit.selectText.10=A hozzáadott és eltávolított keret méretének beállítása a fehér keretek elkerülése érdekében a kimeneten (alapértelmezett: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / szkennelés tisztázása
|
||||
ocr.header=Szkennelés tisztázása / OCR (Optikai karakterfelismerés)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=Automatikus forgatás PDF
|
||||
imageToPDF.selectText.3=Több fájl logika (csak akkor engedélyezett, ha több képpel dolgozik)
|
||||
imageToPDF.selectText.4=Egyesítse egyetlen PDF-fé
|
||||
imageToPDF.selectText.5=Átalakítás különálló PDF-fé
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF képpé alakítása
|
||||
pdfToImage.header=PDF képpé alakítása
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=Kulcsszavak:
|
||||
changeMetadata.modDate=Módosítás dátuma (éééé/hh/nn ÓÓ:PP:MM):
|
||||
changeMetadata.producer=Készítő:
|
||||
changeMetadata.subject=Tárgy:
|
||||
changeMetadata.title=Cím:
|
||||
changeMetadata.trapped=Trapped:
|
||||
changeMetadata.selectText.4=Egyéb metaadatok:
|
||||
changeMetadata.selectText.5=Egyedi metaadatbejegyzés hozzáadása
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl=right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=Pilih Gambar
|
||||
genericSubmit=Kirim
|
||||
processTimeWarning=Peringatan: Proses ini dapat memakan waktu hingga satu menit, tergantung pada ukuran berkas
|
||||
pageOrderPrompt=Urutan Halaman Khusus (Masukkan daftar nomor halaman yang dipisahkan dengan koma atau Fungsi seperti 2n + 1) :
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Ke
|
||||
true=Benar
|
||||
false=Salah
|
||||
@@ -19,6 +20,7 @@ save=Simpan
|
||||
close=Tutup
|
||||
filesSelected=berkas dipilih
|
||||
noFavourites=Tidak ada favorit yang ditambahkan
|
||||
downloadComplete=Download Complete
|
||||
bored=Bosan Menunggu?
|
||||
alphabet=Abjad
|
||||
downloadPdf=Unduh PDF
|
||||
@@ -42,7 +44,7 @@ red=Merah
|
||||
green=Hijau
|
||||
blue=Biru
|
||||
custom=Kustom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=Pengaturan Akun
|
||||
account.adminSettings=Pengaturan Admin - Melihat dan Menambahkan Pengguna
|
||||
account.userControlSettings=Pengaturan Kontrol Pengguna
|
||||
account.changeUsername=Ubah Nama Pengguna
|
||||
account.changeUsername=Ubah Nama Pengguna
|
||||
account.newUsername=Nama pengguna baru
|
||||
account.password=Konfirmasi Kata sandi
|
||||
account.oldPassword=Kata sandi lama
|
||||
account.newPassword=Kata Sandi Baru
|
||||
@@ -362,11 +364,11 @@ PdfToSinglePage.tags=halaman tunggal
|
||||
|
||||
home.showJS.title=Tampilkan Javascript
|
||||
home.showJS.desc=Mencari dan menampilkan JS apa pun yang disuntikkan ke dalam PDF
|
||||
showJS.tags=Hapus, Sembunyikan, padamkan, hitam, hitam, penanda, tersembunyi
|
||||
showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=Redaksional Otomatis
|
||||
home.autoRedact.desc=Menyunting Otomatis (Menghitamkan) teks dalam PDF berdasarkan teks masukan
|
||||
showJS.tags=Hapus, Sembunyikan, padamkan, hitam, hitam, penanda, tersembunyi
|
||||
autoRedact.tags=Hapus, Sembunyikan, padamkan, hitam, hitam, penanda, tersembunyi
|
||||
|
||||
home.tableExtraxt.title=PDF ke CSV
|
||||
home.tableExtraxt.desc=Mengekstrak Tabel dari PDF yang mengonversinya menjadi CSV
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=Bersihkan PDF
|
||||
sanitizePDF.header=Membersihkan berkas PDF
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=Menetapkan ambang batas area kontur minimum untuk
|
||||
ScannerImageSplit.selectText.9=Ukuran Batas:
|
||||
ScannerImageSplit.selectText.10=Menetapkan ukuran batas yang ditambahkan dan dihapus untuk mencegah batas putih pada output (default: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / Pembersihan Pindaian
|
||||
ocr.header=Pemindaian Pembersihan / OCR (Pengenalan Karakter Optik)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=Putar PDF secara otomatis
|
||||
imageToPDF.selectText.3=Logika multi berkas (Hanya diaktifkan jika bekerja dengan banyak gambar)
|
||||
imageToPDF.selectText.4=Gabungkan menjadi satu PDF
|
||||
imageToPDF.selectText.5=Mengonversi ke PDF yang terpisah
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF ke Gambar
|
||||
pdfToImage.header=PDF ke Gambar
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=Kata kunci:
|
||||
changeMetadata.modDate=Tangal Diupdate (yyyy/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=Produser:
|
||||
changeMetadata.subject=Subjek:
|
||||
changeMetadata.title=Judul:
|
||||
changeMetadata.trapped=Terperangkap:
|
||||
changeMetadata.selectText.4=Metadata Lain-lain:
|
||||
changeMetadata.selectText.5=Tambahkan Metadata Khusus
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=Selecteer afbeelding(en)
|
||||
genericSubmit=Indienen
|
||||
processTimeWarning=Waarschuwing: Dit proces kan tot een minuut duren afhankelijk van de bestandsgrootte
|
||||
pageOrderPrompt=Aangepaste pagina volgorde (Voer een komma-gescheiden lijst van paginanummers of functies in, zoals 2n+1) :
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Ga
|
||||
true=Waar
|
||||
false=Onwaar
|
||||
@@ -19,6 +20,7 @@ save=Opslaan
|
||||
close=Sluiten
|
||||
filesSelected=Bestanden geselecteerd
|
||||
noFavourites=Geen favorieten toegevoegd
|
||||
downloadComplete=Download Complete
|
||||
bored=Verveeld met wachten?
|
||||
alphabet=Alfabet
|
||||
downloadPdf=Download PDF
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=Account instellingen
|
||||
account.adminSettings=Beheerdersinstellingen - Gebruikers bekijken en toevoegen
|
||||
account.userControlSettings=Gebruikerscontrole instellingen
|
||||
account.changeUsername=Wijzig gebruikersnaam
|
||||
account.changeUsername=Wijzig gebruikersnaam
|
||||
account.newUsername=Nieuwe gebruikersnaam
|
||||
account.password=Bevestigingswachtwoord
|
||||
account.oldPassword=Oud wachtwoord
|
||||
account.newPassword=Nieuw wachtwoord
|
||||
@@ -366,7 +368,7 @@ showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=Automatisch censureren
|
||||
home.autoRedact.desc=Automatisch censureren (onherkenbaar maken) van tekst in een PDF op basis van ingevoerde tekst
|
||||
showJS.tags=JS
|
||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||
|
||||
home.tableExtraxt.title=PDF naar CSV
|
||||
home.tableExtraxt.desc=Haalt tabellen uit een PDF en converteert ze naar CSV
|
||||
@@ -410,7 +412,7 @@ autoRedact.title=Automatisch censureren
|
||||
autoRedact.header=Automatisch censureren
|
||||
autoRedact.colorLabel=Kleur
|
||||
autoRedact.textsToRedactLabel=Tekst om te censureren (gescheiden door regels)
|
||||
autoRedact.textsToRedactPlaceholder=bijv.\Vertrouwelijk \nTopgeheim
|
||||
autoRedact.textsToRedactPlaceholder=bijv.\Vertrouwelijk \nTopgeheim
|
||||
autoRedact.useRegexLabel=Gebruik regex
|
||||
autoRedact.wholeWordSearchLabel=Zoeken op hele woorden
|
||||
autoRedact.customPaddingLabel=Aangepaste extra ruimtevulling
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Y coördinaat overschrijven
|
||||
AddStampRequest.customMargin=Aangepaste marge
|
||||
AddStampRequest.customColor=Aangepaste tekstkleur
|
||||
AddStampRequest.submit=Indienen
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=PDF opschonen
|
||||
sanitizePDF.header=Een PDF-bestand opschonen
|
||||
@@ -519,7 +522,7 @@ addPageNumbers.selectText.4=Startnummer
|
||||
addPageNumbers.selectText.5=Pagina's om te nummeren
|
||||
addPageNumbers.selectText.6=Aangepaste tekst
|
||||
addPageNumbers.customTextDesc=Aangepaste tekst
|
||||
addPageNumbers.numberPagesDesc=Welke pagina's genummerd moeten worden, standaard 'all', accepteert ook 1-5 of 2,5,9 etc
|
||||
addPageNumbers.numberPagesDesc=Welke pagina's genummerd moeten worden, standaard 'all', accepteert ook 1-5 of 2,5,9 etc
|
||||
addPageNumbers.customNumberDesc=Standaard {n}, accepteert ook 'Pagina {n} van {total}', 'Tekst-{n}', '{filename}-{n}
|
||||
addPageNumbers.submit=Paginanummers toevoegen
|
||||
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=Stelt de minimale contour oppervlakte drempel in
|
||||
ScannerImageSplit.selectText.9=Randgrootte:
|
||||
ScannerImageSplit.selectText.10=Stelt de grootte van de toegevoegde en verwijderde rand in om witte randen in de uitvoer te voorkomen (standaard: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / Scan opruimen
|
||||
ocr.header=Scans opruimen / OCR (Optical Character Recognition)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=PDF automatisch draaien
|
||||
imageToPDF.selectText.3=Meervoudige bestandslogica (Alleen ingeschakeld bij werken met meerdere afbeeldingen)
|
||||
imageToPDF.selectText.4=Voeg samen in één PDF
|
||||
imageToPDF.selectText.5=Zet om naar afzonderlijke PDF's
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF naar afbeelding
|
||||
pdfToImage.header=PDF naar afbeelding
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=Trefwoorden:
|
||||
changeMetadata.modDate=Wijzigingsdatum (yyyy/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=Producent:
|
||||
changeMetadata.subject=Onderwerp:
|
||||
changeMetadata.title=Titel:
|
||||
changeMetadata.trapped=Vastgezet:
|
||||
changeMetadata.selectText.4=Overige metadata:
|
||||
changeMetadata.selectText.5=Voeg aangepaste metadata-invoer toe
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=Selecione a(s) imagem(ns)
|
||||
genericSubmit=Enviar
|
||||
processTimeWarning=Aviso: esse processo pode levar até um minuto, dependendo do tamanho do arquivo
|
||||
pageOrderPrompt=Ordem das páginas (digite uma lista separada por vírgulas de números de página):
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Ir
|
||||
true=Verdadeiro
|
||||
false=Falso
|
||||
@@ -19,6 +20,7 @@ save=Salvar
|
||||
close=Fechar
|
||||
filesSelected=arquivos selecionados
|
||||
noFavourites=Nenhum favorito adicionado
|
||||
downloadComplete=Download Complete
|
||||
bored=Entediado esperando?
|
||||
alphabet=Alfabeto
|
||||
downloadPdf=baixar PDF
|
||||
@@ -42,7 +44,7 @@ red=Red
|
||||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=Account Settings
|
||||
account.adminSettings=Admin Settings - View and Add Users
|
||||
account.userControlSettings=User Control Settings
|
||||
account.changeUsername=Change Username
|
||||
account.changeUsername=Change Username
|
||||
account.newUsername=New Username
|
||||
account.password=Confirmation Password
|
||||
account.oldPassword=Old password
|
||||
account.newPassword=New Password
|
||||
@@ -366,7 +368,7 @@ showJS.tags=JavaScript
|
||||
|
||||
home.autoRedact.title=Auto Redact
|
||||
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
|
||||
showJS.tags=JavaScript
|
||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||
|
||||
home.tableExtraxt.title=PDF to CSV
|
||||
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
||||
@@ -410,7 +412,7 @@ autoRedact.title=Auto Redact
|
||||
autoRedact.header=Auto Redact
|
||||
autoRedact.colorLabel=Colour
|
||||
autoRedact.textsToRedactLabel=Text to Redact (line-separated)
|
||||
autoRedact.textsToRedactPlaceholder=e.g. \nConfidential \nTop-Secret
|
||||
autoRedact.textsToRedactPlaceholder=e.g. \nConfidential \nTop-Secret
|
||||
autoRedact.useRegexLabel=Use Regex
|
||||
autoRedact.wholeWordSearchLabel=Whole Word Search
|
||||
autoRedact.customPaddingLabel=Custom Extra Padding
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=Sanitizar PDF
|
||||
sanitizePDF.header=Sanitizar um arquivo PDF
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=Define o limite mínimo da área de contorno para
|
||||
ScannerImageSplit.selectText.9=Tamanho da Borda:
|
||||
ScannerImageSplit.selectText.10=Define o tamanho da borda adicionada e removida para evitar bordas brancas na saída (padrão: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / Limpeza de Digitalização
|
||||
ocr.header=OCR / Limpeza de Digitalização (Reconhecimento Óptico de Caracteres)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=Girar Automaticamente
|
||||
imageToPDF.selectText.3=Lógica de Vários Arquivos (Ativada apenas ao trabalhar com várias imagens)
|
||||
imageToPDF.selectText.4=Mesclar em um Único PDF
|
||||
imageToPDF.selectText.5=Converter em PDFs Separados
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF para Imagem
|
||||
pdfToImage.header=Converter PDF para Imagem
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=Palavras-chave:
|
||||
changeMetadata.modDate=Data de Modificação (aaaa/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=Produtor:
|
||||
changeMetadata.subject=Assunto:
|
||||
changeMetadata.title=Título:
|
||||
changeMetadata.trapped=Trapped:
|
||||
changeMetadata.selectText.4=Outros Metadados
|
||||
changeMetadata.selectText.5=Adicionar Entrada de Metadados Personalizados
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=Selectează imagini
|
||||
genericSubmit=Trimite
|
||||
processTimeWarning=Avertisment: Acest proces poate dura până la un minut în funcție de dimensiunea fișierului
|
||||
pageOrderPrompt=Ordinea paginilor (Introdu o listă separată prin virgulă de numere de pagină):
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Mergi la pagină
|
||||
true=Adevărat
|
||||
false=Fals
|
||||
@@ -19,6 +20,7 @@ save=Salvează
|
||||
close=Închide
|
||||
filesSelected=fișiere selectate
|
||||
noFavourites=Niciun favorit adăugat
|
||||
downloadComplete=Download Complete
|
||||
bored=Plictisit așteptând?
|
||||
alphabet=Alfabet
|
||||
downloadPdf=Descarcă PDF
|
||||
@@ -42,7 +44,7 @@ red=Red
|
||||
green=Green
|
||||
blue=Blue
|
||||
custom=Custom...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=Account Settings
|
||||
account.adminSettings=Admin Settings - View and Add Users
|
||||
account.userControlSettings=User Control Settings
|
||||
account.changeUsername=Change Username
|
||||
account.changeUsername=Change Username
|
||||
account.newUsername=New Username
|
||||
account.password=Confirmation Password
|
||||
account.oldPassword=Old password
|
||||
account.newPassword=New Password
|
||||
@@ -366,7 +368,7 @@ showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=Auto Redact
|
||||
home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text
|
||||
showJS.tags=JS
|
||||
autoRedact.tags=Redact,Hide,black out,black,marker,hidden
|
||||
|
||||
home.tableExtraxt.title=PDF to CSV
|
||||
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
||||
@@ -410,7 +412,7 @@ autoRedact.title=Auto Redact
|
||||
autoRedact.header=Auto Redact
|
||||
autoRedact.colorLabel=Colour
|
||||
autoRedact.textsToRedactLabel=Text to Redact (line-separated)
|
||||
autoRedact.textsToRedactPlaceholder=e.g. \nConfidential \nTop-Secret
|
||||
autoRedact.textsToRedactPlaceholder=e.g. \nConfidential \nTop-Secret
|
||||
autoRedact.useRegexLabel=Use Regex
|
||||
autoRedact.wholeWordSearchLabel=Whole Word Search
|
||||
autoRedact.customPaddingLabel=Custom Extra Padding
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=Sanitize PDF
|
||||
sanitizePDF.header=Sanitize a PDF file
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=Stabilește pragul minim de arie a conturului pen
|
||||
ScannerImageSplit.selectText.9=Mărimea marginii:
|
||||
ScannerImageSplit.selectText.10=Stabilește mărimea marginii adăugate și eliminate pentru a evita marginile albe în rezultat (implicit: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / Curățare scanare
|
||||
ocr.header=Curățare scanări / OCR (Recunoaștere optică a caracterelor)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=Rotire automată a PDF-ului
|
||||
imageToPDF.selectText.3=Logica pentru mai multe fișiere (activată numai dacă se lucrează cu mai multe imagini)
|
||||
imageToPDF.selectText.4=Unifică într-un singur PDF
|
||||
imageToPDF.selectText.5=Convertă în PDF-uri separate
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF în Imagine
|
||||
pdfToImage.header=PDF în Imagine
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=Cuvinte cheie:
|
||||
changeMetadata.modDate=Data modificării (yyyy/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=Producător:
|
||||
changeMetadata.subject=Subiect:
|
||||
changeMetadata.title=Titlu:
|
||||
changeMetadata.trapped=Blocat:
|
||||
changeMetadata.selectText.4=Alte Metadate:
|
||||
changeMetadata.selectText.5=Adăugați Intrare Metadate Personalizate
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=Odaberi sliku (slike)
|
||||
genericSubmit=Prihvatiti
|
||||
processTimeWarning=Warning:Upozorenje: Ovaj proces može trajati i do minut, u zavisnosti od veličine dokumenta
|
||||
pageOrderPrompt=Prilagođeni redosled stranica (unesi listu brojeva stranica ili funkcija, kao što su 2n+1, razdvojene zarezima) :
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Idi
|
||||
true=Tačno
|
||||
false=Netačno
|
||||
@@ -19,6 +20,7 @@ save=Sačuvaj
|
||||
close=Zatvori
|
||||
filesSelected=odabrani fajlovi
|
||||
noFavourites=Nema dodatih favorita
|
||||
downloadComplete=Download Complete
|
||||
bored=Da li ti je dosadno dok čekaš?
|
||||
alphabet=Alfabet
|
||||
downloadPdf=Skini PDF
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=Podešavanja naloga
|
||||
account.adminSettings=Admin podešavanja - Pregled i dodavanje korisnika
|
||||
account.userControlSettings=Podešavanja kontrole korisnika
|
||||
account.changeUsername=Pormeni korisničko ime
|
||||
account.changeUsername=Pormeni korisničko ime
|
||||
account.newUsername=Novo korisničko ime
|
||||
account.password=Potvrda lozinke
|
||||
account.oldPassword=Stara lozinka
|
||||
account.newPassword=Nova lozinka
|
||||
@@ -362,11 +364,11 @@ PdfToSinglePage.tags=jedna-stranica
|
||||
|
||||
home.showJS.title=Prikaži JavaScript
|
||||
home.showJS.desc=Pretražuje i prikazuje bilo koji JavaScript ubačen u PDF
|
||||
showJS.tags=Cenzura,Sakrij,prekrivanje,crna,marker,skriveno
|
||||
showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=Automatsko Cenzurisanje
|
||||
home.autoRedact.desc=Automatsko cenzurisanje teksta u PDF-u na osnovu unetog teksta
|
||||
showJS.tags=Cenzura,Sakrij,prekrivanje,crna,marker,skriveno
|
||||
autoRedact.tags=Cenzura,Sakrij,prekrivanje,crna,marker,skriveno
|
||||
|
||||
home.tableExtraxt.title=PDF u CSV
|
||||
home.tableExtraxt.desc=Izdvaja tabele iz PDF-a pretvarajući ih u CSV
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=Sanitizacija PDF-a
|
||||
sanitizePDF.header=Sanitizacija PDF fajla
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=Postavlja minimalni prag površine konture za fot
|
||||
ScannerImageSplit.selectText.9=Veličina ivice:
|
||||
ScannerImageSplit.selectText.10=Postavlja veličinu ivice dodate i uklonjene kako bi se sprečile bele ivice u izlazu (podrazumevano: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / Čišćenje skeniranja
|
||||
ocr.header=Čišćenje skeniranja / OCR (Optičko prepoznavanje znakova)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=Automatsko rotiranje PDF-a
|
||||
imageToPDF.selectText.3=Logika za više fajlova (Omogućeno samo ako radite sa više slika)
|
||||
imageToPDF.selectText.4=Spoji u jedan PDF
|
||||
imageToPDF.selectText.5=Konvertuj u odvojene PDF-ove
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF u sliku
|
||||
pdfToImage.header=PDF u sliku
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=Ključne reči:
|
||||
changeMetadata.modDate=Datum izmene (gggg/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=Proizvođač:
|
||||
changeMetadata.subject=Tema:
|
||||
changeMetadata.title=Naslov:
|
||||
changeMetadata.trapped=Zaglavljeno:
|
||||
changeMetadata.selectText.4=Drugi metapodaci:
|
||||
changeMetadata.selectText.5=Dodaj prilagođeni unos metapodataka
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=Resim(leri) seçin
|
||||
genericSubmit=Gönder
|
||||
processTimeWarning=Uyarı: Bu işlem, dosya boyutuna bağlı olarak bir dakikaya kadar sürebilir.
|
||||
pageOrderPrompt=Özel Sayfa Sırası (Virgülle ayrılmış sayfa numaraları veya 2n+1 gibi bir fonksiyon girin) :
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=Git
|
||||
true=Doğru
|
||||
false=Yanlış
|
||||
@@ -19,6 +20,7 @@ save=Kaydet
|
||||
close=Kapat
|
||||
filesSelected=dosya seçildi
|
||||
noFavourites=Favori eklenmedi
|
||||
downloadComplete=Download Complete
|
||||
bored=Sıkıldınız mı?
|
||||
alphabet=Alfabe
|
||||
downloadPdf=PDF İndir
|
||||
@@ -42,7 +44,7 @@ red=Kırmızı
|
||||
green=Yeşil
|
||||
blue=Mavi
|
||||
custom=Özel
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=Hesap Ayarları
|
||||
account.adminSettings=Yönetici Ayarları - Kullanıcıları Görüntüle ve Ekle
|
||||
account.userControlSettings=Kullanıcı Kontrol Ayarları
|
||||
account.changeUsername=Kullanıcı Adını Değiştir
|
||||
account.changeUsername=Kullanıcı Adını Değiştir
|
||||
account.newUsername=Yeni kullanıcı adı
|
||||
account.password=Onay Şifresi
|
||||
account.oldPassword=Eski Şifre
|
||||
account.newPassword=Yeni Şifre
|
||||
@@ -362,11 +364,11 @@ PdfToSinglePage.tags=tek sayfa
|
||||
|
||||
home.showJS.title=Javascript'i Göster
|
||||
home.showJS.desc=Bir PDF'e enjekte edilen herhangi bir JS'i araştırır ve gösterir
|
||||
showJS.tags=Karart,Gizle,karartma,siyah,markör,gizli
|
||||
showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=Otomatik Karartma
|
||||
home.autoRedact.desc=Giriş metnine dayanarak bir PDF'teki metni Otomatik Karartır (Redakte)
|
||||
showJS.tags=Karart,Gizle,karartma,siyah,markör,gizli
|
||||
autoRedact.tags=Karart,Gizle,karartma,siyah,markör,gizli
|
||||
|
||||
home.tableExtraxt.title=PDF to CSV
|
||||
home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV
|
||||
@@ -410,7 +412,7 @@ autoRedact.title=Otomatik Karartma
|
||||
autoRedact.header=Otomatik Karartma
|
||||
autoRedact.colorLabel=Renk
|
||||
autoRedact.textsToRedactLabel=Karartılacak Metin (satır ayrılmış)
|
||||
autoRedact.textsToRedactPlaceholder=Örn. \nGizli \nÇok Gizli
|
||||
autoRedact.textsToRedactPlaceholder=Örn. \nGizli \nÇok Gizli
|
||||
autoRedact.useRegexLabel=Regex Kullan
|
||||
autoRedact.wholeWordSearchLabel=Tam Kelime Arama
|
||||
autoRedact.customPaddingLabel=Özel Ekstra Dolgu
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=PDF'i Temizle
|
||||
sanitizePDF.header=PDF dosyasını temizle
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=Bir fotoğraf için minimum kontur alanı eşiği
|
||||
ScannerImageSplit.selectText.9=Kenar Boyutu:
|
||||
ScannerImageSplit.selectText.10=Çıktıda beyaz kenarların önlenmesi için eklenen ve kaldırılan kenarın boyutunu ayarlar (varsayılan: 1).
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / Tarama Temizleme
|
||||
ocr.header=Taramaları Temizle / OCR (Optik Karakter Tanıma)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=PDF'yi otomatik döndür
|
||||
imageToPDF.selectText.3=Çoklu dosya mantığı (Yalnızca birden fazla resimle çalışırken etkinleştirilir)
|
||||
imageToPDF.selectText.4=Tek bir PDF'e birleştir
|
||||
imageToPDF.selectText.5=Ayrı PDF'lere dönüştür
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF'den Resme
|
||||
pdfToImage.header=PDF'den Resme
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=Anahtar Kelimeler:
|
||||
changeMetadata.modDate=Değişiklik Tarihi (yyyy/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=Üretici:
|
||||
changeMetadata.subject=Konu:
|
||||
changeMetadata.title=Başlık:
|
||||
changeMetadata.trapped=Tuzak:
|
||||
changeMetadata.selectText.4=Diğer Metaveri:
|
||||
changeMetadata.selectText.5=Özel Metaveri Girişi Ekle
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
###########
|
||||
###########
|
||||
# Generic #
|
||||
###########
|
||||
# the direction that the language is written (ltr=left to right, rtl = right to left)
|
||||
@@ -11,6 +11,7 @@ imgPrompt=選擇圖片
|
||||
genericSubmit=送出
|
||||
processTimeWarning=警告:此過程可能需要長達一分鐘,具體取決於檔案大小
|
||||
pageOrderPrompt=自訂頁面順序(輸入以逗號分隔的頁碼或函式,如 2n+1):
|
||||
pageSelectionPrompt=Custom Page Selection (Enter a comma-separated list of page numbers 1,5,6 or Functions like 2n+1) :
|
||||
goToPage=前往
|
||||
true=是
|
||||
false=否
|
||||
@@ -19,6 +20,7 @@ save=儲存
|
||||
close=關閉
|
||||
filesSelected=已選擇的檔案
|
||||
noFavourites=未新增收藏
|
||||
downloadComplete=Download Complete
|
||||
bored=等待時覺得無聊?
|
||||
alphabet=字母表
|
||||
downloadPdf=下載 PDF
|
||||
@@ -42,7 +44,7 @@ red=紅色
|
||||
green=綠色
|
||||
blue=藍色
|
||||
custom=自訂...
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any ploblems!
|
||||
WorkInProgess=Work in progress, May not work or be buggy, Please report any problems!
|
||||
poweredBy=Powered by
|
||||
yes=Yes
|
||||
no=No
|
||||
@@ -120,7 +122,7 @@ account.accountSettings=帳戶設定
|
||||
account.adminSettings=管理設定 - 檢視和新增使用者
|
||||
account.userControlSettings=使用者控制設定
|
||||
account.changeUsername=修改使用者名稱
|
||||
account.changeUsername=修改使用者名稱
|
||||
account.newUsername=新使用者名稱
|
||||
account.password=確認密碼
|
||||
account.oldPassword=舊密碼
|
||||
account.newPassword=新密碼
|
||||
@@ -362,11 +364,11 @@ PdfToSinglePage.tags=單一頁面
|
||||
|
||||
home.showJS.title=顯示 JavaScript
|
||||
home.showJS.desc=搜尋並顯示嵌入 PDF 中的任何 JS(JavaScript)
|
||||
showJS.tags=塗黑,隱藏,塗黑,黑色,標記,隱藏
|
||||
showJS.tags=JS
|
||||
|
||||
home.autoRedact.title=自動塗黑
|
||||
home.autoRedact.desc=根據輸入的文字自動塗黑 PDF 中的文字
|
||||
showJS.tags=塗黑,隱藏,塗黑,黑色,標記,隱藏
|
||||
autoRedact.tags=塗黑,隱藏,塗黑,黑色,標記,隱藏
|
||||
|
||||
home.tableExtraxt.title=PDF 轉 CSV
|
||||
home.tableExtraxt.desc=從 PDF 中提取表格並將其轉換為 CSV
|
||||
@@ -410,7 +412,7 @@ autoRedact.title=自動塗黑
|
||||
autoRedact.header=自動塗黑
|
||||
autoRedact.colorLabel=顏色
|
||||
autoRedact.textsToRedactLabel=要塗黑的文字(以行分隔)
|
||||
autoRedact.textsToRedactPlaceholder=例如 \n機密 \n最高機密
|
||||
autoRedact.textsToRedactPlaceholder=例如 \n機密 \n最高機密
|
||||
autoRedact.useRegexLabel=使用正則表達式
|
||||
autoRedact.wholeWordSearchLabel=整個單詞搜尋
|
||||
autoRedact.customPaddingLabel=自訂額外填充
|
||||
@@ -497,7 +499,8 @@ AddStampRequest.overrideY=Override Y Coordinate
|
||||
AddStampRequest.customMargin=Custom Margin
|
||||
AddStampRequest.customColor=Custom Text Color
|
||||
AddStampRequest.submit=Submit
|
||||
|
||||
|
||||
|
||||
#sanitizePDF
|
||||
sanitizePDF.title=清理 PDF
|
||||
sanitizePDF.header=清理 PDF 檔案
|
||||
@@ -656,7 +659,7 @@ ScannerImageSplit.selectText.8=設定照片的最小輪廓區域閾值
|
||||
ScannerImageSplit.selectText.9=邊框大小:
|
||||
ScannerImageSplit.selectText.10=設定新增和移除的邊框大小,以防止輸出中的白色邊框(預設:1)。
|
||||
|
||||
|
||||
|
||||
#OCR
|
||||
ocr.title=OCR / 掃描清理
|
||||
ocr.header=清理掃描 / OCR(光學字元識別)
|
||||
@@ -775,8 +778,8 @@ imageToPDF.selectText.2=自動旋轉 PDF
|
||||
imageToPDF.selectText.3=多文件邏輯(僅在處理多個影像時啟用)
|
||||
imageToPDF.selectText.4=合併為單一 PDF
|
||||
imageToPDF.selectText.5=轉換為單獨的 PDF
|
||||
|
||||
|
||||
|
||||
|
||||
#pdfToImage
|
||||
pdfToImage.title=PDF 轉圖片
|
||||
pdfToImage.header=PDF 轉圖片
|
||||
@@ -866,7 +869,6 @@ changeMetadata.keywords=關鍵字:
|
||||
changeMetadata.modDate=修改日期(yyyy/MM/dd HH:mm:ss):
|
||||
changeMetadata.producer=製作人:
|
||||
changeMetadata.subject=主題:
|
||||
changeMetadata.title=標題:
|
||||
changeMetadata.trapped=陷阱:
|
||||
changeMetadata.selectText.4=其他中繼資料:
|
||||
changeMetadata.selectText.5=新增自訂中繼資料項目
|
||||
|
||||
@@ -7,15 +7,15 @@ security:
|
||||
csrfDisabled: true
|
||||
loginAttemptCount: 5 # lock user account after 5 tries
|
||||
loginResetTimeMinutes : 120 # lock account for 2 hours after x attempts
|
||||
|
||||
|
||||
system:
|
||||
|
||||
|
||||
defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
|
||||
googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow
|
||||
enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes)
|
||||
customApplications:
|
||||
bookAndHtmlFormatsInstalled: false # Installs Calibre for book format conversion (For non docker it must be manually downloaded but will need to be true to show in UI)
|
||||
|
||||
|
||||
#ui:
|
||||
# appName: exampleAppName # Application's visible name
|
||||
# homeDescription: I am a description # Short description or tagline shown on homepage.
|
||||
|
||||
4
src/main/resources/static/css/account.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.buttons-container {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
28
src/main/resources/static/css/add-image.css
Normal file
@@ -0,0 +1,28 @@
|
||||
#box-drag-container {
|
||||
position: relative;
|
||||
margin: 20px 0;
|
||||
}
|
||||
#pdf-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
width: 100%;
|
||||
}
|
||||
.draggable-buttons-box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
.draggable-buttons-box > button {
|
||||
z-index: 10;
|
||||
background-color: rgba(13, 110, 253, 0.1);
|
||||
}
|
||||
.draggable-canvas {
|
||||
border: 1px solid red;
|
||||
position: absolute;
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
top: 0px;
|
||||
left: 0;
|
||||
}
|
||||
@@ -1,135 +1,141 @@
|
||||
/* Dark Mode Styles */
|
||||
body, select, textarea {
|
||||
--body-background-color: 51, 51, 51;
|
||||
--base-font-color: 255, 255, 255;
|
||||
background-color: rgb(var(--body-background-color)) !important;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
.card {
|
||||
background-color: rgb(var(--body-background-color)) !important;
|
||||
border: 1px solid #999;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #add8e6;
|
||||
}
|
||||
a:hover {
|
||||
color: #87ceeb; /* Slightly brighter blue on hover for accessibility */
|
||||
}
|
||||
|
||||
.dark-card {
|
||||
background-color: rgb(var(--body-background-color)) !important;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
.jumbotron {
|
||||
background-color: #222; /* or any other dark color */
|
||||
color: rgb(var(--base-font-color)) !important; /* or any other light color */
|
||||
}
|
||||
|
||||
.list-group {
|
||||
background-color: #222 !important;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
.list-group-item {
|
||||
background-color: #222 !important;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
#support-section {
|
||||
background-color: #444 !important;
|
||||
}
|
||||
|
||||
#pages-container-wrapper {
|
||||
--background-color: rgba(255, 255, 255, 0.046) !important;
|
||||
--scroll-bar-color: #4c4c4c !important;
|
||||
--scroll-bar-thumb: #d3d3d3 !important;
|
||||
--scroll-bar-thumb-hover: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
|
||||
.favorite-icon img {
|
||||
filter: brightness(0) invert(1) !important;
|
||||
}
|
||||
table thead {
|
||||
background-color: #333 !important;
|
||||
border: 1px solid #444;
|
||||
}
|
||||
table th, table td {
|
||||
border: 1px solid #444 !important;
|
||||
color: white;
|
||||
}
|
||||
.btn {
|
||||
background-color: #444 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-primary {
|
||||
background-color: #007bff !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-secondary {
|
||||
background-color: #6c757d !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-info {
|
||||
background-color: #17a2b8 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-danger {
|
||||
background-color: #dc3545 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.btn-warning {
|
||||
background-color: #ffc107 !important;
|
||||
border: none;
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.btn-outline-secondary {
|
||||
color: #fff !important;
|
||||
border-color: #fff;
|
||||
}
|
||||
.btn-outline-secondary:hover {
|
||||
background-color: #444 !important;
|
||||
color: #007bff !important;
|
||||
border-color: #007bff;
|
||||
}
|
||||
.blackwhite-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
hr {
|
||||
border-color: rgba(255, 255, 255, 0.6); /* semi-transparent white */
|
||||
background-color: rgba(255, 255, 255, 0.6); /* for some browsers that might use background instead of border for <hr> */
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
color: #fff !important;
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
#global-buttons-container input {
|
||||
background-color: #323948;
|
||||
caret-color: #ffffff;
|
||||
color: #ffffff;
|
||||
}
|
||||
#global-buttons-container input::placeholder {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#global-buttons-container input:disabled::-webkit-input-placeholder { /* WebKit browsers */
|
||||
color: #6E6865;
|
||||
}
|
||||
#global-buttons-container input:disabled:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
|
||||
color: #6E6865;
|
||||
}
|
||||
#global-buttons-container input:disabled::-moz-placeholder { /* Mozilla Firefox 19+ */
|
||||
color: #6E6865;
|
||||
}
|
||||
#global-buttons-container input:disabled:-ms-input-placeholder { /* Internet Explorer 10+ */
|
||||
color: #6E6865;
|
||||
}
|
||||
|
||||
/* Dark Mode Styles */
|
||||
body,
|
||||
select,
|
||||
textarea {
|
||||
--body-background-color: 51, 51, 51;
|
||||
--base-font-color: 255, 255, 255;
|
||||
background-color: rgb(var(--body-background-color)) !important;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
.card {
|
||||
background-color: rgb(var(--body-background-color)) !important;
|
||||
border: 1px solid #999;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #add8e6;
|
||||
}
|
||||
a:hover {
|
||||
color: #87ceeb; /* Slightly brighter blue on hover for accessibility */
|
||||
}
|
||||
|
||||
.dark-card {
|
||||
background-color: rgb(var(--body-background-color)) !important;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
.jumbotron {
|
||||
background-color: #222; /* or any other dark color */
|
||||
color: rgb(var(--base-font-color)) !important; /* or any other light color */
|
||||
}
|
||||
|
||||
.list-group {
|
||||
background-color: #222 !important;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
.list-group-item {
|
||||
background-color: #222 !important;
|
||||
color: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
#support-section {
|
||||
background-color: #444 !important;
|
||||
}
|
||||
|
||||
#pages-container-wrapper {
|
||||
--background-color: rgba(255, 255, 255, 0.046) !important;
|
||||
--scroll-bar-color: #4c4c4c !important;
|
||||
--scroll-bar-thumb: #d3d3d3 !important;
|
||||
--scroll-bar-thumb-hover: rgb(var(--base-font-color)) !important;
|
||||
}
|
||||
|
||||
.favorite-icon img {
|
||||
filter: brightness(0) invert(1) !important;
|
||||
}
|
||||
table thead {
|
||||
background-color: #333 !important;
|
||||
border: 1px solid #444;
|
||||
}
|
||||
table th,
|
||||
table td {
|
||||
border: 1px solid #444 !important;
|
||||
color: white;
|
||||
}
|
||||
.btn {
|
||||
background-color: #444 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-primary {
|
||||
background-color: #007bff !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-secondary {
|
||||
background-color: #6c757d !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-info {
|
||||
background-color: #17a2b8 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
.btn-danger {
|
||||
background-color: #dc3545 !important;
|
||||
border: none;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.btn-warning {
|
||||
background-color: #ffc107 !important;
|
||||
border: none;
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.btn-outline-secondary {
|
||||
color: #fff !important;
|
||||
border-color: #fff;
|
||||
}
|
||||
.btn-outline-secondary:hover {
|
||||
background-color: #444 !important;
|
||||
color: #007bff !important;
|
||||
border-color: #007bff;
|
||||
}
|
||||
.blackwhite-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
hr {
|
||||
border-color: rgba(255, 255, 255, 0.6); /* semi-transparent white */
|
||||
background-color: rgba(255, 255, 255, 0.6); /* for some browsers that might use background instead of border for <hr> */
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
color: #fff !important;
|
||||
border-color: #fff;
|
||||
}
|
||||
|
||||
#global-buttons-container input {
|
||||
background-color: #323948;
|
||||
caret-color: #ffffff;
|
||||
color: #ffffff;
|
||||
}
|
||||
#global-buttons-container input::placeholder {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
#global-buttons-container input:disabled::-webkit-input-placeholder {
|
||||
/* WebKit browsers */
|
||||
color: #6e6865;
|
||||
}
|
||||
#global-buttons-container input:disabled:-moz-placeholder {
|
||||
/* Mozilla Firefox 4 to 18 */
|
||||
color: #6e6865;
|
||||
}
|
||||
#global-buttons-container input:disabled::-moz-placeholder {
|
||||
/* Mozilla Firefox 19+ */
|
||||
color: #6e6865;
|
||||
}
|
||||
#global-buttons-container input:disabled:-ms-input-placeholder {
|
||||
/* Internet Explorer 10+ */
|
||||
color: #6e6865;
|
||||
}
|
||||
|
||||
@@ -1,78 +1,78 @@
|
||||
#drag-container {
|
||||
position: fixed;
|
||||
display:flex;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 10000;
|
||||
visibility: hidden;
|
||||
position: fixed;
|
||||
display: flex;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
z-index: 10000;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#drag-container:not(:empty) {
|
||||
visibility: visible;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#drag-container .dragged-img {
|
||||
position: fixed;
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.58);
|
||||
transform-origin: top left;
|
||||
position: fixed;
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.58);
|
||||
transform-origin: top left;
|
||||
}
|
||||
|
||||
.drag-manager_dragging {
|
||||
width: 0px;
|
||||
visibility: hidden;
|
||||
width: 0px;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.drag-manager_draghover {
|
||||
width: 375px !important;
|
||||
width: 375px !important;
|
||||
}
|
||||
|
||||
.drag-manager_draghover .insert-file-button-container {
|
||||
display: none !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.drag-manager_draghover .button-container {
|
||||
visibility: hidden !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
html[lang-direction=ltr] .drag-manager_draghover img {
|
||||
left: calc(50% + 62.5px) !important;
|
||||
html[lang-direction="ltr"] .drag-manager_draghover img {
|
||||
left: calc(50% + 62.5px) !important;
|
||||
}
|
||||
|
||||
html[lang-direction=rtl] .drag-manager_draghover img {
|
||||
left: 125px
|
||||
html[lang-direction="rtl"] .drag-manager_draghover img {
|
||||
left: 125px;
|
||||
}
|
||||
|
||||
.drag-manager_dragging-container .hide-on-drag {
|
||||
display: none !important;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.drag-manager_endpoint {
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
background-color: #FFFFFF10;
|
||||
transition: width 0.1s;
|
||||
animation: end-drop-expand .3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
background-color: #ffffff10;
|
||||
transition: width 0.1s;
|
||||
animation: end-drop-expand 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.drag-manager_endpoint svg {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.drag-manager_endpoint.drag-manager_draghover {
|
||||
width: 150px !important;
|
||||
width: 150px !important;
|
||||
}
|
||||
|
||||
@keyframes end-drop-expand {
|
||||
from {
|
||||
width: 0;
|
||||
}
|
||||
to {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
from {
|
||||
width: 0;
|
||||
}
|
||||
to {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
88
src/main/resources/static/css/error.css
Normal file
@@ -0,0 +1,88 @@
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin-top: 10%;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: #005b7f;
|
||||
}
|
||||
|
||||
.features-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(21rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.feature-card .card-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#support-section {
|
||||
background-color: #f9f9f9;
|
||||
padding: 4rem;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#support-section h1 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#support-section p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#button-group {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
#github-button,
|
||||
#discord-button {
|
||||
display: inline-block;
|
||||
padding: 1rem 2rem;
|
||||
margin: 1rem;
|
||||
background-color: #008cba;
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 3rem;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
#github-button:hover,
|
||||
#discord-button:hover,
|
||||
#home-button:hover {
|
||||
background-color: #005b7f;
|
||||
}
|
||||
|
||||
#home-button {
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
margin: 2em auto;
|
||||
background-color: #008cba;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
border-radius: 25px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
@@ -1,94 +1,97 @@
|
||||
#errorContainer {
|
||||
margin: 20px; /* adjust this value as needed */
|
||||
margin: 20px; /* adjust this value as needed */
|
||||
}
|
||||
|
||||
#helpModalDialog {
|
||||
width: 90%;
|
||||
max-width: 800px;
|
||||
width: 90%;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
#helpModal h1 {
|
||||
text-align: center;
|
||||
margin-top: 10%;
|
||||
text-align: center;
|
||||
margin-top: 10%;
|
||||
}
|
||||
|
||||
#helpModal p {
|
||||
text-align: center;
|
||||
margin-top: 2em;
|
||||
text-align: center;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
#helpModal .button:hover {
|
||||
background-color: #005b7f;
|
||||
background-color: #005b7f;
|
||||
}
|
||||
|
||||
#helpModal .features-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(21rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(21rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
}
|
||||
|
||||
#helpModal .feature-card {
|
||||
border: 1px solid rgba(0, 0, 0, .125);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
#helpModal .feature-card .card-text {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#support-section {
|
||||
background-color: #f9f9f9;
|
||||
padding: 4rem;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
background-color: #f9f9f9;
|
||||
padding: 4rem;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#support-section h1 {
|
||||
margin-top: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#support-section p {
|
||||
margin-top: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#button-group {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
#github-button, #discord-button {
|
||||
display: inline-block;
|
||||
padding: 1rem 2rem;
|
||||
margin: 1rem;
|
||||
background-color: #008CBA;
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 3rem;
|
||||
transition: all 0.3s ease-in-out;
|
||||
#github-button,
|
||||
#discord-button {
|
||||
display: inline-block;
|
||||
padding: 1rem 2rem;
|
||||
margin: 1rem;
|
||||
background-color: #008cba;
|
||||
color: #fff;
|
||||
font-size: 1.2rem;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
border-radius: 3rem;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
#github-button:hover, #discord-button:hover, #home-button:hover {
|
||||
background-color: #005b7f;
|
||||
#github-button:hover,
|
||||
#discord-button:hover,
|
||||
#home-button:hover {
|
||||
background-color: #005b7f;
|
||||
}
|
||||
|
||||
#home-button {
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
margin: 2em auto;
|
||||
background-color: #008CBA;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
border-radius: 25px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
margin: 2em auto;
|
||||
background-color: #008cba;
|
||||
color: white;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
border-radius: 25px;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
.custom-file-label {
|
||||
padding-right: 90px;
|
||||
padding-right: 90px;
|
||||
}
|
||||
|
||||
.selected-files {
|
||||
margin-top: 10px;
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
margin-top: 10px;
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
20
src/main/resources/static/css/footer.css
Normal file
@@ -0,0 +1,20 @@
|
||||
#footer {
|
||||
display: flex;
|
||||
flex-direction: column; /* Stack children vertically */
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.footer-center {
|
||||
display: flex;
|
||||
align-items: center; /* Center children horizontally */
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.footer-powered-by {
|
||||
margin-top: auto; /* Pushes the text to the bottom */
|
||||
color: grey;
|
||||
text-align: center; /* Centers the text inside the div */
|
||||
width: 100%; /* Full width to center the text properly */
|
||||
}
|
||||
@@ -1,49 +1,54 @@
|
||||
#game-container {
|
||||
position: relative;
|
||||
width: 100vh;
|
||||
height: 0;
|
||||
padding-bottom: 75%; /* 4:3 aspect ratio */
|
||||
background-color: transparent;
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
border: 2px solid black; /* Add border */
|
||||
position: relative;
|
||||
width: 100vh;
|
||||
height: 0;
|
||||
padding-bottom: 75%; /* 4:3 aspect ratio */
|
||||
background-color: transparent;
|
||||
margin: auto;
|
||||
overflow: hidden;
|
||||
border: 2px solid black; /* Add border */
|
||||
}
|
||||
|
||||
.pdf, .player, .projectile {
|
||||
position: absolute;
|
||||
.pdf,
|
||||
.player,
|
||||
.projectile {
|
||||
position: absolute;
|
||||
}
|
||||
.pdf {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.player {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.projectile {
|
||||
background-color: black !important;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
background-color: black !important;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
}
|
||||
#score, #level, #lives, #high-score {
|
||||
color: black;
|
||||
font-family: sans-serif;
|
||||
position: absolute;
|
||||
font-size: calc(14px + 0.25vw); /* Reduced font size */
|
||||
#score,
|
||||
#level,
|
||||
#lives,
|
||||
#high-score {
|
||||
color: black;
|
||||
font-family: sans-serif;
|
||||
position: absolute;
|
||||
font-size: calc(14px + 0.25vw); /* Reduced font size */
|
||||
}
|
||||
#score {
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
}
|
||||
#lives {
|
||||
top: 10px;
|
||||
left: calc(7vw); /* Adjusted position */
|
||||
top: 10px;
|
||||
left: calc(9vw); /* Adjusted position */
|
||||
}
|
||||
#high-score {
|
||||
top: 10px;
|
||||
left: calc(14vw); /* Adjusted position */
|
||||
top: 10px;
|
||||
left: calc(14vw); /* Adjusted position */
|
||||
}
|
||||
#level {
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
@@ -1,94 +1,94 @@
|
||||
#page-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#content-wrap {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#footer {
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.navbar {
|
||||
height: auto; /* Adjusts height automatically based on content */
|
||||
white-space: nowrap; /* Prevents wrapping of navbar contents */
|
||||
}
|
||||
/* TODO enable later
|
||||
.navbar .container {
|
||||
|
||||
|
||||
max-width: 100%; //Allows the container to expand up to full width
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}*/
|
||||
|
||||
html[lang-direction=ltr] * {
|
||||
direction: ltr;
|
||||
}
|
||||
html[lang-direction=rtl] * {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
}
|
||||
.ignore-rtl {
|
||||
direction: ltr !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.align-top {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
.align-center-right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.align-center-left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.align-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.btn-group > label:first-of-type {
|
||||
border-top-left-radius: 0.25rem !important;
|
||||
border-bottom-left-radius: 0.25rem !important;
|
||||
}
|
||||
|
||||
html[lang-direction="rtl"] input.form-check-input {
|
||||
position: relative;
|
||||
margin-left: 0px;
|
||||
}
|
||||
html[lang-direction="rtl"] label.form-check-label {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.margin-auto-parent {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
.margin-center {
|
||||
margin: 0 auto;
|
||||
}
|
||||
#pdf-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
width: 100%;
|
||||
}
|
||||
.fixed-shadow-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
width: 100%;
|
||||
}
|
||||
.shadow-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
#page-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#content-wrap {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#footer {
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.navbar {
|
||||
height: auto; /* Adjusts height automatically based on content */
|
||||
white-space: nowrap; /* Prevents wrapping of navbar contents */
|
||||
}
|
||||
/* TODO enable later
|
||||
.navbar .container {
|
||||
|
||||
|
||||
max-width: 100%; //Allows the container to expand up to full width
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}*/
|
||||
|
||||
html[lang-direction="ltr"] * {
|
||||
direction: ltr;
|
||||
}
|
||||
html[lang-direction="rtl"] * {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
}
|
||||
.ignore-rtl {
|
||||
direction: ltr !important;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.align-top {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
.align-center-right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.align-center-left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.align-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.btn-group > label:first-of-type {
|
||||
border-top-left-radius: 0.25rem !important;
|
||||
border-bottom-left-radius: 0.25rem !important;
|
||||
}
|
||||
|
||||
html[lang-direction="rtl"] input.form-check-input {
|
||||
position: relative;
|
||||
margin-left: 0px;
|
||||
}
|
||||
html[lang-direction="rtl"] label.form-check-label {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.margin-auto-parent {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
.margin-center {
|
||||
margin: 0 auto;
|
||||
}
|
||||
#pdf-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
width: 100%;
|
||||
}
|
||||
.fixed-shadow-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
width: 100%;
|
||||
}
|
||||
.shadow-canvas {
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,64 +1,62 @@
|
||||
#searchBar {
|
||||
background-image: url('../images/search.svg');
|
||||
background-position: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
margin-bottom: 12px;
|
||||
padding: 12px 20px 12px 40px;
|
||||
border: 1px solid #ddd;
|
||||
|
||||
|
||||
background-image: url("../images/search.svg");
|
||||
background-position: 16px 16px;
|
||||
background-repeat: no-repeat;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
margin-bottom: 12px;
|
||||
padding: 12px 20px 12px 40px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
.dark-mode-search {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' hei… 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z'/%3E%3C/svg%3E") !important;
|
||||
color: #f8f9fa !important;
|
||||
background-color: #212529 !important;
|
||||
border-color: #343a40 !important;
|
||||
}
|
||||
|
||||
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' hei… 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z'/%3E%3C/svg%3E") !important;
|
||||
color: #f8f9fa !important;
|
||||
background-color: #212529 !important;
|
||||
border-color: #343a40 !important;
|
||||
}
|
||||
|
||||
.features-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 3fr));
|
||||
gap: 25px 30px;
|
||||
}
|
||||
|
||||
.feature-card {
|
||||
border: 2px solid rgba(0, 0, 0, .25);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
background: rgba(13, 110, 253, 0.05);
|
||||
transition: transform 0.3s, border 0.3s;
|
||||
transform-origin: center center;
|
||||
outline: 2px solid transparent;
|
||||
border: 2px solid rgba(0, 0, 0, 0.25);
|
||||
border-radius: 0.25rem;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
background: rgba(13, 110, 253, 0.05);
|
||||
transition:
|
||||
transform 0.3s,
|
||||
border 0.3s;
|
||||
transform-origin: center center;
|
||||
outline: 2px solid transparent;
|
||||
}
|
||||
|
||||
.feature-card a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.feature-card .card-text {
|
||||
flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
outline: 1px solid rgba(0, 0, 0, .5);
|
||||
cursor: pointer;
|
||||
transform: scale(1.1);
|
||||
outline: 1px solid rgba(0, 0, 0, 0.5);
|
||||
cursor: pointer;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.feature-card:hover .card-title {
|
||||
text-decoration: underline;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.card-title.text-primary {
|
||||
color: #000; /* Replace with your desired shade of blue */
|
||||
@@ -67,27 +65,27 @@
|
||||
.home-card-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
transform: translateY(-5px);
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
.home-card-icon-colour {
|
||||
filter: invert(0.2) sepia(2) saturate(50) hue-rotate(190deg);
|
||||
filter: invert(0.2) sepia(2) saturate(50) hue-rotate(190deg);
|
||||
}
|
||||
|
||||
.favorite-icon {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
/* Only show the favorite icons when the parent card is being hovered over */
|
||||
.feature-card:hover .favorite-icon {
|
||||
display: block;
|
||||
display: block;
|
||||
}
|
||||
.favorite-icon img {
|
||||
filter: brightness(0);
|
||||
filter: brightness(0);
|
||||
}
|
||||
|
||||
.jumbotron {
|
||||
padding: 3rem 3rem; /* Reduce vertical padding */
|
||||
padding: 3rem 3rem; /* Reduce vertical padding */
|
||||
}
|
||||
|
||||
@@ -1,40 +1,43 @@
|
||||
|
||||
#image-highlighter {
|
||||
position: fixed;
|
||||
display:flex;
|
||||
inset: 0;
|
||||
z-index: 10000;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
visibility: hidden;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: visbility 0.1s linear, background-color 0.1s linear;
|
||||
position: fixed;
|
||||
display: flex;
|
||||
inset: 0;
|
||||
z-index: 10000;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
visibility: hidden;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition:
|
||||
visbility 0.1s linear,
|
||||
background-color 0.1s linear;
|
||||
}
|
||||
|
||||
#image-highlighter > * {
|
||||
max-width: 80vw;
|
||||
max-height: 80vh;
|
||||
animation: image-highlight .1s linear;
|
||||
transition: transform .1s linear, opacity .1s linear;
|
||||
max-width: 80vw;
|
||||
max-height: 80vh;
|
||||
animation: image-highlight 0.1s linear;
|
||||
transition:
|
||||
transform 0.1s linear,
|
||||
opacity 0.1s linear;
|
||||
}
|
||||
|
||||
#image-highlighter > *.remove {
|
||||
transform: scale(0.8) !important;
|
||||
opacity: 0 !important;
|
||||
transform: scale(0.8) !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
|
||||
#image-highlighter:not(:empty) {
|
||||
background-color: rgba(0, 0, 0, 0.37);
|
||||
visibility: visible;
|
||||
background-color: rgba(0, 0, 0, 0.37);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
@keyframes image-highlight {
|
||||
from {
|
||||
transform: scale(0.8);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
from {
|
||||
transform: scale(0.8);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
9
src/main/resources/static/css/licenses.css
Normal file
@@ -0,0 +1,9 @@
|
||||
td a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
td a:hover,
|
||||
td a:focus {
|
||||
text-decoration: underline;
|
||||
/* Adds underline on hover/focus for clarity */
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
/* Dark Mode Styles */
|
||||
body {
|
||||
--body-background-color: 255, 255, 255;
|
||||
--base-font-color: 33, 37, 41;
|
||||
--body-background-color: 255, 255, 255;
|
||||
--base-font-color: 33, 37, 41;
|
||||
}
|
||||
|
||||
|
||||
#global-buttons-container input {
|
||||
background-color: #ffffff;
|
||||
/*caret-color: #ffffff;*/
|
||||
/*color: #ffffff;*/
|
||||
background-color: #ffffff;
|
||||
/*caret-color: #ffffff;*/
|
||||
/*color: #ffffff;*/
|
||||
}
|
||||
/*#global-buttons-container input:disabled::-webkit-input-placeholder { !* WebKit browsers *!*/
|
||||
/* color: #98A0AB;*/
|
||||
|
||||
111
src/main/resources/static/css/login.css
Normal file
@@ -0,0 +1,111 @@
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.form-signin {
|
||||
width: 100%;
|
||||
max-width: 330px;
|
||||
padding: 15px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.form-signin .checkbox {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.form-signin .form-floating:focus-within {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.form-signin input[type="text"] {
|
||||
margin-bottom: -1px;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.form-signin input[type="password"] {
|
||||
margin-bottom: 10px;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
.container-flex {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
width: 100%; /* Set width to 100% */
|
||||
align-items: center; /* Center its children horizontally */
|
||||
}
|
||||
.footer-bottom {
|
||||
margin-top: auto;
|
||||
}
|
||||
body.light-mode input:-webkit-autofill,
|
||||
body.light-mode input:-webkit-autofill:hover,
|
||||
body.light-mode input:-webkit-autofill:focus,
|
||||
body.light-mode input:-webkit-autofill:active {
|
||||
-webkit-text-fill-color: #212529; /* Dark font color */
|
||||
-webkit-box-shadow: 0 0 0 1000px #f8f9fa inset; /* Light background color */
|
||||
}
|
||||
|
||||
/* Dark Mode */
|
||||
body.dark-mode input:-webkit-autofill,
|
||||
body.dark-mode input:-webkit-autofill:hover,
|
||||
body.dark-mode input:-webkit-autofill:focus,
|
||||
body.dark-mode input:-webkit-autofill:active {
|
||||
-webkit-text-fill-color: #f8f9fa; /* Light font color */
|
||||
-webkit-box-shadow: 0 0 0 1000px #212529 inset; /* Dark background color */
|
||||
}
|
||||
/* Light Mode */
|
||||
body.light-mode .form-floating > input:focus + label {
|
||||
color: #212529 !important; /* Dark text for light background */
|
||||
}
|
||||
|
||||
/* Dark Mode */
|
||||
body.dark-mode .form-floating > input:focus + label {
|
||||
color: #fff !important; /* Light text for dark background */
|
||||
}
|
||||
|
||||
body.light-mode .form-floating > label {
|
||||
color: #212529 !important; /* Dark text for light background */
|
||||
}
|
||||
|
||||
body.dark-mode .form-floating > label {
|
||||
color: #fff !important; /* Light text for dark background */
|
||||
}
|
||||
|
||||
/* Removing default styles for ul and li */
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
/* Positioning the container of these elements to the top right */
|
||||
.your-container-class {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* Styling for the dropdown */
|
||||
.dropdown-menu {
|
||||
min-width: 200px; /* or whatever width you prefer */
|
||||
}
|
||||
|
||||
.navbar-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
@@ -1,29 +1,28 @@
|
||||
.list-group-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filename {
|
||||
flex-grow: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.arrows {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.arrows .btn {
|
||||
margin: 0 3px;
|
||||
}
|
||||
|
||||
.move-up span,
|
||||
.move-down span {
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
|
||||
}
|
||||
.list-group-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filename {
|
||||
flex-grow: 1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.arrows {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.arrows .btn {
|
||||
margin: 0 3px;
|
||||
}
|
||||
|
||||
.move-up span,
|
||||
.move-down span {
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
119
src/main/resources/static/css/multi-tool.css
Normal file
@@ -0,0 +1,119 @@
|
||||
.multi-tool-container {
|
||||
max-width: 95vw;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#global-buttons-container {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: start;
|
||||
|
||||
background-color: rgba(13, 110, 253, 0.1);
|
||||
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||
backdrop-filter: blur(2px);
|
||||
|
||||
top: 10px;
|
||||
z-index: 10;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
#global-buttons-container > * {
|
||||
padding: 0.6rem 0.75rem;
|
||||
}
|
||||
|
||||
#global-buttons-container svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
#export-button {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
#pages-container-wrapper {
|
||||
--background-color: rgba(0, 0, 0, 0.025);
|
||||
--scroll-bar-color: #f1f1f1;
|
||||
--scroll-bar-thumb: #888;
|
||||
--scroll-bar-thumb-hover: #555;
|
||||
background-color: var(--background-color);
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px 25px;
|
||||
border-radius: 10px;
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
min-height: 275px;
|
||||
margin: 0 0 30px 0;
|
||||
}
|
||||
|
||||
#pages-container {
|
||||
margin: auto;
|
||||
gap: 0px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* width */
|
||||
#pages-container-wrapper::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
/* Track */
|
||||
#pages-container-wrapper::-webkit-scrollbar-track {
|
||||
background: var(--scroll-bar-color);
|
||||
}
|
||||
|
||||
/* Handle */
|
||||
#pages-container-wrapper::-webkit-scrollbar-thumb {
|
||||
border-radius: 10px;
|
||||
background: var(--scroll-bar-thumb);
|
||||
}
|
||||
|
||||
/* Handle on hover */
|
||||
#pages-container-wrapper::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--scroll-bar-thumb-hover);
|
||||
}
|
||||
|
||||
.page-container {
|
||||
height: 250px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column-reverse;
|
||||
aspect-ratio: 1;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
transition: width 1s linear;
|
||||
}
|
||||
|
||||
.page-container img {
|
||||
/* max-width: calc(100% - 15px); */
|
||||
max-height: calc(100% - 15px);
|
||||
max-width: 237px;
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
translate: -50% -50%;
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.384);
|
||||
border-radius: 4px;
|
||||
transition: rotate 0.3s;
|
||||
}
|
||||
|
||||
#add-pdf-button {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.page-number {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
color: white;
|
||||
background-color: #007bff; /* Primary blue color */
|
||||
padding: 3px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
z-index: 2;
|
||||
}
|
||||
@@ -1,80 +1,116 @@
|
||||
|
||||
|
||||
#navbarSearch {
|
||||
top: 100%;
|
||||
right: 0;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
transition: all 0.3s;
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#navbarSearch.show {
|
||||
max-height: 300px; /* Adjust this to your desired max height */
|
||||
}
|
||||
|
||||
#searchForm {
|
||||
width: 200px; /* Adjust this value as needed */
|
||||
width: 200px; /* Adjust this value as needed */
|
||||
}
|
||||
|
||||
/* Style the search results to match the navbar */
|
||||
#searchResults {
|
||||
max-height: 200px; /* Adjust this value as needed */
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
max-height: 200px; /* Adjust this value as needed */
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
max-width: 300px; /* Adjust to your preferred width */
|
||||
transition: height 0.3s ease; /* Smooth height transition */
|
||||
}
|
||||
|
||||
#searchResults .dropdown-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
height: 50px; /* Fixed height */
|
||||
overflow: hidden; /* Hide overflow */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
height: 50px; /* Fixed height */
|
||||
overflow: hidden; /* Hide overflow */
|
||||
}
|
||||
|
||||
#searchResults .icon {
|
||||
margin-right: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#searchResults .icon-text {
|
||||
display: inline;
|
||||
overflow: hidden; /* Hide overflow */
|
||||
text-overflow: ellipsis; /* Add ellipsis for long text */
|
||||
display: inline;
|
||||
overflow: hidden; /* Hide overflow */
|
||||
text-overflow: ellipsis; /* Add ellipsis for long text */
|
||||
}
|
||||
|
||||
#search-icon i {
|
||||
font-size: 24px; /* Adjust this to your desired size */
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
#search-icon:hover i {
|
||||
color: #666; /* Adjust this to your hover color */
|
||||
}
|
||||
|
||||
.search-input {
|
||||
transition:
|
||||
border 0.3s,
|
||||
box-shadow 0.3s;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
border-color: #666; /* Adjust this to your focus color */
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* Adjust this to your desired shadow */
|
||||
}
|
||||
|
||||
/* Set a fixed height and styling for each search result item */
|
||||
.search-results a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px; /* space between icon and text */
|
||||
height: 40px; /* Adjust based on your design */
|
||||
overflow: hidden; /* Prevent content from overflowing */
|
||||
white-space: nowrap; /* Prevent text from wrapping to next line */
|
||||
text-overflow: ellipsis; /* Truncate text if it's too long */
|
||||
}
|
||||
|
||||
.main-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
vertical-align: middle;
|
||||
transform: translateY(-2px);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
vertical-align: middle;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
transform: translateY(-2px);
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
vertical-align: middle;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.icon+.icon {
|
||||
margin-left: -4px;
|
||||
.icon + .icon {
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.icon-text {
|
||||
margin-left: 4px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.nav-item-separator {
|
||||
position: relative;
|
||||
margin: 0 4px; /* Adjust the margin as needed */
|
||||
position: relative;
|
||||
margin: 0 4px; /* Adjust the margin as needed */
|
||||
}
|
||||
|
||||
.nav-item-separator::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 10%; /* Adjust the top and bottom margins as needed */
|
||||
bottom: 10%;
|
||||
width: 1px;
|
||||
background-color: #ccc; /* Adjust the color as needed */
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 10%; /* Adjust the top and bottom margins as needed */
|
||||
bottom: 10%;
|
||||
width: 1px;
|
||||
background-color: #ccc; /* Adjust the color as needed */
|
||||
}
|
||||
|
||||
.navbar-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
@@ -1,87 +1,85 @@
|
||||
|
||||
.pdf-actions_button-container {
|
||||
z-index: 2;
|
||||
display:flex;
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s linear;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
opacity: 0;
|
||||
transition: opacity 0.1s linear;
|
||||
}
|
||||
|
||||
.pdf-actions_container:hover .pdf-actions_button-container {
|
||||
opacity: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.pdf-actions_button-container > * {
|
||||
padding: 0.25rem 0.5rem;
|
||||
margin: 3px;
|
||||
display: block;
|
||||
padding: 0.25rem 0.5rem;
|
||||
margin: 3px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pdf-actions_container svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.pdf-actions_container:nth-child(1) .pdf-actions_move-left-button {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
.pdf-actions_container:last-child .pdf-actions_move-right-button {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* "insert pdf" buttons that appear on the right when hover */
|
||||
.pdf-actions_insert-file-button-container {
|
||||
translate: 0 -50%;
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
|
||||
z-index: 1;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
translate: 0 -50%;
|
||||
width: 80px;
|
||||
height: 100%;
|
||||
|
||||
z-index: 1;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.pdf-actions_insert-file-button-container.left {
|
||||
left: -20px;
|
||||
left: -20px;
|
||||
}
|
||||
|
||||
.pdf-actions_insert-file-button-container.right {
|
||||
right: -20px;
|
||||
right: -20px;
|
||||
}
|
||||
|
||||
html[lang-direction=ltr] .pdf-actions_insert-file-button-container.right {
|
||||
display:none;
|
||||
html[lang-direction="ltr"] .pdf-actions_insert-file-button-container.right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
html[lang-direction=rtl] .pdf-actions_insert-file-button-container.left {
|
||||
display:none;
|
||||
html[lang-direction="rtl"] .pdf-actions_insert-file-button-container.left {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pdf-actions_insert-file-button-container.left .pdf-actions_insert-file-button {
|
||||
left: 0;
|
||||
translate: 0 -50%;
|
||||
left: 0;
|
||||
translate: 0 -50%;
|
||||
}
|
||||
|
||||
.pdf-actions_insert-file-button-container.right .pdf-actions_insert-file-button {
|
||||
right: 0;
|
||||
translate: 0 -50%;
|
||||
right: 0;
|
||||
translate: 0 -50%;
|
||||
}
|
||||
|
||||
html[lang-direction=ltr] .pdf-actions_container:last-child > .pdf-actions_insert-file-button-container.right {
|
||||
display: block;
|
||||
html[lang-direction="ltr"] .pdf-actions_container:last-child > .pdf-actions_insert-file-button-container.right {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
html[lang-direction=rtl] .pdf-actions_container:last-child > .pdf-actions_insert-file-button-container.left {
|
||||
display: block;
|
||||
html[lang-direction="rtl"] .pdf-actions_container:last-child > .pdf-actions_insert-file-button-container.left {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.pdf-actions_insert-file-button-container:hover {
|
||||
opacity: 1;
|
||||
transition: opacity 0.05s;
|
||||
opacity: 1;
|
||||
transition: opacity 0.05s;
|
||||
}
|
||||
.pdf-actions_insert-file-button {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 50%;
|
||||
translate: 50% -50%;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 100px;
|
||||
}
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 50%;
|
||||
translate: 50% -50%;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 100px;
|
||||
}
|
||||
|
||||
21
src/main/resources/static/css/pipeline.css
Normal file
@@ -0,0 +1,21 @@
|
||||
.btn-margin {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.bordered-box {
|
||||
border: 1px solid #ddd;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.center-element {
|
||||
width: 80%;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.element-margin {
|
||||
margin: 10px 0;
|
||||
/* Adjust this value to increase/decrease the margin as needed */
|
||||
}
|
||||
@@ -1,37 +1,113 @@
|
||||
/* Rainbow Mode Styles */
|
||||
body {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%);
|
||||
color: #fff !important;
|
||||
--body-background-color: 255, 255, 255;
|
||||
--base-font-color: 33, 37, 41;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
);
|
||||
color: #fff !important;
|
||||
--body-background-color: 255, 255, 255;
|
||||
--base-font-color: 33, 37, 41;
|
||||
}
|
||||
|
||||
.dark-card {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
color: white !important;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
) !important;
|
||||
color: white !important;
|
||||
}
|
||||
.jumbotron {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%);
|
||||
color: #fff !important;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
);
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
color: fff !important;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
) !important;
|
||||
color: fff !important;
|
||||
}
|
||||
.list-group-item {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
color: fff !important;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
) !important;
|
||||
color: fff !important;
|
||||
}
|
||||
#support-section {
|
||||
background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%) !important;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 0, 0, 1) 0%,
|
||||
rgba(255, 154, 0, 1) 10%,
|
||||
rgba(208, 222, 33, 1) 20%,
|
||||
rgba(79, 220, 74, 1) 30%,
|
||||
rgba(63, 218, 216, 1) 40%,
|
||||
rgba(47, 201, 226, 1) 50%,
|
||||
rgba(28, 127, 238, 1) 60%,
|
||||
rgba(95, 21, 242, 1) 70%,
|
||||
rgba(186, 12, 248, 1) 80%,
|
||||
rgba(251, 7, 217, 1) 90%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
) !important;
|
||||
}
|
||||
|
||||
|
||||
#pages-container-wrapper {
|
||||
--background-color: rgba(255, 255, 255, 0.046) !important;
|
||||
--scroll-bar-color: #4c4c4c !important;
|
||||
--scroll-bar-thumb: #d3d3d3 !important;
|
||||
--scroll-bar-thumb-hover: #ffffff !important;
|
||||
}
|
||||
|
||||
|
||||
29
src/main/resources/static/css/rotate-pdf.css
Normal file
@@ -0,0 +1,29 @@
|
||||
#pdf-preview {
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
max-width: calc(100% - 30px);
|
||||
max-height: calc(100% - 30px);
|
||||
box-shadow: 0 0 4px rgba(100, 100, 100, 0.25);
|
||||
transition: rotate 0.3s;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
translate: -50% -50%;
|
||||
}
|
||||
|
||||
.previewContainer {
|
||||
aspect-ratio: 1;
|
||||
width: 100%;
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
border-radius: 0.25rem;
|
||||
margin: 1rem 0;
|
||||
padding: 15px;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.buttonContainer {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
39
src/main/resources/static/css/sign.css
Normal file
@@ -0,0 +1,39 @@
|
||||
select#font-select,
|
||||
select#font-select option {
|
||||
height: 60px; /* Adjust as needed */
|
||||
font-size: 30px; /* Adjust as needed */
|
||||
}
|
||||
|
||||
.drawing-pad-container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#drawing-pad-canvas {
|
||||
background: rgba(125, 125, 125, 0.2);
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
#box-drag-container {
|
||||
position: relative;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.draggable-buttons-box {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
.draggable-buttons-box > button {
|
||||
z-index: 10;
|
||||
background-color: rgba(13, 110, 253, 0.1);
|
||||
}
|
||||
.draggable-canvas {
|
||||
border: 1px solid red;
|
||||
position: absolute;
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
top: 0px;
|
||||
left: 0;
|
||||
}
|
||||
10
src/main/resources/static/css/split-pdf-by-sections.css
Normal file
@@ -0,0 +1,10 @@
|
||||
.pdf-visual-aid {
|
||||
width: 150px; /* Adjust as needed */
|
||||
height: 200px; /* Adjust as needed */
|
||||
border: 1px solid black; /* Represents the PDF page */
|
||||
position: relative;
|
||||
}
|
||||
.line {
|
||||
position: absolute;
|
||||
background-color: red; /* Line color */
|
||||
}
|
||||
41
src/main/resources/static/css/stamp.css
Normal file
@@ -0,0 +1,41 @@
|
||||
.a4container {
|
||||
position: relative;
|
||||
width: 50%;
|
||||
aspect-ratio: 0.707;
|
||||
border: 1px solid #ddd;
|
||||
box-sizing: border-box;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.pageNumber {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 1em;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
background-color: #ccc;
|
||||
width: 15%;
|
||||
height: 15%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.pageNumber:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
#myForm {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.selectedPosition {
|
||||
background-color: #0a0;
|
||||
}
|
||||
|
||||
.selectedPosition.selectedHovered {
|
||||
background-color: #006600;
|
||||
}
|
||||
@@ -1,26 +1,24 @@
|
||||
|
||||
.tab-group {
|
||||
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
.tab-container.active {
|
||||
display: block;
|
||||
border: 1px solid rgba(var(--base-font-color), 0.25);
|
||||
padding: 15px;
|
||||
display: block;
|
||||
border: 1px solid rgba(var(--base-font-color), 0.25);
|
||||
padding: 15px;
|
||||
}
|
||||
.tab-buttons > button {
|
||||
margin-bottom: -1px;
|
||||
background: 0 0;
|
||||
border: 1px solid transparent;
|
||||
color: rgb(var(--base-font-color));
|
||||
|
||||
border-top-left-radius: 0.25rem;
|
||||
border-top-right-radius: 0.25rem;
|
||||
margin-bottom: -1px;
|
||||
background: 0 0;
|
||||
border: 1px solid transparent;
|
||||
color: rgb(var(--base-font-color));
|
||||
|
||||
border-top-left-radius: 0.25rem;
|
||||
border-top-right-radius: 0.25rem;
|
||||
}
|
||||
.tab-buttons > button.active {
|
||||
background-color: rgb(var(--body-background-color));
|
||||
border-color: rgba(var(--base-font-color), 0.25) rgba(var(--base-font-color), 0.25) rgb(var(--body-background-color));
|
||||
}
|
||||
background-color: rgb(var(--body-background-color));
|
||||
border-color: rgba(var(--base-font-color), 0.25) rgba(var(--base-font-color), 0.25) rgb(var(--body-background-color));
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs173">
|
||||
|
||||
|
||||
|
||||
|
||||
<linearGradient
|
||||
id="XMLID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
@@ -37,7 +37,7 @@
|
||||
style="stop-color:#C2C2C9"
|
||||
id="stop158" />
|
||||
</linearGradient>
|
||||
|
||||
|
||||
</defs><sodipodi:namedview
|
||||
id="namedview171"
|
||||
pagecolor="#ffffff"
|
||||
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@@ -1,26 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1235" height="650" viewBox="0 0 7410 3900">
|
||||
<rect width="7410" height="3900" fill="#b22234"/>
|
||||
<path d="M0,450H7410m0,600H0m0,600H7410m0,600H0m0,600H7410m0,600H0" stroke="#fff" stroke-width="300"/>
|
||||
<rect width="2964" height="2100" fill="#3c3b6e"/>
|
||||
<g fill="#fff">
|
||||
<g id="s18">
|
||||
<g id="s9">
|
||||
<g id="s5">
|
||||
<g id="s4">
|
||||
<path id="s" d="M247,90 317.534230,307.082039 132.873218,172.917961H361.126782L176.465770,307.082039z"/>
|
||||
<use xlink:href="#s" y="420"/>
|
||||
<use xlink:href="#s" y="840"/>
|
||||
<use xlink:href="#s" y="1260"/>
|
||||
</g>
|
||||
<use xlink:href="#s" y="1680"/>
|
||||
</g>
|
||||
<use xlink:href="#s4" x="247" y="210"/>
|
||||
</g>
|
||||
<use xlink:href="#s9" x="494"/>
|
||||
</g>
|
||||
<use xlink:href="#s18" x="988"/>
|
||||
<use xlink:href="#s9" x="1976"/>
|
||||
<use xlink:href="#s5" x="2470"/>
|
||||
</g>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1235" height="650" viewBox="0 0 7410 3900">
|
||||
<rect width="7410" height="3900" fill="#b22234"/>
|
||||
<path d="M0,450H7410m0,600H0m0,600H7410m0,600H0m0,600H7410m0,600H0" stroke="#fff" stroke-width="300"/>
|
||||
<rect width="2964" height="2100" fill="#3c3b6e"/>
|
||||
<g fill="#fff">
|
||||
<g id="s18">
|
||||
<g id="s9">
|
||||
<g id="s5">
|
||||
<g id="s4">
|
||||
<path id="s" d="M247,90 317.534230,307.082039 132.873218,172.917961H361.126782L176.465770,307.082039z"/>
|
||||
<use xlink:href="#s" y="420"/>
|
||||
<use xlink:href="#s" y="840"/>
|
||||
<use xlink:href="#s" y="1260"/>
|
||||
</g>
|
||||
<use xlink:href="#s" y="1680"/>
|
||||
</g>
|
||||
<use xlink:href="#s4" x="247" y="210"/>
|
||||
</g>
|
||||
<use xlink:href="#s9" x="494"/>
|
||||
</g>
|
||||
<use xlink:href="#s18" x="988"/>
|
||||
<use xlink:href="#s9" x="1976"/>
|
||||
<use xlink:href="#s5" x="2470"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 899 B After Width: | Height: | Size: 874 B |
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="35px" height="35px" viewBox="0 -0.5 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
|
||||
|
||||
<title>Github-color</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg version="1.1" id="Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
<svg version="1.1" id="Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 32 32" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
|
||||
|
||||
|
Before Width: | Height: | Size: 691 B After Width: | Height: | Size: 690 B |
@@ -1,5 +1,5 @@
|
||||
var toggleCount = 0
|
||||
var lastToggleTime = Date.now()
|
||||
var toggleCount = 0;
|
||||
var lastToggleTime = Date.now();
|
||||
|
||||
var elements = {
|
||||
lightModeStyles: null,
|
||||
@@ -11,18 +11,18 @@ var elements = {
|
||||
navbar: null,
|
||||
navIcons: null,
|
||||
navDropdownMenus: null,
|
||||
}
|
||||
};
|
||||
|
||||
function getElements() {
|
||||
elements.lightModeStyles = document.getElementById("light-mode-styles")
|
||||
elements.darkModeStyles = document.getElementById("dark-mode-styles")
|
||||
elements.rainbowModeStyles = document.getElementById("rainbow-mode-styles")
|
||||
elements.darkModeIcon = document.getElementById("dark-mode-icon")
|
||||
elements.searchBar = document.getElementById("searchBar")
|
||||
elements.formControls = document.querySelectorAll(".form-control")
|
||||
elements.navbar = document.querySelectorAll("nav.navbar")
|
||||
elements.navIcons = document.querySelectorAll("nav .icon, .navbar-icon")
|
||||
elements.navDropdownMenus = document.querySelectorAll("nav .dropdown-menu")
|
||||
elements.lightModeStyles = document.getElementById("light-mode-styles");
|
||||
elements.darkModeStyles = document.getElementById("dark-mode-styles");
|
||||
elements.rainbowModeStyles = document.getElementById("rainbow-mode-styles");
|
||||
elements.darkModeIcon = document.getElementById("dark-mode-icon");
|
||||
elements.searchBar = document.getElementById("searchBar");
|
||||
elements.formControls = document.querySelectorAll(".form-control");
|
||||
elements.navbar = document.querySelectorAll("nav.navbar");
|
||||
elements.navIcons = document.querySelectorAll("nav .icon, .navbar-icon");
|
||||
elements.navDropdownMenus = document.querySelectorAll(".dropdown-menu");
|
||||
}
|
||||
function setMode(mode) {
|
||||
var event = new CustomEvent("modeChanged", { detail: mode });
|
||||
@@ -48,22 +48,22 @@ function setMode(mode) {
|
||||
elements.searchBar.classList.add("dark-mode-search");
|
||||
}
|
||||
if (elements && elements.formControls) {
|
||||
elements.formControls.forEach(input => input.classList.add("bg-dark", "text-white"));
|
||||
elements.formControls.forEach((input) => input.classList.add("bg-dark", "text-white"));
|
||||
}
|
||||
if (elements && elements.navbar) {
|
||||
elements.navbar.forEach(navElement => {
|
||||
elements.navbar.forEach((navElement) => {
|
||||
navElement.classList.remove("navbar-light", "bg-light");
|
||||
navElement.classList.add("navbar-dark", "bg-dark");
|
||||
});
|
||||
}
|
||||
if (elements && elements.navDropdownMenus) {
|
||||
elements.navDropdownMenus.forEach(menu => menu.classList.add("dropdown-menu-dark"));
|
||||
elements.navDropdownMenus.forEach((menu) => menu.classList.add("dropdown-menu-dark"));
|
||||
}
|
||||
if (elements && elements.navIcons) {
|
||||
elements.navIcons.forEach(icon => (icon.style.filter = "invert(1)"));
|
||||
elements.navIcons.forEach((icon) => (icon.style.filter = "invert(1)"));
|
||||
}
|
||||
var tables = document.querySelectorAll(".table");
|
||||
tables.forEach(table => {
|
||||
tables.forEach((table) => {
|
||||
table.classList.add("table-dark");
|
||||
});
|
||||
if (jumbotron) {
|
||||
@@ -78,22 +78,22 @@ function setMode(mode) {
|
||||
elements.searchBar.classList.remove("dark-mode-search");
|
||||
}
|
||||
if (elements && elements.formControls) {
|
||||
elements.formControls.forEach(input => input.classList.remove("bg-dark", "text-white"));
|
||||
elements.formControls.forEach((input) => input.classList.remove("bg-dark", "text-white"));
|
||||
}
|
||||
if (elements && elements.navbar) {
|
||||
elements.navbar.forEach(navElement => {
|
||||
elements.navbar.forEach((navElement) => {
|
||||
navElement.classList.remove("navbar-dark", "bg-dark");
|
||||
navElement.classList.add("navbar-light", "bg-light");
|
||||
});
|
||||
}
|
||||
if (elements && elements.navDropdownMenus) {
|
||||
elements.navDropdownMenus.forEach(menu => menu.classList.remove("dropdown-menu-dark"));
|
||||
elements.navDropdownMenus.forEach((menu) => menu.classList.remove("dropdown-menu-dark"));
|
||||
}
|
||||
if (elements && elements.navIcons) {
|
||||
elements.navIcons.forEach(icon => (icon.style.filter = "none"));
|
||||
elements.navIcons.forEach((icon) => (icon.style.filter = "none"));
|
||||
}
|
||||
var tables = document.querySelectorAll(".table-dark");
|
||||
tables.forEach(table => {
|
||||
tables.forEach((table) => {
|
||||
table.classList.remove("table-dark");
|
||||
});
|
||||
if (jumbotron) {
|
||||
@@ -108,43 +108,43 @@ function setMode(mode) {
|
||||
}
|
||||
|
||||
function toggleDarkMode() {
|
||||
var currentTime = Date.now()
|
||||
var currentTime = Date.now();
|
||||
if (currentTime - lastToggleTime < 1000) {
|
||||
toggleCount++
|
||||
toggleCount++;
|
||||
} else {
|
||||
toggleCount = 1
|
||||
toggleCount = 1;
|
||||
}
|
||||
lastToggleTime = currentTime
|
||||
lastToggleTime = currentTime;
|
||||
|
||||
if (toggleCount >= 18) {
|
||||
localStorage.setItem("dark-mode", "rainbow")
|
||||
setMode("rainbow")
|
||||
localStorage.setItem("dark-mode", "rainbow");
|
||||
setMode("rainbow");
|
||||
} else if (localStorage.getItem("dark-mode") == "on") {
|
||||
localStorage.setItem("dark-mode", "off")
|
||||
setMode("off")
|
||||
localStorage.setItem("dark-mode", "off");
|
||||
setMode("off");
|
||||
} else {
|
||||
localStorage.setItem("dark-mode", "on")
|
||||
setMode("on")
|
||||
localStorage.setItem("dark-mode", "on");
|
||||
setMode("on");
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
getElements()
|
||||
getElements();
|
||||
|
||||
var currentMode = localStorage.getItem("dark-mode")
|
||||
var currentMode = localStorage.getItem("dark-mode");
|
||||
if (currentMode === "on" || currentMode === "off" || currentMode === "rainbow") {
|
||||
setMode(currentMode)
|
||||
setMode(currentMode);
|
||||
} else if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||
setMode("on")
|
||||
setMode("on");
|
||||
} else {
|
||||
setMode("off")
|
||||
setMode("off");
|
||||
}
|
||||
|
||||
var darkModeToggle = document.getElementById("dark-mode-toggle");
|
||||
if (darkModeToggle !== null) {
|
||||
darkModeToggle.addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
toggleDarkMode();
|
||||
});
|
||||
}
|
||||
})
|
||||
darkModeToggle.addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
toggleDarkMode();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,242 +1,265 @@
|
||||
function showErrorBanner(message, stackTrace) {
|
||||
const errorContainer = document.getElementById("errorContainer");
|
||||
errorContainer.style.display = "block"; // Display the banner
|
||||
document.querySelector("#errorContainer .alert-heading").textContent = "Error";
|
||||
document.querySelector("#errorContainer p").textContent = message;
|
||||
document.querySelector("#traceContent").textContent = stackTrace;
|
||||
const errorContainer = document.getElementById("errorContainer");
|
||||
errorContainer.style.display = "block"; // Display the banner
|
||||
document.querySelector("#errorContainer .alert-heading").textContent = "Error";
|
||||
document.querySelector("#errorContainer p").textContent = message;
|
||||
document.querySelector("#traceContent").textContent = stackTrace;
|
||||
}
|
||||
let firstErrorOccurred = false;
|
||||
let firstErrorOccurred = false;
|
||||
|
||||
$(document).ready(function() {
|
||||
$('form').submit(async function(event) {
|
||||
event.preventDefault();
|
||||
firstErrorOccurred = false;
|
||||
const url = this.action;
|
||||
const files = $('#fileInput-input')[0].files;
|
||||
const formData = new FormData(this);
|
||||
|
||||
// Remove empty file entries
|
||||
for (let [key, value] of formData.entries()) {
|
||||
if (value instanceof File && !value.name) {
|
||||
formData.delete(key);
|
||||
}
|
||||
$(document).ready(function () {
|
||||
$("form").submit(async function (event) {
|
||||
event.preventDefault();
|
||||
firstErrorOccurred = false;
|
||||
const url = this.action;
|
||||
const files = $("#fileInput-input")[0].files;
|
||||
const formData = new FormData(this);
|
||||
|
||||
// Remove empty file entries
|
||||
for (let [key, value] of formData.entries()) {
|
||||
if (value instanceof File && !value.name) {
|
||||
formData.delete(key);
|
||||
}
|
||||
}
|
||||
const override = $("#override").val() || "";
|
||||
const originalButtonText = $("#submitBtn").text();
|
||||
$("#submitBtn").text("Processing...");
|
||||
console.log(override);
|
||||
|
||||
// Set a timeout to show the game button if operation takes more than 5 seconds
|
||||
const timeoutId = setTimeout(() => {
|
||||
var boredWaiting = localStorage.getItem("boredWaiting") || "disabled";
|
||||
const showGameBtn = document.getElementById("show-game-btn");
|
||||
if (boredWaiting === "enabled" && showGameBtn) {
|
||||
showGameBtn.style.display = "block";
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
try {
|
||||
if (remoteCall === true) {
|
||||
if (override === "multi" || (!multiple && files.length > 1 && override !== "single")) {
|
||||
await submitMultiPdfForm(url, files);
|
||||
} else {
|
||||
await handleSingleDownload(url, formData);
|
||||
}
|
||||
const override = $('#override').val() || '';
|
||||
const originalButtonText = $('#submitBtn').text();
|
||||
$('#submitBtn').text('Processing...');
|
||||
console.log(override);
|
||||
try {
|
||||
if(remoteCall === true) {
|
||||
if (override === 'multi' || (!multiple && files.length > 1) && override !== 'single' ) {
|
||||
await submitMultiPdfForm(url, files);
|
||||
} else {
|
||||
await handleSingleDownload(url, formData);
|
||||
}
|
||||
}
|
||||
$('#submitBtn').text(originalButtonText);
|
||||
} catch (error) {
|
||||
handleDownloadError(error);
|
||||
$('#submitBtn').text(originalButtonText);
|
||||
console.error(error);
|
||||
}
|
||||
clearTimeout(timeoutId);
|
||||
$("#submitBtn").text(originalButtonText);
|
||||
|
||||
// After process finishes, check for boredWaiting and gameDialog open status
|
||||
const boredWaiting = localStorage.getItem("boredWaiting") || "disabled";
|
||||
const gameDialog = document.getElementById('game-container-wrapper');
|
||||
if (boredWaiting === "enabled" && gameDialog && gameDialog.open) {
|
||||
// Display a green banner at the bottom of the screen saying "Download complete"
|
||||
let downloadCompleteText = "Download Complete";
|
||||
if(window.downloadCompleteText){
|
||||
downloadCompleteText = window.downloadCompleteText;
|
||||
}
|
||||
});
|
||||
$("body").append('<div id="download-complete-banner" style="position:fixed;bottom:0;left:0;width:100%;background-color:green;color:white;text-align:center;padding:10px;font-size:16px;z-index:1000;">'+ downloadCompleteText + '</div>');
|
||||
setTimeout(function() {
|
||||
$("#download-complete-banner").fadeOut("slow", function() {
|
||||
$(this).remove(); // Remove the banner after fading out
|
||||
});
|
||||
}, 5000); // Banner will fade out after 5 seconds
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
clearTimeout(timeoutId);
|
||||
handleDownloadError(error);
|
||||
$("#submitBtn").text(originalButtonText);
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
async function handleSingleDownload(url, formData, isMulti = false, isZip = false) {
|
||||
try {
|
||||
const response = await fetch(url, { method: "POST", body: formData });
|
||||
const contentType = response.headers.get("content-type");
|
||||
|
||||
if (!response.ok) {
|
||||
if (contentType && contentType.includes("application/json")) {
|
||||
return handleJsonResponse(response);
|
||||
console.error("Throwing error banner, response was not okay");
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
async function handleSingleDownload(url, formData, isMulti = false , isZip = false) {
|
||||
try {
|
||||
const response = await fetch(url, { method: 'POST', body: formData });
|
||||
const contentType = response.headers.get('content-type');
|
||||
const contentDisposition = response.headers.get("Content-Disposition");
|
||||
let filename = getFilenameFromContentDisposition(contentDisposition);
|
||||
|
||||
if (!response.ok) {
|
||||
if (contentType && contentType.includes('application/json')) {
|
||||
return handleJsonResponse(response);
|
||||
console.error('Throwing error banner, response was not okay');
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const contentDisposition = response.headers.get('Content-Disposition');
|
||||
let filename = getFilenameFromContentDisposition(contentDisposition);
|
||||
|
||||
const blob = await response.blob();
|
||||
if (contentType.includes('application/pdf') || contentType.includes('image/')) {
|
||||
return handleResponse(blob, filename, !isMulti, isZip);
|
||||
} else {
|
||||
return handleResponse(blob, filename, false, isZip);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error in handleSingleDownload:', error);
|
||||
throw error; // Re-throw the error if you want it to be handled higher up.
|
||||
}
|
||||
const blob = await response.blob();
|
||||
if (contentType.includes("application/pdf") || contentType.includes("image/")) {
|
||||
return handleResponse(blob, filename, !isMulti, isZip);
|
||||
} else {
|
||||
return handleResponse(blob, filename, false, isZip);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error in handleSingleDownload:", error);
|
||||
throw error; // Re-throw the error if you want it to be handled higher up.
|
||||
}
|
||||
}
|
||||
|
||||
function getFilenameFromContentDisposition(contentDisposition) {
|
||||
let filename;
|
||||
let filename;
|
||||
|
||||
if (contentDisposition && contentDisposition.indexOf('attachment') !== -1) {
|
||||
filename = decodeURIComponent(contentDisposition.split('filename=')[1].replace(/"/g, '')).trim();
|
||||
} else {
|
||||
// If the Content-Disposition header is not present or does not contain the filename, use a default filename
|
||||
filename = 'download';
|
||||
}
|
||||
if (contentDisposition && contentDisposition.indexOf("attachment") !== -1) {
|
||||
filename = decodeURIComponent(contentDisposition.split("filename=")[1].replace(/"/g, "")).trim();
|
||||
} else {
|
||||
// If the Content-Disposition header is not present or does not contain the filename, use a default filename
|
||||
filename = "download";
|
||||
}
|
||||
|
||||
return filename;
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function handleJsonResponse(response) {
|
||||
const json = await response.json();
|
||||
const errorMessage = JSON.stringify(json, null, 2);
|
||||
if (errorMessage.toLowerCase().includes('the password is incorrect') || errorMessage.toLowerCase().includes('Password is not provided') || errorMessage.toLowerCase().includes('PDF contains an encryption dictionary')) {
|
||||
if (!firstErrorOccurred) {
|
||||
firstErrorOccurred = true;
|
||||
alert(pdfPasswordPrompt);
|
||||
}
|
||||
} else {
|
||||
showErrorBanner(json.error + ':' + json.message, json.trace);
|
||||
}
|
||||
const json = await response.json();
|
||||
const errorMessage = JSON.stringify(json, null, 2);
|
||||
if (
|
||||
errorMessage.toLowerCase().includes("the password is incorrect") ||
|
||||
errorMessage.toLowerCase().includes("Password is not provided") ||
|
||||
errorMessage.toLowerCase().includes("PDF contains an encryption dictionary")
|
||||
) {
|
||||
if (!firstErrorOccurred) {
|
||||
firstErrorOccurred = true;
|
||||
alert(pdfPasswordPrompt);
|
||||
}
|
||||
} else {
|
||||
showErrorBanner(json.error + ":" + json.message, json.trace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function handleResponse(blob, filename, considerViewOptions = false, isZip = false) {
|
||||
if (!blob) return;
|
||||
const downloadOption = localStorage.getItem('downloadOption');
|
||||
if (considerViewOptions) {
|
||||
if (downloadOption === 'sameWindow') {
|
||||
const url = URL.createObjectURL(blob);
|
||||
window.location.href = url;
|
||||
return;
|
||||
} else if (downloadOption === 'newWindow') {
|
||||
const url = URL.createObjectURL(blob);
|
||||
window.open(url, '_blank');
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!isZip){
|
||||
downloadFile(blob, filename);
|
||||
}
|
||||
return { filename, blob };
|
||||
if (!blob) return;
|
||||
const downloadOption = localStorage.getItem("downloadOption");
|
||||
if (considerViewOptions) {
|
||||
if (downloadOption === "sameWindow") {
|
||||
const url = URL.createObjectURL(blob);
|
||||
window.location.href = url;
|
||||
return;
|
||||
} else if (downloadOption === "newWindow") {
|
||||
const url = URL.createObjectURL(blob);
|
||||
window.open(url, "_blank");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!isZip) {
|
||||
downloadFile(blob, filename);
|
||||
}
|
||||
return { filename, blob };
|
||||
}
|
||||
|
||||
function handleDownloadError(error) {
|
||||
const errorMessage = error.message;
|
||||
showErrorBanner(errorMessage);
|
||||
const errorMessage = error.message;
|
||||
showErrorBanner(errorMessage);
|
||||
}
|
||||
|
||||
let urls = []; // An array to hold all the URLs
|
||||
|
||||
function downloadFile(blob, filename) {
|
||||
if (!(blob instanceof Blob)) {
|
||||
console.error('Invalid blob passed to downloadFile function');
|
||||
return;
|
||||
}
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
urls.push(url); // Store the URL so it doesn't get garbage collected too soon
|
||||
if (!(blob instanceof Blob)) {
|
||||
console.error("Invalid blob passed to downloadFile function");
|
||||
return;
|
||||
}
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
urls.push(url); // Store the URL so it doesn't get garbage collected too soon
|
||||
|
||||
return { filename, blob };
|
||||
return { filename, blob };
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function submitMultiPdfForm(url, files) {
|
||||
const zipThreshold = parseInt(localStorage.getItem('zipThreshold'), 10) || 4;
|
||||
const zipFiles = files.length > zipThreshold;
|
||||
let jszip = null;
|
||||
// Show the progress bar
|
||||
$('#progressBarContainer').show();
|
||||
// Initialize the progress bar
|
||||
|
||||
let progressBar = $('#progressBar');
|
||||
progressBar.css('width', '0%');
|
||||
progressBar.attr('aria-valuenow', 0);
|
||||
progressBar.attr('aria-valuemax', files.length);
|
||||
|
||||
if (zipFiles) {
|
||||
jszip = new JSZip();
|
||||
}
|
||||
|
||||
|
||||
// Get the form with the method attribute set to POST
|
||||
let postForm = document.querySelector('form[method="POST"]');
|
||||
|
||||
// Get existing form data
|
||||
let formData;
|
||||
if (postForm) {
|
||||
formData = new FormData($(postForm)[0]); // Convert the form to a jQuery object and get the raw DOM element
|
||||
} else {
|
||||
console.log("No form with POST method found.");
|
||||
}
|
||||
//Remove file to reuse parameters for other runs
|
||||
formData.delete('fileInput');
|
||||
// Remove empty file entries
|
||||
for (let [key, value] of formData.entries()) {
|
||||
if (value instanceof File && !value.name) {
|
||||
formData.delete(key);
|
||||
}
|
||||
const zipThreshold = parseInt(localStorage.getItem("zipThreshold"), 10) || 4;
|
||||
const zipFiles = files.length > zipThreshold;
|
||||
let jszip = null;
|
||||
// Show the progress bar
|
||||
$("#progressBarContainer").show();
|
||||
// Initialize the progress bar
|
||||
|
||||
let progressBar = $("#progressBar");
|
||||
progressBar.css("width", "0%");
|
||||
progressBar.attr("aria-valuenow", 0);
|
||||
progressBar.attr("aria-valuemax", files.length);
|
||||
|
||||
if (zipFiles) {
|
||||
jszip = new JSZip();
|
||||
}
|
||||
|
||||
// Get the form with the method attribute set to POST
|
||||
let postForm = document.querySelector('form[method="POST"]');
|
||||
|
||||
// Get existing form data
|
||||
let formData;
|
||||
if (postForm) {
|
||||
formData = new FormData($(postForm)[0]); // Convert the form to a jQuery object and get the raw DOM element
|
||||
} else {
|
||||
console.log("No form with POST method found.");
|
||||
}
|
||||
//Remove file to reuse parameters for other runs
|
||||
formData.delete("fileInput");
|
||||
// Remove empty file entries
|
||||
for (let [key, value] of formData.entries()) {
|
||||
if (value instanceof File && !value.name) {
|
||||
formData.delete(key);
|
||||
}
|
||||
const CONCURRENCY_LIMIT = 8;
|
||||
const chunks = [];
|
||||
for (let i = 0; i < Array.from(files).length; i += CONCURRENCY_LIMIT) {
|
||||
chunks.push(Array.from(files).slice(i, i + CONCURRENCY_LIMIT));
|
||||
}
|
||||
}
|
||||
const CONCURRENCY_LIMIT = 8;
|
||||
const chunks = [];
|
||||
for (let i = 0; i < Array.from(files).length; i += CONCURRENCY_LIMIT) {
|
||||
chunks.push(Array.from(files).slice(i, i + CONCURRENCY_LIMIT));
|
||||
}
|
||||
|
||||
for (const chunk of chunks) {
|
||||
const promises = chunk.map(async file => {
|
||||
let fileFormData = new FormData();
|
||||
fileFormData.append('fileInput', file);
|
||||
console.log(fileFormData);
|
||||
// Add other form data
|
||||
for (let pair of formData.entries()) {
|
||||
fileFormData.append(pair[0], pair[1]);
|
||||
console.log(pair[0]+ ', ' + pair[1]);
|
||||
}
|
||||
for (const chunk of chunks) {
|
||||
const promises = chunk.map(async (file) => {
|
||||
let fileFormData = new FormData();
|
||||
fileFormData.append("fileInput", file);
|
||||
console.log(fileFormData);
|
||||
// Add other form data
|
||||
for (let pair of formData.entries()) {
|
||||
fileFormData.append(pair[0], pair[1]);
|
||||
console.log(pair[0] + ", " + pair[1]);
|
||||
}
|
||||
|
||||
try {
|
||||
const downloadDetails = await handleSingleDownload(url, fileFormData, true, zipFiles);
|
||||
console.log(downloadDetails);
|
||||
if (zipFiles) {
|
||||
jszip.file(downloadDetails.filename, downloadDetails.blob);
|
||||
} else {
|
||||
//downloadFile(downloadDetails.blob, downloadDetails.filename);
|
||||
}
|
||||
updateProgressBar(progressBar, Array.from(files).length);
|
||||
} catch (error) {
|
||||
handleDownloadError(error);
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
await Promise.all(promises);
|
||||
|
||||
}
|
||||
try {
|
||||
const downloadDetails = await handleSingleDownload(url, fileFormData, true, zipFiles);
|
||||
console.log(downloadDetails);
|
||||
if (zipFiles) {
|
||||
jszip.file(downloadDetails.filename, downloadDetails.blob);
|
||||
} else {
|
||||
//downloadFile(downloadDetails.blob, downloadDetails.filename);
|
||||
}
|
||||
updateProgressBar(progressBar, Array.from(files).length);
|
||||
} catch (error) {
|
||||
handleDownloadError(error);
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
if (zipFiles) {
|
||||
try {
|
||||
const content = await jszip.generateAsync({ type: "blob" });
|
||||
downloadFile(content, "files.zip");
|
||||
} catch (error) {
|
||||
console.error('Error generating ZIP file: ' + error);
|
||||
}
|
||||
}
|
||||
progressBar.css('width', '100%');
|
||||
progressBar.attr('aria-valuenow', Array.from(files).length);
|
||||
if (zipFiles) {
|
||||
try {
|
||||
const content = await jszip.generateAsync({ type: "blob" });
|
||||
downloadFile(content, "files.zip");
|
||||
} catch (error) {
|
||||
console.error("Error generating ZIP file: " + error);
|
||||
}
|
||||
}
|
||||
progressBar.css("width", "100%");
|
||||
progressBar.attr("aria-valuenow", Array.from(files).length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function updateProgressBar(progressBar, files) {
|
||||
let progress = ((progressBar.attr('aria-valuenow') / files.length) * 100) + (100 / files.length);
|
||||
progressBar.css('width', progress + '%');
|
||||
progressBar.attr('aria-valuenow', parseInt(progressBar.attr('aria-valuenow')) + 1);
|
||||
let progress = (progressBar.attr("aria-valuenow") / files.length) * 100 + 100 / files.length;
|
||||
progressBar.css("width", progress + "%");
|
||||
progressBar.attr("aria-valuenow", parseInt(progressBar.attr("aria-valuenow")) + 1);
|
||||
}
|
||||
window.addEventListener('unload', () => {
|
||||
for (const url of urls) {
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
window.addEventListener("unload", () => {
|
||||
for (const url of urls) {
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,282 +1,287 @@
|
||||
const DraggableUtils = {
|
||||
boxDragContainer: document.getElementById("box-drag-container"),
|
||||
pdfCanvas: document.getElementById("pdf-canvas"),
|
||||
nextId: 0,
|
||||
pdfDoc: null,
|
||||
pageIndex: 0,
|
||||
documentsMap: new Map(),
|
||||
|
||||
boxDragContainer: document.getElementById('box-drag-container'),
|
||||
pdfCanvas: document.getElementById('pdf-canvas'),
|
||||
nextId: 0,
|
||||
pdfDoc: null,
|
||||
pageIndex: 0,
|
||||
documentsMap: new Map(),
|
||||
init() {
|
||||
interact(".draggable-canvas")
|
||||
.draggable({
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
const target = event.target;
|
||||
const x = (parseFloat(target.getAttribute("data-bs-x")) || 0) + event.dx;
|
||||
const y = (parseFloat(target.getAttribute("data-bs-y")) || 0) + event.dy;
|
||||
|
||||
init() {
|
||||
interact('.draggable-canvas')
|
||||
.draggable({
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
const target = event.target;
|
||||
const x = (parseFloat(target.getAttribute('data-bs-x')) || 0) + event.dx;
|
||||
const y = (parseFloat(target.getAttribute('data-bs-y')) || 0) + event.dy;
|
||||
target.style.transform = `translate(${x}px, ${y}px)`;
|
||||
target.setAttribute("data-bs-x", x);
|
||||
target.setAttribute("data-bs-y", y);
|
||||
|
||||
target.style.transform = `translate(${x}px, ${y}px)`;
|
||||
target.setAttribute('data-bs-x', x);
|
||||
target.setAttribute('data-bs-y', y);
|
||||
|
||||
this.onInteraction(target);
|
||||
},
|
||||
},
|
||||
})
|
||||
.resizable({
|
||||
edges: { left: true, right: true, bottom: true, top: true },
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
var target = event.target
|
||||
var x = (parseFloat(target.getAttribute('data-bs-x')) || 0)
|
||||
var y = (parseFloat(target.getAttribute('data-bs-y')) || 0)
|
||||
this.onInteraction(target);
|
||||
},
|
||||
},
|
||||
})
|
||||
.resizable({
|
||||
edges: { left: true, right: true, bottom: true, top: true },
|
||||
listeners: {
|
||||
move: (event) => {
|
||||
var target = event.target;
|
||||
var x = parseFloat(target.getAttribute("data-bs-x")) || 0;
|
||||
var y = parseFloat(target.getAttribute("data-bs-y")) || 0;
|
||||
|
||||
// check if control key is pressed
|
||||
if (event.ctrlKey) {
|
||||
const aspectRatio = target.offsetWidth / target.offsetHeight;
|
||||
// preserve aspect ratio
|
||||
let width = event.rect.width;
|
||||
let height = event.rect.height;
|
||||
const aspectRatio = target.offsetWidth / target.offsetHeight;
|
||||
// preserve aspect ratio
|
||||
let width = event.rect.width;
|
||||
let height = event.rect.height;
|
||||
|
||||
if (Math.abs(event.deltaRect.width) >= Math.abs(event.deltaRect.height)) {
|
||||
height = width / aspectRatio;
|
||||
} else {
|
||||
width = height * aspectRatio;
|
||||
}
|
||||
if (Math.abs(event.deltaRect.width) >= Math.abs(event.deltaRect.height)) {
|
||||
height = width / aspectRatio;
|
||||
} else {
|
||||
width = height * aspectRatio;
|
||||
}
|
||||
|
||||
event.rect.width = width;
|
||||
event.rect.height = height;
|
||||
event.rect.width = width;
|
||||
event.rect.height = height;
|
||||
}
|
||||
|
||||
target.style.width = event.rect.width + 'px'
|
||||
target.style.height = event.rect.height + 'px'
|
||||
target.style.width = event.rect.width + "px";
|
||||
target.style.height = event.rect.height + "px";
|
||||
|
||||
// translate when resizing from top or left edges
|
||||
x += event.deltaRect.left
|
||||
y += event.deltaRect.top
|
||||
x += event.deltaRect.left;
|
||||
y += event.deltaRect.top;
|
||||
|
||||
target.style.transform = 'translate(' + x + 'px,' + y + 'px)'
|
||||
target.style.transform = "translate(" + x + "px," + y + "px)";
|
||||
|
||||
target.setAttribute('data-bs-x', x)
|
||||
target.setAttribute('data-bs-y', y)
|
||||
target.textContent = Math.round(event.rect.width) + '\u00D7' + Math.round(event.rect.height)
|
||||
target.setAttribute("data-bs-x", x);
|
||||
target.setAttribute("data-bs-y", y);
|
||||
target.textContent = Math.round(event.rect.width) + "\u00D7" + Math.round(event.rect.height);
|
||||
|
||||
this.onInteraction(target);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
modifiers: [
|
||||
interact.modifiers.restrictSize({
|
||||
min: { width: 5, height: 5 },
|
||||
}),
|
||||
],
|
||||
inertia: true,
|
||||
});
|
||||
},
|
||||
onInteraction(target) {
|
||||
this.boxDragContainer.appendChild(target);
|
||||
},
|
||||
modifiers: [
|
||||
interact.modifiers.restrictSize({
|
||||
min: { width: 5, height: 5 },
|
||||
}),
|
||||
],
|
||||
inertia: true,
|
||||
});
|
||||
},
|
||||
onInteraction(target) {
|
||||
this.boxDragContainer.appendChild(target);
|
||||
},
|
||||
|
||||
createDraggableCanvas() {
|
||||
const createdCanvas = document.createElement('canvas');
|
||||
createdCanvas.id = `draggable-canvas-${this.nextId++}`;
|
||||
createdCanvas.classList.add("draggable-canvas");
|
||||
createDraggableCanvas() {
|
||||
const createdCanvas = document.createElement("canvas");
|
||||
createdCanvas.id = `draggable-canvas-${this.nextId++}`;
|
||||
createdCanvas.classList.add("draggable-canvas");
|
||||
|
||||
const x = 0;
|
||||
const y = 20;
|
||||
createdCanvas.style.transform = `translate(${x}px, ${y}px)`;
|
||||
createdCanvas.setAttribute('data-bs-x', x);
|
||||
createdCanvas.setAttribute('data-bs-y', y);
|
||||
const x = 0;
|
||||
const y = 20;
|
||||
createdCanvas.style.transform = `translate(${x}px, ${y}px)`;
|
||||
createdCanvas.setAttribute("data-bs-x", x);
|
||||
createdCanvas.setAttribute("data-bs-y", y);
|
||||
|
||||
createdCanvas.onclick = e => this.onInteraction(e.target);
|
||||
createdCanvas.onclick = (e) => this.onInteraction(e.target);
|
||||
|
||||
this.boxDragContainer.appendChild(createdCanvas);
|
||||
return createdCanvas;
|
||||
},
|
||||
createDraggableCanvasFromUrl(dataUrl) {
|
||||
return new Promise((resolve) => {
|
||||
var myImage = new Image();
|
||||
myImage.src = dataUrl;
|
||||
myImage.onload = () => {
|
||||
var createdCanvas = this.createDraggableCanvas();
|
||||
this.boxDragContainer.appendChild(createdCanvas);
|
||||
return createdCanvas;
|
||||
},
|
||||
createDraggableCanvasFromUrl(dataUrl) {
|
||||
return new Promise((resolve) => {
|
||||
var myImage = new Image();
|
||||
myImage.src = dataUrl;
|
||||
myImage.onload = () => {
|
||||
var createdCanvas = this.createDraggableCanvas();
|
||||
|
||||
createdCanvas.width = myImage.width;
|
||||
createdCanvas.height = myImage.height;
|
||||
createdCanvas.width = myImage.width;
|
||||
createdCanvas.height = myImage.height;
|
||||
|
||||
const imgAspect = myImage.width / myImage.height;
|
||||
const pdfAspect = this.boxDragContainer.offsetWidth / this.boxDragContainer.offsetHeight;
|
||||
const imgAspect = myImage.width / myImage.height;
|
||||
const pdfAspect = this.boxDragContainer.offsetWidth / this.boxDragContainer.offsetHeight;
|
||||
|
||||
var scaleMultiplier;
|
||||
if (imgAspect > pdfAspect) {
|
||||
scaleMultiplier = this.boxDragContainer.offsetWidth / myImage.width;
|
||||
} else {
|
||||
scaleMultiplier = this.boxDragContainer.offsetHeight / myImage.height;
|
||||
}
|
||||
|
||||
var newWidth = createdCanvas.width;
|
||||
var newHeight = createdCanvas.height;
|
||||
if (scaleMultiplier < 1) {
|
||||
newWidth = newWidth * scaleMultiplier;
|
||||
newHeight = newHeight * scaleMultiplier;
|
||||
}
|
||||
|
||||
createdCanvas.style.width = newWidth+"px";
|
||||
createdCanvas.style.height = newHeight+"px";
|
||||
|
||||
var myContext = createdCanvas.getContext("2d");
|
||||
myContext.drawImage(myImage,0,0);
|
||||
resolve(createdCanvas);
|
||||
}
|
||||
})
|
||||
},
|
||||
deleteAllDraggableCanvases() {
|
||||
this.boxDragContainer.querySelectorAll(".draggable-canvas").forEach(el => el.remove());
|
||||
},
|
||||
deleteDraggableCanvas(element) {
|
||||
if (element) {
|
||||
element.remove();
|
||||
}
|
||||
},
|
||||
getLastInteracted() {
|
||||
return this.boxDragContainer.querySelector(".draggable-canvas:last-of-type");
|
||||
},
|
||||
|
||||
storePageContents() {
|
||||
var pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
if (!pagesMap) {
|
||||
pagesMap = {};
|
||||
}
|
||||
|
||||
const elements = [...this.boxDragContainer.querySelectorAll(".draggable-canvas")];
|
||||
const draggablesData = elements.map(el => {return{element:el, offsetWidth:el.offsetWidth, offsetHeight:el.offsetHeight}});
|
||||
elements.forEach(el => this.boxDragContainer.removeChild(el));
|
||||
|
||||
pagesMap[this.pageIndex] = draggablesData;
|
||||
pagesMap[this.pageIndex+"-offsetWidth"] = this.pdfCanvas.offsetWidth;
|
||||
pagesMap[this.pageIndex+"-offsetHeight"] = this.pdfCanvas.offsetHeight;
|
||||
|
||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
||||
},
|
||||
loadPageContents() {
|
||||
var pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
this.deleteAllDraggableCanvases();
|
||||
if (!pagesMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
const draggablesData = pagesMap[this.pageIndex];
|
||||
if (draggablesData) {
|
||||
draggablesData.forEach(draggableData => this.boxDragContainer.appendChild(draggableData.element));
|
||||
}
|
||||
|
||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
||||
},
|
||||
|
||||
async renderPage(pdfDocument, pageIdx) {
|
||||
this.pdfDoc = pdfDocument ? pdfDocument : this.pdfDoc;
|
||||
this.pageIndex = pageIdx;
|
||||
|
||||
// persist
|
||||
const page = await this.pdfDoc.getPage(this.pageIndex+1);
|
||||
|
||||
// set the canvas size to the size of the page
|
||||
if (page.rotate == 90 || page.rotate == 270) {
|
||||
this.pdfCanvas.width = page.view[3];
|
||||
this.pdfCanvas.height = page.view[2];
|
||||
var scaleMultiplier;
|
||||
if (imgAspect > pdfAspect) {
|
||||
scaleMultiplier = this.boxDragContainer.offsetWidth / myImage.width;
|
||||
} else {
|
||||
this.pdfCanvas.width = page.view[2];
|
||||
this.pdfCanvas.height = page.view[3];
|
||||
scaleMultiplier = this.boxDragContainer.offsetHeight / myImage.height;
|
||||
}
|
||||
|
||||
// render the page onto the canvas
|
||||
var renderContext = {
|
||||
canvasContext: this.pdfCanvas.getContext("2d"),
|
||||
viewport: page.getViewport({ scale: 1 })
|
||||
var newWidth = createdCanvas.width;
|
||||
var newHeight = createdCanvas.height;
|
||||
if (scaleMultiplier < 1) {
|
||||
newWidth = newWidth * scaleMultiplier;
|
||||
newHeight = newHeight * scaleMultiplier;
|
||||
}
|
||||
|
||||
createdCanvas.style.width = newWidth + "px";
|
||||
createdCanvas.style.height = newHeight + "px";
|
||||
|
||||
var myContext = createdCanvas.getContext("2d");
|
||||
myContext.drawImage(myImage, 0, 0);
|
||||
resolve(createdCanvas);
|
||||
};
|
||||
});
|
||||
},
|
||||
deleteAllDraggableCanvases() {
|
||||
this.boxDragContainer.querySelectorAll(".draggable-canvas").forEach((el) => el.remove());
|
||||
},
|
||||
deleteDraggableCanvas(element) {
|
||||
if (element) {
|
||||
element.remove();
|
||||
}
|
||||
},
|
||||
getLastInteracted() {
|
||||
return this.boxDragContainer.querySelector(".draggable-canvas:last-of-type");
|
||||
},
|
||||
|
||||
storePageContents() {
|
||||
var pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
if (!pagesMap) {
|
||||
pagesMap = {};
|
||||
}
|
||||
|
||||
const elements = [...this.boxDragContainer.querySelectorAll(".draggable-canvas")];
|
||||
const draggablesData = elements.map((el) => {
|
||||
return {
|
||||
element: el,
|
||||
offsetWidth: el.offsetWidth,
|
||||
offsetHeight: el.offsetHeight,
|
||||
};
|
||||
});
|
||||
elements.forEach((el) => this.boxDragContainer.removeChild(el));
|
||||
|
||||
pagesMap[this.pageIndex] = draggablesData;
|
||||
pagesMap[this.pageIndex + "-offsetWidth"] = this.pdfCanvas.offsetWidth;
|
||||
pagesMap[this.pageIndex + "-offsetHeight"] = this.pdfCanvas.offsetHeight;
|
||||
|
||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
||||
},
|
||||
loadPageContents() {
|
||||
var pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
this.deleteAllDraggableCanvases();
|
||||
if (!pagesMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
const draggablesData = pagesMap[this.pageIndex];
|
||||
if (draggablesData) {
|
||||
draggablesData.forEach((draggableData) => this.boxDragContainer.appendChild(draggableData.element));
|
||||
}
|
||||
|
||||
this.documentsMap.set(this.pdfDoc, pagesMap);
|
||||
},
|
||||
|
||||
async renderPage(pdfDocument, pageIdx) {
|
||||
this.pdfDoc = pdfDocument ? pdfDocument : this.pdfDoc;
|
||||
this.pageIndex = pageIdx;
|
||||
|
||||
// persist
|
||||
const page = await this.pdfDoc.getPage(this.pageIndex + 1);
|
||||
|
||||
// set the canvas size to the size of the page
|
||||
if (page.rotate == 90 || page.rotate == 270) {
|
||||
this.pdfCanvas.width = page.view[3];
|
||||
this.pdfCanvas.height = page.view[2];
|
||||
} else {
|
||||
this.pdfCanvas.width = page.view[2];
|
||||
this.pdfCanvas.height = page.view[3];
|
||||
}
|
||||
|
||||
// render the page onto the canvas
|
||||
var renderContext = {
|
||||
canvasContext: this.pdfCanvas.getContext("2d"),
|
||||
viewport: page.getViewport({ scale: 1 }),
|
||||
};
|
||||
await page.render(renderContext).promise;
|
||||
|
||||
//return pdfCanvas.toDataURL();
|
||||
},
|
||||
async incrementPage() {
|
||||
if (this.pageIndex < this.pdfDoc.numPages - 1) {
|
||||
this.storePageContents();
|
||||
await this.renderPage(this.pdfDoc, this.pageIndex + 1);
|
||||
this.loadPageContents();
|
||||
}
|
||||
},
|
||||
async decrementPage() {
|
||||
if (this.pageIndex > 0) {
|
||||
this.storePageContents();
|
||||
await this.renderPage(this.pdfDoc, this.pageIndex - 1);
|
||||
this.loadPageContents();
|
||||
}
|
||||
},
|
||||
|
||||
parseTransform(element) {},
|
||||
async getOverlayedPdfDocument() {
|
||||
const pdfBytes = await this.pdfDoc.getData();
|
||||
const pdfDocModified = await PDFLib.PDFDocument.load(pdfBytes, {
|
||||
ignoreEncryption: true,
|
||||
});
|
||||
this.storePageContents();
|
||||
|
||||
const pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
for (let pageIdx in pagesMap) {
|
||||
if (pageIdx.includes("offset")) {
|
||||
continue;
|
||||
}
|
||||
console.log(typeof pageIdx);
|
||||
|
||||
const page = pdfDocModified.getPage(parseInt(pageIdx));
|
||||
const draggablesData = pagesMap[pageIdx];
|
||||
const offsetWidth = pagesMap[pageIdx + "-offsetWidth"];
|
||||
const offsetHeight = pagesMap[pageIdx + "-offsetHeight"];
|
||||
|
||||
for (const draggableData of draggablesData) {
|
||||
// embed the draggable canvas
|
||||
const draggableElement = draggableData.element;
|
||||
const response = await fetch(draggableElement.toDataURL());
|
||||
const draggableImgBytes = await response.arrayBuffer();
|
||||
const pdfImageObject = await pdfDocModified.embedPng(draggableImgBytes);
|
||||
|
||||
// calculate the position in the pdf document
|
||||
const tansform = draggableElement.style.transform.replace(/[^.,-\d]/g, "");
|
||||
const transformComponents = tansform.split(",");
|
||||
const draggablePositionPixels = {
|
||||
x: parseFloat(transformComponents[0]),
|
||||
y: parseFloat(transformComponents[1]),
|
||||
width: draggableData.offsetWidth,
|
||||
height: draggableData.offsetHeight,
|
||||
};
|
||||
const draggablePositionRelative = {
|
||||
x: draggablePositionPixels.x / offsetWidth,
|
||||
y: draggablePositionPixels.y / offsetHeight,
|
||||
width: draggablePositionPixels.width / offsetWidth,
|
||||
height: draggablePositionPixels.height / offsetHeight,
|
||||
};
|
||||
const draggablePositionPdf = {
|
||||
x: draggablePositionRelative.x * page.getWidth(),
|
||||
y: draggablePositionRelative.y * page.getHeight(),
|
||||
width: draggablePositionRelative.width * page.getWidth(),
|
||||
height: draggablePositionRelative.height * page.getHeight(),
|
||||
};
|
||||
await page.render(renderContext).promise;
|
||||
|
||||
//return pdfCanvas.toDataURL();
|
||||
},
|
||||
async incrementPage() {
|
||||
if (this.pageIndex < this.pdfDoc.numPages-1) {
|
||||
this.storePageContents();
|
||||
await this.renderPage(this.pdfDoc, this.pageIndex+1);
|
||||
this.loadPageContents();
|
||||
}
|
||||
},
|
||||
async decrementPage() {
|
||||
if (this.pageIndex > 0) {
|
||||
this.storePageContents();
|
||||
await this.renderPage(this.pdfDoc, this.pageIndex-1);
|
||||
this.loadPageContents();
|
||||
}
|
||||
},
|
||||
// draw the image
|
||||
page.drawImage(pdfImageObject, {
|
||||
x: draggablePositionPdf.x,
|
||||
y: page.getHeight() - draggablePositionPdf.y - draggablePositionPdf.height,
|
||||
width: draggablePositionPdf.width,
|
||||
height: draggablePositionPdf.height,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
parseTransform(element) {
|
||||
|
||||
},
|
||||
async getOverlayedPdfDocument() {
|
||||
const pdfBytes = await this.pdfDoc.getData();
|
||||
const pdfDocModified = await PDFLib.PDFDocument.load(pdfBytes, { ignoreEncryption: true });
|
||||
this.storePageContents();
|
||||
|
||||
const pagesMap = this.documentsMap.get(this.pdfDoc);
|
||||
for (let pageIdx in pagesMap) {
|
||||
if (pageIdx.includes("offset")) {
|
||||
continue;
|
||||
}
|
||||
console.log(typeof pageIdx);
|
||||
|
||||
const page = pdfDocModified.getPage(parseInt(pageIdx));
|
||||
const draggablesData = pagesMap[pageIdx];
|
||||
const offsetWidth = pagesMap[pageIdx+"-offsetWidth"];
|
||||
const offsetHeight = pagesMap[pageIdx+"-offsetHeight"];
|
||||
|
||||
for (const draggableData of draggablesData) {
|
||||
// embed the draggable canvas
|
||||
const draggableElement = draggableData.element;
|
||||
const response = await fetch(draggableElement.toDataURL());
|
||||
const draggableImgBytes = await response.arrayBuffer();
|
||||
const pdfImageObject = await pdfDocModified.embedPng(draggableImgBytes);
|
||||
|
||||
// calculate the position in the pdf document
|
||||
const tansform = draggableElement.style.transform.replace(/[^.,-\d]/g, '');
|
||||
const transformComponents = tansform.split(",");
|
||||
const draggablePositionPixels = {
|
||||
x: parseFloat(transformComponents[0]),
|
||||
y: parseFloat(transformComponents[1]),
|
||||
width: draggableData.offsetWidth,
|
||||
height: draggableData.offsetHeight,
|
||||
};
|
||||
const draggablePositionRelative = {
|
||||
x: draggablePositionPixels.x / offsetWidth,
|
||||
y: draggablePositionPixels.y / offsetHeight,
|
||||
width: draggablePositionPixels.width / offsetWidth,
|
||||
height: draggablePositionPixels.height / offsetHeight,
|
||||
}
|
||||
const draggablePositionPdf = {
|
||||
x: draggablePositionRelative.x * page.getWidth(),
|
||||
y: draggablePositionRelative.y * page.getHeight(),
|
||||
width: draggablePositionRelative.width * page.getWidth(),
|
||||
height: draggablePositionRelative.height * page.getHeight(),
|
||||
}
|
||||
|
||||
// draw the image
|
||||
page.drawImage(pdfImageObject, {
|
||||
x: draggablePositionPdf.x,
|
||||
y: page.getHeight() - draggablePositionPdf.y - draggablePositionPdf.height,
|
||||
width: draggablePositionPdf.width,
|
||||
height: draggablePositionPdf.height,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.loadPageContents();
|
||||
return pdfDocModified;
|
||||
},
|
||||
}
|
||||
this.loadPageContents();
|
||||
return pdfDocModified;
|
||||
},
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
DraggableUtils.init();
|
||||
DraggableUtils.init();
|
||||
});
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
var traceVisible = false;
|
||||
|
||||
function toggletrace() {
|
||||
var traceDiv = document.getElementById("trace");
|
||||
if (!traceVisible) {
|
||||
traceDiv.style.maxHeight = "500px";
|
||||
traceVisible = true;
|
||||
} else {
|
||||
traceDiv.style.maxHeight = "0px";
|
||||
traceVisible = false;
|
||||
}
|
||||
adjustContainerHeight();
|
||||
var traceDiv = document.getElementById("trace");
|
||||
if (!traceVisible) {
|
||||
traceDiv.style.maxHeight = "500px";
|
||||
traceVisible = true;
|
||||
} else {
|
||||
traceDiv.style.maxHeight = "0px";
|
||||
traceVisible = false;
|
||||
}
|
||||
adjustContainerHeight();
|
||||
}
|
||||
|
||||
function copytrace() {
|
||||
var flip = false
|
||||
if (!traceVisible) {
|
||||
toggletrace()
|
||||
flip = true
|
||||
}
|
||||
var traceContent = document.getElementById("traceContent");
|
||||
var range = document.createRange();
|
||||
range.selectNode(traceContent);
|
||||
window.getSelection().removeAllRanges();
|
||||
window.getSelection().addRange(range);
|
||||
document.execCommand("copy");
|
||||
window.getSelection().removeAllRanges();
|
||||
if (flip) {
|
||||
toggletrace()
|
||||
}
|
||||
var flip = false;
|
||||
if (!traceVisible) {
|
||||
toggletrace();
|
||||
flip = true;
|
||||
}
|
||||
var traceContent = document.getElementById("traceContent");
|
||||
var range = document.createRange();
|
||||
range.selectNode(traceContent);
|
||||
window.getSelection().removeAllRanges();
|
||||
window.getSelection().addRange(range);
|
||||
document.execCommand("copy");
|
||||
window.getSelection().removeAllRanges();
|
||||
if (flip) {
|
||||
toggletrace();
|
||||
}
|
||||
}
|
||||
|
||||
function dismissError() {
|
||||
var errorContainer = document.getElementById("errorContainer");
|
||||
errorContainer.style.display = "none";
|
||||
errorContainer.style.height = "0";
|
||||
var errorContainer = document.getElementById("errorContainer");
|
||||
errorContainer.style.display = "none";
|
||||
errorContainer.style.height = "0";
|
||||
}
|
||||
|
||||
function adjustContainerHeight() {
|
||||
var errorContainer = document.getElementById("errorContainer");
|
||||
var traceDiv = document.getElementById("trace");
|
||||
if (traceVisible) {
|
||||
errorContainer.style.height = errorContainer.scrollHeight - traceDiv.scrollHeight + traceDiv.offsetHeight + "px";
|
||||
} else {
|
||||
errorContainer.style.height = "auto";
|
||||
}
|
||||
var errorContainer = document.getElementById("errorContainer");
|
||||
var traceDiv = document.getElementById("trace");
|
||||
if (traceVisible) {
|
||||
errorContainer.style.height = errorContainer.scrollHeight - traceDiv.scrollHeight + traceDiv.offsetHeight + "px";
|
||||
} else {
|
||||
errorContainer.style.height = "auto";
|
||||
}
|
||||
}
|
||||
function showHelp() {
|
||||
$('#helpModal').modal('show');
|
||||
}
|
||||
$("#helpModal").modal("show");
|
||||
}
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
function updateFavoritesDropdown() {
|
||||
var dropdown = document.querySelector('#favoritesDropdown');
|
||||
|
||||
// Check if dropdown exists
|
||||
if (!dropdown) {
|
||||
console.error('Dropdown element with ID "favoritesDropdown" not found!');
|
||||
return; // Exit the function
|
||||
}
|
||||
dropdown.innerHTML = ''; // Clear the current favorites
|
||||
var dropdown = document.querySelector("#favoritesDropdown");
|
||||
|
||||
var hasFavorites = false;
|
||||
// Check if dropdown exists
|
||||
if (!dropdown) {
|
||||
console.error('Dropdown element with ID "favoritesDropdown" not found!');
|
||||
return; // Exit the function
|
||||
}
|
||||
dropdown.innerHTML = ""; // Clear the current favorites
|
||||
|
||||
for (var i = 0; i < localStorage.length; i++) {
|
||||
var key = localStorage.key(i);
|
||||
if (localStorage.getItem(key) === 'favorite') {
|
||||
// Find the corresponding navbar entry
|
||||
var navbarEntry = document.querySelector(`a[href='${key}']`);
|
||||
if (navbarEntry) {
|
||||
// Create a new dropdown entry
|
||||
var dropdownItem = document.createElement('a');
|
||||
dropdownItem.className = 'dropdown-item';
|
||||
dropdownItem.href = navbarEntry.href;
|
||||
dropdownItem.innerHTML = navbarEntry.innerHTML;
|
||||
dropdown.appendChild(dropdownItem);
|
||||
hasFavorites = true;
|
||||
} else {
|
||||
console.warn(`Navbar entry not found for key: ${key}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
var hasFavorites = false;
|
||||
|
||||
// Show or hide the default item based on whether there are any favorites
|
||||
if (!hasFavorites) {
|
||||
var defaultItem = document.createElement('a');
|
||||
defaultItem.className = 'dropdown-item';
|
||||
defaultItem.textContent = noFavourites;
|
||||
dropdown.appendChild(defaultItem);
|
||||
for (var i = 0; i < localStorage.length; i++) {
|
||||
var key = localStorage.key(i);
|
||||
if (localStorage.getItem(key) === "favorite") {
|
||||
// Find the corresponding navbar entry
|
||||
var navbarEntry = document.querySelector(`a[href='${key}']`);
|
||||
if (navbarEntry) {
|
||||
// Create a new dropdown entry
|
||||
var dropdownItem = document.createElement("a");
|
||||
dropdownItem.className = "dropdown-item";
|
||||
dropdownItem.href = navbarEntry.href;
|
||||
dropdownItem.innerHTML = navbarEntry.innerHTML;
|
||||
dropdown.appendChild(dropdownItem);
|
||||
hasFavorites = true;
|
||||
} else {
|
||||
console.warn(`Navbar entry not found for key: ${key}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show or hide the default item based on whether there are any favorites
|
||||
if (!hasFavorites) {
|
||||
var defaultItem = document.createElement("a");
|
||||
defaultItem.className = "dropdown-item";
|
||||
defaultItem.textContent = noFavourites;
|
||||
dropdown.appendChild(defaultItem);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the DOM content has been fully loaded before calling the function
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
console.log('DOMContentLoaded event fired');
|
||||
updateFavoritesDropdown();
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
console.log("DOMContentLoaded event fired");
|
||||
updateFavoritesDropdown();
|
||||
});
|
||||
|
||||
@@ -1,104 +1,107 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.querySelectorAll('.custom-file-chooser').forEach(setupFileInput);
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
document.querySelectorAll(".custom-file-chooser").forEach(setupFileInput);
|
||||
});
|
||||
|
||||
function setupFileInput(chooser) {
|
||||
const elementId = chooser.getAttribute('data-bs-element-id');
|
||||
const filesSelected = chooser.getAttribute('data-bs-files-selected');
|
||||
const pdfPrompt = chooser.getAttribute('data-bs-pdf-prompt');
|
||||
const elementId = chooser.getAttribute("data-bs-element-id");
|
||||
const filesSelected = chooser.getAttribute("data-bs-files-selected");
|
||||
const pdfPrompt = chooser.getAttribute("data-bs-pdf-prompt");
|
||||
|
||||
let allFiles = [];
|
||||
let overlay;
|
||||
let dragCounter = 0;
|
||||
let allFiles = [];
|
||||
let overlay;
|
||||
let dragCounter = 0;
|
||||
|
||||
const dragenterListener = function() {
|
||||
dragCounter++;
|
||||
if (!overlay) {
|
||||
overlay = document.createElement('div');
|
||||
overlay.style.position = 'fixed';
|
||||
overlay.style.top = 0;
|
||||
overlay.style.left = 0;
|
||||
overlay.style.width = '100%';
|
||||
overlay.style.height = '100%';
|
||||
overlay.style.background = 'rgba(0, 0, 0, 0.5)';
|
||||
overlay.style.color = '#fff';
|
||||
overlay.style.zIndex = '1000';
|
||||
overlay.style.display = 'flex';
|
||||
overlay.style.alignItems = 'center';
|
||||
overlay.style.justifyContent = 'center';
|
||||
overlay.style.pointerEvents = 'none';
|
||||
overlay.innerHTML = '<p>Drop files anywhere to upload</p>';
|
||||
document.getElementById('content-wrap').appendChild(overlay);
|
||||
}
|
||||
};
|
||||
const dragenterListener = function () {
|
||||
dragCounter++;
|
||||
if (!overlay) {
|
||||
overlay = document.createElement("div");
|
||||
overlay.style.position = "fixed";
|
||||
overlay.style.top = 0;
|
||||
overlay.style.left = 0;
|
||||
overlay.style.width = "100%";
|
||||
overlay.style.height = "100%";
|
||||
overlay.style.background = "rgba(0, 0, 0, 0.5)";
|
||||
overlay.style.color = "#fff";
|
||||
overlay.style.zIndex = "1000";
|
||||
overlay.style.display = "flex";
|
||||
overlay.style.alignItems = "center";
|
||||
overlay.style.justifyContent = "center";
|
||||
overlay.style.pointerEvents = "none";
|
||||
overlay.innerHTML = "<p>Drop files anywhere to upload</p>";
|
||||
document.getElementById("content-wrap").appendChild(overlay);
|
||||
}
|
||||
};
|
||||
|
||||
const dragleaveListener = function() {
|
||||
dragCounter--;
|
||||
if (dragCounter === 0) {
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
overlay = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
const dragleaveListener = function () {
|
||||
dragCounter--;
|
||||
if (dragCounter === 0) {
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
overlay = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const dropListener = function(e) {
|
||||
e.preventDefault();
|
||||
const dt = e.dataTransfer;
|
||||
const files = dt.files;
|
||||
const dropListener = function (e) {
|
||||
e.preventDefault();
|
||||
const dt = e.dataTransfer;
|
||||
const files = dt.files;
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
allFiles.push(files[i]);
|
||||
}
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
allFiles.push(files[i]);
|
||||
}
|
||||
|
||||
const dataTransfer = new DataTransfer();
|
||||
allFiles.forEach(file => dataTransfer.items.add(file));
|
||||
const dataTransfer = new DataTransfer();
|
||||
allFiles.forEach((file) => dataTransfer.items.add(file));
|
||||
|
||||
const fileInput = document.getElementById(elementId);
|
||||
fileInput.files = dataTransfer.files;
|
||||
const fileInput = document.getElementById(elementId);
|
||||
fileInput.files = dataTransfer.files;
|
||||
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
overlay = null;
|
||||
}
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
overlay = null;
|
||||
}
|
||||
|
||||
dragCounter = 0;
|
||||
dragCounter = 0;
|
||||
|
||||
fileInput.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
};
|
||||
fileInput.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
};
|
||||
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
||||
document.body.addEventListener(eventName, preventDefaults, false);
|
||||
["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => {
|
||||
document.body.addEventListener(eventName, preventDefaults, false);
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
document.body.addEventListener("dragenter", dragenterListener);
|
||||
document.body.addEventListener("dragleave", dragleaveListener);
|
||||
document.body.addEventListener("drop", dropListener);
|
||||
|
||||
$("#" + elementId).on("change", function (e) {
|
||||
allFiles = Array.from(e.target.files);
|
||||
handleFileInputChange(this);
|
||||
});
|
||||
|
||||
function handleFileInputChange(inputElement) {
|
||||
const files = allFiles;
|
||||
const fileNames = files.map((f) => f.name);
|
||||
const selectedFilesContainer = $(inputElement).siblings(".selected-files");
|
||||
selectedFilesContainer.empty();
|
||||
fileNames.forEach((fileName) => {
|
||||
selectedFilesContainer.append("<div>" + fileName + "</div>");
|
||||
});
|
||||
|
||||
function preventDefaults(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
document.body.addEventListener('dragenter', dragenterListener);
|
||||
document.body.addEventListener('dragleave', dragleaveListener);
|
||||
document.body.addEventListener('drop', dropListener);
|
||||
|
||||
$("#" + elementId).on("change", function(e) {
|
||||
allFiles = Array.from(e.target.files);
|
||||
handleFileInputChange(this);
|
||||
});
|
||||
|
||||
function handleFileInputChange(inputElement) {
|
||||
const files = allFiles;
|
||||
const fileNames = files.map(f => f.name);
|
||||
const selectedFilesContainer = $(inputElement).siblings(".selected-files");
|
||||
selectedFilesContainer.empty();
|
||||
fileNames.forEach(fileName => {
|
||||
selectedFilesContainer.append("<div>" + fileName + "</div>");
|
||||
});
|
||||
if (fileNames.length === 1) {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames[0]);
|
||||
} else if (fileNames.length > 1) {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames.length + " " + filesSelected);
|
||||
} else {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(pdfPrompt);
|
||||
}
|
||||
if (fileNames.length === 1) {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(fileNames[0]);
|
||||
} else if (fileNames.length > 1) {
|
||||
$(inputElement)
|
||||
.siblings(".custom-file-label")
|
||||
.addClass("selected")
|
||||
.html(fileNames.length + " " + filesSelected);
|
||||
} else {
|
||||
$(inputElement).siblings(".custom-file-label").addClass("selected").html(pdfPrompt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||