mirror of
https://github.com/alam00000/bentopdf.git
synced 2026-11-05 03:50:29 +01:00
chore: stop tracking generated build files, fix sponsors workflow and refresh README hero
This commit is contained in:
@@ -1,12 +1,30 @@
|
||||
name: Update Sponsors
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 6 * * 1'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'alam00000/bentopdf'
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: JamesIves/github-sponsors-readme-action@02650b8cd445fc16dfef73195f9c406dce041623 # v1.6.1
|
||||
with:
|
||||
token: ${{ secrets.SPONSORS_TOKEN }}
|
||||
file: 'README.md'
|
||||
file: 'README.md'
|
||||
active-only: false
|
||||
- uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
|
||||
with:
|
||||
commit-message: 'docs: update sponsors'
|
||||
title: 'docs: update sponsors'
|
||||
body: Updates the sponsors list in the README from GitHub Sponsors.
|
||||
branch: chore/update-sponsors
|
||||
delete-branch: true
|
||||
|
||||
@@ -54,3 +54,10 @@ test
|
||||
# Sibling checkouts of the engine/viewer forks
|
||||
bentopdf-pdfium-viewer/
|
||||
bentopdf-pymupdf-wasm/
|
||||
|
||||
/blog/*.html
|
||||
!/blog/author-alam.html
|
||||
/src/partials/tool-links-static.html
|
||||
/security-headers-docs.conf
|
||||
/dist-*.zip
|
||||
/docs/.vitepress/cache/
|
||||
|
||||
+2
-2
@@ -68,8 +68,8 @@ If/when you merge changes from the source BentoPDF repository, the build and dep
|
||||
|
||||
BentoPDF ships a Content-Security-Policy and other security headers for each static host:
|
||||
|
||||
- **Netlify and Cloudflare Pages** read `_headers` from the deployed folder. The build copies `public/_headers` into `dist/_headers`, and `scripts/generate-security-headers.mjs` regenerates both during `npm run build`, so any `VITE_WASM_*`, `VITE_TESSERACT_*`, `VITE_CORS_PROXY_URL` or `VITE_OCR_FONT_BASE_URL` values you set at build time are allowed by the policy. The release `dist-{version}.zip` already contains it.
|
||||
- **Vercel** uses the `headers` block in `vercel.json`. It holds the default policy, so if you point the `VITE_*` URLs at your own servers, update the Content-Security-Policy there to match `public/_headers`.
|
||||
- **Netlify and Cloudflare Pages** read `_headers` from the deployed folder. `npm run build` writes `dist/_headers` with `scripts/generate-security-headers.mjs`, so any `VITE_WASM_*`, `VITE_TESSERACT_*`, `VITE_CORS_PROXY_URL` or `VITE_OCR_FONT_BASE_URL` values you set at build time are allowed by the policy. If you add your own `public/_headers`, the build ships yours instead. The release `dist-{version}.zip` already contains it.
|
||||
- **Vercel** uses the `headers` block in `vercel.json`. It holds the default policy, so if you point the `VITE_*` URLs at your own servers, update the Content-Security-Policy there to match the `dist/_headers` your build produces.
|
||||
- **`npx serve`** reads `serve.json` from the folder it serves. To use the repository's `serve.json` with the build output, run `npx serve dist -c ../serve.json`.
|
||||
- **GitHub Pages** cannot set headers (see the note above).
|
||||
|
||||
|
||||
@@ -1,473 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>
|
||||
How to Edit a PDF Without Uploading It Anywhere | BentoPDF Blog
|
||||
</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Edit PDF text, fill forms, redact, and sign in your browser while the file stays on your device. Step by step, with the right tool for each job."
|
||||
/>
|
||||
<meta name="robots" content="index, follow, max-image-preview:large" />
|
||||
<link
|
||||
rel="canonical"
|
||||
href="https://www.bentopdf.com/blog/edit-pdf-without-uploading"
|
||||
/>
|
||||
<meta property="og:type" content="article" />
|
||||
<meta
|
||||
property="og:url"
|
||||
content="https://www.bentopdf.com/blog/edit-pdf-without-uploading"
|
||||
/>
|
||||
<meta
|
||||
property="og:title"
|
||||
content="How to Edit a PDF Without Uploading It Anywhere"
|
||||
/>
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Edit PDF text, fill forms, redact, and sign in your browser while the file stays on your device. Step by step, with the right tool for each job."
|
||||
/>
|
||||
<meta
|
||||
property="og:image"
|
||||
content="https://www.bentopdf.com/images/og-tools.png"
|
||||
/>
|
||||
<meta property="og:site_name" content="BentoPDF" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<link rel="icon" type="image/svg+xml" href="/images/favicon.svg" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="32x32" />
|
||||
<link href="/src/css/styles.css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body class="antialiased bg-gray-900">
|
||||
{{> navbar }}
|
||||
|
||||
<article class="max-w-3xl mx-auto px-4 py-12">
|
||||
<nav
|
||||
class="flex items-center gap-2 text-sm text-gray-400 mb-6"
|
||||
aria-label="Breadcrumb"
|
||||
>
|
||||
<a href="/blog" class="hover:text-indigo-300">Blog</a>
|
||||
<i class="ph ph-caret-right text-xs" aria-hidden="true"></i>
|
||||
<span class="text-gray-300">Edit a PDF without uploading</span>
|
||||
</nav>
|
||||
|
||||
<h1 class="text-3xl md:text-4xl font-bold text-white mb-4 leading-tight">
|
||||
How to edit a PDF without uploading it anywhere
|
||||
</h1>
|
||||
|
||||
<div class="flex items-center gap-3 mb-10 text-sm text-gray-400">
|
||||
<img
|
||||
src="/images/author-alam.jpg"
|
||||
alt="Alam"
|
||||
width="40"
|
||||
height="40"
|
||||
class="rounded-full"
|
||||
/>
|
||||
<div>
|
||||
<a
|
||||
href="/blog/author-alam"
|
||||
class="text-gray-200 font-semibold hover:text-indigo-300"
|
||||
>Alam</a
|
||||
>, builds BentoPDF ·
|
||||
<time datetime="2026-09-03">September 3, 2026</time>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
You can edit a PDF in your browser without uploading the file to a
|
||||
server.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
Open
|
||||
<a class="text-indigo-300 hover:text-indigo-400" href="/edit-pdf"
|
||||
>BentoPDF's PDF editor</a
|
||||
>, pick your file, make your changes, and download the result. The PDF
|
||||
stays on your device. There's no account and no watermark.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
But “edit a PDF” can mean a few different things. You might want to
|
||||
change existing text, fill out a form, add a signature, redact
|
||||
something, or just highlight a paragraph. The right tool depends on what
|
||||
you're trying to do.
|
||||
</p>
|
||||
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
|
||||
Why edit a PDF without uploading it?
|
||||
</h2>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
Think about the PDFs you normally edit.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
Contracts. Bank statements. Tax documents. Forms with your address or ID
|
||||
number.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
Those aren't necessarily files you want to upload to a random “free
|
||||
PDF editor.”
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
With an on-device PDF editor, the file stays on your computer while
|
||||
you're working on it.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
You can even check this yourself. Open your browser's developer
|
||||
tools, go to the Network tab, and watch what happens while you edit. The
|
||||
PDF itself doesn't need to be sent to a server.
|
||||
</p>
|
||||
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
|
||||
How to edit the actual text in a PDF
|
||||
</h2>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
If you want to change words that are already in the PDF, use
|
||||
<a class="text-indigo-300 hover:text-indigo-400" href="/edit-pdf-text"
|
||||
>Edit PDF Text</a
|
||||
>.
|
||||
</p>
|
||||
<ol
|
||||
class="list-decimal list-inside text-gray-300 leading-relaxed mb-5 space-y-2"
|
||||
>
|
||||
<li>Open the tool.</li>
|
||||
<li>Drop in your PDF.</li>
|
||||
<li>Click on the text you want to change.</li>
|
||||
<li>Type your changes.</li>
|
||||
<li>Download the edited PDF.</li>
|
||||
</ol>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
BentoPDF loads the PDF in your browser and does the editing on your
|
||||
device.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
This is one of the harder things to do with PDFs because PDF text
|
||||
doesn't work quite like text in a Word document. The PDF is mostly
|
||||
concerned with putting things at particular positions on a page, so
|
||||
changing a sentence can mean figuring out how the surrounding text
|
||||
should move.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
It works well for ordinary documents, but PDFs with unusual embedded
|
||||
fonts or very complicated layouts can be trickier. I'd always open
|
||||
the downloaded PDF and check it.
|
||||
</p>
|
||||
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
|
||||
How to annotate a PDF
|
||||
</h2>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
If you don't need to change the existing text, annotating a PDF is
|
||||
much simpler.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
The
|
||||
<a class="text-indigo-300 hover:text-indigo-400" href="/edit-pdf"
|
||||
>PDF editor</a
|
||||
>
|
||||
lets you add highlights, comments, shapes, stamps, text boxes, and
|
||||
images.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
Open the PDF, add your annotations, and download the result.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
Again, the editing happens in your browser rather than on a remote
|
||||
server.
|
||||
</p>
|
||||
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
|
||||
How to fill out a PDF form
|
||||
</h2>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
There are two common kinds of PDF forms.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
If the PDF has actual form fields, open it in
|
||||
<a class="text-indigo-300 hover:text-indigo-400" href="/form-filler"
|
||||
>PDF Form Filler</a
|
||||
>
|
||||
and type into the fields. It handles standard AcroForm fields, and also
|
||||
XFA forms, which are the legacy XML-based format. XFA is worth calling
|
||||
out because Chrome and most other viewers show those files as blank
|
||||
pages, which is why some government forms tell you to open them in Adobe
|
||||
Reader. Firefox and BentoPDF's form filler render them properly.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
If it's a scanned or flattened form, there aren't any fields to
|
||||
click. In that case, you can put text boxes over the blank spaces in the
|
||||
<a class="text-indigo-300 hover:text-indigo-400" href="/edit-pdf"
|
||||
>PDF editor</a
|
||||
>
|
||||
and type into them. If you'd rather have real fields,
|
||||
<a class="text-indigo-300 hover:text-indigo-400" href="/form-creator"
|
||||
>Create PDF Form</a
|
||||
>
|
||||
can add them to the document first.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
This is especially useful for government and HR forms, which often
|
||||
contain personal information I'd rather not upload somewhere just to
|
||||
fill in a few boxes.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
If the PDF is a scan and you actually need to edit the scanned text
|
||||
itself, you'll need OCR first.
|
||||
<a class="text-indigo-300 hover:text-indigo-400" href="/ocr-pdf"
|
||||
>BentoPDF's OCR tool</a
|
||||
>
|
||||
can recognize the text in the document while keeping the processing on
|
||||
your device.
|
||||
</p>
|
||||
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
|
||||
How to redact a PDF properly
|
||||
</h2>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
This one is important because putting a black box over text isn't
|
||||
necessarily redaction.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
If you draw a rectangle over a name, the original name may still exist
|
||||
underneath it. It might still be selectable, searchable, or extractable.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
Proper redaction removes the underlying content.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
The
|
||||
<a class="text-indigo-300 hover:text-indigo-400" href="/edit-pdf"
|
||||
>PDF editor</a
|
||||
>
|
||||
has redaction tools that permanently remove the underlying content
|
||||
rather than drawing over it. For documents where you also want to strip
|
||||
metadata or other hidden content,
|
||||
<a class="text-indigo-300 hover:text-indigo-400" href="/sanitize-pdf"
|
||||
>Sanitize PDF</a
|
||||
>
|
||||
can help with that.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
There's also a privacy reason to do redaction locally: if you upload
|
||||
the original, unredacted PDF to a redaction service, that service has
|
||||
already received the information you're trying to hide.
|
||||
</p>
|
||||
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
|
||||
How to sign a PDF without uploading it
|
||||
</h2>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
<a class="text-indigo-300 hover:text-indigo-400" href="/sign-pdf"
|
||||
>Sign PDF</a
|
||||
>
|
||||
lets you add a drawn, typed, or image signature to a PDF. Place it on
|
||||
the page, resize it, and optionally flatten it so it becomes part of the
|
||||
page instead of an annotation someone can drag away later.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
The signature is added on your device, so you don't need to upload
|
||||
the document to a signing service just to place a signature on it.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
One thing to keep in mind: adding a signature image to a PDF is not the
|
||||
same thing as applying a cryptographic digital signature. If the
|
||||
recipient needs a signature that can actually be verified, use
|
||||
<a
|
||||
class="text-indigo-300 hover:text-indigo-400"
|
||||
href="/digital-sign-pdf"
|
||||
>Digital Signature</a
|
||||
>
|
||||
instead. It signs the document with an X.509 certificate (PKCS#12 .pfx
|
||||
and .p12, or PEM), which proves who signed it and shows whether anything
|
||||
changed afterwards. You can also add a visible signature block on top of
|
||||
that. The certificate password and private key stay in your browser,
|
||||
same as the PDF.
|
||||
</p>
|
||||
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
|
||||
Can you edit a PDF offline?
|
||||
</h2>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">Yes.</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
There's an easy way to test it: load the editor, turn off Wi-Fi, and
|
||||
edit a PDF.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
The PDF processing code runs in your browser using WebAssembly. Once the
|
||||
application has loaded, the actual PDF processing doesn't need a
|
||||
server.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
This is also something you can inspect yourself in your browser's
|
||||
developer tools. The website is how you get the software; it doesn't
|
||||
have to be where your PDF gets processed.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
If you want to run the whole thing yourself, BentoPDF is
|
||||
<a
|
||||
rel="noopener"
|
||||
class="text-indigo-300 hover:text-indigo-400"
|
||||
href="https://github.com/alam00000/bentopdf"
|
||||
>open source and self-hostable</a
|
||||
>. You can run your own instance instead of relying on ours.
|
||||
</p>
|
||||
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
|
||||
What about scanned PDFs?
|
||||
</h2>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
A scanned PDF is basically a collection of images.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
If you want to change the words in it, an ordinary PDF text editor
|
||||
can't simply edit them because there isn't any text there yet.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
You'll need OCR (optical character recognition) to turn the pixels
|
||||
into text.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
You can either OCR the PDF first and then edit the resulting text, or,
|
||||
if you're just filling out a scanned form, put text boxes on top of
|
||||
the existing page.
|
||||
</p>
|
||||
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
|
||||
Is there a file size limit?
|
||||
</h2>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
There isn't an imposed file-size limit.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
The practical limit is your device's available memory. Normal PDFs
|
||||
are usually fine, but a thousand-page scanned archive is a very
|
||||
different workload from a five-page contract.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
For very large PDFs, a desktop application may be a better choice.
|
||||
</p>
|
||||
<h2 class="text-2xl font-bold text-white mt-10 mb-4">
|
||||
Will editing a digitally signed PDF break the signature?
|
||||
</h2>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">Yes.</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
Changing a digitally signed PDF will invalidate its existing signature.
|
||||
This isn't specific to BentoPDF; it's a consequence of changing
|
||||
a document that has already been signed.
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">So the usual order is:</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
<strong>Edit first. Sign last.</strong>
|
||||
</p>
|
||||
<p class="text-gray-300 leading-relaxed mb-5">
|
||||
If you need to make changes to a signed document, make sure you
|
||||
understand the signature requirements before doing so.
|
||||
</p>
|
||||
|
||||
<div class="bg-gray-800 border border-gray-700 rounded-xl p-6 my-10">
|
||||
<p class="text-white font-semibold mb-2">Edit your PDF now</p>
|
||||
<p class="text-gray-400 mb-4">
|
||||
Free, no signup. Your file stays on your device.
|
||||
</p>
|
||||
<a
|
||||
href="/edit-pdf"
|
||||
class="inline-block bg-indigo-600 hover:bg-indigo-700 text-white font-semibold px-5 py-2.5 rounded-lg"
|
||||
>Open the PDF editor</a
|
||||
>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
{{> footer }}
|
||||
<script type="module" src="/src/js/utils/lucide-init.ts"></script>
|
||||
<script type="module" src="/src/js/mobileMenu.ts"></script>
|
||||
<script type="module">
|
||||
import '@phosphor-icons/web/regular';
|
||||
</script>
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
"headline": "How to edit a PDF without uploading it anywhere",
|
||||
"description": "Edit PDF text, fill forms, redact, and sign in your browser while the file stays on your device. Step by step, with the right tool for each job.",
|
||||
"url": "https://www.bentopdf.com/blog/edit-pdf-without-uploading",
|
||||
"datePublished": "2026-09-03",
|
||||
"dateModified": "2026-09-03",
|
||||
"image": "https://www.bentopdf.com/images/og-tools.png",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "Alam",
|
||||
"url": "https://www.bentopdf.com/blog/author-alam",
|
||||
"sameAs": [
|
||||
"https://github.com/alam00000",
|
||||
"https://www.linkedin.com/in/abdullah-alam01/",
|
||||
"https://x.com/alamdraws"
|
||||
]
|
||||
},
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "BentoPDF",
|
||||
"url": "https://www.bentopdf.com"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 1,
|
||||
"name": "Blog",
|
||||
"item": "https://www.bentopdf.com/blog/"
|
||||
},
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 2,
|
||||
"name": "Edit a PDF without uploading",
|
||||
"item": "https://www.bentopdf.com/blog/edit-pdf-without-uploading"
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Why edit a PDF without uploading it?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Think about the PDFs you normally edit. Contracts. Bank statements. Tax documents. Forms with your address or ID number. Those aren't necessarily files you want to upload to a random “free PDF editor.” With an on-device PDF editor, the file stays on your computer while you're working on it. You can even check this yourself. Open your browser's developer tools, go to the Network tab, and watch what happens while you edit. The PDF itself doesn't need to be sent to a server."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Can you edit a PDF offline?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Yes. There's an easy way to test it: load the editor, turn off Wi-Fi, and edit a PDF. The PDF processing code runs in your browser using WebAssembly. Once the application has loaded, the actual PDF processing doesn't need a server. This is also something you can inspect yourself in your browser's developer tools. The website is how you get the software; it doesn't have to be where your PDF gets processed. If you want to run the whole thing yourself, BentoPDF is open source and self-hostable. You can run your own instance instead of relying on ours."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "What about scanned PDFs?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "A scanned PDF is basically a collection of images. If you want to change the words in it, an ordinary PDF text editor can't simply edit them because there isn't any text there yet. You'll need OCR (optical character recognition) to turn the pixels into text. You can either OCR the PDF first and then edit the resulting text, or, if you're just filling out a scanned form, put text boxes on top of the existing page."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Is there a file size limit?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "There isn't an imposed file-size limit. The practical limit is your device's available memory. Normal PDFs are usually fine, but a thousand-page scanned archive is a very different workload from a five-page contract. For very large PDFs, a desktop application may be a better choice."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Will editing a digitally signed PDF break the signature?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Yes. Changing a digitally signed PDF will invalidate its existing signature. This isn't specific to BentoPDF; it's a consequence of changing a document that has already been signed. So the usual order is: Edit first. Sign last. If you need to make changes to a signed document, make sure you understand the signature requirements before doing so."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,87 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>The BentoPDF Blog | Privacy-First PDF Guides</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Guides and honest comparisons from the maintainer of BentoPDF: how PDF tools handle your files, and how to get things done without uploading them."
|
||||
/>
|
||||
<meta name="robots" content="index, follow, max-image-preview:large" />
|
||||
<link rel="canonical" href="https://www.bentopdf.com/blog/" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://www.bentopdf.com/blog/" />
|
||||
<meta property="og:title" content="The BentoPDF Blog" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Guides and honest comparisons from the maintainer of BentoPDF."
|
||||
/>
|
||||
<meta
|
||||
property="og:image"
|
||||
content="https://www.bentopdf.com/images/og-tools.png"
|
||||
/>
|
||||
<meta property="og:site_name" content="BentoPDF" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<link rel="icon" type="image/svg+xml" href="/images/favicon.svg" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="32x32" />
|
||||
<link href="/src/css/styles.css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body class="antialiased bg-gray-900">
|
||||
{{> navbar }}
|
||||
|
||||
<section class="max-w-3xl mx-auto px-4 py-12">
|
||||
<h1 class="text-3xl md:text-4xl font-bold text-white mb-4">
|
||||
The BentoPDF Blog
|
||||
</h1>
|
||||
<p class="text-gray-300 leading-relaxed mb-2">
|
||||
I'm
|
||||
<a
|
||||
href="/blog/author-alam"
|
||||
class="text-indigo-300 hover:text-indigo-400"
|
||||
>Alam</a
|
||||
>. I build BentoPDF and write about PDFs, how they work, and the weird
|
||||
things I run into along the way.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="max-w-3xl mx-auto px-4 pb-16">
|
||||
<div class="space-y-6">
|
||||
<a
|
||||
href="/blog/edit-pdf-without-uploading"
|
||||
class="block bg-gray-800 border border-gray-700 rounded-xl p-6 hover:border-indigo-500 transition-colors"
|
||||
>
|
||||
<h2 class="text-xl font-bold text-white mb-2">
|
||||
How to edit a PDF without uploading it anywhere
|
||||
</h2>
|
||||
<p class="text-gray-400 mb-3">
|
||||
Rewrite text, fill forms, redact properly, and sign, locally on your
|
||||
device.
|
||||
</p>
|
||||
<span class="text-sm text-gray-500">September 3, 2026</span>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{> footer }}
|
||||
<script type="module" src="/src/js/utils/lucide-init.ts"></script>
|
||||
<script type="module" src="/src/js/mobileMenu.ts"></script>
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Blog",
|
||||
"name": "The BentoPDF Blog",
|
||||
"url": "https://www.bentopdf.com/blog/",
|
||||
"description": "Guides and honest comparisons from the maintainer of BentoPDF.",
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "BentoPDF",
|
||||
"url": "https://www.bentopdf.com"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
-283
@@ -1,283 +0,0 @@
|
||||
import { useMediaQuery } from './chunk-BRNHR3LR.js';
|
||||
import { computed, ref, shallowRef, watch } from './chunk-H6MPEGKE.js';
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/index.js
|
||||
import '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/styles/fonts.css';
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/without-fonts.js
|
||||
import '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/styles/vars.css';
|
||||
import '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/styles/base.css';
|
||||
import '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/styles/icons.css';
|
||||
import '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/styles/utils.css';
|
||||
import '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/styles/components/custom-block.css';
|
||||
import '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code.css';
|
||||
import '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/styles/components/vp-code-group.css';
|
||||
import '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/styles/components/vp-doc.css';
|
||||
import '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/styles/components/vp-sponsor.css';
|
||||
import VPBadge from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue';
|
||||
import Layout from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/Layout.vue';
|
||||
import { default as default2 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPBadge.vue';
|
||||
import { default as default3 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPButton.vue';
|
||||
import { default as default4 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPDocAsideSponsors.vue';
|
||||
import { default as default5 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPFeatures.vue';
|
||||
import { default as default6 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPHomeContent.vue';
|
||||
import { default as default7 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPHomeFeatures.vue';
|
||||
import { default as default8 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPHomeHero.vue';
|
||||
import { default as default9 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPHomeSponsors.vue';
|
||||
import { default as default10 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPImage.vue';
|
||||
import { default as default11 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPLink.vue';
|
||||
import { default as default12 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPNavBarSearch.vue';
|
||||
import { default as default13 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPSocialLink.vue';
|
||||
import { default as default14 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPSocialLinks.vue';
|
||||
import { default as default15 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPSponsors.vue';
|
||||
import { default as default16 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPTeamMembers.vue';
|
||||
import { default as default17 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPTeamPage.vue';
|
||||
import { default as default18 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageSection.vue';
|
||||
import { default as default19 } from '/Users/abdullahtapadar/Desktop/bento-pdf/node_modules/vitepress/dist/client/theme-default/components/VPTeamPageTitle.vue';
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/local-nav.js
|
||||
import { onContentUpdated } from 'vitepress';
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/outline.js
|
||||
import { getScrollOffset } from 'vitepress';
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/support/utils.js
|
||||
import { withBase } from 'vitepress';
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/data.js
|
||||
import { useData as useData$ } from 'vitepress';
|
||||
var useData = useData$;
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/support/utils.js
|
||||
function ensureStartingSlash(path) {
|
||||
return path.startsWith('/') ? path : `/${path}`;
|
||||
}
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/support/sidebar.js
|
||||
function getSidebar(_sidebar, path) {
|
||||
if (Array.isArray(_sidebar)) return addBase(_sidebar);
|
||||
if (_sidebar == null) return [];
|
||||
path = ensureStartingSlash(path);
|
||||
const dir = Object.keys(_sidebar)
|
||||
.sort((a, b) => {
|
||||
return b.split('/').length - a.split('/').length;
|
||||
})
|
||||
.find((dir2) => {
|
||||
return path.startsWith(ensureStartingSlash(dir2));
|
||||
});
|
||||
const sidebar = dir ? _sidebar[dir] : [];
|
||||
return Array.isArray(sidebar)
|
||||
? addBase(sidebar)
|
||||
: addBase(sidebar.items, sidebar.base);
|
||||
}
|
||||
function getSidebarGroups(sidebar) {
|
||||
const groups = [];
|
||||
let lastGroupIndex = 0;
|
||||
for (const index in sidebar) {
|
||||
const item = sidebar[index];
|
||||
if (item.items) {
|
||||
lastGroupIndex = groups.push(item);
|
||||
continue;
|
||||
}
|
||||
if (!groups[lastGroupIndex]) {
|
||||
groups.push({ items: [] });
|
||||
}
|
||||
groups[lastGroupIndex].items.push(item);
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
function addBase(items, _base) {
|
||||
return [...items].map((_item) => {
|
||||
const item = { ..._item };
|
||||
const base = item.base || _base;
|
||||
if (base && item.link) item.link = base + item.link;
|
||||
if (item.items) item.items = addBase(item.items, base);
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/sidebar.js
|
||||
function useSidebar() {
|
||||
const { frontmatter, page, theme: theme2 } = useData();
|
||||
const is960 = useMediaQuery('(min-width: 960px)');
|
||||
const isOpen = ref(false);
|
||||
const _sidebar = computed(() => {
|
||||
const sidebarConfig = theme2.value.sidebar;
|
||||
const relativePath = page.value.relativePath;
|
||||
return sidebarConfig ? getSidebar(sidebarConfig, relativePath) : [];
|
||||
});
|
||||
const sidebar = ref(_sidebar.value);
|
||||
watch(_sidebar, (next, prev) => {
|
||||
if (JSON.stringify(next) !== JSON.stringify(prev))
|
||||
sidebar.value = _sidebar.value;
|
||||
});
|
||||
const hasSidebar = computed(() => {
|
||||
return (
|
||||
frontmatter.value.sidebar !== false &&
|
||||
sidebar.value.length > 0 &&
|
||||
frontmatter.value.layout !== 'home'
|
||||
);
|
||||
});
|
||||
const leftAside = computed(() => {
|
||||
if (hasAside)
|
||||
return frontmatter.value.aside == null
|
||||
? theme2.value.aside === 'left'
|
||||
: frontmatter.value.aside === 'left';
|
||||
return false;
|
||||
});
|
||||
const hasAside = computed(() => {
|
||||
if (frontmatter.value.layout === 'home') return false;
|
||||
if (frontmatter.value.aside != null) return !!frontmatter.value.aside;
|
||||
return theme2.value.aside !== false;
|
||||
});
|
||||
const isSidebarEnabled = computed(() => hasSidebar.value && is960.value);
|
||||
const sidebarGroups = computed(() => {
|
||||
return hasSidebar.value ? getSidebarGroups(sidebar.value) : [];
|
||||
});
|
||||
function open() {
|
||||
isOpen.value = true;
|
||||
}
|
||||
function close() {
|
||||
isOpen.value = false;
|
||||
}
|
||||
function toggle() {
|
||||
isOpen.value ? close() : open();
|
||||
}
|
||||
return {
|
||||
isOpen,
|
||||
sidebar,
|
||||
sidebarGroups,
|
||||
hasSidebar,
|
||||
hasAside,
|
||||
leftAside,
|
||||
isSidebarEnabled,
|
||||
open,
|
||||
close,
|
||||
toggle,
|
||||
};
|
||||
}
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/outline.js
|
||||
var ignoreRE = /\b(?:VPBadge|header-anchor|footnote-ref|ignore-header)\b/;
|
||||
var resolvedHeaders = [];
|
||||
function getHeaders(range) {
|
||||
const headers = [
|
||||
...document.querySelectorAll('.VPDoc :where(h1,h2,h3,h4,h5,h6)'),
|
||||
]
|
||||
.filter((el) => el.id && el.hasChildNodes())
|
||||
.map((el) => {
|
||||
const level = Number(el.tagName[1]);
|
||||
return {
|
||||
element: el,
|
||||
title: serializeHeader(el),
|
||||
link: '#' + el.id,
|
||||
level,
|
||||
};
|
||||
});
|
||||
return resolveHeaders(headers, range);
|
||||
}
|
||||
function serializeHeader(h) {
|
||||
let ret = '';
|
||||
for (const node of h.childNodes) {
|
||||
if (node.nodeType === 1) {
|
||||
if (ignoreRE.test(node.className)) continue;
|
||||
ret += node.textContent;
|
||||
} else if (node.nodeType === 3) {
|
||||
ret += node.textContent;
|
||||
}
|
||||
}
|
||||
return ret.trim();
|
||||
}
|
||||
function resolveHeaders(headers, range) {
|
||||
if (range === false) {
|
||||
return [];
|
||||
}
|
||||
const levelsRange =
|
||||
(typeof range === 'object' && !Array.isArray(range)
|
||||
? range.level
|
||||
: range) || 2;
|
||||
const [high, low] =
|
||||
typeof levelsRange === 'number'
|
||||
? [levelsRange, levelsRange]
|
||||
: levelsRange === 'deep'
|
||||
? [2, 6]
|
||||
: levelsRange;
|
||||
return buildTree(headers, high, low);
|
||||
}
|
||||
function buildTree(data, min, max) {
|
||||
resolvedHeaders.length = 0;
|
||||
const result = [];
|
||||
const stack = [];
|
||||
data.forEach((item) => {
|
||||
const node = { ...item, children: [] };
|
||||
let parent = stack[stack.length - 1];
|
||||
while (parent && parent.level >= node.level) {
|
||||
stack.pop();
|
||||
parent = stack[stack.length - 1];
|
||||
}
|
||||
if (
|
||||
node.element.classList.contains('ignore-header') ||
|
||||
(parent && 'shouldIgnore' in parent)
|
||||
) {
|
||||
stack.push({ level: node.level, shouldIgnore: true });
|
||||
return;
|
||||
}
|
||||
if (node.level > max || node.level < min) return;
|
||||
resolvedHeaders.push({ element: node.element, link: node.link });
|
||||
if (parent) parent.children.push(node);
|
||||
else result.push(node);
|
||||
stack.push(node);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/composables/local-nav.js
|
||||
function useLocalNav() {
|
||||
const { theme: theme2, frontmatter } = useData();
|
||||
const headers = shallowRef([]);
|
||||
const hasLocalNav = computed(() => {
|
||||
return headers.value.length > 0;
|
||||
});
|
||||
onContentUpdated(() => {
|
||||
headers.value = getHeaders(
|
||||
frontmatter.value.outline ?? theme2.value.outline
|
||||
);
|
||||
});
|
||||
return {
|
||||
headers,
|
||||
hasLocalNav,
|
||||
};
|
||||
}
|
||||
|
||||
// node_modules/vitepress/dist/client/theme-default/without-fonts.js
|
||||
var theme = {
|
||||
Layout,
|
||||
enhanceApp: ({ app }) => {
|
||||
app.component('Badge', VPBadge);
|
||||
},
|
||||
};
|
||||
var without_fonts_default = theme;
|
||||
export {
|
||||
default2 as VPBadge,
|
||||
default3 as VPButton,
|
||||
default4 as VPDocAsideSponsors,
|
||||
default5 as VPFeatures,
|
||||
default6 as VPHomeContent,
|
||||
default7 as VPHomeFeatures,
|
||||
default8 as VPHomeHero,
|
||||
default9 as VPHomeSponsors,
|
||||
default10 as VPImage,
|
||||
default11 as VPLink,
|
||||
default12 as VPNavBarSearch,
|
||||
default13 as VPSocialLink,
|
||||
default14 as VPSocialLinks,
|
||||
default15 as VPSponsors,
|
||||
default16 as VPTeamMembers,
|
||||
default17 as VPTeamPage,
|
||||
default18 as VPTeamPageSection,
|
||||
default19 as VPTeamPageTitle,
|
||||
without_fonts_default as default,
|
||||
useLocalNav,
|
||||
useSidebar,
|
||||
};
|
||||
//# sourceMappingURL=@theme_index.js.map
|
||||
File diff suppressed because one or more lines are too long
-58
@@ -1,58 +0,0 @@
|
||||
{
|
||||
"hash": "cbe76ac1",
|
||||
"configHash": "fcacb6fc",
|
||||
"lockfileHash": "25b6b516",
|
||||
"browserHash": "e3bcae4a",
|
||||
"optimized": {
|
||||
"vue": {
|
||||
"src": "../../../../node_modules/vue/dist/vue.runtime.esm-bundler.js",
|
||||
"file": "vue.js",
|
||||
"fileHash": "d430f9d5",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vitepress > @vue/devtools-api": {
|
||||
"src": "../../../../node_modules/@vue/devtools-api/dist/index.js",
|
||||
"file": "vitepress___@vue_devtools-api.js",
|
||||
"fileHash": "cdc3240f",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vitepress > @vueuse/core": {
|
||||
"src": "../../../../node_modules/@vueuse/core/index.mjs",
|
||||
"file": "vitepress___@vueuse_core.js",
|
||||
"fileHash": "9c54fae4",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vitepress > @vueuse/integrations/useFocusTrap": {
|
||||
"src": "../../../../node_modules/@vueuse/integrations/useFocusTrap.mjs",
|
||||
"file": "vitepress___@vueuse_integrations_useFocusTrap.js",
|
||||
"fileHash": "dcb2d016",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vitepress > mark.js/src/vanilla.js": {
|
||||
"src": "../../../../node_modules/mark.js/src/vanilla.js",
|
||||
"file": "vitepress___mark__js_src_vanilla__js.js",
|
||||
"fileHash": "89ac005f",
|
||||
"needsInterop": false
|
||||
},
|
||||
"vitepress > minisearch": {
|
||||
"src": "../../../../node_modules/minisearch/dist/es/index.js",
|
||||
"file": "vitepress___minisearch.js",
|
||||
"fileHash": "dcc8fa95",
|
||||
"needsInterop": false
|
||||
},
|
||||
"@theme/index": {
|
||||
"src": "../../../../node_modules/vitepress/dist/client/theme-default/index.js",
|
||||
"file": "@theme_index.js",
|
||||
"fileHash": "12a406fc",
|
||||
"needsInterop": false
|
||||
}
|
||||
},
|
||||
"chunks": {
|
||||
"chunk-BRNHR3LR": {
|
||||
"file": "chunk-BRNHR3LR.js"
|
||||
},
|
||||
"chunk-H6MPEGKE": {
|
||||
"file": "chunk-H6MPEGKE.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
-10696
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
-13806
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
-3
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,583 +0,0 @@
|
||||
import {
|
||||
DefaultMagicKeysAliasMap,
|
||||
StorageSerializers,
|
||||
TransitionPresets,
|
||||
assert,
|
||||
breakpointsAntDesign,
|
||||
breakpointsBootstrapV5,
|
||||
breakpointsElement,
|
||||
breakpointsMasterCss,
|
||||
breakpointsPrimeFlex,
|
||||
breakpointsQuasar,
|
||||
breakpointsSematic,
|
||||
breakpointsTailwind,
|
||||
breakpointsVuetify,
|
||||
breakpointsVuetifyV2,
|
||||
breakpointsVuetifyV3,
|
||||
bypassFilter,
|
||||
camelize,
|
||||
clamp,
|
||||
cloneFnJSON,
|
||||
computedAsync,
|
||||
computedEager,
|
||||
computedInject,
|
||||
computedWithControl,
|
||||
containsProp,
|
||||
controlledRef,
|
||||
createEventHook,
|
||||
createFetch,
|
||||
createFilterWrapper,
|
||||
createGlobalState,
|
||||
createInjectionState,
|
||||
createRef,
|
||||
createReusableTemplate,
|
||||
createSharedComposable,
|
||||
createSingletonPromise,
|
||||
createTemplatePromise,
|
||||
createUnrefFn,
|
||||
customStorageEventName,
|
||||
debounceFilter,
|
||||
defaultDocument,
|
||||
defaultLocation,
|
||||
defaultNavigator,
|
||||
defaultWindow,
|
||||
executeTransition,
|
||||
extendRef,
|
||||
formatDate,
|
||||
formatTimeAgo,
|
||||
get,
|
||||
getLifeCycleTarget,
|
||||
getSSRHandler,
|
||||
hasOwn,
|
||||
hyphenate,
|
||||
identity,
|
||||
increaseWithUnit,
|
||||
injectLocal,
|
||||
invoke,
|
||||
isClient,
|
||||
isDef,
|
||||
isDefined,
|
||||
isIOS,
|
||||
isObject,
|
||||
isWorker,
|
||||
makeDestructurable,
|
||||
mapGamepadToXbox360Controller,
|
||||
noop,
|
||||
normalizeDate,
|
||||
notNullish,
|
||||
now,
|
||||
objectEntries,
|
||||
objectOmit,
|
||||
objectPick,
|
||||
onClickOutside,
|
||||
onElementRemoval,
|
||||
onKeyDown,
|
||||
onKeyPressed,
|
||||
onKeyStroke,
|
||||
onKeyUp,
|
||||
onLongPress,
|
||||
onStartTyping,
|
||||
pausableFilter,
|
||||
promiseTimeout,
|
||||
provideLocal,
|
||||
provideSSRWidth,
|
||||
pxValue,
|
||||
rand,
|
||||
reactify,
|
||||
reactifyObject,
|
||||
reactiveComputed,
|
||||
reactiveOmit,
|
||||
reactivePick,
|
||||
refAutoReset,
|
||||
refDebounced,
|
||||
refDefault,
|
||||
refThrottled,
|
||||
refWithControl,
|
||||
resolveRef,
|
||||
resolveUnref,
|
||||
set,
|
||||
setSSRHandler,
|
||||
syncRef,
|
||||
syncRefs,
|
||||
templateRef,
|
||||
throttleFilter,
|
||||
timestamp,
|
||||
toArray,
|
||||
toReactive,
|
||||
toRef,
|
||||
toRefs,
|
||||
toValue,
|
||||
tryOnBeforeMount,
|
||||
tryOnBeforeUnmount,
|
||||
tryOnMounted,
|
||||
tryOnScopeDispose,
|
||||
tryOnUnmounted,
|
||||
unrefElement,
|
||||
until,
|
||||
useActiveElement,
|
||||
useAnimate,
|
||||
useArrayDifference,
|
||||
useArrayEvery,
|
||||
useArrayFilter,
|
||||
useArrayFind,
|
||||
useArrayFindIndex,
|
||||
useArrayFindLast,
|
||||
useArrayIncludes,
|
||||
useArrayJoin,
|
||||
useArrayMap,
|
||||
useArrayReduce,
|
||||
useArraySome,
|
||||
useArrayUnique,
|
||||
useAsyncQueue,
|
||||
useAsyncState,
|
||||
useBase64,
|
||||
useBattery,
|
||||
useBluetooth,
|
||||
useBreakpoints,
|
||||
useBroadcastChannel,
|
||||
useBrowserLocation,
|
||||
useCached,
|
||||
useClipboard,
|
||||
useClipboardItems,
|
||||
useCloned,
|
||||
useColorMode,
|
||||
useConfirmDialog,
|
||||
useCountdown,
|
||||
useCounter,
|
||||
useCssVar,
|
||||
useCurrentElement,
|
||||
useCycleList,
|
||||
useDark,
|
||||
useDateFormat,
|
||||
useDebounceFn,
|
||||
useDebouncedRefHistory,
|
||||
useDeviceMotion,
|
||||
useDeviceOrientation,
|
||||
useDevicePixelRatio,
|
||||
useDevicesList,
|
||||
useDisplayMedia,
|
||||
useDocumentVisibility,
|
||||
useDraggable,
|
||||
useDropZone,
|
||||
useElementBounding,
|
||||
useElementByPoint,
|
||||
useElementHover,
|
||||
useElementSize,
|
||||
useElementVisibility,
|
||||
useEventBus,
|
||||
useEventListener,
|
||||
useEventSource,
|
||||
useEyeDropper,
|
||||
useFavicon,
|
||||
useFetch,
|
||||
useFileDialog,
|
||||
useFileSystemAccess,
|
||||
useFocus,
|
||||
useFocusWithin,
|
||||
useFps,
|
||||
useFullscreen,
|
||||
useGamepad,
|
||||
useGeolocation,
|
||||
useIdle,
|
||||
useImage,
|
||||
useInfiniteScroll,
|
||||
useIntersectionObserver,
|
||||
useInterval,
|
||||
useIntervalFn,
|
||||
useKeyModifier,
|
||||
useLastChanged,
|
||||
useLocalStorage,
|
||||
useMagicKeys,
|
||||
useManualRefHistory,
|
||||
useMediaControls,
|
||||
useMediaQuery,
|
||||
useMemoize,
|
||||
useMemory,
|
||||
useMounted,
|
||||
useMouse,
|
||||
useMouseInElement,
|
||||
useMousePressed,
|
||||
useMutationObserver,
|
||||
useNavigatorLanguage,
|
||||
useNetwork,
|
||||
useNow,
|
||||
useObjectUrl,
|
||||
useOffsetPagination,
|
||||
useOnline,
|
||||
usePageLeave,
|
||||
useParallax,
|
||||
useParentElement,
|
||||
usePerformanceObserver,
|
||||
usePermission,
|
||||
usePointer,
|
||||
usePointerLock,
|
||||
usePointerSwipe,
|
||||
usePreferredColorScheme,
|
||||
usePreferredContrast,
|
||||
usePreferredDark,
|
||||
usePreferredLanguages,
|
||||
usePreferredReducedMotion,
|
||||
usePreferredReducedTransparency,
|
||||
usePrevious,
|
||||
useRafFn,
|
||||
useRefHistory,
|
||||
useResizeObserver,
|
||||
useSSRWidth,
|
||||
useScreenOrientation,
|
||||
useScreenSafeArea,
|
||||
useScriptTag,
|
||||
useScroll,
|
||||
useScrollLock,
|
||||
useSessionStorage,
|
||||
useShare,
|
||||
useSorted,
|
||||
useSpeechRecognition,
|
||||
useSpeechSynthesis,
|
||||
useStepper,
|
||||
useStorage,
|
||||
useStorageAsync,
|
||||
useStyleTag,
|
||||
useSupported,
|
||||
useSwipe,
|
||||
useTemplateRefsList,
|
||||
useTextDirection,
|
||||
useTextSelection,
|
||||
useTextareaAutosize,
|
||||
useThrottleFn,
|
||||
useThrottledRefHistory,
|
||||
useTimeAgo,
|
||||
useTimeout,
|
||||
useTimeoutFn,
|
||||
useTimeoutPoll,
|
||||
useTimestamp,
|
||||
useTitle,
|
||||
useToNumber,
|
||||
useToString,
|
||||
useToggle,
|
||||
useTransition,
|
||||
useUrlSearchParams,
|
||||
useUserMedia,
|
||||
useVModel,
|
||||
useVModels,
|
||||
useVibrate,
|
||||
useVirtualList,
|
||||
useWakeLock,
|
||||
useWebNotification,
|
||||
useWebSocket,
|
||||
useWebWorker,
|
||||
useWebWorkerFn,
|
||||
useWindowFocus,
|
||||
useWindowScroll,
|
||||
useWindowSize,
|
||||
watchArray,
|
||||
watchAtMost,
|
||||
watchDebounced,
|
||||
watchDeep,
|
||||
watchIgnorable,
|
||||
watchImmediate,
|
||||
watchOnce,
|
||||
watchPausable,
|
||||
watchThrottled,
|
||||
watchTriggerable,
|
||||
watchWithFilter,
|
||||
whenever,
|
||||
} from './chunk-BRNHR3LR.js';
|
||||
import './chunk-H6MPEGKE.js';
|
||||
export {
|
||||
DefaultMagicKeysAliasMap,
|
||||
StorageSerializers,
|
||||
TransitionPresets,
|
||||
assert,
|
||||
computedAsync as asyncComputed,
|
||||
refAutoReset as autoResetRef,
|
||||
breakpointsAntDesign,
|
||||
breakpointsBootstrapV5,
|
||||
breakpointsElement,
|
||||
breakpointsMasterCss,
|
||||
breakpointsPrimeFlex,
|
||||
breakpointsQuasar,
|
||||
breakpointsSematic,
|
||||
breakpointsTailwind,
|
||||
breakpointsVuetify,
|
||||
breakpointsVuetifyV2,
|
||||
breakpointsVuetifyV3,
|
||||
bypassFilter,
|
||||
camelize,
|
||||
clamp,
|
||||
cloneFnJSON,
|
||||
computedAsync,
|
||||
computedEager,
|
||||
computedInject,
|
||||
computedWithControl,
|
||||
containsProp,
|
||||
computedWithControl as controlledComputed,
|
||||
controlledRef,
|
||||
createEventHook,
|
||||
createFetch,
|
||||
createFilterWrapper,
|
||||
createGlobalState,
|
||||
createInjectionState,
|
||||
reactify as createReactiveFn,
|
||||
createRef,
|
||||
createReusableTemplate,
|
||||
createSharedComposable,
|
||||
createSingletonPromise,
|
||||
createTemplatePromise,
|
||||
createUnrefFn,
|
||||
customStorageEventName,
|
||||
debounceFilter,
|
||||
refDebounced as debouncedRef,
|
||||
watchDebounced as debouncedWatch,
|
||||
defaultDocument,
|
||||
defaultLocation,
|
||||
defaultNavigator,
|
||||
defaultWindow,
|
||||
computedEager as eagerComputed,
|
||||
executeTransition,
|
||||
extendRef,
|
||||
formatDate,
|
||||
formatTimeAgo,
|
||||
get,
|
||||
getLifeCycleTarget,
|
||||
getSSRHandler,
|
||||
hasOwn,
|
||||
hyphenate,
|
||||
identity,
|
||||
watchIgnorable as ignorableWatch,
|
||||
increaseWithUnit,
|
||||
injectLocal,
|
||||
invoke,
|
||||
isClient,
|
||||
isDef,
|
||||
isDefined,
|
||||
isIOS,
|
||||
isObject,
|
||||
isWorker,
|
||||
makeDestructurable,
|
||||
mapGamepadToXbox360Controller,
|
||||
noop,
|
||||
normalizeDate,
|
||||
notNullish,
|
||||
now,
|
||||
objectEntries,
|
||||
objectOmit,
|
||||
objectPick,
|
||||
onClickOutside,
|
||||
onElementRemoval,
|
||||
onKeyDown,
|
||||
onKeyPressed,
|
||||
onKeyStroke,
|
||||
onKeyUp,
|
||||
onLongPress,
|
||||
onStartTyping,
|
||||
pausableFilter,
|
||||
watchPausable as pausableWatch,
|
||||
promiseTimeout,
|
||||
provideLocal,
|
||||
provideSSRWidth,
|
||||
pxValue,
|
||||
rand,
|
||||
reactify,
|
||||
reactifyObject,
|
||||
reactiveComputed,
|
||||
reactiveOmit,
|
||||
reactivePick,
|
||||
refAutoReset,
|
||||
refDebounced,
|
||||
refDefault,
|
||||
refThrottled,
|
||||
refWithControl,
|
||||
resolveRef,
|
||||
resolveUnref,
|
||||
set,
|
||||
setSSRHandler,
|
||||
syncRef,
|
||||
syncRefs,
|
||||
templateRef,
|
||||
throttleFilter,
|
||||
refThrottled as throttledRef,
|
||||
watchThrottled as throttledWatch,
|
||||
timestamp,
|
||||
toArray,
|
||||
toReactive,
|
||||
toRef,
|
||||
toRefs,
|
||||
toValue,
|
||||
tryOnBeforeMount,
|
||||
tryOnBeforeUnmount,
|
||||
tryOnMounted,
|
||||
tryOnScopeDispose,
|
||||
tryOnUnmounted,
|
||||
unrefElement,
|
||||
until,
|
||||
useActiveElement,
|
||||
useAnimate,
|
||||
useArrayDifference,
|
||||
useArrayEvery,
|
||||
useArrayFilter,
|
||||
useArrayFind,
|
||||
useArrayFindIndex,
|
||||
useArrayFindLast,
|
||||
useArrayIncludes,
|
||||
useArrayJoin,
|
||||
useArrayMap,
|
||||
useArrayReduce,
|
||||
useArraySome,
|
||||
useArrayUnique,
|
||||
useAsyncQueue,
|
||||
useAsyncState,
|
||||
useBase64,
|
||||
useBattery,
|
||||
useBluetooth,
|
||||
useBreakpoints,
|
||||
useBroadcastChannel,
|
||||
useBrowserLocation,
|
||||
useCached,
|
||||
useClipboard,
|
||||
useClipboardItems,
|
||||
useCloned,
|
||||
useColorMode,
|
||||
useConfirmDialog,
|
||||
useCountdown,
|
||||
useCounter,
|
||||
useCssVar,
|
||||
useCurrentElement,
|
||||
useCycleList,
|
||||
useDark,
|
||||
useDateFormat,
|
||||
refDebounced as useDebounce,
|
||||
useDebounceFn,
|
||||
useDebouncedRefHistory,
|
||||
useDeviceMotion,
|
||||
useDeviceOrientation,
|
||||
useDevicePixelRatio,
|
||||
useDevicesList,
|
||||
useDisplayMedia,
|
||||
useDocumentVisibility,
|
||||
useDraggable,
|
||||
useDropZone,
|
||||
useElementBounding,
|
||||
useElementByPoint,
|
||||
useElementHover,
|
||||
useElementSize,
|
||||
useElementVisibility,
|
||||
useEventBus,
|
||||
useEventListener,
|
||||
useEventSource,
|
||||
useEyeDropper,
|
||||
useFavicon,
|
||||
useFetch,
|
||||
useFileDialog,
|
||||
useFileSystemAccess,
|
||||
useFocus,
|
||||
useFocusWithin,
|
||||
useFps,
|
||||
useFullscreen,
|
||||
useGamepad,
|
||||
useGeolocation,
|
||||
useIdle,
|
||||
useImage,
|
||||
useInfiniteScroll,
|
||||
useIntersectionObserver,
|
||||
useInterval,
|
||||
useIntervalFn,
|
||||
useKeyModifier,
|
||||
useLastChanged,
|
||||
useLocalStorage,
|
||||
useMagicKeys,
|
||||
useManualRefHistory,
|
||||
useMediaControls,
|
||||
useMediaQuery,
|
||||
useMemoize,
|
||||
useMemory,
|
||||
useMounted,
|
||||
useMouse,
|
||||
useMouseInElement,
|
||||
useMousePressed,
|
||||
useMutationObserver,
|
||||
useNavigatorLanguage,
|
||||
useNetwork,
|
||||
useNow,
|
||||
useObjectUrl,
|
||||
useOffsetPagination,
|
||||
useOnline,
|
||||
usePageLeave,
|
||||
useParallax,
|
||||
useParentElement,
|
||||
usePerformanceObserver,
|
||||
usePermission,
|
||||
usePointer,
|
||||
usePointerLock,
|
||||
usePointerSwipe,
|
||||
usePreferredColorScheme,
|
||||
usePreferredContrast,
|
||||
usePreferredDark,
|
||||
usePreferredLanguages,
|
||||
usePreferredReducedMotion,
|
||||
usePreferredReducedTransparency,
|
||||
usePrevious,
|
||||
useRafFn,
|
||||
useRefHistory,
|
||||
useResizeObserver,
|
||||
useSSRWidth,
|
||||
useScreenOrientation,
|
||||
useScreenSafeArea,
|
||||
useScriptTag,
|
||||
useScroll,
|
||||
useScrollLock,
|
||||
useSessionStorage,
|
||||
useShare,
|
||||
useSorted,
|
||||
useSpeechRecognition,
|
||||
useSpeechSynthesis,
|
||||
useStepper,
|
||||
useStorage,
|
||||
useStorageAsync,
|
||||
useStyleTag,
|
||||
useSupported,
|
||||
useSwipe,
|
||||
useTemplateRefsList,
|
||||
useTextDirection,
|
||||
useTextSelection,
|
||||
useTextareaAutosize,
|
||||
refThrottled as useThrottle,
|
||||
useThrottleFn,
|
||||
useThrottledRefHistory,
|
||||
useTimeAgo,
|
||||
useTimeout,
|
||||
useTimeoutFn,
|
||||
useTimeoutPoll,
|
||||
useTimestamp,
|
||||
useTitle,
|
||||
useToNumber,
|
||||
useToString,
|
||||
useToggle,
|
||||
useTransition,
|
||||
useUrlSearchParams,
|
||||
useUserMedia,
|
||||
useVModel,
|
||||
useVModels,
|
||||
useVibrate,
|
||||
useVirtualList,
|
||||
useWakeLock,
|
||||
useWebNotification,
|
||||
useWebSocket,
|
||||
useWebWorker,
|
||||
useWebWorkerFn,
|
||||
useWindowFocus,
|
||||
useWindowScroll,
|
||||
useWindowSize,
|
||||
watchArray,
|
||||
watchAtMost,
|
||||
watchDebounced,
|
||||
watchDeep,
|
||||
watchIgnorable,
|
||||
watchImmediate,
|
||||
watchOnce,
|
||||
watchPausable,
|
||||
watchThrottled,
|
||||
watchTriggerable,
|
||||
watchWithFilter,
|
||||
whenever,
|
||||
};
|
||||
//# sourceMappingURL=vitepress___@vueuse_core.js.map
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sourcesContent": [],
|
||||
"mappings": "",
|
||||
"names": []
|
||||
}
|
||||
-1693
File diff suppressed because it is too large
Load Diff
-7
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
-1813
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Vendored
-347
@@ -1,347 +0,0 @@
|
||||
import {
|
||||
BaseTransition,
|
||||
BaseTransitionPropsValidators,
|
||||
Comment,
|
||||
DeprecationTypes,
|
||||
EffectScope,
|
||||
ErrorCodes,
|
||||
ErrorTypeStrings,
|
||||
Fragment,
|
||||
KeepAlive,
|
||||
ReactiveEffect,
|
||||
Static,
|
||||
Suspense,
|
||||
Teleport,
|
||||
Text,
|
||||
TrackOpTypes,
|
||||
Transition,
|
||||
TransitionGroup,
|
||||
TriggerOpTypes,
|
||||
VueElement,
|
||||
assertNumber,
|
||||
callWithAsyncErrorHandling,
|
||||
callWithErrorHandling,
|
||||
camelize,
|
||||
capitalize,
|
||||
cloneVNode,
|
||||
compatUtils,
|
||||
compile,
|
||||
computed,
|
||||
createApp,
|
||||
createBaseVNode,
|
||||
createBlock,
|
||||
createCommentVNode,
|
||||
createElementBlock,
|
||||
createHydrationRenderer,
|
||||
createPropsRestProxy,
|
||||
createRenderer,
|
||||
createSSRApp,
|
||||
createSlots,
|
||||
createStaticVNode,
|
||||
createTextVNode,
|
||||
createVNode,
|
||||
customRef,
|
||||
defineAsyncComponent,
|
||||
defineComponent,
|
||||
defineCustomElement,
|
||||
defineEmits,
|
||||
defineExpose,
|
||||
defineModel,
|
||||
defineOptions,
|
||||
defineProps,
|
||||
defineSSRCustomElement,
|
||||
defineSlots,
|
||||
devtools,
|
||||
effect,
|
||||
effectScope,
|
||||
getCurrentInstance,
|
||||
getCurrentScope,
|
||||
getCurrentWatcher,
|
||||
getTransitionRawChildren,
|
||||
guardReactiveProps,
|
||||
h,
|
||||
handleError,
|
||||
hasInjectionContext,
|
||||
hydrate,
|
||||
hydrateOnIdle,
|
||||
hydrateOnInteraction,
|
||||
hydrateOnMediaQuery,
|
||||
hydrateOnVisible,
|
||||
initCustomFormatter,
|
||||
initDirectivesForSSR,
|
||||
inject,
|
||||
isMemoSame,
|
||||
isProxy,
|
||||
isReactive,
|
||||
isReadonly,
|
||||
isRef,
|
||||
isRuntimeOnly,
|
||||
isShallow,
|
||||
isVNode,
|
||||
markRaw,
|
||||
mergeDefaults,
|
||||
mergeModels,
|
||||
mergeProps,
|
||||
nextTick,
|
||||
nodeOps,
|
||||
normalizeClass,
|
||||
normalizeProps,
|
||||
normalizeStyle,
|
||||
onActivated,
|
||||
onBeforeMount,
|
||||
onBeforeUnmount,
|
||||
onBeforeUpdate,
|
||||
onDeactivated,
|
||||
onErrorCaptured,
|
||||
onMounted,
|
||||
onRenderTracked,
|
||||
onRenderTriggered,
|
||||
onScopeDispose,
|
||||
onServerPrefetch,
|
||||
onUnmounted,
|
||||
onUpdated,
|
||||
onWatcherCleanup,
|
||||
openBlock,
|
||||
patchProp,
|
||||
popScopeId,
|
||||
provide,
|
||||
proxyRefs,
|
||||
pushScopeId,
|
||||
queuePostFlushCb,
|
||||
reactive,
|
||||
readonly,
|
||||
ref,
|
||||
registerRuntimeCompiler,
|
||||
render,
|
||||
renderList,
|
||||
renderSlot,
|
||||
resolveComponent,
|
||||
resolveDirective,
|
||||
resolveDynamicComponent,
|
||||
resolveFilter,
|
||||
resolveTransitionHooks,
|
||||
setBlockTracking,
|
||||
setDevtoolsHook,
|
||||
setTransitionHooks,
|
||||
shallowReactive,
|
||||
shallowReadonly,
|
||||
shallowRef,
|
||||
ssrContextKey,
|
||||
ssrUtils,
|
||||
stop,
|
||||
toDisplayString,
|
||||
toHandlerKey,
|
||||
toHandlers,
|
||||
toRaw,
|
||||
toRef,
|
||||
toRefs,
|
||||
toValue,
|
||||
transformVNodeArgs,
|
||||
triggerRef,
|
||||
unref,
|
||||
useAttrs,
|
||||
useCssModule,
|
||||
useCssVars,
|
||||
useHost,
|
||||
useId,
|
||||
useModel,
|
||||
useSSRContext,
|
||||
useShadowRoot,
|
||||
useSlots,
|
||||
useTemplateRef,
|
||||
useTransitionState,
|
||||
vModelCheckbox,
|
||||
vModelDynamic,
|
||||
vModelRadio,
|
||||
vModelSelect,
|
||||
vModelText,
|
||||
vShow,
|
||||
version,
|
||||
warn,
|
||||
watch,
|
||||
watchEffect,
|
||||
watchPostEffect,
|
||||
watchSyncEffect,
|
||||
withAsyncContext,
|
||||
withCtx,
|
||||
withDefaults,
|
||||
withDirectives,
|
||||
withKeys,
|
||||
withMemo,
|
||||
withModifiers,
|
||||
withScopeId,
|
||||
} from './chunk-H6MPEGKE.js';
|
||||
export {
|
||||
BaseTransition,
|
||||
BaseTransitionPropsValidators,
|
||||
Comment,
|
||||
DeprecationTypes,
|
||||
EffectScope,
|
||||
ErrorCodes,
|
||||
ErrorTypeStrings,
|
||||
Fragment,
|
||||
KeepAlive,
|
||||
ReactiveEffect,
|
||||
Static,
|
||||
Suspense,
|
||||
Teleport,
|
||||
Text,
|
||||
TrackOpTypes,
|
||||
Transition,
|
||||
TransitionGroup,
|
||||
TriggerOpTypes,
|
||||
VueElement,
|
||||
assertNumber,
|
||||
callWithAsyncErrorHandling,
|
||||
callWithErrorHandling,
|
||||
camelize,
|
||||
capitalize,
|
||||
cloneVNode,
|
||||
compatUtils,
|
||||
compile,
|
||||
computed,
|
||||
createApp,
|
||||
createBlock,
|
||||
createCommentVNode,
|
||||
createElementBlock,
|
||||
createBaseVNode as createElementVNode,
|
||||
createHydrationRenderer,
|
||||
createPropsRestProxy,
|
||||
createRenderer,
|
||||
createSSRApp,
|
||||
createSlots,
|
||||
createStaticVNode,
|
||||
createTextVNode,
|
||||
createVNode,
|
||||
customRef,
|
||||
defineAsyncComponent,
|
||||
defineComponent,
|
||||
defineCustomElement,
|
||||
defineEmits,
|
||||
defineExpose,
|
||||
defineModel,
|
||||
defineOptions,
|
||||
defineProps,
|
||||
defineSSRCustomElement,
|
||||
defineSlots,
|
||||
devtools,
|
||||
effect,
|
||||
effectScope,
|
||||
getCurrentInstance,
|
||||
getCurrentScope,
|
||||
getCurrentWatcher,
|
||||
getTransitionRawChildren,
|
||||
guardReactiveProps,
|
||||
h,
|
||||
handleError,
|
||||
hasInjectionContext,
|
||||
hydrate,
|
||||
hydrateOnIdle,
|
||||
hydrateOnInteraction,
|
||||
hydrateOnMediaQuery,
|
||||
hydrateOnVisible,
|
||||
initCustomFormatter,
|
||||
initDirectivesForSSR,
|
||||
inject,
|
||||
isMemoSame,
|
||||
isProxy,
|
||||
isReactive,
|
||||
isReadonly,
|
||||
isRef,
|
||||
isRuntimeOnly,
|
||||
isShallow,
|
||||
isVNode,
|
||||
markRaw,
|
||||
mergeDefaults,
|
||||
mergeModels,
|
||||
mergeProps,
|
||||
nextTick,
|
||||
nodeOps,
|
||||
normalizeClass,
|
||||
normalizeProps,
|
||||
normalizeStyle,
|
||||
onActivated,
|
||||
onBeforeMount,
|
||||
onBeforeUnmount,
|
||||
onBeforeUpdate,
|
||||
onDeactivated,
|
||||
onErrorCaptured,
|
||||
onMounted,
|
||||
onRenderTracked,
|
||||
onRenderTriggered,
|
||||
onScopeDispose,
|
||||
onServerPrefetch,
|
||||
onUnmounted,
|
||||
onUpdated,
|
||||
onWatcherCleanup,
|
||||
openBlock,
|
||||
patchProp,
|
||||
popScopeId,
|
||||
provide,
|
||||
proxyRefs,
|
||||
pushScopeId,
|
||||
queuePostFlushCb,
|
||||
reactive,
|
||||
readonly,
|
||||
ref,
|
||||
registerRuntimeCompiler,
|
||||
render,
|
||||
renderList,
|
||||
renderSlot,
|
||||
resolveComponent,
|
||||
resolveDirective,
|
||||
resolveDynamicComponent,
|
||||
resolveFilter,
|
||||
resolveTransitionHooks,
|
||||
setBlockTracking,
|
||||
setDevtoolsHook,
|
||||
setTransitionHooks,
|
||||
shallowReactive,
|
||||
shallowReadonly,
|
||||
shallowRef,
|
||||
ssrContextKey,
|
||||
ssrUtils,
|
||||
stop,
|
||||
toDisplayString,
|
||||
toHandlerKey,
|
||||
toHandlers,
|
||||
toRaw,
|
||||
toRef,
|
||||
toRefs,
|
||||
toValue,
|
||||
transformVNodeArgs,
|
||||
triggerRef,
|
||||
unref,
|
||||
useAttrs,
|
||||
useCssModule,
|
||||
useCssVars,
|
||||
useHost,
|
||||
useId,
|
||||
useModel,
|
||||
useSSRContext,
|
||||
useShadowRoot,
|
||||
useSlots,
|
||||
useTemplateRef,
|
||||
useTransitionState,
|
||||
vModelCheckbox,
|
||||
vModelDynamic,
|
||||
vModelRadio,
|
||||
vModelSelect,
|
||||
vModelText,
|
||||
vShow,
|
||||
version,
|
||||
warn,
|
||||
watch,
|
||||
watchEffect,
|
||||
watchPostEffect,
|
||||
watchSyncEffect,
|
||||
withAsyncContext,
|
||||
withCtx,
|
||||
withDefaults,
|
||||
withDirectives,
|
||||
withKeys,
|
||||
withMemo,
|
||||
withModifiers,
|
||||
withScopeId,
|
||||
};
|
||||
//# sourceMappingURL=vue.js.map
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"sources": [],
|
||||
"sourcesContent": [],
|
||||
"mappings": "",
|
||||
"names": []
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
"license": "AGPL-3.0-only",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"predev": "node scripts/generate-blog.mjs && node scripts/generate-static-tool-links.mjs",
|
||||
"dev": "vite",
|
||||
"build": "node scripts/generate-blog.mjs && node scripts/generate-static-tool-links.mjs && tsc && vite build && node scripts/enhance-seo-pages.mjs && NODE_OPTIONS='--max-old-space-size=3072' node scripts/generate-i18n-pages.mjs && node scripts/generate-sitemap.mjs && node scripts/generate-security-headers.mjs && node scripts/seo-audit.mjs",
|
||||
"seo-audit": "node scripts/seo-audit.mjs",
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self' 'wasm-unsafe-eval' 'unsafe-eval' blob: https://cdn.jsdelivr.net/npm/@bentopdf/[email protected]/ https://cdn.jsdelivr.net/npm/@bentopdf/[email protected]/assets/ https://cdn.jsdelivr.net/npm/[email protected]/dist/ https://cdn.jsdelivr.net/npm/[email protected]/dist/ https://cdn.jsdelivr.net/npm/[email protected]/; worker-src 'self' blob:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com https://rawcdn.githack.com; connect-src 'self' blob: https://api.github.com https://fonts.gstatic.com https://cdn.jsdelivr.net https://bentopdf-cors-proxy.bentopdf.workers.dev https://rawcdn.githack.com; object-src 'none'; base-uri 'self'; frame-src 'self' blob:; frame-ancestors 'self'; form-action 'self'
|
||||
X-Frame-Options: SAMEORIGIN
|
||||
X-Content-Type-Options: nosniff
|
||||
X-XSS-Protection: 1; mode=block
|
||||
Referrer-Policy: strict-origin-when-cross-origin
|
||||
Permissions-Policy: geolocation=(), camera=(), microphone=(), payment=(), usb=(), interest-cohort=()
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: credentialless
|
||||
Cross-Origin-Resource-Policy: cross-origin
|
||||
|
||||
/docs
|
||||
! Content-Security-Policy
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-DQUgNM9X0iH2019NkUxeBvnBoEoRKkHBc/I0iLqPNPA=' 'sha256-La1r0VSk0Po4KFI0duEKhmPu+u0I416JW3oONqtdf4M='; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com https://rawcdn.githack.com; connect-src 'self' https://api.github.com https://fonts.gstatic.com https://cdn.jsdelivr.net https://bentopdf-cors-proxy.bentopdf.workers.dev https://rawcdn.githack.com; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'
|
||||
|
||||
/docs/*
|
||||
! Content-Security-Policy
|
||||
Content-Security-Policy: default-src 'self'; script-src 'self' 'sha256-DQUgNM9X0iH2019NkUxeBvnBoEoRKkHBc/I0iLqPNPA=' 'sha256-La1r0VSk0Po4KFI0duEKhmPu+u0I416JW3oONqtdf4M='; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com https://rawcdn.githack.com; connect-src 'self' https://api.github.com https://fonts.gstatic.com https://cdn.jsdelivr.net https://bentopdf-cors-proxy.bentopdf.workers.dev https://rawcdn.githack.com; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 128 KiB |
@@ -178,17 +178,19 @@ function main() {
|
||||
const headers = buildSecurityHeaders();
|
||||
const outPath = join(repoRoot, 'security-headers.conf');
|
||||
const docsOutPath = join(repoRoot, 'security-headers-docs.conf');
|
||||
const staticOutPath = join(repoRoot, 'public', '_headers');
|
||||
writeFileSync(outPath, headers.nginx);
|
||||
writeFileSync(docsOutPath, headers.nginxDocs);
|
||||
writeFileSync(staticOutPath, headers.staticHeaders);
|
||||
console.log(
|
||||
`[security-headers] wrote ${outPath} with ${headers.scriptSources.length} script-src / ${headers.connectOrigins.length} connect-src source(s)`
|
||||
);
|
||||
console.log(`[security-headers] wrote ${docsOutPath} (docs CSP)`);
|
||||
console.log(`[security-headers] wrote ${staticOutPath}`);
|
||||
const distDir = join(repoRoot, 'dist');
|
||||
if (existsSync(distDir)) {
|
||||
const customHeaders = join(repoRoot, 'public', '_headers');
|
||||
if (existsSync(customHeaders)) {
|
||||
console.log(
|
||||
`[security-headers] kept your own ${customHeaders} for static hosts`
|
||||
);
|
||||
} else if (existsSync(distDir)) {
|
||||
const distOutPath = join(distDir, '_headers');
|
||||
writeFileSync(distOutPath, headers.staticHeaders);
|
||||
console.log(`[security-headers] wrote ${distOutPath}`);
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'sha256-DQUgNM9X0iH2019NkUxeBvnBoEoRKkHBc/I0iLqPNPA=' 'sha256-La1r0VSk0Po4KFI0duEKhmPu+u0I416JW3oONqtdf4M='; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com https://rawcdn.githack.com; connect-src 'self' https://api.github.com https://fonts.gstatic.com https://cdn.jsdelivr.net https://bentopdf-cors-proxy.bentopdf.workers.dev https://rawcdn.githack.com; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "geolocation=(), camera=(), microphone=(), payment=(), usb=(), interest-cohort=()" always;
|
||||
add_header Cross-Origin-Opener-Policy "same-origin" always;
|
||||
add_header Cross-Origin-Embedder-Policy "credentialless" always;
|
||||
add_header Cross-Origin-Resource-Policy "cross-origin" always;
|
||||
@@ -1,926 +0,0 @@
|
||||
<div class="col-span-full mt-6 first:mt-0">
|
||||
<h2 class="text-lg font-semibold text-white">Popular Tools</h2>
|
||||
</div>
|
||||
<a
|
||||
href="/edit-pdf-text"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Edit PDF Text</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Click any paragraph and edit it in place with live reflow, fonts, and
|
||||
styling.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-workflow"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF Workflow Builder</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Build custom PDF processing pipelines with a visual node editor.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-multi-tool"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF Multi Tool</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Merge, Split, Organize, Delete, Rotate, Add Blank Pages, Extract and
|
||||
Duplicate in a unified interface.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/merge-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Merge PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Combine multiple PDFs into one file. Preserves Bookmarks.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/split-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Split PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Extract a range of pages into a new PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/compress-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Compress PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Reduce the file size of your PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/edit-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF Editor</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Annotate, highlight, redact, comment, add shapes/images, search, and view
|
||||
PDFs.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/jpg-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">JPG to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Create a PDF from one or more JPG images.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/sign-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Sign PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Draw, type, or upload your signature.</p></a
|
||||
>
|
||||
<a
|
||||
href="/crop-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Crop PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Trim the margins of every page in your PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/extract-pages"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Extract Pages</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Save a selection of pages as new files.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/organize-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Duplicate & Organize</h3>
|
||||
<p class="text-gray-400 text-sm">Duplicate, reorder, and delete pages.</p></a
|
||||
>
|
||||
<a
|
||||
href="/delete-pages"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Delete Pages</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Remove specific pages from your document.
|
||||
</p></a
|
||||
>
|
||||
<div class="col-span-full mt-6 first:mt-0">
|
||||
<h2 class="text-lg font-semibold text-white">Edit & Annotate</h2>
|
||||
</div>
|
||||
<a
|
||||
href="/bookmark"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Edit Bookmarks</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Add, edit, import, delete and extract PDF bookmarks.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/table-of-contents"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Table of Contents</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Generate a table of contents page from PDF bookmarks.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/page-numbers"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Page Numbers</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Insert page numbers into your document.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/add-page-labels"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Add Page Labels</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Apply PDF page labels with Roman numerals, prefixes, and custom starts.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/bates-numbering"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Bates Numbering</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Add sequential Bates numbers across one or more PDF files.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/add-watermark"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Add Watermark</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Stamp text or an image over your PDF pages.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/header-footer"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Header & Footer</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Add text to the top and bottom of pages.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/invert-colors"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Invert Colors</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Create a "dark mode" version of your PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/scanner-effect"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Scanner Effect</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Make your PDF look like a scanned document.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/adjust-colors"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Adjust Colors</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Fine-tune brightness, contrast, saturation and more.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/background-color"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Background Color</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Change the background color of your PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/text-color"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Change Text Color</h3>
|
||||
<p class="text-gray-400 text-sm">Change the color of text in your PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/add-stamps"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Add Stamps</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Add image stamps to your PDF using the annotation toolbar.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/remove-annotations"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Remove Annotations</h3>
|
||||
<p class="text-gray-400 text-sm">Strip comments, highlights, and links.</p></a
|
||||
>
|
||||
<a
|
||||
href="/form-filler"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF Form Filler</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Fill in forms directly in the browser. Also supports XFA forms.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/form-creator"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Create PDF Form</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Create fillable PDF forms with drag-and-drop text fields.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/remove-blank-pages"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Remove Blank Pages</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Automatically detect and delete blank pages.
|
||||
</p></a
|
||||
>
|
||||
<div class="col-span-full mt-6 first:mt-0">
|
||||
<h2 class="text-lg font-semibold text-white">Convert to PDF</h2>
|
||||
</div>
|
||||
<a
|
||||
href="/image-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Images to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert JPG, PNG, BMP, GIF, TIFF, PNM, PGM, PBM, PPM, PAM, JXR, JPX, JP2,
|
||||
PSD, SVG, HEIC, WebP to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/png-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PNG to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Create a PDF from one or more PNG images.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/webp-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">WebP to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Create a PDF from one or more WebP images.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/svg-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">SVG to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Create a PDF from one or more SVG images.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/bmp-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">BMP to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Create a PDF from one or more BMP images.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/heic-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">HEIC to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Create a PDF from one or more HEIC images.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/tiff-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">TIFF to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Create a PDF from one or more TIFF images.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/txt-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Text to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Convert a plain text file into a PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/markdown-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Markdown to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert Markdown to PDF with live preview and syntax highlighting.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/json-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">JSON to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Convert JSON files to PDF format.</p></a
|
||||
>
|
||||
<a
|
||||
href="/odt-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">ODT to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert ODT (OpenDocument Text) files to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/csv-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">CSV to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert CSV (Comma-Separated Values) spreadsheets to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/rtf-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">RTF to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert RTF (Rich Text Format) documents to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/word-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Word to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert Word documents (DOCX, DOC, ODT) to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/excel-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Excel to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert Excel spreadsheets (XLSX, XLS, ODS) to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/powerpoint-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PowerPoint to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert PowerPoint presentations (PPTX, PPT, ODP) to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/xps-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">XPS to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Convert XPS/OXPS documents to PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/mobi-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">MOBI to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Convert MOBI e-books to PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/epub-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">EPUB to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Convert EPUB e-books to PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/fb2-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">FB2 to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert FictionBook (FB2) e-books to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/cbz-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">CBZ to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert comic book archives (CBZ/CBR) to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/wpd-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">WPD to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert WordPerfect documents (WPD) to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/wps-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">WPS to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Convert WPS Office documents to PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/xml-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">XML to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Convert XML documents to PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/pages-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Pages to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Convert Apple Pages documents to PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/odg-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">ODG to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert OpenDocument Graphics (ODG) to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/ods-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">ODS to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert OpenDocument Spreadsheet (ODS) to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/odp-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">ODP to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert OpenDocument Presentation (ODP) to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pub-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PUB to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert Microsoft Publisher (PUB) to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/vsd-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">VSD to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert Microsoft Visio (VSD, VSDX) to PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/psd-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PSD to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert Adobe Photoshop (PSD) files to PDF. Multiple files supported.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/email-to-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Email to PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert email files (EML, MSG) to PDF format.
|
||||
</p></a
|
||||
>
|
||||
<div class="col-span-full mt-6 first:mt-0">
|
||||
<h2 class="text-lg font-semibold text-white">Convert from PDF</h2>
|
||||
</div>
|
||||
<a
|
||||
href="/pdf-to-jpg"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to JPG</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert each PDF page into a JPG image.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-png"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to PNG</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert each PDF page into a PNG image.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-webp"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to WebP</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert each PDF page into a WebP image.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-bmp"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to BMP</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert each PDF page into a BMP image.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-tiff"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to TIFF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert each PDF page into a TIFF image.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-cbz"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to CBZ</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert a PDF into a CBZ (Comic Book Archive) file for comic readers.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-svg"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to SVG</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert each PDF page into a scalable vector graphic.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-csv"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to CSV</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Extract tables from PDF and convert to CSV format.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-excel"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to Excel</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Extract tables from PDF and convert to Excel (XLSX).
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-greyscale"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to Greyscale</h3>
|
||||
<p class="text-gray-400 text-sm">Convert all colors to black and white.</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-json"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to JSON</h3>
|
||||
<p class="text-gray-400 text-sm">Convert PDF files to JSON format.</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-word"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to Word</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert PDF files to editable Word documents.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/extract-images"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Extract Images</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Extract all embedded images from your PDF files.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-markdown"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to Markdown</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert PDF text and tables to Markdown format.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/prepare-pdf-for-ai"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Prepare PDF for AI</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Extract PDF content as LlamaIndex JSON for RAG/LLM pipelines.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-text"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to Text</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Extract text from PDF files and save as plain text (.txt).
|
||||
</p></a
|
||||
>
|
||||
<div class="col-span-full mt-6 first:mt-0">
|
||||
<h2 class="text-lg font-semibold text-white">Organize & Manage</h2>
|
||||
</div>
|
||||
<a
|
||||
href="/ocr-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">OCR PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Make a PDF searchable and copyable.</p></a
|
||||
>
|
||||
<a
|
||||
href="/alternate-merge"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Alternate & Mix Pages</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Merge PDFs by alternating pages from each PDF. Preserves Bookmarks.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/duplex-collate"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Duplex Collate</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Reorder front/back scan blocks into collated page order in one PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/overlay-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF Overlay</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Overlay or underlay pages from one PDF onto another.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/add-attachments"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Add Attachments</h3>
|
||||
<p class="text-gray-400 text-sm">Embed one or more files into your PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/extract-attachments"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Extract Attachments</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Extract all embedded files from PDF(s) as a ZIP.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/edit-attachments"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Edit Attachments</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
View or remove attachments in your PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-layers"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF OCG</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
View, toggle, add, and delete OCG layers in your PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/extract-tables"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Extract Tables</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Extract tables from PDFs as CSV, JSON, or Markdown.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/divide-pages"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Divide Pages</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Divide pages horizontally or vertically.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/add-blank-page"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Add Blank Page</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Insert an empty page anywhere in your PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/reverse-pages"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Reverse Pages</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Flip the order of all pages in your document.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/rotate-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Rotate PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Turn pages in 90-degree increments.</p></a
|
||||
>
|
||||
<a
|
||||
href="/rotate-custom"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Rotate by Custom Degrees</h3>
|
||||
<p class="text-gray-400 text-sm">Rotate pages by any custom angle.</p></a
|
||||
>
|
||||
<a
|
||||
href="/n-up-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">N-Up PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Arrange multiple pages onto a single sheet.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-booklet"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF Booklet</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Rearrange pages for double-sided booklet printing.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/combine-single-page"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Combine to Single Page</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Stitch all pages into one continuous scroll.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/view-metadata"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">View Metadata</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Inspect the hidden properties of your PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/edit-metadata"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Edit Metadata</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Change the author, title, and other properties.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/pdf-to-zip"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDFs to ZIP</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Package multiple PDF files into a ZIP archive.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/compare-pdfs"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Compare PDFs</h3>
|
||||
<p class="text-gray-400 text-sm">Compare two PDFs side by side.</p></a
|
||||
>
|
||||
<a
|
||||
href="/posterize-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Posterize PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Split a large page into multiple smaller pages.
|
||||
</p></a
|
||||
>
|
||||
<div class="col-span-full mt-6 first:mt-0">
|
||||
<h2 class="text-lg font-semibold text-white">Optimize & Repair</h2>
|
||||
</div>
|
||||
<a
|
||||
href="/pdf-to-pdfa"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">PDF to PDF/A</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert PDF to PDF/A for long-term archiving.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/fix-page-size"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Fix Page Size</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Standardize all pages to a uniform size.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/linearize-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Linearize PDF</h3>
|
||||
<p class="text-gray-400 text-sm">Optimize PDF for fast web viewing.</p></a
|
||||
>
|
||||
<a
|
||||
href="/page-dimensions"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Page Dimensions</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Analyze page size, orientation, and units.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/remove-restrictions"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Remove Restrictions</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Remove password protection and security restrictions associated with
|
||||
digitally signed PDF files.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/repair-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Repair PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Recover data from corrupted or damaged PDF files.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/rasterize-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Rasterize PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert PDF to image-based PDF. Flatten layers and remove selectable text.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/deskew-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Deskew PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Automatically straighten tilted scanned pages using OpenCV.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/font-to-outline"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Font to Outline</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Convert all fonts to vector outlines for consistent rendering.
|
||||
</p></a
|
||||
>
|
||||
<div class="col-span-full mt-6 first:mt-0">
|
||||
<h2 class="text-lg font-semibold text-white">Secure PDF</h2>
|
||||
</div>
|
||||
<a
|
||||
href="/protect-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Protect PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Password protect a PDF with strong AES encryption.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/sanitize-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Sanitize PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Remove metadata, annotations, scripts, and more.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/unlock-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Unlock PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Remove the password from a PDF so it opens freely.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/flatten-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Flatten PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Make form fields and annotations non-editable.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/remove-metadata"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Remove Metadata</h3>
|
||||
<p class="text-gray-400 text-sm">Strip hidden data from your PDF.</p></a
|
||||
>
|
||||
<a
|
||||
href="/change-permissions"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Change Permissions</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Set or change user permissions on a PDF.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/digital-sign-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Digital Signature</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Add a cryptographic digital signature using X.509 certificates.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/validate-signature-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Validate Signature</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Verify digital signatures and view certificate details.
|
||||
</p></a
|
||||
>
|
||||
<a
|
||||
href="/timestamp-pdf"
|
||||
class="block bg-gray-800 p-4 rounded-lg border border-gray-700 hover:bg-gray-700 transition-colors"
|
||||
><h3 class="text-white font-semibold mb-1">Timestamp PDF</h3>
|
||||
<p class="text-gray-400 text-sm">
|
||||
Add an RFC 3161 document timestamp using a trusted TSA server.
|
||||
</p></a
|
||||
>
|
||||
@@ -135,9 +135,9 @@ describe('deployment configs match the generator', () => {
|
||||
expect(headerRuleCsp('serve.json', 'docs/**')).toBe(defaults.docsCsp);
|
||||
});
|
||||
|
||||
it('public/_headers for Netlify and Cloudflare Pages', () => {
|
||||
const file = read('public/_headers');
|
||||
expect(file).toBe(defaults.staticHeaders);
|
||||
it('_headers for Netlify and Cloudflare Pages', () => {
|
||||
const file = defaults.staticHeaders;
|
||||
expect(file).toContain(`/*\n Content-Security-Policy: ${defaults.csp}\n`);
|
||||
expect(file).toContain(
|
||||
`/docs/*\n ! Content-Security-Policy\n Content-Security-Policy: ${defaults.docsCsp}\n`
|
||||
);
|
||||
@@ -147,7 +147,9 @@ describe('deployment configs match the generator', () => {
|
||||
});
|
||||
|
||||
it('nginx docs config and .htaccess', () => {
|
||||
expect(read('security-headers-docs.conf')).toBe(defaults.nginxDocs);
|
||||
expect(defaults.nginxDocs).toContain(
|
||||
`add_header Content-Security-Policy "${defaults.docsCsp}" always;`
|
||||
);
|
||||
expect(read('.htaccess')).toContain(
|
||||
`Header always set Content-Security-Policy "${defaults.csp}"`
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user