mirror of
				https://github.com/Frooodle/Stirling-PDF.git
				synced 2025-10-25 11:17:28 +02:00 
			
		
		
		
	starting issue, implementing pdf-to-csv view
This commit is contained in:
		
							parent
							
								
									18c5f5bb2b
								
							
						
					
					
						commit
						d6afb07533
					
				
							
								
								
									
										64
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								build.gradle
									
									
									
									
									
								
							| @ -46,15 +46,15 @@ launch4j { | ||||
|   outfile="Stirling-PDF.exe" | ||||
|   headerType="console" | ||||
|   jarTask = tasks.bootJar | ||||
|    | ||||
| 
 | ||||
|   errTitle="Encountered error, Do you have Java 17?" | ||||
|   downloadUrl="https://download.oracle.com/java/17/latest/jdk-17_windows-x64_bin.exe"  | ||||
|   downloadUrl="https://download.oracle.com/java/17/latest/jdk-17_windows-x64_bin.exe" | ||||
|   variables=["BROWSER_OPEN=true"] | ||||
|   jreMinVersion="17" | ||||
|    | ||||
| 
 | ||||
|   mutexName="Stirling-PDF" | ||||
|   windowTitle="Stirling-PDF" | ||||
|    | ||||
| 
 | ||||
|   messagesStartupError="An error occurred while starting Stirling-PDF" | ||||
|   //messagesJreNotFoundError="This application requires a Java Runtime Environment, Please download Java 17." | ||||
|   messagesJreVersionError="You are running the wrong version of Java, Please download Java 17." | ||||
| @ -63,46 +63,56 @@ launch4j { | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
| 	implementation 'org.yaml:snakeyaml:2.1' | ||||
| 	implementation 'org.springframework.boot:spring-boot-starter-web:3.1.2' | ||||
| 	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.1.2' | ||||
| 	 | ||||
| 	if (System.getenv('DOCKER_ENABLE_SECURITY') != 'false') { | ||||
|     implementation 'org.yaml:snakeyaml:2.1' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-web:3.1.2' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-thymeleaf:3.1.2' | ||||
| 
 | ||||
|     if (System.getenv('DOCKER_ENABLE_SECURITY') != 'false') { | ||||
|         implementation 'org.springframework.boot:spring-boot-starter-security:3.1.2' | ||||
|         implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.2.RELEASE' | ||||
|         implementation "org.springframework.boot:spring-boot-starter-data-jpa" | ||||
| 		implementation "com.h2database:h2" | ||||
|         implementation "com.h2database:h2" | ||||
|     } | ||||
| 	 | ||||
| 	testImplementation 'org.springframework.boot:spring-boot-starter-test:3.1.4' | ||||
| 	 | ||||
| 	 | ||||
| 
 | ||||
| 	// https://mvnrepository.com/artifact/org.apache.pdfbox/jbig2-imageio | ||||
| 	implementation group: 'org.apache.pdfbox', name: 'jbig2-imageio', version: '3.0.4' | ||||
| 	implementation 'commons-io:commons-io:2.13.0' | ||||
| 	 | ||||
|     testImplementation 'org.springframework.boot:spring-boot-starter-test:3.1.4' | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     // https://mvnrepository.com/artifact/org.apache.pdfbox/jbig2-imageio | ||||
|     implementation group: 'org.apache.pdfbox', name: 'jbig2-imageio', version: '3.0.4' | ||||
|     implementation 'commons-io:commons-io:2.13.0' | ||||
|     implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0' | ||||
|      | ||||
| 	//general PDF | ||||
| 
 | ||||
|     //general PDF | ||||
| 
 | ||||
|     // https://mvnrepository.com/artifact/com.opencsv/opencsv | ||||
|     implementation group: 'com.opencsv', name: 'opencsv', version: '5.7.1' | ||||
|     implementation 'org.apache.pdfbox:pdfbox:2.0.29' | ||||
|     implementation 'org.apache.pdfbox:xmpbox:2.0.29' | ||||
|     implementation 'org.bouncycastle:bcprov-jdk15on:1.70' | ||||
|     implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'  | ||||
|     implementation 'org.bouncycastle:bcpkix-jdk15on:1.70' | ||||
|     implementation 'org.springframework.boot:spring-boot-starter-actuator' | ||||
|     implementation 'io.micrometer:micrometer-core' | ||||
|     implementation group: 'com.google.zxing', name: 'core', version: '3.5.2' | ||||
|     // https://mvnrepository.com/artifact/org.commonmark/commonmark | ||||
| 	implementation 'org.commonmark:commonmark:0.21.0' | ||||
|     implementation 'org.commonmark:commonmark:0.21.0' | ||||
|     // https://mvnrepository.com/artifact/com.github.vladimir-bukhtoyarov/bucket4j-core | ||||
| 	implementation 'com.github.vladimir-bukhtoyarov:bucket4j-core:7.6.0' | ||||
|      | ||||
|     implementation 'com.github.vladimir-bukhtoyarov:bucket4j-core:7.6.0' | ||||
| 
 | ||||
|     developmentOnly("org.springframework.boot:spring-boot-devtools") | ||||
| 	compileOnly 'org.projectlombok:lombok:1.18.28' | ||||
| 	annotationProcessor 'org.projectlombok:lombok:1.18.28' | ||||
|     compileOnly 'org.projectlombok:lombok:1.18.28' | ||||
|     annotationProcessor 'org.projectlombok:lombok:1.18.28' | ||||
| 
 | ||||
| //// https://mvnrepository.com/artifact/technology.tabula/tabula | ||||
| //    implementation group: 'technology.tabula', name: 'tabula', version: '1.0.5' | ||||
| 
 | ||||
| 
 | ||||
| //    implementation files('/Users/artempetrenko/Java/Stirling-PDF/tabula-1.0.5-jar-with-dependencies.jar') | ||||
|     implementation fileTree(include: ['tabula-1.0.5-jar-with-dependencies.jar'],dir: 'libs') | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| task writeVersion { | ||||
|     def propsFile = file('src/main/resources/version.properties') | ||||
|     def props = new Properties() | ||||
| @ -128,7 +138,7 @@ jar { | ||||
|         attributes 'Implementation-Title': 'Stirling-PDF', | ||||
|                    'Implementation-Version': project.version | ||||
|     } | ||||
|      | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| tasks.named('test') { | ||||
|  | ||||
| @ -99,6 +99,14 @@ public class ConverterWebController { | ||||
|         return modelAndView; | ||||
|     } | ||||
| 
 | ||||
|     @GetMapping("/pdf-to-csv") | ||||
|     @Hidden | ||||
|     public ModelAndView pdfToCSV() { | ||||
|         ModelAndView modelAndView = new ModelAndView("convert/pdf-to-csv"); | ||||
|         modelAndView.addObject("currentPage", "pdf-to-csv"); | ||||
|         return modelAndView; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @GetMapping("/pdf-to-pdfa") | ||||
|     @Hidden | ||||
|  | ||||
| @ -93,7 +93,6 @@ 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.password=Confirmation Password | ||||
| account.oldPassword=Old password | ||||
| account.newPassword=New Password | ||||
| @ -334,7 +333,12 @@ 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=JS | ||||
| 
 | ||||
| home.tableExtraxt.title=Table Extraction | ||||
| home.tableExtraxt.desc=Table Extraction from PDF to CSV | ||||
| tableExtraxt.tags=CSV | ||||
| 
 | ||||
| 
 | ||||
| ########################### | ||||
| #                         # | ||||
| @ -563,7 +567,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) | ||||
| @ -682,8 +686,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 | ||||
| @ -773,7 +777,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 | ||||
| @ -823,3 +826,9 @@ PDFToXML.title=PDF to XML | ||||
| PDFToXML.header=PDF to XML | ||||
| PDFToXML.credit=This service uses LibreOffice for file conversion. | ||||
| PDFToXML.submit=Convert | ||||
| 
 | ||||
| #PDFToCSV | ||||
| PDFToCSV.title=PDF to CSV | ||||
| PDFToCSV.header=PDF to CSV | ||||
| PDFToCSV.credit=This service uses LibreOffice for file conversion. | ||||
| PDFToCSV.submit=Convert | ||||
|  | ||||
							
								
								
									
										1
									
								
								src/main/resources/static/images/pdf-csv.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/main/resources/static/images/pdf-csv.svg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384V304H176c-35.3 0-64 28.7-64 64V512H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zM200 352h16c22.1 0 40 17.9 40 40v8c0 8.8-7.2 16-16 16s-16-7.2-16-16v-8c0-4.4-3.6-8-8-8H200c-4.4 0-8 3.6-8 8v80c0 4.4 3.6 8 8 8h16c4.4 0 8-3.6 8-8v-8c0-8.8 7.2-16 16-16s16 7.2 16 16v8c0 22.1-17.9 40-40 40H200c-22.1 0-40-17.9-40-40V392c0-22.1 17.9-40 40-40zm133.1 0H368c8.8 0 16 7.2 16 16s-7.2 16-16 16H333.1c-7.2 0-13.1 5.9-13.1 13.1c0 5.2 3 9.9 7.8 12l37.4 16.6c16.3 7.2 26.8 23.4 26.8 41.2c0 24.9-20.2 45.1-45.1 45.1H304c-8.8 0-16-7.2-16-16s7.2-16 16-16h42.9c7.2 0 13.1-5.9 13.1-13.1c0-5.2-3-9.9-7.8-12l-37.4-16.6c-16.3-7.2-26.8-23.4-26.8-41.2c0-24.9 20.2-45.1 45.1-45.1zm98.9 0c8.8 0 16 7.2 16 16v31.6c0 23 5.5 45.6 16 66c10.5-20.3 16-42.9 16-66V368c0-8.8 7.2-16 16-16s16 7.2 16 16v31.6c0 34.7-10.3 68.7-29.6 97.6l-5.1 7.7c-3 4.5-8 7.1-13.3 7.1s-10.3-2.7-13.3-7.1l-5.1-7.7c-19.3-28.9-29.6-62.9-29.6-97.6V368c0-8.8 7.2-16 16-16z"/></svg> | ||||
| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										29
									
								
								src/main/resources/templates/convert/pdf-to-csv.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/main/resources/templates/convert/pdf-to-csv.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| <!DOCTYPE html> | ||||
| <html th:lang="${#locale.toString()}" th:lang-direction="#{language.direction}" xmlns:th="http://www.thymeleaf.org"> | ||||
| 
 | ||||
| <th:block th:insert="~{fragments/common :: head(title=#{PDFToXML.title})}"></th:block> | ||||
| <body> | ||||
|     <th:block th:insert="~{fragments/common :: game}"></th:block> | ||||
|     <div id="page-container"> | ||||
|         <div id="content-wrap"> | ||||
|             <div th:insert="~{fragments/navbar.html :: navbar}"></div> | ||||
|             <br> <br> | ||||
|             <div class="container"> | ||||
|                 <div class="row justify-content-center"> | ||||
|                     <div class="col-md-6"> | ||||
|                         <h2 th:text="#{PDFToCSV.header}"></h2> | ||||
|                         <form method="post" enctype="multipart/form-data" th:action="@{api/v1/convert/pdf/csv}"> | ||||
|                             <div th:replace="~{fragments/common :: fileSelector(name='fileInput', multiple=false, accept='application/pdf')}"></div> | ||||
|                             <br> | ||||
|                             <button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{PDFToCSV.submit}"></button> | ||||
| 
 | ||||
|                         </form> | ||||
|                         <p class="mt-3" th:text="#{PDFToCSV.credit}"></p> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|         <div th:insert="~{fragments/footer.html :: footer}"></div> | ||||
|     </div> | ||||
| </body> | ||||
| </html> | ||||
| @ -1,13 +1,13 @@ | ||||
| <div th:fragment="navbar" class="mx-auto"> | ||||
| <script src="js/languageSelection.js"></script> | ||||
|     <script src="js/languageSelection.js"></script> | ||||
| 
 | ||||
| <script th:inline="javascript"> | ||||
| 	const currentVersion =  /*[[${@appVersion}]]*/ ''; | ||||
| 	const noFavourites =  /*[[#{noFavourites}]]*/ ''; | ||||
| </script> | ||||
| <script th:src="@{js/githubVersion.js}"></script> | ||||
|     <script th:inline="javascript"> | ||||
|         const currentVersion =  /*[[${@appVersion}]]*/ ''; | ||||
|         const noFavourites =  /*[[#{noFavourites}]]*/ ''; | ||||
|     </script> | ||||
|     <script th:src="@{js/githubVersion.js}"></script> | ||||
| 
 | ||||
| <link rel="stylesheet" href="css/navbar.css"> | ||||
|     <link rel="stylesheet" href="css/navbar.css"> | ||||
| 
 | ||||
|     <nav class="navbar navbar-expand-lg navbar-light bg-light"> | ||||
|         <div class="container "> | ||||
| @ -39,33 +39,33 @@ | ||||
|                         </a> | ||||
|                     </li>--> | ||||
| 
 | ||||
| <li class="nav-item nav-item-separator"></li> | ||||
|     <li class="nav-item dropdown" th:classappend="${currentPage}=='remove-pages' OR ${currentPage}=='merge-pdfs' OR ${currentPage}=='split-pdfs' OR ${currentPage}=='crop' OR ${currentPage}=='adjust-contrast' OR ${currentPage}=='pdf-organizer' OR ${currentPage}=='rotate-pdf' OR ${currentPage}=='multi-page-layout' OR ${currentPage}=='scale-pages' OR ${currentPage}=='auto-split-pdf' OR ${currentPage}=='extract-page' OR ${currentPage}=='pdf-to-single-page' ? 'active' : ''"> | ||||
|     <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||||
|         <img class="icon" src="images/file-earmark-pdf.svg" alt="icon"> | ||||
|         <span class="icon-text"  th:text="#{navbar.pageOps}"></span> | ||||
|     </a> | ||||
|     <div class="dropdown-menu" aria-labelledby="navbarDropdown"> | ||||
|         <!-- Existing menu items --> | ||||
|         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('merge-pdfs', 'images/union.svg', 'home.merge.title', 'home.merge.desc', 'merge.tags')}"></div> | ||||
|         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('split-pdfs', 'images/layout-split.svg', 'home.split.title', 'home.split.desc', 'split.tags')}"></div> | ||||
|         <div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'pdf-organizer', 'images/sort-numeric-down.svg', 'home.pdfOrganiser.title', 'home.pdfOrganiser.desc', 'pdfOrganiser.tags')}"></div> | ||||
|         <div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'rotate-pdf', 'images/arrow-clockwise.svg', 'home.rotate.title', 'home.rotate.desc', 'rotate.tags')}"></div> | ||||
|         <div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'remove-pages', 'images/file-earmark-x.svg', 'home.removePages.title', 'home.removePages.desc', 'removePages.tags')}"></div> | ||||
| 		<div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'multi-page-layout', 'images/page-layout.svg', 'home.pageLayout.title', 'home.pageLayout.desc', 'pageLayout.tags')}"></div> | ||||
| 		<div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'scale-pages', 'images/scale-pages.svg', 'home.scalePages.title', 'home.scalePages.desc', 'scalePages.tags')}"></div> | ||||
| 		<div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'auto-split-pdf', 'images/layout-split.svg', 'home.autoSplitPDF.title', 'home.autoSplitPDF.desc', 'autoSplitPDF.tags')}"></div> | ||||
|         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('adjust-contrast', 'images/adjust-contrast.svg', 'home.adjust-contrast.title', 'home.adjust-contrast.desc', 'adjust-contrast.tags')}"></div> | ||||
|         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('crop', 'images/crop.svg', 'home.crop.title', 'home.crop.desc', 'crop.tags')}"></div> | ||||
|         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('extract-page', 'images/extract.svg', 'home.extractPage.title', 'home.extractPage.desc', 'extractPage.tags')}"></div> | ||||
|         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('pdf-to-single-page', 'images/single-page.svg', 'home.PdfToSinglePage.title', 'home.PdfToSinglePage.desc', 'PdfToSinglePage.tags')}"></div> | ||||
|                     <li class="nav-item nav-item-separator"></li> | ||||
|                     <li class="nav-item dropdown" th:classappend="${currentPage}=='remove-pages' OR ${currentPage}=='merge-pdfs' OR ${currentPage}=='split-pdfs' OR ${currentPage}=='crop' OR ${currentPage}=='adjust-contrast' OR ${currentPage}=='pdf-organizer' OR ${currentPage}=='rotate-pdf' OR ${currentPage}=='multi-page-layout' OR ${currentPage}=='scale-pages' OR ${currentPage}=='auto-split-pdf' OR ${currentPage}=='extract-page' OR ${currentPage}=='pdf-to-single-page' ? 'active' : ''"> | ||||
|                         <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||||
|                             <img class="icon" src="images/file-earmark-pdf.svg" alt="icon"> | ||||
|                             <span class="icon-text"  th:text="#{navbar.pageOps}"></span> | ||||
|                         </a> | ||||
|                         <div class="dropdown-menu" aria-labelledby="navbarDropdown"> | ||||
|                             <!-- Existing menu items --> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('merge-pdfs', 'images/union.svg', 'home.merge.title', 'home.merge.desc', 'merge.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('split-pdfs', 'images/layout-split.svg', 'home.split.title', 'home.split.desc', 'split.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'pdf-organizer', 'images/sort-numeric-down.svg', 'home.pdfOrganiser.title', 'home.pdfOrganiser.desc', 'pdfOrganiser.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'rotate-pdf', 'images/arrow-clockwise.svg', 'home.rotate.title', 'home.rotate.desc', 'rotate.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'remove-pages', 'images/file-earmark-x.svg', 'home.removePages.title', 'home.removePages.desc', 'removePages.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'multi-page-layout', 'images/page-layout.svg', 'home.pageLayout.title', 'home.pageLayout.desc', 'pageLayout.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'scale-pages', 'images/scale-pages.svg', 'home.scalePages.title', 'home.scalePages.desc', 'scalePages.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ( 'auto-split-pdf', 'images/layout-split.svg', 'home.autoSplitPDF.title', 'home.autoSplitPDF.desc', 'autoSplitPDF.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('adjust-contrast', 'images/adjust-contrast.svg', 'home.adjust-contrast.title', 'home.adjust-contrast.desc', 'adjust-contrast.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('crop', 'images/crop.svg', 'home.crop.title', 'home.crop.desc', 'crop.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('extract-page', 'images/extract.svg', 'home.extractPage.title', 'home.extractPage.desc', 'extractPage.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('pdf-to-single-page', 'images/single-page.svg', 'home.PdfToSinglePage.title', 'home.PdfToSinglePage.desc', 'PdfToSinglePage.tags')}"></div> | ||||
| 
 | ||||
| 
 | ||||
|     </div> | ||||
| </li> | ||||
| <li class="nav-item nav-item-separator"></li> | ||||
|                         </div> | ||||
|                     </li> | ||||
|                     <li class="nav-item nav-item-separator"></li> | ||||
|                     <li class="nav-item dropdown" th:classappend="${currentPage}=='pdf-to-img' OR ${currentPage}=='img-to-pdf' OR ${currentPage}=='pdf-to-pdfa' OR ${currentPage}=='file-to-pdf' OR ${currentPage}=='xlsx-to-pdf' OR ${currentPage}=='pdf-to-word' OR ${currentPage}=='pdf-to-presentation' OR ${currentPage}=='pdf-to-text' OR ${currentPage}=='pdf-to-html' OR ${currentPage}=='pdf-to-xml' ? 'active' : ''"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" | ||||
|                         aria-haspopup="true" aria-expanded="false"> | ||||
|                                                                                                                                                                                                                                                                                                                                                                                                                                   aria-haspopup="true" aria-expanded="false"> | ||||
|                         <img class="icon" src="images/arrow-left-right.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;"> | ||||
|                         <span class="icon-text"  th:text="#{navbar.convert}"></span> | ||||
|                     </a> | ||||
| @ -75,7 +75,7 @@ | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('file-to-pdf', 'images/file.svg', 'home.fileToPDF.title', 'home.fileToPDF.desc', 'fileToPDF.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('html-to-pdf', 'images/html.svg', 'home.HTMLToPDF.title', 'home.HTMLToPDF.desc', 'HTMLToPDF.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('url-to-pdf', 'images/url.svg', 'home.URLToPDF.title', 'home.URLToPDF.desc', 'URLToPDF.tags')}"></div> | ||||
| 							<div th:replace="~{fragments/navbarEntry :: navbarEntry ('markdown-to-pdf', 'images/markdown.svg', 'home.MarkdownToPDF.title', 'home.MarkdownToPDF.desc', 'MarkdownToPDF.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('markdown-to-pdf', 'images/markdown.svg', 'home.MarkdownToPDF.title', 'home.MarkdownToPDF.desc', 'MarkdownToPDF.tags')}"></div> | ||||
|                             <hr class="dropdown-divider"> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('pdf-to-img', 'images/image.svg', 'home.pdfToImage.title', 'home.pdfToImage.desc', 'pdfToImage.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('pdf-to-word', 'images/file-earmark-word.svg', 'home.PDFToWord.title', 'home.PDFToWord.desc', 'PDFToWord.tags')}"></div> | ||||
| @ -91,32 +91,34 @@ | ||||
|                         </div> | ||||
|                     </li> | ||||
| 
 | ||||
| <li class="nav-item nav-item-separator"></li> | ||||
|                     <li class="nav-item nav-item-separator"></li> | ||||
| 
 | ||||
|                   <li class="nav-item dropdown" th:classappend="${currentPage}=='add-password' OR ${currentPage}=='remove-password' OR ${currentPage}=='add-watermark' OR ${currentPage}=='cert-sign' OR ${currentPage}=='sanitize-pdf' ? 'active' : ''"> | ||||
|                     <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||||
|                         <img class="icon" src="images/shield-check.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;"> <span class="icon-text"  th:text="#{navbar.security}"></span> | ||||
|                     </a> | ||||
|                     <div class="dropdown-menu" aria-labelledby="navbarDropdown"> | ||||
|                         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-password', 'images/lock.svg', 'home.addPassword.title', 'home.addPassword.desc', 'addPassword.tags')}"></div> | ||||
|                         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('remove-password', 'images/unlock.svg', 'home.removePassword.title', 'home.removePassword.desc', 'removePassword.tags')}"></div> | ||||
|                         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('change-permissions', 'images/shield-lock.svg', 'home.permissions.title', 'home.permissions.desc', 'permissions.tags')}"></div> | ||||
|                         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-watermark', 'images/droplet.svg', 'home.watermark.title', 'home.watermark.desc', 'watermark.tags')}"></div> | ||||
|                         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('cert-sign', 'images/award.svg', 'home.certSign.title', 'home.certSign.desc', 'certSign.tags')}"></div> | ||||
|                         <div th:replace="~{fragments/navbarEntry :: navbarEntry ('sanitize-pdf', 'images/sanitize.svg', 'home.sanitizePdf.title', 'home.sanitizePdf.desc', 'sanitizePdf.tags')}"></div> | ||||
| 						<div th:replace="~{fragments/navbarEntry :: navbarEntry ('auto-redact', 'images/eraser-fill.svg', 'home.autoRedact.title', 'home.autoRedact.desc', 'autoRedact.tags')}"></div> | ||||
|                     </div> | ||||
|                 </li> | ||||
|                     <li class="nav-item dropdown" th:classappend="${currentPage}=='add-password' OR ${currentPage}=='remove-password' OR ${currentPage}=='add-watermark' OR ${currentPage}=='cert-sign' OR ${currentPage}=='sanitize-pdf' ? 'active' : ''"> | ||||
|                         <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||||
|                             <img class="icon" src="images/shield-check.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;"> <span class="icon-text"  th:text="#{navbar.security}"></span> | ||||
|                         </a> | ||||
|                         <div class="dropdown-menu" aria-labelledby="navbarDropdown"> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-password', 'images/lock.svg', 'home.addPassword.title', 'home.addPassword.desc', 'addPassword.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('remove-password', 'images/unlock.svg', 'home.removePassword.title', 'home.removePassword.desc', 'removePassword.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('change-permissions', 'images/shield-lock.svg', 'home.permissions.title', 'home.permissions.desc', 'permissions.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-watermark', 'images/droplet.svg', 'home.watermark.title', 'home.watermark.desc', 'watermark.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('cert-sign', 'images/award.svg', 'home.certSign.title', 'home.certSign.desc', 'certSign.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('sanitize-pdf', 'images/sanitize.svg', 'home.sanitizePdf.title', 'home.sanitizePdf.desc', 'sanitizePdf.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('auto-redact', 'images/eraser-fill.svg', 'home.autoRedact.title', 'home.autoRedact.desc', 'autoRedact.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('auto-extract', 'images/eraser-fill.svg', 'home.tableExtraxt.title', 'home.tableExtraxt.desc', 'tableExtraxt.tags')}"></div> | ||||
| 
 | ||||
|                   <li class="nav-item nav-item-separator"></li> | ||||
|                         </div> | ||||
|                     </li> | ||||
| 
 | ||||
|                     <li class="nav-item nav-item-separator"></li> | ||||
|                     <li class="nav-item dropdown" th:classappend="${currentPage}=='sign' OR ${currentPage}=='repair' OR ${currentPage}=='compare' OR ${currentPage}=='show-javascript' OR ${currentPage}=='flatten' OR ${currentPage}=='remove-blanks' OR ${currentPage}=='extract-image-scans' OR ${currentPage}=='change-metadata' OR ${currentPage}=='add-image' OR ${currentPage}=='ocr-pdf' OR ${currentPage}=='change-permissions' OR ${currentPage}=='extract-images' OR ${currentPage}=='compress-pdf' OR ${currentPage}=='add-page-numbers' OR ${currentPage}=='auto-rename' OR ${currentPage}=='get-info-on-pdf' ? 'active' : ''"> | ||||
|                         <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||||
|                         <img class="icon" src="images/card-list.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;"> | ||||
|                         <span class="icon-text"  th:text="#{navbar.other}"></span> | ||||
|                             <img class="icon" src="images/card-list.svg" alt="icon" style="width: 16px; height: 16px; vertical-align: middle;"> | ||||
|                             <span class="icon-text"  th:text="#{navbar.other}"></span> | ||||
| 
 | ||||
|                         </a> | ||||
|                         <div class="dropdown-menu" aria-labelledby="navbarDropdown"> | ||||
|                         	<!--<div th:replace="~{fragments/navbarEntry :: navbarEntry ('pipeline', 'images/pipeline.svg', 'home.pipeline.title', 'home.pipeline.desc', 'pipeline.tags')}"></div> --> | ||||
|                             <!--<div th:replace="~{fragments/navbarEntry :: navbarEntry ('pipeline', 'images/pipeline.svg', 'home.pipeline.title', 'home.pipeline.desc', 'pipeline.tags')}"></div> --> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('ocr-pdf', 'images/search.svg', 'home.ocr.title', 'home.ocr.desc', 'ocr.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-image', 'images/file-earmark-richtext.svg', 'home.addImage.title', 'home.addImage.desc', 'addImage.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('compress-pdf', 'images/file-zip.svg', 'home.compressPdfs.title', 'home.compressPdfs.desc', 'compressPdfs.tags')}"></div> | ||||
| @ -130,8 +132,8 @@ | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('compare', 'images/scales.svg', 'home.compare.title', 'home.compare.desc', 'compare.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('add-page-numbers', 'images/add-page-numbers.svg', 'home.add-page-numbers.title', 'home.add-page-numbers.desc', 'add-page-numbers.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('auto-rename', 'images/fonts.svg', 'home.auto-rename.title', 'home.auto-rename.desc', 'auto-rename.tags')}"></div> | ||||
|                         	<div th:replace="~{fragments/navbarEntry :: navbarEntry ('get-info-on-pdf', 'images/info.svg', 'home.getPdfInfo.title', 'home.getPdfInfo.desc', 'getPdfInfo.tags')}"></div> | ||||
|                         	<div th:replace="~{fragments/navbarEntry :: navbarEntry ('show-javascript', 'images/js.svg', 'home.showJS.title', 'home.showJS.desc', 'showJS.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('get-info-on-pdf', 'images/info.svg', 'home.getPdfInfo.title', 'home.getPdfInfo.desc', 'getPdfInfo.tags')}"></div> | ||||
|                             <div th:replace="~{fragments/navbarEntry :: navbarEntry ('show-javascript', 'images/js.svg', 'home.showJS.title', 'home.showJS.desc', 'showJS.tags')}"></div> | ||||
|                         </div> | ||||
|                     </li> | ||||
| 
 | ||||
| @ -147,23 +149,23 @@ | ||||
|                         </div> | ||||
|                     </li> | ||||
| 
 | ||||
|           | ||||
| 
 | ||||
| 					<script src="js/languageSelection.js"></script> | ||||
| 					<script src="js/darkmode.js"></script> | ||||
| 
 | ||||
|     				<li class="nav-item"> | ||||
|                     <script src="js/languageSelection.js"></script> | ||||
|                     <script src="js/darkmode.js"></script> | ||||
| 
 | ||||
|                     <li class="nav-item"> | ||||
|                         <a class="nav-link" id="dark-mode-toggle" href="#"> | ||||
|                           <img class="navbar-icon" id="dark-mode-icon" src="moon.svg" alt="icon" /> | ||||
|                             <img class="navbar-icon" id="dark-mode-icon" src="moon.svg" alt="icon" /> | ||||
|                         </a> | ||||
|                       </li> | ||||
|                     </li> | ||||
| 
 | ||||
|                     <li class="nav-item dropdown"> | ||||
|                         <a class="nav-link dropdown-toggle" href="#" id="languageDropdown" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||||
|                         <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-globe2 globe-icon" viewBox="0 0 20 20"> | ||||
|                           <path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 1.855-.143.268-.276.56-.395.872.705.157 1.472.257 2.282.287V1.077zM4.249 3.539c.142-.384.304-.744.481-1.078a6.7 6.7 0 0 1 .597-.933A7.01 7.01 0 0 0 3.051 3.05c.362.184.763.349 1.198.49zM3.509 7.5c.036-1.07.188-2.087.436-3.008a9.124 9.124 0 0 1-1.565-.667A6.964 6.964 0 0 0 1.018 7.5h2.49zm1.4-2.741a12.344 12.344 0 0 0-.4 2.741H7.5V5.091c-.91-.03-1.783-.145-2.591-.332zM8.5 5.09V7.5h2.99a12.342 12.342 0 0 0-.399-2.741c-.808.187-1.681.301-2.591.332zM4.51 8.5c.035.987.176 1.914.399 2.741A13.612 13.612 0 0 1 7.5 10.91V8.5H4.51zm3.99 0v2.409c.91.03 1.783.145 2.591.332.223-.827.364-1.754.4-2.741H8.5zm-3.282 3.696c.12.312.252.604.395.872.552 1.035 1.218 1.65 1.887 1.855V11.91c-.81.03-1.577.13-2.282.287zm.11 2.276a6.696 6.696 0 0 1-.598-.933 8.853 8.853 0 0 1-.481-1.079 8.38 8.38 0 0 0-1.198.49 7.01 7.01 0 0 0 2.276 1.522zm-1.383-2.964A13.36 13.36 0 0 1 3.508 8.5h-2.49a6.963 6.963 0 0 0 1.362 3.675c.47-.258.995-.482 1.565-.667zm6.728 2.964a7.009 7.009 0 0 0 2.275-1.521 8.376 8.376 0 0 0-1.197-.49 8.853 8.853 0 0 1-.481 1.078 6.688 6.688 0 0 1-.597.933zM8.5 11.909v3.014c.67-.204 1.335-.82 1.887-1.855.143-.268.276-.56.395-.872A12.63 12.63 0 0 0 8.5 11.91zm3.555-.401c.57.185 1.095.409 1.565.667A6.963 6.963 0 0 0 14.982 8.5h-2.49a13.36 13.36 0 0 1-.437 3.008zM14.982 7.5a6.963 6.963 0 0 0-1.362-3.675c-.47.258-.995.482-1.565.667.248.92.4 1.938.437 3.008h2.49zM11.27 2.461c.177.334.339.694.482 1.078a8.368 8.368 0 0 0 1.196-.49 7.01 7.01 0 0 0-2.275-1.52c.218.283.418.597.597.932zm-.488 1.343a7.765 7.765 0 0 0-.395-.872C9.835 1.897 9.17 1.282 8.5 1.077V4.09c.81-.03 1.577-.13 2.282-.287z"/> | ||||
|                         </svg> | ||||
|                          </a> | ||||
|                             <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-globe2 globe-icon" viewBox="0 0 20 20"> | ||||
|                                 <path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 1.855-.143.268-.276.56-.395.872.705.157 1.472.257 2.282.287V1.077zM4.249 3.539c.142-.384.304-.744.481-1.078a6.7 6.7 0 0 1 .597-.933A7.01 7.01 0 0 0 3.051 3.05c.362.184.763.349 1.198.49zM3.509 7.5c.036-1.07.188-2.087.436-3.008a9.124 9.124 0 0 1-1.565-.667A6.964 6.964 0 0 0 1.018 7.5h2.49zm1.4-2.741a12.344 12.344 0 0 0-.4 2.741H7.5V5.091c-.91-.03-1.783-.145-2.591-.332zM8.5 5.09V7.5h2.99a12.342 12.342 0 0 0-.399-2.741c-.808.187-1.681.301-2.591.332zM4.51 8.5c.035.987.176 1.914.399 2.741A13.612 13.612 0 0 1 7.5 10.91V8.5H4.51zm3.99 0v2.409c.91.03 1.783.145 2.591.332.223-.827.364-1.754.4-2.741H8.5zm-3.282 3.696c.12.312.252.604.395.872.552 1.035 1.218 1.65 1.887 1.855V11.91c-.81.03-1.577.13-2.282.287zm.11 2.276a6.696 6.696 0 0 1-.598-.933 8.853 8.853 0 0 1-.481-1.079 8.38 8.38 0 0 0-1.198.49 7.01 7.01 0 0 0 2.276 1.522zm-1.383-2.964A13.36 13.36 0 0 1 3.508 8.5h-2.49a6.963 6.963 0 0 0 1.362 3.675c.47-.258.995-.482 1.565-.667zm6.728 2.964a7.009 7.009 0 0 0 2.275-1.521 8.376 8.376 0 0 0-1.197-.49 8.853 8.853 0 0 1-.481 1.078 6.688 6.688 0 0 1-.597.933zM8.5 11.909v3.014c.67-.204 1.335-.82 1.887-1.855.143-.268.276-.56.395-.872A12.63 12.63 0 0 0 8.5 11.91zm3.555-.401c.57.185 1.095.409 1.565.667A6.963 6.963 0 0 0 14.982 8.5h-2.49a13.36 13.36 0 0 1-.437 3.008zM14.982 7.5a6.963 6.963 0 0 0-1.362-3.675c-.47.258-.995.482-1.565.667.248.92.4 1.938.437 3.008h2.49zM11.27 2.461c.177.334.339.694.482 1.078a8.368 8.368 0 0 0 1.196-.49 7.01 7.01 0 0 0-2.275-1.52c.218.283.418.597.597.932zm-.488 1.343a7.765 7.765 0 0 0-.395-.872C9.835 1.897 9.17 1.282 8.5 1.077V4.09c.81-.03 1.577-.13 2.282-.287z"/> | ||||
|                             </svg> | ||||
|                         </a> | ||||
|                         <div class="dropdown-menu" aria-labelledby="languageDropdown"> | ||||
|                             <th:block th:insert="~{fragments/languages :: langs}"></th:block> | ||||
|                         </div> | ||||
| @ -178,68 +180,68 @@ | ||||
| 
 | ||||
|                     </li> | ||||
| 
 | ||||
|              <!-- Search Button and Search Bar --> | ||||
| <li class="nav-item position-relative"> | ||||
|     <a href="#" class="nav-link" id="search-icon"> | ||||
|         <img class="navbar-icon" src="images/search.svg" alt="icon" width="24" height="24"> | ||||
|     </a> | ||||
|     <!-- Search Bar --> | ||||
|     <div class="collapse position-absolute" id="navbarSearch"> | ||||
|         <form class="d-flex p-2 bg-white border search-form" id="searchForm"> | ||||
|             <input class="form-control search-input" type="search" placeholder="Search" aria-label="Search" id="navbarSearchInput"> | ||||
|         </form> | ||||
|         <!-- Search Results --> | ||||
|         <div id="searchResults" class="border p-2 bg-white search-results"></div> | ||||
|     </div> | ||||
| </li> | ||||
| <style> | ||||
| #search-icon i { | ||||
|     font-size: 24px; /* Adjust this to your desired size */ | ||||
|     transition: color 0.3s; | ||||
| } | ||||
|                     <!-- Search Button and Search Bar --> | ||||
|                     <li class="nav-item position-relative"> | ||||
|                         <a href="#" class="nav-link" id="search-icon"> | ||||
|                             <img class="navbar-icon" src="images/search.svg" alt="icon" width="24" height="24"> | ||||
|                         </a> | ||||
|                         <!-- Search Bar --> | ||||
|                         <div class="collapse position-absolute" id="navbarSearch"> | ||||
|                             <form class="d-flex p-2 bg-white border search-form" id="searchForm"> | ||||
|                                 <input class="form-control search-input" type="search" placeholder="Search" aria-label="Search" id="navbarSearchInput"> | ||||
|                             </form> | ||||
|                             <!-- Search Results --> | ||||
|                             <div id="searchResults" class="border p-2 bg-white search-results"></div> | ||||
|                         </div> | ||||
|                     </li> | ||||
|                     <style> | ||||
|                         #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-icon:hover i { | ||||
|                             color: #666; /* Adjust this to your hover color */ | ||||
|                         } | ||||
| 
 | ||||
| #navbarSearch { | ||||
|     transition: all 0.3s; | ||||
|     max-height: 0; | ||||
|     overflow: hidden; | ||||
|                         #navbarSearch { | ||||
|                             transition: all 0.3s; | ||||
|                             max-height: 0; | ||||
|                             overflow: hidden; | ||||
| 
 | ||||
| } | ||||
|                         } | ||||
| 
 | ||||
| #navbarSearch.show { | ||||
|     max-height: 300px; /* Adjust this to your desired max height */ | ||||
| } | ||||
|                         #navbarSearch.show { | ||||
|                             max-height: 300px; /* Adjust this to your desired max height */ | ||||
|                         } | ||||
| 
 | ||||
| .search-input { | ||||
|     transition: border 0.3s, box-shadow 0.3s; | ||||
|                         .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 */ | ||||
| } | ||||
|                         .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 */ | ||||
|                         } | ||||
| 
 | ||||
| #searchResults { | ||||
|     max-width: 300px; /* Adjust to your preferred width */ | ||||
|     transition: height 0.3s ease; /* Smooth height transition */ | ||||
| } | ||||
|                         #searchResults { | ||||
|                             max-width: 300px; /* Adjust to your preferred width */ | ||||
|                             transition: height 0.3s ease; /* Smooth height transition */ | ||||
|                         } | ||||
| 
 | ||||
| /* 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 */ | ||||
| } | ||||
|                         /* 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 */ | ||||
|                         } | ||||
| 
 | ||||
| </style> | ||||
|                     </style> | ||||
| 
 | ||||
|                 </ul> | ||||
| 
 | ||||
| @ -251,61 +253,61 @@ | ||||
|         <script src="js/search.js"></script> | ||||
|     </nav> | ||||
| 
 | ||||
| 	<div th:insert="~{fragments/errorBannerPerPage.html :: errorBannerPerPage}"></div> | ||||
|     <div th:insert="~{fragments/errorBannerPerPage.html :: errorBannerPerPage}"></div> | ||||
|     <div class="modal fade" id="settingsModal" tabindex="-1" role="dialog" aria-labelledby="settingsModalLabel" aria-hidden="true"> | ||||
|     <div class="modal-dialog modal-dialog-centered" role="document"> | ||||
|         <div class="modal-content dark-card"> | ||||
|             <div class="modal-header"> | ||||
|                 <h5 class="modal-title" id="settingsModalLabel" th:text="#{settings.title}"></h5> | ||||
|                 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> | ||||
|             </div> | ||||
|             <div class="modal-body"> | ||||
|                 <div class="d-flex justify-content-between align-items-center mb-3"> | ||||
|                     <p class="mb-0" th:utext="#{settings.appVersion} + ' ' + ${@appVersion}"></p> | ||||
|                     <a href="https://github.com/sponsors/Frooodle" target="_blank"> | ||||
|                         <button type="button" class="btn btn-sm btn-outline-primary">Sponsor Stirling-PDF</button> | ||||
|         <div class="modal-dialog modal-dialog-centered" role="document"> | ||||
|             <div class="modal-content dark-card"> | ||||
|                 <div class="modal-header"> | ||||
|                     <h5 class="modal-title" id="settingsModalLabel" th:text="#{settings.title}"></h5> | ||||
|                     <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> | ||||
|                 </div> | ||||
|                 <div class="modal-body"> | ||||
|                     <div class="d-flex justify-content-between align-items-center mb-3"> | ||||
|                         <p class="mb-0" th:utext="#{settings.appVersion} + ' ' + ${@appVersion}"></p> | ||||
|                         <a href="https://github.com/sponsors/Frooodle" target="_blank"> | ||||
|                             <button type="button" class="btn btn-sm btn-outline-primary">Sponsor Stirling-PDF</button> | ||||
|                         </a> | ||||
|                         <a href="swagger-ui/index.html" target="_blank"> | ||||
|                             <button type="button" class="btn btn-sm btn-outline-primary">API</button> | ||||
|                         </a> | ||||
|                         <a href="https://github.com/Frooodle/Stirling-PDF/releases" target="_blank"> | ||||
|                             <button type="button" class="btn btn-sm btn-outline-primary" id="update-btn" th:utext="#{settings.update}"></button> | ||||
|                         </a> | ||||
|                     </div> | ||||
|                     <div class="mb-3"> | ||||
|                         <label for="downloadOption" th:utext="#{settings.downloadOption.title}"></label> | ||||
|                         <select class="form-control" id="downloadOption"> | ||||
|                             <option value="sameWindow" th:utext="#{settings.downloadOption.1}"></option> | ||||
|                             <option value="newWindow" th:utext="#{settings.downloadOption.2}"></option> | ||||
|                             <option value="downloadFile" th:utext="#{settings.downloadOption.3}"></option> | ||||
|                         </select> | ||||
|                     </div> | ||||
|                     <div class="mb-3"> | ||||
|                         <label for="zipThreshold" th:utext="#{settings.zipThreshold}"></label> | ||||
|                         <input type="range" class="form-range" min="1" max="9" step="1" id="zipThreshold" value="4"> | ||||
|                         <span id="zipThresholdValue" class="ms-2"></span> | ||||
|                     </div> | ||||
|                     <div class="mb-3 form-check"> | ||||
|                         <input type="checkbox" class="form-check-input" id="boredWaiting"> | ||||
|                         <label class="form-check-label" for="boredWaiting" th:text="#{bored}"></label> | ||||
|                     </div> | ||||
|                     <a th:if="${@loginEnabled}" href="account" target="_blank"> | ||||
|                         <button type="button" class="btn btn-sm btn-outline-primary" th:text="#{settings.accountSettings}">Account Settings</button> | ||||
|                     </a> | ||||
|                     <a href="swagger-ui/index.html" target="_blank"> | ||||
|                         <button type="button" class="btn btn-sm btn-outline-primary">API</button> | ||||
|                 </div> | ||||
|                 <div class="modal-footer"> | ||||
|                     <a th:if="${@loginEnabled}" href="/logout"> | ||||
|                         <button type="button" class="btn btn-danger" th:text="#{settings.signOut}">Sign Out</button> | ||||
|                     </a> | ||||
|                     <a href="https://github.com/Frooodle/Stirling-PDF/releases" target="_blank"> | ||||
| 					    <button type="button" class="btn btn-sm btn-outline-primary" id="update-btn" th:utext="#{settings.update}"></button> | ||||
| 					</a> | ||||
|                     <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" th:text="#{close}"></button> | ||||
|                 </div> | ||||
|                 <div class="mb-3"> | ||||
|                     <label for="downloadOption" th:utext="#{settings.downloadOption.title}"></label> | ||||
|                     <select class="form-control" id="downloadOption"> | ||||
|                         <option value="sameWindow" th:utext="#{settings.downloadOption.1}"></option> | ||||
|                         <option value="newWindow" th:utext="#{settings.downloadOption.2}"></option> | ||||
|                         <option value="downloadFile" th:utext="#{settings.downloadOption.3}"></option> | ||||
|                     </select> | ||||
|                 </div> | ||||
|                 <div class="mb-3"> | ||||
|                     <label for="zipThreshold" th:utext="#{settings.zipThreshold}"></label> | ||||
|                     <input type="range" class="form-range" min="1" max="9" step="1" id="zipThreshold" value="4"> | ||||
|                     <span id="zipThresholdValue" class="ms-2"></span> | ||||
|                 </div> | ||||
|                 <div class="mb-3 form-check"> | ||||
|                     <input type="checkbox" class="form-check-input" id="boredWaiting"> | ||||
|                     <label class="form-check-label" for="boredWaiting" th:text="#{bored}"></label> | ||||
|                 </div> | ||||
|                 <a th:if="${@loginEnabled}" href="account" target="_blank"> | ||||
|                     <button type="button" class="btn btn-sm btn-outline-primary" th:text="#{settings.accountSettings}">Account Settings</button> | ||||
|                 </a> | ||||
|             </div> | ||||
|             <div class="modal-footer"> | ||||
|             	<a th:if="${@loginEnabled}" href="/logout"> | ||||
| 	                <button type="button" class="btn btn-danger" th:text="#{settings.signOut}">Sign Out</button> | ||||
| 	            </a> | ||||
|                 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" th:text="#{close}"></button> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| <script src="js/settings.js"></script> | ||||
|     <script src="js/settings.js"></script> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -8,98 +8,99 @@ | ||||
| 
 | ||||
| <body> | ||||
| 
 | ||||
|     <div id="page-container"> | ||||
|         <div id="content-wrap"> | ||||
|             <div th:insert="~{fragments/navbar.html :: navbar}"></div> | ||||
|             <!-- Jumbotron --> | ||||
|             <div class="bg-light p-5 rounded d-none d-md-block" id="jumbotron"> | ||||
|                 <div class="container"> | ||||
|                     <h1 class="display-4" th:text="${@appName}"></h1> | ||||
|                     <p class="lead" th:text="${@homeText != 'null' and @homeText != null and @homeText != ''} ? ${@homeText} : #{home.desc}"></p> | ||||
|                 </div> | ||||
| <div id="page-container"> | ||||
|     <div id="content-wrap"> | ||||
|         <div th:insert="~{fragments/navbar.html :: navbar}"></div> | ||||
|         <!-- Jumbotron --> | ||||
|         <div class="bg-light p-5 rounded d-none d-md-block" id="jumbotron"> | ||||
|             <div class="container"> | ||||
|                 <h1 class="display-4" th:text="${@appName}"></h1> | ||||
|                 <p class="lead" th:text="${@homeText != 'null' and @homeText != null and @homeText != ''} ? ${@homeText} : #{home.desc}"></p> | ||||
|             </div> | ||||
| 			<br class="d-md-none"> | ||||
|             <!-- Features --> | ||||
|             <script src="js/homecard.js"></script> | ||||
|             	 | ||||
|             <div class=" container"> | ||||
|         </div> | ||||
|         <br class="d-md-none"> | ||||
|         <!-- Features --> | ||||
|         <script src="js/homecard.js"></script> | ||||
| 
 | ||||
|         <div class=" container"> | ||||
|             <br> | ||||
|             <input type="text" id="searchBar" onkeyup="filterCards()" th:placeholder="#{home.searchBar}"> | ||||
|             <div class="features-container "> | ||||
|             	 | ||||
|             	 | ||||
|                  <!-- <div th:replace="~{fragments/card :: card(id='pipeline', cardTitle=#{home.pipeline.title}, cardText=#{home.pipeline.desc}, cardLink='pipeline', svgPath='images/pipeline.svg')}"></div> --> | ||||
| 
 | ||||
| 
 | ||||
|                 <!-- <div th:replace="~{fragments/card :: card(id='pipeline', cardTitle=#{home.pipeline.title}, cardText=#{home.pipeline.desc}, cardLink='pipeline', svgPath='images/pipeline.svg')}"></div> --> | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='view-pdf', cardTitle=#{home.viewPdf.title}, cardText=#{home.viewPdf.desc}, cardLink='view-pdf', svgPath='images/book-opened.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='multi-tool', cardTitle=#{home.multiTool.title}, cardText=#{home.multiTool.desc}, cardLink='multi-tool', svgPath='images/tools.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='merge-pdfs', cardTitle=#{home.merge.title}, cardText=#{home.merge.desc}, cardLink='merge-pdfs', svgPath='images/union.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='split-pdfs', cardTitle=#{home.split.title}, cardText=#{home.split.desc}, cardLink='split-pdfs', svgPath='images/layout-split.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='rotate-pdf', cardTitle=#{home.rotate.title}, cardText=#{home.rotate.desc}, cardLink='rotate-pdf', svgPath='images/arrow-clockwise.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='crop', cardTitle=#{home.crop.title}, cardText=#{home.crop.desc}, cardLink='crop', svgPath='images/crop.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='add-page-numbers', cardTitle=#{home.add-page-numbers.title}, cardText=#{home.add-page-numbers.desc}, cardLink='add-page-numbers', svgPath='images/add-page-numbers.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='adjust-contrast', cardTitle=#{home.adjust-contrast.title}, cardText=#{home.adjust-contrast.desc}, cardLink='adjust-contrast', svgPath='images/adjust-contrast.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='img-to-pdf', cardTitle=#{home.imageToPdf.title}, cardText=#{home.imageToPdf.desc}, cardLink='img-to-pdf', svgPath='images/image.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='pdf-to-img', cardTitle=#{home.pdfToImage.title}, cardText=#{home.pdfToImage.desc}, cardLink='pdf-to-img', svgPath='images/image.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='pdf-organizer', cardTitle=#{home.pdfOrganiser.title}, cardText=#{home.pdfOrganiser.desc}, cardLink='pdf-organizer', svgPath='images/sort-numeric-down.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='add-image', cardTitle=#{home.addImage.title}, cardText=#{home.addImage.desc}, cardLink='add-image', svgPath='images/file-earmark-richtext.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='add-watermark', cardTitle=#{home.watermark.title}, cardText=#{home.watermark.desc}, cardLink='add-watermark', svgPath='images/droplet.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='file-to-pdf', cardTitle=#{home.fileToPDF.title}, cardText=#{home.fileToPDF.desc}, cardLink='file-to-pdf', svgPath='images/file.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='remove-pages', cardTitle=#{home.removePages.title}, cardText=#{home.removePages.desc}, cardLink='remove-pages', svgPath='images/file-earmark-x.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='add-password', cardTitle=#{home.addPassword.title}, cardText=#{home.addPassword.desc}, cardLink='add-password', svgPath='images/lock.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='remove-password', cardTitle=#{home.removePassword.title}, cardText=#{home.removePassword.desc}, cardLink='remove-password', svgPath='images/unlock.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='compress-pdf', cardTitle=#{home.compressPdfs.title}, cardText=#{home.compressPdfs.desc}, cardLink='compress-pdf', svgPath='images/file-zip.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='change-metadata', cardTitle=#{home.changeMetadata.title}, cardText=#{home.changeMetadata.desc}, cardLink='change-metadata', svgPath='images/clipboard-data.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='change-permissions', cardTitle=#{home.permissions.title}, cardText=#{home.permissions.desc}, cardLink='change-permissions', svgPath='images/shield-lock.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='ocr-pdf', cardTitle=#{home.ocr.title}, cardText=#{home.ocr.desc}, cardLink='ocr-pdf', svgPath='images/search.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='extract-images', cardTitle=#{home.extractImages.title}, cardText=#{home.extractImages.desc}, cardLink='extract-images', svgPath='images/images.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='pdf-to-pdfa', cardTitle=#{home.pdfToPDFA.title}, cardText=#{home.pdfToPDFA.desc}, cardLink='pdf-to-pdfa', svgPath='images/file-earmark-pdf.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='pdf-to-word', cardTitle=#{home.PDFToWord.title}, cardText=#{home.PDFToWord.desc}, cardLink='pdf-to-word', svgPath='images/file-earmark-word.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='pdf-to-presentation', cardTitle=#{home.PDFToPresentation.title}, cardText=#{home.PDFToPresentation.desc}, cardLink='pdf-to-presentation', svgPath='images/file-earmark-ppt.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='pdf-to-text', cardTitle=#{home.PDFToText.title}, cardText=#{home.PDFToText.desc}, cardLink='pdf-to-text', svgPath='images/filetype-txt.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='pdf-to-html', cardTitle=#{home.PDFToHTML.title}, cardText=#{home.PDFToHTML.desc}, cardLink='pdf-to-html', svgPath='images/filetype-html.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='pdf-to-xml', cardTitle=#{home.PDFToXML.title}, cardText=#{home.PDFToXML.desc}, cardLink='pdf-to-xml', svgPath='images/filetype-xml.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='extract-image-scans', cardTitle=#{home.ScannerImageSplit.title}, cardText=#{home.ScannerImageSplit.desc}, cardLink='extract-image-scans', svgPath='images/scanner.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='sign', cardTitle=#{home.sign.title}, cardText=#{home.sign.desc}, cardLink='sign', svgPath='images/sign.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='flatten', cardTitle=#{home.flatten.title}, cardText=#{home.flatten.desc}, cardLink='flatten', svgPath='images/flatten.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='repair', cardTitle=#{home.repair.title}, cardText=#{home.repair.desc}, cardLink='repair', svgPath='images/wrench.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='remove-blanks', cardTitle=#{home.removeBlanks.title}, cardText=#{home.removeBlanks.desc}, cardLink='remove-blanks', svgPath='images/blank-file.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='compare', cardTitle=#{home.compare.title}, cardText=#{home.compare.desc}, cardLink='compare', svgPath='images/scales.svg')}"></div> | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='cert-sign', cardTitle=#{home.certSign.title}, cardText=#{home.certSign.desc}, cardLink='cert-sign', svgPath='images/award.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='multi-page-layout', cardTitle=#{home.pageLayout.title}, cardText=#{home.pageLayout.desc}, cardLink='multi-page-layout', svgPath='images/page-layout.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='scale-pages', cardTitle=#{home.scalePages.title}, cardText=#{home.scalePages.desc}, cardLink='scale-pages', svgPath='images/scale-pages.svg')}"></div> | ||||
|                  | ||||
|                  | ||||
| 
 | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='auto-rename', cardTitle=#{home.auto-rename.title}, cardText=#{home.auto-rename.desc}, cardLink='auto-rename', svgPath='images/fonts.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='auto-split-pdf', cardTitle=#{home.autoSplitPDF.title}, cardText=#{home.autoSplitPDF.desc}, cardLink='auto-split-pdf', svgPath='images/layout-split.svg')}"></div> | ||||
| 				<div th:replace="~{fragments/card :: card(id='sanitize-pdf', cardTitle=#{home.sanitizePdf.title}, cardText=#{home.sanitizePdf.desc}, cardLink='sanitize-pdf', svgPath='images/sanitize.svg')}"></div> | ||||
| 				 | ||||
| 				<div th:replace="~{fragments/card :: card(id='url-to-pdf', cardTitle=#{home.URLToPDF.title}, cardText=#{home.URLToPDF.desc}, cardLink='url-to-pdf', svgPath='images/url.svg')}"></div> | ||||
| 				<div th:replace="~{fragments/card :: card(id='html-to-pdf', cardTitle=#{home.HTMLToPDF.title}, cardText=#{home.HTMLToPDF.desc}, cardLink='html-to-pdf', svgPath='images/html.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='sanitize-pdf', cardTitle=#{home.sanitizePdf.title}, cardText=#{home.sanitizePdf.desc}, cardLink='sanitize-pdf', svgPath='images/sanitize.svg')}"></div> | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='url-to-pdf', cardTitle=#{home.URLToPDF.title}, cardText=#{home.URLToPDF.desc}, cardLink='url-to-pdf', svgPath='images/url.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='html-to-pdf', cardTitle=#{home.HTMLToPDF.title}, cardText=#{home.HTMLToPDF.desc}, cardLink='html-to-pdf', svgPath='images/html.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='markdown-to-pdf', cardTitle=#{home.MarkdownToPDF.title}, cardText=#{home.MarkdownToPDF.desc}, cardLink='markdown-to-pdf', svgPath='images/markdown.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='get-info-on-pdf', cardTitle=#{home.getPdfInfo.title}, cardText=#{home.getPdfInfo.desc}, cardLink='get-info-on-pdf', svgPath='images/info.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='extract-page', cardTitle=#{home.extractPage.title}, cardText=#{home.extractPage.desc}, cardLink='extract-page', svgPath='images/extract.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='pdf-to-single-page', cardTitle=#{home.PdfToSinglePage.title}, cardText=#{home.PdfToSinglePage.desc}, cardLink='pdf-to-single-page', svgPath='images/single-page.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='show-javascript', cardTitle=#{home.showJS.title}, cardText=#{home.showJS.desc}, cardLink='show-javascript', svgPath='images/js.svg')}"></div> | ||||
|                 <div th:replace="~{fragments/card :: card(id='auto-redact', cardTitle=#{home.autoRedact.title}, cardText=#{home.autoRedact.desc}, cardLink='auto-redact', svgPath='images/eraser-fill.svg')}"></div> | ||||
|                  | ||||
|                  | ||||
|                  | ||||
|                  | ||||
| 
 | ||||
|                 <div th:replace="~{fragments/card :: card(id='pdf-to-csv', cardTitle=#{home.tableExtraxt.title}, cardText=#{home.tableExtraxt.desc}, cardLink='pdf-to-csv', svgPath='images/pdf-csv.svg')}"></div> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|             </div> | ||||
|         </div> </div> | ||||
|         <div th:insert="~{fragments/footer.html :: footer}"></div> | ||||
|     </div> | ||||
|     <div th:insert="~{fragments/footer.html :: footer}"></div> | ||||
| </div> | ||||
| </body> | ||||
| 
 | ||||
| </html> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user